cancel
Showing results for 
Search instead for 
Did you mean: 

H3LIS200DL SPI Configuration & Read

Rogers.Gary
Senior II
Posted on June 12, 2017 at 00:54

Hello:

According to all the documentation I can find, I have configured the STM32F4 correctly to interface to the H3LIS200DL accelerometer. This is for use in SPI3 (AF6). Somehow, there's still something amiss. When I try to send/read the 'WHO_AM_I' register, it only returns 0. Here's my setup code:

void configH3LIS200DL( void )

{

    GPIO_InitTypeDef GPIO_InitStructure;

    SPI_InitTypeDef  SPI_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD, ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);

    //Initialize pins for SPI functionality

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_Init(GPIOC, &GPIO_InitStructure);

    

    //Initialize Chip Select pin

    GPIO_InitStructure.GPIO_Pin = ACCHI_CS;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_Init(GPIOD, &GPIO_InitStructure);

    GPIO_SetPinHigh(GPIOD, ACCHI_CS);    

    SPI_I2S_DeInit(SPI3);

    GPIO_PinAFConfig (GPIOC, GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12, GPIO_AF_SPI3);

    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

    SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

    SPI_InitStructure.SPI_CRCPolynomial = 0;

    SPI_Init(SPI3, &SPI_InitStructure);

    SPI_Cmd(SPI3, ENABLE);

}

//the function to send and receive

uint8_t SPI3_Send( uint16_t dataIn )

{

    GPIO_SetPinLow(GPIOD, GPIO_Pin_0);

    // write data to be transmitted to the SPI data register

    SPI3->DR = dataIn;

    // wait until transmit complete

    while( !(SPI3->SR & SPI_I2S_FLAG_TXE) );

    // wait until receive complete    

    while( !(SPI3->SR & SPI_I2S_FLAG_RXNE) );

    // wait until SPI is not busy anymore

    while( SPI3->SR & SPI_I2S_FLAG_BSY );

    GPIO_SetPinHigh(GPIOD, GPIO_Pin_0);        

    

    // return data from SPI3 register

    return SPI3->DR;

}

In main:

    uint16_t rtnValue = SPI3_Send( H3LIS200DL_WHO_AM_I );  //==0xF

    printf('value = %x\n', rtnValue);    

//I also tried a dummy byte after...still no go

    rtnValue = SPI3_Send( 0x00 );

    printf('value = %x\n', rtnValue);

   

I have tried both 8bit and 16bit, and changing the prescaler. I have confirmed the CS line is going Low/high. I have not done any checks on the data lines, but I have other SPI devices (FRAM) that are on SPI1 and they are working OK. CLK/MISO/MOSI are conected correctly.

Can someone explain why this would be happening? What could be the problem?

Thank you...

12 REPLIES 12
Rogers.Gary
Senior II
Posted on June 12, 2017 at 04:33

Sorry to bother...

Having a decent example would make a difference. I have tried to write and read the device several ways, and still get back 0xFF.

Can someone point to just one example using CMSIS standard libraries that shows how to configure, write and read any ST MEMS accelerometer device? I can't find one here, or anywhere.

Rogers.Gary
Senior II
Posted on June 12, 2017 at 04:59

clive1,

I found your examples in the forum of write and read on SPI:

uint8_t SD_WriteByte(uint16_t Data)

{

  /*!< Wait until the transmit buffer is empty */

  while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET);

   

  /*!< Send the byte */

  SPI_I2S_SendData(SPI3, Data);

   

  /*!< Wait to receive a byte*/

  while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET);

   

  /*!< Return the byte read from the SPI bus */

  return SPI_I2S_ReceiveData(SPI3);

}

uint8_t SD_ReadByte(void)

{

  /*!< Wait until the transmit buffer is empty */

  while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET);

 

  /*!< Send the byte */

  SPI_I2S_SendData(SPI3, DUMMY_BYTE);

 

  /*!< Wait until a data is received */

  while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET);

 

  /*!< Return the byte read from the SPI bus */

  return SPI_I2S_ReceiveData(SPI3);

}

Here is the configuration I am using:

   SPI_I2S_DeInit(SPI3);

    GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_SPI3);

    GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_SPI3);

    GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_SPI3);    

    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

    SPI_Init(SPI3, &SPI_InitStructure);

    SPI_Cmd(SPI3, ENABLE);

When I try to write and read the 'WHO_AM_I', I still get back 0xff.

GPIO_SetPinLow(GPIOD, ACCHI_CS);

SD_WriteByte( LIS200DL_WHO_AM_I );        

uint8_t rtnValue = SD_ReadByte();

GPIO_SetPinHigh(GPIOD, ACCHI_CS);      

printf('value = %x\n', rtnValue);     

rtnValue is always 0xff. I have also tried asserting CS low, then high separately after the write and read and it made no difference.

What gives?

I really would appreciate some help, thanks to anyone who can clue me in.

Rogers.Gary
Senior II
Posted on June 12, 2017 at 05:03

SD_WriteByte( LIS200DL_WHO_AM_I | 0x80 | 0x0 );   

Worked.

So my question is, for what reason is this not written into the send function so it does that automatically for 8 bit words?

Thanks...