1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
//! Reset control helpers built on PAC field writers.
use crate::pac;
/// Trait describing a reset line that can be asserted/deasserted.
pub trait ResetLine {
/// Drive the peripheral out of reset.
unsafe fn release(mrcc: &pac::mrcc0::RegisterBlock);
/// Drive the peripheral into reset.
unsafe fn assert(mrcc: &pac::mrcc0::RegisterBlock);
/// Check whether the peripheral is currently released.
fn is_released(mrcc: &pac::mrcc0::RegisterBlock) -> bool;
}
/// Release a reset line for the given peripheral set.
#[inline]
pub unsafe fn release<R: ResetLine>(peripherals: &pac::Peripherals) {
R::release(&peripherals.mrcc0);
}
/// Assert a reset line for the given peripheral set.
#[inline]
pub unsafe fn assert<R: ResetLine>(peripherals: &pac::Peripherals) {
R::assert(&peripherals.mrcc0);
}
/// Pulse a reset line (assert then release) with a short delay.
#[inline]
pub unsafe fn pulse<R: ResetLine>(peripherals: &pac::Peripherals) {
let mrcc = &peripherals.mrcc0;
R::assert(mrcc);
cortex_m::asm::nop();
cortex_m::asm::nop();
R::release(mrcc);
}
macro_rules! impl_reset_line {
($name:ident, $reg:ident, $field:ident) => {
pub struct $name;
impl ResetLine for $name {
#[inline]
unsafe fn release(mrcc: &pac::mrcc0::RegisterBlock) {
mrcc.$reg().modify(|_, w| w.$field().enabled());
}
#[inline]
unsafe fn assert(mrcc: &pac::mrcc0::RegisterBlock) {
mrcc.$reg().modify(|_, w| w.$field().disabled());
}
#[inline]
fn is_released(mrcc: &pac::mrcc0::RegisterBlock) -> bool {
mrcc.$reg().read().$field().is_enabled()
}
}
};
}
pub mod line {
use super::*;
impl_reset_line!(Port2, mrcc_glb_rst1, port2);
impl_reset_line!(Port3, mrcc_glb_rst1, port3);
impl_reset_line!(Gpio3, mrcc_glb_rst2, gpio3);
impl_reset_line!(Lpuart2, mrcc_glb_rst0, lpuart2);
impl_reset_line!(Ostimer0, mrcc_glb_rst1, ostimer0);
impl_reset_line!(Port1, mrcc_glb_rst1, port1);
impl_reset_line!(Adc1, mrcc_glb_rst1, adc1);
}
#[inline]
pub unsafe fn release_reset_port2(peripherals: &pac::Peripherals) {
release::<line::Port2>(peripherals);
}
#[inline]
pub unsafe fn release_reset_port3(peripherals: &pac::Peripherals) {
release::<line::Port3>(peripherals);
}
#[inline]
pub unsafe fn release_reset_gpio3(peripherals: &pac::Peripherals) {
release::<line::Gpio3>(peripherals);
}
#[inline]
pub unsafe fn release_reset_lpuart2(peripherals: &pac::Peripherals) {
release::<line::Lpuart2>(peripherals);
}
#[inline]
pub unsafe fn release_reset_ostimer0(peripherals: &pac::Peripherals) {
release::<line::Ostimer0>(peripherals);
}
/// Convenience shim retained for existing call sites.
#[inline]
pub unsafe fn reset_ostimer0(peripherals: &pac::Peripherals) {
pulse::<line::Ostimer0>(peripherals);
}
#[inline]
pub unsafe fn release_reset_port1(peripherals: &pac::Peripherals) {
release::<line::Port1>(peripherals);
}
#[inline]
pub unsafe fn release_reset_adc1(peripherals: &pac::Peripherals) {
release::<line::Adc1>(peripherals);
}
|