36 #if defined(PIOS_INCLUDE_USB_HID)
45 static void PIOS_USB_HID_RegisterTxCallback(uintptr_t usbhid_id,
pios_com_callback tx_out_cb, uintptr_t context);
46 static void PIOS_USB_HID_RegisterRxCallback(uintptr_t usbhid_id,
pios_com_callback rx_in_cb, uintptr_t context);
47 static void PIOS_USB_HID_TxStart(uintptr_t usbhid_id, uint16_t tx_bytes_avail);
48 static void PIOS_USB_HID_RxStart(uintptr_t usbhid_id, uint16_t rx_bytes_avail);
52 .rx_start = PIOS_USB_HID_RxStart,
53 .bind_tx_cb = PIOS_USB_HID_RegisterTxCallback,
54 .bind_rx_cb = PIOS_USB_HID_RegisterRxCallback,
58 enum pios_usb_hid_dev_magic {
59 PIOS_USB_HID_DEV_MAGIC = 0xAA00BB00,
62 struct pios_usb_hid_dev {
63 enum pios_usb_hid_dev_magic
magic;
69 uintptr_t rx_in_context;
71 uintptr_t tx_out_context;
80 static bool PIOS_USB_HID_validate(
struct pios_usb_hid_dev * usb_hid_dev)
82 return (usb_hid_dev->magic == PIOS_USB_HID_DEV_MAGIC);
85 static struct pios_usb_hid_dev * PIOS_USB_HID_alloc(
void)
87 struct pios_usb_hid_dev * usb_hid_dev;
89 usb_hid_dev = (
struct pios_usb_hid_dev *)
PIOS_malloc(
sizeof(*usb_hid_dev));
90 if (!usb_hid_dev)
return(NULL);
92 memset(usb_hid_dev, 0,
sizeof(*usb_hid_dev));
93 usb_hid_dev->magic = PIOS_USB_HID_DEV_MAGIC;
97 static void PIOS_USB_HID_EP_IN_Callback(
void);
98 static void PIOS_USB_HID_EP_OUT_Callback(
void);
100 static uintptr_t pios_usb_hid_id;
111 struct pios_usb_hid_dev * usb_hid_dev;
113 usb_hid_dev = (
struct pios_usb_hid_dev *) PIOS_USB_HID_alloc();
114 if (!usb_hid_dev)
goto out_fail;
117 usb_hid_dev->cfg =
cfg;
118 usb_hid_dev->lower_id = lower_id;
120 pios_usb_hid_id = (uintptr_t) usb_hid_dev;
126 *usbhid_id = (uintptr_t) usb_hid_dev;
137 static void PIOS_USB_HID_SendReport(
struct pios_usb_hid_dev * usb_hid_dev)
139 uint16_t bytes_to_tx;
141 if (!usb_hid_dev->tx_out_cb) {
145 bool need_yield =
false;
146 #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
147 bytes_to_tx = (usb_hid_dev->tx_out_cb)(usb_hid_dev->tx_out_context,
148 &usb_hid_dev->tx_packet_buffer[1],
149 sizeof(usb_hid_dev->tx_packet_buffer)-1,
153 bytes_to_tx = (usb_hid_dev->tx_out_cb)(usb_hid_dev->tx_out_context,
154 &usb_hid_dev->tx_packet_buffer[2],
155 sizeof(usb_hid_dev->tx_packet_buffer)-2,
159 if (bytes_to_tx == 0) {
164 usb_hid_dev->tx_packet_buffer[0] = 1;
166 #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
167 UserToPMABufferCopy(usb_hid_dev->tx_packet_buffer,
168 GetEPTxAddr(usb_hid_dev->cfg->data_tx_ep),
171 usb_hid_dev->tx_packet_buffer[1] = bytes_to_tx;
172 UserToPMABufferCopy(usb_hid_dev->tx_packet_buffer,
173 GetEPTxAddr(usb_hid_dev->cfg->data_tx_ep),
177 SetEPTxCount(usb_hid_dev->cfg->data_tx_ep,
sizeof(usb_hid_dev->tx_packet_buffer));
178 SetEPTxValid(usb_hid_dev->cfg->data_tx_ep);
181 static void PIOS_USB_HID_RxStart(uintptr_t usbhid_id, uint16_t rx_bytes_avail) {
182 struct pios_usb_hid_dev * usb_hid_dev = (
struct pios_usb_hid_dev *)usbhid_id;
184 bool valid = PIOS_USB_HID_validate(usb_hid_dev);
192 #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
199 if ((GetEPRxStatus(usb_hid_dev->cfg->data_rx_ep) != EP_RX_VALID) &&
200 (rx_bytes_avail >= max_payload_length)) {
201 SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_VALID);
206 static void PIOS_USB_HID_TxStart(uintptr_t usbhid_id, uint16_t tx_bytes_avail)
208 struct pios_usb_hid_dev * usb_hid_dev = (
struct pios_usb_hid_dev *)usbhid_id;
210 bool valid = PIOS_USB_HID_validate(usb_hid_dev);
217 if (GetEPTxStatus(usb_hid_dev->cfg->data_tx_ep) == EP_TX_VALID) {
222 PIOS_USB_HID_SendReport(usb_hid_dev);
225 static void PIOS_USB_HID_RegisterRxCallback(uintptr_t usbhid_id,
pios_com_callback rx_in_cb, uintptr_t context)
227 struct pios_usb_hid_dev * usb_hid_dev = (
struct pios_usb_hid_dev *)usbhid_id;
229 bool valid = PIOS_USB_HID_validate(usb_hid_dev);
236 usb_hid_dev->rx_in_context = context;
237 usb_hid_dev->rx_in_cb = rx_in_cb;
240 static void PIOS_USB_HID_RegisterTxCallback(uintptr_t usbhid_id,
pios_com_callback tx_out_cb, uintptr_t context)
242 struct pios_usb_hid_dev * usb_hid_dev = (
struct pios_usb_hid_dev *)usbhid_id;
244 bool valid = PIOS_USB_HID_validate(usb_hid_dev);
251 usb_hid_dev->tx_out_context = context;
252 usb_hid_dev->tx_out_cb = tx_out_cb;
259 static void PIOS_USB_HID_EP_IN_Callback(
void)
261 struct pios_usb_hid_dev * usb_hid_dev = (
struct pios_usb_hid_dev *)pios_usb_hid_id;
263 bool valid = PIOS_USB_HID_validate(usb_hid_dev);
270 PIOS_USB_HID_SendReport(usb_hid_dev);
276 static void PIOS_USB_HID_EP_OUT_Callback(
void)
278 struct pios_usb_hid_dev * usb_hid_dev = (
struct pios_usb_hid_dev *)pios_usb_hid_id;
280 bool valid = PIOS_USB_HID_validate(usb_hid_dev);
287 DataLength = GetEPRxCount(usb_hid_dev->cfg->data_rx_ep);
288 if (DataLength >
sizeof(usb_hid_dev->rx_packet_buffer)) {
289 DataLength =
sizeof(usb_hid_dev->rx_packet_buffer);
293 PMAToUserBufferCopy((uint8_t *) usb_hid_dev->rx_packet_buffer,
294 GetEPRxAddr(usb_hid_dev->cfg->data_rx_ep),
297 if (!usb_hid_dev->rx_in_cb) {
299 SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_NAK);
305 bool need_yield =
false;
306 #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
307 (usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context,
308 &usb_hid_dev->rx_packet_buffer[1],
313 (usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context,
314 &usb_hid_dev->rx_packet_buffer[2],
315 usb_hid_dev->rx_packet_buffer[1],
320 #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
326 if (headroom >= max_payload_length) {
329 SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_VALID);
332 SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_NAK);
void(* pEpInt_IN[7])(void)
int32_t PIOS_IRQ_Enable(void)
Main PiOS header to include all the compiled in PiOS options.
void * PIOS_malloc(size_t size)
bool PIOS_USB_CheckAvailable(uintptr_t id)
int32_t PIOS_USB_HID_Init(uintptr_t *usbhid_id, const struct pios_usb_hid_cfg *cfg, uintptr_t lower_id)
static struct flyingpicmd_cfg_fa cfg
const struct pios_com_driver pios_usb_hid_com_driver
USB HID layer functions header.
USB COM HID private definitions.
int32_t PIOS_IRQ_Disable(void)
#define PIOS_USB_BOARD_HID_DATA_LENGTH
#define PIOS_Assert(test)
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)