github.com/aykevl/tinygo@v0.5.0/src/machine/usb.go (about)

     1  // +build sam
     2  
     3  package machine
     4  
     5  import (
     6  	"bytes"
     7  	"device/sam"
     8  	"encoding/binary"
     9  	"errors"
    10  )
    11  
    12  const deviceDescriptorSize = 18
    13  
    14  // DeviceDescriptor implements the USB standard device descriptor.
    15  //
    16  // Table 9-8. Standard Device Descriptor
    17  // bLength, bDescriptorType, bcdUSB, bDeviceClass, bDeviceSubClass, bDeviceProtocol, bMaxPacketSize0,
    18  //    idVendor, idProduct, bcdDevice, iManufacturer, iProduct, iSerialNumber, bNumConfigurations */
    19  //
    20  type DeviceDescriptor struct {
    21  	bLength            uint8  // 18
    22  	bDescriptorType    uint8  // 1 USB_DEVICE_DESCRIPTOR_TYPE
    23  	bcdUSB             uint16 // 0x200
    24  	bDeviceClass       uint8
    25  	bDeviceSubClass    uint8
    26  	bDeviceProtocol    uint8
    27  	bMaxPacketSize0    uint8 // Packet 0
    28  	idVendor           uint16
    29  	idProduct          uint16
    30  	bcdDevice          uint16 // 0x100
    31  	iManufacturer      uint8
    32  	iProduct           uint8
    33  	iSerialNumber      uint8
    34  	bNumConfigurations uint8
    35  }
    36  
    37  // NewDeviceDescriptor returns a USB DeviceDescriptor.
    38  func NewDeviceDescriptor(class, subClass, proto, packetSize0 uint8, vid, pid, version uint16, im, ip, is, configs uint8) DeviceDescriptor {
    39  	return DeviceDescriptor{deviceDescriptorSize, 1, 0x200, class, subClass, proto, packetSize0, vid, pid, version, im, ip, is, configs}
    40  }
    41  
    42  // Bytes returns DeviceDescriptor data
    43  func (d DeviceDescriptor) Bytes() []byte {
    44  	buf := bytes.NewBuffer(make([]byte, 0, deviceDescriptorSize))
    45  	binary.Write(buf, binary.LittleEndian, d.bLength)
    46  	binary.Write(buf, binary.LittleEndian, d.bDescriptorType)
    47  	binary.Write(buf, binary.LittleEndian, d.bcdUSB)
    48  	binary.Write(buf, binary.LittleEndian, d.bDeviceClass)
    49  	binary.Write(buf, binary.LittleEndian, d.bDeviceSubClass)
    50  	binary.Write(buf, binary.LittleEndian, d.bDeviceProtocol)
    51  	binary.Write(buf, binary.LittleEndian, d.bMaxPacketSize0)
    52  	binary.Write(buf, binary.LittleEndian, d.idVendor)
    53  	binary.Write(buf, binary.LittleEndian, d.idProduct)
    54  	binary.Write(buf, binary.LittleEndian, d.bcdDevice)
    55  	binary.Write(buf, binary.LittleEndian, d.iManufacturer)
    56  	binary.Write(buf, binary.LittleEndian, d.iProduct)
    57  	binary.Write(buf, binary.LittleEndian, d.iSerialNumber)
    58  	binary.Write(buf, binary.LittleEndian, d.bNumConfigurations)
    59  	return buf.Bytes()
    60  }
    61  
    62  const configDescriptorSize = 9
    63  
    64  // ConfigDescriptor implements the standard USB configuration descriptor.
    65  //
    66  // Table 9-10. Standard Configuration Descriptor
    67  // bLength, bDescriptorType, wTotalLength, bNumInterfaces, bConfigurationValue, iConfiguration
    68  // bmAttributes, bMaxPower
    69  //
    70  type ConfigDescriptor struct {
    71  	bLength             uint8  // 9
    72  	bDescriptorType     uint8  // 2
    73  	wTotalLength        uint16 // total length
    74  	bNumInterfaces      uint8
    75  	bConfigurationValue uint8
    76  	iConfiguration      uint8
    77  	bmAttributes        uint8
    78  	bMaxPower           uint8
    79  }
    80  
    81  // NewConfigDescriptor returns a new USB ConfigDescriptor.
    82  func NewConfigDescriptor(totalLength uint16, interfaces uint8) ConfigDescriptor {
    83  	return ConfigDescriptor{configDescriptorSize, 2, totalLength, interfaces, 1, 0, usb_CONFIG_BUS_POWERED | usb_CONFIG_REMOTE_WAKEUP, 50}
    84  }
    85  
    86  // Bytes returns ConfigDescriptor data.
    87  func (d ConfigDescriptor) Bytes() []byte {
    88  	buf := bytes.NewBuffer(make([]byte, 0, configDescriptorSize))
    89  	binary.Write(buf, binary.LittleEndian, d.bLength)
    90  	binary.Write(buf, binary.LittleEndian, d.bDescriptorType)
    91  	binary.Write(buf, binary.LittleEndian, d.wTotalLength)
    92  	binary.Write(buf, binary.LittleEndian, d.bNumInterfaces)
    93  	binary.Write(buf, binary.LittleEndian, d.bConfigurationValue)
    94  	binary.Write(buf, binary.LittleEndian, d.iConfiguration)
    95  	binary.Write(buf, binary.LittleEndian, d.bmAttributes)
    96  	binary.Write(buf, binary.LittleEndian, d.bMaxPower)
    97  	return buf.Bytes()
    98  }
    99  
   100  const interfaceDescriptorSize = 9
   101  
   102  // InterfaceDescriptor implements the standard USB interface descriptor.
   103  //
   104  // Table 9-12. Standard Interface Descriptor
   105  // bLength, bDescriptorType, bInterfaceNumber, bAlternateSetting, bNumEndpoints, bInterfaceClass,
   106  // bInterfaceSubClass, bInterfaceProtocol, iInterface
   107  //
   108  type InterfaceDescriptor struct {
   109  	bLength            uint8 // 9
   110  	bDescriptorType    uint8 // 4
   111  	bInterfaceNumber   uint8
   112  	bAlternateSetting  uint8
   113  	bNumEndpoints      uint8
   114  	bInterfaceClass    uint8
   115  	bInterfaceSubClass uint8
   116  	bInterfaceProtocol uint8
   117  	iInterface         uint8
   118  }
   119  
   120  // NewInterfaceDescriptor returns a new USB InterfaceDescriptor.
   121  func NewInterfaceDescriptor(n, numEndpoints, class, subClass, protocol uint8) InterfaceDescriptor {
   122  	return InterfaceDescriptor{interfaceDescriptorSize, 4, n, 0, numEndpoints, class, subClass, protocol, 0}
   123  }
   124  
   125  // Bytes returns InterfaceDescriptor data.
   126  func (d InterfaceDescriptor) Bytes() []byte {
   127  	buf := bytes.NewBuffer(make([]byte, 0, interfaceDescriptorSize))
   128  	binary.Write(buf, binary.LittleEndian, d.bLength)
   129  	binary.Write(buf, binary.LittleEndian, d.bDescriptorType)
   130  	binary.Write(buf, binary.LittleEndian, d.bInterfaceNumber)
   131  	binary.Write(buf, binary.LittleEndian, d.bAlternateSetting)
   132  	binary.Write(buf, binary.LittleEndian, d.bNumEndpoints)
   133  	binary.Write(buf, binary.LittleEndian, d.bInterfaceClass)
   134  	binary.Write(buf, binary.LittleEndian, d.bInterfaceSubClass)
   135  	binary.Write(buf, binary.LittleEndian, d.bInterfaceProtocol)
   136  	binary.Write(buf, binary.LittleEndian, d.iInterface)
   137  	return buf.Bytes()
   138  }
   139  
   140  const endpointDescriptorSize = 7
   141  
   142  // EndpointDescriptor implements the standard USB endpoint descriptor.
   143  //
   144  // Table 9-13. Standard Endpoint Descriptor
   145  // bLength, bDescriptorType, bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval
   146  //
   147  type EndpointDescriptor struct {
   148  	bLength          uint8 // 7
   149  	bDescriptorType  uint8 // 5
   150  	bEndpointAddress uint8
   151  	bmAttributes     uint8
   152  	wMaxPacketSize   uint16
   153  	bInterval        uint8
   154  }
   155  
   156  // NewEndpointDescriptor returns a new USB EndpointDescriptor.
   157  func NewEndpointDescriptor(addr, attr uint8, packetSize uint16, interval uint8) EndpointDescriptor {
   158  	return EndpointDescriptor{endpointDescriptorSize, 5, addr, attr, packetSize, interval}
   159  }
   160  
   161  // Bytes returns EndpointDescriptor data.
   162  func (d EndpointDescriptor) Bytes() []byte {
   163  	buf := bytes.NewBuffer(make([]byte, 0, endpointDescriptorSize))
   164  	binary.Write(buf, binary.LittleEndian, d.bLength)
   165  	binary.Write(buf, binary.LittleEndian, d.bDescriptorType)
   166  	binary.Write(buf, binary.LittleEndian, d.bEndpointAddress)
   167  	binary.Write(buf, binary.LittleEndian, d.bmAttributes)
   168  	binary.Write(buf, binary.LittleEndian, d.wMaxPacketSize)
   169  	binary.Write(buf, binary.LittleEndian, d.bInterval)
   170  	return buf.Bytes()
   171  }
   172  
   173  const iadDescriptorSize = 8
   174  
   175  // IADDescriptor is an Interface Association Descriptor, which is used
   176  // to bind 2 interfaces together in CDC composite device.
   177  //
   178  // Standard Interface Association Descriptor:
   179  // bLength, bDescriptorType, bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass,
   180  // bFunctionProtocol, iFunction
   181  //
   182  type IADDescriptor struct {
   183  	bLength           uint8 // 8
   184  	bDescriptorType   uint8 // 11
   185  	bFirstInterface   uint8
   186  	bInterfaceCount   uint8
   187  	bFunctionClass    uint8
   188  	bFunctionSubClass uint8
   189  	bFunctionProtocol uint8
   190  	iFunction         uint8
   191  }
   192  
   193  // NewIADDescriptor returns a new USB IADDescriptor.
   194  func NewIADDescriptor(firstInterface, count, class, subClass, protocol uint8) IADDescriptor {
   195  	return IADDescriptor{iadDescriptorSize, 11, firstInterface, count, class, subClass, protocol, 0}
   196  }
   197  
   198  // Bytes returns IADDescriptor data.
   199  func (d IADDescriptor) Bytes() []byte {
   200  	buf := bytes.NewBuffer(make([]byte, 0, iadDescriptorSize))
   201  	binary.Write(buf, binary.LittleEndian, d.bLength)
   202  	binary.Write(buf, binary.LittleEndian, d.bDescriptorType)
   203  	binary.Write(buf, binary.LittleEndian, d.bFirstInterface)
   204  	binary.Write(buf, binary.LittleEndian, d.bInterfaceCount)
   205  	binary.Write(buf, binary.LittleEndian, d.bFunctionClass)
   206  	binary.Write(buf, binary.LittleEndian, d.bFunctionSubClass)
   207  	binary.Write(buf, binary.LittleEndian, d.bFunctionProtocol)
   208  	binary.Write(buf, binary.LittleEndian, d.iFunction)
   209  	return buf.Bytes()
   210  }
   211  
   212  const cdcCSInterfaceDescriptorSize = 5
   213  
   214  // CDCCSInterfaceDescriptor is a CDC CS interface descriptor.
   215  type CDCCSInterfaceDescriptor struct {
   216  	len     uint8 // 5
   217  	dtype   uint8 // 0x24
   218  	subtype uint8
   219  	d0      uint8
   220  	d1      uint8
   221  }
   222  
   223  // NewCDCCSInterfaceDescriptor returns a new USB CDCCSInterfaceDescriptor.
   224  func NewCDCCSInterfaceDescriptor(subtype, d0, d1 uint8) CDCCSInterfaceDescriptor {
   225  	return CDCCSInterfaceDescriptor{cdcCSInterfaceDescriptorSize, 0x24, subtype, d0, d1}
   226  }
   227  
   228  // Bytes returns CDCCSInterfaceDescriptor data.
   229  func (d CDCCSInterfaceDescriptor) Bytes() []byte {
   230  	buf := bytes.NewBuffer(make([]byte, 0, cdcCSInterfaceDescriptorSize))
   231  	binary.Write(buf, binary.LittleEndian, d.len)
   232  	binary.Write(buf, binary.LittleEndian, d.dtype)
   233  	binary.Write(buf, binary.LittleEndian, d.subtype)
   234  	binary.Write(buf, binary.LittleEndian, d.d0)
   235  	binary.Write(buf, binary.LittleEndian, d.d1)
   236  	return buf.Bytes()
   237  }
   238  
   239  const cmFunctionalDescriptorSize = 5
   240  
   241  // CMFunctionalDescriptor is the functional descriptor general format.
   242  type CMFunctionalDescriptor struct {
   243  	bFunctionLength    uint8
   244  	bDescriptorType    uint8 // 0x24
   245  	bDescriptorSubtype uint8 // 1
   246  	bmCapabilities     uint8
   247  	bDataInterface     uint8
   248  }
   249  
   250  // NewCMFunctionalDescriptor returns a new USB CMFunctionalDescriptor.
   251  func NewCMFunctionalDescriptor(subtype, d0, d1 uint8) CMFunctionalDescriptor {
   252  	return CMFunctionalDescriptor{5, 0x24, subtype, d0, d1}
   253  }
   254  
   255  // Bytes returns the CMFunctionalDescriptor data.
   256  func (d CMFunctionalDescriptor) Bytes() []byte {
   257  	buf := bytes.NewBuffer(make([]byte, 0, cmFunctionalDescriptorSize))
   258  	binary.Write(buf, binary.LittleEndian, d.bFunctionLength)
   259  	binary.Write(buf, binary.LittleEndian, d.bDescriptorType)
   260  	binary.Write(buf, binary.LittleEndian, d.bDescriptorSubtype)
   261  	binary.Write(buf, binary.LittleEndian, d.bmCapabilities)
   262  	binary.Write(buf, binary.LittleEndian, d.bDataInterface)
   263  	return buf.Bytes()
   264  }
   265  
   266  const acmFunctionalDescriptorSize = 4
   267  
   268  // ACMFunctionalDescriptor is a Abstract Control Model (ACM) USB descriptor.
   269  type ACMFunctionalDescriptor struct {
   270  	len            uint8
   271  	dtype          uint8 // 0x24
   272  	subtype        uint8 // 1
   273  	bmCapabilities uint8
   274  }
   275  
   276  // NewACMFunctionalDescriptor returns a new USB ACMFunctionalDescriptor.
   277  func NewACMFunctionalDescriptor(subtype, d0 uint8) ACMFunctionalDescriptor {
   278  	return ACMFunctionalDescriptor{4, 0x24, subtype, d0}
   279  }
   280  
   281  // Bytes returns the ACMFunctionalDescriptor data.
   282  func (d ACMFunctionalDescriptor) Bytes() []byte {
   283  	buf := bytes.NewBuffer(make([]byte, 0, acmFunctionalDescriptorSize))
   284  	binary.Write(buf, binary.LittleEndian, d.len)
   285  	binary.Write(buf, binary.LittleEndian, d.dtype)
   286  	binary.Write(buf, binary.LittleEndian, d.subtype)
   287  	binary.Write(buf, binary.LittleEndian, d.bmCapabilities)
   288  	return buf.Bytes()
   289  }
   290  
   291  // CDCDescriptor is the Communication Device Class (CDC) descriptor.
   292  type CDCDescriptor struct {
   293  	//	IAD
   294  	iad IADDescriptor // Only needed on compound device
   295  
   296  	//	Control
   297  	cif    InterfaceDescriptor
   298  	header CDCCSInterfaceDescriptor
   299  
   300  	// CDC control
   301  	controlManagement    ACMFunctionalDescriptor  // ACM
   302  	functionalDescriptor CDCCSInterfaceDescriptor // CDC_UNION
   303  	callManagement       CMFunctionalDescriptor   // Call Management
   304  	cifin                EndpointDescriptor
   305  
   306  	//	CDC Data
   307  	dif InterfaceDescriptor
   308  	in  EndpointDescriptor
   309  	out EndpointDescriptor
   310  }
   311  
   312  func NewCDCDescriptor(i IADDescriptor, c InterfaceDescriptor,
   313  	h CDCCSInterfaceDescriptor,
   314  	cm ACMFunctionalDescriptor,
   315  	fd CDCCSInterfaceDescriptor,
   316  	callm CMFunctionalDescriptor,
   317  	ci EndpointDescriptor,
   318  	di InterfaceDescriptor,
   319  	inp EndpointDescriptor,
   320  	outp EndpointDescriptor) CDCDescriptor {
   321  	return CDCDescriptor{iad: i,
   322  		cif:                  c,
   323  		header:               h,
   324  		controlManagement:    cm,
   325  		functionalDescriptor: fd,
   326  		callManagement:       callm,
   327  		cifin:                ci,
   328  		dif:                  di,
   329  		in:                   inp,
   330  		out:                  outp}
   331  }
   332  
   333  const cdcSize = iadDescriptorSize +
   334  	interfaceDescriptorSize +
   335  	cdcCSInterfaceDescriptorSize +
   336  	acmFunctionalDescriptorSize +
   337  	cdcCSInterfaceDescriptorSize +
   338  	cmFunctionalDescriptorSize +
   339  	endpointDescriptorSize +
   340  	interfaceDescriptorSize +
   341  	endpointDescriptorSize +
   342  	endpointDescriptorSize
   343  
   344  // Bytes returns CDCDescriptor data.
   345  func (d CDCDescriptor) Bytes() []byte {
   346  	buf := bytes.NewBuffer(make([]byte, 0, cdcSize))
   347  	buf.Write(d.iad.Bytes())
   348  	buf.Write(d.cif.Bytes())
   349  	buf.Write(d.header.Bytes())
   350  	buf.Write(d.controlManagement.Bytes())
   351  	buf.Write(d.functionalDescriptor.Bytes())
   352  	buf.Write(d.callManagement.Bytes())
   353  	buf.Write(d.cifin.Bytes())
   354  	buf.Write(d.dif.Bytes())
   355  	buf.Write(d.in.Bytes())
   356  	buf.Write(d.out.Bytes())
   357  	return buf.Bytes()
   358  }
   359  
   360  // MSCDescriptor is not used yet.
   361  type MSCDescriptor struct {
   362  	msc InterfaceDescriptor
   363  	in  EndpointDescriptor
   364  	out EndpointDescriptor
   365  }
   366  
   367  type cdcLineInfo struct {
   368  	dwDTERate   uint32
   369  	bCharFormat uint8
   370  	bParityType uint8
   371  	bDataBits   uint8
   372  	lineState   uint8
   373  }
   374  
   375  var (
   376  	// TODO: allow setting these
   377  	usb_STRING_LANGUAGE     = [2]uint16{(3 << 8) | (2 + 2), 0x0409} // English
   378  	usb_STRING_PRODUCT      = "Arduino Zero"
   379  	usb_STRING_MANUFACTURER = "Arduino"
   380  
   381  	usb_VID uint16 = 0x2341
   382  	usb_PID uint16 = 0x004d
   383  )
   384  
   385  const (
   386  	usb_IMANUFACTURER = 1
   387  	usb_IPRODUCT      = 2
   388  	usb_ISERIAL       = 3
   389  
   390  	usb_ENDPOINT_TYPE_CONTROL     = 0x00
   391  	usb_ENDPOINT_TYPE_ISOCHRONOUS = 0x01
   392  	usb_ENDPOINT_TYPE_BULK        = 0x02
   393  	usb_ENDPOINT_TYPE_INTERRUPT   = 0x03
   394  
   395  	usb_DEVICE_DESCRIPTOR_TYPE        = 1
   396  	usb_CONFIGURATION_DESCRIPTOR_TYPE = 2
   397  	usb_STRING_DESCRIPTOR_TYPE        = 3
   398  	usb_INTERFACE_DESCRIPTOR_TYPE     = 4
   399  	usb_ENDPOINT_DESCRIPTOR_TYPE      = 5
   400  	usb_DEVICE_QUALIFIER              = 6
   401  	usb_OTHER_SPEED_CONFIGURATION     = 7
   402  
   403  	usbEndpointOut = 0x00
   404  	usbEndpointIn  = 0x80
   405  
   406  	usbEndpointPacketSize = 64 // 64 for Full Speed, EPT size max is 1024
   407  	usb_EPT_NUM           = 7
   408  
   409  	// standard requests
   410  	usb_GET_STATUS        = 0
   411  	usb_CLEAR_FEATURE     = 1
   412  	usb_SET_FEATURE       = 3
   413  	usb_SET_ADDRESS       = 5
   414  	usb_GET_DESCRIPTOR    = 6
   415  	usb_SET_DESCRIPTOR    = 7
   416  	usb_GET_CONFIGURATION = 8
   417  	usb_SET_CONFIGURATION = 9
   418  	usb_GET_INTERFACE     = 10
   419  	usb_SET_INTERFACE     = 11
   420  
   421  	usb_DEVICE_CLASS_COMMUNICATIONS  = 0x02
   422  	usb_DEVICE_CLASS_HUMAN_INTERFACE = 0x03
   423  	usb_DEVICE_CLASS_STORAGE         = 0x08
   424  	usb_DEVICE_CLASS_VENDOR_SPECIFIC = 0xFF
   425  
   426  	usb_CONFIG_POWERED_MASK  = 0x40
   427  	usb_CONFIG_BUS_POWERED   = 0x80
   428  	usb_CONFIG_SELF_POWERED  = 0xC0
   429  	usb_CONFIG_REMOTE_WAKEUP = 0x20
   430  
   431  	// CDC
   432  	usb_CDC_ACM_INTERFACE  = 0 // CDC ACM
   433  	usb_CDC_DATA_INTERFACE = 1 // CDC Data
   434  	usb_CDC_FIRST_ENDPOINT = 1
   435  	usb_CDC_ENDPOINT_ACM   = 1
   436  	usb_CDC_ENDPOINT_OUT   = 2
   437  	usb_CDC_ENDPOINT_IN    = 3
   438  
   439  	// bmRequestType
   440  	usb_REQUEST_HOSTTODEVICE = 0x00
   441  	usb_REQUEST_DEVICETOHOST = 0x80
   442  	usb_REQUEST_DIRECTION    = 0x80
   443  
   444  	usb_REQUEST_STANDARD = 0x00
   445  	usb_REQUEST_CLASS    = 0x20
   446  	usb_REQUEST_VENDOR   = 0x40
   447  	usb_REQUEST_TYPE     = 0x60
   448  
   449  	usb_REQUEST_DEVICE    = 0x00
   450  	usb_REQUEST_INTERFACE = 0x01
   451  	usb_REQUEST_ENDPOINT  = 0x02
   452  	usb_REQUEST_OTHER     = 0x03
   453  	usb_REQUEST_RECIPIENT = 0x1F
   454  
   455  	usb_REQUEST_DEVICETOHOST_CLASS_INTERFACE    = (usb_REQUEST_DEVICETOHOST | usb_REQUEST_CLASS | usb_REQUEST_INTERFACE)
   456  	usb_REQUEST_HOSTTODEVICE_CLASS_INTERFACE    = (usb_REQUEST_HOSTTODEVICE | usb_REQUEST_CLASS | usb_REQUEST_INTERFACE)
   457  	usb_REQUEST_DEVICETOHOST_STANDARD_INTERFACE = (usb_REQUEST_DEVICETOHOST | usb_REQUEST_STANDARD | usb_REQUEST_INTERFACE)
   458  
   459  	// CDC Class requests
   460  	usb_CDC_SET_LINE_CODING        = 0x20
   461  	usb_CDC_GET_LINE_CODING        = 0x21
   462  	usb_CDC_SET_CONTROL_LINE_STATE = 0x22
   463  	usb_CDC_SEND_BREAK             = 0x23
   464  
   465  	usb_CDC_V1_10                         = 0x0110
   466  	usb_CDC_COMMUNICATION_INTERFACE_CLASS = 0x02
   467  
   468  	usb_CDC_CALL_MANAGEMENT             = 0x01
   469  	usb_CDC_ABSTRACT_CONTROL_MODEL      = 0x02
   470  	usb_CDC_HEADER                      = 0x00
   471  	usb_CDC_ABSTRACT_CONTROL_MANAGEMENT = 0x02
   472  	usb_CDC_UNION                       = 0x06
   473  	usb_CDC_CS_INTERFACE                = 0x24
   474  	usb_CDC_CS_ENDPOINT                 = 0x25
   475  	usb_CDC_DATA_INTERFACE_CLASS        = 0x0A
   476  )
   477  
   478  // usbDeviceDescBank is the USB device endpoint descriptor.
   479  // typedef struct {
   480  // 	__IO USB_DEVICE_ADDR_Type      ADDR;        /**< \brief Offset: 0x000 (R/W 32) DEVICE_DESC_BANK Endpoint Bank, Adress of Data Buffer */
   481  // 	__IO USB_DEVICE_PCKSIZE_Type   PCKSIZE;     /**< \brief Offset: 0x004 (R/W 32) DEVICE_DESC_BANK Endpoint Bank, Packet Size */
   482  // 	__IO USB_DEVICE_EXTREG_Type    EXTREG;      /**< \brief Offset: 0x008 (R/W 16) DEVICE_DESC_BANK Endpoint Bank, Extended */
   483  // 	__IO USB_DEVICE_STATUS_BK_Type STATUS_BK;   /**< \brief Offset: 0x00A (R/W  8) DEVICE_DESC_BANK Enpoint Bank, Status of Bank */
   484  // 		 RoReg8                    Reserved1[0x5];
   485  //   } UsbDeviceDescBank;
   486  type usbDeviceDescBank struct {
   487  	ADDR      sam.RegValue
   488  	PCKSIZE   sam.RegValue
   489  	EXTREG    sam.RegValue16
   490  	STATUS_BK sam.RegValue8
   491  	_reserved [5]sam.RegValue8
   492  }
   493  
   494  type usbDeviceDescriptor struct {
   495  	DeviceDescBank [2]usbDeviceDescBank
   496  }
   497  
   498  // typedef struct {
   499  // 	union {
   500  // 		uint8_t bmRequestType;
   501  // 		struct {
   502  // 			uint8_t direction : 5;
   503  // 			uint8_t type : 2;
   504  // 			uint8_t transferDirection : 1;
   505  // 		};
   506  // 	};
   507  // 	uint8_t bRequest;
   508  // 	uint8_t wValueL;
   509  // 	uint8_t wValueH;
   510  // 	uint16_t wIndex;
   511  // 	uint16_t wLength;
   512  // } USBSetup;
   513  type usbSetup struct {
   514  	bmRequestType uint8
   515  	bRequest      uint8
   516  	wValueL       uint8
   517  	wValueH       uint8
   518  	wIndex        uint16
   519  	wLength       uint16
   520  }
   521  
   522  func newUSBSetup(data []byte) usbSetup {
   523  	buf := bytes.NewBuffer(data)
   524  	u := usbSetup{}
   525  	binary.Read(buf, binary.LittleEndian, &(u.bmRequestType))
   526  	binary.Read(buf, binary.LittleEndian, &(u.bRequest))
   527  	binary.Read(buf, binary.LittleEndian, &(u.wValueL))
   528  	binary.Read(buf, binary.LittleEndian, &(u.wValueH))
   529  	binary.Read(buf, binary.LittleEndian, &(u.wIndex))
   530  	binary.Read(buf, binary.LittleEndian, &(u.wLength))
   531  	return u
   532  }
   533  
   534  // USBCDC is the serial interface that works over the USB port.
   535  // To implement the USBCDC interface for a board, you must declare a concrete type as follows:
   536  //
   537  // 		type USBCDC struct {
   538  // 			Buffer *RingBuffer
   539  // 		}
   540  //
   541  // You can also add additional members to this struct depending on your implementation,
   542  // but the *RingBuffer is required.
   543  // When you are declaring the USBCDC for your board, make sure that you also declare the
   544  // RingBuffer using the NewRingBuffer() function:
   545  //
   546  //		USBCDC{Buffer: NewRingBuffer()}
   547  //
   548  
   549  // Read from the RX buffer.
   550  func (usbcdc USBCDC) Read(data []byte) (n int, err error) {
   551  	// check if RX buffer is empty
   552  	size := usbcdc.Buffered()
   553  	if size == 0 {
   554  		return 0, nil
   555  	}
   556  
   557  	// Make sure we do not read more from buffer than the data slice can hold.
   558  	if len(data) < size {
   559  		size = len(data)
   560  	}
   561  
   562  	// only read number of bytes used from buffer
   563  	for i := 0; i < size; i++ {
   564  		v, _ := usbcdc.ReadByte()
   565  		data[i] = v
   566  	}
   567  
   568  	return size, nil
   569  }
   570  
   571  // Write data to the USBCDC.
   572  func (usbcdc USBCDC) Write(data []byte) (n int, err error) {
   573  	for _, v := range data {
   574  		usbcdc.WriteByte(v)
   575  	}
   576  	return len(data), nil
   577  }
   578  
   579  // ReadByte reads a single byte from the RX buffer.
   580  // If there is no data in the buffer, returns an error.
   581  func (usbcdc USBCDC) ReadByte() (byte, error) {
   582  	// check if RX buffer is empty
   583  	buf, ok := usbcdc.Buffer.Get()
   584  	if !ok {
   585  		return 0, errors.New("Buffer empty")
   586  	}
   587  	return buf, nil
   588  }
   589  
   590  // Buffered returns the number of bytes currently stored in the RX buffer.
   591  func (usbcdc USBCDC) Buffered() int {
   592  	return int(usbcdc.Buffer.Used())
   593  }
   594  
   595  // Receive handles adding data to the UART's data buffer.
   596  // Usually called by the IRQ handler for a machine.
   597  func (usbcdc USBCDC) Receive(data byte) {
   598  	usbcdc.Buffer.Put(data)
   599  }