L3gd20 gyroscope sending back repeated bytes on stm32f3discovery

I am working on the stm32f3discovery and am trying to read data from the l3gd20 gyro on the board. When I try to read 6 bytes continuously from OUT_X_L to OUT_Z_H (which is all the data that is used to read readings from the gyroscope) the first three bytes sent are the same as the last three sent.

And when I try to read each register individually all the bytes are the same, I have checked on an oscilloscope and the registers are changing on the MOSI line but the response is 6 repeated bytes.

Both the WHO_AM_I and the OUT_TEMP registers work perfectly fine so I know that the actual SPI isn't the issue.

Here is any appropriate code, any help or point in the right direction will be much appreciated, thanks.

Main.rs

#![no_std]
#![no_main]

extern crate panic_itm; // logs messages over ITM; requires ITM support

use cortex_m::{asm, iprintln, iprint, Peripherals as core_peripherals};
use cortex_m_rt::entry;
use cortex_m_semihosting::{debug, hprintln};
use stm32f3::stm32f303;

mod my_api;
mod sensor;


#[entry]
fn main() -> ! {
    let periph = stm32f303::Peripherals::take().unwrap();
    let mut core_p = core_peripherals::take().unwrap();

    let itm = &mut core_p.ITM.stim[0];
    

    let gpioa = periph.GPIOA;
    let gpioe = periph.GPIOE;
    let rcc = periph.RCC
    let flash = periph.FLASH;
    let spi1 = periph.SPI1;

    set_to_72MHz(&rcc, &flash);

    let spi = my_api::spi_mod::spi_func::new(&rcc, &gpioa, &gpioe, &spi1);

    let mut gyro = sensor::Gyro::gyro::new(&spi, &spi1).init(&spi, &spi1, &gpioe);

    loop {

        iprintln!(itm, "{:?}", gyro.read_data(&spi, &spi1, &gpioe));
    }
}

fn set_to_72MHz(rcc: &stm32f3::stm32f303::RCC, flash: &stm32f3::stm32f303::FLASH){
    rcc.cr.modify(|_,w| w.hseon().set_bit()); //turns on the external oscillator
    while rcc.cr.read().hserdy().bit_is_clear(){} //wait for it to be ready
    flash.acr.modify(|_,w| {
        w.prftbe().set_bit(); //turn on prefetch
        unsafe{w.latency().bits(0b010)} //set latency for 72MHz
    }); 

    rcc.cfgr.modify(|_,w| {
        w.pllxtpre().clear_bit();
        unsafe{w.pllsrc().bits(0b10)};
        w.pllmul().bits(0b0111);
        unsafe{w.hpre().bits(0b0000);
        w.ppre1().bits(0b100);
        w.ppre2().bits(0b000)}
    });

    rcc.cr.modify(|_,w| w.pllon().set_bit());
    while rcc.cr.read().pllrdy().bit_is_clear(){}

    rcc.cfgr.modify(|_,w| unsafe{w.sw().bits(0b10)});
    while rcc.cfgr.read().sws().bits() != 0b10{}
}

