Hello all.
I'm working with SPI and the TM4C is in a slave configuration. I need to send up to (120) 16-bit words to the TM4C in one data stream from the master device. Essentially this is a command buffer from which the TM4C will perform certain operations.
The master has software timed SPI, so there is variation in the transfer rate. Each transfer looks slightly different. A capture from the logic analyzer shows this (each "blip" is a 16-bit word). Chip select (FSS) is toggled between each word.
When I send the 120 test words, the TM4C interrupt triggers correctly, but I am only able to read out at most the first 8 words (a full FIFO worth). The rest of the data is "lost" in the ether.
Based on what I am seeing, the first interrupt triggered is RXTO, which does not seem to make sense. I would have thought RXFF would have been the flag. Regardless, I always see RXTO followed, often but not always, by RXOR.
My configuration of the peripheral is:
ROM_SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_SSI1);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);
GPIOPinUnlockGPIO(GPIO_PORTF_BASE, GPIO_PIN_0); // Unlock protected PF0 GPIO
GPIOPinConfigure(GPIO_PF0_SSI1RX);
GPIOPinConfigure(GPIO_PF1_SSI1TX);
GPIOPinConfigure(GPIO_PF2_SSI1CLK);
GPIOPinConfigure(GPIO_PF3_SSI1FSS);
GPIOPinTypeSSI(GPIO_PORTF_BASE,GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_0);
SSIDisable(SSI1_BASE);
ROM_SSIConfigSetExpClk(SSI1_BASE,ROM_SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,SSI_MODE_SLAVE,385000,16);
SSIEnable(SSI1_BASE);
// ENABLE INTERRUPT ON THE SPI1 Rx FIFO
IntRegister(INT_SSI1, SPI_ISR_Handler);
IntEnable(INT_SSI1);
// Clear out any potential stale data from the Rx FIFO
while(SSIDataGetNonBlocking(SSI1_BASE, &cmd_buffer[0])){}
cmd_buffer[0] = 0;
SSIIntClear(SSI1_BASE, SSI_RXFF | SSI_RXTO | SSI_RXOR);
SSIIntEnable(SSI1_BASE, SSI_RXFF | SSI_RXTO | SSI_RXOR);
IntMasterEnable();
My interrupt contains the following read code:
void SPI_ISR_Handler (void) {
volatile uint32_t ui32Index = 0;
uint16_t isr_source = SSIIntStatus(SSI1_BASE, 1);
if (isr_source & SSI_RXTO) {
while (SSI1_SR_R & SSI_SR_RNE) {
SSIDataGet(SSI1_BASE, &cmd_buffer[ui32Index]);
ui32Index++;
}
SSIIntClear(SSI1_BASE, SSI_RXTO);
}
if (isr_source & SSI_RXFF) {
while (SSI1_SR_R & SSI_SR_RNE) {
SSIDataGet(SSI1_BASE, &cmd_buffer[ui32Index]);
ui32Index++;
}
SSIIntClear(SSI1_BASE, SSI_RXFF);
}
if (isr_source & SSI_RXOR) {
while (SSI1_SR_R & SSI_SR_RNE) {
SSIDataGet(SSI1_BASE, &cmd_buffer[ui32Index]);
ui32Index++;
}
SSIIntClear(SSI1_BASE, SSI_RXOR);
}
}
Can anyone suggest a better method to ensure that I capture all 120 words (or fewer, depending upon the command length)?
Also, for understanding, with the Rx FIFO ignore everything beyond the first 8 words until a read is performed? This is how it appears, but I want to make sure that this is correct.
Thank you!
