diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f33d7eca..043bb4ef 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,3 +22,5 @@ jobs: run: docker run rebbleos make snowy - name: Build asterix run: docker run rebbleos make asterix + - name: Build asterix dvb2 + run: docker run rebbleos make asterix_vla_dvb2 diff --git a/Apps/System/testapp.c b/Apps/System/testapp.c index cc251a7f..a6e5d696 100644 --- a/Apps/System/testapp.c +++ b/Apps/System/testapp.c @@ -14,7 +14,7 @@ static Window *s_main_window; static Menu *s_menu; -StatusBarLayer *status_bar; +static StatusBarLayer *status_bar; static void testapp_exec_window_unload(Window *window); static void _reset_menu_items(void); diff --git a/Apps/System/widgettest.c b/Apps/System/widgettest.c index a3ce1cb6..4361a682 100644 --- a/Apps/System/widgettest.c +++ b/Apps/System/widgettest.c @@ -18,7 +18,7 @@ const char * const test_name = "Test"; static Window *s_main_window; ActionBarLayer *action_bar; -StatusBarLayer *status_bar; +static StatusBarLayer *status_bar; typedef struct { uint8_t hours; diff --git a/Utilities/stm32_crc.py b/Utilities/stm32_crc.py index 1c0bd08d..ad8119aa 100644 --- a/Utilities/stm32_crc.py +++ b/Utilities/stm32_crc.py @@ -9,7 +9,10 @@ def process_word(data, crc=0xffffffff): for x in range(0, 4 - len(data)): d_array.insert(0,0) d_array.reverse() - data = d_array.tostring() + try: + data = d_array.tobytes() + except: + data = d_array.tostring() d = array.array('I', data)[0] crc = crc ^ d diff --git a/hw/drivers/nrf52_ls013b7dh05/nrf52_ls013b7dh05.c b/hw/drivers/nrf52_ls013b7dh05/nrf52_ls013b7dh05.c index 3a5a6ca6..52726bd9 100644 --- a/hw/drivers/nrf52_ls013b7dh05/nrf52_ls013b7dh05.c +++ b/hw/drivers/nrf52_ls013b7dh05/nrf52_ls013b7dh05.c @@ -12,7 +12,13 @@ #define DISPLAY_LINES_PER_CHUNK 21 /* 8 chunks per frame */ +#ifdef BOARD_QSPI_SHARED_DISPLAY +extern void nrf52_spi_lock(); +extern void nrf52_spi_unlock(); +#endif + static void _spi_handler(const nrfx_spim_evt_t *p_event, void *p_context) { + nrf52_spi_unlock(); display_done_isr(0); } @@ -78,6 +84,7 @@ uint8_t hw_display_process_isr() { _dispbuf[p++] = 0; _spi_desc.tx_length = p; + nrf52_spi_lock(); /* handled in _spi_handler */ err = nrfx_spim_xfer(&_display_spi, &_spi_desc, 0); assert(err == NRFX_SUCCESS); diff --git a/hw/drivers/nrf52_qspi_flash/nrf52_qspi_flash.c b/hw/drivers/nrf52_qspi_flash/nrf52_qspi_flash.c index 5920fb0a..acb0a22c 100644 --- a/hw/drivers/nrf52_qspi_flash/nrf52_qspi_flash.c +++ b/hw/drivers/nrf52_qspi_flash/nrf52_qspi_flash.c @@ -7,16 +7,64 @@ #include #include "rebbleos.h" +#include "nrf_gpio.h" #include "nrfx_qspi.h" +#include "rtoswrap.h" /* Asterix has 128Mbit (16MB) of QSPI flash -- a W25Q128JV. */ #define QSPI_JEDEC_ID_W25Q128JV 0xEF4018 -/* Asterix-Vla has 64Mbit (8MB) of QSPI flash - a XT25F64B. */ +/* Asterix-Vla-dvb1 and -dvb2 have 64Mbit (8MB) of QSPI flash - a XT25F64B. */ #define QSPI_JEDEC_ID_XT25F64B 0x0B4017 #include "board_config.h" +#if BOARD_QSPI_SHARED_DISPLAY +/* XXX: abstraction violation: would be nice not to call into rtoswrap stuff + * in HAL */ +static StaticSemaphore_t _nrf52_spi_lock_buf; +static SemaphoreHandle_t _nrf52_spi_lock; + +void nrf52_spi_lock() { + xSemaphoreTake(_nrf52_spi_lock, portMAX_DELAY); +} + +void nrf52_spi_unlock() { + if (xPortIsInsideInterrupt()) { + BaseType_t woken = pdFALSE; + + xSemaphoreGiveFromISR(_nrf52_spi_lock, &woken); + portYIELD_FROM_ISR(woken); + + return; + } + + xSemaphoreGive(_nrf52_spi_lock); +} + +static void _qspi_prepare() { + nrf52_spi_lock(); + nrf_qspi_enable(NRF_QSPI); +} + +static void _qspi_teardown() { + nrf_qspi_disable(NRF_QSPI); + nrf52_spi_unlock(); +} +#else +void nrf52_spi_lock() { +} + +void nrf52_spi_unlock() { +} + +static void _qspi_prepare() { +} + +static void _qspi_teardown() { +} +#endif + #define QSPI_INSTR_JEDEC_ID 0x9F /* We can have out-of-band flash transactions -- like if we break in with @@ -26,6 +74,7 @@ volatile static int _flash_sync = 0; static void _flash_handler(nrfx_qspi_evt_t event, void *ctx) { assert(event == NRFX_QSPI_EVENT_DONE); + _qspi_teardown(); if (_flash_sync) { _flash_sync = 0; return; @@ -34,6 +83,11 @@ static void _flash_handler(nrfx_qspi_evt_t event, void *ctx) { } void hw_flash_init() { +#if BOARD_QSPI_SHARED_DISPLAY + _nrf52_spi_lock = xSemaphoreCreateBinaryStatic(&_nrf52_spi_lock_buf); + nrf52_spi_unlock(); +#endif + nrfx_qspi_config_t config = NRFX_QSPI_DEFAULT_CONFIG; config.phy_if.sck_freq = NRF_QSPI_FREQ_32MDIV1; config.pins.sck_pin = BOARD_QSPI_SCK_PIN; @@ -61,6 +115,9 @@ void hw_flash_init() { nrf_qspi_cinstr_conf_t instr = NRFX_QSPI_DEFAULT_CINSTR(QSPI_INSTR_JEDEC_ID, 4); uint8_t buf[16]; + + /* We are single-threaded at this stage, so we do not need to + * nrf52_spi_lock(). */ err = nrfx_qspi_cinstr_xfer(&instr, NULL, buf); assert(err == NRFX_SUCCESS && "QSPI JEDEC ID read failed"); @@ -78,6 +135,7 @@ void hw_flash_init() { void hw_flash_read_bytes(uint32_t addr, uint8_t *buf, size_t len) { nrfx_err_t err; + _qspi_prepare(); /* unlocked in ISR */ err = nrfx_qspi_read(buf, len, addr); assert(err == NRFX_SUCCESS); } @@ -86,14 +144,17 @@ void hw_flash_erase_64k_sync(uint32_t addr) { nrfx_err_t err; _flash_sync = 1; + _qspi_prepare(); /* unlocked in ISR */ err = nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_64KB, addr); assert(err == NRFX_SUCCESS); while (_flash_sync) ; + _qspi_prepare(); while (nrfx_qspi_mem_busy_check() != NRFX_SUCCESS) ; + _qspi_teardown(); } int hw_flash_erase_sync(uint32_t addr, uint32_t len) { @@ -115,14 +176,17 @@ int hw_flash_write_sync(uint32_t addr, uint8_t *buf, size_t len) { assert((((uint32_t)buf) & 3) == 0); _flash_sync = 1; + _qspi_prepare(); /* unlocked in ISR */ err = nrfx_qspi_write(buf, len, addr); assert(err == NRFX_SUCCESS); while (_flash_sync) ; + _qspi_prepare(); while (nrfx_qspi_mem_busy_check() != NRFX_SUCCESS) ; + _qspi_teardown(); return 0; } diff --git a/hw/platform/asterix/board_config.h b/hw/platform/asterix/board_config.h index 7a644422..f473b0c9 100644 --- a/hw/platform/asterix/board_config.h +++ b/hw/platform/asterix/board_config.h @@ -58,6 +58,31 @@ #define BOARD_DISPLAY_ROT180 +#elif defined(ASTERIX_BOARD_VLA_DVB2) + +#define BOARD_BUTTON_BACK_PIN NRF_GPIO_PIN_MAP(0,27) +#define BOARD_BUTTON_UP_PIN NRF_GPIO_PIN_MAP(1,0) +#define BOARD_BUTTON_SELECT_PIN NRF_GPIO_PIN_MAP(0,11) +#define BOARD_BUTTON_DOWN_PIN NRF_GPIO_PIN_MAP(1,2) + +#define BOARD_DISPLAY_PIN_MOSI NRF_GPIO_PIN_MAP(0,3) +#define BOARD_DISPLAY_PIN_SCK NRF_GPIO_PIN_MAP(0,2) +#define BOARD_DISPLAY_PIN_SCS NRF_GPIO_PIN_MAP(0,25) + +#define BOARD_QSPI_SCK_PIN NRF_GPIO_PIN_MAP(0,2) +#define BOARD_QSPI_CSN_PIN NRF_GPIO_PIN_MAP(0,5) +#define BOARD_QSPI_IO0_PIN NRF_GPIO_PIN_MAP(0,3) /* MOSI */ +#define BOARD_QSPI_IO1_PIN NRF_GPIO_PIN_MAP(0,4) /* MISO */ +#define BOARD_QSPI_SHARED_DISPLAY 1 + +#define BOARD_QSPI_JEDEC_ID QSPI_JEDEC_ID_XT25F64B + +#define BOARD_DEBUG_UART_TXD 35 + +#define BOARD_BACKLIGHT_PIN NRF_GPIO_PIN_MAP(1,4) + +#define BOARD_DISPLAY_ROT180 + #else #error unknown Asterix board diff --git a/hw/platform/asterix/config.mk b/hw/platform/asterix/config.mk index 81952c7d..4428693e 100644 --- a/hw/platform/asterix/config.mk +++ b/hw/platform/asterix/config.mk @@ -43,3 +43,13 @@ HWREV_asterix_vla_dvb1 = asterix_vla_dvb1 CFLAGS_asterix_vla_dvb1 += -DASTERIX_BOARD_VLA_DVB1 PLATFORMS += asterix_vla_dvb1 + +CFLAGS_asterix_vla_dvb2 = $(CFLAGS_asterix_common) +SRCS_asterix_vla_dvb2 = $(SRCS_asterix_common) +LDFLAGS_asterix_vla_dvb2 = $(LDFLAGS_asterix_common) +LIBS_asterix_vla_dvb2 = $(LIBS_asterix_common) +HWREV_asterix_vla_dvb2 = asterix_vla_dvb2 + +CFLAGS_asterix_vla_dvb2 += -DASTERIX_BOARD_VLA_DVB2 + +PLATFORMS += asterix_vla_dvb2 diff --git a/hw/platform/asterix/platform.h b/hw/platform/asterix/platform.h index ce7e95b8..900fe298 100644 --- a/hw/platform/asterix/platform.h +++ b/hw/platform/asterix/platform.h @@ -50,6 +50,23 @@ #define REGION_FS_N_PAGES ((0x7E0000 - REGION_FS_START) / REGION_FS_PAGE_SIZE) #define REGION_FS_ERASE_SIZE (64*1024) +#elif defined(ASTERIX_BOARD_VLA_DVB2) + +/* Asterix-VLA has 8MB of flash. */ + +/* Bootloader private area: 1MB */ +#define REGION_BOOTLOADER_START 0x0 +#define REGION_BOOTLOADER_SIZE 0x100000 + +/* System resources: 1MB */ +#define REGION_RES_START 0x100000 +#define REGION_RES_SIZE 0x100000 + +/* The rest of the filesystem: 6MB */ +#define REGION_FS_START 0x200000 +#define REGION_FS_PAGE_SIZE 0x2000 +#define REGION_FS_N_PAGES ((0x7E0000 - REGION_FS_START) / REGION_FS_PAGE_SIZE) +#define REGION_FS_ERASE_SIZE (64*1024) #else #error incorrect board diff --git a/res b/res index 3e53cb2d..4746cac8 160000 --- a/res +++ b/res @@ -1 +1 @@ -Subproject commit 3e53cb2d05818129dd7b8645894ee0b3d8b65fbb +Subproject commit 4746cac86d91ae8a98e2788c80bf27613a33b212