1use core::marker::PhantomData;
11
12pub use crate::pac::pcnt::unit::conf0::{CTRL_MODE as CtrlMode, EDGE_MODE as EdgeMode};
13use crate::{
14 gpio::{InputSignal, interconnect::PeripheralInput},
15 peripherals::PCNT,
16 system::GenericPeripheralGuard,
17};
18
19pub struct Channel<'d, const UNIT: usize, const NUM: usize> {
21 _phantom: PhantomData<&'d ()>,
22 _not_send: PhantomData<*const ()>,
24 _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Pcnt as u8 }>,
25}
26
27impl<const UNIT: usize, const NUM: usize> Channel<'_, UNIT, NUM> {
28 pub(super) fn new() -> Self {
30 let guard = GenericPeripheralGuard::new();
31
32 Self {
33 _phantom: PhantomData,
34 _not_send: PhantomData,
35 _guard: guard,
36 }
37 }
38
39 pub fn set_ctrl_mode(&self, low: CtrlMode, high: CtrlMode) {
45 let pcnt = PCNT::regs();
46 let conf0 = pcnt.unit(UNIT).conf0();
47
48 conf0.modify(|_, w| {
49 w.ch_hctrl_mode(NUM as u8).variant(high);
50 w.ch_lctrl_mode(NUM as u8).variant(low)
51 });
52 }
53
54 pub fn set_input_mode(&self, neg_edge: EdgeMode, pos_edge: EdgeMode) {
60 let pcnt = PCNT::regs();
61 let conf0 = pcnt.unit(UNIT).conf0();
62
63 conf0.modify(|_, w| {
64 w.ch_neg_mode(NUM as u8).variant(neg_edge);
65 w.ch_pos_mode(NUM as u8).variant(pos_edge)
66 });
67 }
68
69 pub fn set_ctrl_signal<'d>(&self, source: impl PeripheralInput<'d>) -> &Self {
71 let signal = match UNIT {
72 0 => match NUM {
73 0 => InputSignal::PCNT0_CTRL_CH0,
74 1 => InputSignal::PCNT0_CTRL_CH1,
75 _ => unreachable!(),
76 },
77 1 => match NUM {
78 0 => InputSignal::PCNT1_CTRL_CH0,
79 1 => InputSignal::PCNT1_CTRL_CH1,
80 _ => unreachable!(),
81 },
82 2 => match NUM {
83 0 => InputSignal::PCNT2_CTRL_CH0,
84 1 => InputSignal::PCNT2_CTRL_CH1,
85 _ => unreachable!(),
86 },
87 3 => match NUM {
88 0 => InputSignal::PCNT3_CTRL_CH0,
89 1 => InputSignal::PCNT3_CTRL_CH1,
90 _ => unreachable!(),
91 },
92 #[cfg(esp32)]
93 4 => match NUM {
94 0 => InputSignal::PCNT4_CTRL_CH0,
95 1 => InputSignal::PCNT4_CTRL_CH1,
96 _ => unreachable!(),
97 },
98 #[cfg(esp32)]
99 5 => match NUM {
100 0 => InputSignal::PCNT5_CTRL_CH0,
101 1 => InputSignal::PCNT5_CTRL_CH1,
102 _ => unreachable!(),
103 },
104 #[cfg(esp32)]
105 6 => match NUM {
106 0 => InputSignal::PCNT6_CTRL_CH0,
107 1 => InputSignal::PCNT6_CTRL_CH1,
108 _ => unreachable!(),
109 },
110 #[cfg(esp32)]
111 7 => match NUM {
112 0 => InputSignal::PCNT7_CTRL_CH0,
113 1 => InputSignal::PCNT7_CTRL_CH1,
114 _ => unreachable!(),
115 },
116 _ => unreachable!(),
117 };
118
119 if signal as usize <= property!("gpio.input_signal_max") {
120 let source = source.into();
121 source.set_input_enable(true);
122 signal.connect_to(&source);
123 } else {
124 warn!("Signal {:?} out of range", signal);
125 }
126 self
127 }
128
129 pub fn set_edge_signal<'d>(&self, source: impl PeripheralInput<'d>) -> &Self {
131 let signal = match UNIT {
132 0 => match NUM {
133 0 => InputSignal::PCNT0_SIG_CH0,
134 1 => InputSignal::PCNT0_SIG_CH1,
135 _ => unreachable!(),
136 },
137 1 => match NUM {
138 0 => InputSignal::PCNT1_SIG_CH0,
139 1 => InputSignal::PCNT1_SIG_CH1,
140 _ => unreachable!(),
141 },
142 2 => match NUM {
143 0 => InputSignal::PCNT2_SIG_CH0,
144 1 => InputSignal::PCNT2_SIG_CH1,
145 _ => unreachable!(),
146 },
147 3 => match NUM {
148 0 => InputSignal::PCNT3_SIG_CH0,
149 1 => InputSignal::PCNT3_SIG_CH1,
150 _ => unreachable!(),
151 },
152 #[cfg(esp32)]
153 4 => match NUM {
154 0 => InputSignal::PCNT4_SIG_CH0,
155 1 => InputSignal::PCNT4_SIG_CH1,
156 _ => unreachable!(),
157 },
158 #[cfg(esp32)]
159 5 => match NUM {
160 0 => InputSignal::PCNT5_SIG_CH0,
161 1 => InputSignal::PCNT5_SIG_CH1,
162 _ => unreachable!(),
163 },
164 #[cfg(esp32)]
165 6 => match NUM {
166 0 => InputSignal::PCNT6_SIG_CH0,
167 1 => InputSignal::PCNT6_SIG_CH1,
168 _ => unreachable!(),
169 },
170 #[cfg(esp32)]
171 7 => match NUM {
172 0 => InputSignal::PCNT7_SIG_CH0,
173 1 => InputSignal::PCNT7_SIG_CH1,
174 _ => unreachable!(),
175 },
176 _ => unreachable!(),
177 };
178
179 if signal as usize <= property!("gpio.input_signal_max") {
180 let source = source.into();
181 source.set_input_enable(true);
182 signal.connect_to(&source);
183 } else {
184 warn!("Signal {:?} out of range", signal);
185 }
186 self
187 }
188}