├── .gitignore ├── AUTHORS ├── LICENSE ├── dci └── tftdci │ └── spim.go ├── devboard ├── pca10059 │ ├── board │ │ ├── buttons │ │ │ └── button.go │ │ ├── leds │ │ │ └── led.go │ │ └── system │ │ │ └── init.go │ ├── doc │ │ ├── board.jpg │ │ └── bootloader │ │ │ ├── bootloader-copyright.txt │ │ │ └── bootloader.hex │ └── examples │ │ ├── analogclock │ │ └── main.go │ │ ├── ble_blinky │ │ └── main.go │ │ ├── blinky │ │ └── main.go │ │ ├── bootloader │ │ └── private.key │ │ ├── build-blank.sh │ │ ├── build-mbr.sh │ │ ├── build-s132-6.sh │ │ ├── build-s140-7.sh │ │ ├── build.cfg │ │ ├── debug-bmp.sh │ │ ├── debug-oocd.sh │ │ ├── display │ │ └── main.go │ │ ├── gctest │ │ └── main.go │ │ ├── load-bmp-elf.sh │ │ ├── load-bmp-hex.sh │ │ ├── load-nrfutil-s132-6.sh │ │ ├── load-nrfutil-s140-7.sh │ │ ├── load-oocd.sh │ │ ├── ppi │ │ └── main.go │ │ ├── signed-zip.sh │ │ ├── spim │ │ └── main.go │ │ ├── swo-oocd.sh │ │ ├── uart │ │ └── main.go │ │ ├── uarte │ │ └── main.go │ │ └── voltmeter │ │ ├── button.go │ │ ├── display.go │ │ └── main.go └── readme.md ├── go.mod ├── go.sum ├── hal ├── clock │ ├── func.go │ └── regs.go ├── gpio │ ├── conf.go │ ├── ctrl.go │ ├── doc.go │ ├── nrf52.go │ ├── nrf52840.go │ ├── pin.go │ └── port.go ├── gpiote │ ├── chan.go │ ├── nrf52.go │ └── regs.go ├── internal │ ├── alloc.go │ ├── bool.go │ ├── ppi.go │ └── psel │ │ └── reg.go ├── irq │ └── nrf52840.go ├── ppi │ ├── chan.go │ ├── doc.go │ ├── irq.go │ └── nrf52.go ├── rtc │ └── periph.go ├── saadc │ ├── driver.go │ └── periph.go ├── spim │ ├── driver.go │ ├── periph.go │ ├── spim0 │ │ └── driver.go │ ├── spim1 │ │ └── driver.go │ ├── spim2 │ │ └── driver.go │ └── spim3 │ │ └── driver.go ├── system │ ├── rt0.s │ ├── setup.go │ └── timer │ │ └── rtcst │ │ ├── asm.s │ │ └── rtcst.go ├── te │ ├── chan.go │ ├── changroup.go │ ├── doc.go │ ├── event.go │ ├── nrf52.go │ ├── regs.go │ └── task.go ├── timer │ ├── nrf52.go │ └── periph.go ├── todo │ ├── power │ │ ├── func.go │ │ └── regs.go │ ├── qdec │ │ └── periph.go │ ├── radio │ │ ├── doc.go │ │ └── periph.go │ └── temp │ │ └── periph.go ├── uart │ ├── driver.go │ ├── periph.go │ └── uart0 │ │ └── driver.go └── uarte │ ├── driver.go │ ├── periph.go │ ├── uarte0 │ └── driver.go │ └── uarte1 │ └── driver.go ├── p ├── ficr │ ├── nrf52840.go │ └── xnrf52840.go ├── gpio │ ├── nrf52840.go │ └── xnrf52840.go ├── irq │ └── nrf52840.go ├── mmap │ └── nrf52840.go ├── nvmc │ ├── nrf52840.go │ └── xnrf52840.go ├── ppi │ ├── nrf52840.go │ └── xnrf52840.go ├── rtc │ ├── nrf52840.go │ └── xnrf52840.go ├── spi │ ├── nrf52840.go │ └── xnrf52840.go ├── uart │ ├── nrf52840.go │ └── xnrf52840.go ├── uarte │ ├── nrf52840.go │ └── xnrf52840.go └── uicr │ ├── nrf52840.go │ └── xnrf52840.go ├── readme.md ├── softdevice ├── gen │ ├── gen.go │ └── s140 │ │ └── nrf │ │ ├── zerror.go │ │ ├── zerrorsdm.go │ │ ├── zerrorsoc.go │ │ ├── zsddef.go │ │ ├── zsdm.go │ │ ├── zsdm.s │ │ ├── zsoc.go │ │ └── zsoc.s ├── nordic │ └── s140 │ │ ├── headers │ │ ├── ble.h │ │ ├── ble_err.h │ │ ├── ble_gap.h │ │ ├── ble_gatt.h │ │ ├── ble_gattc.h │ │ ├── ble_gatts.h │ │ ├── ble_hci.h │ │ ├── ble_l2cap.h │ │ ├── ble_ranges.h │ │ ├── ble_types.h │ │ ├── nrf52 │ │ │ └── nrf_mbr.h │ │ ├── nrf_error.h │ │ ├── nrf_error_sdm.h │ │ ├── nrf_error_soc.h │ │ ├── nrf_nvic.h │ │ ├── nrf_sdm.h │ │ ├── nrf_soc.h │ │ └── nrf_svc.h │ │ └── hex │ │ ├── s140_nrf52_7.0.1_licence-agreement.txt │ │ ├── s140_nrf52_7.0.1_softdevice.hex │ │ ├── s140_nrf52_7.2.0_license-agreement.txt │ │ └── s140_nrf52_7.2.0_softdevice.hex ├── s140 │ ├── LICENSE-NORDIC │ └── sd │ │ ├── ble │ │ ├── error.go │ │ ├── event.go │ │ ├── func.go │ │ ├── gap │ │ │ ├── error.go │ │ │ ├── event.go │ │ │ ├── func.go │ │ │ ├── svc.go │ │ │ ├── svc.s │ │ │ └── type.go │ │ ├── gatt │ │ │ ├── gatts │ │ │ │ ├── error.go │ │ │ │ ├── event.go │ │ │ │ ├── func.go │ │ │ │ ├── svc.go │ │ │ │ ├── svc.s │ │ │ │ └── type.go │ │ │ └── type.go │ │ ├── hci.go │ │ ├── internal │ │ │ ├── svc.go │ │ │ └── svc.s │ │ ├── svc.go │ │ ├── svc.s │ │ └── type.go │ │ ├── error.go │ │ └── sdm │ │ ├── error.go │ │ ├── sdm.go │ │ ├── svc.go │ │ └── svc.s └── sdutil │ ├── advdata.go │ ├── event.go │ ├── rambase.go │ └── rambase.s └── svd ├── _gen.sh ├── gen.sh └── nrf52840.svd /.gitignore: -------------------------------------------------------------------------------- 1 | *.elf 2 | *.bin 3 | *.zip 4 | devboard/*/examples/*/*.hex 5 | zisrnames.go 6 | core 7 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Michal Derkacz 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 The Embedded Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of the copyright holder nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /dci/tftdci/spim.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Embedded Go authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package tftdci 6 | 7 | import ( 8 | "github.com/embeddedgo/nrf5/hal/gpio" 9 | "github.com/embeddedgo/nrf5/hal/spim" 10 | ) 11 | 12 | // SPIM is an implementation of the tftdrv.DCI that uses an SPIM peripheral 13 | // to communicate with the display in what is known as 4-line serial mode. 14 | type SPIM struct { 15 | spi *spim.Driver 16 | dc gpio.Pin 17 | csn gpio.Pin 18 | mode spim.Config 19 | rf, wf spim.Freq 20 | started bool 21 | reconf bool 22 | } 23 | 24 | // NewSPIM returns new SPI based implementation of tftdrv.DCI. It properly 25 | // configures the provided SPI driver and DC pin to communicate with a display 26 | // controller. Select the SPI mode (CPOL,CPHA), write and read clock speed 27 | // according to the display controller specification. Note that the maximum 28 | // speed may be limited by the concrete instance of nRF5 SPI peripheral, the 29 | // bus topology and the specific display design. 30 | func NewSPIM(drv *spim.Driver, dc gpio.Pin, mode spim.Config, rf, wf spim.Freq) *SPIM { 31 | dci := &SPIM{spi: drv, dc: dc, mode: mode, wf: wf, rf: rf} 32 | dc.Clear() 33 | dc.Setup(gpio.ModeOut) 34 | drv.Setup(dci.mode, wf) 35 | return dci 36 | } 37 | 38 | // UseCSN selects csn as slave select pin. If reconf is true the SPI peripheral 39 | // is reconfigured by any Cmd call so it can be shared with other applications 40 | // (exclusive acces is required until End call). 41 | func (dci *SPIM) UseCSN(csn gpio.Pin, reconf bool) { 42 | dci.csn = csn 43 | dci.reconf = reconf 44 | csn.Set() 45 | csn.Setup(gpio.ModeOut) 46 | } 47 | 48 | func (dci *SPIM) Driver() *spim.Driver { return dci.spi } 49 | func (dci *SPIM) Err(clear bool) error { return nil } 50 | func (dci *SPIM) DC() gpio.Pin { return dci.dc } 51 | 52 | func start(dci *SPIM) { 53 | dci.started = true 54 | if dci.csn.IsValid() { 55 | dci.csn.Clear() 56 | if dci.reconf { 57 | dci.spi.Setup(dci.mode, dci.wf) 58 | } 59 | } 60 | dci.spi.Enable() 61 | } 62 | 63 | func (dci *SPIM) Cmd(p []byte, _ int) { 64 | if !dci.started { 65 | start(dci) 66 | } 67 | dci.dc.Clear() 68 | dci.spi.WriteRead(p, nil) 69 | dci.dc.Set() 70 | } 71 | 72 | func (dci *SPIM) End() { 73 | dci.started = false 74 | if dci.csn.IsValid() { 75 | dci.csn.Set() 76 | } 77 | dci.spi.Disable() 78 | } 79 | 80 | func (dci *SPIM) WriteBytes(p []uint8) { 81 | if !dci.started { 82 | start(dci) 83 | } 84 | dci.spi.WriteRead(p, nil) 85 | } 86 | 87 | func (dci *SPIM) ReadBytes(p []byte) { 88 | if !dci.started { 89 | start(dci) 90 | } 91 | dci.spi.Periph().StoreFREQUENCY(dci.rf) 92 | dci.spi.WriteRead(nil, p) 93 | dci.spi.Periph().StoreFREQUENCY(dci.wf) 94 | } 95 | -------------------------------------------------------------------------------- /devboard/pca10059/board/buttons/button.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package buttons 6 | 7 | import ( 8 | "github.com/embeddedgo/nrf5/hal/gpio" 9 | 10 | _ "github.com/embeddedgo/nrf5/devboard/pca10059/board/system" 11 | ) 12 | 13 | // Onboard buttons 14 | const ( 15 | SW1 Button = 0x16 // P1.06 16 | 17 | User = SW1 18 | ) 19 | 20 | type Button uint8 21 | 22 | func (b Button) prt() int { return int(b) >> 4 } 23 | func (b Button) pin() uint { return uint(b) & 15 } 24 | 25 | func (b Button) Read() int { 26 | return int(gpio.P(b.prt()).Load()>>b.pin())&1 ^ 1 27 | } 28 | func (b Button) Pin() gpio.Pin { 29 | return gpio.P(b.prt()).Pin(int(b.pin())) 30 | } 31 | 32 | func init() { 33 | SW1.Pin().Setup(gpio.ModeIn | gpio.PullUp) 34 | } 35 | -------------------------------------------------------------------------------- /devboard/pca10059/board/leds/led.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package leds 6 | 7 | import ( 8 | "github.com/embeddedgo/nrf5/hal/gpio" 9 | 10 | _ "github.com/embeddedgo/nrf5/devboard/pca10059/board/system" 11 | ) 12 | 13 | // Onboard LEDs 14 | const ( 15 | LD1 LED = 0x06 // P0.06 16 | LD2R LED = 0x08 // P0.08 17 | LD2G LED = 0x19 // P1.09 18 | LD2B LED = 0x0C // P0.12 19 | 20 | User = LD1 21 | Red = LD2R 22 | Green = LD2G 23 | Blue = LD2B 24 | ) 25 | 26 | type LED uint8 27 | 28 | func (d LED) prt() int { return int(d) >> 4 } 29 | func (d LED) pin() uint { return uint(d) & 15 } 30 | 31 | func (d LED) SetOn() { 32 | gpio.P(d.prt()).ClearPins(1 << d.pin()) 33 | } 34 | func (d LED) SetOff() { 35 | gpio.P(d.prt()).SetPins(1 << d.pin()) 36 | } 37 | func (d LED) Set(on int) { 38 | port := gpio.P(d.prt()) 39 | if on&1 == 0 { 40 | port.SetPins(1 << d.pin()) 41 | } else { 42 | port.ClearPins(1 << d.pin()) 43 | } 44 | } 45 | func (d LED) Get() int { 46 | return int(gpio.P(d.prt()).LoadOut()>>d.pin())&1 ^ 1 47 | } 48 | func (d LED) Pin() gpio.Pin { 49 | return gpio.P(d.prt()).Pin(int(d.pin())) 50 | } 51 | 52 | func init() { 53 | cfg := gpio.ModeOut | gpio.DriveH0D1 54 | LD1.SetOff() 55 | LD2R.SetOff() 56 | LD2G.SetOff() 57 | LD2B.SetOff() 58 | LD1.Pin().Setup(cfg) 59 | LD2R.Pin().Setup(cfg) 60 | LD2G.Pin().Setup(cfg) 61 | LD2B.Pin().Setup(cfg) 62 | } 63 | -------------------------------------------------------------------------------- /devboard/pca10059/board/system/init.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package system 6 | 7 | import ( 8 | _ "unsafe" 9 | 10 | "github.com/embeddedgo/nrf5/hal/clock" 11 | "github.com/embeddedgo/nrf5/hal/rtc" 12 | "github.com/embeddedgo/nrf5/hal/system" 13 | "github.com/embeddedgo/nrf5/hal/system/timer/rtcst" 14 | ) 15 | 16 | func init() { 17 | system.Setup(clock.XTAL, clock.XTAL, true) 18 | rtcst.Setup(rtc.RTC(1), 0) 19 | } 20 | 21 | //go:interrupthandler 22 | func _RTC1_Handler() { rtcst.ISR() } 23 | 24 | //go:linkname _RTC1_Handler IRQ17_Handler 25 | -------------------------------------------------------------------------------- /devboard/pca10059/doc/board.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/embeddedgo/nrf5/d46a5e4070267007d70e3048baa39af1de75a7d5/devboard/pca10059/doc/board.jpg -------------------------------------------------------------------------------- /devboard/pca10059/doc/bootloader/bootloader-copyright.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 - 2018, Nordic Semiconductor ASA 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form, except as embedded into a Nordic 12 | Semiconductor ASA integrated circuit in a product or a software update for 13 | such product, must reproduce the above copyright notice, this list of 14 | conditions and the following disclaimer in the documentation and/or other 15 | materials provided with the distribution. 16 | 17 | 3. Neither the name of Nordic Semiconductor ASA nor the names of its 18 | contributors may be used to endorse or promote products derived from this 19 | software without specific prior written permission. 20 | 21 | 4. This software, with or without modification, must only be used with a 22 | Nordic Semiconductor ASA integrated circuit. 23 | 24 | 5. Any software provided in binary form under this license must not be reverse 25 | engineered, decompiled, modified and/or disassembled. 26 | 27 | THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 28 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29 | OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 30 | DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 33 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 36 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /devboard/pca10059/examples/blinky/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "time" 9 | 10 | "github.com/embeddedgo/nrf5/devboard/pca10059/board/buttons" 11 | "github.com/embeddedgo/nrf5/devboard/pca10059/board/leds" 12 | "github.com/embeddedgo/nrf5/hal/clock" 13 | ) 14 | 15 | func delay() { 16 | if buttons.User.Read() != 0 { 17 | time.Sleep(time.Second / 8) 18 | } else { 19 | time.Sleep(time.Second / 2) 20 | } 21 | } 22 | 23 | func main() { 24 | clock.StoreTRACECONFIG(clock.T4MHz, clock.Serial) // enable SWO on P1.00 25 | for { 26 | leds.Blue.SetOff() 27 | leds.User.SetOn() 28 | println("user") 29 | delay() 30 | 31 | leds.User.SetOff() 32 | leds.Red.SetOn() 33 | println("red") 34 | delay() 35 | 36 | leds.Red.SetOff() 37 | leds.Green.SetOn() 38 | println("green") 39 | delay() 40 | 41 | leds.Green.SetOff() 42 | leds.Blue.SetOn() 43 | println("blue") 44 | delay() 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/bootloader/private.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIFR5ISlzpDZoVjBtXv9yE9TVovHwuOn0DbysXajKLKYtoAoGCCqGSM49 3 | AwEHoUQDQgAENcTfId9AE7iIU11xArqJybVxIsl+R6rd3bG62GxWRLyjOVGWayFU 4 | ig5PyJYzwZJYK3BJHmOE1/208P0Fi6GdQw== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/build-blank.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export GOTARGET=nrf52840 4 | export GOTEXT=0x00000000:1M 5 | export GOMEM=0x20000000:256K 6 | export GOSTRIPFN=1 7 | 8 | emgo build $@ 9 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/build-mbr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export GOTARGET=nrf52840 4 | export GOTEXT=0x00001000:1020K 5 | export GOMEM=0x20000008:262136 6 | export GOSTRIPFN=1 7 | export GOOUT=hex 8 | 9 | emgo build $@ 10 | 11 | bootversion=1 12 | appversion=1 13 | 14 | . $(emgo env GOROOT)/../scripts/nrf5-settings.sh 15 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/build-s132-6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo 'For nRF52840 use build-s140-7.sh' 4 | exit 1 5 | 6 | export GOTARGET=nrf52840 7 | export GOTEXT=0x00026000:872K 8 | export GOMEM=0x20002000:253952 9 | export GOSTRIPFN=1 10 | export GOOUT=hex 11 | 12 | emgo build $@ 13 | 14 | bootversion=1 15 | appversion=1 16 | 17 | . $(emgo env GOROOT)/../scripts/nrf5-settings.sh 18 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/build-s140-7.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export GOTARGET=nrf52840 4 | export GOTEXT=0x00027000:868K 5 | export GOMEM=0x20002800:246K 6 | export GOSTRIPFN=1 7 | export GOOUT=hex 8 | 9 | emgo build $@ 10 | 11 | bootversion=1 12 | appversion=1 13 | 14 | . $(emgo env GOROOT)/../scripts/nrf5-settings.sh 15 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/build.cfg: -------------------------------------------------------------------------------- 1 | DISABLE = To prevent unintentionally overwriting the botloader, use one of the ../build-*.sh scripts. -------------------------------------------------------------------------------- /devboard/pca10059/examples/debug-bmp.sh: -------------------------------------------------------------------------------- 1 | ../../../../scripts/debug-bmp.sh -------------------------------------------------------------------------------- /devboard/pca10059/examples/debug-oocd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | TARGET=nrf52 4 | 5 | . $(emgo env GOROOT)/../scripts/debug-oocd.sh 6 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/display/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Embedded Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Display draws on the connected display. 6 | package main 7 | 8 | import ( 9 | "time" 10 | 11 | "github.com/embeddedgo/display/pix/displays" 12 | "github.com/embeddedgo/display/pix/examples" 13 | 14 | _ "github.com/embeddedgo/nrf5/devboard/pca10059/board/system" 15 | 16 | "github.com/embeddedgo/nrf5/dci/tftdci" 17 | "github.com/embeddedgo/nrf5/hal/clock" 18 | "github.com/embeddedgo/nrf5/hal/gpio" 19 | "github.com/embeddedgo/nrf5/hal/spim" 20 | "github.com/embeddedgo/nrf5/hal/spim/spim3" 21 | ) 22 | 23 | func main() { 24 | clock.StoreTRACECONFIG(clock.T4MHz, clock.Serial) // enable SWO on P1.00 25 | 26 | // Assign GPIO pins 27 | 28 | p0 := gpio.P(0) 29 | scl := p0.Pin(13) 30 | mosi := p0.Pin(15) 31 | reset := p0.Pin(17) // optional 32 | dc := p0.Pin(20) 33 | cs := p0.Pin(22) 34 | miso := p0.Pin(24) 35 | 36 | // Configure peripherals 37 | 38 | reset.Set() 39 | reset.Setup(gpio.ModeOut) 40 | 41 | spi := spim3.Driver() 42 | spi.UsePin(scl, spim.SCK) 43 | spi.UsePin(miso, spim.MISO) 44 | spi.UsePin(mosi, spim.MOSI) 45 | 46 | // Hardware reset. Optional for most controllers (exception SSD1306). 47 | reset.Clear() 48 | time.Sleep(time.Millisecond) 49 | reset.Set() 50 | 51 | // Run 52 | 53 | //dp := displays.Adafruit_0i96_128x64_OLED_SSD1306() 54 | //dp := displays.Adafruit_1i5_128x128_OLED_SSD1351() 55 | //dp := displays.Adafruit_1i54_240x240_IPS_ST7789() 56 | dp := displays.Adafruit_2i8_240x320_TFT_ILI9341() 57 | //dp := displays.ERTFTM_1i54_240x240_IPS_ST7789() 58 | //dp := displays.MSP4022_4i0_320x480_TFT_ILI9486() 59 | //dp := displays.Waveshare_1i5_128x128_OLED_SSD1351() 60 | 61 | // TODO: use dp.MaxReadClk and dp.MaxWriteClk instead of F8MHz and F16MHz 62 | dci := tftdci.NewSPIM(spi, dc, spim.CPOL0|spim.CPHA0, spim.F8MHz, spim.F16MHz) 63 | dci.UseCSN(cs, false) 64 | 65 | // Run 66 | 67 | disp := dp.New(dci) 68 | for { 69 | //examples.RotateDisplay(disp) 70 | //examples.DrawText(disp) 71 | examples.GraphicsTest(disp) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/gctest/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This example forces the garbage collector to work hard and periodically 6 | // prints statistics of the memory allocator. 7 | package main 8 | 9 | import ( 10 | "math/rand" 11 | "runtime" 12 | 13 | "github.com/embeddedgo/nrf5/hal/clock" 14 | 15 | _ "github.com/embeddedgo/nrf5/devboard/pca10059/board/system" 16 | ) 17 | 18 | func main() { 19 | clock.StoreTRACECONFIG(clock.T4MHz, clock.Serial) // enable SWO on P1.00 20 | 21 | runtime.GOMAXPROCS(2) 22 | 23 | c := make(chan []uint32, 3) 24 | 25 | go func() { 26 | for { 27 | c <- make([]uint32, rand.Intn(512)+1) 28 | } 29 | }() 30 | 31 | for i := 0; ; i++ { 32 | <-c 33 | if i&1023 == 0 { 34 | if i&32767 == 0 { 35 | printMemstatDescr() 36 | } 37 | printMemstat(i) 38 | } 39 | } 40 | } 41 | 42 | func printMemstatDescr() { 43 | print("#Recv Sys HeapSys StackSys GCSys OtherSys " + 44 | "HeapAlloc/HeapInuse StackInuse HeapIdle " + 45 | "MSpanInuse/MSpanSys MCacheInuse/MCacheSys\n") 46 | } 47 | 48 | var ms runtime.MemStats 49 | 50 | func printMemstat(i int) { 51 | runtime.ReadMemStats(&ms) 52 | print( 53 | i>>10, "K\t", 54 | ms.Sys, "\t", ms.HeapSys, "\t", ms.StackSys, "\t", ms.GCSys, "\t", 55 | ms.OtherSys, "\t\t", 56 | ms.HeapAlloc, " / ", ms.HeapInuse, "\t", ms.StackInuse, "\t", 57 | ms.HeapIdle, "\t\t", 58 | ms.MSpanInuse, " / ", ms.MSpanSys, "\t", ms.MCacheInuse, " / ", 59 | ms.MCacheSys, 60 | "\n", 61 | ) 62 | } 63 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/load-bmp-elf.sh: -------------------------------------------------------------------------------- 1 | ../../../../scripts/load-bmp.sh -------------------------------------------------------------------------------- /devboard/pca10059/examples/load-bmp-hex.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | gdb_cmd=gdb 6 | if command -v arm-none-eabi-gdb; then 7 | gdb_cmd=arm-none-eabi-gdb 8 | elif command -v gdb-multiarch; then 9 | gdb_cmd=gdb-multiarch 10 | fi 11 | 12 | $gdb_cmd \ 13 | -ex 'set pagination off' \ 14 | -ex 'set confirm off' \ 15 | -ex 'target extended-remote /dev/ttyACM0' \ 16 | -ex 'monitor connect_srst enable' \ 17 | -ex 'monitor swdp_scan' \ 18 | -ex 'attach 1' \ 19 | -ex "load $(basename $(pwd))-settings.hex" \ 20 | -ex "load $(basename $(pwd)).hex" \ 21 | -ex 'kill' \ 22 | -ex 'quit' 23 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/load-nrfutil-s132-6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo 'For nRF52840 use load-nrfutil-s140-*' 4 | exit 1 5 | 6 | dfu=usb-serial 7 | port=/dev/ttyACM0 8 | 9 | hw=52 10 | 11 | sdreq=0xA8,0xAF,0xB7 12 | 13 | s132_nrf52_6_0_0_softdevice_hex=0xA8 14 | s132_nrf52_6_1_0_softdevice_hex=0xAF 15 | s132_nrf52_6_1_1_softdevice_hex=0xB7 16 | 17 | . $(emgo env GOROOT)/../scripts/load-nrfutil.sh $@ 18 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/load-nrfutil-s140-7.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | dfu=usb-serial 4 | port=/dev/ttyACM0 5 | 6 | hw=52 7 | 8 | sdreq=0xCA,0x0100 9 | 10 | s140_nrf52_7_0_1_softdevice_hex=0xCA 11 | s140_nrf52_7_2_0_softdevice_hex=0x0100 12 | 13 | . $(emgo env GOROOT)/../scripts/load-nrfutil.sh $@ 14 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/load-oocd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | TARGET=nrf52 4 | TRACECLKIN=4000000 5 | 6 | . $(emgo env GOROOT)/../scripts/load-oocd.sh 7 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/ppi/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "time" 9 | 10 | "github.com/embeddedgo/nrf5/devboard/pca10059/board/buttons" 11 | "github.com/embeddedgo/nrf5/devboard/pca10059/board/leds" 12 | "github.com/embeddedgo/nrf5/hal/gpiote" 13 | "github.com/embeddedgo/nrf5/hal/te" 14 | ) 15 | 16 | func main() { 17 | led := gpiote.Alloc() 18 | led.Setup(leds.User.Pin(), gpiote.ModeTask|gpiote.PolarityToggle) 19 | 20 | btn := gpiote.Alloc() 21 | btn.Setup(buttons.User.Pin(), gpiote.ModeEvent|gpiote.PolarityHiToLo) 22 | 23 | btnled := te.AllocChan() 24 | led.OUT().Task().SetChan(btnled, true) 25 | btn.IN().Event().SetChan(btnled, true) 26 | btnled.Enable() 27 | 28 | for { 29 | leds.Blue.SetOff() 30 | leds.Red.SetOn() 31 | time.Sleep(500 * time.Millisecond) 32 | 33 | leds.Red.SetOff() 34 | leds.Green.SetOn() 35 | time.Sleep(500 * time.Millisecond) 36 | 37 | leds.Green.SetOff() 38 | leds.Blue.SetOn() 39 | time.Sleep(500 * time.Millisecond) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/signed-zip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | appversion=1 4 | key=../bootloader/private.key 5 | 6 | name=$(basename $(pwd)) 7 | 8 | nrfutil pkg generate --hw-version 52 --sd-req 0xCA,0x0100 --key-file $key --application $name.hex --application-version $appversion $name.zip 9 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/spim/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Embedded Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This example tests SPIM peripheral. Make a loop between MISO and MOSI. 6 | // Observe the SWO output. Try disconnect and connect back the loop a few times. 7 | package main 8 | 9 | import ( 10 | "embedded/rtos" 11 | "fmt" 12 | 13 | "github.com/embeddedgo/nrf5/hal/clock" 14 | "github.com/embeddedgo/nrf5/hal/gpio" 15 | "github.com/embeddedgo/nrf5/hal/spim" 16 | 17 | _ "github.com/embeddedgo/nrf5/devboard/pca10059/board/system" 18 | ) 19 | 20 | var drv *spim.Driver 21 | 22 | func main() { 23 | clock.StoreTRACECONFIG(clock.T4MHz, clock.Serial) // enable SWO on P1.00 24 | 25 | println("START!") 26 | p0 := gpio.P(0) 27 | sck := p0.Pin(13) // required to make SPIM working, even if we don't use it 28 | miso := p0.Pin(15) 29 | mosi := p0.Pin(17) 30 | 31 | drv = spim.NewDriver(spim.SPIM(0)) 32 | drv.UsePin(sck, spim.SCK) 33 | drv.UsePin(miso, spim.MISO) 34 | drv.UsePin(mosi, spim.MOSI) 35 | drv.Setup(spim.CPOL0|spim.CPHA0, spim.F1MHz) 36 | drv.Periph().StoreORC('.') 37 | drv.Enable() 38 | drv.IRQ().Enable(rtos.IntPrioLow, 0) 39 | 40 | txbuf := []byte("1234567890abcdefghijklmnoprstuvwxyz") 41 | rxbuf := make([]byte, len(txbuf)+3) 42 | 43 | for { 44 | for i := range rxbuf { 45 | rxbuf[i] = ' ' 46 | } 47 | n := drv.WriteRead(txbuf, rxbuf) 48 | println(fmt.Sprintf("%d: %s", n, rxbuf)) 49 | } 50 | } 51 | 52 | //go:interrupthandler 53 | func SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_Handler() { 54 | drv.ISR() 55 | } 56 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/swo-oocd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | TARGET=nrf52 4 | TRACECLKIN=4000000 5 | 6 | . $(emgo env GOROOT)/../scripts/swo-oocd.sh 7 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/uart/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This example shows how to use the UART peripheral. 6 | package main 7 | 8 | import ( 9 | "github.com/embeddedgo/nrf5/hal/gpio" 10 | "github.com/embeddedgo/nrf5/hal/uart" 11 | "github.com/embeddedgo/nrf5/hal/uart/uart0" 12 | 13 | _ "github.com/embeddedgo/nrf5/devboard/pca10059/board/system" 14 | ) 15 | 16 | func main() { 17 | p1 := gpio.P(1) 18 | rxpin := p1.Pin(10) 19 | txpin := p1.Pin(13) 20 | 21 | tts := uart0.Driver() 22 | tts.UsePin(rxpin, uart.RXD) 23 | tts.UsePin(txpin, uart.TXD) 24 | tts.SetBaudrate(uart.Baud115200) 25 | tts.Enable() 26 | tts.EnableRx(64) 27 | 28 | tts.WriteString("Ready!\r\n") 29 | 30 | buf := make([]byte, 64) 31 | for { 32 | n, err := tts.Read(buf) 33 | if n != 0 { 34 | tts.WriteString("inp: ") 35 | tts.Write(buf[:n]) 36 | tts.WriteString("\r\n") 37 | } 38 | if err != nil { 39 | tts.WriteString("err: " + err.Error() + "\r\n") 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/uarte/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This example shows how to use the UARTE peripheral. 6 | package main 7 | 8 | import ( 9 | "time" 10 | 11 | "github.com/embeddedgo/nrf5/hal/gpio" 12 | "github.com/embeddedgo/nrf5/hal/uarte" 13 | "github.com/embeddedgo/nrf5/hal/uarte/uarte1" 14 | 15 | _ "github.com/embeddedgo/nrf5/devboard/pca10059/board/system" 16 | ) 17 | 18 | func main() { 19 | p1 := gpio.P(1) 20 | rxpin := p1.Pin(10) 21 | txpin := p1.Pin(13) 22 | 23 | tts := uarte1.Driver() 24 | tts.UsePin(rxpin, uarte.RXD) 25 | tts.UsePin(txpin, uarte.TXD) 26 | tts.SetBaudrate(uarte.Baud115200) 27 | tts.Enable() 28 | 29 | for { 30 | tts.Write([]byte("Hello World!")) 31 | tts.WriteByte('\n') 32 | tts.WriteByte('\r') 33 | time.Sleep(time.Second) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/voltmeter/button.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Embedded Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "embedded/rtos" 9 | "time" 10 | 11 | "github.com/embeddedgo/nrf5/hal/gpio" 12 | "github.com/embeddedgo/nrf5/hal/gpiote" 13 | "github.com/embeddedgo/nrf5/hal/te" 14 | ) 15 | 16 | type Button struct { 17 | C <-chan bool 18 | Event *te.Event 19 | 20 | pin gpio.Pin 21 | note rtos.Note 22 | released int 23 | } 24 | 25 | func NewButton(pin gpio.Pin, released int) *Button { 26 | ch := gpiote.Alloc() 27 | ch.Setup(pin, gpiote.ModeEvent|gpiote.PolarityToggle) 28 | c := make(chan bool, 3) 29 | b := &Button{ 30 | C: c, 31 | Event: ch.IN().Event(), 32 | pin: pin, 33 | released: released, 34 | } 35 | go b.run(c) 36 | return b 37 | } 38 | 39 | func (b *Button) wait(state int, long bool) bool { 40 | for { 41 | b.note.Clear() 42 | b.Event.EnableIRQ() 43 | timeout := time.Duration(-1) 44 | if b.pin.Load() == state { 45 | timeout = 50 * time.Millisecond // we need 50 ms of stable state 46 | } 47 | if !b.note.Sleep(timeout) { 48 | if long { 49 | // wait +1 second to detect the long state 50 | long = !b.note.Sleep(time.Second) 51 | } 52 | b.Event.DisableIRQ() 53 | b.Event.Clear() 54 | return long 55 | } 56 | } 57 | } 58 | 59 | func (b *Button) run(c chan<- bool) { 60 | for { 61 | b.wait(b.released, false) 62 | c <- b.wait(b.released^1, true) 63 | } 64 | } 65 | 66 | func (b *Button) ISR() { 67 | b.Event.DisableIRQ() 68 | b.Event.Clear() 69 | b.note.Wakeup() 70 | } 71 | -------------------------------------------------------------------------------- /devboard/pca10059/examples/voltmeter/display.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Embedded Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "fmt" 9 | "image/color" 10 | "strings" 11 | 12 | "github.com/embeddedgo/display/font/subfont/font9/terminus16" 13 | "github.com/embeddedgo/display/pix" 14 | ) 15 | 16 | var ( 17 | bgcolor = color.Gray{0} 18 | fgcolor = color.Gray{255} 19 | ) 20 | 21 | var disp Display 22 | 23 | const ( 24 | Aleft = iota 25 | Aright 26 | Acenter 27 | ) 28 | 29 | // TextArea wraps *pix.TextWriter to add convenient Clear and Printf methods. 30 | type TextArea struct { 31 | *pix.TextWriter 32 | Align byte 33 | } 34 | 35 | // Clear clears the text area using bgcolor and resets the drawing positon to 36 | // its top-left corner. 37 | func (a *TextArea) Clear() { 38 | r := a.Area.Bounds() 39 | a.Area.SetColor(bgcolor) 40 | a.Area.Fill(r) 41 | a.Pos = r.Min 42 | } 43 | 44 | // WriteString allows to print an aligned multiline text string. 45 | func (a *TextArea) WriteString(text string) { 46 | for len(text) != 0 { 47 | var s string 48 | n := strings.IndexByte(text, '\n') 49 | if n >= 0 { 50 | s = text[:n+1] 51 | text = text[n+1:] 52 | } else { 53 | n = len(text) 54 | s = text 55 | text = text[n:] 56 | } 57 | r := a.Area.Bounds() 58 | width := pix.StringWidth(s[:n], a.Face) 59 | switch a.Align { 60 | case Acenter: 61 | a.Pos.X = (r.Min.X + r.Max.X - width) / 2 62 | case Aright: 63 | a.Pos.X = r.Max.X - width 64 | default: // Aleft 65 | a.Pos.X = r.Min.X 66 | } 67 | a.TextWriter.WriteString(s) 68 | } 69 | } 70 | 71 | // Printf works like fmt.Printf 72 | func (a *TextArea) Printf(f string, v ...any) { 73 | a.WriteString(fmt.Sprintf(f, v...)) 74 | } 75 | 76 | // Display repersents the whole display divided in two areas. The top part takes 77 | // up 1/4 of the screen height and the bottom part takes the rest. In case of 78 | // small OLED displays these two areas are often physically implemented using 79 | // two different colors. 80 | // 81 | // The areas are mainly designed to print text but you can use all pix drawing 82 | // primitives on them using their Area fields. 83 | // 84 | // We use single letters to name the areas in a way that allude to HTML tags. 85 | type Display struct { 86 | H TextArea // the top part of the display (header) 87 | P TextArea // the bottom part of the display 88 | } 89 | 90 | // Init initializes the display. 91 | func (d *Display) Init(disp *pix.Display) { 92 | f := terminus16.NewFace( 93 | terminus16.X0020_007e, 94 | //terminus16.X00a0_0175, 95 | ) 96 | 97 | r := disp.Bounds() 98 | r.Max.Y /= 4 99 | d.H.TextWriter = disp.NewArea(r).NewTextWriter(f) 100 | d.H.SetColor(fgcolor) 101 | 102 | r = disp.Bounds() 103 | r.Min.Y = r.Max.Y / 4 104 | d.P.TextWriter = disp.NewArea(r).NewTextWriter(f) 105 | d.P.SetColor(fgcolor) 106 | } 107 | 108 | // Flush ensures that the latest changes are visible on the screen. 109 | func (d *Display) Flush() { 110 | d.H.Area.Flush() 111 | } 112 | -------------------------------------------------------------------------------- /devboard/readme.md: -------------------------------------------------------------------------------- 1 | ## Support for nRF5 development boards 2 | 3 | ### Supported boards 4 | 5 | #### [pca10059](pca10059) 6 | 7 | Nordic [nRF52840-Dongle](https://www.nordicsemi.com/Software-and-tools/Development-Kits/nRF52840-Dongle) (PCA10059) 8 | 9 | ![Nordic nRF52840-Dongle](pca10059/doc/board.jpg) 10 | 11 | ### Directory structure 12 | 13 | Every supported board has its directory here. Each of them contains three subdirectories: 14 | 15 | #### board 16 | 17 | The `board` directory contains Go packages that provide the interface to the peripherals available on the board such as buttons, LEDs, etc. 18 | There is also an `init` package that imported configures the whole system for typical usage. 19 | Usually you don't need to import it explicitly because any other package in the `board` directory imports `init` itself to ensure proper operation. 20 | 21 | #### doc 22 | 23 | The `doc` directory may contain documentation, diagrams, photos and other useful resources. 24 | 25 | #### examples 26 | 27 | The `examples` directory contains simple programs that demonstrate how to use the available Go packages to work with the board and various external peripherals connected to it. 28 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/embeddedgo/nrf5 2 | 3 | go 1.22 4 | 5 | require github.com/embeddedgo/display v1.2.1 6 | 7 | //GOTARGET=nrf52840 8 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/embeddedgo/display v1.2.1 h1:ZbUfDWNhNBwC+HgEEUw/WnnsqsXsPrctJtpK5hjtECY= 2 | github.com/embeddedgo/display v1.2.1/go.mod h1:0sxxBoklqMbA1uBqEAg8Plntmwvt7cNsgxaf7UaS4yw= 3 | -------------------------------------------------------------------------------- /hal/clock/func.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package clock 6 | 7 | import "github.com/embeddedgo/nrf5/hal/te" 8 | 9 | type Task byte 10 | 11 | const ( 12 | HFCLKSTART Task = 0 // Start high frequency crystal oscilator. 13 | HFCLKSTOP Task = 1 // Stop high frequency crystal oscilator. 14 | LFCLKSTART Task = 2 // Start low frequency source. 15 | LFCLKSTOP Task = 3 // Stop low frequency source. 16 | CAL Task = 4 // Start calibration of low freq. RC oscilator. 17 | CTSTART Task = 5 // Start calibration timer. 18 | CTSTOP Task = 6 // Stop calibration timer. 19 | ) 20 | 21 | func (t Task) Task() *te.Task { return r().Regs.Task(int(t)) } 22 | 23 | type Event byte 24 | 25 | const ( 26 | HFCLKSTARTED Event = 0 // High frequency crystal oscilator started. 27 | LFCLKSTARTED Event = 1 // Low frequency source started. 28 | DONE Event = 3 // Calibration of low freq. RC osc. complete. 29 | CTTO Event = 4 // Calibration timer timeout. 30 | ) 31 | 32 | func (e Event) Event() *te.Event { return r().Regs.Event(int(e)) } 33 | 34 | // LoadHFCLKRUN returns true if HFCLKSTART task was triggered. 35 | func LoadHFCLKRUN() bool { 36 | return r().hfclkrun.Load() != 0 37 | } 38 | 39 | type Source byte 40 | 41 | const ( 42 | RC Source = 0 43 | XTAL Source = 1 44 | SYNTH Source = 2 45 | ) 46 | 47 | // LoadHFCLKStat returns information about HFCLK status (running or not) and 48 | // clock source. 49 | func LoadHFCLKSTAT() (src Source, running bool) { 50 | s := r().hfclkstat.Load() 51 | return Source(s & 1), s&(1<<16) != 0 52 | } 53 | 54 | // LoadLFCLKRUN returns true if LFCLKSTART task was triggered. 55 | func LoadLFCLKRUN() bool { 56 | return r().lfclkrun.LoadBits(1<<0) != 0 57 | } 58 | 59 | // LoadLFCLKSTAT returns information about LFCLK status (running or not) and 60 | // clock source. 61 | func LoadLFCLKSTAT() (src Source, running bool) { 62 | s := r().lfclkstat.Load() 63 | return Source(s & 1), s&(1<<16) != 0 64 | } 65 | 66 | // LoadLFCLKSRCCOPY returns clock source for LFCLK from time when LFCLKSTART 67 | // task has been triggered. 68 | func LoadLFCLKSRCCOPY() Source { 69 | return Source(r().lfclksrccopy.LoadBits(3)) 70 | } 71 | 72 | // LoadLFCLKSRC returns clock source for LFCLK. 73 | func LoadLFCLKSRC() Source { 74 | return Source(r().lfclksrc.LoadBits(3)) 75 | } 76 | 77 | // StoreLFCLKSRC sets clock source for LFCLK. It can only be modified when 78 | // LFCLK is not running. 79 | func StoreLFCLKSRC(src Source) { 80 | r().lfclksrc.Store(uint32(src)) 81 | } 82 | 83 | // LoadCTIV returns calibration timer interval in milliseconds. 84 | func LoadCTIV() int { 85 | return int(r().ctiv.LoadBits(0x7f) * 250) 86 | } 87 | 88 | // StoreCTIV sets calibration timer interval as number of milliseconds 89 | // (range: 250 ms to 31750 ms). 90 | func StoreCTIV(ctiv int) { 91 | r().ctiv.Store(uint32(ctiv+125) / 250) 92 | } 93 | 94 | type XtalFreq byte 95 | 96 | const ( 97 | X16MHz XtalFreq = 0xff 98 | X32MHz XtalFreq = 0x00 99 | ) 100 | 101 | // LoadXTALFREQ returns selected frequency of external crystal for HFCLK. nRF51. 102 | func LoadXTALFREQ() XtalFreq { 103 | return XtalFreq(r().xtalfreq.LoadBits(0xff)) 104 | } 105 | 106 | // StoreXTALFREQ selects frequency of external crystal for HFCLK. nRF51. 107 | func StoreXTALFREQ(f XtalFreq) { 108 | r().xtalfreq.Store(uint32(f)) 109 | } 110 | 111 | // TraceSpeed represents speed of Trace Port clock. 112 | type TraceSpeed byte 113 | 114 | const ( 115 | T32MHz TraceSpeed = 0 // 32 MHz Trace Port clock (TRACECLK = 16 MHz). 116 | T16MHz TraceSpeed = 1 // 16 MHz Trace Port clock (TRACECLK = 8 MHz). 117 | T8MHz TraceSpeed = 2 // 8 MHz Trace Port clock (TRACECLK = 4 MHz). 118 | T4MHz TraceSpeed = 3 // 4 MHz Trace Port clock (TRACECLK = 2 MHz). 119 | ) 120 | 121 | // TraceMux represents trace pins multiplexing configuration. 122 | type TraceMux byte 123 | 124 | const ( 125 | GPIO TraceMux = 0 // GPIOs multiplexed onto all trace pins. 126 | Serial TraceMux = 1 // SWO onto P0.18, GPIO onto other trace pins. 127 | Parallel TraceMux = 2 // TRACECLK and TRACEDATA onto P0.20,18,16,15,14. 128 | ) 129 | 130 | // LoadTRACECONFIG returns current speed of Trace Port clock and pin 131 | // multiplexing of trace signals. nRF52. 132 | func LoadTRACECONFIG() (TraceSpeed, TraceMux) { 133 | tc := r().traceconfig.Load() 134 | return TraceSpeed(tc & 3), TraceMux(tc >> 16 & 3) 135 | } 136 | 137 | // StoreTRACECONFIG sets speed of Trace Port clock and pin multiplexing of 138 | // trace signals. nRF52. 139 | func StoreTRACECONFIG(s TraceSpeed, m TraceMux) { 140 | r().traceconfig.Store(uint32(s) | uint32(m)<<16) 141 | } 142 | -------------------------------------------------------------------------------- /hal/clock/regs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package clock provides interface to manage clocks source/generation. 6 | package clock 7 | 8 | import ( 9 | "embedded/mmio" 10 | "embedded/rtos" 11 | "unsafe" 12 | 13 | "github.com/embeddedgo/nrf5/hal/te" 14 | "github.com/embeddedgo/nrf5/p/mmap" 15 | ) 16 | 17 | type regs struct { 18 | te.Regs 19 | 20 | _ [2]mmio.U32 21 | hfclkrun mmio.U32 22 | hfclkstat mmio.U32 23 | _ mmio.U32 24 | lfclkrun mmio.U32 25 | lfclkstat mmio.U32 26 | lfclksrccopy mmio.U32 27 | _ [62]mmio.U32 28 | lfclksrc mmio.U32 29 | _ [7]mmio.U32 30 | ctiv mmio.U32 31 | _ [5]mmio.U32 32 | xtalfreq mmio.U32 33 | _ [2]mmio.U32 34 | traceconfig mmio.U32 35 | } 36 | 37 | func r() *regs { return (*regs)(unsafe.Pointer(mmap.CLOCK_BASE)) } 38 | 39 | // IRQEnabled returns EventMask that lists events that have enabled 40 | // generating interrupts.. 41 | func IRQEnabled() te.EventMask { 42 | return r().IRQEnabled() 43 | } 44 | 45 | // EnableIRQ enables generating interrupts by events specified by mask. 46 | func EnableIRQ(mask te.EventMask) { 47 | r().EnableIRQ(mask) 48 | } 49 | 50 | // DisableIRQ disables generating interrupts by events specified by mask 51 | func DisableIRQ(mask te.EventMask) { 52 | r().DisableIRQ(mask) 53 | } 54 | 55 | // IRQ returns the IRQ number in NVIC associated to the peripheral. 56 | func IRQ() rtos.IRQ { 57 | return r().IRQ() 58 | } 59 | -------------------------------------------------------------------------------- /hal/gpio/conf.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gpio 6 | 7 | // Config is configuration word of GPIO pin. 8 | type Config uint32 9 | 10 | const ( 11 | ModeIn Config = 0 // Input buffer connected, output disabled. 12 | ModeInOut Config = 1 // Input buffer connected, output enabled. 13 | ModeDiscon Config = 2 // Input buffer disconnected, output disabled. 14 | ModeOut Config = 3 // Input buffer disconnected, output enabled. 15 | 16 | PullNone Config = 0 << 2 // Disable pull-up/down resistance. 17 | PullDown Config = 1 << 2 // Enable pull-down resistance. 18 | PullUp Config = 3 << 2 // Enable pull-up resistance. 19 | 20 | DriveS0S1 Config = 0 << 8 // Standard 0, standard 1. 21 | DriveH0S1 Config = 1 << 8 // High drive 0, standard 1. 22 | DriveS0H1 Config = 2 << 8 // Standard 0, high drive 1. 23 | DriveH0H1 Config = 3 << 8 // High drive 0, high drive 1. 24 | DriveD0S1 Config = 4 << 8 // Disconnect 0, standard 1. 25 | DriveD0H1 Config = 5 << 8 // Disconnect 0, high drive 1. 26 | DriveS0D1 Config = 6 << 8 // Standard 0, disconnect 1. 27 | DriveH0D1 Config = 7 << 8 // High drive 0, disconnect 1. 28 | 29 | SenseNone Config = 0 << 16 // Sense disabled. 30 | SenseHigh Config = 2 << 16 // Sense for high level. 31 | SenseLow Config = 3 << 16 // Sense for low level. 32 | ) 33 | 34 | // Setup configures n-th pin in port p. 35 | func (p *Port) SetupPin(n int, cfg Config) { 36 | p.pincnf[n].Store(uint32(cfg)) 37 | } 38 | 39 | // PinConfig returns current configuration of n-th pin in port p. 40 | func (p *Port) PinConfig(n int) Config { 41 | return Config(p.pincnf[n].Load()) 42 | } 43 | 44 | // Setup configures pins. 45 | func (p *Port) Setup(pins Pins, cfg Config) { 46 | for n := 0; n < 32; n++ { 47 | if pins&(1< 1 { 17 | return 0 18 | } 19 | return (mmap.P0_BASE + 0x500) + uintptr(n)*0x300 20 | } 21 | 22 | func portnum(p *Port) int { 23 | n := int(uintptr(unsafe.Pointer(p))-(mmap.P0_BASE+0x500)) / 0x300 24 | if uint(n) > 1 { 25 | return -1 26 | } 27 | return n 28 | } 29 | -------------------------------------------------------------------------------- /hal/gpio/nrf52840.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build nrf52840 6 | 7 | package gpio 8 | 9 | func ain(pin Pin) AIN { 10 | psel := pin.PSEL() 11 | if psel>>5 != 0 { 12 | return -1 13 | } 14 | switch { 15 | case psel <= 1: 16 | return -1 17 | case psel <= 5: 18 | return AIN(psel - 1) 19 | case psel <= 27: 20 | return -1 21 | default: 22 | return AIN(psel - 23) 23 | } 24 | } 25 | 26 | func apin(a AIN) Pin { 27 | if a <= 0 { 28 | return Pin{} 29 | } 30 | h := portaddr(0) + uintptr(a) 31 | if a <= AIN3 { 32 | h += 1 33 | } else { 34 | h += 23 35 | } 36 | return Pin{h} 37 | } 38 | -------------------------------------------------------------------------------- /hal/gpio/pin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gpio 6 | 7 | import ( 8 | "unsafe" 9 | ) 10 | 11 | // Pin represents one phisical pin (specific pin in specific port). 12 | type Pin struct { 13 | h uintptr // [31:7] port address, [6:5] port number, [4:0] pin number 14 | } 15 | 16 | // IsValid reports whether p represents a valid pin. 17 | func (p Pin) IsValid() bool { 18 | return p.h&^0x7F != 0 19 | } 20 | 21 | // Port returns the port where the pin is located. 22 | func (p Pin) Port() *Port { 23 | return (*Port)(unsafe.Pointer(p.h &^ 0x7F)) 24 | } 25 | 26 | // PSEL returns the PSEL representation of GPIO pin in connected state. 27 | func (p Pin) PSEL() PSEL { 28 | if p.h&^0x7F == 0 { 29 | return 0xFFFFFFFF 30 | } 31 | return PSEL(p.h & 0x7F) 32 | } 33 | 34 | // AIN retruns analog intput number that corresponds to p or -1 if 35 | // pin can not be used as analog input. 36 | func (p Pin) AIN() AIN { 37 | return ain(p) 38 | } 39 | 40 | // Num returns the pin number in the port. 41 | func (p Pin) Num() int { 42 | return int(p.h & 0x1F) 43 | } 44 | 45 | // Setup configures pin. 46 | func (p Pin) Setup(cfg Config) { 47 | p.Port().SetupPin(p.Num(), cfg) 48 | } 49 | 50 | // Config returns current configuration of pin. 51 | func (p Pin) Config() Config { 52 | return p.Port().PinConfig(p.Num()) 53 | } 54 | 55 | // Mask returns bitmask that represents the pin. 56 | func (p Pin) Mask() Pins { 57 | return Pin0 << uint(p.Num()) 58 | } 59 | 60 | // Load returns input value of the pin. 61 | func (p Pin) Load() int { 62 | return int(p.Port().in.Load()) >> uint(p.Num()) & 1 63 | } 64 | 65 | // LoadOut returns output value of the pin. 66 | func (p Pin) LoadOut() int { 67 | return int(p.Port().out.Load()) >> uint(p.Num()) & 1 68 | } 69 | 70 | // Set sets output value of the pin to 1 in one atomic operation. 71 | func (p Pin) Set() { 72 | p.Port().outset.Store(uint32(Pin0) << uint(p.Num())) 73 | } 74 | 75 | // Clear sets output value of the pin to 0 in one atomic operation. 76 | func (p Pin) Clear() { 77 | p.Port().outclr.Store(uint32(Pin0) << uint(p.Num())) 78 | } 79 | 80 | // Store sets output value of the pin to the least significant bit of val. 81 | func (p Pin) Store(val int) { 82 | port := p.Port() 83 | n := uint(p.Num()) 84 | if val&1 != 0 { 85 | port.outset.Store(uint32(Pin0) << n) 86 | } else { 87 | port.outclr.Store(uint32(Pin0) << n) 88 | } 89 | } 90 | 91 | // Detect reports whether the pin have met the criteria set by Sense* 92 | // configuration options. nRF52. 93 | func (p Pin) Detect() bool { 94 | return p.Port().latch.Load()>>uint(p.Num())&1 != 0 95 | } 96 | 97 | // ClearDetect clears the detect state for pin. nRF52. 98 | func (p Pin) ClearDetect() { 99 | p.Port().latch.Store(1 << uint(p.Num())) 100 | } 101 | 102 | // PSEL is numerical representation of GPIO pin used as peripheral digital 103 | // signal. It can have two states: connected or disconnected to the peripheral. 104 | type PSEL uint32 105 | 106 | // IsConnected reports the connection state of ps. 107 | func (ps PSEL) IsConnected() bool { 108 | return ps>>31 != 0 109 | } 110 | 111 | // Connected returns ps with connection state changed. 112 | func (ps PSEL) Connected(connected bool) PSEL { 113 | if connected { 114 | return ps &^ 1 << 31 115 | } 116 | return ps | 1<<31 117 | } 118 | 119 | // Pin returns the GPIO pin corresponding to ps. 120 | func (ps PSEL) Pin() Pin { 121 | if ps < 0 { 122 | return Pin{} 123 | } 124 | return Pin{portaddr(int(ps)>>5) | uintptr(ps)} 125 | } 126 | 127 | const ( 128 | ANC AIN = 0 // Not connected. 129 | AIN0 AIN = 1 // Analog input 0. 130 | AIN1 AIN = 2 // Analog input 1. 131 | AIN2 AIN = 3 // Analog input 2. 132 | AIN3 AIN = 4 // Analog input 3. 133 | AIN4 AIN = 5 // Analog input 4. 134 | AIN5 AIN = 6 // Analog input 5. 135 | AIN6 AIN = 7 // Analog input 6. 136 | AIN7 AIN = 8 // Analog input 7. 137 | VDD AIN = 9 // VDD 138 | VDDH1_5 AIN = 0xD // VDDH / 5 139 | ) 140 | 141 | // AIN is an analog input number. 142 | type AIN int8 143 | 144 | // Pin returns the GPIO pin that can be used as analog input a. 145 | func (a AIN) Pin() Pin { 146 | return apin(a) 147 | } 148 | -------------------------------------------------------------------------------- /hal/gpio/port.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gpio 6 | 7 | import ( 8 | "embedded/mmio" 9 | "unsafe" 10 | ) 11 | 12 | // Port represents a GPIO port. 13 | type Port struct { 14 | _ uint32 15 | out mmio.U32 16 | outset mmio.U32 17 | outclr mmio.U32 18 | in mmio.U32 19 | dir mmio.U32 20 | dirset mmio.U32 21 | dirclr mmio.U32 22 | latch mmio.U32 23 | detectmode mmio.U32 24 | _ [118]uint32 25 | pincnf [32]mmio.U32 26 | } 27 | 28 | // P returns n-th GPIO port 29 | func P(n int) *Port { 30 | return (*Port)(unsafe.Pointer(portaddr(n))) 31 | } 32 | 33 | // Num returns the port number. 34 | func (p *Port) Num() int { 35 | return portnum(p) 36 | } 37 | 38 | // Pins is a bitmask which represents the pins of GPIO port. 39 | type Pins uint32 40 | 41 | const ( 42 | Pin0 Pins = 1 << iota 43 | Pin1 44 | Pin2 45 | Pin3 46 | Pin4 47 | Pin5 48 | Pin6 49 | Pin7 50 | Pin8 51 | Pin9 52 | Pin10 53 | Pin11 54 | Pin12 55 | Pin13 56 | Pin14 57 | Pin15 58 | Pin16 59 | Pin17 60 | Pin18 61 | Pin19 62 | Pin20 63 | Pin21 64 | Pin22 65 | Pin23 66 | Pin24 67 | Pin25 68 | Pin26 69 | Pin27 70 | Pin28 71 | Pin29 72 | Pin30 73 | Pin31 74 | ) 75 | 76 | // Pin returns n-th pin in port p. 77 | func (p *Port) Pin(n int) Pin { 78 | if uint(n) > 31 { 79 | panic("gpio: bad pin") 80 | } 81 | ptr := uintptr(unsafe.Pointer(p)) 82 | return Pin{ptr | uintptr(p.Num())<<5 | uintptr(n)} 83 | } 84 | -------------------------------------------------------------------------------- /hal/gpiote/chan.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gpiote 6 | 7 | import ( 8 | "github.com/embeddedgo/nrf5/hal/gpio" 9 | "github.com/embeddedgo/nrf5/hal/internal" 10 | "github.com/embeddedgo/nrf5/hal/te" 11 | ) 12 | 13 | // NumChan is the number of implemented GPIOTE channels (4 in case of nRF51, 8 14 | // in case of nRF52). 15 | const NumChan = numChan 16 | 17 | // Chan represents GPIOTE channel. 18 | type Chan int8 19 | 20 | var unusedChannels uint32 = 1<> 8).Pin(), Config(v &^ psel) 83 | } 84 | 85 | // Setup setups channel c to use pin and cfg configuration. 86 | func (c Chan) Setup(pin gpio.Pin, cfg Config) { 87 | r().config[c].Store(uint32(pin.PSEL())<<8 | uint32(cfg)) 88 | } 89 | -------------------------------------------------------------------------------- /hal/gpiote/nrf52.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build nrf52832 nrf52833 nrf52840 6 | 7 | package gpiote 8 | 9 | const numChan = 8 10 | -------------------------------------------------------------------------------- /hal/gpiote/regs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gpiote 6 | 7 | import ( 8 | "embedded/mmio" 9 | "embedded/rtos" 10 | "unsafe" 11 | 12 | "github.com/embeddedgo/nrf5/hal/te" 13 | "github.com/embeddedgo/nrf5/p/mmap" 14 | ) 15 | 16 | type regs struct { 17 | te.Regs 18 | 19 | _ [68]mmio.U32 20 | config [8]mmio.U32 21 | } 22 | 23 | func r() *regs { 24 | return (*regs)(unsafe.Pointer(mmap.GPIOTE_BASE)) 25 | } 26 | 27 | func IRQ() rtos.IRQ { 28 | return r().IRQ() 29 | } 30 | 31 | func IRQEnabled() te.EventMask { 32 | return r().IRQEnabled() 33 | } 34 | 35 | func EnableIRQ(mask te.EventMask) { 36 | r().EnableIRQ(mask) 37 | } 38 | 39 | func DisableIRQ(mask te.EventMask) { 40 | r().DisableIRQ(mask) 41 | } 42 | -------------------------------------------------------------------------------- /hal/internal/alloc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package internal 6 | 7 | import "sync/atomic" 8 | 9 | func BitAlloc(unused *uint32) int { 10 | for { 11 | m := atomic.LoadUint32(unused) 12 | if m == 0 { 13 | return -1 14 | } 15 | i := uint(0) 16 | for (m>>i)&1 == 0 { 17 | i++ 18 | } 19 | if atomic.CompareAndSwapUint32(unused, m, m&^(1<>31 == 0 20 | } 21 | 22 | func (r *Reg) Store(psel gpio.PSEL, en bool) { 23 | pseldis := uint32(int32(psel)) 24 | if !en { 25 | pseldis |= 1 << 31 26 | } 27 | r.u32.Store(pseldis) 28 | } 29 | -------------------------------------------------------------------------------- /hal/irq/nrf52840.go: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE. GENERATED BY svdxgen. 2 | 3 | //go:build nrf52840 4 | 5 | // Package irq provides the list of supported external interrupts. 6 | package irq 7 | 8 | import "embedded/rtos" 9 | 10 | const ( 11 | POWER_CLOCK rtos.IRQ = 0 12 | RADIO rtos.IRQ = 1 13 | UARTE0_UART0 rtos.IRQ = 2 14 | SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 rtos.IRQ = 3 15 | SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1 rtos.IRQ = 4 16 | NFCT rtos.IRQ = 5 17 | GPIOTE rtos.IRQ = 6 18 | SAADC rtos.IRQ = 7 19 | TIMER0 rtos.IRQ = 8 20 | TIMER1 rtos.IRQ = 9 21 | TIMER2 rtos.IRQ = 10 22 | RTC0 rtos.IRQ = 11 23 | TEMP rtos.IRQ = 12 24 | RNG rtos.IRQ = 13 25 | ECB rtos.IRQ = 14 26 | CCM_AAR rtos.IRQ = 15 27 | WDT rtos.IRQ = 16 28 | RTC1 rtos.IRQ = 17 29 | QDEC rtos.IRQ = 18 30 | COMP_LPCOMP rtos.IRQ = 19 31 | SWI0_EGU0 rtos.IRQ = 20 32 | SWI1_EGU1 rtos.IRQ = 21 33 | SWI2_EGU2 rtos.IRQ = 22 34 | SWI3_EGU3 rtos.IRQ = 23 35 | SWI4_EGU4 rtos.IRQ = 24 36 | SWI5_EGU5 rtos.IRQ = 25 37 | TIMER3 rtos.IRQ = 26 38 | TIMER4 rtos.IRQ = 27 39 | PWM0 rtos.IRQ = 28 40 | PDM rtos.IRQ = 29 41 | MWU rtos.IRQ = 32 42 | PWM1 rtos.IRQ = 33 43 | PWM2 rtos.IRQ = 34 44 | SPIM2_SPIS2_SPI2 rtos.IRQ = 35 45 | RTC2 rtos.IRQ = 36 46 | I2S rtos.IRQ = 37 47 | FPU rtos.IRQ = 38 48 | USBD rtos.IRQ = 39 49 | UARTE1 rtos.IRQ = 40 50 | QSPI rtos.IRQ = 41 51 | CRYPTOCELL rtos.IRQ = 42 52 | PWM3 rtos.IRQ = 45 53 | SPIM3 rtos.IRQ = 47 54 | ) 55 | -------------------------------------------------------------------------------- /hal/ppi/chan.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ppi 6 | 7 | import ( 8 | "github.com/embeddedgo/nrf5/hal/te" 9 | ) 10 | 11 | // Pre-programmed channels. nrf52-. 12 | const ( 13 | TIMER0_COMPARE0__RADIO_TXEN te.Chan = 20 14 | TIMER0_COMPARE0__RADIO_RXEN te.Chan = 21 15 | TIMER0_COMPARE1__RADIO_DISABLE te.Chan = 22 16 | RADIO_BCMATCH__AAR_START te.Chan = 23 17 | RADIO_READY__CCM_KSGEN te.Chan = 24 18 | RADIO_ADDRESS__CCM_CRYPT te.Chan = 25 19 | RADIO_ADDRESS__TIMER0_CAPTURE1 te.Chan = 26 20 | RADIO_END__TIMER0_CAPTURE2 te.Chan = 27 21 | RTC0_COMPARE0__RADIO_TXEN te.Chan = 28 22 | RTC0_COMPARE0__RADIO_RXEN te.Chan = 29 23 | RTC0_COMPARE0__TIMER0_CLEAR te.Chan = 30 24 | RTC0_COMPARE0__TIMER0_START te.Chan = 31 25 | ) 26 | 27 | // LoadEEP returns the channel Event End Point. nRF52-. 28 | func LoadEEP(c te.Chan) *te.Event { 29 | return loadEEP(c) 30 | } 31 | 32 | // StoreEEP sets the channel Event End Point. nRF52-. 33 | func StoreEEP(c te.Chan, e *te.Event) { 34 | storeEEP(c, e) 35 | } 36 | 37 | // LoadTEP returns the channel Task End Point. nRF52-. 38 | func LoadTEP(c te.Chan) *te.Task { 39 | return loadTEP(c) 40 | } 41 | 42 | // StoreTEP sets the value channel Task End Point. nRF52-. 43 | func StoreTEP(c te.Chan, t *te.Task) { 44 | storeTEP(c, t) 45 | } 46 | 47 | // TEP1 returns the value of channel Fork Task End Point. nRF52. 48 | func TEP1(c te.Chan) *te.Task { 49 | return loadTEP1(c) 50 | } 51 | 52 | // SetTEP1 sets the value of channel Fork Task End Point. nRF52. 53 | func SetTEP1(c te.Chan, t *te.Task) { 54 | storeTEP1(c, t) 55 | } 56 | -------------------------------------------------------------------------------- /hal/ppi/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package ppi provides access to some features of PPI (Programmable Peripheral 6 | // Interconnect) and DPPI (Distributed PPI). Most of the features of PPI/DPPI 7 | // like channels, channel groups, channel group tasks are handled in unified way 8 | // by te package. The ppi package allows to manage PPI/DPPI interrupts for 9 | // multiple events simultaneously and exposes some PPI specific features that 10 | // are not supported by te package: list of preprogrammed channels, connecting 11 | // one event/task to multiple channels. 12 | package ppi -------------------------------------------------------------------------------- /hal/ppi/irq.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ppi 6 | 7 | import ( 8 | "embedded/rtos" 9 | 10 | "github.com/embeddedgo/nrf5/hal/te" 11 | ) 12 | 13 | func IRQ() rtos.IRQ { 14 | return r().IRQ() 15 | } 16 | 17 | func IRQEnabled() te.EventMask { 18 | return r().IRQEnabled() 19 | } 20 | 21 | func EnableIRQ(mask te.EventMask) { 22 | r().EnableIRQ(mask) 23 | } 24 | 25 | func DisableIRQ(mask te.EventMask) { 26 | r().DisableIRQ(mask) 27 | } 28 | -------------------------------------------------------------------------------- /hal/ppi/nrf52.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build nrf52832 nrf52833 nrf52840 6 | 7 | package ppi 8 | 9 | import ( 10 | "unsafe" 11 | 12 | "github.com/embeddedgo/nrf5/hal/internal" 13 | "github.com/embeddedgo/nrf5/hal/te" 14 | "github.com/embeddedgo/nrf5/p/mmap" 15 | ) 16 | 17 | const numGroup = 6 18 | 19 | type regs struct { 20 | te.Regs 21 | internal.PPI 22 | } 23 | 24 | func r() *regs { 25 | return (*regs)(unsafe.Pointer(mmap.PPI_BASE)) 26 | } 27 | 28 | func loadEEP(c te.Chan) *te.Event { 29 | return (*te.Event)(unsafe.Pointer(uintptr(r().CH[c].EEP.Load()))) 30 | } 31 | 32 | func storeEEP(c te.Chan, e *te.Event) { 33 | r().CH[c].EEP.Store(uint32(uintptr(unsafe.Pointer(e)))) 34 | } 35 | 36 | func loadTEP(c te.Chan) *te.Task { 37 | return (*te.Task)(unsafe.Pointer(uintptr(r().CH[c].TEP.Load()))) 38 | } 39 | 40 | func storeTEP(c te.Chan, t *te.Task) { 41 | r().CH[c].TEP.Store(uint32(uintptr(unsafe.Pointer(t)))) 42 | } 43 | 44 | func loadTEP1(c te.Chan) *te.Task { 45 | return (*te.Task)(unsafe.Pointer(uintptr(r().FORK_TEP[c].Load()))) 46 | } 47 | 48 | func storeTEP1(c te.Chan, t *te.Task) { 49 | r().FORK_TEP[c].Store(uint32(uintptr(unsafe.Pointer(t)))) 50 | } 51 | -------------------------------------------------------------------------------- /hal/rtc/periph.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package rtc provides access to the registers of Real Time Counter. 6 | package rtc 7 | 8 | import ( 9 | "embedded/mmio" 10 | "unsafe" 11 | 12 | "github.com/embeddedgo/nrf5/hal/te" 13 | "github.com/embeddedgo/nrf5/p/mmap" 14 | ) 15 | 16 | // Periph represents Real Time Counter peripheral. 17 | type Periph struct { 18 | te.Regs 19 | 20 | _ [65]uint32 21 | counter mmio.U32 22 | prescaler mmio.U32 23 | _ [13]uint32 24 | cc [4]mmio.U32 25 | } 26 | 27 | func RTC(n int) *Periph { 28 | switch n { 29 | case 0: 30 | return (*Periph)(unsafe.Pointer(mmap.RTC0_BASE)) 31 | case 1: 32 | return (*Periph)(unsafe.Pointer(mmap.RTC1_BASE)) 33 | case 2: 34 | return (*Periph)(unsafe.Pointer(mmap.RTC2_BASE)) 35 | default: 36 | return nil 37 | } 38 | } 39 | 40 | type Task uint8 41 | 42 | const ( 43 | START Task = 0 // Start RTC COUNTER. 44 | STOP Task = 1 // Stop RTC COUNTER. 45 | CLEAR Task = 2 // Clear RTC COUNTER. 46 | TRIGOVRFLW Task = 3 // Store COUNTER to 0xFFFFF0. 47 | ) 48 | 49 | type Event uint8 50 | 51 | const ( 52 | TICK Event = 0 // Event on COUNTER increment. 53 | OVRFLW Event = 1 // Event on COUNTER overflow. 54 | ) 55 | 56 | // COMPARE returns compare event on CC[n] match. 57 | func COMPARE(n int) Event { 58 | return Event(16 + n) 59 | } 60 | 61 | func (p *Periph) Task(t Task) *te.Task { return p.Regs.Task(int(t)) } 62 | func (p *Periph) Event(e Event) *te.Event { return p.Regs.Event(int(e)) } 63 | 64 | // LoadCOUNTER returns value of counter register. 65 | func (p *Periph) LoadCOUNTER() uint32 { 66 | return p.counter.Load() 67 | } 68 | 69 | // LoadPRESCALER returns value of prescaler register. 70 | func (p *Periph) LoadPRESCALER() uint32 { 71 | return p.prescaler.Load() 72 | } 73 | 74 | // StorePRESCALER stores prescaler to pr (freq = 32768Hz/(pr+1)). Can be used 75 | // only when the timer is stopped. 76 | func (p *Periph) StorePRESCALER(pr int) { 77 | p.prescaler.Store(uint32(pr)) 78 | } 79 | 80 | // LoadCC returns value of n-th compare register. 81 | func (p *Periph) LoadCC(n int) uint32 { 82 | return p.cc[n].Load() 83 | } 84 | 85 | // StoreCC stores n-th compare register to cc. 86 | func (p *Periph) StoreCC(n int, cc uint32) { 87 | p.cc[n].Store(cc) 88 | } 89 | -------------------------------------------------------------------------------- /hal/saadc/driver.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Embedded Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package saadc 6 | 7 | import ( 8 | "runtime" 9 | "sync" 10 | "unsafe" 11 | 12 | "github.com/embeddedgo/nrf5/hal/gpio" 13 | ) 14 | 15 | // TODO: we need []sync.Mutex here in case of multiple SAADC peripherals. 16 | var analogMutex sync.Mutex 17 | 18 | // AnalogInit provides a convenient way to configure the SAADC peripheral to use 19 | // it by AnalogRead function. It configures and calibrates SAADC(0), 20 | // disconnnects all irs channels from analog inputs and changes the 21 | // configuration of channel 0. 22 | // 23 | // The SAADC resolution is set to resBits. The 4x hardware oversampling in burst 24 | // mode is used to reduce the noise. The channel 0 configuration is set to 25 | // G1_4|RVDD1_4|T10us|Burst. You can modify these settings using SAADC(0) 26 | // StoreOVERSAMPLE and StoreCONFIG methods. 27 | func AnalogInit(resBits int) { 28 | p := SAADC(0) 29 | p.IRQ().Disable(0) 30 | p.StoreENABLE(false) 31 | p.StoreRESOLUTION(resBits) 32 | p.StoreOVERSAMPLE(Over4x) 33 | p.StoreSAMPLERATE(0, false) 34 | p.StoreMAXCNT(1) 35 | for ch := 0; ch < 8; ch++ { 36 | p.StorePSELP(ch, gpio.ANC) 37 | p.StorePSELN(ch, gpio.ANC) 38 | } 39 | p.StoreCONFIG(0, G1_4|RVDD1_4|T10us|Burst) 40 | p.StoreENABLE(true) 41 | 42 | p.Event(CALIBRATEDONE).Clear() 43 | p.Task(CALIBRATE).Trig() 44 | for !p.Event(CALIBRATEDONE).IsSet() { 45 | runtime.Gosched() 46 | } 47 | } 48 | 49 | // AnalogRead works like Arduino analogRead function. It connects SAADC channel 50 | // 0 to ain and performs a conversion triggering START and SAMPLE tasks. If the 51 | // 4x oversampling is used (AnalogInit default) the conversion takes about 100 52 | // microsecond just like the original analogRead on Arduino UNO, Nano, Mini, 53 | // Mega. Use SAADC directly in continuous mode to achieve the maximum 200 kHz 54 | // sampling rate (5 microseconds per sample). 55 | // 56 | // The SAADC peripheral and its channel 0 must be properly configured before 57 | // using this function (see AnalogInit). 58 | func AnalogRead(ain gpio.AIN) int { 59 | analogMutex.Lock() 60 | var a int16 61 | p := SAADC(0) 62 | p.StorePSELP(0, ain) 63 | p.StorePTR(unsafe.Pointer(&a)) 64 | p.Event(STARTED).Clear() 65 | p.Task(START).Trig() 66 | p.Event(END).Clear() // clear END here to give more time for STARTED event 67 | for !p.Event(STARTED).IsSet() { 68 | // In practice the CPU never enters here 69 | } 70 | p.Task(SAMPLE).Trig() 71 | for !p.Event(END).IsSet() { 72 | // With Gosched this loop is executed 1-2 times instead of 181 times 73 | // (10bit, Over4x). 74 | runtime.Gosched() 75 | } 76 | analogMutex.Unlock() 77 | return int(a) 78 | } 79 | -------------------------------------------------------------------------------- /hal/spim/driver.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Embedded Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package spim 6 | 7 | import ( 8 | "embedded/mmio" 9 | "embedded/rtos" 10 | "runtime" 11 | "unsafe" 12 | 13 | "github.com/embeddedgo/nrf5/hal/gpio" 14 | "github.com/embeddedgo/nrf5/p/mmap" 15 | ) 16 | 17 | type Driver struct { 18 | p *Periph 19 | done rtos.Note 20 | } 21 | 22 | // NewDriver returns a new driver for p. 23 | func NewDriver(p *Periph) *Driver { 24 | return &Driver{p: p} 25 | } 26 | 27 | func (d *Driver) Periph() *Periph { 28 | return d.p 29 | } 30 | 31 | // Enable enables SPIM peripheral. 32 | func (d *Driver) Enable() { 33 | d.p.StoreENABLE(true) 34 | d.p.Event(END).Clear() 35 | } 36 | 37 | // Disable disables SPIM peripheral. 38 | func (d *Driver) Disable() { 39 | d.p.StoreENABLE(false) 40 | if uintptr(unsafe.Pointer(d.p)) == mmap.SPIM3_BASE { 41 | // see errata 195: SPIM3 continues to draw current after disable 42 | (*mmio.U32)(unsafe.Pointer(uintptr(0x4002F004))).Store(1) 43 | } 44 | } 45 | 46 | // UsePin configurs the specified pin to be used as signal s. 47 | func (d *Driver) UsePin(pin gpio.Pin, s Signal) { 48 | if s == MISO { 49 | pin.Setup(gpio.ModeIn) 50 | } else { 51 | switch s { 52 | case SCK: 53 | if d.p.LoadCONFIG()&CPOL1 != 0 { 54 | pin.Set() 55 | } else { 56 | pin.Clear() 57 | } 58 | case MOSI: 59 | pin.Clear() 60 | case CSN: 61 | pin.Store(^d.p.LoadCSNPOL()) 62 | default: // DCX 63 | pin.Set() 64 | } 65 | pin.Setup(gpio.ModeOut) 66 | } 67 | d.p.StorePSEL(s, pin.PSEL(), true) 68 | } 69 | 70 | // Setup sets the SPI mode and clock frequency. 71 | func (d *Driver) Setup(cfg Config, f Freq) { 72 | // TODO: set gpio output for SCK according to CPOL/CPHA 73 | d.p.StoreCONFIG(cfg) 74 | d.p.StoreFREQUENCY(f) 75 | } 76 | 77 | // IRQ returns the interrupt assigned to UART peripheral used by driver. 78 | func (d *Driver) IRQ() rtos.IRQ { 79 | return d.p.IRQ() 80 | } 81 | 82 | func (d *Driver) ISR() { 83 | d.p.Event(END).DisableIRQ() 84 | d.done.Wakeup() 85 | } 86 | 87 | const minIRQLen = 8 88 | 89 | func (d *Driver) WriteRead(out, in []byte) int { 90 | rxn := len(in) 91 | for len(out)|len(in) != 0 { 92 | n := len(out) 93 | if n != 0 { 94 | if n > 0xFFFF { 95 | n = 0xFFFF 96 | } 97 | d.p.StoreTXDPTR(unsafe.Pointer(&out[0])) 98 | out = out[n:] 99 | } 100 | d.p.StoreTXDMAXCNT(n) 101 | n = len(in) 102 | if n != 0 { 103 | if n > 0xFFFF { 104 | n = 0xFFFF 105 | } 106 | d.p.StoreRXDPTR(unsafe.Pointer(&in[0])) 107 | in = in[n:] 108 | } 109 | d.p.StoreRXDMAXCNT(n) 110 | d.done.Clear() 111 | if n < 8 { 112 | // avoid interrupts for small n 113 | d.p.Task(START).Trig() 114 | for !d.p.Event(END).IsSet() { 115 | if n > 1 { 116 | n-- 117 | runtime.Gosched() 118 | } 119 | } 120 | } else { 121 | d.p.Event(END).EnableIRQ() 122 | d.p.Task(START).Trig() 123 | d.done.Sleep(-1) 124 | } 125 | d.p.Event(END).Clear() 126 | } 127 | return rxn 128 | } 129 | -------------------------------------------------------------------------------- /hal/spim/spim0/driver.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Embedded Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package spim0 6 | 7 | import ( 8 | "embedded/rtos" 9 | _ "unsafe" 10 | 11 | "github.com/embeddedgo/nrf5/hal/spim" 12 | ) 13 | 14 | var driver *spim.Driver 15 | 16 | // Driver returns ready to use driver for SPIM0 peripheral. 17 | func Driver() *spim.Driver { 18 | if driver == nil { 19 | driver = spim.NewDriver(spim.SPIM(0)) 20 | driver.IRQ().Enable(rtos.IntPrioLow, 0) 21 | } 22 | return driver 23 | } 24 | 25 | //go:interrupthandler 26 | func _SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_Handler() { driver.ISR() } 27 | 28 | //go:linkname _SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_Handler IRQ3_Handler 29 | -------------------------------------------------------------------------------- /hal/spim/spim1/driver.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Embedded Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package spim1 6 | 7 | import ( 8 | "embedded/rtos" 9 | _ "unsafe" 10 | 11 | "github.com/embeddedgo/nrf5/hal/spim" 12 | ) 13 | 14 | var driver *spim.Driver 15 | 16 | // Driver returns ready to use driver for SPIM1 peripheral. 17 | func Driver() *spim.Driver { 18 | if driver == nil { 19 | driver = spim.NewDriver(spim.SPIM(1)) 20 | driver.IRQ().Enable(rtos.IntPrioLow, 0) 21 | } 22 | return driver 23 | } 24 | 25 | //go:interrupthandler 26 | func _SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_Handler() { driver.ISR() } 27 | 28 | //go:linkname _SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_Handler IRQ4_Handler 29 | -------------------------------------------------------------------------------- /hal/spim/spim2/driver.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Embedded Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package spim2 6 | 7 | import ( 8 | "embedded/rtos" 9 | _ "unsafe" 10 | 11 | "github.com/embeddedgo/nrf5/hal/spim" 12 | ) 13 | 14 | var driver *spim.Driver 15 | 16 | // Driver returns ready to use driver for SPIM2 peripheral. 17 | func Driver() *spim.Driver { 18 | if driver == nil { 19 | driver = spim.NewDriver(spim.SPIM(2)) 20 | driver.IRQ().Enable(rtos.IntPrioLow, 0) 21 | } 22 | return driver 23 | } 24 | 25 | //go:interrupthandler 26 | func _SPIM2_SPIS2_SPI2_Handler() { driver.ISR() } 27 | 28 | //go:linkname _SPIM2_SPIS2_SPI2_Handler IRQ35_Handler 29 | -------------------------------------------------------------------------------- /hal/spim/spim3/driver.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 The Embedded Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package spim3 6 | 7 | import ( 8 | "embedded/rtos" 9 | _ "unsafe" 10 | 11 | "github.com/embeddedgo/nrf5/hal/spim" 12 | ) 13 | 14 | var driver *spim.Driver 15 | 16 | // Driver returns ready to use driver for SPIM3 peripheral. 17 | func Driver() *spim.Driver { 18 | if driver == nil { 19 | driver = spim.NewDriver(spim.SPIM(3)) 20 | driver.IRQ().Enable(rtos.IntPrioLow, 0) 21 | } 22 | return driver 23 | } 24 | 25 | //go:interrupthandler 26 | func _SPIM3_Handler() { driver.ISR() } 27 | 28 | //go:linkname _SPIM3_Handler IRQ47_Handler 29 | -------------------------------------------------------------------------------- /hal/system/rt0.s: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | #include "go_asm.h" 6 | #include "funcdata.h" 7 | #include "textflag.h" 8 | 9 | // _rt0_thumb_noos is the first function of the Embedded Go program 10 | TEXT _rt0_thumb_noos(SB),NOSPLIT|NOFRAME,$0 11 | // Uncomment in case of truble to connect the debugger to the running program. 12 | //B 0(PC) // gdb `set $pc += 4` to exit this loop 13 | 14 | // Disable exceptions until the CPU is ready for SVCall and PendSV. 15 | CPSID 16 | 17 | // Cortex-M settings. 18 | MOVW $0, R0 // dummy RA 19 | MOVW $runtime·vectors(SB), R1 // arg 20 | MOVM.DB.W [R0-R1], (R13) 21 | BL runtime·initCPU(SB) 22 | ADD $8, R13 23 | 24 | // Clear memory and load the data segment from Flash. 25 | BL runtime·initRAMfromROM(SB) 26 | 27 | // Set the numer of available CPUs. 28 | MOVW $1, R0 29 | MOVW $runtime·ncpu(SB), R1 30 | MOVW R0, (R1) 31 | 32 | MOVW R0, R1 // inform rt0_go that we use default stack arrangement 33 | B runtime·rt0_go(SB) 34 | 35 | 36 | // identcurcpu indetifies the current CPU and returns the pointer to its cpuctx 37 | // in R0. It can clobber R0-R4,LR registers (other registers must be preserved). 38 | TEXT runtime·identcurcpu(SB),NOSPLIT|NOFRAME,$0-0 39 | MOVW $runtime·thetasker(SB), R0 40 | MOVW (R0), R0 // allcpu is the first field of the runtime.tasker struct 41 | MOVW (R0), R0 // R0 = thetasker.allcpu[0] (single CPU system) 42 | RET 43 | 44 | 45 | // func preepmtOrWakeup(cpuid int) 46 | TEXT runtime·preemptOrWakeup(SB),NOSPLIT|NOFRAME,$0-4 47 | // Only single CPU is supported so only cpuid=-1 is expected (wakeup). 48 | SEV // see ARM Errata 563915, STM32F10xx Errata 1.1.2 49 | RET 50 | -------------------------------------------------------------------------------- /hal/system/setup.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package system 6 | 7 | import ( 8 | "github.com/embeddedgo/nrf5/hal/clock" 9 | "github.com/embeddedgo/nrf5/p/nvmc" 10 | ) 11 | 12 | // Setup setups nRF51 to operate using specified HFCLK and LFCLK clock sources.. 13 | func Setup(hfsrc, lfsrc clock.Source, lfena bool) { 14 | clock.StoreLFCLKSRC(lfsrc) 15 | if hfsrc == clock.XTAL { 16 | clock.HFCLKSTART.Task().Trig() 17 | } 18 | if lfena { 19 | clock.LFCLKSTART.Task().Trig() 20 | } 21 | for { 22 | src, run := clock.LoadHFCLKSTAT() 23 | if src == hfsrc && run { 24 | break 25 | } 26 | } 27 | for lfena { 28 | src, run := clock.LoadLFCLKSTAT() 29 | if src == lfsrc && run { 30 | break 31 | } 32 | } 33 | nvmc.NVMC().ICACHECNF.SetBits(nvmc.CACHEEN) 34 | } 35 | -------------------------------------------------------------------------------- /hal/system/timer/rtcst/asm.s: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | #include "textflag.h" 6 | 7 | #define ICSR_ADDR 0xE000ED04 8 | #define ICSR_PENDSVSET (1<<28) 9 | 10 | TEXT ·schedule(SB),NOSPLIT|NOFRAME,$0-0 11 | MOVW $ICSR_ADDR, R0 12 | MOVW $ICSR_PENDSVSET, R1 13 | MOVW R1, (R0) 14 | SEV // see ARM Errata 563915 15 | RET 16 | -------------------------------------------------------------------------------- /hal/system/timer/rtcst/rtcst.go: -------------------------------------------------------------------------------- 1 | // Package rtcst implements a tickless system timer using the real time counter. 2 | package rtcst 3 | 4 | import ( 5 | "embedded/rtos" 6 | 7 | "github.com/embeddedgo/nrf5/hal/rtc" 8 | "github.com/embeddedgo/nrf5/hal/te" 9 | ) 10 | 11 | var g struct { 12 | wakens int64 13 | st *rtc.Periph 14 | softcnt uint32 15 | scale uint32 16 | ccn byte 17 | } 18 | 19 | func cce() *te.Event { 20 | return g.st.Event(rtc.COMPARE(int(g.ccn))) 21 | } 22 | 23 | // Setup setups st as system timer using ccn compare channel number. Usually 24 | // rtc.RTC1 and channel number 0 is used. Setup accepts st at its reset state or 25 | // configured before for other purposes. For its needs it uses only rtc.OVRFLW 26 | // and rtc.COMPARE(ccn) events and can work with any prescaler set before 27 | // (avoid prescaler values that cause tick period > 1 ms). Setup starts st by 28 | // triggering rtc.START task but accepts RTC started before. It setups st.IRQ() 29 | // priority in NVIC and enables IRQ handling. 30 | func Setup(st *rtc.Periph, ccn int) { 31 | if uint(ccn) > 3 { 32 | panic("rtcst: bad ccn") 33 | } 34 | g.st = st 35 | g.ccn = byte(ccn) 36 | cce := cce() 37 | cce.DisablePPI() 38 | cce.DisableIRQ() 39 | g.scale = (st.LoadPRESCALER() + 1) * (1e9 >> 9) 40 | ove := st.Event(rtc.OVRFLW) 41 | ove.DisablePPI() 42 | ove.EnableIRQ() 43 | st.IRQ().Enable(rtos.IntPrioSysTimer, 0) 44 | st.Task(rtc.START).Trig() 45 | rtos.SetSystemTimer(nanotime, setAlarm) 46 | } 47 | 48 | func counters() (ch, cl uint32) { 49 | ch = g.softcnt 50 | for { 51 | cl = g.st.LoadCOUNTER() 52 | ch1 := g.softcnt 53 | if ch1 == ch { 54 | return 55 | } 56 | ch = ch1 57 | } 58 | } 59 | 60 | func nanotime() int64 { 61 | ch, cl := counters() 62 | // exact and efficient calculation of: (ch<<24+cl)*1e9*(prescaler+1)/32768. 63 | scale := int64(g.scale) 64 | h := int64(ch) * scale << (24 - (15 - 9)) 65 | l := int64(cl) * scale >> (15 - 9) 66 | return h + l 67 | } 68 | 69 | func ticks(ch, cl uint32) int64 { 70 | return int64(ch)<<24 | int64(cl) 71 | } 72 | 73 | func setAlarm(ns int64) { 74 | cce := cce() 75 | if ns < 0 { 76 | cce.DisableIRQ() 77 | return 78 | } 79 | if g.wakens == ns { 80 | return 81 | } 82 | g.wakens = ns 83 | scale := int64(g.scale) 84 | wkup := (ns<<(15-9) + scale - 1) / scale // round up, don't wake too early 85 | cce.Clear() 86 | ch, cl := counters() 87 | now := ticks(ch, cl) 88 | sleep := wkup - now 89 | switch { 90 | case sleep > 0xffffff: 91 | g.st.StoreCC(int(g.ccn), cl) 92 | case sleep > 0: 93 | g.st.StoreCC(int(g.ccn), uint32(wkup)&0xffffff) 94 | now = ticks(counters()) 95 | } 96 | if now < wkup { 97 | cce.EnableIRQ() 98 | } else { 99 | // wkup in the past or there is a chance that CC was set to late. 100 | g.wakens = 0 101 | schedule() 102 | } 103 | } 104 | 105 | func ISR() { 106 | ove := g.st.Event(rtc.OVRFLW) 107 | cce := cce() 108 | if ove.IsSet() { 109 | ove.Clear() 110 | g.softcnt++ 111 | } 112 | if cce.IsSet() { 113 | cce.DisableIRQ() 114 | g.wakens = 0 115 | schedule() 116 | } 117 | } 118 | 119 | func schedule() 120 | -------------------------------------------------------------------------------- /hal/te/chan.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package te 6 | 7 | import "github.com/embeddedgo/nrf5/hal/internal" 8 | 9 | // NumChan is the number of channels available to the application. It does not 10 | // include pre-programmed channels. 11 | const NumChan = numChan 12 | 13 | // Chan represents PPI/DPPI channel. 14 | type Chan int8 15 | 16 | var unusedChannels uint32 = 1<> 12 & 0x1FF) 91 | } 92 | -------------------------------------------------------------------------------- /hal/te/task.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package te 6 | 7 | import "embedded/mmio" 8 | 9 | // Task represents a peripheral register that is used to trigger events. 10 | type Task struct { 11 | u32 mmio.U32 12 | } 13 | 14 | // Trig starts action corresponding to task. 15 | func (r *Task) Trig() { 16 | r.u32.Store(1) 17 | } 18 | 19 | // Chan returns the PPI/DPPI channel the task is connected to and reports 20 | // whether subscription of events on this channel is enabled. In case of nRF52- 21 | // which PPI peripheral allows to connect task to multiple PPI channels Chan 22 | // returns the first channel found. 23 | func (r *Task) Chan() (c Chan, en bool) { 24 | return getTaskChan(r) 25 | } 26 | 27 | // SetChan connects the task to the PPI/DPPI channel. En allows to enable or 28 | // disable subscription of events on connected channel. 29 | // 30 | // SetChan allows to write portable code that can work with PPI (nRF52-) and 31 | // DPPI (nRF53) but has some limitations in case of PPI: 32 | // 33 | // - you can connect only up to two tasks to the same channel, 34 | // 35 | // - if en is false the channel is set to -1 which as a result disconnects the 36 | // task from all channels. 37 | // 38 | // The one advantage of PPI over DPPI is ablility to conect one task to multiple 39 | // channels. If you need this feature use SetTEP from ppi package. 40 | func (r *Task) SetChan(c Chan, en bool) { 41 | setTaskChan(r, c, en) 42 | } 43 | -------------------------------------------------------------------------------- /hal/timer/nrf52.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build nrf52832 nrf52833 nrf52840 6 | 7 | package timer 8 | 9 | import ( 10 | "unsafe" 11 | 12 | "github.com/embeddedgo/nrf5/p/mmap" 13 | ) 14 | 15 | func timer(n int) *Periph { 16 | switch { 17 | case uint(n) > 4: 18 | return nil 19 | case n <= 2: 20 | return (*Periph)(unsafe.Pointer(mmap.TIMER0_BASE + uintptr(n)*0x1000)) 21 | default: 22 | return (*Periph)(unsafe.Pointer(mmap.TIMER3_BASE + uintptr(n-3)*0x1000)) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /hal/timer/periph.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package timer provides interface to manage nRF5 timers. 6 | package timer 7 | 8 | import ( 9 | "embedded/mmio" 10 | 11 | "github.com/embeddedgo/nrf5/hal/te" 12 | ) 13 | 14 | // Periph represents timer/counter peripheral. 15 | type Periph struct { 16 | te.Regs 17 | 18 | _ [65]uint32 19 | mode mmio.U32 // timer mode selection 20 | bitmode mmio.U32 // number of bits used 21 | _ uint32 22 | prescaler mmio.U32 23 | _ [11]uint32 24 | cc [6]mmio.U32 // capture/compare registers. 25 | } 26 | 27 | // TIMER returns n-th instance of TIMER peripheral or nil if this instance is 28 | // not implemented. 29 | func TIMER(n int) *Periph { return timer(n) } 30 | 31 | type Task byte 32 | 33 | const ( 34 | START Task = 0 // Start Timer. 35 | STOP Task = 1 // Stop Timer. 36 | COUNT Task = 2 // Increment Timer (Counter mode only). 37 | CLEAR Task = 3 // Clear timer. 38 | ) 39 | 40 | // CAPTURE returns Capture task for CCn register. 41 | func CAPTURE(n int) Task { 42 | return Task(16 + n) 43 | } 44 | 45 | type Event byte 46 | 47 | // COMPARE returns Compare event for CCn register. 48 | func COMPARE(n int) Event { 49 | return Event(16 + n) 50 | } 51 | 52 | func (p *Periph) Task(t Task) *te.Task { return p.Regs.Task(int(t)) } 53 | func (p *Periph) Event(e Event) *te.Event { return p.Regs.Event(int(e)) } 54 | 55 | type Shorts uint32 56 | 57 | const ( 58 | COMPARE0_CLEAR Shorts = 1 << 0 59 | COMPARE1_CLEAR Shorts = 1 << 1 60 | COMPARE2_CLEAR Shorts = 1 << 2 61 | COMPARE3_CLEAR Shorts = 1 << 3 62 | COMPARE4_CLEAR Shorts = 1 << 4 63 | COMPARE5_CLEAR Shorts = 1 << 5 64 | COMPARE0_STOP Shorts = 1 << 8 65 | COMPARE1_STOP Shorts = 1 << 9 66 | COMPARE2_STOP Shorts = 1 << 10 67 | COMPARE3_STOP Shorts = 1 << 11 68 | COMPARE4_STOP Shorts = 1 << 12 69 | COMPARE5_STOP Shorts = 1 << 13 70 | ) 71 | 72 | func (p *Periph) LoadSHORTS() Shorts { return Shorts(p.Regs.LoadSHORTS()) } 73 | func (p *Periph) StoreSHORTS(s Shorts) { p.Regs.StoreSHORTS(uint32(s)) } 74 | 75 | type Mode uint8 76 | 77 | const ( 78 | Timer Mode = 0 79 | Counter Mode = 1 80 | LowPowerCounter Mode = 2 81 | ) 82 | 83 | func (p *Periph) LoadMODE() Mode { 84 | return Mode(p.mode.Load()) 85 | } 86 | 87 | func (p *Periph) StoreMODE(m Mode) { 88 | p.mode.Store(uint32(m)) 89 | } 90 | 91 | type Bitmode uint8 92 | 93 | const ( 94 | Bit8 Bitmode = 1 95 | Bit16 Bitmode = 0 96 | Bit24 Bitmode = 2 97 | Bit32 Bitmode = 3 98 | ) 99 | 100 | func (p *Periph) LoadBITMODE() Bitmode { 101 | return Bitmode(p.bitmode.Load()) 102 | } 103 | 104 | func (p *Periph) StoreBITMODE(m Bitmode) { 105 | p.bitmode.Store(uint32(m)) 106 | } 107 | 108 | func (p *Periph) LoadPRESCALER() int { 109 | return int(p.prescaler.Load()) 110 | } 111 | 112 | // StorePRESCALER sets prescaler to exp (freq = 16MHz/2^exp). Must only be used 113 | // when the timer is stopped. 114 | func (p *Periph) StorePRESCALER(exp int) { 115 | p.prescaler.Store(uint32(exp)) 116 | } 117 | 118 | // LoadCC returns value of n-th Capture/Compare register. nRF51/nRF52 has 4/6 CC 119 | // registers 120 | func (p *Periph) LoadCC(n int) uint32 { 121 | return p.cc[n].Load() 122 | } 123 | 124 | // StoreCC stores cc into n-th Capture/Compare register. nRF51/nRF52 has 4/6 CC 125 | // registers 126 | func (p *Periph) StoreCC(n int, cc uint32) { 127 | p.cc[n].Store(cc) 128 | } 129 | -------------------------------------------------------------------------------- /hal/todo/power/regs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build ignore 6 | 7 | // Package power provides interface to the power managemnt peripheral. 8 | package power 9 | 10 | import ( 11 | "embedded/mmio" 12 | "embedded/rtos" 13 | "unsafe" 14 | 15 | "github.com/embeddedgo/nrf5/hal/te" 16 | "github.com/embeddedgo/nrf5/p/mmap" 17 | ) 18 | 19 | type regs struct { 20 | te.Regs 21 | 22 | resetreas mmio.U32 // 0x400 23 | _ [9]mmio.U32 // 24 | ramstatus mmio.U32 // 0x428 25 | _ [53]mmio.U32 // 26 | systemoff mmio.U32 // 0x500 27 | _ [3]mmio.U32 // 28 | pofcon mmio.U32 // 0x510 29 | _ [2]mmio.U32 // 30 | gpregret [2]mmio.U32 // 0x51C 31 | ramon mmio.U32 // 0x524 32 | _ [7]mmio.U32 // 33 | reset mmio.U32 // 0x544 34 | _ [3]mmio.U32 // 35 | ramonb mmio.U32 // 0x554 36 | _ [8]mmio.U32 // 37 | dcdcen mmio.U32 // 0x578 38 | _ [225]mmio.U32 39 | ram [8]struct{ power, powerset, powerclr mmio.U32 } 40 | } 41 | 42 | func r() *regs { return (*regs)(unsafe.Pointer(mmap.POWER_BASE)) } 43 | 44 | // IRQEnabled returns EventMask that lists events that have enabled 45 | // generating interrupts.. 46 | func IRQEnabled() te.EventMask { 47 | return r().IRQEnabled() 48 | } 49 | 50 | // EnableIRQ enables generating interrupts by events specified by mask. 51 | func EnableIRQ(mask te.EventMask) { 52 | r().EnableIRQ(mask) 53 | } 54 | 55 | // DisableIRQ disables generating interrupts by events specified by mask 56 | func DisableIRQ(mask te.EventMask) { 57 | r().DisableIRQ(mask) 58 | } 59 | 60 | // IRQ returns the IRQ number in NVIC associated to the peripheral. 61 | func IRQ() rtos.IRQ { 62 | return r().IRQ() 63 | } 64 | -------------------------------------------------------------------------------- /hal/todo/radio/doc.go: -------------------------------------------------------------------------------- 1 | // Package radio provides interface to universal 2.4 GHz radio peripheral that 2 | // supports Bluetooth LE (Smart) and other protocols. 3 | package radio -------------------------------------------------------------------------------- /hal/todo/temp/periph.go: -------------------------------------------------------------------------------- 1 | //go:build ignore 2 | 3 | package temp 4 | 5 | import ( 6 | "mmio" 7 | "unsafe" 8 | 9 | "nrf5/hal/internal/mmap" 10 | "nrf5/hal/te" 11 | ) 12 | 13 | type Periph struct { 14 | te.Regs 15 | 16 | _ [66]mmio.U32 17 | temp mmio.U32 18 | _ [5]mmio.U32 19 | a [6]mmio.U32 20 | _ [2]mmio.U32 21 | b [6]mmio.U32 22 | _ [2]mmio.U32 23 | t [5]mmio.U32 24 | } 25 | 26 | //emgo:const 27 | var TEMP = (*Periph)(unsafe.Pointer(mmap.APB_BASE + 0x0C000)) 28 | 29 | type Task byte 30 | 31 | const ( 32 | START Task = 0 // Start temperature measurement. 33 | STOP Task = 1 // Stop temperature measurement. 34 | ) 35 | 36 | type Event byte 37 | 38 | const ( 39 | DATARDY Event = 0 // Temperature measurement complete, data ready. 40 | ) 41 | 42 | func (p *Periph) Task(t Task) *te.Task { return p.Regs.Task(int(t)) } 43 | func (p *Periph) Event(e Event) *te.Event { return p.Regs.Event(int(e)) } 44 | 45 | // LoadTEMP returns temperature (in 0.25 °C units) mesured by last START task. 46 | func (p *Periph) LoadTEMP() int { 47 | return int(p.temp.Load()) 48 | } 49 | 50 | func (p *Periph) A() []mmio.U32 { 51 | return p.a[:] 52 | } 53 | 54 | func (p *Periph) B() []mmio.U32 { 55 | return p.b[:] 56 | } 57 | 58 | func (p *Periph) T() []mmio.U32 { 59 | return p.t[:] 60 | } 61 | -------------------------------------------------------------------------------- /hal/uart/uart0/driver.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uart0 6 | 7 | import ( 8 | "embedded/rtos" 9 | _ "unsafe" 10 | 11 | "github.com/embeddedgo/nrf5/hal/uart" 12 | ) 13 | 14 | var driver *uart.Driver 15 | 16 | // Driver returns ready to use driver for UART. 17 | func Driver() *uart.Driver { 18 | if driver == nil { 19 | driver = uart.NewDriver(uart.UART(0)) 20 | driver.IRQ().Enable(rtos.IntPrioLow, 0) 21 | } 22 | return driver 23 | } 24 | 25 | //go:interrupthandler 26 | func _UARTE0_UART0_Handler() { driver.ISR() } 27 | 28 | //go:linkname _UARTE0_UART0_Handler IRQ2_Handler 29 | -------------------------------------------------------------------------------- /hal/uarte/driver.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uarte 6 | 7 | import ( 8 | "embedded/rtos" 9 | "time" 10 | "unsafe" 11 | 12 | "github.com/embeddedgo/nrf5/hal/gpio" 13 | ) 14 | 15 | type Driver struct { 16 | p *Periph 17 | 18 | // tx state 19 | txdone rtos.Note 20 | 21 | timeoutRx time.Duration 22 | timeoutTx time.Duration 23 | } 24 | 25 | // NewDriver returns a new driver for p. 26 | func NewDriver(p *Periph) *Driver { 27 | return &Driver{p: p, timeoutRx: -1, timeoutTx: -1} 28 | } 29 | 30 | func (d *Driver) Periph() *Periph { 31 | return d.p 32 | } 33 | 34 | // Enable enables UART peripheral. 35 | func (d *Driver) Enable() { 36 | p := d.p 37 | p.StoreENABLE(true) 38 | p.Event(ENDTX).Clear() 39 | p.EnableIRQ(1 << ENDTX) 40 | } 41 | 42 | // Disable disables UART peripheral. 43 | func (d *Driver) Disable() { 44 | d.p.DisableIRQ(1 << ENDTX) 45 | d.p.StoreENABLE(false) 46 | } 47 | 48 | // UsePin configurs the specified pin to be used as signal s. 49 | func (d *Driver) UsePin(pin gpio.Pin, s Signal) { 50 | switch s { 51 | case TXD, RTSn: 52 | pin.Set() 53 | pin.Setup(gpio.ModeOut) 54 | default: 55 | pin.Setup(gpio.ModeIn) 56 | } 57 | d.p.StorePSEL(s, pin.PSEL(), true) 58 | } 59 | 60 | // SetBaudrate sets Tx and Rx baudrate. 61 | func (d *Driver) SetBaudrate(br Baudrate) { 62 | d.p.StoreBAUDRATE(br) 63 | } 64 | 65 | // SetConfig allows to configure UART peripheral to use hardware flow controll, 66 | // add and check parity bit, and use two stop bits instead default one. 67 | func (d *Driver) SetConfig(cfg Config) { 68 | d.p.StoreCONFIG(cfg) 69 | } 70 | 71 | // IRQ returns the interrupt assigned to UART peripheral used by driver. 72 | func (d *Driver) IRQ() rtos.IRQ { 73 | return d.p.IRQ() 74 | } 75 | 76 | func (d *Driver) ISR() { 77 | p := d.p 78 | if endtx := p.Event(ENDTX); endtx.IsSet() { 79 | endtx.Clear() 80 | d.txdone.Wakeup() 81 | } 82 | } 83 | 84 | func (d *Driver) WriteByte(b byte) (err error) { 85 | d.txdone.Clear() 86 | p := d.p 87 | p.StoreTXDPTR(unsafe.Pointer(&b)) 88 | p.StoreTXDMAXCNT(1) 89 | p.Task(STARTTX).Trig() 90 | if !d.txdone.Sleep(d.timeoutTx) { 91 | err = ErrTimeout 92 | } 93 | p.Task(STOPTX).Trig() 94 | return 95 | } 96 | 97 | func (d *Driver) Write(s []byte) (n int, err error) { 98 | if len(s) == 0 { 99 | return 0, nil 100 | } 101 | d.txdone.Clear() 102 | p := d.p 103 | p.StoreTXDPTR(unsafe.Pointer(&s[0])) 104 | p.StoreTXDMAXCNT(len(s)) 105 | p.Task(STARTTX).Trig() 106 | if !d.txdone.Sleep(d.timeoutTx) { 107 | err = ErrTimeout 108 | } 109 | p.Task(STOPTX).Trig() 110 | return p.LoadTXDAMOUNT(), err 111 | } 112 | 113 | type DriverError uint8 114 | 115 | const ( 116 | // ErrBufOverflow is returned if one or more received bytes has been dropped 117 | // because of the lack of free space in the driver's receive buffer. 118 | ErrBufOverflow DriverError = iota + 1 119 | 120 | // ErrTimeout is returned if timeout occured. It means that the read/write 121 | // operation has been interrupted. In case of write you can not determine 122 | // the exact number of bytes sent to the remote party. 123 | ErrTimeout 124 | ) 125 | 126 | // Error implements error interface. 127 | func (e DriverError) Error() string { 128 | switch e { 129 | case ErrBufOverflow: 130 | return "uarte: buffer overflow" 131 | case ErrTimeout: 132 | return "uarte: timeout" 133 | } 134 | return "" 135 | } 136 | -------------------------------------------------------------------------------- /hal/uarte/uarte0/driver.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uarte0 6 | 7 | import ( 8 | "embedded/rtos" 9 | _ "unsafe" 10 | 11 | "github.com/embeddedgo/nrf5/hal/uarte" 12 | ) 13 | 14 | var driver *uarte.Driver 15 | 16 | // Driver returns ready to use driver for UART. 17 | func Driver() *uarte.Driver { 18 | if driver == nil { 19 | driver = uarte.NewDriver(uarte.UARTE(0)) 20 | driver.IRQ().Enable(rtos.IntPrioLow, 0) 21 | } 22 | return driver 23 | } 24 | 25 | //go:interrupthandler 26 | func _UARTE0_UART0_Handler() { driver.ISR() } 27 | 28 | //go:linkname _UARTE0_UART0_Handler IRQ2_Handler 29 | -------------------------------------------------------------------------------- /hal/uarte/uarte1/driver.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uarte1 6 | 7 | import ( 8 | "embedded/rtos" 9 | _ "unsafe" 10 | 11 | "github.com/embeddedgo/nrf5/hal/uarte" 12 | ) 13 | 14 | var driver *uarte.Driver 15 | 16 | // Driver returns ready to use driver for UART. 17 | func Driver() *uarte.Driver { 18 | if driver == nil { 19 | driver = uarte.NewDriver(uarte.UARTE(1)) 20 | driver.IRQ().Enable(rtos.IntPrioLow, 0) 21 | } 22 | return driver 23 | } 24 | 25 | //go:interrupthandler 26 | func _UARTE1_Handler() { driver.ISR() } 27 | 28 | //go:linkname _UARTE1_Handler IRQ40_Handler 29 | -------------------------------------------------------------------------------- /p/gpio/nrf52840.go: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE. GENERATED BY svdxgen. 2 | 3 | //go:build nrf52840 4 | 5 | // Package gpio provides access to the registers of the P peripheral. 6 | // 7 | // Instances: 8 | // 9 | // P0 P0_BASE - - GPIO Port 1 10 | // P1 P1_BASE - - GPIO Port 2 11 | // 12 | // Registers: 13 | // 14 | // 0x504 32 OUT Write GPIO port 15 | // 0x508 32 OUTSET Set individual bits in GPIO port 16 | // 0x50C 32 OUTCLR Clear individual bits in GPIO port 17 | // 0x510 32 IN Read GPIO port 18 | // 0x514 32 DIR Direction of GPIO pins 19 | // 0x518 32 DIRSET DIR set register 20 | // 0x51C 32 DIRCLR DIR clear register 21 | // 0x520 32 LATCH Latch register indicating what GPIO pins that have met the criteria set in the PIN_CNF[n].SENSE registers 22 | // 0x524 32 DETECTMODE Select between default DETECT signal behaviour and LDETECT mode 23 | // 0x700 32 PIN_CNF[32] Configuration of GPIO pins 24 | // 25 | // Import: 26 | // 27 | // github.com/embeddedgo/nrf5/p/mmap 28 | package gpio 29 | 30 | const ( 31 | DETECT DETECTMODE = 0x01 << 0 //+ Select between default DETECT signal behaviour and LDETECT mode 32 | ) 33 | 34 | const ( 35 | DETECTn = 0 36 | ) 37 | 38 | const ( 39 | DIRECTION PIN_CNF = 0x01 << 0 //+ Pin direction. Same physical register as DIR register 40 | INPUT PIN_CNF = 0x01 << 1 //+ Connect or disconnect input buffer 41 | PULL PIN_CNF = 0x03 << 2 //+ Pull configuration 42 | NoPull PIN_CNF = 0x00 << 2 // No pull 43 | Pulldown PIN_CNF = 0x01 << 2 // Pull down on pin 44 | Pullup PIN_CNF = 0x03 << 2 // Pull up on pin 45 | DRIVE PIN_CNF = 0x07 << 8 //+ Drive configuration 46 | S0S1 PIN_CNF = 0x00 << 8 // Standard '0', standard '1' 47 | H0S1 PIN_CNF = 0x01 << 8 // High drive '0', standard '1' 48 | S0H1 PIN_CNF = 0x02 << 8 // Standard '0', high drive '1' 49 | H0H1 PIN_CNF = 0x03 << 8 // High drive '0', high 'drive '1'' 50 | D0S1 PIN_CNF = 0x04 << 8 // Disconnect '0' standard '1' (normally used for wired-or connections) 51 | D0H1 PIN_CNF = 0x05 << 8 // Disconnect '0', high drive '1' (normally used for wired-or connections) 52 | S0D1 PIN_CNF = 0x06 << 8 // Standard '0'. disconnect '1' (normally used for wired-and connections) 53 | H0D1 PIN_CNF = 0x07 << 8 // High drive '0', disconnect '1' (normally used for wired-and connections) 54 | SENSE PIN_CNF = 0x03 << 16 //+ Pin sensing mechanism 55 | Disabled PIN_CNF = 0x00 << 16 // Disabled 56 | High PIN_CNF = 0x02 << 16 // Sense for high level 57 | Low PIN_CNF = 0x03 << 16 // Sense for low level 58 | ) 59 | 60 | const ( 61 | DIRECTIONn = 0 62 | INPUTn = 1 63 | PULLn = 2 64 | DRIVEn = 8 65 | SENSEn = 16 66 | ) 67 | -------------------------------------------------------------------------------- /p/irq/nrf52840.go: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE. GENERATED BY svdxgen. 2 | 3 | //go:build nrf52840 4 | 5 | // Package irq provides the list of supported external interrupts. 6 | package irq 7 | 8 | const ( 9 | POWER_CLOCK = 0 10 | RADIO = 1 11 | UARTE0_UART0 = 2 12 | SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 = 3 13 | SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1 = 4 14 | NFCT = 5 15 | GPIOTE = 6 16 | SAADC = 7 17 | TIMER0 = 8 18 | TIMER1 = 9 19 | TIMER2 = 10 20 | RTC0 = 11 21 | TEMP = 12 22 | RNG = 13 23 | ECB = 14 24 | CCM_AAR = 15 25 | WDT = 16 26 | RTC1 = 17 27 | QDEC = 18 28 | COMP_LPCOMP = 19 29 | SWI0_EGU0 = 20 30 | SWI1_EGU1 = 21 31 | SWI2_EGU2 = 22 32 | SWI3_EGU3 = 23 33 | SWI4_EGU4 = 24 34 | SWI5_EGU5 = 25 35 | TIMER3 = 26 36 | TIMER4 = 27 37 | PWM0 = 28 38 | PDM = 29 39 | MWU = 32 40 | PWM1 = 33 41 | PWM2 = 34 42 | SPIM2_SPIS2_SPI2 = 35 43 | RTC2 = 36 44 | I2S = 37 45 | FPU = 38 46 | USBD = 39 47 | UARTE1 = 40 48 | QSPI = 41 49 | CRYPTOCELL = 42 50 | PWM3 = 45 51 | SPIM3 = 47 52 | ) 53 | -------------------------------------------------------------------------------- /p/nvmc/nrf52840.go: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE. GENERATED BY svdxgen. 2 | 3 | //go:build nrf52840 4 | 5 | // Package nvmc provides access to the registers of the NVMC peripheral. 6 | // 7 | // Instances: 8 | // 9 | // NVMC NVMC_BASE - - Non Volatile Memory Controller 10 | // 11 | // Registers: 12 | // 13 | // 0x400 32 READY Ready flag 14 | // 0x408 32 READYNEXT Ready flag 15 | // 0x504 32 CONFIG Configuration register 16 | // 0x508 32 ERASEPAGE Register for erasing a page in code area 17 | // 0x50C 32 ERASEALL Register for erasing all non-volatile user memory 18 | // 0x510 32 ERASEPCR0 Deprecated register - Register for erasing a page in code area. Equivalent to ERASEPAGE. 19 | // 0x514 32 ERASEUICR Register for erasing user information configuration registers 20 | // 0x518 32 ERASEPAGEPARTIAL Register for partial erase of a page in code area 21 | // 0x51C 32 ERASEPAGEPARTIALCFG Register for partial erase configuration 22 | // 0x540 32 ICACHECNF I-code cache configuration register. 23 | // 0x548 32 IHIT I-code cache hit counter. 24 | // 0x54C 32 IMISS I-code cache miss counter. 25 | // 26 | // Import: 27 | // 28 | // github.com/embeddedgo/nrf5/p/mmap 29 | package nvmc 30 | 31 | const ( 32 | WEN CONFIG = 0x03 << 0 //+ Program memory access mode. It is strongly recommended to only activate erase and write modes when they are actively used. Enabling write or erase will invalidate the cache and keep it invalidated. 33 | Ren CONFIG = 0x00 << 0 // Read only access 34 | Wen CONFIG = 0x01 << 0 // Write enabled 35 | Een CONFIG = 0x02 << 0 // Erase enabled 36 | ) 37 | 38 | const ( 39 | WENn = 0 40 | ) 41 | 42 | const ( 43 | DURATION ERASEPAGEPARTIALCFG = 0x7F << 0 //+ Duration of the partial erase in milliseconds 44 | ) 45 | 46 | const ( 47 | DURATIONn = 0 48 | ) 49 | 50 | const ( 51 | CACHEEN ICACHECNF = 0x01 << 0 //+ Cache enable 52 | CACHEPROFEN ICACHECNF = 0x01 << 8 //+ Cache profiling enable 53 | ) 54 | 55 | const ( 56 | CACHEENn = 0 57 | CACHEPROFENn = 8 58 | ) 59 | -------------------------------------------------------------------------------- /p/ppi/nrf52840.go: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE. GENERATED BY svdxgen. 2 | 3 | //go:build nrf52840 4 | 5 | // Package ppi provides access to the registers of the PPI peripheral. 6 | // 7 | // Instances: 8 | // 9 | // PPI PPI_BASE - - Programmable Peripheral Interconnect 10 | // 11 | // Registers: 12 | // 13 | // 0x000 32 TASK_CHG{EN,DIS}[6] Enable channel group n; Disable channel group n 14 | // 0x500 32 CHEN Channel enable register 15 | // 0x504 32 CHENSET Channel enable set register 16 | // 0x508 32 CHENCLR Channel enable clear register 17 | // 0x510 32 CH{EEP,TEP}[20] Channel n event end-point; Channel n task end-point 18 | // 0x800 32 CHG[6] Channel group n 19 | // 0x910 32 FORK_TEP[32] Channel n task end-point 20 | // 21 | // Import: 22 | // 23 | // github.com/embeddedgo/nrf5/p/mmap 24 | package ppi 25 | -------------------------------------------------------------------------------- /p/rtc/nrf52840.go: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE. GENERATED BY svdxgen. 2 | 3 | //go:build nrf52840 4 | 5 | // Package rtc provides access to the registers of the RTC peripheral. 6 | // 7 | // Instances: 8 | // 9 | // RTC0 RTC0_BASE - RTC0 Real time counter 0 10 | // RTC1 RTC1_BASE - RTC1 Real time counter 1 11 | // RTC2 RTC2_BASE - RTC2 Real time counter 2 12 | // 13 | // Registers: 14 | // 15 | // 0x000 32 TASK_START Start RTC COUNTER 16 | // 0x004 32 TASK_STOP Stop RTC COUNTER 17 | // 0x008 32 TASK_CLEAR Clear RTC COUNTER 18 | // 0x00C 32 TASK_TRIGOVRFLW Set COUNTER to 0xFFFFF0 19 | // 0x100 32 EVENT_TICK Event on COUNTER increment 20 | // 0x104 32 EVENT_OVRFLW Event on COUNTER overflow 21 | // 0x140 32 EVENT_COMPARE[4] Compare event on CC[n] match 22 | // 0x304 32 INTENSET Enable interrupt 23 | // 0x308 32 INTENCLR Disable interrupt 24 | // 0x340 32 EVTEN Enable or disable event routing 25 | // 0x344 32 EVTENSET Enable event routing 26 | // 0x348 32 EVTENCLR Disable event routing 27 | // 0x504 32 COUNTER Current COUNTER value 28 | // 0x508 32 PRESCALER 12 bit prescaler for COUNTER frequency (32768/(PRESCALER+1)).Must be written when RTC is stopped 29 | // 0x540 32 CC[4] Compare register n 30 | // 31 | // Import: 32 | // 33 | // github.com/embeddedgo/nrf5/p/mmap 34 | package rtc 35 | -------------------------------------------------------------------------------- /p/spi/nrf52840.go: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE. GENERATED BY svdxgen. 2 | 3 | //go:build nrf52840 4 | 5 | // Package spi provides access to the registers of the SPI peripheral. 6 | // 7 | // Instances: 8 | // 9 | // SPI0 SPI0_BASE - SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0* Serial Peripheral Interface 0 10 | // SPI1 SPI1_BASE - SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1* Serial Peripheral Interface 1 11 | // SPI2 SPI2_BASE - SPIM2_SPIS2_SPI2* Serial Peripheral Interface 2 12 | // 13 | // Registers: 14 | // 15 | // 0x108 32 EVENT_READY TXD byte sent and RXD byte received 16 | // 0x304 32 INTENSET Enable interrupt 17 | // 0x308 32 INTENCLR Disable interrupt 18 | // 0x500 32 ENABLE Enable SPI 19 | // 0x508 32 PSEL_SCK Pin select for SCK 20 | // 0x50C 32 PSEL_MOSI Pin select for MOSI signal 21 | // 0x510 32 PSEL_MISO Pin select for MISO signal 22 | // 0x518 32 RXD RXD register 23 | // 0x51C 32 TXD TXD register 24 | // 0x524 32 FREQUENCY SPI frequency. Accuracy depends on the HFCLK source selected. 25 | // 0x554 32 CONFIG Configuration register 26 | // 27 | // Import: 28 | // 29 | // github.com/embeddedgo/nrf5/p/mmap 30 | package spi 31 | 32 | const ( 33 | EN ENABLE = 0x0F << 0 //+ Enable or disable SPI 34 | Disabled ENABLE = 0x00 << 0 // Disable SPI 35 | Enabled ENABLE = 0x01 << 0 // Enable SPI 36 | ) 37 | 38 | const ( 39 | ENn = 0 40 | ) 41 | 42 | const ( 43 | FREQ FREQUENCY = 0xFFFFFFFF << 0 //+ SPI master data rate 44 | K125 FREQUENCY = 0x2000000 << 0 // 125 kbps 45 | K250 FREQUENCY = 0x4000000 << 0 // 250 kbps 46 | K500 FREQUENCY = 0x8000000 << 0 // 500 kbps 47 | M1 FREQUENCY = 0x10000000 << 0 // 1 Mbps 48 | M2 FREQUENCY = 0x20000000 << 0 // 2 Mbps 49 | M4 FREQUENCY = 0x40000000 << 0 // 4 Mbps 50 | M8 FREQUENCY = 0x80000000 << 0 // 8 Mbps 51 | ) 52 | 53 | const ( 54 | FREQn = 0 55 | ) 56 | 57 | const ( 58 | ORDER CONFIG = 0x01 << 0 //+ Bit order 59 | CPHA CONFIG = 0x01 << 1 //+ Serial clock (SCK) phase 60 | CPOL CONFIG = 0x01 << 2 //+ Serial clock (SCK) polarity 61 | ) 62 | 63 | const ( 64 | ORDERn = 0 65 | CPHAn = 1 66 | CPOLn = 2 67 | ) 68 | -------------------------------------------------------------------------------- /p/uart/nrf52840.go: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE. GENERATED BY svdxgen. 2 | 3 | //go:build nrf52840 4 | 5 | // Package uart provides access to the registers of the UART peripheral. 6 | // 7 | // Instances: 8 | // 9 | // UART0 UART0_BASE - UARTE0_UART0* Universal Asynchronous Receiver/Transmitter 10 | // 11 | // Registers: 12 | // 13 | // 0x000 32 TASK_STARTRX Start UART receiver 14 | // 0x004 32 TASK_STOPRX Stop UART receiver 15 | // 0x008 32 TASK_STARTTX Start UART transmitter 16 | // 0x00C 32 TASK_STOPTX Stop UART transmitter 17 | // 0x01C 32 TASK_SUSPEND Suspend UART 18 | // 0x100 32 EVENT_CTS CTS is activated (set low). Clear To Send. 19 | // 0x104 32 EVENT_NCTS CTS is deactivated (set high). Not Clear To Send. 20 | // 0x108 32 EVENT_RXDRDY Data received in RXD 21 | // 0x11C 32 EVENT_TXDRDY Data sent from TXD 22 | // 0x124 32 EVENT_ERROR Error detected 23 | // 0x144 32 EVENT_RXTO Receiver timeout 24 | // 0x200 32 SHORTS Shortcuts between local events and tasks 25 | // 0x304 32 INTENSET Enable interrupt 26 | // 0x308 32 INTENCLR Disable interrupt 27 | // 0x480 32 ERRORSRC Error source 28 | // 0x500 32 ENABLE Enable UART 29 | // 0x508 32 PSEL_RTS Pin select for RTS 30 | // 0x50C 32 PSEL_TXD Pin select for TXD 31 | // 0x510 32 PSEL_CTS Pin select for CTS 32 | // 0x514 32 PSEL_RXD Pin select for RXD 33 | // 0x518 32 RXD RXD register 34 | // 0x51C 32 TXD TXD register 35 | // 0x524 32 BAUDRATE Baud rate. Accuracy depends on the HFCLK source selected. 36 | // 0x56C 32 CONFIG Configuration of parity and hardware flow control 37 | // 38 | // Import: 39 | // 40 | // github.com/embeddedgo/nrf5/p/mmap 41 | package uart 42 | 43 | const ( 44 | CTS_STARTRX SHORTS = 0x01 << 3 //+ Shortcut between event CTS and task STARTRX 45 | NCTS_STOPRX SHORTS = 0x01 << 4 //+ Shortcut between event NCTS and task STOPRX 46 | ) 47 | 48 | const ( 49 | CTS_STARTRXn = 3 50 | NCTS_STOPRXn = 4 51 | ) 52 | 53 | const ( 54 | EOVERRUN ERRORSRC = 0x01 << 0 //+ Overrun error 55 | EPARITY ERRORSRC = 0x01 << 1 //+ Parity error 56 | EFRAMING ERRORSRC = 0x01 << 2 //+ Framing error occurred 57 | EBREAK ERRORSRC = 0x01 << 3 //+ Break condition 58 | ) 59 | 60 | const ( 61 | EOVERRUNn = 0 62 | EPARITYn = 1 63 | EFRAMINGn = 2 64 | EBREAKn = 3 65 | ) 66 | 67 | const ( 68 | EN ENABLE = 0x0F << 0 //+ Enable or disable UART 69 | Disabled ENABLE = 0x00 << 0 // Disable UART 70 | Enabled ENABLE = 0x04 << 0 // Enable UART 71 | ) 72 | 73 | const ( 74 | ENn = 0 75 | ) 76 | 77 | const ( 78 | BR BAUDRATE = 0xFFFFFFFF << 0 //+ Baud rate 79 | Baud1200 BAUDRATE = 0x4F000 << 0 // 1200 baud (actual rate: 1205) 80 | Baud2400 BAUDRATE = 0x9D000 << 0 // 2400 baud (actual rate: 2396) 81 | Baud4800 BAUDRATE = 0x13B000 << 0 // 4800 baud (actual rate: 4808) 82 | Baud9600 BAUDRATE = 0x275000 << 0 // 9600 baud (actual rate: 9598) 83 | Baud14400 BAUDRATE = 0x3B0000 << 0 // 14400 baud (actual rate: 14414) 84 | Baud19200 BAUDRATE = 0x4EA000 << 0 // 19200 baud (actual rate: 19208) 85 | Baud28800 BAUDRATE = 0x75F000 << 0 // 28800 baud (actual rate: 28829) 86 | Baud31250 BAUDRATE = 0x800000 << 0 // 31250 baud 87 | Baud38400 BAUDRATE = 0x9D5000 << 0 // 38400 baud (actual rate: 38462) 88 | Baud56000 BAUDRATE = 0xE50000 << 0 // 56000 baud (actual rate: 55944) 89 | Baud57600 BAUDRATE = 0xEBF000 << 0 // 57600 baud (actual rate: 57762) 90 | Baud76800 BAUDRATE = 0x13A9000 << 0 // 76800 baud (actual rate: 76923) 91 | Baud115200 BAUDRATE = 0x1D7E000 << 0 // 115200 baud (actual rate: 115942) 92 | Baud230400 BAUDRATE = 0x3AFB000 << 0 // 230400 baud (actual rate: 231884) 93 | Baud250000 BAUDRATE = 0x4000000 << 0 // 250000 baud 94 | Baud460800 BAUDRATE = 0x75F7000 << 0 // 460800 baud (actual rate: 470588) 95 | Baud921600 BAUDRATE = 0xEBED000 << 0 // 921600 baud (actual rate: 941176) 96 | Baud1M BAUDRATE = 0x10000000 << 0 // 1Mega baud 97 | ) 98 | 99 | const ( 100 | BRn = 0 101 | ) 102 | 103 | const ( 104 | HWFC CONFIG = 0x01 << 0 //+ Hardware flow control 105 | PARITY CONFIG = 0x07 << 1 //+ Parity 106 | Excluded CONFIG = 0x00 << 1 // Exclude parity bit 107 | Included CONFIG = 0x07 << 1 // Include parity bit 108 | STOP CONFIG = 0x01 << 4 //+ Stop bits 109 | ) 110 | 111 | const ( 112 | HWFCn = 0 113 | PARITYn = 1 114 | STOPn = 4 115 | ) 116 | -------------------------------------------------------------------------------- /p/uicr/nrf52840.go: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE. GENERATED BY svdxgen. 2 | 3 | //go:build nrf52840 4 | 5 | // Package uicr provides access to the registers of the UICR peripheral. 6 | // 7 | // Instances: 8 | // 9 | // UICR UICR_BASE - - User information configuration registers 10 | // 11 | // Registers: 12 | // 13 | // 0x014 32 NRFFW[15] Reserved for Nordic firmware design 14 | // 0x050 32 NRFHW[12] Reserved for Nordic hardware design 15 | // 0x080 32 CUSTOMER[32] Reserved for customer 16 | // 0x200 32 PSELRESET[2] Mapping of the nRESET function (see POWER chapter for details) 17 | // 0x208 32 APPROTECT Access port protection 18 | // 0x20C 32 NFCPINS Setting of pins dedicated to NFC functionality: NFC antenna or GPIO 19 | // 0x210 32 DEBUGCTRL Processor debug control 20 | // 0x304 32 REGOUT0 GPIO reference voltage / external output supply voltage in high voltage mode 21 | // 22 | // Import: 23 | // 24 | // github.com/embeddedgo/nrf5/p/mmap 25 | package uicr 26 | 27 | const ( 28 | PIN PSELRESET = 0x1F << 0 //+ GPIO pin number onto which nRESET is exposed 29 | PORT PSELRESET = 0x01 << 5 //+ Port number onto which nRESET is exposed 30 | CONNECT PSELRESET = 0x01 << 31 //+ Connection 31 | ) 32 | 33 | const ( 34 | PINn = 0 35 | PORTn = 5 36 | CONNECTn = 31 37 | ) 38 | 39 | const ( 40 | PALL APPROTECT = 0xFF << 0 //+ Enable or disable access port protection. 41 | Enabled APPROTECT = 0x00 << 0 // Enable 42 | Disabled APPROTECT = 0xFF << 0 // Disable 43 | ) 44 | 45 | const ( 46 | PALLn = 0 47 | ) 48 | 49 | const ( 50 | PROTECT NFCPINS = 0x01 << 0 //+ Setting of pins dedicated to NFC functionality 51 | ) 52 | 53 | const ( 54 | PROTECTn = 0 55 | ) 56 | 57 | const ( 58 | CPUNIDEN DEBUGCTRL = 0xFF << 0 //+ Configure CPU non-intrusive debug features 59 | IDDisabled DEBUGCTRL = 0x00 << 0 // Disable CPU ITM and ETM functionality 60 | IDEnabled DEBUGCTRL = 0xFF << 0 // Enable CPU ITM and ETM functionality (default behavior) 61 | CPUFPBEN DEBUGCTRL = 0xFF << 8 //+ Configure CPU flash patch and breakpoint (FPB) unit behavior 62 | FPBDisabled DEBUGCTRL = 0x00 << 8 // Disable CPU FPB unit. Writes into the FPB registers will be ignored. 63 | FPBEnabled DEBUGCTRL = 0xFF << 8 // Enable CPU FPB unit (default behavior) 64 | ) 65 | 66 | const ( 67 | CPUNIDENn = 0 68 | CPUFPBENn = 8 69 | ) 70 | 71 | const ( 72 | VOUT REGOUT0 = 0x07 << 0 //+ Output voltage from of REG0 regulator stage. The maximum output voltage from this stage is given as VDDH - VEXDIF. 73 | V1_8 REGOUT0 = 0x00 << 0 // 1.8 V 74 | V2_1 REGOUT0 = 0x01 << 0 // 2.1 V 75 | V2_4 REGOUT0 = 0x02 << 0 // 2.4 V 76 | V2_7 REGOUT0 = 0x03 << 0 // 2.7 V 77 | V3_0 REGOUT0 = 0x04 << 0 // 3.0 V 78 | V3_3 REGOUT0 = 0x05 << 0 // 3.3 V 79 | Vdefault REGOUT0 = 0x07 << 0 // Default voltage: 1.8 V 80 | ) 81 | 82 | const ( 83 | VOUTn = 0 84 | ) 85 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | Support for [nRF52 microcontrollers](https://www.nordicsemi.com/Products/nrF52840). 2 | 3 | Contains examples you can run on [supported develompent boards](devboard). -------------------------------------------------------------------------------- /softdevice/gen/s140/nrf/zerror.go: -------------------------------------------------------------------------------- 1 | // Code generated from ../nordic/s140/headers/nrf_error.h; DO NOT EDIT. 2 | 3 | package nrf 4 | 5 | const ERROR_BASE_NUM = (0x0) // Global error base 6 | const ERROR_SDM_BASE_NUM = (0x1000) // SDM error base 7 | const ERROR_SOC_BASE_NUM = (0x2000) // SoC error base 8 | const ERROR_STK_BASE_NUM = (0x3000) // STK error base 9 | const SUCCESS = (ERROR_BASE_NUM + 0) // Successful command 10 | const ERROR_SVC_HANDLER_MISSING = (ERROR_BASE_NUM + 1) // SVC handler is missing 11 | const ERROR_SOFTDEVICE_NOT_ENABLED = (ERROR_BASE_NUM + 2) // SoftDevice has not been enabled 12 | const ERROR_INTERNAL = (ERROR_BASE_NUM + 3) // Internal Error 13 | const ERROR_NO_MEM = (ERROR_BASE_NUM + 4) // No Memory for operation 14 | const ERROR_NOT_FOUND = (ERROR_BASE_NUM + 5) // Not found 15 | const ERROR_NOT_SUPPORTED = (ERROR_BASE_NUM + 6) // Not supported 16 | const ERROR_INVALID_PARAM = (ERROR_BASE_NUM + 7) // Invalid Parameter 17 | const ERROR_INVALID_STATE = (ERROR_BASE_NUM + 8) // Invalid state, operation disallowed in this state 18 | const ERROR_INVALID_LENGTH = (ERROR_BASE_NUM + 9) // Invalid Length 19 | const ERROR_INVALID_FLAGS = (ERROR_BASE_NUM + 10) // Invalid Flags 20 | const ERROR_INVALID_DATA = (ERROR_BASE_NUM + 11) // Invalid Data 21 | const ERROR_DATA_SIZE = (ERROR_BASE_NUM + 12) // Invalid Data size 22 | const ERROR_TIMEOUT = (ERROR_BASE_NUM + 13) // Operation timed out 23 | const ERROR_NULL = (ERROR_BASE_NUM + 14) // Null Pointer 24 | const ERROR_FORBIDDEN = (ERROR_BASE_NUM + 15) // Forbidden Operation 25 | const ERROR_INVALID_ADDR = (ERROR_BASE_NUM + 16) // Bad Memory Address 26 | const ERROR_BUSY = (ERROR_BASE_NUM + 17) // Busy 27 | const ERROR_CONN_COUNT = (ERROR_BASE_NUM + 18) // Maximum connection count exceeded. 28 | const ERROR_RESOURCES = (ERROR_BASE_NUM + 19) // Not enough resources for operation 29 | -------------------------------------------------------------------------------- /softdevice/gen/s140/nrf/zerrorsdm.go: -------------------------------------------------------------------------------- 1 | // Code generated from ../nordic/s140/headers/nrf_error_sdm.h; DO NOT EDIT. 2 | 3 | package nrf 4 | 5 | const ERROR_SDM_LFCLK_SOURCE_UNKNOWN = (ERROR_SDM_BASE_NUM + 0) // Unknown LFCLK source. 6 | const ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION = (ERROR_SDM_BASE_NUM + 1) // Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts). 7 | const ERROR_SDM_INCORRECT_CLENR0 = (ERROR_SDM_BASE_NUM + 2) // Incorrect CLENR0 (can be caused by erroneous SoftDevice flashing). 8 | -------------------------------------------------------------------------------- /softdevice/gen/s140/nrf/zerrorsoc.go: -------------------------------------------------------------------------------- 1 | // Code generated from ../nordic/s140/headers/nrf_error_soc.h; DO NOT EDIT. 2 | 3 | package nrf 4 | 5 | const ERROR_SOC_MUTEX_ALREADY_TAKEN = (ERROR_SOC_BASE_NUM + 0) // Mutex already taken 6 | const ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE = (ERROR_SOC_BASE_NUM + 1) // NVIC interrupt not available 7 | const ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED = (ERROR_SOC_BASE_NUM + 2) // NVIC interrupt priority not allowed 8 | const ERROR_SOC_NVIC_SHOULD_NOT_RETURN = (ERROR_SOC_BASE_NUM + 3) // NVIC should not return 9 | const ERROR_SOC_POWER_MODE_UNKNOWN = (ERROR_SOC_BASE_NUM + 4) // Power mode unknown 10 | const ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN = (ERROR_SOC_BASE_NUM + 5) // Power POF threshold unknown 11 | const ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN = (ERROR_SOC_BASE_NUM + 6) // Power off should not return 12 | const ERROR_SOC_RAND_NOT_ENOUGH_VALUES = (ERROR_SOC_BASE_NUM + 7) // RAND not enough values 13 | const ERROR_SOC_PPI_INVALID_CHANNEL = (ERROR_SOC_BASE_NUM + 8) // Invalid PPI Channel 14 | const ERROR_SOC_PPI_INVALID_GROUP = (ERROR_SOC_BASE_NUM + 9) // Invalid PPI Group 15 | -------------------------------------------------------------------------------- /softdevice/gen/s140/nrf/zsddef.go: -------------------------------------------------------------------------------- 1 | // Code generated from ../nordic/s140/headers/nrf_sd_def.h; DO NOT EDIT. 2 | 3 | package nrf 4 | 5 | const PPI_CHANNELS_USED = 0xFFFE0000 /**< PPI channels utilized by SotfDevice (not available to the application). */ 6 | const PPI_GROUPS_USED = 0x0000000C /**< PPI groups utilized by SoftDevice (not available to the application). */ 7 | const TIMERS_USED = 0x00000001 /**< Timers used by SoftDevice. */ 8 | const SWI_USED = 0x0000003C /**< Software interrupts used by SoftDevice */ 9 | -------------------------------------------------------------------------------- /softdevice/gen/s140/nrf/zsdm.go: -------------------------------------------------------------------------------- 1 | // Code generated from ../nordic/s140/headers/nrf_sdm.h; DO NOT EDIT. 2 | 3 | package nrf 4 | 5 | import ( 6 | "unsafe" 7 | ) 8 | 9 | const MBR_SIZE = 0 10 | const MAJOR_VERSION = (7) 11 | const MINOR_VERSION = (0) 12 | const BUGFIX_VERSION = (1) 13 | const VARIANT_ID = 140 14 | const VERSION = (MAJOR_VERSION*1000000 + MINOR_VERSION*1000 + BUGFIX_VERSION) 15 | const SDM_SVC_BASE = 0x10 16 | const UNIQUE_STR_SIZE = 20 17 | const SDM_INFO_FIELD_INVALID = (0) 18 | const SOFTDEVICE_INFO_STRUCT_OFFSET = (0x2000) 19 | const SOFTDEVICE_INFO_STRUCT_ADDRESS = (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE) 20 | const INFO_STRUCT_SIZE_OFFSET = (SOFTDEVICE_INFO_STRUCT_OFFSET) 21 | const SIZE_OFFSET = (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08) 22 | const FWID_OFFSET = (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C) 23 | const ID_OFFSET = (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x10) 24 | const VERSION_OFFSET = (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x14) 25 | const UNIQUE_STR_OFFSET = (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x18) 26 | const FLASH_SIZE = 0x26000 27 | const FAULT_ID_SD_RANGE_START = 0x00000000 // SoftDevice ID range start. 28 | const FAULT_ID_APP_RANGE_START = 0x00001000 // Application ID range start. 29 | const FAULT_ID_SD_ASSERT = (FAULT_ID_SD_RANGE_START + 1) // SoftDevice assertion. The info parameter is reserved for future used. 30 | const FAULT_ID_APP_MEMACC = (FAULT_ID_APP_RANGE_START + 1) // Application invalid memory access. The info parameter will contain 0x00000000, in case of SoftDevice RAM access violation. In case of SoftDevice peripheral register violation the info parameter will contain the sub-region number of PREGION[0], on whose address range the disallowed write access caused the memory access fault. 31 | 32 | const ( 33 | _SOFTDEVICE_ENABLE = SDM_SVC_BASE + iota 34 | _SOFTDEVICE_DISABLE 35 | _SOFTDEVICE_IS_ENABLED 36 | _SOFTDEVICE_VECTOR_TABLE_BASE_SET 37 | _SVC_SDM_LAST 38 | ) 39 | 40 | const CLOCK_LF_ACCURACY_250_PPM = (0) // Default: 250 ppm 41 | const CLOCK_LF_ACCURACY_500_PPM = (1) // 500 ppm 42 | const CLOCK_LF_ACCURACY_150_PPM = (2) // 150 ppm 43 | const CLOCK_LF_ACCURACY_100_PPM = (3) // 100 ppm 44 | const CLOCK_LF_ACCURACY_75_PPM = (4) // 75 ppm 45 | const CLOCK_LF_ACCURACY_50_PPM = (5) // 50 ppm 46 | const CLOCK_LF_ACCURACY_30_PPM = (6) // 30 ppm 47 | const CLOCK_LF_ACCURACY_20_PPM = (7) // 20 ppm 48 | const CLOCK_LF_ACCURACY_10_PPM = (8) // 10 ppm 49 | const CLOCK_LF_ACCURACY_5_PPM = (9) // 5 ppm 50 | const CLOCK_LF_ACCURACY_2_PPM = (10) // 2 ppm 51 | const CLOCK_LF_ACCURACY_1_PPM = (11) // 1 ppm 52 | const CLOCK_LF_SRC_RC = (0) // LFCLK RC oscillator. 53 | const CLOCK_LF_SRC_XTAL = (1) // LFCLK crystal oscillator. 54 | const CLOCK_LF_SRC_SYNTH = (2) // LFCLK Synthesized from HFCLK. 55 | 56 | type ClockLFCfg struct { 57 | Source uint8 // LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. 58 | RCCtiv uint8 // Only for ::NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second units (nRF52: 1-32). @note To avoid excessive clock drift, 0.5 degrees Celsius is the maximum temperature change allowed in one calibration timer interval. The interval should be selected to ensure this. @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC. 59 | RCTempCtiv uint8 // Only for ::NRF_CLOCK_LF_SRC_RC: How often (in number of calibration intervals) the RC oscillator shall be calibrated if the temperature hasn't changed. 0: Always calibrate even if the temperature hasn't changed. 1: Only calibrate if the temperature has changed (legacy - nRF51 only). 2-33: Check the temperature and only calibrate if it has changed, however calibration will take place every rc_temp_ctiv intervals in any case. @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC. @note For nRF52, the application must ensure calibration at least once every 8 seconds to ensure +/-500 ppm clock stability. The recommended configuration for ::NRF_CLOCK_LF_SRC_RC on nRF52 is rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at least once every 8 seconds and for temperature changes of 0.5 degrees Celsius every 4 seconds. See the Product Specification for the nRF52 device being used for more information. 60 | Accuracy uint8 // External clock accuracy used in the LL to compute timing windows, see @ref NRF_CLOCK_LF_ACCURACY. 61 | } 62 | 63 | // ::sd_softdevice_enable 64 | func EnableSoftdevice(clock_lf_cfg *ClockLFCfg, fault_handler unsafe.Pointer) uint32 65 | 66 | // ::sd_softdevice_disable 67 | func DisableSoftdevice() uint32 68 | 69 | // ::sd_softdevice_is_enabled 70 | func IsEnabledSoftdevice(softdevice_enabled *uint8) uint32 71 | 72 | // ::sd_softdevice_vector_table_base_set 73 | func SetSoftdeviceVectorTableBase(address uint32) uint32 74 | -------------------------------------------------------------------------------- /softdevice/gen/s140/nrf/zsdm.s: -------------------------------------------------------------------------------- 1 | // Code generated from ../nordic/s140/headers/nrf_sdm.h; DO NOT EDIT. 2 | 3 | #include "go_asm.h" 4 | #include "textflag.h" 5 | 6 | TEXT ·EnableSoftdevice(SB),NOSPLIT|NOFRAME,$0 7 | MOVW clock_lf_cfg+0(FP), R0 8 | MOVW fault_handler+4(FP), R1 9 | SWI $const__SOFTDEVICE_ENABLE 10 | MOVW R0, ret+8(FP) 11 | RET 12 | 13 | TEXT ·DisableSoftdevice(SB),NOSPLIT|NOFRAME,$0 14 | SWI $const__SOFTDEVICE_DISABLE 15 | MOVW R0, ret+0(FP) 16 | RET 17 | 18 | TEXT ·IsEnabledSoftdevice(SB),NOSPLIT|NOFRAME,$0 19 | MOVW softdevice_enabled+0(FP), R0 20 | SWI $const__SOFTDEVICE_IS_ENABLED 21 | MOVW R0, ret+4(FP) 22 | RET 23 | 24 | TEXT ·SetSoftdeviceVectorTableBase(SB),NOSPLIT|NOFRAME,$0 25 | MOVW address+0(FP), R0 26 | SWI $const__SOFTDEVICE_VECTOR_TABLE_BASE_SET 27 | MOVW R0, ret+4(FP) 28 | RET 29 | -------------------------------------------------------------------------------- /softdevice/nordic/s140/headers/ble_err.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form, except as embedded into a Nordic 12 | * Semiconductor ASA integrated circuit in a product or a software update for 13 | * such product, must reproduce the above copyright notice, this list of 14 | * conditions and the following disclaimer in the documentation and/or other 15 | * materials provided with the distribution. 16 | * 17 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of its 18 | * contributors may be used to endorse or promote products derived from this 19 | * software without specific prior written permission. 20 | * 21 | * 4. This software, with or without modification, must only be used with a 22 | * Nordic Semiconductor ASA integrated circuit. 23 | * 24 | * 5. Any software provided in binary form under this license must not be reverse 25 | * engineered, decompiled, modified and/or disassembled. 26 | * 27 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 28 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29 | * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 30 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 31 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 33 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 36 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | /** 40 | @addtogroup BLE_COMMON 41 | @{ 42 | @addtogroup nrf_error 43 | @{ 44 | @ingroup BLE_COMMON 45 | @} 46 | 47 | @defgroup ble_err General error codes 48 | @{ 49 | 50 | @brief General error code definitions for the BLE API. 51 | 52 | @ingroup BLE_COMMON 53 | */ 54 | #ifndef NRF_BLE_ERR_H__ 55 | #define NRF_BLE_ERR_H__ 56 | 57 | #include "nrf_error.h" 58 | 59 | #ifdef __cplusplus 60 | extern "C" { 61 | #endif 62 | 63 | /* @defgroup BLE_ERRORS Error Codes 64 | * @{ */ 65 | #define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */ 66 | #define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */ 67 | #define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */ 68 | #define BLE_ERROR_INVALID_ADV_HANDLE (NRF_ERROR_STK_BASE_NUM+0x004) /**< Invalid advertising handle. */ 69 | #define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */ 70 | #define BLE_ERROR_BLOCKED_BY_OTHER_LINKS (NRF_ERROR_STK_BASE_NUM+0x006) /**< The attempt to change link settings failed due to the scheduling of other links. */ 71 | /** @} */ 72 | 73 | 74 | /** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges 75 | * @brief Assignment of subranges for module specific error codes. 76 | * @note For specific error codes, see ble_.h or ble_error_.h. 77 | * @{ */ 78 | #define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */ 79 | #define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */ 80 | #define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */ 81 | #define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */ 82 | /** @} */ 83 | 84 | #ifdef __cplusplus 85 | } 86 | #endif 87 | #endif 88 | 89 | 90 | /** 91 | @} 92 | @} 93 | */ 94 | -------------------------------------------------------------------------------- /softdevice/nordic/s140/headers/nrf_error.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form, except as embedded into a Nordic 12 | * Semiconductor ASA integrated circuit in a product or a software update for 13 | * such product, must reproduce the above copyright notice, this list of 14 | * conditions and the following disclaimer in the documentation and/or other 15 | * materials provided with the distribution. 16 | * 17 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of its 18 | * contributors may be used to endorse or promote products derived from this 19 | * software without specific prior written permission. 20 | * 21 | * 4. This software, with or without modification, must only be used with a 22 | * Nordic Semiconductor ASA integrated circuit. 23 | * 24 | * 5. Any software provided in binary form under this license must not be reverse 25 | * engineered, decompiled, modified and/or disassembled. 26 | * 27 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 28 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29 | * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 30 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 31 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 33 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 36 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | /** 40 | @defgroup nrf_error SoftDevice Global Error Codes 41 | @{ 42 | 43 | @brief Global Error definitions 44 | */ 45 | 46 | /* Header guard */ 47 | #ifndef NRF_ERROR_H__ 48 | #define NRF_ERROR_H__ 49 | 50 | #ifdef __cplusplus 51 | extern "C" { 52 | #endif 53 | 54 | /** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions 55 | * @{ */ 56 | #define NRF_ERROR_BASE_NUM (0x0) ///< Global error base 57 | #define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base 58 | #define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base 59 | #define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base 60 | /** @} */ 61 | 62 | #define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command 63 | #define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing 64 | #define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled 65 | #define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error 66 | #define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation 67 | #define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found 68 | #define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported 69 | #define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter 70 | #define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state 71 | #define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length 72 | #define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags 73 | #define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data 74 | #define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size 75 | #define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out 76 | #define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer 77 | #define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation 78 | #define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address 79 | #define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy 80 | #define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded. 81 | #define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation 82 | 83 | #ifdef __cplusplus 84 | } 85 | #endif 86 | #endif // NRF_ERROR_H__ 87 | 88 | /** 89 | @} 90 | */ 91 | -------------------------------------------------------------------------------- /softdevice/nordic/s140/headers/nrf_error_sdm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form, except as embedded into a Nordic 12 | * Semiconductor ASA integrated circuit in a product or a software update for 13 | * such product, must reproduce the above copyright notice, this list of 14 | * conditions and the following disclaimer in the documentation and/or other 15 | * materials provided with the distribution. 16 | * 17 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of its 18 | * contributors may be used to endorse or promote products derived from this 19 | * software without specific prior written permission. 20 | * 21 | * 4. This software, with or without modification, must only be used with a 22 | * Nordic Semiconductor ASA integrated circuit. 23 | * 24 | * 5. Any software provided in binary form under this license must not be reverse 25 | * engineered, decompiled, modified and/or disassembled. 26 | * 27 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 28 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29 | * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 30 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 31 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 33 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 36 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | /** 40 | @addtogroup nrf_sdm_api 41 | @{ 42 | @defgroup nrf_sdm_error SoftDevice Manager Error Codes 43 | @{ 44 | 45 | @brief Error definitions for the SDM API 46 | */ 47 | 48 | /* Header guard */ 49 | #ifndef NRF_ERROR_SDM_H__ 50 | #define NRF_ERROR_SDM_H__ 51 | 52 | #include "nrf_error.h" 53 | 54 | #ifdef __cplusplus 55 | extern "C" { 56 | #endif 57 | 58 | #define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown LFCLK source. 59 | #define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts). 60 | #define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erroneous SoftDevice flashing). 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | #endif // NRF_ERROR_SDM_H__ 66 | 67 | /** 68 | @} 69 | @} 70 | */ 71 | -------------------------------------------------------------------------------- /softdevice/nordic/s140/headers/nrf_error_soc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form, except as embedded into a Nordic 12 | * Semiconductor ASA integrated circuit in a product or a software update for 13 | * such product, must reproduce the above copyright notice, this list of 14 | * conditions and the following disclaimer in the documentation and/or other 15 | * materials provided with the distribution. 16 | * 17 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of its 18 | * contributors may be used to endorse or promote products derived from this 19 | * software without specific prior written permission. 20 | * 21 | * 4. This software, with or without modification, must only be used with a 22 | * Nordic Semiconductor ASA integrated circuit. 23 | * 24 | * 5. Any software provided in binary form under this license must not be reverse 25 | * engineered, decompiled, modified and/or disassembled. 26 | * 27 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 28 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29 | * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 30 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 31 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 33 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 36 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | /** 40 | @addtogroup nrf_soc_api 41 | @{ 42 | @defgroup nrf_soc_error SoC Library Error Codes 43 | @{ 44 | 45 | @brief Error definitions for the SoC library 46 | 47 | */ 48 | 49 | /* Header guard */ 50 | #ifndef NRF_ERROR_SOC_H__ 51 | #define NRF_ERROR_SOC_H__ 52 | 53 | #include "nrf_error.h" 54 | #ifdef __cplusplus 55 | extern "C" { 56 | #endif 57 | 58 | /* Mutex Errors */ 59 | #define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken 60 | 61 | /* NVIC errors */ 62 | #define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available 63 | #define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed 64 | #define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return 65 | 66 | /* Power errors */ 67 | #define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown 68 | #define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown 69 | #define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return 70 | 71 | /* Rand errors */ 72 | #define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values 73 | 74 | /* PPI errors */ 75 | #define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel 76 | #define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | #endif // NRF_ERROR_SOC_H__ 82 | /** 83 | @} 84 | @} 85 | */ 86 | -------------------------------------------------------------------------------- /softdevice/nordic/s140/headers/nrf_svc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 - 2019, Nordic Semiconductor ASA 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form, except as embedded into a Nordic 12 | * Semiconductor ASA integrated circuit in a product or a software update for 13 | * such product, must reproduce the above copyright notice, this list of 14 | * conditions and the following disclaimer in the documentation and/or other 15 | * materials provided with the distribution. 16 | * 17 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of its 18 | * contributors may be used to endorse or promote products derived from this 19 | * software without specific prior written permission. 20 | * 21 | * 4. This software, with or without modification, must only be used with a 22 | * Nordic Semiconductor ASA integrated circuit. 23 | * 24 | * 5. Any software provided in binary form under this license must not be reverse 25 | * engineered, decompiled, modified and/or disassembled. 26 | * 27 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 28 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29 | * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 30 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 31 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 33 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 36 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | #ifndef NRF_SVC__ 40 | #define NRF_SVC__ 41 | 42 | #include "stdint.h" 43 | 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | /** @brief Supervisor call declaration. 49 | * 50 | * A call to a function marked with @ref SVCALL, will trigger a Supervisor Call (SVC) Exception. 51 | * The SVCs with SVC numbers 0x00-0x0F are forwared to the application. All other SVCs are handled by the SoftDevice. 52 | * 53 | * @param[in] number The SVC number to be used. 54 | * @param[in] return_type The return type of the SVC function. 55 | * @param[in] signature Function signature. The function can have at most four arguments. 56 | */ 57 | 58 | #ifdef SVCALL_AS_NORMAL_FUNCTION 59 | #define SVCALL(number, return_type, signature) return_type signature 60 | #else 61 | 62 | #ifndef SVCALL 63 | #if defined (__CC_ARM) 64 | #define SVCALL(number, return_type, signature) return_type __svc(number) signature 65 | #elif defined (__GNUC__) 66 | #ifdef __cplusplus 67 | #define GCC_CAST_CPP (uint16_t) 68 | #else 69 | #define GCC_CAST_CPP 70 | #endif 71 | #define SVCALL(number, return_type, signature) \ 72 | _Pragma("GCC diagnostic push") \ 73 | _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ 74 | __attribute__((naked)) \ 75 | __attribute__((unused)) \ 76 | static return_type signature \ 77 | { \ 78 | __asm( \ 79 | "svc %0\n" \ 80 | "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \ 81 | ); \ 82 | } \ 83 | _Pragma("GCC diagnostic pop") 84 | 85 | #elif defined (__ICCARM__) 86 | #define PRAGMA(x) _Pragma(#x) 87 | #define SVCALL(number, return_type, signature) \ 88 | PRAGMA(swi_number = (number)) \ 89 | __swi return_type signature; 90 | #else 91 | #define SVCALL(number, return_type, signature) return_type signature 92 | #endif 93 | #endif // SVCALL 94 | 95 | #endif // SVCALL_AS_NORMAL_FUNCTION 96 | 97 | #ifdef __cplusplus 98 | } 99 | #endif 100 | #endif // NRF_SVC__ 101 | -------------------------------------------------------------------------------- /softdevice/nordic/s140/hex/s140_nrf52_7.0.1_licence-agreement.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007 - 2019, Nordic Semiconductor ASA 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form, except as embedded into a Nordic 11 | Semiconductor ASA integrated circuit in a product or a software update for 12 | such product, must reproduce the above copyright notice, this list of 13 | conditions and the following disclaimer in the documentation and/or other 14 | materials provided with the distribution. 15 | 16 | 3. Neither the name of Nordic Semiconductor ASA nor the names of its 17 | contributors may be used to endorse or promote products derived from this 18 | software without specific prior written permission. 19 | 20 | 4. This software, with or without modification, must only be used with a 21 | Nordic Semiconductor ASA integrated circuit. 22 | 23 | 5. Any software provided in binary form under this license must not be reverse 24 | engineered, decompiled, modified and/or disassembled. 25 | 26 | THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 27 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 28 | OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 29 | DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 30 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 32 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 35 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | -------------------------------------------------------------------------------- /softdevice/nordic/s140/hex/s140_nrf52_7.2.0_license-agreement.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007 - 2020, Nordic Semiconductor ASA 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form, except as embedded into a Nordic 11 | Semiconductor ASA integrated circuit in a product or a software update for 12 | such product, must reproduce the above copyright notice, this list of 13 | conditions and the following disclaimer in the documentation and/or other 14 | materials provided with the distribution. 15 | 16 | 3. Neither the name of Nordic Semiconductor ASA nor the names of its 17 | contributors may be used to endorse or promote products derived from this 18 | software without specific prior written permission. 19 | 20 | 4. This software, with or without modification, must only be used with a 21 | Nordic Semiconductor ASA integrated circuit. 22 | 23 | 5. Any software provided in binary form under this license must not be reverse 24 | engineered, decompiled, modified and/or disassembled. 25 | 26 | THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 27 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 28 | OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 29 | DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 30 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 32 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 35 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | -------------------------------------------------------------------------------- /softdevice/s140/LICENSE-NORDIC: -------------------------------------------------------------------------------- 1 | This directory contains the translation of the SoftDevice API to the Go 2 | language. The original code was provided by Nordic Semiconductor ASA as C 3 | source with the following copyright notice: 4 | 5 | Copyright (c) 2014 - 2019, Nordic Semiconductor ASA 6 | 7 | All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 10 | 11 | 1. Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | 2. Redistributions in binary form, except as embedded into a Nordic 15 | Semiconductor ASA integrated circuit in a product or a software update for 16 | such product, must reproduce the above copyright notice, this list of 17 | conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | 3. Neither the name of Nordic Semiconductor ASA nor the names of its 21 | contributors may be used to endorse or promote products derived from this 22 | software without specific prior written permission. 23 | 24 | 4. This software, with or without modification, must only be used with a 25 | Nordic Semiconductor ASA integrated circuit. 26 | 27 | 5. Any software provided in binary form under this license must not be reverse 28 | engineered, decompiled, modified and/or disassembled. 29 | 30 | THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 31 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 32 | OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 33 | DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 34 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 35 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 36 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 37 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 38 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 39 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/error.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package ble 7 | 8 | import "github.com/embeddedgo/nrf5/softdevice/s140/sd" 9 | 10 | const ErrorBase = 0x3000 11 | 12 | type Error uint32 13 | 14 | const ( 15 | ErrNotEnabled Error = ErrorBase + 1 // BLE not enabled 16 | ErrInvalidConnHandle Error = ErrorBase + 2 // invalid connection handle 17 | ErrInvalidAttrHandle Error = ErrorBase + 3 // invalid connection handle 18 | ErrInvalidAdvHandle Error = ErrorBase + 4 // invalid advertising handle 19 | ErrInvalidRole Error = ErrorBase + 5 // invalid advertising handle 20 | ErrBlockedByOtherLinks Error = ErrorBase + 6 // change link settings failed due to the scheduling of other links 21 | ) 22 | 23 | var errStr = [...]string{ 24 | "???", 25 | "BLE not enabled", 26 | "invalid connection handle", 27 | "invalid connection handle", 28 | "invalid advertising handle", 29 | "invalid advertising handle", 30 | "blocked by other links", 31 | } 32 | 33 | func (e Error) Error() string { 34 | s := "???" 35 | if e >= ErrorBase { 36 | if e -= ErrorBase; int(e) < len(errStr) { 37 | s = errStr[e] 38 | } 39 | } 40 | return "ble: " + s 41 | } 42 | 43 | func mkerr(e uint32) error { 44 | switch { 45 | case e == 0: 46 | return nil 47 | case e >= ErrorBase: 48 | return Error(e) 49 | default: 50 | return sd.Error(e) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/event.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package ble 7 | 8 | const ( 9 | EvtBase = 1 10 | EvtLast = 0x0F 11 | ) 12 | 13 | const ( 14 | EvtUserMemReq = EvtBase + 0 // user memory request 15 | EvtUserMemRelease = EvtBase + 1 // user memory release 16 | ) 17 | 18 | type EvtHdr struct { 19 | ID uint16 // event id (eg. EvtUserMemReq, gap.EvtConnected) 20 | Len uint16 // length in octets including this header 21 | ConnHandle Handle // connection handle 22 | } 23 | 24 | func (e *EvtHdr) EventID() uint16 { return e.ID } 25 | 26 | type UserMemReq struct { 27 | EvtHdr 28 | Type MemType // user memory type 29 | } 30 | 31 | type UserMemBlock struct { 32 | Mem *uint8 // Pointer to the start of the user memory block. 33 | Len uint16 // Length in bytes of the user memory block. 34 | } 35 | 36 | type UserMemRelease struct { 37 | EvtHdr 38 | Type MemType // user memory type 39 | MemBlock UserMemBlock // user memory block 40 | } 41 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/func.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package ble 7 | 8 | // Enable enables and initializes the BLE stack. 9 | func Enable(ramBase uintptr) (minBase uintptr, err error) { 10 | e := enable(&ramBase) 11 | return ramBase, mkerr(e) 12 | } 13 | 14 | // AddVSUUID add a Vendor Specific base UUID. 15 | func AddVSUUID(vsuuid *UUID128) (t UUIDType, err error) { 16 | err = mkerr(addUUIDVS(vsuuid, &t)) 17 | return 18 | } 19 | 20 | // EncodeUUID encode UUID bytes into provided buffer ant returns its size in 21 | // bytes. Set buf to nil to only compute encoded UUID size. 22 | func EncodeUUID(uuid *UUID, buf []byte) (int, error) { 23 | var p *byte 24 | if buf != nil { 25 | if len(buf) < 2 || len(buf) < 16 && uuid.Type > UUID16 { 26 | panic("ble: buffer too short for UUID") 27 | } 28 | p = &buf[0] 29 | } 30 | var n uint8 31 | e := encodeUUID(uuid, &n, p) 32 | return int(n), mkerr(e) 33 | } 34 | 35 | func DataBytes(data []byte) Data { 36 | if len(data) == 0 { 37 | return Data{} 38 | } 39 | if len(data) > 0xFFFF { 40 | panic("ble: data too long") 41 | } 42 | return Data{&data[0], uint16(len(data))} 43 | } 44 | 45 | // GetEvt gets an event bytes from the pending events queue. It copies event 46 | // data to dest and returns its size (in bytes). Set dest to nil to only check 47 | // the event size. 48 | func GetEvt(dest []uint32) (uintptr, error) { 49 | n := uint16(len(dest) * 4) 50 | var p *uint32 51 | if dest != nil { 52 | p = &dest[0] 53 | } 54 | e := getEvt(p, &n) 55 | return uintptr(n), mkerr(e) 56 | } 57 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/gap/error.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package gap 7 | 8 | import ( 9 | "github.com/embeddedgo/nrf5/softdevice/s140/sd" 10 | "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble" 11 | ) 12 | 13 | const ErrorBase = ble.ErrorBase + 0x200 14 | 15 | type Error uint32 16 | 17 | const ( 18 | // UUID list does not contain an integral number of UUIDs 19 | ErrUUIDListMismatch Error = ErrorBase + 0 20 | 21 | // Use of whitelist not permitted with discoverable advertising. 22 | ErrDiscoverableWithWhitelist Error = ErrorBase + 1 23 | 24 | // The upper two bits of the address do not correspond to the specified 25 | // address type. 26 | ErrInvalidBLEAddr Error = ErrorBase + 2 27 | 28 | // Attempt to modify the whitelist while already in use by another 29 | // operation. 30 | ErrWhitelistInUse Error = ErrorBase + 3 31 | 32 | // Attempt to modify the device identity list while already in use by 33 | // another operation. 34 | ErrDeviceIdentitiesInUse Error = ErrorBase + 4 35 | 36 | // The device identity list contains entries with duplicate identity 37 | // addresses. 38 | ErrDeviceIdentitiesDuplicate Error = ErrorBase + 5 39 | ) 40 | 41 | var errStr = [...]string{ 42 | "UUID list mismatch", 43 | "discoverable with whitelist", 44 | "invalid BLE addr", 45 | "whitelist in use", 46 | "device identities in use", 47 | "device identities duplicate", 48 | } 49 | 50 | func (e Error) Error() string { 51 | s := "???" 52 | if e >= ErrorBase { 53 | if e -= ErrorBase; int(e) < len(errStr) { 54 | s = errStr[e] 55 | } 56 | } 57 | return "gap: " + s 58 | } 59 | 60 | func mkerr(e uint32) error { 61 | switch { 62 | case e == 0: 63 | return nil 64 | case e >= ErrorBase: 65 | return Error(e) 66 | case e >= ble.ErrorBase: 67 | return ble.Error(e) 68 | default: 69 | return sd.Error(e) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/gap/event.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package gap 7 | 8 | import "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble" 9 | 10 | const ( 11 | EvtBase = 0x10 12 | EvtLast = 0x2F 13 | ) 14 | 15 | const ( 16 | EvtConnected = EvtBase + 0 // connected to peer 17 | EvtDisconnected = EvtBase + 1 // disconnected from peer 18 | EvtConnParamUpdate = EvtBase + 2 // connection parameters updated 19 | EvtSecParamsReq = EvtBase + 3 // req. to provide security param 20 | EvtSecInfoReq = EvtBase + 4 // req. to provide security info 21 | EvtPasskeyDisplay = EvtBase + 5 // req. to display a passkey 22 | EvtKeyPressed = EvtBase + 6 // keypress on the remote device 23 | EvtAuthKeyReq = EvtBase + 7 // req. to provide an auth. key 24 | EvtLESCDHKeyReq = EvtBase + 8 // req. to calculate LESConn DHKey 25 | EvtAuthStatus = EvtBase + 9 // auth. procedure completed 26 | EvtConnSecUpdate = EvtBase + 10 // connection security update 27 | EvtTimeout = EvtBase + 11 // timeout expire 28 | EvtRSSIChanged = EvtBase + 12 // RSSI repor 29 | EvtAdvReport = EvtBase + 13 // advertising repor 30 | EvtSecReq = EvtBase + 14 // security reques 31 | EvtConnParamUpdateReq = EvtBase + 15 // connection param. update req. 32 | EvtScanReqReport = EvtBase + 16 // scan request report 33 | EvtPHYUpdateReq = EvtBase + 17 // PHY update request 34 | EvtPHYUpdate = EvtBase + 18 // PHY update procedure completed 35 | EvtDataLengthUpdateReq = EvtBase + 19 // data length update request 36 | EvtDataLengthUpdate = EvtBase + 20 // LL data ch. PDU pay.len. update 37 | EvtQOSChannelSurveyReport = EvtBase + 21 // channel survey report 38 | EvtADVSetTerminated = EvtBase + 22 // advertising set terminated 39 | ) 40 | 41 | type Connected struct { 42 | ble.EvtHdr 43 | _ uint16 44 | PeerAddr Addr // bluetooth address of the peer device 45 | Role Role // BLE role for this connection 46 | ConnParams ConnParams // GAP connection parameters 47 | AdvHandle uint8 // advertising handle in which advertising has ended 48 | AdvData AdvData // buffers corresponding to the terminated advert. set 49 | } 50 | 51 | type Disconnected struct { 52 | ble.EvtHdr 53 | _ uint16 54 | Reason ble.HCIStatus // HCI error code 55 | } 56 | 57 | type ConnParamUpdate struct { 58 | ble.EvtHdr 59 | _ uint16 60 | ConnParams ConnParams // GAP connection parameters 61 | } 62 | 63 | type DataLengthUpdateReq struct { 64 | ble.EvtHdr 65 | _ uint16 66 | PeerParams DataLengthParams // Peer data length parameters 67 | } 68 | 69 | type DataLengthUpdate struct { 70 | ble.EvtHdr 71 | _ uint16 72 | EffectiveParams DataLengthParams // The effective data length parameters 73 | } 74 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/gap/func.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2019 Michal Derkacz. All rights reserved. 5 | 6 | package gap 7 | 8 | import ( 9 | "unsafe" 10 | 11 | "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble" 12 | "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble/internal" 13 | ) 14 | 15 | func SetConnCfg(cfg *ConnCfg, ramBase uintptr) error { 16 | return mkerr(internal.SetCfg(internal.CONN_CFG_GAP, unsafe.Pointer(cfg), 17 | ramBase)) 18 | } 19 | 20 | // SetRoleCountCfg sets the role count configuration. 21 | func SetRoleCountCfg(cfg *RoleCountCfg, ramBase uintptr) error { 22 | return mkerr(internal.SetCfg(internal.GAP_CFG_ROLE_COUNT, unsafe.Pointer(cfg), ramBase)) 23 | } 24 | 25 | // SetDeviceName sets device name and security mode. 26 | func SetDeviceName(writePerm ConnSecMode, devName string) error { 27 | return mkerr(setDeviceName(&writePerm, devName)) 28 | } 29 | 30 | // SetPPCP sets Peripheral Preferred Connection Parameters. 31 | func SetPPCP(connParams *ConnParams) error { 32 | return mkerr(setPPCP(connParams)) 33 | } 34 | 35 | // ConfigureAdvSet configures an advertising set. 36 | func ConfigureAdvSet(handle AdvSetHandle, data *AdvData, params *AdvParams) (AdvSetHandle, error) { 37 | e := configureAdvSet(&handle, data, params) 38 | return handle, mkerr(e) 39 | } 40 | 41 | // StartAdv starts advertising. 42 | func StartAdv(advHandle AdvSetHandle, connCfgTag uint8) error { 43 | return mkerr(startAdv(advHandle, connCfgTag)) 44 | } 45 | 46 | // StopAdv stops advertising. 47 | func StopAdv(advHandle AdvSetHandle) error { 48 | return mkerr(stopAdv(advHandle)) 49 | } 50 | 51 | // UpdateConnParam updates connection parameters. 52 | func UpdateConnParam(connHandle ble.Handle, connParams *ConnParams) error { 53 | return mkerr(updateConnParam(connHandle, connParams)) 54 | } 55 | 56 | // UpdateDataLength initiated or respondd to a Data Length Update Procedure. 57 | func UpdateDataLength(connHandle ble.Handle, dlParams *DataLengthParams, dlLimitation *DataLengthLimitation) error { 58 | return mkerr(updateDataLength(connHandle, dlParams, dlLimitation)) 59 | } 60 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/gap/svc.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package gap 7 | 8 | import "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble" 9 | 10 | //go:noescape 11 | func setDeviceName(write_perm *ConnSecMode, devName string) uint32 12 | 13 | //go:noescape 14 | func setPPCP(conn_params *ConnParams) uint32 15 | 16 | //go:noescape 17 | func configureAdvSet(adv_handle *AdvSetHandle, adv_data *AdvData, adv_params *AdvParams) uint32 18 | 19 | func startAdv(adv_handle AdvSetHandle, conn_cfg_tag uint8) uint32 20 | 21 | func stopAdv(adv_handle AdvSetHandle) uint32 22 | 23 | //go:noescape 24 | func updateConnParam(conn_handle ble.Handle, conn_params *ConnParams) uint32 25 | 26 | //go:noescape 27 | func updateDataLength(conn_handle ble.Handle, dl_params *DataLengthParams, dl_limitation *DataLengthLimitation) uint32 28 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/gatt/gatts/error.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package gatts 7 | 8 | import ( 9 | "github.com/embeddedgo/nrf5/softdevice/s140/sd" 10 | "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble" 11 | ) 12 | 13 | const ErrorBase = ble.ErrorBase + 0x400 14 | 15 | type Error uint32 16 | 17 | const ( 18 | ErrInvalidAttrType Error = ErrorBase + 0 // invalid attribute type 19 | ErrSysAttrMissing Error = ErrorBase + 1 // system attributes missing 20 | ) 21 | 22 | var errStr = [...]string{ 23 | "invalid attribute type", 24 | "system attributes missing", 25 | } 26 | 27 | func (e Error) Error() string { 28 | s := "???" 29 | if e >= ErrorBase { 30 | if e -= ErrorBase; int(e) < len(errStr) { 31 | s = errStr[e] 32 | } 33 | } 34 | return "gatts: " + s 35 | } 36 | 37 | func mkerr(e uint32) error { 38 | switch { 39 | case e == 0: 40 | return nil 41 | case e >= ErrorBase: 42 | return Error(e) 43 | case e >= ble.ErrorBase: 44 | return ble.Error(e) 45 | default: 46 | return sd.Error(e) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/gatt/gatts/event.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package gatts 7 | 8 | import ( 9 | "unsafe" 10 | 11 | "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble" 12 | ) 13 | 14 | const ( 15 | EvtBase = 0x50 16 | EvtLast = 0x6F 17 | ) 18 | 19 | const ( 20 | EvtWrite = EvtBase + 0 // write operation performed 21 | EvtRWAuthorizeReq = EvtBase + 1 // read/write authorization request 22 | EvtSysAttrMissing = EvtBase + 2 // persistent sys. attr. access is pending 23 | EvtHVC = EvtBase + 3 // handle value confirmation 24 | EvtSCConfirm = EvtBase + 4 // service changed confirmation 25 | EvtExchangeMTUReq = EvtBase + 5 // exchange MTU request 26 | EvtTimeout = EvtBase + 6 // peer failed to resp. to ATT req. in time 27 | EvtHVNTxComplete = EvtBase + 7 // handle val. notification Tx complete 28 | ) 29 | 30 | type Write struct { 31 | ble.EvtHdr 32 | Handle Handle // attribute handle 33 | UUID ble.UUID // attribute UUID 34 | Op Op // type of write operation 35 | AuthRequired bool // writing operation deferred due to auth. requirement 36 | Offset uint16 // offset for the write operation 37 | len uint16 // length of the received data 38 | data [1]uint8 // received data 39 | } 40 | 41 | func (w *Write) Data() []byte { 42 | return (*[1 << 16]byte)(unsafe.Pointer(&w.data[0]))[:w.len:w.len] 43 | } 44 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/gatt/gatts/func.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package gatts 7 | 8 | import ( 9 | "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble" 10 | ) 11 | 12 | // AddService adds a service. 13 | func AddService(typ ServiceType, uuid *ble.UUID) (h Handle, err error) { 14 | err = mkerr(addService(typ, uuid, &h)) 15 | return 16 | } 17 | 18 | func AddCharacteristic(service Handle, charMeta *CharMeta, charVal *Attr) (handles CharHandles, err error) { 19 | err = mkerr(addCharacteristic(service, charMeta, charVal, &handles)) 20 | return 21 | } 22 | 23 | // HVX handles value notification or indication. If len(data) != 0 the 24 | // attribute will be updated before sending the notification or indication. HVX 25 | // returns the number of bytes written to attribute. 26 | func HVX(connHandle ble.Handle, params *HVXParams, data ...byte) (int, error) { 27 | p := hvxParams{params.Handle, params.Type, params.Offset, nil, nil} 28 | if len(data) >= 1<<16 { 29 | panic("gatts: HVX data too long") 30 | } 31 | n := uint16(len(data)) 32 | if n != 0 { 33 | if params.Len != 0 && n > params.Len { 34 | n = params.Len 35 | } 36 | p.len = &n 37 | p.data = &data[0] 38 | } 39 | e := hvx(connHandle, &p) 40 | return int(n), mkerr(e) 41 | } 42 | 43 | type SysAttrFlags uint32 44 | 45 | const ( 46 | SysAttrSys SysAttrFlags = 1 << 0 // restrict system attributes to system services 47 | SysAttrUsr SysAttrFlags = 1 << 1 // restrict system attributes to user services 48 | ) 49 | 50 | // SetSysAttr sets the persistent system attributes for a connection. 51 | func SetSysAttr(connHandle ble.Handle, data []byte, flags SysAttrFlags) error { 52 | var p *byte 53 | if len(data) != 0 { 54 | p = &data[0] 55 | } 56 | return mkerr(setSysAttr(connHandle, p, uint16(len(data)), flags)) 57 | } 58 | 59 | // GetSysAttr retrieves the persistent system attributes. 60 | func GetSysAttr(connHandle ble.Handle, data []byte, flags SysAttrFlags) (int, error) { 61 | var p *byte 62 | var n uint16 63 | if len(data) != 0 { 64 | p = &data[0] 65 | n = uint16(len(data)) 66 | } 67 | e := getSysAttr(connHandle, p, &n, flags) 68 | return int(n), mkerr(e) 69 | } 70 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/gatt/gatts/svc.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package gatts 7 | 8 | import "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble" 9 | 10 | //go:noescape 11 | func addService(typ ServiceType, uuid *ble.UUID, handle *Handle) uint32 12 | 13 | // attr_char_value.Value can escape 14 | func addCharacteristic(service_handle Handle, char_md *CharMeta, attr_char_value *Attr, handles *CharHandles) uint32 15 | 16 | //go:noescape 17 | func hvx(conn_handle ble.Handle, hvx_params *hvxParams) uint32 18 | 19 | //go:noescape 20 | func setSysAttr(conn_handle ble.Handle, sys_attr_data *uint8, len uint16, flags SysAttrFlags) uint32 21 | 22 | //go:noescape 23 | func getSysAttr(conn_handle ble.Handle, sys_attr_data *uint8, len *uint16, flags SysAttrFlags) uint32 24 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/gatt/gatts/svc.s: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | #include "textflag.h" 7 | 8 | #define SVC_BASE 0xA8 9 | 10 | #define SERVICE_ADD (SVC_BASE + 0) 11 | #define INCLUDE_ADD (SVC_BASE + 1) 12 | #define CHARACTERISTIC_ADD (SVC_BASE + 2) 13 | #define DESCRIPTOR_ADD (SVC_BASE + 3) 14 | #define VALUE_SET (SVC_BASE + 4) 15 | #define VALUE_GET (SVC_BASE + 5) 16 | #define HVX (SVC_BASE + 6) 17 | #define SERVICE_CHANGED (SVC_BASE + 7) 18 | #define RW_AUTHORIZE_REPLY (SVC_BASE + 8) 19 | #define SYS_ATTR_SET (SVC_BASE + 9) 20 | #define SYS_ATTR_GET (SVC_BASE + 10) 21 | #define INITIAL_USER_HANDLE_GET (SVC_BASE + 11) 22 | #define ATTR_GET (SVC_BASE + 12) 23 | #define EXCHANGE_MTU_REPLY (SVC_BASE + 13) 24 | 25 | TEXT ·addService(SB),NOSPLIT|NOFRAME,$0 26 | MOVBU typ+0(FP), R0 27 | MOVW uuid+4(FP), R1 28 | MOVW handle+8(FP), R2 29 | SWI $SERVICE_ADD 30 | MOVW R0, ret+12(FP) 31 | RET 32 | 33 | TEXT ·addInclude(SB),NOSPLIT|NOFRAME,$0 34 | MOVHU service_handle+0(FP), R0 35 | MOVHU inc_srvc_handle+2(FP), R1 36 | MOVW include_handle+4(FP), R2 37 | SWI $INCLUDE_ADD 38 | MOVW R0, ret+8(FP) 39 | RET 40 | 41 | TEXT ·addCharacteristic(SB),NOSPLIT|NOFRAME,$0 42 | MOVHU service_handle+0(FP), R0 43 | MOVW char_md+4(FP), R1 44 | MOVW attr_char_value+8(FP), R2 45 | MOVW handles+12(FP), R3 46 | SWI $CHARACTERISTIC_ADD 47 | MOVW R0, ret+16(FP) 48 | RET 49 | 50 | TEXT ·addDescriptor(SB),NOSPLIT|NOFRAME,$0 51 | MOVHU char_handle+0(FP), R0 52 | MOVW attr+4(FP), R1 53 | MOVW handle+8(FP), R2 54 | SWI $DESCRIPTOR_ADD 55 | MOVW R0, ret+12(FP) 56 | RET 57 | 58 | TEXT ·setValue(SB),NOSPLIT|NOFRAME,$0 59 | MOVHU conn_handle+0(FP), R0 60 | MOVHU handle+2(FP), R1 61 | MOVW value+4(FP), R2 62 | SWI $VALUE_SET 63 | MOVW R0, ret+8(FP) 64 | RET 65 | 66 | TEXT ·getValue(SB),NOSPLIT|NOFRAME,$0 67 | MOVHU conn_handle+0(FP), R0 68 | MOVHU handle+2(FP), R1 69 | MOVW value+4(FP), R2 70 | SWI $VALUE_GET 71 | MOVW R0, ret+8(FP) 72 | RET 73 | 74 | TEXT ·hvx(SB),NOSPLIT|NOFRAME,$0 75 | MOVHU conn_handle+0(FP), R0 76 | MOVW hvx_params+4(FP), R1 77 | SWI $HVX 78 | MOVW R0, ret+8(FP) 79 | RET 80 | 81 | TEXT ·changedService(SB),NOSPLIT|NOFRAME,$0 82 | MOVHU conn_handle+0(FP), R0 83 | MOVHU start_handle+2(FP), R1 84 | MOVHU end_handle+4(FP), R2 85 | SWI $SERVICE_CHANGED 86 | MOVW R0, ret+8(FP) 87 | RET 88 | 89 | TEXT ·replyRwAuthorize(SB),NOSPLIT|NOFRAME,$0 90 | MOVHU conn_handle+0(FP), R0 91 | MOVW rw_authorize_reply_params+4(FP), R1 92 | SWI $RW_AUTHORIZE_REPLY 93 | MOVW R0, ret+8(FP) 94 | RET 95 | 96 | TEXT ·setSysAttr(SB),NOSPLIT|NOFRAME,$0 97 | MOVHU conn_handle+0(FP), R0 98 | MOVW sys_attr_data+4(FP), R1 99 | MOVHU len+8(FP), R2 100 | MOVW flags+12(FP), R3 101 | SWI $SYS_ATTR_SET 102 | MOVW R0, ret+16(FP) 103 | RET 104 | 105 | TEXT ·getSysAttr(SB),NOSPLIT|NOFRAME,$0 106 | MOVHU conn_handle+0(FP), R0 107 | MOVW sys_attr_data+4(FP), R1 108 | MOVW len+8(FP), R2 109 | MOVW flags+12(FP), R3 110 | SWI $SYS_ATTR_GET 111 | MOVW R0, ret+16(FP) 112 | RET 113 | 114 | TEXT ·getInitialUserHandle(SB),NOSPLIT|NOFRAME,$0 115 | MOVW handle+0(FP), R0 116 | SWI $INITIAL_USER_HANDLE_GET 117 | MOVW R0, ret+4(FP) 118 | RET 119 | 120 | TEXT ·getAttr(SB),NOSPLIT|NOFRAME,$0 121 | MOVHU handle+0(FP), R0 122 | MOVW uuid+4(FP), R1 123 | MOVW md+8(FP), R2 124 | SWI $ATTR_GET 125 | MOVW R0, ret+12(FP) 126 | RET 127 | 128 | TEXT ·replyExchangeMTU(SB),NOSPLIT|NOFRAME,$0 129 | MOVHU conn_handle+0(FP), R0 130 | MOVHU server_rx_mtu+2(FP), R1 131 | SWI $EXCHANGE_MTU_REPLY 132 | MOVW R0, ret+4(FP) 133 | RET 134 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/gatt/gatts/type.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package gatts 7 | 8 | import ( 9 | "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble" 10 | "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble/gap" 11 | "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble/gatt" 12 | ) 13 | 14 | type Handle uint16 15 | 16 | type ServiceType uint8 17 | 18 | const ( 19 | InvalidService ServiceType = 0 20 | PrimaryService ServiceType = 1 21 | SecondaryService ServiceType = 2 22 | ) 23 | 24 | type AttrOptions uint8 25 | 26 | const ( 27 | VLenAttr AttrOptions = 1 << 0 // variable length attribute 28 | ValLoc AttrOptions = 3 << 1 // attribute value location 29 | ValStack AttrOptions = 1 << 1 // attr. value located in stack memory 30 | ValUser AttrOptions = 2 << 1 // attr. value located in user memory 31 | ReadAuth AttrOptions = 1 << 3 // authoriz. requested on every read 32 | WriteAuth AttrOptions = 1 << 4 // authoriz. requested on every write 33 | ) 34 | 35 | type AttrMeta struct { 36 | ReadPerm gap.ConnSecMode 37 | WritePerm gap.ConnSecMode 38 | Options AttrOptions 39 | } 40 | 41 | type Attr struct { 42 | UUID *ble.UUID // attribute UUID. 43 | Meta *AttrMeta // metadata 44 | InitLen uint16 // initial attribute value length in bytes 45 | InitOffs uint16 // initial attribute value offset in bytes 46 | MaxLen uint16 // maximum attribute value length in bytes 47 | Value *byte // pointer to the attribute data 48 | } 49 | 50 | type CharPF struct { 51 | Format gatt.PF // format of the value 52 | Exponent int8 // exponent for integer data types 53 | Unit uint16 // unit from Bluetooth Assigned Numbers 54 | Namespace uint8 // namespace from Bluetooth Assigned Numbers 55 | Desc uint16 // namespace description from Bluetooth Assigned Numbers 56 | } 57 | 58 | type CharMeta struct { 59 | Props gatt.CharProps // characteristic properties 60 | ExtProps gatt.CharExtProps // characteristic extended properties. 61 | UserDesc *byte // pointer to a UTF-8 encoded string 62 | UserDescMaxSize uint16 63 | UserDescSize uint16 64 | PF *CharPF // presentation format (CPF descriptor) 65 | UserDescMeta *AttrMeta // user description descriptor metadata 66 | CCCDMeta *AttrMeta // client char. conf. descriptor metadeta 67 | SCCDMeta *AttrMeta // server char. conf. descriptor metadata 68 | } 69 | 70 | type CharHandles struct { 71 | Value Handle // handle to the characteristic value. 72 | UserDesc Handle // handle to the user description descriptor 73 | CCCD Handle // handle to the client char. conf. descriptor 74 | SCCD Handle // handle to the server char. conf. descriptor 75 | } 76 | 77 | type Op uint8 78 | 79 | const ( 80 | OpInvalid Op = 0 // invalid operation 81 | OpWriteReq Op = 1 // write request 82 | OpWriteCmd Op = 2 // write command 83 | OpSignWriteCmd Op = 3 // signed write command 84 | OpPrepWriteReq Op = 4 // prepare write request 85 | OpExecWriteReqCancel Op = 5 // cancel all prepared writes 86 | OpExecWriteReqNow Op = 6 // immediately execute all prepared writes 87 | ) 88 | 89 | type HVXParams struct { 90 | Handle Handle // characteristic value handle 91 | Type gatt.HVXType // indication or notification 92 | Offset uint16 // field offset within the attribute value 93 | Len uint16 // field length in bytes (0 means variable length) 94 | } 95 | 96 | type hvxParams struct { 97 | handle Handle 98 | typ gatt.HVXType 99 | offset uint16 100 | len *uint16 101 | data *byte 102 | } 103 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/gatt/type.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package gatt 7 | 8 | type CharProps uint8 9 | 10 | const ( 11 | PropBroadcast CharProps = 1 << 0 // broadcasting permitted 12 | PropRead CharProps = 1 << 1 // reading permitted 13 | PropWriteWoResp CharProps = 1 << 2 // write command permitted 14 | PropWrite CharProps = 1 << 3 // write request permitted 15 | PropNotify CharProps = 1 << 4 // notification permitted 16 | PropIndicate CharProps = 1 << 5 // indications permitted 17 | PropAuthSignedWr CharProps = 1 << 6 // signed write command permitted 18 | ) 19 | 20 | type CharExtProps uint8 21 | 22 | const ( 23 | PropRealiableWr CharExtProps = 1 << 0 // queued write permitted 24 | PropWrAux CharExtProps = 1 << 1 // write Char.User Descr. descriptor permitted 25 | ) 26 | 27 | // Presentation Format 28 | type PF uint8 29 | 30 | const ( 31 | FormatRFU PF = 0x00 // reserved for future use 32 | FormatBoolean PF = 0x01 // boolean 33 | Format2bit PF = 0x02 // unsigned 2-bit integer 34 | FormatNibble PF = 0x03 // unsigned 4-bit integer 35 | FormatUint8 PF = 0x04 // unsigned 8-bit integer 36 | FormatUint12 PF = 0x05 // unsigned 12-bit integer 37 | FormatUint16 PF = 0x06 // unsigned 16-bit integer 38 | FormatUint24 PF = 0x07 // unsigned 24-bit integer 39 | FormatUint32 PF = 0x08 // unsigned 32-bit integer 40 | FormatUint48 PF = 0x09 // unsigned 48-bit integer 41 | FormatUint64 PF = 0x0A // unsigned 64-bit integer 42 | FormatUint128 PF = 0x0B // unsigned 128-bit integer 43 | FormatSint8 PF = 0x0C // signed 8-bit integer 44 | FormatSint12 PF = 0x0D // signed 12-bit integer 45 | FormatSint16 PF = 0x0E // signed 16-bit integer 46 | FormatSint24 PF = 0x0F // signed 24-bit integer 47 | FormatSint32 PF = 0x10 // signed 32-bit integer 48 | FormatSint48 PF = 0x11 // signed 48-bit integer 49 | FormatSint64 PF = 0x12 // signed 64-bit integer 50 | FormatSint128 PF = 0x13 // signed 128-bit integer 51 | FormatFloat32 PF = 0x14 // IEEE-754 32-bit floating point 52 | FormatFloat64 PF = 0x15 // IEEE-754 64-bit floating point 53 | FormatSFloat PF = 0x16 // IEEE-11073 16-bit SFLOAT 54 | FormatFloat PF = 0x17 // IEEE-11073 32-bit FLOAT 55 | FormatDUint16 PF = 0x18 // IEEE-20601 format 56 | FormatUTF8S PF = 0x19 // UTF-8 string 57 | FormatUTF16S PF = 0x1A // UTF-16 string 58 | FormatStruct PF = 0x1B // opaque Structure 59 | ) 60 | 61 | type HVXType uint8 62 | 63 | const ( 64 | HVXInvalid HVXType = 0 // invalid operation 65 | Notification HVXType = 1 // handle value notification 66 | Indication HVXType = 2 // handle value indication 67 | ) 68 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/hci.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package ble 7 | 8 | type HCIStatus uint8 9 | 10 | const ( 11 | HCISuccess HCIStatus = 0x00 12 | HCIUnknownBTLECommand HCIStatus = 0x01 13 | HCIUnknownConnectionIdentifier HCIStatus = 0x02 14 | HCIAuthenticationFailure HCIStatus = 0x05 15 | HCIPinOrKeyMissing HCIStatus = 0x06 16 | HCIMemoryCapacityExceeded HCIStatus = 0x07 17 | HCIConnectionTimeout HCIStatus = 0x08 18 | HCICommandDisallowed HCIStatus = 0x0C 19 | HCIInvalidBTLECommandParameters HCIStatus = 0x12 20 | HCIRemoteUserTerminatedConnection HCIStatus = 0x13 21 | HCIRemoteDevTerminationDueToLowResources HCIStatus = 0x14 22 | HCIRemoteDevTerminationDUETOPOWEROFF HCIStatus = 0x15 23 | HCILocalHostTerminatedConnection HCIStatus = 0x16 24 | HCIUnsupportedRemoteFeature HCIStatus = 0x1A 25 | HCIInvalidLMPParameters HCIStatus = 0x1E 26 | HCIUnspecifiedError HCIStatus = 0x1F 27 | HCILMPResponseTimeout HCIStatus = 0x22 28 | HCILMPErrorTransactionCollision HCIStatus = 0x23 29 | HCILMPPDUNotAllowed HCIStatus = 0x24 30 | HCIInstantPassed HCIStatus = 0x28 31 | HCIPairingWithUnitKeyUnsupported HCIStatus = 0x29 32 | HCIDifferentTransactionCollision HCIStatus = 0x2A 33 | HCIParameterOutOfMandatoryRange HCIStatus = 0x30 34 | HCIControllerBusy HCIStatus = 0x3A 35 | HCIConnIntervalUnacceptable HCIStatus = 0x3B 36 | HCIDirectedAdvertiserTimeout HCIStatus = 0x3C 37 | HCIConnTerminatedDueToMICFailure HCIStatus = 0x3D 38 | HCIConnFailedToBeEstablished HCIStatus = 0x3E 39 | ) 40 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/internal/svc.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package internal 7 | 8 | import "unsafe" 9 | 10 | const CONN_CFG_BASE = 0x20 11 | 12 | const ( 13 | CONN_CFG_GAP = CONN_CFG_BASE + 0 // BLE GAP specific connection configuration. 14 | CONN_CFG_GATTC = CONN_CFG_BASE + 1 // BLE GATTC specific connection configuration. 15 | CONN_CFG_GATTS = CONN_CFG_BASE + 2 // BLE GATTS specific connection configuration. 16 | CONN_CFG_GATT = CONN_CFG_BASE + 3 // BLE GATT specific connection configuration. 17 | CONN_CFG_L2CAP = CONN_CFG_BASE + 4 // BLE L2CAP specific connection configuration. 18 | ) 19 | 20 | const GAP_CFG_BASE = 0x40 21 | 22 | const ( 23 | GAP_CFG_ROLE_COUNT = GAP_CFG_BASE + 0 // Role count configuration. 24 | GAP_CFG_DEVICE_NAME = GAP_CFG_BASE + 1 // Device name configuration. 25 | GAP_CFG_PPCP_INCL_CONFIG = GAP_CFG_BASE + 2 // Peripheral Preferred Connection Parameters characteristic inclusion configuration. 26 | GAP_CFG_CAR_INCL_CONFIG = GAP_CFG_BASE + 3 // Central Address Resolution characteristic inclusion configuration. 27 | ) 28 | 29 | //go:noescape 30 | func SetCfg(cfg_id uint32, cfg unsafe.Pointer, app_ram_base uintptr) uint32 31 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/internal/svc.s: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. 2 | 3 | #include "textflag.h" 4 | 5 | #define SVC_BASE 0x60 6 | 7 | #define CFG_SET (SVC_BASE + 9) 8 | 9 | TEXT ·SetCfg(SB),NOSPLIT|NOFRAME,$0 10 | MOVW cfg_id+0(FP), R0 11 | MOVW cfg+4(FP), R1 12 | MOVW app_ram_base+8(FP), R2 13 | SWI $CFG_SET 14 | MOVW R0, ret+12(FP) 15 | RET 16 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/svc.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package ble 7 | 8 | //go:noescape 9 | func enable(app_ram_base *uintptr) uint32 10 | 11 | //go:noescape 12 | func addUUIDVS(vs_uuid *UUID128, uuid_type *UUIDType) uint32 13 | 14 | //go:noescape 15 | func encodeUUID(uuid *UUID, uuid_le_len *uint8, uuid_le *uint8) uint32 16 | 17 | //go:noescape 18 | func getEvt(dest *uint32, len *uint16) uint32 19 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/svc.s: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | #include "textflag.h" 7 | 8 | #define SVC_BASE 0x60 9 | 10 | #define ENABLE (SVC_BASE + 0) 11 | #define EVT_GET (SVC_BASE + 1) 12 | #define UUID_VS_ADD (SVC_BASE + 2) 13 | #define UUID_DECODE (SVC_BASE + 3) 14 | #define UUID_ENCODE (SVC_BASE + 4) 15 | #define VERSION_GET (SVC_BASE + 5) 16 | #define USER_MEM_REPLY (SVC_BASE + 6) 17 | #define OPT_SET (SVC_BASE + 7) 18 | #define OPT_GET (SVC_BASE + 8) 19 | #define CFG_SET (SVC_BASE + 9) 20 | #define UUID_VS_REMOVE (SVC_BASE + 10) 21 | 22 | TEXT ·enable(SB),NOSPLIT|NOFRAME,$0 23 | MOVW app_ram_base+0(FP), R0 24 | SWI $ENABLE 25 | MOVW R0, ret+4(FP) 26 | RET 27 | 28 | TEXT ·setCfg(SB),NOSPLIT|NOFRAME,$0 29 | MOVW cfg_id+0(FP), R0 30 | MOVW cfg+4(FP), R1 31 | MOVW app_ram_base+8(FP), R2 32 | SWI $CFG_SET 33 | MOVW R0, ret+12(FP) 34 | RET 35 | 36 | TEXT ·getEvt(SB),NOSPLIT|NOFRAME,$0 37 | MOVW dest+0(FP), R0 38 | MOVW len+4(FP), R1 39 | SWI $EVT_GET 40 | MOVW R0, ret+8(FP) 41 | RET 42 | 43 | TEXT ·addUUIDVS(SB),NOSPLIT|NOFRAME,$0 44 | MOVW vs_uuid+0(FP), R0 45 | MOVW uuid_type+4(FP), R1 46 | SWI $UUID_VS_ADD 47 | MOVW R0, ret+8(FP) 48 | RET 49 | 50 | TEXT ·removeUUIDVS(SB),NOSPLIT|NOFRAME,$0 51 | MOVW uuid_type+0(FP), R0 52 | SWI $UUID_VS_REMOVE 53 | MOVW R0, ret+4(FP) 54 | RET 55 | 56 | TEXT ·decodeUUID(SB),NOSPLIT|NOFRAME,$0 57 | MOVBU uuid_le_len+0(FP), R0 58 | MOVW uuid_le+4(FP), R1 59 | MOVW uuid+8(FP), R2 60 | SWI $UUID_DECODE 61 | MOVW R0, ret+12(FP) 62 | RET 63 | 64 | TEXT ·encodeUUID(SB),NOSPLIT|NOFRAME,$0 65 | MOVW uuid+0(FP), R0 66 | MOVW uuid_le_len+4(FP), R1 67 | MOVW uuid_le+8(FP), R2 68 | SWI $UUID_ENCODE 69 | MOVW R0, ret+12(FP) 70 | RET 71 | 72 | TEXT ·getVersion(SB),NOSPLIT|NOFRAME,$0 73 | MOVW version+0(FP), R0 74 | SWI $VERSION_GET 75 | MOVW R0, ret+4(FP) 76 | RET 77 | 78 | TEXT ·replyUserMem(SB),NOSPLIT|NOFRAME,$0 79 | MOVHU conn_handle+0(FP), R0 80 | MOVW block+4(FP), R1 81 | SWI $USER_MEM_REPLY 82 | MOVW R0, ret+8(FP) 83 | RET 84 | 85 | TEXT ·setOpt(SB),NOSPLIT|NOFRAME,$0 86 | MOVW opt_id+0(FP), R0 87 | MOVW opt+4(FP), R1 88 | SWI $OPT_SET 89 | MOVW R0, ret+8(FP) 90 | RET 91 | 92 | TEXT ·getOpt(SB),NOSPLIT|NOFRAME,$0 93 | MOVW opt_id+0(FP), R0 94 | MOVW opt+4(FP), R1 95 | SWI $OPT_GET 96 | MOVW R0, ret+8(FP) 97 | RET 98 | -------------------------------------------------------------------------------- /softdevice/s140/sd/ble/type.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package ble 7 | 8 | type Handle uint16 9 | 10 | const ( 11 | ConnInvalid Handle = 0xFFFF // invalid connection handle 12 | ConnAll Handle = 0xFFFE // applies to all connection handles 13 | ) 14 | 15 | type UUID128 [16]byte // little-endian UUID bytes 16 | 17 | type UUIDType uint8 18 | 19 | const ( 20 | UUIDXX UUIDType = 0 // unknown/invalid UUID type 21 | UUID16 UUIDType = 1 // bluetooth SIG 16-bit UUID 22 | VSUUIDBase UUIDType = 2 // vendor-spcific UUID types start at this index 23 | ) 24 | 25 | type UUID struct { 26 | Value uint16 27 | Type UUIDType 28 | } 29 | 30 | type Data struct { 31 | p *byte 32 | len uint16 33 | } 34 | 35 | type MemType uint8 36 | 37 | const ( 38 | UserMemInvalid MemType = 0 // invalid user memory types 39 | UserMemGATTSQueuedWrites MemType = 1 // User memory for GATTS queued writes 40 | ) 41 | -------------------------------------------------------------------------------- /softdevice/s140/sd/error.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package sd 7 | 8 | type Error uint32 9 | 10 | const ( 11 | ErrSVC Error = 1 // SVC handler is missing 12 | ErrNotEnabled Error = 2 // softdevice not enabled 13 | ErrInternal Error = 3 // internal error 14 | ErrNoMem Error = 4 // no memory for operation 15 | ErrNotFound Error = 5 // not found 16 | ErrNotSupported Error = 6 // not supported 17 | ErrInvalidParam Error = 7 // invalid parameter 18 | ErrInvalidState Error = 8 // invalid state, operation disallowed in this state 19 | ErrInvalidLength Error = 9 // invalid length 20 | ErrInvalidFlags Error = 10 // invalid flags 21 | ErrInvalidData Error = 11 // invalid data 22 | ErrDataSize Error = 12 // invalid data size 23 | ErrTimeout Error = 13 // operation timed out 24 | ErrNil Error = 14 // nil pointer 25 | ErrForbidden Error = 15 // forbidden operation 26 | ErrInvalidAddr Error = 16 // bad memory address 27 | ErrBusy Error = 17 // busy 28 | ErrConnCount Error = 18 // maximum connection count exceeded 29 | ErrResources Error = 19 // not enough resources for operation 30 | ) 31 | 32 | var errStr = [...]string{ 33 | "???", 34 | "SVC handler is missing", 35 | "softdevice not enabled", 36 | "internal error", 37 | "no memory for operation", 38 | "not found", 39 | "not supported", 40 | "invalid parameter", 41 | "invalid state", 42 | "invalid length", 43 | "invalid flags", 44 | "invalid data", 45 | "invalid data size", 46 | "operation timed out", 47 | "nil pointer", 48 | "forbidden operation", 49 | "bad memory address", 50 | "busy", 51 | "maximum connection count exceeded", 52 | "not enough resources for operation", 53 | } 54 | 55 | func (e Error) Error() string { 56 | s := "???" 57 | if int(e) < len(errStr) { 58 | s = errStr[e] 59 | } 60 | return "sd: " + s 61 | } 62 | -------------------------------------------------------------------------------- /softdevice/s140/sd/sdm/error.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package sdm 7 | 8 | import "github.com/embeddedgo/nrf5/softdevice/s140/sd" 9 | 10 | const ErrorBase = 0x1000 11 | 12 | type Error uint32 13 | 14 | const ( 15 | ErrLFCLKS Error = ErrorBase + 0 // unknown LFCLK source 16 | ErrIntCfg Error = ErrorBase + 1 // incorrect interrupt configuration 17 | ErrCLENR0 Error = ErrorBase + 2 // incorrect CLENR0 18 | ) 19 | 20 | var errStr = [...]string{ 21 | "unknown LFCLK source", 22 | "incorrect interrupt configuration", 23 | "incorrect CLENR0", 24 | } 25 | 26 | func (e Error) Error() string { 27 | s := "???" 28 | if e >= ErrorBase { 29 | if e -= ErrorBase; int(e) < len(errStr) { 30 | s = errStr[e] 31 | } 32 | } 33 | return "sdm: " + s 34 | } 35 | 36 | func mkerr(e uint32) error { 37 | switch { 38 | case e == 0: 39 | return nil 40 | case e >= ErrorBase: 41 | return Error(e) 42 | default: 43 | return sd.Error(e) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /softdevice/s140/sd/sdm/sdm.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package sdm 7 | 8 | import "unsafe" 9 | 10 | // LFCLKA represents accuracy of external low-frequency clock source. 11 | type LFCLKA uint8 12 | 13 | const ( 14 | LFCLK250ppm LFCLKA = 0 // 250 ppm (default) 15 | LFCLK500ppm LFCLKA = 1 // 500 ppm 16 | LFCLK150ppm LFCLKA = 2 // 150 ppm 17 | LFCLK100ppm LFCLKA = 3 // 100 ppm 18 | LFCLK75ppm LFCLKA = 4 // 75 ppm 19 | LFCLK50ppm LFCLKA = 5 // 50 ppm 20 | LFCLK30ppm LFCLKA = 6 // 30 ppm 21 | LFCLK20ppm LFCLKA = 7 // 20 ppm 22 | LFCLK10ppm LFCLKA = 8 // 10 ppm 23 | LFCLK5ppm LFCLKA = 9 // 5 ppm 24 | LFCLK2ppm LFCLKA = 10 // 2 ppm 25 | LFCLK1ppm LFCLKA = 11 // 1 ppm 26 | ) 27 | 28 | // LFCLKS represents possible low-frequency clock sources. 29 | type LFCLKS uint8 30 | 31 | const ( 32 | LFCLKRC LFCLKS = 0 // RC oscillator. 33 | LFCLKXTAL LFCLKS = 1 // crystal oscillator. 34 | LFCLKSYNTH LFCLKS = 2 // synthesized from HFCLK. 35 | ) 36 | 37 | // LFCLKC represents configuration of low-frequency clock. 38 | type LFCLKC struct { 39 | Source LFCLKS // clock source 40 | CalInt uint8 // RC oscilator calibration interval in 1/4 second units 41 | CalTempInt uint8 // how often calibrate RC oscilator if temp. has changed 42 | Accuracy LFCLKA // external clock accuracy 43 | } 44 | 45 | var sdfh func(id, pc, info uint32) 46 | 47 | func EnableSoftdevice(lfclkc *LFCLKC, faultHandler func(id, pc, info uint32)) error { 48 | sdfh = faultHandler 49 | return mkerr(enableSoftdevice(lfclkc)) 50 | } 51 | 52 | func DisableSoftdevice() error { 53 | return mkerr(disableSoftdevice()) 54 | } 55 | 56 | func SoftdeviceEnabled() (en bool, err error) { 57 | e := softdeviceEnabled(&en) 58 | return en, mkerr(e) 59 | } 60 | 61 | func SetSoftdeviceVectorTableBase(addr unsafe.Pointer) error { 62 | return mkerr(setSoftdeviceVectorTableBase(addr)) 63 | } 64 | -------------------------------------------------------------------------------- /softdevice/s140/sd/sdm/svc.go: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | package sdm 7 | 8 | import "unsafe" 9 | 10 | //go:noescape 11 | func enableSoftdevice(lfclkc *LFCLKC) uint32 12 | 13 | func disableSoftdevice() uint32 14 | 15 | //go:noescape 16 | func softdeviceEnabled(en *bool) uint32 17 | 18 | //escape 19 | func setSoftdeviceVectorTableBase(addr unsafe.Pointer) uint32 20 | -------------------------------------------------------------------------------- /softdevice/s140/sd/sdm/svc.s: -------------------------------------------------------------------------------- 1 | // Based on C code by Nordic Semiconductor ASA. 2 | // See LICENSE-NORDIC for original C code license. 3 | 4 | // Copyright 2020 Michal Derkacz. 5 | 6 | #include "textflag.h" 7 | 8 | #define SVC_BASE 0x10 9 | 10 | #define SOFTDEVICE_ENABLE (SVC_BASE + 0) 11 | #define SOFTDEVICE_DISABLE (SVC_BASE + 1) 12 | #define SOFTDEVICE_IS_ENABLED (SVC_BASE + 2) 13 | #define SOFTDEVICE_VECTOR_TABLE_BASE_SET (SVC_BASE + 3) 14 | 15 | TEXT nrfFaultHandler(SB),NOSPLIT|NOFRAME,$0 16 | MOVM.DB.W [R4-R11,R14], (R13) 17 | MOVW $0, R3 18 | MOVM.DB.W [R0-R3], (R13) // id, pc, info, 0 19 | BL runtime·identcurcpu(SB) 20 | MOVW R0, g 21 | MOVW ·sdfh(SB), R11 22 | MOVW (R11), R0 23 | BL (R0) 24 | ADD $4, R13 25 | MOVM.IA.W (R13), [R4-R11,R15] 26 | 27 | 28 | TEXT ·enableSoftdevice(SB),NOSPLIT|NOFRAME,$0 29 | MOVW lfclkc+0(FP), R0 30 | MOVW $nrfFaultHandler(SB), R1 31 | SWI $SOFTDEVICE_ENABLE 32 | MOVW R0, ret+4(FP) 33 | RET 34 | 35 | TEXT ·disableSoftdevice(SB),NOSPLIT|NOFRAME,$0 36 | SWI $SOFTDEVICE_DISABLE 37 | MOVW R0, ret+0(FP) 38 | RET 39 | 40 | TEXT ·softdeviceEnabled(SB),NOSPLIT|NOFRAME,$0 41 | MOVW softdevice_enabled+0(FP), R0 42 | SWI $SOFTDEVICE_IS_ENABLED 43 | MOVW R0, ret+4(FP) 44 | RET 45 | 46 | TEXT ·setSoftdeviceVectorTableBase(SB),NOSPLIT|NOFRAME,$0 47 | MOVW address+0(FP), R0 48 | SWI $SOFTDEVICE_VECTOR_TABLE_BASE_SET 49 | MOVW R0, ret+4(FP) 50 | RET 51 | -------------------------------------------------------------------------------- /softdevice/sdutil/advdata.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package sdutil 6 | 7 | import ( 8 | "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble" 9 | "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble/gap" 10 | ) 11 | 12 | type AdvData struct { 13 | buf []byte 14 | } 15 | 16 | func NewAdvData(maxLen int) *AdvData { 17 | return &AdvData{make([]byte, 0, maxLen)} 18 | } 19 | 20 | func (d *AdvData) Data() ble.Data { 21 | return ble.DataBytes(d.buf) 22 | } 23 | 24 | func (d *AdvData) Reset() { 25 | d.buf = d.buf[:0] 26 | } 27 | 28 | func (d *AdvData) AppendBytes(t gap.AdvDataType, b ...byte) { 29 | n := 1 + len(b) 30 | i := len(d.buf) 31 | newLen := i + n + 1 32 | if newLen > cap(d.buf) { 33 | panic("BLE data too long") 34 | } 35 | d.buf = d.buf[:newLen] 36 | d.buf[i] = byte(n) 37 | d.buf[i+1] = byte(t) 38 | copy(d.buf[i+2:], b) 39 | } 40 | 41 | func (d *AdvData) AppendString(t gap.AdvDataType, s string) { 42 | d.AppendBytes(t, []byte(s)...) 43 | } 44 | 45 | func (d *AdvData) AppendUUIDs(t gap.AdvDataType, size int, uuids ...*ble.UUID) { 46 | n := 0 47 | for _, uuid := range uuids { 48 | m, err := ble.EncodeUUID(uuid, nil) 49 | if err != nil { 50 | panic(err.Error()) 51 | } 52 | if m == size { 53 | n += m 54 | } 55 | } 56 | if n == 0 { 57 | return 58 | } 59 | n += 1 60 | i := len(d.buf) 61 | newLen := i + n + 1 62 | if newLen > cap(d.buf) { 63 | panic("BLE data too long") 64 | } 65 | d.buf = d.buf[:newLen] 66 | d.buf[i] = byte(n) 67 | d.buf[i+1] = byte(t) 68 | i += 2 69 | for _, uuid := range uuids { 70 | if m, _ := ble.EncodeUUID(uuid, nil); m != size { 71 | continue 72 | } 73 | m, _ := ble.EncodeUUID(uuid, d.buf[i:]) 74 | i += m 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /softdevice/sdutil/event.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package sdutil 6 | 7 | import ( 8 | "errors" 9 | "unsafe" 10 | 11 | "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble" 12 | "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble/gap" 13 | "github.com/embeddedgo/nrf5/softdevice/s140/sd/ble/gatt/gatts" 14 | ) 15 | 16 | //func bleEvtWordsMax(attmtu int) int { 17 | // bytes := 12 + (attmtu-1)/4*8 // based on BLE_EVT_LEN_MAX(ATT_MTU) 18 | // return (bytes + 3) / 4 19 | //} 20 | 21 | // NextEvent returns next available softdevice event. Internally it calls 22 | // ble.GetEvt twice: first to determine the event size and next to dequeue it. 23 | // For this reason it cannot be used concurently by multiple gorutines. 24 | func NextEvent() (Event, error) { 25 | n, err := ble.GetEvt(nil) 26 | if err != nil { 27 | return nil, err 28 | } 29 | if n < 6 { 30 | return nil, errors.New("sdutil: event too short") 31 | } 32 | buf := make([]uint32, (n+3)/4) 33 | n, err = ble.GetEvt(buf) 34 | if err != nil { 35 | return nil, err 36 | } 37 | p := unsafe.Pointer(&buf[0]) 38 | //print("\n[ ") 39 | //for _, b := range (*[1 << 16]byte)(p)[:n] { 40 | // print(b) 41 | // print(" ") 42 | //} 43 | //print("]\n") 44 | hdr := (*ble.EvtHdr)(p) 45 | if uintptr(hdr.Len) != n { 46 | return nil, errors.New("sdutil: bad event data size") 47 | } 48 | switch { 49 | case ble.EvtBase <= hdr.ID && hdr.ID <= ble.EvtLast: 50 | switch hdr.ID { 51 | case ble.EvtUserMemReq: 52 | return (*ble.UserMemReq)(p), nil 53 | case ble.EvtUserMemRelease: 54 | return (*ble.UserMemRelease)(p), nil 55 | } 56 | case gap.EvtBase <= hdr.ID && hdr.ID <= gap.EvtLast: 57 | switch hdr.ID { 58 | case gap.EvtConnected: 59 | return (*gap.Connected)(p), nil 60 | case gap.EvtDisconnected: 61 | return (*gap.Disconnected)(p), nil 62 | case gap.EvtConnParamUpdate: 63 | return (*gap.ConnParamUpdate)(p), nil 64 | case gap.EvtDataLengthUpdateReq: 65 | return (*gap.DataLengthUpdateReq)(p), nil 66 | } 67 | case gatts.EvtBase <= hdr.ID && hdr.ID <= gatts.EvtLast: 68 | switch hdr.ID { 69 | case gatts.EvtWrite: 70 | return (*gatts.Write)(p), nil 71 | } 72 | } 73 | return hdr, nil // unknown event 74 | } 75 | 76 | type Event interface { 77 | EventID() uint16 78 | } 79 | -------------------------------------------------------------------------------- /softdevice/sdutil/rambase.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. All rights reserved. 2 | 3 | package sdutil 4 | 5 | func AppRAMBase() uintptr 6 | -------------------------------------------------------------------------------- /softdevice/sdutil/rambase.s: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Michal Derkacz. All rights reserved. 2 | 3 | #include "textflag.h" 4 | 5 | TEXT ·AppRAMBase(SB),NOSPLIT|NOFRAME,$0 6 | MOVW $runtime·ramstart(SB), R0 7 | MOVW R0, ret+0(FP) 8 | RET 9 | -------------------------------------------------------------------------------- /svd/_gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd ../../../embeddedgo/nrf5/hal1 6 | hal=$(pwd) 7 | cd ../p 8 | rm -rf * 9 | 10 | svdxgen github.com/embeddedgo/nrf5/p ../svd/*.svd 11 | 12 | perlscript=' 13 | s/\)/"github.com\/embeddedgo\/nrf5\/hal\/periph"\n)/; 14 | 15 | s/type (TASK_|EVENT_|PSEL_|INTEN|EVTEN)\w* uint32//sg; 16 | 17 | s/type RM?(TASK_|EVENT_|PSEL_|INTEN|EVTEN)\w* .*? }//sg; 18 | 19 | s/func \(rm? \*?RM?(TASK_|EVENT_|PSEL_|INTEN|EVTEN)\w*\) .*?}//sg; 20 | 21 | s/(\s|\])RTASK_\w+/\1periph.Task/g; 22 | 23 | s/(\s|\])REVENT_\w+/\1periph.Event/g; 24 | 25 | s/(\s|\])RPSEL_\w+/\1periph.$ENV{signal}/g; 26 | 27 | s/\sPSEL_/ SIG_/g; 28 | 29 | if ( m/INTENSET/ ) { 30 | s/\(/(\n"embedded\/rtos"/; 31 | 32 | s/\sINTENSET\s+RINTENSET/ INT periph.Events/g; 33 | 34 | s/\sINTENCLR\s+RINTENCLR\n//g; 35 | 36 | s/$/\n 37 | func (p *Periph) IRQ() rtos.IRQ { 38 | return rtos.IRQ(uintptr(unsafe.Pointer(p))>>12 & 0x1FF) 39 | } 40 | /s; 41 | } 42 | 43 | if ( m/EVTENSET/ ) { 44 | s/\sEVTENSET\s+REVTENSET/ EVT periph.Events/g; 45 | 46 | s/\sEVTENCLR\s+REVTENCLR\n//g; 47 | 48 | s/\sEVTEN\s+REVTEN/_ uint32/g; 49 | } 50 | 51 | s/func (\w+)0\(\) \*Periph \{ (.*?) }/func \1(n int) *Periph { 52 | switch n { 53 | case 0: \2/sg; 54 | 55 | s/func \w+(\d)\(\) \*Periph \{ (.*?) }/case \1: \2/sg; 56 | 57 | s/(_BASE\)\)\)\n)\n/\1} 58 | return nil 59 | }\n 60 | /sg; 61 | ' 62 | 63 | for p in ficr gpio nvmc rtc uart uicr; do 64 | cd $p 65 | xgen *.go 66 | GOOS=noos GOARCH=thumb go build -tags nrf52840 67 | if [ $p != gpio -a $p != ppi ]; then 68 | mkdir -p $hal/$p 69 | for f in *.go; do cp -f $f $hal/$p/periph-$f; done 70 | signal=Digital 71 | signal=$signal perl -0pi -e "$perlscript" $hal/$p/periph-x*.go 72 | gofmt -w $hal/$p/periph-x*.go 73 | fi 74 | cd .. 75 | done 76 | 77 | perlscript=' 78 | s/package irq/$&\n\nimport "embedded\/rtos"/; 79 | s/ = \d/ rtos.IRQ$&/g; 80 | ' 81 | 82 | cd $hal/irq 83 | rm -f * 84 | cp ../../p/irq/* . 85 | perl -pi -e "$perlscript" *.go -------------------------------------------------------------------------------- /svd/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd ../../../embeddedgo/nrf5/hal 6 | hal=$(pwd) 7 | cd ../p 8 | rm -rf * 9 | 10 | svdxgen github.com/embeddedgo/nrf5/p ../svd/*.svd 11 | 12 | for p in ficr gpio nvmc ppi rtc spi uart uarte uicr; do 13 | cd $p 14 | xgen *.go 15 | GOOS=noos GOARCH=thumb go build -tags nrf52840 16 | cd .. 17 | done 18 | 19 | perlscript=' 20 | s/package irq/$&\n\nimport "embedded\/rtos"/; 21 | s/ = \d/ rtos.IRQ$&/g; 22 | ' 23 | 24 | cd $hal/irq 25 | rm -f * 26 | cp ../../p/irq/* . 27 | perl -pi -e "$perlscript" *.go --------------------------------------------------------------------------------