1use core::fmt::Write;
6use cortexm4::{CortexM4, CortexMVariant};
7use kernel::platform::chip::Chip;
8
9use crate::nvic;
10use crate::wdt;
11use kernel::platform::chip::InterruptService;
12
13pub struct Msp432<'a, I: InterruptService + 'a> {
14 mpu: cortexm4::mpu::MPU,
15 userspace_kernel_boundary: cortexm4::syscall::SysCall,
16 interrupt_service: &'a I,
17}
18
19pub struct Msp432DefaultPeripherals<'a> {
20 pub adc: crate::adc::Adc<'a>,
21 pub uart0: crate::uart::Uart<'a>,
22 pub cs: crate::cs::ClockSystem,
23 pub dma_channels: crate::dma::DmaChannels<'a>,
24 pub adc_ref: crate::ref_module::Ref,
25 pub timer_a0: crate::timer::TimerA<'a>,
26 pub timer_a1: crate::timer::TimerA<'a>,
27 pub timer_a2: crate::timer::TimerA<'a>,
28 pub timer_a3: crate::timer::TimerA<'a>,
29 pub gpio: crate::gpio::GpioManager<'a>,
30 pub i2c0: crate::i2c::I2c<'a>,
31 pub wdt: wdt::Wdt,
32}
33
34impl<'a> Msp432DefaultPeripherals<'a> {
35 pub fn new() -> Self {
36 Self {
37 adc: crate::adc::Adc::new(),
38 uart0: crate::uart::Uart::new(crate::usci::USCI_A0_BASE, 0, 1, 1, 1),
39 cs: crate::cs::ClockSystem::new(),
40 dma_channels: crate::dma::DmaChannels::new(),
41 adc_ref: crate::ref_module::Ref::new(),
42 timer_a0: crate::timer::TimerA::new(crate::timer::TIMER_A0_BASE),
43 timer_a1: crate::timer::TimerA::new(crate::timer::TIMER_A1_BASE),
44 timer_a2: crate::timer::TimerA::new(crate::timer::TIMER_A2_BASE),
45 timer_a3: crate::timer::TimerA::new(crate::timer::TIMER_A3_BASE),
46 gpio: crate::gpio::GpioManager::new(),
47 i2c0: crate::i2c::I2c::new(crate::usci::USCI_B0_BASE),
48 wdt: wdt::Wdt::new(),
49 }
50 }
51
52 pub unsafe fn init(&'a self) {
53 self.uart0.set_dma(
55 &self.dma_channels[self.uart0.tx_dma_chan],
56 &self.dma_channels[self.uart0.rx_dma_chan],
57 );
58 self.dma_channels[self.uart0.tx_dma_chan].set_client(&self.uart0);
59 self.dma_channels[self.uart0.rx_dma_chan].set_client(&self.uart0);
60
61 self.adc.set_modules(
63 &self.adc_ref,
64 &self.timer_a3,
65 &self.dma_channels[self.adc.dma_chan],
66 );
67 self.dma_channels[self.adc.dma_chan].set_client(&self.adc);
68 }
69}
70
71impl kernel::platform::chip::InterruptService for Msp432DefaultPeripherals<'_> {
72 unsafe fn service_interrupt(&self, interrupt: u32) -> bool {
73 match interrupt {
74 nvic::ADC => self.adc.handle_interrupt(),
75 nvic::DMA_INT0 => self.dma_channels.handle_interrupt(0),
76 nvic::DMA_INT1 => self.dma_channels.handle_interrupt(1),
77 nvic::DMA_INT2 => self.dma_channels.handle_interrupt(2),
78 nvic::DMA_INT3 => self.dma_channels.handle_interrupt(3),
79 nvic::DMA_ERR => self.dma_channels.handle_interrupt(-1),
80 nvic::IO_PORT1 => self.gpio.handle_interrupt(0),
81 nvic::IO_PORT2 => self.gpio.handle_interrupt(1),
82 nvic::IO_PORT3 => self.gpio.handle_interrupt(2),
83 nvic::IO_PORT4 => self.gpio.handle_interrupt(3),
84 nvic::IO_PORT5 => self.gpio.handle_interrupt(4),
85 nvic::IO_PORT6 => self.gpio.handle_interrupt(5),
86 nvic::TIMER_A0_0 | nvic::TIMER_A0_1 => self.timer_a0.handle_interrupt(),
87 nvic::TIMER_A1_0 | nvic::TIMER_A1_1 => self.timer_a1.handle_interrupt(),
88 nvic::TIMER_A2_0 | nvic::TIMER_A2_1 => self.timer_a2.handle_interrupt(),
89 nvic::TIMER_A3_0 | nvic::TIMER_A3_1 => self.timer_a3.handle_interrupt(),
90 nvic::USCI_B0 => self.i2c0.handle_interrupt(),
91 _ => return false,
92 }
93 true
94 }
95}
96
97impl<'a, I: InterruptService + 'a> Msp432<'a, I> {
98 pub unsafe fn new(interrupt_service: &'a I) -> Self {
99 Self {
100 mpu: cortexm4::mpu::MPU::new(),
101 userspace_kernel_boundary: cortexm4::syscall::SysCall::new(),
102 interrupt_service,
103 }
104 }
105}
106
107impl<'a, I: InterruptService + 'a> Chip for Msp432<'a, I> {
108 type MPU = cortexm4::mpu::MPU;
109 type UserspaceKernelBoundary = cortexm4::syscall::SysCall;
110
111 fn service_pending_interrupts(&self) {
112 unsafe {
113 loop {
114 if let Some(interrupt) = cortexm4::nvic::next_pending() {
115 if !self.interrupt_service.service_interrupt(interrupt) {
116 panic!("unhandled interrupt {}", interrupt);
117 }
118
119 let n = cortexm4::nvic::Nvic::new(interrupt);
120 n.clear_pending();
121 n.enable();
122 } else {
123 break;
124 }
125 }
126 }
127 }
128
129 fn has_pending_interrupts(&self) -> bool {
130 unsafe { cortexm4::nvic::has_pending() }
131 }
132
133 fn mpu(&self) -> &cortexm4::mpu::MPU {
134 &self.mpu
135 }
136
137 fn userspace_kernel_boundary(&self) -> &cortexm4::syscall::SysCall {
138 &self.userspace_kernel_boundary
139 }
140
141 fn sleep(&self) {
142 unsafe {
143 cortexm4::support::wfi();
144 }
145 }
146
147 unsafe fn atomic<F, R>(&self, f: F) -> R
148 where
149 F: FnOnce() -> R,
150 {
151 cortexm4::support::atomic(f)
152 }
153
154 unsafe fn print_state(&self, write: &mut dyn Write) {
155 CortexM4::print_cortexm_state(write);
156 }
157}