Add display support

This commit is contained in:
Tobias Schramm 2021-02-08 20:50:53 +01:00 committed by Patrick Rathje
parent 959e946ce4
commit d6270ffb3f
9 changed files with 242 additions and 6 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "lib/u8g2/u8g2"]
path = lib/u8g2/u8g2
url = https://github.com/olikraus/u8g2

10
lib/u8g2/library.json Normal file
View File

@ -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"
}
}

1
lib/u8g2/u8g2 Submodule

@ -0,0 +1 @@
Subproject commit 3c6460a73f7f310c665cef0af1d2bac49bf6c655

View File

@ -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

12
src/display.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#include <stdint.h>
#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

175
src/display_pinetime.c Normal file
View File

@ -0,0 +1,175 @@
#ifdef PLATFORM_PINETIME
#include <zephyr.h>
#include <device.h>
#include <display/cfb.h>
#include <drivers/gpio.h>
#include <u8x8.h>
#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

6
src/display_pinetime.h Normal file
View File

@ -0,0 +1,6 @@
#pragma once
#include <stdint.h>
int pinetime_display_init();
void pinetime_display_set_brightness(uint8_t brightness);

View File

@ -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);

View File

@ -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"