Adafruit_dvhstx.h
1 #pragma once 2 3 #include "Adafruit_GFX.h" 4 5 #include "drivers/dvhstx/dvhstx.hpp" 6 7 enum DVHSTXResolution { 8 /* well supported, square pixels on a 16:9 display, actual resolution 9 1280x720@50Hz */ 10 DVHSTX_RESOLUTION_320x180, 11 DVHSTX_RESOLUTION_640x360, 12 13 /* sometimes supported, square pixels on a 16:9 display, actual resolution 14 960x540@60Hz */ 15 DVHSTX_RESOLUTION_480x270, 16 17 /* sometimes supported, square pixels on a 16:9 display, actual resolution 18 800x450@60Hz */ 19 DVHSTX_RESOLUTION_400x225, 20 21 /* well supported, but pixels aren't square on a 16:9 display */ 22 DVHSTX_RESOLUTION_320x240, /* 4:3, actual resolution 640x480@60Hz */ 23 DVHSTX_RESOLUTION_360x240, /* 3:2, actual resolution 720x480@60Hz */ 24 DVHSTX_RESOLUTION_360x200, /* 18:10, actual resolution 720x400@70Hz */ 25 DVHSTX_RESOLUTION_360x288, /* 5:4, actual resolution 720x576@60Hz */ 26 DVHSTX_RESOLUTION_400x300, /* 4:3, actual resolution 800x600@60Hz */ 27 DVHSTX_RESOLUTION_512x384, /* 4:3, actual resolution 1024x768@60Hz */ 28 29 /* sometimes supported, but pixels aren't square on a 16:9 display */ 30 DVHSTX_RESOLUTION_400x240, /* 5:3, actual resolution 800x480@60Hz */ 31 }; 32 33 using pimoroni::DVHSTXPinout; 34 35 // If the board definition provides pre-defined pins for the HSTX connection, 36 // use them to define a default pinout object. 37 // This object can be used as the first argument of the DVHSTX constructor. 38 // Otherwise you must provide the pin nubmers directly as a list of 4 numbers 39 // in curly brackets such as {12, 14, 16, 18}. These give the location of the 40 // positive ("P") pins in the order: Clock, Data 0, Data 1, Data 2; check your 41 // board's schematic for details. 42 #if defined(PIN_CKP) 43 #define DVHSTX_PINOUT_DEFAULT \ 44 { PIN_CKP, PIN_D0P, PIN_D1P, PIN_D2P } 45 #endif 46 47 int16_t dvhstx_width(DVHSTXResolution r); 48 int16_t dvhstx_height(DVHSTXResolution r); 49 50 class DVHSTX16 : public GFXcanvas16 { 51 public: 52 /**************************************************************************/ 53 /*! 54 @brief Instatiate a DVHSTX 16-bit canvas context for graphics 55 @param res Display resolution 56 @param double_buffered Whether to allocate two buffers 57 */ 58 /**************************************************************************/ 59 DVHSTX16(DVHSTXPinout pinout, DVHSTXResolution res, 60 bool double_buffered = false) 61 : GFXcanvas16(dvhstx_width(res), dvhstx_height(res), false), 62 pinout(pinout), res{res}, double_buffered{double_buffered} {} 63 ~DVHSTX16() { end(); } 64 65 bool begin() { 66 bool result = 67 hstx.init(dvhstx_width(res), dvhstx_height(res), 68 pimoroni::DVHSTX::MODE_RGB565, double_buffered, pinout); 69 if (!result) 70 return false; 71 buffer = hstx.get_back_buffer<uint16_t>(); 72 fillScreen(0); 73 return true; 74 } 75 void end() { hstx.reset(); } 76 77 /**********************************************************************/ 78 /*! 79 @brief If double-buffered, wait for retrace and swap buffers. Otherwise, 80 do nothing (returns immediately) 81 @param copy_framebuffer if true, copy the new screen to the new back buffer. 82 Otherwise, the content is undefined. 83 */ 84 /**********************************************************************/ 85 void swap(bool copy_framebuffer = false); 86 87 /**********************************************************************/ 88 /*! 89 @brief Convert 24-bit RGB value to a framebuffer value 90 @param r The input red value, 0 to 255 91 @param g The input red value, 0 to 255 92 @param b The input red value, 0 to 255 93 @return The corresponding 16-bit pixel value 94 */ 95 /**********************************************************************/ 96 uint16_t color565(uint8_t red, uint8_t green, uint8_t blue) { 97 return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | (blue >> 3); 98 } 99 100 private: 101 DVHSTXPinout pinout; 102 DVHSTXResolution res; 103 mutable pimoroni::DVHSTX hstx; 104 bool double_buffered; 105 }; 106 107 class DVHSTX8 : public GFXcanvas8 { 108 public: 109 /**************************************************************************/ 110 /*! 111 @brief Instatiate a DVHSTX 8-bit canvas context for graphics 112 @param res Display resolution 113 @param double_buffered Whether to allocate two buffers 114 */ 115 /**************************************************************************/ 116 DVHSTX8(DVHSTXPinout pinout, DVHSTXResolution res, 117 bool double_buffered = false) 118 : GFXcanvas8(dvhstx_width(res), dvhstx_height(res), false), 119 pinout(pinout), res{res}, double_buffered{double_buffered} {} 120 ~DVHSTX8() { end(); } 121 122 bool begin() { 123 bool result = 124 hstx.init(dvhstx_width(res), dvhstx_height(res), 125 pimoroni::DVHSTX::MODE_PALETTE, double_buffered, pinout); 126 if (!result) 127 return false; 128 for (int i = 0; i < 255; i++) { 129 uint8_t r = (i >> 6) * 255 / 3; 130 uint8_t g = ((i >> 2) & 7) * 255 / 7; 131 uint8_t b = (i & 3) * 255 / 3; 132 setColor(i, r, g, b); 133 } 134 buffer = hstx.get_back_buffer<uint8_t>(); 135 fillScreen(0); 136 return true; 137 } 138 void end() { hstx.reset(); } 139 140 void setColor(uint8_t idx, uint8_t red, uint8_t green, uint8_t blue) { 141 hstx.get_palette()[idx] = (red << 16) | (green << 8) | blue; 142 } 143 void setColor(uint8_t idx, uint32_t rgb) { hstx.get_palette()[idx] = rgb; } 144 145 /**********************************************************************/ 146 /*! 147 @brief If double-buffered, wait for retrace and swap buffers. Otherwise, 148 do nothing (returns immediately) 149 @param copy_framebuffer if true, copy the new screen to the new back buffer. 150 Otherwise, the content is undefined. 151 */ 152 /**********************************************************************/ 153 void swap(bool copy_framebuffer = false); 154 155 private: 156 DVHSTXPinout pinout; 157 DVHSTXResolution res; 158 mutable pimoroni::DVHSTX hstx; 159 bool double_buffered; 160 }; 161 162 using TextColor = pimoroni::DVHSTX::TextColour; 163 164 class DVHSTXText3 : public GFXcanvas16 { 165 public: 166 struct Cell { 167 uint16_t value; 168 Cell(uint8_t c, uint8_t attr = TextColor::TEXT_WHITE) 169 : value(c | (attr << 8)) {} 170 }; 171 /**************************************************************************/ 172 /*! 173 @brief Instatiate a DVHSTX 8-bit canvas context for graphics 174 @param res Display resolution 175 @param double_buffered Whether to allocate two buffers 176 */ 177 /**************************************************************************/ 178 DVHSTXText3(DVHSTXPinout pinout) 179 : GFXcanvas16(91, 30, false), 180 pinout(pinout), res{res}, attr{TextColor::TEXT_WHITE} {} 181 ~DVHSTXText3() { end(); } 182 183 bool begin() { 184 bool result = 185 hstx.init(91, 30, pimoroni::DVHSTX::MODE_TEXT_RGB111, false, pinout); 186 if (!result) 187 return false; 188 buffer = hstx.get_back_buffer<uint16_t>(); 189 return true; 190 } 191 void end() { hstx.reset(); } 192 193 void clear(); 194 195 void set_color(TextColor a) { attr = a; } 196 197 void hide_cursor() { 198 cursor_visible = false; 199 hstx.cursor_off(); 200 } 201 202 void show_cursor() { 203 cursor_visible = true; 204 sync_cursor_with_hstx(); 205 } 206 207 void set_cursor(int x, int y) { 208 if (x < 0) 209 x = 0; 210 if (x > _width) 211 x = _width; 212 if (y < 0) 213 y = 0; 214 if (y >= _height) 215 y = _height - 1; 216 cursor_x = x; 217 cursor_y = y; 218 sync_cursor_with_hstx(); 219 } 220 221 size_t write(uint8_t c); 222 223 private: 224 DVHSTXPinout pinout; 225 DVHSTXResolution res; 226 mutable pimoroni::DVHSTX hstx; 227 bool double_buffered; 228 bool cursor_visible = false; 229 TextColor attr; 230 uint8_t cursor_x = 0, cursor_y = 0; 231 232 void sync_cursor_with_hstx() { 233 if (cursor_visible) { 234 hstx.set_cursor(cursor_x == _width ? _width - 1 : cursor_x, cursor_y); 235 } 236 } 237 };