#include "betalupi_ergodox.h" #include "extra_mappings.h" #include "features/beta_rawhid.h" #include "features/rawhid_commands.h" extern uint8_t layer_layouts[]; #ifdef BETA_ENABLE_SPELLCHECK #include "features/spellcheck.h" #endif // See features/beta_rawhid.h for prococol documentation void raw_hid_receive(uint8_t *data, uint8_t length) { uint8_t cmd = data[0]; switch (cmd) { case CMD_HELLO: ergodox_right_led_1_on(); _delay_ms(50); ergodox_right_led_1_off(); hid_send_state(); break; #ifdef ENABLE_RGB_MATRIX_FFT_ANIM case CMD_ANIM_DATA: cmd_animation(data, length); break; #endif #ifdef BETA_ENABLE_SPELLCHECK case CMD_SPELLCHECK_WORD: if (data[1]) { ergodox_right_led_1_on(); _delay_ms(50); ergodox_right_led_1_off(); } break; #endif default: break; } } uint8_t nth_byte(size_t n, uint32_t data) { return (data >> (8 * n)) & 0xFF; } // state: layer state. // If this is 0, we'll use global layer_state instead. void _hid_send_state(_hid_send_state_args args) { uint32_t state = args.state ? args.state : layer_state; uint8_t packet[RAW_EPSIZE] = { CMD_SEND_STATE, // Animation state, set later 0x00, // Layer state nth_byte(0, state), nth_byte(1, state), nth_byte(2, state), nth_byte(3, state), // Keymap for active layer layer_layouts[biton32(state)] }; // Set second byte if (rgb_matrix_get_flags() != LED_FLAG_ALL) { // RGB matrix is disabled packet[1] = 0x00; } else { uint8_t mode = rgb_matrix_get_mode(); switch (mode) { #ifdef ENABLE_RGB_MATRIX_FFT_ANIM case RGB_MATRIX_CUSTOM_FFT_ANIM: // FFT Animation is active packet[1] = 0x02; break; #endif default: // Normal animation is active packet[1] = 0x01; break; } } // Note that all sent packets MUST be // RAW_EPSIZE long. raw_hid_send(packet, RAW_EPSIZE); } #ifdef BETA_ENABLE_SPELLCHECK void hid_send_word() { uint8_t packet[RAW_EPSIZE] = { CMD_SPELLCHECK_WORD, spellcheck_buffer_size }; for (int i = 0; i < 2 + spellcheck_buffer_size; i++) { packet[i + 2] = spellcheck_buffer[i]; } raw_hid_send(packet, RAW_EPSIZE); } #endif #ifdef ENABLE_RGB_MATRIX_FFT_ANIM #define FFT_PER_KEY 50 void cmd_animation(uint8_t *data, uint8_t length) { switch (data[1]) { case CMD_ANIM_DATA_fft: // Only read data if animation is in fft mode if (rgb_matrix_get_mode() == RGB_MATRIX_CUSTOM_FFT_ANIM) { // Data should be a pointer to 10 uint8_ts, each representing // the height of a bar on the display. for (uint8_t bin = 0; bin < 10; bin++) { // Scale data values uint8_t d = data[bin + 2]; for (uint8_t i = 0; i < 5; i++) { // Ignore negative indices. // See fft_col_to_array definition. if (fft_col_to_array[bin][i] < 0) { if (d >= FFT_PER_KEY) { d -= FFT_PER_KEY; } else { d = 0; } continue; } uint8_t row = fft_col_to_array[bin][i] % MATRIX_ROWS; uint8_t col = fft_col_to_array[bin][i] / MATRIX_ROWS; if (d >= FFT_PER_KEY) { g_rgb_frame_buffer[row][col] = 0xFF; d -= FFT_PER_KEY; } else if (d > 0) { g_rgb_frame_buffer[row][col] = ((double) d / FFT_PER_KEY) * 0xFF; d = 0; } else { g_rgb_frame_buffer[row][col] = 0; } /* rgb_matrix_set_color( fft_col_to_array[bin][i], last_brightness, 0x00, last_brightness ); */ } } } else { // If not in fft mode and we receive fft data, send a state packet so host stops sending data. hid_send_state(); } break; } } #endif