35 #if defined(PIOS_INCLUDE_USB_HID)
44 static void PIOS_USB_HID_RegisterTxCallback(uintptr_t usbhid_id,
pios_com_callback tx_out_cb, uintptr_t context);
45 static void PIOS_USB_HID_RegisterRxCallback(uintptr_t usbhid_id,
pios_com_callback rx_in_cb, uintptr_t context);
46 static void PIOS_USB_HID_TxStart(uintptr_t usbhid_id, uint16_t tx_bytes_avail);
47 static void PIOS_USB_HID_RxStart(uintptr_t usbhid_id, uint16_t rx_bytes_avail);
51 .rx_start = PIOS_USB_HID_RxStart,
52 .bind_tx_cb = PIOS_USB_HID_RegisterTxCallback,
53 .bind_rx_cb = PIOS_USB_HID_RegisterRxCallback,
57 enum pios_usb_hid_dev_magic {
58 PIOS_USB_HID_DEV_MAGIC = 0xAA00BB00,
61 struct pios_usb_hid_dev {
62 enum pios_usb_hid_dev_magic
magic;
68 uintptr_t rx_in_context;
70 uintptr_t tx_out_context;
79 static bool PIOS_USB_HID_validate(
struct pios_usb_hid_dev * usb_hid_dev)
81 return (usb_hid_dev->magic == PIOS_USB_HID_DEV_MAGIC);
84 static struct pios_usb_hid_dev * PIOS_USB_HID_alloc(
void)
86 struct pios_usb_hid_dev * usb_hid_dev;
88 usb_hid_dev = (
struct pios_usb_hid_dev *)
PIOS_malloc(
sizeof(*usb_hid_dev));
89 if (!usb_hid_dev)
return(NULL);
91 memset(usb_hid_dev, 0,
sizeof(*usb_hid_dev));
92 usb_hid_dev->magic = PIOS_USB_HID_DEV_MAGIC;
96 static void PIOS_USB_HID_EP_IN_Callback(
void);
97 static void PIOS_USB_HID_EP_OUT_Callback(
void);
99 static uintptr_t pios_usb_hid_id;
110 struct pios_usb_hid_dev * usb_hid_dev;
112 usb_hid_dev = (
struct pios_usb_hid_dev *) PIOS_USB_HID_alloc();
113 if (!usb_hid_dev)
goto out_fail;
116 usb_hid_dev->cfg =
cfg;
117 usb_hid_dev->lower_id = lower_id;
119 pios_usb_hid_id = (uintptr_t) usb_hid_dev;
125 *usbhid_id = (uintptr_t) usb_hid_dev;
133 static void PIOS_USB_HID_SendReport(
struct pios_usb_hid_dev * usb_hid_dev)
135 uint16_t bytes_to_tx;
137 if (!usb_hid_dev->tx_out_cb) {
141 bool need_yield =
false;
142 #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
143 bytes_to_tx = (usb_hid_dev->tx_out_cb)(usb_hid_dev->tx_out_context,
144 &usb_hid_dev->tx_packet_buffer[1],
145 sizeof(usb_hid_dev->tx_packet_buffer)-1,
149 bytes_to_tx = (usb_hid_dev->tx_out_cb)(usb_hid_dev->tx_out_context,
150 &usb_hid_dev->tx_packet_buffer[2],
151 sizeof(usb_hid_dev->tx_packet_buffer)-2,
155 if (bytes_to_tx == 0) {
160 usb_hid_dev->tx_packet_buffer[0] = 1;
162 #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
163 UserToPMABufferCopy(usb_hid_dev->tx_packet_buffer,
164 GetEPTxAddr(usb_hid_dev->cfg->data_tx_ep),
167 usb_hid_dev->tx_packet_buffer[1] = bytes_to_tx;
168 UserToPMABufferCopy(usb_hid_dev->tx_packet_buffer,
169 GetEPTxAddr(usb_hid_dev->cfg->data_tx_ep),
173 SetEPTxCount(usb_hid_dev->cfg->data_tx_ep,
sizeof(usb_hid_dev->tx_packet_buffer));
174 SetEPTxValid(usb_hid_dev->cfg->data_tx_ep);
177 static void PIOS_USB_HID_RxStart(uintptr_t usbhid_id, uint16_t rx_bytes_avail) {
178 struct pios_usb_hid_dev * usb_hid_dev = (
struct pios_usb_hid_dev *)usbhid_id;
180 bool valid = PIOS_USB_HID_validate(usb_hid_dev);
188 #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
195 if ((GetEPRxStatus(usb_hid_dev->cfg->data_rx_ep) != EP_RX_VALID) &&
196 (rx_bytes_avail >= max_payload_length)) {
197 SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_VALID);
202 static void PIOS_USB_HID_TxStart(uintptr_t usbhid_id, uint16_t tx_bytes_avail)
204 struct pios_usb_hid_dev * usb_hid_dev = (
struct pios_usb_hid_dev *)usbhid_id;
206 bool valid = PIOS_USB_HID_validate(usb_hid_dev);
213 if (GetEPTxStatus(usb_hid_dev->cfg->data_tx_ep) == EP_TX_VALID) {
218 PIOS_USB_HID_SendReport(usb_hid_dev);
221 static void PIOS_USB_HID_RegisterRxCallback(uintptr_t usbhid_id,
pios_com_callback rx_in_cb, uintptr_t context)
223 struct pios_usb_hid_dev * usb_hid_dev = (
struct pios_usb_hid_dev *)usbhid_id;
225 bool valid = PIOS_USB_HID_validate(usb_hid_dev);
232 usb_hid_dev->rx_in_context = context;
233 usb_hid_dev->rx_in_cb = rx_in_cb;
236 static void PIOS_USB_HID_RegisterTxCallback(uintptr_t usbhid_id,
pios_com_callback tx_out_cb, uintptr_t context)
238 struct pios_usb_hid_dev * usb_hid_dev = (
struct pios_usb_hid_dev *)usbhid_id;
240 bool valid = PIOS_USB_HID_validate(usb_hid_dev);
247 usb_hid_dev->tx_out_context = context;
248 usb_hid_dev->tx_out_cb = tx_out_cb;
255 static void PIOS_USB_HID_EP_IN_Callback(
void)
257 struct pios_usb_hid_dev * usb_hid_dev = (
struct pios_usb_hid_dev *)pios_usb_hid_id;
259 bool valid = PIOS_USB_HID_validate(usb_hid_dev);
266 PIOS_USB_HID_SendReport(usb_hid_dev);
272 static void PIOS_USB_HID_EP_OUT_Callback(
void)
274 struct pios_usb_hid_dev * usb_hid_dev = (
struct pios_usb_hid_dev *)pios_usb_hid_id;
276 bool valid = PIOS_USB_HID_validate(usb_hid_dev);
283 DataLength = GetEPRxCount(usb_hid_dev->cfg->data_rx_ep);
284 if (DataLength >
sizeof(usb_hid_dev->rx_packet_buffer)) {
285 DataLength =
sizeof(usb_hid_dev->rx_packet_buffer);
289 PMAToUserBufferCopy((uint8_t *) usb_hid_dev->rx_packet_buffer,
290 GetEPRxAddr(usb_hid_dev->cfg->data_rx_ep),
293 if (!usb_hid_dev->rx_in_cb) {
295 SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_NAK);
301 bool need_yield =
false;
302 #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
303 (usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context,
304 &usb_hid_dev->rx_packet_buffer[1],
305 sizeof(usb_hid_dev->rx_packet_buffer)-1,
309 (usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context,
310 &usb_hid_dev->rx_packet_buffer[2],
311 usb_hid_dev->rx_packet_buffer[1],
316 #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
322 if (headroom >= max_payload_length) {
325 SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_VALID);
328 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)