1use crate::include::{GpioError, ProgError, PWM_MAP};
28use crate::gpio::{Pin, PWM};
29use stm32f4::stm32f446::{NVIC, Interrupt, interrupt};
30use cortex_m::interrupt::{Mutex, free};
31use core::cell::RefCell;
32use rtt_target::rprintln;
33
34static TIME_COUNTER: Mutex<RefCell<usize>> = Mutex::new(RefCell::new(0));
35
36
37#[doc(hidden)]
39pub fn setup_pwm(pin: (char, u8)) -> Result<(u8, u8, u8), ProgError>{
40 let peripheral_ptr;
41 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
42 let rcc = &peripheral_ptr.RCC;
43
44 let (timer, ccch, af) = match check_pwm(pin) {
45 Ok(target) => target,
46 Err(error) => return Err(error)
47 };
48
49 match timer {
50 1 => {
51 let tim1 = &peripheral_ptr.TIM1;
52 rcc.apb2enr.modify(|_, w| w.tim1en().enabled());
53 tim1.cr1.modify(|_, w| w.arpe().enabled());
54 tim1.psc.write(|w| w.psc().bits(1000));
55 tim1.arr.write(|w| w.arr().bits(255));
56 tim1.egr.write(|w| w.ug().set_bit());
57 match ccch {
58 1 => tim1.ccmr1_output().modify(|_, w| { w.oc1pe().enabled(); w.oc1m().pwm_mode1()}),
59 2 => tim1.ccmr1_output().modify(|_, w| { w.oc2pe().enabled(); w.oc2m().pwm_mode1()}),
60 3 => tim1.ccmr2_output().modify(|_, w| { w.oc3pe().enabled(); w.oc3m().pwm_mode1()}),
61 4 => tim1.ccmr2_output().modify(|_, w| { w.oc4pe().enabled(); w.oc4m().pwm_mode1()}),
62 _ => unreachable!()
63 };
64 tim1.ccer.modify(|r, w| unsafe {w.bits(r.bits() | (1 << (4 * (ccch - 1))))});
65 tim1.cr1.modify(|_, w| w.cen().enabled());
66 },
67 2 => {
68 let tim2 = &peripheral_ptr.TIM2;
69 rcc.apb2enr.modify(|_, w| w.tim1en().enabled());
70 tim2.cr1.modify(|_, w| w.arpe().enabled());
71 tim2.psc.write(|w| w.psc().bits(1000));
72 tim2.arr.write(|w| w.arr().bits(255));
73 tim2.egr.write(|w| w.ug().set_bit());
74 match ccch {
75 1 => tim2.ccmr1_output().modify(|_, w| { w.oc1pe().enabled(); w.oc1m().pwm_mode1()}),
76 2 => tim2.ccmr1_output().modify(|_, w| { w.oc2pe().enabled(); w.oc2m().pwm_mode1()}),
77 3 => tim2.ccmr2_output().modify(|_, w| { w.oc3pe().enabled(); w.oc3m().pwm_mode1()}),
78 4 => tim2.ccmr2_output().modify(|_, w| { w.oc4pe().enabled(); w.oc4m().pwm_mode1()}),
79 _ => unreachable!()
80 };
81 tim2.ccer.modify(|r, w| unsafe {w.bits(r.bits() | (1 << (4 * (ccch - 1))))});
82 tim2.cr1.modify(|_, w| w.cen().enabled());
83 },
84 3 => {
85 let tim3 = &peripheral_ptr.TIM3;
86 rcc.apb2enr.modify(|_, w| w.tim1en().enabled());
87 tim3.cr1.modify(|_, w| w.arpe().enabled());
88 tim3.psc.write(|w| w.psc().bits(1000));
89 tim3.arr.write(|w| w.arr().bits(255));
90 tim3.egr.write(|w| w.ug().set_bit());
91 match ccch {
92 1 => tim3.ccmr1_output().modify(|_, w| { w.oc1pe().enabled(); w.oc1m().pwm_mode1()}),
93 2 => tim3.ccmr1_output().modify(|_, w| { w.oc2pe().enabled(); w.oc2m().pwm_mode1()}),
94 3 => tim3.ccmr2_output().modify(|_, w| { w.oc3pe().enabled(); w.oc3m().pwm_mode1()}),
95 4 => tim3.ccmr2_output().modify(|_, w| { w.oc4pe().enabled(); w.oc4m().pwm_mode1()}),
96 _ => unreachable!()
97 };
98 tim3.ccer.modify(|r, w| unsafe {w.bits(r.bits() | (1 << (4 * (ccch - 1))))});
99 tim3.cr1.modify(|_, w| w.cen().enabled());
100 },
101 4 => {
102 let tim4 = &peripheral_ptr.TIM4;
103 rcc.apb2enr.modify(|_, w| w.tim1en().enabled());
104 tim4.cr1.modify(|_, w| w.arpe().enabled());
105 tim4.psc.write(|w| w.psc().bits(1000));
106 tim4.arr.write(|w| w.arr().bits(255));
107 tim4.egr.write(|w| w.ug().set_bit());
108 match ccch {
109 1 => tim4.ccmr1_output().modify(|_, w| { w.oc1pe().enabled(); w.oc1m().pwm_mode1()}),
110 2 => tim4.ccmr1_output().modify(|_, w| { w.oc2pe().enabled(); w.oc2m().pwm_mode1()}),
111 3 => tim4.ccmr2_output().modify(|_, w| { w.oc3pe().enabled(); w.oc3m().pwm_mode1()}),
112 4 => tim4.ccmr2_output().modify(|_, w| { w.oc4pe().enabled(); w.oc4m().pwm_mode1()}),
113 _ => unreachable!()
114 };
115 tim4.ccer.modify(|r, w| unsafe {w.bits(r.bits() | (1 << (4 * (ccch - 1))))});
116 tim4.cr1.modify(|_, w| w.cen().enabled());
117 },
118 _ => unreachable!()
119 };
120
121 return Ok((timer, ccch, af));
122}
123
124pub fn pwm_write(pin: &Pin<PWM>, value: u8) -> Result<(), GpioError> {
140 let peripheral_ptr;
141 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
142
143 match pin.inner.timer {
144 1 => {
145 let tim1 = &peripheral_ptr.TIM1;
146 match pin.inner.ccch {
147 1 => tim1.ccr1.write(|w| w.ccr().bits(value.into())),
148 2 => tim1.ccr2.write(|w| w.ccr().bits(value.into())),
149 3 => tim1.ccr3.write(|w| w.ccr().bits(value.into())),
150 4 => tim1.ccr4.write(|w| w.ccr().bits(value.into())),
151 _ => unreachable!()
152 };
153 },
154 2 => {
155 let tim2 = &peripheral_ptr.TIM2;
156 match pin.inner.ccch {
157 1 => tim2.ccr1.write(|w| w.ccr().bits(value.into())),
158 2 => tim2.ccr2.write(|w| w.ccr().bits(value.into())),
159 3 => tim2.ccr3.write(|w| w.ccr().bits(value.into())),
160 4 => tim2.ccr4.write(|w| w.ccr().bits(value.into())),
161 _ => unreachable!()
162 };
163 },
164 3 => {
165 let tim3 = &peripheral_ptr.TIM3;
166 match pin.inner.ccch {
167 1 => tim3.ccr1.write(|w| w.ccr().bits(value.into())),
168 2 => tim3.ccr2.write(|w| w.ccr().bits(value.into())),
169 3 => tim3.ccr3.write(|w| w.ccr().bits(value.into())),
170 4 => tim3.ccr4.write(|w| w.ccr().bits(value.into())),
171 _ => unreachable!()
172 };
173 },
174 4 => {
175 let tim4 = &peripheral_ptr.TIM4;
176 match pin.inner.ccch {
177 1 => tim4.ccr1.write(|w| w.ccr().bits(value.into())),
178 2 => tim4.ccr2.write(|w| w.ccr().bits(value.into())),
179 3 => tim4.ccr3.write(|w| w.ccr().bits(value.into())),
180 4 => tim4.ccr4.write(|w| w.ccr().bits(value.into())),
181 _ => unreachable!()
182 };
183 },
184 _ => unreachable!()
185 };
186
187 return Ok(());
188}
189
190
191fn check_pwm(pin: (char, u8)) -> Result<(u8, u8, u8), ProgError> {
193 if !PWM_MAP.pins.contains(&pin) {return Err(ProgError::InvalidConfiguration);}
194 else {
195 let timer = PWM_MAP.timers[PWM_MAP.pins.iter().position(|&i| i == pin).unwrap()];
196 let ccch = PWM_MAP.ccchs[PWM_MAP.pins.iter().position(|&i| i == pin).unwrap()];
197 let af = match timer {
198 1 => 1,
199 2 => 1,
200 3 => 2,
201 4 => 2,
202 _ => unreachable!()
203 };
204
205 return Ok((timer, ccch, af));
206 }
207}
208
209
210pub fn delay(ms: u16) {
229 let peripheral_ptr;
230 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
231 let rcc = &peripheral_ptr.RCC;
232 let tim6 = &peripheral_ptr.TIM6;
233
234 if rcc.apb1enr.read().tim6en().is_disabled() {
235 rcc.apb1enr.modify(|_, w| w.tim6en().enabled());
236 tim6.cr1.modify(|_, w| {
237 w.arpe().enabled();
238 w.opm().set_bit()
239 });
240
241 tim6.psc.write(|w| w.psc().bits(16000));
243 }
244
245 tim6.arr.write(|w| w.arr().bits(ms));
246 tim6.egr.write(|w| w.ug().update());
247 tim6.cr1.modify(|_, w| w.cen().enabled());
248 while tim6.cr1.read().cen().bit_is_set() {}
249}
250
251pub fn start_time() {
272 let peripheral_ptr;
273 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
274 let rcc = &peripheral_ptr.RCC;
275 let tim7 = &peripheral_ptr.TIM7;
276
277 if rcc.apb1enr.read().tim7en().is_enabled() {
278 rprintln!("Millis Timer already configured! | start_time()");
279 return;
280 }
281
282 rcc.apb1enr.modify(|_, w| w.tim7en().enabled());
283 tim7.cr1.modify(|_, w| w.arpe().enabled());
284
285 tim7.dier.modify(|_, w| w.uie().enabled());
286 unsafe {NVIC::unmask(Interrupt::TIM7);}
287
288 tim7.psc.write(|w| w.psc().bits(16));
290 tim7.arr.write(|w| w.arr().bits(1000));
291 tim7.egr.write(|w| w.ug().update());
292 tim7.cr1.modify(|_, w| w.cen().enabled());
293}
294
295pub fn millis() -> usize {
314 let peripheral_ptr;
315 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
316 let tim7 = &peripheral_ptr.TIM6;
317
318 let buffer: usize;
319
320 tim7.cr1.modify(|_, w| w.cen().disabled());
321 buffer = free(|cs| *TIME_COUNTER.borrow(cs).borrow());
322 tim7.cr1.modify(|_, w| w.cen().enabled());
323
324 return buffer;
325}
326
327
328#[allow(non_snake_case)]
330#[interrupt]
331fn TIM7() {
332 free(|cs| TIME_COUNTER.borrow(cs).replace_with(|&mut i| i + 1));
333}