Skip to content

Commit ddab0c9

Browse files
committed
Merge branch 'develop'
2 parents fa2a23d + 6117f4d commit ddab0c9

File tree

7 files changed

+351
-220
lines changed

7 files changed

+351
-220
lines changed

.gitmodules

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[submodule "hidapi"]
22
path = hidapi
3-
url = https://github.com/PastaJ36/hidapi.git
3+
url = https://github.com/libusb/hidapi.git
4+
branch = master

hidapi

src/wooting-rgb-sdk.c

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ static uint8_t rgb_buffer0[RGB_RAW_BUFFER_SIZE] = { 0 };
2424
static uint8_t rgb_buffer1[RGB_RAW_BUFFER_SIZE] = { 0 };
2525
static uint8_t rgb_buffer2[RGB_RAW_BUFFER_SIZE] = { 0 };
2626
static uint8_t rgb_buffer3[RGB_RAW_BUFFER_SIZE] = { 0 };
27+
static uint8_t rgb_buffer4[RGB_RAW_BUFFER_SIZE] = { 0 };
2728

2829
static bool rgb_buffer0_changed = false;
2930
static bool rgb_buffer1_changed = false;
3031
static bool rgb_buffer2_changed = false;
3132
static bool rgb_buffer3_changed = false;
33+
static bool rgb_buffer4_changed = false;
3234

