ARMEBS4  revision-26.06.2015
stm32_usbd_cdc.c
1 #include "heivs/config.h"
2 #if (USE_STM32_USB_HOST_MODE || USE_STM32_USB_USE_DEVICE_MODE || USE_STM32_USB_OTG_MODE)
3 /**
4  * \file heivs/stm32_usbd_cdc.c
5  * \see heivs/stm32_usbd_cdc.h
6  */
7 
8 #include "config/usb_conf.h"
9 #if defined(USE_DEVICE_MODE)
10 
11 #include "heivs/stm32_usbd_cdc.h"
12 #include "heivs/time.h"
13 
14 #include "stm32/usb/usbd_cdc_core.h"
15 #include "stm32/usb/usb_core.h"
16 #include "stm32/usb/usbd_usr.h"
17 #include "stm32/usb/usbd_desc.h"
18 #include "stm32/usb/usb_dcd_int.h"
19 #include "stm32/usb/usb_hcd_int.h"
20 
21 #include <string.h>
22 
23 static uint16_t cdc_init(void)
24 {
25  return USBD_OK;
26 }
27 
28 static uint16_t cdc_deinit(void)
29 {
30  return USBD_OK;
31 }
32 
33 static uint16_t cdc_ctrl(uint32_t cmd, const uint8_t* buf, uint32_t len)
34 {
35  (void)cmd;
36  (void)buf;
37  (void)len;
38 
39  return USBD_OK;
40 }
41 
42 static status_e(*cdc_user_rx)(USB_OTG_CORE_HANDLE *dev, const uint32_t *buffer, size_t len);
43 
44 static uint16_t cdc_rx(const uint32_t* buf, uint32_t len)
45 {
46  cdc_user_rx(&USB_OTG_Core, buf, len);
47 
48  return USBD_OK;
49 }
50 
51 enum state_e
52 {
53  STATE_IDLE = 0x00,
54  STATE_SENDING = 0x01,
55 };
56 
57 static volatile enum state_e state;
58 
59 static uint16_t cdc_data_tx_emtpy(void)
60 {
61  state = STATE_IDLE;
62  return USBD_OK;
63 }
64 
65 const CDC_IF_Prop_TypeDef APP_FOPS =
66 {
67  .pIf_Init = cdc_init,
68  .pIf_DeInit = cdc_deinit,
69  .pIf_Ctrl = cdc_ctrl,
70  .pIf_DataRx = cdc_rx,
71  .pIf_DataTxEmpty = cdc_data_tx_emtpy,
72 };
73 
74 static void do_nothing(void)
75 {
76 
77 }
78 
79 static void do_nothing_u8(uint8_t _unused)
80 {
81  (void)_unused;
82 }
83 
84 static USBD_Usr_cb_TypeDef default_USR_cb =
85 {
86  .Init = do_nothing,
87  .DeviceReset = do_nothing_u8,
88  .DeviceConfigured = do_nothing,
89  .DeviceSuspended = do_nothing,
90  .DeviceResumed = do_nothing,
91 
92  .DeviceConnected = do_nothing,
93  .DeviceDisconnected = do_nothing,
94 };
95 
96 status_e usbd_cdc_init(usbd_cdc_rx_t rx, USBD_Usr_cb_TypeDef *usr_cb)
97 {
98  if (rx == NULL)
99  {
100  return ERROR_BAD_PARAM;
101  }
102 
103  if (!usr_cb)
104  {
105  usr_cb = &default_USR_cb;
106  }
107 
108  state = STATE_IDLE;
109 
110  cdc_user_rx = rx;
111 
112  USBD_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_CDC_cb, usr_cb);
113 
114  return NO_ERROR;
115 }
116 
117 const uint32_t max_size = 0x10000;
118 size_t usbd_cdc_tx_nowait_maxsize(void)
119 {
120  return max_size;
121 }
122 
123 status_e usbd_cdc_tx(const void *data, size_t len, enum usb_cdc_wait_e wait)
124 {
125  timeout_t timeout;
126 
127  if (wait == WAIT_NO_WAIT && state != STATE_IDLE)
128  {
129  return ERROR_AGAIN;
130  }
131 
132  timeout = time_set_timeout_ms(1000);
133  while (state == STATE_SENDING)
134  {
135  if (time_elapsed(timeout))
136  {
137  return ERROR_TIMEOUT;
138  }
139  }
140 
141  /**
142  * FIXME
143  * There is somewhere in the USB stack a size limit. It should be
144  * better to fix it in the USB stack, but let's workaround here.
145  */
146  if (len > max_size && wait == WAIT_NO_WAIT)
147  {
148  return ERROR_BAD_PARAM;
149  }
150 
151  while (len > max_size)
152  {
153  state = STATE_SENDING;
154  DCD_EP_Tx(&USB_OTG_Core, CDC_IN_EP, (void *)data, max_size);
155 
156  timeout = time_set_timeout_ms(1000);
157  while (state == STATE_SENDING)
158  {
159  if (time_elapsed(timeout))
160  {
161  return ERROR_TIMEOUT;
162  }
163  }
164  data += max_size;
165  len -= max_size;
166  }
167 
168  state = STATE_SENDING;
169  DCD_EP_Tx(&USB_OTG_Core, CDC_IN_EP, (void *)data, len);
170  if (!(wait & WAIT_TX_FINISHED))
171  {
172  return NO_ERROR;
173  }
174 
175  timeout = time_set_timeout_ms(1000);
176  while (state == STATE_SENDING)
177  {
178  if (time_elapsed(timeout))
179  {
180  return ERROR_TIMEOUT;
181  }
182  }
183 
184  return NO_ERROR;
185 }
186 #endif
187 #endif /* (USE_STM32_USB_HOST_MODE || USE_STM32_USB_USE_DEVICE_MODE || USE_STM32_USB_OTG_MODE) */
No comment.
Definition: error.h:64
simple time abstraction
libheivs configuration file
static uint32_t time_elapsed(timeout_t timeout)
Is this time passed?
Definition: time.h:71
USB device CDC (virtural com port) interface.
Parameter unsupported.
Definition: error.h:56
Retry later.
Definition: error.h:49
Timeout structure.
Definition: time.h:34
timeout_t time_set_timeout_ms(uint32_t ms)
Set an obscure time at least ms milliseconds in the future.
Definition: time.c:15
status_e
Known errors.
Definition: error.h:21
No error.
Definition: error.h:28