diff --git a/src/device/arm/arm.go b/src/device/arm/arm.go new file mode 100644 index 00000000..5374a5d3 --- /dev/null +++ b/src/device/arm/arm.go @@ -0,0 +1,59 @@ +// CMSIS abstraction functions. +// +// Original copyright: +// +// Copyright (c) 2009 - 2015 ARM LIMITED +// +// All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// - Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// - Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// - Neither the name of ARM nor the names of its contributors may be used +// to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +package arm + +type __reg uint32 +type RegValue = __reg + +const ( + SCS_BASE = 0xE000E000 + NVIC_BASE = SCS_BASE + 0x0100 +) + +// Nested Vectored Interrupt Controller (NVIC). +var NVIC = struct { + ISER [8]__reg +}{ + ISER: [8]__reg{ + NVIC_BASE + 0x000, + NVIC_BASE + 0x004, + NVIC_BASE + 0x008, + NVIC_BASE + 0x00C, + NVIC_BASE + 0x010, + NVIC_BASE + 0x014, + NVIC_BASE + 0x018, + NVIC_BASE + 0x01C, + }, +} + +// Enable the given interrupt number. +func EnableIRQ(irq uint32) { + NVIC.ISER[irq >> 5] = 1 << (irq & 0x1F) +} diff --git a/src/runtime/runtime_nrf.c b/src/runtime/runtime_nrf.c index b9b48123..ab8bb3fe 100644 --- a/src/runtime/runtime_nrf.c +++ b/src/runtime/runtime_nrf.c @@ -6,30 +6,6 @@ #include "runtime_nrf.h" #include -void uart_init(uint32_t pin_tx) { - NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Enabled; - NRF_UART0->BAUDRATE = UART_BAUDRATE_BAUDRATE_Baud115200; - NRF_UART0->TASKS_STARTTX = 1; - NRF_UART0->PSELTXD = 6; -} - -void uart_send(uint8_t c) { - NRF_UART0->TXD = c; - while (NRF_UART0->EVENTS_TXDRDY != 1) {} - NRF_UART0->EVENTS_TXDRDY = 0; -} - -void rtc_init() { - // Make sure the low-frequency clock is running. - NRF_CLOCK->TASKS_LFCLKSTART = 1; - while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {} - NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; - - NRF_RTC0->TASKS_START = 1; - NVIC_SetPriority(RTC0_IRQn, 3); - NVIC_EnableIRQ(RTC0_IRQn); -} - static volatile bool rtc_wakeup; void rtc_sleep(uint32_t ticks) { diff --git a/src/runtime/runtime_nrf.go b/src/runtime/runtime_nrf.go index cb3d1550..8278da05 100644 --- a/src/runtime/runtime_nrf.go +++ b/src/runtime/runtime_nrf.go @@ -6,15 +6,43 @@ package runtime // #include "runtime_nrf.h" import "C" -func init() { - C.uart_init(6) // pin_tx = 6, for NRF52840-DK - C.rtc_init() -} +import ( + "device/arm" + "device/nrf" +) const Microsecond = 1 +func init() { + initUART() + initLFCLK() + initRTC() +} + +func initUART() { + nrf.UART0.ENABLE = nrf.UART0_ENABLE_ENABLE_Enabled + nrf.UART0.BAUDRATE = nrf.UART0_BAUDRATE_BAUDRATE_Baud115200 + nrf.UART0.TASKS_STARTTX = 1 + nrf.UART0.PSELTXD = 6 // pin 6 for NRF52840-DK +} + +func initLFCLK() { + nrf.CLOCK.LFCLKSRC = nrf.CLOCK_LFCLKSTAT_SRC_Xtal + nrf.CLOCK.TASKS_LFCLKSTART = 1 + for nrf.CLOCK.EVENTS_LFCLKSTARTED == 0 {} + nrf.CLOCK.EVENTS_LFCLKSTARTED = 0 +} + +func initRTC() { + nrf.RTC0.TASKS_START = 1 + // TODO: set priority + arm.EnableIRQ(nrf.IRQ_RTC0) +} + func putchar(c byte) { - C.uart_send(C.uint8_t(c)) + nrf.UART0.TXD = nrf.RegValue(c) + for nrf.UART0.EVENTS_TXDRDY == 0 {} + nrf.UART0.EVENTS_TXDRDY = 0 } func Sleep(d Duration) { diff --git a/src/runtime/runtime_nrf.h b/src/runtime/runtime_nrf.h index 945dcc7c..1ae8572e 100644 --- a/src/runtime/runtime_nrf.h +++ b/src/runtime/runtime_nrf.h @@ -2,10 +2,5 @@ #pragma once #include -#include -void uart_init(uint32_t pin_tx); -void uart_send(uint8_t c); - -void rtc_init(); void rtc_sleep(uint32_t ticks);