diff options
Diffstat (limited to 'drivers/avr/serial.c')
| -rw-r--r-- | drivers/avr/serial.c | 139 |
1 files changed, 97 insertions, 42 deletions
diff --git a/drivers/avr/serial.c b/drivers/avr/serial.c index c27cbfdd0..526a0946b 100644 --- a/drivers/avr/serial.c +++ b/drivers/avr/serial.c | |||
| @@ -20,50 +20,111 @@ | |||
| 20 | 20 | ||
| 21 | #ifdef SOFT_SERIAL_PIN | 21 | #ifdef SOFT_SERIAL_PIN |
| 22 | 22 | ||
| 23 | # ifdef __AVR_ATmega32U4__ | 23 | # if !(defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) |
| 24 | // if using ATmega32U4 I2C, can not use PD0 and PD1 in soft serial. | 24 | # error serial.c is not supported for the currently selected MCU |
| 25 | # ifdef USE_AVR_I2C | 25 | # endif |
| 26 | # if SOFT_SERIAL_PIN == D0 || SOFT_SERIAL_PIN == D1 | 26 | // if using ATmega32U4/2, AT90USBxxx I2C, can not use PD0 and PD1 in soft serial. |
| 27 | # error Using ATmega32U4 I2C, so can not use PD0, PD1 | 27 | # if defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) |
| 28 | # endif | 28 | # if defined(USE_AVR_I2C) && (SOFT_SERIAL_PIN == D0 || SOFT_SERIAL_PIN == D1) |
| 29 | # error Using I2C, so can not use PD0, PD1 | ||
| 29 | # endif | 30 | # endif |
| 31 | # endif | ||
| 32 | // PD0..PD3, common config | ||
| 33 | # if SOFT_SERIAL_PIN == D0 | ||
| 34 | # define EIMSK_BIT _BV(INT0) | ||
| 35 | # define EICRx_BIT (~(_BV(ISC00) | _BV(ISC01))) | ||
| 36 | # define SERIAL_PIN_INTERRUPT INT0_vect | ||
| 37 | # define EICRx EICRA | ||
| 38 | # elif SOFT_SERIAL_PIN == D1 | ||
| 39 | # define EIMSK_BIT _BV(INT1) | ||
| 40 | # define EICRx_BIT (~(_BV(ISC10) | _BV(ISC11))) | ||
| 41 | # define SERIAL_PIN_INTERRUPT INT1_vect | ||
| 42 | # define EICRx EICRA | ||
| 43 | # elif SOFT_SERIAL_PIN == D2 | ||
| 44 | # define EIMSK_BIT _BV(INT2) | ||
| 45 | # define EICRx_BIT (~(_BV(ISC20) | _BV(ISC21))) | ||
| 46 | # define SERIAL_PIN_INTERRUPT INT2_vect | ||
| 47 | # define EICRx EICRA | ||
| 48 | # elif SOFT_SERIAL_PIN == D3 | ||
| 49 | # define EIMSK_BIT _BV(INT3) | ||
| 50 | # define EICRx_BIT (~(_BV(ISC30) | _BV(ISC31))) | ||
| 51 | # define SERIAL_PIN_INTERRUPT INT3_vect | ||
| 52 | # define EICRx EICRA | ||
| 53 | # endif | ||
| 30 | 54 | ||
| 31 | # define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) | 55 | // ATmegaxxU2 specific config |
| 32 | # define setPinOutput(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF)) | 56 | # if defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) |
| 33 | # define writePinHigh(pin) (PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) | 57 | // PD4(INT5), PD6(INT6), PD7(INT7), PC7(INT4) |
| 34 | # define writePinLow(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF)) | 58 | # if SOFT_SERIAL_PIN == D4 |
| 35 | # define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF))) | 59 | # define EIMSK_BIT _BV(INT5) |
| 36 | 60 | # define EICRx_BIT (~(_BV(ISC50) | _BV(ISC51))) | |
| 37 | # if SOFT_SERIAL_PIN >= D0 && SOFT_SERIAL_PIN <= D3 | 61 | # define SERIAL_PIN_INTERRUPT INT5_vect |
| 38 | # if SOFT_SERIAL_PIN == D0 | 62 | # define EICRx EICRB |
| 39 | # define EIMSK_BIT _BV(INT0) | 63 | # elif SOFT_SERIAL_PIN == D6 |
| 40 | # define EICRx_BIT (~(_BV(ISC00) | _BV(ISC01))) | 64 | # define EIMSK_BIT _BV(INT6) |
| 41 | # define SERIAL_PIN_INTERRUPT INT0_vect | 65 | # define EICRx_BIT (~(_BV(ISC60) | _BV(ISC61))) |
| 42 | # elif SOFT_SERIAL_PIN == D1 | 66 | # define SERIAL_PIN_INTERRUPT INT6_vect |
| 43 | # define EIMSK_BIT _BV(INT1) | 67 | # define EICRx EICRB |
| 44 | # define EICRx_BIT (~(_BV(ISC10) | _BV(ISC11))) | 68 | # elif SOFT_SERIAL_PIN == D7 |
| 45 | # define SERIAL_PIN_INTERRUPT INT1_vect | 69 | # define EIMSK_BIT _BV(INT7) |
| 46 | # elif SOFT_SERIAL_PIN == D2 | 70 | # define EICRx_BIT (~(_BV(ISC70) | _BV(ISC71))) |
| 47 | # define EIMSK_BIT _BV(INT2) | 71 | # define SERIAL_PIN_INTERRUPT INT7_vect |
| 48 | # define EICRx_BIT (~(_BV(ISC20) | _BV(ISC21))) | 72 | # define EICRx EICRB |
| 49 | # define SERIAL_PIN_INTERRUPT INT2_vect | 73 | # elif SOFT_SERIAL_PIN == C7 |
| 50 | # elif SOFT_SERIAL_PIN == D3 | 74 | # define EIMSK_BIT _BV(INT4) |
| 51 | # define EIMSK_BIT _BV(INT3) | 75 | # define EICRx_BIT (~(_BV(ISC40) | _BV(ISC41))) |
| 52 | # define EICRx_BIT (~(_BV(ISC30) | _BV(ISC31))) | 76 | # define SERIAL_PIN_INTERRUPT INT4_vect |
| 53 | # define SERIAL_PIN_INTERRUPT INT3_vect | 77 | # define EICRx EICRB |
| 54 | # endif | 78 | # endif |
| 79 | # endif | ||
| 80 | |||
| 81 | // ATmegaxxU4 specific config | ||
| 82 | # if defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) | ||
| 83 | // PE6(INT6) | ||
| 84 | # if SOFT_SERIAL_PIN == E6 | ||
| 85 | # define EIMSK_BIT _BV(INT6) | ||
| 86 | # define EICRx_BIT (~(_BV(ISC60) | _BV(ISC61))) | ||
| 87 | # define SERIAL_PIN_INTERRUPT INT6_vect | ||
| 88 | # define EICRx EICRB | ||
| 89 | # endif | ||
| 90 | # endif | ||
| 91 | |||
| 92 | // AT90USBxxx specific config | ||
| 93 | # if defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) | ||
| 94 | // PE4..PE7(INT4..INT7) | ||
| 95 | # if SOFT_SERIAL_PIN == E4 | ||
| 96 | # define EIMSK_BIT _BV(INT4) | ||
| 97 | # define EICRx_BIT (~(_BV(ISC40) | _BV(ISC41))) | ||
| 98 | # define SERIAL_PIN_INTERRUPT INT4_vect | ||
| 99 | # define EICRx EICRB | ||
| 100 | # elif SOFT_SERIAL_PIN == E5 | ||
| 101 | # define EIMSK_BIT _BV(INT5) | ||
| 102 | # define EICRx_BIT (~(_BV(ISC50) | _BV(ISC51))) | ||
| 103 | # define SERIAL_PIN_INTERRUPT INT5_vect | ||
| 104 | # define EICRx EICRB | ||
| 55 | # elif SOFT_SERIAL_PIN == E6 | 105 | # elif SOFT_SERIAL_PIN == E6 |
| 56 | # define EIMSK_BIT _BV(INT6) | 106 | # define EIMSK_BIT _BV(INT6) |
| 57 | # define EICRx_BIT (~(_BV(ISC60) | _BV(ISC61))) | 107 | # define EICRx_BIT (~(_BV(ISC60) | _BV(ISC61))) |
| 58 | # define SERIAL_PIN_INTERRUPT INT6_vect | 108 | # define SERIAL_PIN_INTERRUPT INT6_vect |
| 59 | # else | 109 | # define EICRx EICRB |
| 60 | # error invalid SOFT_SERIAL_PIN value | 110 | # elif SOFT_SERIAL_PIN == E7 |
| 111 | # define EIMSK_BIT _BV(INT7) | ||
| 112 | # define EICRx_BIT (~(_BV(ISC70) | _BV(ISC71))) | ||
| 113 | # define SERIAL_PIN_INTERRUPT INT7_vect | ||
| 114 | # define EICRx EICRB | ||
| 61 | # endif | 115 | # endif |
| 116 | # endif | ||
| 62 | 117 | ||
| 63 | # else | 118 | # ifndef SERIAL_PIN_INTERRUPT |
| 64 | # error serial.c now support ATmega32U4 only | 119 | # error invalid SOFT_SERIAL_PIN value |
| 65 | # endif | 120 | # endif |
| 66 | 121 | ||
| 122 | # define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) | ||
| 123 | # define setPinOutput(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF)) | ||
| 124 | # define writePinHigh(pin) (PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) | ||
| 125 | # define writePinLow(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF)) | ||
| 126 | # define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF))) | ||
| 127 | |||
| 67 | # define ALWAYS_INLINE __attribute__((always_inline)) | 128 | # define ALWAYS_INLINE __attribute__((always_inline)) |
| 68 | # define NO_INLINE __attribute__((noinline)) | 129 | # define NO_INLINE __attribute__((noinline)) |
| 69 | # define _delay_sub_us(x) __builtin_avr_delay_cycles(x) | 130 | # define _delay_sub_us(x) __builtin_avr_delay_cycles(x) |
| @@ -210,15 +271,9 @@ void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size) { | |||
| 210 | Transaction_table_size = (uint8_t)sstd_table_size; | 271 | Transaction_table_size = (uint8_t)sstd_table_size; |
| 211 | serial_input_with_pullup(); | 272 | serial_input_with_pullup(); |
| 212 | 273 | ||
| 213 | // Enable INT0-INT3,INT6 | 274 | // Enable INT0-INT7 |
| 214 | EIMSK |= EIMSK_BIT; | 275 | EIMSK |= EIMSK_BIT; |
| 215 | # if SOFT_SERIAL_PIN == E6 | 276 | EICRx &= EICRx_BIT; |
| 216 | // Trigger on falling edge of INT6 | ||
| 217 | EICRB &= EICRx_BIT; | ||
| 218 | # else | ||
| 219 | // Trigger on falling edge of INT0-INT3 | ||
| 220 | EICRA &= EICRx_BIT; | ||
| 221 | # endif | ||
| 222 | } | 277 | } |
| 223 | 278 | ||
| 224 | // Used by the sender to synchronize timing with the reciver. | 279 | // Used by the sender to synchronize timing with the reciver. |
