瀏覽代碼

m24lr64e: Initial Implementation

This module was developed and tested on the Grove NFC Tag.  It is an
8KB EEPROM accessable (with various protection capabilites) via I2C
and NFC capable devices.

The code was based on the Seeed Studio example code with some help
from the datasheet.

Signed-off-by: Jon Trulson <jtrulson@ics.com>
Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
Jon Trulson 9 年之前
父節點
當前提交
5733918a2f

+ 3
- 0
examples/c++/CMakeLists.txt 查看文件

@@ -122,6 +122,7 @@ add_executable (ht9170-example ht9170.cxx)
122 122
 add_executable (h3lis331dl-example h3lis331dl.cxx)
123 123
 add_executable (ad8232-example ad8232.cxx)
124 124
 add_executable (grovescam-example grovescam.cxx)
125
+add_executable (m24lr64e-example m24lr64e.cxx)
125 126
 
126 127
 include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l)
127 128
 include_directories (${PROJECT_SOURCE_DIR}/src/grove)
@@ -222,6 +223,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/ht9170)
222 223
 include_directories (${PROJECT_SOURCE_DIR}/src/h3lis331dl)
223 224
 include_directories (${PROJECT_SOURCE_DIR}/src/ad8232)
224 225
 include_directories (${PROJECT_SOURCE_DIR}/src/grovescam)
226
+include_directories (${PROJECT_SOURCE_DIR}/src/m24lr64e)
225 227
 
226 228
 target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT})
227 229
 target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT})
@@ -345,3 +347,4 @@ target_link_libraries (ht9170-example ht9170 ${CMAKE_THREAD_LIBS_INIT})
345 347
 target_link_libraries (h3lis331dl-example h3lis331dl ${CMAKE_THREAD_LIBS_INIT})
346 348
 target_link_libraries (ad8232-example ad8232 ${CMAKE_THREAD_LIBS_INIT})
347 349
 target_link_libraries (grovescam-example grovescam ${CMAKE_THREAD_LIBS_INIT})
350
+target_link_libraries (m24lr64e-example m24lr64e ${CMAKE_THREAD_LIBS_INIT})

+ 65
- 0
examples/c++/m24lr64e.cxx 查看文件

@@ -0,0 +1,65 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2015 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <unistd.h>
26
+#include <iostream>
27
+#include "m24lr64e.h"
28
+
29
+using namespace std;
30
+using namespace upm;
31
+
32
+int main(int argc, char **argv)
33
+{
34
+//! [Interesting]
35
+  // Instantiate an M24LR64E on I2C bus 0
36
+
37
+  upm::M24LR64E *nfcTag = new upm::M24LR64E(M24LR64E_I2C_BUS);
38
+
39
+  // This example accesses the device in the 'user' (default) mode,
40
+  // reads the last byte of data in the EEPROM, inverts it, writes
41
+  // it back, and then re-reads it.
42
+
43
+  // Read the last byte of the EEPROM area
44
+
45
+  int addr = M24LR64E::EEPROM_I2C_LENGTH - 1;
46
+  printf("Address: %d\n", addr);
47
+  uint8_t byte = nfcTag->readByte(addr);
48
+  printf("Read byte: %02x\n", byte);
49
+
50
+  // Now change it to it's opposite and write it
51
+  byte = ~byte;
52
+  nfcTag->writeByte(addr, byte);
53
+  printf("Wrote inverted byte: %02x\n", byte);
54
+
55
+  // Now read it back.
56
+  byte = nfcTag->readByte(addr);
57
+  printf("Read byte: %02x\n", byte);
58
+
59
+//! [Interesting]
60
+
61
+  cout << "Exiting..." << endl;
62
+
63
+  delete nfcTag;
64
+  return 0;
65
+}

+ 59
- 0
examples/javascript/m24lr64e.js 查看文件

