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

     1  //go:build (sam && atsamd51) || (sam && atsame5x)
     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 SAMD51 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_OTHER, handleUSBIRQ).Enable()
    65  	interrupt.New(sam.IRQ_USB_SOF_HSOF, handleUSBIRQ).Enable()
    66  	interrupt.New(sam.IRQ_USB_TRCPT0, handleUSBIRQ).Enable()
    67  	interrupt.New(sam.IRQ_USB_TRCPT1, handleUSBIRQ).Enable()
    68  
    69  	dev.initcomplete = true
    70  }
    71  
    72  func handlePadCalibration() {
    73  	// Load Pad Calibration data from non-volatile memory
    74  	// This requires registers that are not included in the SVD file.
    75  	// Modeled after defines from samd21g18a.h and nvmctrl.h:
    76  	//
    77  	// #define NVMCTRL_OTP4 0x00806020
    78  	//
    79  	// #define USB_FUSES_TRANSN_ADDR       (NVMCTRL_OTP4 + 4)
    80  	// #define USB_FUSES_TRANSN_Pos        13           /**< \brief (NVMCTRL_OTP4) USB pad Transn calibration */
    81  	// #define USB_FUSES_TRANSN_Msk        (0x1Fu << USB_FUSES_TRANSN_Pos)
    82  	// #define USB_FUSES_TRANSN(value)     ((USB_FUSES_TRANSN_Msk & ((value) << USB_FUSES_TRANSN_Pos)))
    83  
    84  	// #define USB_FUSES_TRANSP_ADDR       (NVMCTRL_OTP4 + 4)
    85  	// #define USB_FUSES_TRANSP_Pos        18           /**< \brief (NVMCTRL_OTP4) USB pad Transp calibration */
    86  	// #define USB_FUSES_TRANSP_Msk        (0x1Fu << USB_FUSES_TRANSP_Pos)
    87  	// #define USB_FUSES_TRANSP(value)     ((USB_FUSES_TRANSP_Msk & ((value) << USB_FUSES_TRANSP_Pos)))
    88  
    89  	// #define USB_FUSES_TRIM_ADDR         (NVMCTRL_OTP4 + 4)
    90  	// #define USB_FUSES_TRIM_Pos          23           /**< \brief (NVMCTRL_OTP4) USB pad Trim calibration */
    91  	// #define USB_FUSES_TRIM_Msk          (0x7u << USB_FUSES_TRIM_Pos)
    92  	// #define USB_FUSES_TRIM(value)       ((USB_FUSES_TRIM_Msk & ((value) << USB_FUSES_TRIM_Pos)))
    93  	//
    94  	fuse := *(*uint32)(unsafe.Pointer(uintptr(0x00806020) + 4))
    95  	calibTransN := uint16(fuse>>13) & uint16(0x1f)
    96  	calibTransP := uint16(fuse>>18) & uint16(0x1f)
    97  	calibTrim := uint16(fuse>>23) & uint16(0x7)
    98  
    99  	if calibTransN == 0x1f {
   100  		calibTransN = 5
   101  	}
   102  	sam.USB_DEVICE.PADCAL.SetBits(calibTransN << sam.USB_DEVICE_PADCAL_TRANSN_Pos)
   103  
   104  	if calibTransP == 0x1f {
   105  		calibTransP = 29
   106  	}
   107  	sam.USB_DEVICE.PADCAL.SetBits(calibTransP << sam.USB_DEVICE_PADCAL_TRANSP_Pos)
   108  
   109  	if calibTrim == 0x7 {
   110  		calibTrim = 3
   111  	}
   112  	sam.USB_DEVICE.PADCAL.SetBits(calibTrim << sam.USB_DEVICE_PADCAL_TRIM_Pos)
   113  }
   114  
   115  func handleUSBIRQ(intr interrupt.Interrupt) {
   116  	// reset all interrupt flags
   117  	flags := sam.USB_DEVICE.INTFLAG.Get()
   118  	sam.USB_DEVICE.INTFLAG.Set(flags)
   119  
   120  	// End of reset
   121  	if (flags & sam.USB_DEVICE_INTFLAG_EORST) > 0 {
   122  		// Configure control endpoint
   123  		initEndpoint(0, usb.ENDPOINT_TYPE_CONTROL)
   124  
   125  		usbConfiguration = 0
   126  
   127  		// ack the End-Of-Reset interrupt
   128  		sam.USB_DEVICE.INTFLAG.Set(sam.USB_DEVICE_INTFLAG_EORST)
   129  	}
   130  
   131  	// Start of frame
   132  	if (flags & sam.USB_DEVICE_INTFLAG_SOF) > 0 {
   133  		// if you want to blink LED showing traffic, this would be the place...
   134  	}
   135  
   136  	// Endpoint 0 Setup interrupt
   137  	if getEPINTFLAG(0)&sam.USB_DEVICE_ENDPOINT_EPINTFLAG_RXSTP > 0 {
   138  		// ack setup received
   139  		setEPINTFLAG(0, sam.USB_DEVICE_ENDPOINT_EPINTFLAG_RXSTP)
   140  
   141  		// parse setup
   142  		setup := usb.NewSetup(udd_ep_out_cache_buffer[0][:])
   143  
   144  		// Clear the Bank 0 ready flag on Control OUT
   145  		usbEndpointDescriptors[0].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[0]))))
   146  		usbEndpointDescriptors[0].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   147  		setEPSTATUSCLR(0, sam.USB_DEVICE_ENDPOINT_EPSTATUSCLR_BK0RDY)
   148  
   149  		ok := false
   150  		if (setup.BmRequestType & usb.REQUEST_TYPE) == usb.REQUEST_STANDARD {
   151  			// Standard Requests
   152  			ok = handleStandardSetup(setup)
   153  		} else {
   154  			// Class Interface Requests
   155  			if setup.WIndex < uint16(len(usbSetupHandler)) && usbSetupHandler[setup.WIndex] != nil {
   156  				ok = usbSetupHandler[setup.WIndex](setup)
   157  			}
   158  		}
   159  
   160  		if ok {
   161  			// set Bank1 ready
   162  			setEPSTATUSSET(0, sam.USB_DEVICE_ENDPOINT_EPSTATUSSET_BK1RDY)
   163  		} else {
   164  			// Stall endpoint
   165  			setEPSTATUSSET(0, sam.USB_DEVICE_ENDPOINT_EPINTFLAG_STALL1)
   166  		}
   167  
   168  		if getEPINTFLAG(0)&sam.USB_DEVICE_ENDPOINT_EPINTFLAG_STALL1 > 0 {
   169  			// ack the stall
   170  			setEPINTFLAG(0, sam.USB_DEVICE_ENDPOINT_EPINTFLAG_STALL1)
   171  
   172  			// clear stall request
   173  			setEPINTENCLR(0, sam.USB_DEVICE_ENDPOINT_EPINTENCLR_STALL1)
   174  		}
   175  	}
   176  
   177  	// Now the actual transfer handlers, ignore endpoint number 0 (setup)
   178  	var i uint32
   179  	for i = 1; i < uint32(len(endPoints)); i++ {
   180  		// Check if endpoint has a pending interrupt
   181  		epFlags := getEPINTFLAG(i)
   182  		setEPINTFLAG(i, epFlags)
   183  		if (epFlags & sam.USB_DEVICE_ENDPOINT_EPINTFLAG_TRCPT0) > 0 {
   184  			buf := handleEndpointRx(i)
   185  			if usbRxHandler[i] != nil {
   186  				usbRxHandler[i](buf)
   187  			}
   188  			handleEndpointRxComplete(i)
   189  		} else if (epFlags & sam.USB_DEVICE_ENDPOINT_EPINTFLAG_TRCPT1) > 0 {
   190  			if usbTxHandler[i] != nil {
   191  				usbTxHandler[i]()
   192  			}
   193  		}
   194  	}
   195  }
   196  
   197  func initEndpoint(ep, config uint32) {
   198  	switch config {
   199  	case usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn:
   200  		// set packet size
   201  		usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
   202  
   203  		// set data buffer address
   204  		usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
   205  
   206  		// set endpoint type
   207  		setEPCFG(ep, ((usb.ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE1_Pos))
   208  
   209  		setEPINTENSET(ep, sam.USB_DEVICE_ENDPOINT_EPINTENSET_TRCPT1)
   210  
   211  	case usb.ENDPOINT_TYPE_BULK | usb.EndpointOut:
   212  		// set packet size
   213  		usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
   214  
   215  		// set data buffer address
   216  		usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
   217  
   218  		// set endpoint type
   219  		setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE0_Pos))
   220  
   221  		// receive interrupts when current transfer complete
   222  		setEPINTENSET(ep, sam.USB_DEVICE_ENDPOINT_EPINTENSET_TRCPT0)
   223  
   224  		// set byte count to zero, we have not received anything yet
   225  		usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   226  
   227  		// ready for next transfer
   228  		setEPSTATUSCLR(ep, sam.USB_DEVICE_ENDPOINT_EPSTATUSCLR_BK0RDY)
   229  
   230  	case usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointOut:
   231  		// set packet size
   232  		usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
   233  
   234  		// set data buffer address
   235  		usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
   236  
   237  		// set endpoint type
   238  		setEPCFG(ep, ((usb.ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE0_Pos))
   239  
   240  		// receive interrupts when current transfer complete
   241  		setEPINTENSET(ep, sam.USB_DEVICE_ENDPOINT_EPINTENSET_TRCPT0)
   242  
   243  		// set byte count to zero, we have not received anything yet
   244  		usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   245  
   246  		// ready for next transfer
   247  		setEPSTATUSCLR(ep, sam.USB_DEVICE_ENDPOINT_EPSTATUSCLR_BK0RDY)
   248  
   249  	case usb.ENDPOINT_TYPE_BULK | usb.EndpointIn:
   250  		// set packet size
   251  		usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
   252  
   253  		// set data buffer address
   254  		usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
   255  
   256  		// set endpoint type
   257  		setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE1_Pos))
   258  
   259  		// NAK on endpoint IN, the bank is not yet filled in.
   260  		setEPSTATUSCLR(ep, sam.USB_DEVICE_ENDPOINT_EPSTATUSCLR_BK1RDY)
   261  
   262  		setEPINTENSET(ep, sam.USB_DEVICE_ENDPOINT_EPINTENSET_TRCPT1)
   263  
   264  	case usb.ENDPOINT_TYPE_CONTROL:
   265  		// Control OUT
   266  		// set packet size
   267  		usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
   268  
   269  		// set data buffer address
   270  		usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
   271  
   272  		// set endpoint type
   273  		setEPCFG(ep, getEPCFG(ep)|((usb.ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE0_Pos))
   274  
   275  		// Control IN
   276  		// set packet size
   277  		usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
   278  
   279  		// set data buffer address
   280  		usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
   281  
   282  		// set endpoint type
   283  		setEPCFG(ep, getEPCFG(ep)|((usb.ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE1_Pos))
   284  
   285  		// Prepare OUT endpoint for receive
   286  		// set multi packet size for expected number of receive bytes on control OUT
   287  		usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits(64 << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
   288  
   289  		// set byte count to zero, we have not received anything yet
   290  		usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   291  
   292  		// NAK on endpoint OUT to show we are ready to receive control data
   293  		setEPSTATUSSET(ep, sam.USB_DEVICE_ENDPOINT_EPSTATUSSET_BK0RDY)
   294  
   295  		// Enable Setup-Received interrupt
   296  		setEPINTENSET(0, sam.USB_DEVICE_ENDPOINT_EPINTENSET_RXSTP)
   297  	}
   298  }
   299  
   300  func handleUSBSetAddress(setup usb.Setup) bool {
   301  	// set packet size 64 with auto Zlp after transfer
   302  	usbEndpointDescriptors[0].DeviceDescBank[1].PCKSIZE.Set((epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos) |
   303  		uint32(1<<31)) // autozlp
   304  
   305  	// ack the transfer is complete from the request
   306  	setEPINTFLAG(0, sam.USB_DEVICE_ENDPOINT_EPINTFLAG_TRCPT1)
   307  
   308  	// set bank ready for data
   309  	setEPSTATUSSET(0, sam.USB_DEVICE_ENDPOINT_EPSTATUSSET_BK1RDY)
   310  
   311  	// wait for transfer to complete
   312  	timeout := 3000
   313  	for (getEPINTFLAG(0) & sam.USB_DEVICE_ENDPOINT_EPINTFLAG_TRCPT1) == 0 {
   314  		timeout--
   315  		if timeout == 0 {
   316  			return true
   317  		}
   318  	}
   319  
   320  	// last, set the device address to that requested by host
   321  	sam.USB_DEVICE.DADD.SetBits(setup.WValueL)
   322  	sam.USB_DEVICE.DADD.SetBits(sam.USB_DEVICE_DADD_ADDEN)
   323  
   324  	return true
   325  }
   326  
   327  // SendUSBInPacket sends a packet for USB (interrupt in / bulk in).
   328  func SendUSBInPacket(ep uint32, data []byte) bool {
   329  	sendUSBPacket(ep, data, 0)
   330  
   331  	// clear transfer complete flag
   332  	setEPINTFLAG(ep, sam.USB_DEVICE_ENDPOINT_EPINTFLAG_TRCPT1)
   333  
   334  	// send data by setting bank ready
   335  	setEPSTATUSSET(ep, sam.USB_DEVICE_ENDPOINT_EPSTATUSSET_BK1RDY)
   336  
   337  	return true
   338  }
   339  
   340  //go:noinline
   341  func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
   342  	l := uint16(len(data))
   343  	if 0 < maxsize && maxsize < l {
   344  		l = maxsize
   345  	}
   346  
   347  	// Set endpoint address for sending data
   348  	if ep == 0 {
   349  		copy(udd_ep_control_cache_buffer[:], data[:l])
   350  		usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_control_cache_buffer))))
   351  	} else {
   352  		copy(udd_ep_in_cache_buffer[ep][:], data[:l])
   353  		usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
   354  	}
   355  
   356  	// clear multi-packet size which is total bytes already sent
   357  	usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
   358  
   359  	// set byte count, which is total number of bytes to be sent
   360  	usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   361  	usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits((uint32(l) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask) << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   362  }
   363  
   364  func ReceiveUSBControlPacket() ([cdcLineInfoSize]byte, error) {
   365  	var b [cdcLineInfoSize]byte
   366  
   367  	// Wait until OUT transfer is ready.
   368  	timeout := 300000
   369  	for (getEPSTATUS(0) & sam.USB_DEVICE_ENDPOINT_EPSTATUS_BK0RDY) == 0 {
   370  		timeout--
   371  		if timeout == 0 {
   372  			return b, ErrUSBReadTimeout
   373  		}
   374  	}
   375  
   376  	// Wait until OUT transfer is completed.
   377  	timeout = 300000
   378  	for (getEPINTFLAG(0) & sam.USB_DEVICE_ENDPOINT_EPINTFLAG_TRCPT0) == 0 {
   379  		timeout--
   380  		if timeout == 0 {
   381  			return b, ErrUSBReadTimeout
   382  		}
   383  	}
   384  
   385  	// get data
   386  	bytesread := uint32((usbEndpointDescriptors[0].DeviceDescBank[0].PCKSIZE.Get() >>
   387  		usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask)
   388  
   389  	if bytesread != cdcLineInfoSize {
   390  		return b, ErrUSBBytesRead
   391  	}
   392  
   393  	copy(b[:7], udd_ep_out_cache_buffer[0][:7])
   394  
   395  	return b, nil
   396  }
   397  
   398  func handleEndpointRx(ep uint32) []byte {
   399  	// get data
   400  	count := int((usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.Get() >>
   401  		usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask)
   402  
   403  	return udd_ep_out_cache_buffer[ep][:count]
   404  }
   405  
   406  func handleEndpointRxComplete(ep uint32) {
   407  	// set byte count to zero
   408  	usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   409  
   410  	// set multi packet size to 64
   411  	usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits(64 << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
   412  
   413  	// set ready for next data
   414  	setEPSTATUSCLR(ep, sam.USB_DEVICE_ENDPOINT_EPSTATUSCLR_BK0RDY)
   415  }
   416  
   417  func SendZlp() {
   418  	usbEndpointDescriptors[0].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
   419  }
   420  
   421  func epPacketSize(size uint16) uint32 {
   422  	switch size {
   423  	case 8:
   424  		return 0
   425  	case 16:
   426  		return 1
   427  	case 32:
   428  		return 2
   429  	case 64:
   430  		return 3
   431  	case 128:
   432  		return 4
   433  	case 256:
   434  		return 5
   435  	case 512:
   436  		return 6
   437  	case 1023:
   438  		return 7
   439  	default:
   440  		return 0
   441  	}
   442  }
   443  
   444  func getEPCFG(ep uint32) uint8 {
   445  	return sam.USB_DEVICE.DEVICE_ENDPOINT[ep].EPCFG.Get()
   446  }
   447  
   448  func setEPCFG(ep uint32, val uint8) {
   449  	sam.USB_DEVICE.DEVICE_ENDPOINT[ep].EPCFG.Set(val)
   450  }
   451  
   452  func setEPSTATUSCLR(ep uint32, val uint8) {
   453  	sam.USB_DEVICE.DEVICE_ENDPOINT[ep].EPSTATUSCLR.Set(val)
   454  }
   455  
   456  func setEPSTATUSSET(ep uint32, val uint8) {
   457  	sam.USB_DEVICE.DEVICE_ENDPOINT[ep].EPSTATUSSET.Set(val)
   458  }
   459  
   460  func getEPSTATUS(ep uint32) uint8 {
   461  	return sam.USB_DEVICE.DEVICE_ENDPOINT[ep].EPSTATUS.Get()
   462  }
   463  
   464  func getEPINTFLAG(ep uint32) uint8 {
   465  	return sam.USB_DEVICE.DEVICE_ENDPOINT[ep].EPINTFLAG.Get()
   466  }
   467  
   468  func setEPINTFLAG(ep uint32, val uint8) {
   469  	sam.USB_DEVICE.DEVICE_ENDPOINT[ep].EPINTFLAG.Set(val)
   470  }
   471  
   472  func setEPINTENCLR(ep uint32, val uint8) {
   473  	sam.USB_DEVICE.DEVICE_ENDPOINT[ep].EPINTENCLR.Set(val)
   474  }
   475  
   476  func setEPINTENSET(ep uint32, val uint8) {
   477  	sam.USB_DEVICE.DEVICE_ENDPOINT[ep].EPINTENSET.Set(val)
   478  }