transport.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #include <string.h>
  2. #include <stddef.h>
  3. #include "config.h"
  4. #include "matrix.h"
  5. #include "quantum.h"
  6. #define ROWS_PER_HAND (MATRIX_ROWS / 2)
  7. #ifdef RGBLIGHT_ENABLE
  8. # include "rgblight.h"
  9. #endif
  10. #ifdef BACKLIGHT_ENABLE
  11. # include "backlight.h"
  12. extern backlight_config_t backlight_config;
  13. #endif
  14. #ifdef ENCODER_ENABLE
  15. # include "encoder.h"
  16. #endif
  17. #if defined(USE_I2C) || defined(EH)
  18. # include "i2c_master.h"
  19. # include "i2c_slave.h"
  20. typedef struct __attribute__ ((__packed__)) {
  21. #ifdef BACKLIGHT_ENABLE
  22. uint8_t backlight_level;
  23. #endif
  24. #ifdef RGBLIGHT_ENABLE
  25. uint32_t rgb_settings;
  26. #endif
  27. #ifdef ENCODER_ENABLE
  28. uint8_t encoder_state[NUMBER_OF_ENCODERS];
  29. #endif
  30. // Keep matrix last, we are only using this for it's offset
  31. uint8_t matrix_start[0];
  32. } transport_values_t;
  33. __attribute__ ((unused))
  34. static transport_values_t transport_values;
  35. #ifdef BACKLIGHT_ENABLE
  36. # define I2C_BACKLIT_START (uint8_t)offsetof(transport_values_t, backlight_level)
  37. #endif
  38. #ifdef RGBLIGHT_ENABLE
  39. # define I2C_RGB_START (uint8_t)offsetof(transport_values_t, rgb_settings)
  40. #endif
  41. #ifdef ENCODER_ENABLE
  42. # define I2C_ENCODER_START (uint8_t)offsetof(transport_values_t, encoder_state)
  43. #endif
  44. #define I2C_KEYMAP_START (uint8_t)offsetof(transport_values_t, matrix_start)
  45. # define TIMEOUT 100
  46. # ifndef SLAVE_I2C_ADDRESS
  47. # define SLAVE_I2C_ADDRESS 0x32
  48. # endif
  49. // Get rows from other half over i2c
  50. bool transport_master(matrix_row_t matrix[]) {
  51. i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_START, (void *)matrix, ROWS_PER_HAND * sizeof(matrix_row_t), TIMEOUT);
  52. // write backlight info
  53. # ifdef BACKLIGHT_ENABLE
  54. uint8_t level = get_backlight_level();
  55. if (level != transport_values.backlight_level) {
  56. if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIT_START, (void *)&level, sizeof(level), TIMEOUT) >= 0) {
  57. transport_values.backlight_level = level;
  58. }
  59. }
  60. # endif
  61. # ifdef RGBLIGHT_ENABLE
  62. uint32_t rgb = rgblight_read_dword();
  63. if (rgb != transport_values.rgb_settings) {
  64. if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START, (void *)&rgb, sizeof(rgb), TIMEOUT) >= 0) {
  65. transport_values.rgb_settings = rgb;
  66. }
  67. }
  68. # endif
  69. # ifdef ENCODER_ENABLE
  70. i2c_readReg(SLAVE_I2C_ADDRESS, I2C_ENCODER_START, (void *)transport_values.encoder_state, sizeof(transport_values.encoder_state), TIMEOUT);
  71. encoder_update_raw(&transport_values.encoder_state[0]);
  72. # endif
  73. return true;
  74. }
  75. void transport_slave(matrix_row_t matrix[]) {
  76. // Copy matrix to I2C buffer
  77. memcpy((void*)(i2c_slave_reg + I2C_KEYMAP_START), (void *)matrix, ROWS_PER_HAND * sizeof(matrix_row_t) );
  78. // Read Backlight Info
  79. # ifdef BACKLIGHT_ENABLE
  80. backlight_set(i2c_slave_reg[I2C_BACKLIT_START]);
  81. # endif
  82. # ifdef RGBLIGHT_ENABLE
  83. uint32_t rgb = *(uint32_t *)(i2c_slave_reg + I2C_RGB_START);
  84. // Update the RGB with the new data
  85. rgblight_update_dword(rgb);
  86. # endif
  87. # ifdef ENCODER_ENABLE
  88. encoder_state_raw((uint8_t*)(i2c_slave_reg + I2C_ENCODER_START));
  89. # endif
  90. }
  91. void transport_master_init(void) { i2c_init(); }
  92. void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); }
  93. #else // USE_SERIAL
  94. # include "serial.h"
  95. typedef struct __attribute__ ((__packed__)) {
  96. # ifdef ENCODER_ENABLE
  97. uint8_t encoder_state[NUMBER_OF_ENCODERS];
  98. # endif
  99. // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack
  100. matrix_row_t smatrix[ROWS_PER_HAND];
  101. } Serial_s2m_buffer_t;
  102. typedef struct __attribute__ ((__packed__)) {
  103. # ifdef BACKLIGHT_ENABLE
  104. uint8_t backlight_level;
  105. # endif
  106. # if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
  107. rgblight_config_t rgblight_config; // not yet use
  108. //
  109. // When MCUs on both sides drive their respective RGB LED chains,
  110. // it is necessary to synchronize, so it is necessary to communicate RGB
  111. // information. In that case, define RGBLED_SPLIT with info on the number
  112. // of LEDs on each half.
  113. //
  114. // Otherwise, if the master side MCU drives both sides RGB LED chains,
  115. // there is no need to communicate.
  116. # endif
  117. } Serial_m2s_buffer_t;
  118. volatile Serial_s2m_buffer_t serial_s2m_buffer = {};
  119. volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
  120. uint8_t volatile status0 = 0;
  121. SSTD_t transactions[] = {
  122. {
  123. (uint8_t *)&status0,
  124. sizeof(serial_m2s_buffer),
  125. (uint8_t *)&serial_m2s_buffer,
  126. sizeof(serial_s2m_buffer),
  127. (uint8_t *)&serial_s2m_buffer,
  128. },
  129. };
  130. void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
  131. void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
  132. bool transport_master(matrix_row_t matrix[]) {
  133. if (soft_serial_transaction()) {
  134. return false;
  135. }
  136. // TODO: if MATRIX_COLS > 8 change to unpack()
  137. for (int i = 0; i < ROWS_PER_HAND; ++i) {
  138. matrix[i] = serial_s2m_buffer.smatrix[i];
  139. }
  140. # ifdef BACKLIGHT_ENABLE
  141. // Write backlight level for slave to read
  142. serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0;
  143. # endif
  144. # if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
  145. static rgblight_config_t prev_rgb = {~0};
  146. uint32_t rgb = rgblight_read_dword();
  147. if (rgb != prev_rgb.raw) {
  148. serial_m2s_buffer.rgblight_config.raw = rgb;
  149. prev_rgb.raw = rgb;
  150. }
  151. # endif
  152. # ifdef ENCODER_ENABLE
  153. encoder_update_raw((uint8_t*)&serial_s2m_buffer.encoder_state);
  154. # endif
  155. return true;
  156. }
  157. void transport_slave(matrix_row_t matrix[]) {
  158. // TODO: if MATRIX_COLS > 8 change to pack()
  159. for (int i = 0; i < ROWS_PER_HAND; ++i) {
  160. serial_s2m_buffer.smatrix[i] = matrix[i];
  161. }
  162. # ifdef BACKLIGHT_ENABLE
  163. backlight_set(serial_m2s_buffer.backlight_level);
  164. # endif
  165. # if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
  166. // Update RGB config with the new data
  167. rgblight_update_dword(serial_m2s_buffer.rgblight_config.raw);
  168. # endif
  169. # ifdef ENCODER_ENABLE
  170. encoder_state_raw((uint8_t*)&serial_s2m_buffer.encoder_state);
  171. # endif
  172. }
  173. #endif