Bladeren bron

sm130: Added new sensor (basic function was implemented and not tested)

Signed-off-by: Kiveisha Yevgeniy <yevgeniy.kiveisha@intel.com>
Kiveisha Yevgeniy 10 jaren geleden
bovenliggende
commit
bb38b35b32
5 gewijzigde bestanden met toevoegingen van 435 en 0 verwijderingen
  1. 5
    0
      src/sm130/CMakeLists.txt
  2. 8
    0
      src/sm130/jsupm_sm130.i
  3. 9
    0
      src/sm130/pyupm_sm130.i
  4. 265
    0
      src/sm130/sm130.cxx
  5. 148
    0
      src/sm130/sm130.h

+ 5
- 0
src/sm130/CMakeLists.txt Bestand weergeven

@@ -0,0 +1,5 @@
1
+set (libname "sm130")
2
+set (libdescription "upm rfid reader")
3
+set (module_src ${libname}.cxx)
4
+set (module_h ${libname}.h)
5
+upm_module_init()

+ 8
- 0
src/sm130/jsupm_sm130.i Bestand weergeven

@@ -0,0 +1,8 @@
1
+%module jsupm_sm130
2
+%include "../upm.i"
3
+
4
+%{
5
+    #include "sm130.h"
6
+%}
7
+
8
+%include "sm130.h"

+ 9
- 0
src/sm130/pyupm_sm130.i Bestand weergeven

@@ -0,0 +1,9 @@
1
+%module pyupm_sm130
2
+%include "../upm.i"
3
+
4
+%feature("autodoc", "3");
5
+
6
+%include "sm130.h"
7
+%{
8
+    #include "sm130.h"
9
+%}

+ 265
- 0
src/sm130/sm130.cxx Bestand weergeven

