Merge pull request #623 from microbuilder/nrf52840

nRF52: [WIP] Feather52840 BSP and nRF52840 Serial Bootloader and
This commit is contained in:
Kevin Townsend 2018-02-15 22:29:46 +01:00 committed by GitHub
commit fb5f653442
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 10973 additions and 5 deletions

1
.gitignore vendored
View File

@ -7,6 +7,7 @@
*.bin
*.map
*.hex
!ports/nrf/**/bootloader/*.hex
*.dis
*.exe

View File

@ -35,8 +35,7 @@
#define BOOTLOADER_VERSION_REGISTER NRF_TIMER2->CC[0]
uint32_t bootloaderVersion = 0;
void board_init(void)
{
void board_init(void) {
// Retrieve bootloader version
bootloaderVersion = BOOTLOADER_VERSION_REGISTER;
}

View File

@ -0,0 +1,201 @@
# Setup
The `feather52840` board is currently based on the `PCA10056` development
board from Nordic Semiconductors, since commercial modules are not yet
available for the nRF52840.
The difference between the `pca10056` and `feather52840` board support
packages is that no bootloader is present on the `pca10056` (a HW debugger
like a Segger J-Link is required to flash firmware images), whereas the
`feather52840` package uses a serial bootloader, with a slightly different
flash layout to account for the bootloader's presence.
Both targets run on the same hardware and assume the same pinouts.
The `feather52840` board support package will be updated at a later date
to reflect any pin changes in the final Feather form-factor HW.
## Installing CircuitPython submodules
Before you can build, you will need to run the following commands once, which
will install the submodules that are part of the CircuitPython ecosystem, and
build the `mpy-cross` tool:
```
$ cd circuitpython
$ git submodule update --init
$ make -C mpy-cross
```
You then need to download the SD and Nordic SDK files via:
> This script relies on `wget`, which must be available from the command line.
```
$ cd ports/nrf
$ ./drivers/bluetooth/download_ble_stack.sh
```
## Installing the Serial Bootloader
The Adafruit nRF52840 Feather uses a serial bootloader that allows you to
update the core CircuitPython firmware and internal file system contents
using only a serial connection.
On empty devices, the serial bootloader will need to be flashed once using a
HW debugger such as a Segger J-Link before the serial updater (`nrfutil`) can
be used.
### Install `nrfjprog`
Before you can install the bootloader, you will first need to install the
`nrfjprog` tool from Nordic Semiconductors for your operating system. The
binary files can be downloaded via the following links:
- [nRF5x toolset tar for Linux 32-bit v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-Linux32/52619)
- [nRF5x toolset tar for Linux 64-bit v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-Linux64/51388)
- [nRF5x toolset tar for OSX v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-OSX/53406)
- [nRF5x toolset installer for Windows v9.7.2](http://www.nordicsemi.com/eng/nordic/Products/nRF52832/nRF5x-Command-Line-Tools-Win32/48768)
You will then need to add the `nrfjprog` folder to your system `PATH` variable
so that it is available from the command line. The exact process for this is
OS specific, but on a POSIX type system like OS X or Linux, you can
temporarily add the location to your `PATH` environment variables as follows:
```
$ export PATH=$PATH:YOURPATHHERE/nRF5x-Command-Line-Tools_9_7_2_OSX/nrfjprog/
```
You can test this by running the following command:
```
$ nrfjprog --version
nrfjprog version: 9.7.2
JLinkARM.dll version: 6.20f
```
### Flash the 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-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-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/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
causes a known conflict with reliable USB CDC serial port communication. In
order to use the serial bootloader, **you must disable MSD support on the
Segger J-Link**!
To disable mass storage support, run the `JLinkExe` (or equivalent) command,
and send `MSDDisable`. (You can re-enable MSD support via `MSDEnable`):
```
$ JLinkExe
SEGGER J-Link Commander V6.20f (Compiled Oct 13 2017 17:20:01)
DLL version V6.20f, compiled Oct 13 2017 17:19:52
Connecting to J-Link via USB...O.K.
Firmware: J-Link OB-SAM3U128-V2-NordicSemi compiled Jul 24 2017 17:30:12
Hardware version: V1.00
S/N: 683947110
VTref = 3.300V
Type "connect" to establish a target connection, '?' for help
J-Link>MSDDisable
Probe configured successfully.
J-Link>exit
```
## Building and Flashing CircuitPython
### Installing `nrfutil`
If you haven't installed the required command-line tool yet, go to the
`/libs/nrfutil` folder (where nrfutil 0.5.2b is installed as a sub-module)
and run the following commands:
> If you get a 'sudo: pip: command not found' error running 'sudo pip install',
you can install pip via 'sudo easy_install pip'
```
$ cd ../../lib/nrfutil
$ sudo pip install -r requirements.txt
$ sudo python setup.py install
```
#### Changes to `nrfutil` in 0.5.2b
**IMPORTANT**: Make sure that you have version **0.5.2b**, since a small
change was required to `dfu_transport_serial.py` to account for the
increased minimum flash erase time on the nRF52840 compared to the earlier
nRF52832!
You can also manually change the file with the following new values (lines
67-68), and reinstall the utility via `sudo python setup.py install`:
```
FLASH_PAGE_ERASE_MAX_TIME = 0.1 # Worst time to erase a page 100 ms
FLASH_PAGE_ERASE_MIN_TIME = 0.09 # Best time to erase a page 90 ms
```
### Flashing CircuitPython
With the serial bootloader present on your board, you first need to force your
board into DFU mode by holding down BUTTON1 and RESETTING the board (with
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
command:
```
$ make V=1 SD=s140 SERIAL=/dev/tty.usbmodem1411 BOARD=feather52840 dfu-gen dfu-flash
```
This should give you the following results:
```
$ make V=1 SD=s140 SERIAL=/dev/tty.usbmodem1411 BOARD=feather52840 dfu-gen dfu-flash
nrfutil dfu genpkg --sd-req 0xFFFE --dev-type 0x0052 --application build-feather52840-s140/firmware.hex build-feather52840-s140/dfu-package.zip
Zip created at build-feather52840-s140/dfu-package.zip
nrfutil --verbose dfu serial --package build-feather52840-s140/dfu-package.zip -p /dev/tty.usbmodem1411 -b 115200
Upgrading target on /dev/tty.usbmodem1411 with DFU package /Users/kevintownsend/Dropbox/microBuilder/Code/CircuitPython/circuitpython-mb/ports/nrf/build-feather52840-s140/dfu-package.zip. Flow control is disabled.
Starting DFU upgrade of type 4, SoftDevice size: 0, bootloader size: 0, application size: 195252
Sending DFU start packet
Sending DFU init packet
Sending firmware file
################################################################################################################################################################################################################################################################################################################################################################################################
Activating new firmware
DFU upgrade took 41.6610329151s
Device programmed.
```

View File

@ -0,0 +1,47 @@
/*
GNU linker script for NRF52840 w/S140 6.0.0 SoftDevice
MEMORY MAP
------------------------------------------------------------------------
START ADDR END ADDR SIZE DESCRIPTION
---------- ---------- ------- -----------------------------------------
0x000FF000..0x000FFFFF ( 4KB) Bootloader Settings
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
0x00025000..0x000B1FFF (564KB) Application Code (including ISR vector)
0x00001000..0x00024FFF (144KB) SoftDevice
0x00000000..0x00000FFF (4KB) Master Boot Record
*/
/* Specify the memory areas (S140 6.0.0) */
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
/* 0x2000000 - RAM:ORIGIN is reserved for Softdevice */
RAM (xrw) : ORIGIN = 0x20004000, LENGTH = 0x20040000 - 0x20004000
}
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_heap_size = 0;
/* top end of the stack */
/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/
_estack = ORIGIN(RAM) + LENGTH(RAM);
/* RAM extents for the garbage collector */
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
_heap_end = 0x20007000; /* tunable */
INCLUDE "boards/common.ld"

