add split_scomm.c/split_scomm.h and change serial.c/serial.h

serial.c was divided into 2 layers, split_scom.c and serial.c.
The upper layer split_scomm.c is called from matrix.c.
The lower layer serial.c accesses the hardware.
pull/3608/head
mtei 7 years ago
parent 4b945ac358
commit 8804993a89

@ -34,7 +34,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef USE_MATRIX_I2C #ifdef USE_MATRIX_I2C
# include "i2c.h" # include "i2c.h"
#else // USE_SERIAL #else // USE_SERIAL
# include "serial.h" # include "split_scomm.h"
#endif #endif
#ifndef DEBOUNCE #ifndef DEBOUNCE
@ -182,7 +182,7 @@ i2c_error: // the cable is disconnceted, or something else went wrong
int serial_transaction(void) { int serial_transaction(void) {
int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
int ret=serial_update_buffers(); int ret=serial_update_buffers(1);
if (ret ) { if (ret ) {
if(ret==2)RXLED1; if(ret==2)RXLED1;
return 1; return 1;

@ -1,3 +1,4 @@
SRC += rev2/matrix.c \ SRC += rev2/matrix.c
rev2/split_util.c \ SRC += rev2/split_util.c
ws2812.c SRC += rev2/split_scomm.c
SRC += ws2812.c

@ -8,9 +8,6 @@
#define SERIAL_PIN_MASK _BV(PD2) #define SERIAL_PIN_MASK _BV(PD2)
#define SERIAL_PIN_INTERRUPT INT2_vect #define SERIAL_PIN_INTERRUPT INT2_vect
#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
#define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2
//// #error rev2 serial config //// #error rev2 serial config
#endif /* SOFT_SERIAL_CONFIG_H */ #endif /* SOFT_SERIAL_CONFIG_H */

@ -0,0 +1,36 @@
#ifdef USE_SERIAL
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <split_scomm.h>
#include "serial.h"
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;
SSTD_t transactions[] = {
{ (uint8_t *)&status0,
sizeof(serial_master_buffer), (uint8_t *)serial_master_buffer,
sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer
}
};
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(int master_update)
{
return soft_serial_transaction(0);
}
#endif /* USE_SERIAL */

@ -0,0 +1,15 @@
#ifndef SPLIT_COMM_H
#define SPLIT_COMM_H
// Buffers for master - slave communication
#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
#define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2
extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH];
extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH];
void serial_master_init(void);
void serial_slave_init(void);
int serial_update_buffers(int master_changed);
#endif /* SPLIT_COMM_H */

@ -11,7 +11,7 @@
#ifdef USE_MATRIX_I2C #ifdef USE_MATRIX_I2C
# include "i2c.h" # include "i2c.h"
#else #else
# include "serial.h" # include "split_scomm.h"
#endif #endif
volatile bool isLeftHand = true; volatile bool isLeftHand = true;

@ -1,6 +1,9 @@
SRC += i2c.c \ SRC += i2c.c
serial.c \ SRC += serial.c
ssd1306.c SRC += ssd1306.c
# if firmware size over limit, try this option
# CFLAGS += -flto
# MCU name # MCU name
#MCU = at90usb1287 #MCU = at90usb1287

@ -9,8 +9,10 @@
#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <util/delay.h> #include <util/delay.h>
#include <stddef.h>
#include <stdbool.h> #include <stdbool.h>
#include "serial.h" #include "serial.h"
//#include <pro_micro.h>
#ifdef USE_SERIAL #ifdef USE_SERIAL
@ -55,11 +57,7 @@
#define SLAVE_INT_WIDTH 1 #define SLAVE_INT_WIDTH 1
#define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY #define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY
uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; static SSTD_t *Transaction_table = NULL;
uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0};
#define SLAVE_DATA_CORRUPT (1<<0)
volatile uint8_t status = 0;
inline static inline static
void serial_delay(void) { void serial_delay(void) {
@ -109,26 +107,30 @@ void serial_high(void) {
SERIAL_PIN_PORT |= SERIAL_PIN_MASK; SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
} }
void serial_master_init(void) { void soft_serial_initiator_init(SSTD_t *sstd_table)
serial_debug_init(); {
serial_output(); serial_debug_init();
serial_high(); Transaction_table = sstd_table;
serial_output();
serial_high();
} }
void serial_slave_init(void) { void soft_serial_target_init(SSTD_t *sstd_table)
serial_debug_init(); {
serial_input_with_pullup(); serial_debug_init();
Transaction_table = sstd_table;
serial_input_with_pullup();
#if SERIAL_PIN_MASK == _BV(PD0) #if SERIAL_PIN_MASK == _BV(PD0)
// Enable INT0 // Enable INT0
EIMSK |= _BV(INT0); EIMSK |= _BV(INT0);
// Trigger on falling edge of INT0 // Trigger on falling edge of INT0
EICRA &= ~(_BV(ISC00) | _BV(ISC01)); EICRA &= ~(_BV(ISC00) | _BV(ISC01));
#elif SERIAL_PIN_MASK == _BV(PD2) #elif SERIAL_PIN_MASK == _BV(PD2)
// Enable INT2 // Enable INT2
EIMSK |= _BV(INT2); EIMSK |= _BV(INT2);
// Trigger on falling edge of INT2 // Trigger on falling edge of INT2
EICRA &= ~(_BV(ISC20) | _BV(ISC21)); EICRA &= ~(_BV(ISC20) | _BV(ISC21));
#else #else
#error unknown SERIAL_PIN_MASK value #error unknown SERIAL_PIN_MASK value
#endif #endif
@ -228,7 +230,7 @@ uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) {
uint8_t checksum_received = serial_read_byte(); uint8_t checksum_received = serial_read_byte();
debug_bytewidth_end(); debug_bytewidth_end();
return checksum_computed != checksum_received; return checksum_computed == checksum_received;
} }
inline static inline static
@ -255,38 +257,38 @@ ISR(SERIAL_PIN_INTERRUPT) {
serial_low(); serial_low();
serial_output(); serial_output();
SSTD_t *trans = Transaction_table;
// slave send phase // slave send phase
serial_send_packet((uint8_t *)serial_slave_buffer, SERIAL_SLAVE_BUFFER_LENGTH); serial_send_packet((uint8_t *)trans->target2initiator_buffer,
trans->target2initiator_buffer_size);
// slave switch to input // slave switch to input
change_sender2reciver(); change_sender2reciver();
// slave recive phase // slave recive phase
if (serial_recive_packet((uint8_t *)serial_master_buffer,SERIAL_MASTER_BUFFER_LENGTH) ) { if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer,
status |= SLAVE_DATA_CORRUPT; trans->initiator2target_buffer_size) ) {
*trans->status = RECIVE_ACCEPTED;
} else { } else {
status &= ~SLAVE_DATA_CORRUPT; *trans->status = RECIVE_DATA_ERROR;
} }
sync_recv(); //weit master output to high sync_recv(); //weit master output to high
debug_output_mode(); debug_input_mode(); // indicate intterupt exit debug_output_mode(); debug_input_mode(); // indicate intterupt exit
} }
inline /////////
bool serial_slave_DATA_CORRUPT(void) { // start transaction by initiator
return status & SLAVE_DATA_CORRUPT; //
} // int soft_serial_transaction(int sstd_index)
// Copies the serial_slave_buffer to the master and sends the
// serial_master_buffer to the slave.
// //
// Returns: // Returns:
// 0 => no error // TRANSACTION_END
// 1 => slave did not respond // TRANSACTION_NO_RESPONSE
// 2 => checksum error // TRANSACTION_DATA_ERROR
int serial_update_buffers(void) { int soft_serial_transaction(int sstd_index) {
// this code is very time dependent, so we need to disable interrupts // this code is very time dependent, so we need to disable interrupts
SSTD_t *trans = &Transaction_table[sstd_index];
cli(); cli();
// signal to the slave that we want to start a transaction // signal to the slave that we want to start a transaction
@ -309,7 +311,8 @@ int serial_update_buffers(void) {
// master recive phase // master recive phase
// if the slave is present syncronize with it // if the slave is present syncronize with it
if (serial_recive_packet((uint8_t *)serial_slave_buffer, SERIAL_SLAVE_BUFFER_LENGTH) ) { if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer,
trans->target2initiator_buffer_size) ) {
serial_output(); serial_output();
serial_high(); serial_high();
sei(); sei();
@ -320,7 +323,8 @@ int serial_update_buffers(void) {
change_reciver2sender(); change_reciver2sender();
// master send phase // master send phase
serial_send_packet((uint8_t *)serial_master_buffer, SERIAL_MASTER_BUFFER_LENGTH); serial_send_packet((uint8_t *)trans->initiator2target_buffer,
trans->initiator2target_buffer_size);
// always, release the line when not in use // always, release the line when not in use
sync_send(); sync_send();

@ -12,18 +12,31 @@
// #define SERIAL_PIN_INPUT PIND // #define SERIAL_PIN_INPUT PIND
// #define SERIAL_PIN_MASK _BV(PD?) ?=0,2 // #define SERIAL_PIN_MASK _BV(PD?) ?=0,2
// #define SERIAL_PIN_INTERRUPT INT?_vect ?=0,2 // #define SERIAL_PIN_INTERRUPT INT?_vect ?=0,2
// #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
// #define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2
// Buffers for master - slave communication
extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH];
extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH];
void serial_master_init(void);
void serial_slave_init(void);
int serial_update_buffers(void);
bool serial_slave_data_corrupt(void);
// 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 1
#define TRANSACTION_DATA_ERROR 2
int soft_serial_transaction(int sstd_index);
// target status
#define RECIVE_ACCEPTED 1
#define RECIVE_DATA_ERROR 2
int soft_serial_get_and_clean_target_status(int sstd_index);

Loading…
Cancel
Save