@@ -0,0 +1,265 @@
1
+/*
2
+ * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
3
+ * Copyright (c) 2014 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 <iostream>
26
+#include <unistd.h>
27
+#include <stdlib.h>
28
+#include <string.h>
29
+
30
+#include "sm130.h"
31
+
32
+using namespace upm;
33
+
34
+struct SM130Exception : public std::exception {
35
+    std::string message;
36
+    SM130Exception (std::string msg) : message (msg) { }
37
+    ~SM130Exception () throw () { }
38
+    const char* what() const throw () { return message.c_str(); }
39
+};
40
+
41
+SM130::SM130 (int bus, int devAddr, int rst, int dready) {
42
+    mraa_result_t error = MRAA_SUCCESS;
43
+
44
+    this->m_name = "SM130";
45
+
46
+    this->m_i2cAddr = devAddr;
47
+    this->m_bus = bus;
48
+
49
+    this->m_i2Ctx = mraa_i2c_init(this->m_bus);
50
+
51
+    mraa_result_t ret = mraa_i2c_address(this->m_i2Ctx, this->m_i2cAddr);
52
+    if (ret != MRAA_SUCCESS) {
53
+        throw SM130Exception ("Couldn't initilize I2C.");
54
+    }
55
+
56
+    this->m_resetPinCtx = mraa_gpio_init (rst);
57
+    if (m_resetPinCtx == NULL) {
58
+        throw SM130Exception ("Couldn't initilize RESET pin.");
59
+    }
60
+
61
+    this->m_dataReadyPinCtx = mraa_gpio_init (dready);
62
+    if (m_dataReadyPinCtx == NULL) {
63
+        throw SM130Exception ("Couldn't initilize DATA READY pin.");
64
+    }
65
+
66
+    error = mraa_gpio_dir (this->m_resetPinCtx, MRAA_GPIO_OUT);
67
+    if (error != MRAA_SUCCESS) {
68
+        throw SM130Exception ("Couldn't set direction for RESET pin.");
69
+    }
70
+
71
+    error = mraa_gpio_dir (this->m_dataReadyPinCtx, MRAA_GPIO_OUT);
72
+    if (error != MRAA_SUCCESS) {
73
+        throw SM130Exception ("Couldn't set direction for DATA READY pin.");
74
+    }
75
+}
76
+
77
+SM130::~SM130 () {
78
+    mraa_result_t error = MRAA_SUCCESS;
79
+
80
+    error = mraa_i2c_stop(this->m_i2Ctx);
81
+    if (error != MRAA_SUCCESS) {
82
+        mraa_result_print(error);
83
+    }
84
+    error = mraa_gpio_close (this->m_resetPinCtx);
85
+    if (error != MRAA_SUCCESS) {
86
+        mraa_result_print(error);
87
+    }
88
+    error = mraa_gpio_close (this->m_dataReadyPinCtx);
89
+    if (error != MRAA_SUCCESS) {
90
+        mraa_result_print(error);
91
+    }
92
+}
93
+
94
+const char*
95
+SM130::getFirmwareVersion () {
96
+    // Send VERSION command and retry a few times if no response
97
+    for (uint8_t n = 0; n < 10; n++) {
98
+        sendCommand (CMD_VERSION);
99
+        if (available() && getCommand() == CMD_VERSION)
100
+        //  return versionString;
101
+        usleep(100 * 1000);
102
+    }
103
+
104
+    return 0;
105
+}
106
+
107
+uint8_t
108
+SM130::available () {
109
+    // If in SEEK mode and using DREADY pin, check the status
110
+    if (this->m_LastCMD == CMD_SEEK_TAG) {
111
+        if (!mraa_gpio_read(this->m_dataReadyPinCtx)) {
112
+            return false;
113
+        }
114
+    }
115
+
116
+    // Set the maximum length of the expected response packet
117
+    uint8_t len;
118
+    switch(this->m_LastCMD) {
119
+        case CMD_ANTENNA_POWER:
120
+        case CMD_AUTHENTICATE:
121
+        case CMD_DEC_VALUE:
122
+        case CMD_INC_VALUE:
123
+        case CMD_WRITE_KEY:
124
+        case CMD_HALT_TAG:
125
+        case CMD_SLEEP:
126
+            len = 4;
127
+            break;
128
+        case CMD_WRITE4:
129
+        case CMD_WRITE_VALUE:
130
+        case CMD_READ_VALUE:
131
+            len = 8;
132
+        case CMD_SEEK_TAG:
133
+        case CMD_SELECT_TAG:
134
+            len = 11;
135
+            break;
136
+        default:
137
+            len = SIZE_PACKET;
138
+    }
139
+
140
+    // If valid data received, process the response packet
141
+    if (this->i2cRecievePacket(len) > 0) {
142
+        // Init response variables
143
+        this->m_TagType = this->m_TagLength = *this->m_TagString = 0;
144
+
145
+        // If packet length is 2, the command failed. Set error code.
146
+        errorCode = this->getPacketLength () < 3 ? this->m_Data[2] : 0;
147
+
148
+        // Process command response
149
+        switch (this->getCommand ()) {
150
+            case CMD_RESET:
151
+            case CMD_VERSION:
152
+                // RESET and VERSION commands produce the firmware version
153
+                len = std::min ((unsigned int) getPacketLength (), sizeof (this->m_Version)) - 1;
154
+                memcpy(this->m_Version, this->m_Data + 2, len);
155
+                this->m_Version[len] = 0;
156
+                break;
157
+
158
+            case CMD_SEEK_TAG:
159
+            case CMD_SELECT_TAG:
160
+                // If no error, get tag number
161
+                if(errorCode == 0 && this->getPacketLength () >= 6)
162
+                {
163
+                    this->m_TagLength = this->getPacketLength () - 2;
164
+                    this->m_TagType = this->m_Data[2];
165
+                    memcpy(this->m_TagNumber, this->m_Data + 3, this->m_TagLength);
166
+                    this->arrayToHex (this->m_TagString, this->m_TagNumber, this->m_TagLength);
167
+                }
168
+                break;
169
+
170
+            case CMD_AUTHENTICATE:
171
+                break;
172
+
173
+            case CMD_READ16:
174
+                break;
175
+
176
+            case CMD_WRITE16:
177
+            case CMD_WRITE4:
178
+                break;
179
+
180
+            case CMD_ANTENNA_POWER:
181
+                errorCode = 0;
182
+                antennaPower = this->m_Data[2];
183
+                break;
184
+
185
+            case CMD_SLEEP:
186
+                // If in SLEEP mode, no data is available
187
+                return false;
188
+        }
189
+
190
+        // Data available
191
+        return true;
192
+    }
193
+    // No data available
194
+    return false;
195
+}
196
+
197
+uint16_t
198
+SM130::i2cRecievePacket (uint32_t len) {
199
+    int readByte = 0;
200
+
201
+    mraa_i2c_address(this->m_i2Ctx, this->m_i2cAddr);
202
+    readByte = mraa_i2c_read(this->m_i2Ctx, this->m_Data, len);
203
+
204
+    if (readByte > 0) {
205
+        // verify checksum if length > 0 and <= SIZE_PAYLOAD
206
+        if (this->m_Data[0] > 0 && this->m_Data[0] <= SIZE_PAYLOAD)
207
+        {
208
+            uint8_t i, sum;
209
+            for (i = 0, sum = 0; i <= this->m_Data[0]; i++) {
210
+                sum += this->m_Data[i];
211
+            }
212
+            // return with length of response, or -1 if invalid checksum
213
+            return sum == this->m_Data[i] ? this->m_Data[0] : -1;
214
+        }
215
+    }
216
+
217
+    return readByte;
218
+}
219
+
220
+void
221
+SM130::arrayToHex (char *s, uint8_t array[], uint8_t len) {
222
+    for (uint8_t i = 0; i < len; i++) {
223
+        *s++ = toHex(array[i] >> 4);
224
+        *s++ = toHex(array[i]);
225
+    }
226
+
227
+    *s = 0;
228
+}
229
+
230
+char
231
+SM130::toHex (uint8_t b) {
232
+    b = b & 0x0f;
233
+
234
+    return b < 10 ? b + '0' : b + 'A' - 10;
235
+}
236
+
237
+mraa_result_t
238
+SM130::i2cTransmitPacket (uint32_t len) {
239
+    mraa_result_t error = MRAA_SUCCESS;
240
+    uint8_t sum = 0;
241
+
242
+    // Save last command
243
+    this->m_LastCMD = this->m_Data[0];
244
+
245
+    // calculate the sum check
246
+    for (int i = 0; i < len; i++) {
247
+        sum += this->m_Data[i];
248
+    }
249
+
250
+    // placing the sum check to the last byte of the packet
251
+    this->m_Data[len + 1] = sum;
252
+
253
+    error = mraa_i2c_address (this->m_i2Ctx, this->m_i2cAddr);
254
+    error = mraa_i2c_write (this->m_i2Ctx, this->m_Data, len + 1);
255
+
256
+    return error;
257
+}
258
+
259
+mraa_result_t
260
+SM130::sendCommand (uint8_t cmd) {
261
+    this->m_Data[0] = 1;
262
+    this->m_Data[1] = cmd;
263
+    this->i2cTransmitPacket(2);
264
+}
265
+

+ 148
- 0
src/sm130/sm130.h Bestand weergeven

@@ -0,0 +1,148 @@
1
+/*
2
+ * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ * 
5
+ * Based on SM130 library developed by Marc Boon <http://www.marcboon.com>
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining
8
+ * a copy of this software and associated documentation files (the
9
+ * "Software"), to deal in the Software without restriction, including
10
+ * without limitation the rights to use, copy, modify, merge, publish,
11
+ * distribute, sublicense, and/or sell copies of the Software, and to
12
+ * permit persons to whom the Software is furnished to do so, subject to
13
+ * the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ */
26
+#pragma once
27
+
28
+#include <string>
29
+#include <mraa/aio.h>
30
+#include <mraa/gpio.h>
31
+#include <mraa/i2c.h>
32
+#include <unistd.h>
33
+#include <stdlib.h>
34
+
35
+#define SIZE_PAYLOAD 18                 // maximum payload size of I2C packet
36
+#define SIZE_PACKET (SIZE_PAYLOAD + 2)  // total I2C packet size, including length uint8_t and checksum
37
+
38
+#define HIGH                  1
39
+#define LOW                   0
40
+
41
+namespace upm {
42
+
43
+/**
44
+ * @brief C++ API for SM130 RFID reader module
45
+ *
46
+ * This file defines the SM130 C++ interface for libsm130
47
+ *
48
+ */
49
+class SM130 {
50
+    
51
+    uint8_t m_Data[SIZE_PACKET]; //!< packet data
52
+	char    m_Version[8];      //!< version string
53
+	uint8_t m_TagNumber[7];    //!< tag number as uint8_t array
54
+	uint8_t m_TagLength;       //!< length of tag number in uint8_ts (4 or 7)
55
+	char    m_TagString[15];   //!< tag number as hex string
56
+	uint8_t m_TagType;         //!< type of tag
57
+	char    errorCode;         //!< error code from some commands
58
+	uint8_t antennaPower;      //!< antenna power level
59
+	uint8_t m_LastCMD;         //!< last sent command
60
+    
61
+    public:
62
+        static const uint8_t MIFARE_ULTRALIGHT = 1;
63
+        static const uint8_t MIFARE_1K         = 2;
64
+        static const uint8_t MIFARE_4K         = 3;
65
+
66
+        static const uint8_t CMD_RESET         = 0x80;
67
+        static const uint8_t CMD_VERSION       = 0x81;
68
+        static const uint8_t CMD_SEEK_TAG      = 0x82;
69
+        static const uint8_t CMD_SELECT_TAG    = 0x83;
70
+        static const uint8_t CMD_AUTHENTICATE  = 0x85;
71
+        static const uint8_t CMD_READ16        = 0x86;
72
+        static const uint8_t CMD_READ_VALUE    = 0x87;
73
+        static const uint8_t CMD_WRITE16       = 0x89;
74
+        static const uint8_t CMD_WRITE_VALUE   = 0x8a;
75
+        static const uint8_t CMD_WRITE4        = 0x8b;
76
+        static const uint8_t CMD_WRITE_KEY     = 0x8c;
77
+        static const uint8_t CMD_INC_VALUE     = 0x8d;
78
+        static const uint8_t CMD_DEC_VALUE     = 0x8e;
79
+        static const uint8_t CMD_ANTENNA_POWER = 0x90;
80
+        static const uint8_t CMD_READ_PORT     = 0x91;
81
+        static const uint8_t CMD_WRITE_PORT    = 0x92;
82
+        static const uint8_t CMD_HALT_TAG      = 0x93;
83
+        static const uint8_t CMD_SET_BAUD      = 0x94;
84
+        static const uint8_t CMD_SLEEP         = 0x96;
85
+    
86
+         /**
87
+         * Instanciates a SM130 object
88
+         *
89
+         * @param di data pin
90
+         * @param dcki clock pin
91
+         */
92
+        SM130 (int bus, int devAddr, int rst, int dready);
93
+
94
+        /**
95
+         * SM130 object destructor
96
+         */
97
+        ~SM130 ();
98
+        
99
+        /**
100
+         * Get the firmware version string.
101
+         */
102
+        const char* getFirmwareVersion ();
103
+        
104
+        /**
105
+         * 	Checks for availability of a valid response packet.
106
+         *
107
+         *	This function should always be called and return true prior to using results
108
+         *	of a command.
109
+         *
110
+         *	@returns	true if a valid response packet is available
111
+         */
112
+        uint8_t available ();
113
+        
114
+        /**
115
+         * Returns the packet length, excluding checksum
116
+         */
117
+        uint8_t getPacketLength () { return this->m_Data[0]; };
118
+        
119
+        /**
120
+         * Returns the last executed command
121
+         */
122
+        uint8_t getCommand () { return this->m_Data[1]; };
123
+
124
+        /**
125
+         * Return name of the component
126
+         */
127
+        std::string name()
128
+        {
129
+            return m_name;
130
+        }
131
+    private:
132
+        std::string m_name;
133
+        mraa_gpio_context m_resetPinCtx;
134
+        mraa_gpio_context m_dataReadyPinCtx;
135
+        
136
+        int m_i2cAddr;
137
+        int m_bus;
138
+        mraa_i2c_context m_i2Ctx;
139
+        
140
+        void arrayToHex (char *s, uint8_t array[], uint8_t len);
141
+        char toHex (uint8_t b);
142
+        
143
+        uint16_t i2cRecievePacket (uint32_t len);
144
+        mraa_result_t i2cTransmitPacket (uint32_t len);
145
+        mraa_result_t sendCommand (uint8_t cmd);
146
+};
147
+
148
+}