Can Golang (Win11) send messages to a TinyGo USB HID device (Badger2040)

415 Views Asked by At

Note: The following may be impossible - I can't find whether or not in the USB spec.

I am currently using a Badger2040 as a keyboard - using USB HID from TinyGo - which works fine.

I can also (which I didn't expect) print to the console from the Badger2040 and see the printed result on Putty (though it does seem to be unreliable and fails with all output failing from then on - but the badger2040 program is still running).

I would also like to send (USB HID OUT?) text to the Badger2040 from Putty (and PC Go application). I tried typing text in Putty, but it isn't sent (even on pressing Enter).

So - firstly - is this possible (or impossible)? I'm guessing that maybe the USB HID protocol handshaking (or the TinyGo version) doesn't enable standard (serial?) comms from (in my case) PC host to Badger2040 Device. I've looked at https://github.com/tinygo-org/tinygo/blob/release/src/machine/usb.go and EnableHID doesn't set RxHandler - is this a bug or required?

Or, could I send, using USB HID OUT (which I know nothing else about), data from the PC Host to the Badger2040 as if it is a keyboard with a display? A TinyGo example would be great if someone knows of one - I haven't managed to find any myself.

My go code includes:

...
import (
...
    "machine/usb/hid/keyboard"
)
...
var kbd = keyboard.New()


func kbd_send(str string) {
    kbd.Write([]byte(str))
}

I can send strings to be typed as a keyboard - I can also (with apparent unreliability) print to a Putty terminal setup as Speed:115200, Serial, (COM5), and defaults (Data bits: 8, Stop bits: 1, Parity: None, Flow: XON/XOFF) and the output (usually) appears (but the buffer may fill and fail...).

2

There are 2 best solutions below

0
On BEST ANSWER

I found a way to have both comms and USB HID - by using the non standard IO - from an example at https://github.com/tinygo-org/tinygo/blob/release/src/examples/echo/echo.go.

There is a lot more going on than I honestly understand - but it is possible (as detailed by CircuitPython) for a USB HID device to be, for example, a mouse and a keyboard and this also works in TinyGo. However, I only need to be able to currently do a single device and separate serial comms.

The code is a bit long - and not refactored at all - but here is a little sample that may help others (also using the code I posted in the question):

...
    uart := machine.Serial
    uart.Configure(machine.UARTConfig{TX: machine.UART_TX_PIN, RX: machine.UART_RX_PIN})
...
    uart.Write([]byte("Started...\r\n")) // This shows fine
...
    for {
...     // this code below is specific to myself - just checks for a button being pressed
        button_b.Refresh()
        if button_b.Changed && button_b.Val {
            kbd_send("b") // this send a key press to the connected PC
            // println("be good") // this doesn't work now seems to hang
            uart.Write([]byte("b-")) // this appears in putty
        }
...
        if uart.Buffered() > 0 {
            b, _ := uart.ReadByte()
            led.Set(b == byte('z'))
        }
    // sleep here
.. } // ever

This will now allow you to switch the led on/off through putty - connected as previously setup - by type z to switch the led on - and anything else to switch it off.

1
On

Not sure. But I reckon you can more easily do this with circuitPy as it supports HID see https://circuitpython.org/board/pimoroni_badger2040/