diff options
| author | Nick Brassel <nick@tzarc.org> | 2021-06-18 09:10:06 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-18 09:10:06 +1000 |
| commit | 172e6a703041363decd6fc829542f33180c13beb (patch) | |
| tree | a5d4afaa672ab44826865fd76b201e3899083192 /drivers | |
| parent | ef92c9ee2cf4745637635ec1895399e4f013914c (diff) | |
| download | qmk_firmware-172e6a703041363decd6fc829542f33180c13beb.tar.gz qmk_firmware-172e6a703041363decd6fc829542f33180c13beb.zip | |
Extensible split data sync (#11930)
* Extensible split data sync capability through transactions.
- Split common transport has been split up between the transport layer
and data layer.
- Split "transactions" model used, with convergence between I2C and
serial data definitions.
- Slave matrix "generation count" is used to determine if the full slave
matrix needs to be retrieved.
- Encoders get the same "generation count" treatment.
- All other blocks of data are synchronised when a change is detected.
- All transmissions have a globally-configurable deadline before a
transmission is forced (`FORCED_SYNC_THROTTLE_MS`, default 100ms).
- Added atomicity for all core-synced data, preventing partial updates
- Added retries to AVR i2c_master's i2c_start, to minimise the number of
failed transactions when interrupts are disabled on the slave due to
atomicity checks.
- Some keyboards have had slight modifications made in order to ensure
that they still build due to firmware size restrictions.
* Fixup LED_MATRIX compile.
* Parameterise ERROR_DISCONNECT_COUNT.
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/avr/i2c_master.c | 19 | ||||
| -rw-r--r-- | drivers/avr/i2c_slave.c | 29 | ||||
| -rw-r--r-- | drivers/avr/i2c_slave.h | 13 | ||||
| -rw-r--r-- | drivers/avr/serial.c | 82 | ||||
| -rw-r--r-- | drivers/avr/serial.h | 62 | ||||
| -rw-r--r-- | drivers/chibios/serial.c | 52 | ||||
| -rw-r--r-- | drivers/chibios/serial.h | 62 | ||||
| -rw-r--r-- | drivers/chibios/serial_usart.c | 47 | ||||
| -rw-r--r-- | drivers/serial.h | 46 |
9 files changed, 165 insertions, 247 deletions
diff --git a/drivers/avr/i2c_master.c b/drivers/avr/i2c_master.c index b1e488529..2773e0077 100644 --- a/drivers/avr/i2c_master.c +++ b/drivers/avr/i2c_master.c | |||
| @@ -28,8 +28,14 @@ | |||
| 28 | # define F_SCL 400000UL // SCL frequency | 28 | # define F_SCL 400000UL // SCL frequency |
| 29 | #endif | 29 | #endif |
| 30 | 30 | ||
| 31 | #ifndef I2C_START_RETRY_COUNT | ||
| 32 | # define I2C_START_RETRY_COUNT 20 | ||
| 33 | #endif // I2C_START_RETRY_COUNT | ||
| 34 | |||
| 31 | #define TWBR_val (((F_CPU / F_SCL) - 16) / 2) | 35 | #define TWBR_val (((F_CPU / F_SCL) - 16) / 2) |
| 32 | 36 | ||
| 37 | #define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) | ||
| 38 | |||
| 33 | void i2c_init(void) { | 39 | void i2c_init(void) { |
| 34 | TWSR = 0; /* no prescaler */ | 40 | TWSR = 0; /* no prescaler */ |
| 35 | TWBR = (uint8_t)TWBR_val; | 41 | TWBR = (uint8_t)TWBR_val; |
| @@ -47,7 +53,7 @@ void i2c_init(void) { | |||
| 47 | #endif | 53 | #endif |
| 48 | } | 54 | } |
| 49 | 55 | ||
| 50 | i2c_status_t i2c_start(uint8_t address, uint16_t timeout) { | 56 | static i2c_status_t i2c_start_impl(uint8_t address, uint16_t timeout) { |
| 51 | // reset TWI control register | 57 | // reset TWI control register |
| 52 | TWCR = 0; | 58 | TWCR = 0; |
| 53 | // transmit START condition | 59 | // transmit START condition |
| @@ -86,6 +92,17 @@ i2c_status_t i2c_start(uint8_t address, uint16_t timeout) { | |||
| 86 | return I2C_STATUS_SUCCESS; | 92 | return I2C_STATUS_SUCCESS; |
| 87 | } | 93 | } |
| 88 | 94 | ||
| 95 | i2c_status_t i2c_start(uint8_t address, uint16_t timeout) { | ||
| 96 | // Retry i2c_start_impl a bunch times in case the remote side has interrupts disabled. | ||
| 97 | uint16_t timeout_timer = timer_read(); | ||
| 98 | uint16_t time_slice = MAX(1, (timeout == (I2C_TIMEOUT_INFINITE)) ? 5 : (timeout / (I2C_START_RETRY_COUNT))); // if it's infinite, wait 1ms between attempts, otherwise split up the entire timeout into the number of retries | ||
| 99 | i2c_status_t status; | ||
| 100 | do { | ||
| 101 | status = i2c_start_impl(address, time_slice); | ||
| 102 | } while ((status < 0) && ((timeout == I2C_TIMEOUT_INFINITE) || (timer_elapsed(timeout_timer) < timeout))); | ||
| 103 | return status; | ||
| 104 | } | ||
| 105 | |||
| 89 | i2c_status_t i2c_write(uint8_t data, uint16_t timeout) { | 106 | i2c_status_t i2c_write(uint8_t data, uint16_t timeout) { |
| 90 | // load data into data register | 107 | // load data into data register |
| 91 | TWDR = data; | 108 | TWDR = data; |
diff --git a/drivers/avr/i2c_slave.c b/drivers/avr/i2c_slave.c index 62a378165..2907f164c 100644 --- a/drivers/avr/i2c_slave.c +++ b/drivers/avr/i2c_slave.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | * GitHub repository: https://github.com/g4lvanix/I2C-slave-lib | 17 | * GitHub repository: https://github.com/g4lvanix/I2C-slave-lib |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <stddef.h> | ||
| 20 | #include <avr/io.h> | 21 | #include <avr/io.h> |
| 21 | #include <util/twi.h> | 22 | #include <util/twi.h> |
| 22 | #include <avr/interrupt.h> | 23 | #include <avr/interrupt.h> |
| @@ -24,6 +25,12 @@ | |||
| 24 | 25 | ||
| 25 | #include "i2c_slave.h" | 26 | #include "i2c_slave.h" |
| 26 | 27 | ||
| 28 | #if defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) | ||
| 29 | # include "transactions.h" | ||
| 30 | |||
| 31 | static volatile bool is_callback_executor = false; | ||
| 32 | #endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) | ||
| 33 | |||
| 27 | volatile uint8_t i2c_slave_reg[I2C_SLAVE_REG_COUNT]; | 34 | volatile uint8_t i2c_slave_reg[I2C_SLAVE_REG_COUNT]; |
| 28 | 35 | ||
| 29 | static volatile uint8_t buffer_address; | 36 | static volatile uint8_t buffer_address; |
| @@ -48,11 +55,14 @@ ISR(TWI_vect) { | |||
| 48 | case TW_SR_SLA_ACK: | 55 | case TW_SR_SLA_ACK: |
| 49 | // The device is now a slave receiver | 56 | // The device is now a slave receiver |
| 50 | slave_has_register_set = false; | 57 | slave_has_register_set = false; |
| 58 | #if defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) | ||
| 59 | is_callback_executor = false; | ||
| 60 | #endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) | ||
| 51 | break; | 61 | break; |
| 52 | 62 | ||
| 53 | case TW_SR_DATA_ACK: | 63 | case TW_SR_DATA_ACK: |
| 54 | // This device is a slave receiver and has received data | 64 | // This device is a slave receiver and has received data |
| 55 | // First byte is the location then the bytes will be writen in buffer with auto-incriment | 65 | // First byte is the location then the bytes will be writen in buffer with auto-increment |
| 56 | if (!slave_has_register_set) { | 66 | if (!slave_has_register_set) { |
| 57 | buffer_address = TWDR; | 67 | buffer_address = TWDR; |
| 58 | 68 | ||
| @@ -60,10 +70,25 @@ ISR(TWI_vect) { | |||
| 60 | ack = 0; | 70 | ack = 0; |
| 61 | buffer_address = 0; | 71 | buffer_address = 0; |
| 62 | } | 72 | } |
| 63 | slave_has_register_set = true; // address has been receaved now fill in buffer | 73 | slave_has_register_set = true; // address has been received now fill in buffer |
| 74 | |||
| 75 | #if defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) | ||
| 76 | // Work out if we're attempting to execute a callback | ||
| 77 | is_callback_executor = buffer_address == split_transaction_table[I2C_EXECUTE_CALLBACK].initiator2target_offset; | ||
| 78 | #endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) | ||
| 64 | } else { | 79 | } else { |
| 65 | i2c_slave_reg[buffer_address] = TWDR; | 80 | i2c_slave_reg[buffer_address] = TWDR; |
| 66 | buffer_address++; | 81 | buffer_address++; |
| 82 | |||
| 83 | #if defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) | ||
| 84 | // If we're intending to execute a transaction callback, do so, as we've just received the transaction ID | ||
| 85 | if (is_callback_executor) { | ||
| 86 | split_transaction_desc_t *trans = &split_transaction_table[split_shmem->transaction_id]; | ||
| 87 | if (trans->slave_callback) { | ||
| 88 | trans->slave_callback(trans->initiator2target_buffer_size, split_trans_initiator2target_buffer(trans), trans->target2initiator_buffer_size, split_trans_target2initiator_buffer(trans)); | ||
| 89 | } | ||
| 90 | } | ||
| 91 | #endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) | ||
| 67 | } | 92 | } |
| 68 | break; | 93 | break; |
| 69 | 94 | ||
diff --git a/drivers/avr/i2c_slave.h b/drivers/avr/i2c_slave.h index 1cd0625ef..a8647c9da 100644 --- a/drivers/avr/i2c_slave.h +++ b/drivers/avr/i2c_slave.h | |||
| @@ -22,7 +22,18 @@ | |||
| 22 | 22 | ||
| 23 | #pragma once | 23 | #pragma once |
| 24 | 24 | ||
| 25 | #define I2C_SLAVE_REG_COUNT 30 | 25 | #ifndef I2C_SLAVE_REG_COUNT |
| 26 | |||
| 27 | # if defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) | ||
| 28 | # include "transport.h" | ||
| 29 | # define I2C_SLAVE_REG_COUNT sizeof(split_shared_memory_t) | ||
| 30 | # else // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) | ||
| 31 | # define I2C_SLAVE_REG_COUNT 30 | ||
| 32 | # endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) | ||
| 33 | |||
| 34 | #endif // I2C_SLAVE_REG_COUNT | ||
| 35 | |||
| 36 | _Static_assert(I2C_SLAVE_REG_COUNT < 256, "I2C target registers must be single byte"); | ||
| 26 | 37 | ||
| 27 | extern volatile uint8_t i2c_slave_reg[I2C_SLAVE_REG_COUNT]; | 38 | extern volatile uint8_t i2c_slave_reg[I2C_SLAVE_REG_COUNT]; |
| 28 | 39 | ||
diff --git a/drivers/avr/serial.c b/drivers/avr/serial.c index 3647bee0d..9a7345a53 100644 --- a/drivers/avr/serial.c +++ b/drivers/avr/serial.c | |||
| @@ -224,15 +224,8 @@ | |||
| 224 | # define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY / 2) | 224 | # define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY / 2) |
| 225 | 225 | ||
| 226 | # define SLAVE_INT_WIDTH_US 1 | 226 | # define SLAVE_INT_WIDTH_US 1 |
| 227 | # ifndef SERIAL_USE_MULTI_TRANSACTION | 227 | # define SLAVE_INT_ACK_WIDTH_UNIT 2 |
| 228 | # define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY | 228 | # define SLAVE_INT_ACK_WIDTH 4 |
| 229 | # else | ||
| 230 | # define SLAVE_INT_ACK_WIDTH_UNIT 2 | ||
| 231 | # define SLAVE_INT_ACK_WIDTH 4 | ||
| 232 | # endif | ||
| 233 | |||
| 234 | static SSTD_t *Transaction_table = NULL; | ||
| 235 | static uint8_t Transaction_table_size = 0; | ||
| 236 | 229 | ||
| 237 | inline static void serial_delay(void) ALWAYS_INLINE; | 230 | inline static void serial_delay(void) ALWAYS_INLINE; |
| 238 | inline static void serial_delay(void) { _delay_us(SERIAL_DELAY); } | 231 | inline static void serial_delay(void) { _delay_us(SERIAL_DELAY); } |
| @@ -259,16 +252,12 @@ inline static void serial_low(void) { writePinLow(SOFT_SERIAL_PIN); } | |||
| 259 | inline static void serial_high(void) ALWAYS_INLINE; | 252 | inline static void serial_high(void) ALWAYS_INLINE; |
| 260 | inline static void serial_high(void) { writePinHigh(SOFT_SERIAL_PIN); } | 253 | inline static void serial_high(void) { writePinHigh(SOFT_SERIAL_PIN); } |
| 261 | 254 | ||
| 262 | void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size) { | 255 | void soft_serial_initiator_init(void) { |
| 263 | Transaction_table = sstd_table; | ||
| 264 | Transaction_table_size = (uint8_t)sstd_table_size; | ||
| 265 | serial_output(); | 256 | serial_output(); |
| 266 | serial_high(); | 257 | serial_high(); |
| 267 | } | 258 | } |
| 268 | 259 | ||
| 269 | void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size) { | 260 | void soft_serial_target_init(void) { |
| 270 | Transaction_table = sstd_table; | ||
| 271 | Transaction_table_size = (uint8_t)sstd_table_size; | ||
| 272 | serial_input_with_pullup(); | 261 | serial_input_with_pullup(); |
| 273 | 262 | ||
| 274 | // Enable INT0-INT7 | 263 | // Enable INT0-INT7 |
| @@ -395,19 +384,14 @@ static inline uint8_t nibble_bits_count(uint8_t bits) { | |||
| 395 | 384 | ||
| 396 | // interrupt handle to be used by the target device | 385 | // interrupt handle to be used by the target device |
| 397 | ISR(SERIAL_PIN_INTERRUPT) { | 386 | ISR(SERIAL_PIN_INTERRUPT) { |
| 398 | # ifndef SERIAL_USE_MULTI_TRANSACTION | ||
| 399 | serial_low(); | ||
| 400 | serial_output(); | ||
| 401 | SSTD_t *trans = Transaction_table; | ||
| 402 | # else | ||
| 403 | // recive transaction table index | 387 | // recive transaction table index |
| 404 | uint8_t tid, bits; | 388 | uint8_t tid, bits; |
| 405 | uint8_t pecount = 0; | 389 | uint8_t pecount = 0; |
| 406 | sync_recv(); | 390 | sync_recv(); |
| 407 | bits = serial_read_chunk(&pecount, 7); | 391 | bits = serial_read_chunk(&pecount, 8); |
| 408 | tid = bits >> 3; | 392 | tid = bits >> 3; |
| 409 | bits = (bits & 7) != nibble_bits_count(tid); | 393 | bits = (bits & 7) != (nibble_bits_count(tid) & 7); |
| 410 | if (bits || pecount > 0 || tid > Transaction_table_size) { | 394 | if (bits || pecount > 0 || tid > NUM_TOTAL_TRANSACTIONS) { |
| 411 | return; | 395 | return; |
| 412 | } | 396 | } |
| 413 | serial_delay_half1(); | 397 | serial_delay_half1(); |
| @@ -415,18 +399,22 @@ ISR(SERIAL_PIN_INTERRUPT) { | |||
| 415 | serial_high(); // response step1 low->high | 399 | serial_high(); // response step1 low->high |
| 416 | serial_output(); | 400 | serial_output(); |
| 417 | _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT * SLAVE_INT_ACK_WIDTH); | 401 | _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT * SLAVE_INT_ACK_WIDTH); |
| 418 | SSTD_t *trans = &Transaction_table[tid]; | 402 | split_transaction_desc_t *trans = &split_transaction_table[tid]; |
| 419 | serial_low(); // response step2 ack high->low | 403 | serial_low(); // response step2 ack high->low |
| 420 | # endif | 404 | |
| 405 | // If the transaction has a callback, we can execute it now | ||
| 406 | if (trans->slave_callback) { | ||
| 407 | trans->slave_callback(trans->initiator2target_buffer_size, split_trans_initiator2target_buffer(trans), trans->target2initiator_buffer_size, split_trans_target2initiator_buffer(trans)); | ||
| 408 | } | ||
| 421 | 409 | ||
| 422 | // target send phase | 410 | // target send phase |
| 423 | if (trans->target2initiator_buffer_size > 0) serial_send_packet((uint8_t *)trans->target2initiator_buffer, trans->target2initiator_buffer_size); | 411 | if (trans->target2initiator_buffer_size > 0) serial_send_packet((uint8_t *)split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size); |
| 424 | // target switch to input | 412 | // target switch to input |
| 425 | change_sender2reciver(); | 413 | change_sender2reciver(); |
| 426 | 414 | ||
| 427 | // target recive phase | 415 | // target recive phase |
| 428 | if (trans->initiator2target_buffer_size > 0) { | 416 | if (trans->initiator2target_buffer_size > 0) { |
| 429 | if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer, trans->initiator2target_buffer_size)) { | 417 | if (serial_recive_packet((uint8_t *)split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size)) { |
| 430 | *trans->status = TRANSACTION_ACCEPTED; | 418 | *trans->status = TRANSACTION_ACCEPTED; |
| 431 | } else { | 419 | } else { |
| 432 | *trans->status = TRANSACTION_DATA_ERROR; | 420 | *trans->status = TRANSACTION_DATA_ERROR; |
| @@ -448,14 +436,12 @@ ISR(SERIAL_PIN_INTERRUPT) { | |||
| 448 | // TRANSACTION_NO_RESPONSE | 436 | // TRANSACTION_NO_RESPONSE |
| 449 | // TRANSACTION_DATA_ERROR | 437 | // TRANSACTION_DATA_ERROR |
| 450 | // this code is very time dependent, so we need to disable interrupts | 438 | // this code is very time dependent, so we need to disable interrupts |
| 451 | # ifndef SERIAL_USE_MULTI_TRANSACTION | ||
| 452 | int soft_serial_transaction(void) { | ||
| 453 | SSTD_t *trans = Transaction_table; | ||
| 454 | # else | ||
| 455 | int soft_serial_transaction(int sstd_index) { | 439 | int soft_serial_transaction(int sstd_index) { |
| 456 | if (sstd_index > Transaction_table_size) return TRANSACTION_TYPE_ERROR; | 440 | if (sstd_index > NUM_TOTAL_TRANSACTIONS) return TRANSACTION_TYPE_ERROR; |
| 457 | SSTD_t *trans = &Transaction_table[sstd_index]; | 441 | split_transaction_desc_t *trans = &split_transaction_table[sstd_index]; |
| 458 | # endif | 442 | |
| 443 | if (!trans->status) return TRANSACTION_TYPE_ERROR; // not registered | ||
| 444 | |||
| 459 | cli(); | 445 | cli(); |
| 460 | 446 | ||
| 461 | // signal to the target that we want to start a transaction | 447 | // signal to the target that we want to start a transaction |
| @@ -463,27 +449,11 @@ int soft_serial_transaction(int sstd_index) { | |||
| 463 | serial_low(); | 449 | serial_low(); |
| 464 | _delay_us(SLAVE_INT_WIDTH_US); | 450 | _delay_us(SLAVE_INT_WIDTH_US); |
| 465 | 451 | ||
| 466 | # ifndef SERIAL_USE_MULTI_TRANSACTION | ||
| 467 | // wait for the target response | ||
| 468 | serial_input_with_pullup(); | ||
| 469 | _delay_us(SLAVE_INT_RESPONSE_TIME); | ||
| 470 | |||
| 471 | // check if the target is present | ||
| 472 | if (serial_read_pin()) { | ||
| 473 | // target failed to pull the line low, assume not present | ||
| 474 | serial_output(); | ||
| 475 | serial_high(); | ||
| 476 | *trans->status = TRANSACTION_NO_RESPONSE; | ||
| 477 | sei(); | ||
| 478 | return TRANSACTION_NO_RESPONSE; | ||
| 479 | } | ||
| 480 | |||
| 481 | # else | ||
| 482 | // send transaction table index | 452 | // send transaction table index |
| 483 | int tid = (sstd_index << 3) | (7 & nibble_bits_count(sstd_index)); | 453 | int tid = (sstd_index << 3) | (7 & nibble_bits_count(sstd_index)); |
| 484 | sync_send(); | 454 | sync_send(); |
| 485 | _delay_sub_us(TID_SEND_ADJUST); | 455 | _delay_sub_us(TID_SEND_ADJUST); |
| 486 | serial_write_chunk(tid, 7); | 456 | serial_write_chunk(tid, 8); |
| 487 | serial_delay_half1(); | 457 | serial_delay_half1(); |
| 488 | 458 | ||
| 489 | // wait for the target response (step1 low->high) | 459 | // wait for the target response (step1 low->high) |
| @@ -504,12 +474,11 @@ int soft_serial_transaction(int sstd_index) { | |||
| 504 | } | 474 | } |
| 505 | _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT); | 475 | _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT); |
| 506 | } | 476 | } |
| 507 | # endif | ||
| 508 | 477 | ||
| 509 | // initiator recive phase | 478 | // initiator recive phase |
| 510 | // if the target is present syncronize with it | 479 | // if the target is present syncronize with it |
| 511 | if (trans->target2initiator_buffer_size > 0) { | 480 | if (trans->target2initiator_buffer_size > 0) { |
| 512 | if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer, trans->target2initiator_buffer_size)) { | 481 | if (!serial_recive_packet((uint8_t *)split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size)) { |
| 513 | serial_output(); | 482 | serial_output(); |
| 514 | serial_high(); | 483 | serial_high(); |
| 515 | *trans->status = TRANSACTION_DATA_ERROR; | 484 | *trans->status = TRANSACTION_DATA_ERROR; |
| @@ -523,7 +492,7 @@ int soft_serial_transaction(int sstd_index) { | |||
| 523 | 492 | ||
| 524 | // initiator send phase | 493 | // initiator send phase |
| 525 | if (trans->initiator2target_buffer_size > 0) { | 494 | if (trans->initiator2target_buffer_size > 0) { |
| 526 | serial_send_packet((uint8_t *)trans->initiator2target_buffer, trans->initiator2target_buffer_size); | 495 | serial_send_packet((uint8_t *)split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size); |
| 527 | } | 496 | } |
| 528 | 497 | ||
| 529 | // always, release the line when not in use | 498 | // always, release the line when not in use |
| @@ -534,9 +503,8 @@ int soft_serial_transaction(int sstd_index) { | |||
| 534 | return TRANSACTION_END; | 503 | return TRANSACTION_END; |
| 535 | } | 504 | } |
| 536 | 505 | ||
| 537 | # ifdef SERIAL_USE_MULTI_TRANSACTION | ||
| 538 | int soft_serial_get_and_clean_status(int sstd_index) { | 506 | int soft_serial_get_and_clean_status(int sstd_index) { |
| 539 | SSTD_t *trans = &Transaction_table[sstd_index]; | 507 | split_transaction_desc_t *trans = &split_transaction_table[sstd_index]; |
| 540 | cli(); | 508 | cli(); |
| 541 | int retval = *trans->status; | 509 | int retval = *trans->status; |
| 542 | *trans->status = 0; | 510 | *trans->status = 0; |
| @@ -544,8 +512,6 @@ int soft_serial_get_and_clean_status(int sstd_index) { | |||
| 544 | sei(); | 512 | sei(); |
| 545 | return retval; | 513 | return retval; |
| 546 | } | 514 | } |
| 547 | # endif | ||
| 548 | |||
| 549 | #endif | 515 | #endif |
| 550 | 516 | ||
| 551 | // Helix serial.c history | 517 | // Helix serial.c history |
diff --git a/drivers/avr/serial.h b/drivers/avr/serial.h deleted file mode 100644 index 53e66cf90..000000000 --- a/drivers/avr/serial.h +++ /dev/null | |||
| @@ -1,62 +0,0 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <stdbool.h> | ||
| 4 | |||
| 5 | // ///////////////////////////////////////////////////////////////// | ||
| 6 | // Need Soft Serial defines in config.h | ||
| 7 | // ///////////////////////////////////////////////////////////////// | ||
| 8 | // ex. | ||
| 9 | // #define SOFT_SERIAL_PIN ?? // ?? = D0,D1,D2,D3,E6 | ||
| 10 | // OPTIONAL: #define SELECT_SOFT_SERIAL_SPEED ? // ? = 1,2,3,4,5 | ||
| 11 | // // 1: about 137kbps (default) | ||
| 12 | // // 2: about 75kbps | ||
| 13 | // // 3: about 39kbps | ||
| 14 | // // 4: about 26kbps | ||
| 15 | // // 5: about 20kbps | ||
| 16 | // | ||
| 17 | // //// USE simple API (using signle-type transaction function) | ||
| 18 | // /* nothing */ | ||
| 19 | // //// USE flexible API (using multi-type transaction function) | ||
| 20 | // #define SERIAL_USE_MULTI_TRANSACTION | ||
| 21 | // | ||
| 22 | // ///////////////////////////////////////////////////////////////// | ||
| 23 | |||
| 24 | // Soft Serial Transaction Descriptor | ||
| 25 | typedef struct _SSTD_t { | ||
| 26 | uint8_t *status; | ||
| 27 | uint8_t initiator2target_buffer_size; | ||
| 28 | uint8_t *initiator2target_buffer; | ||
| 29 | uint8_t target2initiator_buffer_size; | ||
| 30 | uint8_t *target2initiator_buffer; | ||
| 31 | } SSTD_t; | ||
| 32 | #define TID_LIMIT(table) (sizeof(table) / sizeof(SSTD_t)) | ||
| 33 | |||
| 34 | // initiator is transaction start side | ||
| 35 | void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size); | ||
| 36 | // target is interrupt accept side | ||
| 37 | void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size); | ||
| 38 | |||
| 39 | // initiator resullt | ||
| 40 | #define TRANSACTION_END 0 | ||
| 41 | #define TRANSACTION_NO_RESPONSE 0x1 | ||
| 42 | #define TRANSACTION_DATA_ERROR 0x2 | ||
| 43 | #define TRANSACTION_TYPE_ERROR 0x4 | ||
| 44 | #ifndef SERIAL_USE_MULTI_TRANSACTION | ||
| 45 | int soft_serial_transaction(void); | ||
| 46 | #else | ||
| 47 | int soft_serial_transaction(int sstd_index); | ||
| 48 | #endif | ||
| 49 | |||
| 50 | // target status | ||
| 51 | // *SSTD_t.status has | ||
| 52 | // initiator: | ||
| 53 | // TRANSACTION_END | ||
| 54 | // or TRANSACTION_NO_RESPONSE | ||
| 55 | // or TRANSACTION_DATA_ERROR | ||
| 56 | // target: | ||
| 57 | // TRANSACTION_DATA_ERROR | ||
| 58 | // or TRANSACTION_ACCEPTED | ||
| 59 | #define TRANSACTION_ACCEPTED 0x8 | ||
| 60 | #ifdef SERIAL_USE_MULTI_TRANSACTION | ||
| 61 | int soft_serial_get_and_clean_status(int sstd_index); | ||
| 62 | #endif | ||
diff --git a/drivers/chibios/serial.c b/drivers/chibios/serial.c index 54f7e1321..f54fbcee4 100644 --- a/drivers/chibios/serial.c +++ b/drivers/chibios/serial.c | |||
| @@ -74,21 +74,12 @@ static THD_FUNCTION(Thread1, arg) { | |||
| 74 | } | 74 | } |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | static SSTD_t *Transaction_table = NULL; | 77 | void soft_serial_initiator_init(void) { |
| 78 | static uint8_t Transaction_table_size = 0; | ||
| 79 | |||
| 80 | void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size) { | ||
| 81 | Transaction_table = sstd_table; | ||
| 82 | Transaction_table_size = (uint8_t)sstd_table_size; | ||
| 83 | |||
| 84 | serial_output(); | 78 | serial_output(); |
| 85 | serial_high(); | 79 | serial_high(); |
| 86 | } | 80 | } |
| 87 | 81 | ||
| 88 | void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size) { | 82 | void soft_serial_target_init(void) { |
| 89 | Transaction_table = sstd_table; | ||
| 90 | Transaction_table_size = (uint8_t)sstd_table_size; | ||
| 91 | |||
| 92 | serial_input(); | 83 | serial_input(); |
| 93 | 84 | ||
| 94 | palEnablePadEvent(PAL_PORT(SOFT_SERIAL_PIN), PAL_PAD(SOFT_SERIAL_PIN), PAL_EVENT_MODE_FALLING_EDGE); | 85 | palEnablePadEvent(PAL_PORT(SOFT_SERIAL_PIN), PAL_PAD(SOFT_SERIAL_PIN), PAL_EVENT_MODE_FALLING_EDGE); |
| @@ -154,16 +145,14 @@ void interrupt_handler(void *arg) { | |||
| 154 | uint8_t checksum_computed = 0; | 145 | uint8_t checksum_computed = 0; |
| 155 | int sstd_index = 0; | 146 | int sstd_index = 0; |
| 156 | 147 | ||
| 157 | #ifdef SERIAL_USE_MULTI_TRANSACTION | ||
| 158 | sstd_index = serial_read_byte(); | 148 | sstd_index = serial_read_byte(); |
| 159 | sync_send(); | 149 | sync_send(); |
| 160 | #endif | ||
| 161 | 150 | ||
| 162 | SSTD_t *trans = &Transaction_table[sstd_index]; | 151 | split_transaction_desc_t *trans = &split_transaction_table[sstd_index]; |
| 163 | for (int i = 0; i < trans->initiator2target_buffer_size; ++i) { | 152 | for (int i = 0; i < trans->initiator2target_buffer_size; ++i) { |
| 164 | trans->initiator2target_buffer[i] = serial_read_byte(); | 153 | split_trans_initiator2target_buffer(trans)[i] = serial_read_byte(); |
| 165 | sync_send(); | 154 | sync_send(); |
| 166 | checksum_computed += trans->initiator2target_buffer[i]; | 155 | checksum_computed += split_trans_initiator2target_buffer(trans)[i]; |
| 167 | } | 156 | } |
| 168 | checksum_computed ^= 7; | 157 | checksum_computed ^= 7; |
| 169 | uint8_t checksum_received = serial_read_byte(); | 158 | uint8_t checksum_received = serial_read_byte(); |
| @@ -172,12 +161,17 @@ void interrupt_handler(void *arg) { | |||
| 172 | // wait for the sync to finish sending | 161 | // wait for the sync to finish sending |
| 173 | serial_delay(); | 162 | serial_delay(); |
| 174 | 163 | ||
| 164 | // Allow any slave processing to occur | ||
| 165 | if (trans->slave_callback) { | ||
| 166 | trans->slave_callback(trans->initiator2target_buffer_size, split_trans_initiator2target_buffer(trans), trans->target2initiator_buffer_size, split_trans_target2initiator_buffer(trans)); | ||
| 167 | } | ||
| 168 | |||
| 175 | uint8_t checksum = 0; | 169 | uint8_t checksum = 0; |
| 176 | for (int i = 0; i < trans->target2initiator_buffer_size; ++i) { | 170 | for (int i = 0; i < trans->target2initiator_buffer_size; ++i) { |
| 177 | serial_write_byte(trans->target2initiator_buffer[i]); | 171 | serial_write_byte(split_trans_target2initiator_buffer(trans)[i]); |
| 178 | sync_send(); | 172 | sync_send(); |
| 179 | serial_delay_half(); | 173 | serial_delay_half(); |
| 180 | checksum += trans->target2initiator_buffer[i]; | 174 | checksum += split_trans_target2initiator_buffer(trans)[i]; |
| 181 | } | 175 | } |
| 182 | serial_write_byte(checksum ^ 7); | 176 | serial_write_byte(checksum ^ 7); |
| 183 | sync_send(); | 177 | sync_send(); |
| @@ -206,15 +200,10 @@ void interrupt_handler(void *arg) { | |||
| 206 | // TRANSACTION_NO_RESPONSE | 200 | // TRANSACTION_NO_RESPONSE |
| 207 | // TRANSACTION_DATA_ERROR | 201 | // TRANSACTION_DATA_ERROR |
| 208 | // this code is very time dependent, so we need to disable interrupts | 202 | // this code is very time dependent, so we need to disable interrupts |
| 209 | #ifndef SERIAL_USE_MULTI_TRANSACTION | ||
| 210 | int soft_serial_transaction(void) { | ||
| 211 | int sstd_index = 0; | ||
| 212 | #else | ||
| 213 | int soft_serial_transaction(int sstd_index) { | 203 | int soft_serial_transaction(int sstd_index) { |
| 214 | #endif | 204 | if (sstd_index > NUM_TOTAL_TRANSACTIONS) return TRANSACTION_TYPE_ERROR; |
| 215 | 205 | split_transaction_desc_t *trans = &split_transaction_table[sstd_index]; | |
| 216 | if (sstd_index > Transaction_table_size) return TRANSACTION_TYPE_ERROR; | 206 | if (!trans->status) return TRANSACTION_TYPE_ERROR; // not registered |
| 217 | SSTD_t *trans = &Transaction_table[sstd_index]; | ||
| 218 | 207 | ||
| 219 | // TODO: remove extra delay between transactions | 208 | // TODO: remove extra delay between transactions |
| 220 | serial_delay(); | 209 | serial_delay(); |
| @@ -244,14 +233,13 @@ int soft_serial_transaction(int sstd_index) { | |||
| 244 | 233 | ||
| 245 | uint8_t checksum = 0; | 234 | uint8_t checksum = 0; |
| 246 | // send data to the slave | 235 | // send data to the slave |
| 247 | #ifdef SERIAL_USE_MULTI_TRANSACTION | ||
| 248 | serial_write_byte(sstd_index); // first chunk is transaction id | 236 | serial_write_byte(sstd_index); // first chunk is transaction id |
| 249 | sync_recv(); | 237 | sync_recv(); |
| 250 | #endif | 238 | |
| 251 | for (int i = 0; i < trans->initiator2target_buffer_size; ++i) { | 239 | for (int i = 0; i < trans->initiator2target_buffer_size; ++i) { |
| 252 | serial_write_byte(trans->initiator2target_buffer[i]); | 240 | serial_write_byte(split_trans_initiator2target_buffer(trans)[i]); |
| 253 | sync_recv(); | 241 | sync_recv(); |
| 254 | checksum += trans->initiator2target_buffer[i]; | 242 | checksum += split_trans_initiator2target_buffer(trans)[i]; |
| 255 | } | 243 | } |
| 256 | serial_write_byte(checksum ^ 7); | 244 | serial_write_byte(checksum ^ 7); |
| 257 | sync_recv(); | 245 | sync_recv(); |
| @@ -262,9 +250,9 @@ int soft_serial_transaction(int sstd_index) { | |||
| 262 | // receive data from the slave | 250 | // receive data from the slave |
| 263 | uint8_t checksum_computed = 0; | 251 | uint8_t checksum_computed = 0; |
| 264 | for (int i = 0; i < trans->target2initiator_buffer_size; ++i) { | 252 | for (int i = 0; i < trans->target2initiator_buffer_size; ++i) { |
| 265 | trans->target2initiator_buffer[i] = serial_read_byte(); | 253 | split_trans_target2initiator_buffer(trans)[i] = serial_read_byte(); |
| 266 | sync_recv(); | 254 | sync_recv(); |
| 267 | checksum_computed += trans->target2initiator_buffer[i]; | 255 | checksum_computed += split_trans_target2initiator_buffer(trans)[i]; |
| 268 | } | 256 | } |
| 269 | checksum_computed ^= 7; | 257 | checksum_computed ^= 7; |
| 270 | uint8_t checksum_received = serial_read_byte(); | 258 | uint8_t checksum_received = serial_read_byte(); |
diff --git a/drivers/chibios/serial.h b/drivers/chibios/serial.h deleted file mode 100644 index 0c1857d52..000000000 --- a/drivers/chibios/serial.h +++ /dev/null | |||
| @@ -1,62 +0,0 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <stdbool.h> | ||
| 4 | |||
| 5 | // ///////////////////////////////////////////////////////////////// | ||
| 6 | // Need Soft Serial defines in config.h | ||
| 7 | // ///////////////////////////////////////////////////////////////// | ||
| 8 | // ex. | ||
| 9 | // #define SOFT_SERIAL_PIN ?? // ?? = D0,D1,D2,D3,E6 | ||
| 10 | // OPTIONAL: #define SELECT_SOFT_SERIAL_SPEED ? // ? = 1,2,3,4,5 | ||
| 11 | // // 1: about 137kbps (default) | ||
| 12 | // // 2: about 75kbps | ||
| 13 | // // 3: about 39kbps | ||
| 14 | // // 4: about 26kbps | ||
| 15 | // // 5: about 20kbps | ||
| 16 | // | ||
| 17 | // //// USE simple API (using signle-type transaction function) | ||
| 18 | // /* nothing */ | ||
| 19 | // //// USE flexible API (using multi-type transaction function) | ||
| 20 | // #define SERIAL_USE_MULTI_TRANSACTION | ||
| 21 | // | ||
| 22 | // ///////////////////////////////////////////////////////////////// | ||
| 23 | |||
| 24 | // Soft Serial Transaction Descriptor | ||
| 25 | typedef struct _SSTD_t { | ||
| 26 | uint8_t *status; | ||
| 27 | uint8_t initiator2target_buffer_size; | ||
| 28 | uint8_t *initiator2target_buffer; | ||
| 29 | uint8_t target2initiator_buffer_size; | ||
| 30 | uint8_t *target2initiator_buffer; | ||
| 31 | } SSTD_t; | ||
| 32 | #define TID_LIMIT(table) (sizeof(table) / sizeof(SSTD_t)) | ||
| 33 | |||
| 34 | // initiator is transaction start side | ||
| 35 | void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size); | ||
| 36 | // target is interrupt accept side | ||
| 37 | void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size); | ||
| 38 | |||
| 39 | // initiator result | ||
| 40 | #define TRANSACTION_END 0 | ||
| 41 | #define TRANSACTION_NO_RESPONSE 0x1 | ||
| 42 | #define TRANSACTION_DATA_ERROR 0x2 | ||
| 43 | #define TRANSACTION_TYPE_ERROR 0x4 | ||
| 44 | #ifndef SERIAL_USE_MULTI_TRANSACTION | ||
| 45 | int soft_serial_transaction(void); | ||
| 46 | #else | ||
| 47 | int soft_serial_transaction(int sstd_index); | ||
| 48 | #endif | ||
| 49 | |||
| 50 | // target status | ||
| 51 | // *SSTD_t.status has | ||
| 52 | // initiator: | ||
| 53 | // TRANSACTION_END | ||
| 54 | // or TRANSACTION_NO_RESPONSE | ||
| 55 | // or TRANSACTION_DATA_ERROR | ||
| 56 | // target: | ||
| 57 | // TRANSACTION_DATA_ERROR | ||
| 58 | // or TRANSACTION_ACCEPTED | ||
| 59 | #define TRANSACTION_ACCEPTED 0x8 | ||
| 60 | #ifdef SERIAL_USE_MULTI_TRANSACTION | ||
| 61 | int soft_serial_get_and_clean_status(int sstd_index); | ||
| 62 | #endif | ||
diff --git a/drivers/chibios/serial_usart.c b/drivers/chibios/serial_usart.c index cae29388c..9f180d2d7 100644 --- a/drivers/chibios/serial_usart.c +++ b/drivers/chibios/serial_usart.c | |||
| @@ -113,37 +113,29 @@ void usart_slave_init(void) { | |||
| 113 | chThdCreateStatic(waSlaveThread, sizeof(waSlaveThread), HIGHPRIO, SlaveThread, NULL); | 113 | chThdCreateStatic(waSlaveThread, sizeof(waSlaveThread), HIGHPRIO, SlaveThread, NULL); |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | static SSTD_t* Transaction_table = NULL; | 116 | void soft_serial_initiator_init(void) { usart_master_init(); } |
| 117 | static uint8_t Transaction_table_size = 0; | ||
| 118 | 117 | ||
| 119 | void soft_serial_initiator_init(SSTD_t* sstd_table, int sstd_table_size) { | 118 | void soft_serial_target_init(void) { usart_slave_init(); } |
| 120 | Transaction_table = sstd_table; | ||
| 121 | Transaction_table_size = (uint8_t)sstd_table_size; | ||
| 122 | |||
| 123 | usart_master_init(); | ||
| 124 | } | ||
| 125 | |||
| 126 | void soft_serial_target_init(SSTD_t* sstd_table, int sstd_table_size) { | ||
| 127 | Transaction_table = sstd_table; | ||
| 128 | Transaction_table_size = (uint8_t)sstd_table_size; | ||
| 129 | |||
| 130 | usart_slave_init(); | ||
| 131 | } | ||
| 132 | 119 | ||
| 133 | void handle_soft_serial_slave(void) { | 120 | void handle_soft_serial_slave(void) { |
| 134 | uint8_t sstd_index = sdGet(&SERIAL_USART_DRIVER); // first chunk is always transaction id | 121 | uint8_t sstd_index = sdGet(&SERIAL_USART_DRIVER); // first chunk is always transaction id |
| 135 | SSTD_t* trans = &Transaction_table[sstd_index]; | 122 | split_transaction_desc_t* trans = &split_transaction_table[sstd_index]; |
| 136 | 123 | ||
| 137 | // Always write back the sstd_index as part of a basic handshake | 124 | // Always write back the sstd_index as part of a basic handshake |
| 138 | sstd_index ^= HANDSHAKE_MAGIC; | 125 | sstd_index ^= HANDSHAKE_MAGIC; |
| 139 | sdWrite(&SERIAL_USART_DRIVER, &sstd_index, sizeof(sstd_index)); | 126 | sdWrite(&SERIAL_USART_DRIVER, &sstd_index, sizeof(sstd_index)); |
| 140 | 127 | ||
| 141 | if (trans->initiator2target_buffer_size) { | 128 | if (trans->initiator2target_buffer_size) { |
| 142 | sdRead(&SERIAL_USART_DRIVER, trans->initiator2target_buffer, trans->initiator2target_buffer_size); | 129 | sdRead(&SERIAL_USART_DRIVER, split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size); |
| 130 | } | ||
| 131 | |||
| 132 | // Allow any slave processing to occur | ||
| 133 | if (trans->slave_callback) { | ||
| 134 | trans->slave_callback(trans->initiator2target_buffer_size, split_trans_initiator2target_buffer(trans), trans->target2initiator_buffer_size, split_trans_target2initiator_buffer(trans)); | ||
| 143 | } | 135 | } |
| 144 | 136 | ||
| 145 | if (trans->target2initiator_buffer_size) { | 137 | if (trans->target2initiator_buffer_size) { |
| 146 | sdWrite(&SERIAL_USART_DRIVER, trans->target2initiator_buffer, trans->target2initiator_buffer_size); | 138 | sdWrite(&SERIAL_USART_DRIVER, split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size); |
| 147 | } | 139 | } |
| 148 | 140 | ||
| 149 | if (trans->status) { | 141 | if (trans->status) { |
| @@ -160,17 +152,14 @@ void handle_soft_serial_slave(void) { | |||
| 160 | // TRANSACTION_END | 152 | // TRANSACTION_END |
| 161 | // TRANSACTION_NO_RESPONSE | 153 | // TRANSACTION_NO_RESPONSE |
| 162 | // TRANSACTION_DATA_ERROR | 154 | // TRANSACTION_DATA_ERROR |
| 163 | #ifndef SERIAL_USE_MULTI_TRANSACTION | ||
| 164 | int soft_serial_transaction(void) { | ||
| 165 | uint8_t sstd_index = 0; | ||
| 166 | #else | ||
| 167 | int soft_serial_transaction(int index) { | 155 | int soft_serial_transaction(int index) { |
| 168 | uint8_t sstd_index = index; | 156 | uint8_t sstd_index = index; |
| 169 | #endif | ||
| 170 | 157 | ||
| 171 | if (sstd_index > Transaction_table_size) return TRANSACTION_TYPE_ERROR; | 158 | if (sstd_index > NUM_TOTAL_TRANSACTIONS) return TRANSACTION_TYPE_ERROR; |
| 172 | SSTD_t* trans = &Transaction_table[sstd_index]; | 159 | split_transaction_desc_t* trans = &split_transaction_table[sstd_index]; |
| 173 | msg_t res = 0; | 160 | msg_t res = 0; |
| 161 | |||
| 162 | if (!trans->status) return TRANSACTION_TYPE_ERROR; // not registered | ||
| 174 | 163 | ||
| 175 | sdClear(&SERIAL_USART_DRIVER); | 164 | sdClear(&SERIAL_USART_DRIVER); |
| 176 | 165 | ||
| @@ -189,7 +178,7 @@ int soft_serial_transaction(int index) { | |||
| 189 | } | 178 | } |
| 190 | 179 | ||
| 191 | if (trans->initiator2target_buffer_size) { | 180 | if (trans->initiator2target_buffer_size) { |
| 192 | res = sdWriteTimeout(&SERIAL_USART_DRIVER, trans->initiator2target_buffer, trans->initiator2target_buffer_size, TIME_MS2I(SERIAL_USART_TIMEOUT)); | 181 | res = sdWriteTimeout(&SERIAL_USART_DRIVER, split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size, TIME_MS2I(SERIAL_USART_TIMEOUT)); |
| 193 | if (res < 0) { | 182 | if (res < 0) { |
| 194 | dprintf("serial::usart_transmit NO_RESPONSE\n"); | 183 | dprintf("serial::usart_transmit NO_RESPONSE\n"); |
| 195 | return TRANSACTION_NO_RESPONSE; | 184 | return TRANSACTION_NO_RESPONSE; |
| @@ -197,7 +186,7 @@ int soft_serial_transaction(int index) { | |||
| 197 | } | 186 | } |
| 198 | 187 | ||
| 199 | if (trans->target2initiator_buffer_size) { | 188 | if (trans->target2initiator_buffer_size) { |
| 200 | res = sdReadTimeout(&SERIAL_USART_DRIVER, trans->target2initiator_buffer, trans->target2initiator_buffer_size, TIME_MS2I(SERIAL_USART_TIMEOUT)); | 189 | res = sdReadTimeout(&SERIAL_USART_DRIVER, split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size, TIME_MS2I(SERIAL_USART_TIMEOUT)); |
| 201 | if (res < 0) { | 190 | if (res < 0) { |
| 202 | dprintf("serial::usart_receive NO_RESPONSE\n"); | 191 | dprintf("serial::usart_receive NO_RESPONSE\n"); |
| 203 | return TRANSACTION_NO_RESPONSE; | 192 | return TRANSACTION_NO_RESPONSE; |
diff --git a/drivers/serial.h b/drivers/serial.h new file mode 100644 index 000000000..d9c2a69e9 --- /dev/null +++ b/drivers/serial.h | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | /* Copyright 2021 QMK | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #pragma once | ||
| 18 | |||
| 19 | #include <stdint.h> | ||
| 20 | #include <stdbool.h> | ||
| 21 | |||
| 22 | #include <transactions.h> | ||
| 23 | |||
| 24 | // initiator is transaction start side | ||
| 25 | void soft_serial_initiator_init(void); | ||
| 26 | // target is interrupt accept side | ||
| 27 | void soft_serial_target_init(void); | ||
| 28 | |||
| 29 | // initiator result | ||
| 30 | #define TRANSACTION_END 0 | ||
| 31 | #define TRANSACTION_NO_RESPONSE 0x1 | ||
| 32 | #define TRANSACTION_DATA_ERROR 0x2 | ||
| 33 | #define TRANSACTION_TYPE_ERROR 0x4 | ||
| 34 | int soft_serial_transaction(int sstd_index); | ||
| 35 | |||
| 36 | // target status | ||
| 37 | // *SSTD_t.status has | ||
| 38 | // initiator: | ||
| 39 | // TRANSACTION_END | ||
| 40 | // or TRANSACTION_NO_RESPONSE | ||
| 41 | // or TRANSACTION_DATA_ERROR | ||
| 42 | // target: | ||
| 43 | // TRANSACTION_DATA_ERROR | ||
| 44 | // or TRANSACTION_ACCEPTED | ||
| 45 | #define TRANSACTION_ACCEPTED 0x8 | ||
| 46 | int soft_serial_get_and_clean_status(int sstd_index); | ||
