machine/atsamd21: Add support for bootloader reset/programming and correct error in receiving endpoint 0 data for CDC Set Line Coding changes, implementing system reset on switch to 1200 baud connection speed with DTR false.
Signed-off-by: Ron Evans <ron@hybridgroup.com>
Этот коммит содержится в:
родитель
6c1abfe047
коммит
69aaea44a0
2 изменённых файлов: 46 добавлений и 40 удалений
|
@ -164,4 +164,8 @@ func SystemReset() {
|
||||||
// SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
|
// SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
|
||||||
// SCB_AIRCR_SYSRESETREQ_Msk);
|
// SCB_AIRCR_SYSRESETREQ_Msk);
|
||||||
SCB.AIRCR.Set((0x5FA << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk)
|
SCB.AIRCR.Set((0x5FA << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk)
|
||||||
|
|
||||||
|
for {
|
||||||
|
Asm("wfi")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1401,15 +1401,15 @@ func handleUSB() {
|
||||||
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
|
||||||
epFlags := getEPINTFLAG(i)
|
epFlags := getEPINTFLAG(i)
|
||||||
if epFlags > 0 {
|
if (epFlags&sam.USB_DEVICE_EPINTFLAG_TRCPT0) > 0 ||
|
||||||
|
(epFlags&sam.USB_DEVICE_EPINTFLAG_TRCPT1) > 0 {
|
||||||
switch i {
|
switch i {
|
||||||
case usb_CDC_ENDPOINT_OUT:
|
case usb_CDC_ENDPOINT_OUT:
|
||||||
if (epFlags & sam.USB_DEVICE_EPINTFLAG_TRCPT0) > 0 {
|
handleEndpoint(i)
|
||||||
handleEndpoint(i)
|
|
||||||
}
|
|
||||||
setEPINTFLAG(i, epFlags)
|
|
||||||
case usb_CDC_ENDPOINT_ACM:
|
|
||||||
setEPINTFLAG(i, epFlags)
|
setEPINTFLAG(i, epFlags)
|
||||||
|
case usb_CDC_ENDPOINT_IN, usb_CDC_ENDPOINT_ACM:
|
||||||
|
setEPSTATUSCLR(i, sam.USB_DEVICE_EPSTATUSCLR_BK1RDY)
|
||||||
|
setEPINTFLAG(i, sam.USB_DEVICE_EPINTFLAG_TRCPT1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1631,17 +1631,19 @@ func cdcSetup(setup usbSetup) bool {
|
||||||
|
|
||||||
if setup.bRequest == usb_CDC_SET_LINE_CODING || setup.bRequest == usb_CDC_SET_CONTROL_LINE_STATE {
|
if setup.bRequest == usb_CDC_SET_LINE_CODING || setup.bRequest == usb_CDC_SET_CONTROL_LINE_STATE {
|
||||||
// auto-reset into the bootloader
|
// auto-reset into the bootloader
|
||||||
if usbLineInfo.dwDTERate == 1200 && (usbLineInfo.lineState&0x01) == 0 {
|
if usbLineInfo.dwDTERate == 1200 && usbLineInfo.lineState&usb_CDC_LINESTATE_DTR == 0 {
|
||||||
// TODO: system reset
|
ResetProcessor()
|
||||||
} else {
|
} else {
|
||||||
// TODO: cancel any reset
|
// TODO: cancel any reset
|
||||||
}
|
}
|
||||||
|
sendZlp(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if setup.bRequest == usb_CDC_SEND_BREAK {
|
if setup.bRequest == usb_CDC_SEND_BREAK {
|
||||||
// TODO: something with this value?
|
// TODO: something with this value?
|
||||||
// breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
|
// breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
|
||||||
// return false;
|
// return false;
|
||||||
|
sendZlp(0)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -1662,53 +1664,41 @@ func sendUSBPacket(ep uint32, data []byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func receiveUSBControlPacket() []byte {
|
func receiveUSBControlPacket() []byte {
|
||||||
// set ready to receive data
|
// address
|
||||||
|
usbEndpointDescriptors[0].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[0]))))
|
||||||
|
|
||||||
|
// set byte count to zero
|
||||||
|
usbEndpointDescriptors[0].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
||||||
|
|
||||||
|
// set ready for next data
|
||||||
setEPSTATUSCLR(0, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
|
setEPSTATUSCLR(0, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
|
||||||
|
|
||||||
// read the data
|
|
||||||
bytesread := armRecvCtrlOUT(0)
|
|
||||||
|
|
||||||
// return the data
|
|
||||||
data := make([]byte, 0, bytesread)
|
|
||||||
copy(data, udd_ep_out_cache_buffer[0][:bytesread])
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
func armRecvCtrlOUT(ep uint32) uint32 {
|
|
||||||
// Set output address to receive data
|
|
||||||
usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
|
|
||||||
|
|
||||||
// set multi-packet size which is total expected number of bytes to receive.
|
|
||||||
usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits((8 << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos) |
|
|
||||||
uint32(epPacketSize(64)<<usb_DEVICE_PCKSIZE_SIZE_Pos))
|
|
||||||
|
|
||||||
// clear byte count of bytes received so far.
|
|
||||||
usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
|
||||||
|
|
||||||
// clear ready state to start transfer
|
|
||||||
setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
|
|
||||||
|
|
||||||
// Wait until OUT transfer is ready.
|
// Wait until OUT transfer is ready.
|
||||||
timeout := 3000
|
timeout := 3000
|
||||||
for (getEPSTATUS(ep) & sam.USB_DEVICE_EPSTATUS_BK0RDY) == 0 {
|
for (getEPSTATUS(0) & sam.USB_DEVICE_EPSTATUS_BK0RDY) == 0 {
|
||||||
timeout--
|
timeout--
|
||||||
if timeout == 0 {
|
if timeout == 0 {
|
||||||
return 0
|
return []byte{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until OUT transfer is completed.
|
// Wait until OUT transfer is completed.
|
||||||
timeout = 3000
|
timeout = 300000
|
||||||
for (getEPINTFLAG(ep) & sam.USB_DEVICE_EPINTFLAG_TRCPT0) == 0 {
|
for (getEPINTFLAG(0) & sam.USB_DEVICE_EPINTFLAG_TRCPT0) == 0 {
|
||||||
timeout--
|
timeout--
|
||||||
if timeout == 0 {
|
if timeout == 0 {
|
||||||
return 0
|
return []byte{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// return number of bytes received
|
// get data
|
||||||
return (usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.Get() >>
|
bytesread := uint32((usbEndpointDescriptors[0].DeviceDescBank[0].PCKSIZE.Get() >>
|
||||||
usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask
|
usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask)
|
||||||
|
|
||||||
|
data := make([]byte, bytesread)
|
||||||
|
copy(data, udd_ep_out_cache_buffer[0][:])
|
||||||
|
|
||||||
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendDescriptor creates and sends the various USB descriptor types that
|
// sendDescriptor creates and sends the various USB descriptor types that
|
||||||
|
@ -2083,3 +2073,15 @@ func setEPINTENSET(ep uint32, val uint8) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResetProcessor should perform a system reset in preperation
|
||||||
|
// to switch to the bootloader to flash new firmware.
|
||||||
|
func ResetProcessor() {
|
||||||
|
arm.DisableInterrupts()
|
||||||
|
|
||||||
|
// Perform magic reset into bootloader, as mentioned in
|
||||||
|
// https://github.com/arduino/ArduinoCore-samd/issues/197
|
||||||
|
*(*uint32)(unsafe.Pointer(uintptr(0x20007FFC))) = 0x07738135
|
||||||
|
|
||||||
|
arm.SystemReset()
|
||||||
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче