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