35 #if defined(PIOS_INCLUDE_USB_CDC)
44 static void PIOS_USB_CDC_RegisterTxCallback(uintptr_t usbcdc_id,
pios_com_callback tx_out_cb, uintptr_t context);
45 static void PIOS_USB_CDC_RegisterRxCallback(uintptr_t usbcdc_id,
pios_com_callback rx_in_cb, uintptr_t context);
46 static void PIOS_USB_CDC_TxStart(uintptr_t usbcdc_id, uint16_t tx_bytes_avail);
47 static void PIOS_USB_CDC_RxStart(uintptr_t usbcdc_id, uint16_t rx_bytes_avail);
48 static bool PIOS_USB_CDC_Available (uintptr_t usbcdc_id);
52 .rx_start = PIOS_USB_CDC_RxStart,
53 .bind_tx_cb = PIOS_USB_CDC_RegisterTxCallback,
54 .bind_rx_cb = PIOS_USB_CDC_RegisterRxCallback,
55 .available = PIOS_USB_CDC_Available,
58 enum pios_usb_cdc_dev_magic {
59 PIOS_USB_CDC_DEV_MAGIC = 0xAABBCCDD,
62 struct pios_usb_cdc_dev {
63 enum pios_usb_cdc_dev_magic
magic;
69 uintptr_t rx_in_context;
71 uintptr_t tx_out_context;
85 static bool PIOS_USB_CDC_validate(
struct pios_usb_cdc_dev * usb_cdc_dev)
87 return (usb_cdc_dev->magic == PIOS_USB_CDC_DEV_MAGIC);
90 static struct pios_usb_cdc_dev * PIOS_USB_CDC_alloc(
void)
92 struct pios_usb_cdc_dev * usb_cdc_dev;
94 usb_cdc_dev = (
struct pios_usb_cdc_dev *)
PIOS_malloc(
sizeof(*usb_cdc_dev));
95 if (!usb_cdc_dev)
return(NULL);
97 memset(usb_cdc_dev, 0,
sizeof(*usb_cdc_dev));
98 usb_cdc_dev->magic = PIOS_USB_CDC_DEV_MAGIC;
102 static void PIOS_USB_CDC_DATA_EP_IN_Callback(
void);
103 static void PIOS_USB_CDC_DATA_EP_OUT_Callback(
void);
104 static void PIOS_USB_CDC_CTRL_EP_IN_Callback(
void);
106 static uintptr_t pios_usb_cdc_id;
117 struct pios_usb_cdc_dev * usb_cdc_dev;
119 usb_cdc_dev = (
struct pios_usb_cdc_dev *) PIOS_USB_CDC_alloc();
120 if (!usb_cdc_dev)
goto out_fail;
123 usb_cdc_dev->cfg =
cfg;
124 usb_cdc_dev->lower_id = lower_id;
126 pios_usb_cdc_id = (uintptr_t) usb_cdc_dev;
133 *usbcdc_id = (uintptr_t) usb_cdc_dev;
143 static void PIOS_USB_CDC_RegisterRxCallback(uintptr_t usbcdc_id,
pios_com_callback rx_in_cb, uintptr_t context)
145 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)usbcdc_id;
147 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
154 usb_cdc_dev->rx_in_context = context;
155 usb_cdc_dev->rx_in_cb = rx_in_cb;
158 static void PIOS_USB_CDC_RegisterTxCallback(uintptr_t usbcdc_id,
pios_com_callback tx_out_cb, uintptr_t context)
160 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)usbcdc_id;
162 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
169 usb_cdc_dev->tx_out_context = context;
170 usb_cdc_dev->tx_out_cb = tx_out_cb;
173 static void PIOS_USB_CDC_RxStart(uintptr_t usbcdc_id, uint16_t rx_bytes_avail) {
174 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)usbcdc_id;
176 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
185 if ((GetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep) != EP_RX_VALID) &&
186 (rx_bytes_avail >=
sizeof(usb_cdc_dev->rx_packet_buffer))) {
187 SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_VALID);
192 static void PIOS_USB_CDC_SendData(
struct pios_usb_cdc_dev * usb_cdc_dev)
194 uint16_t bytes_to_tx;
196 if (!usb_cdc_dev->tx_out_cb) {
200 bool need_yield =
false;
201 bytes_to_tx = (usb_cdc_dev->tx_out_cb)(usb_cdc_dev->tx_out_context,
202 usb_cdc_dev->tx_packet_buffer,
203 sizeof(usb_cdc_dev->tx_packet_buffer),
206 if (bytes_to_tx == 0) {
210 UserToPMABufferCopy(usb_cdc_dev->tx_packet_buffer,
211 GetEPTxAddr(usb_cdc_dev->cfg->data_tx_ep),
213 SetEPTxCount(usb_cdc_dev->cfg->data_tx_ep, bytes_to_tx);
214 SetEPTxValid(usb_cdc_dev->cfg->data_tx_ep);
217 static void PIOS_USB_CDC_TxStart(uintptr_t usbcdc_id, uint16_t tx_bytes_avail)
219 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)usbcdc_id;
221 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
228 if (GetEPTxStatus(usb_cdc_dev->cfg->data_tx_ep) == EP_TX_VALID) {
233 PIOS_USB_CDC_SendData(usb_cdc_dev);
236 static void PIOS_USB_CDC_DATA_EP_IN_Callback(
void)
238 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)pios_usb_cdc_id;
240 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
243 PIOS_USB_CDC_SendData(usb_cdc_dev);
246 static void PIOS_USB_CDC_DATA_EP_OUT_Callback(
void)
248 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)pios_usb_cdc_id;
250 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
256 DataLength = GetEPRxCount(usb_cdc_dev->cfg->data_rx_ep);
257 if (DataLength >
sizeof(usb_cdc_dev->rx_packet_buffer)) {
258 usb_cdc_dev->rx_oversize++;
259 DataLength =
sizeof(usb_cdc_dev->rx_packet_buffer);
263 PMAToUserBufferCopy((uint8_t *) usb_cdc_dev->rx_packet_buffer,
264 GetEPRxAddr(usb_cdc_dev->cfg->data_rx_ep),
267 if (!usb_cdc_dev->rx_in_cb) {
269 SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_NAK);
274 bool need_yield =
false;
276 rc = (usb_cdc_dev->rx_in_cb)(usb_cdc_dev->rx_in_context,
277 usb_cdc_dev->rx_packet_buffer,
282 if (rc < DataLength) {
284 usb_cdc_dev->rx_dropped += (DataLength - rc);
287 if (headroom >=
sizeof(usb_cdc_dev->rx_packet_buffer)) {
289 SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_VALID);
292 SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_NAK);
296 static uint16_t control_line_state;
299 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)pios_usb_cdc_id;
301 bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
304 return USB_UNSUPPORT;
307 uint8_t wValue0 = pInformation->USBwValue0;
308 uint8_t wValue1 = pInformation->USBwValue1;
310 control_line_state = wValue1 << 8 | wValue0;
315 static bool PIOS_USB_CDC_Available (uintptr_t usbcdc_id)
317 struct pios_usb_cdc_dev * usb_cdc_dev = (
struct pios_usb_cdc_dev *)usbcdc_id;
319 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);
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);
401 UserToPMABufferCopy((uint8_t *) &uart_state,
402 GetEPTxAddr(usb_cdc_dev->cfg->ctrl_tx_ep),
405 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
#define USB_CDC_CONTROL_LINE_STATE_DTE_PRESENT
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)