diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b97dd61 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/u8g2/u8g2"] + path = lib/u8g2/u8g2 + url = https://github.com/olikraus/u8g2 diff --git a/lib/u8g2/library.json b/lib/u8g2/library.json new file mode 100644 index 0000000..490d126 --- /dev/null +++ b/lib/u8g2/library.json @@ -0,0 +1,10 @@ +{ + "name": "u8g2-generic-c", + "version": "0.0.1", + "description": "Generic C build of U8g2", + "keywords": "Ooph", + "build": { + "srcDir": "u8g2/csrc", + "includeDir": "u8g2/csrc" + } +} diff --git a/lib/u8g2/u8g2 b/lib/u8g2/u8g2 new file mode 160000 index 0000000..3c6460a --- /dev/null +++ b/lib/u8g2/u8g2 @@ -0,0 +1 @@ +Subproject commit 3c6460a73f7f310c665cef0af1d2bac49bf6c655 diff --git a/platformio.ini b/platformio.ini index 3c238fb..32fff50 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] -default_envs = nrf52840_dk +default_envs = pinetime_dk [env:nrf52840_dk] platform = nordicnrf52 @@ -31,19 +31,23 @@ lib_ignore = [env:pinetime_dk] platform = nordicnrf52 board = pinetime_devkit0 -framework = zephyr +framework = zephyr monitor_speed = 115200 test_ignore = test_desktop build_flags = -Iinclude/tls_config +# -I.pio/libdeps/pinetime_dk # For testing: -DUNITY_EXCLUDE_SETJMP_H=1 -DEN_INCLUDE_ZEPHYR_DEPS=1 -DEN_INIT_MBEDTLS_ENTROPY=0 -DCOVID_MEASURE_PERFORMANCE=0 # Used to measure device performance - -DMAX_CONTACTS=10 - -DMAX_PERIOD_CONTACTS=10 + -DMAX_CONTACTS=5 + -DMAX_PERIOD_CONTACTS=5 -DNO_DEPRECATED_BLE_OPTIONS=1 + -DPLATFORM_PINETIME=1 +#lib_ldf_mode = off lib_deps = + u8g2-generic-c prathje/exposure-notification @ ^0.1 lib_ignore = mbedtls diff --git a/src/display.h b/src/display.h new file mode 100644 index 0000000..49671bc --- /dev/null +++ b/src/display.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +#ifdef PLATFORM_PINETIME +#include "display_pinetime.h" +#define platform_display_init pinetime_display_init +#define platform_display_set_brightness pinetime_display_set_brightness +#else +static inline int platform_display_init() { return 0; } +static inline void platform_display_set_brightness(uint8_t brightness) { } +#endif \ No newline at end of file diff --git a/src/display_pinetime.c b/src/display_pinetime.c new file mode 100644 index 0000000..b4ef7a4 --- /dev/null +++ b/src/display_pinetime.c @@ -0,0 +1,175 @@ +#ifdef PLATFORM_PINETIME + +#include +#include +#include +#include + +#include + +#include "display.h" + +#define BACKLIGHT_LOW_OF_NODE DT_ALIAS(led0) +#define BACKLIGHT_MID_OF_NODE DT_ALIAS(led1) +#define BACKLIGHT_HI_OF_NODE DT_ALIAS(led2) +// dev and flags are the same for all backlight GPIOs +#define BACKLIGHT_DEVNAME DT_GPIO_LABEL(BACKLIGHT_LOW_OF_NODE, gpios) +#define BACKLIGHT_FLAGS (DT_GPIO_FLAGS(BACKLIGHT_LOW_OF_NODE, gpios) | GPIO_OUTPUT) +#define BACKLIGHT_LOW_PIN DT_GPIO_PIN(BACKLIGHT_LOW_OF_NODE, gpios) +#define BACKLIGHT_MID_PIN DT_GPIO_PIN(BACKLIGHT_MID_OF_NODE, gpios) +#define BACKLIGHT_HI_PIN DT_GPIO_PIN(BACKLIGHT_HI_OF_NODE, gpios) + +static struct { + const struct device *display_dev; + const struct device *backlight_dev; +} pinetime_display; + +static const u8x8_display_info_t pinetime_display_info = { + // Tile setup for u8x8 + .tile_width = 240 / 8, + .tile_height = 240 / 8, + // Pixel setup for u8g2 + .pixel_width = 240, + .pixel_height = 240, +}; + +static uint16_t tile_tmp[8 * 8]; +// Represents a single u8x8 tile +const struct display_buffer_descriptor buffer_desc = { + .buf_size = sizeof(tile_tmp), + .width = 8, + .height = 8, + .pitch = 8 +}; + +uint8_t u8x8_cmd_cb(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) { + u8x8_tile_t *tile; + int i, x, y; + + switch(msg) { + case U8X8_MSG_DISPLAY_SETUP_MEMORY: + u8x8_d_helper_display_setup_memory(u8x8, &pinetime_display_info); + break; + case U8X8_MSG_DISPLAY_INIT: + u8x8_d_helper_display_init(u8x8); + break; + case U8X8_MSG_DISPLAY_DRAW_TILE: + tile = ((u8x8_tile_t *)arg_ptr); + uint8_t *tile_ptr = tile->tile_ptr; + + for (i = 0; i < tile->cnt; i++) { + int rep = 0; + + for (x = 0; x < 8; x++) { + uint8_t byte = *tile_ptr++; + + for (y = 0; y < 8; y++) { + tile_tmp[x + y * 8] = (byte & (1 << y)) ? 0xffff : 0; + } + } + while (rep < arg_int) { + display_write(pinetime_display.display_dev, (tile->x_pos + i + rep) * 8, tile->y_pos * 8, &buffer_desc, tile_tmp); + rep++; + } + } + break; + case U8X8_MSG_DISPLAY_SET_POWER_SAVE: + if (arg_int) { + display_blanking_on(pinetime_display.display_dev); + } else { + display_blanking_off(pinetime_display.display_dev); + } + } + return 1; +} + +static u8x8_t u8x8; + +void pinetime_display_set_brightness(const uint8_t brightness) { + // Parse 3 MSB only + gpio_pin_set(pinetime_display.backlight_dev, BACKLIGHT_HI_PIN, brightness & 0x80); + gpio_pin_set(pinetime_display.backlight_dev, BACKLIGHT_MID_PIN, brightness & 0x40); + gpio_pin_set(pinetime_display.backlight_dev, BACKLIGHT_LOW_PIN, brightness & 0x20); +} + +int pinetime_display_init() { + int err; + uint8_t ppt; + + // Get display device + pinetime_display.display_dev = device_get_binding("ST7789V"); + if (!pinetime_display.display_dev) { + return -ENODEV; + } + + // Patch in gpio based backlight control +// ((struct display_driver_api *)pinetime_display.display_dev->api)->set_brightness = set_brightness; + + pinetime_display.backlight_dev = device_get_binding(BACKLIGHT_DEVNAME); + if (!pinetime_display.backlight_dev) { + return -ENODEV; + } + + // Initialize backlight GPIOs + err = gpio_pin_configure(pinetime_display.backlight_dev, BACKLIGHT_LOW_PIN, BACKLIGHT_FLAGS); + if (err) { + return err; + } + + err = gpio_pin_configure(pinetime_display.backlight_dev, BACKLIGHT_MID_PIN, BACKLIGHT_FLAGS); + if (err) { + return err; + } + + err = gpio_pin_configure(pinetime_display.backlight_dev, BACKLIGHT_HI_PIN, BACKLIGHT_FLAGS); + if (err) { + return err; + } + pinetime_display_set_brightness(0); + +/* + gpio_pin_set(backlight_dev, PIN, 1); + + display_blanking_off(pinetime_display.display_dev); + + + err = cfb_framebuffer_init(pinetime_display.display_dev); + if (err) { + return err; + } + + err = cfb_framebuffer_clear(pinetime_display.display_dev, false); + if (err) { + return err; + } + + ppt = cfb_get_display_parameter(pinetime_display.display_dev, CFB_DISPLAY_PPT); + + err = cfb_print(pinetime_display.display_dev, "Hello World", 0, 0); + if (err) { + return err; + } + + err = cfb_framebuffer_finalize(pinetime_display.display_dev); + if (err) { + return err; + } + display_write(pinetime_display.display_dev, 0, 0, &buffer_desc, white_8x8); + + display_blanking_off(pinetime_display.display_dev); +*/ + + // Set up graphics library + // Populate all hardware callbacks with dummy functions, we do already have a driver + u8x8_Setup(&u8x8, u8x8_cmd_cb, u8x8_dummy_cb, u8x8_dummy_cb, u8x8_dummy_cb); + u8x8_InitDisplay(&u8x8); + u8x8_ClearDisplay(&u8x8); + u8x8_SetPowerSave(&u8x8, false); + u8x8_SetFont(&u8x8, u8x8_font_amstrad_cpc_extended_f); + u8x8_DrawString(&u8x8, 0, 0, "Hello World"); + display_blanking_off(pinetime_display.display_dev); + + return 0; +} + +#endif \ No newline at end of file diff --git a/src/display_pinetime.h b/src/display_pinetime.h new file mode 100644 index 0000000..2902e8f --- /dev/null +++ b/src/display_pinetime.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +int pinetime_display_init(); +void pinetime_display_set_brightness(uint8_t brightness); diff --git a/src/main.c b/src/main.c index 6633bd0..8d890aa 100644 --- a/src/main.c +++ b/src/main.c @@ -17,12 +17,21 @@ #include "gatt_service.h" #include "covid.h" #include "io.h" +#include "display.h" void main(void) { int err = 0; printk("Starting Covid Contact Tracer\n"); + err = platform_display_init(); + if (err) { + printk("Failed to initialize display: %d\n", err); + return; + } + + platform_display_set_brightness(0xff); + // first init everything // Use custom randomization as the mbdet_tls context initialization messes with the Zeyhr BLE stack. err = en_init(sys_csrand_get); diff --git a/zephyr/prj.conf b/zephyr/prj.conf index 5cffe80..77380cf 100644 --- a/zephyr/prj.conf +++ b/zephyr/prj.conf @@ -10,8 +10,24 @@ CONFIG_ENTROPY_GENERATOR=y CONFIG_MBEDTLS=y CONFIG_MBEDTLS_USER_CONFIG_ENABLE=y CONFIG_MBEDTLS_USER_CONFIG_FILE="user-tls.conf" -CONFIG_MBEDTLS_ENABLE_HEAP=y -CONFIG_MBEDTLS_HEAP_SIZE=16384 +#CONFIG_MBEDTLS_ENABLE_HEAP=y +#CONFIG_MBEDTLS_HEAP_SIZE=4096 #CONFIG_BT_HCI_TX_STACK_SIZE=1024 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +CONFIG_DISPLAY=y +CONFIG_CHARACTER_FRAMEBUFFER=y +CONFIG_SPI=y +CONFIG_ST7789V=y +CONFIG_HEAP_MEM_POOL_SIZE=8192 + +CONFIG_GPIO=y +CONFIG_LED=y + +#CONFIG_LVGL=y +#CONFIG_LVGL_USE_LABEL=y +#CONFIG_LVGL_USE_CONT=y +#CONFIG_LVGL_USE_BTN=y +#CONFIG_LVGL_USE_THEME_MATERIAL=y +#CONFIG_LVGL_DISPLAY_DEV_NAME="ST7789V" \ No newline at end of file