/*
Project : Finger Print Module Driver
Model : R303A/R305A series
Version : 1.0
Date : 05/02/2012
Author : Rejith cv
Location: Thiruvananthapuram, India
E-mail : rejithcvcv@gmail.com
Chip type : AVR
Clock frequency : 8.000000 MHz
*/
#include "usart.c"
const char R30X_ADDRS[] PROGMEM = {0xEF,0x01,0xFF,0xFF,0xFF,0xFF}; //DEFAULT R305 HARDWARE ADDRESS
const char R30X_SCAN[] PROGMEM = {0x01,0x00,0x03,0x01,0x00,0x05}; //SCAN COMMAND PATTERN
const char R30X_GEN_BUFF1[] PROGMEM = {0x01,0x00,0x04,0x02,0x01,0x00,0x08}; //GENERATE TEMPLATE ON BUFF1
const char R30X_GEN_BUFF2[] PROGMEM = {0x01,0x00,0x04,0x02,0x02,0x00,0x09}; //GENERATE TEMPLATE ON BUFF2
const char R30X_COMB_BUFF[] PROGMEM = {0x01,0x00,0x03,0x05,0x00,0x09}; //COMBINE BUFFER 1 AND 2
const char R30X_STORE[] PROGMEM = {0x01,0x00,0x06,0x06,0x02}; //STORE TEMPLATE
const char R30X_SEARCH[] PROGMEM = {0x01,0x00,0x08,0x1B,0x01,0x00,0x00,0x01,0x01,0x00,0x27}; //SEARCH TEMPLATES
const char R30X_DELETE_ALL[] PROGMEM = {0X01,0x00,0x03,0x0D,0x00,0x11}; //Empty all template in library
const char R30X_DELETE[] PROGMEM = {0x01,0x00,0x07,0x0C}; //Delete template
unsigned char matchfinger[2];
void SendR305Address()
{
int i;
ClearUSARTBuff();
for(i=0;i<6;i++)
{
buf.USART[i]=pgm_read_word(&R30X_ADDRS[i]);
}
USART_send_Enable();
}
unsigned char ReadFinger(void)
{
int i;
SendR305Address();
ClearUSARTBuff();
for(i=0;i<6;i++)
{
buf.USART[i]=pgm_read_byte(&R30X_SCAN[i]);
}
USART_send_Enable();
ClearUSARTBuff();
USART_receive_Enable();
return buf.USART[9];
}
unsigned char ScanFinger(int buffer_no)//Main scan finger function 0 in buffer 1 and 1 in buffer 2 respectively
{
int i,tmp;
tmp=ReadFinger();
if (tmp!=0)
return 1;
SendR305Address();
ClearUSARTBuff();
for(i=0;i<7;i++)
{
if(buffer_no==0)
buf.USART[i]=pgm_read_byte(&R30X_GEN_BUFF1[i]);
else
buf.USART[i]=pgm_read_byte(&R30X_GEN_BUFF2[i]);
}
USART_send_Enable();
ClearUSARTBuff();
USART_receive_Enable();
if(buf.USART[9]!=0)return 1;
else return 0;
}
unsigned char DeleteAllFingers(void)
{
int i;
SendR305Address();
ClearUSARTBuff();
for(i=0;i<6;i++)
{
buf.USART[i]=pgm_read_byte(&R30X_DELETE_ALL[i]);
}
USART_send_Enable();
ClearUSARTBuff();
USART_receive_Enable();
return buf.USART[9];
}
unsigned char DeleteFinger(int location,int no)
{
int i;
int checksum;
int conv1,conv2;
SendR305Address();
ClearUSARTBuff();
for(i=0;i<4;i++)
{
buf.USART[i]=pgm_read_byte(&R30X_DELETE[i]);
}
conv1=conv2=0;
for(conv1=0;location!=0;conv1++)//convert int to two hex msb and lsb
{
if(conv1>255)
{
conv1=0;
conv2++;
}
location--;
}
buf.USART[4]=conv2;
buf.USART[5]=conv1;
conv1=conv2=0;
for(conv1=0;no!=0;conv1++)//check sum calculation
{
if(conv1>255)
{
conv1=0;
conv2++;
}
no--;
}
buf.USART[6]=conv2;
buf.USART[7]=conv1;
checksum=buf.USART[0]+buf.USART[1]+buf.USART[2]+buf.USART[3]+buf.USART[4]+buf.USART[5]+buf.USART[6]+buf.USART[7];
conv1=conv2=0;
for(conv1=0;checksum!=0;conv1++)
{
if(conv1>255)
{
conv1=0;
conv2++;
}
checksum--;
}
buf.USART[8]= conv2;
buf.USART[9]= conv1;
USART_send_Enable();
ClearUSARTBuff();
USART_receive_Enable();
if(buf.USART[9]!=0)return 1;
else return 0;
}
unsigned char StoreFinger (char msb, char lsb)
{
int i;
int checksum;
int conv1,conv2=0;
SendR305Address();
ClearUSARTBuff();
for(i=0;i<5;i++)
{
buf.USART[i]=pgm_read_byte(&R30X_STORE[i]);
}
buf.USART[5]=msb;
buf.USART[6]=lsb;
checksum=buf.USART[0]+buf.USART[1]+buf.USART[2]+buf.USART[3]+buf.USART[4]+buf.USART[5]+buf.USART[6];
for(conv1=0;checksum!=0;conv1++)//check sum calculation
{
if(conv1>255)
{
conv1=0;
conv2++;
}
checksum--;
}
buf.USART[7]= conv2;
buf.USART[8]= conv1;
USART_send_Enable();
ClearUSARTBuff();
USART_receive_Enable();
if(buf.USART[9]!=0)return 1;
else return 0;
}
unsigned char CombineFinger()
{
int i;
SendR305Address();
ClearUSARTBuff();
for(i=0;i<6;i++)
{
buf.USART[i]=pgm_read_byte(&R30X_COMB_BUFF[i]);
}
USART_send_Enable();
ClearUSARTBuff();
USART_receive_Enable();
if(buf.USART[9]!=0)return 1;
else return 0;
}
unsigned char EnrollFinger(char scan, int location)//main registry entry
{
int flag;
int conv1,conv2=0;
if(!scan)
{
flag=ScanFinger(0);
if(flag)return 1;//return error
else return 0;
}
else
{
flag=ScanFinger(1);
if(flag)return 1;//return error
}
flag=CombineFinger();
if(flag)return 1;
for(conv1=0;location!=0;conv1++)//convert int to two hex msb and lsb
{
if(conv1>255)
{
conv1=0;
conv2++;
}
location--;
}
flag=StoreFinger(conv2,conv1);
return flag;
}
unsigned char SearchFinger()
{
int i;
if(ScanFinger(0)==1)return 1;
SendR305Address();
ClearUSARTBuff();
for(i=0;i<11;i++)
{
buf.USART[i]=pgm_read_byte(&R30X_SEARCH[i]);
}
USART_send_Enable();
ClearUSARTBuff();
USART_receive_Enable();
matchfinger[0]=buf.USART[11];//lsb
matchfinger[1]=buf.USART[10];//msb
return buf.USART[9];
}
//////USART
#define BAUDRATE 9600
//calculate UBRR value
#define UBRRVAL ((F_CPU/(BAUDRATE*16UL))-1)
#define BUF_SIZE 16
void USART_Disable();
void USART_receive_Enable();
void USART_send_Enable();
char RXC_Flag;
char TXC_Flag;
void USARTInit(void)
{
//Set baud rate
UBRRL=UBRRVAL; //low byte
UBRRH=(UBRRVAL>>8); //high byte
//Set data frame format: asynchronous mode,no parity, 1 stop bit, 8 bit size
UCSRC=(1<<URSEL)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)|
(0<<USBS)|(0<<UCSZ2)|(1<<UCSZ1)|(1<<UCSZ0);
//Enable Transmitter and Receiver
//UCSRB |= (1<<RXEN)|(1<<TXEN)| (1 << RXCIE);
}
//define max buffer size
//type definition of buffer structure
typedef struct{
//Array of chars
char USART[BUF_SIZE];
//array element index
uint8_t index;
}u8buf;
//declare buffer
u8buf buf;
//initialize buffer
void BufferInit()
{
//set index to start of buffer
RXC_Flag=0;
buf.index=0;
}
//write to buffer routine
uint8_t BufferWrite(u8buf *buf, uint8_t u8data)
{
buf->USART[buf->index] = u8data;
//increment buffer index
if(buf->index++<BUF_SIZE)return 0;
else return 1;
}
uint8_t BufferRead(u8buf *buf, volatile uint8_t *u8data)
{
if(buf->USART[buf->index] =='.')return 1;
*u8data=buf->USART[buf->index];
//increment buffer index
if(buf->index++<BUF_SIZE)return 0;
else return 1;
}
//RX Complete interrupt service routine
ISR(USART_RXC_vect)
{
uint8_t u8temp;
u8temp=UDR;
//BL_LCD_OFF;
//_delay_ms(50);
//BL_LCD_ON;
//check if period char or end of buffer
if ((BufferWrite(&buf, u8temp)==1)||(u8temp=='.'))
{
RXC_Flag=1;
USART_Disable();
}
}
//UDR Empty interrupt service routine+
ISR(USART_UDRE_vect )
{
//if index is not at start of buffer
if (BufferRead(&buf, &UDR)==1)
{
USART_Disable();
}
}
void USART_send_Enable()
{
BufferInit();
//USART_Disable();;
//enable transmission and UDR empty interrupt
UCSRB |= (1<<TXEN)|(1<<UDRIE);
while(UCSRB!=0);
}
void USART_receive_Enable()
{
int i=0;
BufferInit();
//USART_Disable();
//enable reception and RC complete interrupt
UCSRB |= (1<<RXEN)|(1<<RXCIE);
do{
i++;
_delay_ms(10);
}
while(UCSRB!=0&&i<100);
}
void USART_Disable()
{
UCSRB=0x00;
}
void ClearUSARTBuff()
{
int i;
for(i=0;i<BUF_SIZE;i++)
{
buf.USART[i]='.';
}
}
Rejith C.V
Thiruvananthapuram
India