LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
usbd_cdc.c
Go to the documentation of this file.
1 /*
2  * @brief Boot ROM drivers/library USB Communication Device Class Definitions
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #define __INCLUDE_FROM_USB_DRIVER
33 #include "../../../USBMode.h"
34 
35 #if defined(USB_CAN_BE_DEVICE)
36 #include "../../../Device.h"
37 #include "../../../Endpoint.h"
38 
39 #if defined(USB_DEVICE_ROM_DRIVER)
40 
42 /* FIXME Abstract & make this size configurable */
43 //#define ROMDRIVER_CDC_MEM_SIZE 0x800
44 #define ROMDRIVER_CDC_DATA_BUFFER_SIZE 640
45 #define CDC_EP_SIZE (CALLBACK_UsbdCdc_Register_DataOutEndpointSize())
46 #if (USB_FORCED_FULLSPEED)
47  #define CDC_MAX_BULK_EP_SIZE 64
48 #else
49  #define CDC_MAX_BULK_EP_SIZE 512
50 #endif
51 
53 typedef struct {
54  uint8_t data[ROMDRIVER_CDC_DATA_BUFFER_SIZE];
55  volatile uint32_t rd_index;
56  volatile uint32_t wr_index;
57  volatile uint32_t count;
58 } CDC_CIRCLE_BUFFER_T;
59 
60 //uint8_t usb_RomDriver_CDC_buffer[ROMDRIVER_CDC_MEM_SIZE] ATTR_ALIGNED(4) __DATA(USBRAM_SECTION);
61 CDC_LINE_CODING* UsbdCdcLineCoding;
62 USBD_HANDLE_T UsbdCdcHdlr; //what is this for?
63 
65 //uint8_t UsbdCdc_EPIN_buffer[CDC_MAX_BULK_EP_SIZE] ATTR_ALIGNED(4) __DATA(USBRAM_SECTION);
66 volatile uint32_t UsbdCdc_EPIN_buffer_count = 0;
68 //uint8_t UsbdCdc_EPOUT_buffer[CDC_MAX_BULK_EP_SIZE] ATTR_ALIGNED(4) __DATA(USBRAM_SECTION);
69 volatile uint32_t UsbdCdc_EPOUT_buffer_index = 0;
70 volatile uint32_t UsbdCdc_EPOUT_buffer_count = 0;
71 
72 CDC_CIRCLE_BUFFER_T UsbdCdc_OUT_buffer, UsbdCdc_IN_buffer;
73 
74 ErrorCode_t UsbdCdc_Bulk_OUT_Hdlr(USBD_HANDLE_T hUsb, void* data, uint32_t event);
75 ErrorCode_t UsbdCdc_Bulk_IN_Hdlr(USBD_HANDLE_T hUsb, void* data, uint32_t event);
76 
77 void UsbdCdc_OUT_Buffer_Reset(void)
78 {
79  UsbdCdc_OUT_buffer.rd_index = 0;
80  UsbdCdc_OUT_buffer.wr_index = 0;
81  UsbdCdc_OUT_buffer.count = 0;
82 }
83 
84 void UsbdCdc_IN_Buffer_Reset(void)
85 {
86  UsbdCdc_IN_buffer.rd_index = 0;
87  UsbdCdc_IN_buffer.wr_index = 0;
88  UsbdCdc_IN_buffer.count = 0;
89 }
90 
91 PRAGMA_WEAK(EVENT_UsbdCdc_SetLineCode,EVENT_UsbdCdc_SetLineCode_Stub)
92 void EVENT_UsbdCdc_SetLineCode(CDC_LINE_CODING* line_coding) ATTR_WEAK ATTR_ALIAS(EVENT_UsbdCdc_SetLineCode_Stub);
93 
95 ErrorCode_t CALLBACK_UsbdCdc_SetLineCode(USBD_HANDLE_T hCDC, CDC_LINE_CODING* line_coding)
96 {
97  memcpy(UsbdCdcLineCoding, line_coding, sizeof(CDC_LINE_CODING));
98  EVENT_UsbdCdc_SetLineCode(line_coding);
99  return LPC_OK;
100 }
101 
103 void UsbdCdc_Init(void)
104 {
105  USBD_CDC_INIT_PARAM_T cdc_param;
106  uint32_t ep_indx;
107  memset((void*)&cdc_param, 0, sizeof(USBD_CDC_INIT_PARAM_T));
108  UsbdCdcLineCoding = (CDC_LINE_CODING*)CALLBACK_UsbdCdc_Register_LineCoding();
109 
110  /* CDC paramas */
111  cdc_param.mem_base = (uint32_t)usb_RomDriver_CDC_buffer;
112  cdc_param.mem_size = (uint32_t)ROMDRIVER_CDC_MEM_SIZE;
115  /* user defined functions */
116  cdc_param.SetLineCode = CALLBACK_UsbdCdc_SetLineCode;
117 
118  /* register Bulk IN endpoint interrupt handler */
119  ep_indx = (((CALLBACK_UsbdCdc_Register_DataInEndpointNumber() & 0x0F) << 1) + 1);
120  USBD_API->core->RegisterEpHandler (UsbHandle, ep_indx, UsbdCdc_Bulk_IN_Hdlr, NULL);
121 
122  /* register Bulk OUT endpoint interrupt handler */
123  ep_indx = ((CALLBACK_UsbdCdc_Register_DataOutEndpointNumber() & 0x0F) << 1);
124  USBD_API->core->RegisterEpHandler (UsbHandle, ep_indx, UsbdCdc_Bulk_OUT_Hdlr, NULL);
125 
126  UsbdCdc_OUT_Buffer_Reset();
127  UsbdCdc_IN_Buffer_Reset();
128  USBD_API->cdc->init(UsbHandle, &cdc_param, &UsbdCdcHdlr);
129 }
130 
131 
133 void UsbdCdc_SendData(uint8_t* buffer, uint32_t cnt)
134 {
135  uint32_t buffer_index = 0;
136  //uint8_t EpAdd = USB_ENDPOINT_IN(CALLBACK_UsbdCdc_Register_DataInEndpointNumber());
137  while(cnt)
138  {
139  if(UsbdCdc_IN_buffer.count <= ROMDRIVER_CDC_DATA_BUFFER_SIZE)
140  {
141  UsbdCdc_IN_buffer.data[UsbdCdc_IN_buffer.wr_index] = buffer[buffer_index++];
142  UsbdCdc_IN_buffer.wr_index++;
143  UsbdCdc_IN_buffer.wr_index &= (ROMDRIVER_CDC_DATA_BUFFER_SIZE -1);
144  UsbdCdc_IN_buffer.count++;
145  cnt--;
146  }
147  }
148 }
149 
151 uint32_t UsbdCdc_RecvData(uint8_t* buffer, uint32_t len)
152 {
153  uint32_t avail_len, i;
154  if(UsbdCdc_OUT_buffer.count > len)
155  {
156  avail_len = len;
157  }else
158  {
159  avail_len = UsbdCdc_OUT_buffer.count;
160  }
161  for(i=0; i<avail_len;i++)
162  {
163  buffer[i] = UsbdCdc_OUT_buffer.data[UsbdCdc_OUT_buffer.rd_index];
164  UsbdCdc_OUT_buffer.rd_index++;
165  UsbdCdc_OUT_buffer.rd_index &= (ROMDRIVER_CDC_DATA_BUFFER_SIZE - 1);
166  UsbdCdc_OUT_buffer.count--;
167  }
168  return avail_len;
169 }
170 
173 {
174  uint32_t avail_count, i;
175 
176  /* Sync OUT EP task */
177  avail_count = ROMDRIVER_CDC_DATA_BUFFER_SIZE - UsbdCdc_OUT_buffer.count;
178  if(avail_count > UsbdCdc_EPOUT_buffer_count)
179  {
180  avail_count = UsbdCdc_EPOUT_buffer_count;
181  }
182  for(i=0; i<avail_count; i++)
183  {
184  uint8_t t = UsbdCdc_EPOUT_buffer[UsbdCdc_EPOUT_buffer_index];
185  UsbdCdc_OUT_buffer.data[UsbdCdc_OUT_buffer.wr_index] = t;
186  UsbdCdc_EPOUT_buffer_index++;
187 
188  UsbdCdc_OUT_buffer.count++;
189  UsbdCdc_OUT_buffer.wr_index++;
190  UsbdCdc_OUT_buffer.wr_index &= (ROMDRIVER_CDC_DATA_BUFFER_SIZE - 1);
191  /* Sync 2 buffers must be implemented when all other tasks completed */
192  UsbdCdc_EPOUT_buffer_count--;
193  }
194 
195  /* Sync IN EP task */
196  if(UsbdCdc_EPIN_buffer_count == 0){
197  if(UsbdCdc_IN_buffer.count > CDC_EP_SIZE)
198  {
199  avail_count = CDC_EP_SIZE;
200  }else
201  {
202  avail_count = UsbdCdc_IN_buffer.count;
203  }
204 
205  for(i=0; i<avail_count; i++)
206  {
207  UsbdCdc_EPIN_buffer[i] = UsbdCdc_IN_buffer.data[UsbdCdc_IN_buffer.rd_index];
208  UsbdCdc_IN_buffer.rd_index++;
209  UsbdCdc_IN_buffer.rd_index &= (ROMDRIVER_CDC_DATA_BUFFER_SIZE - 1);
210  UsbdCdc_IN_buffer.count --;
211  }
212  /* Sync 2 buffers must be implemented when all other tasks completed */
213  UsbdCdc_EPIN_buffer_count = avail_count;
214  }
215 }
216 
217 ErrorCode_t UsbdCdc_Bulk_OUT_Hdlr(USBD_HANDLE_T hUsb, void* data, uint32_t event)
218 {
220  if (event == USB_EVT_OUT)
221  {
222  UsbdCdc_EPOUT_buffer_count = USBD_API->hw->ReadEP(UsbHandle, EpAdd, UsbdCdc_EPOUT_buffer);
223  }
224  else if(event == USB_EVT_OUT_NAK)
225  {
226  if(UsbdCdc_EPOUT_buffer_count == 0)
227  {
228  /* Reset EP OUT buffer */
229  UsbdCdc_EPOUT_buffer_index = 0;
230  /* Send DMA request */
231  USBD_API->hw->ReadReqEP(UsbHandle, EpAdd, UsbdCdc_EPOUT_buffer, CDC_EP_SIZE);
232  }
233  }
234  return LPC_OK;
235 }
236 
237 ErrorCode_t UsbdCdc_Bulk_IN_Hdlr(USBD_HANDLE_T hUsb, void* data, uint32_t event)
238 {
240 
241  if (event == USB_EVT_IN)
242  {
243  USBD_API->hw->WriteEP(UsbHandle, EpAdd, UsbdCdc_EPIN_buffer,UsbdCdc_EPIN_buffer_count);
244  /* Clear EP buffer */
245  UsbdCdc_EPIN_buffer_count = 0;
246  }
247  return LPC_OK;
248 }
249 
250 void UsbdCdc_EVENT_Stub(void* param)
251 {
252 
253 }
254 void EVENT_UsbdCdc_SetLineCode_Stub(CDC_LINE_CODING* line_coding)
255 {
256 
257 }
258 #endif /* USB_DEVICE_ROM_DRIVER */
259 
260 #endif /* USB_CAN_BE_DEVICE */