as3993 ST25RU3993 Firmware
as3993.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  */
34 #include "as3993_config.h"
35 #include "platform.h"
36 #include "as3993.h"
37 #include "as3993_public.h"
38 #include "global.h"
39 #include "logger.h"
40 #include "timer.h"
41 #include "gen2.h"
42 #include "stdlib.h"
43 #include "string.h"
44 #include "Compiler.h"
45 #if VERBOSE_INIT
46 #include <math.h>
47 #endif
48 
50 #define READ 0x40
51 
53 #define AS3980WAITTIME 510
54 
56 #if RUN_ON_AS3980
57 #define WaitForAS3980() {\
58  delay_ms(AS3980WAITTIME); \
59  }
60 #else
61 #define WaitForAS3980() {}
62 #endif
63 
67 volatile u16 as3993Response = 0;
68 
71 static u8 as3993PowerDownRegs[AS3993_REG_ICD+6];
72 
75 static u8 gChipRevisionZero = 1;
76 
77 #if VERBOSE_INIT
78 static void as3993PrintRfpLine(void)
79 {
80  s16 val;
81  s16 ch_val_i;
82  s16 ch_val_q;
83  s16 rf;
84 
85  val = as3993GetReflectedPower( );
86  ch_val_i = ((s8)(val&0xff));
87  ch_val_q = ((s8)((val>>8)&0xff));
88  rf = sqrt(ch_val_i * ch_val_i + ch_val_q * ch_val_q);
89  LOG("rf=%hx ",rf);
90 
91  LOG("%hx", val);
92 
93  for (val = -32; val <= 32 ; val ++)
94  {
95  if ( val == rf )
96  {
97  LOG("A");
98  continue;
99  }
100  if ( val == ch_val_i && val == ch_val_q)
101  {
102  LOG("X");
103  continue;
104  }
105  if ( val == ch_val_i )
106  {
107  LOG("I");
108  continue;
109  }
110  if ( val == ch_val_q )
111  {
112  LOG("Q");
113  continue;
114  }
115  if ( val == 0 )
116  {
117  LOG("0");
118  continue;
119  }
120  LOG(" ");
121  }
122  LOG("\n");
123 }
124 #endif
125 
126 /*------------------------------------------------------------------------- */
127 u16 as3993Initialize(u32 baseFreq)
128 {
129  u8 myBuf[4];
130 
132 
133 #if AS3993DEBUG
134  LOG(CHIP" Init\n");
135  myBuf[0] = AS3993_REG_DEVICEVERSION;
136  LOG("version reg %hhx->",myBuf[0]);
137  myBuf[0] = as3993SingleRead(myBuf[0]);
138  LOG("%hhx\n",myBuf[0]);
139 #endif
140 #if AS3993_DO_SELFTEST
141  // check SPI communication
142  myBuf[0] = 0x55;
143  myBuf[1] = 0xAA;
144  myBuf[2] = 0xFF;
145  myBuf[3] = 0x00;
146  as3993ContinuousWrite(AS3993_REG_MODULATORCONTROL1, myBuf, 4);
147  memset(myBuf, 0x33, sizeof(myBuf));
148  as3993ContinuousRead(AS3993_REG_MODULATORCONTROL1, 4,myBuf);
149  if ((myBuf[0]!=0x55) ||
150  (myBuf[1]!=0xAA) ||
151  (myBuf[2]!=0xFF) ||
152  (myBuf[3]!=0x00))
153  {
154  LOG("%hhx %hhx %hhx %hhx\n", myBuf[0], myBuf[1], myBuf[2], myBuf[3]);
155  return 1; // data bus interface pins not working
156  }
157 
158  // check EN pin + SPI communication
160  as3993ContinuousRead(AS3993_REG_MODULATORCONTROL1, 4, myBuf);
161  if ((myBuf[0]==0x55) ||
162  (myBuf[1]==0xAA) ||
163  (myBuf[2]==0xFF) ||
164  (myBuf[3]==0x00))
165  {
166  LOG("EN pin failed\n");
167  return 2; /* enable pin not working */
168  }
169 
170  // check IRQ line
171  delay_ms(1);
172  WaitForAS3980();
173  as3993SingleWrite(AS3993_REG_IRQMASK1, 0x20);
174  // set up 48Byte transmission, but we supply less, therefore a fifo underflow IRQ is produced
175  as3993SingleWrite(AS3993_REG_TXLENGTHUP, 0x03);
176  as3993SingleCommand(AS3993_CMD_TRANSMCRC);
177  as3993ContinuousWrite(AS3993_REG_FIFO,myBuf,4);
178  as3993ContinuousWrite(AS3993_REG_FIFO,myBuf,4);
179  as3993ContinuousWrite(AS3993_REG_FIFO,myBuf,4);
180  as3993ContinuousWrite(AS3993_REG_FIFO,myBuf,4);
181  as3993ContinuousWrite(AS3993_REG_FIFO,myBuf,4);
182  as3993ContinuousWrite(AS3993_REG_FIFO,myBuf,4);
183 
184  as3993WaitForResponse(RESP_FIFO);
185  if ( !(as3993GetResponse() & RESP_FIFO) )
186  {
187  return 3;
188  }
189 // as3993SingleWrite(AS3993_REG_IRQMASK1, 0x00);
190 // as3993SingleWrite(AS3993_REG_IRQMASK2, 0x40);
191 // as3993SingleCommand(AS3993_CMD_TRIGGERADCCON);
192 // as3993WaitForResponse(RESP_END_CMD);
193 // if ( !(as3993GetResponse() & RESP_END_CMD) )
194 // return 3; /* Interrupt pin not working */
195 
196  as3993ClrResponse();
197 
199  as3993SingleCommand(AS3993_CMD_HOP_TO_MAIN_FREQUENCY);
200 #endif
201 
202  /* chip status control 0x00 */
203  /*STBY - - - - AGC REC RF */
204 //#if RADON || FEMTO2 || FEMTO2_1
205  /* 0 0 0 0 0 1 1 0 = 0x06 */
206  as3993SingleWrite(AS3993_REG_STATUSCTRL, 0x06);
207 //#else
208 // /* 0 0 0 0 0 0 1 0 = 0x02 */
209 // as3993SingleWrite(AS3993_REG_STATUSCTRL, 0x02);
210 //#endif
211 
212  /*protocl control register 0x01 */
213  /*RX_CRC_N DIR_MODE AutoACK1 AutoACK2 - PROT1 PROT0 */
214  /* 0 0 0 0 0 0 0 = 0x00 */
215  as3993SingleWrite(AS3993_REG_PROTOCOLCTRL, 0x00);
216 
217  /* TX options 0x02 */
218  /* - - TxOne1 TxOne0 - Tari2 Tari1 Tari0 */
219 
220 #if FEMTO2 || FETMO2_1
221  /* 0 0 1 1 0 0 1 0 = 0x30 */
222  as3993SingleWrite(AS3993_REG_TXOPTIONS, 0x32);
223 #else
224  /* 0 0 1 1 0 0 0 0 = 0x30 */
225  as3993SingleWrite(AS3993_REG_TXOPTIONS, 0x30);
226 #endif
227  /* RX options register is set by gen2 configuration */
228  /* TRcal high + low register is set by gen2 configuration */
229 
230  /* PLL Main REgister 0x17*/
231  /* use 100kHz as pll reference as we use ETSI as default */
232  as3993SingleWrite(AS3993_REG_PLLMAIN1, 0x54);
233 
234 #if AS3993DEBUG
235  as3993SingleWrite(AS3993_REG_MEASUREMENTCONTROL, 0x80); // enable debug signals on OAD
236 #else
237  as3993SingleWrite(AS3993_REG_MEASUREMENTCONTROL, 0x00);
238 #endif
239 
240  /*MISC1 0x0D */
241  /*hs_output hs_oad miso_pd2 miso_pd1 open_dr s_mix iadd_sink2 iadd_sink1 */
242  /* 1 0 0 0 0 0 0 0 = 0xC0 */
243  as3993SingleWrite(AS3993_REG_MISC1, 0x00
244 #if !RADON
245  | 0x80
246 #endif
247 #if AS3993DEBUG
248  | 0x40
249 #endif
250 #ifdef SINGLEINP
251  | 0x04
252 #endif
253  );
254 
255 #ifdef SINGLEINP
256 #if VERBOSE_INIT
257  LOG("SINLGEINP\n");
258 #endif
259 #endif
260 
261 #ifdef BALANCEDINP
262 #if VERBOSE_INIT
263  LOG("BALANCED INP\n");
264 #endif
265 #endif
266 
267 #ifdef INTPA
268  /*REGULATOR and PA Bias 0x0B */
269  /*pa_bias1-0 rvs_rf2-1 rvs2-0 */
270  /* 1 0 0 1 1 0 1 1 = 0x1B */
271  as3993SingleWrite(AS3993_REG_REGULATORCONTROL, 0xBF);
272 
273  /*RF Output and LO Control Register 0x0C */
274  /*eTX7 - eTX0 */
275  /* 0 1 1 0 1 0 0 0 = 0x68 */
276  /* int PA, PA 14mA */
277  as3993SingleWrite(AS3993_REG_RFOUTPUTCONTROL, 0x68);
278 
279  /* Modulator Control Register 1 0x13 */
280  /* - MAIN_MOD AUXMOD tpreset use_corr ELFP ASKRATE1 ASKRATE0 */
281  /* 0 1 0 0 0 0 0 0 =0x40 */
282  myBuf[0] = 0x40;
283  /* Modulator Control Register 2 0x14 */
284  /*ook_ask PR_ASK MOD_DEP5-MOD_DEP0 */
285  /* 1 1 0 1 1 1 0 1 = 0xDD */
286  myBuf[1] = 0xDD;
287  /* Modulator Control Register 3 0x15 */
288  /*TRFON1 TRFON0 lin_mode TXLEVEL4-TXLEVEL0 */
289  /* 0 0 0 0 0 1 1 1 =0x07 */
290  myBuf[2] = 0x01;
291  as3993ContinuousWrite(AS3993_REG_MODULATORCONTROL1, myBuf, 3);
292 #if VERBOSE_INIT
293  LOG("INTPA\n");
294 #endif
295 #endif
296 
297 #ifdef EXTPA
298  /*REGULATOR and PA Bias 0x0B */
299  /*pa_bias1-0 rvs_rf2-1 rvs2-0 */
300  /* 0 0 0 1 1 0 1 1 = 0x1B */
301  as3993SingleWrite(AS3993_REG_REGULATORCONTROL, 0x1B);
302 
303  /*RF Output and LO Control Register 0x0C */
304  /*eTX7 - eTX0 */
305  /* 0 0 0 0 0 0 1 0 = 0x58 */
306  /* int pa, PA 14mA */
307  as3993SingleWrite(AS3993_REG_RFOUTPUTCONTROL, 0x22);
308 
309  /*Modulator Control Register 1 0x13 */
310  /* - MAIN_MOD AUXMOD tpreset use_corr ELFP ASKRATE1 ASKRATE0 */
311  /* 0 0 1 0 0 0 0 0 =0x20 */
312  myBuf[0] = 0x20;
313  /*Modulator Control Register 2 0x14 */
314 #if RADON
315  /*ook_ask PR_ASK MOD_DEP5-MOD_DEP0 */
316  /* 1 0 0 1 1 1 0 1 = 0xDD */
317  myBuf[1] = 0x9D;
318 #else
319  /*ook_ask PR_ASK MOD_DEP5-MOD_DEP0 */
320  /* 1 1 0 1 1 1 0 1 = 0xDD */
321  myBuf[1] = 0xDD;
322 #endif
323  /*Modulator Control Register 3 0x15 */
324  /*TRFON1 TRFON0 lin_mode TXLEVEL4-TXLEVEL0 */
325 #if RADON
326  /* 0 0 0 0 0 1 1 0 =0x06 */
327  myBuf[2] = 0x06;
328 #else
329  /* 0 0 0 0 0 0 0 1 =0x01 */
330  myBuf[2] = 0x01;
331 #endif
332  as3993ContinuousWrite(AS3993_REG_MODULATORCONTROL1, myBuf, 3);
333 #if VERBOSE_INIT
334  LOG("EXTPA\n");
335 #endif
336 #endif
337 
338  /*RF Output and LO Control Register 0x0C */
339  /*LF_R3<2-1> LF_C3<5-3> cp<2-0> */
340  /* 0 0 1 1 0 1 0 1 = 0x25 */
341  /* 30kOhm, 160pF, 1500uA */
342  as3993SingleWrite(AS3993_REG_CPCONTROL, 0x35);
343 
344 #ifdef INTVCO
345 #if FEMTO2 || FEMTO2_1 || RADON
346  as3993SingleWrite(AS3993_REG_MISC2, 0x40); /* external TCXO AC, no clsys */
347 #else
348  as3993SingleWrite(AS3993_REG_MISC2, 0x00); // no clsys
349 #endif
350 
351 #if VERBOSE_INIT
352  LOG("INTVCO\n");
353 #endif
354 #endif
355 
356  /*Enable Interrupt Register Register 1 0x35 */
357  /*e_irq_TX e_irq_RX e_irq_fifo e_irq_err e_irq_header RFU e_irq_AutoAck e_irq_noresp */
358  /* 1 1 1 1 1 1 1 1 = 0xFF */
359  as3993SingleWrite(AS3993_REG_IRQMASK1, 0xFF);
360  /*Enable Interrupt Register Register 2 0x35 */
361  /*e_irq_ana e_irq_cmd RFU RFU RFU e_irq_err1 e_irq_err2 e_irq_err3 */
362  /* 0 0 0 0 0 1 1 1 = 0x07 */
363  as3993SingleWrite(AS3993_REG_IRQMASK2, 0x07);
364 
365  /*RX Length Register 1 0x3A */
366  /*RX_crc_n2 fifo_dir_irq2 rep_irg2 auto_errcode_RXl RXl11-RXl8 */
367  /* 0 0 0 1 0 0 0 0 = 0x10 */
368  as3993SingleWrite(AS3993_REG_RXLENGTHUP, 0x10);
369 
370  /* Give base freq. a reasonable value */
371  as3993SetBaseFrequency(AS3993_REG_PLLMAIN1, baseFreq);
372  as3993SetSensitivity(-AS3993_NOM_SENSITIVITY);
373 
374 #if AS3993_DO_SELFTEST
375  /* Now that the chip is configured with correct ref frequency the PLL
376  should lock */
377  delay_ms(20);
378  myBuf[0] = as3993SingleRead(AS3993_REG_AGCANDSTATUS);
379  if (!(myBuf[0] & 0x03))
380  {
381  return 4; /* Crystal not stable */
382  }
383  if (!(myBuf[0] & 0x02))
384  {
385  return 5; /* PLL not locked */
386  }
387 
388 #if VERBOSE_INIT
389  {
390  /* Do this now, after everyting else should be configured */
391  u32 i = 100;
392  while(i--){
393  as3993PrintRfpLine();
394  }
395  for( i = 860000UL; i< 960000UL ;i+=1000UL)
396  {
397  LOG("%hx%hx ",(u16)(i>>16),(u16)(i&0xffff));
398  as3993SetBaseFrequency(AS3993_REG_PLLMAIN1, i);
399  as3993PrintRfpLine();
400  }
401  }
402 #endif
403 #endif
404 
405  return 0;
406 }
407 
408 /*------------------------------------------------------------------------- */
415 #if RUN_ON_AS3993 || RUN_ON_AS3980
416 void INTERRUPT as3993Isr(void)
417 {
418  u8 regs[2];
419  static u8 addr = READ | AS3993_REG_IRQSTATUS1;
420  if (gChipRevisionZero)
421  delay_us(30);
422 
423  do{
424  CLREXTIRQ();
425  writeReadAS3993Isr(&addr, 1, regs, 2);
426 #ifdef RFDATARECEIVELED
427  if (AS3993_IRQ1_RX == (regs[0] & (AS3993_IRQ1_RX | AS3993_IRQ1_RXERR))) RFDATARECEIVELED(LEDON);
428  else RFDATARECEIVELED(LEDOFF);
429 #endif
430  as3993Response |= (regs[0] | (regs[1] << 8));
431  }while(AS3993_PORT_INT);
432 
433  //LOG("isr: %hx\n", as3993Response);
434 }
435 #endif
436 
437 /*------------------------------------------------------------------------- */
439 {
440  u8 version;
441  version = as3993SingleRead(AS3993_REG_DEVICEVERSION);
442  if (version > 0x60)
443  gChipRevisionZero = 0;
444  return version;
445 }
446 
447 /*------------------------------------------------------------------------- */
448 void as3993SingleCommand(u8 command)
449 {
450  DISEXTIRQ();
451  writeReadAS3993( &command, 1, 0 , 0 , STOP_SGL, 1);
452  ENEXTIRQ();
453 }
454 
455 /*------------------------------------------------------------------------- */
456 void as3993ContinuousRead(u8 address, s8 len, u8 *readbuf)
457 {
458  DISEXTIRQ();
459  address |= READ;
460  writeReadAS3993( &address, 1, readbuf , len , STOP_CONT, 1);
461  ENEXTIRQ();
462 }
463 
464 /*------------------------------------------------------------------------- */
465 void as3993FifoRead(s8 len, u8 *readbuf)
466 {
467  static u8 address = AS3993_REG_FIFO | READ ;
468  DISEXTIRQ();
469  writeReadAS3993( &address, 1, readbuf , len , STOP_CONT, 1);
470  ENEXTIRQ();
471 }
472 
473 /* Function is called from interrupt and normal level, therefore this
474  function must be forced to be reentrant on Keil compiler. */
475 u8 as3993SingleRead(u8 address)
476 {
477  u8 readdata;
478 
479  DISEXTIRQ();
480  if (address >= 0x23 && address <= 0x26) /* Test reg access */
481  {
482  u8 cmd = 0xb0;
483  writeReadAS3993( &cmd, 1, 0 , 0 , STOP_NONE, 1);
484  }
485  address |= READ;
486  writeReadAS3993( &address, 1, &readdata , 1 , STOP_SGL, 1);
487 
488  ENEXTIRQ();
489  return(readdata);
490 }
491 
492 void as3993ContinuousWrite(u8 address, u8 *buf, s8 len)
493 {
494  DISEXTIRQ();
495  writeReadAS3993( &address, 1, 0 , 0 , STOP_NONE, 1);
496  writeReadAS3993( buf, len, 0 , 0 , STOP_CONT, 0);
497  ENEXTIRQ();
498 }
499 
500 void as3993SingleWrite(u8 address, u8 value)
501 {
502  u8 buf[2];
503  buf[0] = address;
504  buf[1] = value;
505  DISEXTIRQ();
506  if (address >= 0x23 && address <= 0x26) /* Test reg access */
507  {
508  u8 cmd = 0xb0;
509  writeReadAS3993( &cmd, 1, 0 , 0 , STOP_NONE, 1);
510  }
511  writeReadAS3993( buf, 2, 0 , 0 , STOP_SGL, 1);
512  ENEXTIRQ();
513 }
514 
515 /*------------------------------------------------------------------------- */
516 void as3993CommandContinuousAddress(u8 *command, u8 com_len,
517  u8 address, u8 *buf, u8 buf_len)
518 {
519  DISEXTIRQ();
520  writeReadAS3993( command, com_len, 0 , 0 , STOP_NONE, 1);
521  writeReadAS3993( &address, 1, 0 , 0 , STOP_NONE, 0);
522  writeReadAS3993( buf, buf_len, 0 , 0 , STOP_CONT, 0);
523  ENEXTIRQ();
524 }
525 
526 void as3993WaitForResponseTimed(u16 waitMask, u16 counter)
527 {
528  while (((as3993Response & waitMask) == 0) && (counter))
529  {
530  delay_ms(1);
531  counter--;
532  }
533  if (counter==0)
534  {
535 #if !USE_UART_STREAM_DRIVER
536  LOG("TI O T %x %x\n", as3993Response, waitMask);
537 #endif
538  as3993Response = RESP_NORESINTERRUPT;
539  }
540 
541 }
542 
543 void as3993WaitForResponse(u16 waitMask)
544 {
545  u16 counter;
546  counter=0;
547  while (((as3993Response & waitMask) == 0) && (counter < WAITFORRESPONSECOUNT))
548  {
549  counter++;
550  delay_us(WAITFORRESPONSEDELAY);
551  }
552  if (counter >= WAITFORRESPONSECOUNT)
553  {
554 #if !USE_UART_STREAM_DRIVER
555  LOG("TI O response: %x, mask: %x\n", as3993Response, waitMask);
556 #endif
557  as3993Response = RESP_NORESINTERRUPT;
558  }
559 // else
560 // LOG("TI ok response: %x, mask: %x\n", as3993Response, waitMask);
561 }
562 
563 void as3993WaitForResponseFAST(u16 waitMask)
564 {
565  u16 counter;
566  counter=0;
567  while (((as3993Response & waitMask) == 0) && (counter < (10*WAITFORRESPONSECOUNT)))
568  {
569  counter++;
570  delay_us(1);
571  }
572  if (counter >= WAITFORRESPONSECOUNT)
573  {
574  as3993Response = RESP_NORESINTERRUPT;
575  }
576 }
577 
578 #if RUN_ON_AS3993
580 {
581  DISEXTIRQ();
582  as3993ClrResponse();
583 
584  as3993SingleCommand(AS3993_CMD_DIRECT_MODE);
585 
586  setPortDirect();
587 }
588 
590 {
591  setPortNormal();
592 
593  as3993ClrResponse();
594  ENEXTIRQ();
595 }
596 #endif
597 static void as3993LockPLL(void)
598 {
599  u8 buf;
600  u8 var;
601  u16 i;
602 
603  u8 vco_voltage;
604  buf = as3993SingleRead(AS3993_REG_STATUSPAGE);
605  buf &= ~0x30;
606  buf |= 0x10; /* have vco_ri in aglstatus */
607  as3993SingleWrite(AS3993_REG_STATUSPAGE, buf);
608 
609  buf = as3993SingleRead(AS3993_REG_VCOCONTROL);
610  buf |= 0x80; /* set mvco bit */
611  as3993SingleWrite(AS3993_REG_VCOCONTROL, buf);
612  delay_ms(1); /* give PLL some settling time, should be around 500us */
613 
614  vco_voltage = as3993SingleRead(AS3993_REG_AGL) & 0x07;
615 
616  buf &= ~0x80; /* reset mvco bit */
617  as3993SingleWrite(AS3993_REG_VCOCONTROL, buf);
618 
619  if ( vco_voltage <= 1 || vco_voltage >= 6 )
620  {
621  i=0;
622  do
623  {
624  i++;
625  as3993SingleCommand(AS3993_CMD_VCO_AUTO_RANGE);
626  delay_ms(10); /* Please keep in mind, that the Auto Bit procedure will take app. 6 ms whereby the locktime of PLL is just 400us */
627  var=as3993SingleRead(AS3993_REG_AGCANDSTATUS);
628  } while ( (var & 0x02)==0 && (i<3));/* wait for PLL to be locked and give a few attempts */
629  }
630 }
631 
632 /*------------------------------------------------------------------------- */
633 void as3993SetBaseFrequency(u8 regs, u32 frequency)
634 {
635  u8 buf[3];
636  u8 statusreg;
637  u16 ref=0, i, j, x, reg_A,reg_B;
638  u32 divisor;
639 
640  statusreg = as3993SingleRead(AS3993_REG_STATUSCTRL);
641  as3993SingleWrite(AS3993_REG_STATUSCTRL, statusreg & 0xfe);
642  if (regs == AS3993_REG_PLLMAIN1)
643  {
644  as3993ContinuousRead(AS3993_REG_PLLMAIN1, 3, buf);
645  switch (buf[0]& 0x70)
646  {
647 
648  case 0x40: {
649  ref=125;
650  } break;
651  case 0x50: {
652  ref=100;
653  } break;
654  case 0x60: {
655  ref=50;
656  } break;
657  case 0x70: {
658  ref=25;
659  } break;
660  default: {
661  ref=0;
662  }
663  }
664  }
665 
666  if (ref == 0)
667  {
668  return;
669  }
670 
671  divisor=frequency/ref;
672 
673  i = 0x3FFF & (divisor >> 6); /* division by 64 */
674  x = (i<<6)+ i;
675  if (divisor > x)
676  {
677  x += 65;
678  i++;
679  }
680  x -= divisor;
681  j = i;
682  do
683  {
684  if (x >= 33)
685  {
686  i--;
687  x -= 33;
688  }
689  if (x >= 32)
690  {
691  j--;
692  x -= 32;
693  }
694  } while (x >= 32);
695  if (x > 16)
696  { /* subtract 32 from x if it is larger than 16 */
697  x -= 32; /* this yields more closely matched A and B values */
698  j--;
699  }
700 
701  reg_A = i - x;
702  reg_B = j + x;
703  if (regs==AS3993_REG_PLLMAIN1)
704  {
705  buf[0] = (buf[0] & 0xF0) | ((u8)((reg_B >> 6) & 0x0F));
706  buf[1] = (u8)((reg_B << 2) & 0xFC) | (u8)((reg_A >> 8) & 0x03);
707  buf[2] = (u8)reg_A;
708 
709  as3993ContinuousWrite(AS3993_REG_PLLMAIN1, buf, 3);
710  }
711  as3993LockPLL();
712  as3993SingleWrite(AS3993_REG_STATUSCTRL, statusreg);
713 }
714 
716 {
717  u8 i;
718  int count;
719 
720  if (!ENABLE) return;
721 
722  DISEXTIRQ();
723  CLREXTIRQ();
724  /* Switch off antenna */
725  as3993PowerDownRegs[0] = as3993SingleRead(AS3993_REG_STATUSCTRL);
726  as3993SingleWrite(0, as3993PowerDownRegs[0] & (~0x03));
727  for (i=1; i<AS3993_REG_ICD; i++)
728  {
729  if (i!=0x0F)
731  }
732  as3993PowerDownRegs[AS3993_REG_ICD+0] = as3993SingleRead(AS3993_REG_MIXOPTS);
733  as3993PowerDownRegs[AS3993_REG_ICD+1] = as3993SingleRead(AS3993_REG_STATUSPAGE);
734  as3993PowerDownRegs[AS3993_REG_ICD+2] = as3993SingleRead(AS3993_REG_IRQMASK1);
735  as3993PowerDownRegs[AS3993_REG_ICD+3] = as3993SingleRead(AS3993_REG_IRQMASK2);
736  as3993PowerDownRegs[AS3993_REG_ICD+4] = as3993SingleRead(AS3993_REG_TXSETTING);
737  as3993PowerDownRegs[AS3993_REG_ICD+5] = as3993SingleRead(AS3993_REG_RXLENGTHUP);
738  /* Wait for antenna being switched off */
739  count = 500;
740  while(count-- && (as3993SingleRead(AS3993_REG_AGCANDSTATUS) & 0x04))
741  {
742  delay_ms(1);
743  }
744  EN(LOW);
745 }
746 
748 {
749  u8 i;
750  u8 buf[2];
751 
752  if (ENABLE) return;
753 
754  EN(HIGH);
755  delay_us(10);
757 
758  /* Do not switch on antenna before PLL is locked.*/
759  as3993SingleWrite(0, as3993PowerDownRegs[0] & (~0x03));
760  for (i=1; i<AS3993_REG_ICD; i++)
761  {
762  if (i!=0x0F)
764  }
765  as3993SingleWrite(AS3993_REG_MIXOPTS, as3993PowerDownRegs[AS3993_REG_ICD+0]);
766  as3993SingleWrite(AS3993_REG_STATUSPAGE, as3993PowerDownRegs[AS3993_REG_ICD+1]);
767  as3993SingleWrite(AS3993_REG_IRQMASK1, as3993PowerDownRegs[AS3993_REG_ICD+2]);
768  as3993SingleWrite(AS3993_REG_IRQMASK2, as3993PowerDownRegs[AS3993_REG_ICD+3]);
769  as3993SingleWrite(AS3993_REG_TXSETTING, as3993PowerDownRegs[AS3993_REG_ICD+4]);
770  as3993SingleWrite(AS3993_REG_RXLENGTHUP, as3993PowerDownRegs[AS3993_REG_ICD+5] & 0xF0);
771  delay_us(300);
772  as3993LockPLL();
773  as3993SingleWrite(AS3993_REG_STATUSCTRL, as3993PowerDownRegs[0]);
774 
775  buf[0] = as3993SingleRead(AS3993_REG_AGCANDSTATUS);
776  if (!(buf[0] & 0x03))
777  {
778  LOG("/******** Crystal not stable */\n");
779  }
780  if (!(buf[0] & 0x02))
781  {
782  LOG("/********* PLL not locked */\n");
783  }
784  WaitForAS3980();
785  CLREXTIRQ();
786  ENEXTIRQ();
787 }
788 
789 void as3993Reset(void)
790 {
792  delay_ms(1);
794 }
795 
797 {
798  EN(LOW);
799  delay_ms(1);
800  EN(HIGH);
801  delay_us(10);
803 }
804 
806 {
807  u8 stat;
808 
809  as3993ExitPowerDownMode(); //ensure that EN is high
810  stat = as3993SingleRead(AS3993_REG_STATUSCTRL);
811  stat &= 0x7F;
812  as3993SingleWrite(AS3993_REG_STATUSCTRL, stat);
814 }
815 
817 {
818 }
819 
821 {
822  u8 stat;
823 
824  as3993ExitPowerDownMode(); //ensure that EN is high
825  stat = as3993SingleRead(AS3993_REG_STATUSCTRL);
826  stat &= 0x7F;
827  as3993SingleWrite(AS3993_REG_STATUSCTRL, stat);
829 }
830 
832 {
833 }
834 
836 {
837  u8 stat;
838 
839  as3993ExitPowerDownMode(); //ensure that EN is high
841  stat = as3993SingleRead(AS3993_REG_STATUSCTRL);
842  stat |= 0x80;
843  as3993SingleWrite(AS3993_REG_STATUSCTRL, stat);
844 }
845 
847 {
848  u8 stat;
849 
850  as3993ExitPowerDownMode(); //ensure that EN is high
851  stat = as3993SingleRead(AS3993_REG_STATUSCTRL);
852  stat &= ~0x80;
853  as3993SingleWrite(AS3993_REG_STATUSCTRL, stat);
854 }
855 
857 {
858  u8 osc_ok, version;
859  u8 myBuf[2];
860  u16 count = 0;
861 
862  do
863  {
864  version = as3993ReadChipVersion() & 0x60; //ignore revision
865  osc_ok = as3993SingleRead(AS3993_REG_AGCANDSTATUS);
866  count++;
867  }
868  while (!(((version == 0x60) && (osc_ok & 0x01)) || (count > 250))); //wait for startup
869  delay_us(500);
870  as3993ContinuousRead(AS3993_REG_IRQSTATUS1, 2, &myBuf[0]); // ensure that IRQ bits are reset
871  as3993ClrResponse();
872  delay_ms(2); // give AS3993 some time to fully initialize
873 }
874 
875 void as3993AntennaPower( u8 on)
876 {
877  u8 val;
878  unsigned count = 200;
879  val = as3993SingleRead(AS3993_REG_STATUSCTRL);
880 
881  if (on)
882  {
883  if ((val & 0x03) == 0x03)
884  return;
885  val |= 3;
886 
887 #ifdef EXTPA
888  EN_PA(PA_ON);
889  delay_us(300); /* Give PA LDO time to get to maximum power */
890 #endif
891  as3993SingleWrite(AS3993_REG_STATUSCTRL, val);
892  while (count-- && ( (as3993SingleRead(AS3993_REG_AGCANDSTATUS) & 0x04) != 0x04 ) )
893  {
894  //LOG("RF field not stable !\n");
895  delay_us(100);
896  }
897  }
898  else
899  {
900  if ((val & 0x03) != 0x03)
901  return;
902  val &= ~3;
903  as3993SingleWrite(AS3993_REG_STATUSCTRL, val);
904  /* Wait for antenna being switched off */
905  count = 500;
906  while(count-- && (as3993SingleRead(AS3993_REG_AGCANDSTATUS) & 0x04))
907  {
908  delay_us(100);
909  }
910 #ifdef EXTPA
911  EN_PA(PA_OFF);
912 #endif
913 #ifdef RFDATARECEIVELED
914  RFDATARECEIVELED(LEDOFF);
915 #endif
916  }
917 
918  if(on) delay_ms(2); //0.5 Rise Time, 1.5 Settling Time /* according to standard we have to wait 1.5ms before issuing commands */
919 }
920 
922 {
923  s8 sensitivity = 0;
924  u8 reg0a, reg0d, gain;
925 
926  reg0d = as3993SingleRead(AS3993_REG_MISC1);
927  reg0a = as3993SingleRead(AS3993_REG_RXMIXERGAIN);
928 
929  if ((reg0d & 0x04))
930  { /* single ended input mixer*/
931  sensitivity -= AS3993_NOM_SENSITIVITY;
932  if ( (reg0a & 0x03) == 0x03 ) /* 6dB increase */
933  {
934  sensitivity -= 6;
935  }
936  else if ( (reg0a & 0x03) == 0x00 ) /* 6dB decrease */
937  {
938  sensitivity += 6;
939  }
940  }
941  else
942  { /* differential input mixer */
943  sensitivity -= AS3993_NOM_SENSITIVITY;
944  if ( reg0a & 0x01 ) /* mixer attenuation */
945  {
946  sensitivity += 8;
947  }
948  if ( reg0a & 0x02) /* differential mixer gain increase */
949  {
950  sensitivity -= 10;
951  }
952  }
953  gain = (reg0a >> 6) * 3;
954  if ( reg0a & 0x20 )
955  { /* RX Gain direction: increase */
956  sensitivity -= gain;
957  }
958  else
959  {
960  sensitivity += gain;
961  }
962  return sensitivity;
963 }
964 
965 s8 as3993SetSensitivity( s8 minimumSignal )
966 {
967  u8 reg0d, reg0a, gain;
968 
969  reg0a = as3993SingleRead(AS3993_REG_RXMIXERGAIN);
970  reg0d = as3993SingleRead(AS3993_REG_MISC1);
971 
972  reg0a &= 0x1C;
973  if ((reg0d & 0x04))
974  { /* single ended input mixer*/
975  minimumSignal += AS3993_NOM_SENSITIVITY;
976  if ( minimumSignal >= 6 )
977  {
978  minimumSignal -= 6; /* 6dB gain decrease */
979  reg0a |= 0;
980  }
981  else if ( minimumSignal <= -6 )
982  {
983  minimumSignal += 6; /* 6dB gain increase */
984  reg0a |= 3;
985  }
986  else
987  reg0a |= 1; /* nominal gain */
988  }
989  else
990  { /* differential input mixer */
991  minimumSignal += AS3993_NOM_SENSITIVITY;
992  if ( minimumSignal >= 8 ) /* mixer attenuation */
993  {
994  minimumSignal -= 8;
995  reg0a |= 1;
996  }
997  if ( minimumSignal <= -10 ) /* differential mixer gain increase */
998  {
999  minimumSignal += 10;
1000  reg0a |= 2;
1001  }
1002  }
1003  if ( minimumSignal > 0)
1004  {
1005  reg0a &= ~0x20; /* RX Gain direction: decrease */
1006  gain = minimumSignal / 3;
1007  if ( gain>3 ) gain = 3;
1008  minimumSignal -= gain*3;
1009 
1010  }
1011  else
1012  {
1013  reg0a |= 0x20; /* RX Gain direction: increase */
1014  gain = (-minimumSignal+2) / 3;
1015  if ( gain>3 ) gain = 3;
1016  minimumSignal += gain*3;
1017  }
1018  reg0a |= (gain<<6);
1019  as3993SingleWrite(AS3993_REG_RXMIXERGAIN, reg0a);
1020  return minimumSignal;
1021 }
1022 
1023 #ifdef EXTPA
1024 void as3993GetRSSIMaxSensitive( u16 num_of_ms_to_scan, u8 *rawIQ)
1025 {
1026  u8 regValRXFilter, regValRXMixerGain = 0;
1027  u8 regMixOpt = 0;
1028  //RX Filters to match
1029  regValRXFilter = as3993SingleRead(AS3993_REG_RXFILTER);
1030  as3993SingleWrite(AS3993_REG_RXFILTER, 0x80);
1031  //RX GAIN maximum
1032  regValRXMixerGain = as3993SingleRead(AS3993_REG_RXMIXERGAIN);
1033  as3993SetSensitivity(-90);
1034  //Change Mixer Options
1035  regMixOpt = as3993SingleRead(AS3993_REG_MIXOPTS);
1036  as3993SingleWrite(AS3993_REG_MIXOPTS, 0x39);
1037  //delay_us(200);
1038  as3993GetRSSI(num_of_ms_to_scan, rawIQ);
1039  //Restore Settings
1040  as3993SingleWrite(AS3993_REG_RXFILTER, regValRXFilter);
1041  as3993SingleWrite(AS3993_REG_RXMIXERGAIN, regValRXMixerGain);
1042  as3993SingleWrite(AS3993_REG_MIXOPTS, regMixOpt);
1043 
1044 }
1045 
1046 void as3993GetRSSI( u16 num_of_ms_to_scan, u8 *rawIQ)
1047 {
1048  u8 rawVal,valI, valQ = 0;
1049  u8 regValStatusCtrl, regValProtoCtrl = 0;
1050  u8 regValIRQ1Mask, regValStatusPage, regValStatus = 0;
1051  u8 sumRSSI = 0;
1052  u8 singelMeasVal = 0;
1053  u16 num_of_reads = num_of_ms_to_scan * 2 + 1; // 500us delay
1054  unsigned count = 200;
1055 
1056  //PLL check and RF POWER check
1057  regValStatus = as3993SingleRead(AS3993_REG_AGCANDSTATUS);
1058 
1059  while (count-- && ( (as3993SingleRead(AS3993_REG_AGCANDSTATUS) & 0x02) != 0x02 ) )
1060  {
1061  LOG("PLL not locked!\n");
1062  delay_us(100);
1063  }
1064  //Receiver ON and Transmitter ON
1065  regValStatusCtrl = as3993SingleRead(AS3993_REG_STATUSCTRL);
1066  as3993SingleWrite(AS3993_REG_STATUSCTRL, regValStatusCtrl | 0x03 );
1067  //dir_mode = 1
1068  regValProtoCtrl = as3993SingleRead(AS3993_REG_PROTOCOLCTRL);
1069  as3993SingleWrite(AS3993_REG_PROTOCOLCTRL, regValProtoCtrl | 0x40);
1070  //e_irq_noresp = 0
1071  regValIRQ1Mask = as3993SingleRead(AS3993_REG_IRQMASK1);
1072  as3993SingleWrite(AS3993_REG_IRQMASK1, regValIRQ1Mask & 0xFE);
1073  //Real RSSI
1074  regValStatusPage = as3993SingleRead(AS3993_REG_STATUSPAGE);
1075  as3993SingleWrite(AS3993_REG_STATUSPAGE, regValStatusPage & 0xF0);
1076 
1077  //PLL check and RF POWER check
1078  regValStatus = as3993SingleRead(AS3993_REG_AGCANDSTATUS);
1079  count = 200;
1080  while (count-- && ( (as3993SingleRead(AS3993_REG_AGCANDSTATUS) & 0x04) != 0x04 ) )
1081  {
1082  LOG("RF field not stable !\n");
1083  delay_us(100);
1084  }
1085  delay_ms(2);
1086  //Send Direct Command
1087  as3993SingleCommand(AS3993_CMD_ENABLERX);
1088  //Wait and read raw data
1089  while (num_of_reads--)
1090  {
1091  delay_us(500);
1092  rawVal = as3993SingleRead(AS3993_REG_RSSILEVELS);
1093  valI = rawVal&0xf;
1094  valQ = ((rawVal >> 4) & 0xf);
1095  //LOG("rawVal: %hhx Q: %hhx I: %hhx \n",rawVal, valI, valQ );
1096  singelMeasVal = (rawVal&0x0f) + (rawVal>>4);
1097  if (singelMeasVal >= sumRSSI)
1098  {
1099  sumRSSI = singelMeasVal;
1100  *rawIQ = rawVal;
1101  }
1102  }
1103 
1104  //Restore Settings
1105  as3993SingleCommand(AS3993_CMD_BLOCKRX);
1106  as3993SingleWrite(AS3993_REG_STATUSPAGE, regValStatusPage);
1107  as3993SingleWrite(AS3993_REG_IRQMASK1, regValIRQ1Mask);
1108  as3993SingleWrite(AS3993_REG_PROTOCOLCTRL, regValProtoCtrl);
1109  as3993SingleWrite(AS3993_REG_STATUSCTRL, regValStatusCtrl);
1110  return;
1111 }
1112 #endif
1113 
1114 /* ADC Values are in sign magnitude representation -> convert */
1115 #define CONVERT_ADC_TO_NAT(A) (((A)&0x80)?((A)&0x7f):(0 - ((A)&0x7f)))
1116 s8 as3993GetADC( void )
1117 {
1118  s8 val;
1119  as3993SingleCommand(AS3993_CMD_TRIGGERADCCON);
1120  delay_us(20); /* according to spec */
1121  val = as3993SingleRead(AS3993_REG_ADC);
1122  val = CONVERT_ADC_TO_NAT(val);
1123  return val;
1124 }
1125 
1127 {
1128  u16 value;
1129  s8 adcVal;
1130  u8 regMeas, regStatus;
1131  regStatus = as3993SingleRead(AS3993_REG_STATUSCTRL);
1132  regMeas = as3993SingleRead(AS3993_REG_MEASUREMENTCONTROL);
1133  as3993SingleWrite(AS3993_REG_MEASUREMENTCONTROL, regMeas & ~0xC0); /* disable the OAD pin outputs */
1134 
1135  as3993SingleWrite(AS3993_REG_STATUSCTRL, regStatus | 0x03 ); /* Receiver and transmitter are on */
1136  as3993SingleCommand(AS3993_CMD_BLOCKRX); /* Reset the receiver - otherwise the I values seem to oscillate */
1137  as3993SingleCommand(AS3993_CMD_ENABLERX);
1138  as3993SingleWrite(AS3993_REG_MEASUREMENTCONTROL, 0x01); /* Mixer A DC */
1139  delay_us(300); /* settling time */
1140  value = as3993GetADC();
1141  as3993SingleWrite(AS3993_REG_MEASUREMENTCONTROL, 0x02); /* Mixer B DC */
1142  delay_us(300); /* settling time */
1143  adcVal = as3993GetADC();
1144  as3993SingleCommand(AS3993_CMD_BLOCKRX); /* Disable the receiver since we enabled it before */
1145 
1146  /* mask out shifted in sign bits */
1147  value = (value & 0xff) | (adcVal << 8);
1148  as3993SingleWrite(AS3993_REG_MEASUREMENTCONTROL, regMeas);
1149  as3993SingleWrite(AS3993_REG_STATUSCTRL, regStatus);
1150  return value;
1151 }
1152 
1154 {
1155  u16 value;
1156  s8 i_0, q_0;
1157  u8 regMeas, regStatus;
1158  regStatus = as3993SingleRead(AS3993_REG_STATUSCTRL);
1159  regMeas = as3993SingleRead(AS3993_REG_MEASUREMENTCONTROL);
1160  as3993SingleWrite(AS3993_REG_MEASUREMENTCONTROL, regMeas & ~0xC0); /* disable the OAD pin outputs */
1161 
1162  /* First measure the offset which might appear with disabled antenna */
1163  as3993SingleWrite(AS3993_REG_STATUSCTRL, (regStatus | 2) & (~1) ); /* Field off, receiver on */
1164  as3993SingleCommand(AS3993_CMD_BLOCKRX); /* Reset the receiver - otherwise the I values seem to oscillate */
1165  as3993SingleCommand(AS3993_CMD_ENABLERX);
1166  as3993SingleWrite(AS3993_REG_MEASUREMENTCONTROL, 0x01); /* Mixer A DC */
1167  delay_us(300); /* settling time */
1168  i_0 = as3993GetADC();
1169  as3993SingleWrite(AS3993_REG_MEASUREMENTCONTROL, 0x02); /* Mixer B DC */
1170  delay_us(300); /* settling time */
1171  q_0 = as3993GetADC();
1172 
1173  value = (i_0 & 0xff) | (q_0 << 8);
1174  as3993SingleWrite(AS3993_REG_MEASUREMENTCONTROL, regMeas);
1175  as3993SingleWrite(AS3993_REG_STATUSCTRL, regStatus);
1176  return value;
1177 
1178 }
1179 
1180 s8 as3993TxRxGen2Bytes(u8 cmd, u8 *txbuf, u16 txbits,
1181  u8 *rxbuf, u16 *rxbits,
1182  u8 norestime, u8 followCmd,
1183  u8 waitTxIrq)
1184 {
1185  static u8 currCmd;
1186  u8 buf[2];
1187  u8 rxbytes = 0;
1188  u8 checkRxLength = 0;
1189  u16 rxs = 0;
1190  u8 rxed = 0;
1191  if (rxbits)
1192  {
1193  rxbytes = (*rxbits + 7) / 8;
1194  rxs = *rxbits;
1195  *rxbits = 0;
1196  checkRxLength = 1;
1197  }
1198  if(rxbuf || rxs)
1199  {
1200 #if RUN_ON_AS3993
1201  if ((cmd != AS3993_CMD_QUERYREP) && (cmd != AS3993_CMD_QUERYADJUSTUP)&& (cmd != AS3993_CMD_QUERYADJUSTNIC)&& (cmd != AS3993_CMD_QUERYADJUSTDOWN))
1202  {
1203  as3993SingleWrite(AS3993_REG_RXNORESPONSEWAITTIME, norestime);
1204  }
1205 #else
1206  as3993SingleWrite(AS3993_REG_RXNORESPONSEWAITTIME, norestime);
1207 #endif
1208  }
1209  if (rxs)
1210  {
1211  buf[1] = rxs & 0xff;
1212  buf[0] = ((rxs>>8) & 0x0F) | 0x10; // set auto_errcode_rxl
1213 #if RUN_ON_AS3993
1214  if ((cmd != AS3993_CMD_QUERY)&&(cmd != AS3993_CMD_QUERYREP) && (cmd != AS3993_CMD_QUERYADJUSTUP)&& (cmd != AS3993_CMD_QUERYADJUSTNIC)&& (cmd != AS3993_CMD_QUERYADJUSTDOWN))
1215  {
1216  as3993ContinuousWrite(AS3993_REG_RXLENGTHUP,buf,2);
1217  }
1218 #else
1219  as3993ContinuousWrite(AS3993_REG_RXLENGTHUP,buf,2);
1220 #endif
1221  }
1222  if (txbits)
1223  {
1224  u8 txbytes = (txbits + 7)/8;
1225  u8 totx = txbytes;
1226  if (totx > 24) totx = 24;
1227 
1228  /* set up two bytes tx length register */
1229  buf[1] = (txbits % 8) << 1;
1230  buf[1] |= (txbits / 8) << 4;
1231  buf[0] = txbits / 128;
1232  if (cmd != AS3993_CMD_QUERY)
1233  {
1234  as3993ContinuousWrite(AS3993_REG_TXLENGTHUP,buf,2);
1235  }
1236  as3993CommandContinuousAddress(&cmd, 1, AS3993_REG_FIFO, txbuf, totx);
1237  txbytes -= totx;
1238  txbuf += totx;
1239  while (txbytes)
1240  {
1241  totx = txbytes;
1242  if (totx > 16) totx = 18;
1243 
1244  as3993WaitForResponse(RESP_FIFO);
1245  as3993ClrResponseMask(RESP_FIFO);
1246  as3993ContinuousWrite(AS3993_REG_FIFO,txbuf,totx);
1247  txbytes -= totx;
1248  txbuf += totx;
1249  }
1250  currCmd = cmd;
1251  }
1252  else if (cmd)
1253  {
1254  as3993SingleCommand(cmd);
1255  currCmd = cmd;
1256  }
1257  if (currCmd && waitTxIrq)
1258  {
1259  as3993WaitForResponse(RESP_TXIRQ);
1260  as3993ClrResponseMask(RESP_TXIRQ | RESP_FIFO);
1261  }
1262  if (rxbits && !rxs && !rxbuf)
1263  { /* we do not want to receive any data */
1264  as3993SingleCommand(AS3993_CMD_BLOCKRX);
1265  buf[1] = 0;
1266  buf[0] = 0;
1267  as3993ContinuousWrite(AS3993_REG_RXLENGTHUP,buf,2);
1268  }
1269  if (rxbuf)
1270  {
1271  u8 count;
1272  u16 resp;
1273  if (0xff == norestime)
1274  {
1275  u16 responseTimout = 30;
1276  switch (getGen2IntConfig()->linkFreq)
1277  {
1278  case GEN2_LF_40 : responseTimout = 120; break;
1279  case GEN2_LF_160: responseTimout = 50; break;
1280  case GEN2_LF_213: responseTimout = 40; break;
1281  }
1282  as3993WaitForResponseTimed(RESP_RXDONE_OR_ERROR | RESP_FIFO, responseTimout);
1283  }
1284  else
1285  {
1286  if (getGen2IntConfig()->linkFreq == GEN2_LF_640)
1287  {
1288  as3993WaitForResponseFAST(RESP_RXDONE_OR_ERROR | RESP_FIFO);
1289  }
1290  else
1291  {
1292  as3993WaitForResponse(RESP_RXDONE_OR_ERROR | RESP_FIFO);
1293  }
1294  }
1295  while (as3993GetResponse() & RESP_FIFO &&
1296  !(as3993GetResponse() & RESP_RXIRQ))
1297  {
1298  count = 18;
1299  if (checkRxLength && count > rxbytes)
1300  {
1301 #if AS3993DEBUG
1302  LOG("limiting1 %hhx %hhx resp %hx\n",count,rxbytes,as3993GetResponse());
1303 #endif
1304  count = rxbytes;
1305  }
1306  as3993FifoRead(count, rxbuf);
1307  rxbuf += count;
1308  rxbytes -= count;
1309  rxed += count;
1310  as3993ClrResponseMask(RESP_FIFO);
1311  if (checkRxLength && rxbytes == 0) //we do not want to receive more data
1312  return AS3993_ERR_RXCOUNT;
1313  as3993WaitForResponse(RESP_RXDONE_OR_ERROR | RESP_FIFO);
1314  }
1315  as3993WaitForResponse(RESP_RXDONE_OR_ERROR);
1316  resp = as3993GetResponse();
1317  as3993ClrResponse();
1318  if (followCmd && !(resp & (RESP_NORESINTERRUPT | RESP_RXERR)))
1319  {
1320  switch (getGen2IntConfig()->linkFreq)// prevent violate T2 min
1321  {
1322  case GEN2_LF_40 : delay_us(200); break;
1323  case GEN2_LF_160: delay_us(30); break;
1324  case GEN2_LF_213: delay_us(15); break;
1325  case GEN2_LF_256: delay_us(6); break;
1326  }
1327  as3993SingleCommand(followCmd);
1328  currCmd = followCmd;
1329  }
1330  count = as3993SingleRead(AS3993_REG_FIFOSTATUS) & 0x1F; /*get the number of bytes */
1331  if (checkRxLength && count > rxbytes)
1332  {
1333 #if AS3993DEBUG
1334  LOG("limiting %hhx %hhx\n",count,rxbytes);
1335 #endif
1336  count = rxbytes;
1337  resp |= RESP_RXCOUNTERROR;
1338  }
1339  if (count)
1340  as3993FifoRead(count, rxbuf);
1341 
1342  rxed += count;
1343  if (rxbits)
1344  *rxbits = 8 * rxed;
1345 
1346  if (getGen2IntConfig()->linkFreq == GEN2_LF_40)
1347  {
1348  delay_us(100);
1349  }
1350 #if RUN_ON_AS3980 /* on AS3980 header IRQ is actually 2nd-byte IRQ -> ignore if no
1351  command which expects header bit was sent */
1352  if (currCmd != AS3993_CMD_TRANSMCRCEHEAD)
1353  resp &= ~RESP_HEADERBIT;
1354 #endif
1355  if(resp & (RESP_NORESINTERRUPT | RESP_RXERR | RESP_HEADERBIT | RESP_RXCOUNTERROR))
1356  {
1357 #if AS3993DEBUG
1358  if(resp & RESP_RXERR)
1359  { //log errors (except no response)
1360  //LOG("rx error=%hx , rxed=%hhx , rxlen=%hx\n",resp, rxed);
1361  //LOGDUMP(rxbuf, rxed);
1362  }
1363 #endif
1364  if (resp & RESP_NORESINTERRUPT)
1365  return AS3993_ERR_NORES;
1366  if (resp & RESP_HEADERBIT && currCmd == AS3993_CMD_TRANSMCRCEHEAD)
1367  return AS3993_ERR_HEADER;
1368  //if (resp & RESP_FIFOOVERFLOW) return AS3993_ERR_FIFO_OVER;
1369  if (resp & RESP_RXCOUNTERROR)
1370  {
1371  if (!(resp & RESP_RXERR)) //as3980 produces irq_err2 (without irq_rxerr) if new epc is read 500ms after last one.
1372  {
1373  WaitForAS3980(); // Wait for tx to be re-enabled.
1374  }
1375  return AS3993_ERR_RXCOUNT;
1376  }
1377  if (resp & RESP_PREAMBLEERROR) return AS3993_ERR_PREAMBLE;
1378  if (resp & RESP_CRCERROR) return AS3993_ERR_CRC;
1379  return -1;
1380  }
1381  }
1382  return ERR_NONE;
1383 }
s8 as3993TxRxGen2Bytes(u8 cmd, u8 *txbuf, u16 txbits, u8 *rxbuf, u16 *rxbits, u8 norestime, u8 followCmd, u8 waitTxIrq)
Definition: as3993.c:1180
#define EN(x)
Definition: platform.h:80
void as3993ExitDirectMode()
Leave the direct mode.
Definition: as3993.c:589
void setPortNormal()
Definition: platform.c:479
void as3993EnterPowerStandbyMode()
Enter the standby power down mode: EN is high, stby is high and rf_on bit is low. ...
Definition: as3993.c:835
#define GEN2_LF_640
Definition: gen2.h:118
u16 as3993GetReflectedPowerNoiseLevel(void)
Definition: as3993.c:1153
#define LOW
Definition: global.h:49
#define WAITFORRESPONSECOUNT
Definition: as3993.h:215
Declaration of low level functions provided by the as3993 series chips.
#define READ
Definition: as3993.c:50
#define WAITFORRESPONSEDELAY
Definition: as3993.h:211
void as3993EnterPowerNormalMode()
Enter the normal power mode: EN is high, stby and rf_on bits are low.
Definition: as3993.c:805
void as3993WaitForResponse(u16 waitMask)
Definition: as3993.c:543
#define AS3993DEBUG
Definition: as3993_config.h:67
s8 as3993GetADC(void)
Definition: as3993.c:1116
static u8 gChipRevisionZero
Definition: as3993.c:75
#define STOP_NONE
Definition: platform.h:53
This file provides platform (board) specific macros and declarations.
u16 as3993Initialize(u32 baseFreq)
Definition: as3993.c:127
This file provides declarations for global helper functions.
#define RADON
Definition: as3993_config.h:50
#define CLREXTIRQ()
Definition: platform.h:75
This file is the include file for the timer.c file.
void setPortDirect()
Definition: platform.c:474
void as3993ContinuousWrite(u8 address, u8 *buf, s8 len)
Definition: as3993.c:492
void writeReadAS3993(const u8 *wbuf, u8 wlen, u8 *rbuf, u8 rlen, u8 stopMode, u8 doStart)
Definition: platform.c:442
void writeReadAS3993Isr(const u8 *wbuf, u8 wlen, u8 *rbuf, u8 rlen)
Definition: platform.c:458
static u8 as3993PowerDownRegs[AS3993_REG_ICD+6]
Definition: as3993.c:71
void as3993WaitForResponseTimed(u16 waitMask, u16 counter)
Definition: as3993.c:526
s8 as3993GetSensitivity()
Definition: as3993.c:921
void as3993SingleWrite(u8 address, u8 value)
Definition: as3993.c:500
struct gen2Config * getGen2IntConfig()
Returns the Gen2 Configuration.
Definition: gen2.c:1178
#define LOG(...)
Definition: logger.h:119
#define GEN2_LF_40
Definition: gen2.h:113
void as3993FifoRead(s8 len, u8 *readbuf)
Definition: as3993.c:465
void as3993SetBaseFrequency(u8 regs, u32 frequency)
Definition: as3993.c:633
void as3993Reset(void)
Definition: as3993.c:789
void INTERRUPT as3993Isr(void)
Definition: as3993.c:416
u8 as3993ReadChipVersion(void)
Definition: as3993.c:438
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
void as3993ResetDoNotPreserveRegisters(void)
Definition: as3993.c:796
void as3993AntennaPower(u8 on)
Definition: as3993.c:875
#define GEN2_LF_213
Definition: gen2.h:115
Configuration file for all AS99x firmware.
#define AS3993_IRQ1_RXERR
Definition: as3993.h:148
void as3993WaitForResponseFAST(u16 waitMask)
Definition: as3993.c:563
#define STOP_CONT
Definition: platform.h:57
void as3993SingleCommand(u8 command)
Definition: as3993.c:448
#define AS3993_IRQ1_RX
Definition: as3993.h:152
#define ERR_NONE
Definition: errno.h:45
void as3993CommandContinuousAddress(u8 *command, u8 com_len, u8 address, u8 *buf, u8 buf_len)
Definition: as3993.c:516
u8 as3993SingleRead(u8 address)
Definition: as3993.c:475
u16 as3993GetReflectedPower(void)
Definition: as3993.c:1126
serial output log declaration file
void as3993EnterDirectMode()
Enter the direct mode.
Definition: as3993.c:579
#define ENABLE
Definition: platform.h:217
#define GEN2_LF_256
Definition: gen2.h:116
Declaration of public functions provided by the AS3993 series chips.
#define GEN2_LF_160
Definition: gen2.h:114
void as3993WaitForStartup(void)
after EN goes high the IRQ register has to be read after osc_ok goes high.
Definition: as3993.c:856
void as3993ExitPowerStandbyMode()
Exit the standby power down mode.
Definition: as3993.c:846
void as3993ExitPowerNormalMode()
Exit the normal power mode.
Definition: as3993.c:816
#define DISEXTIRQ()
Definition: platform.h:72
#define ENEXTIRQ()
Definition: platform.h:69
void as3993EnterPowerDownMode()
Enter the power down mode by setting EN pin to low, saving registers beforehand.
Definition: as3993.c:715
#define STOP_SGL
Definition: platform.h:55
This file provides declarations for functions for the GEN2 aka ISO6c protocol.
void as3993ContinuousRead(u8 address, s8 len, u8 *readbuf)
Definition: as3993.c:456
volatile u16 as3993Response
Definition: as3993.c:67
#define EN_PA(x)
Definition: platform.h:83
void as3993ExitPowerDownMode()
Exit the power down mode by setting EN pin to high, restoring registers afterwards.
Definition: as3993.c:747
void as3993ExitPowerNormalRfMode()
Exit the normal power mode with rf on.
Definition: as3993.c:831
#define HIGH
Definition: global.h:46
#define WaitForAS3980()
Definition: as3993.c:61