Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
75d8f87b40
|
|||
|
9762476e4b
|
|||
|
3014bc0c3b
|
|||
|
a1cb13a2f9
|
+2
-2
@@ -1,2 +1,2 @@
|
|||||||
/build/**/*
|
/*/**/*
|
||||||
/external/**/*
|
!/html/**/*
|
||||||
|
|||||||
+5
-1
@@ -3,6 +3,9 @@ cmake_minimum_required(VERSION 3.13)
|
|||||||
set(PICO_SDK_PATH /home/kenji/programming/pico/c/pico-sdk)
|
set(PICO_SDK_PATH /home/kenji/programming/pico/c/pico-sdk)
|
||||||
set(PICO_PIO_USB_PATH /home/kenji/programming/pico/c/Pico-PIO-USB)
|
set(PICO_PIO_USB_PATH /home/kenji/programming/pico/c/Pico-PIO-USB)
|
||||||
set(TUSB_NETWORKING_PATH ${PICO_SDK_PATH}/lib/tinyusb/lib/networking)
|
set(TUSB_NETWORKING_PATH ${PICO_SDK_PATH}/lib/tinyusb/lib/networking)
|
||||||
|
if (NOT DEFINED PICO_BOARD)
|
||||||
|
set(PICO_BOARD pico)
|
||||||
|
endif()
|
||||||
include (${PICO_SDK_PATH}/external/pico_sdk_import.cmake)
|
include (${PICO_SDK_PATH}/external/pico_sdk_import.cmake)
|
||||||
project(${PROJECT} C CXX ASM)
|
project(${PROJECT} C CXX ASM)
|
||||||
|
|
||||||
@@ -67,5 +70,6 @@ target_link_libraries(${PROJECT} PRIVATE
|
|||||||
hardware_adc
|
hardware_adc
|
||||||
)
|
)
|
||||||
|
|
||||||
pico_add_extra_outputs(${PROJECT})
|
set_target_properties(${PROJECT} PROPERTIES OUTPUT_NAME "${PROJECT}-${PICO_BOARD}")
|
||||||
|
|
||||||
|
pico_add_extra_outputs(${PROJECT})
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
# HyperX Alloy Elite 2 RGB Controller
|
# HyperX Alloy Elite 2 RGB Controller
|
||||||
|
|
||||||
This project provides individual controls of the RGB LEDs of a HyperX Alloy
|
This project provides individual controls of the RGB LEDs of a HyperX Alloy
|
||||||
Elite 2 keyboard using a webpage served over a USB connection. ADC readings
|
Elite 2 keyboard using a webpage served over a USB connection from a Raspberry
|
||||||
from an attached light dependent resistor can also be used to make the
|
Pi Pico (2). ADC readings from an attached light dependent resistor can also be
|
||||||
lighting adaptive to the environment.
|
used to make the lighting adaptive to the environment.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -12,23 +12,25 @@ lighting adaptive to the environment.
|
|||||||
### Hardware
|
### Hardware
|
||||||
|
|
||||||
You will need the following hardware to make the device:
|
You will need the following hardware to make the device:
|
||||||
- Raspberry Pi Pico
|
- Raspberry Pi Pico or Raspberry Pi Pico 2
|
||||||
- USB extension cable
|
- USB extension cable
|
||||||
- light dependent resistor such as GL5528 (specific part number may vary)
|
- light dependent resistor such as GL5528 (specific part number may vary)
|
||||||
- 10k ohm resistor (resistance value may vary)
|
- 10k ohm resistor (resistance value may vary)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
You will need to cut the USB extension in half and connect the wires from the
|
You will need to cut the USB extension in half and connect the wires from the
|
||||||
female end to the Raspberry Pi Pico. The default configuration is to attach the
|
female end to the Raspberry Pi Pico (2). The default configuration is to attach
|
||||||
USB's green wire to pin 1/GP0 and USB's white wire to pin 2/GP1. You will also
|
the USB's green wire to pin 1/GP0 and USB's white wire to pin 2/GP1. You will
|
||||||
need to connect the red to 5V VBUS/VSYS (since you'll be powering from the
|
also need to connect the red to 5V VBUS/VSYS (since you'll be powering from the
|
||||||
USB host device, VBUS should be fine) and the black to any ground pin. Pin 38
|
USB host device, VBUS should be fine) and the black to any ground pin. Pin 38
|
||||||
is the closest and most convenient. While you can connect the Raspberry Pi Pico
|
is the closest and most convenient. While you can connect the Raspberry Pi Pico
|
||||||
to the host device using the micro USB port and a micro USB cable, since
|
(2) to the host device using the micro USB port and a micro USB cable, since
|
||||||
you have already sacrificed half of the USB extension cable, you might as well
|
you have already sacrificed half of the USB extension cable, you might as well
|
||||||
use the male half to create a standard USB-A connection. If you wish to do so,
|
use the male half to create a standard USB-A connection. If you wish to do so,
|
||||||
then simply connect the red and black wires of the male connector end to
|
then simply connect the red and black wires of the male connector end to
|
||||||
VBUS (5V) and GND, respectively. For the data wires, you can solder them to the
|
VBUS (5V) and GND, respectively. For the data wires, you can solder them to the
|
||||||
two test points TP2 and TP3 on the back of the Raspberry Pi Pico. The white
|
two test points TP2 and TP3 on the back of the Raspberry Pi Pico (2). The white
|
||||||
cable goes to TP2 and the green cable to TP3.
|
cable goes to TP2 and the green cable to TP3.
|
||||||
|
|
||||||

