#include "Adafruit_NeoTrellis.h" /**************************************************************************/ /*! @brief Class constructor @param addr the I2C address this neotrellis object uses @param i2c_bus the I2C bus connected to this neotrellis, defaults to "Wire" */ /**************************************************************************/ Adafruit_NeoTrellis::Adafruit_NeoTrellis(uint8_t addr, TwoWire *i2c_bus) : Adafruit_seesaw(i2c_bus), pixels(NEO_TRELLIS_NUM_KEYS, NEO_TRELLIS_NEOPIX_PIN, NEO_GRB + NEO_KHZ800, i2c_bus) { for (int i = 0; i < NEO_TRELLIS_NUM_KEYS; i++) { _callbacks[i] = NULL; } this->_addr = addr; } /**************************************************************************/ /*! @brief Begin communication with the RGB trellis. @param addr optional i2c address where the device can be found. Defaults to NEO_TRELLIS_ADDR @param flow optional flow control pin @returns true on success, false on error. */ /**************************************************************************/ bool Adafruit_NeoTrellis::begin(uint8_t addr, int8_t flow) { _addr = addr; bool ret = pixels.begin(addr, flow); ret = Adafruit_seesaw::begin(addr, flow, false); if (!ret) return ret; enableKeypadInterrupt(); return ret; } /**************************************************************************/ /*! @brief register a callback function on the passed key. @param key the key number to register the callback on @param cb the callback function that should be called when an event on that key happens */ /**************************************************************************/ void Adafruit_NeoTrellis::registerCallback(uint8_t key, TrellisCallback (*cb)(keyEvent)) { _callbacks[key] = cb; } /**************************************************************************/ /*! @brief unregister a callback on a given key @param key the key number the callback is currently mapped to. */ /**************************************************************************/ void Adafruit_NeoTrellis::unregisterCallback(uint8_t key) { _callbacks[key] = NULL; } /**************************************************************************/ /*! @brief activate or deactivate a given key event @param key the key number to map the event to @param edge the edge sensitivity of the event @param enable pass true to enable the passed event, false to disable it. */ /**************************************************************************/ void Adafruit_NeoTrellis::activateKey(uint8_t key, uint8_t edge, bool enable) { setKeypadEvent(NEO_TRELLIS_KEY(key), edge, enable); } /**************************************************************************/ /*! @brief read all events currently stored in the seesaw fifo and call any callbacks. @param polling pass true if the interrupt pin is not being used, false if it is. Defaults to true. */ /**************************************************************************/ void Adafruit_NeoTrellis::read(bool polling) { uint8_t count = getKeypadCount(); delayMicroseconds(500); if (count > 0) { if (polling) count = count + 2; keyEventRaw e[count]; readKeypad(e, count); for (int i = 0; i < count; i++) { // call any callbacks associated with the key e[i].bit.NUM = NEO_TRELLIS_SEESAW_KEY(e[i].bit.NUM); if (e[i].bit.NUM < NEO_TRELLIS_NUM_KEYS && _callbacks[e[i].bit.NUM] != NULL) { keyEvent evt = {e[i].bit.EDGE, e[i].bit.NUM}; _callbacks[e[i].bit.NUM](evt); } } } } /**************************************************************************/ /*! @brief class constructor @param trelli pointer to a multidimensional array of neotrellis objects. these object must have their I2C addresses specified in the class constructors. @param rows the number of individual neotrellis boards in the Y direction of your matrix. @param cols the number of individual neotrellis boards in the X direction of your matrix. */ /**************************************************************************/ Adafruit_MultiTrellis::Adafruit_MultiTrellis(Adafruit_NeoTrellis *trelli, uint8_t rows, uint8_t cols) { this->_rows = rows; this->_cols = cols; this->_trelli = trelli; } /**************************************************************************/ /*! @brief begin communication with the matrix of neotrellis boards. @returns true on success, false otherwise. */ /**************************************************************************/ bool Adafruit_MultiTrellis::begin() { Adafruit_NeoTrellis *t; for (int n = 0; n < _rows; n++) { for (int m = 0; m < _cols; m++) { t = (_trelli + n * _cols) + m; if (!t->begin(t->_addr)) return false; } } return true; } /**************************************************************************/ /*! @brief register a callback for a key addressed by key index. @param x the column index of the key. column 0 is on the lefthand side of the matix. @param y the row index of the key. row 0 is at the top of the matrix and the numbers increase downwards. @param cb the function to be called when an event from the specified key is detected. */ /**************************************************************************/ void Adafruit_MultiTrellis::registerCallback(uint8_t x, uint8_t y, TrellisCallback (*cb)(keyEvent)) { Adafruit_NeoTrellis *t = (_trelli + y / NEO_TRELLIS_NUM_ROWS * _cols) + x / NEO_TRELLIS_NUM_COLS; int xkey = NEO_TRELLIS_X(x); int ykey = NEO_TRELLIS_Y(y % NEO_TRELLIS_NUM_ROWS * NEO_TRELLIS_NUM_COLS); t->registerCallback(NEO_TRELLIS_XY(xkey, ykey), cb); } /**************************************************************************/ /*! @brief register a callback for a key addressed by key number. @param num the keynumber to set the color of. Key 0 is in the top left corner of the trellis matrix, key 1 is directly to the right of it, and the last key number is in the bottom righthand corner. @param cb the function to be called when an event from the specified key is detected. */ /**************************************************************************/ void Adafruit_MultiTrellis::registerCallback(uint16_t num, TrellisCallback (*cb)(keyEvent)) { uint8_t x = num % (NEO_TRELLIS_NUM_COLS * _cols); uint8_t y = num / (NEO_TRELLIS_NUM_COLS * _cols); registerCallback(x, y, cb); } /**************************************************************************/ /*! @brief Unregister a callback for a key addressed by key index. @param x the column index of the key. column 0 is on the lefthand side of the matix. @param y the row index of the key. row 0 is at the top of the matrix and the numbers increase downwards. */ /**************************************************************************/ void Adafruit_MultiTrellis::unregisterCallback(uint8_t x, uint8_t y) { Adafruit_NeoTrellis *t = (_trelli + y / NEO_TRELLIS_NUM_ROWS * _cols) + x / NEO_TRELLIS_NUM_COLS; int xkey = NEO_TRELLIS_X(x); int ykey = NEO_TRELLIS_Y(y % NEO_TRELLIS_NUM_ROWS * NEO_TRELLIS_NUM_COLS); t->unregisterCallback(NEO_TRELLIS_XY(xkey, ykey)); } /**************************************************************************/ /*! @brief Unregister a callback for a key addressed by key number. @param num the keynumber to set the color of. Key 0 is in the top left corner of the trellis matrix, key 1 is directly to the right of it, and the last key number is in the bottom righthand corner. */ /**************************************************************************/ void Adafruit_MultiTrellis::unregisterCallback(uint16_t num) { uint8_t x = num % (NEO_TRELLIS_NUM_COLS * _cols); uint8_t y = num / (NEO_TRELLIS_NUM_COLS * _cols); unregisterCallback(x, y); } /**************************************************************************/ /*! @brief Activate or deactivate a key by number. @param x the column index of the key. column 0 is on the lefthand side of the matix. @param y the row index of the key. row 0 is at the top of the matrix and the numbers increase downwards. @param edge the edge that the key triggers an event on. Use SEESAW_KEYPAD_EDGE_FALLING or SEESAW_KEYPAD_EDGE_RISING. @param enable pass true to enable the key on the passed edge, false to disable. */ /**************************************************************************/ void Adafruit_MultiTrellis::activateKey(uint8_t x, uint8_t y, uint8_t edge, bool enable) { Adafruit_NeoTrellis *t = (_trelli + y / NEO_TRELLIS_NUM_ROWS * _cols) + x / NEO_TRELLIS_NUM_COLS; int xkey = NEO_TRELLIS_X(x); int ykey = NEO_TRELLIS_Y(y % NEO_TRELLIS_NUM_ROWS * NEO_TRELLIS_NUM_COLS); t->activateKey(NEO_TRELLIS_XY(xkey, ykey), edge, enable); } /**************************************************************************/ /*! @brief Activate or deactivate a key by number. @param num the keynumber to set the color of. Key 0 is in the top left corner of the trellis matrix, key 1 is directly to the right of it, and the last key number is in the bottom righthand corner. @param edge the edge that the key triggers an event on. Use SEESAW_KEYPAD_EDGE_FALLING or SEESAW_KEYPAD_EDGE_RISING. @param enable pass true to enable the key on the passed edge, false to disable. */ /**************************************************************************/ void Adafruit_MultiTrellis::activateKey(uint16_t num, uint8_t edge, bool enable) { uint8_t x = num % (NEO_TRELLIS_NUM_COLS * _cols); uint8_t y = num / (NEO_TRELLIS_NUM_COLS * _cols); activateKey(x, y, edge, enable); } /**************************************************************************/ /*! @brief set the color of a neopixel at a key index. @param x the column index of the key. column 0 is on the lefthand side of the matix. @param y the row index of the key. row 0 is at the top of the matrix and the numbers increase downwards. @param color the color to set the pixel to. This is a 24 bit RGB value. for example, full brightness red would be 0xFF0000, and full brightness blue would be 0x0000FF. */ /**************************************************************************/ void Adafruit_MultiTrellis::setPixelColor(uint8_t x, uint8_t y, uint32_t color) { Adafruit_NeoTrellis *t = (_trelli + y / NEO_TRELLIS_NUM_ROWS * _cols) + x / NEO_TRELLIS_NUM_COLS; int xkey = NEO_TRELLIS_X(x); int ykey = NEO_TRELLIS_Y(y % NEO_TRELLIS_NUM_ROWS * NEO_TRELLIS_NUM_COLS); t->pixels.setPixelColor(NEO_TRELLIS_XY(xkey, ykey), color); } /**************************************************************************/ /*! @brief set the color of a neopixel at a key number. @param num the keynumber to set the color of. Key 0 is in the top left corner of the trellis matrix, key 1 is directly to the right of it, and the last key number is in the bottom righthand corner. @param color the color to set the pixel to. This is a 24 bit RGB value. for example, full brightness red would be 0xFF0000, and full brightness blue would be 0x0000FF. */ /**************************************************************************/ void Adafruit_MultiTrellis::setPixelColor(uint16_t num, uint32_t color) { uint8_t x = num % (NEO_TRELLIS_NUM_COLS * _cols); uint8_t y = num / (NEO_TRELLIS_NUM_COLS * _cols); setPixelColor(x, y, color); } /**************************************************************************/ /*! @brief call show for all connected neotrellis boards to show all neopixels */ /**************************************************************************/ void Adafruit_MultiTrellis::show() { Adafruit_NeoTrellis *t; for (int n = 0; n < _rows; n++) { for (int m = 0; m < _cols; m++) { t = (_trelli + n * _cols) + m; t->pixels.show(); } } } /**************************************************************************/ /*! @brief read all events currently stored in the seesaw fifo and call any callbacks. */ /**************************************************************************/ void Adafruit_MultiTrellis::read() { Adafruit_NeoTrellis *t; for (int n = 0; n < _rows; n++) { for (int m = 0; m < _cols; m++) { t = (_trelli + n * _cols) + m; uint8_t count = t->getKeypadCount(); delayMicroseconds(500); if (count > 0) { count = count + 2; keyEventRaw e[count]; t->readKeypad(e, count); for (int i = 0; i < count; i++) { // call any callbacks associated with the key e[i].bit.NUM = NEO_TRELLIS_SEESAW_KEY(e[i].bit.NUM); if (e[i].bit.NUM < NEO_TRELLIS_NUM_KEYS && t->_callbacks[e[i].bit.NUM] != NULL) { // update the event with the multitrellis number keyEvent evt = {e[i].bit.EDGE, e[i].bit.NUM}; int x = NEO_TRELLIS_X(e[i].bit.NUM); int y = NEO_TRELLIS_Y(e[i].bit.NUM); x = x + m * NEO_TRELLIS_NUM_COLS; y = y + n * NEO_TRELLIS_NUM_ROWS; evt.bit.NUM = y * NEO_TRELLIS_NUM_COLS * _cols + x; t->_callbacks[e[i].bit.NUM](evt); } } } } } }