diff options
Diffstat (limited to 'platforms/avr/drivers/serial.c')
-rw-r--r-- | platforms/avr/drivers/serial.c | 162 |
1 files changed, 74 insertions, 88 deletions
diff --git a/platforms/avr/drivers/serial.c b/platforms/avr/drivers/serial.c index 9a7345a53d..6a36aa5f7f 100644 --- a/platforms/avr/drivers/serial.c +++ b/platforms/avr/drivers/serial.c @@ -16,6 +16,7 @@ #include <util/delay.h> #include <stddef.h> #include <stdbool.h> +#include "gpio.h" #include "serial.h" #ifdef SOFT_SERIAL_PIN @@ -119,12 +120,6 @@ # error invalid SOFT_SERIAL_PIN value # endif -# define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) -# define setPinOutput(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF)) -# define writePinHigh(pin) (PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) -# define writePinLow(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF)) -# define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF))) - # define ALWAYS_INLINE __attribute__((always_inline)) # define NO_INLINE __attribute__((noinline)) # define _delay_sub_us(x) __builtin_avr_delay_cycles(x) @@ -161,59 +156,59 @@ # if SELECT_SOFT_SERIAL_SPEED == 0 // Very High speed -# define SERIAL_DELAY 4 // micro sec +# define SERIAL_DELAY 4 // micro sec # if __GNUC__ < 6 -# define READ_WRITE_START_ADJUST 33 // cycles -# define READ_WRITE_WIDTH_ADJUST 3 // cycles +# define READ_WRITE_START_ADJUST 33 // cycles +# define READ_WRITE_WIDTH_ADJUST 3 // cycles # else -# define READ_WRITE_START_ADJUST 34 // cycles -# define READ_WRITE_WIDTH_ADJUST 7 // cycles +# define READ_WRITE_START_ADJUST 34 // cycles +# define READ_WRITE_WIDTH_ADJUST 7 // cycles # endif # elif SELECT_SOFT_SERIAL_SPEED == 1 // High speed -# define SERIAL_DELAY 6 // micro sec +# define SERIAL_DELAY 6 // micro sec # if __GNUC__ < 6 -# define READ_WRITE_START_ADJUST 30 // cycles -# define READ_WRITE_WIDTH_ADJUST 3 // cycles +# define READ_WRITE_START_ADJUST 30 // cycles +# define READ_WRITE_WIDTH_ADJUST 3 // cycles # else -# define READ_WRITE_START_ADJUST 33 // cycles -# define READ_WRITE_WIDTH_ADJUST 7 // cycles +# define READ_WRITE_START_ADJUST 33 // cycles +# define READ_WRITE_WIDTH_ADJUST 7 // cycles # endif # elif SELECT_SOFT_SERIAL_SPEED == 2 // Middle speed -# define SERIAL_DELAY 12 // micro sec -# define READ_WRITE_START_ADJUST 30 // cycles +# define SERIAL_DELAY 12 // micro sec +# define READ_WRITE_START_ADJUST 30 // cycles # if __GNUC__ < 6 -# define READ_WRITE_WIDTH_ADJUST 3 // cycles +# define READ_WRITE_WIDTH_ADJUST 3 // cycles # else -# define READ_WRITE_WIDTH_ADJUST 7 // cycles +# define READ_WRITE_WIDTH_ADJUST 7 // cycles # endif # elif SELECT_SOFT_SERIAL_SPEED == 3 // Low speed -# define SERIAL_DELAY 24 // micro sec -# define READ_WRITE_START_ADJUST 30 // cycles +# define SERIAL_DELAY 24 // micro sec +# define READ_WRITE_START_ADJUST 30 // cycles # if __GNUC__ < 6 -# define READ_WRITE_WIDTH_ADJUST 3 // cycles +# define READ_WRITE_WIDTH_ADJUST 3 // cycles # else -# define READ_WRITE_WIDTH_ADJUST 7 // cycles +# define READ_WRITE_WIDTH_ADJUST 7 // cycles # endif # elif SELECT_SOFT_SERIAL_SPEED == 4 // Very Low speed -# define SERIAL_DELAY 36 // micro sec -# define READ_WRITE_START_ADJUST 30 // cycles +# define SERIAL_DELAY 36 // micro sec +# define READ_WRITE_START_ADJUST 30 // cycles # if __GNUC__ < 6 -# define READ_WRITE_WIDTH_ADJUST 3 // cycles +# define READ_WRITE_WIDTH_ADJUST 3 // cycles # else -# define READ_WRITE_WIDTH_ADJUST 7 // cycles +# define READ_WRITE_WIDTH_ADJUST 7 // cycles # endif # elif SELECT_SOFT_SERIAL_SPEED == 5 // Ultra Low speed -# define SERIAL_DELAY 48 // micro sec -# define READ_WRITE_START_ADJUST 30 // cycles +# define SERIAL_DELAY 48 // micro sec +# define READ_WRITE_START_ADJUST 30 // cycles # if __GNUC__ < 6 -# define READ_WRITE_WIDTH_ADJUST 3 // cycles +# define READ_WRITE_WIDTH_ADJUST 3 // cycles # else -# define READ_WRITE_WIDTH_ADJUST 7 // cycles +# define READ_WRITE_WIDTH_ADJUST 7 // cycles # endif # else # error invalid SELECT_SOFT_SERIAL_SPEED value @@ -228,29 +223,45 @@ # define SLAVE_INT_ACK_WIDTH 4 inline static void serial_delay(void) ALWAYS_INLINE; -inline static void serial_delay(void) { _delay_us(SERIAL_DELAY); } +inline static void serial_delay(void) { + _delay_us(SERIAL_DELAY); +} inline static void serial_delay_half1(void) ALWAYS_INLINE; -inline static void serial_delay_half1(void) { _delay_us(SERIAL_DELAY_HALF1); } +inline static void serial_delay_half1(void) { + _delay_us(SERIAL_DELAY_HALF1); +} inline static void serial_delay_half2(void) ALWAYS_INLINE; -inline static void serial_delay_half2(void) { _delay_us(SERIAL_DELAY_HALF2); } +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) { setPinOutput(SOFT_SERIAL_PIN); } +inline static void serial_output(void) { + setPinOutput(SOFT_SERIAL_PIN); +} // 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_with_pullup(void) { setPinInputHigh(SOFT_SERIAL_PIN); } +inline static void serial_input_with_pullup(void) { + setPinInputHigh(SOFT_SERIAL_PIN); +} inline static uint8_t serial_read_pin(void) ALWAYS_INLINE; -inline static uint8_t serial_read_pin(void) { return !!readPin(SOFT_SERIAL_PIN); } +inline static uint8_t serial_read_pin(void) { + return !!readPin(SOFT_SERIAL_PIN); +} inline static void serial_low(void) ALWAYS_INLINE; -inline static void serial_low(void) { writePinLow(SOFT_SERIAL_PIN); } +inline static void serial_low(void) { + writePinLow(SOFT_SERIAL_PIN); +} inline static void serial_high(void) ALWAYS_INLINE; -inline static void serial_high(void) { writePinHigh(SOFT_SERIAL_PIN); } +inline static void serial_high(void) { + writePinHigh(SOFT_SERIAL_PIN); +} void soft_serial_initiator_init(void) { serial_output(); @@ -291,7 +302,7 @@ static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) { _delay_sub_us(READ_WRITE_START_ADJUST); for (i = 0, byte = 0, p = PARITY; i < bit; i++) { - serial_delay_half1(); // read the middle of pulses + serial_delay_half1(); // read the middle of pulses if (serial_read_pin()) { byte = (byte << 1) | 1; p ^= 1; @@ -303,7 +314,7 @@ static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) { serial_delay_half2(); } /* recive parity bit */ - serial_delay_half1(); // read the middle of pulses + serial_delay_half1(); // read the middle of pulses pb = serial_read_pin(); _delay_sub_us(READ_WRITE_WIDTH_ADJUST); serial_delay_half2(); @@ -335,7 +346,7 @@ void serial_write_chunk(uint8_t data, uint8_t bit) { } serial_delay(); - serial_low(); // sync_send() / senc_recv() need raise edge + serial_low(); // sync_send() / senc_recv() need raise edge } static void serial_send_packet(uint8_t *buffer, uint8_t size) NO_INLINE; @@ -361,19 +372,19 @@ static uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) { } 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 + 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 + sync_recv(); // 0 + serial_delay(); // 1 + serial_low(); // 3 + serial_output(); // 3 + serial_delay_half1(); // 4 } static inline uint8_t nibble_bits_count(uint8_t bits) { @@ -396,11 +407,11 @@ ISR(SERIAL_PIN_INTERRUPT) { } serial_delay_half1(); - serial_high(); // response step1 low->high + serial_high(); // response step1 low->high serial_output(); _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT * SLAVE_INT_ACK_WIDTH); split_transaction_desc_t *trans = &split_transaction_table[tid]; - serial_low(); // response step2 ack high->low + serial_low(); // response step2 ack high->low // If the transaction has a callback, we can execute it now if (trans->slave_callback) { @@ -414,34 +425,22 @@ ISR(SERIAL_PIN_INTERRUPT) { // target recive phase if (trans->initiator2target_buffer_size > 0) { - if (serial_recive_packet((uint8_t *)split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size)) { - *trans->status = TRANSACTION_ACCEPTED; - } else { - *trans->status = TRANSACTION_DATA_ERROR; - } - } else { - *trans->status = TRANSACTION_ACCEPTED; + serial_recive_packet((uint8_t *)split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size); } - sync_recv(); // weit initiator output to high + sync_recv(); // weit initiator output to high } ///////// // start transaction by initiator // -// int soft_serial_transaction(int sstd_index) +// bool soft_serial_transaction(int sstd_index) // -// Returns: -// TRANSACTION_END -// TRANSACTION_NO_RESPONSE -// TRANSACTION_DATA_ERROR // this code is very time dependent, so we need to disable interrupts -int soft_serial_transaction(int sstd_index) { - if (sstd_index > NUM_TOTAL_TRANSACTIONS) return TRANSACTION_TYPE_ERROR; +bool soft_serial_transaction(int sstd_index) { + if (sstd_index > NUM_TOTAL_TRANSACTIONS) return false; split_transaction_desc_t *trans = &split_transaction_table[sstd_index]; - if (!trans->status) return TRANSACTION_TYPE_ERROR; // not registered - cli(); // signal to the target that we want to start a transaction @@ -468,9 +467,8 @@ int soft_serial_transaction(int sstd_index) { // slave failed to pull the line low, assume not present serial_output(); serial_high(); - *trans->status = TRANSACTION_NO_RESPONSE; sei(); - return TRANSACTION_NO_RESPONSE; + return false; } _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT); } @@ -481,9 +479,8 @@ int soft_serial_transaction(int sstd_index) { if (!serial_recive_packet((uint8_t *)split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size)) { serial_output(); serial_high(); - *trans->status = TRANSACTION_DATA_ERROR; sei(); - return TRANSACTION_DATA_ERROR; + return false; } } @@ -498,19 +495,8 @@ int soft_serial_transaction(int sstd_index) { // always, release the line when not in use sync_send(); - *trans->status = TRANSACTION_END; - sei(); - return TRANSACTION_END; -} - -int soft_serial_get_and_clean_status(int sstd_index) { - split_transaction_desc_t *trans = &split_transaction_table[sstd_index]; - cli(); - int retval = *trans->status; - *trans->status = 0; - ; sei(); - return retval; + return true; } #endif |