/* * keys.c * * Created on: Mar 7, 2022 * Author: Brian.Bailey */ #include #include #include #include #include #include #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" /******************************************************************************* * 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 } 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 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(); } //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; keyData[i].tickCount++; 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 } } } //Update lastState for (uint32_t i = 0; i < KEY_NUM; i++) { keyData[i].lastState = keyData[i].currentState; } }