From fcefcb191cbce5e9d15f844581ddf6d28a7248a1 Mon Sep 17 00:00:00 2001 From: sago35 Date: Tue, 5 Jul 2022 22:28:13 +0900 Subject: [PATCH] samd21,samd51,nrf52840: unify bootloader entry process --- src/machine/machine_atsamd21.go | 4 +- src/machine/machine_atsamd21_usb.go | 2 +- src/machine/machine_atsamd51.go | 4 +- src/machine/machine_atsamd51_usb.go | 2 +- .../machine_nrf52840_enter_bootloader.go | 39 +++++++++++++++++ src/machine/machine_nrf52840_usb.go | 8 +++- .../machine_nrf52840_usb_reset_bossa.go | 23 ++-------- .../machine_nrf52840_usb_reset_none.go | 4 +- src/machine/machine_nrf52840_usb_reset_uf2.go | 43 ++----------------- 9 files changed, 60 insertions(+), 69 deletions(-) create mode 100644 src/machine/machine_nrf52840_enter_bootloader.go diff --git a/src/machine/machine_atsamd21.go b/src/machine/machine_atsamd21.go index 75b01422..01dc9a02 100644 --- a/src/machine/machine_atsamd21.go +++ b/src/machine/machine_atsamd21.go @@ -1734,9 +1734,9 @@ func (tcc *TCC) Set(channel uint8, value uint32) { } } -// ResetProcessor should perform a system reset in preperation +// EnterBootloader should perform a system reset in preperation // to switch to the bootloader to flash new firmware. -func ResetProcessor() { +func EnterBootloader() { arm.DisableInterrupts() // Perform magic reset into bootloader, as mentioned in diff --git a/src/machine/machine_atsamd21_usb.go b/src/machine/machine_atsamd21_usb.go index 117b0b10..e63f6124 100644 --- a/src/machine/machine_atsamd21_usb.go +++ b/src/machine/machine_atsamd21_usb.go @@ -583,7 +583,7 @@ func cdcSetup(setup usbSetup) bool { if setup.bRequest == usb_CDC_SET_LINE_CODING || setup.bRequest == usb_CDC_SET_CONTROL_LINE_STATE { // auto-reset into the bootloader if usbLineInfo.dwDTERate == 1200 && usbLineInfo.lineState&usb_CDC_LINESTATE_DTR == 0 { - ResetProcessor() + EnterBootloader() } else { // TODO: cancel any reset } diff --git a/src/machine/machine_atsamd51.go b/src/machine/machine_atsamd51.go index 4f296832..b2e261ab 100644 --- a/src/machine/machine_atsamd51.go +++ b/src/machine/machine_atsamd51.go @@ -1974,9 +1974,9 @@ func (tcc *TCC) Set(channel uint8, value uint32) { } } -// ResetProcessor should perform a system reset in preparation +// EnterBootloader should perform a system reset in preparation // to switch to the bootloader to flash new firmware. -func ResetProcessor() { +func EnterBootloader() { arm.DisableInterrupts() // Perform magic reset into bootloader, as mentioned in diff --git a/src/machine/machine_atsamd51_usb.go b/src/machine/machine_atsamd51_usb.go index b47ba024..36880287 100644 --- a/src/machine/machine_atsamd51_usb.go +++ b/src/machine/machine_atsamd51_usb.go @@ -586,7 +586,7 @@ func cdcSetup(setup usbSetup) bool { if setup.bRequest == usb_CDC_SET_LINE_CODING || setup.bRequest == usb_CDC_SET_CONTROL_LINE_STATE { // auto-reset into the bootloader if usbLineInfo.dwDTERate == 1200 && usbLineInfo.lineState&usb_CDC_LINESTATE_DTR == 0 { - ResetProcessor() + EnterBootloader() } else { // TODO: cancel any reset } diff --git a/src/machine/machine_nrf52840_enter_bootloader.go b/src/machine/machine_nrf52840_enter_bootloader.go new file mode 100644 index 00000000..283fea15 --- /dev/null +++ b/src/machine/machine_nrf52840_enter_bootloader.go @@ -0,0 +1,39 @@ +//go:build nrf52840 +// +build nrf52840 + +package machine + +import ( + "device/arm" + "device/nrf" +) + +const ( + DFU_MAGIC_SERIAL_ONLY_RESET = 0x4e + DFU_MAGIC_UF2_RESET = 0x57 + DFU_MAGIC_OTA_RESET = 0xA8 +) + +// EnterSerialBootloader resets the chip into the serial bootloader. After +// reset, it can be flashed using serial/nrfutil. +func EnterSerialBootloader() { + arm.DisableInterrupts() + nrf.POWER.GPREGRET.Set(DFU_MAGIC_SERIAL_ONLY_RESET) + arm.SystemReset() +} + +// EnterUF2Bootloader resets the chip into the UF2 bootloader. After reset, it +// can be flashed via nrfutil or by copying a UF2 file to the mass storage device +func EnterUF2Bootloader() { + arm.DisableInterrupts() + nrf.POWER.GPREGRET.Set(DFU_MAGIC_UF2_RESET) + arm.SystemReset() +} + +// EnterOTABootloader resets the chip into the bootloader so that it can be +// flashed via an OTA update +func EnterOTABootloader() { + arm.DisableInterrupts() + nrf.POWER.GPREGRET.Set(DFU_MAGIC_OTA_RESET) + arm.SystemReset() +} diff --git a/src/machine/machine_nrf52840_usb.go b/src/machine/machine_nrf52840_usb.go index 7260ac15..80c8653a 100644 --- a/src/machine/machine_nrf52840_usb.go +++ b/src/machine/machine_nrf52840_usb.go @@ -320,7 +320,9 @@ func (usbcdc *USBCDC) handleInterrupt(interrupt.Interrupt) { count := int(nrf.USBD.SIZE.EPOUT[0].Get()) if count >= 7 { parseUSBLineInfo(udd_ep_out_cache_buffer[0][:count]) - checkShouldReset() + if usbLineInfo.dwDTERate == 1200 && usbLineInfo.lineState&usb_CDC_LINESTATE_DTR == 0 { + EnterBootloader() + } } nrf.USBD.TASKS_EP0STATUS.Set(1) } @@ -484,7 +486,9 @@ func cdcSetup(setup usbSetup) bool { if setup.bRequest == usb_CDC_SET_CONTROL_LINE_STATE { usbLineInfo.lineState = setup.wValueL - checkShouldReset() + if usbLineInfo.dwDTERate == 1200 && usbLineInfo.lineState&usb_CDC_LINESTATE_DTR == 0 { + EnterBootloader() + } nrf.USBD.TASKS_EP0STATUS.Set(1) } diff --git a/src/machine/machine_nrf52840_usb_reset_bossa.go b/src/machine/machine_nrf52840_usb_reset_bossa.go index 1125696e..419ed043 100644 --- a/src/machine/machine_nrf52840_usb_reset_bossa.go +++ b/src/machine/machine_nrf52840_usb_reset_bossa.go @@ -3,25 +3,8 @@ package machine -import ( - "device/arm" - "device/nrf" -) - -const DFU_MAGIC_SERIAL_ONLY_RESET = 0xb0 - -// checkShouldReset is called by the USB-CDC implementation to check whether to -// reset into the bootloader/OTA and if so, resets the chip appropriately. -func checkShouldReset() { - if usbLineInfo.dwDTERate == 1200 && usbLineInfo.lineState&usb_CDC_LINESTATE_DTR == 0 { - EnterSerialBootloader() - } -} - -// EnterSerialBootloader resets the chip into the serial bootloader. After +// EnterBootloader resets the chip into the serial bootloader. After // reset, it can be flashed using serial/nrfutil. -func EnterSerialBootloader() { - arm.DisableInterrupts() - nrf.POWER.GPREGRET.Set(DFU_MAGIC_SERIAL_ONLY_RESET) - arm.SystemReset() +func EnterBootloader() { + EnterSerialBootloader() } diff --git a/src/machine/machine_nrf52840_usb_reset_none.go b/src/machine/machine_nrf52840_usb_reset_none.go index a7a99887..40928082 100644 --- a/src/machine/machine_nrf52840_usb_reset_none.go +++ b/src/machine/machine_nrf52840_usb_reset_none.go @@ -3,5 +3,7 @@ package machine -func checkShouldReset() { +// EnterBootloader resets the chip into the serial bootloader. +func EnterBootloader() { + // skip } diff --git a/src/machine/machine_nrf52840_usb_reset_uf2.go b/src/machine/machine_nrf52840_usb_reset_uf2.go index ec685529..e5a4a6b1 100644 --- a/src/machine/machine_nrf52840_usb_reset_uf2.go +++ b/src/machine/machine_nrf52840_usb_reset_uf2.go @@ -3,45 +3,8 @@ package machine -import ( - "device/arm" - "device/nrf" -) - -const ( - DFU_MAGIC_SERIAL_ONLY_RESET = 0x4e - DFU_MAGIC_UF2_RESET = 0x57 - DFU_MAGIC_OTA_RESET = 0xA8 -) - -// checkShouldReset is called by the USB-CDC implementation to check whether to -// reset into the bootloader/OTA and if so, resets the chip appropriately. -func checkShouldReset() { - if usbLineInfo.dwDTERate == 1200 && usbLineInfo.lineState&usb_CDC_LINESTATE_DTR == 0 { - EnterUF2Bootloader() - } -} - -// EnterSerialBootloader resets the chip into the serial bootloader. After -// reset, it can be flashed using serial/nrfutil. -func EnterSerialBootloader() { - arm.DisableInterrupts() - nrf.POWER.GPREGRET.Set(DFU_MAGIC_SERIAL_ONLY_RESET) - arm.SystemReset() -} - -// EnterUF2Bootloader resets the chip into the UF2 bootloader. After reset, it +// EnterBootloader resets the chip into the UF2 bootloader. After reset, it // can be flashed via nrfutil or by copying a UF2 file to the mass storage device -func EnterUF2Bootloader() { - arm.DisableInterrupts() - nrf.POWER.GPREGRET.Set(DFU_MAGIC_UF2_RESET) - arm.SystemReset() -} - -// EnterOTABootloader resets the chip into the bootloader so that it can be -// flashed via an OTA update -func EnterOTABootloader() { - arm.DisableInterrupts() - nrf.POWER.GPREGRET.Set(DFU_MAGIC_OTA_RESET) - arm.SystemReset() +func EnterBootloader() { + EnterUF2Bootloader() }