/ README.md
README.md
  1  # Adafruit_Protomatter
  2  
  3  "I used protomatter in the Genesis matrix." - David Marcus, Star Trek III
  4  
  5  Code for driving HUB75-style RGB LED matrices, targeted at 32-bit MCUs
  6  using brute-force GPIO (that is, not relying on DMA or other specialized
  7  peripherals beyond a timer interrupt, goal being portability).
  8  
  9  Name might change as it's nondescriptive and tedious to type in code.
 10  
 11  # Matrix Concepts and Jargon
 12  
 13  HUB75 RGB LED matrices are basically a set of six concurrent shift register
 14  chains, each with one output bit per column, the six chains being red, green
 15  and blue bits for two non-adjacent rows, plus a set of row drivers (each
 16  driving the aforementioned two rows) selected by a combination of address
 17  lines. The number of address lines determines the overall matrix height
 18  (3 to 5 bits is common...as an example, 3 address lines = 2^3 = 8 distinct
 19  address line combinations, each driving two rows = 16 pixels high). Address
 20  0 enables rows 0 and height/2, address 1 enables rows 1 and height/2+1, etc.
 21  Shift register chain length determines matrix width...32 and 64 pixels are
 22  common...matrices can be chained to increase width, a 64-pixel wide matrix
 23  is equivalent to two 32-pixel chained matrices, and so forth.
 24  
 25  These matrices render only ONE BIT each for red, green and blue, they DO NOT
 26  natively display full color and must be quickly refreshed by the driving
 27  microcontroller, basically PWM-ing the intermediate shades (this in addition
 28  to the row scanning that must be performed).
 29  
 30  There are a few peculiar RGB LED matrices that have the same physical
 31  connection but work a bit differently -- they might have only have three
 32  shift register chains rather than six, or might use a shift register for
 33  the row selection rather than a set of address lines. The code presented
 34  here DOES NOT support these matrix variants. Aim is to provide support for
 35  all HUB75 matrices in the Adafruit shop. Please don't submit pull requests
 36  for these other matrices as we have no means to test them. If you require
 37  this functionality, it's OK to create a fork of the code, which Git can
 38  help keep up-to-date with any future changes here!
 39  
 40  # Hardware Requirements and Jargon
 41  
 42  The common ground for architectures to support this library:
 43  
 44  * 32-bit device (e.g. ARM core, but potentially ESP32 and others in future)
 45  * One or more 32-bit GPIO PORTs with atomic (single-cycle, not
 46    read-modify-write) bitmask SET and CLEAR registers. A bitmask TOGGLE
 47    register, if present, may improve performance but is NOT required.
 48  * Tolerate 8-bit or word-aligned 16-bit accesses within the 32-bit PORT
 49    registers (e.g. writing just one of four bytes, rather than the whole
 50    32 bits). The library does not use any unaligned accesses (i.e. the
 51    "middle word" of a 32-bit register), even if a device tolerates such.
 52  
 53  # Software Components
 54  
 55  This repository currently consists of:
 56  
 57  * An Arduino C++ library (files Adafruit_Protomatter.cpp and
 58    Adafruit_Protomatter.h, plus the "examples" directory). The Arduino code
 59    is dependent on the Adafruit_GFX library.
 60  
 61  * An underlying C library (files core.c, core.h and arch.h) that might be
 62    adaptable to other runtime environments (e.g. CircuitPython).
 63  
 64  # Arduino Library
 65  
 66  This *might* supersede the RGBmatrixPanel library on non-AVR devices, as the
 67  older library has painted itself into a few corners. The newer library uses
 68  a single constructor for all matrix setups, potentially handling parallel
 69  chains (not yet fully implemented), various matrix sizes and chain lengths,
 70  and variable bit depths from 1 to 6 (refresh rate is a function of all of
 71  these). Note however that it is NOT A DROP-IN REPLACEMENT for RGBmatrixPanel.
 72  The constructor is entirely different, and there are several changes in the
 73  available functions. Also, all colors in the new library are specified as
 74  5/6/5-bit RGB (as this is what the GFX library GFXcanvas16 type uses, being
 75  aimed at low-cost color LCD displays), even if the matrix is configured for
 76  a lower bit depth (colors will be decimated/quantized in this case).
 77  
 78  It does have some new limitations, mostly significant RAM overhead (hence
 79  no plans for AVR port) and that all RGB data pins and the clock pin MUST be
 80  on the same PORT register (e.g. all PORTA or PORTB, can't intermix). RAM
 81  overhead is somewhat reduced (but still large) if those pins are all in a
 82  single 8-bit byte within the PORT (they do not need to be contiguous or
 83  sequential within this byte, if for instance it makes PCB routing easier,
 84  but they should all aim for a single byte). Other pins (matrix address lines,
 85  latch and output enable) can reside on any PORT or bit.
 86  
 87  # C Library
 88  
 89  The underlying C library is focused on *driving* the matrix and does not
 90  provide any drawing operations of its own. That must be handled by
 91  higher-level code, as in the Arduino wrapper which uses the Adafruit_GFX
 92  drawing functions.
 93  
 94  The C code has the same limitations as the Arduino library: all RGB data
 95  pins and the clock pin MUST be on the same PORT register, and it's most
 96  memory efficient (though still a bit gluttonous) if those pins are all
 97  within the same 8-bit byte within the PORT (they do not need to be
 98  contiguous or sequential within that byte). Other pins (matrix address lines,
 99  latch and output enable) can reside on any PORT or bit.
100  
101  When adapting this code to new devices (e.g. nRF52, ESP32) or new runtime
102  environments (e.g. CircuitPython), goal is to put all the device- or
103  platform-specific code into the arch.h file (or completely separate source
104  files, as in the Arduino library .cpp and .h). core.c contains only the
105  device-neutral bitbang code and should not have any "#ifdef DEVICE"- or
106  "#ifdef ENVIRONMENT"-like lines. Macros for things like getting a PORT
107  register address from a pin, or setting up a timer peripheral, all occur
108  in arch.h, which is ONLY #included by core.c (to prevent problems like
109  multiple instances of ISR functions, which must be singularly declared at
110  compile-time).
111  
112  Most macros and functions begin with the prefix **\_PM\_** in order to
113  avoid naming collisions with other code (exception being static functions,
114  which can't be seen outside their source file).