blk_box_tc/main/drivers/TM1640/TM16xx.h
2024-07-28 18:19:16 -05:00

139 lines
6.3 KiB
C++

/*
TM16xx.h - Library for TM1637, TM1638 and similar chips.
Copyright (C) 2011 Ricardo Batista <rjbatista at gmail dot com>
Modified by Maxint R&D. See https://github.com/maxint-rd/
This program is free software: you can redistribute it and/or modify
it under the terms of the version 3 GNU General Public License as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TM16XX_h
#define TM16XX_h
#if !defined(__max)
// MMOLE 180325: min, max are no macro in ESP core 2.3.9 libraries, see https://github.com/esp8266/Arduino/issues/398
// MMOLE 211229: Redefining min/max has issues in newer ESP cores with certain wifi libraries.
// See definition as function template below.
#define __min(a,b) ((a)<(b)?(a):(b))
#define __max(a,b) ((a)>(b)?(a):(b))
#endif
#if !defined(_BV)
// MMOLE 220909: _BV is not defined in Raspberry Pi Pico RP2040 core v2.4.0 or v2.5.2 by Earle F. Philhower
// TM16xx uses it in some classes to determine button presses (TM1628/30/37/38/38Anode
// Note that _BV works on int values (16-bit in Arduino). For that reason using bit() would be better.
// This is how _BV is defined in the AVR libraries used within Arduino:
#define _BV( x )( 1<<(x))
#endif
#define TM16XX_CMD_DATA_AUTO 0x40
#define TM16XX_CMD_DATA_READ 0x42 // command to read data used on two wire interfaces of TM1637
#define TM16XX_CMD_DATA_FIXED 0x44
#define TM16XX_CMD_DISPLAY 0x80
#define TM16XX_CMD_ADDRESS 0xC0
// Common display modes for selecting different GRID x SEGMENT configuration
// Used by e.g. TM1618, TM1620, TM1628, TM1630, TM1668
// (note: TM1652 combined display control and uses a single bit to designate 5x8 or 6x8)
#define TM16XX_CMD_MODE_4GRID 0x00
#define TM16XX_CMD_MODE_5GRID 0x01 // TM1630: 4x8 - 5x7
#define TM16XX_CMD_MODE_6GRID 0x02 // TM1620: 4x10 - 6x8
#define TM16XX_CMD_MODE_7GRID 0x03 // TM1628, TM1668: 4x13 - 7x10, TM1624: 4x14 - 7x11, TM1618: 4x8 - 7x5
#include "TM16xxFonts.h"
#include <driver/gpio.h>
class TM16xx
{
public:
/**
* Instantiate a TM16xx module specifying data, clock and strobe pins (no strobe on some modules),
* the maximum number of displays supported by the chip (as provided by derived chip specific class),
* the number of digits used to display numbers or text,
* display state and the starting intensity (0-7).
*/
TM16xx(gpio_num_t dataPin, gpio_num_t clockPin, gpio_num_t strobePin, uint8_t maxDisplays, uint8_t nDigitsUsed, bool activateDisplay=true, uint8_t intensity=7);
/** Set the display (segments and LEDs) active or off and intensity (range from 0-7). */
virtual void setupDisplay(bool active, uint8_t intensity);
/** Clear the display */
virtual void clearDisplay();
/** Set segments of the display */
virtual void setSegments(uint8_t segments, uint8_t position);
virtual void setSegments16(uint16_t segments, uint8_t position); // some modules support more than 8 segments
// Basic display functions. For additional display features use the TM16xxDisplay class
/** Set a single display at pos (starting at 0) to a digit (left to right) */
virtual void setDisplayDigit(uint8_t digit, uint8_t pos=0, bool dot=false, const uint8_t numberFont[] = TM16XX_NUMBER_FONT);
/** Set the display to a decimal number */
virtual void setDisplayToDecNumber(int nNumber, uint8_t bDots=0);
/** Clear a single display at pos (starting at 0, left to right) */
virtual void clearDisplayDigit(uint8_t pos, bool dot=false);
/** Set the display to the values (left to right) */
virtual void setDisplay(const uint8_t values[], uint8_t size=8);
/** Set the display to the string (defaults to built in font) */
virtual void setDisplayToString(const char* string, const uint32_t dots=0, const uint8_t pos=0, const uint8_t font[] = TM16XX_FONT_DEFAULT);
virtual void sendChar(uint8_t pos, uint8_t data, bool dot); // made public to allow calling from TM16xxDisplay
virtual uint8_t getNumDigits(); // added as public menthod to allow calling from TM16xxDisplay
virtual void sendAsciiChar(uint8_t pos, char c, bool dot); // made public to allow calling from TM16xxDisplay
// Key-scanning functions
// Note: not all TM16xx chips support key-scanning and sizes are different per chip
// Up to 32 key states are supported, but specific chips may support less keys or less combinations
// The chip specific derived class method will return a 32-bit value representing the state of each key, containing 0 if no key is pressed
virtual uint32_t getButtons(); // return state of up to 32 keys.
protected:
// virtual void sendChar(byte pos, byte data, bool dot);
virtual void bitDelay();
virtual void start();
virtual void stop();
virtual void send(uint8_t data);
virtual void sendCommand(uint8_t led);
virtual void sendData(uint8_t add, uint8_t data);
virtual uint8_t receive();
#if !defined(max)
// MMOLE 211229: use c++ function templates to implement our own min/max, as redefining them wont work in newer ESP cores when using certain wifi libraries
// NOTE: min, max are no macro in ESP core 2.3.9 libraries, see https://github.com/esp8266/Arduino/issues/398
// See also
// https://www.cplusplus.com/doc/oldtutorial/templates/
// https://www.alltestanswers.com/c-templates-for-the-two-functions-minimum-and-maximum/
// https://www.learncpp.com/cpp-tutorial/function-templates-with-multiple-template-types/
// MMOLE 220814: Arduino IDE 1.8.12 for LGT328P required "#if !defined(max)" to prevent compilation errors
template <typename T, typename U>
auto max(T x, U y) -> decltype(x>y ? x : y)
{
return x>y ? x : y;
}
template <typename T, typename U>
auto min(T x, U y) -> decltype(x>y ? x : y)
{
return x<y ? x : y;
}
#endif // !defined(max)
uint8_t _maxDisplays=2; // maximum number of digits (grids), chip-dependent
uint8_t _maxSegments=8; // maximum number of segments per display, chip-dependent
uint8_t digits; // number of digits in the display, module dependent
gpio_num_t dataPin;
gpio_num_t clockPin;
gpio_num_t strobePin;
};
#endif