From e99ec28f5fffc41ce2662e883f7e9b56383d758b Mon Sep 17 00:00:00 2001 From: Stefan Kerkmann Date: Mon, 29 Aug 2022 19:16:49 +0200 Subject: [Core] Introduce pointing device specific debug messages (#17663) --- drivers/sensors/cirque_pinnacle.c | 8 -------- drivers/sensors/cirque_pinnacle.h | 1 + drivers/sensors/cirque_pinnacle_i2c.c | 10 ++-------- drivers/sensors/cirque_pinnacle_spi.c | 10 ++-------- drivers/sensors/pimoroni_trackball.c | 21 +++++++++------------ drivers/sensors/pmw33xx_common.c | 13 +++++-------- 6 files changed, 19 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/sensors/cirque_pinnacle.c b/drivers/sensors/cirque_pinnacle.c index 8bd4eb736e..4aed5fe67a 100644 --- a/drivers/sensors/cirque_pinnacle.c +++ b/drivers/sensors/cirque_pinnacle.c @@ -4,8 +4,6 @@ // refer to documentation: Gen2 and Gen3 (Pinnacle ASIC) at https://www.cirque.com/documentation #include "cirque_pinnacle.h" -#include "print.h" -#include "debug.h" #include "wait.h" #include "timer.h" @@ -27,12 +25,6 @@ void cirque_pinnacle_enable_feed(bool feedEnable); void RAP_ReadBytes(uint8_t address, uint8_t* data, uint8_t count); void RAP_Write(uint8_t address, uint8_t data); -#ifdef CONSOLE_ENABLE -void print_byte(uint8_t byte) { - xprintf("%c%c%c%c%c%c%c%c|", (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0')); -} -#endif - #if CIRQUE_PINNACLE_POSITION_MODE /* Logical Scaling Functions */ // Clips raw coordinates to "reachable" window of sensor diff --git a/drivers/sensors/cirque_pinnacle.h b/drivers/sensors/cirque_pinnacle.h index fa06e047f2..8717b32991 100644 --- a/drivers/sensors/cirque_pinnacle.h +++ b/drivers/sensors/cirque_pinnacle.h @@ -5,6 +5,7 @@ #include "cirque_pinnacle_regdefs.h" #include #include +#include "pointing_device_internal.h" #ifndef CIRQUE_PINNACLE_TIMEOUT # define CIRQUE_PINNACLE_TIMEOUT 20 // I2C timeout in milliseconds diff --git a/drivers/sensors/cirque_pinnacle_i2c.c b/drivers/sensors/cirque_pinnacle_i2c.c index b328dd9a7a..3c11e5f079 100644 --- a/drivers/sensors/cirque_pinnacle_i2c.c +++ b/drivers/sensors/cirque_pinnacle_i2c.c @@ -1,8 +1,6 @@ // Copyright (c) 2018 Cirque Corp. Restrictions apply. See: www.cirque.com/sw-license #include "cirque_pinnacle.h" #include "i2c_master.h" -#include "print.h" -#include "debug.h" #include "stdio.h" // Masks for Cirque Register Access Protocol (RAP) @@ -18,9 +16,7 @@ void RAP_ReadBytes(uint8_t address, uint8_t* data, uint8_t count) { if (touchpad_init) { i2c_writeReg(CIRQUE_PINNACLE_ADDR << 1, cmdByte, NULL, 0, CIRQUE_PINNACLE_TIMEOUT); if (i2c_readReg(CIRQUE_PINNACLE_ADDR << 1, cmdByte, data, count, CIRQUE_PINNACLE_TIMEOUT) != I2C_STATUS_SUCCESS) { -#ifdef CONSOLE_ENABLE - dprintf("error cirque_pinnacle i2c_readReg\n"); -#endif + pd_dprintf("error cirque_pinnacle i2c_readReg\n"); touchpad_init = false; } i2c_stop(); @@ -33,9 +29,7 @@ void RAP_Write(uint8_t address, uint8_t data) { if (touchpad_init) { if (i2c_writeReg(CIRQUE_PINNACLE_ADDR << 1, cmdByte, &data, sizeof(data), CIRQUE_PINNACLE_TIMEOUT) != I2C_STATUS_SUCCESS) { -#ifdef CONSOLE_ENABLE - dprintf("error cirque_pinnacle i2c_writeReg\n"); -#endif + pd_dprintf("error cirque_pinnacle i2c_writeReg\n"); touchpad_init = false; } i2c_stop(); diff --git a/drivers/sensors/cirque_pinnacle_spi.c b/drivers/sensors/cirque_pinnacle_spi.c index bd980fc863..5cb39aebb0 100644 --- a/drivers/sensors/cirque_pinnacle_spi.c +++ b/drivers/sensors/cirque_pinnacle_spi.c @@ -1,8 +1,6 @@ // Copyright (c) 2018 Cirque Corp. Restrictions apply. See: www.cirque.com/sw-license #include "cirque_pinnacle.h" #include "spi_master.h" -#include "print.h" -#include "debug.h" // Masks for Cirque Register Access Protocol (RAP) #define WRITE_MASK 0x80 @@ -24,9 +22,7 @@ void RAP_ReadBytes(uint8_t address, uint8_t* data, uint8_t count) { data[i] = spi_write(FILLER_BYTE); // write filler, receive data on the third filler send } } else { -#ifdef CONSOLE_ENABLE - dprintf("error cirque_pinnacle spi_start read\n"); -#endif + pd_dprintf("error cirque_pinnacle spi_start read\n"); touchpad_init = false; } spi_stop(); @@ -42,9 +38,7 @@ void RAP_Write(uint8_t address, uint8_t data) { spi_write(cmdByte); spi_write(data); } else { -#ifdef CONSOLE_ENABLE - dprintf("error cirque_pinnacle spi_start write\n"); -#endif + pd_dprintf("error cirque_pinnacle spi_start write\n"); touchpad_init = false; } spi_stop(); diff --git a/drivers/sensors/pimoroni_trackball.c b/drivers/sensors/pimoroni_trackball.c index 88a351316b..326e59744f 100644 --- a/drivers/sensors/pimoroni_trackball.c +++ b/drivers/sensors/pimoroni_trackball.c @@ -14,10 +14,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + +#include "pointing_device_internal.h" #include "pimoroni_trackball.h" #include "i2c_master.h" -#include "print.h" -#include "debug.h" #include "timer.h" // clang-format off @@ -58,20 +58,17 @@ void pimoroni_trackball_set_rgbw(uint8_t r, uint8_t g, uint8_t b, uint8_t w) { uint8_t data[4] = {r, g, b, w}; __attribute__((unused)) i2c_status_t status = i2c_writeReg(PIMORONI_TRACKBALL_ADDRESS << 1, PIMORONI_TRACKBALL_REG_LED_RED, data, sizeof(data), PIMORONI_TRACKBALL_TIMEOUT); -#ifdef CONSOLE_ENABLE - if (debug_mouse) dprintf("Trackball RGBW i2c_status_t: %d\n", status); -#endif + pd_dprintf("Trackball RGBW i2c_status_t: %d\n", status); } i2c_status_t read_pimoroni_trackball(pimoroni_data_t* data) { i2c_status_t status = i2c_readReg(PIMORONI_TRACKBALL_ADDRESS << 1, PIMORONI_TRACKBALL_REG_LEFT, (uint8_t*)data, sizeof(*data), PIMORONI_TRACKBALL_TIMEOUT); -#ifdef CONSOLE_ENABLE - if (debug_mouse) { - static uint16_t d_timer; - if (timer_elapsed(d_timer) > PIMORONI_TRACKBALL_DEBUG_INTERVAL) { - dprintf("Trackball READ i2c_status_t: %d L: %d R: %d Up: %d D: %d SW: %d\n", status, data->left, data->right, data->up, data->down, data->click); - d_timer = timer_read(); - } + +#ifdef POINTING_DEVICE_DEBUG + static uint16_t d_timer; + if (timer_elapsed(d_timer) > PIMORONI_TRACKBALL_DEBUG_INTERVAL) { + pd_dprintf("Trackball READ i2c_status_t: %d L: %d R: %d Up: %d D: %d SW: %d\n", status, data->left, data->right, data->up, data->down, data->click); + d_timer = timer_read(); } #endif diff --git a/drivers/sensors/pmw33xx_common.c b/drivers/sensors/pmw33xx_common.c index 13164cb150..4993cc2d34 100644 --- a/drivers/sensors/pmw33xx_common.c +++ b/drivers/sensors/pmw33xx_common.c @@ -7,9 +7,8 @@ // Copyright 2020 Ploopy Corporation // SPDX-License-Identifier: GPL-2.0-or-later -#include "debug.h" +#include "pointing_device_internal.h" #include "pmw33xx_common.h" -#include "print.h" #include "string.h" #include "wait.h" #include "spi_master.h" @@ -154,7 +153,7 @@ bool pmw33xx_init(uint8_t sensor) { pmw33xx_read(sensor, REG_Delta_Y_H); if (!pmw33xx_upload_firmware(sensor)) { - dprintf("PMW33XX (%d): firmware upload failed!\n", sensor); + pd_dprintf("PMW33XX (%d): firmware upload failed!\n", sensor); return false; } @@ -170,7 +169,7 @@ bool pmw33xx_init(uint8_t sensor) { pmw33xx_write(sensor, REG_Lift_Config, PMW33XX_LIFTOFF_DISTANCE); if (!pmw33xx_check_signature(sensor)) { - dprintf("PMW33XX (%d): firmware signature verification failed!\n", sensor); + pd_dprintf("PMW33XX (%d): firmware signature verification failed!\n", sensor); return false; } @@ -185,7 +184,7 @@ pmw33xx_report_t pmw33xx_read_burst(uint8_t sensor) { } if (!in_burst[sensor]) { - dprintf("PMW33XX (%d): burst\n", sensor); + pd_dprintf("PMW33XX (%d): burst\n", sensor); if (!pmw33xx_write(sensor, REG_Motion_Burst, 0x00)) { return report; } @@ -208,9 +207,7 @@ pmw33xx_report_t pmw33xx_read_burst(uint8_t sensor) { spi_stop(); - if (debug_config.mouse) { - dprintf("PMW33XX (%d): motion: 0x%x dx: %i dy: %i\n", sensor, report.motion.w, report.delta_x, report.delta_y); - } + pd_dprintf("PMW33XX (%d): motion: 0x%x dx: %i dy: %i\n", sensor, report.motion.w, report.delta_x, report.delta_y); report.delta_x *= -1; report.delta_y *= -1; -- cgit v1.2.3 From 9632360caa5e6511b0ec13cb4c55eb64408232b5 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 30 Aug 2022 03:20:04 -0500 Subject: Use a macro to compute the size of arrays at compile time (#18044) * Add ARRAY_SIZE and CEILING utility macros * Apply a coccinelle patch to use ARRAY_SIZE * fix up some straggling items * Fix 'make test:secure' * Enhance ARRAY_SIZE macro to reject acting on pointers The previous definition would not produce a diagnostic for ``` int *p; size_t num_elem = ARRAY_SIZE(p) ``` but the new one will. * explicitly get definition of ARRAY_SIZE * Convert to ARRAY_SIZE when const is involved The following spatch finds additional instances where the array is const and the division is by the size of the type, not the size of the first element: ``` @ rule5a using "empty.iso" @ type T; const T[] E; @@ - (sizeof(E)/sizeof(T)) + ARRAY_SIZE(E) @ rule6a using "empty.iso" @ type T; const T[] E; @@ - sizeof(E)/sizeof(T) + ARRAY_SIZE(E) ``` * New instances of ARRAY_SIZE added since initial spatch run * Use `ARRAY_SIZE` in docs (found by grep) * Manually use ARRAY_SIZE hs_set is expected to be the same size as uint16_t, though it's made of two 8-bit integers * Just like char, sizeof(uint8_t) is guaranteed to be 1 This is at least true on any plausible system where qmk is actually used. Per my understanding it's universally true, assuming that uint8_t exists: https://stackoverflow.com/questions/48655310/can-i-assume-that-sizeofuint8-t-1 * Run qmk-format on core C files touched in this branch Co-authored-by: Stefan Kerkmann --- drivers/haptic/solenoid.c | 5 +++-- drivers/sensors/pmw33xx_common.c | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/haptic/solenoid.c b/drivers/haptic/solenoid.c index 637a77da3d..4e43903255 100644 --- a/drivers/haptic/solenoid.c +++ b/drivers/haptic/solenoid.c @@ -20,11 +20,12 @@ #include "haptic.h" #include "gpio.h" #include "usb_device_state.h" +#include "util.h" #include uint8_t solenoid_dwell = SOLENOID_DEFAULT_DWELL; static pin_t solenoid_pads[] = SOLENOID_PINS; -#define NUMBER_OF_SOLENOIDS (sizeof(solenoid_pads) / sizeof(pin_t)) +#define NUMBER_OF_SOLENOIDS ARRAY_SIZE(solenoid_pads) bool solenoid_on[NUMBER_OF_SOLENOIDS] = {false}; bool solenoid_buzzing[NUMBER_OF_SOLENOIDS] = {false}; uint16_t solenoid_start[NUMBER_OF_SOLENOIDS] = {0}; @@ -147,7 +148,7 @@ void solenoid_check(void) { void solenoid_setup(void) { #ifdef SOLENOID_PINS_ACTIVE_STATE bool state_temp[] = SOLENOID_PINS_ACTIVE_STATE; - uint8_t bound_check = (sizeof(state_temp) / sizeof(bool)); + uint8_t bound_check = ARRAY_SIZE(state_temp); #endif for (uint8_t i = 0; i < NUMBER_OF_SOLENOIDS; i++) { diff --git a/drivers/sensors/pmw33xx_common.c b/drivers/sensors/pmw33xx_common.c index 4993cc2d34..b8d4e532ca 100644 --- a/drivers/sensors/pmw33xx_common.c +++ b/drivers/sensors/pmw33xx_common.c @@ -17,10 +17,10 @@ extern const uint8_t pmw33xx_firmware_data[PMW33XX_FIRMWARE_LENGTH] PROGMEM; extern const uint8_t pmw33xx_firmware_signature[3] PROGMEM; -static const pin_t cs_pins[] = PMW33XX_CS_PINS; -static bool in_burst[sizeof(cs_pins) / sizeof(pin_t)] = {0}; +static const pin_t cs_pins[] = PMW33XX_CS_PINS; +static bool in_burst[ARRAY_SIZE(cs_pins)] = {0}; -const size_t pmw33xx_number_of_sensors = sizeof(cs_pins) / sizeof(pin_t); +const size_t pmw33xx_number_of_sensors = ARRAY_SIZE(cs_pins); bool __attribute__((cold)) pmw33xx_upload_firmware(uint8_t sensor); bool __attribute__((cold)) pmw33xx_check_signature(uint8_t sensor); -- cgit v1.2.3 From f7d2b001bc4f79164e9ea3a4ff7faa54be0b7d82 Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 8 Sep 2022 04:59:24 +1000 Subject: Move Bluetooth-related function calls up to host/keyboard level (#18274) * Move Bluetooth-related function calls up to host/keyboard level * Remove pointless set_output() call * Move bluetooth (rn42) init to end of keyboard_init() * Enable SPI/UART for ChibiOS targets * Some more slight tweaks --- drivers/bluetooth/bluefruit_le.cpp | 8 +++----- drivers/bluetooth/bluefruit_le.h | 2 -- 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/bluefruit_le.cpp b/drivers/bluetooth/bluefruit_le.cpp index 19310767cf..50170b83fe 100644 --- a/drivers/bluetooth/bluefruit_le.cpp +++ b/drivers/bluetooth/bluefruit_le.cpp @@ -79,9 +79,7 @@ struct sdep_msg { enum queue_type { QTKeyReport, // 1-byte modifier + 6-byte key report QTConsumer, // 16-bit key code -#ifdef MOUSE_ENABLE QTMouseMove, // 4-byte mouse report -#endif }; struct queue_item { @@ -442,7 +440,7 @@ bool bluefruit_le_enable_keyboard(void) { // Disable command echo static const char kEcho[] PROGMEM = "ATE=0"; // Make the advertised name match the keyboard - static const char kGapDevName[] PROGMEM = "AT+GAPDEVNAME=" STR(PRODUCT); + static const char kGapDevName[] PROGMEM = "AT+GAPDEVNAME=" PRODUCT; // Turn on keyboard support static const char kHidEnOn[] PROGMEM = "AT+BLEHIDEN=1"; @@ -581,10 +579,12 @@ static bool process_queue_item(struct queue_item *item, uint16_t timeout) { snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->key.modifier, item->key.keys[0], item->key.keys[1], item->key.keys[2], item->key.keys[3], item->key.keys[4], item->key.keys[5]); return at_command(cmdbuf, NULL, 0, true, timeout); +#ifdef EXTRAKEY_ENABLE case QTConsumer: strcpy_P(fmtbuf, PSTR("AT+BLEHIDCONTROLKEY=0x%04x")); snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->consumer); return at_command(cmdbuf, NULL, 0, true, timeout); +#endif #ifdef MOUSE_ENABLE case QTMouseMove: @@ -658,7 +658,6 @@ void bluefruit_le_send_consumer_key(uint16_t usage) { } } -#ifdef MOUSE_ENABLE void bluefruit_le_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons) { struct queue_item item; @@ -673,7 +672,6 @@ void bluefruit_le_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, send_buf_send_one(); } } -#endif uint32_t bluefruit_le_read_battery_voltage(void) { return state.vbat; diff --git a/drivers/bluetooth/bluefruit_le.h b/drivers/bluetooth/bluefruit_le.h index de301c6167..731ba2e370 100644 --- a/drivers/bluetooth/bluefruit_le.h +++ b/drivers/bluetooth/bluefruit_le.h @@ -40,12 +40,10 @@ extern void bluefruit_le_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uin * (milliseconds) */ extern void bluefruit_le_send_consumer_key(uint16_t usage); -#ifdef MOUSE_ENABLE /* Send a mouse/wheel movement report. * The parameters are signed and indicate positive or negative direction * change. */ extern void bluefruit_le_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons); -#endif /* Compute battery voltage by reading an analog pin. * Returns the integer number of millivolts */ -- cgit v1.2.3 From f20883fef1bc9980d86682a05f763f12679b8c45 Mon Sep 17 00:00:00 2001 From: Ryan Date: Sat, 10 Sep 2022 06:36:39 +1000 Subject: RN42 driver: small cleanups (#18310) * RN42 driver: small cleanups * Include header * Fix mouse report per RN42 UG * Spacing for consistency --- drivers/bluetooth/rn42.c | 32 ++++++++++++++++++-------------- drivers/bluetooth/rn42.h | 4 +++- 2 files changed, 21 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/rn42.c b/drivers/bluetooth/rn42.c index 5d497cda20..0eb1733723 100644 --- a/drivers/bluetooth/rn42.c +++ b/drivers/bluetooth/rn42.c @@ -14,6 +14,8 @@ * along with this program. If not, see . */ +#include "rn42.h" + #include "report.h" #include "uart.h" @@ -69,33 +71,35 @@ void rn42_send_keyboard(report_keyboard_t *report) { uart_write(0xFD); uart_write(0x09); uart_write(0x01); + uart_write(report->mods); uart_write(0x00); - for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { - uart_write(report->keys[i]); - } + uart_write(report->keys[0]); + uart_write(report->keys[1]); + uart_write(report->keys[2]); + uart_write(report->keys[3]); + uart_write(report->keys[4]); + uart_write(report->keys[5]); } void rn42_send_mouse(report_mouse_t *report) { uart_write(0xFD); - uart_write(0x00); - uart_write(0x03); + uart_write(0x05); + uart_write(0x02); + uart_write(report->buttons); uart_write(report->x); uart_write(report->y); - uart_write(report->v); // should try sending the wheel v here - uart_write(report->h); // should try sending the wheel h here - uart_write(0x00); + uart_write(report->v); } -void rn42_send_consumer(uint16_t data) { - static uint16_t last_data = 0; - if (data == last_data) return; - last_data = data; - uint16_t bitmap = rn42_consumer_usage_to_bitmap(data); +void rn42_send_consumer(uint16_t usage) { + uint16_t bitmap = rn42_consumer_usage_to_bitmap(usage); + uart_write(0xFD); uart_write(0x03); uart_write(0x03); + uart_write(bitmap & 0xFF); - uart_write((bitmap >> 8) & 0xFF); + uart_write(bitmap >> 8); } diff --git a/drivers/bluetooth/rn42.h b/drivers/bluetooth/rn42.h index 4747759111..89b716bfcd 100644 --- a/drivers/bluetooth/rn42.h +++ b/drivers/bluetooth/rn42.h @@ -14,6 +14,8 @@ * along with this program. If not, see . */ +#include + #include "report.h" void rn42_init(void); @@ -22,4 +24,4 @@ void rn42_send_keyboard(report_keyboard_t *report); void rn42_send_mouse(report_mouse_t *report); -void rn42_send_consumer(uint16_t data); +void rn42_send_consumer(uint16_t usage); -- cgit v1.2.3 From 40b0b3a9830097ac6be2a2acfd2aa3cf7300fd8f Mon Sep 17 00:00:00 2001 From: Dasky <32983009+daskygit@users.noreply.github.com> Date: Thu, 15 Sep 2022 07:48:43 +0100 Subject: Fix cirque tap from secondary side (#18351) --- drivers/sensors/cirque_pinnacle_gestures.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/sensors/cirque_pinnacle_gestures.c b/drivers/sensors/cirque_pinnacle_gestures.c index a73b745e59..ae3eca71c2 100644 --- a/drivers/sensors/cirque_pinnacle_gestures.c +++ b/drivers/sensors/cirque_pinnacle_gestures.c @@ -37,14 +37,6 @@ static report_mouse_t trackpad_tap(report_mouse_t mouse_report, pinnacle_data_t if (!touchData.zValue) { if (timer_elapsed(tap.timer) < CIRQUE_PINNACLE_TAPPING_TERM && tap.timer != 0) { mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, true, POINTING_DEVICE_BUTTON1); - pointing_device_set_report(mouse_report); - pointing_device_send(); -# if TAP_CODE_DELAY > 0 - wait_ms(TAP_CODE_DELAY); -# endif - mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, false, POINTING_DEVICE_BUTTON1); - pointing_device_set_report(mouse_report); - pointing_device_send(); } } tap.timer = timer_read(); -- cgit v1.2.3 From 1849897444629403fc2e473da6d6f74f8f4f1b8c Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Mon, 19 Sep 2022 07:30:08 +1000 Subject: [QP] Add RGB565 surface. Docs clarification, cleanup, tabsification, and reordering. (#18396) --- drivers/painter/generic/qp_rgb565_surface.c | 277 ++++++++++++++++++++++++++++ drivers/painter/generic/qp_rgb565_surface.h | 42 +++++ drivers/painter/tft_panel/qp_tft_panel.c | 4 +- 3 files changed, 320 insertions(+), 3 deletions(-) create mode 100644 drivers/painter/generic/qp_rgb565_surface.c create mode 100644 drivers/painter/generic/qp_rgb565_surface.h (limited to 'drivers') diff --git a/drivers/painter/generic/qp_rgb565_surface.c b/drivers/painter/generic/qp_rgb565_surface.c new file mode 100644 index 0000000000..c4de336535 --- /dev/null +++ b/drivers/painter/generic/qp_rgb565_surface.c @@ -0,0 +1,277 @@ +// Copyright 2022 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later +#include "color.h" +#include "qp_rgb565_surface.h" +#include "qp_draw.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Common + +// Device definition +typedef struct rgb565_surface_painter_device_t { + struct painter_driver_t base; // must be first, so it can be cast to/from the painter_device_t* type + + // The target buffer + uint16_t *buffer; + + // Manually manage the viewport for streaming pixel data to the display + uint16_t viewport_l; + uint16_t viewport_t; + uint16_t viewport_r; + uint16_t viewport_b; + + // Current write location to the display when streaming pixel data + uint16_t pixdata_x; + uint16_t pixdata_y; + + // Maintain a dirty region so we can stream only what we need + bool is_dirty; + uint16_t dirty_l; + uint16_t dirty_t; + uint16_t dirty_r; + uint16_t dirty_b; + +} rgb565_surface_painter_device_t; + +// Driver storage +rgb565_surface_painter_device_t surface_drivers[RGB565_SURFACE_NUM_DEVICES] = {0}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Helpers + +static inline void increment_pixdata_location(rgb565_surface_painter_device_t *surface) { + // Increment the X-position + surface->pixdata_x++; + + // If the x-coord has gone past the right-side edge, loop it back around and increment the y-coord + if (surface->pixdata_x > surface->viewport_r) { + surface->pixdata_x = surface->viewport_l; + surface->pixdata_y++; + } + + // If the y-coord has gone past the bottom, loop it back to the top + if (surface->pixdata_y > surface->viewport_b) { + surface->pixdata_y = surface->viewport_t; + } +} + +static inline void setpixel(rgb565_surface_painter_device_t *surface, uint16_t x, uint16_t y, uint16_t rgb565) { + // Skip messing with the dirty info if the original value already matches + if (surface->buffer[y * surface->base.panel_width + x] != rgb565) { + // Maintain dirty region + if (surface->dirty_l > x) { + surface->dirty_l = x; + } + if (surface->dirty_r < x) { + surface->dirty_r = x; + } + if (surface->dirty_t > y) { + surface->dirty_t = y; + } + if (surface->dirty_b < y) { + surface->dirty_b = y; + } + + // Always dirty after a setpixel + surface->is_dirty = true; + + // Update the pixel data in the buffer + surface->buffer[y * surface->base.panel_width + x] = rgb565; + } +} + +static inline void append_pixel(rgb565_surface_painter_device_t *surface, uint16_t rgb565) { + setpixel(surface, surface->pixdata_x, surface->pixdata_y, rgb565); + increment_pixdata_location(surface); +} + +static inline void stream_pixdata(rgb565_surface_painter_device_t *surface, const uint16_t *data, uint32_t native_pixel_count) { + for (uint32_t pixel_counter = 0; pixel_counter < native_pixel_count; ++pixel_counter) { + append_pixel(surface, data[pixel_counter]); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Driver vtable + +static bool qp_rgb565_surface_init(painter_device_t device, painter_rotation_t rotation) { + struct painter_driver_t * driver = (struct painter_driver_t *)device; + rgb565_surface_painter_device_t *surface = (rgb565_surface_painter_device_t *)driver; + memset(surface->buffer, 0, driver->panel_width * driver->panel_height * driver->native_bits_per_pixel / 8); + return true; +} + +static bool qp_rgb565_surface_power(painter_device_t device, bool power_on) { + // No-op. + return true; +} + +static bool qp_rgb565_surface_clear(painter_device_t device) { + struct painter_driver_t *driver = (struct painter_driver_t *)device; + driver->driver_vtable->init(device, driver->rotation); // Re-init the surface + return true; +} + +static bool qp_rgb565_surface_flush(painter_device_t device) { + struct painter_driver_t * driver = (struct painter_driver_t *)device; + rgb565_surface_painter_device_t *surface = (rgb565_surface_painter_device_t *)driver; + surface->dirty_l = surface->dirty_t = UINT16_MAX; + surface->dirty_r = surface->dirty_b = 0; + surface->is_dirty = false; + return true; +} + +static bool qp_rgb565_surface_viewport(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom) { + struct painter_driver_t * driver = (struct painter_driver_t *)device; + rgb565_surface_painter_device_t *surface = (rgb565_surface_painter_device_t *)driver; + + // Set the viewport locations + surface->viewport_l = left; + surface->viewport_t = top; + surface->viewport_r = right; + surface->viewport_b = bottom; + + // Reset the write location to the top left + surface->pixdata_x = left; + surface->pixdata_y = top; + return true; +} + +// Stream pixel data to the current write position in GRAM +static bool qp_rgb565_surface_pixdata(painter_device_t device, const void *pixel_data, uint32_t native_pixel_count) { + struct painter_driver_t * driver = (struct painter_driver_t *)device; + rgb565_surface_painter_device_t *surface = (rgb565_surface_painter_device_t *)driver; + stream_pixdata(surface, (const uint16_t *)pixel_data, native_pixel_count); + return true; +} + +// Pixel colour conversion +static bool qp_rgb565_surface_palette_convert_rgb565_swapped(painter_device_t device, int16_t palette_size, qp_pixel_t *palette) { + for (int16_t i = 0; i < palette_size; ++i) { + RGB rgb = hsv_to_rgb_nocie((HSV){palette[i].hsv888.h, palette[i].hsv888.s, palette[i].hsv888.v}); + uint16_t rgb565 = (((uint16_t)rgb.r) >> 3) << 11 | (((uint16_t)rgb.g) >> 2) << 5 | (((uint16_t)rgb.b) >> 3); + palette[i].rgb565 = __builtin_bswap16(rgb565); + } + return true; +} + +// Append pixels to the target location, keyed by the pixel index +static bool qp_rgb565_surface_append_pixels_rgb565(painter_device_t device, uint8_t *target_buffer, qp_pixel_t *palette, uint32_t pixel_offset, uint32_t pixel_count, uint8_t *palette_indices) { + uint16_t *buf = (uint16_t *)target_buffer; + for (uint32_t i = 0; i < pixel_count; ++i) { + buf[pixel_offset + i] = palette[palette_indices[i]].rgb565; + } + return true; +} + +const struct painter_driver_vtable_t rgb565_surface_driver_vtable = { + .init = qp_rgb565_surface_init, + .power = qp_rgb565_surface_power, + .clear = qp_rgb565_surface_clear, + .flush = qp_rgb565_surface_flush, + .pixdata = qp_rgb565_surface_pixdata, + .viewport = qp_rgb565_surface_viewport, + .palette_convert = qp_rgb565_surface_palette_convert_rgb565_swapped, + .append_pixels = qp_rgb565_surface_append_pixels_rgb565, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Comms vtable + +static bool qp_rgb565_surface_comms_init(painter_device_t device) { + // No-op. + return true; +} +static bool qp_rgb565_surface_comms_start(painter_device_t device) { + // No-op. + return true; +} +static void qp_rgb565_surface_comms_stop(painter_device_t device) { + // No-op. +} +uint32_t qp_rgb565_surface_comms_send(painter_device_t device, const void *data, uint32_t byte_count) { + // No-op. + return byte_count; +} + +struct painter_comms_vtable_t rgb565_surface_driver_comms_vtable = { + // These are all effective no-op's because they're not actually needed. + .comms_init = qp_rgb565_surface_comms_init, + .comms_start = qp_rgb565_surface_comms_start, + .comms_stop = qp_rgb565_surface_comms_stop, + .comms_send = qp_rgb565_surface_comms_send}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Factory function for creating a handle to an rgb565 surface + +painter_device_t qp_rgb565_make_surface(uint16_t panel_width, uint16_t panel_height, void *buffer) { + for (uint32_t i = 0; i < RGB565_SURFACE_NUM_DEVICES; ++i) { + rgb565_surface_painter_device_t *driver = &surface_drivers[i]; + if (!driver->base.driver_vtable) { + driver->base.driver_vtable = &rgb565_surface_driver_vtable; + driver->base.comms_vtable = &rgb565_surface_driver_comms_vtable; + driver->base.native_bits_per_pixel = 16; // RGB565 + driver->base.panel_width = panel_width; + driver->base.panel_height = panel_height; + driver->base.rotation = QP_ROTATION_0; + driver->base.offset_x = 0; + driver->base.offset_y = 0; + driver->buffer = (uint16_t *)buffer; + return (painter_device_t)driver; + } + } + return NULL; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Drawing routine to copy out the dirty region and send it to another device + +bool qp_rgb565_surface_draw(painter_device_t surface, painter_device_t display, uint16_t x, uint16_t y) { + struct painter_driver_t * surface_driver = (struct painter_driver_t *)surface; + rgb565_surface_painter_device_t *surface_handle = (rgb565_surface_painter_device_t *)surface_driver; + + // If we're not dirty... we're done. + if (!surface_handle->is_dirty) { + return true; + } + + // Set the target drawing area + bool ok = qp_viewport(display, x + surface_handle->dirty_l, y + surface_handle->dirty_t, x + surface_handle->dirty_r, y + surface_handle->dirty_b); + if (!ok) { + return false; + } + + // Housekeeping of the amount of pixels to transfer + uint32_t total_pixel_count = QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE / sizeof(uint16_t); + uint32_t pixel_counter = 0; + uint16_t *target_buffer = (uint16_t *)qp_internal_global_pixdata_buffer; + + // Fill the global pixdata area so that we can start transferring to the panel + for (uint16_t y = surface_handle->dirty_t; y <= surface_handle->dirty_b; ++y) { + for (uint16_t x = surface_handle->dirty_l; x <= surface_handle->dirty_r; ++x) { + // Update the target buffer + target_buffer[pixel_counter++] = surface_handle->buffer[y * surface_handle->base.panel_width + x]; + + // If we've accumulated enough data, send it + if (pixel_counter == total_pixel_count) { + ok = qp_pixdata(display, qp_internal_global_pixdata_buffer, pixel_counter); + if (!ok) { + return false; + } + // Reset the counter + pixel_counter = 0; + } + } + } + + // If there's any leftover data, send it + if (pixel_counter > 0) { + ok = qp_pixdata(display, qp_internal_global_pixdata_buffer, pixel_counter); + if (!ok) { + return false; + } + } + + // Clear the dirty info for the surface + return qp_flush(surface); +} diff --git a/drivers/painter/generic/qp_rgb565_surface.h b/drivers/painter/generic/qp_rgb565_surface.h new file mode 100644 index 0000000000..19e919bb91 --- /dev/null +++ b/drivers/painter/generic/qp_rgb565_surface.h @@ -0,0 +1,42 @@ +// Copyright 2022 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later +#include "qp_internal.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Quantum Painter RGB565 surface configurables (add to your keyboard's config.h) + +#ifndef RGB565_SURFACE_NUM_DEVICES +/** + * @def This controls the maximum number of surface devices that Quantum Painter can use at any one time. + * Increasing this number allows for multiple framebuffers to be used. Each requires its own RAM allocation. + */ +# define RGB565_SURFACE_NUM_DEVICES 1 +#endif + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Forward declarations + +#ifdef QUANTUM_PAINTER_RGB565_SURFACE_ENABLE +/** + * Factory method for an RGB565 surface (aka framebuffer). + * + * @param panel_width[in] the width of the display panel + * @param panel_height[in] the height of the display panel + * @param buffer[in] pointer to a preallocated buffer of size `(sizeof(uint16_t) * panel_width * panel_height)` + * @return the device handle used with all drawing routines in Quantum Painter + */ +painter_device_t qp_rgb565_make_surface(uint16_t panel_width, uint16_t panel_height, void *buffer); + +/** + * Helper method to draw the dirty contents of the framebuffer to the target device. + * + * After successful completion, the dirty area is reset. + * + * @param surface[in] the surface to copy from + * @param display[in] the display to copy into + * @param x[in] the x-location of the original position of the framebuffer + * @param y[in] the y-location of the original position of the framebuffer + * @return whether the draw operation completed successfully + */ +bool qp_rgb565_surface_draw(painter_device_t surface, painter_device_t display, uint16_t x, uint16_t y); +#endif // QUANTUM_PAINTER_RGB565_SURFACE_ENABLE diff --git a/drivers/painter/tft_panel/qp_tft_panel.c b/drivers/painter/tft_panel/qp_tft_panel.c index ad83b6c792..e7c744ab34 100644 --- a/drivers/painter/tft_panel/qp_tft_panel.c +++ b/drivers/painter/tft_panel/qp_tft_panel.c @@ -7,8 +7,6 @@ #include "qp_draw.h" #include "qp_tft_panel.h" -#define BYTE_SWAP(x) (((((uint16_t)(x)) >> 8) & 0x00FF) | ((((uint16_t)(x)) << 8) & 0xFF00)) - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Quantum Painter API implementations @@ -94,7 +92,7 @@ bool qp_tft_panel_palette_convert_rgb565_swapped(painter_device_t device, int16_ for (int16_t i = 0; i < palette_size; ++i) { RGB rgb = hsv_to_rgb_nocie((HSV){palette[i].hsv888.h, palette[i].hsv888.s, palette[i].hsv888.v}); uint16_t rgb565 = (((uint16_t)rgb.r) >> 3) << 11 | (((uint16_t)rgb.g) >> 2) << 5 | (((uint16_t)rgb.b) >> 3); - palette[i].rgb565 = BYTE_SWAP(rgb565); + palette[i].rgb565 = __builtin_bswap16(rgb565); } return true; } -- cgit v1.2.3 From 36c410592dbd35da33ccc5fd6d2a5cbf4b25a708 Mon Sep 17 00:00:00 2001 From: Ryan Date: Fri, 23 Sep 2022 22:46:23 +1000 Subject: Change `DRIVER_LED_COUNT` to `{LED,RGB}_MATRIX_LED_COUNT` (#18399) --- drivers/led/aw20216.c | 2 +- drivers/led/aw20216.h | 2 +- drivers/led/ckled2001-simple.c | 4 ++-- drivers/led/ckled2001-simple.h | 2 +- drivers/led/ckled2001.c | 4 ++-- drivers/led/ckled2001.h | 2 +- drivers/led/issi/is31fl3731-simple.c | 4 ++-- drivers/led/issi/is31fl3731-simple.h | 2 +- drivers/led/issi/is31fl3731.c | 4 ++-- drivers/led/issi/is31fl3731.h | 2 +- drivers/led/issi/is31fl3733-simple.c | 4 ++-- drivers/led/issi/is31fl3733-simple.h | 2 +- drivers/led/issi/is31fl3733.c | 4 ++-- drivers/led/issi/is31fl3733.h | 2 +- drivers/led/issi/is31fl3736.c | 4 ++-- drivers/led/issi/is31fl3736.h | 6 +++--- drivers/led/issi/is31fl3737.c | 4 ++-- drivers/led/issi/is31fl3737.h | 2 +- drivers/led/issi/is31fl3741.c | 4 ++-- drivers/led/issi/is31fl3741.h | 2 +- drivers/led/issi/is31flcommon.c | 15 +++++++++------ drivers/led/issi/is31flcommon.h | 6 ++++-- 22 files changed, 44 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/led/aw20216.c b/drivers/led/aw20216.c index 55083936ef..cbb0b60774 100644 --- a/drivers/led/aw20216.c +++ b/drivers/led/aw20216.c @@ -133,7 +133,7 @@ void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { } void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { + for (uint8_t i = 0; i < RGB_MATRIX_LED_COUNT; i++) { AW20216_set_color(i, red, green, blue); } } diff --git a/drivers/led/aw20216.h b/drivers/led/aw20216.h index 0a17050fed..c6e71b4b4e 100644 --- a/drivers/led/aw20216.h +++ b/drivers/led/aw20216.h @@ -28,7 +28,7 @@ typedef struct aw_led { uint8_t b; } aw_led; -extern const aw_led PROGMEM g_aw_leds[DRIVER_LED_TOTAL]; +extern const aw_led PROGMEM g_aw_leds[RGB_MATRIX_LED_COUNT]; void AW20216_init(pin_t cs_pin, pin_t en_pin); void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); diff --git a/drivers/led/ckled2001-simple.c b/drivers/led/ckled2001-simple.c index da4bf20b99..6c4ffd398e 100644 --- a/drivers/led/ckled2001-simple.c +++ b/drivers/led/ckled2001-simple.c @@ -148,7 +148,7 @@ void CKLED2001_init(uint8_t addr) { void CKLED2001_set_value(int index, uint8_t value) { ckled2001_led led; - if (index >= 0 && index < DRIVER_LED_TOTAL) { + if (index >= 0 && index < LED_MATRIX_LED_COUNT) { memcpy_P(&led, (&g_ckled2001_leds[index]), sizeof(led)); g_pwm_buffer[led.driver][led.v] = value; @@ -157,7 +157,7 @@ void CKLED2001_set_value(int index, uint8_t value) { } void CKLED2001_set_value_all(uint8_t value) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + for (int i = 0; i < LED_MATRIX_LED_COUNT; i++) { CKLED2001_set_value(i, value); } } diff --git a/drivers/led/ckled2001-simple.h b/drivers/led/ckled2001-simple.h index 731da2e1cd..a56cad3461 100644 --- a/drivers/led/ckled2001-simple.h +++ b/drivers/led/ckled2001-simple.h @@ -25,7 +25,7 @@ typedef struct ckled2001_led { uint8_t v; } __attribute__((packed)) ckled2001_led; -extern const ckled2001_led PROGMEM g_ckled2001_leds[DRIVER_LED_TOTAL]; +extern const ckled2001_led PROGMEM g_ckled2001_leds[LED_MATRIX_LED_COUNT]; void CKLED2001_init(uint8_t addr); bool CKLED2001_write_register(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/drivers/led/ckled2001.c b/drivers/led/ckled2001.c index b7e7db06cc..1651628175 100644 --- a/drivers/led/ckled2001.c +++ b/drivers/led/ckled2001.c @@ -148,7 +148,7 @@ void CKLED2001_init(uint8_t addr) { void CKLED2001_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { ckled2001_led led; - if (index >= 0 && index < DRIVER_LED_TOTAL) { + if (index >= 0 && index < RGB_MATRIX_LED_COUNT) { memcpy_P(&led, (&g_ckled2001_leds[index]), sizeof(led)); g_pwm_buffer[led.driver][led.r] = red; @@ -159,7 +159,7 @@ void CKLED2001_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { } void CKLED2001_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + for (int i = 0; i < RGB_MATRIX_LED_COUNT; i++) { CKLED2001_set_color(i, red, green, blue); } } diff --git a/drivers/led/ckled2001.h b/drivers/led/ckled2001.h index 7d5ad34f95..aa70a0623f 100644 --- a/drivers/led/ckled2001.h +++ b/drivers/led/ckled2001.h @@ -27,7 +27,7 @@ typedef struct ckled2001_led { uint8_t b; } __attribute__((packed)) ckled2001_led; -extern const ckled2001_led PROGMEM g_ckled2001_leds[DRIVER_LED_TOTAL]; +extern const ckled2001_led PROGMEM g_ckled2001_leds[RGB_MATRIX_LED_COUNT]; void CKLED2001_init(uint8_t addr); bool CKLED2001_write_register(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/drivers/led/issi/is31fl3731-simple.c b/drivers/led/issi/is31fl3731-simple.c index 3abe9ea337..84060f9426 100644 --- a/drivers/led/issi/is31fl3731-simple.c +++ b/drivers/led/issi/is31fl3731-simple.c @@ -194,7 +194,7 @@ void IS31FL3731_init(uint8_t addr) { void IS31FL3731_set_value(int index, uint8_t value) { is31_led led; - if (index >= 0 && index < DRIVER_LED_TOTAL) { + if (index >= 0 && index < LED_MATRIX_LED_COUNT) { memcpy_P(&led, (&g_is31_leds[index]), sizeof(led)); // Subtract 0x24 to get the second index of g_pwm_buffer @@ -204,7 +204,7 @@ void IS31FL3731_set_value(int index, uint8_t value) { } void IS31FL3731_set_value_all(uint8_t value) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + for (int i = 0; i < LED_MATRIX_LED_COUNT; i++) { IS31FL3731_set_value(i, value); } } diff --git a/drivers/led/issi/is31fl3731-simple.h b/drivers/led/issi/is31fl3731-simple.h index ded94b0470..1ddadd5209 100644 --- a/drivers/led/issi/is31fl3731-simple.h +++ b/drivers/led/issi/is31fl3731-simple.h @@ -27,7 +27,7 @@ typedef struct is31_led { uint8_t v; } __attribute__((packed)) is31_led; -extern const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL]; +extern const is31_led PROGMEM g_is31_leds[LED_MATRIX_LED_COUNT]; void IS31FL3731_init(uint8_t addr); void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/drivers/led/issi/is31fl3731.c b/drivers/led/issi/is31fl3731.c index 9c6c29f081..fed5354145 100644 --- a/drivers/led/issi/is31fl3731.c +++ b/drivers/led/issi/is31fl3731.c @@ -182,7 +182,7 @@ void IS31FL3731_init(uint8_t addr) { void IS31FL3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { is31_led led; - if (index >= 0 && index < DRIVER_LED_TOTAL) { + if (index >= 0 && index < RGB_MATRIX_LED_COUNT) { memcpy_P(&led, (&g_is31_leds[index]), sizeof(led)); // Subtract 0x24 to get the second index of g_pwm_buffer @@ -194,7 +194,7 @@ void IS31FL3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { } void IS31FL3731_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + for (int i = 0; i < RGB_MATRIX_LED_COUNT; i++) { IS31FL3731_set_color(i, red, green, blue); } } diff --git a/drivers/led/issi/is31fl3731.h b/drivers/led/issi/is31fl3731.h index 6647119eba..6791289c9e 100644 --- a/drivers/led/issi/is31fl3731.h +++ b/drivers/led/issi/is31fl3731.h @@ -28,7 +28,7 @@ typedef struct is31_led { uint8_t b; } __attribute__((packed)) is31_led; -extern const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL]; +extern const is31_led PROGMEM g_is31_leds[RGB_MATRIX_LED_COUNT]; void IS31FL3731_init(uint8_t addr); void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/drivers/led/issi/is31fl3733-simple.c b/drivers/led/issi/is31fl3733-simple.c index 2f41a7b1a9..1e0994d780 100644 --- a/drivers/led/issi/is31fl3733-simple.c +++ b/drivers/led/issi/is31fl3733-simple.c @@ -195,7 +195,7 @@ void IS31FL3733_init(uint8_t addr, uint8_t sync) { } void IS31FL3733_set_value(int index, uint8_t value) { - if (index >= 0 && index < DRIVER_LED_TOTAL) { + if (index >= 0 && index < LED_MATRIX_LED_COUNT) { is31_led led = g_is31_leds[index]; g_pwm_buffer[led.driver][led.v] = value; @@ -204,7 +204,7 @@ void IS31FL3733_set_value(int index, uint8_t value) { } void IS31FL3733_set_value_all(uint8_t value) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + for (int i = 0; i < LED_MATRIX_LED_COUNT; i++) { IS31FL3733_set_value(i, value); } } diff --git a/drivers/led/issi/is31fl3733-simple.h b/drivers/led/issi/is31fl3733-simple.h index f5253e3101..f0ea3adca0 100644 --- a/drivers/led/issi/is31fl3733-simple.h +++ b/drivers/led/issi/is31fl3733-simple.h @@ -29,7 +29,7 @@ typedef struct is31_led { uint8_t v; } __attribute__((packed)) is31_led; -extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL]; +extern const is31_led __flash g_is31_leds[LED_MATRIX_LED_COUNT]; void IS31FL3733_init(uint8_t addr, uint8_t sync); bool IS31FL3733_write_register(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/drivers/led/issi/is31fl3733.c b/drivers/led/issi/is31fl3733.c index add998f256..379eaa0ae3 100644 --- a/drivers/led/issi/is31fl3733.c +++ b/drivers/led/issi/is31fl3733.c @@ -186,7 +186,7 @@ void IS31FL3733_init(uint8_t addr, uint8_t sync) { void IS31FL3733_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { is31_led led; - if (index >= 0 && index < DRIVER_LED_TOTAL) { + if (index >= 0 && index < RGB_MATRIX_LED_COUNT) { memcpy_P(&led, (&g_is31_leds[index]), sizeof(led)); g_pwm_buffer[led.driver][led.r] = red; @@ -197,7 +197,7 @@ void IS31FL3733_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { } void IS31FL3733_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + for (int i = 0; i < RGB_MATRIX_LED_COUNT; i++) { IS31FL3733_set_color(i, red, green, blue); } } diff --git a/drivers/led/issi/is31fl3733.h b/drivers/led/issi/is31fl3733.h index 7653dd17c0..29441846ac 100644 --- a/drivers/led/issi/is31fl3733.h +++ b/drivers/led/issi/is31fl3733.h @@ -30,7 +30,7 @@ typedef struct is31_led { uint8_t b; } __attribute__((packed)) is31_led; -extern const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL]; +extern const is31_led PROGMEM g_is31_leds[RGB_MATRIX_LED_COUNT]; void IS31FL3733_init(uint8_t addr, uint8_t sync); bool IS31FL3733_write_register(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/drivers/led/issi/is31fl3736.c b/drivers/led/issi/is31fl3736.c index e9943614d2..82e7ee3d18 100644 --- a/drivers/led/issi/is31fl3736.c +++ b/drivers/led/issi/is31fl3736.c @@ -168,7 +168,7 @@ void IS31FL3736_init(uint8_t addr) { void IS31FL3736_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { is31_led led; - if (index >= 0 && index < DRIVER_LED_TOTAL) { + if (index >= 0 && index < RGB_MATRIX_LED_COUNT) { memcpy_P(&led, (&g_is31_leds[index]), sizeof(led)); g_pwm_buffer[led.driver][led.r] = red; @@ -179,7 +179,7 @@ void IS31FL3736_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { } void IS31FL3736_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + for (int i = 0; i < RGB_MATRIX_LED_COUNT; i++) { IS31FL3736_set_color(i, red, green, blue); } } diff --git a/drivers/led/issi/is31fl3736.h b/drivers/led/issi/is31fl3736.h index f126034615..ccb19afbcc 100644 --- a/drivers/led/issi/is31fl3736.h +++ b/drivers/led/issi/is31fl3736.h @@ -28,8 +28,8 @@ # define DRIVER_COUNT 2 #endif -#ifndef DRIVER_LED_TOTAL -# define DRIVER_LED_TOTAL 96 +#ifndef RGB_MATRIX_LED_COUNT +# define RGB_MATRIX_LED_COUNT 96 #endif typedef struct is31_led { @@ -39,7 +39,7 @@ typedef struct is31_led { uint8_t b; } __attribute__((packed)) is31_led; -extern const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL]; +extern const is31_led PROGMEM g_is31_leds[RGB_MATRIX_LED_COUNT]; void IS31FL3736_init(uint8_t addr); void IS31FL3736_write_register(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/drivers/led/issi/is31fl3737.c b/drivers/led/issi/is31fl3737.c index 932530ac0a..45a20018c5 100644 --- a/drivers/led/issi/is31fl3737.c +++ b/drivers/led/issi/is31fl3737.c @@ -175,7 +175,7 @@ void IS31FL3737_init(uint8_t addr) { void IS31FL3737_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { is31_led led; - if (index >= 0 && index < DRIVER_LED_TOTAL) { + if (index >= 0 && index < RGB_MATRIX_LED_COUNT) { memcpy_P(&led, (&g_is31_leds[index]), sizeof(led)); g_pwm_buffer[led.driver][led.r] = red; @@ -186,7 +186,7 @@ void IS31FL3737_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { } void IS31FL3737_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + for (int i = 0; i < RGB_MATRIX_LED_COUNT; i++) { IS31FL3737_set_color(i, red, green, blue); } } diff --git a/drivers/led/issi/is31fl3737.h b/drivers/led/issi/is31fl3737.h index ddb70a9df5..fb0c33420c 100644 --- a/drivers/led/issi/is31fl3737.h +++ b/drivers/led/issi/is31fl3737.h @@ -30,7 +30,7 @@ typedef struct is31_led { uint8_t b; } __attribute__((packed)) is31_led; -extern const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL]; +extern const is31_led PROGMEM g_is31_leds[RGB_MATRIX_LED_COUNT]; void IS31FL3737_init(uint8_t addr); void IS31FL3737_write_register(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/drivers/led/issi/is31fl3741.c b/drivers/led/issi/is31fl3741.c index ba6b6761a3..c2cdd4c46f 100644 --- a/drivers/led/issi/is31fl3741.c +++ b/drivers/led/issi/is31fl3741.c @@ -179,7 +179,7 @@ void IS31FL3741_init(uint8_t addr) { void IS31FL3741_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { is31_led led; - if (index >= 0 && index < DRIVER_LED_TOTAL) { + if (index >= 0 && index < RGB_MATRIX_LED_COUNT) { memcpy_P(&led, (&g_is31_leds[index]), sizeof(led)); g_pwm_buffer[led.driver][led.r] = red; @@ -190,7 +190,7 @@ void IS31FL3741_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { } void IS31FL3741_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + for (int i = 0; i < RGB_MATRIX_LED_COUNT; i++) { IS31FL3741_set_color(i, red, green, blue); } } diff --git a/drivers/led/issi/is31fl3741.h b/drivers/led/issi/is31fl3741.h index 3bdb23bd2d..b0089ea5ba 100644 --- a/drivers/led/issi/is31fl3741.h +++ b/drivers/led/issi/is31fl3741.h @@ -30,7 +30,7 @@ typedef struct is31_led { uint32_t b : 10; } __attribute__((packed)) is31_led; -extern const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL]; +extern const is31_led PROGMEM g_is31_leds[RGB_MATRIX_LED_COUNT]; void IS31FL3741_init(uint8_t addr); void IS31FL3741_write_register(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/drivers/led/issi/is31flcommon.c b/drivers/led/issi/is31flcommon.c index 9f4b2123ff..106890a8bf 100644 --- a/drivers/led/issi/is31flcommon.c +++ b/drivers/led/issi/is31flcommon.c @@ -135,14 +135,17 @@ void IS31FL_common_update_pwm_register(uint8_t addr, uint8_t index) { void IS31FL_set_manual_scaling_buffer(void) { for (int i = 0; i < ISSI_MANUAL_SCALING; i++) { is31_led scale = g_is31_scaling[i]; - if (scale.driver >= 0 && scale.driver < DRIVER_LED_TOTAL) { +# ifdef RGB_MATRIX_ENABLE + if (scale.driver >= 0 && scale.driver < RGB_MATRIX_LED_COUNT) { is31_led led = g_is31_leds[scale.driver]; -# ifdef RGB_MATRIX_ENABLE g_scaling_buffer[led.driver][led.r] = scale.r; g_scaling_buffer[led.driver][led.g] = scale.g; g_scaling_buffer[led.driver][led.b] = scale.b; # elif defined(LED_MATRIX_ENABLE) + if (scale.driver >= 0 && scale.driver < LED_MATRIX_LED_COUNT) { + is31_led led = g_is31_leds[scale.driver]; + g_scaling_buffer[led.driver][led.v] = scale.v; # endif g_scaling_buffer_update_required[led.driver] = true; @@ -165,7 +168,7 @@ void IS31FL_common_update_scaling_register(uint8_t addr, uint8_t index) { #ifdef RGB_MATRIX_ENABLE // Colour is set by adjusting PWM register void IS31FL_RGB_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { - if (index >= 0 && index < DRIVER_LED_TOTAL) { + if (index >= 0 && index < RGB_MATRIX_LED_COUNT) { is31_led led = g_is31_leds[index]; g_pwm_buffer[led.driver][led.r] = red; @@ -176,7 +179,7 @@ void IS31FL_RGB_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { } void IS31FL_RGB_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + for (int i = 0; i < RGB_MATRIX_LED_COUNT; i++) { IS31FL_RGB_set_color(i, red, green, blue); } } @@ -215,7 +218,7 @@ void IS31FL_simple_set_scaling_buffer(uint8_t index, bool value) { } void IS31FL_simple_set_brightness(int index, uint8_t value) { - if (index >= 0 && index < DRIVER_LED_TOTAL) { + if (index >= 0 && index < LED_MATRIX_LED_COUNT) { is31_led led = g_is31_leds[index]; g_pwm_buffer[led.driver][led.v] = value; g_pwm_buffer_update_required[led.driver] = true; @@ -223,7 +226,7 @@ void IS31FL_simple_set_brightness(int index, uint8_t value) { } void IS31FL_simple_set_brigntness_all(uint8_t value) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + for (int i = 0; i < LED_MATRIX_LED_COUNT; i++) { IS31FL_simple_set_brightness(i, value); } } diff --git a/drivers/led/issi/is31flcommon.h b/drivers/led/issi/is31flcommon.h index 77e9665e32..18432ffc31 100644 --- a/drivers/led/issi/is31flcommon.h +++ b/drivers/led/issi/is31flcommon.h @@ -43,11 +43,15 @@ typedef struct is31_led { uint8_t b; } __attribute__((packed)) is31_led; +extern const is31_led __flash g_is31_leds[RGB_MATRIX_LED_COUNT]; + #elif defined(LED_MATRIX_ENABLE) typedef struct is31_led { uint8_t driver; uint8_t v; } __attribute__((packed)) is31_led; + +extern const is31_led __flash g_is31_leds[LED_MATRIX_LED_COUNT]; #endif #ifdef ISSI_MANUAL_SCALING @@ -55,8 +59,6 @@ extern const is31_led __flash g_is31_scaling[]; void IS31FL_set_manual_scaling_buffer(void); #endif -extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL]; - void IS31FL_write_single_register(uint8_t addr, uint8_t reg, uint8_t data); bool IS31FL_write_multi_registers(uint8_t addr, uint8_t *source_buffer, uint8_t buffer_size, uint8_t transfer_size, uint8_t start_reg_addr); void IS31FL_unlock_register(uint8_t addr, uint8_t page); -- cgit v1.2.3 From f80058d96e2f1606f648166d320cda15986ced4c Mon Sep 17 00:00:00 2001 From: Ryan Date: Fri, 30 Sep 2022 03:38:09 +1000 Subject: Start Bluetooth API (#18366) --- drivers/bluetooth/bluefruit_le.cpp | 58 ++++++++++++----------------------- drivers/bluetooth/bluefruit_le.h | 12 ++++---- drivers/bluetooth/bluetooth.c | 62 ++++++++++++++++++++++++++++++++++++++ drivers/bluetooth/bluetooth.h | 52 ++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 44 deletions(-) create mode 100644 drivers/bluetooth/bluetooth.c create mode 100644 drivers/bluetooth/bluetooth.h (limited to 'drivers') diff --git a/drivers/bluetooth/bluefruit_le.cpp b/drivers/bluetooth/bluefruit_le.cpp index 50170b83fe..39c14ddd13 100644 --- a/drivers/bluetooth/bluefruit_le.cpp +++ b/drivers/bluetooth/bluefruit_le.cpp @@ -5,7 +5,7 @@ #include #include "debug.h" #include "timer.h" -#include "action_util.h" +#include "gpio.h" #include "ringbuffer.hpp" #include #include "spi_master.h" @@ -288,7 +288,7 @@ static void resp_buf_wait(const char *cmd) { } } -static bool ble_init(void) { +void bluefruit_le_init(void) { state.initialized = false; state.configured = false; state.is_connected = false; @@ -307,7 +307,6 @@ static bool ble_init(void) { wait_ms(1000); // Give it a second to initialize state.initialized = true; - return state.initialized; } static inline uint8_t min(uint8_t a, uint8_t b) { @@ -431,7 +430,7 @@ bool bluefruit_le_is_connected(void) { bool bluefruit_le_enable_keyboard(void) { char resbuf[128]; - if (!state.initialized && !ble_init()) { + if (!state.initialized) { return false; } @@ -613,41 +612,24 @@ static bool process_queue_item(struct queue_item *item, uint16_t timeout) { } } -void bluefruit_le_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nkeys) { +void bluefruit_le_send_keyboard(report_keyboard_t *report) { struct queue_item item; - bool didWait = false; item.queue_type = QTKeyReport; - item.key.modifier = hid_modifier_mask; - item.added = timer_read(); - - while (nkeys >= 0) { - item.key.keys[0] = keys[0]; - item.key.keys[1] = nkeys >= 1 ? keys[1] : 0; - item.key.keys[2] = nkeys >= 2 ? keys[2] : 0; - item.key.keys[3] = nkeys >= 3 ? keys[3] : 0; - item.key.keys[4] = nkeys >= 4 ? keys[4] : 0; - item.key.keys[5] = nkeys >= 5 ? keys[5] : 0; - - if (!send_buf.enqueue(item)) { - if (!didWait) { - dprint("wait for buf space\n"); - didWait = true; - } - send_buf_send_one(); - continue; - } - - if (nkeys <= 6) { - return; - } + item.key.modifier = report->mods; + item.key.keys[0] = report->keys[0]; + item.key.keys[1] = report->keys[1]; + item.key.keys[2] = report->keys[2]; + item.key.keys[3] = report->keys[3]; + item.key.keys[4] = report->keys[4]; + item.key.keys[5] = report->keys[5]; - nkeys -= 6; - keys += 6; + while (!send_buf.enqueue(item)) { + send_buf_send_one(); } } -void bluefruit_le_send_consumer_key(uint16_t usage) { +void bluefruit_le_send_consumer(uint16_t usage) { struct queue_item item; item.queue_type = QTConsumer; @@ -658,15 +640,15 @@ void bluefruit_le_send_consumer_key(uint16_t usage) { } } -void bluefruit_le_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons) { +void bluefruit_le_send_mouse(report_mouse_t *report) { struct queue_item item; item.queue_type = QTMouseMove; - item.mousemove.x = x; - item.mousemove.y = y; - item.mousemove.scroll = scroll; - item.mousemove.pan = pan; - item.mousemove.buttons = buttons; + item.mousemove.x = report->x; + item.mousemove.y = report->y; + item.mousemove.scroll = report->v; + item.mousemove.pan = report->h; + item.mousemove.buttons = report->buttons; while (!send_buf.enqueue(item)) { send_buf_send_one(); diff --git a/drivers/bluetooth/bluefruit_le.h b/drivers/bluetooth/bluefruit_le.h index 731ba2e370..a3de03c35c 100644 --- a/drivers/bluetooth/bluefruit_le.h +++ b/drivers/bluetooth/bluefruit_le.h @@ -7,9 +7,7 @@ #include #include -#include - -#include "config_common.h" +#include "report.h" #ifdef __cplusplus extern "C" { @@ -26,6 +24,8 @@ extern bool bluefruit_le_query_is_connected(void); * calling ble_task() periodically. */ extern bool bluefruit_le_is_connected(void); +extern void bluefruit_le_init(void); + /* Call this periodically to process BLE-originated things */ extern void bluefruit_le_task(void); @@ -34,16 +34,16 @@ extern void bluefruit_le_task(void); * this set of keys. * Also sends a key release indicator, so that the keys do not remain * held down. */ -extern void bluefruit_le_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nkeys); +extern void bluefruit_le_send_keyboard(report_keyboard_t *report); /* Send a consumer usage. * (milliseconds) */ -extern void bluefruit_le_send_consumer_key(uint16_t usage); +extern void bluefruit_le_send_consumer(uint16_t usage); /* Send a mouse/wheel movement report. * The parameters are signed and indicate positive or negative direction * change. */ -extern void bluefruit_le_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons); +extern void bluefruit_le_send_mouse(report_mouse_t *report); /* Compute battery voltage by reading an analog pin. * Returns the integer number of millivolts */ diff --git a/drivers/bluetooth/bluetooth.c b/drivers/bluetooth/bluetooth.c new file mode 100644 index 0000000000..d5382401e7 --- /dev/null +++ b/drivers/bluetooth/bluetooth.c @@ -0,0 +1,62 @@ +/* + * Copyright 2022 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "bluetooth.h" + +#if defined(BLUETOOTH_BLUEFRUIT_LE) +# include "bluefruit_le.h" +#elif defined(BLUETOOTH_RN42) +# include "rn42.h" +#endif + +void bluetooth_init(void) { +#if defined(BLUETOOTH_BLUEFRUIT_LE) + bluefruit_le_init(); +#elif defined(BLUETOOTH_RN42) + rn42_init(); +#endif +} + +void bluetooth_task(void) { +#if defined(BLUETOOTH_BLUEFRUIT_LE) + bluefruit_le_task(); +#endif +} + +void bluetooth_send_keyboard(report_keyboard_t *report) { +#if defined(BLUETOOTH_BLUEFRUIT_LE) + bluefruit_le_send_keyboard(report); +#elif defined(BLUETOOTH_RN42) + rn42_send_keyboard(report); +#endif +} + +void bluetooth_send_mouse(report_mouse_t *report) { +#if defined(BLUETOOTH_BLUEFRUIT_LE) + bluefruit_le_send_mouse(report); +#elif defined(BLUETOOTH_RN42) + rn42_send_mouse(report); +#endif +} + +void bluetooth_send_consumer(uint16_t usage) { +#if defined(BLUETOOTH_BLUEFRUIT_LE) + bluefruit_le_send_consumer(usage); +#elif defined(BLUETOOTH_RN42) + rn42_send_consumer(usage); +#endif +} diff --git a/drivers/bluetooth/bluetooth.h b/drivers/bluetooth/bluetooth.h new file mode 100644 index 0000000000..a923dfe60c --- /dev/null +++ b/drivers/bluetooth/bluetooth.h @@ -0,0 +1,52 @@ +/* + * Copyright 2022 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include "report.h" + +/** + * \brief Initialize the Bluetooth system. + */ +void bluetooth_init(void); + +/** + * \brief Perform housekeeping tasks. + */ +void bluetooth_task(void); + +/** + * \brief Send a keyboard report. + * + * \param report The keyboard report to send. + */ +void bluetooth_send_keyboard(report_keyboard_t *report); + +/** + * \brief Send a mouse report. + * + * \param report The mouse report to send. + */ +void bluetooth_send_mouse(report_mouse_t *report); + +/** + * \brief Send a consumer usage. + * + * \param usage The consumer usage to send. + */ +void bluetooth_send_consumer(uint16_t usage); -- cgit v1.2.3 From b53918fbe9122ef7995dce194951717ac65f7817 Mon Sep 17 00:00:00 2001 From: QMK Bot Date: Thu, 29 Sep 2022 10:47:17 -0700 Subject: Format code according to conventions (#18533) --- drivers/bluetooth/bluetooth.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/bluetooth.h b/drivers/bluetooth/bluetooth.h index a923dfe60c..2e4d0df538 100644 --- a/drivers/bluetooth/bluetooth.h +++ b/drivers/bluetooth/bluetooth.h @@ -32,21 +32,21 @@ void bluetooth_task(void); /** * \brief Send a keyboard report. - * + * * \param report The keyboard report to send. */ void bluetooth_send_keyboard(report_keyboard_t *report); /** * \brief Send a mouse report. - * + * * \param report The mouse report to send. */ void bluetooth_send_mouse(report_mouse_t *report); /** * \brief Sen