kopia lustrzana https://github.com/pimoroni/pimoroni-pico
DV Display: Support multiple scroll offsets
rodzic
b9cd998709
commit
3c2c7ccc94
|
@ -119,7 +119,7 @@ namespace pimoroni {
|
|||
while (gpio_get(VSYNC) == 0);
|
||||
gpio_put(RAM_SEL, bank);
|
||||
if (rewrite_header) {
|
||||
write_header();
|
||||
set_scroll_idx_for_lines(-1, 0, display_height);
|
||||
rewrite_header = false;
|
||||
}
|
||||
}
|
||||
|
@ -128,9 +128,35 @@ namespace pimoroni {
|
|||
swd_reset();
|
||||
}
|
||||
|
||||
void DVDisplay::set_display_offset(const Point& p) {
|
||||
void DVDisplay::set_display_offset(const Point& p, int idx) {
|
||||
int32_t offset = (int32_t)point_to_address(p) - (int32_t)point_to_address({0,0});
|
||||
i2c->write_bytes(I2C_ADDR, I2C_REG_SCROLL, (uint8_t*)&offset, 4);
|
||||
i2c->write_bytes(I2C_ADDR, I2C_REG_SCROLL_BASE + 4*(idx-1), (uint8_t*)&offset, 4);
|
||||
}
|
||||
|
||||
void DVDisplay::set_scroll_idx_for_lines(int idx, int miny, int maxy) {
|
||||
constexpr int buf_size = 32;
|
||||
uint32_t buf[buf_size];
|
||||
uint addr = 4 * (7 + miny);
|
||||
uint line_type = (uint)mode << 28;
|
||||
if (idx >= 0) line_type |= (uint)idx << 30;
|
||||
for (int i = miny; i < maxy; i += buf_size) {
|
||||
int maxj = std::min(buf_size, maxy - i);
|
||||
if (idx >= 0) {
|
||||
for (int j = 0; j < maxj; ++j) {
|
||||
buf[j] = line_type + ((uint32_t)h_repeat << 24) + ((i + j) * frame_width * 6) + base_address;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ram.read_blocking(addr, buf, maxj);
|
||||
for (int j = 0; j < maxj; ++j) {
|
||||
buf[j] &= 0xC0000000;
|
||||
buf[j] |= line_type + ((uint32_t)h_repeat << 24) + ((i + j) * frame_width * 6) + base_address;
|
||||
}
|
||||
}
|
||||
ram.write(addr, buf, maxj * 4);
|
||||
ram.wait_for_finish_blocking();
|
||||
addr += 4 * maxj;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t DVDisplay::get_gpio() {
|
||||
|
@ -294,7 +320,7 @@ namespace pimoroni {
|
|||
{
|
||||
mode = new_mode;
|
||||
rewrite_header = true;
|
||||
write_header();
|
||||
set_scroll_idx_for_lines(-1, 0, display_height);
|
||||
if (mode == MODE_PALETTE) {
|
||||
write_palette();
|
||||
}
|
||||
|
@ -381,19 +407,7 @@ namespace pimoroni {
|
|||
void DVDisplay::write_header()
|
||||
{
|
||||
write_header_preamble();
|
||||
|
||||
uint32_t buf[8];
|
||||
uint addr = 4 * 7;
|
||||
uint line_type = 0x80000000u + ((uint)mode << 28);
|
||||
mp_printf(&mp_plat_print, "Write header, line type %08x\n", line_type);
|
||||
for (int i = 0; i < display_height; i += 8) {
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
buf[j] = line_type + ((uint32_t)h_repeat << 24) + ((i + j) * frame_width * 6) + base_address;
|
||||
}
|
||||
ram.write(addr, buf, 8 * 4);
|
||||
ram.wait_for_finish_blocking();
|
||||
addr += 4 * 8;
|
||||
}
|
||||
set_scroll_idx_for_lines(1, 0, display_height);
|
||||
}
|
||||
|
||||
uint32_t DVDisplay::point_to_address(const Point& p) const {
|
||||
|
|
|
@ -31,8 +31,8 @@ namespace pimoroni {
|
|||
|
||||
// I2C address and registers
|
||||
static constexpr uint I2C_ADDR = 0x0D;
|
||||
static constexpr uint I2C_REG_SET_RES = 0xF8;
|
||||
static constexpr uint I2C_REG_START = 0xF9;
|
||||
static constexpr uint I2C_REG_SET_RES = 0xFC;
|
||||
static constexpr uint I2C_REG_START = 0xFD;
|
||||
static constexpr uint I2C_REG_GPIO = 0xC0;
|
||||
static constexpr uint I2C_REG_LED = 0xC1;
|
||||
static constexpr uint I2C_REG_GPIO_HI = 0xC8;
|
||||
|
@ -41,7 +41,7 @@ namespace pimoroni {
|
|||
static constexpr uint I2C_REG_GPIO_HI_PULL_UP = 0xCB;
|
||||
static constexpr uint I2C_REG_GPIO_HI_PULL_DOWN = 0xCC;
|
||||
static constexpr uint I2C_REG_EDID = 0xED;
|
||||
static constexpr uint I2C_REG_SCROLL = 0xF0;
|
||||
static constexpr uint I2C_REG_SCROLL_BASE = 0xF0;
|
||||
|
||||
//--------------------------------------------------
|
||||
// Variables
|
||||
|
@ -146,9 +146,14 @@ namespace pimoroni {
|
|||
void write_palette_pixel_span(const Point &p, uint l, uint8_t* data);
|
||||
void read_palette_pixel_span(const Point &p, uint l, uint8_t *data);
|
||||
|
||||
// Set the top left corner of the display within the frame, if a larger
|
||||
// frame is specified than the display.
|
||||
void set_display_offset(const Point& p);
|
||||
// Set the scroll offset for a set of scanlines on the display. There are 3 scroll offsets, indexes 1-3.
|
||||
// By default, all scanlines are offset by scroll idx 1, so setting this effectively moves the
|
||||
// top left corner of the display within the frame.
|
||||
void set_display_offset(const Point& p, int idx=1);
|
||||
|
||||
// Configure the scroll offset index to use for a set of scanlines (inclusive of miny, exclusive of maxy),
|
||||
// this applies to the current bank only - you need to set again after flipping to apply the same setting to the other bank.
|
||||
void set_scroll_idx_for_lines(int idx, int miny, int maxy);
|
||||
|
||||
uint8_t get_gpio();
|
||||
uint8_t get_gpio_hi();
|
||||
|
|
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
|
@ -13,7 +13,7 @@ using namespace pimoroni;
|
|||
#define DISPLAY_HEIGHT 480
|
||||
|
||||
#define FRAME_WIDTH 1000
|
||||
#define FRAME_HEIGHT 480
|
||||
#define FRAME_HEIGHT 600
|
||||
|
||||
#define READ_EDID 0
|
||||
#if READ_EDID
|
||||
|
@ -49,7 +49,7 @@ int main() {
|
|||
gpio_set_dir(BUTTON_A, GPIO_IN);
|
||||
gpio_pull_up(BUTTON_A);
|
||||
|
||||
//sleep_ms(5000);
|
||||
sleep_ms(5000);
|
||||
|
||||
DVDisplay display;
|
||||
display.init(DISPLAY_WIDTH, DISPLAY_HEIGHT, DVDisplay::MODE_RGB888, FRAME_WIDTH, FRAME_HEIGHT);
|
||||
|
@ -90,18 +90,23 @@ int main() {
|
|||
printf(".\n");
|
||||
graphics.clear();
|
||||
printf("..\n");
|
||||
display.set_scroll_idx_for_lines(0, 100, 200);
|
||||
display.set_scroll_idx_for_lines(2, 300, FRAME_HEIGHT);
|
||||
display.flip();
|
||||
printf("...\n");
|
||||
sleep_ms(2000);
|
||||
graphics.set_pen(0, 0, 0xFF);
|
||||
graphics.clear();
|
||||
display.set_scroll_idx_for_lines(0, 100, 200);
|
||||
display.set_scroll_idx_for_lines(2, 300, FRAME_HEIGHT);
|
||||
display.flip();
|
||||
|
||||
printf("Starting\n");
|
||||
graphics.set_font("bitmap8");
|
||||
|
||||
Point scroll = {0, 0};
|
||||
int scroll_dir = 1;
|
||||
Point scroll1 = {0, 0};
|
||||
Point scroll2 = {0, 0};
|
||||
int scroll_dir[2] = {1,1};
|
||||
|
||||
constexpr int NUM_CIRCLES = 50;
|
||||
struct Circle {
|
||||
|
@ -204,20 +209,18 @@ int main() {
|
|||
|
||||
//printf("%02x %02x\n", display.get_gpio(), display.get_gpio_hi());
|
||||
|
||||
display.set_display_offset(scroll);
|
||||
#if 1
|
||||
scroll.x += scroll_dir;
|
||||
if (scroll.x + DISPLAY_WIDTH > FRAME_WIDTH || scroll.x < 0) {
|
||||
scroll_dir = -scroll_dir;
|
||||
scroll.x += scroll_dir;
|
||||
display.set_display_offset(scroll1, 1);
|
||||
display.set_display_offset(scroll2, 2);
|
||||
scroll1.x += scroll_dir[0];
|
||||
if (scroll1.x + DISPLAY_WIDTH > FRAME_WIDTH || scroll1.x < 0) {
|
||||
scroll_dir[0] = -scroll_dir[0];
|
||||
scroll1.x += scroll_dir[0];
|
||||
}
|
||||
#else
|
||||
scroll.y += scroll_dir;
|
||||
if (scroll.y + DISPLAY_HEIGHT > FRAME_HEIGHT || scroll.y < 0) {
|
||||
scroll_dir = -scroll_dir;
|
||||
scroll.y += scroll_dir;
|
||||
scroll2.y += scroll_dir[1];
|
||||
if (scroll2.y + DISPLAY_HEIGHT > FRAME_HEIGHT || scroll2.y < 0) {
|
||||
scroll_dir[1] = -scroll_dir[1];
|
||||
scroll2.y += scroll_dir[1];
|
||||
}
|
||||
#endif
|
||||
|
||||
++frames;
|
||||
display.set_gpio_hi_pull_up_all(frames & 0x3F);
|
||||
|
|
Ładowanie…
Reference in New Issue