Update out-of-tree board to new kernel
This commit is contained in:
@@ -15,4 +15,4 @@ cortexm4 = { path = "../../../arch/cortex-m4" }
|
||||
capsules = { path = "../../../capsules" }
|
||||
kernel = { path = "../../../kernel" }
|
||||
nrf52840 = { path = "../../../chips/nrf52840" }
|
||||
nrf52dk_base = { path = "../nrf52dk_base" }
|
||||
nrf52_components = { path = "../nrf52_components" }
|
||||
|
||||
@@ -11,4 +11,4 @@ cortexm4 = { path = "../../../arch/cortex-m4" }
|
||||
capsules = { path = "../../../capsules" }
|
||||
kernel = { path = "../../../kernel" }
|
||||
nrf52840 = { path = "../../../chips/nrf52840" }
|
||||
nrf52dk_base = { path = "../nrf52dk_base" }
|
||||
nrf52_components = { path = "../nrf52_components" }
|
||||
|
||||
@@ -4,14 +4,20 @@
|
||||
//! many exported I/O and peripherals.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
// Disable this attribute when documenting, as a workaround for
|
||||
// https://github.com/rust-lang/rust/issues/62184.
|
||||
#![cfg_attr(not(doc), no_main)]
|
||||
#![feature(const_in_array_repeat_expressions)]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
use capsules::virtual_alarm::VirtualMuxAlarm;
|
||||
use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferredCallClientState};
|
||||
use kernel::component::Component;
|
||||
#[allow(unused_imports)]
|
||||
use kernel::{debug, debug_gpio, debug_verbose, static_init};
|
||||
use kernel::{capabilities, create_capability, debug, debug_gpio, debug_verbose, static_init};
|
||||
use kernel::hil::usb::UsbController;
|
||||
use nrf52840::gpio::Pin;
|
||||
use nrf52dk_base::{SpiPins, UartChannel, UartPins};
|
||||
use nrf52_components::{self, UartChannel, UartPins};
|
||||
|
||||
// The nRF52840 MDK USB Dongle LEDs
|
||||
const LED1_R_PIN: Pin = Pin::P0_23;
|
||||
@@ -27,13 +33,24 @@ const UART_TXD: Pin = Pin::P0_20;
|
||||
const UART_CTS: Option<Pin> = Some(Pin::P0_03);
|
||||
const UART_RXD: Pin = Pin::P0_19;
|
||||
|
||||
const SPI_MOSI: Pin = Pin::P0_05;
|
||||
const SPI_MISO: Pin = Pin::P0_06;
|
||||
const SPI_CLK: Pin = Pin::P0_07;
|
||||
// Constants related to the configuration of the 15.4 network stack
|
||||
const SRC_MAC: u16 = 0xf00f;
|
||||
const PAN_ID: u16 = 0xABCD;
|
||||
|
||||
/// UART Writer
|
||||
pub mod io;
|
||||
|
||||
const VENDOR_ID: u16 = 0x1915; // Nordic Semiconductor
|
||||
const PRODUCT_ID: u16 = 0x521f; // nRF52840 Dongle (PCA10059)
|
||||
static STRINGS: &'static [&'static str] = &[
|
||||
// Manufacturer
|
||||
"Nordic Semiconductor ASA",
|
||||
// Product
|
||||
"OpenSK",
|
||||
// Serial number
|
||||
"v0.1",
|
||||
];
|
||||
|
||||
// State for loading and holding applications.
|
||||
// How should the kernel respond when a process faults.
|
||||
const FAULT_RESPONSE: kernel::procs::FaultResponse = kernel::procs::FaultResponse::Panic;
|
||||
@@ -41,12 +58,8 @@ const FAULT_RESPONSE: kernel::procs::FaultResponse = kernel::procs::FaultRespons
|
||||
// Number of concurrent processes this platform supports.
|
||||
const NUM_PROCS: usize = 8;
|
||||
|
||||
// RAM to be shared by all application processes.
|
||||
#[link_section = ".app_memory"]
|
||||
static mut APP_MEMORY: [u8; 0x3C000] = [0; 0x3C000];
|
||||
|
||||
static mut PROCESSES: [Option<&'static dyn kernel::procs::ProcessType>; NUM_PROCS] =
|
||||
[None, None, None, None, None, None, None, None];
|
||||
[None; NUM_PROCS];
|
||||
|
||||
static mut STORAGE_LOCATIONS: [kernel::StorageLocation; 1] = [kernel::StorageLocation {
|
||||
address: 0xC0000,
|
||||
@@ -61,6 +74,84 @@ static mut CHIP: Option<&'static nrf52840::chip::Chip> = None;
|
||||
#[link_section = ".stack_buffer"]
|
||||
pub static mut STACK_MEMORY: [u8; 0x1000] = [0; 0x1000];
|
||||
|
||||
/// Supported drivers by the platform
|
||||
pub struct Platform {
|
||||
ble_radio: &'static capsules::ble_advertising_driver::BLE<
|
||||
'static,
|
||||
nrf52840::ble_radio::Radio<'static>,
|
||||
VirtualMuxAlarm<'static, nrf52840::rtc::Rtc<'static>>,
|
||||
>,
|
||||
ieee802154_radio: &'static capsules::ieee802154::RadioDriver<'static>,
|
||||
button: &'static capsules::button::Button<'static, nrf52840::gpio::GPIOPin<'static>>,
|
||||
pconsole: &'static capsules::process_console::ProcessConsole<
|
||||
'static,
|
||||
components::process_console::Capability,
|
||||
>,
|
||||
console: &'static capsules::console::Console<'static>,
|
||||
gpio: &'static capsules::gpio::GPIO<'static, nrf52840::gpio::GPIOPin<'static>>,
|
||||
led: &'static capsules::led::LED<'static, nrf52840::gpio::GPIOPin<'static>>,
|
||||
rng: &'static capsules::rng::RngDriver<'static>,
|
||||
temp: &'static capsules::temperature::TemperatureSensor<'static>,
|
||||
ipc: kernel::ipc::IPC,
|
||||
analog_comparator: &'static capsules::analog_comparator::AnalogComparator<
|
||||
'static,
|
||||
nrf52840::acomp::Comparator<'static>,
|
||||
>,
|
||||
alarm: &'static capsules::alarm::AlarmDriver<
|
||||
'static,
|
||||
capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52840::rtc::Rtc<'static>>,
|
||||
>,
|
||||
nvmc: &'static nrf52840::nvmc::SyscallDriver,
|
||||
usb: &'static capsules::usb::usb_ctap::CtapUsbSyscallDriver<
|
||||
'static,
|
||||
'static,
|
||||
nrf52840::usbd::Usbd<'static>,
|
||||
>,
|
||||
}
|
||||
|
||||
impl kernel::Platform for Platform {
|
||||
fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
|
||||
where
|
||||
F: FnOnce(Option<&dyn kernel::Driver>) -> R,
|
||||
{
|
||||
match driver_num {
|
||||
capsules::console::DRIVER_NUM => f(Some(self.console)),
|
||||
capsules::gpio::DRIVER_NUM => f(Some(self.gpio)),
|
||||
capsules::alarm::DRIVER_NUM => f(Some(self.alarm)),
|
||||
capsules::led::DRIVER_NUM => f(Some(self.led)),
|
||||
capsules::button::DRIVER_NUM => f(Some(self.button)),
|
||||
capsules::rng::DRIVER_NUM => f(Some(self.rng)),
|
||||
capsules::ble_advertising_driver::DRIVER_NUM => f(Some(self.ble_radio)),
|
||||
capsules::ieee802154::DRIVER_NUM => f(Some(self.ieee802154_radio)),
|
||||
capsules::temperature::DRIVER_NUM => f(Some(self.temp)),
|
||||
capsules::analog_comparator::DRIVER_NUM => f(Some(self.analog_comparator)),
|
||||
nrf52840::nvmc::DRIVER_NUM => f(Some(self.nvmc)),
|
||||
capsules::usb::usb_ctap::DRIVER_NUM => f(Some(self.usb)),
|
||||
kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
|
||||
_ => f(None),
|
||||
}
|
||||
}
|
||||
|
||||
fn filter_syscall(
|
||||
&self,
|
||||
process: &dyn kernel::procs::ProcessType,
|
||||
syscall: &kernel::syscall::Syscall,
|
||||
) -> Result<(), kernel::ReturnCode> {
|
||||
use kernel::syscall::Syscall;
|
||||
match *syscall {
|
||||
Syscall::COMMAND {
|
||||
driver_number: nrf52840::nvmc::DRIVER_NUM,
|
||||
subdriver_number: cmd,
|
||||
arg0: ptr,
|
||||
arg1: len,
|
||||
} if (cmd == 2 || cmd == 3) && !process.fits_in_storage_location(ptr, len) => {
|
||||
Err(kernel::ReturnCode::EINVAL)
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Entry point in the vector table called on hard reset.
|
||||
#[no_mangle]
|
||||
pub unsafe fn reset_handler() {
|
||||
@@ -72,24 +163,34 @@ pub unsafe fn reset_handler() {
|
||||
kernel::Kernel::new_with_storage(&PROCESSES, &STORAGE_LOCATIONS)
|
||||
);
|
||||
// GPIOs
|
||||
let gpio = components::gpio::GpioComponent::new(board_kernel).finalize(
|
||||
let gpio = components::gpio::GpioComponent::new(
|
||||
board_kernel,
|
||||
components::gpio_component_helper!(
|
||||
&nrf52840::gpio::PORT[Pin::P0_04],
|
||||
&nrf52840::gpio::PORT[Pin::P0_05],
|
||||
&nrf52840::gpio::PORT[Pin::P0_06],
|
||||
&nrf52840::gpio::PORT[Pin::P0_07],
|
||||
&nrf52840::gpio::PORT[Pin::P0_08]
|
||||
nrf52840::gpio::GPIOPin,
|
||||
// left side of the USB plug. Right side is used for UART
|
||||
0 => &nrf52840::gpio::PORT[Pin::P0_04],
|
||||
1 => &nrf52840::gpio::PORT[Pin::P0_05],
|
||||
2 => &nrf52840::gpio::PORT[Pin::P0_06],
|
||||
3 => &nrf52840::gpio::PORT[Pin::P0_07],
|
||||
4 => &nrf52840::gpio::PORT[Pin::P0_08]
|
||||
),
|
||||
);
|
||||
let button = components::button::ButtonComponent::new(board_kernel).finalize(
|
||||
components::button_component_helper!((
|
||||
&nrf52840::gpio::PORT[BUTTON_PIN],
|
||||
kernel::hil::gpio::ActivationMode::ActiveLow,
|
||||
kernel::hil::gpio::FloatingState::PullUp
|
||||
)),
|
||||
);
|
||||
).finalize(components::gpio_component_buf!(nrf52840::gpio::GPIOPin));
|
||||
|
||||
let led = components::led::LedsComponent::new().finalize(components::led_component_helper!(
|
||||
let button = components::button::ButtonComponent::new(
|
||||
board_kernel,
|
||||
components::button_component_helper!(
|
||||
nrf52840::gpio::GPIOPin,
|
||||
(
|
||||
&nrf52840::gpio::PORT[BUTTON_PIN],
|
||||
kernel::hil::gpio::ActivationMode::ActiveLow,
|
||||
kernel::hil::gpio::FloatingState::PullUp
|
||||
)
|
||||
),
|
||||
)
|
||||
.finalize(components::button_component_buf!(nrf52840::gpio::GPIOPin));
|
||||
|
||||
let led = components::led::LedsComponent::new(components::led_component_helper!(
|
||||
nrf52840::gpio::GPIOPin,
|
||||
(
|
||||
&nrf52840::gpio::PORT[LED1_R_PIN],
|
||||
kernel::hil::gpio::ActivationMode::ActiveLow
|
||||
@@ -102,30 +203,216 @@ pub unsafe fn reset_handler() {
|
||||
&nrf52840::gpio::PORT[LED1_B_PIN],
|
||||
kernel::hil::gpio::ActivationMode::ActiveLow
|
||||
)
|
||||
));
|
||||
))
|
||||
.finalize(components::led_component_buf!(nrf52840::gpio::GPIOPin));
|
||||
|
||||
let chip = static_init!(nrf52840::chip::Chip, nrf52840::chip::new());
|
||||
CHIP = Some(chip);
|
||||
|
||||
nrf52dk_base::setup_board(
|
||||
board_kernel,
|
||||
nrf52_components::startup::NrfStartupComponent::new(
|
||||
false,
|
||||
BUTTON_RST_PIN,
|
||||
&nrf52840::gpio::PORT,
|
||||
gpio,
|
||||
LED1_R_PIN,
|
||||
LED1_G_PIN,
|
||||
LED1_B_PIN,
|
||||
led,
|
||||
UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD)),
|
||||
&SpiPins::new(SPI_MOSI, SPI_MISO, SPI_CLK),
|
||||
&None,
|
||||
nrf52840::uicr::Regulator0Output::V3_0,
|
||||
)
|
||||
.finalize(());
|
||||
|
||||
// Create capabilities that the board needs to call certain protected kernel
|
||||
// functions.
|
||||
let process_management_capability =
|
||||
create_capability!(capabilities::ProcessManagementCapability);
|
||||
let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
|
||||
let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
|
||||
|
||||
let gpio_port = &nrf52840::gpio::PORT;
|
||||
|
||||
// Configure kernel debug gpios as early as possible
|
||||
kernel::debug::assign_gpios(
|
||||
Some(&gpio_port[LED1_R_PIN]),
|
||||
Some(&gpio_port[LED1_G_PIN]),
|
||||
Some(&gpio_port[LED1_B_PIN]),
|
||||
);
|
||||
|
||||
let rtc = &nrf52840::rtc::RTC;
|
||||
rtc.start();
|
||||
let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
|
||||
.finalize(components::alarm_mux_component_helper!(nrf52840::rtc::Rtc));
|
||||
let alarm = components::alarm::AlarmDriverComponent::new(board_kernel, mux_alarm)
|
||||
.finalize(components::alarm_component_helper!(nrf52840::rtc::Rtc));
|
||||
let uart_channel = UartChannel::Pins(UartPins::new(UART_RTS, UART_TXD, UART_CTS, UART_RXD));
|
||||
let channel = nrf52_components::UartChannelComponent::new(uart_channel, mux_alarm).finalize(());
|
||||
|
||||
let dynamic_deferred_call_clients =
|
||||
static_init!([DynamicDeferredCallClientState; 2], Default::default());
|
||||
let dynamic_deferred_caller = static_init!(
|
||||
DynamicDeferredCall,
|
||||
DynamicDeferredCall::new(dynamic_deferred_call_clients)
|
||||
);
|
||||
DynamicDeferredCall::set_global_instance(dynamic_deferred_caller);
|
||||
|
||||
// Create a shared UART channel for the console and for kernel debug.
|
||||
let uart_mux =
|
||||
components::console::UartMuxComponent::new(channel, 115200, dynamic_deferred_caller)
|
||||
.finalize(());
|
||||
|
||||
let pconsole =
|
||||
components::process_console::ProcessConsoleComponent::new(board_kernel, uart_mux)
|
||||
.finalize(());
|
||||
|
||||
// Setup the console.
|
||||
let console = components::console::ConsoleComponent::new(board_kernel, uart_mux).finalize(());
|
||||
// Create the debugger object that handles calls to `debug!()`.
|
||||
components::debug_writer::DebugWriterComponent::new(uart_mux).finalize(());
|
||||
|
||||
let ble_radio =
|
||||
nrf52_components::BLEComponent::new(board_kernel, &nrf52840::ble_radio::RADIO, mux_alarm)
|
||||
.finalize(());
|
||||
|
||||
let (ieee802154_radio, _mux_mac) = components::ieee802154::Ieee802154Component::new(
|
||||
board_kernel,
|
||||
&nrf52840::ieee802154_radio::RADIO,
|
||||
&nrf52840::aes::AESECB,
|
||||
PAN_ID,
|
||||
SRC_MAC,
|
||||
)
|
||||
.finalize(components::ieee802154_component_helper!(
|
||||
nrf52840::ieee802154_radio::Radio,
|
||||
nrf52840::aes::AesECB<'static>
|
||||
));
|
||||
|
||||
let temp = components::temperature::TemperatureComponent::new(
|
||||
board_kernel,
|
||||
&nrf52840::temperature::TEMP,
|
||||
)
|
||||
.finalize(());
|
||||
|
||||
let rng = components::rng::RngComponent::new(board_kernel, &nrf52840::trng::TRNG).finalize(());
|
||||
|
||||
// Initialize AC using AIN5 (P0.29) as VIN+ and VIN- as AIN0 (P0.02)
|
||||
// These are hardcoded pin assignments specified in the driver
|
||||
let analog_comparator = components::analog_comparator::AcComponent::new(
|
||||
&nrf52840::acomp::ACOMP,
|
||||
components::acomp_component_helper!(
|
||||
nrf52840::acomp::Channel,
|
||||
&nrf52840::acomp::CHANNEL_AC0
|
||||
),
|
||||
)
|
||||
.finalize(components::acomp_component_buf!(
|
||||
nrf52840::acomp::Comparator
|
||||
));
|
||||
|
||||
let nvmc = static_init!(
|
||||
nrf52840::nvmc::SyscallDriver,
|
||||
nrf52840::nvmc::SyscallDriver::new(
|
||||
&nrf52840::nvmc::NVMC,
|
||||
board_kernel.create_grant(&memory_allocation_capability),
|
||||
)
|
||||
);
|
||||
|
||||
// Configure USB controller
|
||||
let usb:
|
||||
&'static capsules::usb::usb_ctap::CtapUsbSyscallDriver<
|
||||
'static,
|
||||
'static,
|
||||
nrf52840::usbd::Usbd<'static>,
|
||||
> = {
|
||||
let usb_ctap = static_init!(
|
||||
capsules::usb::usbc_ctap_hid::ClientCtapHID<
|
||||
'static,
|
||||
'static,
|
||||
nrf52840::usbd::Usbd<'static>,
|
||||
>,
|
||||
capsules::usb::usbc_ctap_hid::ClientCtapHID::new(
|
||||
&nrf52840::usbd::USBD,
|
||||
capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840,
|
||||
VENDOR_ID,
|
||||
PRODUCT_ID,
|
||||
STRINGS,
|
||||
)
|
||||
);
|
||||
nrf52840::usbd::USBD.set_client(usb_ctap);
|
||||
|
||||
// Enable power events to be sent to USB controller
|
||||
nrf52840::power::POWER.set_usb_client(&nrf52840::usbd::USBD);
|
||||
nrf52840::power::POWER.enable_interrupts();
|
||||
|
||||
// Configure the USB userspace driver
|
||||
let usb_driver = static_init!(
|
||||
capsules::usb::usb_ctap::CtapUsbSyscallDriver<
|
||||
'static,
|
||||
'static,
|
||||
nrf52840::usbd::Usbd<'static>,
|
||||
>,
|
||||
capsules::usb::usb_ctap::CtapUsbSyscallDriver::new(
|
||||
usb_ctap,
|
||||
board_kernel.create_grant(&memory_allocation_capability)
|
||||
)
|
||||
);
|
||||
usb_ctap.set_client(usb_driver);
|
||||
usb_driver as &'static _
|
||||
};
|
||||
|
||||
nrf52_components::NrfClockComponent::new().finalize(());
|
||||
|
||||
let platform = Platform {
|
||||
button,
|
||||
true,
|
||||
&mut APP_MEMORY,
|
||||
ble_radio,
|
||||
ieee802154_radio,
|
||||
pconsole,
|
||||
console,
|
||||
led,
|
||||
gpio,
|
||||
rng,
|
||||
temp,
|
||||
alarm,
|
||||
analog_comparator,
|
||||
nvmc,
|
||||
usb,
|
||||
ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability),
|
||||
};
|
||||
|
||||
platform.pconsole.start();
|
||||
debug!("Initialization complete. Entering main loop\r");
|
||||
debug!("{}", &nrf52840::ficr::FICR_INSTANCE);
|
||||
|
||||
/// These symbols are defined in the linker script.
|
||||
extern "C" {
|
||||
/// Beginning of the ROM region containing app images.
|
||||
static _sapps: u8;
|
||||
/// End of the ROM region containing app images.
|
||||
static _eapps: u8;
|
||||
/// Beginning of the RAM region for app memory.
|
||||
static mut _sappmem: u8;
|
||||
/// End of the RAM region for app memory.
|
||||
static _eappmem: u8;
|
||||
}
|
||||
|
||||
kernel::procs::load_processes(
|
||||
board_kernel,
|
||||
chip,
|
||||
core::slice::from_raw_parts(
|
||||
&_sapps as *const u8,
|
||||
&_eapps as *const u8 as usize - &_sapps as *const u8 as usize,
|
||||
),
|
||||
core::slice::from_raw_parts_mut(
|
||||
&mut _sappmem as *mut u8,
|
||||
&_eappmem as *const u8 as usize - &_sappmem as *const u8 as usize,
|
||||
),
|
||||
&mut PROCESSES,
|
||||
FAULT_RESPONSE,
|
||||
nrf52840::uicr::Regulator0Output::V3_0,
|
||||
false,
|
||||
&Some(&nrf52840::usbd::USBD),
|
||||
&process_management_capability,
|
||||
)
|
||||
.unwrap_or_else(|err| {
|
||||
debug!("Error loading processes!");
|
||||
debug!("{:?}", err);
|
||||
});
|
||||
|
||||
let scheduler = components::sched::round_robin::RoundRobinComponent::new(&PROCESSES)
|
||||
.finalize(components::rr_component_helper!(NUM_PROCS));
|
||||
board_kernel.kernel_loop(
|
||||
&platform,
|
||||
chip,
|
||||
Some(&platform.ipc),
|
||||
scheduler,
|
||||
&main_loop_capability,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user