Skip to content

Commit

Permalink
ninafw: Adding init options to enable customizing hardware
Browse files Browse the repository at this point in the history
  • Loading branch information
bgould committed Jan 16, 2024
1 parent dc7d1b4 commit 731e738
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 20 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ smoketest-tinygo:
@md5sum test.hex
$(TINYGO) build -o test.uf2 -size=short -target=nano-rp2040 ./examples/advertisement
@md5sum test.hex
$(TINYGO) build -o test.uf2 -size=short -target=feather-m4 -tags="ninafw ninafw_featherwing_init" ./examples/advertisement
@md5sum test.hex
$(TINYGO) build -o test.uf2 -size=short -target=pybadge ./examples/advertisement
@md5sum test.hex

smoketest-linux:
# Test on Linux.
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,10 @@ For example, this command can be used to compile and flash an Arduino Nano RP204

tinygo flash -target nano-rp2040 ./examples/heartrate

When using the AirLift WiFi Featherwing with one of Adafruit's feather boards, you can use `ninafw ninafw_featherwing_init` build tags to set up the hardware using the default pins. Make sure to [connect the solder pads on the underside of the board](https://learn.adafruit.com/adafruit-airlift-featherwing-esp32-wifi-co-processor-featherwing/pinouts#spi-and-control-pins-3029450) in order to enable BLE support (see "Optional Control Pins" section).

To use ninafw with other boards, you will need to use the `ninafw` build tag as well as configure the pins and UART for communicating with the ESP32 module by configuring the `AdapterConfig` package variable before calling `DefaultAdapter.Enable()`. See [`adapter_ninafw-featherwing.go`](adapter_ninafw-featherwing.go) for an example of setting the hardware configuration options.

If you want more information about the `nina-fw` firmware, or want to add support for other ESP32-equipped boards, please see https://github.com/arduino/nina-fw

## API stability
Expand Down
22 changes: 22 additions & 0 deletions adapter_ninafw-featherwing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//go:build ninafw && ninafw_featherwing_init

package bluetooth

import (
"machine"
)

func init() {
AdapterConfig = NINAConfig{
UART: machine.DefaultUART,
CS: machine.D13,
ACK: machine.D11,
GPIO0: machine.D10,
RESETN: machine.D12,
CTS: machine.D11, // same as ACK
RTS: machine.D10, // same as GPIO0
BaudRate: 115200,
ResetInverted: true,
SoftFlowControl: true,
}
}
22 changes: 22 additions & 0 deletions adapter_ninafw-machine.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//go:build ninafw && ninafw_machine_init

package bluetooth

import (
"machine"
)

func init() {
AdapterConfig = NINAConfig{
UART: machine.UART_NINA,
CS: machine.NINA_CS,
ACK: machine.NINA_ACK,
GPIO0: machine.NINA_GPIO0,
RESETN: machine.NINA_RESETN,
CTS: machine.NINA_CTS,
RTS: machine.NINA_RTS,
BaudRate: machine.NINA_BAUDRATE,
ResetInverted: machine.NINA_RESET_INVERTED,
SoftFlowControl: machine.NINA_SOFT_FLOWCONTROL,
}
}
63 changes: 43 additions & 20 deletions adapter_ninafw.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,29 @@ import (

const maxConnections = 1

// NINAConfig encapsulates the hardware options for the NINA firmware
type NINAConfig struct {
UART *machine.UART

CS machine.Pin
ACK machine.Pin
GPIO0 machine.Pin
RESETN machine.Pin

TX machine.Pin
RX machine.Pin
CTS machine.Pin
RTS machine.Pin

BaudRate uint32
ResetInverted bool
SoftFlowControl bool
}

// AdapterConfig is used to set the hardware options for the NINA adapter prior
// to calling DefaultAdapter.Enable()
var AdapterConfig NINAConfig

// Adapter represents the UART connection to the NINA fw.
type Adapter struct {
hci *hci
Expand Down Expand Up @@ -40,37 +63,37 @@ var DefaultAdapter = &Adapter{
// Bluetooth-related calls (unless otherwise indicated).
func (a *Adapter) Enable() error {
// reset the NINA in BLE mode
machine.NINA_CS.Configure(machine.PinConfig{Mode: machine.PinOutput})
machine.NINA_CS.Low()
AdapterConfig.CS.Configure(machine.PinConfig{Mode: machine.PinOutput})
AdapterConfig.CS.Low()

if machine.NINA_RESET_INVERTED {
if AdapterConfig.ResetInverted {
resetNINAInverted()
} else {
resetNINA()
}

// serial port for nina chip
uart := machine.UART_NINA
uart := AdapterConfig.UART
cfg := machine.UARTConfig{
TX: machine.NINA_TX,
RX: machine.NINA_RX,
BaudRate: machine.NINA_BAUDRATE,
TX: AdapterConfig.TX,
RX: AdapterConfig.RX,
BaudRate: AdapterConfig.BaudRate,
}
if !machine.NINA_SOFT_FLOWCONTROL {
cfg.CTS = machine.NINA_CTS
cfg.RTS = machine.NINA_RTS
if !AdapterConfig.SoftFlowControl {
cfg.CTS = AdapterConfig.CTS
cfg.RTS = AdapterConfig.RTS
}

uart.Configure(cfg)

a.hci, a.att = newBLEStack(uart)
if machine.NINA_SOFT_FLOWCONTROL {
a.hci.softRTS = machine.NINA_RTS
if AdapterConfig.SoftFlowControl {
a.hci.softRTS = AdapterConfig.RTS
a.hci.softRTS.Configure(machine.PinConfig{Mode: machine.PinOutput})
a.hci.softRTS.High()

a.hci.softCTS = machine.NINA_CTS
machine.NINA_CTS.Configure(machine.PinConfig{Mode: machine.PinInput})
a.hci.softCTS = AdapterConfig.CTS
AdapterConfig.CTS.Configure(machine.PinConfig{Mode: machine.PinInput})
}

a.hci.start()
Expand Down Expand Up @@ -133,20 +156,20 @@ func makeNINAAddress(mac MAC) [6]uint8 {
}

func resetNINA() {
machine.NINA_RESETN.Configure(machine.PinConfig{Mode: machine.PinOutput})
AdapterConfig.RESETN.Configure(machine.PinConfig{Mode: machine.PinOutput})

machine.NINA_RESETN.High()
AdapterConfig.RESETN.High()
time.Sleep(100 * time.Millisecond)
machine.NINA_RESETN.Low()
AdapterConfig.RESETN.Low()
time.Sleep(1000 * time.Millisecond)
}

func resetNINAInverted() {
machine.NINA_RESETN.Configure(machine.PinConfig{Mode: machine.PinOutput})
AdapterConfig.RESETN.Configure(machine.PinConfig{Mode: machine.PinOutput})

machine.NINA_RESETN.Low()
AdapterConfig.RESETN.Low()
time.Sleep(100 * time.Millisecond)
machine.NINA_RESETN.High()
AdapterConfig.RESETN.High()
time.Sleep(1000 * time.Millisecond)
}

Expand Down

0 comments on commit 731e738

Please sign in to comment.