Giter VIP home page Giter VIP logo

esp-idf-hal's People

Contributors

andresv avatar codyps avatar dacut avatar dominaezzz avatar elotom avatar ivmarkov avatar jessebraham avatar jordanhalase avatar kelnos avatar kronsyc avatar liebman avatar lonesometraveler avatar lynaghk avatar mabezdev avatar mbuesch avatar mr-sven avatar n3xed avatar oyvindnetland avatar phosfor avatar pyaillet avatar ricardicus avatar sapir avatar sergiogasquez avatar sirhcel avatar svenstaro avatar torkleyy avatar usbalbin avatar vollbrecht avatar xymist avatar zredshift avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

esp-idf-hal's Issues

ADC Support

I see that there are some documentation around ADC functionality, but it doesn't seem possible to take a reading. There are a few issues that I see:

  • The GpioXX pin structs have no method to convert them to the Analog typestate
  • The Channel and OneShot traits imply that ADC1 and ADC2 newtypes should exist, but they do not
  • The above traits are not implemented for any types

ADC uses the wrong channel with `embedded_hal > 0.2`

At least I'm pretty sure that's the problem. It seems like the implementation of OneShot::read for embedded_hal == 0.2.7 chooses channel 6 for Gpio14, but chooses channel 2 with embedded_hal == 1.0.0-alpha.7.

Here's an example repository that shows the difference.

The output from the example:

Channel 0.2.7: 6
Value   0.2.7: 2179
Channel 1.0.0: 2
Value   1.0.0: 128

Cannot send on a channel in an interrupt.

Hello,
I'm not exactly sure if this is the right place to ask my question. I'll put it here because my problem is related to the esp_idf_hal::interrupt::free function this crate provides.

I've set up an interrupt for a gpio pin using the bindings that esp_idf_sys provides and the interrupt closure gets called successfully when I change the signal on the gpio.
Now I try to send something using the std::sync::mpsc::channel in this interrupt. Even if I disable all interrupts using the esp_idf_hal::interrupt::free function, my program always crashed when I send. I noticed this is only happening when in another task I am waiting on this very channel on the receiver side. When nobody is currently listening, it actually works fine.

Maybe I'm missing something, but using a channel in an interrupt should be fine, shouldn't it? My current alternative uses the esp_idf_hal::interrupt::Mutex to modify a variable, but the obvious downside is that I need to poll the mutex in the main thread.

This is the crash log:

abort() was called at PC 0x40084c23 [lock_acquire_generic:/home/user/Schreibtisch/Rust/ESP-Feed/.embuild/espressif/esp-idf-v4.3.1/components/newlib/locks.c:139] on core 0
Backtrace:0x400894d3 [panic_abort:/home/user/Schreibtisch/Rust/ESP-Feed/.embuild/espressif/esp-idf-v4.3.1/components/esp_system/panic.c:368]:0x3ffb0bf0 0x40089cd1 [esp_system_abort:/home/user/Schreibtisch/Rust/ESP-Feed/.embuild/espressif/esp-idf-v4.3.1/components/esp_system/system_api.c:112]:0x3ffb0c10 0x4009127a [abort:/home/user/Schreibtisch/Rust/ESP-Feed/.embuild/espressif/esp-idf-v4.3.1/components/newlib/abort.c:46]:0x3ffb0c30 0x40084c23 [lock_acquire_generic:/home/user/Schreibtisch/Rust/ESP-Feed/.embuild/espressif/esp-idf-v4.3.1/components/newlib/locks.c:139]:0x3ffb0ca0 0x40084d71 [_lock_acquire_recursive:/home/user/Schreibtisch/Rust/ESP-Feed/.embuild/espressif/esp-idf-v4.3.1/components/newlib/locks.c:167]:0x3ffb0cd0 0x4012dfa7 [pthread_cond_signal:/home/user/Schreibtisch/Rust/ESP-Feed/.embuild/espressif/esp-idf-v4.3.1/components/pthread/pthread_cond_var.c:55]:0x3ffb0cf0 0x4011a6a4 [_ZN3std3sys4unix7condvar7Condvar10notify_one17h4c4fb0ef25fe1e03E:/home/user/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/sys/unix/condvar.rs:70]:0x3ffb0d10 0x40113cb8 [_ZN3std10sys_common13thread_parker7generic6Parker6unpark17h1783f54b39e28f06E:/home/user/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/sys_common/thread_parker/generic.rs:117]:0x3ffb0d50 0x4011535c [_ZN3std6thread6Thread6unpark17h6af55d99665fd82cE:/home/user/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/thread/mod.rs:1116]:0x3ffb0d80 0x400d75c7 [_ZN3std4sync4mpsc6stream15Packet$LT$T$GT$4send17h7c0b4091c113a398E:/home/user/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/sync/mpsc/stream.rs:95]:0x3ffb0da0 0x400d7ed1 [_ZN3std4sync4mpsc15Sender$LT$T$GT$4send17h98e90565710c13efE:/home/user/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/sync/mpsc/mod.rs:??]:0x3ffb0dd0 0x400da477 [_ZN8esp_feed4main28_$u7b$$u7b$closure$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$17hc441ce8b66ed53abE:/home/user/Schreibtisch/Rust/ESP-Feed/src/main.rs:71]:0x3ffb0e70 0x401b8f11 [_ZN89_$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnMut$LT$Args$GT$$GT$8call_mut17h715053f4ad2bc0bcE:/home/user/.rustup/toolchains/esp/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1698]:0x3ffb0ea0 0x400da3c8 [_ZN8esp_feed4main15add_isr_handler11isr_handler17heb3675279633c471E:/home/user/Schreibtisch/Rust/ESP-Feed/src/main.rs:86]:0x3ffb0ec0 0x40083471 [gpio_isr_loop:/home/user/Schreibtisch/Rust/ESP-Feed/.embuild/espressif/esp-idf-v4.3.1/components/driver/gpio.c:427]:0x3ffb0ee0 0x40084a2d [_xt_lowint1:/home/user/Schreibtisch/Rust/ESP-Feed/.embuild/espressif/esp-idf-v4.3.1/components/freertos/port/xtensa/xtensa_vectors.S:1105]:0x3ffb0f00 0x400dc36d [_ZN119_$LT$embedded_graphics..iterator..contiguous..IntoPixels$LT$I$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$4next17hbde4298385048300E:/home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/embedded-graphics-0.7.1/src/iterator/contiguous.rs:43]:0x3ffc8110 0x400db15f [_ZN108_$LT$core..iter..adapters..filter..Filter$LT$I$C$P$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$4fold17h957ba52a8dd7c1a8E:/home/user/.rustup/toolchains/esp/lib/rustlib/src/rust/library/core/src/iter/adapters/filter.rs:101]:0x3ffc8180 0x400daa9e [_ZN22embedded_graphics_core11draw_target10DrawTarget15fill_contiguous17hc2cbdbe1e2081cc8E:/home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/embedded-graphics-core-0.3.3/src/draw_target/mod.rs:392]:0x3ffc81e0 0x400dc433 [_ZN22embedded_graphics_core11draw_target10DrawTarget10fill_solid17hb398de9f39040868E:/home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/embedded-graphics-core-0.3.3/src/draw_target/mod.rs:408]:0x3ffc8230 0x400ec253 [_ZN137_$LT$embedded_graphics..mono_font..mono_text_style..MonoTextStyle$LT$C$GT$$u20$as$u20$embedded_graphics..text..renderer..TextRenderer$GT$15draw_whitespace17hc14285199a196967E:/home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/embedded-graphics-0.7.1/src/mono_font/mono_text_style.rs:245]:0x3ffc8260 0x400e1094 [_ZN141_$LT$embedded_text..rendering..line..RenderElementHandler$LT$F$C$D$C$M$GT$$u20$as$u20$embedded_text..rendering..line_iter..ElementHandler$GT$10whitespace17h756b979f6a52a58eE:/home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/embedded-text-0.5.0/src/rendering/line.rs:110]:0x3ffc82b0 0x400e2b14 [_ZN13embedded_text9rendering9line_iter30LineElementParser$LT$M$C$C$GT$15draw_whitespace17h25fc041db625f700E:/home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/embedded-text-0.5.0/src/rendering/line_iter.rs:??]:0x3ffc8300 0x400df661 [_ZN13embedded_text9rendering9line_iter30LineElementParser$LT$M$C$C$GT$7process17hbfbe8c4cfbd67a36E:/home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/embedded-text-0.5.0/src/rendering/line_iter.rs:303]:0x3ffc8350 0x400dfe9f [_ZN87_$LT$esp_feed..graphics..pages..FeedPage$u20$as$u20$esp_feed..graphics..pages..Page$GT$4draw17hece479e2f97a0fc1E:/home/user/Schreibtisch/Rust/ESP-Feed/src/graphics/pages.rs:58]:0x3ffc8660 0x400de875 [_ZN87_$LT$esp_feed..graphics..pages..PageType$u20$as$u20$esp_feed..graphics..pages..Page$GT$4draw17h93586a86414f8956E:/home/user/Schreibtisch/Rust/ESP-Feed/src/graphics/pages.rs:??]:0x3ffc8730 0x400d9643 [_ZN8esp_feed4main28_$u7b$$u7b$closure$u7d$$u7d$17h36bd4023dc5adbc0E:/home/user/Schreibtisch/Rust/ESP-Feed/src/main.rs:121]:0x3ffc87a0 0x400d85b4 [_ZN3std6thread7Builder15spawn_unchecked28_$u7b$$u7b$closure$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$17hef3453897749fa75E:/home/user/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/thread/mod.rs:483]:0x3ffc8be0 0x400d7ab4 [_ZN3std9panicking3try7do_call17h0c6b2805b5870f83E:/home/user/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/panicking.rs:403]:0x3ffc9020 0x400d646e [_ZN3std5panic12catch_unwind17ha7cc8faa73628f98E:/home/user/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/panic.rs:133]:0x3ffc9460 0x400d8bc0 [_ZN3std6thread7Builder15spawn_unchecked28_$u7b$$u7b$closure$u7d$$u7d$17h8b89bc14e1aa3e52E:/home/user/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/thread/mod.rs:482]:0x3ffc98a0 0x40113703 [_ZN90_$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$9call_once17h9e2c6d31fd4b963cE:/home/user/.rustup/toolchains/esp/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1691]:0x3ffc9cf0 0x4011372a [_ZN90_$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$9call_once17ha80a8b5bb5d9cc99E:/home/user/.rustup/toolchains/esp/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1691]:0x3ffc9d10 0x4011aa7c [_ZN3std3sys4unix6thread6Thread3new12thread_start17h50268559994704c1E:/home/user/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/sys/unix/thread.rs:106]:0x3ffc9d30 0x4012de15 [pthread_task_func:/home/user/Schreibtisch/Rust/ESP-Feed/.embuild/espressif/esp-idf-v4.3.1/components/pthread/pthread.c:209]:0x3ffc9d50 0x4008d42d [vPortTaskWrapper:/home/user/Schreibtisch/Rust/ESP-Feed/.embuild/espressif/esp-idf-v4.3.1/components/freertos/port/xtensa/port.c:168]:0x3ffc9d70
ELF file SHA256: 0000000000000000

