92 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| // 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 |