FeliCa Link(RC-S730) Library
FeliCa Link(RC-S730) Library
- Not all API is tested.
RC-S730
- English Site http://www.sony.net/Products/felica/business/products/RC-S967.html
- Japanese Site http://www.sony.co.jp/Products/felica/business/products/RC-S967.html
Sample
Import programFelicaLink_sample
FeliCa Link library sample
- http:hiro99ma.blogspot.com/2015/03/felicafelica-linki2c.html
RCS730.cpp
- Committer:
- hiro99ma
- Date:
- 2015-03-29
- Revision:
- 1:bb5616cb01fb
- Parent:
- 0:be4ff952ae7a
File content as of revision 1:bb5616cb01fb:
/** FeliCa Link(RC-S730) Library * * @file RCS730.cpp * @author hiro99ma * @version 1.00 */ #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_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_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); } }