I'm targeting the default ESP32 and am using Rustc 1.57.0.0

❯ rustc +esp -vV
rustc 1.57.0-dev
binary: rustc
commit-hash: unknown
commit-date: unknown
host: x86_64-unknown-linux-gnu
release: 1.57.0-dev
LLVM version: 13.0.0

We might need a new target or cfg for the ESP32 Pico Mini 02

I have an Adafruit ESP32 Feather V2 : https://www.adafruit.com/product/5400

The thing that has me puzzled is that its silkscreen shows SCL/20 on one of the pins. https://learn.adafruit.com/adafruit-esp32-feather-v2/pinouts

The gpio.rs clause for #[cfg(esp32)] does not include gpio20. Other esp32 variants do have a gpio20, but adafruit has different feathers for those.

According to the admin response to my Adafruit forum post the processor on this feather is actually an ESP32-PICO-MINI-02, and he provides the data sheet: https://cdn-shop.adafruit.com/product-files/5400/esp32-pico-mini-02_datasheet_en.pdf

Comparing figure 3 (pin layout) from the pico mini's datasheet against figure 2 (pin layout from the ESP32 datasheet shows major differences.

As I have transcribed the tables for Pin Definitions the pico mini has pins
0 1 2 3 4 5 7 8 12 13 14 15 19 20 21 22 25 26 27 32 33 34 35 36 37 38 39
while the ESP32 has pins
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 21 22 23 25 26 27 32 33 34 35 36 37 38 39

Is this Pico Mini 02 different from the esp32, esp32s2, esp32s3 and esp32c3 ? I suspect it need its own mod chip. Does that mean it is a new rust target as well? What is the best way to upgrade the crate to support this board?

Should `Gpio1<Atten0dB<ADC2>` impl `Pull`?

I'm porting some code from the Arduino IDE that uses INPUT_PULLUP with an analog pin. I'm using the internal pull-up as a voltage divider with a photoresistor.

Calling gpio_set_pull_mode on the pin after into_analog_atten_11db seems to work, so I'm wondering if the analog gpio pin structs should implement Pull as well?

ESP32C3 GPIO4 and GPIO5 not working

I'm an unable to control GPIO 4 and 5. Matrix user jessebraham was able to reproduce this.
Other GPIOs behave as expected (using the same code as for GPIO4 and 5)

Full Duplex SPI Support

Hey, I'm new to embedded Rust and looking to use https://github.com/smart-leds-rs/ws2812-spi-rs with my esp32 however it looks like the FullDuplex trait that that library needs is commented out in esp-idf-hal - the details of the comment there are unfortunately over my head atm.

Is it possible to open a FullDuplex SPI interface to connect my WS2812 perhaps with some kind of workaround? Is the trait implementation in esp-idf-hal blocked on an issue in embedded-hal?

Relevant Comment: https://github.com/esp-rs/esp-idf-hal/blob/master/src/spi.rs#L469

Get GPIO by number

Would it be possible to implement a method to get a GPIO Pin by its number?

RMT Support (RX)

I'm currently trying to replicate the ESP-IDF blink get started example for the ESP32-S3 and have run into a couple of roadblocks, specifically when trying to implement led_strip_rmt_ws2812.c.

There is no RMT support in esp-idf-hal, looking at other branches it appears it was once supported, but now removed. Is there a reason for this? Could it be added back in?

The other problem is that it appears the GPIO pin configuration does not match up with the ESP32-S3. You cannot select GPIO48 for example, which is required for the blink example where it uses the RGB LED onboard the ESP32-S3 Dev Kit.

Proposal: Add downgrade option on pins

Currently every Pin has his own type, which is necessary to differentiate between them, but doesn't come in handy in other situations. E.g. assume I want to store an array of pins, now every pin has a different type and we end up with an error because I can't create an array of different types. Another option would be to have an array of trait objects ([&dyn InputPin]), but the fact that the current Pin trait has a method without a self parameter or a where Self: Sized bound prevents it from being saved as a vtable:

pub trait Pin {
    type Error;

    fn pin() -> i32; // where Self: Sized would solve this problem

    fn reset(&mut self) -> Result<(), Self::Error>;
}

Looking at other hal implementations like the nrf-hal or or the stm32h7xx-hal you see a third option: a pin type that erases the Pin number and is generic over it's Mode. This type holds the pin and eventual port number as a member variable. Every concrete pin (say Gpio1<MODE>) now has a downgrade method to convert the pin to a type without the Pin number. An example of this can be found here. With this change it would be able to collect a set of pins in lets say an array:

let my_list: [GpioPin<Input>] = [pins.gpio1.into_input()?.degrade(), pins.gpio2.into_input()?.degrade()];

The problem I see with respect to the current implementation is, that the current Pin trait's pin() method doesn't take self, so it would be impossible for a general Gpio type to implement the trait, which is needed as the current APIs (e.g. Uart) have a InputPin bound on their members and InputPin requires an implementation of Pin for a type:

