Skip to content

Commit 3ae0977

Browse files
Add support for slave display info over raw hid
1 parent 34c0a30 commit 3ae0977

File tree

4 files changed

+137
-2
lines changed

4 files changed

+137
-2
lines changed

keyboards/lily58/keymaps/blanksourcecode/keymap.c

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
#include "ssd1306.h"
99
#endif
1010

11+
// Add headers for raw hid communication
12+
#include <split_scomm.h>
13+
#include "raw_hid.h"
14+
1115
extern keymap_config_t keymap_config;
1216
extern rgblight_config_t rgblight_config;
1317
extern uint8_t is_master;
@@ -228,6 +232,70 @@ void matrix_scan_user(void) {
228232
iota_gfx_task();
229233
}
230234

235+
// HID input
236+
bool is_hid_connected = false; // Flag indicating if we have a PC connection yet
237+
uint8_t screen_max_count = 0; // Number of info screens we can scroll through (set by connecting node script)
238+
uint8_t screen_show_index = 0; // Current index of the info screen we are displaying
239+
uint8_t screen_data_buffer[SERIAL_SCREEN_BUFFER_LENGTH - 1] = {0}; // Buffer used to store the screen data sent by connected node script
240+
int screen_data_index = 0; // Current index into the screen_data_buffer that we should write to
241+
242+
void raw_hid_send_screen_index(void) {
243+
// Send the current info screen index to the connected node script so that it can pass back the new data
244+
uint8_t send_data[32] = {0};
245+
send_data[0] = screen_show_index + 1; // Add one so that we can distinguish it from a null byte
246+
raw_hid_send(send_data, sizeof(send_data));
247+
}
248+
249+
void raw_hid_receive(uint8_t *data, uint8_t length) {
250+
// PC connected, so set the flag to show a message on the master display
251+
is_hid_connected = true;
252+
253+
// Initial connections use '1' in the first byte to indicate this
254+
if (length > 1 && data[0] == 1) {
255+
// New connection so restart screen_data_buffer
256+
screen_data_index = 0;
257+
258+
// The second byte is the number of info screens the connected node script allows us to scroll through
259+
screen_max_count = data[1];
260+
if (screen_show_index >= screen_max_count) {
261+
screen_show_index = 0;
262+
}
263+
264+
// Tell the connection which info screen we want to look at initially
265+
raw_hid_send_screen_index();
266+
return;
267+
}
268+
269+
// Otherwise the data we receive is one line of the screen to show on the display
270+
if (length >= 21) {
271+
// Copy the data into our buffer and increment the number of lines we have got so far
272+
memcpy((char*)&screen_data_buffer[screen_data_index * 21], data, 21);
273+
screen_data_index++;
274+
275+
// Once we reach 4 lines, we have a full screen
276+
if (screen_data_index == 4) {
277+
// Reset the buffer back to receive the next full screen data
278+
screen_data_index = 0;
279+
280+
// Now get ready to transfer the whole 4 lines to the slave side of the keyboard.
281+
// First clear the transfer buffer with spaces just in case.
282+
memset((char*)&serial_slave_screen_buffer[0], ' ', sizeof(serial_slave_screen_buffer));
283+
284+
// Copy in the 4 lines of screen data, but start at index 1, we use index 0 to indicate a connection in the slave code
285+
memcpy((char*)&serial_slave_screen_buffer[1], screen_data_buffer, sizeof(screen_data_buffer));
286+
287+
// Set index 0 to indicate a connection has been established
288+
serial_slave_screen_buffer[0] = 1;
289+
290+
// Make sure to zero terminate the buffer
291+
serial_slave_screen_buffer[sizeof(serial_slave_screen_buffer) - 1] = 0;
292+
293+
// Indicate that the screen data has changed and needs transferring to the slave side
294+
hid_screen_change = true;
295+
}
296+
}
297+
}
298+
231299
// Screen printing
232300
char layer_state_str[20];
233301
const char *write_layer(void) {
@@ -268,15 +336,34 @@ const char *write_rgb(void) {
268336
return rbf_info_str;
269337
}
270338

339+
char hid_info_str[20];
340+
const char *write_hid(void) {
341+
snprintf(hid_info_str, sizeof(hid_info_str), "%s", is_hid_connected ? "connected." : " ");
342+
return hid_info_str;
343+
}
344+
345+
void write_slave_info_screen(struct CharacterMatrix *matrix) {
346+
if (serial_slave_screen_buffer[0] > 0) {
347+
// If the first byte of the buffer is non-zero we should have a full set of data to show,
348+
// So we copy it into the display
349+
matrix_write(matrix, (char*)serial_slave_screen_buffer + 1);
350+
} else {
351+
// Otherwise we just draw the logo
352+
matrix_write_ln(matrix, "");
353+
matrix_write(matrix, read_logo());
354+
}
355+
}
356+
271357
void matrix_render_user(struct CharacterMatrix *matrix) {
272358
if (is_master) {
273359
// Show layer and rgb values on the master side
274360
matrix_write_ln(matrix, write_layer());
275361
matrix_write_ln(matrix, " ");
276362
matrix_write_ln(matrix, write_rgb());
363+
matrix_write(matrix, write_hid()); // Add if we have a connection established
277364
} else {
278-
// Show the logo on the slave side
279-
matrix_write(matrix, read_logo());
365+
// Show the logo or screen info on the slave side
366+
write_slave_info_screen(matrix);
280367
}
281368
}
282369

@@ -451,6 +538,32 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
451538
// Rotary Encoder
452539
void encoder_update_user(uint8_t index, bool clockwise) {
453540
switch (biton32(layer_state)) {
541+
case _RGB: {
542+
// On the RGB layer we control the screen display with the encoder
543+
if (clockwise) {
544+
// Increment and loop back to beginning if we go over the max
545+
screen_show_index++;
546+
if (screen_show_index >= screen_max_count) {
547+
screen_show_index = 0;
548+
}
549+
} else {
550+
// Decrement and loop back to the end if we are about to go below zero,
551+
// Be careful since index is unsigned.
552+
if (screen_show_index == 0) {
553+
screen_show_index = screen_max_count - 1;
554+
} else {
555+
screen_show_index--;
556+
}
557+
}
558+
559+
// If we have a connection we should tell it about the change,
560+
// Otherwise it will be notified when it first connects instead.
561+
if (is_hid_connected) {
562+
raw_hid_send_screen_index();
563+
}
564+
break;
565+
}
566+
454567
default: {
455568
// Page up and Page down on all layers
456569
if (clockwise) {

keyboards/lily58/keymaps/blanksourcecode/rules.mk

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,8 @@ SRC += ./glcdfont.c \
2525
./lib/logo_reader.c \
2626

2727
TAP_DANCE_ENABLE = yes
28+
29+
RAW_ENABLE = yes # Enable RAW HID communication to PC
30+
31+
Link_Time_Optimization = yes # Reduce size of firmware by optimizing at link time
32+
EXTRAFLAGS += -flto

keyboards/lily58/rev1/split_scomm.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@
1313

1414
uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0};
1515
uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0};
16+
uint8_t volatile serial_slave_screen_buffer[SERIAL_SCREEN_BUFFER_LENGTH] = {0};
1617
uint8_t volatile status_com = 0;
1718
uint8_t volatile status1 = 0;
19+
uint8_t volatile status2 = 0;
1820
uint8_t slave_buffer_change_count = 0;
1921
uint8_t s_change_old = 0xff;
2022
uint8_t s_change_new = 0xff;
23+
bool volatile hid_screen_change = false;
2124

2225
SSTD_t transactions[] = {
2326
#define GET_SLAVE_STATUS 0
@@ -37,6 +40,12 @@ SSTD_t transactions[] = {
3740
{ (uint8_t *)&status1,
3841
0, NULL,
3942
sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer
43+
},
44+
#define PUT_SLAVE_SCREEN 3
45+
/* master is transfering screen data to slave */
46+
{ (uint8_t *)&status2,
47+
sizeof(serial_slave_screen_buffer), (uint8_t *)serial_slave_screen_buffer,
48+
0, NULL
4049
}
4150
};
4251

@@ -73,6 +82,11 @@ int serial_update_buffers(int master_update)
7382
smatstatus = TRANSACTION_END; // dummy status
7483
}
7584

85+
if (hid_screen_change) {
86+
soft_serial_transaction(PUT_SLAVE_SCREEN);
87+
hid_screen_change = false;
88+
}
89+
7690
if( !master_update && !need_retry) {
7791
status = soft_serial_transaction(GET_SLAVE_STATUS);
7892
} else {

keyboards/lily58/rev1/split_scomm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010
// Buffers for master - slave communication
1111
#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
1212
#define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2
13+
#define SERIAL_SCREEN_BUFFER_LENGTH (/*SSD1306_MatrixCols*/21 * /*SSD1306_MatrixRows*/4 + /*Extra IsEnabledBit*/1)
1314

1415
extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH];
1516
extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH];
17+
extern volatile uint8_t serial_slave_screen_buffer[SERIAL_SCREEN_BUFFER_LENGTH];
1618
extern uint8_t slave_buffer_change_count;
19+
extern volatile bool hid_screen_change; // Flag marking if the screen data is dirty and needs transferring to slave
1720

1821
void serial_master_init(void);
1922
void serial_slave_init(void);

0 commit comments

Comments
 (0)