From f7f7d4cbbc9b6a685714693819470aab78fb24e0 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Wed, 12 Sep 2018 22:16:06 +0200 Subject: [PATCH] runtime/nrf: translate nrf sleep function from C to Go This is the last critical part of the C runtime. Code size is reduced by 4 bytes for examples/blinky2 (probably due to inlining) and is unchanged for examples/test. --- Makefile | 6 ------ src/runtime/runtime_nrf.c | 30 ------------------------------ src/runtime/runtime_nrf.go | 30 +++++++++++++++++++++++++++--- 3 files changed, 27 insertions(+), 39 deletions(-) delete mode 100644 src/runtime/runtime_nrf.c diff --git a/Makefile b/Makefile index 85adae80..619b708b 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,6 @@ CFLAGS += -I$(CURDIR)/lib/nrfx/mdk CFLAGS += -I$(CURDIR)/lib/CMSIS/CMSIS/Include CFLAGS += -DNRF52832_XXAA CFLAGS += -Wno-uninitialized -RUNTIME_PARTS += build/runtime_nrf.bc RUNTIME_PARTS += build/nrfx_system_nrf52.bc OBJ += build/nrfx_startup_nrf51.o # TODO nrf52, see https://bugs.llvm.org/show_bug.cgi?id=31601 @@ -98,11 +97,6 @@ build/tgo: *.go build/%.o: src/examples/% src/examples/%/*.go build/tgo src/runtime/*.go build/runtime-$(TARGET)-combined.bc ./build/tgo build $(TGOFLAGS) -runtime build/runtime-$(TARGET)-combined.bc -o $@ $(subst src/,,$<) -# Compile C sources for the runtime. -build/%.bc: src/runtime/%.c src/runtime/*.h - @mkdir -p build - clang $(CFLAGS) -c -o $@ $< - # Compile LLVM bitcode from LLVM source. build/%.bc: src/runtime/%.ll $(LLAS) -o $@ $< diff --git a/src/runtime/runtime_nrf.c b/src/runtime/runtime_nrf.c deleted file mode 100644 index 046a7b64..00000000 --- a/src/runtime/runtime_nrf.c +++ /dev/null @@ -1,30 +0,0 @@ - -#include "hal/nrf_gpio.h" -#include "hal/nrf_uart.h" -#include "nrf.h" -#include "runtime.h" -#include "runtime_nrf.h" -#include - -static volatile bool rtc_wakeup; - -void rtc_sleep(uint32_t ticks) { - NRF_RTC0->INTENSET = RTC_INTENSET_COMPARE0_Msk; - rtc_wakeup = false; - if (ticks == 1) { - // Race condition (even in hardware) at ticks == 1. - // TODO: fix this in a better way by detecting it, like the manual - // describes. - ticks = 2; - } - NRF_RTC0->CC[0] = (NRF_RTC0->COUNTER + ticks) & 0x00ffffff; - while (!rtc_wakeup) { - __WFI(); - } -} - -void RTC0_IRQHandler() { - NRF_RTC0->INTENCLR = RTC_INTENSET_COMPARE0_Msk; - NRF_RTC0->EVENTS_COMPARE[0] = 0; - rtc_wakeup = true; -} diff --git a/src/runtime/runtime_nrf.go b/src/runtime/runtime_nrf.go index 8afd00b7..66418e8a 100644 --- a/src/runtime/runtime_nrf.go +++ b/src/runtime/runtime_nrf.go @@ -7,8 +7,6 @@ import ( "device/nrf" ) -func _Cfunc_rtc_sleep(ticks uint32) - const Microsecond = 1 //go:export _start @@ -55,7 +53,7 @@ func sleep(d Duration) { for ticks64 != 0 { monotime() // update timestamp ticks := uint32(ticks64) & 0x7fffff // 23 bits (to be on the safe side) - _Cfunc_rtc_sleep(ticks) // TODO: not accurate (must be d / 30.5175...) + rtc_sleep(ticks) // TODO: not accurate (must be d / 30.5175...) ticks64 -= Duration(ticks) } } @@ -88,3 +86,29 @@ func abort() { func align(ptr uintptr) uintptr { return (ptr + 3) &^ 3 } + +type __volatile bool + +var rtc_wakeup __volatile + +func rtc_sleep(ticks uint32) { + nrf.RTC0.INTENSET = nrf.RTC0_INTENSET_COMPARE0_Msk + rtc_wakeup = false + if ticks == 1 { + // Race condition (even in hardware) at ticks == 1. + // TODO: fix this in a better way by detecting it, like the manual + // describes. + ticks = 2 + } + nrf.RTC0.CC[0] = (nrf.RTC0.COUNTER + nrf.RegValue(ticks)) & 0x00ffffff + for !rtc_wakeup { + arm.Asm("wfi") + } +} + +//go:export RTC0_IRQHandler +func RTC0_IRQHandler() { + nrf.RTC0.INTENCLR = nrf.RTC0_INTENSET_COMPARE0_Msk + nrf.RTC0.EVENTS_COMPARE[0] = 0 + rtc_wakeup = true +}