Fingerprint and demo library for ARM-STM32 made from the Arduino library for R503

Dependents:   R503_fingerprint_HelloWorldV4

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Fingerprint.cpp Source File

Fingerprint.cpp

Go to the documentation of this file.
00001 /*!
00002  * @file Fingerprint.cpp
00003  * @mainpage Adafruit Fingerprint Sensor Library
00004  * @section intro_sec Introduction
00005  * This is a library for our optical Fingerprint sensor
00006  * Designed specifically to work with the Adafruit Fingerprint sensor
00007  * ---. http://www.adafruit.com/products/751
00008  * These displays use TTL Serial to communicate, 2 pins are required to
00009  * interface
00010  * Adafruit invests time and resources providing this open source code,
00011  * please support Adafruit and open-source hardware by purchasing
00012  * products from Adafruit!
00013  * @section author Author
00014  * Written by Limor Fried/Ladyada for Adafruit Industries.
00015  * @section license License
00016  * BSD license, all text above must be included in any redistribution
00017  *
00018  * STM32 adaptation by Christian Dupaty 03/2021
00019  *
00020  */
00021 
00022 #include "Fingerprint.h "  
00023 #include "mbed.h"
00024 
00025 
00026 /*!
00027  * @brief Gets the command packet
00028  */
00029 #define GET_CMD_PACKET(...)                                                    \
00030 uint8_t data[] = {__VA_ARGS__};                                                \
00031  Fingerprint_Packet packet(FINGERPRINT_COMMANDPACKET, sizeof(data),data);      \
00032   writeStructuredPacket(packet);                                               \
00033   if (getStructuredPacket(&packet) != FINGERPRINT_OK)                          \
00034     return FINGERPRINT_PACKETRECIEVEERR;                                       \
00035   if (packet.type != FINGERPRINT_ACKPACKET)                                   \
00036     return FINGERPRINT_PACKETRECIEVEERR;
00037 
00038 /*!
00039  * @brief Sends the command packet
00040  */
00041 #define SEND_CMD_PACKET(...)                                                   \
00042   GET_CMD_PACKET(__VA_ARGS__);                                                 \
00043   return packet.data[0];
00044 
00045 /***************************************************************************
00046  PUBLIC FUNCTIONS
00047  ***************************************************************************/
00048 
00049 
00050 /**************************************************************************/
00051 /*!
00052     @brief  Instantiates sensor with Software Serial
00053     @param  ss Pointer to SoftwareSerial object
00054     @param  password 32-bit integer password (default is 0)
00055 */
00056 /**************************************************************************/
00057 Fingerprint::Fingerprint(PinName serialTX, PinName serialRX, uint32_t password) :   R503Serial(serialTX, serialRX) 
00058 {
00059   thePassword = password;
00060   theAddress = 0xFFFFFFFF;
00061 
00062   status_reg = 0x0; ///< The status register (set by getParameters)
00063   system_id = 0x0;  ///< The system identifier (set by getParameters)
00064   capacity = 64; ///< The fingerprint capacity (set by getParameters)
00065   security_level = 0; ///< The security level (set by getParameters)
00066   device_addr = 0xFFFFFFFF;      ///< The device address (set by getParameters)
00067   packet_len = 64;   ///< The max packet length (set by getParameters)
00068   baud_rate = 57600; ///< The UART baud rate (set by getParameters)
00069   // Init buffer de reception, les deux pointeurs egaux
00070   pe=buffUART;
00071   pl=buffUART;
00072   // active IT sur reception UART vers methode receiveUART
00073   R503Serial.attach(callback(this,&Fingerprint::receiveUART),RawSerial::RxIrq);
00074 }
00075 
00076 /**************************************************************************/
00077 /*!
00078     @brief  Initializes serial interface and baud rate
00079     @param  baudrate Sensor's UART baud rate (usually 57600, 9600 or 115200)
00080 */
00081 /**************************************************************************/
00082 void Fingerprint::begin(uint32_t baudrate) {
00083      R503Serial.baud(baudrate);
00084 }
00085 
00086 /**************************************************************************/
00087 /*!
00088     @brief  Verifies the sensors' access password (default password is
00089    0x0000000). A good way to also check if the sensors is active and responding
00090     @returns True if password is correct
00091 */
00092 /**************************************************************************/
00093 bool Fingerprint::verifyPassword(void) {
00094   return checkPassword() == FINGERPRINT_OK;
00095 }
00096 
00097 uint8_t Fingerprint::checkPassword(void) {
00098   GET_CMD_PACKET(FINGERPRINT_VERIFYPASSWORD, (uint8_t)(thePassword >> 24),(uint8_t)(thePassword >> 16), (uint8_t)(thePassword >> 8),(uint8_t)(thePassword & 0xFF));
00099   if (packet.data[0] == FINGERPRINT_OK)
00100     return FINGERPRINT_OK;
00101   else
00102     return FINGERPRINT_PACKETRECIEVEERR;
00103 }
00104 
00105 /**************************************************************************/
00106 /*!
00107     @brief  Get the sensors parameters, fills in the member variables
00108     status_reg, system_id, capacity, security_level, device_addr, packet_len
00109     and baud_rate
00110     @returns True if password is correct
00111 */
00112 /**************************************************************************/
00113 uint8_t Fingerprint::getParameters(void) {
00114   GET_CMD_PACKET(FINGERPRINT_READSYSPARAM);
00115 
00116   status_reg = ((uint16_t)packet.data[1] << 8) | packet.data[2];
00117   system_id = ((uint16_t)packet.data[3] << 8) | packet.data[4];
00118   capacity = ((uint16_t)packet.data[5] << 8) | packet.data[6];
00119   security_level = ((uint16_t)packet.data[7] << 8) | packet.data[8];
00120   device_addr = ((uint32_t)packet.data[9] << 24) |
00121                 ((uint32_t)packet.data[10] << 16) |
00122                 ((uint32_t)packet.data[11] << 8) | (uint32_t)packet.data[12];
00123   packet_len = ((uint16_t)packet.data[13] << 8) | packet.data[14];
00124   if (packet_len == 0) {
00125     packet_len = 32;
00126   } else if (packet_len == 1) {
00127     packet_len = 64;
00128   } else if (packet_len == 2) {
00129     packet_len = 128;
00130   } else if (packet_len == 3) {
00131     packet_len = 256;
00132   }
00133   baud_rate = (((uint16_t)packet.data[15] << 8) | packet.data[16]) * 9600;
00134 
00135   return packet.data[0];
00136 }
00137 
00138 /**************************************************************************/
00139 /*!
00140     @brief   Ask the sensor to take an image of the finger pressed on surface
00141     @returns <code>FINGERPRINT_OK</code> on success
00142     @returns <code>FINGERPRINT_NOFINGER</code> if no finger detected
00143     @returns <code>FINGERPRINT_PACKETRECIEVEERR</code> on communication error
00144     @returns <code>FINGERPRINT_IMAGEFAIL</code> on imaging error
00145 */
00146 /**************************************************************************/
00147 uint8_t Fingerprint::getImage(void) {
00148   SEND_CMD_PACKET(FINGERPRINT_GETIMAGE);
00149 }
00150 
00151 /**************************************************************************/
00152 /*!
00153     @brief   Ask the sensor to convert image to feature template
00154     @param slot Location to place feature template (put one in 1 and another in
00155    2 for verification to create model)
00156     @returns <code>FINGERPRINT_OK</code> on success
00157     @returns <code>FINGERPRINT_IMAGEMESS</code> if image is too messy
00158     @returns <code>FINGERPRINT_PACKETRECIEVEERR</code> on communication error
00159     @returns <code>FINGERPRINT_FEATUREFAIL</code> on failure to identify
00160    fingerprint features
00161     @returns <code>FINGERPRINT_INVALIDIMAGE</code> on failure to identify
00162    fingerprint features
00163 */
00164 uint8_t Fingerprint::image2Tz(uint8_t slot) {
00165   SEND_CMD_PACKET(FINGERPRINT_IMAGE2TZ, slot);
00166 }
00167 
00168 /**************************************************************************/
00169 /*!
00170     @brief   Ask the sensor to take two print feature template and create a
00171    model
00172     @returns <code>FINGERPRINT_OK</code> on success
00173     @returns <code>FINGERPRINT_PACKETRECIEVEERR</code> on communication error
00174     @returns <code>FINGERPRINT_ENROLLMISMATCH</code> on mismatch of fingerprints
00175 */
00176 uint8_t Fingerprint::createModel(void) {
00177   SEND_CMD_PACKET(FINGERPRINT_REGMODEL);
00178 }
00179 
00180 /**************************************************************************/
00181 /*!
00182     @brief   Ask the sensor to store the calculated model for later matching
00183     @param   location The model location #
00184     @returns <code>FINGERPRINT_OK</code> on success
00185     @returns <code>FINGERPRINT_BADLOCATION</code> if the location is invalid
00186     @returns <code>FINGERPRINT_FLASHERR</code> if the model couldn't be written
00187    to flash memory
00188     @returns <code>FINGERPRINT_PACKETRECIEVEERR</code> on communication error
00189 */
00190 uint8_t Fingerprint::storeModel(uint16_t location) {
00191   SEND_CMD_PACKET(FINGERPRINT_STORE, 0x01, (uint8_t)(location >> 8),
00192                   (uint8_t)(location & 0xFF));
00193 }
00194 
00195 /**************************************************************************/
00196 /*!
00197     @brief   Ask the sensor to load a fingerprint model from flash into buffer 1
00198     @param   location The model location #
00199     @returns <code>FINGERPRINT_OK</code> on success
00200     @returns <code>FINGERPRINT_BADLOCATION</code> if the location is invalid
00201     @returns <code>FINGERPRINT_PACKETRECIEVEERR</code> on communication error
00202 */
00203 uint8_t Fingerprint::loadModel(uint16_t location) {
00204   SEND_CMD_PACKET(FINGERPRINT_LOAD, 0x01, (uint8_t)(location >> 8),
00205                   (uint8_t)(location & 0xFF));
00206 }
00207 
00208 /**************************************************************************/
00209 /*!
00210     @brief   Ask the sensor to transfer 256-byte fingerprint template from the
00211    buffer to the UART
00212     @returns <code>FINGERPRINT_OK</code> on success
00213     @returns <code>FINGERPRINT_PACKETRECIEVEERR</code> on communication error
00214 */
00215 uint8_t Fingerprint::getModel(void) {
00216   SEND_CMD_PACKET(FINGERPRINT_UPLOAD, 0x01);
00217 }
00218 
00219 /**************************************************************************/
00220 /*!
00221     @brief   Ask the sensor to delete a model in memory
00222     @param   location The model location #
00223     @returns <code>FINGERPRINT_OK</code> on success
00224     @returns <code>FINGERPRINT_BADLOCATION</code> if the location is invalid
00225     @returns <code>FINGERPRINT_FLASHERR</code> if the model couldn't be written
00226    to flash memory
00227     @returns <code>FINGERPRINT_PACKETRECIEVEERR</code> on communication error
00228 */
00229 uint8_t Fingerprint::deleteModel(uint16_t location) {
00230   SEND_CMD_PACKET(FINGERPRINT_DELETE, (uint8_t)(location >> 8),
00231                   (uint8_t)(location & 0xFF), 0x00, 0x01);
00232 }
00233 
00234 /**************************************************************************/
00235 /*!
00236     @brief   Ask the sensor to delete ALL models in memory
00237     @returns <code>FINGERPRINT_OK</code> on success
00238     @returns <code>FINGERPRINT_BADLOCATION</code> if the location is invalid
00239     @returns <code>FINGERPRINT_FLASHERR</code> if the model couldn't be written
00240    to flash memory
00241     @returns <code>FINGERPRINT_PACKETRECIEVEERR</code> on communication error
00242 */
00243 uint8_t Fingerprint::emptyDatabase(void) {
00244   SEND_CMD_PACKET(FINGERPRINT_EMPTY);
00245 }
00246 
00247 /**************************************************************************/
00248 /*!
00249     @brief   Ask the sensor to search the current slot 1 fingerprint features to
00250    match saved templates. The matching location is stored in <b>fingerID</b> and
00251    the matching confidence in <b>confidence</b>
00252     @returns <code>FINGERPRINT_OK</code> on fingerprint match success
00253     @returns <code>FINGERPRINT_NOTFOUND</code> no match made
00254     @returns <code>FINGERPRINT_PACKETRECIEVEERR</code> on communication error
00255 */
00256 /**************************************************************************/
00257 uint8_t Fingerprint::fingerFastSearch(void) {
00258   // high speed search of slot #1 starting at page 0x0000 and page #0x00A3
00259   GET_CMD_PACKET(FINGERPRINT_HISPEEDSEARCH, 0x01, 0x00, 0x00, 0x00, 0xA3);
00260   fingerID = 0xFFFF;
00261   confidence = 0xFFFF;
00262 
00263   fingerID = packet.data[1];
00264   fingerID <<= 8;
00265   fingerID |= packet.data[2];
00266 
00267   confidence = packet.data[3];
00268   confidence <<= 8;
00269   confidence |= packet.data[4];
00270 
00271   return packet.data[0];
00272 }
00273 
00274 /**************************************************************************/
00275 /*!
00276     @brief   Control the built in LED
00277     @param on True if you want LED on, False to turn LED off
00278     @returns <code>FINGERPRINT_OK</code> on success
00279 */
00280 /**************************************************************************/
00281 uint8_t Fingerprint::LEDcontrol(bool on) {
00282   if (on) {
00283     SEND_CMD_PACKET(FINGERPRINT_LEDON);
00284   } else {
00285     SEND_CMD_PACKET(FINGERPRINT_LEDOFF);
00286   }
00287 }
00288 
00289 /**************************************************************************/
00290 /*!
00291     @brief   Control the built in Aura LED (if exists). Check datasheet/manual
00292     for different colors and control codes available
00293     @param control The control code (e.g. breathing, full on)
00294     @param speed How fast to go through the breathing/blinking cycles
00295     @param coloridx What color to light the indicator
00296     @param count How many repeats of blinks/breathing cycles
00297     @returns <code>FINGERPRINT_OK</code> on fingerprint match success
00298     @returns <code>FINGERPRINT_NOTFOUND</code> no match made
00299     @returns <code>FINGERPRINT_PACKETRECIEVEERR</code> on communication error
00300 */
00301 /**************************************************************************/
00302 uint8_t Fingerprint::LEDcontrol(uint8_t control, uint8_t speed,
00303                                          uint8_t coloridx, uint8_t count) {
00304   SEND_CMD_PACKET(FINGERPRINT_AURALEDCONFIG, control, speed, coloridx, count);
00305 }
00306 
00307 /**************************************************************************/
00308 /*!
00309     @brief   Ask the sensor to search the current slot fingerprint features to
00310    match saved templates. The matching location is stored in <b>fingerID</b> and
00311    the matching confidence in <b>confidence</b>
00312    @param slot The slot to use for the print search, defaults to 1
00313     @returns <code>FINGERPRINT_OK</code> on fingerprint match success
00314     @returns <code>FINGERPRINT_NOTFOUND</code> no match made
00315     @returns <code>FINGERPRINT_PACKETRECIEVEERR</code> on communication error
00316 */
00317 /**************************************************************************/
00318 uint8_t Fingerprint::fingerSearch(uint8_t slot) {
00319   // search of slot starting thru the capacity
00320   GET_CMD_PACKET(FINGERPRINT_SEARCH, slot, 0x00, 0x00, capacity >> 8,
00321                  capacity & 0xFF);
00322 
00323   fingerID = 0xFFFF;
00324   confidence = 0xFFFF;
00325 
00326   fingerID = packet.data[1];
00327   fingerID <<= 8;
00328   fingerID |= packet.data[2];
00329 
00330   confidence = packet.data[3];
00331   confidence <<= 8;
00332   confidence |= packet.data[4];
00333 
00334   return packet.data[0];
00335 }
00336 
00337 /**************************************************************************/
00338 /*!
00339     @brief   Ask the sensor for the number of templates stored in memory. The
00340    number is stored in <b>templateCount</b> on success.
00341     @returns <code>FINGERPRINT_OK</code> on success
00342     @returns <code>FINGERPRINT_PACKETRECIEVEERR</code> on communication error
00343 */
00344 /**************************************************************************/
00345 uint8_t Fingerprint::getTemplateCount(void) {
00346   GET_CMD_PACKET(FINGERPRINT_TEMPLATECOUNT);
00347 
00348   templateCount = packet.data[1];
00349   templateCount <<= 8;
00350   templateCount |= packet.data[2];
00351 
00352   return packet.data[0];
00353 }
00354 
00355 /**************************************************************************/
00356 /*!
00357     @brief   Set the password on the sensor (future communication will require
00358    password verification so don't forget it!!!)
00359     @param   password 32-bit password code
00360     @returns <code>FINGERPRINT_OK</code> on success
00361     @returns <code>FINGERPRINT_PACKETRECIEVEERR</code> on communication error
00362 */
00363 /**************************************************************************/
00364 uint8_t Fingerprint::setPassword(uint32_t password) {
00365   SEND_CMD_PACKET(FINGERPRINT_SETPASSWORD, (password >> 24), (password >> 16),
00366                   (password >> 8), password);
00367 }
00368 
00369 /**************************************************************************/
00370 /*!
00371     @brief   Helper function to process a packet and send it over UART to the
00372    sensor
00373     @param   packet A structure containing the bytes to transmit
00374 */
00375 /**************************************************************************/
00376 
00377 void Fingerprint::writeStructuredPacket(const Fingerprint_Packet &packet) 
00378 {
00379   R503Serial.putc((uint8_t)(packet.start_code >> 8));
00380   R503Serial.putc((uint8_t)(packet.start_code & 0xFF));
00381   R503Serial.putc(packet.address[0]);
00382   R503Serial.putc(packet.address[1]);
00383   R503Serial.putc(packet.address[2]);
00384   R503Serial.putc(packet.address[3]);
00385   R503Serial.putc(packet.type);
00386 
00387   uint16_t wire_length = packet.length + 2;
00388   R503Serial.putc((uint8_t)(wire_length >> 8));
00389   R503Serial.putc((uint8_t)(wire_length & 0xFF));
00390 
00391   #ifdef FINGERPRINT_DEBUG
00392   printf("-> Send packet \n-> ");
00393   printf("0x%02X%02X ",(uint8_t)(packet.start_code >> 8),(uint8_t)(packet.start_code & 0xFF));
00394   printf(", 0x%02X ",packet.address[0]);
00395   printf(", 0x%02X ",packet.address[1]);
00396   printf(", 0x%02X ",packet.address[2]);
00397   printf(", 0x%02X ",packet.address[3]);
00398   printf(", 0x%02X ",packet.type);
00399   printf(", 0x%02X ",(uint8_t)(wire_length >> 8));
00400   printf(", 0x%02X \n-> Data  ",(uint8_t)(wire_length & 0xFF));
00401   #endif
00402 
00403   uint16_t sum = ((wire_length) >> 8) + ((wire_length)&0xFF) + packet.type;
00404   for (uint8_t i = 0; i < packet.length; i++) 
00405   {
00406     R503Serial.putc(packet.data[i]);
00407     sum += packet.data[i];
00408   #ifdef FINGERPRINT_DEBUG
00409     printf(", 0x%02X ",packet.data[i]);
00410   #endif
00411   }
00412 //  #ifdef FINGERPRINT_DEBUG
00413 //  printf("\n-\n");
00414 //  #endif
00415 
00416   R503Serial.putc((uint8_t)(sum >> 8));
00417   R503Serial.putc((uint8_t)(sum & 0xFF));
00418 
00419 #ifdef FINGERPRINT_DEBUG
00420   printf("-> chksum = 0x%02X%02X \n",(uint8_t)(sum >> 8),(uint8_t)(sum & 0xFF));
00421 #endif
00422 
00423   return;
00424 }
00425 
00426 /**************************************************************************/
00427 /*!
00428     @brief   Helper function to receive data over UART from the sensor and
00429    process it into a packet
00430     @param   packet A structure containing the bytes received
00431     @param   timeout how many milliseconds we're willing to wait
00432     @returns <code>FINGERPRINT_OK</code> on success
00433     @returns <code>FINGERPRINT_TIMEOUT</code> or
00434    <code>FINGERPRINT_BADPACKET</code> on failure
00435 */
00436 /**************************************************************************/
00437 uint8_t Fingerprint::getStructuredPacket(Fingerprint_Packet *packet, uint16_t timeout) 
00438 {
00439   uint8_t byte;
00440   uint16_t idx = 0, timer = 0;
00441 
00442 #ifdef FINGERPRINT_DEBUG
00443   printf("\n<----------------------packet reception\n<- ");
00444 #endif
00445 
00446   while (true) 
00447   {
00448     while (pl==pe)   // rien n'est arrivé 
00449     {
00450       wait_ms(1);
00451       timer++;
00452       if (timer >= timeout) 
00453       {
00454         #ifdef FINGERPRINT_DEBUG
00455         printf("Timed out\n");
00456         #endif
00457         return FINGERPRINT_TIMEOUT;
00458       }
00459     }
00460     byte = readUARTbuff();
00461 
00462     #ifdef FINGERPRINT_DEBUG
00463     printf("0x%02X, ",byte);
00464     #endif
00465     switch (idx) 
00466     {
00467         case 0:
00468           if (byte != (FINGERPRINT_STARTCODE >> 8))
00469             continue;
00470           packet->start_code = (uint16_t)byte << 8;
00471           break;
00472         case 1:
00473           packet->start_code |= byte;
00474           if (packet->start_code != FINGERPRINT_STARTCODE)
00475             return FINGERPRINT_BADPACKET;
00476           break;
00477         case 2: // 4 bytes for adress
00478         case 3:  
00479         case 4:
00480         case 5:
00481           packet->address[idx - 2] = byte;
00482           break;
00483         case 6:
00484           packet->type = byte;
00485           break;
00486         case 7:
00487           packet->length = (uint16_t)byte << 8;
00488           break;
00489         case 8:
00490           packet->length |= byte;
00491           #ifdef FINGERPRINT_DEBUG
00492            printf("\n<- Data ");
00493           #endif
00494           break;
00495         default:
00496           packet->data[idx - 9] = byte;
00497           if ((idx - 8) == packet->length) 
00498           {
00499                 #ifdef FINGERPRINT_DEBUG
00500                 printf("\n<--------------------packet reception OK \n\n");
00501                 #endif
00502                 return FINGERPRINT_OK;
00503           }
00504           break;
00505     }
00506     idx++;
00507   }
00508   // Shouldn't get here so...
00509   // return FINGERPRINT_BADPACKET;
00510 }
00511 
00512 /*
00513 Added by Christian Dupaty, STM32 adaptation
00514 */
00515 
00516 /***************************************************************************
00517  PRIVATE FUNCTIONS
00518  ***************************************************************************/
00519 
00520 void Fingerprint::receiveUART(void) {
00521     uint8_t c;
00522     while(!R503Serial.readable());
00523     c=R503Serial.getc();
00524     *pe=c;
00525     pe++;
00526     if (pe>buffUART+sizeof(buffUART)) pe=buffUART;
00527 }
00528 
00529 uint8_t Fingerprint::readUARTbuff(void) {
00530    uint8_t c;
00531    c=*pl;
00532    pl++;
00533    if (pl>buffUART+sizeof(buffUART)) pl=buffUART;
00534    return c;
00535 }