ChibiOS/HAL  7.0.3
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  /* Getting a full buffer, a buffer is available for sure because this
192  callback is invoked when one has been inserted.*/
193  uint8_t *buf = obqGetFullBufferI(&sdup->obqueue, &n);
194  osalDbgAssert(buf != NULL, "buffer not found");
195  usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in, buf, n);
196  }
197 }
198 
199 /*===========================================================================*/
200 /* Driver exported functions. */
201 /*===========================================================================*/
202 
203 /**
204  * @brief Serial Driver initialization.
205  * @note This function is implicitly invoked by @p halInit(), there is
206  * no need to explicitly initialize the driver.
207  *
208  * @init
209  */
210 void sduInit(void) {
211 }
212 
213 /**
214  * @brief Initializes a generic full duplex driver object.
215  * @details The HW dependent part of the initialization has to be performed
216  * outside, usually in the hardware initialization code.
217  *
218  * @param[out] sdup pointer to a @p SerialUSBDriver structure
219  *
220  * @init
221  */
223 
224  sdup->vmt = &vmt;
225  osalEventObjectInit(&sdup->event);
226  sdup->state = SDU_STOP;
227  ibqObjectInit(&sdup->ibqueue, true, sdup->ib,
229  ibnotify, sdup);
230  obqObjectInit(&sdup->obqueue, true, sdup->ob,
232  obnotify, sdup);
233 }
234 
235 /**
236  * @brief Configures and starts the driver.
237  *
238  * @param[in] sdup pointer to a @p SerialUSBDriver object
239  * @param[in] config the serial over USB driver configuration
240  *
241  * @api
242  */
243 void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config) {
244  USBDriver *usbp = config->usbp;
245 
246  osalDbgCheck(sdup != NULL);
247 
248  osalSysLock();
249  osalDbgAssert((sdup->state == SDU_STOP) || (sdup->state == SDU_READY),
250  "invalid state");
251  usbp->in_params[config->bulk_in - 1U] = sdup;
252  usbp->out_params[config->bulk_out - 1U] = sdup;
253  if (config->int_in > 0U) {
254  usbp->in_params[config->int_in - 1U] = sdup;
255  }
256  sdup->config = config;
257  sdup->state = SDU_READY;
258  osalSysUnlock();
259 }
260 
261 /**
262  * @brief Stops the driver.
263  * @details Any thread waiting on the driver's queues will be awakened with
264  * the message @p MSG_RESET.
265  *
266  * @param[in] sdup pointer to a @p SerialUSBDriver object
267  *
268  * @api
269  */
271  USBDriver *usbp = sdup->config->usbp;
272 
273  osalDbgCheck(sdup != NULL);
274 
275  osalSysLock();
276 
277  osalDbgAssert((sdup->state == SDU_STOP) || (sdup->state == SDU_READY),
278  "invalid state");
279 
280  /* Driver in stopped state.*/
281  usbp->in_params[sdup->config->bulk_in - 1U] = NULL;
282  usbp->out_params[sdup->config->bulk_out - 1U] = NULL;
283  if (sdup->config->int_in > 0U) {
284  usbp->in_params[sdup->config->int_in - 1U] = NULL;
285  }
286  sdup->config = NULL;
287  sdup->state = SDU_STOP;
288 
289  /* Enforces a disconnection.*/
291  ibqResetI(&sdup->ibqueue);
292  obqResetI(&sdup->obqueue);
294 
295  osalSysUnlock();
296 }
297 
298 /**
299  * @brief USB device suspend handler.
300  * @details Generates a @p CHN_DISCONNECT event and puts queues in
301  * non-blocking mode, this way the application cannot get stuck
302  * in the middle of an I/O operations.
303  * @note If this function is not called from an ISR then an explicit call
304  * to @p osalOsRescheduleS() in necessary afterward.
305  *
306  * @param[in] sdup pointer to a @p SerialUSBDriver object
307  *
308  * @iclass
309  */
311 
312  /* Avoiding events spam.*/
313  if(bqIsSuspendedX(&sdup->ibqueue) && bqIsSuspendedX(&sdup->obqueue)) {
314  return;
315  }
317  bqSuspendI(&sdup->ibqueue);
318  bqSuspendI(&sdup->obqueue);
319 }
320 
321 /**
322  * @brief USB device wakeup handler.
323  * @details Generates a @p CHN_CONNECT event and resumes normal queues
324  * operations.
325  *
326  * @note If this function is not called from an ISR then an explicit call
327  * to @p osalOsRescheduleS() in necessary afterward.
328  *
329  * @param[in] sdup pointer to a @p SerialUSBDriver object
330  *
331  * @iclass
332  */
334 
336  bqResumeX(&sdup->ibqueue);
337  bqResumeX(&sdup->obqueue);
338 }
339 
340 /**
341  * @brief USB device configured handler.
342  *
343  * @param[in] sdup pointer to a @p SerialUSBDriver object
344  *
345  * @iclass
346  */
348 
349  ibqResetI(&sdup->ibqueue);
350  bqResumeX(&sdup->ibqueue);
351  obqResetI(&sdup->obqueue);
352  bqResumeX(&sdup->obqueue);
354  (void) sdu_start_receive(sdup);
355 }
356 
357 /**
358  * @brief Default requests hook.
359  * @details Applications wanting to use the Serial over USB driver can use
360  * this function as requests hook in the USB configuration.
361  * The following requests are emulated:
362  * - CDC_GET_LINE_CODING.
363  * - CDC_SET_LINE_CODING.
364  * - CDC_SET_CONTROL_LINE_STATE.
365  * .
366  *
367  * @param[in] usbp pointer to the @p USBDriver object
368  * @return The hook status.
369  * @retval true Message handled internally.
370  * @retval false Message not handled.
371  */
373 
374  if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) {
375  switch (usbp->setup[1]) {
376  case CDC_GET_LINE_CODING:
377  usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL);
378  return true;
379  case CDC_SET_LINE_CODING:
380  usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL);
381  return true;
382  case CDC_SET_CONTROL_LINE_STATE:
383  /* Nothing to do, there are no control lines.*/
384  usbSetupTransfer(usbp, NULL, 0, NULL);
385  return true;
386  default:
387  return false;
388  }
389  }
390  return false;
391 }
392 
393 /**
394  * @brief SOF handler.
395  * @details The SOF interrupt is used for automatic flushing of incomplete
396  * buffers pending in the output queue.
397  *
398  * @param[in] sdup pointer to a @p SerialUSBDriver object
399  *
400  * @iclass
401  */
403 
404  /* If the USB driver is not in the appropriate state then transactions
405  must not be started.*/
406  if ((usbGetDriverStateI(sdup->config->usbp) != USB_ACTIVE) ||
407  (sdup->state != SDU_READY)) {
408  return;
409  }
410 
411  /* If there is already a transaction ongoing then another one cannot be
412  started.*/
413  if (usbGetTransmitStatusI(sdup->config->usbp, sdup->config->bulk_in)) {
414  return;
415  }
416 
417  /* Checking if there only a buffer partially filled, if so then it is
418  enforced in the queue and transmitted.*/
419  if (obqTryFlushI(&sdup->obqueue)) {
420  size_t n;
421  uint8_t *buf = obqGetFullBufferI(&sdup->obqueue, &n);
422 
423  osalDbgAssert(buf != NULL, "queue is empty");
424 
425  usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in, buf, n);
426  }
427 }
428 
429 /**
430  * @brief Default data transmitted callback.
431  * @details The application must use this function as callback for the IN
432  * data endpoint.
433  *
434  * @param[in] usbp pointer to the @p USBDriver object
435  * @param[in] ep IN endpoint number
436  */
438  uint8_t *buf;
439  size_t n;
440  SerialUSBDriver *sdup = usbp->in_params[ep - 1U];
441 
442  if (sdup == NULL) {
443  return;
444  }
445 
447 
448  /* Signaling that space is available in the output queue.*/
450 
451  /* Freeing the buffer just transmitted, if it was not a zero size packet.*/
452  if (usbp->epc[ep]->in_state->txsize > 0U) {
453  obqReleaseEmptyBufferI(&sdup->obqueue);
454  }
455 
456  /* Checking if there is a buffer ready for transmission.*/
457  buf = obqGetFullBufferI(&sdup->obqueue, &n);
458 
459  if (buf != NULL) {
460  /* The endpoint cannot be busy, we are in the context of the callback,
461  so it is safe to transmit without a check.*/
462  usbStartTransmitI(usbp, ep, buf, n);
463  }
464  else if ((usbp->epc[ep]->in_state->txsize > 0U) &&
465  ((usbp->epc[ep]->in_state->txsize &
466  ((size_t)usbp->epc[ep]->in_maxsize - 1U)) == 0U)) {
467  /* Transmit zero sized packet in case the last one has maximum allowed
468  size. Otherwise the recipient may expect more data coming soon and
469  not return buffered data to app. See section 5.8.3 Bulk Transfer
470  Packet Size Constraints of the USB Specification document.*/
471  usbStartTransmitI(usbp, ep, usbp->setup, 0);
472 
473  }
474  else {
475  /* Nothing to transmit.*/
476  }
477 
479 }
480 
481 /**
482  * @brief Default data received callback.
483  * @details The application must use this function as callback for the OUT
484  * data endpoint.
485  *
486  * @param[in] usbp pointer to the @p USBDriver object
487  * @param[in] ep OUT endpoint number
488  */
490  size_t size;
491  SerialUSBDriver *sdup = usbp->out_params[ep - 1U];
492 
493  if (sdup == NULL) {
494  return;
495  }
496 
498 
499  /* Checking for zero-size transactions.*/
500  size = usbGetReceiveTransactionSizeX(sdup->config->usbp,
501  sdup->config->bulk_out);
502  if (size > (size_t)0) {
503  /* Signaling that data is available in the input queue.*/
505 
506  /* Posting the filled buffer in the queue.*/
507  ibqPostFullBufferI(&sdup->ibqueue, size);
508  }
509 
510  /* The endpoint cannot be busy, we are in the context of the callback,
511  so a packet is in the buffer for sure. Trying to get a free buffer
512  for the next transaction.*/
513  (void) sdu_start_receive(sdup);
514 
516 }
517 
518 /**
519  * @brief Default data received callback.
520  * @details The application must use this function as callback for the IN
521  * interrupt endpoint.
522  *
523  * @param[in] usbp pointer to the @p USBDriver object
524  * @param[in] ep endpoint number
525  */
527 
528  (void)usbp;
529  (void)ep;
530 }
531 
532 /**
533  * @brief Control operation on a serial USB port.
534  *
535  * @param[in] usbp pointer to a @p USBDriver object
536  * @param[in] operation control operation code
537  * @param[in,out] arg operation argument
538  *
539  * @return The control operation status.
540  * @retval MSG_OK in case of success.
541  * @retval MSG_TIMEOUT in case of operation timeout.
542  * @retval MSG_RESET in case of operation reset.
543  *
544  * @api
545  */
546 msg_t sduControl(USBDriver *usbp, unsigned int operation, void *arg) {
547 
548  return _ctl((void *)usbp, operation, arg);
549 }
550 
551 #endif /* HAL_USE_SERIAL_USB == TRUE */
552 
553 /** @} */
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:229
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
#define bqIsSuspendedX(bqp)
Return the suspended state of the queue.
Definition: hal_buffers.h:213
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:75
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:241
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:191
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