1 /******************************************************************************************************************************************
2 * 文件名称: usbh_cdc_core.c
3 * 功能说明:
4 * 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
5 * 注意事项:
6 * 版本日期: V1.1.0 2020年11月3日
7 * 升级记录:
8 *
9 *
10 *******************************************************************************************************************************************
11 * @attention
12 *
13 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
14 * REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
15 * FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
16 * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
17 * -ECTION WITH THEIR PRODUCTS.
18 *
19 * COPYRIGHT 2012 Synwit Technology
20 *******************************************************************************************************************************************/
21 #include <stdlib.h>
22 #include <string.h>
23 #include "SWM341.h"
24 #include "usbh_core.h"
25 #include "usbh_stdreq.h"
26 #include "usbh_cdc_core.h"
27 #include "usbh_cdc_funct.h"
28
29
30 USBH_Class_cb_t USBH_CDC_cb =
31 {
32 USBH_CDC_Init,
33 USBH_CDC_DeInit,
34 USBH_CDC_Request,
35 USBH_CDC_Process
36 };
37
38
39 volatile USBH_CDC_Info_t USBH_CDC_Info;
40
41
42 /******************************************************************************************************************************************
43 * 函数名称: USBH_CDC_Init()
44 * 功能说明:
45 * 输 入: 无
46 * 输 出: 无
47 * 注意事项: 无
48 ******************************************************************************************************************************************/
USBH_CDC_Init(USBH_Info_t * phost)49 USBH_Status USBH_CDC_Init(USBH_Info_t *phost)
50 {
51 USB_EpDesc_t *pEpIn, *pEpOut, *pEpCtrl;
52
53 if((phost->Device.Dev_Desc.bDeviceClass == USB_CDC_CLASS) &&
54 (phost->Device.Intf_Desc[0].bInterfaceClass == USB_CDC_CTRL_CLASS) &&
55 (phost->Device.Intf_Desc[1].bInterfaceClass == USB_CDC_DATA_CLASS))
56 {
57 pEpCtrl = &phost->Device.Ep_Desc[0][0];
58
59 if(phost->Device.Ep_Desc[1][0].bEndpointAddress & USB_EP_IN)
60 {
61 pEpIn = &phost->Device.Ep_Desc[1][0];
62 pEpOut = &phost->Device.Ep_Desc[1][1];
63 }
64 else
65 {
66 pEpIn = &phost->Device.Ep_Desc[1][1];
67 pEpOut = &phost->Device.Ep_Desc[1][0];
68 }
69
70 USBH_CDC_Info.InEp = pEpIn->bEndpointAddress;
71 USBH_CDC_Info.InEpSize = pEpIn->wMaxPacketSize;
72 USBH_CDC_Info.OutEp = pEpOut->bEndpointAddress;
73 USBH_CDC_Info.OutEpSize = pEpOut->wMaxPacketSize;
74 USBH_CDC_Info.CtrlEp = pEpCtrl->bEndpointAddress;
75 USBH_CDC_Info.CtrlEpSize = pEpCtrl->wMaxPacketSize;
76
77 USBH_CDC_DeInit(phost);
78 }
79 else
80 {
81 if(phost->usr_cb->DeviceNotSupported)
82 phost->usr_cb->DeviceNotSupported();
83
84 return USBH_NOT_SUPPORTED;
85 }
86
87 return USBH_OK;
88 }
89
90
91 /******************************************************************************************************************************************
92 * 函数名称: USBH_CDC_DeInit()
93 * 功能说明:
94 * 输 入: 无
95 * 输 出: 无
96 * 注意事项: 无
97 ******************************************************************************************************************************************/
USBH_CDC_DeInit(USBH_Info_t * phost)98 void USBH_CDC_DeInit(USBH_Info_t *phost)
99 {
100 USBH_CDC_Info.InEpDATAX = 0;
101 USBH_CDC_Info.OutEpDATAX = 0;
102 USBH_CDC_Info.CtrlEpDATAX = 0;
103
104 USBH_CDC_Info.TxWrPtr = 0;
105 USBH_CDC_Info.TxRdPtr = 0;
106 USBH_CDC_Info.RxWrPtr = 0;
107 USBH_CDC_Info.RxRdPtr = 0;
108
109 USBH_CDC_Info.state = USBH_CDC_SEND;
110 USBH_CDC_Info.reqState = CDC_GET_LINE_CODING;
111 }
112
113
114 /******************************************************************************************************************************************
115 * 函数名称: USBH_CDC_Request()
116 * 功能说明:
117 * 输 入: 无
118 * 输 出: 无
119 * 注意事项: 无
120 ******************************************************************************************************************************************/
USBH_CDC_Request(USBH_Info_t * phost)121 USBH_Status USBH_CDC_Request(USBH_Info_t *phost)
122 {
123 USBH_Status status = USBH_BUSY;
124 USBH_Status reqStatus;
125
126 switch(USBH_CDC_Info.reqState)
127 {
128 case CDC_SET_LINE_CODING:
129 reqStatus = USBH_CDC_SetLineCoding(phost);
130 if(reqStatus == USBH_OK)
131 {
132 USBH_CDC_Info.reqState = CDC_GET_LINE_CODING ;
133 }
134 if(reqStatus == USBH_NOT_SUPPORTED)
135 {
136 USBH_CDC_Info.reqState = CDC_CLR_STALL;
137 }
138 break;
139
140 case CDC_GET_LINE_CODING:
141 reqStatus = USBH_CDC_GetLineCoding(phost);
142 if(reqStatus == USBH_OK)
143 {
144 USBH_CDC_Info.reqState = CDC_SET_CONTROL_LINE;
145 }
146 break;
147
148 case CDC_SET_CONTROL_LINE:
149 reqStatus = USBH_CDC_SetControlLine(phost);
150 if(reqStatus == USBH_OK)
151 {
152 status = USBH_OK;
153 }
154 break;
155
156 case CDC_CLR_STALL:
157 reqStatus = USBH_ClrFeature(phost, 0);
158 if(reqStatus == USBH_OK )
159 {
160 phost->Ctrl.toggle_out = 0;
161
162 USBH_CDC_Info.reqState = CDC_GET_LINE_CODING ;
163 }
164 break;
165 }
166
167 return status;
168 }
169
170
171 /******************************************************************************************************************************************
172 * 函数名称: USBH_CDC_Process()
173 * 功能说明:
174 * 输 入: 无
175 * 输 出: 无
176 * 注意事项: 无
177 ******************************************************************************************************************************************/
USBH_CDC_Process(USBH_Info_t * phost)178 USBH_Status USBH_CDC_Process(USBH_Info_t *phost)
179 {
180 static uint32_t FrameNbr = 0;
181 static uint32_t size;
182 uint32_t available, space;
183 USBH_Status status = USBH_OK;
184 USBH_Resp resp;
185
186 switch(USBH_CDC_Info.state)
187 {
188 case USBH_CDC_SEND:
189 available = USBH_CDC_Info.TxWrPtr - USBH_CDC_Info.TxRdPtr;
190 if((available >= USBH_CDC_Info.OutEpSize) || ((available > 0) && (abs((int)USBH->FRAMENR - (int)USBH_CDC_Info.TxFrameNbr) > 10)))
191 {
192 USBH_CDC_Info.TxFrameNbr = USBH->FRAMENR;
193
194 size = (available > USBH_CDC_Info.OutEpSize) ? USBH_CDC_Info.OutEpSize : available;
195
196 if(USBH_SendOutPacket(phost->Device.Address, USBH_CDC_Info.OutEp, USBH_CDC_Info.OutEpDATAX, (uint8_t *)&USBH_CDC_Info.TxBuff[USBH_CDC_Info.TxRdPtr], size))
197 {
198 USBH_CDC_Info.state = USBH_CDC_SEND_WAIT;
199 }
200 }
201 else
202 {
203 USBH_CDC_Info.state = USBH_CDC_READ;
204 }
205 break;
206
207 case USBH_CDC_SEND_WAIT:
208 resp = USBH_State();
209 if(resp != USBR_NO)
210 {
211 if(resp == USBR_ACK)
212 {
213 USBH_CDC_Info.OutEpDATAX ^= 1;
214
215 USBH_CDC_Info.TxRdPtr += size;
216 if(USBH_CDC_Info.TxRdPtr == USBH_CDC_Info.TxWrPtr) // USBH_CDC_Info.TxBuff 中数据已全部发出
217 {
218 USBH_CDC_Info.TxRdPtr = 0;
219 USBH_CDC_Info.TxWrPtr = 0;
220 }
221 }
222
223 USBH_CDC_Info.state = USBH_CDC_READ;
224 }
225 break;
226
227 case USBH_CDC_READ:
228 space = USBH_CDC_BUFF_SIZE - USBH_CDC_Info.RxWrPtr;
229 if((space >= USBH_CDC_Info.InEpSize) && (abs((int)USBH->FRAMENR - (int)USBH_CDC_Info.TxFrameNbr) > 10))
230 {
231 USBH_CDC_Info.RxFrameNbr = USBH->FRAMENR;
232
233 if(USBH_SendInPacket(phost->Device.Address, USBH_CDC_Info.InEp, USBH_CDC_Info.InEpDATAX, USBH_CDC_Info.InEpSize))
234 {
235 USBH_CDC_Info.state = USBH_CDC_READ_WAIT;
236 }
237 }
238 break;
239
240 case USBH_CDC_READ_WAIT:
241 resp = USBH_State();
242 if(resp != USBR_NO)
243 {
244 if(resp == USBR_ACK)
245 {
246 USBH_CDC_Info.InEpDATAX ^= 1;
247
248 size = USBH_ReadRxBuffer((uint8_t *)&USBH_CDC_Info.RxBuff[USBH_CDC_Info.RxWrPtr], USBH_CDC_Info.InEpSize);
249 USBH_CDC_Info.RxWrPtr += size;
250 }
251
252 USBH_CDC_Info.state = USBH_CDC_SEND;
253 }
254 break;
255
256 case USBH_CDC_CTRL:
257 break;
258 }
259
260 return status;
261 }
262
263
264 /******************************************************************************************************************************************
265 * 函数名称: USBH_CDC_Process()
266 * 功能说明:
267 * 输 入: 无
268 * 输 出: 无
269 * 注意事项: 无
270 ******************************************************************************************************************************************/
USBH_CDC_Send(uint8_t * data,uint16_t size)271 uint32_t USBH_CDC_Send(uint8_t *data, uint16_t size)
272 {
273 uint16_t space = USBH_CDC_BUFF_SIZE - USBH_CDC_Info.TxWrPtr; // 可写入数据个数
274
275 if(space >= size)
276 {
277 __disable_irq();
278
279 memcpy((uint8_t *)&USBH_CDC_Info.TxBuff[USBH_CDC_Info.TxWrPtr], data, size);
280 USBH_CDC_Info.TxWrPtr += size;
281
282 __enable_irq();
283
284 return size;
285 }
286
287 return 0;
288 }
289
290
291 /******************************************************************************************************************************************
292 * 函数名称: USBH_CDC_Process()
293 * 功能说明:
294 * 输 入: 无
295 * 输 出: 无
296 * 注意事项: 无
297 ******************************************************************************************************************************************/
USBH_CDC_Read(uint8_t * buff,uint16_t size)298 uint32_t USBH_CDC_Read(uint8_t *buff, uint16_t size)
299 {
300 uint16_t available = USBH_CDC_Info.RxWrPtr - USBH_CDC_Info.RxRdPtr;
301
302 if(size > available)
303 size = available;
304
305 if(size)
306 {
307 __disable_irq();
308
309 memcpy(buff, (uint8_t *)&USBH_CDC_Info.RxBuff[USBH_CDC_Info.RxRdPtr], size);
310
311 USBH_CDC_Info.RxRdPtr += size;
312 if(USBH_CDC_Info.RxRdPtr == USBH_CDC_Info.RxWrPtr) // USBH_CDC_Info.RxBuff 中数据已全部读出
313 {
314 USBH_CDC_Info.RxRdPtr = 0;
315 USBH_CDC_Info.RxWrPtr = 0;
316 }
317
318 __enable_irq();
319 }
320
321 return size;
322 }
323