| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- #include "config.h"
- #include "matrix.h"
- #include "quantum.h"
- #define ROWS_PER_HAND (MATRIX_ROWS/2)
- #ifdef RGBLIGHT_ENABLE
- # include "rgblight.h"
- #endif
- #ifdef BACKLIGHT_ENABLE
- # include "backlight.h"
- extern backlight_config_t backlight_config;
- #endif
- #if defined(USE_I2C) || defined(EH)
- #include "i2c.h"
- #ifndef SLAVE_I2C_ADDRESS
- # define SLAVE_I2C_ADDRESS 0x32
- #endif
- #if (MATRIX_COLS > 8)
- # error "Currently only supports 8 COLS"
- #endif
- // Get rows from other half over i2c
- bool transport_master(matrix_row_t matrix[]) {
- int err = 0;
- // write backlight info
- #ifdef BACKLIGHT_ENABLE
- if (BACKLIT_DIRTY) {
- err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
- if (err) { goto i2c_error; }
- // Backlight location
- err = i2c_master_write(I2C_BACKLIT_START);
- if (err) { goto i2c_error; }
- // Write backlight
- i2c_master_write(get_backlight_level());
- BACKLIT_DIRTY = false;
- }
- #endif
- err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
- if (err) { goto i2c_error; }
- // start of matrix stored at I2C_KEYMAP_START
- err = i2c_master_write(I2C_KEYMAP_START);
- if (err) { goto i2c_error; }
- // Start read
- err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ);
- if (err) { goto i2c_error; }
- if (!err) {
- int i;
- for (i = 0; i < ROWS_PER_HAND-1; ++i) {
- matrix[i] = i2c_master_read(I2C_ACK);
- }
- matrix[i] = i2c_master_read(I2C_NACK);
- i2c_master_stop();
- } else {
- i2c_error: // the cable is disconnceted, or something else went wrong
- i2c_reset_state();
- return false;
- }
- #ifdef RGBLIGHT_ENABLE
- if (RGB_DIRTY) {
- err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
- if (err) { goto i2c_error; }
- // RGB Location
- err = i2c_master_write(I2C_RGB_START);
- if (err) { goto i2c_error; }
- uint32_t dword = eeconfig_read_rgblight();
- // Write RGB
- err = i2c_master_write_data(&dword, 4);
- if (err) { goto i2c_error; }
- RGB_DIRTY = false;
- i2c_master_stop();
- }
- #endif
- return true;
- }
- void transport_slave(matrix_row_t matrix[]) {
- for (int i = 0; i < ROWS_PER_HAND; ++i)
- {
- i2c_slave_buffer[I2C_KEYMAP_START + i] = matrix[i];
- }
- // Read Backlight Info
- #ifdef BACKLIGHT_ENABLE
- if (BACKLIT_DIRTY)
- {
- backlight_set(i2c_slave_buffer[I2C_BACKLIT_START]);
- BACKLIT_DIRTY = false;
- }
- #endif
- #ifdef RGBLIGHT_ENABLE
- if (RGB_DIRTY)
- {
- // Disable interupts (RGB data is big)
- cli();
- // Create new DWORD for RGB data
- uint32_t dword;
- // Fill the new DWORD with the data that was sent over
- uint8_t * dword_dat = (uint8_t *)(&dword);
- for (int i = 0; i < 4; i++)
- {
- dword_dat[i] = i2c_slave_buffer[I2C_RGB_START + i];
- }
- // Update the RGB now with the new data and set RGB_DIRTY to false
- rgblight_update_dword(dword);
- RGB_DIRTY = false;
- // Re-enable interupts now that RGB is set
- sei();
- }
- #endif
- }
- void transport_master_init(void) {
- i2c_master_init();
- }
- void transport_slave_init(void) {
- i2c_slave_init(SLAVE_I2C_ADDRESS);
- }
- #else // USE_SERIAL
- #include "serial.h"
- typedef struct _Serial_s2m_buffer_t {
- // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack
- matrix_row_t smatrix[ROWS_PER_HAND];
- } Serial_s2m_buffer_t;
- typedef struct _Serial_m2s_buffer_t {
- #ifdef BACKLIGHT_ENABLE
- uint8_t backlight_level;
- #endif
- #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
- rgblight_config_t rgblight_config; //not yet use
- //
- // When MCUs on both sides drive their respective RGB LED chains,
- // it is necessary to synchronize, so it is necessary to communicate RGB information.
- // In that case, define the RGBLIGHT_SPLIT macro.
- //
- // Otherwise, if the master side MCU drives both sides RGB LED chains,
- // there is no need to communicate.
- #endif
- } Serial_m2s_buffer_t;
- volatile Serial_s2m_buffer_t serial_s2m_buffer = {};
- volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
- uint8_t volatile status0 = 0;
- SSTD_t transactions[] = {
- { (uint8_t *)&status0,
- sizeof(serial_m2s_buffer), (uint8_t *)&serial_m2s_buffer,
- sizeof(serial_s2m_buffer), (uint8_t *)&serial_s2m_buffer
- }
- };
- void transport_master_init(void)
- { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
- void transport_slave_init(void)
- { soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
- bool transport_master(matrix_row_t matrix[]) {
- if (soft_serial_transaction()) {
- return false;
- }
- // TODO: if MATRIX_COLS > 8 change to unpack()
- for (int i = 0; i < ROWS_PER_HAND; ++i) {
- matrix[i] = serial_s2m_buffer.smatrix[i];
- }
- #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
- // Code to send RGB over serial goes here (not implemented yet)
- #endif
- #ifdef BACKLIGHT_ENABLE
- // Write backlight level for slave to read
- serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0;
- #endif
- return true;
- }
- void transport_slave(matrix_row_t matrix[]) {
- // TODO: if MATRIX_COLS > 8 change to pack()
- for (int i = 0; i < ROWS_PER_HAND; ++i)
- {
- serial_s2m_buffer.smatrix[i] = matrix[i];
- }
- #ifdef BACKLIGHT_ENABLE
- backlight_set(serial_m2s_buffer.backlight_level);
- #endif
- #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
- // Add serial implementation for RGB here
- #endif
- }
- #endif
|