Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
ST25R3911.cpp
00001 00002 /****************************************************************************** 00003 * @attention 00004 * 00005 * <h2><center>© 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, ®, 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, ®, 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, ®, 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, ®Val, 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, ®Dump[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 }
Generated on Tue Jul 12 2022 18:07:56 by
1.7.2