From 6db323c570205f8ba0114435b2bda3f1a7660c40 Mon Sep 17 00:00:00 2001 From: Fluffy-Bean Date: Mon, 23 Jun 2025 22:51:08 +0100 Subject: [PATCH] Fix screen refresh --- lib_sharp.c | 107 ++++++++++++++++++++++++++++++++-------------------- lib_sharp.h | 32 +++++++++------- 2 files changed, 85 insertions(+), 54 deletions(-) diff --git a/lib_sharp.c b/lib_sharp.c index 2b3633f..6b9a796 100644 --- a/lib_sharp.c +++ b/lib_sharp.c @@ -3,7 +3,19 @@ #include #include "hardware/gpio.h" #include "hardware/spi.h" -#include "lib_sharp.h" +#include "sharp_display.h" + +uint8_t mirror_bytes(uint8_t byte) +{ + uint8_t res = 0; + + for (uint8_t x=0; x < 8; ++x) { + res = (res << 1) | (byte & 1); + byte >>= 1; + } + + return res; +} sharp_display_t sharp_display_new(uint16_t width, uint16_t height, spi_inst_t * spi, uint8_t cs) { @@ -23,73 +35,86 @@ sharp_display_t sharp_display_new(uint16_t width, uint16_t height, spi_inst_t * bool sharp_display_error(sharp_display_t * display) { - return (display == NULL || display->framebuffer == NULL); + return display == NULL || display->framebuffer == NULL; } void sharp_display_refresh_screen(sharp_display_t * display) { - gpio_put(display->cs, true); + uint8_t spi_byte; + + gpio_put(display->cs, 1); sharp_display_toggle_vcom(display); - // These are sizes without the current line and end of line data uint16_t line_size = display->width / 8; - uint16_t frame_size = (display->width * display->height) / 8; - uint16_t buff_size = 1 + display->height * (1 + (display->width / 8) + 1) + 1; - uint8_t buff[buff_size]; + spi_byte = display->vcom | CMD_WRITE; + spi_write_blocking(display->spi, &spi_byte, 1); - uint16_t buff_offset = 0; - - buff[buff_offset] = display->vcom | CMD_WRITE; - buff_offset += 1; - - for (int i = 0; i < frame_size; i += line_size) + for (size_t i = 0; i < display->height; i += 1) { // Current line - buff[buff_offset] = ((i + 1) / (display->width / 8)) + 1; - buff_offset += 1; + spi_byte = mirror_bytes(i + 1); + spi_write_blocking(display->spi, &spi_byte, 1); // Line data - memcpy(buff + buff_offset, display->framebuffer + i, line_size); - buff_offset += line_size; + for (size_t j = 0; j < line_size; j += 1) + { + spi_byte = mirror_bytes(display->framebuffer[(line_size * i) + j]); + spi_write_blocking(display->spi, &spi_byte, 1); + } // End of line - buff[buff_offset] = 0x00; - buff_offset += 1; + spi_byte = 0b00000000; + spi_write_blocking(display->spi, &spi_byte, 1); } - // End of transition - buff[buff_offset] = 0x00; - buff_offset += 1; + // End of transmission + spi_byte = 0b00000000; + spi_write_blocking(display->spi, &spi_byte, 1); - if (buff_size != buff_offset) - { - printf("Sussy buffer size offset\n"); - } - - spi_write_blocking(display->spi, buff, buff_offset); - gpio_put(display->cs, false); + gpio_put(display->cs, 0); } void sharp_display_clear_screen(sharp_display_t * display) { - sharp_display_clear_buffer(display); - gpio_put(display->cs, true); + gpio_put(display->cs, 1); + sharp_display_toggle_vcom(display); - uint8_t buff[2] = {display->vcom | CMD_CLEAR, 0x00}; + memset(display->framebuffer, 0b00000000, (display->width * display->height) / 8); + + uint8_t buff[2]; + buff[0] = display->vcom | CMD_CLEAR; + buff[1] = 0b00000000; spi_write_blocking(display->spi, buff, 2); - - sharp_display_toggle_vcom(display); - gpio_put(display->cs, false); -} - -void sharp_display_clear_buffer(sharp_display_t * display) -{ - memset(display->framebuffer, 0, display->width * display->height / 8); + gpio_put(display->cs, 0); } void sharp_display_toggle_vcom(sharp_display_t * display) { - display->vcom = display->vcom ? 0x00 : CMD_VCOM; + display->vcom ^= CMD_VCOM; +} + +void sharp_display_draw_pixel(sharp_display_t *display, uint16_t x, uint16_t y, sharp_color_t color) +{ + if (x < 0 || x >= display->width || y < 0 || y >= display->height) return; + + uint16_t pixel_in_byte = x % 8; + uint16_t column_in_bytes = (x - pixel_in_byte) / 8; + uint8_t mask = 0b000000001 << pixel_in_byte; + + if (color == WHITE) { + display->framebuffer[y*(display->width / 8) + column_in_bytes] |= ~mask; + } else { + display->framebuffer[y*(display->width / 8) + column_in_bytes] &= ~mask; + } +} + +void sharp_display_fill_screen(sharp_display_t * display, sharp_color_t color) +{ + if (color == WHITE) { + memset(display->framebuffer, 0b11111111, (display->width * display->height) / 8); + } else { + memset(display->framebuffer, 0b00000000, (display->width * display->height) / 8); + } } diff --git a/lib_sharp.h b/lib_sharp.h index 6c45c2f..e01d5f6 100644 --- a/lib_sharp.h +++ b/lib_sharp.h @@ -1,30 +1,36 @@ -#ifndef LIB_SHARP_H -#define LIB_SHARP_H +#ifndef SHARP_DISPLAY +#define SHARP_DISPLAY #include "hardware/spi.h" -#define CMD_WRITE 0x80 -#define CMD_CLEAR 0x20 -#define CMD_VCOM 0x40 +// in LSB format +#define CMD_WRITE 0b10000000 +#define CMD_VCOM 0b01000000 +#define CMD_CLEAR 0b00100000 -#define SWAP(a, b) { a ^= b; b ^= a; a ^= b; } +typedef enum sharp_color +{ + WHITE = 0, + BLACK = 1, +} +sharp_color_t; -typedef struct sharp_display { +typedef struct sharp_display +{ uint16_t width, height; uint8_t cs; uint8_t vcom; uint8_t * framebuffer; spi_inst_t * spi; -} sharp_display_t; +} +sharp_display_t; sharp_display_t sharp_display_new(uint16_t width, uint16_t height, spi_inst_t * spi, uint8_t cs); bool sharp_display_error(sharp_display_t * display); void sharp_display_refresh_screen(sharp_display_t * display); void sharp_display_clear_screen(sharp_display_t * display); -void sharp_display_clear_buffer(sharp_display_t * display); void sharp_display_toggle_vcom(sharp_display_t * display); +void sharp_display_draw_pixel(sharp_display_t *display, uint16_t x, uint16_t y, sharp_color_t color); +void sharp_display_fill_screen(sharp_display_t * display, sharp_color_t color); -void sharp_display_draw_pixel(sharp_display_t *display, int x, int y, bool color); -void sharp_display_draw_circle(sharp_display_t *display, int x0, int y0, int radius, bool color); - -#endif //LIB_SHARP_H +#endif