1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

lws_display: improve apis to use display_state and frac

Adapt disp ops to use lws_display_state_t instead of the const disp object.

Describe display area in pixels and mm using lws_fixed3232.
This commit is contained in:
Andy Green 2022-01-05 07:10:50 +00:00
parent 1d3ec6a3a1
commit aa696773f0
11 changed files with 396 additions and 75 deletions

View file

@ -1,7 +1,7 @@
/*
* lws abstract display
*
* Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
* Copyright (C) 2019 - 2022 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@ -25,9 +25,61 @@
#if !defined(__LWS_DISPLAY_H__)
#define __LWS_DISPLAY_H__
#include <stdint.h>
typedef int16_t lws_display_list_coord_t;
typedef uint16_t lws_display_scalar;
typedef uint16_t lws_display_rotation_t;
typedef uint32_t lws_display_colour_t;
typedef uint16_t lws_display_palette_idx_t;
typedef struct lws_box {
lws_fx_t x;
lws_fx_t y;
lws_fx_t w;
lws_fx_t h;
} lws_box_t;
struct lws_display_state;
struct lws_display;
typedef enum {
LWSSURF_TRUECOLOR32,
LWSSURF_565,
LWSSURF_PALETTE,
} lws_surface_type_t;
typedef struct lws_surface_info {
lws_fx_t wh_px[2];
lws_fx_t wh_mm[2];
const lws_display_colour_t *palette;
size_t palette_depth;
lws_surface_type_t type;
char greyscale; /* line: 0 = RGBA, 1 = YA */
} lws_surface_info_t;
typedef struct lws_greyscale_error {
int16_t rgb[1];
} lws_greyscale_error_t;
typedef struct lws_colour_error {
int16_t rgb[3];
} lws_colour_error_t;
typedef union {
lws_greyscale_error_t grey; /* when ic->greyscale set */
lws_colour_error_t colour; /* when ic->greyscale == 0 */
} lws_surface_error_t;
LWS_VISIBLE LWS_EXTERN void
lws_surface_set_px(const lws_surface_info_t *ic, uint8_t *line, int x,
const lws_display_colour_t *c);
LWS_VISIBLE LWS_EXTERN lws_display_palette_idx_t
lws_display_palettize_grey(const struct lws_surface_info *ic, lws_display_colour_t c,
lws_greyscale_error_t *ectx);
LWS_VISIBLE LWS_EXTERN lws_display_palette_idx_t
lws_display_palettize_col(const struct lws_surface_info *ic, lws_display_colour_t c,
lws_colour_error_t *ectx);
/*
* This is embedded in the actual display implementation object at the top,
@ -41,26 +93,23 @@ typedef uint16_t lws_display_scalar;
*/
typedef struct lws_display {
int (*init)(const struct lws_display *disp);
int (*init)(struct lws_display_state *lds);
const lws_pwm_ops_t *bl_pwm_ops;
int (*contrast)(const struct lws_display *disp, uint8_t contrast);
int (*blit)(const struct lws_display *disp, const uint8_t *src,
lws_display_scalar x, lws_display_scalar y,
lws_display_scalar w, lws_display_scalar h);
int (*power)(const struct lws_display *disp, int state);
int (*contrast)(struct lws_display_state *lds, uint8_t contrast);
int (*blit)(struct lws_display_state *lds, const uint8_t *src,
lws_box_t *box);
int (*power)(struct lws_display_state *lds, int state);
const lws_led_sequence_def_t *bl_active;
const lws_led_sequence_def_t *bl_dim;
const lws_led_sequence_def_t *bl_transition;
const char *name;
void *variant;
int bl_index;
lws_display_scalar w;
/**< display surface width in pixels */
lws_display_scalar h;
/**< display surface height in pixels */
lws_surface_info_t ic;
uint8_t latency_wake_ms;
/**< ms required after wake from sleep before display usable again...
@ -86,6 +135,8 @@ typedef struct lws_display_state {
const lws_display_t *disp;
struct lws_context *ctx;
void *priv; /* subclass driver alloc'd priv */
int autodim_ms;
int off_ms;

View file

@ -1,7 +1,7 @@
/*
* lws abstract display implementation for ili9341 on spi
*
* Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
* Copyright (C) 2019 - 2022 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@ -39,13 +39,12 @@ typedef struct lws_display_ili9341 {
} lws_display_ili9341_t;
int
lws_display_ili9341_spi_init(const struct lws_display *disp);
lws_display_ili9341_spi_init(lws_display_state_t *lds);
int
lws_display_ili9341_spi_blit(const struct lws_display *disp, const uint8_t *src,
lws_display_scalar x, lws_display_scalar y,
lws_display_scalar w, lws_display_scalar h);
lws_display_ili9341_spi_blit(lws_display_state_t *lds, const uint8_t *src,
lws_box_t *box);
int
lws_display_ili9341_spi_power(const struct lws_display *disp, int state);
lws_display_ili9341_spi_power(lws_display_state_t *lds, int state);
#define lws_display_ili9341_ops \
.init = lws_display_ili9341_spi_init, \

View file

@ -46,15 +46,14 @@ typedef struct lws_display_ssd1306 {
} lws_display_ssd1306_t;
int
lws_display_ssd1306_i2c_init(const struct lws_display *disp);
lws_display_ssd1306_i2c_init(lws_display_state_t *lds);
int
lws_display_ssd1306_i2c_contrast(const struct lws_display *disp, uint8_t b);
lws_display_ssd1306_i2c_contrast(lws_display_state_t *lds, uint8_t b);
int
lws_display_ssd1306_i2c_blit(const struct lws_display *disp, const uint8_t *src,
lws_display_scalar x, lws_display_scalar y,
lws_display_scalar w, lws_display_scalar h);
lws_display_ssd1306_i2c_blit(lws_display_state_t *lds, const uint8_t *src,
lws_box_t *box);
int
lws_display_ssd1306_i2c_power(const struct lws_display *disp, int state);
lws_display_ssd1306_i2c_power(lws_display_state_t *lds, int state);
#define lws_display_ssd1306_ops \
.init = lws_display_ssd1306_i2c_init, \

View file

@ -59,9 +59,9 @@ static uint8_t ili9341_320x240_init[] = {
};
int
lws_display_ili9341_spi_init(const struct lws_display *disp)
lws_display_ili9341_spi_init(lws_display_state_t *lds)
{
const lws_display_ili9341_t *ili = (const lws_display_ili9341_t *)disp;
const lws_display_ili9341_t *ili = (const lws_display_ili9341_t *)lds->disp;
lws_spi_desc_t desc;
size_t pos = 0;
uint8_t u[8];
@ -114,17 +114,17 @@ lws_display_ili9341_spi_init(const struct lws_display *disp)
/* backlight handled by PWM */
int
lws_display_ili9341_spi_brightness(const struct lws_display *disp, uint8_t b)
lws_display_ili9341_spi_brightness(lws_display_state_t *lds, uint8_t b)
{
return 0;
}
int
lws_display_ili9341_spi_blit(const struct lws_display *disp, const uint8_t *src,
lws_display_scalar x, lws_display_scalar y,
lws_display_scalar w, lws_display_scalar h)
lws_display_ili9341_spi_blit(lws_display_state_t *lds, const uint8_t *src,
lws_box_t *box)
{
const lws_display_ili9341_t *ili = (const lws_display_ili9341_t *)disp;
const lws_display_ili9341_t *ili = (const lws_display_ili9341_t *)lds->disp;
lws_display_list_coord_t h, y;
lws_spi_desc_t desc;
uint8_t u[5];
@ -137,14 +137,17 @@ lws_display_ili9341_spi_blit(const struct lws_display *disp, const uint8_t *src,
* Blit a line at a time
*/
h = box->h.whole;
y = box->y.whole;
while (h--) {
u[0] = ILI9341_CASET;
desc.data = &u[1];
u[1] = x;
u[2] = x;
u[3] = w >> 8;
u[4] = w & 0xff;
u[1] = box->x.whole;
u[2] = box->x.whole;
u[3] = box->w.whole >> 8;
u[4] = box->w.whole & 0xff;
desc.count_write = 4;
ili->spi->queue(ili->spi, &desc);
@ -158,9 +161,9 @@ lws_display_ili9341_spi_blit(const struct lws_display *disp, const uint8_t *src,
u[0] = ILI9341_RAMWR;
desc.data = src;
desc.count_write = w * 2;
desc.count_write = box->w.whole * 2;
ili->spi->queue(ili->spi, &desc);
src += w * 2;
src += box->w.whole * 2;
y++;
}
@ -168,10 +171,10 @@ lws_display_ili9341_spi_blit(const struct lws_display *disp, const uint8_t *src,
}
int
lws_display_ili9341_spi_power(const struct lws_display *disp, int state)
lws_display_ili9341_spi_power(lws_display_state_t *lds, int state)
{
const lws_display_ili9341_t *ili = (const lws_display_ili9341_t *)disp;
const lws_display_ili9341_t *ili = (const lws_display_ili9341_t *)lds->disp;
lws_spi_desc_t desc;
uint8_t u[1];

View file

@ -1,7 +1,7 @@
/*
* lws abstract display
*
* Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
* Copyright (C) 2019 - 2022 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@ -22,7 +22,7 @@
* IN THE SOFTWARE.
*/
#include <libwebsockets.h>
#include <private-lib-core.h>
static void
sul_autodim_cb(lws_sorted_usec_list_t *sul)
@ -85,7 +85,7 @@ lws_display_state_init(lws_display_state_t *lds, struct lws_context *ctx,
lws_led_transition(lds->bl_lcs, "backlight", &lws_pwmseq_static_off,
&lws_pwmseq_static_on);
disp->init(disp);
disp->init(lds);
}
void
@ -103,7 +103,7 @@ lws_display_state_active(lws_display_state_t *lds)
if (lds->state == LWSDISPS_OFF) {
/* power us up */
lds->disp->power(lds->disp, 1);
lds->disp->power(lds, 1);
lds->state = LWSDISPS_BECOMING_ACTIVE;
waiting_ms = lds->disp->latency_wake_ms;
} else {
@ -120,13 +120,274 @@ lws_display_state_active(lws_display_state_t *lds)
if (waiting_ms >= 0)
lws_sul_schedule(lds->ctx, 0, &lds->sul_autodim, sul_autodim_cb,
waiting_ms * LWS_US_PER_MS);
}
void
lws_display_state_off(lws_display_state_t *lds)
{
lds->disp->power(lds->disp, 0);
lds->disp->power(lds, 0);
lws_sul_cancel(&lds->sul_autodim);
lds->state = LWSDISPS_OFF;
}
int
lws_display_alloc_diffusion(const lws_surface_info_t *ic, lws_surface_error_t **se)
{
size_t size, gsize = ic->greyscale ? sizeof(lws_greyscale_error_t) :
sizeof(lws_colour_error_t);
if (*se)
return 0;
/* defer creation of dlo's 2px-high dlo-width, 2 bytespp or 6 bytespp
* error diffusion buffer */
size = gsize * 2u * (unsigned int)(ic->wh_px[0].whole);
lwsl_info("%s: alloc'd %u for width %d\n", __func__, (unsigned int)size,
(int)ic->wh_px[0].whole);
se[0] = lws_zalloc(size, __func__);
if (!se[0])
return 1;
se[1] = (lws_surface_error_t *)(((uint8_t *)se[0]) +
((size_t)ic->wh_px[0].whole * gsize));
return 0;
}
static void
dist_err_grey(const lws_greyscale_error_t *in, lws_greyscale_error_t *out,
int sixteenths)
{
out->rgb[0] = (int16_t)(out->rgb[0] +
(int16_t)((sixteenths * in->rgb[0]) / 16));
}
static void
dist_err_col(const lws_colour_error_t *in, lws_colour_error_t *out,
int sixteenths)
{
out->rgb[0] = (int16_t)(out->rgb[0] +
(int16_t)((sixteenths * in->rgb[0]) / 16));
out->rgb[1] = (int16_t)(out->rgb[1] +
(int16_t)((sixteenths * in->rgb[1]) / 16));
out->rgb[2] = (int16_t)(out->rgb[2] +
(int16_t)((sixteenths * in->rgb[2]) / 16));
}
void
dist_err_floyd_steinberg_grey(int n, int width, lws_greyscale_error_t *gedl_this,
lws_greyscale_error_t *gedl_next)
{
if (n != width - 1) {
dist_err_grey(&gedl_this[n], &gedl_this[n + 1], 7);
dist_err_grey(&gedl_this[n], &gedl_next[n + 1], 1);
}
if (n)
dist_err_grey(&gedl_this[n], &gedl_next[n - 1], 3);
dist_err_grey(&gedl_this[n], &gedl_next[n], 5);
gedl_this[n].rgb[0] = 0;
}
void
dist_err_floyd_steinberg_col(int n, int width, lws_colour_error_t *edl_this,
lws_colour_error_t *edl_next)
{
if (n != width - 1) {
dist_err_col(&edl_this[n], &edl_this[n + 1], 7);
dist_err_col(&edl_this[n], &edl_next[n + 1], 1);
}
if (n)
dist_err_col(&edl_this[n], &edl_next[n - 1], 3);
dist_err_col(&edl_this[n], &edl_next[n], 5);
edl_this[n].rgb[0] = 0;
edl_this[n].rgb[1] = 0;
edl_this[n].rgb[2] = 0;
}
/*
* #include <stdio.h>
* #include <math.h>
*
* void
* main(void)
* {
* int n;
*
* for (n = 0; n < 256; n++) {
* double d = (double)n / 255.0;
*
* printf("0x%02X, ", (unsigned int)(pow(d, (2.2)) * 255));
* }
*
* }
*/
static const uint8_t gamma2_2[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04,
0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06,
0x06, 0x06, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08,
0x09, 0x09, 0x09, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B,
0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0E, 0x0E, 0x0F,
0x0F, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13,
0x13, 0x14, 0x15, 0x15, 0x16, 0x16, 0x17, 0x17,
0x18, 0x19, 0x19, 0x1A, 0x1B, 0x1B, 0x1C, 0x1D,
0x1D, 0x1E, 0x1F, 0x1F, 0x20, 0x21, 0x21, 0x22,
0x23, 0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28,
0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E,
0x3F, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4A, 0x4B, 0x4D, 0x4E, 0x4F, 0x50,
0x51, 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x5A,
0x5B, 0x5C, 0x5D, 0x5F, 0x60, 0x61, 0x63, 0x64,
0x65, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D, 0x6F,
0x70, 0x72, 0x73, 0x75, 0x76, 0x77, 0x79, 0x7A,
0x7C, 0x7D, 0x7F, 0x80, 0x82, 0x83, 0x85, 0x87,
0x88, 0x8A, 0x8B, 0x8D, 0x8E, 0x90, 0x92, 0x93,
0x95, 0x97, 0x98, 0x9A, 0x9C, 0x9D, 0x9F, 0xA1,
0xA2, 0xA4, 0xA6, 0xA8, 0xA9, 0xAB, 0xAD, 0xAF,
0xB0, 0xB2, 0xB4, 0xB6, 0xB8, 0xBA, 0xBB, 0xBD,
0xBF, 0xC1, 0xC3, 0xC5, 0xC7, 0xC9, 0xCB, 0xCD,
0xCF, 0xD1, 0xD3, 0xD5, 0xD7, 0xD9, 0xDB, 0xDD,
0xDF, 0xE1, 0xE3, 0xE5, 0xE7, 0xE9, 0xEB, 0xED,
0xEF, 0xF1, 0xF4, 0xF6, 0xF8, 0xFA, 0xFC, 0xFF
};
lws_display_palette_idx_t
lws_display_palettize_grey(const lws_surface_info_t *ic, lws_display_colour_t c,
lws_greyscale_error_t *ectx)
{
int best = 0x7fffffff, best_idx = 0, yd;
lws_colour_error_t da, d;
size_t n;
/* put the most desirable colour (adjusted for existing error) in d */
d.rgb[0] = (int)gamma2_2[LWSDC_R(c)];
da.rgb[0] = d.rgb[0] + ectx->rgb[0];
yd = da.rgb[0];
/*
* Choose a palette colour considering the error diffusion adjustments
*/
for (n = 0; n < ic->palette_depth; n++) {
lws_colour_error_t ea;
int sum, y;
y = LWSDC_ALPHA(ic->palette[n]);
ea.rgb[0] = (int16_t)((int)da.rgb[0] - (int)(LWSDC_R(ic->palette[n])));
sum = (ea.rgb[0] < 0 ? -ea.rgb[0] : ea.rgb[0]) +
((yd > y ? (yd - y) * 1 : (y - yd) * 1));
if (sum < best) {
best_idx = (int)n;
best = sum;
}
}
/* report the error between the unadjusted colour and what we chose */
ectx->rgb[0] = (int16_t)((int)da.rgb[0] - (int)(LWSDC_R(ic->palette[best_idx])));
return (lws_display_palette_idx_t)best_idx;
}
/*
* For error disffusion, it's better to use YUV and prioritize reducing error
* in Y (lumience)
*/
#if 0
static void
rgb_to_yuv(uint8_t *yuv, const uint8_t *rgb)
{
yuv[0] = 16 + ((257 * rgb[0]) / 1000) + ((504 * rgb[1]) / 1000) +
((98 * rgb[2]) / 1000);
yuv[1] = 128 - ((148 * rgb[0]) / 1000) - ((291 * rgb[1]) / 1000) +
((439 * rgb[2]) / 1000);
yuv[2] = 128 + ((439 * rgb[0]) / 1000) - ((368 * rgb[1]) / 1000) -
((71 * rgb[2]) / 1000);
}
static void
yuv_to_rgb(uint8_t *rgb, const uint8_t *_yuv)
{
unsigned int yuv[3];
yuv[0] = _yuv[0] - 16;
yuv[1] = _yuv[1] - 128;
yuv[2] = _yuv[2] - 128;
rgb[0] = ((1164 * yuv[0]) / 1000) + ((1596 * yuv[2]) / 1000);
rgb[1] = ((1164 * yuv[0]) / 1090) - ((392 * yuv[1]) / 1000) -
((813 * yuv[2]) / 1000);
rgb[2] = ((1164 * yuv[0]) / 1000) + ((2017 * yuv[1]) / 1000);
}
#endif
lws_display_palette_idx_t
lws_display_palettize_col(const lws_surface_info_t *ic, lws_display_colour_t c,
lws_colour_error_t *ectx)
{
int best = 0x7fffffff, best_idx = 0, yd;
lws_colour_error_t da, d;
size_t n;
/* put the most desirable colour (adjusted for existing error) in d */
d.rgb[0] = (int)gamma2_2[LWSDC_R(c)];
da.rgb[0] = d.rgb[0] + ectx->rgb[0];
yd = da.rgb[0];
d.rgb[1] = (int)gamma2_2[LWSDC_G(c)];
d.rgb[2] = (int)gamma2_2[LWSDC_B(c)];
da.rgb[1] = d.rgb[1] + ectx->rgb[1];
da.rgb[2] = d.rgb[2] + ectx->rgb[2];
yd = RGB_TO_Y(da.rgb[0], da.rgb[1], da.rgb[2]);
/*
* Choose a palette colour considering the error diffusion adjustments
*/
for (n = 0; n < ic->palette_depth; n++) {
lws_colour_error_t ea;
int sum, y;
y = LWSDC_ALPHA(ic->palette[n]);
ea.rgb[0] = (int16_t)((int)da.rgb[0] - (int)(LWSDC_R(ic->palette[n])));
ea.rgb[1] = (int16_t)(da.rgb[1] - (int)(LWSDC_G(ic->palette[n])));
ea.rgb[2] = (int16_t)(da.rgb[2] - (int)(LWSDC_B(ic->palette[n])));
sum = (ea.rgb[0] < 0 ? -ea.rgb[0] : ea.rgb[0]) +
(ea.rgb[1] < 0 ? -ea.rgb[1] : ea.rgb[1]) +
(ea.rgb[2] < 0 ? -ea.rgb[2] : ea.rgb[2]) +
(yd > y ? (yd - y) * 1 : (y - yd) * 1);
if (sum < best) {
best_idx = (int)n;
best = sum;
}
}
/* report the error between the adjusted colour and what we chose */
ectx->rgb[0] = (int16_t)((int)da.rgb[0] - (int)(LWSDC_R(ic->palette[best_idx])));
ectx->rgb[1] = (int16_t)((int)da.rgb[1] - (int)(LWSDC_G(ic->palette[best_idx])));
ectx->rgb[2] = (int16_t)((int)da.rgb[2] - (int)(LWSDC_B(ic->palette[best_idx])));
return (lws_display_palette_idx_t)best_idx;
}

View file

@ -46,9 +46,9 @@ static uint8_t ssd1306_128x64_init[] = {
};
int
lws_display_ssd1306_i2c_init(const struct lws_display *disp)
lws_display_ssd1306_i2c_init(lws_display_state_t *lds)
{
const lws_display_ssd1306_t *si = (const lws_display_ssd1306_t *)disp;
const lws_display_ssd1306_t *si = (const lws_display_ssd1306_t *)lds->disp;
si->i2c->init(si->i2c);
@ -72,9 +72,9 @@ lws_display_ssd1306_i2c_init(const struct lws_display *disp)
}
int
lws_display_ssd1306_i2c_contrast(const struct lws_display *disp, uint8_t b)
lws_display_ssd1306_i2c_contrast(lws_display_state_t *lds, uint8_t b)
{
const lws_display_ssd1306_t *si = (const lws_display_ssd1306_t *)disp;
const lws_display_ssd1306_t *si = (const lws_display_ssd1306_t *)lds->disp;
uint8_t ba[2];
ba[0] = SSD1306_SETCONTRAST;
@ -85,11 +85,11 @@ lws_display_ssd1306_i2c_contrast(const struct lws_display *disp, uint8_t b)
}
int
lws_display_ssd1306_i2c_blit(const struct lws_display *disp, const uint8_t *src,
lws_display_scalar x, lws_display_scalar y,
lws_display_scalar w, lws_display_scalar h)
lws_display_ssd1306_i2c_blit(lws_display_state_t *lds, const uint8_t *src,
lws_box_t *box)
{
const lws_display_ssd1306_t *si = (const lws_display_ssd1306_t *)disp;
const lws_display_ssd1306_t *si = (const lws_display_ssd1306_t *)lds->disp;
lws_display_list_coord_t y = box->y.whole, h = box->h.whole;
uint8_t ba[6];
int n, m;
@ -102,8 +102,8 @@ lws_display_ssd1306_i2c_blit(const struct lws_display *disp, const uint8_t *src,
h = 8;
ba[0] = SSD1306_COLUMNADDR;
ba[1] = x;
ba[2] = x + w - 1;
ba[1] = box->x.whole;
ba[2] = box->x.whole + box->w.whole - 1;
ba[3] = SSD1306_PAGEADDR;
ba[4] = y / 8;
ba[5] = ba[4] + (h / 8) - 1;
@ -114,12 +114,12 @@ lws_display_ssd1306_i2c_blit(const struct lws_display *disp, const uint8_t *src,
return 1;
}
for (n = 0; n < (w * h) / 8;) {
for (n = 0; n < (box->w.whole * h) / 8;) {
lws_bb_i2c_start(si->i2c);
lws_bb_i2c_write(si->i2c, si->i2c7_address << 1);
lws_bb_i2c_write(si->i2c, SSD1306_SETSTARTLINE | y);
for (m = 0; m < w; m++)
for (m = 0; m < box->w.whole; m++)
lws_bb_i2c_write(si->i2c, src[n++]);
lws_bb_i2c_stop(si->i2c);
@ -130,13 +130,13 @@ lws_display_ssd1306_i2c_blit(const struct lws_display *disp, const uint8_t *src,
}
int
lws_display_ssd1306_i2c_power(const struct lws_display *disp, int state)
lws_display_ssd1306_i2c_power(lws_display_state_t *lds, int state)
{
const lws_display_ssd1306_t *si = (const lws_display_ssd1306_t *)disp;
const lws_display_ssd1306_t *si = (const lws_display_ssd1306_t *)lds->disp;
if (!state)
return lws_i2c_command(si->i2c, si->i2c7_address,
SSD1306_DISPLAYOFF | !!state);
return lws_display_ssd1306_i2c_init(disp);
return lws_display_ssd1306_i2c_init(lds);
}

View file

@ -1,7 +1,7 @@
/*
* devices for ESP32 C3 dev board
*
* Written in 2010-2021 by Andy Green <andy@warmcat.com>
* Written in 2010-2022 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
@ -61,8 +61,10 @@ static const lws_pwm_ops_t pwm_ops = {
static const lws_display_ssd1306_t disp = {
.disp = {
lws_display_ssd1306_ops,
.w = 128,
.h = 64
.ic = {
.wh_px = { { 128,0 }, { 64,0 } },
.wh_mm = { { 22,00000000 }, { 10,00000000 } },
},
},
.i2c = (lws_i2c_ops_t *)&li2c,
.gpio = &lws_gpio_plat,

View file

@ -1,7 +1,7 @@
/*
* devices for ESP32 Heltec WB32
*
* Written in 2010-2020 by Andy Green <andy@warmcat.com>
* Written in 2010-2022 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
@ -81,8 +81,10 @@ static const lws_pwm_ops_t pwm_ops = {
static const lws_display_ssd1306_t disp = {
.disp = {
lws_display_ssd1306_ops,
.w = 128,
.h = 64
.ic = {
.wh_px = { { 128,0 }, { 64,0 } },
.wh_mm = { { 22,00000000 }, { 10,00000000 } },
},
},
.i2c = (lws_i2c_ops_t *)&li2c,
.gpio = &lws_gpio_plat,

View file

@ -1,7 +1,7 @@
/*
* lws-minimal-esp32
*
* Written in 2010-2020 by Andy Green <andy@warmcat.com>
* Written in 2010-2022 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
@ -153,6 +153,7 @@ void
app_main(void)
{
struct lws_context_creation_info *info;
lws_box_t box = { {0,0}, {0,0}, {128,0}, {64,0} };
lws_set_log_level(1024 | 15, NULL);
@ -196,7 +197,7 @@ app_main(void)
/* put the logo on the OLED display */
lds.disp->blit(lds.disp, img, 0, 0, 128, 64);
lds.disp->blit(&lds, img, &box);
lws_display_state_active(&lds);
/* the lws event loop */

View file

@ -1,7 +1,7 @@
/*
* devices for ESP WROVER KIT
*
* Written in 2010-2020 by Andy Green <andy@warmcat.com>
* Written in 2010-2022 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
@ -143,8 +143,10 @@ static const lws_display_ili9341_t disp = {
.bl_dim = &lws_pwmseq_static_half,
.bl_transition = &lws_pwmseq_linear_wipe,
.bl_index = 3,
.w = 320,
.h = 240,
.ic = {
.wh_px = { { 320,0 }, { 240,0 } },
.wh_mm = { { 64,00000000 }, { 48,00000000 } },
},
.latency_wake_ms = 150,
},
.spi = (lws_spi_ops_t *)&lbspi,

View file

@ -1,7 +1,7 @@
/*
* lws-minimal-esp32
*
* Written in 2010-2020 by Andy Green <andy@warmcat.com>
* Written in 2010-2022 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
@ -116,7 +116,7 @@ myss_state(void *userobj, void *sh, lws_ss_constate_t state,
switch (state) {
case LWSSSCS_CREATING:
lws_ss_client_connect(m->ss);
return lws_ss_client_connect(m->ss);
break;
default:
break;
@ -183,6 +183,7 @@ void
app_main(void)
{
struct lws_context_creation_info *info;
lws_box_t box = { {0,0}, {0,0}, {320,0}, {240,0} };
lws_set_log_level(1024 | 15, NULL);
@ -231,7 +232,7 @@ app_main(void)
/* put the cat picture up there and enable the backlight */
lds.disp->blit(lds.disp, logo, 0, 0, 320, 240);
lds.disp->blit(&lds, logo, &box);
lws_display_state_active(&lds);
/* the lws event loop */