summaryrefslogtreecommitdiff
path: root/peripheral/libupm/src/zfm20/zfm20.hpp
blob: 91ae18b408d0bc75198a4b7874243393f8cb8c8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
/*
 * Author: Jon Trulson <jtrulson@ics.com>
 * Copyright (c) 2015 Intel Corporation.
 *
 * Thanks to Adafruit for supplying a google translated version of the
 * Chinese datasheet and some clues in their code.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#pragma once

#include <string>
#include <iostream>

#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/time.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <mraa/uart.h>

#define ZFM20_DEFAULT_UART 0

// protocol start codes
#define ZFM20_START1 0xef
#define ZFM20_START2 0x01

#define ZFM20_MAX_PKT_LEN 256

#define ZFM20_TIMEOUT 5000 // in ms

#define ZFM20_DEFAULT_PASSWORD 0x00000000
#define ZFM20_DEFAULT_ADDRESS  0xffffffff


namespace upm {
    /**
     * @brief ZFM-20 Fingerprint Sensor Module library
     * @defgroup zfm20 libupm-zfm20
     * @ingroup seeed uart touch
     */

    /**
     * @library zfm20
     * @sensor zfm20
     * @comname ZFM-20 Fingerprint Sensor
     * @altname Grove Fingerprint Sensor
     * @type touch
     * @man seeed
     * @con uart
     *
     * @brief API for the ZFM-20 Fingerprint Sensor Module
     *
     * This class was tested on the Grove Fingerprint Sensor
     * Module. It can store up to 163 fingerprints.
     *
     * It is connected via a UART at 57,600 baud.
     *
     * @image html zfm20.jpg
     * This example demonstrates how to register and store a new fingerprint
     * @snippet zfm20-register.cxx Interesting
     * This example demonstrates reading a fingerprint and locating it in the DB
     * @snippet zfm20.cxx Interesting
     */
  class ZFM20 {
  public:

    // commands
    typedef enum {
      CMD_GEN_IMAGE                     = 0x01,
      CMD_IMG2TZ                        = 0x02,
      CMD_MATCH                         = 0x03,
      CMD_SEARCH                        = 0x04,
      CMD_REGMODEL                      = 0x05,
      CMD_STORE                         = 0x06,
      CMD_LOAD_TMPL                     = 0x07,
      CMD_UPLOAD_TMPL                   = 0x08,
      CMD_DOWNLOAD_TMPL                 = 0x09,
      CMD_UPLOAD_IMAGE                  = 0x0a,
      CMD_DOWNLOAD_IMAGE                = 0x0b,
      CMD_DELETE_TMPL                   = 0x0c,
      CMD_EMPTYDB                       = 0x0d,
      CMD_SET_SYSPARAMS                 = 0x0e,
      CMD_GET_SYSPARAMS                 = 0x0f,
      CMD_SET_PASSWORD                  = 0x12,
      CMD_VERIFY_PASSWORD               = 0x13,
      CMD_GET_RANDOM_NUMBER             = 0x14,
      CMD_SET_ADDRESS                   = 0x15,
      CMD_GET_TMPL_COUNT                = 0x1d,
      CMD_GET_INDEX_TABLE               = 0x1f
    } ZFM20_COMMAND_T;

    // Error response codes
    typedef enum {
      ERR_OK                            = 0x00,
      ERR_PACKET_RX_ERROR               = 0x01,
      ERR_NO_FINGER                     = 0x02,
      ERR_FP_IMAGE_FAILED               = 0x03,
      ERR_FP_TOO_MESSY                  = 0x06,
      ERR_FP_IMAGE_FEW_FEATURES         = 0x07,
      ERR_FP_NOMATCH                    = 0x08,
      ERR_FP_NOTFOUND                   = 0x09,
      ERR_FP_ENROLLMISMATCH             = 0x0a,
      ERR_BAD_LOCATION                  = 0x0b,
      ERR_DB_ERROR                      = 0x0c,
      ERR_UPLOAD_FEAT_FAILED            = 0x0d,
      ERR_NO_MORE_PACKETS               = 0x0e,
      ERR_UPLOAD_IMG_FAILED             = 0x0f,
      ERR_RM_TMPL_FAILED                = 0x10,
      ERR_EMPTY_DB_FAILED               = 0x11,
      ERR_INVALID_PWD                   = 0x13,
      ERR_INVALID_IMAGE                 = 0x15,
      ERR_RW_FLASH_ERROR                = 0x18,
      ERR_INVALID_REG                   = 0x1a,
      ERR_INVALID_ADDR                  = 0x20,
      ERR_NEEDS_PWD                     = 0x21,
      // end of module-specific errors
      ERR_INTERNAL_ERR                  = 0xff  // API internal error
    } ZFM20_ERRORS_T;

    typedef enum {
      PKT_COMMAND                       = 0x01,
      PKT_DATA                          = 0x02,
      PKT_ACK                           = 0x07,
      PKT_END_DATA                      = 0x08
    } ZFM20_PKTCODES_T;

    /**
     * ZFM20 constructor
     *
     * @param uart Default UART to use (0 or 1)
     */
    ZFM20(int uart);

    /**
     * ZFM20 destructor
     */
    ~ZFM20();

    /**
     * Checks to see if there is data available for reading
     *
     * @param millis Number of milliseconds to wait; 0 means no waiting
     * @return true if there is data available for reading
     */
    bool dataAvailable(unsigned int millis);

    /**
     * Reads any available data in a user-supplied buffer. Note: the
     * call blocks until data is available to be read. Use
     * dataAvailable() to determine whether there is data available
     * beforehand, to avoid blocking.
     *
     * @param buffer Buffer to hold the data read
     * @param len Length of the buffer
     * @return Number of bytes read
     */
    int readData(char *buffer, int len);

    /**
     * Writes the data in the buffer to the device
     *
     * @param buffer Buffer to hold the data read
     * @param len Length of the buffer
     * @return Number of bytes written
     */
    int writeData(char *buffer, int len);

    /**
     * Sets up proper tty I/O modes and the baud rate. For this device,
     * the default baud rate is 57,600 (B57600).
     *
     * @param baud Desired baud rate.
     * @return True if successful
     */
    bool setupTty(speed_t baud=B57600);

    /**
     * Composes and writes a command packet
     *
     * @param pkt Packet
     * @param len Length of packet
     * @return Number of bytes written
     */
    int writeCmdPacket(uint8_t *pkt, int len);

    /**
     * Verifies the packet header and indicates its validity
     *
     * @param pkt Packet to check
     * @param len Length of packet
     * @return True if the packet is valid, false otherwise
     */
    bool verifyPacket(uint8_t *pkt, int len);

    /**
     * Returns the number of milliseconds elapsed since initClock()
     * was last called
     *
     * @return Elapsed milliseconds
     */
    uint32_t getMillis();

    /**
     * Resets the clock
     *
     */
    void initClock();

    /**
     * Sets the address that should be used to access the module
     *
     * @param addr Address to use
     */
    void setAddress(uint32_t addr) { m_address = addr; };

    /**
     * Sets the password that should be used to access the module
     *
     * @param pw Password to use
     */
    void setPassword(uint32_t pw) { m_password = pw; };

    /**
     * Gets the returned data from a request
     *
     * @param pkt Buffer to store the returned data
     * @param len Expected response length; pkt should be at least this
     * large
     * @return True if successful
     */
    bool getResponse(uint8_t *pkt, int len);

    /**
     * Verifies and authenticates to the module. The password used is
     * the last one set by setPassword().
     *
     * @return True if successful
     */
    bool verifyPassword();

    /**
     * Queries the module for the number of stored templates
     * (fingerprints).
     *
     * @return Number of currently stored templates
     */
    int getNumTemplates();

    /**
     * Sets a new password for the module. This passowrd is
     * stored in the module, and is required to access
     * the module in the future.
     *
     * @param pwd New password to set on the module
     * @return True if successful
     */
    bool setNewPassword(uint32_t pwd);

    /**
     * Sets a new address for the module. This address is
     * stored in the module, and is required to access
     * the module in the future.
     *
     * @param addr New address to set on the module
     * @return True if successful
     */
    bool setNewAddress(uint32_t addr);

    /**
     * Generates a new fingerprint image (scans a fingerprint)
     *
     * @return One of the ZFM20_ERRORS_T values
     */
    uint8_t generateImage();

    /**
     * Converts the image in the image buffer (generated by
     * generateImage()) and stores it in one of the two characteristics
     * buffers, 1 or 2
     *
     * @param slot Characteristics buffer to use; must be 1 or 2
     * @return One of the ZFM20_ERRORS_T values
     */
    uint8_t image2Tz(int slot);

    /**
     * Based on the two characteristics buffers (1 & 2), creates a
     * fingerprint model. Once a model is successfully created,
     * it can be stored in the module with storeModel().
     *
     * @return One of the ZFM20_ERRORS_T values
     */
    uint8_t createModel();

    /**
     * Once a fingerprint model is created, this method can be
     * used to store it (via one of the characteristics buffers) in a
     * given location.
     *
     * @param slot Characteristics buffer to store the model, 1 or 2
     * @param id Location to store the model
     * @return One of the ZFM20_ERRORS_T values
     */
    uint8_t storeModel(int slot, uint16_t id);

    /**
     * Deletes a stored model
     *
     * @param id Location containing the model to delete
     * @return One of the ZFM20_ERRORS_T values
     */
    uint8_t deleteModel(uint16_t id);

    /**
     * Deletes the model database (DB)
     *
     * @return One of the ZFM20_ERRORS_T values
     */
    uint8_t deleteDB();

    /**
     * Searches the fingerprint DB and returns an ID and score, if found
     *
     *
     * @param slot Slot containing a converted image to search for
     * @param id ID if found, 0 otherwise
     * @param score Score if found, 0 otherwise
     * @return One of the ZFM20_ERRORS_T values
     */
    uint8_t search(int slot, uint16_t *id, uint16_t *score);

    /**
     * Compares the features in characteristics buffers 1 and 2 and
     * returns a score if they match
     *
     * @param score Score
     * @return One of the ZFM20_ERRORS_T values
     */
    uint8_t match(uint16_t *score);


  protected:
    int ttyFd() { return m_ttyFd; };

  private:
    mraa_uart_context m_uart;
    int m_ttyFd;
    uint32_t m_password;
    uint32_t m_address;
    struct timeval m_startTime;
  };
}