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!