Whenever I use system_flush() in an ISR or SWI, the uC (MSP430F5529) goes to exit.c. Specifically, the uC goes to about():
/****************************************************************************/ /* ABORT - ABNORMAL PROGRAM TERMINATION. CURRENTLY JUST HALTS EXECUTION. */ /****************************************************************************/ void abort(void) { /*-------------------------------------------------------------------*/ /* SET C$$EXIT LABEL SO THE DEBUGGER KNOWS WHEN THE C++ PROGRAM HAS */ /* COMPLETED. THIS CAN BE REMOVED IF THE DEBUGGER IS NOT USED. */ /*-------------------------------------------------------------------*/ __asm(" .global C$$EXIT"); __asm("C$$EXIT: nop"); for (;;); /* SPINS FOREVER */ }
I am not sure why this happens. The uC is connected to another device through SPI. The uC that flushes is the slave. The master send a byte of data very quickly, every 100 cycles at 8.2MHz. My first guess was that the flush() was being interrupted by a message. So I disable the SPI interrupt every time the flush() executed. This didn't stop the uC from aborting from the flush().
Here is my code:
/* * ======== main.c ======== */ #include <xdc/std.h> #include <ti/sysbios/BIOS.h> #include <xdc/cfg/global.h> #include <xdc/runtime/System.h> #include <xdc/runtime/Log.h> #include <driverlib.h> #define GPIO_ALL GPIO_PIN0|GPIO_PIN1|GPIO_PIN2|GPIO_PIN3| \ GPIO_PIN4|GPIO_PIN5|GPIO_PIN6|GPIO_PIN7 uint8_t returnValue = 0x00; uint8_t transmitData = 0x00, receiveData = 0x00; void init_GPIO(void); int init_SPI(void); void start_SPI(void); void SPI_ISR(void); //----------------------------------------- // Globals //----------------------------------------- volatile int16_t i16ToggleCount = 0; /* * ======== main ======== */ Int main() { init_GPIO(); init_SPI(); System_printf("You are in!"); System_flush(); BIOS_start(); /* does not return */ return(0); } void start_SPI(){ char rx_char= {'0'}; rx_char= USCI_A_SPI_receiveData(USCI_A0_BASE); if( rx_char == 0x50){ GPIO_toggleOutputOnPin(GPIO_PORT_P4,GPIO_PIN7); } else{ GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN0); } System_putch(rx_char); if( rx_char == '!' ){ System_putch(rx_char); USCI_A_SPI_disableInterrupt(USCI_A0_BASE, USCI_A_SPI_RECEIVE_INTERRUPT); // System_flush(); // USCI_A_SPI_enableInterrupt(USCI_A0_BASE, USCI_A_SPI_RECEIVE_INTERRUPT); } // System_flush(); } int init_SPI(){ // Configure for SPI // P3.4 as MISO GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3,GPIO_PIN4); // P3.3 as MOSI GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3,GPIO_PIN3); // P2.7 as SCLK GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2,GPIO_PIN7); // P6.6 Chip select GPIO_setAsInputPin(GPIO_PORT_P6,GPIO_PIN6); returnValue = USCI_A_SPI_initSlave( USCI_A0_BASE, USCI_A_SPI_MSB_FIRST, USCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT, USCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW ); if(STATUS_FAIL == returnValue){ return 0; } // Enable SPI Module USCI_A_SPI_enable(USCI_A0_BASE); // Enable Receive Interrupt USCI_A_SPI_clearInterrupt(USCI_A0_BASE, USCI_A_SPI_RECEIVE_INTERRUPT); // Flag may be needed or not USCI_A_SPI_enableInterrupt(USCI_A0_BASE, USCI_A_SPI_RECEIVE_INTERRUPT); return 1; } void init_GPIO(void){ // Disable the Watchdog Timer (important, as this is enabled by default) WDT_A_hold( WDT_A_BASE ); // Set GPIO ports to low-level outputs GPIO_setAsOutputPin( GPIO_PORT_P1, GPIO_PIN0 ); GPIO_setAsOutputPin( GPIO_PORT_P4, GPIO_PIN7 ); GPIO_setOutputLowOnPin( GPIO_PORT_P1, GPIO_PIN0 ); GPIO_setOutputLowOnPin( GPIO_PORT_P4, GPIO_PIN7 ); } void SPI_ISR(void) { Swi_post(SPISwi); USCI_A_SPI_clearInterrupt(USCI_A0_BASE, USCI_A_SPI_RECEIVE_INTERRUPT); // Flag may be needed or not }