ChibiOS 21.11.5
hal_serial_usb.c
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006-2026 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 */
45 {0x00, 0x96, 0x00, 0x00}, /* 38400. */
47};
48
49/*===========================================================================*/
50/* Driver local functions. */
51/*===========================================================================*/
52
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_out)) {
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
85static 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
91static 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
97static msg_t _put(void *ip, uint8_t b) {
98
99 return obqPutTimeout(&((SerialUSBDriver *)ip)->obqueue, b, TIME_INFINITE);
100}
101
102static msg_t _get(void *ip) {
103
104 return ibqGetTimeout(&((SerialUSBDriver *)ip)->ibqueue, TIME_INFINITE);
105}
106
107static msg_t _putt(void *ip, uint8_t b, sysinterval_t timeout) {
108
109 return obqPutTimeout(&((SerialUSBDriver *)ip)->obqueue, b, timeout);
110}
111
112static msg_t _gett(void *ip, sysinterval_t timeout) {
113
114 return ibqGetTimeout(&((SerialUSBDriver *)ip)->ibqueue, timeout);
115}
116
117static 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
123static 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
129static 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 return HAL_RET_UNKNOWN_CTL;
140 default:
141#if defined(SDU_LLD_IMPLEMENTS_CTL)
142 /* The SDU driver does not have a LLD but the application can use this
143 hook to implement extra controls by supplying this function.*/
144 extern msg_t sdu_lld_control(SerialUSBDriver *sdup,
145 unsigned int operation,
146 void *arg);
147 return sdu_lld_control(sdup, operation, arg);
148#else
149 break;
150#endif
151 }
152 return HAL_RET_SUCCESS;
153}
154
155static const struct SerialUSBDriverVMT vmt = {
156 (size_t)0,
159 _ctl
160};
161
162/**
163 * @brief Notification of empty buffer released into the input buffers queue.
164 *
165 * @param[in] bqp the buffers queue pointer.
166 */
167static void ibnotify(io_buffers_queue_t *bqp) {
168 SerialUSBDriver *sdup = bqGetLinkX(bqp);
169 (void) sdu_start_receive(sdup);
170}
171
172/**
173 * @brief Notification of filled buffer inserted into the output buffers queue.
174 *
175 * @param[in] bqp the buffers queue pointer.
176 */
177static void obnotify(io_buffers_queue_t *bqp) {
178 size_t n;
179 SerialUSBDriver *sdup = bqGetLinkX(bqp);
180
181 /* If the USB driver is not in the appropriate state then transactions
182 must not be started.*/
183 if ((usbGetDriverStateI(sdup->config->usbp) != USB_ACTIVE) ||
184 (sdup->state != SDU_READY)) {
185 return;
186 }
187
188 /* Checking if there is already a transaction ongoing on the endpoint.*/
189 if (!usbGetTransmitStatusI(sdup->config->usbp, sdup->config->bulk_in)) {
190 /* Getting a full buffer, a buffer is available for sure because this
191 callback is invoked when one has been inserted.*/
192 uint8_t *buf = obqGetFullBufferI(&sdup->obqueue, &n);
193 osalDbgAssert(buf != NULL, "buffer not found");
194 usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in, buf, n);
195 }
196}
197
198/*===========================================================================*/
199/* Driver exported functions. */
200/*===========================================================================*/
201
202/**
203 * @brief Serial Driver initialization.
204 * @note This function is implicitly invoked by @p halInit(), there is
205 * no need to explicitly initialize the driver.
206 *
207 * @init
208 */
209void sduInit(void) {
210}
211
212/**
213 * @brief Initializes a generic full duplex driver object.
214 * @details The HW dependent part of the initialization has to be performed
215 * outside, usually in the hardware initialization code.
216 *
217 * @param[out] sdup pointer to a @p SerialUSBDriver structure
218 *
219 * @init
220 */
222
223 sdup->vmt = &vmt;
224 osalEventObjectInit(&sdup->event);
225 sdup->state = SDU_STOP;
226 ibqObjectInit(&sdup->ibqueue, true, sdup->ib,
228 ibnotify, sdup);
229 obqObjectInit(&sdup->obqueue, true, sdup->ob,
231 obnotify, sdup);
232}
233
234/**
235 * @brief Configures and starts the driver.
236 *
237 * @param[in] sdup pointer to a @p SerialUSBDriver object
238 * @param[in] config the serial over USB driver configuration
239 * @return The operation status.
240 *
241 * @api
242 */
244 USBDriver *usbp;
245
246 osalDbgCheck((sdup != NULL) && (config != NULL) && (config->usbp != NULL));
247 osalDbgCheck((config->bulk_in > 0U) &&
248 (config->bulk_in <= (usbep_t)USB_MAX_ENDPOINTS));
249 osalDbgCheck((config->bulk_out > 0U) &&
250 (config->bulk_out <= (usbep_t)USB_MAX_ENDPOINTS));
251 if (config->int_in > 0U) {
253 }
254
255 osalSysLock();
256 osalDbgAssert((sdup->state == SDU_STOP) || (sdup->state == SDU_READY),
257 "invalid state");
258
259 usbp = config->usbp;
260 usbp->in_params[config->bulk_in - 1U] = sdup;
261 usbp->out_params[config->bulk_out - 1U] = sdup;
262 if (config->int_in > 0U) {
263 usbp->in_params[config->int_in - 1U] = sdup;
264 }
265 sdup->config = config;
266 sdup->state = SDU_READY;
267
269
270 return HAL_RET_SUCCESS;
271}
272
273/**
274 * @brief Stops the driver.
275 * @details Any thread waiting on the driver's queues will be awakened with
276 * the message @p MSG_RESET.
277 *
278 * @param[in] sdup pointer to a @p SerialUSBDriver object
279 *
280 * @api
281 */
283 USBDriver *usbp = NULL;
284
285 osalDbgCheck(sdup != NULL);
286
287 osalSysLock();
288
289 osalDbgAssert((sdup->state == SDU_STOP) || (sdup->state == SDU_READY),
290 "invalid state");
291
292 if (sdup->config != NULL) {
293 usbp = sdup->config->usbp;
294 }
295
296 /* Driver in stopped state.*/
297 if (usbp != NULL) {
298 usbp->in_params[sdup->config->bulk_in - 1U] = NULL;
299 usbp->out_params[sdup->config->bulk_out - 1U] = NULL;
300 if (sdup->config->int_in > 0U) {
301 usbp->in_params[sdup->config->int_in - 1U] = NULL;
302 }
303 }
304 sdup->config = NULL;
305 sdup->state = SDU_STOP;
306
307 /* Enforces a disconnection.*/
309 ibqResetI(&sdup->ibqueue);
310 obqResetI(&sdup->obqueue);
312
314}
315
316/**
317 * @brief USB device suspend handler.
318 * @details Generates a @p CHN_DISCONNECT event and puts queues in
319 * non-blocking mode, this way the application cannot get stuck
320 * in the middle of an I/O operations.
321 * @note If this function is not called from an ISR then an explicit call
322 * to @p osalOsRescheduleS() is necessary afterward.
323 *
324 * @param[in] sdup pointer to a @p SerialUSBDriver object
325 *
326 * @iclass
327 */
329
330 /* Avoiding events spam.*/
331 if (bqIsSuspendedX(&sdup->ibqueue) && bqIsSuspendedX(&sdup->obqueue)) {
332 return;
333 }
335 bqSuspendI(&sdup->ibqueue);
336 bqSuspendI(&sdup->obqueue);
337}
338
339/**
340 * @brief USB device wakeup handler.
341 * @details Generates a @p CHN_CONNECT event and resumes normal queues
342 * operations.
343 *
344 * @note If this function is not called from an ISR then an explicit call
345 * to @p osalOsRescheduleS() is necessary afterward.
346 *
347 * @param[in] sdup pointer to a @p SerialUSBDriver object
348 *
349 * @iclass
350 */
352
354 bqResumeX(&sdup->ibqueue);
355 bqResumeX(&sdup->obqueue);
356}
357
358/**
359 * @brief USB device configured handler.
360 *
361 * @param[in] sdup pointer to a @p SerialUSBDriver object
362 *
363 * @iclass
364 */
366
367 ibqResetI(&sdup->ibqueue);
368 bqResumeX(&sdup->ibqueue);
369 obqResetI(&sdup->obqueue);
370 bqResumeX(&sdup->obqueue);
372 (void) sdu_start_receive(sdup);
373}
374
375/**
376 * @brief Default requests hook.
377 * @details Applications wanting to use the Serial over USB driver can use
378 * this function as requests hook in the USB configuration.
379 * The following requests are emulated:
380 * - CDC_GET_LINE_CODING.
381 * - CDC_SET_LINE_CODING.
382 * - CDC_SET_CONTROL_LINE_STATE.
383 * .
384 *
385 * @param[in] usbp pointer to the @p USBDriver object
386 * @return The hook status.
387 * @retval true Message handled internally.
388 * @retval false Message not handled.
389 */
391
392 if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) {
393 switch (usbp->setup[1]) {
395 usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL);
396 return true;
398 usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL);
399 return true;
401 /* Nothing to do, there are no control lines.*/
402 usbSetupTransfer(usbp, NULL, 0, NULL);
403 return true;
404 default:
405 return false;
406 }
407 }
408 return false;
409}
410
411/**
412 * @brief SOF handler.
413 * @details The SOF interrupt is used for automatic flushing of incomplete
414 * buffers pending in the output queue.
415 *
416 * @param[in] sdup pointer to a @p SerialUSBDriver object
417 *
418 * @iclass
419 */
421
422 /* If the USB driver is not in the appropriate state then transactions
423 must not be started.*/
424 if ((usbGetDriverStateI(sdup->config->usbp) != USB_ACTIVE) ||
425 (sdup->state != SDU_READY)) {
426 return;
427 }
428
429 /* If there is already a transaction ongoing then another one cannot be
430 started.*/
431 if (usbGetTransmitStatusI(sdup->config->usbp, sdup->config->bulk_in)) {
432 return;
433 }
434
435 /* Checking if there only a buffer partially filled, if so then it is
436 enforced in the queue and transmitted.*/
437 if (obqTryFlushI(&sdup->obqueue)) {
438 size_t n;
439 uint8_t *buf = obqGetFullBufferI(&sdup->obqueue, &n);
440
441 osalDbgAssert(buf != NULL, "queue is empty");
442
443 usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in, buf, n);
444 }
445}
446
447/**
448 * @brief Default data transmitted callback.
449 * @details The application must use this function as callback for the IN
450 * data endpoint.
451 *
452 * @param[in] usbp pointer to the @p USBDriver object
453 * @param[in] ep IN endpoint number
454 */
456 uint8_t *buf;
457 size_t n;
458
459 osalDbgAssert(ep != 0U, "invalid endpoint");
460 if (ep == 0U) {
461 return;
462 }
463 SerialUSBDriver *sdup = usbp->in_params[ep - 1U];
464
465 if (sdup == NULL) {
466 return;
467 }
468
470
471 /* Freeing the buffer just transmitted, if it was not a zero size packet.*/
472 if (usbp->epc[ep]->in_state->txsize > 0U) {
473 obqReleaseEmptyBufferI(&sdup->obqueue);
474
475 /* Signaling that space is available in the output queue.*/
477 }
478
479 /* Checking if there is a buffer ready for transmission.*/
480 buf = obqGetFullBufferI(&sdup->obqueue, &n);
481
482 if (buf != NULL) {
483 /* The endpoint cannot be busy, we are in the context of the callback,
484 so it is safe to transmit without a check.*/
485 usbStartTransmitI(usbp, ep, buf, n);
486 }
487 else if ((usbp->epc[ep]->in_state->txsize > 0U) &&
488 ((usbp->epc[ep]->in_state->txsize &
489 ((size_t)usbp->epc[ep]->in_maxsize - 1U)) == 0U)) {
490 /* Transmit zero sized packet in case the last one has maximum allowed
491 size. Otherwise the recipient may expect more data coming soon and
492 not return buffered data to app. See section 5.8.3 Bulk Transfer
493 Packet Size Constraints of the USB Specification document.*/
494 usbStartTransmitI(usbp, ep, usbp->setup, 0);
495
496 }
497 else {
498 /* Nothing further to transmit.*/
500 }
501
503}
504
505/**
506 * @brief Default data received callback.
507 * @details The application must use this function as callback for the OUT
508 * data endpoint.
509 *
510 * @param[in] usbp pointer to the @p USBDriver object
511 * @param[in] ep OUT endpoint number
512 */
514 size_t size;
515
516 osalDbgAssert(ep != 0U, "invalid endpoint");
517 if (ep == 0U) {
518 return;
519 }
520 SerialUSBDriver *sdup = usbp->out_params[ep - 1U];
521
522 if (sdup == NULL) {
523 return;
524 }
525
527
528 /* Checking for zero-size transactions.*/
529 size = usbGetReceiveTransactionSizeX(sdup->config->usbp,
530 sdup->config->bulk_out);
531 if (size > (size_t)0) {
532 /* Signaling that data is available in the input queue.*/
534
535 /* Posting the filled buffer in the queue.*/
536 ibqPostFullBufferI(&sdup->ibqueue, size);
537 }
538
539 /* The endpoint cannot be busy, we are in the context of the callback,
540 so a packet is in the buffer for sure. Trying to get a free buffer
541 for the next transaction.*/
542 (void) sdu_start_receive(sdup);
543
545}
546
547/**
548 * @brief Default data received callback.
549 * @details The application must use this function as callback for the IN
550 * interrupt endpoint.
551 *
552 * @param[in] usbp pointer to the @p USBDriver object
553 * @param[in] ep endpoint number
554 */
556
557 (void)usbp;
558 (void)ep;
559}
560
561/**
562 * @brief Control operation on a serial USB port.
563 *
564 * @param[in] sdup pointer to a @p SerialUSBDriver object
565 * @param[in] operation control operation code
566 * @param[in,out] arg operation argument
567 *
568 * @return The control operation status.
569 * @retval MSG_OK in case of success.
570 * @retval MSG_TIMEOUT in case of operation timeout.
571 * @retval MSG_RESET in case of operation reset.
572 *
573 * @api
574 */
575msg_t sduControl(SerialUSBDriver *sdup, unsigned int operation, void *arg) {
576
577 return _ctl((void *)sdup, operation, arg);
578}
579
580#endif /* HAL_USE_SERIAL_USB == TRUE */
581
582/** @} */
uint8_t * ibqGetEmptyBufferI(input_buffers_queue_t *ibqp)
Gets the next empty buffer from the queue.
void ibqPostFullBufferI(input_buffers_queue_t *ibqp, size_t size)
Posts a new filled buffer to the queue.
uint8_t * obqGetFullBufferI(output_buffers_queue_t *obqp, size_t *sizep)
Gets the next filled buffer from the queue.
bool obqTryFlushI(output_buffers_queue_t *obqp)
Flushes the current, partially filled, buffer to the queue.
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.
size_t obqWriteTimeout(output_buffers_queue_t *obqp, const uint8_t *bp, size_t n, sysinterval_t timeout)
Output queue write with timeout.
#define bqSuspendI(bqp)
Puts the queue in suspended state.
void obqReleaseEmptyBufferI(output_buffers_queue_t *obqp)
Releases the next filled buffer back in the queue.
struct io_buffers_queue io_buffers_queue_t
Type of a generic queue of buffers.
Definition hal_buffers.h:63
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
msg_t ibqGetTimeout(input_buffers_queue_t *ibqp, sysinterval_t timeout)
Input queue read with timeout.
size_t ibqReadTimeout(input_buffers_queue_t *ibqp, uint8_t *bp, size_t n, sysinterval_t timeout)
Input queue read with timeout.
#define bqIsSuspendedX(bqp)
Return the suspended state of the queue.
void ibqResetI(input_buffers_queue_t *ibqp)
Resets an input buffers queue.
#define bqResumeX(bqp)
Resumes normal queue operations.
void obqResetI(output_buffers_queue_t *obqp)
Resets an output buffers queue.
msg_t obqPutTimeout(output_buffers_queue_t *obqp, uint8_t b, sysinterval_t timeout)
Output queue write with timeout.
#define bqGetLinkX(bqp)
Returns the queue application-defined link.
static const struct EFlashDriverVMT vmt
Definition hal_efl.c:71
#define HAL_RET_SUCCESS
Definition hal.h:93
#define HAL_RET_UNKNOWN_CTL
Unknown control code.
Definition hal.h:119
#define CHN_OUTPUT_EMPTY
Output queue empty.
#define CHN_CTL_INVALID
Invalid operation code.
#define CHN_INPUT_AVAILABLE
Data available in the input queue.
#define CHN_CTL_NOP
Does nothing.
#define CHN_TRANSMISSION_END
Transmission end.
#define chnAddFlagsI(ip, flags)
Adds status flags to the listeners's flags mask.
#define CHN_CONNECTED
Connection happened.
#define CHN_DISCONNECTED
Disconnection happened.
static void osalSysLock(void)
Enters a critical zone from thread context.
Definition osal.h:601
static void osalSysUnlock(void)
Leaves a critical zone from thread context.
Definition osal.h:611
static void osalSysLockFromISR(void)
Enters a critical zone from ISR context.
Definition osal.h:621
void osalOsRescheduleS(void)
Checks if a reschedule is required and performs it.
Definition osal.c:119
static void osalSysUnlockFromISR(void)
Leaves a critical zone from ISR context.
Definition osal.h:631
static void osalEventObjectInit(event_source_t *esp)
Initializes an event source object.
Definition osal.h:737
#define osalDbgAssert(c, remark)
Condition assertion.
Definition osal.h:264
#define osalDbgCheck(c)
Function parameters check.
Definition osal.h:284
static size_t _writet(void *ip, const uint8_t *bp, size_t n, sysinterval_t timeout)
bool sduRequestsHook(USBDriver *usbp)
Default requests hook.
#define SERIAL_USB_BUFFERS_NUMBER
Serial over USB number of buffers.
static msg_t _get(void *ip)
void sduSuspendHookI(SerialUSBDriver *sdup)
USB device suspend handler.
static msg_t _gett(void *ip, sysinterval_t timeout)
static msg_t _ctl(void *ip, unsigned int operation, void *arg)
static msg_t _put(void *ip, uint8_t b)
#define SERIAL_USB_BUFFERS_SIZE
Serial over USB buffers size.
static void ibnotify(io_buffers_queue_t *bqp)
Notification of empty buffer released into the input buffers queue.
void sduInterruptTransmitted(USBDriver *usbp, usbep_t ep)
Default data received callback.
void sduObjectInit(SerialUSBDriver *sdup)
Initializes a generic full duplex driver object.
static bool sdu_start_receive(SerialUSBDriver *sdup)
msg_t sduControl(SerialUSBDriver *sdup, unsigned int operation, void *arg)
Control operation on a serial USB port.
void sduInit(void)
Serial Driver initialization.
static size_t _write(void *ip, const uint8_t *bp, size_t n)
msg_t sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config)
Configures and starts the driver.
static msg_t _putt(void *ip, uint8_t b, sysinterval_t timeout)
void sduDataReceived(USBDriver *usbp, usbep_t ep)
Default data received callback.
void sduWakeupHookI(SerialUSBDriver *sdup)
USB device wakeup handler.
static size_t _readt(void *ip, uint8_t *bp, size_t n, sysinterval_t timeout)
void sduStop(SerialUSBDriver *sdup)
Stops the driver.
void sduSOFHookI(SerialUSBDriver *sdup)
SOF handler.
static size_t _read(void *ip, uint8_t *bp, size_t n)
static cdc_linecoding_t linecoding
void sduDataTransmitted(USBDriver *usbp, usbep_t ep)
Default data transmitted callback.
static void obnotify(io_buffers_queue_t *bqp)
Notification of filled buffer inserted into the output buffers queue.
void sduConfigureHookI(SerialUSBDriver *sdup)
USB device configured handler.
@ SDU_STOP
@ SDU_READY
static size_t _writet(void *ip, const uint8_t *bp, size_t n, sysinterval_t timeout)
Definition hal_serial.c:82
static msg_t _get(void *ip)
Definition hal_serial.c:67
static msg_t _gett(void *ip, sysinterval_t timeout)
Definition hal_serial.c:77
static msg_t _ctl(void *ip, unsigned int operation, void *arg)
Definition hal_serial.c:94
static msg_t _put(void *ip, uint8_t b)
Definition hal_serial.c:62
static size_t _write(void *ip, const uint8_t *bp, size_t n)
Definition hal_serial.c:50
static msg_t _putt(void *ip, uint8_t b, sysinterval_t timeout)
Definition hal_serial.c:72
static size_t _readt(void *ip, uint8_t *bp, size_t n, sysinterval_t timeout)
Definition hal_serial.c:88
static size_t _read(void *ip, uint8_t *bp, size_t n)
Definition hal_serial.c:56
#define CDC_GET_LINE_CODING
Definition hal_usb_cdc.h:48
#define CDC_SET_CONTROL_LINE_STATE
Definition hal_usb_cdc.h:49
#define LC_PARITY_NONE
Definition hal_usb_cdc.h:97
#define LC_STOP_1
Definition hal_usb_cdc.h:93
#define CDC_SET_LINE_CODING
Definition hal_usb_cdc.h:47
#define usbGetDriverStateI(usbp)
Returns the driver state.
Definition hal_usb.h:391
uint8_t usbep_t
Type of an endpoint identifier.
Definition hal_usb.h:264
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:532
#define usbGetReceiveTransactionSizeX(usbp, ep)
Returns the exact size of a receive transaction.
Definition hal_usb.h:461
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:571
#define USB_RTYPE_TYPE_CLASS
Definition hal_usb.h:42
#define usbGetReceiveStatusI(usbp, ep)
Returns the status of an OUT endpoint.
Definition hal_usb.h:446
#define usbSetupTransfer(usbp, buf, n, endcb)
Request transfer setup.
Definition hal_usb.h:479
#define USB_MAX_ENDPOINTS
Maximum endpoint address.
Definition hal_usb_lld.h:37
#define usbGetTransmitStatusI(usbp, ep)
Returns the status of an IN endpoint.
Definition hal_usb.h:432
#define USB_RTYPE_TYPE_MASK
Definition hal_usb.h:40
@ USB_ACTIVE
Definition hal_usb.h:274
int32_t msg_t
Definition chearly.h:87
uint64_t sysinterval_t
Type of time interval.
Definition chtime.h:118
#define TIME_INFINITE
Infinite interval specification for all functions with a timeout specification.
Definition chtime.h:54
HAL subsystem header.
Serial over USB Driver configuration structure.
usbep_t bulk_in
Bulk IN endpoint used for outgoing data transfer.
usbep_t bulk_out
Bulk OUT endpoint used for incoming data transfer.
usbep_t int_in
Interrupt IN endpoint used for notifications.
USBDriver * usbp
USB driver to use.
Full duplex serial driver class.
const struct SerialUSBDriverVMT * vmt
Virtual Methods Table.
SerialDriver virtual methods table.
Structure representing an USB driver.
uint8_t setup[8]
Setup packet buffer.
void * out_params[USB_MAX_ENDPOINTS]
Fields available to user, it can be used to associate an application-defined handler to an OUT endpoi...
void * in_params[USB_MAX_ENDPOINTS]
Fields available to user, it can be used to associate an application-defined handler to an IN endpoin...
const USBEndpointConfig * epc[USB_MAX_ENDPOINTS+1]
Active endpoints configurations.
uint16_t in_maxsize
IN endpoint maximum packet size.
USBInEndpointState * in_state
USBEndpointState associated to the IN endpoint.
size_t txsize
Requested transmit transfer size.
Definition hal_usb_lld.h:87
Type of Line Coding structure.