diff --git a/src/machine/usb_nrf52840.go b/src/machine/usb_nrf52840.go index c2ff3a14..e08146f7 100644 --- a/src/machine/usb_nrf52840.go +++ b/src/machine/usb_nrf52840.go @@ -384,12 +384,6 @@ func cdcSetup(setup usbSetup) bool { return false } -func checkShouldReset() { - if usbLineInfo.dwDTERate == 1200 && usbLineInfo.lineState&usb_CDC_LINESTATE_DTR == 0 { - // TODO: reset here - } -} - func sendUSBPacket(ep uint32, data []byte) { count := len(data) copy(udd_ep_in_cache_buffer[ep][:], data) diff --git a/src/machine/usb_nrf52840_reset_none.go b/src/machine/usb_nrf52840_reset_none.go new file mode 100644 index 00000000..08c615eb --- /dev/null +++ b/src/machine/usb_nrf52840_reset_none.go @@ -0,0 +1,6 @@ +// +build nrf52840,!nrf52840_reset_uf2 + +package machine + +func checkShouldReset() { +} diff --git a/src/machine/usb_nrf52840_reset_uf2.go b/src/machine/usb_nrf52840_reset_uf2.go new file mode 100644 index 00000000..e1d15cd5 --- /dev/null +++ b/src/machine/usb_nrf52840_reset_uf2.go @@ -0,0 +1,46 @@ +// +build nrf52840,nrf52840_reset_uf2 + +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 +// 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/targets/circuitplay-bluefruit.json b/targets/circuitplay-bluefruit.json index e948115b..2e94730d 100644 --- a/targets/circuitplay-bluefruit.json +++ b/targets/circuitplay-bluefruit.json @@ -1,6 +1,7 @@ { "inherits": ["nrf52840"], - "build-tags": ["circuitplay_bluefruit"], + "build-tags": ["circuitplay_bluefruit","nrf52840_reset_uf2"], + "flash-1200-bps-reset": "true", "flash-method": "msd", "msd-volume-name": "CPLAYBTBOOT", "msd-firmware-name": "firmware.uf2", diff --git a/targets/clue_alpha.json b/targets/clue_alpha.json index 6069cf09..5f396adb 100644 --- a/targets/clue_alpha.json +++ b/targets/clue_alpha.json @@ -1,6 +1,7 @@ { "inherits": ["nrf52840"], - "build-tags": ["clue_alpha"], + "build-tags": ["clue_alpha","nrf52840_reset_uf2"], + "flash-1200-bps-reset": "true", "flash-method": "msd", "msd-volume-name": "FTHR840BOOT", "msd-firmware-name": "firmware.uf2",