esp-rs / esp-hal

no_std Hardware Abstraction Layers for ESP32 microcontrollers
https://docs.esp-rs.org/esp-hal/
Apache License 2.0
718 stars 194 forks source link

esp32c6 ESP-NOW unable to set rate. #1612

Open alexbohm opened 10 months ago

alexbohm commented 10 months ago

I'm working on a project using esp now on the esp32c6 and I'm unable to set a rate with the set_rate function.

I can reproduce this with the embassy_esp_now example by adding this line just before the loop.

esp_now.set_rate(esp_wifi::esp_now::WifiPhyRate::Rate2m).unwrap();

When I turn on the wifi logs, I get the message:

INFO - W (336) wifi:
INFO - This API is not supported in WIFI6 mode, please use esp_now_set_peer_rate_config() instead
INFO - 

It doesn't look like esp_now_set_peer_rate_config() is in the bindgen bindings, and according to https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/api-reference/network/esp_now.html#config-esp-now-rate, that's what is supposed to be used to configure the rate for each added peer.

Looking at the header in esp-idf, this function was added fairly recently: https://github.com/espressif/esp-idf/blob/master/components/esp_wifi/include/esp_now.h

bjoernQ commented 10 months ago

Currently we use the drivers/header from ESP-IDF commit c570f674610479fc5e070c8db6d181b73ddf60a8 - we update the drivers more or less regularly

I guess the next update should happen in the first half of January

alexbohm commented 10 months ago

Thanks for the update!

I've been playing around with https://github.com/esp-rs/esp-wireless-drivers-3rdparty to see if I could update them myself while learning a bit more about how this is all integrated.

First I copied the new headers into esp-wifi-sys from esp-idf. This was pretty straight forward, I just matched the filenames.

Then, I played around with updating the libs using esp-wireless-drivers-3rdparty. Most of the libs seemed to update fine except wpa_supplicant needed a couple more options disabled in sdkconfig to keep CONFIG_ESP_WIFI_MBEDTLS_CRYPTO (previously CONFIG_WPA_MBEDTLS_CRYPTO) disabled.

patch/esp32c6/sdkconfig.defaults:

CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=n
CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=n
CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=n
CONFIG_ESP_WIFI_DPP_SUPPORT=n
CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=n
CONFIG_COMPILER_OPTIMIZATION_SIZE=y

Those options let everything compile in esp-wireless-drivers-3rdparty, but in the rust compile it got hung up during linking with:

  = note: rust-lld: error: undefined symbol: sleep
          >>> referenced by os_xtensa.c:55 (/home/alex/esp/esp-idf/components/wpa_supplicant/port/os_xtensa.c:55)
          >>>               os_xtensa.c.obj:(os_sleep) in archive /home/alex/code/esp-control/target/riscv32imac-unknown-none-elf/release/build/esp-wifi-sys-717724a08f01e6eb/out/libwpa_supplicant.a

          rust-lld: error: undefined symbol: usleep
          >>> referenced by os_xtensa.c:55 (/home/alex/esp/esp-idf/components/wpa_supplicant/port/os_xtensa.c:55)
          >>>               os_xtensa.c.obj:(os_sleep) in archive /home/alex/code/esp-control/target/riscv32imac-unknown-none-elf/release/build/esp-wifi-sys-717724a08f01e6eb/out/libwpa_supplicant.a

I'll have to poke a bit more at those functions later, I'm not sure if it should be trying os_xtensa.c anyways.

I did try using the old libwpa_supplicant.a, and the embassy esp now example did compile but it seemed to get stuck during the initialization process.

bjoernQ commented 10 months ago

Thanks for looking into that.

First I copied the new headers into esp-wifi-sys from esp-idf. This was pretty straight forward, I just matched the filenames.

That's certainly fine for testing - in the end the Makefile should copy the headers and libraries

Ending up with just two missing functions is not too bad. Probably you can just implement them in esp-wifi/src/compat I think the original implementation is this: https://github.com/espressif/esp-idf/blob/30870c819f8bf1be1c8a3b4360be8174a280b40c/components/newlib/time.c#L195-L213

You can probably ignore the vTaskDelay part and just use a rom function (ets_delay_us should be available already)

Would be awesome if you could prepare the update. I definitely want to wait until after the next release which will happen immediately after the next esp-hal release but having something prepared would make things easier