View File

@ -0,0 +1,44 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <string.h>
#include <stdbool.h>
#include "nrf.h"
#include "boards/board.h"
void board_init(void) {
}
bool board_requests_safe_mode(void) {
return false;
}
void reset_board(void) {
}

View File

@ -0,0 +1,87 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#define FEATHER52840
#define MICROPY_HW_BOARD_NAME "Feather52840"
#define MICROPY_HW_MCU_NAME "NRF52840"
#define MICROPY_PY_SYS_PLATFORM "nrf52840-PDK"
#define MICROPY_PY_MACHINE_HW_PWM (1)
#define MICROPY_PY_MACHINE_HW_SPI (1)
#define MICROPY_PY_MACHINE_TIMER (1)
#define MICROPY_PY_MACHINE_RTC (1)
#define MICROPY_PY_MACHINE_I2C (1)
#define MICROPY_PY_MACHINE_ADC (1)
#define MICROPY_PY_MACHINE_TEMP (1)
#define MICROPY_HW_HAS_LED (1)
#define MICROPY_HW_HAS_SWITCH (0)
#define MICROPY_HW_HAS_FLASH (0)
#define MICROPY_HW_HAS_SDCARD (0)
#define MICROPY_HW_HAS_MMA7660 (0)
#define MICROPY_HW_HAS_LIS3DSH (0)
#define MICROPY_HW_HAS_LCD (0)
#define MICROPY_HW_ENABLE_RNG (0)
#define MICROPY_HW_ENABLE_RTC (0)
#define MICROPY_HW_ENABLE_TIMER (0)
#define MICROPY_HW_ENABLE_SERVO (0)
#define MICROPY_HW_ENABLE_DAC (0)
#define MICROPY_HW_ENABLE_CAN (0)
#define MICROPY_HW_LED_COUNT (4)
#define MICROPY_HW_LED_PULLUP (1)
#define MICROPY_HW_LED1 (13) // LED1
#define MICROPY_HW_LED2 (14) // LED2
#define MICROPY_HW_LED3 (15) // LED3
#define MICROPY_HW_LED4 (16) // LED4
// UART config
#define MICROPY_HW_UART1_RX (pin_P0_08)
#define MICROPY_HW_UART1_TX (pin_P0_06)
#define MICROPY_HW_UART1_CTS (pin_P0_07)
#define MICROPY_HW_UART1_RTS (pin_P0_05)
#define MICROPY_HW_UART1_HWFC (1)
// SPI0 config
#define MICROPY_HW_SPI0_NAME "SPI0"
#define MICROPY_HW_SPI0_SCK (pin_P1_15)
#define MICROPY_HW_SPI0_MOSI (pin_P1_13)
#define MICROPY_HW_SPI0_MISO (pin_P1_14)
#define MICROPY_HW_PWM0_NAME "PWM0"
#define MICROPY_HW_PWM1_NAME "PWM1"
#define MICROPY_HW_PWM2_NAME "PWM2"
#if 0
#define MICROPY_HW_PWM3_NAME "PWM3"
#endif
#define HELP_TEXT_BOARD_LED "1,2,3,4"
#define PORT_HEAP_SIZE (128*1024)
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500

