diff --git a/keyboards/lily58/keymaps/blanksourcecode/keymap.c b/keyboards/lily58/keymaps/blanksourcecode/keymap.c index d14eb65c9260..03ce31ef0861 100644 --- a/keyboards/lily58/keymaps/blanksourcecode/keymap.c +++ b/keyboards/lily58/keymaps/blanksourcecode/keymap.c @@ -8,6 +8,10 @@ #include "ssd1306.h" #endif +// Add headers for raw hid communication +#include +#include "raw_hid.h" + extern keymap_config_t keymap_config; extern rgblight_config_t rgblight_config; extern uint8_t is_master; @@ -228,6 +232,70 @@ void matrix_scan_user(void) { iota_gfx_task(); } +// HID input +bool is_hid_connected = false; // Flag indicating if we have a PC connection yet +uint8_t screen_max_count = 0; // Number of info screens we can scroll through (set by connecting node script) +uint8_t screen_show_index = 0; // Current index of the info screen we are displaying +uint8_t screen_data_buffer[SERIAL_SCREEN_BUFFER_LENGTH - 1] = {0}; // Buffer used to store the screen data sent by connected node script +int screen_data_index = 0; // Current index into the screen_data_buffer that we should write to + +void raw_hid_send_screen_index(void) { + // Send the current info screen index to the connected node script so that it can pass back the new data + uint8_t send_data[32] = {0}; + send_data[0] = screen_show_index + 1; // Add one so that we can distinguish it from a null byte + raw_hid_send(send_data, sizeof(send_data)); +} + +void raw_hid_receive(uint8_t *data, uint8_t length) { + // PC connected, so set the flag to show a message on the master display + is_hid_connected = true; + + // Initial connections use '1' in the first byte to indicate this + if (length > 1 && data[0] == 1) { + // New connection so restart screen_data_buffer + screen_data_index = 0; + + // The second byte is the number of info screens the connected node script allows us to scroll through + screen_max_count = data[1]; + if (screen_show_index >= screen_max_count) { + screen_show_index = 0; + } + + // Tell the connection which info screen we want to look at initially + raw_hid_send_screen_index(); + return; + } + + // Otherwise the data we receive is one line of the screen to show on the display + if (length >= 21) { + // Copy the data into our buffer and increment the number of lines we have got so far + memcpy((char*)&screen_data_buffer[screen_data_index * 21], data, 21); + screen_data_index++; + + // Once we reach 4 lines, we have a full screen + if (screen_data_index == 4) { + // Reset the buffer back to receive the next full screen data + screen_data_index = 0; + + // Now get ready to transfer the whole 4 lines to the slave side of the keyboard. + // First clear the transfer buffer with spaces just in case. + memset((char*)&serial_slave_screen_buffer[0], ' ', sizeof(serial_slave_screen_buffer)); + + // 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 + memcpy((char*)&serial_slave_screen_buffer[1], screen_data_buffer, sizeof(screen_data_buffer)); + + // Set index 0 to indicate a connection has been established + serial_slave_screen_buffer[0] = 1; + + // Make sure to zero terminate the buffer + serial_slave_screen_buffer[sizeof(serial_slave_screen_buffer) - 1] = 0; + + // Indicate that the screen data has changed and needs transferring to the slave side + hid_screen_change = true; + } + } +} + // Screen printing char layer_state_str[20]; const char *write_layer(void) { @@ -268,15 +336,34 @@ const char *write_rgb(void) { return rbf_info_str; } +char hid_info_str[20]; +const char *write_hid(void) { + snprintf(hid_info_str, sizeof(hid_info_str), "%s", is_hid_connected ? "connected." : " "); + return hid_info_str; +} + +void write_slave_info_screen(struct CharacterMatrix *matrix) { + if (serial_slave_screen_buffer[0] > 0) { + // If the first byte of the buffer is non-zero we should have a full set of data to show, + // So we copy it into the display + matrix_write(matrix, (char*)serial_slave_screen_buffer + 1); + } else { + // Otherwise we just draw the logo + matrix_write_ln(matrix, ""); + matrix_write(matrix, read_logo()); + } +} + void matrix_render_user(struct CharacterMatrix *matrix) { if (is_master) { // Show layer and rgb values on the master side matrix_write_ln(matrix, write_layer()); matrix_write_ln(matrix, " "); matrix_write_ln(matrix, write_rgb()); + matrix_write(matrix, write_hid()); // Add if we have a connection established } else { - // Show the logo on the slave side - matrix_write(matrix, read_logo()); + // Show the logo or screen info on the slave side + write_slave_info_screen(matrix); } } @@ -451,6 +538,32 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { // Rotary Encoder void encoder_update_user(uint8_t index, bool clockwise) { switch (biton32(layer_state)) { + case _RGB: { + // On the RGB layer we control the screen display with the encoder + if (clockwise) { + // Increment and loop back to beginning if we go over the max + screen_show_index++; + if (screen_show_index >= screen_max_count) { + screen_show_index = 0; + } + } else { + // Decrement and loop back to the end if we are about to go below zero, + // Be careful since index is unsigned. + if (screen_show_index == 0) { + screen_show_index = screen_max_count - 1; + } else { + screen_show_index--; + } + } + + // If we have a connection we should tell it about the change, + // Otherwise it will be notified when it first connects instead. + if (is_hid_connected) { + raw_hid_send_screen_index(); + } + break; + } + default: { // Page up and Page down on all layers if (clockwise) { diff --git a/keyboards/lily58/keymaps/blanksourcecode/rules.mk b/keyboards/lily58/keymaps/blanksourcecode/rules.mk index dc14e27c8859..d7567f695235 100644 --- a/keyboards/lily58/keymaps/blanksourcecode/rules.mk +++ b/keyboards/lily58/keymaps/blanksourcecode/rules.mk @@ -25,3 +25,8 @@ SRC += ./glcdfont.c \ ./lib/logo_reader.c \ TAP_DANCE_ENABLE = yes + +RAW_ENABLE = yes # Enable RAW HID communication to PC + +Link_Time_Optimization = yes # Reduce size of firmware by optimizing at link time +EXTRAFLAGS += -flto diff --git a/keyboards/lily58/rev1/split_scomm.c b/keyboards/lily58/rev1/split_scomm.c index a1fe6ba5b823..f83fbaf90163 100755 --- a/keyboards/lily58/rev1/split_scomm.c +++ b/keyboards/lily58/rev1/split_scomm.c @@ -13,11 +13,14 @@ uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; +uint8_t volatile serial_slave_screen_buffer[SERIAL_SCREEN_BUFFER_LENGTH] = {0}; uint8_t volatile status_com = 0; uint8_t volatile status1 = 0; +uint8_t volatile status2 = 0; uint8_t slave_buffer_change_count = 0; uint8_t s_change_old = 0xff; uint8_t s_change_new = 0xff; +bool volatile hid_screen_change = false; SSTD_t transactions[] = { #define GET_SLAVE_STATUS 0 @@ -37,6 +40,12 @@ SSTD_t transactions[] = { { (uint8_t *)&status1, 0, NULL, sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer + }, +#define PUT_SLAVE_SCREEN 3 + /* master is transfering screen data to slave */ + { (uint8_t *)&status2, + sizeof(serial_slave_screen_buffer), (uint8_t *)serial_slave_screen_buffer, + 0, NULL } }; @@ -73,6 +82,11 @@ int serial_update_buffers(int master_update) smatstatus = TRANSACTION_END; // dummy status } + if (hid_screen_change) { + soft_serial_transaction(PUT_SLAVE_SCREEN); + hid_screen_change = false; + } + if( !master_update && !need_retry) { status = soft_serial_transaction(GET_SLAVE_STATUS); } else { diff --git a/keyboards/lily58/rev1/split_scomm.h b/keyboards/lily58/rev1/split_scomm.h index 873d8939d81f..e3223493a2e4 100755 --- a/keyboards/lily58/rev1/split_scomm.h +++ b/keyboards/lily58/rev1/split_scomm.h @@ -10,10 +10,13 @@ // Buffers for master - slave communication #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 #define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2 +#define SERIAL_SCREEN_BUFFER_LENGTH (/*SSD1306_MatrixCols*/21 * /*SSD1306_MatrixRows*/4 + /*Extra IsEnabledBit*/1) extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH]; extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH]; +extern volatile uint8_t serial_slave_screen_buffer[SERIAL_SCREEN_BUFFER_LENGTH]; extern uint8_t slave_buffer_change_count; +extern volatile bool hid_screen_change; // Flag marking if the screen data is dirty and needs transferring to slave void serial_master_init(void); void serial_slave_init(void);