aboutsummaryrefslogtreecommitdiff
path: root/keyboards/fortitude60/serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/fortitude60/serial.c')
-rw-r--r--keyboards/fortitude60/serial.c290
1 files changed, 218 insertions, 72 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)