dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pios_usb_cdc.c
Go to the documentation of this file.
1 
17 /*
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 3 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful, but
24  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26  * for more details.
27  *
28  * You should have received a copy of the GNU General Public License along
29  * with this program; if not, see <http://www.gnu.org/licenses/>
30  */
31 
32 /* Project Includes */
33 #include "pios.h"
34 
35 #if defined(PIOS_INCLUDE_USB_CDC)
36 
37 #include "pios_usb.h"
38 #include "pios_usb_cdc_priv.h"
39 #include "pios_usb_board_data.h" /* PIOS_BOARD_*_DATA_LENGTH */
40 #include "pios_usbhook.h" /* PIOS_USBHOOK_* */
41 
42 /* Implement COM layer driver API */
43 static void PIOS_USB_CDC_RegisterTxCallback(uintptr_t usbcdc_id, pios_com_callback tx_out_cb, uintptr_t context);
44 static void PIOS_USB_CDC_RegisterRxCallback(uintptr_t usbcdc_id, pios_com_callback rx_in_cb, uintptr_t context);
45 static void PIOS_USB_CDC_TxStart(uintptr_t usbcdc_id, uint16_t tx_bytes_avail);
46 static void PIOS_USB_CDC_RxStart(uintptr_t usbcdc_id, uint16_t rx_bytes_avail);
47 static bool PIOS_USB_CDC_Available (uintptr_t usbcdc_id);
48 
50  .tx_start = PIOS_USB_CDC_TxStart,
51  .rx_start = PIOS_USB_CDC_RxStart,
52  .bind_tx_cb = PIOS_USB_CDC_RegisterTxCallback,
53  .bind_rx_cb = PIOS_USB_CDC_RegisterRxCallback,
54  .available = PIOS_USB_CDC_Available,
55 };
56 
57 enum pios_usb_cdc_dev_magic {
58  PIOS_USB_CDC_DEV_MAGIC = 0xAABBCCDD,
59 };
60 
61 struct pios_usb_cdc_dev {
62  enum pios_usb_cdc_dev_magic magic;
63  const struct pios_usb_cdc_cfg * cfg;
64 
65  uintptr_t lower_id;
66 
67  pios_com_callback rx_in_cb;
68  uintptr_t rx_in_context;
69  pios_com_callback tx_out_cb;
70  uintptr_t tx_out_context;
71 
72  bool usb_ctrl_if_enabled;
73  bool usb_data_if_enabled;
74 
75  uint8_t rx_packet_buffer[PIOS_USB_BOARD_CDC_DATA_LENGTH] __attribute__ ((aligned(4)));
76  volatile bool rx_active;
77 
78  /*
79  * NOTE: This is -1 as somewhat of a hack. It ensures that we always send packets
80  * that are strictly < maxPacketSize for this interface which means we never have
81  * to bother with zero length packets (ZLP).
82  */
83  uint8_t tx_packet_buffer[PIOS_USB_BOARD_CDC_DATA_LENGTH - 1] __attribute__ ((aligned(4)));
84  volatile bool tx_active;
85 
86  uint8_t ctrl_tx_packet_buffer[PIOS_USB_BOARD_CDC_MGMT_LENGTH] __attribute__ ((aligned(4)));
87 
88  uint32_t rx_dropped;
89  uint32_t rx_oversize;
90 
91  /*
92  * Used to hold the current state of the simulated UART. Changes to this
93  * variable may trigger new USB CDC Notification packets to be sent to the host.
94  */
95  volatile uint16_t prev_uart_state;
96 };
97 
98 static bool PIOS_USB_CDC_validate(struct pios_usb_cdc_dev * usb_cdc_dev)
99 {
100  return (usb_cdc_dev && (usb_cdc_dev->magic == PIOS_USB_CDC_DEV_MAGIC));
101 }
102 
103 static struct pios_usb_cdc_dev * PIOS_USB_CDC_alloc(void)
104 {
105  struct pios_usb_cdc_dev * usb_cdc_dev;
106 
107  usb_cdc_dev = (struct pios_usb_cdc_dev *)PIOS_malloc(sizeof(*usb_cdc_dev));
108  if (!usb_cdc_dev) return(NULL);
109 
110  memset(usb_cdc_dev, 0, sizeof(*usb_cdc_dev));
111  usb_cdc_dev->magic = PIOS_USB_CDC_DEV_MAGIC;
112  return(usb_cdc_dev);
113 }
114 
115 /* Implement USB_IFOPS for CDC Control Interface */
116 static void PIOS_USB_CDC_CTRL_IF_Init(uintptr_t usb_cdc_id);
117 static void PIOS_USB_CDC_CTRL_IF_DeInit(uintptr_t usb_cdc_id);
118 static bool PIOS_USB_CDC_CTRL_IF_Setup(uintptr_t usb_cdc_id, struct usb_setup_request *req);
119 static void PIOS_USB_CDC_CTRL_IF_CtrlDataOut(uintptr_t usb_cdc_id, const struct usb_setup_request *req);
120 
121 static struct pios_usb_ifops usb_cdc_ctrl_ifops = {
122  .init = PIOS_USB_CDC_CTRL_IF_Init,
123  .deinit = PIOS_USB_CDC_CTRL_IF_DeInit,
124  .setup = PIOS_USB_CDC_CTRL_IF_Setup,
125  .ctrl_data_out = PIOS_USB_CDC_CTRL_IF_CtrlDataOut,
126 };
127 
128 /* Implement USB_IFOPS for CDC Data Interface */
129 static void PIOS_USB_CDC_DATA_IF_Init(uintptr_t usb_cdc_id);
130 static void PIOS_USB_CDC_DATA_IF_DeInit(uintptr_t usb_cdc_id);
131 static bool PIOS_USB_CDC_DATA_IF_Setup(uintptr_t usb_cdc_id, struct usb_setup_request *req);
132 static void PIOS_USB_CDC_DATA_IF_CtrlDataOut(uintptr_t usb_cdc_id, const struct usb_setup_request *req);
133 
134 static struct pios_usb_ifops usb_cdc_data_ifops = {
135  .init = PIOS_USB_CDC_DATA_IF_Init,
136  .deinit = PIOS_USB_CDC_DATA_IF_DeInit,
137  .setup = PIOS_USB_CDC_DATA_IF_Setup,
138  .ctrl_data_out = PIOS_USB_CDC_DATA_IF_CtrlDataOut,
139 };
140 
141 static uintptr_t pios_usb_cdc_id;
142 
143 int32_t PIOS_USB_CDC_Init(uintptr_t * usbcdc_id, const struct pios_usb_cdc_cfg * cfg, uintptr_t lower_id)
144 {
145  PIOS_Assert(usbcdc_id);
146  PIOS_Assert(cfg);
147 
148  struct pios_usb_cdc_dev * usb_cdc_dev;
149 
150  usb_cdc_dev = (struct pios_usb_cdc_dev *) PIOS_USB_CDC_alloc();
151  if (!usb_cdc_dev) goto out_fail;
152 
153  /* Bind the configuration to the device instance */
154  usb_cdc_dev->cfg = cfg;
155  usb_cdc_dev->lower_id = lower_id;
156 
157  pios_usb_cdc_id = (uintptr_t) usb_cdc_dev;
158 
159  /* Rx and Tx are not active yet */
160  usb_cdc_dev->rx_active = false;
161  usb_cdc_dev->tx_active = false;
162 
163  /* Clear stats */
164  usb_cdc_dev->rx_dropped = 0;
165  usb_cdc_dev->rx_oversize = 0;
166 
167  /* Initialize the uart state */
168  usb_cdc_dev->prev_uart_state = 0;
169 
170  /* Register class specific interface callbacks with the USBHOOK layer */
171  usb_cdc_dev->usb_ctrl_if_enabled = false;
172  PIOS_USBHOOK_RegisterIfOps(cfg->ctrl_if, &usb_cdc_ctrl_ifops, (uintptr_t) usb_cdc_dev);
173 
174  /* Register class specific interface callbacks with the USBHOOK layer */
175  usb_cdc_dev->usb_data_if_enabled = false;
176  PIOS_USBHOOK_RegisterIfOps(cfg->data_if, &usb_cdc_data_ifops, (uintptr_t) usb_cdc_dev);
177 
178  *usbcdc_id = (uintptr_t) usb_cdc_dev;
179 
180  return 0;
181 
182 out_fail:
183  return -1;
184 }
185 
186 static bool PIOS_USB_CDC_SendData(struct pios_usb_cdc_dev * usb_cdc_dev)
187 {
188  uint16_t bytes_to_tx;
189 
190  if (!usb_cdc_dev->tx_out_cb) {
191  return false;
192  }
193 
194  bool need_yield = false;
195  bytes_to_tx = (usb_cdc_dev->tx_out_cb)(usb_cdc_dev->tx_out_context,
196  usb_cdc_dev->tx_packet_buffer,
197  sizeof(usb_cdc_dev->tx_packet_buffer),
198  NULL,
199  &need_yield);
200  if (bytes_to_tx == 0) {
201  usb_cdc_dev->tx_active = false;
202 
203  return false;
204  }
205 
206  /*
207  * Mark this endpoint as being tx active _before_ actually transmitting
208  * to make sure we don't race with the Tx completion interrupt
209  */
210  usb_cdc_dev->tx_active = true;
211 
212  PIOS_USBHOOK_EndpointTx(usb_cdc_dev->cfg->data_tx_ep,
213  usb_cdc_dev->tx_packet_buffer,
214  bytes_to_tx);
215 
216  return true;
217 }
218 
219 static void PIOS_USB_CDC_RxStart(uintptr_t usbcdc_id, uint16_t rx_bytes_avail) {
220  struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id;
221 
222  bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
223  PIOS_Assert(valid);
224 
225  /* Make sure this USB interface has been initialized */
226  if (!usb_cdc_dev->usb_data_if_enabled) {
227  return;
228  }
229 
230  if (!PIOS_USB_CheckAvailable(usb_cdc_dev->lower_id)) {
231  return;
232  }
233 
234  // If endpoint was stalled and there is now space make it valid
235  if (!usb_cdc_dev->rx_active && (rx_bytes_avail >= PIOS_USB_BOARD_CDC_DATA_LENGTH)) {
236  PIOS_USBHOOK_EndpointRx(usb_cdc_dev->cfg->data_rx_ep,
237  usb_cdc_dev->rx_packet_buffer,
238  sizeof(usb_cdc_dev->rx_packet_buffer));
239  usb_cdc_dev->rx_active = true;
240  }
241 }
242 
243 static void PIOS_USB_CDC_TxStart(uintptr_t usbcdc_id, uint16_t tx_bytes_avail)
244 {
245  struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id;
246 
247  bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
248  PIOS_Assert(valid);
249 
250  /* Make sure this USB interface has been initialized */
251  if (!usb_cdc_dev->usb_data_if_enabled) {
252  return;
253  }
254 
255  if (!PIOS_USB_CheckAvailable(usb_cdc_dev->lower_id)) {
256  return;
257  }
258 
259  if (!usb_cdc_dev->tx_active) {
260  /* Transmitter is not currently active, send a report */
261  PIOS_USB_CDC_SendData(usb_cdc_dev);
262  }
263 }
264 
265 static void PIOS_USB_CDC_RegisterRxCallback(uintptr_t usbcdc_id, pios_com_callback rx_in_cb, uintptr_t context)
266 {
267  struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id;
268 
269  bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
270  PIOS_Assert(valid);
271 
272  /*
273  * Order is important in these assignments since ISR uses _cb
274  * field to determine if it's ok to dereference _cb and _context
275  */
276  usb_cdc_dev->rx_in_context = context;
277  usb_cdc_dev->rx_in_cb = rx_in_cb;
278 }
279 
280 static void PIOS_USB_CDC_RegisterTxCallback(uintptr_t usbcdc_id, pios_com_callback tx_out_cb, uintptr_t context)
281 {
282  struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id;
283 
284  bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
285  PIOS_Assert(valid);
286 
287  /*
288  * Order is important in these assignments since ISR uses _cb
289  * field to determine if it's ok to dereference _cb and _context
290  */
291  usb_cdc_dev->tx_out_context = context;
292  usb_cdc_dev->tx_out_cb = tx_out_cb;
293 }
294 
295 static bool PIOS_USB_CDC_CTRL_EP_IN_Callback(uintptr_t usb_cdc_id, uint8_t epnum, uint16_t len);
296 
297 static void PIOS_USB_CDC_CTRL_IF_Init(uintptr_t usb_cdc_id)
298 {
299  struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usb_cdc_id;
300 
301  if (!PIOS_USB_CDC_validate(usb_cdc_dev)) {
302  return;
303  }
304 
305  /* Register endpoint specific callbacks with the USBHOOK layer */
306  PIOS_USBHOOK_RegisterEpInCallback(usb_cdc_dev->cfg->ctrl_tx_ep,
307  sizeof(usb_cdc_dev->ctrl_tx_packet_buffer),
308  PIOS_USB_CDC_CTRL_EP_IN_Callback,
309  (uintptr_t) usb_cdc_dev);
310  usb_cdc_dev->usb_ctrl_if_enabled = true;
311 }
312 
313 static void PIOS_USB_CDC_CTRL_IF_DeInit(uintptr_t usb_cdc_id)
314 {
315  struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usb_cdc_id;
316 
317  if (!PIOS_USB_CDC_validate(usb_cdc_dev)) {
318  return;
319  }
320 
321  /* reset state of the usb hid device structure */
322  usb_cdc_dev->usb_ctrl_if_enabled = false;
323 }
324 
325 static uint8_t cdc_altset;
326 static struct usb_cdc_line_coding line_coding = {
327  .dwDTERate = htousbl(57600),
328  .bCharFormat = USB_CDC_LINE_CODING_STOP_1,
329  .bParityType = USB_CDC_LINE_CODING_PARITY_NONE,
330  .bDataBits = 8,
331 };
332 
333 static uint16_t control_line_state;
334 
335 static bool PIOS_USB_CDC_CTRL_IF_Setup(uintptr_t usb_cdc_id, struct usb_setup_request *req)
336 {
337  struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usb_cdc_id;
338 
339  if (!PIOS_USB_CDC_validate(usb_cdc_dev)) {
340  return false;
341  }
342 
343  /* Make sure this is a request for an interface we know about */
344  uint8_t ifnum = req->wIndex & 0xFF;
345  if (ifnum != usb_cdc_dev->cfg->ctrl_if) {
346  return (false);
347  }
348 
351  switch (req->bRequest) {
353  PIOS_USBHOOK_CtrlTx(&cdc_altset, 1);
354  break;
356  cdc_altset = (uint8_t)(req->wValue);
357  break;
358  default:
359  /* Unhandled standard request */
360  return false;
361  break;
362  }
363  break;
365  switch (req->bRequest) {
367  PIOS_USBHOOK_CtrlRx((uint8_t *)&line_coding, sizeof(line_coding));
368  break;
370  PIOS_USBHOOK_CtrlTx((uint8_t *)&line_coding, sizeof(line_coding));
371  break;
373  control_line_state = req->wValue;
374  break;
375  default:
376  /* Unhandled class request */
377  return false;
378  break;
379  }
380  break;
381  default:
382  /* Unhandled request */
383  return false;
384  }
385 
386  return true;
387 }
388 
389 static bool PIOS_USB_CDC_Available (uintptr_t usbcdc_id)
390 {
391  struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id;
392 
393  bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
394  PIOS_Assert(valid);
395 
396  return PIOS_USB_CheckAvailable(usb_cdc_dev->lower_id);
397 }
398 
403 static void PIOS_USB_CDC_CTRL_IF_CtrlDataOut(uintptr_t usb_cdc_id, const struct usb_setup_request *req)
404 {
405  struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usb_cdc_id;
406 
407  if (!PIOS_USB_CDC_validate(usb_cdc_dev)) {
408  return;
409  }
410 
411  /* Make sure this is a request for an interface we know about */
412  uint8_t ifnum = req->wIndex & 0xFF;
413  if (ifnum != usb_cdc_dev->cfg->ctrl_if) {
414  return;
415  }
416 
419  switch (req->bRequest) {
420  default:
421  /* Unhandled standard request */
422  return;
423  break;
424  }
425  break;
427  switch (req->bRequest) {
429  /*
430  * If we cared to, this is where we would apply the new line coding
431  * that is now stored in the line_coding struct. This could be used
432  * to notify the upper COM layer that the baud rate has changed. This
433  * may be useful in the case of a COM USB bridge where we would
434  * auto-adjust the USART baud rate based on the line coding set here.
435  */
436  break;
437  default:
438  /* Unhandled class request */
439  return;
440  break;
441  }
442  break;
443  default:
444  /* Unhandled request */
445  return;
446  }
447 
448  return;
449 }
450 
451 static struct usb_cdc_serial_state_report uart_state = {
452  .bmRequestType = 0xA1,
453  .bNotification = USB_CDC_NOTIFICATION_SERIAL_STATE,
454  .wValue = 0,
455  .wIndex = htousbs(1),
456  .wLength = htousbs(2),
457  .bmUartState = htousbs(2 /* DSR */ | 1 /* DCD */),
458 };
459 
460 static bool PIOS_USB_CDC_CTRL_EP_IN_Callback(uintptr_t usb_cdc_id, uint8_t epnum, uint16_t len)
461 {
462  struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)pios_usb_cdc_id;
463 
464  bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
465  PIOS_Assert(valid);
466 
467  PIOS_USBHOOK_EndpointTx(usb_cdc_dev->cfg->ctrl_tx_ep,
468  (uint8_t *)&uart_state,
469  sizeof(uart_state));
470 
471  return true;
472 }
473 
474 static bool PIOS_USB_CDC_DATA_EP_IN_Callback(uintptr_t usb_cdc_id, uint8_t epnum, uint16_t len);
475 static bool PIOS_USB_CDC_DATA_EP_OUT_Callback(uintptr_t usb_cdc_id, uint8_t epnum, uint16_t len);
476 
477 static void PIOS_USB_CDC_DATA_IF_Init(uintptr_t usb_cdc_id)
478 {
479  struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usb_cdc_id;
480 
481  if (!PIOS_USB_CDC_validate(usb_cdc_dev)) {
482  return;
483  }
484 
485  /* Register endpoint specific callbacks with the USBHOOK layer */
486  PIOS_USBHOOK_RegisterEpInCallback(usb_cdc_dev->cfg->data_tx_ep,
487  sizeof(usb_cdc_dev->tx_packet_buffer),
488  PIOS_USB_CDC_DATA_EP_IN_Callback,
489  (uintptr_t) usb_cdc_dev);
490  PIOS_USBHOOK_RegisterEpOutCallback(usb_cdc_dev->cfg->data_rx_ep,
491  sizeof(usb_cdc_dev->rx_packet_buffer),
492  PIOS_USB_CDC_DATA_EP_OUT_Callback,
493  (uintptr_t) usb_cdc_dev);
494  usb_cdc_dev->usb_data_if_enabled = true;
495 }
496 
497 static void PIOS_USB_CDC_DATA_IF_DeInit(uintptr_t usb_cdc_id)
498 {
499  struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usb_cdc_id;
500 
501  if (!PIOS_USB_CDC_validate(usb_cdc_dev)) {
502  return;
503  }
504 
505  /* reset state of the usb hid device structure */
506  usb_cdc_dev->rx_active = false;
507  usb_cdc_dev->rx_dropped = 0;
508  usb_cdc_dev->rx_oversize = 0;
509  usb_cdc_dev->tx_active = false;
510  usb_cdc_dev->usb_data_if_enabled = false;
511 
512  /* DeRegister endpoint specific callbacks with the USBHOOK layer */
513  PIOS_USBHOOK_DeRegisterEpInCallback(usb_cdc_dev->cfg->data_tx_ep);
514  PIOS_USBHOOK_DeRegisterEpOutCallback(usb_cdc_dev->cfg->data_rx_ep);
515 }
516 
517 static bool PIOS_USB_CDC_DATA_IF_Setup(uintptr_t usb_cdc_id, struct usb_setup_request *req)
518 {
519  /* There are no valid EP0 transactions for CDC DATA interfaces */
520  PIOS_Assert(0);
521 
522  return false;
523 }
524 
529 static void PIOS_USB_CDC_DATA_IF_CtrlDataOut(uintptr_t usb_cdc_id, const struct usb_setup_request *req)
530 {
531  /* CDC DATA interfaces don't have any OUT data stages on the control endpoint */
532  PIOS_Assert(0);
533 }
534 
539 static bool PIOS_USB_CDC_DATA_EP_IN_Callback(uintptr_t usb_cdc_id, uint8_t epnum, uint16_t len)
540 {
541  struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)pios_usb_cdc_id;
542 
543  bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
544  PIOS_Assert(valid);
545 
546  bool rc = PIOS_USB_CDC_SendData(usb_cdc_dev);
547 
548  return rc;
549 }
550 
551 static bool PIOS_USB_CDC_DATA_EP_OUT_Callback(uintptr_t usb_cdc_id, uint8_t epnum, uint16_t len)
552 {
553  struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)pios_usb_cdc_id;
554 
555  if (!PIOS_USB_CDC_validate(usb_cdc_dev)) {
556  return false;
557  }
558 
559  if (len > sizeof(usb_cdc_dev->rx_packet_buffer)) {
560  len = sizeof(usb_cdc_dev->rx_packet_buffer);
561  }
562 
563  if (!usb_cdc_dev->rx_in_cb) {
564  /* No Rx call back registered, disable the receiver */
565  usb_cdc_dev->rx_active = false;
566  return false;
567  }
568 
569  uint16_t headroom;
570  bool need_yield = false;
571  uint16_t bytes_rxed;
572  bytes_rxed = (usb_cdc_dev->rx_in_cb)(usb_cdc_dev->rx_in_context,
573  usb_cdc_dev->rx_packet_buffer,
574  len,
575  &headroom,
576  &need_yield);
577 
578  if (bytes_rxed < len) {
579  /* Lost bytes on rx */
580  usb_cdc_dev->rx_dropped += (len - bytes_rxed);
581  }
582 
583  bool rc;
584  if (headroom >= sizeof(usb_cdc_dev->rx_packet_buffer)) {
585  /* We have room for a maximum length message */
586  PIOS_USBHOOK_EndpointRx(usb_cdc_dev->cfg->data_rx_ep,
587  usb_cdc_dev->rx_packet_buffer,
588  sizeof(usb_cdc_dev->rx_packet_buffer));
589  rc = true;
590  } else {
591  /* Not enough room left for a message, apply backpressure */
592  usb_cdc_dev->rx_active = false;
593  rc = false;
594  }
595 
596  return rc;
597 }
598 
599 #endif /* PIOS_INCLUDE_USB_CDC */
void PIOS_USBHOOK_CtrlTx(const uint8_t *buf, uint16_t len)
Definition: pios_usbhook.c:197
USB_CDC_LINE_CODING_STOP_1
Definition: pios_usb_defs.h:41
Main PiOS header to include all the compiled in PiOS options.
const struct pios_com_driver pios_usb_cdc_com_driver
#define USB_REQ_TYPE_CLASS
APIs for PIOS_USBHOOK layer.
void PIOS_USBHOOK_CtrlRx(uint8_t *buf, uint16_t len)
Definition: pios_usbhook.c:202
USB_CDC_NOTIFICATION_SERIAL_STATE
Definition: pios_usb_defs.h:41
#define USB_REQ_TYPE_MASK
#define USB_REQ_TYPE_STANDARD
void * PIOS_malloc(size_t size)
Definition: pios_heap.c:125
bool PIOS_USB_CheckAvailable(uintptr_t id)
#define USB_REQ_RECIPIENT_MASK
#define PIOS_USB_BOARD_CDC_MGMT_LENGTH
void(* init)(uintptr_t context)
Definition: pios_usbhook.h:55
static struct flyingpicmd_cfg_fa cfg
Definition: main.c:49
#define htousbs(v)
Definition: pios_usb_defs.h:77
void PIOS_USBHOOK_EndpointRx(uint8_t epnum, uint8_t *buf, uint16_t len)
Definition: pios_usbhook.c:214
#define USB_REQ_RECIPIENT_INTERFACE
void PIOS_USBHOOK_RegisterEpInCallback(uint8_t epnum, uint16_t max_len, pios_usbhook_epcb cb, uintptr_t context)
Definition: pios_usbhook.c:128
USB HID layer functions header.
uint32_t magic
void PIOS_USBHOOK_EndpointTx(uint8_t epnum, const uint8_t *buf, uint16_t len)
Definition: pios_usbhook.c:207
void PIOS_USBHOOK_DeRegisterEpInCallback(uint8_t epnum)
Definition: pios_usbhook.c:146
void PIOS_USBHOOK_RegisterEpOutCallback(uint8_t epnum, uint16_t max_len, pios_usbhook_epcb cb, uintptr_t context)
Definition: pios_usbhook.c:156
#define htousbl(v)
Definition: pios_usb_defs.h:78
#define PIOS_USB_BOARD_CDC_DATA_LENGTH
int32_t PIOS_USB_CDC_Init(uintptr_t *usbcdc_id, const struct pios_usb_cdc_cfg *cfg, uintptr_t lower_id)
USB COM CDC private definitions.
void PIOS_USBHOOK_DeRegisterEpOutCallback(uint8_t epnum)
Definition: pios_usbhook.c:188
#define PIOS_Assert(test)
Definition: pios_debug.h:52
USB_CDC_LINE_CODING_PARITY_NONE
Definition: pios_usb_defs.h:41
void(* tx_start)(uintptr_t id, uint16_t tx_bytes_avail)
Definition: pios_com.h:45
void PIOS_USBHOOK_RegisterIfOps(uint8_t ifnum, struct pios_usb_ifops *ifops, uintptr_t context)
Definition: pios_usbhook.c:113
uint16_t(* pios_com_callback)(uintptr_t context, uint8_t *buf, uint16_t buf_len, uint16_t *headroom, bool *task_woken)
Definition: pios_com.h:41
typedef __attribute__
Definition: serial_4way.h:43