alexbohm commented 9 months ago

I added some quick and dirty implementations of those sleeps into https://github.com/alexbohm/esp-wifi/tree/feature/update_esp_now.

Seems to get things building, but running the examples it seems to hit some issues:

TRACE - alloc 228
TRACE - random
Exception 'Load access fault' mepc=0x4080ecea, mtval=0x000001a8
0x4080ecea - ieee80211_set_tx_pti
    at ??:??
0x000001a8 - crypto_hash_finish
    at /home/alex/esp/esp-idf/components/wpa_supplicant/src/crypto/crypto_internal.c:279
TrapFrame
PC=0x4080ecea         RA/x1=0x42061920      SP/x2=0x40810110      GP/x3=0x4086dab0      TP/x4=0x00000000
0x4080ecea - ieee80211_set_tx_pti
    at ??:??
0x42061920 - .L82
    at ??:??
0x40810110 - __global_pointer$
    at ??:??
0x4086dab0 - _stack_end
    at ??:??
0x00000000 - sha512_init
    at /home/alex/esp/esp-idf/components/wpa_supplicant/src/crypto/sha512-internal.c:191
T0/x5=0x4086d890      T1/x6=0x4086d950      T2/x7=0x00000000      S0/FP/x8=0x4081e30c   S1/x9=0x4081dde8
0x4086d890 - _stack_end
    at ??:??
0x4086d950 - _stack_end
    at ??:??
0x00000000 - sha512_init
    at /home/alex/esp/esp-idf/components/wpa_supplicant/src/crypto/sha512-internal.c:191
0x4081e30c - _ZN8esp_wifi9HEAP_DATA17h83c03cabc66b4ff0E
    at ??:??
0x4081dde8 - _ZN8esp_wifi9HEAP_DATA17h83c03cabc66b4ff0E
    at ??:??
A0/x10=0x4081dba8     A1/x11=0x00000008     A2/x12=0x40810000     A3/x13=0xfffeffff     A4/x14=0x00000000
0x4081dba8 - _ZN8esp_wifi9HEAP_DATA17h83c03cabc66b4ff0E
    at ??:??
0x00000008 - sha512_init
    at /home/alex/esp/esp-idf/components/wpa_supplicant/src/crypto/sha512-internal.c:191
0x40810000 - .LANCHOR17
    at ??:??
0xfffeffff - _rtc_fast_bss_start
    at ??:??
0x00000000 - sha512_init
    at /home/alex/esp/esp-idf/components/wpa_supplicant/src/crypto/sha512-internal.c:191
A5/x15=0x00000000     A6/x16=0x00000004     A7/x17=0x42050024     S2/x18=0x4081dba8     S3/x19=0x4081e354
0x00000000 - sha512_init
    at /home/alex/esp/esp-idf/components/wpa_supplicant/src/crypto/sha512-internal.c:191
0x00000004 - sha512_init
    at /home/alex/esp/esp-idf/components/wpa_supplicant/src/crypto/sha512-internal.c:191
0x42050024 - <&T as core::fmt::Display>::fmt
    at /home/alex/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/mod.rs:2294
0x4081dba8 - _ZN8esp_wifi9HEAP_DATA17h83c03cabc66b4ff0E
    at ??:??
0x4081e354 - _ZN8esp_wifi9HEAP_DATA17h83c03cabc66b4ff0E
    at ??:??
S4/x20=0x00000000     S5/x21=0x00000000     S6/x22=0x4081e354     S7/x23=0x40880000     S8/x24=0x40880000
0x00000000 - sha512_init
    at /home/alex/esp/esp-idf/components/wpa_supplicant/src/crypto/sha512-internal.c:191
0x00000000 - sha512_init
    at /home/alex/esp/esp-idf/components/wpa_supplicant/src/crypto/sha512-internal.c:191
0x4081e354 - _ZN8esp_wifi9HEAP_DATA17h83c03cabc66b4ff0E
    at ??:??
0x40880000 - g_saved_pc
    at ??:??
0x40880000 - g_saved_pc
    at ??:??
S9/x25=0x00000001     S10/x26=0x4081e3c4    S11/x27=0x00000001    T3/x28=0x00000002     T4/x29=0x0486d940
0x00000001 - sha512_init
    at /home/alex/esp/esp-idf/components/wpa_supplicant/src/crypto/sha512-internal.c:191
