79 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			79 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /**
 | |
|  * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-3-Clause
 | |
|  */
 | |
| 
 | |
| #include <stdio.h>
 | |
| 
 | |
| #include "pico/stdlib.h"
 | |
| #include "hardware/gpio.h"
 | |
| #include "hardware/pio.h"
 | |
| #include "hub75.pio.h"
 | |
| 
 | |
| #include "mountains_128x64_rgb565.h"
 | |
| 
 | |
| #define DATA_BASE_PIN 0
 | |
| #define DATA_N_PINS 6
 | |
| #define ROWSEL_BASE_PIN 6
 | |
| #define ROWSEL_N_PINS 5
 | |
| #define CLK_PIN 11
 | |
| #define STROBE_PIN 12
 | |
| #define OEN_PIN 13
 | |
| 
 | |
| #define WIDTH 128
 | |
| #define HEIGHT 64
 | |
| 
 | |
| static inline uint32_t gamma_correct_565_888(uint16_t pix) {
 | |
|     uint32_t r_gamma = pix & 0xf800u;
 | |
|     r_gamma *= r_gamma;
 | |
|     uint32_t g_gamma = pix & 0x07e0u;
 | |
|     g_gamma *= g_gamma;
 | |
|     uint32_t b_gamma = pix & 0x001fu;
 | |
|     b_gamma *= b_gamma;
 | |
|     return (b_gamma >> 2 << 16) | (g_gamma >> 14 << 8) | (r_gamma >> 24 << 0);
 | |
| }
 | |
| 
 | |
| int main() {
 | |
|     stdio_init_all();
 | |
| 
 | |
|     PIO pio = pio0;
 | |
|     uint sm_data = 0;
 | |
|     uint sm_row = 1;
 | |
| 
 | |
|     uint data_prog_offs = pio_add_program(pio, &hub75_data_rgb888_program);
 | |
|     uint row_prog_offs = pio_add_program(pio, &hub75_row_program);
 | |
|     hub75_data_rgb888_program_init(pio, sm_data, data_prog_offs, DATA_BASE_PIN, CLK_PIN);
 | |
|     hub75_row_program_init(pio, sm_row, row_prog_offs, ROWSEL_BASE_PIN, ROWSEL_N_PINS, STROBE_PIN);
 | |
| 
 | |
|     static uint32_t gc_row[2][WIDTH];
 | |
|     const uint16_t *img = (const uint16_t*)mountains_128x64;
 | |
| 
 | |
|     while (1) {
 | |
|         for (int rowsel = 0; rowsel < (1 << ROWSEL_N_PINS); ++rowsel) {
 | |
|             for (int x = 0; x < WIDTH; ++x) {
 | |
|                 gc_row[0][x] = gamma_correct_565_888(img[rowsel * WIDTH + x]);
 | |
|                 gc_row[1][x] = gamma_correct_565_888(img[((1u << ROWSEL_N_PINS) + rowsel) * WIDTH + x]);
 | |
|             }
 | |
|             for (int bit = 0; bit < 8; ++bit) {
 | |
|                 hub75_data_rgb888_set_shift(pio, sm_data, data_prog_offs, bit);
 | |
|                 for (int x = 0; x < WIDTH; ++x) {
 | |
|                     pio_sm_put_blocking(pio, sm_data, gc_row[0][x]);
 | |
|                     pio_sm_put_blocking(pio, sm_data, gc_row[1][x]);
 | |
|                 }
 | |
|                 // Dummy pixel per lane
 | |
|                 pio_sm_put_blocking(pio, sm_data, 0);
 | |
|                 pio_sm_put_blocking(pio, sm_data, 0);
 | |
|                 // SM is finished when it stalls on empty TX FIFO
 | |
|                 hub75_wait_tx_stall(pio, sm_data);
 | |
|                 // Also check that previous OEn pulse is finished, else things can get out of sequence
 | |
|                 hub75_wait_tx_stall(pio, sm_row);
 | |
| 
 | |
|                 // Latch row data, pulse output enable for new row.
 | |
|                 pio_sm_put_blocking(pio, sm_row, rowsel | (100u * (1u << bit) << 5));
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
| }
 |