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) {
276 if (display == NULL) {
277 pynq_error(
"display_destroy: display has not been initialized\n");
280 pynq_error(
"display_destroy: internal error (wrong display hardware)\n");
283 uint8_t set = (yflip << 7) | (xflip << 6);
304 pynq_error(
"display_destroy: display has not been initialized\n");
316 pynq_error(
"displayDrawPixel: display has not been initialized\n");
319 pynq_error(
"displayDrawPixel: x=%d y=%d outside screen boundaries\n", x, y);
321 uint16_t _x = x + display->
_offsetx;
322 uint16_t _y = y + display->
_offsety;
333 uint16_t size, uint16_t *
colors) {
335 pynq_error(
"displayDrawMultiPixels: display has not been initialized\n");
337 if (x > display->
_width || x + size > display->
_width ||
340 "displayDrawMultiPixels: x=%d y=%d size=%d outside screen boundaries\n",
344 uint16_t _x1 = x + display->
_offsetx;
345 uint16_t _x2 = _x1 + size;
346 uint16_t _y1 = y + display->
_offsety;
358 uint16_t x2, uint16_t y2, uint16_t color) {
360 pynq_error(
"displayDrawPixel: display has not been initialized\n");
364 pynq_error(
"displayDrawFillRect: x1=%d y1=%d x2=%d y2=%d outside screen "
370 uint16_t x1_temp = x1, x2_temp = x2;
371 uint16_t y1_temp = y1, y2_temp = y2;
383 uint16_t _x1 = x1 + display->
_offsetx;
384 uint16_t _x2 = x2 + display->
_offsetx;
385 uint16_t _y1 = y1 + display->
_offsety;
386 uint16_t _y2 = y2 + display->
_offsety;
393 for (
int i = _x1; i <= _x2; i++) {
394 uint16_t size = _y2 - _y1 + 1;
401 pynq_error(
"displayDisplayOff: display has not been initialized\n");
408 pynq_error(
"displayDisplayOn: display has not been initialized\n");
415 pynq_error(
"displayFillScreen: display has not been initialized\n");
422 uint16_t y2, uint16_t color) {
424 pynq_error(
"displayDrawLine: display has not been initialized\n");
427 pynq_error(
"displayDrawLine: x1=%d y1=%d outside screen boundaries\n", x1,
429 }
else if (x2 >= display->
_width || y2 >= display->
_height) {
430 pynq_error(
"displayDrawLine: x2=%d y2=%d outside screen boundaries\n", x2,
439 dx = (x2 > x1) ? x2 - x1 : x1 - x2;
440 dy = (y2 > y1) ? y2 - y1 : y1 - y2;
443 sx = (x2 > x1) ? 1 : -1;
444 sy = (y2 > y1) ? 1 : -1;
449 for (i = 0; i <= dx; i++) {
462 for (i = 0; i <= dy; i++) {
475 uint16_t y2, uint16_t color) {
477 pynq_error(
"displayDrawRect: display has not been initialized\n");
480 pynq_error(
"displayDrawRect: x1=%d y1=%d outside screen boundaries\n", x1,
482 }
else if (x2 >= display->
_width || y2 >= display->
_height) {
483 pynq_error(
"displayDrawRect: x2=%d y2=%d outside screen boundaries\n", x2,
493 uint16_t w, uint16_t h, uint16_t angle,
500 rd = -angle *
M_PI / 180.0;
503 x1 = (int)(xd * cos(rd) - yd * sin(rd) + xc);
504 y1 = (int)(xd * sin(rd) + yd * cos(rd) + yc);
507 x2 = (int)(xd * cos(rd) - yd * sin(rd) + xc);
508 y2 = (int)(xd * sin(rd) + yd * cos(rd) + yc);
512 x3 = (int)(xd * cos(rd) - yd * sin(rd) + xc);
513 y3 = (int)(xd * sin(rd) + yd * cos(rd) + yc);
516 x4 = (int)(xd * cos(rd) - yd * sin(rd) + xc);
517 y4 = (int)(xd * sin(rd) + yd * cos(rd) + yc);
520 pynq_error(
"displayDrawRectAngle: display has not been initialized\n");
523 pynq_error(
"displayDrawRectAngle: x1=%d y1=%d outside screen boundaries\n",
525 }
else if (x2 >= display->
_width || y2 >= display->
_height) {
526 pynq_error(
"displayDrawRectAngle: x2=%d y2=%d outside screen boundaries\n",
528 }
else if (x3 >= display->
_width || y3 >= display->
_height) {
529 pynq_error(
"displayDrawRectAngle: x3=%d y3=%d outside screen boundaries\n",
531 }
else if (x4 >= display->
_width || y4 >= display->
_height) {
532 pynq_error(
"displayDrawRectAngle: x4=%d y4=%d outside screen boundaries\n",
550 uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3,
553 pynq_error(
"displayDrawTriangle: display has not been initialized\n");
556 pynq_error(
"displayDrawRectAngle: x1=%d y1=%d outside screen boundaries\n",
558 }
else if (x2 >= display->
_width || y2 >= display->
_height) {
559 pynq_error(
"displayDrawRectAngle: x2=%d y2=%d outside screen boundaries\n",
561 }
else if (x3 >= display->
_width || y3 >= display->
_height) {
562 pynq_error(
"displayDrawRectAngle: x3=%d y3=%d outside screen boundaries\n",
577 uint16_t w, uint16_t h, uint16_t angle,
583 rd = -angle *
M_PI / 180.0;
586 x1 = (int)(xd * cos(rd) - yd * sin(rd) + xc);
587 y1 = (int)(xd * sin(rd) + yd * cos(rd) + yc);
591 x2 = (int)(xd * cos(rd) - yd * sin(rd) + xc);
592 y2 = (int)(xd * sin(rd) + yd * cos(rd) + yc);
595 x3 = (int)(xd * cos(rd) - yd * sin(rd) + xc);
596 y3 = (int)(xd * sin(rd) + yd * cos(rd) + yc);
599 pynq_error(
"displayDrawTriangleCenter: display has not been initialized\n");
602 pynq_error(
"displayDrawRectAngle: x1=%d y1=%d outside screen boundaries\n",
604 }
else if (x2 >= display->
_width || y2 >= display->
_height) {
605 pynq_error(
"displayDrawRectAngle: x2=%d y2=%d outside screen boundaries\n",
607 }
else if (x3 >= display->
_width || y3 >= display->
_height) {
608 pynq_error(
"displayDrawRectAngle: x3=%d y3=%d outside screen boundaries\n",
618 uint16_t r, uint16_t color) {
620 pynq_error(
"displayDrawCircle: display has not been initialized\n");
624 "displayDrawCircle: x_center=%d y_center=%d r=%d r cannot be 0\n",
625 x_center, y_center, r);
628 int x_max = x_center + r, x_min = x_center - r, y_max = y_center + r,
629 y_min = y_center - r;
631 if (x_max >= display->
_width || x_min < 0 || y_max >= display->
_height ||
633 pynq_error(
"displayDrawCircle: x_center=%d y_center=%d r=%d outside screen "
635 x_center, y_center, r);
651 if ((old_err = err) <= x)
653 if (old_err > y || err > x)
659 uint16_t y_center, uint16_t r, uint16_t color) {
661 pynq_error(
"displayDrawFillCircle: display has not been initialized\n");
665 "displayDrawFillCircle: x_center=%d y_center=%d r=%d r cannot be 0\n",
666 x_center, y_center, r);
669 int x_max = x_center + r, x_min = x_center - r, y_max = y_center + r,
670 y_min = y_center - r;
672 if (x_max >= display->
_width || x_min < 0 || y_max >= display->
_height ||
674 pynq_error(
"displayDrawFillCircle: x_center=%d y_center=%d r=%d outside "
675 "screen boundaries\n",
676 x_center, y_center, r);
692 y_center + y, color);
694 y_center + y, color);
696 ChangeX = (old_err = err) <= x;
699 if (old_err > y || err > x)
705 uint16_t x2, uint16_t y2, uint16_t r,
708 pynq_error(
"displayDrawRoundRect: display has not been initialized\n");
711 pynq_error(
"displayDrawRoundRect: x_center=%d x1=%d y1=%d r cannot be 0\n",
713 }
else if (x1 >= display->
_width || y1 >= display->
_height) {
714 pynq_error(
"displayDrawRoundRect: x1=%d y1=%d outside screen boundaries\n",
716 }
else if (x2 >= display->
_width || y2 >= display->
_height) {
717 pynq_error(
"displayDrawRoundRect: x2=%d y2=%d outside screen boundaries\n",
739 printf(
"x1=%d x2=%d delta=%d r=%d", x1, x2, x2 - x1, r);
741 printf(
"y1=%d y2=%d delta=%d r=%d", y1, y2, y2 - y1, r);
758 if ((old_err = err) <= x)
760 if (old_err > y || err > x)
765 printf(
"x1+r=%d x2-r=%d", x1 + r, x2 - r);
769 printf(
"y1+r=%d y2-r=%d", y1 + r, y2 - r);
774uint16_t
rgb_conv(uint16_t r, uint16_t g, uint16_t b) {
775 return (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
779 uint8_t ascii, uint16_t color) {
780 uint16_t xx, yy, bit, ofs;
781 unsigned char fonts[128];
782 unsigned char pw, ph;
785 bool rc =
GetFontx(fxs, ascii, fonts, &pw, &ph);
788 pynq_error(
"displayDrawChar: display has not been initialized\n");
792 printf(
"GetFontx rc=%d pw=%d ph=%d\n", rc, pw, ph);
796 pynq_error(
"displayDrawChar: cannot get font from font file\n");
801 if (x + pw >= display->
_width || y + ph >= display->
_height) {
802 pynq_error(
"displayDrawChar: x=%d y=%d for font height=%d width=%d and "
803 "direction=%d outside screen boundaries\n",
808 if (x + ph >= display->
_height || y + pw >= display->
_width) {
809 pynq_error(
"displayDrawChar: x=%d y=%d for font height=%d width=%d and "
810 "direction=%d outside screen boundaries\n",
815 if (x - pw <= 0 || y - ph <= 0) {
816 pynq_error(
"displayDrawChar: x=%d y=%d for font height=%d width=%d and "
817 "direction=%d outside screen boundaries\n",
822 if (x - ph <= 0 || y - pw <= 0) {
823 pynq_error(
"displayDrawChar: x=%d y=%d for font height=%d width=%d and "
824 "direction=%d outside screen boundaries\n",
830 int16_t xd1 = 0, yd1 = 0, xd2 = 0, yd2 = 0;
831 uint16_t xss = 0, yss = 0;
832 int16_t xsd = 0, ysd = 0, next = 0;
833 uint16_t x0 = 0, x1 = 0, y0 = 0, y1 = 0;
904 printf(
"xss=%d yss=%d\n", xss, yss);
908 for (h = 0; h < ph; h++) {
914 for (w = 0; w < ((pw + 4) / 8); w++) {
916 for (bit = 0; bit < 8; bit++) {
948 uint8_t *ascii, uint16_t color) {
949 int length = strlen((
char *)ascii);
951 pynq_error(
"displayDrawString: display has not been initialized\n");
954 printf(
"displayDrawString length=%d\n", length);
955 for (
int i = 0; i < length; i++) {
957 printf(
"ascii[%d]=%x x=%d y=%d\n", i, ascii[i], x, y);
980 pynq_error(
"displaySetFontDirection: display has not been initialized\n");
987 pynq_error(
"displaySetFontFill: display has not been initialized\n");
997 pynq_error(
"displaySetFontUnderLine: display has not been initialized\n");
1005 pynq_error(
"displayUnsetFontUnderLine: display has not been initialized\n");
1012 pynq_error(
"displayBacklightOff: display has not been initialized\n");
1014 if (display->
_bl >= 0) {
1021 pynq_error(
"displayBacklightOn: display has not been initialized\n");
1023 if (display->
_bl >= 0) {
1030 pynq_error(
"displayInversionOff: display has not been initialized\n");
1037 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 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 display_set_flip(display_t *display, bool xflip, bool yflip)
Flip the drawing off the screen.
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 gpio_reset_pin(const pin_t pin)
Function is currently a no-op placeholder for arduino compatibility.
void gpio_set_direction(const pin_t pin, const gpio_direction_t dir)
Set the GPIO pin as in input or output.
void gpio_set_level(const pin_t pin, const gpio_level_t level)
Set the level of the output GPIO pin. If the pin is configured as input, this function does nothing.
void switchbox_set_pin(const pin_t pin_number, const uint8_t pin_type)
Set the type of a switch pin.
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