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