0

I am trying to create a separate file/module that has functions that can deal with the LEDs or gyro for the stm32f3discovery. I am trying to pass the stm32f3 API that holds all of the registers into a function to then use inside.

When I run this code, I get an error saying "there is no field '###' on type '##'". How can I do this?

main.rs

#![no_std]
#![no_main]
use stm32f3::stm32f303;

mod my_api;

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

    let gpioe = periph.GPIOE;
    let rcc = periph.RCC;

    my_api::led::setup_led(&gpioe, &rcc);

    loop {
        my_api::led::all_led_on(&gpioe);
    }
}

my_api.rs

pub mod led {
    pub fn setup_led<G, R>(gpio: &G, rcc: &R) {
        *rcc.ahbenr.modify(|_, w| w.iopeen().set_bit()); //enables clock
        *gpio.moder.modify(|_, w| {
            w.moder8().bits(0b01);
            w.moder9().bits(0b01);
            w.moder10().bits(0b01);
            w.moder11().bits(0b01);
            w.moder12().bits(0b01);
            w.moder13().bits(0b01);
            w.moder14().bits(0b01);
            w.moder15().bits(0b01)
        });
    }

    pub fn all_led_on<G>(gpio: &G) {
        *gpio.odr.modify(|_, w| {
            w.odr8().set_bit();
            w.odr9().set_bit();
            w.odr10().set_bit();
            w.odr11().set_bit();
            w.odr12().set_bit();
            w.odr13().set_bit();
            w.odr14().set_bit();
            w.odr15().set_bit()
        });
    }

    pub fn all_led_off<G>(gpio: &G) {
        *gpio.odr.modify(|_, w| {
            w.odr8().clear_bit();
            w.odr9().clear_bit();
            w.odr10().clear_bit();
            w.odr11().clear_bit();
            w.odr12().clear_bit();
            w.odr13().clear_bit();
            w.odr14().clear_bit();
            w.odr15().clear_bit()
        });
    }
}

Error

error[E0609]: no field `odr` on type `&G`
  --> src/my_api.rs:30:15
   |
29 |     pub fn all_led_off <G> (gpio: &G) {
   |                         - type parameter 'G' declared here
30 |         *gpio.odr.modify(|_,w| {
   |               ^^^

It has this error for all of the calls onto any of the registers

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Jack F
  • 21
  • 2
  • Why did you type `pub fn setup_led`? – Shepmaster May 12 '20 at 16:26
  • It looks like your question might be answered by the answers of [Is it possible to access struct fields from within a trait?](https://stackoverflow.com/q/28219730/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster May 12 '20 at 16:27
  • Surely as I am not using anything to do with traits or any sort of OOP and am just trying to pass the api to be used by the new function so that I can run the one bit of code multiple times, then it doesn't have much to do with the other post although correct me if I am wrong as you will definitely have more experience than me – Jack F May 12 '20 at 17:00
  • Why did you type `pub fn setup_led`? – Shepmaster May 12 '20 at 17:04
  • as I didn't know the type that the api would return as I used this to try and get around it? What would you recommend instead? – Jack F May 12 '20 at 17:09
  • You've used generics, which means that `G` can be *any possible type*. That means that `G` could be `i32` or `String` or `HashMap`, etc.. What behavior do you want when the caller of `setup_led` passes in such types? – Shepmaster May 12 '20 at 17:12
  • I realise that at the moment but as I can't find any information about what datatype rcc or gpioe are and it will only be me using this file in the one project i decided to look past this and i know that it is bad rust but I don't know another way around it – Jack F May 12 '20 at 17:40
  • [How do I print the type of a variable in Rust?](https://stackoverflow.com/q/21747136/155423) – Shepmaster May 12 '20 at 17:41
  • Perfect, that is amazing. It all works fine now. You are an absolute lifesaver. Thank You @Shepmaster – Jack F May 12 '20 at 17:56
  • I encourage you to self-answer your question. – Shepmaster May 12 '20 at 17:58

1 Answers1

0

Instead of using a generic to try and force our way into passing in a type that you don't know use something like:

let my_name: () = 39.2;

It will give an error that will tell you what the value on the right is and you can use that to work out what data type you can pass into the function. As shown printing variable type in rust

Jack F
  • 21
  • 2