From e4a483602de694d977c29539f6b25945fb9789e0 Mon Sep 17 00:00:00 2001 From: Jonas Grosse-Holz Date: Thu, 22 Feb 2024 09:31:01 +0100 Subject: [PATCH] implement display rotation --- ssd1306.c | 24 ++++++++++++++++++++++++ ssd1306.h | 20 ++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/ssd1306.c b/ssd1306.c index 1ce7d9d..35fbe39 100644 --- a/ssd1306.c +++ b/ssd1306.c @@ -63,6 +63,7 @@ bool ssd1306_init(ssd1306_t *p, uint16_t width, uint16_t height, uint8_t address p->height=height; p->pages=height/8; p->address=address; + p->rotation=ROT_0; p->i2c_i=i2c_instance; @@ -140,13 +141,36 @@ inline void ssd1306_clear(ssd1306_t *p) { memset(p->buffer, 0, p->bufsize); } +inline void ssd1306_set_rotation(ssd1306_t *p, rotation_t rotation) { + p->rotation = rotation; +} + +void rotate_coordinates(ssd1306_t *p, uint32_t* x, uint32_t* y) { + uint32_t tmp_x = *x; + if(p->rotation == ROT_90) { + *x = p->height - *y - 1; + *y = tmp_x; + } else if(p->rotation == ROT_180) { + *x = p->width - *x - 1; + *y = p->height - *y - 1; + } else if(p->rotation == ROT_270) { + *x = *y; + *y = p->width - tmp_x - 1; + } + // Keep coordinates as is for ROT_0 +} + void ssd1306_clear_pixel(ssd1306_t *p, uint32_t x, uint32_t y) { + rotate_coordinates(p, &x, &y); + if(x>=p->width || y>=p->height) return; p->buffer[x+p->width*(y>>3)]&=~(0x1<<(y&0x07)); } void ssd1306_draw_pixel(ssd1306_t *p, uint32_t x, uint32_t y) { + rotate_coordinates(p, &x, &y); + if(x>=p->width || y>=p->height) return; p->buffer[x+p->width*(y>>3)]|=0x1<<(y&0x07); // y>>3==y/8 && y&0x7==y%8 diff --git a/ssd1306.h b/ssd1306.h index 138cef3..ef70cb2 100644 --- a/ssd1306.h +++ b/ssd1306.h @@ -56,6 +56,17 @@ typedef enum { SET_CHARGE_PUMP = 0x8D } ssd1306_command_t; +/** + * @brief defines rotations/orientations + */ +typedef enum { + ROT_0 = 0, + ROT_90 = 1, + ROT_180 = 2, + ROT_270 = 3, +} rotation_t; + + /** * @brief holds the configuration */ @@ -68,6 +79,7 @@ typedef struct { bool external_vcc; /**< whether display uses external vcc */ uint8_t *buffer; /**< display buffer */ size_t bufsize; /**< buffer size */ + rotation_t rotation; /**< rotation of display */ } ssd1306_t; /** @@ -143,6 +155,14 @@ void ssd1306_show(ssd1306_t *p); */ void ssd1306_clear(ssd1306_t *p); +/** + @brief sets the rotation for + + @param[in] p : instance of display + @param[in] rotation : rotation angle +*/ +void ssd1306_set_rotation(ssd1306_t *p, rotation_t rotation); + /** @brief clear pixel on buffer