diff --git a/tmk_core/protocol/chibios/chibios.c b/tmk_core/protocol/chibios/chibios.c index c9a480c325..4f4ad2b655 100644 --- a/tmk_core/protocol/chibios/chibios.c +++ b/tmk_core/protocol/chibios/chibios.c @@ -74,6 +74,10 @@ void virtser_task(void); void raw_hid_task(void); #endif +#ifdef XAP_ENABLE +void xap_task(void); +#endif + #ifdef CONSOLE_ENABLE void console_task(void); #endif @@ -218,4 +222,7 @@ void protocol_post_task(void) { #ifdef RAW_ENABLE raw_hid_task(); #endif +#ifdef XAP_ENABLE + xap_task(); +#endif } diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index d9aa351ecb..a95ca79da9 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -53,6 +53,10 @@ extern keymap_config_t keymap_config; # include "joystick.h" #endif +#ifdef XAP_ENABLE +# include "xap.h" +#endif + /* --------------------------------------------------------- * Global interface variables and declarations * --------------------------------------------------------- @@ -313,6 +317,9 @@ typedef struct { #ifdef RAW_ENABLE usb_driver_config_t raw_driver; #endif +#ifdef XAP_ENABLE + usb_driver_config_t xap_driver; +#endif #ifdef MIDI_ENABLE usb_driver_config_t midi_driver; #endif @@ -346,6 +353,14 @@ static usb_driver_configs_t drivers = { .raw_driver = QMK_USB_DRIVER_CONFIG(RAW, 0, false), #endif +#ifdef XAP_ENABLE +# define XAP_IN_CAPACITY 4 +# define XAP_OUT_CAPACITY 4 +# define XAP_IN_MODE USB_EP_MODE_TYPE_INTR +# define XAP_OUT_MODE USB_EP_MODE_TYPE_INTR + .xap_driver = QMK_USB_DRIVER_CONFIG(XAP, 0, false), +#endif + #ifdef MIDI_ENABLE # define MIDI_STREAM_IN_CAPACITY 4 # define MIDI_STREAM_OUT_CAPACITY 4 @@ -1111,6 +1126,52 @@ void raw_hid_task(void) { #endif +#ifdef XAP_ENABLE +extern void xap_receive(xap_token_t token, const uint8_t *data, size_t length); + +void xap_send_base(uint8_t *data, uint8_t length) { + // TODO: implement variable size packet + if (length != XAP_EPSIZE) { + return; + } + chnWrite(&drivers.xap_driver.driver, data, length); +} + +void xap_send(xap_token_t token, uint8_t response_flags, const void *data, size_t length) { + uint8_t rdata[XAP_EPSIZE] = {0}; + *(xap_token_t *)&rdata[0] = token; + if (length > (XAP_EPSIZE - 4)) response_flags &= ~(XAP_RESPONSE_FLAG_SUCCESS); + rdata[2] = response_flags; + if (response_flags & (XAP_RESPONSE_FLAG_SUCCESS)) { + rdata[3] = (uint8_t)length; + if (data != NULL) { + memcpy(&rdata[4], data, length); + } + } + xap_send_base(rdata, sizeof(rdata)); +} + +void xap_receive_base(const void *data) { + const uint8_t *u8data = (const uint8_t *)data; + xap_token_t token = *(xap_token_t *)&u8data[0]; + uint8_t length = u8data[2]; + if (length <= (XAP_EPSIZE - 3)) { + xap_receive(token, &u8data[3], length); + } +} + +void xap_task(void) { + uint8_t buffer[XAP_EPSIZE]; + size_t size = 0; + do { + size_t size = chnReadTimeout(&drivers.xap_driver.driver, buffer, sizeof(buffer), TIME_IMMEDIATE); + if (size > 0) { + xap_receive_base(buffer); + } + } while (size > 0); +} +#endif // XAP_ENABLE + #ifdef MIDI_ENABLE void send_midi_packet(MIDI_EventPacket_t *event) {