aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPekaso <pekaso34@gmail.com>2018-11-15 11:36:53 +0900
committerDrashna Jaelre <drashna@live.com>2018-11-14 18:36:53 -0800
commitdaf08f40f2aeb815322d65d14a90ae56ea22953c (patch)
tree01e5482ac0928983abd6a2f00d6a3b3699d4da10
parentd8f090e5592fd5b6fde35ae36e36f2473c716312 (diff)
downloadqmk_firmware-daf08f40f2aeb815322d65d14a90ae56ea22953c.tar.gz
qmk_firmware-daf08f40f2aeb815322d65d14a90ae56ea22953c.zip
serial.c update (#4423)
-rw-r--r--keyboards/fortitude60/serial.c290
-rw-r--r--keyboards/fortitude60/serial.h59
-rw-r--r--keyboards/fortitude60/serial_config.h8
3 files changed, 254 insertions, 103 deletions
diff --git a/keyboards/fortitude60/serial.c b/keyboards/fortitude60/serial.c
index cea1a5f6c..6006ebf1b 100644
--- a/keyboards/fortitude60/serial.c
+++ b/keyboards/fortitude60/serial.c
@@ -1,5 +1,10 @@
1/* 1/*
2 * WARNING: be careful changing this code, it is very timing dependent 2 * WARNING: be careful changing this code, it is very timing dependent
3 *
4 * 2018-10-28 checked
5 * avr-gcc 4.9.2
6 * avr-gcc 5.4.0
7 * avr-gcc 7.3.0
3 */ 8 */
4 9
5#ifndef F_CPU 10#ifndef F_CPU
@@ -14,10 +19,60 @@
14#include "serial.h" 19#include "serial.h"
15//#include <pro_micro.h> 20//#include <pro_micro.h>
16 21
17#ifdef USE_SERIAL 22#ifdef SOFT_SERIAL_PIN
18 23
19#ifndef SERIAL_USE_MULTI_TRANSACTION 24#ifdef __AVR_ATmega32U4__
20/* --- USE Simple API (OLD API, compatible with let's split serial.c) */ 25 // if using ATmega32U4 I2C, can not use PD0 and PD1 in soft serial.
26 #ifdef USE_I2C
27 #if SOFT_SERIAL_PIN == D0 || SOFT_SERIAL_PIN == D1
28 #error Using ATmega32U4 I2C, so can not use PD0, PD1
29 #endif
30 #endif
31
32 #if SOFT_SERIAL_PIN >= D0 && SOFT_SERIAL_PIN <= D3
33 #define SERIAL_PIN_DDR DDRD
34 #define SERIAL_PIN_PORT PORTD
35 #define SERIAL_PIN_INPUT PIND
36 #if SOFT_SERIAL_PIN == D0
37 #define SERIAL_PIN_MASK _BV(PD0)
38 #define EIMSK_BIT _BV(INT0)
39 #define EICRx_BIT (~(_BV(ISC00) | _BV(ISC01)))
40 #define SERIAL_PIN_INTERRUPT INT0_vect
41 #elif SOFT_SERIAL_PIN == D1
42 #define SERIAL_PIN_MASK _BV(PD1)
43 #define EIMSK_BIT _BV(INT1)
44 #define EICRx_BIT (~(_BV(ISC10) | _BV(ISC11)))
45 #define SERIAL_PIN_INTERRUPT INT1_vect
46 #elif SOFT_SERIAL_PIN == D2
47 #define SERIAL_PIN_MASK _BV(PD2)
48 #define EIMSK_BIT _BV(INT2)
49 #define EICRx_BIT (~(_BV(ISC20) | _BV(ISC21)))
50 #define SERIAL_PIN_INTERRUPT INT2_vect
51 #elif SOFT_SERIAL_PIN == D3
52 #define SERIAL_PIN_MASK _BV(PD3)
53 #define EIMSK_BIT _BV(INT3)
54 #define EICRx_BIT (~(_BV(ISC30) | _BV(ISC31)))
55 #define SERIAL_PIN_INTERRUPT INT3_vect
56 #endif
57 #elif SOFT_SERIAL_PIN == E6
58 #define SERIAL_PIN_DDR DDRE
59 #define SERIAL_PIN_PORT PORTE
60 #define SERIAL_PIN_INPUT PINE
61 #define SERIAL_PIN_MASK _BV(PE6)
62 #define EIMSK_BIT _BV(INT6)
63 #define EICRx_BIT (~(_BV(ISC60) | _BV(ISC61)))
64 #define SERIAL_PIN_INTERRUPT INT6_vect
65 #else
66 #error invalid SOFT_SERIAL_PIN value
67 #endif
68
69#else
70 #error serial.c now support ATmega32U4 only
71#endif
72
73//////////////// for backward compatibility ////////////////////////////////
74#if !defined(SERIAL_USE_SINGLE_TRANSACTION) && !defined(SERIAL_USE_MULTI_TRANSACTION)
75/* --- USE OLD API (compatible with let's split serial.c) */
21 #if SERIAL_SLAVE_BUFFER_LENGTH > 0 76 #if SERIAL_SLAVE_BUFFER_LENGTH > 0
22 uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; 77 uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0};
23 #endif 78 #endif
@@ -42,56 +97,118 @@ SSTD_t transactions[] = {
42}; 97};
43 98
44void serial_master_init(void) 99void serial_master_init(void)
45{ soft_serial_initiator_init(transactions); } 100{ soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
46 101
47void serial_slave_init(void) 102void serial_slave_init(void)
48{ soft_serial_target_init(transactions); } 103{ soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
49 104
50// 0 => no error 105// 0 => no error
51// 1 => slave did not respond 106// 1 => slave did not respond
52// 2 => checksum error 107// 2 => checksum error
53int serial_update_buffers() 108int serial_update_buffers()
54{ return soft_serial_transaction(); } 109{
110 int result;
111 result = soft_serial_transaction();
112 return result;
113}
55 114
56#endif // Simple API (OLD API, compatible with let's split serial.c) 115#endif // end of OLD API (compatible with let's split serial.c)
116////////////////////////////////////////////////////////////////////////////
57 117
58#define ALWAYS_INLINE __attribute__((always_inline)) 118#define ALWAYS_INLINE __attribute__((always_inline))
59#define NO_INLINE __attribute__((noinline)) 119#define NO_INLINE __attribute__((noinline))
60#define _delay_sub_us(x) __builtin_avr_delay_cycles(x) 120#define _delay_sub_us(x) __builtin_avr_delay_cycles(x)
61 121
62// Serial pulse period in microseconds. 122// parity check
63#define TID_SEND_ADJUST 14 123#define ODD_PARITY 1
124#define EVEN_PARITY 0
125#define PARITY EVEN_PARITY
126
127#ifdef SERIAL_DELAY
128 // custom setup in config.h
129 // #define TID_SEND_ADJUST 2
130 // #define SERIAL_DELAY 6 // micro sec
131 // #define READ_WRITE_START_ADJUST 30 // cycles
132 // #define READ_WRITE_WIDTH_ADJUST 8 // cycles
133#else
134// ============ Standard setups ============
135
136#ifndef SELECT_SOFT_SERIAL_SPEED
137#define SELECT_SOFT_SERIAL_SPEED 1
138// 0: about 189kbps
139// 1: about 137kbps (default)
140// 2: about 75kbps
141// 3: about 39kbps
142// 4: about 26kbps
143// 5: about 20kbps
144#endif
64 145
65#define SELECT_SERIAL_SPEED 1 146#if __GNUC__ < 6
66#if SELECT_SERIAL_SPEED == 0 147 #define TID_SEND_ADJUST 14
148#else
149 #define TID_SEND_ADJUST 2
150#endif
151
152#if SELECT_SOFT_SERIAL_SPEED == 0
67 // Very High speed 153 // Very High speed
68 #define SERIAL_DELAY 4 // micro sec 154 #define SERIAL_DELAY 4 // micro sec
69 #define READ_WRITE_START_ADJUST 33 // cycles 155 #if __GNUC__ < 6
70 #define READ_WRITE_WIDTH_ADJUST 3 // cycles 156 #define READ_WRITE_START_ADJUST 33 // cycles
71#elif SELECT_SERIAL_SPEED == 1 157 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
158 #else
159 #define READ_WRITE_START_ADJUST 34 // cycles
160 #define READ_WRITE_WIDTH_ADJUST 7 // cycles
161 #endif
162#elif SELECT_SOFT_SERIAL_SPEED == 1
72 // High speed 163 // High speed
73 #define SERIAL_DELAY 6 // micro sec 164 #define SERIAL_DELAY 6 // micro sec
74 #define READ_WRITE_START_ADJUST 30 // cycles 165 #if __GNUC__ < 6
75 #define READ_WRITE_WIDTH_ADJUST 3 // cycles 166 #define READ_WRITE_START_ADJUST 30 // cycles
76#elif SELECT_SERIAL_SPEED == 2 167 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
168 #else
169 #define READ_WRITE_START_ADJUST 33 // cycles
170 #define READ_WRITE_WIDTH_ADJUST 7 // cycles
171 #endif
172#elif SELECT_SOFT_SERIAL_SPEED == 2
77 // Middle speed 173 // Middle speed
78 #define SERIAL_DELAY 12 // micro sec 174 #define SERIAL_DELAY 12 // micro sec
79 #define READ_WRITE_START_ADJUST 30 // cycles 175 #define READ_WRITE_START_ADJUST 30 // cycles
80 #define READ_WRITE_WIDTH_ADJUST 3 // cycles 176 #if __GNUC__ < 6
81#elif SELECT_SERIAL_SPEED == 3 177 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
178 #else
179 #define READ_WRITE_WIDTH_ADJUST 7 // cycles
180 #endif
181#elif SELECT_SOFT_SERIAL_SPEED == 3
82 // Low speed 182 // Low speed
83 #define SERIAL_DELAY 24 // micro sec 183 #define SERIAL_DELAY 24 // micro sec
84 #define READ_WRITE_START_ADJUST 30 // cycles 184 #define READ_WRITE_START_ADJUST 30 // cycles
85 #define READ_WRITE_WIDTH_ADJUST 3 // cycles 185 #if __GNUC__ < 6
86#elif SELECT_SERIAL_SPEED == 4 186 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
187 #else
188 #define READ_WRITE_WIDTH_ADJUST 7 // cycles
189 #endif
190#elif SELECT_SOFT_SERIAL_SPEED == 4
87 // Very Low speed 191 // Very Low speed
88 #define SERIAL_DELAY 50 // micro sec 192 #define SERIAL_DELAY 36 // micro sec
89 #define READ_WRITE_START_ADJUST 30 // cycles 193 #define READ_WRITE_START_ADJUST 30 // cycles
90 #define READ_WRITE_WIDTH_ADJUST 3 // cycles 194 #if __GNUC__ < 6
195 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
196 #else
197 #define READ_WRITE_WIDTH_ADJUST 7 // cycles
198 #endif
199#elif SELECT_SOFT_SERIAL_SPEED == 5
200 // Ultra Low speed
201 #define SERIAL_DELAY 48 // micro sec
202 #define READ_WRITE_START_ADJUST 30 // cycles
203 #if __GNUC__ < 6
204 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
205 #else
206 #define READ_WRITE_WIDTH_ADJUST 7 // cycles
207 #endif
91#else 208#else
92#error Illegal Serial Speed 209#error invalid SELECT_SOFT_SERIAL_SPEED value
93#endif 210#endif /* SELECT_SOFT_SERIAL_SPEED */
94 211#endif /* SERIAL_DELAY */
95 212
96#define SERIAL_DELAY_HALF1 (SERIAL_DELAY/2) 213#define SERIAL_DELAY_HALF1 (SERIAL_DELAY/2)
97#define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY/2) 214#define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY/2)
@@ -105,17 +222,21 @@ int serial_update_buffers()
105#endif 222#endif
106 223
107static SSTD_t *Transaction_table = NULL; 224static SSTD_t *Transaction_table = NULL;
225static uint8_t Transaction_table_size = 0;
108 226
227inline static void serial_delay(void) ALWAYS_INLINE;
109inline static 228inline static
110void serial_delay(void) { 229void serial_delay(void) {
111 _delay_us(SERIAL_DELAY); 230 _delay_us(SERIAL_DELAY);
112} 231}
113 232
233inline static void serial_delay_half1(void) ALWAYS_INLINE;
114inline static 234inline static
115void serial_delay_half1(void) { 235void serial_delay_half1(void) {
116 _delay_us(SERIAL_DELAY_HALF1); 236 _delay_us(SERIAL_DELAY_HALF1);
117} 237}
118 238
239inline static void serial_delay_half2(void) ALWAYS_INLINE;
119inline static 240inline static
120void serial_delay_half2(void) { 241void serial_delay_half2(void) {
121 _delay_us(SERIAL_DELAY_HALF2); 242 _delay_us(SERIAL_DELAY_HALF2);
@@ -135,6 +256,7 @@ void serial_input_with_pullup(void) {
135 SERIAL_PIN_PORT |= SERIAL_PIN_MASK; 256 SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
136} 257}
137 258
259inline static uint8_t serial_read_pin(void) ALWAYS_INLINE;
138inline static 260inline static
139uint8_t serial_read_pin(void) { 261uint8_t serial_read_pin(void) {
140 return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK); 262 return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK);
@@ -152,30 +274,28 @@ void serial_high(void) {
152 SERIAL_PIN_PORT |= SERIAL_PIN_MASK; 274 SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
153} 275}
154 276
155void soft_serial_initiator_init(SSTD_t *sstd_table) 277void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size)
156{ 278{
157 Transaction_table = sstd_table; 279 Transaction_table = sstd_table;
280 Transaction_table_size = (uint8_t)sstd_table_size;
158 serial_output(); 281 serial_output();
159 serial_high(); 282 serial_high();
160} 283}
161 284
162void soft_serial_target_init(SSTD_t *sstd_table) 285void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size)
163{ 286{
164 Transaction_table = sstd_table; 287 Transaction_table = sstd_table;
288 Transaction_table_size = (uint8_t)sstd_table_size;
165 serial_input_with_pullup(); 289 serial_input_with_pullup();
166 290
167#if SERIAL_PIN_MASK == _BV(PD0) 291 // Enable INT0-INT3,INT6
168 // Enable INT0 292 EIMSK |= EIMSK_BIT;
169 EIMSK |= _BV(INT0); 293#if SERIAL_PIN_MASK == _BV(PE6)
170 // Trigger on falling edge of INT0 294 // Trigger on falling edge of INT6
171 EICRA &= ~(_BV(ISC00) | _BV(ISC01)); 295 EICRB &= EICRx_BIT;
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));
177#else 296#else
178 #error unknown SERIAL_PIN_MASK value 297 // Trigger on falling edge of INT0-INT3
298 EICRA &= EICRx_BIT;
179#endif 299#endif
180} 300}
181 301
@@ -191,7 +311,7 @@ void sync_recv(void) {
191} 311}
192 312
193// Used by the reciver to send a synchronization signal to the sender. 313// Used by the reciver to send a synchronization signal to the sender.
194static void sync_send(void)NO_INLINE; 314static void sync_send(void) NO_INLINE;
195static 315static
196void sync_send(void) { 316void sync_send(void) {
197 serial_low(); 317 serial_low();
@@ -205,12 +325,12 @@ static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) {
205 uint8_t byte, i, p, pb; 325 uint8_t byte, i, p, pb;
206 326
207 _delay_sub_us(READ_WRITE_START_ADJUST); 327 _delay_sub_us(READ_WRITE_START_ADJUST);
208 for( i = 0, byte = 0, p = 0; i < bit; i++ ) { 328 for( i = 0, byte = 0, p = PARITY; i < bit; i++ ) {
209 serial_delay_half1(); // read the middle of pulses 329 serial_delay_half1(); // read the middle of pulses
210 if( serial_read_pin() ) { 330 if( serial_read_pin() ) {
211 byte = (byte << 1) | 1; p ^= 1; 331 byte = (byte << 1) | 1; p ^= 1;
212 } else { 332 } else {
213 byte = (byte << 1) | 0; p ^= 0; 333 byte = (byte << 1) | 0; p ^= 0;
214 } 334 }
215 _delay_sub_us(READ_WRITE_WIDTH_ADJUST); 335 _delay_sub_us(READ_WRITE_WIDTH_ADJUST);
216 serial_delay_half2(); 336 serial_delay_half2();
@@ -230,13 +350,13 @@ static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) {
230void serial_write_chunk(uint8_t data, uint8_t bit) NO_INLINE; 350void serial_write_chunk(uint8_t data, uint8_t bit) NO_INLINE;
231void serial_write_chunk(uint8_t data, uint8_t bit) { 351void serial_write_chunk(uint8_t data, uint8_t bit) {
232 uint8_t b, p; 352 uint8_t b, p;
233 for( p = 0, b = 1<<(bit-1); b ; b >>= 1) { 353 for( p = PARITY, b = 1<<(bit-1); b ; b >>= 1) {
234 if(data & b) { 354 if(data & b) {
235 serial_high(); p ^= 1; 355 serial_high(); p ^= 1;
236 } else { 356 } else {
237 serial_low(); p ^= 0; 357 serial_low(); p ^= 0;
238 } 358 }
239 serial_delay(); 359 serial_delay();
240 } 360 }
241 /* send parity bit */ 361 /* send parity bit */
242 if(p & 1) { serial_high(); } 362 if(p & 1) { serial_high(); }
@@ -288,6 +408,13 @@ void change_reciver2sender(void) {
288 serial_delay_half1(); //4 408 serial_delay_half1(); //4
289} 409}
290 410
411static inline uint8_t nibble_bits_count(uint8_t bits)
412{
413 bits = (bits & 0x5) + (bits >> 1 & 0x5);
414 bits = (bits & 0x3) + (bits >> 2 & 0x3);
415 return bits;
416}
417
291// interrupt handle to be used by the target device 418// interrupt handle to be used by the target device
292ISR(SERIAL_PIN_INTERRUPT) { 419ISR(SERIAL_PIN_INTERRUPT) {
293 420
@@ -297,12 +424,15 @@ ISR(SERIAL_PIN_INTERRUPT) {
297 SSTD_t *trans = Transaction_table; 424 SSTD_t *trans = Transaction_table;
298#else 425#else
299 // recive transaction table index 426 // recive transaction table index
300 uint8_t tid; 427 uint8_t tid, bits;
301 uint8_t pecount = 0; 428 uint8_t pecount = 0;
302 sync_recv(); 429 sync_recv();
303 tid = serial_read_chunk(&pecount,4); 430 bits = serial_read_chunk(&pecount,7);
304 if(pecount> 0) 431 tid = bits>>3;
432 bits = (bits&7) != nibble_bits_count(tid);
433 if( bits || pecount> 0 || tid > Transaction_table_size ) {
305 return; 434 return;
435 }
306 serial_delay_half1(); 436 serial_delay_half1();
307 437
308 serial_high(); // response step1 low->high 438 serial_high(); // response step1 low->high
@@ -315,17 +445,17 @@ ISR(SERIAL_PIN_INTERRUPT) {
315 // target send phase 445 // target send phase
316 if( trans->target2initiator_buffer_size > 0 ) 446 if( trans->target2initiator_buffer_size > 0 )
317 serial_send_packet((uint8_t *)trans->target2initiator_buffer, 447 serial_send_packet((uint8_t *)trans->target2initiator_buffer,
318 trans->target2initiator_buffer_size); 448 trans->target2initiator_buffer_size);
319 // target switch to input 449 // target switch to input
320 change_sender2reciver(); 450 change_sender2reciver();
321 451
322 // target recive phase 452 // target recive phase
323 if( trans->initiator2target_buffer_size > 0 ) { 453 if( trans->initiator2target_buffer_size > 0 ) {
324 if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer, 454 if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer,
325 trans->initiator2target_buffer_size) ) { 455 trans->initiator2target_buffer_size) ) {
326 *trans->status = TRANSACTION_ACCEPTED; 456 *trans->status = TRANSACTION_ACCEPTED;
327 } else { 457 } else {
328 *trans->status = TRANSACTION_DATA_ERROR; 458 *trans->status = TRANSACTION_DATA_ERROR;
329 } 459 }
330 } else { 460 } else {
331 *trans->status = TRANSACTION_ACCEPTED; 461 *trans->status = TRANSACTION_ACCEPTED;
@@ -349,6 +479,8 @@ int soft_serial_transaction(void) {
349 SSTD_t *trans = Transaction_table; 479 SSTD_t *trans = Transaction_table;
350#else 480#else
351int soft_serial_transaction(int sstd_index) { 481int soft_serial_transaction(int sstd_index) {
482 if( sstd_index > Transaction_table_size )
483 return TRANSACTION_TYPE_ERROR;
352 SSTD_t *trans = &Transaction_table[sstd_index]; 484 SSTD_t *trans = &Transaction_table[sstd_index];
353#endif 485#endif
354 cli(); 486 cli();
@@ -375,9 +507,10 @@ int soft_serial_transaction(int sstd_index) {
375 507
376#else 508#else
377 // send transaction table index 509 // send transaction table index
510 int tid = (sstd_index<<3) | (7 & nibble_bits_count(sstd_index));
378 sync_send(); 511 sync_send();
379 _delay_sub_us(TID_SEND_ADJUST); 512 _delay_sub_us(TID_SEND_ADJUST);
380 serial_write_chunk(sstd_index, 4); 513 serial_write_chunk(tid, 7);
381 serial_delay_half1(); 514 serial_delay_half1();
382 515
383 // wait for the target response (step1 low->high) 516 // wait for the target response (step1 low->high)
@@ -389,12 +522,12 @@ int soft_serial_transaction(int sstd_index) {
389 // check if the target is present (step2 high->low) 522 // check if the target is present (step2 high->low)
390 for( int i = 0; serial_read_pin(); i++ ) { 523 for( int i = 0; serial_read_pin(); i++ ) {
391 if (i > SLAVE_INT_ACK_WIDTH + 1) { 524 if (i > SLAVE_INT_ACK_WIDTH + 1) {
392 // slave failed to pull the line low, assume not present 525 // slave failed to pull the line low, assume not present
393 serial_output(); 526 serial_output();
394 serial_high(); 527 serial_high();
395 *trans->status = TRANSACTION_NO_RESPONSE; 528 *trans->status = TRANSACTION_NO_RESPONSE;
396 sei(); 529 sei();
397 return TRANSACTION_NO_RESPONSE; 530 return TRANSACTION_NO_RESPONSE;
398 } 531 }
399 _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT); 532 _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT);
400 } 533 }
@@ -404,12 +537,12 @@ int soft_serial_transaction(int sstd_index) {
404 // if the target is present syncronize with it 537 // if the target is present syncronize with it
405 if( trans->target2initiator_buffer_size > 0 ) { 538 if( trans->target2initiator_buffer_size > 0 ) {
406 if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer, 539 if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer,
407 trans->target2initiator_buffer_size) ) { 540 trans->target2initiator_buffer_size) ) {
408 serial_output(); 541 serial_output();
409 serial_high(); 542 serial_high();
410 *trans->status = TRANSACTION_DATA_ERROR; 543 *trans->status = TRANSACTION_DATA_ERROR;
411 sei(); 544 sei();
412 return TRANSACTION_DATA_ERROR; 545 return TRANSACTION_DATA_ERROR;
413 } 546 }
414 } 547 }
415 548
@@ -419,7 +552,7 @@ int soft_serial_transaction(int sstd_index) {
419 // initiator send phase 552 // initiator send phase
420 if( trans->initiator2target_buffer_size > 0 ) { 553 if( trans->initiator2target_buffer_size > 0 ) {
421 serial_send_packet((uint8_t *)trans->initiator2target_buffer, 554 serial_send_packet((uint8_t *)trans->initiator2target_buffer,
422 trans->initiator2target_buffer_size); 555 trans->initiator2target_buffer_size);
423 } 556 }
424 557
425 // always, release the line when not in use 558 // always, release the line when not in use
@@ -441,4 +574,17 @@ int soft_serial_get_and_clean_status(int sstd_index) {
441} 574}
442#endif 575#endif
443 576
444#endif \ No newline at end of file 577#endif
578
579// Helix serial.c history
580// 2018-1-29 fork from let's split and add PD2, modify sync_recv() (#2308, bceffdefc)
581// 2018-6-28 bug fix master to slave comm and speed up (#3255, 1038bbef4)
582// (adjusted with avr-gcc 4.9.2)
583// 2018-7-13 remove USE_SERIAL_PD2 macro (#3374, f30d6dd78)
584// (adjusted with avr-gcc 4.9.2)
585// 2018-8-11 add support multi-type transaction (#3608, feb5e4aae)
586// (adjusted with avr-gcc 4.9.2)
587// 2018-10-21 fix serial and RGB animation conflict (#4191, 4665e4fff)
588// (adjusted with avr-gcc 7.3.0)
589// 2018-10-28 re-adjust compiler depend value of delay (#4269, 8517f8a66)
590// (adjusted with avr-gcc 5.4.0, 7.3.0)
diff --git a/keyboards/fortitude60/serial.h b/keyboards/fortitude60/serial.h
index d00898055..2e53928df 100644
--- a/keyboards/fortitude60/serial.h
+++ b/keyboards/fortitude60/serial.h
@@ -4,40 +4,47 @@
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 config.h
8// ///////////////////////////////////////////////////////////////// 8// /////////////////////////////////////////////////////////////////
9// ex. 9// ex.
10// #define SERIAL_PIN_DDR DDRD 10// #define SOFT_SERIAL_PIN ?? // ?? = D0,D1,D2,D3,E6
11// #define SERIAL_PIN_PORT PORTD 11// OPTIONAL: #define SELECT_SOFT_SERIAL_SPEED ? // ? = 1,2,3,4,5
12// #define SERIAL_PIN_INPUT PIND 12// // 1: about 137kbps (default)
13// #define SERIAL_PIN_MASK _BV(PD?) ?=0,2 13// // 2: about 75kbps
14// #define SERIAL_PIN_INTERRUPT INT?_vect ?=0,2 14// // 3: about 39kbps
15// // 4: about 26kbps
16// // 5: about 20kbps
15// 17//
16// //// USE Simple API (OLD API, compatible with let's split serial.c) 18// //// USE OLD API (compatible with let's split serial.c)
17// ex. 19// ex.
18// #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 20// #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
19// #define SERIAL_MASTER_BUFFER_LENGTH 1 21// #define SERIAL_MASTER_BUFFER_LENGTH 1
20// 22//
21// //// USE flexible API (using multi-type transaction function) 23// //// USE NEW API
22// #define SERIAL_USE_MULTI_TRANSACTION 24// //// USE simple API (using signle-type transaction function)
25// #define SERIAL_USE_SINGLE_TRANSACTION
26// //// USE flexible API (using multi-type transaction function)
27// #define SERIAL_USE_MULTI_TRANSACTION
23// 28//
24// ///////////////////////////////////////////////////////////////// 29// /////////////////////////////////////////////////////////////////
25 30
26 31
27#ifndef SERIAL_USE_MULTI_TRANSACTION 32//////////////// for backward compatibility ////////////////////////////////
28/* --- USE Simple API (OLD API, compatible with let's split serial.c) */ 33#if !defined(SERIAL_USE_SINGLE_TRANSACTION) && !defined(SERIAL_USE_MULTI_TRANSACTION)
29#if SERIAL_SLAVE_BUFFER_LENGTH > 0 34/* --- USE OLD API (compatible with let's split serial.c) */
30extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH]; 35 #if SERIAL_SLAVE_BUFFER_LENGTH > 0
31#endif 36 extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH];
32#if SERIAL_MASTER_BUFFER_LENGTH > 0 37 #endif
33extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH]; 38 #if SERIAL_MASTER_BUFFER_LENGTH > 0
34#endif 39 extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH];
40 #endif
35 41
36void serial_master_init(void); 42 void serial_master_init(void);
37void serial_slave_init(void); 43 void serial_slave_init(void);
38int serial_update_buffers(void); 44 int serial_update_buffers(void);
39 45
40#endif // USE Simple API 46#endif // end of USE OLD API
47////////////////////////////////////////////////////////////////////////////
41 48
42// Soft Serial Transaction Descriptor 49// Soft Serial Transaction Descriptor
43typedef struct _SSTD_t { 50typedef struct _SSTD_t {
@@ -47,16 +54,18 @@ typedef struct _SSTD_t {
47 uint8_t target2initiator_buffer_size; 54 uint8_t target2initiator_buffer_size;
48 uint8_t *target2initiator_buffer; 55 uint8_t *target2initiator_buffer;
49} SSTD_t; 56} SSTD_t;
57#define TID_LIMIT( table ) (sizeof(table) / sizeof(SSTD_t))
50 58
51// initiator is transaction start side 59// initiator is transaction start side
52void soft_serial_initiator_init(SSTD_t *sstd_table); 60void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size);
53// target is interrupt accept side 61// target is interrupt accept side
54void soft_serial_target_init(SSTD_t *sstd_table); 62void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size);
55 63
56// initiator resullt 64// initiator resullt
57#define TRANSACTION_END 0 65#define TRANSACTION_END 0
58#define TRANSACTION_NO_RESPONSE 0x1 66#define TRANSACTION_NO_RESPONSE 0x1
59#define TRANSACTION_DATA_ERROR 0x2 67#define TRANSACTION_DATA_ERROR 0x2
68#define TRANSACTION_TYPE_ERROR 0x4
60#ifndef SERIAL_USE_MULTI_TRANSACTION 69#ifndef SERIAL_USE_MULTI_TRANSACTION
61int soft_serial_transaction(void); 70int soft_serial_transaction(void);
62#else 71#else
@@ -72,9 +81,9 @@ int soft_serial_transaction(int sstd_index);
72// target: 81// target:
73// TRANSACTION_DATA_ERROR 82// TRANSACTION_DATA_ERROR
74// or TRANSACTION_ACCEPTED 83// or TRANSACTION_ACCEPTED
75#define TRANSACTION_ACCEPTED 0x4 84#define TRANSACTION_ACCEPTED 0x8
76#ifdef SERIAL_USE_MULTI_TRANSACTION 85#ifdef SERIAL_USE_MULTI_TRANSACTION
77int soft_serial_get_and_clean_status(int sstd_index); 86int soft_serial_get_and_clean_status(int sstd_index);
78#endif 87#endif
79 88
80#endif /* SOFT_SERIAL_H */ \ No newline at end of file 89#endif /* SOFT_SERIAL_H */
diff --git a/keyboards/fortitude60/serial_config.h b/keyboards/fortitude60/serial_config.h
index 96a54afbd..d4a42bce3 100644
--- a/keyboards/fortitude60/serial_config.h
+++ b/keyboards/fortitude60/serial_config.h
@@ -2,13 +2,9 @@
2#define SOFT_SERIAL_CONFIG_H 2#define SOFT_SERIAL_CONFIG_H
3 3
4/* Soft Serial defines */ 4/* Soft Serial defines */
5#define SERIAL_PIN_DDR DDRD 5#define SOFT_SERIAL_PIN D2
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 6
11#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 7#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
12#define SERIAL_MASTER_BUFFER_LENGTH 1 8#define SERIAL_MASTER_BUFFER_LENGTH 1
13 9
14#endif /* SOFT_SERIAL_CONFIG_H */ \ No newline at end of file 10#endif /* SOFT_SERIAL_CONFIG_H */