diff --git a/Makefile b/Makefile index 98ce364..7b6177b 100644 --- a/Makefile +++ b/Makefile @@ -3,13 +3,13 @@ # Simplified version from: https://github.com/hexagon5un/AVR-Programming MCU = atmega328p -F_CPU = 8000000 -BAUD = 9600 +F_CPU = 16000000 +BAUD = 38400 PROGRAMMER_TYPE = avrispmkII PROGRAMMER_ARGS = MAIN = avrtft.c -SRC = bitmaps.c cmd.c dejavu.c display.c tft.c font.c spi.c hack.c usart.c +SRC = bitmaps.c bmp.c cmd.c dejavu.c display.c tft.c font.c spi.c hack.c usart.c CC = avr-gcc OBJCOPY = avr-objcopy @@ -33,7 +33,7 @@ OBJ = $(SRC:.c=.o) OBJ = $(SRC:.S=.o) -$(TARGET).elf: bitmaps.h cmd.h dejavu.h display.h tft.h font.h pins.h \ +$(TARGET).elf: bitmaps.h bmp.h cmd.h dejavu.h display.h tft.h font.h pins.h \ spi.h types.h hack.h usart.h utils.h Makefile all: $(TARGET).hex diff --git a/README.md b/README.md index 82ec28d..1f969f0 100644 --- a/README.md +++ b/README.md @@ -12,22 +12,25 @@ * Draw strings in Hack and DejaVu * Draw bitmaps (emojis) * Write text and bitmaps via USART +* Stream BMP images via USART * Logging via USART Ideas: -* Write pictures via USART (probably too slow) * Read pictures from SD Card * Display 4K@50Hz videos... +The AVR is clocked with a crystal for reliable communication via USART. + ![IMG_20231118_225206](https://github.com/gitdode/avrtft/assets/11530253/747ad970-1306-48a2-8a7a-978977b5b7d4) ## Write something via USART Connect to the controller with for example GTKTerm (9600 Baud). -Write some text and a bitmap: +Write some text and a bitmap, and upload a BMP image: `c 0xffff` // clear display +`d` // display the demo `t 0 0 h Just some text` // write text in Hack to row 0 column 0 `b 0 112 0` // write bitmap with index 0 ('blush' emoji) to row 0 column 224 -`d` // display the demo +`p 0 0` // prepare to "stream" a 16-Bit (5/6/5) RGB BMP image diff --git a/avrtft.c b/avrtft.c index 1ccd29f..23373c2 100644 --- a/avrtft.c +++ b/avrtft.c @@ -5,7 +5,7 @@ * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, version 2. * - * Experimental project to drive a TFT display with an ST7735 driver. + * Experimental project to drive a TFT display with an ST7735R driver. * * Created on: 06.11.2023 * Author: torsten.roemer@luniks.net @@ -29,6 +29,7 @@ #include "bitmaps.h" #include "display.h" #include "utils.h" +#include "bmp.h" /* Timer0 interrupts per second */ #define INTS_SEC F_CPU / (256UL * 255) @@ -44,9 +45,6 @@ * Sets up the pins. */ static void initPins(void) { - // set LED pin as output pin - DDR_LED |= (1 << PIN_LED); - // set MOSI and SCK as output pin DDR_SPI |= (1 << PIN_MOSI); DDR_SPI |= (1 << PIN_SCK); @@ -86,21 +84,7 @@ OCR0A = 255; // enable timer0 compare match A interrupt - TIMSK0 |= (1 << OCIE0A); -} - -/** - * Turns the LED on. - */ -static void ledOn(void) { - PORT_LED |= (1 << PIN_LED); -} - -/** - * Turns the LED off. - */ -static void ledOff(void) { - PORT_LED &= ~(1 << PIN_LED); + // TIMSK0 |= (1 << OCIE0A); } int main(void) { @@ -113,24 +97,22 @@ // enable global interrupts sei(); + _delay_ms(1000); initDisplay(); while (true) { // show a demo once at the start - if (!once && ints >= INTS_SEC) { + if (!once) { // setFrame(0x00); hackDemo(); writeBitmap(0, 88, BLUSH); once = true; } - - if (ints >= INTS_SEC * 3) { - ints = 0; - ledOn(); - // do something and update the display - _delay_ms(100); - ledOff(); + + if (isStreaming() && bit_is_set(UCSR0A, RXC0)) { + char data = UDR0; + stream(data); } if (isUSARTReceived()) { diff --git a/bmp.c b/bmp.c new file mode 100644 index 0000000..b286cba --- /dev/null +++ b/bmp.c @@ -0,0 +1,165 @@ +/* + * File: bmp.h + * Author: dode + * + * Thanks to https://en.wikipedia.org/wiki/BMP_file_format + * + * Created on 22. November 2023, 23:10 + */ + +#include "bmp.h" +#include "display.h" +#include "tft.h" +#include "usart.h" +#include "hack.h" + +#define BUF_SIZE 4 + +static bool error = false; + +static row_t row = 0; +static col_t col = 0; + +static uint32_t buf[BUF_SIZE]; +static uint32_t offset = 0; +static uint32_t pixelStart = -1; +static uint32_t pixelEnd = -1; +// static uint32_t headerSize = 0; +static uint32_t bitmapWidth = 0; +static uint32_t bitmapHeight = 0; +static uint16_t bitsPerPixel = 0; +static uint32_t imageSize = 0; +// static uint16_t rowSize = 0; + +/** + * Pushes the given byte on the stack and the oldest off the stack. + * + * @param byte + */ +static void push(uint8_t byte) { + for (uint8_t i = BUF_SIZE; i-- > 1;) { + buf[i] = buf[i - 1]; + } + buf[0] = byte; +} + +void prepare(row_t srow, col_t scol) { + row = srow; + col = scol; + offset = 0; + setStreaming(true); +} + +void stream(uint8_t byte) { + if (error) { + // TODO recover from error condition + // setStreaming(false); + return; + } + push(byte); + + if (offset == 0x0 + 1) { + if (!(buf[1] == 0x42 && buf[0] == 0x4d)) { + // not a BMP + // TODO __flash + char *lines[] = { + "Not a BMP image or", + "transmission error" + }; + writeError(lines, 2); + error = true; + return; + } + } + + if (offset == 0x0a + 3) { + pixelStart = buf[0] << 24; + pixelStart = buf[1] << 16; + pixelStart = buf[2] << 8; + pixelStart = buf[3] << 0; + } + + /* + if (offset == 0x0e + 3) { + headerSize = buf[0] << 24; + headerSize = buf[1] << 16; + headerSize = buf[2] << 8; + headerSize = buf[3] << 0; + } + */ + + if (offset == 0x12 + 3) { + bitmapWidth = buf[0] << 24; + bitmapWidth = buf[1] << 16; + bitmapWidth = buf[2] << 8; + bitmapWidth = buf[3] << 0; + } + + if (offset == 0x16 + 3) { + bitmapHeight = buf[0] << 24; + bitmapHeight = buf[1] << 16; + bitmapHeight = buf[2] << 8; + bitmapHeight = buf[3] << 0; + } + + if (offset == 0x1c + 1) { + bitsPerPixel = buf[0] << 8; + bitsPerPixel = buf[1] << 0; + + if (bitsPerPixel != 16) { + // not a 16-Bit RGB BMP + // TODO __flash + char *lines[] = { + "Only 16-Bit (5/6/5)", + "RGB is supported" + }; + writeError(lines, 2); + error = true; + return; + } + } + + if (offset == 0x22) { + imageSize = bitmapWidth * bitmapHeight * bitsPerPixel / 8; + pixelEnd = pixelStart + imageSize; + // rowSize = ((bitsPerPixel * bitmapWidth + 31) / 32) * 4; + uint8_t padding = (bitmapWidth * bitmapHeight * 2) % 4; + + if (padding != 0) { + // row padding currently not supported + // TODO __flash + char *lines[] = { + "Only bitmaps where", + "(w * h * 2) % 4 = 0", + "are supported" + }; + writeError(lines, 3); + error = true; + return; + } + } + + if (offset == pixelStart) { + // do horizontal flip because pixel data in a BMP is bottom to top + setArea(row, col, bitmapWidth, bitmapHeight, true); + writeStart(); + } + + // TODO calculate number of pad bytes and discard them + if (offset < pixelEnd && offset >= pixelStart) { + // swap endianess + // TODO get rid of division + if ((offset - pixelStart) % 2) { + writeByte(buf[0]); + writeByte(buf[1]); + } + } + + offset++; + + if (offset == pixelEnd) { + writeEnd(); + setStreaming(false); + // printString("write end\r\n"); + } +} \ No newline at end of file diff --git a/bmp.h b/bmp.h new file mode 100644 index 0000000..b81d5a0 --- /dev/null +++ b/bmp.h @@ -0,0 +1,35 @@ +/* + * File: bmp.h + * Author: dode + * + * Created on 22. November 2023, 23:10 + */ + +#ifndef BMP_H +#define BMP_H + +#include +#include +#include "types.h" + +/** + * Prepares to "stream" a BMP image via USART to the display, + * with its upper left corner at the given coordinates. + * + * @param row + * @param col + */ +void prepare(row_t row, col_t col); + +/** + * Does basic parsing of the BMP image (16-Bit 5/6/5 RGB) sent via USART and + * sends the image pixels to the display. + * Image dimensions have to be '(w * h * 2) % 4 = 0' because padded rows + * are currently not supported. + * + * @param byte raw BMP byte recieved via USART + */ +void stream(uint8_t byte); + +#endif /* BMP_H */ + diff --git a/cats/Bali160x128.bmp b/cats/Bali160x128.bmp new file mode 100644 index 0000000..4c58819 --- /dev/null +++ b/cats/Bali160x128.bmp Binary files differ diff --git a/cats/Chico160x128.bmp b/cats/Chico160x128.bmp new file mode 100644 index 0000000..bc9928f --- /dev/null +++ b/cats/Chico160x128.bmp Binary files differ diff --git a/cats/Linus160x128.bmp b/cats/Linus160x128.bmp new file mode 100644 index 0000000..1a73679 --- /dev/null +++ b/cats/Linus160x128.bmp Binary files differ diff --git a/cats/Tamy160x128.bmp b/cats/Tamy160x128.bmp new file mode 100644 index 0000000..7497a91 --- /dev/null +++ b/cats/Tamy160x128.bmp Binary files differ diff --git a/cats/cats.sh b/cats/cats.sh new file mode 100755 index 0000000..d87a173 --- /dev/null +++ b/cats/cats.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +echo "c 0" > /dev/ttyUSB0 +sleep 1 +echo "t 20 12 h Katzen... " > /dev/ttyUSB0 +sleep 1 +echo "t 56 44 h Katzen... " > /dev/ttyUSB0 +sleep 1 +echo "t 92 80 h Katzen! " > /dev/ttyUSB0 + +sleep 1 +echo "p 0 0" > /dev/ttyUSB0 +cat Chico160x128.bmp > /dev/ttyUSB0 +sleep 3 +echo "p 0 0" > /dev/ttyUSB0 +cat Tamy160x128.bmp > /dev/ttyUSB0 +sleep 3 +echo "p 0 0" > /dev/ttyUSB0 +cat Linus160x128.bmp > /dev/ttyUSB0 +sleep 3 +echo "p 0 0" > /dev/ttyUSB0 +cat Bali160x128.bmp > /dev/ttyUSB0 diff --git a/cmd.c b/cmd.c index 69040ac..4cb6d9a 100644 --- a/cmd.c +++ b/cmd.c @@ -15,6 +15,7 @@ #include "hack.h" #include "dejavu.h" #include "bitmaps.h" +#include "bmp.h" /** * Sets the frame buffer to the given 16-Bit (5/6/5) RGB color. @@ -64,6 +65,15 @@ writeBitmap(row, col, index); } +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); + + prepare(row, col); +} + /** * Writes the Hack demo. */ @@ -79,6 +89,7 @@ case CMD_CLEAR: clear(data); break; case CMD_TEXT: text(data); break; case CMD_BITMAP: bitmap(data); break; + case CMD_BMP: bmp(data); break; case CMD_DEMO: demo(); break; default: break; } diff --git a/cmd.h b/cmd.h index 8630e10..6ee166b 100644 --- a/cmd.h +++ b/cmd.h @@ -10,11 +10,17 @@ /** Clear frame buffer: 'c <0x0000 - 0xffff>'. */ #define CMD_CLEAR 'c' + /** Display one line of text: 't '. */ #define CMD_TEXT 't' + /** Display a bitmap: 'b '. */ #define CMD_BITMAP 'b' -/** Display Unifont demo: 'd'. */ + +/** Prepare "streaming" a .bmp: 'p '. */ +#define CMD_BMP 'p' + +/** Display Hack demo: 'd'. */ #define CMD_DEMO 'd' #define FONT_HACK 'h' diff --git a/display.c b/display.c index 3e5a6f3..e34fb44 100644 --- a/display.c +++ b/display.c @@ -20,12 +20,21 @@ #include "utils.h" void setFrame(uint16_t color) { - setDisplay(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, color); + fillArea(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, color); +} + +void writeError(char *lines[], uint8_t length) { + setFrame(0xffff); + const __flash Font *hack = &hackFont; + for (uint8_t i = 0; i < length; i++) { + writeString(i * hack->height, 0, hack, lines[i]); + } } 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, SPACE_RGB16); + setArea(row, col, bitmap->width, bitmap->height, false); + writeData(bitmap->bitmap, bitmap->width, bitmap->height, SPACE_RGB16); return bitmap->width; } @@ -33,7 +42,8 @@ width_t writeGlyph(row_t row, col_t col, const __flash Font *font, code_t code) { const __flash Glyph *glyph = getGlyphAddress(font, code); // TODO handle DejaVu font with 1-Bit B/W colors - writeDisplay(row, col, glyph->bitmap, glyph->width, font->height, SPACE_GREY4); + setArea(row, col, glyph->width, font->height, false); + writeData(glyph->bitmap, glyph->width, font->height, SPACE_GREY4); return glyph->width; } diff --git a/display.h b/display.h index 74830d4..e971193 100644 --- a/display.h +++ b/display.h @@ -14,13 +14,23 @@ /** * Sets the whole display to the given 16-Bit (5/6/5) RGB color. + * * @param color */ void setFrame(uint16_t color); /** + * Writes the given lines of text to the top left corner of the display. + * + * @param lines text + * @param length number of lines + */ +void writeError(char *lines[], uint8_t length); + +/** * 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 index @@ -31,6 +41,7 @@ /** * 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 (8 pixels) * @param col (1 pixel) * @param font @@ -41,6 +52,7 @@ /** * Writes the given string with the given font to the given row and column. + * * @param row (8 pixels) * @param col (1 pixel) * @param font diff --git a/nbproject/Makefile-Custom.mk b/nbproject/Makefile-Custom.mk index b7ff1e6..32bd2b3 100644 --- a/nbproject/Makefile-Custom.mk +++ b/nbproject/Makefile-Custom.mk @@ -38,9 +38,10 @@ ${OBJECTDIR}/_ext/48b9b4a1/avrtft.o \ ${OBJECTDIR}/_ext/48b9b4a1/display.o \ ${OBJECTDIR}/_ext/48b9b4a1/font.o \ + ${OBJECTDIR}/_ext/48b9b4a1/hack.o \ ${OBJECTDIR}/_ext/48b9b4a1/spi.o \ ${OBJECTDIR}/_ext/48b9b4a1/tft.o \ - ${OBJECTDIR}/hack.o + ${OBJECTDIR}/bmp.o # C Compiler Flags @@ -79,6 +80,10 @@ ${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 +${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 + ${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 @@ -87,9 +92,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}/hack.o: hack.c +${OBJECTDIR}/bmp.o: bmp.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 + $(COMPILE.c) -g -DBAUD=9600 -DF_CPU=8000000UL -D__AVR_ATmega328P__ -D__flash=volatile -I. -o ${OBJECTDIR}/bmp.o bmp.c # Subprojects .build-subprojects: diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index 5caa0f3..828cd08 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -3,6 +3,8 @@ avrtft.c + bmp.c + bmp.h display.c font.c hack.c @@ -48,11 +50,15 @@ + + - + + + diff --git a/pins.h b/pins.h index 5aa7f17..ae5a832 100644 --- a/pins.h +++ b/pins.h @@ -10,11 +10,6 @@ #include -/* LED pins */ -#define DDR_LED DDRC -#define PORT_LED PORTC -#define PIN_LED PC5 - /* SPI */ #define DDR_SPI DDRB #define PORT_SPI PORTB diff --git a/tft.c b/tft.c index 6d644f6..aaee31f 100644 --- a/tft.c +++ b/tft.c @@ -82,45 +82,42 @@ } void initDisplay(void) { + // Hardware reset hwReset(); + // TODO necessary? _delay_ms(120); - // SWRESET + // Software reset displaySel(); displayCmd(SWRESET); displayDes(); + // TODO necessary? _delay_ms(120); - // SLPOUT + // Sleep out & booster on displaySel(); displayCmd(SLPOUT); displayDes(); - // NORON + // Partial off (Normal) displaySel(); displayCmd(NORON); displayDes(); - // COLMOD + // Interface pixel format displaySel(); displayCmd(COLMOD); displayData(0b00111101); displayDes(); - - // MADCTL - displaySel(); - displayCmd(MADCTL); - displayData(0b01110110); - displayDes(); - // DISPON + // Display on displaySel(); displayCmd(DISPON); displayDes(); - // SLPIN + // Sleep in & booster off // displaySel(); // displayCmd(SLPIN); // displayDes(); @@ -128,33 +125,33 @@ printString("done initializing display\r\n"); } -void setDisplay(uint16_t row, uint16_t col, - width_t width, height_t height, - uint16_t color) { +void fillArea(row_t row, col_t col, + width_t width, height_t height, + uint16_t color) { - // CASET - uint16_t ys = col; - uint16_t ye = col + width - 1; + // X address start/end + uint16_t xs = col; + uint16_t xe = 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 + // Y address start/end + uint16_t ys = row; + uint16_t ye = row + height - 1; + displaySel(); + displayCmd(RASET); + displayData(ys >> 8); + displayData(ys); + displayData(ye >> 8); + displayData(ye); + displayDes(); + + // Memory write displaySel(); displayCmd(RAMWR); displaySetData(); @@ -168,34 +165,51 @@ 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; +void setArea(row_t row, col_t col, + width_t width, height_t height, + bool hflip) { + + // Memory data access control + uint8_t madctl = 0b01110110; + if (hflip) { + madctl = 0b00110110; + } displaySel(); - displayCmd(CASET); - displayData(ys >> 8); - displayData(ys); - displayData(ye >> 8); - displayData(ye); + displayCmd(MADCTL); + displayData(madctl); displayDes(); - // RASET - uint16_t xs = row; - uint16_t xe = row + height - 1; + // X address start/end + uint16_t xs = col; + uint16_t xe = col + width - 1; displaySel(); - displayCmd(RASET); + displayCmd(CASET); displayData(xs >> 8); displayData(xs); displayData(xe >> 8); displayData(xe); displayDes(); - // RAMWR + // Y address start/end + uint16_t ys = row; + uint16_t ye = row + height - 1; + if (hflip) { + xs = DISPLAY_HEIGHT - row - height; + xe = DISPLAY_HEIGHT - row - 1; + } + displaySel(); + displayCmd(RASET); + displayData(ys >> 8); + displayData(ys); + displayData(ye >> 8); + displayData(ye); + displayDes(); +} + +void writeData(const __flash uint8_t *bitmap, + width_t width, height_t height, + uint8_t space) { + // Memory write displaySel(); displayCmd(RAMWR); displaySetData(); @@ -218,5 +232,22 @@ } } - displayDes(); + displayDes(); +} + +void writeStart(void) { + // Memory write + displaySel(); + displayCmd(RAMWR); + displaySetData(); +} + +void writeByte(uint8_t byte) { + // Memory write + transmit(byte); +} + +void writeEnd(void) { + // Memory write + displayDes(); } diff --git a/tft.h b/tft.h index ff769fc..21edebb 100644 --- a/tft.h +++ b/tft.h @@ -65,22 +65,50 @@ * @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); +void fillArea(row_t row, col_t col, + width_t width, height_t height, + uint16_t color); /** - * Writes image data to the given area of the display. + * Sets the area to write image data to. + * * @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 hflip if image should be flipped horizontally + */ +void setArea(row_t row, col_t col, + width_t width, height_t height, + bool hflip); + +/** + * Writes image data to the previously set area. + * + * @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 writeDisplay(uint16_t row, uint16_t col, - const __flash uint8_t *bitmap, - width_t width, height_t height, - uint8_t space); +void writeData(const __flash uint8_t *bitmap, + width_t width, height_t height, + uint8_t space); + +/** + * Sets to write data to display RAM. + */ +void writeStart(void); + +/** + * Writes the given byte to display RAM. + * + * @param byte + */ +void writeByte(uint8_t byte); + +/** + * Completes writing data to display RAM. + */ +void writeEnd(void); #endif /* TFT_H */ diff --git a/usart.c b/usart.c index 89287cb..e9d9d4e 100644 --- a/usart.c +++ b/usart.c @@ -12,16 +12,18 @@ #include #include "usart.h" #include "utils.h" +#include "bmp.h" static volatile bool usartReceived = false; +static volatile bool streaming = false; -static char usartData[USART_LENGTH]; +char usartData[USART_LENGTH]; /** * Called when data was received via USART. */ ISR(USART_RX_vect) { - if (bit_is_set(UCSR0A, RXC0) && !usartReceived) { + if (!usartReceived && bit_is_set(UCSR0A, RXC0)) { char data = UDR0; size_t length = strlen(usartData); if (length < USART_LENGTH - 1 && data != '\n' && data != '\r') { @@ -48,6 +50,19 @@ return usartReceived; } +void setStreaming(bool enabled) { + if (enabled) { + UCSR0B &= ~(1 << RXCIE0); + } else { + UCSR0B |= (1 << RXCIE0); + } + streaming = enabled; +} + +bool isStreaming(void) { + return streaming; +} + void getUSARTData(char *data, size_t size) { if (size > 0) { data[0] = '\0'; diff --git a/usart.h b/usart.h index bfa6c0e..568e6bc 100644 --- a/usart.h +++ b/usart.h @@ -11,7 +11,7 @@ #include #include -#define USART_LENGTH 73 +#define USART_LENGTH 128 #ifndef BAUD #define BAUD 9600 @@ -28,6 +28,21 @@ bool isUSARTReceived(void); /** + * Disable/enable accepting commands by disabling/enabling interrupts + * when data was received. + * + * @param enabled disable/enable commands. + */ +void setStreaming(bool enabled); + +/** + * Returns true if accepting commands is disabled, false otherwise. + * + * @return true if disabled, false otherwise + */ +bool isStreaming(void); + +/** * Appends the data received via USART to the given string with the given * length. */