mirror of
https://github.com/whowechina/diva_pico.git
synced 2026-10-06 21:58:02 +03:00
Arcade light support
This commit is contained in:
Binary file not shown.
@@ -5,7 +5,7 @@ function(make_firmware board board_def)
|
||||
pico_sdk_init()
|
||||
add_executable(${board}
|
||||
main.c slider.c rgb.c button.c save.c config.c commands.c
|
||||
cli.c mpr121.c hebtn.c usb_descriptors.c)
|
||||
cli.c mpr121.c hebtn.c lzfx.c usb_descriptors.c)
|
||||
target_compile_definitions(${board} PUBLIC ${board_def})
|
||||
pico_enable_stdio_usb(${board} 1)
|
||||
pico_enable_stdio_uart(${board} 0)
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Lzfx decompressor
|
||||
* WHowe <github.com/whowechina>
|
||||
* This is actually taken from CrazyRedMachine's repo
|
||||
* <https://github.com/CrazyRedMachine/RedBoard/blob/main/io_dll/src/utils/hid_impl.c>
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "lzfx.h"
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef const u8 *LZSTATE[LZFX_HSIZE];
|
||||
|
||||
|
||||
/* Guess len. No parameters may be NULL; this is not checked. */
|
||||
static int lzfx_getsize(const void *ibuf, unsigned int ilen, unsigned int *olen)
|
||||
{
|
||||
|
||||
u8 const *ip = (const u8 *)ibuf;
|
||||
u8 const *const in_end = ip + ilen;
|
||||
int tot_len = 0;
|
||||
|
||||
while (ip < in_end)
|
||||
{
|
||||
|
||||
unsigned int ctrl = *ip++;
|
||||
|
||||
if (ctrl < (1 << 5))
|
||||
{
|
||||
|
||||
ctrl++;
|
||||
|
||||
if (ip + ctrl > in_end)
|
||||
return LZFX_ECORRUPT;
|
||||
|
||||
tot_len += ctrl;
|
||||
ip += ctrl;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
unsigned int len = (ctrl >> 5);
|
||||
|
||||
if (len == 7)
|
||||
{ /* i.e. format #2 */
|
||||
len += *ip++;
|
||||
}
|
||||
|
||||
len += 2; /* len is now #octets */
|
||||
|
||||
if (ip >= in_end)
|
||||
return LZFX_ECORRUPT;
|
||||
|
||||
ip++; /* skip the ref byte */
|
||||
|
||||
tot_len += len;
|
||||
}
|
||||
}
|
||||
|
||||
*olen = tot_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decompressor */
|
||||
int lzfx_decompress(const void *ibuf, unsigned int ilen,
|
||||
void *obuf, unsigned int *olen)
|
||||
{
|
||||
|
||||
u8 const *ip = (const u8 *)ibuf;
|
||||
u8 const *const in_end = ip + ilen;
|
||||
u8 *op = (u8 *)obuf;
|
||||
u8 const *const out_end = (olen == NULL ? NULL : op + *olen);
|
||||
|
||||
unsigned int remain_len = 0;
|
||||
int rc;
|
||||
|
||||
if (olen == NULL)
|
||||
return LZFX_EARGS;
|
||||
if (ibuf == NULL)
|
||||
{
|
||||
if (ilen != 0)
|
||||
return LZFX_EARGS;
|
||||
*olen = 0;
|
||||
return 0;
|
||||
}
|
||||
if (obuf == NULL)
|
||||
{
|
||||
if (olen != 0)
|
||||
return LZFX_EARGS;
|
||||
return lzfx_getsize(ibuf, ilen, olen);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
unsigned int ctrl = *ip++;
|
||||
|
||||
/* Format 000LLLLL: a literal byte string follows, of length L+1 */
|
||||
if (ctrl < (1 << 5))
|
||||
{
|
||||
|
||||
ctrl++;
|
||||
|
||||
if (fx_expect_false(op + ctrl > out_end))
|
||||
{
|
||||
--ip; /* Rewind to control byte */
|
||||
goto guess;
|
||||
}
|
||||
if (fx_expect_false(ip + ctrl > in_end))
|
||||
return LZFX_ECORRUPT;
|
||||
|
||||
do
|
||||
*op++ = *ip++;
|
||||
while (--ctrl);
|
||||
|
||||
/* Format #1 [LLLooooo oooooooo]: backref of length L+1+2
|
||||
^^^^^ ^^^^^^^^
|
||||
A B
|
||||
#2 [111ooooo LLLLLLLL oooooooo] backref of length L+7+2
|
||||
^^^^^ ^^^^^^^^
|
||||
A B
|
||||
In both cases the location of the backref is computed from the
|
||||
remaining part of the data as follows:
|
||||
|
||||
location = op - A*256 - B - 1
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
unsigned int len = (ctrl >> 5);
|
||||
u8 *ref = op - ((ctrl & 0x1f) << 8) - 1;
|
||||
|
||||
if (len == 7)
|
||||
len += *ip++; /* i.e. format #2 */
|
||||
|
||||
len += 2; /* len is now #octets */
|
||||
|
||||
if (fx_expect_false(op + len > out_end))
|
||||
{
|
||||
ip -= (len >= 9) ? 2 : 1; /* Rewind to control byte */
|
||||
goto guess;
|
||||
}
|
||||
if (fx_expect_false(ip >= in_end))
|
||||
return LZFX_ECORRUPT;
|
||||
|
||||
ref -= *ip++;
|
||||
|
||||
if (fx_expect_false(ref < (u8 *)obuf))
|
||||
return LZFX_ECORRUPT;
|
||||
|
||||
do
|
||||
*op++ = *ref++;
|
||||
while (--len);
|
||||
}
|
||||
|
||||
} while (ip < in_end);
|
||||
|
||||
*olen = op - (u8 *)obuf;
|
||||
|
||||
return 0;
|
||||
|
||||
guess:
|
||||
rc = lzfx_getsize(ip, ilen - (ip - (u8 *)ibuf), &remain_len);
|
||||
if (rc >= 0)
|
||||
*olen = remain_len + (op - (u8 *)obuf);
|
||||
return rc;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Lzfx decompressor
|
||||
* WHowe <github.com/whowechina>
|
||||
* This is actually taken from CrazyRedMachine's repo
|
||||
* <https://github.com/CrazyRedMachine/RedBoard/blob/main/io_dll/src/utils/hid_impl.c>
|
||||
*/
|
||||
|
||||
#define LZFX_ESIZE -1 /* Output buffer too small */
|
||||
#define LZFX_ECORRUPT -2 /* Invalid data for decompression */
|
||||
#define LZFX_EARGS -3 /* Arguments invalid (NULL) */
|
||||
#define LZFX_HLOG 16
|
||||
#define LZFX_HSIZE (1 << (LZFX_HLOG))
|
||||
|
||||
#define fx_expect_false(expr) (expr)
|
||||
#define fx_expect_true(expr) (expr)
|
||||
|
||||
int lzfx_decompress(const void* ibuf, unsigned int ilen,
|
||||
void* obuf, unsigned int *olen);
|
||||
+41
-18
@@ -33,6 +33,7 @@
|
||||
#include "rgb.h"
|
||||
#include "button.h"
|
||||
#include "hebtn.h"
|
||||
#include "lzfx.h"
|
||||
|
||||
struct __attribute__((packed)) {
|
||||
uint16_t buttons; // 16 buttons; see JoystickButtons_t for bit mapping
|
||||
@@ -101,12 +102,8 @@ static void gen_joy_report()
|
||||
|
||||
}
|
||||
|
||||
static uint64_t last_hid_time = 0;
|
||||
static bool motor_running = false;
|
||||
|
||||
static void run_lights()
|
||||
{
|
||||
uint64_t now = time_us_64();
|
||||
uint32_t button_colors[] = {
|
||||
rgb32(0, 0xff, 0, false),
|
||||
rgb32(0xe0, 0x10, 0xe0, false),
|
||||
@@ -119,19 +116,27 @@ static void run_lights()
|
||||
for (int i = 0; i < 5; i++) {
|
||||
bool pressed = buttons & (1 << i);
|
||||
uint32_t color = pressed ? button_colors[i] : 0x505050;
|
||||
if (motor_running && (now / 50000 % 2 == 0)) {
|
||||
color = 0;
|
||||
}
|
||||
rgb_button_color(i, color);
|
||||
}
|
||||
|
||||
uint64_t now = time_us_64();
|
||||
|
||||
static int rainbow_level = 0;
|
||||
|
||||
int zone_num = slider_zone_num();
|
||||
uint32_t phase = ((now >> 10) / zone_num) & 0xff;
|
||||
if (now - last_hid_time >= 1000000) {
|
||||
for (int i = 0; i < zone_num; i++) {
|
||||
uint32_t color = rgb32_from_hsv(i * 256 / zone_num + phase, 255, 96);
|
||||
rgb_slider_color(i, slider_touched(i) ? 0xffffff: color);
|
||||
}
|
||||
uint32_t touch_bits = slider_touch_bits();
|
||||
|
||||
if ((touch_bits) && (rainbow_level > 80)) {
|
||||
rainbow_level -= (rainbow_level > 168) ? 2 : 1;
|
||||
}
|
||||
if ((!touch_bits) && (rainbow_level < 256)) {
|
||||
rainbow_level += (rainbow_level < 168) ? 2 : 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < zone_num; i++) {
|
||||
uint32_t color = rgb32_from_hsv(i * 256 / zone_num + phase, 255, rainbow_level / 2);
|
||||
rgb_slider_color(i, touch_bits & (1 << i) ? 0xffffff: color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,12 +276,30 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id,
|
||||
hid_report_type_t report_type, uint8_t const *buffer,
|
||||
uint16_t bufsize)
|
||||
{
|
||||
if (bufsize > 1) {
|
||||
motor_running = !motor_running;
|
||||
}
|
||||
|
||||
if (report_type == HID_REPORT_TYPE_OUTPUT) {
|
||||
last_hid_time = time_us_64();
|
||||
return;
|
||||
}
|
||||
static uint8_t obuf[48];
|
||||
memcpy(obuf, buffer, bufsize);
|
||||
if (report_id == REPORT_ID_LED_SLIDER_1) {
|
||||
rgb_set_hid_slider(0, 16, obuf);
|
||||
} else if (report_id == REPORT_ID_LED_SLIDER_2) {
|
||||
rgb_set_hid_slider(16, 16, obuf);
|
||||
} else if (report_id == REPORT_ID_LED_BUTTON) {
|
||||
rgb_set_hid_button(obuf);
|
||||
}
|
||||
} else if (report_type == HID_REPORT_TYPE_FEATURE) {
|
||||
if (report_id == REPORT_ID_LED_COMPRESSED) {
|
||||
static uint8_t fbuf[64];
|
||||
memcpy(fbuf, buffer, bufsize);
|
||||
static uint8_t decomp[100];
|
||||
unsigned int olen = sizeof(decomp);
|
||||
if (lzfx_decompress(fbuf + 1, fbuf[0], decomp, &olen) != 0) {
|
||||
return;
|
||||
}
|
||||
if (olen < 96) {
|
||||
return;
|
||||
}
|
||||
rgb_set_hid_slider(0, 32, decomp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+63
-11
@@ -20,9 +20,13 @@
|
||||
#include "board_defs.h"
|
||||
#include "config.h"
|
||||
|
||||
static uint32_t rgb_buf[37]; // 4(Main buttons) + 1(Start button) + 32(Max Slider)
|
||||
#define HID_LIGHT_TIMEOUT_MS 1000
|
||||
|
||||
static int8_t button_rgb[] = RGB_BUTTON_MAP;
|
||||
static uint32_t main_buf[37]; // 4(Main buttons) + 1(Start button) + 32(Max Slider)
|
||||
static uint32_t hid_buf[37];
|
||||
static uint64_t hid_timeout = 0;
|
||||
|
||||
static int8_t button_rgb_map[] = RGB_BUTTON_MAP;
|
||||
|
||||
#define _MAP_LED(x) _MAKE_MAPPER(x)
|
||||
#define _MAKE_MAPPER(x) MAP_LED_##x
|
||||
@@ -92,20 +96,23 @@ static void drive_led()
|
||||
}
|
||||
last = now;
|
||||
|
||||
for (int i = 0; i < count_of(rgb_buf); i++) {
|
||||
pio_sm_put_blocking(pio0, 0, rgb_buf[i] << 8u);
|
||||
bool use_hid = (hid_timeout > 0) && (now < hid_timeout);
|
||||
const uint32_t *buf = use_hid ? hid_buf : main_buf;
|
||||
|
||||
for (int i = 0; i < count_of(main_buf); i++) {
|
||||
pio_sm_put_blocking(pio0, 0, buf[i] << 8u);
|
||||
}
|
||||
}
|
||||
|
||||
void rgb_set_colors(const uint32_t *colors, unsigned index, size_t num)
|
||||
{
|
||||
if (index >= count_of(rgb_buf)) {
|
||||
if (index >= count_of(main_buf)) {
|
||||
return;
|
||||
}
|
||||
if (index + num > count_of(rgb_buf)) {
|
||||
num = count_of(rgb_buf) - index;
|
||||
if (index + num > count_of(main_buf)) {
|
||||
num = count_of(main_buf) - index;
|
||||
}
|
||||
memcpy(&rgb_buf[index], colors, num * sizeof(*colors));
|
||||
memcpy(&main_buf[index], colors, num * sizeof(*colors));
|
||||
}
|
||||
|
||||
static inline uint32_t apply_level(uint32_t color, uint8_t level)
|
||||
@@ -123,8 +130,8 @@ static inline uint32_t apply_level(uint32_t color, uint8_t level)
|
||||
|
||||
void rgb_button_color(unsigned index, uint32_t color)
|
||||
{
|
||||
if (index < count_of(button_rgb)) {
|
||||
rgb_buf[button_rgb[index]] = apply_level(color, diva_cfg->light.level.button);
|
||||
if (index < count_of(button_rgb_map)) {
|
||||
main_buf[button_rgb_map[index]] = apply_level(color, diva_cfg->light.level.button);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +140,51 @@ void rgb_slider_color(unsigned index, uint32_t color)
|
||||
if (index > 32) {
|
||||
return;
|
||||
}
|
||||
rgb_buf[5 + index] = apply_level(color, diva_cfg->light.level.slider);
|
||||
main_buf[5 + index] = apply_level(color, diva_cfg->light.level.slider);
|
||||
}
|
||||
|
||||
static inline void update_hid_timeout()
|
||||
{
|
||||
hid_timeout = time_us_64() + HID_LIGHT_TIMEOUT_MS * 1000;
|
||||
}
|
||||
|
||||
static inline uint32_t led_rgb(const uint8_t *grb, int index)
|
||||
{
|
||||
const uint8_t *src = grb + index * 3;
|
||||
return rgb32(src[1], src[0], src[2], false);
|
||||
}
|
||||
|
||||
void rgb_set_hid_slider(unsigned index, unsigned num, const uint8_t *grb)
|
||||
{
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (index + i >= 32) {
|
||||
return;
|
||||
}
|
||||
uint32_t *dest = &hid_buf[5 + index + i];
|
||||
*dest = apply_level(led_rgb(grb, i), diva_cfg->light.level.slider);
|
||||
}
|
||||
|
||||
update_hid_timeout();
|
||||
}
|
||||
|
||||
void rgb_set_hid_button(const uint8_t *scale)
|
||||
{
|
||||
uint32_t button_colors[] = {
|
||||
rgb32(0, 0xff, 0, false),
|
||||
rgb32(0xe0, 0x10, 0xe0, false),
|
||||
rgb32(0, 0, 0xff, false),
|
||||
rgb32(0xff, 0, 0, false),
|
||||
};
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int button_led = button_rgb_map[i];
|
||||
uint32_t color = apply_level(button_colors[i], scale[i]);
|
||||
hid_buf[button_led] = apply_level(color, diva_cfg->light.level.button);
|
||||
}
|
||||
|
||||
hid_buf[4] = main_buf[4]; // HID doesn't have start button light
|
||||
|
||||
update_hid_timeout();
|
||||
}
|
||||
|
||||
void rgb_init()
|
||||
@@ -144,6 +195,7 @@ void rgb_init()
|
||||
ws2812_program_init(pio0, 0, pio0_offset, RGB_PIN, 800000, false);
|
||||
}
|
||||
|
||||
|
||||
void rgb_update()
|
||||
{
|
||||
drive_led();
|
||||
|
||||
@@ -22,4 +22,7 @@ void rgb_set_colors(const uint32_t *colors, unsigned index, size_t num);
|
||||
void rgb_button_color(unsigned index, uint32_t color);
|
||||
void rgb_slider_color(unsigned index, uint32_t color);
|
||||
|
||||
void rgb_set_hid_slider(unsigned index, unsigned num, const uint8_t *grb);
|
||||
void rgb_set_hid_button(const uint8_t *scale);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -102,6 +102,11 @@ bool slider_touched(unsigned zone)
|
||||
return touch_bits & (1 << zone);
|
||||
}
|
||||
|
||||
uint32_t slider_touch_bits()
|
||||
{
|
||||
return touch_bits;
|
||||
}
|
||||
|
||||
unsigned slider_count(unsigned zone)
|
||||
{
|
||||
if (zone >= zone_num) {
|
||||
|
||||
@@ -13,6 +13,8 @@ void slider_init();
|
||||
void slider_update();
|
||||
uint16_t slider_zone_num();
|
||||
bool slider_touched(unsigned zone);
|
||||
uint32_t slider_touch_bits();
|
||||
|
||||
const uint16_t *slider_raw();
|
||||
void slider_update_config();
|
||||
unsigned slider_count(unsigned zone);
|
||||
|
||||
@@ -102,9 +102,6 @@ extern "C" {
|
||||
#define CFG_TUD_MIDI 0
|
||||
#define CFG_TUD_VENDOR 0
|
||||
|
||||
// HID buffer size Should be sufficient to hold ID (if any) + Data
|
||||
#define CFG_TUD_HID_EP_BUFSIZE 64
|
||||
|
||||
#define CFG_TUD_VENDOR 0
|
||||
|
||||
// HID buffer size Should be sufficient to hold ID (if any) + Data
|
||||
|
||||
@@ -78,8 +78,13 @@ uint8_t const desc_hid_report_joy[] = {
|
||||
DIVAPICO_REPORT_DESC_JOYSTICK,
|
||||
};
|
||||
|
||||
uint8_t const desc_hid_report_nkro[] = {
|
||||
DIVAPICO_REPORT_DESC_NKRO,
|
||||
uint8_t const desc_hid_report_led[] = {
|
||||
DIVAPICO_LED_HEADER,
|
||||
DIVAPICO_REPORT_DESC_LED_SLIDER_1,
|
||||
DIVAPICO_REPORT_DESC_LED_SLIDER_2,
|
||||
DIVAPICO_REPORT_DESC_LED_BUTTON,
|
||||
DIVAPICO_REPORT_DESC_LED_COMPRESSED,
|
||||
DIVAPICO_LED_FOOTER
|
||||
};
|
||||
|
||||
// Invoked when received GET HID REPORT DESCRIPTOR
|
||||
@@ -91,7 +96,7 @@ uint8_t const* tud_hid_descriptor_report_cb(uint8_t itf)
|
||||
case 0:
|
||||
return desc_hid_report_joy;
|
||||
case 1:
|
||||
return desc_hid_report_nkro;
|
||||
return desc_hid_report_led;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@@ -100,7 +105,7 @@ uint8_t const* tud_hid_descriptor_report_cb(uint8_t itf)
|
||||
// Configuration Descriptor
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
enum { ITF_NUM_JOY, ITF_NUM_NKRO,
|
||||
enum { ITF_NUM_JOY, ITF_NUM_LED,
|
||||
ITF_NUM_CLI, ITF_NUM_CLI_DATA,
|
||||
ITF_NUM_TOTAL };
|
||||
|
||||
@@ -112,8 +117,7 @@ enum { ITF_NUM_JOY, ITF_NUM_NKRO,
|
||||
#define EPNUM_JOY_OUT 0x01
|
||||
#define EPNUM_JOY_IN 0x81
|
||||
|
||||
//#define EPNUM_LED 0x86
|
||||
#define EPNUM_KEY 0x87
|
||||
#define EPNUM_LED 0x86
|
||||
|
||||
#define EPNUM_CLI_NOTIF 0x89
|
||||
#define EPNUM_CLI_OUT 0x0a
|
||||
@@ -131,9 +135,9 @@ uint8_t const desc_configuration_joy[] = {
|
||||
sizeof(desc_hid_report_joy), EPNUM_JOY_OUT, EPNUM_JOY_IN,
|
||||
CFG_TUD_HID_EP_BUFSIZE, 1),
|
||||
|
||||
TUD_HID_DESCRIPTOR(ITF_NUM_NKRO, 5, HID_ITF_PROTOCOL_NONE,
|
||||
sizeof(desc_hid_report_nkro), EPNUM_KEY,
|
||||
CFG_TUD_HID_EP_BUFSIZE, 1),
|
||||
TUD_HID_DESCRIPTOR(ITF_NUM_LED, 5, HID_ITF_PROTOCOL_NONE,
|
||||
sizeof(desc_hid_report_led), EPNUM_LED,
|
||||
CFG_TUD_HID_EP_BUFSIZE, 4),
|
||||
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CLI, 6, EPNUM_CLI_NOTIF,
|
||||
8, EPNUM_CLI_OUT, EPNUM_CLI_IN, 64),
|
||||
@@ -157,7 +161,7 @@ const char *string_desc_arr[] = {
|
||||
"Diva Pico Controller", // 2: Product
|
||||
"123456", // 3: Serials, should use chip ID
|
||||
"Diva Pico Joystick",
|
||||
"Diva Pico NKRO",
|
||||
"Diva Pico LED",
|
||||
"Diva Pico CLI Port",
|
||||
};
|
||||
|
||||
@@ -175,25 +179,12 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
|
||||
}
|
||||
|
||||
const size_t base_num = sizeof(string_desc_arr) / sizeof(string_desc_arr[0]);
|
||||
const char *colors[] = {"Blue", "Red", "Green"};
|
||||
char str[64];
|
||||
|
||||
if (index < base_num) {
|
||||
strcpy(str, string_desc_arr[index]);
|
||||
} else if (index < base_num + 48 + 45) {
|
||||
const char *names[] = {"Key ", "Splitter "};
|
||||
int led = index - base_num;
|
||||
int id = led / 6 + 1;
|
||||
int type = led / 3 % 2;
|
||||
int brg = led % 3;
|
||||
sprintf(str, "%s%02d %s", names[type], id, colors[brg]);
|
||||
} else if (index < base_num + 48 + 45 + 18) {
|
||||
int led = index - base_num - 48 - 45;
|
||||
int id = led / 3 + 1;
|
||||
int brg = led % 3;
|
||||
sprintf(str, "Tower %02d %s", id, colors[brg]);
|
||||
} else {
|
||||
sprintf(str, "Unknown %d", index);
|
||||
sprintf(str, "B%02d", index - base_num);
|
||||
}
|
||||
|
||||
uint8_t chr_count = strlen(str);
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
enum {
|
||||
REPORT_ID_JOYSTICK = 1,
|
||||
REPORT_ID_LED_SLIDER_1 = 4,
|
||||
REPORT_ID_LED_SLIDER_2 = 5,
|
||||
REPORT_ID_LED_BUTTON = 6,
|
||||
REPORT_ID_LED_COMPRESSED = 11,
|
||||
};
|
||||
|
||||
// because they are missing from tusb_hid.h
|
||||
@@ -58,40 +62,52 @@ enum {
|
||||
HID_OUTPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
HID_COLLECTION_END
|
||||
|
||||
#define DIVAPICO_REPORT_DESC_NKRO \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_KEYBOARD), \
|
||||
#define DIVAPICO_LED_HEADER \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), HID_USAGE(0x00), \
|
||||
HID_COLLECTION(HID_COLLECTION_APPLICATION), \
|
||||
/* Modifier */ \
|
||||
HID_REPORT_SIZE(1), \
|
||||
HID_REPORT_COUNT(8), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_KEYBOARD), \
|
||||
HID_USAGE_MIN(224), \
|
||||
HID_USAGE_MAX(231), \
|
||||
HID_LOGICAL_MIN(0), \
|
||||
HID_LOGICAL_MAX(1), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
/* LED output that we don't care */ \
|
||||
HID_REPORT_COUNT(5), \
|
||||
HID_REPORT_SIZE(1), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_LED), \
|
||||
HID_USAGE_MIN(1), \
|
||||
HID_USAGE_MAX(5), \
|
||||
HID_OUTPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
HID_REPORT_COUNT(1), \
|
||||
HID_REPORT_SIZE(3), \
|
||||
HID_OUTPUT(HID_CONSTANT), \
|
||||
/* Full Keyboard Bitmap */ \
|
||||
HID_REPORT_SIZE(1), \
|
||||
HID_REPORT_COUNT(120), \
|
||||
HID_LOGICAL_MIN(0), \
|
||||
HID_LOGICAL_MAX(1), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_KEYBOARD), \
|
||||
HID_USAGE_MIN(0), \
|
||||
HID_USAGE_MAX(119), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(8), \
|
||||
HID_INPUT(HID_CONSTANT | HID_VARIABLE | HID_ABSOLUTE)
|
||||
|
||||
#define DIVAPICO_LED_FOOTER \
|
||||
HID_COLLECTION_END
|
||||
|
||||
// HID_REPORT_ID(REPORT_ID_NKRO)
|
||||
// Slider First 16 LEDs (48 rgb zones, BRG order)
|
||||
#define DIVAPICO_REPORT_DESC_LED_SLIDER_1 \
|
||||
HID_REPORT_ID(REPORT_ID_LED_SLIDER_1) \
|
||||
HID_REPORT_COUNT(48), HID_REPORT_SIZE(8), \
|
||||
HID_LOGICAL_MIN(0x00), HID_LOGICAL_MAX_N(0x00ff, 2), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_ORDINAL), \
|
||||
HID_USAGE_MIN(1), HID_USAGE_MAX(48), \
|
||||
HID_STRING_MINIMUM(8), HID_STRING_MAXIMUM(55), \
|
||||
HID_OUTPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE)
|
||||
|
||||
// Slider Remaining 16 LEDs (48 rgb zones, BRG order)
|
||||
#define DIVAPICO_REPORT_DESC_LED_SLIDER_2 \
|
||||
HID_REPORT_ID(REPORT_ID_LED_SLIDER_2) \
|
||||
HID_REPORT_COUNT(48), HID_REPORT_SIZE(8), \
|
||||
HID_LOGICAL_MIN(0x00), HID_LOGICAL_MAX_N(0x00ff, 2), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_ORDINAL), \
|
||||
HID_USAGE_MIN(49), HID_USAGE_MAX(96), \
|
||||
HID_STRING_MINIMUM(56), HID_STRING_MAXIMUM(103), /* Delta to previous */ \
|
||||
HID_OUTPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE)
|
||||
|
||||
// Button LEDs (18 rgb zones, BRG order)
|
||||
#define DIVAPICO_REPORT_DESC_LED_BUTTON \
|
||||
HID_REPORT_ID(REPORT_ID_LED_BUTTON) \
|
||||
HID_REPORT_COUNT(4), HID_REPORT_SIZE(8), \
|
||||
HID_LOGICAL_MIN(0x00), HID_LOGICAL_MAX_N(0x00ff, 2), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_ORDINAL), \
|
||||
HID_USAGE_MIN(97), HID_USAGE_MAX(100), \
|
||||
HID_STRING_MINIMUM(104), HID_STRING_MAXIMUM(107), /* Delta to previous */ \
|
||||
HID_OUTPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE)
|
||||
|
||||
// LEDs Compressed
|
||||
#define DIVAPICO_REPORT_DESC_LED_COMPRESSED \
|
||||
HID_REPORT_ID(REPORT_ID_LED_COMPRESSED) \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_ORDINAL), \
|
||||
HID_USAGE(0x00), \
|
||||
HID_LOGICAL_MIN(0x00), HID_LOGICAL_MAX_N(0x00ff, 2), \
|
||||
HID_REPORT_SIZE(8), HID_REPORT_COUNT(63), \
|
||||
HID_FEATURE(HID_DATA | HID_VARIABLE | HID_ABSOLUTE)
|
||||
|
||||
#endif /* USB_DESCRIPTORS_H_ */
|
||||
|
||||
Reference in New Issue
Block a user