/* @file: FIRMARE.h @author: Erik Tóth @contact: etoth@tsn.at @date: 2025-10-26 @brief: Header for FIRMWARE.cpp */ #include #include #include #ifndef FIRMWARE_H #define FIRMWARE_H #define N_MAX_QUEUE 10 #define N_MAX_ROWS 8 #define N_MAX_COLS 8 #define MS_DEBOUNCE 20 #define N_MAX_DAC_CH 4 struct Key { int row; int col; }; const Key NOT_A_KEY = {-1, -1}; bool isNotKey(Key k); bool isEqualKey(Key k1, Key k2); class Keyboard { public: Keyboard(uint8_t nRows, uint8_t nCols, uint8_t *pinsRow, uint8_t *pinsCol); void begin(); void update(); int getQueueLength(); Key getQueue(uint8_t index); private: uint8_t _nRows; uint8_t _nCols; uint8_t *_pinsRow; uint8_t *_pinsCol; bool _keyState[N_MAX_COLS][N_MAX_ROWS]; bool _keyStateLatest[N_MAX_COLS][N_MAX_ROWS]; unsigned long _lastChangeTime[N_MAX_COLS][N_MAX_ROWS]; Key _activeKeys[N_MAX_QUEUE]; uint8_t _nActiveKeys; uint8_t _nSticky; void _addActiveKey(uint8_t row, uint8_t col); void _removeActiveKey(uint8_t row, uint8_t col); bool _inQueue(uint8_t row, uint8_t col); bool _inQueue(Key k); bool _isNotKey(Key k); bool _isEqualKey(Key k1, Key k2); }; class CV { public: CV(Adafruit_MCP4728 *dac, TwoWire *wire, uint8_t nCV, MCP4728_channel_t *cvChannelMap, uint16_t *keyToVoltage, uint8_t row, uint8_t col); bool begin(uint8_t pinSDA, uint8_t pinSCL); void setVoltage(uint8_t cvIndex, Key k); void setVoltage(uint8_t cvIndex, uint16_t mV); void clearAll(); private: Adafruit_MCP4728 *_dac; TwoWire *_wire; uint8_t _nCV; uint8_t _row; uint8_t _col; MCP4728_channel_t _cvChannelMap[N_MAX_DAC_CH]; uint16_t *_keyToVoltage; uint8_t _getKeyToVoltageIndex(uint8_t row, uint8_t col); uint8_t _getKeyToVoltageIndex(Key k); }; #endif