1use kernel::utilities::cells::OptionalCell;
16use kernel::utilities::registers::interfaces::{Readable, Writeable};
17use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite, WriteOnly};
18use kernel::utilities::StaticRef;
19use kernel::ErrorCode;
20
21const TEMP_BASE: StaticRef<TempRegisters> =
22 unsafe { StaticRef::new(0x4000C000 as *const TempRegisters) };
23
24#[repr(C)]
25struct TempRegisters {
26 pub task_start: WriteOnly<u32, Task::Register>,
29 pub task_stop: WriteOnly<u32, Task::Register>,
32 pub _reserved1: [u32; 62],
34 pub event_datardy: ReadWrite<u32, Event::Register>,
37 pub _reserved2: [u32; 128],
41 pub intenset: ReadWrite<u32, Intenset::Register>,
44 pub intenclr: ReadWrite<u32, Intenclr::Register>,
47 pub _reserved3: [u32; 127],
49 pub temp: ReadOnly<u32, Temperature::Register>,
52 pub _reserved4: [u32; 5],
54 #[cfg(feature = "nrf52")]
57 pub a: [ReadWrite<u32, A::Register>; 6],
58 pub _reserved5: [u32; 2],
59 #[cfg(feature = "nrf52")]
62 pub b: [ReadWrite<u32, B::Register>; 6],
63 pub _reserved6: [u32; 2],
64 #[cfg(feature = "nrf52")]
67 pub t: [ReadWrite<u32, B::Register>; 5],
68}
69
70register_bitfields! [u32,
71 Task [
73 ENABLE OFFSET(0) NUMBITS(1)
74 ],
75
76 Event [
78 READY OFFSET(0) NUMBITS(1)
79 ],
80
81 Intenset [
83 DATARDY OFFSET(0) NUMBITS(1)
84 ],
85
86 Intenclr [
88 DATARDY OFFSET(0) NUMBITS(1)
89 ],
90
91 Temperature [
93 TEMP OFFSET(0) NUMBITS(32)
94 ],
95
96 A [
98 SLOPE OFFSET(0) NUMBITS(12)
99 ],
100
101 B [
103 INTERCEPT OFFSET(0) NUMBITS(14)
104 ],
105
106 T [
108 PIECE OFFSET(0) NUMBITS(8)
109 ]
110];
111
112pub struct Temp<'a> {
113 registers: StaticRef<TempRegisters>,
114 client: OptionalCell<&'a dyn kernel::hil::sensors::TemperatureClient>,
115}
116
117impl<'a> Temp<'a> {
118 pub const fn new() -> Temp<'a> {
119 Temp {
120 registers: TEMP_BASE,
121 client: OptionalCell::empty(),
122 }
123 }
124
125 pub fn handle_interrupt(&self) {
127 self.disable_interrupts();
129
130 let temp = (self.registers.temp.get() as i32 * 100) / 4;
133
134 self.registers.task_stop.write(Task::ENABLE::SET);
136
137 self.disable_interrupts();
139
140 self.client.map(|client| client.callback(Ok(temp)));
142 }
143
144 fn enable_interrupts(&self) {
145 self.registers.intenset.write(Intenset::DATARDY::SET);
146 }
147
148 fn disable_interrupts(&self) {
149 self.registers.intenclr.write(Intenclr::DATARDY::SET);
150 }
151}
152
153impl<'a> kernel::hil::sensors::TemperatureDriver<'a> for Temp<'a> {
154 fn read_temperature(&self) -> Result<(), ErrorCode> {
155 self.enable_interrupts();
156 self.registers.event_datardy.write(Event::READY::CLEAR);
157 self.registers.task_start.write(Task::ENABLE::SET);
158 Ok(())
159 }
160
161 fn set_client(&self, client: &'a dyn kernel::hil::sensors::TemperatureClient) {
162 self.client.set(client);
163 }
164}