# Issue with timer_func() and delay_func() in generic library for R551 Fingerprint Sensor - ATMega328p

Apologies for the long-winded question.

I've recently stepped outside of the Arduino realm for hardware programming. I'm working on a project that interfaces a R551 Fingerprint Sensor with an ATMega328p via UART. I found this library created for a generic microcontroller that should work with the sensor provided I give it correct function prototypes to use.

All I'm trying to do right now is confirm that these two devices can talk to each other, but I'm running into an issue when I step through the program; it seems that my program is running into an infinite loop on two lines within the library, depending on which values I use for my parameters. My program is below:

#include <avr/io.h>
#include <avr/interrupt.h>
#include "fpm.h"
#define F_CPU 16000000
#define BAUD 57600
#define BRC ((F_CPU/16/BAUD) - 1)
#define UART_BUFFER_SIZE 512
#include <util/delay.h>

volatile uint8_t *UART_buffer;
uint8_t available = 0;
uint16_t buffer_size = 0;
uint16_t UART_write_index = 0;
volatile uint32_t milliseconds = 0;

void setup(void);
void send_packet(uint8_t *bytes, uint16_t len);
uint16_t avail_packet(void);
uint32_t millis(void);

int main(void)
{
setup();

FPM finger;
FPM_System_Params params;
finger.avail_func = avail_packet;
finger.write_func = send_packet;

if (fpm_begin(&finger, 1000, 2000)) {
printf("Found fingerprint sensor!\r\n");
printf("Capacity: %d\r\n", params.capacity);
printf("Packet length: %d\r\n", fpm_packet_lengths[params.packet_len]);
}
else {
printf("Did not find fingerprint sensor :(\r\n");
while (1);
}
}

void setup(void)
{
UBRR0H = (BRC >> 8); //Shifts the BRC into the high BAUD register.
UBRR0L = BRC; //Shifts the BRC into the low BAUD register.

UCSR0B = (1 << TXEN0); //Sets the TX enable bit.
UCSR0B = (1 << RXEN0); //Sets the RX enable bit.
UCSR0C = (1 << UCSZ00) | (1 << UCSZ01); //Sets packet size.

UART_buffer = malloc(512 * sizeof(uint8_t));
}

{
*bytes = UART_buffer;
for(int i = 0; i < available; i++)
UART_buffer[i] = '\0';

return 0;
}

void send_packet(uint8_t *bytes, uint16_t len)
{
while(len > 0)
{
UDR0 = *bytes++;
len--;
}
}

uint16_t avail_packet(void)
{
return buffer_size;
}

uint32_t millis(void)
{
return milliseconds;
}

ISR(USART_RX_vect)
{
UART_buffer[UART_write_index] = UDR0;
UART_write_index++;
buffer_size++;

if(UART_write_index > UART_BUFFER_SIZE)
UART_write_index = 0;
}

/*ISR(TIMER0_COMPA_vect)
{
++milliseconds;
}*/


Going inside the definition of fpm_begin(&finger, 1000, 2000), I reach the following block of code, and this is where I begin to have problems:

uint8_t fpm_begin(FPM * fpm, fpm_millis_func _millis_func, fpm_delay_func _delay_func) {
millis_func = _millis_func;
delay_func = _delay_func;

delay_func(1000);            // 500 ms at least according to datasheet

fpm->buffer[1] = (fpm->password >> 24) & 0xff; fpm->buffer[2] = (fpm->password >> 16) & 0xff;
fpm->buffer[3] = (fpm->password >> 8) & 0xff; fpm->buffer[4] = fpm->password & 0xff;
write_packet(fpm, FPM_COMMANDPACKET, fpm->buffer, 5);

uint8_t confirm_code = 0;

if (len < 0 || confirm_code != FPM_OK)
return 0;

return 0;

return 1;
}


Unless I have 1000 and 2000 contained within the parameters for fpm_begin(&finger, 1000, 2000), delay_func(1000); will kick me back to the original if statement I started at, and this will just run in a loop without end. If I do have 1000 and 2000 contained within the parameters, I'm able to reach the int16_t len = read_ack_get_response(fpm, &confirm_code); line. Going into the definition of this (as well as the get_reply function contained within it), we get to the following block:

static int16_t get_reply(FPM * fpm, uint8_t * replyBuf, uint16_t buflen,
uint8_t * pktid, fpm_uart_write_func out_stream) {

uint8_t pid = 0;
uint16_t length = 0;
uint16_t chksum = 0;
uint16_t remn = 0;


When I reach millis_func(), it will do the same thing as delay_func(), kick me back to the beginning if statement and get stuck in a loop. I am unsure of why this is, but I believe it is related to a timing issue on the ATMega, as enabling the TIMER0_COMPA_vect ISR will cause me to get stuck at delay_func(1000);, no matter what integers I put it within the parameters of fpm_begin. I know I am supposed to have function prototypes here, but again, the ISR seems to be messing things up.