PingPong/Core/Src/IR_CMD_Wrapper.c

168 lines
5.1 KiB
C

#include "IR_CMD_Handler.h"
#include "IR.h"
#include "SimpleTimer.h"
#include "ShiftReg.h"
#include "Print.h"
#include "Indicator.h"
#define IR_Timeout 137
#define ResetInputProgerss_Timeout 2500
#define InitialRepeatTime 100 // Начальный интервал времени между вызовами функции при удержании
#define MinRepeatTime 30 // Минимально допустимый интервал времени между вызовами функции при удержании
#define HoldTime 500 // Время, необходимое для определения удержания
#define RepeatDecay 10 // Шаг уменьшения времени между вызовами функции при удержании
#define NULL_NumberParam 0xFFFF
//extern unsigned char IR_Command;
//extern unsigned char IR_Address;
extern unsigned char IRStatus;
IRData data;
IRData old_data;
uint32_t IR_Timeout_timer = 0;
uint8_t dataHandled_flag = 0;
uint32_t inputInProgerss_timer = 0;
uint8_t inputInProgerss = 0;
uint8_t digitInputInProgerss = 0;
uint8_t inputDigit = 0; // left = 0 to right
uint16_t inputParam = NULL_NumberParam;
uint32_t holdStartTime = 0; // Время начала удержания
uint32_t lastRepeatTime = 0; // Последнее время повторного вызова функции
uint32_t currentRepeatTime = InitialRepeatTime; // Текущее значение интервала между вызовами функции
void IR_Home_Process();
void IR_ParamEnter();
void IR_CMD_Clear();
void (*InputHandler)(void) = IR_Home_Process;
void NullFunc(){};
void (*onParamEnter)() = NullFunc;
void (*onHoldRepeat)() = NullFunc; // Указатель на функцию, вызываемую при удержании
void paramEnter(void(*onEnter_)()){
InputHandler = IR_ParamEnter;
onParamEnter = onEnter_;
}
// Установка функции для вызова при удержании
void setHoldRepeatHandler(void (*handler)()) {
onHoldRepeat = handler;
}
void IR_CMD_Handler() {
// timeout tick
if (dataHandled_flag && (millis() - IR_Timeout_timer > IR_Timeout)) {
dataHandled_flag = 0;
}
if (inputInProgerss && (millis() - inputInProgerss_timer > ResetInputProgerss_Timeout)) {
IR_CMD_Clear();
uint8_t blinkPeriod = 25;
for (int i = 9; i <= 10; ++i) {
led_blink_num(i, blinkPeriod, 4);
}
}
// cmd handler
if (IR_Available()) {
data = getIRData();
IR_Timeout_timer = millis();
// works once per button press
if (memcmp(&data, &old_data, sizeof(IRData)) != 0 || !dataHandled_flag) {
dataHandled_flag = 1;
if (IR_Address == 0x01) {
onHoldRepeat = NullFunc;
InputHandler();
inputInProgerss = 1;
inputInProgerss_timer = millis();
holdStartTime = millis(); // Запоминаем время начала удержания
lastRepeatTime = holdStartTime; // Инициализируем таймер повторного вызова
currentRepeatTime = InitialRepeatTime; // Сбрасываем интервал повторного вызова
uint8_t blinkPeriod = 75;
led_blink_num(19, blinkPeriod, 1);
led_blink_num(18, blinkPeriod, 1);
led_blink_num(17, blinkPeriod, 1);
led_blink_num(2, blinkPeriod, 1);
led_blink_num(1, blinkPeriod, 1);
led_blink_num(0, blinkPeriod, 1);
}
memcpy(&old_data, &data, sizeof(IRData));
} else {
// Проверка на удержание кнопки
if (millis() - holdStartTime > HoldTime) { // Если кнопка удерживается дольше HoldTime
if (millis() - lastRepeatTime > currentRepeatTime) { // Если прошло достаточно времени для повторного вызова
lastRepeatTime = millis(); // Обновляем время последнего вызова
// uint8_t blinkPeriod = 10;
led_writeMirror(9, 1);
HAL_Delay(1);
led_writeMirror(9,0);
onHoldRepeat(); // Вызываем функцию при удержании
// Уменьшаем интервал до минимального значения
if (currentRepeatTime > MinRepeatTime) {
currentRepeatTime -= RepeatDecay;
if (currentRepeatTime < MinRepeatTime) {
currentRepeatTime = MinRepeatTime;
}
}
}
}
}
IR_Timeout_timer = millis();
ClearIRStatus();
}
}
void IR_CMD_Clear() {
InputHandler = IR_Home_Process;
inputDigit = 0;
inputInProgerss = 0;
digitInputInProgerss = 0;
inputParam = NULL_NumberParam;
}
void IR_ParamEnter() {
if (0 <= data.command && data.command <= 9) {
if (digitInputInProgerss) {
inputParam = inputParam * 10; // dec shift << 1
inputParam += (data.command + 1) % 10;
} else {
inputParam = (data.command + 1) % 10;
}
digitInputInProgerss = 1;
} else {
digitInputInProgerss = 0;
switch (data.command) {
case IR_ENTER:
if(inputParam != NULL_NumberParam){
print("Enter: ");
printNumber(inputParam);
onParamEnter();
}
inputParam = NULL_NumberParam;
digitInputInProgerss = 0;
break;
case IR_START:
break;
default:
IR_Home_Process();
break;
}
}
}