@@ -272,7 +272,8 @@ pub enum BaudrateTolerance {
272
272
/// Accept the closest achievable baud rate without restriction.
273
273
#[ default]
274
274
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.
276
277
Exact ,
277
278
/// Allow a certain percentage of deviation.
278
279
ErrorPercent ( u8 ) ,
@@ -288,6 +289,7 @@ pub struct Config {
288
289
baudrate : u32 ,
289
290
/// Determines how close to the desired baud rate value the driver should
290
291
/// set the baud rate.
292
+ #[ builder_lite( skip_setter) ]
291
293
baudrate_tolerance : BaudrateTolerance ,
292
294
/// Number of data bits in each frame (5, 6, 7, or 8 bits).
293
295
data_bits : DataBits ,
@@ -346,6 +348,19 @@ impl Default for RxConfig {
346
348
}
347
349
348
350
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
+ }
349
364
/// Calculates the total symbol length in bits based on the configured
350
365
/// data bits, parity, and stop bits.
351
366
fn symbol_length ( & self ) -> u8 {
@@ -1214,7 +1229,10 @@ where
1214
1229
/// # Errors.
1215
1230
/// Errors will be returned in the cases described in
1216
1231
/// [`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.
1218
1236
pub fn apply_config ( & mut self , config : & Config ) -> Result < ( ) , ConfigError > {
1219
1237
self . rx . apply_config ( config) ?;
1220
1238
self . tx . apply_config ( config) ?;
@@ -2459,8 +2477,15 @@ impl Info {
2459
2477
let actual_baud = self . get_baudrate ( clk) ;
2460
2478
2461
2479
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
+ }
2464
2489
}
2465
2490
BaudrateTolerance :: ErrorPercent ( percent) => {
2466
2491
let deviation = ( ( config. baudrate as i64 - actual_baud as i64 ) . unsigned_abs ( )
@@ -2544,8 +2569,15 @@ impl Info {
2544
2569
let actual_baud = self . get_baudrate ( clk) ;
2545
2570
2546
2571
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
+ }
2549
2581
}
2550
2582
BaudrateTolerance :: ErrorPercent ( percent) => {
2551
2583
let deviation = ( ( config. baudrate as i64 - actual_baud as i64 ) . unsigned_abs ( )
@@ -2583,8 +2615,15 @@ impl Info {
2583
2615
let actual_baud = self . get_baudrate ( clk) ;
2584
2616
2585
2617
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
+ }
2588
2627
}
2589
2628
BaudrateTolerance :: ErrorPercent ( percent) => {
2590
2629
let deviation = ( ( config. baudrate as i64 - actual_baud as i64 ) . unsigned_abs ( )
0 commit comments