diff options
-rw-r--r-- | keyboards/helix/rev1/keymaps/OLED_sample/serial_config.h | 2 | ||||
-rw-r--r-- | keyboards/helix/rev1/rules.mk | 4 | ||||
-rw-r--r-- | keyboards/helix/rev1/serial_config.h | 2 | ||||
-rw-r--r-- | keyboards/helix/rev2/keymaps/default/config.h | 3 | ||||
-rw-r--r-- | keyboards/helix/rev2/keymaps/edvorakjp/config.h | 3 | ||||
-rw-r--r-- | keyboards/helix/rev2/keymaps/five_rows/config.h | 6 | ||||
-rw-r--r-- | keyboards/helix/rev2/keymaps/five_rows_jis/config.h | 3 | ||||
-rw-r--r-- | keyboards/helix/rev2/keymaps/froggy/config.h | 3 | ||||
-rw-r--r-- | keyboards/helix/rev2/keymaps/led_test/config.h | 3 | ||||
-rw-r--r-- | keyboards/helix/rev2/matrix.c | 58 | ||||
-rw-r--r-- | keyboards/helix/rev2/rules.mk | 7 | ||||
-rw-r--r-- | keyboards/helix/rev2/serial_config.h | 3 | ||||
-rw-r--r-- | keyboards/helix/rev2/serial_config_simpleapi.h | 8 | ||||
-rw-r--r-- | keyboards/helix/rev2/split_scomm.c | 73 | ||||
-rw-r--r-- | keyboards/helix/rev2/split_scomm.h | 24 | ||||
-rw-r--r-- | keyboards/helix/rev2/split_util.c | 2 | ||||
-rw-r--r-- | keyboards/helix/rules.mk | 9 | ||||
-rw-r--r-- | keyboards/helix/serial.c | 411 | ||||
-rw-r--r-- | keyboards/helix/serial.h | 63 |
19 files changed, 514 insertions, 173 deletions
diff --git a/keyboards/helix/rev1/keymaps/OLED_sample/serial_config.h b/keyboards/helix/rev1/keymaps/OLED_sample/serial_config.h index be2e7cb8b..b991b874b 100644 --- a/keyboards/helix/rev1/keymaps/OLED_sample/serial_config.h +++ b/keyboards/helix/rev1/keymaps/OLED_sample/serial_config.h | |||
@@ -9,7 +9,7 @@ | |||
9 | #define SERIAL_PIN_INTERRUPT INT2_vect | 9 | #define SERIAL_PIN_INTERRUPT INT2_vect |
10 | 10 | ||
11 | #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 | 11 | #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 |
12 | #define SERIAL_MASTER_BUFFER_LENGTH 1 | 12 | #define SERIAL_MASTER_BUFFER_LENGTH 0 |
13 | 13 | ||
14 | //// #error rev1/keymaps/OLED_sample serial config | 14 | //// #error rev1/keymaps/OLED_sample serial config |
15 | 15 | ||
diff --git a/keyboards/helix/rev1/rules.mk b/keyboards/helix/rev1/rules.mk index daba80eae..13834f5da 100644 --- a/keyboards/helix/rev1/rules.mk +++ b/keyboards/helix/rev1/rules.mk | |||
@@ -1,4 +1,4 @@ | |||
1 | SRC += rev1/matrix.c \ | 1 | SRC += rev1/matrix.c |
2 | rev1/split_util.c | 2 | SRC += rev1/split_util.c |
3 | 3 | ||
4 | BACKLIGHT_ENABLE = no | 4 | BACKLIGHT_ENABLE = no |
diff --git a/keyboards/helix/rev1/serial_config.h b/keyboards/helix/rev1/serial_config.h index 2b668a6af..51c6aa375 100644 --- a/keyboards/helix/rev1/serial_config.h +++ b/keyboards/helix/rev1/serial_config.h | |||
@@ -9,7 +9,7 @@ | |||
9 | #define SERIAL_PIN_INTERRUPT INT0_vect | 9 | #define SERIAL_PIN_INTERRUPT INT0_vect |
10 | 10 | ||
11 | #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 | 11 | #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 |
12 | #define SERIAL_MASTER_BUFFER_LENGTH 1 | 12 | #define SERIAL_MASTER_BUFFER_LENGTH 0 |
13 | 13 | ||
14 | /// #error rev1 serial config | 14 | /// #error rev1 serial config |
15 | 15 | ||
diff --git a/keyboards/helix/rev2/keymaps/default/config.h b/keyboards/helix/rev2/keymaps/default/config.h index 6da6849a1..185e67838 100644 --- a/keyboards/helix/rev2/keymaps/default/config.h +++ b/keyboards/helix/rev2/keymaps/default/config.h | |||
@@ -21,6 +21,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
21 | #ifndef CONFIG_USER_H | 21 | #ifndef CONFIG_USER_H |
22 | #define CONFIG_USER_H | 22 | #define CONFIG_USER_H |
23 | 23 | ||
24 | // if you need more program area, try uncomment follow line | ||
25 | //#include "serial_config_simpleapi.h" | ||
26 | |||
24 | // place overrides here | 27 | // place overrides here |
25 | 28 | ||
26 | #endif /* CONFIG_USER_H */ | 29 | #endif /* CONFIG_USER_H */ |
diff --git a/keyboards/helix/rev2/keymaps/edvorakjp/config.h b/keyboards/helix/rev2/keymaps/edvorakjp/config.h index a7a5f8360..ead31605b 100644 --- a/keyboards/helix/rev2/keymaps/edvorakjp/config.h +++ b/keyboards/helix/rev2/keymaps/edvorakjp/config.h | |||
@@ -1,6 +1,9 @@ | |||
1 | #ifndef CONFIG_USER_H | 1 | #ifndef CONFIG_USER_H |
2 | #define CONFIG_USER_H | 2 | #define CONFIG_USER_H |
3 | 3 | ||
4 | // if you need more program area, try uncomment follow line | ||
5 | //#include "serial_config_simpleapi.h" | ||
6 | |||
4 | #undef TAPPING_FORCE_HOLD | 7 | #undef TAPPING_FORCE_HOLD |
5 | #undef TAPPING_TERM | 8 | #undef TAPPING_TERM |
6 | #define TAPPING_TERM 120 | 9 | #define TAPPING_TERM 120 |
diff --git a/keyboards/helix/rev2/keymaps/five_rows/config.h b/keyboards/helix/rev2/keymaps/five_rows/config.h index 6da6849a1..837219460 100644 --- a/keyboards/helix/rev2/keymaps/five_rows/config.h +++ b/keyboards/helix/rev2/keymaps/five_rows/config.h | |||
@@ -21,6 +21,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
21 | #ifndef CONFIG_USER_H | 21 | #ifndef CONFIG_USER_H |
22 | #define CONFIG_USER_H | 22 | #define CONFIG_USER_H |
23 | 23 | ||
24 | // if you need more program area, try uncomment follow line | ||
25 | //#include "serial_config_simpleapi.h" | ||
26 | |||
27 | #undef TAPPING_TERM | ||
28 | #define TAPPING_TERM 140 | ||
29 | |||
24 | // place overrides here | 30 | // place overrides here |
25 | 31 | ||
26 | #endif /* CONFIG_USER_H */ | 32 | #endif /* CONFIG_USER_H */ |
diff --git a/keyboards/helix/rev2/keymaps/five_rows_jis/config.h b/keyboards/helix/rev2/keymaps/five_rows_jis/config.h index 34650b99a..c380b7db4 100644 --- a/keyboards/helix/rev2/keymaps/five_rows_jis/config.h +++ b/keyboards/helix/rev2/keymaps/five_rows_jis/config.h | |||
@@ -23,6 +23,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
23 | 23 | ||
24 | // place overrides here | 24 | // place overrides here |
25 | 25 | ||
26 | // if you need more program area, try uncomment follow line | ||
27 | //#include "serial_config_simpleapi.h" | ||
28 | |||
26 | #ifdef MOUSEKEY_ENABLE | 29 | #ifdef MOUSEKEY_ENABLE |
27 | #undef MOUSEKEY_INTERVAL | 30 | #undef MOUSEKEY_INTERVAL |
28 | #define MOUSEKEY_INTERVAL 0 | 31 | #define MOUSEKEY_INTERVAL 0 |
diff --git a/keyboards/helix/rev2/keymaps/froggy/config.h b/keyboards/helix/rev2/keymaps/froggy/config.h index df72aef12..dad248303 100644 --- a/keyboards/helix/rev2/keymaps/froggy/config.h +++ b/keyboards/helix/rev2/keymaps/froggy/config.h | |||
@@ -21,6 +21,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
21 | #ifndef CONFIG_USER_H | 21 | #ifndef CONFIG_USER_H |
22 | #define CONFIG_USER_H | 22 | #define CONFIG_USER_H |
23 | 23 | ||
24 | // if you need more program area, try uncomment follow line | ||
25 | //#include "serial_config_simpleapi.h" | ||
26 | |||
24 | #undef TAPPING_TERM | 27 | #undef TAPPING_TERM |
25 | #define TAPPING_TERM 200 | 28 | #define TAPPING_TERM 200 |
26 | #define ONESHOT_TAP_TOGGLE 5 /* Tapping this number of times holds the key until tapped this number of times again. */ | 29 | #define ONESHOT_TAP_TOGGLE 5 /* Tapping this number of times holds the key until tapped this number of times again. */ |
diff --git a/keyboards/helix/rev2/keymaps/led_test/config.h b/keyboards/helix/rev2/keymaps/led_test/config.h index 6da6849a1..043825452 100644 --- a/keyboards/helix/rev2/keymaps/led_test/config.h +++ b/keyboards/helix/rev2/keymaps/led_test/config.h | |||
@@ -21,6 +21,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
21 | #ifndef CONFIG_USER_H | 21 | #ifndef CONFIG_USER_H |
22 | #define CONFIG_USER_H | 22 | #define CONFIG_USER_H |
23 | 23 | ||
24 | // if you need more program area, try uncomment follow line | ||
25 | #include "serial_config_simpleapi.h" | ||
26 | |||
24 | // place overrides here | 27 | // place overrides here |
25 | 28 | ||
26 | #endif /* CONFIG_USER_H */ | 29 | #endif /* CONFIG_USER_H */ |
diff --git a/keyboards/helix/rev2/matrix.c b/keyboards/helix/rev2/matrix.c index 8a1ce3af1..322959dbb 100644 --- a/keyboards/helix/rev2/matrix.c +++ b/keyboards/helix/rev2/matrix.c | |||
@@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
20 | */ | 20 | */ |
21 | #include <stdint.h> | 21 | #include <stdint.h> |
22 | #include <stdbool.h> | 22 | #include <stdbool.h> |
23 | #include <string.h> | ||
23 | #include <avr/io.h> | 24 | #include <avr/io.h> |
24 | #include <avr/wdt.h> | 25 | #include <avr/wdt.h> |
25 | #include <avr/interrupt.h> | 26 | #include <avr/interrupt.h> |
@@ -34,7 +35,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
34 | #ifdef USE_MATRIX_I2C | 35 | #ifdef USE_MATRIX_I2C |
35 | # include "i2c.h" | 36 | # include "i2c.h" |
36 | #else // USE_SERIAL | 37 | #else // USE_SERIAL |
37 | # include "serial.h" | 38 | # include "split_scomm.h" |
38 | #endif | 39 | #endif |
39 | 40 | ||
40 | #ifndef DEBOUNCE | 41 | #ifndef DEBOUNCE |
@@ -102,6 +103,8 @@ void matrix_init(void) | |||
102 | init_cols(); | 103 | init_cols(); |
103 | 104 | ||
104 | TX_RX_LED_INIT; | 105 | TX_RX_LED_INIT; |
106 | TXLED0; | ||
107 | RXLED0; | ||
105 | 108 | ||
106 | // initialize matrix state: all keys off | 109 | // initialize matrix state: all keys off |
107 | for (uint8_t i=0; i < MATRIX_ROWS; i++) { | 110 | for (uint8_t i=0; i < MATRIX_ROWS; i++) { |
@@ -178,17 +181,20 @@ i2c_error: // the cable is disconnceted, or something else went wrong | |||
178 | 181 | ||
179 | #else // USE_SERIAL | 182 | #else // USE_SERIAL |
180 | 183 | ||
181 | int serial_transaction(void) { | 184 | int serial_transaction(int master_changed) { |
182 | int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; | 185 | int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; |
186 | #ifdef SERIAL_USE_MULTI_TRANSACTION | ||
187 | int ret=serial_update_buffers(master_changed); | ||
188 | #else | ||
183 | int ret=serial_update_buffers(); | 189 | int ret=serial_update_buffers(); |
190 | #endif | ||
184 | if (ret ) { | 191 | if (ret ) { |
185 | if(ret==2)RXLED1; | 192 | if(ret==2) RXLED1; |
186 | return 1; | 193 | return 1; |
187 | } | 194 | } |
188 | RXLED0; | 195 | RXLED0; |
189 | for (int i = 0; i < ROWS_PER_HAND; ++i) { | 196 | memcpy(&matrix[slaveOffset], |
190 | matrix[slaveOffset+i] = serial_slave_buffer[i]; | 197 | (void *)serial_slave_buffer, sizeof(serial_slave_buffer)); |
191 | } | ||
192 | return 0; | 198 | return 0; |
193 | } | 199 | } |
194 | #endif | 200 | #endif |
@@ -199,19 +205,9 @@ uint8_t matrix_scan(void) | |||
199 | matrix_master_scan(); | 205 | matrix_master_scan(); |
200 | }else{ | 206 | }else{ |
201 | matrix_slave_scan(); | 207 | matrix_slave_scan(); |
202 | 208 | int offset = (isLeftHand) ? ROWS_PER_HAND : 0; | |
203 | // if(serial_slave_DATA_CORRUPT()){ | 209 | memcpy(&matrix[offset], |
204 | // TXLED0; | 210 | (void *)serial_master_buffer, sizeof(serial_master_buffer)); |
205 | int offset = (isLeftHand) ? ROWS_PER_HAND : 0; | ||
206 | |||
207 | for (int i = 0; i < ROWS_PER_HAND; ++i) { | ||
208 | matrix[offset+i] = serial_master_buffer[i]; | ||
209 | } | ||
210 | |||
211 | // }else{ | ||
212 | // TXLED1; | ||
213 | // } | ||
214 | |||
215 | matrix_scan_quantum(); | 211 | matrix_scan_quantum(); |
216 | } | 212 | } |
217 | return 1; | 213 | return 1; |
@@ -221,6 +217,7 @@ uint8_t matrix_scan(void) | |||
221 | uint8_t matrix_master_scan(void) { | 217 | uint8_t matrix_master_scan(void) { |
222 | 218 | ||
223 | int ret = _matrix_scan(); | 219 | int ret = _matrix_scan(); |
220 | int mchanged = 1; | ||
224 | 221 | ||
225 | #ifndef KEYBOARD_helix_rev1 | 222 | #ifndef KEYBOARD_helix_rev1 |
226 | int offset = (isLeftHand) ? 0 : ROWS_PER_HAND; | 223 | int offset = (isLeftHand) ? 0 : ROWS_PER_HAND; |
@@ -231,16 +228,19 @@ uint8_t matrix_master_scan(void) { | |||
231 | // i2c_slave_buffer[i] = matrix[offset+i]; | 228 | // i2c_slave_buffer[i] = matrix[offset+i]; |
232 | // } | 229 | // } |
233 | #else // USE_SERIAL | 230 | #else // USE_SERIAL |
234 | for (int i = 0; i < ROWS_PER_HAND; ++i) { | 231 | #ifdef SERIAL_USE_MULTI_TRANSACTION |
235 | serial_master_buffer[i] = matrix[offset+i]; | 232 | mchanged = memcmp((void *)serial_master_buffer, |
236 | } | 233 | &matrix[offset], sizeof(serial_master_buffer)); |
234 | #endif | ||
235 | memcpy((void *)serial_master_buffer, | ||
236 | &matrix[offset], sizeof(serial_master_buffer)); | ||
237 | #endif | 237 | #endif |
238 | #endif | 238 | #endif |
239 | 239 | ||
240 | #ifdef USE_MATRIX_I2C | 240 | #ifdef USE_MATRIX_I2C |
241 | if( i2c_transaction() ) { | 241 | if( i2c_transaction() ) { |
242 | #else // USE_SERIAL | 242 | #else // USE_SERIAL |
243 | if( serial_transaction() ) { | 243 | if( serial_transaction(mchanged) ) { |
244 | #endif | 244 | #endif |
245 | // turn on the indicator led when halves are disconnected | 245 | // turn on the indicator led when halves are disconnected |
246 | TXLED1; | 246 | TXLED1; |
@@ -274,9 +274,19 @@ void matrix_slave_scan(void) { | |||
274 | i2c_slave_buffer[i] = matrix[offset+i]; | 274 | i2c_slave_buffer[i] = matrix[offset+i]; |
275 | } | 275 | } |
276 | #else // USE_SERIAL | 276 | #else // USE_SERIAL |
277 | #ifdef SERIAL_USE_MULTI_TRANSACTION | ||
278 | int change = 0; | ||
279 | #endif | ||
277 | for (int i = 0; i < ROWS_PER_HAND; ++i) { | 280 | for (int i = 0; i < ROWS_PER_HAND; ++i) { |
281 | #ifdef SERIAL_USE_MULTI_TRANSACTION | ||
282 | if( serial_slave_buffer[i] != matrix[offset+i] ) | ||
283 | change = 1; | ||
284 | #endif | ||
278 | serial_slave_buffer[i] = matrix[offset+i]; | 285 | serial_slave_buffer[i] = matrix[offset+i]; |
279 | } | 286 | } |
287 | #ifdef SERIAL_USE_MULTI_TRANSACTION | ||
288 | slave_buffer_change_count += change; | ||
289 | #endif | ||
280 | #endif | 290 | #endif |
281 | } | 291 | } |
282 | 292 | ||
diff --git a/keyboards/helix/rev2/rules.mk b/keyboards/helix/rev2/rules.mk index 6ab01f44b..4ea623c43 100644 --- a/keyboards/helix/rev2/rules.mk +++ b/keyboards/helix/rev2/rules.mk | |||
@@ -1,3 +1,4 @@ | |||
1 | SRC += rev2/matrix.c \ | 1 | SRC += rev2/matrix.c |
2 | rev2/split_util.c \ | 2 | SRC += rev2/split_util.c |
3 | ws2812.c | 3 | SRC += rev2/split_scomm.c |
4 | SRC += ws2812.c | ||
diff --git a/keyboards/helix/rev2/serial_config.h b/keyboards/helix/rev2/serial_config.h index 82c6e4e83..8d7e62837 100644 --- a/keyboards/helix/rev2/serial_config.h +++ b/keyboards/helix/rev2/serial_config.h | |||
@@ -8,8 +8,7 @@ | |||
8 | #define SERIAL_PIN_MASK _BV(PD2) | 8 | #define SERIAL_PIN_MASK _BV(PD2) |
9 | #define SERIAL_PIN_INTERRUPT INT2_vect | 9 | #define SERIAL_PIN_INTERRUPT INT2_vect |
10 | 10 | ||
11 | #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 | 11 | #define SERIAL_USE_MULTI_TRANSACTION |
12 | #define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2 | ||
13 | 12 | ||
14 | //// #error rev2 serial config | 13 | //// #error rev2 serial config |
15 | 14 | ||
diff --git a/keyboards/helix/rev2/serial_config_simpleapi.h b/keyboards/helix/rev2/serial_config_simpleapi.h new file mode 100644 index 000000000..e2d22a41e --- /dev/null +++ b/keyboards/helix/rev2/serial_config_simpleapi.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef SERIAL_CONFIG_SIMPLEAPI_H | ||
2 | #define SERIAL_CONFIG_SIMPLEAPI_H | ||
3 | |||
4 | #undef SERIAL_USE_MULTI_TRANSACTION | ||
5 | #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 | ||
6 | #define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2 | ||
7 | |||
8 | #endif // SERIAL_CONFIG_SIMPLEAPI_H | ||
diff --git a/keyboards/helix/rev2/split_scomm.c b/keyboards/helix/rev2/split_scomm.c new file mode 100644 index 000000000..9719eb22e --- /dev/null +++ b/keyboards/helix/rev2/split_scomm.c | |||
@@ -0,0 +1,73 @@ | |||
1 | #ifdef USE_SERIAL | ||
2 | #ifdef SERIAL_USE_MULTI_TRANSACTION | ||
3 | /* --- USE flexible API (using multi-type transaction function) --- */ | ||
4 | |||
5 | #include <stdbool.h> | ||
6 | #include <stdint.h> | ||
7 | #include <stddef.h> | ||
8 | #include <split_scomm.h> | ||
9 | #include "serial.h" | ||
10 | #ifdef SERIAL_DEBUG_MODE | ||
11 | #include <avr/io.h> | ||
12 | #endif | ||
13 | |||
14 | uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; | ||
15 | uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; | ||
16 | uint8_t volatile status_com = 0; | ||
17 | uint8_t volatile status1 = 0; | ||
18 | uint8_t slave_buffer_change_count = 0; | ||
19 | uint8_t s_change_old = 0xff; | ||
20 | |||
21 | SSTD_t transactions[] = { | ||
22 | #define GET_SLAVE_STATUS 0 | ||
23 | /* master buffer not changed, only recive slave_buffer_change_count */ | ||
24 | { (uint8_t *)&status_com, | ||
25 | 0, NULL, | ||
26 | sizeof(slave_buffer_change_count), &slave_buffer_change_count, | ||
27 | }, | ||
28 | #define PUT_MASTER_GET_SLAVE_STATUS 1 | ||
29 | /* master buffer changed need send, and recive slave_buffer_change_count */ | ||
30 | { (uint8_t *)&status_com, | ||
31 | sizeof(serial_master_buffer), (uint8_t *)serial_master_buffer, | ||
32 | sizeof(slave_buffer_change_count), &slave_buffer_change_count, | ||
33 | }, | ||
34 | #define GET_SLAVE_BUFFER 2 | ||
35 | /* recive serial_slave_buffer */ | ||
36 | { (uint8_t *)&status1, | ||
37 | 0, NULL, | ||
38 | sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer | ||
39 | } | ||
40 | }; | ||
41 | |||
42 | void serial_master_init(void) | ||
43 | { | ||
44 | soft_serial_initiator_init(transactions); | ||
45 | } | ||
46 | |||
47 | void serial_slave_init(void) | ||
48 | { | ||
49 | soft_serial_target_init(transactions); | ||
50 | } | ||
51 | |||
52 | // 0 => no error | ||
53 | // 1 => slave did not respond | ||
54 | // 2 => checksum error | ||
55 | int serial_update_buffers(int master_update) | ||
56 | { | ||
57 | int status; | ||
58 | static int need_retry = 0; | ||
59 | if( s_change_old != slave_buffer_change_count ) { | ||
60 | status = soft_serial_transaction(GET_SLAVE_BUFFER); | ||
61 | if( status == TRANSACTION_END ) | ||
62 | s_change_old = slave_buffer_change_count; | ||
63 | } | ||
64 | if( !master_update && !need_retry) | ||
65 | status = soft_serial_transaction(GET_SLAVE_STATUS); | ||
66 | else | ||
67 | status = soft_serial_transaction(PUT_MASTER_GET_SLAVE_STATUS); | ||
68 | need_retry = ( status == TRANSACTION_END ) ? 0 : 1; | ||
69 | return status; | ||
70 | } | ||
71 | |||
72 | #endif // SERIAL_USE_MULTI_TRANSACTION | ||
73 | #endif /* USE_SERIAL */ | ||
diff --git a/keyboards/helix/rev2/split_scomm.h b/keyboards/helix/rev2/split_scomm.h new file mode 100644 index 000000000..873d8939d --- /dev/null +++ b/keyboards/helix/rev2/split_scomm.h | |||
@@ -0,0 +1,24 @@ | |||
1 | #ifndef SPLIT_COMM_H | ||
2 | #define SPLIT_COMM_H | ||
3 | |||
4 | #ifndef SERIAL_USE_MULTI_TRANSACTION | ||
5 | /* --- USE Simple API (OLD API, compatible with let's split serial.c) --- */ | ||
6 | #include "serial.h" | ||
7 | |||
8 | #else | ||
9 | /* --- USE flexible API (using multi-type transaction function) --- */ | ||
10 | // Buffers for master - slave communication | ||
11 | #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 | ||
12 | #define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2 | ||
13 | |||
14 | extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH]; | ||
15 | extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH]; | ||
16 | extern uint8_t slave_buffer_change_count; | ||
17 | |||
18 | void serial_master_init(void); | ||
19 | void serial_slave_init(void); | ||
20 | int serial_update_buffers(int master_changed); | ||
21 | |||
22 | #endif | ||
23 | |||
24 | #endif /* SPLIT_COMM_H */ | ||
diff --git a/keyboards/helix/rev2/split_util.c b/keyboards/helix/rev2/split_util.c index beb39fa00..e1ff8b437 100644 --- a/keyboards/helix/rev2/split_util.c +++ b/keyboards/helix/rev2/split_util.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #ifdef USE_MATRIX_I2C | 11 | #ifdef USE_MATRIX_I2C |
12 | # include "i2c.h" | 12 | # include "i2c.h" |
13 | #else | 13 | #else |
14 | # include "serial.h" | 14 | # include "split_scomm.h" |
15 | #endif | 15 | #endif |
16 | 16 | ||
17 | volatile bool isLeftHand = true; | 17 | volatile bool isLeftHand = true; |
diff --git a/keyboards/helix/rules.mk b/keyboards/helix/rules.mk index c35f93fb0..e42f92cf8 100644 --- a/keyboards/helix/rules.mk +++ b/keyboards/helix/rules.mk | |||
@@ -1,6 +1,9 @@ | |||
1 | SRC += i2c.c \ | 1 | SRC += i2c.c |
2 | serial.c \ | 2 | SRC += serial.c |
3 | ssd1306.c | 3 | SRC += ssd1306.c |
4 | |||
5 | # if firmware size over limit, try this option | ||
6 | # CFLAGS += -flto | ||
4 | 7 | ||
5 | # MCU name | 8 | # MCU name |
6 | #MCU = at90usb1287 | 9 | #MCU = at90usb1287 |
diff --git a/keyboards/helix/serial.c b/keyboards/helix/serial.c index 591941587..11ceff0b3 100644 --- a/keyboards/helix/serial.c +++ b/keyboards/helix/serial.c | |||
@@ -9,40 +9,85 @@ | |||
9 | #include <avr/io.h> | 9 | #include <avr/io.h> |
10 | #include <avr/interrupt.h> | 10 | #include <avr/interrupt.h> |
11 | #include <util/delay.h> | 11 | #include <util/delay.h> |
12 | #include <stddef.h> | ||
12 | #include <stdbool.h> | 13 | #include <stdbool.h> |
13 | #include "serial.h" | 14 | #include "serial.h" |
15 | //#include <pro_micro.h> | ||
14 | 16 | ||
15 | #ifdef USE_SERIAL | 17 | #ifdef USE_SERIAL |
16 | 18 | ||
19 | #ifndef SERIAL_USE_MULTI_TRANSACTION | ||
20 | /* --- USE Simple API (OLD API, compatible with let's split serial.c) */ | ||
21 | #if SERIAL_SLAVE_BUFFER_LENGTH > 0 | ||
22 | uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; | ||
23 | #endif | ||
24 | #if SERIAL_MASTER_BUFFER_LENGTH > 0 | ||
25 | uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; | ||
26 | #endif | ||
27 | uint8_t volatile status0 = 0; | ||
28 | |||
29 | SSTD_t transactions[] = { | ||
30 | { (uint8_t *)&status0, | ||
31 | #if SERIAL_MASTER_BUFFER_LENGTH > 0 | ||
32 | sizeof(serial_master_buffer), (uint8_t *)serial_master_buffer, | ||
33 | #else | ||
34 | 0, (uint8_t *)NULL, | ||
35 | #endif | ||
36 | #if SERIAL_SLAVE_BUFFER_LENGTH > 0 | ||
37 | sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer | ||
38 | #else | ||
39 | 0, (uint8_t *)NULL, | ||
40 | #endif | ||
41 | } | ||
42 | }; | ||
43 | |||
44 | void serial_master_init(void) | ||
45 | { soft_serial_initiator_init(transactions); } | ||
46 | |||
47 | void serial_slave_init(void) | ||
48 | { soft_serial_target_init(transactions); } | ||
49 | |||
50 | // 0 => no error | ||
51 | // 1 => slave did not respond | ||
52 | // 2 => checksum error | ||
53 | int serial_update_buffers() | ||
54 | { return soft_serial_transaction(); } | ||
55 | |||
56 | #endif // Simple API (OLD API, compatible with let's split serial.c) | ||
57 | |||
58 | #define ALWAYS_INLINE __attribute__((always_inline)) | ||
59 | #define NO_INLINE __attribute__((noinline)) | ||
17 | #define _delay_sub_us(x) __builtin_avr_delay_cycles(x) | 60 | #define _delay_sub_us(x) __builtin_avr_delay_cycles(x) |
18 | 61 | ||
19 | // Serial pulse period in microseconds. | 62 | // Serial pulse period in microseconds. |
63 | #define TID_SEND_ADJUST 14 | ||
64 | |||
20 | #define SELECT_SERIAL_SPEED 1 | 65 | #define SELECT_SERIAL_SPEED 1 |
21 | #if SELECT_SERIAL_SPEED == 0 | 66 | #if SELECT_SERIAL_SPEED == 0 |
22 | // Very High speed | 67 | // Very High speed |
23 | #define SERIAL_DELAY 4 // micro sec | 68 | #define SERIAL_DELAY 4 // micro sec |
24 | #define READ_WRITE_START_ADJUST 30 // cycles | 69 | #define READ_WRITE_START_ADJUST 33 // cycles |
25 | #define READ_WRITE_WIDTH_ADJUST 10 // cycles | 70 | #define READ_WRITE_WIDTH_ADJUST 3 // cycles |
26 | #elif SELECT_SERIAL_SPEED == 1 | 71 | #elif SELECT_SERIAL_SPEED == 1 |
27 | // High speed | 72 | // High speed |
28 | #define SERIAL_DELAY 6 // micro sec | 73 | #define SERIAL_DELAY 6 // micro sec |
29 | #define READ_WRITE_START_ADJUST 23 // cycles | 74 | #define READ_WRITE_START_ADJUST 30 // cycles |
30 | #define READ_WRITE_WIDTH_ADJUST 10 // cycles | 75 | #define READ_WRITE_WIDTH_ADJUST 3 // cycles |
31 | #elif SELECT_SERIAL_SPEED == 2 | 76 | #elif SELECT_SERIAL_SPEED == 2 |
32 | // Middle speed | 77 | // Middle speed |
33 | #define SERIAL_DELAY 12 // micro sec | 78 | #define SERIAL_DELAY 12 // micro sec |
34 | #define READ_WRITE_START_ADJUST 25 // cycles | 79 | #define READ_WRITE_START_ADJUST 30 // cycles |
35 | #define READ_WRITE_WIDTH_ADJUST 10 // cycles | 80 | #define READ_WRITE_WIDTH_ADJUST 3 // cycles |
36 | #elif SELECT_SERIAL_SPEED == 3 | 81 | #elif SELECT_SERIAL_SPEED == 3 |
37 | // Low speed | 82 | // Low speed |
38 | #define SERIAL_DELAY 24 // micro sec | 83 | #define SERIAL_DELAY 24 // micro sec |
39 | #define READ_WRITE_START_ADJUST 25 // cycles | 84 | #define READ_WRITE_START_ADJUST 30 // cycles |
40 | #define READ_WRITE_WIDTH_ADJUST 10 // cycles | 85 | #define READ_WRITE_WIDTH_ADJUST 3 // cycles |
41 | #elif SELECT_SERIAL_SPEED == 4 | 86 | #elif SELECT_SERIAL_SPEED == 4 |
42 | // Very Low speed | 87 | // Very Low speed |
43 | #define SERIAL_DELAY 50 // micro sec | 88 | #define SERIAL_DELAY 50 // micro sec |
44 | #define READ_WRITE_START_ADJUST 25 // cycles | 89 | #define READ_WRITE_START_ADJUST 30 // cycles |
45 | #define READ_WRITE_WIDTH_ADJUST 10 // cycles | 90 | #define READ_WRITE_WIDTH_ADJUST 3 // cycles |
46 | #else | 91 | #else |
47 | #error Illegal Serial Speed | 92 | #error Illegal Serial Speed |
48 | #endif | 93 | #endif |
@@ -51,14 +96,15 @@ | |||
51 | #define SERIAL_DELAY_HALF1 (SERIAL_DELAY/2) | 96 | #define SERIAL_DELAY_HALF1 (SERIAL_DELAY/2) |
52 | #define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY/2) | 97 | #define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY/2) |
53 | 98 | ||
54 | #define SLAVE_INT_WIDTH 1 | 99 | #define SLAVE_INT_WIDTH_US 1 |
55 | #define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY | 100 | #ifndef SERIAL_USE_MULTI_TRANSACTION |
56 | 101 | #define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY | |
57 | uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; | 102 | #else |
58 | uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; | 103 | #define SLAVE_INT_ACK_WIDTH_UNIT 2 |
104 | #define SLAVE_INT_ACK_WIDTH 4 | ||
105 | #endif | ||
59 | 106 | ||
60 | #define SLAVE_DATA_CORRUPT (1<<0) | 107 | static SSTD_t *Transaction_table = NULL; |
61 | volatile uint8_t status = 0; | ||
62 | 108 | ||
63 | inline static | 109 | inline static |
64 | void serial_delay(void) { | 110 | void serial_delay(void) { |
@@ -75,12 +121,14 @@ void serial_delay_half2(void) { | |||
75 | _delay_us(SERIAL_DELAY_HALF2); | 121 | _delay_us(SERIAL_DELAY_HALF2); |
76 | } | 122 | } |
77 | 123 | ||
124 | inline static void serial_output(void) ALWAYS_INLINE; | ||
78 | inline static | 125 | inline static |
79 | void serial_output(void) { | 126 | void serial_output(void) { |
80 | SERIAL_PIN_DDR |= SERIAL_PIN_MASK; | 127 | SERIAL_PIN_DDR |= SERIAL_PIN_MASK; |
81 | } | 128 | } |
82 | 129 | ||
83 | // make the serial pin an input with pull-up resistor | 130 | // make the serial pin an input with pull-up resistor |
131 | inline static void serial_input_with_pullup(void) ALWAYS_INLINE; | ||
84 | inline static | 132 | inline static |
85 | void serial_input_with_pullup(void) { | 133 | void serial_input_with_pullup(void) { |
86 | SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK; | 134 | SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK; |
@@ -92,50 +140,58 @@ uint8_t serial_read_pin(void) { | |||
92 | return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK); | 140 | return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK); |
93 | } | 141 | } |
94 | 142 | ||
143 | inline static void serial_low(void) ALWAYS_INLINE; | ||
95 | inline static | 144 | inline static |
96 | void serial_low(void) { | 145 | void serial_low(void) { |
97 | SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK; | 146 | SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK; |
98 | } | 147 | } |
99 | 148 | ||
149 | inline static void serial_high(void) ALWAYS_INLINE; | ||
100 | inline static | 150 | inline static |
101 | void serial_high(void) { | 151 | void serial_high(void) { |
102 | SERIAL_PIN_PORT |= SERIAL_PIN_MASK; | 152 | SERIAL_PIN_PORT |= SERIAL_PIN_MASK; |
103 | } | 153 | } |
104 | 154 | ||
105 | void serial_master_init(void) { | 155 | void soft_serial_initiator_init(SSTD_t *sstd_table) |
106 | serial_output(); | 156 | { |
107 | serial_high(); | 157 | Transaction_table = sstd_table; |
158 | serial_output(); | ||
159 | serial_high(); | ||
108 | } | 160 | } |
109 | 161 | ||
110 | void serial_slave_init(void) { | 162 | void soft_serial_target_init(SSTD_t *sstd_table) |
111 | serial_input_with_pullup(); | 163 | { |
164 | Transaction_table = sstd_table; | ||
165 | serial_input_with_pullup(); | ||
112 | 166 | ||
113 | #if SERIAL_PIN_MASK == _BV(PD0) | 167 | #if SERIAL_PIN_MASK == _BV(PD0) |
114 | // Enable INT0 | 168 | // Enable INT0 |
115 | EIMSK |= _BV(INT0); | 169 | EIMSK |= _BV(INT0); |
116 | // Trigger on falling edge of INT0 | 170 | // Trigger on falling edge of INT0 |
117 | EICRA &= ~(_BV(ISC00) | _BV(ISC01)); | 171 | EICRA &= ~(_BV(ISC00) | _BV(ISC01)); |
118 | #elif SERIAL_PIN_MASK == _BV(PD2) | 172 | #elif SERIAL_PIN_MASK == _BV(PD2) |
119 | // Enable INT2 | 173 | // Enable INT2 |
120 | EIMSK |= _BV(INT2); | 174 | EIMSK |= _BV(INT2); |
121 | // Trigger on falling edge of INT2 | 175 | // Trigger on falling edge of INT2 |
122 | EICRA &= ~(_BV(ISC20) | _BV(ISC21)); | 176 | EICRA &= ~(_BV(ISC20) | _BV(ISC21)); |
123 | #else | 177 | #else |
124 | #error unknown SERIAL_PIN_MASK value | 178 | #error unknown SERIAL_PIN_MASK value |
125 | #endif | 179 | #endif |
126 | } | 180 | } |
127 | 181 | ||
128 | // Used by the sender to synchronize timing with the reciver. | 182 | // Used by the sender to synchronize timing with the reciver. |
183 | static void sync_recv(void) NO_INLINE; | ||
129 | static | 184 | static |
130 | void sync_recv(void) { | 185 | void sync_recv(void) { |
131 | for (int i = 0; i < SERIAL_DELAY*5 && serial_read_pin(); i++ ) { | 186 | for (uint8_t i = 0; i < SERIAL_DELAY*5 && serial_read_pin(); i++ ) { |
132 | } | 187 | } |
133 | // This shouldn't hang if the slave disconnects because the | 188 | // This shouldn't hang if the target disconnects because the |
134 | // serial line will float to high if the slave does disconnect. | 189 | // serial line will float to high if the target does disconnect. |
135 | while (!serial_read_pin()); | 190 | while (!serial_read_pin()); |
136 | } | 191 | } |
137 | 192 | ||
138 | // Used by the reciver to send a synchronization signal to the sender. | 193 | // Used by the reciver to send a synchronization signal to the sender. |
194 | static void sync_send(void)NO_INLINE; | ||
139 | static | 195 | static |
140 | void sync_send(void) { | 196 | void sync_send(void) { |
141 | serial_low(); | 197 | serial_low(); |
@@ -144,152 +200,245 @@ void sync_send(void) { | |||
144 | } | 200 | } |
145 | 201 | ||
146 | // Reads a byte from the serial line | 202 | // Reads a byte from the serial line |
147 | static | 203 | static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) NO_INLINE; |
148 | uint8_t serial_read_byte(void) { | 204 | static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) { |
149 | uint8_t byte = 0; | 205 | uint8_t byte, i, p, pb; |
206 | |||
150 | _delay_sub_us(READ_WRITE_START_ADJUST); | 207 | _delay_sub_us(READ_WRITE_START_ADJUST); |
151 | for ( uint8_t i = 0; i < 8; ++i) { | 208 | for( i = 0, byte = 0, p = 0; i < bit; i++ ) { |
152 | serial_delay_half1(); // read the middle of pulses | 209 | serial_delay_half1(); // read the middle of pulses |
153 | byte = (byte << 1) | serial_read_pin(); | 210 | if( serial_read_pin() ) { |
154 | _delay_sub_us(READ_WRITE_WIDTH_ADJUST); | 211 | byte = (byte << 1) | 1; p ^= 1; |
155 | serial_delay_half2(); | 212 | } else { |
213 | byte = (byte << 1) | 0; p ^= 0; | ||
214 | } | ||
215 | _delay_sub_us(READ_WRITE_WIDTH_ADJUST); | ||
216 | serial_delay_half2(); | ||
156 | } | 217 | } |
218 | /* recive parity bit */ | ||
219 | serial_delay_half1(); // read the middle of pulses | ||
220 | pb = serial_read_pin(); | ||
221 | _delay_sub_us(READ_WRITE_WIDTH_ADJUST); | ||
222 | serial_delay_half2(); | ||
223 | |||
224 | *pterrcount += (p != pb)? 1 : 0; | ||
225 | |||
157 | return byte; | 226 | return byte; |
158 | } | 227 | } |
159 | 228 | ||
160 | // Sends a byte with MSB ordering | 229 | // Sends a byte with MSB ordering |
161 | static | 230 | void serial_write_chunk(uint8_t data, uint8_t bit) NO_INLINE; |
162 | void serial_write_byte(uint8_t data) { | 231 | void serial_write_chunk(uint8_t data, uint8_t bit) { |
163 | uint8_t b = 1<<7; | 232 | uint8_t b, p; |
164 | while( b ) { | 233 | for( p = 0, b = 1<<(bit-1); b ; b >>= 1) { |
165 | if(data & b) { | 234 | if(data & b) { |
166 | serial_high(); | 235 | serial_high(); p ^= 1; |
167 | } else { | 236 | } else { |
168 | serial_low(); | 237 | serial_low(); p ^= 0; |
238 | } | ||
239 | serial_delay(); | ||
169 | } | 240 | } |
170 | b >>= 1; | 241 | /* send parity bit */ |
242 | if(p & 1) { serial_high(); } | ||
243 | else { serial_low(); } | ||
171 | serial_delay(); | 244 | serial_delay(); |
172 | } | ||
173 | serial_low(); // sync_send() / senc_recv() need raise edge | ||
174 | } | ||
175 | 245 | ||
176 | // interrupt handle to be used by the slave device | 246 | serial_low(); // sync_send() / senc_recv() need raise edge |
177 | ISR(SERIAL_PIN_INTERRUPT) { | 247 | } |
178 | serial_output(); | ||
179 | 248 | ||
180 | // slave send phase | 249 | static void serial_send_packet(uint8_t *buffer, uint8_t size) NO_INLINE; |
181 | uint8_t checksum = 0; | 250 | static |
182 | for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { | 251 | void serial_send_packet(uint8_t *buffer, uint8_t size) { |
252 | for (uint8_t i = 0; i < size; ++i) { | ||
253 | uint8_t data; | ||
254 | data = buffer[i]; | ||
183 | sync_send(); | 255 | sync_send(); |
184 | serial_write_byte(serial_slave_buffer[i]); | 256 | serial_write_chunk(data,8); |
185 | checksum += serial_slave_buffer[i]; | ||
186 | } | 257 | } |
187 | sync_send(); | 258 | } |
188 | serial_write_byte(checksum); | 259 | |
189 | 260 | static uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) NO_INLINE; | |
190 | // slave switch to input | 261 | static |
191 | sync_send(); //0 | 262 | uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) { |
192 | serial_delay_half1(); //1 | 263 | uint8_t pecount = 0; |
193 | serial_low(); //2 | 264 | for (uint8_t i = 0; i < size; ++i) { |
194 | serial_input_with_pullup(); //2 | 265 | uint8_t data; |
195 | serial_delay_half1(); //3 | ||
196 | |||
197 | // slave recive phase | ||
198 | uint8_t checksum_computed = 0; | ||
199 | for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { | ||
200 | sync_recv(); | 266 | sync_recv(); |
201 | serial_master_buffer[i] = serial_read_byte(); | 267 | data = serial_read_chunk(&pecount, 8); |
202 | checksum_computed += serial_master_buffer[i]; | 268 | buffer[i] = data; |
203 | } | 269 | } |
270 | return pecount == 0; | ||
271 | } | ||
272 | |||
273 | inline static | ||
274 | void change_sender2reciver(void) { | ||
275 | sync_send(); //0 | ||
276 | serial_delay_half1(); //1 | ||
277 | serial_low(); //2 | ||
278 | serial_input_with_pullup(); //2 | ||
279 | serial_delay_half1(); //3 | ||
280 | } | ||
281 | |||
282 | inline static | ||
283 | void change_reciver2sender(void) { | ||
284 | sync_recv(); //0 | ||
285 | serial_delay(); //1 | ||
286 | serial_low(); //3 | ||
287 | serial_output(); //3 | ||
288 | serial_delay_half1(); //4 | ||
289 | } | ||
290 | |||
291 | // interrupt handle to be used by the target device | ||
292 | ISR(SERIAL_PIN_INTERRUPT) { | ||
293 | |||
294 | #ifndef SERIAL_USE_MULTI_TRANSACTION | ||
295 | serial_low(); | ||
296 | serial_output(); | ||
297 | SSTD_t *trans = Transaction_table; | ||
298 | #else | ||
299 | // recive transaction table index | ||
300 | uint8_t tid; | ||
301 | uint8_t pecount = 0; | ||
204 | sync_recv(); | 302 | sync_recv(); |
205 | uint8_t checksum_received = serial_read_byte(); | 303 | tid = serial_read_chunk(&pecount,4); |
304 | if(pecount> 0) | ||
305 | return; | ||
306 | serial_delay_half1(); | ||
206 | 307 | ||
207 | if ( checksum_computed != checksum_received ) { | 308 | serial_high(); // response step1 low->high |
208 | status |= SLAVE_DATA_CORRUPT; | 309 | serial_output(); |
310 | _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT*SLAVE_INT_ACK_WIDTH); | ||
311 | SSTD_t *trans = &Transaction_table[tid]; | ||
312 | serial_low(); // response step2 ack high->low | ||
313 | #endif | ||
314 | |||
315 | // target send phase | ||
316 | if( trans->target2initiator_buffer_size > 0 ) | ||
317 | serial_send_packet((uint8_t *)trans->target2initiator_buffer, | ||
318 | trans->target2initiator_buffer_size); | ||
319 | // target switch to input | ||
320 | change_sender2reciver(); | ||
321 | |||
322 | // target recive phase | ||
323 | if( trans->initiator2target_buffer_size > 0 ) { | ||
324 | if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer, | ||
325 | trans->initiator2target_buffer_size) ) { | ||
326 | *trans->status = TRANSACTION_ACCEPTED; | ||
327 | } else { | ||
328 | *trans->status = TRANSACTION_DATA_ERROR; | ||
329 | } | ||
209 | } else { | 330 | } else { |
210 | status &= ~SLAVE_DATA_CORRUPT; | 331 | *trans->status = TRANSACTION_ACCEPTED; |
211 | } | 332 | } |
212 | 333 | ||
213 | sync_recv(); //weit master output to high | 334 | sync_recv(); //weit initiator output to high |
214 | } | ||
215 | |||
216 | inline | ||
217 | bool serial_slave_DATA_CORRUPT(void) { | ||
218 | return status & SLAVE_DATA_CORRUPT; | ||
219 | } | 335 | } |
220 | 336 | ||
221 | // Copies the serial_slave_buffer to the master and sends the | 337 | ///////// |
222 | // serial_master_buffer to the slave. | 338 | // start transaction by initiator |
339 | // | ||
340 | // int soft_serial_transaction(int sstd_index) | ||
223 | // | 341 | // |
224 | // Returns: | 342 | // Returns: |
225 | // 0 => no error | 343 | // TRANSACTION_END |
226 | // 1 => slave did not respond | 344 | // TRANSACTION_NO_RESPONSE |
227 | // 2 => checksum error | 345 | // TRANSACTION_DATA_ERROR |
228 | int serial_update_buffers(void) { | 346 | // this code is very time dependent, so we need to disable interrupts |
229 | // this code is very time dependent, so we need to disable interrupts | 347 | #ifndef SERIAL_USE_MULTI_TRANSACTION |
348 | int soft_serial_transaction(void) { | ||
349 | SSTD_t *trans = Transaction_table; | ||
350 | #else | ||
351 | int soft_serial_transaction(int sstd_index) { | ||
352 | SSTD_t *trans = &Transaction_table[sstd_index]; | ||
353 | #endif | ||
230 | cli(); | 354 | cli(); |
231 | 355 | ||
232 | // signal to the slave that we want to start a transaction | 356 | // signal to the target that we want to start a transaction |
233 | serial_output(); | 357 | serial_output(); |
234 | serial_low(); | 358 | serial_low(); |
235 | _delay_us(SLAVE_INT_WIDTH); | 359 | _delay_us(SLAVE_INT_WIDTH_US); |
236 | 360 | ||
237 | // wait for the slaves response | 361 | #ifndef SERIAL_USE_MULTI_TRANSACTION |
362 | // wait for the target response | ||
238 | serial_input_with_pullup(); | 363 | serial_input_with_pullup(); |
239 | _delay_us(SLAVE_INT_RESPONSE_TIME); | 364 | _delay_us(SLAVE_INT_RESPONSE_TIME); |
240 | 365 | ||
241 | // check if the slave is present | 366 | // check if the target is present |
242 | if (serial_read_pin()) { | 367 | if (serial_read_pin()) { |
243 | // slave failed to pull the line low, assume not present | 368 | // target failed to pull the line low, assume not present |
244 | serial_output(); | 369 | serial_output(); |
245 | serial_high(); | 370 | serial_high(); |
371 | *trans->status = TRANSACTION_NO_RESPONSE; | ||
246 | sei(); | 372 | sei(); |
247 | return 1; | 373 | return TRANSACTION_NO_RESPONSE; |
248 | } | 374 | } |
249 | 375 | ||
250 | // master recive phase | 376 | #else |
251 | // if the slave is present syncronize with it | 377 | // send transaction table index |
378 | sync_send(); | ||
379 | _delay_sub_us(TID_SEND_ADJUST); | ||
380 | serial_write_chunk(sstd_index, 4); | ||
381 | serial_delay_half1(); | ||
252 | 382 | ||
253 | uint8_t checksum_computed = 0; | 383 | // wait for the target response (step1 low->high) |
254 | // receive data from the slave | 384 | serial_input_with_pullup(); |
255 | for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { | 385 | while( !serial_read_pin() ) { |
256 | sync_recv(); | 386 | _delay_sub_us(2); |
257 | serial_slave_buffer[i] = serial_read_byte(); | ||
258 | checksum_computed += serial_slave_buffer[i]; | ||
259 | } | 387 | } |
260 | sync_recv(); | ||
261 | uint8_t checksum_received = serial_read_byte(); | ||
262 | 388 | ||
263 | if (checksum_computed != checksum_received) { | 389 | // check if the target is present (step2 high->low) |
264 | serial_output(); | 390 | for( int i = 0; serial_read_pin(); i++ ) { |
265 | serial_high(); | 391 | if (i > SLAVE_INT_ACK_WIDTH + 1) { |
266 | sei(); | 392 | // slave failed to pull the line low, assume not present |
267 | return 2; | 393 | serial_output(); |
394 | serial_high(); | ||
395 | *trans->status = TRANSACTION_NO_RESPONSE; | ||
396 | sei(); | ||
397 | return TRANSACTION_NO_RESPONSE; | ||
398 | } | ||
399 | _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT); | ||
268 | } | 400 | } |
401 | #endif | ||
269 | 402 | ||
270 | // master switch to output | 403 | // initiator recive phase |
271 | sync_recv(); //0 | 404 | // if the target is present syncronize with it |
272 | serial_delay(); //1 | 405 | if( trans->target2initiator_buffer_size > 0 ) { |
273 | serial_low(); //3 | 406 | if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer, |
274 | serial_output(); // 3 | 407 | trans->target2initiator_buffer_size) ) { |
275 | serial_delay_half1(); //4 | 408 | serial_output(); |
276 | 409 | serial_high(); | |
277 | // master send phase | 410 | *trans->status = TRANSACTION_DATA_ERROR; |
278 | uint8_t checksum = 0; | 411 | sei(); |
279 | 412 | return TRANSACTION_DATA_ERROR; | |
280 | for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { | 413 | } |
281 | sync_send(); | 414 | } |
282 | serial_write_byte(serial_master_buffer[i]); | 415 | |
283 | checksum += serial_master_buffer[i]; | 416 | // initiator switch to output |
417 | change_reciver2sender(); | ||
418 | |||
419 | // initiator send phase | ||
420 | if( trans->initiator2target_buffer_size > 0 ) { | ||
421 | serial_send_packet((uint8_t *)trans->initiator2target_buffer, | ||
422 | trans->initiator2target_buffer_size); | ||
284 | } | 423 | } |
285 | sync_send(); | ||
286 | serial_write_byte(checksum); | ||
287 | 424 | ||
288 | // always, release the line when not in use | 425 | // always, release the line when not in use |
289 | sync_send(); | 426 | sync_send(); |
290 | 427 | ||
428 | *trans->status = TRANSACTION_END; | ||
291 | sei(); | 429 | sei(); |
292 | return 0; | 430 | return TRANSACTION_END; |
293 | } | 431 | } |
294 | 432 | ||
433 | #ifdef SERIAL_USE_MULTI_TRANSACTION | ||
434 | int soft_serial_get_and_clean_status(int sstd_index) { | ||
435 | SSTD_t *trans = &Transaction_table[sstd_index]; | ||
436 | cli(); | ||
437 | int retval = *trans->status; | ||
438 | *trans->status = 0;; | ||
439 | sei(); | ||
440 | return retval; | ||
441 | } | ||
442 | #endif | ||
443 | |||
295 | #endif | 444 | #endif |
diff --git a/keyboards/helix/serial.h b/keyboards/helix/serial.h index c3c9569b2..d2b7fd8e6 100644 --- a/keyboards/helix/serial.h +++ b/keyboards/helix/serial.h | |||
@@ -3,25 +3,78 @@ | |||
3 | 3 | ||
4 | #include <stdbool.h> | 4 | #include <stdbool.h> |
5 | 5 | ||
6 | // //////////////////////////////////////////// | 6 | // ///////////////////////////////////////////////////////////////// |
7 | // Need Soft Serial defines in serial_config.h | 7 | // Need Soft Serial defines in serial_config.h |
8 | // //////////////////////////////////////////// | 8 | // ///////////////////////////////////////////////////////////////// |
9 | // ex. | 9 | // ex. |
10 | // #define SERIAL_PIN_DDR DDRD | 10 | // #define SERIAL_PIN_DDR DDRD |
11 | // #define SERIAL_PIN_PORT PORTD | 11 | // #define SERIAL_PIN_PORT PORTD |
12 | // #define SERIAL_PIN_INPUT PIND | 12 | // #define SERIAL_PIN_INPUT PIND |
13 | // #define SERIAL_PIN_MASK _BV(PD?) ?=0,2 | 13 | // #define SERIAL_PIN_MASK _BV(PD?) ?=0,2 |
14 | // #define SERIAL_PIN_INTERRUPT INT?_vect ?=0,2 | 14 | // #define SERIAL_PIN_INTERRUPT INT?_vect ?=0,2 |
15 | // | ||
16 | // //// USE Simple API (OLD API, compatible with let's split serial.c) | ||
17 | // ex. | ||
15 | // #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 | 18 | // #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 |
16 | // #define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2 | 19 | // #define SERIAL_MASTER_BUFFER_LENGTH 1 |
20 | // | ||
21 | // //// USE flexible API (using multi-type transaction function) | ||
22 | // #define SERIAL_USE_MULTI_TRANSACTION | ||
23 | // | ||
24 | // ///////////////////////////////////////////////////////////////// | ||
25 | |||
17 | 26 | ||
18 | // Buffers for master - slave communication | 27 | #ifndef SERIAL_USE_MULTI_TRANSACTION |
28 | /* --- USE Simple API (OLD API, compatible with let's split serial.c) */ | ||
29 | #if SERIAL_SLAVE_BUFFER_LENGTH > 0 | ||
19 | extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH]; | 30 | extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH]; |
31 | #endif | ||
32 | #if SERIAL_MASTER_BUFFER_LENGTH > 0 | ||
20 | extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH]; | 33 | extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH]; |
34 | #endif | ||
21 | 35 | ||
22 | void serial_master_init(void); | 36 | void serial_master_init(void); |
23 | void serial_slave_init(void); | 37 | void serial_slave_init(void); |
24 | int serial_update_buffers(void); | 38 | int serial_update_buffers(void); |
25 | bool serial_slave_data_corrupt(void); | 39 | |
40 | #endif // USE Simple API | ||
41 | |||
42 | // Soft Serial Transaction Descriptor | ||
43 | typedef struct _SSTD_t { | ||
44 | uint8_t *status; | ||
45 | uint8_t initiator2target_buffer_size; | ||
46 | uint8_t *initiator2target_buffer; | ||
47 | uint8_t target2initiator_buffer_size; | ||
48 | uint8_t *target2initiator_buffer; | ||
49 | } SSTD_t; | ||
50 | |||
51 | // initiator is transaction start side | ||
52 | void soft_serial_initiator_init(SSTD_t *sstd_table); | ||
53 | // target is interrupt accept side | ||
54 | void soft_serial_target_init(SSTD_t *sstd_table); | ||
55 | |||
56 | // initiator resullt | ||
57 | #define TRANSACTION_END 0 | ||
58 | #define TRANSACTION_NO_RESPONSE 0x1 | ||
59 | #define TRANSACTION_DATA_ERROR 0x2 | ||
60 | #ifndef SERIAL_USE_MULTI_TRANSACTION | ||
61 | int soft_serial_transaction(void); | ||
62 | #else | ||
63 | int soft_serial_transaction(int sstd_index); | ||
64 | #endif | ||
65 | |||
66 | // target status | ||
67 | // *SSTD_t.status has | ||
68 | // initiator: | ||
69 | // TRANSACTION_END | ||
70 | // or TRANSACTION_NO_RESPONSE | ||
71 | // or TRANSACTION_DATA_ERROR | ||
72 | // target: | ||
73 | // TRANSACTION_DATA_ERROR | ||
74 | // or TRANSACTION_ACCEPTED | ||
75 | #define TRANSACTION_ACCEPTED 0x4 | ||
76 | #ifdef SERIAL_USE_MULTI_TRANSACTION | ||
77 | int soft_serial_get_and_clean_status(int sstd_index); | ||
78 | #endif | ||
26 | 79 | ||
27 | #endif /* SOFT_SERIAL_H */ | 80 | #endif /* SOFT_SERIAL_H */ |