92 lines
2.9 KiB
C++
92 lines
2.9 KiB
C++
#include "keyboard.h"
|
|
#include "usart.h"
|
|
extern "C" {
|
|
extern const unsigned dtmf_low_tab [];
|
|
extern const unsigned dtmf_hi__tab [];
|
|
};
|
|
static const uint32_t col_table [] = {
|
|
0x0002'001Cu,
|
|
0x0004'001Au,
|
|
0x0008'0016u,
|
|
0x0010'000Eu,
|
|
};
|
|
static const char * out_table [] = {
|
|
"*741", "0852", "#963"
|
|
};
|
|
unsigned int Keyboard::Send(uint16_t * const ptr, const unsigned int len) {
|
|
for (unsigned n=0u; n<len; n++) ptr [n] = 1000 + gl.step() + gh.step();
|
|
const unsigned index = (col_cnt >> 1) & 3u;
|
|
if ((col_cnt & 1) == 0u) { // sudý cnt zapíše 0 na port (řádek)
|
|
GPIOC.BSHR.R = col_table [ index ];
|
|
} else { // lichý, následný přečte sloupec
|
|
const uint32_t row = (~GPIOC.INDR.R >> 5) & 0x7u;
|
|
if (status [index] != row) { // změna - je potřeba něco udělat
|
|
if (row) led << false;
|
|
else led << true;
|
|
char c = '\0';
|
|
gl.set(dtmf_low_tab [index]);
|
|
if (row & 1u) { // ono to row je vlastně sloupec,
|
|
c = out_table [2] [index]; // nechce se mi to přepisovat
|
|
gh.set (dtmf_hi__tab [2]);
|
|
} else if (row & 2u) {
|
|
c = out_table [0] [index];
|
|
gh.set (dtmf_hi__tab [0]);
|
|
} else if (row & 4u) {
|
|
c = out_table [1] [index];
|
|
gh.set (dtmf_hi__tab [1]);
|
|
} else { // konec stisku tlačítka
|
|
gh.set(0u); gl.set(0u); // ticho
|
|
}
|
|
if (c) out(c);
|
|
status [index] = row;
|
|
}
|
|
}
|
|
col_cnt += 1u;
|
|
return len;
|
|
}
|
|
void Keyboard::init() {
|
|
for (unsigned n=0u; n<4u; n++) status [n] = 0u;
|
|
led << true;
|
|
RCC.APB2PCENR.B.IOPCEN = SET;
|
|
GPIOC.CFGLR.modify([](GPIOA_Type::CFGLR_DEF & r) -> auto {
|
|
r.B.MODE1 = 1u; // Output mode, maximum speed 10MHz
|
|
r.B.CNF1 = 1u; // Universal open-drain output mode
|
|
r.B.MODE2 = 1u; // Output mode, maximum speed 10MHz
|
|
r.B.CNF2 = 1u; // Universal open-drain output mode
|
|
r.B.MODE3 = 1u; // Output mode, maximum speed 10MHz
|
|
r.B.CNF3 = 1u; // Universal open-drain output mode
|
|
r.B.MODE4 = 1u; // Output mode, maximum speed 10MHz
|
|
r.B.CNF4 = 1u; // Universal open-drain output mode
|
|
|
|
r.B.MODE5 = 0u; // Input mode
|
|
r.B.CNF5 = 2u; // With pull-up and pull-down mode
|
|
r.B.MODE6 = 0u; // Input mode
|
|
r.B.CNF6 = 2u; // With pull-up and pull-down mode
|
|
r.B.MODE7 = 0u; // Input mode
|
|
r.B.CNF7 = 2u; // With pull-up and pull-down mode
|
|
return r.R;
|
|
});
|
|
GPIOC.OUTDR.R |= 0xE0u; // pull-up vstupů
|
|
}
|
|
void Keyboard::out(const char c) {
|
|
usart.Down (&c, 1u);
|
|
if (c == '#') {
|
|
usart.Down ("\r\n", 2u);
|
|
pas_num = BEGIN;
|
|
pas_cnt = 0u;
|
|
relay << false;
|
|
return;
|
|
}
|
|
if (c == password [pas_cnt] and pas_num == BEGIN) {
|
|
pas_cnt += 1u;
|
|
if (password [pas_cnt] == '\0') { // konec
|
|
pas_num = END;
|
|
pas_cnt = 0u;
|
|
relay << true;
|
|
}
|
|
} else {
|
|
pas_num = BEGIN;
|
|
pas_cnt = 0u;
|
|
relay << false;
|
|
}
|
|
}
|