From 2b4f7d3400e156b971ed53d8561c63fc60893c1b Mon Sep 17 00:00:00 2001 From: mtei <2170248+mtei@users.noreply.github.com> Date: Sun, 22 Jul 2018 18:03:33 +0900 Subject: [PATCH] serial.c: multiple types of transaction support Add 4 bits transaction-type field at packet top. Select Transaction Descriptor Table entry by transaction-type. --- .../rev1/keymaps/OLED_sample/serial_config.h | 3 +- keyboards/helix/rev1/serial_config.h | 2 + keyboards/helix/rev1/split_scomm.c | 4 +- keyboards/helix/rev2/serial_config.h | 3 + keyboards/helix/rev2/split_scomm.c | 14 ++- keyboards/helix/serial.c | 93 +++++++++++++++++-- keyboards/helix/serial.h | 24 +++-- 7 files changed, 125 insertions(+), 18 deletions(-) diff --git a/keyboards/helix/rev1/keymaps/OLED_sample/serial_config.h b/keyboards/helix/rev1/keymaps/OLED_sample/serial_config.h index be2e7cb8b1..009052fa8a 100644 --- a/keyboards/helix/rev1/keymaps/OLED_sample/serial_config.h +++ b/keyboards/helix/rev1/keymaps/OLED_sample/serial_config.h @@ -8,8 +8,7 @@ #define SERIAL_PIN_MASK _BV(PD2) #define SERIAL_PIN_INTERRUPT INT2_vect -#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 -#define SERIAL_MASTER_BUFFER_LENGTH 1 +#define SERIAL_USE_SIMPLE_TRANSACTION //// #error rev1/keymaps/OLED_sample serial config diff --git a/keyboards/helix/rev1/serial_config.h b/keyboards/helix/rev1/serial_config.h index f021d6e04b..36e60305e2 100644 --- a/keyboards/helix/rev1/serial_config.h +++ b/keyboards/helix/rev1/serial_config.h @@ -8,6 +8,8 @@ #define SERIAL_PIN_MASK _BV(PD0) #define SERIAL_PIN_INTERRUPT INT0_vect +#define SERIAL_USE_SIMPLE_TRANSACTION + /// #error rev1 serial config #endif /* SOFT_SERIAL_CONFIG_H */ diff --git a/keyboards/helix/rev1/split_scomm.c b/keyboards/helix/rev1/split_scomm.c index 14491abe84..a5c0485e30 100644 --- a/keyboards/helix/rev1/split_scomm.c +++ b/keyboards/helix/rev1/split_scomm.c @@ -10,8 +10,6 @@ uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; uint8_t volatile status0 = 0; SSTD_t transactions[] = { - -#define WHOLE_MATRIX_EXCHANGE 0 { (uint8_t *)&status0, sizeof(serial_master_buffer), (uint8_t *)serial_master_buffer, sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer @@ -33,6 +31,6 @@ void serial_slave_init(void) // 2 => checksum error int serial_update_buffers(int master_update) { - return soft_serial_transaction(WHOLE_MATRIX_EXCHANGE); + return soft_serial_transaction(); } #endif /* USE_SERIAL */ diff --git a/keyboards/helix/rev2/serial_config.h b/keyboards/helix/rev2/serial_config.h index d93419e4a3..9664ba159f 100644 --- a/keyboards/helix/rev2/serial_config.h +++ b/keyboards/helix/rev2/serial_config.h @@ -8,6 +8,9 @@ #define SERIAL_PIN_MASK _BV(PD2) #define SERIAL_PIN_INTERRUPT INT2_vect +// if you need more program area, use this macro +// #define SERIAL_USE_SIMPLE_TRANSACTION + //// #error rev2 serial config #endif /* SOFT_SERIAL_CONFIG_H */ diff --git a/keyboards/helix/rev2/split_scomm.c b/keyboards/helix/rev2/split_scomm.c index 14491abe84..1ddd9b8b7d 100644 --- a/keyboards/helix/rev2/split_scomm.c +++ b/keyboards/helix/rev2/split_scomm.c @@ -9,14 +9,22 @@ uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; uint8_t volatile status0 = 0; +#ifdef SERIAL_USE_SIMPLE_TRANSACTION +SSTD_t transactions[] = { + { (uint8_t *)&status0, + sizeof(serial_master_buffer), (uint8_t *)serial_master_buffer, + sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer + } +}; +#else SSTD_t transactions[] = { - #define WHOLE_MATRIX_EXCHANGE 0 { (uint8_t *)&status0, sizeof(serial_master_buffer), (uint8_t *)serial_master_buffer, sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer } }; +#endif void serial_master_init(void) { @@ -33,6 +41,10 @@ void serial_slave_init(void) // 2 => checksum error int serial_update_buffers(int master_update) { +#ifdef SERIAL_USE_SIMPLE_TRANSACTION + return soft_serial_transaction(); +#else return soft_serial_transaction(WHOLE_MATRIX_EXCHANGE); +#endif } #endif /* USE_SERIAL */ diff --git a/keyboards/helix/serial.c b/keyboards/helix/serial.c index 930c975d27..0870ddf106 100644 --- a/keyboards/helix/serial.c +++ b/keyboards/helix/serial.c @@ -21,6 +21,8 @@ #define _delay_sub_us(x) __builtin_avr_delay_cycles(x) // Serial pulse period in microseconds. +#define TID_SEND_ADJUST 14 + #define SELECT_SERIAL_SPEED 1 #if SELECT_SERIAL_SPEED == 0 // Very High speed @@ -55,8 +57,13 @@ #define SERIAL_DELAY_HALF1 (SERIAL_DELAY/2) #define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY/2) -#define SLAVE_INT_WIDTH 1 -#define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY +#define SLAVE_INT_WIDTH_US 1 +#ifdef SERIAL_USE_SIMPLE_TRANSACTION + #define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY +#else + #define SLAVE_INT_ACK_WIDTH_UNIT 2 + #define SLAVE_INT_ACK_WIDTH 4 +#endif static SSTD_t *Transaction_table = NULL; @@ -272,10 +279,31 @@ void change_reciver2sender(void) { // interrupt handle to be used by the target device ISR(SERIAL_PIN_INTERRUPT) { debug_output_mode(); debug_input_mode(); // indicate intterupt entry + debug_recvsample(); debug_recvsample(); // indicate intterupt entry + debug_sync_start(); debug_sync_end(); // indicate intterupt entry +#ifdef SERIAL_USE_SIMPLE_TRANSACTION serial_low(); serial_output(); SSTD_t *trans = Transaction_table; +#else + // recive transaction table index + uint8_t tid; + uint8_t pecount = 0; + sync_recv(); + debug_bytewidth_start(); + tid = serial_read_chunk(&pecount,4); + debug_bytewidth_end(); + if(pecount> 0) + return; + serial_delay_half1(); + + serial_high(); // response step1 low->high + serial_output(); + _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT*SLAVE_INT_ACK_WIDTH); + SSTD_t *trans = &Transaction_table[tid]; + serial_low(); // response step2 ack high->low +#endif // target send phase if( trans->target2initiator_buffer_size > 0 ) @@ -288,10 +316,10 @@ ISR(SERIAL_PIN_INTERRUPT) { if( trans->initiator2target_buffer_size > 0 ) { if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer, trans->initiator2target_buffer_size) ) { - *trans->status = RECIVE_ACCEPTED; + *trans->status = TRANSACTION_ACCEPTED; } else { debug_parity_on(); - *trans->status = RECIVE_DATA_ERROR; + *trans->status = TRANSACTION_DATA_ERROR; debug_parity_off(); } } @@ -309,16 +337,22 @@ ISR(SERIAL_PIN_INTERRUPT) { // TRANSACTION_END // TRANSACTION_NO_RESPONSE // TRANSACTION_DATA_ERROR +// this code is very time dependent, so we need to disable interrupts +#ifdef SERIAL_USE_SIMPLE_TRANSACTION +int soft_serial_transaction(void) { + SSTD_t *trans = Transaction_table; +#else int soft_serial_transaction(int sstd_index) { - // this code is very time dependent, so we need to disable interrupts SSTD_t *trans = &Transaction_table[sstd_index]; +#endif cli(); // signal to the target that we want to start a transaction serial_output(); serial_low(); - _delay_us(SLAVE_INT_WIDTH); + _delay_us(SLAVE_INT_WIDTH_US); +#ifdef SERIAL_USE_SIMPLE_TRANSACTION // wait for the target response serial_input_with_pullup(); _delay_us(SLAVE_INT_RESPONSE_TIME); @@ -328,10 +362,44 @@ int soft_serial_transaction(int sstd_index) { // target failed to pull the line low, assume not present serial_output(); serial_high(); + *trans->status = TRANSACTION_NO_RESPONSE; sei(); return TRANSACTION_NO_RESPONSE; } +#else + // send transaction table index + sync_send(); + debug_bytewidth_start(); + _delay_sub_us(TID_SEND_ADJUST); + serial_write_chunk(sstd_index, 4); + debug_bytewidth_end(); + serial_delay_half1(); + + // wait for the target response (step1 low->high) + serial_input_with_pullup(); + while( !serial_read_pin() ) { + _delay_sub_us(2); + debug_output_mode(); debug_input_mode(); // indicate check pin timeing + } + + // check if the target is present (step2 high->low) + debug_output_mode(); _delay_sub_us(1); debug_input_mode(); // indicate check pin timeing + for( int i = 0; serial_read_pin(); i++ ) { + if (i > SLAVE_INT_ACK_WIDTH + 1) { + // slave failed to pull the line low, assume not present + serial_output(); + serial_high(); + *trans->status = TRANSACTION_NO_RESPONSE; + sei(); + return TRANSACTION_NO_RESPONSE; + } + debug_output_mode(); + _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT); + debug_input_mode(); // indicate check pin timeing + } +#endif + // initiator recive phase // if the target is present syncronize with it if( trans->target2initiator_buffer_size > 0 ) { @@ -341,6 +409,7 @@ int soft_serial_transaction(int sstd_index) { serial_output(); serial_high(); debug_parity_off(); + *trans->status = TRANSACTION_DATA_ERROR; sei(); return TRANSACTION_DATA_ERROR; } @@ -359,8 +428,20 @@ int soft_serial_transaction(int sstd_index) { sync_send(); debug_input_mode(); debug_output_mode(); // indicate intterupt exit + *trans->status = TRANSACTION_END; sei(); return TRANSACTION_END; } +#ifndef SERIAL_USE_SIMPLE_TRANSACTION +int soft_serial_get_and_clean_status(int sstd_index) { + SSTD_t *trans = &Transaction_table[sstd_index]; + cli(); + int retval = *trans->status; + *trans->status = 0;; + sei(); + return retval; +} +#endif + #endif diff --git a/keyboards/helix/serial.h b/keyboards/helix/serial.h index 2f94f14efa..8664f12eb9 100644 --- a/keyboards/helix/serial.h +++ b/keyboards/helix/serial.h @@ -29,15 +29,27 @@ void soft_serial_target_init(SSTD_t *sstd_table); // initiator resullt #define TRANSACTION_END 0 -#define TRANSACTION_NO_RESPONSE 1 -#define TRANSACTION_DATA_ERROR 2 +#define TRANSACTION_NO_RESPONSE 0x1 +#define TRANSACTION_DATA_ERROR 0x2 +#ifdef SERIAL_USE_SIMPLE_TRANSACTION +int soft_serial_transaction(void); +#else int soft_serial_transaction(int sstd_index); +#endif // target status -#define RECIVE_ACCEPTED 1 -#define RECIVE_DATA_ERROR 2 -int soft_serial_get_and_clean_target_status(int sstd_index); - +// *SSTD_t.status has +// initiator: +// TRANSACTION_END +// or TRANSACTION_NO_RESPONSE +// or TRANSACTION_DATA_ERROR +// target: +// TRANSACTION_DATA_ERROR +// or TRANSACTION_ACCEPTED +#define TRANSACTION_ACCEPTED 0x4 +#ifndef SERIAL_USE_SIMPLE_TRANSACTION +int soft_serial_get_and_clean_status(int sstd_index); +#endif // debug flags