machine/samd21/arduino-nano33: adds support for Arduino Nano33 IoT along with mapping to NINA-W102 WiFi chip.
Also adds DTR and RTS functions along with timeouts to USBCDC functions to prevent lockups. Signed-off-by: Ron Evans <ron@hybridgroup.com>
Этот коммит содержится в:
родитель
ffa38b183b
коммит
fc9188a298
8 изменённых файлов: 271 добавлений и 31 удалений
138
src/machine/board_arduino_nano33.go
Обычный файл
138
src/machine/board_arduino_nano33.go
Обычный файл
|
@ -0,0 +1,138 @@
|
||||||
|
// +build sam,atsamd21,arduino_nano33
|
||||||
|
|
||||||
|
// This contains the pin mappings for the Arduino Nano33 IoT board.
|
||||||
|
//
|
||||||
|
// For more information, see: https://store.arduino.cc/nano-33-iot
|
||||||
|
//
|
||||||
|
package machine
|
||||||
|
|
||||||
|
import "device/sam"
|
||||||
|
|
||||||
|
// GPIO Pins
|
||||||
|
const (
|
||||||
|
RX0 Pin = PB23 // UART2 RX
|
||||||
|
TX1 Pin = PB22 // UART2 TX
|
||||||
|
|
||||||
|
D2 Pin = PB10 // PWM available
|
||||||
|
D3 Pin = PB11 // PWM available
|
||||||
|
D4 Pin = PA07
|
||||||
|
D5 Pin = PA05 // PWM available
|
||||||
|
D6 Pin = PA04 // PWM available
|
||||||
|
D7 Pin = PA06
|
||||||
|
|
||||||
|
D8 Pin = PA18
|
||||||
|
D9 Pin = PA20 // PWM available
|
||||||
|
D10 Pin = PA21 // PWM available
|
||||||
|
D11 Pin = PA16 // PWM available
|
||||||
|
D12 Pin = PA19 // PWM available
|
||||||
|
|
||||||
|
D13 Pin = PA17
|
||||||
|
)
|
||||||
|
|
||||||
|
// Analog pins
|
||||||
|
const (
|
||||||
|
A0 Pin = PA02 // ADC/AIN[0]
|
||||||
|
A1 Pin = PB02 // ADC/AIN[10]
|
||||||
|
A2 Pin = PA11 // ADC/AIN[19]
|
||||||
|
A3 Pin = PA10 // ADC/AIN[18]
|
||||||
|
A4 Pin = PB08 // ADC/AIN[2], SCL: SERCOM2/PAD[1]
|
||||||
|
A5 Pin = PB09 // ADC/AIN[3], SDA: SERCOM2/PAD[1]
|
||||||
|
A6 Pin = PA09 // ADC/AIN[17]
|
||||||
|
A7 Pin = PB03 // ADC/AIN[11]
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LED = D13
|
||||||
|
)
|
||||||
|
|
||||||
|
// NINA-W102 Pins
|
||||||
|
|
||||||
|
const (
|
||||||
|
NINA_MOSI Pin = PA12
|
||||||
|
NINA_MISO Pin = PA13
|
||||||
|
NINA_CS Pin = PA14
|
||||||
|
NINA_SCK Pin = PA15
|
||||||
|
NINA_GPIO0 Pin = PA27
|
||||||
|
NINA_RESETN Pin = PA08
|
||||||
|
NINA_ACK Pin = PA28
|
||||||
|
)
|
||||||
|
|
||||||
|
// UART0 aka USBCDC pins
|
||||||
|
const (
|
||||||
|
USBCDC_DM_PIN Pin = PA24
|
||||||
|
USBCDC_DP_PIN Pin = PA25
|
||||||
|
)
|
||||||
|
|
||||||
|
// UART1 on the Arduino Nano 33 connects to the onboard NINA-W102 WiFi chip.
|
||||||
|
var (
|
||||||
|
UART1 = UART{Bus: sam.SERCOM5_USART,
|
||||||
|
Buffer: NewRingBuffer(),
|
||||||
|
Mode: PinSERCOMAlt,
|
||||||
|
IRQVal: sam.IRQ_SERCOM5,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// UART1 pins
|
||||||
|
const (
|
||||||
|
UART_TX_PIN Pin = PA22
|
||||||
|
UART_RX_PIN Pin = PA23
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:export SERCOM5_IRQHandler
|
||||||
|
func handleUART1() {
|
||||||
|
defaultUART1Handler()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UART2 on the Arduino Nano 33 connects to the normal TX/RX pins.
|
||||||
|
var (
|
||||||
|
UART2 = UART{Bus: sam.SERCOM3_USART,
|
||||||
|
Buffer: NewRingBuffer(),
|
||||||
|
Mode: PinSERCOMAlt,
|
||||||
|
IRQVal: sam.IRQ_SERCOM3,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:export SERCOM3_IRQHandler
|
||||||
|
func handleUART2() {
|
||||||
|
// should reset IRQ
|
||||||
|
UART2.Receive(byte((UART2.Bus.DATA.Get() & 0xFF)))
|
||||||
|
UART2.Bus.INTFLAG.SetBits(sam.SERCOM_USART_INTFLAG_RXC)
|
||||||
|
}
|
||||||
|
|
||||||
|
// I2C pins
|
||||||
|
const (
|
||||||
|
SDA_PIN Pin = A4 // SDA: SERCOM4/PAD[1]
|
||||||
|
SCL_PIN Pin = A5 // SCL: SERCOM4/PAD[1]
|
||||||
|
)
|
||||||
|
|
||||||
|
// I2C on the Arduino Nano 33.
|
||||||
|
var (
|
||||||
|
I2C0 = I2C{Bus: sam.SERCOM4_I2CM,
|
||||||
|
SDA: SDA_PIN,
|
||||||
|
SCL: SCL_PIN,
|
||||||
|
PinMode: PinSERCOMAlt}
|
||||||
|
)
|
||||||
|
|
||||||
|
// SPI pins
|
||||||
|
const (
|
||||||
|
SPI0_SCK_PIN Pin = PB11 // SCK: SERCOM4/PAD[3]
|
||||||
|
SPI0_MOSI_PIN Pin = PB10 // MOSI: SERCOM4/PAD[2]
|
||||||
|
SPI0_MISO_PIN Pin = PA12 // MISO: SERCOM4/PAD[0]
|
||||||
|
)
|
||||||
|
|
||||||
|
// SPI on the Arduino Nano 33.
|
||||||
|
var (
|
||||||
|
SPI0 = SPI{Bus: sam.SERCOM1_SPI}
|
||||||
|
)
|
||||||
|
|
||||||
|
// I2S pins
|
||||||
|
const (
|
||||||
|
I2S_SCK_PIN Pin = PA10
|
||||||
|
I2S_SD_PIN Pin = PA08
|
||||||
|
I2S_WS_PIN = NoPin // TODO: figure out what this is on Arduino Nano 33.
|
||||||
|
)
|
||||||
|
|
||||||
|
// I2S on the Arduino Nano 33.
|
||||||
|
var (
|
||||||
|
I2S0 = I2S{Bus: sam.I2S}
|
||||||
|
)
|
|
@ -65,6 +65,20 @@ const (
|
||||||
UART_RX_PIN = PB09 // PORTB
|
UART_RX_PIN = PB09 // PORTB
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// UART1 on the Circuit Playground Express.
|
||||||
|
var (
|
||||||
|
UART1 = UART{Bus: sam.SERCOM1_USART,
|
||||||
|
Buffer: NewRingBuffer(),
|
||||||
|
Mode: PinSERCOM,
|
||||||
|
IRQVal: sam.IRQ_SERCOM1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:export SERCOM1_IRQHandler
|
||||||
|
func handleUART1() {
|
||||||
|
defaultUART1Handler()
|
||||||
|
}
|
||||||
|
|
||||||
// I2C pins
|
// I2C pins
|
||||||
const (
|
const (
|
||||||
SDA_PIN = PB02 // I2C0 external
|
SDA_PIN = PB02 // I2C0 external
|
||||||
|
|
|
@ -48,6 +48,20 @@ const (
|
||||||
UART_RX_PIN = D11
|
UART_RX_PIN = D11
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// UART1 on the Feather M0.
|
||||||
|
var (
|
||||||
|
UART1 = UART{Bus: sam.SERCOM1_USART,
|
||||||
|
Buffer: NewRingBuffer(),
|
||||||
|
Mode: PinSERCOM,
|
||||||
|
IRQVal: sam.IRQ_SERCOM1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:export SERCOM1_IRQHandler
|
||||||
|
func handleUART1() {
|
||||||
|
defaultUART1Handler()
|
||||||
|
}
|
||||||
|
|
||||||
// I2C pins
|
// I2C pins
|
||||||
const (
|
const (
|
||||||
SDA_PIN = PA22 // SDA: SERCOM3/PAD[0]
|
SDA_PIN = PA22 // SDA: SERCOM3/PAD[0]
|
||||||
|
|
|
@ -48,6 +48,20 @@ const (
|
||||||
UART_RX_PIN = D11
|
UART_RX_PIN = D11
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// UART1 on the ItsyBitsy M0.
|
||||||
|
var (
|
||||||
|
UART1 = UART{Bus: sam.SERCOM1_USART,
|
||||||
|
Buffer: NewRingBuffer(),
|
||||||
|
Mode: PinSERCOM,
|
||||||
|
IRQVal: sam.IRQ_SERCOM1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:export SERCOM1_IRQHandler
|
||||||
|
func handleUART1() {
|
||||||
|
defaultUART1Handler()
|
||||||
|
}
|
||||||
|
|
||||||
// I2C pins
|
// I2C pins
|
||||||
const (
|
const (
|
||||||
SDA_PIN = PA22 // SDA: SERCOM3/PAD[0]
|
SDA_PIN = PA22 // SDA: SERCOM3/PAD[0]
|
||||||
|
|
|
@ -39,6 +39,20 @@ const (
|
||||||
UART_RX_PIN = D3
|
UART_RX_PIN = D3
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// UART1 on the Trinket M0.
|
||||||
|
var (
|
||||||
|
UART1 = UART{Bus: sam.SERCOM1_USART,
|
||||||
|
Buffer: NewRingBuffer(),
|
||||||
|
Mode: PinSERCOM,
|
||||||
|
IRQVal: sam.IRQ_SERCOM1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:export SERCOM1_IRQHandler
|
||||||
|
func handleUART1() {
|
||||||
|
defaultUART1Handler()
|
||||||
|
}
|
||||||
|
|
||||||
// SPI pins
|
// SPI pins
|
||||||
const (
|
const (
|
||||||
SPI0_SCK_PIN = D3
|
SPI0_SCK_PIN = D3
|
||||||
|
|
|
@ -250,14 +250,13 @@ func waitADCSync() {
|
||||||
type UART struct {
|
type UART struct {
|
||||||
Buffer *RingBuffer
|
Buffer *RingBuffer
|
||||||
Bus *sam.SERCOM_USART_Type
|
Bus *sam.SERCOM_USART_Type
|
||||||
|
Mode PinMode
|
||||||
|
IRQVal uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// UART0 is actually a USB CDC interface.
|
// UART0 is actually a USB CDC interface.
|
||||||
UART0 = USBCDC{Buffer: NewRingBuffer()}
|
UART0 = USBCDC{Buffer: NewRingBuffer()}
|
||||||
|
|
||||||
// The first hardware serial port on the SAMD21. Uses the SERCOM0 interface.
|
|
||||||
UART1 = UART{Bus: sam.SERCOM1_USART, Buffer: NewRingBuffer()}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -300,6 +299,8 @@ func (uart UART) Configure(config UARTConfig) {
|
||||||
txpad = sercomTXPad2
|
txpad = sercomTXPad2
|
||||||
case PA16:
|
case PA16:
|
||||||
txpad = sercomTXPad0
|
txpad = sercomTXPad0
|
||||||
|
case PA22:
|
||||||
|
txpad = sercomTXPad0
|
||||||
default:
|
default:
|
||||||
panic("Invalid TX pin for UART")
|
panic("Invalid TX pin for UART")
|
||||||
}
|
}
|
||||||
|
@ -315,13 +316,15 @@ func (uart UART) Configure(config UARTConfig) {
|
||||||
rxpad = sercomRXPad3
|
rxpad = sercomRXPad3
|
||||||
case PA17:
|
case PA17:
|
||||||
rxpad = sercomRXPad1
|
rxpad = sercomRXPad1
|
||||||
|
case PA23:
|
||||||
|
rxpad = sercomRXPad1
|
||||||
default:
|
default:
|
||||||
panic("Invalid RX pin for UART")
|
panic("Invalid RX pin for UART")
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure pins
|
// configure pins
|
||||||
config.TX.Configure(PinConfig{Mode: PinSERCOM})
|
config.TX.Configure(PinConfig{Mode: uart.Mode})
|
||||||
config.RX.Configure(PinConfig{Mode: PinSERCOM})
|
config.RX.Configure(PinConfig{Mode: uart.Mode})
|
||||||
|
|
||||||
// reset SERCOM0
|
// reset SERCOM0
|
||||||
uart.Bus.CTRLA.SetBits(sam.SERCOM_USART_CTRLA_SWRST)
|
uart.Bus.CTRLA.SetBits(sam.SERCOM_USART_CTRLA_SWRST)
|
||||||
|
@ -372,13 +375,7 @@ func (uart UART) Configure(config UARTConfig) {
|
||||||
uart.Bus.INTENSET.Set(sam.SERCOM_USART_INTENSET_RXC)
|
uart.Bus.INTENSET.Set(sam.SERCOM_USART_INTENSET_RXC)
|
||||||
|
|
||||||
// Enable RX IRQ.
|
// Enable RX IRQ.
|
||||||
if config.TX == PA10 {
|
arm.EnableIRQ(uart.IRQVal)
|
||||||
// UART0
|
|
||||||
arm.EnableIRQ(sam.IRQ_SERCOM0)
|
|
||||||
} else {
|
|
||||||
// UART1 which is the normal default, since UART0 is used for USBCDC.
|
|
||||||
arm.EnableIRQ(sam.IRQ_SERCOM1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBaudRate sets the communication speed for the UART.
|
// SetBaudRate sets the communication speed for the UART.
|
||||||
|
@ -404,8 +401,8 @@ func (uart UART) WriteByte(c byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:export SERCOM1_IRQHandler
|
// defaultUART1Handler handles the UART1 IRQ.
|
||||||
func handleUART1() {
|
func defaultUART1Handler() {
|
||||||
// should reset IRQ
|
// should reset IRQ
|
||||||
UART1.Receive(byte((UART1.Bus.DATA.Get() & 0xFF)))
|
UART1.Receive(byte((UART1.Bus.DATA.Get() & 0xFF)))
|
||||||
UART1.Bus.INTFLAG.SetBits(sam.SERCOM_USART_INTFLAG_RXC)
|
UART1.Bus.INTFLAG.SetBits(sam.SERCOM_USART_INTFLAG_RXC)
|
||||||
|
@ -1182,23 +1179,35 @@ func (usbcdc USBCDC) WriteByte(c byte) error {
|
||||||
usbEndpointDescriptors[usb_CDC_ENDPOINT_IN].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
|
usbEndpointDescriptors[usb_CDC_ENDPOINT_IN].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
|
||||||
|
|
||||||
// set count of bytes to be sent
|
// set count of bytes to be sent
|
||||||
usbEndpointDescriptors[usb_CDC_ENDPOINT_IN].DeviceDescBank[1].PCKSIZE.SetBits((1&usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask)<<usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos |
|
usbEndpointDescriptors[usb_CDC_ENDPOINT_IN].DeviceDescBank[1].PCKSIZE.SetBits((1 & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask) << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
||||||
(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos))
|
|
||||||
|
|
||||||
// ack transfer complete flag
|
// clear transfer complete flag
|
||||||
setEPINTFLAG(usb_CDC_ENDPOINT_IN, sam.USB_DEVICE_EPINTFLAG_TRCPT1)
|
setEPINTFLAG(usb_CDC_ENDPOINT_IN, sam.USB_DEVICE_EPINTFLAG_TRCPT1)
|
||||||
|
|
||||||
// send data by setting bank ready
|
// send data by setting bank ready
|
||||||
setEPSTATUSSET(usb_CDC_ENDPOINT_IN, sam.USB_DEVICE_EPSTATUSSET_BK1RDY)
|
setEPSTATUSSET(usb_CDC_ENDPOINT_IN, sam.USB_DEVICE_EPSTATUSSET_BK1RDY)
|
||||||
|
|
||||||
// wait for transfer to complete
|
// wait for transfer to complete
|
||||||
|
timeout := 3000
|
||||||
for (getEPINTFLAG(usb_CDC_ENDPOINT_IN) & sam.USB_DEVICE_EPINTFLAG_TRCPT1) == 0 {
|
for (getEPINTFLAG(usb_CDC_ENDPOINT_IN) & sam.USB_DEVICE_EPINTFLAG_TRCPT1) == 0 {
|
||||||
|
timeout--
|
||||||
|
if timeout == 0 {
|
||||||
|
return errors.New("USBCDC write byte timeout")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (usbcdc USBCDC) DTR() bool {
|
||||||
|
return (usbLineInfo.lineState & usb_CDC_LINESTATE_DTR) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (usbcdc USBCDC) RTS() bool {
|
||||||
|
return (usbLineInfo.lineState & usb_CDC_LINESTATE_RTS) > 0
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// these are SAMD21 specific.
|
// these are SAMD21 specific.
|
||||||
usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos = 0
|
usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos = 0
|
||||||
|
@ -1346,6 +1355,7 @@ func handleUSB() {
|
||||||
|
|
||||||
// Clear the Bank 0 ready flag on Control OUT
|
// Clear the Bank 0 ready flag on Control OUT
|
||||||
setEPSTATUSCLR(0, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
|
setEPSTATUSCLR(0, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
|
||||||
|
usbEndpointDescriptors[0].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
||||||
|
|
||||||
ok := false
|
ok := false
|
||||||
if (setup.bmRequestType & usb_REQUEST_TYPE) == usb_REQUEST_STANDARD {
|
if (setup.bmRequestType & usb_REQUEST_TYPE) == usb_REQUEST_STANDARD {
|
||||||
|
@ -1375,20 +1385,25 @@ func handleUSB() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now the actual transfer handlers
|
// Now the actual transfer handlers, ignore endpoint number 0 (setup)
|
||||||
eptInts := sam.USB_DEVICE.EPINTSMRY.Get() & 0xFE // Remove endpoint number 0 (setup)
|
|
||||||
var i uint32
|
var i uint32
|
||||||
for i = 1; i < uint32(len(endPoints)); i++ {
|
for i = 1; i < uint32(len(endPoints)); i++ {
|
||||||
// Check if endpoint has a pending interrupt
|
// Check if endpoint has a pending interrupt
|
||||||
if eptInts&(1<<i) > 0 {
|
|
||||||
// yes, so handle flags
|
|
||||||
epFlags := getEPINTFLAG(i)
|
epFlags := getEPINTFLAG(i)
|
||||||
setEPINTFLAG(i, epFlags)
|
if epFlags > 0 {
|
||||||
|
switch i {
|
||||||
// Endpoint Transfer Complete Interrupt
|
case usb_CDC_ENDPOINT_OUT:
|
||||||
if (epFlags & sam.USB_DEVICE_EPINTFLAG_TRCPT0) > 0 {
|
if (epFlags & sam.USB_DEVICE_EPINTFLAG_TRCPT0) > 0 {
|
||||||
handleEndpoint(i)
|
handleEndpoint(i)
|
||||||
}
|
}
|
||||||
|
setEPINTFLAG(i, epFlags)
|
||||||
|
case usb_CDC_ENDPOINT_IN, usb_CDC_ENDPOINT_ACM:
|
||||||
|
// set bank ready
|
||||||
|
setEPSTATUSCLR(i, sam.USB_DEVICE_EPSTATUSCLR_BK1RDY)
|
||||||
|
|
||||||
|
// ack transfer complete
|
||||||
|
setEPINTFLAG(i, sam.USB_DEVICE_EPINTFLAG_TRCPT1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1403,7 +1418,7 @@ func initEndpoint(ep, config uint32) {
|
||||||
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
|
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
|
||||||
|
|
||||||
// set endpoint type
|
// set endpoint type
|
||||||
setEPCFG(ep, getEPCFG(ep)|((usb_ENDPOINT_TYPE_INTERRUPT+1)<<sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
|
setEPCFG(ep, ((usb_ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
|
||||||
|
|
||||||
case usb_ENDPOINT_TYPE_BULK | usbEndpointOut:
|
case usb_ENDPOINT_TYPE_BULK | usbEndpointOut:
|
||||||
// set packet size
|
// set packet size
|
||||||
|
@ -1413,11 +1428,14 @@ func initEndpoint(ep, config uint32) {
|
||||||
usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
|
usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
|
||||||
|
|
||||||
// set endpoint type
|
// set endpoint type
|
||||||
setEPCFG(ep, getEPCFG(ep)|((usb_ENDPOINT_TYPE_BULK+1)<<sam.USB_DEVICE_EPCFG_EPTYPE0_Pos))
|
setEPCFG(ep, ((usb_ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_EPCFG_EPTYPE0_Pos))
|
||||||
|
|
||||||
// ack the current transfer
|
// receive interrupts when current transfer complete
|
||||||
setEPINTENSET(ep, sam.USB_DEVICE_EPINTENSET_TRCPT0)
|
setEPINTENSET(ep, sam.USB_DEVICE_EPINTENSET_TRCPT0)
|
||||||
|
|
||||||
|
// set byte count to zero, we have not received anything yet
|
||||||
|
usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
||||||
|
|
||||||
// ready for next transfer
|
// ready for next transfer
|
||||||
setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
|
setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
|
||||||
|
|
||||||
|
@ -1432,7 +1450,7 @@ func initEndpoint(ep, config uint32) {
|
||||||
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
|
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
|
||||||
|
|
||||||
// set endpoint type
|
// set endpoint type
|
||||||
setEPCFG(ep, getEPCFG(ep)|((usb_ENDPOINT_TYPE_BULK+1)<<sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
|
setEPCFG(ep, ((usb_ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
|
||||||
|
|
||||||
// NAK on endpoint IN, the bank is not yet filled in.
|
// NAK on endpoint IN, the bank is not yet filled in.
|
||||||
setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK1RDY)
|
setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK1RDY)
|
||||||
|
@ -1515,7 +1533,12 @@ func handleStandardSetup(setup usbSetup) bool {
|
||||||
setEPSTATUSSET(0, sam.USB_DEVICE_EPSTATUSSET_BK1RDY)
|
setEPSTATUSSET(0, sam.USB_DEVICE_EPSTATUSSET_BK1RDY)
|
||||||
|
|
||||||
// wait for transfer to complete
|
// wait for transfer to complete
|
||||||
|
timeout := 3000
|
||||||
for (getEPINTFLAG(0) & sam.USB_DEVICE_EPINTFLAG_TRCPT1) == 0 {
|
for (getEPINTFLAG(0) & sam.USB_DEVICE_EPINTFLAG_TRCPT1) == 0 {
|
||||||
|
timeout--
|
||||||
|
if timeout == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// last, set the device address to that requested by host
|
// last, set the device address to that requested by host
|
||||||
|
@ -1659,11 +1682,21 @@ func armRecvCtrlOUT(ep uint32) uint32 {
|
||||||
setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
|
setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
|
||||||
|
|
||||||
// Wait until OUT transfer is ready.
|
// Wait until OUT transfer is ready.
|
||||||
|
timeout := 3000
|
||||||
for (getEPSTATUS(ep) & sam.USB_DEVICE_EPSTATUS_BK0RDY) == 0 {
|
for (getEPSTATUS(ep) & sam.USB_DEVICE_EPSTATUS_BK0RDY) == 0 {
|
||||||
|
timeout--
|
||||||
|
if timeout == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until OUT transfer is completed.
|
// Wait until OUT transfer is completed.
|
||||||
|
timeout = 3000
|
||||||
for (getEPINTFLAG(ep) & sam.USB_DEVICE_EPINTFLAG_TRCPT0) == 0 {
|
for (getEPINTFLAG(ep) & sam.USB_DEVICE_EPINTFLAG_TRCPT0) == 0 {
|
||||||
|
timeout--
|
||||||
|
if timeout == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// return number of bytes received
|
// return number of bytes received
|
||||||
|
@ -1800,9 +1833,14 @@ func handleEndpoint(ep uint32) {
|
||||||
UART0.Receive(byte((udd_ep_out_cache_buffer[ep][i] & 0xFF)))
|
UART0.Receive(byte((udd_ep_out_cache_buffer[ep][i] & 0xFF)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set byte count to zero
|
||||||
|
usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
||||||
|
|
||||||
|
// set multi packet size to 64
|
||||||
|
usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits(64 << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
|
||||||
|
|
||||||
// set ready for next data
|
// set ready for next data
|
||||||
setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
|
setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendZlp(ep uint32) {
|
func sendZlp(ep uint32) {
|
||||||
|
|
|
@ -473,6 +473,9 @@ const (
|
||||||
usb_CDC_CS_INTERFACE = 0x24
|
usb_CDC_CS_INTERFACE = 0x24
|
||||||
usb_CDC_CS_ENDPOINT = 0x25
|
usb_CDC_CS_ENDPOINT = 0x25
|
||||||
usb_CDC_DATA_INTERFACE_CLASS = 0x0A
|
usb_CDC_DATA_INTERFACE_CLASS = 0x0A
|
||||||
|
|
||||||
|
usb_CDC_LINESTATE_DTR = 0x01
|
||||||
|
usb_CDC_LINESTATE_RTS = 0x02
|
||||||
)
|
)
|
||||||
|
|
||||||
// usbDeviceDescBank is the USB device endpoint descriptor.
|
// usbDeviceDescBank is the USB device endpoint descriptor.
|
||||||
|
|
5
targets/arduino-nano33.json
Обычный файл
5
targets/arduino-nano33.json
Обычный файл
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"inherits": ["atsamd21g18a"],
|
||||||
|
"build-tags": ["sam", "atsamd21g18a", "arduino_nano33"],
|
||||||
|
"flash": "bossac -d -i -e -w -v -R --offset=0x2000 {bin}"
|
||||||
|
}
|
Загрузка…
Создание таблицы
Сослаться в новой задаче