mirror of
https://github.com/esp-rs/esp-idf-hal.git
synced 2025-09-28 21:01:26 +00:00
fix wrong Alert enum indexing (#533)
* fix wrong Alert enum indexing closes #532 * remove TryFromPrimitive from Alert enum Its wrong to derive TryFromPrimitive in this case, since the numbers in this cases represent bitpositions An example: ```rust #[derive(Debug, EnumSetType, TryFromPrimitive)] #[enumset(repr = "u32")] #[repr(u32)] enum MyType { One = 1, Two = 2, Three = 3, } ``` would produce a wrong derive like ```rust impl ::num_enum::TryFromPrimitive for MyType { type Primitive = u32; type Error = ::num_enum::TryFromPrimitiveError<Self>; const NAME: &'static str = "MyType"; fn try_from_primitive( number: Self::Primitive, ) -> ::core::result::Result<Self, ::num_enum::TryFromPrimitiveError<Self>> { #![allow(non_upper_case_globals)] const One__num_enum_0__: u32 = 1; const Two__num_enum_0__: u32 = 2; const Three__num_enum_0__: u32 = 3; #[deny(unreachable_patterns)] match number { One__num_enum_0__ => ::core::result::Result::Ok(Self::One), Two__num_enum_0__ => ::core::result::Result::Ok(Self::Two), Three__num_enum_0__ => ::core::result::Result::Ok(Self::Three), #[allow(unreachable_patterns)] _ => { ::core::result::Result::Err( ::num_enum::TryFromPrimitiveError::<Self>::new(number), ) } } } } impl ::core::convert::TryFrom<u32> for MyType { type Error = ::num_enum::TryFromPrimitiveError<Self>; #[inline] fn try_from( number: u32, ) -> ::core::result::Result<Self, ::num_enum::TryFromPrimitiveError<Self>> { ::num_enum::TryFromPrimitive::try_from_primitive(number) } } ``` * remove not needed num_enum dependency * changelog
This commit is contained in:
parent
7117923788
commit
a371755b8c
27
CHANGELOG.md
27
CHANGELOG.md
@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Fix the SDMMC driver for ESP-IDF V5.5+
|
||||
- Replace Arc with Rc in ledc_threads example (#514)
|
||||
- Fix outdated task docs
|
||||
- CAN: fix wrong Alert enum indexing / remove wrong TryFromPrimitive derive (#532)
|
||||
|
||||
## [0.45.2] - 2025-01-15
|
||||
|
||||
@ -68,7 +69,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [0.44.1] - 2024-07-09
|
||||
### Fixed
|
||||
* The crate now does build with ESP-IDF V4.4.x + esp32c2/esp32c6/esp32h2, yet these MCUs should only be used with ESP-IDF V5+
|
||||
* The crate now does build with ESP-IDF V4.4.x + esp32c2/esp32c6/esp32h2, yet these MCUs should only be used with ESP-IDF V5+
|
||||
as they are not officially supported with ESP-IDF V4.4.x (#450)
|
||||
* Enum `ResetReason` not dealing with all reset reasons (panics on unknown reset reason) (#443, #444)
|
||||
|
||||
@ -100,7 +101,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
* ledc: max_duty() method miscalulated in certain conditions. (#431)
|
||||
* timer: fix clock usage in timer driver used with ESP-IDF v5.x (#441)
|
||||
* i2c: use correct xtal for esp32c2 on timeout calculations. (#438)
|
||||
|
||||
|
||||
## [0.43.1] - 2024-02-21
|
||||
* Fix - PinDriver state changes and the drop call invoked pull-ups to be enabled. New default behavior on init / state transition / drop is to not enable pull-ups. (#344). If users want to reduce power usage on unused pins, they now need to manually enable pull-ups on a pin. For example, call `core::mem::forget` on the PinDriver instance after setting the pull-ups.
|
||||
* #354 - breaking change - `rmt` driver now does not directly expose `rmt_item32_t` but rather - wraps it with a `Symbol` newtype
|
||||
@ -120,7 +121,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
* #350 - Not checking for ESP_FAIL in AsyncCanDriver::transmit
|
||||
|
||||
## [0.42.5] - 2023-11-12
|
||||
* BREAKING CHANGE IN A PATCH RELEASE DUE TO DISCOVERED UB: The `subscribe` methods in drivers `PinDriver`, `PcntDriver` and `TimerDriver`
|
||||
* BREAKING CHANGE IN A PATCH RELEASE DUE TO DISCOVERED UB: The `subscribe` methods in drivers `PinDriver`, `PcntDriver` and `TimerDriver`
|
||||
no longer accept non-static callbacks, as these lead to UB / crash when the driver is forgotten with e.g. `core::mem::forget`. Since local borrows
|
||||
are a very useful feature however, these are still allowed via the newly-introduced and even more unsafe `subscribe_nonstatic` method.
|
||||
|
||||
@ -238,12 +239,12 @@ The main themes of the 0.39 release are:
|
||||
#### Restore drop semantics for all drivers
|
||||
|
||||
* The `release()` method is now retired everywhere
|
||||
* Just dropping a driver will make it stop functioning
|
||||
* Just dropping a driver will make it stop functioning
|
||||
* If peripherals need to be reused after the driver is dropped, this is achieved by passing the peripherals to the driver constructor via `&mut` references, e.g. `I2cMasterDriver::new(&mut peripherals.i2c1, &mut peripherals.pins.gpio10, &mut peripherals.pins.gpio11, &mut peripherals.pins.gpio12)`
|
||||
|
||||
### Simpler driver types
|
||||
|
||||
* All peripheral generics are removed from all drivers' types; e.g., the I2C master driver now has the following type signature: `I2cMasterDriver<'d>`
|
||||
* All peripheral generics are removed from all drivers' types; e.g., the I2C master driver now has the following type signature: `I2cMasterDriver<'d>`
|
||||
* The lifetime - `'d` from above designates the lifetime of the peripheral (e.g. `I2c`) that is used by the driver
|
||||
* In the most common case where the peripheral is just moved into the driver (and no longer accessible when the driver is dropped), `'d` = `'static`, or in other words, the type signature of the driver becomes `I2cMasterDriver<'static>` and can even be type aliased by the user as in `pub type SimpleI2cMasterDriver = I2cMasterDriver<'static>;`
|
||||
* When the peripherals are passed to the driver using `&mut` references, `'d` designates the lifetime of the `&mut` reference
|
||||
@ -289,13 +290,13 @@ methods are actually safe to call from an ISR routine. Those which are unsafe wi
|
||||
|
||||
In addition to implementing `embedded-hal` crates, `esp-idf-hal` integrates with the wider Rust embedded ecosystem by providing out of the box critical section implementation for the `critical-section` crate.
|
||||
|
||||
To enable this support, you need to compile the crate with the `critical-section` feature enabled.
|
||||
To enable this support, you need to compile the crate with the `critical-section` feature enabled.
|
||||
|
||||
Note that the provided critical section implementation is based on `esp_idf_hal::task::CriticalSection`, which itself is based on a recursive FreeRtos mutex.
|
||||
This means that you can `enter()` the critical section for long periods of time, and your code can still be preempted by ISR routines or high priority FreeRtos tasks (threads), thus you should not worry about slowing down the whole RTOS reaction times by using a critical section.
|
||||
This also means however, that this critical section (and its native `esp_idf_hal::task::CriticalSection` equivalent) CANNOT be used from an ISR context.
|
||||
|
||||
If you need a critical section with a warranty that your code will not be interrupted by an ISR or higher priority tasks (i.e. working accross ISRs and tasks), you should be using
|
||||
If you need a critical section with a warranty that your code will not be interrupted by an ISR or higher priority tasks (i.e. working accross ISRs and tasks), you should be using
|
||||
`esp_idf_hal::interrupt::IsrCriticalSection` instance, or the `esp_idf_hal::interrupt::free` method. Keep in mind that you should stay in this type of critical section for a very short period of time, because it **disables all interrupts**.
|
||||
|
||||
### Support for the `embassy-sync` crate
|
||||
@ -304,7 +305,7 @@ The HAL provides two mutex implementations that implement the `RawMutex` trait f
|
||||
* `EspRawMutex` - this implementation uses a FreeRtos mutex and behaves similarly to `esp_idf_hal::task::CriticalSection`
|
||||
* `IsrRawMutex` - this implementation works by disabling all interrupts and thus behaves similarly to `esp_idf_hal::interrupt::IsrCriticalSection`
|
||||
|
||||
To enable this support, you need to compile the crate with the `embassy-sync` feature enabled.
|
||||
To enable this support, you need to compile the crate with the `embassy-sync` feature enabled.
|
||||
|
||||
While `embassy-sync` itself can use - via its `CriticalSectionRawMutex` mutex bridge - whatever a HAL is providing as a critical section to the `critical-section` crate, the above two implementations provide further benefits:
|
||||
* `EspRawMutex` is almost the same as the `embassy-sync` native `CriticalSectionRawMutex` with the one major difference that ALL `CriticalSectionRawMutex` instances in fact share a **single** RTOS mutex underneath. This is a limitation which is coming from the `critical-section` crate itself. In contrast, each `EspRawMutex` instance has its own separate RTOS mutex
|
||||
@ -315,12 +316,12 @@ While `embassy-sync` itself can use - via its `CriticalSectionRawMutex` mutex br
|
||||
This is another HAL feature that integrates the ESP-RS ecosystem with the Rust embedded async ecosystem.
|
||||
|
||||
The [`edge-executor`](https://github.com/ivmarkov/edge-executor) crate is a simple local-only executor that is based on the popular `async-task` crate coming from the Smol async executor (which in turn powers the `async-std` executor).
|
||||
Without getting into too many details, `edge-executor` is useful in embedded cotexts because
|
||||
* It is `no_std` compatible (but requires an allocator, unlike [`embassy-executor`](https://github.com/embassy-rs/embassy), so the latter might be a better fit for bare-metal use cases where ESP IDF is not utilized)
|
||||
Without getting into too many details, `edge-executor` is useful in embedded cotexts because
|
||||
* It is `no_std` compatible (but requires an allocator, unlike [`embassy-executor`](https://github.com/embassy-rs/embassy), so the latter might be a better fit for bare-metal use cases where ESP IDF is not utilized)
|
||||
* Has a small footprint
|
||||
* Is ISR-friendly in that it can operate from an ISR context - or - which would be the natural setup when used on top of a RTOS like ESP IDF's FreeRtos - can be **awoken** directly from an ISR routine, this having a minimal latency
|
||||
|
||||
To enable this support, you need to compile the crate with the `edge-executor` feature enabled.
|
||||
To enable this support, you need to compile the crate with the `edge-executor` feature enabled.
|
||||
|
||||
The support for `edge-executor` in `esp-idf-hal` is in terms of providing an ISR-friendly `Monitor` trait implementation for `edge-executor` - `FreeRtosMonitor` - that can be awoken directly from an ISR, and is based on the FreeRtos task notification mechanism which is exposed in the `esp_idf_hal::task` crate.
|
||||
|
||||
@ -337,9 +338,9 @@ This is now addressed in that the `esp-idf-hal` crate models two new peripherals
|
||||
### SPI driver rework
|
||||
|
||||
The SPI driver is now split into two structures
|
||||
* `SpiDriver` - represents an initialized SPI bus and manages access to the underlying SPI hardware
|
||||
* `SpiDriver` - represents an initialized SPI bus and manages access to the underlying SPI hardware
|
||||
* `SpiDeviceDriver` (new) - an abstraction for rach device connected to the SPI bus
|
||||
|
||||
|
||||
The above split allows for the creation of more than one device per SPI bus. (Up to 6 for the esp32c* variants and 3 for all others).
|
||||
When creating an `SpiDeviceDriver` instance, user is required to provide a `Borrow` to the `SpiDriver` instance (as in `SpiDriver`, `&SpiDriver`, `&mut SpiDriver`, `Rc(SpiDriver)` or `Arc(SpiDriver)`), so that the SPI bus stays initialized throughout the liftime of all devices.
|
||||
|
||||
|
@ -33,7 +33,7 @@ embassy-sync = [] # For now, the dependecy on the `embassy-sync` crate is non-op
|
||||
adc-oneshot-legacy = []
|
||||
# Similar to adc-oneshot-legacy
|
||||
# - When enabled (default), the code for the legacy RMT TX/RX driver will be compiled.
|
||||
# - When disabled the code for the new onewire RMT driver will be compiled.
|
||||
# - When disabled the code for the new onewire RMT driver will be compiled.
|
||||
rmt-legacy = []
|
||||
# Propagated esp-idf-sys features
|
||||
native = ["esp-idf-sys/native"]
|
||||
@ -55,7 +55,6 @@ embedded-io-async = "0.6"
|
||||
esp-idf-sys = { version = "0.36", default-features = false }
|
||||
critical-section = { version = "1.1.1", optional = true, features = ["restore-state-none"] }
|
||||
heapless = "0.8"
|
||||
num_enum = { version = "0.7", default-features = false }
|
||||
enumset = { version = "1.1.4", default-features = false }
|
||||
log = { version = "0.4", default-features = false }
|
||||
atomic-waker = { version = "1.1.1", default-features = false }
|
||||
|
58
src/can.rs
58
src/can.rs
@ -41,8 +41,6 @@ use enumset::{EnumSet, EnumSetType};
|
||||
|
||||
use esp_idf_sys::*;
|
||||
|
||||
use num_enum::TryFromPrimitive;
|
||||
|
||||
use crate::cpu::Core;
|
||||
use crate::delay::{self, BLOCK, NON_BLOCK};
|
||||
use crate::interrupt::InterruptType;
|
||||
@ -360,28 +358,46 @@ pub mod config {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumSetType, TryFromPrimitive)]
|
||||
#[derive(Debug, EnumSetType)]
|
||||
#[enumset(repr = "u32")]
|
||||
#[repr(u32)]
|
||||
pub enum Alert {
|
||||
TransmitIdle = 1,
|
||||
Success = 2,
|
||||
Received = 3,
|
||||
BelowErrorWarning = 4,
|
||||
ActiveError = 5,
|
||||
RecoveryInProgress = 6,
|
||||
BusRecovered = 7,
|
||||
ArbLost = 8,
|
||||
AboveErrorWarning = 9,
|
||||
BusError = 10,
|
||||
TransmitFailed = 11,
|
||||
ReceiveQueueFull = 12,
|
||||
ErrorPass = 13,
|
||||
BusOffline = 14,
|
||||
ReceiveFifoOverflow = 15,
|
||||
TransmitRetried = 16,
|
||||
PeripheralReset = 17,
|
||||
AlertAndLog = 18,
|
||||
/// No more messages to transmit
|
||||
TransmitIdle = 0,
|
||||
/// The previous transmission was successful
|
||||
Success = 1,
|
||||
/// A frame has been received and added to the RX queue
|
||||
Received = 2,
|
||||
/// Both error counters have dropped below error warning limit
|
||||
BelowErrorWarning = 3,
|
||||
/// TWAI controller has become error active
|
||||
ActiveError = 4,
|
||||
/// TWAI controller is undergoing bus recovery
|
||||
RecoveryInProgress = 5,
|
||||
/// TWAI controller has successfully completed bus recovery
|
||||
BusRecovered = 6,
|
||||
/// The previous transmission lost arbitration
|
||||
ArbLost = 7,
|
||||
/// One of the error counters have exceeded the error warning limit
|
||||
AboveErrorWarning = 8,
|
||||
/// A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus
|
||||
BusError = 9,
|
||||
/// The previous transmission has failed (for single shot transmission)
|
||||
TransmitFailed = 10,
|
||||
/// The RX queue is full causing a frame to be lost
|
||||
ReceiveQueueFull = 11,
|
||||
/// TWAI controller has become error passive
|
||||
ErrorPass = 12,
|
||||
/// Bus-off condition occurred. TWAI controller can no longer influence bus
|
||||
BusOffline = 13,
|
||||
/// An RX FIFO overrun has occurred
|
||||
ReceiveFifoOverflow = 14,
|
||||
/// An message transmission was cancelled and retried due to an errata workaround
|
||||
TransmitRetried = 15,
|
||||
/// The TWAI controller was reset
|
||||
PeripheralReset = 16,
|
||||
/// In addition to alerting also Logs the event
|
||||
AlertAndLog = 17,
|
||||
}
|
||||
|
||||
/// CAN abstraction
|
||||
|
Loading…
x
Reference in New Issue
Block a user