Files

283 lines
8.9 KiB
C
Raw Permalink Normal View History

2016-10-07 23:44:50 +02:00
#include "Button.h"
#include "Random.h"
#include "Common.h"
#include "Settings.h"
#include "Memory.h"
#include "Map.h"
2018-11-28 18:40:51 +01:00
#include "Configuration.h"
2017-06-15 22:11:38 +02:00
#include "Terminal/CommandLine.h"
2016-10-07 23:44:50 +02:00
#include "Application/Application.h"
#define BUTTON_PORT PORTA
#define BUTTON_L PIN5_bm
#define BUTTON_R PIN6_bm
#define BUTTON_L_PINCTRL PIN5CTRL
#define BUTTON_R_PINCTRL PIN6CTRL
#define BUTTON_MASK (BUTTON_L | BUTTON_R)
#define LONG_PRESS_TICK_COUNT 10
static const MapEntryType PROGMEM ButtonActionMap[] = {
2017-11-07 15:53:23 +01:00
{ .Id = BUTTON_ACTION_NONE, .Text = "NONE" },
{ .Id = BUTTON_ACTION_UID_RANDOM, .Text = "UID_RANDOM" },
{ .Id = BUTTON_ACTION_UID_LEFT_INCREMENT, .Text = "UID_LEFT_INCREMENT" },
{ .Id = BUTTON_ACTION_UID_RIGHT_INCREMENT, .Text = "UID_RIGHT_INCREMENT" },
{ .Id = BUTTON_ACTION_UID_LEFT_DECREMENT, .Text = "UID_LEFT_DECREMENT" },
{ .Id = BUTTON_ACTION_UID_RIGHT_DECREMENT, .Text = "UID_RIGHT_DECREMENT" },
{ .Id = BUTTON_ACTION_CYCLE_SETTINGS, .Text = "CYCLE_SETTINGS" },
{ .Id = BUTTON_ACTION_STORE_MEM, .Text = "STORE_MEM" },
{ .Id = BUTTON_ACTION_RECALL_MEM, .Text = "RECALL_MEM" },
{ .Id = BUTTON_ACTION_TOGGLE_FIELD, .Text = "TOGGLE_FIELD" },
{ .Id = BUTTON_ACTION_STORE_LOG, .Text = "STORE_LOG" },
{ .Id = BUTTON_ACTION_CLONE, .Text = "CLONE" },
2019-11-20 07:04:55 -06:00
{ .Id = BUTTON_ACTION_CLONE_MFU, .Text = "CLONE_MFU" },
2016-10-07 23:44:50 +02:00
};
2019-11-15 10:21:40 +01:00
static void ExecuteButtonAction(ButtonActionEnum ButtonAction) {
2016-10-07 23:44:50 +02:00
uint8_t UidBuffer[32];
2019-11-15 10:21:40 +01:00
switch (ButtonAction) {
case BUTTON_ACTION_UID_RANDOM: {
for (uint8_t i = 0; i < ActiveConfiguration.UidSize; i++) {
UidBuffer[i] = RandomGetByte();
}
/* If we are using an ISO15 tag, the first byte needs to be E0 by standard */
if (ActiveConfiguration.TagFamily == TAG_FAMILY_ISO15693) {
UidBuffer[0] = 0xE0;
}
ApplicationSetUid(UidBuffer);
break;
2018-11-28 18:40:51 +01:00
}
2016-10-07 23:44:50 +02:00
2019-11-15 10:21:40 +01:00
case BUTTON_ACTION_UID_LEFT_INCREMENT: {
uint8_t offset = 0;
#ifdef SUPPORT_UID7_FIX_MANUFACTURER_BYTE
2019-11-15 10:21:40 +01:00
if (ActiveConfiguration.UidSize == 7) {
offset = 1;
}
#endif
2019-11-15 10:21:40 +01:00
ApplicationGetUid(UidBuffer);
bool Carry = 1;
uint8_t i;
2016-10-07 23:44:50 +02:00
2019-11-15 10:21:40 +01:00
for (i = offset; i < ActiveConfiguration.UidSize; i++) {
if (Carry) {
if (UidBuffer[i] == 0xFF) {
Carry = 1;
} else {
Carry = 0;
}
UidBuffer[i] = (UidBuffer[i] + 1) & 0xFF;
2016-10-07 23:44:50 +02:00
}
}
2019-11-15 10:21:40 +01:00
ApplicationSetUid(UidBuffer);
break;
2016-10-07 23:44:50 +02:00
}
2019-11-15 10:21:40 +01:00
case BUTTON_ACTION_UID_RIGHT_INCREMENT: {
ApplicationGetUid(UidBuffer);
bool Carry = 1;
uint8_t i = ActiveConfiguration.UidSize;
2016-10-07 23:44:50 +02:00
2019-11-15 10:21:40 +01:00
while (i-- > 0) {
if (Carry) {
if (UidBuffer[i] == 0xFF) {
Carry = 1;
} else {
Carry = 0;
}
2016-10-07 23:44:50 +02:00
2019-11-15 10:21:40 +01:00
UidBuffer[i] = (UidBuffer[i] + 1) & 0xFF;
2016-10-07 23:44:50 +02:00
}
}
2019-11-15 10:21:40 +01:00
ApplicationSetUid(UidBuffer);
break;
2016-10-07 23:44:50 +02:00
}
2019-11-15 10:21:40 +01:00
case BUTTON_ACTION_UID_LEFT_DECREMENT: {
uint8_t offset = 0;
#ifdef SUPPORT_UID7_FIX_MANUFACTURER_BYTE
2019-11-15 10:21:40 +01:00
if (ActiveConfiguration.UidSize == 7) {
offset = 1;
}
#endif
2019-11-15 10:21:40 +01:00
ApplicationGetUid(UidBuffer);
bool Carry = 1;
uint8_t i;
2016-10-07 23:44:50 +02:00
2019-11-15 10:21:40 +01:00
for (i = offset; i < ActiveConfiguration.UidSize; i++) {
if (Carry) {
if (UidBuffer[i] == 0x00) {
Carry = 1;
} else {
Carry = 0;
}
UidBuffer[i] = (UidBuffer[i] - 1) & 0xFF;
2016-10-07 23:44:50 +02:00
}
}
2019-11-15 10:21:40 +01:00
ApplicationSetUid(UidBuffer);
break;
2016-10-07 23:44:50 +02:00
}
2019-11-15 10:21:40 +01:00
case BUTTON_ACTION_UID_RIGHT_DECREMENT: {
ApplicationGetUid(UidBuffer);
bool Carry = 1;
uint8_t i = ActiveConfiguration.UidSize;
2016-10-07 23:44:50 +02:00
2019-11-15 10:21:40 +01:00
while (i-- > 0) {
if (Carry) {
if (UidBuffer[i] == 0x00) {
Carry = 1;
} else {
Carry = 0;
}
2016-10-07 23:44:50 +02:00
2019-11-15 10:21:40 +01:00
UidBuffer[i] = (UidBuffer[i] - 1) & 0xFF;
2016-10-07 23:44:50 +02:00
}
}
2019-11-15 10:21:40 +01:00
ApplicationSetUid(UidBuffer);
break;
2016-10-07 23:44:50 +02:00
}
2019-11-15 10:21:40 +01:00
case BUTTON_ACTION_CYCLE_SETTINGS: {
SettingsCycle();
break;
2017-11-07 15:53:23 +01:00
}
2016-10-07 23:44:50 +02:00
2019-11-15 10:21:40 +01:00
case BUTTON_ACTION_STORE_MEM: {
MemoryStore();
break;
}
2016-10-07 23:44:50 +02:00
2019-11-15 10:21:40 +01:00
case BUTTON_ACTION_RECALL_MEM: {
MemoryRecall();
break;
}
2016-10-07 23:44:50 +02:00
2019-11-15 10:21:40 +01:00
case BUTTON_ACTION_TOGGLE_FIELD: {
if (!CodecGetReaderField()) {
CodecReaderFieldStart();
} else {
CodecReaderFieldStop();
}
break;
}
case BUTTON_ACTION_STORE_LOG: {
LogSRAMToFRAM();
break;
}
case BUTTON_ACTION_CLONE: {
CommandExecute("CLONE");
break;
}
2019-11-20 07:04:55 -06:00
case BUTTON_ACTION_CLONE_MFU: {
2019-11-25 13:29:14 +01:00
CommandExecute("CLONE_MFU");
break;
2019-11-20 07:04:55 -06:00
}
2019-11-15 10:21:40 +01:00
default:
break;
2016-10-07 23:44:50 +02:00
}
}
2019-11-15 10:21:40 +01:00
void ButtonInit(void) {
2017-11-07 15:53:23 +01:00
BUTTON_PORT.DIRCLR = BUTTON_MASK;
BUTTON_PORT.BUTTON_R_PINCTRL = PORT_OPC_PULLUP_gc;
BUTTON_PORT.BUTTON_L_PINCTRL = PORT_OPC_PULLUP_gc;
2016-10-07 23:44:50 +02:00
}
2019-11-15 10:21:40 +01:00
void ButtonTick(void) {
2016-10-07 23:44:50 +02:00
static uint8_t ButtonRPressTick = 0;
static uint8_t ButtonLPressTick = 0;
uint8_t ThisButtonState = ~BUTTON_PORT.IN;
if (ThisButtonState & BUTTON_R) {
2017-11-07 15:53:23 +01:00
/* Button is currently pressed */
if (ButtonRPressTick < LONG_PRESS_TICK_COUNT) {
/* Count ticks while button is being pressed */
ButtonRPressTick++;
} else if (ButtonRPressTick == LONG_PRESS_TICK_COUNT) {
/* Long button press detected execute button action and advance PressTickCounter
* to an invalid state. */
ExecuteButtonAction(GlobalSettings.ActiveSettingPtr->ButtonActions[BUTTON_R_PRESS_LONG]);
ButtonRPressTick++;
} else {
/* Button is still pressed, ignore */
}
2016-10-07 23:44:50 +02:00
} else if (!(ThisButtonState & BUTTON_MASK)) {
2017-11-07 15:53:23 +01:00
/* Button is currently not being pressed. Check if PressTickCounter contains
* a recent short button press. */
2019-11-15 10:21:40 +01:00
if ((ButtonRPressTick > 0) && (ButtonRPressTick <= LONG_PRESS_TICK_COUNT)) {
2017-11-07 15:53:23 +01:00
/* We have a short button press */
ExecuteButtonAction(GlobalSettings.ActiveSettingPtr->ButtonActions[BUTTON_R_PRESS_SHORT]);
}
2016-10-07 23:44:50 +02:00
2017-11-07 15:53:23 +01:00
ButtonRPressTick = 0;
2016-10-07 23:44:50 +02:00
}
if (ThisButtonState & BUTTON_L) {
2017-11-07 15:53:23 +01:00
/* Button is currently pressed */
if (ButtonLPressTick < LONG_PRESS_TICK_COUNT) {
/* Count ticks while button is being pressed */
ButtonLPressTick++;
} else if (ButtonLPressTick == LONG_PRESS_TICK_COUNT) {
/* Long button press detected execute button action and advance PressTickCounter
* to an invalid state. */
ExecuteButtonAction(GlobalSettings.ActiveSettingPtr->ButtonActions[BUTTON_L_PRESS_LONG]);
ButtonLPressTick++;
} else {
/* Button is still pressed, ignore */
}
2016-10-07 23:44:50 +02:00
} else if (!(ThisButtonState & BUTTON_MASK)) {
2017-11-07 15:53:23 +01:00
/* Button is currently not being pressed. Check if PressTickCounter contains
* a recent short button press. */
2019-11-15 10:21:40 +01:00
if ((ButtonLPressTick > 0) && (ButtonLPressTick <= LONG_PRESS_TICK_COUNT)) {
2017-11-07 15:53:23 +01:00
/* We have a short button press */
ExecuteButtonAction(GlobalSettings.ActiveSettingPtr->ButtonActions[BUTTON_L_PRESS_SHORT]);
}
2016-10-07 23:44:50 +02:00
2017-11-07 15:53:23 +01:00
ButtonLPressTick = 0;
2016-10-07 23:44:50 +02:00
}
}
2019-11-15 10:21:40 +01:00
void ButtonGetActionList(char *List, uint16_t BufferSize) {
2017-11-07 15:53:23 +01:00
MapToString(ButtonActionMap, ARRAY_COUNT(ButtonActionMap), List, BufferSize);
2016-10-07 23:44:50 +02:00
}
2019-11-15 10:21:40 +01:00
void ButtonSetActionById(ButtonTypeEnum Type, ButtonActionEnum Action) {
2016-10-07 23:44:50 +02:00
#ifndef BUTTON_SETTING_GLOBAL
2017-11-07 15:53:23 +01:00
GlobalSettings.ActiveSettingPtr->ButtonActions[Type] = Action;
2016-10-07 23:44:50 +02:00
#else
2017-11-07 15:53:23 +01:00
/* Write button action to all settings when using global settings */
2019-11-15 10:21:40 +01:00
for (uint8_t i = 0; i < SETTINGS_COUNT; i++) {
2017-11-07 15:53:23 +01:00
GlobalSettings.Settings[i].ButtonActions[Type] = Action;
}
2016-10-07 23:44:50 +02:00
#endif
}
2019-11-15 10:21:40 +01:00
void ButtonGetActionByName(ButtonTypeEnum Type, char *Action, uint16_t BufferSize) {
2017-11-07 15:53:23 +01:00
MapIdToText(ButtonActionMap, ARRAY_COUNT(ButtonActionMap),
2019-11-15 10:21:40 +01:00
GlobalSettings.ActiveSettingPtr->ButtonActions[Type], Action, BufferSize);
2016-10-07 23:44:50 +02:00
}
2019-11-15 10:21:40 +01:00
bool ButtonSetActionByName(ButtonTypeEnum Type, const char *Action) {
2017-11-07 15:53:23 +01:00
MapIdType Id;
2016-10-07 23:44:50 +02:00
2017-11-07 15:53:23 +01:00
if (MapTextToId(ButtonActionMap, ARRAY_COUNT(ButtonActionMap), Action, &Id)) {
ButtonSetActionById(Type, Id);
return true;
} else {
return false;
}
2016-10-07 23:44:50 +02:00
}