Hi,
I am using TM4C1294NCPDT plays the role of SPI slave. The protocol between master and slave is using 5 bytes.
Three instruction bytes and two data bytes. Now, I face two problems.
1. Always outputs nothing at first transmit after boot-up. The second transmit outputs signal. Below is the first run screenshot.
(Yellow: CS, Blue: Clock, Green: Master request, Pink: Slave response)
Below is the second run screen shot.
(Yellow: CS, Blue: Clock, Green: Master request, Pink: Slave response)
2. Slave response data always appear on next transmit
Example: Slave should send data 0x08 at this time, but 0x08 appears at the next transmit
Run 0 1 2 3 4
Should 0x08 0x09 0x0A 0x0B 0x0C
Actual 0x00 0x08 0x09 0x0A 0x0B
Below is the SSI setting
void ssi0Init(void) { UINT32 g_ulDataRx[5]; // // The SSI0 peripheral must be enabled for use. // SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0); // // For this example SSI0 is used with PortA[5:2]. GPIO port A needs to be // enabled so these pins can be used. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // // Configure the pin muxing for SSI0 functions on port A2, A3, A4, and A5. // This step is not necessary if your part does not support pin muxing. // GPIOPinConfigure(GPIO_PA2_SSI0CLK); GPIOPinConfigure(GPIO_PA3_SSI0FSS); GPIOPinConfigure(GPIO_PA4_SSI0XDAT0); GPIOPinConfigure(GPIO_PA5_SSI0XDAT1); // // Configure the GPIO settings for the SSI pins. This function also gives // control of these pins to the SSI hardware. Consult the data sheet to // see which functions are allocated per pin. // The pins are assigned as follows: // PA5 - SSI0Tx // PA4 - SSI0Rx // PA3 - SSI0Fss // PA2 - SSI0CLK // GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2); // // Configure and enable the SSI0 port for SPI master mode. // SSIConfigSetExpClk(SSI0_BASE, g_ui32SysClock, SSI_FRF_MOTO_MODE_0, SSI_MODE_SLAVE, 1000000, 8); //SSIAdvModeSet(SSI0_BASE, SSI_ADV_MODE_LEGACY); // // Enable the SSI0 module. // SSIEnable(SSI0_BASE); // // Enable RX timeout interrupt. // SSIIntEnable(SSI0_BASE, SSI_RXTO); // // Read any residual data from the SSI port. This makes sure the receive // FIFOs are empty, so we don't read any unwanted junk. This is done here // because the SPI SSI mode is full-duplex, which allows you to send and // receive at the same time. The SSIDataGetNonBlocking function returns // "true" when data was returned, and "false" when no data was returned. // The "non-blocking" function checks if there is any data in the receive // FIFO and does not "hang" if there isn't. // while(SSIDataGetNonBlocking(SSI0_BASE, &g_ulDataRx[0])) { } // // Clear any pending interrupt // SSIIntClear(SSI0_BASE, SSI_RXTO); // // Enable the SSI2 interrupts to ARM core. This has to be done here, // otherwise the RX timeout interrupt will fire before all the data has // been transferred. This is specific to this example as both the SSI // master and slave are on the same microcontroller. // IntEnable(INT_SSI0); }
Below is the Interrupt Handler
void SSI0IntHandler(void) { uint32_t i; uint32_t int_status; //Get the interrrupt status. int_status = SSIIntStatus(SSI0_BASE, true); // Clear the asserted interrupts. if(int_status&SSI_RXTO) { ssi0INT = 1;//semaphore for(i=0;i<5;i++) { SSIDataGet(SSI0_BASE, &ssi0RxBUFF[i]); } } SSIIntClear(SSI0_BASE, int_status); }
Below is the main task
uint8_t ssi0RxBUFF[5]; uint8_t ssi0TxBUFF[5]; uint32_t ssi0INT; uint32_t ssi0XmitCnt = 5; INT32 ATU_Service(void) { uint32_t idx; UINT8 vswr_value_h, vswr_value_l; CALI_FREQ_INFO_ENTRY_S pData; UINT16 data; if(ssi0INT) { ssi0INT = 0; memcpy(ssi0TxBUFF, ssi0RxBUFF, 5); ssi0TxBUFF[4] = ssi0XmitCnt++; for(idx=0;idx<5;idx++) { SSIDataPutNonBlocking(SSI0_BASE, ssi0TxBUFF[idx]); } IoPrintf("\r\n Input = "); for(idx=0;idx<5;idx++) { IoPrintf("0x%02x ",ssi0RxBUFF[idx]); } IoPrintf("\r\n Output = "); for(idx=0;idx<5;idx++) { IoPrintf("0x%02x ",ssi0TxBUFF[idx]); } } } main(void) { ssi0Init(); while(1) { ATU_Service(); } }
I appreciate any help or guidance that is provided!
Regards,
Collin