FeliCa Link library sample
Dependencies: RCS730 SB1602E mbed
FeliCa Link Library using sample (NUCLEO-F411RE).
- SCL/D15 ... SCL
- SDA/D14 ... SDA
- D8(PA_9) ... IRQ
- D7(PA_8) ... RFDET (LED blink)
SB1602E is used for debugging. Not necessary.
Diff: RCS730.cpp
- Revision:
- 0:6efd0ff1fcbe
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RCS730.cpp Sun Mar 29 06:13:12 2015 +0000 @@ -0,0 +1,303 @@ +#include "RCS730.h" + + +namespace { + const int I2C_SLV_ADDR = 0x80; //Default Slave Address(8bit) + const int RETRY_NUM = 5; //max I2C Retry count + + + inline int set_tag_rf_send_enable(RCS730 *pRcs) + { + uint32_t val = 0x00000001; + return pRcs->pageWrite(RCS730::REG_TAG_TX_CTRL, reinterpret_cast<const uint8_t*>(&val), sizeof(val)); + } + + int read_rf_buf(RCS730 *pRcs, uint8_t *pData) + { + const int LEN_FIRST = 16; + int len = 0; + int ret; + + //read from LEN + ret = pRcs->sequentialRead(RCS730::BUF_RF_COMM, pData, LEN_FIRST); + if (ret == 0) { + len = pData[0]; + } + if ((ret == 0) && (pData[0] > LEN_FIRST)) { + ret = pRcs->sequentialRead(RCS730::BUF_RF_COMM + LEN_FIRST, pData + LEN_FIRST, pData[0] - LEN_FIRST); + if (ret != 0) { + len = 0; + } + } + + return len; + } +} + + +RCS730::RCS730(I2C &I2c) + : _i2c(I2c), _slvAddr(I2C_SLV_ADDR) +{ + _cbTable.pUserData = 0; + _cbTable.pCbRxHTRDone = 0; + _cbTable.pCbRxHTWDone = 0; +} + +RCS730::~RCS730() +{ +} + + +void RCS730::setCallbackTable(const callbacktable_t *pInitTable) +{ + _cbTable = *pInitTable; +} + + +int RCS730::byteWrite(uint16_t MemAddr, uint8_t Data) +{ + int ret; + int retry = RETRY_NUM; + char buf[3]; + + buf[0] = (char)(MemAddr >> 8); + buf[1] = (char)(MemAddr & 0xff); + buf[2] = (char)Data; + + do { + ret = _i2c.write(_slvAddr, buf, (int)sizeof(buf)); + } while ((ret != 0) && (retry--)); + + return ret; +} + + +int RCS730::pageWrite(uint16_t MemAddr, const uint8_t *pData, int Length) +{ + int ret; + int retry = RETRY_NUM; + char buf[2]; + + buf[0] = (char)(MemAddr >> 8); + buf[1] = (char)(MemAddr & 0xff); + + do { + ret = _i2c.write(_slvAddr, buf, (int)sizeof(buf), true); + } while ((ret != 0) && (retry--)); + if (ret == 0) { + for (int i = 0; i < Length; i++) { + ret = !_i2c.write(pData[i]); //I2C::write(b) return 1 if success. + if (ret != 0) { + break; + } + } + } + _i2c.stop(); + + return ret; +} + + +int RCS730::randomRead(uint16_t MemAddr, uint8_t *pData) +{ + return sequentialRead(MemAddr, pData, 1); +} + + +int RCS730::sequentialRead(uint16_t MemAddr, uint8_t *pData, int Length) +{ + int ret; + int retry = RETRY_NUM; + char buf[2]; + + buf[0] = (char)(MemAddr >> 8); + buf[1] = (char)(MemAddr & 0xff); + + do { + ret = _i2c.write(_slvAddr, buf, (int)sizeof(buf), true); + } while ((ret != 0) && (retry--)); + if (ret == 0) { + ret = _i2c.read(_slvAddr | 1, reinterpret_cast<char*>(pData), Length); + } + + return ret; +} + + +int RCS730::currentAddrRead(uint8_t *pData) +{ + int ret; + int retry = RETRY_NUM; + + do { + ret = _i2c.read((int)(_slvAddr | 1), reinterpret_cast<char*>(pData), 1); + } while ((ret != 0) && (retry--)); + + return ret; +} + + +inline int RCS730::readRegister(uint16_t Reg, uint32_t* pData) +{ + return sequentialRead(Reg, reinterpret_cast<uint8_t*>(pData), sizeof(uint32_t)); +} + + +inline int RCS730::writeRegisterForce(uint16_t Reg, uint32_t Data) +{ + return pageWrite(Reg, reinterpret_cast<const uint8_t*>(&Data), sizeof(Data)); +} + + +int RCS730::writeRegister(uint16_t Reg, uint32_t Data, uint32_t Mask/*=0xffffffff*/) +{ + int ret; + uint32_t cur; //current register value + + ret = readRegister(Reg, &cur); + if (ret == 0) { + if ((cur & Mask) != Data) { + // change value + Data |= cur & ~Mask; + ret = writeRegisterForce(Reg, Data); + } + } + + return ret; +} + + +int RCS730::setRegOpMode(OpMode Mode) +{ + return writeRegister(REG_OPMODE, static_cast<uint32_t>(Mode)); +} + + +int RCS730::setRegSlaveAddr(int SAddr) +{ + int ret; + + ret = writeRegister(REG_I2C_SLAVE_ADDR, static_cast<uint32_t>(SAddr)); + + if (ret == 0) { + _slvAddr = SAddr << 1; + } + + return ret; +} + + +int RCS730::setRegInterruptMask(uint32_t Mask, uint32_t Value) +{ + return writeRegister(REG_INT_MASK, Value, Mask); +} + + +int RCS730::setRegPlugSysCode(PlugSysCode SysCode) +{ + return writeRegister(REG_PLUG_CONF1, static_cast<uint32_t>(SysCode), 0x00000002); +} + + +int RCS730::goToInitializeStatus() +{ + return writeRegisterForce(REG_INIT_CTRL, 0x0000004a); +} + + +int RCS730::initFTMode(OpMode Mode) +{ + int ret; + + if (OPMODE_PLUG < Mode) { + return -1; + } + + ret = setRegOpMode(Mode); + if (ret == 0) { + //ret = setRegInterruptMask(MSK_INT_TAG_TX_DONE | MSK_INT_TAG_RW_RX_DONE2, 0); + ret = setRegInterruptMask(MSK_INT_TAG_RW_RX_DONE2, 0); + } + + return ret; +} + + +#if 0 +int RCS730::initNfcDepMode() +{ + int ret; + + ret = setRegOpMode(OPMODE_NFCDEP); + if (ret == 0) { + ret = setRegInterruptMask(MSK_INT_TAG_TX_DONE | MSK_INT_TAG_NFC_DEP_RX_DONE, 0); + } + + return ret; +} +#endif + + +void RCS730::isrIrq() +{ + int ret; + bool b_send = false; + uint32_t intstat; + uint8_t rf_buf[256]; + + ret = readRegister(REG_INT_STATUS, &intstat); + if (ret == 0) { + + if (intstat & MSK_INT_TAG_RW_RX_DONE2) { + //Read or Write w/o Enc Rx done for HT block + int len = read_rf_buf(this, rf_buf); + if (len > 0) { + switch (rf_buf[1]) { + case 0x06: //Read w/o Enc + if (_cbTable.pCbRxHTRDone) { + b_send = (*_cbTable.pCbRxHTRDone)(_cbTable.pUserData, rf_buf, len); + } + break; + case 0x08: //Write w/o Enc; + if (_cbTable.pCbRxHTWDone) { + b_send = (*_cbTable.pCbRxHTWDone)(_cbTable.pUserData, rf_buf, len); + } + break; + default: + break; + } + } + } +#if 0 + if (_cbTable.pCbRxDepDone && (intstat & MSK_INT_TAG_NFC_DEP_RX_DONE)) { + //DEP command Rx done + int len = read_rf_buf(this, rf_buf); + (*_cbTable.pCbRxDepDone)(_cbTable.pUserData, rf_buf, len); + } + if (_cbTable.pCbTxDone && (intstat & MSK_INT_TAG_TX_DONE)) { + //Tx Done + int len = read_rf_buf(this, rf_buf); + (*_cbTable.pCbTxDone)(_cbTable.pUserData, rf_buf, len); + } + + uint32_t intother = intstat & ~(MSK_INT_TAG_TX_DONE | MSK_INT_TAG_NFC_DEP_RX_DONE | MSK_INT_TAG_RW_RX_DONE2); + if (_cbTable.pCbOther && intother) { + (*_cbTable.mCbOther)(_cbTable.pUserData, 0, intother); + } +#endif + + //response + if (b_send) { + ret = pageWrite(BUF_RF_COMM, rf_buf, rf_buf[0]); + if (ret == 0) { + set_tag_rf_send_enable(this); + } + } + + writeRegisterForce(REG_INT_CLEAR, intstat); + } +} + + + +