transport.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include "config.h"
  2. #include "matrix.h"
  3. #include "quantum.h"
  4. #define ROWS_PER_HAND (MATRIX_ROWS/2)
  5. #ifdef RGBLIGHT_ENABLE
  6. # include "rgblight.h"
  7. #endif
  8. #ifdef BACKLIGHT_ENABLE
  9. # include "backlight.h"
  10. extern backlight_config_t backlight_config;
  11. #endif
  12. #if defined(USE_I2C) || defined(EH)
  13. #include "i2c.h"
  14. #ifndef SLAVE_I2C_ADDRESS
  15. # define SLAVE_I2C_ADDRESS 0x32
  16. #endif
  17. #if (MATRIX_COLS > 8)
  18. # error "Currently only supports 8 COLS"
  19. #endif
  20. // Get rows from other half over i2c
  21. bool transport_master(matrix_row_t matrix[]) {
  22. int err = 0;
  23. // write backlight info
  24. #ifdef BACKLIGHT_ENABLE
  25. if (BACKLIT_DIRTY) {
  26. err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
  27. if (err) { goto i2c_error; }
  28. // Backlight location
  29. err = i2c_master_write(I2C_BACKLIT_START);
  30. if (err) { goto i2c_error; }
  31. // Write backlight
  32. i2c_master_write(get_backlight_level());
  33. BACKLIT_DIRTY = false;
  34. }
  35. #endif
  36. err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
  37. if (err) { goto i2c_error; }
  38. // start of matrix stored at I2C_KEYMAP_START
  39. err = i2c_master_write(I2C_KEYMAP_START);
  40. if (err) { goto i2c_error; }
  41. // Start read
  42. err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ);
  43. if (err) { goto i2c_error; }
  44. if (!err) {
  45. int i;
  46. for (i = 0; i < ROWS_PER_HAND-1; ++i) {
  47. matrix[i] = i2c_master_read(I2C_ACK);
  48. }
  49. matrix[i] = i2c_master_read(I2C_NACK);
  50. i2c_master_stop();
  51. } else {
  52. i2c_error: // the cable is disconnceted, or something else went wrong
  53. i2c_reset_state();
  54. return false;
  55. }
  56. #ifdef RGBLIGHT_ENABLE
  57. if (RGB_DIRTY) {
  58. err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
  59. if (err) { goto i2c_error; }
  60. // RGB Location
  61. err = i2c_master_write(I2C_RGB_START);
  62. if (err) { goto i2c_error; }
  63. uint32_t dword = eeconfig_read_rgblight();
  64. // Write RGB
  65. err = i2c_master_write_data(&dword, 4);
  66. if (err) { goto i2c_error; }
  67. RGB_DIRTY = false;
  68. i2c_master_stop();
  69. }
  70. #endif
  71. return true;
  72. }
  73. void transport_slave(matrix_row_t matrix[]) {
  74. for (int i = 0; i < ROWS_PER_HAND; ++i)
  75. {
  76. i2c_slave_buffer[I2C_KEYMAP_START + i] = matrix[i];
  77. }
  78. // Read Backlight Info
  79. #ifdef BACKLIGHT_ENABLE
  80. if (BACKLIT_DIRTY)
  81. {
  82. backlight_set(i2c_slave_buffer[I2C_BACKLIT_START]);
  83. BACKLIT_DIRTY = false;
  84. }
  85. #endif
  86. #ifdef RGBLIGHT_ENABLE
  87. if (RGB_DIRTY)
  88. {
  89. // Disable interupts (RGB data is big)
  90. cli();
  91. // Create new DWORD for RGB data
  92. uint32_t dword;
  93. // Fill the new DWORD with the data that was sent over
  94. uint8_t * dword_dat = (uint8_t *)(&dword);
  95. for (int i = 0; i < 4; i++)
  96. {
  97. dword_dat[i] = i2c_slave_buffer[I2C_RGB_START + i];
  98. }
  99. // Update the RGB now with the new data and set RGB_DIRTY to false
  100. rgblight_update_dword(dword);
  101. RGB_DIRTY = false;
  102. // Re-enable interupts now that RGB is set
  103. sei();
  104. }
  105. #endif
  106. }
  107. void transport_master_init(void) {
  108. i2c_master_init();
  109. }
  110. void transport_slave_init(void) {
  111. i2c_slave_init(SLAVE_I2C_ADDRESS);
  112. }
  113. #else // USE_SERIAL
  114. #include "serial.h"
  115. typedef struct _Serial_s2m_buffer_t {
  116. // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack
  117. matrix_row_t smatrix[ROWS_PER_HAND];
  118. } Serial_s2m_buffer_t;
  119. typedef struct _Serial_m2s_buffer_t {
  120. #ifdef BACKLIGHT_ENABLE
  121. uint8_t backlight_level;
  122. #endif
  123. #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
  124. rgblight_config_t rgblight_config; //not yet use
  125. //
  126. // When MCUs on both sides drive their respective RGB LED chains,
  127. // it is necessary to synchronize, so it is necessary to communicate RGB information.
  128. // In that case, define the RGBLIGHT_SPLIT macro.
  129. //
  130. // Otherwise, if the master side MCU drives both sides RGB LED chains,
  131. // there is no need to communicate.
  132. #endif
  133. } Serial_m2s_buffer_t;
  134. volatile Serial_s2m_buffer_t serial_s2m_buffer = {};
  135. volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
  136. uint8_t volatile status0 = 0;
  137. SSTD_t transactions[] = {
  138. { (uint8_t *)&status0,
  139. sizeof(serial_m2s_buffer), (uint8_t *)&serial_m2s_buffer,
  140. sizeof(serial_s2m_buffer), (uint8_t *)&serial_s2m_buffer
  141. }
  142. };
  143. void transport_master_init(void)
  144. { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
  145. void transport_slave_init(void)
  146. { soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
  147. bool transport_master(matrix_row_t matrix[]) {
  148. if (soft_serial_transaction()) {
  149. return false;
  150. }
  151. // TODO: if MATRIX_COLS > 8 change to unpack()
  152. for (int i = 0; i < ROWS_PER_HAND; ++i) {
  153. matrix[i] = serial_s2m_buffer.smatrix[i];
  154. }
  155. #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
  156. // Code to send RGB over serial goes here (not implemented yet)
  157. #endif
  158. #ifdef BACKLIGHT_ENABLE
  159. // Write backlight level for slave to read
  160. serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0;
  161. #endif
  162. return true;
  163. }
  164. void transport_slave(matrix_row_t matrix[]) {
  165. // TODO: if MATRIX_COLS > 8 change to pack()
  166. for (int i = 0; i < ROWS_PER_HAND; ++i)
  167. {
  168. serial_s2m_buffer.smatrix[i] = matrix[i];
  169. }
  170. #ifdef BACKLIGHT_ENABLE
  171. backlight_set(serial_m2s_buffer.backlight_level);
  172. #endif
  173. #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
  174. // Add serial implementation for RGB here
  175. #endif
  176. }
  177. #endif