Diego Ostuni / ST25R3911
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ST25R3911.cpp Source File

ST25R3911.cpp

Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003   * @attention
00004   *
00005   * <h2><center>&copy; COPYRIGHT 2016 STMicroelectronics</center></h2>
00006   *
00007   * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
00008   * You may not use this file except in compliance with the License.
00009   * You may obtain a copy of the License at:
00010   *
00011   *        http://www.st.com/myliberty
00012   *
00013   * Unless required by applicable law or agreed to in writing, software 
00014   * distributed under the License is distributed on an "AS IS" BASIS, 
00015   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
00016   * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
00017   * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
00018   * See the License for the specific language governing permissions and
00019   * limitations under the License.
00020   *
00021 ******************************************************************************/
00022 
00023 
00024 /*
00025  *      PROJECT:   ST25R3911 firmware
00026  *      $Revision: $
00027  *      LANGUAGE:  ISO C99
00028  */
00029 
00030 /*! \file
00031  *
00032  *  \author Ulrich Herrmann
00033  *
00034  *  \brief ST25R3911 high level interface
00035  *
00036  */
00037 
00038 /*
00039 ******************************************************************************
00040 * INCLUDES
00041 ******************************************************************************
00042 */
00043 
00044 #include "ST25R3911.h"
00045 #include "st25r3911_com.h"
00046 #include "st25r3911_interrupt.h"
00047 
00048 
00049 
00050 #include "stdio.h"
00051 #include <limits.h>
00052 
00053 
00054 
00055 
00056 /*
00057 ******************************************************************************
00058 * LOCAL VARIABLES
00059 ******************************************************************************
00060 */
00061 static uint32_t st25r3911NoResponseTime_64fcs;
00062 typedef uint16_t      ReturnCode ; //eeeee.... st_errno.h
00063 #ifdef ST25R391X_COM_SINGLETXRX
00064 static uint8_t comBuf[ST25R3911_BUF_LEN];
00065 #endif /* ST25R391X_COM_SINGLETXRX */
00066 
00067 /*
00068 ******************************************************************************
00069 * LOCAL FUNCTION PROTOTYPES
00070 ******************************************************************************
00071 */
00072 static ReturnCode st25r3911ExecuteCommandAndGetResult(uint8_t cmd, uint8_t resreg, uint8_t sleeptime, uint8_t* result, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 );
00073 
00074 
00075 static inline void st25r3911CheckFieldSetLED(uint8_t val, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00076 {
00077     if (ST25R3911_REG_OP_CONTROL_tx_en & val)
00078     {
00079         fieldLED_06 -> write(1);
00080 
00081     }
00082     else
00083     {
00084         fieldLED_06 -> write(0);
00085     }
00086 
00087 }
00088 /*
00089 ******************************************************************************
00090 * GLOBAL FUNCTIONS
00091 ******************************************************************************
00092 */
00093 
00094 /*!
00095  *****************************************************************************
00096  *  \brief  Returns the content of a register within the ST25R3911
00097  *
00098  *  This function is used to read out the content of ST25R3911 registers.
00099  *
00100  *  \param[in]  reg: Address of register to read.
00101  *  \param[out] val: Returned value.
00102  *  \param[in]  mspiChannel: Channel of the SPI
00103  *  \param[in]  gpio_cs: Chip Select of the SPI
00104  *  \param[in]  IRQ: Interrupt line. Not implemented, It is a polling application.
00105  *  \param[out]  fieldLED_01: Digital Output of the LED1
00106  *  \param[out]  fieldLED_02: Digital Output of the LED2
00107  *  \param[out]  fieldLED_03: Digital Output of the LED3
00108  *  \param[out]  fieldLED_04: Digital Output of the LED4
00109  *  \param[out]  fieldLED_05: Digital Output of the LED5
00110  *  \param[out]  fieldLED_06: Digital Output of the LED6
00111  *
00112  *
00113  *****************************************************************************
00114  */
00115 
00116 void ST25R3911::readRegister(uint8_t reg, uint8_t* val, SPI* mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00117 {
00118 
00119     uint8_t buf[2];
00120     uint8_t buf_rx[2];
00121     buf_rx[0] = 0;
00122     buf_rx[1] = 0;
00123 
00124 
00125     buf[0] = (reg | ST25R3911_READ_MODE);
00126     buf[1] = 0;
00127 
00128     IRQ->disable_irq();
00129     *gpio_cs = 0;
00130     wait_us(50);
00131     mspiChannel -> write((const char *)(buf) ,2 , (char*)(buf_rx) , 2);
00132     *gpio_cs = 1;
00133     IRQ->enable_irq();
00134 
00135 
00136 
00137     if(val != NULL)
00138     {
00139       *val = buf_rx[1];
00140     }
00141 
00142 }
00143 
00144 /*!
00145  *****************************************************************************
00146  *  \brief  Writes a given value to a register within the ST25R3911
00147  *
00148  *  This function is used to write \a val to address \a reg within the ST25R3911.
00149  *
00150  *  \param[in]  reg: Address of the register to write.
00151  *  \param[in]  val: Value to be written.
00152  *  \param[in]  mspiChannel: Channel of the SPI
00153  *  \param[in]  gpio_cs: Chip Select of the SPI
00154  *  \param[in]  IRQ: Interrupt line. Not implemented, It is a polling application.
00155  *  \param[out]  fieldLED_01: Digital Output of the LED1
00156  *  \param[out]  fieldLED_02: Digital Output of the LED2
00157  *  \param[out]  fieldLED_03: Digital Output of the LED3
00158  *  \param[out]  fieldLED_04: Digital Output of the LED4
00159  *  \param[out]  fieldLED_05: Digital Output of the LED5
00160  *  \param[out]  fieldLED_06: Digital Output of the LED6
00161  *
00162  *****************************************************************************
00163  */
00164 
00165 
00166 void ST25R3911::writeRegister(uint8_t reg, uint8_t val, SPI * mspiChannel,  DigitalOut * gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00167 {
00168 
00169     uint8_t buf[2];
00170 
00171     buf[0] = reg | ST25R3911_WRITE_MODE;
00172     buf[1] = val;
00173 
00174     if (ST25R3911_REG_OP_CONTROL == reg)
00175     {
00176         st25r3911CheckFieldSetLED(val, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00177     }
00178 
00179     IRQ->disable_irq();
00180     *gpio_cs = 0;
00181     wait_us(50);
00182     mspiChannel -> write((const char *)(buf) ,2, NULL , NULL);
00183     *gpio_cs = 1;
00184     IRQ->enable_irq();
00185 
00186 
00187 }
00188 
00189 
00190 
00191 /*!
00192  *****************************************************************************
00193  *  \brief  Reads from multiple ST25R3911 registers
00194  *
00195  *  This function is used to read from multiple registers using the
00196  *  auto-increment feature. That is, after each read the address pointer
00197  *  inside the ST25R3911 gets incremented automatically.
00198  *
00199  *  \param[in]  reg: Address of the frist register to read from.
00200  *  \param[in]  values: pointer to a buffer where the result shall be written to.
00201  *  \param[in]  length: Number of registers to be read out.
00202  *  \param[in]  mspiChannel: Channel of the SPI
00203  *  \param[in]  mST25: Object of the ST25 chip
00204  *  \param[in]  gpio_cs: Chip Select of the SPI
00205  *  \param[in]  IRQ: Interrupt line. Not implemented, It is a polling application.
00206  *  \param[out]  fieldLED_01: Digital Output of the LED1
00207  *  \param[out]  fieldLED_02: Digital Output of the LED2
00208  *  \param[out]  fieldLED_03: Digital Output of the LED3
00209  *  \param[out]  fieldLED_04: Digital Output of the LED4
00210  *  \param[out]  fieldLED_05: Digital Output of the LED5
00211  *  \param[out]  fieldLED_06: Digital Output of the LED6
00212  *
00213  *****************************************************************************
00214  */
00215 
00216 
00217 void ST25R3911::readMultipleRegisters(uint8_t reg, uint8_t* val, uint8_t length, SPI * mspiChannel, ST25R3911* mST25,  DigitalOut * gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00218 {
00219 
00220     uint8_t cmd = (reg | ST25R3911_READ_MODE);
00221     uint8_t index = 0;
00222 
00223 
00224     if (length > 0)
00225     {
00226         /* make this operation atomic */
00227         for(index = 0; index < length; index ++)
00228         {
00229 
00230             mST25 -> readRegister(cmd + index, (val + index), mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00231 
00232         }
00233     }
00234 
00235 
00236 }
00237 
00238 /*!
00239  *****************************************************************************
00240  *  \brief  Writes multiple values to ST25R3911 registers
00241  *
00242  *  This function is used to write multiple values to the ST25R3911 using the
00243  *  auto-increment feature. That is, after each write the address pointer
00244  *  inside the ST25R3911 gets incremented automatically.
00245  *
00246  *  \param[in]  reg: Address of the frist register to write.
00247  *  \param[in]  values: pointer to a buffer containing the values to be written.
00248  *  \param[in]  length: Number of values to be written.
00249  *  \param[in]  mST25: Object of the ST25 chip
00250  *  \param[in]  mspiChannel: Channel of the SPI
00251  *  \param[in]  gpio_cs: Chip Select of the SPI
00252  *  \param[out]  fieldLED_01: Digital Output of the LED1
00253  *  \param[out]  fieldLED_02: Digital Output of the LED2
00254  *  \param[out]  fieldLED_03: Digital Output of the LED3
00255  *  \param[out]  fieldLED_04: Digital Output of the LED4
00256  *  \param[out]  fieldLED_05: Digital Output of the LED5
00257  *  \param[out]  fieldLED_06: Digital Output of the LED6
00258  *
00259  *****************************************************************************
00260  */
00261 
00262 void ST25R3911::writeMultipleRegisters(uint8_t reg, const uint8_t* values, uint8_t length, SPI * mspiChannel, ST25R3911* mST25,  DigitalOut * gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00263 {
00264 
00265     uint8_t cmd = (reg | ST25R3911_WRITE_MODE);
00266     uint8_t index = 0;
00267 
00268     if (reg <= ST25R3911_REG_OP_CONTROL && reg+length >= ST25R3911_REG_OP_CONTROL)
00269     {
00270         st25r3911CheckFieldSetLED(values[ST25R3911_REG_OP_CONTROL-reg], fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00271     }
00272 
00273     if (length > 0)
00274     {
00275         /* make this operation atomic */
00276         for(index = 0; index < length; index ++)
00277         {
00278             mST25 -> writeRegister(cmd + index, *(values + index), mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00279         }
00280     }
00281 
00282 }
00283 
00284 /*!
00285  *****************************************************************************
00286  *  \brief  Execute a direct command
00287  *
00288  *  This function is used to start so-called direct command. These commands
00289  *  are implemented inside the chip and each command has unique code (see
00290  *  datasheet).
00291  *
00292  *  \param[in]  cmd : code of the direct command to be executed.
00293  *  \param[in]  mspiChannel: Channel of the SPI
00294  *  \param[in]  gpio_cs: Chip Select of the SPI
00295  *  \param[in]  IRQ: Interrupt line. Not implemented, It is a polling application.
00296  *  \param[out]  fieldLED_01: Digital Output of the LED1
00297  *  \param[out]  fieldLED_02: Digital Output of the LED2
00298  *  \param[out]  fieldLED_03: Digital Output of the LED3
00299  *  \param[out]  fieldLED_04: Digital Output of the LED4
00300  *  \param[out]  fieldLED_05: Digital Output of the LED5
00301  *  \param[out]  fieldLED_06: Digital Output of the LED6
00302  *
00303  *****************************************************************************
00304  */
00305 
00306 void ST25R3911::executeCommand(uint8_t cmd, SPI* mspiChannel,  DigitalOut * gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00307 {
00308 
00309     uint8_t reg[1];
00310     reg[0] = cmd;
00311 
00312     if ( cmd >= ST25R3911_CMD_TRANSMIT_WITH_CRC && cmd <= ST25R3911_CMD_RESPONSE_RF_COLLISION_0)
00313     {
00314         fieldLED_06 -> write(0);
00315     }
00316 
00317     IRQ->disable_irq();
00318     *gpio_cs = 0;
00319     wait_us(50);
00320     mspiChannel -> write(( const char *)(reg), ST25R3911_CMD_LEN, NULL , NULL);
00321     *gpio_cs = 1;
00322     IRQ->enable_irq();
00323 
00324 
00325     return;
00326 }
00327 
00328 /*!
00329  *****************************************************************************
00330  *  \brief  Execute several direct commands
00331  *
00332  *  This function is used to start so-called direct command. These commands
00333  *  are implemented inside the chip and each command has unique code (see
00334  *  datasheet).
00335  *
00336  *  \param[in]  cmds   : codes of the direct command to be executed.
00337  *  \param[in]  length : number of commands to be executed
00338  *  \param[in]  mST25: Object of the ST25 chip
00339  *  \param[in]  mspiChannel: Channel of the SPI
00340  *  \param[in]  gpio_cs: Chip Select of the SPI
00341  *  \param[in]  IRQ: Interrupt line. Not implemented, It is a polling application.
00342  *  \param[out]  fieldLED_01: Digital Output of the LED1
00343  *  \param[out]  fieldLED_02: Digital Output of the LED2
00344  *  \param[out]  fieldLED_03: Digital Output of the LED3
00345  *  \param[out]  fieldLED_04: Digital Output of the LED4
00346  *  \param[out]  fieldLED_05: Digital Output of the LED5
00347  *  \param[out]  fieldLED_06: Digital Output of the LED6
00348  *
00349  *****************************************************************************
00350  */
00351 
00352 
00353 void ST25R3911::executeCommands(uint8_t *cmds, uint8_t length, ST25R3911* mST25, SPI* mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00354 {
00355 
00356     uint8_t index;
00357 
00358     for(index = 0; index < length; index++)
00359     {
00360         mST25 -> executeCommand(*cmds, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00361         *cmds++;
00362     }
00363 
00364     return;
00365 }
00366 
00367 
00368 
00369 
00370 
00371 /*!
00372  *****************************************************************************
00373  *  \brief  Writes values to ST25R3911 FIFO
00374  *
00375  *  This function needs to be called in order to write to the ST25R3911 FIFO.
00376  *
00377  *  \param[in]  values: pointer to a buffer containing the values to be written
00378  *                      to the FIFO.
00379  *  \param[in]  length: Number of values to be written.
00380  *  \param[in]  mspiChannel: Channel of the SPI
00381  *  \param[in]  gpio_cs: Chip Select of the SPI
00382  *  \param[in]  IRQ: Interrupt line. Not implemented, It is a polling application.
00383  *  \param[out]  fieldLED_01: Digital Output of the LED1
00384  *  \param[out]  fieldLED_02: Digital Output of the LED2
00385  *  \param[out]  fieldLED_03: Digital Output of the LED3
00386  *  \param[out]  fieldLED_04: Digital Output of the LED4
00387  *  \param[out]  fieldLED_05: Digital Output of the LED5
00388  *  \param[out]  fieldLED_06: Digital Output of the LED6
00389  *
00390  *****************************************************************************
00391  */
00392 
00393 
00394 
00395 void ST25R3911::writeFifo(const uint8_t* val, uint8_t length, SPI* mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00396 {
00397 
00398     if (length > 0)
00399     {
00400 
00401         uint8_t cmd = ST25R3911_FIFO_LOAD;
00402         uint8_t values[length + 1];
00403         values[0] = cmd;
00404         for(int i = 0 ; i < length; i++)
00405             values[i + 1] = *(val + i);
00406 
00407         IRQ->disable_irq();
00408         *gpio_cs = 0;
00409         wait_us(50);
00410         mspiChannel -> write( (const char *)values , length + 1, NULL , NULL);
00411         *gpio_cs = 1;
00412         IRQ->enable_irq();
00413 
00414     }
00415 
00416     return;
00417 }
00418 
00419 /*!
00420  *****************************************************************************
00421  *  \brief  Read values from ST25R3911 FIFO
00422  *
00423  *  This function needs to be called in order to read from ST25R3911 FIFO.
00424  *
00425  *  \param[out]  buf: pointer to a buffer where the FIFO content shall be
00426  *                       written to.
00427  *  \param[in]  length: Number of bytes to read. (= size of \a buf)
00428  *  \note: This function doesn't check whether \a length is really the
00429  *  number of available bytes in FIFO
00430  *  \param[in]  mspiChannel: Channel of the SPI
00431  *  \param[in]  gpio_cs: Chip Select of the SPI
00432  *  \param[in]  IRQ: Interrupt line. Not implemented, It is a polling application.
00433  *  \param[out]  fieldLED_01: Digital Output of the LED1
00434  *  \param[out]  fieldLED_02: Digital Output of the LED2
00435  *  \param[out]  fieldLED_03: Digital Output of the LED3
00436  *  \param[out]  fieldLED_04: Digital Output of the LED4
00437  *  \param[out]  fieldLED_05: Digital Output of the LED5
00438  *  \param[out]  fieldLED_06: Digital Output of the LED6
00439  *
00440  *****************************************************************************
00441  */
00442 
00443 void ST25R3911::readFifo(uint8_t* buf, uint8_t length, SPI* mspiChannel, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00444 {
00445     if (length > 0)
00446     {
00447 
00448         uint8_t cmd[2];
00449         cmd[0] = ST25R3911_FIFO_READ;
00450         cmd[1] = 0;
00451 
00452         IRQ->disable_irq();
00453         *gpio_cs = 0;
00454         wait_us(50);
00455         mspiChannel -> write((const char *)cmd, ST25R3911_CMD_LEN, NULL, NULL);
00456         mspiChannel -> write(NULL, NULL, (char *)buf, length);
00457         *gpio_cs = 1;
00458         IRQ->enable_irq();
00459 
00460     }
00461 
00462 
00463 
00464     return ;
00465 }
00466 
00467 
00468 
00469 ////////////////////////////////
00470 void st25r3911TxRxOn( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00471 {
00472     st25r3911SetRegisterBits(ST25R3911_REG_OP_CONTROL, (ST25R3911_REG_OP_CONTROL_rx_en | ST25R3911_REG_OP_CONTROL_tx_en), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00473 }
00474 
00475 void st25r3911TxRxOff( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00476 {
00477     st25r3911ClrRegisterBits(ST25R3911_REG_OP_CONTROL, (ST25R3911_REG_OP_CONTROL_rx_en | ST25R3911_REG_OP_CONTROL_tx_en), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00478 }
00479 
00480 
00481 void st25r3911OscOn( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00482 {
00483     uint8_t reg = 0;
00484 
00485     /* Make sure that oscillator is turned on and stable */
00486     mST25 -> readRegister( ST25R3911_REG_OP_CONTROL, &reg, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00487 
00488     /* Use ST25R3911_REG_OP_CONTROL_en instead of ST25R3911_REG_AUX_DISPLAY_osc_ok to be on the safe side */
00489     if (!(ST25R3911_REG_OP_CONTROL_en & reg))
00490     {
00491         /* enable oscillator frequency stable interrupt */
00492         st25r3911EnableInterrupts(ST25R3911_IRQ_MASK_OSC, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00493 
00494         /* enable oscillator and regulator output */
00495         st25r3911ModifyRegister(ST25R3911_REG_OP_CONTROL, 0x00, ST25R3911_REG_OP_CONTROL_en, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00496 
00497         /* wait for the oscillator interrupt */
00498         st25r3911WaitForInterruptsTimed(ST25R3911_IRQ_MASK_OSC, ST25R3911_OSC_STABLE_TIMEOUT, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00499         st25r3911DisableInterrupts(ST25R3911_IRQ_MASK_OSC, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00500     }
00501 
00502 } /* st25r3911OscOn() */
00503 
00504 
00505 void st25r3911Initialize(SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00506 {
00507 
00508 
00509     uint16_t vdd_mV;
00510 
00511 
00512 
00513     /* first, reset the st25r3911 */
00514     mST25 -> executeCommand(ST25R3911_CMD_SET_DEFAULT, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00515 
00516 
00517     /* enable pull downs on miso line */
00518     st25r3911ModifyRegister(ST25R3911_REG_IO_CONF2, 0,
00519             ST25R3911_REG_IO_CONF2_miso_pd1 |
00520             ST25R3911_REG_IO_CONF2_miso_pd2, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00521 
00522     /* after reset all interrupts are enabled. so disable them at first */
00523     st25r3911DisableInterrupts(ST25R3911_IRQ_MASK_ALL, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00524     /* and clear them, just to be sure... */
00525     st25r3911ClearInterrupts( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00526 
00527     /* trim settings for VHBR board, will anyway changed later on */
00528     mST25 -> writeRegister(ST25R3911_REG_ANT_CAL_TARGET, 0x80, mspiChannel,  gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00529 
00530     st25r3911OscOn( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00531 
00532     /* Measure vdd and set sup3V bit accordingly */
00533     vdd_mV = st25r3911MeasureVoltage(ST25R3911_REG_REGULATOR_CONTROL_mpsv_vdd, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00534 
00535     st25r3911ModifyRegister(ST25R3911_REG_IO_CONF2,
00536                          ST25R3911_REG_IO_CONF2_sup3V,
00537                          (vdd_mV < 3600)?ST25R3911_REG_IO_CONF2_sup3V:0, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00538 
00539     /* Make sure Transmitter and Receiver are disabled */
00540     st25r3911TxRxOff( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00541 
00542     return;
00543 }
00544 
00545 void st25r3911Deinitialize(SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00546 {
00547     st25r3911DisableInterrupts(ST25R3911_IRQ_MASK_ALL, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00548 
00549     /* Disabe Tx and Rx, Keep OSC */
00550     st25r3911TxRxOff( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00551 
00552     return;
00553 }
00554 
00555 ReturnCode st25r3911AdjustRegulators(uint16_t* result_mV, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00556 {
00557     uint8_t result;
00558     uint8_t io_conf2;
00559     ReturnCode err = ERR_NONE ;
00560 
00561     /* first check the status of the reg_s bit in ST25R3911_REG_VREG_DEF register.
00562        if this bit is set adjusting the regulators is not allowed */
00563     mST25 -> readRegister(ST25R3911_REG_REGULATOR_CONTROL, &result, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00564 
00565     if (result & ST25R3911_REG_REGULATOR_CONTROL_reg_s)
00566     {
00567         return ERR_REQUEST ;
00568     }
00569 
00570     st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_ADJUST_REGULATORS,
00571                                     ST25R3911_REG_REGULATOR_RESULT,
00572                                     5,
00573                                     &result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00574     mST25 -> readRegister(ST25R3911_REG_IO_CONF2, &io_conf2, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00575 
00576     result >>= ST25R3911_REG_REGULATOR_RESULT_shift_reg;
00577     result -= 5;
00578     if (result_mV)
00579     {
00580         if(io_conf2 & ST25R3911_REG_IO_CONF2_sup3V)
00581         {
00582             *result_mV = 2400;
00583             *result_mV += result * 100;
00584         }
00585         else
00586         {
00587             *result_mV = 3900;
00588             *result_mV += result * 120;
00589         }
00590     }
00591     return err;
00592 }
00593 
00594 void st25r3911MeasureRF(uint8_t* result, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00595 {
00596     st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_MEASURE_AMPLITUDE,
00597                                     ST25R3911_REG_AD_RESULT,
00598                                     10,
00599                                     result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00600 }
00601 
00602 void st25r3911MeasureCapacitance(uint8_t* result, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00603 {
00604     st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_MEASURE_CAPACITANCE,
00605                                     ST25R3911_REG_AD_RESULT,
00606                                     10,
00607                                     result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00608 }
00609 
00610 void st25r3911MeasureAntennaResonance(uint8_t* result, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00611 {
00612     st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_MEASURE_PHASE,
00613                                     ST25R3911_REG_AD_RESULT,
00614                                     10,
00615                                     result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00616 }
00617 
00618 void st25r3911CalibrateAntenna(uint8_t* result, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00619 {
00620     st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_CALIBRATE_ANTENNA,
00621                                     ST25R3911_REG_ANT_CAL_RESULT,
00622                                     10,
00623                                     result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00624 }
00625 
00626 void st25r3911CalibrateModulationDepth(uint8_t* result, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00627 {
00628     st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_CALIBRATE_MODULATION,
00629                                     ST25R3911_REG_AM_MOD_DEPTH_RESULT,
00630                                     10,
00631                                     result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00632 }
00633 
00634 
00635 void st25r3911CalibrateCapacitiveSensor(uint8_t* result, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00636 {
00637   st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_CALIBRATE_C_SENSOR,
00638                                     ST25R3911_REG_CAP_SENSOR_RESULT,
00639                                     10,
00640                                     result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00641 }
00642 
00643 
00644 ReturnCode st25r3911SetBitrate(uint8_t txRate, uint8_t rxRate, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00645 {
00646     uint8_t reg;
00647 
00648        mST25 -> readRegister(ST25R3911_REG_BIT_RATE, &reg, mspiChannel,  gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00649     if (rxRate != ST25R3911_BR_DO_NOT_SET)
00650     {
00651         if(rxRate > ST25R3911_BR_3390)
00652         {
00653             return ERR_PARAM ;
00654         }
00655         else
00656         {
00657             reg &= ~ST25R3911_REG_BIT_RATE_mask_rxrate;
00658             reg |= rxRate << ST25R3911_REG_BIT_RATE_shift_rxrate;
00659         }
00660     }
00661     if (txRate != ST25R3911_BR_DO_NOT_SET)
00662     {
00663         if(txRate > ST25R3911_BR_6780)
00664         {
00665             return ERR_PARAM ;
00666         }
00667         else
00668         {
00669             reg &= ~ST25R3911_REG_BIT_RATE_mask_txrate;
00670             reg |= txRate<<ST25R3911_REG_BIT_RATE_shift_txrate;
00671         }
00672     }
00673     mST25 -> writeRegister(ST25R3911_REG_BIT_RATE, reg, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00674 
00675     return ERR_NONE ;
00676 }
00677 
00678 
00679 uint16_t st25r3911MeasureVoltage(uint8_t mpsv,SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00680 {
00681     uint8_t result;
00682     uint16_t mV;
00683 
00684     mpsv &= ST25R3911_REG_REGULATOR_CONTROL_mask_mpsv;
00685 
00686     st25r3911ModifyRegister(ST25R3911_REG_REGULATOR_CONTROL,
00687                          ST25R3911_REG_REGULATOR_CONTROL_mask_mpsv,
00688                          mpsv, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00689 
00690     st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_MEASURE_VDD,
00691             ST25R3911_REG_AD_RESULT,
00692             100,
00693             &result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 );
00694     mV = ((uint16_t)result) * 23;
00695     mV += ((((uint16_t)result) * 438) + 500) / 1000;
00696 
00697     return mV;
00698 }
00699 
00700 
00701 uint8_t st25r3911GetNumFIFOLastBits(  SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00702 {
00703     uint8_t  reg;
00704     
00705     mST25 ->  readRegister( ST25R3911_REG_FIFO_RX_STATUS2, &reg, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00706     
00707     return ((reg & ST25R3911_REG_FIFO_RX_STATUS2_mask_fifo_lb) >> ST25R3911_REG_FIFO_RX_STATUS2_shift_fifo_lb);
00708 }
00709 
00710 uint32_t st25r3911GetNoResponseTime_64fcs()
00711 {
00712     return st25r3911NoResponseTime_64fcs;
00713 }
00714 
00715 void st25r3911StartGPTimer_8fcs(uint16_t gpt_8fcs, uint8_t trigger_source, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00716 {
00717     st25r3911SetGPTime_8fcs(gpt_8fcs, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00718 
00719     st25r3911ModifyRegister(ST25R3911_REG_GPT_CONTROL,
00720             ST25R3911_REG_GPT_CONTROL_gptc_mask,
00721             trigger_source, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00722     if (!trigger_source)
00723         mST25 -> executeCommand(ST25R3911_CMD_START_GP_TIMER, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00724 
00725     return;
00726 }
00727 
00728 void st25r3911SetGPTime_8fcs(uint16_t gpt_8fcs, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00729 {
00730     mST25 -> writeRegister(ST25R3911_REG_GPT1, gpt_8fcs >> 8, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00731     mST25 -> writeRegister(ST25R3911_REG_GPT2, gpt_8fcs & 0xff, mspiChannel,  gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00732 
00733     return;
00734 }
00735 
00736 bool st25r3911CheckReg( uint8_t reg, uint8_t mask, uint8_t val, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00737 {
00738     uint8_t regVal;
00739 
00740     regVal = 0;
00741     mST25 -> readRegister( reg, &regVal, mspiChannel,  gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00742 
00743     return ((regVal & mask) == val );
00744 }
00745 
00746 
00747 bool st25r3911CheckChipID( uint8_t *rev, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00748 {
00749     uint8_t ID;
00750 
00751 
00752     mST25 -> readRegister(ST25R3911_REG_IC_IDENTITY, &ID, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00753 
00754     /* Check if IC Identity Register contains ST25R3911's IC type code */
00755     if( (ID & ST25R3911_REG_IC_IDENTITY_mask_ic_type)  != (ST25R3911_REG_IC_IDENTITY_ic_type) )
00756     {
00757         return false;
00758     }
00759 
00760 
00761     if(rev != NULL)
00762     {
00763         *rev = (ID & ST25R3911_REG_IC_IDENTITY_mask_ic_rev);
00764     }
00765     
00766     return true;
00767 }
00768 
00769 ReturnCode st25r3911SetNoResponseTime_64fcs(uint32_t nrt_64fcs, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00770 {
00771     ReturnCode err = ERR_NONE ;
00772     uint8_t nrt_step = 0;
00773 
00774     st25r3911NoResponseTime_64fcs = nrt_64fcs;
00775     if (nrt_64fcs > USHRT_MAX)
00776     {
00777         nrt_step = ST25R3911_REG_GPT_CONTROL_nrt_step;
00778         nrt_64fcs = (nrt_64fcs + 63) / 64;
00779         if (nrt_64fcs > USHRT_MAX)
00780         {
00781             nrt_64fcs = USHRT_MAX;
00782             err = ERR_PARAM ;
00783         }
00784         st25r3911NoResponseTime_64fcs = 64 * nrt_64fcs;
00785     }
00786 
00787     st25r3911ModifyRegister(ST25R3911_REG_GPT_CONTROL, ST25R3911_REG_GPT_CONTROL_nrt_step, nrt_step, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00788     mST25 -> writeRegister(ST25R3911_REG_NO_RESPONSE_TIMER1, nrt_64fcs >> 8, mspiChannel,  gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00789     mST25 -> writeRegister(ST25R3911_REG_NO_RESPONSE_TIMER2, nrt_64fcs & 0xff, mspiChannel,  gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00790 
00791     return err;
00792 }
00793 
00794 ReturnCode st25r3911SetStartNoResponseTime_64fcs(uint32_t nrt_64fcs, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00795 {
00796     ReturnCode err;
00797 
00798     err = st25r3911SetNoResponseTime_64fcs( nrt_64fcs, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00799     if(err == ERR_NONE )
00800     {
00801           mST25 -> executeCommand(ST25R3911_CMD_START_NO_RESPONSE_TIMER, mspiChannel,  gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00802     }
00803 
00804     return err;
00805 }
00806 
00807 ReturnCode st25r3911PerformCollisionAvoidance( uint8_t FieldONCmd, uint8_t pdThreshold, uint8_t caThreshold, uint8_t nTRFW, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00808 {
00809     uint8_t  treMask;
00810     uint32_t irqs;
00811 
00812     if( (FieldONCmd != ST25R3911_CMD_INITIAL_RF_COLLISION)    &&
00813         (FieldONCmd != ST25R3911_CMD_RESPONSE_RF_COLLISION_0) &&
00814         (FieldONCmd != ST25R3911_CMD_RESPONSE_RF_COLLISION_N)   )
00815     {
00816         return ERR_PARAM ;
00817     }
00818 
00819     /* Check if new thresholds are to be applied */
00820     if( (pdThreshold != ST25R3911_THRESHOLD_DO_NOT_SET) || (caThreshold != ST25R3911_THRESHOLD_DO_NOT_SET) )
00821     {
00822         treMask = 0;
00823 
00824         if(pdThreshold != ST25R3911_THRESHOLD_DO_NOT_SET)
00825         {
00826             treMask |= ST25R3911_REG_FIELD_THRESHOLD_mask_trg;
00827         }
00828 
00829         if(caThreshold != ST25R3911_THRESHOLD_DO_NOT_SET)
00830         {
00831             treMask |= ST25R3911_REG_FIELD_THRESHOLD_mask_rfe;
00832         }
00833 
00834         /* Set Detection Threshold and|or Collision Avoidance Threshold */
00835         st25r3911ChangeRegisterBits( ST25R3911_REG_FIELD_THRESHOLD, treMask, (pdThreshold & ST25R3911_REG_FIELD_THRESHOLD_mask_trg) | (caThreshold & ST25R3911_REG_FIELD_THRESHOLD_mask_rfe ), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00836     }
00837     
00838     /* Set n x TRFW */
00839     st25r3911ModifyRegister(ST25R3911_REG_AUX, ST25R3911_REG_AUX_mask_nfc_n, (nTRFW & ST25R3911_REG_AUX_mask_nfc_n), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00840 
00841     /* Enable and clear CA specific interrupts and execute command */
00842     st25r3911EnableInterrupts( (ST25R3911_IRQ_MASK_CAC | ST25R3911_IRQ_MASK_CAT), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00843     st25r3911GetInterrupt( (ST25R3911_IRQ_MASK_CAC | ST25R3911_IRQ_MASK_CAT), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00844 
00845     mST25 -> executeCommand(FieldONCmd, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00846 
00847     irqs = st25r3911WaitForInterruptsTimed(ST25R3911_IRQ_MASK_CAC | ST25R3911_IRQ_MASK_CAT, ST25R3911_CA_TIMEOUT, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00848 
00849     /* Clear any previous External Field events and disable CA specific interrupts */
00850     st25r3911GetInterrupt( (ST25R3911_IRQ_MASK_EOF | ST25R3911_IRQ_MASK_EON), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00851     st25r3911DisableInterrupts((ST25R3911_IRQ_MASK_CAC | ST25R3911_IRQ_MASK_CAT), mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 );
00852 
00853 
00854     if(ST25R3911_IRQ_MASK_CAC & irqs)                             /* Collision occurred */
00855     {
00856         return ERR_RF_COLLISION ;
00857     }
00858 
00859     if(ST25R3911_IRQ_MASK_CAT & irqs)                             /* No Collision detected, Field On */
00860     {
00861         return ERR_NONE ;
00862     }
00863 
00864     /* No interrupt detected */
00865     return ERR_INTERNAL ;
00866 }
00867 
00868 ReturnCode st25r3911GetRegsDump(uint8_t* resRegDump, uint8_t* sizeRegDump, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00869 {
00870     uint8_t regIt;
00871     uint8_t regDump[ST25R3911_REG_IC_IDENTITY+1];
00872     
00873     if(!sizeRegDump || !resRegDump)
00874     {
00875         return ERR_PARAM ;
00876     }
00877     
00878     for( regIt = ST25R3911_REG_IO_CONF1; regIt < SIZEOF_ARRAY(regDump); regIt++ )
00879     {
00880           mST25 -> readRegister(regIt, &regDump[regIt], mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00881     }
00882     
00883     *sizeRegDump = MIN(*sizeRegDump, regIt);
00884     ST_MEMCPY(resRegDump, regDump, *sizeRegDump );
00885 
00886     return ERR_NONE ;
00887 }
00888 
00889 
00890 void st25r3911SetNumTxBits( uint32_t nBits, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00891 {
00892     mST25 -> writeRegister(ST25R3911_REG_NUM_TX_BYTES2, (uint8_t)((nBits >> 0) & 0xff), mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00893     mST25 -> writeRegister(ST25R3911_REG_NUM_TX_BYTES1, (uint8_t)((nBits >> 8) & 0xff), mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00894 }
00895 
00896 
00897 bool st25r3911IsCmdValid( uint8_t cmd )
00898 {
00899     if( !((cmd >= ST25R3911_CMD_SET_DEFAULT)       && (cmd <= ST25R3911_CMD_ANALOG_PRESET))           &&
00900         !((cmd >= ST25R3911_CMD_MASK_RECEIVE_DATA) && (cmd <= ST25R3911_CMD_CLEAR_RSSI))              &&
00901         !((cmd >= ST25R3911_CMD_TRANSPARENT_MODE)  && (cmd <= ST25R3911_CMD_START_NO_RESPONSE_TIMER)) &&
00902         !((cmd >= ST25R3911_CMD_TEST_CLEARA)       && (cmd <= ST25R3911_CMD_FUSE_PPROM))               )
00903     {
00904         return false;
00905     }
00906     return true;
00907 }
00908 
00909 ReturnCode st25r3911StreamConfigure(const struct st25r3911StreamConfig  *config, SPI* mspiChannel, ST25R3911* mST25,  DigitalOut * gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00910 {
00911     uint8_t smd = 0;
00912     uint8_t mode;
00913 
00914     if (config->useBPSK )
00915     {
00916         mode = ST25R3911_REG_MODE_om_bpsk_stream;
00917         if (config->din <2 || config->din >4) /* not in fc/4 .. fc/16 */
00918         {
00919             return ERR_PARAM ;
00920         }
00921         smd |= (4 - config->din ) << ST25R3911_REG_STREAM_MODE_shift_scf;
00922 
00923     }
00924     else
00925     {
00926         mode = ST25R3911_REG_MODE_om_subcarrier_stream;
00927         if (config->din <3 || config->din >6) /* not in fc/8 .. fc/64 */
00928         {
00929             return ERR_PARAM ;
00930         }
00931         smd |= (6 - config->din ) << ST25R3911_REG_STREAM_MODE_shift_scf;
00932         if (config->report_period_length  == 0)
00933         {
00934             return ERR_PARAM ;
00935         }
00936     }
00937 
00938     if (config->dout <1 || config->dout >7) /* not in fc/2 .. fc/128 */
00939     {
00940         return ERR_PARAM ;
00941     }
00942     smd |= (7 - config->dout ) << ST25R3911_REG_STREAM_MODE_shift_stx;
00943 
00944     if (config->report_period_length  > 3)
00945     {
00946         return ERR_PARAM ;
00947     }
00948     smd |= config->report_period_length  << ST25R3911_REG_STREAM_MODE_shift_scp;
00949 
00950     mST25 -> writeRegister(ST25R3911_REG_STREAM_MODE, smd, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00951     st25r3911ChangeRegisterBits(ST25R3911_REG_MODE, ST25R3911_REG_MODE_mask_om, mode, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
00952 
00953     return ERR_NONE ;
00954 }
00955 
00956 bool st25r3911IrqIsWakeUpCap( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00957 {
00958   return ( st25r3911GetInterrupt( ST25R3911_IRQ_MASK_WCAP, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 )  ? true : false );
00959 }
00960 
00961 
00962 bool st25r3911IrqIsWakeUpPhase( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00963 {
00964   return ( st25r3911GetInterrupt( ST25R3911_IRQ_MASK_WPH, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 )  ? true : false );
00965 }
00966 
00967 
00968 bool st25r3911IrqIsWakeUpAmplitude( SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00969 {
00970   return ( st25r3911GetInterrupt( ST25R3911_IRQ_MASK_WAM, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 )  ? true : false );
00971 }
00972 
00973 /*
00974 ******************************************************************************
00975 * LOCAL FUNCTIONS
00976 ******************************************************************************
00977 */
00978 /*!
00979  *****************************************************************************
00980  *  \brief  Executes a direct command and returns the result
00981  *
00982  *  This function executes the direct command given by \a cmd waits for
00983  *  \a sleeptime and returns the result read from register \a resreg.
00984  *
00985  *  \param[in] cmd: direct command to execute.
00986  *  \param[in] resreg: Address of the register containing the result.
00987  *  \param[in] sleeptime: time in milliseconds to wait before reading the result.
00988  *  \param[out] result: 8 bit long result
00989  *
00990  *****************************************************************************
00991  */
00992 static ReturnCode st25r3911ExecuteCommandAndGetResult(uint8_t cmd, uint8_t resreg, uint8_t sleeptime, uint8_t* result, SPI* mspiChannel, ST25R3911* mST25, DigitalOut* gpio_cs, InterruptIn* IRQ, DigitalOut* fieldLED_01, DigitalOut* fieldLED_02, DigitalOut* fieldLED_03, DigitalOut* fieldLED_04, DigitalOut* fieldLED_05, DigitalOut* fieldLED_06 )
00993 {
00994 
00995     if (   (cmd >= ST25R3911_CMD_INITIAL_RF_COLLISION && cmd <= ST25R3911_CMD_RESPONSE_RF_COLLISION_0)
00996             || (cmd == ST25R3911_CMD_MEASURE_AMPLITUDE)
00997             || (cmd >= ST25R3911_CMD_ADJUST_REGULATORS && cmd <= ST25R3911_CMD_MEASURE_PHASE)
00998             || (cmd >= ST25R3911_CMD_CALIBRATE_C_SENSOR && cmd <= ST25R3911_CMD_MEASURE_VDD)
00999             || (cmd >= 0xFD && cmd <= 0xFE )
01000        )
01001     {
01002         st25r3911EnableInterrupts(ST25R3911_IRQ_MASK_DCT, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
01003         st25r3911GetInterrupt(ST25R3911_IRQ_MASK_DCT, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
01004         mST25 -> executeCommand(cmd, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
01005         st25r3911WaitForInterruptsTimed(ST25R3911_IRQ_MASK_DCT, sleeptime, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
01006         st25r3911DisableInterrupts(ST25R3911_IRQ_MASK_DCT, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
01007     }
01008     else
01009     {
01010         return ERR_PARAM ;
01011     }
01012 
01013     /* read out the result if the pointer is not NULL */
01014     if (result)
01015               mST25 -> readRegister(resreg, result, mspiChannel,  gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ;
01016 
01017     return ERR_NONE ;
01018 
01019 }