0x4081e3c4 - _ZN8esp_wifi9HEAP_DATA17h83c03cabc66b4ff0E
    at ??:??
0x00000001 - sha512_init
    at /home/alex/esp/esp-idf/components/wpa_supplicant/src/crypto/sha512-internal.c:191
0x00000002 - sha512_init
    at /home/alex/esp/esp-idf/components/wpa_supplicant/src/crypto/sha512-internal.c:191
0x0486d940 - .Ldebug_info0
    at ??:??
T5/x30=0x40810dec     T6/x31=0x00000002
0x40810dec - _ZN3log5STATE17h2cf7c8ece114e704E
    at ??:??
0x00000002 - sha512_init
    at /home/alex/esp/esp-idf/components/wpa_supplicant/src/crypto/sha512-internal.c:191

MSTATUS=0x00001881
0x00001881 - 
    at ??:??
MCAUSE=0x00000005
0x00000005 - sha512_init
    at /home/alex/esp/esp-idf/components/wpa_supplicant/src/crypto/sha512-internal.c:191
MTVAL=0x000001a8
0x000001a8 - crypto_hash_finish
    at /home/alex/esp/esp-idf/components/wpa_supplicant/src/crypto/crypto_internal.c:279

No backtrace available - make sure to force frame-pointers. (see https://crates.io/crates/esp-backtrace)

I've seen Illegal instruction, Load access fault, Store/AMO access fault between trying the various examples so something is funky.

bjoernQ commented 9 months ago

Could you try with https://github.com/esp-rs/esp-hal/pull/1008 ? With the changes there I was able to see

esp-now version 1
Send
Send broadcast status: Ok(())
Send
Send broadcast status: Ok(())
Send
Send broadcast status: Ok(())
Send
Send broadcast status: Ok(())
Send
Send broadcast status: Ok(())
Send
Send broadcast status: Ok(())
alexbohm commented 9 months ago

Nice! I'm seeing the same here. esp-rs/esp-hal#1008 seems to stop the exceptions but something is still not quite right. It doesn't seem to receive anything from another esp running that same esp-now broadcast example.

I also tried the dhcp and embassy dhcp example and while they ran, it couldn't seem to connect to the network, giving a reason 201:

INFO - D (4236) wifi:
INFO - Send disconnect event, reason=201
INFO - 

I'm pretty sure I have my password correct, so according to https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/api-guides/wifi.html, it's having trouble finding/scanning the access point.

bjoernQ commented 9 months ago

At least progress - I think the newer drivers added some config parameters - are we sure we set values which make sense (e.g. compared to what esp-idf's defaults are)?

IIRC the esp-now example at least sends something which was shown on another device (running the example from main)

alexbohm commented 9 months ago

I've been looking at some of the config options. tbh, I don't have enough experience with esp wifi stuff to know which ones to change. I compared them to what is in the esp idf, and it seems like they are set to appropriate defaults? I did switch one of the new options rx_mgmt_buf_num to the default of 5 but it didn't seem to change anything.

With one board running the old drivers and one board running the "updated" drivers, I ran the esp now example and the old drivers did receive the esp now messages from the updated drivers, so at least I know that the updated drivers are sending the messages.

bjoernQ commented 9 months ago

Many of those settings are a mystery since they are often not well documented - I usually try to align them with the defaults in esp-idf in that case

Interesting it seems to be able to send the messages just fine but only fails to receive anything 😲 doesn't make me look forward to the next driver update after publishing 0.2

bjoernQ commented 8 months ago

The drivers are updated now - unfortunately you will need to patch esp-hal for now (until the next esp-hal release)

alexbohm commented 8 months ago

Thanks for getting the drivers updated! Out of curiosity, after updating did sending and receiving just work? Maybe I just had a bad build.

I've been exploring how to set the rates and it seems like some of the phymodes + rates may need protocol, bandwidth, and channel changes in order to use them. I created a draft pull request esp-rs/esp-wifi-sys#418 with some hardcoded values for now.

I'm not sure what the best api is for setting the rate, whether it calls only esp_now_set_peer_rate_config or if it does the channel/bandwidth changes in that same function as well.

bjoernQ commented 8 months ago

Thanks for getting the drivers updated! Out of curiosity, after updating did sending and receiving just work? Maybe I just had a bad build.

Yes, it just worked for me