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.

TM4C1294NCPDT: SPI communication issues with LIS3DHTR

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: CC1101

I am trying to comunicate by SPI a TM4C1294 with a LIS3DHTR, but I have some trouble.

I am using a custom board and I have connected the acelerometer to SSI0 port, I have a cc1101 device connected to this port also.

This is the SPI initialization code I am using:

void ACC_config(uint32_t clock,int16_t *acc1,int16_t *acc2,int16_t *acc3, int16_t *inc1,int16_t *inc2,int16_t *inc3)
{
sysclock=clock;
ACC1=acc1;
ACC2=acc2;
ACC3=acc3;
INC1=inc1;
INC2=inc2;
INC3=inc3;

SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);

while(!SysCtlPeripheralReady(SYSCTL_PERIPH_SSI0))
{
}


SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_3);
GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_PIN_3);

/* IO port is configured as SSI function */
GPIOPinConfigure(GPIO_PA2_SSI0CLK);
GPIOPinConfigure(GPIO_PA3_SSI0FSS);
GPIOPinConfigure(GPIO_PA4_SSI0XDAT0);
GPIOPinConfigure(GPIO_PA5_SSI0XDAT1);

/* Set the mode of the SSI IO port */
GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5);

SSIDisable(SSI0_BASE);

/* SSI configuration Mode 3 (Polarity = 1 Phase = 1) Master mode Speed ​​1MHz Data length 8 bits*/
//SSIConfigSetExpClk(SSI0_BASE, sysclock, SSI_FRF_MOTO_MODE_1, SSI_MODE_MASTER, 100000, 16);
SSIConfigSetExpClk(SSI0_BASE, sysclock, SSI_FRF_MOTO_MODE_2, SSI_MODE_MASTER, 100000, 8);
/* Enable SSI0 */
SSIEnable(SSI0_BASE);
uint32_t pui32DataRx;
while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx))
{
}


lis3dh_configure();

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Where clock is:

g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

These are the read/write functions I am using:

void lis3dh_read_xyz(int16_t *x, int16_t *y, int16_t *z)
{

//uint8_t ansbuf[2];

lis3dh_read_reg(0x20,&reg1);
lis3dh_read_reg(0x23,&reg4);

lis3dh_read_reg(LIS3DH_WHO_AM_I, &id);
lis3dh_read_reg(LIS3DH_OUT_X_L, &x_l);
lis3dh_read_reg(LIS3DH_OUT_X_H, &x_h);

lis3dh_read_reg(LIS3DH_OUT_Y_L, &y_l);
lis3dh_read_reg(LIS3DH_OUT_Y_H, &y_h);

lis3dh_read_reg(LIS3DH_OUT_Z_L, &z_l);
lis3dh_read_reg(LIS3DH_OUT_Z_H, &z_h);

*x= (x_h <<8 | x_l); // 12 bit data
*y= (y_h <<8 | y_l); // 12 bit data
*z= (z_h <<8 | z_l); // 12 bit data

}

void lis3dh_read_reg(uint8_t addr, uint8_t *DataRead)
{
uint8_t dummy;
uint8_t operation;
uint8_t byte;
uint32_t ui32DummyData;
uint32_t address;
operation = LIS3DH_SINGLE_READ;

lis3dh_CsStart();


address=(operation|addr);
// TX
while (SSIBusy(SSI0_BASE)) ;
SSIDataPut(SSI0_BASE, (address)); //Puts a data element into the SSI transmit FIFO

// WAIT DONE
while (SSIBusy(SSI0_BASE));

SSIDataGet(SSI0_BASE, &dummy);

SSIDataPut(SSI0_BASE, (0x00)); //Puts a data element into the SSI transmit FIFO
// WAIT DONE
while (SSIBusy(SSI0_BASE));
SSIDataGet(SSI0_BASE, &byte);

readed= byte;
*DataRead=readed;
lis3dh_CsStop();
}

void lis3dh_mult_read_reg(uint8_t addr, uint8_t *DataRead, uint8_t len)
{
uint8_t operation;
uint8_t address;
uint8_t byte;
uint8_t dummy;
if(len > 1){
operation = LIS3DH_MULTIPLE_READ;
}else{
operation = LIS3DH_SINGLE_READ;
}

lis3dh_CsStart();
//SysCtlDelay(5);
address=operation|addr;

while (SSIBusy(SSI0_BASE));
SSIDataPut(SSI0_BASE, address); //Puts a data element into the SSI transmit FIFO

// WAIT DONE
while (SSIBusy(SSI0_BASE));
SSIDataGet(SSI0_BASE, &dummy);

uint8_t i;
for(i=0; i<len; i++)
{
// TX DUMMY 0s
SSIDataPut(SSI0_BASE, (0x00));

// WAIT DONE
while (SSIBusy(SSI0_BASE));
// RX
SSIDataGet(SSI0_BASE, &byte);

DataRead[i] = byte;
}
//SysCtlDelay(5);
lis3dh_CsStop();
}

void lis3dh_write_reg(uint8_t addr, uint8_t DataWrite)
{
uint8_t operation = LIS3DH_SINGLE_WRITE;
uint32_t ui32DummyData;
uint32_t address;
uint8_t dummy;

lis3dh_CsStart();
//SysCtlDelay(5);
address=(operation|addr);
// TX OP + ADDR
while (SSIBusy(SSI0_BASE)) ;
SSIDataPut(SSI0_BASE, address); //Puts a data element into the SSI transmit FIFO
// WAIT DONE
while (SSIBusy(SSI0_BASE));
SSIDataGet(SSI0_BASE, &dummy);

SSIDataPut(SSI0_BASE, DataWrite); //Puts a data element into the SSI transmit FIFO

// WAIT DONE
while (SSIBusy(SSI0_BASE));
SSIDataGet(SSI0_BASE, &dummy);

//SysCtlDelay(5);
lis3dh_CsStop();

}

Any suggestion?

Thanks in advance.

  • Hello Ander,

    From looking at the datasheet and reviewing SPI specs it looks like this device uses SPI Mode 3. You have code showing both Mode 1 and Mode 2 have been tried, but have you tried SSI_FRF_MOTO_MODE_3?

    The other thing I would recommend is getting an LSA (or if needed, an oscilloscope) on the lines to see what is being output by the MCU and any potential response from the target device.

    Best Regards,

    Ralph Jacobi

  • Thanks for de answer Ralph!

    I have been trying with all modes, but looking the datasheet (". SDI and SDO are respectively the serial port data input and output. Those lines are driven at the falling edge of SPC and should be captured at the rising edge of SPC.") and reading this introduction to SPI ("Figure 5. SPI Mode 2, CPOL = 1, CPHA = 0: CLK idle state = high, data sampled on the rising edge and shifted on the falling edge."), I have interpreted the MODE 2 was the correct mode.

    Anyway, I have the SPI comunication with the LIS3DHTR running. I Have follow these steps:

    1. I have chose the SSI_FRF_MOTO_MODE_0 (I will try with other modes)
    2. The SPI bus is shared between LISD3HTR and CC1101 ics. I set the CC1101 to High to avoid interferences.
    3.  I control the LIS3DHTR CS manually. It was managed by SSI peripheral and It went High between the adress byte and dummy byte. I think this was reseting the read operation.

    Now I will try to get comunicating with the CC1101.