AVR128DB18, MCS7 GCC, C executable.
I am experimenting with interrupt service routine (first attempt at writing and testing ISR on this platform.)
I am using USART0 in Async mode (which otherwise is working well without interrupts involved) as the test case. No other onboard peripherals are active, nor are peripheral interrupts enabled (except for the one instance at USART0 RXIE.)
I have not enabled watchdog timer (or brownout detection).
I believe I am configuring USART0 to cause an interrupt when a byte is received (however, not when a byte is sent, nor under any other circumstance.) I am likely failing to do this properly (or set up ISR properly).
Once I enable CPU interrupts (sei), the program continues to work properly until the first byte arrives at the USART0 receive data port.
At that point, the program appears to restart, rather than enter the ISR as expected.
I have two ISRs defined - ISR(BADISR_vect) and ISR(USART0_RXC_vect); neither appears to be called
Am I missing something basic for this? I've read (and read and read)
https://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html
however, I've not been able to find my culprit.
Below is the code segment (abridged, so only the relevant initialization and ISRs are listed, and failure mode are described.) I've captured the bit-level settings of USART0 (in 0x8000..0x080E) as they are set before the first character is received when interrupts are enabled in a comment at the end. Once the first interrupt happens, the program resets, so I've not yet been able to capture any changes to those settings.
Thanks for any pointers!
Dave
#include <avr/io.h> #include <avr/cpufunc.h> #include <avr/interrupt.h> ISR(BADISR_vect) { // Do this for uncaught interrupt // This does not appear to ever be called } ISR(USART0_RXC_vect) { // Do this when USART0 has received a character // This does not appear to ever be called } void initialize_usart0(void) { // All the rest of initalizing USART0 details would go here (omitted) as without interrupts USART0 is receiving and transmitting data properly. // Asynchronous mode, 8 bits/character, 1 stop bit, no parity bit, normal speed mode, transmit data pin is set for output, receive enabled, transmit enabled. // The following change was made to enable interrupt when a byte is received in the USART: USART0_CTRLA = USART_RXCIF_bm; // Enable interrupt - should call ISR(USART0_RXC_vect) when a byte arrives at USART0 RxD pin } int main(void) { // When the problem is triggered (USART0 receives one byte while it's interrupts are // enabled and CPU interrupts are enabled), we get back to this point unexpectedly, // without ever calling ISR(BADISR_vect) or ISR(USART0_RXCIF_vect) // All other initialization gets done here, except usart0 - no other peripherals have interrupts enabled initialize_usart0(); // Initialize usart0, and enable interrupt when character received (see above) // Everything works through this point in the code, interrupts are off sei(); // Turn on CPU interrupts // Everything works beyond this point, *until* the USART receives a character // When USART0 receives it's first incoming byte, // the program appears to restart (gets back to int main(void) above) // ISR(BADISR_vect) does not appear to be called // ISR(USART0_RXC_vect) does not appear to be called } /* USART0 registers (before the first receive character with interrupts on) RXDATAL 30 (the last character that was received while interrupts were off) RXDATAH 00 (no errors or interrupt flags; 8-bit data so no 9th bit) TXDATAL 20 (the last character that was sent) TXDATAH 00 (8-bit data, so no 9th bit) STATUS 40 TXCIF is high CTRLA 80 RXCIE is high CTRLB C0 RXEN, TXEN are high CTRLC 03 CHSIZE = 011 = BAUD 10 BAUD = 10000 (2710 hex) OTHERS 00 */