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.

SPI giving back 0xFF Tiva-TM4C1294XL

Other Parts Discussed in Thread: TM4C1294NCPDT

Hi.

I am trying to make a small SPI application with an Accelerometer unit. However, when I try to read the data out of it, I always see a value of 0xFF on the output through UART.  I did set the CS line ( using Port B Pin 1) low before reading/writing data, and then high again when I'm done reading/writing data. I am using the exact code as in the TI/Peripheral/SSI/SPI-MASTER. 

Please help me out as I have been stuck on this for the past 7 days. My code is as follows:

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "drivers/pinout.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
#include "driverlib/ssi.h"
#include "inc/tm4c1294ncpdt.h"

//===================================== INITIALIZE UART ON PORT A =================================================
//=================================================================================================================
void InitUART(void){
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
UARTStdioConfig(0, 115200, 16000000);}
//=================================================================================================================

//===================================== INITIALIZE SPI ON PORT D =================================================
//=================================================================================================================
void InitSSI(void){
ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_OSC), 25000000);
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
SSIDisable(SSI2_BASE);
GPIOPinConfigure(GPIO_PD3_SSI2CLK);
GPIOPinConfigure(GPIO_PD2_SSI2FSS);
GPIOPinConfigure(GPIO_PD1_SSI2XDAT0);
GPIOPinConfigure(GPIO_PD0_SSI2XDAT1);
UARTprintf("\nTest Start");
GPIOPinTypeSSI(GPIO_PORTD_BASE, GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1 | GPIO_PIN_0);
UARTprintf("\nTest Success");
SSIConfigSetExpClk(SSI2_BASE, ui32SysClock, SSI_FRF_MOTO_MODE_0,SSI_MODE_MASTER, 1000000, 8);
SSIEnable(SSI2_BASE);}

//=================================================================================================================

//===================================== NEW SPI WRITE FUNCTION ====================================================
//=================================================================================================================
void SSI2Write(uint32_t SSIData1,uint32_t SSIData2){
GPIO_PORTB_AHB_DATA_R &= ~(1<<1); // Make CS Line low
SysCtlDelay(24000000/3); // Slight Delay
while(SSIBusy(SSI2_BASE))
{}
SSIDataPut(SSI2_BASE, SSIData1);
SSIDataPut(SSI2_BASE, SSIData2);
while(SSIBusy(SSI2_BASE))
{}
SysCtlDelay(24000000/3); // Slight Delay
GPIO_PORTB_AHB_DATA_R |= (1<<1); //Make CS Line High
}
//=================================================================================================================


//===================================== NEW SPI READ FUNCTION ====================================================
//=================================================================================================================
uint32_t SSI2Read(uint32_t Addr, uint32_t Dummy){
uint32_t Data=0;
GPIO_PORTB_AHB_DATA_R &= ~(1<<1); // Make CS Line low
SysCtlDelay(240000/3); // Slight Delay
while(SSIBusy(SSI2_BASE))
{}
SSIDataPut(SSI2_BASE, Addr);
SSIDataPut(SSI2_BASE, Dummy);
while(SSIBusy(SSI2_BASE))
{}
SSIDataGet(SSI2_BASE,&Data);
while(SSIBusy(SSI2_BASE))
{}
SysCtlDelay(240000/3);// Slight Delay
GPIO_PORTB_AHB_DATA_R |= (1<<1); //Make CS Line High
return Data;
}
//=================================================================================================================

/=============================================== MAIN FUNCTION ====================================================
//=================================================================================================================

