diff --git a/Makefile b/Makefile index b6cf60c..2f32faf 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,11 @@ # - ST7735R # - ST7789 # - ILI9341 +# and also, for larger TTL displays: +# - RA8875 + +# Set to 1 for RA8875, 0 for other drivers +DRIVER = 0 # Display dimensions DISPLAY_WIDTH = 320 @@ -26,8 +31,8 @@ VFLIP = 1 MAIN = avrtft.c -SRC = bitmaps.c bmp.c cmd.c display.c emojis.c i2c.c paint.c tft.c touch.c \ - font.c spi.c hack.c usart.c sdcard.c +SRC = bitmaps.c bmp.c cmd.c colorspace.c display.c emojis.c font.c \ + hack.c i2c.c paint.c ra8875.c sdcard.c spi.c tft.c touch.c usart.c CC = avr-gcc OBJCOPY = avr-objcopy @@ -36,6 +41,7 @@ AVRDUDE = avrdude CFLAGS = -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -DBAUD=$(BAUD) +CFLAGS += -DDRIVER=$(DRIVER) CFLAGS += -DDISPLAY_WIDTH=$(DISPLAY_WIDTH) -DDISPLAY_HEIGHT=$(DISPLAY_HEIGHT) CFLAGS += -DINVERT=$(INVERT) -DBGR=$(BGR) -DHFLIP=$(HFLIP) -DVFLIP=$(VFLIP) CFLAGS += -O2 -I. @@ -45,7 +51,7 @@ CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -mrelax CFLAGS += -std=gnu99 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523 -CFLAGS += --param=min-pagesize=0 +# CFLAGS += --param=min-pagesize=0 TARGET = $(strip $(basename $(MAIN))) SRC += $(TARGET).c @@ -53,9 +59,9 @@ OBJ = $(SRC:.c=.o) OBJ = $(SRC:.S=.o) -$(TARGET).elf: bitmaps.h bmp.h cmd.h display.h emojis.h i2c.h paint.h tft.h \ - touch.h font.h pins.h spi.h types.h hack.h usart.h utils.h \ - sdcard.h Makefile +$(TARGET).elf: bitmaps.h bmp.h cmd.h colorspace.h display.h emojis.h font.h \ + hack.h i2c.h paint.h ra8875.h sdcard.h spi.h tft.h touch.h \ + pins.h types.h usart.h utils.h Makefile all: $(TARGET).hex @@ -73,7 +79,7 @@ $(OBJDUMP) -S $< > $@ size: $(TARGET).elf - $(AVRSIZE) -G $(TARGET).elf + $(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf clean: rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \ diff --git a/README.md b/README.md index cbd8849..ec86513 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,12 @@ * [Adafruit 2.0" Color IPS TFT 320x240 ST7789](https://www.adafruit.com/product/4311) * [Adafruit 2.8" Color TFT LCD with Cap Touch 320x240 ILI9341](https://www.adafruit.com/product/2090) +Additionally, there is some support for larger (up to 800x480) TTL displays, for example the +[Adadruit 7.0" 40-pin TFT Display - 800x480 with Touchscreen](https://www.adafruit.com/product/2354), +with the RA8875 controller like the +[RA8875 Driver Board for 40-pin TFT Touch Displays - 800x480 Max](https://www.adafruit.com/product/1590) +including touch support. + Currently implemented features: * Mostly complete UTF-8 set (code points U+0000 to U+00FF) of Hack font @@ -19,7 +25,7 @@ * Upload BMP images via USART (16-Bit 5/6/5 RGB) * Basic SD card support: read and write blocks of 512 bytes * Read BMP images from SD card (raw) -* Process touch events (FT6206) +* Process touch events (FT6206, RA8875) * Very basic paint application * Logging via USART @@ -84,3 +90,13 @@ supporting touch with reliable usability. ![IMG_20240103_134738](https://github.com/gitdode/avrtft/assets/11530253/5e9947cc-e236-49e7-a06b-1dbfffa304b7) + +## Larger (up to 800x480) TTL displays + +If at all possible, it probably is quite a challenge to drive such a 40-pin display with a 28-pin +MCU like the ATmega238P, but it is easy with the RA8875 driver, offering support for a touch screen +as well. Here it is combined with the [SparkFun Level Shifting microSD Breakout](https://www.sparkfun.com/products/13743) +to read images from an SD card, advancing to the next image by touching the screen. + +![IMG_20240704_214710](https://github.com/gitdode/avrtft/assets/11530253/a09af16d-0dcf-4c1f-a8d6-0fb965b75fda) + diff --git a/avrtft.c b/avrtft.c index c1e49d5..14ab67b 100644 --- a/avrtft.c +++ b/avrtft.c @@ -25,6 +25,7 @@ #include "usart.h" #include "spi.h" #include "tft.h" +#include "ra8875.h" #include "cmd.h" #include "bitmaps.h" #include "display.h" @@ -36,10 +37,10 @@ bool sdcard = false; -static volatile bool touch = false; +static volatile bool int0 = false; ISR(INT0_vect) { - touch = true; + int0 = true; } /** @@ -64,20 +65,24 @@ DDR_DSPI |= (1 << PIN_DCS); DDR_DSPI |= (1 << PIN_DC); DDR_DISP |= (1 << PIN_RST); + + // set display busy pin as input pin (default) + DDR_DISP &= ~(1 << PIN_BUSY); // drive SPI and display output pins high PORT_SDC |= (1 << PIN_SDCS); PORT_DSPI |= (1 << PIN_DCS); PORT_DSPI |= (1 << PIN_DC); PORT_DISP |= (1 << PIN_RST); + + // pull display busy pin high + PORT_DISP |= (1 << PIN_BUSY); } /** * Enables SPI master mode. */ static void initSPI(void) { - // min speed for a cool visual effect :-) - // SPCR |= (1 << SPR1) | (1 << SPR0); SPCR |= (1 << MSTR); SPCR |= (1 << SPE); } @@ -102,35 +107,31 @@ } int main(void) { - initUSART(); initPins(); initSPI(); initI2C(); - - // enable global interrupts - sei(); - - _delay_ms(1000); - - // may need to decrease SPI bus clock frequency for initialization sdcard = initSDCard(); initDisplay(); initTouchInt(); + // enable global interrupts + sei(); + // ignore initial touch interrupt _delay_ms(1); - touch = false; + int0 = false; // do something at the start if (!sdcard) { initPaint(); + // hackDemo(); + // demoDisplay(); } - // hackDemo(); while (true) { - if (touch) { - touch = false; + if (int0 && isTouch()) { + int0 = false; Point point = {0}; // memset(&point, 0, sizeof (Point)); uint8_t event = readTouch(&point); @@ -139,6 +140,8 @@ } else { paintEvent(event, &point); } + + clearTouch(); } if (isStreamingData()) { diff --git a/bitmaps.c b/bitmaps.c index 6956228..e5d53b3 100644 --- a/bitmaps.c +++ b/bitmaps.c @@ -5,10 +5,7 @@ * Created on 6. November 2023, 18:45 */ -#include #include "bitmaps.h" -#include "tft.h" -#include "utils.h" const __flash uint8_t FREE_DATA[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, diff --git a/bitmaps.h b/bitmaps.h index 29f5cbe..11ec3d9 100644 --- a/bitmaps.h +++ b/bitmaps.h @@ -8,8 +8,11 @@ #ifndef BITMAPS_H #define BITMAPS_H +#include #include #include "types.h" +#include "colorspace.h" +#include "utils.h" #define FREE 0 #define LINE 1 diff --git a/bmp.c b/bmp.c index 02725db..997c3a9 100644 --- a/bmp.c +++ b/bmp.c @@ -13,8 +13,8 @@ static bool error = false; -static row_t row = 0; -static col_t col = 0; +static x_t x = 0; +static y_t y = 0; static uint8_t buf[BUF_SIZE]; static uint32_t offset = 0; @@ -35,8 +35,8 @@ */ static void reset(void) { error = false; - row = 0; - col = 0; + y = 0; + x = 0; offset = 0; pixelStart = -1; pixelEnd = -1; @@ -73,10 +73,10 @@ } } -void prepareBMP(row_t srow, col_t scol) { +void prepareBMP(x_t sx, y_t sy) { reset(); - row = srow; - col = scol; + x = sx; + y = sy; setStreamingData(true); } @@ -88,8 +88,8 @@ push(byte); if (offset == pixelStart) { - // do horizontal flip because pixel data in a BMP is bottom to top - setArea(row, col, bitmapWidth, bitmapHeight, true, false); + // do vertical flip because pixel data in a BMP is bottom to top + setArea(x, y, bitmapWidth, bitmapHeight, false, true); writeStart(); } else if (offset > pixelStart) { // TODO calculate number of pad bytes and discard them @@ -194,7 +194,8 @@ do { displayDes(); bool success = readSingleBlock(address++, block); - displaySel(); + // FIXME seems to break active window/cursor + writeRestart(); if (success) { for (uint16_t i = 0; i < SD_BLOCK_SIZE; i++) { status = streamBMP(block[i]); diff --git a/bmp.h b/bmp.h index 38d985a..1b4efe3 100644 --- a/bmp.h +++ b/bmp.h @@ -35,10 +35,10 @@ * Prepares to "stream" a BMP image via USART to the display, * with its upper left corner at the given coordinates. * - * @param row - * @param col + * @param x + * @param y */ -void prepareBMP(row_t row, col_t col); +void prepareBMP(x_t x, y_t y); /** * Does basic parsing of the BMP image (16-Bit 5/6/5 RGB) sent via USART and diff --git a/cats/cats.sh b/cats/cats.sh index 72bdbc3..fa7a87d 100755 --- a/cats/cats.sh +++ b/cats/cats.sh @@ -6,11 +6,11 @@ # clear the display all black and write some text in Hack font, and so on... echo "c 0" > /dev/ttyUSB0 sleep 1 -echo "t 20 12 Katzen... " > /dev/ttyUSB0 +echo "t 12 20 Katzen... " > /dev/ttyUSB0 sleep 1 -echo "t 56 44 Katzen... " > /dev/ttyUSB0 +echo "t 44 56 Katzen... " > /dev/ttyUSB0 sleep 1 -echo "t 92 80 Katzen! " > /dev/ttyUSB0 +echo "t 80 92 Katzen! " > /dev/ttyUSB0 sleep 1 diff --git a/cmd.c b/cmd.c index b784b48..5b75368 100644 --- a/cmd.c +++ b/cmd.c @@ -5,8 +5,6 @@ * Created on 18. April 2023, 21:18 */ -#include -#include #include "cmd.h" extern bool sdcard; @@ -24,43 +22,51 @@ } /** - * Writes one line of text to the given row and column. + * Writes one line of text to the given x and y coordinates. * @param data */ static void text(char *data) { strtok(data, " "); char *end; - row_t row = strtol(strtok(NULL, " "), &end, 10); - col_t col = strtol(strtok(NULL, " "), &end, 10); + x_t x = strtol(strtok(NULL, " "), &end, 10); + y_t y = strtol(strtok(NULL, " "), &end, 10); char *text = strtok(NULL, "\0"); const __flash Font *hack = &hackFont; - writeString(row, col, hack, text); + writeString(x, y, hack, text); } /** - * Writes the bitmap with the given index to the given row and column. + * Writes the bitmap with the given index to the given x and y coordinates. * @param data */ static void bitmap(char *data) { strtok(data, " "); char *end; - row_t row = strtol(strtok(NULL, " "), &end, 10); - col_t col = strtol(strtok(NULL, " "), &end, 10); + x_t x = strtol(strtok(NULL, " "), &end, 10); + y_t y = strtol(strtok(NULL, " "), &end, 10); uint8_t index = strtol(strtok(NULL, " "), &end, 10); - writeBitmap(row, col, index); + writeBitmap(x, y, index); } +/** + * Prepares for writing a BMP image to the given x and y coordinates. + * @param data + */ static void bmp(char *data) { strtok(data, " "); char *end; - row_t row = strtol(strtok(NULL, " "), &end, 10); - col_t col = strtol(strtok(NULL, " "), &end, 10); + x_t x = strtol(strtok(NULL, " "), &end, 10); + y_t y = strtol(strtok(NULL, " "), &end, 10); - prepareBMP(row, col); + prepareBMP(x, y); } +/** + * Reads a BMP image from SD Card starting at the given address. + * @param data + */ static void bmpSD(char *data) { strtok(data, " "); char *end; diff --git a/cmd.h b/cmd.h index 7e6c926..d31a11e 100644 --- a/cmd.h +++ b/cmd.h @@ -8,6 +8,8 @@ #ifndef CMD_H #define CMD_H +#include +#include #include "usart.h" #include "tft.h" #include "display.h" @@ -21,13 +23,13 @@ /** Clear frame buffer: 'c <0x0000 - 0xffff>'. */ #define CMD_CLEAR 'c' -/** Display one line of text: 't '. */ +/** Display one line of text: 't '. */ #define CMD_TEXT 't' -/** Display a bitmap: 'b '. */ +/** Display a bitmap: 'b '. */ #define CMD_BITMAP 'b' -/** Prepare "streaming" a .bmp: 'p '. */ +/** Prepare "streaming" a .bmp: 'p '. */ #define CMD_BMP 'p' /** Read a .bmp: from SD card: 's
'. */ diff --git a/colorspace.c b/colorspace.c new file mode 100644 index 0000000..1200878 --- /dev/null +++ b/colorspace.c @@ -0,0 +1,83 @@ +/* + * File: colorspace.c + * Author: torsten.roemer@luniks.net + * + * Created on 3. Juli 2024, 19:03 + */ + +#include "colorspace.h" + +/** + * Converts the given 8 pixel in 1-Bit monochrome to 16-Bit RGB (5/6/5) color + * stored in the given array of 16 bytes. + * + * @param grey 8 pixel in 1-Bit monochrome + * @param rgb 8 pixel in 16-Bit RGB (5/6/5) color + */ +static void mono1ToRGB16(uint8_t mono, uint8_t *rgb) { + for (uint8_t i = 0; i < 16; i++) { + rgb[i] = (mono & (1 << ((15 - i) >> 1))) ? 0x0 : 0xff; + } +} + +/* + * Converts the given two pixel in 4-Bit greyscale to 16-Bit RGB (5/6/5) color + * stored in the given array of four bytes. + * + * @param grey two pixel in 4-Bit greyscale + * @param rgb two pixel in 16-Bit RGB (5/6/5) color + */ +static void grey4ToRGB16(uint8_t grey, uint8_t *rgb) { + uint8_t grey4 = ((grey >> 4) & 1); + uint8_t grey0 = ((grey >> 0) & 1); + + rgb[0] = (grey & 0xf0); + rgb[0] |= (grey4 << 3); + rgb[0] |= (grey >> 5); + + rgb[1] = ((grey & 0xf0) << 3); + rgb[1] |= ((grey & 0xf0) >> 3); + rgb[1] |= (grey4 << 6) | (grey4 << 5) | (grey4 << 0); + + rgb[2] = (grey << 4); + rgb[2] |= (grey0 << 3); + rgb[2] |= ((grey & 0x0f) >> 1); + + rgb[3] = (grey << 7); + rgb[3] |= ((grey & 0x0f) << 1); + rgb[3] |= (grey0 << 6) | (grey0 << 5) | (grey0 << 0); +} + +void writeSpace(const __flash uint8_t *bitmap, + width_t width, height_t height, + space_t space) { + switch (space) { + case SPACE_MONO1: { + bytes_t bytes = width * height / 8; + for (uint16_t i = 0; i < bytes; i++) { + uint8_t rgb[16]; + mono1ToRGB16(bitmap[i], rgb); + for (uint8_t j = 0; j < 16; j++) { + transmit(rgb[j]); + } + } + }; break; + case SPACE_GREY4: { + bytes_t bytes = width * height / 2; + for (uint16_t i = 0; i < bytes; i++) { + uint8_t rgb[4]; + grey4ToRGB16(bitmap[i], rgb); + for (uint8_t j = 0; j < 4; j++) { + transmit(rgb[j]); + } + } + }; break; + default: { + // SPACE_RGB16 + bytes_t bytes = width * height * 2; + for (uint16_t i = 0; i < bytes; i++) { + transmit(bitmap[i]); + } + } + } +} \ No newline at end of file diff --git a/colorspace.h b/colorspace.h new file mode 100644 index 0000000..7d47e86 --- /dev/null +++ b/colorspace.h @@ -0,0 +1,34 @@ +/* + * File: colorspace.h + * Author: torsten.roemer@luniks.net + * + * Created on 3. Juli 2024, 19:02 + */ + +#ifndef COLORSPACE_H +#define COLORSPACE_H + +// TODO use enum? typedef? +#define SPACE_MONO1 1 +#define SPACE_GREY4 4 +#define SPACE_RGB16 16 + +#include +#include "types.h" +#include "spi.h" + +/** + * Helper to write image data to the display, converting from the given + * color space to that of the display. + * + * @param bitmap pointer to bitmap data in program memory + * @param width width of the bitmap in pixels + * @param height height of the bitmap in pixels + * @param space color space of the bitmap + */ +void writeSpace(const __flash uint8_t *bitmap, + width_t width, height_t height, + space_t space); + +#endif /* COLORSPACE_H */ + diff --git a/display.c b/display.c index 1e9ac51..d5e5dd0 100644 --- a/display.c +++ b/display.c @@ -5,52 +5,40 @@ * Created on 18. April 2023, 21:56 */ -#include -#include -#include -#include -#include #include "display.h" -#include "hack.h" -#include "bitmaps.h" -#include "emojis.h" -#include "spi.h" -#include "tft.h" -#include "usart.h" -#include "utils.h" void setFrame(uint16_t color) { fillArea(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, color); } -void drawRectangle(row_t row, col_t col, width_t width, height_t height, +void drawRectangle(x_t x, y_t y, width_t width, height_t height, uint8_t thickness, uint16_t color) { width -= thickness; height -= thickness; - fillArea(row, col, width, thickness, color); - fillArea(row, col + width, thickness, height, color); - fillArea(row + height, col, width + thickness, thickness, color); - fillArea(row, col, thickness, height, color); + fillArea(x, y, width, thickness, color); + fillArea(x + width, y, thickness, height, color); + fillArea(x, y + height, width + thickness, thickness, color); + fillArea(x, y, thickness, height, color); } -width_t writeBitmap(row_t row, col_t col, uint16_t index) { +width_t writeBitmap(x_t x, y_t y, uint16_t index) { const __flash Bitmap *bitmap = &bitmaps[index]; - setArea(row, col, bitmap->width, bitmap->height, false, false); + setArea(x, y, bitmap->width, bitmap->height, false, false); writeData(bitmap->bitmap, bitmap->width, bitmap->height, bitmap->space); return bitmap->width; } -width_t writeGlyph(row_t row, col_t col, const __flash Font *font, code_t code) { +width_t writeGlyph(x_t x, y_t y, const __flash Font *font, code_t code) { const __flash Glyph *glyph = getGlyphAddress(font, code); - setArea(row, col, glyph->width, font->height, false, false); + setArea(x, y, glyph->width, font->height, false, false); writeData(glyph->bitmap, glyph->width, font->height, font->space); return glyph->width; } -void writeString(row_t row, col_t col, const __flash Font *font, const char *string) { +void writeString(x_t x, y_t y, const __flash Font *font, const char *string) { uint8_t offset = 0; bool emoji = false; const __flash Font *emojis = &emojiFont; @@ -66,11 +54,11 @@ offset = 64; } else if (emoji) { code_t code = c; - col += writeGlyph(row, col, emojis, code); + x += writeGlyph(x, y, emojis, code); emoji = false; } else { code_t code = c + offset; - col += writeGlyph(row, col, font, code); + x += writeGlyph(x, y, font, code); offset = 0; } } @@ -80,7 +68,7 @@ setFrame(0xffff); const __flash Font *hack = &hackFont; for (uint8_t i = 0; i < length; i++) { - writeString(i * hack->height, 0, hack, lines[i]); + writeString(0, i * hack->height, hack, lines[i]); } } @@ -91,6 +79,6 @@ const __flash char *line = demoTextLines[i]; char buf[HACK_DEMO_LINE_SIZE]; strlcpy_P(buf, line, HACK_DEMO_LINE_SIZE - 1); - writeString(i * hack->height, 0, hack, buf); + writeString(0, i * hack->height, hack, buf); } } diff --git a/display.h b/display.h index 9bcf80c..078b26f 100644 --- a/display.h +++ b/display.h @@ -8,9 +8,21 @@ #ifndef DISPLAY_H #define DISPLAY_H +#include +#include +#include +#include +#include #include "types.h" #include "bitmaps.h" #include "font.h" +#include "hack.h" +#include "emojis.h" +#include "bitmaps.h" +#include "spi.h" +#include "tft.h" +#include "usart.h" +#include "utils.h" /** * Sets the whole display to the given 16-Bit (5/6/5) RGB color. @@ -23,48 +35,48 @@ * Draws a rectangle with the given origin and dimensions, line thickness * and color. * - * @param row - * @param col + * @param x + * @param y * @param width * @param height * @param thickness * @param color */ -void drawRectangle(row_t row, col_t col, width_t width, height_t height, +void drawRectangle(x_t x, y_t y, width_t width, height_t height, uint8_t thickness, uint16_t color); /** * Writes the bitmap with the given index to the given row and column * and returns the width of the bitmap. * - * @param row - * @param col + * @param x + * @param y * @param index * @return bitmap width */ -width_t writeBitmap(row_t row, col_t col, uint16_t index); +width_t writeBitmap(x_t x, y_t y, uint16_t index); /** * Writes the glyph with the given pseudo UTF-8 code point with the given * font to the given row and column and returns the width of the glyph. * - * @param row - * @param col + * @param x + * @param y * @param font * @param code * @return glyph width */ -width_t writeGlyph(row_t row, col_t col, const __flash Font *font, code_t code); +width_t writeGlyph(x_t x, y_t y, const __flash Font *font, code_t code); /** * Writes the given string with the given font to the given row and column. * - * @param row - * @param col + * @param x + * @param y * @param font * @param string */ -void writeString(row_t row, col_t col, const __flash Font *font, const char *string); +void writeString(x_t x, y_t y, const __flash Font *font, const char *string); /** * Writes the given lines of text to the top left corner of the display. diff --git a/emojis.c b/emojis.c index b9d62bc..1dd0c57 100644 --- a/emojis.c +++ b/emojis.c @@ -7,11 +7,7 @@ * Created on 26. November 2023, 20:29 */ -#include -#include "font.h" #include "emojis.h" -#include "tft.h" -#include "utils.h" #define WIDTH 16 #define HEIGHT 16 diff --git a/emojis.h b/emojis.h index e056ef0..715a6da 100644 --- a/emojis.h +++ b/emojis.h @@ -10,7 +10,10 @@ #ifndef EMOJIS_H #define EMOJIS_H +#include #include "font.h" +#include "tft.h" +#include "utils.h" /** * Emoji "font". diff --git a/emojis/emojis.sh b/emojis/emojis.sh index 736eccf..4ed6add 100755 --- a/emojis/emojis.sh +++ b/emojis/emojis.sh @@ -7,49 +7,49 @@ echo "c ffff" > /dev/ttyUSB0 sleep 1 echo -e "t 0 0 Hello Emojis!" > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 16 0 \ts' > /dev/ttyUSB0 -sleep 0.1 +sleep 0.2 +echo -e 't 0 16 \ts' > /dev/ttyUSB0 +sleep 0.2 echo -e 't 16 16 \tb' > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 16 32 \tg' > /dev/ttyUSB0 -# sleep 0.1 -# echo -e 't 16 48 \tn' > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 16 48 \tm' > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 16 64 \th' > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 16 80 \tt' > /dev/ttyUSB0 -# sleep 0.1 -# echo -e 't 16 112 \te' > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 16 96 \ta' > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 32 0 \tU' > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 32 16 \tD' > /dev/ttyUSB0 -sleep 0.1 +sleep 0.2 +echo -e 't 32 16 \tg' > /dev/ttyUSB0 +# sleep 0.2 +# echo -e 't 48 16 \tn' > /dev/ttyUSB0 +sleep 0.2 +echo -e 't 48 16 \tm' > /dev/ttyUSB0 +sleep 0.2 +echo -e 't 64 16 \th' > /dev/ttyUSB0 +sleep 0.2 +echo -e 't 80 16 \tt' > /dev/ttyUSB0 +# sleep 0.2 +# echo -e 't 112 16 \te' > /dev/ttyUSB0 +sleep 0.2 +echo -e 't 96 16 \ta' > /dev/ttyUSB0 +sleep 0.2 +echo -e 't 0 32 \tU' > /dev/ttyUSB0 +sleep 0.2 +echo -e 't 16 32 \tD' > /dev/ttyUSB0 +sleep 0.2 echo -e 't 32 32 \tS' > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 32 48 \tA' > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 32 64 \tu' > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 32 80 \to' > /dev/ttyUSB0 -# sleep 0.1 -# echo -e 't 32 96 \tO' > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 48 0 \tH' > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 48 16 \tB' > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 48 32 \tP' > /dev/ttyUSB0 -sleep 0.1 +sleep 0.2 +echo -e 't 48 32 \tA' > /dev/ttyUSB0 +sleep 0.2 +echo -e 't 64 32 \tu' > /dev/ttyUSB0 +sleep 0.2 +echo -e 't 80 32 \to' > /dev/ttyUSB0 +# sleep 0.2 +# echo -e 't 96 32 \tO' > /dev/ttyUSB0 +sleep 0.2 +echo -e 't 0 48 \tH' > /dev/ttyUSB0 +sleep 0.2 +echo -e 't 16 48 \tB' > /dev/ttyUSB0 +sleep 0.2 +echo -e 't 32 48 \tP' > /dev/ttyUSB0 +sleep 0.2 echo -e 't 48 48 \tT' > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 48 64 \tF' > /dev/ttyUSB0 -sleep 0.1 -echo -e 't 48 80 \tR' > /dev/ttyUSB0 -# sleep 0.1 -# echo -e 't 48 96 \tC' > /dev/ttyUSB0 +sleep 0.2 +echo -e 't 64 48 \tF' > /dev/ttyUSB0 +sleep 0.2 +echo -e 't 80 48 \tR' > /dev/ttyUSB0 +# sleep 0.2 +# echo -e 't 96 48 \tC' > /dev/ttyUSB0 diff --git a/hack.c b/hack.c index c25d8dd..bb42959 100644 --- a/hack.c +++ b/hack.c @@ -15,10 +15,7 @@ */ #include -#include "font.h" #include "hack.h" -#include "tft.h" -#include "utils.h" #define WIDTH 8 #define HEIGHT 16 diff --git a/hack.h b/hack.h index df0086d..4d4ba19 100644 --- a/hack.h +++ b/hack.h @@ -18,6 +18,8 @@ #define HACK_H #include "font.h" +#include "colorspace.h" +#include "utils.h" #define HACK_DEMO_SIZE 8 #define HACK_DEMO_LINE_SIZE 64 diff --git a/nbproject/Makefile-Custom.mk b/nbproject/Makefile-Custom.mk index 7103c2a..f47383d 100644 --- a/nbproject/Makefile-Custom.mk +++ b/nbproject/Makefile-Custom.mk @@ -21,7 +21,7 @@ AS=avr-as # Macros -CND_PLATFORM=AVR2.1-GCC13.2-Linux +CND_PLATFORM=AVR-Linux CND_DLIB_EXT=so CND_CONF=Custom CND_DISTDIR=dist @@ -37,12 +37,13 @@ OBJECTFILES= \ ${OBJECTDIR}/_ext/48b9b4a1/avrtft.o \ ${OBJECTDIR}/_ext/48b9b4a1/bmp.o \ + ${OBJECTDIR}/_ext/48b9b4a1/colorspace.o \ ${OBJECTDIR}/_ext/48b9b4a1/display.o \ - ${OBJECTDIR}/_ext/48b9b4a1/emojis.o \ ${OBJECTDIR}/_ext/48b9b4a1/font.o \ ${OBJECTDIR}/_ext/48b9b4a1/hack.o \ ${OBJECTDIR}/_ext/48b9b4a1/i2c.o \ ${OBJECTDIR}/_ext/48b9b4a1/paint.o \ + ${OBJECTDIR}/_ext/48b9b4a1/ra8875.o \ ${OBJECTDIR}/_ext/48b9b4a1/sdcard.o \ ${OBJECTDIR}/_ext/48b9b4a1/spi.o \ ${OBJECTDIR}/_ext/48b9b4a1/tft.o \ @@ -75,51 +76,55 @@ ${OBJECTDIR}/_ext/48b9b4a1/avrtft.o: /home/dode/dev/avrtft/avrtft.c ${MKDIR} -p ${OBJECTDIR}/_ext/48b9b4a1 - $(COMPILE.c) -g -DBAUD=9600 -DF_CPU=8000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -std=c99 -o ${OBJECTDIR}/_ext/48b9b4a1/avrtft.o /home/dode/dev/avrtft/avrtft.c + $(COMPILE.c) -g -DBAUD=38400 -DDRIVER=0 -DF_CPU=16000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -std=c99 -o ${OBJECTDIR}/_ext/48b9b4a1/avrtft.o /home/dode/dev/avrtft/avrtft.c ${OBJECTDIR}/_ext/48b9b4a1/bmp.o: /home/dode/dev/avrtft/bmp.c ${MKDIR} -p ${OBJECTDIR}/_ext/48b9b4a1 - $(COMPILE.c) -g -DBAUD=9600 -DF_CPU=8000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -o ${OBJECTDIR}/_ext/48b9b4a1/bmp.o /home/dode/dev/avrtft/bmp.c + $(COMPILE.c) -g -DBAUD=38400 -DDRIVER=0 -DF_CPU=16000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -o ${OBJECTDIR}/_ext/48b9b4a1/bmp.o /home/dode/dev/avrtft/bmp.c + +${OBJECTDIR}/_ext/48b9b4a1/colorspace.o: /home/dode/dev/avrtft/colorspace.c + ${MKDIR} -p ${OBJECTDIR}/_ext/48b9b4a1 + $(COMPILE.c) -g -DBAUD=38400 -DDRIVER=0 -DF_CPU=16000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -o ${OBJECTDIR}/_ext/48b9b4a1/colorspace.o /home/dode/dev/avrtft/colorspace.c ${OBJECTDIR}/_ext/48b9b4a1/display.o: /home/dode/dev/avrtft/display.c ${MKDIR} -p ${OBJECTDIR}/_ext/48b9b4a1 - $(COMPILE.c) -g -DBAUD=9600 -DF_CPU=8000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -std=c99 -o ${OBJECTDIR}/_ext/48b9b4a1/display.o /home/dode/dev/avrtft/display.c - -${OBJECTDIR}/_ext/48b9b4a1/emojis.o: /home/dode/dev/avrtft/emojis.c - ${MKDIR} -p ${OBJECTDIR}/_ext/48b9b4a1 - $(COMPILE.c) -g -DBAUD=9600 -DF_CPU=8000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -std=c99 -o ${OBJECTDIR}/_ext/48b9b4a1/emojis.o /home/dode/dev/avrtft/emojis.c + $(COMPILE.c) -g -DBAUD=38400 -DDRIVER=0 -DF_CPU=16000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -std=c99 -o ${OBJECTDIR}/_ext/48b9b4a1/display.o /home/dode/dev/avrtft/display.c ${OBJECTDIR}/_ext/48b9b4a1/font.o: /home/dode/dev/avrtft/font.c ${MKDIR} -p ${OBJECTDIR}/_ext/48b9b4a1 - $(COMPILE.c) -g -DBAUD=9600 -DF_CPU=8000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -std=c99 -o ${OBJECTDIR}/_ext/48b9b4a1/font.o /home/dode/dev/avrtft/font.c + $(COMPILE.c) -g -DBAUD=38400 -DDRIVER=0 -DF_CPU=16000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -std=c99 -o ${OBJECTDIR}/_ext/48b9b4a1/font.o /home/dode/dev/avrtft/font.c ${OBJECTDIR}/_ext/48b9b4a1/hack.o: /home/dode/dev/avrtft/hack.c ${MKDIR} -p ${OBJECTDIR}/_ext/48b9b4a1 - $(COMPILE.c) -g -DBAUD=9600 -DF_CPU=8000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -std=c99 -o ${OBJECTDIR}/_ext/48b9b4a1/hack.o /home/dode/dev/avrtft/hack.c + $(COMPILE.c) -g -DBAUD=38400 -DDRIVER=0 -DF_CPU=16000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -std=c99 -o ${OBJECTDIR}/_ext/48b9b4a1/hack.o /home/dode/dev/avrtft/hack.c ${OBJECTDIR}/_ext/48b9b4a1/i2c.o: /home/dode/dev/avrtft/i2c.c ${MKDIR} -p ${OBJECTDIR}/_ext/48b9b4a1 - $(COMPILE.c) -g -DBAUD=9600 -DF_CPU=8000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -o ${OBJECTDIR}/_ext/48b9b4a1/i2c.o /home/dode/dev/avrtft/i2c.c + $(COMPILE.c) -g -DBAUD=38400 -DDRIVER=0 -DF_CPU=16000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -o ${OBJECTDIR}/_ext/48b9b4a1/i2c.o /home/dode/dev/avrtft/i2c.c ${OBJECTDIR}/_ext/48b9b4a1/paint.o: /home/dode/dev/avrtft/paint.c ${MKDIR} -p ${OBJECTDIR}/_ext/48b9b4a1 - $(COMPILE.c) -g -DBAUD=9600 -DF_CPU=8000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -o ${OBJECTDIR}/_ext/48b9b4a1/paint.o /home/dode/dev/avrtft/paint.c + $(COMPILE.c) -g -DBAUD=38400 -DDRIVER=0 -DF_CPU=16000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -o ${OBJECTDIR}/_ext/48b9b4a1/paint.o /home/dode/dev/avrtft/paint.c + +${OBJECTDIR}/_ext/48b9b4a1/ra8875.o: /home/dode/dev/avrtft/ra8875.c + ${MKDIR} -p ${OBJECTDIR}/_ext/48b9b4a1 + $(COMPILE.c) -g -DBAUD=38400 -DDRIVER=0 -DF_CPU=16000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -o ${OBJECTDIR}/_ext/48b9b4a1/ra8875.o /home/dode/dev/avrtft/ra8875.c ${OBJECTDIR}/_ext/48b9b4a1/sdcard.o: /home/dode/dev/avrtft/sdcard.c ${MKDIR} -p ${OBJECTDIR}/_ext/48b9b4a1 - $(COMPILE.c) -g -DBAUD=9600 -DF_CPU=8000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -o ${OBJECTDIR}/_ext/48b9b4a1/sdcard.o /home/dode/dev/avrtft/sdcard.c + $(COMPILE.c) -g -DBAUD=38400 -DDRIVER=0 -DF_CPU=16000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -o ${OBJECTDIR}/_ext/48b9b4a1/sdcard.o /home/dode/dev/avrtft/sdcard.c ${OBJECTDIR}/_ext/48b9b4a1/spi.o: /home/dode/dev/avrtft/spi.c ${MKDIR} -p ${OBJECTDIR}/_ext/48b9b4a1 - $(COMPILE.c) -g -DBAUD=9600 -DF_CPU=8000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -std=c99 -o ${OBJECTDIR}/_ext/48b9b4a1/spi.o /home/dode/dev/avrtft/spi.c + $(COMPILE.c) -g -DBAUD=38400 -DDRIVER=0 -DF_CPU=16000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -std=c99 -o ${OBJECTDIR}/_ext/48b9b4a1/spi.o /home/dode/dev/avrtft/spi.c ${OBJECTDIR}/_ext/48b9b4a1/tft.o: /home/dode/dev/avrtft/tft.c ${MKDIR} -p ${OBJECTDIR}/_ext/48b9b4a1 - $(COMPILE.c) -g -DBAUD=9600 -DF_CPU=8000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -std=c99 -o ${OBJECTDIR}/_ext/48b9b4a1/tft.o /home/dode/dev/avrtft/tft.c + $(COMPILE.c) -g -DBAUD=38400 -DDRIVER=0 -DF_CPU=16000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -std=c99 -o ${OBJECTDIR}/_ext/48b9b4a1/tft.o /home/dode/dev/avrtft/tft.c ${OBJECTDIR}/_ext/48b9b4a1/touch.o: /home/dode/dev/avrtft/touch.c ${MKDIR} -p ${OBJECTDIR}/_ext/48b9b4a1 - $(COMPILE.c) -g -DBAUD=9600 -DF_CPU=8000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -o ${OBJECTDIR}/_ext/48b9b4a1/touch.o /home/dode/dev/avrtft/touch.c + $(COMPILE.c) -g -DBAUD=38400 -DDRIVER=0 -DF_CPU=16000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -o ${OBJECTDIR}/_ext/48b9b4a1/touch.o /home/dode/dev/avrtft/touch.c # Subprojects .build-subprojects: diff --git a/nbproject/Makefile-variables.mk b/nbproject/Makefile-variables.mk index 6f43ff9..e75751d 100644 --- a/nbproject/Makefile-variables.mk +++ b/nbproject/Makefile-variables.mk @@ -7,13 +7,13 @@ CND_BUILDDIR=build CND_DISTDIR=dist # Custom configuration -CND_PLATFORM_Custom=AVR2.1-GCC13.2-Linux -CND_ARTIFACT_DIR_Custom=dist/Custom/AVR2.1-GCC13.2-Linux +CND_PLATFORM_Custom=AVR-Linux +CND_ARTIFACT_DIR_Custom=dist/Custom/AVR-Linux CND_ARTIFACT_NAME_Custom=avrtft -CND_ARTIFACT_PATH_Custom=dist/Custom/AVR2.1-GCC13.2-Linux/avrtft -CND_PACKAGE_DIR_Custom=dist/Custom/AVR2.1-GCC13.2-Linux/package +CND_ARTIFACT_PATH_Custom=dist/Custom/AVR-Linux/avrtft +CND_PACKAGE_DIR_Custom=dist/Custom/AVR-Linux/package CND_PACKAGE_NAME_Custom=avrtft.tar -CND_PACKAGE_PATH_Custom=dist/Custom/AVR2.1-GCC13.2-Linux/package/avrtft.tar +CND_PACKAGE_PATH_Custom=dist/Custom/AVR-Linux/package/avrtft.tar # # include compiler specific variables # diff --git a/nbproject/Package-Custom.bash b/nbproject/Package-Custom.bash index b32617e..b7c8628 100644 --- a/nbproject/Package-Custom.bash +++ b/nbproject/Package-Custom.bash @@ -6,7 +6,7 @@ # Macros TOP=`pwd` -CND_PLATFORM=AVR2.1-GCC13.2-Linux +CND_PLATFORM=AVR-Linux CND_CONF=Custom CND_DISTDIR=dist CND_BUILDDIR=build diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index 3072644..b4528fe 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -2,20 +2,20 @@ - - emojis.sh.bash - avrtft.c bmp.c bmp.h + colorspace.c + colorspace.h display.c - emojis.c font.c hack.c i2c.c i2c.h paint.c paint.h + ra8875.c + ra8875.h sdcard.c sdcard.h spi.c @@ -39,7 +39,7 @@ - AVR2.1-GCC13.2|GNU + AVR|GNU false false @@ -49,8 +49,9 @@ . - BAUD=9600 - F_CPU=8000000UL + BAUD=38400 + DRIVER=0 + F_CPU=16000000UL __AVR_ATmega328P__ __flash=volatile @@ -62,15 +63,12 @@ + + + + - - - - @@ -83,6 +81,10 @@ + + + + diff --git a/paint.c b/paint.c index 460d11d..a5da2fc 100644 --- a/paint.c +++ b/paint.c @@ -6,7 +6,6 @@ */ #include "paint.h" -#include "usart.h" static uint16_t colors[] = { 0xf800, 0x07e0, 0x001f, @@ -24,7 +23,7 @@ */ static void paintColors(void) { for (uint8_t i = 0; i < CTRL_COUNT; i++) { - fillArea(CTRL_WIDTH * i, 0, CTRL_WIDTH, CTRL_WIDTH, colors[i]); + fillArea(0, CTRL_WIDTH * i, CTRL_WIDTH, CTRL_WIDTH, colors[i]); } } @@ -32,13 +31,13 @@ * Paints the tool selection. */ static void paintTools(void) { - fillArea(0, DISPLAY_WIDTH - CTRL_WIDTH, + fillArea(DISPLAY_WIDTH - CTRL_WIDTH, 0, CTRL_WIDTH, CTRL_WIDTH * TOOL_COUNT, 0xffff); for (uint8_t i = 0; i < TOOL_COUNT; i++) { - drawRectangle(CTRL_WIDTH * i, DISPLAY_WIDTH - CTRL_WIDTH, + drawRectangle(DISPLAY_WIDTH - CTRL_WIDTH, CTRL_WIDTH * i, CTRL_WIDTH, CTRL_WIDTH + 1, 1, 0x0); - writeBitmap(CTRL_WIDTH * i + BITMAP_PADDING, - DISPLAY_WIDTH - CTRL_WIDTH + BITMAP_PADDING, i); + writeBitmap(DISPLAY_WIDTH - CTRL_WIDTH + BITMAP_PADDING, + CTRL_WIDTH * i + BITMAP_PADDING, i); } } @@ -52,7 +51,7 @@ paintTools(); // highlight default tool - drawRectangle(CTRL_WIDTH * tool, DISPLAY_WIDTH - CTRL_WIDTH, + drawRectangle(DISPLAY_WIDTH - CTRL_WIDTH, CTRL_WIDTH * tool, CTRL_WIDTH, CTRL_WIDTH + 1, 2, 0x0); } @@ -63,7 +62,7 @@ uint8_t i = point->y / (CTRL_WIDTH + 1); // repaint colors, highlight and select color paintColors(); - drawRectangle(CTRL_WIDTH * i, 0, + drawRectangle(0, CTRL_WIDTH * i, CTRL_WIDTH, CTRL_WIDTH, 2, 0x0); color = colors[i]; } @@ -73,7 +72,7 @@ // tool selected if (i == TOOL_CLEAR) { // clear canvas - fillArea(0, CTRL_WIDTH, DISPLAY_WIDTH - 2 * CTRL_WIDTH + 1, + fillArea(CTRL_WIDTH, 0, DISPLAY_WIDTH - 2 * CTRL_WIDTH + 1, DISPLAY_HEIGHT, 0xffff); } else if (i == TOOL_THICK) { // increment line thickness @@ -83,7 +82,7 @@ } else if (i < TOOL_COUNT) { // repaint tools, highlight and select tool paintTools(); - drawRectangle(CTRL_WIDTH * i, DISPLAY_WIDTH - CTRL_WIDTH, + drawRectangle(DISPLAY_WIDTH - CTRL_WIDTH, CTRL_WIDTH * i, CTRL_WIDTH, CTRL_WIDTH + 1, 2, 0x0); tool = i; } @@ -96,9 +95,9 @@ void paintPoint(uint8_t event, Point *point) { if (tool == TOOL_ERASER) { - fillArea(point->y - thoff, point->x - thoff, thick, thick, 0xffff); + fillArea(point->x - thoff, point->y - thoff, thick, thick, 0xffff); } else { - fillArea(point->y - thoff, point->x - thoff, thick, thick, color); + fillArea(point->x - thoff, point->y - thoff, thick, thick, color); } if (prev.x != -1) { @@ -111,21 +110,21 @@ float yd = (point->y - prev.y) / d; for (int i = 1; i < d; i++) { - col_t xi = prev.x + xd * i; - row_t yi = prev.y + yd * i; - fillArea(yi - thoff, xi - thoff, thick, thick, color); + x_t xi = prev.x + xd * i; + y_t yi = prev.y + yd * i; + fillArea(xi - thoff, yi - thoff, thick, thick, color); } } } // draw a rectangle spanning the previous and current point if (tool == TOOL_RECT && event == EVENT_PRESS_DOWN) { - row_t x1 = fmin(prev.x, point->x); - row_t y1 = fmin(prev.y, point->y); - col_t x2 = fmax(prev.x, point->x); - col_t y2 = fmax(prev.y, point->y); + y_t x1 = fmin(prev.x, point->x); + y_t y1 = fmin(prev.y, point->y); + x_t x2 = fmax(prev.x, point->x); + x_t y2 = fmax(prev.y, point->y); - drawRectangle(y1 - thoff, x1 - thoff, + drawRectangle(x1 - thoff, y1 - thoff, x2 - x1 + thick, y2 - y1 + thick, thick, color); // unset previous point and leave (for now) prev = (Point){-1}; diff --git a/paint.h b/paint.h index e0d7bbf..1edc94a 100644 --- a/paint.h +++ b/paint.h @@ -11,7 +11,7 @@ #include #include #include - +#include "usart.h" #include "tft.h" #include "touch.h" #include "display.h" diff --git a/pins.h b/pins.h index 1455c1b..8b1f960 100644 --- a/pins.h +++ b/pins.h @@ -39,6 +39,8 @@ /* Display other */ #define DDR_DISP DDRD #define PORT_DISP PORTD +#define PINP_DISP PIND +#define PIN_BUSY PD5 // display wait #define PIN_RST PD7 // display reset #endif /* PINS_H */ diff --git a/ra8875.c b/ra8875.c new file mode 100644 index 0000000..6139c7b --- /dev/null +++ b/ra8875.c @@ -0,0 +1,424 @@ +/* + * File: ra8875.c + * Author: torsten.roemer@luniks.net + * + * Thanks to https://github.com/adafruit/Adafruit_RA8875 + * for PLL settings and HSync and VSync timings! + * + * Created on 1. Juni 2024, 15:33 + */ + +#if DRIVER == 1 + +#include "ra8875.h" + +/** + * Does a hardware reset. + */ +static void hwReset(void) { + PORT_DISP &= ~(1 << PIN_RST); + _delay_ms(10); + PORT_DISP |= (1 << PIN_RST); + _delay_ms(100); +} + +/** + * Waits until the display is no longer busy. + */ +static void waitBusy(void) { + loop_until_bit_is_set(PINP_DISP, PIN_BUSY); +} + +/** + * Writes given command to controller. + * + * @param cmd + */ +static void cmdWrite(uint8_t cmd) { + displaySel(); + transmit(CMD_WRITE); + transmit(cmd); + displayDes(); +} + +/** + * Reads status of controller. + * + * @return status + */ +static uint8_t statusRead(void) { + displaySel(); + transmit(STATUS_READ); + uint8_t status = transmit(0x00); + displayDes(); + + return status; +} + +/** + * Writes given data to controller. + * + * @param data + */ +static void dataWrite(uint8_t data) { + displaySel(); + transmit(DATA_WRITE); + transmit(data); + displayDes(); +} + +/** + * Reads data from controller. + * + * @return data + */ +static uint8_t dataRead(void) { + displaySel(); + transmit(DATA_READ); + uint8_t data = transmit(0x00); + displayDes(); + + return data; +} + +/** + * Writes given data to given register. + * + * @param reg + * @param data + */ +static void regWrite(uint8_t reg, uint8_t data) { + cmdWrite(reg); + dataWrite(data); +} + +/** + * Reads data from given register and returns it. + * + * @param reg + * @return data + */ +static uint8_t regRead(uint8_t reg) { + cmdWrite(reg); + return dataRead(); +} + +/** + * Sets the window in that to write text, draw graphics or write to memory. + * The cursor must be set to the start coordinates of the window. + * + * @param xs X start + * @param ys Y start + * @param xe X end + * @param ye Y end + */ +static void setActiveWindow(x_t xs, y_t ys, x_t xe, y_t ye) { + // horizontal start point of active window + regWrite(HSAW0, xs); + regWrite(HSAW1, xs >> 8); + + // vertical start point of active window + regWrite(VSAW0, ys); + regWrite(VSAW1, ys >> 8); + + // horizontal end point of active window + regWrite(HEAW0, xe); + regWrite(HEAW1, xe >> 8); + + // vertical end point of active window + regWrite(VEAW0, ye); + regWrite(VEAW1, ye >> 8); +} + +/** + * Sets the cursor to given X and Y coordinates. + * + * @param x + * @param y + */ +static void setCursor(x_t x, y_t y) { + regWrite(CURH0, x); + regWrite(CURH1, x >> 8); + + regWrite(CURV0, y); + regWrite(CURV1, y >> 8); +} + +/** + * Switches to graphics mode. + */ +static void graphicsMode(void) { + uint8_t data = regRead(MWCR0); + data &= ~(1 << 7); + regWrite(MWCR0, data); +} + +/** + * Switches to text mode. + */ +static void textMode(void) { + uint8_t data = regRead(MWCR0); + data |= (1 << 7); + regWrite(MWCR0, data); +} + +void initDisplay(void) { + spiSlow(); + + hwReset(); + + // set wake up + // cmdWrite(PWRR); + // dataWrite(0x00); + // _delay_ms(100); + + // set PLL + regWrite(PLLC1, 0x00 + 11); // 800x480: 11 + _delay_ms(1); + regWrite(PLLC2, 0x02); // div by 4 + _delay_ms(1); + + // set pixel clock + regWrite(PCSR, 0x80 | 0x01); // 800x480: falling edge, system clock div by 2 + _delay_ms(20); + + // set 16-bit color depth, 8-bit MCU + regWrite(SYSR, 0x0c | 0x00); + + // display width + regWrite(HDWR, DISPLAY_WIDTH / 8 - 1); + + // horizontal sync + regWrite(HNDFTR, 0x00 + HNDFT); + regWrite(HNDR, (HNDP - HNDFT - 2) / 8); + regWrite(HSTR, HSP / 8 - 1); + regWrite(HPWR, 0x00 + (HPW / 8 - 1)); + + // display height + regWrite(VDHR0, (uint8_t)(DISPLAY_HEIGHT - 1)); + regWrite(VDHR1, DISPLAY_HEIGHT >> 8); + + // vertical sync + regWrite(VNDR0, VNDP - 1); + regWrite(VNDR1, VNDP >> 8); + regWrite(VSTR0, VSP - 1); + regWrite(VSTR1, VSP >> 8); + regWrite(VPWR, 0x00 + VPW - 1); + + uint8_t dpcr = regRead(DPCR); + if (HFLIP) { + dpcr |= (1 << 3); + } + if (VFLIP) { + dpcr |= (1 << 2); + } + regWrite(DPCR, dpcr); + + setActiveWindow(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1); + + // clear full display + regWrite(MCLR, 0x80 | 0x00); + + _delay_ms(100); + + // display on + regWrite(PWRR, 0x80); + _delay_ms(20); + + // TFT LCD backlight on + // PWM1 + regWrite(P1CR, 0x80); + regWrite(P1DCR, 0xff); + + // GPIOX write to enable display + regWrite(GPIOX, 1); + + // enable touch panel, wait 4096 clocks, system clock/8 + regWrite(TPCR0, 0x80 | 0x30 | 0x03); + // enable debounce for touch interrupt + regWrite(TPCR1, 0x04); + // enable touch interrupt + regWrite(INTC1, 0x04); + + spiFast(); + + printString("done initializing display\r\n"); +} + +void demoDisplay(void) { + graphicsMode(); + + drawPixel(30, 30, 0xffff); + + drawCircle( 10, 10, 10, 0xffff); + drawCircle(790, 10, 10, 0xffff); + drawCircle( 10, 470, 10, 0xffff); + drawCircle(790, 470, 10, 0xffff); + + drawCircle(200, 240, 30, 0b1111100000000000); + drawCircle(400, 240, 30, 0b0000011111100000); + drawCircle(600, 240, 30, 0b0000000000011111); + + textMode(); + + writeText(350, 300, 0x07e0, 0x0000, "Hello RA8875!"); + + graphicsMode(); +} + +void setBackground(uint16_t color) { + // red + regWrite(BGCR0, (color & 0xf800) >> 11); + // green + regWrite(BGCR1, (color & 0x07e0) >> 5); + // blue + regWrite(BGCR2, (color & 0x001f) >> 0); +} + +void setForeground(uint16_t color) { + // red + regWrite(FGCR0, (color & 0xf800) >> 11); + // green + regWrite(FGCR1, (color & 0x07e0) >> 5); + // blue + regWrite(FGCR2, (color & 0x001f) >> 0); +} + +void drawPixel(x_t x, y_t y, uint16_t color) { + setCursor(x, y); + + cmdWrite(MRWC); + displaySel(); + transmit(DATA_WRITE); + transmit(color >> 8); + transmit(color); + displayDes(); + + waitBusy(); +} + +void drawCircle(x_t x, y_t y, uint16_t radius, uint16_t color) { + // set the center of the circle + regWrite(DCHR0, x); + regWrite(DCHR1, x >> 8); + + regWrite(DCVR0, y); + regWrite(DCVR1, y >> 8); + + // set the radius of the circle + regWrite(DCRR, radius); + + // set the color of the circle + setForeground(color); + + // start circle drawing function + regWrite(DCR, 0x40 | 0x20); + + waitBusy(); +} + +void writeText(x_t x, y_t y, uint16_t fg, uint16_t bg, char *string) { + regWrite(F_CURXL, x); + regWrite(F_CURXH, x >> 8); + + regWrite(F_CURYL, y); + regWrite(F_CURYH, y >> 8); + + setForeground(fg); + setBackground(bg); + + cmdWrite(MRWC); + for (; *string != '\0'; string++) { + dataWrite(*string); + } +} + +void writeStart(void) { + cmdWrite(MRWC); + displaySel(); + transmit(DATA_WRITE); +} + +void writeRestart(void) { + cmdWrite(MRWC); + displaySel(); + transmit(DATA_WRITE); +} + +void writeByte(uint8_t byte) { + transmit(byte); +} + +void writeEnd(void) { + displayDes(); + waitBusy(); +} + +void fillArea(x_t x, y_t y, + width_t width, height_t height, + uint16_t color) { + // FIXME + drawCircle(x, y, 10, 0x07e0); +} + +void setArea(x_t x, y_t y, + width_t width, height_t height, + bool hflip, bool vflip) { + setActiveWindow(x, y, x + width - 1, y + height - 1); + setCursor(x, y); + + uint8_t mwcr2 = regRead(MWCR0); + if (hflip) { + mwcr2 |= (1 << 2); + } else { + mwcr2 &= ~(1 << 2); + } + // vertical flip in memory not possible? + regWrite(MWCR0, mwcr2); +} + +void writeData(const __flash uint8_t *bitmap, + width_t width, height_t height, + space_t space) { + writeStart(); + writeSpace(bitmap, width, height, space); + writeEnd(); +} + +bool isTouch(void) { + uint8_t data = regRead(INTC2); + + return data & 0x04; +} + +// TODO calibration +uint8_t readTouch(Point *point) { + uint8_t tpxh = regRead(TPXH); + uint8_t tpyh = regRead(TPYH); + uint8_t tpxyl = regRead(TPXYL); + + point->x = (tpxh << 2); + point->x |= (tpxyl & 0x03); + + point->y = (tpyh << 2); + point->y |= ((tpxyl & 0x0c) >> 2); + + // 10-bit ADC + point->x = ((uint32_t)point->x * DISPLAY_WIDTH) >> 10; + point->y = ((uint32_t)point->y * DISPLAY_HEIGHT) >> 10; + + if (HFLIP) { + point->x = DISPLAY_WIDTH - point->x; + } + if (VFLIP) { + point->y = DISPLAY_HEIGHT - point->y; + } + + return EVENT_PRESS_DOWN; +} + +void clearTouch(void) { + regWrite(INTC2, 0x04); +} + +#endif /* DRIVER */ \ No newline at end of file diff --git a/ra8875.h b/ra8875.h new file mode 100644 index 0000000..9eaf02c --- /dev/null +++ b/ra8875.h @@ -0,0 +1,169 @@ +/* + * File: ra8875.h + * Author: torsten.roemer@luniks.net + * + * Created on 1. Juni 2024, 15:32 + */ + +#ifndef RA8875_H +#define RA8875_H + +#include +#include "tft.h" +#include "touch.h" +#include "types.h" +#include "pins.h" +#include "usart.h" +#include "spi.h" + +#define CMD_WRITE 0x80 +#define STATUS_READ 0xc0 +#define DATA_WRITE 0x00 +#define DATA_READ 0x40 + +/* System & Configuration Registers */ +#define PWRR 0x01 +#define MRWC 0x02 +#define PCSR 0x04 +#define SYSR 0x10 + +/* Horizontal (Sync) Registers */ +#define HDWR 0x14 +#define HNDFTR 0x15 +#define HNDR 0x16 +#define HSTR 0x17 +#define HPWR 0x18 + +/* Vertical (Sync) Registers */ +#define VDHR0 0x19 +#define VDHR1 0x1a +#define VNDR0 0x1b +#define VNDR1 0x1c +#define VSTR0 0x1d +#define VSTR1 0x1e +#define VPWR 0x1f + +/* LCD Display Control Registers */ +#define DPCR 0x20 +#define FNCR0 0x21 +#define FNCR1 0x22 +#define F_CURXL 0x2a +#define F_CURXH 0x2b +#define F_CURYL 0x2c +#define F_CURYH 0x2d + +/* Active Window & Scroll Window Setting Registers */ +#define HSAW0 0x30 +#define HSAW1 0x31 +#define VSAW0 0x32 +#define VSAW1 0x33 +#define HEAW0 0x34 +#define HEAW1 0x35 +#define VEAW0 0x36 +#define VEAW1 0x37 + +/* Cursor Setting Registers */ +#define MWCR0 0x40 +#define CURH0 0x46 +#define CURH1 0x47 +#define CURV0 0x48 +#define CURV1 0x49 + +/* Background Color Registers */ +#define BGCR0 0x60 +#define BGCR1 0x61 +#define BGCR2 0x62 + +/* Foreground Color Registers */ +#define FGCR0 0x63 +#define FGCR1 0x64 +#define FGCR2 0x65 + +/* Touch Panel Control Registers */ +#define TPCR0 0x70 +#define TPCR1 0x71 +#define TPXH 0x72 +#define TPYH 0x73 +#define TPXYL 0x74 + +/* Interrupt Control Registers */ +#define INTC1 0xf0 +#define INTC2 0xf1 + +/* PLL Setting Registers */ +#define PLLC1 0x88 +#define PLLC2 0x89 + +/* PWM Control Registers */ +#define P1CR 0x8a +#define P1DCR 0x8b + +/* Memory Clear Control Register */ +#define MCLR 0x8e + +/* Drawing Contol Registers */ +#define DCR 0x90 +#define DCHR0 0x99 +#define DCHR1 0x9a +#define DCVR0 0x9b +#define DCVR1 0x9c +#define DCRR 0x9d + +/* Key & IO Control Registers */ +#define GPIOX 0xc7 + +/* HSync + VSync currently only for 800x480 */ +#define HNDFT 0 +#define HNDP 10 +#define HSP 32 +#define HPW 96 + +#define VNDP 32 +#define VSP 23 +#define VPW 2 + +/** + * Sets given background color. + * + * @param color + */ +void setBackground(uint16_t color); + +/** + * Sets given foreground color. + * + * @param color + */ +void setForeground(uint16_t color); + +/** + * Draws a pixel at given coordinates and color. + * + * @param x + * @param y + * @param color + */ +void drawPixel(x_t x, y_t y, uint16_t color); + +/** + * Draws a circle at given center coordinates, radius and color. + * + * @param x + * @param y + * @param radius + * @param color + */ +void drawCircle(x_t x, y_t y, uint16_t radius, uint16_t color); + +/** + * Writes given text at given coordinates and foreground and background color. + * + * @param x + * @param y + * @param fg + * @param bg + * @param string + */ +void writeText(x_t x, y_t y, uint16_t fg, uint16_t bg, char *string); + +#endif /* RA8875_H */ diff --git a/scripts/text.sh b/scripts/text.sh new file mode 100755 index 0000000..e6c8262 --- /dev/null +++ b/scripts/text.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +# set up the terminal for communication with the controller +stty -F /dev/ttyUSB0 speed 38400 cs8 -parenb -cstopb raw + +# clear the display all black +# echo "c ffff" > /dev/ttyUSB0 +sleep 1.5 +# inefficiently write some more text line by line on a 800x480 display +echo "t 0 0 Bärtierchen (Tardigrada) - auch Wasserbären genannt - bilden einen Tierstamm innerhalb der " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 16 Häutungstiere (Ecdysozoa). Die meistens weniger als einen Millimeter großen achtbeinigen Tiere " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 32 erinnern durch ihr Aussehen und ihre tapsig wirkende Fortbewegungsweise etwas an Bären, was zu ihrer " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 48 Bezeichnung im deutschen Sprachraum führte. Auch ihr wissenschaftlicher Name (von lateinisch " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 64 tardigradus 'langsam schreitend, langsam', zusammengesetzt aus tarde 'langsam' und gradi 'Schritte " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 80 machen, schreiten, einherschreiten')[1] geht auf die langsame Fortbewegung zurück. " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 96 " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 112 Sie leben weltweit im Meer, Süßwasser oder in feuchten Lebensräumen an Land; besonders häufig " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 128 findet man sie dort in Mooskissen. Eine Eigenschaft der Tiere ist die Kryptobiose, ein " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 144 todesähnlicher Zustand, in dem sie extreme Umweltbedingungen überdauern können. Bärtierchen können " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 160 sich sowohl vom Inhalt von Pflanzenzellen ernähren als auch räuberisch von kleinen Tieren wie " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 176 Fadenwürmern (Nematoda) oder Rädertierchen (Rotifera), die sie dazu anstechen und aussaugen. " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 192 Bärtierchen pflanzen sich meistens geschlechtlich fort. Manche Arten vermehren sich aber auch " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 208 parthenogenetisch, das heißt ohne Beteiligung von Männchen; die Eier der Weibchen entwickeln sich " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 224 in diesem Fall ohne Befruchtung." > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 240 " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 256 Die nächsten heute noch lebenden Verwandten der Bärtierchen sind vermutlich Glieder- (Arthropoda) " > /dev/ttyUSB0 +sleep 1.5 +echo "t 0 272 und Stummelfüßer (Onychophora), mit denen sie das Taxon Panarthropoda bilden. " > /dev/ttyUSB0 +sleep 1.5 \ No newline at end of file diff --git a/sdcard.c b/sdcard.c index 9d3670e..50a3e04 100644 --- a/sdcard.c +++ b/sdcard.c @@ -91,6 +91,8 @@ * Supplies ramp up time. */ static void powerOn(void) { + _delay_ms(100); + deselect(); _delay_ms(1); @@ -313,7 +315,7 @@ // power on powerOn(); - + // go to idle state response[0] = sendIdle(); if (response[0] > 0x01) { @@ -362,7 +364,7 @@ printString("sd card not ready\r\n"); return false; } - + printString("sd card ready\r\n"); return true; diff --git a/spi.c b/spi.c index 7a2b75e..1e699d7 100644 --- a/spi.c +++ b/spi.c @@ -5,11 +5,19 @@ * Created on 1. April 2023, 18:59 */ -#include -#include -#include "pins.h" #include "spi.h" +void spiSlow(void) { + SPCR &= ~(1 << SPR0); + SPCR |= (1 << SPR1); + SPSR &= ~(1 << SPI2X); +} + +void spiFast(void) { + SPCR &= ~(1 << SPR1) & ~(1 << SPR0); + SPSR &= ~(1 << SPI2X); +} + void sdCardSel(void) { PORT_SDC &= ~(1 << PIN_SDCS); } diff --git a/spi.h b/spi.h index 6633090..0b7f8d4 100644 --- a/spi.h +++ b/spi.h @@ -8,6 +8,20 @@ #ifndef SPI_H #define SPI_H +#include +#include +#include "pins.h" + +/** + * Sets slow SPI speed. + */ +void spiSlow(void); + +/** + * Sets fast SPI speed. + */ +void spiFast(void); + /** * Selects the SD card to talk to via SPI. */ diff --git a/tft.c b/tft.c index 40cd516..506ff49 100644 --- a/tft.c +++ b/tft.c @@ -5,58 +5,9 @@ * Created on 6. November 2023, 18:45 */ -#include -#include -#include -#include -#include +#if DRIVER == 0 + #include "tft.h" -#include "pins.h" -#include "usart.h" -#include "spi.h" - -#include "bitmaps.h" - -/** - * Converts the given 8 pixel in 1-Bit monochrome to 16-Bit RGB (5/6/5) color - * stored in the given array of 16 bytes. - * - * @param grey 8 pixel in 1-Bit monochrome - * @param rgb 8 pixel in 16-Bit RGB (5/6/5) color - */ -static void mono1ToRGB16(uint8_t mono, uint8_t *rgb) { - for (uint8_t i = 0; i < 16; i++) { - rgb[i] = (mono & (1 << ((15 - i) >> 1))) ? 0x0 : 0xff; - } -} - -/* - * Converts the given two pixel in 4-Bit greyscale to 16-Bit RGB (5/6/5) color - * stored in the given array of four bytes. - * - * @param grey two pixel in 4-Bit greyscale - * @param rgb two pixel in 16-Bit RGB (5/6/5) color - */ -static void grey4ToRGB16(uint8_t grey, uint8_t *rgb) { - uint8_t grey4 = ((grey >> 4) & 1); - uint8_t grey0 = ((grey >> 0) & 1); - - rgb[0] = (grey & 0xf0); - rgb[0] |= (grey4 << 3); - rgb[0] |= (grey >> 5); - - rgb[1] = ((grey & 0xf0) << 3); - rgb[1] |= ((grey & 0xf0) >> 3); - rgb[1] |= (grey4 << 6) | (grey4 << 5) | (grey4 << 0); - - rgb[2] = (grey << 4); - rgb[2] |= (grey0 << 3); - rgb[2] |= ((grey & 0x0f) >> 1); - - rgb[3] = (grey << 7); - rgb[3] |= ((grey & 0x0f) << 1); - rgb[3] |= (grey0 << 6) | (grey0 << 5) | (grey0 << 0); -} /** * Does a hardware reset. @@ -110,15 +61,15 @@ static void madctl(bool hflip, bool vflip) { // Memory data access control uint8_t madctl = 0b00110110; - madctl |= (VFLIP << 7); - madctl |= (HFLIP << 6); + madctl |= (HFLIP << 7); + madctl |= (VFLIP << 6); madctl |= (BGR << 3); - if (vflip) { + if (hflip) { // Row Address Order (MY) madctl ^= (1 << 7); } - if (hflip) { + if (vflip) { // Column Address Order (MX) madctl ^= (1 << 6); } @@ -135,7 +86,7 @@ * @param xs start address * @param xe end address */ -static void caset(uint16_t xs, uint16_t xe) { +static void caset(x_t xs, x_t xe) { displaySel(); displayCmd(CASET); displayData(xs >> 8); @@ -151,7 +102,7 @@ * @param ys start address * @param ye end address */ -static void raset(uint16_t ys, uint16_t ye) { +static void raset(y_t ys, y_t ye) { displaySel(); displayCmd(RASET); displayData(ys >> 8); @@ -210,6 +161,10 @@ printString("done initializing display\r\n"); } +void demoDisplay(void) { + // TODO +} + void writeStart(void) { // Memory write displaySel(); @@ -217,6 +172,10 @@ displaySetData(); } +void writeRestart(void) { + displaySel(); +} + void writeByte(uint8_t byte) { // Memory write transmit(byte); @@ -227,20 +186,20 @@ displayDes(); } -void fillArea(row_t row, col_t col, +void fillArea(x_t x, x_t y, width_t width, height_t height, uint16_t color) { madctl(false, false); // X address start/end - uint16_t xs = col; - uint16_t xe = col + width - 1; + uint16_t xs = x; + uint16_t xe = x + width - 1; caset(xs, xe); // Y address start/end - uint16_t ys = row; - uint16_t ye = row + height - 1; + uint16_t ys = y; + uint16_t ye = y + height - 1; raset(ys, ye); writeStart(); @@ -254,27 +213,27 @@ writeEnd(); } -void setArea(row_t row, col_t col, +void setArea(x_t x, y_t y, width_t width, height_t height, bool hflip, bool vflip) { madctl(hflip, vflip); // X address start/end - uint16_t xs = col; - uint16_t xe = col + width - 1; - if (vflip) { - xs = DISPLAY_WIDTH - col - width; - xe = DISPLAY_WIDTH - col - 1; + uint16_t xs = x; + uint16_t xe = x + width - 1; + if (hflip) { + xs = DISPLAY_WIDTH - x - width; + xe = DISPLAY_WIDTH - x - 1; } caset(xs, xe); // Y address start/end - uint16_t ys = row; - uint16_t ye = row + height - 1; - if (hflip) { - ys = DISPLAY_HEIGHT - row - height; - ye = DISPLAY_HEIGHT - row - 1; + uint16_t ys = y; + uint16_t ye = y + height - 1; + if (vflip) { + ys = DISPLAY_HEIGHT - y - height; + ye = DISPLAY_HEIGHT - y - 1; } raset(ys, ye); } @@ -283,36 +242,8 @@ width_t width, height_t height, space_t space) { writeStart(); - - switch (space) { - case SPACE_MONO1: { - bytes_t bytes = width * height / 8; - for (uint16_t i = 0; i < bytes; i++) { - uint8_t rgb[16]; - mono1ToRGB16(bitmap[i], rgb); - for (uint8_t j = 0; j < 16; j++) { - transmit(rgb[j]); - } - } - }; break; - case SPACE_GREY4: { - bytes_t bytes = width * height / 2; - for (uint16_t i = 0; i < bytes; i++) { - uint8_t rgb[4]; - grey4ToRGB16(bitmap[i], rgb); - for (uint8_t j = 0; j < 4; j++) { - transmit(rgb[j]); - } - } - }; break; - default: { - // SPACE_RGB16 - bytes_t bytes = width * height * 2; - for (uint16_t i = 0; i < bytes; i++) { - transmit(bitmap[i]); - } - } - } - + writeSpace(bitmap, width, height, space); writeEnd(); } + +#endif /* DRIVER */ diff --git a/tft.h b/tft.h index 7f359c4..8d83425 100644 --- a/tft.h +++ b/tft.h @@ -8,8 +8,16 @@ #ifndef TFT_H #define TFT_H +#include +#include #include +#include +#include #include "types.h" +#include "pins.h" +#include "usart.h" +#include "spi.h" +#include "colorspace.h" #define SWRESET 0x01 #define SLPIN 0x10 @@ -48,22 +56,27 @@ #define VFLIP 0 #endif -// TODO use enum? typedef? -#define SPACE_MONO1 1 -#define SPACE_GREY4 4 -#define SPACE_RGB16 16 - /** * Initializes the display. */ void initDisplay(void); /** + * Displays a demo. + */ +void demoDisplay(void); + +/** * Sets to write data to display RAM. */ void writeStart(void); /** + * Restart writing to display after SPI deselecting it. + */ +void writeRestart(void); + +/** * Writes the given byte to display RAM. * * @param byte @@ -78,27 +91,27 @@ /** * Sets the given color in the given area of the display. * - * @param row row in pixels, origin top left - * @param col column in pixels, origin top left + * @param x in pixels, origin top left + * @param y in pixels, origin top left * @param width width in pixels * @param height height in pixels * @param color 16-Bit (5/6/5) RGB color */ -void fillArea(row_t row, col_t col, +void fillArea(x_t x, y_t y, width_t width, height_t height, uint16_t color); /** * Sets the area to write image data to. * - * @param row row in pixels, origin top left - * @param col column in pixels, origin top left + * @param x in pixels, origin top left + * @param y in pixels, origin top left * @param width width of the bitmap in pixels * @param height height of the bitmap in pixels * @param hflip if image should be flipped horizontally * @param vflip if image should be flipped vertically */ -void setArea(row_t row, col_t col, +void setArea(x_t x, y_t y, width_t width, height_t height, bool hflip, bool vflip); diff --git a/touch.c b/touch.c index cd35383..d09306a 100644 --- a/touch.c +++ b/touch.c @@ -5,11 +5,13 @@ * Created on 12. Dezember 2023, 23:44 */ -#include +#if DRIVER == 0 + #include "touch.h" -#include "i2c.h" -#include "tft.h" -#include "usart.h" + +bool isTouch(void) { + return true; +} uint8_t readTouch(Point *point) { i2cStart(); @@ -41,12 +43,18 @@ i2cStop(); - if (!VFLIP) { + if (!HFLIP) { point->x = DISPLAY_WIDTH - point->x; } - if (HFLIP) { + if (VFLIP) { point->y = DISPLAY_HEIGHT - point->y; } return eventFlag; } + +void clearTouch(void) { + // no-op +} + +#endif /* DRIVER */ \ No newline at end of file diff --git a/touch.h b/touch.h index 7a8d470..0239979 100644 --- a/touch.h +++ b/touch.h @@ -5,7 +5,11 @@ * Created on 12. Dezember 2023, 23:44 */ +#include #include "types.h" +#include "i2c.h" +#include "tft.h" +#include "usart.h" #ifndef TOUCH_H #define TOUCH_H @@ -19,6 +23,13 @@ #define EVENT_NO_EVENT 3 /** + * Returns true if there was a touch event, false otherwise. + * + * @return true if touch event + */ +bool isTouch(void); + +/** * Reads the current touch position into the given point and returns * the touch event. * @@ -30,4 +41,9 @@ */ uint8_t readTouch(Point *point); +/** + * Clears the touch event. + */ +void clearTouch(void); + #endif /* TOUCH_H */ diff --git a/types.h b/types.h index 726a167..af5ebfd 100644 --- a/types.h +++ b/types.h @@ -9,6 +9,7 @@ #define TYPES_H #include +#include /* Width, height and color space of bitmaps and glyphs */ typedef uint16_t width_t; @@ -18,9 +19,9 @@ /* Width * height * bytes per pixel */ typedef uint32_t bytes_t; -/* Number of rows and columns of the display */ -typedef uint16_t row_t; -typedef uint16_t col_t; +/* X and Y coordinates of the display */ +typedef uint16_t x_t; +typedef uint16_t y_t; /* Char code (like UTF-8 code point) */ typedef uint8_t code_t; diff --git a/usart.c b/usart.c index 26f9aad..18c9d12 100644 --- a/usart.c +++ b/usart.c @@ -5,14 +5,7 @@ * Author: dode@luniks.net */ -#include -#include -#include -#include -#include #include "usart.h" -#include "utils.h" -#include "bmp.h" static volatile bool usartReceived = false; static volatile bool streaming = false; diff --git a/usart.h b/usart.h index 52ac1c6..a73f286 100644 --- a/usart.h +++ b/usart.h @@ -8,8 +8,14 @@ #ifndef USART_H_ #define USART_H_ -#include #include +#include +#include +#include +#include +#include +#include "utils.h" +#include "bmp.h" #define USART_LENGTH 128