ChibiOS/HAL 9.0.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 */
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 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
156static const struct SerialUSBDriverVMT vmt = {
157 (size_t)0,
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 */
168static 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 */
178static 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 */
210void 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 * @return The operation status.
241 *
242 * @api
243 */
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
253 usbp->in_params[config->bulk_in - 1U] = sdup;
254 usbp->out_params[config->bulk_out - 1U] = sdup;
255 if (config->int_in > 0U) {
256 usbp->in_params[config->int_in - 1U] = sdup;
257 }
258 sdup->config = config;
259 sdup->state = SDU_READY;
260
262
263 return HAL_RET_SUCCESS;
264}
265
266/**
267 * @brief Stops the driver.
268 * @details Any thread waiting on the driver's queues will be awakened with
269 * the message @p MSG_RESET.
270 *
271 * @param[in] sdup pointer to a @p SerialUSBDriver object
272 *
273 * @api
274 */
276 USBDriver *usbp = sdup->config->usbp;
277
278 osalDbgCheck(sdup != NULL);
279
280 osalSysLock();
281
282 osalDbgAssert((sdup->state == SDU_STOP) || (sdup->state == SDU_READY),
283 "invalid state");
284
285 /* Driver in stopped state.*/
286 usbp->in_params[sdup->config->bulk_in - 1U] = NULL;
287 usbp->out_params[sdup->config->bulk_out - 1U] = NULL;
288 if (sdup->config->int_in > 0U) {
289 usbp->in_params[sdup->config->int_in - 1U] = NULL;
290 }
291 sdup->config = NULL;
292 sdup->state = SDU_STOP;
293
294 /* Enforces a disconnection.*/
296 ibqResetI(&sdup->ibqueue);
297 obqResetI(&sdup->obqueue);
299
301}
302
303/**
304 * @brief USB device suspend handler.
305 * @details Generates a @p CHN_DISCONNECT event and puts queues in
306 * non-blocking mode, this way the application cannot get stuck
307 * in the middle of an I/O operations.
308 * @note If this function is not called from an ISR then an explicit call
309 * to @p osalOsRescheduleS() in necessary afterward.
310 *
311 * @param[in] sdup pointer to a @p SerialUSBDriver object
312 *
313 * @iclass
314 */
316
317 /* Avoiding events spam.*/
318 if (bqIsSuspendedX(&sdup->ibqueue) && bqIsSuspendedX(&sdup->obqueue)) {
319 return;
320 }
322 bqSuspendI(&sdup->ibqueue);
323 bqSuspendI(&sdup->obqueue);
324}
325
326/**
327 * @brief USB device wakeup handler.
328 * @details Generates a @p CHN_CONNECT event and resumes normal queues
329 * operations.
330 *
331 * @note If this function is not called from an ISR then an explicit call
332 * to @p osalOsRescheduleS() in necessary afterward.
333 *
334 * @param[in] sdup pointer to a @p SerialUSBDriver object
335 *
336 * @iclass
337 */
339
341 bqResumeX(&sdup->ibqueue);
342 bqResumeX(&sdup->obqueue);
343}
344
345/**
346 * @brief USB device configured handler.
347 *
348 * @param[in] sdup pointer to a @p SerialUSBDriver object
349 *
350 * @iclass
351 */
353
354 ibqResetI(&sdup->ibqueue);
355 bqResumeX(&sdup->ibqueue);
356 obqResetI(&sdup->obqueue);
357 bqResumeX(&sdup->obqueue);
359 (void) sdu_start_receive(sdup);
360}
361
362/**
363 * @brief Default requests hook.
364 * @details Applications wanting to use the Serial over USB driver can use
365 * this function as requests hook in the USB configuration.
366 * The following requests are emulated:
367 * - CDC_GET_LINE_CODING.
368 * - CDC_SET_LINE_CODING.
369 * - CDC_SET_CONTROL_LINE_STATE.
370 * .
371 *
372 * @param[in] usbp pointer to the @p USBDriver object
373 * @return The hook status.
374 * @retval true Message handled internally.
375 * @retval false Message not handled.
376 */
378
379 if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) {
380 switch (usbp->setup[1]) {
382 usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL);
383 return true;
385 usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL);
386 return true;
388 /* Nothing to do, there are no control lines.*/
389 usbSetupTransfer(usbp, NULL, 0, NULL);
390 return true;
391 default:
392 return false;
393 }
394 }
395 return false;
396}
397
398/**
399 * @brief SOF handler.
400 * @details The SOF interrupt is used for automatic flushing of incomplete
401 * buffers pending in the output queue.
402 *
403 * @param[in] sdup pointer to a @p SerialUSBDriver object
404 *
405 * @iclass
406 */
408
409 /* If the USB driver is not in the appropriate state then transactions
410 must not be started.*/
411 if ((usbGetDriverStateI(sdup->config->usbp) != USB_ACTIVE) ||
412 (sdup->state != SDU_READY)) {
413 return;
414 }
415
416 /* If there is already a transaction ongoing then another one cannot be
417 started.*/
418 if (usbGetTransmitStatusI(sdup->config->usbp, sdup->config->bulk_in)) {
419 return;
420 }
421
422 /* Checking if there only a buffer partially filled, if so then it is
423 enforced in the queue and transmitted.*/
424 if (obqTryFlushI(&sdup->obqueue)) {
425 size_t n;
426 uint8_t *buf = obqGetFullBufferI(&sdup->obqueue, &n);
427
428 osalDbgAssert(buf != NULL, "queue is empty");
429
430 usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in, buf, n);
431 }
432}
433
434/**
435 * @brief Default data transmitted callback.
436 * @details The application must use this function as callback for the IN
437 * data endpoint.
438 *
439 * @param[in] usbp pointer to the @p USBDriver object
440 * @param[in] ep IN endpoint number
441 */
443 uint8_t *buf;
444 size_t n;
445 SerialUSBDriver *sdup = usbp->in_params[ep - 1U];
446
447 if (sdup == NULL) {
448 return;
449 }
450
452
453 /* Signaling that space is available in the output queue.*/
455
456 /* Freeing the buffer just transmitted, if it was not a zero size packet.*/
457 if (usbp->epc[ep]->in_state->txsize > 0U) {
458 obqReleaseEmptyBufferI(&sdup->obqueue);
459 }
460
461 /* Checking if there is a buffer ready for transmission.*/
462 buf = obqGetFullBufferI(&sdup->obqueue, &n);
463
464 if (buf != NULL) {
465 /* The endpoint cannot be busy, we are in the context of the callback,
466 so it is safe to transmit without a check.*/
467 usbStartTransmitI(usbp, ep, buf, n);
468 }
469 else if ((usbp->epc[ep]->in_state->txsize > 0U) &&
470 ((usbp->epc[ep]->in_state->txsize &
471 ((size_t)usbp->epc[ep]->in_maxsize - 1U)) == 0U)) {
472 /* Transmit zero sized packet in case the last one has maximum allowed
473 size. Otherwise the recipient may expect more data coming soon and
474 not return buffered data to app. See section 5.8.3 Bulk Transfer
475 Packet Size Constraints of the USB Specification document.*/
476 usbStartTransmitI(usbp, ep, usbp->setup, 0);
477
478 }
479 else {
480 /* Nothing to transmit.*/
481 }
482
484}
485
486/**
487 * @brief Default data received callback.
488 * @details The application must use this function as callback for the OUT
489 * data endpoint.
490 *
491 * @param[in] usbp pointer to the @p USBDriver object
492 * @param[in] ep OUT endpoint number
493 */
495 size_t size;
496 SerialUSBDriver *sdup = usbp->out_params[ep - 1U];
497
498 if (sdup == NULL) {
499 return;
500 }
501
503
504 /* Checking for zero-size transactions.*/
505 size = usbGetReceiveTransactionSizeX(sdup->config->usbp,
506 sdup->config->bulk_out);
507 if (size > (size_t)0) {
508 /* Signaling that data is available in the input queue.*/
510
511 /* Posting the filled buffer in the queue.*/
512 ibqPostFullBufferI(&sdup->ibqueue, size);
513 }
514
515 /* The endpoint cannot be busy, we are in the context of the callback,
516 so a packet is in the buffer for sure. Trying to get a free buffer
517 for the next transaction.*/
518 (void) sdu_start_receive(sdup);
519
521}
522
523/**
524 * @brief Default data received callback.
525 * @details The application must use this function as callback for the IN
526 * interrupt endpoint.
527 *
528 * @param[in] usbp pointer to the @p USBDriver object
529 * @param[in] ep endpoint number
530 */
532
533 (void)usbp;
534 (void)ep;
535}
536
537/**
538 * @brief Control operation on a serial USB port.
539 *
540 * @param[in] usbp pointer to a @p USBDriver object
541 * @param[in] operation control operation code
542 * @param[in,out] arg operation argument
543 *
544 * @return The control operation status.
545 * @retval MSG_OK in case of success.
546 * @retval MSG_TIMEOUT in case of operation timeout.
547 * @retval MSG_RESET in case of operation reset.
548 *
549 * @api
550 */
551msg_t sduControl(USBDriver *usbp, unsigned int operation, void *arg) {
552
553 return _ctl((void *)usbp, operation, arg);
554}
555
556#endif /* HAL_USE_SERIAL_USB == TRUE */
557
558/** @} */
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 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 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
int32_t msg_t
Type of a message.
Definition osal.h:159
uint32_t sysinterval_t
Type of system time interval.
Definition osal.h:169
#define MSG_OK
Definition osal.h:56
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
#define TIME_INFINITE
Definition osal.h:66
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)
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.
msg_t sduControl(USBDriver *usbp, unsigned int operation, void *arg)
Control operation on a serial USB port.
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:479
#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:518
#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:476
#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
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.