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 {
|
||||
// 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()
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue