mirror of
https://github.com/erik-toth/audio-synth.git
synced 2025-12-06 08:00:02 +00:00
Erste Funktionen zur Firmware erstellt. Keyboard auslesen im Warteschlangen Prinzip. Test-Programm mit 3x4-Matrix Tastatur
172 lines
3.9 KiB
C++
172 lines
3.9 KiB
C++
/*
|
|
@file: FIRMWARE.cpp
|
|
@author: Erik Tóth
|
|
@contact: etoth@tsn.at
|
|
@date: 2025-10-26
|
|
@brief: Firmware for MCU
|
|
*/
|
|
|
|
#include "FIRMWARE.h"
|
|
|
|
bool isNotKey(Key k)
|
|
{
|
|
if((k.row == NOT_A_KEY.row) && (k.col == NOT_A_KEY.col)) return true;
|
|
else return false;
|
|
}
|
|
|
|
bool isEqualKey(Key k1, Key k2)
|
|
{
|
|
if((k1.row == k2.row) && (k1.col == k2.col)) return true;
|
|
else return false;
|
|
}
|
|
|
|
Keyboard::Keyboard(uint8_t nRows, uint8_t nCols, uint8_t *pinsRow, uint8_t *pinsCol)
|
|
{
|
|
_nRows = nRows;
|
|
_nCols = nCols;
|
|
_pinsRow = pinsRow;
|
|
_pinsCol = pinsCol;
|
|
|
|
_nActiveKeys = 0;
|
|
_nSticky = 2;
|
|
|
|
for(uint8_t i = 0; i < _nRows; i++)
|
|
{
|
|
for(uint8_t j = 0; j < _nCols; j++)
|
|
{
|
|
_keyState[i][j] = false;
|
|
_keyStateLatest[i][j] = false;
|
|
_lastChangeTime[i][j] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Keyboard::begin()
|
|
{
|
|
for(int i = 0; i < _nRows; i++) pinMode(_pinsRow[i], INPUT_PULLDOWN);
|
|
for(int i = 0; i < _nCols; i++) pinMode(_pinsCol[i], OUTPUT);
|
|
}
|
|
|
|
void Keyboard::update()
|
|
{
|
|
unsigned long now = millis();
|
|
for(uint8_t i = 0; i < _nCols; i++)
|
|
{
|
|
digitalWrite(_pinsCol[i], HIGH);
|
|
for(uint8_t j = 0; j < _nRows; ++j)
|
|
{
|
|
bool reading = (digitalRead(_pinsRow[j]) == HIGH);
|
|
|
|
if(reading != _keyStateLatest[i][j])
|
|
{
|
|
_keyStateLatest[i][j] = reading;
|
|
_lastChangeTime[i][j] = now;
|
|
}
|
|
|
|
if((now - _lastChangeTime[i][j]) > MS_DEBOUNCE)
|
|
{
|
|
if(reading != _keyState[i][j])
|
|
{
|
|
_keyState[i][j] = reading;
|
|
|
|
if(reading) _addActiveKey(i, j);
|
|
else _removeActiveKey(i, j);
|
|
}
|
|
}
|
|
}
|
|
digitalWrite(_pinsCol[i], LOW);
|
|
}
|
|
if((_nActiveKeys == 1) && _inQueue(NOT_A_KEY)) _nActiveKeys = 0;
|
|
}
|
|
|
|
int Keyboard::getQueueLength()
|
|
{
|
|
return _nActiveKeys;
|
|
}
|
|
|
|
Key Keyboard::getQueue(uint8_t index)
|
|
{
|
|
if(index < _nActiveKeys) return _activeKeys[index];
|
|
else return NOT_A_KEY;
|
|
}
|
|
|
|
bool Keyboard::_inQueue(uint8_t row, uint8_t col)
|
|
{
|
|
for(uint8_t i = 0; i < _nActiveKeys; i++)
|
|
{
|
|
if((_activeKeys[i].row == row) && (_activeKeys[i].col == col)) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Keyboard::_inQueue(Key k)
|
|
{
|
|
for(uint8_t i = 0; i < _nActiveKeys; i++)
|
|
{
|
|
if(_isEqualKey(_activeKeys[i], k)) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Keyboard::_isNotKey(Key k)
|
|
{
|
|
return isNotKey(k);
|
|
}
|
|
|
|
bool Keyboard::_isEqualKey(Key k1, Key k2)
|
|
{
|
|
return isEqualKey(k1, k2);
|
|
}
|
|
|
|
void Keyboard::_addActiveKey(uint8_t row, uint8_t col)
|
|
{
|
|
if(_inQueue(NOT_A_KEY))
|
|
{
|
|
for(int i = 0; i < _nSticky; i++)
|
|
{
|
|
if(_isNotKey(_activeKeys[i]))
|
|
{
|
|
_activeKeys[i] = {row, col};
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else if((_nActiveKeys < N_MAX_QUEUE) && !(_inQueue(row, col)))
|
|
{
|
|
_activeKeys[_nActiveKeys++] = {row, col};
|
|
}
|
|
else return;
|
|
}
|
|
|
|
void Keyboard::_removeActiveKey(uint8_t row, uint8_t col)
|
|
{
|
|
bool notKeyReplaced = true;
|
|
|
|
for(uint8_t i = 0; i < _nActiveKeys; i++)
|
|
{
|
|
if((_activeKeys[i].row == row) && (_activeKeys[i].col == col))
|
|
{
|
|
if(i < _nSticky)
|
|
{
|
|
_activeKeys[i] = NOT_A_KEY;
|
|
notKeyReplaced = false;
|
|
}
|
|
|
|
if((_isNotKey(_activeKeys[i])) && (_nActiveKeys-1 >= _nSticky))
|
|
{
|
|
_activeKeys[i] = _activeKeys[_nSticky];
|
|
notKeyReplaced = true;
|
|
}
|
|
|
|
for(uint8_t j = i; j < _nActiveKeys-1; j++)
|
|
{
|
|
if(j >= _nSticky) _activeKeys[j] = _activeKeys[j + 1];
|
|
}
|
|
|
|
if(notKeyReplaced || (i > _nSticky)) _nActiveKeys--;
|
|
else if(_isNotKey(_activeKeys[_nSticky-1])) _nActiveKeys--;
|
|
|
|
return;
|
|
}
|
|
}
|
|
} |