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