@@ -0,0 +1,59 @@
1
+/*jslint node:true, vars:true, bitwise:true, unparam:true */
2
+/*jshint unused:true */
3
+
4
+/*
5
+ * Author: Jon Trulson <jtrulson@ics.com>
6
+ * Copyright (c) 2015 Intel Corporation.
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining
9
+ * a copy of this software and associated documentation files (the
10
+ * "Software"), to deal in the Software without restriction, including
11
+ * without limitation the rights to use, copy, modify, merge, publish,
12
+ * distribute, sublicense, and/or sell copies of the Software, and to
13
+ * permit persons to whom the Software is furnished to do so, subject to
14
+ * the following conditions:
15
+ *
16
+ * The above copyright notice and this permission notice shall be
17
+ * included in all copies or substantial portions of the Software.
18
+ *
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+
29
+var nfcTagObj = require('jsupm_m24lr64e');
30
+
31
+// Instantiate a M24LR64E Grove NFC Tag Module on UART 0
32
+var nfcTag = new nfcTagObj.M24LR64E(nfcTagObj.M24LR64E_I2C_BUS);
33
+
34
+// This example accesses the device in the 'user' (default) mode,
35
+// reads the last byte of data in the EEPROM, inverts it, writes
36
+// it back, and then re-reads it.
37
+
38
+// Read the last byte of the EEPROM area
39
+var addr = (nfcTagObj.M24LR64E.EEPROM_I2C_LENGTH - 1);
40
+console.log("Address: " + addr);
41
+var byte = nfcTag.readByte(addr);
42
+
43
+console.log("Read byte: " + byte.toString(16));
44
+
45
+// Now change it to it's opposite and write it
46
+byte = (~byte & 0xff);
47
+nfcTag.writeByte(addr, byte);
48
+console.log("Wrote inverted byte: " + byte.toString(16));
49
+
50
+// Now read it back.
51
+byte = nfcTag.readByte(addr);
52
+console.log("Read byte: " + byte.toString(16));
53
+
54
+// clean up
55
+nfcTag = null;
56
+nfcTagObj.cleanUp();
57
+nfcTagObj = null;
58
+console.log("Exiting...");
59
+process.exit(0);

+ 49
- 0
examples/python/m24lr64e.py 查看文件

@@ -0,0 +1,49 @@
1
+#!/usr/bin/python
2
+# Author: Jon Trulson <jtrulson@ics.com>
3
+# Copyright (c) 2015 Intel Corporation.
4
+#
5
+# Permission is hereby granted, free of charge, to any person obtaining
6
+# a copy of this software and associated documentation files (the
7
+# "Software"), to deal in the Software without restriction, including
8
+# without limitation the rights to use, copy, modify, merge, publish,
9
+# distribute, sublicense, and/or sell copies of the Software, and to
10
+# permit persons to whom the Software is furnished to do so, subject to
11
+# the following conditions:
12
+#
13
+# The above copyright notice and this permission notice shall be
14
+# included in all copies or substantial portions of the Software.
15
+#
16
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+import sys
25
+import pyupm_m24lr64e as nfcTagObj
26
+
27
+# Instantiate a M24LR64E Grove NFC Tag Module on UART 0
28
+nfcTag = nfcTagObj.M24LR64E(nfcTagObj.M24LR64E_I2C_BUS)
29
+
30
+# This example accesses the device in the 'user' (default) mode,
31
+# reads the last byte of data in the EEPROM, inverts it, writes
32
+# it back, and then re-reads it.
33
+
34
+# Read the last byte of the EEPROM area
35
+addr = (nfcTagObj.M24LR64E.EEPROM_I2C_LENGTH - 1)
36
+print "Address: ", addr
37
+byte = nfcTag.readByte(addr)
38
+
39
+print "Read byte: ", format(byte, '02x')
40
+
41
+# Now change it to it's opposite and write it
42
+byte = (~byte & 0xff)
43
+nfcTag.writeByte(addr, byte)
44
+print "Wrote inverted byte: ", format(byte, '02x')
45
+
46
+# Now read it back.
47
+byte = nfcTag.readByte(addr)
48
+print "Read byte: ", format(byte, '02x')
49
+

+ 5
- 0
src/m24lr64e/CMakeLists.txt 查看文件

@@ -0,0 +1,5 @@
1
+set (libname "m24lr64e")
2
+set (libdescription "upm m24lr64e grove NFC tag")
3
+set (module_src ${libname}.cxx)
4
+set (module_h ${libname}.h)
5
+upm_module_init()

+ 10
- 0
src/m24lr64e/jsupm_m24lr64e.i 查看文件

@@ -0,0 +1,10 @@
1
+%module jsupm_m24lr64e
2
+%include "../upm.i"
3
+
4
+%include "stdint.i"
5
+
6
+%{
7
+    #include "m24lr64e.h"
8
+%}
9
+
10
+%include "m24lr64e.h"

+ 290
- 0
src/m24lr64e/m24lr64e.cxx 查看文件

@@ -0,0 +1,290 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2015 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <unistd.h>
26
+#include <math.h>
27
+#include <iostream>
28
+#include <string>
29
+
30
+#include "m24lr64e.h"
31
+
32
+using namespace upm;
33
+using namespace std;
34
+
35
+
36
+M24LR64E::M24LR64E(int bus, AccessMode mode):
37
+  m_i2c(bus)
38
+{
39
+  if (mode == USER_MODE)
40
+    m_addr = M24LR64E_DEFAULT_I2C_ADDR;
41
+  else
42
+    m_addr = M24LR64E_DEFAULT_I2C_ADDR_E2;
43
+
44
+  mraa_result_t rv;
45
+  if ( (rv = m_i2c.address(m_addr)) != MRAA_SUCCESS)
46
+    {
47
+      cerr << "M24LR64E: Could not initialize i2c address. " << endl;
48
+      mraa_result_print(rv);
49
+      return;
50
+    }
51
+}
52
+
53
+M24LR64E::~M24LR64E()
54
+{
55
+}
56
+
57
+bool M24LR64E::submitPasswd(uint32_t passwd)
58
+{
59
+  // this device actually uses two bytes to address a register
60
+  const int pktLen = 11;
61
+  uint8_t buf[pktLen];
62
+
63
+  buf[0] = 0x09;
64
+  buf[1] = 0x00;
65
+
66
+  buf[2] = ((passwd >> 24) & 0xff);
67
+  buf[3] = ((passwd >> 16) & 0xff);
68
+  buf[4] = ((passwd >> 8) & 0xff);
69
+  buf[5] = (passwd & 0xff);
70
+
71
+  buf[6] = 0x09;
72
+
73
+  // the password is written twice
74
+  buf[7] = ((passwd >> 24) & 0xff);
75
+  buf[8] = ((passwd >> 16) & 0xff);
76
+  buf[9] = ((passwd >> 8) & 0xff);
77
+  buf[10] = (passwd & 0xff);
78
+  
79
+  if (m_i2c.write(buf, pktLen))
80
+    {
81
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": write failed" << endl;
82
+      return false;
83
+    }
84
+
85
+  return true;
86
+}
87
+
88
+bool M24LR64E::writePasswd(uint32_t passwd)
89
+{
90
+  const int pktLen = 11;
91
+  uint8_t buf[pktLen];
92
+
93
+  buf[0] = 0x09;
94
+  buf[1] = 0x00;
95
+
96
+  buf[2] = ((passwd >> 24) & 0xff);
97
+  buf[3] = ((passwd >> 16) & 0xff);
98
+  buf[4] = ((passwd >> 8) & 0xff);
99
+  buf[5] = (passwd & 0xff);
100
+
101
+  buf[6] = 0x07;
102
+
103
+  // the password is written twice
104
+  buf[7] = ((passwd >> 24) & 0xff);
105
+  buf[8] = ((passwd >> 16) & 0xff);
106
+  buf[9] = ((passwd >> 8) & 0xff);
107
+  buf[10] = (passwd & 0xff);
108
+  
109
+  if (m_i2c.write(buf, pktLen))
110
+    {
111
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": write failed" << endl;
112
+      return false;
113
+    }
114
+
115
+  return true;
116
+}
117
+
118
+void M24LR64E::sectorProtectConfig(unsigned int sectorNumber, 
119
+                                   bool protectEnable, 
120
+                                   SectorAccessRight accessRight, 
121
+                                   SectorSelectPassWd passwd)
122
+{
123
+  if(!protectEnable) {
124
+    EEPROM_Write_Byte(sectorNumber,0x0);
125
+  } else {
126
+    EEPROM_Write_Byte(sectorNumber,
127
+                      protectEnable | (accessRight<<1) |(passwd<<2));
128
+  }
129
+}
130
+
131
+void M24LR64E::clearSectorProtect(void)
132
+{
133
+  uint8_t buf[64]={0x0};
134
+  EEPROM_Write_Bytes(0, buf, 64);
135
+}
136
+
137
+
138
+void M24LR64E::sectorWriteLockBit(unsigned int sectorNumber, 
139
+                                  bool sockEnable)
140
+{
141
+  unsigned int sectorAddress = SECTOR_SECURITY_STATUS_BASE_ADDR 
142
+    + (sectorNumber/8);
143
+  uint8_t sectorBit = sectorNumber % 8;
144
+  uint8_t preStatus = EEPROM_Read_Byte(sectorAddress);
145
+  
146
+  bool status = (preStatus >> sectorBit) & 0x01;
147
+  if(status != sockEnable) {
148
+    if(status == true) {
149
+      writeByte(sectorAddress,preStatus&(~(1<<sectorBit)));
150
+    } else {
151
+      writeByte(sectorAddress,preStatus|(1<<sectorBit));
152
+    }
153
+  }
154
+}
155
+
156
+uint8_t M24LR64E::getDSFID()
157
+{
158
+  return EEPROM_Read_Byte(DSFID_ADDR);
159
+}
160
+
161
+uint8_t M24LR64E::getAFI()
162
+{
163
+  return EEPROM_Read_Byte(AFI_ADDR);
164
+}
165
+
166
+void M24LR64E::getUID(uint8_t* buf)
167
+{
168
+  EEPROM_Read_Bytes(UID_ADDR,buf,UID_LENGTH);    
169
+}
170
+
171
+uint32_t M24LR64E::getMemorySize()
172
+{
173
+  uint32_t volume = 0x0;
174
+  volume = EEPROM_Read_Byte(MEM_SIZE_ADDR); 
175
+  volume = volume<<8|EEPROM_Read_Byte(MEM_SIZE_ADDR+1);
176
+  volume = volume<<8|EEPROM_Read_Byte(MEM_SIZE_ADDR+2);
177
+  return volume;
178
+}
179
+
180
+void M24LR64E::clearMemory()
181
+{
182
+  for(int i = 0; i < EEPROM_I2C_LENGTH; i++){
183
+    writeByte(i,0x0);
184
+  }
185
+}
186
+
187
+void M24LR64E::writeByte(unsigned int address, uint8_t data)
188
+{
189
+  EEPROM_Write_Byte(address, data);
190
+}
191
+
192
+void M24LR64E::writeBytes(unsigned int address, uint8_t* buf, unsigned int len)
193
+{
194
+  EEPROM_Write_Bytes(address, buf, len);
195
+}
196
+
197
+uint8_t M24LR64E::readByte(unsigned int address)
198
+{
199
+  return EEPROM_Read_Byte(address);
200
+}
201
+
202
+void M24LR64E::readBytes(unsigned int address, uint8_t* buf, unsigned int len)
203
+{
204
+  EEPROM_Read_Bytes(address, buf, len);
205
+}
206
+
207
+void M24LR64E::EEPROM_Write_Byte(unsigned int address, uint8_t data)
208
+{
209
+  const int pktLen = 3;
210
+  uint8_t buf[pktLen];
211
+  
212
+  buf[0] = ((address >> 8) & 0xff);
213
+  buf[1] = (address & 0xff);
214
+  buf[2] = data;
215
+
216
+  if (m_i2c.write(buf, pktLen))
217
+    cerr << __FUNCTION__ << "@" << __LINE__ << ": write failed" << endl;
218
+
219
+  usleep(I2C_WRITE_TIME * 1000);
220
+}
221
+
222
+void M24LR64E::EEPROM_Write_Bytes(unsigned int address, uint8_t* data,
223
+                                  unsigned int len)
224
+{
225
+  const int pktLen = 2 + len;
226
+  uint8_t buf[pktLen];
227
+  
228
+  buf[0] = ((address >> 8) & 0xff);
229
+  buf[1] = (address & 0xff);
230
+
231
+  for (int i=0; i<len; i++)
232
+    buf[2+i] = data[i];
233
+
234
+  if (m_i2c.write(buf, pktLen))
235
+    cerr << __FUNCTION__ << "@" << __LINE__ << ": write failed" << endl;
236
+
237
+  usleep(I2C_WRITE_TIME * 1000);
238
+}
239
+
240
+uint8_t M24LR64E::EEPROM_Read_Byte(unsigned int address)
241
+{
242
+  const int apktLen = 2;
243
+  uint8_t abuf[apktLen];
244
+
245
+  abuf[0] = ((address >> 8) & 0xff);
246
+  abuf[1] = (address & 0xff);
247
+  
248
+  if (m_i2c.write(abuf, apktLen))
249
+    {
250
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": write failed" << endl;
251
+      return 0x00;
252
+    }
253
+
254
+  const int pktLen = 1;
255
+  uint8_t buf[apktLen];
256
+
257
+  buf[0] = 0;
258
+  
259
+  if (m_i2c.read(buf, pktLen) != pktLen)
260
+    {
261
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": read failed" << endl;
262
+      return 0x00;
263
+    }
264
+  
265
+  return buf[0];
266
+}
267
+
268
+unsigned int M24LR64E::EEPROM_Read_Bytes(unsigned int address, 
269
+                                         uint8_t* buf, unsigned int len)
270
+{
271
+  const int apktLen = 2;
272
+  uint8_t abuf[apktLen];
273
+
274
+  abuf[0] = ((address >> 8) & 0xff);
275
+  abuf[1] = (address & 0xff);
276
+  
277
+  if (m_i2c.write(abuf, apktLen))
278
+    {
279
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": write failed" << endl;
280
+      return false;
281
+    }
282
+
283
+  int rv = m_i2c.read(buf, len);
284
+  if (rv != len)
285
+    {
286
+      cerr << __FUNCTION__ << "@" << __LINE__ << ": read failed" << endl;
287
+    }
288
+
289
+  return rv;
290
+}

+ 282
- 0
src/m24lr64e/m24lr64e.h 查看文件

@@ -0,0 +1,282 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2015 Intel Corporation.
4
+ *
5
+ *
6
+ * This code was adapted from the Seeed Studio code at:
7
+ * https://github.com/Seeed-Studio/NFC_Tag_M24LR6E  
8
+ *
9
+ * Copyright (c) 2014 seeed technology inc.
10
+ * Website    : www.seeed.cc
11
+ * Author     : lawliet zou
12
+ * Create Time: March 2014
13
+ *
14
+ * Permission is hereby granted, free of charge, to any person obtaining
15
+ * a copy of this software and associated documentation files (the
16
+ * "Software"), to deal in the Software without restriction, including
17
+ * without limitation the rights to use, copy, modify, merge, publish,
18
+ * distribute, sublicense, and/or sell copies of the Software, and to
19
+ * permit persons to whom the Software is furnished to do so, subject to
20
+ * the following conditions:
21
+ *
22
+ * The above copyright notice and this permission notice shall be
23
+ * included in all copies or substantial portions of the Software.
24
+ *
25
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
+ */
33
+#pragma once
34
+
35
+#include <string>
36
+#include <mraa/i2c.hpp>
37
+
38
+#define M24LR64E_I2C_BUS 0
39
+#define M24LR64E_DEFAULT_I2C_ADDR 0x53
40
+#define M24LR64E_DEFAULT_I2C_ADDR_E2 (M24LR64E_DEFAULT_I2C_ADDR | 0x04)
41
+
42
+namespace upm {
43
+  
44
+  /**
45
+   * @brief Grove NFC Tag
46
+   * @defgroup m24lr64e libupm-m24lr64e
47
+   * @ingroup seeed i2c other
48
+   */
49
+
50
+  /**
51
+   * @library m24lr64e
52
+   * @sensor m24lr64e
53
+   * @comname Grove NFC Tag
54
+   * @type other
55
+   * @man seeed
56
+   * @web http://www.seeedstudio.com/wiki/Grove_-_NFC_Tag
57
+   * @con i2c
58
+   *
59
+   * @brief C++ API for the M24LR64E based Grove NFC Tag
60
+   *
61
+   * The Grove NFC tag is, in essence, an 8KB EEPROM that can be written
62
+   * to or read from using I2C and NFC equipped devices.
63
+   *
64
+   * The USER mode (default) allows read and write access to all 8KB
65
+   * of space, provided the sector security status (SSS) allows it.
66
+   * The ROOT mode allows modification of the SSS data and other
67
+   * information, provided the proper password is submitted.  The
68
+   * default password for a new tag is 0x00000000.  See the data sheet
69
+   * for much more detailed information.
70
+   *
71
+   * The Seeed Studio wiki page for this device includes a link to an
72
+   * Android application that can be used to also read and write the
73
+   * device via NFC, as well as set the NFC passwords, which cannot be
74
+   * done via I2C.
75
+   *
76
+   * @snippet m24lr64e.cxx Interesting
77
+   */
78
+  class M24LR64E {
79
+  public:
80
+    
81
+    static const int EEPROM_I2C_LENGTH          = 8192;
82
+    static const int PASSWORD_LENGTH            = 4;
83
+    static const int SECTOR_SECURITY_STATUS_BASE_ADDR = 0x800; // 2048
84
+    
85
+    static const uint8_t LOCK_PROTECT_BIT       = 0x01;
86
+    static const uint8_t WRITE_READ_PROTECT_BIT = 0x02;
87
+    static const uint8_t PASSWORD_CTRL_BIT      = 0x04;
88
+    
89
+    static const int UID_LENGTH                 = 8; // bytes
90
+
91
+    static const unsigned int I2C_WRITE_TIME    = 5; // 5ms
92
+
93
+    /**
94
+     * M24LR64E addresses, accessable only in root mode
95
+     */
96
+    typedef enum {
97
+      I2C_PASSWORD_ADDR                  = 2304,
98
+      RF_PASSWORD_1_ADDR                 = 2308, // RF pwds not available in
99
+      RF_PASSWORD_2_ADDR                 = 2312, // i2c access modes
100
+      RF_PASSWORD_3_ADDR                 = 2316,
101
+      DSFID_ADDR                         = 2320, // 1 byte
102
+      AFI_ADDR                           = 2321, // 1 byte
103
+      RESV_ADDR                          = 2322, // 1 bytes
104
+      CONFIG_ADDR                        = 2323, // 1 bytes
105
+      UID_ADDR                           = 2324, // 8 bytes
106
+      MEM_SIZE_ADDR                      = 2332, // 3 bytes
107
+      IC_REF_ADDR                        = 2335, // 1 byte
108
+      PROG_COMP_ENERGY_HARVEST_ADDR      = 2339  // 1 byte
109
+    } M24LR64E_ADDR_T;
110
+
111
+    enum AccessMode {
112
+      USER_MODE = 0x0,   // offer simple read/write access right
113
+      ROOT_MODE = 0x1    // offer password change access right
114
+    };
115
+
116
+    enum SectorAccessRight {
117
+      //      **********************************
118
+      //      *  submit passWd *   no submit   * 
119
+      //b2,b1 *  Read * Write  *  Read * Write *
120
+      // 00   *    1       1        1      0   *
121
+      // 01   *    1       1        1      1   *
122
+      // 10   *    1       1        0      0   *
123
+      // 11   *    0       1        0      0   *
124
+      //      **********************************
125
+      Access_1110 = 0,
126
+      Access_1111 = 1,
127
+      Access_1100 = 2,
128
+      Access_0111 = 3,
129
+    };
130
+
131
+    enum SectorSelectPassWd {
132
+      //00 => no passwd protect
133
+      //01 => passWd 1
134
+      //10 => passWd 2
135
+      //11 => passwd 3
136
+      noPasswd = 0,
137
+      passwd_1 = 1,
138
+      passwd_2 = 2,
139
+      passwd_3 = 3,
140
+    };
141
+
142
+    /**
143
+     * m24lr64e constructor
144
+     *
145
+     * @param bus i2c bus to use
146
+     * @param mode the access mode (user or root) to use
147
+     */
148
+    M24LR64E(int bus, AccessMode mode = USER_MODE);
149
+
150
+    /**
151
+     * M24LR64E Destructor
152
+     */
153
+    ~M24LR64E();
154
+    
155
+    /**
156
+     * submit an i2c access password
157
+     *
158
+     * @param passwd the 4-byte access password
159
+     */
160
+    bool submitPasswd(uint32_t passwd);
161
+
162
+    /**
163
+     * write a new i2c password
164
+     *
165
+     * @param passwd the 4-byte access password
166
+     */
167
+    bool writePasswd(uint32_t passwd);
168
+
169
+    /**
170
+     * Set the protection bit for a sector. Must be in ROOT mode
171
+     *
172
+     * @param sectorNumber the sector whose protection you are modifying
173
+     * @param protectEnable true if you are enabling protection
174
+     * @param accessRight the access rights to set
175
+     * @param passwd the password number to enable, if any
176
+     */
177
+    void sectorProtectConfig(unsigned int sectorNumber, 
178
+                             bool protectEnable, 
179
+                             SectorAccessRight accessRight, 
180
+                             SectorSelectPassWd passwd);
181
+
182
+    /**
183
+     * Clear the sector protection bits.  Must be in ROOT mode.
184
+     */
185
+    void clearSectorProtect(void);
186
+
187
+    /**
188
+     * Set or clear the Sector Security Status Lock bit for a sector.  
189
+     * Must be in ROOT mode.
190
+     *
191
+     * @param sectorNumber the sector who's SSS you want to modify
192
+     * @param sockEnable true r false to set or clear the bit
193
+     */
194
+    void sectorWriteLockBit(unsigned int sectorNumber, 
195
+                            bool sockEnable);
196
+
197
+    /**
198
+     * return the Data Storage Familiy Identifier
199
+     * Must be in ROOT mode.
200
+     *
201
+     * @return the DSFID
202
+     */
203
+    uint8_t getDSFID();
204
+
205
+    /**
206
+     * return the Application Family Identifier
207
+     * Must be in ROOT mode.
208
+     *
209
+     * @return the AFI
210
+     */
211
+    uint8_t getAFI();
212
+
213
+    /**
214
+     * return the Unique ID.
215
+     * Must be in ROOT mode.
216
+     *
217
+     * @param buf buffer to hold returned UID.  Must be UID_LENGTH bytes.
218
+     */
219
+    void getUID(uint8_t* buf);
220
+
221
+    /**
222
+     * return the memory size
223
+     * Must be in ROOT mode.
224
+     *
225
+     * @return the amount of memory present
226
+     */
227
+    uint32_t getMemorySize();
228
+
229
+    /**
230
+     * set all memory to 0, if permissions allow
231
+     */
232
+    void clearMemory();
233
+
234
+    /**
235
+     * write a byte to EEPROM
236
+     *
237
+     * @param address address to write to
238
+     * @param data data to write
239
+     */
240
+    void writeByte(unsigned int address, uint8_t data);
241
+
242
+    /**
243
+     * write bytes to EEPROM
244
+     *
245
+     * @param address address to write to
246
+     * @param data data to write
247
+     * @param data length of data buffer
248
+     */
249
+    void writeBytes(unsigned int address, uint8_t* buf, unsigned int len);
250
+
251
+    /**
252
+     * read a byte from EEPROM
253
+     *
254
+     * @param address address to read from
255
+     * @return data value read
256
+     */
257
+    uint8_t readByte(unsigned int address);
258
+
259
+    /**
260
+     * read multiple bytes from EEPROM
261
+     *
262
+     * @param address address to read from
263
+     * @param buffer buffer to store data
264
+     * @param len number of bytes to read
265
+     */
266
+    void readBytes(unsigned int address, uint8_t* buf, unsigned int len);
267
+
268
+  protected:
269
+    mraa::I2c m_i2c;
270
+    void EEPROM_Write_Byte(unsigned int address, uint8_t data);
271
+    void EEPROM_Write_Bytes(unsigned int address, uint8_t* data,
272
+                            unsigned int len);
273
+    uint8_t EEPROM_Read_Byte(unsigned int address);
274
+    unsigned int EEPROM_Read_Bytes(unsigned int address, 
275
+                                   uint8_t* buf, unsigned int len);
276
+
277
+  private:
278
+    uint8_t m_addr;
279
+  };
280
+}
281
+
282
+

+ 15
- 0
src/m24lr64e/pyupm_m24lr64e.i 查看文件

@@ -0,0 +1,15 @@
1
+%module pyupm_m24lr64e
2
+%include "../upm.i"
3
+
4
+%include "stdint.i"
5
+
6
+%feature("autodoc", "3");
7
+
8
+#ifdef DOXYGEN
9
+%include "m24lr64e_doc.i"
10
+#endif
11
+
12
+%include "m24lr64e.h"
13
+%{
14
+    #include "m24lr64e.h"
15
+%}