You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							225 lines
						
					
					
						
							5.2 KiB
						
					
					
				
			
		
		
	
	
							225 lines
						
					
					
						
							5.2 KiB
						
					
					
				
 | 
						|
#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
 |