Advertisement
Guest User

Untitled

a guest
Jan 25th, 2019
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 39.70 KB | None | 0 0
  1. /**
  2. \mainpage Arduino LED Matrix Library
  3. The Maxim 72xx LED Controller IC
  4. --------------------------------
  5. The MAX7219/MAX7221 are compact, serial input/output display drivers that
  6. interface microprocessors to 7-segment numeric LED displays of up to 8 digits,
  7. bar-graph displays, or 64 individual LEDs. Included on-chip are a BCD code-B
  8. decoder, multiplex scan circuitry, segment and digit drivers, and an 8x8 static
  9. RAM that stores each digit.
  10.  
  11. A 4-wire serial interface (SPI) allows the devices to be cascaded, with
  12. communications passed through the first device in the chain to all others. Individual
  13. elements may be addressed and updated without rewriting the entire display.
  14.  
  15. This library implements functions that allow the MAX72xx to be used
  16. for LED matrices (64 individual LEDs), allowing the programmer to use the LED
  17. matrix as a pixel device, displaying graphics elements much like any other
  18. pixel addressable display.
  19.  
  20. Topics
  21. ------
  22. - \subpage pageHardware
  23. - \subpage pageSoftware
  24. - \subpage pageConnect
  25.  
  26. Revision History
  27. ----------------
  28. April 2015 version 2.7
  29. - Changed to Daft Punk example to run without switch
  30. - Now supporting IDE Library Manager
  31.  
  32. February 2015 version 2.6
  33. - Improvements to HW_Mapper utility
  34. - Added HW_USE_FC16 for FC-16 display modules
  35. - Added USE_HW_OTHER for user defined hardware configuration
  36. - Fixed incorrect spelling for HW_REV_COLS in transformbuffer() & corresponding bug
  37. - Added PrintText_ML example
  38.  
  39. February 2015 version 2.5
  40. - Documented process for adding new hardware module type
  41. - Fixed PROGMEM definitions for IDE version 1.5.7 compile error
  42. - Added Daft Punk example code
  43. - Updated HW_Mapper example/utility with built-in instructions
  44. - Minor problems with Parola font setting interaction fixed
  45.  
  46. April 2014 version 2.4
  47. - Improved reliability of initialization code to remove artifacts
  48.  + Changed order of hardware initialization for SS, _csPin
  49.  + Changed initialisation sequence at begin()
  50.  + Fixed memset bug identified by bperrybap
  51. - Reworked command SPI transmissions for efficiency
  52. - Cleanup up compiler warnings on inline wrapper code functions
  53. - Cleaned up examples begin() - better defined library default values
  54. - Reviewed and tidied up some documentation
  55.  
  56. March 2014 - version 2.3
  57. - Extensive rework of the font system
  58.  + New font Microsoft Excel VBA based builder tool available
  59.  + Removed USE_FONT_ADJUST and related code - replace by builder tool
  60.  + Fixed width font has been removed from the library. Definition still available in font builder
  61.  + fontype_t definition changed to suit new requirements
  62. - Transform zoning implemented (contiguous subset of services)
  63.  + Transformation functions, control, clear, setRow methods overloaded with range specifier
  64.  + User callback for L/R rotation function syntax added a device parameter
  65.  + New Zones example
  66. - USE_*_HW hardware types now separated out for future flexibility
  67.  + Rework of the library to use new schema for defining hardware characteristics
  68.  + New utility code to map out digits and segments for unknown hardware types
  69. - Rechecked and reworked examples for new library
  70.  
  71. November 2013 - version 2.2
  72. - Replaced reference to SPI library with inline code to allow for different select lines
  73. - Obsoleted INCLUDE_HARDWARE_SPI conditional compile switch
  74. - Fixed legacy code function name error when USE_FONT_ADJUST switch turned on
  75. - Implemented USE_PAROLA_HW to allow cheaply available matrix modules to be used in ganged mode
  76. - Fixed reversal of bit field for set/get Row/Column functions -> flipped charset data
  77. - Added Eyes example program
  78. - Upgraded and reorganized documentation
  79.  
  80. June 2013 - version 2.1
  81. - Include the selection of hardware SPI interface (10x speed improvement)
  82. - Tidied up comments
  83.  
  84. April 2013 - version 2.0
  85. - Major update and rewrite of library code:
  86. - Improved speed and efficiency of code
  87. - Increased level of abstraction in the library for pixel methods
  88. - Increased level of abstraction for character and font methods
  89. - Increased number of functions and added variable sized font
  90. - Changed defines to enumerated types within the scope of the class
  91. - Updated functionality to simplify controlling multiple devices
  92. - Changed text and comments to be aligned to doxygen documentation generation
  93.  
  94. June 2012 - version 1.0
  95. - Incorporated elements of Arduino LedControl (Eberhard Fahle) and MAX7219 libraries
  96. - Easier functionality for pixel graphics treatment of 8x8 matrices
  97.  
  98. Copyright
  99. ---------
  100. Copyright (C) 2012-15 Marco Colli. All rights reserved.
  101.  
  102. This library is free software; you can redistribute it and/or
  103. modify it under the terms of the GNU Lesser General Public
  104. License as published by the Free Software Foundation; either
  105. version 2.1 of the License, or (at your option) any later version.
  106.  
  107. This library is distributed in the hope that it will be useful,
  108. but WITHOUT ANY WARRANTY; without even the implied warranty of
  109. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  110. Lesser General Public License for more details.
  111.  
  112. You should have received a copy of the GNU Lesser General Public
  113. License along with this library; if not, write to the Free Software
  114. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  115.  
  116. \page pageSoftware Software
  117. The Library
  118. -----------
  119. The library implements functions that allow the MAX72xx to be used
  120. for LED matrices (64 individual LEDs), allowing the programmer to use the LED
  121. matrix as a pixel device, displaying graphics elements much like any other
  122. pixel addressable display.
  123.  
  124. In this scenario, it is convenient to abstract out the concept of the hardware device
  125. and create a uniform and consistent pixel address space, with the libraries determining
  126. device and device-element address. Similarly, control of the devices should be uniform
  127. and abstracted to a system level.
  128.  
  129. The library still retains flexibility for device level control, should the developer
  130. require, through the use of overloaded class methods.
  131. ___
  132.  
  133. Conditional Compilation Switches
  134. --------------------------------
  135. The library allows the run time code to be tailored through the use of compilation
  136. switches. The compile options start with USE_ and are documented in the section
  137. related to the main header file MD_MAX72xx.h.
  138.  
  139. _NOTE_: Compile switches must be edited in the library header file. Arduino header file
  140. 'mashing' during compilation makes the setting of these switches from user code
  141. completely unreliable.
  142. ___
  143.  
  144. Font Storage Format
  145. -------------------
  146. One default font is defined as part of the library in PROGMEM memory. Alternative fonts
  147. can be specified to the library. The font builder tool provides a convenient way to develop
  148. alternative fonts.
  149.  
  150. The fonts are stored as a series of contiguous bytes in the following format:
  151. - byte 1 - the number of bytes that form this character (could be zero)
  152. - byte 2..n - each byte is a column of the character to be formed, starting with the
  153. leftmost column of the character. The least significant bit of the byte is the bottom
  154. pixel position of the character matrix (row 7).
  155.  
  156. To find a character in the font table, the library looks at the first byte (size),
  157. skips 'size'+1 bytes to the next character size byte and repeat until the last or
  158. target character is reached.
  159.  
  160. The compile-time switch USE_INDEX_FONT enables indexing of the font table for faster access, at
  161. the expense of increased RAM usage. If indexing is enabled, a single lookup is required to
  162. access the character data, rather than the sequential search described above.
  163.  
  164. The support for fonts (methods and data) may be completely disabled  if not required through
  165. the compile-time switch USE_LOCAL_FONT. This will also disable user defined fonts.
  166.  
  167.  
  168. \page pageConnect System Connections
  169. Connections to the Arduino Board (SPI interface)
  170. ------------------------------------------------
  171. The modules are connected through a 4-wire serial interface (SPI), and devices are cascaded,
  172. with communications passed through the first device in the chain to all others. The Arduino
  173. should be connected to the IN side of the first module in the chain.
  174.  
  175. The Arduino interface is implemented with either
  176. + The hardware SPI interface, or
  177. + 3 arbitrary digital outputs that are passed through to the class constructor.
  178.  
  179. The AVR hardware SPI interface is fast but fixed to predetermined output pins. The more general
  180. software interface uses the Arduino shiftOut() library function, making it slower but allows the
  181. use of arbitrary digital pins to send the data to the device. Which mode is enabled depends
  182. on the class constructor used.
  183.  
  184. The Arduino interface is implemented with 3 digital outputs that are passed through to
  185. the class constructor. The digital outputs define the SPI interface as follows:
  186. - DIN (MOSI) - the Data IN signal shifts data into the display module. Data is loaded into
  187. the device's internal 16-bit shift register on CLK's rising edge.
  188. - CLK (SCK) - the CLocK signal that is used to time the data for the device.
  189. - LD (SS) - the interface is active when LoaD signal is LOW. Serial data are loaded into the
  190. device shift register while LOAD is LOW and latched in on the rising edge.
  191.  
  192. The LD signal is used to select the entire device chain. This allows separate LD
  193. outputs to control multiple displays sharing the same DIN and CLK signals. The
  194. software needs to instantiate a separate object for each display.
  195.  
  196. The remaining interface pins are for +5V and GND. The power supply must be able to supply
  197. enough current for the number of connected modules.
  198. */
  199. #ifndef MD_MAX72xx_h
  200. #define MD_MAX72xx_h
  201.  
  202. #include <Arduino.h>
  203.  
  204. /**
  205.  * \file
  206.  * \brief Main header file for the MD_MAX72xx library
  207.  */
  208.  
  209. /**
  210.  \def USE_PAROLA_HW
  211.  Set to 1 (default) to use the Parola hardware modules. The
  212.  software was originally designed to operate with this hardware type.
  213.  */
  214. #define USE_PAROLA_HW   1
  215.  
  216. /**
  217.  \def USE_GENERIC_HW
  218.  Set to 1 to use 'generic' hardware modules commonly available, with
  219.  connectors at the top and bottom of the PCB, available from many sources.
  220.  */
  221. #define USE_GENERIC_HW  0
  222.  
  223. /**
  224.  \def USE_ICSTATION_HW
  225.  Set to 1 to use ICStation DIY hardware module kits available from
  226.  http://www.icstation.com/product_info.php?products_id=2609#.UxqVJyxWGHs
  227.  This hardware must be set up with the input on the RHS.
  228.  */
  229. #define USE_ICSTATION_HW    0
  230.  
  231. /**
  232.  \def USE_FC16_HW
  233.  Set to 1 to use FC16 hardware module kits.
  234.  FC16 modules are similar in format to the ICStation modules but are wired differently.
  235.  Modules are identified by a FC-16 designation on the PCB
  236.   */
  237. #define USE_FC16_HW 0
  238.  
  239. /**
  240.  \def USE_OTHER_HW
  241.  Set to 1 to use other hardware not defined above.
  242.  Module 0 (Data In) must be set up on the RHS and the CUSTOM hardware defines
  243.  must be set up in the MD_MAD72xx_lib.h file under for this section, using the HW_Mapper
  244.  utility to work out what the correct values to use are.
  245.  */
  246. #define USE_OTHER_HW    0
  247.  
  248. /**
  249.  \def USE_LOCAL_FONT
  250.  Set to 1 (default) to enable local font in this library and enable
  251.  loadChar() and related methods. If the library is just used for
  252.  graphics some FLASH RAM can be saved by not including the code to process
  253.  font data. The font file is stored in PROGMEM.
  254.  */
  255. #define USE_LOCAL_FONT  1
  256.  
  257. /**
  258.  \def USE_INDEX_FONT
  259.  Set to 1 to enable font indexing to speed up font lookups - usually disabled.
  260.  This will trade off increased stack RAM usage for lookup speed if enabled.
  261.  When disabled lookups will then become linear searches through PROGMEM.
  262.  Uses FONT_INDEX_SIZE elements of uint16_t (512 bytes) if enabled. For most
  263.  purposes the increase in speed is not needed.
  264.  
  265.  USE_LOCAL FONT must be enabled for this option to take effect.
  266.  */
  267. #define USE_INDEX_FONT  0
  268.  
  269. // Display parameter constants
  270. // Defined values that are used throughout the library to define physical limits
  271. #define ROW_SIZE    8       ///< The size in pixels of a row in the device LED matrix array
  272. #define COL_SIZE    8       ///< The size in pixels of a column in the device LED matrix array
  273. #define MAX_INTENSITY   0x1 ///< The maximum intensity value that can be set for a LED array
  274. #define MAX_SCANLIMIT   7   ///< The maximum scan limit value that can be set for the devices
  275.  
  276. /**
  277.  * Core object for the MD_MAX72XX library
  278.  */
  279. class MD_MAX72XX
  280. {
  281. public:
  282. #if USE_LOCAL_FONT
  283.     /**
  284.      * Font definition type.
  285.      *
  286.      * This type is used in the setFont() method to set the font to be used
  287.      */
  288.     typedef const PROGMEM uint8_t   fontType_t;
  289. #endif
  290.  
  291.     /**
  292.      * Control Request enumerated type.
  293.      *
  294.      * This enumerated type is used with the control() method to identify
  295.      * the control action request.
  296.      */
  297.     enum controlRequest_t
  298.     {
  299.         SHUTDOWN = 0,   ///< Shut down the MAX72XX. Requires ON/OFF value. Library default is OFF.
  300.         SCANLIMIT = 1///< Set the scan limit for the MAX72XX. Requires numeric value [0..MAX_SCANLIMIT]. Library default is all on.
  301.         INTENSITY = 2///< Set the LED intensity for the MAX72XX. Requires numeric value [0..MAX_INTENSITY]. LIbrary default is MAX_INTENSITY/2.
  302.         TEST = 3,       ///< Set the MAX72XX in test mode. Requires ON/OFF value. Library default is OFF.
  303.         DECODE = 4,     ///< Set the MAX72XX 7 segment decode mode. Requires ON/OFF value. Library default is OFF.
  304.         UPDATE = 10,    ///< Enable or disable auto updates of the devices from the library. Requires ON/OFF value. Library default is ON.
  305.         WRAPAROUND = 11 ///< Enable or disable wraparound when shifting (circular buffer). Requires ON/OFF value. Library default is OFF.
  306.     };
  307.  
  308.     /**
  309.      * Control Value enumerated type.
  310.      *
  311.      * This enumerated type is used with the control() method as the
  312.      * ON/OFF value for a control request. Other values may be used
  313.      * if numeric data is required.
  314.      */
  315.     enum controlValue_t
  316.     {
  317.         OFF = 0,    ///< General OFF status request
  318.         ON = 1      ///< General ON status request
  319.     };
  320.  
  321.     /**
  322.      * Transformation Types enumerated type.
  323.      *
  324.      * This enumerated type is used in the transform() methods to identify a
  325.      * specific transformation of the display data in the device buffers.
  326.      */
  327.     enum transformType_t
  328.     {
  329.         TSL,    ///< Transform Shift Left one pixel element
  330.         TSR,    ///< Transform Shift Right one pixel element
  331.         TSU,    ///< Transform Shift Up one pixel element
  332.         TSD,    ///< Transform Shift Down one pixel element
  333.         TFLR,   ///< Transform Flip Left to Right
  334.         TFUD,   ///< Transform Flip Up to Down
  335.         TRC,    ///< Transform Rotate Clockwise 90 degrees
  336.         TINV    ///< Transform INVert (pixels inverted)
  337.     };
  338.  
  339.   /**
  340.    * Class Constructor - arbitrary digital interface.
  341.    *
  342.    * Instantiate a new instance of the class. The parameters passed are used to
  343.    * connect the software to the hardware. Multiple instances may co-exist
  344.    * but they should not share the same hardware CS pin (SPI interface).
  345.    *
  346.    * \param dataPin     output on the Arduino where data gets shifted out.
  347.    * \param clkPin      output for the clock signal.
  348.    * \param csPin       output for selecting the device.
  349.    * \param numDevices  number of devices connected. Default is 1 if not supplied.
  350.    *                    Memory for device buffers is dynamically allocated based
  351.    *                    on this parameter.
  352.    */
  353.   MD_MAX72XX(uint8_t dataPin, uint8_t clkPin, uint8_t csPin, uint8_t numDevices=1);
  354.  
  355.   /**
  356.    * Class Constructor - SPI hardware interface.
  357.    *
  358.    * Instantiate a new instance of the class. The parameters passed are used to
  359.    * connect the software to the hardware. Multiple instances may co-exist
  360.    * but they should not share the same hardware CS pin (SPI interface).
  361.    * The dataPin and the clockPin are defined by the Arduino hardware definition
  362.    * (SPI MOSI and SCK signals).
  363.    *
  364.    * \param csPin       output for selecting the device.
  365.    * \param numDevices  number of devices connected. Default is 1 if not supplied.
  366.    *                    Memory for device buffers is dynamically allocated based
  367.    *                    on this parameter.
  368.    */
  369.   MD_MAX72XX(uint8_t csPin, uint8_t numDevices=1);
  370.  
  371.   /**
  372.    * Initialize the object.
  373.    *
  374.    * Initialise the object data. This needs to be called during setup() to initialise new
  375.    * data for the class that cannot be done during the object creation.
  376.    *
  377.    * The LED hardware is initialized to the middle intensity value, all rows showing,
  378.    * and all LEDs cleared (off). Test, shutdown and decode modes are off. Display updates
  379.    * are on and wraparound is off.
  380.    */
  381.   void begin(void);
  382.  
  383.   /**
  384.    * Class Destructor.
  385.    *
  386.    * Released allocated memory and does the necessary to clean up once the object is
  387.    * no longer required.
  388.    */
  389.   ~MD_MAX72XX();
  390.  
  391.   //--------------------------------------------------------------
  392.   /** \name Methods for object and hardware control.
  393.    * @{
  394.    */
  395.   /**
  396.    * Set the control status of the specified parameter for the specified device.
  397.    *
  398.    * The device has a number of control parameters that can be set through this method.
  399.    * The type of control action required is passed through the mode parameter and
  400.    * should be one of the control actions defined by controlRequest_t. The value that
  401.    * needs to be supplied on the control action required is one of the defined
  402.    * actions in controlValue_t or a numeric parameter suitable for the control action.
  403.    *
  404.    * \param dev         address of the device to control [0..getDeviceCount()-1].
  405.    * \param mode        one of the defined control requests.
  406.    * \param value       parameter value or one of the control status defined.
  407.    * \return false if parameter errors, true otherwise.
  408.    */
  409.   bool control(uint8_t dev, controlRequest_t mode, int value);
  410.  
  411.   /**
  412.    * Set the control status of the specified parameter for all devices.
  413.    *
  414.    * Invokes the control function for each device in turn. as this is a wrapper for the
  415.    * control(startDev, endDev, ...) methods, see the documentation for that method.
  416.    *
  417.    * \param mode        one of the defined control requests.
  418.    * \param value       parameter value or one of the control status defined.
  419.    * \return No return value.
  420.    */
  421.   inline void control(controlRequest_t mode, int value) { control(0, getDeviceCount()-1, mode, value); };
  422.  
  423.   /**
  424.    * Set the control status of the specified parameter for contiguous subset of devices.
  425.    *
  426.    * Invokes the control function for each device in turn for the devices in the subset.
  427.    * See documentation for the control() method.
  428.    *
  429.    * \param startDev    the first device for the transformation [0..getDeviceCount()-1]
  430.    * \param endDev      the last device for the transformation [0..getDeviceCount()-1]
  431.    * \param mode        one of the defined control requests.
  432.    * \param value       parameter value or one of the control status defined.
  433.    * \return false if parameter errors, true otherwise.
  434.    */
  435.   bool control(uint8_t startDev, uint8_t endDev, controlRequest_t mode, int value);
  436.  
  437.   /**
  438.    * Gets the number of devices attached to this class instance.
  439.    *
  440.    * \return uint8_t representing the number of devices attached to this object.
  441.    */
  442.   uint8_t getDeviceCount(void) { return(_maxDevices); };
  443.  
  444.   /**
  445.    * Gets the maximum number of columns for devices attached to this class instance.
  446.    *
  447.    * \return uint16_t representing the number of columns.
  448.    */
  449.   uint16_t getColumnCount(void) { return(_maxDevices*COL_SIZE); };
  450.  
  451.   /**
  452.    * Set the Shift Data In callback function.
  453.    *
  454.    * The callback function is called from the library when a transform shift left
  455.    * or shift right operation is executed and the library needs to obtain data for
  456.    * the end element of the shift (ie, conceptually this is the new data that is
  457.    * shifted 'into' the display). The callback function is invoked when
  458.    * - WRAPAROUND is not active, as the data would automatically supplied within the library.
  459.    * - the call to transform() is global (ie, not for an individual buffer).
  460.    *  
  461.    * The callback function takes 2 parameters:
  462.    * - the device number requesting the data [0..getDeviceCount()-1]
  463.    * - one of the transformation types in transformType_t) that tells the callback function
  464.    * what shift is being performed
  465.    * The return value is the data for the column to be shifted into the display.
  466.    *
  467.    * \param cb  the address of the function to be called from the library.
  468.    * \return No return data
  469.    */
  470.   void setShiftDataInCallback(uint8_t (*cb)(uint8_t dev, transformType_t t)) { _cbShiftDataIn = cb; };
  471.  
  472.   /**
  473.    * Set the Shift Data Out callback function.
  474.    *
  475.    * The callback function is called from the library when a transform shift left
  476.    * or shift right operation is executed and the library is about to discard the data for
  477.    * the first element of the shift (ie, conceptually this is the data that 'falls' off
  478.    * the front end of the scrolling display). The callback function is invoked when
  479.    * - WRAPAROUND is not active, as the data would automatically supplied to the tail end.
  480.    * - the call to transform() is global (ie, not for an individual buffer).
  481.    *  
  482.    * The callback function is with supplied 3 parameters, with no return value required:
  483.    * - the device number that is the source of the data [0..getDeviceCount()-1]
  484.    * - one of the transformation types transformType_t that tells the callback
  485.    * function the type of shifting being executed
  486.    * - the data for the column being shifted out
  487.    *
  488.    * \param cb  the address of the function to be called from the library.
  489.    * \return No return data
  490.    */
  491.   void setShiftDataOutCallback(void (*cb)(uint8_t dev, transformType_t t, uint8_t colData)) { _cbShiftDataOut = cb; };
  492.  
  493.   /** @} */
  494.  
  495.   //--------------------------------------------------------------
  496.   /** \name Methods for graphics and bitmap related abstraction.
  497.    * @{
  498.    */
  499.   /**
  500.    * Clear all the display data on all the display devices.
  501.    *
  502.    * \return No return value.
  503.    */
  504.   inline void clear(void) { clear(0, getDeviceCount()-1); };
  505.  
  506.   /**
  507.    * Clear all the display data on a subset of devices.
  508.    *
  509.    * endDev must be greater than or equal to startDev.
  510.    *
  511.    * \param startDev    the first device to clear [0..getDeviceCount()-1]
  512.    * \param endDev      the last device to clear [0..getDeviceCount()-1]
  513.    * \return No return value.
  514.    */
  515.   void clear(uint8_t startDev, uint8_t endDev);
  516.  
  517.   /**
  518.    * Draw a line between two points on the display
  519.    *
  520.    * Draw a line between the specified points. The LED will be turned on or
  521.    * off depending on the value supplied. The column number will be dereferenced
  522.    * into the device and column within the device, allowing the LEDs to be treated
  523.    * as a continuous pixel field.
  524.    *
  525.    * \param r1      starting row coordinate for the point [0..ROW_SIZE-1].
  526.    * \param c1      starting column coordinate for the point [0..getColumnCount()-1].
  527.    * \param r2      ending row coordinate for the point [0..ROW_SIZE-1].
  528.    * \param c2      ending column coordinate for the point [0..getColumnCount())-1].
  529.    * \param state   true - switch on; false - switch off.
  530.    * \return false if parameter errors, true otherwise.
  531.    */
  532.   bool drawLine(uint8_t r1, uint16_t c1, uint8_t r2, uint16_t c2, bool state);
  533.  
  534.  /**
  535.    * Load a bitmap from the display buffers to a user buffer.
  536.    *
  537.    * Allows the calling program to read bitmaps (characters or graphic)
  538.    * elements from the library display buffers. The data buffer
  539.    * pointer should be a block of uint8_t data of size elements that will
  540.    * contain the returned data.
  541.    *
  542.    * \param col     address of the display column [0..getColumnCount()-1].
  543.    * \param size    number of columns of data to return.
  544.    * \param *pd     Pointer to a data buffer [0..size-1].
  545.    * \return false if parameter errors, true otherwise. If true, data will be in the buffer at *pd.
  546.    */
  547.   bool getBuffer(uint16_t col, uint8_t size, uint8_t *pd);
  548.  
  549.   /**
  550.    * Get the LEDS status for the specified column.
  551.    *
  552.    * This method operates on a specific buffer
  553.    *
  554.    * This method operates on one column, getting the bit field value of
  555.    * the LEDs in the column. The column is referenced with the absolute column
  556.    * number (ie, the device number is inferred from the column).
  557.    *
  558.    * \param c       column which is to be set [0..getColumnCount()-1].
  559.    * \return uint8_t value with each bit set to 1 if the corresponding LED is lit. 0 is returned for parameter error.
  560.    */
  561.   uint8_t getColumn(uint8_t c) { return getColumn((c / COL_SIZE), c % COL_SIZE); };
  562.  
  563.   /**
  564.    * Get the status of a single LED, addressed as a pixel.
  565.    *
  566.    * The method will get the status of a specific LED element based on its
  567.    * coordinate position. The column number is dereferenced into the device
  568.    * and column within the device, allowing the LEDs to be treated as a
  569.    * continuous pixel field.
  570.    *
  571.    * \param r       row coordinate for the point [0..ROW_SIZE-1].
  572.    * \param c       column coordinate for the point [0..getColumnCount()-1].
  573.    * \return true if LED is on, false if off or parameter errors.
  574.    */
  575.   bool getPoint(uint8_t r, uint16_t c);
  576.  
  577.  /**
  578.    * Load a bitfield from the user buffer to a display buffer.
  579.    *
  580.    * Allows the calling program to define bitmaps (characters or graphic)
  581.    * elements and pass them to the library for display. The data buffer
  582.    * pointer should be a block of uint8_t data of size elements that define
  583.    * the bitmap.
  584.    *
  585.    * \param col     address of the display column [0..getColumnCount()-1].
  586.    * \param size    number of columns of data following.
  587.    * \param *pd     Pointer to a data buffer [0..size-1].
  588.    * \return false if parameter errors, true otherwise.
  589.    */
  590.   bool setBuffer(uint16_t col, uint8_t size, uint8_t *pd);
  591.  
  592.   /**
  593.    * Set all LEDs in a specific column to a new state.
  594.    *
  595.    * This method operates on one column, setting the value of the LEDs in
  596.    * the column to the specified value bitfield. The column is
  597.    * referenced with the absolute column number (ie, the device number is
  598.    * inferred from the column). The method is useful for drawing vertical
  599.    * lines and patterns when the display is being treated as a pixel field.
  600.    * The least significant bit of the value is the lowest row number.
  601.    *
  602.    * \param c       column which is to be set [0..getColumnCount()-1].
  603.    * \param value   each bit set to 1 will light up the corresponding LED.
  604.    * \return false if parameter errors, true otherwise.
  605.    */
  606.   bool setColumn(uint8_t c, uint8_t value) { return setColumn((c / COL_SIZE), c % COL_SIZE, value); };
  607.  
  608.   /**
  609.    * Set the status of a single LED, addressed as a pixel.
  610.    *
  611.    * The method will set the value of a specific LED element based on its
  612.    * coordinate position. The LED will be turned on or off depending on the
  613.    * value supplied. The column number is dereferenced into the device and
  614.    * column within the device, allowing the LEDs to be treated as a
  615.    * continuous pixel field.
  616.    *
  617.    * \param r       row coordinate for the point [0..ROW_SIZE-1].
  618.    * \param c       column coordinate for the point [0..getColumnCount()-1].
  619.    * \param state   true - switch on; false - switch off.
  620.    * \return false if parameter errors, true otherwise.
  621.    */
  622.   bool setPoint(uint8_t r, uint16_t c, bool state);
  623.  
  624.   /**
  625.    * Set all LEDs in a row to a new state on all devices.
  626.    *
  627.    * This method operates on all devices, setting the value of the LEDs in
  628.    * the row to the specified value bit field. The method is useful for
  629.    * drawing patterns and lines horizontally across on the entire display.
  630.    * The least significant bit of the value is the lowest column number.
  631.    *
  632.    * \param r      row which is to be set [0..ROW_SIZE-1].
  633.    * \param value  each bit set to 1 will light up the corresponding LED on each device.
  634.    * \return false if parameter errors, true otherwise.
  635.    */
  636.   inline bool setRow(uint8_t r, uint8_t value) { return setRow(0, getDeviceCount()-1, r, value); };
  637.  
  638.   /**
  639.    * Set all LEDs in a row to a new state on contiguous subset of devices.
  640.    *
  641.    * This method operates on a contiguous subset of devices, setting the value
  642.    * of the LEDs in the row to the specified value bit field. The method is useful for
  643.    * drawing patterns and lines horizontally across specific devices only.
  644.    * endDev must be greater than or equal to startDev.
  645.    * The least significant bit of the value is the lowest column number.
  646.    *
  647.    * \param startDev    the first device for the transformation [0..getDeviceCount()-1]
  648.    * \param endDev      the last device for the transformation [0..getDeviceCount()-1]
  649.    * \param r           row which is to be set [0..ROW_SIZE-1].
  650.    * \param value       each bit set to 1 will light up the corresponding LED on each device.
  651.    * \return false if parameter errors, true otherwise.
  652.    */
  653.   bool setRow(uint8_t startDev, uint8_t endDev, uint8_t r, uint8_t value);
  654.  
  655.   /**
  656.    * Apply a transformation to the data in all the devices.
  657.    *
  658.    * The buffers for all devices can be transformed using one of the enumerated
  659.    * transformations in transformType_t. The transformation is carried across
  660.    * device boundaries (ie, there is overflow to an adjacent devices if appropriate).
  661.    *
  662.    * \param ttype  one of the transformation types in transformType_t.
  663.    * \return false if parameter errors, true otherwise.
  664.    */
  665.   inline bool transform(transformType_t ttype) { return transform(0, getDeviceCount()-1, ttype); };
  666.  
  667.   /**
  668.    * Apply a transformation to the data in contiguous subset of devices.
  669.    *
  670.    * The buffers for all devices in the subset can be transformed using one of the enumerated
  671.    * transformations in transformType_t. The transformation is carried across
  672.    * device boundaries (ie, there is overflow to an adjacent devices if appropriate).
  673.    * endDev must be greater than or equal to startDev.
  674.    *
  675.    * \param startDev    the first device for the transformation [0..getDeviceCount()-1]
  676.    * \param endDev      the last device for the transformation [0..getDeviceCount()-1]
  677.    * \param ttype       one of the transformation types in transformType_t.
  678.    * \return false if parameter errors, true otherwise.
  679.    */
  680.   bool transform(uint8_t startDev, uint8_t endDev, transformType_t ttype);
  681.  
  682.   /**
  683.    * Turn auto display updates on or off.
  684.    *
  685.    * Turn auto updates on and off, as required. When auto updates are turned OFF the
  686.    * display will not update after each operation. Display updates can be forced at any
  687.    * time using using a call to update() with no parameters.
  688.    *
  689.    * This function is a convenience wrapper for the more general control() function call.
  690.    *
  691.    * \param mode    one of the types in controlValue_t (ON/OFF).
  692.    * \return No return value.
  693.    */
  694.   void update(controlValue_t mode) { control(UPDATE, mode); };
  695.  
  696.   /**
  697.    * Force an update of all devices
  698.    *
  699.    * Used when auto updates have been turned off through the control
  700.    * method. This will force all buffered changes to be written to
  701.    * all the connected devices.
  702.    *
  703.    * \return no return value.
  704.    */
  705.   void update(void) { flushBufferAll(); };
  706.  
  707.   /**
  708.    * Turn display wraparound on or off.
  709.    *
  710.    * When shifting left or right, up or down, the outermost edge is normally lost and a blank
  711.    * row or column inserted on the opposite side. If this options is enabled, the edge is wrapped
  712.    * around to the opposite side.
  713.    *
  714.    * This function is a convenience wrapper for the more general control() function call.
  715.    *
  716.    * \param mode    one of the types in controlValue_t (ON/OFF).
  717.    * \return No return value.
  718.    */
  719.   void wraparound(controlValue_t mode) { control(WRAPAROUND, mode); };
  720.   /** @} */
  721.  
  722.   //--------------------------------------------------------------
  723.   /** \name Methods for managing specific devices or display buffers.
  724.    * @{
  725.    */
  726.   /**
  727.    * Clear all display data in the specified buffer.
  728.    *
  729.    * \param buf     address of the buffer to clear [0..getDeviceCount()-1].
  730.    * \return false if parameter errors, true otherwise.
  731.    */
  732.   bool clear(uint8_t buf);
  733.  
  734.   /**
  735.    * Get the state of the LEDs in a specific column.
  736.    *
  737.    * This method operates on the specific buffer, returning the bit field value of
  738.    * the LEDs in the column.
  739.    *
  740.    * \param buf     address of the display [0..getDeviceCount()-1].
  741.    * \param c       column which is to be set [0..COL_SIZE-1].
  742.    * \return uint8_t value with each bit set to 1 if the corresponding LED is lit. 0 is returned for parameter error.
  743.    */
  744.   uint8_t getColumn(uint8_t buf, uint8_t c);
  745.  
  746.   /**
  747.    * Get the state of the LEDs in a specified row.
  748.    *
  749.    * This method operates on the specific buffer, returning the bit field value of
  750.    * the LEDs in the row.
  751.    *
  752.    * \param buf     address of the display [0..getDeviceCount()-1].
  753.    * \param r       row which is to be set [0..ROW_SIZE-1].
  754.    * \return uint8_t value with each bit set to 1 if the corresponding LED is lit. 0 is returned for parameter error.
  755.    */
  756.   uint8_t getRow(uint8_t buf, uint8_t r);
  757.  
  758.   /**
  759.    * Set all LEDs in a column to a new state.
  760.    *
  761.    * This method operates on a specific buffer, setting the value of the LEDs in
  762.    * the column to the specified value bit field. The method is useful for
  763.    * drawing patterns and lines vertically on the display device.
  764.    * The least significant bit of the value is the lowest column number.
  765.    *
  766.    * \param buf     address of the display [0..getDeviceCount()-1].
  767.    * \param c       column which is to be set [0..COL_SIZE-1].
  768.    * \param value   each bit set to 1 will light up the corresponding LED.
  769.    * \return false if parameter errors, true otherwise.
  770.    */
  771.   bool setColumn(uint8_t buf, uint8_t c, uint8_t value);
  772.  
  773.   /**
  774.    * Set all LEDs in a row to a new state.
  775.    *
  776.    * This method operates on a specific device, setting the value of the LEDs in
  777.    * the row to the specified value bit field. The method is useful for
  778.    * drawing patterns and lines horizontally across the display device.
  779.    * The least significant bit of the value is the lowest row number.
  780.    *
  781.    * \param buf     address of the display [0..getDeviceCount()-1].
  782.    * \param r       row which is to be set [0..ROW_SIZE-1].
  783.    * \param value   each bit set to 1 within this byte will light up the corresponding LED.
  784.    * \return false if parameter errors, true otherwise.
  785.    */
  786.   bool setRow(uint8_t buf, uint8_t r, uint8_t value);
  787.  
  788.   /**
  789.    * Apply a transformation to the data in the specified device.
  790.    *
  791.    * The buffer for one device can be transformed using one of the enumerated
  792.    * transformations in transformType_t. The transformation is limited to the
  793.    * nominated device buffer only (ie, there is no overflow to an adjacent device).
  794.    *
  795.    * \param buf    address of the display [0..getBufferCount()-1].
  796.    * \param ttype  one of the transformation types in transformType_t.
  797.    * \return false if parameter errors, true otherwise.
  798.    */
  799.   bool transform(uint8_t buf, transformType_t ttype);
  800.  
  801.   /**
  802.    * Force an update of one buffer.
  803.    *
  804.    * Used when auto updates have been turned off through the control()
  805.    * method. This will force all buffered display changes to be written to
  806.    * the specified device at the same time.
  807.    * Note that control() messages are not buffered but cause immediate action.
  808.    *
  809.    * \param buf address of the display [0..getBufferCount()-1].
  810.    * \return No return value.
  811.    */
  812.   void update(uint8_t buf) { flushBuffer(buf); };
  813.   /** @} */
  814.  
  815. #if USE_LOCAL_FONT
  816.   //--------------------------------------------------------------
  817.   /** \name Methods for font and characters.
  818.    * @{
  819.    */
  820.   /**
  821.    * Load a character from the font data into a user buffer.
  822.    *
  823.    * Copy the bitmap for a library font character (current font set by setFont()) and
  824.    * return it in the data area passed by the user. If the user buffer is not large
  825.    * enough, only the first size elements are copied to the buffer.
  826.    *
  827.    * NOTE: This function is only available if the library defined value
  828.    * USE_LOCAL_FONT is set to 1.
  829.    *
  830.    * \param c       the character to retrieve.
  831.    * \param size    the size of the user buffer in unit8_t units.
  832.    * \param buf     address of the user buffer supplied.
  833.    * \return width (in columns) of the character, 0 if parameter errors.
  834.    */
  835.   uint8_t getChar(uint8_t c, uint8_t size, uint8_t *buf);
  836.  
  837.   /**
  838.    * Load a character from the font data starting at a specific column.
  839.    *
  840.    * Load a character from the font table directly into the display at the column
  841.    * specified. The currently selected font table is used as the source.
  842.    *
  843.    * NOTE: This function is only available if the library defined value
  844.    * USE_LOCAL_FONT is set to 1.
  845.    *
  846.    * \param col     column of the display in the range accepted [0..getColumnCount()-1].
  847.    * \param c       the character to display.
  848.    * \return width (in columns) of the character, 0 if parameter errors.
  849.    */
  850.   uint8_t setChar(uint16_t col, uint8_t c);
  851.  
  852.   /**
  853.    * Set the current font table.
  854.    *
  855.    * Font data is stored in PROGMEM, in the format described elsewhere in the
  856.    * documentation. All characters retrieved or used after this call will use
  857.    * the nominated font (default or user defined). To specify a user defined
  858.    * character set, pass the PROGMEM address of the font table. Passing a NULL
  859.    * pointer resets the font table to the library default table.
  860.    * This function also causes the font index table to be recreated if the
  861.    * library defined value USE_INDEX_TABLE is set to 1.
  862.    *
  863.    * NOTE: This function is only available if the library defined value
  864.    * USE_LOCAL_FONT is set to 1.
  865.    *
  866.    * \param f   fontType_t pointer to the table of font data in PROGMEM or NULL.
  867.    * \return false if parameter errors, true otherwise.
  868.    */
  869.   bool setFont(fontType_t *f);
  870. #endif // USE_LOCAL_FONT
  871.   /** @} */  
  872.  
  873. private:
  874.   typedef struct
  875.   {
  876.     uint8_t dig[ROW_SIZE];  // data for each digit of the MAX72xx (DIG0-DIG7)
  877.     uint8_t changed;        // one bit for each digit changed ('dirty bit')
  878.   } deviceInfo_t;
  879.  
  880.   // SPI interface data
  881.   uint8_t   _dataPin;       // DATA is shifted out of this pin ...
  882.   uint8_t   _clkPin;        // ... signaled by a CLOCK on this pin ...
  883.   uint8_t   _csPin;         // ... and LOADed when the chip select pin is driven HIGH to LOW
  884.   bool      _hardwareSPI;   // true if SPI interface is the hardware interface
  885.    
  886.   // Device buffer data
  887.   uint8_t   _maxDevices;    // maximum number of devices in use
  888.   deviceInfo_t* _matrix;    // the current status of the LED matrix (buffers)
  889.   uint8_t*  _spiData;       // data buffer for writing to SPI interface
  890.  
  891.   // User callback function for shifting operations
  892.   uint8_t   (*_cbShiftDataIn)(uint8_t dev, transformType_t t);
  893.   void      (*_cbShiftDataOut)(uint8_t dev, transformType_t t, uint8_t colData);
  894.    
  895.   // Control data for the library
  896.   bool      _updateEnabled; // update the display when this is true, suspend otherwise
  897.   bool      _wrapAround;    // when shifting, wrap left to right and vice versa (circular buffer)
  898.  
  899. #if USE_LOCAL_FONT
  900.   // Font related data
  901.   fontType_t    *_fontData;     // pointer to the current font data being used
  902.   uint16_t      *_fontIndex;    // font index for faster access to font table offsets
  903.  
  904.   uint16_t  getFontCharOffset(uint8_t c);   // find the character in the font data
  905.   void      buildFontIndex(void);           // build a font index
  906. #endif
  907.  
  908.   // Private functions
  909.   void spiSend(void);           // do the actual physical communications task
  910.   void spiClearBuffer(void);    // clear the SPI send buffer
  911.   void controlHardware(uint8_t dev, controlRequest_t mode, int value);  // set hardware control commands
  912.   void controlLibrary(controlRequest_t mode, int value);    // set internal control commands
  913.  
  914.   void flushBuffer(uint8_t buf);    // determine what needs to be sent for one device and transmit
  915.   void flushBufferAll();            // determine what needs to be sent for all devices and transmit
  916.  
  917.   uint8_t bitReverse(uint8_t b);    // reverse the order of bits in the byte
  918.   bool transformBuffer(uint8_t buf, transformType_t ttype); // internal transform function
  919.  
  920.   bool copyRow(uint8_t buf, uint8_t rSrc, uint8_t rDest);   // copy a row from Src to Dest
  921.   bool copyColumn(uint8_t buf, uint8_t cSrc, uint8_t cDest);    // copy a row from Src to Dest
  922. };
  923.  
  924. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement