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

     1  //go:build sam && atsamd21
     2  
     3  package machine
     4  
     5  import (
     6  	"device/sam"
     7  	"machine/usb"
     8  	"runtime/interrupt"
     9  	"unsafe"
    10  )
    11  
    12  const (
    13  	// these are SAMD21 specific.
    14  	usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos  = 0
    15  	usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask = 0x3FFF
    16  
    17  	usb_DEVICE_PCKSIZE_SIZE_Pos  = 28
    18  	usb_DEVICE_PCKSIZE_SIZE_Mask = 0x7
    19  
    20  	usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos  = 14
    21  	usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask = 0x3FFF
    22  )
    23  
    24  // Configure the USB peripheral. The config is here for compatibility with the UART interface.
    25  func (dev *USBDevice) Configure(config UARTConfig) {
    26  	if dev.initcomplete {
    27  		return
    28  	}
    29  
    30  	// reset USB interface
    31  	sam.USB_DEVICE.CTRLA.SetBits(sam.USB_DEVICE_CTRLA_SWRST)
    32  	for sam.USB_DEVICE.SYNCBUSY.HasBits(sam.USB_DEVICE_SYNCBUSY_SWRST) ||
    33  		sam.USB_DEVICE.SYNCBUSY.HasBits(sam.USB_DEVICE_SYNCBUSY_ENABLE) {
    34  	}
    35  
    36  	sam.USB_DEVICE.DESCADD.Set(uint32(uintptr(unsafe.Pointer(&usbEndpointDescriptors))))
    37  
    38  	// configure pins
    39  	USBCDC_DM_PIN.Configure(PinConfig{Mode: PinCom})
    40  	USBCDC_DP_PIN.Configure(PinConfig{Mode: PinCom})
    41  
    42  	// performs pad calibration from store fuses
    43  	handlePadCalibration()
    44  
    45  	// run in standby
    46  	sam.USB_DEVICE.CTRLA.SetBits(sam.USB_DEVICE_CTRLA_RUNSTDBY)
    47  
    48  	// set full speed
    49  	sam.USB_DEVICE.CTRLB.SetBits(sam.USB_DEVICE_CTRLB_SPDCONF_FS << sam.USB_DEVICE_CTRLB_SPDCONF_Pos)
    50  
    51  	// attach
    52  	sam.USB_DEVICE.CTRLB.ClearBits(sam.USB_DEVICE_CTRLB_DETACH)
    53  
    54  	// enable interrupt for end of reset
    55  	sam.USB_DEVICE.INTENSET.SetBits(sam.USB_DEVICE_INTENSET_EORST)
    56  
    57  	// enable interrupt for start of frame
    58  	sam.USB_DEVICE.INTENSET.SetBits(sam.USB_DEVICE_INTENSET_SOF)
    59  
    60  	// enable USB
    61  	sam.USB_DEVICE.CTRLA.SetBits(sam.USB_DEVICE_CTRLA_ENABLE)
    62  
    63  	// enable IRQ
    64  	interrupt.New(sam.IRQ_USB, handleUSBIRQ).Enable()
    65  
    66  	dev.initcomplete = true
    67  }
    68  
    69  func handlePadCalibration() {
    70  	// Load Pad Calibration data from non-volatile memory
    71  	// This requires registers that are not included in the SVD file.
    72  	// Modeled after defines from samd21g18a.h and nvmctrl.h:
    73  	//
    74  	// #define NVMCTRL_OTP4 0x00806020
    75  	//
    76  	// #define USB_FUSES_TRANSN_ADDR       (NVMCTRL_OTP4 + 4)
    77  	// #define USB_FUSES_TRANSN_Pos        13           /**< \brief (NVMCTRL_OTP4) USB pad Transn calibration */
    78  	// #define USB_FUSES_TRANSN_Msk        (0x1Fu << USB_FUSES_TRANSN_Pos)
    79  	// #define USB_FUSES_TRANSN(value)     ((USB_FUSES_TRANSN_Msk & ((value) << USB_FUSES_TRANSN_Pos)))
    80  
    81  	// #define USB_FUSES_TRANSP_ADDR       (NVMCTRL_OTP4 + 4)
    82  	// #define USB_FUSES_TRANSP_Pos        18           /**< \brief (NVMCTRL_OTP4) USB pad Transp calibration */
    83  	// #define USB_FUSES_TRANSP_Msk        (0x1Fu << USB_FUSES_TRANSP_Pos)
    84  	// #define USB_FUSES_TRANSP(value)     ((USB_FUSES_TRANSP_Msk & ((value) << USB_FUSES_TRANSP_Pos)))
    85  
    86  	// #define USB_FUSES_TRIM_ADDR         (NVMCTRL_OTP4 + 4)
    87  	// #define USB_FUSES_TRIM_Pos          23           /**< \brief (NVMCTRL_OTP4) USB pad Trim calibration */
    88  	// #define USB_FUSES_TRIM_Msk          (0x7u << USB_FUSES_TRIM_Pos)
    89  	// #define USB_FUSES_TRIM(value)       ((USB_FUSES_TRIM_Msk & ((value) << USB_FUSES_TRIM_Pos)))
    90  	//
    91  	fuse := *(*uint32)(unsafe.Pointer(uintptr(0x00806020) + 4))
    92  	calibTransN := uint16(fuse>>13) & uint16(0x1f)
    93  	calibTransP := uint16(fuse>>18) & uint16(0x1f)
    94  	calibTrim := uint16(fuse>>23) & uint16(0x7)
    95  
    96  	if calibTransN == 0x1f {
    97  		calibTransN = 5
    98  	}
    99  	sam.USB_DEVICE.PADCAL.SetBits(calibTransN << sam.USB_DEVICE_PADCAL_TRANSN_Pos)
   100  
   101  	if calibTransP == 0x1f {
   102  		calibTransP = 29
   103  	}
   104  	sam.USB_DEVICE.PADCAL.SetBits(calibTransP << sam.USB_DEVICE_PADCAL_TRANSP_Pos)
   105  
   106  	if calibTrim == 0x7 {
   107  		calibTrim = 3
   108  	}
   109  	sam.USB_DEVICE.PADCAL.SetBits(calibTrim << sam.USB_DEVICE_PADCAL_TRIM_Pos)
   110  }
   111  
   112  func handleUSBIRQ(intr interrupt.Interrupt) {
   113  	// reset all interrupt flags
   114  	flags := sam.USB_DEVICE.INTFLAG.Get()
   115  	sam.USB_DEVICE.INTFLAG.Set(flags)
   116  
   117  	// End of reset
   118  	if (flags & sam.USB_DEVICE_INTFLAG_EORST) > 0 {
   119  		// Configure control endpoint
   120  		initEndpoint(0, usb.ENDPOINT_TYPE_CONTROL)
   121  
   122  		usbConfiguration = 0
   123  
   124  		// ack the End-Of-Reset interrupt
   125  		sam.USB_DEVICE.INTFLAG.Set(sam.USB_DEVICE_INTFLAG_EORST)
   126  	}
   127  
   128  	// Start of frame
   129  	if (flags & sam.USB_DEVICE_INTFLAG_SOF) > 0 {
   130  		// if you want to blink LED showing traffic, this would be the place...
   131  	}
   132  
   133  	// Endpoint 0 Setup interrupt
   134  	if getEPINTFLAG(0)&sam.USB_DEVICE_EPINTFLAG_RXSTP > 0 {
   135  		// ack setup received
   136  		setEPINTFLAG(0, sam.USB_DEVICE_EPINTFLAG_RXSTP)
   137  
   138  		// parse setup
   139  		setup := usb.NewSetup(udd_ep_out_cache_buffer[0][:])
   140  
   141  		// Clear the Bank 0 ready flag on Control OUT
   142  		usbEndpointDescriptors[0].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[0]))))
   143  		usbEndpointDescriptors[0].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   144  		setEPSTATUSCLR(0, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
   145  
   146  		ok := false
   147  		if (setup.BmRequestType & usb.REQUEST_TYPE) == usb.REQUEST_STANDARD {
   148  			// Standard Requests
   149  			ok = handleStandardSetup(setup)
   150  		} else {
   151  			// Class Interface Requests
   152  			if setup.WIndex < uint16(len(usbSetupHandler)) && usbSetupHandler[setup.WIndex] != nil {
   153  				ok = usbSetupHandler[setup.WIndex](setup)
   154  			}
   155  		}
   156  
   157  		if ok {
   158  			// set Bank1 ready
   159  			setEPSTATUSSET(0, sam.USB_DEVICE_EPSTATUSSET_BK1RDY)
   160  		} else {
   161  			// Stall endpoint
   162  			setEPSTATUSSET(0, sam.USB_DEVICE_EPINTFLAG_STALL1)
   163  		}
   164  
   165  		if getEPINTFLAG(0)&sam.USB_DEVICE_EPINTFLAG_STALL1 > 0 {
   166  			// ack the stall
   167  			setEPINTFLAG(0, sam.USB_DEVICE_EPINTFLAG_STALL1)
   168  
   169  			// clear stall request
   170  			setEPINTENCLR(0, sam.USB_DEVICE_EPINTENCLR_STALL1)
   171  		}
   172  	}
   173  
   174  	// Now the actual transfer handlers, ignore endpoint number 0 (setup)
   175  	var i uint32
   176  	for i = 1; i < uint32(len(endPoints)); i++ {
   177  		// Check if endpoint has a pending interrupt
   178  		epFlags := getEPINTFLAG(i)
   179  		setEPINTFLAG(i, epFlags)
   180  		if (epFlags & sam.USB_DEVICE_EPINTFLAG_TRCPT0) > 0 {
   181  			buf := handleEndpointRx(i)
   182  			if usbRxHandler[i] != nil {
   183  				usbRxHandler[i](buf)
   184  			}
   185  			handleEndpointRxComplete(i)
   186  		} else if (epFlags & sam.USB_DEVICE_EPINTFLAG_TRCPT1) > 0 {
   187  			if usbTxHandler[i] != nil {
   188  				usbTxHandler[i]()
   189  			}
   190  		}
   191  	}
   192  }
   193  
   194  func initEndpoint(ep, config uint32) {
   195  	switch config {
   196  	case usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn:
   197  		// set packet size
   198  		usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
   199  
   200  		// set data buffer address
   201  		usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
   202  
   203  		// set endpoint type
   204  		setEPCFG(ep, ((usb.ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
   205  
   206  		setEPINTENSET(ep, sam.USB_DEVICE_EPINTENSET_TRCPT1)
   207  
   208  	case usb.ENDPOINT_TYPE_BULK | usb.EndpointOut:
   209  		// set packet size
   210  		usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
   211  
   212  		// set data buffer address
   213  		usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
   214  
   215  		// set endpoint type
   216  		setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_EPCFG_EPTYPE0_Pos))
   217  
   218  		// receive interrupts when current transfer complete
   219  		setEPINTENSET(ep, sam.USB_DEVICE_EPINTENSET_TRCPT0)
   220  
   221  		// set byte count to zero, we have not received anything yet
   222  		usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   223  
   224  		// ready for next transfer
   225  		setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
   226  
   227  	case usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointOut:
   228  		// set packet size
   229  		usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
   230  
   231  		// set data buffer address
   232  		usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
   233  
   234  		// set endpoint type
   235  		setEPCFG(ep, ((usb.ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_EPCFG_EPTYPE0_Pos))
   236  
   237  		// receive interrupts when current transfer complete
   238  		setEPINTENSET(ep, sam.USB_DEVICE_EPINTENSET_TRCPT0)
   239  
   240  		// set byte count to zero, we have not received anything yet
   241  		usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   242  
   243  		// ready for next transfer
   244  		setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
   245  
   246  	case usb.ENDPOINT_TYPE_BULK | usb.EndpointIn:
   247  		// set packet size
   248  		usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
   249  
   250  		// set data buffer address
   251  		usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
   252  
   253  		// set endpoint type
   254  		setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
   255  
   256  		// NAK on endpoint IN, the bank is not yet filled in.
   257  		setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK1RDY)
   258  
   259  		setEPINTENSET(ep, sam.USB_DEVICE_EPINTENSET_TRCPT1)
   260  
   261  	case usb.ENDPOINT_TYPE_CONTROL:
   262  		// Control OUT
   263  		// set packet size
   264  		usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
   265  
   266  		// set data buffer address
   267  		usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
   268  
   269  		// set endpoint type
   270  		setEPCFG(ep, getEPCFG(ep)|((usb.ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_EPCFG_EPTYPE0_Pos))
   271  
   272  		// Control IN
   273  		// set packet size
   274  		usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
   275  
   276  		// set data buffer address
   277  		usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
   278  
   279  		// set endpoint type
   280  		setEPCFG(ep, getEPCFG(ep)|((usb.ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
   281  
   282  		// Prepare OUT endpoint for receive
   283  		// set multi packet size for expected number of receive bytes on control OUT
   284  		usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits(64 << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
   285  
   286  		// set byte count to zero, we have not received anything yet
   287  		usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   288  
   289  		// NAK on endpoint OUT to show we are ready to receive control data
   290  		setEPSTATUSSET(ep, sam.USB_DEVICE_EPSTATUSSET_BK0RDY)
   291  
   292  		// Enable Setup-Received interrupt
   293  		setEPINTENSET(0, sam.USB_DEVICE_EPINTENSET_RXSTP)
   294  	}
   295  }
   296  
   297  func handleUSBSetAddress(setup usb.Setup) bool {
   298  	// set packet size 64 with auto Zlp after transfer
   299  	usbEndpointDescriptors[0].DeviceDescBank[1].PCKSIZE.Set((epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos) |
   300  		uint32(1<<31)) // autozlp
   301  
   302  	// ack the transfer is complete from the request
   303  	setEPINTFLAG(0, sam.USB_DEVICE_EPINTFLAG_TRCPT1)
   304  
   305  	// set bank ready for data
   306  	setEPSTATUSSET(0, sam.USB_DEVICE_EPSTATUSSET_BK1RDY)
   307  
   308  	// wait for transfer to complete
   309  	timeout := 3000
   310  	for (getEPINTFLAG(0) & sam.USB_DEVICE_EPINTFLAG_TRCPT1) == 0 {
   311  		timeout--
   312  		if timeout == 0 {
   313  			return true
   314  		}
   315  	}
   316  
   317  	// last, set the device address to that requested by host
   318  	sam.USB_DEVICE.DADD.SetBits(setup.WValueL)
   319  	sam.USB_DEVICE.DADD.SetBits(sam.USB_DEVICE_DADD_ADDEN)
   320  
   321  	return true
   322  }
   323  
   324  // SendUSBInPacket sends a packet for USB (interrupt in / bulk in).
   325  func SendUSBInPacket(ep uint32, data []byte) bool {
   326  	sendUSBPacket(ep, data, 0)
   327  
   328  	// clear transfer complete flag
   329  	setEPINTFLAG(ep, sam.USB_DEVICE_EPINTFLAG_TRCPT1)
   330  
   331  	// send data by setting bank ready
   332  	setEPSTATUSSET(ep, sam.USB_DEVICE_EPSTATUSSET_BK1RDY)
   333  
   334  	return true
   335  }
   336  
   337  //go:noinline
   338  func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
   339  	l := uint16(len(data))
   340  	if 0 < maxsize && maxsize < l {
   341  		l = maxsize
   342  	}
   343  
   344  	// Set endpoint address for sending data
   345  	if ep == 0 {
   346  		copy(udd_ep_control_cache_buffer[:], data[:l])
   347  		usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_control_cache_buffer))))
   348  	} else {
   349  		copy(udd_ep_in_cache_buffer[ep][:], data[:l])
   350  		usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
   351  	}
   352  
   353  	// clear multi-packet size which is total bytes already sent
   354  	usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
   355  
   356  	// set byte count, which is total number of bytes to be sent
   357  	usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   358  	usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits((uint32(l) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask) << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   359  }
   360  
   361  func ReceiveUSBControlPacket() ([cdcLineInfoSize]byte, error) {
   362  	var b [cdcLineInfoSize]byte
   363  
   364  	// Wait until OUT transfer is ready.
   365  	timeout := 300000
   366  	for (getEPSTATUS(0) & sam.USB_DEVICE_EPSTATUS_BK0RDY) == 0 {
   367  		timeout--
   368  		if timeout == 0 {
   369  			return b, ErrUSBReadTimeout
   370  		}
   371  	}
   372  
   373  	// Wait until OUT transfer is completed.
   374  	timeout = 300000
   375  	for (getEPINTFLAG(0) & sam.USB_DEVICE_EPINTFLAG_TRCPT0) == 0 {
   376  		timeout--
   377  		if timeout == 0 {
   378  			return b, ErrUSBReadTimeout
   379  		}
   380  	}
   381  
   382  	// get data
   383  	bytesread := uint32((usbEndpointDescriptors[0].DeviceDescBank[0].PCKSIZE.Get() >>
   384  		usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask)
   385  
   386  	if bytesread != cdcLineInfoSize {
   387  		return b, ErrUSBBytesRead
   388  	}
   389  
   390  	copy(b[:7], udd_ep_out_cache_buffer[0][:7])
   391  
   392  	return b, nil
   393  }
   394  
   395  func handleEndpointRx(ep uint32) []byte {
   396  	// get data
   397  	count := int((usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.Get() >>
   398  		usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask)
   399  
   400  	return udd_ep_out_cache_buffer[ep][:count]
   401  }
   402  
   403  func handleEndpointRxComplete(ep uint32) {
   404  	// set byte count to zero
   405  	usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   406  
   407  	// set multi packet size to 64
   408  	usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits(64 << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
   409  
   410  	// set ready for next data
   411  	setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
   412  
   413  }
   414  
   415  func SendZlp() {
   416  	usbEndpointDescriptors[0].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   417  }
   418  
   419  func epPacketSize(size uint16) uint32 {
   420  	switch size {
   421  	case 8:
   422  		return 0
   423  	case 16:
   424  		return 1
   425  	case 32:
   426  		return 2
   427  	case 64:
   428  		return 3
   429  	case 128:
   430  		return 4
   431  	case 256:
   432  		return 5
   433  	case 512:
   434  		return 6
   435  	case 1023:
   436  		return 7
   437  	default:
   438  		return 0
   439  	}
   440  }
   441  
   442  func getEPCFG(ep uint32) uint8 {
   443  	switch ep {
   444  	case 0:
   445  		return sam.USB_DEVICE.EPCFG0.Get()
   446  	case 1:
   447  		return sam.USB_DEVICE.EPCFG1.Get()
   448  	case 2:
   449  		return sam.USB_DEVICE.EPCFG2.Get()
   450  	case 3:
   451  		return sam.USB_DEVICE.EPCFG3.Get()
   452  	case 4:
   453  		return sam.USB_DEVICE.EPCFG4.Get()
   454  	case 5:
   455  		return sam.USB_DEVICE.EPCFG5.Get()
   456  	case 6:
   457  		return sam.USB_DEVICE.EPCFG6.Get()
   458  	case 7:
   459  		return sam.USB_DEVICE.EPCFG7.Get()
   460  	default:
   461  		return 0
   462  	}
   463  }
   464  
   465  func setEPCFG(ep uint32, val uint8) {
   466  	switch ep {
   467  	case 0:
   468  		sam.USB_DEVICE.EPCFG0.Set(val)
   469  	case 1:
   470  		sam.USB_DEVICE.EPCFG1.Set(val)
   471  	case 2:
   472  		sam.USB_DEVICE.EPCFG2.Set(val)
   473  	case 3:
   474  		sam.USB_DEVICE.EPCFG3.Set(val)
   475  	case 4:
   476  		sam.USB_DEVICE.EPCFG4.Set(val)
   477  	case 5:
   478  		sam.USB_DEVICE.EPCFG5.Set(val)
   479  	case 6:
   480  		sam.USB_DEVICE.EPCFG6.Set(val)
   481  	case 7:
   482  		sam.USB_DEVICE.EPCFG7.Set(val)
   483  	default:
   484  		return
   485  	}
   486  }
   487  
   488  func setEPSTATUSCLR(ep uint32, val uint8) {
   489  	switch ep {
   490  	case 0:
   491  		sam.USB_DEVICE.EPSTATUSCLR0.Set(val)
   492  	case 1:
   493  		sam.USB_DEVICE.EPSTATUSCLR1.Set(val)
   494  	case 2:
   495  		sam.USB_DEVICE.EPSTATUSCLR2.Set(val)
   496  	case 3:
   497  		sam.USB_DEVICE.EPSTATUSCLR3.Set(val)
   498  	case 4:
   499  		sam.USB_DEVICE.EPSTATUSCLR4.Set(val)
   500  	case 5:
   501  		sam.USB_DEVICE.EPSTATUSCLR5.Set(val)
   502  	case 6:
   503  		sam.USB_DEVICE.EPSTATUSCLR6.Set(val)
   504  	case 7:
   505  		sam.USB_DEVICE.EPSTATUSCLR7.Set(val)
   506  	default:
   507  		return
   508  	}
   509  }
   510  
   511  func setEPSTATUSSET(ep uint32, val uint8) {
   512  	switch ep {
   513  	case 0:
   514  		sam.USB_DEVICE.EPSTATUSSET0.Set(val)
   515  	case 1:
   516  		sam.USB_DEVICE.EPSTATUSSET1.Set(val)
   517  	case 2:
   518  		sam.USB_DEVICE.EPSTATUSSET2.Set(val)
   519  	case 3:
   520  		sam.USB_DEVICE.EPSTATUSSET3.Set(val)
   521  	case 4:
   522  		sam.USB_DEVICE.EPSTATUSSET4.Set(val)
   523  	case 5:
   524  		sam.USB_DEVICE.EPSTATUSSET5.Set(val)
   525  	case 6:
   526  		sam.USB_DEVICE.EPSTATUSSET6.Set(val)
   527  	case 7:
   528  		sam.USB_DEVICE.EPSTATUSSET7.Set(val)
   529  	default:
   530  		return
   531  	}
   532  }
   533  
   534  func getEPSTATUS(ep uint32) uint8 {
   535  	switch ep {
   536  	case 0:
   537  		return sam.USB_DEVICE.EPSTATUS0.Get()
   538  	case 1:
   539  		return sam.USB_DEVICE.EPSTATUS1.Get()
   540  	case 2:
   541  		return sam.USB_DEVICE.EPSTATUS2.Get()
   542  	case 3:
   543  		return sam.USB_DEVICE.EPSTATUS3.Get()
   544  	case 4:
   545  		return sam.USB_DEVICE.EPSTATUS4.Get()
   546  	case 5:
   547  		return sam.USB_DEVICE.EPSTATUS5.Get()
   548  	case 6:
   549  		return sam.USB_DEVICE.EPSTATUS6.Get()
   550  	case 7:
   551  		return sam.USB_DEVICE.EPSTATUS7.Get()
   552  	default:
   553  		return 0
   554  	}
   555  }
   556  
   557  func getEPINTFLAG(ep uint32) uint8 {
   558  	switch ep {
   559  	case 0:
   560  		return sam.USB_DEVICE.EPINTFLAG0.Get()
   561  	case 1:
   562  		return sam.USB_DEVICE.EPINTFLAG1.Get()
   563  	case 2:
   564  		return sam.USB_DEVICE.EPINTFLAG2.Get()
   565  	case 3:
   566  		return sam.USB_DEVICE.EPINTFLAG3.Get()
   567  	case 4:
   568  		return sam.USB_DEVICE.EPINTFLAG4.Get()
   569  	case 5:
   570  		return sam.USB_DEVICE.EPINTFLAG5.Get()
   571  	case 6:
   572  		return sam.USB_DEVICE.EPINTFLAG6.Get()
   573  	case 7:
   574  		return sam.USB_DEVICE.EPINTFLAG7.Get()
   575  	default:
   576  		return 0
   577  	}
   578  }
   579  
   580  func setEPINTFLAG(ep uint32, val uint8) {
   581  	switch ep {
   582  	case 0:
   583  		sam.USB_DEVICE.EPINTFLAG0.Set(val)
   584  	case 1:
   585  		sam.USB_DEVICE.EPINTFLAG1.Set(val)
   586  	case 2:
   587  		sam.USB_DEVICE.EPINTFLAG2.Set(val)
   588  	case 3:
   589  		sam.USB_DEVICE.EPINTFLAG3.Set(val)
   590  	case 4:
   591  		sam.USB_DEVICE.EPINTFLAG4.Set(val)
   592  	case 5:
   593  		sam.USB_DEVICE.EPINTFLAG5.Set(val)
   594  	case 6:
   595  		sam.USB_DEVICE.EPINTFLAG6.Set(val)
   596  	case 7:
   597  		sam.USB_DEVICE.EPINTFLAG7.Set(val)
   598  	default:
   599  		return
   600  	}
   601  }
   602  
   603  func setEPINTENCLR(ep uint32, val uint8) {
   604  	switch ep {
   605  	case 0:
   606  		sam.USB_DEVICE.EPINTENCLR0.Set(val)
   607  	case 1:
   608  		sam.USB_DEVICE.EPINTENCLR1.Set(val)
   609  	case 2:
   610  		sam.USB_DEVICE.EPINTENCLR2.Set(val)
   611  	case 3:
   612  		sam.USB_DEVICE.EPINTENCLR3.Set(val)
   613  	case 4:
   614  		sam.USB_DEVICE.EPINTENCLR4.Set(val)
   615  	case 5:
   616  		sam.USB_DEVICE.EPINTENCLR5.Set(val)
   617  	case 6:
   618  		sam.USB_DEVICE.EPINTENCLR6.Set(val)
   619  	case 7:
   620  		sam.USB_DEVICE.EPINTENCLR7.Set(val)
   621  	default:
   622  		return
   623  	}
   624  }
   625  
   626  func setEPINTENSET(ep uint32, val uint8) {
   627  	switch ep {
   628  	case 0:
   629  		sam.USB_DEVICE.EPINTENSET0.Set(val)
   630  	case 1:
   631  		sam.USB_DEVICE.EPINTENSET1.Set(val)
   632  	case 2:
   633  		sam.USB_DEVICE.EPINTENSET2.Set(val)
   634  	case 3:
   635  		sam.USB_DEVICE.EPINTENSET3.Set(val)
   636  	case 4:
   637  		sam.USB_DEVICE.EPINTENSET4.Set(val)
   638  	case 5:
   639  		sam.USB_DEVICE.EPINTENSET5.Set(val)
   640  	case 6:
   641  		sam.USB_DEVICE.EPINTENSET6.Set(val)
   642  	case 7:
   643  		sam.USB_DEVICE.EPINTENSET7.Set(val)
   644  	default:
   645  		return
   646  	}
   647  }