mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-09-08 15:59:08 +00:00
Multi screen support, with dyn alignment (#2801)
This commit is contained in:
@@ -102,6 +102,56 @@ void lcd_init() {
|
||||
// LCDs are configured for IM[2:0] = 001
|
||||
// 8080-I system, 16-bit parallel bus
|
||||
|
||||
io.lcd_data_write_command_and_data(0xE0, {0x00, 0x09, 0x0C, 0x03, 0x10, 0x06, 0x34, 0x68,
|
||||
0x49, 0x02, 0x0A, 0x07, 0x2C, 0x31, 0x0F});
|
||||
|
||||
io.lcd_data_write_command_and_data(0xE1, {0x00, 0x12, 0x15, 0x02, 0x10, 0x06, 0x35, 0x35,
|
||||
0x4A, 0x05, 0x10, 0x0C, 0x2F, 0x33, 0x0F});
|
||||
|
||||
io.lcd_data_write_command_and_data(0xC0, {0x0F, 0x0F}); // Vreg1out=4.5 Vreg2out=-4.5
|
||||
|
||||
io.lcd_data_write_command_and_data(0xC1, {0x44}); // VGH = 5*VCI VGL = -4*VCI
|
||||
|
||||
io.lcd_data_write_command_and_data(0xC5, {0x00, 0x66, 0x80}); // VCOM
|
||||
|
||||
io.lcd_data_write_command_and_data(0x36, {
|
||||
(1 << 7) | // MY=1
|
||||
(0 << 6) | // MX=0
|
||||
(0 << 5) | // MV=0
|
||||
(1 << 4) | // ML=1: reverse vertical refresh to simplify scrolling logic
|
||||
(1 << 3) // BGR=1: For Kingtech LCD, BGR filter.
|
||||
});
|
||||
|
||||
// io.lcd_data_write_command_and_data(0x36, {0x48});
|
||||
io.lcd_data_write_command_and_data(0x3A, {0x65}); // 0x55 was the original
|
||||
// 这里的刷新率过低?
|
||||
// io.lcd_data_write_command_and_data(0xB1, {0x40, 0x1F}); // fix 60 fps
|
||||
io.lcd_data_write_command_and_data(0xB1, {0xA0, 0x11}); // Frame rate source is 11fps
|
||||
|
||||
io.lcd_data_write_command_and_data(0xB4, {0x02}); // 2 dot inversion
|
||||
|
||||
io.lcd_data_write_command_and_data(0xEE, {0x00, 0x04});
|
||||
|
||||
io.lcd_data_write_command_and_data(0xE9, {0x00});
|
||||
|
||||
io.lcd_data_write_command_and_data(0xF7, {0xA9, 0x51, 0x2C, 0x82});
|
||||
|
||||
io.lcd_data_write_command_and_data(0x21, {}); // Display Inversion On
|
||||
|
||||
io.lcd_data_write_command_and_data(0x11, {}); // Sleep Out
|
||||
chThdSleepMilliseconds(120); // Delay 120ms
|
||||
|
||||
io.lcd_data_write_command_and_data(0x29, {}); // Display On
|
||||
chThdSleepMilliseconds(50); // Delay 50ms
|
||||
|
||||
// Turn on Tearing Effect Line (TE) output signal.
|
||||
io.lcd_data_write_command_and_data(0x35, {0b00000000});
|
||||
}
|
||||
|
||||
void lcd_init_pp() {
|
||||
// LCDs are configured for IM[2:0] = 001
|
||||
// 8080-I system, 16-bit parallel bus
|
||||
|
||||
//
|
||||
// 0x3a: DBI[2:0] = 101
|
||||
// MDT[1:0] = XX (if not in 18-bit mode, right?)
|
||||
@@ -281,6 +331,16 @@ void lcd_vertical_scrolling_start_address(
|
||||
|
||||
} // namespace
|
||||
|
||||
uint32_t ILI9341::lcd_read_display_id() {
|
||||
io.lcd_data_write_command_and_data(0x04, {});
|
||||
io.lcd_read_data_raw();
|
||||
|
||||
uint32_t value3 = io.lcd_read_data_raw();
|
||||
uint32_t value4 = io.lcd_read_data_raw();
|
||||
uint32_t value5 = io.lcd_read_data_raw();
|
||||
return value5 + (value4 << 8) + (value3 << 16);
|
||||
}
|
||||
|
||||
bool ILI9341::read_display_status() {
|
||||
lcd_reset();
|
||||
uint32_t display_status = lcd_read_display_status();
|
||||
@@ -302,7 +362,32 @@ bool ILI9341::read_display_status() {
|
||||
|
||||
void ILI9341::init() {
|
||||
lcd_reset();
|
||||
lcd_init();
|
||||
bool hpp = false;
|
||||
// detect method 1
|
||||
uint32_t id = lcd_read_display_id();
|
||||
if (id == 5537894) hpp = true;
|
||||
|
||||
// detect method 2 - not working!
|
||||
if (!hpp) {
|
||||
draw_pixel({318, 478}, ui::Color::red());
|
||||
fill_rectangle_unrolled8({0, 0, 240, 320}, ui::Color::black());
|
||||
std::vector<ui::ColorRGB888> checker(1);
|
||||
read_pixels({318, 478, 1, 1}, checker.data(), 1);
|
||||
if (checker[0].b <= 10 && checker[0].g <= 10 && checker[0].r >= 100)
|
||||
hpp = true;
|
||||
}
|
||||
// init screen
|
||||
if (hpp) {
|
||||
device_type = DEV_PORTARF;
|
||||
lcd_init();
|
||||
screen_width = 320;
|
||||
screen_height = 480;
|
||||
} else {
|
||||
device_type = DEV_PORTAPACK;
|
||||
lcd_init_pp();
|
||||
screen_width = 240;
|
||||
screen_height = 320;
|
||||
}
|
||||
}
|
||||
|
||||
void ILI9341::shutdown() {
|
||||
@@ -335,7 +420,7 @@ void ILI9341::fill_rectangle_unrolled8(ui::Rect r, const ui::Color c) {
|
||||
}
|
||||
}
|
||||
|
||||
void ILI9341::render_line(const ui::Point p, const uint8_t count, const ui::Color* line_buffer) {
|
||||
void ILI9341::render_line(const ui::Point p, const uint16_t count, const ui::Color* line_buffer) {
|
||||
lcd_start_ram_write(p, {count, 1});
|
||||
io.lcd_write_pixels(line_buffer, count);
|
||||
}
|
||||
@@ -473,8 +558,8 @@ bool ILI9341::draw_bmp_from_sdcard_file(const ui::Point p, const std::filesystem
|
||||
bmp_header_t bmp_header;
|
||||
uint8_t type = 0;
|
||||
char buffer[257];
|
||||
ui::Color line_buffer[240];
|
||||
|
||||
ui::Color line_buffer[320];
|
||||
int16_t start_x = p.x();
|
||||
auto result = bmpimage.open(file);
|
||||
if (result.is_valid())
|
||||
return false;
|
||||
@@ -508,8 +593,8 @@ bool ILI9341::draw_bmp_from_sdcard_file(const ui::Point p, const std::filesystem
|
||||
|
||||
width = bmp_header.width;
|
||||
height = bmp_header.height;
|
||||
|
||||
if (width != 240)
|
||||
start_x = (screen_width - start_x - width) / 2 + start_x; // center horizontally
|
||||
if (width > screen_width || width > 320)
|
||||
return false;
|
||||
|
||||
file_pos = bmp_header.image_data;
|
||||
@@ -560,7 +645,7 @@ bool ILI9341::draw_bmp_from_sdcard_file(const ui::Point p, const std::filesystem
|
||||
if (read_size.value() != 256)
|
||||
break;
|
||||
}
|
||||
render_line({p.x(), p.y() + py}, px, line_buffer);
|
||||
render_line({start_x, p.y() + py}, px, line_buffer);
|
||||
px = 0;
|
||||
py--;
|
||||
|
||||
@@ -668,7 +753,7 @@ void ILI9341::draw_bitmap(
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const auto pixel = pixels[i >> 3] & (1U << (i & 0x7));
|
||||
if (pixel) {
|
||||
draw_pixel(ui::Point(x, y), foreground);
|
||||
if (x <= screen_width && y <= screen_height) draw_pixel(ui::Point(x, y), foreground);
|
||||
}
|
||||
// move to next px
|
||||
x++;
|
||||
@@ -740,8 +825,12 @@ ui::Coord ILI9341::scroll_area_y(const ui::Coord y) const {
|
||||
}
|
||||
|
||||
void ILI9341::scroll_disable() {
|
||||
lcd_vertical_scrolling_definition(0, height(), 0);
|
||||
lcd_vertical_scrolling_start_address(0);
|
||||
if (device_type == DEV_PORTAPACK) {
|
||||
lcd_vertical_scrolling_definition(0, height(), 0);
|
||||
lcd_vertical_scrolling_start_address(0);
|
||||
} else {
|
||||
io.lcd_data_write_command_and_data(0x13, {}); // normal mode
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace lcd */
|
||||
|
||||
Reference in New Issue
Block a user