diff options
| author | Pekaso <pekaso34@gmail.com> | 2018-11-15 11:36:53 +0900 |
|---|---|---|
| committer | Drashna Jaelre <drashna@live.com> | 2018-11-14 18:36:53 -0800 |
| commit | daf08f40f2aeb815322d65d14a90ae56ea22953c (patch) | |
| tree | 01e5482ac0928983abd6a2f00d6a3b3699d4da10 /keyboards/fortitude60 | |
| parent | d8f090e5592fd5b6fde35ae36e36f2473c716312 (diff) | |
| download | qmk_firmware-daf08f40f2aeb815322d65d14a90ae56ea22953c.tar.gz qmk_firmware-daf08f40f2aeb815322d65d14a90ae56ea22953c.zip | |
serial.c update (#4423)
Diffstat (limited to 'keyboards/fortitude60')
| -rw-r--r-- | keyboards/fortitude60/serial.c | 290 | ||||
| -rw-r--r-- | keyboards/fortitude60/serial.h | 59 | ||||
| -rw-r--r-- | keyboards/fortitude60/serial_config.h | 8 |
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 | ||
| 44 | void serial_master_init(void) | 99 | void serial_master_init(void) |
| 45 | { soft_serial_initiator_init(transactions); } | 100 | { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); } |
| 46 | 101 | ||
| 47 | void serial_slave_init(void) | 102 | void 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 |
| 53 | int serial_update_buffers() | 108 | int 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 | ||
| 107 | static SSTD_t *Transaction_table = NULL; | 224 | static SSTD_t *Transaction_table = NULL; |
| 225 | static uint8_t Transaction_table_size = 0; | ||
| 108 | 226 | ||
| 227 | inline static void serial_delay(void) ALWAYS_INLINE; | ||
| 109 | inline static | 228 | inline static |
| 110 | void serial_delay(void) { | 229 | void serial_delay(void) { |
| 111 | _delay_us(SERIAL_DELAY); | 230 | _delay_us(SERIAL_DELAY); |
| 112 | } | 231 | } |
| 113 | 232 | ||
| 233 | inline static void serial_delay_half1(void) ALWAYS_INLINE; | ||
| 114 | inline static | 234 | inline static |
| 115 | void serial_delay_half1(void) { | 235 | void serial_delay_half1(void) { |
| 116 | _delay_us(SERIAL_DELAY_HALF1); | 236 | _delay_us(SERIAL_DELAY_HALF1); |
| 117 | } | 237 | } |
| 118 | 238 | ||
| 239 | inline static void serial_delay_half2(void) ALWAYS_INLINE; | ||
| 119 | inline static | 240 | inline static |
| 120 | void serial_delay_half2(void) { | 241 | void 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 | ||
| 259 | inline static uint8_t serial_read_pin(void) ALWAYS_INLINE; | ||
| 138 | inline static | 260 | inline static |
| 139 | uint8_t serial_read_pin(void) { | 261 | uint8_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 | ||
| 155 | void soft_serial_initiator_init(SSTD_t *sstd_table) | 277 | void 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 | ||
| 162 | void soft_serial_target_init(SSTD_t *sstd_table) | 285 | void 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. |
| 194 | static void sync_send(void)NO_INLINE; | 314 | static void sync_send(void) NO_INLINE; |
| 195 | static | 315 | static |
| 196 | void sync_send(void) { | 316 | void 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) { | |||
| 230 | void serial_write_chunk(uint8_t data, uint8_t bit) NO_INLINE; | 350 | void serial_write_chunk(uint8_t data, uint8_t bit) NO_INLINE; |
| 231 | void serial_write_chunk(uint8_t data, uint8_t bit) { | 351 | void 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 | ||
| 411 | static 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 |
| 292 | ISR(SERIAL_PIN_INTERRUPT) { | 419 | ISR(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 |
| 351 | int soft_serial_transaction(int sstd_index) { | 481 | int 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) */ |
| 30 | extern 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 |
| 33 | extern 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 | ||
| 36 | void serial_master_init(void); | 42 | void serial_master_init(void); |
| 37 | void serial_slave_init(void); | 43 | void serial_slave_init(void); |
| 38 | int 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 |
| 43 | typedef struct _SSTD_t { | 50 | typedef 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 |
| 52 | void soft_serial_initiator_init(SSTD_t *sstd_table); | 60 | void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size); |
| 53 | // target is interrupt accept side | 61 | // target is interrupt accept side |
| 54 | void soft_serial_target_init(SSTD_t *sstd_table); | 62 | void 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 |
| 61 | int soft_serial_transaction(void); | 70 | int 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 |
| 77 | int soft_serial_get_and_clean_status(int sstd_index); | 86 | int 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 */ |
