ChibiOS/HAL  6.1.0
hal_serial_usb.c
Go to the documentation of this file.
1 /*
2  ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16 
17 /**
18  * @file hal_serial_usb.c
19  * @brief Serial over USB Driver code.
20  *
21  * @addtogroup SERIAL_USB
22  * @{
23  */
24 
25 #include "hal.h"
26 
27 #if (HAL_USE_SERIAL_USB == TRUE) || defined(__DOXYGEN__)
28 
29 /*===========================================================================*/
30 /* Driver local definitions. */
31 /*===========================================================================*/
32 
33 /*===========================================================================*/
34 /* Driver exported variables. */
35 /*===========================================================================*/
36 
37 /*===========================================================================*/
38 /* Driver local variables and types. */
39 /*===========================================================================*/
40 
41 /*
42  * Current Line Coding.
43  */
44 static cdc_linecoding_t linecoding = {
45  {0x00, 0x96, 0x00, 0x00}, /* 38400. */
46  LC_STOP_1, LC_PARITY_NONE, 8
47 };
48 
49 /*===========================================================================*/
50 /* Driver local functions. */
51 /*===========================================================================*/
52 
53 static bool sdu_start_receive(SerialUSBDriver *sdup) {
54  uint8_t *buf;
55 
56  /* If the USB driver is not in the appropriate state then transactions
57  must not be started.*/
58  if ((usbGetDriverStateI(sdup->config->usbp) != USB_ACTIVE) ||
59  (sdup->state != SDU_READY)) {
60  return true;
61  }
62 
63  /* Checking if there is already a transaction ongoing on the endpoint.*/
64  if (usbGetReceiveStatusI(sdup->config->usbp, sdup->config->bulk_in)) {
65  return true;
66  }
67 
68  /* Checking if there is a buffer ready for incoming data.*/
69  buf = ibqGetEmptyBufferI(&sdup->ibqueue);
70  if (buf == NULL) {
71  return true;
72  }
73 
74  /* Buffer found, starting a new transaction.*/
75  usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out,
77 
78  return false;
79 }
80 
81 /*
82  * Interface implementation.
83  */
84 
85 static size_t _write(void *ip, const uint8_t *bp, size_t n) {
86 
87  return obqWriteTimeout(&((SerialUSBDriver *)ip)->obqueue, bp,
88  n, TIME_INFINITE);
89 }
90 
91 static size_t _read(void *ip, uint8_t *bp, size_t n) {
92 
93  return ibqReadTimeout(&((SerialUSBDriver *)ip)->ibqueue, bp,
94  n, TIME_INFINITE);
95 }
96 
97 static msg_t _put(void *ip, uint8_t b) {
98 
99  return obqPutTimeout(&((SerialUSBDriver *)ip)->obqueue, b, TIME_INFINITE);
100 }
101 
102 static msg_t _get(void *ip) {
103 
104  return ibqGetTimeout(&((SerialUSBDriver *)ip)->ibqueue, TIME_INFINITE);
105 }
106 
107 static msg_t _putt(void *ip, uint8_t b, sysinterval_t timeout) {
108 
109  return obqPutTimeout(&((SerialUSBDriver *)ip)->obqueue, b, timeout);
110 }
111 
112 static msg_t _gett(void *ip, sysinterval_t timeout) {
113 
114  return ibqGetTimeout(&((SerialUSBDriver *)ip)->ibqueue, timeout);
115 }
116 
117 static size_t _writet(void *ip, const uint8_t *bp, size_t n,
118  sysinterval_t timeout) {
119 
120  return obqWriteTimeout(&((SerialUSBDriver *)ip)->obqueue, bp, n, timeout);
121 }
122 
123 static size_t _readt(void *ip, uint8_t *bp, size_t n,
124  sysinterval_t timeout) {
125 
126  return ibqReadTimeout(&((SerialUSBDriver *)ip)->ibqueue, bp, n, timeout);
127 }
128 
129 static msg_t _ctl(void *ip, unsigned int operation, void *arg) {
130  SerialUSBDriver *sdup = (SerialUSBDriver *)ip;
131 
132  osalDbgCheck(sdup != NULL);
133 
134  switch (operation) {
135  case CHN_CTL_NOP:
136  osalDbgCheck(arg == NULL);
137  break;
138  case CHN_CTL_INVALID:
139  osalDbgAssert(false, "invalid CTL operation");
140  break;
141  default:
142 #if defined(SDU_LLD_IMPLEMENTS_CTL)
143  /* The SDU driver does not have a LLD but the application can use this
144  hook to implement extra controls by supplying this function.*/
145  extern msg_t sdu_lld_control(SerialUSBDriver *sdup,
146  unsigned int operation,
147  void *arg);
148  return sdu_lld_control(sdup, operation, arg);
149 #else
150  break;
151 #endif
152  }
153  return MSG_OK;
154 }
155 
156 static const struct SerialUSBDriverVMT vmt = {
157  (size_t)0,
158  _write, _read, _put, _get,
159  _putt, _gett, _writet, _readt,
160  _ctl
161 };
162 
163 /**
164  * @brief Notification of empty buffer released into the input buffers queue.
165  *
166  * @param[in] bqp the buffers queue pointer.
167  */
168 static void ibnotify(io_buffers_queue_t *bqp) {
169  SerialUSBDriver *sdup = bqGetLinkX(bqp);
170  (void) sdu_start_receive(sdup);
171 }
172 
173 /**
174  * @brief Notification of filled buffer inserted into the output buffers queue.
175  *
176  * @param[in] bqp the buffers queue pointer.
177  */
178 static void obnotify(io_buffers_queue_t *bqp) {
179  size_t n;
180  SerialUSBDriver *sdup = bqGetLinkX(bqp);
181 
182  /* If the USB driver is not in the appropriate state then transactions
183  must not be started.*/
184  if ((usbGetDriverStateI(sdup->config->usbp) != USB_ACTIVE) ||
185  (sdup->state != SDU_READY)) {
186  return;
187  }
188 
189  /* Checking if there is already a transaction ongoing on the endpoint.*/
190  if (!usbGetTransmitStatusI(sdup->config->usbp, sdup->config->bulk_in)) {
191  /* Trying to get a full buffer.*/
192  uint8_t *buf = obqGetFullBufferI(&sdup->obqueue, &n);
193  if (buf != NULL) {
194  /* Buffer found, starting a new transaction.*/
195  usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in, buf, n);
196  }
197  }
198 }
199 
200 /*===========================================================================*/
201 /* Driver exported functions. */
202 /*===========================================================================*/
203 
204 /**
205  * @brief Serial Driver initialization.
206  * @note This function is implicitly invoked by @p halInit(), there is
207  * no need to explicitly initialize the driver.
208  *
209  * @init
210  */
211 void sduInit(void) {
212 }
213 
214 /**
215  * @brief Initializes a generic full duplex driver object.
216  * @details The HW dependent part of the initialization has to be performed
217  * outside, usually in the hardware initialization code.
218  *
219  * @param[out] sdup pointer to a @p SerialUSBDriver structure
220  *
221  * @init
222  */
224 
225  sdup->vmt = &vmt;
226  osalEventObjectInit(&sdup->event);
227  sdup->state = SDU_STOP;
228  ibqObjectInit(&sdup->ibqueue, true, sdup->ib,
230  ibnotify, sdup);
231  obqObjectInit(&sdup->obqueue, true, sdup->ob,
233  obnotify, sdup);
234 }
235 
236 /**
237  * @brief Configures and starts the driver.
238  *
239  * @param[in] sdup pointer to a @p SerialUSBDriver object
240  * @param[in] config the serial over USB driver configuration
241  *
242  * @api
243  */
244 void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config) {
245  USBDriver *usbp = config->usbp;
246 
247  osalDbgCheck(sdup != NULL);
248 
249  osalSysLock();
250  osalDbgAssert((sdup->state == SDU_STOP) || (sdup->state == SDU_READY),
251  "invalid state");
252  usbp->in_params[config->bulk_in - 1U] = sdup;
253  usbp->out_params[config->bulk_out - 1U] = sdup;
254  if (config->int_in > 0U) {
255  usbp->in_params[config->int_in - 1U] = sdup;
256  }
257  sdup->config = config;
258  sdup->state = SDU_READY;
259  osalSysUnlock();
260 }
261 
262 /**
263  * @brief Stops the driver.
264  * @details Any thread waiting on the driver's queues will be awakened with
265  * the message @p MSG_RESET.
266  *
267  * @param[in] sdup pointer to a @p SerialUSBDriver object
268  *
269  * @api
270  */
272  USBDriver *usbp = sdup->config->usbp;
273 
274  osalDbgCheck(sdup != NULL);
275 
276  osalSysLock();
277 
278  osalDbgAssert((sdup->state == SDU_STOP) || (sdup->state == SDU_READY),
279  "invalid state");
280 
281  /* Driver in stopped state.*/
282  usbp->in_params[sdup->config->bulk_in - 1U] = NULL;
283  usbp->out_params[sdup->config->bulk_out - 1U] = NULL;
284  if (sdup->config->int_in > 0U) {
285  usbp->in_params[sdup->config->int_in - 1U] = NULL;
286  }
287  sdup->config = NULL;
288  sdup->state = SDU_STOP;
289 
290  /* Enforces a disconnection.*/
292  ibqResetI(&sdup->ibqueue);
293  obqResetI(&sdup->obqueue);
295 
296  osalSysUnlock();
297 }
298 
299 /**
300  * @brief USB device suspend handler.
301  * @details Generates a @p CHN_DISCONNECT event and puts queues in
302  * non-blocking mode, this way the application cannot get stuck
303  * in the middle of an I/O operations.
304  * @note If this function is not called from an ISR then an explicit call
305  * to @p osalOsRescheduleS() in necessary afterward.
306  *
307  * @param[in] sdup pointer to a @p SerialUSBDriver object
308  *
309  * @iclass
310  */
312 
314  bqSuspendI(&sdup->ibqueue);
315  bqSuspendI(&sdup->obqueue);
316 }
317 
318 /**
319  * @brief USB device wakeup handler.
320  * @details Generates a @p CHN_CONNECT event and resumes normal queues
321  * operations.
322  *
323  * @note If this function is not called from an ISR then an explicit call
324  * to @p osalOsRescheduleS() in necessary afterward.
325  *
326  * @param[in] sdup pointer to a @p SerialUSBDriver object
327  *
328  * @iclass
329  */
331 
333  bqResumeX(&sdup->ibqueue);
334  bqResumeX(&sdup->obqueue);
335 }
336 
337 /**
338  * @brief USB device configured handler.
339  *
340  * @param[in] sdup pointer to a @p SerialUSBDriver object
341  *
342  * @iclass
343  */
345 
346  ibqResetI(&sdup->ibqueue);
347  bqResumeX(&sdup->ibqueue);
348  obqResetI(&sdup->obqueue);
349  bqResumeX(&sdup->obqueue);
351  (void) sdu_start_receive(sdup);
352 }
353 
354 /**
355  * @brief Default requests hook.
356  * @details Applications wanting to use the Serial over USB driver can use
357  * this function as requests hook in the USB configuration.
358  * The following requests are emulated:
359  * - CDC_GET_LINE_CODING.
360  * - CDC_SET_LINE_CODING.
361  * - CDC_SET_CONTROL_LINE_STATE.
362  * .
363  *
364  * @param[in] usbp pointer to the @p USBDriver object
365  * @return The hook status.
366  * @retval true Message handled internally.
367  * @retval false Message not handled.
368  */
370 
371  if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) {
372  switch (usbp->setup[1]) {
373  case CDC_GET_LINE_CODING:
374  usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL);
375  return true;
376  case CDC_SET_LINE_CODING:
377  usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL);
378  return true;
379  case CDC_SET_CONTROL_LINE_STATE:
380  /* Nothing to do, there are no control lines.*/
381  usbSetupTransfer(usbp, NULL, 0, NULL);
382  return true;
383  default:
384  return false;
385  }
386  }
387  return false;
388 }
389 
390 /**
391  * @brief SOF handler.
392  * @details The SOF interrupt is used for automatic flushing of incomplete
393  * buffers pending in the output queue.
394  *
395  * @param[in] sdup pointer to a @p SerialUSBDriver object
396  *
397  * @iclass
398  */
400 
401  /* If the USB driver is not in the appropriate state then transactions
402  must not be started.*/
403  if ((usbGetDriverStateI(sdup->config->usbp) != USB_ACTIVE) ||
404  (sdup->state != SDU_READY)) {
405  return;
406  }
407 
408  /* If there is already a transaction ongoing then another one cannot be
409  started.*/
410  if (usbGetTransmitStatusI(sdup->config->usbp, sdup->config->bulk_in)) {
411  return;
412  }
413 
414  /* Checking if there only a buffer partially filled, if so then it is
415  enforced in the queue and transmitted.*/
416  if (obqTryFlushI(&sdup->obqueue)) {
417  size_t n;
418  uint8_t *buf = obqGetFullBufferI(&sdup->obqueue, &n);
419 
420  osalDbgAssert(buf != NULL, "queue is empty");
421 
422  usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in, buf, n);
423  }
424 }
425 
426 /**
427  * @brief Default data transmitted callback.
428  * @details The application must use this function as callback for the IN
429  * data endpoint.
430  *
431  * @param[in] usbp pointer to the @p USBDriver object
432  * @param[in] ep IN endpoint number
433  */
435  uint8_t *buf;
436  size_t n;
437  SerialUSBDriver *sdup = usbp->in_params[ep - 1U];
438 
439  if (sdup == NULL) {
440  return;
441  }
442 
444 
445  /* Signaling that space is available in the output queue.*/
447 
448  /* Freeing the buffer just transmitted, if it was not a zero size packet.*/
449  if (usbp->epc[ep]->in_state->txsize > 0U) {
450  obqReleaseEmptyBufferI(&sdup->obqueue);
451  }
452 
453  /* Checking if there is a buffer ready for transmission.*/
454  buf = obqGetFullBufferI(&sdup->obqueue, &n);
455 
456  if (buf != NULL) {
457  /* The endpoint cannot be busy, we are in the context of the callback,
458  so it is safe to transmit without a check.*/
459  usbStartTransmitI(usbp, ep, buf, n);
460  }
461  else if ((usbp->epc[ep]->in_state->txsize > 0U) &&
462  ((usbp->epc[ep]->in_state->txsize &
463  ((size_t)usbp->epc[ep]->in_maxsize - 1U)) == 0U)) {
464  /* Transmit zero sized packet in case the last one has maximum allowed
465  size. Otherwise the recipient may expect more data coming soon and
466  not return buffered data to app. See section 5.8.3 Bulk Transfer
467  Packet Size Constraints of the USB Specification document.*/
468  usbStartTransmitI(usbp, ep, usbp->setup, 0);
469 
470  }
471  else {
472  /* Nothing to transmit.*/
473  }
474 
476 }
477 
478 /**
479  * @brief Default data received callback.
480  * @details The application must use this function as callback for the OUT
481  * data endpoint.
482  *
483  * @param[in] usbp pointer to the @p USBDriver object
484  * @param[in] ep OUT endpoint number
485  */
487  size_t size;
488  SerialUSBDriver *sdup = usbp->out_params[ep - 1U];
489 
490  if (sdup == NULL) {
491  return;
492  }
493 
495 
496  /* Checking for zero-size transactions.*/
497  size = usbGetReceiveTransactionSizeX(sdup->config->usbp,
498  sdup->config->bulk_out);
499  if (size > (size_t)0) {
500  /* Signaling that data is available in the input queue.*/
502 
503  /* Posting the filled buffer in the queue.*/
504  ibqPostFullBufferI(&sdup->ibqueue, size);
505  }
506 
507  /* The endpoint cannot be busy, we are in the context of the callback,
508  so a packet is in the buffer for sure. Trying to get a free buffer
509  for the next transaction.*/
510  (void) sdu_start_receive(sdup);
511 
513 }
514 
515 /**
516  * @brief Default data received callback.
517  * @details The application must use this function as callback for the IN
518  * interrupt endpoint.
519  *
520  * @param[in] usbp pointer to the @p USBDriver object
521  * @param[in] ep endpoint number
522  */
524 
525  (void)usbp;
526  (void)ep;
527 }
528 
529 /**
530  * @brief Control operation on a serial USB port.
531  *
532  * @param[in] usbp pointer to a @p USBDriver object
533  * @param[in] operation control operation code
534  * @param[in,out] arg operation argument
535  *
536  * @return The control operation status.
537  * @retval MSG_OK in case of success.
538  * @retval MSG_TIMEOUT in case of operation timeout.
539  * @retval MSG_RESET in case of operation reset.
540  *
541  * @api
542  */
543 msg_t sduControl(USBDriver *usbp, unsigned int operation, void *arg) {
544 
545  return _ctl((void *)usbp, operation, arg);
546 }
547 
548 #endif /* HAL_USE_SERIAL_USB == TRUE */
549 
550 /** @} */
uint8_t * ibqGetEmptyBufferI(input_buffers_queue_t *ibqp)
Gets the next empty buffer from the queue.
Definition: hal_buffers.c:129
static void ibnotify(io_buffers_queue_t *bqp)
Notification of empty buffer released into the input buffers queue.
uint8_t * obqGetFullBufferI(output_buffers_queue_t *obqp, size_t *sizep)
Gets the next filled buffer from the queue.
Definition: hal_buffers.c:486
uint16_t in_maxsize
IN endpoint maximum packet size.
Definition: hal_usb_lld.h:167
void obqReleaseEmptyBufferI(output_buffers_queue_t *obqp)
Releases the next filled buffer back in the queue.
Definition: hal_buffers.c:508
const USBEndpointConfig * epc[USB_MAX_ENDPOINTS+1]
Active endpoints configurations.
Definition: hal_usb_lld.h:237
uint8_t setup[8]
Setup packet buffer.
Definition: hal_usb_lld.h:271
USBDriver * usbp
USB driver to use.
void sduWakeupHookI(SerialUSBDriver *sdup)
USB device wakeup handler.
void sduStop(SerialUSBDriver *sdup)
Stops the driver.
size_t txsize
Requested transmit transfer size.
Definition: hal_usb_lld.h:87
#define usbGetReceiveStatusI(usbp, ep)
Returns the status of an OUT endpoint.
Definition: hal_usb.h:446
void sduConfigureHookI(SerialUSBDriver *sdup)
USB device configured handler.
void sduInterruptTransmitted(USBDriver *usbp, usbep_t ep)
Default data received callback.
void sduInit(void)
Serial Driver initialization.
HAL subsystem header.
#define bqSuspendI(bqp)
Puts the queue in suspended state.
Definition: hal_buffers.h:203
static void osalSysLockFromISR(void)
Enters a critical zone from ISR context.
Definition: osal.h:550
bool sduRequestsHook(USBDriver *usbp)
Default requests hook.
void sduDataTransmitted(USBDriver *usbp, usbep_t ep)
Default data transmitted callback.
void ibqResetI(input_buffers_queue_t *ibqp)
Resets an input buffers queue.
Definition: hal_buffers.c:107
static void osalSysUnlock(void)
Leaves a critical zone from thread context.
Definition: osal.h:540
const struct SerialUSBDriverVMT * vmt
Virtual Methods Table.
void osalOsRescheduleS(void)
Checks if a reschedule is required and performs it.
Definition: osal.c:119
Type of Line Coding structure.
Definition: hal_usb_cdc.h:119
static void osalEventObjectInit(event_source_t *esp)
Initializes an event source object.
Definition: osal.h:665
Structure representing an USB driver.
Definition: hal_usb_lld.h:217
usbep_t bulk_out
Bulk OUT endpoint used for incoming data transfer.
void * out_params[USB_MAX_ENDPOINTS]
Fields available to user, it can be used to associate an application-defined handler to an OUT endpoi...
Definition: hal_usb_lld.h:251
void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config)
Configures and starts the driver.
int32_t msg_t
Type of a message.
Definition: osal.h:160
size_t ibqReadTimeout(input_buffers_queue_t *ibqp, uint8_t *bp, size_t n, sysinterval_t timeout)
Input queue read with timeout.
Definition: hal_buffers.c:358
#define SERIAL_USB_BUFFERS_SIZE
Serial over USB buffers size.
#define usbGetDriverStateI(usbp)
Returns the driver state.
Definition: hal_usb.h:391
void sduSOFHookI(SerialUSBDriver *sdup)
SOF handler.
void ibqPostFullBufferI(input_buffers_queue_t *ibqp, size_t size)
Posts a new filled buffer to the queue.
Definition: hal_buffers.c:148
size_t obqWriteTimeout(output_buffers_queue_t *obqp, const uint8_t *bp, size_t n, sysinterval_t timeout)
Output queue write with timeout.
Definition: hal_buffers.c:721
void sduDataReceived(USBDriver *usbp, usbep_t ep)
Default data received callback.
bool obqTryFlushI(output_buffers_queue_t *obqp)
Flushes the current, partially filled, buffer to the queue.
Definition: hal_buffers.c:795
#define usbGetTransmitStatusI(usbp, ep)
Returns the status of an IN endpoint.
Definition: hal_usb.h:432
void usbStartReceiveI(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n)
Starts a receive transaction on an OUT endpoint.
Definition: hal_usb.c:453
void sduObjectInit(SerialUSBDriver *sdup)
Initializes a generic full duplex driver object.
void obqObjectInit(output_buffers_queue_t *obqp, bool suspended, uint8_t *bp, size_t size, size_t n, bqnotify_t onfy, void *link)
Initializes an output buffers queue object.
Definition: hal_buffers.c:432
#define osalDbgCheck(c)
Function parameters check.
Definition: osal.h:278
static void osalSysUnlockFromISR(void)
Leaves a critical zone from ISR context.
Definition: osal.h:560
usbep_t bulk_in
Bulk IN endpoint used for outgoing data transfer.
#define CHN_CONNECTED
Connection happened.
Definition: hal_channels.h:233
uint32_t sysinterval_t
Type of system time interval.
Definition: osal.h:170
usbep_t int_in
Interrupt IN endpoint used for notifications.
msg_t obqPutTimeout(output_buffers_queue_t *obqp, uint8_t b, sysinterval_t timeout)
Output queue write with timeout.
Definition: hal_buffers.c:671
static void obnotify(io_buffers_queue_t *bqp)
Notification of filled buffer inserted into the output buffers queue.
Structure of a generic buffers queue.
Definition: hal_buffers.h:59
void * in_params[USB_MAX_ENDPOINTS]
Fields available to user, it can be used to associate an application-defined handler to an IN endpoin...
Definition: hal_usb_lld.h:244
static void osalSysLock(void)
Enters a critical zone from thread context.
Definition: osal.h:530
#define bqResumeX(bqp)
Resumes normal queue operations.
Definition: hal_buffers.h:215
msg_t ibqGetTimeout(input_buffers_queue_t *ibqp, sysinterval_t timeout)
Input queue read with timeout.
Definition: hal_buffers.c:309
void obqResetI(output_buffers_queue_t *obqp)
Resets an output buffers queue.
Definition: hal_buffers.c:463
void sduSuspendHookI(SerialUSBDriver *sdup)
USB device suspend handler.
#define bqGetLinkX(bqp)
Returns the queue application-defined link.
Definition: hal_buffers.h:175
Full duplex serial driver class.
#define chnAddFlagsI(ip, flags)
Adds status flags to the listeners's flags mask.
Definition: hal_channels.h:308
SerialDriver virtual methods table.
#define osalDbgAssert(c, remark)
Condition assertion.
Definition: osal.h:258
#define CHN_OUTPUT_EMPTY
Output queue empty.
Definition: hal_channels.h:239
uint8_t usbep_t
Type of an endpoint identifier.
Definition: hal_usb.h:264
msg_t sduControl(USBDriver *usbp, unsigned int operation, void *arg)
Control operation on a serial USB port.
#define CHN_DISCONNECTED
Disconnection happened.
Definition: hal_channels.h:235
void usbStartTransmitI(USBDriver *usbp, usbep_t ep, const uint8_t *buf, size_t n)
Starts a transmit transaction on an IN endpoint.
Definition: hal_usb.c:492
#define CHN_INPUT_AVAILABLE
Data available in the input queue.
Definition: hal_channels.h:237
void ibqObjectInit(input_buffers_queue_t *ibqp, bool suspended, uint8_t *bp, size_t size, size_t n, bqnotify_t infy, void *link)
Initializes an input buffers queue object.
Definition: hal_buffers.c:76
Serial over USB Driver configuration structure.
#define usbSetupTransfer(usbp, buf, n, endcb)
Request transfer setup.
Definition: hal_usb.h:476
USBInEndpointState * in_state
USBEndpointState associated to the IN endpoint.
Definition: hal_usb_lld.h:178
#define SERIAL_USB_BUFFERS_NUMBER
Serial over USB number of buffers.
#define usbGetReceiveTransactionSizeX(usbp, ep)
Returns the exact size of a receive transaction.
Definition: hal_usb.h:461