This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
I am using F28379D-Launchpad for my project and decided to utilise SYS/BIOS this time. I am running CC9+ with bios_6_82_00_16, C2000Ware_3_01_00_00, Driverlib and xdctools_3_60_02_34_core packages.
My device is suppose act as a SPI Slave. I have a Hercules Launchpad that acts as the master. It transmits 7 bytes of data to the Slave periodically.
I had this working, with the RX interrupt but I could not seem to make the Delfino respond as a Slave. So I started re-evaluating my protocol. So not every SPI message is 7 bytes. This means that I can set RX interrupt level to 7 and when the IRQ is thrown I would just process the data.
The SYSBIOS is initialised, the IO is fine, the peripheral is good too, however after couple of milliseconds I get an error and the interrupts stop servicing. The debug is below.
enter main() [comms_manager_task] Initialising... [comms_manager_task] Running... [memory_task] Initialising... [memory_task] Running... ti.sysbios.family.c28.Hwi: line 1032: E_unpluggedInterrupt: Unplugged interrupt flagged: intr# 19 xdc.runtime.Error.raise: terminating execution ti.sysbios.gates.GateMutex: line 99: assertion failure: A_badContext: bad calling context. See GateMutex API doc for details. xdc.runtime.Error.raise: terminating execution
I've been following the SYS/BIOS manual and I've determined that I need to:
So the current flow is:
I have set GPIO to go HIGH before 2.a and go LOW after 2.e
What I see happening is that this all works at the start for some number of SPI messages and then the interrupt is disconnected.
The trace below shows the CS, CLK, MOSI and the GPIO HIGH/LOW.
communications_manager.c
void cm_task(UArg a0, UArg a1) { System_printf("[comms_manager_task] Initialising...\n"); spi_init_io(); spi_init(); Error_init(&hwi_spi_rx_eb); Hwi_Params_init(&hwi_spi_rx_params); hwi_spi_rx_params.arg = 72U; hwi_spi_rx = Hwi_create(72U, spiaRxFIFOISR, &hwi_spi_rx_params, &hwi_spi_rx_eb); if (hwi_spi_rx == NULL) { System_abort("[comms_manager_task] hwi_spi_rx_params create failed"); } Hwi_enableInterrupt(72U); Error_init(&swi_spi_rx_eb); Swi_Params_init(&swi_spi_rx_params); swi_spi_rx = Swi_create(bsw_spi_process_data, &swi_spi_rx_params, &swi_spi_rx_eb); if (swi_spi_rx == NULL) { System_abort("[comms_manager_task] swi_spi_rx_params create failed"); } System_printf("[comms_manager_task] Running...\n"); System_flush(); for(;;) { if(true == ds_require_transmit_updates()) { /**/ } Task_sleep(1000); } } /** * @brief SPI B Receive FIFO ISR */ void spiaRxFIFOISR(UArg arg){ Swi_post(swi_spi_rx); }
spi.c
/** * @brief Function to configure SPI Slave module * * @param base, one of the supported SPI Base addresses * @param mode, one of SPI_Mode */ void spi_init_device(uint32_t base,SPI_Mode mode) { crc_error = 0U; /* Must put SPI into reset before configuring it */ SPI_disableModule(base); /* SPI configuration. Use a 500kHz SPICLK and 16-bit word size. */ SPI_setConfig(base, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0, mode, SPI_BUS_SPEED_HZ, SPI_WORD_LENGTH_BITS); SPI_disableLoopback(base); SPI_setEmulationMode(base, SPI_EMULATION_FREE_RUN); /* FIFO and interrupt configuration */ SPI_enableFIFO(base); SPI_clearInterruptStatus(base, SPI_INT_RXFF | SPI_INT_RXFF_OVERFLOW); SPI_setFIFOInterruptLevel(base, SPI_FIFO_TXFULL, SPI_FIFO_RX7); SPI_enableInterrupt(base, SPI_INT_RXFF | SPI_INT_RXFF_OVERFLOW); /* Configuration complete. Enable the module. */ SPI_enableModule(base); } uint16_t status; uint16_t address; void bsw_spi_process_data(UArg arg0, UArg arg1) { GPIO_writePin(29, 1); for(uint16_t i = 0U; i < SPI_WRITE_MSG_BYTE_COUNT; i++) { rData[i] = (HWREGH(SPIA_BASE + SPI_O_RXBUF) & 0x00FFU); } addr = (rData[0] & SPI_ADDR_MASK); if(SPI_WRITE_FLAG == (rData[0] & SPI_WRITE_FLAG)) { uint32_t value = (((uint32_t)rData[1]) << 24U); value |= (((uint32_t)rData[2]) << 16U); value |= (rData[3] << 8U); value |= rData[4]; } /* Clear interrupt flag and issue ACK */ HWREGH(SPIA_BASE + SPI_O_FFRX) |= SPI_FFRX_RXFFINTCLR; HWREGH(SPIA_BASE + SPI_O_FFRX) |= SPI_FFRX_RXFFOVFCLR; Hwi_restoreInterrupt(6,1); GPIO_writePin(29, 0); }
app.cfg
var Defaults = xdc.useModule('xdc.runtime.Defaults'); var Diags = xdc.useModule('xdc.runtime.Diags'); var Error = xdc.useModule('xdc.runtime.Error'); var Log = xdc.useModule('xdc.runtime.Log'); var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf'); var Main = xdc.useModule('xdc.runtime.Main'); var Memory = xdc.useModule('xdc.runtime.Memory') var SysMin = xdc.useModule('xdc.runtime.SysMin'); var System = xdc.useModule('xdc.runtime.System'); var Text = xdc.useModule('xdc.runtime.Text'); var BIOS = xdc.useModule('ti.sysbios.BIOS'); var Clock = xdc.useModule('ti.sysbios.knl.Clock'); var Swi = xdc.useModule('ti.sysbios.knl.Swi'); var Task = xdc.useModule('ti.sysbios.knl.Task'); var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore'); var Boot = xdc.useModule('ti.catalog.c2800.initF2837x.Boot'); var ti_sysbios_hal_Hwi = xdc.useModule('ti.sysbios.hal.Hwi'); var UIAProfile = xdc.useModule('ti.uia.events.UIAProfile'); var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup'); /* * Uncomment this line to globally disable Asserts. * All modules inherit the default from the 'Defaults' module. You * can override these defaults on a per-module basis using Module.common$. * Disabling Asserts will save code space and improve runtime performance. Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF; */ /* * Uncomment this line to keep module names from being loaded on the target. * The module name strings are placed in the .const section. Setting this * parameter to false will save space in the .const section. Error and * Assert messages will contain an "unknown module" prefix instead * of the actual module name. Defaults.common$.namedModule = false; */ /* * Minimize exit handler array in System. The System module includes * an array of functions that are registered with System_atexit() to be * called by System_exit(). */ System.maxAtexitHandlers = 4; /* * Uncomment this line to disable the Error print function. * We lose error information when this is disabled since the errors are * not printed. Disabling the raiseHook will save some code space if * your app is not using System_printf() since the Error_print() function * calls System_printf(). Error.raiseHook = null; */ /* * Uncomment this line to keep Error, Assert, and Log strings from being * loaded on the target. These strings are placed in the .const section. * Setting this parameter to false will save space in the .const section. * Error, Assert and Log message will print raw ids and args instead of * a formatted message. Text.isLoaded = false; */ /* * Uncomment this line to disable the output of characters by SysMin * when the program exits. SysMin writes characters to a circular buffer. * This buffer can be viewed using the SysMin Output view in ROV. SysMin.flushAtExit = false; */ /* * The BIOS module will create the default heap for the system. * Specify the size of this default heap. */ BIOS.heapSize = 0x800; /* * Build a custom SYS/BIOS library from sources. */ BIOS.libType = BIOS.LibType_Custom; /* System stack size (used by ISRs and Swis) */ Program.stack = 0x100; /* Circular buffer size for System_printf() */ SysMin.bufSize = 0x200; /* * Create and install logger for the whole system */ var loggerBufParams = new LoggerBuf.Params(); loggerBufParams.numEntries = 32; var logger0 = LoggerBuf.create(loggerBufParams); Defaults.common$.logger = logger0; Main.common$.diags_INFO = Diags.ALWAYS_ON; System.SupportProxy = SysMin; BIOS.cpuFreq.lo = 200000000; Boot.SPLLFMULT = Boot.Fract_0; Boot.SPLLIMULT = 20; Boot.SYSCLKDIVSEL = 1; Boot.OSCCLKSRCSEL = Boot.OscClk_XTAL; Boot.disableWatchdog = true; Boot.OSCCLK = 20; BIOS.customCCOpts = "-v28 -DLARGE_MODEL=1 -ml --float_support=fpu32 -q -mo --program_level_compile -o3 -g";
#19 is the illegal/ITRAP ISR, so somehow an invalid instruction was fetched. A lot of the time this is caused by issues like stack overflow or some other buffer overflow, so use ROV and the memory browser to check for signs of that.
Another common cause is trying to call a function that needs to be run from RAM before it has actually been copied from flash to RAM, so if you have any ramfuncs functions or something similar, confirm that the are where they're supposed to be.
Whitney
Also, I think you can find out the return address (irp) from ROV as well, so if you were to create a Hwi for the illegal ISR, put a breakpoint in it and then check the return address and the breakpoint is hit, it may give you some hint of what is happening.
Whitney