Compare commits

...
47 Commits
Author SHA1 Message Date
Ha Thach 2e6c877d1b Merge pull request #320 from adafruit/sense-tft
add & enable DISPLAY_VSENSOR_PIN if available (required for sense tft)
2024-01-29 17:03:31 +07:00
hathach 59df4f9e8c add & enable DISPLAY_VSENSOR_PIN if available (required for sense tft) 2024-01-29 16:41:46 +07:00
Limor "Ladyada" Fried 64d8e34567 Merge pull request #319 from adafruit/add-slash-screen
Add slash screen
2024-01-05 13:35:38 -05:00
hathach 3d920bf62b - add slash screen for CLUE
- optimize ST77XX_SWRESET, skip if reset pin is available.
2024-01-05 19:06:01 +07:00
hathach ed9bf7a8dd fix ci 2024-01-05 17:25:53 +07:00
hathach 0eead42aec add display for sense tft 2024-01-05 16:59:16 +07:00
hathach a6a8962b1d get slash screen running 2024-01-05 16:46:02 +07:00
hathach 79add7baf5 - add screen/display support for st77xx
- able to make spi transfer, but data seem to be off
2024-01-05 15:49:27 +07:00
Ha Thach 101a54da10 Merge pull request #318 from adafruit/rename-feather-sense-tft
rename to feather sense tft
2024-01-04 18:29:02 +07:00
hathach e81391f395 rename to feather sense tft 2024-01-04 18:23:51 +07:00
Ha Thach eaaf5f8e84 Merge pull request #317 from adafruit/add-feather-tft
Add feather tft
2024-01-03 22:29:26 +07:00
hathach 1c85a7a5be try to install setuptools for linkermap 2024-01-03 22:21:29 +07:00
hathach f5a1947974 add feather tft to ci build 2024-01-03 22:13:28 +07:00
hathach 66db5aeda3 add support for NEOPIXEL_POWER_PIN, also change code style 2024-01-03 22:12:13 +07:00
hathach 36a1f428dd add feather nrf52840 tft 2024-01-03 22:10:22 +07:00
Ha Thach 7210c3914d Merge pull request #309 from markbirss/master
Adds support for the Makerdiary nRF52840 Connect Kit board
2023-08-01 20:51:33 +07:00
Mark Trevor Birss 8b8c9d58be Update board.h 2023-08-01 15:44:15 +02:00
Mark Trevor Birss 39da39544b Update githubci.yml 2023-07-21 12:58:07 +02:00
Mark Trevor Birss 386ed04058 Update githubci.yml add Makerdiary nrf52840 connectkit 2023-07-21 10:37:04 +02:00
Mark Trevor Birss c87ea51b86 Update board.h
changes requested to board-id
2023-07-20 17:28:03 +02:00
Ha Thach 9924e54654 Merge pull request #310 from adafruit/add-cmake
Add cmake build for nrf52840
2023-07-20 22:12:12 +07:00
hathach 2de2fbf82f add PR template 2023-07-20 22:06:28 +07:00
hathach dbc7648649 add linker --print-memory-usage 2023-07-20 22:00:29 +07:00
hathach ffa2379818 add cmake support, starting with feather nrf52840 and pca10056. Seems to work well 2023-07-20 21:07:49 +07:00
Mark Trevor Birss aebee3dfd4 Add files via upload 2023-07-20 09:46:00 +02:00
Ha Thach 277a0c83f4 Merge pull request #305 from hyx0329/pr-m60-fix
Fix M60
2023-05-26 14:39:17 +07:00
hyx0329 e34b183f1d Fix support for M60 keyboard
- Change BUTTON_2 to ESC and setup related pins properly
- Always enable the battery
2023-05-25 17:56:05 +08:00
hyx0329 188e25948b Add board_init2 and board_teardown2
This also replace `board_init_extra`.
2023-05-25 17:52:02 +08:00
Ha Thach 80c3a8401b Merge pull request #293 from Montvydas/bugfix-ota-dfu-stuck
Set the default max MTU size within the DFU transport to 23
2023-02-27 14:35:00 +07:00
montea 5f95de1314 Set MTU to 23 within main.c file as per request on the comment above it 2023-02-13 10:46:51 +00:00
montea a980696dd0 Changed the default max MTU size within the DFU transport to 23, which is the required size for the legacy bootloader to perform a successful OTA with the latest Nordic-DFU-Library. 2023-02-12 18:51:21 +00:00
Ha Thach 2107d4e97f Merge pull request #291 from aovestdipaperino/master
Add support for XIAO BLE Sense boards
2023-02-08 09:00:40 +07:00
Paperinik 1bca78c0c8 Update githubci.yml
Added:
-xiao_nrf52840_ble
-xiao_nrf52840_ble_sense
2023-02-05 18:27:02 -08:00
Paperinik d7494e81ce Update board.h 2023-02-05 18:24:19 -08:00
Paperinik aac573642b Update board.h
UF2 board ID updated to specs.
2023-02-05 18:23:35 -08:00
Paperino cf3f39f576 Add support for Xiao BLE boards 2023-01-26 17:37:43 -08:00
Paperino 99ad4d5c0f Add support for xiao ble nrf52840 based boards. 2023-01-26 17:37:18 -08:00
Ha Thach da70d4a6ab Merge pull request #284 from kylemccreery/pillbug
Add new board PillBug
2022-11-18 17:33:10 +07:00
Kyle McCreery 4f908f3330 Initial commit of reformatted pillbug defines 2022-11-09 23:24:49 -05:00
Ha Thach b55f516c11 Merge pull request #281 from adafruit/update-doc
update readme doc
2022-10-16 20:06:08 +07:00
hathach d2977b16c8 update readme doc 2022-10-16 19:24:08 +07:00
Ha Thach 0cb582d10c Merge pull request #280 from adafruit/add-debug-build
Add debug build
2022-10-16 16:24:58 +07:00
Ha Thach 7229caf9d6 Merge branch 'master' into add-debug-build 2022-10-16 13:13:54 +07:00
hathach 3af7f744b4 add temp flash-skip-crc target 2022-10-16 13:09:19 +07:00
Ha Thach de32e8cf0a Merge pull request #273 from whiz00/build-fix
fix 'array subscript 0 is outside array bounds' for newer gcc versions
2022-09-08 17:49:27 +07:00
Gabriel Hansson 5217eb6dbc fix error: array subscript 0 is outside array bounds for newer gcc versions 2022-08-29 18:29:21 +00:00
hathach c42dce080c add debug linker when building with DEBUG=1
extend bootloader start to reserved app for debug build
2022-07-14 12:28:02 +07:00
45 changed files with 2256 additions and 374 deletions

No files matched your search

