H3LIS200DL SPI Configuration & Read
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-06-11 03:54 PM
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...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-06-11 04:05 PM
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-06-11 04:14 PM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-06-11 04:35 PM
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....
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-06-11 04:45 PM
I have discovered that Pin2 and Pin 3, both marked as NC in the data sheet, are grounded. Is this potentially the problem?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-06-11 04:47 PM
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);- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-06-11 04:51 PM
Done already, please check the code I have posted:
GPIO_PinAFConfig (GPIOC, GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12, GPIO_AF_SPI3);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-06-11 05:55 PM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-06-11 06:04 PM
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-06-11 07:29 PM
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.
Up vote any posts that you find helpful, it shows what's working..