Compare commits

..

22 commits

Author SHA1 Message Date
ladyada
e98fd6a846 add double buffer 2025-03-23 15:26:55 -04:00
Limor "Ladyada" Fried
731f56d6d9
Merge pull request #13 from adafruit/doublebuffering-fix
Fix double buffering & add double buffering to text
2025-03-23 15:17:05 -04:00
636aaee80f document constructor fully 2025-03-19 19:24:44 -05:00
68df90473a clang it 2025-03-19 19:24:00 -05:00
a0f7624c00 Fix double buffering & add double buffering to text 2025-03-19 19:21:53 -05:00
Liz
7b0ae0d870
Update library.properties 2025-03-03 14:03:04 -05:00
5675ddb5e7
Merge pull request #9 from adafruit/640x480-mode-fixes
Some checks failed
Arduino Library CI / build (feather_rp2350) (push) Has been cancelled
Arduino Library CI / build (metro_rp2350) (push) Has been cancelled
Arduino Library CI / clang (push) Has been cancelled
Arduino Library CI / doxygen (push) Has been cancelled
640x480 mode fixes
2025-02-27 11:25:32 -06:00
e21bf9a484 clang-format
Some checks failed
Arduino Library CI / build (feather_rp2350) (push) Has been cancelled
Arduino Library CI / build (metro_rp2350) (push) Has been cancelled
Arduino Library CI / clang (push) Has been cancelled
Arduino Library CI / doxygen (push) Has been cancelled
2025-02-27 11:20:03 -06:00
1a37ef563b Make more interesting use of the palette mode 2025-02-27 09:51:08 -06:00
35a6298bb2 Add 640x480 and 720x400 modes
And permit non-pixel-multiplied palette modes
2025-02-27 09:51:08 -06:00
49c2c71fa6 Ignore generated files 2025-02-27 09:46:53 -06:00
Liz
8a6c26e440
Merge pull request #8 from adafruit/fix-docs
Some checks are pending
Arduino Library CI / build (feather_rp2350) (push) Waiting to run
Arduino Library CI / build (metro_rp2350) (push) Waiting to run
Arduino Library CI / clang (push) Waiting to run
Arduino Library CI / doxygen (push) Waiting to run
document everything
2025-02-26 10:03:26 -05:00
a5a2b632fd doxygen must be quiet
Some checks failed
Arduino Library CI / build (feather_rp2350) (push) Has been cancelled
Arduino Library CI / build (metro_rp2350) (push) Has been cancelled
Arduino Library CI / clang (push) Has been cancelled
Arduino Library CI / doxygen (push) Has been cancelled
2025-02-25 21:49:26 -06:00
6c66a5d8d6 clang-format requires this 2025-02-25 21:46:48 -06:00
4a3c697c80 Run clang-format 2025-02-25 21:43:19 -06:00
ff4f947e69 document everything 2025-02-25 21:41:44 -06:00
e17e2a53c4
Merge pull request #6 from adafruit/default-pinout-with-warning
Some checks are pending
Arduino Library CI / build (feather_rp2350) (push) Waiting to run
Arduino Library CI / build (metro_rp2350) (push) Waiting to run
Arduino Library CI / clang (push) Waiting to run
Arduino Library CI / doxygen (push) Waiting to run
Always provide a pinout, so that CI can proceed
2025-02-25 18:30:13 -06:00
bf210232d3 add header to avoid error during CI not seen locally
Some checks failed
Arduino Library CI / build (feather_rp2350) (push) Has been cancelled
Arduino Library CI / build (metro_rp2350) (push) Has been cancelled
Arduino Library CI / clang (push) Has been cancelled
Arduino Library CI / doxygen (push) Has been cancelled
2025-02-25 18:09:05 -06:00
3105bdde83 add parens suggested by compiler 2025-02-25 18:08:46 -06:00
647420b788 Add a default pinout & reformat 2025-02-25 18:08:13 -06:00
adb43b2546 Use more parallelism in CI
this decreases the total wait time, even if it uses more resources in all
2025-02-25 18:08:13 -06:00
d4afecd70b Undo clang formatting 2025-02-25 18:08:11 -06:00
11 changed files with 2812 additions and 66 deletions

View file

