Initial commit
This commit is contained in:
@@ -0,0 +1,262 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "pico/stdlib.h"
|
||||
#include "tusb.h"
|
||||
#include "hardware/adc.h"
|
||||
|
||||
#include "corsair_strafe2.h"
|
||||
#include "usb_descriptors.h"
|
||||
|
||||
static bool sending = false;
|
||||
static absolute_time_t lastTime;
|
||||
static bool backlight = false;
|
||||
|
||||
static unsigned char buf[BUF_SIZE];
|
||||
static uint8_t buf_idx=0;
|
||||
static uint8_t packets_sent=0;
|
||||
static uint8_t color_idx = 0;
|
||||
static uint8_t channel = 1;
|
||||
static uint8_t channel_packet = 0;
|
||||
static uint8_t curcolor = 0;
|
||||
|
||||
static uint8_t input;
|
||||
static uint8_t bit=0;
|
||||
static uint8_t byte=0;
|
||||
static uint8_t boot_pos=0;
|
||||
|
||||
// used to map Corsair's keycode to standard keyboard scan code
|
||||
static const int16_t nkro_key[NKRO_BUF_SIZE*8] = {
|
||||
49, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 61, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 53, 51, 28, 34, 16, 29, 31, 36, 32, 20, 26, 27, 55, 65, 12, 30, 15, 17, 18, 19, 21, 22, 23, 59, 60, 1, 108, 37, 35, 14, 33, 13, 25, 24, 62, 63, 64, 0, 3, 2, 153, 52, 152, 144, 6, 7, 109, -1, 258, 77, 78, 79, 80, 81, 82, 83, 56, 57, 58, 48, 143, 54, 145, 50, 84, 85, 86, 5, 4, 90, 88, 89, 87, 253, 135, 128, 242, -1, 243, 91, 92, 93, 94, 95, 96, 103, 104, 105, 212, 100, 101, 102, 97, 98, 99, 106, 107, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 136, 137, 255, 249, 250, 251, 226, 227, 228, 229, 230, 231, 240, 241, 147, 146, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
void get_light() {
|
||||
// get measurement from ADC and set a flag for the backlight based on
|
||||
// reading from the LDR
|
||||
if (adc_read() > 400) {
|
||||
backlight = false;
|
||||
} else {
|
||||
backlight = true;
|
||||
}
|
||||
}
|
||||
|
||||
void rgb_task(uint8_t dev_addr, uint8_t instance, uint8_t report_id) {
|
||||
// RGB color data is sent in multiple packets - determine whether we
|
||||
// are in the middle of sending color data, and if so, send the next
|
||||
// packet; otherwise begin sending the next round of color data
|
||||
// 1 second after the last packet of the last round
|
||||
if (sending) {
|
||||
if ( absolute_time_diff_us(lastTime, get_absolute_time()) > 100000) {
|
||||
// set color to different intensities of white based on whether
|
||||
// backlight is flagged as "on" or "off"
|
||||
if( backlight) {
|
||||
// turn on backlight at a bright level (#505050)
|
||||
send_color(dev_addr, instance, report_id, 0x50, 0x50, 0x50);
|
||||
} else{
|
||||
// turn on backlight at a dim level (#101010)
|
||||
send_color(dev_addr, instance, report_id, 0x10, 0x10, 0x10);
|
||||
}
|
||||
lastTime = get_absolute_time();
|
||||
}
|
||||
} else {
|
||||
if ( absolute_time_diff_us(lastTime, get_absolute_time()) > 1000000) {
|
||||
send_initial(dev_addr, instance, report_id);
|
||||
lastTime = get_absolute_time();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// send a single color packet
|
||||
void send_color(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t red, uint8_t green, uint8_t blue) {
|
||||
memset(buf, 0x00, BUF_SIZE);
|
||||
|
||||
buf_idx = 0;
|
||||
|
||||
// packets 1 and packets 2 are commands to activate software control
|
||||
// mode and initiate sending of key-by-key lighting data
|
||||
if(packets_sent==1){
|
||||
buf[0x00] = 0x07;
|
||||
buf[0x01] = 0x05;
|
||||
buf[0x02] = 0x02;
|
||||
buf[0x04] = 0x03;
|
||||
}
|
||||
if(packets_sent==2){
|
||||
buf[0x00] = 0x07;
|
||||
buf[0x01] = 0x05;
|
||||
buf[0x02] = 0x08;
|
||||
buf[0x04] = 0x01;
|
||||
}
|
||||
// send RGB data - each color channel submits all keys for the channel
|
||||
// before moving to the next channel, i.e. all R values for all keys,
|
||||
// all G values for all keys, then all B values for all keys
|
||||
if(packets_sent>2){
|
||||
if(color_idx < NUM_KEYS) {
|
||||
channel_packet++;
|
||||
buf[0x00] = 0x7F;
|
||||
buf[0x01] = channel_packet;
|
||||
if(NUM_KEYS - color_idx > 60) {
|
||||
buf[0x02] = 60;
|
||||
} else{
|
||||
buf[0x02] = NUM_KEYS-color_idx;
|
||||
}
|
||||
|
||||
// determine value to send based on which channel we are currently
|
||||
// transmitting
|
||||
if(channel == 1){
|
||||
curcolor = red;
|
||||
}
|
||||
if(channel == 2){
|
||||
curcolor = green;
|
||||
}
|
||||
if(channel == 3){
|
||||
curcolor = blue;
|
||||
}
|
||||
|
||||
buf_idx=4;
|
||||
// set all keys in this packet to the value for the R/G/B channel
|
||||
while(color_idx < NUM_KEYS && buf_idx < BUF_SIZE){
|
||||
buf[buf_idx] = curcolor;
|
||||
buf_idx++;
|
||||
color_idx++;
|
||||
}
|
||||
} else{
|
||||
// start a new packet stating we are done sending 24-bit
|
||||
// color packet for the currently selected channel and how many
|
||||
// packets were sent for that color channel
|
||||
buf[0x00] = 0x07;
|
||||
buf[0x01] = 0x28;
|
||||
buf[0x02] = channel;
|
||||
buf[0x03] = channel_packet;
|
||||
channel++;
|
||||
channel_packet=0;
|
||||
color_idx = 0;
|
||||
// final byte says whether to expect another channel (0x01) or
|
||||
// whether we have sent the final channel (0x02)
|
||||
if (channel>3) {
|
||||
buf[0x04] = 0x02;
|
||||
sending = false;
|
||||
} else {
|
||||
buf[0x04] = 0x01;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(tuh_hid_send_report(dev_addr, instance, report_id, buf, BUF_SIZE))
|
||||
{
|
||||
// packet sent sucessfully
|
||||
}
|
||||
|
||||
|
||||
packets_sent++;
|
||||
}
|
||||
|
||||
|
||||
void send_initial(uint8_t dev_addr, uint8_t instance, uint8_t report_id) {
|
||||
memset(buf, 0x00, BUF_SIZE);
|
||||
|
||||
color_idx = 0;
|
||||
|
||||
// setup and send initialization packet
|
||||
buf[0x00] = 0x07;
|
||||
buf[0x01] = 0x04;
|
||||
buf[0x02] = 0x02;
|
||||
|
||||
if (tuh_hid_send_report(dev_addr, instance, report_id, buf, BUF_SIZE))
|
||||
{
|
||||
sending = true;
|
||||
packets_sent=1;
|
||||
channel = 1;
|
||||
channel_packet = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// initiate the ADC and setup reading from ADC2
|
||||
void startADC() {
|
||||
stdio_init_all();
|
||||
adc_init();
|
||||
adc_gpio_init(28);
|
||||
adc_select_input(2);
|
||||
}
|
||||
|
||||
/*
|
||||
// take bitmap NKRO keypress data and turn it into boot protocol HID report
|
||||
void nkro2boot(uint8_t const* nkro_report, uint8_t* boot_report, uint16_t len) {
|
||||
memset(boot_report, 0x00, 8);
|
||||
(void) len;
|
||||
// copy modifiers
|
||||
boot_report[0] = nkro_report[0];
|
||||
boot_pos=2;
|
||||
|
||||
// set regular keyboard keys
|
||||
for (byte=1; byte<NKRO_BUF_SIZE; byte++) {
|
||||
input = nkro_report[byte];
|
||||
for (bit=0; bit < 8; bit++) {
|
||||
if ( (input >> bit) & 1) {
|
||||
boot_report[boot_pos] = byte*8+bit-8;
|
||||
boot_pos++;
|
||||
if(boot_pos>=8) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// take Corsair's single key up/down update message and update the
|
||||
// NKRO HID report bitmap
|
||||
uint8_t corsair2nkro(uint8_t const* corsair_report, uint8_t* nkro_report, uint16_t len) {
|
||||
memset(nkro_report, 0x00, NKRO_BUF_SIZE);
|
||||
|
||||
(void) len;
|
||||
|
||||
// search for media keys
|
||||
input = corsair_report[12];
|
||||
if( (input >> 1) & 1) {
|
||||
// mute
|
||||
nkro_report[2] = 0xE2;
|
||||
return REPORT_ID_CONSUMER_CONTROL;
|
||||
}
|
||||
if( (input >> 2) & 1) {
|
||||
// stop
|
||||
nkro_report[2] = 0xB7;
|
||||
return REPORT_ID_CONSUMER_CONTROL;
|
||||
}
|
||||
if( (input >> 3) & 1) {
|
||||
// back
|
||||
nkro_report[2] = 0xB6;
|
||||
return REPORT_ID_CONSUMER_CONTROL;
|
||||
}
|
||||
if( (input >> 4) & 1) {
|
||||
// pause/play
|
||||
nkro_report[2] = 0xCD;
|
||||
return REPORT_ID_CONSUMER_CONTROL;
|
||||
}
|
||||
if( (input >> 5) & 1) {
|
||||
// mute
|
||||
nkro_report[2] = 0xB5;
|
||||
return REPORT_ID_CONSUMER_CONTROL;
|
||||
}
|
||||
input = corsair_report[16];
|
||||
if( (input >> 2) & 1) {
|
||||
// volume up
|
||||
nkro_report[2] = 0xE9;
|
||||
return REPORT_ID_CONSUMER_CONTROL;
|
||||
}
|
||||
if( (input >> 3) & 1) {
|
||||
// volume down
|
||||
nkro_report[2] = 0xEA;
|
||||
return REPORT_ID_CONSUMER_CONTROL;
|
||||
}
|
||||
|
||||
// set regular keyboard keys
|
||||
for (byte=0; byte<NKRO_BUF_SIZE; byte++) {
|
||||
input = corsair_report[byte];
|
||||
for (bit=0; bit < 8; bit++) {
|
||||
if ( (input >> bit) & 1) {
|
||||
if (nkro_key[byte*8+bit] >= 0) {
|
||||
SET_KEYBIT(nkro_report, nkro_key[byte*8+bit]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return REPORT_ID_KEYBOARD;
|
||||
}
|
||||
Reference in New Issue
Block a user