aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKosuke Adachi <ks@fstn.jp>2018-11-05 03:46:26 +0900
committerDrashna Jaelre <drashna@live.com>2018-11-04 10:46:26 -0800
commit756d92c1a071b6c481b67a44671308fc9d680afe (patch)
treeda31f7ef36eb2566ab6eca7af2932cd4377f70ed
parente9fd42df71ebc367fccbbf918a1794498aa57914 (diff)
downloadqmk_firmware-756d92c1a071b6c481b67a44671308fc9d680afe.tar.gz
qmk_firmware-756d92c1a071b6c481b67a44671308fc9d680afe.zip
Keyboard: Update the serial.c of crkbd based on the helix-serial.c (#4349)
-rw-r--r--keyboards/crkbd/rev1/serial_config.h12
-rw-r--r--keyboards/crkbd/rev1/split_scomm.c49
-rw-r--r--keyboards/crkbd/rev1/split_scomm.h5
-rw-r--r--keyboards/crkbd/rev1/split_util.h5
-rw-r--r--keyboards/crkbd/serial.c284
-rw-r--r--keyboards/crkbd/serial.h27
6 files changed, 277 insertions, 105 deletions
diff --git a/keyboards/crkbd/rev1/serial_config.h b/keyboards/crkbd/rev1/serial_config.h
index 671ed821d..4fab8e8dd 100644
--- a/keyboards/crkbd/rev1/serial_config.h
+++ b/keyboards/crkbd/rev1/serial_config.h
@@ -1,10 +1,4 @@
1#pragma once 1#ifndef SOFT_SERIAL_PIN
2 2#define SOFT_SERIAL_PIN D2
3/* Soft Serial defines */
4#define SERIAL_PIN_DDR DDRD
5#define SERIAL_PIN_PORT PORTD
6#define SERIAL_PIN_INPUT PIND
7#define SERIAL_PIN_MASK _BV(PD2)
8#define SERIAL_PIN_INTERRUPT INT2_vect
9
10#define SERIAL_USE_MULTI_TRANSACTION 3#define SERIAL_USE_MULTI_TRANSACTION
4#endif
diff --git a/keyboards/crkbd/rev1/split_scomm.c b/keyboards/crkbd/rev1/split_scomm.c
index 9719eb22e..ada786796 100644
--- a/keyboards/crkbd/rev1/split_scomm.c
+++ b/keyboards/crkbd/rev1/split_scomm.c
@@ -7,8 +7,8 @@
7#include <stddef.h> 7#include <stddef.h>
8#include <split_scomm.h> 8#include <split_scomm.h>
9#include "serial.h" 9#include "serial.h"
10#ifdef SERIAL_DEBUG_MODE 10#ifdef CONSOLE_ENABLE
11#include <avr/io.h> 11 #include <print.h>
12#endif 12#endif
13 13
14uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; 14uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0};
@@ -17,6 +17,7 @@ uint8_t volatile status_com = 0;
17uint8_t volatile status1 = 0; 17uint8_t volatile status1 = 0;
18uint8_t slave_buffer_change_count = 0; 18uint8_t slave_buffer_change_count = 0;
19uint8_t s_change_old = 0xff; 19uint8_t s_change_old = 0xff;
20uint8_t s_change_new = 0xff;
20 21
21SSTD_t transactions[] = { 22SSTD_t transactions[] = {
22#define GET_SLAVE_STATUS 0 23#define GET_SLAVE_STATUS 0
@@ -41,12 +42,12 @@ SSTD_t transactions[] = {
41 42
42void serial_master_init(void) 43void serial_master_init(void)
43{ 44{
44 soft_serial_initiator_init(transactions); 45 soft_serial_initiator_init(transactions, TID_LIMIT(transactions));
45} 46}
46 47
47void serial_slave_init(void) 48void serial_slave_init(void)
48{ 49{
49 soft_serial_target_init(transactions); 50 soft_serial_target_init(transactions, TID_LIMIT(transactions));
50} 51}
51 52
52// 0 => no error 53// 0 => no error
@@ -54,19 +55,37 @@ void serial_slave_init(void)
54// 2 => checksum error 55// 2 => checksum error
55int serial_update_buffers(int master_update) 56int serial_update_buffers(int master_update)
56{ 57{
57 int status; 58 int status, smatstatus;
58 static int need_retry = 0; 59 static int need_retry = 0;
59 if( s_change_old != slave_buffer_change_count ) { 60
60 status = soft_serial_transaction(GET_SLAVE_BUFFER); 61 if( s_change_old != s_change_new ) {
61 if( status == TRANSACTION_END ) 62 smatstatus = soft_serial_transaction(GET_SLAVE_BUFFER);
62 s_change_old = slave_buffer_change_count; 63 if( smatstatus == TRANSACTION_END ) {
64 s_change_old = s_change_new;
65#ifdef CONSOLE_ENABLE
66 uprintf("slave matrix = %b %b %b %b %b\n",
67 serial_slave_buffer[0], serial_slave_buffer[1],
68 serial_slave_buffer[2], serial_slave_buffer[3],
69 serial_slave_buffer[4] );
70#endif
71 }
72 } else {
73 // serial_slave_buffer dosen't change
74 smatstatus = TRANSACTION_END; // dummy status
75 }
76
77 if( !master_update && !need_retry) {
78 status = soft_serial_transaction(GET_SLAVE_STATUS);
79 } else {
80 status = soft_serial_transaction(PUT_MASTER_GET_SLAVE_STATUS);
81 }
82 if( status == TRANSACTION_END ) {
83 s_change_new = slave_buffer_change_count;
84 need_retry = 0;
85 } else {
86 need_retry = 1;
63 } 87 }
64 if( !master_update && !need_retry) 88 return smatstatus;
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} 89}
71 90
72#endif // SERIAL_USE_MULTI_TRANSACTION 91#endif // SERIAL_USE_MULTI_TRANSACTION
diff --git a/keyboards/crkbd/rev1/split_scomm.h b/keyboards/crkbd/rev1/split_scomm.h
index 16887eb74..873d8939d 100644
--- a/keyboards/crkbd/rev1/split_scomm.h
+++ b/keyboards/crkbd/rev1/split_scomm.h
@@ -1,4 +1,5 @@
1#pragma once 1#ifndef SPLIT_COMM_H
2#define SPLIT_COMM_H
2 3
3#ifndef SERIAL_USE_MULTI_TRANSACTION 4#ifndef SERIAL_USE_MULTI_TRANSACTION
4/* --- USE Simple API (OLD API, compatible with let's split serial.c) --- */ 5/* --- USE Simple API (OLD API, compatible with let's split serial.c) --- */
@@ -19,3 +20,5 @@ void serial_slave_init(void);
19int serial_update_buffers(int master_changed); 20int serial_update_buffers(int master_changed);
20 21
21#endif 22#endif
23
24#endif /* SPLIT_COMM_H */
diff --git a/keyboards/crkbd/rev1/split_util.h b/keyboards/crkbd/rev1/split_util.h
index f59304756..687ca19bd 100644
--- a/keyboards/crkbd/rev1/split_util.h
+++ b/keyboards/crkbd/rev1/split_util.h
@@ -1,4 +1,5 @@
1#pragma once 1#ifndef SPLIT_KEYBOARD_UTIL_H
2#define SPLIT_KEYBOARD_UTIL_H
2 3
3#include <stdbool.h> 4#include <stdbool.h>
4#include "eeconfig.h" 5#include "eeconfig.h"
@@ -14,3 +15,5 @@ void split_keyboard_setup(void);
14bool has_usb(void); 15bool has_usb(void);
15 16
16void matrix_master_OLED_init (void); 17void matrix_master_OLED_init (void);
18
19#endif
diff --git a/keyboards/crkbd/serial.c b/keyboards/crkbd/serial.c
index 11ceff0b3..325c29a3f 100644
--- a/keyboards/crkbd/serial.c
+++ b/keyboards/crkbd/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,8 +19,58 @@
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
24#ifdef __AVR_ATmega32U4__
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 ////////////////////////////////
19#ifndef SERIAL_USE_MULTI_TRANSACTION 74#ifndef SERIAL_USE_MULTI_TRANSACTION
20/* --- USE Simple API (OLD API, compatible with let's split serial.c) */ 75/* --- USE Simple API (OLD API, compatible with let's split serial.c) */
21 #if SERIAL_SLAVE_BUFFER_LENGTH > 0 76 #if SERIAL_SLAVE_BUFFER_LENGTH > 0
@@ -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 Simple API (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
193 #define READ_WRITE_START_ADJUST 30 // 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
89 #define READ_WRITE_START_ADJUST 30 // cycles 202 #define READ_WRITE_START_ADJUST 30 // cycles
90 #define READ_WRITE_WIDTH_ADJUST 3 // 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
@@ -442,3 +575,16 @@ int soft_serial_get_and_clean_status(int sstd_index) {
442#endif 575#endif
443 576
444#endif 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/crkbd/serial.h b/keyboards/crkbd/serial.h
index 76c6aaa04..7e0c0847a 100644
--- a/keyboards/crkbd/serial.h
+++ b/keyboards/crkbd/serial.h
@@ -1,16 +1,19 @@
1#pragma once 1#ifndef SOFT_SERIAL_H
2#define SOFT_SERIAL_H
2 3
3#include <stdbool.h> 4#include <stdbool.h>
4 5
5// ///////////////////////////////////////////////////////////////// 6// /////////////////////////////////////////////////////////////////
6// Need Soft Serial defines in serial_config.h 7// Need Soft Serial defines in config.h
7// ///////////////////////////////////////////////////////////////// 8// /////////////////////////////////////////////////////////////////
8// ex. 9// ex.
9// #define SERIAL_PIN_DDR DDRD 10// #define SOFT_SERIAL_PIN ?? // ?? = D0,D1,D2,D3,E6
10// #define SERIAL_PIN_PORT PORTD 11// OPTIONAL: #define SELECT_SOFT_SERIAL_SPEED ? // ? = 1,2,3,4,5
11// #define SERIAL_PIN_INPUT PIND 12// // 1: about 137kbps (default)
12// #define SERIAL_PIN_MASK _BV(PD?) ?=0,2 13// // 2: about 75kbps
13// #define SERIAL_PIN_INTERRUPT INT?_vect ?=0,2 14// // 3: about 39kbps
15// // 4: about 26kbps
16// // 5: about 20kbps
14// 17//
15// //// USE Simple API (OLD API, compatible with let's split serial.c) 18// //// USE Simple API (OLD API, compatible with let's split serial.c)
16// ex. 19// ex.
@@ -46,16 +49,18 @@ typedef struct _SSTD_t {
46 uint8_t target2initiator_buffer_size; 49 uint8_t target2initiator_buffer_size;
47 uint8_t *target2initiator_buffer; 50 uint8_t *target2initiator_buffer;
48} SSTD_t; 51} SSTD_t;
52#define TID_LIMIT( table ) (sizeof(table) / sizeof(SSTD_t))
49 53
50// initiator is transaction start side 54// initiator is transaction start side
51void soft_serial_initiator_init(SSTD_t *sstd_table); 55void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size);
52// target is interrupt accept side 56// target is interrupt accept side
53void soft_serial_target_init(SSTD_t *sstd_table); 57void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size);
54 58
55// initiator resullt 59// initiator resullt
56#define TRANSACTION_END 0 60#define TRANSACTION_END 0
57#define TRANSACTION_NO_RESPONSE 0x1 61#define TRANSACTION_NO_RESPONSE 0x1
58#define TRANSACTION_DATA_ERROR 0x2 62#define TRANSACTION_DATA_ERROR 0x2
63#define TRANSACTION_TYPE_ERROR 0x4
59#ifndef SERIAL_USE_MULTI_TRANSACTION 64#ifndef SERIAL_USE_MULTI_TRANSACTION
60int soft_serial_transaction(void); 65int soft_serial_transaction(void);
61#else 66#else
@@ -71,7 +76,9 @@ int soft_serial_transaction(int sstd_index);
71// target: 76// target:
72// TRANSACTION_DATA_ERROR 77// TRANSACTION_DATA_ERROR
73// or TRANSACTION_ACCEPTED 78// or TRANSACTION_ACCEPTED
74#define TRANSACTION_ACCEPTED 0x4 79#define TRANSACTION_ACCEPTED 0x8
75#ifdef SERIAL_USE_MULTI_TRANSACTION 80#ifdef SERIAL_USE_MULTI_TRANSACTION
76int soft_serial_get_and_clean_status(int sstd_index); 81int soft_serial_get_and_clean_status(int sstd_index);
77#endif 82#endif
83
84#endif /* SOFT_SERIAL_H */