1pub use tm4c_hal::sysctl::*;
25
26use crate::{
27 bb,
28 time::{Hertz, U32Ext},
29};
30use cortex_m::asm::nop;
31
32pub struct Sysctl {
34 pub power_control: PowerControl,
37 pub clock_setup: ClockSetup,
39}
40
41#[non_exhaustive]
43pub struct PowerControl {}
44
45#[non_exhaustive]
47pub struct ClockSetup {
48 pub oscillator: Oscillator,
50}
51
52#[derive(Clone, Copy)]
54pub enum Oscillator {
55 Main(CrystalFrequency, SystemClock),
58 PrecisionInternal(SystemClock),
61 LowFrequencyInternal(Divider),
63}
64
65#[derive(Clone, Copy)]
67pub enum SystemClock {
68 UseOscillator(Divider),
70 UsePll(PllOutputFrequency),
73}
74
75#[derive(Clone, Copy)]
77pub enum CrystalFrequency {
78 _4mhz,
80 _4_09mhz,
82 _4_91mhz,
84 _5mhz,
86 _5_12mhz,
88 _6mhz,
90 _6_14mhz,
92 _7_37mhz,
94 _8mhz,
96 _8_19mhz,
98 _10mhz,
100 _12mhz,
102 _12_2mhz,
104 _13_5mhz,
106 _14_3mhz,
108 _16mhz,
110 _16_3mhz,
112 _18mhz,
114 _20mhz,
116 _24mhz,
118 _25mhz,
120}
121
122impl Into<Hertz> for CrystalFrequency {
123 fn into(self) -> Hertz {
124 Hertz(match self {
125 CrystalFrequency::_4mhz => 4_000_000,
126 CrystalFrequency::_4_09mhz => 4_090_000,
127 CrystalFrequency::_4_91mhz => 4_910_000,
128 CrystalFrequency::_5mhz => 5_000_000,
129 CrystalFrequency::_5_12mhz => 5_120_000,
130 CrystalFrequency::_6mhz => 6_000_000,
131 CrystalFrequency::_6_14mhz => 6_140_000,
132 CrystalFrequency::_7_37mhz => 7_370_000,
133 CrystalFrequency::_8mhz => 8_000_000,
134 CrystalFrequency::_8_19mhz => 8_190_000,
135 CrystalFrequency::_10mhz => 10_000_000,
136 CrystalFrequency::_12mhz => 12_000_000,
137 CrystalFrequency::_12_2mhz => 12_200_000,
138 CrystalFrequency::_13_5mhz => 13_500_000,
139 CrystalFrequency::_14_3mhz => 14_300_000,
140 CrystalFrequency::_16mhz => 16_000_000,
141 CrystalFrequency::_16_3mhz => 16_300_000,
142 CrystalFrequency::_18mhz => 18_000_000,
143 CrystalFrequency::_20mhz => 20_000_000,
144 CrystalFrequency::_24mhz => 24_000_000,
145 CrystalFrequency::_25mhz => 25_000_000,
146 })
147 }
148}
149
150#[derive(Clone, Copy)]
152pub enum PllOutputFrequency {
153 _120mhz,
155 _60mhz,
157 _48mhz,
159 _30mhz,
161 _24mhz,
163 _12mhz,
165 _6mhz,
167}
168
169impl Into<Hertz> for PllOutputFrequency {
170 fn into(self) -> Hertz {
171 Hertz(match self {
172 PllOutputFrequency::_120mhz => 120_000_000,
173 PllOutputFrequency::_60mhz => 60_000_000,
174 PllOutputFrequency::_48mhz => 48_000_000,
175 PllOutputFrequency::_30mhz => 30_000_000,
176 PllOutputFrequency::_24mhz => 24_000_000,
177 PllOutputFrequency::_12mhz => 12_000_000,
178 PllOutputFrequency::_6mhz => 6_000_000,
179 })
180 }
181}
182
183#[derive(Clone, Copy)]
185pub enum Divider {
186 _1 = 1,
188 _2 = 2,
190 _3 = 3,
192 _4 = 4,
194 _5 = 5,
196 _6 = 6,
198 _7 = 7,
200 _8 = 8,
202 _9 = 9,
204 _10 = 10,
206 _11 = 11,
208 _12 = 12,
210 _13 = 13,
212 _14 = 14,
214 _15 = 15,
216 _16 = 16,
218}
219
220#[derive(Copy, Clone)]
222pub enum Domain {
223 Watchdog1,
225 Watchdog0,
227 Timer5,
229 Timer4,
231 Timer3,
233 Timer2,
235 Timer1,
237 Timer0,
239 GpioQ,
241 GpioP,
243 GpioN,
245 GpioM,
247 GpioL,
249 GpioK,
251 GpioJ,
253 GpioH,
255 GpioG,
257 GpioF,
259 GpioE,
261 GpioD,
263 GpioC,
265 GpioB,
267 GpioA,
269 MicroDma,
271 Hibernation,
273 Uart7,
275 Uart6,
277 Uart5,
279 Uart4,
281 Uart3,
283 Uart2,
285 Uart1,
287 Uart0,
289 Ssi3,
291 Ssi2,
293 Ssi1,
295 Ssi0,
297 I2c3,
299 I2c2,
301 I2c1,
303 I2c0,
305 Usb,
307 Can,
309 Adc1,
311 Adc0,
313 AnalogComparator,
315 Eeprom,
317 Pwm0,
319 Pwm1,
321 Emac0,
323 Ephy0,
325}
326
327pub fn reset(_lock: &PowerControl, pd: Domain) {
329 let p = unsafe { &*tm4c129x::SYSCTL::ptr() };
331 match pd {
332 Domain::Watchdog1 => unsafe {
333 bb::toggle_bit(&p.srwd, 1);
334 bb::spin_bit(&p.prwd, 1);
335 },
336 Domain::Watchdog0 => unsafe {
337 bb::toggle_bit(&p.srwd, 0);
338 bb::spin_bit(&p.prwd, 0);
339 },
340 Domain::Timer5 => unsafe {
341 bb::toggle_bit(&p.srtimer, 5);
342 bb::spin_bit(&p.prtimer, 5);
343 },
344 Domain::Timer4 => unsafe {
345 bb::toggle_bit(&p.srtimer, 4);
346 bb::spin_bit(&p.prtimer, 4);
347 },
348 Domain::Timer3 => unsafe {
349 bb::toggle_bit(&p.srtimer, 3);
350 bb::spin_bit(&p.prtimer, 3);
351 },
352 Domain::Timer2 => unsafe {
353 bb::toggle_bit(&p.srtimer, 2);
354 bb::spin_bit(&p.prtimer, 2);
355 },
356 Domain::Timer1 => unsafe {
357 bb::toggle_bit(&p.srtimer, 1);
358 bb::spin_bit(&p.prtimer, 1);
359 },
360 Domain::Timer0 => unsafe {
361 bb::toggle_bit(&p.srtimer, 0);
362 bb::spin_bit(&p.prtimer, 0);
363 },
364 Domain::GpioQ => unsafe {
365 bb::toggle_bit(&p.srgpio, 14);
366 bb::spin_bit(&p.prgpio, 14);
367 },
368 Domain::GpioP => unsafe {
369 bb::toggle_bit(&p.srgpio, 13);
370 bb::spin_bit(&p.prgpio, 13);
371 },
372 Domain::GpioN => unsafe {
373 bb::toggle_bit(&p.srgpio, 12);
374 bb::spin_bit(&p.prgpio, 12);
375 },
376 Domain::GpioM => unsafe {
377 bb::toggle_bit(&p.srgpio, 11);
378 bb::spin_bit(&p.prgpio, 11);
379 },
380 Domain::GpioL => unsafe {
381 bb::toggle_bit(&p.srgpio, 10);
382 bb::spin_bit(&p.prgpio, 10);
383 },
384 Domain::GpioK => unsafe {
385 bb::toggle_bit(&p.srgpio, 9);
386 bb::spin_bit(&p.prgpio, 9);
387 },
388 Domain::GpioJ => unsafe {
389 bb::toggle_bit(&p.srgpio, 8);
390 bb::spin_bit(&p.prgpio, 8);
391 },
392 Domain::GpioH => unsafe {
393 bb::toggle_bit(&p.srgpio, 7);
394 bb::spin_bit(&p.prgpio, 7);
395 },
396 Domain::GpioG => unsafe {
397 bb::toggle_bit(&p.srgpio, 6);
398 bb::spin_bit(&p.prgpio, 6);
399 },
400 Domain::GpioF => unsafe {
401 bb::toggle_bit(&p.srgpio, 5);
402 bb::spin_bit(&p.prgpio, 5);
403 },
404 Domain::GpioE => unsafe {
405 bb::toggle_bit(&p.srgpio, 4);
406 bb::spin_bit(&p.prgpio, 4);
407 },
408 Domain::GpioD => unsafe {
409 bb::toggle_bit(&p.srgpio, 3);
410 bb::spin_bit(&p.prgpio, 3);
411 },
412 Domain::GpioC => unsafe {
413 bb::toggle_bit(&p.srgpio, 2);
414 bb::spin_bit(&p.prgpio, 2);
415 },
416 Domain::GpioB => unsafe {
417 bb::toggle_bit(&p.srgpio, 1);
418 bb::spin_bit(&p.prgpio, 1);
419 },
420 Domain::GpioA => unsafe {
421 bb::toggle_bit(&p.srgpio, 0);
422 bb::spin_bit(&p.prgpio, 0);
423 },
424 Domain::MicroDma => unsafe {
425 bb::toggle_bit(&p.srdma, 0);
426 bb::spin_bit(&p.prdma, 0);
427 },
428 Domain::Hibernation => unsafe {
429 bb::toggle_bit(&p.srhib, 0);
430 bb::spin_bit(&p.prhib, 0);
431 },
432 Domain::Uart7 => unsafe {
433 bb::toggle_bit(&p.sruart, 7);
434 bb::spin_bit(&p.pruart, 7);
435 },
436 Domain::Uart6 => unsafe {
437 bb::toggle_bit(&p.sruart, 6);
438 bb::spin_bit(&p.pruart, 6);
439 },
440 Domain::Uart5 => unsafe {
441 bb::toggle_bit(&p.sruart, 5);
442 bb::spin_bit(&p.pruart, 5);
443 },
444 Domain::Uart4 => unsafe {
445 bb::toggle_bit(&p.sruart, 4);
446 bb::spin_bit(&p.pruart, 4);
447 },
448 Domain::Uart3 => unsafe {
449 bb::toggle_bit(&p.sruart, 3);
450 bb::spin_bit(&p.pruart, 3);
451 },
452 Domain::Uart2 => unsafe {
453 bb::toggle_bit(&p.sruart, 2);
454 bb::spin_bit(&p.pruart, 2);
455 },
456 Domain::Uart1 => unsafe {
457 bb::toggle_bit(&p.sruart, 1);
458 bb::spin_bit(&p.pruart, 1);
459 },
460 Domain::Uart0 => unsafe {
461 bb::toggle_bit(&p.sruart, 0);
462 bb::spin_bit(&p.pruart, 0);
463 },
464 Domain::Ssi3 => unsafe {
465 bb::toggle_bit(&p.srssi, 3);
466 bb::spin_bit(&p.prssi, 3);
467 },
468 Domain::Ssi2 => unsafe {
469 bb::toggle_bit(&p.srssi, 2);
470 bb::spin_bit(&p.prssi, 2);
471 },
472 Domain::Ssi1 => unsafe {
473 bb::toggle_bit(&p.srssi, 1);
474 bb::spin_bit(&p.prssi, 1);
475 },
476 Domain::Ssi0 => unsafe {
477 bb::toggle_bit(&p.srssi, 0);
478 bb::spin_bit(&p.prssi, 0);
479 },
480 Domain::I2c3 => unsafe {
481 bb::toggle_bit(&p.sri2c, 3);
482 bb::spin_bit(&p.pri2c, 3);
483 },
484 Domain::I2c2 => unsafe {
485 bb::toggle_bit(&p.sri2c, 2);
486 bb::spin_bit(&p.pri2c, 2);
487 },
488 Domain::I2c1 => unsafe {
489 bb::toggle_bit(&p.sri2c, 1);
490 bb::spin_bit(&p.pri2c, 1);
491 },
492 Domain::I2c0 => unsafe {
493 bb::toggle_bit(&p.sri2c, 0);
494 bb::spin_bit(&p.pri2c, 0);
495 },
496 Domain::Usb => unsafe {
497 bb::toggle_bit(&p.srusb, 0);
498 bb::spin_bit(&p.prusb, 0);
499 },
500 Domain::Can => unsafe {
501 bb::toggle_bit(&p.srcan, 0);
502 bb::spin_bit(&p.prcan, 0);
503 },
504 Domain::Adc1 => unsafe {
505 bb::toggle_bit(&p.sradc, 1);
506 bb::spin_bit(&p.pradc, 1);
507 },
508 Domain::Adc0 => unsafe {
509 bb::toggle_bit(&p.sradc, 0);
510 bb::spin_bit(&p.pradc, 0);
511 },
512 Domain::AnalogComparator => unsafe {
513 bb::toggle_bit(&p.sracmp, 0);
514 bb::spin_bit(&p.pracmp, 0);
515 },
516 Domain::Eeprom => unsafe {
517 bb::toggle_bit(&p.sreeprom, 0);
518 bb::spin_bit(&p.preeprom, 0);
519 },
520 Domain::Pwm0 => unsafe {
521 bb::toggle_bit(&p.srpwm, 0);
522 bb::spin_bit(&p.prpwm, 0);
523 },
524 Domain::Pwm1 => unsafe {
525 bb::toggle_bit(&p.srpwm, 1);
526 bb::spin_bit(&p.prpwm, 1);
527 },
528 Domain::Emac0 => unsafe {
529 bb::toggle_bit(&p.sremac, 0);
530 bb::spin_bit(&p.premac, 0);
531 },
532 Domain::Ephy0 => unsafe {
533 bb::toggle_bit(&p.srephy, 0);
534 bb::spin_bit(&p.prephy, 0);
535 },
536 }
537}
538
539pub fn control_power(_lock: &PowerControl, pd: Domain, run_mode: RunMode, state: PowerState) {
546 let on = match state {
547 PowerState::On => true,
548 PowerState::Off => false,
549 };
550 match run_mode {
551 RunMode::Run => control_run_power(pd, on),
552 RunMode::Sleep => control_sleep_power(pd, on),
553 RunMode::DeepSleep => control_deep_sleep_power(pd, on),
554 }
555 nop();
559 nop();
560 nop();
561}
562
563fn control_run_power(pd: Domain, on: bool) {
564 let p = unsafe { &*tm4c129x::SYSCTL::ptr() };
566 match pd {
567 Domain::Watchdog1 => unsafe { bb::change_bit(&p.rcgcwd, 1, on) },
568 Domain::Watchdog0 => unsafe { bb::change_bit(&p.rcgcwd, 0, on) },
569 Domain::Timer5 => unsafe { bb::change_bit(&p.rcgctimer, 5, on) },
570 Domain::Timer4 => unsafe { bb::change_bit(&p.rcgctimer, 4, on) },
571 Domain::Timer3 => unsafe { bb::change_bit(&p.rcgctimer, 3, on) },
572 Domain::Timer2 => unsafe { bb::change_bit(&p.rcgctimer, 2, on) },
573 Domain::Timer1 => unsafe { bb::change_bit(&p.rcgctimer, 1, on) },
574 Domain::Timer0 => unsafe { bb::change_bit(&p.rcgctimer, 0, on) },
575 Domain::GpioQ => unsafe { bb::change_bit(&p.rcgcgpio, 14, on) },
576 Domain::GpioP => unsafe { bb::change_bit(&p.rcgcgpio, 13, on) },
577 Domain::GpioN => unsafe { bb::change_bit(&p.rcgcgpio, 12, on) },
578 Domain::GpioM => unsafe { bb::change_bit(&p.rcgcgpio, 11, on) },
579 Domain::GpioL => unsafe { bb::change_bit(&p.rcgcgpio, 10, on) },
580 Domain::GpioK => unsafe { bb::change_bit(&p.rcgcgpio, 9, on) },
581 Domain::GpioJ => unsafe { bb::change_bit(&p.rcgcgpio, 8, on) },
582 Domain::GpioH => unsafe { bb::change_bit(&p.rcgcgpio, 7, on) },
583 Domain::GpioG => unsafe { bb::change_bit(&p.rcgcgpio, 6, on) },
584 Domain::GpioF => unsafe { bb::change_bit(&p.rcgcgpio, 5, on) },
585 Domain::GpioE => unsafe { bb::change_bit(&p.rcgcgpio, 4, on) },
586 Domain::GpioD => unsafe { bb::change_bit(&p.rcgcgpio, 3, on) },
587 Domain::GpioC => unsafe { bb::change_bit(&p.rcgcgpio, 2, on) },
588 Domain::GpioB => unsafe { bb::change_bit(&p.rcgcgpio, 1, on) },
589 Domain::GpioA => unsafe { bb::change_bit(&p.rcgcgpio, 0, on) },
590 Domain::MicroDma => unsafe { bb::change_bit(&p.rcgcdma, 0, on) },
591 Domain::Hibernation => unsafe { bb::change_bit(&p.rcgchib, 0, on) },
592 Domain::Uart7 => unsafe { bb::change_bit(&p.rcgcuart, 7, on) },
593 Domain::Uart6 => unsafe { bb::change_bit(&p.rcgcuart, 6, on) },
594 Domain::Uart5 => unsafe { bb::change_bit(&p.rcgcuart, 5, on) },
595 Domain::Uart4 => unsafe { bb::change_bit(&p.rcgcuart, 4, on) },
596 Domain::Uart3 => unsafe { bb::change_bit(&p.rcgcuart, 3, on) },
597 Domain::Uart2 => unsafe { bb::change_bit(&p.rcgcuart, 2, on) },
598 Domain::Uart1 => unsafe { bb::change_bit(&p.rcgcuart, 1, on) },
599 Domain::Uart0 => unsafe { bb::change_bit(&p.rcgcuart, 0, on) },
600 Domain::Ssi3 => unsafe { bb::change_bit(&p.rcgcssi, 3, on) },
601 Domain::Ssi2 => unsafe { bb::change_bit(&p.rcgcssi, 2, on) },
602 Domain::Ssi1 => unsafe { bb::change_bit(&p.rcgcssi, 1, on) },
603 Domain::Ssi0 => unsafe { bb::change_bit(&p.rcgcssi, 0, on) },
604 Domain::I2c3 => unsafe { bb::change_bit(&p.rcgci2c, 3, on) },
605 Domain::I2c2 => unsafe { bb::change_bit(&p.rcgci2c, 2, on) },
606 Domain::I2c1 => unsafe { bb::change_bit(&p.rcgci2c, 1, on) },
607 Domain::I2c0 => unsafe { bb::change_bit(&p.rcgci2c, 0, on) },
608 Domain::Usb => unsafe { bb::change_bit(&p.rcgcusb, 0, on) },
609 Domain::Can => unsafe { bb::change_bit(&p.rcgccan, 0, on) },
610 Domain::Adc1 => unsafe { bb::change_bit(&p.rcgcadc, 1, on) },
611 Domain::Adc0 => unsafe { bb::change_bit(&p.rcgcadc, 0, on) },
612 Domain::AnalogComparator => unsafe { bb::change_bit(&p.rcgcacmp, 0, on) },
613 Domain::Eeprom => unsafe { bb::change_bit(&p.rcgceeprom, 0, on) },
614 Domain::Pwm0 => unsafe { bb::change_bit(&p.rcgcpwm, 0, on) },
615 Domain::Pwm1 => unsafe { bb::change_bit(&p.rcgcpwm, 1, on) },
616 Domain::Emac0 => unsafe { bb::change_bit(&p.rcgcemac, 0, on) },
617 Domain::Ephy0 => unsafe { bb::change_bit(&p.rcgcephy, 0, on) },
618 }
619}
620
621fn control_sleep_power(pd: Domain, on: bool) {
622 let p = unsafe { &*tm4c129x::SYSCTL::ptr() };
624 match pd {
625 Domain::Watchdog1 => unsafe { bb::change_bit(&p.scgcwd, 1, on) },
626 Domain::Watchdog0 => unsafe { bb::change_bit(&p.scgcwd, 0, on) },
627 Domain::Timer5 => unsafe { bb::change_bit(&p.scgctimer, 5, on) },
628 Domain::Timer4 => unsafe { bb::change_bit(&p.scgctimer, 4, on) },
629 Domain::Timer3 => unsafe { bb::change_bit(&p.scgctimer, 3, on) },
630 Domain::Timer2 => unsafe { bb::change_bit(&p.scgctimer, 2, on) },
631 Domain::Timer1 => unsafe { bb::change_bit(&p.scgctimer, 1, on) },
632 Domain::Timer0 => unsafe { bb::change_bit(&p.scgctimer, 0, on) },
633 Domain::GpioQ => unsafe { bb::change_bit(&p.scgcgpio, 14, on) },
634 Domain::GpioP => unsafe { bb::change_bit(&p.scgcgpio, 13, on) },
635 Domain::GpioN => unsafe { bb::change_bit(&p.scgcgpio, 12, on) },
636 Domain::GpioM => unsafe { bb::change_bit(&p.scgcgpio, 11, on) },
637 Domain::GpioL => unsafe { bb::change_bit(&p.scgcgpio, 10, on) },
638 Domain::GpioK => unsafe { bb::change_bit(&p.scgcgpio, 9, on) },
639 Domain::GpioJ => unsafe { bb::change_bit(&p.scgcgpio, 8, on) },
640 Domain::GpioH => unsafe { bb::change_bit(&p.scgcgpio, 7, on) },
641 Domain::GpioG => unsafe { bb::change_bit(&p.scgcgpio, 6, on) },
642 Domain::GpioF => unsafe { bb::change_bit(&p.scgcgpio, 5, on) },
643 Domain::GpioE => unsafe { bb::change_bit(&p.scgcgpio, 4, on) },
644 Domain::GpioD => unsafe { bb::change_bit(&p.scgcgpio, 3, on) },
645 Domain::GpioC => unsafe { bb::change_bit(&p.scgcgpio, 2, on) },
646 Domain::GpioB => unsafe { bb::change_bit(&p.scgcgpio, 1, on) },
647 Domain::GpioA => unsafe { bb::change_bit(&p.scgcgpio, 0, on) },
648 Domain::MicroDma => unsafe { bb::change_bit(&p.scgcdma, 0, on) },
649 Domain::Hibernation => unsafe { bb::change_bit(&p.scgchib, 0, on) },
650 Domain::Uart7 => unsafe { bb::change_bit(&p.scgcuart, 7, on) },
651 Domain::Uart6 => unsafe { bb::change_bit(&p.scgcuart, 6, on) },
652 Domain::Uart5 => unsafe { bb::change_bit(&p.scgcuart, 5, on) },
653 Domain::Uart4 => unsafe { bb::change_bit(&p.scgcuart, 4, on) },
654 Domain::Uart3 => unsafe { bb::change_bit(&p.scgcuart, 3, on) },
655 Domain::Uart2 => unsafe { bb::change_bit(&p.scgcuart, 2, on) },
656 Domain::Uart1 => unsafe { bb::change_bit(&p.scgcuart, 1, on) },
657 Domain::Uart0 => unsafe { bb::change_bit(&p.scgcuart, 0, on) },
658 Domain::Ssi3 => unsafe { bb::change_bit(&p.scgcssi, 3, on) },
659 Domain::Ssi2 => unsafe { bb::change_bit(&p.scgcssi, 2, on) },
660 Domain::Ssi1 => unsafe { bb::change_bit(&p.scgcssi, 1, on) },
661 Domain::Ssi0 => unsafe { bb::change_bit(&p.scgcssi, 0, on) },
662 Domain::I2c3 => unsafe { bb::change_bit(&p.scgci2c, 3, on) },
663 Domain::I2c2 => unsafe { bb::change_bit(&p.scgci2c, 2, on) },
664 Domain::I2c1 => unsafe { bb::change_bit(&p.scgci2c, 1, on) },
665 Domain::I2c0 => unsafe { bb::change_bit(&p.scgci2c, 0, on) },
666 Domain::Usb => unsafe { bb::change_bit(&p.scgcusb, 0, on) },
667 Domain::Can => unsafe { bb::change_bit(&p.scgccan, 0, on) },
668 Domain::Adc1 => unsafe { bb::change_bit(&p.scgcadc, 1, on) },
669 Domain::Adc0 => unsafe { bb::change_bit(&p.scgcadc, 0, on) },
670 Domain::AnalogComparator => unsafe { bb::change_bit(&p.scgcacmp, 0, on) },
671 Domain::Eeprom => unsafe { bb::change_bit(&p.scgceeprom, 0, on) },
672 Domain::Pwm0 => unsafe { bb::change_bit(&p.scgcpwm, 0, on) },
673 Domain::Pwm1 => unsafe { bb::change_bit(&p.scgcpwm, 1, on) },
674 Domain::Emac0 => unsafe { bb::change_bit(&p.scgcemac, 0, on) },
675 Domain::Ephy0 => unsafe { bb::change_bit(&p.scgcephy, 0, on) },
676 }
677}
678
679fn control_deep_sleep_power(pd: Domain, on: bool) {
680 let p = unsafe { &*tm4c129x::SYSCTL::ptr() };
682 match pd {
683 Domain::Watchdog1 => unsafe { bb::change_bit(&p.dcgcwd, 1, on) },
684 Domain::Watchdog0 => unsafe { bb::change_bit(&p.dcgcwd, 0, on) },
685 Domain::Timer5 => unsafe { bb::change_bit(&p.dcgctimer, 5, on) },
686 Domain::Timer4 => unsafe { bb::change_bit(&p.dcgctimer, 4, on) },
687 Domain::Timer3 => unsafe { bb::change_bit(&p.dcgctimer, 3, on) },
688 Domain::Timer2 => unsafe { bb::change_bit(&p.dcgctimer, 2, on) },
689 Domain::Timer1 => unsafe { bb::change_bit(&p.dcgctimer, 1, on) },
690 Domain::Timer0 => unsafe { bb::change_bit(&p.dcgctimer, 0, on) },
691 Domain::GpioQ => unsafe { bb::change_bit(&p.dcgcgpio, 14, on) },
692 Domain::GpioP => unsafe { bb::change_bit(&p.dcgcgpio, 13, on) },
693 Domain::GpioN => unsafe { bb::change_bit(&p.dcgcgpio, 12, on) },
694 Domain::GpioM => unsafe { bb::change_bit(&p.dcgcgpio, 11, on) },
695 Domain::GpioL => unsafe { bb::change_bit(&p.dcgcgpio, 10, on) },
696 Domain::GpioK => unsafe { bb::change_bit(&p.dcgcgpio, 9, on) },
697 Domain::GpioJ => unsafe { bb::change_bit(&p.dcgcgpio, 8, on) },
698 Domain::GpioH => unsafe { bb::change_bit(&p.dcgcgpio, 7, on) },
699 Domain::GpioG => unsafe { bb::change_bit(&p.dcgcgpio, 6, on) },
700 Domain::GpioF => unsafe { bb::change_bit(&p.dcgcgpio, 5, on) },
701 Domain::GpioE => unsafe { bb::change_bit(&p.dcgcgpio, 4, on) },
702 Domain::GpioD => unsafe { bb::change_bit(&p.dcgcgpio, 3, on) },
703 Domain::GpioC => unsafe { bb::change_bit(&p.dcgcgpio, 2, on) },
704 Domain::GpioB => unsafe { bb::change_bit(&p.dcgcgpio, 1, on) },
705 Domain::GpioA => unsafe { bb::change_bit(&p.dcgcgpio, 0, on) },
706 Domain::MicroDma => unsafe { bb::change_bit(&p.dcgcdma, 0, on) },
707 Domain::Hibernation => unsafe { bb::change_bit(&p.dcgchib, 0, on) },
708 Domain::Uart7 => unsafe { bb::change_bit(&p.dcgcuart, 7, on) },
709 Domain::Uart6 => unsafe { bb::change_bit(&p.dcgcuart, 6, on) },
710 Domain::Uart5 => unsafe { bb::change_bit(&p.dcgcuart, 5, on) },
711 Domain::Uart4 => unsafe { bb::change_bit(&p.dcgcuart, 4, on) },
712 Domain::Uart3 => unsafe { bb::change_bit(&p.dcgcuart, 3, on) },
713 Domain::Uart2 => unsafe { bb::change_bit(&p.dcgcuart, 2, on) },
714 Domain::Uart1 => unsafe { bb::change_bit(&p.dcgcuart, 1, on) },
715 Domain::Uart0 => unsafe { bb::change_bit(&p.dcgcuart, 0, on) },
716 Domain::Ssi3 => unsafe { bb::change_bit(&p.dcgcssi, 3, on) },
717 Domain::Ssi2 => unsafe { bb::change_bit(&p.dcgcssi, 2, on) },
718 Domain::Ssi1 => unsafe { bb::change_bit(&p.dcgcssi, 1, on) },
719 Domain::Ssi0 => unsafe { bb::change_bit(&p.dcgcssi, 0, on) },
720 Domain::I2c3 => unsafe { bb::change_bit(&p.dcgci2c, 3, on) },
721 Domain::I2c2 => unsafe { bb::change_bit(&p.dcgci2c, 2, on) },
722 Domain::I2c1 => unsafe { bb::change_bit(&p.dcgci2c, 1, on) },
723 Domain::I2c0 => unsafe { bb::change_bit(&p.dcgci2c, 0, on) },
724 Domain::Usb => unsafe { bb::change_bit(&p.dcgcusb, 0, on) },
725 Domain::Can => unsafe { bb::change_bit(&p.dcgccan, 0, on) },
726 Domain::Adc1 => unsafe { bb::change_bit(&p.dcgcadc, 1, on) },
727 Domain::Adc0 => unsafe { bb::change_bit(&p.dcgcadc, 0, on) },
728 Domain::AnalogComparator => unsafe { bb::change_bit(&p.dcgcacmp, 0, on) },
729 Domain::Eeprom => unsafe { bb::change_bit(&p.dcgceeprom, 0, on) },
730 Domain::Pwm0 => unsafe { bb::change_bit(&p.dcgcpwm, 0, on) },
731 Domain::Pwm1 => unsafe { bb::change_bit(&p.dcgcpwm, 1, on) },
732 Domain::Emac0 => unsafe { bb::change_bit(&p.dcgcemac, 0, on) },
733 Domain::Ephy0 => unsafe { bb::change_bit(&p.dcgcephy, 0, on) },
734 }
735}
736
737pub trait SysctlExt {
739 fn constrain(self) -> Sysctl;
742}
743
744impl SysctlExt for tm4c129x::SYSCTL {
745 fn constrain(self) -> Sysctl {
746 Sysctl {
747 power_control: PowerControl {},
748 clock_setup: ClockSetup {
749 oscillator: Oscillator::PrecisionInternal(SystemClock::UseOscillator(Divider::_1)),
750 },
751 }
752 }
753}
754
755impl ClockSetup {
756 pub fn freeze(self) -> Clocks {
759 let p = unsafe { &*tm4c129x::SYSCTL::ptr() };
761
762 let osc: Hertz;
763 let sysclk: Hertz;
764
765 match self.oscillator {
766 Oscillator::PrecisionInternal(SystemClock::UseOscillator(div)) => {
768 osc = 16_000_000.hz();
770 sysclk = (osc.0 / (div as u32)).hz();
771
772 p.rsclkcfg.modify(|_, w| {
773 w.osysdiv().bits(div as u16 - 1);
774
775 w
776 });
777 }
778 Oscillator::PrecisionInternal(SystemClock::UsePll(output_frequency)) => {
779 osc = 16_000_000.hz();
780 sysclk = output_frequency.into();
781
782 p.rsclkcfg.modify(|_, w| w.pllsrc().piosc());
787
788 p.pllfreq0.modify(|_, w| {
789 w.pllpwr().set_bit();
790
791 w.mfrac().bits(0);
792 w.mint().bits(30);
793
794 w
795 });
796
797 p.pllfreq1.modify(|_, w| {
798 w.q().bits(0);
799 w.n().bits(0);
800
801 w
802 });
803
804 p.rsclkcfg.modify(|_, w| w.newfreq().set_bit());
805
806 let (xbcht, xbce, xws) = match sysclk.0 {
807 f if f <= 16_000_000 => (0, true, 0),
808 f if f <= 40_000_000 => (2, false, 1),
809 f if f <= 60_000_000 => (3, false, 2),
810 f if f <= 80_000_000 => (4, false, 3),
811 f if f <= 100_000_000 => (5, false, 4),
812 f if f <= 120_000_000 => (6, false, 5),
813 _ => unreachable!(),
814 };
815
816 p.memtim0.modify(|_, w| {
818 unsafe {
819 w.fbcht().bits(xbcht);
820 w.ebcht().bits(xbcht);
821
822 w.fbce().bit(xbce);
823 w.ebce().bit(xbce);
824
825 w.fws().bits(xws);
826 w.ews().bits(xws);
827 }
828
829 w
830 });
831
832 while p.pllstat.read().lock().bit_is_clear() {
837 cortex_m::asm::nop();
838 }
839
840 p.rsclkcfg.modify(|_, w| {
843 w.usepll().set_bit();
844 w.memtimu().set_bit();
845 w.psysdiv().bits((480_000_000 / sysclk.0 - 1) as u16);
846
847 w
848 });
849 }
850
851 Oscillator::Main(crystal_frequency, SystemClock::UseOscillator(div)) => {
852 osc = crystal_frequency.into();
853 sysclk = (osc.0 / (div as u32)).hz();
854
855 p.moscctl.modify(|_, w| {
857 w.oscrng().set_bit();
858
859 w.noxtal().clear_bit();
860 w.pwrdn().clear_bit();
861
862 w
863 });
864
865 let (xbcht, xbce, xws) = match sysclk.0 {
866 f if f < 16_000_000 => (0, true, 0),
867 f if f < 40_000_000 => (2, false, 1),
868 _ => unreachable!(),
869 };
870
871 p.memtim0.modify(|_, w| {
873 unsafe {
874 w.fbcht().bits(xbcht);
875 w.ebcht().bits(xbcht);
876
877 w.fbce().bit(xbce);
878 w.ebce().bit(xbce);
879
880 w.fws().bits(xws);
881 w.ews().bits(xws);
882 }
883
884 w
885 });
886
887 while p.ris.read().moscpupris().bit_is_clear() {
891 cortex_m::asm::nop();
892 }
893
894 p.rsclkcfg.modify(|_, w| {
896 w.oscsrc().mosc();
897 w.memtimu().set_bit();
898
899 w.osysdiv().bits(div as u16 - 1);
900
901 w
902 });
903 }
904
905 Oscillator::Main(crystal_frequency, SystemClock::UsePll(output_frequency)) => {
906 osc = crystal_frequency.into();
907 sysclk = output_frequency.into();
908
909 p.moscctl.modify(|_, w| {
911 w.oscrng().set_bit();
912
913 w.noxtal().clear_bit();
914 w.pwrdn().clear_bit();
915
916 w
917 });
918
919 while p.ris.read().moscpupris().bit_is_clear() {
923 cortex_m::asm::nop();
924 }
925
926 p.rsclkcfg.modify(|_, w| w.pllsrc().mosc());
931
932 p.pllfreq1.modify(|_, w| {
933 w.q().bits(0);
934 w.n().bits(4);
935
936 w
937 });
938
939 p.pllfreq0.modify(|_, w| {
940 w.mfrac().bits(0);
941 w.mint().bits(96);
942
943 w
944 });
945
946 p.pllfreq0.modify(|_, w| w.pllpwr().set_bit());
947
948 while p.pllstat.read().lock().bit_is_clear() {
954 cortex_m::asm::nop();
955 }
956
957 let (xbcht, xbce, xws) = match sysclk.0 {
958 f if f <= 16_000_000 => (0, true, 0),
959 f if f <= 40_000_000 => (2, false, 1),
960 f if f <= 60_000_000 => (3, false, 2),
961 f if f <= 80_000_000 => (4, false, 3),
962 f if f <= 100_000_000 => (5, false, 4),
963 f if f <= 120_000_000 => (6, false, 5),
964 _ => unreachable!(),
965 };
966
967 p.memtim0.modify(|_, w| {
969 unsafe {
970 w.fbcht().bits(xbcht);
971 w.ebcht().bits(xbcht);
972
973 w.fbce().bit(xbce);
974 w.ebce().bit(xbce);
975
976 w.fws().bits(xws);
977 w.ews().bits(xws);
978 }
979
980 w
981 });
982
983 p.rsclkcfg.modify(|_, w| {
986 w.usepll().set_bit();
987 w.memtimu().set_bit();
988 w.psysdiv().bits((480_000_000 / sysclk.0 - 1) as u16);
989
990 w
991 });
992 }
993
994 Oscillator::LowFrequencyInternal(_div) => unimplemented!(),
995 }
996
997 Clocks { osc, sysclk }
998 }
999}
1000
1001impl PowerControl {}
1002
1003pub mod chip_id {
1005 pub use tm4c_hal::sysctl::chip_id::*;
1006
1007 pub fn get() -> Result<ChipId, Error> {
1010 let p = unsafe { &*tm4c129x::SYSCTL::ptr() };
1012 let did0 = p.did0.read();
1013 if did0.ver().bits() != 0x01 {
1014 return Err(Error::UnknownDid0Ver(did0.ver().bits()));
1015 }
1016 let device_class = match did0.class().bits() {
1017 0x05 => DeviceClass::StellarisBlizzard,
1018 0x0a => DeviceClass::Snowflake,
1019 _ => DeviceClass::Unknown,
1020 };
1021 let major = did0.maj().bits();
1022 let minor = did0.min().bits();
1023 let did1 = p.did1.read();
1024 if did1.ver().bits() != 0x01 {
1025 return Err(Error::UnknownDid1Ver(did1.ver().bits()));
1027 }
1028 let part_no = match did1.prtno().bits() {
1029 0x1F => PartNo::Tm4c1294ncpdt,
1030 45 => PartNo::Tm4c129encpdt,
1031 e => PartNo::Unknown(e),
1032 };
1033 let pin_count = match did1.pincnt().bits() {
1034 0 => PinCount::_28,
1035 1 => PinCount::_48,
1036 2 => PinCount::_100,
1037 3 => PinCount::_64,
1038 4 => PinCount::_144,
1039 5 => PinCount::_157,
1040 6 => PinCount::_168,
1041 _ => PinCount::Unknown,
1042 };
1043 let temp_range = match did1.temp().bits() {
1044 0 => TempRange::Commercial,
1045 1 => TempRange::Industrial,
1046 2 => TempRange::Extended,
1047 3 => TempRange::IndustrialOrExtended,
1048 _ => TempRange::Unknown,
1049 };
1050 let package = match did1.pkg().bits() {
1051 0 => Package::Soic,
1052 1 => Package::Lqfp,
1053 2 => Package::Bga,
1054 _ => Package::Unknown,
1055 };
1056 let rohs_compliant = did1.rohs().bit_is_set();
1057 let qualification = match did1.qual().bits() {
1058 0 => Qualification::EngineeringSample,
1059 1 => Qualification::PilotProduction,
1060 2 => Qualification::FullyQualified,
1061 _ => Qualification::Unknown,
1062 };
1063 Ok(ChipId {
1064 device_class,
1065 major,
1066 minor,
1067 pin_count,
1068 temp_range,
1069 package,
1070 rohs_compliant,
1071 qualification,
1072 part_no,
1073 })
1074 }
1075}
1076
1077