diff --git a/README.md b/README.md index 647a11d..aa2550c 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,31 @@ # AVRTFT -Project to drive a TFT LCD like the +Simple project to drive a TFT LCD like the [Adafruit 1.8" Color TFT LCD 160x128 ST7735R](https://www.adafruit.com/product/358) with an AVR MCU (ATmega328P) and avr-libc. Currently implemented: -* Nearly complete UTF-8 set (code points U+0000 to U+00FF) of GNU Unifont +* Mostly complete UTF-8 set (code points U+0000 to U+00FF) of Hack font + with antialiasing (4-Bit greyscale) * Small subset of large glyphs in DejaVu: 0-9 and some special characters -* Store font and bitmaps in program memory instead of RAM -* Draw strings in Unifont and DejaVu -* Draw bitmaps +* Draw strings in Hack and DejaVu +* Draw bitmaps (emojis) * Write text and bitmaps via USART * Logging via USART +Ideas: + +* Write pictures via USART (probably too slow) +* Read pictures from SD Card +* Display 4K@50Hz videos... + ## Write something via USART Connect to the controller with for example GTKTerm (9600 Baud). Write some text and a bitmap: -TODO... \ No newline at end of file +`c 0xffff` // clear display +`t 0 0 h Just some text` // write text in Hack to row 0 column 0 +`b 0 112` // write bitmap with index 0 ('blush' emoji) to row 0 column 224 +`d` // display the demo diff --git a/avrtft.c b/avrtft.c index 2852e96..1ccd29f 100644 --- a/avrtft.c +++ b/avrtft.c @@ -69,7 +69,8 @@ * Enables SPI master mode. */ static void initSPI(void) { - SPCR |= (1 << SPR0); + // min speed for a cool visual effect :-) + // SPCR |= (1 << SPR1) | (1 << SPR0); SPCR |= (1 << MSTR); SPCR |= (1 << SPE); } diff --git a/cmd.c b/cmd.c index d6761ba..69040ac 100644 --- a/cmd.c +++ b/cmd.c @@ -17,13 +17,13 @@ #include "bitmaps.h" /** - * Sets the frame buffer to black (0xff) or white (0x00). + * Sets the frame buffer to the given 16-Bit (5/6/5) RGB color. * @param data */ static void clear(char *data) { strtok(data, " "); char *end; - uint8_t color = strtol(strtok(NULL, " "), &end, 16); + uint16_t color = strtol(strtok(NULL, " "), &end, 16); setFrame(color); } @@ -33,21 +33,21 @@ * @param data */ static void text(char *data) { -// strtok(data, " "); -// char *end; -// uint16_t row = strtol(strtok(NULL, " "), &end, 10); -// uint16_t col = strtol(strtok(NULL, " "), &end, 10); -// char *font = strtok(NULL, " "); -// char *text = strtok(NULL, "\0"); -// -// const __flash Font *unifont = &unifontFont; -// const __flash Font *dejavu = &dejaVuFont; -// -// switch(*font) { -// case FONT_UNIFONT: writeString(row, col, unifont, text); break; -// case FONT_DEJAVU: writeString(row, col, dejavu, text); break; -// default: break; -// } + strtok(data, " "); + char *end; + row_t row = strtol(strtok(NULL, " "), &end, 10); + col_t col = strtol(strtok(NULL, " "), &end, 10); + char *font = strtok(NULL, " "); + char *text = strtok(NULL, "\0"); + + const __flash Font *hack = &hackFont; + // const __flash Font *dejavu = &dejaVuFont; + + switch(*font) { + case FONT_HACK: writeString(row, col, hack, text); break; + // case FONT_DEJAVU: writeString(row, col, dejavu, text); break; + default: break; + } } /** @@ -57,8 +57,8 @@ static void bitmap(char *data) { strtok(data, " "); char *end; - uint16_t row = strtol(strtok(NULL, " "), &end, 10); - uint16_t col = strtol(strtok(NULL, " "), &end, 10); + row_t row = strtol(strtok(NULL, " "), &end, 10); + col_t col = strtol(strtok(NULL, " "), &end, 10); uint8_t index = strtol(strtok(NULL, " "), &end, 10); writeBitmap(row, col, index); @@ -68,7 +68,6 @@ * Writes the Hack demo. */ static void demo(void) { - setFrame(0x00); hackDemo(); writeBitmap(0, 88, BLUSH); } diff --git a/cmd.h b/cmd.h index f1b3515..8630e10 100644 --- a/cmd.h +++ b/cmd.h @@ -8,7 +8,7 @@ #ifndef CMD_H #define CMD_H -/** Clear frame buffer: 'c <0xff|0x00>'. */ +/** Clear frame buffer: 'c <0x0000 - 0xffff>'. */ #define CMD_CLEAR 'c' /** Display one line of text: 't '. */ #define CMD_TEXT 't' @@ -16,10 +16,8 @@ #define CMD_BITMAP 'b' /** Display Unifont demo: 'd'. */ #define CMD_DEMO 'd' -/** Update display (full or fast mode): 'u <0|1>'. */ -#define CMD_UPDATE 'u' -#define FONT_UNIFONT 'u' +#define FONT_HACK 'h' #define FONT_DEJAVU 'd' /** diff --git a/display.c b/display.c index 9264149..3e5a6f3 100644 --- a/display.c +++ b/display.c @@ -12,27 +12,28 @@ #include #include "display.h" #include "hack.h" -// #include "dejavu.h" +#include "dejavu.h" #include "bitmaps.h" #include "spi.h" #include "tft.h" #include "usart.h" #include "utils.h" -void setFrame(uint8_t byte) { - +void setFrame(uint16_t color) { + setDisplay(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, color); } width_t writeBitmap(row_t row, col_t col, uint16_t index) { const __flash Bitmap *bitmap = &bitmaps[index]; - writeDisplay(row, col, bitmap->bitmap, bitmap->width, bitmap->height, COLOR_RGB16); + writeDisplay(row, col, bitmap->bitmap, bitmap->width, bitmap->height, SPACE_RGB16); return bitmap->width; } width_t writeGlyph(row_t row, col_t col, const __flash Font *font, code_t code) { const __flash Glyph *glyph = getGlyphAddress(font, code); - writeDisplay(row, col, glyph->bitmap, glyph->width, font->height, COLOR_GREY4); + // TODO handle DejaVu font with 1-Bit B/W colors + writeDisplay(row, col, glyph->bitmap, glyph->width, font->height, SPACE_GREY4); return glyph->width; } diff --git a/display.h b/display.h index 631874c..74830d4 100644 --- a/display.h +++ b/display.h @@ -12,7 +12,11 @@ #include "bitmaps.h" #include "font.h" -void setFrame(uint8_t byte); +/** + * Sets the whole display to the given 16-Bit (5/6/5) RGB color. + * @param color + */ +void setFrame(uint16_t color); /** * Writes the bitmap with the given index to the given row and column diff --git a/nbproject/Makefile-Custom.mk b/nbproject/Makefile-Custom.mk index fef7c59..b7ff1e6 100644 --- a/nbproject/Makefile-Custom.mk +++ b/nbproject/Makefile-Custom.mk @@ -36,15 +36,11 @@ # Object Files OBJECTFILES= \ ${OBJECTDIR}/_ext/48b9b4a1/avrtft.o \ - ${OBJECTDIR}/_ext/48b9b4a1/bitmaps.o \ - ${OBJECTDIR}/_ext/48b9b4a1/cmd.o \ - ${OBJECTDIR}/_ext/48b9b4a1/dejavu.o \ ${OBJECTDIR}/_ext/48b9b4a1/display.o \ ${OBJECTDIR}/_ext/48b9b4a1/font.o \ ${OBJECTDIR}/_ext/48b9b4a1/spi.o \ ${OBJECTDIR}/_ext/48b9b4a1/tft.o \ - ${OBJECTDIR}/_ext/48b9b4a1/unifont.o \ - ${OBJECTDIR}/_ext/48b9b4a1/usart.o + ${OBJECTDIR}/hack.o # C Compiler Flags @@ -75,18 +71,6 @@ ${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 -${OBJECTDIR}/_ext/48b9b4a1/bitmaps.o: /home/dode/dev/avrtft/bitmaps.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/bitmaps.o /home/dode/dev/avrtft/bitmaps.c - -${OBJECTDIR}/_ext/48b9b4a1/cmd.o: /home/dode/dev/avrtft/cmd.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/cmd.o /home/dode/dev/avrtft/cmd.c - -${OBJECTDIR}/_ext/48b9b4a1/dejavu.o: /home/dode/dev/avrtft/dejavu.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/dejavu.o /home/dode/dev/avrtft/dejavu.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 @@ -103,13 +87,9 @@ ${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 -${OBJECTDIR}/_ext/48b9b4a1/unifont.o: /home/dode/dev/avrtft/unifont.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/unifont.o /home/dode/dev/avrtft/unifont.c - -${OBJECTDIR}/_ext/48b9b4a1/usart.o: /home/dode/dev/avrtft/usart.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/usart.o /home/dode/dev/avrtft/usart.c +${OBJECTDIR}/hack.o: hack.c + ${MKDIR} -p ${OBJECTDIR} + $(COMPILE.c) -g -DBAUD=9600 -DF_CPU=8000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -std=c99 -o ${OBJECTDIR}/hack.o hack.c # Subprojects .build-subprojects: diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index 4100e30..5caa0f3 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -3,15 +3,11 @@ avrtft.c - bitmaps.c - cmd.c - dejavu.c display.c font.c + hack.c spi.c tft.c - unifont.c - usart.c - - - - - - @@ -62,9 +52,7 @@ - - - + diff --git a/tft.c b/tft.c index a82876b..41d7358 100644 --- a/tft.c +++ b/tft.c @@ -121,10 +121,9 @@ printString("done initializing display\r\n"); } -void writeDisplay(uint16_t row, uint16_t col, - const __flash uint8_t *bitmap, +void setDisplay(uint16_t row, uint16_t col, width_t width, height_t height, - uint8_t color) { + uint16_t color) { // CASET uint16_t ys = col; @@ -153,15 +152,56 @@ displayCmd(RAMWR); displaySetData(); - if (color == COLOR_RGB16) { - uint16_t bytes = width * height * 2; + bytes_t bytes = width * height; + for (uint16_t i = 0; i < bytes; i++) { + transmit(color >> 8); + transmit(color); + } + + displayDes(); +} + +void writeDisplay(uint16_t row, uint16_t col, + const __flash uint8_t *bitmap, + width_t width, height_t height, + uint8_t space) { + + // CASET + uint16_t ys = col; + uint16_t ye = col + width - 1; + displaySel(); + displayCmd(CASET); + displayData(ys >> 8); + displayData(ys); + displayData(ye >> 8); + displayData(ye); + displayDes(); + + // RASET + uint16_t xs = row; + uint16_t xe = row + height - 1; + displaySel(); + displayCmd(RASET); + displayData(xs >> 8); + displayData(xs); + displayData(xe >> 8); + displayData(xe); + displayDes(); + + // RAMWR + displaySel(); + displayCmd(RAMWR); + displaySetData(); + + if (space == SPACE_RGB16) { + bytes_t bytes = width * height * 2; for (uint16_t i = 0; i < bytes; i++) { transmit(bitmap[i]); } } - if (color == COLOR_GREY4) { - uint16_t bytes = width * height / 2; + if (space == SPACE_GREY4) { + bytes_t bytes = width * height / 2; for (uint16_t i = 0; i < bytes; i++) { uint8_t rgb[4]; fourBitGreyTo16BitRGB(bitmap[i], rgb); diff --git a/tft.h b/tft.h index 52c610d..ff769fc 100644 --- a/tft.h +++ b/tft.h @@ -25,8 +25,9 @@ #define DISPLAY_WIDTH 160 #define DISPLAY_HEIGHT 128 -#define COLOR_GREY4 0 -#define COLOR_RGB16 1 +// TODO use enum? typedef? +#define SPACE_GREY4 0 +#define SPACE_RGB16 1 /** * Sets display to send a command. @@ -40,11 +41,13 @@ /** * Sends the given command to the display. + * @param cmd */ void displayCmd(uint8_t cmd); /** * Sends the given data to the display. + * @param data */ void displayData(uint8_t data); @@ -54,11 +57,30 @@ void initDisplay(void); /** - * Writes image data to the display. + * 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 width width in pixels + * @param height height in pixels + * @param color 16-Bit (5/6/5) RGB color + */ +void setDisplay(uint16_t row, uint16_t col, + width_t width, height_t height, + uint16_t color); + +/** + * Writes image data to the given area of the display. + * @param row row in pixels, origin top left + * @param bitmap pointer to bitmap data in program memory + * @param col column in pixels, origin top left + * @param width width of the bitmap in pixels + * @param height height of the bitmap in pixels + * @param space color space of the bitmap */ void writeDisplay(uint16_t row, uint16_t col, const __flash uint8_t *bitmap, width_t width, height_t height, - uint8_t color); + uint8_t space); #endif /* TFT_H */ diff --git a/types.h b/types.h index 9e1ba8d..b1c1d38 100644 --- a/types.h +++ b/types.h @@ -9,18 +9,21 @@ #define TYPES_H /* Width and height of bitmaps and glyphs */ -typedef uint8_t width_t; -typedef uint8_t height_t; +typedef uint8_t width_t; +typedef uint8_t height_t; + +/* Width * height * bytes per pixel */ +typedef uint16_t bytes_t; /* Number of rows and columns of the display */ -typedef uint8_t row_t; -typedef uint8_t col_t; +typedef uint8_t row_t; +typedef uint8_t col_t; /* Char code (like UTF-8 code point) */ -typedef uint8_t code_t; +typedef uint8_t code_t; /* Number of glyphs of a font */ -typedef uint8_t length_t; +typedef uint8_t length_t; #endif /* TYPES_H */