1use core::fmt::Write;
6use cortexm4f::{nvic, CortexM4F, CortexMVariant};
7use kernel::platform::chip::InterruptService;
8
9pub struct NRF52<'a, I: InterruptService + 'a> {
10 mpu: cortexm4f::mpu::MPU,
11 userspace_kernel_boundary: cortexm4f::syscall::SysCall,
12 interrupt_service: &'a I,
13}
14
15impl<'a, I: InterruptService + 'a> NRF52<'a, I> {
16 pub unsafe fn new(interrupt_service: &'a I) -> Self {
17 Self {
18 mpu: cortexm4f::mpu::MPU::new(),
19 userspace_kernel_boundary: cortexm4f::syscall::SysCall::new(),
20 interrupt_service,
21 }
22 }
23}
24
25pub struct Nrf52DefaultPeripherals<'a> {
31 pub acomp: crate::acomp::Comparator<'a>,
32 pub ecb: crate::aes::AesECB<'a>,
33 pub pwr_clk: crate::power::Power<'a>,
34 pub ble_radio: crate::ble_radio::Radio<'a>,
35 pub trng: crate::trng::Trng<'a>,
36 pub rtc: crate::rtc::Rtc<'a>,
37 pub temp: crate::temperature::Temp<'a>,
38 pub timer0: crate::timer::TimerAlarm<'a>,
39 pub timer1: crate::timer::TimerAlarm<'a>,
40 pub timer2: crate::timer::Timer,
41 pub uarte0: crate::uart::Uarte<'a>,
42 pub spim0: crate::spi::SPIM<'a>,
43 pub twi1: crate::i2c::TWI<'a>,
44 pub spim2: crate::spi::SPIM<'a>,
45 pub adc: crate::adc::Adc<'a>,
46 pub nvmc: crate::nvmc::Nvmc,
47 pub clock: crate::clock::Clock,
48 pub pwm0: crate::pwm::Pwm,
49}
50
51impl Nrf52DefaultPeripherals<'_> {
52 pub fn new() -> Self {
53 Self {
54 acomp: crate::acomp::Comparator::new(),
55 ecb: crate::aes::AesECB::new(),
56 pwr_clk: crate::power::Power::new(),
57 ble_radio: crate::ble_radio::Radio::new(),
58 trng: crate::trng::Trng::new(),
59 rtc: crate::rtc::Rtc::new(),
60 temp: crate::temperature::Temp::new(),
61 timer0: crate::timer::TimerAlarm::new(0),
62 timer1: crate::timer::TimerAlarm::new(1),
63 timer2: crate::timer::Timer::new(2),
64 uarte0: crate::uart::Uarte::new(crate::uart::UARTE0_BASE),
65 spim0: crate::spi::SPIM::new(0),
66 twi1: crate::i2c::TWI::new_twi1(),
67 spim2: crate::spi::SPIM::new(2),
68 adc: crate::adc::Adc::new(3300),
70 nvmc: crate::nvmc::Nvmc::new(),
71 clock: crate::clock::Clock::new(),
72 pwm0: crate::pwm::Pwm::new(),
73 }
74 }
75 pub fn init(&'static self) {
77 kernel::deferred_call::DeferredCallClient::register(&self.nvmc);
78 }
79}
80impl kernel::platform::chip::InterruptService for Nrf52DefaultPeripherals<'_> {
81 unsafe fn service_interrupt(&self, interrupt: u32) -> bool {
82 match interrupt {
83 crate::peripheral_interrupts::COMP => self.acomp.handle_interrupt(),
84 crate::peripheral_interrupts::ECB => self.ecb.handle_interrupt(),
85 crate::peripheral_interrupts::POWER_CLOCK => self.pwr_clk.handle_interrupt(),
86 crate::peripheral_interrupts::RADIO => match self.ble_radio.is_enabled() {
87 false => (),
88 true => self.ble_radio.handle_interrupt(),
89 },
90 crate::peripheral_interrupts::RNG => self.trng.handle_interrupt(),
91 crate::peripheral_interrupts::RTC1 => self.rtc.handle_interrupt(),
92 crate::peripheral_interrupts::TEMP => self.temp.handle_interrupt(),
93 crate::peripheral_interrupts::TIMER0 => self.timer0.handle_interrupt(),
94 crate::peripheral_interrupts::TIMER1 => self.timer1.handle_interrupt(),
95 crate::peripheral_interrupts::TIMER2 => self.timer2.handle_interrupt(),
96 crate::peripheral_interrupts::UART0 => self.uarte0.handle_interrupt(),
97 crate::peripheral_interrupts::SPI0_TWI0 => self.spim0.handle_interrupt(),
98 crate::peripheral_interrupts::SPI1_TWI1 => self.twi1.handle_interrupt(),
99 crate::peripheral_interrupts::SPIM2_SPIS2_SPI2 => self.spim2.handle_interrupt(),
100 crate::peripheral_interrupts::ADC => self.adc.handle_interrupt(),
101 _ => return false,
102 }
103 true
104 }
105}
106
107impl<'a, I: InterruptService + 'a> kernel::platform::chip::Chip for NRF52<'a, I> {
108 type MPU = cortexm4f::mpu::MPU;
109 type UserspaceKernelBoundary = cortexm4f::syscall::SysCall;
110
111 fn mpu(&self) -> &Self::MPU {
112 &self.mpu
113 }
114
115 fn userspace_kernel_boundary(&self) -> &Self::UserspaceKernelBoundary {
116 &self.userspace_kernel_boundary
117 }
118
119 fn service_pending_interrupts(&self) {
120 unsafe {
121 loop {
122 if let Some(interrupt) = nvic::next_pending() {
123 if !self.interrupt_service.service_interrupt(interrupt) {
124 panic!("unhandled interrupt {}", interrupt);
125 }
126 let n = nvic::Nvic::new(interrupt);
127 n.clear_pending();
128 n.enable();
129 } else {
130 break;
131 }
132 }
133 }
134 }
135
136 fn has_pending_interrupts(&self) -> bool {
137 unsafe { nvic::has_pending() }
138 }
139
140 fn sleep(&self) {
141 unsafe {
142 cortexm4f::support::wfi();
143 }
144 }
145
146 unsafe fn atomic<F, R>(&self, f: F) -> R
147 where
148 F: FnOnce() -> R,
149 {
150 cortexm4f::support::atomic(f)
151 }
152
153 unsafe fn print_state(&self, write: &mut dyn Write) {
154 CortexM4F::print_cortexm_state(write);
155 }
156}