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.
Revision 0:be4ff952ae7a, committed 2015-03-29
- Comitter:
- hiro99ma
- Date:
- Sun Mar 29 06:11:57 2015 +0000
- Child:
- 1:bb5616cb01fb
- Commit message:
- first publish
Changed in this revision
| RCS730.cpp | Show annotated file Show diff for this revision Revisions of this file |
| RCS730.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/RCS730.cpp Sun Mar 29 06:11:57 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);
+ }
+}
+
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/RCS730.h Sun Mar 29 06:11:57 2015 +0000
@@ -0,0 +1,330 @@
+/** FeliCa Link(RC-S730) Library
+ *
+ * @file RCS730.h
+ * @author hiro99ma
+ * @version 1.00
+ */
+
+#ifndef RCS730_H
+#define RCS730_H
+
+#include "mbed.h"
+
+/** callback function type */
+typedef bool (*RCS730_CALLBACK_T)(void *pUser, uint8_t *pData, uint8_t Len);
+
+
+/** FeliCa Link(RC-S730) class
+ *
+ * @class RCS730
+ */
+class RCS730 {
+public:
+ static const uint16_t BLK_PAD0 = 0x0000; //!< [addr]PAD0
+ static const uint16_t BLK_PAD1 = 0x0001; //!< [addr]PAD1
+ static const uint16_t BLK_PAD2 = 0x0002; //!< [addr]PAD2
+ static const uint16_t BLK_PAD3 = 0x0003; //!< [addr]PAD3
+ static const uint16_t BLK_PAD4 = 0x0004; //!< [addr]PAD4
+ static const uint16_t BLK_PAD5 = 0x0005; //!< [addr]PAD5
+ static const uint16_t BLK_PAD6 = 0x0006; //!< [addr]PAD6
+ static const uint16_t BLK_PAD7 = 0x0007; //!< [addr]PAD7
+ static const uint16_t BLK_PAD8 = 0x0008; //!< [addr]PAD8
+ static const uint16_t BLK_PAD9 = 0x0009; //!< [addr]PAD9
+ static const uint16_t BLK_PAD10 = 0x000a; //!< [addr]PAD10
+ static const uint16_t BLK_PAD11 = 0x000b; //!< [addr]PAD11
+ static const uint16_t BLK_PAD12 = 0x000c; //!< [addr]PAD12
+ static const uint16_t BLK_PAD13 = 0x000d; //!< [addr]PAD13
+ static const uint16_t BLK_REG = 0x000e; //!< [addr]REG
+ static const uint16_t BLK_RC = 0x0080; //!< [addr]RC
+ static const uint16_t BLK_MAC = 0x0081; //!< [addr]MAC
+ static const uint16_t BLK_ID = 0x0082; //!< [addr]ID
+ static const uint16_t BLK_D_ID = 0x0083; //!< [addr]D_ID
+ static const uint16_t BLK_SER_C = 0x0084; //!< [addr]SER_C
+ static const uint16_t BLK_SYS_C = 0x0085; //!< [addr]SYS_C
+ static const uint16_t BLK_CKV = 0x0086; //!< [addr]CKV
+ static const uint16_t BLK_CK = 0x0087; //!< [addr]CK
+ static const uint16_t BLK_MC = 0x0088; //!< [addr]MC
+ static const uint16_t BLK_WCNT = 0x0090; //!< [addr]WCNT
+ static const uint16_t BLK_MAC_A = 0x0091; //!< [addr]MAC_A
+ static const uint16_t BLK_STATE = 0x0092; //!< [addr]STATE
+ static const uint16_t BLK_CRC_CHECK = 0x00a0; //!< [addr]CRC_CHECK
+
+ static const uint16_t REG_OPMODE = 0x0b00; //!< [addr]Operation Mode register
+ static const uint16_t REG_TAG_TX_CTRL = 0x0b04; //!< [addr]Tag TX Control register
+ static const uint16_t REG_TAG_RX_CTRL = 0x0b08; //!< [addr]Tag RX Control register
+ static const uint16_t REG_RF_STATUS = 0x0b0c; //!< [addr]RF Status register
+ static const uint16_t REG_I2C_SLAVE_ADDR = 0x0b10; //!< [addr]I2C Slave Address register
+ static const uint16_t REG_I2C_BUFF_CTRL = 0x0b14; //!< [addr]I2C Buffer Control register
+ static const uint16_t REG_I2C_STATUS = 0x0b18; //!< [addr]I2C Status register
+ static const uint16_t REG_INT_MASK = 0x0b20; //!< [addr]Interrupt Mask register
+ static const uint16_t REG_INT_RAW_STATUS = 0x0b24; //!< [addr]Interrupt Raw Status register
+ static const uint16_t REG_INT_STATUS = 0x0b28; //!< [addr]Interrupt Status register
+ static const uint16_t REG_INT_CLEAR = 0x0b2c; //!< [addr]Interrupt Clear register
+ static const uint16_t REG_WRT_PROTECT = 0x0b30; //!< [addr]Write Protect register
+ static const uint16_t REG_STBY_CTRL = 0x0b34; //!< [addr]Standby Control register
+ static const uint16_t REG_INIT_CTRL = 0x0b38; //!< [addr]Initialize Control register
+ static const uint16_t REG_HOST_IF_SECURITY = 0x0b40; //!< [addr]Host Interface Security register
+ static const uint16_t REG_HOST_IF_WCNT = 0x0b44; //!< [addr]Host Interface WCNT register
+ static const uint16_t REG_RF_PARAM = 0x0b50; //!< [addr]RF Parameter register
+ static const uint16_t REG_LITES_HT_CONF = 0x0b60; //!< [addr]Lite-S Host Through Configration register
+ static const uint16_t REG_LITES_PMM = 0x0b64; //!< [addr]Lite-S PMm register
+ static const uint16_t REG_PLUG_CONF1 = 0x0b80; //!< [addr]Plug Configration 1 register
+ static const uint16_t REG_PLUG_CONF2 = 0x0b84; //!< [addr]Plug Configration 2 register
+ static const uint16_t REG_PLUG_CONF3 = 0x0b88; //!< [addr]Plug Configration 3 register
+ static const uint16_t REG_DEP_CONF = 0x0ba0; //!< [addr]DEP Configration register
+ static const uint16_t REG_DEP_PMM1 = 0x0ba4; //!< [addr]DEP PMm1 register
+ static const uint16_t REG_DEP_PMM2 = 0x0ba8; //!< [addr]DEP PMm2 register
+ static const uint16_t REG_RW_CONF = 0x0bc0; //!< [addr]RW Configration register
+ static const uint16_t REG_RW_CTRL = 0x0b4c; //!< [addr]RW Control register
+ static const uint16_t REG_RW_TIMEOUT = 0x0bc8; //!< [addr]RW Timeout register
+
+ static const uint16_t BUF_RF_COMM = 0x0c00; //!< [addr]RF Communication
+ static const uint16_t BUF_I2CFELICA_COMM = 0x0d00; //!< [addr]I2C FeliCa Communication
+
+ static const uint32_t MSK_MODE_CHANGED = 0x80000000; //!< OPMODE changed
+ static const uint32_t MSK_INT_RW_RX_ERROR = 0x00080000; //!< [R/W]
+ static const uint32_t MSK_INT_RW_RX_TIMEOUT = 0x00040000; //!< [R/W]
+ static const uint32_t MSK_INT_RW_RX_DONE = 0x00020000; //!< [R/W]
+ static const uint32_t MSK_INT_RW_TX_DONE = 0x00010000; //!< [R/W]
+ static const uint32_t MSK_INT_I2C_FELICA_CMD_ERROR = 0x00000200; //!< [I2C]
+ static const uint32_t MSK_INT_I2C_FELICA_CMD_DONE = 0x00000100; //!< [I2C]
+ static const uint32_t MSK_INT_TAG_TX_DONE = 0x00000040; //!< [tag/DEP]Tx done
+ static const uint32_t MSK_INT_TAG_NFC_DEP_RX_DONE = 0x00000020; //!< [DEP]D4 command Rx done
+ static const uint32_t MSK_INT_TAG_RW_RX_DONE3 = 0x00000010; //!< [tag]Write w/o Enc Rx done for HT block
+ static const uint32_t MSK_INT_TAG_RW_RX_DONE2 = 0x00000008; //!< [tag]Read or Write w/o Enc Rx done for HT block
+ static const uint32_t MSK_INT_TAG_RW_RX_DONE1 = 0x00000004; //!< [tag]Write w/o Enc Rx done for User block
+ static const uint32_t MSK_INT_TAG_PL_RX_DONE = 0x00000002; //!< [tag]Polling Rx done
+ static const uint32_t MSK_INT_TAG_RX_DONE = 0x00000001; //!< [tag]Read or Write w/o Enc Rx done
+ static const uint32_t MSK_ALL = 0x800f037f;
+
+public:
+
+ /** Operation Mode
+ *
+ * @enum OpMode
+ */
+ enum OpMode {
+ OPMODE_LITES_HT = 0x00, //!< Lite-S HT mode
+ OPMODE_PLUG = 0x01, //!< Plug mode
+ OPMODE_NFCDEP = 0x02, //!< NFC-DEP mode
+ OPMODE_LITES = 0x03 //!< Lite-S mode
+ };
+
+
+ /** System Code in Plug mode
+ *
+ * @enum PlugSysCode
+ */
+ enum PlugSysCode {
+ PLUG_SYS_CODE_FEEL = 0, //!< 0xFEE1
+ PLUG_SYS_CODE_NDEF = 2, //!< 0x12FC
+ };
+
+
+ /** Callback Table
+ *
+ * @struct callbacktable_t
+ */
+ struct callbacktable_t {
+ void *pUserData; //!< User Data pointer
+ RCS730_CALLBACK_T pCbRxHTRDone; //!< Rx Done(Read w/o Enc[HT mode])
+ RCS730_CALLBACK_T pCbRxHTWDone; //!< Rx Done(Write w/o Enc[HT mode])
+#if 0
+ RCS730_CALLBACK_T pCbTxDone; //!< Tx Done
+ RCS730_CALLBACK_T pCbRxDepDone; //!< Rx Done(DEP mode)
+ RCS730_CALLBACK_T pCbOther; //!< Other IRQ interrupt
+#endif
+ };
+
+public:
+ /** constructor
+ *
+ * @param [in,out] I2c I2C
+ */
+ RCS730(I2C &I2c);
+
+ /** destructor
+ */
+ virtual ~RCS730();
+
+ /** Set Callback Table
+ *
+ * @param [in] pInitTable callback table
+ */
+ void setCallbackTable(const callbacktable_t *pInitTable);
+
+
+public:
+ /** Byte Write(1byte)
+ *
+ * @param [in] MemAddr memory address to write
+ * @param [in] pData data to write
+ * @retval 0 success
+ */
+ int byteWrite(uint16_t MemAddr, uint8_t Data);
+
+
+ /** Page Write
+ *
+ * @param [in] MemAddr memory address to write
+ * @param [in] pData data to write
+ * @param [in] Length pData Length
+ * @retval 0 success
+ */
+ int pageWrite(uint16_t MemAddr, const uint8_t *pData, int Length);
+
+
+ /** Random Read(1byte)
+ *
+ * @param [in] MemAddr memory address to read
+ * @param [out] pData data buffer to read
+ * @retval 0 success
+ */
+ int randomRead(uint16_t MemAddr, uint8_t *pData);
+
+
+ /** Sequential Read
+ *
+ * @param [in] MemAddr memory address to read
+ * @param [out] pData data buffer to read
+ * @param [in] Length pData Length
+ * @retval 0 success
+ */
+ int sequentialRead(uint16_t MemAddr, uint8_t *pData, int Length);
+
+
+ /** Current Address Read(1byte)
+ *
+ * @param [out] pData data buffer to read
+ * @retval 0 success
+ */
+ int currentAddrRead(uint8_t *pData);
+
+
+ /** Read Register
+ *
+ * @param [in] Reg FeliCa Link Register
+ * @param [out] pData data buffer to read
+ * @retval 0 success
+ */
+ inline int readRegister(uint16_t Reg, uint32_t *pData);
+
+
+ /** Write Register Force
+ *
+ * @param [in] Reg FeliCa Link Register
+ * @param [in] Data data buffer to write
+ * @retval 0 success
+ */
+ inline int writeRegisterForce(uint16_t Reg, uint32_t Data);
+
+
+ /** Write Register
+ *
+ * Write Register if not same.
+ *
+ * @param [in] Reg FeliCa Link Register
+ * @param [in] Data data buffer to write
+ * @param [in] Mask write mask(default: 0xffffffff)
+ * @retval 0 success
+ *
+ * @note
+ * - this API like below:
+ * @code
+ * uint32_t val = REG[Reg];
+ * REG[Reg] = (val & ~Mask) | Data;
+ * @endcode
+ */
+ int writeRegister(uint16_t Reg, uint32_t Data, uint32_t Mask=0xffffffff);
+
+
+ /** Set FeliCa Lite operation mode
+ *
+ * @param [in] Mode Operation Mode
+ * @retval 0 success
+ *
+ * @note
+ * - This value is written to non-volatile memory in FeliCa Link.
+ */
+ int setRegOpMode(OpMode Mode);
+
+
+ /** Set I2C Slave Address
+ *
+ * @param [in] SAddr Slave Address(7bit address)
+ * @retval 0 success
+ *
+ * @attention
+ * - SAddr is "7bit" address(not 8bit address).
+ *
+ * @note
+ * - This value is written to non-volatile memory in FeliCa Link.
+ * - Default slave address is 0x40.
+ */
+ int setRegSlaveAddr(int SAddr);
+
+
+ /** Set FeliCa Lite interrupt mask
+ *
+ * @param [in] Mask Bit Mask
+ * @param [in] Value Set value to Mask
+ * @retval 0 success
+ *
+ * @note
+ * - This value is written to non-volatile memory in FeliCa Link.
+ */
+ int setRegInterruptMask(uint32_t Mask, uint32_t Value);
+
+
+ /** Set System Code in Plug mode
+ *
+ * @param [in] SysCode System Code
+ * @retval 0 success
+ *
+ * @note
+ * - This value is written to non-volatile memory in FeliCa Link.
+ */
+ int setRegPlugSysCode(PlugSysCode SysCode);
+
+
+ /** go to initialize status
+ *
+ * @retval 0 success
+ */
+ int goToInitializeStatus();
+
+
+ /** initialize to FeliCa Through mode
+ *
+ * @param [in] Mode Operation Mode(OPMODE_LITES_HT or OPMODE_PLUG)
+ * @retval 0 success
+ */
+ int initFTMode(OpMode Mode);
+
+
+#if 0
+ /** initialize to NFC-DEP mode
+ *
+ * @retval 0 success
+ */
+ int initNfcDepMode();
+#endif
+
+
+ /** Interrupt Service Routine(IRQ pin)
+ *
+ */
+ void isrIrq();
+
+
+private:
+ I2C& _i2c; //!< I2C
+ int _slvAddr; //!< Slave Address(8bit)
+ callbacktable_t _cbTable; //!< Callback Table
+};
+
+#endif /* RCS730_H */
+
+
+
+