as3993 ST25RU3993 Firmware
appl_commands.c
Go to the documentation of this file.
1 /*
2  *****************************************************************************
3  * AS3993/ST25RU3993 Firmware tech@eleckits.com http://iot.eleckits.com *
4  * STMicroelectronics ST25RU3993 is an EPC Class 1 Gen 2 RFID reader IC *
5  * *
6  * IMPORTANT - PLEASE READ CAREFULLY BEFORE COPYING, INSTALLING OR USING *
7  * THE SOFTWARE. *
8  * *
9  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
10  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
11  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
12  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT *
13  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *
14  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
15  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
16  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *
17  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
18  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE *
19  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
20  *****************************************************************************
21  */
22 
45 /*
46  ******************************************************************************
47  * INCLUDES
48  ******************************************************************************
49  */
50 #include "as3993_config.h"
51 #include "platform.h"
52 #include "global.h"
53 #include "gen2.h"
54 #include "as3993_public.h"
55 #include "appl_commands.h"
56 #include "logger.h"
57 #include "errno.h"
58 #include "iso6b.h"
59 #include "timer.h"
60 #include "string.h"
61 #include <limits.h>
62 #include "as3993.h"
63 #include "tuner.h"
64 
65 /*
66  ******************************************************************************
67  * DEFINES
68  ******************************************************************************
69  */
71 #define APPLDEBUG 0
72 
74 #define SESSION_GEN2 1
75 
76 #define SESSION_ISO6B 2
77 
79 #define MAX_SELECTS 2
80 
82 #define POWER_DOWN 0
83 
84 #define POWER_NORMAL 1
85 
86 #define POWER_NORMAL_RF 2
87 
88 #define POWER_STANDBY 3
89 
90 #if APPLDEBUG && (USE_LOGGER == LOGGER_ON)
91 #define APPLOG dbgLog
92 #define APPLOGDUMP dbgHexDump
93 #else
94 #define APPLOG(...)
95 #define APPLOGDUMP(...)
96 #endif
97 
98 /*
99  ******************************************************************************
100  * LOCAL TYPES
101  ******************************************************************************
102  */
105 struct CmdBuffer{
106  const u8 *rxData;
107  u16 rxSize;
108  u8 *txData;
109  u16 txSize;
110  s8 result;
111 };
112 
113 /*
114  ******************************************************************************
115  * LOCAL VARIABLES
116  ******************************************************************************
117  */
118 #if RUN_ON_AS3980
119 
120 static struct gen2Config gen2Configuration = {TARI_25, GEN2_LF_40, GEN2_COD_MILLER8, TREXT_ON, 0, GEN2_SESSION_S0, 0};
122 u8 gen2qbegin = 0;
123 #else
124 
125 #if FEMTO2 || FEMTO2_1 || RADON || (NEWTON && !RUN_ON_AS3980 )
126 
127 static struct gen2Config gen2Configuration = {TARI_25, GEN2_LF_256, GEN2_COD_MILLER4, TREXT_OFF, 0, GEN2_SESSION_S0, 0};
129 u8 gen2qbegin = 4;
130 #else
131 
132 static struct gen2Config gen2Configuration = {TARI_125, GEN2_LF_256, GEN2_COD_MILLER4, TREXT_OFF, 0, GEN2_SESSION_S0, 0};
134 u8 gen2qbegin = 4;
135 #endif
136 
137 #endif
138 
140 static u16 inventoryDelay = 0;
142 static u16 scanTuningInterval = 500;
143 #ifdef TUNER
144 
145 static u16 tuningCounter = 0;
146 #endif
147 
148 static u8 scanRetuningLevel = 30;
150 static int num_selects;
152 static struct gen2SelectParams selParams[MAX_SELECTS];
153 
155 static u8 num_of_tags;
158 
161 
165 
168 
172 static u8 guiActiveProfile = 1;
174 static u8 guiNumFreqs=4;
176 static u32 guiMinFreq = 865700;
178 static u32 guiMaxFreq = 867500;
181 static s8 rssiThreshold;
184 static u16 idleTime = 0;
187 static u16 maxSendingTime = 10000;
190 static u16 listeningTime = 1;
192 static u16 maxSendingLimit;
196 static u8 cyclicInventory;
200 static u8 autoAckMode;
204 static u8 fastInventory;
206 static BOOL adaptiveQ = 0;
208 static u8 adjustmentRounds = 2;
210 static u8 adjustmentUpThreshold = 25;
212 static u8 adjustmentDownThreshold = 13;
220 static u8 rssiMode;
225 static s8 inventoryResult;
226 
227 #ifdef ANTENNA_SWITCH
228 
229 #if RADON || FEMTO2 || FEMTO2_1 || NEWTON
230 static u8 usedAntenna = 2;
231 #else
232 static u8 usedAntenna = 1;
233 #endif
234 #endif
235 #ifdef TUNER
236 
240 static TuningTable tuningTable __attribute__((far));
242 static TunerParameters tunerParams __attribute__((far)) = {15, 15, 15} ;
243 #if RADON
244 static TunerParameters tunerAnt1Params __attribute__((far)) = {15, 15, 15};
245 #endif
246 #endif
247 
250 static struct CmdBuffer cmdBuffer;
252 static u16 currentFreqIdx;
254 static u8 currentSession = 0; // start with invalid session (neither Gen2 nor ISO 6b)
255 
256 void configTxRx(void);
257 void readerConfig(void);
258 void antennaPower(void);
259 void antennaTuner(void);
260 void autoTuner(void);
261 void tunerTable(void);
262 u8 inventoryGen2(void);
263 s8 gen2ReadTID(Tag* tag);
264 void wrongCommand(void);
265 void initCommands(void);
266 
267 void selectTag(void);
268 void writeToTag(void);
269 void readFromTag(void);
270 void executeGenericCommand(void);
271 void executeRSSICMD(void);
272 void lockUnlockTag(void);
273 static void hopChannelRelease(void);
274 static s8 hopFrequencies(void);
275 static void powerDownReader(void);
276 static void powerUpReader(void);
277 #if RUN_ON_AS3993
278 static void adaptSlotCounter(int num_of_tags );
279 #endif
280 #ifdef TUNER
281 static void applyTunerSettingForFreq(u32 freq);
282 #endif
283 
289 static BOOL continueCheckTimeout( )
290 {
291  if (maxSendingLimit == 0) return 1;
292  if ( slowTimerValue() >= maxSendingLimit )
293  {
294  APPLOG("allocation timeout\n");
295  slowTimerStop();
297  return 0;
298  }
299  return 1;
300 }
301 
304 //static BOOL continueAlways(void)
305 //{
306 // return 1;
307 //}
308 
311 static void checkAndSetSession( u8 newSession)
312 {
313  if (currentSession == newSession) return;
314  switch (currentSession)
315  {
316  case SESSION_GEN2:
317  gen2Close();
318  break;
319  case SESSION_ISO6B:
320 #if ISO6B
321  iso6bClose();
322 #endif
323  break;
324  }
325  switch (newSession)
326  {
327  case SESSION_GEN2:
329  break;
330  case SESSION_ISO6B:
331 #if ISO6B
332  iso6bOpen();
333 #endif
334  break;
335  }
336  currentSession = newSession;
337 }
338 
344 {
345  wrongCommand();
346 }
347 
348 void wrongCommand(void)
349 {
350 
351  APPLOG("WRONG COMMAND\n");
352  cmdBuffer.result = ERR_REQUEST;
353 }
354 
355 void performSelects()
356 {
357  int i;
358  for (i = 0; i<num_selects; i++)
359  {
360  gen2Select(selParams + i);
361  /* We would have to wait T4=2*RTcal here (max 140us). Logic analyzer showed enough time without delaying */
362  }
363 }
364 
365 #define POWER_AND_SELECT_TAG() do{ status = hopFrequencies(); if (status) goto exit; powerAndSelectTag(); if(num_of_tags==0){status=GEN2_ERR_SELECT;goto exit;}}while(0)
366 
367 static int powerAndSelectTag( void )
368 {
369  performSelects();
370 #if RUN_ON_AS3993
371  num_of_tags = gen2SearchForTagsAutoAck(tags_+1, 1, 0, continueCheckTimeout, 1, 0, NULL);
372 #else
373  num_of_tags = gen2SearchForTags(tags_+1, 1, 0, 0, 0, 0, continueCheckTimeout, 1, 0, NULL);
374 #endif
375  if (num_of_tags == 0)
376  {
377  APPLOG("Could not select tag\n");
378  }
379  else
380  {
381  selectedTag = tags_+1;
382  }
383  return num_of_tags;
384 }
385 
386 
403 {
404  antennaPower();
405 }
406 
407 void antennaPower(void)
408 {
409  switch (cmdBuffer.rxData[0])
410  {
411  case ANT_POWER_OFF:
412  APPLOG("ANTENNA OFF\n");
413  powerUpReader();
415  powerDownReader();
416  cmdBuffer.result = ERR_NONE;
417  break;
418  case ANT_POWER_ON:
419  APPLOG("ANTENNA ON\n");
420  powerUpReader();
422  cmdBuffer.result = ERR_NONE;
423  break;
424  default:
425  APPLOG("ANTENNA ERROR\n");
426  cmdBuffer.result = ERR_PARAM;
427  break;
428  }
429  cmdBuffer.txData[0] = 0;
430  cmdBuffer.txSize = CMD_ANTENNA_POWER_REPLY_SIZE;
431 }
432 
502 {
503  antennaTuner();
504 }
505 
506 extern TunerConfiguration mainTuner;
507 #if RADON
508 extern TunerConfiguration ant1Tuner;
509 #endif
510 void antennaTuner(void)
511 {
512  APPLOG("antennaTuner\n");
513  APPLOGDUMP(cmdBuffer.rxData, cmdBuffer.rxSize);
514  memset(cmdBuffer.txData, 0, CMD_ANTENNA_TUNER_REPLY_SIZE);
515 
516 #ifdef TUNER
517  if (cmdBuffer.rxData[0] && mainTuner.cinSenFn)
518  {
519  tunerParams.cin = cmdBuffer.rxData[1];
520  if (tunerParams.cin > 31)
521  tunerParams.cin = 31;
522  tunerSetCap(&mainTuner, TUNER_CIN, tunerParams.cin);
523  }
524  if (cmdBuffer.rxData[2] && mainTuner.clenSenFn)
525  {
526  tunerParams.clen = cmdBuffer.rxData[3];
527  if (tunerParams.clen > 31)
528  tunerParams.clen = 31;
529  tunerSetCap(&mainTuner, TUNER_CLEN, tunerParams.clen);
530  }
531  if (cmdBuffer.rxData[4] && mainTuner.coutSenFn)
532  {
533  tunerParams.cout = cmdBuffer.rxData[5];
534  if (tunerParams.cout > 31)
535  tunerParams.cout = 31;
536  tunerSetCap(&mainTuner, TUNER_COUT, tunerParams.cout);
537  }
538  APPLOG("receive main tuner parameters cin= %hhx, clen= %hhx cout=%hhx\n", tunerParams.cin, tunerParams.clen, tunerParams.cout);
539 #if RADON
540  if (cmdBuffer.rxData[6] && ant1Tuner.cinSenFn)
541  {
542  tunerAnt1Params.cin = cmdBuffer.rxData[7];
543  if (tunerAnt1Params.cin > 31)
544  tunerAnt1Params.cin = 31;
545  tunerSetCap(&ant1Tuner, TUNER_CIN, tunerAnt1Params.cin);
546  }
547  if (cmdBuffer.rxData[8] && ant1Tuner.clenSenFn)
548  {
549  tunerAnt1Params.clen = cmdBuffer.rxData[9];
550  if (tunerAnt1Params.clen > 31)
551  tunerAnt1Params.clen = 31;
552  tunerSetCap(&ant1Tuner, TUNER_CLEN, tunerAnt1Params.clen);
553  }
554  if (cmdBuffer.rxData[10] && ant1Tuner.coutSenFn)
555  {
556  tunerAnt1Params.cout = cmdBuffer.rxData[11];
557  if (tunerAnt1Params.cout > 31)
558  tunerAnt1Params.cout = 31;
559  tunerSetCap(&ant1Tuner, TUNER_COUT, tunerAnt1Params.cout);
560  }
561  APPLOG("receive ant1 tuner parameters cin= %hhx, clen= %hhx cout=%hhx\n", tunerAnt1Params.cin, tunerAnt1Params.clen, tunerAnt1Params.cout);
562 #endif
563 
564  cmdBuffer.txData[0] = ERR_NONE;
565  cmdBuffer.txData[1] = tunerParams.cin;
566  cmdBuffer.txData[3] = tunerParams.clen;
567  cmdBuffer.txData[5] = tunerParams.cout;
568 #if RADON
569  cmdBuffer.txData[7] = tunerAnt1Params.cin;
570  cmdBuffer.txData[9] = tunerAnt1Params.clen;
571  cmdBuffer.txData[11]= tunerAnt1Params.cout;
572  APPLOG("send ant1 tuner parameters cin= %hhx, clen= %hhx cout=%hhx\n", tunerAnt1Params.cin, tunerAnt1Params.clen, tunerAnt1Params.cout);
573 #endif
574  cmdBuffer.txSize = CMD_ANTENNA_TUNER_REPLY_SIZE;
575  APPLOG("send main tuner parameters cin= %hhx, clen= %hhx cout=%hhx\n", tunerParams.cin, tunerParams.clen, tunerParams.cout);
576  APPLOGDUMP(cmdBuffer.txData, cmdBuffer.txSize);
577  cmdBuffer.result = ERR_NONE;
578 #else
579  cmdBuffer.txSize = CMD_ANTENNA_TUNER_REPLY_SIZE;
580  cmdBuffer.result = ERR_REQUEST;
581 #endif
582 }
583 
612 void callAutoTuner(void)
613 {
614  powerUpReader();
615  autoTuner();
616  powerDownReader();
617 }
618 
619 void autoTuner(void)
620 {
621 #ifdef TUNER
622  u8 algo = cmdBuffer.rxData[0] & 0xf;
623  u8 tuner_id = cmdBuffer.rxData[0] >> 4;
624  APPLOG("autoTuner\n");
625  APPLOGDUMP(cmdBuffer.rxData, cmdBuffer.rxSize);
626  TunerConfiguration *tuner = NULL;
627  TunerParameters *params = NULL;
628 
629  if(0 == tuner_id)
630  {
631  tuner = &mainTuner;
632  params = &tunerParams;
633  }
634 
635  if (cmdBuffer.rxData[0])
636  {
637  APPLOG("tune antenna, algorithm: %hhx, id=%hhx\n", cmdBuffer.rxData[0],tuner_id);
638  }
639 
640 #if RADON
641  if(1 == tuner_id)
642  {
643  tuner = &ant1Tuner;
644  params = &tunerAnt1Params;
645  }
646 #endif
647 
648  if (NULL != tuner)
649  {
650  switch (algo)
651  {
652  case (1): /* Simple: hill climb from current setting */
654  tunerOneHillClimb(tuner, params, 100);
656  break;
657  case (2): /* advanced: hill climb from more points */
659  tunerMultiHillClimb(tuner, params);
661  break;
662  case (3): /* try all combinations */
664  tunerTraversal(tuner, params);
666  break;
667  default:
668  break;
669  }
670  tunerSetTuning(tuner, params->cin, params->clen, params->cout);
671  }
672 
673  cmdBuffer.txSize = CMD_AUTO_TUNER_REPLY_SIZE;
674  APPLOG("send tune parameters cin= %hhx, clen= %hhx cout=%hhx\n", params->cin, params->clen, params->cout);
675  APPLOGDUMP(cmdBuffer.txData, cmdBuffer.txSize);
676  cmdBuffer.result = ERR_NONE;
677 #else
678  APPLOG("autoTuner\n");
679  APPLOGDUMP(cmdBuffer.rxData, cmdBuffer.rxSize);
680  cmdBuffer.txSize = CMD_AUTO_TUNER_REPLY_SIZE;
681  cmdBuffer.result = ERR_REQUEST;
682 #endif
683 }
684 
685 #ifdef TUNER
686 
689 static u8 addToTuningTable(void)
690 {
691  u8 idx;
692  u16 iq1 = 0, iq2 = 0;
693  u32 freq;
694  freq = 0;
695  freq += (long)cmdBuffer.rxData[1];
696  freq += ((long)cmdBuffer.rxData[2]) << 8;
697  freq += ((long)cmdBuffer.rxData[3]) << 16;
698 
699  idx = tuningTable.tableSize;
700  if (idx > MAXTUNE)
701  idx = MAXTUNE;
702  tuningTable.freq[idx] = freq;
703  tuningTable.tuneEnable[idx] = 0;
704  if (cmdBuffer.rxData[4] > 0)
705  {
706  //set antenna 1
707  tuningTable.tuneEnable[idx] += 1;
708  tuningTable.cin[0][idx] = cmdBuffer.rxData[5];
709  tuningTable.clen[0][idx] = cmdBuffer.rxData[6];
710  tuningTable.cout[0][idx] = cmdBuffer.rxData[7];
711  iq1 = (u16)cmdBuffer.rxData[8];
712  iq1 += ((u16)cmdBuffer.rxData[9]) << 8;
713  tuningTable.tunedIQ[0][idx] = iq1;
714  }
715  if (cmdBuffer.rxData[10] > 0)
716  {
717  //set antenna 2
718  tuningTable.tuneEnable[idx] += 2;
719  tuningTable.cin[1][idx] = cmdBuffer.rxData[11];
720  tuningTable.clen[1][idx] = cmdBuffer.rxData[12];
721  tuningTable.cout[1][idx] = cmdBuffer.rxData[13];
722  iq2 = (u16)cmdBuffer.rxData[14];
723  iq2 += ((u16)cmdBuffer.rxData[15]) << 8;
724  tuningTable.tunedIQ[1][idx] = iq2;
725  }
726  if (tuningTable.tuneEnable[idx] > 0) //if this tuning entry is used adjust size of table.
727  tuningTable.tableSize++;
728 
729  APPLOG("add tunetable f=%x%x, tablesize=%hhx, tune1=%hhx cin1=%hhx clen1=%hhx cout1=%hhx iq1=%hx "
730  "tune2=%hhx cin2=%hhx clen2=%hhx cout2=%hhx iq2=%hx\n", freq, tuningTable.tableSize,
731  cmdBuffer.rxData[4], cmdBuffer.rxData[5], cmdBuffer.rxData[6], cmdBuffer.rxData[7], iq1,
732  cmdBuffer.rxData[10], cmdBuffer.rxData[11], cmdBuffer.rxData[12], cmdBuffer.rxData[13], iq2);
733 
734  if (tuningTable.tableSize >= MAXTUNE)
735  {
736  tuningTable.tableSize = MAXTUNE;
737  return MAXTUNE + 1;
738  }
739  else
740  return tuningTable.tableSize;
741 }
742 #endif
743 
880 void callTunerTable(void)
881 {
882  tunerTable();
883 }
884 
885 void tunerTable(void)
886 {
887  APPLOG("tunerTable\n");
888  APPLOGDUMP(cmdBuffer.rxData, cmdBuffer.rxSize);
889  memset(cmdBuffer.txData, 0, CMD_TUNER_TABLE_REPLY_SIZE);
890 
891 #ifdef TUNER
892  cmdBuffer.result = ERR_NONE;
893  switch (cmdBuffer.rxData[0])
894  {
895  case 0x00:
896  /*retrieve tuning table size */
897  cmdBuffer.txData[0] = 0x00; //subcmd
898  cmdBuffer.txData[1] = MAXTUNE;
899  cmdBuffer.txData[2] = tuningTable.tableSize;
900  break;
901  case 0x01:
902  /*delete tuning table */
903  APPLOG("delete tuning table tablesize= %hhx\n", tuningTable.tableSize);
904  tuningTable.currentEntry = 0;
905  tuningTable.tableSize = 0;
906  cmdBuffer.txData[0] = 0x01; //subcmd
907  cmdBuffer.txData[1] = MAXTUNE;
908  break;
909  case 0x02: /* add new entry in tuning table */
910  if (cmdBuffer.rxSize < 16)
911  cmdBuffer.result = ERR_PARAM;
912  else
913  if (addToTuningTable() > MAXTUNE)
914  cmdBuffer.result = ERR_NOMEM; //maximum of tuning table reached
915  cmdBuffer.txData[0] = 0x02; //subcmd
916  cmdBuffer.txData[1] = MAXTUNE - tuningTable.tableSize;
917  break;
918  default:
919  cmdBuffer.txData[0] = 0xFF; //subcmd
920  cmdBuffer.txData[1] = MAXTUNE;
921  cmdBuffer.result = ERR_REQUEST;
922  break;
923  }
924  cmdBuffer.txSize = CMD_TUNER_TABLE_REPLY_SIZE;
925  APPLOGDUMP(cmdBuffer.txData, cmdBuffer.txSize);
926 #else
927  cmdBuffer.txSize = CMD_ANTENNA_TUNER_REPLY_SIZE;
928  cmdBuffer.result = ERR_REQUEST;
929  cmdBuffer.txData[0] = 0xFF; //subcmd
930  cmdBuffer.txData[1] = 0;
931 #endif
932 
933 }
934 
935 
996 {
997  readerConfig();
998 }
999 
1000 void readerConfig(void)
1001 {
1002  u8 result = ERR_NONE;
1003  APPLOG("readerConfig\n");
1004  APPLOGDUMP(cmdBuffer.rxData, cmdBuffer.rxSize);
1005 
1006  if (cmdBuffer.rxData[0]) // change power down configuration
1007  {
1008  if (cmdBuffer.rxData[1] > POWER_STANDBY) //invalid power down configuration
1009  {
1010  result = ERR_PARAM;
1011  }
1012  else
1013  { // before changing configuration we have to power up
1014  powerUpReader();
1015  readerPowerDownMode = cmdBuffer.rxData[1];
1016  powerDownReader();
1017  }
1018  }
1019 
1020  memset(cmdBuffer.txData, 0xFF, CMD_READER_CONFIG_REPLY_SIZE);
1021 #if RUN_ON_AS3993
1022  cmdBuffer.txData[0] = 93;
1023 #elif RUN_ON_AS3980
1024  cmdBuffer.txData[0] = 80;
1025 #else
1026  cmdBuffer.txData[0] = 0xFF; //unsupported
1027 #endif
1028 
1029  cmdBuffer.txData[1] = readerInitStatus;
1030 
1031 #ifdef INTVCO
1032  cmdBuffer.txData[2] = 0;
1033 #endif
1034 #ifdef EXTVCO
1035  cmdBuffer.txData[2] = 1;
1036 #endif
1037 
1038 #ifdef INTPA
1039  cmdBuffer.txData[3] = 0;
1040 #endif
1041 #ifdef EXTPA
1042  cmdBuffer.txData[3] = 1;
1043 #endif
1044 
1045 #ifdef BALANCEDINP
1046  cmdBuffer.txData[4] = 0;
1047 #endif
1048 #ifdef SINGLEINP
1049  cmdBuffer.txData[4] = 1;
1050 #endif
1051 
1052 #ifdef ANTENNA_SWITCH
1053  cmdBuffer.txData[5] = 1;
1054 #else
1055  cmdBuffer.txData[5] = 0;
1056 #endif
1057 
1058 #ifdef TUNER
1059  cmdBuffer.txData[6] =
1060  ((mainTuner.cinSenFn==0)?0:TUNER_CIN)|
1061  ((mainTuner.clenSenFn==0)?0:TUNER_CLEN)|
1062  ((mainTuner.coutSenFn==0)?0:TUNER_COUT)|
1063  0;
1064 #else
1065  cmdBuffer.txData[6] = 0;
1066 #endif
1067  cmdBuffer.txData[7] = readerPowerDownMode;
1068  cmdBuffer.txData[8] = HARDWARE_ID_NUM;
1069 
1070 #ifdef TUNER
1071 #if RADON
1072  cmdBuffer.txData[9] =
1073  ((ant1Tuner.cinSenFn==0)?0:TUNER_CIN)|
1074  ((ant1Tuner.clenSenFn==0)?0:TUNER_CLEN)|
1075  ((ant1Tuner.coutSenFn==0)?0:TUNER_COUT)|
1076  (2<<4)| /* Disabled for antenna 2 */
1077  0;
1078 #else
1079  cmdBuffer.txData[9] = 0;
1080 #endif
1081 #endif
1082 
1083  if (cmdBuffer.txSize > CMD_READER_CONFIG_REPLY_SIZE)
1084  cmdBuffer.txSize = CMD_READER_CONFIG_REPLY_SIZE;
1085  cmdBuffer.result = result;
1086 }
1087 
1097 u8 writeRegister(u8 addr, u8 value, u16 * txSize, u8 * txData)
1098 {
1099  APPLOG("WRITE\n");
1100  powerUpReader();
1101  if (addr < 0x80)
1102  {
1103  as3993SingleWrite(addr, value);
1104  }
1105  else
1106  {
1107  as3993SingleCommand(addr);
1108  }
1109  txData[0] = 0;
1110  *txSize = WRITE_REG_REPLY_SIZE;
1111  /* do not power down reader after writing register, as user probably wants to
1112  * see the effect of his register write. */
1113  //powerDownReader();
1114  return ERR_NONE;
1115 }
1116 
1125 u8 readRegister(u8 addr, u16 * txSize, u8 * txData)
1126 {
1127  APPLOG("READ\n");
1128  powerUpReader();
1129  txData[0] = as3993SingleRead(addr);
1130 
1131  *txSize = READ_REG_REPLY_SIZE;
1132  powerDownReader();
1133  return ERR_NONE;
1134 }
1135 
1187 void callConfigTxRx(void)
1188 {
1189  powerUpReader();
1190  configTxRx();
1191  powerDownReader();
1192 }
1193 
1194 void configTxRx()
1195 {
1196  APPLOG("configTxParams\n");
1197  APPLOGDUMP(cmdBuffer.rxData, cmdBuffer.rxSize);
1198 
1199  if (cmdBuffer.rxData[0]) as3993SetSensitivity( cmdBuffer.rxData[1] );
1200 #ifdef ANTENNA_SWITCH
1201  if (cmdBuffer.rxData[2])
1202  {
1203  usedAntenna = cmdBuffer.rxData[3];
1204  if (usedAntenna > 2) //prevent mis-configuration of antenna switch.
1205  usedAntenna = 2;
1206  else if (usedAntenna < 1)
1207  usedAntenna = 1;
1209  }
1210 #endif
1211 
1212  cmdBuffer.txSize = CMD_CONFIG_TX_RX_REPLY_SIZE;
1213 
1214  cmdBuffer.txData[1] = (u8) as3993GetSensitivity();
1215 #ifdef ANTENNA_SWITCH
1216  cmdBuffer.txData[3] = usedAntenna;
1217 #endif
1218 
1219  cmdBuffer.result = ERR_NONE;
1220 
1221 }
1222 
1223 void configGen2()
1224 {
1225  APPLOG("configGen2, len: %hx\n", cmdBuffer.rxSize);
1226  APPLOGDUMP(cmdBuffer.rxData, cmdBuffer.rxSize);
1227  if (currentSession == SESSION_GEN2) currentSession = 0;
1228 
1229  if (cmdBuffer.rxData[0]) gen2Configuration.linkFreq = cmdBuffer.rxData[1];
1230  if (cmdBuffer.rxData[2]) gen2Configuration.miller = cmdBuffer.rxData[3];
1231  if (cmdBuffer.rxData[4]) gen2Configuration.session = cmdBuffer.rxData[5];
1232  if (cmdBuffer.rxData[6]) gen2Configuration.trext = cmdBuffer.rxData[7];
1233  if (cmdBuffer.rxData[8]) gen2Configuration.tari = cmdBuffer.rxData[9];
1234  if (cmdBuffer.rxData[10]) gen2qbegin = cmdBuffer.rxData[11];
1235  if (cmdBuffer.rxData[12]) gen2Configuration.sel = cmdBuffer.rxData[13];
1236  if (cmdBuffer.rxData[14]) gen2Configuration.target = cmdBuffer.rxData[15];
1237 /*
1238  powerUpReader();
1239  gen2Configure(&gen2Configuration);
1240  powerDownReader();
1241 */
1242  memset(cmdBuffer.txData, 0, CMD_GEN2_SETTINGS_REPLY_SIZE);
1243  cmdBuffer.txSize = CMD_GEN2_SETTINGS_REPLY_SIZE;
1244  cmdBuffer.result = ERR_NONE;
1245 
1246  cmdBuffer.txData[1] = gen2Configuration.linkFreq;
1247  cmdBuffer.txData[3] = gen2Configuration.miller;
1248  cmdBuffer.txData[5] = gen2Configuration.session;
1249  cmdBuffer.txData[7] = gen2Configuration.trext;
1250  cmdBuffer.txData[9] = gen2Configuration.tari;
1251  cmdBuffer.txData[11] = gen2qbegin;
1252  cmdBuffer.txData[13] = gen2Configuration.sel;
1253  cmdBuffer.txData[15] = gen2Configuration.target;
1254  APPLOGDUMP(cmdBuffer.txData, cmdBuffer.txSize);
1255 }
1256 
1383 void callConfigGen2(void)
1384 {
1385  configGen2();
1386 }
1387 
1395 u8 readRegisters(u16 * txSize, u8 * txData)
1396 {
1397  u8 i;
1398  u8 idx = 0;
1399 
1400  APPLOG("READ registers complete\n");
1401  powerUpReader();
1402 
1403  for ( i = 0; i < 0x3f; i++)
1404  {
1405  /* register data is transmitted without gaps like in register layout of AS3993. */
1406  if (!( (i == 0x0F)
1407  || (i > 0x1D && i < 0x22)
1408  || (i > 0x22 && i < 0x29)
1409  || (i > 0x2E && i < 0x33)
1410  || (i == 0x34)))
1411  {
1412  txData[idx] = as3993SingleRead(i);
1413  idx++;
1414  }
1415  }
1416  *txSize = idx + 1; // data + command byte
1417  APPLOGDUMP(txData, *txSize);
1418  powerDownReader();
1419  return ERR_NONE;
1420 }
1421 
1422 
1423 static void initTagInfo()
1424 {
1425  u32 i;
1426  u8 *ptr;
1427 
1428  ptr = (u8*)tags_;
1429 
1430  for (i = 0; i < sizeof(tags_) ; i ++)
1431  {
1432  *ptr++ = 0;
1433  }
1434 }
1435 
1456 {
1457 #if ISO6B
1458  int i = 0;
1459  unsigned char word_data[8];
1460 
1461  memcpy(&word_data, &cmdBuffer.rxData[i+1], 8);
1462 
1463  APPLOG("call 6b Inventory\n");
1464 
1465  powerUpReader();
1466 
1468  as3993AntennaPower(1);
1469 
1470  num_of_tags = iso6bInventoryRound (tags_, MAXTAG, cmdBuffer.rxData[0], &word_data[0], cmdBuffer.rxData[9]);
1471 
1472  powerDownReader();
1473 #if RADON
1474  delay_ms(100);
1475 #endif
1476 
1477  cmdBuffer.txData[0] = num_of_tags;
1478 
1479  for(i = 1; i <= num_of_tags;i++)
1480  {
1481  memcpy(&cmdBuffer.txData[1 + (i-1)*8],tags_[i-1].epc,8); // uid length is always 4 in iso6b
1482  }
1483  cmdBuffer.result = ERR_NONE;
1484  cmdBuffer.txSize = 1+ num_of_tags * 8;
1485 
1486  APPLOGDUMP(&cmdBuffer.txData[0], cmdBuffer.txSize);
1487 #else
1488  cmdBuffer.txData[0] = 0; /* no tags */
1489  cmdBuffer.result = ERR_REQUEST;
1490  cmdBuffer.txSize = 1;
1491 #endif
1492 }
1493 
1509 {
1510 #if ISO6B
1511  s8 result;
1512  unsigned char word_data[8];
1513  unsigned char uid[8];
1514  memcpy(&uid, &cmdBuffer.rxData[0], 8);
1515 
1516  APPLOG("call 6b Read \n");
1517 
1518  powerUpReader();
1519 
1521  as3993AntennaPower(1);
1522  delay_ms(1);
1523  result = iso6bRead(&uid[0],cmdBuffer.rxData[8], &word_data[0]);
1524 
1525  as3993SingleWrite(AS3993_REG_STATUSCTRL, 0x00);
1526  powerDownReader();
1527 #if RADON
1528  delay_ms(100);
1529 #endif
1530  cmdBuffer.result = result;
1531  cmdBuffer.txSize = CMD_READ_FROM_TAG_6B_REPLY_SIZE;
1532  memcpy(&cmdBuffer.txData[0], &word_data[0], cmdBuffer.txSize);
1533 #else
1534  cmdBuffer.result = ERR_REQUEST;
1535  cmdBuffer.txSize = CMD_READ_FROM_TAG_6B_REPLY_SIZE;
1536 #endif
1537 }
1538 
1553 {
1554 #if ISO6B
1555  s8 result;
1556  unsigned char response[1];
1557  unsigned char uid[8];
1558  memcpy(&uid, &cmdBuffer.rxData[0], 8);
1559 
1560  APPLOG("call 6b Write \n");
1561 
1562  powerUpReader();
1564  as3993AntennaPower(1);
1565  delay_ms(1);
1566  result = iso6bWrite(&uid[0],cmdBuffer.rxData[8],cmdBuffer.rxData[9], &response[0]);
1567 
1568  as3993SingleWrite(AS3993_REG_STATUSCTRL, 0x00);
1569 
1570  powerDownReader();
1571 #if RADON
1572  delay_ms(100);
1573 #endif
1574  cmdBuffer.result = result;
1575  cmdBuffer.txSize = 1;
1576  memcpy(&cmdBuffer.txData[0], &response[0], cmdBuffer.txSize);
1577 
1578  APPLOGDUMP(&cmdBuffer.txData[0], cmdBuffer.txSize);
1579 #else
1580  cmdBuffer.result = ERR_REQUEST;
1581  cmdBuffer.txSize = CMD_WRITE_TO_TAG_6B_REPLY_SIZE;
1582 #endif
1583 }
1584 
1590 {
1591  u8 foundTags;
1592  if (tagDataAvailable) // wait until all tag data has been sent before starting next inventory round
1593  {
1594  return;
1595  }
1596  foundTags = inventoryGen2();
1597  tagDataAvailable = 1;
1598  APPLOG("inventory Gen2, found tags: %hhx\n", foundTags);
1599 }
1600 
1668 {
1669  autoAckMode = cmdBuffer.rxData[0];
1670  fastInventory = cmdBuffer.rxData[1] & 0x01;
1671  readTIDinInventoryRound = (cmdBuffer.rxData[1] & 0x02) >> 1;
1672  rssiMode = cmdBuffer.rxData[2];
1674  cmdBuffer.result = ERR_NONE;
1675 }
1676 
1677 u8 inventoryGen2(void)
1678 {
1679  s8 result;
1680  s8 (*followTagCommand)(Tag *tag) = NULL;
1681 
1682 
1683  num_of_tags = 0;
1684  APPLOG("INVENTORY Gen2 , autoAck: %hhx, fast: %hhx, rssi: %hhx\n", autoAckMode, fastInventory, rssiMode);
1685  result = hopFrequencies();
1686  if( !result )
1687  {
1689  as3993SingleWrite(AS3993_REG_STATUSPAGE, rssiMode);
1690  if (rssiMode == RSSI_MODE_PEAK) //if we use peak rssi mode, we have to send anti collision commands
1691  as3993SingleCommand(AS3993_CMD_ANTI_COLL_ON);
1692 
1693  performSelects();
1694 
1696  {
1697  followTagCommand = gen2ReadTID;
1698  }
1699 
1700  if( !autoAckMode )
1702  else
1703  {
1705 
1706 #if RUN_ON_AS3993
1708 #endif
1709 #if RUN_ON_AS3980
1710  delay_ms(400); // AS3980 Read Rate Limited to 2-3 reads/sec.
1711 #endif
1712  }
1713 
1714  if (rssiMode == RSSI_MODE_PEAK) //if we use peak rssi mode, we have to send anti collision commands
1715  as3993SingleCommand(AS3993_CMD_ANTI_COLL_OFF);
1716  }
1717  inventoryResult = result;
1718  hopChannelRelease();
1719 #if RADON
1720  delay_ms(100);
1721 #endif
1722 
1723  delay_ms(inventoryDelay);
1724  APPLOG("end inventory, found tags: %hhx\n", num_of_tags);
1725  return num_of_tags;
1726 }
1727 
1849 void callSelectTag(void)
1850 {
1851 #if RUN_ON_AS3980
1852  cmdBuffer.txSize = CMD_SELECT_REPLY_SIZE;
1853  cmdBuffer.result = ERR_REQUEST;
1854 #else
1855  //powerUpReader();
1856  //checkAndSetSession(SESSION_GEN2);
1857  selectTag();
1858  //powerDownReader();
1859 #endif
1860 }
1861 
1862 void selectTag(void)
1863 {
1864  s8 status=ERR_NONE;
1865  u8 idx = 0;
1866 
1867  if (cmdBuffer.rxData[0] == 0)
1868  { /* Clear list */
1869  num_selects = 0;
1870  goto exit;
1871  }
1872  else if (cmdBuffer.rxData[0] == 1)
1873  { /* Add to list */
1874  if(num_selects == MAX_SELECTS)
1875  {
1876  status = ERR_NOMEM;
1877  goto exit;
1878  }
1879  }
1880  else if (cmdBuffer.rxData[0] == 2)
1881  { /* Clear and Add to list */
1882  num_selects = 0;
1883  }
1884  if(cmdBuffer.rxSize < 9)
1885  {
1886  status = ERR_PARAM;
1887  goto exit;
1888  }
1889  idx = num_selects;
1890  num_selects++;
1891  selParams[idx].mask_address = 0x0000;
1892 
1893  selParams[idx].target = cmdBuffer.rxData[1];
1894  selParams[idx].action = cmdBuffer.rxData[2];
1895  selParams[idx].mem_bank = cmdBuffer.rxData[3];
1896  selParams[idx].mask_address = (u32) cmdBuffer.rxData[4];
1897  selParams[idx].mask_address |= ((u32)cmdBuffer.rxData[5]) << 8;
1898  selParams[idx].mask_len = cmdBuffer.rxData[6];
1899  selParams[idx].truncation = cmdBuffer.rxData[7];
1900 
1901  if((cmdBuffer.rxSize - 9) < (selParams[idx].mask_len+7)/8)
1902  {
1903  APPLOG("SELECT ERR_PARAM: ml=%hx rxsize=%hhx\n",selParams[idx].mask_len,cmdBuffer.rxSize);
1904  status = ERR_PARAM;
1905  goto exit;
1906  }
1907 
1908  memcpy(selParams[idx].mask,cmdBuffer.rxData+8,(selParams[idx].mask_len+7)/8);
1909 
1910  APPLOG("SELECT Tag target\n");
1911  APPLOGDUMP(selParams[idx].mask, (selParams[idx].mask_len+7)/8);
1912  initTagInfo();
1913 
1914  status = ERR_NONE; /* Tag found */
1915 
1916 exit:
1917  cmdBuffer.txSize = CMD_SELECT_REPLY_SIZE;
1918  cmdBuffer.result = status;
1919 }
1920 
1940 void callWriteToTag(void)
1941 {
1942  powerUpReader();
1944  writeToTag();
1945 }
1946 
1947 u8 writeTagMem(u32 memAdress,Tag const * tag, u8 const * data_buf, u8 data_length_words, u8 mem_type, s8* status, u8* tag_error)
1948 {
1949  s8 error = ERR_NONE;
1950  u8 length = 0;
1951  u8 count;
1952  APPLOG("len=%hhx\n",data_length_words);
1953 
1954  while (length < data_length_words)
1955  {
1956  /*writing pc into tag */
1957  count=0;
1958  do
1959  {
1960  error = gen2WriteWordToTag(tag, mem_type, memAdress + length, &data_buf[2*length], tag_error);
1961  count++;
1962  if (error) delay_ms(20); /* Potentially writing is still ongoing, avoid metastable eeprom and stuff*/
1963  } while ( (count<7) && (error!=0) && continueCheckTimeout()); /* Give them 3 possible trials before giving up */
1965 
1966  if (error)
1967  {
1968  *status = error;
1969  return(length); /*error occourd while writing to tag */
1970  }
1971  length += 1;
1972  }
1973 
1974  return length;
1975 }
1976 
1977 void writeToTag(void)
1978 {
1979  u8 len = 0;
1980  s8 status=0;
1981  u8 membank = cmdBuffer.rxData[0];
1982  u32 address = readU32FromLittleEndianBuffer(&cmdBuffer.rxData[1]);
1983  u8 datalen = (cmdBuffer.rxSize - 9)/2;
1984 
1985  APPLOG("WRITE TO Tag\n");
1986  APPLOGDUMP(cmdBuffer.rxData, cmdBuffer.rxSize);
1987  POWER_AND_SELECT_TAG();
1988  if ( (cmdBuffer.rxData[5]==0) \
1989  &&(cmdBuffer.rxData[6]==0) \
1990  &&(cmdBuffer.rxData[7]==0) \
1991  &&(cmdBuffer.rxData[8]==0) ) /* accesspwd not set */
1992  {
1993  APPLOG("no need to access Tag\n");
1994  }
1995  else
1996  {
1997  status=gen2AccessTag(selectedTag, cmdBuffer.rxData+5);
1998  APPLOG("need to access Tag");
1999  if (status==0)
2000  {
2001  APPLOG(" -> suceeded\n");
2002  }
2003  else
2004  {
2005  APPLOG(" -> failed\n");
2006  goto exit;
2007  }
2008  }
2009 
2010  len = writeTagMem(address, selectedTag, cmdBuffer.rxData+9,
2011  datalen, membank, &status, cmdBuffer.txData + 1);
2012 
2013 exit:
2014 
2015  hopChannelRelease();
2016  cmdBuffer.txSize = CMD_WRITE_TO_TAG_REPLY_SIZE;
2017  cmdBuffer.txData[0] = len;
2018  cmdBuffer.result = status;
2019 }
2020 
2021 #define RNDI 7 //index of first random value in buffer
2022 static void pseudoRandomContinuousModulation()
2023 {
2024  static u8 bufferIndex = 0;
2025  static u16 rnd;
2026  u8 buf[2];
2027  u16 rxbits = 0;
2028 
2029  //prepare a pseudo random value
2030  rnd ^= (cmdBuffer.rxData[RNDI+bufferIndex*2] | (cmdBuffer.rxData[RNDI+bufferIndex*2+1]<<8)); // get the random value from the GUI
2031  rnd ^= TMR3; // add currently running timer value, to get some additional entropy
2032 
2033  bufferIndex++;
2034  if (bufferIndex > 5)
2035  bufferIndex = 0;
2036 
2037  // now send the data
2038 #if RUN_ON_AS3980
2039  buf[0] = (rnd & 0x7F);
2040 #else
2041  buf[0] = (rnd & 0xFF);
2042 #endif
2043  buf[1] = (rnd >> 8) & 0xFF;
2044  //APPLOG("rnd: %hhx\n", rnd);
2045  //APPLOGDUMP(buf,2);
2046  as3993TxRxGen2Bytes(AS3993_CMD_TRANSMCRC, buf, 16, 0, &rxbits, 0, 0, 1);
2047 }
2048 
2177 void callChangeFreq(void)
2178 {
2179  u16 reflectedValues = 0;
2180  u16 noiseLevel = 0;
2181  u32 freq = 0;
2182 
2183  freq += (u32)cmdBuffer.rxData[1];
2184  freq += ((u32)cmdBuffer.rxData[2]) << 8;
2185  freq += ((u32)cmdBuffer.rxData[3]) << 16;
2186 
2187  APPLOG("CHANGE FREQ f=%x%x, subcmd=%hhx\n", freq, cmdBuffer.rxData[0]);
2188  APPLOGDUMP(cmdBuffer.rxData, cmdBuffer.rxSize);
2189 
2190  switch (cmdBuffer.rxData[0])
2191  {
2192  case 0x01: // get RSSI
2193  {
2194  if (cmdBuffer.rxSize < CMD_CHANGE_FREQ_RSSI_RX_SIZE)
2195  {
2196  cmdBuffer.result = ERR_PARAM;
2197  cmdBuffer.txSize = 3;
2198  break;
2199  }
2200 #ifdef EXTPA
2201  u8 rssiValues = 0;
2202  u8 regValRFOutput;
2203  powerUpReader();
2204  as3993AntennaPower(0);
2205  //PA eTX<3>eTX<2> disable
2206  regValRFOutput = as3993SingleRead(AS3993_REG_RFOUTPUTCONTROL);
2207  as3993SingleWrite(AS3993_REG_RFOUTPUTCONTROL, regValRFOutput & 0xC3 );
2208  delay_ms(5);
2209  as3993SetBaseFrequency(AS3993_REG_PLLMAIN1,freq);
2210  as3993GetRSSI(listeningTime,&rssiValues);
2211  as3993SingleWrite(AS3993_REG_RFOUTPUTCONTROL, regValRFOutput);
2212  powerDownReader();
2213 
2214  cmdBuffer.txSize = 3;
2215  cmdBuffer.txData[0] = rssiValues&0xf;
2216  cmdBuffer.txData[1] = ((rssiValues >> 4) & 0xf);
2217  cmdBuffer.txData[2] = 0;
2218  cmdBuffer.result = ERR_NONE;
2219 #else
2220  cmdBuffer.txSize = 3;
2221  cmdBuffer.txData[0] = 0;
2222  cmdBuffer.txData[1] = 0;
2223  cmdBuffer.txData[2] = 0;
2224  cmdBuffer.result = ERR_REQUEST;
2225 #endif
2226  break;
2227  }
2228  case 0x02: // get reflected Power
2229  {
2230  if (cmdBuffer.rxSize < CMD_CHANGE_FREQ_REFL_RX_SIZE)
2231  {
2232  cmdBuffer.result = ERR_PARAM;
2233  cmdBuffer.txSize = 2;
2234  break;
2235  }
2236  powerUpReader();
2237  as3993SetBaseFrequency(AS3993_REG_PLLMAIN1, freq);
2238  #ifdef TUNER
2239  if (cmdBuffer.rxData[4] > 0)
2240  {
2241  applyTunerSettingForFreq(freq);
2242  }
2243  #endif
2244  noiseLevel = as3993GetReflectedPowerNoiseLevel();
2245  as3993AntennaPower(1);
2246  delay_us(5000);//more Settling Time for the Tuning
2247  reflectedValues = as3993GetReflectedPower();
2248  as3993AntennaPower(0);
2249  cmdBuffer.txSize = 2;
2250  cmdBuffer.txData[0] = (reflectedValues & 0xff) - (noiseLevel & 0xff);
2251  cmdBuffer.txData[1] = ((reflectedValues >> 8)&0xff) - ((noiseLevel >> 8)&0xff);
2252  cmdBuffer.result = ERR_NONE;
2253  powerDownReader();
2254  break;
2255  }
2256  case 0x04:
2257  { /* Add to the frequency List */
2258  if (cmdBuffer.rxSize < CMD_CHANGE_FREQ_ADD_RX_SIZE)
2259  {
2260  cmdBuffer.result = ERR_PARAM;
2261  cmdBuffer.txSize = 1;
2262  break;
2263  }
2264  if (cmdBuffer.rxData[4]) // clear frequency list before adding
2265  {
2266  Frequencies.numFreqs = 0;
2267  guiNumFreqs = 0;
2268  guiMaxFreq = freq;
2269  guiMinFreq = freq;
2270  }
2271  Frequencies.numFreqs ++;
2272  guiNumFreqs++;
2273  if (Frequencies.numFreqs > MAXFREQ)
2274  {
2275  Frequencies.numFreqs = MAXFREQ;
2276  cmdBuffer.txSize = 1;
2277  cmdBuffer.txData[0] = 0;
2278  cmdBuffer.result = ERR_NOMEM;
2279  }
2280  else
2281  {
2282  Frequencies.freq[Frequencies.numFreqs - 1] = freq;
2283  guiActiveProfile = cmdBuffer.rxData[5];
2284  if (guiMaxFreq < freq) guiMaxFreq = freq;
2285  if (guiMinFreq > freq) guiMinFreq = freq;
2286  cmdBuffer.txSize = 1;
2287  cmdBuffer.txData[0] = 0x00;
2288  cmdBuffer.result = ERR_NONE;
2289  }
2290  break;
2291  }
2292  case 0x05:
2293  { // get frequency list parameters
2294  cmdBuffer.txData[0] = guiActiveProfile;
2295  cmdBuffer.txData[1] = guiMinFreq & 0xff;
2296  cmdBuffer.txData[2] = (guiMinFreq >> 8) & 0xff;
2297  cmdBuffer.txData[3] = (guiMinFreq >> 16) & 0xff;
2298  cmdBuffer.txData[4] = guiMaxFreq & 0xff;
2299  cmdBuffer.txData[5] = (guiMaxFreq >> 8) & 0xff;
2300  cmdBuffer.txData[6] = (guiMaxFreq >> 16) & 0xff;
2301  cmdBuffer.txData[7] = Frequencies.numFreqs;
2302  cmdBuffer.txData[8] = guiNumFreqs;
2303  cmdBuffer.txSize = 9;
2304  cmdBuffer.result = ERR_NONE;
2305  break;
2306  }
2307  case 0x08:
2308  {
2309  /* set parameters for frequency hopping */
2310  if (cmdBuffer.rxSize < CMD_CHANGE_FREQ_SETHOP_RX_SIZE)
2311  {
2312  cmdBuffer.result = ERR_PARAM;
2313  cmdBuffer.txSize = 1;
2314  break;
2315  }
2316  listeningTime = cmdBuffer.rxData[1];
2317  listeningTime |= (cmdBuffer.rxData[2]<<8);
2318  maxSendingTime = cmdBuffer.rxData[3];
2319  maxSendingTime |= (cmdBuffer.rxData[4]<<8);
2320  idleTime = cmdBuffer.rxData[5];
2321  idleTime |= (cmdBuffer.rxData[6]<<8);
2322  rssiThreshold = cmdBuffer.rxData[7];
2323  cmdBuffer.txSize = 1;
2324  cmdBuffer.txData[0] = 0x00;
2325  if (maxSendingTime <50)
2326  {
2327  maxSendingTime = 50;
2328  }
2329  cmdBuffer.result = ERR_NONE;
2330  break;
2331  }
2332  case 0x09:
2333  { /* get frequency hopping infos */
2334  cmdBuffer.txSize = 7;
2335  cmdBuffer.txData[0] = listeningTime & 0xff;
2336  cmdBuffer.txData[1] = (listeningTime >> 8) & 0xff;
2337  cmdBuffer.txData[2] = maxSendingTime & 0xff;
2338  cmdBuffer.txData[3] = (maxSendingTime >> 8) & 0xff;
2339  cmdBuffer.txData[4] = idleTime & 0xff;
2340  cmdBuffer.txData[5] = (idleTime >> 8) & 0xff;
2341  cmdBuffer.txData[6] = rssiThreshold;
2342  cmdBuffer.result = ERR_NONE;
2343  break;
2344  }
2345  case 0x10:
2346  {
2347  /* continuous modulation */
2348  if (cmdBuffer.rxSize < CMD_CHANGE_FREQ_CONTMOD_RX_SIZE)
2349  {
2350  cmdBuffer.result = ERR_PARAM;
2351  cmdBuffer.txSize = 0;
2352  break;
2353  }
2354  u16 time_ms = cmdBuffer.rxData[4] | (cmdBuffer.rxData[5]<<8);
2355  u8 rxnorespwait, rxwait;
2356  u16 rxbits = 0;
2357 #if RUN_ON_AS3980
2358  u8 txbuf[] = {0x9E, 0x9E};
2359 #endif
2360  APPLOG("continuous modulation, duration: %hx\n", time_ms);
2361  powerUpReader();
2362  rxnorespwait = as3993SingleRead( AS3993_REG_RXNORESPONSEWAITTIME );
2363  rxwait = as3993SingleRead( AS3993_REG_RXWAITTIME);
2364  as3993SingleWrite( AS3993_REG_RXNORESPONSEWAITTIME, 0 );
2365  as3993SingleWrite( AS3993_REG_RXWAITTIME, 0 );
2366  as3993SetBaseFrequency(AS3993_REG_PLLMAIN1, freq);
2368  cmdBuffer.txSize = 0;
2369  maxSendingLimit = time_ms;
2371  as3993AntennaPower(1);
2372  delay_ms(1);
2373  slowTimerStart();
2374  do{
2375  if (cmdBuffer.rxData[6] == 0x01)
2376  { /* pseudo random continuous modulation */
2377  pseudoRandomContinuousModulation();
2378  }
2379  else
2380  { /* static modulation */
2381 #if RUN_ON_AS3980
2382  as3993TxRxGen2Bytes(AS3993_CMD_TRANSMCRC, txbuf, 16, 0, &rxbits, 0, 0, 1);
2383 #else
2384  as3993TxRxGen2Bytes(AS3993_CMD_NAK, 0, 0, 0, &rxbits, 0, 0, 1);
2385 #endif
2386  }
2387  as3993ClrResponse();
2388  }while(continueCheckTimeout());
2389  as3993AntennaPower(0);
2390  as3993SingleWrite( AS3993_REG_RXNORESPONSEWAITTIME, rxnorespwait );
2391  as3993SingleWrite( AS3993_REG_RXWAITTIME, rxwait );
2392  powerDownReader();
2393  APPLOG("finished sending \n");
2394  return;
2395  }
2396 
2397 
2398  default:
2399  {
2400  cmdBuffer.txSize = 2;
2401  cmdBuffer.txData[0] = 0xFF;
2402  cmdBuffer.txData[1] = 0xFF;
2403  cmdBuffer.result = ERR_REQUEST;
2404  break;
2405  }
2406  }
2407  APPLOG("changeFreq finished, reply data: \n");
2408  APPLOGDUMP(cmdBuffer.txData, cmdBuffer.txSize);
2409 }
2410 
2434 {
2435  powerUpReader();
2437  readFromTag();
2438 }
2439 
2440 void readFromTag(void)
2441 {
2442  s8 status = ERR_NONE;
2443  u8 membank = cmdBuffer.rxData[0];
2444  u32 wrdPtr = readU32FromLittleEndianBuffer(&cmdBuffer.rxData[1]);
2445  u8 datalen = cmdBuffer.txSize;
2446  u8 rxed = CMD_ERROR_REPLY_SIZE;// set to 1 if POWER_AND_SELECT_TAG failed
2447 
2448  APPLOG("READ FROM Tag\n");
2449  APPLOG("membank = %hhx\n", membank);
2450  APPLOG("wrdptr = %hx%hx\n", wrdPtr);
2451  APPLOG("raw datalen = %hhx\n", datalen);
2452  APPLOGDUMP(cmdBuffer.rxData, cmdBuffer.rxSize);
2453  memset(cmdBuffer.txData, 0x00, cmdBuffer.txSize);
2454 
2455  POWER_AND_SELECT_TAG();
2456 
2457  if ( (cmdBuffer.rxData[5]==0) \
2458  &&(cmdBuffer.rxData[6]==0) \
2459  &&(cmdBuffer.rxData[7]==0) \
2460  &&(cmdBuffer.rxData[8]==0) ) /* accesspwd not set */
2461  {
2462  APPLOG("no need to access Tag\n");
2463  }
2464  else
2465  {
2466  status=gen2AccessTag(selectedTag, cmdBuffer.rxData+5);
2467  APPLOG("need to access Tag");
2468  if (status==0)
2469  {
2470  APPLOG(" -> suceeded\n");
2471  }
2472  else
2473  {
2474  APPLOG(" -> failed status: %hhx\n", status);
2475  status=GEN2_ERR_ACCESS;
2476  goto exit;
2477  }
2478  }
2479  rxed = 0;
2480  if (datalen & 1)
2481  { /* Special mode for odd size: read word by word until error */
2482  u8 * b = cmdBuffer.txData;
2483  datalen /= 2;
2484  while(ERR_NONE == status && datalen && continueCheckTimeout())
2485  {
2486  status = gen2ReadFromTag(selectedTag, membank, wrdPtr++, 1, b);
2487  if (ERR_CHIP_HEADER == status)
2488  { /* Header bit means only one byte status */
2489  rxed++;
2490  }
2491  else if (ERR_NONE == status)
2492  {
2493  rxed+=2;
2494  }
2495  b+=2;
2496  datalen--;
2497  }
2499  }
2500  else
2501  {
2502  datalen /= 2;
2503  status = gen2ReadFromTag(selectedTag, membank, wrdPtr, datalen, cmdBuffer.txData);
2504  if (ERR_CHIP_HEADER == status)
2505  { /* Header bit means only one byte status */
2506  rxed = 1;
2507  }
2508  else if (ERR_NONE == status)
2509  {
2510  rxed = datalen * 2;
2511  }
2512  }
2513 exit:
2514  hopChannelRelease();
2515  cmdBuffer.txSize = rxed;
2516  cmdBuffer.result = status;
2517  APPLOG("read finished, status: %hhx rxed: %hhx\n", status, rxed);
2518  APPLOGDUMP(cmdBuffer.txData, cmdBuffer.txSize);
2519 }
2520 
2535 {
2536  powerUpReader();
2538  lockUnlockTag();
2539 }
2540 void lockUnlockTag(void)
2541 {
2542  const u8 *mask = cmdBuffer.rxData;
2543  s8 status;
2544  APPLOG("Lock Tag\n");
2545  APPLOG("Command %hhx %hhx\n", cmdBuffer.rxData[0], cmdBuffer.rxData[1]);
2546  APPLOGDUMP(cmdBuffer.rxData, cmdBuffer.rxSize);
2547 
2548  POWER_AND_SELECT_TAG();
2549 
2550  if ( (cmdBuffer.rxData[3]==0)
2551  &&(cmdBuffer.rxData[4]==0)
2552  &&(cmdBuffer.rxData[5]==0)
2553  &&(cmdBuffer.rxData[6]==0) ) /* accesspwd not set */
2554  {
2555  APPLOG("no need to access Tag\n");
2556  }
2557  else
2558  {
2559  status=gen2AccessTag(selectedTag, &cmdBuffer.rxData[3]);
2560  if (status!=0) goto exit;
2561  APPLOG("need to access Tag");
2562  if (status==0)APPLOG(" access suceeded\n");
2563  else APPLOG(" access failed\n");
2564  }
2565 
2566  APPLOG("LOCK UNLOCK Tag: mask_and_action %hhx %hhx %hhx \n", mask[0],mask[1],mask[2]);
2567  status = gen2LockTag(selectedTag, mask, cmdBuffer.txData);
2568 
2569 exit:
2570  if (status) delay_ms(20); /* Potentially transaction is still ongoing, avoid metastable eeprom and stuff*/
2571  hopChannelRelease();
2572  cmdBuffer.result = status;
2573  cmdBuffer.txSize = CMD_LOCK_REPLY_SIZE;
2574 }
2575 
2594 void callKillTag(void)
2595 {
2596  s8 status;
2597  const u8* password = cmdBuffer.rxData;
2598  u8 rfu = cmdBuffer.rxData[4];
2599  u8 recom = cmdBuffer.rxData[5];
2600 
2601  powerUpReader();
2603 
2604  APPLOG("KILL Tag\n");
2605 
2606  POWER_AND_SELECT_TAG();
2607 
2608  status = gen2KillTag(selectedTag, password, rfu, recom, cmdBuffer.txData);
2609 
2610 exit:
2611  if (status) delay_ms(20); /* Potentially writing is still ongoing, avoid metastable eeprom and stuff*/
2612  hopChannelRelease();
2613  cmdBuffer.txSize = CMD_KILL_TAG_REPLY_SIZE;
2614  cmdBuffer.result = status;
2615 }
2616 
2639 void callStartStop(void)
2640 {
2641  APPLOG("STARTSTOP: %hhx %hhx\n", cmdBuffer.rxData[0], cmdBuffer.rxData[1]);
2642  if (cmdBuffer.rxData[0])
2643  {
2644  cyclicInventory = cmdBuffer.rxData[1];
2645  if (cyclicInventory)
2646  {
2647  autoAckMode = cmdBuffer.rxData[2];
2648  fastInventory = cmdBuffer.rxData[3] & 0x01;
2649  readTIDinInventoryRound = (cmdBuffer.rxData[3] & 0x02) >> 1 ;
2650  rssiMode = cmdBuffer.rxData[4];
2651  }
2652  }
2653  cmdBuffer.txSize = CMD_START_STOP_REPLY_SIZE;
2654  cmdBuffer.result = ERR_NONE;
2655  if(!cyclicInventory)
2656  powerDownReader();
2657 }
2684 {
2686  executeGenericCommand();
2687 }
2688 
2689 void executeGenericCommand()
2690 {
2691  s8 status = ERR_NONE;
2692  u16 toTagSize, fromTagSize;
2693  u8 toTagBuffer[200];
2694  u8 cmd, norestime;
2695  u16 dataBytes, leftBits, startBytehandle;
2696  u16 receivedBytes=CMD_ERROR_REPLY_SIZE;// set to CMD_ERROR_REPLY_SIZE if POWER_AND_SELECT_TAG failed
2697 
2698  APPLOG("Execute GCom: rxed: %hhx, txed: %hhx\n ", cmdBuffer.rxSize, cmdBuffer.txSize);
2699  APPLOGDUMP(cmdBuffer.rxData, cmdBuffer.rxSize);
2700  memset(cmdBuffer.txData, 0x00, cmdBuffer.txSize);
2701 
2702  POWER_AND_SELECT_TAG();
2703 
2704  if ( (cmdBuffer.rxData[0]==0) &&(cmdBuffer.rxData[1]==0) &&(cmdBuffer.rxData[2]==0) &&(cmdBuffer.rxData[3]==0) ) /* accesspwd not set */
2705  {
2706  APPLOG("no need to access Tag\n");
2707  }
2708  else
2709  {
2710  status=gen2AccessTag(selectedTag, cmdBuffer.rxData);
2711  APPLOG("need to access Tag");
2712  if (status==0)
2713  {
2714  APPLOG(" -> suceeded\n");
2715  }
2716  else
2717  {
2718  APPLOG(" -> failed status: %hhx\n", status);
2719  status=GEN2_ERR_ACCESS;
2720  goto exit;
2721  }
2722  }
2723 
2724  // Get Values from Stream
2725  toTagSize = (cmdBuffer.rxData[4] << 4) | ((cmdBuffer.rxData[5] & 0xF0) >> 4);
2726  fromTagSize = ((cmdBuffer.rxData[5] & 0x0F) << 8) | (cmdBuffer.rxData[6]);
2727  cmd = cmdBuffer.rxData[7];
2728  norestime = cmdBuffer.rxData[8];
2729 
2730  dataBytes = (toTagSize - 16 + 7)/8 ;
2731  leftBits = (dataBytes * 8) -(toTagSize-16);
2732  startBytehandle = dataBytes - 1;
2733  if ( leftBits == 0 )
2734  {
2735  startBytehandle++;
2736  leftBits = 8;
2737  }
2738  insertBitStream(&toTagBuffer[0], (cmdBuffer.rxData)+9, dataBytes, 8 );
2739  insertBitStream(&toTagBuffer[startBytehandle], selectedTag->handle, 2, leftBits);
2740 
2741  status = as3993TxRxGen2Bytes(cmd, toTagBuffer, toTagSize, (cmdBuffer.txData + 2), &fromTagSize, norestime, 0, 1);
2742 
2743  cmdBuffer.txData[1] = (u8)fromTagSize;
2744 
2745  receivedBytes = (fromTagSize+7)/8 + 2;
2746  APPLOG("fromTagBuf: status: %hhx txed: %hhx\n", status, fromTagSize);
2747  APPLOGDUMP(cmdBuffer.txData, receivedBytes);
2748  delay_ms(20);
2749 exit:
2750  hopChannelRelease();
2751  cmdBuffer.txData[0] = (u8) status;
2752  cmdBuffer.txSize = receivedBytes;
2753  cmdBuffer.result = status;
2754 }
2755 
2756 void callRSSIMeasureCMD(void)
2757 {
2758  powerUpReader();
2760  executeRSSICMD();
2761 }
2762 
2763 void executeRSSICMD()
2764 {
2765  s8 status = ERR_NONE;
2766  u8 count = cmdBuffer.txSize / 4;
2767  u8 *b = cmdBuffer.txData;
2768  u32 freq;
2769 
2770  freq = 0;
2771  freq += (u32)cmdBuffer.rxData[0];
2772  freq += ((u32)cmdBuffer.rxData[1]) << 8;
2773  freq += ((u32)cmdBuffer.rxData[2]) << 16;
2774 
2775  APPLOG("RSSI CMD f=%x%x\n", freq);
2776 
2777  cmdBuffer.txSize = 0;
2778 
2779  as3993AntennaPower(1);
2780 
2781  as3993SetBaseFrequency(AS3993_REG_PLLMAIN1, freq);
2782 
2783  performSelects();
2784 
2785  while ( count-- )
2786  {
2787  status = gen2QueryMeasureRSSI(b+0, b+1, (s8*) b+2, (s8*) b+3);
2788  if (status)
2789  {/* Pick lowest values and invalid agc_reg to denote fail */
2790  b[0] = 0;
2791  b[1] = 0;
2792  b[2] = SCHAR_MIN;
2793  b[3] = SCHAR_MIN;
2794  }
2795  b+=4;
2796  cmdBuffer.txSize += 4;
2797  }
2798 
2799  as3993AntennaPower(0);
2800 }
2801 
2802 void initCommands(void)
2803 {
2804  currentSession = 0;
2805  cyclicInventory = 0;
2806  fastInventory = 0;
2808  autoAckMode = 1;
2809  rssiMode = 0x06; //rssi at 2nd byte
2810  rssiThreshold = 3;
2812 
2813  tagDataAvailable = 0;
2814  num_of_tags = 0;
2815 #ifdef ANTENNA_SWITCH
2817 #endif
2818  as3993AntennaPower(0);
2819  powerDownReader();
2820 }
2821 
2822 #ifdef TUNER
2823 static void applyTunerSettingForFreq(u32 freq)
2824 {
2825  u8 i, idx;
2826  unsigned long int diff, best;
2827 
2828  if (tuningTable.tableSize == 0) //tuning is disabled
2829  return;
2830 
2831  //find the best matching frequency
2832  best = 1.0e4;
2833  idx = 0;
2834  for(i=0; i<tuningTable.tableSize; i++)
2835  {
2836  //CON_print("***** find tune f=%x%x, tablefreq=%x%x, idx=%hhx", freq, tuningTable.freq[i], idx);
2837  if (tuningTable.freq[i] > freq)
2838  diff = tuningTable.freq[i] - freq;
2839  else
2840  diff = freq - tuningTable.freq[i];
2841  if (diff < best)
2842  {
2843  idx = i;
2844  best = diff;
2845  }
2846  }
2847  //apply the found parameters if enabled for the current antenna
2848  tuningTable.currentEntry = idx;
2849  if (tuningTable.tuneEnable[idx] & usedAntenna)
2850  {
2851  tunerSetTuning(&mainTuner, tuningTable.cin[usedAntenna - 1][idx],
2852  tuningTable.clen[usedAntenna - 1][idx],
2853  tuningTable.cout[usedAntenna - 1][idx]);
2854  APPLOG("***** apply tune f=%x%x, idx=%hhx, tune1=%hhx cin=%hhx clen=%hhx cout=%hhx\n", freq, idx,
2855  tuningTable.tuneEnable[idx], tuningTable.cin[usedAntenna-1][idx],
2856  tuningTable.clen[usedAntenna-1][idx], tuningTable.cout[usedAntenna-1][idx]);
2857  tunerParams.cin = tuningTable.cin[usedAntenna - 1][idx];
2858  tunerParams.clen = tuningTable.clen[usedAntenna - 1][idx];
2859  tunerParams.cout = tuningTable.cout[usedAntenna - 1][idx];
2860  }
2861 }
2862 #endif
2863 
2864 
2865 static s8 hopFrequencies(void)
2866 {
2867  u16 idleDelay;
2868  u8 rssiIQsum = 0;
2869 #ifdef EXTPA
2870 #if NEWTON
2871  u8 i, rssi = 0;
2872  u8 regValRFOutput = 0;
2873 #endif
2874 #endif
2875  APPLOG("hop Freq\n");
2876  slowTimerStart(); //start timer for idle delay
2877  powerUpReader();
2878  as3993AntennaPower(0);
2879 
2880  idleDelay = slowTimerValue();
2881  if ( idleTime > idleDelay)
2882  { /* wait for idle time */
2883  delay_ms(idleTime - idleDelay);
2884  }
2885  slowTimerStop();
2886  if (Frequencies.numFreqs == 0)
2887  {
2888  if (!cyclicInventory)
2889  powerDownReader();
2890  return GEN2_ERR_CHANNEL_TIMEOUT;
2891  }
2892 
2893 #ifdef EXTPA
2894 #if NEWTON
2895  //PA eTX<3>eTX<2> disable
2896  regValRFOutput = as3993SingleRead(AS3993_REG_RFOUTPUTCONTROL);
2897  as3993SingleWrite(AS3993_REG_RFOUTPUTCONTROL, regValRFOutput & 0xC3 );
2898  delay_ms(5);
2899 
2900  for (i = 0; i < Frequencies.numFreqs; i++)
2901  {
2902  if ( ++currentFreqIdx >= Frequencies.numFreqs ) currentFreqIdx = 0;
2903 
2904  if (rssiThreshold >= 32)
2905  break; //we skip rssi measurement if threshold is to low and I + Q is always below this threshold
2906 
2907  // change for RSSI PLL frequency, dependency on filter setting --> see comment of define AS3993_RSSI_FREQUENCY_OFFSET
2908  as3993SetBaseFrequency(AS3993_REG_PLLMAIN1, Frequencies.freq[currentFreqIdx]-AS3993_RSSI_FREQUENCY_OFFSET);
2909 
2910  as3993GetRSSIMaxSensitive(listeningTime,&rssi);
2911  rssiIQsum = (rssi&0x0f) + (rssi>>4);
2912  if (rssiIQsum <= rssiThreshold)
2913  {
2914  APPLOG("FREQ f=%x%x occ TH = %hhx rssi = %hhx ----OK \n", Frequencies.freq[currentFreqIdx], rssiThreshold, rssiIQsum);
2915  break; /* Found free frequency, now we can return */
2916  }
2917  else
2918  {
2919  APPLOG("FREQ f=%x%x occ TH = %hhx dBm = %hhx \n", Frequencies.freq[currentFreqIdx], rssiThreshold, rssiIQsum);
2920  }
2921  }
2922  as3993SetBaseFrequency(AS3993_REG_PLLMAIN1, Frequencies.freq[currentFreqIdx]);
2923 
2924  as3993SingleWrite(AS3993_REG_RFOUTPUTCONTROL, regValRFOutput);
2925 #else
2926  if ( ++currentFreqIdx >= Frequencies.numFreqs ) currentFreqIdx = 0;
2927  as3993SetBaseFrequency(AS3993_REG_PLLMAIN1, Frequencies.freq[currentFreqIdx]);
2928 #endif
2929 #else
2930  if ( ++currentFreqIdx >= Frequencies.numFreqs ) currentFreqIdx = 0;
2931  as3993SetBaseFrequency(AS3993_REG_PLLMAIN1, Frequencies.freq[currentFreqIdx]);
2932 #endif
2934 
2935  if (rssiIQsum <= rssiThreshold)
2936  {
2937  slowTimerStart();
2939 #ifdef TUNER
2940  applyTunerSettingForFreq(Frequencies.freq[currentFreqIdx]);
2941 #endif
2942 #if RADON
2943  delay_ms(1); // FIXME uhe 2013-11-21 an extra delay is needed after as3993GetRSSI() before turning on field otherwise refleced power values are really high
2944 #endif
2945  as3993AntennaPower(1);
2946 #if RADON
2947  {
2948  u16 refl;
2949  u8 regs[2];
2950  /* Read configured gain values */
2951  regs[0] = as3993SingleRead(AS3993_REG_TRCALHIGH);
2952  regs[1] = as3993SingleRead(AS3993_REG_RXMIXERGAIN);
2953  /* Write nominal gain values */
2954  as3993SingleWrite(AS3993_REG_TRCALHIGH, 0x00);
2955  as3993SingleWrite(AS3993_REG_RXMIXERGAIN, 0x00);
2956  refl = tunerGetReflected();
2957  /* Restore configured gain values */
2958  as3993SingleWrite(AS3993_REG_TRCALHIGH, regs[0]);
2959  as3993SingleWrite(AS3993_REG_RXMIXERGAIN,regs[1]);
2960  if (refl > 6032)
2961  {
2962  REFLPOWERTOOHIGHLED(LEDON);
2964  as3993AntennaPower(0);
2965  if (!cyclicInventory)
2966  powerDownReader();
2967  delay_ms(100);
2968  APPLOG("hopFrequencies failed: reflected power too high: %hx > %hx\n",refl,6032);
2969  return ERR_REFLECTED_POWER;
2970  }
2971  else
2972  {
2973  REFLPOWERTOOHIGHLED(LEDOFF);
2974  }
2975  }
2976 #endif
2977 #ifdef TUNER
2978  //if ( tuningTable.tableSize > 0 && ++Frequencies.countFreqHop[currentFreqIdx] > scanTuningInterval ) /* If tuning is enabled and this frequency has been selected for the (scanTuningInterval)th time, check if we have to do a re-tune (autotune) */
2979 
2980  /* If tuning is enabled check if we have to do a re-tune (autotune) */
2981  if ( tuningTable.tableSize > 0 && ++tuningCounter > scanTuningInterval )
2982  {
2983  u16 refl;
2984  refl = tunerGetReflected();
2985  APPLOG("countFreqHop has reached %hhx\n",Frequencies.countFreqHop[currentFreqIdx]);
2986  APPLOG("old reflected power: %hx\n", tuningTable.tunedIQ[usedAntenna-1][tuningTable.currentEntry]);
2987  APPLOG("measured reflected power: %hx\n", refl);
2988  Frequencies.countFreqHop[currentFreqIdx] = 0;
2989  if ( refl > tuningTable.tunedIQ[usedAntenna-1][tuningTable.currentEntry] * ( 1.0 + (scanRetuningLevel/100.0) ) ||
2990  refl < tuningTable.tunedIQ[usedAntenna-1][tuningTable.currentEntry] * ( 1.0 - (scanRetuningLevel/100.0) ) )
2991  /* if reflected power differs scanRetuningLevel/100 compared to last tuning time, redo tuning */
2992  {
2993  tunerOneHillClimb(&mainTuner, &tunerParams, 100);
2994  //tunerMultiHillClimb(&antennaParams);
2995  APPLOG("redo tuning, old cin: %hhx, clen: %hhx, cout: %hhx\n", tuningTable.cin[usedAntenna-1][tuningTable.currentEntry],
2996  tuningTable.clen[usedAntenna-1][tuningTable.currentEntry], tuningTable.cout[usedAntenna-1][tuningTable.currentEntry]);
2997  APPLOG("new values cin: %hhx, clen: %hhx, cout: %hhx, iq: %hx\n", tunerParams.cin,
2998  tunerParams.clen, tunerParams.cout, tunerParams.reflectedPower);
2999  tuningTable.cin[usedAntenna-1][tuningTable.currentEntry] = tunerParams.cin;
3000  tuningTable.clen[usedAntenna-1][tuningTable.currentEntry] = tunerParams.clen;
3001  tuningTable.cout[usedAntenna-1][tuningTable.currentEntry] = tunerParams.cout;
3002  tuningTable.tunedIQ[usedAntenna-1][tuningTable.currentEntry] = tunerParams.reflectedPower;
3003  }
3004  if (tuningCounter >= (scanTuningInterval + Frequencies.numFreqs))
3005  {
3006  tuningCounter = 0;
3007  }
3008  }
3009 #endif
3010  return GEN2_OK;
3011  }
3012  else
3013  {
3015  as3993AntennaPower(0);
3016  if (!cyclicInventory)
3017  powerDownReader();
3018  APPLOG("hopFrequencies failed: did not find a free channel\n");
3019  return GEN2_ERR_CHANNEL_TIMEOUT;
3020  }
3021 }
3022 
3023 static void hopChannelRelease(void)
3024 {
3025  slowTimerStop();
3027  as3993AntennaPower(0);
3028  if (!cyclicInventory)
3029  powerDownReader();
3030 }
3031 
3037 {
3038  if (cyclicInventory)
3039  {
3041  return 1;
3042  }
3043  return 0;
3044 }
3045 
3050 static void powerDownReader(void)
3051 {
3052  APPLOG("powerDownReader: %hx\n", readerPowerDownMode);
3053  switch (readerPowerDownMode)
3054  {
3055  case POWER_DOWN:
3057  break;
3058  case POWER_NORMAL:
3060  break;
3061  case POWER_NORMAL_RF:
3063  break;
3064  case POWER_STANDBY:
3066  break;
3067  default:
3069  }
3070 }
3071 
3075 static void powerUpReader(void)
3076 {
3077  APPLOG("powerUpReader: %hx\n", readerPowerDownMode);
3078  switch (readerPowerDownMode)
3079  {
3080  case POWER_DOWN:
3082  break;
3083  case POWER_NORMAL:
3085  break;
3086  case POWER_NORMAL_RF:
3088  break;
3089  case POWER_STANDBY:
3091  break;
3092  default:
3094  }
3095 }
3096 
3097 
3324 u8 commands( u8 protocol, u16 rxSize, const u8 * rxData, u16 * txSize, u8 * txData )
3325 {
3326  APPLOG("%hhxI\n", protocol);
3327  if (rxSize == 0) return ERR_REQUEST;
3328  cyclicInventory = 0; //stop cyclic inventory when new command has been received.
3329 
3330  if (protocol >= CALL_FKT_SIZE)
3331  {
3332  APPLOG("invalid command:ERR_REQUEST\n");
3333  return ERR_REQUEST;
3334  }
3335  /* setup pointers etc for usb command funtions, which use local buffers. */
3336  cmdBuffer.rxData = rxData;
3337  cmdBuffer.rxSize = rxSize;
3338  cmdBuffer.txData = txData;
3339  cmdBuffer.txSize = *txSize;
3340  cmdBuffer.result = ERR_REQUEST;
3341  if (rxSize < call_fkt_[protocol].min_rx_size)
3342  {
3343  APPLOG("commands(%hhx):ERR_REQUEST %hx < %hx\n",protocol,rxSize,call_fkt_[protocol].min_rx_size);
3344  return ERR_REQUEST;
3345  }
3346  if (*txSize < call_fkt_[protocol].min_tx_size)
3347  {
3348  APPLOG("commands(%hhx):ERR_PARAM %hx < %hx\n",protocol,*txSize, call_fkt_[protocol].min_tx_size);
3349  return ERR_PARAM;
3350  }
3351 
3352  // call the function associated with the command
3353  call_fkt_[protocol].func();
3354 
3355  *txSize = cmdBuffer.txSize;
3356  APPLOG("commands execution finished len:%hhx, replyError:%hhx\n\n", *txSize, cmdBuffer.result);
3357  return cmdBuffer.result;
3358 }
3359 
3360 #define SENDTAGHEADER 3
3361 #define SENDNOTAGINFO 7
3362 #define SENDTAGFIXDATALEN 8
3363 #define SENDTAGMINLEN (SENDTAGHEADER + SENDTAGFIXDATALEN)
3364 
3390 u8 sendTagData( u8 * protocol, u16 * txSize, u8 * txData, u16 remainingSize )
3391 {
3392  static u8 element = 0;
3393  u16 offset;
3394 
3395  *txSize = 0;
3396  if (!tagDataAvailable)
3397  {
3398  return ERR_NONE;
3399  }
3400  if (remainingSize < SENDTAGMINLEN)
3401  { //not enough buffer to send next tag data, wait for buffer to be sent.
3402  //APPLOG("send tag data buffer full, len: %hhx\n", *txSize);
3403  //APPLOGDUMP(txData, *txSize);
3404  return ERR_NONE;
3405  }
3406 
3407  APPLOG("send tag data, numTags: %hhx , elem: %hhx\n", num_of_tags, element);
3408  *protocol = CMD_INVENTORY_GEN2;
3409  txData[0] = cyclicInventory;
3410  if (num_of_tags == 0)
3411  {
3412  txData[1] = 0;
3413  txData[2] = 0;
3414  txData[3] = inventoryResult;
3415  txData[4] = Frequencies.freq[currentFreqIdx] & 0xff;
3416  txData[5] = (Frequencies.freq[currentFreqIdx] >> 8) & 0xff;
3417  txData[6] = (Frequencies.freq[currentFreqIdx] >> 16) & 0xff;
3418  *txSize = SENDNOTAGINFO;
3419  tagDataAvailable = 0;
3420  element = 0;
3421  return ERR_NONE;
3422  }
3423  *txSize = SENDTAGHEADER;
3424  txData[2] = 0; //number of tags in reply
3425  offset = SENDTAGHEADER; //index in buffer where data for next tag can be put
3426  while (element < num_of_tags)
3427  {
3428  if (remainingSize < (*txSize + SENDTAGMINLEN + tags_[element].epclen))
3429  { //not enough buffer to send next tag data, wait for buffer to be sent.
3430  //APPLOG("send tag data buffer full2, elem: %hhx , txSize: %hhx , offset: %hhx , remain: %hhx\n", element, *txSize, offset, remainingSize);
3431  //APPLOGDUMP(txData, *txSize);
3432  return ERR_NONE;
3433  }
3434  txData[1] = num_of_tags - element - 1; //set number of tags left
3435  txData[2]++; //increase number of tags in reply
3436  *txSize += SENDTAGFIXDATALEN + tags_[element].epclen;
3437  txData[offset+0] = tags_[element].agc;
3438  txData[offset+1] = tags_[element].rssi;
3439  txData[offset+2] = Frequencies.freq[currentFreqIdx] & 0xff;
3440  txData[offset+3] = (Frequencies.freq[currentFreqIdx] >> 8) & 0xff;
3441  txData[offset+4] = (Frequencies.freq[currentFreqIdx] >> 16) & 0xff;
3442  txData[offset+5] = tags_[element].epclen + 2;
3443  txData[offset+6] = tags_[element].pc[0];
3444  txData[offset+7] = tags_[element].pc[1];
3445  memcpy(&txData[offset+8], tags_[element].epc, tags_[element].epclen);
3446 
3448  {
3449  txData[offset+8+tags_[element].epclen] = tags_[element].tidlength;
3450  memcpy(&txData[offset+8+tags_[element].epclen+1], tags_[element].tid, tags_[element].tidlength);
3451  offset += tags_[element].tidlength+1;
3452  *txSize += tags_[element].tidlength+1;
3453  }
3454  offset += SENDTAGFIXDATALEN + tags_[element].epclen;
3455  element++;
3456  }
3457  APPLOG("all tags sent, len: %hhx , elem: %hhx , numTags: %hhx\n", *txSize, element, num_of_tags);
3458  APPLOGDUMP(txData, *txSize);
3459  // all tags have been sent
3460  tagDataAvailable = 0;
3461  element = 0;
3462  return ERR_NONE;
3463 }
3489 void callConfigPA(void)
3490 {
3491 
3492 #if NEWTON
3493  int rwMode = cmdBuffer.rxData[0];
3494  APPLOG("Config PA %hhx\n", cmdBuffer.rxData[0]);
3495 
3496  if (rwMode == 1)
3497  {
3498  _LATB5 = (cmdBuffer.rxData[1] & 0x01); //G8
3499  _LATB2 = (cmdBuffer.rxData[1] & 0x02) >> 1; //G16
3500  }
3501  cmdBuffer.txData[0] = _LATB2 << 1;
3502  cmdBuffer.txData[0] |= _LATB5;
3503  cmdBuffer.txSize = 1;
3504  cmdBuffer.result = ERR_NONE;
3505 
3506 #else
3507  APPLOG("not available\n");
3508  cmdBuffer.result = ERR_PARAM;
3509 #endif
3510 }
3511 
3542 {
3543  int wDelayMode = cmdBuffer.rxData[0];
3544  int wQAdjustParamsMode = cmdBuffer.rxData[3];
3545  int wScanTuningParamsMode = cmdBuffer.rxData[8];
3546 
3547  APPLOG("Inventory Parameters, Delay: %hhx %hhx; Adaptive Q: %hhx\n", cmdBuffer.rxData[1], cmdBuffer.rxData[2], cmdBuffer.rxData[4]);
3548  APPLOG("AddRounds: %hhx, Adjust Up Thh: %hhx, Adjust Up Thh: %hhx\n", cmdBuffer.rxData[5], cmdBuffer.rxData[6], cmdBuffer.rxData[7]);
3549  APPLOG("Scan Tuning Interval: %hhx %hhx;Retuning Level: %hhx\n", cmdBuffer.rxData[9], cmdBuffer.rxData[10], cmdBuffer.rxData[11]);
3550 
3551  if (wDelayMode == 1)
3552  {
3553  APPLOG("Change Delay \n");
3554  inventoryDelay = cmdBuffer.rxData[1] << 8;
3555  inventoryDelay |= cmdBuffer.rxData[2];
3556  }
3557 
3558  if (wQAdjustParamsMode == 1)
3559  {
3560  APPLOG("Change Query Adjust Parameters \n");
3561  adaptiveQ = cmdBuffer.rxData[4];
3562  adjustmentRounds = cmdBuffer.rxData[5];
3563  adjustmentUpThreshold = cmdBuffer.rxData[6];
3564  adjustmentDownThreshold = cmdBuffer.rxData[7];
3565  }
3566 
3567  if (wScanTuningParamsMode == 1)
3568  {
3569  APPLOG("Change Scan Tuning interval \n");
3570  scanTuningInterval = cmdBuffer.rxData[9] << 8;
3571  scanTuningInterval |= cmdBuffer.rxData[10];
3572  scanRetuningLevel = cmdBuffer.rxData[11];
3573  }
3574 
3575  cmdBuffer.txData[0] = (inventoryDelay & 0xFF00) >> 8;
3576  cmdBuffer.txData[1] = inventoryDelay & 0xFF;
3577  cmdBuffer.txData[2] = adaptiveQ;
3578  cmdBuffer.txData[3] = adjustmentRounds;
3579  cmdBuffer.txData[4] = adjustmentUpThreshold;
3580  cmdBuffer.txData[5] = adjustmentDownThreshold;
3581  cmdBuffer.txData[6] = (scanTuningInterval & 0xFF00) >> 8;
3582  cmdBuffer.txData[7] = scanTuningInterval & 0xFF;
3583  cmdBuffer.txData[8] = scanRetuningLevel;
3584 
3585  APPLOG("Inventory Parameters, Delay: %hhx %hhx; Adaptive Q: %hhx\n", cmdBuffer.txData[0], cmdBuffer.txData[1], cmdBuffer.txData[2]);
3586  APPLOG("AddRounds: %hhx, Adjust Up Thh: %hhx, Adjust Up Thh: %hhx\n", cmdBuffer.txData[3], cmdBuffer.txData[4], cmdBuffer.txData[5]);
3587  APPLOG("Scan Tuning Interval: %hhx %hhx;Retuning Level: %hhx\n", cmdBuffer.txData[6], cmdBuffer.txData[7], cmdBuffer.txData[8]);
3588 
3589  cmdBuffer.txSize = 9;
3590  cmdBuffer.result = ERR_NONE;
3591 
3592 }
3593 
3607 {
3608  s8 ret;
3609  u8 wordCount = 4;
3610  u32 wordPtr = 0;
3611 
3612  APPLOG("read TAG=%hhx\n",tag->epc[0]);
3613  tag->tidlength=0;
3614  ret = gen2ReadFromTag(tag, MEM_TID, wordPtr, wordCount, tag->tid);
3615 
3616 
3617 
3618  if (ret == ERR_NONE)
3619  {
3620  APPLOG("first 4 Words correctly read");
3621  tag->tidlength = wordCount * 2;
3622 
3623  wordPtr = 4;
3624  wordCount = 1;
3625  while (wordPtr < (TIDLENGTH/2))
3626  {
3627  ret = gen2ReadFromTag(tag, MEM_TID, wordPtr, wordCount, (tag->tid + (wordPtr*2)));
3628  if (ret != ERR_NONE) {break;}
3629  wordPtr++;
3630  tag->tidlength += wordCount * 2;
3631  }
3632  if ( (ret != ERR_NONE) && !((ret == ERR_CHIP_HEADER) && (tag->tid[wordPtr*2])== 0x03))
3633  {
3634  tag->tidlength = 0x1;
3635  tag->tid[0] = 0xFD;
3636  }
3637  }
3638  else if ( (ret == ERR_CHIP_HEADER) && (tag->tid[0] == 0x03) )// Memory Overrun? TID shorter than 4 Words
3639  {
3640  APPLOG("ERROR Headerbit=%hhx\n", tag->tid[0]);
3641  wordCount = 1;
3642  while (wordPtr < (TIDLENGTH/2))
3643  {
3644  ret = gen2ReadFromTag(tag, MEM_TID, wordPtr, wordCount, (tag->tid + (wordPtr*2)));
3645  if (ret != ERR_NONE) {break;}
3646  wordPtr++;
3647  tag->tidlength += wordCount * 2;
3648  }
3649  if ( (ret != ERR_NONE) && !((ret == ERR_CHIP_HEADER) && (tag->tid[wordPtr*2])== 0x03))
3650  {
3651  tag->tidlength = 0x1;
3652  tag->tid[0] = 0xFE;
3653  }
3654  }
3655  else
3656  {
3657  tag->tidlength = 0x1;
3658  tag->tid[0] = 0xFF;
3659  }
3660  return ret;
3661 
3662 }
3663 #if RUN_ON_AS3993
3664 
3672 {
3673  if ( adaptiveQ )
3674  {
3675  u16 slots = 1 << gen2qbegin;
3676  APPLOG("slots:%x; tags: %x", slots, num_of_tags);
3677  if ((slots <= (2.0 * num_of_tags)) && (gen2qbegin < MAXGEN2Q))
3678  {
3679  gen2qbegin++;
3680  APPLOG("q++: ");
3681  }
3682  else if (((double)slots/2) > (2.0 * num_of_tags) && (gen2qbegin > 0) )
3683  {
3684  gen2qbegin--;
3685  APPLOG("q--: ");
3686  }
3687  else
3688  {
3689  APPLOG("q==: ");
3690  }
3691 
3692  APPLOG("New q %hhx\n", gen2qbegin);
3693  }
3694 }
3695 #endif
static u8 adjustmentUpThreshold
static void checkAndSetSession(u8 newSession)
void callConfigTxRx(void)
s8 as3993TxRxGen2Bytes(u8 cmd, u8 *txbuf, u16 txbits, u8 *rxbuf, u16 *rxbits, u8 norestime, u8 followCmd, u8 waitTxIrq)
Definition: as3993.c:1180
void callInventory6B(void)
s8 iso6bWrite(u8 *uid, u8 addr, u8 data, u8 *buffer)
Issue WRITE command according to ISO18000-6 to write a specified number of bytes to a memory location...
Definition: iso6b.c:291
u16 readerInitStatus
static u16 listeningTime
ISO6B protocol header file.
void as3993EnterPowerStandbyMode()
Enter the standby power down mode: EN is high, stby is high and rf_on bit is low. ...
Definition: as3993.c:835
static u8 usedAntenna
#define GEN2_COD_MILLER8
Definition: gen2.h:124
u16 slowTimerValue()
Definition: timer.c:48
u16 as3993GetReflectedPowerNoiseLevel(void)
Definition: as3993.c:1153
Main error codes. Please add your application specific error codes in your application starting with ...
void callStartStop(void)
Declaration of low level functions provided by the as3993 series chips.
void callReadFromTag6B(void)
s8 gen2LockTag(Tag *tag, const u8 *mask_action, u8 *tag_reply)
Definition: gen2.c:485
void callAutoTuner(void)
struct callFunction call_fkt_[CALL_FKT_SIZE]
static struct CmdBuffer cmdBuffer
This file provides declarations for tuner related functions.
#define SESSION_GEN2
Definition: appl_commands.c:74
void as3993EnterPowerNormalMode()
Enter the normal power mode: EN is high, stby and rf_on bits are low.
Definition: as3993.c:805
static s8 rssiThreshold
static int num_selects
void insertBitStream(u8 *dest, u8 const *source, u8 len, u8 bitpos)
Definition: global.c:71
void callWriteToTag6B(void)
s8 gen2KillTag(Tag const *tag, u8 const *password, u8 rfu, u8 recom, u8 *tag_error)
Definition: gen2.c:519
static struct gen2Config gen2Configuration
void callAntennaPower(void)
#define POWER_NORMAL
Definition: appl_commands.c:84
void slowTimerStart()
Definition: timer.c:38
unsigned gen2SearchForTags(Tag *tags_, u8 maxtags, u8 q, u8 addRounds, u8 queryAdjustUpTh, u8 queryAdjustDownTh, BOOL(*cbContinueScanning)(void), BOOL singulate, BOOL toggleSession, s8(*followTagCommand)(Tag *tag))
Definition: gen2.c:679
int doCyclicInventory(void)
static u8 readerPowerDownMode
u8 epc[EPCLENGTH]
Definition: as3993_public.h:66
#define ERR_REQUEST
Definition: errno.h:50
u8 gen2qbegin
#define TUNER_CIN
#define MAXGEN2Q
Definition: global.h:79
This file provides platform (board) specific macros and declarations.
This file provides declarations for global helper functions.
s8 iso6bRead(u8 *uid, u8 addr, u8 *buffer)
Issue READ command according to ISO18000-6 and stores the result in a buffer.
Definition: iso6b.c:229
static TuningTable tuningTable __attribute__((far))
#define POWER_NORMAL_RF
Definition: appl_commands.c:86
static u8 adjustmentRounds
static u8 num_of_tags
void tunerOneHillClimb(const TunerConfiguration *config, TunerParameters *p, u16 maxSteps)
Definition: tuner.c:332
unsigned gen2SearchForTagsAutoAck(Tag *tags_, u8 maxtags, u8 q, BOOL(*cbContinueScanning)(void), BOOL singulate, BOOL toggleSession, s8(*followTagCommand)(Tag *tag))
Definition: gen2.c:861
This file is the include file for the timer.c file.
static void powerDownReader(void)
void callSelectTag(void)
void callLockUnlockTag(void)
#define MEM_TID
Definition: gen2.h:141
#define ERR_NOMEM
Definition: errno.h:46
u8 tid[TIDLENGTH]
Definition: as3993_public.h:78
void gen2Close(void)
Close a session.
Definition: gen2.c:1174
#define MAX_SELECTS
Definition: appl_commands.c:79
s8 gen2AccessTag(Tag const *tag, u8 const *password)
Definition: gen2.c:438
#define MAXTAG
Definition: global.h:77
s8 as3993GetSensitivity()
Definition: as3993.c:921
void callTunerTable(void)
static BOOL continueCheckTimeout()
#define SWITCH_ANTENNA(x)
Definition: platform.h:228
static u8 cyclicInventory
static u8 currentSession
void tunerMultiHillClimb(const TunerConfiguration *config, TunerParameters *res)
Definition: tuner.c:356
static u8 adjustmentDownThreshold
void callInventoryGen2(void)
void as3993SingleWrite(u8 address, u8 value)
Definition: as3993.c:500
void callWriteToTag(void)
static u16 inventoryDelay
void callInventoryGen2Internal()
s8 gen2QueryMeasureRSSI(u8 *agc, u8 *log_rssis, s8 *irssi, s8 *qrssi)
Perform a gen2 QUERY command and measure received signal strength.
Definition: gen2.c:205
s8 gen2WriteWordToTag(Tag const *tag, u8 memBank, u32 wordPtr, u8 const *databuf, u8 *tag_error)
Definition: gen2.c:566
#define GEN2_LF_40
Definition: gen2.h:113
#define TUNER_COUT
void iso6bClose()
Close a session.
Definition: iso6b.c:113
void as3993SetBaseFrequency(u8 regs, u32 frequency)
Definition: as3993.c:633
Freq Frequencies
void gen2Select(struct gen2SelectParams *p)
Definition: gen2.c:142
static u16 scanTuningInterval
static u32 guiMinFreq
#define GEN2_COD_MILLER4
Definition: gen2.h:123
void iso6bOpen()
Open a session.
Definition: iso6b.c:94
Tag * selectedTag
static u8 maxSendingLimitTimedOut
#define GEN2_ERR_ACCESS
Definition: gen2.h:181
#define TUNER_CLEN
void callGenericCommand(void)
#define TARI_125
Definition: gen2.h:132
void tunerSetTuning(const TunerConfiguration *config, u8 cin, u8 clen, u8 cout)
Definition: tuner.c:428
u8 pc[2]
Definition: as3993_public.h:64
void as3993EnterPowerNormalRfMode()
Enter the normal power mode with rf on. EN is high, stby bit is low and rf_on bit is high...
Definition: as3993.c:820
static struct gen2SelectParams selParams[MAX_SELECTS]
void as3993AntennaPower(u8 on)
Definition: as3993.c:875
static u8 tagDataAvailable
u8 readRegister(u8 addr, u16 *txSize, u8 *txData)
void tunerTraversal(const TunerConfiguration *config, TunerParameters *res)
Definition: tuner.c:385
void callConfigGen2(void)
u8 readRegisters(u16 *txSize, u8 *txData)
static u8 readTIDinInventoryRound
Configuration file for all AS99x firmware.
Tag tags_[MAXTAG]
#define APPLOG(...)
Definition: appl_commands.c:94
#define APPLOGDUMP(...)
Definition: appl_commands.c:95
void callReadFromTag(void)
static u8 fastInventory
static s8 inventoryResult
void callWrongCommand(void)
static u16 maxSendingTime
void tunerSetCap(const TunerConfiguration *config, u8 component, u8 val)
Definition: tuner.c:166
static u8 guiActiveProfile
void gen2Open(const struct gen2Config *config)
Open a session.
Definition: gen2.c:1169
#define POWER_DOWN
Definition: appl_commands.c:82
void as3993SingleCommand(u8 command)
Definition: as3993.c:448
#define TIDLENGTH
Definition: global.h:67
#define ERR_NONE
Definition: errno.h:45
static void powerUpReader(void)
void callReaderConfig(void)
u8 as3993SingleRead(u8 address)
Definition: as3993.c:475
#define MAXFREQ
Definition: global.h:73
u16 as3993GetReflectedPower(void)
Definition: as3993.c:1126
This file is the include file for the appl_commands.c file.
static u32 guiMaxFreq
u8 commands(u8 protocol, u16 rxSize, const u8 *rxData, u16 *txSize, u8 *txData)
s8 gen2ReadTID(Tag *tag)
void callKillTag(void)
serial output log declaration file
u16 tunerGetReflected(void)
Definition: tuner.c:211
#define TARI_25
Definition: gen2.h:133
void slowTimerStop()
Definition: timer.c:53
#define POWER_STANDBY
Definition: appl_commands.c:88
#define MAXTUNE
Definition: global.h:75
s8 iso6bInventoryRound(Tag *tags, u8 maxtags, u8 mask, u8 *filter, u8 startaddress)
Definition: iso6b.c:117
#define GEN2_LF_256
Definition: gen2.h:116
u8 handle[2]
Definition: as3993_public.h:70
Declaration of public functions provided by the AS3993 series chips.
#define SESSION_ISO6B
Definition: appl_commands.c:76
#define GEN2_OK
Definition: gen2.h:179
void as3993ExitPowerStandbyMode()
Exit the standby power down mode.
Definition: as3993.c:846
static u16 currentFreqIdx
void as3993ExitPowerNormalMode()
Exit the normal power mode.
Definition: as3993.c:816
#define CMD_INVENTORY_GEN2
Definition: appl_commands.h:88
void callConfigPA(void)
static u8 addToTuningTable(void)
static u16 tuningCounter
u8 sendTagData(u8 *protocol, u16 *txSize, u8 *txData, u16 remainingSize)
#define TREXT_ON
Definition: gen2.h:128
static u16 maxSendingLimit
void as3993EnterPowerDownMode()
Enter the power down mode by setting EN pin to low, saving registers beforehand.
Definition: as3993.c:715
static void adaptSlotCounter(int num_of_tags)
void callInventoryParams(void)
static u16 idleTime
static u8 scanRetuningLevel
static u8 rssiMode
This file provides declarations for functions for the GEN2 aka ISO6c protocol.
static u8 guiNumFreqs
#define GEN2_ERR_CHANNEL_TIMEOUT
Definition: gen2.h:183
#define TREXT_OFF
Definition: gen2.h:127
void callAntennaTuner(void)
void as3993ExitPowerDownMode()
Exit the power down mode by setting EN pin to high, restoring registers afterwards.
Definition: as3993.c:747
static BOOL adaptiveQ
void as3993ExitPowerNormalRfMode()
Exit the normal power mode with rf on.
Definition: as3993.c:831
s8 gen2ReadFromTag(Tag *tag, u8 memBank, u32 wordPtr, u8 wordCount, u8 *destbuf)
Definition: gen2.c:611
void callChangeFreq(void)
#define ERR_PARAM
Definition: errno.h:52
u8 writeRegister(u8 addr, u8 value, u16 *txSize, u8 *txData)
static u8 autoAckMode