41 #if EPCDEBUG && (USE_LOGGER == LOGGER_ON)
43 #define EPCLOGDUMP dbgHexDump
47 #define EPCLOGDUMP(...)
52 #define EPC_QUERYREP 0
56 #define EPC_QUERY 0x08
58 #define EPC_QUERYADJUST 0x09
60 #define EPC_SELECT 0x0A
64 #define EPC_REQRN 0xC1
68 #define EPC_WRITE 0xC3
74 #define EPC_ACCESS 0xC6
76 #define EPC_BLOCKWRITE 0xC7
78 #define EPC_BLOCKERASE 0xC8
80 #define EPC_BLOCKPERMALOCK 0xC9
82 #define GEN2_RESET_TIMEOUT 10
87 struct gen2InternalConfig{
88 struct gen2Config config;
103 static struct gen2InternalConfig gen2IntConfig;
122 static u8 gen2InsertEBV(u32 value, u8 *p, u8 bitpos)
131 static void gen2GetAgcRssi(u8 *agc, u8 *rssi)
144 #if !RUN_ON_AS3980 // no select on AS3980 available
145 u16 len = p->mask_len;
156 buf_[0] = ((
EPC_SELECT<<4)&0xF0) | ((p->target<<1)&0x0E) | ((p->action>>2)&0x01);
157 buf_[1] = ((p->action<<6)&0xC0) | ((p->mem_bank<<4)&0x30);
158 ebvLen = gen2InsertEBV(p->mask_address,
buf_+1, 4);
159 buf_[1+ebvLen] = ((p->mask_len>>4)&0x0F);
160 buf_[2+ebvLen] = ((p->mask_len<<4)&0xF0);
163 for (j = len; j >= 8 ; j -= 8, mask++)
165 buf_[i] |= 0x0F & (*mask >> 4);
167 buf_[i] = 0xF0 & (*mask << 4);
172 buf_[i] |= ((p->truncation<<3)&0x08);
175 { jLeftBits = 0xFF << (8-j);
177 buf_[i] |= (jLeftBits >> 4) & (*mask >> 4);
178 buf_[i+1] = (jLeftBits << 4) & (*mask << 4);
180 posTruncbit = (p->truncation & 0x01) <<(7-j);
181 buf_[i] |= (posTruncbit >> 4) ;
182 buf_[i+1] |= (posTruncbit << 4) ;
185 len += 21 + ebvLen * 8;
193 static void gen2PrepareQueryCmd(u8 *buf, u8 q)
195 buf[0] = ((gen2IntConfig.DR<<5)&0x20) |
196 ((gen2IntConfig.config.miller<<3)&0x18) |
197 ((gen2IntConfig.config.trext<<2)&0x04) |
198 ((gen2IntConfig.config.sel<<0)&0x03);
199 buf[1] = ((gen2IntConfig.config.session<<6)&0xC0) |
200 ((gen2IntConfig.config.target<<5)&0x20) |
218 gen2PrepareQueryCmd(
buf_, 0);
232 gen2GetAgcRssi(agc, log_rssis);
261 static s8 gen2Slot(
Tag *tag, u8 qCommand, u8 q, BOOL fast, u8 followCommand)
272 case AS3993_CMD_QUERY:
273 gen2PrepareQueryCmd(
buf_, q);
282 if (ret == AS3993_ERR_NORES)
284 EPCLOG(
" query -> noresp\n");
289 EPCLOG(
" query -> err %hhx\n", ret);
296 rxlen =
sizeof(
buf_)*8;
300 if (ret < 0 || rxlen < 16)
302 EPCLOG(
" ack rx rest(pc=%hhx) -> err %hhx\n", tag->
pc[0], ret);
306 tag->
epclen = (rxlen+7)/8-4;
308 tag->
epclen = (rxlen+7)/8-2;
316 gen2GetAgcRssi(&tag->
agc, &tag->
rssi);
317 if (((tag->
pc[0] & 0xF8) >> 2) != tag->
epclen)
328 gen2GetAgcRssi(&tag->
agc, &tag->
rssi);
331 EPCLOG(
" reqrn -> err %hhx\n", ret);
334 if (((tag->
pc[0] & 0xF8) >> 2) != tag->
epclen)
336 EPCLOG(
" reqrn -> err %hhx\n", ret);
353 rxlen =
sizeof(
buf_)*8;
356 case AS3993_CMD_QUERY:
357 gen2PrepareQueryCmd(
buf_, q);
366 if (ret == AS3993_ERR_NORES)
368 EPCLOG(
" query -> noresp\n");
377 if (ret < 0 || rxlen < 16)
379 EPCLOG(
" auto ack rx (pc=%hhx) -> err %hhx\n", tag->
pc[0], ret);
383 tag->
epclen = (rxlen+7)/8-4;
385 tag->
epclen = (rxlen+7)/8-2;
393 gen2GetAgcRssi(&tag->
agc, &tag->
rssi);
394 if (((tag->
pc[0] & 0xF8) >> 2) != tag->
epclen)
406 gen2GetAgcRssi(&tag->
agc, &tag->
rssi);
409 EPCLOG(
" reqrn -> err %hhx\n", ret);
413 if (((tag->
pc[0] & 0xF8) >> 2) != tag->
epclen)
447 for (count = 0; count < 2; count++)
456 buf_[1] = password[0] ^ temp_rn16[0];
457 buf_[2] = password[1] ^ temp_rn16[1];
465 EPCLOG(
"access failed, tx-ret: %hhx\n", ret);
470 if ((tagResponse[1] != tag->
handle[1]) ||
471 (tagResponse[0] != tag->
handle[0]))
473 EPCLOG(
"handle not correct\n");
477 if (count ==0)
EPCLOG(
"first part of access ok\n");
478 if (count ==1)
EPCLOG(
"second part of access ok\n");
497 buf_[1] = mask_action[0];
498 buf_[2] = mask_action[1];
500 buf_[3] = ((mask_action[2] ) & 0xF0);
505 for (count=0; count<6; count++)
514 if (ERR_CHIP_HEADER == ret && rxbits) *tag_reply =
buf_[0];
519 s8
gen2KillTag(
Tag const * tag, u8
const * password, u8 rfu, u8 recom, u8* tag_error)
525 u8 cmd = AS3993_CMD_TRANSMCRC;
526 u8 no_resp_time = gen2IntConfig.no_resp_time;
529 for (count = 0; count < 2; count++)
539 cmd = AS3993_CMD_TRANSMCRCEHEAD;
547 buf_[1] = password[0] ^ temp_rn16[0];
548 buf_[2] = password[1] ^ temp_rn16[1];
550 buf_[3] = ((rfu << 5) & 0xE0);
561 if(ERR_CHIP_HEADER == error && rxbits) *tag_error =
buf_[0];
567 u8
const * databuf, u8 * tag_error)
578 EPCLOG(
"wDtT %hx%hx->%hhx%hhx\n",wordPtr,databuf[0],databuf[1]);
587 buf_[1] = (memBank << 6) & 0xC0;
588 ebvlen = gen2InsertEBV(wordPtr, &
buf_[1], 6);
590 datab = databuf[0] ^ temp_rn16[0];
591 buf_[1+ebvlen] |= ((datab >> 2) & 0x3F);
592 buf_[2+ebvlen] = (datab << 6) & 0xC0;
594 datab = databuf[1] ^ temp_rn16[1];
595 buf_[2+ebvlen] |= ((datab >> 2) & 0x3F);
596 buf_[3+ebvlen] = (datab << 6) & 0xC0;
602 if (ERR_CHIP_HEADER == ret && rxbits) *tag_error =
buf_[0];
603 EPCLOG(
" smo %hhx\n",ret);
606 EPCLOG(
" rxbits = %hx\n",rxbits);
612 u8 wordCount, u8 *destbuf)
614 u16 bit_count = (wordCount * 2 + 4) * 8 + 1;
619 buf_[1] = (memBank << 6) & 0xC0;
620 ebvlen = gen2InsertEBV(wordPtr, &
buf_[1], 6);
621 buf_[1+ebvlen] |= ((wordCount >> 2) & 0x3F);
622 buf_[2+ebvlen] = (wordCount << 6) & 0xC0;
625 ret =
as3993TxRxGen2Bytes(AS3993_CMD_TRANSMCRCEHEAD,
buf_, 34+8*ebvlen, destbuf, &bit_count, gen2IntConfig.no_resp_time, 0, 1);
627 EPCLOG(
"bank=%hhx, w=%hx%hx, wc = %hhx ret=%hhx\n",memBank,wordPtr,wordCount,ret);
632 void gen2PrintGen2Settings()
636 LOG(
"Gen2 registers:\n");
642 void gen2PrintEPC(
Tag *tag)
645 EPCLOG(
"Print PC %hhx %hhx\n",tag->
pc[0], tag->
pc[1]);
647 for (count=0; count<(tag->
epclen); count++)
659 EPCLOG(
"TAG %hhx:\n",tagNr);
662 EPCLOG(
"Number of read bytes: %d\n",epclen+2);
666 while (count < epclen)
684 , u8 queryAdjustDownTh
685 , BOOL (*cbContinueScanning)(
void)
688 , s8 (*followTagCommand)(
Tag *tag)
693 u8 cmd = AS3993_CMD_QUERY;
695 u8 rounds = addRounds + 1;
702 followCmd = AS3993_CMD_QUERYREP;
707 if (followTagCommand != NULL)
716 EPCLOG(
"Searching for Tags, maxtags=%hhd, q=%hhd\n",maxtags,q);
717 EPCLOG(
"-------------------------------\n");
719 for (i=0; i < maxtags; i++)
721 tags_[i].
rn16[0] = 0;
722 tags_[i].
rn16[1] = 0;
728 if ( gen2Slot(tags_+num_of_tags, cmd, q, !singulate, followCmd) == 1)
730 if (followTagCommand != NULL)
732 followTagCommand(tags_+num_of_tags);
746 if (num_of_tags >= maxtags)
750 EPCLOG(
"next slot, command: %x\n", cmd);
753 if ((cmd == AS3993_CMD_QUERYADJUSTUP) || (cmd == AS3993_CMD_QUERYADJUSTNIC) ||(cmd == AS3993_CMD_QUERYADJUSTDOWN))
756 if (gen2IntConfig.config.tari ==
TARI_25)
760 else if (gen2IntConfig.config.tari ==
TARI_125)
771 switch (gen2Slot(tags_+num_of_tags, cmd, q, !singulate, followCmd))
776 cmd = AS3993_CMD_QUERYREP;
782 cmd = AS3993_CMD_QUERYREP;
783 if (followTagCommand != NULL)
785 followTagCommand(tags_+num_of_tags);
786 cmd = AS3993_CMD_QUERYREP;
792 cmd = AS3993_CMD_QUERYREP;
797 goOn = cbContinueScanning();
798 }
while (slot_count && goOn );
800 EPCLOG(
"q=%hhx, collisions=%x, num_of_tags=%x",q,collisions,num_of_tags);
809 if(( collisions >= (1UL<<q) * (queryAdjustUpTh/100))&& (q <8) )
813 cmd = AS3993_CMD_QUERYADJUSTUP;
815 else if( collisions < (1UL<<q) * (queryAdjustDownTh/100) )
819 cmd = AS3993_CMD_QUERYADJUSTDOWN;
824 cmd = AS3993_CMD_QUERYADJUSTNIC;
833 }
while(num_of_tags < maxtags && rounds && cbContinueScanning() );
842 if (followTagCommand == NULL)
854 EPCLOG(
"-------------------------------\n");
855 EPCLOG(
"%hx Tags found", num_of_tags);
864 , BOOL (*cbContinueScanning)(
void)
867 , s8 (*followTagCommand)(
Tag *tag)
874 u8 cmd = AS3993_CMD_QUERY;
883 followCmd = AS3993_CMD_QUERYREP;
886 EPCLOG(
"Searching for Tags with autoACK, maxtags=%hhd, q=%hhd\n",maxtags, q);
887 EPCLOG(
"-------------------------------\n");
889 if (followTagCommand != NULL)
907 for (i=0; i < maxtags; i++)
909 tags_[i].
rn16[0] = 0;
910 tags_[i].
rn16[1] = 0;
918 if (
gen2SlotAutoAck(tags_+num_of_tags, cmd, q, !singulate, followCmd) == 1)
920 if (followTagCommand != NULL)
922 followTagCommand(tags_+num_of_tags);
929 if (num_of_tags >= maxtags)
934 switch (
gen2SlotAutoAck(tags_+num_of_tags, cmd, q, !singulate, followCmd))
939 cmd = AS3993_CMD_QUERYREP;
946 cmd = AS3993_CMD_QUERYREP;
947 if (followTagCommand != NULL)
949 followTagCommand(tags_+num_of_tags);
950 cmd = AS3993_CMD_QUERYREP;
956 cmd = AS3993_CMD_QUERYREP;
961 goOn = cbContinueScanning();
962 }
while (slot_count && goOn );
975 if (followTagCommand == NULL)
987 EPCLOG(
"-------------------------------\n");
988 EPCLOG(
"%hx Tags found", num_of_tags);
999 u8 session = config->session;
1000 gen2IntConfig.DR = 1;
1001 gen2IntConfig.config = *config;
1005 gen2IntConfig.config.trext =
TREXT_ON;
1007 switch (config->linkFreq) {
1015 if (gen2IntConfig.config.tari ==
TARI_25)
1017 else if (gen2IntConfig.config.tari ==
TARI_625)
1030 if (gen2IntConfig.config.tari ==
TARI_625)
1032 gen2IntConfig.DR = 0;
1042 if (gen2IntConfig.config.tari ==
TARI_25)
1044 else if (gen2IntConfig.config.tari ==
TARI_125)
1057 if (gen2IntConfig.config.tari ==
TARI_625)
1059 gen2IntConfig.DR = 0;
1070 if (gen2IntConfig.config.tari ==
TARI_25)
1085 if (gen2IntConfig.config.tari ==
TARI_625)
1087 gen2IntConfig.DR = 0;
1098 if (gen2IntConfig.config.tari ==
TARI_25)
1111 if (gen2IntConfig.config.tari ==
TARI_125)
1113 gen2IntConfig.DR = 0;
1124 if (gen2IntConfig.config.tari ==
TARI_25)
1126 if (gen2IntConfig.config.tari ==
TARI_125)
1147 gen2IntConfig.DR = 0;
1152 reg[0] |= gen2IntConfig.config.tari;
1153 reg[1] = (reg[1] & ~0x0F)
1154 | gen2IntConfig.config.miller
1155 | (gen2IntConfig.config.trext<<3);
1157 gen2IntConfig.no_resp_time = reg[5];
1162 reg[0] = (reg[0] & ~0x03) | gen2IntConfig.config.session;
1165 reg[0] = reg[0] & ~0x07;
1180 return &(gen2IntConfig.config);
s8 as3993TxRxGen2Bytes(u8 cmd, u8 *txbuf, u16 txbits, u8 *rxbuf, u16 *rxbits, u8 norestime, u8 followCmd, u8 waitTxIrq)
Declaration of low level functions provided by the as3993 series chips.
static s8 gen2SlotAutoAck(Tag *tag, u8 qCommand, u8 q, BOOL fast, u8 followCommand)
s8 gen2LockTag(Tag *tag, const u8 *mask_action, u8 *tag_reply)
void as3993WaitForResponse(u16 waitMask)
void insertBitStream(u8 *dest, u8 const *source, u8 len, u8 bitpos)
s8 gen2KillTag(Tag const *tag, u8 const *password, u8 rfu, u8 recom, u8 *tag_error)
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))
unsigned gen2SearchForTagsAutoAck(Tag *tags_, u8 maxtags, u8 q, BOOL(*cbContinueScanning)(void), BOOL singulate, BOOL toggleSession, s8(*followTagCommand)(Tag *tag))
void gen2PrintTagInfo(Tag *tag, u8 epclen, u8 tagNr)
This file is the include file for the timer.c file.
void as3993ContinuousWrite(u8 address, u8 *buf, s8 len)
void gen2Close(void)
Close a session.
s8 gen2AccessTag(Tag const *tag, u8 const *password)
void gen2Configure(const struct gen2Config *config)
Set the link frequency.
static s8 gen2ReqRNHandleChar(u8 const *handle, u8 *dest_handle)
void as3993SingleWrite(u8 address, u8 value)
struct gen2Config * getGen2IntConfig()
Returns the Gen2 Configuration.
s8 gen2QueryMeasureRSSI(u8 *agc, u8 *log_rssis, s8 *irssi, s8 *qrssi)
Perform a gen2 QUERY command and measure received signal strength.
void u32ToEbv(u32 value, u8 *ebv, u8 *len)
s8 gen2WriteWordToTag(Tag const *tag, u8 memBank, u32 wordPtr, u8 const *databuf, u8 *tag_error)
void gen2Select(struct gen2SelectParams *p)
void as3993AntennaPower(u8 on)
Configuration file for all AS99x firmware.
void gen2Open(const struct gen2Config *config)
Open a session.
void as3993SingleCommand(u8 command)
u8 as3993SingleRead(u8 address)
serial output log declaration file
This file provides declarations for functions for the GEN2 aka ISO6c protocol.
static u8 buf_[8+EPCLENGTH+PCLENGTH+CRCLENGTH]
void as3993ContinuousRead(u8 address, s8 len, u8 *readbuf)
s8 gen2ReadFromTag(Tag *tag, u8 memBank, u32 wordPtr, u8 wordCount, u8 *destbuf)