github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/usb/hid/hid.go (about)

     1  package hid
     2  
     3  import (
     4  	"errors"
     5  	"machine"
     6  	"machine/usb"
     7  	"machine/usb/descriptor"
     8  )
     9  
    10  // from usb-hid.go
    11  var (
    12  	ErrHIDInvalidPort    = errors.New("invalid USB port")
    13  	ErrHIDInvalidCore    = errors.New("invalid USB core")
    14  	ErrHIDReportTransfer = errors.New("failed to transfer HID report")
    15  )
    16  
    17  const (
    18  	hidEndpoint = usb.HID_ENDPOINT_IN
    19  
    20  	REPORT_TYPE_INPUT   = 1
    21  	REPORT_TYPE_OUTPUT  = 2
    22  	REPORT_TYPE_FEATURE = 3
    23  )
    24  
    25  type hidDevicer interface {
    26  	TxHandler() bool
    27  	RxHandler([]byte) bool
    28  }
    29  
    30  var devices [5]hidDevicer
    31  var size int
    32  
    33  // SetHandler sets the handler. Only the first time it is called, it
    34  // calls machine.EnableHID for USB configuration
    35  func SetHandler(d hidDevicer) {
    36  	if size == 0 {
    37  		machine.ConfigureUSBEndpoint(descriptor.CDCHID,
    38  			[]usb.EndpointConfig{
    39  				{
    40  					Index:     usb.HID_ENDPOINT_OUT,
    41  					IsIn:      false,
    42  					Type:      usb.ENDPOINT_TYPE_INTERRUPT,
    43  					RxHandler: rxHandler,
    44  				},
    45  				{
    46  					Index:     usb.HID_ENDPOINT_IN,
    47  					IsIn:      true,
    48  					Type:      usb.ENDPOINT_TYPE_INTERRUPT,
    49  					TxHandler: txHandler,
    50  				},
    51  			},
    52  			[]usb.SetupConfig{
    53  				{
    54  					Index:   usb.HID_INTERFACE,
    55  					Handler: setupHandler,
    56  				},
    57  			})
    58  	}
    59  
    60  	devices[size] = d
    61  	size++
    62  }
    63  
    64  func txHandler() {
    65  	for _, d := range devices {
    66  		if d == nil {
    67  			continue
    68  		}
    69  		if done := d.TxHandler(); done {
    70  			return
    71  		}
    72  	}
    73  }
    74  
    75  func rxHandler(b []byte) {
    76  	for _, d := range devices {
    77  		if d == nil {
    78  			continue
    79  		}
    80  		if done := d.RxHandler(b); done {
    81  			return
    82  		}
    83  	}
    84  }
    85  
    86  var DefaultSetupHandler = setupHandler
    87  
    88  func setupHandler(setup usb.Setup) bool {
    89  	ok := false
    90  	if setup.BmRequestType == usb.SET_REPORT_TYPE && setup.BRequest == usb.SET_IDLE {
    91  		machine.SendZlp()
    92  		ok = true
    93  	}
    94  	return ok
    95  }
    96  
    97  // SendUSBPacket sends a HIDPacket.
    98  func SendUSBPacket(b []byte) {
    99  	machine.SendUSBInPacket(hidEndpoint, b)
   100  }