• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022, sakumisu
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include "usbd_core.h"
7 #include "usbd_cdc.h"
8 
9 const char *stop_name[] = { "1", "1.5", "2" };
10 const char *parity_name[] = { "N", "O", "E", "M", "S" };
11 
cdc_acm_class_interface_request_handler(struct usb_setup_packet * setup,uint8_t ** data,uint32_t * len)12 static int cdc_acm_class_interface_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
13 {
14     USB_LOG_DBG("CDC Class request: "
15                 "bRequest 0x%02x\r\n",
16                 setup->bRequest);
17 
18     struct cdc_line_coding line_coding;
19     bool dtr, rts;
20     uint8_t intf_num = LO_BYTE(setup->wIndex);
21 
22     switch (setup->bRequest) {
23         case CDC_REQUEST_SET_LINE_CODING:
24 
25             /*******************************************************************************/
26             /* Line Coding Structure                                                       */
27             /*-----------------------------------------------------------------------------*/
28             /* Offset | Field       | Size | Value  | Description                          */
29             /* 0      | dwDTERate   |   4  | Number |Data terminal rate, in bits per second*/
30             /* 4      | bCharFormat |   1  | Number | Stop bits                            */
31             /*                                        0 - 1 Stop bit                       */
32             /*                                        1 - 1.5 Stop bits                    */
33             /*                                        2 - 2 Stop bits                      */
34             /* 5      | bParityType |  1   | Number | Parity                               */
35             /*                                        0 - None                             */
36             /*                                        1 - Odd                              */
37             /*                                        2 - Even                             */
38             /*                                        3 - Mark                             */
39             /*                                        4 - Space                            */
40             /* 6      | bDataBits  |   1   | Number Data bits (5, 6, 7, 8 or 16).          */
41             /*******************************************************************************/
42             memcpy(&line_coding, *data, setup->wLength);
43             USB_LOG_DBG("Set intf:%d linecoding <%d %d %s %s>\r\n",
44                         intf_num,
45                         line_coding.dwDTERate,
46                         line_coding.bDataBits,
47                         parity_name[line_coding.bParityType],
48                         stop_name[line_coding.bCharFormat]);
49 
50             usbd_cdc_acm_set_line_coding(intf_num, &line_coding);
51             break;
52 
53         case CDC_REQUEST_SET_CONTROL_LINE_STATE:
54             dtr = (setup->wValue & 0x0001);
55             rts = (setup->wValue & 0x0002);
56             USB_LOG_DBG("Set intf:%d DTR 0x%x,RTS 0x%x\r\n",
57                         intf_num,
58                         dtr,
59                         rts);
60             usbd_cdc_acm_set_dtr(intf_num, dtr);
61             usbd_cdc_acm_set_rts(intf_num, rts);
62             break;
63 
64         case CDC_REQUEST_GET_LINE_CODING:
65             usbd_cdc_acm_get_line_coding(intf_num, &line_coding);
66             memcpy(*data, &line_coding, 7);
67             *len = 7;
68             USB_LOG_DBG("Get intf:%d linecoding %d %d %d %d\r\n",
69                         intf_num,
70                         line_coding.dwDTERate,
71                         line_coding.bCharFormat,
72                         line_coding.bParityType,
73                         line_coding.bDataBits);
74             break;
75         case CDC_REQUEST_SEND_BREAK:
76             usbd_cdc_acm_send_break(intf_num);
77             break;
78         default:
79             USB_LOG_WRN("Unhandled CDC Class bRequest 0x%02x\r\n", setup->bRequest);
80             return -1;
81     }
82 
83     return 0;
84 }
85 
usbd_cdc_acm_init_intf(struct usbd_interface * intf)86 struct usbd_interface *usbd_cdc_acm_init_intf(struct usbd_interface *intf)
87 {
88     intf->class_interface_handler = cdc_acm_class_interface_request_handler;
89     intf->class_endpoint_handler = NULL;
90     intf->vendor_handler = NULL;
91     intf->notify_handler = NULL;
92 
93     return intf;
94 }
95 
usbd_cdc_acm_set_line_coding(uint8_t intf,struct cdc_line_coding * line_coding)96 __WEAK void usbd_cdc_acm_set_line_coding(uint8_t intf, struct cdc_line_coding *line_coding)
97 {
98 }
99 
usbd_cdc_acm_get_line_coding(uint8_t intf,struct cdc_line_coding * line_coding)100 __WEAK void usbd_cdc_acm_get_line_coding(uint8_t intf, struct cdc_line_coding *line_coding)
101 {
102     line_coding->dwDTERate = 2000000;
103     line_coding->bDataBits = 8;
104     line_coding->bParityType = 0;
105     line_coding->bCharFormat = 0;
106 }
107 
usbd_cdc_acm_set_dtr(uint8_t intf,bool dtr)108 __WEAK void usbd_cdc_acm_set_dtr(uint8_t intf, bool dtr)
109 {
110 }
111 
usbd_cdc_acm_set_rts(uint8_t intf,bool rts)112 __WEAK void usbd_cdc_acm_set_rts(uint8_t intf, bool rts)
113 {
114 }
115 
usbd_cdc_acm_send_break(uint8_t intf)116 __WEAK void usbd_cdc_acm_send_break(uint8_t intf)
117 {
118 }
119