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