// Raspberry Pi Pico PIO program to output data to a TFT // controller via a 8 bit 8080 style data path. // Original sourced from: // https://github.com/zapta/pio_tft // Side set: 1 output pin, TFT_WR. Active low. // Data set: 8 consecutive output pins, TFT_D0 .. TFT_D7 .program tft_io .side_set 1 opt ; The TFT_WR output. // The C++ code switches between the different SM routines // by waiting for the SM to be idle and setting its PC. // The default SM routine is a 16 bit transfer // Do a block fill of N+1 pixels. public block_fill: // Fetch colour value. pull side 1 // Move colour to x. mov x, osr // Fetch pixel count N (sends N+1 pixels). pull // Move pixel count to y. mov y, osr next: // Copy colour value into osr, colour in LS 16 bits. mov osr, x side 1 // Output colour 8 MS bits, unwanted top 16 bits shifted through. out pins, 24 side 0 [1] // Write first colour byte. nop side 1 [1] // Write second colour byte. out pins, 8 side 0 [1] // Decrement pixel count and loop. jmp y--, next side 1 .wrap_target // Transmit a 16 bit value (LS 16 bits of 32 bits). public start_tx: // Fetch the next 32 bit value from the TX FIFO and set TFT_WR high. pull side 1 // Write the first byte (MSB) and set WR low. This also // shifts the unused top 16 bits through. out pins, 24 side 0 [1] // Set WR high and delay to next byte. nop side 1 [1] // Output the second byte and set TFT_WRITE low. out pins, 8 side 0 [1] // Set WR high and jump back to start. jmp start_tx side 1 // Transmit an 8 bit value (LS 8 bits of 32 bits). public start_8: // Fetch the next 32 bit value from the TX FIFO and set TFT_WR high. pull side 1 // Write the first byte (LSB) and sets WR low. This also // shifts the unused top 24 bits through. out pins, 32 side 0 [1] // Jump to start jmp start_tx side 1 // Transmit a set window command sequence. public set_addr_window: // Loop count in x (to send caset, paset and ramwr commands). set x, 2 side 1 pull_cmd: // Set TFT_DC low. set pins, 0 // Fetch caset, paset or ramwr. pull // Output LS byte (caset, paset or ramwr), discarding top 24 bits, set TFT_WR low. out pins, 32 side 0 // Jump to end if 3rd cmd byte ramwr sent (x == 0) jmp !x, end_set_addr // pull next start and end coordinates, TFT_WR high. pull side 1 // Set TFT_DC high. set pins, 1 send_xy: // Output byte, TFT_WR low. out pins, 8 side 0 [1] // Loop until 4 bytes sent, TFT_WR high. jmp !osre, send_xy side 1 [1] end_set_addr: // Loop back for next command and write last command. jmp x--, pull_cmd side 1 // Set DC high. set pins, 1 // Auto-wrap back to start_tx. .wrap