Merge pull request #319 from adafruit/add-slash-screen
Add slash screen
This commit is contained in:
commit
64d8e34567
14 changed files with 757 additions and 55 deletions
|
|
@ -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")
|
||||
|
|
@ -30,13 +31,14 @@ set(SDK ${CMAKE_CURRENT_LIST_DIR}/lib/sdk/components)
|
|||
set(SOFTDEVICE ${CMAKE_CURRENT_LIST_DIR}/lib/softdevice)
|
||||
set(TUSB ${CMAKE_CURRENT_LIST_DIR}/lib/tinyusb/src)
|
||||
|
||||
set(UF2CONV_PY ${CMAKE_CURRENT_LIST_DIR}/lib/uf2/utils/uf2conv.py)
|
||||
set(UF2_FAMILY_ID_BOOTLOADER 0xd663823c)
|
||||
|
||||
#-------------------
|
||||
# Bootloader
|
||||
#-------------------
|
||||
set(CMAKE_EXECUTABLE_SUFFIX .elf)
|
||||
add_executable(bootloader)
|
||||
#set_target_properties(bootloader PROPERTIES OUTPUT_NAME "${BOARD}_bootloader.elf")
|
||||
|
||||
|
||||
# SD_VERSION can be overwritten by board.cmake
|
||||
if(NOT DEFINED SD_VERSION)
|
||||
|
|
@ -51,6 +53,8 @@ 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
|
||||
|
|
@ -112,10 +116,29 @@ target_include_directories(bootloader PUBLIC
|
|||
${SOFTDEVICE}/mbr/headers
|
||||
)
|
||||
|
||||
# Debug option
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
# TODO not work yet, also need to add segger rtt, DFU_APP_DATA_RESERVED=0, BOOTLOADER_REGION_START=0xED000
|
||||
set(LD_FILE ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT}_debug.ld)
|
||||
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 ()
|
||||
|
|
@ -123,8 +146,7 @@ endif ()
|
|||
target_link_options(bootloader PUBLIC
|
||||
"LINKER:--script=${LD_FILE}"
|
||||
-L${NRFX}/mdk
|
||||
--specs=nosys.specs
|
||||
--specs=nano.specs
|
||||
--specs=nosys.specs --specs=nano.specs
|
||||
)
|
||||
target_compile_options(bootloader PUBLIC
|
||||
-fno-builtin
|
||||
|
|
@ -149,7 +171,6 @@ target_compile_options(bootloader PUBLIC
|
|||
)
|
||||
target_compile_definitions(bootloader PUBLIC
|
||||
SOFTDEVICE_PRESENT
|
||||
DFU_APP_DATA_RESERVED=7*4096
|
||||
)
|
||||
|
||||
if (TRACE_ETM STREQUAL "1")
|
||||
|
|
@ -195,6 +216,7 @@ 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
|
||||
|
|
@ -207,6 +229,7 @@ if (MCU_VARIANT STREQUAL "nrf52")
|
|||
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
|
||||
|
|
@ -218,6 +241,8 @@ elseif (MCU_VARIANT STREQUAL "nrf52833")
|
|||
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
|
||||
|
|
@ -233,6 +258,10 @@ endif ()
|
|||
set(SD_FILENAME ${SD_NAME}_nrf52_${SD_VERSION})
|
||||
set(SD_HEX ${SOFTDEVICE}/${SD_FILENAME}/${SD_FILENAME}_softdevice.hex)
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
target_compile_definitions(bootloader PUBLIC DFU_APP_DATA_RESERVED=${DFU_APP_DATA_RESERVED})
|
||||
endif ()
|
||||
|
||||
#----------------------------------
|
||||
# Get UF2 version from git
|
||||
#----------------------------------
|
||||
|
|
@ -257,12 +286,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 +305,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 +317,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
|
||||
)
|
||||
|
|
|
|||
9
Makefile
9
Makefile
|
|
@ -123,7 +123,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 +139,8 @@ C_SRC += \
|
|||
src/dfu_init.c \
|
||||
src/flash_nrf5x.c \
|
||||
src/main.c \
|
||||
src/screen.c \
|
||||
src/images.c \
|
||||
|
||||
# all files in boards
|
||||
C_SRC += src/boards/boards.c
|
||||
|
|
@ -314,6 +316,7 @@ ifneq ($(USE_NFCT),yes)
|
|||
endif
|
||||
|
||||
CFLAGS += -DSOFTDEVICE_PRESENT
|
||||
CFLAGS += -DUF2_VERSION_BASE='"$(GIT_VERSION)"'
|
||||
CFLAGS += -DUF2_VERSION='"$(GIT_VERSION) $(GIT_SUBMODULE_VERSIONS)"'
|
||||
CFLAGS += -DBLEDIS_FW_VERSION='"$(GIT_VERSION) $(SD_NAME) $(SD_VERSION)"'
|
||||
|
||||
|
|
@ -328,9 +331,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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -31,9 +31,6 @@
|
|||
#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. */
|
||||
|
||||
|
|
@ -43,7 +40,16 @@ void neopixel_write(uint8_t* pixels);
|
|||
void neopixel_teardown(void);
|
||||
#endif
|
||||
|
||||
//------------- IMPLEMENTATION -------------//
|
||||
//--------------------------------------------------------------------+
|
||||
// IMPLEMENTATION
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
static uint32_t _systick_count = 0;
|
||||
void SysTick_Handler(void) {
|
||||
_systick_count++;
|
||||
led_tick();
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
@ -96,6 +102,7 @@ void board_init(void) {
|
|||
#if ENABLE_DCDC_1 == 1
|
||||
NRF_POWER->DCDCEN = 1;
|
||||
#endif
|
||||
|
||||
// Make sure any custom inits are performed
|
||||
board_init2();
|
||||
|
||||
|
|
@ -144,6 +151,10 @@ 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;
|
||||
|
|
@ -164,13 +175,122 @@ void board_teardown(void) {
|
|||
board_teardown2();
|
||||
}
|
||||
|
||||
static uint32_t _systick_count = 0;
|
||||
//--------------------------------------------------------------------+
|
||||
// Display
|
||||
//--------------------------------------------------------------------+
|
||||
#ifdef DISPLAY_PIN_SCK
|
||||
#include "nrf_spim.h"
|
||||
|
||||
void SysTick_Handler(void) {
|
||||
_systick_count++;
|
||||
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);
|
||||
|
||||
static inline void tft_cs(bool state) {
|
||||
nrf_gpio_pin_write(DISPLAY_PIN_CS, state);
|
||||
}
|
||||
|
||||
static inline void tft_dc(bool state) {
|
||||
nrf_gpio_pin_write(DISPLAY_PIN_DC, state);
|
||||
}
|
||||
|
||||
static void tft_cmd(uint8_t cmd, uint8_t const* data, size_t narg) {
|
||||
tft_cs(false);
|
||||
|
||||
// send command
|
||||
tft_dc(false);
|
||||
spi_write(_spim, &cmd, 1);
|
||||
|
||||
// send data
|
||||
if (narg > 0) {
|
||||
tft_dc(true);
|
||||
spi_write(_spim, data, narg);
|
||||
}
|
||||
|
||||
tft_cs(true);
|
||||
}
|
||||
|
||||
void board_display_init(void) {
|
||||
//------------- SPI init -------------//
|
||||
// highspeed SPIM should set SCK and MOSI to high drive
|
||||
nrf_gpio_cfg(DISPLAY_PIN_SCK, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_CONNECT,
|
||||
NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
|
||||
nrf_gpio_cfg(DISPLAY_PIN_MOSI, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT,
|
||||
NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
|
||||
nrf_gpio_cfg_output(DISPLAY_PIN_CS);
|
||||
nrf_gpio_pin_set(DISPLAY_PIN_CS);
|
||||
|
||||
nrf_spim_pins_set(_spim, DISPLAY_PIN_SCK, DISPLAY_PIN_MOSI, NRF_SPIM_PIN_NOT_CONNECTED);
|
||||
nrf_spim_frequency_set(_spim, NRF_SPIM_FREQ_4M);
|
||||
nrf_spim_configure(_spim, NRF_SPIM_MODE_0, NRF_SPIM_BIT_ORDER_MSB_FIRST);
|
||||
nrf_spim_orc_set(_spim, 0xFF);
|
||||
|
||||
nrf_spim_enable(_spim);
|
||||
|
||||
//------------- Display Init -------------//
|
||||
nrf_gpio_cfg_output(DISPLAY_PIN_DC);
|
||||
|
||||
#if defined(DISPLAY_PIN_RST) && DISPLAY_PIN_RST >= 0
|
||||
nrf_gpio_cfg_output(DISPLAY_PIN_RST);
|
||||
nrf_gpio_pin_clear(DISPLAY_PIN_RST);
|
||||
NRFX_DELAY_MS(10);
|
||||
nrf_gpio_pin_set(DISPLAY_PIN_RST);
|
||||
NRFX_DELAY_MS(20);
|
||||
#endif
|
||||
|
||||
#if defined(DISPLAY_PIN_BL) && DISPLAY_PIN_BL >= 0
|
||||
nrf_gpio_cfg_output(DISPLAY_PIN_BL);
|
||||
nrf_gpio_pin_write(DISPLAY_PIN_BL, DISPLAY_BL_ON);
|
||||
#endif
|
||||
|
||||
tft_controller_init();
|
||||
}
|
||||
|
||||
void board_display_teardown(void) {
|
||||
nrf_spim_disable(_spim);
|
||||
}
|
||||
|
||||
void board_display_draw_line(uint16_t y, uint8_t const* buf, size_t nbytes) {
|
||||
// column and row address set
|
||||
uint32_t xa32 = DISPLAY_COL_OFFSET << 16 | DISPLAY_WIDTH;
|
||||
xa32 = __builtin_bswap32(xa32);
|
||||
|
||||
y += DISPLAY_ROW_OFFSET;
|
||||
uint32_t ya32 = (y << 16) | (y + 1);
|
||||
ya32 = __builtin_bswap32(ya32);
|
||||
|
||||
tft_cmd(0x2A, (uint8_t*) &xa32, 4);
|
||||
tft_cmd(0x2B, (uint8_t*) &ya32, 4);
|
||||
|
||||
// command: memory write
|
||||
tft_cmd(0x2C, buf, nbytes);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// LED Indicator
|
||||
//--------------------------------------------------------------------+
|
||||
void pwm_teardown(NRF_PWM_Type* pwm) {
|
||||
pwm->TASKS_SEQSTART[0] = 0;
|
||||
pwm->ENABLE = 0;
|
||||
|
|
@ -547,3 +667,108 @@ void neopixel_write (uint8_t *pixels) {
|
|||
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
|
||||
//--------------------------------------------------------------------+
|
||||
|
|
|
|||
1
src/boards/circuitplayground_nrf52840/board.cmake
Normal file
1
src/boards/circuitplayground_nrf52840/board.cmake
Normal file
|
|
@ -0,0 +1 @@
|
|||
set(MCU_VARIANT nrf52840)
|
||||
1
src/boards/clue_nrf52840/board.cmake
Normal file
1
src/boards/clue_nrf52840/board.cmake
Normal file
|
|
@ -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
|
||||
//--------------------------------------------------------------------+
|
||||
|
|
|
|||
|
|
@ -47,6 +47,32 @@
|
|||
#define BUTTON_2 _PINNUM(1, 10) // DFU pin
|
||||
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Display
|
||||
//--------------------------------------------------------------------+
|
||||
#define DISPLAY_CONTROLLER_ST7789
|
||||
|
||||
#define DISPLAY_PIN_SCK _PINNUM(0, 26)
|
||||
#define DISPLAY_PIN_MOSI _PINNUM(0, 5)
|
||||
|
||||
#define DISPLAY_PIN_CS _PINNUM(1, 5)
|
||||
#define DISPLAY_PIN_DC _PINNUM(1, 1)
|
||||
#define DISPLAY_PIN_RST _PINNUM(1, 3)
|
||||
#define DISPLAY_PIN_BL _PINNUM(0, 27)
|
||||
#define DISPLAY_BL_ON 1 // GPIO state to enable back light
|
||||
|
||||
#define DISPLAY_WIDTH 240
|
||||
#define DISPLAY_HEIGHT 135
|
||||
|
||||
#define DISPLAY_COL_OFFSET 53
|
||||
#define DISPLAY_ROW_OFFSET 40
|
||||
|
||||
// Memory Data Access Control & // Vertical Scroll Start Address
|
||||
#define DISPLAY_MADCTL (TFT_MADCTL_MX)
|
||||
#define DISPLAY_VSCSAD 0
|
||||
|
||||
#define DISPLAY_TITLE "Sense TFT"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// BLE OTA
|
||||
//--------------------------------------------------------------------+
|
||||
|
|
@ -62,7 +88,7 @@
|
|||
|
||||
//------------- UF2 -------------//
|
||||
#define UF2_PRODUCT_NAME "Adafruit Feather nRF52840 Sense TFT"
|
||||
#define UF2_VOLUME_LABEL "FTHRSNSBOOT"
|
||||
#define UF2_VOLUME_LABEL "SENSTFTBOOT"
|
||||
#define UF2_BOARD_ID "nRF52840-FeatherSenseTFT-revA"
|
||||
#define UF2_INDEX_URL "https://www.adafruit.com/product/"
|
||||
|
||||
|
|
|
|||
124
src/images.c
Normal file
124
src/images.c
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
#include "boards.h"
|
||||
|
||||
#if defined(DISPLAY_PIN_SCK)
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// all https://makecode.com/_VrfEKzV4xfvq
|
||||
|
||||
// https://makecode.com/_7VxXm3JMPXfM - file
|
||||
// https://makecode.com/_LuEUCsPEKUbs - download
|
||||
const uint8_t fileLogo[] = {
|
||||
32, 32, 71, 140, 201, 151, 1, 2, 146, 1, 2, 146, 63, 2, 151, 9, 153, 9, 153, 9, 146, 1, 9, 146, 3, 9, 146, 7, 9, 137, 205, 72, 140, 206, 36, 139, 207, 18, 138, 206, 36, 139, 205, 72, 149, 7, 9, 146, 3, 9, 146, 1, 9, 153, 9, 153, 9, 153, 9, 148, 63, 2, 146, 1, 2, 146, 1, 2, 146, 201, 191, 191, 191, 174
|
||||
};
|
||||
|
||||
// https://makecode.com/_9b0RcK5yRa12
|
||||
const uint8_t pendriveLogo[] = {
|
||||
32, 32, 59, 137, 215, 137, 1, 143, 1, 8, 146, 203, 149, 3, 8, 146, 3, 8, 146, 115, 8, 146, 115, 8, 146, 3, 8, 146, 3, 8, 146, 115, 8, 146, 115, 8, 146, 3, 8, 146, 3, 8, 146, 203, 149, 1, 8, 146, 1, 8, 146, 1, 120, 211, 191, 191, 191, 191, 191, 191, 191, 135
|
||||
};
|
||||
|
||||
// https://makecode.com/_TTqbj705L4mr
|
||||
const uint8_t arrowLogo[] = {
|
||||
32, 32, 54, 137, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 146, 211, 142, 209, 144, 207, 146, 205, 148, 203, 150, 201, 152, 199, 154, 31, 154, 7, 154, 1, 191, 191, 191, 175
|
||||
};
|
||||
|
||||
const uint8_t font8[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x5e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00,
|
||||
0x28, 0xfe, 0x28, 0xfe, 0x28, 0x00,
|
||||
0x4c, 0x92, 0xff, 0x92, 0x64, 0x00,
|
||||
0x02, 0x65, 0x12, 0x48, 0xa6, 0x40,
|
||||
0x6c, 0x92, 0x92, 0x6c, 0xa0, 0x00,
|
||||
0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0x82, 0x00, 0x00,
|
||||
0x00, 0x00, 0x82, 0x7c, 0x00, 0x00,
|
||||
0x54, 0x38, 0x10, 0x38, 0x54, 0x00,
|
||||
0x10, 0x10, 0x7c, 0x10, 0x10, 0x00,
|
||||
0x00, 0x00, 0x90, 0x70, 0x00, 0x00,
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x00,
|
||||
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
|
||||
0x00, 0x60, 0x10, 0x08, 0x06, 0x00,
|
||||
0x00, 0x3c, 0x42, 0x42, 0x3c, 0x00,
|
||||
0x00, 0x44, 0x7e, 0x40, 0x00, 0x00,
|
||||
0x00, 0x44, 0x62, 0x52, 0x4c, 0x00,
|
||||
0x00, 0x42, 0x4a, 0x4e, 0x32, 0x00,
|
||||
0x30, 0x28, 0x24, 0x7e, 0x20, 0x00,
|
||||
0x00, 0x4e, 0x4a, 0x4a, 0x32, 0x00,
|
||||
0x00, 0x3c, 0x4a, 0x4a, 0x30, 0x00,
|
||||
0x00, 0x02, 0x62, 0x12, 0x0e, 0x00,
|
||||
0x00, 0x34, 0x4a, 0x4a, 0x34, 0x00,
|
||||
0x00, 0x0c, 0x52, 0x52, 0x3c, 0x00,
|
||||
0x00, 0x00, 0x6c, 0x6c, 0x00, 0x00,
|
||||
0x00, 0x00, 0x96, 0x76, 0x00, 0x00,
|
||||
0x10, 0x28, 0x28, 0x44, 0x44, 0x00,
|
||||
0x28, 0x28, 0x28, 0x28, 0x28, 0x00,
|
||||
0x44, 0x44, 0x28, 0x28, 0x10, 0x00,
|
||||
0x00, 0x02, 0x59, 0x09, 0x06, 0x00,
|
||||
0x3c, 0x42, 0x5a, 0x56, 0x08, 0x00,
|
||||
0x78, 0x14, 0x12, 0x14, 0x78, 0x00,
|
||||
0x7e, 0x4a, 0x4a, 0x4a, 0x34, 0x00,
|
||||
0x00, 0x3c, 0x42, 0x42, 0x24, 0x00,
|
||||
0x00, 0x7e, 0x42, 0x42, 0x3c, 0x00,
|
||||
0x00, 0x7e, 0x4a, 0x4a, 0x42, 0x00,
|
||||
0x00, 0x7e, 0x0a, 0x0a, 0x02, 0x00,
|
||||
0x00, 0x3c, 0x42, 0x52, 0x34, 0x00,
|
||||
0x00, 0x7e, 0x08, 0x08, 0x7e, 0x00,
|
||||
0x00, 0x42, 0x7e, 0x42, 0x00, 0x00,
|
||||
0x20, 0x40, 0x42, 0x3e, 0x02, 0x00,
|
||||
0x00, 0x7e, 0x08, 0x14, 0x62, 0x00,
|
||||
0x00, 0x7e, 0x40, 0x40, 0x40, 0x00,
|
||||
0x7e, 0x04, 0x18, 0x04, 0x7e, 0x00,
|
||||
0x00, 0x7e, 0x04, 0x08, 0x7e, 0x00,
|
||||
0x3c, 0x42, 0x42, 0x42, 0x3c, 0x00,
|
||||
0x00, 0x7e, 0x12, 0x12, 0x0c, 0x00,
|
||||
0x00, 0x3c, 0x52, 0x62, 0xbc, 0x00,
|
||||
0x00, 0x7e, 0x12, 0x12, 0x6c, 0x00,
|
||||
0x00, 0x24, 0x4a, 0x52, 0x24, 0x00,
|
||||
0x02, 0x02, 0x7e, 0x02, 0x02, 0x00,
|
||||
0x00, 0x3e, 0x40, 0x40, 0x3e, 0x00,
|
||||
0x00, 0x1e, 0x70, 0x70, 0x1e, 0x00,
|
||||
0x7e, 0x20, 0x18, 0x20, 0x7e, 0x00,
|
||||
0x42, 0x24, 0x18, 0x24, 0x42, 0x00,
|
||||
0x06, 0x08, 0x70, 0x08, 0x06, 0x00,
|
||||
0x00, 0x62, 0x52, 0x4a, 0x46, 0x00,
|
||||
0x00, 0x7e, 0x42, 0x42, 0x00, 0x00,
|
||||
0x00, 0x06, 0x08, 0x10, 0x60, 0x00,
|
||||
0x00, 0x42, 0x42, 0x7e, 0x00, 0x00,
|
||||
0x08, 0x04, 0x02, 0x04, 0x08, 0x00,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
|
||||
0x00, 0x00, 0x02, 0x04, 0x00, 0x00,
|
||||
0x00, 0x30, 0x48, 0x48, 0x78, 0x00,
|
||||
0x00, 0x7e, 0x48, 0x48, 0x30, 0x00,
|
||||
0x00, 0x30, 0x48, 0x48, 0x48, 0x00,
|
||||
0x00, 0x30, 0x48, 0x48, 0x7e, 0x00,
|
||||
0x00, 0x30, 0x68, 0x58, 0x50, 0x00,
|
||||
0x00, 0x10, 0x7c, 0x12, 0x04, 0x00,
|
||||
0x00, 0x18, 0xa4, 0xa4, 0x78, 0x00,
|
||||
0x00, 0x7e, 0x08, 0x08, 0x70, 0x00,
|
||||
0x00, 0x48, 0x7a, 0x40, 0x00, 0x00,
|
||||
0x00, 0x40, 0x84, 0x7d, 0x00, 0x00,
|
||||
0x00, 0x7e, 0x10, 0x28, 0x40, 0x00,
|
||||
0x00, 0x42, 0x7e, 0x40, 0x00, 0x00,
|
||||
0x78, 0x08, 0x30, 0x08, 0x70, 0x00,
|
||||
0x00, 0x78, 0x08, 0x08, 0x70, 0x00,
|
||||
0x00, 0x30, 0x48, 0x48, 0x30, 0x00,
|
||||
0x00, 0xfc, 0x24, 0x24, 0x18, 0x00,
|
||||
0x00, 0x18, 0x24, 0x24, 0xfc, 0x00,
|
||||
0x00, 0x78, 0x10, 0x08, 0x10, 0x00,
|
||||
0x00, 0x50, 0x58, 0x68, 0x28, 0x00,
|
||||
0x00, 0x08, 0x3e, 0x48, 0x20, 0x00,
|
||||
0x00, 0x38, 0x40, 0x40, 0x78, 0x00,
|
||||
0x00, 0x18, 0x60, 0x60, 0x18, 0x00,
|
||||
0x38, 0x40, 0x30, 0x40, 0x38, 0x00,
|
||||
0x00, 0x48, 0x30, 0x30, 0x48, 0x00,
|
||||
0x00, 0x5c, 0xa0, 0xa0, 0x7c, 0x00,
|
||||
0x00, 0x48, 0x68, 0x58, 0x48, 0x00,
|
||||
0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
|
||||
0x00, 0x08, 0x04, 0x08, 0x04, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -477,9 +477,4 @@ __attribute__ ((used)) int _write (int fhdl, const void *buf, size_t 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
src/screen.c
Normal file
266
src/screen.c
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Ha Thach (tinyusb.org) for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "boards.h"
|
||||
|
||||
#if defined(DISPLAY_PIN_SCK)
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Overlap 4x chars by this much.
|
||||
#define CHAR4_KERNING 3
|
||||
|
||||
// Width of a single 4x char, adjusted by kerning
|
||||
#define CHAR4_KERNED_WIDTH (6 * 4 - CHAR4_KERNING)
|
||||
|
||||
#define COL0(r, g, b) ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
|
||||
#define COL(c) COL0((c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff)
|
||||
|
||||
enum {
|
||||
COLOR_BLACK = 0,
|
||||
COLOR_WHITE = 1,
|
||||
COLOR_RED = 2,
|
||||
COLOR_PINK = 3,
|
||||
COLOR_ORANGE = 4,
|
||||
COLOR_YELLOW = 5,
|
||||
COLOR_CYAN = 6,
|
||||
COLOR_GREEN = 7,
|
||||
COLOR_BLUE = 8,
|
||||
COLOR_AQUA = 9,
|
||||
COLOR_PURPLE = 10,
|
||||
};
|
||||
|
||||
// 16-bit 565 color from 24-bit 888 format
|
||||
const uint16_t palette[] = {
|
||||
COL(0x000000), // 0
|
||||
COL(0xffffff), // 1
|
||||
COL(0xff2121), // 2
|
||||
COL(0xff93c4), // 3
|
||||
COL(0xff8135), // 4
|
||||
COL(0xfff609), // 5
|
||||
COL(0x249ca3), // 6
|
||||
COL(0x78dc52), // 7
|
||||
COL(0x003fad), // 8
|
||||
COL(0x87f2ff), // 9
|
||||
COL(0x8e2ec4), // 10
|
||||
|
||||
COL(0xa4839f), // 11
|
||||
COL(0x5c406c), // 12
|
||||
COL(0xe5cdc4), // 13
|
||||
COL(0x91463d), // 14
|
||||
COL(0x000000), // 15
|
||||
};
|
||||
|
||||
// TODO only buffer partial screen to save SRAM
|
||||
// ESP32s2 can only statically allocated DRAM up to 160KB.
|
||||
// the remaining 160KB can only be allocated at runtime as heap.
|
||||
static uint8_t frame_buf[DISPLAY_WIDTH * DISPLAY_HEIGHT];
|
||||
//static uint8_t* frame_buf;
|
||||
|
||||
extern const uint8_t font8[];
|
||||
extern const uint8_t fileLogo[];
|
||||
extern const uint8_t pendriveLogo[];
|
||||
extern const uint8_t arrowLogo[];
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
//
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// print character with font size = 1
|
||||
static void printch(int x, int y, int color, const uint8_t* fnt) {
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
uint8_t* p = frame_buf + (x + i) * DISPLAY_HEIGHT + y;
|
||||
uint8_t mask = 0x01;
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
if (*fnt & mask) {
|
||||
*p = color;
|
||||
}
|
||||
p++;
|
||||
mask <<= 1;
|
||||
}
|
||||
fnt++;
|
||||
}
|
||||
}
|
||||
|
||||
// print character with font size = 4
|
||||
static void printch4(int x, int y, int color, const uint8_t* fnt) {
|
||||
for (int i = 0; i < 6 * 4; ++i) {
|
||||
uint8_t* p = frame_buf + (x + i) * DISPLAY_HEIGHT + y;
|
||||
uint8_t mask = 0x01;
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
for (int k = 0; k < 4; ++k) {
|
||||
if (*fnt & mask) {
|
||||
*p = color;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
mask <<= 1;
|
||||
}
|
||||
if ((i & 3) == 3) {
|
||||
fnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// print icon
|
||||
static void printicon(int x, int y, int color, const uint8_t* icon) {
|
||||
int w = *icon++;
|
||||
int h = *icon++;
|
||||
int sz = *icon++;
|
||||
|
||||
uint8_t mask = 0x80;
|
||||
int runlen = 0;
|
||||
int runbit = 0;
|
||||
uint8_t lastb = 0x00;
|
||||
|
||||
for (int i = 0; i < w; ++i) {
|
||||
uint8_t* p = frame_buf + (x + i) * DISPLAY_HEIGHT + y;
|
||||
for (int j = 0; j < h; ++j) {
|
||||
int c = 0;
|
||||
if (mask != 0x80) {
|
||||
if (lastb & mask) {
|
||||
c = 1;
|
||||
}
|
||||
mask <<= 1;
|
||||
} else if (runlen) {
|
||||
if (runbit) {
|
||||
c = 1;
|
||||
}
|
||||
runlen--;
|
||||
} else {
|
||||
if (sz-- <= 0) {
|
||||
//TU_LOG1("Screen Panic code = 10");
|
||||
}
|
||||
lastb = *icon++;
|
||||
if (lastb & 0x80) {
|
||||
runlen = lastb & 63;
|
||||
runbit = lastb & 0x40;
|
||||
} else {
|
||||
mask = 0x01;
|
||||
}
|
||||
--j;
|
||||
continue; // restart
|
||||
}
|
||||
if (c) {
|
||||
*p = color;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// print text with font size = 1
|
||||
static void print(int x, int y, int col, const char* text) {
|
||||
int x0 = x;
|
||||
while (*text) {
|
||||
char c = *text++;
|
||||
if (c == '\r') continue;
|
||||
if (c == '\n') {
|
||||
x = x0;
|
||||
y += 10;
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
if (x + 8 > DISPLAY_WIDTH) {
|
||||
x = x0;
|
||||
y += 10;
|
||||
}
|
||||
*/
|
||||
if (c < ' ') c = '?';
|
||||
if (c >= 0x7f) c = '?';
|
||||
c -= ' ';
|
||||
printch(x, y, col, &font8[c * 6]);
|
||||
x += 6;
|
||||
}
|
||||
}
|
||||
|
||||
// Print text with font size = 4
|
||||
static void print4(int x, int y, int color, const char* text) {
|
||||
while (*text) {
|
||||
char c = *text++;
|
||||
c -= ' ';
|
||||
printch4(x, y, color, &font8[c * 6]);
|
||||
x += CHAR4_KERNED_WIDTH;
|
||||
if (x + CHAR4_KERNED_WIDTH > DISPLAY_WIDTH) {
|
||||
// Next char won't fit.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
//
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
static void draw_screen(uint8_t const* fb) {
|
||||
uint8_t const* p = fb;
|
||||
for (int y = 0; y < DISPLAY_WIDTH; ++y) {
|
||||
uint8_t cc[DISPLAY_HEIGHT * 2];
|
||||
uint32_t dst = 0;
|
||||
for (int x = 0; x < DISPLAY_HEIGHT; ++x) {
|
||||
uint16_t color = palette[*p++ & 0xf];
|
||||
cc[dst++] = color >> 8;
|
||||
cc[dst++] = color & 0xff;
|
||||
}
|
||||
|
||||
board_display_draw_line(y, cc, sizeof(cc));
|
||||
}
|
||||
}
|
||||
|
||||
// draw color bar
|
||||
static void drawBar(int y, int h, int color) {
|
||||
for (int x = 0; x < DISPLAY_WIDTH; ++x) {
|
||||
memset(frame_buf + x * DISPLAY_HEIGHT + y, color, h);
|
||||
}
|
||||
}
|
||||
|
||||
// draw drag & drop screen
|
||||
void screen_draw_drag(void) {
|
||||
drawBar(0, 52, COLOR_GREEN);
|
||||
drawBar(52, 55, COLOR_BLUE);
|
||||
drawBar(107, 14, COLOR_ORANGE);
|
||||
|
||||
// Center UF2_PRODUCT_NAME and UF2_VERSION_BASE.
|
||||
int name_x = (DISPLAY_WIDTH - CHAR4_KERNED_WIDTH * (int) strlen(DISPLAY_TITLE)) / 2;
|
||||
print4(name_x >= 0 ? name_x : 0, 5, COLOR_WHITE, DISPLAY_TITLE);
|
||||
|
||||
int version_x = (DISPLAY_WIDTH - 6 * (int) strlen(UF2_VERSION_BASE)) / 2;
|
||||
print(version_x >= 0 ? version_x : 0, 40, COLOR_PURPLE, UF2_VERSION_BASE);
|
||||
|
||||
// TODO the reset should be center as well
|
||||
print(23, 110, 1, "circuitpython.org");
|
||||
|
||||
#define DRAG 70
|
||||
#define DRAGX 10
|
||||
printicon(DRAGX + 20, DRAG + 5, COLOR_WHITE, fileLogo);
|
||||
printicon(DRAGX + 66, DRAG, COLOR_WHITE, arrowLogo);
|
||||
printicon(DRAGX + 108, DRAG, COLOR_WHITE, pendriveLogo);
|
||||
print(10, DRAG - 12, COLOR_WHITE, "firmware.uf2");
|
||||
print(90, DRAG - 12, COLOR_WHITE, UF2_VOLUME_LABEL);
|
||||
|
||||
draw_screen(frame_buf);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue