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:
parent
cd3c0c4835
commit
f639d80012
2 changed files with 63 additions and 10 deletions
|
@ -41,7 +41,6 @@ var DefaultAdapter = &Adapter{
|
||||||
func (a *Adapter) Enable() error {
|
func (a *Adapter) Enable() error {
|
||||||
// reset the NINA in BLE mode
|
// reset the NINA in BLE mode
|
||||||
machine.NINA_CS.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
machine.NINA_CS.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
machine.NINA_RESETN.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
|
||||||
machine.NINA_CS.Low()
|
machine.NINA_CS.Low()
|
||||||
|
|
||||||
if machine.NINA_RESET_INVERTED {
|
if machine.NINA_RESET_INVERTED {
|
||||||
|
@ -51,16 +50,28 @@ func (a *Adapter) Enable() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// serial port for nina chip
|
// serial port for nina chip
|
||||||
uart := machine.UART1
|
uart := machine.UART_NINA
|
||||||
uart.Configure(machine.UARTConfig{
|
cfg := machine.UARTConfig{
|
||||||
TX: machine.NINA_TX,
|
TX: machine.NINA_TX,
|
||||||
RX: machine.NINA_RX,
|
RX: machine.NINA_RX,
|
||||||
BaudRate: machine.NINA_BAUDRATE,
|
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)
|
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()
|
a.hci.start()
|
||||||
|
|
||||||
|
@ -122,6 +133,8 @@ func makeNINAAddress(mac MAC) [6]uint8 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func resetNINA() {
|
func resetNINA() {
|
||||||
|
machine.NINA_RESETN.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
|
||||||
machine.NINA_RESETN.High()
|
machine.NINA_RESETN.High()
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
machine.NINA_RESETN.Low()
|
machine.NINA_RESETN.Low()
|
||||||
|
@ -129,6 +142,8 @@ func resetNINA() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func resetNINAInverted() {
|
func resetNINAInverted() {
|
||||||
|
machine.NINA_RESETN.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
|
||||||
machine.NINA_RESETN.Low()
|
machine.NINA_RESETN.Low()
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
machine.NINA_RESETN.High()
|
machine.NINA_RESETN.High()
|
||||||
|
|
|
@ -117,6 +117,8 @@ type leConnectData struct {
|
||||||
|
|
||||||
type hci struct {
|
type hci struct {
|
||||||
uart *machine.UART
|
uart *machine.UART
|
||||||
|
softCTS machine.Pin
|
||||||
|
softRTS machine.Pin
|
||||||
att *att
|
att *att
|
||||||
buf []byte
|
buf []byte
|
||||||
address [6]byte
|
address [6]byte
|
||||||
|
@ -129,12 +131,21 @@ type hci struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newHCI(uart *machine.UART) *hci {
|
func newHCI(uart *machine.UART) *hci {
|
||||||
return &hci{uart: uart,
|
return &hci{
|
||||||
buf: make([]byte, 256),
|
uart: uart,
|
||||||
|
softCTS: machine.NoPin,
|
||||||
|
softRTS: machine.NoPin,
|
||||||
|
buf: make([]byte, 256),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *hci) start() error {
|
func (h *hci) start() error {
|
||||||
|
if h.softRTS != machine.NoPin {
|
||||||
|
h.softRTS.Low()
|
||||||
|
|
||||||
|
defer h.softRTS.High()
|
||||||
|
}
|
||||||
|
|
||||||
for h.uart.Buffered() > 0 {
|
for h.uart.Buffered() > 0 {
|
||||||
h.uart.ReadByte()
|
h.uart.ReadByte()
|
||||||
}
|
}
|
||||||
|
@ -151,6 +162,12 @@ func (h *hci) reset() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *hci) poll() error {
|
func (h *hci) poll() error {
|
||||||
|
if h.softRTS != machine.NoPin {
|
||||||
|
h.softRTS.Low()
|
||||||
|
|
||||||
|
defer h.softRTS.High()
|
||||||
|
}
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
for h.uart.Buffered() > 0 {
|
for h.uart.Buffered() > 0 {
|
||||||
data, _ := h.uart.ReadByte()
|
data, _ := h.uart.ReadByte()
|
||||||
|
@ -322,7 +339,7 @@ func (h *hci) sendCommandWithParams(opcode uint16, params []byte) error {
|
||||||
h.buf[3] = byte(len(params))
|
h.buf[3] = byte(len(params))
|
||||||
copy(h.buf[4:], 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
|
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)]))
|
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 err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
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 {
|
type aclDataHeader struct {
|
||||||
handle uint16
|
handle uint16
|
||||||
dlen uint16
|
dlen uint16
|
||||||
|
|
Loading…
Reference in a new issue