|

|
||||||
@@ -49,23 +51,23 @@ hole for the LDR to detect ambient light.
|
|||||||
|
|
||||||
## Software
|
## Software
|
||||||
|
|
||||||
Flash the elite2_rgb.uf2 file from the latest
|
Flash the elite2_rgb-pico.uf2 or elite2_rgb-pico2.uf2 file from the latest
|
||||||
[release](https://git.kkozai.com/kenji/alloy_elite2_rgb/releases) to the
|
[release](https://git.kkozai.com/kenji/alloy_elite2_rgb/releases) to the
|
||||||
Raspberry Pi Pico, and connect the keyboard to the female USB port and insert
|
Raspberry Pi Pico (2), and connect the keyboard to the female USB port and
|
||||||
the male USB connector of the device into your host device such as PC.
|
insert the male USB connector of the device into your host device such as PC.
|
||||||
|
|
||||||
To load the UI for configuring the RGB lighting, open a browser to the page at
|
To load the UI for configuring the RGB lighting, open a browser to the page at
|
||||||
http://alloyelite2.usb, or if that doesn't load, to http://192.168.226.1
|
http://alloyelite2.usb, or if that doesn't load, to http://192.168.226.1
|
||||||
(226 is E2 for "Elite 2" in hexademical). From the webpage, you can click on
|
(226 is E2 for "Elite 2" in hexadecimal). From the webpage, you can click on
|
||||||
any individual key that you want to configure and change the color using the
|
any individual key that you want to configure and change the color using the
|
||||||
color selector or by manually inputting the RGB color value into the text
|
color selector or by manually inputting the RGB color value into the text
|
||||||
boxes. To finalize setting the color for the selected key(s), click on the
|
boxes. To finalize setting the color for the selected key(s), click on the
|
||||||
"Set Color" button.
|
"Set Color" button.
|
||||||
|
|
||||||
To save the lighting configuration to the Pico 2 so that it loads the next time
|
To save the lighting configuration to the Pico (2) so that it loads the next
|
||||||
it is powered on, click on the "Save" button under the "Flash Memory" section.
|
time it is powered on, click on the "Save" button under the "Flash Memory"
|
||||||
If you make unsaved changes and want to reload the configuration from memory,
|
section. If you make unsaved changes and want to reload the configuration from
|
||||||
you can also click the "Load" button to reset to the last saved setting.
|
memory, you can also click the "Load" button to reset to the last saved setting.
|
||||||
|
|
||||||
If the checkbox next to "Adaptive" is selected when setting the color, the key's
|
If the checkbox next to "Adaptive" is selected when setting the color, the key's
|
||||||
brightness will automatically adjust with the ambient lighting, as determined by
|
brightness will automatically adjust with the ambient lighting, as determined by
|
||||||
|
|||||||
+11
-25
@@ -1,4 +1,5 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include "pico/multicore.h"
|
#include "pico/multicore.h"
|
||||||
@@ -13,7 +14,8 @@
|
|||||||
|
|
||||||
static absolute_time_t lastSend;
|
static absolute_time_t lastSend;
|
||||||
static absolute_time_t lastRead;
|
static absolute_time_t lastRead;
|
||||||
static uint16_t adc_value = 0;
|
//static uint16_t adc_value = 0;
|
||||||
|
static uint8_t adc_value = 0;
|
||||||
static bool mute = false;
|
static bool mute = false;
|
||||||
|
|
||||||
static unsigned char buf[BUF_SIZE];
|
static unsigned char buf[BUF_SIZE];
|
||||||
@@ -165,7 +167,7 @@ static struct key key_list[NUM_KEYS] =
|
|||||||
void get_light() {
|
void get_light() {
|
||||||
// get ADC reading from LDR every 500ms
|
// get ADC reading from LDR every 500ms
|
||||||
if ( absolute_time_diff_us(lastRead, get_absolute_time()) >= 500000) {
|
if ( absolute_time_diff_us(lastRead, get_absolute_time()) >= 500000) {
|
||||||
adc_value = adc_read();
|
adc_value = log2(adc_read());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,24 +178,6 @@ void rgb_task(uint8_t dev_addr) {
|
|||||||
// updated color info (packets_sent>0) and continue to send the next
|
// updated color info (packets_sent>0) and continue to send the next
|
||||||
// packet if so at a rate of one packet every 20ms
|
// packet if so at a rate of one packet every 20ms
|
||||||
// otherwise, wait 0.5s before sending the next set of color packets
|
// otherwise, wait 0.5s before sending the next set of color packets
|
||||||
|
|
||||||
/*if (packets_sent>0) {
|
|
||||||
if ( absolute_time_diff_us(lastSend, get_absolute_time()) >= 20000) {
|
|
||||||
if (backlight) {
|
|
||||||
send_color(dev_addr, 0x20, 0x20, 0x20);
|
|
||||||
// send a dim white color (#202020) for all keys
|
|
||||||
} else {
|
|
||||||
send_color(dev_addr, 0x00, 0x00, 0x00);
|
|
||||||
// turn off all lighting by sending (#000000) for all keys
|
|
||||||
}
|
|
||||||
lastSend = get_absolute_time();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ( absolute_time_diff_us(lastSend, get_absolute_time()) >= 500000) {
|
|
||||||
send_initial(dev_addr);
|
|
||||||
lastSend = get_absolute_time();
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
if ( absolute_time_diff_us(lastSend, get_absolute_time()) >= delay) {
|
if ( absolute_time_diff_us(lastSend, get_absolute_time()) >= delay) {
|
||||||
if ( packets_sent == 0) {
|
if ( packets_sent == 0) {
|
||||||
// first packet is initialization packet
|
// first packet is initialization packet
|
||||||
@@ -227,9 +211,9 @@ static void send_color(uint8_t dev_addr) {
|
|||||||
buf[buf_idx] = 0x81;
|
buf[buf_idx] = 0x81;
|
||||||
switch (key_list[key_idx].mode) {
|
switch (key_list[key_idx].mode) {
|
||||||
case RGB_MODE_ADAPTIVE: // adjust brightness based on LDR ADC reading
|
case RGB_MODE_ADAPTIVE: // adjust brightness based on LDR ADC reading
|
||||||
buf[buf_idx+1] = (ADC_MAX-adc_value)*key_list[key_idx].red/ADC_MAX;
|
buf[buf_idx+1] = (ADC_MAX_LOG2-adc_value)*key_list[key_idx].red/ADC_MAX_LOG2;
|
||||||
buf[buf_idx+2] = (ADC_MAX-adc_value)*key_list[key_idx].green/ADC_MAX;
|
buf[buf_idx+2] = (ADC_MAX_LOG2-adc_value)*key_list[key_idx].green/ADC_MAX_LOG2;
|
||||||
buf[buf_idx+3] = (ADC_MAX-adc_value)*key_list[key_idx].blue/ADC_MAX;
|
buf[buf_idx+3] = (ADC_MAX_LOG2-adc_value)*key_list[key_idx].blue/ADC_MAX_LOG2;
|
||||||
break;
|
break;
|
||||||
case RGB_MODE_MUTE:
|
case RGB_MODE_MUTE:
|
||||||
if (mute) {
|
if (mute) {
|
||||||
@@ -328,8 +312,6 @@ void parse_colors(char * data, uint16_t len) {
|
|||||||
if (token != NULL) {
|
if (token != NULL) {
|
||||||
// first string is the RGB color code
|
// first string is the RGB color code
|
||||||
uint8_t red, green, blue;
|
uint8_t red, green, blue;
|
||||||
// sscanf(token, "%2x%2x%2x", &red, &green, &blue);
|
|
||||||
// sscanf causes Pico 1 to crash
|
|
||||||
red = hexbyte(token);
|
red = hexbyte(token);
|
||||||
green = hexbyte(token+2);
|
green = hexbyte(token+2);
|
||||||
blue = hexbyte(token+4);
|
blue = hexbyte(token+4);
|
||||||
@@ -378,6 +360,7 @@ void startADC() {
|
|||||||
|
|
||||||
// forward HID report after processing
|
// forward HID report after processing
|
||||||
bool forward_report(uint8_t instance, uint8_t const* report, uint16_t len) {
|
bool forward_report(uint8_t instance, uint8_t const* report, uint16_t len) {
|
||||||
|
if (device_state == DEVICE_ACTIVE ) {
|
||||||
if (instance == 0x01 && report[0] == 0x03 && report[1] == 0xE2) {
|
if (instance == 0x01 && report[0] == 0x03 && report[1] == 0xE2) {
|
||||||
mute = !mute;
|
mute = !mute;
|
||||||
}
|
}
|
||||||
@@ -385,6 +368,9 @@ bool forward_report(uint8_t instance, uint8_t const* report, uint16_t len) {
|
|||||||
return tud_hid_n_report(instance, 0, report, len);
|
return tud_hid_n_report(instance, 0, report, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// save RGB configuration to flash
|
// save RGB configuration to flash
|
||||||
void save_rgb_config(void) {
|
void save_rgb_config(void) {
|
||||||
// set save signature and number of bytes to be written into config
|
// set save signature and number of bytes to be written into config
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#define NUM_KEYS 126
|
#define NUM_KEYS 126
|
||||||
#define BUF_SIZE 64
|
#define BUF_SIZE 64
|
||||||
#define ADC_MAX 4096
|
#define ADC_MAX 4096
|
||||||
|
#define ADC_MAX_LOG2 log2(ADC_MAX)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RGG_MODE_INVALID=0,
|
RGG_MODE_INVALID=0,
|
||||||
@@ -187,6 +188,12 @@ bool load_rgb_config(void);
|
|||||||
|
|
||||||
#define CFG_SIGNATURE 0x9e4c
|
#define CFG_SIGNATURE 0x9e4c
|
||||||
|
|
||||||
|
#if PICO_RP2040
|
||||||
#define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES - FLASH_SECTOR_SIZE)
|
#define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES - FLASH_SECTOR_SIZE)
|
||||||
|
#elif PICO_RP2350
|
||||||
|
#define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES - FLASH_BLOCK_SIZE - FLASH_SECTOR_SIZE)
|
||||||
|
#else
|
||||||
|
#error "Unsupported device. Expected RP2040 or RP2350."
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+25
-1
@@ -1034,7 +1034,31 @@ static const unsigned char data_index_html[] = {
|
|||||||
0x61, 0x6c, 0x75, 0x65, 0x29, 0x20, 0x3c, 0x20, 0x30, 0x29,
|
0x61, 0x6c, 0x75, 0x65, 0x29, 0x20, 0x3c, 0x20, 0x30, 0x29,
|
||||||
0x20, 0x7b, 0xa, 0x9, 0x9, 0x9, 0x63, 0x68, 0x61, 0x6e,
|
0x20, 0x7b, 0xa, 0x9, 0x9, 0x9, 0x63, 0x68, 0x61, 0x6e,
|
||||||
0x6e, 0x65, 0x6c, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20,
|
0x6e, 0x65, 0x6c, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20,
|
||||||
0x3d, 0x20, 0x30, 0x3b, 0xa, 0x9, 0x9, 0x7d, 0xa, 0x9,
|
0x3d, 0x20, 0x30, 0x3b, 0xa, 0x9, 0x9, 0x7d, 0x20, 0x65,
|
||||||
|
0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x20, 0x28, 0x20, 0x69,
|
||||||
|
0x73, 0x4e, 0x61, 0x4e, 0x28, 0x70, 0x61, 0x72, 0x73, 0x65,
|
||||||
|
0x49, 0x6e, 0x74, 0x28, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
|
||||||
|
0x6c, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x29, 0x20,
|
||||||
|
0x29, 0x20, 0x7b, 0xa, 0x9, 0x9, 0x9, 0x2f, 0x2f, 0x20,
|
||||||
|
0x6e, 0x6f, 0x6e, 0x2d, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69,
|
||||||
|
0x63, 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20,
|
||||||
|
0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x73,
|
||||||
|
0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x65, 0x66, 0x61,
|
||||||
|
0x75, 0x6c, 0x74, 0xa, 0x9, 0x9, 0x9, 0x63, 0x68, 0x61,
|
||||||
|
0x6e, 0x6e, 0x65, 0x6c, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||||
|
0x20, 0x3d, 0x20, 0x31, 0x32, 0x38, 0x3b, 0xa, 0x9, 0x9,
|
||||||
|
0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0xa, 0x9,
|
||||||
|
0x9, 0x9, 0x2f, 0x2f, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x20,
|
||||||
|
0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20,
|
||||||
|
0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x62,
|
||||||
|
0x6f, 0x78, 0x20, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74,
|
||||||
|
0x73, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x70, 0x61, 0x72,
|
||||||
|
0x73, 0x65, 0x72, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x6b, 0x73,
|
||||||
|
0xa, 0x9, 0x9, 0x9, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
|
||||||
|
0x6c, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20,
|
||||||
|
0x70, 0x61, 0x72, 0x73, 0x65, 0x49, 0x6e, 0x74, 0x28, 0x63,
|
||||||
|
0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x2e, 0x76, 0x61, 0x6c,
|
||||||
|
0x75, 0x65, 0x29, 0x3b, 0xa, 0x9, 0x9, 0x7d, 0xa, 0x9,
|
||||||
0x7d, 0xa, 0xa, 0x9, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65,
|
0x7d, 0xa, 0xa, 0x9, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65,
|
||||||
0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d,
|
0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d,
|
||||||
0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x72,
|
0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x72,
|
||||||
|
|||||||
+14772
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 268 KiB |
+12
-10
@@ -13,9 +13,9 @@
|
|||||||
|
|
||||||
#include "usb_device.h"
|
#include "usb_device.h"
|
||||||
|
|
||||||
char cdc_buf[64];
|
char cdc_buf[128];
|
||||||
uint16_t cdc_len;
|
uint16_t cdc_len;
|
||||||
size_t cdc_count;
|
uint32_t cdc_count;
|
||||||
device_state_t device_state;
|
device_state_t device_state;
|
||||||
|
|
||||||
static uint8_t desc_configuration[DESC_CFG_MAX];
|
static uint8_t desc_configuration[DESC_CFG_MAX];
|
||||||
@@ -75,19 +75,17 @@ void usb_device_main(void) {
|
|||||||
while (true) {
|
while (true) {
|
||||||
switch ( device_state ) {
|
switch ( device_state ) {
|
||||||
case DEVICE_ACTIVE:
|
case DEVICE_ACTIVE:
|
||||||
|
if (!tud_mounted()) {
|
||||||
|
device_state = DEVICE_INACTIVE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case DEVICE_INACTIVE:
|
case DEVICE_INACTIVE:
|
||||||
break;
|
break;
|
||||||
case DEVICE_RESTART:
|
case DEVICE_RESTART:
|
||||||
if (tud_disconnect()) {
|
if (tud_disconnect()) {
|
||||||
sleep_ms(10);
|
|
||||||
if (tud_connect()) {
|
|
||||||
if ( host_state == HOST_INACTIVE ) {
|
|
||||||
device_state = DEVICE_INACTIVE;
|
device_state = DEVICE_INACTIVE;
|
||||||
} else {
|
sleep_ms(10);
|
||||||
device_state = DEVICE_ACTIVE;
|
tud_connect();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -214,7 +212,6 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Invoked when received SET_REPORT control request or
|
// Invoked when received SET_REPORT control request or
|
||||||
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
|
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
|
||||||
void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) {
|
void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) {
|
||||||
@@ -238,6 +235,11 @@ uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_t
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invoked when device is mounted
|
||||||
|
void tud_mount_cb(void) {
|
||||||
|
device_state = DEVICE_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
// print message to CDC in raw hex
|
// print message to CDC in raw hex
|
||||||
void cdc_print_hex(uint8_t const* msg, uint16_t msg_len) {
|
void cdc_print_hex(uint8_t const* msg, uint16_t msg_len) {
|
||||||
(void) msg;
|
(void) msg;
|
||||||
|
|||||||
+2
-2
@@ -30,9 +30,9 @@ typedef enum {
|
|||||||
DEVICE_RESTART,
|
DEVICE_RESTART,
|
||||||
} device_state_t;
|
} device_state_t;
|
||||||
|
|
||||||
extern char cdc_buf[64];
|
extern char cdc_buf[128];
|
||||||
extern uint16_t cdc_len;
|
extern uint16_t cdc_len;
|
||||||
extern size_t cdc_count;
|
extern uint32_t cdc_count;
|
||||||
extern device_state_t device_state;
|
extern device_state_t device_state;
|
||||||
|
|
||||||
void usb_device_main(void);
|
void usb_device_main(void);
|
||||||
|
|||||||
+28
-4
@@ -19,6 +19,7 @@ uint8_t num_mounted=0;
|
|||||||
static absolute_time_t request_time;
|
static absolute_time_t request_time;
|
||||||
static bool enabled=false;
|
static bool enabled=false;
|
||||||
static uint8_t kb_addr=0;
|
static uint8_t kb_addr=0;
|
||||||
|
static struct hid_report last_report;
|
||||||
|
|
||||||
static void usb_host_init(void);
|
static void usb_host_init(void);
|
||||||
static void host_ready(void);
|
static void host_ready(void);
|
||||||
@@ -79,6 +80,22 @@ void usb_host_main(void) {
|
|||||||
if (enabled) {
|
if (enabled) {
|
||||||
rgb_task(kb_addr);
|
rgb_task(kb_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (last_report.len > 0 ) {
|
||||||
|
// previous report was not forwarded, resend
|
||||||
|
if ( forward_report(last_report.instance, last_report.report, last_report.len) ) {
|
||||||
|
// clear queue
|
||||||
|
last_report.len = 0;
|
||||||
|
memset(last_report.report, 0x00, REPORT_MAX_SIZE);
|
||||||
|
|
||||||
|
// continue requesting reports
|
||||||
|
if ( !tuh_hid_receive_report(last_report.dev_addr, last_report.instance) ) {
|
||||||
|
tud_cdc_write_str("Error: cannot request report\r\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tud_cdc_write_str("Error: failed resend report\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -142,14 +159,21 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons
|
|||||||
cdc_print_hex(report, len);
|
cdc_print_hex(report, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
forward_report(instance, report, len);
|
// forward report to device output
|
||||||
|
if ( !forward_report(instance, report, len) ) {
|
||||||
|
tud_cdc_write_str("Error: cannot forward report\r\n");
|
||||||
|
// queue report for resending
|
||||||
|
last_report.dev_addr = dev_addr;
|
||||||
|
last_report.instance = instance;
|
||||||
|
last_report.len = len;
|
||||||
|
memcpy(last_report.report, report, len);
|
||||||
|
} else {
|
||||||
// continue to request to receive report
|
// continue to request to receive report
|
||||||
if ( !tuh_hid_receive_report(dev_addr, instance) )
|
if ( !tuh_hid_receive_report(dev_addr, instance) ) {
|
||||||
{
|
|
||||||
tud_cdc_write_str("Error: cannot request report\r\n");
|
tud_cdc_write_str("Error: cannot request report\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// start listening on host for HID events
|
// start listening on host for HID events
|
||||||
static void host_ready(void) {
|
static void host_ready(void) {
|
||||||
|
|||||||
@@ -23,6 +23,13 @@ struct report_desc {
|
|||||||
bool listening;
|
bool listening;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct hid_report {
|
||||||
|
uint8_t dev_addr;
|
||||||
|
uint8_t instance;
|
||||||
|
uint16_t len;
|
||||||
|
uint8_t report[REPORT_MAX_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
#define REPORT_DESC_ALLOC() (struct report_desc *)malloc(sizeof(struct report_desc))
|
#define REPORT_DESC_ALLOC() (struct report_desc *)malloc(sizeof(struct report_desc))
|
||||||
|
|
||||||
extern host_state_t host_state;
|
extern host_state_t host_state;
|
||||||
|
|||||||
+4
-3
@@ -354,12 +354,14 @@ static err_t ws_read(struct altcp_pcb *pcb, struct ws_state *wss, struct pbuf *p
|
|||||||
uint8_t masked = data[1] & 0x80;
|
uint8_t masked = data[1] & 0x80;
|
||||||
uint16_t msg_len = data[1] & 0x7F;
|
uint16_t msg_len = data[1] & 0x7F;
|
||||||
uint8_t *msg;
|
uint8_t *msg;
|
||||||
|
uint8_t *mask;
|
||||||
|
|
||||||
switch (msg_len) {
|
switch (msg_len) {
|
||||||
case 126: // next two bytes are length
|
case 126: // next two bytes are length
|
||||||
memcpy(&msg_len, &data[2], 2);
|
msg_len = ( (uint16_t)data[2] << 8) | data[3];
|
||||||
if (len >= 8) {
|
if (len >= 8) {
|
||||||
msg = &data[8];
|
msg = &data[8];
|
||||||
|
mask = &data[4];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 127: // next four bytes are length
|
case 127: // next four bytes are length
|
||||||
@@ -369,6 +371,7 @@ static err_t ws_read(struct altcp_pcb *pcb, struct ws_state *wss, struct pbuf *p
|
|||||||
default:
|
default:
|
||||||
if (len >= 6) {
|
if (len >= 6) {
|
||||||
msg = &data[6];
|
msg = &data[6];
|
||||||
|
mask = &data[2];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -382,8 +385,6 @@ static err_t ws_read(struct altcp_pcb *pcb, struct ws_state *wss, struct pbuf *p
|
|||||||
if (msg && ws_receive_cb != NULL) {
|
if (msg && ws_receive_cb != NULL) {
|
||||||
// unmask the data if mask bit is received
|
// unmask the data if mask bit is received
|
||||||
if (masked) {
|
if (masked) {
|
||||||
uint8_t *mask = &data[2];
|
|
||||||
|
|
||||||
for (int i=0; i<msg_len; i++) {
|
for (int i=0; i<msg_len; i++) {
|
||||||
msg[i] ^= mask[i % 4];
|
msg[i] ^= mask[i % 4];
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
#define WS_MAX_RETRIES 10
|
#define WS_MAX_RETRIES 10
|
||||||
#define WS_POLL_INTERVAL 60 // WS_POLL_INTERVAL/2 seconds
|
#define WS_POLL_INTERVAL 60 // WS_POLL_INTERVAL/2 seconds
|
||||||
#define WS_MAX_CONN 4
|
#define WS_MAX_CONN 4
|
||||||
#define WS_BUFFER_SIZE 512
|
#define WS_BUFFER_SIZE 1024
|
||||||
|
|
||||||
#define OP_CONT 0x00
|
#define OP_CONT 0x00
|
||||||
#define OP_TEXT 0x01
|
#define OP_TEXT 0x01
|
||||||
|
|||||||
Reference in New Issue
Block a user