led-matrix.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. // -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
  2. // Copyright (C) 2013 Henner Zeller <h.zeller@acm.org>
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation version 2.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program. If not, see <http://gnu.org/licenses/gpl-2.0.txt>
  15. // Controlling 16x32 or 32x32 RGB matrixes via GPIO. It allows daisy chaining
  16. // of a string of these, and also connecting a parallel string on newer
  17. // Raspberry Pis with more GPIO pins available.
  18. #ifndef RPI_RGBMATRIX_H
  19. #define RPI_RGBMATRIX_H
  20. #include <stdint.h>
  21. #include <stddef.h>
  22. #include <string>
  23. #include <vector>
  24. #include "canvas.h"
  25. #include "thread.h"
  26. #include "pixel-mapper.h"
  27. namespace rgb_matrix {
  28. class RGBMatrix;
  29. class FrameCanvas; // Canvas for Double- and Multibuffering
  30. struct RuntimeOptions;
  31. // The RGB matrix provides the framebuffer and the facilities to constantly
  32. // update the LED matrix.
  33. //
  34. // This implement the Canvas interface that represents the display with
  35. // (led_cols * chained_displays)x(rows * parallel_displays) pixels.
  36. //
  37. // If can do multi-buffering using the CreateFrameCanvas() and SwapOnVSync()
  38. // methods. This is useful for animations and to prevent tearing.
  39. //
  40. // If you arrange the panels in a different way in the physical space, write
  41. // a CanvasTransformer that does coordinate remapping and which should be added
  42. // to the transformers, like with UArrangementTransformer in demo-main.cc.
  43. class RGBMatrix : public Canvas {
  44. public:
  45. // Options to initialize the RGBMatrix. Also see the main README.md for
  46. // detailed descriptions of the command line flags.
  47. struct Options {
  48. Options(); // Creates a default option set.
  49. // Validate the options and possibly output a message to string. If
  50. // "err" is NULL, outputs validation problems to stderr.
  51. // Returns 'true' if all options look good.
  52. bool Validate(std::string *err) const;
  53. // Name of the hardware mapping. Something like "regular" or "adafruit-hat"
  54. const char *hardware_mapping;
  55. // The "rows" are the number
  56. // of rows supported by the display, so 32 or 16. Default: 32.
  57. // Flag: --led-rows
  58. int rows;
  59. // The "cols" are the number of columns per panel. Typically something
  60. // like 32, but also 64 is possible. Sometimes even 40.
  61. // cols * chain_length is the total length of the display, so you can
  62. // represent a 64 wide display as cols=32, chain=2 or cols=64, chain=1;
  63. // same thing, but more convenient to think of.
  64. // Flag: --led-cols
  65. int cols;
  66. // The chain_length is the number of displays daisy-chained together
  67. // (output of one connected to input of next). Default: 1
  68. // Flag: --led-chain
  69. int chain_length;
  70. // The number of parallel chains connected to the Pi; in old Pis with 26
  71. // GPIO pins, that is 1, in newer Pis with 40 interfaces pins, that can
  72. // also be 2 or 3. The effective number of pixels in vertical direction is
  73. // then thus rows * parallel. Default: 1
  74. // Flag: --led-parallel
  75. int parallel;
  76. // Set PWM bits used for output. Default is 11, but if you only deal with
  77. // limited comic-colors, 1 might be sufficient. Lower require less CPU and
  78. // increases refresh-rate.
  79. // Flag: --led-pwm-bits
  80. int pwm_bits;
  81. // Change the base time-unit for the on-time in the lowest
  82. // significant bit in nanoseconds.
  83. // Higher numbers provide better quality (more accurate color, less
  84. // ghosting), but have a negative impact on the frame rate.
  85. // Flag: --led-pwm-lsb-nanoseconds
  86. int pwm_lsb_nanoseconds;
  87. // The lower bits can be time-dithered for higher refresh rate.
  88. // Flag: --led-pwm-dither-bits
  89. int pwm_dither_bits;
  90. // The initial brightness of the panel in percent. Valid range is 1..100
  91. // Default: 100
  92. // Flag: --led-brightness
  93. int brightness;
  94. // Scan mode: 0=progressive, 1=interlaced.
  95. // Flag: --led-scan-mode
  96. int scan_mode;
  97. // Default row address type is 0, corresponding to direct setting of the
  98. // row, while row address type 1 is used for panels that only have A/B,
  99. // typically some 64x64 panels
  100. int row_address_type; // Flag --led-row-addr-type
  101. // Type of multiplexing. 0 = direct, 1 = stripe, 2 = checker,...
  102. // Flag: --led-multiplexing
  103. int multiplexing;
  104. // Disable the PWM hardware subsystem to create pulses.
  105. // Typically, you don't want to disable hardware pulsing, this is mostly
  106. // for debugging and figuring out if there is interference with the
  107. // sound system.
  108. // This won't do anything if output enable is not connected to GPIO 18 in
  109. // non-standard wirings.
  110. bool disable_hardware_pulsing; // Flag: --led-hardware-pulse
  111. // Show refresh rate on the terminal for debugging and tweaking purposes.
  112. bool show_refresh_rate; // Flag: --led-show-refresh
  113. // Some panels have inversed colors.
  114. bool inverse_colors; // Flag: --led-inverse
  115. // In case the internal sequence of mapping is not "RGB", this contains the
  116. // real mapping. Some panels mix up these colors. String of length three
  117. // which has to contain all characters R, G and B.
  118. const char *led_rgb_sequence; // Flag: --led-rgb-sequence
  119. // A string describing a sequence of pixel mappers that should be applied
  120. // to this matrix. A semicolon-separated list of pixel-mappers with optional
  121. // parameter.
  122. const char *pixel_mapper_config; // Flag: --led-pixel-mapper
  123. // Panel type. Typically an empty string or NULL, but some panels need
  124. // a particular initialization sequence, so this is used for that.
  125. // This can be e.g. "FM6126A" for that particular panel type.
  126. const char *panel_type; // Flag: --led-panel-type
  127. // Limit refresh rate of LED panel. This will help on a loaded system
  128. // to keep a constant refresh rate. <= 0 for no limit.
  129. int limit_refresh_rate_hz; // Flag: --led-limit-refresh
  130. };
  131. // Factory to create a matrix. Additional functionality includes dropping
  132. // privileges and becoming a daemon.
  133. // Returns NULL, if there was a problem (a message then is written to stderr).
  134. static RGBMatrix *CreateFromOptions(const Options &options,
  135. const RuntimeOptions &runtime_options);
  136. // A factory that parses your main() commandline flags to read options
  137. // meant to configure the the matrix and returns a freshly allocated matrix.
  138. //
  139. // Optionally, you can pass in option structs with a couple of defaults
  140. // which are used unless overwritten on the command line.
  141. // A matrix is created and returned; also the options structs are
  142. // updated to reflect the values that were used and set on the command line.
  143. //
  144. // If you allow the user to start a daemon with --led-daemon, make sure to
  145. // call this function before you have started any threads, so early on in
  146. // main() (see RuntimeOptions documentation).
  147. //
  148. // Note, the permissions are dropped by default from 'root' to 'daemon', so
  149. // if you are required to stay root after this, disable this option in
  150. // the default RuntimeOptions (set drop_privileges = -1).
  151. // Returns NULL, if there was a problem (a message then is written to stderr).
  152. static RGBMatrix *CreateFromFlags(int *argc, char ***argv,
  153. RGBMatrix::Options *default_options = NULL,
  154. RuntimeOptions *default_runtime_opts = NULL,
  155. bool remove_consumed_flags = true);
  156. // Stop matrix, delete all resources.
  157. virtual ~RGBMatrix();
  158. // -- Canvas interface. These write to the active FrameCanvas
  159. // (see documentation in canvas.h)
  160. //
  161. // Since this is updating the canvas that is currently displayed, this
  162. // might result in tearing.
  163. // Prefer using a FrameCanvas and do double-buffering, see section below.
  164. virtual int width() const;
  165. virtual int height() const;
  166. virtual void SetPixel(int x, int y,
  167. uint8_t red, uint8_t green, uint8_t blue);
  168. virtual void Clear();
  169. virtual void Fill(uint8_t red, uint8_t green, uint8_t blue);
  170. // -- Double- and Multibuffering.
  171. // Create a new buffer to be used for multi-buffering. The returned new
  172. // Buffer implements a Canvas with the same size of thie RGBMatrix.
  173. // You can use it to draw off-screen on it, then swap it with the active
  174. // buffer using SwapOnVSync(). That would be classic double-buffering.
  175. //
  176. // You can also create as many FrameCanvas as you like and for instance use
  177. // them to pre-fill scenes of an animation for fast playback later.
  178. //
  179. // The ownership of the created Canvases remains with the RGBMatrix, so you
  180. // don't have to worry about deleting them (but you also don't want to create
  181. // more than needed as this will fill up your memory as they are only deleted
  182. // when the RGBMatrix is deleted).
  183. FrameCanvas *CreateFrameCanvas();
  184. // This method waits to the next VSync and swaps the active buffer with the
  185. // supplied buffer. The formerly active buffer is returned.
  186. //
  187. // If you pass in NULL, the active buffer is returned, but it won't be
  188. // replaced with NULL. You can use the NULL-behavior to just wait on
  189. // VSync or to retrieve the initial buffer when preparing a multi-buffer
  190. // animation.
  191. //
  192. // The optional "framerate_fraction" parameter allows to choose which
  193. // multiple of the global frame-count to use. So it slows down your animation
  194. // to an exact integer fraction of the refresh rate.
  195. // Default is 1, so immediately next available frame.
  196. // (Say you have 140Hz refresh rate, then a value of 5 would give you an
  197. // 28Hz animation, nicely locked to the refresh-rate).
  198. // If you combine this with Options::limit_refresh_rate_hz you can create
  199. // time-correct animations.
  200. FrameCanvas *SwapOnVSync(FrameCanvas *other, unsigned framerate_fraction = 1);
  201. // -- Setting shape and behavior of matrix.
  202. // Apply a pixel mapper. This is used to re-map pixels according to some
  203. // scheme implemented by the PixelMapper. Does _not_ take ownership of the
  204. // mapper. Mapper can be NULL, in which case nothing happens.
  205. // Returns a boolean indicating if this was successful.
  206. bool ApplyPixelMapper(const PixelMapper *mapper);
  207. // Note, there used to be ApplyStaticTransformer(), which has been deprecated
  208. // since 2018 and changed to a compile-time option, then finally removed
  209. // in 2020. Use PixelMapper instead, which is simpler and more intuitive.
  210. // Set PWM bits used for output. Default is 11, but if you only deal with
  211. // limited comic-colors, 1 might be sufficient. Lower require less CPU and
  212. // increases refresh-rate.
  213. //
  214. // Returns boolean to signify if value was within range.
  215. //
  216. // This sets the PWM bits for the current active FrameCanvas and future
  217. // ones that are created with CreateFrameCanvas().
  218. bool SetPWMBits(uint8_t value);
  219. uint8_t pwmbits(); // return the pwm-bits of the currently active buffer.
  220. // Map brightness of output linearly to input with CIE1931 profile.
  221. void set_luminance_correct(bool on);
  222. bool luminance_correct() const;
  223. // Set brightness in percent for all created FrameCanvas. 1%..100%.
  224. // This will only affect newly set pixels.
  225. void SetBrightness(uint8_t brightness);
  226. uint8_t brightness();
  227. //-- GPIO interaction.
  228. // This library uses the GPIO pins to drive the matrix; this is a safe way
  229. // to request the 'remaining' bits to be used for user purposes.
  230. // Request user readable GPIO bits.
  231. // This function allows you to request pins you'd like to read with
  232. // AwaitInputChange().
  233. // Only bits that are not already in use for reading or wrtiting
  234. // by the matrix are allowed.
  235. // Input is a bitmap of all the GPIO bits you're interested in; returns all
  236. // the bits that are actually available.
  237. uint64_t RequestInputs(uint64_t all_interested_bits);
  238. // This function will return whenever the GPIO input pins
  239. // change (pins that are not already in use for output, that is) or the
  240. // timeout is reached. You need to have reserved the inputs with
  241. // matrix->RequestInputs(...) first (e.g.
  242. // matrix->RequestInputs((1<<25)|(1<<24));
  243. //
  244. // A positive timeout waits the given amount of milliseconds for a change
  245. // (e.g. a button-press) to occur; if there is no change, it will just
  246. // return the last value.
  247. // If you just want to know how the pins are right now, call with zero
  248. // timeout.
  249. // A negative number waits forever and will only return if there is a change.
  250. //
  251. // This function only samples between display refreshes so polling some
  252. // input does not generate flicker and provide a convenient change interface.
  253. //
  254. // Returns the bitmap of all GPIO input pins.
  255. uint64_t AwaitInputChange(int timeout_ms);
  256. // Request user writable GPIO bits.
  257. // This allows to request a bitmap of GPIO-bits to be used by the user for
  258. // writing.
  259. // Only bits that are not already in use for reading or wrtiting
  260. // by the matrix are allowed.
  261. // Returns the subset bits that are _actually_ available,
  262. uint64_t RequestOutputs(uint64_t output_bits);
  263. // Set the user-settable bits according to output bits.
  264. void OutputGPIO(uint64_t output_bits);
  265. // Legacy way to set gpio pins. We're not doing this anymore but need to
  266. // be source-compatible with old calls of the form
  267. // matrix->gpio()->RequestInputs(...)
  268. //
  269. // Don't use, use AwaitInputChange() directly.
  270. RGBMatrix *gpio() __attribute__((deprecated)) { return this; }
  271. //-- Rarely needed
  272. // Start the refresh thread.
  273. // This is only needed if you chose RuntimeOptions::daemon = -1 (see below),
  274. // otherwise the refresh thread is already started.
  275. bool StartRefresh();
  276. private:
  277. class Impl;
  278. RGBMatrix(Impl *impl) : impl_(impl) {}
  279. Impl *const impl_;
  280. };
  281. namespace internal {
  282. class Framebuffer;
  283. }
  284. class FrameCanvas : public Canvas {
  285. public:
  286. // Set PWM bits used for this Frame.
  287. // Simple comic-colors, 1 might be sufficient (111 RGB, i.e. 8 colors).
  288. // Lower require less CPU.
  289. // Returns boolean to signify if value was within range.
  290. bool SetPWMBits(uint8_t value);
  291. uint8_t pwmbits();
  292. // Map brightness of output linearly to input with CIE1931 profile.
  293. void set_luminance_correct(bool on);
  294. bool luminance_correct() const;
  295. void SetBrightness(uint8_t brightness);
  296. uint8_t brightness();
  297. //-- Serialize()/Deserialize() are fast ways to store and re-create a canvas.
  298. // Provides a pointer to a buffer of the internal representation to
  299. // be copied out for later Deserialize().
  300. //
  301. // Returns a "data" pointer and the data "len" in the given out-paramters;
  302. // the content can be copied from there by the caller.
  303. //
  304. // Note, the content is not simply RGB, it is the opaque and platform
  305. // specific representation which allows to make deserialization very fast.
  306. // It is also bigger than just RGB; if you want to store it somewhere,
  307. // using compression is a good idea.
  308. void Serialize(const char **data, size_t *len) const;
  309. // Load data previously stored with Serialize(). Needs to be restored into
  310. // a FrameCanvas with exactly the same settings (rows, chain, transformer,...)
  311. // as serialized.
  312. // Returns 'false' if size is unexpected.
  313. // This method should only be called if FrameCanvas is off-screen.
  314. bool Deserialize(const char *data, size_t len);
  315. // Copy content from other FrameCanvas owned by the same RGBMatrix.
  316. void CopyFrom(const FrameCanvas &other);
  317. // -- Canvas interface.
  318. virtual int width() const;
  319. virtual int height() const;
  320. virtual void SetPixel(int x, int y,
  321. uint8_t red, uint8_t green, uint8_t blue);
  322. virtual void Clear();
  323. virtual void Fill(uint8_t red, uint8_t green, uint8_t blue);
  324. private:
  325. friend class RGBMatrix;
  326. FrameCanvas(internal::Framebuffer *frame) : frame_(frame){}
  327. virtual ~FrameCanvas(); // Any FrameCanvas is owned by RGBMatrix.
  328. internal::Framebuffer *framebuffer() { return frame_; }
  329. internal::Framebuffer *const frame_;
  330. };
  331. // Runtime options to simplify doing common things for many programs such as
  332. // dropping privileges and becoming a daemon.
  333. struct RuntimeOptions {
  334. RuntimeOptions();
  335. int gpio_slowdown; // 0 = no slowdown. Flag: --led-slowdown-gpio
  336. // ----------
  337. // If the following options are set to disabled with -1, they are not
  338. // even offered via the command line flags.
  339. // ----------
  340. // Thre are three possible values here
  341. // -1 : don't leave choise of becoming daemon to the command line parsing.
  342. // If set to -1, the --led-daemon option is not offered.
  343. // 0 : do not becoma a daemon, run in forgreound (default value)
  344. // 1 : become a daemon, run in background.
  345. //
  346. // If daemon is disabled (= -1), the user has to call
  347. // RGBMatrix::StartRefresh() manually once the matrix is created, to leave
  348. // the decision to become a daemon
  349. // after the call (which requires that no threads have been started yet).
  350. // In the other cases (off or on), the choice is already made, so the thread
  351. // is conveniently already started for you.
  352. int daemon; // -1 disabled. 0=off, 1=on. Flag: --led-daemon
  353. // Drop privileges from 'root' to 'daemon' once the hardware is initialized.
  354. // This is usually a good idea unless you need to stay on elevated privs.
  355. int drop_privileges; // -1 disabled. 0=off, 1=on. flag: --led-drop-privs
  356. // By default, the gpio is initialized for you, but if you run on a platform
  357. // not the Raspberry Pi, this will fail. If you don't need to access GPIO
  358. // e.g. you want to just create a stream output (see content-streamer.h),
  359. // set this to false.
  360. bool do_gpio_init;
  361. };
  362. // Convenience utility functions to read standard rgb-matrix flags and create
  363. // a RGBMatrix. Commandline flags are something like --led-rows, --led-chain,
  364. // --led-parallel. See output of PrintMatrixFlags() for all available options
  365. // and detailed description in
  366. // https://github.com/hzeller/rpi-rgb-led-matrix#changing-parameters-via-command-line-flags
  367. //
  368. // Example use:
  369. /*
  370. using rgb_matrix::RGBMatrix;
  371. int main(int argc, char **argv) {
  372. RGBMatrix::Options led_options;
  373. rgb_matrix::RuntimeOptions runtime;
  374. // Set defaults
  375. led_options.chain_length = 3;
  376. led_options.show_refresh_rate = true;
  377. runtime.drop_privileges = 1;
  378. if (!rgb_matrix::ParseOptionsFromFlags(&argc, &argv, &led_options, &runtime)) {
  379. rgb_matrix::PrintMatrixFlags(stderr);
  380. return 1;
  381. }
  382. // Do your own command line handling with the remaining flags.
  383. while (getopt()) {...}
  384. // Looks like we're ready to start
  385. RGBMatrix *matrix = RGBMatrix::CreateFromOptions(led_options, runtime);
  386. if (matrix == NULL) {
  387. return 1;
  388. }
  389. // .. now use matrix
  390. delete matrix; // Make sure to delete it in the end to switch off LEDs.
  391. return 0;
  392. }
  393. */
  394. // This parses the flags from argv and updates the structs with the parsed-out
  395. // values. Structs can be NULL if you are not interested in it.
  396. //
  397. // The recongized flags are removed from argv if "remove_consumed_flags" is
  398. // true; this simplifies your command line processing for the remaining options.
  399. //
  400. // Returns 'true' on success, 'false' if there was flag parsing problem.
  401. bool ParseOptionsFromFlags(int *argc, char ***argv,
  402. RGBMatrix::Options *default_options,
  403. RuntimeOptions *rt_options,
  404. bool remove_consumed_flags = true);
  405. // Show all the available options in a style that can be used in a --help
  406. // output on the command line.
  407. void PrintMatrixFlags(FILE *out,
  408. const RGBMatrix::Options &defaults = RGBMatrix::Options(),
  409. const RuntimeOptions &rt_opt = RuntimeOptions());
  410. // Legacy version of RGBMatrix::CreateFromOptions()
  411. inline RGBMatrix *CreateMatrixFromOptions(
  412. const RGBMatrix::Options &options,
  413. const RuntimeOptions &runtime_options) {
  414. return RGBMatrix::CreateFromOptions(options, runtime_options);
  415. }
  416. // Legacy version of RGBMatrix::CreateFromFlags()
  417. inline RGBMatrix *CreateMatrixFromFlags(
  418. int *argc, char ***argv,
  419. RGBMatrix::Options *default_options = NULL,
  420. RuntimeOptions *default_runtime_opts = NULL,
  421. bool remove_consumed_flags = true) {
  422. return RGBMatrix::CreateFromFlags(argc, argv,
  423. default_options, default_runtime_opts,
  424. remove_consumed_flags);
  425. }
  426. } // end namespace rgb_matrix
  427. #endif // RPI_RGBMATRIX_H