1use kernel::debug;
22use kernel::hil;
23use kernel::utilities::cells::OptionalCell;
24use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
25use kernel::utilities::registers::{
26 register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly,
27};
28use kernel::utilities::StaticRef;
29use kernel::ErrorCode;
30
31use crate::clocks;
32use crate::gpio::RPGpio;
33
34register_bitfields![u32,
35 CSR [
36 EN OFFSET(0) NUMBITS(1) [],
38 PH_CORRECT OFFSET(1) NUMBITS(1) [],
40 A_INV OFFSET(2) NUMBITS(1) [],
42 B_INV OFFSET(3) NUMBITS(1) [],
44 DIVMOD OFFSET(4) NUMBITS(2) [
49 FREE_RUNNING = 0,
51 B_HIGH = 1,
53 B_RISING = 2,
55 B_FALLING = 3
57 ],
58 PH_RET OFFSET(6) NUMBITS(1) [],
61 PH_ADV OFFSET(7) NUMBITS(1) []
64 ],
65
66 DIV [
71 FRAC OFFSET(0) NUMBITS(4) [],
72 INT OFFSET(4) NUMBITS(8) []
73 ],
74
75 CTR [
77 CTR OFFSET(0) NUMBITS(16) []
78 ],
79
80 CC [
82 A OFFSET(0) NUMBITS(16) [],
83 B OFFSET(16) NUMBITS(16) []
84 ],
85
86 TOP [
92 TOP OFFSET(0) NUMBITS(16) []
93 ],
94
95 CH [
98 CH OFFSET(0) NUMBITS(8) [
99 CH0 = 1,
100 CH1 = 2,
101 CH2 = 4,
102 CH3 = 8,
103 CH4 = 16,
104 CH5 = 32,
105 CH6 = 64,
106 CH7 = 128
107 ]
108 ]
109];
110
111const NUMBER_CHANNELS: usize = 8;
112
113#[repr(C)]
114struct Channel {
115 csr: ReadWrite<u32, CSR::Register>,
117 div: ReadWrite<u32, DIV::Register>,
119 ctr: ReadWrite<u32, CTR::Register>,
121 cc: ReadWrite<u32, CC::Register>,
123 top: ReadWrite<u32, TOP::Register>,
125}
126
127register_structs! {
128 PwmRegisters {
129 (0x0000 => ch: [Channel; NUMBER_CHANNELS]),
131 (0x00A0 => en: ReadWrite<u32, CH::Register>),
136 (0x00A4 => intr: WriteOnly<u32, CH::Register>),
138 (0x00A8 => inte: ReadWrite<u32, CH::Register>),
140 (0x00AC => intf: ReadWrite<u32, CH::Register>),
142 (0x00B0 => ints: ReadOnly<u32, CH::Register>),
144 (0x00B4 => @END),
145 }
146}
147
148#[derive(Clone, Copy)]
149pub enum DivMode {
162 FreeRunning,
163 High,
164 Rising,
165 Falling,
166}
167
168#[derive(Clone, Copy, PartialEq, Debug)]
172pub enum ChannelNumber {
173 Ch0,
174 Ch1,
175 Ch2,
176 Ch3,
177 Ch4,
178 Ch5,
179 Ch6,
180 Ch7,
181}
182
183const CHANNEL_NUMBERS: [ChannelNumber; NUMBER_CHANNELS] = [
184 ChannelNumber::Ch0,
185 ChannelNumber::Ch1,
186 ChannelNumber::Ch2,
187 ChannelNumber::Ch3,
188 ChannelNumber::Ch4,
189 ChannelNumber::Ch5,
190 ChannelNumber::Ch6,
191 ChannelNumber::Ch7,
192];
193
194impl From<RPGpio> for ChannelNumber {
237 fn from(gpio: RPGpio) -> Self {
238 match gpio as u8 >> 1 & 0b111 {
239 0 => ChannelNumber::Ch0,
241 1 => ChannelNumber::Ch1,
242 2 => ChannelNumber::Ch2,
243 3 => ChannelNumber::Ch3,
244 4 => ChannelNumber::Ch4,
245 5 => ChannelNumber::Ch5,
246 6 => ChannelNumber::Ch6,
247 _ => ChannelNumber::Ch7,
248 }
249 }
250}
251
252#[derive(Clone, Copy, PartialEq, Debug)]
259pub enum ChannelPin {
260 A,
261 B,
262}
263
264impl From<RPGpio> for ChannelPin {
266 fn from(gpio: RPGpio) -> Self {
267 match gpio as u8 & 0b0000_0001 {
268 0 => ChannelPin::A,
270 _ => ChannelPin::B,
271 }
272 }
273}
274
275struct PwmChannelConfiguration {
279 en: bool,
280 ph_correct: bool,
281 a_inv: bool,
282 b_inv: bool,
283 divmode: DivMode,
284 int: u8,
285 frac: u8,
286 cc_a: u16,
287 cc_b: u16,
288 top: u16,
289}
290
291impl Default for PwmChannelConfiguration {
292 fn default() -> Self {
301 PwmChannelConfiguration {
302 en: false,
303 ph_correct: false,
304 a_inv: false,
305 b_inv: false,
306 divmode: DivMode::FreeRunning,
307 int: 1,
308 frac: 0,
309 cc_a: 0,
310 cc_b: 0,
311 top: u16::MAX,
312 }
313 }
314}
315
316const PWM_BASE: StaticRef<PwmRegisters> =
317 unsafe { StaticRef::new(0x40050000 as *const PwmRegisters) };
318
319pub struct Pwm<'a> {
321 registers: StaticRef<PwmRegisters>,
322 clocks: OptionalCell<&'a clocks::Clocks>,
323}
324
325impl<'a> Pwm<'a> {
326 pub fn new() -> Self {
334 let pwm = Self {
335 registers: PWM_BASE,
336 clocks: OptionalCell::empty(),
337 };
338 pwm.init();
339 pwm
340 }
341
342 fn set_enabled(&self, channel_number: ChannelNumber, enable: bool) {
347 self.registers.ch[channel_number as usize]
348 .csr
349 .modify(match enable {
350 true => CSR::EN::SET,
351 false => CSR::EN::CLEAR,
352 });
353 }
354
355 fn set_ph_correct(&self, channel_number: ChannelNumber, ph_correct: bool) {
360 self.registers.ch[channel_number as usize]
361 .csr
362 .modify(match ph_correct {
363 true => CSR::PH_CORRECT::SET,
364 false => CSR::PH_CORRECT::CLEAR,
365 });
366 }
367
368 fn set_invert_polarity_a(&self, channel_number: ChannelNumber, inv: bool) {
371 self.registers.ch[channel_number as usize]
372 .csr
373 .modify(match inv {
374 true => CSR::A_INV::SET,
375 false => CSR::A_INV::CLEAR,
376 });
377 }
378
379 fn set_invert_polarity_b(&self, channel_number: ChannelNumber, inv: bool) {
382 self.registers.ch[channel_number as usize]
383 .csr
384 .modify(match inv {
385 true => CSR::B_INV::SET,
386 false => CSR::B_INV::CLEAR,
387 });
388 }
389
390 fn set_invert_polarity(&self, channel_number: ChannelNumber, a_inv: bool, b_inv: bool) {
392 self.set_invert_polarity_a(channel_number, a_inv);
393 self.set_invert_polarity_b(channel_number, b_inv);
394 }
395
396 fn set_div_mode(&self, channel_number: ChannelNumber, div_mode: DivMode) {
403 self.registers.ch[channel_number as usize]
404 .csr
405 .modify(match div_mode {
406 DivMode::FreeRunning => CSR::DIVMOD::FREE_RUNNING,
407 DivMode::High => CSR::DIVMOD::B_HIGH,
408 DivMode::Rising => CSR::DIVMOD::B_RISING,
409 DivMode::Falling => CSR::DIVMOD::B_FALLING,
410 });
411 }
412
413 fn set_divider_int_frac(&self, channel_number: ChannelNumber, int: u8, frac: u8) {
420 if int == 0 || frac > 15 {
421 return;
422 }
423 self.registers.ch[channel_number as usize]
424 .div
425 .modify(DIV::INT.val(int as u32));
426 self.registers.ch[channel_number as usize]
427 .div
428 .modify(DIV::FRAC.val(frac as u32));
429 }
430
431 fn set_compare_value_a(&self, channel_number: ChannelNumber, cc_a: u16) {
434 self.registers.ch[channel_number as usize]
435 .cc
436 .modify(CC::A.val(cc_a as u32));
437 }
438
439 fn set_compare_value_b(&self, channel_number: ChannelNumber, cc_b: u16) {
442 self.registers.ch[channel_number as usize]
443 .cc
444 .modify(CC::B.val(cc_b as u32));
445 }
446
447 fn set_compare_values_a_and_b(&self, channel_number: ChannelNumber, cc_a: u16, cc_b: u16) {
449 self.set_compare_value_a(channel_number, cc_a);
450 self.set_compare_value_b(channel_number, cc_b);
451 }
452
453 fn set_top(&self, channel_number: ChannelNumber, top: u16) {
455 self.registers.ch[channel_number as usize]
456 .top
457 .modify(TOP::TOP.val(top as u32));
458 }
459
460 fn get_counter(&self, channel_number: ChannelNumber) -> u16 {
462 self.registers.ch[channel_number as usize]
463 .ctr
464 .read(CTR::CTR) as u16
465 }
466
467 fn set_counter(&self, channel_number: ChannelNumber, value: u16) {
469 self.registers.ch[channel_number as usize]
470 .ctr
471 .modify(CTR::CTR.val(value as u32));
472 }
473
474 fn wait_for(count: usize, f: impl Fn() -> bool) -> bool {
475 for _ in 0..count {
476 if f() {
477 return true;
478 }
479 }
480
481 false
482 }
483
484 fn advance_count(&self, channel_number: ChannelNumber) -> bool {
489 self.registers.ch[channel_number as usize]
490 .csr
491 .modify(CSR::PH_ADV::SET);
492 Self::wait_for(100, || {
493 self.registers.ch[channel_number as usize]
494 .csr
495 .read(CSR::PH_ADV)
496 == 0
497 })
498 }
499
500 fn retard_count(&self, channel_number: ChannelNumber) -> bool {
505 self.registers.ch[channel_number as usize]
506 .csr
507 .modify(CSR::PH_RET::SET);
508 Self::wait_for(100, || {
509 self.registers.ch[channel_number as usize]
510 .csr
511 .read(CSR::PH_RET)
512 == 0
513 })
514 }
515
516 fn enable_interrupt(&self, channel_number: ChannelNumber) {
518 let mask = self.registers.inte.read(CH::CH);
521 self.registers
522 .inte
523 .modify(CH::CH.val(mask | 1 << channel_number as u32));
524 }
525
526 fn disable_interrupt(&self, channel_number: ChannelNumber) {
528 let mask = self.registers.inte.read(CH::CH);
529 self.registers
530 .inte
531 .modify(CH::CH.val(mask & !(1 << channel_number as u32)));
532 }
533
534 fn enable_mask_interrupt(&self, mask: u8) {
538 let old_mask = self.registers.inte.read(CH::CH);
539 self.registers
540 .inte
541 .modify(CH::CH.val(old_mask | mask as u32));
542 }
543
544 fn disable_mask_interrupt(&self, mask: u8) {
548 let old_mask = self.registers.inte.read(CH::CH);
549 self.registers
550 .inte
551 .modify(CH::CH.val(old_mask & !mask as u32));
552 }
553
554 fn clear_interrupt(&self, channel_number: ChannelNumber) {
556 self.registers
557 .intr
558 .write(CH::CH.val(1 << channel_number as u32));
559 }
560
561 fn force_interrupt(&self, channel_number: ChannelNumber) {
563 let mask = self.registers.intf.read(CH::CH);
564 self.registers
565 .intf
566 .modify(CH::CH.val(mask | 1 << channel_number as u32));
567 }
568
569 fn unforce_interrupt(&self, channel_number: ChannelNumber) {
571 let mask = self.registers.intf.read(CH::CH);
572 self.registers
573 .intf
574 .modify(CH::CH.val(mask & !(1 << channel_number as u32)));
575 }
576
577 fn get_interrupt_status(&self, channel_number: ChannelNumber) -> bool {
579 (self.registers.ints.read(CH::CH) & 1 << channel_number as u32) != 0
580 }
581
582 fn configure_channel(&self, channel_number: ChannelNumber, config: &PwmChannelConfiguration) {
584 self.set_ph_correct(channel_number, config.ph_correct);
585 self.set_invert_polarity(channel_number, config.a_inv, config.b_inv);
586 self.set_div_mode(channel_number, config.divmode);
587 self.set_divider_int_frac(channel_number, config.int, config.frac);
588 self.set_compare_value_a(channel_number, config.cc_a);
589 self.set_compare_value_b(channel_number, config.cc_b);
590 self.set_top(channel_number, config.top);
591 self.set_enabled(channel_number, config.en);
592 }
593
594 fn init(&self) {
596 let default_config: PwmChannelConfiguration = PwmChannelConfiguration::default();
597 for channel_number in CHANNEL_NUMBERS {
598 self.configure_channel(channel_number, &default_config);
599 self.set_counter(channel_number, 0);
600 self.disable_interrupt(channel_number);
601 }
602 self.registers.intr.write(CH::CH.val(0));
603 }
604
605 pub(crate) fn set_clocks(&self, clocks: &'a clocks::Clocks) {
608 self.clocks.set(clocks);
609 }
610
611 fn new_pwm_pin(&'a self, channel_number: ChannelNumber, channel_pin: ChannelPin) -> PwmPin<'a> {
613 PwmPin {
614 pwm_struct: self,
615 channel_number,
616 channel_pin,
617 }
618 }
619
620 fn gpio_to_pwm(&self, gpio: RPGpio) -> (ChannelNumber, ChannelPin) {
622 (ChannelNumber::from(gpio), ChannelPin::from(gpio))
623 }
624
625 pub fn gpio_to_pwm_pin(&'a self, gpio: RPGpio) -> PwmPin<'a> {
631 let (channel_number, channel_pin) = self.gpio_to_pwm(gpio);
632 self.new_pwm_pin(channel_number, channel_pin)
633 }
634
635 fn compute_top_int_frac(&self, selected_freq_hz: usize) -> Result<(u16, u8, u8), ()> {
640 let max_freq_hz = hil::pwm::Pwm::get_maximum_frequency_hz(self);
641 let threshold_freq_hz = max_freq_hz / hil::pwm::Pwm::get_maximum_duty_cycle(self);
642 if selected_freq_hz > max_freq_hz || selected_freq_hz == 0 {
644 return Err(());
645 }
646
647 if selected_freq_hz > threshold_freq_hz {
649 return Ok(((max_freq_hz / selected_freq_hz - 1) as u16, 1, 0));
650 }
651 let top = u16::MAX;
655 let int = threshold_freq_hz / selected_freq_hz;
657 if int >= 256 {
660 return Err(());
661 }
662 let frac = ((threshold_freq_hz << 4) / selected_freq_hz - (int << 4)) as u8;
665
666 Ok((top, int as u8, frac))
669 }
670
671 fn start_pwm_pin(
675 &self,
676 channel_number: ChannelNumber,
677 channel_pin: ChannelPin,
678 frequency_hz: usize,
679 duty_cycle: usize,
680 ) -> Result<(), ErrorCode> {
681 let (top, int, frac) = match self.compute_top_int_frac(frequency_hz) {
682 Ok(result) => result,
683 Err(()) => return Result::from(ErrorCode::INVAL),
684 };
685
686 let max_duty_cycle = hil::pwm::Pwm::get_maximum_duty_cycle(self);
687 if duty_cycle > max_duty_cycle {
689 return Err(ErrorCode::INVAL);
690 }
691 let compare_value = if duty_cycle == max_duty_cycle {
694 if top == u16::MAX {
695 return Result::from(ErrorCode::INVAL);
696 } else {
697 top + 1
699 }
700 } else {
701 ((top as usize + 1) * duty_cycle / max_duty_cycle) as u16
705 };
706
707 self.set_top(channel_number, top);
709 self.set_divider_int_frac(channel_number, int, frac);
710 if channel_pin == ChannelPin::A {
712 self.set_compare_value_a(channel_number, compare_value);
713 } else {
714 self.set_compare_value_b(channel_number, compare_value);
715 }
716 self.set_enabled(channel_number, true);
718 Ok(())
719 }
720
721 fn stop_pwm_channel(&self, channel_number: ChannelNumber) -> Result<(), ErrorCode> {
727 self.set_enabled(channel_number, false);
728 Ok(())
729 }
730}
731
732impl hil::pwm::Pwm for Pwm<'_> {
734 type Pin = RPGpio;
735
736 fn start(
761 &self,
762 pin: &Self::Pin,
763 frequency_hz: usize,
764 duty_cycle: usize,
765 ) -> Result<(), ErrorCode> {
766 let (channel_number, channel_pin) = self.gpio_to_pwm(*pin);
767 self.start_pwm_pin(channel_number, channel_pin, frequency_hz, duty_cycle)
768 }
769
770 fn stop(&self, pin: &Self::Pin) -> Result<(), ErrorCode> {
781 let (channel_number, _) = self.gpio_to_pwm(*pin);
782 self.stop_pwm_channel(channel_number)
783 }
784
785 fn get_maximum_frequency_hz(&self) -> usize {
791 self.clocks
792 .unwrap_or_panic()
793 .get_frequency(clocks::Clock::System) as usize
794 }
795
796 fn get_maximum_duty_cycle(&self) -> usize {
798 u16::MAX as usize + 1
799 }
800}
801
802pub struct PwmPin<'a> {
804 pwm_struct: &'a Pwm<'a>,
805 channel_number: ChannelNumber,
806 channel_pin: ChannelPin,
807}
808
809impl PwmPin<'_> {
810 pub fn get_channel_number(&self) -> ChannelNumber {
812 self.channel_number
813 }
814
815 pub fn get_channel_pin(&self) -> ChannelPin {
817 self.channel_pin
818 }
819
820 fn set_invert_polarity(&self, inv: bool) {
822 if self.channel_pin == ChannelPin::A {
823 self.pwm_struct
824 .set_invert_polarity_a(self.channel_number, inv);
825 } else {
826 self.pwm_struct
827 .set_invert_polarity_b(self.channel_number, inv);
828 }
829 }
830
831 fn set_compare_value(&self, compare_value: u16) {
833 if self.channel_pin == ChannelPin::A {
834 self.pwm_struct
835 .set_compare_value_a(self.channel_number, compare_value);
836 } else {
837 self.pwm_struct
838 .set_compare_value_b(self.channel_number, compare_value);
839 }
840 }
841}
842
843impl hil::pwm::PwmPin for PwmPin<'_> {
844 fn start(&self, frequency_hz: usize, duty_cycle: usize) -> Result<(), ErrorCode> {
846 self.pwm_struct.start_pwm_pin(
847 self.channel_number,
848 self.channel_pin,
849 frequency_hz,
850 duty_cycle,
851 )
852 }
853
854 fn stop(&self) -> Result<(), ErrorCode> {
856 self.pwm_struct.stop_pwm_channel(self.channel_number)
857 }
858
859 fn get_maximum_frequency_hz(&self) -> usize {
861 hil::pwm::Pwm::get_maximum_frequency_hz(self.pwm_struct)
862 }
863
864 fn get_maximum_duty_cycle(&self) -> usize {
866 hil::pwm::Pwm::get_maximum_duty_cycle(self.pwm_struct)
867 }
868}
869
870pub mod unit_tests {
911 use super::{
912 debug, hil, ChannelNumber, ChannelPin, DivMode, Pwm, RPGpio, Readable, CC, CH, CSR, CTR,
913 DIV, TOP,
914 };
915
916 fn test_channel_number() {
917 debug!("Testing ChannelNumber enum...");
918 assert_eq!(ChannelNumber::from(RPGpio::GPIO0), ChannelNumber::Ch0);
919 assert_eq!(ChannelNumber::from(RPGpio::GPIO3), ChannelNumber::Ch1);
920 assert_eq!(ChannelNumber::from(RPGpio::GPIO14), ChannelNumber::Ch7);
921 assert_eq!(ChannelNumber::from(RPGpio::GPIO28), ChannelNumber::Ch6);
922 debug!("ChannelNumber enum OK");
923 }
924
925 fn test_channel_pin() {
926 debug!("Testing ChannelPin enum...");
927 assert_eq!(ChannelPin::from(RPGpio::GPIO4), ChannelPin::A);
928 assert_eq!(ChannelPin::from(RPGpio::GPIO5), ChannelPin::B);
929 debug!("ChannelPin enum OK");
930 }
931
932 fn test_channel(pwm: &Pwm, channel_number: ChannelNumber) {
933 debug!("Starting testing channel {}...", channel_number as usize);
934
935 pwm.set_enabled(channel_number, true);
937 assert_eq!(
938 pwm.registers.ch[channel_number as usize].csr.read(CSR::EN),
939 1
940 );
941 pwm.set_enabled(channel_number, false);
942 assert_eq!(
943 pwm.registers.ch[channel_number as usize].csr.read(CSR::EN),
944 0
945 );
946
947 pwm.set_ph_correct(channel_number, true);
949 assert_eq!(
950 pwm.registers.ch[channel_number as usize]
951 .csr
952 .read(CSR::PH_CORRECT),
953 1
954 );
955 pwm.set_ph_correct(channel_number, false);
956 assert_eq!(
957 pwm.registers.ch[channel_number as usize]
958 .csr
959 .read(CSR::PH_CORRECT),
960 0
961 );
962
963 pwm.set_invert_polarity(channel_number, true, true);
965 assert_eq!(
966 pwm.registers.ch[channel_number as usize]
967 .csr
968 .read(CSR::A_INV),
969 1
970 );
971 assert_eq!(
972 pwm.registers.ch[channel_number as usize]
973 .csr
974 .read(CSR::B_INV),
975 1
976 );
977 pwm.set_invert_polarity(channel_number, true, false);
978 assert_eq!(
979 pwm.registers.ch[channel_number as usize]
980 .csr
981 .read(CSR::A_INV),
982 1
983 );
984 assert_eq!(
985 pwm.registers.ch[channel_number as usize]
986 .csr
987 .read(CSR::B_INV),
988 0
989 );
990 pwm.set_invert_polarity(channel_number, false, true);
991 assert_eq!(
992 pwm.registers.ch[channel_number as usize]
993 .csr
994 .read(CSR::A_INV),
995 0
996 );
997 assert_eq!(
998 pwm.registers.ch[channel_number as usize]
999 .csr
1000 .read(CSR::B_INV),
1001 1
1002 );
1003 pwm.set_invert_polarity(channel_number, false, false);
1004 assert_eq!(
1005 pwm.registers.ch[channel_number as usize]
1006 .csr
1007 .read(CSR::A_INV),
1008 0
1009 );
1010 assert_eq!(
1011 pwm.registers.ch[channel_number as usize]
1012 .csr
1013 .read(CSR::B_INV),
1014 0
1015 );
1016
1017 pwm.set_div_mode(channel_number, DivMode::FreeRunning);
1019 assert_eq!(
1020 pwm.registers.ch[channel_number as usize]
1021 .csr
1022 .read(CSR::DIVMOD),
1023 DivMode::FreeRunning as u32
1024 );
1025 pwm.set_div_mode(channel_number, DivMode::High);
1026 assert_eq!(
1027 pwm.registers.ch[channel_number as usize]
1028 .csr
1029 .read(CSR::DIVMOD),
1030 DivMode::High as u32
1031 );
1032 pwm.set_div_mode(channel_number, DivMode::Rising);
1033 assert_eq!(
1034 pwm.registers.ch[channel_number as usize]
1035 .csr
1036 .read(CSR::DIVMOD),
1037 DivMode::Rising as u32
1038 );
1039 pwm.set_div_mode(channel_number, DivMode::Falling);
1040 assert_eq!(
1041 pwm.registers.ch[channel_number as usize]
1042 .csr
1043 .read(CSR::DIVMOD),
1044 DivMode::Falling as u32
1045 );
1046
1047 pwm.set_divider_int_frac(channel_number, 123, 4);
1049 assert_eq!(
1050 pwm.registers.ch[channel_number as usize].div.read(DIV::INT),
1051 123
1052 );
1053 assert_eq!(
1054 pwm.registers.ch[channel_number as usize]
1055 .div
1056 .read(DIV::FRAC),
1057 4
1058 );
1059
1060 pwm.set_compare_value_a(channel_number, 2022);
1062 assert_eq!(
1063 pwm.registers.ch[channel_number as usize].cc.read(CC::A),
1064 2022
1065 );
1066 pwm.set_compare_value_b(channel_number, 12);
1067 assert_eq!(pwm.registers.ch[channel_number as usize].cc.read(CC::B), 12);
1068 pwm.set_compare_values_a_and_b(channel_number, 2023, 1);
1069 assert_eq!(
1070 pwm.registers.ch[channel_number as usize].cc.read(CC::A),
1071 2023
1072 );
1073 assert_eq!(pwm.registers.ch[channel_number as usize].cc.read(CC::B), 1);
1074
1075 pwm.set_top(channel_number, 12345);
1077 assert_eq!(
1078 pwm.registers.ch[channel_number as usize].top.read(TOP::TOP),
1079 12345
1080 );
1081
1082 pwm.set_counter(channel_number, 1);
1084 assert_eq!(
1085 pwm.registers.ch[channel_number as usize].ctr.read(CTR::CTR),
1086 1
1087 );
1088 assert_eq!(pwm.get_counter(channel_number), 1);
1089
1090 pwm.set_div_mode(channel_number, DivMode::FreeRunning);
1095 assert!(pwm.advance_count(channel_number));
1096 assert_eq!(pwm.get_counter(channel_number), 2);
1097 pwm.set_enabled(channel_number, true);
1098 assert!(pwm.retard_count(channel_number));
1102 pwm.set_enabled(channel_number, false);
1104
1105 pwm.enable_interrupt(channel_number);
1107 assert_eq!(
1108 pwm.registers.inte.read(CH::CH),
1109 1 << (channel_number as u32)
1110 );
1111 pwm.disable_interrupt(channel_number);
1112 assert_eq!(pwm.registers.inte.read(CH::CH), 0);
1113
1114 pwm.enable_interrupt(channel_number);
1116 pwm.set_counter(channel_number, 12345);
1117 pwm.advance_count(channel_number);
1118 assert!(pwm.get_interrupt_status(channel_number));
1119 pwm.disable_interrupt(channel_number);
1120
1121 pwm.clear_interrupt(channel_number);
1123 assert!(!pwm.get_interrupt_status(channel_number));
1124
1125 pwm.force_interrupt(channel_number);
1127 assert_eq!(
1128 pwm.registers.intf.read(CH::CH),
1129 1 << (channel_number as u32)
1130 );
1131 assert!(pwm.get_interrupt_status(channel_number));
1132 pwm.unforce_interrupt(channel_number);
1133 assert_eq!(pwm.registers.intf.read(CH::CH), 0);
1134 assert!(!pwm.get_interrupt_status(channel_number));
1135
1136 debug!("Channel {} works!", channel_number as usize);
1137 }
1138
1139 fn test_pwm_struct(pwm: &Pwm) {
1140 debug!("Testing PWM struct...");
1141 let channel_number_list = [
1142 ChannelNumber::Ch1,
1144 ChannelNumber::Ch2,
1145 ChannelNumber::Ch3,
1146 ChannelNumber::Ch4,
1147 ChannelNumber::Ch5,
1148 ChannelNumber::Ch6,
1149 ChannelNumber::Ch7,
1150 ];
1151
1152 pwm.enable_mask_interrupt(u8::MAX);
1154 assert_eq!(pwm.registers.inte.read(CH::CH), u8::MAX as u32);
1155 pwm.disable_mask_interrupt(u8::MAX);
1156 assert_eq!(pwm.registers.inte.read(CH::CH), 0);
1157
1158 for channel_number in channel_number_list {
1159 test_channel(pwm, channel_number);
1160 }
1161 debug!("PWM struct OK");
1162 }
1163
1164 fn test_pwm_pin_struct<'a>(pwm: &'a Pwm<'a>) {
1165 debug!("Testing PwmPin struct...");
1166 let pwm_pin = pwm.gpio_to_pwm_pin(RPGpio::GPIO13);
1167 assert_eq!(pwm_pin.get_channel_number(), ChannelNumber::Ch6);
1168 assert_eq!(pwm_pin.get_channel_pin(), ChannelPin::B);
1169
1170 pwm_pin.set_invert_polarity(true);
1171 assert_eq!(
1172 pwm.registers.ch[pwm_pin.get_channel_number() as usize]
1173 .csr
1174 .read(CSR::B_INV),
1175 1
1176 );
1177 pwm_pin.set_invert_polarity(false);
1178 assert_eq!(
1179 pwm.registers.ch[pwm_pin.get_channel_number() as usize]
1180 .csr
1181 .read(CSR::B_INV),
1182 0
1183 );
1184
1185 pwm_pin.set_compare_value(987);
1186 assert_eq!(
1187 pwm.registers.ch[pwm_pin.get_channel_number() as usize]
1188 .cc
1189 .read(CC::B),
1190 987
1191 );
1192 debug!("PwmPin struct OK");
1193 }
1194
1195 fn test_pwm_trait(pwm: &Pwm) {
1196 debug!("Testing PWM HIL trait...");
1197 let max_freq_hz = hil::pwm::Pwm::get_maximum_frequency_hz(pwm);
1198 let max_duty_cycle = hil::pwm::Pwm::get_maximum_duty_cycle(pwm);
1199
1200 let (top, int, frac) = pwm.compute_top_int_frac(max_freq_hz).unwrap();
1201 assert_eq!(top, 0);
1202 assert_eq!(int, 1);
1203 assert_eq!(frac, 0);
1204
1205 let (top, int, frac) = pwm.compute_top_int_frac(max_freq_hz / 4).unwrap();
1206 assert_eq!(top, 3);
1207 assert_eq!(int, 1);
1208 assert_eq!(frac, 0);
1209
1210 let (top, int, frac) = pwm
1211 .compute_top_int_frac(max_freq_hz / max_duty_cycle)
1212 .unwrap();
1213 assert_eq!(top, u16::MAX);
1214 assert_eq!(int, 1);
1215 assert_eq!(frac, 0);
1216
1217 let (top, int, frac) = pwm
1218 .compute_top_int_frac(max_freq_hz / max_duty_cycle / 2)
1219 .unwrap();
1220 assert_eq!(top, u16::MAX);
1221 assert_eq!(int, 2);
1222 assert_eq!(frac, 0);
1223
1224 let freq = ((max_freq_hz / max_duty_cycle) as f32 / 2.5) as usize;
1225 let (top, int, frac) = pwm.compute_top_int_frac(freq).unwrap();
1226 assert_eq!(top, u16::MAX);
1227 assert_eq!(int, 2);
1228 assert_eq!(frac, 8);
1229
1230 let freq = ((max_freq_hz / max_duty_cycle) as f32 / 3.15) as usize;
1231 let (top, int, frac) = pwm.compute_top_int_frac(freq).unwrap();
1232 assert_eq!(top, u16::MAX);
1233 assert_eq!(int, 3);
1234 assert_eq!(frac, 2);
1235
1236 assert!(pwm
1237 .compute_top_int_frac(max_freq_hz / max_duty_cycle / 256)
1238 .is_err());
1239 assert!(pwm.compute_top_int_frac(max_freq_hz + 1).is_err());
1240
1241 let (channel_number, channel_pin) = pwm.gpio_to_pwm(RPGpio::GPIO24);
1242 assert!(pwm
1243 .start_pwm_pin(channel_number, channel_pin, max_freq_hz / 4, 0)
1244 .is_ok());
1245 assert_eq!(pwm.registers.ch[channel_number as usize].cc.read(CC::A), 0);
1246
1247 assert!(pwm
1248 .start_pwm_pin(
1249 channel_number,
1250 channel_pin,
1251 max_freq_hz / 4,
1252 max_duty_cycle / 4 * 3
1253 )
1254 .is_ok());
1255 assert_eq!(pwm.registers.ch[channel_number as usize].cc.read(CC::A), 3);
1256
1257 assert!(pwm
1258 .start_pwm_pin(channel_number, channel_pin, max_freq_hz / 4, max_duty_cycle)
1259 .is_ok());
1260 assert_eq!(pwm.registers.ch[channel_number as usize].cc.read(CC::A), 4);
1261
1262 assert!(pwm
1263 .start_pwm_pin(
1264 channel_number,
1265 channel_pin,
1266 max_freq_hz / max_duty_cycle,
1267 max_duty_cycle
1268 )
1269 .is_err());
1270 assert!(pwm
1271 .start_pwm_pin(channel_number, channel_pin, max_freq_hz + 1, max_duty_cycle)
1272 .is_err());
1273 assert!(pwm
1274 .start_pwm_pin(channel_number, channel_pin, max_freq_hz, max_duty_cycle + 1)
1275 .is_err());
1276 debug!("PWM HIL trait OK")
1277 }
1278
1279 pub fn run<'a>(pwm: &'a Pwm<'a>) {
1283 test_channel_number();
1284 test_channel_pin();
1285 test_pwm_struct(pwm);
1286 test_pwm_pin_struct(pwm);
1287 test_pwm_trait(pwm);
1288 }
1289}