Fingerprint Scanner API using GT511C3 fingerprint scanner.

Dependencies:   4DGL-uLCD-SE GT511C3 SDFileSystem mbed

Fork of GT511C3test by Toshihisa T

The fingerprint scanner is designed to take attendance over a group of students. It requires a the group owner to store a preloaded list of student id numbers in a .txt file to the memory (SD card) in return of a 5 digits keypass to gain access to the database when taking attendance.

While there may exist multiple group owner and a group owner with multiple databases, each group will be uniquely identified by the 5 digits keypass. The program limits each scanner to open ONE session at a time where only one group will be able to take attendance during its session. Once a session is closed, a report of the attendance taken during the open session is generated and sent via ethernet to owner and there is no way to reopen the session again.

For the initial setup, each fingerprint database needs to be populated by the students. This set up can be done continuously during a session while taking attendance that session.

Committer:
yoshua0207
Date:
Tue Dec 01 19:10:10 2015 +0000
Revision:
8:a1ba925cf903
Current fingerprint scanner code.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yoshua0207 8:a1ba925cf903 1 // This library provides the high-level functions needed to use the I2C
yoshua0207 8:a1ba925cf903 2 // serial interface supported by the hardware of several AVR processors.
yoshua0207 8:a1ba925cf903 3 #include <avr/io.h>
yoshua0207 8:a1ba925cf903 4 #include <avr/interrupt.h>
yoshua0207 8:a1ba925cf903 5 #include "types.h"
yoshua0207 8:a1ba925cf903 6 #include "defs.h"
yoshua0207 8:a1ba925cf903 7
yoshua0207 8:a1ba925cf903 8 // TWSR values (not bits)
yoshua0207 8:a1ba925cf903 9 // (taken from avr-libc twi.h - thank you Marek Michalkiewicz)
yoshua0207 8:a1ba925cf903 10 // Master
yoshua0207 8:a1ba925cf903 11 #define TW_START 0x08
yoshua0207 8:a1ba925cf903 12 #define TW_REP_START 0x10
yoshua0207 8:a1ba925cf903 13 // Master Transmitter
yoshua0207 8:a1ba925cf903 14 #define TW_MT_SLA_ACK 0x18
yoshua0207 8:a1ba925cf903 15 #define TW_MT_SLA_NACK 0x20
yoshua0207 8:a1ba925cf903 16 #define TW_MT_DATA_ACK 0x28
yoshua0207 8:a1ba925cf903 17 #define TW_MT_DATA_NACK 0x30
yoshua0207 8:a1ba925cf903 18 #define TW_MT_ARB_LOST 0x38
yoshua0207 8:a1ba925cf903 19 // Master Receiver
yoshua0207 8:a1ba925cf903 20 #define TW_MR_ARB_LOST 0x38
yoshua0207 8:a1ba925cf903 21 #define TW_MR_SLA_ACK 0x40
yoshua0207 8:a1ba925cf903 22 #define TW_MR_SLA_NACK 0x48
yoshua0207 8:a1ba925cf903 23 #define TW_MR_DATA_ACK 0x50
yoshua0207 8:a1ba925cf903 24 #define TW_MR_DATA_NACK 0x58
yoshua0207 8:a1ba925cf903 25 // Slave Transmitter
yoshua0207 8:a1ba925cf903 26 #define TW_ST_SLA_ACK 0xA8
yoshua0207 8:a1ba925cf903 27 #define TW_ST_ARB_LOST_SLA_ACK 0xB0
yoshua0207 8:a1ba925cf903 28 #define TW_ST_DATA_ACK 0xB8
yoshua0207 8:a1ba925cf903 29 #define TW_ST_DATA_NACK 0xC0
yoshua0207 8:a1ba925cf903 30 #define TW_ST_LAST_DATA 0xC8
yoshua0207 8:a1ba925cf903 31 // Slave Receiver
yoshua0207 8:a1ba925cf903 32 #define TW_SR_SLA_ACK 0x60
yoshua0207 8:a1ba925cf903 33 #define TW_SR_ARB_LOST_SLA_ACK 0x68
yoshua0207 8:a1ba925cf903 34 #define TW_SR_GCALL_ACK 0x70
yoshua0207 8:a1ba925cf903 35 #define TW_SR_ARB_LOST_GCALL_ACK 0x78
yoshua0207 8:a1ba925cf903 36 #define TW_SR_DATA_ACK 0x80
yoshua0207 8:a1ba925cf903 37 #define TW_SR_DATA_NACK 0x88
yoshua0207 8:a1ba925cf903 38 #define TW_SR_GCALL_DATA_ACK 0x90
yoshua0207 8:a1ba925cf903 39 #define TW_SR_GCALL_DATA_NACK 0x98
yoshua0207 8:a1ba925cf903 40 #define TW_SR_STOP 0xA0
yoshua0207 8:a1ba925cf903 41 // Misc
yoshua0207 8:a1ba925cf903 42 #define TW_NO_INFO 0xF8
yoshua0207 8:a1ba925cf903 43 #define TW_BUS_ERROR 0x00
yoshua0207 8:a1ba925cf903 44
yoshua0207 8:a1ba925cf903 45 // defines and constants
yoshua0207 8:a1ba925cf903 46 #define TWCR_CMD_MASK 0x0F
yoshua0207 8:a1ba925cf903 47 #define TWSR_STATUS_MASK 0xF8
yoshua0207 8:a1ba925cf903 48
yoshua0207 8:a1ba925cf903 49 // return values
yoshua0207 8:a1ba925cf903 50 #define I2C_OK 0x00
yoshua0207 8:a1ba925cf903 51 #define I2C_ERROR_NODEV 0x01
yoshua0207 8:a1ba925cf903 52
yoshua0207 8:a1ba925cf903 53 #define sbi(var, mask) ((var) |= (uint8_t)(1 << mask))
yoshua0207 8:a1ba925cf903 54 #define cbi(var, mask) ((var) &= (uint8_t)~(1 << mask))
yoshua0207 8:a1ba925cf903 55
yoshua0207 8:a1ba925cf903 56 #define WRITE_sda() DDRC = DDRC | 0b00010000 //SDA must be output when writing
yoshua0207 8:a1ba925cf903 57 #define READ_sda() DDRC = DDRC & 0b11101111 //SDA must be input when reading - don't forget the resistor on SDA!!
yoshua0207 8:a1ba925cf903 58
yoshua0207 8:a1ba925cf903 59 // functions
yoshua0207 8:a1ba925cf903 60
yoshua0207 8:a1ba925cf903 61 //! Initialize I2C (TWI) interface
yoshua0207 8:a1ba925cf903 62 void i2cInit(void);
yoshua0207 8:a1ba925cf903 63
yoshua0207 8:a1ba925cf903 64 //! Set the I2C transaction bitrate (in KHz)
yoshua0207 8:a1ba925cf903 65 void i2cSetBitrate(unsigned short bitrateKHz);
yoshua0207 8:a1ba925cf903 66
yoshua0207 8:a1ba925cf903 67 // Low-level I2C transaction commands
yoshua0207 8:a1ba925cf903 68 //! Send an I2C start condition in Master mode
yoshua0207 8:a1ba925cf903 69 void i2cSendStart(void);
yoshua0207 8:a1ba925cf903 70 //! Send an I2C stop condition in Master mode
yoshua0207 8:a1ba925cf903 71 void i2cSendStop(void);
yoshua0207 8:a1ba925cf903 72 //! Wait for current I2C operation to complete
yoshua0207 8:a1ba925cf903 73 void i2cWaitForComplete(void);
yoshua0207 8:a1ba925cf903 74 //! Send an (address|R/W) combination or a data byte over I2C
yoshua0207 8:a1ba925cf903 75 void i2cSendByte(unsigned char data);
yoshua0207 8:a1ba925cf903 76 //! Receive a data byte over I2C
yoshua0207 8:a1ba925cf903 77 // ackFlag = TRUE if recevied data should be ACK'ed
yoshua0207 8:a1ba925cf903 78 // ackFlag = FALSE if recevied data should be NACK'ed
yoshua0207 8:a1ba925cf903 79 void i2cReceiveByte(unsigned char ackFlag);
yoshua0207 8:a1ba925cf903 80 //! Pick up the data that was received with i2cReceiveByte()
yoshua0207 8:a1ba925cf903 81 unsigned char i2cGetReceivedByte(void);
yoshua0207 8:a1ba925cf903 82 //! Get current I2c bus status from TWSR
yoshua0207 8:a1ba925cf903 83 unsigned char i2cGetStatus(void);
yoshua0207 8:a1ba925cf903 84 void delay_ms(uint16_t x);
yoshua0207 8:a1ba925cf903 85
yoshua0207 8:a1ba925cf903 86 // high-level I2C transaction commands
yoshua0207 8:a1ba925cf903 87
yoshua0207 8:a1ba925cf903 88 //! send I2C data to a device on the bus (non-interrupt based)
yoshua0207 8:a1ba925cf903 89 unsigned char i2cMasterSendNI(unsigned char deviceAddr, unsigned char length, unsigned char* data);
yoshua0207 8:a1ba925cf903 90 //! receive I2C data from a device on the bus (non-interrupt based)
yoshua0207 8:a1ba925cf903 91 unsigned char i2cMasterReceiveNI(unsigned char deviceAddr, unsigned char length, unsigned char *data);
yoshua0207 8:a1ba925cf903 92
yoshua0207 8:a1ba925cf903 93 /*********************
yoshua0207 8:a1ba925cf903 94 ****I2C Functions****
yoshua0207 8:a1ba925cf903 95 *********************/
yoshua0207 8:a1ba925cf903 96
yoshua0207 8:a1ba925cf903 97 void i2cInit(void)
yoshua0207 8:a1ba925cf903 98 {
yoshua0207 8:a1ba925cf903 99 // set i2c bit rate to 40KHz
yoshua0207 8:a1ba925cf903 100 i2cSetBitrate(100);
yoshua0207 8:a1ba925cf903 101 // enable TWI (two-wire interface)
yoshua0207 8:a1ba925cf903 102 sbi(TWCR, TWEN); // Enable TWI
yoshua0207 8:a1ba925cf903 103 }
yoshua0207 8:a1ba925cf903 104
yoshua0207 8:a1ba925cf903 105 void i2cSetBitrate(unsigned short bitrateKHz)
yoshua0207 8:a1ba925cf903 106 {
yoshua0207 8:a1ba925cf903 107 unsigned char bitrate_div;
yoshua0207 8:a1ba925cf903 108 // set i2c bitrate
yoshua0207 8:a1ba925cf903 109 // SCL freq = F_CPU/(16+2*TWBR))
yoshua0207 8:a1ba925cf903 110 cbi(TWSR, TWPS0);
yoshua0207 8:a1ba925cf903 111 cbi(TWSR, TWPS1);
yoshua0207 8:a1ba925cf903 112
yoshua0207 8:a1ba925cf903 113 //calculate bitrate division
yoshua0207 8:a1ba925cf903 114 bitrate_div = ((F_CPU/4000l)/bitrateKHz);
yoshua0207 8:a1ba925cf903 115 if(bitrate_div >= 16)
yoshua0207 8:a1ba925cf903 116 bitrate_div = (bitrate_div-16)/2;
yoshua0207 8:a1ba925cf903 117 outb(TWBR, bitrate_div);
yoshua0207 8:a1ba925cf903 118 }
yoshua0207 8:a1ba925cf903 119
yoshua0207 8:a1ba925cf903 120 void i2cSendStart(void)
yoshua0207 8:a1ba925cf903 121 {
yoshua0207 8:a1ba925cf903 122 WRITE_sda();
yoshua0207 8:a1ba925cf903 123 // send start condition
yoshua0207 8:a1ba925cf903 124 TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
yoshua0207 8:a1ba925cf903 125 }
yoshua0207 8:a1ba925cf903 126
yoshua0207 8:a1ba925cf903 127 void i2cSendStop(void)
yoshua0207 8:a1ba925cf903 128 {
yoshua0207 8:a1ba925cf903 129 // transmit stop condition
yoshua0207 8:a1ba925cf903 130 TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
yoshua0207 8:a1ba925cf903 131 }
yoshua0207 8:a1ba925cf903 132
yoshua0207 8:a1ba925cf903 133 void i2cWaitForComplete(void)
yoshua0207 8:a1ba925cf903 134 {
yoshua0207 8:a1ba925cf903 135 int i = 0; //time out variable
yoshua0207 8:a1ba925cf903 136
yoshua0207 8:a1ba925cf903 137 // wait for i2c interface to complete operation
yoshua0207 8:a1ba925cf903 138 while ((!(TWCR & (1<<TWINT))) && (i < 90))
yoshua0207 8:a1ba925cf903 139 i++;
yoshua0207 8:a1ba925cf903 140 }
yoshua0207 8:a1ba925cf903 141
yoshua0207 8:a1ba925cf903 142 void i2cSendByte(unsigned char data)
yoshua0207 8:a1ba925cf903 143 {
yoshua0207 8:a1ba925cf903 144 delay_ms(1);
yoshua0207 8:a1ba925cf903 145 //printf("sending 0x%x\n", data);
yoshua0207 8:a1ba925cf903 146 WRITE_sda();
yoshua0207 8:a1ba925cf903 147 // save data to the TWDR
yoshua0207 8:a1ba925cf903 148 TWDR = data;
yoshua0207 8:a1ba925cf903 149 // begin send
yoshua0207 8:a1ba925cf903 150 TWCR = (1<<TWINT)|(1<<TWEN);
yoshua0207 8:a1ba925cf903 151 }
yoshua0207 8:a1ba925cf903 152
yoshua0207 8:a1ba925cf903 153 void i2cReceiveByte(unsigned char ackFlag)
yoshua0207 8:a1ba925cf903 154 {
yoshua0207 8:a1ba925cf903 155 // begin receive over i2c
yoshua0207 8:a1ba925cf903 156 if( ackFlag )
yoshua0207 8:a1ba925cf903 157 {
yoshua0207 8:a1ba925cf903 158 // ackFlag = TRUE: ACK the recevied data
yoshua0207 8:a1ba925cf903 159 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
yoshua0207 8:a1ba925cf903 160 }
yoshua0207 8:a1ba925cf903 161 else
yoshua0207 8:a1ba925cf903 162 {
yoshua0207 8:a1ba925cf903 163 // ackFlag = FALSE: NACK the recevied data
yoshua0207 8:a1ba925cf903 164 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
yoshua0207 8:a1ba925cf903 165 }
yoshua0207 8:a1ba925cf903 166 }
yoshua0207 8:a1ba925cf903 167
yoshua0207 8:a1ba925cf903 168 unsigned char i2cGetReceivedByte(void)
yoshua0207 8:a1ba925cf903 169 {
yoshua0207 8:a1ba925cf903 170 // retieve received data byte from i2c TWDR
yoshua0207 8:a1ba925cf903 171 return( inb(TWDR) );
yoshua0207 8:a1ba925cf903 172 }
yoshua0207 8:a1ba925cf903 173
yoshua0207 8:a1ba925cf903 174 unsigned char i2cGetStatus(void)
yoshua0207 8:a1ba925cf903 175 {
yoshua0207 8:a1ba925cf903 176 // retieve current i2c status from i2c TWSR
yoshua0207 8:a1ba925cf903 177 return( inb(TWSR) );
yoshua0207 8:a1ba925cf903 178 }
yoshua0207 8:a1ba925cf903 179
yoshua0207 8:a1ba925cf903 180 void delay_ms(uint16_t x)
yoshua0207 8:a1ba925cf903 181 {
yoshua0207 8:a1ba925cf903 182 uint8_t y, z;
yoshua0207 8:a1ba925cf903 183 for ( ; x > 0 ; x--){
yoshua0207 8:a1ba925cf903 184 for ( y = 0 ; y < 90 ; y++){
yoshua0207 8:a1ba925cf903 185 for ( z = 0 ; z < 6 ; z++){
yoshua0207 8:a1ba925cf903 186 asm volatile ("nop");
yoshua0207 8:a1ba925cf903 187 }
yoshua0207 8:a1ba925cf903 188 }
yoshua0207 8:a1ba925cf903 189 }
yoshua0207 8:a1ba925cf903 190 }