mirror of
https://github.com/oltaco/Adafruit_nRF52_Bootloader_OTAFIX.git
synced 2026-10-25 17:03:59 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29ca3ebfab | ||
|
|
4e700d4904 | ||
|
|
8473ff6f35 | ||
|
|
5f99d530ff | ||
|
|
c5150ccf02 | ||
|
|
438a08e0ac | ||
|
|
2d68ec56e3 | ||
|
|
836c8dcc76 | ||
|
|
9e25f4ac0a | ||
|
|
a73fe207a8 | ||
|
|
ea3bb737de | ||
|
|
0bc8a8993f | ||
|
|
78b39b4347 | ||
|
|
e7450022a8 | ||
|
|
4f8c2afabf | ||
|
|
2e6c877d1b | ||
|
|
59df4f9e8c | ||
|
|
64d8e34567 | ||
|
|
3d920bf62b | ||
|
|
ed9bf7a8dd | ||
|
|
0eead42aec | ||
|
|
a6a8962b1d | ||
|
|
79add7baf5 | ||
|
|
101a54da10 | ||
|
|
e81391f395 | ||
|
|
eaaf5f8e84 | ||
|
|
1c85a7a5be | ||
|
|
f5a1947974 | ||
|
|
66db5aeda3 | ||
|
|
36a1f428dd |
No files matched your search
@@ -3,10 +3,8 @@
|
||||
*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.*
|
||||
|
||||
@@ -9,95 +9,51 @@ on:
|
||||
- created
|
||||
|
||||
jobs:
|
||||
set-matrix:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set matrix
|
||||
id: set-matrix
|
||||
working-directory: src/boards
|
||||
run: |
|
||||
MATRIX_JSON=$(ls -d */ | sed 's/\/$//' | jq -R -s -c 'split("\n")[:-1]')
|
||||
echo "matrix=$MATRIX_JSON"
|
||||
echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT
|
||||
|
||||
build:
|
||||
needs: set-matrix
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board:
|
||||
# Adafruit Boards
|
||||
- 'circuitplayground_nrf52840'
|
||||
- 'clue_nrf52840'
|
||||
- 'feather_nrf52832'
|
||||
- 'feather_nrf52833_express'
|
||||
- 'feather_nrf52840_express'
|
||||
- 'feather_nrf52840_sense'
|
||||
- 'itsybitsy_nrf52840_express'
|
||||
- 'metro_nrf52840_express'
|
||||
- 'ledglasses_nrf52840'
|
||||
# Other Makers (Alphabetical order)
|
||||
- 'adm_b_nrf52840_1'
|
||||
- 'ae_bl652_bo'
|
||||
- 'aramcon_badge_2019'
|
||||
- 'aramcon2_badge'
|
||||
- 'arcade_feather_nrf52840_express'
|
||||
- 'arduino_nano_33_ble'
|
||||
- 'bast_ble'
|
||||
- 'bluemicro_nrf52833'
|
||||
- 'bluemicro_nrf52840'
|
||||
- 'challenger_840_ble'
|
||||
- 'ebyte_e104_bt5032a'
|
||||
- 'ebyte_e73_tbb'
|
||||
- 'electronut_labs_papyr'
|
||||
- 'ikigaisense_vita'
|
||||
- 'm60_keyboard'
|
||||
- 'mdk_nrf52840_dongle'
|
||||
- 'mikoto'
|
||||
- 'nice_nano'
|
||||
- 'nrf52840_bboard'
|
||||
- 'nRF52840_connect_kit'
|
||||
- 'nrf52840_m2'
|
||||
- 'ohs2020_badge'
|
||||
- 'particle_argon'
|
||||
- 'particle_boron'
|
||||
- 'particle_xenon'
|
||||
- 'pca10056'
|
||||
- 'pca10059'
|
||||
- 'pca10100'
|
||||
- 'pitaya_go'
|
||||
- 'raytac_mdbt50q_db_40'
|
||||
- 'raytac_mdbt50q_rx'
|
||||
- 'sparkfun_nrf52840_micromod'
|
||||
- 'waveshare_nrf52840_eval'
|
||||
- 'xiao_nrf52840_ble'
|
||||
- 'xiao_nrf52840_ble_sense'
|
||||
|
||||
board: ${{ fromJSON(needs.set-matrix.outputs.matrix) }}
|
||||
steps:
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v3
|
||||
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
|
||||
- name: Checkout linkermap
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: hathach/linkermap
|
||||
path: linkermap
|
||||
|
||||
- name: Install ARM GCC
|
||||
uses: carlosperate/arm-none-eabi-gcc-action@v1
|
||||
with:
|
||||
release: '10-2020-q4'
|
||||
release: '12.3.Rel1'
|
||||
|
||||
- name: Install Tools
|
||||
run: |
|
||||
pip3 install adafruit-nrfutil uritemplate requests intelhex
|
||||
pip3 install linkermap/
|
||||
pip3 install adafruit-nrfutil uritemplate requests intelhex setuptools
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
arm-none-eabi-gcc --version
|
||||
make BOARD=${{ matrix.board }} all
|
||||
make BOARD=${{ matrix.board }} copy-artifact
|
||||
|
||||
- name: Linker Map
|
||||
run: make BOARD=${{ matrix.board }} linkermap
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.board }}
|
||||
path: _bin/${{ matrix.board }}
|
||||
|
||||
+118
-86
@@ -1,4 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.17)
|
||||
find_package(Python COMPONENTS Interpreter)
|
||||
|
||||
if (NOT DEFINED BOARD)
|
||||
message(FATAL_ERROR "BOARD is not defined")
|
||||
@@ -24,26 +25,31 @@ set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/cmake/toolchain/arm_${TOOLCHA
|
||||
|
||||
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(NRFX_DIR ${CMAKE_CURRENT_LIST_DIR}/lib/nrfx)
|
||||
set(SDK11_DIR ${CMAKE_CURRENT_LIST_DIR}/lib/sdk11/components)
|
||||
set(SDK_DIR ${CMAKE_CURRENT_LIST_DIR}/lib/sdk/components)
|
||||
set(SOFTDEVICE_DIR ${CMAKE_CURRENT_LIST_DIR}/lib/softdevice)
|
||||
set(TINYUSB_DIR ${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)
|
||||
#set_target_properties(bootloader PROPERTIES OUTPUT_NAME "${BOARD}_bootloader.elf")
|
||||
|
||||
|
||||
# SD_VERSION can be overwritten by board.cmake
|
||||
if(NOT DEFINED SD_VERSION)
|
||||
set(SD_VERSION 6.1.1)
|
||||
if(MCU_VARIANT STREQUAL "nrf52833")
|
||||
set(SD_VERSION 7.3.0)
|
||||
else()
|
||||
set(SD_VERSION 6.1.1)
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
set(MBR_HEX ${SOFTDEVICE}/mbr/hex/mbr_nrf52_2.4.1_mbr.hex)
|
||||
set(MBR_HEX ${SOFTDEVICE_DIR}/mbr/hex/mbr_nrf52_2.4.1_mbr.hex)
|
||||
|
||||
target_sources(bootloader PUBLIC
|
||||
# src
|
||||
@@ -51,33 +57,35 @@ target_sources(bootloader PUBLIC
|
||||
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
|
||||
${NRFX_DIR}/drivers/src/nrfx_power.c
|
||||
${NRFX_DIR}/drivers/src/nrfx_nvmc.c
|
||||
${NRFX_DIR}/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
|
||||
${SDK11_DIR}/libraries/bootloader_dfu/bootloader.c
|
||||
${SDK11_DIR}/libraries/bootloader_dfu/bootloader_settings.c
|
||||
${SDK11_DIR}/libraries/bootloader_dfu/bootloader_util.c
|
||||
${SDK11_DIR}/libraries/bootloader_dfu/dfu_transport_serial.c
|
||||
${SDK11_DIR}/libraries/bootloader_dfu/dfu_transport_ble.c
|
||||
${SDK11_DIR}/libraries/bootloader_dfu/dfu_single_bank.c
|
||||
${SDK11_DIR}/ble/ble_services/ble_dfu/ble_dfu.c
|
||||
${SDK11_DIR}/ble/ble_services/ble_dis/ble_dis.c
|
||||
${SDK11_DIR}/drivers_nrf/pstorage/pstorage_raw.c
|
||||
# latest sdk
|
||||
${SDK}/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
|
||||
${SDK_DIR}/libraries/timer/app_timer.c
|
||||
${SDK_DIR}/libraries/scheduler/app_scheduler.c
|
||||
${SDK_DIR}/libraries/util/app_error.c
|
||||
${SDK_DIR}/libraries/util/app_util_platform.c
|
||||
${SDK_DIR}/libraries/crc16/crc16.c
|
||||
${SDK_DIR}/libraries/hci/hci_mem_pool.c
|
||||
${SDK_DIR}/libraries/hci/hci_slip.c
|
||||
${SDK_DIR}/libraries/hci/hci_transport.c
|
||||
${SDK_DIR}/libraries/util/nrf_assert.c
|
||||
# ASM
|
||||
${NRFX}/mdk/gcc_startup_${MCU_VARIANT}.S
|
||||
${NRFX_DIR}/mdk/gcc_startup_${MCU_VARIANT}.S
|
||||
)
|
||||
target_include_directories(bootloader PUBLIC
|
||||
src
|
||||
@@ -85,46 +93,64 @@ target_include_directories(bootloader PUBLIC
|
||||
src/boards/${BOARD}
|
||||
src/cmsis/include
|
||||
src/usb
|
||||
${TUSB}
|
||||
${TINYUSB_DIR}
|
||||
# nrfx
|
||||
${NRFX}
|
||||
${NRFX}/mdk
|
||||
${NRFX}/hal
|
||||
${NRFX}/drivers/include
|
||||
${NRFX}/drivers/src
|
||||
${NRFX_DIR}
|
||||
${NRFX_DIR}/mdk
|
||||
${NRFX_DIR}/hal
|
||||
${NRFX_DIR}/drivers/include
|
||||
${NRFX_DIR}/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
|
||||
${SDK11_DIR}/libraries/bootloader_dfu
|
||||
${SDK11_DIR}/libraries/bootloader_dfu/hci_transport
|
||||
${SDK11_DIR}/drivers_nrf/pstorage
|
||||
${SDK11_DIR}/ble/common
|
||||
${SDK11_DIR}/ble/ble_services/ble_dfu
|
||||
${SDK11_DIR}/ble/ble_services/ble_dis
|
||||
# later sdk with updated drivers
|
||||
${SDK}/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
|
||||
${SDK_DIR}/libraries/timer
|
||||
${SDK_DIR}/libraries/scheduler
|
||||
${SDK_DIR}/libraries/crc16
|
||||
${SDK_DIR}/libraries/util
|
||||
${SDK_DIR}/libraries/hci/config
|
||||
${SDK_DIR}/libraries/hci
|
||||
${SDK_DIR}/libraries/uart
|
||||
${SDK_DIR}/drivers_nrf/delay
|
||||
# Softdevice
|
||||
${SOFTDEVICE}/mbr/headers
|
||||
${SOFTDEVICE_DIR}/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)
|
||||
message(FATAL_ERROR "Debug build not supported yet")
|
||||
|
||||
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
|
||||
-L${NRFX_DIR}/mdk
|
||||
--specs=nosys.specs --specs=nano.specs
|
||||
)
|
||||
target_compile_options(bootloader PUBLIC
|
||||
-fno-builtin
|
||||
@@ -145,11 +171,10 @@ target_compile_options(bootloader PUBLIC
|
||||
-Wno-endif-labels
|
||||
-Wunreachable-code
|
||||
# Suppress warning caused by SDK
|
||||
-Wno-unused-parameter -Wno-expansion-to-defined
|
||||
-Wno-unused-parameter -Wno-expansion-to-defined -Wno-array-bounds
|
||||
)
|
||||
target_compile_definitions(bootloader PUBLIC
|
||||
SOFTDEVICE_PRESENT
|
||||
DFU_APP_DATA_RESERVED=7*4096
|
||||
)
|
||||
|
||||
if (TRACE_ETM STREQUAL "1")
|
||||
@@ -160,14 +185,14 @@ 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
|
||||
${SDK_DIR}/libraries/uart/app_uart.c
|
||||
${SDK_DIR}/drivers_nrf/uart/nrf_drv_uart.c
|
||||
${SDK_DIR}/drivers_nrf/common/nrf_drv_common.c
|
||||
)
|
||||
target_include_directories(bootloader PUBLIC
|
||||
${SDK11}/libraries/util
|
||||
${SDK}/drivers_nrf/common
|
||||
${SDK}/drivers_nrf/uart
|
||||
${SDK11_DIR}/libraries/util
|
||||
${SDK_DIR}/drivers_nrf/common
|
||||
${SDK_DIR}/drivers_nrf/uart
|
||||
)
|
||||
else ()
|
||||
# USB transport
|
||||
@@ -178,13 +203,13 @@ else ()
|
||||
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
|
||||
${TINYUSB_DIR}/portable/nordic/nrf5x/dcd_nrf5x.c
|
||||
${TINYUSB_DIR}/common/tusb_fifo.c
|
||||
${TINYUSB_DIR}/device/usbd.c
|
||||
${TINYUSB_DIR}/device/usbd_control.c
|
||||
${TINYUSB_DIR}/class/cdc/cdc_device.c
|
||||
${TINYUSB_DIR}/class/msc/msc_device.c
|
||||
${TINYUSB_DIR}/tusb.c
|
||||
)
|
||||
endif ()
|
||||
|
||||
@@ -195,43 +220,43 @@ endif ()
|
||||
if (MCU_VARIANT STREQUAL "nrf52")
|
||||
set(SD_NAME s132)
|
||||
set(DFU_DEV_REV 0xADAF)
|
||||
set(DFU_APP_DATA_RESERVED 7*4096)
|
||||
target_compile_definitions(bootloader PUBLIC
|
||||
NRF52
|
||||
NRF52832_XXAA
|
||||
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)
|
||||
set(SD_HEX ${SOFTDEVICE_DIR}/${SD_FILENAME}/${SD_FILENAME}_softdevice.hex)
|
||||
|
||||
target_include_directories(bootloader PUBLIC
|
||||
${SOFTDEVICE_DIR}/${SD_FILENAME}/${SD_FILENAME}_API/include
|
||||
)
|
||||
|
||||
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
|
||||
@@ -257,12 +282,12 @@ math(EXPR MK_BOOTLOADER_VERSION "(${RELEASE_VERSION_MAJOR} << 16) + (${RELEASE_V
|
||||
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
|
||||
#----------------------------------
|
||||
@@ -276,6 +301,8 @@ add_custom_command(TARGET bootloader POST_BUILD
|
||||
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)
|
||||
|
||||
#----------------------------------
|
||||
@@ -286,11 +313,16 @@ if (NOT DEFINED NRFJPROG)
|
||||
set(NRFJPROG nrfjprog)
|
||||
endif()
|
||||
|
||||
add_custom_target(flash
|
||||
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
|
||||
)
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
# local customization
|
||||
-include Makefile.user
|
||||
|
||||
# Board specific
|
||||
-include src/boards/$(BOARD)/board.mk
|
||||
|
||||
SDK_PATH = lib/sdk/components
|
||||
SDK11_PATH = lib/sdk11/components
|
||||
TUSB_PATH = lib/tinyusb/src
|
||||
@@ -18,7 +21,11 @@ SD_PATH = lib/softdevice/$(SD_FILENAME)
|
||||
|
||||
# SD_VERSION can be overwritten by board.mk
|
||||
ifndef SD_VERSION
|
||||
SD_VERSION = 6.1.1
|
||||
ifeq ($(MCU_SUB_VARIANT),nrf52833)
|
||||
SD_VERSION = 7.3.0
|
||||
else
|
||||
SD_VERSION = 6.1.1
|
||||
endif
|
||||
endif
|
||||
|
||||
SD_FILENAME = $(SD_NAME)_nrf52_$(SD_VERSION)
|
||||
@@ -89,25 +96,10 @@ endif
|
||||
BMP_PORT ?= $(shell ls -1 /dev/cu.usbmodem????????1 | head -1)
|
||||
GDB_BMP = $(GDB) -ex 'target extended-remote $(BMP_PORT)' -ex 'monitor swdp_scan' -ex 'attach 1'
|
||||
|
||||
#---------------------------------
|
||||
# Select the board to build
|
||||
#---------------------------------
|
||||
# Note: whitespace is not allowed in the filenames... it WILL break this part of the script
|
||||
BOARD_LIST = $(sort $(filter-out boards.h boards.c,$(notdir $(wildcard src/boards/*))))
|
||||
|
||||
ifeq ($(filter $(BOARD),$(BOARD_LIST)),)
|
||||
$(info You must provide a BOARD parameter with 'BOARD='. Supported boards are:)
|
||||
$(foreach b,$(BOARD_LIST),$(info - $(b)))
|
||||
$(error Invalid BOARD specified)
|
||||
endif
|
||||
|
||||
# Build directory
|
||||
BUILD = _build/build-$(BOARD)
|
||||
BIN = _bin/$(BOARD)
|
||||
|
||||
# Board specific
|
||||
-include src/boards/$(BOARD)/board.mk
|
||||
|
||||
# MCU_SUB_VARIANT can be nrf52 (nrf52832), nrf52833, nrf52840
|
||||
ifeq ($(MCU_SUB_VARIANT),nrf52)
|
||||
SD_NAME = s132
|
||||
@@ -123,7 +115,7 @@ else ifeq ($(MCU_SUB_VARIANT),nrf52840)
|
||||
SD_NAME = s140
|
||||
DFU_DEV_REV = 52840
|
||||
CFLAGS += -DNRF52840_XXAA -DS140
|
||||
# App reserved 40KB to match circuitpython for 840
|
||||
# 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)
|
||||
@@ -139,6 +131,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
|
||||
@@ -314,6 +308,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)"'
|
||||
|
||||
@@ -328,9 +323,9 @@ ifeq ($(DEBUG), 1)
|
||||
C_SRC += $(RTT_SRC)/RTT/SEGGER_RTT.c
|
||||
DFU_APP_DATA_RESERVED = 0
|
||||
|
||||
# expand bootloader address to 28KB of reserved app
|
||||
# expand bootloader address to 28KB/40KB of reserved app
|
||||
ifeq ($(MCU_SUB_VARIANT),nrf52840)
|
||||
CFLAGS += -DBOOTLOADER_REGION_START=0xED000
|
||||
CFLAGS += -DBOOTLOADER_REGION_START=0xEA000
|
||||
else
|
||||
CFLAGS += -DBOOTLOADER_REGION_START=0x6D000
|
||||
endif
|
||||
@@ -339,7 +334,8 @@ endif
|
||||
CFLAGS += -DDFU_APP_DATA_RESERVED=$(DFU_APP_DATA_RESERVED)
|
||||
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523
|
||||
ifneq ($(findstring 12.,$(shell $(CC) --version 2>/dev/null)),)
|
||||
# Fixes for gcc version 12 and 13.
|
||||
ifneq (,$(filter 12.% 13.%,$(shell $(CC) -dumpversion 2>/dev/null)))
|
||||
CFLAGS += --param=min-pagesize=0
|
||||
endif
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ MEMORY
|
||||
* APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START);
|
||||
*/
|
||||
/* due to lack of flash for debug, we will use reserved app to extend bootloader size */
|
||||
FLASH (rx) : ORIGIN = 0xF4000-28K, LENGTH = 0xFE000-0xF4000 - 2K + 28K /* 38 KB */
|
||||
FLASH (rx) : ORIGIN = 0xF4000 - 40K, LENGTH = 0xFE000-0xF4000 - 2K + 40K /* 38 KB */
|
||||
|
||||
BOOTLOADER_CONFIG (r): ORIGIN = 0xFE000 - 2K, LENGTH = 2K
|
||||
|
||||
|
||||
+397
-189
@@ -31,42 +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_init2(void) { }
|
||||
void __attribute__((weak)) board_init2(void) {}
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
void board_init(void) {
|
||||
// stop LF clock just in case we jump from application without reset
|
||||
NRF_CLOCK->TASKS_LFCLKSTOP = 1UL;
|
||||
|
||||
@@ -85,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
|
||||
|
||||
@@ -96,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_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
|
||||
|
||||
@@ -127,14 +132,13 @@ void board_init(void)
|
||||
|
||||
// Configure Systick for led blinky
|
||||
NVIC_SetPriority(SysTick_IRQn, 7);
|
||||
SysTick_Config(SystemCoreClock/1000);
|
||||
SysTick_Config(SystemCoreClock / 1000);
|
||||
}
|
||||
|
||||
// Actions at the end of board_teardown.
|
||||
void __attribute__((weak)) board_teardown2(void) { }
|
||||
void __attribute__((weak)) board_teardown2(void) {}
|
||||
|
||||
void board_teardown(void)
|
||||
{
|
||||
void board_teardown(void) {
|
||||
// Disable systick, turn off LEDs
|
||||
SysTick->CTRL = 0;
|
||||
|
||||
@@ -147,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
|
||||
@@ -159,8 +167,7 @@ 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);
|
||||
}
|
||||
|
||||
@@ -168,43 +175,153 @@ void board_teardown(void)
|
||||
board_teardown2();
|
||||
}
|
||||
|
||||
static uint32_t _systick_count = 0;
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
_systick_count++;
|
||||
//--------------------------------------------------------------------+
|
||||
// Display
|
||||
//--------------------------------------------------------------------+
|
||||
#ifdef DISPLAY_PIN_SCK
|
||||
#include "nrf_spim.h"
|
||||
|
||||
led_tick();
|
||||
#define TFT_MADCTL_MY 0x80 ///< Page addr order: Bottom to top
|
||||
#define TFT_MADCTL_MX 0x40 ///< Column addr order: Right to left
|
||||
#define TFT_MADCTL_MV 0x20 ///< Page/Column order: Reverse Mode ( X <-> Y )
|
||||
#define TFT_MADCTL_ML 0x10 ///< LCD refresh Bottom to top
|
||||
#define TFT_MADCTL_MH 0x04 ///< LCD refresh right to left
|
||||
#define TFT_MADCTL_RGB 0x00 ///< Red-Green-Blue pixel order
|
||||
#define TFT_MADCTL_BGR 0x08 ///< Blue-Green-Red pixel order
|
||||
|
||||
// Note don't use SPIM3 since it has lots of errata
|
||||
NRF_SPIM_Type* _spim = NRF_SPIM0;
|
||||
|
||||
static void spi_write(NRF_SPIM_Type *p_spim, uint8_t const *tx_buf, size_t tx_len) {
|
||||
nrf_spim_tx_buffer_set(p_spim, tx_buf, tx_len);
|
||||
nrf_spim_rx_buffer_set(p_spim, NULL, 0);
|
||||
|
||||
nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_ENDTX);
|
||||
nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_END);
|
||||
nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_START);
|
||||
|
||||
// blocking wait until xfer complete
|
||||
while (!nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END)){}
|
||||
}
|
||||
|
||||
static void tft_controller_init(void);
|
||||
|
||||
void pwm_teardown(NRF_PWM_Type* pwm )
|
||||
{
|
||||
static inline void tft_cs(bool state) {
|
||||
nrf_gpio_pin_write(DISPLAY_PIN_CS, state);
|
||||
}
|
||||
|
||||
static inline void tft_dc(bool state) {
|
||||
nrf_gpio_pin_write(DISPLAY_PIN_DC, state);
|
||||
}
|
||||
|
||||
static void tft_cmd(uint8_t cmd, uint8_t const* data, size_t narg) {
|
||||
tft_cs(false);
|
||||
|
||||
// send command
|
||||
tft_dc(false);
|
||||
spi_write(_spim, &cmd, 1);
|
||||
|
||||
// send data
|
||||
if (narg > 0) {
|
||||
tft_dc(true);
|
||||
spi_write(_spim, data, narg);
|
||||
}
|
||||
|
||||
tft_cs(true);
|
||||
}
|
||||
|
||||
void board_display_init(void) {
|
||||
//------------- SPI init -------------//
|
||||
// highspeed SPIM should set SCK and MOSI to high drive
|
||||
nrf_gpio_cfg(DISPLAY_PIN_SCK, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_CONNECT,
|
||||
NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
|
||||
nrf_gpio_cfg(DISPLAY_PIN_MOSI, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT,
|
||||
NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
|
||||
nrf_gpio_cfg_output(DISPLAY_PIN_CS);
|
||||
nrf_gpio_pin_set(DISPLAY_PIN_CS);
|
||||
|
||||
nrf_spim_pins_set(_spim, DISPLAY_PIN_SCK, DISPLAY_PIN_MOSI, NRF_SPIM_PIN_NOT_CONNECTED);
|
||||
nrf_spim_frequency_set(_spim, NRF_SPIM_FREQ_4M);
|
||||
nrf_spim_configure(_spim, NRF_SPIM_MODE_0, NRF_SPIM_BIT_ORDER_MSB_FIRST);
|
||||
nrf_spim_orc_set(_spim, 0xFF);
|
||||
|
||||
nrf_spim_enable(_spim);
|
||||
|
||||
//------------- Display Init -------------//
|
||||
nrf_gpio_cfg_output(DISPLAY_PIN_DC);
|
||||
|
||||
#if defined(DISPLAY_VSENSOR_PIN) && DISPLAY_VSENSOR_PIN >= 0
|
||||
nrf_gpio_cfg_output(DISPLAY_VSENSOR_PIN);
|
||||
nrf_gpio_pin_write(DISPLAY_VSENSOR_PIN, DISPLAY_VSENSOR_ON);
|
||||
#endif
|
||||
|
||||
#if defined(DISPLAY_PIN_RST) && DISPLAY_PIN_RST >= 0
|
||||
nrf_gpio_cfg_output(DISPLAY_PIN_RST);
|
||||
nrf_gpio_pin_clear(DISPLAY_PIN_RST);
|
||||
NRFX_DELAY_MS(10);
|
||||
nrf_gpio_pin_set(DISPLAY_PIN_RST);
|
||||
NRFX_DELAY_MS(20);
|
||||
#endif
|
||||
|
||||
#if defined(DISPLAY_PIN_BL) && DISPLAY_PIN_BL >= 0
|
||||
nrf_gpio_cfg_output(DISPLAY_PIN_BL);
|
||||
nrf_gpio_pin_write(DISPLAY_PIN_BL, DISPLAY_BL_ON);
|
||||
#endif
|
||||
|
||||
tft_controller_init();
|
||||
}
|
||||
|
||||
void board_display_teardown(void) {
|
||||
nrf_spim_disable(_spim);
|
||||
}
|
||||
|
||||
void board_display_draw_line(uint16_t y, uint8_t const* buf, size_t nbytes) {
|
||||
// column and row address set
|
||||
uint32_t xa32 = DISPLAY_COL_OFFSET << 16 | DISPLAY_WIDTH;
|
||||
xa32 = __builtin_bswap32(xa32);
|
||||
|
||||
y += DISPLAY_ROW_OFFSET;
|
||||
uint32_t ya32 = (y << 16) | (y + 1);
|
||||
ya32 = __builtin_bswap32(ya32);
|
||||
|
||||
tft_cmd(0x2A, (uint8_t*) &xa32, 4);
|
||||
tft_cmd(0x2B, (uint8_t*) &ya32, 4);
|
||||
|
||||
// command: memory write
|
||||
tft_cmd(0x2C, buf, nbytes);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// LED Indicator
|
||||
//--------------------------------------------------------------------+
|
||||
void pwm_teardown(NRF_PWM_Type* pwm) {
|
||||
pwm->TASKS_SEQSTART[0] = 0;
|
||||
pwm->ENABLE = 0;
|
||||
pwm->ENABLE = 0;
|
||||
|
||||
pwm->PSEL.OUT[0] = 0xFFFFFFFF;
|
||||
pwm->PSEL.OUT[1] = 0xFFFFFFFF;
|
||||
pwm->PSEL.OUT[2] = 0xFFFFFFFF;
|
||||
pwm->PSEL.OUT[3] = 0xFFFFFFFF;
|
||||
|
||||
pwm->MODE = 0;
|
||||
pwm->COUNTERTOP = 0x3FF;
|
||||
pwm->PRESCALER = 0;
|
||||
pwm->DECODER = 0;
|
||||
pwm->LOOP = 0;
|
||||
pwm->SEQ[0].PTR = 0;
|
||||
pwm->SEQ[0].CNT = 0;
|
||||
pwm->MODE = 0;
|
||||
pwm->COUNTERTOP = 0x3FF;
|
||||
pwm->PRESCALER = 0;
|
||||
pwm->DECODER = 0;
|
||||
pwm->LOOP = 0;
|
||||
pwm->SEQ[0].PTR = 0;
|
||||
pwm->SEQ[0].CNT = 0;
|
||||
}
|
||||
|
||||
static uint16_t led_duty_cycles[PWM0_CH_NUM] = { 0 };
|
||||
static uint16_t led_duty_cycles[PWM0_CH_NUM] = {0};
|
||||
|
||||
#if LEDS_NUMBER > PWM0_CH_NUM
|
||||
#error "Only " PWM0_CH_NUM " concurrent status LEDs are supported."
|
||||
#endif
|
||||
|
||||
void led_pwm_init(uint32_t led_index, uint32_t led_pin)
|
||||
{
|
||||
NRF_PWM_Type* pwm = NRF_PWM0;
|
||||
void led_pwm_init(uint32_t led_index, uint32_t led_pin) {
|
||||
NRF_PWM_Type* pwm = NRF_PWM0;
|
||||
|
||||
pwm->ENABLE = 0;
|
||||
|
||||
@@ -213,15 +330,15 @@ void led_pwm_init(uint32_t led_index, uint32_t led_pin)
|
||||
|
||||
pwm->PSEL.OUT[led_index] = led_pin;
|
||||
|
||||
pwm->MODE = PWM_MODE_UPDOWN_Up;
|
||||
pwm->COUNTERTOP = 0xff;
|
||||
pwm->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_16;
|
||||
pwm->DECODER = PWM_DECODER_LOAD_Individual;
|
||||
pwm->LOOP = 0;
|
||||
pwm->MODE = PWM_MODE_UPDOWN_Up;
|
||||
pwm->COUNTERTOP = 0xff;
|
||||
pwm->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_16;
|
||||
pwm->DECODER = PWM_DECODER_LOAD_Individual;
|
||||
pwm->LOOP = 0;
|
||||
|
||||
pwm->SEQ[0].PTR = (uint32_t) (led_duty_cycles);
|
||||
pwm->SEQ[0].CNT = 4; // default mode is Individual --> count must be 4
|
||||
pwm->SEQ[0].REFRESH = 0;
|
||||
pwm->SEQ[0].PTR = (uint32_t) (led_duty_cycles);
|
||||
pwm->SEQ[0].CNT = 4; // default mode is Individual --> count must be 4
|
||||
pwm->SEQ[0].REFRESH = 0;
|
||||
pwm->SEQ[0].ENDDELAY = 0;
|
||||
|
||||
pwm->ENABLE = 1;
|
||||
@@ -230,13 +347,11 @@ void led_pwm_init(uint32_t led_index, uint32_t led_pin)
|
||||
// pwm->TASKS_SEQSTART[0] = 1;
|
||||
}
|
||||
|
||||
void led_pwm_teardown(void)
|
||||
{
|
||||
void led_pwm_teardown(void) {
|
||||
pwm_teardown(NRF_PWM0);
|
||||
}
|
||||
|
||||
void led_pwm_duty_cycle(uint32_t led_index, uint16_t duty_cycle)
|
||||
{
|
||||
void led_pwm_duty_cycle(uint32_t led_index, uint16_t duty_cycle) {
|
||||
led_duty_cycles[led_index] = duty_cycle;
|
||||
nrf_pwm_event_clear(NRF_PWM0, NRF_PWM_EVENT_SEQEND0);
|
||||
nrf_pwm_task_trigger(NRF_PWM0, NRF_PWM_TASK_SEQSTART0);
|
||||
@@ -246,102 +361,103 @@ static uint32_t primary_cycle_length;
|
||||
#ifdef LED_SECONDARY_PIN
|
||||
static uint32_t secondary_cycle_length;
|
||||
#endif
|
||||
|
||||
void led_tick() {
|
||||
uint32_t millis = _systick_count;
|
||||
uint32_t millis = _systick_count;
|
||||
|
||||
uint32_t cycle = millis % primary_cycle_length;
|
||||
uint32_t half_cycle = primary_cycle_length / 2;
|
||||
if (cycle > half_cycle) {
|
||||
cycle = primary_cycle_length - cycle;
|
||||
}
|
||||
uint16_t duty_cycle = 0x4f * cycle / half_cycle;
|
||||
#if LED_STATE_ON == 1
|
||||
duty_cycle = 0xff - duty_cycle;
|
||||
#endif
|
||||
led_pwm_duty_cycle(LED_PRIMARY, duty_cycle);
|
||||
uint32_t cycle = millis % primary_cycle_length;
|
||||
uint32_t half_cycle = primary_cycle_length / 2;
|
||||
if (cycle > half_cycle) {
|
||||
cycle = primary_cycle_length - cycle;
|
||||
}
|
||||
uint16_t duty_cycle = 0x4f * cycle / half_cycle;
|
||||
#if LED_STATE_ON == 1
|
||||
duty_cycle = 0xff - duty_cycle;
|
||||
#endif
|
||||
led_pwm_duty_cycle(LED_PRIMARY, duty_cycle);
|
||||
|
||||
#ifdef LED_SECONDARY_PIN
|
||||
cycle = millis % secondary_cycle_length;
|
||||
half_cycle = secondary_cycle_length / 2;
|
||||
if (cycle > half_cycle) {
|
||||
cycle = secondary_cycle_length - cycle;
|
||||
}
|
||||
duty_cycle = 0x8f * cycle / half_cycle;
|
||||
#if LED_STATE_ON == 1
|
||||
duty_cycle = 0xff - duty_cycle;
|
||||
#endif
|
||||
led_pwm_duty_cycle(LED_SECONDARY, duty_cycle);
|
||||
#endif
|
||||
#ifdef LED_SECONDARY_PIN
|
||||
cycle = millis % secondary_cycle_length;
|
||||
half_cycle = secondary_cycle_length / 2;
|
||||
if (cycle > half_cycle) {
|
||||
cycle = secondary_cycle_length - cycle;
|
||||
}
|
||||
duty_cycle = 0x8f * cycle / half_cycle;
|
||||
#if LED_STATE_ON == 1
|
||||
duty_cycle = 0xff - duty_cycle;
|
||||
#endif
|
||||
led_pwm_duty_cycle(LED_SECONDARY, duty_cycle);
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint32_t rgb_color;
|
||||
static bool temp_color_active = false;
|
||||
void led_state(uint32_t state)
|
||||
{
|
||||
uint32_t new_rgb_color = rgb_color;
|
||||
uint32_t temp_color = 0;
|
||||
switch (state) {
|
||||
case STATE_USB_MOUNTED:
|
||||
new_rgb_color = 0x00ff00;
|
||||
primary_cycle_length = 3000;
|
||||
break;
|
||||
|
||||
case STATE_BOOTLOADER_STARTED:
|
||||
case STATE_USB_UNMOUNTED:
|
||||
new_rgb_color = 0xff0000;
|
||||
primary_cycle_length = 300;
|
||||
break;
|
||||
void led_state(uint32_t state) {
|
||||
uint32_t new_rgb_color = rgb_color;
|
||||
uint32_t temp_color = 0;
|
||||
switch (state) {
|
||||
case STATE_USB_MOUNTED:
|
||||
new_rgb_color = 0x00ff00;
|
||||
primary_cycle_length = 3000;
|
||||
break;
|
||||
|
||||
case STATE_WRITING_STARTED:
|
||||
temp_color = 0xff0000;
|
||||
primary_cycle_length = 100;
|
||||
break;
|
||||
case STATE_BOOTLOADER_STARTED:
|
||||
case STATE_USB_UNMOUNTED:
|
||||
new_rgb_color = 0xff0000;
|
||||
primary_cycle_length = 300;
|
||||
break;
|
||||
|
||||
case STATE_WRITING_FINISHED:
|
||||
// Empty means to unset any temp colors.
|
||||
primary_cycle_length = 3000;
|
||||
break;
|
||||
case STATE_WRITING_STARTED:
|
||||
temp_color = 0xff0000;
|
||||
primary_cycle_length = 100;
|
||||
break;
|
||||
|
||||
case STATE_BLE_CONNECTED:
|
||||
new_rgb_color = 0x0000ff;
|
||||
#ifdef LED_SECONDARY_PIN
|
||||
secondary_cycle_length = 3000;
|
||||
#else
|
||||
primary_cycle_length = 3000;
|
||||
#endif
|
||||
break;
|
||||
case STATE_WRITING_FINISHED:
|
||||
// Empty means to unset any temp colors.
|
||||
primary_cycle_length = 3000;
|
||||
break;
|
||||
|
||||
case STATE_BLE_DISCONNECTED:
|
||||
new_rgb_color = 0xff00ff;
|
||||
#ifdef LED_SECONDARY_PIN
|
||||
secondary_cycle_length = 300;
|
||||
#else
|
||||
primary_cycle_length = 300;
|
||||
#endif
|
||||
break;
|
||||
case STATE_BLE_CONNECTED:
|
||||
new_rgb_color = 0x0000ff;
|
||||
#ifdef LED_SECONDARY_PIN
|
||||
secondary_cycle_length = 3000;
|
||||
#else
|
||||
primary_cycle_length = 3000;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
uint8_t* final_color = NULL;
|
||||
new_rgb_color &= BOARD_RGB_BRIGHTNESS;
|
||||
if (temp_color != 0){
|
||||
temp_color &= BOARD_RGB_BRIGHTNESS;
|
||||
final_color = (uint8_t*)&temp_color;
|
||||
temp_color_active = true;
|
||||
} else if (new_rgb_color != rgb_color) {
|
||||
final_color = (uint8_t*)&new_rgb_color;
|
||||
rgb_color = new_rgb_color;
|
||||
} else if (temp_color_active) {
|
||||
final_color = (uint8_t*)&rgb_color;
|
||||
}
|
||||
case STATE_BLE_DISCONNECTED:
|
||||
new_rgb_color = 0xff00ff;
|
||||
#ifdef LED_SECONDARY_PIN
|
||||
secondary_cycle_length = 300;
|
||||
#else
|
||||
primary_cycle_length = 300;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
uint8_t* final_color = NULL;
|
||||
new_rgb_color &= BOARD_RGB_BRIGHTNESS;
|
||||
if (temp_color != 0) {
|
||||
temp_color &= BOARD_RGB_BRIGHTNESS;
|
||||
final_color = (uint8_t*) &temp_color;
|
||||
temp_color_active = true;
|
||||
} else if (new_rgb_color != rgb_color) {
|
||||
final_color = (uint8_t*) &new_rgb_color;
|
||||
rgb_color = new_rgb_color;
|
||||
} else if (temp_color_active) {
|
||||
final_color = (uint8_t*) &rgb_color;
|
||||
}
|
||||
|
||||
#if defined(LED_NEOPIXEL) || defined(LED_RGB_RED_PIN) || defined(LED_APA102)
|
||||
if (final_color != NULL) {
|
||||
neopixel_write(final_color);
|
||||
}
|
||||
if (final_color != NULL) {
|
||||
neopixel_write(final_color);
|
||||
}
|
||||
#else
|
||||
(void) final_color;
|
||||
(void) final_color;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -354,11 +470,10 @@ void led_state(uint32_t state)
|
||||
|
||||
#define BYTE_PER_PIXEL 3
|
||||
|
||||
static uint16_t pixels_pattern[NEOPIXELS_NUMBER*BYTE_PER_PIXEL * 8 + 2];
|
||||
static uint16_t pixels_pattern[NEOPIXELS_NUMBER * BYTE_PER_PIXEL * 8 + 2];
|
||||
|
||||
// use PWM1 for neopixel
|
||||
void neopixel_init(void)
|
||||
{
|
||||
void neopixel_init(void) {
|
||||
// To support both the SoftDevice + Neopixels we use the EasyDMA
|
||||
// feature from the NRF25. However this technique implies to
|
||||
// generate a pattern and store it on the memory. The actual
|
||||
@@ -394,40 +509,33 @@ void neopixel_init(void)
|
||||
// pwm->INTEN |= (PWM_INTEN_SEQEND0_Enabled<<PWM_INTEN_SEQEND0_Pos);
|
||||
|
||||
// PSEL must be configured before enabling PWM
|
||||
nrf_pwm_pins_set(pwm, (uint32_t[] ) { LED_NEOPIXEL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL });
|
||||
nrf_pwm_pins_set(pwm, (uint32_t[]) {LED_NEOPIXEL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL});
|
||||
|
||||
// Enable the PWM
|
||||
nrf_pwm_enable(pwm);
|
||||
}
|
||||
|
||||
void neopixel_teardown(void)
|
||||
{
|
||||
uint8_t rgb[3] = { 0, 0, 0 };
|
||||
void neopixel_teardown(void) {
|
||||
uint8_t rgb[3] = {0, 0, 0};
|
||||
|
||||
NRFX_DELAY_US(50); // wait for previous write is complete
|
||||
|
||||
neopixel_write(rgb);
|
||||
NRFX_DELAY_US(50); // wait for this write
|
||||
|
||||
pwm_teardown(NRF_PWM1);
|
||||
}
|
||||
|
||||
// write 3 bytes color RGB to built-in neopixel
|
||||
void neopixel_write (uint8_t *pixels)
|
||||
{
|
||||
void neopixel_write(uint8_t* pixels) {
|
||||
// convert RGB to GRB
|
||||
uint8_t grb[BYTE_PER_PIXEL] = {pixels[1], pixels[2], pixels[0]};
|
||||
uint16_t pos = 0; // bit position
|
||||
|
||||
// Set all neopixel to same value
|
||||
for (uint16_t n = 0; n < NEOPIXELS_NUMBER; n++ )
|
||||
{
|
||||
for(uint8_t c = 0; c < BYTE_PER_PIXEL; c++)
|
||||
{
|
||||
for (uint16_t n = 0; n < NEOPIXELS_NUMBER; n++) {
|
||||
for (uint8_t c = 0; c < BYTE_PER_PIXEL; c++) {
|
||||
uint8_t const pix = grb[c];
|
||||
|
||||
for ( uint8_t mask = 0x80; mask > 0; mask >>= 1 )
|
||||
{
|
||||
for (uint8_t mask = 0x80; mask > 0; mask >>= 1) {
|
||||
pixels_pattern[pos] = (pix & mask) ? MAGIC_T1H : MAGIC_T0H;
|
||||
pos++;
|
||||
}
|
||||
@@ -441,14 +549,15 @@ void neopixel_write (uint8_t *pixels)
|
||||
NRF_PWM_Type* pwm = NRF_PWM1;
|
||||
|
||||
nrf_pwm_seq_ptr_set(pwm, 0, pixels_pattern);
|
||||
nrf_pwm_seq_cnt_set(pwm, 0, sizeof(pixels_pattern)/2);
|
||||
nrf_pwm_seq_cnt_set(pwm, 0, sizeof(pixels_pattern) / 2);
|
||||
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQEND0);
|
||||
nrf_pwm_task_trigger(pwm, NRF_PWM_TASK_SEQSTART0);
|
||||
|
||||
// blocking wait for sequence complete
|
||||
while( !nrf_pwm_event_check(pwm, NRF_PWM_EVENT_SEQEND0) ) {}
|
||||
while (!nrf_pwm_event_check(pwm, NRF_PWM_EVENT_SEQEND0)) {}
|
||||
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQEND0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef LED_APA102
|
||||
@@ -460,8 +569,7 @@ void neopixel_write (uint8_t *pixels)
|
||||
static uint8_t pixels_pattern[PATTERN_SIZE() + 4];
|
||||
|
||||
// use SPIM1 for dotstar
|
||||
void neopixel_init(void)
|
||||
{
|
||||
void neopixel_init(void) {
|
||||
NRF_SPIM_Type* spi = NRF_SPIM1;
|
||||
|
||||
nrf_spim_disable(spi);
|
||||
@@ -492,8 +600,7 @@ void neopixel_init(void)
|
||||
neopixel_write(rgb);
|
||||
}
|
||||
|
||||
void neopixel_teardown(void)
|
||||
{
|
||||
void neopixel_teardown(void) {
|
||||
uint8_t rgb[3] = {0, 0, 0 };
|
||||
neopixel_write(rgb);
|
||||
|
||||
@@ -502,8 +609,7 @@ void neopixel_teardown(void)
|
||||
}
|
||||
|
||||
// write 3 bytes color RGB to built-in neopixel
|
||||
void neopixel_write (uint8_t *pixels)
|
||||
{
|
||||
void neopixel_write (uint8_t *pixels) {
|
||||
NRF_SPIM_Type* spi = NRF_SPIM1;
|
||||
|
||||
//brightness, blue, green, red
|
||||
@@ -514,10 +620,10 @@ void neopixel_write (uint8_t *pixels)
|
||||
pixels_pattern[3] = 0;
|
||||
|
||||
for (uint8_t i = 4; i < PATTERN_SIZE(); i+=4) {
|
||||
pixels_pattern[i] = bbgr[0];
|
||||
pixels_pattern[i+1] = bbgr[1];
|
||||
pixels_pattern[i+2] = bbgr[2];
|
||||
pixels_pattern[i+3] = bbgr[3];
|
||||
pixels_pattern[i] = bbgr[0];
|
||||
pixels_pattern[i+1] = bbgr[1];
|
||||
pixels_pattern[i+2] = bbgr[2];
|
||||
pixels_pattern[i+3] = bbgr[3];
|
||||
}
|
||||
|
||||
pixels_pattern[PATTERN_SIZE()] = 0xff;
|
||||
@@ -545,15 +651,13 @@ void neopixel_write (uint8_t *pixels)
|
||||
#define LED_RGB_BLUE 2
|
||||
#define LED_RGB_GREEN 3
|
||||
|
||||
void neopixel_init(void)
|
||||
{
|
||||
void neopixel_init(void) {
|
||||
led_pwm_init(LED_RGB_RED, LED_RGB_RED_PIN);
|
||||
led_pwm_init(LED_RGB_GREEN, LED_RGB_GREEN_PIN);
|
||||
led_pwm_init(LED_RGB_BLUE, LED_RGB_BLUE_PIN);
|
||||
}
|
||||
|
||||
void neopixel_teardown(void)
|
||||
{
|
||||
void neopixel_teardown(void) {
|
||||
uint8_t rgb[3] = { 0, 0, 0 };
|
||||
neopixel_write(rgb);
|
||||
nrf_gpio_cfg_default(LED_RGB_RED_PIN);
|
||||
@@ -562,10 +666,114 @@ void neopixel_teardown(void)
|
||||
}
|
||||
|
||||
// write 3 bytes color to a built-in neopixel
|
||||
void neopixel_write (uint8_t *pixels)
|
||||
{
|
||||
void neopixel_write (uint8_t *pixels) {
|
||||
led_pwm_duty_cycle(LED_RGB_RED, pixels[2]);
|
||||
led_pwm_duty_cycle(LED_RGB_GREEN, pixels[1]);
|
||||
led_pwm_duty_cycle(LED_RGB_BLUE, pixels[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Display controller
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#ifdef DISPLAY_CONTROLLER_ST7789
|
||||
|
||||
#define ST_CMD_DELAY 0x80 // special signifier for command lists
|
||||
|
||||
#define ST77XX_NOP 0x00
|
||||
#define ST77XX_SWRESET 0x01
|
||||
#define ST77XX_RDDID 0x04
|
||||
#define ST77XX_RDDST 0x09
|
||||
|
||||
#define ST77XX_SLPIN 0x10
|
||||
#define ST77XX_SLPOUT 0x11
|
||||
#define ST77XX_PTLON 0x12
|
||||
#define ST77XX_NORON 0x13
|
||||
|
||||
#define ST77XX_INVOFF 0x20
|
||||
#define ST77XX_INVON 0x21
|
||||
#define ST77XX_DISPOFF 0x28
|
||||
#define ST77XX_DISPON 0x29
|
||||
#define ST77XX_CASET 0x2A
|
||||
#define ST77XX_RASET 0x2B
|
||||
#define ST77XX_RAMWR 0x2C
|
||||
#define ST77XX_RAMRD 0x2E
|
||||
|
||||
#define ST77XX_PTLAR 0x30
|
||||
#define ST77XX_TEOFF 0x34
|
||||
#define ST77XX_TEON 0x35
|
||||
#define ST77XX_MADCTL 0x36
|
||||
#define ST77XX_VSCSAD 0x37
|
||||
#define ST77XX_COLMOD 0x3A
|
||||
|
||||
#define ST77XX_MADCTL_MY 0x80
|
||||
#define ST77XX_MADCTL_MX 0x40
|
||||
#define ST77XX_MADCTL_MV 0x20
|
||||
#define ST77XX_MADCTL_ML 0x10
|
||||
#define ST77XX_MADCTL_RGB 0x00
|
||||
|
||||
#define ST77XX_RDID1 0xDA
|
||||
#define ST77XX_RDID2 0xDB
|
||||
#define ST77XX_RDID3 0xDC
|
||||
#define ST77XX_RDID4 0xDD
|
||||
|
||||
// Some ready-made 16-bit ('565') color settings:
|
||||
#define ST77XX_BLACK 0x0000
|
||||
#define ST77XX_WHITE 0xFFFF
|
||||
#define ST77XX_RED 0xF800
|
||||
#define ST77XX_GREEN 0x07E0
|
||||
#define ST77XX_BLUE 0x001F
|
||||
#define ST77XX_CYAN 0x07FF
|
||||
#define ST77XX_MAGENTA 0xF81F
|
||||
#define ST77XX_YELLOW 0xFFE0
|
||||
#define ST77XX_ORANGE 0xFC00
|
||||
|
||||
static void tft_controller_init(void) {
|
||||
// Init commands for 7789 screens
|
||||
uint8_t cmdinit_st7789[] = {
|
||||
#if !defined(DISPLAY_PIN_RST) || (DISPLAY_PIN_RST < 0)
|
||||
// Software reset if rst pin not available, no args, w/delay ~150 ms delay
|
||||
ST77XX_SWRESET, ST_CMD_DELAY, 150,
|
||||
#endif
|
||||
// Out of sleep mode, no args, w/delay 10 ms delay
|
||||
ST77XX_SLPOUT, ST_CMD_DELAY, 10,
|
||||
// Set color mode, 1 arg + delay: 16-bit color, 10 ms delay
|
||||
ST77XX_COLMOD, 1 + ST_CMD_DELAY, 0x55, 10,
|
||||
// Mem access ctrl (directions), 1 arg: Row/col addr, bottom-top refresh
|
||||
ST77XX_MADCTL, 1, DISPLAY_MADCTL,
|
||||
// Vertical Scroll Start Address of RAM
|
||||
// ST77XX_VSCSAD, 2, DISPLAY_VSCSAD >> 8, DISPLAY_VSCSAD & 0xFF,
|
||||
// Column addr set, 4 args, no delay: XSTART = 0, XEND = 240
|
||||
ST77XX_CASET, 4, 0x00, 0, 0, 240,
|
||||
// Row addr set, 4 args, no delay: YSTART = 0 YEND = 320
|
||||
ST77XX_RASET, 4, 0x00, 0, 320 >> 8, 320 & 0xFF,
|
||||
// Inversion on
|
||||
ST77XX_INVON, ST_CMD_DELAY, 10,
|
||||
// Normal display on, no args, w/delay 10 ms delay
|
||||
ST77XX_NORON, ST_CMD_DELAY, 10,
|
||||
// Main screen turn on, no args, delay 10 ms delay
|
||||
ST77XX_DISPON, ST_CMD_DELAY, 10
|
||||
};
|
||||
|
||||
size_t count = 0;
|
||||
while (count < sizeof(cmdinit_st7789)) {
|
||||
uint8_t const cmd = cmdinit_st7789[count++];
|
||||
uint8_t const cmd_arg = cmdinit_st7789[count++];
|
||||
uint8_t const has_delay = cmd_arg & ST_CMD_DELAY;
|
||||
uint8_t const narg = cmd_arg & ~ST_CMD_DELAY;
|
||||
|
||||
tft_cmd(cmd, cmdinit_st7789 + count, narg);
|
||||
count += narg;
|
||||
|
||||
if (has_delay) {
|
||||
uint16_t delay = (uint16_t) cmdinit_st7789[count++];
|
||||
if (delay == 255) {
|
||||
delay = 500; // If 255, delay for 500 ms
|
||||
}
|
||||
NRFX_DELAY_MS(delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
@@ -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
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
MCU_SUB_VARIANT = nrf52833
|
||||
SD_VERSION = 7.3.0
|
||||
@@ -36,6 +36,7 @@
|
||||
#define LED_STATE_ON 1
|
||||
|
||||
#define LED_NEOPIXEL _PINNUM(0, 16)
|
||||
#define NEOPIXEL_POWER_PIN _PINNUM(1, 14)
|
||||
#define NEOPIXELS_NUMBER 1
|
||||
#define BOARD_RGB_BRIGHTNESS 0x040404
|
||||
|
||||
@@ -63,7 +64,7 @@
|
||||
//------------- UF2 -------------//
|
||||
#define UF2_PRODUCT_NAME "Adafruit Feather nRF52840 Express"
|
||||
#define UF2_VOLUME_LABEL "FTHR840BOOT"
|
||||
#define UF2_BOARD_ID "nRF52840-Feather-revD"
|
||||
#define UF2_BOARD_ID "nRF52840-Feather-revE"
|
||||
#define UF2_INDEX_URL "https://www.adafruit.com/product/4062"
|
||||
|
||||
#endif // _FEATHER_NRF52840_H
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Ha Thach for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _FEATHER_NRF52840_SENSE_TFT_H
|
||||
#define _FEATHER_NRF52840_SENSE_TFT_H
|
||||
|
||||
#define _PINNUM(port, pin) ((port)*32 + (pin))
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* LED
|
||||
*------------------------------------------------------------------*/
|
||||
#define LEDS_NUMBER 1
|
||||
#define LED_PRIMARY_PIN _PINNUM(0, 11)
|
||||
#define LED_STATE_ON 1
|
||||
|
||||
#define LED_NEOPIXEL _PINNUM(1, 8)
|
||||
#define NEOPIXEL_POWER_PIN _PINNUM(1, 2)
|
||||
#define NEOPIXELS_NUMBER 1
|
||||
#define BOARD_RGB_BRIGHTNESS 0x040404
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* BUTTON
|
||||
*------------------------------------------------------------------*/
|
||||
#define BUTTONS_NUMBER 2
|
||||
#define BUTTON_1 _PINNUM(1, 6)
|
||||
#define BUTTON_2 _PINNUM(1, 10) // DFU pin
|
||||
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Display
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// VSensor required to power the display
|
||||
#define DISPLAY_VSENSOR_PIN _PINNUM(1, 7)
|
||||
#define DISPLAY_VSENSOR_ON 1
|
||||
|
||||
#define DISPLAY_CONTROLLER_ST7789
|
||||
|
||||
#define DISPLAY_PIN_SCK _PINNUM(0, 26)
|
||||
#define DISPLAY_PIN_MOSI _PINNUM(0, 5)
|
||||
|
||||
#define DISPLAY_PIN_CS _PINNUM(1, 5)
|
||||
#define DISPLAY_PIN_DC _PINNUM(1, 1)
|
||||
#define DISPLAY_PIN_RST _PINNUM(1, 3)
|
||||
#define DISPLAY_PIN_BL _PINNUM(0, 27)
|
||||
#define DISPLAY_BL_ON 1 // GPIO state to enable back light
|
||||
|
||||
#define DISPLAY_WIDTH 240
|
||||
#define DISPLAY_HEIGHT 135
|
||||
|
||||
#define DISPLAY_COL_OFFSET 53
|
||||
#define DISPLAY_ROW_OFFSET 40
|
||||
|
||||
// Memory Data Access Control & // Vertical Scroll Start Address
|
||||
#define DISPLAY_MADCTL (TFT_MADCTL_MX)
|
||||
#define DISPLAY_VSCSAD 0
|
||||
|
||||
#define DISPLAY_TITLE "Sense TFT"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// BLE OTA
|
||||
//--------------------------------------------------------------------+
|
||||
#define BLEDIS_MANUFACTURER "Adafruit Industries"
|
||||
#define BLEDIS_MODEL "Feather nRF52840 Sense TFT"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USB
|
||||
//--------------------------------------------------------------------+
|
||||
#define USB_DESC_VID 0x239A
|
||||
#define USB_DESC_UF2_PID 0x0087
|
||||
#define USB_DESC_CDC_ONLY_PID 0x0088
|
||||
|
||||
//------------- UF2 -------------//
|
||||
#define UF2_PRODUCT_NAME "Adafruit Feather nRF52840 Sense TFT"
|
||||
#define UF2_VOLUME_LABEL "SENSTFTBOOT"
|
||||
#define UF2_BOARD_ID "nRF52840-FeatherSenseTFT-revA"
|
||||
#define UF2_INDEX_URL "https://www.adafruit.com/product/"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1 @@
|
||||
MCU_SUB_VARIANT = nrf52840
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "boards.h"
|
||||
#include "uf2/configkeys.h"
|
||||
|
||||
__attribute__((used, section(".bootloaderConfig")))
|
||||
const uint32_t bootloaderConfig[] =
|
||||
{
|
||||
/* CF2 START */
|
||||
CFG_MAGIC0, CFG_MAGIC1, // magic
|
||||
5, 100, // used entries, total entries
|
||||
|
||||
204, 0x100000, // FLASH_BYTES = 0x100000
|
||||
205, 0x40000, // RAM_BYTES = 0x40000
|
||||
208, (USB_DESC_VID << 16) | USB_DESC_UF2_PID, // BOOTLOADER_BOARD_ID = USB VID+PID, used for verification when updating bootloader via uf2
|
||||
209, 0xada52840, // UF2_FAMILY = 0xada52840
|
||||
210, 0x20, // PINS_PORT_SIZE = PA_32
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
/* CF2 END */
|
||||
};
|
||||
@@ -57,10 +57,10 @@
|
||||
// USB
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Shared VID/PID with Feather nRF52840, will be disabled for building in the future
|
||||
// Shared VID/PID with pca10056
|
||||
#define USB_DESC_VID 0x239A
|
||||
#define USB_DESC_UF2_PID 0x0029
|
||||
#define USB_DESC_CDC_ONLY_PID 0x0029
|
||||
#define USB_DESC_UF2_PID 0x00DA
|
||||
#define USB_DESC_CDC_ONLY_PID 0x00DA
|
||||
|
||||
#define UF2_PRODUCT_NAME "Particle Argon"
|
||||
#define UF2_VOLUME_LABEL "ARGONBOOT "
|
||||
|
||||
@@ -57,10 +57,10 @@
|
||||
// USB
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Shared VID/PID with Feather nRF52840, will be disabled for building in the future
|
||||
// Shared VID/PID with pca10056
|
||||
#define USB_DESC_VID 0x239A
|
||||
#define USB_DESC_UF2_PID 0x0029
|
||||
#define USB_DESC_CDC_ONLY_PID 0x0029
|
||||
#define USB_DESC_UF2_PID 0x00DA
|
||||
#define USB_DESC_CDC_ONLY_PID 0x00DA
|
||||
|
||||
#define UF2_PRODUCT_NAME "Particle Boron"
|
||||
#define UF2_VOLUME_LABEL "BORONBOOT "
|
||||
|
||||
@@ -57,10 +57,10 @@
|
||||
// USB
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Shared VID/PID with Feather nRF52840, will be disabled for building in the future
|
||||
// Shared VID/PID with pca10056
|
||||
#define USB_DESC_VID 0x239A
|
||||
#define USB_DESC_UF2_PID 0x0029
|
||||
#define USB_DESC_CDC_ONLY_PID 0x0029
|
||||
#define USB_DESC_UF2_PID 0x00DA
|
||||
#define USB_DESC_CDC_ONLY_PID 0x00DA
|
||||
|
||||
#define UF2_PRODUCT_NAME "Particle Xenon"
|
||||
#define UF2_VOLUME_LABEL "XENONBOOT "
|
||||
|
||||
@@ -53,8 +53,8 @@
|
||||
|
||||
// Shared VID/PID with Feather nRF52840, will be disabled for building in the future
|
||||
#define USB_DESC_VID 0x239A
|
||||
#define USB_DESC_UF2_PID 0x0029
|
||||
#define USB_DESC_CDC_ONLY_PID 0x0029
|
||||
#define USB_DESC_UF2_PID 0x00DA
|
||||
#define USB_DESC_CDC_ONLY_PID 0x00DA
|
||||
|
||||
#define UF2_PRODUCT_NAME "Nordic nRF52840 DK"
|
||||
#define UF2_BOARD_ID "nRF52840-pca10056-v1"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
set(MCU_VARIANT nrf52833)
|
||||
@@ -50,11 +50,12 @@
|
||||
//--------------------------------------------------------------------+
|
||||
// USB
|
||||
//--------------------------------------------------------------------+
|
||||
#define USB_DESC_VID 0x1915
|
||||
#define USB_DESC_UF2_PID 0x521F
|
||||
#define USB_DESC_CDC_ONLY_PID 0x521F
|
||||
#define USB_DESC_VID 0x239A
|
||||
#define USB_DESC_UF2_PID 0x00D8
|
||||
#define USB_DESC_CDC_ONLY_PID 0x00D8
|
||||
|
||||
#define UF2_PRODUCT_NAME "Nordic nRF52833 DK"
|
||||
#define UF2_VOLUME_LABEL "NRF833BOOT"
|
||||
#define UF2_BOARD_ID "nRF52833-pca10100-v1"
|
||||
#define UF2_INDEX_URL "https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52833-DK"
|
||||
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
MCU_SUB_VARIANT = nrf52833
|
||||
SD_VERSION=7.2.0
|
||||
MCU_SUB_VARIANT = nrf52833
|
||||
+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
|
||||
+60
-114
@@ -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
|
||||
@@ -132,20 +128,21 @@ 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 23
|
||||
enum { BLE_CONN_CFG_HIGH_BANDWIDTH = 1 };
|
||||
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