ninafw: add support for software RTS/CTS flow control for boards where hardware support is not available

Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
deadprogram 2024-01-06 19:07:18 +01:00 committed by Ron Evans
parent cd3c0c4835
commit f639d80012
2 changed files with 63 additions and 10 deletions

View file

@ -41,7 +41,6 @@ var DefaultAdapter = &Adapter{
func (a *Adapter) Enable() error {
// reset the NINA in BLE mode
machine.NINA_CS.Configure(machine.PinConfig{Mode: machine.PinOutput})
machine.NINA_RESETN.Configure(machine.PinConfig{Mode: machine.PinOutput})
machine.NINA_CS.Low()
if machine.NINA_RESET_INVERTED {
@ -51,16 +50,28 @@ func (a *Adapter) Enable() error {
}
// serial port for nina chip
uart := machine.UART1
uart.Configure(machine.UARTConfig{
uart := machine.UART_NINA
cfg := machine.UARTConfig{
TX: machine.NINA_TX,
RX: machine.NINA_RX,
BaudRate: machine.NINA_BAUDRATE,
CTS: machine.NINA_CTS,
RTS: machine.NINA_RTS,
})
}
if !machine.NINA_SOFT_FLOWCONTROL {
cfg.CTS = machine.NINA_CTS
cfg.RTS = machine.NINA_RTS
}
uart.Configure(cfg)
a.hci, a.att = newBLEStack(uart)
if machine.NINA_SOFT_FLOWCONTROL {
a.hci.softRTS = machine.NINA_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.start()
@ -122,6 +133,8 @@ func makeNINAAddress(mac MAC) [6]uint8 {
}
func resetNINA() {
machine.NINA_RESETN.Configure(machine.PinConfig{Mode: machine.PinOutput})
machine.NINA_RESETN.High()
time.Sleep(100 * time.Millisecond)
machine.NINA_RESETN.Low()
@ -129,6 +142,8 @@ func resetNINA() {
}
func resetNINAInverted() {
machine.NINA_RESETN.Configure(machine.PinConfig{Mode: machine.PinOutput})
machine.NINA_RESETN.Low()
time.Sleep(100 * time.Millisecond)
machine.NINA_RESETN.High()

View file

@ -117,6 +117,8 @@ type leConnectData struct {
type hci struct {
uart *machine.UART
softCTS machine.Pin
softRTS machine.Pin
att *att
buf []byte
address [6]byte
@ -129,12 +131,21 @@ type hci struct {
}
func newHCI(uart *machine.UART) *hci {
return &hci{uart: uart,
return &hci{
uart: uart,
softCTS: machine.NoPin,
softRTS: machine.NoPin,
buf: make([]byte, 256),
}
}
func (h *hci) start() error {
if h.softRTS != machine.NoPin {
h.softRTS.Low()
defer h.softRTS.High()
}
for h.uart.Buffered() > 0 {
h.uart.ReadByte()
}
@ -151,6 +162,12 @@ func (h *hci) reset() error {
}
func (h *hci) poll() error {
if h.softRTS != machine.NoPin {
h.softRTS.Low()
defer h.softRTS.High()
}
i := 0
for h.uart.Buffered() > 0 {
data, _ := h.uart.ReadByte()
@ -322,7 +339,7 @@ func (h *hci) sendCommandWithParams(opcode uint16, params []byte) error {
h.buf[3] = byte(len(params))
copy(h.buf[4:], params)
if _, err := h.uart.Write(h.buf[:4+len(params)]); err != nil {
if _, err := h.write(h.buf[:4+len(params)]); err != nil {
return err
}
@ -356,13 +373,34 @@ func (h *hci) sendAclPkt(handle uint16, cid uint8, data []byte) error {
println("hci send acl data", handle, cid, hex.EncodeToString(h.buf[:9+len(data)]))
}
if _, err := h.uart.Write(h.buf[:9+len(data)]); err != nil {
if _, err := h.write(h.buf[:9+len(data)]); err != nil {
return err
}
return nil
}
const writeAttempts = 200
func (h *hci) write(buf []byte) (int, error) {
if h.softCTS != machine.NoPin {
retries := writeAttempts
for h.softCTS.Get() {
retries--
if retries == 0 {
return 0, ErrHCITimeout
}
}
}
n, err := h.uart.Write(buf)
if err != nil {
return 0, err
}
return n, nil
}
type aclDataHeader struct {
handle uint16
dlen uint16