@ -4,6 +4,10 @@ on: [pull_request, push, repository_dispatch]
jobs:
build:
strategy:
matrix:
arduino-platform: ["feather_rp2350", "metro_rp2350"]
runs-on: ubuntu-latest
steps:
@ -20,10 +24,41 @@ jobs:
run: bash ci/actions_install.sh
- name: test platforms
run: python3 ci/build_platform.py feather_rp2350 metro_rp2350
run: python3 ci/build_platform.py ${{ matrix.arduino-platform }}
clang:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- uses: actions/checkout@v3
- uses: actions/checkout@v3
with:
repository: adafruit/ci-arduino
path: ci
- name: pre-install
run: bash ci/actions_install.sh
- name: clang
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -e "./src/drivers/dvhstx" -e './.git' -r .
doxygen:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- uses: actions/checkout@v3
- uses: actions/checkout@v3
with:
repository: adafruit/ci-arduino
path: ci
- name: pre-install
run: bash ci/actions_install.sh
- name: doxygen
env:

2
.gitignore vendored
View file

@ -1 +1,3 @@
build/*
/doxygen
/html

2459
Doxyfile Normal file

File diff suppressed because it is too large Load diff

View file

@ -4,15 +4,11 @@
// If your board definition has PIN_CKP and related defines,
// DVHSTX_PINOUT_DEFAULT is available
DVHSTX16 display(DVHSTX_PINOUT_DEFAULT, DVHSTX_RESOLUTION_320x240);
// If you get the message "error: 'DVHSTX_PINOUT_DEFAULTx' was not declared"
// then you need to give the pins numbers explicitly, like the example below.
// The order is: {CKP, D0P, D1P, D2P} DVHSTX16 display({12, 14, 16, 18},
// DVHSTX_RESOLUTION_320x240);
#ifdef PIN_CKP
DVHSTX16 display(DVHSTX_PINOUT_DEFAULT, DVHSTX_RESOLUTION_320x240);
#else
DVHSTX16 display({14, 18, 16, 12}, DVHSTX_RESOLUTION_320x240);
#endif
void setup() {
Serial.begin(115200);

View file

@ -4,15 +4,30 @@
// If your board definition has PIN_CKP and related defines,
// DVHSTX_PINOUT_DEFAULT is available
DVHSTX8 display(DVHSTX_PINOUT_DEFAULT, DVHSTX_RESOLUTION_640x360);
// If you get the message "error: 'DVHSTX_PINOUT_DEFAULTx' was not declared"
// then you need to give the pins numbers explicitly, like the example below.
// The order is: {CKP, D0P, D1P, D2P} DVHSTX8 display({12, 14, 16, 18},
// DVHSTX_RESOLUTION_640x360);
#ifdef PIN_CKP
DVHSTX16 display(DVHSTX_PINOUT_DEFAULT, DVHSTX_RESOLUTION_320x240);
#else
DVHSTX16 display({14, 18, 16, 12}, DVHSTX_RESOLUTION_320x240);
#endif
struct moving_point {
int x, y, dx, dy;
void step() {
x += dx;
if (x < 0) { x = 0; dx = random(3) + 1; }
if (x >= display.width()) { x = display.width() - 1; dx = -random(3) - 1; }
y += dy;
if (y < 0) { y = 0; dy = random(3) + 1; }
if (y >= display.height()) { y = display.height() - 1; dy = -random(3) - 1; }
}
};
moving_point p1, p2;
int random_with_sign(int n) {
return random(2) ? random(n-1)+1 : -random(n-1)-1;
}
void setup() {
Serial.begin(115200);
@ -23,12 +38,20 @@ void setup() {
digitalWrite(LED_BUILTIN, (millis() / 500) & 1);
}
Serial.println("display initialized");
p1 = moving_point{random(display.width()), random(display.height()), random_with_sign(3), random_with_sign(3)};
p2 = moving_point{random(display.width()), random(display.height()), random_with_sign(3), random_with_sign(3)};
}
void loop() {
// Draw random lines
display.drawLine(random(display.width()), random(display.height()),
random(display.width()), random(display.height()),
random(65536));
sleep_ms(1);
static int j;
display.drawLine(p1.x, p1.y, p2.x, p2.y, 1 + (j + 254) % 255);
Serial.printf("%d %d %d %d\r\n", p1.x, p1.y, p1.dx, p1.dy);
p1.step();
p2.step();
for(int i=1; i<256; i++) {
display.setColor(i, ((i + j) % 255) * 0x010101);
}
j += 1;
delay(3);
}

View file

@ -4,16 +4,12 @@
// If your board definition has PIN_CKP and related defines,
// DVHSTX_PINOUT_DEFAULT is available
DVHSTXText display(DVHSTX_PINOUT_DEFAULT);
// If you get the message "error: 'DVHSTX_PINOUT_DEFAULTx' was not declared"
// then you need to give the pins numbers explicitly, like the example below.
// The order is: {CKP, D0P, D1P, D2P}.
//
// DVHSTXText3 display({12, 14, 16, 18});
#ifdef PIN_CKP
DVHSTX16 display(DVHSTX_PINOUT_DEFAULT, DVHSTX_RESOLUTION_320x240);
#else
DVHSTX16 display({14, 18, 16, 12}, DVHSTX_RESOLUTION_320x240);
#endif
// DVHSTXText display({12, 14, 16, 18});
const static TextColor colors[] = {
TextColor::TEXT_BLACK, TextColor::TEXT_RED, TextColor::TEXT_GREEN,

View file

@ -1,5 +1,5 @@
name=Adafruit DVI HSTX
version=1.0.0
version=1.2.0
author=Jeff Epler
maintainer=Adafruit <info@adafruit.com>
sentence=Arduino library for RP2350 DVI output, based on dvhstx

View file

@ -13,10 +13,14 @@ int16_t dvhstx_width(DVHSTXResolution r) {
return 400;
case DVHSTX_RESOLUTION_320x240:
return 320;
case DVHSTX_RESOLUTION_640x480:
return 640;
case DVHSTX_RESOLUTION_360x240:
return 360;
case DVHSTX_RESOLUTION_360x200:
return 360;
case DVHSTX_RESOLUTION_720x400:
return 720;
case DVHSTX_RESOLUTION_360x288:
return 360;
case DVHSTX_RESOLUTION_400x300:
@ -42,10 +46,14 @@ int16_t dvhstx_height(DVHSTXResolution r) {
return 225;
case DVHSTX_RESOLUTION_320x240:
return 240;
case DVHSTX_RESOLUTION_640x480:
return 480;
case DVHSTX_RESOLUTION_360x240:
return 240;
case DVHSTX_RESOLUTION_360x200:
return 200;
case DVHSTX_RESOLUTION_720x400:
return 400;
case DVHSTX_RESOLUTION_360x288:
return 288;
case DVHSTX_RESOLUTION_400x300:
@ -66,6 +74,7 @@ void DVHSTX16::swap(bool copy_framebuffer) {
memcpy(hstx.get_front_buffer<uint8_t>(), hstx.get_back_buffer<uint8_t>(),
sizeof(uint16_t) * _width * _height);
}
buffer = hstx.get_back_buffer<uint16_t>();
}
void DVHSTX8::swap(bool copy_framebuffer) {
if (!double_buffered) {
@ -76,14 +85,26 @@ void DVHSTX8::swap(bool copy_framebuffer) {
memcpy(hstx.get_front_buffer<uint8_t>(), hstx.get_back_buffer<uint8_t>(),
sizeof(uint8_t) * _width * _height);
}
buffer = hstx.get_back_buffer<uint8_t>();
}
void DVHSTXText::swap(bool copy_framebuffer) {
if (!double_buffered) {
return;
}
hstx.flip_blocking();
if (copy_framebuffer) {
memcpy(hstx.get_front_buffer<uint8_t>(), hstx.get_back_buffer<uint8_t>(),
sizeof(uint16_t) * _width * _height);
}
buffer = hstx.get_back_buffer<uint16_t>();
}
void DVHSTXText3::clear() {
void DVHSTXText::clear() {
std::fill(getBuffer(), getBuffer() + WIDTH * HEIGHT, attr << 8);
}
// Character framebuffer is actually a small GFXcanvas16, so...
size_t DVHSTXText3::write(uint8_t c) {
size_t DVHSTXText::write(uint8_t c) {
if (!*this)
return 0;

View file

@ -4,31 +4,77 @@
#include "drivers/dvhstx/dvhstx.hpp"
enum DVHSTXResolution {
/* well supported, square pixels on a 16:9 display, actual resolution
1280x720@50Hz */
DVHSTX_RESOLUTION_320x180,
DVHSTX_RESOLUTION_640x360,
#if DOXYGEN
/// Enumerated types in the library. Due to a technical limitations in the
/// documentation generator, these are displayed as members of a class called
/// "enum", but in reality they are defined as top-level enumerations.
struct enum {
public :
#endif
/* sometimes supported, square pixels on a 16:9 display, actual resolution
960x540@60Hz */
DVHSTX_RESOLUTION_480x270,
/// Available video resolutions
enum DVHSTXResolution {
DVHSTX_RESOLUTION_320x180, ///< well supported, aspect ratio 16:9,
///< actual resolution 1280x720@50Hz
DVHSTX_RESOLUTION_640x360, ///< well supported, aspect ratio 16:9,
///< actual resolution 1280x720@50Hz
/* sometimes supported, square pixels on a 16:9 display, actual resolution
800x450@60Hz */
DVHSTX_RESOLUTION_400x225,
DVHSTX_RESOLUTION_480x270, ///< sometimes supported, aspect ratio 16:9,
///< actual resolution 960x540@60Hz
/* well supported, but pixels aren't square on a 16:9 display */
DVHSTX_RESOLUTION_320x240, /* 4:3, actual resolution 640x480@60Hz */
DVHSTX_RESOLUTION_360x240, /* 3:2, actual resolution 720x480@60Hz */
DVHSTX_RESOLUTION_360x200, /* 18:10, actual resolution 720x400@70Hz */
DVHSTX_RESOLUTION_360x288, /* 5:4, actual resolution 720x576@60Hz */
DVHSTX_RESOLUTION_400x300, /* 4:3, actual resolution 800x600@60Hz */
DVHSTX_RESOLUTION_512x384, /* 4:3, actual resolution 1024x768@60Hz */
DVHSTX_RESOLUTION_400x225, ///< sometimes supported, aspect ratio 16:9,
///< actual resolution 800x450@60Hz
/* sometimes supported, but pixels aren't square on a 16:9 display */
DVHSTX_RESOLUTION_400x240, /* 5:3, actual resolution 800x480@60Hz */
DVHSTX_RESOLUTION_320x240, ///< well supported, aspect ratio 4:3, actual
///< resolution 640x480@60Hz
DVHSTX_RESOLUTION_640x480, ///< well supported, aspect ratio 4:3, actual
///< resolution 640x480@60Hz
DVHSTX_RESOLUTION_360x240, ///< well supported, aspect ratio 3:2, actual
///< resolution 720x480@60Hz
DVHSTX_RESOLUTION_360x200, ///< well supported, aspect ratio 9:5, actual
///< resolution 720x400@70Hz (very close to
///< 16:9)
DVHSTX_RESOLUTION_720x400, ///< well supported, aspect ratio 9:5, actual
///< resolution 720x400@70Hz (very close to
///< 16:9)
DVHSTX_RESOLUTION_360x288, ///< well supported, aspect ratio 5:4, actual
///< resolution 720x576@60Hz
DVHSTX_RESOLUTION_400x300, ///< well supported, aspect ratio 4:3, actual
///< resolution 800x600@60Hz
DVHSTX_RESOLUTION_512x384, ///< well supported, aspect ratio 4:3, actual
///< resolution 1024x768@60Hz
/* sometimes supported, but pixels aren't square on a 16:9 display */
DVHSTX_RESOLUTION_400x240, ///< well supported, aspect ratio 5:3, actual
///< resolution 800x480@60Hz
};
#if DOXYGEN
/// Foreground, background & attribute definitions for DVHSTXText Cells
enum TextColor{
TEXT_BLACK, ///< Black foreground color
TEXT_RED, ///< Red foreground color
TEXT_GREEN, ///< Green foreground color
TEXT_YELLOW, ///< Yellow foreground color
TEXT_BLUE, ///< Blue foreground color
TEXT_MAGENTA, ///< Magenta foreground color
TEXT_WHITE, ///< White foreground color
BG_BLACK, ///< Black background color
BG_RED, ///< Red background color
BG_GREEN, ///< Green background color
BG_YELLOW, ///< Yellow background color
BG_BLUE, ///< Blue background color
BG_MAGENTA, ///< Magenta background color
BG_CYAN, ///< Cyan background color
BG_WHITE, ///< White background color
ATTR_NORMAL_INTEN, ///< Normal intensity foreground
ATTR_LOW_INTEN, ///< Lower intensity foreground
ATTR_V_LOW_INTEN, ///< Lowest intensity foreground
};
};
#endif
using pimoroni::DVHSTXPinout;
@ -42,16 +88,25 @@ using pimoroni::DVHSTXPinout;
#if defined(PIN_CKP)
#define DVHSTX_PINOUT_DEFAULT \
{ PIN_CKP, PIN_D0P, PIN_D1P, PIN_D2P }
#else
#if !defined(DVHSTX_NO_DEFAULT_PINOUT_WARNING)
#pragma GCC warning \
"DVHSTX_PINOUT_DEFAULT is a default pinout. If you get no video display, use the correct pinout for your board."
#endif
#define DVHSTX_PINOUT_DEFAULT \
{ 12, 14, 16, 18 }
#endif
int16_t dvhstx_width(DVHSTXResolution r);
int16_t dvhstx_height(DVHSTXResolution r);
/// A 16-bit canvas displaying to a DVI monitor
class DVHSTX16 : public GFXcanvas16 {
public:
/**************************************************************************/
/*!
@brief Instatiate a DVHSTX 16-bit canvas context for graphics
@param pinout Details of the HSTX pinout
@param res Display resolution
@param double_buffered Whether to allocate two buffers
*/
@ -62,6 +117,12 @@ public:
pinout(pinout), res{res}, double_buffered{double_buffered} {}
~DVHSTX16() { end(); }
/**************************************************************************/
/*!
@brief Start the display
@return true if successful, false in case of error
*/
/**************************************************************************/
bool begin() {
bool result =
hstx.init(dvhstx_width(res), dvhstx_height(res),
@ -72,6 +133,11 @@ public:
fillScreen(0);
return true;
}
/**************************************************************************/
/*!
@brief Stop the display
*/
/**************************************************************************/
void end() { hstx.reset(); }
/**********************************************************************/
@ -93,8 +159,8 @@ public:
@return The corresponding 16-bit pixel value
*/
/**********************************************************************/
uint16_t color565(uint8_t red, uint8_t green, uint8_t blue) {
return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | (blue >> 3);
uint16_t color565(uint8_t r, uint8_t g, uint8_t b) {
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
}
private:
@ -104,11 +170,13 @@ private:
bool double_buffered;
};
/// An 8-bit canvas displaying to a DVI monitor
class DVHSTX8 : public GFXcanvas8 {
public:
/**************************************************************************/
/*!
@brief Instatiate a DVHSTX 8-bit canvas context for graphics
@param pinout Details of the HSTX pinout
@param res Display resolution
@param double_buffered Whether to allocate two buffers
*/
@ -119,6 +187,12 @@ public:
pinout(pinout), res{res}, double_buffered{double_buffered} {}
~DVHSTX8() { end(); }
/**************************************************************************/
/*!
@brief Start the display
@return true if successful, false in case of error
*/
/**************************************************************************/
bool begin() {
bool result =
hstx.init(dvhstx_width(res), dvhstx_height(res),
@ -135,11 +209,32 @@ public:
fillScreen(0);
return true;
}
/**************************************************************************/
/*!
@brief Stop the display
*/
/**************************************************************************/
void end() { hstx.reset(); }
void setColor(uint8_t idx, uint8_t red, uint8_t green, uint8_t blue) {
hstx.get_palette()[idx] = (red << 16) | (green << 8) | blue;
/**************************************************************************/
/*!
@brief Set the given palette entry to a RGB888 color
@param idx The palette entry number, from 0 to 255
@param r The input red value, 0 to 255
@param g The input red value, 0 to 255
@param b The input red value, 0 to 255
*/
/**************************************************************************/
void setColor(uint8_t idx, uint8_t r, uint8_t g, uint8_t b) {
hstx.get_palette()[idx] = (r << 16) | (g << 8) | b;
}
/**************************************************************************/
/*!
@brief Set the given palette entry to a RGB888 color
@param idx The palette entry number, from 0 to 255
@param rgb The 24-bit RGB value in the form 0x00RRGGBB
*/
/**************************************************************************/
void setColor(uint8_t idx, uint32_t rgb) { hstx.get_palette()[idx] = rgb; }
/**********************************************************************/
@ -161,55 +256,130 @@ private:
using TextColor = pimoroni::DVHSTX::TextColour;
class DVHSTXText3 : public GFXcanvas16 {
/// A text-mode canvas displaying to a DVI monitor
///
/// The text mode display is always 91x30 characters at a resolution of 1280x720
/// pixels.
class DVHSTXText : public GFXcanvas16 {
public:
/// Each element of the canvas is a Cell, which comprises a character and an
/// attribute.
struct Cell {
uint16_t value;
uint16_t value; ///< A value where the low 8 bits are the character and the
///< high 8 bits are the attribute
/**************************************************************************/
/*!
@brief Create a cell object from an ASCII character and an attribute
@param c ASCII character value. Glyphs from 32 to 126 inclusive are
available
@param attr Attribute value. Can be the logical OR of a text color, a
background color, and an intensity flag
*/
/**************************************************************************/
Cell(uint8_t c, uint8_t attr = TextColor::TEXT_WHITE)
: value(c | (attr << 8)) {}
};
/**************************************************************************/
/*!
@brief Instatiate a DVHSTX 8-bit canvas context for graphics
@param res Display resolution
@param pinout Details of the HSTX pinout
@param double_buffered Whether to allocate two buffers
*/
/**************************************************************************/
DVHSTXText3(DVHSTXPinout pinout)
: GFXcanvas16(91, 30, false),
pinout(pinout), res{res}, attr{TextColor::TEXT_WHITE} {}
~DVHSTXText3() { end(); }
DVHSTXText(DVHSTXPinout pinout, bool double_buffered = false)
: GFXcanvas16(91, 30, false), double_buffered{double_buffered},
pinout(pinout), res{}, attr{TextColor::TEXT_WHITE} {}
~DVHSTXText() { end(); }
/**************************************************************************/
/*!
@brief Check if the display is running
@return true if the display is running
*/
/**************************************************************************/
operator bool() const { return hstx.get_back_buffer<uint16_t>(); }
/**************************************************************************/
/*!
@brief Start the display
@return true if successful, false in case of error
*/
/**************************************************************************/
bool begin() {
bool result =
hstx.init(91, 30, pimoroni::DVHSTX::MODE_TEXT_RGB111, false, pinout);
bool result = hstx.init(91, 30, pimoroni::DVHSTX::MODE_TEXT_RGB111,
double_buffered, pinout);
if (!result)
return false;
buffer = hstx.get_back_buffer<uint16_t>();
return true;
}
/**************************************************************************/
/*!
@brief Stop the display
*/
/**************************************************************************/
void end() { hstx.reset(); }
/**************************************************************************/
/*!
@brief Clear the display. All cells are set to character 32 (space) with
the current color
*/
/**************************************************************************/
void clear();
/**************************************************************************/
/*!
@brief Set the color used by write()
@param a Attribute value. Can be the logical OR of a text color, a
background color, and an intensity flag
*/
/**************************************************************************/
void setColor(uint8_t a) { attr = a; }
/**************************************************************************/
/*!
@brief Set the color used by write()
@param fg A foreground color
@param bg A background color
@param inten An intensity flag
*/
/**************************************************************************/
void setColor(TextColor fg, TextColor bg,
TextColor inten = TextColor::ATTR_NORMAL_INTEN) {
attr = fg | bg | inten;
}
/**************************************************************************/
/*!
@brief Hide the block cursor
*/
/**************************************************************************/
void hideCursor() {
cursor_visible = false;
hstx.cursor_off();
}
/**************************************************************************/
/*!
@brief Show the block cursor
*/
/**************************************************************************/
void showCursor() {
cursor_visible = true;
sync_cursor_with_hstx();
}
/**************************************************************************/
/*!
@brief Move the position for write(), and the block cursor (if shown)
@param x The screen location horizontally, from 0 to 91 inclusive
@param y The screen location vertically, from 0 to 29 inclusive
Note that when the cursor's X position is (zero-based) 91 it is shown on
(zero-based) column 90 but the next character written will be wrapped and
shown at the beginning of the next line.
*/
/**************************************************************************/
void setCursor(int x, int y) {
if (x < 0)
x = 0;
@ -224,11 +394,51 @@ public:
sync_cursor_with_hstx();
}
/**************************************************************************/
/*!
@brief Write a character to the display
@param c The character to write
Because this class is a subclass of Print, you can also use methods like
print, println, and printf to write text.
Text is written with the current attribute, and the screen automatically
wraps and scrolls when needed.
This function fails (returns 0) if the display was not successfully started
with begin().
@return 1 if the character is written, 0 if it was not
*/
/**************************************************************************/
size_t write(uint8_t c);
/**************************************************************************/
/*!
@brief Get the current cursor X position, from 0 to 91
@return The column position of the cursor
*/
/**************************************************************************/
int getCursorX() const { return cursor_x; }
/**************************************************************************/
/*!
@brief Get the current cursor Y position, from 0 to 29
@return The row position of the cursor
*/
/**************************************************************************/
int getCursorY() const { return cursor_y; }
/**********************************************************************/
/*!
@brief If double-buffered, wait for retrace and swap buffers. Otherwise,
do nothing (returns immediately)
@param copy_framebuffer if true, copy the new screen to the new back buffer.
Otherwise, the content is undefined.
*/
/**********************************************************************/
void swap(bool copy_framebuffer = false);
private:
DVHSTXPinout pinout;
DVHSTXResolution res;

View file

@ -209,13 +209,17 @@ void __scratch_x("display") DVHSTX::gfx_dma_handler() {
*dst_ptr++ = val;
*dst_ptr++ = val;
}
}
else {
} else if (h_repeat_shift == 1) {
for (int i = 0; i < timing_mode->h_active_pixels; i += 2) {
uint32_t val = display_palette[*src_ptr++];
*dst_ptr++ = val;
*dst_ptr++ = val;
}
} else {
for (int i = 0; i < timing_mode->h_active_pixels; i += 1) {
uint32_t val = display_palette[*src_ptr++];
*dst_ptr++ = val;
}
}
}
}
@ -319,16 +323,16 @@ void __scratch_x("display") DVHSTX::text_dma_handler() {
bg_xor = bg * 0x3030303;
tmp_h = colour * ((bits >> 6) & 0x3030303) ^ bg_xor;
*dst_ptr++ = tmp_l & 0xffff | (tmp_h << 16);
*dst_ptr++ = (tmp_l & 0xffff) | (tmp_h << 16);
tmp_l = tmp_h >> 16;
tmp_h = colour * ((bits >> 4) & 0x3030303) ^ bg_xor;
*dst_ptr++ = tmp_l & 0xffff | (tmp_h << 16);
*dst_ptr++ = (tmp_l & 0xffff) | (tmp_h << 16);
tmp_l = tmp_h >> 16;
tmp_h = colour * ((bits >> 2) & 0x3030303) ^ bg_xor;
*dst_ptr++ = tmp_l & 0xffff | (tmp_h << 16);
*dst_ptr++ = (tmp_l & 0xffff) | (tmp_h << 16);
tmp_l = tmp_h >> 16;
tmp_h = colour * ((bits >> 0) & 0x3030303) ^ bg_xor;
*dst_ptr++ = tmp_l & 0xffff | (tmp_h << 16);
*dst_ptr++ = (tmp_l & 0xffff) | (tmp_h << 16);
}
if (y / 24 == cursor_y) {
uint8_t* dst_ptr = (uint8_t*)&line_buffers[ch_num * line_buf_total_len + count_of(vactive_text_line_header)] + 14 * cursor_x;

View file

@ -2,6 +2,7 @@
#include <string.h>
#include "dvi.hpp"
#include "pico/stdlib.h"
#include "hardware/gpio.h"
@ -125,7 +126,6 @@ namespace pimoroni {
private:
RGB888 palette[PALETTE_SIZE];
bool double_buffered;
uint8_t* frame_buffer_display;
uint8_t* frame_buffer_back;
uint32_t* font_cache = nullptr;