Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async SPI - already borrowed: BorrowMutError on esp32s3 #1863

Closed
VersBinarii opened this issue Jul 26, 2024 · 3 comments
Closed

Async SPI - already borrowed: BorrowMutError on esp32s3 #1863

VersBinarii opened this issue Jul 26, 2024 · 3 comments

Comments

@VersBinarii
Copy link

VersBinarii commented Jul 26, 2024

Hello,
I'm having issue with the following code and would appreciate some pointers on how to make it work.

    let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
    let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
    let tim: ErasedTimer = timg0.timer0.into();
    let timer0 = OneShotTimer::new(tim);
    let timers = make_static!([timer0]);
    esp_hal_embassy::init(&clocks, timers);

    esp_println::logger::init_logger_from_env();

    let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
    let sclk = io.pins.gpio1;
    let din = io.pins.gpio2;
    let eink_cs = Output::new(io.pins.gpio3, Level::High);
    let eink_dc = Output::new(io.pins.gpio4, Level::High);
    let busy = Input::new(io.pins.gpio7, Pull::Up);
    let reset = Output::new(io.pins.gpio8, Level::High);
    let dma = Dma::new(peripherals.DMA);
    let dma_channel = dma.channel0;
    let (tx_descriptors, rx_descriptors) = dma_descriptors!(32000);

    let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
        .with_mosi(din)
        .with_sck(sclk)
        .with_dma(
            dma_channel.configure_for_async(false, DmaPriority::Priority0),
            tx_descriptors,
            rx_descriptors,
        );
    let spi: SafeSpiDma = FlashSafeDma::new(spi);
    let spi_device = ExclusiveDevice::new(spi, eink_cs, Delay).unwrap();
    let spi_interface = SpiInterface::new(spi_device, eink_dc);
    let mut driver = WeActStudio213TriColorDriver::new(spi_interface, busy, reset, Delay);
    let mut display = Display213TriColor::new();
    display.set_rotation(DisplayRotation::Rotate90);
    driver.init().await.expect("Failed to init");
    let style = MonoTextStyle::new(&PROFONT_24_POINT, TriColor::Red);
    let mut string_buf = String::<30>::new();
    write!(string_buf, "Time:\nInterval:").unwrap();
    let _ = Text::with_text_style(&string_buf, Point::new(8, 40), style, TextStyle::default())
        .draw(&mut display)
        .unwrap();
    string_buf.clear();
    if let Err(e) = driver.full_update(display).await {
        log::error!("Error: {:?}", e);
    }

The code results with following:

I (45) boot: ESP-IDF v5.1-beta1-378-gea5e0ff298-dirt 2nd stage bootloader
I (46) boot: compile time Jun  7 2023 08:07:32
I (47) boot: Multicore bootloader
I (51) boot: chip revision: v0.2
I (55) boot.esp32s3: Boot SPI Speed : 40MHz
I (59) boot.esp32s3: SPI Mode       : DIO
I (64) boot.esp32s3: SPI Flash Size : 4MB
I (69) boot: Enabling RNG early entropy source...
I (74) boot: Partition Table:
I (78) boot: ## Label            Usage          Type ST Offset   Length
I (85) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (93) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (100) boot:  2 factory          factory app      00 00 00010000 003f0000
I (108) boot: End of partition table
I (112) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=07e24h ( 32292) map
I (128) esp_image: segment 1: paddr=00017e4c vaddr=3fc8929c size=00008h (     8) load
I (129) esp_image: segment 2: paddr=00017e5c vaddr=40378000 size=0129ch (  4764) load
I (139) esp_image: segment 3: paddr=00019100 vaddr=00000000 size=06f18h ( 28440)
I (153) esp_image: segment 4: paddr=00020020 vaddr=42000020 size=1169ch ( 71324) map
I (172) boot: Loaded app from partition at offset 0x10000
I (173) boot: Disabling RNG early entropy source...



!! A panic occured in 'config/cargo/git/checkouts/esp-hal-42ec44e8c6943228/2744a5d/esp-hal-embassy/src/time_driver.rs', at line 171, column 37:
PanicInfo {
    payload: Any { .. },
    message: Some(
        already borrowed: BorrowMutError,
    ),
    location: Location {
        file: ".config/cargo/git/checkouts/esp-hal-42ec44e8c6943228/2744a5d/esp-hal-embassy/src/time_driver.rs",
        line: 171,
        col: 37,
    },
    can_unwind: true,
    force_no_backtrace: false,
}

Backtrace:

0x420108b4
0x420108b4 - core::cell::RefCell<T>::borrow_mut
    at .rustup/toolchains/esp/lib/rustlib/src/rust/library/core/src/cell.rs:1076
0x4200169f
0x4200169f - embassy_time_driver::set_alarm
    at .config/cargo/git/checkouts/embassy-9312dcb0ed774b29/2537fc6/embassy-time-driver/src/lib.rs:163
0x42008503
0x42008503 - calendar::__xtensa_lx_rt_main
    at Devel/Embedded/esp_embassy/src/main.rs:59
