1#![no_std]
10#![cfg_attr(not(doc), no_main)]
13#![deny(missing_docs)]
14use core::ptr::{addr_of, addr_of_mut};
15
16use capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm;
17use components::gpio::GpioComponent;
18use components::rng::RngComponent;
19use kernel::capabilities;
20use kernel::component::Component;
21use kernel::hil::gpio;
22use kernel::hil::led::LedLow;
23use kernel::hil::screen::ScreenRotation;
24use kernel::platform::{KernelResources, SyscallDriverLookup};
25use kernel::scheduler::round_robin::RoundRobinSched;
26use kernel::{create_capability, debug, static_init};
27use stm32f412g::chip_specs::Stm32f412Specs;
28use stm32f412g::clocks::hsi::HSI_FREQUENCY_MHZ;
29use stm32f412g::interrupt_service::Stm32f412gDefaultPeripherals;
30use stm32f412g::rcc::PllSource;
31
32pub mod io;
34
35const NUM_PROCS: usize = 4;
37
38static mut PROCESSES: [Option<&'static dyn kernel::process::Process>; NUM_PROCS] =
40 [None, None, None, None];
41
42static mut CHIP: Option<&'static stm32f412g::chip::Stm32f4xx<Stm32f412gDefaultPeripherals>> = None;
43static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
44 None;
45
46const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
48 capsules_system::process_policies::PanicFaultPolicy {};
49
50#[no_mangle]
52#[link_section = ".stack_buffer"]
53pub static mut STACK_MEMORY: [u8; 0x2000] = [0; 0x2000];
54
55type TemperatureSTMSensor = components::temperature_stm::TemperatureSTMComponentType<
56 capsules_core::virtualizers::virtual_adc::AdcDevice<'static, stm32f412g::adc::Adc<'static>>,
57>;
58type TemperatureDriver = components::temperature::TemperatureComponentType<TemperatureSTMSensor>;
59type RngDriver = components::rng::RngComponentType<stm32f412g::trng::Trng<'static>>;
60
61struct STM32F412GDiscovery {
64 console: &'static capsules_core::console::Console<'static>,
65 ipc: kernel::ipc::IPC<{ NUM_PROCS as u8 }>,
66 led: &'static capsules_core::led::LedDriver<
67 'static,
68 LedLow<'static, stm32f412g::gpio::Pin<'static>>,
69 4,
70 >,
71 button: &'static capsules_core::button::Button<'static, stm32f412g::gpio::Pin<'static>>,
72 alarm: &'static capsules_core::alarm::AlarmDriver<
73 'static,
74 VirtualMuxAlarm<'static, stm32f412g::tim2::Tim2<'static>>,
75 >,
76 gpio: &'static capsules_core::gpio::GPIO<'static, stm32f412g::gpio::Pin<'static>>,
77 adc: &'static capsules_core::adc::AdcVirtualized<'static>,
78 touch: &'static capsules_extra::touch::Touch<'static>,
79 screen: &'static capsules_extra::screen::Screen<'static>,
80 temperature: &'static TemperatureDriver,
81 rng: &'static RngDriver,
82
83 scheduler: &'static RoundRobinSched<'static>,
84 systick: cortexm4::systick::SysTick,
85}
86
87impl SyscallDriverLookup for STM32F412GDiscovery {
89 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
90 where
91 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
92 {
93 match driver_num {
94 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
95 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
96 capsules_core::button::DRIVER_NUM => f(Some(self.button)),
97 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
98 kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
99 capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
100 capsules_core::adc::DRIVER_NUM => f(Some(self.adc)),
101 capsules_extra::touch::DRIVER_NUM => f(Some(self.touch)),
102 capsules_extra::screen::DRIVER_NUM => f(Some(self.screen)),
103 capsules_extra::temperature::DRIVER_NUM => f(Some(self.temperature)),
104 capsules_core::rng::DRIVER_NUM => f(Some(self.rng)),
105 _ => f(None),
106 }
107 }
108}
109
110impl
111 KernelResources<
112 stm32f412g::chip::Stm32f4xx<
113 'static,
114 stm32f412g::interrupt_service::Stm32f412gDefaultPeripherals<'static>,
115 >,
116 > for STM32F412GDiscovery
117{
118 type SyscallDriverLookup = Self;
119 type SyscallFilter = ();
120 type ProcessFault = ();
121 type Scheduler = RoundRobinSched<'static>;
122 type SchedulerTimer = cortexm4::systick::SysTick;
123 type WatchDog = ();
124 type ContextSwitchCallback = ();
125
126 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
127 self
128 }
129 fn syscall_filter(&self) -> &Self::SyscallFilter {
130 &()
131 }
132 fn process_fault(&self) -> &Self::ProcessFault {
133 &()
134 }
135 fn scheduler(&self) -> &Self::Scheduler {
136 self.scheduler
137 }
138 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
139 &self.systick
140 }
141 fn watchdog(&self) -> &Self::WatchDog {
142 &()
143 }
144 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
145 &()
146 }
147}
148
149unsafe fn setup_dma(
151 dma: &stm32f412g::dma::Dma1,
152 dma_streams: &'static [stm32f412g::dma::Stream<stm32f412g::dma::Dma1>; 8],
153 usart2: &'static stm32f412g::usart::Usart<stm32f412g::dma::Dma1>,
154) {
155 use stm32f412g::dma::Dma1Peripheral;
156 use stm32f412g::usart;
157
158 dma.enable_clock();
159
160 let usart2_tx_stream = &dma_streams[Dma1Peripheral::USART2_TX.get_stream_idx()];
161 let usart2_rx_stream = &dma_streams[Dma1Peripheral::USART2_RX.get_stream_idx()];
162
163 usart2.set_dma(
164 usart::TxDMA(usart2_tx_stream),
165 usart::RxDMA(usart2_rx_stream),
166 );
167
168 usart2_tx_stream.set_client(usart2);
169 usart2_rx_stream.set_client(usart2);
170
171 usart2_tx_stream.setup(Dma1Peripheral::USART2_TX);
172 usart2_rx_stream.setup(Dma1Peripheral::USART2_RX);
173
174 cortexm4::nvic::Nvic::new(Dma1Peripheral::USART2_TX.get_stream_irqn()).enable();
175 cortexm4::nvic::Nvic::new(Dma1Peripheral::USART2_RX.get_stream_irqn()).enable();
176}
177
178unsafe fn set_pin_primary_functions(
180 syscfg: &stm32f412g::syscfg::Syscfg,
181 i2c1: &stm32f412g::i2c::I2C,
182 gpio_ports: &'static stm32f412g::gpio::GpioPorts<'static>,
183 peripheral_clock_frequency: usize,
184) {
185 use kernel::hil::gpio::Configure;
186 use stm32f412g::gpio::{AlternateFunction, Mode, PinId, PortId};
187
188 syscfg.enable_clock();
189
190 gpio_ports.get_port_from_port_id(PortId::E).enable_clock();
191
192 gpio_ports.get_pin(PinId::PE02).map(|pin| {
194 pin.make_output();
195
196 kernel::debug::assign_gpios(Some(pin), None, None);
198 });
199
200 gpio_ports.get_port_from_port_id(PortId::A).enable_clock();
201
202 gpio_ports.get_pin(PinId::PA02).map(|pin| {
204 pin.set_mode(Mode::AlternateFunctionMode);
205 pin.set_alternate_function(AlternateFunction::AF7);
207 });
208 gpio_ports.get_pin(PinId::PA03).map(|pin| {
209 pin.set_mode(Mode::AlternateFunctionMode);
210 pin.set_alternate_function(AlternateFunction::AF7);
212 });
213
214 gpio_ports.get_pin(PinId::PG01).map(|pin| {
222 pin.enable_interrupt();
223 });
224
225 gpio_ports.get_pin(PinId::PF15).map(|pin| {
227 pin.enable_interrupt();
228 });
229
230 gpio_ports.get_pin(PinId::PF14).map(|pin| {
232 pin.enable_interrupt();
233 });
234
235 gpio_ports.get_pin(PinId::PG00).map(|pin| {
237 pin.enable_interrupt();
238 });
239
240 gpio_ports.get_pin(PinId::PG09).map(|pin| {
242 pin.enable_interrupt();
243 });
244
245 gpio_ports.get_port_from_port_id(PortId::B).enable_clock();
248 gpio_ports.get_port_from_port_id(PortId::C).enable_clock();
250 gpio_ports.get_port_from_port_id(PortId::D).enable_clock();
251 gpio_ports.get_port_from_port_id(PortId::F).enable_clock();
252 gpio_ports.get_port_from_port_id(PortId::G).enable_clock();
253 gpio_ports.get_port_from_port_id(PortId::H).enable_clock();
254
255 gpio_ports.get_pin(PinId::PB06).map(|pin| {
257 pin.set_mode_output_opendrain();
259 pin.set_mode(Mode::AlternateFunctionMode);
260 pin.set_floating_state(kernel::hil::gpio::FloatingState::PullNone);
261 pin.set_alternate_function(AlternateFunction::AF4);
263 });
264 gpio_ports.get_pin(PinId::PB07).map(|pin| {
265 pin.set_mode_output_opendrain();
267 pin.set_floating_state(kernel::hil::gpio::FloatingState::PullNone);
268 pin.set_mode(Mode::AlternateFunctionMode);
269 pin.set_alternate_function(AlternateFunction::AF4);
271 });
272
273 i2c1.enable_clock();
274 i2c1.set_speed(
275 stm32f412g::i2c::I2CSpeed::Speed400k,
276 peripheral_clock_frequency,
277 );
278
279 gpio_ports.get_pin(PinId::PG05).map(|pin| {
281 pin.enable_interrupt();
282 });
283
284 gpio_ports.get_pin(PinId::PA01).map(|pin| {
288 pin.set_mode(stm32f412g::gpio::Mode::AnalogMode);
289 });
290
291 gpio_ports.get_pin(PinId::PC01).map(|pin| {
293 pin.set_mode(stm32f412g::gpio::Mode::AnalogMode);
294 });
295
296 gpio_ports.get_pin(PinId::PC03).map(|pin| {
298 pin.set_mode(stm32f412g::gpio::Mode::AnalogMode);
299 });
300
301 gpio_ports.get_pin(PinId::PC04).map(|pin| {
303 pin.set_mode(stm32f412g::gpio::Mode::AnalogMode);
304 });
305
306 gpio_ports.get_pin(PinId::PC05).map(|pin| {
308 pin.set_mode(stm32f412g::gpio::Mode::AnalogMode);
309 });
310
311 gpio_ports.get_pin(PinId::PB00).map(|pin| {
313 pin.set_mode(stm32f412g::gpio::Mode::AnalogMode);
314 });
315
316 cortexm4::nvic::Nvic::new(stm32f412g::nvic::EXTI9_5).enable();
318
319 let pins = [
322 PinId::PD00,
323 PinId::PD01,
324 PinId::PD04,
325 PinId::PD05,
326 PinId::PD08,
327 PinId::PD09,
328 PinId::PD10,
329 PinId::PD14,
330 PinId::PD15,
331 PinId::PD07,
332 PinId::PE07,
333 PinId::PE08,
334 PinId::PE09,
335 PinId::PE10,
336 PinId::PE11,
337 PinId::PE12,
338 PinId::PE13,
339 PinId::PE14,
340 PinId::PE15,
341 PinId::PF00,
342 ];
343
344 for pin in pins.iter() {
345 gpio_ports.get_pin(*pin).map(|pin| {
346 pin.set_mode(stm32f412g::gpio::Mode::AlternateFunctionMode);
347 pin.set_floating_state(gpio::FloatingState::PullUp);
348 pin.set_speed();
349 pin.set_alternate_function(stm32f412g::gpio::AlternateFunction::AF12);
350 });
351 }
352
353 use kernel::hil::gpio::Output;
354
355 gpio_ports.get_pin(PinId::PF05).map(|pin| {
356 pin.make_output();
357 pin.set_floating_state(gpio::FloatingState::PullNone);
358 pin.set();
359 });
360
361 gpio_ports.get_pin(PinId::PG04).map(|pin| {
362 pin.make_input();
363 });
364}
365
366unsafe fn setup_peripherals(
368 tim2: &stm32f412g::tim2::Tim2,
369 fsmc: &stm32f412g::fsmc::Fsmc,
370 trng: &stm32f412g::trng::Trng,
371) {
372 cortexm4::nvic::Nvic::new(stm32f412g::nvic::USART2).enable();
374
375 tim2.enable_clock();
377 tim2.start();
378 cortexm4::nvic::Nvic::new(stm32f412g::nvic::TIM2).enable();
379
380 fsmc.enable();
382
383 trng.enable_clock();
385}
386
387#[inline(never)]
393unsafe fn start() -> (
394 &'static kernel::Kernel,
395 STM32F412GDiscovery,
396 &'static stm32f412g::chip::Stm32f4xx<'static, Stm32f412gDefaultPeripherals<'static>>,
397) {
398 stm32f412g::init();
399
400 let rcc = static_init!(stm32f412g::rcc::Rcc, stm32f412g::rcc::Rcc::new());
401 let clocks = static_init!(
402 stm32f412g::clocks::Clocks<Stm32f412Specs>,
403 stm32f412g::clocks::Clocks::new(rcc)
404 );
405
406 let syscfg = static_init!(
407 stm32f412g::syscfg::Syscfg,
408 stm32f412g::syscfg::Syscfg::new(clocks)
409 );
410
411 let exti = static_init!(stm32f412g::exti::Exti, stm32f412g::exti::Exti::new(syscfg));
412
413 let dma1 = static_init!(stm32f412g::dma::Dma1, stm32f412g::dma::Dma1::new(clocks));
414 let dma2 = static_init!(stm32f412g::dma::Dma2, stm32f412g::dma::Dma2::new(clocks));
415
416 let peripherals = static_init!(
417 Stm32f412gDefaultPeripherals,
418 Stm32f412gDefaultPeripherals::new(clocks, exti, dma1, dma2)
419 );
420
421 peripherals.init();
422
423 let _ = clocks.set_ahb_prescaler(stm32f412g::rcc::AHBPrescaler::DivideBy1);
424 let _ = clocks.set_apb1_prescaler(stm32f412g::rcc::APBPrescaler::DivideBy4);
425 let _ = clocks.set_apb2_prescaler(stm32f412g::rcc::APBPrescaler::DivideBy2);
426 let _ = clocks.set_pll_frequency_mhz(PllSource::HSI, 100);
427 let _ = clocks.pll.enable();
428 let _ = clocks.set_sys_clock_source(stm32f412g::rcc::SysClockSource::PLL);
429
430 let base_peripherals = &peripherals.stm32f4;
431 setup_peripherals(
432 &base_peripherals.tim2,
433 &base_peripherals.fsmc,
434 &peripherals.trng,
435 );
436
437 set_pin_primary_functions(
438 syscfg,
439 &base_peripherals.i2c1,
440 &base_peripherals.gpio_ports,
441 clocks.get_apb1_frequency_mhz(),
442 );
443
444 setup_dma(
445 dma1,
446 &base_peripherals.dma1_streams,
447 &base_peripherals.usart2,
448 );
449
450 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&*addr_of!(PROCESSES)));
451
452 let chip = static_init!(
453 stm32f412g::chip::Stm32f4xx<Stm32f412gDefaultPeripherals>,
454 stm32f412g::chip::Stm32f4xx::new(peripherals)
455 );
456 CHIP = Some(chip);
457
458 base_peripherals.usart2.enable_clock();
462 let uart_mux = components::console::UartMuxComponent::new(&base_peripherals.usart2, 115200)
463 .finalize(components::uart_mux_component_static!());
464
465 (*addr_of_mut!(io::WRITER)).set_initialized();
466
467 let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
470 let process_management_capability =
471 create_capability!(capabilities::ProcessManagementCapability);
472
473 let console = components::console::ConsoleComponent::new(
475 board_kernel,
476 capsules_core::console::DRIVER_NUM,
477 uart_mux,
478 )
479 .finalize(components::console_component_static!());
480 components::debug_writer::DebugWriterComponent::new(uart_mux)
482 .finalize(components::debug_writer_component_static!());
483
484 let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
489 LedLow<'static, stm32f412g::gpio::Pin>,
490 LedLow::new(
491 base_peripherals
492 .gpio_ports
493 .get_pin(stm32f412g::gpio::PinId::PE00)
494 .unwrap()
495 ),
496 LedLow::new(
497 base_peripherals
498 .gpio_ports
499 .get_pin(stm32f412g::gpio::PinId::PE01)
500 .unwrap()
501 ),
502 LedLow::new(
503 base_peripherals
504 .gpio_ports
505 .get_pin(stm32f412g::gpio::PinId::PE02)
506 .unwrap()
507 ),
508 LedLow::new(
509 base_peripherals
510 .gpio_ports
511 .get_pin(stm32f412g::gpio::PinId::PE03)
512 .unwrap()
513 ),
514 ));
515
516 let button = components::button::ButtonComponent::new(
518 board_kernel,
519 capsules_core::button::DRIVER_NUM,
520 components::button_component_helper!(
521 stm32f412g::gpio::Pin,
522 (
524 base_peripherals
525 .gpio_ports
526 .get_pin(stm32f412g::gpio::PinId::PA00)
527 .unwrap(),
528 kernel::hil::gpio::ActivationMode::ActiveHigh,
529 kernel::hil::gpio::FloatingState::PullNone
530 ),
531 (
533 base_peripherals
534 .gpio_ports
535 .get_pin(stm32f412g::gpio::PinId::PG01)
536 .unwrap(),
537 kernel::hil::gpio::ActivationMode::ActiveHigh,
538 kernel::hil::gpio::FloatingState::PullNone
539 ),
540 (
542 base_peripherals
543 .gpio_ports
544 .get_pin(stm32f412g::gpio::PinId::PF15)
545 .unwrap(),
546 kernel::hil::gpio::ActivationMode::ActiveHigh,
547 kernel::hil::gpio::FloatingState::PullNone
548 ),
549 (
551 base_peripherals
552 .gpio_ports
553 .get_pin(stm32f412g::gpio::PinId::PF14)
554 .unwrap(),
555 kernel::hil::gpio::ActivationMode::ActiveHigh,
556 kernel::hil::gpio::FloatingState::PullNone
557 ),
558 (
560 base_peripherals
561 .gpio_ports
562 .get_pin(stm32f412g::gpio::PinId::PG00)
563 .unwrap(),
564 kernel::hil::gpio::ActivationMode::ActiveHigh,
565 kernel::hil::gpio::FloatingState::PullNone
566 )
567 ),
568 )
569 .finalize(components::button_component_static!(stm32f412g::gpio::Pin));
570
571 let tim2 = &base_peripherals.tim2;
574 let mux_alarm = components::alarm::AlarmMuxComponent::new(tim2).finalize(
575 components::alarm_mux_component_static!(stm32f412g::tim2::Tim2),
576 );
577
578 let alarm = components::alarm::AlarmDriverComponent::new(
579 board_kernel,
580 capsules_core::alarm::DRIVER_NUM,
581 mux_alarm,
582 )
583 .finalize(components::alarm_component_static!(stm32f412g::tim2::Tim2));
584
585 let gpio = GpioComponent::new(
587 board_kernel,
588 capsules_core::gpio::DRIVER_NUM,
589 components::gpio_component_helper!(
590 stm32f412g::gpio::Pin,
591 0 => base_peripherals.gpio_ports.get_pin(stm32f412g::gpio::PinId::PG09).unwrap(), 1 => base_peripherals.gpio_ports.get_pin(stm32f412g::gpio::PinId::PG14).unwrap(), 2 => base_peripherals.gpio_ports.get_pin(stm32f412g::gpio::PinId::PG13).unwrap(), 3 => base_peripherals.gpio_ports.get_pin(stm32f412g::gpio::PinId::PF04).unwrap(), 4 => base_peripherals.gpio_ports.get_pin(stm32f412g::gpio::PinId::PG12).unwrap(), 5 => base_peripherals.gpio_ports.get_pin(stm32f412g::gpio::PinId::PF10).unwrap(), 6 => base_peripherals.gpio_ports.get_pin(stm32f412g::gpio::PinId::PF03).unwrap(), 7 => base_peripherals.gpio_ports.get_pin(stm32f412g::gpio::PinId::PG11).unwrap(), 8 => base_peripherals.gpio_ports.get_pin(stm32f412g::gpio::PinId::PG10).unwrap(), 9 => base_peripherals.gpio_ports.get_pin(stm32f412g::gpio::PinId::PB08).unwrap(), 10 => base_peripherals.gpio_ports.get_pin(stm32f412g::gpio::PinId::PA15).unwrap(), 11 => base_peripherals.gpio_ports.get_pin(stm32f412g::gpio::PinId::PA07).unwrap(), 12 => base_peripherals.gpio_ports.get_pin(stm32f412g::gpio::PinId::PA06).unwrap(), 13 => base_peripherals.gpio_ports.get_pin(stm32f412g::gpio::PinId::PA15).unwrap() ),
617 )
618 .finalize(components::gpio_component_static!(stm32f412g::gpio::Pin));
619
620 let rng = RngComponent::new(
622 board_kernel,
623 capsules_core::rng::DRIVER_NUM,
624 &peripherals.trng,
625 )
626 .finalize(components::rng_component_static!(stm32f412g::trng::Trng));
627
628 let mux_i2c = components::i2c::I2CMuxComponent::new(&base_peripherals.i2c1, None)
631 .finalize(components::i2c_mux_component_static!(stm32f412g::i2c::I2C));
632
633 let ft6x06 = components::ft6x06::Ft6x06Component::new(
634 mux_i2c,
635 0x38,
636 base_peripherals
637 .gpio_ports
638 .get_pin(stm32f412g::gpio::PinId::PG05)
639 .unwrap(),
640 )
641 .finalize(components::ft6x06_component_static!(stm32f412g::i2c::I2C));
642
643 let bus = components::bus::Bus8080BusComponent::new(&base_peripherals.fsmc).finalize(
644 components::bus8080_bus_component_static!(stm32f412g::fsmc::Fsmc,),
645 );
646
647 let tft = components::st77xx::ST77XXComponent::new(
648 mux_alarm,
649 bus,
650 None,
651 base_peripherals
652 .gpio_ports
653 .get_pin(stm32f412g::gpio::PinId::PD11),
654 &capsules_extra::st77xx::ST7789H2,
655 )
656 .finalize(components::st77xx_component_static!(
657 capsules_extra::bus::Bus8080Bus<'static, stm32f412g::fsmc::Fsmc>,
659 stm32f412g::tim2::Tim2,
661 stm32f412g::gpio::Pin,
663 ));
664
665 let _ = tft.init();
666
667 let screen = components::screen::ScreenComponent::new(
668 board_kernel,
669 capsules_extra::screen::DRIVER_NUM,
670 tft,
671 Some(tft),
672 )
673 .finalize(components::screen_component_static!(1024));
674
675 let touch = components::touch::MultiTouchComponent::new(
676 board_kernel,
677 capsules_extra::touch::DRIVER_NUM,
678 ft6x06,
679 Some(ft6x06),
680 Some(tft),
681 )
682 .finalize(components::touch_component_static!());
683
684 touch.set_screen_rotation_offset(ScreenRotation::Rotated90);
685
686 let adc_mux = components::adc::AdcMuxComponent::new(&base_peripherals.adc1)
693 .finalize(components::adc_mux_component_static!(stm32f412g::adc::Adc));
694
695 let temp_sensor = components::temperature_stm::TemperatureSTMComponent::new(
696 adc_mux,
697 stm32f412g::adc::Channel::Channel18,
698 2.5,
699 0.76,
700 )
701 .finalize(components::temperature_stm_adc_component_static!(
702 stm32f412g::adc::Adc
703 ));
704
705 let temp = components::temperature::TemperatureComponent::new(
706 board_kernel,
707 capsules_extra::temperature::DRIVER_NUM,
708 temp_sensor,
709 )
710 .finalize(components::temperature_component_static!(
711 TemperatureSTMSensor
712 ));
713
714 let adc_channel_0 =
715 components::adc::AdcComponent::new(adc_mux, stm32f412g::adc::Channel::Channel1)
716 .finalize(components::adc_component_static!(stm32f412g::adc::Adc));
717
718 let adc_channel_1 =
719 components::adc::AdcComponent::new(adc_mux, stm32f412g::adc::Channel::Channel11)
720 .finalize(components::adc_component_static!(stm32f412g::adc::Adc));
721
722 let adc_channel_2 =
723 components::adc::AdcComponent::new(adc_mux, stm32f412g::adc::Channel::Channel13)
724 .finalize(components::adc_component_static!(stm32f412g::adc::Adc));
725
726 let adc_channel_3 =
727 components::adc::AdcComponent::new(adc_mux, stm32f412g::adc::Channel::Channel14)
728 .finalize(components::adc_component_static!(stm32f412g::adc::Adc));
729
730 let adc_channel_4 =
731 components::adc::AdcComponent::new(adc_mux, stm32f412g::adc::Channel::Channel15)
732 .finalize(components::adc_component_static!(stm32f412g::adc::Adc));
733
734 let adc_channel_5 =
735 components::adc::AdcComponent::new(adc_mux, stm32f412g::adc::Channel::Channel8)
736 .finalize(components::adc_component_static!(stm32f412g::adc::Adc));
737
738 let adc_syscall =
739 components::adc::AdcVirtualComponent::new(board_kernel, capsules_core::adc::DRIVER_NUM)
740 .finalize(components::adc_syscall_component_helper!(
741 adc_channel_0,
742 adc_channel_1,
743 adc_channel_2,
744 adc_channel_3,
745 adc_channel_4,
746 adc_channel_5
747 ));
748
749 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
750 .finalize(components::process_printer_text_component_static!());
751 PROCESS_PRINTER = Some(process_printer);
752
753 let process_console = components::process_console::ProcessConsoleComponent::new(
755 board_kernel,
756 uart_mux,
757 mux_alarm,
758 process_printer,
759 Some(cortexm4::support::reset),
760 )
761 .finalize(components::process_console_component_static!(
762 stm32f412g::tim2::Tim2
763 ));
764 let _ = process_console.start();
765
766 let scheduler = components::sched::round_robin::RoundRobinComponent::new(&*addr_of!(PROCESSES))
767 .finalize(components::round_robin_component_static!(NUM_PROCS));
768
769 let stm32f412g = STM32F412GDiscovery {
770 console,
771 ipc: kernel::ipc::IPC::new(
772 board_kernel,
773 kernel::ipc::DRIVER_NUM,
774 &memory_allocation_capability,
775 ),
776 led,
777 button,
778 alarm,
779 gpio,
780 adc: adc_syscall,
781 touch,
782 screen,
783 temperature: temp,
784 rng,
785
786 scheduler,
787 systick: cortexm4::systick::SysTick::new_with_calibration(
788 (HSI_FREQUENCY_MHZ * 1_000_000) as u32,
789 ),
790 };
791
792 debug!("Initialization complete. Entering main loop");
800
801 extern "C" {
802 static _sapps: u8;
806
807 static _eapps: u8;
811
812 static mut _sappmem: u8;
816
817 static _eappmem: u8;
821 }
822
823 kernel::process::load_processes(
824 board_kernel,
825 chip,
826 core::slice::from_raw_parts(
827 core::ptr::addr_of!(_sapps),
828 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
829 ),
830 core::slice::from_raw_parts_mut(
831 core::ptr::addr_of_mut!(_sappmem),
832 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
833 ),
834 &mut *addr_of_mut!(PROCESSES),
835 &FAULT_RESPONSE,
836 &process_management_capability,
837 )
838 .unwrap_or_else(|err| {
839 debug!("Error loading processes!");
840 debug!("{:?}", err);
841 });
842
843 (board_kernel, stm32f412g, chip)
849}
850
851#[no_mangle]
853pub unsafe fn main() {
854 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
855
856 let (board_kernel, platform, chip) = start();
857 board_kernel.kernel_loop(&platform, chip, Some(&platform.ipc), &main_loop_capability);
858}