From fb1611c0ca99d9e609057c46507be2af8389bb7b Mon Sep 17 00:00:00 2001 From: Anson Bridges Date: Tue, 17 Feb 2026 11:37:50 -0800 Subject: firmware coad --- firmware/rf test/Core/Src/sharpmem.c | 160 +++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 firmware/rf test/Core/Src/sharpmem.c (limited to 'firmware/rf test/Core/Src/sharpmem.c') diff --git a/firmware/rf test/Core/Src/sharpmem.c b/firmware/rf test/Core/Src/sharpmem.c new file mode 100644 index 0000000..0117921 --- /dev/null +++ b/firmware/rf test/Core/Src/sharpmem.c @@ -0,0 +1,160 @@ +#include "sharpmem.h" +#include "fonts.h" + +void SHARPMEM_TOGGLEVCOM(SharpMemDisplay_t *display) { + display->_sharpmem_vcom = display->_sharpmem_vcom ? 0x00 : SHARPMEM_BIT_VCOM; +} + +void SHARPMEM_draw_pixel(SharpMemDisplay_t *display, uint16_t x, uint16_t y, bool black) { + if ((x >= display->width) || (y >= display->height)) + return; + + if (black) { + display->_buffer[(y * display->width + x) / 8] |= (0x1 << (x & 7)); //potentially expensive when run many times, use lookup from adafruit lib + } else { + display->_buffer[(y * display->width + x) / 8] &= ~(0x1 << (x & 7)); + } +} + +void SHARPMEM_draw_line(SharpMemDisplay_t *display, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool black, uint8_t thickness) { + +} + +void SHARPMEM_draw_circle(SharpMemDisplay_t *display, uint16_t x, uint16_t y, uint8_t r, bool filled) { + +} + +void SHARPMEM_draw_rect(SharpMemDisplay_t *display, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool filled) { + +} + +void SHARPMEM_write(SharpMemDisplay_t *display, char *text, uint8_t font_index, uint16_t x0, uint16_t y0, bool inverse, bool force_bg) { + /*uint8_t mask = 0xFF; + uint8_t a1, a2, b; + if(font_index > NUMBER_OF_FONTS) return; + bitmap_font_t *font = fonts[font_index]; + + for (uint8_t ci = 0; ci < strlen(text); ci++){ + uint16_t base_index = font->lookup[(uint8_t)text[ci]]; + uint8_t offset = (x0 + (ci)*font->char_w) % 8; + + for (uint8_t y = 0; y < font->char_h; y++) { + if(y+y0 > display->height) return; + + uint8_t start_byte = (x0 + ci*font->char_w)/8 + (y0+y)*display->width/8; + + if((x0 + ci*font->char_w % 8)) + memcpy(display->_buffer + ((y+y0)*(display->width)/8) + x0/8 + ci*font->char_w/8 , font->font_bytes + base_index*font->bytes_per_char + y*font->bytes_per_row , font->bytes_per_row); + else { + uint8_t charbase = base_index*font->bytes_per_char + y*font->bytes_per_row; + bool single_ended_last_byte = (offset + font->char_w - 1) / 8 > (bytes_per_row-1); + uint8_t buffer_bytes = font->bytes_per_row + ( single_ended_last_byte ? 1 : 0 ); + for(uint8_t b_i = 0; b_i < buffer_bytes; b_i++) { + b = display->_buffer[start_byte + b_i]; + a2 = font->font_bytes[ charbase + b_i ] >> offset; + if(b_i == 0) { + b = ((mask >> offset) & a2) + ( (mask << (8-offset)) & b ); + } else if (b_i != (buffer_bytes-1 + !single_ended_last_byte)) { + a1 = font->font_bytes[ charbase + b_i - 1 ] << (8-offset); + if (!single_ended_last_byte) { + uint8_t remainder = (offset + font->char_w) % 8; + b = ( (a1 + a2) & (mask << (8-remainder)) ) + ((mask >> remainder) & b); + } + else b = a1 + a2; + } else { + a1 = font->font_bytes[ charbase + b_i - 1 ] << (8-offset); + uint8_t remainder = (offset + font->char_w) % 8; + b = ((mask << (8-remainder)) & a1) + ( (mask >> remainder) & b ); + } + display->_buffer[start_byte + b_i] = b; + } + start_byte += font->bytes_per_char; + end_byte += font->bytes_per_char; + } + } + }*/ + + // potentially inefficient but simplest algorithm involving reading and writing every single pixel + if(font_index > NUMBER_OF_FONTS) return; + bitmap_font_t *font = fonts[font_index]; + + for (uint8_t ci = 0; ci < strlen(text); ci++){ + uint16_t base_index = font->lookup[(uint8_t)text[ci]]; + + for (uint16_t y = 0; y < font->char_h; y++) { + uint16_t charbase = base_index*font->bytes_per_char + y*font->bytes_per_row; + for (uint16_t x = 0; x < font->char_w; x++) { + bool white = ( (font->font_bytes[charbase + x/8] & (0x1 << (x%8)) ) == 0 ); + if (!force_bg && white) continue; + if (inverse) white = !white; + SHARPMEM_draw_pixel(display, x0+ci*font->char_w+x, y0+y, !white); + } + } + } +} + +uint8_t SHARPMEM_get_pixel(SharpMemDisplay_t *display, uint16_t x, uint16_t y) { + if ((x >= display->width) || (y >= display->height)) + return 1; //1 = empty + +} + +void SHARPMEM_clear_display(SharpMemDisplay_t *display) { + HAL_GPIO_WritePin(display->lcdmode_pin_bank, display->lcdmode_pin, GPIO_PIN_RESET); // set lcdmode pin to low for manual vcom control + + memset(display->_buffer, 0xff, (display->width * display->height) / 8); + + // Send the clear screen command rather than doing a HW refresh (quicker) + + uint8_t clear_data[2] = {(uint8_t)(display->_sharpmem_vcom | SHARPMEM_BIT_CLEAR), + 0x00}; + + HAL_GPIO_WritePin(display->cs_pin_bank, display->cs_pin, GPIO_PIN_SET); + HAL_SPI_Transmit(display->spidev, clear_data, 2, 16); + HAL_GPIO_WritePin(display->cs_pin_bank, display->cs_pin, GPIO_PIN_RESET); + + SHARPMEM_TOGGLEVCOM(display); + HAL_GPIO_WritePin(display->lcdmode_pin_bank, display->lcdmode_pin, GPIO_PIN_SET); // set lcdmode pin to high for 1Hz external vcom signal +} + +void SHARPMEM_refresh_display(SharpMemDisplay_t *display) { + HAL_GPIO_WritePin(display->lcdmode_pin_bank, display->lcdmode_pin, GPIO_PIN_RESET); // set lcdmode pin to low for manual vcom control + uint16_t i, currentline; + + //spidev->beginTransaction(); + // Send the write command + HAL_GPIO_WritePin(display->cs_pin_bank, display->cs_pin, GPIO_PIN_SET); + uint8_t write_data[1] = {0x00 | SHARPMEM_BIT_WRITECMD}; + HAL_SPI_Transmit(display->spidev, write_data, 1, 100); + SHARPMEM_TOGGLEVCOM(display); + + uint8_t bytes_per_line = display->width / 8; + uint16_t totalbytes = (display->width * display->height) / 8; + + for (i = 0; i < totalbytes; i += bytes_per_line) { + uint8_t line[bytes_per_line + 2]; + + // Send address byte + currentline = ((i + 1) / (display->width / 8)) + 1; + line[0] = currentline; + // copy over this line + memcpy(line + 1, display->_buffer + i, bytes_per_line); + // Send end of line + line[bytes_per_line + 1] = 0x00; + // send it! + HAL_SPI_Transmit(display->spidev, line, bytes_per_line + 2, 16); + } + + // Send another trailing 8 bits for the last line + HAL_SPI_Transmit(display->spidev, (0x00), 1, 100); + HAL_GPIO_WritePin(display->cs_pin_bank, display->cs_pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(display->lcdmode_pin_bank, display->lcdmode_pin, GPIO_PIN_SET); // set lcdmode pin to high for 1Hz external vcom signal +} + +void SHARPMEM_clear_display_buffer(SharpMemDisplay_t *display) { + memset(display->_buffer, 0xff, (display->width * display->height) / 8); +} + +uint8_t *SHARPMEM_get_buffer(SharpMemDisplay_t *display) { + +} -- cgit v1.2.3