M480 BSP V3.05.005
The Board Support Package for M480 Series
cdc_core.c
Go to the documentation of this file.
1/**************************************************************************/
10#include <stdio.h>
11#include <string.h>
12#include <stdlib.h>
13
14#include "NuMicro.h"
15
16#include "usb.h"
17#include "usbh_lib.h"
18#include "usbh_cdc.h"
19
20
34#define USB_XFER_TIMEOUT 100
36
47{
48 uint32_t xfer_len;
49 int ret;
50
51 if (cdev == NULL)
53
54 if (cdev->iface_cdc == NULL)
56
57 ret = usbh_ctrl_xfer(cdev->udev,
58 REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE, /* bmRequestType */
59 CDC_GET_LINE_CODING, /* bRequest */
60 0, /* wValue */
61 cdev->iface_cdc->if_num, /* wIndex */
62 7, /* wLength */
63 (uint8_t *)line_code, /* data buffer */
64 &xfer_len, CDC_CMD_TIMEOUT);
65
66
67 if ((ret < 0) || (xfer_len != 7))
68 {
69 CDC_DBGMSG("GET_LINE_CODIN command failed. %d, %d\n", ret, xfer_len);
70 return ret;
71 }
72 return ret;
73}
74
75
86{
87 uint32_t xfer_len;
88 int ret;
89
90 if (cdev == NULL)
91 return USBH_ERR_NOT_FOUND;
92
93 if (cdev->iface_cdc == NULL)
94 return USBH_ERR_NOT_FOUND;
95
96 if ((line_code->stop_bits != 0) && (line_code->stop_bits != 1) &&
97 (line_code->stop_bits != 2))
99
100 if (line_code->parity > 4)
102
103 if ((line_code->data_bits != 5) && (line_code->data_bits != 6) &&
104 (line_code->data_bits != 7) && (line_code->data_bits != 8) &&
105 (line_code->data_bits != 16))
107
108 ret = usbh_ctrl_xfer(cdev->udev,
109 REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE, /* bmRequestType */
110 CDC_SET_LINE_CODING, /* bRequest */
111 0, /* wValue */
112 cdev->iface_cdc->if_num, /* wIndex */
113 7, /* wLength */
114 (uint8_t *)line_code, /* data buffer */
115 &xfer_len, CDC_CMD_TIMEOUT);
116
117 if (ret < 0)
118 {
119 CDC_DBGMSG("SET_LINE_CODIN command failed. %d\n", ret);
120 return ret;
121 }
122 return 0;
123}
124
135int32_t usbh_cdc_set_control_line_state(CDC_DEV_T *cdev, int active_carrier, int DTE_present)
136{
137 uint32_t xfer_len;
138 int ret;
139 uint16_t ctrl_bitmap = 0;
140
141 if (cdev == NULL)
143
144 if (cdev->iface_cdc == NULL)
146
147 if (active_carrier)
148 ctrl_bitmap |= 0x02;
149
150 if (DTE_present)
151 ctrl_bitmap |= 0x01;
152
153 ret = usbh_ctrl_xfer(cdev->udev,
154 REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE, /* bmRequestType */
155 CDC_SET_CONTROL_LINE_STATE, /* bRequest */
156 ctrl_bitmap, /* wValue */
157 cdev->iface_cdc->if_num, /* wIndex */
158 0, /* wLength */
159 NULL, /* data buffer */
160 &xfer_len, CDC_CMD_TIMEOUT);
161
162
163 if (ret)
164 {
165 CDC_DBGMSG("SET_CONTROL_LINE_STATE command failed. %d\n", ret);
166 return ret;
167 }
168 return ret;
169}
170
172/*
173 * CDC INT-in complete function
174 */
175static void cdc_int_in_irq(UTR_T *utr)
176{
177 CDC_DEV_T *cdev;
178 int ret;
179
180 //CDC_DBGMSG("cdc_int_in_irq. %d\n", utr->xfer_len);
181
182 cdev = (CDC_DEV_T *)utr->context;
183
184 if (utr->status)
185 {
186 CDC_DBGMSG("cdc_int_in_irq - has error: 0x%x\n", utr->status);
187 return;
188 }
189
190 if (cdev->sts_func && utr->xfer_len)
191 cdev->sts_func(cdev, utr->buff, utr->xfer_len);
192
193 utr->xfer_len = 0;
194 ret = usbh_int_xfer(utr);
195 if (ret)
196 {
197 CDC_DBGMSG("cdc_int_in_irq - failed to submit interrupt-in request (%d)", ret);
198 free_utr(utr);
199 cdev->utr_sts = NULL;
200 }
201}
202
204
214{
215 EP_INFO_T *ep;
216 UTR_T *utr;
217 int ret;
218
219 if ((cdev == NULL) || (cdev->iface_cdc == NULL))
220 return USBH_ERR_NOT_FOUND;
221
222 if (!func || cdev->utr_sts)
224
225 ep = cdev->ep_sts;
226 if (ep == NULL)
227 {
228 ep = usbh_iface_find_ep(cdev->iface_cdc, 0, EP_ADDR_DIR_IN | EP_ATTR_TT_INT);
229 if (ep == NULL)
230 {
231 CDC_DBGMSG("Interrupt-in endpoint not found in this CDC device!\n");
233 }
234 cdev->ep_sts = ep;
235 }
236
237 utr = alloc_utr(cdev->udev);
238 if (utr == NULL)
239 {
240 CDC_DBGMSG("Failed to allocated UTR!\n");
241 return USBH_ERR_MEMORY_OUT;
242 }
243
244 utr->buff = (uint8_t *)cdev->sts_buff;
245 utr->context = cdev;
246 utr->ep = ep;
247 utr->data_len = ep->wMaxPacketSize;
248 if (utr->data_len > CDC_STATUS_BUFF_SIZE)
249 {
250 CDC_DBGMSG("Warning! CDC_STATUS_BUFF_SIZE %d is smaller than max. packet size %d!\n", CDC_STATUS_BUFF_SIZE, ep->wMaxPacketSize);
251 utr->data_len = CDC_STATUS_BUFF_SIZE;
252 }
253 utr->xfer_len = 0;
254 utr->func = cdc_int_in_irq;
255
256 cdev->utr_sts = utr;
257 cdev->sts_func = func;
258
259 ret = usbh_int_xfer(utr);
260 if (ret < 0)
261 {
262 CDC_DBGMSG("Error - failed to submit interrupt read request (%d)", ret);
263 free_utr(utr);
264 cdev->utr_sts = NULL;
265 return ret;
266 }
267
268 return 0;
269}
271/*
272 * CDC BULK-in complete function
273 */
274static void cdc_bulk_in_irq(UTR_T *utr)
275{
276 CDC_DEV_T *cdev;
277
278 //CDC_DBGMSG("cdc_bulk_in_irq. %d\n", utr->xfer_len);
279
280 cdev = (CDC_DEV_T *)utr->context;
281
282 if (utr->status)
283 {
284 CDC_DBGMSG("cdc_bulk_in_irq - has error: 0x%x\n", utr->status);
285 return;
286 }
287
288 if (cdev->rx_func)
289 cdev->rx_func(cdev, utr->buff, utr->xfer_len);
290
291 free_utr(utr);
292 cdev->utr_rx = NULL;
293 cdev->rx_busy = 0;
294}
295
297
307{
308 EP_INFO_T *ep;
309 UTR_T *utr;
310 int ret;
311
312 if ((cdev == NULL) || (cdev->iface_data == NULL))
313 return USBH_ERR_NOT_FOUND;
314
315 if (!func)
317
318 ep = cdev->ep_rx;
319 if (ep == NULL)
320 {
321 ep = usbh_iface_find_ep(cdev->iface_data, 0, EP_ADDR_DIR_IN | EP_ATTR_TT_BULK);
322 if (ep == NULL)
323 {
324 CDC_DBGMSG("Bulk-in endpoint not found in this CDC device!\n");
326 }
327 cdev->ep_rx = ep;
328 }
329
330 utr = alloc_utr(cdev->udev);
331 if (utr == NULL)
332 {
333 CDC_DBGMSG("Failed to allocated UTR!\n");
334 return USBH_ERR_MEMORY_OUT;
335 }
336
337 utr->buff = (uint8_t *)cdev->rx_buff;
338 utr->context = cdev;
339 utr->ep = ep;
340 utr->data_len = ep->wMaxPacketSize;
341 if (utr->data_len > CDC_RX_BUFF_SIZE)
342 {
343 CDC_DBGMSG("Warning! CDC_RX_BUFF_SIZE %d is smaller than max. packet size %d!\n", CDC_RX_BUFF_SIZE, ep->wMaxPacketSize);
344 utr->data_len = CDC_RX_BUFF_SIZE;
345 }
346 utr->xfer_len = 0;
347 utr->func = cdc_bulk_in_irq;
348
349 cdev->rx_func = func;
350 cdev->utr_rx = utr;
351 cdev->rx_busy = 1;
352
353 ret = usbh_bulk_xfer(utr);
354 if (ret < 0)
355 {
356 CDC_DBGMSG("Error - failed to submit bulk in request (%d)", ret);
357 free_utr(utr);
358 cdev->utr_rx = NULL;
359 cdev->rx_busy = 0;
360 return ret;
361 }
362 return 0;
363}
365/*
366 * CDC BULK-in complete function
367 */
368static volatile int bulk_out_done;
369static void cdc_bulk_out_irq(UTR_T *utr)
370{
371 bulk_out_done = 1;
372}
374
383int32_t usbh_cdc_send_data(CDC_DEV_T *cdev, uint8_t *buff, int buff_len)
384{
385 EP_INFO_T *ep;
386 UTR_T *utr;
387 uint32_t t0;
388 int ret;
389
390 if ((cdev == NULL) || (cdev->iface_data == NULL))
391 return USBH_ERR_NOT_FOUND;
392
393 ep = cdev->ep_tx;
394 if (ep == NULL)
395 {
396 ep = usbh_iface_find_ep(cdev->iface_data, 0, EP_ADDR_DIR_OUT | EP_ATTR_TT_BULK);
397 if (ep == NULL)
398 {
399 CDC_DBGMSG("Bulk-out endpoint not found in this CDC device!\n");
401 }
402 cdev->ep_tx = ep;
403 }
404
405 utr = alloc_utr(cdev->udev);
406 if (utr == NULL)
407 {
408 CDC_DBGMSG("Failed to allocated UTR!\n");
409 return USBH_ERR_MEMORY_OUT;
410 }
411
412 utr->context = cdev;
413 utr->ep = ep;
414 utr->buff = buff;
415 utr->data_len = buff_len;
416 utr->xfer_len = 0;
417 utr->func = cdc_bulk_out_irq;
418 bulk_out_done = 0;
419
420 ret = usbh_bulk_xfer(utr);
421 if (ret < 0)
422 {
423 CDC_DBGMSG("Error - failed to submit bulk in request (%d)", ret);
424 free_utr(utr);
425 return ret;
426 }
427
428 t0 = get_ticks();
429 while (bulk_out_done == 0)
430 {
431 if (get_ticks() - t0 > USB_XFER_TIMEOUT)
432 {
433 usbh_quit_utr(utr);
434 free_utr(utr);
435 return USBH_ERR_TIMEOUT;
436 }
437 }
438
439 free_utr(utr);
440 return 0;
441}
442 /* end of group USBH_EXPORTED_FUNCTIONS */
444 /* end of group USBH_Library */
446 /* end of group Library */
448
449
450/*** (C) COPYRIGHT 2018~2019 Nuvoton Technology Corp. ***/
451
452
NuMicro peripheral access layer header file.
#define NULL
NULL pointer.
Definition: M480.h:605
#define USBH_ERR_TIMEOUT
Definition: usbh_lib.h:46
#define USBH_ERR_EP_NOT_FOUND
Definition: usbh_lib.h:40
#define USBH_ERR_INVALID_PARAM
Definition: usbh_lib.h:38
#define USBH_ERR_NOT_FOUND
Definition: usbh_lib.h:39
#define USBH_ERR_MEMORY_OUT
Definition: usbh_lib.h:32
int32_t usbh_cdc_start_to_receive_data(struct cdc_dev_t *cdev, CDC_CB_FUNC *func)
Make CDC device start to receive data from bulk-in transfer pipe.
Definition: cdc_core.c:306
int32_t usbh_cdc_set_line_coding(CDC_DEV_T *cdev, LINE_CODING_T *line_code)
SET_LINE_CODING request.
Definition: cdc_core.c:85
HIDDEN_SYMBOLS int32_t usbh_cdc_set_control_line_state(struct cdc_dev_t *cdev, int active_carrier, int DTE_present)
SET_CONTROL_LINE_STATE request.
Definition: cdc_core.c:135
int32_t usbh_cdc_send_data(struct cdc_dev_t *cdev, uint8_t *buff, int buff_len)
Send a block of data via CDC device's bulk-out transfer pipe.
Definition: cdc_core.c:383
int32_t usbh_cdc_start_polling_status(struct cdc_dev_t *cdev, CDC_CB_FUNC *func)
Start purge the CDC device's interrupt-in transfer pipe.
Definition: cdc_core.c:213
int32_t usbh_cdc_get_line_coding(CDC_DEV_T *cdev, LINE_CODING_T *line_code)
GET_LINE_CODING request.
Definition: cdc_core.c:46
uint32_t get_ticks(void)
A function return current tick count.
LINE_CODING_T
Definition: usbh_cdc.h:169
uint8_t rx_busy
Definition: usbh_cdc.h:190
IFACE_T * iface_data
Definition: usbh_cdc.h:179
uint32_t sts_buff[CDC_STATUS_BUFF_SIZE/4]
Definition: usbh_cdc.h:186
CDC_CB_FUNC * sts_func
Definition: usbh_cdc.h:188
UDEV_T * udev
Definition: usbh_cdc.h:177
IFACE_T * iface_cdc
Definition: usbh_cdc.h:178
UTR_T * utr_sts
Definition: usbh_cdc.h:184
EP_INFO_T * ep_rx
Definition: usbh_cdc.h:182
EP_INFO_T * ep_tx
Definition: usbh_cdc.h:183
uint32_t rx_buff[CDC_RX_BUFF_SIZE/4]
Definition: usbh_cdc.h:187
UTR_T * utr_rx
Definition: usbh_cdc.h:185
CDC_CB_FUNC * rx_func
Definition: usbh_cdc.h:189
EP_INFO_T * ep_sts
Definition: usbh_cdc.h:181
void() CDC_CB_FUNC(struct cdc_dev_t *cdev, uint8_t *rdata, int data_len)
Definition: usbh_lib.h:120
USB Host library header file.
USB Host CDC(Communication Device Class) driver header file.
USB Host library exported header file.