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
			| 
								 
											7 years ago
										 
									 | 
							
								
							 | 
						||
| 
								 | 
							
								#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
							 |