Skip to content

Commit 46bd259

Browse files
committed
rework Exact setting
1 parent 8fb6c69 commit 46bd259

File tree

2 files changed

+55
-12
lines changed

2 files changed

+55
-12
lines changed

esp-hal/src/spi/master.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -635,8 +635,8 @@ impl Config {
635635
}
636636

637637
fn validate(&self) -> Result<(), ConfigError> {
638-
// Max supported frequency is 80Mhz
639-
if self.frequency > HertzU32::MHz(80) {
638+
// Maximum supported frequency is 80Mhz, minimum is about 70khz.
639+
if self.frequency < HertzU32::kHz(70) || self.frequency > HertzU32::MHz(80) {
640640
return Err(ConfigError::UnsupportedFrequency);
641641
}
642642
Ok(())
@@ -1056,8 +1056,12 @@ where
10561056
/// Change the bus configuration.
10571057
///
10581058
/// # Errors.
1059-
/// If frequency passed in config exceeds 80Mhz, a corresponding
1060-
/// [`ConfigError`] variant will be returned.
1059+
/// If frequency passed in config exceeds 80Mhz or is below 70kHz, a
1060+
/// corresponding [`ConfigError`] variant will be returned. If the user
1061+
/// has specified in the configuration that they want frequency to
1062+
/// correspond exactly or with some percentage of deviation to the
1063+
/// desired value, and the driver cannot reach this speed - an error
1064+
/// will also be returned.
10611065
pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
10621066
self.driver().apply_config(config)
10631067
}

esp-hal/src/uart.rs

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ pub enum BaudrateTolerance {
272272
/// Accept the closest achievable baud rate without restriction.
273273
#[default]
274274
Closest,
275-
/// Require an exact match, otherwise return an error.
275+
/// In this setting, the deviation of only 1% from the desired baud value is
276+
/// tolerated.
276277
Exact,
277278
/// Allow a certain percentage of deviation.
278279
ErrorPercent(u8),
@@ -288,6 +289,7 @@ pub struct Config {
288289
baudrate: u32,
289290
/// Determines how close to the desired baud rate value the driver should
290291
/// set the baud rate.
292+
#[builder_lite(skip_setter)]
291293
baudrate_tolerance: BaudrateTolerance,
292294
/// Number of data bits in each frame (5, 6, 7, or 8 bits).
293295
data_bits: DataBits,
@@ -346,6 +348,19 @@ impl Default for RxConfig {
346348
}
347349

348350
impl Config {
351+
/// Set the baudrate tolerance of the UART configuration.
352+
pub fn with_baudrate_tolerance(mut self, tolerance: BaudrateTolerance) -> Self {
353+
self.baudrate_tolerance = match tolerance {
354+
BaudrateTolerance::Exact => BaudrateTolerance::Exact,
355+
BaudrateTolerance::Closest => BaudrateTolerance::Closest,
356+
BaudrateTolerance::ErrorPercent(percentage) => {
357+
assert!(percentage > 0 && percentage <= 100);
358+
BaudrateTolerance::ErrorPercent(percentage)
359+
}
360+
};
361+
362+
self
363+
}
349364
/// Calculates the total symbol length in bits based on the configured
350365
/// data bits, parity, and stop bits.
351366
fn symbol_length(&self) -> u8 {
@@ -1214,7 +1229,10 @@ where
12141229
/// # Errors.
12151230
/// Errors will be returned in the cases described in
12161231
/// [`UartRx::apply_config`] and if baud rate passed in config exceeds
1217-
/// 5MBaud or is equal to zero.
1232+
/// 5MBaud or is equal to zero. If the user has specified in the
1233+
/// configuration that they want baudrate to correspond exactly or with some
1234+
/// percentage of deviation to the desired value, and the driver cannot
1235+
/// reach this speed - an error will also be returned.
12181236
pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
12191237
self.rx.apply_config(config)?;
12201238
self.tx.apply_config(config)?;
@@ -2459,8 +2477,15 @@ impl Info {
24592477
let actual_baud = self.get_baudrate(clk);
24602478

24612479
match config.baudrate_tolerance {
2462-
BaudrateTolerance::Exact if actual_baud != config.baudrate => {
2463-
return Err(ConfigError::UnachievableBaudrate)
2480+
BaudrateTolerance::Exact => {
2481+
let deviation = ((config.baudrate as i64 - actual_baud as i64).unsigned_abs()
2482+
* 100)
2483+
/ actual_baud as u64;
2484+
// We tolerate deviation of 1% from the desired baud value, as it never will be
2485+
// exactly the same
2486+
if deviation > 1 as u64 {
2487+
return Err(ConfigError::UnachievableBaudrate);
2488+
}
24642489
}
24652490
BaudrateTolerance::ErrorPercent(percent) => {
24662491
let deviation = ((config.baudrate as i64 - actual_baud as i64).unsigned_abs()
@@ -2544,8 +2569,15 @@ impl Info {
25442569
let actual_baud = self.get_baudrate(clk);
25452570

25462571
match config.baudrate_tolerance {
2547-
BaudrateTolerance::Exact if actual_baud != config.baudrate => {
2548-
return Err(ConfigError::UnachievableBaudrate)
2572+
BaudrateTolerance::Exact => {
2573+
let deviation = ((config.baudrate as i64 - actual_baud as i64).unsigned_abs()
2574+
* 100)
2575+
/ actual_baud as u64;
2576+
// We tolerate deviation of 1% from the desired baud value, as it never will be
2577+
// exactly the same
2578+
if deviation > 1 as u64 {
2579+
return Err(ConfigError::UnachievableBaudrate);
2580+
}
25492581
}
25502582
BaudrateTolerance::ErrorPercent(percent) => {
25512583
let deviation = ((config.baudrate as i64 - actual_baud as i64).unsigned_abs()
@@ -2583,8 +2615,15 @@ impl Info {
25832615
let actual_baud = self.get_baudrate(clk);
25842616

25852617
match config.baudrate_tolerance {
2586-
BaudrateTolerance::Exact if actual_baud != config.baudrate => {
2587-
return Err(ConfigError::UnachievableBaudrate)
2618+
BaudrateTolerance::Exact => {
2619+
let deviation = ((config.baudrate as i64 - actual_baud as i64).unsigned_abs()
2620+
* 100)
2621+
/ actual_baud as u64;
2622+
// We tolerate deviation of 1% from the desired baud value, as it never will be
2623+
// exactly the same
2624+
if deviation > 1 as u64 {
2625+
return Err(ConfigError::UnachievableBaudrate);
2626+
}
25882627
}
25892628
BaudrateTolerance::ErrorPercent(percent) => {
25902629
let deviation = ((config.baudrate as i64 - actual_baud as i64).unsigned_abs()

0 commit comments

Comments
 (0)