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
netstv
Associate II
Posted on June 12, 2017 at 01:05

Can you hook up a scope to see what the lines tell you?  Everytime I do a board bringup, I always have the hardware guys give me one board with wires or create testpoints so I can connect a scope and see the lines.

I don't see anything wrong with what you have setup... However, I don't know what SPI3_Send does.

So things that I would check:

1.  Does your chip select line go from high to low at the start.

2.  Is your polarity and clock phase setup properly.  (I.E. SPI Mode)

3.  Do you see your clock line move

4.  Do you see the data lines move.

Also, are there other devices on this SPI bus?

Rogers.Gary
Senior II
Posted on June 12, 2017 at 01:14

Hi

1 - Yes, I confirmed that CS goes low

2 - The polarity and clock phase are taken from an example using LIS302DL. I am assuming (And I would hope it's correct)  that all of ST's accelerometers would have these parameters the same.

3 - Have not checked, but again - I have a device on SPI1 that functions with no issues.

4 - No other devices on SPI3.

BTW - the SPI3_Send function code is provided.

Thanks

Rogers.Gary
Senior II
Posted on June 12, 2017 at 01:35

Hi again,

I have checked the CS line, it is transitioning HIGH->LOW->HIGH. In this transition (or at all) , SCK, MOSI and MISO are NOT toggling. What could be wrong with the configuration?

Thanks....

Rogers.Gary
Senior II
Posted on June 12, 2017 at 01:45

I have discovered that Pin2 and Pin 3, both marked as NC in the data sheet, are grounded. Is this potentially the problem?

netstv
Associate II
Posted on June 12, 2017 at 01:47

Don't  you have to configure the alternate function for those pins?

Something like:

GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
Rogers.Gary
Senior II
Posted on June 12, 2017 at 01:51

Done already, please check the code I have posted:

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

Rogers.Gary
Senior II
Posted on June 12, 2017 at 02:55

thanks. Changed to this, and still no clock:

   SPI_I2S_DeInit(SPI3);

    GPIO_PinAFConfig(GPIOC, GPIO_Pin_10, GPIO_AF_SPI3);

    GPIO_PinAFConfig(GPIOC, GPIO_Pin_11, GPIO_AF_SPI3);

    GPIO_PinAFConfig(GPIOC, 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);

also, thanks steve for pointing that out, it wasn't clear that was the problem.

clive1, could it be that pins 2 and 3 are grounded? the data sheet is not explicit that it is not permitted (or a problem) it was done by mistake.

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

ok, I see what I did wrong. Should be 'GPIO_PinSourcex' just like that, according to gpio_c header file. It's now returning 0xFF, or 0xffff (if I set 8 or 16 bit)

I am now getting a clock signal as well!

Is there still a setting problem?

thanks!

Posted on June 12, 2017 at 02:29

Your code isn't valid. PinAFConfig takes singular PinSource arguments (an index), not OR'd together Pin arguments (a mask). See form provided by Steve above.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..