Other Parts Discussed in Thread: ADC141S626, SEGGER
Hi All,
I am trying to debug an issue where I expect to read data from the SSI ISR handler when a receive timeout interrupt is triggered, but no data is available. When we read the masked interrupt status it is 0. This should indicate that no interrupt was triggered so why did the processor jump to the interrupt handler?
What we're trying to do:
We use the Timer 0A interrupt to start an SSI transfer using the Tivaware SSIDataPutNonBlocking API. The SSI speed is set to 1MHz and the receive timeout interrupt is enabled so ~48uS later (16 bits SSI + 32 clock timeout) the SSI interrupt triggers. I can verify the timing works as expected with my debugger. The issue is very random, we can do 1000s of data transfers without issue and then one will fail. We can run one system for days without issue and another system will only work for a few minutes.
Debugger Screenshots:
Relevant Code snippets:
#define ADC141_GPIO_PERIPH SYSCTL_PERIPH_GPIOH #define ADC141_PERIPH SYSCTL_PERIPH_SSI2 #define ADC141_GPIO_BASE GPIO_PORTH_BASE #define ADC141_SSI_BASE SSI2_BASE #define ADC141_SCLK_PIN GPIO_PIN_4 #define ADC141_CS_PIN GPIO_PIN_5 #define ADC141_SDO GPIO_PIN_6 #define ADC141_GPIO_SSICLK_CFG GPIO_PH4_SSI2CLK #define ADC141_GPIO_SSIRX_CFG GPIO_PH6_SSI2RX #define ADC141_GPIO_SSICS_CFG GPIO_PH5_SSI2FSS #define ADC141_BAUD 1000000 #define ADC141_PROTOCOL SSI_FRF_MOTO_MODE_3 #define ADC141_MODE SSI_MODE_MASTER #define ADC141_DATAWIDTH 16 /* Initialization code */ SysCtlPeripheralEnable(ADC141_GPIO_PERIPH); SysCtlPeripheralEnable(ADC141_PERIPH); GPIOPinConfigure(ADC141_GPIO_SSICLK_CFG); GPIOPinConfigure(ADC141_GPIO_SSIRX_CFG); GPIOPinConfigure(ADC141_GPIO_SSICS_CFG); GPIOPinTypeSSI(ADC141_GPIO_BASE, ADC141_SCLK_PIN | ADC141_SDO | ADC141_CS_PIN); SSIConfigSetExpClk(ADC141_SSI_BASE, SysCtlClockGet(), ADC141_PROTOCOL, ADC141_MODE, ADC141_BAUD, ADC141_DATAWIDTH); SSIIntEnable(ADC141_SSI_BASE, SSI_RXTO); IntPrioritySet(INT_SSI2, 0xE0); IntEnable(INT_SSI2); SSIEnable(ADC141_SSI_BASE); void TIMER0A_Handler(void) { TimerIntClear(TIMER0_BASE, TimerIntStatus(TIMER0_BASE, false)); SSIDataPutNonBlocking(ADC141_SSI_BASE, 0); } void SSI2_Handler(void) { uint32_t countSamples = 0; int32_t recv = 0; uint32_t ssiStatusRegister = HWREG(ADC141_SSI_BASE + SSI_O_SR); uint32_t ssiRawInterruptStatus = HWREG(ADC141_SSI_BASE + SSI_O_RIS); uint32_t ssiMaskedInterruptStatus = HWREG(ADC141_SSI_BASE + SSI_O_MIS); if((ssiStatusRegister & SSI_SR_RNE) == 0) { __asm("BKPT 0"); } // Read from the SSI receive FIFO, returns number of elements read countSamples = (uint32_t)SSIDataGetNonBlocking(ADC141_SSI_BASE, (uint32_t *)&recv); SSIIntClear(ADC141_SSI_BASE, SSIIntStatus(ADC141_SSI_BASE, false)); /* snip */ }