aboutsummaryrefslogtreecommitdiff
path: root/drivers/avr/serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/avr/serial.c')
-rw-r--r--drivers/avr/serial.c139
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.