Fork of the GitHub
ST25R3911.cpp
- Committer:
- DiegoOstuni
- Date:
- 2019-11-14
- Revision:
- 0:98fcd1266df0
File content as of revision 0:98fcd1266df0:
/****************************************************************************** * @attention * * <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2> * * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/myliberty * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ /* * PROJECT: ST25R3911 firmware * $Revision: $ * LANGUAGE: ISO C99 */ /*! \file * * \author Ulrich Herrmann * * \brief ST25R3911 high level interface * */ /* ****************************************************************************** * INCLUDES ****************************************************************************** */ #include "ST25R3911.h" #include "st25r3911_com.h" #include "st25r3911_interrupt.h" #include "stdio.h" #include <limits.h> /* ****************************************************************************** * LOCAL VARIABLES ****************************************************************************** */ static uint32_t st25r3911NoResponseTime_64fcs; typedef uint16_t ReturnCode; //eeeee.... st_errno.h #ifdef ST25R391X_COM_SINGLETXRX static uint8_t comBuf[ST25R3911_BUF_LEN]; #endif /* ST25R391X_COM_SINGLETXRX */ /* ****************************************************************************** * LOCAL FUNCTION PROTOTYPES ****************************************************************************** */ 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 ); 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 ) { if (ST25R3911_REG_OP_CONTROL_tx_en & val) { fieldLED_06 -> write(1); } else { fieldLED_06 -> write(0); } } /* ****************************************************************************** * GLOBAL FUNCTIONS ****************************************************************************** */ /*! ***************************************************************************** * \brief Returns the content of a register within the ST25R3911 * * This function is used to read out the content of ST25R3911 registers. * * \param[in] reg: Address of register to read. * \param[out] val: Returned value. * \param[in] mspiChannel: Channel of the SPI * \param[in] gpio_cs: Chip Select of the SPI * \param[in] IRQ: Interrupt line. Not implemented, It is a polling application. * \param[out] fieldLED_01: Digital Output of the LED1 * \param[out] fieldLED_02: Digital Output of the LED2 * \param[out] fieldLED_03: Digital Output of the LED3 * \param[out] fieldLED_04: Digital Output of the LED4 * \param[out] fieldLED_05: Digital Output of the LED5 * \param[out] fieldLED_06: Digital Output of the LED6 * * ***************************************************************************** */ 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 ) { uint8_t buf[2]; uint8_t buf_rx[2]; buf_rx[0] = 0; buf_rx[1] = 0; buf[0] = (reg | ST25R3911_READ_MODE); buf[1] = 0; IRQ->disable_irq(); *gpio_cs = 0; wait_us(50); mspiChannel -> write((const char *)(buf) ,2 , (char*)(buf_rx) , 2); *gpio_cs = 1; IRQ->enable_irq(); if(val != NULL) { *val = buf_rx[1]; } } /*! ***************************************************************************** * \brief Writes a given value to a register within the ST25R3911 * * This function is used to write \a val to address \a reg within the ST25R3911. * * \param[in] reg: Address of the register to write. * \param[in] val: Value to be written. * \param[in] mspiChannel: Channel of the SPI * \param[in] gpio_cs: Chip Select of the SPI * \param[in] IRQ: Interrupt line. Not implemented, It is a polling application. * \param[out] fieldLED_01: Digital Output of the LED1 * \param[out] fieldLED_02: Digital Output of the LED2 * \param[out] fieldLED_03: Digital Output of the LED3 * \param[out] fieldLED_04: Digital Output of the LED4 * \param[out] fieldLED_05: Digital Output of the LED5 * \param[out] fieldLED_06: Digital Output of the LED6 * ***************************************************************************** */ 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 ) { uint8_t buf[2]; buf[0] = reg | ST25R3911_WRITE_MODE; buf[1] = val; if (ST25R3911_REG_OP_CONTROL == reg) { st25r3911CheckFieldSetLED(val, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; } IRQ->disable_irq(); *gpio_cs = 0; wait_us(50); mspiChannel -> write((const char *)(buf) ,2, NULL , NULL); *gpio_cs = 1; IRQ->enable_irq(); } /*! ***************************************************************************** * \brief Reads from multiple ST25R3911 registers * * This function is used to read from multiple registers using the * auto-increment feature. That is, after each read the address pointer * inside the ST25R3911 gets incremented automatically. * * \param[in] reg: Address of the frist register to read from. * \param[in] values: pointer to a buffer where the result shall be written to. * \param[in] length: Number of registers to be read out. * \param[in] mspiChannel: Channel of the SPI * \param[in] mST25: Object of the ST25 chip * \param[in] gpio_cs: Chip Select of the SPI * \param[in] IRQ: Interrupt line. Not implemented, It is a polling application. * \param[out] fieldLED_01: Digital Output of the LED1 * \param[out] fieldLED_02: Digital Output of the LED2 * \param[out] fieldLED_03: Digital Output of the LED3 * \param[out] fieldLED_04: Digital Output of the LED4 * \param[out] fieldLED_05: Digital Output of the LED5 * \param[out] fieldLED_06: Digital Output of the LED6 * ***************************************************************************** */ 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 ) { uint8_t cmd = (reg | ST25R3911_READ_MODE); uint8_t index = 0; if (length > 0) { /* make this operation atomic */ for(index = 0; index < length; index ++) { mST25 -> readRegister(cmd + index, (val + index), mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; } } } /*! ***************************************************************************** * \brief Writes multiple values to ST25R3911 registers * * This function is used to write multiple values to the ST25R3911 using the * auto-increment feature. That is, after each write the address pointer * inside the ST25R3911 gets incremented automatically. * * \param[in] reg: Address of the frist register to write. * \param[in] values: pointer to a buffer containing the values to be written. * \param[in] length: Number of values to be written. * \param[in] mST25: Object of the ST25 chip * \param[in] mspiChannel: Channel of the SPI * \param[in] gpio_cs: Chip Select of the SPI * \param[out] fieldLED_01: Digital Output of the LED1 * \param[out] fieldLED_02: Digital Output of the LED2 * \param[out] fieldLED_03: Digital Output of the LED3 * \param[out] fieldLED_04: Digital Output of the LED4 * \param[out] fieldLED_05: Digital Output of the LED5 * \param[out] fieldLED_06: Digital Output of the LED6 * ***************************************************************************** */ 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 ) { uint8_t cmd = (reg | ST25R3911_WRITE_MODE); uint8_t index = 0; if (reg <= ST25R3911_REG_OP_CONTROL && reg+length >= ST25R3911_REG_OP_CONTROL) { st25r3911CheckFieldSetLED(values[ST25R3911_REG_OP_CONTROL-reg], fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; } if (length > 0) { /* make this operation atomic */ for(index = 0; index < length; index ++) { mST25 -> writeRegister(cmd + index, *(values + index), mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; } } } /*! ***************************************************************************** * \brief Execute a direct command * * This function is used to start so-called direct command. These commands * are implemented inside the chip and each command has unique code (see * datasheet). * * \param[in] cmd : code of the direct command to be executed. * \param[in] mspiChannel: Channel of the SPI * \param[in] gpio_cs: Chip Select of the SPI * \param[in] IRQ: Interrupt line. Not implemented, It is a polling application. * \param[out] fieldLED_01: Digital Output of the LED1 * \param[out] fieldLED_02: Digital Output of the LED2 * \param[out] fieldLED_03: Digital Output of the LED3 * \param[out] fieldLED_04: Digital Output of the LED4 * \param[out] fieldLED_05: Digital Output of the LED5 * \param[out] fieldLED_06: Digital Output of the LED6 * ***************************************************************************** */ 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 ) { uint8_t reg[1]; reg[0] = cmd; if ( cmd >= ST25R3911_CMD_TRANSMIT_WITH_CRC && cmd <= ST25R3911_CMD_RESPONSE_RF_COLLISION_0) { fieldLED_06 -> write(0); } IRQ->disable_irq(); *gpio_cs = 0; wait_us(50); mspiChannel -> write(( const char *)(reg), ST25R3911_CMD_LEN, NULL , NULL); *gpio_cs = 1; IRQ->enable_irq(); return; } /*! ***************************************************************************** * \brief Execute several direct commands * * This function is used to start so-called direct command. These commands * are implemented inside the chip and each command has unique code (see * datasheet). * * \param[in] cmds : codes of the direct command to be executed. * \param[in] length : number of commands to be executed * \param[in] mST25: Object of the ST25 chip * \param[in] mspiChannel: Channel of the SPI * \param[in] gpio_cs: Chip Select of the SPI * \param[in] IRQ: Interrupt line. Not implemented, It is a polling application. * \param[out] fieldLED_01: Digital Output of the LED1 * \param[out] fieldLED_02: Digital Output of the LED2 * \param[out] fieldLED_03: Digital Output of the LED3 * \param[out] fieldLED_04: Digital Output of the LED4 * \param[out] fieldLED_05: Digital Output of the LED5 * \param[out] fieldLED_06: Digital Output of the LED6 * ***************************************************************************** */ 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 ) { uint8_t index; for(index = 0; index < length; index++) { mST25 -> executeCommand(*cmds, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; *cmds++; } return; } /*! ***************************************************************************** * \brief Writes values to ST25R3911 FIFO * * This function needs to be called in order to write to the ST25R3911 FIFO. * * \param[in] values: pointer to a buffer containing the values to be written * to the FIFO. * \param[in] length: Number of values to be written. * \param[in] mspiChannel: Channel of the SPI * \param[in] gpio_cs: Chip Select of the SPI * \param[in] IRQ: Interrupt line. Not implemented, It is a polling application. * \param[out] fieldLED_01: Digital Output of the LED1 * \param[out] fieldLED_02: Digital Output of the LED2 * \param[out] fieldLED_03: Digital Output of the LED3 * \param[out] fieldLED_04: Digital Output of the LED4 * \param[out] fieldLED_05: Digital Output of the LED5 * \param[out] fieldLED_06: Digital Output of the LED6 * ***************************************************************************** */ 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 ) { if (length > 0) { uint8_t cmd = ST25R3911_FIFO_LOAD; uint8_t values[length + 1]; values[0] = cmd; for(int i = 0 ; i < length; i++) values[i + 1] = *(val + i); IRQ->disable_irq(); *gpio_cs = 0; wait_us(50); mspiChannel -> write( (const char *)values , length + 1, NULL , NULL); *gpio_cs = 1; IRQ->enable_irq(); } return; } /*! ***************************************************************************** * \brief Read values from ST25R3911 FIFO * * This function needs to be called in order to read from ST25R3911 FIFO. * * \param[out] buf: pointer to a buffer where the FIFO content shall be * written to. * \param[in] length: Number of bytes to read. (= size of \a buf) * \note: This function doesn't check whether \a length is really the * number of available bytes in FIFO * \param[in] mspiChannel: Channel of the SPI * \param[in] gpio_cs: Chip Select of the SPI * \param[in] IRQ: Interrupt line. Not implemented, It is a polling application. * \param[out] fieldLED_01: Digital Output of the LED1 * \param[out] fieldLED_02: Digital Output of the LED2 * \param[out] fieldLED_03: Digital Output of the LED3 * \param[out] fieldLED_04: Digital Output of the LED4 * \param[out] fieldLED_05: Digital Output of the LED5 * \param[out] fieldLED_06: Digital Output of the LED6 * ***************************************************************************** */ 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 ) { if (length > 0) { uint8_t cmd[2]; cmd[0] = ST25R3911_FIFO_READ; cmd[1] = 0; IRQ->disable_irq(); *gpio_cs = 0; wait_us(50); mspiChannel -> write((const char *)cmd, ST25R3911_CMD_LEN, NULL, NULL); mspiChannel -> write(NULL, NULL, (char *)buf, length); *gpio_cs = 1; IRQ->enable_irq(); } return ; } //////////////////////////////// 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 ) { 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 ) ; } 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 ) { 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 ) ; } 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 ) { uint8_t reg = 0; /* Make sure that oscillator is turned on and stable */ mST25 -> readRegister( ST25R3911_REG_OP_CONTROL, ®, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; /* Use ST25R3911_REG_OP_CONTROL_en instead of ST25R3911_REG_AUX_DISPLAY_osc_ok to be on the safe side */ if (!(ST25R3911_REG_OP_CONTROL_en & reg)) { /* enable oscillator frequency stable interrupt */ st25r3911EnableInterrupts(ST25R3911_IRQ_MASK_OSC, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; /* enable oscillator and regulator output */ 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 ) ; /* wait for the oscillator interrupt */ 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 ) ; st25r3911DisableInterrupts(ST25R3911_IRQ_MASK_OSC, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; } } /* st25r3911OscOn() */ 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 ) { uint16_t vdd_mV; /* first, reset the st25r3911 */ mST25 -> executeCommand(ST25R3911_CMD_SET_DEFAULT, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; /* enable pull downs on miso line */ st25r3911ModifyRegister(ST25R3911_REG_IO_CONF2, 0, ST25R3911_REG_IO_CONF2_miso_pd1 | ST25R3911_REG_IO_CONF2_miso_pd2, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; /* after reset all interrupts are enabled. so disable them at first */ st25r3911DisableInterrupts(ST25R3911_IRQ_MASK_ALL, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; /* and clear them, just to be sure... */ st25r3911ClearInterrupts( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; /* trim settings for VHBR board, will anyway changed later on */ mST25 -> writeRegister(ST25R3911_REG_ANT_CAL_TARGET, 0x80, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; st25r3911OscOn( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; /* Measure vdd and set sup3V bit accordingly */ 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 ) ; st25r3911ModifyRegister(ST25R3911_REG_IO_CONF2, ST25R3911_REG_IO_CONF2_sup3V, (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 ) ; /* Make sure Transmitter and Receiver are disabled */ st25r3911TxRxOff( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; return; } 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 ) { st25r3911DisableInterrupts(ST25R3911_IRQ_MASK_ALL, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; /* Disabe Tx and Rx, Keep OSC */ st25r3911TxRxOff( mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; return; } 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 ) { uint8_t result; uint8_t io_conf2; ReturnCode err = ERR_NONE; /* first check the status of the reg_s bit in ST25R3911_REG_VREG_DEF register. if this bit is set adjusting the regulators is not allowed */ mST25 -> readRegister(ST25R3911_REG_REGULATOR_CONTROL, &result, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; if (result & ST25R3911_REG_REGULATOR_CONTROL_reg_s) { return ERR_REQUEST; } st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_ADJUST_REGULATORS, ST25R3911_REG_REGULATOR_RESULT, 5, &result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; mST25 -> readRegister(ST25R3911_REG_IO_CONF2, &io_conf2, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; result >>= ST25R3911_REG_REGULATOR_RESULT_shift_reg; result -= 5; if (result_mV) { if(io_conf2 & ST25R3911_REG_IO_CONF2_sup3V) { *result_mV = 2400; *result_mV += result * 100; } else { *result_mV = 3900; *result_mV += result * 120; } } return err; } 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 ) { st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_MEASURE_AMPLITUDE, ST25R3911_REG_AD_RESULT, 10, result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; } 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 ) { st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_MEASURE_CAPACITANCE, ST25R3911_REG_AD_RESULT, 10, result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; } 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 ) { st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_MEASURE_PHASE, ST25R3911_REG_AD_RESULT, 10, result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; } 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 ) { st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_CALIBRATE_ANTENNA, ST25R3911_REG_ANT_CAL_RESULT, 10, result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; } 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 ) { st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_CALIBRATE_MODULATION, ST25R3911_REG_AM_MOD_DEPTH_RESULT, 10, result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; } 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 ) { st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_CALIBRATE_C_SENSOR, ST25R3911_REG_CAP_SENSOR_RESULT, 10, result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; } 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 ) { uint8_t reg; mST25 -> readRegister(ST25R3911_REG_BIT_RATE, ®, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; if (rxRate != ST25R3911_BR_DO_NOT_SET) { if(rxRate > ST25R3911_BR_3390) { return ERR_PARAM; } else { reg &= ~ST25R3911_REG_BIT_RATE_mask_rxrate; reg |= rxRate << ST25R3911_REG_BIT_RATE_shift_rxrate; } } if (txRate != ST25R3911_BR_DO_NOT_SET) { if(txRate > ST25R3911_BR_6780) { return ERR_PARAM; } else { reg &= ~ST25R3911_REG_BIT_RATE_mask_txrate; reg |= txRate<<ST25R3911_REG_BIT_RATE_shift_txrate; } } mST25 -> writeRegister(ST25R3911_REG_BIT_RATE, reg, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; return ERR_NONE; } 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 ) { uint8_t result; uint16_t mV; mpsv &= ST25R3911_REG_REGULATOR_CONTROL_mask_mpsv; st25r3911ModifyRegister(ST25R3911_REG_REGULATOR_CONTROL, ST25R3911_REG_REGULATOR_CONTROL_mask_mpsv, mpsv, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; st25r3911ExecuteCommandAndGetResult(ST25R3911_CMD_MEASURE_VDD, ST25R3911_REG_AD_RESULT, 100, &result, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ); mV = ((uint16_t)result) * 23; mV += ((((uint16_t)result) * 438) + 500) / 1000; return mV; } 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 ) { uint8_t reg; mST25 -> readRegister( ST25R3911_REG_FIFO_RX_STATUS2, ®, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; return ((reg & ST25R3911_REG_FIFO_RX_STATUS2_mask_fifo_lb) >> ST25R3911_REG_FIFO_RX_STATUS2_shift_fifo_lb); } uint32_t st25r3911GetNoResponseTime_64fcs() { return st25r3911NoResponseTime_64fcs; } 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 ) { st25r3911SetGPTime_8fcs(gpt_8fcs, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; st25r3911ModifyRegister(ST25R3911_REG_GPT_CONTROL, ST25R3911_REG_GPT_CONTROL_gptc_mask, trigger_source, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; if (!trigger_source) mST25 -> executeCommand(ST25R3911_CMD_START_GP_TIMER, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; return; } 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 ) { mST25 -> writeRegister(ST25R3911_REG_GPT1, gpt_8fcs >> 8, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; mST25 -> writeRegister(ST25R3911_REG_GPT2, gpt_8fcs & 0xff, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; return; } 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 ) { uint8_t regVal; regVal = 0; mST25 -> readRegister( reg, ®Val, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; return ((regVal & mask) == val ); } 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 ) { uint8_t ID; mST25 -> readRegister(ST25R3911_REG_IC_IDENTITY, &ID, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; /* Check if IC Identity Register contains ST25R3911's IC type code */ if( (ID & ST25R3911_REG_IC_IDENTITY_mask_ic_type) != (ST25R3911_REG_IC_IDENTITY_ic_type) ) { return false; } if(rev != NULL) { *rev = (ID & ST25R3911_REG_IC_IDENTITY_mask_ic_rev); } return true; } 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 ) { ReturnCode err = ERR_NONE; uint8_t nrt_step = 0; st25r3911NoResponseTime_64fcs = nrt_64fcs; if (nrt_64fcs > USHRT_MAX) { nrt_step = ST25R3911_REG_GPT_CONTROL_nrt_step; nrt_64fcs = (nrt_64fcs + 63) / 64; if (nrt_64fcs > USHRT_MAX) { nrt_64fcs = USHRT_MAX; err = ERR_PARAM; } st25r3911NoResponseTime_64fcs = 64 * nrt_64fcs; } 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 ) ; 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 ) ; 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 ) ; return err; } 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 ) { ReturnCode err; err = st25r3911SetNoResponseTime_64fcs( nrt_64fcs, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; if(err == ERR_NONE) { mST25 -> executeCommand(ST25R3911_CMD_START_NO_RESPONSE_TIMER, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; } return err; } 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 ) { uint8_t treMask; uint32_t irqs; if( (FieldONCmd != ST25R3911_CMD_INITIAL_RF_COLLISION) && (FieldONCmd != ST25R3911_CMD_RESPONSE_RF_COLLISION_0) && (FieldONCmd != ST25R3911_CMD_RESPONSE_RF_COLLISION_N) ) { return ERR_PARAM; } /* Check if new thresholds are to be applied */ if( (pdThreshold != ST25R3911_THRESHOLD_DO_NOT_SET) || (caThreshold != ST25R3911_THRESHOLD_DO_NOT_SET) ) { treMask = 0; if(pdThreshold != ST25R3911_THRESHOLD_DO_NOT_SET) { treMask |= ST25R3911_REG_FIELD_THRESHOLD_mask_trg; } if(caThreshold != ST25R3911_THRESHOLD_DO_NOT_SET) { treMask |= ST25R3911_REG_FIELD_THRESHOLD_mask_rfe; } /* Set Detection Threshold and|or Collision Avoidance Threshold */ 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 ) ; } /* Set n x TRFW */ 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 ) ; /* Enable and clear CA specific interrupts and execute command */ 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 ) ; 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 ) ; mST25 -> executeCommand(FieldONCmd, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 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 ) ; /* Clear any previous External Field events and disable CA specific interrupts */ 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 ) ; 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 ); if(ST25R3911_IRQ_MASK_CAC & irqs) /* Collision occurred */ { return ERR_RF_COLLISION; } if(ST25R3911_IRQ_MASK_CAT & irqs) /* No Collision detected, Field On */ { return ERR_NONE; } /* No interrupt detected */ return ERR_INTERNAL; } 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 ) { uint8_t regIt; uint8_t regDump[ST25R3911_REG_IC_IDENTITY+1]; if(!sizeRegDump || !resRegDump) { return ERR_PARAM; } for( regIt = ST25R3911_REG_IO_CONF1; regIt < SIZEOF_ARRAY(regDump); regIt++ ) { mST25 -> readRegister(regIt, ®Dump[regIt], mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; } *sizeRegDump = MIN(*sizeRegDump, regIt); ST_MEMCPY(resRegDump, regDump, *sizeRegDump ); return ERR_NONE; } 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 ) { 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 ) ; 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 ) ; } bool st25r3911IsCmdValid( uint8_t cmd ) { if( !((cmd >= ST25R3911_CMD_SET_DEFAULT) && (cmd <= ST25R3911_CMD_ANALOG_PRESET)) && !((cmd >= ST25R3911_CMD_MASK_RECEIVE_DATA) && (cmd <= ST25R3911_CMD_CLEAR_RSSI)) && !((cmd >= ST25R3911_CMD_TRANSPARENT_MODE) && (cmd <= ST25R3911_CMD_START_NO_RESPONSE_TIMER)) && !((cmd >= ST25R3911_CMD_TEST_CLEARA) && (cmd <= ST25R3911_CMD_FUSE_PPROM)) ) { return false; } return true; } 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 ) { uint8_t smd = 0; uint8_t mode; if (config->useBPSK) { mode = ST25R3911_REG_MODE_om_bpsk_stream; if (config->din<2 || config->din>4) /* not in fc/4 .. fc/16 */ { return ERR_PARAM; } smd |= (4 - config->din) << ST25R3911_REG_STREAM_MODE_shift_scf; } else { mode = ST25R3911_REG_MODE_om_subcarrier_stream; if (config->din<3 || config->din>6) /* not in fc/8 .. fc/64 */ { return ERR_PARAM; } smd |= (6 - config->din) << ST25R3911_REG_STREAM_MODE_shift_scf; if (config->report_period_length == 0) { return ERR_PARAM; } } if (config->dout<1 || config->dout>7) /* not in fc/2 .. fc/128 */ { return ERR_PARAM; } smd |= (7 - config->dout) << ST25R3911_REG_STREAM_MODE_shift_stx; if (config->report_period_length > 3) { return ERR_PARAM; } smd |= config->report_period_length << ST25R3911_REG_STREAM_MODE_shift_scp; mST25 -> writeRegister(ST25R3911_REG_STREAM_MODE, smd, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; 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 ) ; return ERR_NONE; } 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 ) { 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 ); } 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 ) { 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 ); } 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 ) { 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 ); } /* ****************************************************************************** * LOCAL FUNCTIONS ****************************************************************************** */ /*! ***************************************************************************** * \brief Executes a direct command and returns the result * * This function executes the direct command given by \a cmd waits for * \a sleeptime and returns the result read from register \a resreg. * * \param[in] cmd: direct command to execute. * \param[in] resreg: Address of the register containing the result. * \param[in] sleeptime: time in milliseconds to wait before reading the result. * \param[out] result: 8 bit long result * ***************************************************************************** */ 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 ) { if ( (cmd >= ST25R3911_CMD_INITIAL_RF_COLLISION && cmd <= ST25R3911_CMD_RESPONSE_RF_COLLISION_0) || (cmd == ST25R3911_CMD_MEASURE_AMPLITUDE) || (cmd >= ST25R3911_CMD_ADJUST_REGULATORS && cmd <= ST25R3911_CMD_MEASURE_PHASE) || (cmd >= ST25R3911_CMD_CALIBRATE_C_SENSOR && cmd <= ST25R3911_CMD_MEASURE_VDD) || (cmd >= 0xFD && cmd <= 0xFE ) ) { st25r3911EnableInterrupts(ST25R3911_IRQ_MASK_DCT, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; st25r3911GetInterrupt(ST25R3911_IRQ_MASK_DCT, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; mST25 -> executeCommand(cmd, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; st25r3911WaitForInterruptsTimed(ST25R3911_IRQ_MASK_DCT, sleeptime, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; st25r3911DisableInterrupts(ST25R3911_IRQ_MASK_DCT, mspiChannel, mST25, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; } else { return ERR_PARAM; } /* read out the result if the pointer is not NULL */ if (result) mST25 -> readRegister(resreg, result, mspiChannel, gpio_cs, IRQ, fieldLED_01, fieldLED_02, fieldLED_03, fieldLED_04, fieldLED_05, fieldLED_06 ) ; return ERR_NONE; }