Fingerprint and demo library for ARM-STM32 made from the Arduino library for R503
Dependents: R503_fingerprint_HelloWorldV4
Fingerprint.cpp
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 }
Generated on Thu Jul 14 2022 22:39:35 by 1.7.2