Simplify virtual_spitft a bit
This commit is contained in:
parent
9c99e4246d
commit
a4a97b3244
1 changed files with 26 additions and 33 deletions
|
|
@ -6,16 +6,14 @@
|
|||
|
||||
// Configurables ----
|
||||
|
||||
// Your basic 320x240 16-bit color display:
|
||||
DVIGFX16 display(320, 240, dvi_timing_640x480p_60hz, VREG_VOLTAGE_1_20, pimoroni_demo_hdmi_cfg);
|
||||
// Not all RP2040s can deal with the 295 MHz overclock this requires, but if you'd like to try:
|
||||
//DVIGFX16 display(400, 240, dvi_timing_800x480p_60hz, VREG_VOLTAGE_1_30, pimoroni_demo_hdmi_cfg);
|
||||
|
||||
// GPIO connected to (or shared with) TFT control.
|
||||
// Careful not to overlap the DVI pins.
|
||||
#define PIN_DATA 18 // 3 contiguous pins start here: data, DC, clk
|
||||
#define PIN_CS 21 // Chip-select need not be contiguous
|
||||
|
||||
// 320x240 16-bit color display:
|
||||
DVIGFX16 display(320, 240, dvi_timing_640x480p_60hz, VREG_VOLTAGE_1_20, pimoroni_demo_hdmi_cfg);
|
||||
|
||||
// Output of pioasm ----
|
||||
|
||||
#define fourwire_wrap_target 2
|
||||
|
|
@ -46,7 +44,7 @@ static inline pio_sm_config fourwire_program_get_default_config(uint offset) {
|
|||
|
||||
// end pioasm output ----
|
||||
|
||||
PIO pio = pio1; // pio0 is used by libdvi
|
||||
PIO pio = pio1; // libdvi uses pio0 (but has 1 avail state machine if you want to use it)
|
||||
uint sm;
|
||||
uint16_t *framebuf = display.getBuffer();
|
||||
uint8_t decode[256];
|
||||
|
|
@ -80,7 +78,7 @@ uint8_t decode[256];
|
|||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
while(!Serial);
|
||||
//while(!Serial);
|
||||
if (!display.begin()) { // Blink LED if insufficient RAM
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
for (;;) digitalWrite(LED_BUILTIN, (millis() / 500) & 1);
|
||||
|
|
@ -136,47 +134,45 @@ void setup() {
|
|||
// State machine should handle malformed requests somewhat,
|
||||
// e.g. RAMWR writes that wrap around or drop mid-data.
|
||||
|
||||
uint8_t cmd = COMMAND_NOP; // Last received command
|
||||
// Address window and current pixel position:
|
||||
uint16_t X0 = 0, X1 = display.width() - 1, Y0 = 0, Y1 = display.height() - 1;
|
||||
uint16_t x = 0, y = 0;
|
||||
uint8_t cmd = COMMAND_NOP; // Last received command
|
||||
uint16_t X0 = 0, X1 = display.width() - 1; // Address window X
|
||||
uint16_t Y0 = 0, Y1 = display.height() - 1; // Address window Y
|
||||
uint16_t x = 0, y = 0; // Current pixel pos.
|
||||
union { // Data receive buffer sufficient for implemented commands
|
||||
uint8_t b[4];
|
||||
uint16_t w[2];
|
||||
uint32_t l;
|
||||
} buf;
|
||||
uint8_t buflen = 0; // Number of bytes expected following command
|
||||
uint8_t bufidx = 0; // Current position in buf.b[] array
|
||||
int8_t bufidx = -1; // Current pos. in buf.b[] array (or -1 = full)
|
||||
|
||||
for (;;) {
|
||||
uint16_t ww = pio_sm_get_blocking(pio, sm); // Read next word (data & DC interleaved)
|
||||
if ((ww & 0x2)) { // DC bit is set, that means it's data (most common case, hence 1st)
|
||||
if (bufidx < buflen) { // Decode & process only if recv buffer isn't full
|
||||
buf.b[bufidx++] = DECODE(ww);
|
||||
if (bufidx >= buflen) { // Receive threshold reached?
|
||||
if (bufidx >= 0) { // Decode & process only if recv buffer isn't full
|
||||
buf.b[bufidx] = DECODE(ww);
|
||||
// Buffer is filled in reverse so byte swaps aren't needed on uint16_t values
|
||||
if (--bufidx < 0) { // Receive threshold reached?
|
||||
switch (cmd) {
|
||||
case COMMAND_CASET:
|
||||
// Clipping is not performed here because framebuffer
|
||||
// may be a different size than implied SPI device.
|
||||
// That occurs in the RAMWR condition later.
|
||||
X0 = __builtin_bswap16(buf.w[0]);
|
||||
X1 = __builtin_bswap16(buf.w[1]);
|
||||
X0 = buf.w[1]; // [sic.] 1 because buffer is loaded in reverse
|
||||
X1 = buf.w[0];
|
||||
if (X0 > X1) {
|
||||
uint16_t tmp = X0;
|
||||
X0 = X1;
|
||||
X1 = tmp;
|
||||
}
|
||||
buflen = 0; // Disregard any further data
|
||||
break;
|
||||
case COMMAND_PASET:
|
||||
Y0 = __builtin_bswap16(buf.w[0]);
|
||||
Y1 = __builtin_bswap16(buf.w[1]);
|
||||
Y0 = buf.w[1]; // [sic.] 1 because buffer is loaded in reverse
|
||||
Y1 = buf.w[0];
|
||||
if (Y0 > Y1) {
|
||||
uint16_t tmp = Y0;
|
||||
Y0 = Y1;
|
||||
Y1 = tmp;
|
||||
}
|
||||
buflen = 0; // Disregard any further data
|
||||
break;
|
||||
case COMMAND_RAMWR:
|
||||
// Write pixel to screen, increment X/Y, wrap around as needed.
|
||||
|
|
@ -187,14 +183,14 @@ void setup() {
|
|||
// If it's required, then rotation, mirroring and clipping will
|
||||
// all need to be handled in this code...but, can write direct to
|
||||
// framebuffer then, might save some cycles.
|
||||
display.drawPixel(x, y, __builtin_bswap16(buf.w[0]));
|
||||
display.drawPixel(x, y, buf.w[0]);
|
||||
if (++x > X1) {
|
||||
x = X0;
|
||||
if (++y > Y1) {
|
||||
y = Y0;
|
||||
}
|
||||
}
|
||||
bufidx = 0; // Reset for next pixel
|
||||
bufidx = 1; // Reset buffer counter for next pixel
|
||||
// Buflen is left as-is, so more pixels can be processed
|
||||
break;
|
||||
case COMMAND_MADCTL:
|
||||
|
|
@ -216,39 +212,36 @@ void setup() {
|
|||
display.setRotation(3);
|
||||
break;
|
||||
}
|
||||
//madctl = buf.b[0];
|
||||
buflen = 0; // Disregard any further data
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // Is command
|
||||
bufidx = 0; // Reset data recv buffer
|
||||
cmd = DECODE(ww);
|
||||
switch (cmd) {
|
||||
case COMMAND_SWRESET:
|
||||
display.setRotation(0);
|
||||
x = y = X0 = Y0 = buflen = 0;
|
||||
x = y = X0 = Y0 = 0;
|
||||
X1 = display.width() - 1;
|
||||
Y1 = display.height() - 1;
|
||||
break;
|
||||
case COMMAND_CASET:
|
||||
buflen = 4; // Expecting 2 16-bit values (X0, X1)
|
||||
bufidx = 3; // Expecting two 16-bit values (X0, X1)
|
||||
break;
|
||||
case COMMAND_PASET:
|
||||
buflen = 4; // Expecting 2 16-bit values (Y0, Y1)
|
||||
bufidx = 3; // Expecting two 16-bit values (Y0, Y1)
|
||||
break;
|
||||
case COMMAND_RAMWR:
|
||||
buflen = 2; // Expecting 1+ 16-bit values
|
||||
bufidx = 1; // Expecting one 16-bit value (or more)
|
||||
x = X0; // Start at UL of address window
|
||||
y = Y0;
|
||||
break;
|
||||
case COMMAND_MADCTL:
|
||||
buflen = 1; // Expecting 1 8-bit value
|
||||
bufidx = 0; // Expecting one 8-bit value
|
||||
break;
|
||||
default:
|
||||
// Unknown or unimplemented command, discard any data that follows
|
||||
buflen = 0;
|
||||
bufidx = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue