nrf52840dk_hotp_tutorial/
main.rs1#![no_std]
8#![cfg_attr(not(doc), no_main)]
11#![deny(missing_docs)]
12
13use core::ptr::addr_of_mut;
14use kernel::component::Component;
15use kernel::debug;
16use kernel::hil::usb::Client;
17use kernel::platform::{KernelResources, SyscallDriverLookup};
18use kernel::static_init;
19use kernel::{capabilities, create_capability};
20use nrf52840::gpio::Pin;
21use nrf52840dk_lib::{self, PROCESSES};
22
23const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
26 capsules_system::process_policies::PanicFaultPolicy {};
27
28type ScreenDriver = components::screen::ScreenComponentType;
30
31type UsbHw = nrf52840::usbd::Usbd<'static>; type KeyboardHidDriver = components::keyboard_hid::KeyboardHidComponentType<UsbHw>;
34
35type HmacSha256Software = components::hmac::HmacSha256SoftwareComponentType<
37 capsules_extra::sha256::Sha256Software<'static>,
38>;
39type HmacDriver = components::hmac::HmacComponentType<HmacSha256Software, 32>;
40
41struct Platform {
42 keyboard_hid_driver: &'static KeyboardHidDriver,
43 hmac: &'static HmacDriver,
44 screen: &'static ScreenDriver,
45 base: nrf52840dk_lib::Platform,
46}
47
48const KEYBOARD_HID_DRIVER_NUM: usize = capsules_core::driver::NUM::KeyboardHid as usize;
49
50impl SyscallDriverLookup for Platform {
51 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
52 where
53 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
54 {
55 match driver_num {
56 capsules_extra::hmac::DRIVER_NUM => f(Some(self.hmac)),
57 KEYBOARD_HID_DRIVER_NUM => f(Some(self.keyboard_hid_driver)),
58 capsules_extra::screen::DRIVER_NUM => f(Some(self.screen)),
59 _ => self.base.with_driver(driver_num, f),
60 }
61 }
62}
63
64type Chip = nrf52840dk_lib::Chip;
65
66impl KernelResources<Chip> for Platform {
67 type SyscallDriverLookup = Self;
68 type SyscallFilter = <nrf52840dk_lib::Platform as KernelResources<Chip>>::SyscallFilter;
69 type ProcessFault = <nrf52840dk_lib::Platform as KernelResources<Chip>>::ProcessFault;
70 type Scheduler = <nrf52840dk_lib::Platform as KernelResources<Chip>>::Scheduler;
71 type SchedulerTimer = <nrf52840dk_lib::Platform as KernelResources<Chip>>::SchedulerTimer;
72 type WatchDog = <nrf52840dk_lib::Platform as KernelResources<Chip>>::WatchDog;
73 type ContextSwitchCallback =
74 <nrf52840dk_lib::Platform as KernelResources<Chip>>::ContextSwitchCallback;
75
76 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
77 self
78 }
79 fn syscall_filter(&self) -> &Self::SyscallFilter {
80 self.base.syscall_filter()
81 }
82 fn process_fault(&self) -> &Self::ProcessFault {
83 self.base.process_fault()
84 }
85 fn scheduler(&self) -> &Self::Scheduler {
86 self.base.scheduler()
87 }
88 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
89 self.base.scheduler_timer()
90 }
91 fn watchdog(&self) -> &Self::WatchDog {
92 self.base.watchdog()
93 }
94 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
95 self.base.context_switch_callback()
96 }
97}
98
99#[no_mangle]
101pub unsafe fn main() {
102 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
103
104 let (board_kernel, base_platform, chip, nrf52840_peripherals, _mux_alarm) =
106 nrf52840dk_lib::start();
107
108 let sha256_sw = components::sha::ShaSoftware256Component::new()
113 .finalize(components::sha_software_256_component_static!());
114
115 let hmac_sha256_sw = components::hmac::HmacSha256SoftwareComponent::new(sha256_sw).finalize(
116 components::hmac_sha256_software_component_static!(capsules_extra::sha256::Sha256Software),
117 );
118
119 let hmac = components::hmac::HmacComponent::new(
120 board_kernel,
121 capsules_extra::hmac::DRIVER_NUM,
122 hmac_sha256_sw,
123 )
124 .finalize(components::hmac_component_static!(HmacSha256Software, 32));
125
126 const SCREEN_I2C_SDA_PIN: Pin = Pin::P1_10;
131 const SCREEN_I2C_SCL_PIN: Pin = Pin::P1_11;
132
133 let i2c_bus = components::i2c::I2CMuxComponent::new(&nrf52840_peripherals.nrf52.twi1, None)
134 .finalize(components::i2c_mux_component_static!(nrf52840::i2c::TWI));
135 nrf52840_peripherals.nrf52.twi1.configure(
136 nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SCL_PIN as u32),
137 nrf52840::pinmux::Pinmux::new(SCREEN_I2C_SDA_PIN as u32),
138 );
139 nrf52840_peripherals
140 .nrf52
141 .twi1
142 .set_speed(nrf52840::i2c::Speed::K400);
143
144 let ssd1306_sh1106_i2c = components::i2c::I2CComponent::new(i2c_bus, 0x3c)
146 .finalize(components::i2c_component_static!(nrf52840::i2c::TWI));
147
148 #[cfg(feature = "screen_ssd1306")]
150 let ssd1306_sh1106 = components::ssd1306::Ssd1306Component::new(ssd1306_sh1106_i2c, true)
151 .finalize(components::ssd1306_component_static!(nrf52840::i2c::TWI));
152
153 #[cfg(feature = "screen_sh1106")]
154 let ssd1306_sh1106 = components::sh1106::Sh1106Component::new(ssd1306_sh1106_i2c, true)
155 .finalize(components::sh1106_component_static!(nrf52840::i2c::TWI));
156
157 let screen = components::screen::ScreenComponent::new(
158 board_kernel,
159 capsules_extra::screen::DRIVER_NUM,
160 ssd1306_sh1106,
161 None,
162 )
163 .finalize(components::screen_component_static!(1032));
164
165 ssd1306_sh1106.init_screen();
166
167 let strings = static_init!(
173 [&str; 3],
174 [
175 "Nordic Semiconductor", "nRF52840dk - TockOS", "serial0001", ]
179 );
180
181 let usb_device = &nrf52840_peripherals.usbd;
182
183 let (keyboard_hid, keyboard_hid_driver) = components::keyboard_hid::KeyboardHidComponent::new(
185 board_kernel,
186 capsules_core::driver::NUM::KeyboardHid as usize,
187 usb_device,
188 0x1915, 0x503a,
190 strings,
191 )
192 .finalize(components::keyboard_hid_component_static!(UsbHw));
193
194 keyboard_hid.enable();
195 keyboard_hid.attach();
196
197 let platform = Platform {
202 base: base_platform,
203 keyboard_hid_driver,
204 hmac,
205 screen,
206 };
207
208 extern "C" {
210 static _sapps: u8;
212 static _eapps: u8;
214 static mut _sappmem: u8;
216 static _eappmem: u8;
218 }
219
220 let process_management_capability =
221 create_capability!(capabilities::ProcessManagementCapability);
222
223 kernel::process::load_processes(
224 board_kernel,
225 chip,
226 core::slice::from_raw_parts(
227 core::ptr::addr_of!(_sapps),
228 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
229 ),
230 core::slice::from_raw_parts_mut(
231 core::ptr::addr_of_mut!(_sappmem),
232 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
233 ),
234 &mut *addr_of_mut!(PROCESSES),
235 &FAULT_RESPONSE,
236 &process_management_capability,
237 )
238 .unwrap_or_else(|err| {
239 debug!("Error loading processes!");
240 debug!("{:?}", err);
241 });
242
243 board_kernel.kernel_loop(
244 &platform,
245 chip,
246 Some(&platform.base.ipc),
247 &main_loop_capability,
248 );
249}