cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f3discovery - l3gd20 gyroscope send constant values

leszek
Associate II
Posted on September 08, 2015 at 12:16

Hello,

I have problem with l3gd20 gyroscope, which is part of stm32f3disco. I try to communicate with it using built in stm32f3 uC. I wrote my library for using SPI and this gyroscope. Theoretically SPI is working correctly, because I receive proper value of WHO_AM_I register, but when I try to read measurement registers (OUT_X_L etc.), the values of register dont change - they are constant even when I'm moving the board. They can only change when I turn off and turn on the power, but then I am reading new constant values. I was trying to run my application on three different stm32f3 disco - the results were the same. I'm doing simple configuration of l3gd20 - I write CTRL_REG1_PD | CTRL_REG1_XEN | CTRL_REG1_YEN | CTRL_REG1_ZEN to CTRL_REG1. I really don't know where is the problem - do I configure it wrong? Or is my configuration of SPI partially wrong? Below is source code of my SPI configuration. I would be grateful for your help.


void
l3gd20_conf() {

/* włącz zegary */

RCC->AHBENR |= RCC_AHBENR_GPIOAEN;

RCC->AHBENR |= RCC_AHBENR_GPIOEEN;

RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;



/* ustaw alternatywne funkcje dla GPIO - SCK, MISO, MOSI */

GPIOA->MODER |= GPIO_MODER_MODER5_1 | GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1;

GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR5 | GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7;

GPIOA->AFR[0] |= GPIO_AFRL_AF5_5 | GPIO_AFRL_AF5_6 | GPIO_AFRL_AF5_7;


/* ustaw PE3 jako CS - GPIO output */

GPIOE->MODER |= GPIO_MODER_MODER3_0;

GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR3;

GPIOE->ODR |= GPIO_ODR_3;


/* ustaw SPI MASTER 2,25 MHz; ramka 8 bitow */

SPI1->CR1 |= SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_MSTR |SPI_CR1_BR_1 | SPI_CR1_BR_0;

SPI1->CR2 |= SPI_CR2_FRXTH;

/* wlacz SPI */

SPI1->CR1 |= SPI_CR1_SPE;

}


void
l3gd20_send_byte(uint8_t data) {

volatile
uint8_t * 
const
ptr = (
volatile
uint8_t *)&SPI1->DR; 

while
(!(SPI1->SR & SPI_SR_TXE)); 

*ptr = data; 

}

/*

uint8_t l3gd20_transfer_byte(uint8_t mode, uint8_t addr, uint8_t data) {

uint8_t buf;


CS_LOW();

if (mode == 1) {

addr |= 0x80;

l3gd20_send_byte(addr);

l3gd20_send_byte(DUMMY_BYTE);

while (!(SPI1->SR & SPI_SR_RXNE));

buf = (uint8_t)SPI1->DR;

return buf;

} else {

l3gd20_send_byte(addr);

l3gd20_send_byte(data);

return 0;

}

CS_HIGH();

}*/

uint8_t l3gd20_transfer_byte(uint8_t val) {


/*while (!(SPI1->SR & SPI_SR_TXE));

SPI1->DR = val;

while (!(SPI1->SR & SPI_SR_RXNE));

return (uint8_t)SPI1->DR;*/

volatile
uint8_t * 
const
ptr = (
volatile
uint8_t *)&SPI1->DR; 

while
(!(SPI1->SR & SPI_SR_TXE)); 

*ptr = val; 

while
(!(SPI1->SR & SPI_SR_RXNE)); 

return
*ptr;

}


void
l3gd20_write_byte(uint8_t addr, uint8_t val) {

uint8_t d;

CS_LOW();

d = l3gd20_transfer_byte(addr);

d = l3gd20_transfer_byte(val);

CS_HIGH();

}


uint8_t l3gd20_read_byte(uint8_t addr) {

volatile
uint8_t val;

addr |= R_BIT;

CS_LOW();

val = l3gd20_transfer_byte(addr);

val = l3gd20_transfer_byte(DUMMY_BYTE);

CS_HIGH();

return
val;

}

#spi #stm32f3 #l3gd20 #drdy #stm32
3 REPLIES 3
adam239955
Associate II
Posted on September 08, 2015 at 12:36

With an oscilloscope you can check the GPIO PE1 that Data Ready changes. You will have to configure CTRL_REG3 to enable the interrupt. If it is constant, the values in your gyroscope are never read.

Hope this is some help.
leszek
Associate II
Posted on September 08, 2015 at 13:16

Unfortunatelly i haven't got an oscilloscope. But I assume that you think that I should wait fixed part of time, before I read first values. I am doing big loops beetween start configuration of SPI and sending of configuration to l3gd After configuration I also make big loop, so I think that before I read first bytes everythinh should stable and data should be ready.

It takes few minutes beetween start-up and read first byte.. And next reading are with time interval about ~3 seconds, so imo this must be sufficient interval. Initial configuration code:

for
(it = 0; it < 100000000; it++);
for
(it = 0; it < 100000000; it++);
for
(it = 0; it < 100000000; it++);
l3gd20_conf();
for
(it = 0; it < 100000000; it++);
for
(it = 0; it < 100000000; it++);
for
(it = 0; it < 100000000; it++); 
for
(it = 0; it < 100000000; it++);
l3gd20_write_byte(CTRL_REG1, CTRL_REG1_PD | CTRL_REG1_XEN | CTRL_REG1_YEN | CTRL_REG1_ZEN);
for
(it = 0; it < 100000000; it++);
for
(it = 0; it < 100000000; it++); 
for
(it = 0; it < 100000000; it++);
for
(it = 0; it < 100000000; it++);

leszek
Associate II
Posted on September 08, 2015 at 16:19

I also found out that when I'm checking status register new vaules are only available at first time, so that's why I'm reading constant data, but I dont understand why this is situation occurs, because the device is configured to continuos data updating