forked from ceres-c/ChameleonMini
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSniff15693.c
215 lines (187 loc) · 7.98 KB
/
Sniff15693.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/*
* SniffISO15693.h
*
* Created on: 05.11.2019
* Author: ceres-c
*/
#ifdef CONFIG_ISO15693_SNIFF_SUPPORT
#include "../Codec/SniffISO15693.h"
#include "Sniff15693.h"
typedef enum {
AUTOCALIB_INIT,
AUTOCALIB_READER_DATA,
AUTOCALIB_CARD_DATA,
} Sniff15693State;
Sniff15693Command Sniff15693CurrentCommand;
static Sniff15693State autocalib_state = AUTOCALIB_INIT;
static bool disable_autothreshold = true;
/* The Autocalib shall work as following: */
/* Calls to AppProcess shall always alternate b/w ReaderData and CardData */
/* If there are 2 successive calls to to AppProcess with ReaderData, it means */
/* we have not received card data -> bad case */
/* So, we need always two calls to AppProcess to evaluate b/w good & bad case */
/* two calls are called a cycle further on */
/* we do increment the threshold after each cycle */
/* We store the first successfull card data as min_succ_th (means the threshold when we have received */
/* card data the first time */
/* And now we increment the threshold further, until we dont get card data anymore */
/* This will be stored in 'max_succ_th */
/* We do assume now, that the optimal threshold is between min_succ_th and max_succ_th */
/* With this approach we do avoid, to maintain a large array of possible thresholds */
/* The serach range is defined by the DemodFloorNoiseLevel */
/* We search b/w: */
/* 0.5 * DemodFloorNoiseLevel --> 1.5 * DemodFloorNoiseLevel */
/*
_________________________ scanning range ______________________________________
/ \
-|---------|-----------------------------------------threshold-----------------------------|------------>
| |
typical pattern| |
- bad case |------------------------+-++++-+-+---------------------------------------------|
+ good case | | | |
| min_succ_th | |
| max_succ_th |
min_th max_th
And finally the desired threshold is: (min_succ_th + max_succ_th) >> 1
*/
static uint16_t min_th = 0;
static uint16_t max_th = 0xFFF;
static uint16_t min_succ_th = 0;
static uint16_t max_succ_th = 0xFFF;
static bool last_cycle_successful = false;
void SniffISO15693AppTimeout(void)
{
SniffISO15693AppReset();
}
void SniffISO15693AppInit(void)
{
Sniff15693CurrentCommand = Sniff15693_Do_Nothing;
autocalib_state = AUTOCALIB_INIT;
if(disable_autothreshold)
SniffISO15693CtrlAutoThreshold(false);
}
void SniffISO15693AppReset(void)
{
SniffISO15693AppInit();
}
void SniffISO15693AppTask(void)
{
}
void SniffISO15693AppTick(void)
{
}
INLINE SniffISO15693InitAutocalib(void){
uint16_t floor_noise = SniffISO15693GetFloorNoise();
char str[64];
/* We search b/w: */
/* 0.5 * DemodFloorNoiseLevel --> 1.5 * DemodFloorNoiseLevel */
min_th = floor_noise >> 1;
max_th = floor_noise + (floor_noise >> 1);
if(min_th >= max_th) {
min_th = 0;
max_th = 0xFFF;
}
min_succ_th = 0;
max_succ_th = 0xFFF;
last_cycle_successful = false;
sprintf(str, "Sniff15693: Start Autocalibration %d - %d ", min_th, max_th);
LogEntry(LOG_INFO_GENERIC, str, strlen(str));
SniffISO15693CtrlAutoThreshold(false);
CodecThresholdSet(min_th);
return;
}
INLINE SniffISO15693FinishAutocalib(void){
uint16_t new_th;
char str[64];
new_th = (min_succ_th + max_succ_th) >> 1;
CodecThresholdSet(new_th);
sprintf(str, "Sniff15693: Finished Autocalibration %d - %d --> % d", min_succ_th, max_succ_th, new_th);
LogEntry(LOG_INFO_GENERIC, str, strlen(str));
SniffISO15693AppInit();
CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, NULL);
//CommandLinePendingTaskFinished(COMMAND_INFO_FALSE_ID, NULL);
}
INLINE SniffISO15693IncrementThreshold(void){
uint16_t th;
char str[64];
int i;
/* So increment the threshold */
/* Steps of 3*16=48 are sufficient for us */
for (i=0;i<3;i++)
th = CodecThresholdIncrement();
sprintf(str, "Sniff15693: Try next th=%d", th);
LogEntry(LOG_INFO_GENERIC, str, strlen(str));
if(th >= max_th) {
/* We are finished now */
/* Evaluate the results */
SniffISO15693FinishAutocalib();
}
}
uint16_t SniffISO15693AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes)
{
char str[64];
switch (Sniff15693CurrentCommand) {
case Sniff15693_Do_Nothing: {
return 0;
}
case Sniff15693_Autocalibrate: {
switch(autocalib_state){
case(AUTOCALIB_INIT):
SniffISO15693InitAutocalib();
if(TrafficSource == TRAFFIC_CARD)
autocalib_state = AUTOCALIB_CARD_DATA;
else
autocalib_state = AUTOCALIB_READER_DATA;
break;
case(AUTOCALIB_READER_DATA): /* Means last time we have received reader data */
if(TrafficSource == TRAFFIC_READER){
/* Second time Reader Data received */
/* This means no card data received */
/* If we had successful tries before */
/* we need to record it as threshold max here */
if(last_cycle_successful == true){
max_succ_th = GlobalSettings.ActiveSettingPtr->ReaderThreshold -
CODEC_THRESHOLD_CALIBRATE_STEPS;
sprintf(str, "Sniff15693: Updated max_succ_th (%d) ", max_succ_th);
LogEntry(LOG_INFO_GENERIC, str, strlen(str));
}
last_cycle_successful = false;
}else{
/* We have received card data now */
/* Threshold is in a good range */
/* if min_succ_th was never set ( == 0) */
/* Set it now to the current threshold */
if (min_succ_th == 0)
min_succ_th = GlobalSettings.ActiveSettingPtr->ReaderThreshold;
last_cycle_successful = true;
sprintf(str, "Sniff15693: Found card data (%d) ", min_succ_th);
LogEntry(LOG_INFO_GENERIC, str, strlen(str));
autocalib_state = AUTOCALIB_CARD_DATA;
}
SniffISO15693IncrementThreshold();
break;
case(AUTOCALIB_CARD_DATA): /* Means last time we have received card data */
if(TrafficSource == TRAFFIC_CARD){
/* We have received card data now */
/* Threshold is in a good range */
/* if min_succ_th was never set ( == 0) */
/* Set it now to the current threshold */
if (min_succ_th == 0)
min_succ_th = GlobalSettings.ActiveSettingPtr->ReaderThreshold;
last_cycle_successful = true;
sprintf(str, "Sniff15693: Found card data (%d) ", min_succ_th);
LogEntry(LOG_INFO_GENERIC, str, strlen(str));
SniffISO15693IncrementThreshold();
}else{
autocalib_state = AUTOCALIB_READER_DATA;
}
break;
default:
break;
}
return 0;
}
}
return 0;
}
#endif /* CONFIG_ISO15693_SNIFF_SUPPORT */