Skip to content

Commit

Permalink
add nrf52840dk-bonus
Browse files Browse the repository at this point in the history
  • Loading branch information
bradjc committed Mar 5, 2024
1 parent 6bb6a1c commit c9e1f8e
Show file tree
Hide file tree
Showing 13 changed files with 725 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ members = [
"boards/wm1110dev",
"boards/makepython-nrf52840",
"boards/nordic/nrf52840dk",
"boards/nordic/nrf52840dk-bonus",
"boards/nordic/nrf52840_dongle",
"boards/nordic/nrf52dk",
"boards/sma_q3",
Expand Down
21 changes: 21 additions & 0 deletions boards/nordic/nrf52840dk-bonus/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Licensed under the Apache License, Version 2.0 or the MIT License.
# SPDX-License-Identifier: Apache-2.0 OR MIT
# Copyright Tock Contributors 2022.

[package]
name = "nrf52840dk-bonus"
version.workspace = true
authors.workspace = true
build = "../../build.rs"
edition.workspace = true

[dependencies]
components = { path = "../../components" }
cortexm4 = { path = "../../../arch/cortex-m4" }
kernel = { path = "../../../kernel" }
nrf52840 = { path = "../../../chips/nrf52840" }
nrf52_components = { path = "../nrf52_components" }
nrf52840dk = { path = "../nrf52840dk" }

capsules-core = { path = "../../../capsules/core" }
capsules-extra = { path = "../../../capsules/extra" }
39 changes: 39 additions & 0 deletions boards/nordic/nrf52840dk-bonus/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Licensed under the Apache License, Version 2.0 or the MIT License.
# SPDX-License-Identifier: Apache-2.0 OR MIT
# Copyright Tock Contributors 2022.

# Makefile for building the tock kernel for the nRF development kit

TARGET=thumbv7em-none-eabi
PLATFORM=nrf52840dk-bonus

include ../../Makefile.common

TOCKLOADER=tockloader

# Where in the SAM4L flash to load the kernel with `tockloader`
KERNEL_ADDRESS=0x00000

# Upload programs over uart with tockloader
ifdef PORT
TOCKLOADER_GENERAL_FLAGS += --port $(PORT)
endif

# Default target for installing the kernel.
.PHONY: install
install: flash

# Upload the kernel over JTAG
.PHONY: flash
flash: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).bin
$(TOCKLOADER) $(TOCKLOADER_GENERAL_FLAGS) flash --address $(KERNEL_ADDRESS) --board nrf52dk --jlink $<

# Upload the kernel over JTAG using OpenOCD
.PHONY: flash-openocd
flash-openocd: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).bin
$(TOCKLOADER) $(TOCKLOADER_GENERAL_FLAGS) flash --address $(KERNEL_ADDRESS) --board nrf52dk --openocd $<

# Upload the kernel over serial/bootloader
.PHONY: program
program: $(TOCK_ROOT_DIRECTORY)target/$(TARGET)/release/$(PLATFORM).hex
$(error Cannot program nRF52840DK over USB. Use \`make flash\` and JTAG)
63 changes: 63 additions & 0 deletions boards/nordic/nrf52840dk-bonus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
Platform-Specific Instructions: nRF52840-DK
===================================

The [nRF52840 Development
Kit](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) is a platform
based around the nRF52840, an SoC with an ARM Cortex-M4 and a BLE
radio. The kit is Arduino shield compatible and includes several
buttons.

## Getting Started

First, follow the [Tock Getting Started guide](../../../doc/Getting_Started.md)

JTAG is the preferred method to program. The development kit has an
integrated JTAG debugger, you simply need to [install JTAG
software](../../../doc/Getting_Started.md#loading-the-kernel-onto-a-board).

## Programming the kernel
Once you have all software installed, you should be able to simply run
make flash in this directory to install a fresh kernel.

## Programming user-level applications
You can program an application over USB using the integrated JTAG and `tockloader`:

```bash
$ cd libtock-c/examples/<app>
$ make
$ tockloader install --jlink --board nrf52dk
```

The same options (`--jlink --board nrf52dk`) must be passed for other tockloader commands
such as `erase-apps` or `list`.

Viewing console output on the nrf52840dk is slightly different from other boards. You must use
```bash
$ tockloader listen
```
**followed by a press of the reset button** in order to view console output starting from the boot
sequence. Notably, you should not
pass the `--jlink` option to `tockloader listen`.

## Console output

This board supports two methods for writing messages to a console interface
(console driver for applications as well as debug statements in the kernel).

By default, messages are written to a UART interface over the GPIO pins `P0.05`
to `P0.08` (see the [main.rs](src/main.rs) file).

If you don't have any UART cables or want to use a different interface, there is
also a console over the Segger RTT protocol. This only requires a micro-USB
cable on the USB debugging port (the same used to flash Tock on the board), and
is enabled by setting the `USB_DEBUGGING` constant to `true` in the
[main.rs](src/main.rs) file.
This disables the UART interface.

For instructions about how to receive RTT messages on the host, see the
[corresponding capsule](../../../capsules/src/segger_rtt.rs).

## Debugging

See the [nrf52dk README](../nrf52dk/README.md) for information about debugging
the nRF52840dk.
28 changes: 28 additions & 0 deletions boards/nordic/nrf52840dk-bonus/jtag/gdbinit_pca10040.jlink
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Licensed under the Apache License, Version 2.0 or the MIT License.
# SPDX-License-Identifier: Apache-2.0 OR MIT
# Copyright Tock Contributors 2018.
#
#
#
# J-LINK GDB SERVER initialization
#
# This connects to a GDB Server listening
# for commands on localhost at tcp port 2331
target remote localhost:2331
monitor speed 30
file ../../../../target/thumbv7em-none-eabi/release/nrf52dk
monitor reset
#
# CPU core initialization (to be done by user)
#
# Set the processor mode
# monitor reg cpsr = 0xd3
# Set auto JTAG speed
monitor speed auto
# Setup GDB FOR FASTER DOWNLOADS
set remote memory-write-packet-size 1024
set remote memory-write-packet-size fixed
# tui enable
# layout split
# layout service_pending_interrupts
b initialize_ram_jump_to_main
5 changes: 5 additions & 0 deletions boards/nordic/nrf52840dk-bonus/jtag/jdbserver_pca10040.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Licensed under the Apache License, Version 2.0 or the MIT License.
# SPDX-License-Identifier: Apache-2.0 OR MIT
# Copyright Tock Contributors 2023.

JLinkGDBServer -device nrf52 -speed 1200 -if swd -AutoConnect 1 -port 2331
6 changes: 6 additions & 0 deletions boards/nordic/nrf52840dk-bonus/layout.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* Licensed under the Apache License, Version 2.0 or the MIT License. */
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
/* Copyright Tock Contributors 2023. */

INCLUDE ../nrf52840_chip_layout.ld
INCLUDE ../../kernel_layout.ld
114 changes: 114 additions & 0 deletions boards/nordic/nrf52840dk-bonus/src/io.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2022.

use core::fmt::Write;
use core::panic::PanicInfo;
use kernel::debug;
use kernel::debug::IoWrite;
use kernel::hil::led;
use kernel::hil::uart;
use kernel::hil::uart::Configure;
use nrf52840::gpio::Pin;
use nrf52840::uart::{Uarte, UARTE0_BASE};

use crate::CHIP;
use crate::PROCESSES;
use crate::PROCESS_PRINTER;

enum Writer {
WriterUart(/* initialized */ bool),
WriterRtt(&'static capsules_extra::segger_rtt::SeggerRttMemory<'static>),
}

static mut WRITER: Writer = Writer::WriterUart(false);

// Wait a fixed number of cycles to avoid missing characters over the RTT console
fn wait() {
for _ in 0..1000 {
cortexm4::support::nop();
}
}

/// Set the RTT memory buffer used to output panic messages.
pub unsafe fn set_rtt_memory(
rtt_memory: &'static capsules_extra::segger_rtt::SeggerRttMemory<'static>,
) {
WRITER = Writer::WriterRtt(rtt_memory);
}

impl Write for Writer {
fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
self.write(s.as_bytes());
Ok(())
}
}

impl IoWrite for Writer {
fn write(&mut self, buf: &[u8]) -> usize {
match self {
Writer::WriterUart(ref mut initialized) => {
// Here, we create a second instance of the Uarte struct.
// This is okay because we only call this during a panic, and
// we will never actually process the interrupts
let uart = Uarte::new(UARTE0_BASE);
if !*initialized {
*initialized = true;
let _ = uart.configure(uart::Parameters {
baud_rate: 115200,
stop_bits: uart::StopBits::One,
parity: uart::Parity::None,
hw_flow_control: false,
width: uart::Width::Eight,
});
}
for &c in buf {
unsafe {
uart.send_byte(c);
}
while !uart.tx_ready() {}
}
}
Writer::WriterRtt(rtt_memory) => {
let up_buffer = unsafe { &*rtt_memory.get_up_buffer_ptr() };
let buffer_len = up_buffer.length.get();
let buffer = unsafe {
core::slice::from_raw_parts_mut(
up_buffer.buffer.get() as *mut u8,
buffer_len as usize,
)
};

let mut write_position = up_buffer.write_position.get();

for &c in buf {
buffer[write_position as usize] = c;
write_position = (write_position + 1) % buffer_len;
up_buffer.write_position.set(write_position);
wait();
}
}
};
buf.len()
}
}

#[cfg(not(test))]
#[no_mangle]
#[panic_handler]
/// Panic handler
pub unsafe fn panic_fmt(pi: &PanicInfo) -> ! {
// The nRF52840DK LEDs (see back of board)
let led_kernel_pin = &nrf52840::gpio::GPIOPin::new(Pin::P0_13);
let led = &mut led::LedLow::new(led_kernel_pin);
let writer = &mut WRITER;
debug::panic(
&mut [led],
writer,
pi,
&cortexm4::support::nop,
&PROCESSES,
&CHIP,
&PROCESS_PRINTER,
)
}
Loading

0 comments on commit c9e1f8e

Please sign in to comment.