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