Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ninafw: allow custom config #224

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ninafw_featherwing_init can just be featherwing.


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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about name ninafw_machine_init instead to ninafw_onboard?


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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest name this HCIConfig so it can be more easily used for non-NINA HCI controllers.

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
Loading