198 lines
6.1 KiB
C
198 lines
6.1 KiB
C
/***************************************************************************
|
|
* Copyright (C) 2024 by Silvano Seva IU2KWO *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 3 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* 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/> *
|
|
***************************************************************************/
|
|
|
|
#include <stdint.h>
|
|
#include <peripherals/gpio.h>
|
|
#include <interfaces/delays.h>
|
|
#include <interfaces/keyboard.h>
|
|
#include <interfaces/platform.h>
|
|
#include <hwconfig.h>
|
|
|
|
|
|
/*
|
|
* Keyboard map:
|
|
*
|
|
* R902 R903 R904 R909 R926
|
|
* +-------+-------+-------+-------+-------+
|
|
* | Col 1 | Col 2 | Col 3 | Col 4 | Col 5 |
|
|
* +-------+-------+-------+-------+-------+-------+
|
|
* | Row 1 | 1 | 2 | 3 | k1 | k5 | R905
|
|
* +-------+-------+-------+-------+-------+-------+
|
|
* | Row 2 | 4 | 5 | 6 | k2 | k6 | R906
|
|
* +-------+-------+-------+-------+-------+-------+
|
|
* | Row 3 | 7 | 8 | 9 | k3 | | R907
|
|
* +-------+-------+-------+-------+-------+-------+
|
|
* | Row 4 | * | 0 | # | k4 | | R908
|
|
* +-------+-------+-------+-------+-------+-------+
|
|
*
|
|
*/
|
|
|
|
static uint8_t knobPrev = 0;
|
|
static uint8_t knobPos = 0;
|
|
|
|
static uint8_t getKnobPos()
|
|
{
|
|
static const uint8_t knobTable[] =
|
|
{
|
|
0x09, 0x0A, 0x04, 0x03, 0x08,
|
|
0x07, 0x05, 0x06, 0x0C, 0x0B,
|
|
0x01, 0x02, 0x0D, 0x0E, 0x10, 0x0F
|
|
};
|
|
|
|
uint8_t encState = (gpio_readPin(CH_SELECTOR_3) << 3)
|
|
| (gpio_readPin(CH_SELECTOR_2) << 2)
|
|
| (gpio_readPin(CH_SELECTOR_1) << 1)
|
|
| gpio_readPin(CH_SELECTOR_0);
|
|
|
|
return knobTable[encState];
|
|
}
|
|
|
|
void kbd_init()
|
|
{
|
|
gpio_setMode(KB_COL5, INPUT_PULL_DOWN);
|
|
gpio_setMode(SIDE_KEY1, INPUT);
|
|
gpio_setMode(SIDE_KEY2, INPUT);
|
|
gpio_setMode(SIDE_KEY3, INPUT);
|
|
gpio_setMode(ALARM_KEY, INPUT);
|
|
|
|
gpio_setMode(CH_SELECTOR_0, INPUT);
|
|
gpio_setMode(CH_SELECTOR_1, INPUT);
|
|
gpio_setMode(CH_SELECTOR_2, INPUT);
|
|
gpio_setMode(CH_SELECTOR_3, INPUT);
|
|
|
|
knobPos = getKnobPos();
|
|
knobPrev = knobPos;
|
|
}
|
|
|
|
void kbd_terminate()
|
|
{
|
|
|
|
}
|
|
|
|
keyboard_t kbd_getKeys()
|
|
{
|
|
keyboard_t keys = 0;
|
|
|
|
knobPos = getKnobPos();
|
|
if(knobPos != knobPrev)
|
|
{
|
|
if(knobPos > knobPrev)
|
|
keys |= KNOB_RIGHT;
|
|
else if(knobPos < knobPrev)
|
|
keys |= KNOB_LEFT;
|
|
|
|
if((knobPos > 8) && (knobPrev < 8))
|
|
{
|
|
keys |= KNOB_LEFT;
|
|
keys &= ~KNOB_RIGHT;
|
|
}
|
|
|
|
if((knobPos < 8) && (knobPrev > 8))
|
|
{
|
|
keys |= KNOB_RIGHT;
|
|
keys &= ~KNOB_LEFT;
|
|
}
|
|
|
|
knobPrev = knobPos;
|
|
}
|
|
|
|
/*
|
|
* Rows and columns lines are in common with the display, so we have to
|
|
* configure them as inputs before scanning. However, before configuring them
|
|
* as inputs, we put them as outputs and force a low logical level in order
|
|
* to be sure that any residual charge on both the display controller's inputs
|
|
* and in the capacitors in parallel to the Dx lines is dissipated.
|
|
*/
|
|
gpio_setMode(LCD_D0, OUTPUT);
|
|
gpio_setMode(LCD_D1, OUTPUT);
|
|
gpio_setMode(LCD_D2, OUTPUT);
|
|
gpio_setMode(LCD_D3, OUTPUT);
|
|
gpio_setMode(LCD_D4, OUTPUT);
|
|
gpio_setMode(LCD_D5, OUTPUT);
|
|
gpio_setMode(LCD_D6, OUTPUT);
|
|
gpio_setMode(LCD_D7, OUTPUT);
|
|
|
|
gpio_clearPin(LCD_D0);
|
|
gpio_clearPin(LCD_D1);
|
|
gpio_clearPin(LCD_D2);
|
|
gpio_clearPin(LCD_D3);
|
|
gpio_clearPin(LCD_D4);
|
|
gpio_clearPin(LCD_D5);
|
|
gpio_clearPin(LCD_D6);
|
|
gpio_clearPin(LCD_D7);
|
|
|
|
|
|
gpio_setMode(KB_COL1, INPUT_PULL_DOWN);
|
|
gpio_setMode(KB_COL2, INPUT_PULL_DOWN);
|
|
gpio_setMode(KB_COL3, INPUT_PULL_DOWN);
|
|
gpio_setMode(KB_COL4, INPUT_PULL_DOWN);
|
|
|
|
gpio_setPin(KB_ROW1);
|
|
|
|
delayUs(10);
|
|
if(gpio_readPin(KB_COL1) != 0) keys |= KEY_1;
|
|
if(gpio_readPin(KB_COL2) != 0) keys |= KEY_2;
|
|
if(gpio_readPin(KB_COL3) != 0) keys |= KEY_3;
|
|
if(gpio_readPin(KB_COL4) != 0) keys |= KEY_ENTER;
|
|
if(gpio_readPin(KB_COL5) != 0) keys |= KEY_UP;
|
|
|
|
gpio_clearPin(KB_ROW1);
|
|
gpio_setPin(KB_ROW2);
|
|
|
|
delayUs(10);
|
|
if(gpio_readPin(KB_COL1) != 0) keys |= KEY_4;
|
|
if(gpio_readPin(KB_COL2) != 0) keys |= KEY_5;
|
|
if(gpio_readPin(KB_COL3) != 0) keys |= KEY_6;
|
|
if(gpio_readPin(KB_COL4) != 0) keys |= KEY_ESC;
|
|
if(gpio_readPin(KB_COL5) != 0) keys |= KEY_DOWN;
|
|
|
|
gpio_clearPin(KB_ROW2);
|
|
gpio_setPin(KB_ROW3);
|
|
|
|
delayUs(10);
|
|
if(gpio_readPin(KB_COL1) != 0) keys |= KEY_7;
|
|
if(gpio_readPin(KB_COL2) != 0) keys |= KEY_8;
|
|
if(gpio_readPin(KB_COL3) != 0) keys |= KEY_9;
|
|
if(gpio_readPin(KB_COL4) != 0) keys |= KEY_F4;
|
|
|
|
gpio_clearPin(KB_ROW3);
|
|
gpio_setPin(KB_ROW4);
|
|
|
|
delayUs(10);
|
|
if(gpio_readPin(KB_COL1) != 0) keys |= KEY_STAR;
|
|
if(gpio_readPin(KB_COL2) != 0) keys |= KEY_0;
|
|
if(gpio_readPin(KB_COL3) != 0) keys |= KEY_HASH;
|
|
if(gpio_readPin(KB_COL4) != 0) keys |= KEY_F5;
|
|
|
|
gpio_clearPin(KB_ROW4);
|
|
|
|
if(gpio_readPin(SIDE_KEY1) == 0) keys |= KEY_MONI;
|
|
if(gpio_readPin(SIDE_KEY2) == 0) keys |= KEY_F1;
|
|
if(gpio_readPin(SIDE_KEY3) == 0) keys |= KEY_F2;
|
|
if(gpio_readPin(ALARM_KEY) == 0) keys |= KEY_F3;
|
|
|
|
return keys;
|
|
}
|
|
|
|
/*
|
|
* This function is defined in platform.h
|
|
*/
|
|
int8_t platform_getChSelector()
|
|
{
|
|
return knobPos;
|
|
}
|