+18
View File
@@ -0,0 +1,18 @@
## Checklist
*By completing this PR sufficiently, you help us to review this Pull Request quicker and also help improve the quality of Release Notes*
- [ ] Please provide specific title of the PR describing the change
- [ ] Please provide related links (*eg. Issue which will be closed by this Pull Request*)
- [ ] If you are adding an new boards, please make sure
- [ ] Provide link to your allocated VID/PID if applicable
- [ ] Add your board to [action ci](/.github/workflows) in correct workflow and alphabet order for release binary
- [ ] `UF2_BOARD_ID` in your board.h follow correct format from [uf2 specs](https://github.com/microsoft/uf2#files-exposed-by-bootloaders)
*This checklist items that are not applicable to your PR can be deleted.*
-----------
## Description of Change
Please describe your proposed Pull Request and it's impact.
+8 -4
View File
@@ -22,6 +22,7 @@ jobs:
- 'feather_nrf52833_express'
- 'feather_nrf52840_express'
- 'feather_nrf52840_sense'
- 'feather_nrf52840_sense_tft'
- 'itsybitsy_nrf52840_express'
- 'metro_nrf52840_express'
- 'ledglasses_nrf52840'
@@ -45,6 +46,7 @@ jobs:
- 'mikoto'
- 'nice_nano'
- 'nrf52840_bboard'
- 'nRF52840_connect_kit'
- 'nrf52840_m2'
- 'ohs2020_badge'
- 'particle_argon'
@@ -58,19 +60,21 @@ jobs:
- 'raytac_mdbt50q_rx'
- 'sparkfun_nrf52840_micromod'
- 'waveshare_nrf52840_eval'
- 'xiao_nrf52840_ble'
- 'xiao_nrf52840_ble_sense'
steps:
- name: Setup Python
uses: actions/setup-python@v3
- name: Checkout Code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true
- name: Checkout linkermap
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
repository: hathach/linkermap
path: linkermap
@@ -82,7 +86,7 @@ jobs:
- name: Install Tools
run: |
pip3 install adafruit-nrfutil uritemplate requests intelhex
pip3 install adafruit-nrfutil uritemplate requests intelhex setuptools
pip3 install linkermap/
- name: Build
+340
View File
@@ -0,0 +1,340 @@
cmake_minimum_required(VERSION 3.17)
find_package(Python COMPONENTS Interpreter)
if (NOT DEFINED BOARD)
message(FATAL_ERROR "BOARD is not defined")
endif ()
if (NOT DEFINED TOOLCHAIN)
set(TOOLCHAIN gcc)
endif ()
# include board specific
include(${CMAKE_CURRENT_LIST_DIR}/src/boards/${BOARD}/board.cmake)
# toolchain set up
if (MCU_VARIANT STREQUAL "nrf5340_application")
set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor")
set(JLINK_DEVICE nrf5340_xxaa_app)
else ()
set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor")
set(JLINK_DEVICE ${MCU_VARIANT}_xxaa)
endif ()
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
project(Adafruit_nRF52_Bootloader C ASM)
set(NRFX ${CMAKE_CURRENT_LIST_DIR}/lib/nrfx)
set(SDK11 ${CMAKE_CURRENT_LIST_DIR}/lib/sdk11/components)
set(SDK ${CMAKE_CURRENT_LIST_DIR}/lib/sdk/components)
set(SOFTDEVICE ${CMAKE_CURRENT_LIST_DIR}/lib/softdevice)
set(TUSB ${CMAKE_CURRENT_LIST_DIR}/lib/tinyusb/src)
set(UF2CONV_PY ${CMAKE_CURRENT_LIST_DIR}/lib/uf2/utils/uf2conv.py)
set(UF2_FAMILY_ID_BOOTLOADER 0xd663823c)
#-------------------
# Bootloader
#-------------------
set(CMAKE_EXECUTABLE_SUFFIX .elf)
add_executable(bootloader)
# SD_VERSION can be overwritten by board.cmake
if(NOT DEFINED SD_VERSION)
set(SD_VERSION 6.1.1)
endif ()
set(MBR_HEX ${SOFTDEVICE}/mbr/hex/mbr_nrf52_2.4.1_mbr.hex)
target_sources(bootloader PUBLIC
# src
src/dfu_ble_svc.c
src/dfu_init.c
src/flash_nrf5x.c
src/main.c
src/screen.c
src/images.c
src/boards/boards.c
# nrfx
${NRFX}/drivers/src/nrfx_power.c
${NRFX}/drivers/src/nrfx_nvmc.c
${NRFX}/mdk/system_${MCU_VARIANT}.c
# sdk 11
${SDK11}/libraries/bootloader_dfu/bootloader.c
${SDK11}/libraries/bootloader_dfu/bootloader_settings.c
${SDK11}/libraries/bootloader_dfu/bootloader_util.c
${SDK11}/libraries/bootloader_dfu/dfu_transport_serial.c
${SDK11}/libraries/bootloader_dfu/dfu_transport_ble.c
${SDK11}/libraries/bootloader_dfu/dfu_single_bank.c
${SDK11}/ble/ble_services/ble_dfu/ble_dfu.c
${SDK11}/ble/ble_services/ble_dis/ble_dis.c
${SDK11}/drivers_nrf/pstorage/pstorage_raw.c
# latest sdk
${SDK}/libraries/timer/app_timer.c
${SDK}/libraries/scheduler/app_scheduler.c
${SDK}/libraries/util/app_error.c
${SDK}/libraries/util/app_util_platform.c
${SDK}/libraries/crc16/crc16.c
${SDK}/libraries/hci/hci_mem_pool.c
${SDK}/libraries/hci/hci_slip.c
${SDK}/libraries/hci/hci_transport.c
${SDK}/libraries/util/nrf_assert.c
# ASM
${NRFX}/mdk/gcc_startup_${MCU_VARIANT}.S
)
target_include_directories(bootloader PUBLIC
src
src/boards
src/boards/${BOARD}
src/cmsis/include
src/usb
${TUSB}
# nrfx
${NRFX}
${NRFX}/mdk
${NRFX}/hal
${NRFX}/drivers/include
${NRFX}/drivers/src
# sdk 11 for cdc/ble dfu
${SDK11}/libraries/bootloader_dfu
${SDK11}/libraries/bootloader_dfu/hci_transport
${SDK11}/drivers_nrf/pstorage
${SDK11}/ble/common
${SDK11}/ble/ble_services/ble_dfu
${SDK11}/ble/ble_services/ble_dis
# later sdk with updated drivers
${SDK}/libraries/timer
${SDK}/libraries/scheduler
${SDK}/libraries/crc16
${SDK}/libraries/util
${SDK}/libraries/hci/config
${SDK}/libraries/hci
${SDK}/libraries/uart
${SDK}/drivers_nrf/delay
# Softdevice
${SOFTDEVICE}/mbr/headers
)
# Debug option
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
# TODO not work yet, also need to add segger rtt, DFU_APP_DATA_RESERVED=0, BOOTLOADER_REGION_START=0xED000
set(LD_FILE ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT}_debug.ld)
target_sources(bootloader PUBLIC
lib/SEGGER_RTT/RTT/SEGGER_RTT.c
)
target_include_directories(bootloader PUBLIC
lib/SEGGER_RTT/RTT
)
target_compile_definitions(bootloader PUBLIC
CFG_DEBUG
SEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
DFU_APP_DATA_RESERVED=0
)
if (MCU_VARIANT STREQUAL "nrf52840")
target_compile_definitions(bootloader PUBLIC BOOTLOADER_REGION_START=0xEA000)
else ()
target_compile_definitions(bootloader PUBLIC BOOTLOADER_REGION_START=0x6D000)
endif ()
else ()
set(LD_FILE ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT}.ld)
endif ()
target_link_options(bootloader PUBLIC
"LINKER:--script=${LD_FILE}"
-L${NRFX}/mdk
--specs=nosys.specs --specs=nano.specs
)
target_compile_options(bootloader PUBLIC
-fno-builtin
-fshort-enums
-fstack-usage
-fno-strict-aliasing
-Wall
-Wextra
-Werror
-Wfatal-errors
-Werror-implicit-function-declaration
-Wfloat-equal
-Wundef
-Wshadow
-Wwrite-strings
-Wsign-compare
-Wmissing-format-attribute
-Wno-endif-labels
-Wunreachable-code
# Suppress warning caused by SDK
-Wno-unused-parameter -Wno-expansion-to-defined
)
target_compile_definitions(bootloader PUBLIC
SOFTDEVICE_PRESENT
)
if (TRACE_ETM STREQUAL "1")
# ENABLE_TRACE will cause system_nrf5x.c to set up ETM trace
target_compile_definitions(bootloader PUBLIC ENABLE_TRACE)
endif ()
if (MCU_VARIANT STREQUAL "nrf52")
# UART transport
target_sources(bootloader PUBLIC
${SDK}/libraries/uart/app_uart.c
${SDK}/drivers_nrf/uart/nrf_drv_uart.c
${SDK}/drivers_nrf/common/nrf_drv_common.c
)
target_include_directories(bootloader PUBLIC
${SDK11}/libraries/util
${SDK}/drivers_nrf/common
${SDK}/drivers_nrf/uart
)
else ()
# USB transport
target_sources(bootloader PUBLIC
src/boards/${BOARD}/pinconfig.c
src/usb/msc_uf2.c
src/usb/usb.c
src/usb/usb_desc.c
src/usb/uf2/ghostfat.c
# TinyUSB
${TUSB}/portable/nordic/nrf5x/dcd_nrf5x.c
${TUSB}/common/tusb_fifo.c
${TUSB}/device/usbd.c
${TUSB}/device/usbd_control.c
${TUSB}/class/cdc/cdc_device.c
${TUSB}/class/msc/msc_device.c
${TUSB}/tusb.c
)
endif ()
#----------------------------------------------------
# MCU Variant differences
# Supported are: nrf52 (nrf52832), nrf52833, nrf52840
#----------------------------------------------------
if (MCU_VARIANT STREQUAL "nrf52")
set(SD_NAME s132)
set(DFU_DEV_REV 0xADAF)
set(DFU_APP_DATA_RESERVED 7*4096)
target_compile_definitions(bootloader PUBLIC
NRF52
NRF52832_XXAA
S132
)
target_include_directories(bootloader PUBLIC
${SOFTDEVICE}/s132_nrf52_6.1.1/s132_nrf52_6.1.1_API/include
)
elseif (MCU_VARIANT STREQUAL "nrf52833")
set(SD_NAME s140)
set(DFU_DEV_REV 52833)
set(DFU_APP_DATA_RESERVED 7*4096)
target_compile_definitions(bootloader PUBLIC
NRF52833_XXAA
S140
)
target_include_directories(bootloader PUBLIC
${SOFTDEVICE}/s140_nrf52_6.1.1/s140_nrf52_6.1.1_API/include
)
elseif (MCU_VARIANT STREQUAL "nrf52840")
set(SD_NAME s140)
set(DFU_DEV_REV 52840)
# App reserved 40KB (8+32) to match circuitpython for 840
set(DFU_APP_DATA_RESERVED 10*4096)
target_compile_definitions(bootloader PUBLIC
NRF52840_XXAA
S140
)
target_include_directories(bootloader PUBLIC
${SOFTDEVICE}/s140_nrf52_6.1.1/s140_nrf52_6.1.1_API/include
)
else ()
message(FATAL_ERROR "MCU_VARIANT ${MCU_VARIANT} is unknown")
endif ()
set(SD_FILENAME ${SD_NAME}_nrf52_${SD_VERSION})
set(SD_HEX ${SOFTDEVICE}/${SD_FILENAME}/${SD_FILENAME}_softdevice.hex)
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions(bootloader PUBLIC DFU_APP_DATA_RESERVED=${DFU_APP_DATA_RESERVED})
endif ()
#----------------------------------
# Get UF2 version from git
#----------------------------------
execute_process(COMMAND git describe --dirty --always --tags OUTPUT_VARIABLE GIT_VERSION)
string(STRIP ${GIT_VERSION} GIT_VERSION)
execute_process(COMMAND bash "-c" "git submodule status | cut -d\" \" -f3,4 | paste -s -d\" \" -"
OUTPUT_VARIABLE GIT_SUBMODULE_VERSIONS
)
string(STRIP ${GIT_SUBMODULE_VERSIONS} GIT_SUBMODULE_VERSIONS)
string(REPLACE ../ "" GIT_SUBMODULE_VERSIONS ${GIT_SUBMODULE_VERSIONS})
string(REPLACE lib/ "" GIT_SUBMODULE_VERSIONS ${GIT_SUBMODULE_VERSIONS})
string(REPLACE "-" ";" RELEASE_VERSION ${GIT_VERSION})
list(GET RELEASE_VERSION 0 RELEASE_VERSION)
string(REPLACE "." ";" RELEASE_VERSION ${RELEASE_VERSION})
list(GET RELEASE_VERSION 0 RELEASE_VERSION_MAJOR)
list(GET RELEASE_VERSION 1 RELEASE_VERSION_MINOR)
list(GET RELEASE_VERSION 2 RELEASE_VERSION_PATCH)
math(EXPR MK_BOOTLOADER_VERSION "(${RELEASE_VERSION_MAJOR} << 16) + (${RELEASE_VERSION_MINOR} << 8) + ${RELEASE_VERSION_PATCH}")
cmake_print_variables(GIT_VERSION GIT_SUBMODULE_VERSIONS MK_BOOTLOADER_VERSION)
target_compile_definitions(bootloader PUBLIC
UF2_VERSION_BASE="${GIT_VERSION}"
UF2_VERSION="${GIT_VERSION} - ${GIT_SUBMODULE_VERSIONS}"
BLEDIS_FW_VERSION="${GIT_VERSION} ${SD_NAME} ${SD_VERSION}"
MK_BOOTLOADER_VERSION=${MK_BOOTLOADER_VERSION}
)
#----------------------------------
# Post build
#----------------------------------
# run size after build
add_custom_command(TARGET bootloader POST_BUILD
COMMAND ${CMAKE_SIZE} $<TARGET_FILE:bootloader>
)
# Add bin/hex output
add_custom_command(TARGET bootloader POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:bootloader> $<TARGET_FILE_DIR:bootloader>/bootloader.bin
COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:bootloader> $<TARGET_FILE_DIR:bootloader>/bootloader.hex
COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/tools/hexmerge.py --overlap=replace -o $<TARGET_FILE_DIR:bootloader>/bootloader_mbr.hex $<TARGET_FILE_DIR:bootloader>/bootloader.hex ${MBR_HEX}
COMMAND ${Python_EXECUTABLE} ${UF2CONV_PY} -f ${UF2_FAMILY_ID_BOOTLOADER} -c -o $<TARGET_FILE_DIR:bootloader>/bootloader_mbr.uf2 $<TARGET_FILE_DIR:bootloader>/bootloader_mbr.hex
VERBATIM)
#----------------------------------
# Flashing target
#----------------------------------
if (NOT DEFINED NRFJPROG)
set(NRFJPROG nrfjprog)
endif()
add_custom_target(flash-jlink
DEPENDS bootloader
COMMAND ${NRFJPROG} --program $<TARGET_FILE:bootloader> --verify --sectoranduicrerase -f nrf52 --reset
)
add_custom_target(flash-uf2
DEPENDS bootloader
COMMAND ${Python_EXECUTABLE} ${UF2CONV_PY} -f ${UF2_FAMILY_ID_BOOTLOADER} --deploy $<TARGET_FILE_DIR:bootloader>/bootloader_mbr.uf2
)
add_custom_target(flash-sd
COMMAND ${NRFJPROG} --program ${SD_HEX} --verify --sectorerase -f nrf52 --reset
)
add_custom_target(flash-mbr
COMMAND ${NRFJPROG} --program ${MBR_HEX} --verify --sectorerase -f nrf52 --reset
)
add_custom_target(flash-erase
COMMAND ${NRFJPROG} -f nrf52 --eraseall
)
+34 -4
View File
@@ -27,7 +27,11 @@ SD_HEX = $(SD_PATH)/$(SD_FILENAME)_softdevice.hex
MBR_HEX = lib/softdevice/mbr/hex/mbr_nrf52_2.4.1_mbr.hex
# linker by MCU eg. nrf52840.ld
LD_FILE = linker/$(MCU_SUB_VARIANT).ld
ifeq ($(DEBUG), 1)
LD_FILE = linker/$(MCU_SUB_VARIANT)_debug.ld
else
LD_FILE = linker/$(MCU_SUB_VARIANT).ld
endif
GIT_VERSION := $(shell git describe --dirty --always --tags)
GIT_SUBMODULE_VERSIONS := $(shell git submodule status | cut -d" " -f3,4 | paste -s -d" " -)
@@ -109,17 +113,18 @@ ifeq ($(MCU_SUB_VARIANT),nrf52)
SD_NAME = s132
DFU_DEV_REV = 0xADAF
CFLAGS += -DNRF52 -DNRF52832_XXAA -DS132
CFLAGS += -DDFU_APP_DATA_RESERVED=7*4096
DFU_APP_DATA_RESERVED=7*4096
else ifeq ($(MCU_SUB_VARIANT),nrf52833)
SD_NAME = s140
DFU_DEV_REV = 52833
CFLAGS += -DNRF52833_XXAA -DS140
CFLAGS += -DDFU_APP_DATA_RESERVED=7*4096
DFU_APP_DATA_RESERVED=7*4096
else ifeq ($(MCU_SUB_VARIANT),nrf52840)
SD_NAME = s140
DFU_DEV_REV = 52840
CFLAGS += -DNRF52840_XXAA -DS140
CFLAGS += -DDFU_APP_DATA_RESERVED=10*4096
# App reserved 40KB (8+32) to match circuitpython for 840
DFU_APP_DATA_RESERVED=10*4096
else
$(error Sub Variant $(MCU_SUB_VARIANT) is unknown)
endif
@@ -134,6 +139,8 @@ C_SRC += \
src/dfu_init.c \
src/flash_nrf5x.c \
src/main.c \
src/screen.c \
src/images.c \
# all files in boards
C_SRC += src/boards/boards.c
@@ -309,6 +316,7 @@ ifneq ($(USE_NFCT),yes)
endif
CFLAGS += -DSOFTDEVICE_PRESENT
CFLAGS += -DUF2_VERSION_BASE='"$(GIT_VERSION)"'
CFLAGS += -DUF2_VERSION='"$(GIT_VERSION) $(GIT_SUBMODULE_VERSIONS)"'
CFLAGS += -DBLEDIS_FW_VERSION='"$(GIT_VERSION) $(SD_NAME) $(SD_VERSION)"'
@@ -321,6 +329,21 @@ ifeq ($(DEBUG), 1)
RTT_SRC = lib/SEGGER_RTT
IPATH += $(RTT_SRC)/RTT
C_SRC += $(RTT_SRC)/RTT/SEGGER_RTT.c
DFU_APP_DATA_RESERVED = 0
# expand bootloader address to 28KB/40KB of reserved app
ifeq ($(MCU_SUB_VARIANT),nrf52840)
CFLAGS += -DBOOTLOADER_REGION_START=0xEA000
else
CFLAGS += -DBOOTLOADER_REGION_START=0x6D000
endif
endif
CFLAGS += -DDFU_APP_DATA_RESERVED=$(DFU_APP_DATA_RESERVED)
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523
ifneq ($(findstring 12.,$(shell $(CC) --version 2>/dev/null)),)
CFLAGS += --param=min-pagesize=0
endif
#------------------------------------------------------------------------------
@@ -330,6 +353,7 @@ endif
LDFLAGS += \
$(CFLAGS) \
-Wl,-L,linker -Wl,-T,$(LD_FILE) \
-Wl,--print-memory-usage \
-Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections \
-specs=nosys.specs -specs=nano.specs
@@ -476,6 +500,12 @@ dfu-flash: flash-dfu
flash-dfu: $(BUILD)/$(MERGED_FILE).zip
@:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0)
$(NRFUTIL) --verbose dfu serial --package $< -p $(SERIAL) -b 115200 --singlebank --touch 1200
# flash skip crc magic ( app valid = 0x0001, crc = 0x0000 )
#flash-skip-crc:
# nrfjprog --memwr $(BOOT_SETTING_ADDR) --val 0x00000001 -f nrf52
# nrfjprog --memwr 0xFF000 --val 0x00000001 -f nrf52
# nrfjprog --memwr 0x7F000 --val 0x00000001 -f nrf52
#------------------- Debugging -------------------
+23 -28
View File
@@ -2,7 +2,17 @@
[![Build Status](https://github.com/adafruit/Adafruit_nRF52_Bootloader/workflows/Build/badge.svg)](https://github.com/adafruit/Adafruit_nRF52_Bootloader/actions)
This is a CDC/DFU/UF2 bootloader for nRF52 boards.
A CDC/DFU/UF2 bootloader for Nordic nRF52 microcontroller. UF2 is an easy-to-use bootloader that appears as a flash drive. You can just copy `.uf2`-format application images to the flash drive to load new firmware. See https://github.com/Microsoft/uf2 for more information.
DFU via serial/CDC requires [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil), a modified version of [Nordic nrfutil](https://github.com/NordicSemiconductor/pc-nrfutil). Install `python3` if it is not installed already and run this command to install adafruit-nrfutil from PyPi:
```
$ pip3 install --user adafruit-nrfutil
```
## Supported Boards
Officially supported boards are:
- [Adafruit CLUE](https://www.adafruit.com/product/4500)
- [Adafruit Circuit Playground Bluefruit](https://www.adafruit.com/product/4333)
@@ -12,34 +22,9 @@ This is a CDC/DFU/UF2 bootloader for nRF52 boards.
- [Adafruit ItsyBitsy nRF52840 Express](https://www.adafruit.com/product/4481)
- [Adafruit LED Glasses Driver nRF52840](https://www.adafruit.com/product/5217)
- Adafruit Metro nRF52840 Express
- [Akizukidenshi AE-BL652-BO](https://akizukidenshi.com/catalog/g/gK-15567/)
- [Electronut Labs Papyr](https://docs.electronut.in/papyr/)
- [iLabs Challenger 840 BLE](https://ilabs.se/challenger-840-ble-datasheet/)
- [MakerDiary MDK nRF52840 USB Dongle](https://makerdiary.com/products/nrf52840-mdk-usb-dongle)
- [MakerDiary nRF52840 M.2 Module](https://makerdiary.com/products/nrf52840-m2-module)
- [Nordic nRF52840DK PCA10056](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK)
- [Nordic nRF52840DK PCA10059 ("Dongle")](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle)
- Particle Argon
- Particle Boron
- Particle Xenon
- [SparkFun MicroMod nRF52840](https://www.sparkfun.com/products/16984)
- [Raytac MDBT50Q-RX Dongle](https://www.adafruit.com/product/5199)
UF2 is an easy-to-use bootloader that appears as a flash drive. You can just copy `.uf2`-format
application images to the flash drive to load new firmware. See https://github.com/Microsoft/uf2 and https://github.com/adafruit/uf2-samdx1 for more information.
[adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil), a modified version of [Nordic nrfutil](https://github.com/NordicSemiconductor/pc-nrfutil), is required to perform DFU. Install `python3` if it is not installed already and run this command to install adafruit-nrfutil from PyPi:
```
$ pip3 install --user adafruit-nrfutil
```
Clone this repo with following commands, or fork it for your own development
```
git clone https://github.com/adafruit/Adafruit_nRF52_Bootloader
cd Adafruit_nRF52_Bootloader
git submodule update --init
```
In addition, there is also lots of other 3rd-party boards which are added by other makers, users and community. Check out the [complete list of all boards here](/src/boards).
## Features
@@ -129,6 +114,16 @@ You must have have a J-Link available to "unbrick" your device.
### Build:
Firstly clone this repo with following commands
```
git clone https://github.com/adafruit/Adafruit_nRF52_Bootloader
cd Adafruit_nRF52_Bootloader
git submodule update --init
```
Then build it with `make BOARD={board} all`, for example:
```
make BOARD=feather_nrf52840_express all
```
+19
View File
@@ -0,0 +1,19 @@
if (TOOLCHAIN STREQUAL "gcc")
set(TOOLCHAIN_COMMON_FLAGS
-mthumb
-mcpu=cortex-m33
-mfloat-abi=hard
-mfpu=fpv5-sp-d16
)
set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "")
elseif (TOOLCHAIN STREQUAL "iar")
set(TOOLCHAIN_COMMON_FLAGS
--cpu cortex-m33
--fpu VFPv5-SP
)
set(FREERTOS_PORT IAR_ARM_CM4F CACHE INTERNAL "")
endif ()
+23
View File
@@ -0,0 +1,23 @@
if (TOOLCHAIN STREQUAL "gcc")
set(TOOLCHAIN_COMMON_FLAGS
-mthumb
-mcpu=cortex-m4
-mfloat-abi=hard
-mfpu=fpv4-sp-d16
)
if (NOT DEFINED FREERTOS_PORT)
set(FREERTOS_PORT GCC_ARM_CM4F CACHE INTERNAL "")
endif ()
elseif (TOOLCHAIN STREQUAL "iar")
set(TOOLCHAIN_COMMON_FLAGS
--cpu cortex-m4
--fpu VFPv4
)
if (NOT DEFINED FREERTOS_PORT)
set(FREERTOS_PORT IAR_ARM_CM4F CACHE INTERNAL "")
endif ()
endif ()
+46
View File
@@ -0,0 +1,46 @@
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER "arm-none-eabi-gcc")
set(CMAKE_CXX_COMPILER "arm-none-eabi-g++")
set(CMAKE_ASM_COMPILER "arm-none-eabi-gcc")
set(CMAKE_SIZE "arm-none-eabi-size" CACHE FILEPATH "")
set(CMAKE_OBJCOPY "arm-none-eabi-objcopy" CACHE FILEPATH "")
set(CMAKE_OBJDUMP "arm-none-eabi-objdump" CACHE FILEPATH "")
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
# Look for includes and libraries only in the target system prefix.
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# pass TOOLCHAIN_CPU to
set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_SYSTEM_PROCESSOR)
include(${CMAKE_CURRENT_LIST_DIR}/../cpu/${CMAKE_SYSTEM_PROCESSOR}.cmake)
# enable all possible warnings for building examples
list(APPEND TOOLCHAIN_COMMON_FLAGS
-fdata-sections
-ffunction-sections
-fsingle-precision-constant
-fno-strict-aliasing
)
set(TOOLCHAIN_EXE_LINKER_FLAGS
-Wl,--print-memory-usage
-Wl,--gc-sections
#-Wl,--cref
)
include(${CMAKE_CURRENT_LIST_DIR}/set_flags.cmake)
# try_compile is cmake test compiling its own example,
# pass -nostdlib to skip stdlib linking
get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE)
if (IS_IN_TRY_COMPILE)
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib")
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib")
endif ()
+17
View File
@@ -0,0 +1,17 @@
include(CMakePrintHelpers)
# join the toolchain flags into a single string
list(JOIN TOOLCHAIN_COMMON_FLAGS " " TOOLCHAIN_COMMON_FLAGS)
foreach (LANG IN ITEMS C CXX ASM)
set(CMAKE_${LANG}_FLAGS_INIT ${TOOLCHAIN_COMMON_FLAGS})
#cmake_print_variables(CMAKE_${LANG}_FLAGS_INIT)
# optimization flags for LOG, LOGGER ?
#set(CMAKE_${LANG}_FLAGS_RELEASE_INIT "-Os")
#set(CMAKE_${LANG}_FLAGS_DEBUG_INIT "-O0")
endforeach ()
# Linker
list(JOIN TOOLCHAIN_EXE_LINKER_FLAGS " " CMAKE_EXE_LINKER_FLAGS_INIT)
@@ -37,7 +37,7 @@
#define BLEGAP_EVENT_LENGTH 6
#define BLEGATT_ATT_MTU_MAX 247
#define BLEGATT_ATT_MTU_MAX 23
enum { BLE_CONN_CFG_HIGH_BANDWIDTH = 1 };
#define DFU_REV_MAJOR 0x00 /** DFU Major revision number to be exposed. */
@@ -48,14 +48,18 @@ static inline bool is_sd_existed(void)
#define CODE_PAGE_SIZE 0x1000 /**< Size of a flash codepage. Used for size of the reserved flash space in the bootloader region. Will be runtime checked against NRF_UICR->CODEPAGESIZE to ensure the region is correct. */
#if defined(NRF52832_XXAA) || defined(NRF52833_XXAA)
// Flash = 512 KB
// Flash = 512 KB, allow to be defined in debug mode
#ifndef BOOTLOADER_REGION_START
#define BOOTLOADER_REGION_START 0x00074000 /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register. This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value. The value is used to determine max application size for updating. */
#endif
#define BOOTLOADER_MBR_PARAMS_PAGE_ADDRESS 0x0007E000 /**< The field specifies the page location of the mbr params page address. */
#define BOOTLOADER_SETTINGS_ADDRESS 0x0007F000 /**< The field specifies the page location of the bootloader settings address. */
#elif defined(NRF52840_XXAA)
// Flash = 1024 KB
// Flash = 1024 KB, allow to be defined in debug mode
#ifndef BOOTLOADER_REGION_START
#define BOOTLOADER_REGION_START 0x000F4000 /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register. This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value. The value is used to determine max application size for updating. */
#endif
#define BOOTLOADER_MBR_PARAMS_PAGE_ADDRESS 0x000FE000 /**< The field specifies the page location of the mbr params page address. */
#define BOOTLOADER_SETTINGS_ADDRESS 0x000FF000 /**< The field specifies the page location of the bootloader settings address. */
+99
View File
@@ -0,0 +1,99 @@
/* Linker script to configure memory regions. */
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
MEMORY
{
/** Flash start address for the bootloader. This setting will also be stored in UICR to allow the
* MBR to init the bootloader when starting the system. This value must correspond to
* BOOTLOADER_REGION_START found in dfu_types.h. The system is prevented from starting up if
* those values do not match. The check is performed in main.c, see
* APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START);
*/
/* due to lack of flash for debug, we will use reserved app to extend bootloader size */
FLASH (rx) : ORIGIN = 0x74000-28K, LENGTH = 0x7E000-0x74000-2K + 28K
BOOTLOADER_CONFIG (r): ORIGIN = 0x7E000 - 2K, LENGTH = 2K
/** Location of mbr params page in flash. */
MBR_PARAMS_PAGE (rw) : ORIGIN = 0x0007E000, LENGTH = 0x1000
/** Location of bootloader setting in flash. */
BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x0007F000, LENGTH = 0x1000
/** RAM Region for bootloader. */
/* Avoid conflict with NOINIT for OTA bond sharing */
RAM (rwx) : ORIGIN = 0x20008000, LENGTH = 0x20020000-0x20008000
/* Location for double reset detection, no init */
DBL_RESET (rwx) : ORIGIN = 0x20007F7C, LENGTH = 0x04
/** Location of non initialized RAM. Non initialized RAM is used for exchanging bond information
* from application to bootloader when using buttonless DFU OTA. */
NOINIT (rwx) : ORIGIN = 0x20007F80, LENGTH = 0x80
/** Location in UICR where bootloader start address is stored. */
UICR_BOOTLOADER (r) : ORIGIN = 0x10001014, LENGTH = 0x04
/** Location in UICR where mbr params page address is stored. */
UICR_MBR_PARAM_PAGE(r) : ORIGIN = 0x10001018, LENGTH = 0x04
}
SECTIONS
{
.fs_data_out ALIGN(4):
{
PROVIDE( __start_fs_data = .);
KEEP(*(fs_data))
PROVIDE( __stop_fs_data = .);
} = 0
.bootloaderConfig :
{
KEEP(*(.bootloaderConfig))
} > BOOTLOADER_CONFIG
/* Place the bootloader settings page in flash. */
.bootloaderSettings(NOLOAD) :
{
} > BOOTLOADER_SETTINGS
/* Write the bootloader address in UICR. */
.uicrBootStartAddress :
{
KEEP(*(.uicrBootStartAddress))
} > UICR_BOOTLOADER
/* Place the mbr params page in flash. */
.mbrParamsPage(NOLOAD) :
{
} > MBR_PARAMS_PAGE
/* Write the bootloader address in UICR. */
.uicrMbrParamsPageAddress :
{
KEEP(*(.uicrMbrParamsPageAddress))
} > UICR_MBR_PARAM_PAGE
.dbl_reset(NOLOAD) :
{
} > DBL_RESET
/* No init RAM section in bootloader. Used for bond information exchange. */
.noinit(NOLOAD) :
{
} > NOINIT
/* other placements follow here... */
}
INCLUDE "nrf_common.ld"
+99
View File
@@ -0,0 +1,99 @@
/* Linker script to configure memory regions. */
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
MEMORY
{
/** Flash start address for the bootloader. This setting will also be stored in UICR to allow the
* MBR to init the bootloader when starting the system. This value must correspond to
* BOOTLOADER_REGION_START found in dfu_types.h. The system is prevented from starting up if
* those values do not match. The check is performed in main.c, see
* APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START);
*/
/* due to lack of flash for debug, we will use reserved app to extend bootloader size */
FLASH (rx) : ORIGIN = 0xF4000 - 40K, LENGTH = 0xFE000-0xF4000 - 2K + 40K /* 38 KB */
BOOTLOADER_CONFIG (r): ORIGIN = 0xFE000 - 2K, LENGTH = 2K
/** Location of mbr params page in flash. */
MBR_PARAMS_PAGE (rw) : ORIGIN = 0xFE000, LENGTH = 0x1000
/** Location of bootloader setting in flash. */
BOOTLOADER_SETTINGS (rw) : ORIGIN = 0xFF000, LENGTH = 0x1000
/** RAM Region for bootloader. */
/* Avoid conflict with NOINIT for OTA bond sharing */
RAM (rwx) : ORIGIN = 0x20008000, LENGTH = 0x20040000-0x20008000
/* Location for double reset detection, no init */
DBL_RESET (rwx) : ORIGIN = 0x20007F7C, LENGTH = 0x04
/** Location of non initialized RAM. Non initialized RAM is used for exchanging bond information
* from application to bootloader when using buttonless DFU OTA. */
NOINIT (rwx) : ORIGIN = 0x20007F80, LENGTH = 0x80
/** Location in UICR where bootloader start address is stored. */
UICR_BOOTLOADER (r) : ORIGIN = 0x10001014, LENGTH = 0x04
/** Location in UICR where mbr params page address is stored. */
UICR_MBR_PARAM_PAGE(r) : ORIGIN = 0x10001018, LENGTH = 0x04
}
SECTIONS
{
.fs_data_out ALIGN(4):
{
PROVIDE( __start_fs_data = .);
KEEP(*(fs_data))
PROVIDE( __stop_fs_data = .);
} = 0
.bootloaderConfig :
{
KEEP(*(.bootloaderConfig))
} > BOOTLOADER_CONFIG
/* Place the bootloader settings page in flash. */
.bootloaderSettings(NOLOAD) :
{
} > BOOTLOADER_SETTINGS
/* Write the bootloader address in UICR. */
.uicrBootStartAddress :
{
KEEP(*(.uicrBootStartAddress))
} > UICR_BOOTLOADER
/* Place the mbr params page in flash. */
.mbrParamsPage(NOLOAD) :
{
} > MBR_PARAMS_PAGE
/* Write the bootloader address in UICR. */
.uicrMbrParamsPageAddress :
{
KEEP(*(.uicrMbrParamsPageAddress))
} > UICR_MBR_PARAM_PAGE
.dbl_reset(NOLOAD) :
{
} > DBL_RESET
/* No init RAM section in bootloader. Used for bond information exchange. */
.noinit(NOLOAD) :
{
} > NOINIT
/* other placements follow here... */
}
INCLUDE "nrf_common.ld"
+89
View File
@@ -0,0 +1,89 @@
/* Linker script to configure memory regions. */
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
MEMORY
{
/** Flash start address for the bootloader. This setting will also be stored in UICR to allow the
* MBR to init the bootloader when starting the system. This value must correspond to
* BOOTLOADER_REGION_START found in dfu_types.h. The system is prevented from starting up if
* those values do not match. The check is performed in main.c, see
* APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START);
*/
FLASH (rx) : ORIGIN = 0x74000-28K, LENGTH = 0x7E000-0x74000+28K /* 40 KB */
/** Location of mbr params page in flash. */
MBR_PARAMS_PAGE (rw) : ORIGIN = 0x7E000, LENGTH = 0x1000
/** Location of bootloader setting in flash. */
BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x7F000, LENGTH = 0x1000
/** RAM Region for bootloader. */
RAM (rwx) : ORIGIN = 0x20008000, LENGTH = 0x20010000-0x20008000
/* Location for double reset detection, no init */
DBL_RESET (rwx) : ORIGIN = 0x20007F7C, LENGTH = 0x04
/** Location of non initialized RAM. Non initialized RAM is used for exchanging bond information
* from application to bootloader when using buttonless DFU OTA. */
NOINIT (rwx) : ORIGIN = 0x20007F80, LENGTH = 0x80
/** Location in UICR where bootloader start address is stored. */
UICR_BOOTLOADER (r) : ORIGIN = 0x10001014, LENGTH = 0x04
/** Location in UICR where mbr params page address is stored. */
UICR_MBR_PARAM_PAGE(r) : ORIGIN = 0x10001018, LENGTH = 0x04
}
SECTIONS
{
.fs_data_out ALIGN(4):
{
PROVIDE( __start_fs_data = .);
KEEP(*(fs_data))
PROVIDE( __stop_fs_data = .);
} = 0
/* Place the bootloader settings page in flash. */
.bootloaderSettings(NOLOAD) :
{
} > BOOTLOADER_SETTINGS
/* Write the bootloader address in UICR. */
.uicrBootStartAddress :
{
KEEP(*(.uicrBootStartAddress))
} > UICR_BOOTLOADER
/* Place the mbr params page in flash. */
.mbrParamsPage(NOLOAD) :
{
} > MBR_PARAMS_PAGE
/* Write the bootloader address in UICR. */
.uicrMbrParamsPageAddress :
{
KEEP(*(.uicrMbrParamsPageAddress))
} > UICR_MBR_PARAM_PAGE
.dbl_reset(NOLOAD) :
{
} > DBL_RESET
/* No init RAM section in bootloader. Used for bond information exchange. */
.noinit(NOLOAD) :
{
} > NOINIT
/* other placements follow here... */
}
INCLUDE "nrf_common.ld"
+404 -189
View File
@@ -31,41 +31,42 @@
#include "nrf_spim.h"
#endif
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
//--------------------------------------------------------------------+
#define SCHED_MAX_EVENT_DATA_SIZE sizeof(app_timer_event_t) /**< Maximum size of scheduler events. */
#define SCHED_QUEUE_SIZE 30 /**< Maximum number of events in the scheduler queue. */
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
void neopixel_init(void);
void neopixel_write(uint8_t *pixels);
void neopixel_teardown(void);
void neopixel_init(void);
void neopixel_write(uint8_t* pixels);
void neopixel_teardown(void);
#endif
//------------- IMPLEMENTATION -------------//
void button_init(uint32_t pin)
{
if ( BUTTON_PULL == NRF_GPIO_PIN_PULLDOWN )
{
//--------------------------------------------------------------------+
// IMPLEMENTATION
//--------------------------------------------------------------------+
static uint32_t _systick_count = 0;
void SysTick_Handler(void) {
_systick_count++;
led_tick();
}
void button_init(uint32_t pin) {
if (BUTTON_PULL == NRF_GPIO_PIN_PULLDOWN) {
nrf_gpio_cfg_sense_input(pin, BUTTON_PULL, NRF_GPIO_PIN_SENSE_HIGH);
}
else
{
} else {
nrf_gpio_cfg_sense_input(pin, BUTTON_PULL, NRF_GPIO_PIN_SENSE_LOW);
}
}
bool button_pressed(uint32_t pin)
{
bool button_pressed(uint32_t pin) {
uint32_t const active_state = (BUTTON_PULL == NRF_GPIO_PIN_PULLDOWN ? 1 : 0);
return nrf_gpio_pin_read(pin) == active_state;
}
// This is declared so that a board specific init can be called from here.
void __attribute__((weak)) board_init_extra(void) { }
void board_init(void)
{
void __attribute__((weak)) board_init2(void) {}
void board_init(void) {
// stop LF clock just in case we jump from application without reset
NRF_CLOCK->TASKS_LFCLKSTOP = 1UL;
@@ -84,8 +85,14 @@ void board_init(void)
led_pwm_init(LED_SECONDARY, LED_SECONDARY_PIN);
#endif
#endif
// use neopixel for use enumeration
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
// use neopixel for use enumeration
#ifdef NEOPIXEL_POWER_PIN
nrf_gpio_cfg_output(NEOPIXEL_POWER_PIN);
nrf_gpio_pin_write(NEOPIXEL_POWER_PIN, 1);
#endif
neopixel_init();
#endif
@@ -95,26 +102,25 @@ void board_init(void)
#if ENABLE_DCDC_1 == 1
NRF_POWER->DCDCEN = 1;
#endif
// Make sure any custom inits are performed
board_init_extra();
board_init2();
// When board is supplied on VDDH (and not VDD), this specifies what voltage the GPIO should run at
// and what voltage is output at VDD. The default (0xffffffff) is 1.8V; typically you'll want
// #define UICR_REGOUT0_VALUE UICR_REGOUT0_VOUT_3V3
// in board.h when using that power configuration.
// When board is supplied on VDDH (and not VDD), this specifies what voltage the GPIO should run at
// and what voltage is output at VDD. The default (0xffffffff) is 1.8V; typically you'll want
// #define UICR_REGOUT0_VALUE UICR_REGOUT0_VOUT_3V3
// in board.h when using that power configuration.
#ifdef UICR_REGOUT0_VALUE
if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) !=
(UICR_REGOUT0_VALUE << UICR_REGOUT0_VOUT_Pos))
{
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~((uint32_t)UICR_REGOUT0_VOUT_Msk)) |
(UICR_REGOUT0_VALUE << UICR_REGOUT0_VOUT_Pos);
if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) != (UICR_REGOUT0_VALUE << UICR_REGOUT0_VOUT_Pos)){
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~((uint32_t)UICR_REGOUT0_VOUT_Msk)) |
(UICR_REGOUT0_VALUE << UICR_REGOUT0_VOUT_Pos);
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
NVIC_SystemReset();
NVIC_SystemReset();
}
#endif
@@ -126,11 +132,13 @@ void board_init(void)
// Configure Systick for led blinky
NVIC_SetPriority(SysTick_IRQn, 7);
SysTick_Config(SystemCoreClock/1000);
SysTick_Config(SystemCoreClock / 1000);
}
void board_teardown(void)
{
// Actions at the end of board_teardown.
void __attribute__((weak)) board_teardown2(void) {}
void board_teardown(void) {
// Disable systick, turn off LEDs
SysTick->CTRL = 0;
@@ -143,11 +151,15 @@ void board_teardown(void)
neopixel_teardown();
#endif
#ifdef DISPLAY_PIN_SCK
board_display_teardown();
#endif
// Stop RTC1 used by app_timer
NVIC_DisableIRQ(RTC1_IRQn);
NRF_RTC1->EVTENCLR = RTC_EVTEN_COMPARE0_Msk;
NRF_RTC1->INTENCLR = RTC_INTENSET_COMPARE0_Msk;
NRF_RTC1->TASKS_STOP = 1;
NRF_RTC1->EVTENCLR = RTC_EVTEN_COMPARE0_Msk;
NRF_RTC1->INTENCLR = RTC_INTENSET_COMPARE0_Msk;
NRF_RTC1->TASKS_STOP = 1;
NRF_RTC1->TASKS_CLEAR = 1;
// Stop LF clock
@@ -155,49 +167,161 @@ void board_teardown(void)
// make sure all pins are back in reset state
// NUMBER_OF_PINS is defined in nrf_gpio.h
for (int i = 0; i < NUMBER_OF_PINS; ++i)
{
for (int i = 0; i < NUMBER_OF_PINS; ++i) {
nrf_gpio_cfg_default(i);
}
// board specific teardown actions
board_teardown2();
}
static uint32_t _systick_count = 0;
void SysTick_Handler(void)
{
_systick_count++;
//--------------------------------------------------------------------+
// Display
//--------------------------------------------------------------------+
#ifdef DISPLAY_PIN_SCK
#include "nrf_spim.h"
led_tick();
#define TFT_MADCTL_MY 0x80 ///< Page addr order: Bottom to top
#define TFT_MADCTL_MX 0x40 ///< Column addr order: Right to left
#define TFT_MADCTL_MV 0x20 ///< Page/Column order: Reverse Mode ( X <-> Y )
#define TFT_MADCTL_ML 0x10 ///< LCD refresh Bottom to top
#define TFT_MADCTL_MH 0x04 ///< LCD refresh right to left
#define TFT_MADCTL_RGB 0x00 ///< Red-Green-Blue pixel order
#define TFT_MADCTL_BGR 0x08 ///< Blue-Green-Red pixel order
// Note don't use SPIM3 since it has lots of errata
NRF_SPIM_Type* _spim = NRF_SPIM0;
static void spi_write(NRF_SPIM_Type *p_spim, uint8_t const *tx_buf, size_t tx_len) {
nrf_spim_tx_buffer_set(p_spim, tx_buf, tx_len);
nrf_spim_rx_buffer_set(p_spim, NULL, 0);
nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_ENDTX);
nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_END);
nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_START);
// blocking wait until xfer complete
while (!nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END)){}
}
static void tft_controller_init(void);
void pwm_teardown(NRF_PWM_Type* pwm )
{
static inline void tft_cs(bool state) {
nrf_gpio_pin_write(DISPLAY_PIN_CS, state);
}
static inline void tft_dc(bool state) {
nrf_gpio_pin_write(DISPLAY_PIN_DC, state);
}
static void tft_cmd(uint8_t cmd, uint8_t const* data, size_t narg) {
tft_cs(false);
// send command
tft_dc(false);
spi_write(_spim, &cmd, 1);
// send data
if (narg > 0) {
tft_dc(true);
spi_write(_spim, data, narg);
}
tft_cs(true);
}
void board_display_init(void) {
//------------- SPI init -------------//
// highspeed SPIM should set SCK and MOSI to high drive
nrf_gpio_cfg(DISPLAY_PIN_SCK, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_CONNECT,
NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
nrf_gpio_cfg(DISPLAY_PIN_MOSI, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
nrf_gpio_cfg_output(DISPLAY_PIN_CS);
nrf_gpio_pin_set(DISPLAY_PIN_CS);
nrf_spim_pins_set(_spim, DISPLAY_PIN_SCK, DISPLAY_PIN_MOSI, NRF_SPIM_PIN_NOT_CONNECTED);
nrf_spim_frequency_set(_spim, NRF_SPIM_FREQ_4M);
nrf_spim_configure(_spim, NRF_SPIM_MODE_0, NRF_SPIM_BIT_ORDER_MSB_FIRST);
nrf_spim_orc_set(_spim, 0xFF);
nrf_spim_enable(_spim);
//------------- Display Init -------------//
nrf_gpio_cfg_output(DISPLAY_PIN_DC);
#if defined(DISPLAY_VSENSOR_PIN) && DISPLAY_VSENSOR_PIN >= 0
nrf_gpio_cfg_output(DISPLAY_VSENSOR_PIN);
nrf_gpio_pin_write(DISPLAY_VSENSOR_PIN, DISPLAY_VSENSOR_ON);
#endif
#if defined(DISPLAY_PIN_RST) && DISPLAY_PIN_RST >= 0
nrf_gpio_cfg_output(DISPLAY_PIN_RST);
nrf_gpio_pin_clear(DISPLAY_PIN_RST);
NRFX_DELAY_MS(10);
nrf_gpio_pin_set(DISPLAY_PIN_RST);
NRFX_DELAY_MS(20);
#endif
#if defined(DISPLAY_PIN_BL) && DISPLAY_PIN_BL >= 0
nrf_gpio_cfg_output(DISPLAY_PIN_BL);
nrf_gpio_pin_write(DISPLAY_PIN_BL, DISPLAY_BL_ON);
#endif
tft_controller_init();
}
void board_display_teardown(void) {
nrf_spim_disable(_spim);
}
void board_display_draw_line(uint16_t y, uint8_t const* buf, size_t nbytes) {
// column and row address set
uint32_t xa32 = DISPLAY_COL_OFFSET << 16 | DISPLAY_WIDTH;
xa32 = __builtin_bswap32(xa32);
y += DISPLAY_ROW_OFFSET;
uint32_t ya32 = (y << 16) | (y + 1);
ya32 = __builtin_bswap32(ya32);
tft_cmd(0x2A, (uint8_t*) &xa32, 4);
tft_cmd(0x2B, (uint8_t*) &ya32, 4);
// command: memory write
tft_cmd(0x2C, buf, nbytes);
}
#endif
//--------------------------------------------------------------------+
// LED Indicator
//--------------------------------------------------------------------+
void pwm_teardown(NRF_PWM_Type* pwm) {
pwm->TASKS_SEQSTART[0] = 0;
pwm->ENABLE = 0;
pwm->ENABLE = 0;
pwm->PSEL.OUT[0] = 0xFFFFFFFF;
pwm->PSEL.OUT[1] = 0xFFFFFFFF;
pwm->PSEL.OUT[2] = 0xFFFFFFFF;
pwm->PSEL.OUT[3] = 0xFFFFFFFF;
pwm->MODE = 0;
pwm->COUNTERTOP = 0x3FF;
pwm->PRESCALER = 0;
pwm->DECODER = 0;
pwm->LOOP = 0;
pwm->SEQ[0].PTR = 0;
pwm->SEQ[0].CNT = 0;
pwm->MODE = 0;
pwm->COUNTERTOP = 0x3FF;
pwm->PRESCALER = 0;
pwm->DECODER = 0;
pwm->LOOP = 0;
pwm->SEQ[0].PTR = 0;
pwm->SEQ[0].CNT = 0;
}
static uint16_t led_duty_cycles[PWM0_CH_NUM] = { 0 };
static uint16_t led_duty_cycles[PWM0_CH_NUM] = {0};
#if LEDS_NUMBER > PWM0_CH_NUM
#error "Only " PWM0_CH_NUM " concurrent status LEDs are supported."
#endif
void led_pwm_init(uint32_t led_index, uint32_t led_pin)
{
NRF_PWM_Type* pwm = NRF_PWM0;
void led_pwm_init(uint32_t led_index, uint32_t led_pin) {
NRF_PWM_Type* pwm = NRF_PWM0;
pwm->ENABLE = 0;
@@ -206,15 +330,15 @@ void led_pwm_init(uint32_t led_index, uint32_t led_pin)
pwm->PSEL.OUT[led_index] = led_pin;
pwm->MODE = PWM_MODE_UPDOWN_Up;
pwm->COUNTERTOP = 0xff;
pwm->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_16;
pwm->DECODER = PWM_DECODER_LOAD_Individual;
pwm->LOOP = 0;
pwm->MODE = PWM_MODE_UPDOWN_Up;
pwm->COUNTERTOP = 0xff;
pwm->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_16;
pwm->DECODER = PWM_DECODER_LOAD_Individual;
pwm->LOOP = 0;
pwm->SEQ[0].PTR = (uint32_t) (led_duty_cycles);
pwm->SEQ[0].CNT = 4; // default mode is Individual --> count must be 4
pwm->SEQ[0].REFRESH = 0;
pwm->SEQ[0].PTR = (uint32_t) (led_duty_cycles);
pwm->SEQ[0].CNT = 4; // default mode is Individual --> count must be 4
pwm->SEQ[0].REFRESH = 0;
pwm->SEQ[0].ENDDELAY = 0;
pwm->ENABLE = 1;
@@ -223,13 +347,11 @@ void led_pwm_init(uint32_t led_index, uint32_t led_pin)
// pwm->TASKS_SEQSTART[0] = 1;
}
void led_pwm_teardown(void)
{
void led_pwm_teardown(void) {
pwm_teardown(NRF_PWM0);
}
void led_pwm_duty_cycle(uint32_t led_index, uint16_t duty_cycle)
{
void led_pwm_duty_cycle(uint32_t led_index, uint16_t duty_cycle) {
led_duty_cycles[led_index] = duty_cycle;
nrf_pwm_event_clear(NRF_PWM0, NRF_PWM_EVENT_SEQEND0);
nrf_pwm_task_trigger(NRF_PWM0, NRF_PWM_TASK_SEQSTART0);
@@ -239,102 +361,103 @@ static uint32_t primary_cycle_length;
#ifdef LED_SECONDARY_PIN
static uint32_t secondary_cycle_length;
#endif
void led_tick() {
uint32_t millis = _systick_count;
uint32_t millis = _systick_count;
uint32_t cycle = millis % primary_cycle_length;
uint32_t half_cycle = primary_cycle_length / 2;
if (cycle > half_cycle) {
cycle = primary_cycle_length - cycle;
}
uint16_t duty_cycle = 0x4f * cycle / half_cycle;
#if LED_STATE_ON == 1
duty_cycle = 0xff - duty_cycle;
#endif
led_pwm_duty_cycle(LED_PRIMARY, duty_cycle);
uint32_t cycle = millis % primary_cycle_length;
uint32_t half_cycle = primary_cycle_length / 2;
if (cycle > half_cycle) {
cycle = primary_cycle_length - cycle;
}
uint16_t duty_cycle = 0x4f * cycle / half_cycle;
#if LED_STATE_ON == 1
duty_cycle = 0xff - duty_cycle;
#endif
led_pwm_duty_cycle(LED_PRIMARY, duty_cycle);
#ifdef LED_SECONDARY_PIN
cycle = millis % secondary_cycle_length;
half_cycle = secondary_cycle_length / 2;
if (cycle > half_cycle) {
cycle = secondary_cycle_length - cycle;
}
duty_cycle = 0x8f * cycle / half_cycle;
#if LED_STATE_ON == 1
duty_cycle = 0xff - duty_cycle;
#endif
led_pwm_duty_cycle(LED_SECONDARY, duty_cycle);
#endif
#ifdef LED_SECONDARY_PIN
cycle = millis % secondary_cycle_length;
half_cycle = secondary_cycle_length / 2;
if (cycle > half_cycle) {
cycle = secondary_cycle_length - cycle;
}
duty_cycle = 0x8f * cycle / half_cycle;
#if LED_STATE_ON == 1
duty_cycle = 0xff - duty_cycle;
#endif
led_pwm_duty_cycle(LED_SECONDARY, duty_cycle);
#endif
}
static uint32_t rgb_color;
static bool temp_color_active = false;
void led_state(uint32_t state)
{
uint32_t new_rgb_color = rgb_color;
uint32_t temp_color = 0;
switch (state) {
case STATE_USB_MOUNTED:
new_rgb_color = 0x00ff00;
primary_cycle_length = 3000;
break;
case STATE_BOOTLOADER_STARTED:
case STATE_USB_UNMOUNTED:
new_rgb_color = 0xff0000;
primary_cycle_length = 300;
break;
void led_state(uint32_t state) {
uint32_t new_rgb_color = rgb_color;
uint32_t temp_color = 0;
switch (state) {
case STATE_USB_MOUNTED:
new_rgb_color = 0x00ff00;
primary_cycle_length = 3000;
break;
case STATE_WRITING_STARTED:
temp_color = 0xff0000;
primary_cycle_length = 100;
break;
case STATE_BOOTLOADER_STARTED:
case STATE_USB_UNMOUNTED:
new_rgb_color = 0xff0000;
primary_cycle_length = 300;
break;
case STATE_WRITING_FINISHED:
// Empty means to unset any temp colors.
primary_cycle_length = 3000;
break;
case STATE_WRITING_STARTED:
temp_color = 0xff0000;
primary_cycle_length = 100;
break;
case STATE_BLE_CONNECTED:
new_rgb_color = 0x0000ff;
#ifdef LED_SECONDARY_PIN
secondary_cycle_length = 3000;
#else
primary_cycle_length = 3000;
#endif
break;
case STATE_WRITING_FINISHED:
// Empty means to unset any temp colors.
primary_cycle_length = 3000;
break;
case STATE_BLE_DISCONNECTED:
new_rgb_color = 0xff00ff;
#ifdef LED_SECONDARY_PIN
secondary_cycle_length = 300;
#else
primary_cycle_length = 300;
#endif
break;
case STATE_BLE_CONNECTED:
new_rgb_color = 0x0000ff;
#ifdef LED_SECONDARY_PIN
secondary_cycle_length = 3000;
#else
primary_cycle_length = 3000;
#endif
break;
default:
break;
}
uint8_t* final_color = NULL;
new_rgb_color &= BOARD_RGB_BRIGHTNESS;
if (temp_color != 0){
temp_color &= BOARD_RGB_BRIGHTNESS;
final_color = (uint8_t*)&temp_color;
temp_color_active = true;
} else if (new_rgb_color != rgb_color) {
final_color = (uint8_t*)&new_rgb_color;
rgb_color = new_rgb_color;
} else if (temp_color_active) {
final_color = (uint8_t*)&rgb_color;
}
case STATE_BLE_DISCONNECTED:
new_rgb_color = 0xff00ff;
#ifdef LED_SECONDARY_PIN
secondary_cycle_length = 300;
#else
primary_cycle_length = 300;
#endif
break;
default:
break;
}
uint8_t* final_color = NULL;
new_rgb_color &= BOARD_RGB_BRIGHTNESS;
if (temp_color != 0) {
temp_color &= BOARD_RGB_BRIGHTNESS;
final_color = (uint8_t*) &temp_color;
temp_color_active = true;
} else if (new_rgb_color != rgb_color) {
final_color = (uint8_t*) &new_rgb_color;
rgb_color = new_rgb_color;
} else if (temp_color_active) {
final_color = (uint8_t*) &rgb_color;
}
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
if (final_color != NULL) {
neopixel_write(final_color);
}
if (final_color != NULL) {
neopixel_write(final_color);
}
#else
(void) final_color;
(void) final_color;
#endif
}
@@ -347,11 +470,10 @@ void led_state(uint32_t state)
#define BYTE_PER_PIXEL 3
static uint16_t pixels_pattern[NEOPIXELS_NUMBER*BYTE_PER_PIXEL * 8 + 2];
static uint16_t pixels_pattern[NEOPIXELS_NUMBER * BYTE_PER_PIXEL * 8 + 2];
// use PWM1 for neopixel
void neopixel_init(void)
{
void neopixel_init(void) {
// To support both the SoftDevice + Neopixels we use the EasyDMA
// feature from the NRF25. However this technique implies to
// generate a pattern and store it on the memory. The actual
@@ -387,40 +509,33 @@ void neopixel_init(void)
// pwm->INTEN |= (PWM_INTEN_SEQEND0_Enabled<<PWM_INTEN_SEQEND0_Pos);
// PSEL must be configured before enabling PWM
nrf_pwm_pins_set(pwm, (uint32_t[] ) { LED_NEOPIXEL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL });
nrf_pwm_pins_set(pwm, (uint32_t[]) {LED_NEOPIXEL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL});
// Enable the PWM
nrf_pwm_enable(pwm);
}
void neopixel_teardown(void)
{
uint8_t rgb[3] = { 0, 0, 0 };
void neopixel_teardown(void) {
uint8_t rgb[3] = {0, 0, 0};
NRFX_DELAY_US(50); // wait for previous write is complete
neopixel_write(rgb);
NRFX_DELAY_US(50); // wait for this write
pwm_teardown(NRF_PWM1);
}
// write 3 bytes color RGB to built-in neopixel
void neopixel_write (uint8_t *pixels)
{
void neopixel_write(uint8_t* pixels) {
// convert RGB to GRB
uint8_t grb[BYTE_PER_PIXEL] = {pixels[1], pixels[2], pixels[0]};
uint16_t pos = 0; // bit position
// Set all neopixel to same value
for (uint16_t n = 0; n < NEOPIXELS_NUMBER; n++ )
{
for(uint8_t c = 0; c < BYTE_PER_PIXEL; c++)
{
for (uint16_t n = 0; n < NEOPIXELS_NUMBER; n++) {
for (uint8_t c = 0; c < BYTE_PER_PIXEL; c++) {
uint8_t const pix = grb[c];
for ( uint8_t mask = 0x80; mask > 0; mask >>= 1 )
{
for (uint8_t mask = 0x80; mask > 0; mask >>= 1) {
pixels_pattern[pos] = (pix & mask) ? MAGIC_T1H : MAGIC_T0H;
pos++;
}
@@ -434,14 +549,15 @@ void neopixel_write (uint8_t *pixels)
NRF_PWM_Type* pwm = NRF_PWM1;
nrf_pwm_seq_ptr_set(pwm, 0, pixels_pattern);
nrf_pwm_seq_cnt_set(pwm, 0, sizeof(pixels_pattern)/2);
nrf_pwm_seq_cnt_set(pwm, 0, sizeof(pixels_pattern) / 2);
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQEND0);
nrf_pwm_task_trigger(pwm, NRF_PWM_TASK_SEQSTART0);
// blocking wait for sequence complete
while( !nrf_pwm_event_check(pwm, NRF_PWM_EVENT_SEQEND0) ) {}
while (!nrf_pwm_event_check(pwm, NRF_PWM_EVENT_SEQEND0)) {}
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQEND0);
}
#endif
#ifdef LED_APA102
@@ -453,8 +569,7 @@ void neopixel_write (uint8_t *pixels)
static uint8_t pixels_pattern[PATTERN_SIZE() + 4];
// use SPIM1 for dotstar
void neopixel_init(void)
{
void neopixel_init(void) {
NRF_SPIM_Type* spi = NRF_SPIM1;
nrf_spim_disable(spi);
@@ -485,8 +600,7 @@ void neopixel_init(void)
neopixel_write(rgb);
}
void neopixel_teardown(void)
{
void neopixel_teardown(void) {
uint8_t rgb[3] = {0, 0, 0 };
neopixel_write(rgb);
@@ -495,8 +609,7 @@ void neopixel_teardown(void)
}
// write 3 bytes color RGB to built-in neopixel
void neopixel_write (uint8_t *pixels)
{
void neopixel_write (uint8_t *pixels) {
NRF_SPIM_Type* spi = NRF_SPIM1;
//brightness, blue, green, red
@@ -507,10 +620,10 @@ void neopixel_write (uint8_t *pixels)
pixels_pattern[3] = 0;
for (uint8_t i = 4; i < PATTERN_SIZE(); i+=4) {
pixels_pattern[i] = bbgr[0];
pixels_pattern[i+1] = bbgr[1];
pixels_pattern[i+2] = bbgr[2];
pixels_pattern[i+3] = bbgr[3];
pixels_pattern[i] = bbgr[0];
pixels_pattern[i+1] = bbgr[1];
pixels_pattern[i+2] = bbgr[2];
pixels_pattern[i+3] = bbgr[3];
}
pixels_pattern[PATTERN_SIZE()] = 0xff;
@@ -538,15 +651,13 @@ void neopixel_write (uint8_t *pixels)
#define LED_RGB_BLUE 2
#define LED_RGB_GREEN 3
void neopixel_init(void)
{
void neopixel_init(void) {
led_pwm_init(LED_RGB_RED, LED_RGB_RED_PIN);
led_pwm_init(LED_RGB_GREEN, LED_RGB_GREEN_PIN);
led_pwm_init(LED_RGB_BLUE, LED_RGB_BLUE_PIN);
}
void neopixel_teardown(void)
{
void neopixel_teardown(void) {
uint8_t rgb[3] = { 0, 0, 0 };
neopixel_write(rgb);
nrf_gpio_cfg_default(LED_RGB_RED_PIN);
@@ -555,10 +666,114 @@ void neopixel_teardown(void)
}
// write 3 bytes color to a built-in neopixel
void neopixel_write (uint8_t *pixels)
{
void neopixel_write (uint8_t *pixels) {
led_pwm_duty_cycle(LED_RGB_RED, pixels[2]);
led_pwm_duty_cycle(LED_RGB_GREEN, pixels[1]);
led_pwm_duty_cycle(LED_RGB_BLUE, pixels[0]);
}
#endif
//--------------------------------------------------------------------+
// Display controller
//--------------------------------------------------------------------+
#ifdef DISPLAY_CONTROLLER_ST7789
#define ST_CMD_DELAY 0x80 // special signifier for command lists
#define ST77XX_NOP 0x00
#define ST77XX_SWRESET 0x01
#define ST77XX_RDDID 0x04
#define ST77XX_RDDST 0x09
#define ST77XX_SLPIN 0x10
#define ST77XX_SLPOUT 0x11
#define ST77XX_PTLON 0x12
#define ST77XX_NORON 0x13
#define ST77XX_INVOFF 0x20
#define ST77XX_INVON 0x21
#define ST77XX_DISPOFF 0x28
#define ST77XX_DISPON 0x29
#define ST77XX_CASET 0x2A
#define ST77XX_RASET 0x2B
#define ST77XX_RAMWR 0x2C
#define ST77XX_RAMRD 0x2E
#define ST77XX_PTLAR 0x30
#define ST77XX_TEOFF 0x34
#define ST77XX_TEON 0x35
#define ST77XX_MADCTL 0x36
#define ST77XX_VSCSAD 0x37
#define ST77XX_COLMOD 0x3A
#define ST77XX_MADCTL_MY 0x80
#define ST77XX_MADCTL_MX 0x40
#define ST77XX_MADCTL_MV 0x20
#define ST77XX_MADCTL_ML 0x10
#define ST77XX_MADCTL_RGB 0x00
#define ST77XX_RDID1 0xDA
#define ST77XX_RDID2 0xDB
#define ST77XX_RDID3 0xDC
#define ST77XX_RDID4 0xDD
// Some ready-made 16-bit ('565') color settings:
#define ST77XX_BLACK 0x0000
#define ST77XX_WHITE 0xFFFF
#define ST77XX_RED 0xF800
#define ST77XX_GREEN 0x07E0
#define ST77XX_BLUE 0x001F
#define ST77XX_CYAN 0x07FF
#define ST77XX_MAGENTA 0xF81F
#define ST77XX_YELLOW 0xFFE0
#define ST77XX_ORANGE 0xFC00
static void tft_controller_init(void) {
// Init commands for 7789 screens
uint8_t cmdinit_st7789[] = {
#if !defined(DISPLAY_PIN_RST) || (DISPLAY_PIN_RST < 0)
// Software reset if rst pin not available, no args, w/delay ~150 ms delay
ST77XX_SWRESET, ST_CMD_DELAY, 150,
#endif
// Out of sleep mode, no args, w/delay 10 ms delay
ST77XX_SLPOUT, ST_CMD_DELAY, 10,
// Set color mode, 1 arg + delay: 16-bit color, 10 ms delay
ST77XX_COLMOD, 1 + ST_CMD_DELAY, 0x55, 10,
// Mem access ctrl (directions), 1 arg: Row/col addr, bottom-top refresh
ST77XX_MADCTL, 1, DISPLAY_MADCTL,
// Vertical Scroll Start Address of RAM
// ST77XX_VSCSAD, 2, DISPLAY_VSCSAD >> 8, DISPLAY_VSCSAD & 0xFF,
// Column addr set, 4 args, no delay: XSTART = 0, XEND = 240
ST77XX_CASET, 4, 0x00, 0, 0, 240,
// Row addr set, 4 args, no delay: YSTART = 0 YEND = 320
ST77XX_RASET, 4, 0x00, 0, 320 >> 8, 320 & 0xFF,
// Inversion on
ST77XX_INVON, ST_CMD_DELAY, 10,
// Normal display on, no args, w/delay 10 ms delay
ST77XX_NORON, ST_CMD_DELAY, 10,
// Main screen turn on, no args, delay 10 ms delay
ST77XX_DISPON, ST_CMD_DELAY, 10
};
size_t count = 0;
while (count < sizeof(cmdinit_st7789)) {
uint8_t const cmd = cmdinit_st7789[count++];
uint8_t const cmd_arg = cmdinit_st7789[count++];
uint8_t const has_delay = cmd_arg & ST_CMD_DELAY;
uint8_t const narg = cmd_arg & ~ST_CMD_DELAY;
tft_cmd(cmd, cmdinit_st7789 + count, narg);
count += narg;
if (has_delay) {
uint16_t delay = (uint16_t) cmdinit_st7789[count++];
if (delay == 255) {
delay = 500; // If 255, delay for 500 ms
}
NRFX_DELAY_MS(delay);
}
}
}
#endif
+10
View File
@@ -114,6 +114,16 @@ bool button_pressed(uint32_t pin);
bool is_ota(void);
//--------------------------------------------------------------------+
// Display
//--------------------------------------------------------------------+
#ifdef DISPLAY_PIN_SCK
void board_display_init(void);
void board_display_teardown(void);
void board_display_draw_line(uint16_t y, uint8_t const* buf, size_t nbytes);
void screen_draw_drag(void);
#endif
//--------------------------------------------------------------------+
// DEBUG
//--------------------------------------------------------------------+
+1 -1
View File
@@ -19,7 +19,7 @@ const uint32_t bootloaderConfig[] =
/* CF2 END */
};
void board_init_extra(void)
void board_init2(void)
{
// Turn LDO on
nrf_gpio_cfg_output(LDO_CONTROL_PIN);
@@ -0,0 +1 @@
set(MCU_VARIANT nrf52840)
+1
View File
@@ -0,0 +1 @@
set(MCU_VARIANT nrf52840)
+26
View File
@@ -46,6 +46,32 @@
#define BUTTON_2 _PINNUM(1, 10) // right button
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
//--------------------------------------------------------------------+
// Display
//--------------------------------------------------------------------+
#define DISPLAY_CONTROLLER_ST7789
#define DISPLAY_PIN_SCK _PINNUM(0, 14)
#define DISPLAY_PIN_MOSI _PINNUM(0, 15)
#define DISPLAY_PIN_CS _PINNUM(0, 12)
#define DISPLAY_PIN_DC _PINNUM(0, 13)
#define DISPLAY_PIN_RST _PINNUM(1, 3)
#define DISPLAY_PIN_BL _PINNUM(1, 5)
#define DISPLAY_BL_ON 1 // GPIO state to enable back light
#define DISPLAY_WIDTH 240
#define DISPLAY_HEIGHT 240
#define DISPLAY_COL_OFFSET 0
#define DISPLAY_ROW_OFFSET 80
// Memory Data Access Control & // Vertical Scroll Start Address
#define DISPLAY_MADCTL (TFT_MADCTL_MY)
#define DISPLAY_VSCSAD 0
#define DISPLAY_TITLE "CLUE"
//--------------------------------------------------------------------+
// BLE OTA
//--------------------------------------------------------------------+
@@ -0,0 +1 @@
set(MCU_VARIANT nrf52840)
@@ -0,0 +1 @@
set(MCU_VARIANT nrf52840)
@@ -0,0 +1,100 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 Ha Thach 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.
*/
#ifndef _FEATHER_NRF52840_SENSE_TFT_H
#define _FEATHER_NRF52840_SENSE_TFT_H
#define _PINNUM(port, pin) ((port)*32 + (pin))
/*------------------------------------------------------------------*/
/* LED
*------------------------------------------------------------------*/
#define LEDS_NUMBER 1
#define LED_PRIMARY_PIN _PINNUM(0, 11)
#define LED_STATE_ON 1
#define LED_NEOPIXEL _PINNUM(1, 8)
#define NEOPIXEL_POWER_PIN _PINNUM(1, 2)
#define NEOPIXELS_NUMBER 1
#define BOARD_RGB_BRIGHTNESS 0x040404
/*------------------------------------------------------------------*/
/* BUTTON
*------------------------------------------------------------------*/
#define BUTTONS_NUMBER 2
#define BUTTON_1 _PINNUM(1, 6)
#define BUTTON_2 _PINNUM(1, 10) // DFU pin
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
//--------------------------------------------------------------------+
// Display
//--------------------------------------------------------------------+
// VSensor required to power the display
#define DISPLAY_VSENSOR_PIN _PINNUM(1, 7)
#define DISPLAY_VSENSOR_ON 1
#define DISPLAY_CONTROLLER_ST7789
#define DISPLAY_PIN_SCK _PINNUM(0, 26)
#define DISPLAY_PIN_MOSI _PINNUM(0, 5)
#define DISPLAY_PIN_CS _PINNUM(1, 5)
#define DISPLAY_PIN_DC _PINNUM(1, 1)
#define DISPLAY_PIN_RST _PINNUM(1, 3)
#define DISPLAY_PIN_BL _PINNUM(0, 27)
#define DISPLAY_BL_ON 1 // GPIO state to enable back light
#define DISPLAY_WIDTH 240
#define DISPLAY_HEIGHT 135
#define DISPLAY_COL_OFFSET 53
#define DISPLAY_ROW_OFFSET 40
// Memory Data Access Control & // Vertical Scroll Start Address
#define DISPLAY_MADCTL (TFT_MADCTL_MX)
#define DISPLAY_VSCSAD 0
#define DISPLAY_TITLE "Sense TFT"
//--------------------------------------------------------------------+
// BLE OTA
//--------------------------------------------------------------------+
#define BLEDIS_MANUFACTURER "Adafruit Industries"
#define BLEDIS_MODEL "Feather nRF52840 Sense TFT"
//--------------------------------------------------------------------+
// USB
//--------------------------------------------------------------------+
#define USB_DESC_VID 0x239A
#define USB_DESC_UF2_PID 0x0087
#define USB_DESC_CDC_ONLY_PID 0x0088
//------------- UF2 -------------//
#define UF2_PRODUCT_NAME "Adafruit Feather nRF52840 Sense TFT"
#define UF2_VOLUME_LABEL "SENSTFTBOOT"
#define UF2_BOARD_ID "nRF52840-FeatherSenseTFT-revA"
#define UF2_INDEX_URL "https://www.adafruit.com/product/"
#endif
@@ -0,0 +1 @@
MCU_SUB_VARIANT = nrf52840
@@ -0,0 +1,19 @@
#include "boards.h"
#include "uf2/configkeys.h"
__attribute__((used, section(".bootloaderConfig")))
const uint32_t bootloaderConfig[] =
{
/* CF2 START */
CFG_MAGIC0, CFG_MAGIC1, // magic
5, 100, // used entries, total entries
204, 0x100000, // FLASH_BYTES = 0x100000
205, 0x40000, // RAM_BYTES = 0x40000
208, (USB_DESC_VID << 16) | USB_DESC_UF2_PID, // BOOTLOADER_BOARD_ID = USB VID+PID, used for verification when updating bootloader via uf2
209, 0xada52840, // UF2_FAMILY = 0xada52840
210, 0x20, // PINS_PORT_SIZE = PA_32
0, 0, 0, 0, 0, 0, 0, 0
/* CF2 END */
};
+6 -1
View File
@@ -43,9 +43,14 @@
*------------------------------------------------------------------*/
#define BUTTONS_NUMBER 2
#define BUTTON_1 _PINNUM(0, 27)
#define BUTTON_2 _PINNUM(1, 7)
#define BUTTON_2 _PINNUM(0, 19) // ESC
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
/*------------------------------------------------------------------*/
/* On board regulator control
*------------------------------------------------------------------*/
#define LDO_CONTROL_PIN _PINNUM(0, 28) // Enables external pwr
//--------------------------------------------------------------------+
// BLE OTA
//--------------------------------------------------------------------+
+38
View File
@@ -1,4 +1,5 @@
#include "boards.h"
#include "board.h"
#include "uf2/configkeys.h"
__attribute__((used, section(".bootloaderConfig")))
@@ -17,3 +18,40 @@ const uint32_t bootloaderConfig[] =
0, 0, 0, 0, 0, 0, 0, 0
/* CF2 END */
};
static void power_on(void)
{
// Turn on the regulator
nrf_gpio_cfg_output(LDO_CONTROL_PIN);
nrf_gpio_pin_write(LDO_CONTROL_PIN, 1);
}
void board_init2(void)
{
power_on();
// configure P0.05 for ESC/BUTTON_2
// P0.05 --- |<- --- / --- P0.19
// diode sw(esc)
// mode: output, push-pull, low
nrf_gpio_cfg(
_PINNUM(0, 5),
NRF_GPIO_PIN_DIR_OUTPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_NOPULL,
NRF_GPIO_PIN_H0D1,
NRF_GPIO_PIN_NOSENSE
);
nrf_gpio_pin_write(_PINNUM(0, 5), 0);
// Wait the buttons stable.
// This is mandatory, or the keyboard will enter bootloader whenever
// booted by pressing the button at back (same with BUTTON_1)
NRFX_DELAY_MS(300);
}
void board_teardown2(void)
{
// re-enable the battery
power_on();
}
+71
View File
@@ -0,0 +1,71 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Yihui Xiong for Makerdiary
*
* 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.
*/
#ifndef _MAKERDIARY_NRF82540_CONNECT_KIT_H_
#define _MAKERDIARY_NRF82540_CONNECT_KIT_H_
#define _PINNUM(port, pin) ((port)*32 + (pin))
/*------------------------------------------------------------------*/
/* LED
*------------------------------------------------------------------*/
#define LEDS_NUMBER 1
#define LED_PRIMARY_PIN _PINNUM(1, 15) // Green
#define LED_STATE_ON 0
#define LED_RGB_RED_PIN _PINNUM(1, 10)
#define LED_RGB_GREEN_PIN _PINNUM(1, 11)
#define LED_RGB_BLUE_PIN _PINNUM(1, 12)
#define BOARD_RGB_BRIGHTNESS 0x404040
/*------------------------------------------------------------------*/
/* BUTTON
*------------------------------------------------------------------*/
#define BUTTONS_NUMBER 2
#define BUTTON_1 _PINNUM(1, 0) // P1.00: User Button
#define BUTTON_2 _PINNUM(1, 7) // P1.07: NC
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
//--------------------------------------------------------------------+
// BLE OTA
//--------------------------------------------------------------------+
#define BLEDIS_MANUFACTURER "Makerdiary"
#define BLEDIS_MODEL "nRF52840 Connect Kit"
//--------------------------------------------------------------------+
// USB
//--------------------------------------------------------------------+
#define USB_DESC_VID 0x2886
#define USB_DESC_UF2_PID 0xF00F
#define USB_DESC_CDC_ONLY_PID 0xF00F
//--------------------------------------------------------------------+
// UF2
//--------------------------------------------------------------------+
#define UF2_PRODUCT_NAME "nRF52840 Connect Kit"
#define UF2_VOLUME_LABEL "CONNECTKIT"
#define UF2_BOARD_ID "nRF52840-Connect-Kit"
#define UF2_INDEX_URL "https://wiki.makerdiary.com/nrf52840-connectkit/"
#endif /* _MAKERDIARY_NRF82540_CONNECT_KIT_H_ */
+2
View File
@@ -0,0 +1,2 @@
MCU_SUB_VARIANT = nrf52840
USE_NFCT = yes
@@ -0,0 +1,19 @@
#include "boards.h"
#include "uf2/configkeys.h"
__attribute__((used, section(".bootloaderConfig")))
const uint32_t bootloaderConfig[] =
{
/* CF2 START */
CFG_MAGIC0, CFG_MAGIC1, // magic
5, 100, // used entries, total entries
204, 0x100000, // FLASH_BYTES = 0x100000
205, 0x40000, // RAM_BYTES = 0x40000
208, (USB_DESC_VID << 16) | USB_DESC_UF2_PID, // BOOTLOADER_BOARD_ID = USB VID+PID, used for verification when updating bootloader via uf2
209, 0xada52840, // UF2_FAMILY = 0xada52840
210, 0x20, // PINS_PORT_SIZE = PA_32
0, 0, 0, 0, 0, 0, 0, 0
/* CF2 END */
};
+1
View File
@@ -0,0 +1 @@
set(MCU_VARIANT nrf52840)
+65
View File
@@ -0,0 +1,65 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2022 Kyle McCreery
*
* 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.
*/
#ifndef _PillBug_H
#define _PillBug_H
#define _PINNUM(port, pin) ((port)*32 + (pin))
#define UICR_REGOUT0_VALUE UICR_REGOUT0_VOUT_3V3
/*------------------------------------------------------------------*/
/* LED
*------------------------------------------------------------------*/
#define LEDS_NUMBER 1
#define LED_PRIMARY_PIN _PINNUM(0, 20) // Blue
#define LED_STATE_ON 1
/*------------------------------------------------------------------*/
/* BUTTON
*------------------------------------------------------------------*/
#define BUTTONS_NUMBER 2 // none connected at all
#define BUTTON_1 _PINNUM(0, 18) // unusable: RESET
#define BUTTON_2 _PINNUM(0, 21) // no connection
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
//--------------------------------------------------------------------+
// BLE OTA
//--------------------------------------------------------------------+
#define BLEDIS_MANUFACTURER "MechWild"
#define BLEDIS_MODEL "PillBug"
//--------------------------------------------------------------------+
// USB
//--------------------------------------------------------------------+
#define USB_DESC_VID 0x16D0
#define USB_DESC_UF2_PID 0x10ED
#define USB_DESC_CDC_ONLY_PID 0x10ED
#define UF2_PRODUCT_NAME "PillBug"
#define UF2_VOLUME_LABEL "PillBug"
#define UF2_BOARD_ID "nRF52840-PillBug"
#define UF2_INDEX_URL "https://mechwild.com"
#endif // _PillBug_H
+1
View File
@@ -0,0 +1 @@
MCU_SUB_VARIANT = nrf52840
+19
View File
@@ -0,0 +1,19 @@
#include "boards.h"
#include "uf2/configkeys.h"
__attribute__((used, section(".bootloaderConfig")))
const uint32_t bootloaderConfig[] =
{
/* CF2 START */
CFG_MAGIC0, CFG_MAGIC1, // magic
5, 100, // used entries, total entries
204, 0x100000, // FLASH_BYTES = 0x100000
205, 0x40000, // RAM_BYTES = 0x40000
208, (USB_DESC_VID << 16) | USB_DESC_UF2_PID, // BOOTLOADER_BOARD_ID = USB VID+PID, used for verification when updating bootloader via uf2
209, 0xada52840, // UF2_FAMILY = 0xada52840
210, 0x20, // PINS_PORT_SIZE = PA_32
0, 0, 0, 0, 0, 0, 0, 0
/* CF2 END */
};
+68
View File
@@ -0,0 +1,68 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 Ha Thach 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.
*/
#ifndef _XIAO_BLE
#define _XIAO_BLE
#define _PINNUM(port, pin) ((port)*32 + (pin))
/*------------------------------------------------------------------*/
/* LED
*------------------------------------------------------------------*/
// The board has 3 leds, but changing the number here causes OTA issues.
#define LEDS_NUMBER 1
#define LED_PRIMARY_PIN _PINNUM(0, 26)
#define LED_STATE_ON 0
#define NEOPIXELS_NUMBER 0
/*------------------------------------------------------------------*/
/* BUTTON
*------------------------------------------------------------------*/
#define BUTTONS_NUMBER 2
#define BUTTON_1 _PINNUM(0, 18)
// Button 2 is defined as D1 from expansion board.
#define BUTTON_2 _PINNUM(0, 3)
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
//--------------------------------------------------------------------+
// BLE OTA
//--------------------------------------------------------------------+
#define BLEDIS_MANUFACTURER "Seeed"
#define BLEDIS_MODEL "XIAO nRF52840"
//--------------------------------------------------------------------+
// USB
//--------------------------------------------------------------------+
#define USB_DESC_VID 0x2886
#define USB_DESC_UF2_PID 0x0044
#define USB_DESC_CDC_ONLY_PID 0x0044
//------------- UF2 -------------//
#define UF2_PRODUCT_NAME "Seeed XIAO nRF52840"
#define UF2_VOLUME_LABEL "XIAO-BOOT"
#define UF2_BOARD_ID "nRF52840-SeeedXiao-v1"
#define UF2_INDEX_URL "https://www.seeedstudio.com/"
#endif // _XIAO_BLE
+2
View File
@@ -0,0 +1,2 @@
MCU_SUB_VARIANT = nrf52840
SD_VERSION = 7.3.0
+19
View File
@@ -0,0 +1,19 @@
#include "boards.h"
#include "uf2/configkeys.h"
__attribute__((used, section(".bootloaderConfig")))
const uint32_t bootloaderConfig[] =
{
/* CF2 START */
CFG_MAGIC0, CFG_MAGIC1, // magic
5, 100, // used entries, total entries
204, 0x100000, // FLASH_BYTES = 0x100000
205, 0x40000, // RAM_BYTES = 0x40000
208, (USB_DESC_VID << 16) | USB_DESC_UF2_PID, // BOOTLOADER_BOARD_ID = USB VID+PID, used for verification when updating bootloader via uf2
209, 0xada52840, // UF2_FAMILY = 0xada52840
210, 0x20, // PINS_PORT_SIZE = PA_32
0, 0, 0, 0, 0, 0, 0, 0
/* CF2 END */
};
@@ -0,0 +1,68 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 Ha Thach 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.
*/
#ifndef _XIAO_BLE_SENSE
#define _XIAO_BLE_SENSE
#define _PINNUM(port, pin) ((port)*32 + (pin))
/*------------------------------------------------------------------*/
/* LED
*------------------------------------------------------------------*/
// The board has 3 leds, but changing the number here causes OTA issues.
#define LEDS_NUMBER 1
#define LED_PRIMARY_PIN _PINNUM(0, 26)
#define LED_STATE_ON 0
#define NEOPIXELS_NUMBER 0
/*------------------------------------------------------------------*/
/* BUTTON
*------------------------------------------------------------------*/
#define BUTTONS_NUMBER 2
#define BUTTON_1 _PINNUM(0, 18)
// Button 2 is defined as D1 from expansion board.
#define BUTTON_2 _PINNUM(0, 3)
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
//--------------------------------------------------------------------+
// BLE OTA
//--------------------------------------------------------------------+
#define BLEDIS_MANUFACTURER "Seeed"
#define BLEDIS_MODEL "XIAO nRF52840 Sense"
//--------------------------------------------------------------------+
// USB
//--------------------------------------------------------------------+
#define USB_DESC_VID 0x2886
#define USB_DESC_UF2_PID 0x0045
#define USB_DESC_CDC_ONLY_PID 0x0045
//------------- UF2 -------------//
#define UF2_PRODUCT_NAME "Seeed XIAO nRF52840"
#define UF2_VOLUME_LABEL "XIAO-SENSE"
#define UF2_BOARD_ID "nRF52840-SeeedXiaoSense-v1"
#define UF2_INDEX_URL "https://www.seeedstudio.com/"
#endif // _XIAO_BLE_SENSE
@@ -0,0 +1,2 @@
MCU_SUB_VARIANT = nrf52840
SD_VERSION = 7.3.0
@@ -0,0 +1,19 @@
#include "boards.h"
#include "uf2/configkeys.h"
__attribute__((used, section(".bootloaderConfig")))
const uint32_t bootloaderConfig[] =
{
/* CF2 START */
CFG_MAGIC0, CFG_MAGIC1, // magic
5, 100, // used entries, total entries
204, 0x100000, // FLASH_BYTES = 0x100000
205, 0x40000, // RAM_BYTES = 0x40000
208, (USB_DESC_VID << 16) | USB_DESC_UF2_PID, // BOOTLOADER_BOARD_ID = USB VID+PID, used for verification when updating bootloader via uf2
209, 0xada52840, // UF2_FAMILY = 0xada52840
210, 0x20, // PINS_PORT_SIZE = PA_32
0, 0, 0, 0, 0, 0, 0, 0
/* CF2 END */
};
+124
View File
@@ -0,0 +1,124 @@
#include "boards.h"
#if defined(DISPLAY_PIN_SCK)
#include <stdint.h>
// all https://makecode.com/_VrfEKzV4xfvq
// https://makecode.com/_7VxXm3JMPXfM - file
// https://makecode.com/_LuEUCsPEKUbs - download
const uint8_t fileLogo[] = {
32, 32, 71, 140, 201, 151, 1, 2, 146, 1, 2, 146, 63, 2, 151, 9, 153, 9, 153, 9, 146, 1, 9, 146, 3, 9, 146, 7, 9, 137, 205, 72, 140, 206, 36, 139, 207, 18, 138, 206, 36, 139, 205, 72, 149, 7, 9, 146, 3, 9, 146, 1, 9, 153, 9, 153, 9, 153, 9, 148, 63, 2, 146, 1, 2, 146, 1, 2, 146, 201, 191, 191, 191, 174
};
// https://makecode.com/_9b0RcK5yRa12
const uint8_t pendriveLogo[] = {
32, 32, 59, 137, 215, 137, 1, 143, 1, 8, 146, 203, 149, 3, 8, 146, 3, 8, 146, 115, 8, 146, 115, 8, 146, 3, 8, 146, 3, 8, 146, 115, 8, 146, 115, 8, 146, 3, 8, 146, 3, 8, 146, 203, 149, 1, 8, 146, 1, 8, 146, 1, 120, 211, 191, 191, 191, 191, 191, 191, 191, 135
};
// https://makecode.com/_TTqbj705L4mr
const uint8_t arrowLogo[] = {
32, 32, 54, 137, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 146, 211, 142, 209, 144, 207, 146, 205, 148, 203, 150, 201, 152, 199, 154, 31, 154, 7, 154, 1, 191, 191, 191, 175
};
const uint8_t font8[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5e, 0x00, 0x00, 0x00,
0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00,
0x28, 0xfe, 0x28, 0xfe, 0x28, 0x00,
0x4c, 0x92, 0xff, 0x92, 0x64, 0x00,
0x02, 0x65, 0x12, 0x48, 0xa6, 0x40,
0x6c, 0x92, 0x92, 0x6c, 0xa0, 0x00,
0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7c, 0x82, 0x00, 0x00,
0x00, 0x00, 0x82, 0x7c, 0x00, 0x00,
0x54, 0x38, 0x10, 0x38, 0x54, 0x00,
0x10, 0x10, 0x7c, 0x10, 0x10, 0x00,
0x00, 0x00, 0x90, 0x70, 0x00, 0x00,
0x10, 0x10, 0x10, 0x10, 0x10, 0x00,
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
0x00, 0x60, 0x10, 0x08, 0x06, 0x00,
0x00, 0x3c, 0x42, 0x42, 0x3c, 0x00,
0x00, 0x44, 0x7e, 0x40, 0x00, 0x00,
0x00, 0x44, 0x62, 0x52, 0x4c, 0x00,
0x00, 0x42, 0x4a, 0x4e, 0x32, 0x00,
0x30, 0x28, 0x24, 0x7e, 0x20, 0x00,
0x00, 0x4e, 0x4a, 0x4a, 0x32, 0x00,
0x00, 0x3c, 0x4a, 0x4a, 0x30, 0x00,
0x00, 0x02, 0x62, 0x12, 0x0e, 0x00,
0x00, 0x34, 0x4a, 0x4a, 0x34, 0x00,
0x00, 0x0c, 0x52, 0x52, 0x3c, 0x00,
0x00, 0x00, 0x6c, 0x6c, 0x00, 0x00,
0x00, 0x00, 0x96, 0x76, 0x00, 0x00,
0x10, 0x28, 0x28, 0x44, 0x44, 0x00,
0x28, 0x28, 0x28, 0x28, 0x28, 0x00,
0x44, 0x44, 0x28, 0x28, 0x10, 0x00,
0x00, 0x02, 0x59, 0x09, 0x06, 0x00,
0x3c, 0x42, 0x5a, 0x56, 0x08, 0x00,
0x78, 0x14, 0x12, 0x14, 0x78, 0x00,
0x7e, 0x4a, 0x4a, 0x4a, 0x34, 0x00,
0x00, 0x3c, 0x42, 0x42, 0x24, 0x00,
0x00, 0x7e, 0x42, 0x42, 0x3c, 0x00,
0x00, 0x7e, 0x4a, 0x4a, 0x42, 0x00,
0x00, 0x7e, 0x0a, 0x0a, 0x02, 0x00,
0x00, 0x3c, 0x42, 0x52, 0x34, 0x00,
0x00, 0x7e, 0x08, 0x08, 0x7e, 0x00,
0x00, 0x42, 0x7e, 0x42, 0x00, 0x00,
0x20, 0x40, 0x42, 0x3e, 0x02, 0x00,
0x00, 0x7e, 0x08, 0x14, 0x62, 0x00,
0x00, 0x7e, 0x40, 0x40, 0x40, 0x00,
0x7e, 0x04, 0x18, 0x04, 0x7e, 0x00,
0x00, 0x7e, 0x04, 0x08, 0x7e, 0x00,
0x3c, 0x42, 0x42, 0x42, 0x3c, 0x00,
0x00, 0x7e, 0x12, 0x12, 0x0c, 0x00,
0x00, 0x3c, 0x52, 0x62, 0xbc, 0x00,
0x00, 0x7e, 0x12, 0x12, 0x6c, 0x00,
0x00, 0x24, 0x4a, 0x52, 0x24, 0x00,
0x02, 0x02, 0x7e, 0x02, 0x02, 0x00,
0x00, 0x3e, 0x40, 0x40, 0x3e, 0x00,
0x00, 0x1e, 0x70, 0x70, 0x1e, 0x00,
0x7e, 0x20, 0x18, 0x20, 0x7e, 0x00,
0x42, 0x24, 0x18, 0x24, 0x42, 0x00,
0x06, 0x08, 0x70, 0x08, 0x06, 0x00,
0x00, 0x62, 0x52, 0x4a, 0x46, 0x00,
0x00, 0x7e, 0x42, 0x42, 0x00, 0x00,
0x00, 0x06, 0x08, 0x10, 0x60, 0x00,
0x00, 0x42, 0x42, 0x7e, 0x00, 0x00,
0x08, 0x04, 0x02, 0x04, 0x08, 0x00,
0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
0x00, 0x00, 0x02, 0x04, 0x00, 0x00,
0x00, 0x30, 0x48, 0x48, 0x78, 0x00,
0x00, 0x7e, 0x48, 0x48, 0x30, 0x00,
0x00, 0x30, 0x48, 0x48, 0x48, 0x00,
0x00, 0x30, 0x48, 0x48, 0x7e, 0x00,
0x00, 0x30, 0x68, 0x58, 0x50, 0x00,
0x00, 0x10, 0x7c, 0x12, 0x04, 0x00,
0x00, 0x18, 0xa4, 0xa4, 0x78, 0x00,
0x00, 0x7e, 0x08, 0x08, 0x70, 0x00,
0x00, 0x48, 0x7a, 0x40, 0x00, 0x00,
0x00, 0x40, 0x84, 0x7d, 0x00, 0x00,
0x00, 0x7e, 0x10, 0x28, 0x40, 0x00,
0x00, 0x42, 0x7e, 0x40, 0x00, 0x00,
0x78, 0x08, 0x30, 0x08, 0x70, 0x00,
0x00, 0x78, 0x08, 0x08, 0x70, 0x00,
0x00, 0x30, 0x48, 0x48, 0x30, 0x00,
0x00, 0xfc, 0x24, 0x24, 0x18, 0x00,
0x00, 0x18, 0x24, 0x24, 0xfc, 0x00,
0x00, 0x78, 0x10, 0x08, 0x10, 0x00,
0x00, 0x50, 0x58, 0x68, 0x28, 0x00,
0x00, 0x08, 0x3e, 0x48, 0x20, 0x00,
0x00, 0x38, 0x40, 0x40, 0x78, 0x00,
0x00, 0x18, 0x60, 0x60, 0x18, 0x00,
0x38, 0x40, 0x30, 0x40, 0x38, 0x00,
0x00, 0x48, 0x30, 0x30, 0x48, 0x00,
0x00, 0x5c, 0xa0, 0xa0, 0x7c, 0x00,
0x00, 0x48, 0x68, 0x58, 0x48, 0x00,
0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
0x00, 0x00, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
0x00, 0x08, 0x04, 0x08, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
#endif
+61 -115
View File
@@ -68,6 +68,7 @@
#include "nrfx_nvmc.h"
#ifdef NRF_USBD
#include "uf2/uf2.h"
#include "nrf_usbd.h"
#include "tusb.h"
@@ -80,16 +81,11 @@ void usb_teardown(void);
extern void tusb_hal_nrf_power_event(uint32_t event);
#else
#define usb_init(x) led_state(STATE_USB_MOUNTED) // mark nrf52832 as mounted
#define usb_teardown()
#endif
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
/*
* Blinking patterns:
* - DFU Serial : LED Status blink
@@ -131,21 +127,22 @@ extern void tusb_hal_nrf_power_event(uint32_t event);
// These value must be the same with one in dfu_transport_ble.c
#define BLEGAP_EVENT_LENGTH 6
#define BLEGATT_ATT_MTU_MAX 247
enum { BLE_CONN_CFG_HIGH_BANDWIDTH = 1 };
#define BLEGATT_ATT_MTU_MAX 23
enum {
BLE_CONN_CFG_HIGH_BANDWIDTH = 1
};
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
uint32_t* dbl_reset_mem = ((uint32_t*) DFU_DBL_RESET_MEM );
uint32_t* dbl_reset_mem = ((uint32_t*) DFU_DBL_RESET_MEM);
// true if ble, false if serial
bool _ota_dfu = false;
bool _ota_connected = false;
bool _sd_inited = false;
bool is_ota(void)
{
bool is_ota(void) {
return _ota_dfu;
}
@@ -154,18 +151,16 @@ static uint32_t ble_stack_init(void);
// The SoftDevice must only be initialized if a chip reset has occurred.
// Soft reset (jump ) from application must not reinitialize the SoftDevice.
static void mbr_init_sd(void)
{
static void mbr_init_sd(void) {
PRINTF("SD_MBR_COMMAND_INIT_SD\r\n");
sd_mbr_command_t com = { .command = SD_MBR_COMMAND_INIT_SD };
sd_mbr_command_t com = {.command = SD_MBR_COMMAND_INIT_SD};
sd_mbr_command(&com);
}
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
int main(void)
{
int main(void) {
// Populate Boot Address and MBR Param into MBR if not already
// MBR_BOOTLOADER_ADDR/MBR_PARAM_PAGE_ADDR are used if available, else UICR registers are used
// Note: skip it for now since this will prevent us to change the size of bootloader in the future
@@ -177,14 +172,11 @@ int main(void)
board_init();
bootloader_init();
PRINTF("Bootloader Start\r\n");
led_state(STATE_BOOTLOADER_STARTED);
// When updating SoftDevice, bootloader will reset before swapping SD
if (bootloader_dfu_sd_in_progress())
{
if (bootloader_dfu_sd_in_progress()) {
led_state(STATE_WRITING_STARTED);
bootloader_dfu_sd_update_continue();
@@ -207,14 +199,11 @@ int main(void)
* - sd_softdevice_vector_table_base_set(APP_ADDR)
* - jump to App reset
*/
if (bootloader_app_is_valid() && !bootloader_dfu_sd_in_progress())
{
if (bootloader_app_is_valid() && !bootloader_dfu_sd_in_progress()) {
PRINTF("App is valid\r\n");
if ( is_sd_existed() )
{
if (is_sd_existed()) {
// MBR forward IRQ to SD (if not already)
if ( !_sd_inited ) mbr_init_sd();
if (!_sd_inited) mbr_init_sd();
// Make sure SD is disabled
sd_softdevice_disable();
@@ -230,8 +219,7 @@ int main(void)
NVIC_SystemReset();
}
static void check_dfu_mode(void)
{
static void check_dfu_mode(void) {
uint32_t const gpregret = NRF_POWER->GPREGRET;
// SD is already Initialized in case of BOOTLOADER_DFU_OTA_MAGIC
@@ -249,7 +237,7 @@ static void check_dfu_mode(void)
// start either serial, uf2 or ble
bool dfu_start = _ota_dfu || serial_only_dfu || uf2_dfu ||
(((*dbl_reset_mem) == DFU_DBL_RESET_MAGIC) && reason_reset_pin);
(((*dbl_reset_mem) == DFU_DBL_RESET_MAGIC) && reason_reset_pin);
// Clear GPREGRET if it is our values
if (dfu_start || dfu_skip) NRF_POWER->GPREGRET = 0;
@@ -262,7 +250,7 @@ static void check_dfu_mode(void)
dfu_start = dfu_start || button_pressed(BUTTON_DFU);
// DFU + FRESET are pressed --> OTA
_ota_dfu = _ota_dfu || ( button_pressed(BUTTON_DFU) && button_pressed(BUTTON_FRESET) ) ;
_ota_dfu = _ota_dfu || (button_pressed(BUTTON_DFU) && button_pressed(BUTTON_FRESET));
bool const valid_app = bootloader_app_is_valid();
bool const just_start_app = valid_app && !dfu_start && (*dbl_reset_mem) == DFU_DBL_RESET_APP;
@@ -270,8 +258,7 @@ static void check_dfu_mode(void)
if (!just_start_app && APP_ASKS_FOR_SINGLE_TAP_RESET()) dfu_start = 1;
// App mode: Double Reset detection or DFU startup for nrf52832
if ( ! (just_start_app || dfu_start || !valid_app) )
{
if (!(just_start_app || dfu_start || !valid_app)) {
#ifdef NRF52832_XXAA
/* Even DFU is not active, we still force an 1000 ms dfu serial mode when startup
* to support auto programming from Arduino IDE
@@ -281,8 +268,7 @@ static void check_dfu_mode(void)
bootloader_dfu_start(false, DFU_SERIAL_STARTUP_INTERVAL, false);
#else
// Note: RESETREAS is not clear by bootloader, it should be cleared by application upon init()
if (reason_reset_pin)
{
if (reason_reset_pin) {
// Register our first reset for double reset detection
(*dbl_reset_mem) = DFU_DBL_RESET_MAGIC;
@@ -292,77 +278,59 @@ static void check_dfu_mode(void)
#endif
}
if (APP_ASKS_FOR_SINGLE_TAP_RESET())
{
if (APP_ASKS_FOR_SINGLE_TAP_RESET()) {
(*dbl_reset_mem) = DFU_DBL_RESET_APP;
}
else
{
} else {
(*dbl_reset_mem) = 0;
}
// Enter DFU mode accordingly to input
if ( dfu_start || !valid_app )
{
if ( _ota_dfu )
{
if (dfu_start || !valid_app) {
if (_ota_dfu) {
led_state(STATE_BLE_DISCONNECTED);
if (!_sd_inited ) mbr_init_sd();
if (!_sd_inited) mbr_init_sd();
_sd_inited = true;
ble_stack_init();
}
else
{
} else {
led_state(STATE_USB_UNMOUNTED);
usb_init(serial_only_dfu);
}
// Initiate an update of the firmware.
if (APP_ASKS_FOR_SINGLE_TAP_RESET() || uf2_dfu || serial_only_dfu)
{
if (APP_ASKS_FOR_SINGLE_TAP_RESET() || uf2_dfu || serial_only_dfu) {
// If USB is not enumerated in 3s (eg. because we're running on battery), we restart into app.
bootloader_dfu_start(_ota_dfu, 3000, true);
}
else
{
bootloader_dfu_start(_ota_dfu, 3000, true);
} else {
// No timeout if bootloader requires user action (double-reset).
bootloader_dfu_start(_ota_dfu, 0, false);
bootloader_dfu_start(_ota_dfu, 0, false);
}
if ( _ota_dfu )
{
if (_ota_dfu) {
sd_softdevice_disable();
}else
{
} else {
usb_teardown();
}
}
}
// Initializes the SotdDevice by following SD specs section
// "Master Boot Record and SoftDevice initializaton procedure"
static uint32_t ble_stack_init(void)
{
static uint32_t ble_stack_init(void) {
// Forward vector table to bootloader address so that we can handle BLE events
sd_softdevice_vector_table_base_set(BOOTLOADER_REGION_START);
// Enable Softdevice, Use Internal OSC to compatible with all boards
nrf_clock_lf_cfg_t clock_cfg =
{
nrf_clock_lf_cfg_t clock_cfg = {
.source = NRF_CLOCK_LF_SRC_RC,
.rc_ctiv = 16,
.rc_temp_ctiv = 2,
.accuracy = NRF_CLOCK_LF_ACCURACY_250_PPM
};
sd_softdevice_enable(&clock_cfg, app_error_fault_handler);
sd_nvic_EnableIRQ(SD_EVT_IRQn);
/*------------- Configure BLE params -------------*/
extern uint32_t __data_start__[]; // defined in linker
extern uint32_t __data_start__[]; // defined in linker
uint32_t ram_start = (uint32_t) __data_start__;
ble_cfg_t blecfg;
@@ -370,9 +338,9 @@ static uint32_t ble_stack_init(void)
// Configure the maximum number of connections.
varclr(&blecfg);
blecfg.gap_cfg.role_count_cfg.adv_set_count = 1;
blecfg.gap_cfg.role_count_cfg.periph_role_count = 1;
blecfg.gap_cfg.role_count_cfg.periph_role_count = 1;
blecfg.gap_cfg.role_count_cfg.central_role_count = 0;
blecfg.gap_cfg.role_count_cfg.central_sec_count = 0;
blecfg.gap_cfg.role_count_cfg.central_sec_count = 0;
sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &blecfg, ram_start);
// NRF_DFU_BLE_REQUIRES_BONDS
@@ -389,7 +357,7 @@ static uint32_t ble_stack_init(void)
// Event Length + HVN queue + WRITE CMD queue setting affecting bandwidth
varclr(&blecfg);
blecfg.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_HIGH_BANDWIDTH;
blecfg.conn_cfg.params.gap_conn_cfg.conn_count = 1;
blecfg.conn_cfg.params.gap_conn_cfg.conn_count = 1;
blecfg.conn_cfg.params.gap_conn_cfg.event_length = BLEGAP_EVENT_LENGTH;
sd_ble_cfg_set(BLE_CONN_CFG_GAP, &blecfg, ram_start);
@@ -407,19 +375,16 @@ static uint32_t ble_stack_init(void)
return NRF_SUCCESS;
}
//--------------------------------------------------------------------+
// Error Handler
//--------------------------------------------------------------------+
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
{
volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */
if ( (*ARM_CM_DHCSR) & 1UL ) __asm("BKPT #0\n"); /* Only halt mcu if debugger is attached */
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) {
volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */
if ((*ARM_CM_DHCSR) & 1UL) __asm("BKPT #0\n"); /* Only halt mcu if debugger is attached */
NVIC_SystemReset();
}
void assert_nrf_callback (uint16_t line_num, uint8_t const * p_file_name)
{
void assert_nrf_callback(uint16_t line_num, uint8_t const* p_file_name) {
app_error_fault_handler(0xDEADBEEF, 0, 0);
}
@@ -428,9 +393,8 @@ void assert_nrf_callback (uint16_t line_num, uint8_t const * p_file_name)
*------------------------------------------------------------------*/
// Process BLE event from SD
uint32_t proc_ble(void)
{
__ALIGN(4) uint8_t ev_buf[ BLE_EVT_LEN_MAX(BLEGATT_ATT_MTU_MAX) ];
uint32_t proc_ble(void) {
__ALIGN(4) uint8_t ev_buf[BLE_EVT_LEN_MAX(BLEGATT_ATT_MTU_MAX)];
uint16_t ev_len = BLE_EVT_LEN_MAX(BLEGATT_ATT_MTU_MAX);
// Init header
@@ -441,25 +405,24 @@ uint32_t proc_ble(void)
uint32_t err = sd_ble_evt_get(ev_buf, &ev_len);
// Handle valid event, ignore error
if( NRF_SUCCESS == err)
{
switch (evt->header.evt_id)
{
if (NRF_SUCCESS == err) {
switch (evt->header.evt_id) {
case BLE_GAP_EVT_CONNECTED:
_ota_connected = true;
led_state(STATE_BLE_CONNECTED);
break;
break;
case BLE_GAP_EVT_DISCONNECTED:
_ota_connected = false;
led_state(STATE_BLE_DISCONNECTED);
break;
break;
default: break;
default:
break;
}
// from dfu_transport_ble
extern void ble_evt_dispatch(ble_evt_t * p_ble_evt);
extern void ble_evt_dispatch(ble_evt_t* p_ble_evt);
ble_evt_dispatch(evt);
}
@@ -467,68 +430,51 @@ uint32_t proc_ble(void)
}
// process SOC event from SD
uint32_t proc_soc(void)
{
uint32_t proc_soc(void) {
uint32_t soc_evt = 0;
uint32_t err = sd_evt_get(&soc_evt);
if (NRF_SUCCESS == err)
{
if (NRF_SUCCESS == err) {
pstorage_sys_event_handler(soc_evt);
#ifdef NRF_USBD
/*------------- usb power event handler -------------*/
int32_t usbevt = (soc_evt == NRF_EVT_POWER_USB_DETECTED ) ? NRFX_POWER_USB_EVT_DETECTED:
(soc_evt == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY :
(soc_evt == NRF_EVT_POWER_USB_REMOVED ) ? NRFX_POWER_USB_EVT_REMOVED : -1;
int32_t usbevt = (soc_evt == NRF_EVT_POWER_USB_DETECTED) ? NRFX_POWER_USB_EVT_DETECTED :
(soc_evt == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY :
(soc_evt == NRF_EVT_POWER_USB_REMOVED) ? NRFX_POWER_USB_EVT_REMOVED : -1;
if ( usbevt >= 0) tusb_hal_nrf_power_event((uint32_t) usbevt);
if (usbevt >= 0) tusb_hal_nrf_power_event((uint32_t) usbevt);
#endif
}
return err;
}
void proc_sd_task(void* evt_data, uint16_t evt_size)
{
void proc_sd_task(void* evt_data, uint16_t evt_size) {
(void) evt_data;
(void) evt_size;
// process BLE and SOC until there is no more events
while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) )
{
while ((NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc())) {
// nothing
}
}
void SD_EVT_IRQHandler(void)
{
void SD_EVT_IRQHandler(void) {
// Use App Scheduler to defer handling code in non-isr context
app_sched_event_put(NULL, 0, proc_sd_task);
}
//--------------------------------------------------------------------+
// RTT printf retarget for Debug
//--------------------------------------------------------------------+
#ifdef CFG_DEBUG
#include "SEGGER_RTT.h"
__attribute__ ((used))
int _write (int fhdl, const void *buf, size_t count)
{
__attribute__ ((used)) int _write (int fhdl, const void *buf, size_t count) {
(void) fhdl;
SEGGER_RTT_Write(0, (char*) buf, (int) count);
return count;
}
__attribute__ ((used))
int _read (int fhdl, char *buf, size_t count)
{
(void) fhdl;
return SEGGER_RTT_Read(0, buf, count);
}
#endif
-2
View File
@@ -18,10 +18,8 @@
// UART
#ifdef NRF52832_XXAA
#define NRFX_UART_ENABLED 1
#define NRFX_UART0_ENABLED 1
#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY 7
#define NRFX_UART_DEFAULT_CONFIG_HWFC NRF_UART_HWFC_DISABLED
#define NRFX_UART_DEFAULT_CONFIG_PARITY NRF_UART_PARITY_EXCLUDED
+266
View File
@@ -0,0 +1,266 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Ha Thach (tinyusb.org) 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 "boards.h"
#if defined(DISPLAY_PIN_SCK)
#include <string.h>
#include <stdlib.h>
// Overlap 4x chars by this much.
#define CHAR4_KERNING 3
// Width of a single 4x char, adjusted by kerning
#define CHAR4_KERNED_WIDTH (6 * 4 - CHAR4_KERNING)
#define COL0(r, g, b) ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
#define COL(c) COL0((c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff)
enum {
COLOR_BLACK = 0,
COLOR_WHITE = 1,
COLOR_RED = 2,
COLOR_PINK = 3,
COLOR_ORANGE = 4,
COLOR_YELLOW = 5,
COLOR_CYAN = 6,
COLOR_GREEN = 7,
COLOR_BLUE = 8,
COLOR_AQUA = 9,
COLOR_PURPLE = 10,
};
// 16-bit 565 color from 24-bit 888 format
const uint16_t palette[] = {
COL(0x000000), // 0
COL(0xffffff), // 1
COL(0xff2121), // 2
COL(0xff93c4), // 3
COL(0xff8135), // 4
COL(0xfff609), // 5
COL(0x249ca3), // 6
COL(0x78dc52), // 7
COL(0x003fad), // 8
COL(0x87f2ff), // 9
COL(0x8e2ec4), // 10
COL(0xa4839f), // 11
COL(0x5c406c), // 12
COL(0xe5cdc4), // 13
COL(0x91463d), // 14
COL(0x000000), // 15
};
// TODO only buffer partial screen to save SRAM
// ESP32s2 can only statically allocated DRAM up to 160KB.
// the remaining 160KB can only be allocated at runtime as heap.
static uint8_t frame_buf[DISPLAY_WIDTH * DISPLAY_HEIGHT];
//static uint8_t* frame_buf;
extern const uint8_t font8[];
extern const uint8_t fileLogo[];
extern const uint8_t pendriveLogo[];
extern const uint8_t arrowLogo[];
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
// print character with font size = 1
static void printch(int x, int y, int color, const uint8_t* fnt) {
for (int i = 0; i < 6; ++i) {
uint8_t* p = frame_buf + (x + i) * DISPLAY_HEIGHT + y;
uint8_t mask = 0x01;
for (int j = 0; j < 8; ++j) {
if (*fnt & mask) {
*p = color;
}
p++;
mask <<= 1;
}
fnt++;
}
}
// print character with font size = 4
static void printch4(int x, int y, int color, const uint8_t* fnt) {
for (int i = 0; i < 6 * 4; ++i) {
uint8_t* p = frame_buf + (x + i) * DISPLAY_HEIGHT + y;
uint8_t mask = 0x01;
for (int j = 0; j < 8; ++j) {
for (int k = 0; k < 4; ++k) {
if (*fnt & mask) {
*p = color;
}
p++;
}
mask <<= 1;
}
if ((i & 3) == 3) {
fnt++;
}
}
}
// print icon
static void printicon(int x, int y, int color, const uint8_t* icon) {
int w = *icon++;
int h = *icon++;
int sz = *icon++;
uint8_t mask = 0x80;
int runlen = 0;
int runbit = 0;
uint8_t lastb = 0x00;
for (int i = 0; i < w; ++i) {
uint8_t* p = frame_buf + (x + i) * DISPLAY_HEIGHT + y;
for (int j = 0; j < h; ++j) {
int c = 0;
if (mask != 0x80) {
if (lastb & mask) {
c = 1;
}
mask <<= 1;
} else if (runlen) {
if (runbit) {
c = 1;
}
runlen--;
} else {
if (sz-- <= 0) {
//TU_LOG1("Screen Panic code = 10");
}
lastb = *icon++;
if (lastb & 0x80) {
runlen = lastb & 63;
runbit = lastb & 0x40;
} else {
mask = 0x01;
}
--j;
continue; // restart
}
if (c) {
*p = color;
}
p++;
}
}
}
// print text with font size = 1
static void print(int x, int y, int col, const char* text) {
int x0 = x;
while (*text) {
char c = *text++;
if (c == '\r') continue;
if (c == '\n') {
x = x0;
y += 10;
continue;
}
/*
if (x + 8 > DISPLAY_WIDTH) {
x = x0;
y += 10;
}
*/
if (c < ' ') c = '?';
if (c >= 0x7f) c = '?';
c -= ' ';
printch(x, y, col, &font8[c * 6]);
x += 6;
}
}
// Print text with font size = 4
static void print4(int x, int y, int color, const char* text) {
while (*text) {
char c = *text++;
c -= ' ';
printch4(x, y, color, &font8[c * 6]);
x += CHAR4_KERNED_WIDTH;
if (x + CHAR4_KERNED_WIDTH > DISPLAY_WIDTH) {
// Next char won't fit.
return;
}
}
}
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
static void draw_screen(uint8_t const* fb) {
uint8_t const* p = fb;
for (int y = 0; y < DISPLAY_WIDTH; ++y) {
uint8_t cc[DISPLAY_HEIGHT * 2];
uint32_t dst = 0;
for (int x = 0; x < DISPLAY_HEIGHT; ++x) {
uint16_t color = palette[*p++ & 0xf];
cc[dst++] = color >> 8;
cc[dst++] = color & 0xff;
}
board_display_draw_line(y, cc, sizeof(cc));
}
}
// draw color bar
static void drawBar(int y, int h, int color) {
for (int x = 0; x < DISPLAY_WIDTH; ++x) {
memset(frame_buf + x * DISPLAY_HEIGHT + y, color, h);
}
}
// draw drag & drop screen
void screen_draw_drag(void) {
drawBar(0, 52, COLOR_GREEN);
drawBar(52, 55, COLOR_BLUE);
drawBar(107, 14, COLOR_ORANGE);
// Center UF2_PRODUCT_NAME and UF2_VERSION_BASE.
int name_x = (DISPLAY_WIDTH - CHAR4_KERNED_WIDTH * (int) strlen(DISPLAY_TITLE)) / 2;
print4(name_x >= 0 ? name_x : 0, 5, COLOR_WHITE, DISPLAY_TITLE);
int version_x = (DISPLAY_WIDTH - 6 * (int) strlen(UF2_VERSION_BASE)) / 2;
print(version_x >= 0 ? version_x : 0, 40, COLOR_PURPLE, UF2_VERSION_BASE);
// TODO the reset should be center as well
print(23, 110, 1, "circuitpython.org");
#define DRAG 70
#define DRAGX 10
printicon(DRAGX + 20, DRAG + 5, COLOR_WHITE, fileLogo);
printicon(DRAGX + 66, DRAG, COLOR_WHITE, arrowLogo);
printicon(DRAGX + 108, DRAG, COLOR_WHITE, pendriveLogo);
print(10, DRAG - 12, COLOR_WHITE, "firmware.uf2");
print(90, DRAG - 12, COLOR_WHITE, UF2_VOLUME_LABEL);
draw_screen(frame_buf);
}
#endif
+18 -27
View File
@@ -43,49 +43,41 @@
extern void tusb_hal_nrf_power_event(uint32_t event);
// power callback when SD is not enabled
static void power_event_handler(nrfx_power_usb_evt_t event)
{
static void power_event_handler(nrfx_power_usb_evt_t event) {
tusb_hal_nrf_power_event((uint32_t) event);
}
// Forward USB interrupt events to TinyUSB IRQ Handler
void USBD_IRQHandler(void)
{
void USBD_IRQHandler(void) {
tud_int_handler(0);
}
//------------- IMPLEMENTATION -------------//
void usb_init(bool cdc_only)
{
void usb_init(bool cdc_only) {
// 0, 1 is reserved for SD
NVIC_SetPriority(USBD_IRQn, 2);
// USB power may already be ready at this time -> no event generated
// We need to invoke the handler based on the status initially
uint32_t usb_reg;
uint8_t sd_en = false;
if ( is_sd_existed() )
{
if (is_sd_existed()) {
sd_softdevice_is_enabled(&sd_en);
}
if ( sd_en )
{
if (sd_en) {
sd_power_usbdetected_enable(true);
sd_power_usbpwrrdy_enable(true);
sd_power_usbremoved_enable(true);
sd_power_usbregstatus_get(&usb_reg);
}else
{
} else {
// Power module init
const nrfx_power_config_t pwr_cfg = { 0 };
const nrfx_power_config_t pwr_cfg = {0};
nrfx_power_init(&pwr_cfg);
// Register USB power handler
const nrfx_power_usbevt_config_t config = { .handler = power_event_handler };
const nrfx_power_usbevt_config_t config = {.handler = power_event_handler};
nrfx_power_usbevt_init(&config);
nrfx_power_usbevt_enable();
@@ -93,24 +85,25 @@ void usb_init(bool cdc_only)
usb_reg = NRF_POWER->USBREGSTATUS;
}
if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) {
if (usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk) {
tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED);
}
if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) {
if (usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk) {
tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY);
}
usb_desc_init(cdc_only);
uf2_init();
// Init TinyUSB stack
tusb_init();
#ifdef DISPLAY_PIN_SCK
board_display_init();
screen_draw_drag();
#endif
}
void usb_teardown(void)
{
void usb_teardown(void) {
// Simulate an disconnect which cause pullup disable, USB perpheral disable and hclk disable
tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_REMOVED);
}
@@ -118,12 +111,10 @@ void usb_teardown(void)
//--------------------------------------------------------------------+
// tinyusb callbacks
//--------------------------------------------------------------------+
void tud_mount_cb(void)
{
void tud_mount_cb(void) {
led_state(STATE_USB_MOUNTED);
}
void tud_umount_cb(void)
{
void tud_umount_cb(void) {
led_state(STATE_USB_UNMOUNTED);
}