esp-rs / esp-idf-hal Goto Github PK
View Code? Open in Web Editor NEWembedded-hal implementation for Rust on ESP32 and ESP-IDF
Home Page: https://docs.esp-rs.org/esp-idf-hal/
License: Apache License 2.0
embedded-hal implementation for Rust on ESP32 and ESP-IDF
Home Page: https://docs.esp-rs.org/esp-idf-hal/
License: Apache License 2.0
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:
GpioXX
pin structs have no method to convert them to the Analog
typestateChannel
and OneShot
traits imply that ADC1
and ADC2
newtypes should exist, but they do notAt 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
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
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?
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?
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)
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
Would it be possible to implement a method to get a GPIO Pin by its number?
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.
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?
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!
(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(())
}
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.
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)
:
First row is CLK, second CS, third MOSI, forth is DC (for the display).
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;
| ^^
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.
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?
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
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!
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?
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.
hello,
I need to add some components to "sys-idf". how can I do it?
I tested this way.
but I think this is not right.
Hoping to take advantage of the QSPI and DMA features of the SPI peripheral. This is listed as TODO in spi.rs
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
I'm getting a compilation issue on the ESP Rust Demo where esp-idf-hal
can't compile because a function isn't found:
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)
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_t
s until the last one, which will set the CS pin back to high, ending the transaction.
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?
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.
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 ?
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)
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?
This would bring:
embedded-hal
traits implemented@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?
The example contains peripherals.pins.gpio1
https://github.com/esp-rs/esp-idf-hal/blob/master/examples/ledc-simple.rs#L17
This causes conflict with --monitor
on ESP32 and the user can see only question marks filling the terminal.
GPIO1 for ESP32 is UART 0 TX, consider changing it to GPIO4.
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.
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
According to this https://www.esp32.com/viewtopic.php?t=2687 those pins are configured for JTAG after reset and they must be set to GPIO from pinmux before they can be used as GPIO pins.
As per a comment from @MabezDev:
Could non blocking be implemented using uart_wait_tx_done with a low (or 0) timeout.
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.
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:
Line 129 in d446ec9
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!
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
Hi All,
I'm trying to get a esp32c3 (m5stack c3u board) to communicate with a mpu9250, its connected with:
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();
Hi!
Is there any way to access the MCPWM peripheral found in ESP32 and ESP32-S3 through this crate?
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)
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" }
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.
Subject says it all :)
https://github.com/esp-rs/esp-idf-hal/blob/fb2c9f7657a302600494c44fc1c1073f62c49248/src/gpio.rs#L909..L924
Here the GPIOs 11-17 for the ESP32C3 are unmapped. Is this intentional?
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?
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.
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?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.