aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPekaso <pekaso34@gmail.com>2018-09-28 10:06:19 +0900
committerDrashna Jaelre <drashna@live.com>2018-09-27 18:06:19 -0700
commita65085a89354e89ddd3517aa63c74ef6dd32ca8b (patch)
tree7fa976bcd86055d56c6c3be9528c2aaf976ae1c7
parent8ef747accf6e59ff50a3dde1cb34f56e4edce9fe (diff)
downloadqmk_firmware-a65085a89354e89ddd3517aa63c74ef6dd32ca8b.tar.gz
qmk_firmware-a65085a89354e89ddd3517aa63c74ef6dd32ca8b.zip
Keyboard: [Fortitude60] LED fix and Serial improvement (#3982)
* arrangement Underglow * modified serial function references from helix * Remove defines (ws2812_*REG)
-rw-r--r--keyboards/fortitude60/config.h1
-rw-r--r--keyboards/fortitude60/keymaps/default/config.h1
-rw-r--r--keyboards/fortitude60/keymaps/default/keymap.c4
-rw-r--r--keyboards/fortitude60/keymaps/default/rules.mk1
-rw-r--r--keyboards/fortitude60/rev1/config.h11
-rw-r--r--keyboards/fortitude60/rev1/rules.mk1
-rw-r--r--keyboards/fortitude60/serial.c451
-rw-r--r--keyboards/fortitude60/serial.h86
-rw-r--r--keyboards/fortitude60/serial_config.h14
9 files changed, 420 insertions, 150 deletions
diff --git a/keyboards/fortitude60/config.h b/keyboards/fortitude60/config.h
index 863722d7d..27a44ab92 100644
--- a/keyboards/fortitude60/config.h
+++ b/keyboards/fortitude60/config.h
@@ -19,5 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
19#define CONFIG_H 19#define CONFIG_H
20 20
21#include "config_common.h" 21#include "config_common.h"
22#include <serial_config.h>
22 23
23#endif // CONFIG_H 24#endif // CONFIG_H
diff --git a/keyboards/fortitude60/keymaps/default/config.h b/keyboards/fortitude60/keymaps/default/config.h
index b356791fc..174837348 100644
--- a/keyboards/fortitude60/keymaps/default/config.h
+++ b/keyboards/fortitude60/keymaps/default/config.h
@@ -28,7 +28,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
28// #define MASTER_RIGHT 28// #define MASTER_RIGHT
29#define EE_HANDS 29#define EE_HANDS
30 30
31#define USE_SERIAL_PD2
32/* #undef RGBLED_NUM */ 31/* #undef RGBLED_NUM */
33/* #define RGBLIGHT_ANIMATIONS */ 32/* #define RGBLIGHT_ANIMATIONS */
34/* #define RGBLED_NUM 12 */ 33/* #define RGBLED_NUM 12 */
diff --git a/keyboards/fortitude60/keymaps/default/keymap.c b/keyboards/fortitude60/keymaps/default/keymap.c
index 18d2527e4..9d724a8ec 100644
--- a/keyboards/fortitude60/keymaps/default/keymap.c
+++ b/keyboards/fortitude60/keymaps/default/keymap.c
@@ -119,9 +119,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
119 * ,-----------------------------------------. ,-----------------------------------------. 119 * ,-----------------------------------------. ,-----------------------------------------.
120 * | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Del | 120 * | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Del |
121 * |------+------+------+------+------+------. ,------+------+------+------+------+------| 121 * |------+------+------+------+------+------. ,------+------+------+------+------+------|
122 * | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Bksp | 122 * | ` | 1 | | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Bksp |
123 * |------+------+------+------+------+------. ,------+------+------+------+------+------| 123 * |------+------+------+------+------+------. ,------+------+------+------+------+------|
124 * | Del | F1 | F2 | F3 | F4 | F5 | | F6 | - | = | [ | ] | | | 124 * | Del | | | | F4 | F5 | | F6 | - | = | [ | ] | | |
125 * |------+------+------+------+------+------+-------------+------+------+------+------+------+------| 125 * |------+------+------+------+------+------+-------------+------+------+------+------+------+------|
126 * | | F7 | F8 | F9 | F10 | F11 | | | F12 |ISO # |ISO / | | | | 126 * | | F7 | F8 | F9 | F10 | F11 | | | F12 |ISO # |ISO / | | | |
127 * `-------------+------+------+------+------+------+------+------+------+------+------+-------------' 127 * `-------------+------+------+------+------+------+------+------+------+------+------+-------------'
diff --git a/keyboards/fortitude60/keymaps/default/rules.mk b/keyboards/fortitude60/keymaps/default/rules.mk
index e0ed6f0c2..1964bd0a7 100644
--- a/keyboards/fortitude60/keymaps/default/rules.mk
+++ b/keyboards/fortitude60/keymaps/default/rules.mk
@@ -1 +1,2 @@
1RGBLIGHT_ENABLE = no 1RGBLIGHT_ENABLE = no
2BACKLIGHT_ENABLE = no \ No newline at end of file
diff --git a/keyboards/fortitude60/rev1/config.h b/keyboards/fortitude60/rev1/config.h
index 4ba195ff8..8c6f21afe 100644
--- a/keyboards/fortitude60/rev1/config.h
+++ b/keyboards/fortitude60/rev1/config.h
@@ -64,12 +64,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
64) 64)
65 65
66/* ws2812 RGB LED */ 66/* ws2812 RGB LED */
67/* #define RGB_DI_PIN D3 */ 67#ifdef RGBLIGHT_ENABLE
68/* #define RGBLIGHT_TIMER */ 68 #define RGB_DI_PIN B5
69/* #define RGBLED_NUM 16 // Number of LEDs */ 69 #define RGBLIGHT_TIMER
70/* #define ws2812_PORTREG PORTD */ 70 #define RGBLED_NUM 18 // Number of LEDs */
71/* #define ws2812_DDRREG DDRD */ 71#endif
72
73/* 72/*
74 * Feature disable options 73 * Feature disable options
75 * These options are also useful to firmware size reduction. 74 * These options are also useful to firmware size reduction.
diff --git a/keyboards/fortitude60/rev1/rules.mk b/keyboards/fortitude60/rev1/rules.mk
index bd518d8f2..e69de29bb 100644
--- a/keyboards/fortitude60/rev1/rules.mk
+++ b/keyboards/fortitude60/rev1/rules.mk
@@ -1 +0,0 @@
1BACKLIGHT_ENABLE = yes
diff --git a/keyboards/fortitude60/serial.c b/keyboards/fortitude60/serial.c
index 46dfad021..cea1a5f6c 100644
--- a/keyboards/fortitude60/serial.c
+++ b/keyboards/fortitude60/serial.c
@@ -9,20 +9,102 @@
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>
16
17#ifdef USE_SERIAL
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
29SSTD_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
44void serial_master_init(void)
45{ soft_serial_initiator_init(transactions); }
14 46
15#ifndef USE_I2C 47void serial_slave_init(void)
48{ soft_serial_target_init(transactions); }
16 49
17// Serial pulse period in microseconds. Its probably a bad idea to lower this 50// 0 => no error
18// value. 51// 1 => slave did not respond
19#define SERIAL_DELAY 24 52// 2 => checksum error
53int 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))
60#define _delay_sub_us(x) __builtin_avr_delay_cycles(x)
61
62// Serial pulse period in microseconds.
63#define TID_SEND_ADJUST 14
64
65#define SELECT_SERIAL_SPEED 1
66#if SELECT_SERIAL_SPEED == 0
67 // Very High speed
68 #define SERIAL_DELAY 4 // micro sec
69 #define READ_WRITE_START_ADJUST 33 // cycles
70 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
71#elif SELECT_SERIAL_SPEED == 1
72 // High speed
73 #define SERIAL_DELAY 6 // micro sec
74 #define READ_WRITE_START_ADJUST 30 // cycles
75 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
76#elif SELECT_SERIAL_SPEED == 2
77 // Middle speed
78 #define SERIAL_DELAY 12 // micro sec
79 #define READ_WRITE_START_ADJUST 30 // cycles
80 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
81#elif SELECT_SERIAL_SPEED == 3
82 // Low speed
83 #define SERIAL_DELAY 24 // micro sec
84 #define READ_WRITE_START_ADJUST 30 // cycles
85 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
86#elif SELECT_SERIAL_SPEED == 4
87 // Very Low speed
88 #define SERIAL_DELAY 50 // micro sec
89 #define READ_WRITE_START_ADJUST 30 // cycles
90 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
91#else
92#error Illegal Serial Speed
93#endif
20 94
21uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0};
22uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0};
23 95
24#define SLAVE_DATA_CORRUPT (1<<0) 96#define SERIAL_DELAY_HALF1 (SERIAL_DELAY/2)
25volatile uint8_t status = 0; 97#define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY/2)
98
99#define SLAVE_INT_WIDTH_US 1
100#ifndef SERIAL_USE_MULTI_TRANSACTION
101 #define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY
102#else
103 #define SLAVE_INT_ACK_WIDTH_UNIT 2
104 #define SLAVE_INT_ACK_WIDTH 4
105#endif
106
107static SSTD_t *Transaction_table = NULL;
26 108
27inline static 109inline static
28void serial_delay(void) { 110void serial_delay(void) {
@@ -30,13 +112,25 @@ void serial_delay(void) {
30} 112}
31 113
32inline static 114inline static
115void serial_delay_half1(void) {
116 _delay_us(SERIAL_DELAY_HALF1);
117}
118
119inline static
120void serial_delay_half2(void) {
121 _delay_us(SERIAL_DELAY_HALF2);
122}
123
124inline static void serial_output(void) ALWAYS_INLINE;
125inline static
33void serial_output(void) { 126void serial_output(void) {
34 SERIAL_PIN_DDR |= SERIAL_PIN_MASK; 127 SERIAL_PIN_DDR |= SERIAL_PIN_MASK;
35} 128}
36 129
37// make the serial pin an input with pull-up resistor 130// make the serial pin an input with pull-up resistor
131inline static void serial_input_with_pullup(void) ALWAYS_INLINE;
38inline static 132inline static
39void serial_input(void) { 133void serial_input_with_pullup(void) {
40 SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK; 134 SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK;
41 SERIAL_PIN_PORT |= SERIAL_PIN_MASK; 135 SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
42} 136}
@@ -46,190 +140,305 @@ uint8_t serial_read_pin(void) {
46 return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK); 140 return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK);
47} 141}
48 142
143inline static void serial_low(void) ALWAYS_INLINE;
49inline static 144inline static
50void serial_low(void) { 145void serial_low(void) {
51 SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK; 146 SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK;
52} 147}
53 148
149inline static void serial_high(void) ALWAYS_INLINE;
54inline static 150inline static
55void serial_high(void) { 151void serial_high(void) {
56 SERIAL_PIN_PORT |= SERIAL_PIN_MASK; 152 SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
57} 153}
58 154
59void serial_master_init(void) { 155void soft_serial_initiator_init(SSTD_t *sstd_table)
60 serial_output(); 156{
61 serial_high(); 157 Transaction_table = sstd_table;
158 serial_output();
159 serial_high();
62} 160}
63 161
64void serial_slave_init(void) { 162void soft_serial_target_init(SSTD_t *sstd_table)
65 serial_input(); 163{
66 164 Transaction_table = sstd_table;
67#ifndef USE_SERIAL_PD2 165 serial_input_with_pullup();
68 // Enable INT0 166
69 EIMSK |= _BV(INT0); 167#if SERIAL_PIN_MASK == _BV(PD0)
70 // Trigger on falling edge of INT0 168 // Enable INT0
71 EICRA &= ~(_BV(ISC00) | _BV(ISC01)); 169 EIMSK |= _BV(INT0);
170 // Trigger on falling edge of INT0
171 EICRA &= ~(_BV(ISC00) | _BV(ISC01));
172#elif SERIAL_PIN_MASK == _BV(PD2)
173 // Enable INT2
174 EIMSK |= _BV(INT2);
175 // Trigger on falling edge of INT2
176 EICRA &= ~(_BV(ISC20) | _BV(ISC21));
72#else 177#else
73 // Enable INT2 178 #error unknown SERIAL_PIN_MASK value
74 EIMSK |= _BV(INT2);
75 // Trigger on falling edge of INT2
76 EICRA &= ~(_BV(ISC20) | _BV(ISC21));
77#endif 179#endif
78} 180}
79 181
80// Used by the master to synchronize timing with the slave. 182// Used by the sender to synchronize timing with the reciver.
183static void sync_recv(void) NO_INLINE;
81static 184static
82void sync_recv(void) { 185void sync_recv(void) {
83 serial_input(); 186 for (uint8_t i = 0; i < SERIAL_DELAY*5 && serial_read_pin(); i++ ) {
84 // This shouldn't hang if the slave disconnects because the 187 }
85 // serial line will float to high if the slave does disconnect. 188 // This shouldn't hang if the target disconnects because the
189 // serial line will float to high if the target does disconnect.
86 while (!serial_read_pin()); 190 while (!serial_read_pin());
87 serial_delay();
88} 191}
89 192
90// Used by the slave to send a synchronization signal to the master. 193// Used by the reciver to send a synchronization signal to the sender.
194static void sync_send(void)NO_INLINE;
91static 195static
92void sync_send(void) { 196void sync_send(void) {
93 serial_output();
94
95 serial_low(); 197 serial_low();
96 serial_delay(); 198 serial_delay();
97
98 serial_high(); 199 serial_high();
99} 200}
100 201
101// Reads a byte from the serial line 202// Reads a byte from the serial line
102static 203static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) NO_INLINE;
103uint8_t serial_read_byte(void) { 204static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) {
104 uint8_t byte = 0; 205 uint8_t byte, i, p, pb;
105 serial_input(); 206
106 for ( uint8_t i = 0; i < 8; ++i) { 207 _delay_sub_us(READ_WRITE_START_ADJUST);
107 byte = (byte << 1) | serial_read_pin(); 208 for( i = 0, byte = 0, p = 0; i < bit; i++ ) {
108 serial_delay(); 209 serial_delay_half1(); // read the middle of pulses
109 _delay_us(1); 210 if( serial_read_pin() ) {
211 byte = (byte << 1) | 1; p ^= 1;
212 } else {
213 byte = (byte << 1) | 0; p ^= 0;
214 }
215 _delay_sub_us(READ_WRITE_WIDTH_ADJUST);
216 serial_delay_half2();
110 } 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;
111 225
112 return byte; 226 return byte;
113} 227}
114 228
115// Sends a byte with MSB ordering 229// Sends a byte with MSB ordering
116static 230void serial_write_chunk(uint8_t data, uint8_t bit) NO_INLINE;
117void serial_write_byte(uint8_t data) { 231void serial_write_chunk(uint8_t data, uint8_t bit) {
118 uint8_t b = 8; 232 uint8_t b, p;
119 serial_output(); 233 for( p = 0, b = 1<<(bit-1); b ; b >>= 1) {
120 while( b-- ) { 234 if(data & b) {
121 if(data & (1 << b)) { 235 serial_high(); p ^= 1;
122 serial_high(); 236 } else {
123 } else { 237 serial_low(); p ^= 0;
124 serial_low(); 238 }
239 serial_delay();
125 } 240 }
241 /* send parity bit */
242 if(p & 1) { serial_high(); }
243 else { serial_low(); }
126 serial_delay(); 244 serial_delay();
127 }
128}
129 245
130// interrupt handle to be used by the slave device 246 serial_low(); // sync_send() / senc_recv() need raise edge
131ISR(SERIAL_PIN_INTERRUPT) { 247}
132 sync_send();
133 248
134 uint8_t checksum = 0; 249static void serial_send_packet(uint8_t *buffer, uint8_t size) NO_INLINE;
135 for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { 250static
136 serial_write_byte(serial_slave_buffer[i]); 251void 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];
137 sync_send(); 255 sync_send();
138 checksum += serial_slave_buffer[i]; 256 serial_write_chunk(data,8);
139 } 257 }
140 serial_write_byte(checksum); 258}
141 sync_send();
142 259
143 // wait for the sync to finish sending 260static uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) NO_INLINE;
144 serial_delay(); 261static
262uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) {
263 uint8_t pecount = 0;
264 for (uint8_t i = 0; i < size; ++i) {
265 uint8_t data;
266 sync_recv();
267 data = serial_read_chunk(&pecount, 8);
268 buffer[i] = data;
269 }
270 return pecount == 0;
271}
145 272
146 // read the middle of pulses 273inline static
147 _delay_us(SERIAL_DELAY/2); 274void 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}
148 281
149 uint8_t checksum_computed = 0; 282inline static
150 for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { 283void change_reciver2sender(void) {
151 serial_master_buffer[i] = serial_read_byte(); 284 sync_recv(); //0
152 sync_send(); 285 serial_delay(); //1
153 checksum_computed += serial_master_buffer[i]; 286 serial_low(); //3
154 } 287 serial_output(); //3
155 uint8_t checksum_received = serial_read_byte(); 288 serial_delay_half1(); //4
156 sync_send(); 289}
157 290
158 serial_input(); // end transaction 291// interrupt handle to be used by the target device
292ISR(SERIAL_PIN_INTERRUPT) {
159 293
160 if ( checksum_computed != checksum_received ) { 294#ifndef SERIAL_USE_MULTI_TRANSACTION
161 status |= SLAVE_DATA_CORRUPT; 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;
302 sync_recv();
303 tid = serial_read_chunk(&pecount,4);
304 if(pecount> 0)
305 return;
306 serial_delay_half1();
307
308 serial_high(); // response step1 low->high
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 }
162 } else { 330 } else {
163 status &= ~SLAVE_DATA_CORRUPT; 331 *trans->status = TRANSACTION_ACCEPTED;
164 } 332 }
165}
166 333
167inline 334 sync_recv(); //weit initiator output to high
168bool serial_slave_DATA_CORRUPT(void) {
169 return status & SLAVE_DATA_CORRUPT;
170} 335}
171 336
172// Copies the serial_slave_buffer to the master and sends the 337/////////
173// serial_master_buffer to the slave. 338// start transaction by initiator
339//
340// int soft_serial_transaction(int sstd_index)
174// 341//
175// Returns: 342// Returns:
176// 0 => no error 343// TRANSACTION_END
177// 1 => slave did not respond 344// TRANSACTION_NO_RESPONSE
178int serial_update_buffers(void) { 345// TRANSACTION_DATA_ERROR
179 // this code is very time dependent, so we need to disable interrupts 346// this code is very time dependent, so we need to disable interrupts
347#ifndef SERIAL_USE_MULTI_TRANSACTION
348int soft_serial_transaction(void) {
349 SSTD_t *trans = Transaction_table;
350#else
351int soft_serial_transaction(int sstd_index) {
352 SSTD_t *trans = &Transaction_table[sstd_index];
353#endif
180 cli(); 354 cli();
181 355
182 // signal to the slave that we want to start a transaction 356 // signal to the target that we want to start a transaction
183 serial_output(); 357 serial_output();
184 serial_low(); 358 serial_low();
185 _delay_us(1); 359 _delay_us(SLAVE_INT_WIDTH_US);
186 360
187 // wait for the slaves response 361#ifndef SERIAL_USE_MULTI_TRANSACTION
188 serial_input(); 362 // wait for the target response
189 serial_high(); 363 serial_input_with_pullup();
190 _delay_us(SERIAL_DELAY); 364 _delay_us(SLAVE_INT_RESPONSE_TIME);
191 365
192 // check if the slave is present 366 // check if the target is present
193 if (serial_read_pin()) { 367 if (serial_read_pin()) {
194 // slave failed to pull the line low, assume not present 368 // target failed to pull the line low, assume not present
369 serial_output();
370 serial_high();
371 *trans->status = TRANSACTION_NO_RESPONSE;
195 sei(); 372 sei();
196 return 1; 373 return TRANSACTION_NO_RESPONSE;
197 } 374 }
198 375
199 // if the slave is present syncronize with it 376#else
200 sync_recv(); 377 // send transaction table index
201 378 sync_send();
202 uint8_t checksum_computed = 0; 379 _delay_sub_us(TID_SEND_ADJUST);
203 // receive data from the slave 380 serial_write_chunk(sstd_index, 4);
204 for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { 381 serial_delay_half1();
205 serial_slave_buffer[i] = serial_read_byte(); 382
206 sync_recv(); 383 // wait for the target response (step1 low->high)
207 checksum_computed += serial_slave_buffer[i]; 384 serial_input_with_pullup();
385 while( !serial_read_pin() ) {
386 _delay_sub_us(2);
208 } 387 }
209 uint8_t checksum_received = serial_read_byte();
210 sync_recv();
211 388
212 if (checksum_computed != checksum_received) { 389 // check if the target is present (step2 high->low)
213 sei(); 390 for( int i = 0; serial_read_pin(); i++ ) {
214 return 2; 391 if (i > SLAVE_INT_ACK_WIDTH + 1) {
392 // slave failed to pull the line low, assume not present
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);
215 } 400 }
401#endif
216 402
217 uint8_t checksum = 0; 403 // initiator recive phase
218 // send data to the slave 404 // if the target is present syncronize with it
219 for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { 405 if( trans->target2initiator_buffer_size > 0 ) {
220 serial_write_byte(serial_master_buffer[i]); 406 if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer,
221 sync_recv(); 407 trans->target2initiator_buffer_size) ) {
222 checksum += serial_master_buffer[i]; 408 serial_output();
409 serial_high();
410 *trans->status = TRANSACTION_DATA_ERROR;
411 sei();
412 return TRANSACTION_DATA_ERROR;
413 }
414 }
415
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);
223 } 423 }
224 serial_write_byte(checksum);
225 sync_recv();
226 424
227 // always, release the line when not in use 425 // always, release the line when not in use
228 serial_output(); 426 sync_send();
229 serial_high();
230 427
428 *trans->status = TRANSACTION_END;
231 sei(); 429 sei();
232 return 0; 430 return TRANSACTION_END;
233} 431}
234 432
433#ifdef SERIAL_USE_MULTI_TRANSACTION
434int 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}
235#endif 442#endif
443
444#endif \ No newline at end of file
diff --git a/keyboards/fortitude60/serial.h b/keyboards/fortitude60/serial.h
index 361f1881b..d00898055 100644
--- a/keyboards/fortitude60/serial.h
+++ b/keyboards/fortitude60/serial.h
@@ -1,32 +1,80 @@
1#ifndef MY_SERIAL_H 1#ifndef SOFT_SERIAL_H
2#define MY_SERIAL_H 2#define SOFT_SERIAL_H
3 3
4#include "config.h"
5#include <stdbool.h> 4#include <stdbool.h>
6 5
7/* TODO: some defines for interrupt setup */ 6// /////////////////////////////////////////////////////////////////
8#define SERIAL_PIN_DDR DDRD 7// Need Soft Serial defines in serial_config.h
9#define SERIAL_PIN_PORT PORTD 8// /////////////////////////////////////////////////////////////////
10#define SERIAL_PIN_INPUT PIND 9// ex.
10// #define SERIAL_PIN_DDR DDRD
11// #define SERIAL_PIN_PORT PORTD
12// #define SERIAL_PIN_INPUT PIND
13// #define SERIAL_PIN_MASK _BV(PD?) ?=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.
18// #define SERIAL_SLAVE_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// /////////////////////////////////////////////////////////////////
11 25
12#ifndef USE_SERIAL_PD2
13#define SERIAL_PIN_MASK _BV(PD0)
14#define SERIAL_PIN_INTERRUPT INT0_vect
15#else
16#define SERIAL_PIN_MASK _BV(PD2)
17#define SERIAL_PIN_INTERRUPT INT2_vect
18#endif
19
20#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
21#define SERIAL_MASTER_BUFFER_LENGTH 1
22 26
23// 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
24extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH]; 30extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH];
31#endif
32#if SERIAL_MASTER_BUFFER_LENGTH > 0
25extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH]; 33extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH];
34#endif
26 35
27void serial_master_init(void); 36void serial_master_init(void);
28void serial_slave_init(void); 37void serial_slave_init(void);
29int serial_update_buffers(void); 38int serial_update_buffers(void);
30bool serial_slave_data_corrupt(void);
31 39
40#endif // USE Simple API
41
42// Soft Serial Transaction Descriptor
43typedef 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
52void soft_serial_initiator_init(SSTD_t *sstd_table);
53// target is interrupt accept side
54void 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
61int soft_serial_transaction(void);
62#else
63int soft_serial_transaction(int sstd_index);
32#endif 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
77int soft_serial_get_and_clean_status(int sstd_index);
78#endif
79
80#endif /* SOFT_SERIAL_H */ \ No newline at end of file
diff --git a/keyboards/fortitude60/serial_config.h b/keyboards/fortitude60/serial_config.h
new file mode 100644
index 000000000..96a54afbd
--- /dev/null
+++ b/keyboards/fortitude60/serial_config.h
@@ -0,0 +1,14 @@
1#ifndef SOFT_SERIAL_CONFIG_H
2#define SOFT_SERIAL_CONFIG_H
3
4/* Soft Serial defines */
5#define SERIAL_PIN_DDR DDRD
6#define SERIAL_PIN_PORT PORTD
7#define SERIAL_PIN_INPUT PIND
8#define SERIAL_PIN_MASK _BV(PD2)
9#define SERIAL_PIN_INTERRUPT INT2_vect
10
11#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
12#define SERIAL_MASTER_BUFFER_LENGTH 1
13
14#endif /* SOFT_SERIAL_CONFIG_H */ \ No newline at end of file