/**
* @file KEY_ATY.c
*
* @param Project DEVICE_GENERAL_ATY_LIB
*
* @author ATY
*
* @copyright
* - Copyright 2017 - 2026 MZ-ATY
* - This code follows:
* - MZ-ATY Various Contents Joint Statement -
*
* https://mengze.top/MZ-ATY_VCJS
* - CC 4.0 BY-NC-SA -
*
* https://creativecommons.org/licenses/by-nc-sa/4.0/
* - Your use will be deemed to have accepted the terms of this statement.
*
* @brief functions of keys for C platform (Dev-style)
*
* @version
* - 1_01_251112 > ATY
* -# Refactor to Dev-style; remove legacy global interfaces
********************************************************************************
*/
#ifndef __KEY_ATY_C
#define __KEY_ATY_C
#include "KEY_ATY.h"
static inline uint16_t _margin_12_10(uint16_t v) { return (uint16_t)(v + v/5); }
uint8_t KEY_ATY_InitDev(struct KEY_ATY_Dev* dev, uint8_t key_count)
{
if (!dev) return 1;
if (key_count > KEY_ATY_MAX_KEYS) return 2;
dev->key_count = key_count;
if (dev->release_debounce_time == 0) dev->release_debounce_time = 20;
if (dev->press_debounce_time == 0) dev->press_debounce_time = 100;
if (dev->long_time == 0) dev->long_time = 800;
if (dev->vlong_time == 0) dev->vlong_time = dev->long_time * 3;
if (dev->ad_threshold == 0) dev->ad_threshold = 800;
for (uint8_t i = 0; i < KEY_ATY_MAX_KEYS; ++i) {
dev->lastKeyType[i] = 0;
dev->keyExportType[i] = 0;
dev->keyScanCount[i] = 0;
dev->keyReleaseCount[i]= 0;
}
if (dev->debugEnable == 1 && dev->LOG) dev->LOG("\r\nKEY_ATY init done.");
return 0;
}
static void _key_process_release(struct KEY_ATY_Dev* dev, uint8_t idx)
{
if (dev->keyReleaseCount[idx] > dev->release_debounce_time) {
if (dev->keyScanCount[idx] >= dev->press_debounce_time && dev->keyScanCount[idx] < dev->long_time) {
dev->keyExportType[idx] = KEY_TYPE_SINGLE;
dev->keyScanCount[idx] = 0;
dev->keyReleaseCount[idx] = 0;
} else {
if (dev->lastKeyType[idx] == KEY_TYPE_ACCESS_NEW) dev->lastKeyType[idx] = 0;
dev->keyExportType[idx] = KEY_TYPE_RELASE;
dev->keyScanCount[idx] = 0;
}
}
if (dev->keyReleaseCount[idx] < dev->release_debounce_time * 2) dev->keyReleaseCount[idx]++;
}
static void _key_process_press(struct KEY_ATY_Dev* dev, uint8_t idx)
{
if (dev->keyScanCount[idx] < _margin_12_10(dev->vlong_time)) dev->keyScanCount[idx]++;
if (dev->keyScanCount[idx] >= dev->long_time && dev->keyScanCount[idx] < dev->vlong_time) {
dev->keyExportType[idx] = KEY_TYPE_LONG;
} else if (dev->keyScanCount[idx] >= dev->vlong_time) {
dev->keyExportType[idx] = KEY_TYPE_VLONG;
}
}
static void _key_post_update(struct KEY_ATY_Dev* dev, uint8_t idx)
{
if (dev->keyExportType[idx] != KEY_TYPE_RELASE && dev->lastKeyType[idx] == 0) {
dev->lastKeyType[idx] = dev->keyExportType[idx];
}
}
void KEY_ATY_ScanDigitalDev(struct KEY_ATY_Dev* dev, uint8_t keyIndex)
{
__ATY_LOCK(dev);
if (!dev || !dev->readDigital || keyIndex >= dev->key_count) { __ATY_UNLOCK(dev); return; }
uint8_t pressed = dev->readDigital(keyIndex);
if (!pressed) { _key_process_release(dev, keyIndex); }
else { _key_process_press(dev, keyIndex); }
_key_post_update(dev, keyIndex);
__ATY_UNLOCK(dev);
}
float KEY_ATY_ScanAnalogDev(struct KEY_ATY_Dev* dev, uint8_t keyIndex)
{
__ATY_LOCK(dev);
if (!dev || !dev->readAnalog || keyIndex >= dev->key_count) { __ATY_UNLOCK(dev); return 0.0f; }
float val = dev->readAnalog(keyIndex);
if (val < dev->ad_threshold) { _key_process_release(dev, keyIndex); }
else { _key_process_press(dev, keyIndex); }
_key_post_update(dev, keyIndex);
__ATY_UNLOCK(dev);
return val;
}
uint8_t KEY_ATY_GetTypeDev(struct KEY_ATY_Dev* dev, uint8_t keyIndex)
{
if (!dev || keyIndex >= dev->key_count) return KEY_TYPE_RELASE;
return dev->lastKeyType[keyIndex];
}
void KEY_ATY_AccessNewDev(struct KEY_ATY_Dev* dev, uint8_t keyIndex)
{
if (!dev || keyIndex >= dev->key_count) return;
if (dev->lastKeyType[keyIndex] != KEY_TYPE_RELASE) dev->lastKeyType[keyIndex] = KEY_TYPE_ACCESS_NEW;
}
#endif /* __KEY_ATY_C */
/******************************** End Of File *********************************/