Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ChibiOS: Consolidate report sending code #19607

Merged
merged 2 commits into from
Jan 17, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 40 additions & 151 deletions tmk_core/protocol/chibios/usb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -859,100 +859,61 @@ uint8_t keyboard_leds(void) {
return keyboard_led_state;
}

/* prepare and start sending a report IN
* not callable from ISR or locked state */
void send_keyboard(report_keyboard_t *report) {
osalSysLock();
if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
goto unlock;
}

#ifdef NKRO_ENABLE
if (keymap_config.nkro && keyboard_protocol) { /* NKRO protocol */
/* need to wait until the previous packet has made it through */
/* can rewrite this using the synchronous API, then would wait
* until *after* the packet has been transmitted. I think
* this is more efficient */
/* busy wait, should be short and not very common */
if (usbGetTransmitStatusI(&USB_DRIVER, SHARED_IN_EPNUM)) {
/* Need to either suspend, or loop and call unlock/lock during
* every iteration - otherwise the system will remain locked,
* no interrupts served, so USB not going through as well.
* Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
osalThreadSuspendS(&(&USB_DRIVER)->epc[SHARED_IN_EPNUM]->in_state->thread);

/* after osalThreadSuspendS returns USB status might have changed */
if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
goto unlock;
}
}
usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)report, sizeof(struct nkro_report));
} else
#endif /* NKRO_ENABLE */
{ /* regular protocol */
/* need to wait until the previous packet has made it through */
/* busy wait, should be short and not very common */
if (usbGetTransmitStatusI(&USB_DRIVER, KEYBOARD_IN_EPNUM)) {
/* Need to either suspend, or loop and call unlock/lock during
* every iteration - otherwise the system will remain locked,
* no interrupts served, so USB not going through as well.
* Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
osalThreadSuspendS(&(&USB_DRIVER)->epc[KEYBOARD_IN_EPNUM]->in_state->thread);

/* after osalThreadSuspendS returns USB status might have changed */
if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
goto unlock;
}
}
uint8_t *data, size;
if (keyboard_protocol) {
data = (uint8_t *)report;
size = KEYBOARD_REPORT_SIZE;
} else { /* boot protocol */
data = &report->mods;
size = 8;
}
usbStartTransmitI(&USB_DRIVER, KEYBOARD_IN_EPNUM, data, size);
}
keyboard_report_sent = *report;

unlock:
osalSysUnlock();
}

/* ---------------------------------------------------------
* Mouse functions
* ---------------------------------------------------------
*/

#ifdef MOUSE_ENABLE
void send_mouse(report_mouse_t *report) {
void send_report(uint8_t endpoint, void *report, size_t size) {
osalSysLock();
if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
osalSysUnlock();
return;
}

if (usbGetTransmitStatusI(&USB_DRIVER, MOUSE_IN_EPNUM)) {
if (usbGetTransmitStatusI(&USB_DRIVER, endpoint)) {
/* Need to either suspend, or loop and call unlock/lock during
* every iteration - otherwise the system will remain locked,
* no interrupts served, so USB not going through as well.
* Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[MOUSE_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) {
if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[endpoint]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) {
osalSysUnlock();
return;
}
}
usbStartTransmitI(&USB_DRIVER, MOUSE_IN_EPNUM, (uint8_t *)report, sizeof(report_mouse_t));
mouse_report_sent = *report;
usbStartTransmitI(&USB_DRIVER, endpoint, report, size);
osalSysUnlock();
}

#else /* MOUSE_ENABLE */
/* prepare and start sending a report IN
* not callable from ISR or locked state */
void send_keyboard(report_keyboard_t *report) {
uint8_t ep = KEYBOARD_IN_EPNUM;
size_t size = KEYBOARD_REPORT_SIZE;

/* If we're in Boot Protocol, don't send any report ID or other funky fields */
if (!keyboard_protocol) {
send_report(ep, &report->mods, 8);
} else {
#ifdef NKRO_ENABLE
if (keymap_config.nkro) {
ep = SHARED_IN_EPNUM;
size = sizeof(struct nkro_report);
}
#endif

send_report(ep, report, size);
}

keyboard_report_sent = *report;
}

/* ---------------------------------------------------------
* Mouse functions
* ---------------------------------------------------------
*/

void send_mouse(report_mouse_t *report) {
(void)report;
#ifdef MOUSE_ENABLE
send_report(MOUSE_IN_EPNUM, report, sizeof(report_mouse_t));
mouse_report_sent = *report;
#endif
}
#endif /* MOUSE_ENABLE */

/* ---------------------------------------------------------
* Extrakey functions
Expand All @@ -961,97 +922,25 @@ void send_mouse(report_mouse_t *report) {

void send_extra(report_extra_t *report) {
#ifdef EXTRAKEY_ENABLE
osalSysLock();
if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
osalSysUnlock();
return;
}

if (usbGetTransmitStatusI(&USB_DRIVER, SHARED_IN_EPNUM)) {
/* Need to either suspend, or loop and call unlock/lock during
* every iteration - otherwise the system will remain locked,
* no interrupts served, so USB not going through as well.
* Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[SHARED_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) {
osalSysUnlock();
return;
}
}

usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)report, sizeof(report_extra_t));
osalSysUnlock();
send_report(SHARED_IN_EPNUM, report, sizeof(report_extra_t));
#endif
}

void send_programmable_button(report_programmable_button_t *report) {
#ifdef PROGRAMMABLE_BUTTON_ENABLE
osalSysLock();
if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
osalSysUnlock();
return;
}

if (usbGetTransmitStatusI(&USB_DRIVER, SHARED_IN_EPNUM)) {
/* Need to either suspend, or loop and call unlock/lock during
* every iteration - otherwise the system will remain locked,
* no interrupts served, so USB not going through as well.
* Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[SHARED_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) {
osalSysUnlock();
return;
}
}

usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)report, sizeof(report_programmable_button_t));
osalSysUnlock();
send_report(SHARED_IN_EPNUM, report, sizeof(report_programmable_button_t));
#endif
}

void send_joystick(report_joystick_t *report) {
#ifdef JOYSTICK_ENABLE
osalSysLock();
if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
osalSysUnlock();
return;
}

if (usbGetTransmitStatusI(&USB_DRIVER, JOYSTICK_IN_EPNUM)) {
/* Need to either suspend, or loop and call unlock/lock during
* every iteration - otherwise the system will remain locked,
* no interrupts served, so USB not going through as well.
* Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[JOYSTICK_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) {
osalSysUnlock();
return;
}
}

usbStartTransmitI(&USB_DRIVER, JOYSTICK_IN_EPNUM, (uint8_t *)report, sizeof(report_joystick_t));
osalSysUnlock();
send_report(JOYSTICK_IN_EPNUM, report, sizeof(report_joystick_t));
#endif
}

void send_digitizer(report_digitizer_t *report) {
#ifdef DIGITIZER_ENABLE
osalSysLock();
if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
osalSysUnlock();
return;
}

if (usbGetTransmitStatusI(&USB_DRIVER, DIGITIZER_IN_EPNUM)) {
/* Need to either suspend, or loop and call unlock/lock during
* every iteration - otherwise the system will remain locked,
* no interrupts served, so USB not going through as well.
* Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[DIGITIZER_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) {
osalSysUnlock();
return;
}
}

usbStartTransmitI(&USB_DRIVER, DIGITIZER_IN_EPNUM, (uint8_t *)report, sizeof(report_digitizer_t));
osalSysUnlock();
send_report(DIGITIZER_IN_EPNUM, report, sizeof(report_digitizer_t));
#endif
}

Expand Down