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 | 
