]> git.donarmstrong.com Git - qmk_firmware.git/blob - quantum/split_common/transport.c
Next set of split_common changes (#4974)
[qmk_firmware.git] / quantum / split_common / transport.c
1
2 #include "config.h"
3 #include "matrix.h"
4 #include "quantum.h"
5
6 #define ROWS_PER_HAND (MATRIX_ROWS / 2)
7
8 #ifdef RGBLIGHT_ENABLE
9 #  include "rgblight.h"
10 #endif
11
12 #ifdef BACKLIGHT_ENABLE
13 #  include "backlight.h"
14 extern backlight_config_t backlight_config;
15 #endif
16
17 #if defined(USE_I2C) || defined(EH)
18
19 #  include "i2c_master.h"
20 #  include "i2c_slave.h"
21
22 #  define I2C_BACKLIT_START 0x00
23 // Need 4 bytes for RGB (32 bit)
24 #  define I2C_RGB_START 0x01
25 #  define I2C_KEYMAP_START 0x05
26
27 #  define TIMEOUT 100
28
29 #  ifndef SLAVE_I2C_ADDRESS
30 #    define SLAVE_I2C_ADDRESS 0x32
31 #  endif
32
33 // Get rows from other half over i2c
34 bool transport_master(matrix_row_t matrix[]) {
35   i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_START, (void *)matrix, ROWS_PER_HAND * sizeof(matrix_row_t), TIMEOUT);
36
37   // write backlight info
38 #  ifdef BACKLIGHT_ENABLE
39   static uint8_t prev_level = ~0;
40   uint8_t        level      = get_backlight_level();
41   if (level != prev_level) {
42     i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIT_START, (void *)&level, sizeof(level), TIMEOUT);
43     prev_level = level;
44   }
45 #  endif
46
47 #  ifdef RGBLIGHT_ENABLE
48   static uint32_t prev_rgb = ~0;
49   uint32_t        rgb      = eeconfig_read_rgblight();
50   if (rgb != prev_rgb) {
51     i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START, (void *)&rgb, sizeof(rgb), TIMEOUT);
52     prev_rgb = rgb;
53   }
54 #  endif
55
56   return true;
57 }
58
59 void transport_slave(matrix_row_t matrix[]) {
60   for (int i = 0; i < ROWS_PER_HAND * sizeof(matrix_row_t); ++i) {
61     i2c_slave_reg[I2C_KEYMAP_START + i] = matrix[i];
62   }
63
64 // Read Backlight Info
65 #  ifdef BACKLIGHT_ENABLE
66   backlight_set(i2c_slave_reg[I2C_BACKLIT_START]);
67 #  endif
68
69 #  ifdef RGBLIGHT_ENABLE
70   uint32_t rgb = *(uint32_t *)(i2c_slave_reg + I2C_RGB_START);
71   // Update the RGB with the new data
72   rgblight_update_dword(rgb);
73 #  endif
74 }
75
76 void transport_master_init(void) { i2c_init(); }
77
78 void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); }
79
80 #else  // USE_SERIAL
81
82 #  include "serial.h"
83
84 typedef struct _Serial_s2m_buffer_t {
85   // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack
86   matrix_row_t smatrix[ROWS_PER_HAND];
87 } Serial_s2m_buffer_t;
88
89 typedef struct _Serial_m2s_buffer_t {
90 #  ifdef BACKLIGHT_ENABLE
91   uint8_t           backlight_level;
92 #  endif
93 #  if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
94   rgblight_config_t rgblight_config;  // not yet use
95   //
96   // When MCUs on both sides drive their respective RGB LED chains,
97   // it is necessary to synchronize, so it is necessary to communicate RGB
98   // information. In that case, define the RGBLIGHT_SPLIT macro.
99   //
100   // Otherwise, if the master side MCU drives both sides RGB LED chains,
101   // there is no need to communicate.
102 #  endif
103 } Serial_m2s_buffer_t;
104
105 volatile Serial_s2m_buffer_t serial_s2m_buffer = {};
106 volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
107 uint8_t volatile status0                       = 0;
108
109 SSTD_t transactions[] = {
110     {
111         (uint8_t *)&status0,
112         sizeof(serial_m2s_buffer),
113         (uint8_t *)&serial_m2s_buffer,
114         sizeof(serial_s2m_buffer),
115         (uint8_t *)&serial_s2m_buffer,
116     },
117 };
118
119 void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
120
121 void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
122
123 bool transport_master(matrix_row_t matrix[]) {
124   if (soft_serial_transaction()) {
125     return false;
126   }
127
128   // TODO:  if MATRIX_COLS > 8 change to unpack()
129   for (int i = 0; i < ROWS_PER_HAND; ++i) {
130     matrix[i] = serial_s2m_buffer.smatrix[i];
131   }
132
133 #  if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
134   // Code to send RGB over serial goes here (not implemented yet)
135 #  endif
136
137 #  ifdef BACKLIGHT_ENABLE
138   // Write backlight level for slave to read
139   serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0;
140 #  endif
141
142   return true;
143 }
144
145 void transport_slave(matrix_row_t matrix[]) {
146   // TODO: if MATRIX_COLS > 8 change to pack()
147   for (int i = 0; i < ROWS_PER_HAND; ++i) {
148     serial_s2m_buffer.smatrix[i] = matrix[i];
149   }
150 #  ifdef BACKLIGHT_ENABLE
151   backlight_set(serial_m2s_buffer.backlight_level);
152 #  endif
153 #  if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
154 // Add serial implementation for RGB here
155 #  endif
156 }
157
158 #endif