my_api.rs

    pub mod spi_mod{
    pub struct spi_func{}

    impl spi_func{
        pub fn new(rcc: &stm32f3::stm32f303::RCC, gpioa: &stm32f3::stm32f303::GPIOA, gpioe: &stm32f3::stm32f303::GPIOE, spi: &stm32f3::stm32f303::SPI1) -> Self {
            rcc.apb2enr.modify(|_,w| w.spi1en().set_bit()); //enable spi clock

            rcc.ahbenr.modify(|_,w| w.iopaen().set_bit()); // enable gpio clocks
            rcc.ahbenr.modify(|_,w| w.iopeen().set_bit());

            gpioe.moder.modify(|_,w| w.moder3().bits(0b01)); //CS pin
            gpioe.otyper.modify(|_,w| w.ot3().clear_bit());
            gpioe.odr.modify(|_,w| w.odr3().set_bit()); //bring pe3 high to disable gyro com

            // PA5 -> SCL  // PA6 -> MISO  // PA7 -> MOSI
            gpioa.moder.modify(|_,w| {
                w.moder5().bits(0b10); // output type
                w.moder6().bits(0b10);
                w.moder7().bits(0b10)});

            gpioa.otyper.modify(|_,w| {
                w.ot5().clear_bit();// push pull type
                w.ot6().clear_bit();
                w.ot7().clear_bit()});

            gpioa.ospeedr.modify(|_,w| {
                w.ospeedr5().bits(0b11);// fast mode
                w.ospeedr6().bits(0b11);
                w.ospeedr7().bits(0b11)});

            gpioa.afrl.modify(|_,w| {
                w.afrl5().bits(0b0101);//Alternate function 5
                w.afrl6().bits(0b0101);
                w.afrl7().bits(0b0101)
            });

            spi.cr1.modify(|_,w| {
                w.bidimode().clear_bit(); //bidirectional mode
                w.ssm().set_bit(); // hardware slave management disabled
                w.ssi().set_bit(); // slave not selected    -------------------------------
                w.br().bits(0b011); // bring rate from 72MHz to 72/16MHz = 4.5MHz as gyro cant go above 10MHz
                w.mstr().set_bit(); // set to master mode
                w.cpol().set_bit(); // set to mode 3 to work for the l3gd20
                w.cpha().set_bit()
            });

            spi.cr2.modify(|_,w| {
                //unsafe{w.ds().bits(0b0111)}; // data size = 8 bits
                w.errie().clear_bit();
                w.txeie().set_bit(); //enable interupt flags   
                w.rxneie().set_bit();
                w.ssoe().clear_bit() //set to single master mode
            });

            spi.cr1.modify(|_,w| w.spe().set_bit()); // enable spi

            spi_func{}
            
        }

        fn check_faults(&self, spi1: &stm32f3::stm32f303::SPI1) -> bool {
            if spi1.sr.read().ovr().bit_is_set(){ //checks through all the flags
                false
            }else if spi1.sr.read().modf().bit_is_set(){
                false
            }else if spi1.sr.read().crcerr().bit_is_set(){
                false
            }else if spi1.sr.read().udr().bit_is_set(){
                false
            } else {
                true
            }
        }

        pub fn write(&self, spi1: &stm32f3::stm32f303::SPI1, data: u16) {
            if self.check_faults(&spi1){
                spi1.dr.modify(|_,w| w.dr().bits(data)); //write to the dr register
                while spi1.sr.read().bsy().bit_is_set(){}
            }
        }

        pub fn read(&self, spi1: &stm32f3::stm32f303::SPI1) -> u8 {
            if self.check_faults(&spi1){
                while spi1.sr.read().bsy().bit_is_set(){}
                return (spi1.dr.read().dr().bits() >> 8) as u8 //read from the dr register
            }
            0
            
        }

        pub fn write_data(&self, spi1: &stm32f3::stm32f303::SPI1, reg_address: u8, data: u8) {
            let total_data: u16 = ((data as u16) << 8) + (reg_address as u16);
            self.write(&spi1, total_data);
        }

        pub fn read_register(&self, spi1: &stm32f3::stm32f303::SPI1, reg_address: u8) -> u8{
            self.write(&spi1, (reg_address | 0x80) as u16); //set the bit to read mode and send
            self.read(&spi1) //read the result
        }

        pub fn read_multiple_register(&self, spi1: &stm32f3::stm32f303::SPI1, reg_address: u8, rx_data: &mut [u8]){
            self.write(&spi1, (reg_address | 0x80 | 0x40) as u16);
            for d in rx_data.iter_mut(){
                self.write(&spi1, 0x00);
                *d = self.read(&spi1);
            }

        }
    
    }
}

