mirror of
https://github.com/oltaco/Adafruit_nRF52_Bootloader_OTAFIX.git
synced 2026-10-22 19:44:38 +00:00
Merge branch 'master' into fork/SeeedJP/pr/1
# Conflicts: # src/boards/boards.c # src/main.c
This commit is contained in:
138 files changed
+4331
-25846
No files matched your search
@@ -0,0 +1,99 @@
|
||||
---
|
||||
Language: Cpp
|
||||
BasedOnStyle: LLVM
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignConsecutiveBitFields:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignConsecutiveDeclarations:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignConsecutiveMacros:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: true
|
||||
AcrossComments: false
|
||||
AlignConsecutiveShortCaseStatements:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: true
|
||||
AcrossComments: true
|
||||
AlignCaseColons: false
|
||||
AlignEscapedNewlines: LeftWithLastLine
|
||||
AlignOperands: true
|
||||
AlignTrailingComments:
|
||||
Kind: Always
|
||||
OverEmptyLines: 2
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Empty
|
||||
AllowShortCaseExpressionOnASingleLine: true
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: true
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: true
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BracedInitializerIndentWidth: 2
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakConstructorInitializers: AfterColon
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
ContinuationIndentWidth: 2
|
||||
ColumnLimit: 120
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
Cpp11BracedListStyle: true
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^<.*'
|
||||
Priority: 1
|
||||
- Regex: '^".*'
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
||||
IndentPPDirectives: BeforeHash
|
||||
InsertBraces: true
|
||||
IndentCaseLabels: true
|
||||
InsertNewlineAtEOF: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 2
|
||||
NamespaceIndentation: All
|
||||
PenaltyBreakBeforeFirstCallParameter: 1000000
|
||||
PenaltyBreakOpenParenthesis: 1000000
|
||||
PPIndentWidth: 2
|
||||
QualifierAlignment: Custom
|
||||
QualifierOrder: ['static', 'const', 'volatile', 'restrict', 'type']
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeRangeBasedForLoopColon: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInAngles: false
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SortIncludes: false
|
||||
TabWidth: 2
|
||||
...
|
||||
@@ -0,0 +1,16 @@
|
||||
## 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
|
||||
- [ ] If you are adding an new boards, please make sure
|
||||
- [ ] Provide link to your allocated VID/PID if applicable
|
||||
- [ ] `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.
|
||||
@@ -9,92 +9,51 @@ on:
|
||||
- created
|
||||
|
||||
jobs:
|
||||
set-matrix:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set matrix
|
||||
id: set-matrix
|
||||
working-directory: src/boards
|
||||
run: |
|
||||
MATRIX_JSON=$(ls -d */ | sed 's/\/$//' | jq -R -s -c 'split("\n")[:-1]')
|
||||
echo "matrix=$MATRIX_JSON"
|
||||
echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT
|
||||
|
||||
build:
|
||||
needs: set-matrix
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board:
|
||||
# Adafruit Boards
|
||||
- 'circuitplayground_nrf52840'
|
||||
- 'clue_nrf52840'
|
||||
- 'feather_nrf52832'
|
||||
- 'feather_nrf52833_express'
|
||||
- 'feather_nrf52840_express'
|
||||
- 'feather_nrf52840_sense'
|
||||
- 'itsybitsy_nrf52840_express'
|
||||
- 'metro_nrf52840_express'
|
||||
- 'ledglasses_nrf52840'
|
||||
# Other Makers (Alphabetical order)
|
||||
- 'adm_b_nrf52840_1'
|
||||
- 'ae_bl652_bo'
|
||||
- 'aramcon_badge_2019'
|
||||
- 'aramcon2_badge'
|
||||
- 'arcade_feather_nrf52840_express'
|
||||
- 'arduino_nano_33_ble'
|
||||
- 'bast_ble'
|
||||
- 'bluemicro_nrf52833'
|
||||
- 'bluemicro_nrf52840'
|
||||
- 'challenger_840_ble'
|
||||
- 'ebyte_e104_bt5032a'
|
||||
- 'ebyte_e73_tbb'
|
||||
- 'electronut_labs_papyr'
|
||||
- 'ikigaisense_vita'
|
||||
- 'm60_keyboard'
|
||||
- 'mdk_nrf52840_dongle'
|
||||
- 'mikoto'
|
||||
- 'nice_nano'
|
||||
- 'nrf52840_bboard'
|
||||
- 'nrf52840_m2'
|
||||
- 'ohs2020_badge'
|
||||
- 'particle_argon'
|
||||
- 'particle_boron'
|
||||
- 'particle_xenon'
|
||||
- 'pca10056'
|
||||
- 'pca10059'
|
||||
- 'pca10100'
|
||||
- 'pitaya_go'
|
||||
- 'raytac_mdbt50q_db_40'
|
||||
- 'raytac_mdbt50q_rx'
|
||||
- 'sparkfun_nrf52840_micromod'
|
||||
- 'waveshare_nrf52840_eval'
|
||||
|
||||
board: ${{ fromJSON(needs.set-matrix.outputs.matrix) }}
|
||||
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
|
||||
with:
|
||||
repository: hathach/linkermap
|
||||
path: linkermap
|
||||
|
||||
- name: Install ARM GCC
|
||||
uses: carlosperate/arm-none-eabi-gcc-action@v1
|
||||
with:
|
||||
release: '10-2020-q4'
|
||||
release: '12.3.Rel1'
|
||||
|
||||
- name: Install Tools
|
||||
run: |
|
||||
pip3 install adafruit-nrfutil uritemplate requests intelhex
|
||||
pip3 install linkermap/
|
||||
pip3 install adafruit-nrfutil uritemplate requests intelhex setuptools
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
arm-none-eabi-gcc --version
|
||||
make BOARD=${{ matrix.board }} all
|
||||
make BOARD=${{ matrix.board }} copy-artifact
|
||||
|
||||
- name: Linker Map
|
||||
run: make BOARD=${{ matrix.board }} linkermap
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.board }}
|
||||
path: _bin/${{ matrix.board }}
|
||||
|
||||
@@ -65,3 +65,7 @@ TAGS
|
||||
|
||||
.DS_Store
|
||||
Makefile.user
|
||||
|
||||
# Exclude all SoftDevice S340 files
|
||||
lib/softdevice/s340*
|
||||
|
||||
@@ -8,3 +8,6 @@
|
||||
path = lib/uf2
|
||||
url = https://github.com/microsoft/uf2.git
|
||||
|
||||
[submodule "lib/tinycrypt"]
|
||||
path = lib/tinycrypt
|
||||
url = https://github.com/intel/tinycrypt
|
||||
+379
@@ -0,0 +1,379 @@
|
||||
cmake_minimum_required(VERSION 3.17)
|
||||
include(CMakePrintHelpers)
|
||||
find_package(Python COMPONENTS Interpreter)
|
||||
|
||||
if (NOT DEFINED BOARD)
|
||||
message(FATAL_ERROR "BOARD is not defined")
|
||||
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 ()
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/cmake/toolchain/arm_gcc.cmake)
|
||||
|
||||
set(NRFX_DIR ${CMAKE_CURRENT_LIST_DIR}/lib/nrfx)
|
||||
set(SDK11_DIR ${CMAKE_CURRENT_LIST_DIR}/lib/sdk11/components)
|
||||
set(SDK_DIR ${CMAKE_CURRENT_LIST_DIR}/lib/sdk/components)
|
||||
set(SOFTDEVICE_DIR ${CMAKE_CURRENT_LIST_DIR}/lib/softdevice)
|
||||
set(MBR_HEX ${SOFTDEVICE_DIR}/mbr/hex/mbr_nrf52_2.4.1_mbr.hex)
|
||||
set(TINYUSB_DIR ${CMAKE_CURRENT_LIST_DIR}/lib/tinyusb/src)
|
||||
set(TCRYPT_DIR ${CMAKE_CURRENT_LIST_DIR}/lib/tinycrypt/lib)
|
||||
|
||||
option(SIGNED_FW "Enable signed firmware verification" OFF)
|
||||
option(DUALBANK_FW "Enable dual bank DFU support" OFF)
|
||||
option(FORCE_UF2 "Force UF2 support even with SIGNED_FW" OFF)
|
||||
set(SIGNED_FW_QX "" CACHE STRING "Public key Qx (comma-separated bytes)")
|
||||
set(SIGNED_FW_QY "" CACHE STRING "Public key Qy (comma-separated bytes)")
|
||||
|
||||
set(UF2CONV_PY ${CMAKE_CURRENT_LIST_DIR}/lib/uf2/utils/uf2conv.py)
|
||||
set(UF2_FAMILY_ID_BOOTLOADER 0xd663823c)
|
||||
|
||||
#-------------------
|
||||
# Bootloader
|
||||
#-------------------
|
||||
if (NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "")
|
||||
set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Build type" FORCE)
|
||||
endif ()
|
||||
|
||||
project(Adafruit_nRF52_Bootloader C ASM)
|
||||
set(CMAKE_EXECUTABLE_SUFFIX .elf)
|
||||
add_executable(bootloader
|
||||
# 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_DIR}/drivers/src/nrfx_power.c
|
||||
${NRFX_DIR}/drivers/src/nrfx_nvmc.c
|
||||
${NRFX_DIR}/mdk/system_${MCU_VARIANT}.c
|
||||
# sdk 11
|
||||
${SDK11_DIR}/libraries/bootloader_dfu/bootloader.c
|
||||
${SDK11_DIR}/libraries/bootloader_dfu/bootloader_settings.c
|
||||
${SDK11_DIR}/libraries/bootloader_dfu/bootloader_util.c
|
||||
${SDK11_DIR}/libraries/bootloader_dfu/dfu_transport_serial.c
|
||||
${SDK11_DIR}/libraries/bootloader_dfu/dfu_transport_ble.c
|
||||
${SDK11_DIR}/ble/ble_services/ble_dfu/ble_dfu.c
|
||||
${SDK11_DIR}/ble/ble_services/ble_dis/ble_dis.c
|
||||
${SDK11_DIR}/drivers_nrf/pstorage/pstorage_raw.c
|
||||
# latest sdk
|
||||
${SDK_DIR}/libraries/timer/app_timer.c
|
||||
${SDK_DIR}/libraries/scheduler/app_scheduler.c
|
||||
${SDK_DIR}/libraries/util/app_error.c
|
||||
${SDK_DIR}/libraries/util/app_util_platform.c
|
||||
${SDK_DIR}/libraries/crc16/crc16.c
|
||||
${SDK_DIR}/libraries/hci/hci_mem_pool.c
|
||||
${SDK_DIR}/libraries/hci/hci_slip.c
|
||||
${SDK_DIR}/libraries/hci/hci_transport.c
|
||||
${SDK_DIR}/libraries/util/nrf_assert.c
|
||||
# startup
|
||||
${NRFX_DIR}/mdk/gcc_startup_${MCU_VARIANT}.S
|
||||
)
|
||||
|
||||
if (DUALBANK_FW)
|
||||
target_sources(bootloader PUBLIC
|
||||
${SDK11_DIR}/libraries/bootloader_dfu/dfu_dual_bank.c
|
||||
)
|
||||
else ()
|
||||
target_sources(bootloader PUBLIC
|
||||
${SDK11_DIR}/libraries/bootloader_dfu/dfu_single_bank.c
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (SIGNED_FW)
|
||||
target_sources(bootloader PUBLIC
|
||||
${TCRYPT_DIR}/source/sha256.c
|
||||
${TCRYPT_DIR}/source/ecc.c
|
||||
${TCRYPT_DIR}/source/ecc_dsa.c
|
||||
${TCRYPT_DIR}/source/utils.c
|
||||
)
|
||||
|
||||
target_include_directories(bootloader PUBLIC
|
||||
${TCRYPT_DIR}/include
|
||||
)
|
||||
endif ()
|
||||
|
||||
target_include_directories(bootloader PUBLIC
|
||||
src
|
||||
src/boards
|
||||
src/boards/${BOARD}
|
||||
src/cmsis/include
|
||||
src/usb
|
||||
${TINYUSB_DIR}
|
||||
# nrfx
|
||||
${NRFX_DIR}
|
||||
${NRFX_DIR}/mdk
|
||||
${NRFX_DIR}/hal
|
||||
${NRFX_DIR}/drivers/include
|
||||
${NRFX_DIR}/drivers/src
|
||||
# sdk 11 for cdc/ble dfu
|
||||
${SDK11_DIR}/libraries/bootloader_dfu
|
||||
${SDK11_DIR}/libraries/bootloader_dfu/hci_transport
|
||||
${SDK11_DIR}/drivers_nrf/pstorage
|
||||
${SDK11_DIR}/ble/common
|
||||
${SDK11_DIR}/ble/ble_services/ble_dfu
|
||||
${SDK11_DIR}/ble/ble_services/ble_dis
|
||||
# later sdk with updated drivers
|
||||
${SDK_DIR}/libraries/timer
|
||||
${SDK_DIR}/libraries/scheduler
|
||||
${SDK_DIR}/libraries/crc16
|
||||
${SDK_DIR}/libraries/util
|
||||
${SDK_DIR}/libraries/hci/config
|
||||
${SDK_DIR}/libraries/hci
|
||||
${SDK_DIR}/libraries/uart
|
||||
${SDK_DIR}/drivers_nrf/delay
|
||||
# Softdevice
|
||||
${SOFTDEVICE_DIR}/mbr/headers
|
||||
)
|
||||
|
||||
# Debug linker file
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(LD_FILE ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT}_debug.ld)
|
||||
else ()
|
||||
set(LD_FILE ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT}.ld)
|
||||
endif ()
|
||||
|
||||
target_link_options(bootloader PUBLIC
|
||||
"LINKER:--script=${LD_FILE}"
|
||||
-L${NRFX_DIR}/mdk
|
||||
-nostartfiles
|
||||
--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 -Wno-array-bounds
|
||||
)
|
||||
target_compile_definitions(bootloader PUBLIC
|
||||
SOFTDEVICE_PRESENT
|
||||
CONFIG_GPIO_AS_PINRESET
|
||||
__START=main
|
||||
__STARTUP_CLEAR_BSS
|
||||
)
|
||||
|
||||
if (SIGNED_FW)
|
||||
if (SIGNED_FW_QX STREQUAL "" OR SIGNED_FW_QY STREQUAL "")
|
||||
message(FATAL_ERROR "SIGNED_FW requires SIGNED_FW_QX and SIGNED_FW_QY to be set")
|
||||
endif ()
|
||||
string(REPLACE " " "" SIGNED_FW_QX_STR "${SIGNED_FW_QX}")
|
||||
string(REPLACE " " "" SIGNED_FW_QY_STR "${SIGNED_FW_QY}")
|
||||
target_compile_definitions(bootloader PUBLIC
|
||||
SIGNED_FW
|
||||
"SIGNED_FW_QX=${SIGNED_FW_QX_STR}"
|
||||
"SIGNED_FW_QY=${SIGNED_FW_QY_STR}"
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (FORCE_UF2)
|
||||
target_compile_definitions(bootloader PUBLIC FORCE_UF2)
|
||||
endif ()
|
||||
|
||||
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_DIR}/libraries/uart/app_uart.c
|
||||
${SDK_DIR}/drivers_nrf/uart/nrf_drv_uart.c
|
||||
${SDK_DIR}/drivers_nrf/common/nrf_drv_common.c
|
||||
)
|
||||
target_include_directories(bootloader PUBLIC
|
||||
${SDK11_DIR}/libraries/util
|
||||
${SDK_DIR}/drivers_nrf/common
|
||||
${SDK_DIR}/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
|
||||
${TINYUSB_DIR}/portable/nordic/nrf5x/dcd_nrf5x.c
|
||||
${TINYUSB_DIR}/common/tusb_fifo.c
|
||||
${TINYUSB_DIR}/device/usbd.c
|
||||
${TINYUSB_DIR}/device/usbd_control.c
|
||||
${TINYUSB_DIR}/class/cdc/cdc_device.c
|
||||
${TINYUSB_DIR}/class/msc/msc_device.c
|
||||
${TINYUSB_DIR}/tusb.c
|
||||
)
|
||||
endif ()
|
||||
|
||||
#----------------------------------------------------
|
||||
# MCU Variant differences
|
||||
# Supported are: nrf52 (nrf52832), nrf52833, nrf52840
|
||||
#----------------------------------------------------
|
||||
|
||||
# SD_VERSION can be overwritten by board.cmake
|
||||
if(NOT DEFINED SD_VERSION)
|
||||
if(MCU_VARIANT STREQUAL "nrf52833")
|
||||
set(SD_VERSION 7.3.0)
|
||||
else()
|
||||
set(SD_VERSION 6.1.1)
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
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)
|
||||
elseif (MCU_VARIANT STREQUAL "nrf52833")
|
||||
set(DFU_DEV_REV 52833)
|
||||
set(DFU_APP_DATA_RESERVED 7*4096)
|
||||
target_compile_definitions(bootloader PUBLIC NRF52833_XXAA)
|
||||
if (NOT DEFINED SD_NAME)
|
||||
set(SD_NAME s140)
|
||||
endif ()
|
||||
elseif (MCU_VARIANT STREQUAL "nrf52840")
|
||||
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)
|
||||
if (NOT DEFINED SD_NAME)
|
||||
set(SD_NAME s140)
|
||||
endif ()
|
||||
else ()
|
||||
message(FATAL_ERROR "MCU_VARIANT ${MCU_VARIANT} is unknown")
|
||||
endif ()
|
||||
|
||||
set(SD_FILENAME ${SD_NAME}_nrf52_${SD_VERSION})
|
||||
set(SD_HEX ${SOFTDEVICE_DIR}/${SD_FILENAME}/${SD_FILENAME}_softdevice.hex)
|
||||
|
||||
string(TOUPPER ${SD_NAME} SD_NAME_UPPER)
|
||||
target_compile_definitions(bootloader PUBLIC ${SD_NAME_UPPER})
|
||||
target_include_directories(bootloader PUBLIC
|
||||
${SOFTDEVICE_DIR}/${SD_FILENAME}/${SD_FILENAME}_API/include
|
||||
)
|
||||
|
||||
# debug build
|
||||
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
|
||||
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 ()
|
||||
target_compile_definitions(bootloader PUBLIC DFU_APP_DATA_RESERVED=${DFU_APP_DATA_RESERVED})
|
||||
endif ()
|
||||
|
||||
#----------------------------------
|
||||
# ANT_LICENSE_KEY handling
|
||||
#----------------------------------
|
||||
if (DEFINED ANT_LICENSE_KEY)
|
||||
target_compile_definitions(bootloader PUBLIC ANT_LICENSE_KEY=${ANT_LICENSE_KEY})
|
||||
endif()
|
||||
|
||||
#----------------------------------
|
||||
# Get UF2 version from git
|
||||
#----------------------------------
|
||||
execute_process(COMMAND git describe --dirty --always --tags OUTPUT_VARIABLE GIT_VERSION)
|
||||
string(STRIP ${GIT_VERSION} GIT_VERSION)
|
||||
|
||||
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 MK_BOOTLOADER_VERSION)
|
||||
|
||||
target_compile_definitions(bootloader PUBLIC
|
||||
UF2_VERSION="${GIT_VERSION}"
|
||||
BLEDIS_FW_VERSION="${GIT_VERSION} ${SD_NAME} ${SD_VERSION}"
|
||||
MK_BOOTLOADER_VERSION=${MK_BOOTLOADER_VERSION}
|
||||
)
|
||||
|
||||
# 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-bootloader
|
||||
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
|
||||
DEPENDS flash-mbr
|
||||
COMMAND ${NRFJPROG} --program ${SD_HEX} --verify --sectorerase -f nrf52
|
||||
)
|
||||
|
||||
add_custom_target(flash-mbr
|
||||
COMMAND ${NRFJPROG} --program ${MBR_HEX} --verify --sectorerase -f nrf52
|
||||
)
|
||||
|
||||
add_custom_target(flash-erase
|
||||
COMMAND ${NRFJPROG} -f nrf52 --eraseall
|
||||
)
|
||||
|
||||
add_custom_target(flash-all
|
||||
DEPENDS bootloader flash-erase
|
||||
COMMAND ${NRFJPROG} --program ${SD_HEX} --verify --sectorerase -f nrf52
|
||||
COMMAND ${NRFJPROG} --program $<TARGET_FILE:bootloader> --verify --sectoranduicrerase -f nrf52 --reset
|
||||
)
|
||||
|
||||
# flash skip crc magic ( app valid = 0x0001, crc = 0x0000 )
|
||||
#add_custom_target(flash-skip-crc
|
||||
# #COMMAND ${NRFJPROG} --memwr $(BOOT_SETTING_ADDR) --val 0x00000001 -f nrf52
|
||||
# COMMAND ${NRFJPROG} --memwr 0xFF000 --val 0x00000001 -f nrf52
|
||||
# #COMMAND ${NRFJPROG} --memwr 0x7F000 --val 0x00000001 -f nrf52
|
||||
# )
|
||||
@@ -1,24 +1,39 @@
|
||||
#------------------------------------------------------------------------------
|
||||
# CONFIGURE
|
||||
# - SDK_PATH : path to SDK directory
|
||||
# - SDK_PATH : path to SDK directory
|
||||
#
|
||||
# - SD_NAME : e.g s132, s140
|
||||
# - SD_VERSION : SoftDevice version e.g 6.0.0
|
||||
# - SD_HEX : to bootloader hex binary
|
||||
# - SD_NAME : e.g s132, s140
|
||||
# - SD_VERSION : SoftDevice version e.g 6.0.0
|
||||
# - SD_HEX : to bootloader hex binary
|
||||
# - SIGNED_FW : if bootloader will ONLY accept signed firmware
|
||||
# - SIGNED_FW_QX : Qx for signed firmware verification
|
||||
# - SIGNED_FW_QY : Qy for signed firmware verification
|
||||
# - DUALBANK_FW : If bootloader will implement a dual bank feature to allow autorecover from failed
|
||||
# - FORCE_UF2 : if SIGNED_FW is 1, will force to include UF2 support (UNSECURE, UF2 does NOT validate signature!)
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
PYTHON = python
|
||||
|
||||
# local customization
|
||||
-include Makefile.user
|
||||
|
||||
# Board specific
|
||||
-include src/boards/$(BOARD)/board.mk
|
||||
|
||||
SDK_PATH = lib/sdk/components
|
||||
SDK11_PATH = lib/sdk11/components
|
||||
TUSB_PATH = lib/tinyusb/src
|
||||
TCRYPT_PATH = lib/tinycrypt/lib
|
||||
NRFX_PATH = lib/nrfx
|
||||
SD_PATH = lib/softdevice/$(SD_FILENAME)
|
||||
|
||||
# SD_VERSION can be overwritten by board.mk
|
||||
ifndef SD_VERSION
|
||||
SD_VERSION = 6.1.1
|
||||
ifeq ($(MCU_SUB_VARIANT),nrf52833)
|
||||
SD_VERSION = 7.3.0
|
||||
else
|
||||
SD_VERSION = 6.1.1
|
||||
endif
|
||||
endif
|
||||
|
||||
SD_FILENAME = $(SD_NAME)_nrf52_$(SD_VERSION)
|
||||
@@ -26,15 +41,23 @@ SD_HEX = $(SD_PATH)/$(SD_FILENAME)_softdevice.hex
|
||||
|
||||
MBR_HEX = lib/softdevice/mbr/hex/mbr_nrf52_2.4.1_mbr.hex
|
||||
|
||||
# Detect the operating system
|
||||
# The "OS" environment variable on Windows is always "Windows_NT"
|
||||
# when running under a modern shell like cmd.exe or powershell
|
||||
ifeq ($(OS),Windows_NT)
|
||||
NULL_DEVICE = NUL
|
||||
else
|
||||
NULL_DEVICE = /dev/null
|
||||
endif
|
||||
|
||||
# linker by MCU eg. nrf52840.ld
|
||||
ifeq ($(DEBUG), 1)
|
||||
LD_FILE = linker/$(MCU_SUB_VARIANT)_debug.ld
|
||||
LD_FILE = linker/$(MCU_SUB_VARIANT)_debug.ld
|
||||
else
|
||||
LD_FILE = linker/$(MCU_SUB_VARIANT).ld
|
||||
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" " -)
|
||||
|
||||
# compiled file name
|
||||
OUT_NAME = $(BOARD)_bootloader-$(GIT_VERSION)
|
||||
@@ -42,6 +65,8 @@ OUT_NAME = $(BOARD)_bootloader-$(GIT_VERSION)
|
||||
# merged file = compiled + sd
|
||||
MERGED_FILE = $(OUT_NAME)_$(SD_NAME)_$(SD_VERSION)
|
||||
|
||||
UF2_FAMILY_ID_BOOTLOADER = 0xd663823c
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Tool Configure
|
||||
#------------------------------------------------------------------------------
|
||||
@@ -89,45 +114,45 @@ endif
|
||||
BMP_PORT ?= $(shell ls -1 /dev/cu.usbmodem????????1 | head -1)
|
||||
GDB_BMP = $(GDB) -ex 'target extended-remote $(BMP_PORT)' -ex 'monitor swdp_scan' -ex 'attach 1'
|
||||
|
||||
#---------------------------------
|
||||
# Select the board to build
|
||||
#---------------------------------
|
||||
# Note: whitespace is not allowed in the filenames... it WILL break this part of the script
|
||||
BOARD_LIST = $(sort $(filter-out boards.h boards.c,$(notdir $(wildcard src/boards/*))))
|
||||
|
||||
ifeq ($(filter $(BOARD),$(BOARD_LIST)),)
|
||||
$(info You must provide a BOARD parameter with 'BOARD='. Supported boards are:)
|
||||
$(foreach b,$(BOARD_LIST),$(info - $(b)))
|
||||
$(error Invalid BOARD specified)
|
||||
endif
|
||||
|
||||
# Build directory
|
||||
BUILD = _build/build-$(BOARD)
|
||||
BIN = _bin/$(BOARD)
|
||||
|
||||
# Board specific
|
||||
-include src/boards/$(BOARD)/board.mk
|
||||
|
||||
# MCU_SUB_VARIANT can be nrf52 (nrf52832), nrf52833, nrf52840
|
||||
ifeq ($(MCU_SUB_VARIANT),nrf52)
|
||||
CFLAGS += -DNRF52 -DNRF52832_XXAA
|
||||
SD_NAME = s132
|
||||
DFU_DEV_REV = 0xADAF
|
||||
CFLAGS += -DNRF52 -DNRF52832_XXAA -DS132
|
||||
DFU_APP_DATA_RESERVED=7*4096
|
||||
else ifeq ($(MCU_SUB_VARIANT),nrf52833)
|
||||
SD_NAME = s140
|
||||
CFLAGS += -DNRF52833_XXAA
|
||||
DFU_DEV_REV = 52833
|
||||
CFLAGS += -DNRF52833_XXAA -DS140
|
||||
DFU_APP_DATA_RESERVED=7*4096
|
||||
ifndef SD_NAME
|
||||
SD_NAME = s140
|
||||
endif
|
||||
else ifeq ($(MCU_SUB_VARIANT),nrf52840)
|
||||
SD_NAME = s140
|
||||
CFLAGS += -DNRF52840_XXAA
|
||||
DFU_DEV_REV = 52840
|
||||
CFLAGS += -DNRF52840_XXAA -DS140
|
||||
# App reserved 40KB (8+32) to match circuitpython for 840
|
||||
DFU_APP_DATA_RESERVED=10*4096
|
||||
ifndef SD_NAME
|
||||
SD_NAME = s140
|
||||
endif
|
||||
else
|
||||
$(error Sub Variant $(MCU_SUB_VARIANT) is unknown)
|
||||
endif
|
||||
|
||||
SD_NAME_UPPER = $(subst s,S,${SD_NAME})
|
||||
CFLAGS += -D$(SD_NAME_UPPER)
|
||||
|
||||
#----------------------------------
|
||||
# ANT_LICENSE_KEY handling
|
||||
#----------------------------------
|
||||
ifdef ANT_LICENSE_KEY
|
||||
CFLAGS += -DANT_LICENSE_KEY=\"$(ANT_LICENSE_KEY)\"
|
||||
endif
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# SOURCE FILES
|
||||
#------------------------------------------------------------------------------
|
||||
@@ -138,6 +163,17 @@ C_SRC += \
|
||||
src/dfu_init.c \
|
||||
src/flash_nrf5x.c \
|
||||
src/main.c \
|
||||
src/screen.c \
|
||||
src/images.c \
|
||||
|
||||
# if using a signed firmware
|
||||
ifeq ($(SIGNED_FW), 1)
|
||||
C_SRC += \
|
||||
$(TCRYPT_PATH)/source/sha256.c \
|
||||
$(TCRYPT_PATH)/source/ecc.c \
|
||||
$(TCRYPT_PATH)/source/ecc_dsa.c \
|
||||
$(TCRYPT_PATH)/source/utils.c
|
||||
endif
|
||||
|
||||
# all files in boards
|
||||
C_SRC += src/boards/boards.c
|
||||
@@ -153,7 +189,11 @@ C_SRC += $(SDK11_PATH)/libraries/bootloader_dfu/bootloader_settings.c
|
||||
C_SRC += $(SDK11_PATH)/libraries/bootloader_dfu/bootloader_util.c
|
||||
C_SRC += $(SDK11_PATH)/libraries/bootloader_dfu/dfu_transport_serial.c
|
||||
C_SRC += $(SDK11_PATH)/libraries/bootloader_dfu/dfu_transport_ble.c
|
||||
ifeq ($(DUALBANK_FW), 1)
|
||||
C_SRC += $(SDK11_PATH)/libraries/bootloader_dfu/dfu_dual_bank.c
|
||||
else
|
||||
C_SRC += $(SDK11_PATH)/libraries/bootloader_dfu/dfu_single_bank.c
|
||||
endif
|
||||
C_SRC += $(SDK11_PATH)/ble/ble_services/ble_dfu/ble_dfu.c
|
||||
C_SRC += $(SDK11_PATH)/ble/ble_services/ble_dis/ble_dis.c
|
||||
C_SRC += $(SDK11_PATH)/drivers_nrf/pstorage/pstorage_raw.c
|
||||
@@ -187,10 +227,10 @@ C_SRC += src/boards/$(BOARD)/pinconfig.c
|
||||
|
||||
# USB Application ( MSC + UF2 )
|
||||
C_SRC += \
|
||||
src/usb/msc_uf2.c \
|
||||
src/usb/usb_desc.c \
|
||||
src/usb/usb.c \
|
||||
src/usb/uf2/ghostfat.c
|
||||
src/usb/msc_uf2.c \
|
||||
src/usb/uf2/ghostfat.c \
|
||||
src/usb/usb.c
|
||||
|
||||
# TinyUSB stack
|
||||
C_SRC += \
|
||||
@@ -201,9 +241,9 @@ C_SRC += \
|
||||
$(TUSB_PATH)/class/cdc/cdc_device.c \
|
||||
$(TUSB_PATH)/class/msc/msc_device.c \
|
||||
$(TUSB_PATH)/tusb.c
|
||||
|
||||
endif
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Assembly Files
|
||||
#------------------------------------------------------------------------------
|
||||
@@ -221,6 +261,11 @@ IPATH += \
|
||||
src/cmsis/include \
|
||||
src/usb \
|
||||
$(TUSB_PATH)
|
||||
|
||||
ifeq ($(SIGNED_FW), 1)
|
||||
IPATH += \
|
||||
$(TCRYPT_PATH)/include
|
||||
endif
|
||||
|
||||
# nrfx
|
||||
IPATH += \
|
||||
@@ -313,9 +358,19 @@ ifneq ($(USE_NFCT),yes)
|
||||
endif
|
||||
|
||||
CFLAGS += -DSOFTDEVICE_PRESENT
|
||||
CFLAGS += -DUF2_VERSION='"$(GIT_VERSION) $(GIT_SUBMODULE_VERSIONS)"'
|
||||
CFLAGS += -DUF2_VERSION='"$(GIT_VERSION)"'
|
||||
CFLAGS += -DBLEDIS_FW_VERSION='"$(GIT_VERSION) $(SD_NAME) $(SD_VERSION)"'
|
||||
|
||||
ifeq ($(SIGNED_FW), 1)
|
||||
CFLAGS += -DSIGNED_FW
|
||||
CFLAGS += -DSIGNED_FW_QX='$(SIGNED_FW_QX)'
|
||||
CFLAGS += -DSIGNED_FW_QY='$(SIGNED_FW_QY)'
|
||||
endif
|
||||
|
||||
ifeq ($(FORCE_UF2), 1)
|
||||
CFLAGS += -DFORCE_UF2
|
||||
endif
|
||||
|
||||
_VER = $(subst ., ,$(word 1, $(subst -, ,$(GIT_VERSION))))
|
||||
CFLAGS += -DMK_BOOTLOADER_VERSION='($(word 1,$(_VER)) << 16) + ($(word 2,$(_VER)) << 8) + $(word 3,$(_VER))'
|
||||
|
||||
@@ -327,9 +382,9 @@ ifeq ($(DEBUG), 1)
|
||||
C_SRC += $(RTT_SRC)/RTT/SEGGER_RTT.c
|
||||
DFU_APP_DATA_RESERVED = 0
|
||||
|
||||
# expand bootloader address to 28KB of reserved app
|
||||
# expand bootloader address to 28KB/40KB of reserved app
|
||||
ifeq ($(MCU_SUB_VARIANT),nrf52840)
|
||||
CFLAGS += -DBOOTLOADER_REGION_START=0xED000
|
||||
CFLAGS += -DBOOTLOADER_REGION_START=0xEA000
|
||||
else
|
||||
CFLAGS += -DBOOTLOADER_REGION_START=0x6D000
|
||||
endif
|
||||
@@ -338,7 +393,8 @@ 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)),)
|
||||
# Fixes for gcc version 12, 13 and 14.
|
||||
ifneq (,$(filter 12.% 13.% 14.%,$(shell $(CC) -dumpversion 2>$(NULL_DEVICE))))
|
||||
CFLAGS += --param=min-pagesize=0
|
||||
endif
|
||||
|
||||
@@ -349,6 +405,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
|
||||
|
||||
@@ -432,17 +489,17 @@ $(BUILD)/$(OUT_NAME).hex: $(BUILD)/$(OUT_NAME).out
|
||||
# Hex file with mbr (still no SD)
|
||||
$(BUILD)/$(OUT_NAME)_nosd.hex: $(BUILD)/$(OUT_NAME).hex
|
||||
@echo Create $(notdir $@)
|
||||
@python3 tools/hexmerge.py --overlap=replace -o $@ $< $(MBR_HEX)
|
||||
@$(PYTHON) tools/hexmerge.py --overlap=replace -o $@ $< $(MBR_HEX)
|
||||
|
||||
# Bootolader self-update uf2
|
||||
$(BUILD)/update-$(OUT_NAME)_nosd.uf2: $(BUILD)/$(OUT_NAME)_nosd.hex
|
||||
@echo Create $(notdir $@)
|
||||
@python3 lib/uf2/utils/uf2conv.py -f 0xd663823c -c -o $@ $^
|
||||
$(PYTHON) lib/uf2/utils/uf2conv.py -f $(UF2_FAMILY_ID_BOOTLOADER) -c -o $@ $^
|
||||
|
||||
# merge bootloader and sd hex together
|
||||
$(BUILD)/$(MERGED_FILE).hex: $(BUILD)/$(OUT_NAME).hex
|
||||
@echo Create $(notdir $@)
|
||||
@python3 tools/hexmerge.py -o $@ $< $(SD_HEX)
|
||||
@$(PYTHON) tools/hexmerge.py -o $@ $< $(SD_HEX)
|
||||
|
||||
# Create pkg zip file for bootloader+SD combo to use with DFU CDC
|
||||
$(BUILD)/$(MERGED_FILE).zip: $(BUILD)/$(OUT_NAME).hex
|
||||
@@ -490,12 +547,17 @@ flash-mbr:
|
||||
@echo Flashing: $(MBR_HEX)
|
||||
$(call FLASH_NOUICR_CMD,$(MBR_HEX))
|
||||
|
||||
# flash using uf2
|
||||
flash-uf2: $(BUILD)/update-$(OUT_NAME)_nosd.uf2
|
||||
@echo Flashing: $(notdir $<)
|
||||
python lib/uf2/utils/uf2conv.py -f $(UF2_FAMILY_ID_BOOTLOADER) --deploy $<
|
||||
|
||||
# dfu with adafruit-nrfutil using CDC interface
|
||||
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
|
||||
|
||||
@@ -28,10 +28,16 @@ In addition, there is also lots of other 3rd-party boards which are added by oth
|
||||
|
||||
## Features
|
||||
|
||||
- DFU over Serial and OTA ( application, Bootloader+SD )
|
||||
- DFU over Serial and OTA (application, Bootloader+SD)
|
||||
- Self-upgradable via Serial and OTA
|
||||
- DFU using UF2 (https://github.com/Microsoft/uf2) (application only)
|
||||
- Auto-enter DFU briefly on startup for DTR auto-reset trick (832 only)
|
||||
- Supports dual bank firmware updates (disabled by default)
|
||||
- Supports signed firmware updates (disabled by default)
|
||||
|
||||
Note: For OTA, `Packet Receipt Notification` (PRN) must be 8 or less, which can be configured in nRF DFU. Otherwise, the
|
||||
bootloader will run out of
|
||||
memory.
|
||||
|
||||
## How to use
|
||||
|
||||
@@ -101,7 +107,7 @@ Pre-builtin binaries are available on GitHub [releases](https://github.com/adafr
|
||||
Note: The bootloader can be downgraded. Since the binary release is a merged version of
|
||||
both bootloader and the Nordic SoftDevice, you can freely upgrade/downgrade to any version you like.
|
||||
|
||||
## How to compile and build
|
||||
## How to compile and build
|
||||
|
||||
You should only continue if you are looking to develop bootloader for your own.
|
||||
You must have have a J-Link available to "unbrick" your device.
|
||||
@@ -114,14 +120,20 @@ You must have have a J-Link available to "unbrick" your device.
|
||||
|
||||
### Build:
|
||||
|
||||
Firstly clone this repo with following commands
|
||||
Firstly clone this repo including its submodules with following command:
|
||||
|
||||
```
|
||||
git clone --recurse-submodules https://github.com/adafruit/Adafruit_nRF52_Bootloader
|
||||
```
|
||||
|
||||
For git versions before `2.13.0` you have to do that manually:
|
||||
```
|
||||
git clone https://github.com/adafruit/Adafruit_nRF52_Bootloader
|
||||
cd Adafruit_nRF52_Bootloader
|
||||
git submodule update --init
|
||||
```
|
||||
|
||||
#### Build using `make`
|
||||
Then build it with `make BOARD={board} all`, for example:
|
||||
|
||||
```
|
||||
@@ -131,12 +143,43 @@ make BOARD=feather_nrf52840_express all
|
||||
For the list of supported boards, run `make` without `BOARD=` :
|
||||
|
||||
```
|
||||
$ make
|
||||
make
|
||||
You must provide a BOARD parameter with 'BOARD='
|
||||
Supported boards are: feather_nrf52840_express feather_nrf52840_express pca10056
|
||||
Makefile:90: *** BOARD not defined. Stop
|
||||
```
|
||||
|
||||
#### Build using `cmake`
|
||||
|
||||
Firstly initialize your build environment by passing your board to `cmake` via `-DBOARD={board}`:
|
||||
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DBOARD=feather_nrf52840_express
|
||||
```
|
||||
|
||||
And then build it with:
|
||||
|
||||
```bash
|
||||
make
|
||||
```
|
||||
|
||||
You can also use the generator of your choice. For example adding the `-GNinja` and then you can invoke `ninja build` instead of `make`.
|
||||
|
||||
To list all supported targets, run:
|
||||
|
||||
```bash
|
||||
cmake --build . --target help
|
||||
```
|
||||
|
||||
To build individual targets, you can specify it directly with `make` or using `cmake --build`:
|
||||
|
||||
```bash
|
||||
make bootloader
|
||||
cmake --build . --target bootloader
|
||||
```
|
||||
|
||||
### Flash
|
||||
|
||||
To flash the bootloader (without softdevice/mbr) using JLink:
|
||||
@@ -169,6 +212,57 @@ To flash MBR only
|
||||
make BOARD=feather_nrf52840_express flash-mbr
|
||||
```
|
||||
|
||||
### Dual bank firmware support:
|
||||
|
||||
This bootloader can split the FLASH memory into 2 partitions, one for the last successfully uploaded firmware, and the other for the new firmware that is being uploaded. In case the firmware upload fails, the bootloader will revert to the last working firmware version. The only drawback is that the maximum firmware size is half of the device FLASH size: That is why it is disabled by default.
|
||||
You can enable this feature by passing DUALBANK_FW=1 to the make process while compiling the bootloader
|
||||
|
||||
### Signed firmware support:
|
||||
This bootloader can validate that the uploaded firmware is digitally signed, and refuse to install unsigned or signed with the improper key firmware. Because this will make Arduino uploads stop working (because they are not digitally signed), this feature is disabled by default.
|
||||
But if you want to ensure noone else is allowed to upload firmware to your device, this option is probably what you want to enable.
|
||||
|
||||
To create a signing key, you will need the adafruit-nrfutil utility. First, generate a signing key and store at given path by using
|
||||
|
||||
```
|
||||
adafruit-nrfutil keys --gen-key stored_key.pem
|
||||
```
|
||||
|
||||
This command will create a signing key and store it in the file stored_key.pem. STORE THIS FILE IN A SAFE PLACE, as without it, you won't be able to sign your firmware packages, and the bootloader will refuse to flash them!!
|
||||
|
||||
Now, you must show the verification key (that is calculated from the signing key):
|
||||
|
||||
```
|
||||
adafruit-nrfutil keys --show-vk code stored_key.pem
|
||||
```
|
||||
|
||||
This command will read your signing key (from the file stored_key.pem) and display C source code with the Qx and Qy arrays: Something along the lines
|
||||
|
||||
```
|
||||
static uint8_t Qx[] = { ... };
|
||||
static uint8_t Qy[] = { ... };
|
||||
```
|
||||
|
||||
You must save the Qx and Qy values, remove all spaces, and pass them to the make command line
|
||||
```
|
||||
make BOARD=feather_nrf52840_express SIGNED_FW=1 SIGNED_FW_QX='Qx values' SIGNED_FW_QY='Qy values'
|
||||
```
|
||||
|
||||
And replace Qx values with the Qx array values, and the Qy values with the Qy array values. That will create a bootloader that ONLY accepts firmware signed with the stored_key.pem signing key. Take into account that the option SIGNED_FW=1 is what enables to build a bootloader that enforces signing, and will ALSO result in disabling UF2 support, as UF2 format does NOT support signing keys. There is an option (only for testing!) called FORCE_UF2 that will FORCE UF2 support on bootloaders that enforce firmware security. It is there to bypass security so you can test a secure bootloader and have a way to recover it something goes wrong, but should NEVER be used if you want to enforce security
|
||||
|
||||
Finally, to create a signed firmware application/bootloader update package, you can use, for example
|
||||
|
||||
```
|
||||
adafruit-nrfutil dfu genpkg --dev-type 0x0052 --sd-req 0x0123 --application "application.hex" --key-file "stored_key.pem" "application_package.zip"
|
||||
```
|
||||
|
||||
Please, use full paths for all files. The examples omit them for clarity!
|
||||
|
||||
And, to upload it to your device,
|
||||
|
||||
```
|
||||
adafruit-nrfutil.exe --verbose dfu serial -pkg "application_package.zip" -p /dev/tty0 -b 115200
|
||||
```
|
||||
|
||||
### Common makefile problems
|
||||
|
||||
#### `arm-none-eabi-gcc`: No such file or directory
|
||||
@@ -176,7 +270,7 @@ make BOARD=feather_nrf52840_express flash-mbr
|
||||
If you get the following error ...
|
||||
|
||||
```
|
||||
$ make BOARD=feather_nrf52840_express all
|
||||
make BOARD=feather_nrf52840_express all
|
||||
Compiling file: main.c
|
||||
/bin/sh: /usr/bin/arm-none-eabi-gcc: No such file or directory
|
||||
make: *** [_build/main.o] Error 127
|
||||
@@ -185,7 +279,7 @@ make: *** [_build/main.o] Error 127
|
||||
... you may need to pass the location of the GCC ARM toolchain binaries to `make` using
|
||||
the variable `CROSS_COMPILE` as below:
|
||||
```
|
||||
$ make CROSS_COMPILE=/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi- BOARD=feather_nrf52832 all
|
||||
make CROSS_COMPILE=/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi- BOARD=feather_nrf52832 all
|
||||
```
|
||||
|
||||
For other compile errors, check the gcc version with `arm-none-eabi-gcc --version` to insure it is at least 9.x.
|
||||
|
||||
@@ -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 ()
|
||||
@@ -0,0 +1,6 @@
|
||||
set(TOOLCHAIN_COMMON_FLAGS
|
||||
-mthumb
|
||||
-mcpu=cortex-m4
|
||||
-mfloat-abi=hard
|
||||
-mfpu=fpv4-sp-d16
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
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_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
-g
|
||||
)
|
||||
|
||||
set(TOOLCHAIN_EXE_LINKER_FLAGS
|
||||
-Wl,--print-memory-usage
|
||||
-Wl,--gc-sections
|
||||
#-Wl,--cref
|
||||
)
|
||||
|
||||
# join the toolchain flags into a single string
|
||||
list(JOIN TOOLCHAIN_COMMON_FLAGS " " TOOLCHAIN_COMMON_FLAGS)
|
||||
list(JOIN TOOLCHAIN_EXE_LINKER_FLAGS " " CMAKE_EXE_LINKER_FLAGS_INIT)
|
||||
|
||||
set(CMAKE_C_FLAGS_INIT "${TOOLCHAIN_COMMON_FLAGS} ${TOOLCHAIN_C_FLAGS}")
|
||||
set(CMAKE_ASM_FLAGS_INIT "${TOOLCHAIN_COMMON_FLAGS} ${TOOLCHAIN_ASM_FLAGS}")
|
||||
@@ -17,13 +17,13 @@
|
||||
#include <stddef.h>
|
||||
#include "sdk_common.h"
|
||||
|
||||
#define MAX_DFU_PKT_LEN 20 /**< Maximum length (in bytes) of the DFU Packet characteristic. */
|
||||
#define PKT_START_DFU_PARAM_LEN 2 /**< Length (in bytes) of the parameters for Packet Start DFU Request. */
|
||||
#define PKT_INIT_DFU_PARAM_LEN 2 /**< Length (in bytes) of the parameters for Packet Init DFU Request. */
|
||||
#define PKT_RCPT_NOTIF_REQ_LEN 3 /**< Length (in bytes) of the Packet Receipt Notification Request. */
|
||||
#define MAX_PKTS_RCPT_NOTIF_LEN 6 /**< Maximum length (in bytes) of the Packets Receipt Notification. */
|
||||
#define MAX_RESPONSE_LEN 7 /**< Maximum length (in bytes) of the response to a Control Point command. */
|
||||
#define MAX_NOTIF_BUFFER_LEN MAX(MAX_PKTS_RCPT_NOTIF_LEN, MAX_RESPONSE_LEN) /**< Maximum length (in bytes) of the buffer needed by DFU Service while sending notifications to peer. */
|
||||
#define MAX_DFU_PKT_LEN (BLEGATT_ATT_MTU_MAX - 3) /**< Maximum length (in bytes) of the DFU Packet characteristic. */
|
||||
#define PKT_START_DFU_PARAM_LEN 2 /**< Length (in bytes) of the parameters for Packet Start DFU Request. */
|
||||
#define PKT_INIT_DFU_PARAM_LEN 2 /**< Length (in bytes) of the parameters for Packet Init DFU Request. */
|
||||
#define PKT_RCPT_NOTIF_REQ_LEN 3 /**< Length (in bytes) of the Packet Receipt Notification Request. */
|
||||
#define MAX_PKTS_RCPT_NOTIF_LEN 6 /**< Maximum length (in bytes) of the Packets Receipt Notification. */
|
||||
#define MAX_RESPONSE_LEN 7 /**< Maximum length (in bytes) of the response to a Control Point command. */
|
||||
#define MAX_NOTIF_BUFFER_LEN MAX(MAX_PKTS_RCPT_NOTIF_LEN, MAX_RESPONSE_LEN) /**< Maximum length (in bytes) of the buffer needed by DFU Service while sending notifications to peer. */
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -57,7 +57,8 @@ static uint32_t dfu_pkt_char_add(ble_dfu_t * const p_dfu)
|
||||
|
||||
memset(&char_md, 0, sizeof(char_md));
|
||||
|
||||
char_md.char_props.write_wo_resp = 1;
|
||||
char_md.char_props.write = 1; // For those improved apps that can take advantage of ACK
|
||||
char_md.char_props.write_wo_resp = 1; // Nordic IOS DFU app REQUIRES Write Without Response */
|
||||
char_md.p_char_user_desc = NULL;
|
||||
char_md.p_char_pf = NULL;
|
||||
char_md.p_user_desc_md = NULL;
|
||||
@@ -555,29 +556,35 @@ uint32_t ble_dfu_bytes_rcvd_report(ble_dfu_t * p_dfu, uint32_t num_of_firmware_b
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
ble_gatts_hvx_params_t hvx_params;
|
||||
uint16_t index = 0;
|
||||
uint32_t err_code;
|
||||
do {
|
||||
|
||||
// Encode the Op Code.
|
||||
m_notif_buffer[index++] = OP_CODE_RESPONSE;
|
||||
ble_gatts_hvx_params_t hvx_params;
|
||||
uint16_t index = 0;
|
||||
|
||||
// Encode the Op Code.
|
||||
m_notif_buffer[index++] = OP_CODE_RESPONSE;
|
||||
|
||||
// Encode the Reqest Op Code.
|
||||
m_notif_buffer[index++] = OP_CODE_IMAGE_SIZE_REQ;
|
||||
|
||||
// Encode the Response Value.
|
||||
m_notif_buffer[index++] = (uint8_t)BLE_DFU_RESP_VAL_SUCCESS;
|
||||
|
||||
index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]);
|
||||
|
||||
memset(&hvx_params, 0, sizeof(hvx_params));
|
||||
|
||||
hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
|
||||
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
|
||||
hvx_params.offset = 0;
|
||||
hvx_params.p_len = &index;
|
||||
hvx_params.p_data = m_notif_buffer;
|
||||
|
||||
err_code = sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
|
||||
} while (err_code == NRF_ERROR_RESOURCES);
|
||||
|
||||
// Encode the Reqest Op Code.
|
||||
m_notif_buffer[index++] = OP_CODE_IMAGE_SIZE_REQ;
|
||||
|
||||
// Encode the Response Value.
|
||||
m_notif_buffer[index++] = (uint8_t)BLE_DFU_RESP_VAL_SUCCESS;
|
||||
|
||||
index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]);
|
||||
|
||||
memset(&hvx_params, 0, sizeof(hvx_params));
|
||||
|
||||
hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
|
||||
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
|
||||
hvx_params.offset = 0;
|
||||
hvx_params.p_len = &index;
|
||||
hvx_params.p_data = m_notif_buffer;
|
||||
|
||||
return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
@@ -593,22 +600,28 @@ uint32_t ble_dfu_pkts_rcpt_notify(ble_dfu_t * p_dfu, uint32_t num_of_firmware_by
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
ble_gatts_hvx_params_t hvx_params;
|
||||
uint16_t index = 0;
|
||||
uint32_t err_code;
|
||||
do {
|
||||
|
||||
m_notif_buffer[index++] = OP_CODE_PKT_RCPT_NOTIF;
|
||||
ble_gatts_hvx_params_t hvx_params;
|
||||
uint16_t index = 0;
|
||||
|
||||
m_notif_buffer[index++] = OP_CODE_PKT_RCPT_NOTIF;
|
||||
|
||||
index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]);
|
||||
|
||||
memset(&hvx_params, 0, sizeof(hvx_params));
|
||||
|
||||
hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
|
||||
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
|
||||
hvx_params.offset = 0;
|
||||
hvx_params.p_len = &index;
|
||||
hvx_params.p_data = m_notif_buffer;
|
||||
|
||||
index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]);
|
||||
err_code = sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
|
||||
} while (err_code == NRF_ERROR_RESOURCES);
|
||||
|
||||
memset(&hvx_params, 0, sizeof(hvx_params));
|
||||
|
||||
hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
|
||||
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
|
||||
hvx_params.offset = 0;
|
||||
hvx_params.p_len = &index;
|
||||
hvx_params.p_data = m_notif_buffer;
|
||||
|
||||
return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
@@ -626,24 +639,30 @@ uint32_t ble_dfu_response_send(ble_dfu_t * p_dfu,
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
ble_gatts_hvx_params_t hvx_params;
|
||||
uint16_t index = 0;
|
||||
uint32_t err_code;
|
||||
do {
|
||||
|
||||
m_notif_buffer[index++] = OP_CODE_RESPONSE;
|
||||
ble_gatts_hvx_params_t hvx_params;
|
||||
uint16_t index = 0;
|
||||
|
||||
m_notif_buffer[index++] = OP_CODE_RESPONSE;
|
||||
|
||||
// Encode the Request Op code
|
||||
m_notif_buffer[index++] = (uint8_t)dfu_proc;
|
||||
|
||||
// Encode the Response Value.
|
||||
m_notif_buffer[index++] = (uint8_t)resp_val;
|
||||
|
||||
memset(&hvx_params, 0, sizeof(hvx_params));
|
||||
|
||||
hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
|
||||
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
|
||||
hvx_params.offset = 0;
|
||||
hvx_params.p_len = &index;
|
||||
hvx_params.p_data = m_notif_buffer;
|
||||
|
||||
err_code = sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
|
||||
} while (err_code == NRF_ERROR_RESOURCES);
|
||||
|
||||
// Encode the Request Op code
|
||||
m_notif_buffer[index++] = (uint8_t)dfu_proc;
|
||||
|
||||
// Encode the Response Value.
|
||||
m_notif_buffer[index++] = (uint8_t)resp_val;
|
||||
|
||||
memset(&hvx_params, 0, sizeof(hvx_params));
|
||||
|
||||
hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
|
||||
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
|
||||
hvx_params.offset = 0;
|
||||
hvx_params.p_len = &index;
|
||||
hvx_params.p_data = m_notif_buffer;
|
||||
|
||||
return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
|
||||
return err_code;
|
||||
}
|
||||
@@ -280,6 +280,10 @@ static void app_notify(uint32_t result, cmd_queue_element_t * p_elem)
|
||||
*/
|
||||
void pstorage_sys_event_handler(uint32_t sys_evt)
|
||||
{
|
||||
// Do not bother processing events we are not interested in
|
||||
if (sys_evt != NRF_EVT_FLASH_OPERATION_SUCCESS &&
|
||||
sys_evt != NRF_EVT_FLASH_OPERATION_ERROR) return;
|
||||
|
||||
uint32_t retval = NRF_SUCCESS;
|
||||
|
||||
// The event shall only be processed if requested by this module.
|
||||
@@ -339,6 +343,7 @@ void pstorage_sys_event_handler(uint32_t sys_evt)
|
||||
* @brief Function for processing of commands and issuing flash access request to the SoftDevice.
|
||||
*
|
||||
* @return The return value received from SoftDevice.
|
||||
* @remark This function is only called when m_cmd_queue.flash_access == false
|
||||
*/
|
||||
static uint32_t cmd_process(void)
|
||||
{
|
||||
@@ -352,6 +357,9 @@ static uint32_t cmd_process(void)
|
||||
|
||||
storage_addr = p_cmd->storage_addr.block_id;
|
||||
|
||||
// Let's assume we will do a flash access
|
||||
m_cmd_queue.flash_access = true;
|
||||
|
||||
switch (p_cmd->op_code)
|
||||
{
|
||||
case PSTORAGE_STORE_OP_CODE:
|
||||
@@ -396,9 +404,10 @@ static uint32_t cmd_process(void)
|
||||
break;
|
||||
}
|
||||
|
||||
if (retval == NRF_SUCCESS)
|
||||
// An error means we will not do it
|
||||
if (retval != NRF_SUCCESS)
|
||||
{
|
||||
m_cmd_queue.flash_access = true;
|
||||
m_cmd_queue.flash_access = false;
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
||||
@@ -40,6 +40,8 @@ typedef enum
|
||||
DFU_STATE_WAIT_4_ACTIVATE /**< State for: waiting for dfu_image_activate(). */
|
||||
} dfu_state_t;
|
||||
|
||||
#define DFU_TIMEOUT_INTERVAL APP_TIMER_TICKS(360000) /**< DFU timeout interval in milliseconds. */
|
||||
|
||||
#define IS_UPDATING_SD(START_PKT) ((START_PKT).dfu_update_mode & DFU_UPDATE_SD) /**< Macro for determining if a SoftDevice update is ongoing. */
|
||||
#define IS_UPDATING_BL(START_PKT) ((START_PKT).dfu_update_mode & DFU_UPDATE_BL) /**< Macro for determining if a Bootloader update is ongoing. */
|
||||
#define IS_UPDATING_APP(START_PKT) ((START_PKT).dfu_update_mode & DFU_UPDATE_APP) /**< Macro for determining if a Application update is ongoing. */
|
||||
|
||||
@@ -0,0 +1,896 @@
|
||||
/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "dfu.h"
|
||||
#include <dfu_types.h>
|
||||
#include "dfu_bank_internal.h"
|
||||
#include "nrf.h"
|
||||
#include "nrf_sdm.h"
|
||||
#include "app_error.h"
|
||||
#include "app_timer.h"
|
||||
#include "bootloader.h"
|
||||
#include "bootloader_types.h"
|
||||
#include "pstorage.h"
|
||||
#include "nrf_mbr.h"
|
||||
#include "dfu_init.h"
|
||||
#include "sdk_common.h"
|
||||
|
||||
static dfu_state_t m_dfu_state; /**< Current DFU state. */
|
||||
static uint32_t m_image_size; /**< Size of the image that will be transmitted. */
|
||||
|
||||
static dfu_start_packet_t m_start_packet; /**< Start packet received for this update procedure. Contains update mode and image sizes information to be used for image transfer. */
|
||||
static uint8_t m_init_packet[128]; /**< Init packet, can hold CRC, Hash, Signed Hash and similar, for image validation, integrity check and authorization checking. */
|
||||
static uint8_t m_init_packet_length; /**< Length of init packet received. */
|
||||
static uint16_t m_image_crc; /**< Calculated CRC of the image received. */
|
||||
|
||||
APP_TIMER_DEF(m_dfu_timer_id); /**< Application timer id. */
|
||||
static bool m_dfu_timed_out = false; /**< Boolean flag value for tracking DFU timer timeout state. */
|
||||
|
||||
static pstorage_handle_t m_storage_handle_swap; /**< Pstorage handle for the swap area (bank 1). Bank used when updating an application or bootloader without SoftDevice. */
|
||||
static pstorage_handle_t m_storage_handle_app; /**< Pstorage handle for the application area (bank 0). Bank used when updating a SoftDevice w/wo bootloader. Handle also used when swapping received application from bank 1 to bank 0. */
|
||||
static pstorage_handle_t * mp_storage_handle_active; /**< Pointer to the pstorage handle for the active bank for receiving of data packets. */
|
||||
|
||||
static dfu_callback_t m_data_pkt_cb; /**< Callback from DFU Bank module for notification of asynchronous operation such as flash prepare. */
|
||||
static dfu_bank_func_t m_functions; /**< Structure holding operations for the selected update process. */
|
||||
|
||||
|
||||
/**@brief Function for handling callbacks from pstorage module.
|
||||
*
|
||||
* @details Handles pstorage results for clear and storage operation. For detailed description of
|
||||
* the parameters provided with the callback, please refer to \ref pstorage_ntf_cb_t.
|
||||
*/
|
||||
static void pstorage_callback_handler(pstorage_handle_t * p_handle,
|
||||
uint8_t op_code,
|
||||
uint32_t result,
|
||||
uint8_t * p_data,
|
||||
uint32_t data_len)
|
||||
{
|
||||
switch (op_code)
|
||||
{
|
||||
case PSTORAGE_STORE_OP_CODE:
|
||||
if ((m_dfu_state == DFU_STATE_RX_DATA_PKT) && (m_data_pkt_cb != NULL))
|
||||
{
|
||||
m_data_pkt_cb(DATA_PACKET, result, p_data);
|
||||
}
|
||||
break;
|
||||
|
||||
case PSTORAGE_CLEAR_OP_CODE:
|
||||
if (m_dfu_state == DFU_STATE_PREPARING)
|
||||
{
|
||||
m_functions.cleared();
|
||||
m_dfu_state = DFU_STATE_RDY;
|
||||
if (m_data_pkt_cb != NULL)
|
||||
{
|
||||
m_data_pkt_cb(START_PACKET, result, p_data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
APP_ERROR_CHECK(result);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling the DFU timeout.
|
||||
*
|
||||
* @param[in] p_context The timeout context.
|
||||
*/
|
||||
static void dfu_timeout_handler(void * p_context)
|
||||
{
|
||||
UNUSED_PARAMETER(p_context);
|
||||
dfu_update_status_t update_status = {0};
|
||||
|
||||
m_dfu_timed_out = true;
|
||||
update_status.status_code = DFU_TIMEOUT;
|
||||
|
||||
bootloader_dfu_update_process(update_status);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for restarting the DFU Timer.
|
||||
*
|
||||
* @details This function will stop and restart the DFU timer. This function will be called by the
|
||||
* functions handling any DFU packet received from the peer that is transferring a firmware
|
||||
* image.
|
||||
*/
|
||||
static uint32_t dfu_timer_restart(void)
|
||||
{
|
||||
if (m_dfu_timed_out)
|
||||
{
|
||||
// The DFU timer had already timed out.
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
uint32_t err_code = app_timer_stop(m_dfu_timer_id);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
err_code = app_timer_start(m_dfu_timer_id, DFU_TIMEOUT_INTERVAL, NULL);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for preparing of flash before receiving SoftDevice image.
|
||||
*
|
||||
* @details This function will erase current application area to ensure sufficient amount of
|
||||
* storage for the SoftDevice image. Upon erase complete a callback will be done.
|
||||
* See \ref dfu_bank_prepare_t for further details.
|
||||
*/
|
||||
static void dfu_prepare_func_app_erase(uint32_t image_size)
|
||||
{
|
||||
mp_storage_handle_active = &m_storage_handle_app;
|
||||
|
||||
// Doing a SoftDevice update thus current application must be cleared to ensure enough space
|
||||
// for new SoftDevice.
|
||||
m_dfu_state = DFU_STATE_PREPARING;
|
||||
|
||||
if ( is_ota() )
|
||||
{
|
||||
uint32_t err_code = pstorage_clear(&m_storage_handle_app, m_image_size);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
flash_nrf5x_erase(DFU_BANK_0_REGION_START, m_image_size);
|
||||
|
||||
// invoke complete callback
|
||||
pstorage_callback_handler(&m_storage_handle_app, PSTORAGE_CLEAR_OP_CODE, NRF_SUCCESS, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for preparing swap before receiving application or bootloader image.
|
||||
*
|
||||
* @details This function will erase current swap area to ensure flash is ready for storage of the
|
||||
* Application or Bootloader image. Upon erase complete a callback will be done.
|
||||
* See \ref dfu_bank_prepare_t for further details.
|
||||
*/
|
||||
static void dfu_prepare_func_swap_erase(uint32_t image_size)
|
||||
{
|
||||
mp_storage_handle_active = &m_storage_handle_swap;
|
||||
|
||||
m_dfu_state = DFU_STATE_PREPARING;
|
||||
|
||||
if ( is_ota() )
|
||||
{
|
||||
uint32_t err_code = pstorage_clear(&m_storage_handle_swap, image_size);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
flash_nrf5x_erase(DFU_BANK_1_REGION_START, image_size);
|
||||
|
||||
// invoke complete callback
|
||||
pstorage_callback_handler(&m_storage_handle_swap, PSTORAGE_CLEAR_OP_CODE, NRF_SUCCESS, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling behaviour when clear operation has completed.
|
||||
*/
|
||||
static void dfu_cleared_func_swap(void)
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling behaviour when clear operation has completed.
|
||||
*/
|
||||
static void dfu_cleared_func_app(void)
|
||||
{
|
||||
dfu_update_status_t update_status = { 0 };
|
||||
update_status.status_code = DFU_BANK_0_ERASED;
|
||||
bootloader_dfu_update_process(update_status);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for calculating storage offset for receiving SoftDevice image.
|
||||
*
|
||||
* @details When a new SoftDevice is received it will be temporary stored in flash before moved to
|
||||
* address 0x0. In order to successfully validate transfer and relocation it is important
|
||||
* that temporary image and final installed image does not overlap hence an offset must
|
||||
* be calculated in case new image is larger than currently installed SoftDevice.
|
||||
*/
|
||||
uint32_t offset_calculate(uint32_t sd_image_size)
|
||||
{
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (m_start_packet.sd_image_size > DFU_BANK_0_REGION_START)
|
||||
{
|
||||
uint32_t page_mask = (CODE_PAGE_SIZE - 1);
|
||||
uint32_t diff = m_start_packet.sd_image_size - DFU_BANK_0_REGION_START;
|
||||
|
||||
offset = diff & ~page_mask;
|
||||
|
||||
// Align offset to next page if image size is not page sized.
|
||||
if ((diff & page_mask) > 0)
|
||||
{
|
||||
offset += CODE_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for activating received SoftDevice image.
|
||||
*
|
||||
* @note This function will not move the SoftDevice image.
|
||||
* The bootloader settings will be marked as SoftDevice update complete and the swapping of
|
||||
* current SoftDevice will occur after system reset.
|
||||
*
|
||||
* @return NRF_SUCCESS on success.
|
||||
*/
|
||||
static uint32_t dfu_activate_sd(void)
|
||||
{
|
||||
dfu_update_status_t update_status = {0};
|
||||
|
||||
update_status.status_code = DFU_UPDATE_SD_COMPLETE;
|
||||
update_status.app_crc = m_image_crc;
|
||||
update_status.sd_image_start = DFU_BANK_0_REGION_START;
|
||||
update_status.sd_size = m_start_packet.sd_image_size;
|
||||
update_status.bl_size = m_start_packet.bl_image_size;
|
||||
update_status.app_size = m_start_packet.app_image_size;
|
||||
|
||||
bootloader_dfu_update_process(update_status);
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for activating received Application image.
|
||||
*
|
||||
* @details This function will move the received application image from swap (bank 1) to
|
||||
* application area (bank 0).
|
||||
*
|
||||
* @return NRF_SUCCESS on success. Error code otherwise.
|
||||
*/
|
||||
static uint32_t dfu_activate_app(void)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
// Erase BANK 0.
|
||||
if ( is_ota() )
|
||||
{
|
||||
err_code = pstorage_clear(&m_storage_handle_app, m_start_packet.app_image_size);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
err_code = pstorage_store(&m_storage_handle_app,
|
||||
(uint8_t *)m_storage_handle_swap.block_id,
|
||||
m_start_packet.app_image_size,
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
flash_nrf5x_erase(DFU_BANK_0_REGION_START, m_start_packet.app_image_size);
|
||||
pstorage_callback_handler(&m_storage_handle_app, PSTORAGE_CLEAR_OP_CODE, NRF_SUCCESS, NULL, 0);
|
||||
|
||||
flash_nrf5x_write(DFU_BANK_0_REGION_START, (uint8_t *)DFU_BANK_1_REGION_START, m_start_packet.app_image_size, false);
|
||||
flash_nrf5x_flush(false);
|
||||
pstorage_callback_handler(&m_storage_handle_app, PSTORAGE_STORE_OP_CODE, NRF_SUCCESS, (uint8_t *) DFU_BANK_1_REGION_START, m_start_packet.app_image_size);
|
||||
}
|
||||
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
dfu_update_status_t update_status = { 0 };
|
||||
|
||||
memset(&update_status, 0, sizeof(dfu_update_status_t ));
|
||||
update_status.status_code = DFU_UPDATE_APP_COMPLETE;
|
||||
update_status.app_crc = m_image_crc;
|
||||
update_status.app_size = m_start_packet.app_image_size;
|
||||
|
||||
bootloader_dfu_update_process(update_status);
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for activating received Bootloader image.
|
||||
*
|
||||
* @note This function will not move the bootloader image.
|
||||
* The bootloader settings will be marked as Bootloader update complete and the swapping of
|
||||
* current bootloader will occur after system reset.
|
||||
*
|
||||
* @return NRF_SUCCESS on success.
|
||||
*/
|
||||
static uint32_t dfu_activate_bl(void)
|
||||
{
|
||||
dfu_update_status_t update_status = {0};
|
||||
|
||||
update_status.status_code = DFU_UPDATE_BOOT_COMPLETE;
|
||||
update_status.app_crc = m_image_crc;
|
||||
update_status.sd_size = m_start_packet.sd_image_size;
|
||||
update_status.bl_size = m_start_packet.bl_image_size;
|
||||
update_status.app_size = m_start_packet.app_image_size;
|
||||
|
||||
bootloader_dfu_update_process(update_status);
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t dfu_init(void)
|
||||
{
|
||||
uint32_t err_code;
|
||||
pstorage_module_param_t storage_module_param = {.cb = pstorage_callback_handler};
|
||||
|
||||
m_init_packet_length = 0;
|
||||
m_image_crc = 0;
|
||||
|
||||
err_code = pstorage_register(&storage_module_param, &m_storage_handle_app);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
m_dfu_state = DFU_STATE_INIT_ERROR;
|
||||
return err_code;
|
||||
}
|
||||
|
||||
m_storage_handle_app.block_id = DFU_BANK_0_REGION_START;
|
||||
m_storage_handle_swap = m_storage_handle_app;
|
||||
m_storage_handle_swap.block_id = DFU_BANK_1_REGION_START;
|
||||
|
||||
// Create the timer to monitor the activity by the peer doing the firmware update.
|
||||
err_code = app_timer_create(&m_dfu_timer_id,
|
||||
APP_TIMER_MODE_SINGLE_SHOT,
|
||||
dfu_timeout_handler);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
// Start the DFU timer.
|
||||
err_code = app_timer_start(m_dfu_timer_id, DFU_TIMEOUT_INTERVAL, NULL);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
m_data_received = 0;
|
||||
m_dfu_state = DFU_STATE_IDLE;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void dfu_register_callback(dfu_callback_t callback_handler)
|
||||
{
|
||||
m_data_pkt_cb = callback_handler;
|
||||
}
|
||||
|
||||
|
||||
uint32_t dfu_start_pkt_handle(dfu_update_packet_t * p_packet)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
m_start_packet = *(p_packet->params.start_packet);
|
||||
|
||||
// Check that the requested update procedure is supported.
|
||||
// Currently the following combinations are allowed:
|
||||
// - Application
|
||||
// - SoftDevice
|
||||
// - Bootloader
|
||||
// - SoftDevice with Bootloader
|
||||
if (IS_UPDATING_APP(m_start_packet) &&
|
||||
(IS_UPDATING_SD(m_start_packet) || IS_UPDATING_BL(m_start_packet)))
|
||||
{
|
||||
// App update is only supported independently.
|
||||
return NRF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (!(IS_WORD_SIZED(m_start_packet.sd_image_size) &&
|
||||
IS_WORD_SIZED(m_start_packet.bl_image_size) &&
|
||||
IS_WORD_SIZED(m_start_packet.app_image_size)))
|
||||
{
|
||||
// Image_sizes are not a multiple of 4 (word size).
|
||||
return NRF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
m_image_size = m_start_packet.sd_image_size + m_start_packet.bl_image_size +
|
||||
m_start_packet.app_image_size;
|
||||
|
||||
if (m_start_packet.bl_image_size > DFU_BL_IMAGE_MAX_SIZE)
|
||||
{
|
||||
return NRF_ERROR_DATA_SIZE;
|
||||
}
|
||||
|
||||
if (IS_UPDATING_SD(m_start_packet))
|
||||
{
|
||||
if (m_image_size > (DFU_IMAGE_MAX_SIZE_FULL))
|
||||
{
|
||||
return NRF_ERROR_DATA_SIZE;
|
||||
}
|
||||
m_functions.prepare = dfu_prepare_func_app_erase;
|
||||
m_functions.cleared = dfu_cleared_func_app;
|
||||
m_functions.activate = dfu_activate_sd;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_image_size > DFU_IMAGE_MAX_SIZE_BANKED)
|
||||
{
|
||||
return NRF_ERROR_DATA_SIZE;
|
||||
}
|
||||
|
||||
m_functions.prepare = dfu_prepare_func_swap_erase;
|
||||
m_functions.cleared = dfu_cleared_func_swap;
|
||||
if (IS_UPDATING_BL(m_start_packet))
|
||||
{
|
||||
m_functions.activate = dfu_activate_bl;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_functions.activate = dfu_activate_app;
|
||||
}
|
||||
}
|
||||
|
||||
if ( DFU_STATE_IDLE != m_dfu_state )
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
|
||||
// Valid peer activity detected. Hence restart the DFU timer.
|
||||
err_code = dfu_timer_restart();
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
m_functions.prepare(m_image_size);
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet)
|
||||
{
|
||||
uint32_t data_length;
|
||||
uint32_t err_code;
|
||||
uint32_t * p_data;
|
||||
|
||||
VERIFY_PARAM_NOT_NULL(p_packet);
|
||||
|
||||
// Check pointer alignment.
|
||||
if (!is_word_aligned(p_packet->params.data_packet.p_data_packet))
|
||||
{
|
||||
// The p_data_packet is not word aligned address.
|
||||
return NRF_ERROR_INVALID_ADDR;
|
||||
}
|
||||
|
||||
switch (m_dfu_state)
|
||||
{
|
||||
case DFU_STATE_RDY:
|
||||
case DFU_STATE_RX_INIT_PKT:
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
|
||||
case DFU_STATE_RX_DATA_PKT:
|
||||
data_length = p_packet->params.data_packet.packet_length * sizeof(uint32_t);
|
||||
|
||||
if ((m_data_received + data_length) > m_image_size)
|
||||
{
|
||||
// The caller is trying to write more bytes into the flash than the size provided to
|
||||
// the dfu_image_size_set function. This is treated as a serious error condition and
|
||||
// an unrecoverable one. Hence point the variable mp_app_write_address to the top of
|
||||
// the flash area. This will ensure that all future application data packet writes
|
||||
// will be blocked because of the above check.
|
||||
m_data_received = 0xFFFFFFFF;
|
||||
|
||||
return NRF_ERROR_DATA_SIZE;
|
||||
}
|
||||
|
||||
// Valid peer activity detected. Hence restart the DFU timer.
|
||||
err_code = dfu_timer_restart();
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
p_data = (uint32_t *)p_packet->params.data_packet.p_data_packet;
|
||||
|
||||
if ( is_ota() )
|
||||
{
|
||||
err_code = pstorage_store(mp_storage_handle_active, (uint8_t *)p_data, data_length, m_data_received);
|
||||
VERIFY_SUCCESS(err_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
flash_nrf5x_write(
|
||||
(mp_storage_handle_active == &m_storage_handle_app
|
||||
? DFU_BANK_0_REGION_START
|
||||
: DFU_BANK_1_REGION_START)
|
||||
+ m_data_received, p_data, data_length, false);
|
||||
pstorage_callback_handler(mp_storage_handle_active, PSTORAGE_STORE_OP_CODE, NRF_SUCCESS, (uint8_t *) p_data, data_length);
|
||||
}
|
||||
|
||||
m_data_received += data_length;
|
||||
|
||||
if (m_data_received != m_image_size)
|
||||
{
|
||||
// The entire image is not received yet. More data is expected.
|
||||
err_code = NRF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !is_ota() ) flash_nrf5x_flush(false);
|
||||
|
||||
// The entire image has been received. Return NRF_SUCCESS.
|
||||
err_code = NRF_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
uint32_t dfu_init_pkt_complete(void)
|
||||
{
|
||||
uint32_t err_code = NRF_ERROR_INVALID_STATE;
|
||||
|
||||
// DFU initialization has been done and a start packet has been received.
|
||||
if (IMAGE_WRITE_IN_PROGRESS())
|
||||
{
|
||||
// Image write is already in progress. Cannot handle an init packet now.
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (m_dfu_state == DFU_STATE_RX_INIT_PKT)
|
||||
{
|
||||
err_code = dfu_init_prevalidate(m_init_packet, m_init_packet_length, m_start_packet.dfu_update_mode);
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
m_dfu_state = DFU_STATE_RX_DATA_PKT;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_init_packet_length = 0;
|
||||
}
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
uint32_t dfu_init_pkt_handle(dfu_update_packet_t * p_packet)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
uint32_t length;
|
||||
|
||||
switch (m_dfu_state)
|
||||
{
|
||||
case DFU_STATE_RDY:
|
||||
m_dfu_state = DFU_STATE_RX_INIT_PKT;
|
||||
// When receiving init packet in state ready just update and fall through this case.
|
||||
/* FALLTHRU */
|
||||
|
||||
case DFU_STATE_RX_INIT_PKT:
|
||||
// DFU initialization has been done and a start packet has been received.
|
||||
if (IMAGE_WRITE_IN_PROGRESS())
|
||||
{
|
||||
// Image write is already in progress. Cannot handle an init packet now.
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
// Valid peer activity detected. Hence restart the DFU timer.
|
||||
err_code = dfu_timer_restart();
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
length = p_packet->params.data_packet.packet_length * sizeof(uint32_t);
|
||||
if ((m_init_packet_length + length) > sizeof(m_init_packet))
|
||||
{
|
||||
return NRF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
memcpy(&m_init_packet[m_init_packet_length],
|
||||
&p_packet->params.data_packet.p_data_packet[0],
|
||||
length);
|
||||
m_init_packet_length += length;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Either the start packet was not received or dfu_init function was not called before.
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t dfu_image_validate()
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
switch (m_dfu_state)
|
||||
{
|
||||
case DFU_STATE_RX_DATA_PKT:
|
||||
// Check if the application image write has finished.
|
||||
if (m_data_received != m_image_size)
|
||||
{
|
||||
// Image not yet fully transferred by the peer or the peer has attempted to write
|
||||
// too much data. Hence the validation should fail.
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dfu_state = DFU_STATE_VALIDATE;
|
||||
|
||||
// Valid peer activity detected. Hence restart the DFU timer.
|
||||
err_code = dfu_timer_restart();
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
err_code = dfu_init_postvalidate((uint8_t *)mp_storage_handle_active->block_id,
|
||||
m_image_size);
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
m_dfu_state = DFU_STATE_WAIT_4_ACTIVATE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
uint32_t dfu_image_activate()
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
switch (m_dfu_state)
|
||||
{
|
||||
case DFU_STATE_WAIT_4_ACTIVATE:
|
||||
|
||||
// Stop the DFU Timer because the peer activity need not be monitored any longer.
|
||||
err_code = app_timer_stop(m_dfu_timer_id);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
err_code = m_functions.activate();
|
||||
break;
|
||||
|
||||
default:
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
void dfu_reset(void)
|
||||
{
|
||||
dfu_update_status_t update_status = { 0 };
|
||||
|
||||
update_status.status_code = DFU_RESET;
|
||||
|
||||
bootloader_dfu_update_process(update_status);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t dfu_compare_block(uint32_t * ptr1, uint32_t * ptr2, uint32_t len)
|
||||
{
|
||||
sd_mbr_command_t sd_mbr_cmd;
|
||||
|
||||
sd_mbr_cmd.command = SD_MBR_COMMAND_COMPARE;
|
||||
sd_mbr_cmd.params.compare.ptr1 = ptr1;
|
||||
sd_mbr_cmd.params.compare.ptr2 = ptr2;
|
||||
sd_mbr_cmd.params.compare.len = len / sizeof(uint32_t);
|
||||
|
||||
return sd_mbr_command(&sd_mbr_cmd);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t dfu_copy_sd(uint32_t * src, uint32_t * dst, uint32_t len)
|
||||
{
|
||||
sd_mbr_command_t sd_mbr_cmd;
|
||||
|
||||
sd_mbr_cmd.command = SD_MBR_COMMAND_COPY_SD;
|
||||
sd_mbr_cmd.params.copy_sd.src = src;
|
||||
sd_mbr_cmd.params.copy_sd.dst = dst;
|
||||
sd_mbr_cmd.params.copy_sd.len = len / sizeof(uint32_t);
|
||||
|
||||
return sd_mbr_command(&sd_mbr_cmd);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t dfu_sd_img_block_swap(uint32_t * src,
|
||||
uint32_t * dst,
|
||||
uint32_t len,
|
||||
uint32_t block_size)
|
||||
{
|
||||
// It is necessary to swap the new SoftDevice in 3 rounds to ensure correct copy of data
|
||||
// and verification of data in case power reset occurs during write to flash.
|
||||
// To ensure the robustness of swapping the images are compared backwards till start of
|
||||
// image swap. If the back is identical everything is swapped.
|
||||
uint32_t err_code = dfu_compare_block(src, dst, len);
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
|
||||
if ((uint32_t)dst > SOFTDEVICE_REGION_START)
|
||||
{
|
||||
err_code = dfu_sd_img_block_swap((uint32_t *)((uint32_t)src - block_size),
|
||||
(uint32_t *)((uint32_t)dst - block_size),
|
||||
block_size,
|
||||
block_size);
|
||||
VERIFY_SUCCESS(err_code);
|
||||
}
|
||||
|
||||
err_code = dfu_copy_sd(src, dst, len);
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
return dfu_compare_block(src, dst, len);
|
||||
}
|
||||
|
||||
|
||||
uint32_t dfu_sd_image_swap(void)
|
||||
{
|
||||
bootloader_settings_t boot_settings;
|
||||
|
||||
bootloader_settings_get(&boot_settings);
|
||||
|
||||
if (boot_settings.sd_image_size == 0)
|
||||
{
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
if ((SOFTDEVICE_REGION_START + boot_settings.sd_image_size) > boot_settings.sd_image_start)
|
||||
{
|
||||
uint32_t err_code;
|
||||
uint32_t sd_start = SOFTDEVICE_REGION_START;
|
||||
uint32_t block_size = (boot_settings.sd_image_start - sd_start) / 2;
|
||||
|
||||
/* ##### FIX START ##### */
|
||||
block_size &= ~(uint32_t)(CODE_PAGE_SIZE - 1);
|
||||
/* ##### FIX END ##### */
|
||||
|
||||
uint32_t image_end = boot_settings.sd_image_start + boot_settings.sd_image_size;
|
||||
|
||||
uint32_t img_block_start = boot_settings.sd_image_start + 2 * block_size;
|
||||
uint32_t sd_block_start = sd_start + 2 * block_size;
|
||||
|
||||
if (SD_SIZE_GET(MBR_SIZE) < boot_settings.sd_image_size)
|
||||
{
|
||||
// This will clear a page thus ensuring the old image is invalidated before swapping.
|
||||
err_code = dfu_copy_sd((uint32_t *)(sd_start + block_size),
|
||||
(uint32_t *)(sd_start + block_size),
|
||||
sizeof(uint32_t));
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
err_code = dfu_copy_sd((uint32_t *)sd_start, (uint32_t *)sd_start, sizeof(uint32_t));
|
||||
VERIFY_SUCCESS(err_code);
|
||||
}
|
||||
|
||||
return dfu_sd_img_block_swap((uint32_t *)img_block_start,
|
||||
(uint32_t *)sd_block_start,
|
||||
image_end - img_block_start,
|
||||
block_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (boot_settings.sd_image_size != 0)
|
||||
{
|
||||
return dfu_copy_sd((uint32_t *)boot_settings.sd_image_start,
|
||||
(uint32_t *)SOFTDEVICE_REGION_START,
|
||||
boot_settings.sd_image_size);
|
||||
}
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t dfu_bl_image_swap(void)
|
||||
{
|
||||
bootloader_settings_t bootloader_settings;
|
||||
sd_mbr_command_t sd_mbr_cmd;
|
||||
|
||||
bootloader_settings_get(&bootloader_settings);
|
||||
|
||||
if (bootloader_settings.bl_image_size != 0)
|
||||
{
|
||||
uint32_t bl_image_start = (bootloader_settings.sd_image_size == 0) ?
|
||||
DFU_BANK_1_REGION_START :
|
||||
bootloader_settings.sd_image_start +
|
||||
bootloader_settings.sd_image_size;
|
||||
|
||||
sd_mbr_cmd.command = SD_MBR_COMMAND_COPY_BL;
|
||||
sd_mbr_cmd.params.copy_bl.bl_src = (uint32_t *)(bl_image_start);
|
||||
sd_mbr_cmd.params.copy_bl.bl_len = bootloader_settings.bl_image_size / sizeof(uint32_t);
|
||||
|
||||
return sd_mbr_command(&sd_mbr_cmd);
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t dfu_bl_image_validate(void)
|
||||
{
|
||||
bootloader_settings_t bootloader_settings;
|
||||
|
||||
sd_mbr_command_t sd_mbr_cmd_1;
|
||||
sd_mbr_command_t sd_mbr_cmd_2;
|
||||
|
||||
bootloader_settings_get(&bootloader_settings);
|
||||
|
||||
if (bootloader_settings.bl_image_size != 0)
|
||||
{
|
||||
uint32_t bl_image_start_1 = (bootloader_settings.sd_image_size == 0) ?
|
||||
DFU_BANK_0_REGION_START :
|
||||
bootloader_settings.sd_image_start +
|
||||
bootloader_settings.sd_image_size;
|
||||
|
||||
sd_mbr_cmd_1.command = SD_MBR_COMMAND_COMPARE;
|
||||
sd_mbr_cmd_1.params.compare.ptr1 = (uint32_t *)BOOTLOADER_REGION_START;
|
||||
sd_mbr_cmd_1.params.compare.ptr2 = (uint32_t *)(bl_image_start_1);
|
||||
sd_mbr_cmd_1.params.compare.len = bootloader_settings.bl_image_size / sizeof(uint32_t);
|
||||
|
||||
uint32_t err_code = sd_mbr_command(&sd_mbr_cmd_1);
|
||||
if (err_code != NRF_SUCCESS) {
|
||||
return err_code;
|
||||
}
|
||||
|
||||
uint32_t bl_image_start_2 = (bootloader_settings.sd_image_size == 0) ?
|
||||
DFU_BANK_1_REGION_START :
|
||||
bootloader_settings.sd_image_start +
|
||||
bootloader_settings.sd_image_size;
|
||||
|
||||
sd_mbr_cmd_2.command = SD_MBR_COMMAND_COMPARE;
|
||||
sd_mbr_cmd_2.params.compare.ptr1 = (uint32_t *)BOOTLOADER_REGION_START;
|
||||
sd_mbr_cmd_2.params.compare.ptr2 = (uint32_t *)(bl_image_start_2);
|
||||
sd_mbr_cmd_2.params.compare.len = bootloader_settings.bl_image_size / sizeof(uint32_t);
|
||||
|
||||
return sd_mbr_command(&sd_mbr_cmd_2);
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t dfu_sd_image_validate(void)
|
||||
{
|
||||
bootloader_settings_t bootloader_settings;
|
||||
sd_mbr_command_t sd_mbr_cmd;
|
||||
|
||||
bootloader_settings_get(&bootloader_settings);
|
||||
|
||||
if (bootloader_settings.sd_image_size == 0)
|
||||
{
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
if ((SOFTDEVICE_REGION_START + bootloader_settings.sd_image_size) > bootloader_settings.sd_image_start)
|
||||
{
|
||||
uint32_t sd_start = SOFTDEVICE_REGION_START;
|
||||
uint32_t block_size = (bootloader_settings.sd_image_start - sd_start) / 2;
|
||||
uint32_t image_end = bootloader_settings.sd_image_start +
|
||||
bootloader_settings.sd_image_size;
|
||||
|
||||
/* ##### FIX START ##### */
|
||||
block_size &= ~(uint32_t)(CODE_PAGE_SIZE - 1);
|
||||
/* ##### FIX END ##### */
|
||||
|
||||
uint32_t img_block_start = bootloader_settings.sd_image_start + 2 * block_size;
|
||||
uint32_t sd_block_start = sd_start + 2 * block_size;
|
||||
|
||||
if (SD_SIZE_GET(MBR_SIZE) < bootloader_settings.sd_image_size)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
return dfu_sd_img_block_swap((uint32_t *)img_block_start,
|
||||
(uint32_t *)sd_block_start,
|
||||
image_end - img_block_start,
|
||||
block_size);
|
||||
}
|
||||
|
||||
sd_mbr_cmd.command = SD_MBR_COMMAND_COMPARE;
|
||||
sd_mbr_cmd.params.compare.ptr1 = (uint32_t *)SOFTDEVICE_REGION_START;
|
||||
sd_mbr_cmd.params.compare.ptr2 = (uint32_t *)bootloader_settings.sd_image_start;
|
||||
sd_mbr_cmd.params.compare.len = bootloader_settings.sd_image_size / sizeof(uint32_t);
|
||||
|
||||
return sd_mbr_command(&sd_mbr_cmd);
|
||||
}
|
||||
@@ -31,10 +31,13 @@ static dfu_state_t m_dfu_state; /**< Current DFU
|
||||
static uint32_t m_image_size; /**< Size of the image that will be transmitted. */
|
||||
|
||||
static dfu_start_packet_t m_start_packet; /**< Start packet received for this update procedure. Contains update mode and image sizes information to be used for image transfer. */
|
||||
static uint8_t m_init_packet[64]; /**< Init packet, can hold CRC, Hash, Signed Hash and similar, for image validation, integrety check and authorization checking. */
|
||||
static uint8_t m_init_packet[128]; /**< Init packet, can hold CRC, Hash, Signed Hash and similar, for image validation, integrety check and authorization checking. */
|
||||
static uint8_t m_init_packet_length; /**< Length of init packet received. */
|
||||
static uint16_t m_image_crc; /**< Calculated CRC of the image received. */
|
||||
|
||||
APP_TIMER_DEF(m_dfu_timer_id); /**< Application timer id. */
|
||||
static bool m_dfu_timed_out = false; /**< Boolean flag value for tracking DFU timer timeout state. */
|
||||
|
||||
static pstorage_handle_t m_storage_handle_app; /**< Pstorage handle for the application area (bank 0). Bank used when updating a SoftDevice w/wo bootloader. Handle also used when swapping received application from bank 1 to bank 0. */
|
||||
static pstorage_handle_t * mp_storage_handle_active; /**< Pointer to the pstorage handle for the active bank for receiving of data packets. */
|
||||
|
||||
@@ -80,6 +83,47 @@ static void pstorage_callback_handler(pstorage_handle_t * p_handle,
|
||||
APP_ERROR_CHECK(result);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling the DFU timeout.
|
||||
*
|
||||
* @param[in] p_context The timeout context.
|
||||
*/
|
||||
static void dfu_timeout_handler(void * p_context)
|
||||
{
|
||||
UNUSED_PARAMETER(p_context);
|
||||
dfu_update_status_t update_status;
|
||||
|
||||
m_dfu_timed_out = true;
|
||||
update_status.status_code = DFU_TIMEOUT;
|
||||
|
||||
bootloader_dfu_update_process(update_status);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for restarting the DFU Timer.
|
||||
*
|
||||
* @details This function will stop and restart the DFU timer. This function will be called by the
|
||||
* functions handling any DFU packet received from the peer that is transferring a firmware
|
||||
* image.
|
||||
*/
|
||||
static uint32_t dfu_timer_restart(void)
|
||||
{
|
||||
if (m_dfu_timed_out)
|
||||
{
|
||||
// The DFU timer had already timed out.
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
uint32_t err_code = app_timer_stop(m_dfu_timer_id);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
err_code = app_timer_start(m_dfu_timer_id, DFU_TIMEOUT_INTERVAL, NULL);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for preparing of flash before receiving SoftDevice image.
|
||||
*
|
||||
* @details This function will erase current application area to ensure sufficient amount of
|
||||
@@ -88,31 +132,24 @@ static void pstorage_callback_handler(pstorage_handle_t * p_handle,
|
||||
*/
|
||||
static void dfu_prepare_func_app_erase(uint32_t image_size)
|
||||
{
|
||||
mp_storage_handle_active = &m_storage_handle_app;
|
||||
mp_storage_handle_active = &m_storage_handle_app;
|
||||
|
||||
// Doing a SoftDevice update thus current application must be cleared to ensure enough space
|
||||
// for new SoftDevice.
|
||||
m_dfu_state = DFU_STATE_PREPARING;
|
||||
// Doing a SoftDevice update thus current application must be cleared to ensure enough space
|
||||
// for new SoftDevice.
|
||||
m_dfu_state = DFU_STATE_PREPARING;
|
||||
|
||||
if ( is_ota() )
|
||||
{
|
||||
uint32_t err_code = pstorage_clear(&m_storage_handle_app, m_image_size);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t const page_count = NRFX_CEIL_DIV(m_image_size, CODE_PAGE_SIZE);
|
||||
|
||||
for ( uint32_t i = 0; i < page_count; i++ )
|
||||
if ( is_ota() )
|
||||
{
|
||||
uint32_t const addr = DFU_BANK_0_REGION_START + i * CODE_PAGE_SIZE;
|
||||
PRINTF("Erase 0x%08lX\r\n", addr);
|
||||
nrfx_nvmc_page_erase(addr);
|
||||
uint32_t err_code = pstorage_clear(&m_storage_handle_app, m_image_size);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
flash_nrf5x_erase(DFU_BANK_0_REGION_START, m_image_size);
|
||||
|
||||
// invoke complete callback
|
||||
pstorage_callback_handler(&m_storage_handle_app, PSTORAGE_CLEAR_OP_CODE, NRF_SUCCESS, NULL, 0);
|
||||
}
|
||||
// invoke complete callback
|
||||
pstorage_callback_handler(&m_storage_handle_app, PSTORAGE_CLEAR_OP_CODE, NRF_SUCCESS, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -136,14 +173,14 @@ static void dfu_cleared_func_app(void)
|
||||
uint32_t offset_calculate(uint32_t sd_image_size)
|
||||
{
|
||||
uint32_t offset = 0;
|
||||
|
||||
|
||||
if (m_start_packet.sd_image_size > DFU_BANK_0_REGION_START)
|
||||
{
|
||||
uint32_t page_mask = (CODE_PAGE_SIZE - 1);
|
||||
uint32_t diff = m_start_packet.sd_image_size - DFU_BANK_0_REGION_START;
|
||||
|
||||
|
||||
offset = diff & ~page_mask;
|
||||
|
||||
|
||||
// Align offset to next page if image size is not page sized.
|
||||
if ((diff & page_mask) > 0)
|
||||
{
|
||||
@@ -189,8 +226,7 @@ static uint32_t dfu_activate_sd(void)
|
||||
*/
|
||||
static uint32_t dfu_activate_app(void)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
dfu_update_status_t update_status;
|
||||
dfu_update_status_t update_status = { 0 };
|
||||
|
||||
memset(&update_status, 0, sizeof(dfu_update_status_t ));
|
||||
update_status.status_code = DFU_UPDATE_APP_COMPLETE;
|
||||
@@ -199,7 +235,7 @@ static uint32_t dfu_activate_app(void)
|
||||
|
||||
bootloader_dfu_update_process(update_status);
|
||||
|
||||
return err_code;
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +249,7 @@ static uint32_t dfu_activate_app(void)
|
||||
*/
|
||||
static uint32_t dfu_activate_bl(void)
|
||||
{
|
||||
dfu_update_status_t update_status;
|
||||
dfu_update_status_t update_status = {0};
|
||||
|
||||
update_status.status_code = DFU_UPDATE_BOOT_COMPLETE;
|
||||
update_status.app_crc = m_image_crc;
|
||||
@@ -244,6 +280,16 @@ uint32_t dfu_init(void)
|
||||
|
||||
m_storage_handle_app.block_id = DFU_BANK_0_REGION_START;
|
||||
|
||||
// Create the timer to monitor the activity by the peer doing the firmware update.
|
||||
err_code = app_timer_create(&m_dfu_timer_id,
|
||||
APP_TIMER_MODE_SINGLE_SHOT,
|
||||
dfu_timeout_handler);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
// Start the DFU timer.
|
||||
err_code = app_timer_start(m_dfu_timer_id, DFU_TIMEOUT_INTERVAL, NULL);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
m_data_received = 0;
|
||||
m_dfu_state = DFU_STATE_IDLE;
|
||||
|
||||
@@ -259,6 +305,8 @@ void dfu_register_callback(dfu_callback_t callback_handler)
|
||||
|
||||
uint32_t dfu_start_pkt_handle(dfu_update_packet_t * p_packet)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
m_start_packet = *(p_packet->params.start_packet);
|
||||
|
||||
// Check that the requested update procedure is supported.
|
||||
@@ -267,7 +315,7 @@ uint32_t dfu_start_pkt_handle(dfu_update_packet_t * p_packet)
|
||||
// - SoftDevice
|
||||
// - Bootloader
|
||||
// - SoftDevice with Bootloader
|
||||
if (IS_UPDATING_APP(m_start_packet) &&
|
||||
if (IS_UPDATING_APP(m_start_packet) &&
|
||||
(IS_UPDATING_SD(m_start_packet) || IS_UPDATING_BL(m_start_packet)))
|
||||
{
|
||||
// App update is only supported independently.
|
||||
@@ -284,7 +332,7 @@ uint32_t dfu_start_pkt_handle(dfu_update_packet_t * p_packet)
|
||||
|
||||
m_image_size = m_start_packet.sd_image_size + m_start_packet.bl_image_size +
|
||||
m_start_packet.app_image_size;
|
||||
|
||||
|
||||
if (m_start_packet.bl_image_size > DFU_BL_IMAGE_MAX_SIZE)
|
||||
{
|
||||
return NRF_ERROR_DATA_SIZE;
|
||||
@@ -296,7 +344,7 @@ uint32_t dfu_start_pkt_handle(dfu_update_packet_t * p_packet)
|
||||
}
|
||||
m_functions.prepare = dfu_prepare_func_app_erase;
|
||||
m_functions.cleared = dfu_cleared_func_app;
|
||||
|
||||
|
||||
if (IS_UPDATING_SD(m_start_packet))
|
||||
{
|
||||
m_functions.activate = dfu_activate_sd;
|
||||
@@ -312,6 +360,10 @@ uint32_t dfu_start_pkt_handle(dfu_update_packet_t * p_packet)
|
||||
|
||||
if ( DFU_STATE_IDLE != m_dfu_state ) return NRF_ERROR_INVALID_STATE;
|
||||
|
||||
// Valid peer activity detected. Hence restart the DFU timer.
|
||||
err_code = dfu_timer_restart();
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
m_functions.prepare(m_image_size);
|
||||
|
||||
return NRF_SUCCESS;
|
||||
@@ -354,17 +406,21 @@ uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet)
|
||||
return NRF_ERROR_DATA_SIZE;
|
||||
}
|
||||
|
||||
// Valid peer activity detected. Hence restart the DFU timer.
|
||||
err_code = dfu_timer_restart();
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
p_data = (uint32_t *)p_packet->params.data_packet.p_data_packet;
|
||||
|
||||
if ( is_ota() )
|
||||
{
|
||||
err_code = pstorage_store(mp_storage_handle_active, (uint8_t *)p_data, data_length, m_data_received);
|
||||
VERIFY_SUCCESS(err_code);
|
||||
err_code = pstorage_store(mp_storage_handle_active, (uint8_t *)p_data, data_length, m_data_received);
|
||||
VERIFY_SUCCESS(err_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
flash_nrf5x_write(DFU_BANK_0_REGION_START + m_data_received, p_data, data_length, false);
|
||||
pstorage_callback_handler(mp_storage_handle_active, PSTORAGE_STORE_OP_CODE, NRF_SUCCESS, (uint8_t *) p_data, data_length);
|
||||
flash_nrf5x_write(DFU_BANK_0_REGION_START + m_data_received, p_data, data_length, false);
|
||||
pstorage_callback_handler(mp_storage_handle_active, PSTORAGE_STORE_OP_CODE, NRF_SUCCESS, (uint8_t *) p_data, data_length);
|
||||
}
|
||||
|
||||
m_data_received += data_length;
|
||||
@@ -376,10 +432,10 @@ uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet)
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !is_ota() ) flash_nrf5x_flush(false);
|
||||
if ( !is_ota() ) flash_nrf5x_flush(false);
|
||||
|
||||
// The entire image has been received. Return NRF_SUCCESS.
|
||||
err_code = NRF_SUCCESS;
|
||||
// The entire image has been received. Return NRF_SUCCESS.
|
||||
err_code = NRF_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -395,14 +451,14 @@ uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet)
|
||||
uint32_t dfu_init_pkt_complete(void)
|
||||
{
|
||||
uint32_t err_code = NRF_ERROR_INVALID_STATE;
|
||||
|
||||
|
||||
// DFU initialization has been done and a start packet has been received.
|
||||
if (IMAGE_WRITE_IN_PROGRESS())
|
||||
{
|
||||
// Image write is already in progress. Cannot handle an init packet now.
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
|
||||
if (m_dfu_state == DFU_STATE_RX_INIT_PKT)
|
||||
{
|
||||
err_code = dfu_init_prevalidate(m_init_packet, m_init_packet_length, m_start_packet.dfu_update_mode);
|
||||
@@ -421,6 +477,7 @@ uint32_t dfu_init_pkt_complete(void)
|
||||
|
||||
uint32_t dfu_init_pkt_handle(dfu_update_packet_t * p_packet)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
uint32_t length;
|
||||
|
||||
switch (m_dfu_state)
|
||||
@@ -438,6 +495,10 @@ uint32_t dfu_init_pkt_handle(dfu_update_packet_t * p_packet)
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
// Valid peer activity detected. Hence restart the DFU timer.
|
||||
err_code = dfu_timer_restart();
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
length = p_packet->params.data_packet.packet_length * sizeof(uint32_t);
|
||||
if ((m_init_packet_length + length) > sizeof(m_init_packet))
|
||||
{
|
||||
@@ -477,9 +538,16 @@ uint32_t dfu_image_validate()
|
||||
{
|
||||
m_dfu_state = DFU_STATE_VALIDATE;
|
||||
|
||||
err_code = dfu_init_postvalidate((uint8_t *)mp_storage_handle_active->block_id, m_image_size);
|
||||
VERIFY_SUCCESS(err_code);
|
||||
m_dfu_state = DFU_STATE_WAIT_4_ACTIVATE;
|
||||
// Valid peer activity detected. Hence restart the DFU timer.
|
||||
err_code = dfu_timer_restart();
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
err_code = dfu_init_postvalidate((uint8_t *)mp_storage_handle_active->block_id,
|
||||
m_image_size);
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
m_dfu_state = DFU_STATE_WAIT_4_ACTIVATE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -499,6 +567,11 @@ uint32_t dfu_image_activate()
|
||||
switch (m_dfu_state)
|
||||
{
|
||||
case DFU_STATE_WAIT_4_ACTIVATE:
|
||||
|
||||
// Stop the DFU Timer because the peer activity need not be monitored any longer.
|
||||
err_code = app_timer_stop(m_dfu_timer_id);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
err_code = m_functions.activate();
|
||||
break;
|
||||
|
||||
@@ -513,7 +586,7 @@ uint32_t dfu_image_activate()
|
||||
|
||||
void dfu_reset(void)
|
||||
{
|
||||
dfu_update_status_t update_status;
|
||||
dfu_update_status_t update_status = { 0 };
|
||||
|
||||
update_status.status_code = DFU_RESET;
|
||||
|
||||
@@ -547,13 +620,13 @@ static uint32_t dfu_copy_sd(uint32_t * src, uint32_t * dst, uint32_t len)
|
||||
}
|
||||
|
||||
|
||||
static uint32_t dfu_sd_img_block_swap(uint32_t * src,
|
||||
uint32_t * dst,
|
||||
uint32_t len,
|
||||
static uint32_t dfu_sd_img_block_swap(uint32_t * src,
|
||||
uint32_t * dst,
|
||||
uint32_t len,
|
||||
uint32_t block_size)
|
||||
{
|
||||
// It is neccesarry to swap the new SoftDevice in 3 rounds to ensure correct copy of data
|
||||
// and verifucation of data in case power reset occurs during write to flash.
|
||||
// and verification of data in case power reset occurs during write to flash.
|
||||
// To ensure the robustness of swapping the images are compared backwards till start of
|
||||
// image swap. If the back is identical everything is swapped.
|
||||
uint32_t err_code = dfu_compare_block(src, dst, len);
|
||||
@@ -564,9 +637,9 @@ static uint32_t dfu_sd_img_block_swap(uint32_t * src,
|
||||
|
||||
if ((uint32_t)dst > SOFTDEVICE_REGION_START)
|
||||
{
|
||||
err_code = dfu_sd_img_block_swap((uint32_t *)((uint32_t)src - block_size),
|
||||
(uint32_t *)((uint32_t)dst - block_size),
|
||||
block_size,
|
||||
err_code = dfu_sd_img_block_swap((uint32_t *)((uint32_t)src - block_size),
|
||||
(uint32_t *)((uint32_t)dst - block_size),
|
||||
block_size,
|
||||
block_size);
|
||||
VERIFY_SUCCESS(err_code);
|
||||
}
|
||||
@@ -588,37 +661,37 @@ uint32_t dfu_sd_image_swap(void)
|
||||
{
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
if ((SOFTDEVICE_REGION_START + boot_settings.sd_image_size) > boot_settings.sd_image_start)
|
||||
{
|
||||
uint32_t err_code;
|
||||
uint32_t sd_start = SOFTDEVICE_REGION_START;
|
||||
uint32_t block_size = (boot_settings.sd_image_start - sd_start) / 2;
|
||||
|
||||
|
||||
/* ##### FIX START ##### */
|
||||
block_size &= ~(uint32_t)(CODE_PAGE_SIZE - 1);
|
||||
/* ##### FIX END ##### */
|
||||
|
||||
block_size &= ~(uint32_t)(CODE_PAGE_SIZE - 1);
|
||||
/* ##### FIX END ##### */
|
||||
|
||||
uint32_t image_end = boot_settings.sd_image_start + boot_settings.sd_image_size;
|
||||
|
||||
uint32_t img_block_start = boot_settings.sd_image_start + 2 * block_size;
|
||||
uint32_t sd_block_start = sd_start + 2 * block_size;
|
||||
|
||||
|
||||
if (SD_SIZE_GET(MBR_SIZE) < boot_settings.sd_image_size)
|
||||
{
|
||||
// This will clear a page thus ensuring the old image is invalidated before swapping.
|
||||
err_code = dfu_copy_sd((uint32_t *)(sd_start + block_size),
|
||||
(uint32_t *)(sd_start + block_size),
|
||||
err_code = dfu_copy_sd((uint32_t *)(sd_start + block_size),
|
||||
(uint32_t *)(sd_start + block_size),
|
||||
sizeof(uint32_t));
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
err_code = dfu_copy_sd((uint32_t *)sd_start, (uint32_t *)sd_start, sizeof(uint32_t));
|
||||
VERIFY_SUCCESS(err_code);
|
||||
}
|
||||
|
||||
return dfu_sd_img_block_swap((uint32_t *)img_block_start,
|
||||
(uint32_t *)sd_block_start,
|
||||
image_end - img_block_start,
|
||||
|
||||
return dfu_sd_img_block_swap((uint32_t *)img_block_start,
|
||||
(uint32_t *)sd_block_start,
|
||||
image_end - img_block_start,
|
||||
block_size);
|
||||
}
|
||||
else
|
||||
@@ -626,7 +699,7 @@ uint32_t dfu_sd_image_swap(void)
|
||||
if (boot_settings.sd_image_size != 0)
|
||||
{
|
||||
return dfu_copy_sd((uint32_t *)boot_settings.sd_image_start,
|
||||
(uint32_t *)SOFTDEVICE_REGION_START,
|
||||
(uint32_t *)SOFTDEVICE_REGION_START,
|
||||
boot_settings.sd_image_size);
|
||||
}
|
||||
}
|
||||
@@ -646,7 +719,7 @@ uint32_t dfu_bl_image_swap(void)
|
||||
{
|
||||
uint32_t bl_image_start = (bootloader_settings.sd_image_size == 0) ?
|
||||
DFU_BANK_0_REGION_START :
|
||||
bootloader_settings.sd_image_start +
|
||||
bootloader_settings.sd_image_start +
|
||||
bootloader_settings.sd_image_size;
|
||||
|
||||
sd_mbr_cmd.command = SD_MBR_COMMAND_COPY_BL;
|
||||
@@ -658,27 +731,43 @@ uint32_t dfu_bl_image_swap(void)
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t dfu_bl_image_validate(void)
|
||||
{
|
||||
bootloader_settings_t bootloader_settings;
|
||||
sd_mbr_command_t sd_mbr_cmd;
|
||||
|
||||
sd_mbr_command_t sd_mbr_cmd_1;
|
||||
sd_mbr_command_t sd_mbr_cmd_2;
|
||||
|
||||
bootloader_settings_get(&bootloader_settings);
|
||||
|
||||
if (bootloader_settings.bl_image_size != 0)
|
||||
{
|
||||
uint32_t bl_image_start = (bootloader_settings.sd_image_size == 0) ?
|
||||
uint32_t bl_image_start_1 = (bootloader_settings.sd_image_size == 0) ?
|
||||
DFU_BANK_0_REGION_START :
|
||||
bootloader_settings.sd_image_start +
|
||||
bootloader_settings.sd_image_size;
|
||||
|
||||
sd_mbr_cmd.command = SD_MBR_COMMAND_COMPARE;
|
||||
sd_mbr_cmd.params.compare.ptr1 = (uint32_t *)BOOTLOADER_REGION_START;
|
||||
sd_mbr_cmd.params.compare.ptr2 = (uint32_t *)(bl_image_start);
|
||||
sd_mbr_cmd.params.compare.len = bootloader_settings.bl_image_size / sizeof(uint32_t);
|
||||
sd_mbr_cmd_1.command = SD_MBR_COMMAND_COMPARE;
|
||||
sd_mbr_cmd_1.params.compare.ptr1 = (uint32_t *)BOOTLOADER_REGION_START;
|
||||
sd_mbr_cmd_1.params.compare.ptr2 = (uint32_t *)(bl_image_start_1);
|
||||
sd_mbr_cmd_1.params.compare.len = bootloader_settings.bl_image_size / sizeof(uint32_t);
|
||||
|
||||
return sd_mbr_command(&sd_mbr_cmd);
|
||||
uint32_t err_code = sd_mbr_command(&sd_mbr_cmd_1);
|
||||
if (err_code != NRF_SUCCESS) {
|
||||
return err_code;
|
||||
}
|
||||
|
||||
uint32_t bl_image_start_2 = (bootloader_settings.sd_image_size == 0) ?
|
||||
DFU_BANK_1_REGION_START :
|
||||
bootloader_settings.sd_image_start +
|
||||
bootloader_settings.sd_image_size;
|
||||
|
||||
sd_mbr_cmd_2.command = SD_MBR_COMMAND_COMPARE;
|
||||
sd_mbr_cmd_2.params.compare.ptr1 = (uint32_t *)BOOTLOADER_REGION_START;
|
||||
sd_mbr_cmd_2.params.compare.ptr2 = (uint32_t *)(bl_image_start_2);
|
||||
sd_mbr_cmd_2.params.compare.len = bootloader_settings.bl_image_size / sizeof(uint32_t);
|
||||
|
||||
return sd_mbr_command(&sd_mbr_cmd_2);
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
@@ -695,17 +784,18 @@ uint32_t dfu_sd_image_validate(void)
|
||||
{
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
if ((SOFTDEVICE_REGION_START + bootloader_settings.sd_image_size) > bootloader_settings.sd_image_start)
|
||||
{
|
||||
uint32_t sd_start = SOFTDEVICE_REGION_START;
|
||||
uint32_t block_size = (bootloader_settings.sd_image_start - sd_start) / 2;
|
||||
uint32_t image_end = bootloader_settings.sd_image_start +
|
||||
uint32_t image_end = bootloader_settings.sd_image_start +
|
||||
bootloader_settings.sd_image_size;
|
||||
|
||||
/* ##### FIX START ##### */
|
||||
block_size &= ~(uint32_t)(CODE_PAGE_SIZE - 1);
|
||||
/* ##### FIX END ##### */
|
||||
block_size &= ~(uint32_t)(CODE_PAGE_SIZE - 1);
|
||||
/* ##### FIX END ##### */
|
||||
|
||||
uint32_t img_block_start = bootloader_settings.sd_image_start + 2 * block_size;
|
||||
uint32_t sd_block_start = sd_start + 2 * block_size;
|
||||
|
||||
@@ -714,12 +804,12 @@ uint32_t dfu_sd_image_validate(void)
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
return dfu_sd_img_block_swap((uint32_t *)img_block_start,
|
||||
(uint32_t *)sd_block_start,
|
||||
image_end - img_block_start,
|
||||
return dfu_sd_img_block_swap((uint32_t *)img_block_start,
|
||||
(uint32_t *)sd_block_start,
|
||||
image_end - img_block_start,
|
||||
block_size);
|
||||
}
|
||||
|
||||
|
||||
sd_mbr_cmd.command = SD_MBR_COMMAND_COMPARE;
|
||||
sd_mbr_cmd.params.compare.ptr1 = (uint32_t *)SOFTDEVICE_REGION_START;
|
||||
sd_mbr_cmd.params.compare.ptr2 = (uint32_t *)bootloader_settings.sd_image_start;
|
||||
|
||||
@@ -35,11 +35,6 @@
|
||||
#include "nrf_delay.h"
|
||||
#include "sdk_common.h"
|
||||
|
||||
|
||||
#define BLEGAP_EVENT_LENGTH 6
|
||||
#define BLEGATT_ATT_MTU_MAX 247
|
||||
enum { BLE_CONN_CFG_HIGH_BANDWIDTH = 1 };
|
||||
|
||||
#define DFU_REV_MAJOR 0x00 /** DFU Major revision number to be exposed. */
|
||||
#define DFU_REV_MINOR 0x08 /** DFU Minor revision number to be exposed. */
|
||||
#define DFU_REVISION ((DFU_REV_MAJOR << 8) | DFU_REV_MINOR) /** DFU Revision number to be exposed. Combined of major and minor versions. */
|
||||
@@ -47,16 +42,19 @@ enum { BLE_CONN_CFG_HIGH_BANDWIDTH = 1 };
|
||||
#define BLE_HANDLE_MAX 0xFFFF /**< Max handle value is BLE. */
|
||||
|
||||
// limit of 8 chars
|
||||
#ifndef DEVICE_NAME
|
||||
#define DEVICE_NAME "AdaDFU" /**< Name of device. Will be included in the advertising data. */
|
||||
#endif
|
||||
|
||||
#define MIN_CONN_INTERVAL (uint16_t)(MSEC_TO_UNITS(10, UNIT_1_25_MS)) /**< Minimum acceptable connection interval (11.25 milliseconds). */
|
||||
#define MIN_CONN_INTERVAL (uint16_t)(MSEC_TO_UNITS(15, UNIT_1_25_MS)) /**< Minimum acceptable connection interval (11.25 milliseconds). */
|
||||
#define MAX_CONN_INTERVAL (uint16_t)(MSEC_TO_UNITS(30, UNIT_1_25_MS)) /**< Maximum acceptable connection interval (15 milliseconds). */
|
||||
#define SLAVE_LATENCY 0 /**< Slave latency. */
|
||||
#define CONN_SUP_TIMEOUT (4 * 100) /**< Connection supervisory timeout (4 seconds). */
|
||||
#define SLAVE_LATENCY 4 /**< Slave latency. */
|
||||
#define CONN_SUP_TIMEOUT MSEC_TO_UNITS(8000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds). */
|
||||
#define SPEEDUP_FLASH_WRITES 1 /**< Speedup FLASH writes by changing Softdevice local latency */
|
||||
|
||||
#define APP_ADV_INTERVAL MSEC_TO_UNITS(25, UNIT_0_625_MS) /**< The advertising interval (25 ms.). */
|
||||
#define APP_ADV_TIMEOUT BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED /**< The advertising timeout in units of seconds. This is set to @ref BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED so that the advertisement is done as long as there there is a call to @ref dfu_transport_close function.*/
|
||||
#define APP_DIRECTED_ADV_TIMEOUT 50 /**< number of direct advertisement (each lasting 1.28seconds). */
|
||||
#define APP_DIRECTED_ADV_TIMEOUT 50 /**< number of direct advertisement (each lasting 1.28seconds). */
|
||||
#define PEER_ADDRESS_TYPE_INVALID 0xFF /**< Value indicating that no valid peer address exists. This will be the case when a private resolvable address is used in which case there is no address available but instead an IRK is present. */
|
||||
#define PEER_ADDRESS_TYPE_INVALID 0xFF /**< Value indicating that no valid peer address exists. This will be the case when a private resolvable address is used in which case there is no address available but instead an IRK is present. */
|
||||
|
||||
@@ -75,8 +73,9 @@ enum { BLE_CONN_CFG_HIGH_BANDWIDTH = 1 };
|
||||
|
||||
#define IS_CONNECTED() (m_conn_handle != BLE_CONN_HANDLE_INVALID) /**< Macro to determine if the device is in connected state. */
|
||||
|
||||
#define APP_FEATURE_NOT_SUPPORTED BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2 /**< Reply when unsupported features are requested. */
|
||||
#define SD_IMAGE_SIZE_OFFSET 0 /**< Offset in start packet for the size information for SoftDevice. */
|
||||
#define APP_FEATURE_NOT_SUPPORTED \
|
||||
(BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2) /**< Reply when unsupported features are requested. */
|
||||
#define SD_IMAGE_SIZE_OFFSET 0 /**< Offset in start packet for the size information for SoftDevice. */
|
||||
#define BL_IMAGE_SIZE_OFFSET 4 /**< Offset in start packet for the size information for bootloader. */
|
||||
#define APP_IMAGE_SIZE_OFFSET 8 /**< Offset in start packet for the size information for application. */
|
||||
|
||||
@@ -208,7 +207,35 @@ static ble_dfu_resp_val_t nrf_err_code_translate(uint32_t err_c
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SPEEDUP_FLASH_WRITES
|
||||
static void prioritize_ble_over_flash_writes(void) {
|
||||
// We set the local latency to 0: That will revert latency to the negotiated one with the host.
|
||||
// That will increase throughput to the maximum possible
|
||||
ble_opt_t opt;
|
||||
varclr(&opt);
|
||||
opt.gap_opt.local_conn_latency.conn_handle = m_conn_handle; /**< Connection Handle */
|
||||
opt.gap_opt.local_conn_latency.requested_latency = 0; /**< Requested local connection latency. */
|
||||
opt.gap_opt.local_conn_latency.p_actual_latency =
|
||||
NULL; /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return value). */
|
||||
sd_ble_opt_set(BLE_GAP_OPT_LOCAL_CONN_LATENCY, &opt);
|
||||
}
|
||||
|
||||
static void prioritize_flash_writes_over_ble(void) {
|
||||
// We set the local latency to the maximum possible: That will make FLASH writes faster, as BLE comms will
|
||||
// be delayed (even losing RXd packets, but this is the same as a poor connection and will be handled by
|
||||
// the protocol itself)
|
||||
ble_opt_t opt;
|
||||
varclr(&opt);
|
||||
opt.gap_opt.local_conn_latency.conn_handle = m_conn_handle; /**< Connection Handle */
|
||||
opt.gap_opt.local_conn_latency.requested_latency = 50; /**< Requested local connection latency. */
|
||||
opt.gap_opt.local_conn_latency.p_actual_latency =
|
||||
NULL; /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return value). */
|
||||
sd_ble_opt_set(BLE_GAP_OPT_LOCAL_CONN_LATENCY, &opt);
|
||||
}
|
||||
#else
|
||||
#define prioritize_ble_over_flash_writes()
|
||||
#define prioritize_flash_writes_over_ble()
|
||||
#endif
|
||||
/**@brief Function for handling the callback events from the dfu module.
|
||||
* Callbacks are expected when \ref dfu_data_pkt_handle has been executed.
|
||||
*
|
||||
@@ -226,6 +253,9 @@ static void dfu_cb_handler(uint32_t packet, uint32_t result, uint8_t * p_data)
|
||||
case DATA_PACKET:
|
||||
if (result != NRF_SUCCESS)
|
||||
{
|
||||
// Restore latency to the negotiated one
|
||||
prioritize_ble_over_flash_writes();
|
||||
|
||||
// Disconnect from peer.
|
||||
if (IS_CONNECTED())
|
||||
{
|
||||
@@ -242,6 +272,9 @@ static void dfu_cb_handler(uint32_t packet, uint32_t result, uint8_t * p_data)
|
||||
// If the callback matches final data packet received then the peer is notified.
|
||||
if (mp_final_packet == p_data)
|
||||
{
|
||||
// Restore latency to the negotiated one
|
||||
prioritize_ble_over_flash_writes();
|
||||
|
||||
// Notify the DFU Controller about the success of the procedure.
|
||||
err_code = ble_dfu_response_send(&m_dfu,
|
||||
BLE_DFU_RECEIVE_APP_PROCEDURE,
|
||||
@@ -252,6 +285,10 @@ static void dfu_cb_handler(uint32_t packet, uint32_t result, uint8_t * p_data)
|
||||
break;
|
||||
|
||||
case START_PACKET:
|
||||
|
||||
// Restore latency to the negotiated one
|
||||
prioritize_ble_over_flash_writes();
|
||||
|
||||
// Translate the err_code returned by the above function to DFU Response Value.
|
||||
resp_val = nrf_err_code_translate(result, BLE_DFU_START_PROCEDURE);
|
||||
|
||||
@@ -324,9 +361,15 @@ static void start_data_process(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
|
||||
start_packet.bl_image_size = uint32_decode(p_length_data + BL_IMAGE_SIZE_OFFSET);
|
||||
start_packet.app_image_size = uint32_decode(p_length_data + APP_IMAGE_SIZE_OFFSET);
|
||||
|
||||
// Prioritize FLASH writes over BLE comms
|
||||
prioritize_flash_writes_over_ble();
|
||||
|
||||
err_code = dfu_start_pkt_handle(&update_packet);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
// Prioritize BLE over flash writes
|
||||
prioritize_ble_over_flash_writes();
|
||||
|
||||
// Translate the err_code returned by the above function to DFU Response Value.
|
||||
ble_dfu_resp_val_t resp_val;
|
||||
|
||||
@@ -743,8 +786,22 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
|
||||
switch (p_ble_evt->header.evt_id)
|
||||
{
|
||||
case BLE_GAP_EVT_CONNECTED:
|
||||
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
|
||||
m_is_advertising = false;
|
||||
{
|
||||
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
|
||||
m_is_advertising = false;
|
||||
|
||||
// Force changing the slave latency to try to improve transfer throughput (bandwidth)
|
||||
// But Android and IOS will override it with their minimum supported value
|
||||
ble_gap_conn_params_t p_conn_params;
|
||||
p_conn_params.min_conn_interval = p_ble_evt->evt.gap_evt.params.connected.conn_params.min_conn_interval;
|
||||
p_conn_params.max_conn_interval = p_ble_evt->evt.gap_evt.params.connected.conn_params.max_conn_interval;
|
||||
p_conn_params.slave_latency = SLAVE_LATENCY;
|
||||
p_conn_params.conn_sup_timeout = p_ble_evt->evt.gap_evt.params.connected.conn_params.conn_sup_timeout;
|
||||
|
||||
err_code = sd_ble_gap_conn_param_update(m_conn_handle, &p_conn_params);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVT_DISCONNECTED:
|
||||
@@ -774,6 +831,9 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
|
||||
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVT_CONN_PARAM_UPDATE:
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
|
||||
{
|
||||
ble_gap_sec_keyset_t keys;
|
||||
@@ -900,6 +960,11 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
|
||||
case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
|
||||
{
|
||||
uint16_t att_mtu = MIN(p_ble_evt->evt.gatts_evt.params.exchange_mtu_request.client_rx_mtu, BLEGATT_ATT_MTU_MAX);
|
||||
|
||||
// Round it to a multiple of 4 plus 3 bytes, as we need data packets to be multiple of 4 bytes
|
||||
att_mtu &= 0xFFFCU;
|
||||
att_mtu |= 3;
|
||||
|
||||
PRINTF("GAP ATT MTU is changed to %d\r\n", att_mtu);
|
||||
APP_ERROR_CHECK( sd_ble_gatts_exchange_mtu_reply(m_conn_handle, att_mtu) );
|
||||
}
|
||||
|
||||
@@ -74,8 +74,12 @@ static inline bool is_sd_existed(void)
|
||||
#endif
|
||||
|
||||
#define DFU_IMAGE_MAX_SIZE_FULL (DFU_REGION_TOTAL_SIZE - DFU_APP_DATA_RESERVED) /**< Maximum size of an application, excluding save data from the application. */
|
||||
#define DFU_IMAGE_MAX_SIZE_BANKED (((DFU_IMAGE_MAX_SIZE_FULL) - \
|
||||
(DFU_IMAGE_MAX_SIZE_FULL % (2 * CODE_PAGE_SIZE)))/2) /**< Maximum size of an application, excluding save data from the application. */
|
||||
|
||||
#define DFU_BL_IMAGE_MAX_SIZE (BOOTLOADER_MBR_PARAMS_PAGE_ADDRESS - BOOTLOADER_REGION_START) /**< Maximum size of a bootloader, excluding save data from the current bootloader. */
|
||||
#define DFU_BANK_0_REGION_START CODE_REGION_1_START /**< Bank 0 region start. */
|
||||
#define DFU_BANK_1_REGION_START (DFU_BANK_0_REGION_START + DFU_IMAGE_MAX_SIZE_BANKED) /**< Bank 1 region start. */
|
||||
|
||||
#define EMPTY_FLASH_MASK 0xFFFFFFFF /**< Bit mask that defines an empty address in flash. */
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
## Working with SoftDevice S340
|
||||
|
||||
The SoftDevice S340 is closed-source, not publicly available and is only distributed by Garmin Canada Inc.
|
||||
|
||||
In order to be able to download the required ANT+ capable SoftDevice and place SoftDevice S340 v7.0.1 files here. You need to register an 'ANT+ Adopter' account at [thisisant.com](https://www.thisisant.com/register/). After around one business day you will receive access to the resources there. Then do the following steps:
|
||||
- Download the SoftDevice S340 v7.0.1 [(here)](https://www.thisisant.com/developer/components/nrf52832#tab_protocol_stacks_tab) and extract its contents
|
||||
- Under `lib/softdevice` in this repository there is a folder called `s340_nrf52_7.0.1`
|
||||
- Copy the API folder `ANT_s340_nrf52_7.0.1.API`, the license agreement `License_Agreement_ANT_Softdevice_rev3_3.pdf` and the hex file `ANT_s340_nrf52_7.0.1.hex` from the extracted contents to it
|
||||
- Rename the API folder to `s340_nrf52_7.0.1_API`
|
||||
- Rename the hex file to `s340_nrf52_7.0.1_softdevice.hex`
|
||||
- Check `lib/softdevice/s340_nrf52_7.0.1_API/include/nrf_sdm.h` on line 191 to get an *evaluation key* for the ANT SoftDevice which can later be used for the `ANT_LICENSE_KEY` parameter
|
||||
- **VERY IMPORTANT:** You MUST obtain a valid commercial license key BEFORE releasing a product to market that uses the ANT SoftDevice!
|
||||
|
||||
To use the SoftDevice S340 with an existing board the `SD_NAME`, `SD_VERSION` and `ANT_LICENSE_KEY` parameters can just be passed to the command line of the `make` command, e.g.:
|
||||
```
|
||||
make BOARD=xiao_nrf52840_ble_sense SD_NAME=s340 SD_VERSION=7.0.1 ANT_LICENSE_KEY=<YOUR_LICENSE_KEY_OR_EVALUATION_KEY> all
|
||||
```
|
||||
|
||||
To add or modify a board with an ANT+ capable SoftDevice S340 the `SD_VERSION` and `SD_NAME` parameters in the corresponding `board.mk` file have to be set:
|
||||
```
|
||||
SD_VERSION = 7.0.1
|
||||
SD_NAME = s340
|
||||
```
|
||||
Submodule
+1
Submodule lib/tinycrypt added at cf24c907a6.
+1
-1
Submodule lib/uf2 updated: adbb8c7260...b19ac9ad61.
+1
-5
@@ -1,7 +1,7 @@
|
||||
/* Linker script to configure memory regions. */
|
||||
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-lgcc -lc -lnosys)
|
||||
/*GROUP(-lgcc -lc -lnosys)*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
@@ -19,8 +19,6 @@ MEMORY
|
||||
/** Location of bootloader setting in flash. */
|
||||
BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x7F000, LENGTH = 0x1000
|
||||
|
||||
|
||||
|
||||
/** RAM Region for bootloader. */
|
||||
RAM (rwx) : ORIGIN = 0x20008000, LENGTH = 0x20010000-0x20008000
|
||||
|
||||
@@ -30,8 +28,6 @@ MEMORY
|
||||
/** 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
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/* Linker script to configure memory regions. */
|
||||
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-lgcc -lc -lnosys)
|
||||
/*GROUP(-lgcc -lc -lnosys)*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Linker script to configure memory regions. */
|
||||
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-lgcc -lc -lnosys)
|
||||
/*GROUP(-lgcc -lc)*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
|
||||
+2
-7
@@ -1,7 +1,7 @@
|
||||
/* Linker script to configure memory regions. */
|
||||
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-lgcc -lc -lnosys)
|
||||
/*GROUP(-lgcc -lc -lnosys)*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
@@ -21,8 +21,6 @@ MEMORY
|
||||
/** 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
|
||||
@@ -33,9 +31,7 @@ MEMORY
|
||||
/** 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
|
||||
|
||||
@@ -91,7 +87,6 @@ SECTIONS
|
||||
{
|
||||
|
||||
} > NOINIT
|
||||
|
||||
/* other placements follow here... */
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Linker script to configure memory regions. */
|
||||
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-lgcc -lc -lnosys)
|
||||
/*GROUP(-lgcc -lc)*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
@@ -12,7 +12,7 @@ MEMORY
|
||||
* 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-28K, LENGTH = 0xFE000-0xF4000 - 2K + 28K /* 38 KB */
|
||||
FLASH (rx) : ORIGIN = 0xF4000 - 40K, LENGTH = 0xFE000-0xF4000 - 2K + 40K /* 38 KB */
|
||||
|
||||
BOOTLOADER_CONFIG (r): ORIGIN = 0xFE000 - 2K, LENGTH = 2K
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Linker script to configure memory regions. */
|
||||
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-lgcc -lc -lnosys)
|
||||
/*GROUP(-lgcc -lc)*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
|
||||
@@ -1,363 +0,0 @@
|
||||
<!DOCTYPE CrossStudio_Project_File>
|
||||
<solution Name="Adafruit_nRF52_Bootloader" target="8" version="2">
|
||||
<project Name="Adafruit_nRF52_Bootloader">
|
||||
<configuration
|
||||
Name="Common"
|
||||
Placement="Flash"
|
||||
Target="nRF52840_xxAA"
|
||||
arm_architecture="v7EM"
|
||||
arm_core_type="Cortex-M4"
|
||||
arm_endian="Little"
|
||||
arm_fp_abi="Hard"
|
||||
arm_fpu_type="FPv4-SP-D16"
|
||||
arm_interwork="No"
|
||||
arm_linker_heap_size="1024"
|
||||
arm_linker_process_stack_size="0"
|
||||
arm_linker_stack_size="1024"
|
||||
arm_simulator_memory_simulation_parameter="ROM;0x00000000;0x00100000;RAM;0x20000000;0x00040000"
|
||||
arm_target_debug_interface_type="ADIv5"
|
||||
arm_target_device_name="nRF52840_xxAA"
|
||||
arm_target_interface_type="SWD"
|
||||
build_treat_warnings_as_errors="Yes"
|
||||
c_preprocessor_definitions="__nRF_FAMILY;ARM_MATH_CM4;FLASH_PLACEMENT=1;NO_VTOR_CONFIG;MK_BOOTLOADER_VERSION=0x00020A;CONFIG_GPIO_AS_PINRESET;CONFIG_NFCT_PINS_AS_GPIOS;SOFTDEVICE_PRESENT;UF2_VERSION="Segger";BLEDIS_FW_VERSION="Segger";DFU_APP_DATA_RESERVED=7*4096;CFG_DEBUG"
|
||||
c_user_include_directories=".;../src/;../src/usb;../src/boards;../src/cmsis/include;$(tusbDir);$(nrfxDir);$(nrfxDir)/mdk;$(nrfxDir)/hal;$(nrfxDir)/drivers/include;$(nrfxDir)/drivers/src;$(sdDir)/include;$(sdDir)/include/nrf52;$(sdk11Dir)/drivers_nrf/pstorage;$(sdk11Dir)/ble/common/;$(sdk11Dir)/ble/ble_services/ble_dfu;$(sdk11Dir)/ble/ble_services/ble_dis;$(sdk11Dir)/libraries/bootloader_dfu;$(sdk11Dir)/libraries/bootloader_dfu/hci_transport;$(sdk11Dir)/libraries/util;$(sdkDir)/toolchain/cmsis/include;$(sdkDir)/device;$(sdkDir)/toolchain;$(sdkDir)/drivers_nrf/hal;$(sdkDir)/drivers_nrf/systick;$(sdkDir)/drivers_nrf/uart;$(sdkDir)/drivers_nrf/usbd;$(sdkDir)/drivers_nrf/common;$(sdkDir)/drivers_nrf/delay;$(sdkDir)/drivers_nrf/power;$(sdkDir)/drivers_nrf/clock;$(sdkDir)/libraries/util;$(sdkDir)/libraries/timer;$(sdkDir)/libraries/scheduler;$(sdkDir)/libraries/crc16;$(sdkDir)/libraries/util;$(sdkDir)/libraries/hci/config;$(sdkDir)/libraries/uart;$(sdkDir)/libraries/hci;$(sdkDir)/external/fprintf;$(sdkDir)/libraries/strerror;$(sdkDir)/libraries/atomic;$(sdkDir)/libraries/balloc;$(sdkDir)/libraries/experimental_log/src;$(sdkDir)/libraries/experimental_log;$(sdkDir)/libraries/experimental_section_vars;$(sdkDir)/libraries/experimental_memobj"
|
||||
debug_initial_breakpoint_set_option="Never"
|
||||
debug_register_definition_file="$(ProjectDir)/nrf52840_Registers.xml"
|
||||
debug_target_connection="J-Link"
|
||||
gcc_enable_all_warnings="No"
|
||||
gcc_entry_point="Reset_Handler"
|
||||
gcc_optimization_level="Debug"
|
||||
linker_memory_map_file="$(ProjectDir)/nRF52840_xxAA_MemoryMap.xml"
|
||||
linker_printf_width_precision_supported="Yes"
|
||||
linker_section_placement_file="$(ProjectDir)/flash_placement.xml"
|
||||
macros="DeviceHeaderFile=$(PackagesDir)/nRF/CMSIS/Device/Include/nrf.h;DeviceLibraryIdentifier=M4lf;DeviceSystemFile=$(PackagesDir)/nRF/CMSIS/Device/Source/system_nrf52840.c;DeviceVectorsFile=$(PackagesDir)/nRF/Source/ses_nrf52840_Vectors.s;DeviceFamily=nRF;Target=nRF52840_xxAA;Placement=Flash;sdkDir=../lib/sdk/components;sdk11Dir=../lib/sdk11/components;sdDir=../lib/softdevice/s140_nrf52_6.1.1/s140_nrf52_6.1.1_API;tusbDir=../lib/tinyusb/src;nrfxDir=../lib/nrfx"
|
||||
project_directory=""
|
||||
project_type="Executable"
|
||||
target_reset_script="Reset();"
|
||||
target_script_file="$(ProjectDir)/nRF_Target.js"
|
||||
target_trace_initialize_script="EnableTrace("$(TraceInterfaceType)")" />
|
||||
<folder Name="RTT Files">
|
||||
<file file_name="SEGGER_RTT.c" />
|
||||
<file file_name="SEGGER_RTT.h" />
|
||||
<file file_name="SEGGER_RTT_Conf.h" />
|
||||
<file file_name="SEGGER_RTT_SES.c" />
|
||||
</folder>
|
||||
<folder Name="Script Files">
|
||||
<file file_name="nRF_Target.js">
|
||||
<configuration Name="Common" file_type="Reset Script" />
|
||||
</file>
|
||||
</folder>
|
||||
<folder Name="System Files">
|
||||
<file file_name="thumb_crt0.s" />
|
||||
<file file_name="flash_placement.xml" />
|
||||
<file file_name="nRF52840_xxAA_MemoryMap.xml" />
|
||||
<file file_name="nRF52832_xxAA_MemoryMap.xml" />
|
||||
</folder>
|
||||
<configuration Name="Debug Single" gcc_optimization_level="Debug" />
|
||||
<configuration
|
||||
Name="Release Single"
|
||||
gcc_optimization_level="Optimize For Size" />
|
||||
<folder Name="lib">
|
||||
<folder
|
||||
Name="sdk"
|
||||
exclude=""
|
||||
filter="*.h;*.c"
|
||||
path="../lib/sdk"
|
||||
recurse="Yes" />
|
||||
<folder Name="sdk11">
|
||||
<folder Name="components">
|
||||
<folder Name="ble">
|
||||
<folder Name="ble_services">
|
||||
<folder Name="ble_dfu">
|
||||
<file file_name="../lib/sdk11/components/ble/ble_services/ble_dfu/ble_dfu.c" />
|
||||
<file file_name="../lib/sdk11/components/ble/ble_services/ble_dfu/ble_dfu.h" />
|
||||
</folder>
|
||||
<folder Name="ble_dis">
|
||||
<file file_name="../lib/sdk11/components/ble/ble_services/ble_dis/ble_dis.c" />
|
||||
<file file_name="../lib/sdk11/components/ble/ble_services/ble_dis/ble_dis.h" />
|
||||
</folder>
|
||||
</folder>
|
||||
<folder Name="common">
|
||||
<file file_name="../lib/sdk11/components/ble/common/ble_srv_common.h" />
|
||||
</folder>
|
||||
</folder>
|
||||
<folder Name="drivers_nrf">
|
||||
<folder Name="pstorage">
|
||||
<file file_name="../lib/sdk11/components/drivers_nrf/pstorage/pstorage.h" />
|
||||
<file file_name="../lib/sdk11/components/drivers_nrf/pstorage/pstorage_raw.c" />
|
||||
</folder>
|
||||
</folder>
|
||||
<folder Name="libraries">
|
||||
<folder Name="bootloader_dfu">
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/bootloader.c" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/bootloader.h" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/bootloader_settings.c" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/bootloader_settings.h" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/bootloader_types.h" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/bootloader_util.c" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/bootloader_util.h" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/dfu.h" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/dfu_bank_internal.h" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/dfu_ble_svc.h" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/dfu_ble_svc_internal.h" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/dfu_init.h" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/dfu_transport.h" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/dfu_transport_ble.c" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/dfu_transport_serial.c" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/dfu_types.h" />
|
||||
<folder Name="ble_transport">
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/ble_transport/hci_mem_pool_internal.h" />
|
||||
</folder>
|
||||
<folder Name="hci_transport">
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/hci_transport/hci_mem_pool_internal.h" />
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/hci_transport/hci_transport_config.h" />
|
||||
</folder>
|
||||
<file file_name="../lib/sdk11/components/libraries/bootloader_dfu/dfu_single_bank.c" />
|
||||
</folder>
|
||||
<folder Name="util">
|
||||
<file file_name="../lib/sdk11/components/libraries/util/nrf_log.h" />
|
||||
</folder>
|
||||
</folder>
|
||||
</folder>
|
||||
</folder>
|
||||
<folder Name="tinyusb">
|
||||
<folder Name="src">
|
||||
<file file_name="../lib/tinyusb/src/tusb.c" />
|
||||
<file file_name="../lib/tinyusb/src/tusb.h" />
|
||||
<file file_name="../lib/tinyusb/src/tusb_hal.h" />
|
||||
<file file_name="../lib/tinyusb/src/tusb_option.h" />
|
||||
<folder Name="class">
|
||||
<folder Name="cdc">
|
||||
<file file_name="../lib/tinyusb/src/class/cdc/cdc.h" />
|
||||
<file file_name="../lib/tinyusb/src/class/cdc/cdc_device.c" />
|
||||
<file file_name="../lib/tinyusb/src/class/cdc/cdc_device.h" />
|
||||
</folder>
|
||||
<folder Name="hid">
|
||||
<file file_name="../lib/tinyusb/src/class/hid/hid.h" />
|
||||
<file file_name="../lib/tinyusb/src/class/hid/hid_device.c" />
|
||||
<file file_name="../lib/tinyusb/src/class/hid/hid_device.h" />
|
||||
</folder>
|
||||
<folder Name="msc">
|
||||
<file file_name="../lib/tinyusb/src/class/msc/msc.h" />
|
||||
<file file_name="../lib/tinyusb/src/class/msc/msc_device.c" />
|
||||
<file file_name="../lib/tinyusb/src/class/msc/msc_device.h" />
|
||||
</folder>
|
||||
</folder>
|
||||
<folder Name="common">
|
||||
<file file_name="../lib/tinyusb/src/common/binary.h" />
|
||||
<file file_name="../lib/tinyusb/src/common/timeout_timer.h" />
|
||||
<file file_name="../lib/tinyusb/src/common/tusb_common.h" />
|
||||
<file file_name="../lib/tinyusb/src/common/tusb_compiler.h" />
|
||||
<file file_name="../lib/tinyusb/src/common/tusb_error.h" />
|
||||
<file file_name="../lib/tinyusb/src/common/tusb_fifo.c" />
|
||||
<file file_name="../lib/tinyusb/src/common/tusb_fifo.h" />
|
||||
<file file_name="../lib/tinyusb/src/common/tusb_types.h" />
|
||||
<file file_name="../lib/tinyusb/src/common/tusb_verify.h" />
|
||||
<folder Name="compiler">
|
||||
<file file_name="../lib/tinyusb/src/common/compiler/tusb_compiler_gcc.h" />
|
||||
<file file_name="../lib/tinyusb/src/common/compiler/tusb_compiler_iar.h" />
|
||||
</folder>
|
||||
</folder>
|
||||
<folder Name="device">
|
||||
<file file_name="../lib/tinyusb/src/device/dcd.h" />
|
||||
<file file_name="../lib/tinyusb/src/device/usbd.c" />
|
||||
<file file_name="../lib/tinyusb/src/device/usbd.h" />
|
||||
<file file_name="../lib/tinyusb/src/device/usbd_pvt.h" />
|
||||
<file file_name="../lib/tinyusb/src/device/usbd_control.c" />
|
||||
</folder>
|
||||
<folder Name="osal">
|
||||
<file file_name="../lib/tinyusb/src/osal/osal.h" />
|
||||
<file file_name="../lib/tinyusb/src/osal/osal_none.h" />
|
||||
</folder>
|
||||
<folder Name="portable">
|
||||
<folder Name="nordic">
|
||||
<folder Name="nrf5x">
|
||||
<file file_name="../lib/tinyusb/src/portable/nordic/nrf5x/dcd_nrf5x.c" />
|
||||
</folder>
|
||||
</folder>
|
||||
</folder>
|
||||
</folder>
|
||||
<configuration Name="Feather52832" build_exclude_from_build="Yes" />
|
||||
</folder>
|
||||
<folder Name="nrfx">
|
||||
<file file_name="../lib/nrfx/nrfx.h" />
|
||||
<folder Name="drivers">
|
||||
<file file_name="../lib/nrfx/drivers/nrfx_common.h" />
|
||||
<file file_name="../lib/nrfx/drivers/nrfx_errors.h" />
|
||||
<folder Name="include">
|
||||
<file file_name="../lib/nrfx/drivers/include/nrf_bitmask.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_adc.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_clock.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_comp.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_gpiote.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_i2s.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_lpcomp.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_pdm.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_power.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_power_clock.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_ppi.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_pwm.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_qdec.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_qspi.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_rng.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_rtc.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_saadc.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_spi.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_spim.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_spis.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_swi.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_systick.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_timer.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_twi.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_twim.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_twis.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_uart.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_uarte.h" />
|
||||
<file file_name="../lib/nrfx/drivers/include/nrfx_wdt.h" />
|
||||
</folder>
|
||||
<folder Name="src">
|
||||
<file file_name="../lib/nrfx/drivers/src/nrfx_power.c" />
|
||||
<file file_name="../lib/nrfx/drivers/src/nrfx_nvmc.c" />
|
||||
</folder>
|
||||
</folder>
|
||||
<folder Name="hal">
|
||||
<file file_name="../lib/nrfx/hal/nrf_adc.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_ccm.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_clock.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_comp.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_ecb.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_egu.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_gpio.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_gpiote.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_i2s.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_lpcomp.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_nvmc.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_pdm.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_power.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_ppi.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_pwm.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_qdec.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_qspi.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_radio.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_rng.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_rtc.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_saadc.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_spi.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_spim.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_spis.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_systick.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_temp.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_timer.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_twi.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_twim.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_twis.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_uart.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_uarte.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_usbd.h" />
|
||||
<file file_name="../lib/nrfx/hal/nrf_wdt.h" />
|
||||
</folder>
|
||||
<folder Name="mdk">
|
||||
<file file_name="../lib/nrfx/mdk/compiler_abstraction.h" />
|
||||
<file file_name="../lib/nrfx/mdk/nrf.h" />
|
||||
<file file_name="../lib/nrfx/mdk/nrf52.h" />
|
||||
<file file_name="../lib/nrfx/mdk/nrf52832_peripherals.h" />
|
||||
<file file_name="../lib/nrfx/mdk/nrf52840.h" />
|
||||
<file file_name="../lib/nrfx/mdk/nrf52840_bitfields.h" />
|
||||
<file file_name="../lib/nrfx/mdk/nrf52840_peripherals.h" />
|
||||
<file file_name="../lib/nrfx/mdk/nrf52_bitfields.h" />
|
||||
<file file_name="../lib/nrfx/mdk/nrf_peripherals.h" />
|
||||
<file file_name="../lib/nrfx/mdk/ses_startup_nrf52.s">
|
||||
<configuration
|
||||
Name="Feather52840 Size++"
|
||||
build_exclude_from_build="Yes" />
|
||||
<configuration
|
||||
Name="Feather52840"
|
||||
build_exclude_from_build="Yes" />
|
||||
</file>
|
||||
<file file_name="../lib/nrfx/mdk/ses_startup_nrf52840.s">
|
||||
<configuration
|
||||
Name="Feather52840 Size++"
|
||||
build_exclude_from_build="No" />
|
||||
<configuration
|
||||
Name="Feather52832"
|
||||
build_exclude_from_build="Yes" />
|
||||
</file>
|
||||
<file file_name="../lib/nrfx/mdk/ses_startup_nrf_common.s">
|
||||
<configuration
|
||||
Name="Feather52840 Size++"
|
||||
build_exclude_from_build="No" />
|
||||
</file>
|
||||
<file file_name="../lib/nrfx/mdk/startup_config.h" />
|
||||
<file file_name="../lib/nrfx/mdk/system_nrf52.c">
|
||||
<configuration
|
||||
Name="Feather52840 Size++"
|
||||
build_exclude_from_build="Yes" />
|
||||
<configuration
|
||||
Name="Feather52840"
|
||||
build_exclude_from_build="Yes" />
|
||||
</file>
|
||||
<file file_name="../lib/nrfx/mdk/system_nrf52.h" />
|
||||
<file file_name="../lib/nrfx/mdk/system_nrf52840.c">
|
||||
<configuration
|
||||
Name="Feather52832"
|
||||
build_exclude_from_build="Yes" />
|
||||
</file>
|
||||
<file file_name="../lib/nrfx/mdk/system_nrf52840.h" />
|
||||
</folder>
|
||||
<folder Name="soc">
|
||||
<file file_name="../lib/nrfx/soc/nrfx_coredep.h" />
|
||||
<file file_name="../lib/nrfx/soc/nrfx_irqs.h" />
|
||||
<file file_name="../lib/nrfx/soc/nrfx_irqs_nrf51.h" />
|
||||
<file file_name="../lib/nrfx/soc/nrfx_irqs_nrf52810.h" />
|
||||
<file file_name="../lib/nrfx/soc/nrfx_irqs_nrf52832.h" />
|
||||
<file file_name="../lib/nrfx/soc/nrfx_irqs_nrf52840.h" />
|
||||
</folder>
|
||||
</folder>
|
||||
</folder>
|
||||
<configuration
|
||||
Name="Feather52840"
|
||||
c_preprocessor_definitions="NRF52840_XXAA;S140"
|
||||
c_user_include_directories="../src/boards/feather_nrf52840_express"
|
||||
gcc_optimization_level="Debug"
|
||||
linker_memory_map_file="nRF52840_xxAA_MemoryMap.xml" />
|
||||
<configuration
|
||||
Name="Feather52832"
|
||||
c_preprocessor_definitions="NRF52832_XXAA;S132"
|
||||
c_user_include_directories="../src/boards/feather_nrf52832"
|
||||
gcc_optimization_level="Debug"
|
||||
linker_memory_map_file="nRF52832_xxAA_MemoryMap.xml" />
|
||||
<folder Name="src">
|
||||
<folder Name="boards">
|
||||
<folder Name="feather_nrf52840_express">
|
||||
<file file_name="../src/boards/feather_nrf52840_express/board.h" />
|
||||
<file file_name="../src/boards/feather_nrf52840_express/pinconfig.c" />
|
||||
</folder>
|
||||
<file file_name="../src/boards/boards.c" />
|
||||
<file file_name="../src/boards/boards.h" />
|
||||
</folder>
|
||||
<folder
|
||||
Name="cmsis"
|
||||
exclude=""
|
||||
filter="*.c;*.h"
|
||||
path="../src/cmsis"
|
||||
recurse="Yes" />
|
||||
<file file_name="../src/dfu_ble_svc.c" />
|
||||
<file file_name="../src/dfu_init.c" />
|
||||
<file file_name="../src/flash_nrf5x.c" />
|
||||
<file file_name="../src/flash_nrf5x.h" />
|
||||
<file file_name="../src/main.c" />
|
||||
<file file_name="../src/nrfx_config.h" />
|
||||
<file file_name="../src/nrfx_glue.h" />
|
||||
<file file_name="../src/pstorage_platform.h" />
|
||||
<file file_name="../src/sdk_config.h" />
|
||||
<folder
|
||||
Name="usb"
|
||||
exclude=""
|
||||
filter="*.c;*.h"
|
||||
path="../src/usb"
|
||||
recurse="Yes" />
|
||||
</folder>
|
||||
</project>
|
||||
<configuration Name="Feather52840" />
|
||||
<configuration Name="Feather52832" />
|
||||
</solution>
|
||||
-1329
File diff suppressed because it is too large.
Load diff
@@ -1,234 +0,0 @@
|
||||
/*********************************************************************
|
||||
* SEGGER MICROCONTROLLER GmbH & Co. KG *
|
||||
* Solutions for real time microcontroller applications *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* * This software may in its unmodified form be freely redistributed *
|
||||
* in source form. *
|
||||
* * The source code may be modified, provided the source code *
|
||||
* retains the above copyright notice, this list of conditions and *
|
||||
* the following disclaimer. *
|
||||
* * Modified versions of this software in source or linkable form *
|
||||
* may not be distributed without prior consent of SEGGER. *
|
||||
* * This software may only be used for communication with SEGGER *
|
||||
* J-Link debug probes. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* RTT version: 5.12e *
|
||||
* *
|
||||
**********************************************************************
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
File : SEGGER_RTT.h
|
||||
Purpose : Implementation of SEGGER real-time transfer which allows
|
||||
real-time communication on targets which support debugger
|
||||
memory accesses while the CPU is running.
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_RTT_H
|
||||
#define SEGGER_RTT_H
|
||||
|
||||
#include "SEGGER_RTT_Conf.h"
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, fixed
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Types
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
//
|
||||
// Description for a circular buffer (also called "ring buffer")
|
||||
// which is used as up-buffer (T->H)
|
||||
//
|
||||
typedef struct {
|
||||
const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4"
|
||||
char* pBuffer; // Pointer to start of buffer
|
||||
unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty.
|
||||
unsigned WrOff; // Position of next item to be written by either target.
|
||||
volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host.
|
||||
unsigned Flags; // Contains configuration flags
|
||||
} SEGGER_RTT_BUFFER_UP;
|
||||
|
||||
//
|
||||
// Description for a circular buffer (also called "ring buffer")
|
||||
// which is used as down-buffer (H->T)
|
||||
//
|
||||
typedef struct {
|
||||
const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4"
|
||||
char* pBuffer; // Pointer to start of buffer
|
||||
unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty.
|
||||
volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host.
|
||||
unsigned RdOff; // Position of next item to be read by target (down-buffer).
|
||||
unsigned Flags; // Contains configuration flags
|
||||
} SEGGER_RTT_BUFFER_DOWN;
|
||||
|
||||
//
|
||||
// RTT control block which describes the number of buffers available
|
||||
// as well as the configuration for each buffer
|
||||
//
|
||||
//
|
||||
typedef struct {
|
||||
char acID[16]; // Initialized to "SEGGER RTT"
|
||||
int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2)
|
||||
int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2)
|
||||
SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host
|
||||
SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target
|
||||
} SEGGER_RTT_CB;
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Global data
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
extern SEGGER_RTT_CB _SEGGER_RTT;
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT API functions
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
|
||||
int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
|
||||
int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
|
||||
int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
|
||||
int SEGGER_RTT_GetKey (void);
|
||||
unsigned SEGGER_RTT_HasData (unsigned BufferIndex);
|
||||
int SEGGER_RTT_HasKey (void);
|
||||
void SEGGER_RTT_Init (void);
|
||||
unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize);
|
||||
unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize);
|
||||
int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName);
|
||||
int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName);
|
||||
int SEGGER_RTT_WaitKey (void);
|
||||
unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s);
|
||||
void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
//
|
||||
// Function macro for performance optimization
|
||||
//
|
||||
#define SEGGER_RTT_HASDATA(n) (_SEGGER_RTT.aDown[n].WrOff - _SEGGER_RTT.aDown[n].RdOff)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT "Terminal" API functions
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
int SEGGER_RTT_SetTerminal (char TerminalId);
|
||||
int SEGGER_RTT_TerminalOut (char TerminalId, const char* s);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT printf functions (require SEGGER_RTT_printf.c)
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
//
|
||||
// Operating modes. Define behavior if buffer is full (not enough space for entire message)
|
||||
//
|
||||
#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0U) // Skip. Do not block, output nothing. (Default)
|
||||
#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1U) // Trim: Do not block, output as much as fits.
|
||||
#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2U) // Block: Wait until there is space in the buffer.
|
||||
#define SEGGER_RTT_MODE_MASK (3U)
|
||||
|
||||
//
|
||||
// Control sequences, based on ANSI.
|
||||
// Can be used to control color, and clear the screen
|
||||
//
|
||||
#define RTT_CTRL_RESET "[0m" // Reset to default colors
|
||||
#define RTT_CTRL_CLEAR "[2J" // Clear screen, reposition cursor to top left
|
||||
|
||||
#define RTT_CTRL_TEXT_BLACK "[2;30m"
|
||||
#define RTT_CTRL_TEXT_RED "[2;31m"
|
||||
#define RTT_CTRL_TEXT_GREEN "[2;32m"
|
||||
#define RTT_CTRL_TEXT_YELLOW "[2;33m"
|
||||
#define RTT_CTRL_TEXT_BLUE "[2;34m"
|
||||
#define RTT_CTRL_TEXT_MAGENTA "[2;35m"
|
||||
#define RTT_CTRL_TEXT_CYAN "[2;36m"
|
||||
#define RTT_CTRL_TEXT_WHITE "[2;37m"
|
||||
|
||||
#define RTT_CTRL_TEXT_BRIGHT_BLACK "[1;30m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_RED "[1;31m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_GREEN "[1;32m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_YELLOW "[1;33m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_BLUE "[1;34m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "[1;35m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_CYAN "[1;36m"
|
||||
#define RTT_CTRL_TEXT_BRIGHT_WHITE "[1;37m"
|
||||
|
||||
#define RTT_CTRL_BG_BLACK "[24;40m"
|
||||
#define RTT_CTRL_BG_RED "[24;41m"
|
||||
#define RTT_CTRL_BG_GREEN "[24;42m"
|
||||
#define RTT_CTRL_BG_YELLOW "[24;43m"
|
||||
#define RTT_CTRL_BG_BLUE "[24;44m"
|
||||
#define RTT_CTRL_BG_MAGENTA "[24;45m"
|
||||
#define RTT_CTRL_BG_CYAN "[24;46m"
|
||||
#define RTT_CTRL_BG_WHITE "[24;47m"
|
||||
|
||||
#define RTT_CTRL_BG_BRIGHT_BLACK "[4;40m"
|
||||
#define RTT_CTRL_BG_BRIGHT_RED "[4;41m"
|
||||
#define RTT_CTRL_BG_BRIGHT_GREEN "[4;42m"
|
||||
#define RTT_CTRL_BG_BRIGHT_YELLOW "[4;43m"
|
||||
#define RTT_CTRL_BG_BRIGHT_BLUE "[4;44m"
|
||||
#define RTT_CTRL_BG_BRIGHT_MAGENTA "[4;45m"
|
||||
#define RTT_CTRL_BG_BRIGHT_CYAN "[4;46m"
|
||||
#define RTT_CTRL_BG_BRIGHT_WHITE "[4;47m"
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
@@ -1,242 +0,0 @@
|
||||
/*********************************************************************
|
||||
* SEGGER MICROCONTROLLER GmbH & Co. KG *
|
||||
* Solutions for real time microcontroller applications *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* * This software may in its unmodified form be freely redistributed *
|
||||
* in source form. *
|
||||
* * The source code may be modified, provided the source code *
|
||||
* retains the above copyright notice, this list of conditions and *
|
||||
* the following disclaimer. *
|
||||
* * Modified versions of this software in source or linkable form *
|
||||
* may not be distributed without prior consent of SEGGER. *
|
||||
* * This software may only be used for communication with SEGGER *
|
||||
* J-Link debug probes. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* RTT version: 5.12e *
|
||||
* *
|
||||
**********************************************************************
|
||||
----------------------------------------------------------------------
|
||||
File : SEGGER_RTT_Conf.h
|
||||
Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
allows real-time communication on targets which support
|
||||
debugger memory accesses while the CPU is running.
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_RTT_CONF_H
|
||||
#define SEGGER_RTT_CONF_H
|
||||
|
||||
#ifdef __ICCARM__
|
||||
#include <intrinsics.h>
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, configurable
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (2) // Max. number of up-buffers (T->H) available on this target (Default: 2)
|
||||
#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (2) // Max. number of down-buffers (H->T) available on this target (Default: 2)
|
||||
|
||||
#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k)
|
||||
#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)
|
||||
|
||||
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64)
|
||||
|
||||
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
|
||||
|
||||
//
|
||||
// Target is not allowed to perform other RTT operations while string still has not been stored completely.
|
||||
// Otherwise we would probably end up with a mixed string in the buffer.
|
||||
// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
|
||||
//
|
||||
// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
|
||||
// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
|
||||
// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
|
||||
// (Higher priority = lower priority number)
|
||||
// Default value for embOS: 128u
|
||||
// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
// In case of doubt mask all interrupts: 0u
|
||||
//
|
||||
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for SEGGER Embedded Studio,
|
||||
* Rowley CrossStudio and GCC
|
||||
*/
|
||||
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
|
||||
#ifdef __ARM_ARCH_6M__
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs %0, primask \n\t" \
|
||||
"mov r1, $1 \n\t" \
|
||||
"msr primask, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: \
|
||||
); \
|
||||
}
|
||||
|
||||
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs %0, basepri \n\t" \
|
||||
"mov r1, %1 \n\t" \
|
||||
"msr basepri, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: \
|
||||
); \
|
||||
}
|
||||
|
||||
#elif defined(__ARM_ARCH_7A__)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs r1, CPSR \n\t" \
|
||||
"mov %0, r1 \n\t" \
|
||||
"orr r1, r1, #0xC0 \n\t" \
|
||||
"msr CPSR_c, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
|
||||
"mrs r1, CPSR \n\t" \
|
||||
"bic r1, r1, #0xC0 \n\t" \
|
||||
"and r0, r0, #0xC0 \n\t" \
|
||||
"orr r1, r1, r0 \n\t" \
|
||||
"msr CPSR_c, r1 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: "r0", "r1" \
|
||||
); \
|
||||
}
|
||||
#else
|
||||
#define SEGGER_RTT_LOCK()
|
||||
#define SEGGER_RTT_UNLOCK()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for IAR EWARM
|
||||
*/
|
||||
#ifdef __ICCARM__
|
||||
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_PRIMASK(); \
|
||||
__set_PRIMASK(1);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
|
||||
}
|
||||
#elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__)))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_BASEPRI(); \
|
||||
__set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for KEIL ARM
|
||||
*/
|
||||
#ifdef __CC_ARM
|
||||
#if (defined __TARGET_ARCH_6S_M)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
register unsigned char PRIMASK __asm( "primask"); \
|
||||
LockState = PRIMASK; \
|
||||
PRIMASK = 1u; \
|
||||
__schedule_barrier();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \
|
||||
__schedule_barrier(); \
|
||||
}
|
||||
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
register unsigned char BASEPRI __asm( "basepri"); \
|
||||
LockState = BASEPRI; \
|
||||
BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \
|
||||
__schedule_barrier();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \
|
||||
__schedule_barrier(); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration fallback
|
||||
*/
|
||||
#ifndef SEGGER_RTT_LOCK
|
||||
#define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts)
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_RTT_UNLOCK
|
||||
#define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*************************** End of file ****************************/
|
||||
@@ -1,76 +0,0 @@
|
||||
/*********************************************************************
|
||||
* SEGGER MICROCONTROLLER GmbH & Co. KG *
|
||||
* Solutions for real time microcontroller applications *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* * This software may in its unmodified form be freely redistributed *
|
||||
* in source form. *
|
||||
* * The source code may be modified, provided the source code *
|
||||
* retains the above copyright notice, this list of conditions and *
|
||||
* the following disclaimer. *
|
||||
* * Modified versions of this software in source or linkable form *
|
||||
* may not be distributed without prior consent of SEGGER. *
|
||||
* * This software may only be used for communication with SEGGER *
|
||||
* J-Link debug probes. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------- END-OF-HEADER ---------------------------------------------
|
||||
File : SEGGER_RTT_Syscalls_SES.c
|
||||
Purpose : Reimplementation of printf, puts and
|
||||
implementation of __putchar and __getchar using RTT in SES.
|
||||
To use RTT for printf output, include this file in your
|
||||
application.
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
#include "SEGGER_RTT.h"
|
||||
#include "__libc.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int printf(const char *fmt,...) {
|
||||
char buffer[128];
|
||||
va_list args;
|
||||
va_start (args, fmt);
|
||||
int n = vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||
SEGGER_RTT_Write(0, buffer, n);
|
||||
va_end(args);
|
||||
return n;
|
||||
}
|
||||
|
||||
int puts(const char *s) {
|
||||
return SEGGER_RTT_WriteString(0, s);
|
||||
}
|
||||
|
||||
int __putchar(int x, __printf_tag_ptr ctx) {
|
||||
(void)ctx;
|
||||
SEGGER_RTT_Write(0, (char *)&x, 1);
|
||||
return x;
|
||||
}
|
||||
|
||||
int __getchar() {
|
||||
return SEGGER_RTT_WaitKey();
|
||||
}
|
||||
|
||||
/****** End Of File *************************************************/
|
||||
@@ -1,43 +0,0 @@
|
||||
<!DOCTYPE Linker_Placement_File>
|
||||
<Root name="Flash Section Placement">
|
||||
<MemorySegment name="$(FLASH_NAME:FLASH)">
|
||||
<ProgramSection alignment="0x100" load="Yes" name=".vectors" start="$(FLASH_START:)" />
|
||||
<ProgramSection alignment="4" load="Yes" name=".init" />
|
||||
<ProgramSection alignment="4" load="Yes" name=".init_rodata" />
|
||||
<ProgramSection alignment="4" load="Yes" name=".text" />
|
||||
<ProgramSection alignment="4" load="Yes" name=".dtors" />
|
||||
<ProgramSection alignment="4" load="Yes" name=".ctors" />
|
||||
<ProgramSection alignment="4" load="Yes" name=".rodata" />
|
||||
<ProgramSection alignment="4" load="Yes" name=".ARM.exidx" address_symbol="__exidx_start" end_symbol="__exidx_end" />
|
||||
<ProgramSection alignment="4" load="Yes" runin=".fast_run" name=".fast" />
|
||||
<ProgramSection alignment="4" load="Yes" runin=".data_run" name=".data" />
|
||||
<ProgramSection alignment="4" load="Yes" runin=".tdata_run" name=".tdata" />
|
||||
</MemorySegment>
|
||||
<MemorySegment name="$(RAM_NAME:RAM);SRAM">
|
||||
<ProgramSection alignment="0x100" load="No" name=".vectors_ram" start="$(RAM_START:$(SRAM_START:))" />
|
||||
<ProgramSection alignment="4" load="No" name=".fast_run" />
|
||||
<ProgramSection alignment="4" load="No" name=".data_run" />
|
||||
<ProgramSection alignment="4" load="No" name=".tdata_run" />
|
||||
<ProgramSection alignment="4" load="No" name=".bss" />
|
||||
<ProgramSection alignment="4" load="No" name=".tbss" />
|
||||
<ProgramSection alignment="4" load="No" name=".non_init" />
|
||||
<ProgramSection alignment="4" size="__HEAPSIZE__" load="No" name=".heap" />
|
||||
<ProgramSection alignment="8" size="__STACKSIZE__" load="No" place_from_segment_end="Yes" name=".stack" />
|
||||
<ProgramSection alignment="8" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process" />
|
||||
</MemorySegment>
|
||||
<MemorySegment name="$(FLASH2_NAME:BOOTLOADER_SETTINGS)">
|
||||
<ProgramSection alignment="4" load="No" name=".bootloaderSettings" />
|
||||
</MemorySegment>
|
||||
<MemorySegment name="$(FLASH3_NAME:MBR_PARAMS_PAGE)">
|
||||
<ProgramSection alignment="4" load="No" name=".mbrParamsPage" keep="Yes" />
|
||||
</MemorySegment>
|
||||
<MemorySegment name="$(FLASH4_NAME:UICR_BOOTLOADER)">
|
||||
<ProgramSection alignment="4" load="Yes" name=".uicrBootStartAddress" keep="Yes" />
|
||||
</MemorySegment>
|
||||
<MemorySegment name="$(FLASH5_NAME:UICR_MBR_PARAM_PAGE)">
|
||||
<ProgramSection alignment="4" load="Yes" name=".uicrMbrParamsPageAddress" keep="Yes" />
|
||||
</MemorySegment>
|
||||
<MemorySegment name="$(RAM2_NAME:NOINIT)">
|
||||
<ProgramSection alignment="4" load="No" name=".noinit" />
|
||||
</MemorySegment>
|
||||
</Root>
|
||||
@@ -1,10 +0,0 @@
|
||||
<!DOCTYPE Board_Memory_Definition_File>
|
||||
<root name="nRF52832_xxAA">
|
||||
<MemorySegment name="FLASH" start="0x74000" size="0xA000" access="ReadOnly" />
|
||||
<MemorySegment name="BOOTLOADER_SETTINGS" start="0x0007F000" size="0x1000" access="ReadOnly" />
|
||||
<MemorySegment name="MBR_PARAMS_PAGE" start="0x0007E000" size="0x1000" access="ReadOnly" />
|
||||
<MemorySegment name="UICR_BOOTLOADER" start="0x10001014" size="0x04" access="ReadOnly" />
|
||||
<MemorySegment name="UICR_MBR_PARAM_PAGE" start="0x10001018" size="0x04" access="ReadOnly" />
|
||||
<MemorySegment name="RAM" start="0x20003000" size="0x4F7C" access="Read/Write" />
|
||||
<MemorySegment name="NOINIT" start="0x20007F80" size="0x80" access="Read/Write" />
|
||||
</root>
|
||||
@@ -1,10 +0,0 @@
|
||||
<!DOCTYPE Board_Memory_Definition_File>
|
||||
<root name="nRF52840_xxAA">
|
||||
<MemorySegment name="FLASH" start="0x000F4000" size="0xA000" access="ReadOnly" />
|
||||
<MemorySegment name="BOOTLOADER_SETTINGS" start="0x000FF000" size="0x1000" access="ReadOnly" />
|
||||
<MemorySegment name="MBR_PARAMS_PAGE" start="0x000FE000" size="0x1000" access="ReadOnly" />
|
||||
<MemorySegment name="UICR_BOOTLOADER" start="0x10001014" size="0x04" access="ReadOnly" />
|
||||
<MemorySegment name="UICR_MBR_PARAM_PAGE" start="0x10001018" size="0x04" access="ReadOnly" />
|
||||
<MemorySegment name="RAM" start="0x20008000" size="0x38000" access="Read/Write" />
|
||||
<MemorySegment name="NOINIT" start="0x20007F80" size="0x80" access="Read/Write" />
|
||||
</root>
|
||||
@@ -1,19 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* Solutions for real time microcontroller applications *
|
||||
*****************************************************************************
|
||||
* *
|
||||
* (c) 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* Internet: www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
function Reset() {
|
||||
TargetInterface.resetAndStop();
|
||||
}
|
||||
|
||||
function EnableTrace(traceInterfaceType) {
|
||||
// TODO: Enable trace
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,420 +0,0 @@
|
||||
// SEGGER Embedded Studio, runtime support.
|
||||
//
|
||||
// Copyright (c) 2014-2017 SEGGER Microcontroller GmbH & Co KG
|
||||
// Copyright (c) 2001-2017 Rowley Associates Limited.
|
||||
//
|
||||
// This file may be distributed under the terms of the License Agreement
|
||||
// provided with this software.
|
||||
//
|
||||
// THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
//
|
||||
// Preprocessor Definitions
|
||||
// ------------------------
|
||||
// APP_ENTRY_POINT
|
||||
//
|
||||
// Defines the application entry point function, if undefined this setting
|
||||
// defaults to "main".
|
||||
//
|
||||
// INITIALIZE_STACK
|
||||
//
|
||||
// If defined, the contents of the stack will be initialized to a the
|
||||
// value 0xCC.
|
||||
//
|
||||
// INITIALIZE_SECONDARY_SECTIONS
|
||||
//
|
||||
// If defined, the .data2, .text2, .rodata2 and .bss2 sections will be initialized.
|
||||
//
|
||||
// INITIALIZE_TCM_SECTIONS
|
||||
//
|
||||
// If defined, the .data_tcm, .text_tcm, .rodata_tcm and .bss_tcm sections
|
||||
// will be initialized.
|
||||
//
|
||||
// INITIALIZE_USER_SECTIONS
|
||||
//
|
||||
// If defined, the function InitializeUserMemorySections will be called prior
|
||||
// to entering main in order to allow the user to initialize any user defined
|
||||
// memory sections.
|
||||
//
|
||||
// FULL_LIBRARY
|
||||
//
|
||||
// If defined then
|
||||
// - argc, argv are setup by the debug_getargs.
|
||||
// - the exit symbol is defined and executes on return from main.
|
||||
// - the exit symbol calls destructors, atexit functions and then debug_exit.
|
||||
//
|
||||
// If not defined then
|
||||
// - argc and argv are zero.
|
||||
// - the exit symbol is defined, executes on return from main and loops
|
||||
//
|
||||
|
||||
#ifndef APP_ENTRY_POINT
|
||||
#define APP_ENTRY_POINT main
|
||||
#endif
|
||||
|
||||
#ifndef ARGSSPACE
|
||||
#define ARGSSPACE 128
|
||||
#endif
|
||||
.syntax unified
|
||||
|
||||
.global _start
|
||||
.extern APP_ENTRY_POINT
|
||||
.global exit
|
||||
.weak exit
|
||||
|
||||
#ifdef INITIALIZE_USER_SECTIONS
|
||||
.extern InitializeUserMemorySections
|
||||
#endif
|
||||
|
||||
.section .init, "ax"
|
||||
.code 16
|
||||
.align 2
|
||||
.thumb_func
|
||||
|
||||
_start:
|
||||
/* Set up main stack if size > 0 */
|
||||
ldr r1, =__stack_end__
|
||||
ldr r0, =__stack_start__
|
||||
subs r2, r1, r0
|
||||
beq 1f
|
||||
#ifdef __ARM_EABI__
|
||||
movs r2, #0x7
|
||||
bics r1, r2
|
||||
#endif
|
||||
mov sp, r1
|
||||
#ifdef INITIALIZE_STACK
|
||||
movs r2, #0xCC
|
||||
ldr r0, =__stack_start__
|
||||
bl memory_set
|
||||
#endif
|
||||
1:
|
||||
|
||||
/* Set up process stack if size > 0 */
|
||||
ldr r1, =__stack_process_end__
|
||||
ldr r0, =__stack_process_start__
|
||||
subs r2, r1, r0
|
||||
beq 1f
|
||||
#ifdef __ARM_EABI__
|
||||
movs r2, #0x7
|
||||
bics r1, r2
|
||||
#endif
|
||||
msr psp, r1
|
||||
movs r2, #2
|
||||
msr control, r2
|
||||
#ifdef INITIALIZE_STACK
|
||||
movs r2, #0xCC
|
||||
bl memory_set
|
||||
#endif
|
||||
1:
|
||||
|
||||
/* Copy initialized memory sections into RAM (if necessary). */
|
||||
ldr r0, =__data_load_start__
|
||||
ldr r1, =__data_start__
|
||||
ldr r2, =__data_end__
|
||||
bl memory_copy
|
||||
ldr r0, =__text_load_start__
|
||||
ldr r1, =__text_start__
|
||||
ldr r2, =__text_end__
|
||||
bl memory_copy
|
||||
ldr r0, =__fast_load_start__
|
||||
ldr r1, =__fast_start__
|
||||
ldr r2, =__fast_end__
|
||||
bl memory_copy
|
||||
ldr r0, =__ctors_load_start__
|
||||
ldr r1, =__ctors_start__
|
||||
ldr r2, =__ctors_end__
|
||||
bl memory_copy
|
||||
ldr r0, =__dtors_load_start__
|
||||
ldr r1, =__dtors_start__
|
||||
ldr r2, =__dtors_end__
|
||||
bl memory_copy
|
||||
ldr r0, =__rodata_load_start__
|
||||
ldr r1, =__rodata_start__
|
||||
ldr r2, =__rodata_end__
|
||||
bl memory_copy
|
||||
ldr r0, =__tdata_load_start__
|
||||
ldr r1, =__tdata_start__
|
||||
ldr r2, =__tdata_end__
|
||||
bl memory_copy
|
||||
#ifdef INITIALIZE_SECONDARY_SECTIONS
|
||||
ldr r0, =__data2_load_start__
|
||||
ldr r1, =__data2_start__
|
||||
ldr r2, =__data2_end__
|
||||
bl memory_copy
|
||||
ldr r0, =__text2_load_start__
|
||||
ldr r1, =__text2_start__
|
||||
ldr r2, =__text2_end__
|
||||
bl memory_copy
|
||||
ldr r0, =__rodata2_load_start__
|
||||
ldr r1, =__rodata2_start__
|
||||
ldr r2, =__rodata2_end__
|
||||
bl memory_copy
|
||||
#endif /* #ifdef INITIALIZE_SECONDARY_SECTIONS */
|
||||
#ifdef INITIALIZE_TCM_SECTIONS
|
||||
ldr r0, =__data_tcm_load_start__
|
||||
ldr r1, =__data_tcm_start__
|
||||
ldr r2, =__data_tcm_end__
|
||||
bl memory_copy
|
||||
ldr r0, =__text_tcm_load_start__
|
||||
ldr r1, =__text_tcm_start__
|
||||
ldr r2, =__text_tcm_end__
|
||||
bl memory_copy
|
||||
ldr r0, =__rodata_tcm_load_start__
|
||||
ldr r1, =__rodata_tcm_start__
|
||||
ldr r2, =__rodata_tcm_end__
|
||||
bl memory_copy
|
||||
#endif /* #ifdef INITIALIZE_TCM_SECTIONS */
|
||||
|
||||
/* Zero the bss. */
|
||||
ldr r0, =__bss_start__
|
||||
ldr r1, =__bss_end__
|
||||
movs r2, #0
|
||||
bl memory_set
|
||||
ldr r0, =__tbss_start__
|
||||
ldr r1, =__tbss_end__
|
||||
movs r2, #0
|
||||
bl memory_set
|
||||
#ifdef INITIALIZE_SECONDARY_SECTIONS
|
||||
ldr r0, =__bss2_start__
|
||||
ldr r1, =__bss2_end__
|
||||
mov r2, #0
|
||||
bl memory_set
|
||||
#endif /* #ifdef INITIALIZE_SECONDARY_SECTIONS */
|
||||
#ifdef INITIALIZE_TCM_SECTIONS
|
||||
ldr r0, =__bss_tcm_start__
|
||||
ldr r1, =__bss_tcm_end__
|
||||
mov r2, #0
|
||||
bl memory_set
|
||||
#endif /* #ifdef INITIALIZE_TCM_SECTIONS */
|
||||
|
||||
/* Initialize the heap */
|
||||
ldr r0, = __heap_start__
|
||||
ldr r1, = __heap_end__
|
||||
subs r1, r1, r0
|
||||
cmp r1, #8
|
||||
blt 1f
|
||||
movs r2, #0
|
||||
str r2, [r0]
|
||||
adds r0, r0, #4
|
||||
str r1, [r0]
|
||||
1:
|
||||
|
||||
#ifdef INITIALIZE_USER_SECTIONS
|
||||
ldr r2, =InitializeUserMemorySections
|
||||
blx r2
|
||||
#endif
|
||||
|
||||
/* Call constructors */
|
||||
ldr r0, =__ctors_start__
|
||||
ldr r1, =__ctors_end__
|
||||
ctor_loop:
|
||||
cmp r0, r1
|
||||
beq ctor_end
|
||||
ldr r2, [r0]
|
||||
adds r0, #4
|
||||
push {r0-r1}
|
||||
blx r2
|
||||
pop {r0-r1}
|
||||
b ctor_loop
|
||||
ctor_end:
|
||||
|
||||
/* Setup initial call frame */
|
||||
movs r0, #0
|
||||
mov lr, r0
|
||||
mov r12, sp
|
||||
|
||||
.type start, function
|
||||
start:
|
||||
/* Jump to application entry point */
|
||||
#ifdef FULL_LIBRARY
|
||||
movs r0, #ARGSSPACE
|
||||
ldr r1, =args
|
||||
ldr r2, =debug_getargs
|
||||
blx r2
|
||||
ldr r1, =args
|
||||
#else
|
||||
movs r0, #0
|
||||
movs r1, #0
|
||||
#endif
|
||||
ldr r2, =APP_ENTRY_POINT
|
||||
blx r2
|
||||
|
||||
.thumb_func
|
||||
exit:
|
||||
#ifdef FULL_LIBRARY
|
||||
mov r5, r0 // save the exit parameter/return result
|
||||
|
||||
/* Call destructors */
|
||||
ldr r0, =__dtors_start__
|
||||
ldr r1, =__dtors_end__
|
||||
dtor_loop:
|
||||
cmp r0, r1
|
||||
beq dtor_end
|
||||
ldr r2, [r0]
|
||||
add r0, #4
|
||||
push {r0-r1}
|
||||
blx r2
|
||||
pop {r0-r1}
|
||||
b dtor_loop
|
||||
dtor_end:
|
||||
|
||||
/* Call atexit functions */
|
||||
ldr r2, =_execute_at_exit_fns
|
||||
blx r2
|
||||
|
||||
/* Call debug_exit with return result/exit parameter */
|
||||
mov r0, r5
|
||||
ldr r2, =debug_exit
|
||||
blx r2
|
||||
#endif
|
||||
|
||||
/* Returned from application entry point, loop forever. */
|
||||
exit_loop:
|
||||
b exit_loop
|
||||
|
||||
.thumb_func
|
||||
memory_copy:
|
||||
cmp r0, r1
|
||||
beq 2f
|
||||
subs r2, r2, r1
|
||||
beq 2f
|
||||
1:
|
||||
ldrb r3, [r0]
|
||||
adds r0, r0, #1
|
||||
strb r3, [r1]
|
||||
adds r1, r1, #1
|
||||
subs r2, r2, #1
|
||||
bne 1b
|
||||
2:
|
||||
bx lr
|
||||
|
||||
.thumb_func
|
||||
memory_set:
|
||||
cmp r0, r1
|
||||
beq 1f
|
||||
strb r2, [r0]
|
||||
adds r0, r0, #1
|
||||
b memory_set
|
||||
1:
|
||||
bx lr
|
||||
|
||||
// default C/C++ library helpers
|
||||
|
||||
.macro HELPER helper_name
|
||||
.section .text.\helper_name, "ax", %progbits
|
||||
.global \helper_name
|
||||
.weak \helper_name
|
||||
\helper_name:
|
||||
.thumb_func
|
||||
.endm
|
||||
|
||||
.macro JUMPTO name
|
||||
#if defined(__thumb__) && !defined(__thumb2__)
|
||||
mov r12, r0
|
||||
ldr r0, =\name
|
||||
push {r0}
|
||||
mov r0, r12
|
||||
pop {pc}
|
||||
#else
|
||||
b \name
|
||||
#endif
|
||||
.endm
|
||||
|
||||
HELPER __aeabi_read_tp
|
||||
ldr r0, =__tbss_start__-8
|
||||
bx lr
|
||||
HELPER __heap_lock
|
||||
bx lr
|
||||
HELPER __heap_unlock
|
||||
bx lr
|
||||
HELPER __printf_lock
|
||||
bx lr
|
||||
HELPER __printf_unlock
|
||||
bx lr
|
||||
HELPER __scanf_lock
|
||||
bx lr
|
||||
HELPER __scanf_unlock
|
||||
bx lr
|
||||
HELPER __debug_io_lock
|
||||
bx lr
|
||||
HELPER __debug_io_unlock
|
||||
bx lr
|
||||
HELPER abort
|
||||
b .
|
||||
HELPER __assert
|
||||
b .
|
||||
HELPER __aeabi_assert
|
||||
b .
|
||||
HELPER __cxa_pure_virtual
|
||||
b .
|
||||
HELPER __cxa_guard_acquire
|
||||
ldr r3, [r0]
|
||||
#if defined(__thumb__) && !defined(__thumb2__)
|
||||
movs r0, #1
|
||||
tst r3, r0
|
||||
#else
|
||||
tst r3, #1
|
||||
#endif
|
||||
beq 1f
|
||||
movs r0, #0
|
||||
bx lr
|
||||
1:
|
||||
movs r0, #1
|
||||
bx lr
|
||||
HELPER __cxa_guard_release
|
||||
movs r3, #1
|
||||
str r3, [r0]
|
||||
bx lr
|
||||
HELPER __cxa_guard_abort
|
||||
bx lr
|
||||
HELPER __sync_synchronize
|
||||
bx lr
|
||||
HELPER __getchar
|
||||
JUMPTO debug_getchar
|
||||
HELPER __putchar
|
||||
JUMPTO debug_putchar
|
||||
HELPER __open
|
||||
JUMPTO debug_fopen
|
||||
HELPER __close
|
||||
JUMPTO debug_fclose
|
||||
HELPER __write
|
||||
mov r3, r0
|
||||
mov r0, r1
|
||||
movs r1, #1
|
||||
JUMPTO debug_fwrite
|
||||
HELPER __read
|
||||
mov r3, r0
|
||||
mov r0, r1
|
||||
movs r1, #1
|
||||
JUMPTO debug_fread
|
||||
HELPER __seek
|
||||
push {r4, lr}
|
||||
mov r4, r0
|
||||
bl debug_fseek
|
||||
cmp r0, #0
|
||||
bne 1f
|
||||
mov r0, r4
|
||||
bl debug_ftell
|
||||
pop {r4, pc}
|
||||
1:
|
||||
ldr r0, =-1
|
||||
pop {r4, pc}
|
||||
// char __user_locale_name_buffer[];
|
||||
.section .bss.__user_locale_name_buffer, "aw", %nobits
|
||||
.global __user_locale_name_buffer
|
||||
.weak __user_locale_name_buffer
|
||||
__user_locale_name_buffer:
|
||||
.word 0x0
|
||||
|
||||
#ifdef FULL_LIBRARY
|
||||
.bss
|
||||
args:
|
||||
.space ARGSSPACE
|
||||
#endif
|
||||
|
||||
/* Setup attibutes of stack and heap sections so they don't take up room in the elf file */
|
||||
.section .stack, "wa", %nobits
|
||||
.section .stack_process, "wa", %nobits
|
||||
.section .heap, "wa", %nobits
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52833)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
+417
-196
@@ -27,40 +27,39 @@
|
||||
#include "app_scheduler.h"
|
||||
#include "app_timer.h"
|
||||
|
||||
#ifdef LED_APA102
|
||||
#ifdef LED_APA102_CLK
|
||||
#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);
|
||||
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102_CLK)
|
||||
void neopixel_init(void);
|
||||
void neopixel_write(uint8_t* pixels);
|
||||
void neopixel_teardown(void);
|
||||
#endif
|
||||
|
||||
//------------- IMPLEMENTATION -------------//
|
||||
//--------------------------------------------------------------------+
|
||||
// IMPLEMENTATION
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
static uint32_t _systick_count = 0;
|
||||
void SysTick_Handler(void) {
|
||||
_systick_count++;
|
||||
led_tick();
|
||||
}
|
||||
|
||||
#if defined(BUTTON_DFU) || defined(BUTTON_FRESET)
|
||||
|
||||
void button_init(uint32_t pin)
|
||||
{
|
||||
if ( BUTTON_PULL == NRF_GPIO_PIN_PULLDOWN )
|
||||
{
|
||||
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;
|
||||
}
|
||||
@@ -68,9 +67,9 @@ bool button_pressed(uint32_t pin)
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -93,8 +92,14 @@ void board_init(void)
|
||||
led_pwm_init(LED_SECONDARY, LED_SECONDARY_PIN);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102_CLK)
|
||||
// use neopixel for use enumeration
|
||||
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
|
||||
#ifdef NEOPIXEL_POWER_PIN
|
||||
nrf_gpio_cfg_output(NEOPIXEL_POWER_PIN);
|
||||
nrf_gpio_pin_write(NEOPIXEL_POWER_PIN, 1);
|
||||
#endif
|
||||
|
||||
neopixel_init();
|
||||
#endif
|
||||
|
||||
@@ -104,26 +109,33 @@ 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);
|
||||
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
// for some reason bellow condition is true even though debugger show 3.0V
|
||||
// pyocd> rw 0x10001304
|
||||
// 10001304: fffffffc
|
||||
// it leads to infinite boot loop. Let wait for NVM to be ready first.
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) == (UICR_REGOUT0_VOUT_DEFAULT << 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){}
|
||||
// to avoid infinity boot loop reset only if REGOUT0 was set correctly
|
||||
if((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) == (UICR_REGOUT0_VALUE << UICR_REGOUT0_VOUT_Pos)){
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -135,11 +147,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;
|
||||
|
||||
@@ -148,15 +162,19 @@ void board_teardown(void)
|
||||
led_pwm_teardown();
|
||||
#endif
|
||||
|
||||
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
|
||||
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102_CLK)
|
||||
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
|
||||
@@ -164,49 +182,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;
|
||||
|
||||
@@ -215,15 +345,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;
|
||||
@@ -232,13 +362,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);
|
||||
@@ -248,102 +376,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 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);
|
||||
void led_tick(void) {
|
||||
uint32_t millis = _systick_count;
|
||||
|
||||
#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
|
||||
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
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
|
||||
if (final_color != NULL) {
|
||||
neopixel_write(final_color);
|
||||
}
|
||||
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_CLK)
|
||||
if (final_color != NULL) {
|
||||
neopixel_write(final_color);
|
||||
}
|
||||
#else
|
||||
(void) final_color;
|
||||
(void) final_color;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -356,11 +485,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
|
||||
@@ -396,40 +524,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++;
|
||||
}
|
||||
@@ -443,17 +564,18 @@ 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
|
||||
#ifdef LED_APA102_CLK
|
||||
#define BYTE_PER_PIXEL 4
|
||||
|
||||
// 4 zero bytes are required to initiate update
|
||||
@@ -462,8 +584,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);
|
||||
@@ -494,8 +615,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);
|
||||
|
||||
@@ -504,8 +624,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
|
||||
@@ -516,10 +635,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;
|
||||
@@ -547,15 +666,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);
|
||||
@@ -564,10 +681,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
|
||||
@@ -112,6 +112,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
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -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)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -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 nrf52)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52833)
|
||||
@@ -1,2 +1 @@
|
||||
MCU_SUB_VARIANT = nrf52833
|
||||
SD_VERSION = 7.3.0
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -36,6 +36,7 @@
|
||||
#define LED_STATE_ON 1
|
||||
|
||||
#define LED_NEOPIXEL _PINNUM(0, 16)
|
||||
#define NEOPIXEL_POWER_PIN _PINNUM(1, 14)
|
||||
#define NEOPIXELS_NUMBER 1
|
||||
#define BOARD_RGB_BRIGHTNESS 0x040404
|
||||
|
||||
@@ -63,7 +64,7 @@
|
||||
//------------- UF2 -------------//
|
||||
#define UF2_PRODUCT_NAME "Adafruit Feather nRF52840 Express"
|
||||
#define UF2_VOLUME_LABEL "FTHR840BOOT"
|
||||
#define UF2_BOARD_ID "nRF52840-Feather-revD"
|
||||
#define UF2_BOARD_ID "nRF52840-Feather-revE"
|
||||
#define UF2_INDEX_URL "https://www.adafruit.com/product/4062"
|
||||
|
||||
#endif // _FEATHER_NRF52840_H
|
||||
@@ -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 */
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -34,9 +34,14 @@
|
||||
#define LED_PRIMARY_PIN _PINNUM(0, 6)
|
||||
#define LED_STATE_ON 1
|
||||
|
||||
#define LED_NEOPIXEL _PINNUM(0, 8)
|
||||
#define NEOPIXELS_NUMBER 1
|
||||
#define BOARD_RGB_BRIGHTNESS 0x040404
|
||||
#define LED_APA102_CLK _PINNUM(1, 9)
|
||||
#define LED_APA102_DATA _PINNUM(0, 8)
|
||||
#define LED_APA102_BRIGHTNESS 0x1
|
||||
#define APA102_NUMBER 1
|
||||
|
||||
// For dotstart set to max for colour information is not masked off
|
||||
#define BOARD_RGB_BRIGHTNESS 0xffffffff
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* BUTTON
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -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
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52)
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 _MBN52832DK_H
|
||||
#define _MBN52832DK_H
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* LED
|
||||
*------------------------------------------------------------------*/
|
||||
#define LEDS_NUMBER 2
|
||||
#define LED_PRIMARY_PIN 17 // LED1
|
||||
#define LED_SECONDARY_PIN 18 // LED2
|
||||
#define LED_STATE_ON 1
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* BUTTON
|
||||
*------------------------------------------------------------------*/
|
||||
#define BUTTONS_NUMBER 2
|
||||
#define BUTTON_1 13
|
||||
#define BUTTON_2 14
|
||||
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* UART (only used by nRF52832)
|
||||
*------------------------------------------------------------------*/
|
||||
#define RX_PIN_NUMBER 8
|
||||
#define TX_PIN_NUMBER 6
|
||||
#define CTS_PIN_NUMBER 0
|
||||
#define RTS_PIN_NUMBER 0
|
||||
#define HWFC false
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// BLE OTA
|
||||
//--------------------------------------------------------------------+
|
||||
#define BLEDIS_MANUFACTURER "Murata"
|
||||
#define BLEDIS_MODEL "MBN52832DK"
|
||||
|
||||
#define UF2_BOARD_ID "nRF52832-MBN52832DK-v1"
|
||||
#define UF2_PRODUCT_NAME "Murata MBN52832DK"
|
||||
#define UF2_INDEX_URL "https://www.murata.com/ja-jp/products/connectivitymodule/bluetooth/overview/lineup/mbn52832"
|
||||
|
||||
#endif // _MBN52832DK_H
|
||||
@@ -0,0 +1,2 @@
|
||||
# nrf52 is nrf52832
|
||||
MCU_SUB_VARIANT = nrf52
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -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_ */
|
||||
@@ -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 */
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 _NRFMICRO_NRF52840
|
||||
#define _NRFMICRO_NRF52840
|
||||
|
||||
#define _PINNUM(port, pin) ((port)*32 + (pin))
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* LED
|
||||
*------------------------------------------------------------------*/
|
||||
#define LEDS_NUMBER 1
|
||||
#define LED_PRIMARY_PIN _PINNUM(1, 10)
|
||||
#define LED_STATE_ON 1 // State when LED is lit (active HIGH)
|
||||
|
||||
#define NEOPIXELS_NUMBER 0
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* BUTTON
|
||||
*------------------------------------------------------------------*/
|
||||
#define BUTTONS_NUMBER 2
|
||||
#define BUTTON_1 _PINNUM(1, 2) // DFU
|
||||
#define BUTTON_2 _PINNUM(0, 12) // FRST
|
||||
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// BLE OTA
|
||||
//--------------------------------------------------------------------+
|
||||
#define BLEDIS_MANUFACTURER "nRFMicro"
|
||||
#define BLEDIS_MODEL "nRFMicro nRF52840"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USB
|
||||
//--------------------------------------------------------------------+
|
||||
#define USB_DESC_VID 0x1209
|
||||
#define USB_DESC_UF2_PID 0x5284
|
||||
#define USB_DESC_CDC_ONLY_PID 0x5284
|
||||
|
||||
//------------- UF2 -------------//
|
||||
#define UF2_PRODUCT_NAME "nRFMicro"
|
||||
#define UF2_VOLUME_LABEL "NRFMICRO"
|
||||
#define UF2_BOARD_ID "nRF52840-nRFMicro-v0"
|
||||
#define UF2_INDEX_URL "https://github.com/joric/nrfmicro/wiki"
|
||||
|
||||
#endif // _NRFMICRO_NRF52840
|
||||
@@ -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 */
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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 _OMNIMO_NRF52840_H
|
||||
#define _OMNIMO_NRF52840_H
|
||||
|
||||
#define _PINNUM(port, pin) ((port)*32 + (pin))
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* LED
|
||||
*------------------------------------------------------------------*/
|
||||
#define LEDS_NUMBER 2
|
||||
#define LED_PRIMARY_PIN _PINNUM(1, 15)
|
||||
#define LED_SECONDARY_PIN _PINNUM(1, 10)
|
||||
#define LED_STATE_ON 1
|
||||
|
||||
#define LED_NEOPIXEL _PINNUM(0, 16)
|
||||
|
||||
#define NEOPIXELS_NUMBER 1
|
||||
#define BOARD_RGB_BRIGHTNESS 0x040404
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* BUTTON
|
||||
*------------------------------------------------------------------*/
|
||||
#define BUTTONS_NUMBER 2
|
||||
#define BUTTON_1 _PINNUM(1, 02)
|
||||
#define BUTTON_2 _PINNUM(1, 07)
|
||||
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// BLE OTA
|
||||
//--------------------------------------------------------------------+
|
||||
#define BLEDIS_MANUFACTURER "eAFAQ"
|
||||
#define BLEDIS_MODEL "OMNIMO nRF52840"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USB
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
//Shared VID/PID with pca10056
|
||||
#define USB_DESC_VID 0x1209
|
||||
#define USB_DESC_UF2_PID 0xCECE
|
||||
#define USB_DESC_CDC_ONLY_PID 0xCECE
|
||||
|
||||
//------------- UF2 -------------//
|
||||
#define UF2_PRODUCT_NAME "Omnimo nRF52840"
|
||||
#define UF2_VOLUME_LABEL "OMNIn52BOOT"
|
||||
#define UF2_BOARD_ID "nRF52840-Omnimo"
|
||||
#define UF2_INDEX_URL "https://www.crowdsupply.com/eafaq/omnimo-nrf52840"
|
||||
|
||||
#endif // _OMNIMO_NRF52840_H
|
||||
@@ -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 */
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -57,10 +57,10 @@
|
||||
// USB
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Shared VID/PID with Feather nRF52840, will be disabled for building in the future
|
||||
// Shared VID/PID with pca10056
|
||||
#define USB_DESC_VID 0x239A
|
||||
#define USB_DESC_UF2_PID 0x0029
|
||||
#define USB_DESC_CDC_ONLY_PID 0x0029
|
||||
#define USB_DESC_UF2_PID 0x00DA
|
||||
#define USB_DESC_CDC_ONLY_PID 0x00DA
|
||||
|
||||
#define UF2_PRODUCT_NAME "Particle Argon"
|
||||
#define UF2_VOLUME_LABEL "ARGONBOOT "
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -57,10 +57,10 @@
|
||||
// USB
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Shared VID/PID with Feather nRF52840, will be disabled for building in the future
|
||||
// Shared VID/PID with pca10056
|
||||
#define USB_DESC_VID 0x239A
|
||||
#define USB_DESC_UF2_PID 0x0029
|
||||
#define USB_DESC_CDC_ONLY_PID 0x0029
|
||||
#define USB_DESC_UF2_PID 0x00DA
|
||||
#define USB_DESC_CDC_ONLY_PID 0x00DA
|
||||
|
||||
#define UF2_PRODUCT_NAME "Particle Boron"
|
||||
#define UF2_VOLUME_LABEL "BORONBOOT "
|
||||
|
||||
Loaded 100 of 138 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user