added autocalibrate command

This commit is contained in:
Georg
2017-07-12 10:52:05 +02:00
parent b6e920b984
commit c764e52bdc
7 changed files with 140 additions and 11 deletions
@@ -101,9 +101,6 @@ static uint8_t CardCandidatesIdx = 0;
uint16_t addParityBits(uint8_t * Buffer, uint16_t BitCount)
{
uint8_t i = CardIdentificationList[0].ATQA;
if (i == 0)
return 0;
if (BitCount == 7)
return 7;
if (BitCount % 8)
@@ -473,6 +470,87 @@ uint16_t Reader14443AAppProcess(uint8_t* Buffer, uint16_t BitCount)
return rVal;
}
case Reader14443_Autocalibrate:
{
static enum {
RT_STATE_IDLE,
RT_STATE_SEARCHING
} RTState = RT_STATE_IDLE;
static uint8_t ErrorCount = 0;
static uint8_t Thresholds[(CODEC_THRESHOLD_CALIBRATE_MAX - CODEC_THRESHOLD_CALIBRATE_MIN) / CODEC_THRESHOLD_CALIBRATE_STEPS] = {0}; // todo this could be improved by using the bits and not the whole bytes
if (RTState == RT_STATE_IDLE)
{
CodecThresholdSet(CODEC_THRESHOLD_CALIBRATE_MIN);
RTState = RT_STATE_SEARCHING;
ErrorCount = 0;
} else if (RTState == RT_STATE_SEARCHING && ReaderState <= STATE_HALT && ErrorCount++ == 8) {
if (CodecThresholdIncrement() >= CODEC_THRESHOLD_CALIBRATE_MAX)
{
RTState = RT_STATE_IDLE;
bool block = false;
uint16_t min = 0;
uint16_t max = 0;
uint16_t maxdiff = 0;
uint16_t maxdiffoffset = 0;
CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, NULL);
uint16_t i;
for (i = 0; i < (CODEC_THRESHOLD_CALIBRATE_MAX - CODEC_THRESHOLD_CALIBRATE_MIN) / CODEC_THRESHOLD_CALIBRATE_STEPS; i++)
{
char tmpBuf[10];
snprintf(tmpBuf, 10, "%4" PRIu16 ": ", i*CODEC_THRESHOLD_CALIBRATE_STEPS + CODEC_THRESHOLD_CALIBRATE_MIN);
TerminalSendString(tmpBuf);
if (Thresholds[i])
{
TerminalSendStringP(PSTR("+\r\n"));
if (!block)
{
block = true;
min = i;
}
} else {
TerminalSendStringP(PSTR("-\r\n"));
if (block)
{
block = false;
max = i;
if ((max - min) > maxdiff)
{
maxdiff = max - min;
maxdiffoffset = min;
}
}
}
Thresholds[i] = 0; // reset the threshold so the next run won't show old results
}
CodecThresholdSet((maxdiffoffset + maxdiff / 2) * CODEC_THRESHOLD_CALIBRATE_STEPS + CODEC_THRESHOLD_CALIBRATE_MIN);
Selected = false;
Reader14443CurrentCommand = Reader14443_Do_Nothing;
CodecReaderFieldStop();
return 0;
}
Thresholds[(ReaderThreshold - CODEC_THRESHOLD_CALIBRATE_MIN) / CODEC_THRESHOLD_CALIBRATE_STEPS] = 0;
CodecThresholdIncrement();
ErrorCount = 0;
}
uint16_t rVal = Reader14443A_Select(Buffer, BitCount);
if (Selected) // we are done finding the threshold
{
Thresholds[(ReaderThreshold - CODEC_THRESHOLD_CALIBRATE_MIN) / CODEC_THRESHOLD_CALIBRATE_STEPS] = 1;
CodecThresholdIncrement();
ReaderState = STATE_IDLE;
Reader14443ACodecStart();
return Reader14443A_Halt(Buffer);
}
return rVal;
}
case Reader14443_Read_MF_Ultralight:
{
static uint8_t MFURead_CurrentAdress = 0;
@@ -714,14 +792,14 @@ uint16_t Reader14443AAppProcess(uint8_t* Buffer, uint16_t BitCount)
tmpBuf[size-3] = '\0';
CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, tmpBuf);
if (!enoughspace)
TerminalSendString("There is at least one more card type candidate, but there was not enough terminal buffer space.\r\n");
TerminalSendStringP(PSTR("There is at least one more card type candidate, but there was not enough terminal buffer space.\r\n"));
}
// print general data
TerminalSendString("ATQA:\t");
TerminalSendStringP(PSTR("ATQA:\t"));
CommandLineAppendData(&CardCharacteristics.ATQA, 2);
TerminalSendString("UID:\t");
TerminalSendStringP(PSTR("UID:\t"));
CommandLineAppendData(CardCharacteristics.UID, CardCharacteristics.UIDSize);
TerminalSendString("SAK:\t");
TerminalSendStringP(PSTR("SAK:\t"));
CommandLineAppendData(&CardCharacteristics.SAK, 1);
Reader14443CurrentCommand = Reader14443_Do_Nothing;
@@ -28,6 +28,7 @@ typedef enum {
Reader14443_Send,
Reader14443_Send_Raw,
Reader14443_Get_UID,
Reader14443_Autocalibrate,
Reader14443_Read_MF_Ultralight,
Reader14443_Identify
} Reader14443Command;
+19
View File
@@ -82,3 +82,22 @@ bool CodecIsReaderToBeRestarted(void)
return false;
}
void CodecThresholdSet(uint16_t th)
{
ReaderThreshold = th;
DACB.CH0DATA = th;
}
uint16_t CodecThresholdIncrement(void)
{
ReaderThreshold += CODEC_THRESHOLD_CALIBRATE_STEPS;
DACB.CH0DATA = ReaderThreshold;
return ReaderThreshold;
}
void CodecThresholdReset(void)
{
ReaderThreshold = 400;
DACB.CH0DATA = ReaderThreshold;
}
+7
View File
@@ -73,6 +73,9 @@
#define CODEC_READER_PINCTRL_RIGHT PIN1CTRL
#define CODEC_AC_DEMOD_SETTINGS AC_HSMODE_bm | AC_HYSMODE_NO_gc
#define CODEC_MAXIMUM_THRESHOLD 0xFFF // the maximum voltage can be calculated with ch0data * Vref / 0xFFF
#define CODEC_THRESHOLD_CALIBRATE_MIN 128
#define CODEC_THRESHOLD_CALIBRATE_MAX 1024
#define CODEC_THRESHOLD_CALIBRATE_STEPS 8
#define CODEC_TIMER_TIMESTAMPS TCD1
#define CODEC_TIMER_TIMESTAMPS_CCA_VECT TCD1_CCA_vect
@@ -251,4 +254,8 @@ bool CodecIsReaderFieldReady(void);
void CodecReaderFieldRestart(uint16_t delay);
#define FIELD_RESTART() CodecReaderFieldRestart(100)
bool CodecIsReaderToBeRestarted(void);
void CodecThresholdSet(uint16_t th);
uint16_t CodecThresholdIncrement(void);
void CodecThresholdReset(void);
#endif /* CODEC_H_ */
+11 -4
View File
@@ -296,11 +296,18 @@ const PROGMEM CommandEntryType CommandTable[] = {
.GetFunc = CommandGetThreshold
},
{
.Command = COMMAND_FIELD,
.ExecFunc = NO_FUNCTION,
.Command = COMMAND_AUTOCALIBRATE,
.ExecFunc = CommandExecAutocalibrate,
.ExecParamFunc = NO_FUNCTION,
.SetFunc = CommandSetField,
.GetFunc = CommandGetField
.SetFunc = NO_FUNCTION,
.GetFunc = NO_FUNCTION
},
{
.Command = COMMAND_FIELD,
.ExecFunc = NO_FUNCTION,
.ExecParamFunc = NO_FUNCTION,
.SetFunc = CommandSetField,
.GetFunc = CommandGetField
},
{ /* This has to be last element */
.Command = COMMAND_LIST_END,
@@ -624,3 +624,17 @@ CommandStatusIdType CommandGetField(char* OutMessage)
OutMessage[1] = '\0';
return COMMAND_INFO_OK_WITH_TEXT_ID;
}
CommandStatusIdType CommandExecAutocalibrate(char* OutMessage)
{
if (GlobalSettings.ActiveSettingPtr->Configuration != CONFIG_ISO14443A_READER)
return COMMAND_ERR_INVALID_USAGE_ID;
ApplicationReset();
Reader14443CurrentCommand = Reader14443_Autocalibrate;
Reader14443AAppInit();
Reader14443ACodecStart();
CommandLinePendingTaskTimeout = &Reader14443AAppTimeout;
return TIMEOUT_COMMAND;
}
@@ -177,6 +177,9 @@ CommandStatusIdType CommandSetTimeout(char* OutMessage, const char* InParam);
CommandStatusIdType CommandGetThreshold(char* OutParam);
CommandStatusIdType CommandSetThreshold(char* OutMessage, const char* InParam);
#define COMMAND_AUTOCALIBRATE "AUTOCALIBRATE"
CommandStatusIdType CommandExecAutocalibrate(char* OutMessage);
#define COMMAND_FIELD "FIELD"
CommandStatusIdType CommandSetField(char* OutMessage, const char* InParam);
CommandStatusIdType CommandGetField(char* OutMessage);