Skip to content

Commit 840c886

Browse files
committed
First test of support for dual hub75s
1 parent e1e456d commit 840c886

File tree

3 files changed

+46
-12
lines changed

3 files changed

+46
-12
lines changed

drivers/hub75/hub75.cpp

+30-4
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,28 @@
88

99
namespace pimoroni {
1010

11-
Hub75::Hub75(uint width, uint height, Pixel *buffer, PanelType panel_type, bool inverted_stb, COLOR_ORDER color_order)
12-
: width(width), height(height), panel_type(panel_type), inverted_stb(inverted_stb), color_order(color_order)
11+
Hub75::Hub75(uint width, uint height, Pixel *buffer, PanelType panel_type, bool inverted_stb, COLOR_ORDER color_order, bool duo)
12+
: width(width), height(height), panel_type(panel_type), inverted_stb(inverted_stb), color_order(color_order), duo_mode(duo)
1313
{
14+
if(duo) {
15+
pin_r0 += 32;
16+
pin_g0 += 32;
17+
pin_b0 += 32;
18+
pin_r1 += 32;
19+
pin_g1 += 32;
20+
pin_b1 += 32;
21+
pin_row_a += 32;
22+
pin_row_b += 32;
23+
pin_row_c += 32;
24+
pin_row_d += 32;
25+
pin_row_e += 32;
26+
pin_clk += 32;
27+
pin_stb += 32;
28+
pin_oe += 32;
29+
pio = pio1;
30+
pio_set_gpio_base(pio, 16);
31+
}
32+
1433
// Set up allllll the GPIO
1534
gpio_init(pin_r0); gpio_set_function(pin_r0, GPIO_FUNC_SIO); gpio_set_dir(pin_r0, true); gpio_put(pin_r0, 0);
1635
gpio_init(pin_g0); gpio_set_function(pin_g0, GPIO_FUNC_SIO); gpio_set_dir(pin_g0, true); gpio_put(pin_g0, 0);
@@ -159,8 +178,15 @@ void Hub75::start(irq_handler_t handler) {
159178
} else {
160179
row_prog_offs = pio_add_program(pio, &hub75_row_program);
161180
}
162-
hub75_data_rgb888_program_init(pio, sm_data, data_prog_offs, DATA_BASE_PIN, pin_clk);
163-
hub75_row_program_init(pio, sm_row, row_prog_offs, ROWSEL_BASE_PIN, ROWSEL_N_PINS, pin_stb, latch_cycles);
181+
182+
if(duo_mode) {
183+
hub75_data_rgb888_program_init(pio, sm_data, data_prog_offs, DUO_DATA_BASE_PIN, pin_clk);
184+
hub75_row_program_init(pio, sm_row, row_prog_offs, DUO_ROWSEL_BASE_PIN, ROWSEL_N_PINS, pin_stb, latch_cycles);
185+
}
186+
else {
187+
hub75_data_rgb888_program_init(pio, sm_data, data_prog_offs, DATA_BASE_PIN, pin_clk);
188+
hub75_row_program_init(pio, sm_row, row_prog_offs, ROWSEL_BASE_PIN, ROWSEL_N_PINS, pin_stb, latch_cycles);
189+
}
164190

165191
// Prevent flicker in Python caused by the smaller dataset just blasting through the PIO too quickly
166192
pio_sm_set_clkdiv(pio, sm_data, width <= 32 ? 2.0f : 1.0f);

drivers/hub75/hub75.hpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ const uint ROWSEL_BASE_PIN = 6;
1717
const uint ROWSEL_N_PINS = 5;
1818
const uint BIT_DEPTH = 10;
1919

20+
const uint DUO_DATA_BASE_PIN = DATA_BASE_PIN + 32;
21+
const uint DUO_ROWSEL_BASE_PIN = ROWSEL_BASE_PIN + 32;
22+
2023
/*
2124
10-bit gamma table, allowing us to gamma correct our 8-bit colour values up
2225
to 10-bit without losing dynamic range.
@@ -86,6 +89,7 @@ class Hub75 {
8689
PanelType panel_type;
8790
bool inverted_stb = false;
8891
COLOR_ORDER color_order;
92+
bool duo_mode = false;
8993
Pixel background = 0;
9094

9195
// DMA & PIO
@@ -140,7 +144,7 @@ class Hub75 {
140144
Hub75(uint width, uint height) : Hub75(width, height, nullptr) {};
141145
Hub75(uint width, uint height, Pixel *buffer) : Hub75(width, height, buffer, PANEL_GENERIC) {};
142146
Hub75(uint width, uint height, Pixel *buffer, PanelType panel_type) : Hub75(width, height, buffer, panel_type, false) {};
143-
Hub75(uint width, uint height, Pixel *buffer, PanelType panel_type, bool inverted_stb, COLOR_ORDER color_order=COLOR_ORDER::RGB);
147+
Hub75(uint width, uint height, Pixel *buffer, PanelType panel_type, bool inverted_stb, COLOR_ORDER color_order=COLOR_ORDER::RGB, bool duo=false);
144148
~Hub75();
145149

146150
void FM6126A_write_register(uint16_t value, uint8_t position);

micropython/modules/hub75/hub75.cpp

+11-7
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,12 @@ typedef struct _Hub75_obj_t {
4040
void *buf;
4141
} _Hub75_obj_t;
4242

43-
_Hub75_obj_t *hub75_obj;
43+
_Hub75_obj_t *hub75_obj[2];
4444

4545

4646
void __isr dma_complete() {
47-
if(hub75_obj) hub75_obj->hub75->dma_complete();
47+
if(hub75_obj[0]) hub75_obj[0]->hub75->dma_complete();
48+
if(hub75_obj[1]) hub75_obj[1]->hub75->dma_complete();
4849
}
4950

5051
/***** Print *****/
@@ -86,7 +87,8 @@ mp_obj_t Hub75_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, c
8687
ARG_buffer,
8788
ARG_panel_type,
8889
ARG_stb_invert,
89-
ARG_color_order
90+
ARG_color_order,
91+
ARG_duo
9092
};
9193
static const mp_arg_t allowed_args[] = {
9294
{ MP_QSTR_width, MP_ARG_REQUIRED | MP_ARG_INT },
@@ -95,6 +97,7 @@ mp_obj_t Hub75_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, c
9597
{ MP_QSTR_panel_type, MP_ARG_INT, {.u_int = 0} },
9698
{ MP_QSTR_stb_invert, MP_ARG_INT, {.u_int = 0} },
9799
{ MP_QSTR_color_order, MP_ARG_INT, {.u_int = (uint8_t)Hub75::COLOR_ORDER::RGB} },
100+
{ MP_QSTR_duo, MP_ARG_INT, {.u_int = 0} },
98101
};
99102

100103
// Parse args.
@@ -106,6 +109,7 @@ mp_obj_t Hub75_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, c
106109
PanelType paneltype = (PanelType)args[ARG_panel_type].u_int;
107110
bool stb_invert = args[ARG_stb_invert].u_int;
108111
Hub75::COLOR_ORDER color_order = (Hub75::COLOR_ORDER)args[ARG_color_order].u_int;
112+
bool duo_mode = args[ARG_duo].u_int;
109113

110114
Pixel *buffer = nullptr;
111115

@@ -120,11 +124,11 @@ mp_obj_t Hub75_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, c
120124
buffer = m_new(Pixel, width * height);
121125
}
122126

123-
hub75_obj = mp_obj_malloc_with_finaliser(_Hub75_obj_t, &Hub75_type);
124-
hub75_obj->buf = buffer;
125-
hub75_obj->hub75 = m_new_class(Hub75, width, height, buffer, paneltype, stb_invert, color_order);
127+
hub75_obj[duo_mode] = mp_obj_malloc_with_finaliser(_Hub75_obj_t, &Hub75_type);
128+
hub75_obj[duo_mode]->buf = buffer;
129+
hub75_obj[duo_mode]->hub75 = m_new_class(Hub75, width, height, buffer, paneltype, stb_invert, color_order, duo_mode);
126130

127-
return MP_OBJ_FROM_PTR(hub75_obj);
131+
return MP_OBJ_FROM_PTR(hub75_obj[duo_mode]);
128132
}
129133

130134
mp_obj_t Hub75_clear(mp_obj_t self_in) {

0 commit comments

Comments
 (0)