1use crate::analog::enable_channel;
30use crate::time::setup_pwm;
31use crate::include::{ProgError, PIN_CONF};
32use rtt_target::rprintln;
33
34pub struct Pin<T> {
36 #[doc(hidden)]
37 pub block: char,
38 #[doc(hidden)]
39 pub number: u8,
40 #[doc(hidden)]
41 pub inner: T
42}
43
44#[doc(hidden)]
45pub struct Input;
46#[doc(hidden)]
47pub struct Output;
48#[doc(hidden)]
49pub struct AlternateFunction(u32);
50#[doc(hidden)]
51pub struct Analog {
52 #[doc(hidden)]
53 pub core: u8,
54 #[doc(hidden)]
55 pub channel: u8
56}
57#[doc(hidden)]
58pub struct PWM {
59 #[doc(hidden)]
60 pub timer: u8,
61 #[doc(hidden)]
62 pub ccch: u8
63}
64
65pub enum GpioSpeed {
76 Low, Medium, Fast, High
77}
78
79pub enum GpioBias {
81 None, Pullup, Pulldown
82}
83
84
85pub fn pinmode_input(pin: (char, u8)) -> Result<Pin<Input>, ProgError> {
92 let peripheral_ptr;
93 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
94 let rcc = &peripheral_ptr.RCC;
95
96 if let Err(error) = check_pin(pin) {return Err(error);}
97
98 unsafe {
99 if !PIN_CONF.contains(&pin) {PIN_CONF.push(pin).unwrap();}
100 else {
101 rprintln!("P{}{} is already configured! | pin_mode()", pin.0.to_uppercase(), pin.1);
102 return Err(ProgError::AlreadyConfigured);
103 }
104 }
105
106 match pin.0 {
107 'a' => {
108 let gpioa = &peripheral_ptr.GPIOA;
109 rcc.ahb1enr.modify(|_, w| w.gpioaen().enabled());
110 gpioa.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)))});
111 },
112 'b' => {
113 let gpiob = &peripheral_ptr.GPIOB;
114 rcc.ahb1enr.modify(|_, w| w.gpioben().enabled());
115 gpiob.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)))});
116 },
117 'c' => {
118 let gpioc = &peripheral_ptr.GPIOC;
119 rcc.ahb1enr.modify(|_, w| w.gpiocen().enabled());
120 gpioc.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)))});
121 },
122 'd' => {
123 let gpiod = &peripheral_ptr.GPIOD;
124 rcc.ahb1enr.modify(|_, w| w.gpioden().enabled());
125 gpiod.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)))});
126 },
127 'h' => {
128 let gpioh = &peripheral_ptr.GPIOH;
129 rcc.ahb1enr.modify(|_, w| w.gpiohen().enabled());
130 gpioh.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)))});
131 },
132 _ => unreachable!()
133 };
134
135 return Ok(Pin {
136 block: pin.0,
137 number: pin.1,
138 inner: Input
139 });
140}
141
142pub unsafe fn pinmode_input_force(pin: (char, u8)) -> Result<Pin<Input>, ProgError> {
153 let peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();
154 let rcc = &peripheral_ptr.RCC;
155
156 if let Err(error) = check_pin(pin) {return Err(error);}
157
158 match pin.0 {
159 'a' => {
160 let gpioa = &peripheral_ptr.GPIOA;
161 rcc.ahb1enr.modify(|_, w| w.gpioaen().enabled());
162 gpioa.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)))});
163 },
164 'b' => {
165 let gpiob = &peripheral_ptr.GPIOB;
166 rcc.ahb1enr.modify(|_, w| w.gpioben().enabled());
167 gpiob.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)))});
168 },
169 'c' => {
170 let gpioc = &peripheral_ptr.GPIOC;
171 rcc.ahb1enr.modify(|_, w| w.gpiocen().enabled());
172 gpioc.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)))});
173 },
174 'd' => {
175 let gpiod = &peripheral_ptr.GPIOD;
176 rcc.ahb1enr.modify(|_, w| w.gpioden().enabled());
177 gpiod.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)))});
178 },
179 'h' => {
180 let gpioh = &peripheral_ptr.GPIOH;
181 rcc.ahb1enr.modify(|_, w| w.gpiohen().enabled());
182 gpioh.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)))});
183 },
184 _ => unreachable!()
185 };
186
187 return Ok(Pin {
188 block: pin.0,
189 number: pin.1,
190 inner: Input
191 });
192}
193
194pub fn pinmode_output(pin: (char, u8)) -> Result<Pin<Output>, ProgError> {
200 let peripheral_ptr;
201 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
202 let rcc = &peripheral_ptr.RCC;
203
204 if let Err(error) = check_pin(pin) {return Err(error);}
205
206 unsafe {
207 if !PIN_CONF.contains(&pin) {PIN_CONF.push(pin).unwrap();}
208 else {
209 rprintln!("P{}{} is already configured! | pin_mode()", pin.0.to_uppercase(), pin.1);
210 return Err(ProgError::AlreadyConfigured);
211 }
212 }
213
214 match pin.0 {
215 'a' => {
216 let gpioa = &peripheral_ptr.GPIOA;
217 rcc.ahb1enr.modify(|_, w| w.gpioaen().enabled());
218 gpioa.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (1 << (2 * pin.1)))});
219 },
220 'b' => {
221 let gpiob = &peripheral_ptr.GPIOB;
222 rcc.ahb1enr.modify(|_, w| w.gpioben().enabled());
223 gpiob.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (1 << (2 * pin.1)))});
224 },
225 'c' => {
226 let gpioc = &peripheral_ptr.GPIOC;
227 rcc.ahb1enr.modify(|_, w| w.gpiocen().enabled());
228 gpioc.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (1 << (2 * pin.1)))});
229 },
230 'd' => {
231 let gpiod = &peripheral_ptr.GPIOD;
232 rcc.ahb1enr.modify(|_, w| w.gpioden().enabled());
233 gpiod.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (1 << (2 * pin.1)))});
234 },
235 'h' => {
236 let gpioh = &peripheral_ptr.GPIOH;
237 rcc.ahb1enr.modify(|_, w| w.gpiohen().enabled());
238 gpioh.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (1 << (2 * pin.1)))});
239 },
240 _ => unreachable!()
241 };
242
243 return Ok(Pin {
244 block: pin.0,
245 number: pin.1,
246 inner: Output
247 });
248}
249
250pub unsafe fn pinmode_output_force(pin: (char, u8)) -> Result<Pin<Output>, ProgError> {
261 let peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();
262 let rcc = &peripheral_ptr.RCC;
263
264 if let Err(error) = check_pin(pin) {return Err(error);}
265
266 match pin.0 {
267 'a' => {
268 let gpioa = &peripheral_ptr.GPIOA;
269 rcc.ahb1enr.modify(|_, w| w.gpioaen().enabled());
270 gpioa.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (1 << (2 * pin.1)))});
271 },
272 'b' => {
273 let gpiob = &peripheral_ptr.GPIOB;
274 rcc.ahb1enr.modify(|_, w| w.gpioben().enabled());
275 gpiob.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (1 << (2 * pin.1)))});
276 },
277 'c' => {
278 let gpioc = &peripheral_ptr.GPIOC;
279 rcc.ahb1enr.modify(|_, w| w.gpiocen().enabled());
280 gpioc.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (1 << (2 * pin.1)))});
281 },
282 'd' => {
283 let gpiod = &peripheral_ptr.GPIOD;
284 rcc.ahb1enr.modify(|_, w| w.gpioden().enabled());
285 gpiod.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (1 << (2 * pin.1)))});
286 },
287 'h' => {
288 let gpioh = &peripheral_ptr.GPIOH;
289 rcc.ahb1enr.modify(|_, w| w.gpiohen().enabled());
290 gpioh.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (1 << (2 * pin.1)))});
291 },
292 _ => unreachable!()
293 };
294
295 return Ok(Pin {
296 block: pin.0,
297 number: pin.1,
298 inner: Output
299 });
300}
301
302pub fn pinmode_alternate_function(pin: (char, u8), af: u32) -> Result<Pin<AlternateFunction>, ProgError> {
308 let peripheral_ptr;
309 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
310 let rcc = &peripheral_ptr.RCC;
311
312 if let Err(error) = check_pin(pin) {return Err(error);}
313 if af > 15 {
314 rprintln!("Only alternate funtion values between 0 and 15 are valid! | pin_mode()");
315 return Err(ProgError::InvalidConfiguration);
316 }
317
318 unsafe {
319 if !PIN_CONF.contains(&pin) {PIN_CONF.push(pin).unwrap();}
320 else {
321 rprintln!("P{}{} is already configured! | pin_mode()", pin.0.to_uppercase(), pin.1);
322 return Err(ProgError::AlreadyConfigured);
323 }
324 }
325
326 match pin.0 {
327 'a' => {
328 let gpioa = &peripheral_ptr.GPIOA;
329 rcc.ahb1enr.modify(|_, w| w.gpioaen().enabled());
330 gpioa.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
331 if pin.1 > 7 {gpioa.afrh.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * (pin.1 - 8))))});}
332 else {gpioa.afrl.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * pin.1)))});}
333 },
334 'b' => {
335 let gpiob = &peripheral_ptr.GPIOB;
336 rcc.ahb1enr.modify(|_, w| w.gpioben().enabled());
337 gpiob.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
338 if pin.1 > 7 {gpiob.afrh.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * (pin.1 - 8))))});}
339 else {gpiob.afrl.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * pin.1)))});}
340 },
341 'c' => {
342 let gpioc = &peripheral_ptr.GPIOC;
343 rcc.ahb1enr.modify(|_, w| w.gpiocen().enabled());
344 gpioc.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
345 if pin.1 > 7 {gpioc.afrh.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * (pin.1 - 8))))});}
346 else {gpioc.afrl.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * pin.1)))});}
347 },
348 'd' => {
349 let gpiod = &peripheral_ptr.GPIOD;
350 rcc.ahb1enr.modify(|_, w| w.gpioden().enabled());
351 gpiod.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
352 if pin.1 > 7 {gpiod.afrh.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * (pin.1 - 8))))});}
353 else {gpiod.afrl.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * pin.1)))});}
354 },
355 'h' => {
356 let gpioh = &peripheral_ptr.GPIOH;
357 rcc.ahb1enr.modify(|_, w| w.gpiohen().enabled());
358 gpioh.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
359 if pin.1 > 7 {gpioh.afrh.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * (pin.1 - 8))))});}
360 else {gpioh.afrl.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * pin.1)))});}
361 },
362 _ => unreachable!()
363 };
364
365 return Ok(Pin {
366 block: pin.0,
367 number: pin.1,
368 inner: AlternateFunction(af)
369 });
370}
371
372pub unsafe fn pinmode_alternate_function_force(pin: (char, u8), af: u32) -> Result<Pin<AlternateFunction>, ProgError> {
383 let peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();
384 let rcc = &peripheral_ptr.RCC;
385
386 if let Err(error) = check_pin(pin) {return Err(error);}
387 if af > 15 {
388 rprintln!("Only alternate funtion values between 0 and 15 are valid! | pin_mode()");
389 return Err(ProgError::InvalidConfiguration);
390 }
391
392 match pin.0 {
393 'a' => {
394 let gpioa = &peripheral_ptr.GPIOA;
395 rcc.ahb1enr.modify(|_, w| w.gpioaen().enabled());
396 gpioa.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
397 if pin.1 > 7 {gpioa.afrh.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * (pin.1 - 8))))});}
398 else {gpioa.afrl.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * pin.1)))});}
399 },
400 'b' => {
401 let gpiob = &peripheral_ptr.GPIOB;
402 rcc.ahb1enr.modify(|_, w| w.gpioben().enabled());
403 gpiob.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
404 if pin.1 > 7 {gpiob.afrh.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * (pin.1 - 8))))});}
405 else {gpiob.afrl.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * pin.1)))});}
406 },
407 'c' => {
408 let gpioc = &peripheral_ptr.GPIOC;
409 rcc.ahb1enr.modify(|_, w| w.gpiocen().enabled());
410 gpioc.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
411 if pin.1 > 7 {gpioc.afrh.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * (pin.1 - 8))))});}
412 else {gpioc.afrl.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * pin.1)))});}
413 },
414 'd' => {
415 let gpiod = &peripheral_ptr.GPIOD;
416 rcc.ahb1enr.modify(|_, w| w.gpioden().enabled());
417 gpiod.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
418 if pin.1 > 7 {gpiod.afrh.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * (pin.1 - 8))))});}
419 else {gpiod.afrl.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * pin.1)))});}
420 },
421 'h' => {
422 let gpioh = &peripheral_ptr.GPIOH;
423 rcc.ahb1enr.modify(|_, w| w.gpiohen().enabled());
424 gpioh.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
425 if pin.1 > 7 {gpioh.afrh.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * (pin.1 - 8))))});}
426 else {gpioh.afrl.modify(|r, w| unsafe {w.bits(r.bits() | (af << (4 * pin.1)))});}
427 },
428 _ => unreachable!()
429 };
430
431 return Ok(Pin {
432 block: pin.0,
433 number: pin.1,
434 inner: AlternateFunction(af)
435 });
436}
437
438pub fn pinmode_analog(pin: (char, u8)) -> Result<Pin<Analog>, ProgError> {
445 let peripheral_ptr;
446 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
447 let rcc = &peripheral_ptr.RCC;
448
449 let channel_data: (u8, u8);
450
451 if let Err(error) = check_pin(pin) {return Err(error);}
452
453 unsafe {
454 if !PIN_CONF.contains(&pin) {PIN_CONF.push(pin).unwrap();}
455 else {
456 rprintln!("P{}{} is already configured! | pin_mode()", pin.0.to_uppercase(), pin.1);
457 return Err(ProgError::AlreadyConfigured);
458 }
459 }
460
461 match pin.0 {
462 'a' => {
463 let gpioa = &peripheral_ptr.GPIOA;
464 rcc.ahb1enr.modify(|_, w| w.gpioaen().enabled());
465 gpioa.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (3 << (2 * pin.1)))});
466 channel_data = match enable_channel(pin) {
467 Ok(value) => value,
468 Err(error) => return Err(error)
469 };
470 },
471 'b' => {
472 let gpiob = &peripheral_ptr.GPIOB;
473 rcc.ahb1enr.modify(|_, w| w.gpioben().enabled());
474 gpiob.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (3 << (2 * pin.1)))});
475 channel_data = match enable_channel(pin) {
476 Ok(value) => value,
477 Err(error) => return Err(error)
478 };
479 },
480 'c' => {
481 let gpioc = &peripheral_ptr.GPIOC;
482 rcc.ahb1enr.modify(|_, w| w.gpiocen().enabled());
483 gpioc.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (3 << (2 * pin.1)))});
484 channel_data = match enable_channel(pin) {
485 Ok(value) => value,
486 Err(error) => return Err(error)
487 };
488 },
489 'd' => {
490 let gpiod = &peripheral_ptr.GPIOD;
491 rcc.ahb1enr.modify(|_, w| w.gpioden().enabled());
492 gpiod.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (3 << (2 * pin.1)))});
493 channel_data = match enable_channel(pin) {
494 Ok(value) => value,
495 Err(error) => return Err(error)
496 };
497 },
498 'h' => {
499 let gpioh = &peripheral_ptr.GPIOH;
500 rcc.ahb1enr.modify(|_, w| w.gpiohen().enabled());
501 gpioh.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (3 << (2 * pin.1)))});
502 channel_data = match enable_channel(pin) {
503 Ok(value) => value,
504 Err(error) => return Err(error)
505 };
506 },
507 _ => unreachable!()
508 };
509
510 return Ok(Pin {
511 block: pin.0,
512 number: pin.1,
513 inner: Analog {
514 core: channel_data.0,
515 channel: channel_data.1
516 }
517 });
518}
519
520pub unsafe fn pinmode_analog_force(pin: (char, u8)) -> Result<Pin<Analog>, ProgError> {
532 let peripheral_ptr;
533 peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();
534 let rcc = &peripheral_ptr.RCC;
535
536 let channel_data: (u8, u8);
537
538 if let Err(error) = check_pin(pin) {return Err(error);}
539
540 match pin.0 {
541 'a' => {
542 let gpioa = &peripheral_ptr.GPIOA;
543 rcc.ahb1enr.modify(|_, w| w.gpioaen().enabled());
544 gpioa.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (3 << (2 * pin.1)))});
545 channel_data = match enable_channel(pin) {
546 Ok(value) => value,
547 Err(error) => return Err(error)
548 };
549 },
550 'b' => {
551 let gpiob = &peripheral_ptr.GPIOB;
552 rcc.ahb1enr.modify(|_, w| w.gpioben().enabled());
553 gpiob.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (3 << (2 * pin.1)))});
554 channel_data = match enable_channel(pin) {
555 Ok(value) => value,
556 Err(error) => return Err(error)
557 };
558 },
559 'c' => {
560 let gpioc = &peripheral_ptr.GPIOC;
561 rcc.ahb1enr.modify(|_, w| w.gpiocen().enabled());
562 gpioc.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (3 << (2 * pin.1)))});
563 channel_data = match enable_channel(pin) {
564 Ok(value) => value,
565 Err(error) => return Err(error)
566 };
567 },
568 'd' => {
569 let gpiod = &peripheral_ptr.GPIOD;
570 rcc.ahb1enr.modify(|_, w| w.gpioden().enabled());
571 gpiod.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (3 << (2 * pin.1)))});
572 channel_data = match enable_channel(pin) {
573 Ok(value) => value,
574 Err(error) => return Err(error)
575 };
576 },
577 'h' => {
578 let gpioh = &peripheral_ptr.GPIOH;
579 rcc.ahb1enr.modify(|_, w| w.gpiohen().enabled());
580 gpioh.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (3 << (2 * pin.1)))});
581 channel_data = match enable_channel(pin) {
582 Ok(value) => value,
583 Err(error) => return Err(error)
584 };
585 },
586 _ => unreachable!()
587 };
588
589 return Ok(Pin {
590 block: pin.0,
591 number: pin.1,
592 inner: Analog {
593 core: channel_data.0,
594 channel: channel_data.1
595 }
596 });
597}
598
599pub fn pinmode_pwm(pin: (char, u8)) -> Result<Pin<PWM>, ProgError> {
606 let peripheral_ptr;
607 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
608 let rcc = &peripheral_ptr.RCC;
609
610 if let Err(error) = check_pin(pin) {return Err(error);}
611
612 unsafe {
613 if !PIN_CONF.contains(&pin) {PIN_CONF.push(pin).unwrap();}
614 else {
615 rprintln!("P{}{} is already configured! | pin_mode()", pin.0.to_uppercase(), pin.1);
616 return Err(ProgError::AlreadyConfigured);
617 }
618 }
619
620 let returns = match setup_pwm(pin) {
621 Ok(values) => values,
622 Err(error) => return Err(error)
623 };
624
625 match pin.0 {
626 'a' => {
627 let gpioa = &peripheral_ptr.GPIOA;
628 rcc.ahb1enr.modify(|_, w| w.gpioaen().enabled());
629 gpioa.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
630 if pin.1 > 7 {gpioa.afrh.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * (pin.1 - 8))))});}
631 else {gpioa.afrl.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * pin.1)))});}
632 },
633 'b' => {
634 let gpiob = &peripheral_ptr.GPIOB;
635 rcc.ahb1enr.modify(|_, w| w.gpioben().enabled());
636 gpiob.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
637 if pin.1 > 7 {gpiob.afrh.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * (pin.1 - 8))))});}
638 else {gpiob.afrl.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * pin.1)))});}
639 },
640 'c' => {
641 let gpioc = &peripheral_ptr.GPIOC;
642 rcc.ahb1enr.modify(|_, w| w.gpiocen().enabled());
643 gpioc.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
644 if pin.1 > 7 {gpioc.afrh.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * (pin.1 - 8))))});}
645 else {gpioc.afrl.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * pin.1)))});}
646 },
647 'd' => {
648 let gpiod = &peripheral_ptr.GPIOD;
649 rcc.ahb1enr.modify(|_, w| w.gpioden().enabled());
650 gpiod.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
651 if pin.1 > 7 {gpiod.afrh.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * (pin.1 - 8))))});}
652 else {gpiod.afrl.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * pin.1)))});}
653 },
654 'h' => {
655 let gpioh = &peripheral_ptr.GPIOH;
656 rcc.ahb1enr.modify(|_, w| w.gpiohen().enabled());
657 gpioh.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
658 if pin.1 > 7 {gpioh.afrh.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * (pin.1 - 8))))});}
659 else {gpioh.afrl.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * pin.1)))});}
660 },
661 _ => unreachable!()
662 };
663
664 return Ok(Pin {
665 block: pin.0,
666 number: pin.1,
667 inner: PWM {
668 timer: returns.0,
669 ccch: returns.1
670 }
671 });
672}
673
674pub unsafe fn pinmode_pwm_force(pin: (char, u8)) -> Result<Pin<PWM>, ProgError> {
686 let peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();
687 let rcc = &peripheral_ptr.RCC;
688
689 if let Err(error) = check_pin(pin) {return Err(error);}
690
691 if !PIN_CONF.contains(&pin) {PIN_CONF.push(pin).unwrap();}
692 else {
693 rprintln!("P{}{} is already configured! | pin_mode()", pin.0.to_uppercase(), pin.1);
694 return Err(ProgError::AlreadyConfigured);
695 }
696
697 let returns = match setup_pwm(pin) {
698 Ok(values) => values,
699 Err(error) => return Err(error)
700 };
701
702 match pin.0 {
703 'a' => {
704 let gpioa = &peripheral_ptr.GPIOA;
705 rcc.ahb1enr.modify(|_, w| w.gpioaen().enabled());
706 gpioa.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
707 if pin.1 > 7 {gpioa.afrh.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * (pin.1 - 8))))});}
708 else {gpioa.afrl.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * pin.1)))});}
709 },
710 'b' => {
711 let gpiob = &peripheral_ptr.GPIOB;
712 rcc.ahb1enr.modify(|_, w| w.gpioben().enabled());
713 gpiob.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
714 if pin.1 > 7 {gpiob.afrh.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * (pin.1 - 8))))});}
715 else {gpiob.afrl.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * pin.1)))});}
716 },
717 'c' => {
718 let gpioc = &peripheral_ptr.GPIOC;
719 rcc.ahb1enr.modify(|_, w| w.gpiocen().enabled());
720 gpioc.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
721 if pin.1 > 7 {gpioc.afrh.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * (pin.1 - 8))))});}
722 else {gpioc.afrl.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * pin.1)))});}
723 },
724 'd' => {
725 let gpiod = &peripheral_ptr.GPIOD;
726 rcc.ahb1enr.modify(|_, w| w.gpioden().enabled());
727 gpiod.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
728 if pin.1 > 7 {gpiod.afrh.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * (pin.1 - 8))))});}
729 else {gpiod.afrl.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * pin.1)))});}
730 },
731 'h' => {
732 let gpioh = &peripheral_ptr.GPIOH;
733 rcc.ahb1enr.modify(|_, w| w.gpiohen().enabled());
734 gpioh.moder.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * pin.1)) | (2 << (2 * pin.1)))});
735 if pin.1 > 7 {gpioh.afrh.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * (pin.1 - 8))))});}
736 else {gpioh.afrl.modify(|r, w| unsafe {w.bits(r.bits() | ((returns.2 as u32) << (4 * pin.1)))});}
737 },
738 _ => unreachable!()
739 };
740
741 return Ok(Pin {
742 block: pin.0,
743 number: pin.1,
744 inner: PWM {
745 timer: returns.0,
746 ccch: returns.1
747 }
748 });
749}
750
751pub fn digital_write(pin: &Pin<Output>, value: bool) {
755 let peripheral_ptr;
756 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
757
758 match pin.block {
759 'a' => {
760 let gpioa = &peripheral_ptr.GPIOA;
761 if value {gpioa.bsrr.write(|w| unsafe {w.bits(1 << pin.number)});}
762 else {gpioa.bsrr.write(|w| unsafe {w.bits(1 << (pin.number + 16))});}
763 },
764 'b' => {
765 let gpiob = &peripheral_ptr.GPIOB;
766 if value {gpiob.bsrr.write(|w| unsafe {w.bits(1 << pin.number)});}
767 else {gpiob.bsrr.write(|w| unsafe {w.bits(1 << (pin.number + 16))});}
768 },
769 'c' => {
770 let gpioc = &peripheral_ptr.GPIOC;
771 if value {gpioc.bsrr.write(|w| unsafe {w.bits(1 << pin.number)});}
772 else {gpioc.bsrr.write(|w| unsafe {w.bits(1 << (pin.number + 16))});}
773 },
774 'd' => {
775 let gpiod = &peripheral_ptr.GPIOD;
776 if value {gpiod.bsrr.write(|w| unsafe {w.bits(1 << pin.number)});}
777 else {gpiod.bsrr.write(|w| unsafe {w.bits(1 << (pin.number + 16))});}
778 },
779 'h' => {
780 let gpioh = &peripheral_ptr.GPIOH;
781 if value {gpioh.bsrr.write(|w| unsafe {w.bits(1 << pin.number)});}
782 else {gpioh.bsrr.write(|w| unsafe {w.bits(1 << (pin.number + 16))});}
783 },
784 _ => unreachable!()
785 };
786}
787
788pub fn digital_read(pin: &Pin<Input>) -> bool {
792 let peripheral_ptr;
793 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
794
795 let bits = match pin.block {
796 'a' => {
797 let gpioa = &peripheral_ptr.GPIOA;
798 gpioa.idr.read().bits()
799 },
800 'b' => {
801 let gpiob = &peripheral_ptr.GPIOB;
802 gpiob.idr.read().bits()
803 },
804 'c' => {
805 let gpioc = &peripheral_ptr.GPIOC;
806 gpioc.idr.read().bits()
807 },
808 'd' => {
809 let gpiod = &peripheral_ptr.GPIOD;
810 gpiod.idr.read().bits()
811 },
812 'h' => {
813 let gpioh = &peripheral_ptr.GPIOH;
814 gpioh.idr.read().bits()
815 },
816 _ => unreachable!()
817 };
818
819 return bits & (1 << pin.number) == (1 << pin.number);
820}
821
822pub fn digital_state(pin: &Pin<Output>) -> bool {
826 let peripheral_ptr;
827 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
828
829 let bits = match pin.block {
830 'a' => {
831 let gpioa = &peripheral_ptr.GPIOA;
832 gpioa.odr.read().bits()
833 },
834 'b' => {
835 let gpiob = &peripheral_ptr.GPIOB;
836 gpiob.odr.read().bits()
837 },
838 'c' => {
839 let gpioc = &peripheral_ptr.GPIOC;
840 gpioc.odr.read().bits()
841 },
842 'd' => {
843 let gpiod = &peripheral_ptr.GPIOD;
844 gpiod.odr.read().bits()
845 },
846 'h' => {
847 let gpioh = &peripheral_ptr.GPIOH;
848 gpioh.odr.read().bits()
849 },
850 _ => unreachable!()
851 };
852
853 return bits & (1 << pin.number) == (1 << pin.number);
854}
855
856pub fn set_bias<T>(pin: &Pin<T>, bias: GpioBias) {
861 let peripheral_ptr;
862 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
863
864 let num = pin.number;
865
866 match pin.block {
867 'a' => {
868 let gpioa = &peripheral_ptr.GPIOA;
869 match bias {
870 GpioBias::None => gpioa.pupdr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)))}),
871 GpioBias::Pullup => gpioa.pupdr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (1 << (2 * num)))}),
872 GpioBias::Pulldown => gpioa.pupdr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (2 << (2 * num)))})
873 };
874 },
875 'b' => {
876 let gpiob = &peripheral_ptr.GPIOB;
877 match bias {
878 GpioBias::None => gpiob.pupdr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)))}),
879 GpioBias::Pullup => gpiob.pupdr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (1 << (2 * num)))}),
880 GpioBias::Pulldown => gpiob.pupdr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (2 << (2 * num)))})
881 };
882 },
883 'c' => {
884 let gpioc = &peripheral_ptr.GPIOC;
885 match bias {
886 GpioBias::None => gpioc.pupdr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)))}),
887 GpioBias::Pullup => gpioc.pupdr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (1 << (2 * num)))}),
888 GpioBias::Pulldown => gpioc.pupdr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (2 << (2 * num)))})
889 };
890 },
891 'd' => {
892 let gpiod = &peripheral_ptr.GPIOD;
893 match bias {
894 GpioBias::None => gpiod.pupdr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)))}),
895 GpioBias::Pullup => gpiod.pupdr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (1 << (2 * num)))}),
896 GpioBias::Pulldown => gpiod.pupdr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (2 << (2 * num)))})
897 };
898 },
899 'h' => {
900 let gpioh = &peripheral_ptr.GPIOH;
901 match bias {
902 GpioBias::None => gpioh.pupdr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)))}),
903 GpioBias::Pullup => gpioh.pupdr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (1 << (2 * num)))}),
904 GpioBias::Pulldown => gpioh.pupdr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (2 << (2 * num)))})
905 };
906 },
907 _ => unreachable!()
908 };
909}
910
911pub fn set_speed<T>(pin: &Pin<T>, speed: GpioSpeed) {
917 let peripheral_ptr;
918 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
919
920 let num = pin.number;
921
922 match pin.block {
923 'a' => {
924 let gpioa = &peripheral_ptr.GPIOA;
925 match speed {
926 GpioSpeed::Low => gpioa.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)))}),
927 GpioSpeed::Medium => gpioa.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (1 << (2 * num)))}),
928 GpioSpeed::Fast => gpioa.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (2 << (2 * num)))}),
929 GpioSpeed::High => gpioa.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() | (3 << (2 * num)))})
930 };
931 },
932 'b' => {
933 let gpiob = &peripheral_ptr.GPIOB;
934 match speed {
935 GpioSpeed::Low => gpiob.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)))}),
936 GpioSpeed::Medium => gpiob.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (1 << (2 * num)))}),
937 GpioSpeed::Fast => gpiob.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (2 << (2 * num)))}),
938 GpioSpeed::High => gpiob.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() | (3 << (2 * num)))})
939 };
940 },
941 'c' => {
942 let gpioc = &peripheral_ptr.GPIOC;
943 match speed {
944 GpioSpeed::Low => gpioc.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)))}),
945 GpioSpeed::Medium => gpioc.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (1 << (2 * num)))}),
946 GpioSpeed::Fast => gpioc.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (2 << (2 * num)))}),
947 GpioSpeed::High => gpioc.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() | (3 << (2 * num)))})
948 };
949 },
950 'd' => {
951 let gpiod = &peripheral_ptr.GPIOD;
952 match speed {
953 GpioSpeed::Low => gpiod.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)))}),
954 GpioSpeed::Medium => gpiod.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (1 << (2 * num)))}),
955 GpioSpeed::Fast => gpiod.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (2 << (2 * num)))}),
956 GpioSpeed::High => gpiod.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() | (3 << (2 * num)))})
957 };
958 },
959 'h' => {
960 let gpioh = &peripheral_ptr.GPIOH;
961 match speed {
962 GpioSpeed::Low => gpioh.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)))}),
963 GpioSpeed::Medium => gpioh.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (1 << (2 * num)))}),
964 GpioSpeed::Fast => gpioh.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() & !(3 << (2 * num)) | (2 << (2 * num)))}),
965 GpioSpeed::High => gpioh.ospeedr.modify(|r, w| unsafe {w.bits(r.bits() | (3 << (2 * num)))})
966 };
967 },
968 _ => unreachable!()
969 };
970}
971
972pub fn open_drain<T>(pin: &Pin<T>, op: bool) {
977 let peripheral_ptr;
978 unsafe {peripheral_ptr = stm32f4::stm32f446::Peripherals::steal();}
979
980 match pin.block {
981 'a' => {
982 let gpioa = &peripheral_ptr.GPIOA;
983 if op {gpioa.otyper.modify(|r, w| unsafe {w.bits(r.bits() | (1 << pin.number))});}
984 else {gpioa.otyper.modify(|r, w| unsafe {w.bits(r.bits() | (0 << pin.number))});}
985 },
986 'b' => {
987 let gpiob = &peripheral_ptr.GPIOB;
988 if op {gpiob.otyper.modify(|r, w| unsafe {w.bits(r.bits() | (1 << pin.number))});}
989 else {gpiob.otyper.modify(|r, w| unsafe {w.bits(r.bits() | (0 << pin.number))});}
990 },
991 'c' => {
992 let gpioc = &peripheral_ptr.GPIOC;
993 if op {gpioc.otyper.modify(|r, w| unsafe {w.bits(r.bits() | (1 << pin.number))});}
994 else {gpioc.otyper.modify(|r, w| unsafe {w.bits(r.bits() | (0 << pin.number))});}
995 },
996 'd' => {
997 let gpiod = &peripheral_ptr.GPIOD;
998 if op {gpiod.otyper.modify(|r, w| unsafe {w.bits(r.bits() | (1 << pin.number))});}
999 else {gpiod.otyper.modify(|r, w| unsafe {w.bits(r.bits() | (0 << pin.number))});}
1000 },
1001 'h' => {
1002 let gpioh = &peripheral_ptr.GPIOH;
1003 if op {gpioh.otyper.modify(|r, w| unsafe {w.bits(r.bits() | (1 << pin.number))});}
1004 else {gpioh.otyper.modify(|r, w| unsafe {w.bits(r.bits() | (0 << pin.number))});}
1005 },
1006 _ => unreachable!()
1007 };
1008}
1009
1010
1011fn check_pin(pin: (char, u8)) -> Result<(), ProgError> {
1013 if pin.1 > 15 || pin.0 == 'd' && pin.1 != 2 || pin.0 == 'h' && pin.1 != 0 && pin.1 != 1 {
1014 rprintln!("P{}{} is not an available GPIO Pin!", pin.0.to_uppercase(), pin.1);
1015 return Err(ProgError::InvalidConfiguration);
1016 }
1017 else {return Ok(());}
1018}
1019
1020impl<T> Drop for Pin<T> {
1021 fn drop(&mut self) {
1022 unsafe {PIN_CONF.swap_remove(PIN_CONF.iter().position(|&i| i == (self.block, self.number)).unwrap());}
1023 }
1024}