diff options
| -rw-r--r-- | embassy-stm32/gen.py | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/rtc.rs | 242 |
2 files changed, 13 insertions, 233 deletions
diff --git a/embassy-stm32/gen.py b/embassy-stm32/gen.py index fc1986721..ee1b2677f 100644 --- a/embassy-stm32/gen.py +++ b/embassy-stm32/gen.py | |||
| @@ -186,6 +186,10 @@ for chip in chips.values(): | |||
| 186 | if func := funcs.get(f'{name}_D7'): | 186 | if func := funcs.get(f'{name}_D7'): |
| 187 | f.write(f'impl_sdmmc_pin!({name}, D7Pin, {pin}, {func});') | 187 | f.write(f'impl_sdmmc_pin!({name}, D7Pin, {pin}, {func});') |
| 188 | 188 | ||
| 189 | if block_name == 'TimGp16': | ||
| 190 | if re.match('TIM[2345]$', name): | ||
| 191 | f.write(f'impl_timer!({name});') | ||
| 192 | |||
| 189 | if block_mod == 'exti': | 193 | if block_mod == 'exti': |
| 190 | for irq in chip['interrupts']: | 194 | for irq in chip['interrupts']: |
| 191 | if re.match('EXTI', irq): | 195 | if re.match('EXTI', irq): |
diff --git a/embassy-stm32/src/rtc.rs b/embassy-stm32/src/rtc.rs index 1ccac0e2d..d7987b1b3 100644 --- a/embassy-stm32/src/rtc.rs +++ b/embassy-stm32/src/rtc.rs | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 1 | use core::cell::Cell; | 3 | use core::cell::Cell; |
| 2 | use core::convert::TryInto; | 4 | use core::convert::TryInto; |
| 3 | use core::sync::atomic::{compiler_fence, AtomicU32, Ordering}; | 5 | use core::sync::atomic::{compiler_fence, AtomicU32, Ordering}; |
| 4 | 6 | ||
| 5 | use embassy::interrupt::InterruptExt; | 7 | use embassy::interrupt::InterruptExt; |
| 6 | use embassy::time::{Clock, TICKS_PER_SECOND}; | 8 | use embassy::time::{Clock, TICKS_PER_SECOND}; |
| 7 | use embassy::util::AtomicWaker; | ||
| 8 | 9 | ||
| 9 | use crate::interrupt::{CriticalSection, Interrupt, Mutex}; | 10 | use crate::interrupt::{CriticalSection, Interrupt, Mutex}; |
| 10 | use crate::pac::timer::TimGp16; | 11 | use crate::pac::timer::TimGp16; |
| @@ -339,247 +340,22 @@ pub(crate) mod sealed { | |||
| 339 | type Interrupt: Interrupt; | 340 | type Interrupt: Interrupt; |
| 340 | 341 | ||
| 341 | fn inner() -> TimerInner; | 342 | fn inner() -> TimerInner; |
| 342 | fn state() -> &'static AtomicWaker; | ||
| 343 | } | 343 | } |
| 344 | } | 344 | } |
| 345 | 345 | ||
| 346 | pub trait Instance: sealed::Instance + Sized + 'static {} | 346 | pub trait Instance: sealed::Instance + Sized + 'static {} |
| 347 | 347 | ||
| 348 | /* | ||
| 349 | |||
| 350 | #[allow(unused_macros)] | ||
| 351 | macro_rules! impl_timer { | 348 | macro_rules! impl_timer { |
| 352 | ($module:ident: ($TYPE:ident, $INT:ident, $apbenr:ident, $enrbit:expr, $apbrstr:ident, $rstrbit:expr, $ppre:ident, $pclk: ident), 3) => { | 349 | ($inst:ident) => { |
| 353 | mod $module { | 350 | impl crate::rtc::sealed::Instance for peripherals::$inst { |
| 354 | use super::*; | 351 | type Interrupt = interrupt::$inst; |
| 355 | |||
| 356 | impl sealed::Instance for $TYPE {} | ||
| 357 | |||
| 358 | impl Instance for $TYPE { | ||
| 359 | type Interrupt = interrupt::$INT; | ||
| 360 | |||
| 361 | fn set_compare(&self, n: usize, value: u16) { | ||
| 362 | // NOTE(unsafe) these registers accept all the range of u16 values | ||
| 363 | match n { | ||
| 364 | 0 => self.ccr1.write(|w| unsafe { w.bits(value.into()) }), | ||
| 365 | 1 => self.ccr2.write(|w| unsafe { w.bits(value.into()) }), | ||
| 366 | 2 => self.ccr3.write(|w| unsafe { w.bits(value.into()) }), | ||
| 367 | 3 => self.ccr4.write(|w| unsafe { w.bits(value.into()) }), | ||
| 368 | _ => {} | ||
| 369 | } | ||
| 370 | } | ||
| 371 | |||
| 372 | fn set_compare_interrupt(&self, n: usize, enable: bool) { | ||
| 373 | if n > 3 { | ||
| 374 | return; | ||
| 375 | } | ||
| 376 | let bit = n as u8 + 1; | ||
| 377 | unsafe { | ||
| 378 | if enable { | ||
| 379 | bb::set(&self.dier, bit); | ||
| 380 | } else { | ||
| 381 | bb::clear(&self.dier, bit); | ||
| 382 | } | ||
| 383 | } | ||
| 384 | } | ||
| 385 | |||
| 386 | fn compare_interrupt_status(&self, n: usize) -> bool { | ||
| 387 | let status = self.sr.read(); | ||
| 388 | match n { | ||
| 389 | 0 => status.cc1if().bit_is_set(), | ||
| 390 | 1 => status.cc2if().bit_is_set(), | ||
| 391 | 2 => status.cc3if().bit_is_set(), | ||
| 392 | 3 => status.cc4if().bit_is_set(), | ||
| 393 | _ => false, | ||
| 394 | } | ||
| 395 | } | ||
| 396 | |||
| 397 | fn compare_clear_flag(&self, n: usize) { | ||
| 398 | if n > 3 { | ||
| 399 | return; | ||
| 400 | } | ||
| 401 | let bit = n as u8 + 1; | ||
| 402 | unsafe { | ||
| 403 | bb::clear(&self.sr, bit); | ||
| 404 | } | ||
| 405 | } | ||
| 406 | |||
| 407 | fn overflow_interrupt_status(&self) -> bool { | ||
| 408 | self.sr.read().uif().bit_is_set() | ||
| 409 | } | ||
| 410 | |||
| 411 | fn overflow_clear_flag(&self) { | ||
| 412 | unsafe { | ||
| 413 | bb::clear(&self.sr, 0); | ||
| 414 | } | ||
| 415 | } | ||
| 416 | |||
| 417 | fn set_psc_arr(&self, psc: u16, arr: u16) { | ||
| 418 | // NOTE(unsafe) All u16 values are valid | ||
| 419 | self.psc.write(|w| unsafe { w.bits(psc.into()) }); | ||
| 420 | self.arr.write(|w| unsafe { w.bits(arr.into()) }); | ||
| 421 | 352 | ||
| 422 | unsafe { | 353 | fn inner() -> crate::rtc::TimerInner { |
| 423 | // Set URS, generate update, clear URS | 354 | const INNER: crate::rtc::TimerInner = crate::rtc::TimerInner($inst); |
| 424 | bb::set(&self.cr1, 2); | 355 | INNER |
| 425 | self.egr.write(|w| w.ug().set_bit()); | ||
| 426 | bb::clear(&self.cr1, 2); | ||
| 427 | } | ||
| 428 | } | ||
| 429 | |||
| 430 | fn stop_and_reset(&self) { | ||
| 431 | unsafe { | ||
| 432 | bb::clear(&self.cr1, 0); | ||
| 433 | } | ||
| 434 | self.cnt.reset(); | ||
| 435 | } | ||
| 436 | |||
| 437 | fn start(&self) { | ||
| 438 | unsafe { bb::set(&self.cr1, 0) } | ||
| 439 | } | ||
| 440 | |||
| 441 | fn counter(&self) -> u16 { | ||
| 442 | self.cnt.read().bits() as u16 | ||
| 443 | } | ||
| 444 | |||
| 445 | fn ppre(clocks: &Clocks) -> u8 { | ||
| 446 | clocks.$ppre() | ||
| 447 | } | ||
| 448 | |||
| 449 | fn pclk(clocks: &Clocks) -> u32 { | ||
| 450 | clocks.$pclk().0 | ||
| 451 | } | ||
| 452 | } | 356 | } |
| 453 | } | 357 | } |
| 454 | }; | ||
| 455 | |||
| 456 | ($module:ident: ($TYPE:ident, $INT:ident, $apbenr:ident, $enrbit:expr, $apbrstr:ident, $rstrbit:expr, $ppre:ident, $pclk: ident), 1) => { | ||
| 457 | mod $module { | ||
| 458 | use super::*; | ||
| 459 | use crate::hal::pac::{$TYPE, RCC}; | ||
| 460 | |||
| 461 | impl sealed::Sealed for $TYPE {} | ||
| 462 | |||
| 463 | impl Instance for $TYPE { | ||
| 464 | type Interrupt = interrupt::$INT; | ||
| 465 | const REAL_ALARM_COUNT: usize = 1; | ||
| 466 | |||
| 467 | fn enable_clock(&self) { | ||
| 468 | // NOTE(unsafe) It will only be used for atomic operations | ||
| 469 | unsafe { | ||
| 470 | let rcc = &*RCC::ptr(); | ||
| 471 | |||
| 472 | bb::set(&rcc.$apbenr, $enrbit); | ||
| 473 | bb::set(&rcc.$apbrstr, $rstrbit); | ||
| 474 | bb::clear(&rcc.$apbrstr, $rstrbit); | ||
| 475 | } | ||
| 476 | } | ||
| 477 | 358 | ||
| 478 | fn set_compare(&self, n: usize, value: u16) { | 359 | impl crate::rtc::Instance for peripherals::$inst {} |
| 479 | // NOTE(unsafe) these registers accept all the range of u16 values | ||
| 480 | match n { | ||
| 481 | 0 => self.ccr1.write(|w| unsafe { w.bits(value.into()) }), | ||
| 482 | 1 => self.ccr2.write(|w| unsafe { w.bits(value.into()) }), | ||
| 483 | _ => {} | ||
| 484 | } | ||
| 485 | } | ||
| 486 | |||
| 487 | fn set_compare_interrupt(&self, n: usize, enable: bool) { | ||
| 488 | if n > 1 { | ||
| 489 | return; | ||
| 490 | } | ||
| 491 | let bit = n as u8 + 1; | ||
| 492 | unsafe { | ||
| 493 | if enable { | ||
| 494 | bb::set(&self.dier, bit); | ||
| 495 | } else { | ||
| 496 | bb::clear(&self.dier, bit); | ||
| 497 | } | ||
| 498 | } | ||
| 499 | } | ||
| 500 | |||
| 501 | fn compare_interrupt_status(&self, n: usize) -> bool { | ||
| 502 | let status = self.sr.read(); | ||
| 503 | match n { | ||
| 504 | 0 => status.cc1if().bit_is_set(), | ||
| 505 | 1 => status.cc2if().bit_is_set(), | ||
| 506 | _ => false, | ||
| 507 | } | ||
| 508 | } | ||
| 509 | |||
| 510 | fn compare_clear_flag(&self, n: usize) { | ||
| 511 | if n > 1 { | ||
| 512 | return; | ||
| 513 | } | ||
| 514 | let bit = n as u8 + 1; | ||
| 515 | unsafe { | ||
| 516 | bb::clear(&self.sr, bit); | ||
| 517 | } | ||
| 518 | } | ||
| 519 | |||
| 520 | fn overflow_interrupt_status(&self) -> bool { | ||
| 521 | self.sr.read().uif().bit_is_set() | ||
| 522 | } | ||
| 523 | |||
| 524 | fn overflow_clear_flag(&self) { | ||
| 525 | unsafe { | ||
| 526 | bb::clear(&self.sr, 0); | ||
| 527 | } | ||
| 528 | } | ||
| 529 | |||
| 530 | fn set_psc_arr(&self, psc: u16, arr: u16) { | ||
| 531 | // NOTE(unsafe) All u16 values are valid | ||
| 532 | self.psc.write(|w| unsafe { w.bits(psc.into()) }); | ||
| 533 | self.arr.write(|w| unsafe { w.bits(arr.into()) }); | ||
| 534 | |||
| 535 | unsafe { | ||
| 536 | // Set URS, generate update, clear URS | ||
| 537 | bb::set(&self.cr1, 2); | ||
| 538 | self.egr.write(|w| w.ug().set_bit()); | ||
| 539 | bb::clear(&self.cr1, 2); | ||
| 540 | } | ||
| 541 | } | ||
| 542 | |||
| 543 | fn stop_and_reset(&self) { | ||
| 544 | unsafe { | ||
| 545 | bb::clear(&self.cr1, 0); | ||
| 546 | } | ||
| 547 | self.cnt.reset(); | ||
| 548 | } | ||
| 549 | |||
| 550 | fn start(&self) { | ||
| 551 | unsafe { bb::set(&self.cr1, 0) } | ||
| 552 | } | ||
| 553 | |||
| 554 | fn counter(&self) -> u16 { | ||
| 555 | self.cnt.read().bits() as u16 | ||
| 556 | } | ||
| 557 | |||
| 558 | fn ppre(clocks: &Clocks) -> u8 { | ||
| 559 | clocks.$ppre() | ||
| 560 | } | ||
| 561 | |||
| 562 | fn pclk(clocks: &Clocks) -> u32 { | ||
| 563 | clocks.$pclk().0 | ||
| 564 | } | ||
| 565 | } | ||
| 566 | } | ||
| 567 | }; | 360 | }; |
| 568 | } | 361 | } |
| 569 | */ | ||
| 570 | |||
| 571 | /* | ||
| 572 | impl_timer!(tim2: (TIM2, TIM2, apb1enr, 0, apb1rstr, 0, ppre1, pclk1), 3); | ||
| 573 | |||
| 574 | impl_timer!(tim3: (TIM3, TIM3, apb1enr, 1, apb1rstr, 1, ppre1, pclk1), 3); | ||
| 575 | |||
| 576 | |||
| 577 | impl_timer!(tim4: (TIM4, TIM4, apb1enr, 2, apb1rstr, 2, ppre1, pclk1), 3); | ||
| 578 | |||
| 579 | impl_timer!(tim5: (TIM5, TIM5, apb1enr, 3, apb1rstr, 3, ppre1, pclk1), 3); | ||
| 580 | |||
| 581 | impl_timer!(tim9: (TIM9, TIM1_BRK_TIM9, apb2enr, 16, apb2rstr, 16, ppre2, pclk2), 1); | ||
| 582 | |||
| 583 | #[cfg(not(any(feature = "stm32f401", feature = "stm32f410", feature = "stm32f411")))] | ||
| 584 | impl_timer!(tim12: (TIM12, TIM8_BRK_TIM12, apb1enr, 6, apb1rstr, 6, ppre1, pclk1), 1); | ||
| 585 | */ | ||