void main(void){

SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

SysCtlDelay(24000000/3);      // INITIAL DELAY TO ALLOW ACCELEROMETER TO START UP IT'S REGISTERS

InitUART();      // SET UART ON PORT A

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
GPIO_PORTB_AHB_DEN_R |=(1<<1);
GPIO_PORTB_AHB_DIR_R |=(1<<1);
GPIO_PORTB_AHB_DATA_R |= (1<<1); // SETTING FOR PIN B1 TO BE CHIP SELECT LINE

InitSSI();      // SET SSI ON PORT D

UARTprintf("\nAddr: 0x18, Data: 0x38");SSI2Write(0x18,0x38);
UARTprintf("\nAddr: 0x10, Data: 0x60");SSI2Write(0x10,0x60);
UARTprintf("\nAddr: 0x0D, Data: 0x01");SSI2Write(0x0D,0x01); // START THE ACCELEROMETER

SysCtlDelay(24000000/3); //Slight Delay

while(1)
{uint32_t Data=SSI2Read(((0x22)|(0x80)),0x00);
UARTprintf("\nData Received: %i",Data);}

}

//=================================================================================================================

  • Hello Ahmad,

    The issue seems to be in the manner you are doing SSI Transaction. The SSI requires that for every byte you put you get one data in the RXFIFO. Hence when sending the addr the byte that has been shifted in is being read out by the SSIDataGet and not byte corresponding to the SSIDataPut of Dummy byte

    Regards
    Amit
  • Hi Amit.

    Thanks for your reply. I changed my Write and Read codes to the following, but I'm still getting 0xff when I output the data sent from the SSI2Read function. Could you please advise on what I'm still doing wrong ?

    void SSI2Write(uint32_t SSIData1,uint32_t SSIData2){
    GPIO_PORTB_AHB_DATA_R &= ~(1<<1); // Make CS Line low
    SysCtlDelay(24000000/3); // Slight Delay

    while(SSIBusy(SSI2_BASE))
    {}
    SSIDataPut(SSI2_BASE, SSIData1);
    while(SSIBusy(SSI2_BASE))
    {}
    SSIDataPut(SSI2_BASE, SSIData2);
    while(SSIBusy(SSI2_BASE))
    {}
    SysCtlDelay(24000000/3); // Slight Delay
    GPIO_PORTB_AHB_DATA_R |= (1<<1); //Make CS Line High
    }


    uint32_t SSI2Read(uint32_t SSIAddr){
    uint32_t Data=0x00;
    GPIO_PORTB_AHB_DATA_R &= ~(1<<1); // Make CS Line low
    SysCtlDelay(240000/3); // Slight Delay
    while(SSIBusy(SSI2_BASE))
    {}
    SSIDataPut(SSI2_BASE, SSIAddr);
    while(SSIBusy(SSI2_BASE))
    {}
    SSIDataPut(SSI2_BASE,0xFF);
    SSIDataGet(SSI2_BASE,&Data);
    while(SSIBusy(SSI2_BASE))
    {}
    SysCtlDelay(240000/3);// Slight Delay
    GPIO_PORTB_AHB_DATA_R |= (1<<1); //Make CS Line High
    return Data;
    }
  • Hello Ahmad,

    Every SSIDataPut must have a SSIDataGet. This is irrespective of whether it is Write operations from TM4C or Read operations from TM4C. As an example I have edited the Write code. A similar change must be done for read code. Also can you check on a scope or LA what is happening on the MOSI and MISO lines. That will bring a crucially needed debug point.

    void SSI2Write(uint32_t SSIData1,uint32_t SSIData2){
    uint32_t ui32DummyData;
    GPIO_PORTB_AHB_DATA_R &= ~(1<<1); // Make CS Line low
    SysCtlDelay(24000000/3); // Slight Delay

    while(SSIBusy(SSI2_BASE))
    {}
    SSIDataPut(SSI2_BASE, SSIData1);
    while(SSIBusy(SSI2_BASE))
    SSIDataGet(SSI2_BASE, &ui32DummyData);
    {}
    SSIDataPut(SSI2_BASE, SSIData2);
    while(SSIBusy(SSI2_BASE))
    SSIDataGet(SSI2_BASE, &ui32DummyData);
    {}
    SysCtlDelay(24000000/3); // Slight Delay
    GPIO_PORTB_AHB_DATA_R |= (1<<1); //Make CS Line High
    }

    Regards
    Amit