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
Do you have reference material which details how to use SPI1 under SWI configuration?
I have it working but keep crashing. I tried HWI/SWI disabled but does not fix this.I also get this warning, how to fix this?
Description Resource Path Location Type
#515-D a value of type "void (*)(void)" cannot be assigned to an entity of type "SPI_CallbackFxn" TM4C_SPI_Master.c /RFDDAQ-1J/070_SPIBus line 142 C/C++ Problem
void TM4C_HWI_Timer4_Event(UArg instance) { UInt Hkey; Hkey = Hwi_disable(); // to ensure atomic behaviour. Other HWI event is put to queue by TI-RTOS. GPIO_toggle(EK_PL5_EXP5_TIMINGPIN); Hwi_clearInterrupt(INT_TIMER4A_TM4C129); if(TimerIntStatus(TIMER4_BASE, false) != 0) { //--------------------------Increment DAC Pointer. DACPointer++; if (DACPointer>=16) DACPointer=0; //-------------------------- TimerIntClear(TIMER4_BASE, 0x2FFF); // Clear All Interrupt including TIMER_TIMA_TIMEOUT, etc // Swi_Params swiParams; // Swi_getAttrs(RFD_SWI_DAC12Update_handle, NULL, &swiParams); // Copy parameter from SWI module // swiParams.arg0 = DAC_SineTable[DACPointer]; // Update DAC pointer // //swiParams.arg1 = 0; // Swi_setAttrs(RFD_SWI_DAC12Update_handle, NULL, &swiParams); // Save parameter back to SWI module Swi_post(RFD_SWI_DAC12Update_handle); // Post SWI (see below) } GPIO_toggle(EK_PL5_EXP5_TIMINGPIN); Hwi_restore(Hkey); } //================================================================== //================================================================== RFD_DAC12Update_SWI_Fxn // Purpose : Process SPI operation to update DAC voltage level. // Input : // Output : // Note : The SPI cannot run by HWI so we use SWI. //================================================================== void RFD_DAC12Update_SWI_Fxn(UArg arg0, UArg arg1) { UInt Skey; Skey = Swi_disable(); GPIO_write(EK_PH0_DACTEST_CS, PINLOW); RFD_SPI1_DAQ12_16Bits((uINT16)(arg0 & 0x00000FFF)); Swi_restore(Skey); } void RFD_DAC12Update_test_Fxn(void) { GPIO_write(EK_PH0_DACTEST_CS, PINHIGH); }
Hi Richard,
We don't have any specific examples for SPI using SWI. I think you might have already tried the TI-RTOS SPI example which is using TASK , not SWI. For SWI usage you can refer to the section 3.5 Software Interrupt in the TI-RTOS Kernel user's guide for details.
It is not clear to me what you meant that the SPI stops working after a while. Did the SWI still get called after you think the SPI stops working? Try to place a breakpoint in your SPI function to see if it is getting called.
I'm not a TI-RTOS expert but I don't think it is necessary to disable the SWI if you can setup the correct priority such that your RFD_DAC12Update_SWI_Fxn will not be preempted by other SWIs. Same can be done for the HWI.
Looking at your code, it does not seem that you are using the TI-RTOS provides drivers for SPI but rather you are using the TivaWare drivers for SPI. Is this correct? From a high level I don't see an issue with your usage of the Swi_post() within the HWI ISR. Below is an example code of using the SWI which is similar to what you have.
//---------------------------------------- // BIOS header files //---------------------------------------- #include <xdc/std.h> //mandatory - have to include first, for BIOS types #include <ti/sysbios/BIOS.h> //mandatory - if you call APIs like BIOS_start() #include <xdc/runtime/Log.h> //needed for any Log_info() call #include <xdc/cfg/global.h> //header file for statically defined objects/handles #include <xdc/runtime/System.h> #include <xdc/runtime/Error.h> #include <ti/sysbios/hal/Hwi.h> //------------------------------------------ // TivaWare Header Files //------------------------------------------ #include <stdint.h> #include <stdbool.h> #include "inc/hw_types.h" #include "inc/hw_memmap.h" #include "driverlib/sysctl.h" #include "driverlib/gpio.h" #include "inc/hw_ints.h" #include "driverlib/interrupt.h" #include "driverlib/timer.h" //---------------------------------------- // Prototypes //---------------------------------------- void hardware_init(void); void ledToggle(void); void Timer_ISR(void); //--------------------------------------- // Globals //--------------------------------------- volatile int16_t i16ToggleCount = 0; //--------------------------------------------------------------------------- // main() //--------------------------------------------------------------------------- void main(void) { Hwi_Params hwiParams; Hwi_Handle myHwi; Error_Block eb; /* Initialize error block and hwiParams to default values */ Error_init(&eb); Hwi_Params_init(&hwiParams); hwiParams.enableInt = FALSE; /* Create Hwi on vector 51 which is the TIMER3A */ myHwi = Hwi_create(51, (Hwi_FuncPtr)Timer_ISR, &hwiParams, &eb); if (myHwi == NULL) { System_abort("Hwi create failed"); } Hwi_enableInterrupt(51); Swi_Params swiParams; Swi_Handle LEDSwi; Error_Block eb2; /* Initialize error block and hwiParams to default values */ Error_init(&eb2); Swi_Params_init(&swiParams); LEDSwi = Swi_create((Swi_FuncPtr)ledToggle, &swiParams, &eb2); if (LEDSwi == NULL) { System_abort("Swi create failed"); } hardware_init(); // init hardware via Xware BIOS_start(); } //--------------------------------------------------------------------------- // hardware_init() // // inits GPIO pins for toggling the LED //--------------------------------------------------------------------------- void hardware_init(void) { uint32_t ui32Period; //Set CPU Clock to 40MHz. 400MHz PLL/2 = 200 DIV 5 = 40MHz SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); // ADD Tiva-C GPIO setup - enables port, sets pins 1-3 (RGB) pins for output SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); // Turn on the LED GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 4); // Timer 2 setup code SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER3); // enable Timer 3 periph clks TimerConfigure(TIMER3_BASE, TIMER_CFG_PERIODIC); // cfg Timer 3 mode - periodic ui32Period = (SysCtlClockGet() /2); // period = CPU clk div 2 (500ms) TimerLoadSet(TIMER3_BASE, TIMER_A, ui32Period); // set Timer 3 period TimerIntEnable(TIMER3_BASE, TIMER_TIMA_TIMEOUT); // enables Timer 3 to interrupt CPU TimerEnable(TIMER3_BASE, TIMER_A); // enable Timer 3 } //--------------------------------------------------------------------------- // ledToggle() // // toggles LED on Tiva-C LaunchPad //--------------------------------------------------------------------------- void ledToggle(void) { // LED values - 2=RED, 4=BLUE, 8=GREEN if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2)) { GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0); } else { GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 4); } i16ToggleCount += 1; // keep track of #toggles Log_info1("LED TOGGLED [%u] TIMES",i16ToggleCount); // send toggle count to UIA } //--------------------------------------------------------------------------- // Timer ISR - called by BIOS Hwi (see app.cfg) // // Posts Swi (or later a Semaphore) to toggle the LED //--------------------------------------------------------------------------- void Timer_ISR(void) { TimerIntClear(TIMER3_BASE, TIMER_TIMA_TIMEOUT); // must clear timer flag FROM timer Swi_post(LEDSwi); // post LEDSwi }
So the problem can be either SPI specific or related to how the SPI is used in the Ti-RTOS context which will need more investigation from your side. Do you have many other HWIs/SWIs going on? What if for debugging purpose, you disable/remove these non SPI SWIs? Will it make a difference?
I closing this due to a sidetracked project and will review this discussion in few week time.