HUB75 tidyup, examples

pull/193/head
Phil Howard 2021-11-23 12:48:55 +00:00
rodzic c07567f922
commit d4bf69324f
17 zmienionych plików z 188 dodań i 19 usunięć

Wyświetl plik

@ -23,3 +23,4 @@ add_subdirectory(button)
add_subdirectory(plasma)
add_subdirectory(rgbled)
add_subdirectory(icp10125)
add_subdirectory(hub75)

Wyświetl plik

@ -0,0 +1 @@
include(${CMAKE_CURRENT_LIST_DIR}/hub75.cmake)

Wyświetl plik

@ -0,0 +1,11 @@
add_library(hub75 INTERFACE)
target_sources(hub75 INTERFACE
${CMAKE_CURRENT_LIST_DIR}/hub75.cpp)
target_include_directories(hub75 INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need
target_link_libraries(hub75 INTERFACE pico_stdlib hardware_pio hardware_dma)
pico_generate_pio_header(hub75 ${CMAKE_CURRENT_LIST_DIR}/hub75.pio)

Wyświetl plik

@ -38,7 +38,7 @@ Pixel hsv_to_rgb(float h, float s, float v) {
Hub75::Hub75(uint8_t width, uint8_t height, Pixel *buffer, PanelType panel_type)
: width(width), height(height), front_buffer(buffer), back_buffer(buffer + width * height)
: width(width), height(height), panel_type(panel_type)
{
// Set up allllll the GPIO
gpio_init(pin_r0); gpio_set_function(pin_r0, GPIO_FUNC_SIO); gpio_set_dir(pin_r0, true); gpio_put(pin_r0, 0);
@ -59,8 +59,14 @@ Hub75::Hub75(uint8_t width, uint8_t height, Pixel *buffer, PanelType panel_type)
gpio_init(pin_stb); gpio_set_function(pin_stb, GPIO_FUNC_SIO); gpio_set_dir(pin_stb, true); gpio_put(pin_clk, !stb_polarity);
gpio_init(pin_oe); gpio_set_function(pin_oe, GPIO_FUNC_SIO); gpio_set_dir(pin_oe, true); gpio_put(pin_clk, !oe_polarity);
if (panel_type == PANEL_FM6126A) {
FM6126A_setup();
if (buffer == nullptr) {
front_buffer = new Pixel[width * height];
back_buffer = new Pixel[width * height];
managed_buffer = true;
} else {
front_buffer = buffer;
back_buffer = buffer + width * height;
managed_buffer = false;
}
}
@ -135,6 +141,10 @@ void Hub75::start(irq_handler_t handler) {
pio_clear_instruction_memory(pio);
}
if (panel_type == PANEL_FM6126A) {
FM6126A_setup();
}
pio_sm_claim(pio, sm_data);
pio_sm_claim(pio, sm_row);
@ -204,6 +214,10 @@ void Hub75::stop(irq_handler_t handler) {
}
Hub75::~Hub75() {
if (managed_buffer) {
delete[] front_buffer;
delete[] back_buffer;
}
}
void Hub75::clear() {

Wyświetl plik

@ -56,7 +56,9 @@ class Hub75 {
uint8_t height;
Pixel *front_buffer;
Pixel *back_buffer;
bool managed_buffer = false;
bool running = false;
PanelType panel_type;
// DMA & PIO
uint dma_channel = 0;

Wyświetl plik

@ -1 +1,2 @@
include(interstate75_hello_world.cmake)
include(interstate75_hello_world.cmake)
include(interstate75_pio_dma.cmake)

Wyświetl plik

@ -9,8 +9,4 @@ pico_add_extra_outputs(${OUTPUT_NAME})
target_link_libraries(${OUTPUT_NAME}
pico_stdlib
pico_multicore
hardware_pio
hardware_dma
)
pico_generate_pio_header(${OUTPUT_NAME} ${CMAKE_CURRENT_LIST_DIR}/hub75.pio)
)

Wyświetl plik

@ -234,12 +234,14 @@ void hub75_display_update() {
// This latches all the values we've just clocked into the column shift registers.
// The values will appear on the output pins, ready for the display to be driven.
gpio_put(PIN_STB, STB_POLARITY);
asm volatile("nop \nnop"); // Batman!
gpio_put(PIN_STB, !STB_POLARITY);
// 4. Asset the output-enable signal (OE)
// This turns on the display for a brief period to light the selected rows/columns.
gpio_put(PIN_OE, OE_POLARITY);
// 4. Delay
// 5. Delay
// Delay for a period of time coressponding to "bit"'s significance
for(auto s = 0u; s < bit; ++s) {
// The basic premise here is that "bit" will step through the values:
@ -252,12 +254,11 @@ void hub75_display_update() {
asm volatile("nop \nnop"); // Batman!
}
// 5. De-assert latch/strobe signal (STB) + output-enable signal (OE)
// 6. De-assert output-enable signal (OE)
// Ready to go again!
gpio_put(PIN_STB, !STB_POLARITY);
gpio_put(PIN_OE, !OE_POLARITY);
// 6. GOTO 1.
// 7. GOTO 1.
}
sleep_us(1);
}

Wyświetl plik

@ -0,0 +1,13 @@
set(OUTPUT_NAME interstate75_pio_dma)
add_executable(${OUTPUT_NAME} interstate75_pio_dma.cpp)
# enable usb output
pico_enable_stdio_usb(${OUTPUT_NAME} 1)
pico_add_extra_outputs(${OUTPUT_NAME})
target_link_libraries(${OUTPUT_NAME}
pico_stdlib
pico_multicore
hub75
)

Wyświetl plik

@ -0,0 +1,50 @@
#include <stdio.h>
#include <math.h>
#include <cstdint>
#include <cstring>
#include "pico/stdlib.h"
#include "common/pimoroni_common.hpp"
#include "hub75.hpp"
using namespace pimoroni;
// Display size in pixels
// Should be either 64x64 or 32x32 but perhaps 64x32 an other sizes will work.
// Note: this example uses only 5 address lines so it's limited to 32*2 pixels.
const uint8_t WIDTH = 32;
const uint8_t HEIGHT = 32;
Hub75 hub75(WIDTH, HEIGHT, nullptr);
void __isr dma_complete() {
hub75.dma_complete();
}
int main() {
hub75.start(dma_complete);
// Basic loop to draw something to the screen.
// This gets the distance from the middle of the display and uses it to paint a circular colour cycle.
while (true) {
float offset = millis() / 10000.0f;
for(auto x = 0u; x < WIDTH; x++) {
for(auto y = 0u; y < HEIGHT; y++) {
// Center our rainbow circles
float x1 = ((int)x - WIDTH / 2);
float y1 = ((int)y - HEIGHT / 2);
// Get hue as the distance from the display center as float from 0.0 to 1.0f.
float h = float(x1*x1 + y1*y1) / float(WIDTH*WIDTH + HEIGHT*HEIGHT);
// Offset our hue to animate the effect
h -= offset;
hub75.set_hsv(x, y, h, 1.0f, 1.0f);
}
}
hub75.flip();
sleep_ms(1000 / 60);
}
}

Wyświetl plik

@ -0,0 +1,23 @@
import hub75
import time
WIDTH, HEIGHT = 32, 32
hub = hub75.Hub75(WIDTH, HEIGHT, panel_type=hub75.PANEL_GENERIC)
hub.start()
hub.clear()
hub.flip()
while True:
h = time.ticks_ms() / 5000.0
hub.set_all_hsv(h, 1.0, 1.0)
for y in range(8):
for x in range(WIDTH):
c = int(x * 255 / WIDTH)
hub.set_rgb(x, y, c, c, c)
for x in range(WIDTH):
hub.set_rgb(x, x, 255, 0, 0)
hub.set_rgb(WIDTH - 1 - x, x, 255, 0, 0)
hub.flip()
time.sleep(1.0 / 60)

Wyświetl plik

@ -0,0 +1,23 @@
import hub75
import time
WIDTH, HEIGHT = 64, 64
hub = hub75.Hub75(WIDTH, HEIGHT, panel_type=hub75.PANEL_FM6126A)
hub.start()
hub.clear()
hub.flip()
while True:
h = time.ticks_ms() / 5000.0
hub.set_all_hsv(h, 1.0, 1.0)
for y in range(8):
for x in range(WIDTH):
c = int(x * 255 / WIDTH)
hub.set_rgb(x, y, c, c, c)
for x in range(WIDTH):
hub.set_rgb(x, x, 255, 0, 0)
hub.set_rgb(WIDTH - 1 - x, x, 255, 0, 0)
hub.flip()
time.sleep(1.0 / 60)

Wyświetl plik

@ -0,0 +1,23 @@
import hub75
import time
WIDTH, HEIGHT = 64, 64
hub = hub75.Hub75(WIDTH, HEIGHT, panel_type=hub75.PANEL_GENERIC)
hub.start()
hub.clear()
hub.flip()
while True:
h = time.ticks_ms() / 5000.0
hub.set_all_hsv(h, 1.0, 1.0)
for y in range(8):
for x in range(WIDTH):
c = int(x * 255 / WIDTH)
hub.set_rgb(x, y, c, c, c)
for x in range(WIDTH):
hub.set_rgb(x, x, 255, 0, 0)
hub.set_rgb(WIDTH - 1 - x, x, 255, 0, 0)
hub.flip()
time.sleep(1.0 / 60)

Wyświetl plik

@ -1,5 +1,5 @@
#include <cstdio>
#include "lib/hub75.hpp"
#include "hub75.hpp"
#include "pico/multicore.h"
#define MP_OBJ_TO_PTR2(o, t) ((t *)(uintptr_t)(o))
@ -37,19 +37,28 @@ void __isr dma_complete() {
void Hub75_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
(void)kind; // Unused input parameter
_Hub75_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Hub75_obj_t);
mp_print_str(print, "Hub75(");
mp_print_str(print, "Hub75( ");
mp_print_str(print, "dimensions = ");
mp_obj_print_helper(print, mp_obj_new_int(self->hub75->width), PRINT_REPR);
mp_print_str(print, " x ");
mp_obj_print_helper(print, mp_obj_new_int(self->hub75->height), PRINT_REPR);
mp_print_str(print, "addr = front: ");
mp_print_str(print, ", addr = front: ");
mp_obj_print_helper(print, mp_obj_new_int((uint32_t)&self->hub75->front_buffer[0]), PRINT_REPR);
mp_print_str(print, " back: ");
mp_obj_print_helper(print, mp_obj_new_int((uint32_t)&self->hub75->back_buffer[0]), PRINT_REPR);
mp_print_str(print, ")");
switch(self->hub75->panel_type) {
case PANEL_GENERIC:
mp_print_str(print, ", panel: generic ");
break;
case PANEL_FM6126A:
mp_print_str(print, ", panel: generic ");
break;
}
mp_print_str(print, " )");
}
/***** Destructor ******/

Wyświetl plik

@ -3,11 +3,12 @@ add_library(usermod_hub75 INTERFACE)
target_sources(usermod_pico_display INTERFACE
${CMAKE_CURRENT_LIST_DIR}/hub75.c
${CMAKE_CURRENT_LIST_DIR}/hub75.cpp
${CMAKE_CURRENT_LIST_DIR}/lib/hub75.cpp
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/hub75/hub75.cpp
)
target_include_directories(usermod_hub75 INTERFACE
${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/../../../drivers/hub75/
)
target_compile_definitions(usermod_hub75 INTERFACE
@ -22,4 +23,4 @@ set_source_files_properties(
"-Wno-discarded-qualifiers -Wno-implicit-int"
)
pico_generate_pio_header(usermod_hub75 ${CMAKE_CURRENT_LIST_DIR}/lib/hub75.pio)
pico_generate_pio_header(usermod_hub75 ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/hub75/hub75.pio)