36 #if defined(PIOS_INCLUDE_USB_CDC)
45 static void PIOS_USB_CDC_RegisterTxCallback(uintptr_t usbcdc_id,
pios_com_callback tx_out_cb, uintptr_t context);
46 static void PIOS_USB_CDC_RegisterRxCallback(uintptr_t usbcdc_id,
pios_com_callback rx_in_cb, uintptr_t context);
47 static void PIOS_USB_CDC_TxStart(uintptr_t usbcdc_id, uint16_t tx_bytes_avail);
48 static void PIOS_USB_CDC_RxStart(uintptr_t usbcdc_id, uint16_t rx_bytes_avail);
49 static bool PIOS_USB_CDC_Available (uintptr_t usbcdc_id);
53 .rx_start = PIOS_USB_CDC_RxStart,
54 .bind_tx_cb = PIOS_USB_CDC_RegisterTxCallback,
55 .bind_rx_cb = PIOS_USB_CDC_RegisterRxCallback,
56 .available = PIOS_USB_CDC_Available,
59 enum pios_usb_cdc_dev_magic {
60 PIOS_USB_CDC_DEV_MAGIC = 0xAABBCCDD,
63 struct pios_usb_cdc_dev {
64 enum pios_usb_cdc_dev_magic
magic;
70 uintptr_t rx_in_context;
72 uintptr_t tx_out_context;
86 static bool PIOS_USB_CDC_validate(
struct pios_usb_cdc_dev * usb_cdc_dev)
88 return (usb_cdc_dev->magic == PIOS_USB_CDC_DEV_MAGIC);
91 static struct pios_usb_cdc_dev * PIOS_USB_CDC_alloc(
void)
93 struct pios_usb_cdc_dev * usb_cdc_dev;
95 usb_cdc_dev = (
struct pios_usb_cdc_dev *)
PIOS_malloc(
sizeof(*usb_cdc_dev));
96 if (!usb_cdc_dev)
return(NULL);
98 memset(usb_cdc_dev, 0,
sizeof(*usb_cdc_dev));
99 usb_cdc_dev->magic = PIOS_USB_CDC_DEV_MAGIC;
103 static void PIOS_USB_CDC_DATA_EP_IN_Callback(
void);
104 static void PIOS_USB_CDC_DATA_EP_OUT_Callback(
void);
105 static void PIOS_USB_CDC_CTRL_EP_IN_Callback(
void);
107 static uintptr_t pios_usb_cdc_id;
118 struct pios_usb_cdc_dev * usb_cdc_dev;
120 usb_cdc_dev = (
struct pios_usb_cdc_dev *) PIOS_USB_CDC_alloc();
121 if (!usb_cdc_dev)
goto out_fail;
124 usb_cdc_dev->cfg =
cfg;
125 usb_cdc_dev->lower_id = lower_id;
127 pios_usb_cdc_id = (uintptr_t) usb_cdc_dev;
134 *usbcdc_id = (uintptr_t) usb_cdc_dev;
144 static void PIOS_USB_CDC_RegisterRxCallback(uintptr_t usbcdc_id,
pios_com_callback rx_in_cb, uintptr_t context)
146 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)usbcdc_id;
148 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
155 usb_cdc_dev->rx_in_context = context;
156 usb_cdc_dev->rx_in_cb = rx_in_cb;
159 static void PIOS_USB_CDC_RegisterTxCallback(uintptr_t usbcdc_id,
pios_com_callback tx_out_cb, uintptr_t context)
161 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)usbcdc_id;
163 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
170 usb_cdc_dev->tx_out_context = context;
171 usb_cdc_dev->tx_out_cb = tx_out_cb;
174 static void PIOS_USB_CDC_RxStart(uintptr_t usbcdc_id, uint16_t rx_bytes_avail) {
175 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)usbcdc_id;
177 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
186 if ((GetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep) != EP_RX_VALID) &&
187 (rx_bytes_avail >=
sizeof(usb_cdc_dev->rx_packet_buffer))) {
188 SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_VALID);
193 static void PIOS_USB_CDC_SendData(
struct pios_usb_cdc_dev * usb_cdc_dev)
195 uint16_t bytes_to_tx;
197 if (!usb_cdc_dev->tx_out_cb) {
201 bool need_yield =
false;
202 bytes_to_tx = (usb_cdc_dev->tx_out_cb)(usb_cdc_dev->tx_out_context,
203 usb_cdc_dev->tx_packet_buffer,
204 sizeof(usb_cdc_dev->tx_packet_buffer),
207 if (bytes_to_tx == 0) {
211 UserToPMABufferCopy(usb_cdc_dev->tx_packet_buffer,
212 GetEPTxAddr(usb_cdc_dev->cfg->data_tx_ep),
214 SetEPTxCount(usb_cdc_dev->cfg->data_tx_ep, bytes_to_tx);
215 SetEPTxValid(usb_cdc_dev->cfg->data_tx_ep);
218 static void PIOS_USB_CDC_TxStart(uintptr_t usbcdc_id, uint16_t tx_bytes_avail)
220 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)usbcdc_id;
222 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
229 if (GetEPTxStatus(usb_cdc_dev->cfg->data_tx_ep) == EP_TX_VALID) {
234 PIOS_USB_CDC_SendData(usb_cdc_dev);
237 static void PIOS_USB_CDC_DATA_EP_IN_Callback(
void)
239 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)pios_usb_cdc_id;
241 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
244 PIOS_USB_CDC_SendData(usb_cdc_dev);
247 static void PIOS_USB_CDC_DATA_EP_OUT_Callback(
void)
249 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)pios_usb_cdc_id;
251 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
257 DataLength = GetEPRxCount(usb_cdc_dev->cfg->data_rx_ep);
258 if (DataLength >
sizeof(usb_cdc_dev->rx_packet_buffer)) {
259 usb_cdc_dev->rx_oversize++;
260 DataLength =
sizeof(usb_cdc_dev->rx_packet_buffer);
264 PMAToUserBufferCopy((uint8_t *) usb_cdc_dev->rx_packet_buffer,
265 GetEPRxAddr(usb_cdc_dev->cfg->data_rx_ep),
268 if (!usb_cdc_dev->rx_in_cb) {
270 SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_NAK);
275 bool need_yield =
false;
277 rc = (usb_cdc_dev->rx_in_cb)(usb_cdc_dev->rx_in_context,
278 usb_cdc_dev->rx_packet_buffer,
283 if (rc < DataLength) {
285 usb_cdc_dev->rx_dropped += (DataLength - rc);
288 if (headroom >=
sizeof(usb_cdc_dev->rx_packet_buffer)) {
290 SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_VALID);
293 SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_NAK);
297 static uint16_t control_line_state;
300 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)pios_usb_cdc_id;
302 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
305 return USB_UNSUPPORT;
308 uint8_t wValue0 = pInformation->USBwValue0;
309 uint8_t wValue1 = pInformation->USBwValue1;
311 control_line_state = wValue1 << 8 | wValue0;
316 static bool PIOS_USB_CDC_Available (uintptr_t usbcdc_id)
318 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)usbcdc_id;
320 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
335 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)pios_usb_cdc_id;
337 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
345 pInformation->Ctrl_Info.Usb_wLength =
sizeof(line_coding);
346 pInformation->Ctrl_Info.Usb_rLength =
sizeof(line_coding);
350 return ((uint8_t *) &line_coding);
356 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)pios_usb_cdc_id;
358 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
365 pInformation->Ctrl_Info.Usb_wLength =
sizeof(line_coding);
368 return ((uint8_t *) &line_coding);
378 .bmUartState =
htousbs(2 | 1 ),
381 static void PIOS_USB_CDC_CTRL_EP_IN_Callback(
void)
383 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)pios_usb_cdc_id;
385 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
388 UserToPMABufferCopy((
const uint8_t *) &uart_state,
389 GetEPTxAddr(usb_cdc_dev->cfg->ctrl_tx_ep),
393 SetEPTxValid(usb_cdc_dev->cfg->ctrl_tx_ep);
void(* pEpInt_IN[7])(void)
USB_CDC_LINE_CODING_STOP_1
int32_t PIOS_IRQ_Enable(void)
Main PiOS header to include all the compiled in PiOS options.
const struct pios_com_driver pios_usb_cdc_com_driver
USB_CDC_NOTIFICATION_SERIAL_STATE
void * PIOS_malloc(size_t size)
bool PIOS_USB_CheckAvailable(uintptr_t id)
uint8_t * PIOS_USB_CDC_SetLineCoding(uint16_t Length)
#define PIOS_USB_BOARD_CDC_MGMT_LENGTH
static struct flyingpicmd_cfg_fa cfg
const uint8_t * PIOS_USB_CDC_GetLineCoding(uint16_t Length)
USB HID layer functions header.
int32_t PIOS_IRQ_Disable(void)
#define PIOS_USB_BOARD_CDC_DATA_LENGTH
RESULT PIOS_USB_CDC_SetControlLineState(void)
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.
#define PIOS_Assert(test)
USB_CDC_LINE_CODING_PARITY_NONE
void(* tx_start)(uintptr_t id, uint16_t tx_bytes_avail)
void(* pEpInt_OUT[7])(void)
uint16_t(* pios_com_callback)(uintptr_t context, uint8_t *buf, uint16_t buf_len, uint16_t *headroom, bool *task_woken)