/// Pins used by the UART interface
///
/// Note that any two pins may be used
pub struct Pins<
    TX: OutputPin, // needs Pin
    RX: InputPin, // needs Pin
    // default pins to allow type inference
    CTS: InputPin = crate::gpio::Gpio1<crate::gpio::Input>,
    RTS: OutputPin = crate::gpio::Gpio2<crate::gpio::Output>,
> {
    pub tx: TX,
    pub rx: RX,
    pub cts: Option<CTS>,
    pub rts: Option<RTS>,
}

What do you think about this change? Does it make sense or did I miss something?

how can I iterator gpio?

HI all,

I test some keyboard matrix program and have a problem. How can I use array to save the GPIOs?
something like that...

rowPins =[gpio1,gpio2,gpio3,gpio4];
colPins = [gpio5,gpio6,gpio7,gpio8];

for row in rowPins{
row.set_low().unwrap();....
}

or something like that...?
rowPins =(gpio1,gpio2,gpio3,gpio4);....
but this way doesn't support iterator...

thank you very much!

GPIO pins receive current during deep sleep

(Originally submitted by @mihai-dinculescu against esp-idf-sys.)

Running the code below keeps the led on during the deep sleep, which is different from what I've experienced using the Arduino libs.
Afaik unless gpio_hold_en(gpio_num_t gpio_num) is called alongside gpio_deep_sleep_hold_en(), the pin should go back to low during deep sleep.

Chip type:         ESP32 (revision 1)
Crystal frequency: 40MHz
Flash size:        4MB
Features:          WiFi, BT, Dual Core, Coding Scheme None
[dependencies]
anyhow = { version = "1.0", features = ["backtrace"] }
esp-idf-hal = "0.31"
esp-idf-sys = { version = "0.29", features = ["binstart", "native"] }
use anyhow::Context;
use esp_idf_hal::delay;
use esp_idf_hal::prelude::*;

fn main() -> anyhow::Result<()> {
    esp_idf_sys::link_patches();

    let peripherals = Peripherals::take().context("failed to get peripherals")?;
    let pins = peripherals.pins;

    let mut led = pins.gpio25.into_output_od()?;
    led.set_high()?;

    let mut delay = delay::Ets;
    delay.delay_ms(3000_u32);

    println!("going to sleep...");
    unsafe {
        esp_idf_sys::esp_sleep_enable_timer_wakeup(30 * 1_000_000u64);
        esp_idf_sys::esp_deep_sleep_start();
    }

    Ok(())
}

Support for DelayUntil (From Esp-IDF FreeRTOS xTaskDelayUntil)

Sorry I am new user of this crate and I was doing my previous code on ESP-IDF C code.
I would like to use FreeRTOS features while taking advantage of the abstraction that provides the HAL (If its not possible let me know). I found that its not straightforward or not possible to use the freertos-rs crate as the implementation by ESP-IDF is not the same as the original FreeRTOS.

My issue is, i saw there is a Delay function, but not DelayUntil like in FreeRTOS. And I would like to make a Task or Thread woke up at the same time periodically, not depending on the execution time of that task/thread. Would it be possible to make one?

I found a workaround using esp-idf-sys:

    unsafe {
        let xLastWakeTime = esp_idf_sys::xTaskGetTickCount();
        esp_idf_sys::xTaskDelayUntil(Box::into_raw(Box::new(xLastWakeTime)) as _, 10);
    }

