├── .gitattributes ├── .github └── workflows │ ├── linux.yml │ ├── macos.yml │ └── windows.yml ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── adapter.go ├── adapter_cyw43439.go ├── adapter_darwin.go ├── adapter_hci.go ├── adapter_hci_uart.go ├── adapter_linux.go ├── adapter_ninafw.go ├── adapter_nrf51.go ├── adapter_nrf528xx-full.go ├── adapter_nrf528xx-peripheral.go ├── adapter_nrf528xx.go ├── adapter_s110.go ├── adapter_s113v7.go ├── adapter_s132.go ├── adapter_s140v6.go ├── adapter_s140v7.go ├── adapter_sd.go ├── adapter_windows.go ├── att_hci.go ├── bluetooth.go ├── characteristic_uuids.go ├── debug.go ├── error_sd.go ├── examples ├── advertisement │ └── main.go ├── battery │ └── main.go ├── beacon │ └── main.go ├── circuitplay │ └── main.go ├── connparams │ └── main.go ├── device-information │ └── main.go ├── discover │ ├── main.go │ ├── mcu.go │ └── os.go ├── heartrate-monitor │ ├── main.go │ ├── mcu.go │ └── os.go ├── heartrate │ └── main.go ├── ledcolor │ └── main.go ├── nusclient │ └── main.go ├── nusserver │ └── main.go ├── scanner │ └── main.go ├── stop-advertisement │ └── main.go └── tinyscan │ ├── badger2040w.go │ ├── clue.go │ ├── main.go │ ├── pybadge.go │ └── pyportal.go ├── gap.go ├── gap_darwin.go ├── gap_hci.go ├── gap_linux.go ├── gap_nrf51.go ├── gap_nrf528xx-advertisement.go ├── gap_nrf528xx-central.go ├── gap_sd.go ├── gap_test.go ├── gap_windows.go ├── gattc_darwin.go ├── gattc_hci.go ├── gattc_linux.go ├── gattc_sd.go ├── gattc_windows.go ├── gatts.go ├── gatts_hci.go ├── gatts_linux.go ├── gatts_other.go ├── gatts_sd.go ├── gatts_windows.go ├── go.mod ├── go.sum ├── hci.go ├── hci_cyw43439.go ├── images └── gobluetooth.png ├── l2cap_hci.go ├── mac.go ├── nodebug.go ├── rawterm ├── hosted.go └── nrf.go ├── s110_nrf51_8.0.0 ├── s110_nrf51_8.0.0_API │ └── include │ │ ├── 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 │ │ ├── nrf_error.h │ │ ├── nrf_error_sdm.h │ │ ├── nrf_error_soc.h │ │ ├── nrf_mbr.h │ │ ├── nrf_sdm.h │ │ ├── nrf_soc.h │ │ ├── nrf_svc.h │ │ └── softdevice_assert.h ├── s110_nrf51_8.0.0_licence_agreement.txt └── s110_nrf51_8.0.0_softdevice.hex ├── s113_nrf52_7.0.1 ├── s113_nrf52_7.0.1_API │ └── include │ │ ├── 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 ├── s113_nrf52_7.0.1_license-agreement.txt └── s113_nrf52_7.0.1_softdevice.hex ├── s132_nrf52_6.1.1 ├── s132_nrf52_6.1.1_API │ └── include │ │ ├── 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 ├── s132_nrf52_6.1.1_license-agreement.txt └── s132_nrf52_6.1.1_softdevice.hex ├── s140_nrf52_6.1.1 ├── s140_nrf52_6.1.1_API │ └── include │ │ ├── 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 ├── s140_nrf52_6.1.1_license-agreement.txt └── s140_nrf52_6.1.1_softdevice.hex ├── s140_nrf52_7.3.0 ├── s140_nrf52_7.3.0_API │ └── include │ │ ├── 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 ├── s140_nrf52_7.3.0_license-agreement.txt └── s140_nrf52_7.3.0_softdevice.hex ├── service_uuids.go ├── tools ├── gen-characteristic-uuids │ └── main.go └── gen-service-uuids │ └── main.go ├── uuid.go ├── uuid_hci.go ├── uuid_sd.go ├── uuid_test.go └── version.go /.gitattributes: -------------------------------------------------------------------------------- 1 | s132_nrf52_6.1.1/* linguist-vendored 2 | -------------------------------------------------------------------------------- /.github/workflows/linux.yml: -------------------------------------------------------------------------------- 1 | name: Linux 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - dev 8 | - release 9 | workflow_dispatch: 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | container: ghcr.io/tinygo-org/tinygo-dev 15 | steps: 16 | - name: Work around CVE-2022-24765 17 | # We're not on a multi-user machine, so this is safe. 18 | run: git config --global --add safe.directory "$GITHUB_WORKSPACE" 19 | - name: Checkout 20 | uses: actions/checkout@v3 21 | - name: TinyGo version check 22 | run: tinygo version 23 | - name: Run unit tests 24 | run: go test 25 | - name: Run TinyGo smoke tests 26 | run: make smoketest-tinygo 27 | - name: Run Linux smoke tests 28 | run: make smoketest-linux 29 | - name: "Run Windows cross-compiled smoke tests" 30 | run: make smoketest-windows 31 | -------------------------------------------------------------------------------- /.github/workflows/macos.yml: -------------------------------------------------------------------------------- 1 | name: macOS 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - dev 8 | - release 9 | 10 | concurrency: 11 | group: ${{ github.workflow }}-${{ github.ref }} 12 | cancel-in-progress: true 13 | 14 | jobs: 15 | macos-13: 16 | name: macos-13 17 | runs-on: macos-13 18 | steps: 19 | - name: Install Go 20 | uses: actions/setup-go@v5 21 | with: 22 | go-version: '1.21' 23 | - name: Checkout 24 | uses: actions/checkout@v4 25 | - name: Run unit tests 26 | run: go test 27 | - name: "Run macOS smoke tests" 28 | run: make smoketest-macos 29 | 30 | macos-14: 31 | name: macos-14 32 | runs-on: macos-14 33 | steps: 34 | - name: Install Go 35 | uses: actions/setup-go@v5 36 | with: 37 | go-version: '1.23' 38 | - name: Checkout 39 | uses: actions/checkout@v4 40 | - name: Run unit tests 41 | run: go test 42 | - name: "Run macOS smoke tests" 43 | run: make smoketest-macos 44 | -------------------------------------------------------------------------------- /.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: Windows 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - dev 8 | - release 9 | 10 | jobs: 11 | build-windows: 12 | name: build-windows 13 | runs-on: windows-2022 14 | steps: 15 | - name: Install Go 16 | uses: actions/setup-go@v4.1.0 17 | with: 18 | go-version: '1.21.0' 19 | - name: Checkout 20 | uses: actions/checkout@v3.6.0 21 | - name: Run unit tests 22 | run: go test 23 | - name: "Run Windows smoke tests" 24 | run: make smoketest-windows 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | test.hex 2 | test.uf2 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "bluetooth-numbers-database"] 2 | path = bluetooth-numbers-database 3 | url = https://github.com/NordicSemiconductor/bluetooth-numbers-database.git 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | Thank you for your interest in improving the Go Bluetooth module. 4 | 5 | We would like your help to make this project better, so we appreciate any contributions. See if one of the following descriptions matches your situation: 6 | 7 | ### New to Bluetooth Programming 8 | 9 | We'd love to get your feedback on getting started with the Go Bluetooth. Run into any difficulty, confusion, or anything else? You are not alone. We want to know about your experience, so we can help the next people. Please open a Github issue with your questions, or you can also get in touch directly with us on our Slack channel at [https://gophers.slack.com/messages/CDJD3SUP6](https://gophers.slack.com/messages/CDJD3SUP6). 10 | 11 | ### Something in the Go Bluetooth package is not working as you expect 12 | 13 | Please open a Github issue with your problem, and we will be happy to assist. 14 | 15 | ### Something related to Bluetooth programming that you want/need does not appear to be in Go Bluetooth 16 | 17 | We probably have not implemented it yet. Your pull request adding the functionality would be greatly appreciated. 18 | 19 | Please open a Github issue. We want to help, and also make sure that there is no duplications of efforts. Sometimes what you need is already being worked on by someone else. 20 | 21 | If your contribution includes a new API (one that does not exist yet for any BLE stack), please make sure it is portable: 22 | 23 | * Ideally, add support for it to two different Bluetooth APIs at the same time, for example CoreBluetooth and BlueZ. 24 | * If you are unable to do so, please explain (with links to documentation!) why this feature also fits a different API. 25 | 26 | ## How to use our Github repository 27 | 28 | The `release` branch of this repo will always have the latest released version of the Go Bluetooth module. All of the active development work for the next release will take place in the `dev` branch. The Go Bluetooth module will use semantic versioning and will create a tag/release for each release. 29 | 30 | Here is how to contribute back some code or documentation: 31 | 32 | - Fork repo 33 | - Create a feature branch off of the `dev` branch 34 | - Make some useful change 35 | - Make sure the tests still pass 36 | - Submit a pull request against the `dev` branch. 37 | - Be kind 38 | 39 | ## How to run tests 40 | 41 | To run the bare metal tests: 42 | 43 | ``` 44 | make smoketest-tinygo 45 | ``` 46 | 47 | To run tests for a specific operating system: 48 | 49 | ``` 50 | make smoketest-linux 51 | ``` 52 | 53 | or 54 | 55 | ``` 56 | make smoketest-macos 57 | ``` 58 | 59 | or 60 | 61 | ``` 62 | make smoketest-windows 63 | ``` 64 | 65 | You should be able to run the tests for your own operating system. Note that cross-compilation may or may not work, depending on which tools you have installed. 66 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019-2025 TinyGo 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 | 29 | TinyGo Bluetooth includes data files from the Nordic Semiconductor Bluetooth 30 | Numbers Database (https://github.com/NordicSemiconductor/bluetooth-numbers-database). 31 | Copyright (c) 2019 - 2020, Nordic Semiconductor ASA. All rights reserved. 32 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | TINYGO=tinygo 3 | 4 | smoketest: smoketest-tinygo smoketest-linux smoketest-windows 5 | 6 | smoketest-tinygo: 7 | # Test all examples (and some boards) 8 | $(TINYGO) build -o test.hex -size=short -target=pca10040-s132v6 ./examples/advertisement 9 | @md5sum test.hex 10 | $(TINYGO) build -o test.uf2 -size=short -target=circuitplay-bluefruit ./examples/advertisement 11 | @md5sum test.hex 12 | $(TINYGO) build -o test.uf2 -size=short -target=circuitplay-bluefruit ./examples/circuitplay 13 | @md5sum test.hex 14 | $(TINYGO) build -o test.hex -size=short -target=circuitplay-bluefruit ./examples/connparams 15 | @md5sum test.hex 16 | $(TINYGO) build -o test.uf2 -size=short -target=circuitplay-bluefruit ./examples/discover 17 | @md5sum test.hex 18 | $(TINYGO) build -o test.hex -size=short -target=pca10040-s132v6 ./examples/heartrate 19 | @md5sum test.hex 20 | $(TINYGO) build -o test.hex -size=short -target=reelboard-s140v7 ./examples/ledcolor 21 | @md5sum test.hex 22 | $(TINYGO) build -o test.hex -size=short -target=pca10040-s132v6 ./examples/nusclient 23 | @md5sum test.hex 24 | $(TINYGO) build -o test.hex -size=short -target=pca10040-s132v6 ./examples/nusserver 25 | @md5sum test.hex 26 | $(TINYGO) build -o test.hex -size=short -target=pca10040-s132v6 ./examples/scanner 27 | @md5sum test.hex 28 | $(TINYGO) build -o test.hex -size=short -target=pca10040-s132v6 ./examples/stop-advertisement 29 | @md5sum test.hex 30 | # Test some more boards that are not tested above. 31 | $(TINYGO) build -o test.hex -size=short -target=pca10056-s140v7 ./examples/advertisement 32 | @md5sum test.hex 33 | $(TINYGO) build -o test.hex -size=short -target=microbit-s110v8 ./examples/nusserver 34 | @md5sum test.hex 35 | $(TINYGO) build -o test.hex -size=short -target=microbit-v2-s113v7 ./examples/nusserver 36 | @md5sum test.hex 37 | $(TINYGO) build -o test.uf2 -size=short -target=nano-rp2040 ./examples/discover 38 | @md5sum test.hex 39 | $(TINYGO) build -o test.uf2 -size=short -target=arduino-nano33 ./examples/discover 40 | @md5sum test.hex 41 | $(TINYGO) build -o test.uf2 -size=short -target=pyportal ./examples/discover 42 | @md5sum test.hex 43 | $(TINYGO) build -o test.uf2 -size=short -target=nano-rp2040 ./examples/advertisement 44 | @md5sum test.hex 45 | $(TINYGO) build -o test.uf2 -size=short -target=circuitplay-express -tags="hci hci_uart" ./examples/advertisement 46 | @md5sum test.hex 47 | $(TINYGO) build -o test.uf2 -size=short -target=pico-w ./examples/discover 48 | @md5sum test.hex 49 | $(TINYGO) build -o test.uf2 -size=short -target=badger2040-w ./examples/advertisement 50 | @md5sum test.hex 51 | 52 | smoketest-linux: 53 | # Test on Linux. 54 | GOOS=linux go build -o /tmp/go-build-discard ./examples/advertisement 55 | GOOS=linux go build -o /tmp/go-build-discard ./examples/connparams 56 | GOOS=linux go build -o /tmp/go-build-discard ./examples/heartrate 57 | GOOS=linux go build -o /tmp/go-build-discard ./examples/heartrate-monitor 58 | GOOS=linux go build -o /tmp/go-build-discard ./examples/nusserver 59 | GOOS=linux go build -o /tmp/go-build-discard ./examples/scanner 60 | GOOS=linux go build -o /tmp/go-build-discard ./examples/discover 61 | 62 | smoketest-windows: 63 | # Test on Windows. 64 | GOOS=windows go build -o /tmp/go-build-discard ./examples/scanner 65 | GOOS=windows go build -o /tmp/go-build-discard ./examples/discover 66 | GOOS=windows go build -o /tmp/go-build-discard ./examples/heartrate-monitor 67 | GOOS=windows go build -o /tmp/go-build-discard ./examples/advertisement 68 | GOOS=windows go build -o /tmp/go-build-discard ./examples/heartrate 69 | 70 | smoketest-macos: 71 | # Test on macos. 72 | GOOS=darwin CGO_ENABLED=1 go build -o /tmp/go-build-discard ./examples/scanner 73 | GOOS=darwin CGO_ENABLED=1 go build -o /tmp/go-build-discard ./examples/discover 74 | GOOS=darwin CGO_ENABLED=1 go build -o /tmp/go-build-discard ./examples/nusclient 75 | GOOS=darwin CGO_ENABLED=1 go build -o /tmp/go-build-discard ./examples/heartrate-monitor 76 | 77 | gen-uuids: 78 | # generate the standard service and characteristic UUIDs 79 | go run ./tools/gen-service-uuids/main.go 80 | go run ./tools/gen-characteristic-uuids/main.go 81 | -------------------------------------------------------------------------------- /adapter.go: -------------------------------------------------------------------------------- 1 | package bluetooth 2 | 3 | // SetConnectHandler sets a handler function to be called whenever the adaptor connects 4 | // or disconnects. You must call this before you call adaptor.Connect() for centrals 5 | // or adaptor.Start() for peripherals in order for it to work. 6 | func (a *Adapter) SetConnectHandler(c func(device Device, connected bool)) { 7 | a.connectHandler = c 8 | } 9 | -------------------------------------------------------------------------------- /adapter_cyw43439.go: -------------------------------------------------------------------------------- 1 | //go:build cyw43439 2 | 3 | package bluetooth 4 | 5 | import ( 6 | "machine" 7 | 8 | "log/slog" 9 | 10 | "github.com/soypat/cyw43439" 11 | ) 12 | 13 | const maxConnections = 1 14 | 15 | // Adapter represents a SPI connection to the HCI controller on an attached CYW4349 module. 16 | type Adapter struct { 17 | hciAdapter 18 | } 19 | 20 | // DefaultAdapter is the default adapter on the current system. 21 | // 22 | // Make sure to call Enable() before using it to initialize the adapter. 23 | var DefaultAdapter = &Adapter{ 24 | hciAdapter: hciAdapter{ 25 | isDefault: true, 26 | connectHandler: func(device Device, connected bool) { 27 | return 28 | }, 29 | connectedDevices: make([]Device, 0, maxConnections), 30 | }, 31 | } 32 | 33 | // Enable configures the BLE stack. It must be called before any 34 | // Bluetooth-related calls (unless otherwise indicated). 35 | func (a *Adapter) Enable() error { 36 | if debug { 37 | println("Initializing CYW43439 device") 38 | } 39 | 40 | dev := cyw43439.NewPicoWDevice() 41 | cfg := cyw43439.DefaultBluetoothConfig() 42 | if debug { 43 | cfg.Logger = slog.New(slog.NewTextHandler(machine.USBCDC, &slog.HandlerOptions{ 44 | Level: slog.LevelDebug - 2, 45 | })) 46 | } 47 | 48 | err := dev.Init(cfg) 49 | if err != nil { 50 | if debug { 51 | println("Error initializing CYW43439 device", err.Error()) 52 | } 53 | return err 54 | } 55 | 56 | transport := &hciSPI{dev: dev} 57 | 58 | a.hci, a.att = newBLEStack(transport) 59 | if debug { 60 | println("Enabling CYW43439 device") 61 | } 62 | 63 | a.enable() 64 | 65 | if debug { 66 | println("Enabled CYW43439 device") 67 | } 68 | 69 | return nil 70 | } 71 | 72 | type hciSPI struct { 73 | dev *cyw43439.Device 74 | } 75 | 76 | func (h *hciSPI) startRead() { 77 | } 78 | 79 | func (h *hciSPI) endRead() { 80 | } 81 | 82 | func (h *hciSPI) Buffered() int { 83 | return h.dev.BufferedHCI() 84 | } 85 | 86 | func (h *hciSPI) ReadByte() (byte, error) { 87 | var buf [1]byte 88 | 89 | r, err := h.dev.HCIReadWriter() 90 | if err != nil { 91 | return 0, err 92 | } 93 | if _, err := r.Read(buf[:]); err != nil { 94 | return 0, err 95 | } 96 | 97 | return buf[0], nil 98 | } 99 | 100 | func (h *hciSPI) Read(buf []byte) (int, error) { 101 | r, err := h.dev.HCIReadWriter() 102 | if err != nil { 103 | return 0, err 104 | } 105 | 106 | return r.Read(buf) 107 | } 108 | 109 | func (h *hciSPI) Write(buf []byte) (int, error) { 110 | w, err := h.dev.HCIReadWriter() 111 | if err != nil { 112 | return 0, err 113 | } 114 | 115 | return w.Write(buf) 116 | } 117 | -------------------------------------------------------------------------------- /adapter_hci_uart.go: -------------------------------------------------------------------------------- 1 | //go:build hci && hci_uart 2 | 3 | package bluetooth 4 | 5 | import ( 6 | "machine" 7 | ) 8 | 9 | const maxConnections = 1 10 | 11 | // Adapter represents a "plain" UART connection to the HCI controller. 12 | type Adapter struct { 13 | hciAdapter 14 | 15 | uart *machine.UART 16 | 17 | // used for software flow control 18 | cts, rts machine.Pin 19 | } 20 | 21 | // DefaultAdapter is the default adapter on the current system. 22 | // 23 | // Make sure to call Enable() before using it to initialize the adapter. 24 | var DefaultAdapter = &Adapter{ 25 | hciAdapter: hciAdapter{ 26 | isDefault: true, 27 | connectHandler: func(device Device, connected bool) { 28 | return 29 | }, 30 | connectedDevices: make([]Device, 0, maxConnections), 31 | }, 32 | } 33 | 34 | // SetUART sets the UART to use for the HCI connection. 35 | // It must be called before calling Enable(). 36 | // Note that the UART must be configured with hardware flow control, or 37 | // SetSoftwareFlowControl() must be called. 38 | func (a *Adapter) SetUART(uart *machine.UART) error { 39 | a.uart = uart 40 | 41 | return nil 42 | } 43 | 44 | // SetSoftwareFlowControl sets the pins to use for software flow control, 45 | // if hardware flow control is not available. 46 | func (a *Adapter) SetSoftwareFlowControl(cts, rts machine.Pin) error { 47 | a.cts = cts 48 | a.rts = rts 49 | 50 | return nil 51 | } 52 | 53 | // Enable configures the BLE stack. It must be called before any 54 | // Bluetooth-related calls (unless otherwise indicated). 55 | func (a *Adapter) Enable() error { 56 | transport := &hciUART{uart: a.uart} 57 | if a.cts != 0 && a.rts != 0 { 58 | transport.rts = a.rts 59 | a.rts.Configure(machine.PinConfig{Mode: machine.PinOutput}) 60 | a.rts.High() 61 | 62 | transport.cts = a.cts 63 | a.cts.Configure(machine.PinConfig{Mode: machine.PinInput}) 64 | } 65 | 66 | a.hci, a.att = newBLEStack(transport) 67 | a.enable() 68 | 69 | return nil 70 | } 71 | 72 | type hciUART struct { 73 | uart *machine.UART 74 | 75 | // used for software flow control 76 | cts, rts machine.Pin 77 | } 78 | 79 | func (h *hciUART) startRead() { 80 | if h.rts != machine.NoPin { 81 | h.rts.Low() 82 | } 83 | } 84 | 85 | func (h *hciUART) endRead() { 86 | if h.rts != machine.NoPin { 87 | h.rts.High() 88 | } 89 | } 90 | 91 | func (h *hciUART) Buffered() int { 92 | return h.uart.Buffered() 93 | } 94 | 95 | func (h *hciUART) ReadByte() (byte, error) { 96 | return h.uart.ReadByte() 97 | } 98 | 99 | func (h *hciUART) Read(buf []byte) (int, error) { 100 | return h.uart.Read(buf) 101 | } 102 | 103 | const writeAttempts = 200 104 | 105 | func (h *hciUART) Write(buf []byte) (int, error) { 106 | if h.cts != machine.NoPin { 107 | retries := writeAttempts 108 | for h.cts.Get() { 109 | retries-- 110 | if retries == 0 { 111 | return 0, ErrHCITimeout 112 | } 113 | } 114 | } 115 | 116 | n, err := h.uart.Write(buf) 117 | if err != nil { 118 | return 0, err 119 | } 120 | 121 | return n, nil 122 | } 123 | -------------------------------------------------------------------------------- /adapter_linux.go: -------------------------------------------------------------------------------- 1 | //go:build !baremetal 2 | 3 | // Some documentation for the BlueZ D-Bus interface: 4 | // https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc 5 | 6 | package bluetooth 7 | 8 | import ( 9 | "errors" 10 | "fmt" 11 | 12 | "github.com/godbus/dbus/v5" 13 | ) 14 | 15 | const defaultAdapter = "hci0" 16 | 17 | type Adapter struct { 18 | id string 19 | scanCancelChan chan struct{} 20 | bus *dbus.Conn 21 | bluez dbus.BusObject // object at / 22 | adapter dbus.BusObject // object at /org/bluez/hciX 23 | address string 24 | defaultAdvertisement *Advertisement 25 | 26 | connectHandler func(device Device, connected bool) 27 | } 28 | 29 | // NewAdapter creates a new Adapter with the given ID. 30 | // 31 | // Make sure to call Enable() before using it to initialize the adapter. 32 | func NewAdapter(id string) *Adapter { 33 | return &Adapter{ 34 | id: id, 35 | connectHandler: func(device Device, connected bool) {}, 36 | } 37 | } 38 | 39 | // DefaultAdapter is the default adapter on the system. On Linux, it is the 40 | // first adapter available. 41 | // 42 | // Make sure to call Enable() before using it to initialize the adapter. 43 | var DefaultAdapter = NewAdapter(defaultAdapter) 44 | 45 | // Enable configures the BLE stack. It must be called before any 46 | // Bluetooth-related calls (unless otherwise indicated). 47 | func (a *Adapter) Enable() (err error) { 48 | bus, err := dbus.SystemBus() 49 | if err != nil { 50 | return err 51 | } 52 | a.bus = bus 53 | a.bluez = a.bus.Object("org.bluez", dbus.ObjectPath("/")) 54 | a.adapter = a.bus.Object("org.bluez", dbus.ObjectPath("/org/bluez/"+a.id)) 55 | addr, err := a.adapter.GetProperty("org.bluez.Adapter1.Address") 56 | if err != nil { 57 | if err, ok := err.(dbus.Error); ok && err.Name == "org.freedesktop.DBus.Error.UnknownObject" { 58 | return fmt.Errorf("bluetooth: adapter %s does not exist", a.adapter.Path()) 59 | } 60 | return fmt.Errorf("could not activate BlueZ adapter: %w", err) 61 | } 62 | addr.Store(&a.address) 63 | 64 | return nil 65 | } 66 | 67 | func (a *Adapter) Address() (MACAddress, error) { 68 | if a.address == "" { 69 | return MACAddress{}, errors.New("adapter not enabled") 70 | } 71 | mac, err := ParseMAC(a.address) 72 | if err != nil { 73 | return MACAddress{}, err 74 | } 75 | return MACAddress{MAC: mac}, nil 76 | } 77 | -------------------------------------------------------------------------------- /adapter_ninafw.go: -------------------------------------------------------------------------------- 1 | //go:build ninafw 2 | 3 | package bluetooth 4 | 5 | import ( 6 | "machine" 7 | "time" 8 | ) 9 | 10 | const maxConnections = 1 11 | 12 | // Adapter represents the HCI connection to the NINA fw using the hardware UART. 13 | type Adapter struct { 14 | hciAdapter 15 | } 16 | 17 | // DefaultAdapter is the default adapter on the current system. 18 | // 19 | // Make sure to call Enable() before using it to initialize the adapter. 20 | var DefaultAdapter = &Adapter{ 21 | hciAdapter: hciAdapter{ 22 | isDefault: true, 23 | connectHandler: func(device Device, connected bool) { 24 | return 25 | }, 26 | connectedDevices: make([]Device, 0, maxConnections), 27 | }, 28 | } 29 | 30 | // Enable configures the BLE stack. It must be called before any 31 | // Bluetooth-related calls (unless otherwise indicated). 32 | func (a *Adapter) Enable() error { 33 | // reset the NINA in BLE mode 34 | machine.NINA_CS.Configure(machine.PinConfig{Mode: machine.PinOutput}) 35 | machine.NINA_CS.Low() 36 | 37 | if machine.NINA_RESET_INVERTED { 38 | resetNINAInverted() 39 | } else { 40 | resetNINA() 41 | } 42 | 43 | // serial port for nina chip 44 | uart := machine.UART_NINA 45 | cfg := machine.UARTConfig{ 46 | TX: machine.NINA_TX, 47 | RX: machine.NINA_RX, 48 | BaudRate: machine.NINA_BAUDRATE, 49 | } 50 | if !machine.NINA_SOFT_FLOWCONTROL { 51 | cfg.CTS = machine.NINA_CTS 52 | cfg.RTS = machine.NINA_RTS 53 | } 54 | 55 | uart.Configure(cfg) 56 | 57 | transport := &hciUART{uart: uart} 58 | if machine.NINA_SOFT_FLOWCONTROL { 59 | machine.NINA_RTS.Configure(machine.PinConfig{Mode: machine.PinOutput}) 60 | machine.NINA_RTS.High() 61 | 62 | machine.NINA_CTS.Configure(machine.PinConfig{Mode: machine.PinInput}) 63 | } 64 | 65 | a.hci, a.att = newBLEStack(transport) 66 | return a.enable() 67 | } 68 | 69 | func resetNINA() { 70 | machine.NINA_RESETN.Configure(machine.PinConfig{Mode: machine.PinOutput}) 71 | 72 | machine.NINA_RESETN.High() 73 | time.Sleep(100 * time.Millisecond) 74 | machine.NINA_RESETN.Low() 75 | time.Sleep(1000 * time.Millisecond) 76 | } 77 | 78 | func resetNINAInverted() { 79 | machine.NINA_RESETN.Configure(machine.PinConfig{Mode: machine.PinOutput}) 80 | 81 | machine.NINA_RESETN.Low() 82 | time.Sleep(100 * time.Millisecond) 83 | machine.NINA_RESETN.High() 84 | time.Sleep(1000 * time.Millisecond) 85 | } 86 | 87 | type hciUART struct { 88 | uart *machine.UART 89 | } 90 | 91 | func (h *hciUART) startRead() { 92 | if machine.NINA_SOFT_FLOWCONTROL { 93 | machine.NINA_RTS.Low() 94 | } 95 | } 96 | 97 | func (h *hciUART) endRead() { 98 | if machine.NINA_SOFT_FLOWCONTROL { 99 | machine.NINA_RTS.High() 100 | } 101 | } 102 | 103 | func (h *hciUART) Buffered() int { 104 | return h.uart.Buffered() 105 | } 106 | 107 | func (h *hciUART) ReadByte() (byte, error) { 108 | return h.uart.ReadByte() 109 | } 110 | 111 | func (h *hciUART) Read(buf []byte) (int, error) { 112 | return h.uart.Read(buf) 113 | } 114 | 115 | const writeAttempts = 200 116 | 117 | func (h *hciUART) Write(buf []byte) (int, error) { 118 | if machine.NINA_SOFT_FLOWCONTROL { 119 | retries := writeAttempts 120 | for machine.NINA_CTS.Get() { 121 | retries-- 122 | if retries == 0 { 123 | return 0, ErrHCITimeout 124 | } 125 | } 126 | } 127 | 128 | n, err := h.uart.Write(buf) 129 | if err != nil { 130 | return 0, err 131 | } 132 | 133 | return n, nil 134 | } 135 | -------------------------------------------------------------------------------- /adapter_nrf51.go: -------------------------------------------------------------------------------- 1 | //go:build softdevice && s110v8 2 | 3 | package bluetooth 4 | 5 | /* 6 | #include "nrf_sdm.h" 7 | #include "ble.h" 8 | #include "ble_gap.h" 9 | 10 | void assertHandler(uint32_t pc, uint16_t line_number, const uint8_t * p_file_name); 11 | */ 12 | import "C" 13 | 14 | import "unsafe" 15 | 16 | //export assertHandler 17 | func assertHandler(pc uint32, line_number uint16, p_file_name *byte) { 18 | println("SoftDevice assert") 19 | } 20 | 21 | func (a *Adapter) enable() error { 22 | // Enable the SoftDevice. 23 | errCode := C.sd_softdevice_enable(C.NRF_CLOCK_LFCLKSRC_RC_250_PPM_250MS_CALIBRATION, C.softdevice_assertion_handler_t(C.assertHandler)) 24 | if errCode != 0 { 25 | return Error(errCode) 26 | } 27 | 28 | // Enable the BLE stack. 29 | enableParams := C.ble_enable_params_t{ 30 | gatts_enable_params: C.ble_gatts_enable_params_t{ 31 | attr_tab_size: C.BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, 32 | }, 33 | } 34 | errCode = C.sd_ble_enable(&enableParams) 35 | return makeError(errCode) 36 | } 37 | 38 | func handleEvent() { 39 | id := eventBuf.header.evt_id 40 | switch { 41 | case id >= C.BLE_GAP_EVT_BASE && id <= C.BLE_GAP_EVT_LAST: 42 | gapEvent := eventBuf.evt.unionfield_gap_evt() 43 | switch id { 44 | case C.BLE_GAP_EVT_CONNECTED: 45 | currentConnection.handle.Reg = uint16(gapEvent.conn_handle) 46 | connectEvent := gapEvent.params.unionfield_connected() 47 | device := Device{ 48 | Address: Address{makeMACAddress(connectEvent.peer_addr)}, 49 | connectionHandle: gapEvent.conn_handle, 50 | } 51 | DefaultAdapter.connectHandler(device, true) 52 | case C.BLE_GAP_EVT_DISCONNECTED: 53 | if defaultAdvertisement.isAdvertising.Get() != 0 { 54 | // The advertisement was running but was automatically stopped 55 | // by the connection event. 56 | // Note that it cannot be restarted during connect like this, 57 | // because it would need to be reconfigured as a non-connectable 58 | // advertisement. That's left as a future addition, if 59 | // necessary. 60 | defaultAdvertisement.start() 61 | } 62 | currentConnection.handle.Reg = C.BLE_CONN_HANDLE_INVALID 63 | device := Device{ 64 | connectionHandle: gapEvent.conn_handle, 65 | } 66 | DefaultAdapter.connectHandler(device, false) 67 | case C.BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: 68 | // Respond with the default PPCP connection parameters by passing 69 | // nil: 70 | // > If NULL is provided on a peripheral role, the parameters in the 71 | // > PPCP characteristic of the GAP service will be used instead. If 72 | // > NULL is provided on a central role and in response to a 73 | // > BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request 74 | // > will be rejected 75 | C.sd_ble_gap_conn_param_update(gapEvent.conn_handle, nil) 76 | default: 77 | if debug { 78 | println("unknown GAP event:", id) 79 | } 80 | } 81 | case id >= C.BLE_GATTS_EVT_BASE && id <= C.BLE_GATTS_EVT_LAST: 82 | gattsEvent := eventBuf.evt.unionfield_gatts_evt() 83 | switch id { 84 | case C.BLE_GATTS_EVT_WRITE: 85 | writeEvent := gattsEvent.params.unionfield_write() 86 | len := writeEvent.len - writeEvent.offset 87 | data := (*[255]byte)(unsafe.Pointer(&writeEvent.data[0]))[:len:len] 88 | handler := DefaultAdapter.getCharWriteHandler(writeEvent.handle) 89 | if handler != nil { 90 | handler.callback(Connection(gattsEvent.conn_handle), int(writeEvent.offset), data) 91 | } 92 | case C.BLE_GATTS_EVT_SYS_ATTR_MISSING: 93 | // This event is generated when reading the Generic Attribute 94 | // service. It appears to be necessary for bonded devices. 95 | // From the docs: 96 | // > If the pointer is NULL, the system attribute info is 97 | // > initialized, assuming that the application does not have any 98 | // > previously saved system attribute data for this device. 99 | // Maybe we should look at the error, but as there's not really a 100 | // way to handle it, ignore it. 101 | C.sd_ble_gatts_sys_attr_set(gattsEvent.conn_handle, nil, 0, 0) 102 | default: 103 | if debug { 104 | println("unknown GATTS event:", id, id-C.BLE_GATTS_EVT_BASE) 105 | } 106 | } 107 | default: 108 | if debug { 109 | println("unknown event:", id) 110 | } 111 | } 112 | } 113 | 114 | func (a *Adapter) Address() (MACAddress, error) { 115 | var addr C.ble_gap_addr_t 116 | errCode := C.sd_ble_gap_address_get(&addr) 117 | if errCode != 0 { 118 | return MACAddress{}, Error(errCode) 119 | } 120 | return MACAddress{MAC: makeAddress(addr.addr)}, nil 121 | } 122 | 123 | // Convert a C.ble_gap_addr_t to a MACAddress struct. 124 | func makeMACAddress(addr C.ble_gap_addr_t) MACAddress { 125 | return MACAddress{ 126 | MAC: makeAddress(addr.addr), 127 | isRandom: addr.addr_type != 0, 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /adapter_nrf528xx-peripheral.go: -------------------------------------------------------------------------------- 1 | //go:build softdevice && s113v7 2 | 3 | package bluetooth 4 | 5 | // This file implements the event handler for SoftDevices with only peripheral 6 | // mode support. This includes the S113. 7 | 8 | /* 9 | #include "nrf_sdm.h" 10 | #include "nrf_nvic.h" 11 | #include "ble.h" 12 | #include "ble_gap.h" 13 | */ 14 | import "C" 15 | 16 | import ( 17 | "unsafe" 18 | ) 19 | 20 | func handleEvent() { 21 | id := eventBuf.header.evt_id 22 | switch { 23 | case id >= C.BLE_GAP_EVT_BASE && id <= C.BLE_GAP_EVT_LAST: 24 | gapEvent := eventBuf.evt.unionfield_gap_evt() 25 | switch id { 26 | case C.BLE_GAP_EVT_CONNECTED: 27 | if debug { 28 | println("evt: connected in peripheral role") 29 | } 30 | currentConnection.handle.Reg = uint16(gapEvent.conn_handle) 31 | connectEvent := gapEvent.params.unionfield_connected() 32 | device := Device{ 33 | Address: Address{makeMACAddress(connectEvent.peer_addr)}, 34 | connectionHandle: gapEvent.conn_handle, 35 | } 36 | DefaultAdapter.connectHandler(device, true) 37 | case C.BLE_GAP_EVT_DISCONNECTED: 38 | if debug { 39 | println("evt: disconnected") 40 | } 41 | currentConnection.handle.Reg = C.BLE_CONN_HANDLE_INVALID 42 | // Auto-restart advertisement if needed. 43 | if defaultAdvertisement.isAdvertising.Get() != 0 { 44 | // The advertisement was running but was automatically stopped 45 | // by the connection event. 46 | // Note that it cannot be restarted during connect like this, 47 | // because it would need to be reconfigured as a non-connectable 48 | // advertisement. That's left as a future addition, if 49 | // necessary. 50 | C.sd_ble_gap_adv_start(defaultAdvertisement.handle, C.BLE_CONN_CFG_TAG_DEFAULT) 51 | } 52 | device := Device{ 53 | connectionHandle: gapEvent.conn_handle, 54 | } 55 | DefaultAdapter.connectHandler(device, false) 56 | case C.BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: 57 | // We need to respond with sd_ble_gap_data_length_update. Setting 58 | // both parameters to nil will make sure we send the default values. 59 | C.sd_ble_gap_data_length_update(gapEvent.conn_handle, nil, nil) 60 | case C.BLE_GAP_EVT_DATA_LENGTH_UPDATE: 61 | // ignore confirmation of data length successfully updated 62 | case C.BLE_GAP_EVT_PHY_UPDATE_REQUEST: 63 | phyUpdateRequest := gapEvent.params.unionfield_phy_update_request() 64 | C.sd_ble_gap_phy_update(gapEvent.conn_handle, &phyUpdateRequest.peer_preferred_phys) 65 | case C.BLE_GAP_EVT_PHY_UPDATE: 66 | // ignore confirmation of phy successfully updated 67 | default: 68 | if debug { 69 | println("unknown GAP event:", id) 70 | } 71 | } 72 | case id >= C.BLE_GATTS_EVT_BASE && id <= C.BLE_GATTS_EVT_LAST: 73 | gattsEvent := eventBuf.evt.unionfield_gatts_evt() 74 | switch id { 75 | case C.BLE_GATTS_EVT_WRITE: 76 | writeEvent := gattsEvent.params.unionfield_write() 77 | len := writeEvent.len - writeEvent.offset 78 | data := (*[255]byte)(unsafe.Pointer(&writeEvent.data[0]))[:len:len] 79 | handler := DefaultAdapter.getCharWriteHandler(writeEvent.handle) 80 | if handler != nil { 81 | handler.callback(Connection(gattsEvent.conn_handle), int(writeEvent.offset), data) 82 | } 83 | case C.BLE_GATTS_EVT_SYS_ATTR_MISSING: 84 | // This event is generated when reading the Generic Attribute 85 | // service. It appears to be necessary for bonded devices. 86 | // From the docs: 87 | // > If the pointer is NULL, the system attribute info is 88 | // > initialized, assuming that the application does not have any 89 | // > previously saved system attribute data for this device. 90 | // Maybe we should look at the error, but as there's not really a 91 | // way to handle it, ignore it. 92 | C.sd_ble_gatts_sys_attr_set(gattsEvent.conn_handle, nil, 0, 0) 93 | case C.BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: 94 | // This event is generated by some devices. While we could support 95 | // larger MTUs, this default MTU is supported everywhere. 96 | C.sd_ble_gatts_exchange_mtu_reply(gattsEvent.conn_handle, C.BLE_GATT_ATT_MTU_DEFAULT) 97 | case C.BLE_GATTS_EVT_HVN_TX_COMPLETE: 98 | // ignore confirmation of a notification successfully sent 99 | default: 100 | if debug { 101 | println("unknown GATTS event:", id, id-C.BLE_GATTS_EVT_BASE) 102 | } 103 | } 104 | default: 105 | if debug { 106 | println("unknown event:", id) 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /adapter_nrf528xx.go: -------------------------------------------------------------------------------- 1 | //go:build (softdevice && s113v7) || (softdevice && s132v6) || (softdevice && s140v6) || (softdevice && s140v7) 2 | 3 | package bluetooth 4 | 5 | // This file defines the SoftDevice adapter for all nrf52-series chips. 6 | 7 | /* 8 | #include "nrf_sdm.h" 9 | #include "nrf_nvic.h" 10 | #include "ble.h" 11 | #include "ble_gap.h" 12 | 13 | void assertHandler(void); 14 | */ 15 | import "C" 16 | 17 | import ( 18 | "machine" 19 | "unsafe" 20 | ) 21 | 22 | //export assertHandler 23 | func assertHandler() { 24 | println("SoftDevice assert") 25 | } 26 | 27 | var clockConfigXtal C.nrf_clock_lf_cfg_t = C.nrf_clock_lf_cfg_t{ 28 | source: C.NRF_CLOCK_LF_SRC_XTAL, 29 | rc_ctiv: 0, 30 | rc_temp_ctiv: 0, 31 | accuracy: C.NRF_CLOCK_LF_ACCURACY_250_PPM, 32 | } 33 | 34 | //go:extern __app_ram_base 35 | var appRAMBase [0]uint32 36 | 37 | func (a *Adapter) enable() error { 38 | // Enable the SoftDevice. 39 | var clockConfig *C.nrf_clock_lf_cfg_t 40 | if machine.HasLowFrequencyCrystal { 41 | clockConfig = &clockConfigXtal 42 | } 43 | errCode := C.sd_softdevice_enable(clockConfig, C.nrf_fault_handler_t(C.assertHandler)) 44 | if errCode != 0 { 45 | return Error(errCode) 46 | } 47 | 48 | // Enable the BLE stack. 49 | appRAMBase := C.uint32_t(uintptr(unsafe.Pointer(&appRAMBase))) 50 | errCode = C.sd_ble_enable(&appRAMBase) 51 | return makeError(errCode) 52 | } 53 | 54 | func (a *Adapter) Address() (MACAddress, error) { 55 | var addr C.ble_gap_addr_t 56 | errCode := C.sd_ble_gap_addr_get(&addr) 57 | if errCode != 0 { 58 | return MACAddress{}, Error(errCode) 59 | } 60 | return MACAddress{MAC: makeAddress(addr.addr)}, nil 61 | } 62 | 63 | // Convert a C.ble_gap_addr_t to a MACAddress struct. 64 | func makeMACAddress(addr C.ble_gap_addr_t) MACAddress { 65 | return MACAddress{ 66 | MAC: makeAddress(addr.addr), 67 | isRandom: addr.bitfield_addr_type() != 0, 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /adapter_s110.go: -------------------------------------------------------------------------------- 1 | //go:build softdevice && s110v8 2 | 3 | package bluetooth 4 | 5 | /* 6 | // Add the correct SoftDevice include path to CFLAGS, so #include will work as 7 | // expected. 8 | #cgo CFLAGS: -Is110_nrf51_8.0.0/s110_nrf51_8.0.0_API/include 9 | */ 10 | import "C" 11 | -------------------------------------------------------------------------------- /adapter_s113v7.go: -------------------------------------------------------------------------------- 1 | //go:build softdevice && s113v7 2 | 3 | package bluetooth 4 | 5 | /* 6 | // Add the correct SoftDevice include path to CFLAGS, so #include will work as 7 | // expected. 8 | #cgo CFLAGS: -Is113_nrf52_7.0.1/s113_nrf52_7.0.1_API/include 9 | 10 | #include "nrf_nvic.h" 11 | nrf_nvic_state_t nrf_nvic_state = {0}; 12 | */ 13 | import "C" 14 | -------------------------------------------------------------------------------- /adapter_s132.go: -------------------------------------------------------------------------------- 1 | //go:build softdevice && s132v6 2 | 3 | package bluetooth 4 | 5 | /* 6 | // Add the correct SoftDevice include path to CFLAGS, so #include will work as 7 | // expected. 8 | #cgo CFLAGS: -Is132_nrf52_6.1.1/s132_nrf52_6.1.1_API/include 9 | 10 | #include "nrf_nvic.h" 11 | nrf_nvic_state_t nrf_nvic_state = {0}; 12 | */ 13 | import "C" 14 | -------------------------------------------------------------------------------- /adapter_s140v6.go: -------------------------------------------------------------------------------- 1 | //go:build softdevice && s140v6 2 | 3 | package bluetooth 4 | 5 | /* 6 | // Add the correct SoftDevice include path to CFLAGS, so #include will work as 7 | // expected. 8 | #cgo CFLAGS: -Is140_nrf52_6.1.1/s140_nrf52_6.1.1_API/include 9 | 10 | #include "nrf_nvic.h" 11 | nrf_nvic_state_t nrf_nvic_state = {0}; 12 | */ 13 | import "C" 14 | -------------------------------------------------------------------------------- /adapter_s140v7.go: -------------------------------------------------------------------------------- 1 | //go:build softdevice && s140v7 2 | 3 | package bluetooth 4 | 5 | /* 6 | // Add the correct SoftDevice include path to CFLAGS, so #include will work as 7 | // expected. 8 | #cgo CFLAGS: -Is140_nrf52_7.3.0/s140_nrf52_7.3.0_API/include 9 | 10 | #include "nrf_nvic.h" 11 | nrf_nvic_state_t nrf_nvic_state = {0}; 12 | */ 13 | import "C" 14 | -------------------------------------------------------------------------------- /adapter_windows.go: -------------------------------------------------------------------------------- 1 | package bluetooth 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | 7 | "github.com/go-ole/go-ole" 8 | "github.com/saltosystems/winrt-go" 9 | "github.com/saltosystems/winrt-go/windows/devices/bluetooth/advertisement" 10 | "github.com/saltosystems/winrt-go/windows/foundation" 11 | ) 12 | 13 | type Adapter struct { 14 | watcher *advertisement.BluetoothLEAdvertisementWatcher 15 | 16 | connectHandler func(device Device, connected bool) 17 | 18 | defaultAdvertisement *Advertisement 19 | } 20 | 21 | // DefaultAdapter is the default adapter on the system. 22 | // 23 | // Make sure to call Enable() before using it to initialize the adapter. 24 | var DefaultAdapter = &Adapter{ 25 | connectHandler: func(device Device, connected bool) { 26 | return 27 | }, 28 | } 29 | 30 | // Enable configures the BLE stack. It must be called before any 31 | // Bluetooth-related calls (unless otherwise indicated). 32 | func (a *Adapter) Enable() error { 33 | return ole.RoInitialize(1) // initialize with multithreading enabled 34 | } 35 | 36 | func awaitAsyncOperation(asyncOperation *foundation.IAsyncOperation, genericParamSignature string) error { 37 | var status foundation.AsyncStatus 38 | 39 | // We need to obtain the GUID of the AsyncOperationCompletedHandler, but its a generic delegate 40 | // so we also need the generic parameter type's signature: 41 | // AsyncOperationCompletedHandler 42 | iid := winrt.ParameterizedInstanceGUID(foundation.GUIDAsyncOperationCompletedHandler, genericParamSignature) 43 | 44 | // Wait until the async operation completes. 45 | waitChan := make(chan struct{}) 46 | handler := foundation.NewAsyncOperationCompletedHandler(ole.NewGUID(iid), func(instance *foundation.AsyncOperationCompletedHandler, asyncInfo *foundation.IAsyncOperation, asyncStatus foundation.AsyncStatus) { 47 | status = asyncStatus 48 | close(waitChan) 49 | }) 50 | defer handler.Release() 51 | 52 | asyncOperation.SetCompleted(handler) 53 | 54 | // Wait until async operation has stopped, and finish. 55 | <-waitChan 56 | 57 | if status != foundation.AsyncStatusCompleted { 58 | return fmt.Errorf("async operation failed with status %d", status) 59 | } 60 | return nil 61 | } 62 | 63 | func (a *Adapter) Address() (MACAddress, error) { 64 | // TODO: get mac address 65 | return MACAddress{}, errors.New("not implemented") 66 | } 67 | -------------------------------------------------------------------------------- /bluetooth.go: -------------------------------------------------------------------------------- 1 | // Package bluetooth provides a cross-platform Bluetooth module for Go 2 | // that can be used on operating systems such as Linux, macOS, and Windows. 3 | // 4 | // It can also be used running "bare metal" on microcontrollers such as 5 | // those produced by Nordic Semiconductor. 6 | // 7 | // This package can be use to create Bluetooth Low Energy centrals as well as peripherals. 8 | package bluetooth // import "tinygo.org/x/bluetooth" 9 | -------------------------------------------------------------------------------- /debug.go: -------------------------------------------------------------------------------- 1 | //go:build bledebug 2 | 3 | package bluetooth 4 | 5 | var debug = true 6 | -------------------------------------------------------------------------------- /error_sd.go: -------------------------------------------------------------------------------- 1 | //go:build softdevice 2 | 3 | package bluetooth 4 | 5 | // #include 6 | // #include "nrf_error.h" 7 | // #include "nrf_error_sdm.h" 8 | import "C" 9 | 10 | // Error is an error from within the SoftDevice. 11 | type Error uint32 12 | 13 | func (e Error) Error() string { 14 | switch { 15 | case e >= C.NRF_ERROR_BASE_NUM && e < C.NRF_ERROR_SDM_BASE_NUM: 16 | // Global errors. 17 | switch e { 18 | case C.NRF_SUCCESS: 19 | return "no error" 20 | case C.NRF_ERROR_SVC_HANDLER_MISSING: 21 | return "SVC handler is missing" 22 | case C.NRF_ERROR_SOFTDEVICE_NOT_ENABLED: 23 | return "SoftDevice has not been enabled" 24 | case C.NRF_ERROR_INTERNAL: 25 | return "internal error" 26 | case C.NRF_ERROR_NO_MEM: 27 | return "no memory for operation" 28 | case C.NRF_ERROR_NOT_FOUND: 29 | return "not found" 30 | case C.NRF_ERROR_NOT_SUPPORTED: 31 | return "not supported" 32 | case C.NRF_ERROR_INVALID_PARAM: 33 | return "invalid parameter" 34 | case C.NRF_ERROR_INVALID_STATE: 35 | return "invalid state, operation disallowed in this state" 36 | case C.NRF_ERROR_INVALID_LENGTH: 37 | return "invalid Length" 38 | case C.NRF_ERROR_INVALID_FLAGS: 39 | return "invalid flags" 40 | case C.NRF_ERROR_INVALID_DATA: 41 | return "invalid data" 42 | case C.NRF_ERROR_DATA_SIZE: 43 | return "invalid data size" 44 | case C.NRF_ERROR_TIMEOUT: 45 | return "operation timed out" 46 | case C.NRF_ERROR_NULL: 47 | return "null pointer" 48 | case C.NRF_ERROR_FORBIDDEN: 49 | return "forbidden operation" 50 | case C.NRF_ERROR_INVALID_ADDR: 51 | return "bad memory address" 52 | case C.NRF_ERROR_BUSY: 53 | return "busy" 54 | case 18: // C.NRF_ERROR_CONN_COUNT, not available on nrf51 55 | return "maximum connection count exceeded" 56 | case 19: // C.NRF_ERROR_RESOURCES, not available on nrf51 57 | return "not enough resources for operation" 58 | default: 59 | return "other global error" 60 | } 61 | case e >= C.NRF_ERROR_SDM_BASE_NUM && e < C.NRF_ERROR_SOC_BASE_NUM: 62 | // SDM errors. 63 | switch e { 64 | case C.NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN: 65 | return "unknown LFCLK source" 66 | case C.NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION: 67 | return "incorrect interrupt configuration" 68 | case C.NRF_ERROR_SDM_INCORRECT_CLENR0: 69 | return "incorrect CLENR0" 70 | default: 71 | return "other SDM error" 72 | } 73 | case e >= C.NRF_ERROR_SOC_BASE_NUM && e < C.NRF_ERROR_STK_BASE_NUM: 74 | // SoC errors. 75 | return "other SoC error" 76 | case e >= C.NRF_ERROR_STK_BASE_NUM && e < 0x4000: 77 | // STK errors. 78 | return "other STK error" 79 | default: 80 | // Other errors. 81 | return "other error" 82 | } 83 | } 84 | 85 | // makeError returns an error (using the Error type) if the error code is 86 | // non-zero, otherwise it returns nil. It is used with internal API calls. 87 | func makeError(code C.uint32_t) error { 88 | if code != 0 { 89 | return Error(code) 90 | } 91 | return nil 92 | } 93 | -------------------------------------------------------------------------------- /examples/advertisement/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "time" 5 | 6 | "tinygo.org/x/bluetooth" 7 | ) 8 | 9 | var adapter = bluetooth.DefaultAdapter 10 | 11 | func main() { 12 | must("enable BLE stack", adapter.Enable()) 13 | adv := adapter.DefaultAdvertisement() 14 | must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ 15 | LocalName: "Go Bluetooth", 16 | ManufacturerData: []bluetooth.ManufacturerDataElement{ 17 | {CompanyID: 0xffff, Data: []byte{0x01, 0x02}}, 18 | }, 19 | })) 20 | must("start adv", adv.Start()) 21 | 22 | println("advertising...") 23 | address, _ := adapter.Address() 24 | for { 25 | println("Go Bluetooth /", address.MAC.String()) 26 | time.Sleep(time.Second) 27 | } 28 | } 29 | 30 | func must(action string, err error) { 31 | if err != nil { 32 | panic("failed to " + action + ": " + err.Error()) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/battery/main.go: -------------------------------------------------------------------------------- 1 | // example that demonstrates how to create a BLE peripheral device with the Battery Service. 2 | package main 3 | 4 | import ( 5 | "math/rand" 6 | "time" 7 | 8 | "tinygo.org/x/bluetooth" 9 | ) 10 | 11 | var adapter = bluetooth.DefaultAdapter 12 | 13 | var ( 14 | localName = "TinyGo Battery" 15 | 16 | batteryLevel uint8 = 75 // 75% 17 | battery bluetooth.Characteristic 18 | ) 19 | 20 | func main() { 21 | println("starting") 22 | must("enable BLE stack", adapter.Enable()) 23 | adv := adapter.DefaultAdvertisement() 24 | must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ 25 | LocalName: localName, 26 | ServiceUUIDs: []bluetooth.UUID{bluetooth.ServiceUUIDBattery}, 27 | })) 28 | must("start adv", adv.Start()) 29 | 30 | must("add service", adapter.AddService(&bluetooth.Service{ 31 | UUID: bluetooth.ServiceUUIDBattery, 32 | Characteristics: []bluetooth.CharacteristicConfig{ 33 | { 34 | Handle: &battery, 35 | UUID: bluetooth.CharacteristicUUIDBatteryLevel, 36 | Value: []byte{byte(batteryLevel)}, 37 | Flags: bluetooth.CharacteristicReadPermission | bluetooth.CharacteristicNotifyPermission, 38 | }, 39 | }, 40 | })) 41 | 42 | for { 43 | println("tick", time.Now().Format("04:05.000")) 44 | 45 | // random variation in batteryLevel 46 | batteryLevel = randomInt(65, 85) 47 | 48 | // and push the next notification 49 | battery.Write([]byte{batteryLevel}) 50 | 51 | time.Sleep(time.Second) 52 | } 53 | } 54 | 55 | func must(action string, err error) { 56 | if err != nil { 57 | panic("failed to " + action + ": " + err.Error()) 58 | } 59 | } 60 | 61 | // Returns an int >= min, < max 62 | func randomInt(min, max int) uint8 { 63 | return uint8(min + rand.Intn(max-min)) 64 | } 65 | -------------------------------------------------------------------------------- /examples/beacon/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/binary" 5 | "math/rand" 6 | "time" 7 | 8 | "tinygo.org/x/bluetooth" 9 | ) 10 | 11 | var adapter = bluetooth.DefaultAdapter 12 | 13 | var ( 14 | temperatureData [2]byte 15 | sd = []bluetooth.ServiceDataElement{ 16 | { 17 | UUID: bluetooth.CharacteristicUUIDTemperature, 18 | Data: temperatureData[:], 19 | }, 20 | } 21 | 22 | opts = bluetooth.AdvertisementOptions{ 23 | LocalName: "Go Bluetooth", 24 | ServiceData: sd, 25 | AdvertisementType: bluetooth.AdvertisingTypeScanInd, 26 | } 27 | ) 28 | 29 | func main() { 30 | must("enable BLE stack", adapter.Enable()) 31 | adv := adapter.DefaultAdvertisement() 32 | 33 | println("advertising...") 34 | address, _ := adapter.Address() 35 | for { 36 | setServiceData(randomInt(100, 500)) 37 | must("config adv", adv.Configure(opts)) 38 | must("start adv", adv.Start()) 39 | 40 | println("Go Bluetooth /", address.MAC.String()) 41 | time.Sleep(time.Second) 42 | adv.Stop() 43 | } 44 | } 45 | 46 | func setServiceData(m1 uint16) { 47 | binary.LittleEndian.PutUint16(temperatureData[:], m1) 48 | } 49 | 50 | // Returns an int >= min, < max 51 | func randomInt(min, max int) uint16 { 52 | return uint16(min + rand.Intn(max-min)) 53 | } 54 | 55 | func must(action string, err error) { 56 | if err != nil { 57 | panic("failed to " + action + ": " + err.Error()) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /examples/circuitplay/main.go: -------------------------------------------------------------------------------- 1 | // This example is intended to be used with the Adafruit Circuitplay Bluefruit board. 2 | // It allows you to control the color of the built-in NeoPixel LEDS while they animate 3 | // in a circular pattern. 4 | package main 5 | 6 | import ( 7 | "image/color" 8 | "machine" 9 | "time" 10 | 11 | "tinygo.org/x/bluetooth" 12 | "tinygo.org/x/drivers/ws2812" 13 | ) 14 | 15 | var adapter = bluetooth.DefaultAdapter 16 | 17 | // TODO: use atomics to access this value. 18 | var ledColor = [3]byte{0xff, 0x00, 0x00} // start out with red 19 | var leds [10]color.RGBA 20 | 21 | var ( 22 | serviceUUID = [16]byte{0xa0, 0xb4, 0x00, 0x01, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3} 23 | charUUID = [16]byte{0xa0, 0xb4, 0x00, 0x02, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3} 24 | ) 25 | 26 | var neo machine.Pin = machine.NEOPIXELS 27 | var led machine.Pin = machine.LED 28 | var ws ws2812.Device 29 | var rg bool 30 | 31 | var connected bool 32 | var disconnected bool = true 33 | 34 | func main() { 35 | println("starting") 36 | 37 | led.Configure(machine.PinConfig{Mode: machine.PinOutput}) 38 | neo.Configure(machine.PinConfig{Mode: machine.PinOutput}) 39 | ws = ws2812.New(neo) 40 | 41 | adapter.SetConnectHandler(func(d bluetooth.Device, c bool) { 42 | connected = c 43 | 44 | if !connected && !disconnected { 45 | clearLEDS() 46 | disconnected = true 47 | } 48 | 49 | if connected { 50 | disconnected = false 51 | } 52 | }) 53 | 54 | must("enable BLE stack", adapter.Enable()) 55 | adv := adapter.DefaultAdvertisement() 56 | must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ 57 | LocalName: "TinyGo colors", 58 | })) 59 | must("start adv", adv.Start()) 60 | 61 | var ledColorCharacteristic bluetooth.Characteristic 62 | must("add service", adapter.AddService(&bluetooth.Service{ 63 | UUID: bluetooth.NewUUID(serviceUUID), 64 | Characteristics: []bluetooth.CharacteristicConfig{ 65 | { 66 | Handle: &ledColorCharacteristic, 67 | UUID: bluetooth.NewUUID(charUUID), 68 | Value: ledColor[:], 69 | Flags: bluetooth.CharacteristicReadPermission | bluetooth.CharacteristicWritePermission | bluetooth.CharacteristicWriteWithoutResponsePermission, 70 | WriteEvent: func(client bluetooth.Connection, offset int, value []byte) { 71 | if offset != 0 || len(value) != 3 { 72 | return 73 | } 74 | ledColor[0] = value[0] 75 | ledColor[1] = value[1] 76 | ledColor[2] = value[2] 77 | }, 78 | }, 79 | }, 80 | })) 81 | 82 | for { 83 | rg = !rg 84 | if connected { 85 | writeLEDS() 86 | } 87 | led.Set(rg) 88 | time.Sleep(100 * time.Millisecond) 89 | } 90 | } 91 | 92 | func must(action string, err error) { 93 | if err != nil { 94 | panic("failed to " + action + ": " + err.Error()) 95 | } 96 | } 97 | 98 | func writeLEDS() { 99 | for i := range leds { 100 | rg = !rg 101 | if rg { 102 | leds[i] = color.RGBA{R: ledColor[0], G: ledColor[1], B: ledColor[2]} 103 | } else { 104 | leds[i] = color.RGBA{R: 0x00, G: 0x00, B: 0x00} 105 | } 106 | } 107 | 108 | ws.WriteColors(leds[:]) 109 | } 110 | 111 | func clearLEDS() { 112 | for i := range leds { 113 | leds[i] = color.RGBA{R: 0x00, G: 0x00, B: 0x00} 114 | } 115 | 116 | ws.WriteColors(leds[:]) 117 | } 118 | -------------------------------------------------------------------------------- /examples/connparams/main.go: -------------------------------------------------------------------------------- 1 | // Test for setting connection parameters. 2 | // 3 | // To test this feature, run this either on a desktop OS or by flashing it to a 4 | // device with TinyGo. Then connect to it from a BLE connection debugger, for 5 | // example nRF Connect on Android. After a second, you should see in the log of 6 | // the BLE app that the connection latency has been updated. It might look 7 | // something like this: 8 | // 9 | // Connection parameters updated (interval: 510.0ms, latency: 0, timeout: 10000ms) 10 | package main 11 | 12 | import ( 13 | "time" 14 | 15 | "tinygo.org/x/bluetooth" 16 | ) 17 | 18 | var ( 19 | adapter = bluetooth.DefaultAdapter 20 | newDevice chan bluetooth.Device 21 | ) 22 | 23 | func main() { 24 | must("enable BLE stack", adapter.Enable()) 25 | 26 | newDevice = make(chan bluetooth.Device, 1) 27 | adapter.SetConnectHandler(func(device bluetooth.Device, connected bool) { 28 | // If this is a new device, signal it to the separate goroutine. 29 | if connected { 30 | select { 31 | case newDevice <- device: 32 | default: 33 | } 34 | } 35 | }) 36 | 37 | // Start advertising, so we can be found. 38 | const name = "Go BLE test" 39 | adv := adapter.DefaultAdvertisement() 40 | adv.Configure(bluetooth.AdvertisementOptions{ 41 | LocalName: name, 42 | }) 43 | adv.Start() 44 | println("advertising:", name) 45 | 46 | for device := range newDevice { 47 | println("connection from device:", device.Address.String()) 48 | 49 | // Discover services and characteristics. 50 | svcs, err := device.DiscoverServices(nil) 51 | if err != nil { 52 | println(" failed to resolve services:", err) 53 | } 54 | for _, svc := range svcs { 55 | println(" service:", svc.UUID().String()) 56 | chars, err := svc.DiscoverCharacteristics(nil) 57 | if err != nil { 58 | println(" failed to resolve characteristics:", err) 59 | } 60 | for _, char := range chars { 61 | println(" characteristic:", char.UUID().String()) 62 | } 63 | } 64 | 65 | // Update connection parameters (as a test). 66 | time.Sleep(time.Second) 67 | err = device.RequestConnectionParams(bluetooth.ConnectionParams{ 68 | MinInterval: bluetooth.NewDuration(495 * time.Millisecond), 69 | MaxInterval: bluetooth.NewDuration(510 * time.Millisecond), 70 | Timeout: bluetooth.NewDuration(10 * time.Second), 71 | }) 72 | if err != nil { 73 | println(" failed to update connection parameters:", err) 74 | continue 75 | } 76 | println(" updated connection parameters") 77 | } 78 | } 79 | 80 | func must(action string, err error) { 81 | if err != nil { 82 | panic("failed to " + action + ": " + err.Error()) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /examples/device-information/main.go: -------------------------------------------------------------------------------- 1 | // example that demonstrates how to create a BLE peripheral device with the Device Information Service. 2 | package main 3 | 4 | import ( 5 | "time" 6 | 7 | "tinygo.org/x/bluetooth" 8 | ) 9 | 10 | var adapter = bluetooth.DefaultAdapter 11 | 12 | var ( 13 | localName = "TinyGo Device" 14 | 15 | manufacturerName = "TinyGo" 16 | manufacturerNameCharacteristic bluetooth.Characteristic 17 | 18 | modelNumber = "Model 1" 19 | modelNumberCharacteristic bluetooth.Characteristic 20 | 21 | serialNumber = "123456" 22 | serialNumberCharacteristic bluetooth.Characteristic 23 | 24 | softwareVersion = "1.0.0" 25 | softwareVersionCharacteristic bluetooth.Characteristic 26 | 27 | firmwareVersion = "1.0.0" 28 | firmwareVersionCharacteristic bluetooth.Characteristic 29 | 30 | hardwareVersion = "1.0.0" 31 | hardwareVersionCharacteristic bluetooth.Characteristic 32 | ) 33 | 34 | func main() { 35 | println("starting") 36 | must("enable BLE stack", adapter.Enable()) 37 | adv := adapter.DefaultAdvertisement() 38 | must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ 39 | LocalName: localName, 40 | ServiceUUIDs: []bluetooth.UUID{bluetooth.ServiceUUIDDeviceInformation}, 41 | })) 42 | must("start adv", adv.Start()) 43 | 44 | must("add service", adapter.AddService(&bluetooth.Service{ 45 | UUID: bluetooth.ServiceUUIDDeviceInformation, 46 | Characteristics: []bluetooth.CharacteristicConfig{ 47 | { 48 | Handle: &manufacturerNameCharacteristic, 49 | UUID: bluetooth.CharacteristicUUIDManufacturerNameString, 50 | Value: []byte(manufacturerName), 51 | Flags: bluetooth.CharacteristicReadPermission, 52 | }, 53 | { 54 | Handle: &modelNumberCharacteristic, 55 | UUID: bluetooth.CharacteristicUUIDModelNumberString, 56 | Value: []byte(modelNumber), 57 | Flags: bluetooth.CharacteristicReadPermission, 58 | }, 59 | { 60 | Handle: &serialNumberCharacteristic, 61 | UUID: bluetooth.CharacteristicUUIDSerialNumberString, 62 | Value: []byte(serialNumber), 63 | Flags: bluetooth.CharacteristicReadPermission, 64 | }, 65 | { 66 | Handle: &softwareVersionCharacteristic, 67 | UUID: bluetooth.CharacteristicUUIDSoftwareRevisionString, 68 | Value: []byte(softwareVersion), 69 | Flags: bluetooth.CharacteristicReadPermission, 70 | }, 71 | { 72 | Handle: &firmwareVersionCharacteristic, 73 | UUID: bluetooth.CharacteristicUUIDFirmwareRevisionString, 74 | Value: []byte(firmwareVersion), 75 | Flags: bluetooth.CharacteristicReadPermission, 76 | }, 77 | { 78 | Handle: &hardwareVersionCharacteristic, 79 | UUID: bluetooth.CharacteristicUUIDHardwareRevisionString, 80 | Value: []byte(hardwareVersion), 81 | Flags: bluetooth.CharacteristicReadPermission, 82 | }, 83 | }, 84 | })) 85 | 86 | for { 87 | time.Sleep(time.Second) 88 | } 89 | } 90 | 91 | func must(action string, err error) { 92 | if err != nil { 93 | panic("failed to " + action + ": " + err.Error()) 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /examples/discover/main.go: -------------------------------------------------------------------------------- 1 | // This example scans and then connects to a specific Bluetooth peripheral 2 | // and then displays all of the services and characteristics. 3 | // 4 | // To run this on a desktop system: 5 | // 6 | // go run ./examples/discover EE:74:7D:C9:2A:68 7 | // 8 | // To run this on a microcontroller, change the constant value in the file 9 | // "mcu.go" to set the MAC address of the device you want to discover. 10 | // Then, flash to the microcontroller board like this: 11 | // 12 | // tinygo flash -o circuitplay-bluefruit ./examples/discover 13 | // 14 | // Once the program is flashed to the board, connect to the USB port 15 | // via serial to view the output. 16 | package main 17 | 18 | import ( 19 | "strconv" 20 | 21 | "tinygo.org/x/bluetooth" 22 | ) 23 | 24 | var adapter = bluetooth.DefaultAdapter 25 | 26 | func main() { 27 | wait() 28 | 29 | println("enabling") 30 | 31 | // Enable BLE interface. 32 | must("enable BLE stack", adapter.Enable()) 33 | 34 | ch := make(chan bluetooth.ScanResult, 1) 35 | 36 | // Start scanning. 37 | println("scanning...") 38 | err := adapter.Scan(func(adapter *bluetooth.Adapter, result bluetooth.ScanResult) { 39 | println("found device:", result.Address.String(), result.RSSI, result.LocalName()) 40 | if result.Address.String() == connectAddress() { 41 | adapter.StopScan() 42 | ch <- result 43 | } 44 | }) 45 | 46 | var device bluetooth.Device 47 | select { 48 | case result := <-ch: 49 | device, err = adapter.Connect(result.Address, bluetooth.ConnectionParams{}) 50 | if err != nil { 51 | println(err.Error()) 52 | return 53 | } 54 | 55 | println("connected to ", result.Address.String()) 56 | } 57 | 58 | // get services 59 | println("discovering services/characteristics") 60 | srvcs, err := device.DiscoverServices(nil) 61 | must("discover services", err) 62 | 63 | // buffer to retrieve characteristic data 64 | buf := make([]byte, 255) 65 | 66 | for _, srvc := range srvcs { 67 | println("- service", srvc.UUID().String()) 68 | 69 | chars, err := srvc.DiscoverCharacteristics(nil) 70 | if err != nil { 71 | println(err) 72 | } 73 | for _, char := range chars { 74 | println("-- characteristic", char.UUID().String()) 75 | mtu, err := char.GetMTU() 76 | if err != nil { 77 | println(" mtu: error:", err.Error()) 78 | } else { 79 | println(" mtu:", mtu) 80 | } 81 | n, err := char.Read(buf) 82 | if err != nil { 83 | println(" ", err.Error()) 84 | } else { 85 | println(" data bytes", strconv.Itoa(n)) 86 | println(" value =", string(buf[:n])) 87 | } 88 | } 89 | } 90 | 91 | err = device.Disconnect() 92 | if err != nil { 93 | println(err) 94 | } 95 | 96 | done() 97 | } 98 | 99 | func must(action string, err error) { 100 | if err != nil { 101 | panic("failed to " + action + ": " + err.Error()) 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /examples/discover/mcu.go: -------------------------------------------------------------------------------- 1 | //go:build baremetal 2 | 3 | package main 4 | 5 | import ( 6 | "time" 7 | ) 8 | 9 | // DeviceAddress is the MAC address of the Bluetooth peripheral you want to connect to. 10 | // Replace this by using -ldflags="-X main.DeviceAddress=[MAC ADDRESS]" 11 | // where [MAC ADDRESS] is the actual MAC address of the peripheral. 12 | // For example: 13 | // tinygo flash -target circuitplay-bluefruit -ldflags="-X main.DeviceAddress=7B:36:98:8C:41:1C" ./examples/discover/ 14 | var DeviceAddress string 15 | 16 | func connectAddress() string { 17 | return DeviceAddress 18 | } 19 | 20 | // wait on baremetal, proceed immediately on desktop OS. 21 | func wait() { 22 | time.Sleep(3 * time.Second) 23 | } 24 | 25 | // done just blocks forever, allows USB CDC reset for flashing new software. 26 | func done() { 27 | println("Done.") 28 | 29 | time.Sleep(1 * time.Hour) 30 | } 31 | -------------------------------------------------------------------------------- /examples/discover/os.go: -------------------------------------------------------------------------------- 1 | //go:build !baremetal 2 | 3 | package main 4 | 5 | import "os" 6 | 7 | func connectAddress() string { 8 | if len(os.Args) < 2 { 9 | println("usage: discover [address]") 10 | os.Exit(1) 11 | } 12 | 13 | // look for device with specific name 14 | address := os.Args[1] 15 | 16 | return address 17 | } 18 | 19 | // wait on baremetal, proceed immediately on desktop OS. 20 | func wait() { 21 | } 22 | 23 | // done just prints a message and allows program to exit. 24 | func done() { 25 | println("Done.") 26 | } 27 | -------------------------------------------------------------------------------- /examples/heartrate-monitor/main.go: -------------------------------------------------------------------------------- 1 | // This example scans and then connects to a specific Bluetooth peripheral 2 | // that can provide the Heart Rate Service (HRS). 3 | // 4 | // Once connected, it subscribes to notifications for the data value, and 5 | // displays it. 6 | // The Heart Rate Measurement characteristic is a variable-length structure (array) containing a Flags field, a Heart 7 | // Rate Measurement Value field and, based on the contents of the Flags field, may contain additional fields 8 | // such as Energy Expended or RR-Interval. 9 | // More info can be found here: https://www.bluetooth.com/specifications/specs/gatt-specification-supplement-6/ 10 | // In this example only the heart rate is used, this is the second element in the array of bytes. 11 | // 12 | // To run this on a desktop system: 13 | // 14 | // go run ./examples/heartrate-monitor EE:74:7D:C9:2A:68 15 | // 16 | // To run this on a microcontroller, change the constant value in the file 17 | // "mcu.go" to set the MAC address of the device you want to discover. 18 | // Then, flash to the microcontroller board like this: 19 | // 20 | // tinygo flash -o circuitplay-bluefruit ./examples/heartrate-monitor 21 | // 22 | // Once the program is flashed to the board, connect to the USB port 23 | // via serial to view the output. 24 | package main 25 | 26 | import ( 27 | "tinygo.org/x/bluetooth" 28 | ) 29 | 30 | var ( 31 | adapter = bluetooth.DefaultAdapter 32 | 33 | heartRateServiceUUID = bluetooth.ServiceUUIDHeartRate 34 | heartRateCharacteristicUUID = bluetooth.CharacteristicUUIDHeartRateMeasurement 35 | ) 36 | 37 | func main() { 38 | println("enabling") 39 | 40 | // Enable BLE interface. 41 | must("enable BLE stack", adapter.Enable()) 42 | 43 | ch := make(chan bluetooth.ScanResult, 1) 44 | 45 | // Start scanning. 46 | println("scanning...") 47 | err := adapter.Scan(func(adapter *bluetooth.Adapter, result bluetooth.ScanResult) { 48 | println("found device:", result.Address.String(), result.RSSI, result.LocalName()) 49 | if result.Address.String() == connectAddress() { 50 | adapter.StopScan() 51 | ch <- result 52 | } 53 | }) 54 | 55 | var device bluetooth.Device 56 | select { 57 | case result := <-ch: 58 | device, err = adapter.Connect(result.Address, bluetooth.ConnectionParams{}) 59 | if err != nil { 60 | println(err.Error()) 61 | return 62 | } 63 | 64 | println("connected to ", result.Address.String()) 65 | } 66 | 67 | // get services 68 | println("discovering services/characteristics") 69 | srvcs, err := device.DiscoverServices([]bluetooth.UUID{heartRateServiceUUID}) 70 | must("discover services", err) 71 | 72 | if len(srvcs) == 0 { 73 | panic("could not find heart rate service") 74 | } 75 | 76 | srvc := srvcs[0] 77 | 78 | println("found service", srvc.UUID().String()) 79 | 80 | chars, err := srvc.DiscoverCharacteristics([]bluetooth.UUID{heartRateCharacteristicUUID}) 81 | if err != nil { 82 | println(err) 83 | } 84 | 85 | if len(chars) == 0 { 86 | panic("could not find heart rate characteristic") 87 | } 88 | 89 | char := chars[0] 90 | println("found characteristic", char.UUID().String()) 91 | 92 | char.EnableNotifications(func(buf []byte) { 93 | println("data:", uint8(buf[1])) 94 | }) 95 | 96 | select {} 97 | } 98 | 99 | func must(action string, err error) { 100 | if err != nil { 101 | panic("failed to " + action + ": " + err.Error()) 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /examples/heartrate-monitor/mcu.go: -------------------------------------------------------------------------------- 1 | //go:build baremetal 2 | 3 | package main 4 | 5 | import ( 6 | "time" 7 | ) 8 | 9 | // DeviceAddress is the MAC address of the Bluetooth peripheral you want to connect to. 10 | // Replace this by using -ldflags="-X main.DeviceAddress=[MAC ADDRESS]" 11 | // where [MAC ADDRESS] is the actual MAC address of the peripheral. 12 | // For example: 13 | // tinygo flash -target circuitplay-bluefruit -ldflags="-X main.DeviceAddress=7B:36:98:8C:41:1C" ./examples/heartrate-monitor/ 14 | var DeviceAddress string 15 | 16 | func connectAddress() string { 17 | return DeviceAddress 18 | } 19 | 20 | // done just blocks forever, allows USB CDC reset for flashing new software. 21 | func done() { 22 | println("Done.") 23 | 24 | time.Sleep(1 * time.Hour) 25 | } 26 | -------------------------------------------------------------------------------- /examples/heartrate-monitor/os.go: -------------------------------------------------------------------------------- 1 | //go:build !baremetal 2 | 3 | package main 4 | 5 | import "os" 6 | 7 | func connectAddress() string { 8 | if len(os.Args) < 2 { 9 | println("usage: heartrate-monitor [address]") 10 | os.Exit(1) 11 | } 12 | 13 | // look for device with specific name 14 | address := os.Args[1] 15 | 16 | return address 17 | } 18 | 19 | // done just prints a message and allows program to exit. 20 | func done() { 21 | println("Done.") 22 | } 23 | -------------------------------------------------------------------------------- /examples/heartrate/main.go: -------------------------------------------------------------------------------- 1 | // this example implements a BLE heart rate sensor. 2 | // see https://www.bluetooth.com/specifications/specs/heart-rate-profile-1-0/ for the full spec. 3 | package main 4 | 5 | import ( 6 | "math/rand" 7 | "time" 8 | 9 | "tinygo.org/x/bluetooth" 10 | ) 11 | 12 | var ( 13 | adapter = bluetooth.DefaultAdapter 14 | 15 | heartRateMeasurement bluetooth.Characteristic 16 | bodyLocation bluetooth.Characteristic 17 | controlPoint bluetooth.Characteristic 18 | 19 | heartRate uint8 = 75 // 75bpm 20 | ) 21 | 22 | func main() { 23 | println("starting") 24 | must("enable BLE stack", adapter.Enable()) 25 | adv := adapter.DefaultAdvertisement() 26 | must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ 27 | LocalName: "Go HRS", 28 | ServiceUUIDs: []bluetooth.UUID{bluetooth.ServiceUUIDHeartRate}, 29 | })) 30 | must("start adv", adv.Start()) 31 | 32 | must("add service", adapter.AddService(&bluetooth.Service{ 33 | UUID: bluetooth.ServiceUUIDHeartRate, 34 | Characteristics: []bluetooth.CharacteristicConfig{ 35 | { 36 | Handle: &heartRateMeasurement, 37 | UUID: bluetooth.CharacteristicUUIDHeartRateMeasurement, 38 | Value: []byte{0, heartRate}, 39 | Flags: bluetooth.CharacteristicNotifyPermission, 40 | }, 41 | { 42 | Handle: &bodyLocation, 43 | UUID: bluetooth.CharacteristicUUIDBodySensorLocation, 44 | Value: []byte{1}, // "Chest" 45 | Flags: bluetooth.CharacteristicReadPermission, 46 | }, 47 | { 48 | Handle: &controlPoint, 49 | UUID: bluetooth.CharacteristicUUIDHeartRateControlPoint, 50 | Value: []byte{0}, 51 | Flags: bluetooth.CharacteristicWritePermission, 52 | }, 53 | }, 54 | })) 55 | 56 | nextBeat := time.Now() 57 | for { 58 | nextBeat = nextBeat.Add(time.Minute / time.Duration(heartRate)) 59 | println("tick", time.Now().Format("04:05.000")) 60 | time.Sleep(nextBeat.Sub(time.Now())) 61 | 62 | // random variation in heartrate 63 | heartRate = randomInt(65, 85) 64 | 65 | // and push the next notification 66 | heartRateMeasurement.Write([]byte{0, heartRate}) 67 | } 68 | } 69 | 70 | func must(action string, err error) { 71 | if err != nil { 72 | panic("failed to " + action + ": " + err.Error()) 73 | } 74 | } 75 | 76 | // Returns an int >= min, < max 77 | func randomInt(min, max int) uint8 { 78 | return uint8(min + rand.Intn(max-min)) 79 | } 80 | -------------------------------------------------------------------------------- /examples/ledcolor/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "machine" 5 | "time" 6 | 7 | "tinygo.org/x/bluetooth" 8 | ) 9 | 10 | var adapter = bluetooth.DefaultAdapter 11 | 12 | // TODO: use atomics to access this value. 13 | var ledColor = [3]byte{0xff, 0x00, 0x00} // start out with red 14 | var leds = [3]machine.Pin{machine.LED_RED, machine.LED_GREEN, machine.LED_BLUE} 15 | var hasColorChange = true 16 | 17 | var ( 18 | serviceUUID = [16]byte{0xa0, 0xb4, 0x00, 0x01, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3} 19 | charUUID = [16]byte{0xa0, 0xb4, 0x00, 0x02, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3} 20 | ) 21 | 22 | func main() { 23 | println("starting") 24 | must("enable BLE stack", adapter.Enable()) 25 | adv := adapter.DefaultAdvertisement() 26 | must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ 27 | LocalName: "LED colors", 28 | })) 29 | must("start adv", adv.Start()) 30 | 31 | var ledColorCharacteristic bluetooth.Characteristic 32 | must("add service", adapter.AddService(&bluetooth.Service{ 33 | UUID: bluetooth.NewUUID(serviceUUID), 34 | Characteristics: []bluetooth.CharacteristicConfig{ 35 | { 36 | Handle: &ledColorCharacteristic, 37 | UUID: bluetooth.NewUUID(charUUID), 38 | Value: ledColor[:], 39 | Flags: bluetooth.CharacteristicReadPermission | bluetooth.CharacteristicWritePermission | bluetooth.CharacteristicWriteWithoutResponsePermission, 40 | WriteEvent: func(client bluetooth.Connection, offset int, value []byte) { 41 | if offset != 0 || len(value) != 3 { 42 | return 43 | } 44 | ledColor[0] = value[0] 45 | ledColor[1] = value[1] 46 | ledColor[2] = value[2] 47 | hasColorChange = true 48 | }, 49 | }, 50 | }, 51 | })) 52 | 53 | for _, led := range leds { 54 | led.Configure(machine.PinConfig{Mode: machine.PinOutput}) 55 | } 56 | 57 | for { 58 | for !hasColorChange { 59 | time.Sleep(10 * time.Millisecond) 60 | } 61 | hasColorChange = false 62 | for i, led := range leds { 63 | led.Set(ledColor[i] == 0) 64 | } 65 | } 66 | } 67 | 68 | func must(action string, err error) { 69 | if err != nil { 70 | panic("failed to " + action + ": " + err.Error()) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /examples/nusclient/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // This example implements a NUS (Nordic UART Service) client. See nusserver for 4 | // details. 5 | 6 | import ( 7 | "tinygo.org/x/bluetooth" 8 | "tinygo.org/x/bluetooth/rawterm" 9 | ) 10 | 11 | var ( 12 | serviceUUID = bluetooth.ServiceUUIDNordicUART 13 | rxUUID = bluetooth.CharacteristicUUIDUARTRX 14 | txUUID = bluetooth.CharacteristicUUIDUARTTX 15 | ) 16 | 17 | var adapter = bluetooth.DefaultAdapter 18 | 19 | func main() { 20 | // Enable BLE interface. 21 | err := adapter.Enable() 22 | if err != nil { 23 | println("could not enable the BLE stack:", err.Error()) 24 | return 25 | } 26 | 27 | // The address to connect to. Set during scanning and read afterwards. 28 | var foundDevice bluetooth.ScanResult 29 | 30 | // Scan for NUS peripheral. 31 | println("Scanning...") 32 | err = adapter.Scan(func(adapter *bluetooth.Adapter, result bluetooth.ScanResult) { 33 | if !result.AdvertisementPayload.HasServiceUUID(serviceUUID) { 34 | return 35 | } 36 | foundDevice = result 37 | 38 | // Stop the scan. 39 | err := adapter.StopScan() 40 | if err != nil { 41 | // Unlikely, but we can't recover from this. 42 | println("failed to stop the scan:", err.Error()) 43 | } 44 | }) 45 | if err != nil { 46 | println("could not start a scan:", err.Error()) 47 | return 48 | } 49 | 50 | // Found a device: print this event. 51 | if name := foundDevice.LocalName(); name == "" { 52 | print("Connecting to ", foundDevice.Address.String(), "...") 53 | println() 54 | } else { 55 | print("Connecting to ", name, " (", foundDevice.Address.String(), ")...") 56 | println() 57 | } 58 | 59 | // Found a NUS peripheral. Connect to it. 60 | device, err := adapter.Connect(foundDevice.Address, bluetooth.ConnectionParams{}) 61 | if err != nil { 62 | println("Failed to connect:", err.Error()) 63 | return 64 | } 65 | 66 | // Connected. Look up the Nordic UART Service. 67 | println("Discovering service...") 68 | services, err := device.DiscoverServices([]bluetooth.UUID{serviceUUID}) 69 | if err != nil { 70 | println("Failed to discover the Nordic UART Service:", err.Error()) 71 | return 72 | } 73 | service := services[0] 74 | 75 | // Get the two characteristics present in this service. 76 | chars, err := service.DiscoverCharacteristics([]bluetooth.UUID{rxUUID, txUUID}) 77 | if err != nil { 78 | println("Failed to discover RX and TX characteristics:", err.Error()) 79 | return 80 | } 81 | rx := chars[0] 82 | tx := chars[1] 83 | 84 | // Enable notifications to receive incoming data. 85 | err = tx.EnableNotifications(func(value []byte) { 86 | for _, c := range value { 87 | rawterm.Putchar(c) 88 | } 89 | }) 90 | if err != nil { 91 | println("Failed to enable TX notifications:", err.Error()) 92 | return 93 | } 94 | 95 | println("Connected. Exit console using Ctrl-X.") 96 | rawterm.Configure() 97 | defer rawterm.Restore() 98 | var line []byte 99 | for { 100 | ch := rawterm.Getchar() 101 | line = append(line, ch) 102 | 103 | // Send the current line to the central. 104 | if ch == '\x18' { 105 | // The user pressed Ctrl-X, exit the program. 106 | break 107 | } else if ch == '\n' { 108 | sendbuf := line // copy buffer 109 | // Reset the slice while keeping the buffer in place. 110 | line = line[:0] 111 | 112 | // Send the sendbuf after breaking it up in pieces. 113 | for len(sendbuf) != 0 { 114 | // Chop off up to 20 bytes from the sendbuf. 115 | partlen := 20 116 | if len(sendbuf) < 20 { 117 | partlen = len(sendbuf) 118 | } 119 | part := sendbuf[:partlen] 120 | sendbuf = sendbuf[partlen:] 121 | // This performs a "write command" aka "write without response". 122 | _, err := rx.WriteWithoutResponse(part) 123 | if err != nil { 124 | println("could not send:", err.Error()) 125 | } 126 | } 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /examples/nusserver/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // This example implements a NUS (Nordic UART Service) peripheral. 4 | // I can't find much official documentation on the protocol, but this can be 5 | // helpful: 6 | // https://learn.adafruit.com/introducing-adafruit-ble-bluetooth-low-energy-friend/uart-service 7 | // 8 | // Code to interact with a raw terminal is in separate files with build tags. 9 | 10 | import ( 11 | "tinygo.org/x/bluetooth" 12 | "tinygo.org/x/bluetooth/rawterm" 13 | ) 14 | 15 | var ( 16 | serviceUUID = bluetooth.ServiceUUIDNordicUART 17 | rxUUID = bluetooth.CharacteristicUUIDUARTRX 18 | txUUID = bluetooth.CharacteristicUUIDUARTTX 19 | ) 20 | 21 | func main() { 22 | println("starting") 23 | adapter := bluetooth.DefaultAdapter 24 | must("enable BLE stack", adapter.Enable()) 25 | adv := adapter.DefaultAdvertisement() 26 | must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ 27 | LocalName: "NUS", // Nordic UART Service 28 | ServiceUUIDs: []bluetooth.UUID{serviceUUID}, 29 | })) 30 | must("start adv", adv.Start()) 31 | 32 | var rxChar bluetooth.Characteristic 33 | var txChar bluetooth.Characteristic 34 | must("add service", adapter.AddService(&bluetooth.Service{ 35 | UUID: serviceUUID, 36 | Characteristics: []bluetooth.CharacteristicConfig{ 37 | { 38 | Handle: &rxChar, 39 | UUID: rxUUID, 40 | Flags: bluetooth.CharacteristicWritePermission | bluetooth.CharacteristicWriteWithoutResponsePermission, 41 | WriteEvent: func(client bluetooth.Connection, offset int, value []byte) { 42 | txChar.Write(value) 43 | for _, c := range value { 44 | rawterm.Putchar(c) 45 | } 46 | }, 47 | }, 48 | { 49 | Handle: &txChar, 50 | UUID: txUUID, 51 | Flags: bluetooth.CharacteristicNotifyPermission | bluetooth.CharacteristicReadPermission, 52 | }, 53 | }, 54 | })) 55 | 56 | rawterm.Configure() 57 | defer rawterm.Restore() 58 | print("NUS console enabled, use Ctrl-X to exit\r\n") 59 | var line []byte 60 | for { 61 | ch := rawterm.Getchar() 62 | rawterm.Putchar(ch) 63 | line = append(line, ch) 64 | 65 | // Send the current line to the central. 66 | if ch == '\x18' { 67 | // The user pressed Ctrl-X, exit the terminal. 68 | break 69 | } else if ch == '\n' { 70 | sendbuf := line // copy buffer 71 | // Reset the slice while keeping the buffer in place. 72 | line = line[:0] 73 | 74 | // Send the sendbuf after breaking it up in pieces. 75 | for len(sendbuf) != 0 { 76 | // Chop off up to 20 bytes from the sendbuf. 77 | partlen := 20 78 | if len(sendbuf) < 20 { 79 | partlen = len(sendbuf) 80 | } 81 | part := sendbuf[:partlen] 82 | sendbuf = sendbuf[partlen:] 83 | // This also sends a notification. 84 | _, err := txChar.Write(part) 85 | must("send notification", err) 86 | } 87 | } 88 | } 89 | } 90 | 91 | func must(action string, err error) { 92 | if err != nil { 93 | panic("failed to " + action + ": " + err.Error()) 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /examples/scanner/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "tinygo.org/x/bluetooth" 5 | ) 6 | 7 | var adapter = bluetooth.DefaultAdapter 8 | 9 | func main() { 10 | // Enable BLE interface. 11 | must("enable BLE stack", adapter.Enable()) 12 | 13 | // Start scanning. 14 | println("scanning...") 15 | err := adapter.Scan(func(adapter *bluetooth.Adapter, device bluetooth.ScanResult) { 16 | println("found device:", device.Address.String(), device.RSSI, device.LocalName()) 17 | }) 18 | must("start scan", err) 19 | } 20 | 21 | func must(action string, err error) { 22 | if err != nil { 23 | panic("failed to " + action + ": " + err.Error()) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/stop-advertisement/main.go: -------------------------------------------------------------------------------- 1 | // This example advertises for 5 minutes after 2 | // - boot 3 | // - disconnect 4 | // and then stops advertising. 5 | package main 6 | 7 | import ( 8 | "time" 9 | 10 | "tinygo.org/x/bluetooth" 11 | ) 12 | 13 | var adapter = bluetooth.DefaultAdapter 14 | 15 | var advUntil = time.Now().Add(5 * time.Minute) 16 | var advState = true 17 | 18 | func main() { 19 | must("enable BLE stack", adapter.Enable()) 20 | adv := adapter.DefaultAdvertisement() 21 | must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ 22 | LocalName: "Go Bluetooth", 23 | })) 24 | adapter.SetConnectHandler(func(device bluetooth.Device, connected bool) { 25 | if connected { 26 | println("connected, not advertising...") 27 | advState = false 28 | } else { 29 | println("disconnected, advertising...") 30 | advState = true 31 | advUntil = time.Now().Add(5 * time.Minute) 32 | } 33 | }) 34 | must("start adv", adv.Start()) 35 | 36 | println("advertising...") 37 | address, _ := adapter.Address() 38 | for { 39 | if advState && time.Now().After(advUntil) { 40 | println("timeout, not advertising...") 41 | advState = false 42 | must("stop adv", adv.Stop()) 43 | } 44 | println("Go Bluetooth /", address.MAC.String()) 45 | time.Sleep(time.Second) 46 | } 47 | } 48 | 49 | func must(action string, err error) { 50 | if err != nil { 51 | panic("failed to " + action + ": " + err.Error()) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /examples/tinyscan/badger2040w.go: -------------------------------------------------------------------------------- 1 | //go:build badger2040_w 2 | 3 | package main 4 | 5 | import ( 6 | "tinygo.org/x/tinyfont/proggy" 7 | "tinygo.org/x/tinyterm" 8 | "tinygo.org/x/tinyterm/displays" 9 | ) 10 | 11 | var ( 12 | font = &proggy.TinySZ8pt7b 13 | ) 14 | 15 | func initTerminal() { 16 | display := displays.Init() 17 | 18 | terminal = tinyterm.NewTerminal(display) 19 | terminal.Configure(&tinyterm.Config{ 20 | Font: font, 21 | FontHeight: 10, 22 | FontOffset: 6, 23 | UseSoftwareScroll: true, 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /examples/tinyscan/clue.go: -------------------------------------------------------------------------------- 1 | //go:build clue 2 | 3 | package main 4 | 5 | import ( 6 | "tinygo.org/x/tinyfont/proggy" 7 | "tinygo.org/x/tinyterm" 8 | "tinygo.org/x/tinyterm/displays" 9 | ) 10 | 11 | var ( 12 | font = &proggy.TinySZ8pt7b 13 | ) 14 | 15 | func initTerminal() { 16 | display := displays.Init() 17 | 18 | terminal = tinyterm.NewTerminal(display) 19 | terminal.Configure(&tinyterm.Config{ 20 | Font: font, 21 | FontHeight: 10, 22 | FontOffset: 6, 23 | UseSoftwareScroll: true, 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /examples/tinyscan/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "image/color" 6 | "time" 7 | 8 | "tinygo.org/x/bluetooth" 9 | "tinygo.org/x/tinyterm" 10 | ) 11 | 12 | var ( 13 | terminal *tinyterm.Terminal 14 | 15 | black = color.RGBA{0, 0, 0, 255} 16 | adapter = bluetooth.DefaultAdapter 17 | ) 18 | 19 | func main() { 20 | initTerminal() 21 | 22 | terminalOutput("enable interface...") 23 | 24 | must("enable BLE interface", adapter.Enable()) 25 | time.Sleep(time.Second) 26 | 27 | terminalOutput("start scan...") 28 | 29 | must("start scan", adapter.Scan(scanHandler)) 30 | 31 | for { 32 | time.Sleep(time.Minute) 33 | terminalOutput("scanning...") 34 | } 35 | } 36 | 37 | func scanHandler(adapter *bluetooth.Adapter, device bluetooth.ScanResult) { 38 | msg := fmt.Sprintf("%s %d %s", device.Address.String(), device.RSSI, device.LocalName()) 39 | terminalOutput(msg) 40 | } 41 | 42 | func must(action string, err error) { 43 | if err != nil { 44 | for { 45 | terminalOutput("failed to " + action + ": " + err.Error()) 46 | 47 | time.Sleep(time.Second) 48 | } 49 | } 50 | } 51 | 52 | func terminalOutput(s string) { 53 | println(s) 54 | fmt.Fprintf(terminal, "\n%s", s) 55 | 56 | terminal.Display() 57 | } 58 | -------------------------------------------------------------------------------- /examples/tinyscan/pybadge.go: -------------------------------------------------------------------------------- 1 | //go:build pybadge 2 | 3 | package main 4 | 5 | import ( 6 | "tinygo.org/x/tinyfont" 7 | "tinygo.org/x/tinyterm" 8 | "tinygo.org/x/tinyterm/displays" 9 | ) 10 | 11 | var ( 12 | font = &tinyfont.Picopixel 13 | ) 14 | 15 | func initTerminal() { 16 | display := displays.Init() 17 | 18 | terminal = tinyterm.NewTerminal(display) 19 | terminal.Configure(&tinyterm.Config{ 20 | Font: font, 21 | FontHeight: 8, 22 | FontOffset: 4, 23 | UseSoftwareScroll: true, 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /examples/tinyscan/pyportal.go: -------------------------------------------------------------------------------- 1 | //go:build pyportal 2 | 3 | package main 4 | 5 | import ( 6 | "tinygo.org/x/tinyfont/proggy" 7 | "tinygo.org/x/tinyterm" 8 | "tinygo.org/x/tinyterm/displays" 9 | ) 10 | 11 | var ( 12 | font = &proggy.TinySZ8pt7b 13 | ) 14 | 15 | func initTerminal() { 16 | display := displays.Init() 17 | 18 | terminal = tinyterm.NewTerminal(display) 19 | terminal.Configure(&tinyterm.Config{ 20 | Font: font, 21 | FontHeight: 10, 22 | FontOffset: 6, 23 | UseSoftwareScroll: true, 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /gap_nrf51.go: -------------------------------------------------------------------------------- 1 | //go:build softdevice && s110v8 2 | 3 | package bluetooth 4 | 5 | /* 6 | #include "ble_gap.h" 7 | 8 | // Workaround wrapper function to avoid pointer arguments escaping to heap 9 | static inline uint32_t sd_ble_gap_adv_start_noescape(ble_gap_adv_params_t const p_adv_params) { 10 | return sd_ble_gap_adv_start(&p_adv_params); 11 | } 12 | */ 13 | import "C" 14 | 15 | import ( 16 | "runtime/volatile" 17 | "time" 18 | "unsafe" 19 | ) 20 | 21 | // Address contains a Bluetooth MAC address. 22 | type Address struct { 23 | MACAddress 24 | } 25 | 26 | // Advertisement encapsulates a single advertisement instance. 27 | type Advertisement struct { 28 | interval Duration 29 | isAdvertising volatile.Register8 30 | typ uint8 31 | } 32 | 33 | var defaultAdvertisement Advertisement 34 | 35 | // DefaultAdvertisement returns the default advertisement instance but does not 36 | // configure it. 37 | func (a *Adapter) DefaultAdvertisement() *Advertisement { 38 | return &defaultAdvertisement 39 | } 40 | 41 | // Configure this advertisement. 42 | func (a *Advertisement) Configure(options AdvertisementOptions) error { 43 | // Fill empty options with reasonable defaults. 44 | if options.Interval == 0 { 45 | // Pick an advertisement interval recommended by Apple (section 35.5 46 | // Advertising Interval): 47 | // https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf 48 | options.Interval = NewDuration(152500 * time.Microsecond) // 152.5ms 49 | } 50 | 51 | // Construct payload. 52 | var payload rawAdvertisementPayload 53 | if !payload.addFromOptions(options) { 54 | return errAdvertisementPacketTooBig 55 | } 56 | 57 | switch options.AdvertisementType { 58 | case AdvertisingTypeInd: 59 | a.typ = C.BLE_GAP_ADV_TYPE_ADV_IND 60 | case AdvertisingTypeDirectInd: 61 | a.typ = C.BLE_GAP_ADV_TYPE_ADV_DIRECT_IND 62 | case AdvertisingTypeScanInd: 63 | a.typ = C.BLE_GAP_ADV_TYPE_ADV_SCAN_IND 64 | case AdvertisingTypeNonConnInd: 65 | a.typ = C.BLE_GAP_ADV_TYPE_ADV_NONCONN_IND 66 | } 67 | 68 | errCode := C.sd_ble_gap_adv_data_set((*C.uint8_t)(unsafe.Pointer(&payload.data[0])), C.uint8_t(payload.len), nil, 0) 69 | a.interval = options.Interval 70 | return makeError(errCode) 71 | } 72 | 73 | // Start advertisement. May only be called after it has been configured. 74 | func (a *Advertisement) Start() error { 75 | a.isAdvertising.Set(1) 76 | errCode := a.start() 77 | return makeError(errCode) 78 | } 79 | 80 | // Stop advertisement. 81 | func (a *Advertisement) Stop() error { 82 | a.isAdvertising.Set(0) 83 | errCode := C.sd_ble_gap_adv_stop() 84 | return makeError(errCode) 85 | } 86 | 87 | // Low-level version of Start. Used to restart advertisement when a connection 88 | // is lost. 89 | func (a *Advertisement) start() C.uint32_t { 90 | params := C.ble_gap_adv_params_t{ 91 | _type: a.typ, 92 | fp: C.BLE_GAP_ADV_FP_ANY, 93 | interval: C.uint16_t(a.interval), 94 | timeout: 0, // no timeout 95 | } 96 | return C.sd_ble_gap_adv_start_noescape(params) 97 | } 98 | 99 | // SetRandomAddress sets the random address to be used for advertising. 100 | func (a *Adapter) SetRandomAddress(mac MAC) error { 101 | var addr C.ble_gap_addr_t 102 | addr.addr = makeSDAddress(mac) 103 | addr.addr_type = C.BLE_GAP_ADDR_TYPE_RANDOM_STATIC 104 | 105 | errCode := C.sd_ble_gap_address_set(C.BLE_GAP_ADDR_CYCLE_MODE_NONE, &addr) 106 | if errCode != 0 { 107 | return Error(errCode) 108 | } 109 | return nil 110 | } 111 | -------------------------------------------------------------------------------- /gap_nrf528xx-advertisement.go: -------------------------------------------------------------------------------- 1 | //go:build (softdevice && s113v7) || (softdevice && s132v6) || (softdevice && s140v6) || (softdevice && s140v7) 2 | 3 | package bluetooth 4 | 5 | import ( 6 | "runtime/volatile" 7 | "time" 8 | "unsafe" 9 | ) 10 | 11 | /* 12 | #include "ble_gap.h" 13 | */ 14 | import "C" 15 | 16 | // Address contains a Bluetooth MAC address. 17 | type Address struct { 18 | MACAddress 19 | } 20 | 21 | // Advertisement encapsulates a single advertisement instance. 22 | type Advertisement struct { 23 | handle C.uint8_t 24 | isAdvertising volatile.Register8 25 | payload rawAdvertisementPayload 26 | } 27 | 28 | // The nrf528xx devices only seem to support one advertisement instance. The way 29 | // multiple advertisements are implemented is by changing the packet data 30 | // frequently. 31 | var defaultAdvertisement = Advertisement{ 32 | handle: C.BLE_GAP_ADV_SET_HANDLE_NOT_SET, 33 | } 34 | 35 | // DefaultAdvertisement returns the default advertisement instance but does not 36 | // configure it. 37 | func (a *Adapter) DefaultAdvertisement() *Advertisement { 38 | return &defaultAdvertisement 39 | } 40 | 41 | // Configure this advertisement. 42 | func (a *Advertisement) Configure(options AdvertisementOptions) error { 43 | // Fill empty options with reasonable defaults. 44 | if options.Interval == 0 { 45 | // Pick an advertisement interval recommended by Apple (section 35.5 46 | // Advertising Interval): 47 | // https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf 48 | options.Interval = NewDuration(152500 * time.Microsecond) // 152.5ms 49 | } 50 | 51 | // Construct payload. 52 | // Note that the payload needs to be part of the Advertisement object as the 53 | // memory is still used after sd_ble_gap_adv_set_configure returns. 54 | a.payload.reset() 55 | if !a.payload.addFromOptions(options) { 56 | return errAdvertisementPacketTooBig 57 | } 58 | 59 | var typ uint8 60 | switch options.AdvertisementType { 61 | case AdvertisingTypeInd: 62 | typ = C.BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED 63 | case AdvertisingTypeDirectInd: 64 | typ = C.BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED 65 | case AdvertisingTypeScanInd: 66 | typ = C.BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED 67 | case AdvertisingTypeNonConnInd: 68 | typ = C.BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED 69 | } 70 | 71 | data := C.ble_gap_adv_data_t{} 72 | data.adv_data = C.ble_data_t{ 73 | p_data: (*C.uint8_t)(unsafe.Pointer(&a.payload.data[0])), 74 | len: C.uint16_t(a.payload.len), 75 | } 76 | params := C.ble_gap_adv_params_t{ 77 | properties: C.ble_gap_adv_properties_t{ 78 | _type: typ, 79 | }, 80 | interval: C.uint32_t(options.Interval), 81 | } 82 | errCode := C.sd_ble_gap_adv_set_configure(&a.handle, &data, ¶ms) 83 | return makeError(errCode) 84 | } 85 | 86 | // Start advertisement. May only be called after it has been configured. 87 | func (a *Advertisement) Start() error { 88 | a.isAdvertising.Set(1) 89 | errCode := C.sd_ble_gap_adv_start(a.handle, C.BLE_CONN_CFG_TAG_DEFAULT) 90 | return makeError(errCode) 91 | } 92 | 93 | // Stop advertisement. 94 | func (a *Advertisement) Stop() error { 95 | a.isAdvertising.Set(0) 96 | errCode := C.sd_ble_gap_adv_stop(a.handle) 97 | return makeError(errCode) 98 | } 99 | 100 | // SetRandomAddress sets the random address to be used for advertising. 101 | func (a *Adapter) SetRandomAddress(mac MAC) error { 102 | var addr C.ble_gap_addr_t 103 | addr.addr = makeSDAddress(mac) 104 | addr.set_bitfield_addr_type(C.BLE_GAP_ADDR_TYPE_RANDOM_STATIC) 105 | 106 | errCode := C.sd_ble_gap_addr_set(&addr) 107 | if errCode != 0 { 108 | return Error(errCode) 109 | } 110 | return nil 111 | } 112 | -------------------------------------------------------------------------------- /gap_sd.go: -------------------------------------------------------------------------------- 1 | //go:build softdevice 2 | 3 | package bluetooth 4 | 5 | /* 6 | #include "ble_gap.h" 7 | */ 8 | import "C" 9 | 10 | // Device is a connection to a remote peripheral or central. 11 | type Device struct { 12 | Address Address 13 | 14 | connectionHandle C.uint16_t 15 | } 16 | -------------------------------------------------------------------------------- /gap_test.go: -------------------------------------------------------------------------------- 1 | package bluetooth 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func TestCreateAdvertisementPayload(t *testing.T) { 10 | type testCase struct { 11 | raw string 12 | parsed AdvertisementOptions 13 | } 14 | tests := []testCase{ 15 | { 16 | raw: "\x02\x01\x06", // flags 17 | parsed: AdvertisementOptions{}, 18 | }, 19 | { 20 | raw: "\x02\x01\x06", // flags 21 | parsed: AdvertisementOptions{ 22 | // Interval doesn't affect the advertisement payload. 23 | Interval: NewDuration(100 * time.Millisecond), 24 | }, 25 | }, 26 | { 27 | raw: "\x02\x01\x06" + // flags 28 | "\x07\x09foobar", // local name 29 | parsed: AdvertisementOptions{ 30 | LocalName: "foobar", 31 | }, 32 | }, 33 | { 34 | raw: "\x02\x01\x06" + // flags 35 | "\x0b\x09Heart rate" + // local name 36 | "\x03\x03\x0d\x18", // service UUID 37 | parsed: AdvertisementOptions{ 38 | LocalName: "Heart rate", 39 | ServiceUUIDs: []UUID{ 40 | ServiceUUIDHeartRate, 41 | }, 42 | }, 43 | }, 44 | { 45 | // Note: the two service UUIDs should really be merged into one to 46 | // save space. 47 | raw: "\x02\x01\x06" + // flags 48 | "\x0b\x09Heart rate" + // local name 49 | "\x03\x03\x0d\x18" + // heart rate service UUID 50 | "\x03\x03\x0f\x18", // battery service UUID 51 | parsed: AdvertisementOptions{ 52 | LocalName: "Heart rate", 53 | ServiceUUIDs: []UUID{ 54 | ServiceUUIDHeartRate, 55 | ServiceUUIDBattery, 56 | }, 57 | }, 58 | }, 59 | { 60 | raw: "\x02\x01\x06" + // flags 61 | "\a\xff\x34\x12asdf", // manufacturer data 62 | parsed: AdvertisementOptions{ 63 | ManufacturerData: []ManufacturerDataElement{ 64 | {0x1234, []byte("asdf")}, 65 | }, 66 | }, 67 | }, 68 | { 69 | raw: "\x02\x01\x06" + // flags 70 | "\x04\xff\x34\x12\x05" + // manufacturer data 1 71 | "\x05\xff\xff\xff\x03\x07" + // manufacturer data 2 72 | "\x03\xff\x11\x00", // manufacturer data 3 73 | parsed: AdvertisementOptions{ 74 | ManufacturerData: []ManufacturerDataElement{ 75 | {0x1234, []byte{5}}, 76 | {0xffff, []byte{3, 7}}, 77 | {0x0011, []byte{}}, 78 | }, 79 | }, 80 | }, 81 | { 82 | raw: "\x02\x01\x06" + // flags 83 | "\x05\x16\xD2\xFC\x40\x02" + // service data 16-Bit UUID 84 | "\x06\x20\xD2\xFC\x40\x02\xC4", // service data 32-Bit UUID 85 | parsed: AdvertisementOptions{ 86 | ServiceData: []ServiceDataElement{ 87 | {UUID: New16BitUUID(0xFCD2), Data: []byte{0x40, 0x02}}, 88 | {UUID: New32BitUUID(0x0240FCD2), Data: []byte{0xC4}}, 89 | }, 90 | }, 91 | }, 92 | { 93 | raw: "\x02\x01\x06" + // flags 94 | "\x05\x16\xD2\xFC\x40\x02" + // service data 16-Bit UUID 95 | "\x05\x16\xD3\xFC\x40\x02", // service data 16-Bit UUID 96 | parsed: AdvertisementOptions{ 97 | ServiceData: []ServiceDataElement{ 98 | {UUID: New16BitUUID(0xFCD2), Data: []byte{0x40, 0x02}}, 99 | {UUID: New16BitUUID(0xFCD3), Data: []byte{0x40, 0x02}}, 100 | }, 101 | }, 102 | }, 103 | { 104 | raw: "\x02\x01\x06" + // flags 105 | "\x04\x16\xD2\xFC\x40" + // service data 16-Bit UUID 106 | "\x12\x21\xB8\x6C\x75\x05\xE9\x25\xBD\x93\xA8\x42\x32\xC3\x00\x01\xAF\xAD\x09", // service data 128-Bit UUID 107 | parsed: AdvertisementOptions{ 108 | ServiceData: []ServiceDataElement{ 109 | {UUID: New16BitUUID(0xFCD2), Data: []byte{0x40}}, 110 | { 111 | UUID: NewUUID([16]byte{0xad, 0xaf, 0x01, 0x00, 0xc3, 0x32, 0x42, 0xa8, 0x93, 0xbd, 0x25, 0xe9, 0x05, 0x75, 0x6c, 0xb8}), 112 | Data: []byte{0x09}, 113 | }, 114 | }, 115 | }, 116 | }, 117 | } 118 | for _, tc := range tests { 119 | var expectedRaw rawAdvertisementPayload 120 | expectedRaw.len = uint8(len(tc.raw)) 121 | copy(expectedRaw.data[:], tc.raw) 122 | 123 | var raw rawAdvertisementPayload 124 | raw.addFromOptions(tc.parsed) 125 | if raw != expectedRaw { 126 | t.Errorf("error when serializing options: %#v\nexpected: %#v\nactual: %#v\n", tc.parsed, tc.raw, string(raw.data[:raw.len])) 127 | } 128 | mdata := raw.ManufacturerData() 129 | if !reflect.DeepEqual(mdata, tc.parsed.ManufacturerData) { 130 | t.Errorf("ManufacturerData was not parsed as expected:\nexpected: %#v\nactual: %#v", tc.parsed.ManufacturerData, mdata) 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /gatts.go: -------------------------------------------------------------------------------- 1 | package bluetooth 2 | 3 | // Service is a GATT service to be used in AddService. 4 | type Service struct { 5 | handle uint16 6 | UUID 7 | Characteristics []CharacteristicConfig 8 | } 9 | 10 | type WriteEvent = func(client Connection, offset int, value []byte) 11 | 12 | // CharacteristicConfig contains some parameters for the configuration of a 13 | // single characteristic. 14 | // 15 | // The Handle field may be nil. If it is set, it points to a characteristic 16 | // handle that can be used to access the characteristic at a later time. 17 | type CharacteristicConfig struct { 18 | Handle *Characteristic 19 | UUID 20 | Value []byte 21 | Flags CharacteristicPermissions 22 | WriteEvent WriteEvent 23 | } 24 | 25 | // CharacteristicPermissions lists a number of basic permissions/capabilities 26 | // that clients have regarding this characteristic. For example, if you want to 27 | // allow clients to read the value of this characteristic (a common scenario), 28 | // set the Read permission. 29 | type CharacteristicPermissions uint8 30 | 31 | // Characteristic permission bitfields. 32 | const ( 33 | CharacteristicBroadcastPermission CharacteristicPermissions = 1 << iota 34 | CharacteristicReadPermission 35 | CharacteristicWriteWithoutResponsePermission 36 | CharacteristicWritePermission 37 | CharacteristicNotifyPermission 38 | CharacteristicIndicatePermission 39 | ) 40 | 41 | // Broadcast returns whether broadcasting of the value is permitted. 42 | func (p CharacteristicPermissions) Broadcast() bool { 43 | return p&CharacteristicBroadcastPermission != 0 44 | } 45 | 46 | // Read returns whether reading of the value is permitted. 47 | func (p CharacteristicPermissions) Read() bool { 48 | return p&CharacteristicReadPermission != 0 49 | } 50 | 51 | // Write returns whether writing of the value with Write Request is permitted. 52 | func (p CharacteristicPermissions) Write() bool { 53 | return p&CharacteristicWritePermission != 0 54 | } 55 | 56 | // WriteWithoutResponse returns whether writing of the value with Write Command 57 | // is permitted. 58 | func (p CharacteristicPermissions) WriteWithoutResponse() bool { 59 | return p&CharacteristicWriteWithoutResponsePermission != 0 60 | } 61 | 62 | // Notify returns whether notifications are permitted. 63 | func (p CharacteristicPermissions) Notify() bool { 64 | return p&CharacteristicNotifyPermission != 0 65 | } 66 | 67 | // Indicate returns whether indications are permitted. 68 | func (p CharacteristicPermissions) Indicate() bool { 69 | return p&CharacteristicIndicatePermission != 0 70 | } 71 | -------------------------------------------------------------------------------- /gatts_hci.go: -------------------------------------------------------------------------------- 1 | //go:build hci || ninafw || cyw43439 2 | 3 | package bluetooth 4 | 5 | type Characteristic struct { 6 | adapter *Adapter 7 | handle uint16 8 | permissions CharacteristicPermissions 9 | value []byte 10 | cccd uint16 11 | } 12 | 13 | // AddService creates a new service with the characteristics listed in the 14 | // Service struct. 15 | func (a *Adapter) AddService(service *Service) error { 16 | uuid := service.UUID.Bytes() 17 | serviceHandle := a.att.addLocalAttribute(attributeTypeService, 0, shortUUID(gattServiceUUID).UUID(), 0, uuid[:]) 18 | valueHandle := serviceHandle 19 | endHandle := serviceHandle 20 | 21 | for i := range service.Characteristics { 22 | data := service.Characteristics[i].UUID.Bytes() 23 | cuuid := append([]byte{}, data[:]...) 24 | 25 | // add characteristic declaration 26 | charHandle := a.att.addLocalAttribute(attributeTypeCharacteristic, serviceHandle, shortUUID(gattCharacteristicUUID).UUID(), CharacteristicReadPermission, cuuid[:]) 27 | 28 | // add characteristic value 29 | vf := CharacteristicPermissions(0) 30 | if service.Characteristics[i].Flags.Read() { 31 | vf |= CharacteristicReadPermission 32 | } 33 | if service.Characteristics[i].Flags.Write() { 34 | vf |= CharacteristicWritePermission 35 | } 36 | valueHandle = a.att.addLocalAttribute(attributeTypeCharacteristicValue, charHandle, service.Characteristics[i].UUID, vf, service.Characteristics[i].Value) 37 | endHandle = valueHandle 38 | 39 | // add characteristic descriptor 40 | if service.Characteristics[i].Flags.Notify() || 41 | service.Characteristics[i].Flags.Indicate() { 42 | endHandle = a.att.addLocalAttribute(attributeTypeDescriptor, charHandle, shortUUID(gattClientCharacteristicConfigUUID).UUID(), CharacteristicReadPermission|CharacteristicWritePermission, []byte{0, 0}) 43 | } 44 | 45 | if service.Characteristics[i].Handle == nil { 46 | service.Characteristics[i].Handle = &Characteristic{} 47 | } 48 | 49 | service.Characteristics[i].Handle.adapter = a 50 | service.Characteristics[i].Handle.handle = valueHandle 51 | service.Characteristics[i].Handle.permissions = service.Characteristics[i].Flags 52 | if len(service.Characteristics[i].Value) > 0 { 53 | service.Characteristics[i].Handle.value = service.Characteristics[i].Value 54 | } 55 | 56 | if (service.Characteristics[i].Flags.Write() || 57 | service.Characteristics[i].Flags.WriteWithoutResponse()) && 58 | service.Characteristics[i].WriteEvent != nil { 59 | handlers := append(a.charWriteHandlers, charWriteHandler{ 60 | handle: valueHandle, 61 | callback: service.Characteristics[i].WriteEvent, 62 | }) 63 | a.charWriteHandlers = handlers 64 | } 65 | 66 | if debug { 67 | println("added characteristic", charHandle, valueHandle, service.Characteristics[i].UUID.String()) 68 | } 69 | 70 | a.att.addLocalCharacteristic(charHandle, service.Characteristics[i].Flags, valueHandle, service.Characteristics[i].UUID, service.Characteristics[i].Handle) 71 | } 72 | 73 | if debug { 74 | println("added service", serviceHandle, endHandle, service.UUID.String()) 75 | } 76 | 77 | a.att.addLocalService(serviceHandle, endHandle, service.UUID) 78 | 79 | return nil 80 | } 81 | 82 | // Write replaces the characteristic value with a new value. 83 | func (c *Characteristic) Write(p []byte) (n int, err error) { 84 | if !(c.permissions.Write() || c.permissions.WriteWithoutResponse() || 85 | c.permissions.Notify() || c.permissions.Indicate()) { 86 | return 0, errNoWrite 87 | } 88 | 89 | hdl := c.adapter.getCharWriteHandler(c.handle) 90 | if hdl != nil { 91 | hdl.callback(Connection(c.handle), 0, p) 92 | } 93 | 94 | copy(c.value, p) 95 | 96 | if c.cccd&0x01 != 0 { 97 | // send notification 98 | c.adapter.att.sendNotification(c.handle, c.value) 99 | } 100 | 101 | return len(c.value), nil 102 | } 103 | 104 | func (c *Characteristic) readCCCD() (uint16, error) { 105 | if !c.permissions.Notify() { 106 | return 0, errNoNotify 107 | } 108 | 109 | return c.cccd, nil 110 | } 111 | 112 | func (c *Characteristic) writeCCCD(val uint16) error { 113 | if !c.permissions.Notify() { 114 | return errNoNotify 115 | } 116 | 117 | c.cccd = val 118 | 119 | return nil 120 | } 121 | 122 | func (c *Characteristic) readValue() ([]byte, error) { 123 | if !c.permissions.Read() { 124 | return nil, errNoRead 125 | } 126 | 127 | return c.value, nil 128 | } 129 | -------------------------------------------------------------------------------- /gatts_other.go: -------------------------------------------------------------------------------- 1 | //go:build !linux && !windows 2 | 3 | package bluetooth 4 | 5 | // Characteristic is a single characteristic in a service. It has an UUID and a 6 | // value. 7 | type Characteristic struct { 8 | permissions CharacteristicPermissions 9 | } 10 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module tinygo.org/x/bluetooth 2 | 3 | go 1.20 4 | 5 | require ( 6 | github.com/go-ole/go-ole v1.2.6 7 | github.com/godbus/dbus/v5 v5.1.0 8 | github.com/saltosystems/winrt-go v0.0.0-20240509164145-4f7860a3bd2b 9 | github.com/soypat/cyw43439 v0.0.0-20241116210509-ae1ce0e084c5 10 | github.com/tinygo-org/cbgo v0.0.4 11 | golang.org/x/crypto v0.12.0 12 | tinygo.org/x/drivers v0.28.1-0.20241028090715-76a4276b5dea 13 | tinygo.org/x/tinyfont v0.4.0 14 | tinygo.org/x/tinyterm v0.3.1-0.20241028084705-e36d93d72cca 15 | ) 16 | 17 | require ( 18 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect 19 | github.com/sirupsen/logrus v1.9.3 // indirect 20 | github.com/soypat/seqs v0.0.0-20240527012110-1201bab640ef // indirect 21 | github.com/tinygo-org/pio v0.0.0-20231216154340-cd888eb58899 // indirect 22 | golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691 // indirect 23 | golang.org/x/sys v0.11.0 // indirect 24 | golang.org/x/term v0.11.0 // indirect 25 | ) 26 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= 5 | github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= 6 | github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= 7 | github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 8 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= 9 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= 10 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 11 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 12 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 13 | github.com/saltosystems/winrt-go v0.0.0-20240509164145-4f7860a3bd2b h1:du3zG5fd8snsFN6RBoLA7fpaYV9ZQIsyH9snlk2Zvik= 14 | github.com/saltosystems/winrt-go v0.0.0-20240509164145-4f7860a3bd2b/go.mod h1:CIltaIm7qaANUIvzr0Vmz71lmQMAIbGJ7cvgzX7FMfA= 15 | github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= 16 | github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= 17 | github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 18 | github.com/soypat/cyw43439 v0.0.0-20241116210509-ae1ce0e084c5 h1:arwJFX1x5zq+wUp5ADGgudhMQEXKNMQOmTh+yYgkwzw= 19 | github.com/soypat/cyw43439 v0.0.0-20241116210509-ae1ce0e084c5/go.mod h1:1Otjk6PRhfzfcVHeWMEeku/VntFqWghUwuSQyivb2vE= 20 | github.com/soypat/seqs v0.0.0-20240527012110-1201bab640ef h1:phH95I9wANjTYw6bSYLZDQfNvao+HqYDom8owbNa0P4= 21 | github.com/soypat/seqs v0.0.0-20240527012110-1201bab640ef/go.mod h1:oCVCNGCHMKoBj97Zp9znLbQ1nHxpkmOY9X+UAGzOxc8= 22 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 23 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 24 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 25 | github.com/stretchr/testify v1.7.5 h1:s5PTfem8p8EbKQOctVV53k6jCJt3UX4IEJzwh+C324Q= 26 | github.com/tinygo-org/cbgo v0.0.4 h1:3D76CRYbH03Rudi8sEgs/YO0x3JIMdyq8jlQtk/44fU= 27 | github.com/tinygo-org/cbgo v0.0.4/go.mod h1:7+HgWIHd4nbAz0ESjGlJ1/v9LDU1Ox8MGzP9mah/fLk= 28 | github.com/tinygo-org/pio v0.0.0-20231216154340-cd888eb58899 h1:/DyaXDEWMqoVUVEJVJIlNk1bXTbFs8s3Q4GdPInSKTQ= 29 | github.com/tinygo-org/pio v0.0.0-20231216154340-cd888eb58899/go.mod h1:LU7Dw00NJ+N86QkeTGjMLNkYcEYMor6wTDpTCu0EaH8= 30 | golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= 31 | golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= 32 | golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691 h1:/yRP+0AN7mf5DkD3BAI6TOFnd51gEoDEb8o35jIFtgw= 33 | golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= 34 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 35 | golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 36 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 37 | golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= 38 | golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 39 | golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= 40 | golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= 41 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 42 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 43 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 44 | tinygo.org/x/drivers v0.28.1-0.20241028090715-76a4276b5dea h1:1ORaETzQPC3iCAda5TW35HiqbSji3JPu8cKZBfyG7P8= 45 | tinygo.org/x/drivers v0.28.1-0.20241028090715-76a4276b5dea/go.mod h1:q/mU8G/wz821p8xXqbkBACOlmZFDHXd//DnYnCW+dDQ= 46 | tinygo.org/x/tinyfont v0.4.0 h1:XexPKEKiHInf6p4CMCJwsIheVPY0T46HUs6ictYyZfE= 47 | tinygo.org/x/tinyfont v0.4.0/go.mod h1:7nVj3j3geqBoPDzpFukAhF1C8AP9YocMsZy0HSAcGCA= 48 | tinygo.org/x/tinyterm v0.3.1-0.20241028084705-e36d93d72cca h1:rEyh4NoFMxPwD1xlkOMF0tQlec2MZICdOrKE9KMYt2c= 49 | tinygo.org/x/tinyterm v0.3.1-0.20241028084705-e36d93d72cca/go.mod h1:cA/wQ+7eghtbs4ZB+xn9qhZoUIe4lRcsr6KID5iO78g= 50 | -------------------------------------------------------------------------------- /hci_cyw43439.go: -------------------------------------------------------------------------------- 1 | //go:build cyw43439 2 | 3 | package bluetooth 4 | 5 | const ( 6 | ogfVendor = 0x3f 7 | 8 | ocfSetBTMACAddr = 0x0001 9 | ) 10 | 11 | func (a *Adapter) SetBdAddr(address Address) error { 12 | return a.hci.setBdAddr(address) 13 | } 14 | 15 | func (h *hci) setBdAddr(address Address) error { 16 | hciPacket := make([]byte, len(address.MACAddress.MAC)) 17 | // Reverse the byte order as per spec 18 | for i := range address.MACAddress.MAC { 19 | hciPacket[i] = address.MACAddress.MAC[len(address.MACAddress.MAC)-1-i] 20 | } 21 | 22 | if err := h.sendWithoutResponse(ogfVendor<= '0' && c <= '9' { 21 | nibble = c - '0' + 0x0 22 | } else if c >= 'A' && c <= 'F' { 23 | nibble = c - 'A' + 0xA 24 | } else { 25 | err = errInvalidMAC 26 | return 27 | } 28 | if macIndex < 0 { 29 | err = errInvalidMAC 30 | return 31 | } 32 | if macIndex%2 == 0 { 33 | mac[macIndex/2] |= nibble 34 | } else { 35 | mac[macIndex/2] |= nibble << 4 36 | } 37 | macIndex-- 38 | } 39 | if macIndex != -1 { 40 | err = errInvalidMAC 41 | } 42 | return 43 | } 44 | 45 | // String returns a human-readable version of this MAC address, such as 46 | // 11:22:33:AA:BB:CC. 47 | func (mac MAC) String() string { 48 | // TODO: make this more efficient. 49 | s := "" 50 | for i := 5; i >= 0; i-- { 51 | c := mac[i] 52 | // Insert a hyphen at the correct locations. 53 | if i != 5 { 54 | s += ":" 55 | } 56 | 57 | // First nibble. 58 | nibble := c >> 4 59 | if nibble <= 9 { 60 | s += string(nibble + '0') 61 | } else { 62 | s += string(nibble + 'A' - 10) 63 | } 64 | 65 | // Second nibble. 66 | nibble = c & 0x0f 67 | if nibble <= 9 { 68 | s += string(nibble + '0') 69 | } else { 70 | s += string(nibble + 'A' - 10) 71 | } 72 | } 73 | 74 | return s 75 | } 76 | -------------------------------------------------------------------------------- /nodebug.go: -------------------------------------------------------------------------------- 1 | //go:build !bledebug 2 | 3 | package bluetooth 4 | 5 | var debug = false 6 | -------------------------------------------------------------------------------- /rawterm/hosted.go: -------------------------------------------------------------------------------- 1 | //go:build (linux && !baremetal) || darwin 2 | 3 | // Package rawterm provides some sort of raw terminal interface, both on hosted 4 | // systems and baremetal. It is intended only for use by examples. 5 | // 6 | // Newlines are always LF (not CR or CRLF). While terminals generally use a 7 | // different format (CR when pressing the enter key and CRLF for newline) the 8 | // format returned by Getchar and expected as input by Putchar is a single LF 9 | // as newline symbol. 10 | package rawterm 11 | 12 | import ( 13 | "os" 14 | 15 | "golang.org/x/crypto/ssh/terminal" 16 | ) 17 | 18 | var terminalState *terminal.State 19 | 20 | // Getchar returns a single character from stdin, or a serial input. Newlines 21 | // are encoded with a single LF ('\n'). 22 | func Getchar() byte { 23 | var b [1]byte 24 | os.Stdin.Read(b[:]) 25 | if b[0] == '\r' { 26 | return '\n' 27 | } 28 | return b[0] 29 | } 30 | 31 | // Putchar writes a single character to the terminal. Newlines are expected to 32 | // be encoded as LF symbols ('\n'). 33 | func Putchar(ch byte) { 34 | if ch == '\n' { 35 | // Terminals expect CRLF. 36 | Putchar('\r') 37 | } 38 | b := [1]byte{ch} 39 | os.Stdout.Write(b[:]) 40 | } 41 | 42 | // Configure initializes the terminal for use by raw reading/writing (using 43 | // Getchar/Putchar). It must be restored after use with Restore. You can do this 44 | // with the following code: 45 | // 46 | // rawterm.Configure() 47 | // defer rawterm.Restore() 48 | // // use raw terminal features 49 | func Configure() { 50 | terminalState, _ = terminal.MakeRaw(0) 51 | } 52 | 53 | // Restore restores the state to before a call to Configure. It must be called 54 | // after a call to Configure to restore the terminal state, and must only be 55 | // called after a call to Configure. 56 | func Restore() { 57 | terminal.Restore(0, terminalState) 58 | } 59 | -------------------------------------------------------------------------------- /rawterm/nrf.go: -------------------------------------------------------------------------------- 1 | //go:build nrf 2 | 3 | package rawterm 4 | 5 | import ( 6 | "machine" 7 | "time" 8 | ) 9 | 10 | var serial = machine.UART0 11 | 12 | // Getchar returns a single character from stdin, or a serial input. Newlines 13 | // are encoded with a single LF ('\n'). 14 | func Getchar() byte { 15 | for { 16 | // TODO: let ReadByte block instead of polling here. 17 | time.Sleep(1 * time.Millisecond) 18 | if serial.Buffered() <= 0 { 19 | continue 20 | } 21 | ch, _ := serial.ReadByte() 22 | if ch == 0 { 23 | continue 24 | } 25 | if ch == '\r' { 26 | ch = '\n' 27 | } 28 | return ch 29 | } 30 | } 31 | 32 | // Putchar writes a single character to the terminal. Newlines are expected to 33 | // be encoded as LF symbols ('\n'). 34 | func Putchar(ch byte) { 35 | if ch == '\n' { 36 | serial.WriteByte('\r') 37 | } 38 | serial.WriteByte(ch) 39 | } 40 | 41 | // Configure initializes the terminal for use by raw reading/writing (using 42 | // Getchar/Putchar). It must be restored after use with Restore. You can do this 43 | // with the following code: 44 | // 45 | // rawterm.Configure() 46 | // defer rawterm.Restore() 47 | // // use raw terminal features 48 | func Configure() { 49 | } 50 | 51 | // Restore restores the state to before a call to Configure. It must be called 52 | // after a call to Configure to restore the terminal state, and must only be 53 | // called after a call to Configure. 54 | func Restore() { 55 | } 56 | -------------------------------------------------------------------------------- /s110_nrf51_8.0.0/s110_nrf51_8.0.0_API/include/ble_err.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 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 must reproduce the above copyright notice, this 12 | * list of conditions and the following disclaimer in the documentation and/or 13 | * other materials provided with the distribution. 14 | * 15 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of other 16 | * contributors to this software may be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * 4. This software must only be used in a processor manufactured by Nordic 20 | * Semiconductor ASA, or in a processor manufactured by a third party that 21 | * is used in combination with a processor manufactured by Nordic Semiconductor. 22 | * 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 28 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 31 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | * 35 | */ 36 | 37 | /** 38 | @addtogroup BLE_COMMON 39 | @{ 40 | @addtogroup nrf_error 41 | @{ 42 | @ingroup BLE_COMMON 43 | @} 44 | 45 | @defgroup ble_err General error codes 46 | @{ 47 | 48 | @brief General error code definitions for the BLE API. 49 | 50 | @ingroup BLE_COMMON 51 | */ 52 | #ifndef NRF_BLE_ERR_H__ 53 | #define NRF_BLE_ERR_H__ 54 | 55 | #include "nrf_error.h" 56 | 57 | /* @defgroup BLE_ERRORS Error Codes 58 | * @{ */ 59 | #define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */ 60 | #define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */ 61 | #define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */ 62 | #define BLE_ERROR_NO_TX_BUFFERS (NRF_ERROR_STK_BASE_NUM+0x004) /**< Buffer capacity exceeded. */ 63 | #define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */ 64 | /** @} */ 65 | 66 | 67 | /** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges 68 | * @brief Assignment of subranges for module specific error codes. 69 | * @note For specific error codes, see ble_.h or ble_error_.h. 70 | * @{ */ 71 | #define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */ 72 | #define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */ 73 | #define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */ 74 | #define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */ 75 | /** @} */ 76 | 77 | #endif 78 | 79 | 80 | /** 81 | @} 82 | @} 83 | */ 84 | -------------------------------------------------------------------------------- /s110_nrf51_8.0.0/s110_nrf51_8.0.0_API/include/nrf_error.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 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 must reproduce the above copyright notice, this 12 | * list of conditions and the following disclaimer in the documentation and/or 13 | * other materials provided with the distribution. 14 | * 15 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of other 16 | * contributors to this software may be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * 4. This software must only be used in a processor manufactured by Nordic 20 | * Semiconductor ASA, or in a processor manufactured by a third party that 21 | * is used in combination with a processor manufactured by Nordic Semiconductor. 22 | * 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 28 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 31 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | * 35 | */ 36 | /** 37 | @defgroup nrf_error SoftDevice Global Error Codes 38 | @{ 39 | 40 | @brief Global Error definitions 41 | */ 42 | 43 | /* Header guard */ 44 | #ifndef NRF_ERROR_H__ 45 | #define NRF_ERROR_H__ 46 | 47 | /** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions 48 | * @{ */ 49 | #define NRF_ERROR_BASE_NUM (0x0) ///< Global error base 50 | #define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base 51 | #define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base 52 | #define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base 53 | /** @} */ 54 | 55 | #define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command 56 | #define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing 57 | #define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled 58 | #define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error 59 | #define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation 60 | #define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found 61 | #define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported 62 | #define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter 63 | #define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state 64 | #define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length 65 | #define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags 66 | #define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data 67 | #define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Data size exceeds limit 68 | #define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out 69 | #define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer 70 | #define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation 71 | #define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address 72 | #define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy 73 | 74 | #endif // NRF_ERROR_H__ 75 | 76 | /** 77 | @} 78 | */ 79 | -------------------------------------------------------------------------------- /s110_nrf51_8.0.0/s110_nrf51_8.0.0_API/include/nrf_error_sdm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 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 must reproduce the above copyright notice, this 12 | * list of conditions and the following disclaimer in the documentation and/or 13 | * other materials provided with the distribution. 14 | * 15 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of other 16 | * contributors to this software may be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * 4. This software must only be used in a processor manufactured by Nordic 20 | * Semiconductor ASA, or in a processor manufactured by a third party that 21 | * is used in combination with a processor manufactured by Nordic Semiconductor. 22 | * 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 28 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 31 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | * 35 | */ 36 | /** 37 | @addtogroup nrf_sdm_api 38 | @{ 39 | @defgroup nrf_sdm_error SoftDevice Manager Error Codes 40 | @{ 41 | 42 | @brief Error definitions for the SDM API 43 | */ 44 | 45 | /* Header guard */ 46 | #ifndef NRF_ERROR_SDM_H__ 47 | #define NRF_ERROR_SDM_H__ 48 | 49 | #include "nrf_error.h" 50 | 51 | #define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown lfclk source. 52 | #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). 53 | #define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erronous SoftDevice flashing). 54 | 55 | #endif // NRF_ERROR_SDM_H__ 56 | 57 | /** 58 | @} 59 | @} 60 | */ 61 | -------------------------------------------------------------------------------- /s110_nrf51_8.0.0/s110_nrf51_8.0.0_API/include/nrf_error_soc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 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 must reproduce the above copyright notice, this 12 | * list of conditions and the following disclaimer in the documentation and/or 13 | * other materials provided with the distribution. 14 | * 15 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of other 16 | * contributors to this software may be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * 4. This software must only be used in a processor manufactured by Nordic 20 | * Semiconductor ASA, or in a processor manufactured by a third party that 21 | * is used in combination with a processor manufactured by Nordic Semiconductor. 22 | * 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 28 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 31 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | * 35 | */ 36 | /** 37 | @addtogroup nrf_soc_api 38 | @{ 39 | @defgroup nrf_soc_error SoC Library Error Codes 40 | @{ 41 | 42 | @brief Error definitions for the SoC library 43 | 44 | */ 45 | 46 | /* Header guard */ 47 | #ifndef NRF_ERROR_SOC_H__ 48 | #define NRF_ERROR_SOC_H__ 49 | 50 | #include "nrf_error.h" 51 | 52 | /* Mutex Errors */ 53 | #define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken 54 | 55 | /* NVIC errors */ 56 | #define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available 57 | #define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed 58 | #define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return 59 | 60 | /* Power errors */ 61 | #define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown 62 | #define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown 63 | #define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return 64 | 65 | /* Rand errors */ 66 | #define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values 67 | 68 | /* PPI errors */ 69 | #define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel 70 | #define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group 71 | 72 | #endif // NRF_ERROR_SOC_H__ 73 | /** 74 | @} 75 | @} 76 | */ 77 | -------------------------------------------------------------------------------- /s110_nrf51_8.0.0/s110_nrf51_8.0.0_API/include/nrf_svc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 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 must reproduce the above copyright notice, this 12 | * list of conditions and the following disclaimer in the documentation and/or 13 | * other materials provided with the distribution. 14 | * 15 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of other 16 | * contributors to this software may be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * 4. This software must only be used in a processor manufactured by Nordic 20 | * Semiconductor ASA, or in a processor manufactured by a third party that 21 | * is used in combination with a processor manufactured by Nordic Semiconductor. 22 | * 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 28 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 31 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | * 35 | */ 36 | 37 | #ifndef NRF_SVC__ 38 | #define NRF_SVC__ 39 | 40 | #ifdef SVCALL_AS_NORMAL_FUNCTION 41 | #define SVCALL(number, return_type, signature) return_type signature 42 | #else 43 | 44 | #ifndef SVCALL 45 | #if defined (__CC_ARM) 46 | #define SVCALL(number, return_type, signature) return_type __svc(number) signature 47 | #elif defined (__GNUC__) 48 | #define SVCALL(number, return_type, signature) \ 49 | _Pragma("GCC diagnostic ignored \"-Wunused-function\"") \ 50 | _Pragma("GCC diagnostic push") \ 51 | _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ 52 | __attribute__((naked)) static return_type signature \ 53 | { \ 54 | __asm( \ 55 | "svc %0\n" \ 56 | "bx r14" : : "I" (number) : "r0" \ 57 | ); \ 58 | } \ 59 | _Pragma("GCC diagnostic pop") 60 | #elif defined (__ICCARM__) 61 | #define PRAGMA(x) _Pragma(#x) 62 | #define SVCALL(number, return_type, signature) \ 63 | PRAGMA(swi_number = number) \ 64 | __swi return_type signature; 65 | #else 66 | #define SVCALL(number, return_type, signature) return_type signature 67 | #endif 68 | #endif // SVCALL 69 | 70 | #endif // SVCALL_AS_NORMAL_FUNCTION 71 | #endif // NRF_SVC__ 72 | -------------------------------------------------------------------------------- /s110_nrf51_8.0.0/s110_nrf51_8.0.0_API/include/softdevice_assert.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 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 must reproduce the above copyright notice, this 12 | * list of conditions and the following disclaimer in the documentation and/or 13 | * other materials provided with the distribution. 14 | * 15 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of other 16 | * contributors to this software may be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * 4. This software must only be used in a processor manufactured by Nordic 20 | * Semiconductor ASA, or in a processor manufactured by a third party that 21 | * is used in combination with a processor manufactured by Nordic Semiconductor. 22 | * 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 28 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 31 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | * 35 | */ 36 | 37 | /** @brief Utilities for verifying program logic 38 | */ 39 | 40 | #ifndef SOFTDEVICE_ASSERT_H_ 41 | #define SOFTDEVICE_ASSERT_H_ 42 | 43 | #include 44 | 45 | /** @brief This function handles assertions. 46 | * 47 | * 48 | * @note 49 | * This function is called when an assertion has triggered. 50 | * 51 | * 52 | * @param line_num The line number where the assertion is called 53 | * @param file_name Pointer to the file name 54 | */ 55 | void assert_softdevice_callback(uint16_t line_num, const uint8_t *file_name); 56 | 57 | 58 | /*lint -emacro(506, ASSERT) */ /* Suppress "Constant value Boolean */ 59 | /*lint -emacro(774, ASSERT) */ /* Suppress "Boolean within 'if' always evaluates to True" */ \ 60 | /** @brief Check intended for production code 61 | * 62 | * Check passes if "expr" evaluates to true. */ 63 | #define ASSERT(expr) \ 64 | if (expr) \ 65 | { \ 66 | } \ 67 | else \ 68 | { \ 69 | assert_softdevice_callback((uint16_t)__LINE__, (uint8_t *)__FILE__); \ 70 | /*lint -unreachable */ \ 71 | } 72 | 73 | #endif /* SOFTDEVICE_ASSERT_H_ */ 74 | -------------------------------------------------------------------------------- /s110_nrf51_8.0.0/s110_nrf51_8.0.0_licence_agreement.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinygo-org/bluetooth/b82048cd9da0fdabb6f2508f461c364184087b3a/s110_nrf51_8.0.0/s110_nrf51_8.0.0_licence_agreement.txt -------------------------------------------------------------------------------- /s113_nrf52_7.0.1/s113_nrf52_7.0.1_API/include/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 | -------------------------------------------------------------------------------- /s113_nrf52_7.0.1/s113_nrf52_7.0.1_API/include/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 | -------------------------------------------------------------------------------- /s113_nrf52_7.0.1/s113_nrf52_7.0.1_API/include/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 | -------------------------------------------------------------------------------- /s113_nrf52_7.0.1/s113_nrf52_7.0.1_API/include/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 | -------------------------------------------------------------------------------- /s113_nrf52_7.0.1/s113_nrf52_7.0.1_license-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 | -------------------------------------------------------------------------------- /s132_nrf52_6.1.1/s132_nrf52_6.1.1_API/include/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 | -------------------------------------------------------------------------------- /s132_nrf52_6.1.1/s132_nrf52_6.1.1_API/include/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 | -------------------------------------------------------------------------------- /s132_nrf52_6.1.1/s132_nrf52_6.1.1_API/include/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 | -------------------------------------------------------------------------------- /s132_nrf52_6.1.1/s132_nrf52_6.1.1_API/include/nrf_svc.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 | #ifndef NRF_SVC__ 40 | #define NRF_SVC__ 41 | 42 | #include "stdint.h" 43 | 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | #ifdef SVCALL_AS_NORMAL_FUNCTION 49 | #define SVCALL(number, return_type, signature) return_type signature 50 | #else 51 | 52 | #ifndef SVCALL 53 | #if defined (__CC_ARM) 54 | #define SVCALL(number, return_type, signature) return_type __svc(number) signature 55 | #elif defined (__GNUC__) 56 | #ifdef __cplusplus 57 | #define GCC_CAST_CPP (uint16_t) 58 | #else 59 | #define GCC_CAST_CPP 60 | #endif 61 | #define SVCALL(number, return_type, signature) \ 62 | _Pragma("GCC diagnostic push") \ 63 | _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ 64 | __attribute__((naked)) \ 65 | __attribute__((unused)) \ 66 | static return_type signature \ 67 | { \ 68 | __asm( \ 69 | "svc %0\n" \ 70 | "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \ 71 | ); \ 72 | } \ 73 | _Pragma("GCC diagnostic pop") 74 | 75 | #elif defined (__ICCARM__) 76 | #define PRAGMA(x) _Pragma(#x) 77 | #define SVCALL(number, return_type, signature) \ 78 | PRAGMA(swi_number = (number)) \ 79 | __swi return_type signature; 80 | #else 81 | #define SVCALL(number, return_type, signature) return_type signature 82 | #endif 83 | #endif // SVCALL 84 | 85 | #endif // SVCALL_AS_NORMAL_FUNCTION 86 | 87 | #ifdef __cplusplus 88 | } 89 | #endif 90 | #endif // NRF_SVC__ 91 | -------------------------------------------------------------------------------- /s132_nrf52_6.1.1/s132_nrf52_6.1.1_license-agreement.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007 - 2018, 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 | -------------------------------------------------------------------------------- /s140_nrf52_6.1.1/s140_nrf52_6.1.1_API/include/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 | -------------------------------------------------------------------------------- /s140_nrf52_6.1.1/s140_nrf52_6.1.1_API/include/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 | -------------------------------------------------------------------------------- /s140_nrf52_6.1.1/s140_nrf52_6.1.1_API/include/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 | -------------------------------------------------------------------------------- /s140_nrf52_6.1.1/s140_nrf52_6.1.1_API/include/nrf_svc.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 | #ifndef NRF_SVC__ 40 | #define NRF_SVC__ 41 | 42 | #include "stdint.h" 43 | 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | #ifdef SVCALL_AS_NORMAL_FUNCTION 49 | #define SVCALL(number, return_type, signature) return_type signature 50 | #else 51 | 52 | #ifndef SVCALL 53 | #if defined (__CC_ARM) 54 | #define SVCALL(number, return_type, signature) return_type __svc(number) signature 55 | #elif defined (__GNUC__) 56 | #ifdef __cplusplus 57 | #define GCC_CAST_CPP (uint16_t) 58 | #else 59 | #define GCC_CAST_CPP 60 | #endif 61 | #define SVCALL(number, return_type, signature) \ 62 | _Pragma("GCC diagnostic push") \ 63 | _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ 64 | __attribute__((naked)) \ 65 | __attribute__((unused)) \ 66 | static return_type signature \ 67 | { \ 68 | __asm( \ 69 | "svc %0\n" \ 70 | "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \ 71 | ); \ 72 | } \ 73 | _Pragma("GCC diagnostic pop") 74 | 75 | #elif defined (__ICCARM__) 76 | #define PRAGMA(x) _Pragma(#x) 77 | #define SVCALL(number, return_type, signature) \ 78 | PRAGMA(swi_number = (number)) \ 79 | __swi return_type signature; 80 | #else 81 | #define SVCALL(number, return_type, signature) return_type signature 82 | #endif 83 | #endif // SVCALL 84 | 85 | #endif // SVCALL_AS_NORMAL_FUNCTION 86 | 87 | #ifdef __cplusplus 88 | } 89 | #endif 90 | #endif // NRF_SVC__ 91 | -------------------------------------------------------------------------------- /s140_nrf52_6.1.1/s140_nrf52_6.1.1_license-agreement.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007 - 2018, 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 | -------------------------------------------------------------------------------- /s140_nrf52_7.3.0/s140_nrf52_7.3.0_API/include/ble_err.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 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 | -------------------------------------------------------------------------------- /s140_nrf52_7.3.0/s140_nrf52_7.3.0_API/include/nrf_error_sdm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 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 | -------------------------------------------------------------------------------- /s140_nrf52_7.3.0/s140_nrf52_7.3.0_API/include/nrf_error_soc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 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 | -------------------------------------------------------------------------------- /s140_nrf52_7.3.0/s140_nrf52_7.3.0_API/include/nrf_svc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 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 | -------------------------------------------------------------------------------- /s140_nrf52_7.3.0/s140_nrf52_7.3.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 | -------------------------------------------------------------------------------- /tools/gen-characteristic-uuids/main.go: -------------------------------------------------------------------------------- 1 | //go:build ignore 2 | 3 | package main 4 | 5 | import ( 6 | "encoding/hex" 7 | "encoding/json" 8 | "fmt" 9 | "io/ioutil" 10 | "os" 11 | "regexp" 12 | "strings" 13 | "text/template" 14 | "time" 15 | 16 | "golang.org/x/text/cases" 17 | "golang.org/x/text/language" 18 | 19 | "tinygo.org/x/bluetooth" 20 | ) 21 | 22 | type Characteristic struct { 23 | Name string `json:"name"` 24 | Identifier string `json:"identifier"` 25 | UUID string `json:"uuid"` 26 | Source string `json:"source"` 27 | } 28 | 29 | func (c Characteristic) VarName() string { 30 | str := strings.ReplaceAll(c.Name, "Characteristic", "") 31 | 32 | // Remove non-alphanumeric characters. 33 | var nonAlphanumericRegex = regexp.MustCompile(`[^a-zA-Z0-9 ]+`) 34 | str = nonAlphanumericRegex.ReplaceAllString(str, "") 35 | 36 | str = cases.Title(language.Und, cases.NoLower).String(str) 37 | return strings.ReplaceAll(str, " ", "") 38 | } 39 | 40 | func (c Characteristic) UUIDFunc() string { 41 | if len(c.UUID) == 4 { 42 | return "New16BitUUID(0x" + c.UUID + ")" 43 | } 44 | uuid, err := bluetooth.ParseUUID(strings.ToLower(c.UUID)) 45 | if err != nil { 46 | panic(err) 47 | } 48 | b := uuid.Bytes() 49 | bs := hex.EncodeToString(b[:]) 50 | bss := "" 51 | for i := 0; i < len(bs); i += 2 { 52 | bss = "0x" + bs[i:i+2] + "," + bss 53 | } 54 | return "NewUUID([16]byte{" + bss + "})" 55 | } 56 | 57 | func dedupCharacteristics(characteristics []Characteristic) []Characteristic { 58 | // Group characteristics by name. 59 | byName := make(map[string][]Characteristic) 60 | for _, c := range characteristics { 61 | byName[c.Name] = append(byName[c.Name], c) 62 | } 63 | 64 | var newCharacteristics []Characteristic 65 | 66 | // Find duplicate characteristics and rename them. 67 | for name, cs := range byName { 68 | for i, c := range cs { 69 | if len(cs) > 1 { 70 | c.Name = fmt.Sprintf("%s %d", name, i+1) 71 | } 72 | newCharacteristics = append(newCharacteristics, c) 73 | } 74 | } 75 | 76 | return newCharacteristics 77 | } 78 | 79 | func main() { 80 | jsonFile, err := os.Open("bluetooth-numbers-database/v1/characteristic_uuids.json") 81 | if err != nil { 82 | fmt.Println(err) 83 | } 84 | 85 | defer jsonFile.Close() 86 | 87 | data, _ := ioutil.ReadAll(jsonFile) 88 | 89 | var characteristics []Characteristic 90 | json.Unmarshal(data, &characteristics) 91 | 92 | characteristics = dedupCharacteristics(characteristics) 93 | 94 | f, err := os.Create("characteristic_uuids.go") 95 | if err != nil { 96 | fmt.Println(err) 97 | return 98 | } 99 | defer f.Close() 100 | 101 | packageTemplate := template.Must(template.New("").Parse(tmpl)) 102 | 103 | packageTemplate.Execute(f, struct { 104 | Timestamp time.Time 105 | Characteristics []Characteristic 106 | }{ 107 | Timestamp: time.Now(), 108 | Characteristics: characteristics, 109 | }) 110 | } 111 | 112 | var tmpl = `// Code generated by bin/gen-characteristic-uuids; DO NOT EDIT. 113 | // This file was generated on {{.Timestamp}} using the list of standard characteristics UUIDs from 114 | // https://github.com/NordicSemiconductor/bluetooth-numbers-database/blob/master/v1/characteristics_uuids.json 115 | // 116 | package bluetooth 117 | 118 | var ( 119 | {{ range .Characteristics }} 120 | // CharacteristicUUID{{.VarName}} - {{.Name}} 121 | CharacteristicUUID{{.VarName}} = {{.UUIDFunc}} 122 | {{ end }} 123 | ) 124 | ` 125 | -------------------------------------------------------------------------------- /tools/gen-service-uuids/main.go: -------------------------------------------------------------------------------- 1 | //go:build ignore 2 | 3 | package main 4 | 5 | import ( 6 | "encoding/hex" 7 | "encoding/json" 8 | "fmt" 9 | "io/ioutil" 10 | "os" 11 | "regexp" 12 | "strings" 13 | "text/template" 14 | "time" 15 | 16 | "golang.org/x/text/cases" 17 | "golang.org/x/text/language" 18 | 19 | "tinygo.org/x/bluetooth" 20 | ) 21 | 22 | type Service struct { 23 | Name string `json:"name"` 24 | Identifier string `json:"identifier"` 25 | UUID string `json:"uuid"` 26 | Source string `json:"source"` 27 | } 28 | 29 | func (s Service) VarName() string { 30 | str := strings.ReplaceAll(s.Name, "Service", "") 31 | 32 | // Remove non-alphanumeric characters. 33 | var nonAlphanumericRegex = regexp.MustCompile(`[^a-zA-Z0-9 ]+`) 34 | str = nonAlphanumericRegex.ReplaceAllString(str, "") 35 | 36 | str = cases.Title(language.Und, cases.NoLower).String(str) 37 | return strings.ReplaceAll(str, " ", "") 38 | } 39 | 40 | func (s Service) UUIDFunc() string { 41 | if len(s.UUID) == 4 { 42 | return "New16BitUUID(0x" + s.UUID + ")" 43 | } 44 | uuid, err := bluetooth.ParseUUID(strings.ToLower(s.UUID)) 45 | if err != nil { 46 | panic(err) 47 | } 48 | b := uuid.Bytes() 49 | bs := hex.EncodeToString(b[:]) 50 | bss := "" 51 | for i := 0; i < len(bs); i += 2 { 52 | bss = "0x" + bs[i:i+2] + "," + bss 53 | } 54 | return "NewUUID([16]byte{" + bss + "})" 55 | } 56 | 57 | func dedupServices(services []Service) []Service { 58 | // Group services by name. 59 | byName := make(map[string][]Service) 60 | for _, svc := range services { 61 | byName[svc.Name] = append(byName[svc.Name], svc) 62 | } 63 | 64 | var newServices []Service 65 | 66 | // Find duplicate services and rename them. 67 | for name, svcs := range byName { 68 | for i, svc := range svcs { 69 | if len(svcs) > 1 { 70 | svc.Name = fmt.Sprintf("%s %d", name, i+1) 71 | } 72 | newServices = append(newServices, svc) 73 | } 74 | } 75 | 76 | return newServices 77 | } 78 | 79 | func main() { 80 | jsonFile, err := os.Open("bluetooth-numbers-database/v1/service_uuids.json") 81 | if err != nil { 82 | fmt.Println(err) 83 | } 84 | 85 | defer jsonFile.Close() 86 | 87 | data, _ := ioutil.ReadAll(jsonFile) 88 | 89 | var services []Service 90 | json.Unmarshal(data, &services) 91 | 92 | services = dedupServices(services) 93 | 94 | f, err := os.Create("service_uuids.go") 95 | if err != nil { 96 | fmt.Println(err) 97 | return 98 | } 99 | defer f.Close() 100 | 101 | packageTemplate := template.Must(template.New("").Parse(tmpl)) 102 | 103 | packageTemplate.Execute(f, struct { 104 | Timestamp time.Time 105 | Services []Service 106 | }{ 107 | Timestamp: time.Now(), 108 | Services: services, 109 | }) 110 | } 111 | 112 | var tmpl = `// Code generated by bin/gen-service-uuids; DO NOT EDIT. 113 | // This file was generated on {{.Timestamp}} using the list of standard service UUIDs from 114 | // https://github.com/NordicSemiconductor/bluetooth-numbers-database/blob/master/v1/service_uuids.json 115 | // 116 | package bluetooth 117 | 118 | var ( 119 | {{ range .Services }} 120 | // ServiceUUID{{.VarName}} - {{.Name}} 121 | ServiceUUID{{.VarName}} = {{.UUIDFunc}} 122 | {{ end }} 123 | ) 124 | ` 125 | -------------------------------------------------------------------------------- /uuid_hci.go: -------------------------------------------------------------------------------- 1 | //go:build hci || ninafw || cyw43439 2 | 3 | package bluetooth 4 | 5 | type shortUUID uint16 6 | 7 | // UUID returns the full length UUID for this short UUID. 8 | func (s shortUUID) UUID() UUID { 9 | return New16BitUUID(uint16(s)) 10 | } 11 | 12 | // isIn checks the passed in slice of UUIDs to see if this uuid is in it. 13 | func (uuid UUID) isIn(uuids []UUID) bool { 14 | for _, u := range uuids { 15 | if u == uuid { 16 | return true 17 | } 18 | } 19 | return false 20 | } 21 | -------------------------------------------------------------------------------- /uuid_sd.go: -------------------------------------------------------------------------------- 1 | //go:build softdevice 2 | 3 | package bluetooth 4 | 5 | /* 6 | #include "ble.h" 7 | */ 8 | import "C" 9 | import "unsafe" 10 | 11 | type shortUUID C.ble_uuid_t 12 | 13 | func (uuid UUID) shortUUID() (C.ble_uuid_t, C.uint32_t) { 14 | var short C.ble_uuid_t 15 | short.uuid = C.uint16_t(uuid[3]) 16 | if uuid.Is16Bit() { 17 | short._type = C.BLE_UUID_TYPE_BLE 18 | return short, 0 19 | } 20 | errCode := C.sd_ble_uuid_vs_add((*C.ble_uuid128_t)(unsafe.Pointer(&uuid[0])), &short._type) 21 | return short, errCode 22 | } 23 | 24 | // UUID returns the full length UUID for this short UUID. 25 | func (s shortUUID) UUID() UUID { 26 | if s._type == C.BLE_UUID_TYPE_BLE { 27 | return New16BitUUID(uint16(s.uuid)) 28 | } 29 | var outLen C.uint8_t 30 | var outUUID UUID 31 | C.sd_ble_uuid_encode(((*C.ble_uuid_t)(unsafe.Pointer(&s))), &outLen, ((*C.uint8_t)(unsafe.Pointer(&outUUID)))) 32 | return outUUID 33 | } 34 | 35 | // IsIn checks the passed in slice of short UUIDs to see if this uuid is in it. 36 | func (s shortUUID) IsIn(uuids []C.ble_uuid_t) bool { 37 | for _, u := range uuids { 38 | if shortUUID(u) == s { 39 | return true 40 | } 41 | } 42 | return false 43 | } 44 | -------------------------------------------------------------------------------- /uuid_test.go: -------------------------------------------------------------------------------- 1 | package bluetooth 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | ) 7 | 8 | func TestUUIDString(t *testing.T) { 9 | checkUUID(t, New16BitUUID(0x1234), "00001234-0000-1000-8000-00805f9b34fb") 10 | } 11 | 12 | func checkUUID(t *testing.T, uuid UUID, check string) { 13 | if uuid.String() != check { 14 | t.Errorf("expected UUID %s but got %s", check, uuid.String()) 15 | } 16 | } 17 | 18 | func TestParseUUIDTooSmall(t *testing.T) { 19 | _, e := ParseUUID("00001234-0000-1000-8000-00805f9b34f") 20 | if e != errInvalidUUID { 21 | t.Errorf("expected errInvalidUUID but got %v", e) 22 | } 23 | } 24 | 25 | func TestParseUUIDTooLarge(t *testing.T) { 26 | _, e := ParseUUID("00001234-0000-1000-8000-00805F9B34FB0") 27 | if e != errInvalidUUID { 28 | t.Errorf("expected errInvalidUUID but got %v", e) 29 | } 30 | } 31 | 32 | func TestStringUUID(t *testing.T) { 33 | uuidString := "00001234-0000-1000-8000-00805f9b34fb" 34 | u, e := ParseUUID(uuidString) 35 | if e != nil { 36 | t.Errorf("expected nil but got %v", e) 37 | } 38 | if u.String() != uuidString { 39 | t.Errorf("expected %s but got %s", uuidString, u.String()) 40 | } 41 | } 42 | 43 | func TestStringUUIDUpperCase(t *testing.T) { 44 | uuidString := strings.ToUpper("00001234-0000-1000-8000-00805f9b34fb") 45 | u, e := ParseUUID(uuidString) 46 | if e != nil { 47 | t.Errorf("expected nil but got %v", e) 48 | } 49 | if !strings.EqualFold(u.String(), uuidString) { 50 | t.Errorf("%s does not match %s ignoring case", uuidString, u.String()) 51 | } 52 | } 53 | 54 | func TestStringUUIDLowerCase(t *testing.T) { 55 | uuidString := strings.ToLower("00001234-0000-1000-8000-00805f9b34fb") 56 | u, e := ParseUUID(uuidString) 57 | if e != nil { 58 | t.Errorf("expected nil but got %v", e) 59 | } 60 | if !strings.EqualFold(u.String(), uuidString) { 61 | t.Errorf("%s does not match %s ignoring case", uuidString, u.String()) 62 | } 63 | } 64 | 65 | func BenchmarkUUIDToString(b *testing.B) { 66 | uuid, e := ParseUUID("00001234-0000-1000-8000-00805f9b34fb") 67 | if e != nil { 68 | b.Errorf("expected nil but got %v", e) 69 | } 70 | for i := 0; i < b.N; i++ { 71 | _ = uuid.String() 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /version.go: -------------------------------------------------------------------------------- 1 | package bluetooth 2 | 3 | // Version returns a user-readable string showing the version of the bluetooth package for support purposes. 4 | // Update this value before release of new version of software. 5 | const Version = "0.11.0" 6 | --------------------------------------------------------------------------------