diff --git a/display.c b/display.c index d5e5dd0..a208d20 100644 --- a/display.c +++ b/display.c @@ -11,17 +11,6 @@ fillArea(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, color); } -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(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(x_t x, y_t y, uint16_t index) { const __flash Bitmap *bitmap = &bitmaps[index]; setArea(x, y, bitmap->width, bitmap->height, false, false); diff --git a/display.h b/display.h index 078b26f..13affa7 100644 --- a/display.h +++ b/display.h @@ -32,20 +32,6 @@ void setFrame(uint16_t color); /** - * Draws a rectangle with the given origin and dimensions, line thickness - * and color. - * - * @param x - * @param y - * @param width - * @param height - * @param thickness - * @param color - */ -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. * diff --git a/paint.c b/paint.c index a5da2fc..dfa108e 100644 --- a/paint.c +++ b/paint.c @@ -7,6 +7,9 @@ #include "paint.h" +#define THICKNESS 2 * fmax(1, DISPLAY_WIDTH / 320.0) +#define THICK_OFF (THICKNESS + 1) / 2; + static uint16_t colors[] = { 0xf800, 0x07e0, 0x001f, 0xffe0, 0xf81f, 0x07ff, @@ -15,8 +18,30 @@ static uint8_t tool = TOOL_FREE; static Point prev = {0}; static uint16_t color = 0x0; -static uint8_t thick = 3; // line thickness -static uint8_t thoff = 2; // offset to "center" point relative to thickness +static uint8_t thick = THICKNESS; // line thickness +static uint8_t thoff = THICK_OFF; // offset to "center" point relative to thickness + +/** + * Paints a rectangle with the given origin and dimensions, line thickness + * and color. + * + * @param x + * @param y + * @param width + * @param height + * @param thickness + * @param color + */ +static void paintRectangle(x_t x, y_t y, width_t width, height_t height, + uint8_t thickness, uint16_t color) { + width -= thickness; + height -= thickness; + + 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); +} /** * Paints the color selection. @@ -34,8 +59,8 @@ fillArea(DISPLAY_WIDTH - CTRL_WIDTH, 0, CTRL_WIDTH, CTRL_WIDTH * TOOL_COUNT, 0xffff); for (uint8_t i = 0; i < TOOL_COUNT; i++) { - drawRectangle(DISPLAY_WIDTH - CTRL_WIDTH, CTRL_WIDTH * i, - CTRL_WIDTH, CTRL_WIDTH + 1, 1, 0x0); + paintRectangle(DISPLAY_WIDTH - CTRL_WIDTH, CTRL_WIDTH * i, + CTRL_WIDTH, CTRL_WIDTH + 1, 1, 0x0); writeBitmap(DISPLAY_WIDTH - CTRL_WIDTH + BITMAP_PADDING, CTRL_WIDTH * i + BITMAP_PADDING, i); } @@ -51,8 +76,8 @@ paintTools(); // highlight default tool - drawRectangle(DISPLAY_WIDTH - CTRL_WIDTH, CTRL_WIDTH * tool, - CTRL_WIDTH, CTRL_WIDTH + 1, 2, 0x0); + paintRectangle(DISPLAY_WIDTH - CTRL_WIDTH, CTRL_WIDTH * tool, + CTRL_WIDTH, CTRL_WIDTH + 1, 2, 0x0); } void paintEvent(uint8_t event, Point *point) { @@ -62,28 +87,28 @@ uint8_t i = point->y / (CTRL_WIDTH + 1); // repaint colors, highlight and select color paintColors(); - drawRectangle(0, CTRL_WIDTH * i, - CTRL_WIDTH, CTRL_WIDTH, 2, 0x0); + paintRectangle(0, CTRL_WIDTH * i, + CTRL_WIDTH, CTRL_WIDTH, 2, 0x0); color = colors[i]; } - } else if (point->x > DISPLAY_WIDTH - CTRL_WIDTH - thoff) { + } else if (point->x > DISPLAY_WIDTH - CTRL_WIDTH - thoff - 1) { if (event == EVENT_PRESS_DOWN) { uint8_t i = point->y / (CTRL_WIDTH + 1); // tool selected if (i == TOOL_CLEAR) { // clear canvas - fillArea(CTRL_WIDTH, 0, DISPLAY_WIDTH - 2 * CTRL_WIDTH + 1, + fillArea(CTRL_WIDTH, 0, DISPLAY_WIDTH - 2 * CTRL_WIDTH, DISPLAY_HEIGHT, 0xffff); } else if (i == TOOL_THICK) { // increment line thickness - thick += 3; - if (thick > 12) thick = 3; + thick += THICKNESS; + if (thick > THICKNESS * 4) thick = THICKNESS; thoff = (thick + 1) / 2; } else if (i < TOOL_COUNT) { // repaint tools, highlight and select tool paintTools(); - drawRectangle(DISPLAY_WIDTH - CTRL_WIDTH, CTRL_WIDTH * i, - CTRL_WIDTH, CTRL_WIDTH + 1, 2, 0x0); + paintRectangle(DISPLAY_WIDTH - CTRL_WIDTH, CTRL_WIDTH * i, + CTRL_WIDTH, CTRL_WIDTH + 1, 2, 0x0); tool = i; } prev = (Point){-1}; @@ -124,8 +149,8 @@ x_t x2 = fmax(prev.x, point->x); x_t y2 = fmax(prev.y, point->y); - drawRectangle(x1 - thoff, y1 - thoff, - x2 - x1 + thick, y2 - y1 + thick, thick, color); + paintRectangle(x1 - thoff, y1 - thoff, + x2 - x1 + thick, y2 - y1 + thick, thick, color); // unset previous point and leave (for now) prev = (Point){-1}; return; @@ -133,4 +158,4 @@ } prev = *point; -} \ No newline at end of file +} diff --git a/ra8875.c b/ra8875.c index 6139c7b..bf37bca 100644 --- a/ra8875.c +++ b/ra8875.c @@ -162,6 +162,34 @@ regWrite(MWCR0, data); } +/** + * Sets given background color. + * + * @param color + */ +static void setBackground(uint16_t color) { + // red + regWrite(BGCR0, (color & 0xf800) >> 11); + // green + regWrite(BGCR1, (color & 0x07e0) >> 5); + // blue + regWrite(BGCR2, (color & 0x001f) >> 0); +} + +/** + * Sets given foreground color. + * + * @param color + */ +static void setForeground(uint16_t color) { + // red + regWrite(FGCR0, (color & 0xf800) >> 11); + // green + regWrite(FGCR1, (color & 0x07e0) >> 5); + // blue + regWrite(FGCR2, (color & 0x001f) >> 0); +} + void initDisplay(void) { spiSlow(); @@ -179,7 +207,7 @@ _delay_ms(1); // set pixel clock - regWrite(PCSR, 0x80 | 0x01); // 800x480: falling edge, system clock div by 2 + regWrite(PCSR, 0x80 | 0x01); // 800x480: falling edge, system clock/2 _delay_ms(20); // set 16-bit color depth, 8-bit MCU @@ -233,10 +261,10 @@ // 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 panel, wait 16384 clocks, system clock/32 + regWrite(TPCR0, 0x80 | 0x50 | 0x05); + // do not enable debounce for touch interrupt in auto mode + regWrite(TPCR1, 0x00); // enable touch interrupt regWrite(INTC1, 0x04); @@ -256,7 +284,7 @@ drawCircle(790, 470, 10, 0xffff); drawCircle(200, 240, 30, 0b1111100000000000); - drawCircle(400, 240, 30, 0b0000011111100000); + drawRectangle(370, 210, 60, 60, 0b0000011111100000); drawCircle(600, 240, 30, 0b0000000000011111); textMode(); @@ -266,24 +294,6 @@ 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); @@ -298,25 +308,42 @@ } 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 drawRectangle(x_t x, y_t y, width_t width, height_t height, + uint16_t color) { + regWrite(DLHSR0, x); + regWrite(DLHSR1, x >> 8); + + regWrite(DLVSR0, y); + regWrite(DLVSR1, y >> 8); + + regWrite(DLHER0, x + width - 1); + regWrite(DLHER1, (x + width - 1) >> 8); + + regWrite(DLVER0, y + height - 1); + regWrite(DLVER1, (y + height - 1) >> 8); + + setForeground(color); + + regWrite(DCR, 0x80 | 0x20 | 0x10); + + 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); @@ -357,8 +384,29 @@ void fillArea(x_t x, y_t y, width_t width, height_t height, uint16_t color) { - // FIXME - drawCircle(x, y, 10, 0x07e0); + regWrite(HDBE0, x); + regWrite(HDBE1, x >> 8); + + regWrite(VDBE0, y); + regWrite(VDBE1, y >> 8); // Bit 7 selects layer + + regWrite(BEWR0, width); + regWrite(BEWR1, width >> 8); + + regWrite(BEHR0, height); + regWrite(BEHR1, height >> 8); + + // use BTE function "Solid Fill" + regWrite(BECR1, 0x0c); + + setForeground(color); + + regWrite(BECR0, 0x80); + + waitBusy(); + + // reset active window to full screen + setActiveWindow(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1); } void setArea(x_t x, y_t y, @@ -391,7 +439,6 @@ return data & 0x04; } -// TODO calibration uint8_t readTouch(Point *point) { uint8_t tpxh = regRead(TPXH); uint8_t tpyh = regRead(TPYH); @@ -414,10 +461,18 @@ point->y = DISPLAY_HEIGHT - point->y; } + // simple calibration + point->x = point->x - (DISPLAY_WIDTH / 2 - point->x) / TOUCH_CAL_X; + point->y = point->y - (DISPLAY_HEIGHT / 2 - point->y) / TOUCH_CAL_Y; + + point->x = fmax(0, fmin(DISPLAY_WIDTH - 1, point->x)); + point->y = fmax(0, fmin(DISPLAY_HEIGHT - 1, point->y)); + return EVENT_PRESS_DOWN; } void clearTouch(void) { + _delay_ms(10); regWrite(INTC2, 0x04); } diff --git a/ra8875.h b/ra8875.h index 9eaf02c..91c6ce3 100644 --- a/ra8875.h +++ b/ra8875.h @@ -16,6 +16,9 @@ #include "usart.h" #include "spi.h" +#define TOUCH_CAL_X 9 +#define TOUCH_CAL_Y 4 + #define CMD_WRITE 0x80 #define STATUS_READ 0xc0 #define DATA_WRITE 0x00 @@ -69,6 +72,18 @@ #define CURV0 0x48 #define CURV1 0x49 +/* Block Transfer Engine (BTE) Control Registers */ +#define BECR0 0x50 +#define BECR1 0x51 +#define HDBE0 0x58 +#define HDBE1 0x59 +#define VDBE0 0x5a +#define VDBE1 0x5b +#define BEWR0 0x5c +#define BEWR1 0x5d +#define BEHR0 0x5e +#define BEHR1 0x5f + /* Background Color Registers */ #define BGCR0 0x60 #define BGCR1 0x61 @@ -103,6 +118,14 @@ /* Drawing Contol Registers */ #define DCR 0x90 +#define DLHSR0 0x91 +#define DLHSR1 0x92 +#define DLVSR0 0x93 +#define DLVSR1 0x94 +#define DLHER0 0x95 +#define DLHER1 0x96 +#define DLVER0 0x97 +#define DLVER1 0x98 #define DCHR0 0x99 #define DCHR1 0x9a #define DCVR0 0x9b @@ -123,39 +146,6 @@ #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 diff --git a/tft.c b/tft.c index 506ff49..bcc2f2c 100644 --- a/tft.c +++ b/tft.c @@ -165,6 +165,19 @@ // TODO } +void drawPixel(x_t x, y_t y, uint16_t color) { + // TODO +} + +void drawCircle(x_t x, y_t y, uint16_t radius, uint16_t color) { + // TODO +} + +void drawRectangle(x_t x, y_t y, width_t width, height_t height, + uint16_t color) { + // TODO +} + void writeStart(void) { // Memory write displaySel(); diff --git a/tft.h b/tft.h index 8d83425..12325f2 100644 --- a/tft.h +++ b/tft.h @@ -67,6 +67,37 @@ void demoDisplay(void); /** + * 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, with given 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); + +/** + * Draws a rectangle at given origin, with given width, height and color. + * + * @param x + * @param y + * @param width + * @param height + * @param color + */ +void drawRectangle(x_t x, y_t y, width_t width, height_t height, + uint16_t color); + +/** * Sets to write data to display RAM. */ void writeStart(void);