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.
Tool/software: TI-RTOS
Dear TI team,
I tried using SPI with Timer4A periodic timer in TM4C123GXL evaluation kit. When i ran SPI and timer individually, it works. It fails when i combined it together. There's a strange behavior that when i ran,
SPI0_init();
Timer4_init();
It works. When i ran,
Timer4_init();
SPI0_init();
It fails. It fails in line - SPI_transfer(...). This is its output
System provider is set to SysMin. Halt the target to view any SysMin contents in ROV.
init timer
done
open spi [OK]
e: 0x20000400.
Task stack size: 0x400.
R0 = 0x00000000 R8 = 0x0000842c
R1 = 0x400ff028 R9 = 0xffffffff
R2 = 0x00000001 R10 = 0xffffffff
R3 = 0x00000008 R11 = 0xffffffff
R4 = 0x00008634 R12 = 0x000000a0
R5 = 0x00000000 SP(R13) = 0x20000748
R6 = 0x200007a8 LR(R14) = 0x00003189
R7 = 0x200007c0 PC(R15) = 0x00003188
PSR = 0x01000000
ICSR = 0x00417817
MMFSR = 0x00
BFSR = 0x00
UFSR = 0x0000
HFSR = 0x00000000
DFSR = 0x00000001
MMAR = 0xe000ed34
BFAR = 0xe000ed38
AFSR = 0x00000000
Terminating execution...
In ROV debugging, no BIOS error but there's a decoded exception in HWI, Undefined Hwi: 23. More detail in dubugging will be shown below.
I used tirtos for TivaC version 2.16.1.14, TI compiler version 5.2.6, CCS version 6.2.0.00050
I created project using tirtos empty project template
My question are
1) Why i cannot make SPI and timer to works at the same time?
2) What cause it fails when i ran Timer4_init() and then SPI0_init()
This is my full code and debug. Please help.
Thank you,
Sarawin
// ============= empty.c ===============/
/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/System.h>
/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Clock.h>
/* TI-RTOS Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/I2C.h>
// #include <ti/drivers/SDSPI.h>
#include <ti/drivers/SPI.h>
#include <ti/drivers/UART.h>
// #include <ti/drivers/Watchdog.h>
// #include <ti/drivers/WiFi.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/interrupt.h"
#include "driverlib/rom.h"
#include "driverlib/timer.h"
#include "driverlib/sysctl.h"
/* Board Header file */
#include "BoardConfig.h"
#define TASKSTACKSIZE 1024
Task_Struct task0_Struct;
Char task0_Stack[TASKSTACKSIZE];
static SPI_Handle spiHandle = NULL;
static void Timer4_init(void);
static void Timer4_intHandler(void);
static void SPI0_init(void);
static void Timer4_init()
{
System_printf("init timer\r\n");
System_flush();
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER4);
TimerConfigure(TIMER4_BASE, TIMER_CFG_A_PERIODIC);
// IntPrioritySet(INT_TIMER4A,4<<5);
TimerIntRegister(TIMER4_BASE,TIMER_A,Timer4_intHandler);
uint32_t const freq = SysCtlClockGet(); // freq = 80 000 000 = 80MHz
uint32_t const period = freq >> 2; // Overflow period = 1 sec
TimerLoadSet(TIMER4_BASE, TIMER_A, period);
IntMasterEnable();
TimerIntEnable(TIMER4_BASE, TIMER_TIMA_TIMEOUT);
IntEnable(INT_TIMER4A);
TimerEnable(TIMER4_BASE, TIMER_A);
System_printf("done\r\n");
System_flush();
}
static void Timer4_intHandler(void){
TimerIntClear(TIMER4_BASE, TIMER_TIMA_TIMEOUT);
GPIO_toggle(Board_LED1);
}
static void SPI0_init(void)
{
SPI_Params spiParams;
SPI_Params_init(&spiParams);
spiParams.bitRate = 8000000;
spiParams.frameFormat = SPI_POL0_PHA0;
spiHandle = SPI_open(Board_SPI0,&spiParams);
if(spiHandle == NULL){
System_printf("open spi [FAIL]\r\n");
System_flush();
while(true);
}
System_printf("open spi [OK]\r\n");
System_flush();
SPI_Transaction transaction;
uint8_t txBuf[4];
uint8_t rxBuf[4];
transaction.count = 4;
transaction.txBuf = txBuf;
transaction.rxBuf = rxBuf;
uint8_t addr = 0x00;
uint32_t val = 0x000000;
txBuf[0] = addr;
txBuf[1] = (uint8_t)((val>>16)&0xFF);
txBuf[2] = (uint8_t)((val>>8)&0xFF);
txBuf[3] = (uint8_t)((val>>0)&0xFF);
SPI_transfer(spiHandle,&transaction);
SPI_close(spiHandle);
}
static void task0_init(void)
{
Timer4_init();
SPI0_init();
}
void task0_fxn(UArg arg0, UArg arg1)
{
task0_init();
System_printf("Task start\r\n");
System_flush();
while (1) {
Task_sleep((UInt)arg0);
GPIO_toggle(Board_LED0);
}
}
/*
* ======== main ========
*/
int main(void)
{
Task_Params taskParams;
/* Call board init functions */
Board_initGeneral();
Board_initGPIO();
// Board_initI2C();
// Board_initSDSPI();
Board_initSPI();
// Board_initUART();
// Board_initUSB(Board_USBDEVICE);
// Board_initWatchdog();
// Board_initWiFi();
/* Construct heartBeat Task thread */
Task_Params_init(&taskParams);
taskParams.arg0 = 1000;
taskParams.stackSize = TASKSTACKSIZE;
taskParams.stack = &task0_Stack;
Task_construct(&task0_Struct, (Task_FuncPtr)task0_fxn, &taskParams, NULL);
/* Turn on user LED */
GPIO_write(Board_LED0, Board_LED_ON);
System_printf("Starting the example\nSystem provider is set to SysMin. "
"Halt the target to view any SysMin contents in ROV.\n");
/* SysMin will only print to the console when you call flush or exit */
System_flush();
/* Start BIOS */
BIOS_start();
return (0);
}
// ====== SPI section in BoardConfig.c ======= //
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(SPI_config, ".const:SPI_config")
#pragma DATA_SECTION(spiTivaDMAHWAttrs, ".const:spiTivaDMAHWAttrs")
#endif
#include <ti/drivers/SPI.h>
#include <ti/drivers/spi/SPITivaDMA.h>
SPITivaDMA_Object spiTivaDMAObjects[BOARD_SPICOUNT];
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_ALIGN(spiTivaDMAscratchBuf, 32)
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment=32
#elif defined(__GNUC__)
__attribute__ ((aligned (32)))
#endif
uint32_t spiTivaDMAscratchBuf[BOARD_SPICOUNT];
const SPITivaDMA_HWAttrs spiTivaDMAHWAttrs[BOARD_SPICOUNT] = {
{
.baseAddr = SSI0_BASE,
.intNum = INT_SSI0,
.intPriority = (~0),
.scratchBufPtr = &spiTivaDMAscratchBuf[0],
.defaultTxBufValue = 0,
.rxChannelIndex = UDMA_CHANNEL_SSI0RX,
.txChannelIndex = UDMA_CHANNEL_SSI0TX,
.channelMappingFxn = uDMAChannelAssign,
.rxChannelMappingFxnArg = UDMA_CH10_SSI0RX,
.txChannelMappingFxnArg = UDMA_CH11_SSI0TX
},
};
const SPI_Config SPI_config[] = {
{
.fxnTablePtr = &SPITivaDMA_fxnTable,
.object = &spiTivaDMAObjects[0],
.hwAttrs = &spiTivaDMAHWAttrs[0]
},
{NULL, NULL, NULL},
};
void Board_initSPI(void)
{
/* SPI0 */
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
/* Need to unlock PF0 */
GPIOPinConfigure(GPIO_PA2_SSI0CLK);
GPIOPinConfigure(GPIO_PA3_SSI0FSS);
GPIOPinConfigure(GPIO_PA4_SSI0RX);
GPIOPinConfigure(GPIO_PA5_SSI0TX);
GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5);
Board_initDMA();
SPI_init();
}
// ===== SPI section in BoardConfig.h ===== //
typedef enum Board_SPIName {
BOARD_SPI0 = 0,
BOARD_SPICOUNT
} Board_SPIName;
This diagnosis seems most reasonable - but for the fact that poster claims it is the "calling order" - (and only one such order) which distresses.
Follows his direct quote: "There's a strange behavior that when i ran,
SPI0_init();
Timer4_init();
It works. When i ran,
Timer4_init();
SPI0_init();
It fails"
Would not the disallowed, "IntRegister" - along w/equally disallowed, "IntMasterEnable" - both be called - independent of, "calling order?" (thus should not "either order" fail?)