This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C1294 SSI transmit Receive Interrupt issue



Hello All,

I am currently working on TM4C1294 board.

I have issue while using SSI interrupt.

I have configured two boards as Master and Slave on SSI freq of 10Mhz for 16bits in legacy mode with INT_RXFF enable only.

I am successfully able to transmit data of 16 bit to slave.

but issue is when slave transmit response to Master side. i am unable to receive correct data.

e.g.

From Master -> Slave (0x700F,0xFFFF,0x7FFD,0x7444) this case is fine.same sequence i observed on slave side ever time.

From slave -> Master (0x700F,0xFFFF,0x7FFD,0x7444) this case has error.

i got on Master side (0x0000,0x0000,0x0000,0x000) first time.

then second time (0x0000,0xFFFF,0x7FFD,0x7444) then

third time (0x7444,0xFFFF,0x7FFD,0x7444) and then i got third sequence continuous.

Please help me.

Thanks

Viraj

  • Hello Viraj

    How Can I tell what is happening w/o having the master and slave side configuration and code!!!

    However some tips on such a communication

    1. Always Start the application with a SysCtlPeripheralReset to the SSI Controller to ensure no stale data remains in the SSI FIFO
    2. Ensure that the SSI Clock is first kept at a lower frequency like 100KHz to ensure that it is not a wiring artifact creating setup issues
    3. Ensure that the Slave sends the data after it gets a data. This will prevent a FIFO overwrite as the Slave is an independent device. Also most SSI Slaves work in the manner where the first transaction is generally not sent as a Command Phase is associated with it.

    Regards
    Amit
  • SPI.zipHello Amit,

    Sorry My bad.

    Please find the attached code for both Master and slave.

    One more thing that while sending back data from slave to Master if i put condition for busy ssi then it get stuck in that.so i have commented.

    Thanks

    Viraj

  • Hello Viraj,

    The Master expects 4 units of data but slave is writing 5 words to the FIFO is the first mismatch I see. Secondly, the protocol can be simplified by the fact that the slave is sending a fixed pattern 0x1111. Can you instead simplify the code, that till the CPU on the Master does not see 0x1111 it will perform dummy SSIDataPut. On the byte it sees 0x1111, it will perform a fixed number of writes to get the slave message.

    On the Slave side, once the valid number of TX from master is completed, it shall flush the remaining bytes. I do not see why a timer needs to be made on the slave side for periodic writes. A simple mismatch on the timer can cause FIFO overflow for the slave.

    Regards
    Amit
  • Hello Amit,

    Sorry for delay reply i was busy in another interface for the same project.

    I have changed the code for Master.I have kept SSI Recieve configuration on interrupt based in SSI_TXFF mode.

    Now i am doing loopback data from master MOSI to MISO.I receive successfully data of 16 bytes at a time but then after my FIFO is overrrun if i send more data(e.g. more than 16 bytes).

    I also know that FIFO size is 16 bits x 8 location (16 bytes) but how it work i dont get it.

    I have also checked with SSI_TXOR but again i am unable to receive any interrupt after FIFO overrun.When it get overrun ? and how to agian recieve interrupt for same?

    Can you please suggest me ?

    I have attached my code below.

    Thanks

    Viraj

    //My init function
    
    	//
    	// The SSI0 peripheral must be enabled for use.
    	//
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
    
    	//
    	// For this example SSI0 is used with PortA[5:2].  The actual port and
    	// pins used may be different on your part, consult the data sheet for
    	// more information.  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 - SSI0Rx
    	//      PA4 - SSI0Tx
    	//      PA3 - SSI0Fss
    	//      PA2 - SSI0CLK
    	GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2);
    
    
    	//
    	// Configures the synchronous serial interface.
    	// This function configures the synchronous serial interface.  It sets
    	// the SSI protocol, mode of operation, bit rate, and data width.
    	//
    	SSIConfigSetExpClk(SSI0_BASE, ui32SysClockfreq, SSI_FRF_MOTO_MODE_1,SSI_MODE_MASTER, ui32SPIClockfreq, 16);
    
    	//
    	// Enable the SSI0 module.
    	//
    	SSIEnable(SSI0_BASE);
    
    	//
    	// Enable the Interrupt source SSI_RXFF for Recieve FIFO full or less.
    	//
    	SSIIntEnable(SSI0_BASE, SSI_RXFF);
    
    	//
    	// Enable the Interrupt source SSI_RXFF for Recieve FIFO full or less.
    	//
    	SSIIntEnable(SSI0_BASE, SSI_RXOR);
    
    	//
    	// Disable the all other Interrupt sources
    	//
    	SSIIntDisable(SSI0_BASE, SSI_TXFF);
    	SSIIntDisable(SSI0_BASE, SSI_TXEOT);
    	SSIIntDisable(SSI0_BASE, SSI_RXTO);
    
    	//
    	// clear any pending interrupt
    	//
    	SSIIntClear(SSI0_BASE, SSI_RXFF);
    	SSIIntClear(SSI0_BASE, SSI_RXOR);
    
    
        return (void)0;
    
    
    
    //My Transmit code on Master side 
    	uint32_t l_i_data1[2] = {0xAAAA,0xAAAA};
    
    	
    	if (SSIDataPutNonBlocking(SSI0_BASE, l_i_data1[0]) != 0 )
    	{
    
    	}
    
    	Wait until SSI0 is done transferring all the data in the transmit FIFO.
    	while( SSIBusy(SSI0_BASE) )
    	{ ; }
    
    
    	if (SSIDataPutNonBlocking(SSI0_BASE, l_i_data1[1]) != 0 )
    	{
    
    	}
    
    	
    	while( SSIBusy(SSI0_BASE) )
    	{ ; }
    
    	if (SSIDataPutNonBlocking(SSI0_BASE, l_i_data1[0]) != 0 )
    	{
    
    	}
    
    	Wait until SSI0 is done transferring all the data in the transmit FIFO.
    	while( SSIBusy(SSI0_BASE) )
    	{ ; }
    
    
    	if (SSIDataPutNonBlocking(SSI0_BASE, l_i_data1[1]) != 0 )
    	{
    
    	}
    
    	
    	while( SSIBusy(SSI0_BASE) )
    	{ ; }
    	return (void)NO_ERROR;
    	
    	
    //My receive handler code on Master side. interrupt base.
    
    	uint32_t  ulStatus;
    
    
    	//
    	// Read interrupt status.
    	//
    	ulStatus = SSIIntStatus(SSI0_BASE, 1);
    
    
    	if(ulStatus & SSI_RXFF  || ulStatus & SSI_RXOR)
    	{
    		//
    		// Read NUM_SSI_DATA bytes of data from SSI2 RX FIFO.
    		//
    		while(!SSIDataGetNonBlocking(SSI0_BASE, &g_ul_SSIDataRx[0]))
    		{
    		}
    		while(!SSIDataGetNonBlocking(SSI0_BASE, &g_ul_SSIDataRx[1]))
    		{
    		}
    		while(!SSIDataGetNonBlocking(SSI0_BASE, &g_ul_SSIDataRx[2]))
    		{
    		}
    		while(!SSIDataGetNonBlocking(SSI0_BASE, &g_ul_SSIDataRx[3]))
    		{
    		}
    
    #ifdef DEBUG_UART
    		UARTprintf("\nFirst\n");
    		UARTprintf("\nRX[0].%x\n",g_ul_SSIDataRx[0]);
    		UARTprintf("\nRX[1] %x\n",g_ul_SSIDataRx[1]);
    		UARTprintf("\nRX[2] %x\n",g_ul_SSIDataRx[2]);
    		UARTprintf("\nRX[3] %x\n",g_ul_SSIDataRx[3]);
    #endif /*DEBUG_UART*/
    
    
    	}
    
    
    	//
    	// Clear interrupts.
    	//
    	SSIIntClear(SSI0_BASE, ulStatus);
    
    #ifdef DEBUG_UART
    	UARTprintf("\nClear interrupts: %x\n",ulStatus);
    #endif /*DEBUG_UART*/
    

  • Hello Viraj

    There is nothing called SSI_TXOR. There is only SSI_RXOR which is receiver Fifo overrun. This happens when the CPU does not read fast enough from the FIFO of the Receiver to cause it to drain before the next word/byte is received.

    I checked the code and that you are writing 4 bytes. So that should not cause the overrun. Secondly the SSI Interrupt is not enabled at the NVIC. Thirdly the SSI RXTO is disabled. So if there is data in the FIFO that is not reached the RXFF mark it will not trigger an interrupt.

    Regards
    Amt