Skip to content

Commit b68d100

Browse files
committed
o Next step in avoiding the need to re-compile: make hardware GPIO
mapping choosable at run-time (and hence: via command line flag). Now, Adafruit HAT users don't have to recompile.
1 parent 9cbb4e1 commit b68d100

21 files changed

+504
-345
lines changed

README.md

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ This documentation is split into parts that help you through the process
8484
* <a href="wiring.md"><img src="img/wire-up-icon.png"></a>
8585
[Wire up the matrix to your Pi](./wiring.md). This document describes what
8686
goes where. You might also be interested in [breakout boards](./adapter)
87-
for that. If you have an [Adafruit HAT], necessary steps are
88-
[described below](#if-you-have-an-adafruit-hat)
87+
for that. If you have an [Adafruit HAT], you can choose that with
88+
a command line option [described below](#if-you-have-an-adafruit-hat)
8989
* Run a demo. You find that in the
9090
[examples-api-use/](./examples-api-use#running-some-demos) directory:
9191
```
@@ -133,8 +133,22 @@ Some might need to be changed for your particular kind of panel.
133133
Here is a little run-down of what these command-line flags do and when you'd
134134
like to change them.
135135

136+
First things first: if you have a different wiring than described in
137+
[wiring](./wiring.md), for instance if you have an Adafruit HAT, you can
138+
choose these here:
139+
140+
```
141+
--led-gpio-mapping=<gpio-mapping>: Name of GPIO mapping used. Default "regular"
142+
```
143+
144+
This can have values such as
145+
- `--led-gpio-mapping=regular` The standard mapping of this library, described in the [wiring](./wiring.md) page.
146+
- `--led-gpio-mapping=adafruit-hat` standard Adafruit HAT or
147+
- `--led-gpio-mapping=adafruit-hat-pwm` Adafruit HAT with the anti-flicker hardware mod [described below](#improving-flicker).
148+
149+
The next most important flags describe the type and number of displays connected
150+
136151
```
137-
# These are the most important
138152
--led-rows=<rows> : Panel rows. 8, 16, 32 or 64. (Default: 32).
139153
--led-chain=<chained> : Number of daisy-chained panels. (Default: 1).
140154
--led-parallel=<parallel> : For A/B+ models or RPi2,3b: parallel chains. range=1..3 (Default: 1).
@@ -365,16 +379,19 @@ ready-made vs. single-chain tradeoff is worthwhile, then you might go for that
365379
The Adafruit HAT uses this library but a modified pinout to support other
366380
features on the HAT. So they forked this library and modified the pinout there.
367381
However, that fork is _ancient_, so I strongly suggest to use this original
368-
library instead - which in the meantime also has a way to switch to their pinout.
382+
library instead. You can choose the Adafruit pinout with a command line flag.
369383

370-
In this library here, you can choose the Adafruit HAT pinout by editing
371-
`lib/Makefile` and change `HARDWARE_DESC?=regular` to `HARDWARE_DESC=adafruit-hat`.
384+
Just pass the option `--led-gpio-mapping=adafruit-hat`.
372385

373-
Alternatively, you can prefix the compilation call with this variable like so:
386+
If you want to have this the default whenever you start (or if you are using
387+
the Python library that does not support to set this at runtime yet), add the
388+
following setting in front of your compilation:
374389
```
375390
HARDWARE_DESC=adafruit-hat make
376391
```
377-
Then re-compile and a display connected to the HAT should work.
392+
(alternatively, you can modify the `lib/Makefile` and change it there directly)
393+
Then re-compile and the new flag default is now `adafruit-hat`, so
394+
no need to set it on the command line.
378395

379396
### Improving flicker
380397

@@ -384,14 +401,17 @@ following picture (click to enlarge):
384401

385402
<a href="img/adafruit-mod.jpg"><img src="img/adafruit-mod.jpg" height="80px"></a>
386403

387-
Then, uncomment the following line in the Makefile and recompile.
404+
Then, start your programs with `--led-gpio-mapping=adafruit-hat-pwm`.
388405

406+
If you want to make this the default setting your program starts with, you can
407+
also manually choose this with
389408
```
390-
#DEFINES+=-DADAFRUIT_RGBMATRIX_HAT_PWM
409+
HARDWARE_DESC=adafruit-hat-pwm make
391410
```
411+
to get this as default setting.
392412

393-
Reboot the Pi and you now should have less visible flicker. This essentially
394-
gives you the hardware pulses feature.
413+
Now you should have less visible flicker. This essentially
414+
switches on the hardware pulses feature for the Adafruit HAT.
395415

396416
### 64x64 with E-line on Adafruit HAT
397417
There are LED panels that have 64x64 LEDs packed, but they need 5 address lines,

examples-api-use/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Options:
1717
in the middle in an U-arrangement to get more vertical space.
1818
-R <rotation> : Sets the rotation of matrix. Allowed: 0, 90, 180, 270. Default: 0.
1919
-t <seconds> : Run for these number of seconds, then exit.
20+
--led-gpio-mapping=<name> : Name of GPIO mapping used. Default "regular"
2021
--led-rows=<rows> : Panel rows. 8, 16, 32 or 64. (Default: 32).
2122
--led-chain=<chained> : Number of daisy-chained panels. (Default: 1).
2223
--led-parallel=<parallel> : For A/B+ models or RPi2,3b: parallel chains. range=1..3 (Default: 1).
@@ -86,6 +87,7 @@ using rgb_matrix::RGBMatrix;
8687
int main(int argc, char **argv) {
8788
// Set some defaults
8889
RGBMatrix::Options my_defaults;
90+
my_defaults.hardware_mapping = "regular"; // or e.g. "adafruit-hat" or "adafruit-hat-pwm"
8991
my_defaults.chain_length = 3;
9092
my_defaults.show_refresh_rate = true;
9193
rgb_matrix::RuntimeOptions runtime_defaults;

examples-api-use/c-example.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
#include "led-matrix-c.h"
77

8+
#include <stdio.h>
89
#include <string.h>
910
#include <unistd.h>
1011

@@ -31,6 +32,10 @@ int main(int argc, char **argv) {
3132
offscreen_canvas = led_matrix_create_offscreen_canvas(matrix);
3233

3334
led_canvas_get_size(offscreen_canvas, &width, &height);
35+
36+
fprintf(stderr, "Size: %dx%d. Hardware gpio mapping: %s\n",
37+
width, height, options.hardware_mapping);
38+
3439
for (i = 0; i < 1000; ++i) {
3540
for (y = 0; y < height; ++y) {
3641
for (x = 0; x < width; ++x) {

examples-api-use/demo-main.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,8 @@ int main(int argc, char *argv[]) {
11601160
matrix->ApplyStaticTransformer(RotateTransformer(rotation));
11611161
}
11621162

1163-
printf("Size: %dx%d\n", matrix->width(), matrix->height());
1163+
printf("Size: %dx%d. Hardware gpio mapping: %s\n",
1164+
matrix->width(), matrix->height(), matrix_options.hardware_mapping);
11641165

11651166
Canvas *canvas = matrix;
11661167

examples-api-use/minimal-example.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ static void DrawOnCanvas(Canvas *canvas) {
4545

4646
int main(int argc, char *argv[]) {
4747
RGBMatrix::Options defaults;
48+
defaults.hardware_mapping = "regular"; // or e.g. "adafruit-hat"
4849
defaults.rows = 32;
4950
defaults.chain_length = 1;
5051
defaults.parallel = 1;

include/led-matrix-c.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ struct LedCanvas;
4343
* should zero out this struct before setting anything.
4444
*/
4545
struct RGBLedMatrixOptions {
46+
/*
47+
* Name of the hardware mapping used. If passed NULL here, the default
48+
* is used.
49+
*/
50+
const char *hardware_mapping;
51+
4652
/* The "rows" are the number of rows supported by the display, so 32 or 16.
4753
* Default: 32.
4854
* Corresponding flag: --led-rows

include/led-matrix.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ class RGBMatrix : public Canvas {
6161
// Returns 'true' if all options look good.
6262
bool Validate(std::string *err) const;
6363

64+
// Name of the hardware mapping. Something like "regular" or "adafruit-hat"
65+
const char *hardware_mapping;
66+
6467
// The "rows" are the number
6568
// of rows supported by the display, so 32 or 16. Default: 32.
6669
// Flag: --led-rows

lib/Makefile

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,32 @@
44
# -lrgbmatrix
55
##
66
OBJECTS=gpio.o led-matrix.o options-initialize.o framebuffer.o \
7-
thread.o bdf-font.o graphics.o transformer.o led-matrix-c.o
7+
thread.o bdf-font.o graphics.o transformer.o led-matrix-c.o \
8+
hardware-mapping.o
89
TARGET=librgbmatrix
910

1011
# There are several different pinouts for various breakout boards that uses
1112
# this library. If you are using the described pinout in the toplevel README.md
1213
# or the standard active-3 breakout board, then 'regular' is the one you'd like
13-
# to use (there is also a 'classic' one for an early form).
14+
# to use.
1415
#
1516
# Adafruit also made a breakout board, if you want to use that, choose
1617
# 'adafruit-hat'
1718
#
1819
# These are the choices
1920
# regular # Following this project wiring and using these PCBs
2021
# adafruit-hat # If you have a RGB matrix HAT from Adafruit
21-
# classic # Not really used anymore
22+
# adafruit-hat-pwm # If you have an Adafruit HAT with PWM hardware mod.
23+
# classic # (deprecated) Classic Pi1/2/. Not used anymore.
24+
# classic-pi1 # (deprecated) Classic pinout on Rasperry Pi 1
2225
HARDWARE_DESC?=regular
2326

2427
###
2528
# After you change any of the following DEFINES, make sure to 'make' again.
2629
#
27-
# Note, all of these options that don't directly influence the hardware mapping
28-
# can now can be set programmatically and via command line flags as well.
29-
# So be prepared for these to be removed in this Makefile.
30+
# Note, all of these options can now can be set programmatically and
31+
# via command line flags as well. No real need to change them in the Makefile.
32+
# (So be prepared for these to be removed at some point)
3033
###
3134

3235
# If you see that your display is inverse, you might have a matrix variant
@@ -105,12 +108,9 @@ HARDWARE_DESC?=regular
105108
# connect GPIO 4 (old OE) with 18 (the new OE); there are
106109
# convenient solder holes labeled 4 and 18 on the Adafruit HAT, pretty
107110
# close together.
108-
# Then uncomment the following define and recompile.
109-
#DEFINES+=-DADAFRUIT_RGBMATRIX_HAT_PWM
110-
111-
# If you use HARDWARE_DESC=classic and a Raspberry Pi 1, Revision A,
112-
# this might be useful (untested).
113-
#DEFINES+=-DPI_REV1_RGB_PINOUT
111+
# Then you can set the flag --led-gpio-mapping=adafruit-hat-pwm
112+
# .. or uncomment the following line.
113+
#HARDWARE_DESC=adafruit-hat-pwm
114114

115115
# Typically, a Hub75 panel is split in two half displays, so that a 1:16
116116
# multiplexing actually multiplexes over two half displays and gives 32 lines.
@@ -125,8 +125,10 @@ HARDWARE_DESC?=regular
125125
# make USER_DEFINES="-DSHOW_REFRESH_RATE"
126126
DEFINES+=$(USER_DEFINES)
127127

128+
DEFINES+=-DDEFAULT_HARDWARE='"$(HARDWARE_DESC)"'
128129
INCDIR=../include
129-
CXXFLAGS=-Wall -O3 -g -fPIC $(DEFINES) -Ihardware/$(HARDWARE_DESC)
130+
CFLAGS=-Wall -O3 -g -fPIC $(DEFINES)
131+
CXXFLAGS=$(CFLAGS)
130132

131133
all : $(TARGET).a $(TARGET).so.1
132134

@@ -144,11 +146,13 @@ graphics.o: graphics.cc utf8-internal.h
144146
%.o : %.cc compiler-flags
145147
$(CXX) -I$(INCDIR) $(CXXFLAGS) -c -o $@ $<
146148

149+
%.o : %.c compiler-flags
150+
$(CC) -I$(INCDIR) $(CXXFLAGS) -c -o $@ $<
151+
147152
clean:
148153
rm -f $(OBJECTS) $(TARGET).a $(TARGET).so.1
149154

150155
compiler-flags: FORCE
151-
@if [ ! -d hardware/$(HARDWARE_DESC) ] ; then echo "HARDWARE_DESC='$(HARDWARE_DESC)' is an unsupported hardware description. Typo ?"; exit 1; fi
152156
@echo '$(CXX) $(CXXFLAGS)' | cmp -s - $@ || echo '$(CXX) $(CXXFLAGS)' > $@
153157

154158
.PHONY: FORCE

lib/framebuffer-internal.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
#include <stdint.h>
1919

20+
#include "hardware-mapping.h"
21+
2022
namespace rgb_matrix {
2123
class GPIO;
2224
class PinPulser;
@@ -64,6 +66,7 @@ class Framebuffer {
6466
~Framebuffer();
6567

6668
// Initialize GPIO bits for output. Only call once.
69+
static void InitHardwareMapping(const char *named_hardware);
6770
static void InitGPIO(GPIO *io, int rows, int parallel,
6871
bool allow_hardware_pulsing,
6972
int pwm_lsb_nanoseconds);
@@ -96,9 +99,7 @@ class Framebuffer {
9699
void Fill(uint8_t red, uint8_t green, uint8_t blue);
97100

98101
private:
99-
// Define the type to do the pin-mapping. These are include fils
100-
// found in include directory hardware/$(name-of-mapping)
101-
#include "led-panel-pin-mapping.h" // see HARDWARE_DESC in lib/Makefile
102+
static const struct HardwareMapping *hardware_mapping_;
102103

103104
void InitDefaultDesignator(int x, int y, PixelDesignator *designator);
104105
inline void MapColors(uint8_t r, uint8_t g, uint8_t b,
@@ -125,11 +126,8 @@ class Framebuffer {
125126
// Each bitplane-column is pre-filled IoBits, of which the colors are set.
126127
// Of course, that means that we store unrelated bits in the frame-buffer,
127128
// but it allows easy access in the critical section.
128-
IoBits *bitplane_buffer_;
129-
inline IoBits *ValueAt(int double_row, int column, int bit);
130-
inline IoBits &color_bits(uint32_t *val) {
131-
return *reinterpret_cast<IoBits*>(val);
132-
}
129+
gpio_bits_t *bitplane_buffer_;
130+
inline gpio_bits_t *ValueAt(int double_row, int column, int bit);
133131

134132
PixelMapper **shared_mapper_; // Storage in RGBMatrix.
135133
};

0 commit comments

Comments
 (0)