kopia lustrzana https://github.com/pimoroni/pimoroni-pico
HUB75 tidyup, examples
rodzic
c07567f922
commit
d4bf69324f
|
@ -23,3 +23,4 @@ add_subdirectory(button)
|
|||
add_subdirectory(plasma)
|
||||
add_subdirectory(rgbled)
|
||||
add_subdirectory(icp10125)
|
||||
add_subdirectory(hub75)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
include(${CMAKE_CURRENT_LIST_DIR}/hub75.cmake)
|
|
@ -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)
|
|
@ -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() {
|
|
@ -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;
|
|
@ -1 +1,2 @@
|
|||
include(interstate75_hello_world.cmake)
|
||||
include(interstate75_pio_dma.cmake)
|
|
@ -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)
|
||||
)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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 ******/
|
||||
|
|
|
@ -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)
|
Ładowanie…
Reference in New Issue