简体   繁体   中英

rust struct: struct with generics as variable

I have this, using rp2040_hal:

use defmt_rtt as _;
use embedded_hal::timer::CountDown;
use rp2040_hal::pio::StateMachineIndex;
use rp2040_hal::prelude::_rphal_pio_PIOExt;
use rp2040_hal::{gpio::PinId, timer::Timer, Clock};
use rp_pico::hal::clocks::ClocksManager;
use rp_pico::hal::pac::Peripherals;
use smart_leds::RGB8;
use ws2812_pio::{self, Ws2812};

pub struct LedControl<C, I, SM>
where
    C: CountDown,
    I: PinId + rp2040_hal::gpio::bank0::BankPinId,
    SM: StateMachineIndex,
{
    leds: [RGB8; 100],
    num_of_leds: usize,
    ws: Ws2812<rp2040_hal::pac::PIO0, SM, C, I>,
}
impl<C, I, SM> LedControl<C, I, SM>
where
    C: CountDown,
    I: PinId + rp2040_hal::gpio::bank0::BankPinId,
    SM: StateMachineIndex,
{
    pub fn new(pins: rp2040_hal::gpio::Pins, clk: &ClocksManager, timer: &Timer, num: usize) {
        let mut pc = Peripherals::take().unwrap();
        let (mut pio, sm0, _, _, _) = pc.PIO0.split(&mut pc.RESETS);
        let strip = Ws2812::new(
            pins.gpio4.into_mode(),
            &mut pio,
            sm0,
            clk.peripheral_clock.freq(),
            timer.count_down(),
        );
        LedControl {
            num_of_leds: num,
            ws: strip,
            leds: [(0, 0, 0).into(); 100],
        };
    }

    pub fn modifyPixel(&mut self, rgb: &(u8, u8, u8), idx: &usize) {
        self.leds[idx.clone()] = (*rgb).into()
    }

    pub fn pixels(&mut self) -> [RGB8; 100] {
        return self.leds.clone();
    }

    pub fn test_ws(&mut self) {
        self.ws.write(self.leds.iter().copied()).unwarp();
    }
}

with cargo.toml:

[package]
edition = "2021"
name = "rp2040-project-WS3823"
version = "0.1.0"

[dependencies]
cortex-m = "0.7"
cortex-m-rt = "0.7"
embedded-hal = { version = "0.2.5", features = ["unproven"] }

defmt = "0.3"
defmt-rtt = "0.4.0"
panic-probe = { version = "0.3", features = ["print-defmt"] }

# We're using a Pico by default on this template
rp-pico = "0.6.0"

# but you can use any BSP. Uncomment this to use the pro_micro_rp2040 BSP instead
# sparkfun-pro-micro-rp2040 = "0.3"

# If you're not going to use a Board Support Package you'll need these:
rp2040-hal = { version = "0.7.0", features = ["rt"] }
# rp2040-boot2 = "0.2"
smart-leds = "0.3.0"
ws2812-pio = "0.5.0"
fugit = "0.3.6"

# cargo build/run
[profile.dev]
codegen-units = 1
debug = 2
debug-assertions = true
incremental = false
opt-level = 3
overflow-checks = true

# cargo build/run --release
[profile.release]
codegen-units = 1
debug = 2
debug-assertions = false
incremental = false
lto = 'fat'
opt-level = 3
overflow-checks = false

# do not optimize proc-macro crates = faster builds from scratch
[profile.dev.build-override]
codegen-units = 8
debug = false
debug-assertions = false
opt-level = 0
overflow-checks = false

[profile.release.build-override]
codegen-units = 8
debug = false
debug-assertions = false
opt-level = 0
overflow-checks = false

# cargo test
[profile.test]
codegen-units = 1
debug = 2
debug-assertions = true
incremental = false
opt-level = 3
overflow-checks = true

# cargo test --release
[profile.bench]
codegen-units = 1
debug = 2
debug-assertions = false
incremental = false
lto = 'fat'
opt-level = 3

the error is:

self.ws.write(self.leds.iter().copied()).unwarp();
   |    ^^^^^ method not found in `Ws2812<rp2040_hal::rp2040_pac::PIO0, SM, C, I>`

which make since because this is a generic reference, not an implementation, but how do I tell the compiler that I am using the implementation? ('strip' in the c-tor)

I am using the template for the pico pi: https://github.com/rp-rs/rp2040-project-template.git

There are two problems in your code:

  • SmartLedsWrite , which provides write() , is not in scope
  • SmartLedsWrite requires your timer to be specifically of type rp2040_hal::timer::CountDown , not of impl embedded_hal::timer::CountDown , as can be seen here .

The write() function is part of the SmartLedsWrite trait.

To use a trait in Rust, it has to be in scope.

You can bring it in scope by modifying the following line in your code:

use smart_leds::RGB8;

to:

use smart_leds::{SmartLedsWrite, RGB8};

Fixing the CountDown requires introducing a lifetime on your LedControl object and replacing the generic with an actual type.

This code compiles (not sure if it works, don't have the required hardware in front of me):

use defmt_rtt as _;
use rp2040_hal::pio::StateMachineIndex;
use rp2040_hal::prelude::_rphal_pio_PIOExt;
use rp2040_hal::timer::CountDown;
use rp2040_hal::{gpio::PinId, timer::Timer, Clock};
use rp_pico::hal::clocks::ClocksManager;
use rp_pico::hal::pac::Peripherals;
use smart_leds::{SmartLedsWrite, RGB8};
use ws2812_pio::{self, Ws2812};

pub struct LedControl<'t, I, SM>
where
    I: PinId + rp2040_hal::gpio::bank0::BankPinId,
    SM: StateMachineIndex,
{
    leds: [RGB8; 100],
    num_of_leds: usize,
    ws: Ws2812<rp2040_hal::pac::PIO0, SM, CountDown<'t>, I>,
}
impl<'t, I, SM> LedControl<'t, I, SM>
where
    I: PinId + rp2040_hal::gpio::bank0::BankPinId,
    SM: StateMachineIndex,
{
    pub fn new(pins: rp2040_hal::gpio::Pins, clk: &ClocksManager, timer: &Timer, num: usize) {
        let mut pc = Peripherals::take().unwrap();
        let (mut pio, sm0, _, _, _) = pc.PIO0.split(&mut pc.RESETS);
        let strip = Ws2812::new(
            pins.gpio4.into_mode(),
            &mut pio,
            sm0,
            clk.peripheral_clock.freq(),
            timer.count_down(),
        );
        LedControl {
            num_of_leds: num,
            ws: strip,
            leds: [(0, 0, 0).into(); 100],
        };
    }

    pub fn modifyPixel(&mut self, rgb: &(u8, u8, u8), idx: &usize) {
        self.leds[idx.clone()] = (*rgb).into()
    }

    pub fn pixels(&mut self) -> [RGB8; 100] {
        return self.leds.clone();
    }

    pub fn test_ws(&mut self) {
        self.ws.write(self.leds.iter().copied()).unwrap();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM