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.

TM4C123G SPI problem

Hi,

I'm using TM4C123G for sending commands through SPI to a Semtech SX1272 transceiver. I've tried almost everything, but nothing works. It seems that SX1272 does not receive anything. I post my code here in case I'm doing sth wrong with TM4C123G.


#include <stdbool.h>
#include <stdint.h>

#include "inc/hw_memmap.h"

#include "inc/hw_types.h"

#include "driverlib/gpio.h" 
#include "driverlib/pin_map.h"
#include "driverlib/ssi.h"
#include "driverlib/sysctl.h"

#define NUM_BYTES_SSI 2

int main(void) {
uint32_t pui32DataTx1 [NUM_BYTES_SSI];
uint32_t pui32DataTx2 [NUM_BYTES_SSI];
uint32_t pui32DataTx3 [NUM_BYTES_SSI];
uint32_t pui32DataTx4 [NUM_BYTES_SSI];
uint32_t pui32DataTx5 [NUM_BYTES_SSI];
uint32_t pui32DataRx [NUM_BYTES_SSI];
uint32_t ui32Index, i, k;

uint32_t TS_OSC=250*16/3;
uint32_t TS_FS=60*16/3;
uint32_t TS_TR=120*16/3;

uint8_t ui8LED=2;

SysCtlPeripheralEnable (SYSCTL_PERIPH_GPIOF);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3)

SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

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, 1000000, 8);

SSIEnable (SSI0_BASE);

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

/////Simple FSK Tx/////
pui32DataTx1[0]=0x81; //RegOpMode (w)
pui32DataTx1[1]=0x00; //Sleep

pui32DataTx2[0]=0x81; //RegOpMode (w)
pui32DataTx2[1]=0x01; //Stdby

pui32DataTx3[0]=0x81; //RegOpMode (w)
pui32DataTx3[1]=0x02; //FSTx

pui32DataTx4[0]=0x81; //RegOpMode (w)
pui32DataTx4[1]=0x03; //Tx

for (ui32Index=0; ui32Index<NUM_BYTES_SSI; ui32Index++)
{
SSIDataPut (SSI0_BASE, 0xFF);
SSIDataPut (SSI0_BASE, pui32DataTx1[ui32Index]);
}

while (SSIBusy(SSI0_BASE))
{
}

SysCtlDelay(TS_OSC);

for (ui32Index=0; ui32Index<NUM_BYTES_SSI; ui32Index++)
{
SSIDataPut (SSI0_BASE, 0xFF);
SSIDataPut (SSI0_BASE, pui32DataTx2[ui32Index]);
}

while (SSIBusy(SSI0_BASE))
{
}

SysCtlDelay(TS_OSC+TS_FS);

for (ui32Index=0; ui32Index<NUM_BYTES_SSI; ui32Index++)
{
SSIDataPut (SSI0_BASE, 0xFF);
SSIDataPut (SSI0_BASE, pui32DataTx3[ui32Index]);
}

while (SSIBusy(SSI0_BASE))
{
}

SysCtlDelay(TS_OSC+TS_FS+TS_TR);

for (ui32Index=0; ui32Index<NUM_BYTES_SSI; ui32Index++)
{
SSIDataPut (SSI0_BASE, 0xFF);
SSIDataPut (SSI0_BASE, pui32DataTx4[ui32Index]);
}

while (SSIBusy(SSI0_BASE))
{
}
SysCtlDelay(TS_OSC+TS_FS+TS_TR);

for (i=0; i<3; i++)
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, ui8LED);
// Delay for a bit
SysCtlDelay(2000000);
//SysCtlDelay(3000000*16/3);
// Cycle through Red, Green and Blue LEDs
if (ui8LED == 8)
{
ui8LED = 2;
}
else
{
ui8LED = ui8LED*2;
}
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 5);
}

for (ui32Index=0; ui32Index<NUM_BYTES_SSI; ui32Index++)
{
SSIDataPut (SSI0_BASE, 0xFF);
SSIDataGet (SSI0_BASE, &pui32DataRx[ui32Index]);
}

return 0;
}

Thanks in advance,

Alberto

  • Hello Alberto,

    I checked the code and it works fine on the TM4C123 LaunchPad. The CLK, FSS and TXD toggle as expected. The LED's glow as expected (Red-Blue-Green-Blue)

    Couple of things you would want to do

    1. When doing only SSIDataPut operation loop, also do a SSIDataGet so that the RXFIFO is flushed.

    2. I tried checking the data sheet but it does not open (you can attach the same if you have it). If the requirement from the part is that the CS be held low for the duration of the SSI TX, then change the SSI FSS pin to a GPIO and make it low during the SSI Transmission and high when SSI is Idle

    Regards

    Amit

  • Hi Amit, thanks for your answer.

    The SSI connection is configured as Freescale Mode 0 (Polarity=0, Phase=0) so the CS goes low when transmitting and high when idle. SX1272 requires Freescale Mode 0 so I guess this is not the problem. Furthermore, I manually checked all four SPI signals with an oscilloscope and everything is right.

    I tried to do a SSIDataGet in the loops, but nothing happens. 

    Maybe I should take a look to a code example that uses SPI with another device?

    5165.sx1272.pdf

    Thanks again, 

    Alberto

  • Hello Alberto,

    Thanks for sending the PDF.

    As I suspected, the device actually expects the CS (or FSS) to be low for the full transmission. So you would need to configure FSS Pin as a GPIO and then keep it High when SSI is Idle.

    When you need to send a data then make the FSS Pin by a GPIOPinWrite as 0 complete the for loop of sending the bytes and then make the FSS Pin high.

    Regards

    Amit

  • Hi Amit, 

    I've tried what you suggested, but nothing happens. I shall copy my code read/write operations here in case I made a mistake.

    Write:

    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 0x00); //CS low
    SSIDataPut (SSI0_BASE, 0xFF); //dummy byte
    for (ui32Index=0; ui32Index<NUM_BYTES_SSI; ui32Index++)
    {
    SSIDataPut (SSI0_BASE, pui32DataTx1[ui32Index]);
    }
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 0xFF); //CS high

    while (SSIBusy(SSI0_BASE)){}

    Read:

    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 0x00); //CS low
    SSIDataPut (SSI0_BASE, 0x02); //read address
    SSIDataPut (SSI0_BASE, 0xFF); //dummy byte
    SSIDataGet (SSI0_BASE, &pui32DataRx[0]);
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 0xFF); //CS high

    Thanks in advance,

    Alberto

  • Hello Alberto,

    Changes as follows

    Write:

    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 0x00); //CS low
    SSIDataPut (SSI0_BASE, 0xFF); //dummy byte

    SSIDataGet (SSI0_BASE, &pui32DummyData); //dummy byte
    for (ui32Index=0; ui32Index<NUM_BYTES_SSI; ui32Index++)
    {
    SSIDataPut (SSI0_BASE, pui32DataTx1[ui32Index]);

    SSIDataGet (SSI0_BASE, &pui32DummyData); //dummy byte
    }

    while (SSIBusy(SSI0_BASE)){}

    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 0xFF); //CS high

    Read:

    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 0x00); //CS low
    SSIDataPut (SSI0_BASE, 0x02); //read address

    SSIDataGet (SSI0_BASE, &pui32DummyData); //dummy byte
    SSIDataPut (SSI0_BASE, 0xFF); //dummy byte
    SSIDataGet (SSI0_BASE, &pui32DataRx[0]);

    while (SSIBusy(SSI0_BASE)){}
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 0xFF); //CS high

    Regards

    Amit