View File

@ -0,0 +1,4 @@
# This file is a placeholder to enable building with 'SD=s140' flag
# The actual config data is stored in the file referenced below, regardless
# of whether S140 is actively used or not.
include boards/$(BOARD)/mpconfigboard.mk

View File

@ -0,0 +1,35 @@
MCU_SERIES = m4
MCU_VARIANT = nrf52
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
NRF_DEFINES += -DNRF52840_XXAA
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)
endif
check_defined = \
$(strip $(foreach 1,$1, \
$(call __check_defined,$1,$(strip $(value 2)))))
__check_defined = \
$(if $(value $1),, \
$(error Undefined make flag: $1$(if $2, ($2))))
.PHONY: dfu-gen dfu-flash boot-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
boot-flash:
nrfjprog --program $(BOOTLOADER_FILENAME).hex -f nrf52 --chiperase --reset

View File

@ -0,0 +1,18 @@
#ifndef NRF52_HAL_CONF_H__
#define NRF52_HAL_CONF_H__
#define HAL_UART_MODULE_ENABLED
#define HAL_SPI_MODULE_ENABLED
#define HAL_TIME_MODULE_ENABLED
#define HAL_PWM_MODULE_ENABLED
#define HAL_RTC_MODULE_ENABLED
#define HAL_TIMER_MODULE_ENABLED
#define HAL_TWI_MODULE_ENABLED
#define HAL_ADCE_MODULE_ENABLED
#define HAL_TEMP_MODULE_ENABLED
#define HAL_RNG_MODULE_ENABLED
// #define HAL_UARTE_MODULE_ENABLED
// #define HAL_SPIE_MODULE_ENABLED
// #define HAL_TWIE_MODULE_ENABLED
#endif // NRF52_HAL_CONF_H__

