Files
TX/source/keys.c
2025-06-20 18:02:50 -05:00

365 lines
8.1 KiB
C

/*
* keys.c
*
* Created on: Mar 7, 2022
* Author: Brian.Bailey
*/
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include<arm_math.h>
#include <stdint.h>
#include "fsl_common.h"
#include "fsl_gpio.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "keys.h"
#include "timer.h"
#include "io.h"
#include "System/system.h"
/*******************************************************************************
* Definitions
******************************************************************************/
//KEY GPIO DEFINITIONS
/*
#define KEY0_PORT 1 // 208002
#define KEY1_PORT 1
#define KEY2_PORT 0
#define KEY3_PORT 0
#define KEY4_PORT 0
#define KEY5_PORT 0
*/
#define KEY0_PORT 1 // 208004
#define KEY1_PORT 0
#define KEY2_PORT 0
#define KEY3_PORT 0
#define KEY4_PORT 0
#define KEY5_PORT 0
/* //208002
#define KEY0_PIN 15 //Power On/Off key //on off
#define KEY1_PIN 5 //MODE key //SFTKY0
#define KEY2_PIN 2 //UP key //SFTKY1
#define KEY3_PIN 3 //DOWN key //SFTKY2
#define KEY4_PIN 8 //FREQUENCY key //SFTKY3
#define KEY5_PIN 9 //Menu key //SFTKY4
*/
// 208004
#define KEY0_PIN 15 //Power On/Off key //on off 208004
#define KEY1_PIN 14 //MODE key //SFTKY0
#define KEY2_PIN 2 //UP key //SFTKY1
#define KEY3_PIN 3 //DOWN key //SFTKY2
#define KEY4_PIN 24 //FREQUENCY key //SFTKY3
#define KEY5_PIN 25 //Menu key //SFTKY4
#define KEY_UP_PIN KEY2_PIN //UP key
#define KEY_DOWN_PIN KEY3_PIN //DOWN key
#define KEY_FREQ_PIN KEY4_PIN //FREQ key
/*******************************************************************************
* Variables
******************************************************************************/
//Move this to header file later
typedef struct
{
uint32_t gpioPin; //Key gpio pin within the port
uint32_t gpioPort; // Key GPIO Port
uint32_t tickCount; //number of consecutive ticks key held ON
uint32_t currentState; //Key on/off for current tick
uint32_t lastState; //key on/off last tick
uint32_t longPressDetected; //Long press
uint32_t shortPressDetected; //short press
uint32_t pressTime;
} KEY_DATA_t;
KEY_DATA_t keyData[KEY_NUM];
uint32_t key_bits;
extern uint32_t TX_TIME[];
extern uint32_t Tx_timer;
extern TIMER_t tmr;
//TESTING
static uint32_t keyPressCount = 0;
static SYSTEM_DATA_t *_sys;
/*******************************************************************************
* Static Function Declarations
******************************************************************************/
static void InitKeyData(void);
/*******************************************************************************
* Static Functions
******************************************************************************/
//Assign port and pin to each key
static void InitKeyData(void)
{
//Init keys as digital inputs, no interrupts
//Set keyData[] gpioPins
keyData[0].gpioPin = KEY0_PIN; // ON_POLL
keyData[1].gpioPin = KEY1_PIN; // SFTKY0
keyData[2].gpioPin = KEY2_PIN; // SFTKY1
keyData[3].gpioPin = KEY3_PIN; // SFTKY2
keyData[4].gpioPin = KEY4_PIN; // SFTKY3
keyData[5].gpioPin = KEY5_PIN; // SFTKY4
//Set keyData[] gpioPorts
keyData[0].gpioPort = KEY0_PORT;
keyData[1].gpioPort = KEY1_PORT;
keyData[2].gpioPort = KEY2_PORT;
keyData[3].gpioPort = KEY3_PORT;
keyData[4].gpioPort = KEY4_PORT;
keyData[5].gpioPort = KEY5_PORT;
}
/*******************************************************************************
* Public Functions
******************************************************************************/
void KEY_Init(void)
{
InitKeyData();
KEY_ClearKeyPresses();
KEY_ClearAll();
_sys = system_getSys();
}
//reset all key states and timer values
void KEY_ClearAll(void)
{
for (uint32_t i = 0; i < KEY_NUM; i++)
{
keyData[i].lastState = 0;
keyData[i].tickCount = 0;
}
}
//Clear key presses
void KEY_ClearKeyPresses(void)
{
key_bits = 0;
// key_bits &= !KEY_ALL;
}
//waits for key press returns key and clears previous keys
uint32_t KEY_WaitForKeyPress(uint32_t keyMask)
{
while(!(key_bits & keyMask));
uint32_t tempKeys = key_bits;
KEY_ClearKeyPresses();
return tempKeys;
}
/* returns 1 if a key press event is present, 0 otherwise
*
*/
bool KEY_IsKeyPressed(uint32_t keyMask)
{
return (key_bits & keyMask);
}
//return the key press event bits
uint32_t KEY_GetPressed(void)
{
uint32_t tempKeys = key_bits;
KEY_ClearKeyPresses();
return tempKeys;
}
uint8_t KEY_GetModeKeyHeld(void)
{
return !GPIO_PinRead(GPIO, keyData[1].gpioPort, keyData[1].gpioPin);
}
//Get current state of UP key
uint8_t KEY_GetUpKeyHeld(void)
{
return !GPIO_PinRead(GPIO, keyData[2].gpioPort, keyData[2].gpioPin);
}
//Get current state of DOWN key
uint8_t KEY_GetDownKeyHeld(void)
{
return !GPIO_PinRead(GPIO, keyData[3].gpioPort, keyData[3].gpioPin);
}
//Get current state of FREQUENCY key
uint8_t KEY_GetFrequencyKeyHeld(void)
{
return !GPIO_PinRead(GPIO, keyData[4].gpioPort, keyData[4].gpioPin);
}
//Get current state of DOWN key
uint8_t KEY_GetPowerKeyHeld(void)
{
return !GPIO_PinRead(GPIO, keyData[0].gpioPort, keyData[0].gpioPin);
}
#if 0
//Called from gui task
void KEY_Locate(void)
{
static uint8_t upKeyHeld = false;
static uint8_t downKeyHeld = false;
//Increase gain repeatedly if UP key held
#if 0
if(KEY_IsKeyPressed(KEY_UP | (KEY_UP << KEY_LONG_PRESS))) //UP key short or long press
{
upKeyHeld = true;
}
#endif
if(upKeyHeld)
{
if(!GPIO_PinRead(KEY_GPIO, KEY_UP_PIN)) //read the port to see if key held
{
GAIN_IncreaseGain();
}
else
{
upKeyHeld = false;
}
}
//Decrease gain repeatedly if DOWN key held
#if 0
if(KEY_IsKeyPressed(KEY_UP | (KEY_UP << KEY_LONG_PRESS))) //UP key short or long press
{
downKeyHeld = true;
}
#endif
if(downKeyHeld)
{
if(!GPIO_PinRead(KEY_GPIO, KEY_DOWN_PIN)) //read DOWN key
{
GAIN_DecreaseGain();
}
else
{
downKeyHeld = false;
}
}
uint32_t pressed = KEY_GetPressed();
switch (pressed)
//This won't work if multiple keys pressed, but it'll clear them
{
case KEY_VOLUME:
AUDIO_ChangeVolume();
break;
case KEY_MODE:
//Change Mode / Screen
break;
case KEY_UP:
GAIN_IncreaseGain();
break;
case (KEY_UP << KEY_LONG_PRESS):
upKeyHeld = true; //key held down, setup for repeated gain increases
break;
case KEY_DOWN:
GAIN_DecreaseGain();
break;
case (KEY_DOWN << KEY_LONG_PRESS):
downKeyHeld = true; //key held down, setup for repeated gain decreases
break;
case KEY_FREQ:
FREQ_ChangeFrequency();
break;
case KEY_POWER:
//Shut down
break;
case KEY_TX_CTL:
//TX Control
break;
case KEY_FA:
//Frequency Analysis
break;
case KEY_MENU:
KEY_ClearAll(); //clear all key data so it's clean for the menu
xSemaphoreGive(xSem_RunMenu); //Run the menu
xSemaphoreTake(xSem_ExitMenu, portMAX_DELAY); //Block gui task until menu done
break;
}
KEY_ClearKeyPresses();
}
#endif
//Processing for key presses
//Key# corresponds to i
//This is called at intervals of KEY_TIMER_PERIOD_MS
void KEY_Update(void)
{
for (uint32_t i = 0; i < KEY_NUM; i++)
{
//if Key is pressed
//GPIO_PinRead(GPIO_Type *base, uint32_t port, uint32_t pin)
if (!GPIO_PinRead(GPIO, keyData[i].gpioPort, keyData[i].gpioPin))
{
keyData[i].currentState = 1;
if (keyData[i].pressTime == 0)
{
keyData[i].pressTime = _sys->systemTime;
}
keyData[i].tickCount = (_sys->systemTime - keyData[i].pressTime);
if (keyData[i].tickCount >= KEY_LONG_PRESS_TICKS)
{
//Long press detected
key_bits |= ((1 << i) << KEY_LONG_PRESS);//set long press event
//Don't reset tickCount. Continue tick accumulation. when key released it won't do anything
}
Tx_timer = TX_TIME[tmr.autoShutdown]; // reload the timer
}
else //Key is NOT pressed
{
//If key was pressed last time, check for valid keypress
if (keyData[i].lastState)
{
if (keyData[i].tickCount >= KEY_SHORT_PRESS_MIN_TICKS
&& keyData[i].tickCount <= KEY_SHORT_PRESS_MAX_TICKS)
{
//Short press detected
key_bits |= ((1 << i) << KEY_SHORT_PRESS);//set short press event
}
keyData[i].tickCount = 0; //reset tick count
keyData[i].pressTime = 0;
}
}
}
//Update lastState
for (uint32_t i = 0; i < KEY_NUM; i++)
{
keyData[i].lastState = keyData[i].currentState;
}
}