mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-28 04:40:52 +00:00
esp32: Block ADC2
usage simultaneously with radio
(#3876)
* block `ADC2` usage simultaneously with radio (esp32) * implement `Drop` for `ADC2` (esp32) fmt format * multiple fixes * make functions internal, lint package * Cleanup * use `fetch_or` instead * take it easy
This commit is contained in:
parent
4eb4c89944
commit
e1917abf9f
@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- PSRAM on ESP32-S2 (#3811)
|
||||
- WDT now allows configuring longer timeouts (#3816)
|
||||
- `ADC2` now cannot be used simultaneously with `radio` on ESP32 (#3876)
|
||||
|
||||
### Removed
|
||||
|
||||
|
@ -1,10 +1,43 @@
|
||||
use core::marker::PhantomData;
|
||||
use core::{
|
||||
marker::PhantomData,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
|
||||
use super::{AdcConfig, Attenuation};
|
||||
use crate::peripherals::{ADC1, ADC2, RTC_IO, SENS};
|
||||
use crate::{
|
||||
peripherals::{ADC1, ADC2, RTC_IO, SENS},
|
||||
private::{self},
|
||||
};
|
||||
|
||||
pub(super) const NUM_ATTENS: usize = 10;
|
||||
|
||||
// ADC2 cannot be used with `radio` functionality on `esp32`, this global helps us to track it's
|
||||
// state to prevent unexpected behaviour
|
||||
static ADC2_IN_USE: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
/// ADC Error
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// `ADC2` is used together with `radio`.
|
||||
Adc2InUse,
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
/// Tries to "claim" `ADC2` peripheral and set its status
|
||||
pub fn try_claim_adc2(_: private::Internal) -> Result<(), Error> {
|
||||
if ADC2_IN_USE.fetch_or(true, Ordering::Relaxed) {
|
||||
Err(Error::Adc2InUse)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
/// Resets `ADC2` usage status to `Unused`
|
||||
pub fn release_adc2(_: private::Internal) {
|
||||
ADC2_IN_USE.store(false, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// The sampling/readout resolution of the ADC.
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
@ -44,6 +77,8 @@ pub trait RegisterAccess {
|
||||
fn read_done_sar() -> bool;
|
||||
|
||||
fn read_data_sar() -> u16;
|
||||
|
||||
fn instance_number() -> u8;
|
||||
}
|
||||
|
||||
impl RegisterAccess for ADC1<'_> {
|
||||
@ -119,6 +154,10 @@ impl RegisterAccess for ADC1<'_> {
|
||||
.meas1_data_sar()
|
||||
.bits()
|
||||
}
|
||||
|
||||
fn instance_number() -> u8 {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
impl RegisterAccess for ADC2<'_> {
|
||||
@ -194,6 +233,10 @@ impl RegisterAccess for ADC2<'_> {
|
||||
.meas2_data_sar()
|
||||
.bits()
|
||||
}
|
||||
|
||||
fn instance_number() -> u8 {
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
/// Analog-to-Digital Converter peripheral driver.
|
||||
@ -210,7 +253,18 @@ where
|
||||
{
|
||||
/// Configure a given ADC instance using the provided configuration, and
|
||||
/// initialize the ADC for use
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// `ADC2` cannot be used simultaneously with `radio` functionalities, otherwise this function
|
||||
/// will panic.
|
||||
pub fn new(adc_instance: ADCI, config: AdcConfig<ADCI>) -> Self {
|
||||
if ADCI::instance_number() == 2 && try_claim_adc2(private::Internal).is_err() {
|
||||
panic!(
|
||||
"ADC2 is already in use by Radio. On ESP32, ADC2 cannot be used simultaneously with Wi-Fi or Bluetooth."
|
||||
);
|
||||
}
|
||||
|
||||
let sensors = SENS::regs();
|
||||
|
||||
// Set reading and sampling resolution
|
||||
@ -372,3 +426,9 @@ mod adc_implementation {
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ADC2<'_> {
|
||||
fn drop(&mut self) {
|
||||
release_adc2(private::Internal);
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Fixed a BLE panic caused by unimplemented functions (#3762)
|
||||
- Fixed the BLE stack crashing in certain cases (#3854)
|
||||
|
||||
- `ADC2` now cannot be used simultaneously with `radio` on ESP32 (#3876)
|
||||
|
||||
### Removed
|
||||
|
||||
|
@ -114,6 +114,8 @@ use common_adapter::chip_specific::phy_mem_init;
|
||||
use esp_config::*;
|
||||
use esp_hal::{self as hal};
|
||||
use esp_radio_preempt_driver as preempt;
|
||||
#[cfg(esp32)]
|
||||
use hal::analog::adc::{release_adc2, try_claim_adc2};
|
||||
use hal::{
|
||||
clock::{Clocks, init_radio_clocks},
|
||||
time::Rate,
|
||||
@ -217,6 +219,10 @@ impl Drop for Controller<'_> {
|
||||
|
||||
// This shuts down the task switcher and timer tick interrupt.
|
||||
preempt::disable();
|
||||
|
||||
#[cfg(esp32)]
|
||||
// Allow using `ADC2` again
|
||||
release_adc2(unsafe { esp_hal::Internal::conjure() });
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,6 +230,11 @@ impl Drop for Controller<'_> {
|
||||
///
|
||||
/// Make sure to **not** call this function while interrupts are disabled.
|
||||
pub fn init<'d>() -> Result<Controller<'d>, InitializationError> {
|
||||
#[cfg(esp32)]
|
||||
if try_claim_adc2(unsafe { hal::Internal::conjure() }).is_err() {
|
||||
return Err(InitializationError::Adc2IsUsed);
|
||||
}
|
||||
|
||||
if crate::is_interrupts_disabled() {
|
||||
return Err(InitializationError::InterruptsDisabled);
|
||||
}
|
||||
@ -294,6 +305,9 @@ pub enum InitializationError {
|
||||
InterruptsDisabled,
|
||||
/// The scheduler is not initialized.
|
||||
SchedulerNotInitialized,
|
||||
#[cfg(esp32)]
|
||||
// ADC2 cannot be used with `radio` functionality on `esp32`.
|
||||
Adc2IsUsed,
|
||||
}
|
||||
|
||||
#[cfg(feature = "wifi")]
|
||||
|
Loading…
x
Reference in New Issue
Block a user