35#define LOG_DOMAIN "display"
40#define M_PI 3.14159265358979323846
43static volatile uint32_t *spi0 = NULL;
48#define GPIO_MODE_OUTPUT 1
64 while (((spi0[0x64 / 4]) & 4) == 0) {
73 spi0[0x68 / 4] = data;
74 while (((spi0[0x64 / 4]) & 4) == 0) {
80 static uint8_t Byte[2];
81 Byte[0] = (data >> 8) & 0xFF;
82 Byte[1] = data & 0xFF;
84 spi0[0x68 / 4] = Byte[0];
85 spi0[0x68 / 4] = Byte[1];
87 while (((spi0[0x64 / 4]) & 4) == 0) {
93 static uint8_t Byte[4];
94 Byte[0] = (addr1 >> 8) & 0xFF;
95 Byte[1] = addr1 & 0xFF;
96 Byte[2] = (addr2 >> 8) & 0xFF;
97 Byte[3] = addr2 & 0xFF;
101 spi0[0x68 / 4] = Byte[0];
102 spi0[0x68 / 4] = Byte[1];
103 spi0[0x68 / 4] = Byte[2];
104 spi0[0x68 / 4] = Byte[3];
106 while (((spi0[0x64 / 4]) & 4) == 0) {
113 for (
int i = 0; i < size; i++) {
114 while (((spi0[0x64 / 4]) & 8) == 8) {
116 spi0[0x68 / 4] = (color >> 8) & 0xFF;
117 while (((spi0[0x64 / 4]) & 8) == 8) {
119 spi0[0x68 / 4] = (color)&0xFF;
121 while (((spi0[0x64 / 4]) & 4) == 0) {
129 for (
int i = 0; i < size; i++) {
130 while (((spi0[0x64 / 4]) & 8) == 8) {
132 spi0[0x68 / 4] = (
colors[i] >> 8) & 0xFF;
133 while (((spi0[0x64 / 4]) & 8) == 8) {
135 spi0[0x68 / 4] = (
colors[i]) & 0xFF;
139 while (((spi0[0x64 / 4]) & 4) == 0) {
165 printf(
"spi reset: %08X\n", spi0[0x40 / 4]);
166 spi0[0x40 / 4] = 0x0000000a;
168 printf(
"spi control: %08X\n", spi0[0x60 / 4]);
169 spi0[0x60 / 4] = (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1);
171 printf(
"spi control: %08X\n", spi0[0x60 / 4]);
173 printf(
"spi status: %08X\n", spi0[0x64 / 4]);
178 printf(
"spi control: %08X\n", spi0[0x60 / 4]);
180 printf(
"testing DISPLAY\n");
182 printf(
"LCD_CS=%d\n", LCD_CS);
190 printf(
"LCD_DC=%d", LCD_DC);
195 printf(
"LCD_RESET=%d", LCD_RESET);
197 if (LCD_RESET >= 0) {
209 printf(
"LCD_BL=%d", LCD_BL);
217 printf(
"LCD_MOSI=%d", LCD_MOSI);
219 printf(
"LCD_SCLK=%d\n", LCD_SCLK);
221 display->
_dc = LCD_DC;
222 display->
_bl = LCD_BL;
270 if (display->
_bl >= 0) {
281 pynq_error(
"display_destroy: display has not been initialized\n");
293 pynq_error(
"displayDrawPixel: display has not been initialized\n");
296 pynq_error(
"displayDrawPixel: x=%d y=%d outside screen boundaries\n", x, y);
298 uint16_t _x = x + display->
_offsetx;
299 uint16_t _y = y + display->
_offsety;
310 uint16_t size, uint16_t *
colors) {
312 pynq_error(
"displayDrawMultiPixels: display has not been initialized\n");
314 if (x > display->
_width || x + size > display->
_width ||
317 "displayDrawMultiPixels: x=%d y=%d size=%d outside screen boundaries\n",
321 uint16_t _x1 = x + display->
_offsetx;
322 uint16_t _x2 = _x1 + size;
323 uint16_t _y1 = y + display->
_offsety;
335 uint16_t x2, uint16_t y2, uint16_t color) {
337 pynq_error(
"displayDrawPixel: display has not been initialized\n");
341 pynq_error(
"displayDrawFillRect: x1=%d y1=%d x2=%d y2=%d outside screen "
347 uint16_t x1_temp = x1, x2_temp = x2;
348 uint16_t y1_temp = y1, y2_temp = y2;
360 uint16_t _x1 = x1 + display->
_offsetx;
361 uint16_t _x2 = x2 + display->
_offsetx;
362 uint16_t _y1 = y1 + display->
_offsety;
363 uint16_t _y2 = y2 + display->
_offsety;
370 for (
int i = _x1; i <= _x2; i++) {
371 uint16_t size = _y2 - _y1 + 1;
378 pynq_error(
"displayDisplayOff: display has not been initialized\n");
385 pynq_error(
"displayDisplayOn: display has not been initialized\n");
392 pynq_error(
"displayFillScreen: display has not been initialized\n");
399 uint16_t y2, uint16_t color) {
401 pynq_error(
"displayDrawLine: display has not been initialized\n");
404 pynq_error(
"displayDrawLine: x1=%d y1=%d outside screen boundaries\n", x1,
406 }
else if (x2 >= display->
_width || y2 >= display->
_height) {
407 pynq_error(
"displayDrawLine: x2=%d y2=%d outside screen boundaries\n", x2,
416 dx = (x2 > x1) ? x2 - x1 : x1 - x2;
417 dy = (y2 > y1) ? y2 - y1 : y1 - y2;
420 sx = (x2 > x1) ? 1 : -1;
421 sy = (y2 > y1) ? 1 : -1;
426 for (i = 0; i <= dx; i++) {
439 for (i = 0; i <= dy; i++) {
452 uint16_t y2, uint16_t color) {
454 pynq_error(
"displayDrawRect: display has not been initialized\n");
457 pynq_error(
"displayDrawRect: x1=%d y1=%d outside screen boundaries\n", x1,
459 }
else if (x2 >= display->
_width || y2 >= display->
_height) {
460 pynq_error(
"displayDrawRect: x2=%d y2=%d outside screen boundaries\n", x2,
470 uint16_t w, uint16_t h, uint16_t angle,
477 rd = -angle *
M_PI / 180.0;
480 x1 = (int)(xd * cos(rd) - yd * sin(rd) + xc);
481 y1 = (int)(xd * sin(rd) + yd * cos(rd) + yc);
484 x2 = (int)(xd * cos(rd) - yd * sin(rd) + xc);
485 y2 = (int)(xd * sin(rd) + yd * cos(rd) + yc);
489 x3 = (int)(xd * cos(rd) - yd * sin(rd) + xc);
490 y3 = (int)(xd * sin(rd) + yd * cos(rd) + yc);
493 x4 = (int)(xd * cos(rd) - yd * sin(rd) + xc);
494 y4 = (int)(xd * sin(rd) + yd * cos(rd) + yc);
497 pynq_error(
"displayDrawRectAngle: display has not been initialized\n");
500 pynq_error(
"displayDrawRectAngle: x1=%d y1=%d outside screen boundaries\n",
502 }
else if (x2 >= display->
_width || y2 >= display->
_height) {
503 pynq_error(
"displayDrawRectAngle: x2=%d y2=%d outside screen boundaries\n",
505 }
else if (x3 >= display->
_width || y3 >= display->
_height) {
506 pynq_error(
"displayDrawRectAngle: x3=%d y3=%d outside screen boundaries\n",
508 }
else if (x4 >= display->
_width || y4 >= display->
_height) {
509 pynq_error(
"displayDrawRectAngle: x4=%d y4=%d outside screen boundaries\n",
527 uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3,
530 pynq_error(
"displayDrawTriangle: display has not been initialized\n");
533 pynq_error(
"displayDrawRectAngle: x1=%d y1=%d outside screen boundaries\n",
535 }
else if (x2 >= display->
_width || y2 >= display->
_height) {
536 pynq_error(
"displayDrawRectAngle: x2=%d y2=%d outside screen boundaries\n",
538 }
else if (x3 >= display->
_width || y3 >= display->
_height) {
539 pynq_error(
"displayDrawRectAngle: x3=%d y3=%d outside screen boundaries\n",
554 uint16_t w, uint16_t h, uint16_t angle,
560 rd = -angle *
M_PI / 180.0;
563 x1 = (int)(xd * cos(rd) - yd * sin(rd) + xc);
564 y1 = (int)(xd * sin(rd) + yd * cos(rd) + yc);
568 x2 = (int)(xd * cos(rd) - yd * sin(rd) + xc);
569 y2 = (int)(xd * sin(rd) + yd * cos(rd) + yc);
572 x3 = (int)(xd * cos(rd) - yd * sin(rd) + xc);
573 y3 = (int)(xd * sin(rd) + yd * cos(rd) + yc);
576 pynq_error(
"displayDrawTriangleCenter: display has not been initialized\n");
579 pynq_error(
"displayDrawRectAngle: x1=%d y1=%d outside screen boundaries\n",
581 }
else if (x2 >= display->
_width || y2 >= display->
_height) {
582 pynq_error(
"displayDrawRectAngle: x2=%d y2=%d outside screen boundaries\n",
584 }
else if (x3 >= display->
_width || y3 >= display->
_height) {
585 pynq_error(
"displayDrawRectAngle: x3=%d y3=%d outside screen boundaries\n",
595 uint16_t r, uint16_t color) {
597 pynq_error(
"displayDrawCircle: display has not been initialized\n");
601 "displayDrawCircle: x_center=%d y_center=%d r=%d r cannot be 0\n",
602 x_center, y_center, r);
605 int x_max = x_center + r, x_min = x_center - r, y_max = y_center + r,
606 y_min = y_center - r;
608 if (x_max >= display->
_width || x_min < 0 || y_max >= display->
_height ||
610 pynq_error(
"displayDrawCircle: x_center=%d y_center=%d r=%d outside screen "
612 x_center, y_center, r);
628 if ((old_err = err) <= x)
630 if (old_err > y || err > x)
636 uint16_t y_center, uint16_t r, uint16_t color) {
638 pynq_error(
"displayDrawFillCircle: display has not been initialized\n");
642 "displayDrawFillCircle: x_center=%d y_center=%d r=%d r cannot be 0\n",
643 x_center, y_center, r);
646 int x_max = x_center + r, x_min = x_center - r, y_max = y_center + r,
647 y_min = y_center - r;
649 if (x_max >= display->
_width || x_min < 0 || y_max >= display->
_height ||
651 pynq_error(
"displayDrawFillCircle: x_center=%d y_center=%d r=%d outside "
652 "screen boundaries\n",
653 x_center, y_center, r);
669 y_center + y, color);
671 y_center + y, color);
673 ChangeX = (old_err = err) <= x;
676 if (old_err > y || err > x)
682 uint16_t x2, uint16_t y2, uint16_t r,
685 pynq_error(
"displayDrawRoundRect: display has not been initialized\n");
688 pynq_error(
"displayDrawRoundRect: x_center=%d x1=%d y1=%d r cannot be 0\n",
690 }
else if (x1 >= display->
_width || y1 >= display->
_height) {
691 pynq_error(
"displayDrawRoundRect: x1=%d y1=%d outside screen boundaries\n",
693 }
else if (x2 >= display->
_width || y2 >= display->
_height) {
694 pynq_error(
"displayDrawRoundRect: x2=%d y2=%d outside screen boundaries\n",
716 printf(
"x1=%d x2=%d delta=%d r=%d", x1, x2, x2 - x1, r);
718 printf(
"y1=%d y2=%d delta=%d r=%d", y1, y2, y2 - y1, r);
735 if ((old_err = err) <= x)
737 if (old_err > y || err > x)
742 printf(
"x1+r=%d x2-r=%d", x1 + r, x2 - r);
746 printf(
"y1+r=%d y2-r=%d", y1 + r, y2 - r);
751uint16_t
rgb_conv(uint16_t r, uint16_t g, uint16_t b) {
752 return (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
756 uint8_t ascii, uint16_t color) {
757 uint16_t xx, yy, bit, ofs;
758 unsigned char fonts[128];
759 unsigned char pw, ph;
762 bool rc =
GetFontx(fxs, ascii, fonts, &pw, &ph);
765 pynq_error(
"displayDrawChar: display has not been initialized\n");
769 printf(
"GetFontx rc=%d pw=%d ph=%d\n", rc, pw, ph);
773 pynq_error(
"displayDrawChar: cannot get font from font file\n");
778 if (x + pw >= display->
_width || y + ph >= display->
_height) {
779 pynq_error(
"displayDrawChar: x=%d y=%d for font height=%d width=%d and "
780 "direction=%d outside screen boundaries\n",
785 if (x + ph >= display->
_height || y + pw >= display->
_width) {
786 pynq_error(
"displayDrawChar: x=%d y=%d for font height=%d width=%d and "
787 "direction=%d outside screen boundaries\n",
792 if (x - pw <= 0 || y - ph <= 0) {
793 pynq_error(
"displayDrawChar: x=%d y=%d for font height=%d width=%d and "
794 "direction=%d outside screen boundaries\n",
799 if (x - ph <= 0 || y - pw <= 0) {
800 pynq_error(
"displayDrawChar: x=%d y=%d for font height=%d width=%d and "
801 "direction=%d outside screen boundaries\n",
807 int16_t xd1 = 0, yd1 = 0, xd2 = 0, yd2 = 0;
808 uint16_t xss = 0, yss = 0;
809 int16_t xsd = 0, ysd = 0, next = 0;
810 uint16_t x0 = 0, x1 = 0, y0 = 0, y1 = 0;
881 printf(
"xss=%d yss=%d\n", xss, yss);
885 for (h = 0; h < ph; h++) {
891 for (w = 0; w < ((pw + 4) / 8); w++) {
893 for (bit = 0; bit < 8; bit++) {
925 uint8_t *ascii, uint16_t color) {
926 int length = strlen((
char *)ascii);
928 pynq_error(
"displayDrawString: display has not been initialized\n");
931 printf(
"displayDrawString length=%d\n", length);
932 for (
int i = 0; i < length; i++) {
934 printf(
"ascii[%d]=%x x=%d y=%d\n", i, ascii[i], x, y);
957 pynq_error(
"displaySetFontDirection: display has not been initialized\n");
964 pynq_error(
"displaySetFontFill: display has not been initialized\n");
974 pynq_error(
"displaySetFontUnderLine: display has not been initialized\n");
982 pynq_error(
"displayUnsetFontUnderLine: display has not been initialized\n");
989 pynq_error(
"displayBacklightOff: display has not been initialized\n");
991 if (display->
_bl >= 0) {
998 pynq_error(
"displayBacklightOn: display has not been initialized\n");
1000 if (display->
_bl >= 0) {
1007 pynq_error(
"displayInversionOff: display has not been initialized\n");
1014 pynq_error(
"displayInversionOn: display has not been initialized\n");
void displayInit(display_t *display, int width, int height, int offsetx, int offsety)
void spi_master_init(display_t *display)
void display_destroy(display_t *display __attribute__((unused)))
gpio_level_t spi_to_gpio(spi_mode_t mode)
bool spi_master_write_command(display_t *display, uint8_t cmd)
bool spi_master_write_addr(display_t *display, uint16_t addr1, uint16_t addr2)
bool spi_master_write_color(display_t *display, uint16_t color, uint16_t size)
bool spi_master_write_data_word(display_t *display, uint16_t data)
bool spi_master_write_data_byte(display_t *display, uint8_t data)
bool spi_master_write_colors(display_t *display, uint16_t *colors, uint16_t size)
void displayDrawMultiPixels(display_t *display, uint16_t x, uint16_t y, uint16_t size, uint16_t *colors)
void gpio_set_level(const gpio_t pin, const gpio_level_t level)
void gpio_reset_pin(const gpio_t pin)
void gpio_set_direction(const gpio_t pin, const gpio_direction_t direction)
void switchbox_set_pin(const int32_t pin_number, const uint8_t pin_type)
void arm_shared_close(arm_shared *handle)
void * arm_shared_init(arm_shared *handle, const uint32_t address, const uint32_t length)
int displayDrawString(display_t *display, FontxFile *fx, uint16_t x, uint16_t y, uint8_t *ascii, uint16_t color)
Function to draw a string on the display.
void displayDrawFillRect(display_t *display, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
Draw a filled rectangle to the display.
void displaySetFontUnderLine(display_t *display, uint16_t color)
Turns on _font_underline in the display handle and sets the _font_underline_color to the specified co...
void displaySetFontDirection(display_t *display, uint16_t dir)
Changes the direction the characters will be printed.
void displayDrawTriangle(display_t *display, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color)
Draw a triangle without infill between the three given points in the given color.
void displaySetFontFill(display_t *display, uint16_t color)
Enables the _font_fill and sets the _font_fill_color in the display handle.
void displayDrawRect(display_t *display, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
Draw a filled rectangle.
void displayUnsetFontFill(display_t *display)
Sets the _font_fill parameter to false in the display handle, turns off the font fill.
void display_init(display_t *display)
Initialize the display display.
uint16_t rgb_conv(uint16_t r, uint16_t g, uint16_t b)
RGB conversion for generating a color.
void displayDisplayOff(display_t *display)
Turn off the display.
void displayDrawLine(display_t *display, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
Draw a line from two coordinates.
void displayInversionOff(display_t *display)
Turn off inversion of the colors.
void displayDrawRoundRect(display_t *display, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t r, uint16_t color)
Draw a rectangle with rounded angles.
void displayInversionOn(display_t *display)
Turn on inversion of the colors.
int displayDrawChar(display_t *display, FontxFile *fxs, uint16_t x, uint16_t y, uint8_t ascii, uint16_t color)
Draws a character on the given coordinates of the display.
void displayBacklightOn(display_t *display)
Turn on the display backlight.
void displayDrawCircle(display_t *display, uint16_t x_center, uint16_t y_center, uint16_t r, uint16_t color)
Draw a circle without infill on the display.
void displayFillScreen(display_t *display, uint16_t color)
Fill entire display with a single color using the ldcDrawFillRect function.
void displayBacklightOff(display_t *display)
Turn off the display backlight.
void displayDisplayOn(display_t *display)
Initialize DISPLAY screen.
void displayUnsetFontUnderLine(display_t *display)
Turns off _font_underline in the display handle.
void displayDrawPixel(display_t *display, uint16_t x, uint16_t y, uint16_t color)
Draw a single pixel to the display.
colors
Colors that can be used with the display.
void displayDrawRectAngle(display_t *display, uint16_t xc, uint16_t yc, uint16_t w, uint16_t h, uint16_t angle, uint16_t color)
Draws a rectangle with rounded corners at a specified angle on the display.
void displayDrawFillCircle(display_t *display, uint16_t x_center, uint16_t y_center, uint16_t r, uint16_t color)
Draw a circle with infill on the display.
void displayDrawTriangleCenter(display_t *display, uint16_t xc, uint16_t yc, uint16_t w, uint16_t h, uint16_t angle, uint16_t color)
Draws a triangle at a specified angle on the display.
bool GetFontx(FontxFile *fxs, uint8_t ascii, uint8_t *pGlyph, uint8_t *pw, uint8_t *ph)
Gets the glyph data for the specified ASCII character.
void sleep_msec(int msec)
Wait for msec milliseconds.
Struct representing a font file.
Internal type, do not use. Type of display that stores parameters for usage in different functions.
uint16_t _font_fill_color
uint16_t _font_underline_color