0x4201107a
0x4201107a - Reset
    at .config/cargo/registry/src/index.crates.io-6f17d22bba15001f/xtensa-lx-rt-0.16.0/src/lib.rs:70
0x403788b0
0x403788b0 - ESP32Reset
    at .config/cargo/git/checkouts/esp-hal-42ec44e8c6943228/2744a5d/esp-hal/src/soc/esp32s3/mod.rs:152
0x3ffffffd
0x3ffffffd - _stack_start_cpu0
    at ??:??
0x403cdd79
0x403cdd79 - _ZN7esp32s312__INTERRUPTS17hcdbf28238c6f341aE
    at ??:??
0x403c9971
0x403c9971 - _ZN7esp32s312__INTERRUPTS17hcdbf28238c6f341aE
    at ??:??
0x40045c01
0x40045c01 - rom_i2c_writeReg_Mask
    at ??:??
0x40043ab6
0x40043ab6 - rom_i2c_writeReg_Mask
    at ??:??

The actual lines of code that cause the crash are:

    if let Err(e) = driver.full_update(display).await {
        log::error!("Error: {:?}", e);
    }

Removing it makes the rest of the code work correctly
I'm using follwing packages:

[dependencies]
esp-hal-embassy = { version = "0.2", features = ["esp32s3"] }
embassy-executor = { version = "0.5.0", features = [
  "task-arena-size-327680",
  "integrated-timers",
] }
embassy-time = { version = "0.3.1", features = [] }
embassy-sync = { version = "0.6.0" }
embassy-embedded-hal = { version = "0.1.0" }
esp-backtrace = { version = "0.13.0", features = [
  "esp32s3",
  "exception-handler",
  "panic-handler",
  "println",
] }
esp-hal = { version = "0.19.0", features = ["esp32s3", "async"] }
esp-println = { version = "0.10.0", features = ["esp32s3", "log"] }
log = { version = "0.4.21" }
static_cell = { version = "2", features = ["nightly"] }
bme280 = { version = "0.5.1", features = ["async"] }
embedded-hal-async = { version = "1.0.0" }
display-interface = { version = "0.5" }
display-interface-spi = { version = "0.5" }
embedded-hal-bus = { version = "0.2.0", features = ["async"] }
weact-studio-epd = { git = "https://github.com/avsaase/weact-studio-epd" }
profont = { version = "0.7.0" }
embedded-graphics = { version = "0.8.1" }
heapless = { version = "0.8" }

[patch.crates-io]
embassy-embedded-hal = { git = "https://github.com/embassy-rs/embassy", rev = "2537fc6f4fcbdaa0fcea45a37382d61f59cc5767" }
embassy-executor = { git = "https://github.com/embassy-rs/embassy", rev = "2537fc6f4fcbdaa0fcea45a37382d61f59cc5767" }
embassy-time = { git = "https://github.com/embassy-rs/embassy", rev = "2537fc6f4fcbdaa0fcea45a37382d61f59cc5767" }
embassy-time-driver = { git = "https://github.com/embassy-rs/embassy", rev = "2537fc6f4fcbdaa0fcea45a37382d61f59cc5767" }
embassy-time-queue-driver = { git = "https://github.com/embassy-rs/embassy", rev = "2537fc6f4fcbdaa0fcea45a37382d61f59cc5767" }
embassy-sync = { git = "https://github.com/embassy-rs/embassy", rev = "2537fc6f4fcbdaa0fcea45a37382d61f59cc5767" }
display-interface = { git = "https://github.com/therealprof/display-interface", rev = "8fca041b0288740678f16c1d05cce21bd3867ee5" }
display-interface-spi = { git = "https://github.com/therealprof/display-interface", rev = "8fca041b0288740678f16c1d05cce21bd3867ee5" }
esp-hal = { git = "https://github.com/esp-rs/esp-hal", rev = "2744a5d" }
esp-hal-embassy = { git = "https://github.com/esp-rs/esp-hal", rev = "2744a5d" }
@VersBinarii VersBinarii changed the title Async SPI - already borrowed: BorrowMutError Async SPI - already borrowed: BorrowMutError on esp32s3 Jul 26, 2024
@plaes
Copy link
Contributor

plaes commented Jul 27, 2024

Firstly, this line looks really odd as one would assume you would add at least driver as an argument there...

    let mut display = Display213TriColor::new();

How about:

    if let Err(e) = driver.full_update(&mut display).await {
        log::error!("Error: {:?}", e);
    }

@VersBinarii
Copy link
Author

VersBinarii commented Jul 28, 2024

@plaes this is how the API for the driver is designed

@VersBinarii
Copy link
Author

Ok, i managed to get it working without changing any code i did however change the dependencies to following:

embassy-executor = { version = "0.5.0", features = ["nightly"] }
embassy-time = { version = "0.3.1", features = ["generic-queue"] }

@github-project-automation github-project-automation bot moved this from Todo to Done in esp-rs Jul 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

2 participants