corstone300_hal/
fpgaio.rs

1// Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
2//
3// SPDX-License-Identifier: MIT
4
5use crate::pac;
6
7pub struct Led<const ID: usize>;
8impl<const ID: usize> embedded_hal::digital::v2::OutputPin for Led<ID> {
9    type Error = core::convert::Infallible;
10
11    fn set_low(&mut self) -> Result<(), Self::Error> {
12        unsafe {
13            let mask = 1 << ID;
14            let fpgaio = &*pac::FPGAIO::ptr();
15            fpgaio.led.modify(|r, w| w.bits(r.bits() & !mask));
16        }
17        Ok(())
18    }
19
20    fn set_high(&mut self) -> Result<(), Self::Error> {
21        unsafe {
22            let mask = 1 << ID;
23            let fpgaio = &*pac::FPGAIO::ptr();
24            fpgaio.led.modify(|r, w| w.bits(r.bits() | mask));
25        }
26        Ok(())
27    }
28}
29impl<const ID: usize> embedded_hal::digital::v2::StatefulOutputPin for Led<ID> {
30    fn is_set_high(&self) -> Result<bool, Self::Error> {
31        unsafe {
32            let mask = 1 << ID;
33            let fpgaio = &*pac::FPGAIO::ptr();
34            Ok(fpgaio.led.read().bits() & mask == mask)
35        }
36    }
37
38    fn is_set_low(&self) -> Result<bool, Self::Error> {
39        unsafe {
40            let mask = 1 << ID;
41            let fpgaio = &*pac::FPGAIO::ptr();
42            Ok(fpgaio.led.read().bits() & mask == 0)
43        }
44    }
45}
46impl<const ID: usize> embedded_hal::digital::v2::toggleable::Default for Led<ID> {}
47
48pub struct Button<const _ID: usize>;
49impl<const ID: usize> embedded_hal::digital::v2::InputPin for Button<ID> {
50    type Error = core::convert::Infallible;
51
52    fn is_high(&self) -> Result<bool, Self::Error> {
53        unsafe {
54            let mask = 1 << ID;
55            let fpgaio = &*pac::FPGAIO::ptr();
56            Ok(fpgaio.button.read().bits() & mask == mask)
57        }
58    }
59
60    fn is_low(&self) -> Result<bool, Self::Error> {
61        unsafe {
62            let mask = 1 << ID;
63            let fpgaio = &*pac::FPGAIO::ptr();
64            Ok(fpgaio.button.read().bits() & mask == 0)
65        }
66    }
67}
68pub struct Switch<const _ID: usize>;
69impl<const ID: usize> embedded_hal::digital::v2::InputPin for Switch<ID> {
70    type Error = core::convert::Infallible;
71
72    fn is_high(&self) -> Result<bool, Self::Error> {
73        unsafe {
74            let mask = 1 << ID;
75            let fpgaio = &*pac::FPGAIO::ptr();
76            Ok(fpgaio.switches.read().bits() & mask == mask)
77        }
78    }
79
80    fn is_low(&self) -> Result<bool, Self::Error> {
81        unsafe {
82            let mask = 1 << ID;
83            let fpgaio = &*pac::FPGAIO::ptr();
84            Ok(fpgaio.switches.read().bits() & mask == 0)
85        }
86    }
87}
88pub struct Clocks;
89impl Clocks {
90    pub fn clk1hz(&self) -> u32 {
91        unsafe {
92            let fpgaio = &*pac::FPGAIO::ptr();
93            fpgaio.clk1hz.read().bits()
94        }
95    }
96    pub fn clk100hz(&self) -> u32 {
97        unsafe {
98            let fpgaio = &*pac::FPGAIO::ptr();
99            fpgaio.clk100hz.read().bits()
100        }
101    }
102    pub fn counter(&mut self) -> &pac::fpgaio::COUNTER {
103        unsafe {
104            let fpgaio = &*pac::FPGAIO::ptr();
105            &fpgaio.counter
106        }
107    }
108    pub fn prescaler(&mut self) -> &pac::fpgaio::PRESCALER {
109        unsafe {
110            let fpgaio = &*pac::FPGAIO::ptr();
111            &fpgaio.prescaler
112        }
113    }
114    pub fn pscntr(&mut self) -> &pac::fpgaio::PSCNTR {
115        unsafe {
116            let fpgaio = &*pac::FPGAIO::ptr();
117            &fpgaio.pscntr
118        }
119    }
120}
121
122pub struct Parts {
123    pub ul0: Led<0>,
124    pub ul1: Led<1>,
125    pub ul2: Led<2>,
126    pub ul3: Led<3>,
127    pub ul4: Led<4>,
128    pub ul5: Led<5>,
129    pub ul6: Led<6>,
130    pub ul7: Led<7>,
131    pub pb1led: Led<8>,
132    pub pb2led: Led<9>,
133    pub button0: Button<0>,
134    pub button1: Button<1>,
135    pub switch0: Switch<0>,
136    pub switch1: Switch<1>,
137    pub switch2: Switch<2>,
138    pub switch3: Switch<3>,
139    pub switch4: Switch<4>,
140    pub switch5: Switch<5>,
141    pub switch6: Switch<6>,
142    pub switch7: Switch<7>,
143    pub clocks: Clocks,
144}
145
146pub trait FPGAIOExt {
147    fn split(self) -> Parts;
148}
149
150macro_rules! impl_ext {
151    ($p:path) => {
152        impl FPGAIOExt for $p {
153            fn split(self) -> Parts {
154                Parts {
155                    ul0: Led,
156                    ul1: Led,
157                    ul2: Led,
158                    ul3: Led,
159                    ul4: Led,
160                    ul5: Led,
161                    ul6: Led,
162                    ul7: Led,
163                    pb1led: Led,
164                    pb2led: Led,
165                    button0: Button,
166                    button1: Button,
167                    switch0: Switch,
168                    switch1: Switch,
169                    switch2: Switch,
170                    switch3: Switch,
171                    switch4: Switch,
172                    switch5: Switch,
173                    switch6: Switch,
174                    switch7: Switch,
175                    clocks: Clocks,
176                }
177            }
178        }
179    };
180}
181
182impl_ext!(super::pac::FPGAIO);
183impl_ext!(super::pac::FPGAIO_SECURE);