cancel
Showing results for 
Search instead for 
Did you mean: 

Getting 0xFF and correct value when read received SPI data

arlen
Associate II
Posted on September 21, 2016 at 21:29

Hi, I started to work on SPI, my intention is to read three gyroscope sensor by SPI bus,

Currently I testing SPI preipheral of my STM32 Discovery Board (STM32F407), this board has the sensor LIS302DL , when i read the ''WHo am I'' register I received 0x3F but it should be 0x7B, even more when I read continuously this register it got 0x3F,0x3F, 0x3F and more then i receive 0xFF,0xFF and several times and basicaly i receive groups of 0x3F and groups of 0xFF, other register read correctly the default values but it still appear 0xFFs. I used some code I found in this forum, here below part of the code

#include ''stm32f4xx.h''
#include ''stdint.h''
#include <
stdio.h
>
#define Rst_NSS1 GPIO_ResetBits(GPIOE,GPIO_Pin_3) 
#define Set_NSS1 GPIO_SetBits(GPIOE,GPIO_Pin_3) 
/*More codes*/
static void SystemClock_Config(void)
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
if(RCC_WaitForHSEStartUp()){
RCC_PLLConfig(RCC_PLLSource_HSE,PLL_M,PLL_N,8,PLL_Q);
RCC_PLLCmd(ENABLE);
while(SET != RCC_GetFlagStatus(RCC_FLAG_PLLRDY));
//Delay(900);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB clock = SYSCLK (168MHz)
RCC_PCLK1Config(RCC_HCLK_Div4); //APB1 clock = HCLK/4 
RCC_PCLK2Config(RCC_HCLK_Div16); //APB2 clock = HCLK/16
RCC_GetClocksFreq(&Clocks);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_ADC3, ENABLE); 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);// for USART1 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);// for SPI1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);// for SPI2
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE);// for SPI3
//RCC_MCO1Config(RCC_MCO1Source_HSE,RCC_MCO1Div_1);
//RCC_MCO2Config(RCC_MCO2Source_PLLCLK,RCC_MCO2Div_1);
}
} 
void Init_SPI1(void){
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_Init(SPI1,&SPI_InitStructure);
SPI_TIModeCmd(SPI1,DISABLE);
SPI_Cmd(SPI1,ENABLE);
SPI_CalculateCRC(SPI1, DISABLE);
void Init_GPIO(void){
/* SPI1 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; //(SCK|MISO|MOSI)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //(NSS : customized)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOE, &GPIO_InitStructure);
} 
uint32_t Registro,i;
uint16_t tempo;
uint16_t ReadSPI = 0x7F;
uint16_t WriteSPI = 0x7F;
uint16_t Addr = 0x80;
#define RdAddrPlus(MemAdd) ((0x80 | MemAdd) | 0x40)
#define RdAddr(MemAdd) ((0x80 | MemAdd) & 0xBF) 
#define WrAddrPlus(MemAdd) ((0x7F & MemAdd) | 0x40)
#define WrAddr(MemAdd) (0x7F & MemAdd & 0xBF)
uint16_t SPI_SendByte(uint16_t DataSpi)
{
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == 0){} //wait for transmit buffer to not be empty (ie data loaded in)
//USART_puts(USART1,''SPI bus Free\n\r'');
SPI_I2S_SendData(SPI1,DataSpi); 
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == 0){} //wait for transmit buffer to not be empty (ie data loaded in)
return(SPI_I2S_ReceiveData(SPI1)); // Clear out any pending RX data
} 
int main()
{
SystemCoreClockUpdate();
SystemClock_Config();
if (SysTick_Config(SystemCoreClock / 168000)) { /* SysTick 1 msec interrupts */
while (1); /* Capture error */
}
Init_GPIO();
Init_USART1();
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // enable the USART1 receive interrupt 
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
NVIC_Init(&NVIC_InitStructure); 
USART_Cmd(USART1, ENABLE); // enable USART1
USART_puts(USART1,''INICIO:D \n \r'');
NVIC_Configuration();
Init_SPI1();
/* SPI */
Rst_NSS1;
//Set_NSS1;
Delay(10); 
//SPI_SendByte(RdAddr(0x0F));
while(1){
SPI_SendByte(RdAddr(0x20));
tempo = SPI_SendByte(RdAddr(0x00));
sprintf(texto,''SPI1 DR: %x \n\r'',tempo);
USART_puts(USART1,texto);
}
return 0;
}

I hope someone can help me with this thanks in advance #device #stm32f4 #stm32f4 #discovery #discovery #spi #spi #device
5 REPLIES 5
arlen
Associate II
Posted on September 22, 2016 at 23:29

Hi

thanks for you help,

I´ve checked the PCB discovery version, and I've just realized that it was the version 2013 which use the sensor LIS3DSH , no the LIS302,

Now the register are read correctly, it is according to the datasheet however I still got 0xFF.

someone had this trouble?

I attach a picture showing the data in UART

Thanks in advance

0690X00000605RzQAI.png

________________

Attachments :

SPI_test.png : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I1AZ&d=%2Fa%2F0X0000000bjw%2Fm_vr0bNO1xDrNLX9Ir7Q3ZZqocyXUZu7S3SO2WaAkGo&asPdf=false
michaelc.barton9
Associate II
Posted on September 23, 2016 at 17:33

NSS pin uses GPIOE, but there's no:

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);

HTH

arlen
Associate II
Posted on September 23, 2016 at 22:35

hi barton

Thanks for your help, Yes , i missed it, i've added it and it works, Now i can read the registers correctly, however i have noticed that the when i read the same register several times the first value is always 0xFF and the next values are read correctly , it is 0x21 (this is rigth value) Why does it happen?, i know that while SPI peripheral is sending the data,at the same time the SPI DR register is filled , the code below is the part how i read the same register several times:

Ind=5;
/* SPI */
while(Ind){
Rst_NSS1; 
Delay(10); 
SPI_SendByte(RdAddr(0x0D)); //this function return the SPI DR register to clear out any pending RX data
tempo = SPI_SendByte(RdAddr(0x00));
Set_NSS1; 
sprintf(texto,''SPI1 DR: %x 

'',tempo);
USART_puts(USART1,texto);
Ind--;//while(1){
} 

and I got : 0xFF 0x21 0x21 ... I tried to do a multireading using this code but it doesn't work, It gives only 0xFF:

Ind=5;
/* SPI */
Rst_NSS1; 
Delay(10);
SPI_SendByte(RdAddr(0x0D)); //this function return the SPI DR register to clear out any pending RX data
while(Ind){ 
tempo = SPI_SendByte(RdAddr(0x00)); 
sprintf(texto,''SPI1 DR: %x 

'',tempo);
USART_puts(USART1,texto);
Ind--;
} 
Set_NSS1;

I not sure about that , but the multireading just works when it wannaa read several times increasing the address? or it can also be used reading the same register? arlen
michaelc.barton9
Associate II
Posted on September 24, 2016 at 09:22

arlen

already suggested, I think you need to look at the ST examples for this board which work fine

they are available here:

http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-libraries-expansions/stsw-stm32068.html