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...
2017-06-11 07:33 PM
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.
2017-06-11 07:59 PM
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.
2017-06-11 08:03 PM
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...