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.

issues with testing an spi interface

Other Parts Discussed in Thread: TM4C123GH6PM

Hi, I have written some code in order to activate an SPI interface on my TM4C123GH6PM micro.

#include "tm4c123gh6pm.h"
#include <stdint.h>

void ssi_init(void){
	volatile unsigned long delay;
	SYSCTL_RCGC1_R |= SYSCTL_RCGC1_SSI0;		//activate SSI0 
	SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOA;		//activate clock to PORTA
	delay = SYSCTL_RCGC2_R;
	GPIO_PORTA_AFSEL_R |= 0x2C;					//activate alternate function on PA2,3,5
	GPIO_PORTA_PCTL_R = (GPIO_PORTA_PCTL_R&0xFF0F00FF)+0x00202200;		//pin control given to SSI0Fss, SSI0Clk and SSI0Tx
	GPIO_PORTA_DEN_R |= 0x2C;		//enable digital on each pin
	SSI0_CR1_R &= ~SSI_CR1_SSE;		//disable SSI during config
	SSI0_CR1_R &= ~SSI_CR1_MS;		//master mode
	SSI0_CPSR_R = (SSI0_CPSR_R&~SSI_CPSR_CPSDVSR_M)+2;				//8MHZ
	SSI0_CR0_R &= ~(SSI_CR0_SCR_M | SSI_CR0_SPH | SSI_CR0_SPO);	//Freescale SPH=SPO=0
	SSI0_CR0_R = (SSI0_CR0_R&~SSI_CR0_FRF_M)+SSI_CR0_FRF_MOTO;
	SSI0_CR0_R = (SSI0_CR0_R&~SSI_CR0_DSS_M)+SSI_CR0_DSS_8;		//Frame length is 8-bit
	SSI0_CR1_R |= SSI_CR1_SSE;		//enable SSI
}

void data_send(unsigned char data){
	while((SSI0_SR_R&0x00000002)==0){};		//Wait for buffer
	SSI0_DR_R = data;							//send data
}



int main(void){
	unsigned char data = 0xAA;
	ssi_init();
	while(1){
		data_send(data);
	}
}
		
		
		

The file contains an initialisation routine which was created using the databook and examples from Jonathan Valvano's book as a general guide. There is a second routine which places the test data into the SSI_DR register. To test it I i initialised a test frame and then just repeatedly call the data send routine.

Now my thoughts are that I should be able to see the pin change on SSIClk, SSITx and SSIFss using an oscilloscope but clearly I am doing something wrong because I can't see anything. Is it the code or my method of testing the interface or both. All help is greatly appreciated.

  • Hello Richard,

    The procedure looks right, except for flushing of the RXFIFO. I would do the code in the following manner

    #include <stdint.h>
    #include "inc/hw_sysctl.h"
    #include "inc/hw_gpio.h"
    #include "inc/hw_ssi.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/ssi.h"
    #include "inc/tm4c123gh6pm.h"
    
    void ssi_init(void){
        SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        GPIOPinConfigure(GPIO_PA2_SSI0CLK);
        GPIOPinConfigure(GPIO_PA3_SSI0FSS);
        GPIOPinConfigure(GPIO_PA4_SSI0RX);
        GPIOPinConfigure(GPIO_PA5_SSI0TX);
    
        GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 |
                       GPIO_PIN_2);
        SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
                           SSI_MODE_MASTER, 8000000, 8);
        SSIEnable(SSI0_BASE);
    }
    
    void data_send(unsigned char data){
        uint32_t ui32ReadData;
        SSIDataPut(SSI0_BASE, data);
        while(SSIBusy(SSI0_BASE))
        SSIDataGet(SSI0_BASE, ui32ReadData);
    }
    
    
    
    int main(void){
    	unsigned char data = 0xAA;
    	ssi_init();
    	while(1){
    		data_send(data);
    	}
    }
    		
    		
    		

    This is based on the example for SSI. It is a working solution and is easier to debug and use

    Regards

    Amit

  • Hello Amit,

    Thankyou for your response. Just one query. What do you mean by flushing the RXFIFO. I thought I hadn't configured it for use?

    Kind Regards

    Richard

  • Hello Richard,

    The flushing of RXFIFO involves reading the RXFIFO, which may have been left in the code due to a previous run of the code (especially if we use CCS Restart Option)/ This will ensure that the RXFIFO is always empty

        while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx[0]))
        {
        }

    Another way of flushing the RXFIFO is to reset the peripheral before enabling the peripheral using SysCtlPeripheralReset API Call before SysCtlPeripheralEnable API Call.


    Regards

    Amit