senor.rs

    pub mod Gyro{
    pub use crate::my_api::spi_mod;
    const WHO_AM_I: u8 = 0x0F;
    const CTRL_REG1: u8 = 0x20;
    const CTRL_REG4: u8 = 0x23;
    const OUT_TEMP: u8 = 0x26;
    const OUT_X_L: u8 = 0x28;
    const OUT_X_H: u8 = 0x29;
    const OUT_Y_L: u8 = 0x2A;
    const OUT_Y_H: u8 = 0x2B;
    const OUT_Z_L: u8 = 0x2C;
    const OUT_Z_H: u8 = 0x2D;

    pub struct gyro{
        pub x: i16,
        pub y: i16,
        pub z: i16,
        offset_x: i32,
        offset_y: i32,
        offset_z: i32,
        pub temp: i8
    }

    impl gyro{
        pub fn new(my_spi_mod: &spi_mod::spi_func, spi1: &stm32f3::stm32f303::SPI1) -> Self {
            gyro{
                x: 0,
                y: 0,
                z: 0,
                offset_x: 0,
                offset_y: 0,
                offset_z: 0,
                temp: 0,
            }
        }

        pub fn init(self, spi: &spi_mod::spi_func, spi1: &stm32f3::stm32f303::SPI1, gpioe: &stm32f3::stm32f303::GPIOE) -> Self{
            self.cs_low(&gpioe);
            spi.write_data(&spi1, CTRL_REG1, 0x3F); //power on the gyro 
            self.cs_high(&gpioe);
            
            self.cs_low(&gpioe);
            spi.write_data(&spi1, CTRL_REG4, 0x10); //power on the gyro 
            self.cs_high(&gpioe);
            
            self
        }

        pub fn who_am_i(&self, spi: &spi_mod::spi_func, spi1: &stm32f3::stm32f303::SPI1, gpioe: &stm32f3::stm32f303::GPIOE) -> u8 {
            self.cs_low(&gpioe);
            let data = spi.read_register(&spi1, WHO_AM_I);
            self.cs_high(&gpioe);
            data
        }

        pub fn read_temp(&mut self, spi: &spi_mod::spi_func, spi1: &stm32f3::stm32f303::SPI1, gpioe: &stm32f3::stm32f303::GPIOE) {
            self.cs_low(&gpioe);
            self.temp = spi.read_register(&spi1, OUT_TEMP) as i8;
            self.cs_high(&gpioe);

        }


        pub fn read_data(&mut self, spi: &spi_mod::spi_func, spi1: &stm32f3::stm32f303::SPI1, gpioe: &stm32f3::stm32f303::GPIOE) -> [u8;6]{
            let mut data: [u8;6] = [0,0,0,0,0,0];
            
            self.cs_low(&gpioe);
            spi.read_multiple_register(&spi1, OUT_X_L, &mut data);

            // data[0] = spi.read_register(&spi1, OUT_X_L);
            // data[1] = spi.read_register(&spi1, OUT_X_H);

            // data[2] = spi.read_register(&spi1, OUT_Y_L);
            // data[3] = spi.read_register(&spi1, OUT_Y_H);

            // data[4] = spi.read_register(&spi1, OUT_Z_L);
            // data[5] = spi.read_register(&spi1, OUT_Z_H);

            self.cs_high(&gpioe);

            self.x = ((data[0] as u16) + ((data[1] as u16) << 8)) as i16;
            self.y = ((data[2] as u16) + ((data[3] as u16) << 8)) as i16;
            self.z = ((data[4] as u16) + ((data[5] as u16) << 8)) as i16;

            data            
            
        }

        fn cs_low(&self, gpioe: &stm32f3::stm32f303::GPIOE){
            gpioe.odr.modify(|_,w| w.odr3().clear_bit());
        }

        fn cs_high(&self, gpioe: &stm32f3::stm32f303::GPIOE){
            gpioe.odr.modify(|_,w| w.odr3().set_bit());
        }

    }
}

This is the result when using
sensor.rs -> read_data() -> spi.read_multiple_register(&spi1, OUT_X_L, &mut data);
Screenshot from 2020-06-12 17-22-20

And then this is what I get when when I use the commented out bit instead
Screenshot from 2020-06-12 17-24-53

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.