But I am not sure it should be done like this.
(If the Feature can't be added, feel free to let me know if I am wrong at the core of my intent, and give any suggestions.)

(I am using a ESP32-S board
crates: esp-idf-sys, embedded-hal, esp-idf-hal
)

Thank you for your help.

SPI on ESP32-C3 is not working as expected

I have been trying to write a display driver for GC9A01 and ESP32-C3, but have issues using the SPI interface.
What I have been observing is that for every byte of data I am sending over the bus, there is another concaternated byte with 0xff written on the bus. E.g. writing spi.write(&[0x12]) results in 0x12 0xff observed on the bus with a logic analyzer. Writing multiple bytes, e.g. 0x23 0x45 0x56 results in 0x23 0x45 0x56 0xff 0xff 0xff.

It sounds the same as issue #79 . It seems that for every transaction polling_transmit gets called twice, first for transmitting the data, and a second time with transaction_length = 0, but somehow results in the additional bytes on the bus.

How I initially discovered this:

    fn write_cmd(&mut self, cmd: u8) -> Result<(), error::DriverError> {
        let dc = &mut self.dc;

        self.spi
            .transaction(|b| {
                dc.set_low().unwrap();
                b.write(&[cmd]).unwrap();
                Ok(())
            })
            .map_err(|_| DriverError::IO)?;
        Ok(())
    }

and a view on the bus when calling write_cmd(0xeb); write_cmd(0x14):
Bildschirmfoto vom 2022-07-09 18-05-46

First row is CLK, second CS, third MOSI, forth is DC (for the display).

uart example does not compile

The uart example (https://github.com/esp-rs/esp-idf-hal/blob/master/examples/uart_loopback.rs) cannot be implemented because nb seems to be private (ver esp-idf-hal = "0.38"):

error[E0432]: unresolved imports `embedded_hal::serial::nb::Read`, `embedded_hal::serial::nb::Write`
  --> src/main.rs:28:34
   |
28 | use embedded_hal::{serial::{nb::{Read, Write}, Read}, can::nb};
   |                                  ^^^^  ^^^^^ no `Write` in the root
   |                                  |
   |                                  no `Read` in the root

error[E0603]: crate `nb` is private
  --> src/main.rs:28:29
   |
28 | use embedded_hal::{serial::{nb::{Read, Write}, Read}, can::nb};
   |                             ^^ private crate
   |
note: the crate `nb` is defined here
  --> /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/embedded-hal-0.2.7/src/serial.rs:3:5
   |
3  | use nb;
   |     ^^

Include simple examples demonstrating the use of various peripherals

Like most other HAL crates do, we should include some basic examples demonstrating how to use the various peripherals. This was discussed briefly in our community meeting today, and there seemed to be a consensus that this would be a valuable addition to the repository.

rmt::Transmit::start unsound?

It seems to me that once rmt::Transmit::start has been called, since the signal ownership was passed and rmt_write_items is called without block, the signal actually might (or probably will?) be dropped before actually writing out the items. I tested a bit and was able to get everything from memory access violation errors to watchdog errors. I suppose that start would have to return a handle that holds a reference to the signal and can't be dropped until the signal has been fully written. Having drop for the "signal transmit handle" block is controversial i suppose?

Feature request: VariableLengthSignal::with_capacity( ) -> Self

Okay, so esp_idf_hal::rmt::VariableLengthSignal uses a Vec to store pulses, but doesn't allow the programmer to specify a capacity when it is initialized, which means the underlying array will have to be reallocated multiple times.

I'd like there to be an alternative function which lets you pick the Vec's capacity when the struct is initialized

Compilation error v0.37.4 - cannot find struct, variant or union type `ledc_timer_config_t__bindgen_ty_1` in this scope

I'm trying to compile a freshly generated project for use on a ESP32-C3. The Cargo.toml looks like this

[package]
name = "c3-sharp"
version = "0.1.0"
authors = ["Tom Hemmes <[email protected]>"]
edition = "2018"
resolver = "2"

[profile.release]
opt-level = "s"

[profile.dev]
debug = true # Symbols are nice and they don't increase the size on Flash
opt-level = "z"

[features]
pio = ["esp-idf-sys/pio"]

[dependencies]
esp-idf-sys = { version = "0.31.6", features = ["binstart"] }
esp-idf-hal = "0.37.4"
esp-idf-svc = "0.41.4"

[build-dependencies]
embuild = "0.29"
anyhow = "1"

and rust-toolchain.toml like this

[toolchain]
channel = "nightly"

But I'm receiving the following error from the esp-idf-hal compilation:

   Compiling c3-sharp v0.1.0 (/Users/tomhemmes/c3-sharp)
   Compiling esp-idf-hal v0.37.4
error[E0422]: cannot find struct, variant or union type `ledc_timer_config_t__bindgen_ty_1` in this scope
     --> /Users/tomhemmes/.cargo/registry/src/github.com-1ecc6299db9ec823/esp-idf-hal-0.37.4/src/ledc.rs:103:31
      |
103   |             __bindgen_anon_1: ledc_timer_config_t__bindgen_ty_1 {
      |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a struct with a similar name exists: `ledc_channel_config_t__bindgen_ty_1`
      |
     ::: /Users/tomhemmes/c3-sharp/target/riscv32imc-esp-espidf/debug/build/esp-idf-sys-c65e9af4e48a5bb8/out/bindings.rs:67846:1
      |
67846 | pub struct ledc_channel_config_t__bindgen_ty_1 {
      | ---------------------------------------------- similarly named struct `ledc_channel_config_t__bindgen_ty_1` defined here

error[E0560]: struct `esp_idf_sys::ledc_timer_config_t` has no field named `__bindgen_anon_1`
   --> /Users/tomhemmes/.cargo/registry/src/github.com-1ecc6299db9ec823/esp-idf-hal-0.37.4/src/ledc.rs:103:13
    |
103 |             __bindgen_anon_1: ledc_timer_config_t__bindgen_ty_1 {
    |             ^^^^^^^^^^^^^^^^ `esp_idf_sys::ledc_timer_config_t` does not have this field
    |
    = note: available fields are: `speed_mode`, `duty_resolution`, `timer_num`, `freq_hz`, `clk_cfg`

I've tried different (older) version combinations of sys, hal and svc. However, those lead to yet different errors. For which I'm happy to file an issue if you still deem it relevant.

Any pointers on how to resolve this issue would be highly appreciated!

How to loop over GPIO pins?

I am trying to write a driver for a 7-segment LED and I want to be able to loop over the GPIO pins for convenience, is there any way to do this at the moment?

Error is not propagated with ?

ESP32 TTGO, rust-1.55-dev.

Notice how serial is created and its error is propagated with ?.
Main should print error if something happens in run().

#![allow(clippy::single_component_path_imports)]

use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
use std::sync::{Condvar, Mutex};
use std::{cell::RefCell, env, sync::atomic::*, sync::Arc, thread, time::*};

use anyhow::*;
use log::*;

use embedded_svc::anyerror::*;
use embedded_svc::io;

use esp_idf_svc::nvs::*;
use esp_idf_svc::sysloop::*;

use esp_idf_hal::delay;
use esp_idf_hal::gpio;
use esp_idf_hal::prelude::*;
use esp_idf_hal::serial;
use esp_idf_hal::spi;

use esp_idf_sys;
use esp_idf_sys::{esp, EspError};

use display_interface_spi::SPIInterfaceNoCS;

use embedded_graphics::mono_font::{ascii::FONT_10X20, MonoTextStyle};
use embedded_graphics::pixelcolor::*;
use embedded_graphics::prelude::*;
use embedded_graphics::primitives::*;
use embedded_graphics::text::*;

use st7789;

thread_local! {
    static TLS: RefCell<u32> = RefCell::new(13);
}

fn main() -> Result<()> {
    // bind the log crate to the ESP Logging facilities
    esp_idf_svc::log::EspLogger::initialize_default();
    env::set_var("RUST_BACKTRACE", "1");

    if let Err(e) = run() {
        error!("run err: {:?}", e);
    }

    loop {
        info!("X");
        thread::sleep(Duration::from_secs(1));
    }
    Ok(())
}

fn run() -> Result<()> {
    use std::fmt::Write;
    let peripherals = Peripherals::take().unwrap();
    let pins = peripherals.pins;

    let config = serial::config::Config::default().baudrate(Hertz(115_200));

    info!("setup serial");
    let mut serial: serial::Serial<_, _, _> = serial::Serial::new(
        peripherals.uart1,
        serial::Pins {
            tx: pins.gpio27.into_output()?,
            rx: pins.gpio26.into_input()?,
            cts: None,
            rts: None,
        },
        config,
    )?;

    // match serial::Serial::new(
    //     peripherals.uart1,
    //     serial::Pins {
    //         tx: pins.gpio27.into_output()?,
    //         rx: pins.gpio26.into_input()?,
    //         cts: Option::<gpio::Gpio21<gpio::Unknown>>::None,
    //         rts: Option::<gpio::Gpio22<gpio::Unknown>>::None,
    //     },
    //     config,
    // ) {
    //     Ok(serial) => {}
    //     Err(e) => error!("serial {:?}", e),
    // }

    info!("spin..");
    let mut s: usize = 0;
    //loop {
    while s < 10 {
        info!("secs {}", s);
        //writeln!(serial, "{}", format!("secs {}", s)).unwrap();

        thread::sleep(Duration::from_secs(1));
        s += 1;
    }

    Ok(())
}

Log:

cargo espflash /dev/tty.usbserial-0201CA3F
...
...
...

cargo espmonitor /dev/tty.usbserial-0201CA3F                                                                                                    22s  ●  ~/D/y/esp32rogue
ESPMonitor 0.5.2

Commands:
    CTRL+R    Reset chip
    CTRL+C    Exit

Opening /dev/tty.usbserial-0201CA3F with speed 115200
WARNING: Flash image /Users/andres/Development/yaak/esp32rogue/target/xtensa-esp32-none-elf/debug/esp32rogue does not exist (you may need to build it)
Resetting device... done
ets Jun  8 2016 00:22:57
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0048,len:12
ho 0 tail 12 room 4
load:0x3fff0054,len:4800
load:0x40078000,len:17448
load:0x4007c428,len:4840
entry 0x4007c6a0
I (162) cpu_start: Pro cpu up.
I (162) cpu_start: Starting app cpu, entry point is 0x400816b4
I (0) cpu_start: App cpu up.
I (176) cpu_start: Pro cpu start user code
I (177) cpu_start: cpu freq: 160000000
I (177) cpu_start: Application information:
I (181) cpu_start: Project name:     esp-idf
I (186) cpu_start: App version:      b8b0138
I (191) cpu_start: Compile time:     Oct 21 2021 14:26:10
I (197) cpu_start: ELF file SHA256:  0000000000000000...
I (203) cpu_start: ESP-IDF:          4.3.0
I (208) heap_init: Initializing. RAM available for dynamic allocation:
I (215) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (221) heap_init: At 3FFB3508 len 0002CAF8 (178 KiB): DRAM
I (227) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (234) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (240) heap_init: At 4008CFB4 len 0001304C (76 KiB): IRAM
I (247) spi_flash: detected chip: generic
I (251) spi_flash: flash io: dio

And the same thing if this is used:

match serial::Serial::new(
    peripherals.uart1,
    serial::Pins {
        tx: pins.gpio27.into_output()?,
        rx: pins.gpio26.into_input()?,
        cts: Option::<gpio::Gpio21<gpio::Unknown>>::None,
        rts: Option::<gpio::Gpio22<gpio::Unknown>>::None,
    },
    config,
) {
    Ok(serial) => {}
    Err(e) => error!("serial {:?}", e),
}

Log:

cargo espflash /dev/tty.usbserial-0201CA3F
...
...
...

cargo espmonitor /dev/tty.usbserial-0201CA3F

ESPMonitor 0.5.2

Commands:
    CTRL+R    Reset chip
    CTRL+C    Exit

Opening /dev/tty.usbserial-0201CA3F with speed 115200
WARNING: Flash image /Users/andres/Development/yaak/esp32rogue/target/xtensa-esp32-none-elf/debug/esp32rogue does not exist (you may need to build it)
Resetting device... done
ets Jun  8 2016 00:22:57
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0048,len:12
ho 0 tail 12 room 4
load:0x3fff0054,len:4800
load:0x40078000,len:17448
load:0x4007c428,len:4840
entry 0x4007c6a0
I (162) cpu_start: Pro cpu up.
I (162) cpu_start: Starting app cpu, entry point is 0x400816b4
I (0) cpu_start: App cpu up.
I (177) cpu_start: Pro cpu start user code
I (177) cpu_start: cpu freq: 160000000
I (177) cpu_start: Application information:
I (181) cpu_start: Project name:     esp-idf
I (186) cpu_start: App version:      b8b0138
I (191) cpu_start: Compile time:     Oct 21 2021 14:26:10
I (197) cpu_start: ELF file SHA256:  0000000000000000...
I (203) cpu_start: ESP-IDF:          4.3.0
I (208) heap_init: Initializing. RAM available for dynamic allocation:
I (215) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (221) heap_init: At 3FFB3508 len 0002CAF8 (178 KiB): DRAM
I (227) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (234) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (240) heap_init: At 4008CFB4 len 0001304C (76 KiB): IRAM
I (247) spi_flash: detected chip: generic
I (251) spi_flash: flash io: dio
I (256) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (267) esp32rogue: setup serial
E (267) uart: uart_driver_install(1323): uart rx buffer length error
E (277) esp32rogue: serial EspError(-1)
I (287) esp32rogue: spin..
I (287) esp32rogue: secs 0
I (1287) esp32rogue: secs 1
I (2287) esp32rogue: secs 2
I (3287) esp32rogue: secs 3

Notice that this time it printed uart error message and we also see log line from main loop.

add component to idf

hello,
I need to add some components to "sys-idf". how can I do it?

I tested this way.

  1. clone sys-idf-hal
  2. add esp-littlfs to components
  3. add esp-littlefs to binding.h
  4. build it.

but I think this is not right.

QSPI support

Hoping to take advantage of the QSPI and DMA features of the SPI peripheral. This is listed as TODO in spi.rs

Issue with delay While using ILI9341 with SPI.

Facing a horrible error on implementing delay, while trying to connect using SPI with a dsiplay using the crate https://crates.io/crates/ili9341

Tried delay provided with FreeRtos and Ets but it didn't work

> 10     let mut lcd = Ili9341::new( ‣Ili9341<SPIInterface<Master<…>, …>, …>                                                                
    9     ¦   spi_interface,                                                                                                                 
    8     ¦   DummyPin::new_low(),                                                                                                           
>>  7     ¦   &mut delay,                                                                                                                    
    6     ¦   Landscape,                                                                                                                     
    5     ¦   DisplaySize320x480,                                                                                                            
    4     ).unwrap();  

Error is
&mut delay,
| ^^^^^^^^^^ the trait embedded_hal::blocking::delay::DelayMs<u16> is not implemented for Result<(), Infallible>
|
~/.cargo/registry/src/github.com-1ecc6299db9ec823/ili9341-0.5.0/src/lib.rs:87:16
|
87 | DELAY: DelayMs,
| ^^^^^^^^^^^^ required by this bound in Ili9341::<IFACE, RESET>::new

_frxt_setup_switch() not found

I'm getting a compilation issue on the ESP Rust Demo where esp-idf-hal can't compile because a function isn't found:

image

It seems like this was introduced in df907d5, and I'm not sure what this function is supposed to be referring to. If it's helpful, I'm building in the espressif/idf-rust-examples Docker container, and just running cargo build with no other changes to the repo.

As a side-note, I notice that CI is failing on this project, and I'm curious if it's failing early due to a clippy warning, and that might have masked this issue. (edit: it linked me to this run for some reason, it looks like your CI isn't actually failing)

SPI transaction API does not use a single transaction as documented.

The implementation locks the bus to execute all the given operations but it starts a new transaction for each operation.
It simply calls transfer_internal which does not keep the CS pin low after the call.
In addition, transfer_internal itself, doesn't execute the transfer in a single transaction.

The fix is to add SPI_TRANS_CS_KEEP_ACTIVE as a flag in all the spi_transaction_ts until the last one, which will set the CS pin back to high, ending the transaction.

Is BLE supported?

The readme says that this repository is supposed to have ble support: "For embedded projects that don't need Rust STD support, WiFi or BLE (and thus don't link with the ESP-IDF SDK), please check esp-hal."

I've looked at the library files, but couldn't find any trace for BLE support. Am I missing something?

ESP32-C3 GPIO's `is_set_high` and `is_set_low` functions always return `false`/`true` respectively

This is a strange issue, as I have had this working before.

My application runs as expected, with the exception that the LED does not blink. The loop index is printed over serial for each iteration of the loop as intended. I have confirmed my hardware and test setup are okay by flashing the blinky example from esp-idf, which worked as expected.

I have added the minimal project to a repository, generated from esp-idf-template:
https://github.com/jessebraham/esp32c3-idf-hal-test

Rust nightly version is quite new:

λ rustc +nightly --version
rustc 1.59.0-nightly (48a5999fc 2021-12-01)

I'm hoping I'm missing something silly here, but I have tried using multiple GPIOs, tried resetting the pin first, all to no avail.

Handle 80Mhz for SPI freq

Hi !
I'm playing with spi_bus/device initialization in esp-idf-hal and saw that I could setup the freq to 80Mhz by passing SPI_DEVICE_NO_DUMMY to spi_device_interface_config_t::flags like what's documented here in the Dummy bit workaround section.

I have a working example which greatly improves performance for driving my st7789 screen with mipidsi.

Would you be open to a PR exposing more configuration for SPI Bus/Device ?

uart rx buffer length error

On ESP32.

use esp_idf_hal::serial;

let peripherals = Peripherals::take().unwrap();
let pins = peripherals.pins;

let config = serial::config::Config::default().baudrate(Hertz(115_200));

match serial::Serial::new(
    peripherals.uart1,
    serial::Pins {
        tx: pins.gpio27.into_output()?,
        rx: pins.gpio26.into_input()?,
        cts: Option::<gpio::Gpio21<gpio::Unknown>>::None,
        rts: Option::<gpio::Gpio22<gpio::Unknown>>::None,
    },
    config,
) {
    Ok(serial) => {}
    Err(e) => error!("uart {:?}", e),
}
E (658) uart: uart_driver_install(1323): uart rx buffer length error
E (658) esp32rogue: uart EspError(-1)

Missing data in UART receiver

I am trying to read some data over UART. The exact amount is not known in advance, so I put together the following helper:

let start = SystemTime::now();
let serial: serial::Serial<serial::UART1, _, _> = serial::Serial::new(
  // standard setup jazz from https://github.com/esp-rs/esp-idf-hal/blob/master/examples/uart_loopback.rs#L30
).unwrap();
let (uart_tx, uart_rx) = serial.split();

fn reader_helper() -> Result<Vec<u8>> {
  match uart_rx.count() {
    Ok(uart_data_count) => {
      if uart_data_count > 0 {
        for _ in 0..uart_data_count {
          let read_result = nb::block!(uart_rx.read());
          match read_result {
            Ok(d) => // do smth with the data
            Err(e) => // err handling 
           }
         }
       }
     }
     Err(error) =>  // ..
   };
   // ...
}

let start = SystemTime::now();

// wait timeout seconds trying to read all the data coming in
while start.elapsed().unwrap().as_secs() < timeout {
    thread::sleep(Duration::from_millis(10));
    match reader_helper() {
        Ok(uart_data) => // use data
        Err(err) => // error handling 
    }
}

This seems to have been working until recently. Now as I am larger amounts of data, my home made uart reader is only receiving some of it. I can see about 600 bytes of data sent to the device (tracing it in the logic analyzer) but I only get around 300+ bytes read. What I have tried so far, is patching buffer size here by increasing it but with no luck.

How would one troubleshoot this?

Merge `embedded-hal-1-compat` into mainline

This would bring:

  • CAN driver support
  • Forward compatibility with embedded-hal-1.0-alpha6, while preserving compatibility with embeded-hal V0.2
  • Simplified (and hopefully a bit faster) SPI driver, with more embedded-hal traits implemented
  • Simplified gpio in terms of code size and repetition

@andresv Can you confirm that the CAN driver you contributed works as it is supposed to work in that branch?
Also if you can look into this comment? I've "fixed" it in the branch, but the thing is, is it indeed a bug that needs fixing?

compile error esp-idf `driver`component

Hi,
I just wanted to checkout the latest versions of esp-idf-sys, esp-idf-svc and esp-idf-hal and just stumbled across a compile error.

compile_error!("esp-idf-hal requires the `driver` ESP-IDF component to be enabled");

Fired here

I would assume, I have to enable some flags in the sdkconfig since the message sais a driver component is missing.
I took a look at the documentation but could not find anything meaningful that is called a 'driver component' or similar.

What do I have to look for?

I'm on esp-idf v4.4 and have an xtensa esp32 if that's important.

Crash or strange result when printing f32

Not sure if this is the place for this kind of issue...

During #93 (see comment)I discovered that the following code snippet seems to crash on ESP32-S3 and likely ESP32(have not tested the last example on ESP32 yet):

fn main() -> anyhow::Result<()> {
    esp_idf_sys::link_patches();

    let v = 16.0;
    println!("f32 literal is={v}");

    let v = f32::from(16_u16);
    println!("Converting the number seems to work");
    println!("from u16 to f32 is={v}"); // <--- Boom
    loop {}
}

Also note in the log from where I first discovered the problem that there is weird output for several of the "duty" lines before the crash. From what I can tell the actual number printed is important. 16 seems to be the smallest integer >= 0 that when converted to f32 causes a crash. Some of the smaller values only causes weird output.

Somehow I can not seem to reproduce the problem by using a f32 literal(not the exact same value due to floating point magic?)

Compiling in release mode and using IDF v4.4

Error while compiling - "unknown target triple 'xtensa'"

Hi,

While running the next line, from the commit 75b4e4f406c91d8b5e444343b42518b3a176dbdb:

cargo +esp espflash --release --example blinky --target "xtensa-esp32-espidf" --monitor

I get the following error in the library esp-idf-sys v0.31.6:

  error: unknown target triple 'xtensa', please use -triple or -arch
  thread 'main' panicked at 'libclang error; possible causes include:
  - Invalid flag syntax
  - Unrecognized flags
  - Invalid flag arguments
  - File I/O errors
  - Host vs. target architecture mismatch
  If you encounter an error missing from this list, please file an issue or a PR!', /Users/<myhome>/.cargo/registry/src/github.com-1ecc6299db9ec823/bindgen-0.59.2/src/ir/context.rs:538:15
  stack backtrace:
     0:        0x104790912 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h9afe59a1dfa97b4e
     1:        0x1047a99ca - core::fmt::write::h01cb9ef889114011
     2:        0x104778b68 - std::io::Write::write_fmt::h70891e8f82467d23
     3:        0x10477e6ad - std::panicking::default_hook::{{closure}}::h9d7f6ea805ba2dac
     4:        0x10477e365 - std::panicking::default_hook::hc4486dfa32fbb2ce
     5:        0x10477ed2f - std::panicking::rust_panic_with_hook::he9eb721f4a61501f
     6:        0x104791063 - std::panicking::begin_panic_handler::{{closure}}::h5791cd4611a70525
     7:        0x104790a27 - std::sys_common::backtrace::__rust_end_short_backtrace::h7b88daa5f104157c
     8:        0x10477e7f3 - _rust_begin_unwind
     9:        0x1047cf4f3 - core::panicking::panic_fmt::h003274a57d151cc2
    10:        0x1047b10ab - core::panicking::panic_display::h24eb689b53dc19a5
    11:        0x1047b105c - core::panicking::panic_str::h1f9d55d18cde4ac7
    12:        0x1047cf659 - core::option::expect_failed::h2ba5575c5c102319
    13:        0x1043885bc - core::option::Option<T>::expect::ha71576b0ffed911d
    14:        0x104441051 - bindgen::ir::context::BindgenContext::new::h2ab985b72399931c
    15:        0x10432c8da - bindgen::Bindings::generate::h1b52378fbc0ff94c
    16:        0x10432a27d - bindgen::Builder::generate::h038dbcc501be9d6c
    17:        0x1041bcfc9 - embuild::bindgen::run_for_file::h0041c6e36dc766ce
    18:        0x1041bcc10 - embuild::bindgen::run::h892577e00ca134cd
    19:        0x1040fbef4 - build_script_build::main::h739f4e85c0bf3841
    20:        0x1041225fa - core::ops::function::FnOnce::call_once::h3acbe9e0aff91789
    21:        0x1041037bd - std::sys_common::backtrace::__rust_begin_short_backtrace::h996ad941173a893c
    22:        0x10412df00 - std::rt::lang_start::{{closure}}::h20b4d24733aec3db
    23:        0x10476fef5 - std::rt::lang_start_internal::h4ec0af3080375829
    24:        0x10412dee2 - std::rt::lang_start::ha575dcc73898eafa
    25:        0x1040fcbd6 - _main

It's a MacOS, not Linux or Windows.
Thank you.

`FreeRtos::delay_us` will block for less than the given time for fractional milliseconds

embedded_hal states that delay_us:

Pauses execution for at minimum us microseconds. Pause can be longer if the implementation requires it due to precision/timing issues.

The following line always rounds down, resulting in a much shorter delay:

let ms = us / 1000;

I see two solutions, either: using esp_timer_get_time and spinning after vTaskDelay, or doing integer ceiling division instead.


Ran into this trying to bitbang a 1-Wire interface, and still can't seem to get it right. Any suggestions would be helpful!

Converting GpioPin<Input> To GpioPin<SubscribedInput>

Hi!
First of all, thank you for your amazing work, it is really interesting trying out rust in the esp32 world.

Building a driver for a sensor, I would like to be able to receive a generic GpioPin<Input> (or maybe GpioPin<Unknown>?) and be able to install an interrupt for it thus making it a SubscribedInput.

The motivation is of course to decouple the driver from the specific GPIO received.

Example:

struct RotaryEncoder {
    pub clk: GpioPin<SubscribedInput>,
    pub dt: GpioPin<Input>,
}

impl RotaryEncoder {
    fn new(clk: GpioPin<Input>, dt: GpioPin<Input>) -> Self {
       let clk = unsafe clk.into_subscribed(|| {/*some interrupt logic*/}, InterruptType::AnyEdge);

        Self { clk, dt }
    }
} 

As I am not very well trained in rust yet, I am not sure what is the best way to acheive that.. prehaps a trait Subscribe for all 'Pin + InputPin' which implements the into_subscribed function?

A different approach would be to receive a GpioPin<SubscribedInput>,
but with an empty callback (maybe an Option<FnMut> instead of FnMut) and allow subscribing to it after it's creation.

It would be good to be able to change ISR and interrupt type on a pin in runtime especially due to esp32 limitations in AnyEdge interrupts. see espressif's ECO workarounds_for_bugs_in_esp32 3.14

Thank you again

I2C NoAcknowledge on ESP32c3

Hi All,
I'm trying to get a esp32c3 (m5stack c3u board) to communicate with a mpu9250, its connected with:

  • gpio4 = sda
  • gpio5 = scl

But no matter what I keep getting the error:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: I2cError { kind: NoAcknowledge(Unknown), cause: EspError(-1) }', src/main.rs:62:37

I've tried using the write_read function and just directly using a mpu9250 crate so I think the issue lays with the esp_idf_hal crate. I was initially using version 0.37.4 and I tried to go back to version 0.35.2 which also did not work. I've confirmed the mpu9250 is functional by downloading a demo arduino program to the esp32c3 and everything reads just fine with the exact same circuit and hardware.

Below is the test code I've been using. Am I doing something wrong?

use embedded_hal::blocking::i2c::{Read, Write};
use esp_idf_hal::i2c;
use esp_idf_hal::prelude::*;
use esp_idf_hal::units::FromValueType;
use esp_idf_sys as _;
use std::thread;
use std::time::Duration;

fn main() {
    // Temporary. Will disappear once ESP-IDF 4.4 is released, but for now it is necessary to call this function once,
    // or else some patches to the runtime implemented by esp-idf-sys might not link properly.
    esp_idf_sys::link_patches();
    esp_idf_svc::log::EspLogger::initialize_default();
    let per = Peripherals::take().unwrap();
    let sda = per.pins.gpio4.into_input_output().unwrap();
    let scl = per.pins.gpio5.into_output().unwrap();
    let i2c = per.i2c0;

    let config = <i2c::config::MasterConfig as Default>::default().baudrate(400.kHz().into());
    let mut i2cdev =
        i2c::Master::<i2c::I2C0, _, _>::new(i2c, i2c::MasterPins { sda, scl }, config).unwrap();

    loop {
        let mut buff: [u8; 6] = [0; 6];
        i2cdev.write(0x68, &[0x75]).unwrap();
        i2cdev.read(0x68, &mut buff).unwrap();
        log::info!("wai value is {:?}", buff);
        thread::sleep(Duration::from_millis(100));
    }
}

P.S. the line numbers are off because I eliminated a ton of comments. The line that is failing is: i2cdev.write(0x68, &[0x75]).unwrap();

esp_image: invalid segment length 0x3ffb0000

Error when booting:

ets Jun  8 2016 00:22:57
rst:0x3 (SW_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0048,len:12
ho 0 tail 12 room 4
load:0x3fff0054,len:4800
load:0x40078000 [__udivmoddi4:??:??],len:17448
load:0x4007c428 [__udivmoddi4:??:??],len:4840
entry 0x4007c6a0 [__udivmoddi4:??:??]
E (194) esp_image: invalid segment length 0x3ffb0000
E (194) boot: Factory app partition is not bootable
E (194) boot: No bootable app partitions in the partition table
$ readelf --sections target/xtensa-esp32-espidf/debug/robotica-remote-rust
There are 98 section headers, starting at offset 0x2557da4:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .rtc.text         PROGBITS        400c0000 171010 000000 00   W  0   0  1
  [ 2] .rtc.dummy        PROGBITS        3ff80000 171010 000000 00   W  0   0  1
  [ 3] .rtc.force_fast   PROGBITS        3ff80000 171010 000000 00   W  0   0  1
  [ 4] .rtc.data         PROGBITS        50000000 171000 000010 00  WA  0   0  8
  [ 5] .rtc_noinit       PROGBITS        50000010 171010 000000 00   W  0   0  1
  [ 6] .rtc.force_slow   PROGBITS        50000010 171010 000000 00   W  0   0  1
  [ 7] .iram0.vectors    PROGBITS        40080000 055000 000403 00  AX  0   0  4
  [ 8] .iram0.text       PROGBITS        40080404 055404 014b7f 00  AX  0   0  4
  [ 9] .dram0.data       PROGBITS        3ffb0000 051000 0037f8 00  WA  0   0 16
  [10] .ext_ram_noinit   PROGBITS        3f800000 171010 000000 00   W  0   0  1
  [11] .noinit           PROGBITS        3ffb37f8 171010 000000 00   W  0   0  1
  [12] .ext_ram.bss      PROGBITS        3f800000 171010 000000 00   W  0   0  1
  [13] .dram0.bss        NOBITS          3ffb37f8 0547f8 008450 00  WA  0   0  8
  [14] .flash.appdesc    PROGBITS        3f400020 001020 000100 00   A  0   0 16
  [15] .flash.rodata     PROGBITS        3f400120 001120 04fee0 00  WA  0   0 16
  [16] .flash.rodat[...] NOBITS          3f450000 051000 001b7c 00   A  0   0  1
  [17] .flash.text       PROGBITS        400d0020 06a020 105217 00  AX  0   0  4
  [18] .phyiram.20       PROGBITS        401d5238 16f238 000061 00  AX  0   0  4
  [19] .phyiram.18       PROGBITS        401d529c 16f29c 00010e 00  AX  0   0  4
  [20] .phyiram.19       PROGBITS        401d53ac 16f3ac 000090 00  AX  0   0  4
  [21] .phyiram.17       PROGBITS        401d543c 16f43c 0002d7 00  AX  0   0  4
  [22] .phyiram.0        PROGBITS        401d5714 16f714 00002b 00  AX  0   0  4
  [23] .phyiram.1        PROGBITS        401d5740 16f740 00007d 00  AX  0   0  4
  [24] .phyiram.2        PROGBITS        401d57c0 16f7c0 00021e 00  AX  0   0  4
  [25] .phyiram.3        PROGBITS        401d59e0 16f9e0 0000ab 00  AX  0   0  4
  [26] .phyiram.4        PROGBITS        401d5a8c 16fa8c 0000ff 00  AX  0   0  4
  [27] .phyiram.6        PROGBITS        401d5b8c 16fb8c 000083 00  AX  0   0  4
  [28] .phyiram.7        PROGBITS        401d5c10 16fc10 0001ff 00  AX  0   0  4
  [29] .phyiram.8        PROGBITS        401d5e10 16fe10 000177 00  AX  0   0  4
  [30] .phyiram.9        PROGBITS        401d5f88 16ff88 00008e 00  AX  0   0  4
  [31] .phyiram.13       PROGBITS        401d6018 170018 0000ba 00  AX  0   0  4
  [32] .phyiram.12       PROGBITS        401d60d4 1700d4 0000eb 00  AX  0   0  4
  [33] .phyiram.14       PROGBITS        401d61c0 1701c0 0001cb 00  AX  0   0  4
  [34] .phyiram.16       PROGBITS        401d638c 17038c 000072 00  AX  0   0  4
  [35] .phyiram.11       PROGBITS        401d6400 170400 000078 00  AX  0   0  4
  [36] .phyiram.15       PROGBITS        401d6478 170478 0000ba 00  AX  0   0  4
  [37] .phyiram.21       PROGBITS        401d6534 170534 00004a 00  AX  0   0  4
  [38] .phyiram.22       PROGBITS        401d6580 170580 000031 00  AX  0   0  4
  [39] .phyiram.23       PROGBITS        401d65b4 1705b4 000103 00  AX  0   0  4
  [40] .phyiram.24       PROGBITS        401d66b8 1706b8 000087 00  AX  0   0  4
  [41] .iram0.text_end   NOBITS          40094f83 069f83 000001 00  WA  0   0  1
  [42] .iram0.data       PROGBITS        40094f84 171010 000000 00   W  0   0  1
  [43] .iram0.bss        PROGBITS        40094f84 171010 000000 00   W  0   0  1
  [44] .dram0.heap_start PROGBITS        3ffbbc48 171010 000000 00   W  0   0  1
  [45] .xtensa.info      NOTE            00000000 171010 000038 00      0   0  1
  [46] .comment          PROGBITS        00000000 171048 00011a 01  MS  0   0  1
  [47] .xt.lit._ZN3[...] PROGBITS        00000000 171162 000000 00      0   0  1
  [48] .xt.prop._ZN[...] PROGBITS        00000000 171162 000048 00      0   0  1
  [49] .xt.prop._ZN[...] PROGBITS        00000000 1711aa 000054 00      0   0  1
  [50] .xt.lit._ZN1[...] PROGBITS        00000000 1711fe 000000 00      0   0  1
  [51] .xt.lit._ZN1[...] PROGBITS        00000000 1711fe 000008 00      0   0  1
  [52] .xt.prop._ZN[...] PROGBITS        00000000 171206 00006c 00      0   0  1
  [53] .xt.prop._ZN[...] PROGBITS        00000000 171272 00003c 00      0   0  1
  [54] .xt.prop._ZN[...] PROGBITS        00000000 1712ae 00003c 00      0   0  1
  [55] .xt.prop._ZT[...] PROGBITS        00000000 1712ea 00000c 00      0   0  1
  [56] .xt.lit._ZN3[...] PROGBITS        00000000 1712f6 000000 00      0   0  1
  [57] .xt.prop._ZN[...] PROGBITS        00000000 1712f6 000000 00      0   0  1
  [58] .xt.prop._ZN[...] PROGBITS        00000000 1712f6 000024 00      0   0  1
  [59] .xt.prop._ZN[...] PROGBITS        00000000 17131a 000024 00      0   0  1
  [60] .xt.prop._ZT[...] PROGBITS        00000000 17133e 00000c 00      0   0  1
  [61] .xt.lit._ZN3[...] PROGBITS        00000000 17134a 000000 00      0   0  1
  [62] .xt.prop._ZN[...] PROGBITS        00000000 17134a 000000 00      0   0  1
  [63] .xt.prop._ZN[...] PROGBITS        00000000 17134a 000024 00      0   0  1
  [64] .xt.prop._ZN[...] PROGBITS        00000000 17136e 000024 00      0   0  1
  [65] .xt.prop._ZN[...] PROGBITS        00000000 171392 000054 00      0   0  1
  [66] .xt.prop._ZN[...] PROGBITS        00000000 1713e6 000054 00      0   0  1
  [67] .xt.prop._ZT[...] PROGBITS        00000000 17143a 00000c 00      0   0  1
  [68] .xt.prop._ZN[...] PROGBITS        00000000 171446 000054 00      0   0  1
  [69] .xt.lit._ZN3[...] PROGBITS        00000000 17149a 000000 00      0   0  1
  [70] .xt.lit._ZNK[...] PROGBITS        00000000 17149a 000008 00      0   0  1
  [71] .xt.lit._ZN1[...] PROGBITS        00000000 1714a2 000008 00      0   0  1
  [72] .xt.prop._ZN[...] PROGBITS        00000000 1714aa 000000 00      0   0  1
  [73] .xt.prop._ZN[...] PROGBITS        00000000 1714aa 00003c 00      0   0  1
  [74] .xt.prop._ZN[...] PROGBITS        00000000 1714e6 00003c 00      0   0  1
  [75] .xt.prop._ZN[...] PROGBITS        00000000 171522 000030 00      0   0  1
  [76] .xt.prop._ZN[...] PROGBITS        00000000 171552 00003c 00      0   0  1
  [77] .xt.lit._ZN1[...] PROGBITS        00000000 17158e 000008 00      0   0  1
  [78] .xt.prop._ZN[...] PROGBITS        00000000 171596 000048 00      0   0  1
  [79] .xt.prop._ZN[...] PROGBITS        00000000 1715de 00003c 00      0   0  1
  [80] .xt.prop._ZN[...] PROGBITS        00000000 17161a 000054 00      0   0  1
  [81] .xt.prop._ZT[...] PROGBITS        00000000 17166e 00000c 00      0   0  1
  [82] .xt.prop._ZT[...] PROGBITS        00000000 17167a 00000c 00      0   0  1
  [83] .xt.prop._ZT[...] PROGBITS        00000000 171686 00000c 00      0   0  1
  [84] .xt.prop._ZT[...] PROGBITS        00000000 171692 00000c 00      0   0  1
  [85] .debug_loc        PROGBITS        00000000 17169e 31d60b 00      0   0  1
  [86] .debug_abbrev     PROGBITS        00000000 48eca9 096b12 00      0   0  1
  [87] .debug_info       PROGBITS        00000000 5257bb b0fdc1 00      0   0  1
  [88] .debug_aranges    PROGBITS        00000000 1035580 038720 00      0   0  8
  [89] .debug_ranges     PROGBITS        00000000 106dca0 0bce38 00      0   0  8
  [90] .debug_str        PROGBITS        00000000 112aad8 711d3c 01  MS  0   0  1
  [91] .debug_pubnames   PROGBITS        00000000 183c814 32d478 00      0   0  1
  [92] .debug_pubtypes   PROGBITS        00000000 1b69c8c 4bae2f 00      0   0  1
  [93] .debug_frame      PROGBITS        00000000 2024abc 07fb44 00      0   0  4
  [94] .debug_line       PROGBITS        00000000 20a4600 3cad41 00      0   0  1
  [95] .symtab           SYMTAB          00000000 246f344 037da0 10     96 4468  4
  [96] .strtab           STRTAB          00000000 24a70e4 0b022b 00      0   0  1
  [97] .shstrtab         STRTAB          00000000 255730f 000a93 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  p (processor specific)
$ espflash save-image esp32 target/xtensa-esp32-espidf/debug/robotica-remote-rust  image && esptool.py --chip esp32 image_info image 
esptool.py v4.1

A fatal error occurred: End of file reading segment 0x0, length 1073414144 (actual length 1175288)

SPI no longer works after update from `v0.30 -> v0.37`

I've been using an ESP32-S3 to control a couple of TMC5160s over SPI using esp-idf-hal v0.30. Yesterday, I updated the project to esp-idf-hal v0.37 and found that the SPI communication no longer works. The code is unchanged between v0.30 and v0.37, except for the necessary changes to spi::config::Config during initialization.

Any idea what might be causing this? I would guess that it is related to 2d0554d? I'll try to debug the issue by myself in the meantime.

The relevant section of code looks roughly like this, after the abstractions have been removed:

// Note: spi_pins.cs == None
let spi_pins = ...
let mut cs = ...

let spi = Master::<SPI2, _, _, _, _>::new(
        peripherals.spi2,
        spi_pins,
        esp_idf_hal::spi::config::Config {
            baudrate: Hertz(4_000_000),
            data_mode: embedded_hal::spi::MODE_3,                    // v0.37: V02Type(MODE_3).into()
            bit_order: esp_idf_hal::spi::config::BitOrder::MSBFirst, // v0.37: Removed
        },
    )?;
    
// Note: config::BitOrder should (?) be irrelevant, since I construct the bytes myself. As far as I could see from spi.rs
// the BitOrder only affects the ordering of the bytes (weirdly enough) when using Word::load/store for u16, u32.
let data: &mut [[u8; 5]] = ...
for datagram in data {
    cs.set_low()?;
    spi.transfer(&mut datagram)?;
    cs.set_high()?;
}

Versions used:

# Old
esp-idf-sys = { version = "0.28.3", features = ["binstart"] }
embedded-svc = "0.15.4"
esp-idf-svc = "0.34.3"
esp-idf-hal = "0.30.0"
embedded-hal = "0.2"

# New
esp-idf-sys = { version = "0.31", features = ["binstart"] }
embedded-svc = "0.21"
esp-idf-svc = "0.41"
esp-idf-hal = "0.37"
embedded-hal = "0.2"

# Common
ESP_IDF_VERSION = { value = "release/v4.4" } 

unable to use embedded-hal 0.2.7 spi::MODE_0 as argument to Config::data_mode

The following statement triggers a compiler error

use esp_idf_hal::spi;
use esp_idf_hal::units::FromValueType;

    let config = <spi::config::Config as Default>::default()
        // .baudrate(24.MHz().into())
        .baudrate(20.MHz().into())
        .data_mode(embedded_hal::spi::MODE_0);

The compiler error is

error[E0308]: mismatched types
  --> src/main.rs:15:20
   |
15 |         .data_mode(embedded_hal::spi::MODE_0);
   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `embedded_hal::spi::Mode`, found struct `Mode`
   |
   = note: perhaps two different versions of crate `embedded_hal` are being used?

It seems that data_mode needs the Mode from embedded-hal version 1.0.0-alpha.8 while my app uses 0.2.7 . I have been able to import and use both versions of the crate, but I was told this should not be this unergonomic, and I should file this issue.

Missing environment variable

I'm trying to connect this hal to the project built from cargo-generate by this guidance, but it seems like environment variable requested in build.rs script of this crate is absent (the output like: 'environment is absent;' produced by this line.) To reproduce this try to create a project (accordingly to guide) and add in Cargo.toml following lines:

esp-idf-sys = { version = "0.30.3", features = ["binstart"] }
esp-idf-svc = "0.36.9"
esp-idf-hal = "0.32.9"
embedded-svc = "0.16"
embedded-hal = "0.2"

Do you have maybe any suggestions how to fix that?

Implement GpioX methods on generic GpioPin

Many functions like into_input or into_output are implemented on the specific GpioX pins, but not the generic GpioPin.

Especially when trying to write ergonomic libraries, this makes things fairly hard. E.g. if I want to greate a generic output which can be attached to any GPIO, I'd want a user to only tell me which pin to use and the lib would take care of initializing it. At the moment I have to decide (as far as I can see) either to take a generic pin, or to handle initialization.

This might be related to #66 which I think is a similar situation and one I'd expected to work too.

Thoughts on FreeRTOS queue/semaphore wrappers?

It would be really cool to utilise native FreeRTOS queues and semaphores from Rust safely.

There's this wrapper, but it uses a C shim. It would be far nicer to safely wrap esp-idf-sys.

Are there any plans within the esp-rs project on this front?

Also, off-topic, but is there a place of discussion for esp-rs? Like a discord or IRC?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.