Merge pull request #934 from microbuilder/usbboot
[WIP] nRF52840 USB Bootloader
This commit is contained in:
commit
9fc0ec6af8
|
@ -7,7 +7,7 @@
|
|||
*.bin
|
||||
*.map
|
||||
*.hex
|
||||
!ports/nrf/**/bootloader/*.hex
|
||||
!ports/nrf/**/bootloader/**/*.hex
|
||||
*.dis
|
||||
*.exe
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit d48561b07386132b849d0125b0ff6a532d833d8b
|
||||
Subproject commit 9e7dfb28a5c6f3d7a19340971b32e0c2b4128ecf
|
|
@ -291,9 +291,22 @@ FLASHER ?=
|
|||
|
||||
ifeq ($(FLASHER),)
|
||||
|
||||
# Adafruit use bootloader that requires writing to its settting ( app valid = 0x0001, crc = 0x0000 )
|
||||
ifneq (,$(filter $(BOARD),feather52 feather52840))
|
||||
|
||||
flash: $(BUILD)/$(OUTPUT_FILENAME).hex
|
||||
nrfjprog --program $< --sectorerase -f $(MCU_VARIANT)
|
||||
nrfjprog --erasepage $(BOOT_SETTING_ADDR) -f $(MCU_VARIANT)
|
||||
nrfjprog --memwr $(BOOT_SETTING_ADDR) --val 0x00000001 -f $(MCU_VARIANT)
|
||||
nrfjprog --reset -f $(MCU_VARIANT)
|
||||
|
||||
else
|
||||
|
||||
flash: $(BUILD)/$(OUTPUT_FILENAME).hex
|
||||
nrfjprog --program $< --sectorerase -f $(MCU_VARIANT)
|
||||
nrfjprog --reset -f $(MCU_VARIANT)
|
||||
|
||||
endif
|
||||
|
||||
sd: $(BUILD)/$(OUTPUT_FILENAME).hex
|
||||
nrfjprog --eraseall -f $(MCU_VARIANT)
|
||||
|
|
|
@ -28,6 +28,20 @@ This is a port of CircuitPython to the Nordic Semiconductor nRF52 series of chip
|
|||
* nRF52840
|
||||
* [PCA10056](http://www.nordicsemi.com/eng/Products/nRF52840-Preview-DK)
|
||||
|
||||
## Board Specific Instructions
|
||||
|
||||
For board-specific instructions on building and flashing CircuitPython, see
|
||||
the following links:
|
||||
|
||||
> **NOTE**: These board specific readmes may be more up to date than the
|
||||
generic board-neutral documentation further down.
|
||||
|
||||
* Adafruit [Feather nRF52](boards/feather52/README.md): 512KB Flash, 64KB SRAM
|
||||
* Adafruit [Feather nRF52840](boards/feather52840/README.md): 1MB Flash, 256KB SRAM
|
||||
* Nordic PCA10056 see [Feather nRF52840](boards/feather52840/README.md)
|
||||
|
||||
For all other board targets, see the generic notes below.
|
||||
|
||||
## Compile and Flash
|
||||
|
||||
Prerequisite steps for building the nrf port:
|
||||
|
|
|
@ -6,6 +6,7 @@ SOFTDEV_VERSION ?= 2.0.1
|
|||
LD_FILE = boards/feather52/custom_nrf52832_dfu_app_$(SOFTDEV_VERSION).ld
|
||||
BOOTLOADER_PKG = boards/feather52/bootloader/feather52_bootloader_$(SOFTDEV_VERSION)_s132_single.zip
|
||||
|
||||
BOOT_SETTING_ADDR = 0x7F000
|
||||
NRF_DEFINES += -DNRF52832_XXAA
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
|
@ -31,12 +32,12 @@ __check_defined = \
|
|||
.PHONY: dfu-gen dfu-flash boot-flash
|
||||
|
||||
dfu-gen:
|
||||
$(NRFUTIL) dfu genpkg --dev-type 0x0052 --application $(BUILD)/$(OUTPUT_FILENAME).hex $(BUILD)/dfu-package.zip
|
||||
$(NRFUTIL) dfu genpkg --sd-req 0xFFFE --dev-type 0x0052 --application $(BUILD)/$(OUTPUT_FILENAME).hex $(BUILD)/dfu-package.zip
|
||||
|
||||
dfu-flash:
|
||||
@:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyUSB0)
|
||||
$(NRFUTIL) dfu serial --package $(BUILD)/dfu-package.zip -p $(SERIAL) -b 115200
|
||||
$(NRFUTIL) dfu serial --package $(BUILD)/dfu-package.zip -p $(SERIAL) -b 115200 --singlebank
|
||||
|
||||
boot-flash:
|
||||
dfu-bootloader:
|
||||
@:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyUSB0)
|
||||
$(NRFUTIL) dfu serial --package $(BOOTLOADER_PKG) -p $(SERIAL) -b 115200
|
||||
|
|
|
@ -74,7 +74,7 @@ nrfjprog version: 9.7.2
|
|||
JLinkARM.dll version: 6.20f
|
||||
```
|
||||
|
||||
### Flash the Bootloader with `nrfjprog`
|
||||
### Option 1 (nRF52832 or nRF52840): Flash the HW UART Bootloader with `nrfjprog`
|
||||
|
||||
> This operation only needs to be done once, and only on boards that don't
|
||||
already have the serial bootloader installed.
|
||||
|
@ -105,6 +105,37 @@ Run.
|
|||
From this point onward, you can now use a simple serial port for firmware
|
||||
updates.
|
||||
|
||||
### Option 2 (nRF52840): Flash the USB CDC Bootloader with 'nrfjprog'
|
||||
|
||||
> This operation only needs to be done once, and only on boards that don't
|
||||
already have the serial bootloader installed.
|
||||
|
||||
Once `nrfjprog` is installed and available in `PATH` you can flash your
|
||||
board with the serial bootloader via the following command:
|
||||
|
||||
```
|
||||
make SD=s140 BOARD=feather52840 boot-usb-flash
|
||||
```
|
||||
|
||||
This should give you the following (or very similar) output, and you will see
|
||||
a DFU blinky pattern on one of the board LEDs:
|
||||
|
||||
```
|
||||
$ make SD=s140 BOARD=feather52840 boot-usb-flash
|
||||
Use make V=1, make V=2 or set BUILD_VERBOSE similarly in your environment to increase build verbosity.
|
||||
nrfjprog --program boards/feather52840/bootloader/usb/feather52840_bootloader_6.0.0_s140_single.hex -f nrf52 --chiperase --reset
|
||||
Parsing hex file.
|
||||
Erasing user available code and UICR flash areas.
|
||||
Applying system reset.
|
||||
Checking that the area to write is not protected.
|
||||
Programing device.
|
||||
Applying system reset.
|
||||
Run.
|
||||
```
|
||||
|
||||
From this point onward, you can now use a simple serial port for firmware
|
||||
updates.
|
||||
|
||||
### IMPORTANT: Disable Mass Storage on PCA10056 J-Link
|
||||
|
||||
The J-Link firmware on the PCA10056 implement USB Mass Storage, but this
|
||||
|
@ -174,11 +205,11 @@ BUTTON1 still pressed as you come out of reset).
|
|||
This will give you a **fast blinky DFU pattern** to indicate you are in DFU
|
||||
mode.
|
||||
|
||||
At this point, you can build and flash a CircuitPython binary via the following
|
||||
At this point, you can **build and flash** a CircuitPython binary via the following
|
||||
command:
|
||||
|
||||
```
|
||||
$ make V=1 SD=s140 SERIAL=/dev/tty.usbmodem1411 BOARD=feather52840 dfu-gen dfu-flash
|
||||
$ make V=1 SD=s140 SERIAL=/dev/tty.usbmodem1411 BOARD=feather52840 all dfu-gen dfu-flash
|
||||
```
|
||||
|
||||
This should give you the following results:
|
||||
|
|
|
@ -9,12 +9,11 @@
|
|||
0x000FE000..0x000FEFFF ( 4KB) Master Boot Record Params
|
||||
0x000F4000..0x000FDFFF ( 40KB) Serial + OTA Bootloader
|
||||
|
||||
0x000F3000..0x000F3FFF ( 4KB ) Private Config Data (Bonding, Keys, etc.)
|
||||
0x000F2000..0x000F2FFF ( 4KB ) User NVM data
|
||||
0x000B2000..0x000F1FFF (256KB) User Filesystem
|
||||
0x000ED000..0x000F3FFF (28KB ) Private Config Data (Bonding, Keys, etc.)
|
||||
0x000AD000..0x000ECFFF (256KB) User Filesystem
|
||||
|
||||
0x00025000..0x000B1FFF (564KB) Application Code (including ISR vector)
|
||||
0x00001000..0x00024FFF (144KB) SoftDevice
|
||||
0x00026000..0x000ACFFF (540KB) Application Code (including ISR vector)
|
||||
0x00001000..0x00025FFF (148KB) SoftDevice
|
||||
0x00000000..0x00000FFF (4KB) Master Boot Record
|
||||
*/
|
||||
|
||||
|
@ -23,9 +22,9 @@ MEMORY
|
|||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000
|
||||
|
||||
FLASH_ISR (rx) : ORIGIN = 0x00025000, LENGTH = 0x001000
|
||||
FLASH_TEXT (rx) : ORIGIN = 0x00026000, LENGTH = 0x08C000
|
||||
FLASH_FATFS (r) : ORIGIN = 0x000B2000, LENGTH = 0x040000
|
||||
FLASH_ISR (rx) : ORIGIN = 0x00026000, LENGTH = 0x001000
|
||||
FLASH_TEXT (rx) : ORIGIN = 0x00027000, LENGTH = 0x086000
|
||||
FLASH_FATFS (r) : ORIGIN = 0x000AD000, LENGTH = 0x040000
|
||||
|
||||
/* 0x2000000 - RAM:ORIGIN is reserved for Softdevice */
|
||||
RAM (xrw) : ORIGIN = 0x20004000, LENGTH = 0x20040000 - 0x20004000
|
||||
|
@ -42,6 +41,6 @@ _estack = ORIGIN(RAM) + LENGTH(RAM);
|
|||
|
||||
/* RAM extents for the garbage collector */
|
||||
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
|
||||
_heap_end = 0x20007000; /* tunable */
|
||||
_heap_end = 0x20020000; /* tunable */
|
||||
|
||||
INCLUDE "boards/common.ld"
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -28,7 +28,7 @@
|
|||
|
||||
#define MICROPY_HW_BOARD_NAME "Feather52840"
|
||||
#define MICROPY_HW_MCU_NAME "NRF52840"
|
||||
#define MICROPY_PY_SYS_PLATFORM "nrf52840-PDK"
|
||||
#define MICROPY_PY_SYS_PLATFORM "nrf52840"
|
||||
|
||||
#define MICROPY_PY_MACHINE_HW_PWM (1)
|
||||
#define MICROPY_PY_MACHINE_HW_SPI (1)
|
||||
|
|
|
@ -4,8 +4,10 @@ MCU_SUB_VARIANT = nrf52840
|
|||
SOFTDEV_VERSION ?= 6.0.0-6.alpha
|
||||
|
||||
LD_FILE = boards/feather52840/bluefruit_nrf52840_s140_6.0.0.ld
|
||||
BOOTLOADER_FILENAME = boards/feather52840/bootloader/feather52840_bootloader_6.0.0_s140_single
|
||||
BOOT_UART_FILE = boards/feather52840/bootloader/uart/feather52840_bootloader_6.0.0_s140_single
|
||||
BOOT_USB_FILE = boards/feather52840/bootloader/usb/feather52840_bootloader_6.0.0_s140_single
|
||||
|
||||
BOOT_SETTING_ADDR = 0xFF000
|
||||
NRF_DEFINES += -DNRF52840_XXAA
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
|
@ -17,8 +19,8 @@ endif
|
|||
CFLAGS += -DADAFRUIT_FEATHER52840
|
||||
|
||||
ifeq ($(SD), )
|
||||
INC += -Idrivers/bluetooth/s140_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/s140_$(MCU_SUB_VARIANT)_$(SOFTDEV_VERSION)_API/include
|
||||
INC += -Idrivers/bluetooth/s140_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/s140_$(MCU_SUB_VARIANT)_$(SOFTDEV_VERSION)_API/include/$(MCU_VARIANT)
|
||||
INC += -Idrivers/bluetooth/s140_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/s140_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include
|
||||
INC += -Idrivers/bluetooth/s140_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/s140_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include/$(MCU_VARIANT)
|
||||
endif
|
||||
|
||||
check_defined = \
|
||||
|
@ -28,14 +30,18 @@ __check_defined = \
|
|||
$(if $(value $1),, \
|
||||
$(error Undefined make flag: $1$(if $2, ($2))))
|
||||
|
||||
.PHONY: dfu-gen dfu-flash boot-flash
|
||||
.PHONY: dfu-gen dfu-flash boot-flash boot-usb-flash
|
||||
|
||||
dfu-gen:
|
||||
$(NRFUTIL) dfu genpkg --sd-req 0xFFFE --dev-type 0x0052 --application $(BUILD)/$(OUTPUT_FILENAME).hex $(BUILD)/dfu-package.zip
|
||||
|
||||
dfu-flash:
|
||||
@:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyUSB0)
|
||||
$(NRFUTIL) --verbose dfu serial --package $(BUILD)/dfu-package.zip -p $(SERIAL) -b 115200
|
||||
@:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0)
|
||||
$(NRFUTIL) --verbose dfu serial --package $(BUILD)/dfu-package.zip -p $(SERIAL) -b 115200 --singlebank
|
||||
|
||||
boot-flash:
|
||||
nrfjprog --program $(BOOTLOADER_FILENAME).hex -f nrf52 --chiperase --reset
|
||||
dfu-bootloader:
|
||||
@:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0)
|
||||
$(NRFUTIL) --verbose dfu serial --package $(BOOT_USB_FILE).zip -p $(SERIAL) -b 115200
|
||||
|
||||
bootloader:
|
||||
nrfjprog --program $(BOOT_USB_FILE).hex -f nrf52 --chiperase --reset
|
|
@ -8,7 +8,11 @@ else ifeq ($(SOFTDEV_VERSION), 5.0.0)
|
|||
CFLAGS += -DBLE_API_VERSION=4
|
||||
endif
|
||||
else ifeq ($(SD), s140)
|
||||
SOFTDEV_VERSION_LONG = $(SD)_$(MCU_SUB_VARIANT)_$(SOFTDEV_VERSION)
|
||||
ifeq ($(SOFTDEV_VERSION), 6.0.0-6.alpha)
|
||||
SOFTDEV_VERSION_LONG = $(SD)_$(MCU_SUB_VARIANT)_$(SOFTDEV_VERSION)
|
||||
else
|
||||
SOFTDEV_VERSION_LONG = $(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)
|
||||
endif
|
||||
|
||||
CFLAGS += -DBLUETOOTH_SD=140
|
||||
CFLAGS += -DBLE_API_VERSION=4
|
||||
|
|
|
@ -53,6 +53,24 @@ function download_s140_nrf52_6_0_0_6_alpha
|
|||
cd -
|
||||
}
|
||||
|
||||
function download_s140_nrf52_6_0_0
|
||||
{
|
||||
echo ""
|
||||
echo "####################################"
|
||||
echo "### Downloading s140_nrf52_6.0.0 ###"
|
||||
echo "####################################"
|
||||
echo ""
|
||||
|
||||
mkdir -p "${1}/s140_nrf52_6.0.0"
|
||||
cd "${1}/s140_nrf52_6.0.0"
|
||||
|
||||
wget https://www.nordicsemi.com/eng/nordic/download_resource/60624/19/10544096/116072
|
||||
mv 116072 temp.zip
|
||||
unzip -u temp.zip
|
||||
rm temp.zip
|
||||
cd -
|
||||
}
|
||||
|
||||
SCRIPT_DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
|
@ -60,6 +78,7 @@ if [ $# -eq 0 ]; then
|
|||
download_s132_nrf52_2_0_1 "${SCRIPT_DIR}"
|
||||
download_s132_nrf52_5_0_0 "${SCRIPT_DIR}"
|
||||
download_s140_nrf52_6_0_0_6_alpha "${SCRIPT_DIR}"
|
||||
download_s140_nrf52_6_0_0 "${SCRIPT_DIR}"
|
||||
else
|
||||
case $1 in
|
||||
"s132_nrf52_2_0_1" )
|
||||
|
@ -68,6 +87,8 @@ else
|
|||
download_s132_nrf52_5_0_0 "${SCRIPT_DIR}" ;;
|
||||
"s140_nrf52_6_0_0_6_alpha" )
|
||||
download_s140_nrf52_6_0_0_6_alpha "${SCRIPT_DIR}" ;;
|
||||
"s140_nrf52_6_0_0" )
|
||||
download_s140_nrf52_6_0_0 "${SCRIPT_DIR}" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ int hal_uart_available(NRF_UART_Type * p_instance)
|
|||
|
||||
void hal_uart_init(NRF_UART_Type * p_instance, hal_uart_init_t const * p_uart_init) {
|
||||
hal_gpio_cfg_pin(p_uart_init->tx_pin->port, p_uart_init->tx_pin->pin, HAL_GPIO_MODE_OUTPUT, HAL_GPIO_PULL_DISABLED);
|
||||
hal_gpio_cfg_pin(p_uart_init->tx_pin->port, p_uart_init->rx_pin->pin, HAL_GPIO_MODE_INPUT, HAL_GPIO_PULL_DISABLED);
|
||||
hal_gpio_cfg_pin(p_uart_init->rx_pin->port, p_uart_init->rx_pin->pin, HAL_GPIO_MODE_INPUT, HAL_GPIO_PULL_DISABLED);
|
||||
|
||||
hal_gpio_pin_clear(p_uart_init->tx_pin->port, p_uart_init->tx_pin->pin);
|
||||
|
||||
|
@ -156,6 +156,10 @@ void hal_uart_init(NRF_UART_Type * p_instance, hal_uart_init_t const * p_uart_in
|
|||
NVIC_EnableIRQ(p_uart_init->irq_num);
|
||||
}
|
||||
|
||||
bool hal_uart_inited(NRF_UART_Type * p_instance)
|
||||
{
|
||||
return !(p_instance->PSELTXD & (1 << 31)) && !(p_instance->PSELRXD & (1 << 31));
|
||||
}
|
||||
|
||||
void UARTE0_UART0_IRQHandler(void)
|
||||
{
|
||||
|
|
|
@ -117,6 +117,7 @@ typedef struct
|
|||
typedef void (*uart_complete_cb)(void);
|
||||
|
||||
void hal_uart_init(NRF_UART_Type * p_instance, hal_uart_init_t const * p_uart_init);
|
||||
bool hal_uart_inited(NRF_UART_Type * p_instance);
|
||||
|
||||
hal_uart_error_t hal_uart_char_write(NRF_UART_Type * p_instance, uint8_t ch);
|
||||
|
||||
|
|
|
@ -331,6 +331,6 @@ extern const struct _mp_obj_module_t ble_module;
|
|||
#include <alloca.h>
|
||||
|
||||
#define MICROPY_PIN_DEFS_PORT_H "pin_defs_nrf5.h"
|
||||
//#define CIRCUITPY_BOOT_OUTPUT_FILE "/boot_out.txt"
|
||||
#define CIRCUITPY_BOOT_OUTPUT_FILE "/boot_out.txt"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -65,9 +65,23 @@ bool mp_hal_stdin_any(void) {
|
|||
}
|
||||
|
||||
void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
|
||||
while(len--) {
|
||||
hal_uart_char_write(UART_INSTANCE, *str++);
|
||||
}
|
||||
|
||||
// #ifdef MICROPY_HW_LED_TX
|
||||
// gpio_toggle_pin_level(MICROPY_HW_LED_TX);
|
||||
// #endif
|
||||
//
|
||||
// #ifdef CIRCUITPY_BOOT_OUTPUT_FILE
|
||||
// if (boot_output_file != NULL) {
|
||||
// UINT bytes_written = 0;
|
||||
// f_write(boot_output_file, str, len, &bytes_written);
|
||||
// }
|
||||
// #endif
|
||||
|
||||
if ( hal_uart_inited(UART_INSTANCE) ) {
|
||||
while(len--) {
|
||||
hal_uart_char_write(UART_INSTANCE, *str++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mp_hal_stdout_tx_strn_cooked(const char *str, mp_uint_t len) {
|
||||
|
|
|
@ -49,8 +49,13 @@ void serial_init(void) {
|
|||
.id = 0,
|
||||
.rx_pin = &MICROPY_HW_UART1_RX,
|
||||
.tx_pin = &MICROPY_HW_UART1_TX,
|
||||
#if MICROPY_HW_UART1_HWFC
|
||||
.rts_pin = &MICROPY_HW_UART1_RTS,
|
||||
.cts_pin = &MICROPY_HW_UART1_CTS,
|
||||
#else
|
||||
.rts_pin = NULL,
|
||||
.cts_pin = NULL,
|
||||
#endif
|
||||
.flow_control = MICROPY_HW_UART1_HWFC ? true : false,
|
||||
.use_parity = false,
|
||||
.baud_rate = HAL_UART_BAUD_115K2,
|
||||
|
|
Loading…
Reference in New Issue