View File

@ -0,0 +1,48 @@
P0_00,P0_00
P0_01,P0_01
P0_02,P0_02,ADC0_IN0
P0_03,P0_03,ADC0_IN1
P0_04,P0_04,ADC0_IN2
P0_05,P0_05,ADC0_IN3
P0_06,P0_06
P0_07,P0_07
P0_08,P0_08
P0_09,P0_09
P0_10,P0_10
P0_11,P0_11
P0_12,P0_12
P0_13,P0_13
P0_14,P0_14
P0_15,P0_15
P0_16,P0_16
P0_17,P0_17
P0_18,P0_18
P0_19,P0_19
P0_20,P0_20
P0_21,P0_21
P0_22,P0_22
P0_23,P0_23
P0_24,P0_24
P0_25,P0_25
P0_26,P0_26
P0_27,P0_27
P0_28,P0_28,ADC0_IN4
P0_29,P0_29,ADC0_IN5
P0_30,P0_30,ADC0_IN6
P0_31,P0_31,ADC0_IN7
P1_00,P1_00
P1_01,P1_01
P1_02,P1_02
P1_03,P1_03
P1_04,P1_04
P1_05,P1_05
P1_06,P1_06
P1_07,P1_07
P1_08,P1_08
P1_09,P1_09
P1_10,P1_10
P1_11,P1_11
P1_12,P1_12
P1_13,P1_13
P1_14,P1_14
P1_15,P1_15
1 P0_00,P0_00
2 P0_01,P0_01
3 P0_02,P0_02,ADC0_IN0
4 P0_03,P0_03,ADC0_IN1
5 P0_04,P0_04,ADC0_IN2
6 P0_05,P0_05,ADC0_IN3
7 P0_06,P0_06
8 P0_07,P0_07
9 P0_08,P0_08
10 P0_09,P0_09
11 P0_10,P0_10
12 P0_11,P0_11
13 P0_12,P0_12
14 P0_13,P0_13
15 P0_14,P0_14
16 P0_15,P0_15
17 P0_16,P0_16
18 P0_17,P0_17
19 P0_18,P0_18
20 P0_19,P0_19
21 P0_20,P0_20
22 P0_21,P0_21
23 P0_22,P0_22
24 P0_23,P0_23
25 P0_24,P0_24
26 P0_25,P0_25
27 P0_26,P0_26
28 P0_27,P0_27
29 P0_28,P0_28,ADC0_IN4
30 P0_29,P0_29,ADC0_IN5
31 P0_30,P0_30,ADC0_IN6
32 P0_31,P0_31,ADC0_IN7
33 P1_00,P1_00
34 P1_01,P1_01
35 P1_02,P1_02
36 P1_03,P1_03
37 P1_04,P1_04
38 P1_05,P1_05
39 P1_06,P1_06
40 P1_07,P1_07
41 P1_08,P1_08
42 P1_09,P1_09
43 P1_10,P1_10
44 P1_11,P1_11
45 P1_12,P1_12
46 P1_13,P1_13
47 P1_14,P1_14
48 P1_15,P1_15