| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

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) __BSS(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) __BSS(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) __BSS(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;
113 cdc_param.cif_intf_desc = (uint8_t*)CALLBACK_UsbdCdc_Register_ControlInterfaceDescriptor();
114 cdc_param.dif_intf_desc = (uint8_t*)CALLBACK_UsbdCdc_Register_DataInterfaceDescriptor();
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
172 void UsbdCdc_IO_Buffer_Sync_Task(void)
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 {
219 uint8_t EpAdd = USB_ENDPOINT_OUT(CALLBACK_UsbdCdc_Register_DataOutEndpointNumber());
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 {
239 uint8_t EpAdd = USB_ENDPOINT_IN(CALLBACK_UsbdCdc_Register_DataInEndpointNumber());
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 */