From a65085a89354e89ddd3517aa63c74ef6dd32ca8b Mon Sep 17 00:00:00 2001 From: Pekaso Date: Fri, 28 Sep 2018 10:06:19 +0900 Subject: [PATCH] Keyboard: [Fortitude60] LED fix and Serial improvement (#3982) * arrangement Underglow * modified serial function references from helix * Remove defines (ws2812_*REG) --- keyboards/fortitude60/config.h | 1 + .../fortitude60/keymaps/default/config.h | 1 - .../fortitude60/keymaps/default/keymap.c | 4 +- .../fortitude60/keymaps/default/rules.mk | 1 + keyboards/fortitude60/rev1/config.h | 11 +- keyboards/fortitude60/rev1/rules.mk | 1 - keyboards/fortitude60/serial.c | 455 +++++++++++++----- keyboards/fortitude60/serial.h | 86 +++- keyboards/fortitude60/serial_config.h | 14 + 9 files changed, 422 insertions(+), 152 deletions(-) create mode 100644 keyboards/fortitude60/serial_config.h diff --git a/keyboards/fortitude60/config.h b/keyboards/fortitude60/config.h index 863722d7d0..27a44ab928 100644 --- a/keyboards/fortitude60/config.h +++ b/keyboards/fortitude60/config.h @@ -19,5 +19,6 @@ along with this program. If not, see . #define CONFIG_H #include "config_common.h" +#include #endif // CONFIG_H diff --git a/keyboards/fortitude60/keymaps/default/config.h b/keyboards/fortitude60/keymaps/default/config.h index b356791fc8..1748373481 100644 --- a/keyboards/fortitude60/keymaps/default/config.h +++ b/keyboards/fortitude60/keymaps/default/config.h @@ -28,7 +28,6 @@ along with this program. If not, see . // #define MASTER_RIGHT #define EE_HANDS -#define USE_SERIAL_PD2 /* #undef RGBLED_NUM */ /* #define RGBLIGHT_ANIMATIONS */ /* #define RGBLED_NUM 12 */ diff --git a/keyboards/fortitude60/keymaps/default/keymap.c b/keyboards/fortitude60/keymaps/default/keymap.c index 18d2527e45..9d724a8ec6 100644 --- a/keyboards/fortitude60/keymaps/default/keymap.c +++ b/keyboards/fortitude60/keymaps/default/keymap.c @@ -119,9 +119,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * ,-----------------------------------------. ,-----------------------------------------. * | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Del | * |------+------+------+------+------+------. ,------+------+------+------+------+------| - * | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Bksp | + * | ` | 1 | ↑ | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Bksp | * |------+------+------+------+------+------. ,------+------+------+------+------+------| - * | Del | F1 | F2 | F3 | F4 | F5 | | F6 | - | = | [ | ] | | | + * | Del | ← | ↓ | → | F4 | F5 | | F6 | - | = | [ | ] | | | * |------+------+------+------+------+------+-------------+------+------+------+------+------+------| * | | F7 | F8 | F9 | F10 | F11 | | | F12 |ISO # |ISO / | | | | * `-------------+------+------+------+------+------+------+------+------+------+------+-------------' diff --git a/keyboards/fortitude60/keymaps/default/rules.mk b/keyboards/fortitude60/keymaps/default/rules.mk index e0ed6f0c2d..1964bd0a7c 100644 --- a/keyboards/fortitude60/keymaps/default/rules.mk +++ b/keyboards/fortitude60/keymaps/default/rules.mk @@ -1 +1,2 @@ RGBLIGHT_ENABLE = no +BACKLIGHT_ENABLE = no \ No newline at end of file diff --git a/keyboards/fortitude60/rev1/config.h b/keyboards/fortitude60/rev1/config.h index 4ba195ff8e..8c6f21afe6 100644 --- a/keyboards/fortitude60/rev1/config.h +++ b/keyboards/fortitude60/rev1/config.h @@ -64,12 +64,11 @@ along with this program. If not, see . ) /* ws2812 RGB LED */ -/* #define RGB_DI_PIN D3 */ -/* #define RGBLIGHT_TIMER */ -/* #define RGBLED_NUM 16 // Number of LEDs */ -/* #define ws2812_PORTREG PORTD */ -/* #define ws2812_DDRREG DDRD */ - +#ifdef RGBLIGHT_ENABLE + #define RGB_DI_PIN B5 + #define RGBLIGHT_TIMER + #define RGBLED_NUM 18 // Number of LEDs */ +#endif /* * Feature disable options * These options are also useful to firmware size reduction. diff --git a/keyboards/fortitude60/rev1/rules.mk b/keyboards/fortitude60/rev1/rules.mk index bd518d8f27..e69de29bb2 100644 --- a/keyboards/fortitude60/rev1/rules.mk +++ b/keyboards/fortitude60/rev1/rules.mk @@ -1 +0,0 @@ -BACKLIGHT_ENABLE = yes diff --git a/keyboards/fortitude60/serial.c b/keyboards/fortitude60/serial.c index 46dfad021d..cea1a5f6ca 100644 --- a/keyboards/fortitude60/serial.c +++ b/keyboards/fortitude60/serial.c @@ -9,34 +9,128 @@ #include #include #include +#include #include #include "serial.h" +//#include -#ifndef USE_I2C +#ifdef USE_SERIAL -// Serial pulse period in microseconds. Its probably a bad idea to lower this -// value. -#define SERIAL_DELAY 24 +#ifndef SERIAL_USE_MULTI_TRANSACTION +/* --- USE Simple API (OLD API, compatible with let's split serial.c) */ + #if SERIAL_SLAVE_BUFFER_LENGTH > 0 + uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; + #endif + #if SERIAL_MASTER_BUFFER_LENGTH > 0 + uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; + #endif + uint8_t volatile status0 = 0; -uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; -uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; +SSTD_t transactions[] = { + { (uint8_t *)&status0, + #if SERIAL_MASTER_BUFFER_LENGTH > 0 + sizeof(serial_master_buffer), (uint8_t *)serial_master_buffer, + #else + 0, (uint8_t *)NULL, + #endif + #if SERIAL_SLAVE_BUFFER_LENGTH > 0 + sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer + #else + 0, (uint8_t *)NULL, + #endif + } +}; -#define SLAVE_DATA_CORRUPT (1<<0) -volatile uint8_t status = 0; +void serial_master_init(void) +{ soft_serial_initiator_init(transactions); } + +void serial_slave_init(void) +{ soft_serial_target_init(transactions); } + +// 0 => no error +// 1 => slave did not respond +// 2 => checksum error +int serial_update_buffers() +{ return soft_serial_transaction(); } + +#endif // Simple API (OLD API, compatible with let's split serial.c) + +#define ALWAYS_INLINE __attribute__((always_inline)) +#define NO_INLINE __attribute__((noinline)) +#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 + #define SERIAL_DELAY 4 // micro sec + #define READ_WRITE_START_ADJUST 33 // cycles + #define READ_WRITE_WIDTH_ADJUST 3 // cycles +#elif SELECT_SERIAL_SPEED == 1 + // High speed + #define SERIAL_DELAY 6 // micro sec + #define READ_WRITE_START_ADJUST 30 // cycles + #define READ_WRITE_WIDTH_ADJUST 3 // cycles +#elif SELECT_SERIAL_SPEED == 2 + // Middle speed + #define SERIAL_DELAY 12 // micro sec + #define READ_WRITE_START_ADJUST 30 // cycles + #define READ_WRITE_WIDTH_ADJUST 3 // cycles +#elif SELECT_SERIAL_SPEED == 3 + // Low speed + #define SERIAL_DELAY 24 // micro sec + #define READ_WRITE_START_ADJUST 30 // cycles + #define READ_WRITE_WIDTH_ADJUST 3 // cycles +#elif SELECT_SERIAL_SPEED == 4 + // Very Low speed + #define SERIAL_DELAY 50 // micro sec + #define READ_WRITE_START_ADJUST 30 // cycles + #define READ_WRITE_WIDTH_ADJUST 3 // cycles +#else +#error Illegal Serial Speed +#endif + + +#define SERIAL_DELAY_HALF1 (SERIAL_DELAY/2) +#define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY/2) + +#define SLAVE_INT_WIDTH_US 1 +#ifndef SERIAL_USE_MULTI_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; inline static void serial_delay(void) { _delay_us(SERIAL_DELAY); } +inline static +void serial_delay_half1(void) { + _delay_us(SERIAL_DELAY_HALF1); +} + +inline static +void serial_delay_half2(void) { + _delay_us(SERIAL_DELAY_HALF2); +} + +inline static void serial_output(void) ALWAYS_INLINE; inline static void serial_output(void) { SERIAL_PIN_DDR |= SERIAL_PIN_MASK; } // make the serial pin an input with pull-up resistor +inline static void serial_input_with_pullup(void) ALWAYS_INLINE; inline static -void serial_input(void) { +void serial_input_with_pullup(void) { SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK; SERIAL_PIN_PORT |= SERIAL_PIN_MASK; } @@ -46,190 +140,305 @@ uint8_t serial_read_pin(void) { return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK); } +inline static void serial_low(void) ALWAYS_INLINE; inline static void serial_low(void) { SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK; } +inline static void serial_high(void) ALWAYS_INLINE; inline static void serial_high(void) { SERIAL_PIN_PORT |= SERIAL_PIN_MASK; } -void serial_master_init(void) { - serial_output(); - serial_high(); +void soft_serial_initiator_init(SSTD_t *sstd_table) +{ + Transaction_table = sstd_table; + serial_output(); + serial_high(); } -void serial_slave_init(void) { - serial_input(); +void soft_serial_target_init(SSTD_t *sstd_table) +{ + Transaction_table = sstd_table; + serial_input_with_pullup(); -#ifndef USE_SERIAL_PD2 - // Enable INT0 - EIMSK |= _BV(INT0); - // Trigger on falling edge of INT0 - EICRA &= ~(_BV(ISC00) | _BV(ISC01)); +#if SERIAL_PIN_MASK == _BV(PD0) + // Enable INT0 + EIMSK |= _BV(INT0); + // Trigger on falling edge of INT0 + EICRA &= ~(_BV(ISC00) | _BV(ISC01)); +#elif SERIAL_PIN_MASK == _BV(PD2) + // Enable INT2 + EIMSK |= _BV(INT2); + // Trigger on falling edge of INT2 + EICRA &= ~(_BV(ISC20) | _BV(ISC21)); #else - // Enable INT2 - EIMSK |= _BV(INT2); - // Trigger on falling edge of INT2 - EICRA &= ~(_BV(ISC20) | _BV(ISC21)); + #error unknown SERIAL_PIN_MASK value #endif } -// Used by the master to synchronize timing with the slave. +// Used by the sender to synchronize timing with the reciver. +static void sync_recv(void) NO_INLINE; static void sync_recv(void) { - serial_input(); - // This shouldn't hang if the slave disconnects because the - // serial line will float to high if the slave does disconnect. + for (uint8_t i = 0; i < SERIAL_DELAY*5 && serial_read_pin(); i++ ) { + } + // This shouldn't hang if the target disconnects because the + // serial line will float to high if the target does disconnect. while (!serial_read_pin()); - serial_delay(); } -// Used by the slave to send a synchronization signal to the master. +// Used by the reciver to send a synchronization signal to the sender. +static void sync_send(void)NO_INLINE; static void sync_send(void) { - serial_output(); - serial_low(); serial_delay(); - serial_high(); } // Reads a byte from the serial line -static -uint8_t serial_read_byte(void) { - uint8_t byte = 0; - serial_input(); - for ( uint8_t i = 0; i < 8; ++i) { - byte = (byte << 1) | serial_read_pin(); - serial_delay(); - _delay_us(1); +static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) NO_INLINE; +static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) { + uint8_t byte, i, p, pb; + + _delay_sub_us(READ_WRITE_START_ADJUST); + for( i = 0, byte = 0, p = 0; i < bit; i++ ) { + serial_delay_half1(); // read the middle of pulses + if( serial_read_pin() ) { + byte = (byte << 1) | 1; p ^= 1; + } else { + byte = (byte << 1) | 0; p ^= 0; + } + _delay_sub_us(READ_WRITE_WIDTH_ADJUST); + serial_delay_half2(); } + /* recive parity bit */ + serial_delay_half1(); // read the middle of pulses + pb = serial_read_pin(); + _delay_sub_us(READ_WRITE_WIDTH_ADJUST); + serial_delay_half2(); + + *pterrcount += (p != pb)? 1 : 0; return byte; } // Sends a byte with MSB ordering -static -void serial_write_byte(uint8_t data) { - uint8_t b = 8; - serial_output(); - while( b-- ) { - if(data & (1 << b)) { - serial_high(); - } else { - serial_low(); +void serial_write_chunk(uint8_t data, uint8_t bit) NO_INLINE; +void serial_write_chunk(uint8_t data, uint8_t bit) { + uint8_t b, p; + for( p = 0, b = 1<<(bit-1); b ; b >>= 1) { + if(data & b) { + serial_high(); p ^= 1; + } else { + serial_low(); p ^= 0; + } + serial_delay(); } + /* send parity bit */ + if(p & 1) { serial_high(); } + else { serial_low(); } serial_delay(); + + serial_low(); // sync_send() / senc_recv() need raise edge +} + +static void serial_send_packet(uint8_t *buffer, uint8_t size) NO_INLINE; +static +void serial_send_packet(uint8_t *buffer, uint8_t size) { + for (uint8_t i = 0; i < size; ++i) { + uint8_t data; + data = buffer[i]; + sync_send(); + serial_write_chunk(data,8); } } -// interrupt handle to be used by the slave device +static uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) NO_INLINE; +static +uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) { + uint8_t pecount = 0; + for (uint8_t i = 0; i < size; ++i) { + uint8_t data; + sync_recv(); + data = serial_read_chunk(&pecount, 8); + buffer[i] = data; + } + return pecount == 0; +} + +inline static +void change_sender2reciver(void) { + sync_send(); //0 + serial_delay_half1(); //1 + serial_low(); //2 + serial_input_with_pullup(); //2 + serial_delay_half1(); //3 +} + +inline static +void change_reciver2sender(void) { + sync_recv(); //0 + serial_delay(); //1 + serial_low(); //3 + serial_output(); //3 + serial_delay_half1(); //4 +} + +// interrupt handle to be used by the target device ISR(SERIAL_PIN_INTERRUPT) { - sync_send(); - uint8_t checksum = 0; - for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { - serial_write_byte(serial_slave_buffer[i]); - sync_send(); - checksum += serial_slave_buffer[i]; - } - serial_write_byte(checksum); - sync_send(); +#ifndef SERIAL_USE_MULTI_TRANSACTION + serial_low(); + serial_output(); + SSTD_t *trans = Transaction_table; +#else + // recive transaction table index + uint8_t tid; + uint8_t pecount = 0; + sync_recv(); + tid = serial_read_chunk(&pecount,4); + if(pecount> 0) + return; + serial_delay_half1(); - // wait for the sync to finish sending - serial_delay(); + 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 - // read the middle of pulses - _delay_us(SERIAL_DELAY/2); + // target send phase + if( trans->target2initiator_buffer_size > 0 ) + serial_send_packet((uint8_t *)trans->target2initiator_buffer, + trans->target2initiator_buffer_size); + // target switch to input + change_sender2reciver(); - uint8_t checksum_computed = 0; - for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { - serial_master_buffer[i] = serial_read_byte(); - sync_send(); - checksum_computed += serial_master_buffer[i]; - } - uint8_t checksum_received = serial_read_byte(); - sync_send(); - - serial_input(); // end transaction - - if ( checksum_computed != checksum_received ) { - status |= SLAVE_DATA_CORRUPT; + // target recive phase + if( trans->initiator2target_buffer_size > 0 ) { + if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer, + trans->initiator2target_buffer_size) ) { + *trans->status = TRANSACTION_ACCEPTED; + } else { + *trans->status = TRANSACTION_DATA_ERROR; + } } else { - status &= ~SLAVE_DATA_CORRUPT; + *trans->status = TRANSACTION_ACCEPTED; } + + sync_recv(); //weit initiator output to high } -inline -bool serial_slave_DATA_CORRUPT(void) { - return status & SLAVE_DATA_CORRUPT; -} - -// Copies the serial_slave_buffer to the master and sends the -// serial_master_buffer to the slave. +///////// +// start transaction by initiator +// +// int soft_serial_transaction(int sstd_index) // // Returns: -// 0 => no error -// 1 => slave did not respond -int serial_update_buffers(void) { - // this code is very time dependent, so we need to disable interrupts +// TRANSACTION_END +// TRANSACTION_NO_RESPONSE +// TRANSACTION_DATA_ERROR +// this code is very time dependent, so we need to disable interrupts +#ifndef SERIAL_USE_MULTI_TRANSACTION +int soft_serial_transaction(void) { + SSTD_t *trans = Transaction_table; +#else +int soft_serial_transaction(int sstd_index) { + SSTD_t *trans = &Transaction_table[sstd_index]; +#endif cli(); - // signal to the slave that we want to start a transaction + // signal to the target that we want to start a transaction serial_output(); serial_low(); - _delay_us(1); + _delay_us(SLAVE_INT_WIDTH_US); - // wait for the slaves response - serial_input(); - serial_high(); - _delay_us(SERIAL_DELAY); +#ifndef SERIAL_USE_MULTI_TRANSACTION + // wait for the target response + serial_input_with_pullup(); + _delay_us(SLAVE_INT_RESPONSE_TIME); - // check if the slave is present + // check if the target is present if (serial_read_pin()) { - // slave failed to pull the line low, assume not present + // target failed to pull the line low, assume not present + serial_output(); + serial_high(); + *trans->status = TRANSACTION_NO_RESPONSE; sei(); - return 1; + return TRANSACTION_NO_RESPONSE; } - // if the slave is present syncronize with it - sync_recv(); +#else + // send transaction table index + sync_send(); + _delay_sub_us(TID_SEND_ADJUST); + serial_write_chunk(sstd_index, 4); + serial_delay_half1(); - uint8_t checksum_computed = 0; - // receive data from the slave - for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { - serial_slave_buffer[i] = serial_read_byte(); - sync_recv(); - checksum_computed += serial_slave_buffer[i]; - } - uint8_t checksum_received = serial_read_byte(); - sync_recv(); - - if (checksum_computed != checksum_received) { - sei(); - return 2; + // wait for the target response (step1 low->high) + serial_input_with_pullup(); + while( !serial_read_pin() ) { + _delay_sub_us(2); } - uint8_t checksum = 0; - // send data to the slave - for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { - serial_write_byte(serial_master_buffer[i]); - sync_recv(); - checksum += serial_master_buffer[i]; + // check if the target is present (step2 high->low) + 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; + } + _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT); + } +#endif + + // initiator recive phase + // if the target is present syncronize with it + if( trans->target2initiator_buffer_size > 0 ) { + if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer, + trans->target2initiator_buffer_size) ) { + serial_output(); + serial_high(); + *trans->status = TRANSACTION_DATA_ERROR; + sei(); + return TRANSACTION_DATA_ERROR; + } + } + + // initiator switch to output + change_reciver2sender(); + + // initiator send phase + if( trans->initiator2target_buffer_size > 0 ) { + serial_send_packet((uint8_t *)trans->initiator2target_buffer, + trans->initiator2target_buffer_size); } - serial_write_byte(checksum); - sync_recv(); // always, release the line when not in use - serial_output(); - serial_high(); + sync_send(); + *trans->status = TRANSACTION_END; sei(); - return 0; + return TRANSACTION_END; } +#ifdef SERIAL_USE_MULTI_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 \ No newline at end of file diff --git a/keyboards/fortitude60/serial.h b/keyboards/fortitude60/serial.h index 361f1881b6..d008980556 100644 --- a/keyboards/fortitude60/serial.h +++ b/keyboards/fortitude60/serial.h @@ -1,32 +1,80 @@ -#ifndef MY_SERIAL_H -#define MY_SERIAL_H +#ifndef SOFT_SERIAL_H +#define SOFT_SERIAL_H -#include "config.h" #include -/* TODO: some defines for interrupt setup */ -#define SERIAL_PIN_DDR DDRD -#define SERIAL_PIN_PORT PORTD -#define SERIAL_PIN_INPUT PIND +// ///////////////////////////////////////////////////////////////// +// Need Soft Serial defines in serial_config.h +// ///////////////////////////////////////////////////////////////// +// ex. +// #define SERIAL_PIN_DDR DDRD +// #define SERIAL_PIN_PORT PORTD +// #define SERIAL_PIN_INPUT PIND +// #define SERIAL_PIN_MASK _BV(PD?) ?=0,2 +// #define SERIAL_PIN_INTERRUPT INT?_vect ?=0,2 +// +// //// USE Simple API (OLD API, compatible with let's split serial.c) +// ex. +// #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 +// #define SERIAL_MASTER_BUFFER_LENGTH 1 +// +// //// USE flexible API (using multi-type transaction function) +// #define SERIAL_USE_MULTI_TRANSACTION +// +// ///////////////////////////////////////////////////////////////// -#ifndef USE_SERIAL_PD2 -#define SERIAL_PIN_MASK _BV(PD0) -#define SERIAL_PIN_INTERRUPT INT0_vect -#else -#define SERIAL_PIN_MASK _BV(PD2) -#define SERIAL_PIN_INTERRUPT INT2_vect -#endif -#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 -#define SERIAL_MASTER_BUFFER_LENGTH 1 - -// Buffers for master - slave communication +#ifndef SERIAL_USE_MULTI_TRANSACTION +/* --- USE Simple API (OLD API, compatible with let's split serial.c) */ +#if SERIAL_SLAVE_BUFFER_LENGTH > 0 extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH]; +#endif +#if SERIAL_MASTER_BUFFER_LENGTH > 0 extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH]; +#endif void serial_master_init(void); void serial_slave_init(void); int serial_update_buffers(void); -bool serial_slave_data_corrupt(void); +#endif // USE Simple API + +// Soft Serial Transaction Descriptor +typedef struct _SSTD_t { + uint8_t *status; + uint8_t initiator2target_buffer_size; + uint8_t *initiator2target_buffer; + uint8_t target2initiator_buffer_size; + uint8_t *target2initiator_buffer; +} SSTD_t; + +// initiator is transaction start side +void soft_serial_initiator_init(SSTD_t *sstd_table); +// target is interrupt accept side +void soft_serial_target_init(SSTD_t *sstd_table); + +// initiator resullt +#define TRANSACTION_END 0 +#define TRANSACTION_NO_RESPONSE 0x1 +#define TRANSACTION_DATA_ERROR 0x2 +#ifndef SERIAL_USE_MULTI_TRANSACTION +int soft_serial_transaction(void); +#else +int soft_serial_transaction(int sstd_index); #endif + +// target status +// *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 +#ifdef SERIAL_USE_MULTI_TRANSACTION +int soft_serial_get_and_clean_status(int sstd_index); +#endif + +#endif /* SOFT_SERIAL_H */ \ No newline at end of file diff --git a/keyboards/fortitude60/serial_config.h b/keyboards/fortitude60/serial_config.h new file mode 100644 index 0000000000..96a54afbd8 --- /dev/null +++ b/keyboards/fortitude60/serial_config.h @@ -0,0 +1,14 @@ +#ifndef SOFT_SERIAL_CONFIG_H +#define SOFT_SERIAL_CONFIG_H + +/* Soft Serial defines */ +#define SERIAL_PIN_DDR DDRD +#define SERIAL_PIN_PORT PORTD +#define SERIAL_PIN_INPUT PIND +#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 + +#endif /* SOFT_SERIAL_CONFIG_H */ \ No newline at end of file