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),
57 PrecisionInternal(SystemClock),
59 PrecisionInternalDiv4(Divider),
62 LowFrequencyInternal(Divider),
64}
65
66#[derive(Clone, Copy)]
68pub enum SystemClock {
69 UseOscillator(Divider),
71 UsePll(PllOutputFrequency),
74}
75
76#[derive(Clone, Copy)]
78pub enum CrystalFrequency {
79 _4mhz,
81 _4_09mhz,
83 _4_91mhz,
85 _5mhz,
87 _5_12mhz,
89 _6mhz,
91 _6_14mhz,
93 _7_37mhz,
95 _8mhz,
97 _8_19mhz,
99 _10mhz,
101 _12mhz,
103 _12_2mhz,
105 _13_5mhz,
107 _14_3mhz,
109 _16mhz,
111 _16_3mhz,
113 _18mhz,
115 _20mhz,
117 _24mhz,
119 _25mhz,
121}
122
123impl Into<Hertz> for CrystalFrequency {
124 fn into(self) -> Hertz {
125 Hertz(match self {
126 CrystalFrequency::_4mhz => 4_000_000,
127 CrystalFrequency::_4_09mhz => 4_090_000,
128 CrystalFrequency::_4_91mhz => 4_910_000,
129 CrystalFrequency::_5mhz => 5_000_000,
130 CrystalFrequency::_5_12mhz => 5_120_000,
131 CrystalFrequency::_6mhz => 6_000_000,
132 CrystalFrequency::_6_14mhz => 6_140_000,
133 CrystalFrequency::_7_37mhz => 7_370_000,
134 CrystalFrequency::_8mhz => 8_000_000,
135 CrystalFrequency::_8_19mhz => 8_190_000,
136 CrystalFrequency::_10mhz => 10_000_000,
137 CrystalFrequency::_12mhz => 12_000_000,
138 CrystalFrequency::_12_2mhz => 12_200_000,
139 CrystalFrequency::_13_5mhz => 13_500_000,
140 CrystalFrequency::_14_3mhz => 14_300_000,
141 CrystalFrequency::_16mhz => 16_000_000,
142 CrystalFrequency::_16_3mhz => 16_300_000,
143 CrystalFrequency::_18mhz => 18_000_000,
144 CrystalFrequency::_20mhz => 20_000_000,
145 CrystalFrequency::_24mhz => 24_000_000,
146 CrystalFrequency::_25mhz => 25_000_000,
147 })
148 }
149}
150
151#[derive(Clone, Copy)]
153pub enum PllOutputFrequency {
154 _80_00mhz = 0,
156 _66_67mhz = 2,
158 _50_00mhz = 3,
160 _40_00mhz = 4,
162 _33_33mhz = 5,
164 _28_57mhz = 6,
166 _25mhz = 7,
168 _22_22mhz = 8,
170 _20mhz = 9,
172 _18_18mhz = 10,
174 _16_67mhz = 11,
176 _15_38mhz = 12,
178 _14_29mhz = 13,
180 _13_33mhz = 14,
182 _12_5mhz = 15,
184}
185
186impl Into<Hertz> for PllOutputFrequency {
187 fn into(self) -> Hertz {
188 Hertz(match self {
189 PllOutputFrequency::_80_00mhz => 80_000_000,
190 PllOutputFrequency::_66_67mhz => 66_670_000,
191 PllOutputFrequency::_50_00mhz => 50_000_000,
192 PllOutputFrequency::_40_00mhz => 40_000_000,
193 PllOutputFrequency::_33_33mhz => 33_330_000,
194 PllOutputFrequency::_28_57mhz => 28_570_000,
195 PllOutputFrequency::_25mhz => 25_000_000,
196 PllOutputFrequency::_22_22mhz => 22_220_000,
197 PllOutputFrequency::_20mhz => 20_000_000,
198 PllOutputFrequency::_18_18mhz => 18_180_000,
199 PllOutputFrequency::_16_67mhz => 16_670_000,
200 PllOutputFrequency::_15_38mhz => 15_380_000,
201 PllOutputFrequency::_14_29mhz => 14_290_000,
202 PllOutputFrequency::_13_33mhz => 13_330_000,
203 PllOutputFrequency::_12_5mhz => 12_500_000,
204 })
205 }
206}
207
208#[derive(Clone, Copy)]
210pub enum Divider {
211 _1 = 1,
213 _2 = 2,
215 _3 = 3,
217 _4 = 4,
219 _5 = 5,
221 _6 = 6,
223 _7 = 7,
225 _8 = 8,
227 _9 = 9,
229 _10 = 10,
231 _11 = 11,
233 _12 = 12,
235 _13 = 13,
237 _14 = 14,
239 _15 = 15,
241 _16 = 16,
243}
244
245#[derive(Copy, Clone)]
247pub enum Domain {
248 Watchdog1,
250 Watchdog0,
252 Timer5,
254 Timer4,
256 Timer3,
258 Timer2,
260 Timer1,
262 Timer0,
264 GpioF,
266 GpioE,
268 GpioD,
270 GpioC,
272 GpioB,
274 GpioA,
276 MicroDma,
278 Hibernation,
280 Uart7,
282 Uart6,
284 Uart5,
286 Uart4,
288 Uart3,
290 Uart2,
292 Uart1,
294 Uart0,
296 Ssi3,
298 Ssi2,
300 Ssi1,
302 Ssi0,
304 I2c3,
306 I2c2,
308 I2c1,
310 I2c0,
312 Usb,
314 Can,
316 Adc1,
318 Adc0,
320 AnalogComparator,
322 Eeprom,
324 WideTimer5,
326 WideTimer4,
328 WideTimer3,
330 WideTimer2,
332 WideTimer1,
334 WideTimer0,
336 Pwm0,
338 Pwm1,
340}
341
342pub fn reset(_lock: &PowerControl, pd: Domain) {
344 let p = unsafe { &*tm4c123x::SYSCTL::ptr() };
346 match pd {
347 Domain::Watchdog1 => unsafe {
348 bb::toggle_bit(&p.srwd, 1);
349 bb::spin_bit(&p.prwd, 1);
350 },
351 Domain::Watchdog0 => unsafe {
352 bb::toggle_bit(&p.srwd, 0);
353 bb::spin_bit(&p.prwd, 0);
354 },
355 Domain::Timer5 => unsafe {
356 bb::toggle_bit(&p.srtimer, 5);
357 bb::spin_bit(&p.prtimer, 5);
358 },
359 Domain::Timer4 => unsafe {
360 bb::toggle_bit(&p.srtimer, 4);
361 bb::spin_bit(&p.prtimer, 4);
362 },
363 Domain::Timer3 => unsafe {
364 bb::toggle_bit(&p.srtimer, 3);
365 bb::spin_bit(&p.prtimer, 3);
366 },
367 Domain::Timer2 => unsafe {
368 bb::toggle_bit(&p.srtimer, 2);
369 bb::spin_bit(&p.prtimer, 2);
370 },
371 Domain::Timer1 => unsafe {
372 bb::toggle_bit(&p.srtimer, 1);
373 bb::spin_bit(&p.prtimer, 1);
374 },
375 Domain::Timer0 => unsafe {
376 bb::toggle_bit(&p.srtimer, 0);
377 bb::spin_bit(&p.prtimer, 0);
378 },
379 Domain::GpioF => unsafe {
380 bb::toggle_bit(&p.srgpio, 5);
381 bb::spin_bit(&p.prgpio, 5);
382 },
383 Domain::GpioE => unsafe {
384 bb::toggle_bit(&p.srgpio, 4);
385 bb::spin_bit(&p.prgpio, 4);
386 },
387 Domain::GpioD => unsafe {
388 bb::toggle_bit(&p.srgpio, 3);
389 bb::spin_bit(&p.prgpio, 3);
390 },
391 Domain::GpioC => unsafe {
392 bb::toggle_bit(&p.srgpio, 2);
393 bb::spin_bit(&p.prgpio, 2);
394 },
395 Domain::GpioB => unsafe {
396 bb::toggle_bit(&p.srgpio, 1);
397 bb::spin_bit(&p.prgpio, 1);
398 },
399 Domain::GpioA => unsafe {
400 bb::toggle_bit(&p.srgpio, 0);
401 bb::spin_bit(&p.prgpio, 0);
402 },
403 Domain::MicroDma => unsafe {
404 bb::toggle_bit(&p.srdma, 0);
405 bb::spin_bit(&p.prdma, 0);
406 },
407 Domain::Hibernation => unsafe {
408 bb::toggle_bit(&p.srhib, 0);
409 bb::spin_bit(&p.prhib, 0);
410 },
411 Domain::Uart7 => unsafe {
412 bb::toggle_bit(&p.sruart, 7);
413 bb::spin_bit(&p.pruart, 7);
414 },
415 Domain::Uart6 => unsafe {
416 bb::toggle_bit(&p.sruart, 6);
417 bb::spin_bit(&p.pruart, 6);
418 },
419 Domain::Uart5 => unsafe {
420 bb::toggle_bit(&p.sruart, 5);
421 bb::spin_bit(&p.pruart, 5);
422 },
423 Domain::Uart4 => unsafe {
424 bb::toggle_bit(&p.sruart, 4);
425 bb::spin_bit(&p.pruart, 4);
426 },
427 Domain::Uart3 => unsafe {
428 bb::toggle_bit(&p.sruart, 3);
429 bb::spin_bit(&p.pruart, 3);
430 },
431 Domain::Uart2 => unsafe {
432 bb::toggle_bit(&p.sruart, 2);
433 bb::spin_bit(&p.pruart, 2);
434 },
435 Domain::Uart1 => unsafe {
436 bb::toggle_bit(&p.sruart, 1);
437 bb::spin_bit(&p.pruart, 1);
438 },
439 Domain::Uart0 => unsafe {
440 bb::toggle_bit(&p.sruart, 0);
441 bb::spin_bit(&p.pruart, 0);
442 },
443 Domain::Ssi3 => unsafe {
444 bb::toggle_bit(&p.srssi, 3);
445 bb::spin_bit(&p.prssi, 3);
446 },
447 Domain::Ssi2 => unsafe {
448 bb::toggle_bit(&p.srssi, 2);
449 bb::spin_bit(&p.prssi, 2);
450 },
451 Domain::Ssi1 => unsafe {
452 bb::toggle_bit(&p.srssi, 1);
453 bb::spin_bit(&p.prssi, 1);
454 },
455 Domain::Ssi0 => unsafe {
456 bb::toggle_bit(&p.srssi, 0);
457 bb::spin_bit(&p.prssi, 0);
458 },
459 Domain::I2c3 => unsafe {
460 bb::toggle_bit(&p.sri2c, 3);
461 bb::spin_bit(&p.pri2c, 3);
462 },
463 Domain::I2c2 => unsafe {
464 bb::toggle_bit(&p.sri2c, 2);
465 bb::spin_bit(&p.pri2c, 2);
466 },
467 Domain::I2c1 => unsafe {
468 bb::toggle_bit(&p.sri2c, 1);
469 bb::spin_bit(&p.pri2c, 1);
470 },
471 Domain::I2c0 => unsafe {
472 bb::toggle_bit(&p.sri2c, 0);
473 bb::spin_bit(&p.pri2c, 0);
474 },
475 Domain::Usb => unsafe {
476 bb::toggle_bit(&p.srusb, 0);
477 bb::spin_bit(&p.prusb, 0);
478 },
479 Domain::Can => unsafe {
480 bb::toggle_bit(&p.srcan, 0);
481 bb::spin_bit(&p.prcan, 0);
482 },
483 Domain::Adc1 => unsafe {
484 bb::toggle_bit(&p.sradc, 1);
485 bb::spin_bit(&p.pradc, 1);
486 },
487 Domain::Adc0 => unsafe {
488 bb::toggle_bit(&p.sradc, 0);
489 bb::spin_bit(&p.pradc, 0);
490 },
491 Domain::AnalogComparator => unsafe {
492 bb::toggle_bit(&p.sracmp, 0);
493 bb::spin_bit(&p.pracmp, 0);
494 },
495 Domain::Eeprom => unsafe {
496 bb::toggle_bit(&p.sreeprom, 0);
497 bb::spin_bit(&p.preeprom, 0);
498 },
499 Domain::WideTimer5 => unsafe {
500 bb::toggle_bit(&p.srwtimer, 5);
501 bb::spin_bit(&p.prwtimer, 5);
502 },
503 Domain::WideTimer4 => unsafe {
504 bb::toggle_bit(&p.srwtimer, 4);
505 bb::spin_bit(&p.prwtimer, 4);
506 },
507 Domain::WideTimer3 => unsafe {
508 bb::toggle_bit(&p.srwtimer, 3);
509 bb::spin_bit(&p.prwtimer, 3);
510 },
511 Domain::WideTimer2 => unsafe {
512 bb::toggle_bit(&p.srwtimer, 2);
513 bb::spin_bit(&p.prwtimer, 2);
514 },
515 Domain::WideTimer1 => unsafe {
516 bb::toggle_bit(&p.srwtimer, 1);
517 bb::spin_bit(&p.prwtimer, 1);
518 },
519 Domain::WideTimer0 => unsafe {
520 bb::toggle_bit(&p.srwtimer, 0);
521 bb::spin_bit(&p.prwtimer, 0);
522 },
523 Domain::Pwm0 => unsafe {
524 bb::toggle_bit(&p.srpwm, 0);
525 bb::spin_bit(&p.prpwm, 0);
526 },
527 Domain::Pwm1 => unsafe {
528 bb::toggle_bit(&p.srpwm, 1);
529 bb::spin_bit(&p.prpwm, 1);
530 },
531 }
532}
533
534pub fn control_power(_lock: &PowerControl, pd: Domain, run_mode: RunMode, state: PowerState) {
541 let on = match state {
542 PowerState::On => true,
543 PowerState::Off => false,
544 };
545 match run_mode {
546 RunMode::Run => control_run_power(pd, on),
547 RunMode::Sleep => control_sleep_power(pd, on),
548 RunMode::DeepSleep => control_deep_sleep_power(pd, on),
549 }
550 nop();
554 nop();
555 nop();
556}
557
558fn control_run_power(pd: Domain, on: bool) {
559 let p = unsafe { &*tm4c123x::SYSCTL::ptr() };
561 match pd {
562 Domain::Watchdog1 => unsafe { bb::change_bit(&p.rcgcwd, 1, on) },
563 Domain::Watchdog0 => unsafe { bb::change_bit(&p.rcgcwd, 0, on) },
564 Domain::Timer5 => unsafe { bb::change_bit(&p.rcgctimer, 5, on) },
565 Domain::Timer4 => unsafe { bb::change_bit(&p.rcgctimer, 4, on) },
566 Domain::Timer3 => unsafe { bb::change_bit(&p.rcgctimer, 3, on) },
567 Domain::Timer2 => unsafe { bb::change_bit(&p.rcgctimer, 2, on) },
568 Domain::Timer1 => unsafe { bb::change_bit(&p.rcgctimer, 1, on) },
569 Domain::Timer0 => unsafe { bb::change_bit(&p.rcgctimer, 0, on) },
570 Domain::GpioF => unsafe { bb::change_bit(&p.rcgcgpio, 5, on) },
571 Domain::GpioE => unsafe { bb::change_bit(&p.rcgcgpio, 4, on) },
572 Domain::GpioD => unsafe { bb::change_bit(&p.rcgcgpio, 3, on) },
573 Domain::GpioC => unsafe { bb::change_bit(&p.rcgcgpio, 2, on) },
574 Domain::GpioB => unsafe { bb::change_bit(&p.rcgcgpio, 1, on) },
575 Domain::GpioA => unsafe { bb::change_bit(&p.rcgcgpio, 0, on) },
576 Domain::MicroDma => unsafe { bb::change_bit(&p.rcgcdma, 0, on) },
577 Domain::Hibernation => unsafe { bb::change_bit(&p.rcgchib, 0, on) },
578 Domain::Uart7 => unsafe { bb::change_bit(&p.rcgcuart, 7, on) },
579 Domain::Uart6 => unsafe { bb::change_bit(&p.rcgcuart, 6, on) },
580 Domain::Uart5 => unsafe { bb::change_bit(&p.rcgcuart, 5, on) },
581 Domain::Uart4 => unsafe { bb::change_bit(&p.rcgcuart, 4, on) },
582 Domain::Uart3 => unsafe { bb::change_bit(&p.rcgcuart, 3, on) },
583 Domain::Uart2 => unsafe { bb::change_bit(&p.rcgcuart, 2, on) },
584 Domain::Uart1 => unsafe { bb::change_bit(&p.rcgcuart, 1, on) },
585 Domain::Uart0 => unsafe { bb::change_bit(&p.rcgcuart, 0, on) },
586 Domain::Ssi3 => unsafe { bb::change_bit(&p.rcgcssi, 3, on) },
587 Domain::Ssi2 => unsafe { bb::change_bit(&p.rcgcssi, 2, on) },
588 Domain::Ssi1 => unsafe { bb::change_bit(&p.rcgcssi, 1, on) },
589 Domain::Ssi0 => unsafe { bb::change_bit(&p.rcgcssi, 0, on) },
590 Domain::I2c3 => unsafe { bb::change_bit(&p.rcgci2c, 3, on) },
591 Domain::I2c2 => unsafe { bb::change_bit(&p.rcgci2c, 2, on) },
592 Domain::I2c1 => unsafe { bb::change_bit(&p.rcgci2c, 1, on) },
593 Domain::I2c0 => unsafe { bb::change_bit(&p.rcgci2c, 0, on) },
594 Domain::Usb => unsafe { bb::change_bit(&p.rcgcusb, 0, on) },
595 Domain::Can => unsafe { bb::change_bit(&p.rcgccan, 0, on) },
596 Domain::Adc1 => unsafe { bb::change_bit(&p.rcgcadc, 1, on) },
597 Domain::Adc0 => unsafe { bb::change_bit(&p.rcgcadc, 0, on) },
598 Domain::AnalogComparator => unsafe { bb::change_bit(&p.rcgcacmp, 0, on) },
599 Domain::Eeprom => unsafe { bb::change_bit(&p.rcgceeprom, 0, on) },
600 Domain::WideTimer5 => unsafe { bb::change_bit(&p.rcgcwtimer, 5, on) },
601 Domain::WideTimer4 => unsafe { bb::change_bit(&p.rcgcwtimer, 4, on) },
602 Domain::WideTimer3 => unsafe { bb::change_bit(&p.rcgcwtimer, 3, on) },
603 Domain::WideTimer2 => unsafe { bb::change_bit(&p.rcgcwtimer, 2, on) },
604 Domain::WideTimer1 => unsafe { bb::change_bit(&p.rcgcwtimer, 1, on) },
605 Domain::WideTimer0 => unsafe { bb::change_bit(&p.rcgcwtimer, 0, on) },
606 Domain::Pwm0 => unsafe { bb::change_bit(&p.rcgcpwm, 0, on) },
607 Domain::Pwm1 => unsafe { bb::change_bit(&p.rcgcpwm, 1, on) },
608 }
609}
610
611fn control_sleep_power(pd: Domain, on: bool) {
612 let p = unsafe { &*tm4c123x::SYSCTL::ptr() };
614 match pd {
615 Domain::Watchdog1 => unsafe { bb::change_bit(&p.scgcwd, 1, on) },
616 Domain::Watchdog0 => unsafe { bb::change_bit(&p.scgcwd, 0, on) },
617 Domain::Timer5 => unsafe { bb::change_bit(&p.scgctimer, 5, on) },
618 Domain::Timer4 => unsafe { bb::change_bit(&p.scgctimer, 4, on) },
619 Domain::Timer3 => unsafe { bb::change_bit(&p.scgctimer, 3, on) },
620 Domain::Timer2 => unsafe { bb::change_bit(&p.scgctimer, 2, on) },
621 Domain::Timer1 => unsafe { bb::change_bit(&p.scgctimer, 1, on) },
622 Domain::Timer0 => unsafe { bb::change_bit(&p.scgctimer, 0, on) },
623 Domain::GpioF => unsafe { bb::change_bit(&p.scgcgpio, 5, on) },
624 Domain::GpioE => unsafe { bb::change_bit(&p.scgcgpio, 4, on) },
625 Domain::GpioD => unsafe { bb::change_bit(&p.scgcgpio, 3, on) },
626 Domain::GpioC => unsafe { bb::change_bit(&p.scgcgpio, 2, on) },
627 Domain::GpioB => unsafe { bb::change_bit(&p.scgcgpio, 1, on) },
628 Domain::GpioA => unsafe { bb::change_bit(&p.scgcgpio, 0, on) },
629 Domain::MicroDma => unsafe { bb::change_bit(&p.scgcdma, 0, on) },
630 Domain::Hibernation => unsafe { bb::change_bit(&p.scgchib, 0, on) },
631 Domain::Uart7 => unsafe { bb::change_bit(&p.scgcuart, 7, on) },
632 Domain::Uart6 => unsafe { bb::change_bit(&p.scgcuart, 6, on) },
633 Domain::Uart5 => unsafe { bb::change_bit(&p.scgcuart, 5, on) },
634 Domain::Uart4 => unsafe { bb::change_bit(&p.scgcuart, 4, on) },
635 Domain::Uart3 => unsafe { bb::change_bit(&p.scgcuart, 3, on) },
636 Domain::Uart2 => unsafe { bb::change_bit(&p.scgcuart, 2, on) },
637 Domain::Uart1 => unsafe { bb::change_bit(&p.scgcuart, 1, on) },
638 Domain::Uart0 => unsafe { bb::change_bit(&p.scgcuart, 0, on) },
639 Domain::Ssi3 => unsafe { bb::change_bit(&p.scgcssi, 3, on) },
640 Domain::Ssi2 => unsafe { bb::change_bit(&p.scgcssi, 2, on) },
641 Domain::Ssi1 => unsafe { bb::change_bit(&p.scgcssi, 1, on) },
642 Domain::Ssi0 => unsafe { bb::change_bit(&p.scgcssi, 0, on) },
643 Domain::I2c3 => unsafe { bb::change_bit(&p.scgci2c, 3, on) },
644 Domain::I2c2 => unsafe { bb::change_bit(&p.scgci2c, 2, on) },
645 Domain::I2c1 => unsafe { bb::change_bit(&p.scgci2c, 1, on) },
646 Domain::I2c0 => unsafe { bb::change_bit(&p.scgci2c, 0, on) },
647 Domain::Usb => unsafe { bb::change_bit(&p.scgcusb, 0, on) },
648 Domain::Can => unsafe { bb::change_bit(&p.scgccan, 0, on) },
649 Domain::Adc1 => unsafe { bb::change_bit(&p.scgcadc, 1, on) },
650 Domain::Adc0 => unsafe { bb::change_bit(&p.scgcadc, 0, on) },
651 Domain::AnalogComparator => unsafe { bb::change_bit(&p.scgcacmp, 0, on) },
652 Domain::Eeprom => unsafe { bb::change_bit(&p.scgceeprom, 0, on) },
653 Domain::WideTimer5 => unsafe { bb::change_bit(&p.scgcwtimer, 5, on) },
654 Domain::WideTimer4 => unsafe { bb::change_bit(&p.scgcwtimer, 4, on) },
655 Domain::WideTimer3 => unsafe { bb::change_bit(&p.scgcwtimer, 3, on) },
656 Domain::WideTimer2 => unsafe { bb::change_bit(&p.scgcwtimer, 2, on) },
657 Domain::WideTimer1 => unsafe { bb::change_bit(&p.scgcwtimer, 1, on) },
658 Domain::WideTimer0 => unsafe { bb::change_bit(&p.scgcwtimer, 0, on) },
659 Domain::Pwm0 => unsafe { bb::change_bit(&p.scgcpwm, 0, on) },
660 Domain::Pwm1 => unsafe { bb::change_bit(&p.scgcpwm, 1, on) },
661 }
662}
663
664fn control_deep_sleep_power(pd: Domain, on: bool) {
665 let p = unsafe { &*tm4c123x::SYSCTL::ptr() };
667 match pd {
668 Domain::Watchdog1 => unsafe { bb::change_bit(&p.dcgcwd, 1, on) },
669 Domain::Watchdog0 => unsafe { bb::change_bit(&p.dcgcwd, 0, on) },
670 Domain::Timer5 => unsafe { bb::change_bit(&p.dcgctimer, 5, on) },
671 Domain::Timer4 => unsafe { bb::change_bit(&p.dcgctimer, 4, on) },
672 Domain::Timer3 => unsafe { bb::change_bit(&p.dcgctimer, 3, on) },
673 Domain::Timer2 => unsafe { bb::change_bit(&p.dcgctimer, 2, on) },
674 Domain::Timer1 => unsafe { bb::change_bit(&p.dcgctimer, 1, on) },
675 Domain::Timer0 => unsafe { bb::change_bit(&p.dcgctimer, 0, on) },
676 Domain::GpioF => unsafe { bb::change_bit(&p.dcgcgpio, 5, on) },
677 Domain::GpioE => unsafe { bb::change_bit(&p.dcgcgpio, 4, on) },
678 Domain::GpioD => unsafe { bb::change_bit(&p.dcgcgpio, 3, on) },
679 Domain::GpioC => unsafe { bb::change_bit(&p.dcgcgpio, 2, on) },
680 Domain::GpioB => unsafe { bb::change_bit(&p.dcgcgpio, 1, on) },
681 Domain::GpioA => unsafe { bb::change_bit(&p.dcgcgpio, 0, on) },
682 Domain::MicroDma => unsafe { bb::change_bit(&p.dcgcdma, 0, on) },
683 Domain::Hibernation => unsafe { bb::change_bit(&p.dcgchib, 0, on) },
684 Domain::Uart7 => unsafe { bb::change_bit(&p.dcgcuart, 7, on) },
685 Domain::Uart6 => unsafe { bb::change_bit(&p.dcgcuart, 6, on) },
686 Domain::Uart5 => unsafe { bb::change_bit(&p.dcgcuart, 5, on) },
687 Domain::Uart4 => unsafe { bb::change_bit(&p.dcgcuart, 4, on) },
688 Domain::Uart3 => unsafe { bb::change_bit(&p.dcgcuart, 3, on) },
689 Domain::Uart2 => unsafe { bb::change_bit(&p.dcgcuart, 2, on) },
690 Domain::Uart1 => unsafe { bb::change_bit(&p.dcgcuart, 1, on) },
691 Domain::Uart0 => unsafe { bb::change_bit(&p.dcgcuart, 0, on) },
692 Domain::Ssi3 => unsafe { bb::change_bit(&p.dcgcssi, 3, on) },
693 Domain::Ssi2 => unsafe { bb::change_bit(&p.dcgcssi, 2, on) },
694 Domain::Ssi1 => unsafe { bb::change_bit(&p.dcgcssi, 1, on) },
695 Domain::Ssi0 => unsafe { bb::change_bit(&p.dcgcssi, 0, on) },
696 Domain::I2c3 => unsafe { bb::change_bit(&p.dcgci2c, 3, on) },
697 Domain::I2c2 => unsafe { bb::change_bit(&p.dcgci2c, 2, on) },
698 Domain::I2c1 => unsafe { bb::change_bit(&p.dcgci2c, 1, on) },
699 Domain::I2c0 => unsafe { bb::change_bit(&p.dcgci2c, 0, on) },
700 Domain::Usb => unsafe { bb::change_bit(&p.dcgcusb, 0, on) },
701 Domain::Can => unsafe { bb::change_bit(&p.dcgccan, 0, on) },
702 Domain::Adc1 => unsafe { bb::change_bit(&p.dcgcadc, 1, on) },
703 Domain::Adc0 => unsafe { bb::change_bit(&p.dcgcadc, 0, on) },
704 Domain::AnalogComparator => unsafe { bb::change_bit(&p.dcgcacmp, 0, on) },
705 Domain::Eeprom => unsafe { bb::change_bit(&p.dcgceeprom, 0, on) },
706 Domain::WideTimer5 => unsafe { bb::change_bit(&p.dcgcwtimer, 5, on) },
707 Domain::WideTimer4 => unsafe { bb::change_bit(&p.dcgcwtimer, 4, on) },
708 Domain::WideTimer3 => unsafe { bb::change_bit(&p.dcgcwtimer, 3, on) },
709 Domain::WideTimer2 => unsafe { bb::change_bit(&p.dcgcwtimer, 2, on) },
710 Domain::WideTimer1 => unsafe { bb::change_bit(&p.dcgcwtimer, 1, on) },
711 Domain::WideTimer0 => unsafe { bb::change_bit(&p.dcgcwtimer, 0, on) },
712 Domain::Pwm0 => unsafe { bb::change_bit(&p.dcgcpwm, 0, on) },
713 Domain::Pwm1 => unsafe { bb::change_bit(&p.dcgcpwm, 1, on) },
714 }
715}
716
717pub trait SysctlExt {
719 fn constrain(self) -> Sysctl;
721}
722
723impl SysctlExt for tm4c123x::SYSCTL {
724 fn constrain(self) -> Sysctl {
725 Sysctl {
726 power_control: PowerControl {},
727 clock_setup: ClockSetup {
728 oscillator: Oscillator::PrecisionInternal(SystemClock::UseOscillator(Divider::_1)),
729 },
730 }
731 }
732}
733
734impl ClockSetup {
735 pub fn freeze(self) -> Clocks {
738 let p = unsafe { &*tm4c123x::SYSCTL::ptr() };
740
741 let mut osc = 0u32;
742 let mut sysclk = 0u32;
743
744 match self.oscillator {
745 Oscillator::Main(crystal_frequency, system_clock) => {
746 p.rcc.write(|w| {
747 w.bypass().set_bit();
749 w.oscsrc().main();
751 w.moscdis().clear_bit();
753 unsafe {
755 w.sysdiv().bits(0x00);
756 }
757 osc = match crystal_frequency {
759 CrystalFrequency::_4mhz => {
760 w.xtal()._4mhz();
761 4_000_000
762 }
763 CrystalFrequency::_4_09mhz => {
764 w.xtal()._4_09mhz();
765 4_090_000
766 }
767 CrystalFrequency::_4_91mhz => {
768 w.xtal()._4_91mhz();
769 4_910_000
770 }
771 CrystalFrequency::_5mhz => {
772 w.xtal()._5mhz();
773 5_000_000
774 }
775 CrystalFrequency::_5_12mhz => {
776 w.xtal()._5_12mhz();
777 5_120_000
778 }
779 CrystalFrequency::_6mhz => {
780 w.xtal()._6mhz();
781 6_000_000
782 }
783 CrystalFrequency::_6_14mhz => {
784 w.xtal()._6_14mhz();
785 6_140_000
786 }
787 CrystalFrequency::_7_37mhz => {
788 w.xtal()._7_37mhz();
789 7_370_000
790 }
791 CrystalFrequency::_8mhz => {
792 w.xtal()._8mhz();
793 8_000_000
794 }
795 CrystalFrequency::_8_19mhz => {
796 w.xtal()._8_19mhz();
797 8_190_000
798 }
799 CrystalFrequency::_10mhz => {
800 w.xtal()._10mhz();
801 10_000_000
802 }
803 CrystalFrequency::_12mhz => {
804 w.xtal()._12mhz();
805 12_000_000
806 }
807 CrystalFrequency::_12_2mhz => {
808 w.xtal()._12_2mhz();
809 12_200_000
810 }
811 CrystalFrequency::_13_5mhz => {
812 w.xtal()._13_5mhz();
813 13_500_000
814 }
815 CrystalFrequency::_14_3mhz => {
816 w.xtal()._14_3mhz();
817 14_300_000
818 }
819 CrystalFrequency::_16mhz => {
820 w.xtal()._16mhz();
821 16_000_000
822 }
823 CrystalFrequency::_16_3mhz => {
824 w.xtal()._16_3mhz();
825 16_300_000
826 }
827 CrystalFrequency::_18mhz => {
828 w.xtal()._18mhz();
829 18_000_000
830 }
831 CrystalFrequency::_20mhz => {
832 w.xtal()._20mhz();
833 20_000_000
834 }
835 CrystalFrequency::_24mhz => {
836 w.xtal()._24mhz();
837 24_000_000
838 }
839 CrystalFrequency::_25mhz => {
840 w.xtal()._25mhz();
841 25_000_000
842 }
843 };
844 if let SystemClock::UseOscillator(div) = system_clock {
845 w.usesysdiv().set_bit();
846 unsafe {
847 w.sysdiv().bits(div as u8 - 1);
848 }
849 sysclk = osc / (div as u32);
850 } else {
851 w.usesysdiv().clear_bit();
853 unsafe {
854 w.sysdiv().bits(0);
855 }
856 sysclk = osc;
857 }
858 w
859 });
860 }
861 Oscillator::PrecisionInternal(system_clock) => {
863 osc = 16_000_000;
864 p.rcc.write(|w| {
865 w.bypass().set_bit();
867 w.oscsrc().int();
869 w.moscdis().set_bit();
871 if let SystemClock::UseOscillator(div) = system_clock {
873 w.usesysdiv().set_bit();
874 unsafe {
875 w.sysdiv().bits(div as u8 - 1);
876 }
877 sysclk = osc / (div as u32);
878 } else {
879 w.usesysdiv().clear_bit();
881 unsafe {
882 w.sysdiv().bits(0);
883 }
884 sysclk = osc;
885 }
886 w
887 });
888 }
889 Oscillator::PrecisionInternalDiv4(div) => {
890 osc = 4_000_000;
891 p.rcc.write(|w| {
892 w.bypass().set_bit();
894 w.oscsrc().int4();
896 w.moscdis().set_bit();
898 w.usesysdiv().set_bit();
899 unsafe {
900 w.sysdiv().bits(div as u8 - 1);
901 }
902 sysclk = osc / (div as u32);
903 w
904 });
905 }
906 Oscillator::LowFrequencyInternal(div) => {
907 osc = 30_000;
908 p.rcc.write(|w| {
909 w.bypass().set_bit();
911 w.oscsrc()._30();
913 w.moscdis().set_bit();
915 w.usesysdiv().set_bit();
916 unsafe {
917 w.sysdiv().bits(div as u8 - 1);
918 }
919 sysclk = osc / (div as u32);
920 w
921 });
922 }
923 }
924
925 match self.oscillator {
926 Oscillator::PrecisionInternal(SystemClock::UsePll(f))
927 | Oscillator::Main(_, SystemClock::UsePll(f)) => {
928 p.misc.write(|w| w.plllmis().set_bit());
933
934 p.rcc.modify(|_, w| w.pwrdn().clear_bit());
936
937 while p.pllstat.read().lock().bit_is_clear() {
938 nop();
939 }
940
941 match f {
942 PllOutputFrequency::_80_00mhz => {
944 p.rcc2.write(|w| {
945 w.usercc2().set_bit();
946 w.div400().set_bit();
948 w.sysdiv2lsb().clear_bit();
950 unsafe { w.sysdiv2().bits(2) };
951 w.bypass2().clear_bit();
952 w
953 });
954 sysclk = 400_000_000u32 / 5;
955 }
956 _ => {
957 p.rcc.modify(|_, w| {
959 unsafe { w.sysdiv().bits(f as u8) };
960 w.usesysdiv().set_bit();
961 w.bypass().clear_bit();
962 w
963 });
964 sysclk = 400_000_000u32 / (2 * ((f as u32) + 1));
965 }
966 }
967 }
968 _ => {}
969 }
970
971 Clocks {
972 osc: osc.hz(),
973 sysclk: sysclk.hz(),
974 }
975 }
976}
977
978impl PowerControl {}
979
980pub mod chip_id {
982 pub use tm4c_hal::sysctl::chip_id::*;
983
984 pub fn get() -> Result<ChipId, Error> {
987 let p = unsafe { &*tm4c123x::SYSCTL::ptr() };
989 let did0 = p.did0.read();
990 if did0.ver().bits() != 0x01 {
991 return Err(Error::UnknownDid0Ver(did0.ver().bits()));
992 }
993 let device_class = match did0.class().bits() {
994 0x05 => DeviceClass::StellarisBlizzard,
995 0x0a => DeviceClass::Snowflake,
996 _ => DeviceClass::Unknown,
997 };
998 let major = did0.maj().bits();
999 let minor = did0.min().bits();
1000 let did1 = p.did1.read();
1001 if did1.ver().bits() != 0x01 {
1002 return Err(Error::UnknownDid1Ver(did1.ver().bits()));
1004 }
1005 let part_no = match did1.prtno().bits() {
1006 0x04 => PartNo::Lm4f120h5qr,
1007 0xA1 => PartNo::Tm4c123gh6pm,
1008 e => PartNo::Unknown(e),
1009 };
1010 let pin_count = match did1.pincnt().bits() {
1011 0 => PinCount::_28,
1012 1 => PinCount::_48,
1013 2 => PinCount::_100,
1014 3 => PinCount::_64,
1015 4 => PinCount::_144,
1016 5 => PinCount::_157,
1017 6 => PinCount::_168,
1018 _ => PinCount::Unknown,
1019 };
1020 let temp_range = match did1.temp().bits() {
1021 0 => TempRange::Commercial,
1022 1 => TempRange::Industrial,
1023 2 => TempRange::Extended,
1024 3 => TempRange::IndustrialOrExtended,
1025 _ => TempRange::Unknown,
1026 };
1027 let package = match did1.pkg().bits() {
1028 0 => Package::Soic,
1029 1 => Package::Lqfp,
1030 2 => Package::Bga,
1031 _ => Package::Unknown,
1032 };
1033 let rohs_compliant = did1.rohs().bit_is_set();
1034 let qualification = match did1.qual().bits() {
1035 0 => Qualification::EngineeringSample,
1036 1 => Qualification::PilotProduction,
1037 2 => Qualification::FullyQualified,
1038 _ => Qualification::Unknown,
1039 };
1040 Ok(ChipId {
1041 device_class,
1042 major,
1043 minor,
1044 pin_count,
1045 temp_range,
1046 package,
1047 rohs_compliant,
1048 qualification,
1049 part_no,
1050 })
1051 }
1052}
1053
1054