3335
// Converts the array index to a memory location in the RGB buffers
3436
static uint8_t get_safe_led_idex(uint8_t row, uint8_t column) {
@@ -41,7 +43,8 @@ static uint8_t get_safe_led_idex(uint8_t row, uint8_t column) {
4143
{ 10, 22, 21, NOLED, NOLED, NOLED, 33, NOLED, NOLED, NOLED, 94, 58, 67, 68, 70, 79, 82, NOLED, 111, 112, NOLED }
4244
};
4345

44-
if (row < WOOTING_RGB_ROWS && column < WOOTING_RGB_COLS) {
46+
WOOTING_USB_META* meta = wooting_usb_get_meta();
47+
if (row < meta->max_rows && column < meta->max_columns) {
4548
return rgb_led_index[row][column];
4649
} else {
4750
return NOLED;
@@ -59,6 +62,7 @@ void wooting_rgb_set_disconnected_cb(void_cb cb) {
5962
bool wooting_rgb_reset() {
6063
if (wooting_usb_send_feature(WOOTING_RESET_ALL_COMMAND, 0, 0, 0, 0)) {
6164
wooting_usb_disconnect(false);
65+
return true;
6266
}
6367
else {
6468
return false;
@@ -144,6 +148,13 @@ bool wooting_rgb_array_update_keyboard() {
144148
rgb_buffer3_changed = false;
145149
}
146150

151+
if (rgb_buffer4_changed && wooting_usb_get_meta()->device_type == DEVICE_KEYBOARD) {
152+
if (!wooting_usb_send_buffer(PART4, rgb_buffer4)) {
153+
return false;
154+
}
155+
rgb_buffer4_changed = false;
156+
}
157+
147158
return true;
148159
}
149160

@@ -155,13 +166,19 @@ static bool wooting_rgb_array_change_single(uint8_t row, uint8_t column, uint8_t
155166
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
156167
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d
157168
};
169+
158170
uint8_t led_index = get_safe_led_idex(row, column);
159171
uint8_t *buffer_pointer;
160172

161-
if (led_index >= 96) {
173+
// prevent assigning led's that don't exist
174+
if (led_index > wooting_usb_get_meta()->led_index_max) {
162175
return false;
163176
}
164-
if (led_index >= 72) {
177+
if (led_index >= 96) {
178+
buffer_pointer = rgb_buffer4;
179+
rgb_buffer4_changed = true;
180+
}
181+
else if (led_index >= 72) {
165182
buffer_pointer = rgb_buffer3;
166183
rgb_buffer3_changed = true;
167184
}
@@ -189,7 +206,7 @@ static bool wooting_rgb_array_change_single(uint8_t row, uint8_t column, uint8_t
189206
rgb_buffer2[iso_enter_index + 0x10] = rgb_buffer2[buffer_index + 0x10];
190207
rgb_buffer2[iso_enter_index + 0x20] = rgb_buffer2[buffer_index + 0x20];
191208
}
192-
if (led_index == LED_LEFT_SHIFT_ANSI) {
209+
else if (led_index == LED_LEFT_SHIFT_ANSI) {
193210
uint8_t iso_shift_index = pwm_mem_map[LED_LEFT_SHIFT_ISO];
194211
rgb_buffer0[iso_shift_index] = rgb_buffer0[buffer_index];
195212
rgb_buffer0[iso_shift_index + 0x10] = rgb_buffer0[buffer_index + 0x10];
@@ -213,16 +230,18 @@ bool wooting_rgb_array_set_single(uint8_t row, uint8_t column, uint8_t red, uint
213230
}
214231

215232
bool wooting_rgb_array_set_full(const uint8_t* colors_buffer) {
216-
int baseIndex = 0;
217-
for (int row = 0; row < WOOTING_RGB_ROWS; row++) {
218-
for (int col = 0; col < WOOTING_RGB_COLS; col++) {
219-
uint8_t red = colors_buffer[baseIndex + 0];
220-
uint8_t green = colors_buffer[baseIndex + 1];
221-
uint8_t blue = colors_buffer[baseIndex + 2];
233+
const uint8_t columns = wooting_usb_get_meta()->max_columns;
234+
235+
for (uint8_t row = 0; row < WOOTING_RGB_ROWS; row++) {
236+
const uint8_t* color = colors_buffer + row * WOOTING_RGB_COLS * 3;
237+
for (uint8_t col = 0; col < columns; col++) {
238+
uint8_t red = color[0];
239+
uint8_t green = color[1];
240+
uint8_t blue = color[2];
222241

223242
wooting_rgb_array_change_single(row, col, red, green, blue);
224243

225-
baseIndex += 3;
244+
color += 3;
226245
}
227246
}
228247

@@ -233,3 +252,8 @@ bool wooting_rgb_array_set_full(const uint8_t* colors_buffer) {
233252
return true;
234253
}
235254
}
255+
256+
const WOOTING_USB_META* wooting_rgb_device_info() {
257+
if (!wooting_usb_get_meta()->connected) wooting_usb_find_keyboard();
258+
return wooting_usb_get_meta();
259+
}

src/wooting-rgb-sdk.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ extern "C" {
2727

2828
typedef void(*void_cb)(void);
2929

30-
#define WOOTING_RGB_ROWS 6
31-
#define WOOTING_RGB_COLS 21
3230

3331
/** @brief Check if keyboard connected.
3432
@@ -149,7 +147,7 @@ This function will set a complete color array. This will not directly update the
149147
If you use a non-C language it is recommended to use the wooting_rgb_array_set_single function to change the colors to avoid compatibility issues.
150148
151149
Buffer should be layout out as [Row0Col0Red, Row0Col0Green, Row0Col0Blue, Row0Col1Red, Row0Col1Green, Row0Col1Blue, ... Row5Row20Red, Row5Row20Green, Row5Row20Blue].
152-
Expected size is 6 row * 21 columns * 3 colors per key = 576 bytes.
150+
Expected size is 6 row * 21 columns * 3 colors per key = 378 bytes.
153151
154152
@ingroup API
155153
@param colors_buffer Pointer to a buffer of a full color array
@@ -159,6 +157,17 @@ This functions return true (1) if the colours are changed (if auto update flag:
159157
*/
160158
WOOTINGRGBSDK_API bool wooting_rgb_array_set_full(const uint8_t *colors_buffer);
161159

160+
/** @brief Retrieve information about the connected Device
161+
162+
This function returns a pointer to a struct which provides various relevant details about the currently connected device. E.g. max rgb rows, columns, etc
163+
164+
@ingroup API
165+
166+
@returns
167+
This functions returns a pointer to a `WOOTING_USB_META` struct which contains relevant Device Information
168+
*/
169+
WOOTINGRGBSDK_API const WOOTING_USB_META* wooting_rgb_device_info();
170+
162171
#ifdef __cplusplus
163172
}
164173
#endif

src/wooting-usb.c

Lines changed: 98 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@
1313

1414
#define WOOTING_COMMAND_SIZE 8
1515
#define WOOTING_REPORT_SIZE 129
16-
#define WOOTING_ONE_VID 0x03EB
16+
#define WOOTING_VID 0x03EB
1717
#define WOOTING_ONE_PID 0xFF01
18+
#define WOOTING_TWO_PID 0xFF02
1819

19-
static uint16_t getCrc16ccitt(const uint8_t* buffer, uint16_t size);
20+
static WOOTING_USB_META wooting_usb_meta;
21+
22+
uint8_t key_code_limit = WOOTING_TWO_KEY_CODE_LIMIT;
2023

2124
static void_cb disconnected_callback = NULL;
2225
static hid_device* keyboard_handle = NULL;
@@ -41,7 +44,50 @@ static uint16_t getCrc16ccitt(const uint8_t* buffer, uint16_t size)
4144
return crc;
4245
}
4346

47+
#pragma region Set Meta
48+
49+
static void reset_meta() {
50+
wooting_usb_meta.connected = false;
51+
52+
wooting_usb_meta.model = "N/A";
53+
wooting_usb_meta.device_type = -1;
54+
wooting_usb_meta.led_index_max = 0;
55+
wooting_usb_meta.max_rows = 0;
56+
wooting_usb_meta.max_columns = 0;
57+
wooting_usb_meta.led_index_max = 0;
58+
}
59+
60+
static void set_meta_wooting_one() {
61+
wooting_usb_meta.model = "Wooting one";
62+
wooting_usb_meta.device_type = DEVICE_KEYBOARD_TKL;
63+
wooting_usb_meta.led_index_max = WOOTING_ONE_KEY_CODE_LIMIT;
64+
wooting_usb_meta.max_rows = WOOTING_RGB_ROWS;
65+
wooting_usb_meta.max_columns = WOOTING_ONE_RGB_COLS;
66+
wooting_usb_meta.led_index_max = WOOTING_ONE_KEY_CODE_LIMIT;
67+
}
68+
69+
static void set_meta_wooting_two() {
70+
wooting_usb_meta.model = "Wooting two";
71+
wooting_usb_meta.device_type = DEVICE_KEYBOARD;
72+
wooting_usb_meta.led_index_max = WOOTING_TWO_KEY_CODE_LIMIT;
73+
wooting_usb_meta.max_rows = WOOTING_RGB_ROWS;
74+
wooting_usb_meta.max_columns = WOOTING_TWO_RGB_COLS;
75+
wooting_usb_meta.led_index_max = WOOTING_TWO_KEY_CODE_LIMIT;
76+
}
77+
78+
WOOTING_USB_META* wooting_usb_get_meta() {
79+
//We want to initialise the struct to the default values if it hasn't been set
80+
if (wooting_usb_meta.model == NULL){
81+
reset_meta();
82+
}
83+
84+
return &wooting_usb_meta;
85+
}
86+
87+
#pragma endregion
88+
4489
void wooting_usb_disconnect(bool trigger_cb) {
90+
reset_meta();
4591
hid_close(keyboard_handle);
4692
keyboard_handle = NULL;
4793

@@ -62,9 +108,17 @@ bool wooting_usb_find_keyboard() {
62108
return hid_read_timeout(keyboard_handle, &stub, 0, 0) != -1;
63109
}
64110

65-
struct hid_device_info* hid_info = hid_enumerate(WOOTING_ONE_VID, WOOTING_ONE_PID);
111+
struct hid_device_info* hid_info;
66112

67-
if (hid_info == NULL) {
113+
reset_meta();
114+
115+
if ((hid_info = hid_enumerate(WOOTING_VID, WOOTING_ONE_PID)) != NULL) {
116+
set_meta_wooting_one();
117+
}
118+
else if ((hid_info = hid_enumerate(WOOTING_VID, WOOTING_TWO_PID)) != NULL) {
119+
set_meta_wooting_two();
120+
}
121+
else {
68122
return false;
69123
}
70124

@@ -105,6 +159,7 @@ bool wooting_usb_find_keyboard() {
105159
}
106160

107161
hid_free_enumeration(hid_info);
162+
wooting_usb_meta.connected = true;
108163
return keyboard_found;
109164
}
110165

@@ -120,34 +175,39 @@ bool wooting_usb_send_buffer(RGB_PARTS part_number, uint8_t rgb_buffer[]) {
120175
report_buffer[2] = 0xDA; // Magicword
121176
report_buffer[3] = WOOTING_RAW_COLORS_REPORT; // Report ID
122177
switch (part_number) {
123-
case PART0: {
124-
report_buffer[4] = 0; // Slave nr
125-
report_buffer[5] = 0; // Reg start address
126-
break;
127-
}
128-
case PART1: {
129-
report_buffer[4] = 0; // Slave nr
130-
report_buffer[5] = RGB_RAW_BUFFER_SIZE; // Reg start address
131-
break;
132-
}
133-
case PART2: {
134-
report_buffer[4] = 1; // Slave nr
135-
report_buffer[5] = 0; // Reg start address
136-
break;
137-
}
138-
case PART3: {
139-
report_buffer[4] = 1; // Slave nr
140-
report_buffer[5] = RGB_RAW_BUFFER_SIZE; // Reg start address
141-
break;
142-
}
143-
case PART4: {
144-
report_buffer[4] = 2; // Slave nr
145-
report_buffer[5] = 0; // Reg start address
146-
break;
147-
}
148-
default: {
149-
return false;
150-
}
178+
case PART0: {
179+
report_buffer[4] = 0; // Slave nr
180+
report_buffer[5] = 0; // Reg start address
181+
break;
182+
}
183+
case PART1: {
184+
report_buffer[4] = 0; // Slave nr
185+
report_buffer[5] = RGB_RAW_BUFFER_SIZE; // Reg start address
186+
break;
187+
}
188+
case PART2: {
189+
report_buffer[4] = 1; // Slave nr
190+
report_buffer[5] = 0; // Reg start address
191+
break;
192+
}
193+
case PART3: {
194+
report_buffer[4] = 1; // Slave nr
195+
report_buffer[5] = RGB_RAW_BUFFER_SIZE; // Reg start address
196+
break;
197+
}
198+
// wooting_rgb_array_update_keyboard will not run into this
199+
case PART4: {
200+
//Wooting One will not have this part of the report
201+
if (wooting_usb_meta.device_type != DEVICE_KEYBOARD) {
202+
return false;
203+
}
204+
report_buffer[4] = 2; // Slave nr
205+
report_buffer[5] = 0; // Reg start address
206+
break;
207+
}
208+
default: {
209+
return false;
210+
}
151211
}
152212

153213
memcpy(&report_buffer[6], rgb_buffer, RGB_RAW_BUFFER_SIZE);
@@ -169,6 +229,12 @@ bool wooting_usb_send_feature(uint8_t commandId, uint8_t parameter0, uint8_t par
169229
if (!wooting_usb_find_keyboard()) {
170230
return false;
171231
}
232+
// prevent sending unnecessary data to the wootings if the index exceedes it's capabilities
233+
if ((commandId == WOOTING_SINGLE_COLOR_COMMAND && parameter0 > key_code_limit)
234+
|| (commandId == WOOTING_SINGLE_RESET_COMMAND && parameter3 > key_code_limit)) {
235+
// this is not a usb error so let's return true. wooting_rgb_direct_set_key would also behave differently otherwise.
236+
return true;
237+
}
172238

173239
uint8_t report_buffer[WOOTING_COMMAND_SIZE];
174240

src/wooting-usb.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,35 @@ typedef enum RGB_PARTS {
1717
PART4
1818
} RGB_PARTS;
1919

20+
21+
typedef enum WOOTING_DEVICE_TYPE {
22+
// 10 Keyless Keyboard. E.g. Wooting One
23+
DEVICE_KEYBOARD_TKL = 1,
24+
25+
// Full Size keyboard. E.g. Wooting Two
26+
DEVICE_KEYBOARD = 2
27+
} WOOTING_DEVICE_TYPE;
28+
29+
typedef struct WOOTING_USB_META {
30+
bool connected;
31+
const char* model;
32+
uint8_t max_rows;
33+
uint8_t max_columns;
34+
uint8_t led_index_max;
35+
WOOTING_DEVICE_TYPE device_type;
36+
37+
} WOOTING_USB_META;
38+
2039
#define RGB_RAW_BUFFER_SIZE 96
2140

41+
#define WOOTING_RGB_ROWS 6
42+
#define WOOTING_RGB_COLS 21
43+
#define WOOTING_ONE_RGB_COLS 17
44+
#define WOOTING_TWO_RGB_COLS 21
45+
46+
#define WOOTING_ONE_KEY_CODE_LIMIT 95
47+
#define WOOTING_TWO_KEY_CODE_LIMIT 116
48+
2249
#define WOOTING_RAW_COLORS_REPORT 11
2350
#define WOOTING_SINGLE_COLOR_COMMAND 30
2451
#define WOOTING_SINGLE_RESET_COMMAND 31
@@ -27,6 +54,10 @@ typedef enum RGB_PARTS {
2754

2855
void wooting_usb_set_disconnected_cb(void_cb cb);
2956
void wooting_usb_disconnect(bool trigger_cb);
30-
bool wooting_usb_find_keyboard();
57+
58+
bool wooting_usb_find_keyboard(void);
59+
60+
WOOTING_USB_META* wooting_usb_get_meta();
61+
3162
bool wooting_usb_send_buffer(RGB_PARTS part_number, uint8_t rgb_buffer[]);
3263
bool wooting_usb_send_feature(uint8_t commandId, uint8_t parameter0, uint8_t parameter1, uint8_t parameter2, uint8_t parameter3);

0 commit comments

Comments
 (0)