Making software using VB language
As in my final project I had a requirement of a software which will be used for communicating with the board I decided to utilized this week for designing and implementing it.
Software will be communicating with the controller over RS 232 interface.
Software will be divided into 3 sections
Before starting with actual implementation of software have made rough sketches of same using paper pen.
Have decided to use VB language for software development and .Net framework as found it to be convinient for my application
This test code detect the available COM ports and shows them in drop box list
Second dropdown provides the list of baud rates which we want to use for communication
Using button 1 we can open the port and button 2 was used to send data written onto text box on selected COM port at selected baud rate. For testing whatever data listen on serial is shown in output window. For testing purpose have shorted RX and TX of my laptop serial port so if every thing is working okay should be able to see the data I am sending on debug output window.
Again had started by writing it on paper
Started with new project by name Amol_FAB_BOMBAY_PROJECT
Have created a module where I am going to define all the commands and there replies. The reason was so I will be able to modify it easy in future. Also if there are multiple form each form is able to access these values.
Designing forms and writting backend code.
Tab 1 : This form will be used for establishing connection with the controller board. Using drop down user has to select the COM port and baud rate and then click on connect button. If connection is successful Connection success message will be displayed else Error in connection message will be displayed.
Tab 2 : Here user has to enter card number(max 8 digit) and then select expiry date for the card.
Later click onUpload card button. If card is uploaded successfully Success dialogue box will pop up else
error dialogue box.
Using Get Date/Time button we can read the date/time set inside the controller. It will get displayed
in Date and Time boxes. If we wish set the date click on set date/time button. When this button is
pressed PC date and time is sync with the controller.
Tab 3 : It is used for downloading log from the controller. When user click on Get Log button, logs from controller are read and shown on display grid. Also the logs gets stored into text file at location were software exe is kept.
As the activity of downloading the log takes longer time "Please wait message is shown to inform user to wait."
Pre defined time out is added for all commands. Whenever there is no response from the controller. Software display a dialogue box saying "Error connecting to device"
Now the 2nd part was developing same protocol and communication interface in firmware. As hardware was ready I started will serial implementation in hardware.
// Enable the peripherals
SysCtlPeripheralEnable( SYSCTL_PERIPH_UART2 );
SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOG );
// Set GPIO G0 and G1 as UART pins.
GPIOPinTypeUART( GPIO_PORTG_BASE, Serial2_Rx | Serial2_Tx );
// Configure the UART for 9600, 8-N-1 operation.
UARTConfigSetExpClk( UART2_BASE, SysCtlClockGet(), 9600,
( UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE ) );
//Set the UART FIFO Level
UARTFIFOLevelSet( UART2_BASE, UART_FIFO_TX1_8,UART_FIFO_RX1_8 );
// Enable the UART interrupt.
IntEnable( INT_UART2 );
UARTIntEnable( UART2_BASE, UART_INT_RX | UART_INT_RT );
#define RX_BUFFER_SIZE_2 100
#define TX_BUFFER_SIZE_2 5000
#define TX_TIMEOUT_2 1
#define RX_TIMEOUT_2 1
-------------------------------------CLEAR UART 2 TX BUFFER------------------------------------
void clear_uart_2_tx_buffer()
{
unsigned int i;
tx_timeout_counter_2=0;
for (i=0;i < TX_BUFFER_SIZE_2;i++)
{
tx_buffer_2[i] = 0;
}
}
-------------------------------------CLEAR UART 2 RX BUFFER------------------------------------
void clear_uart_2_rx_buffer()
{
unsigned int i;
rx_count_2 = 0;
rx_start_2 = false;
rx_command_ready_2 =false;
rx_timeout_counter_2=0;
for (i=0;i < RX_BUFFER_SIZE_2;i++)
{
rx_buffer_2[i] = 0;
}
}
void UART2IntHandler(void)
{
unsigned long ulStatus;
tBoolean rx_interrupt = false;
tBoolean tx_interrupt = false;
unsigned char received_char = 0;
// Get the interrrupt status.
ulStatus = UARTIntStatus( UART2_BASE, true );
if( UART_INT_RX )
{
rx_interrupt = true;
}
if( UART_INT_TX )
{
tx_interrupt = true;
}
// Clear the asserted interrupts. Clearing an interrupt takes time.
UARTIntClear( UART2_BASE, ulStatus );
if(rx_interrupt == true)
{
received_char = UARTCharGetNonBlocking( UART2_BASE );
if (rx_command_ready_2 == false) //Ensuring that previous data has been processed
{
rx_buffer_2[rx_count_2++] = received_char;
rx_start_2 = true;
if(rx_count_2 == 2)
{
if((rx_buffer_2[0] == 'C') && (rx_buffer_2[1] == 'O'))
{
rx_command_ready_2 = true;
rx_start_2 = false;
cmd_no = 1;
}
if((rx_buffer_2[0] == 'G') && (rx_buffer_2[1] == 'D'))
{
rx_command_ready_2 = true;
rx_start_2 = false;
cmd_no = 4;
}
if((rx_buffer_2[0] == 'G') && (rx_buffer_2[1] == 'L'))
{
rx_command_ready_2 = true;
rx_start_2 = false;
cmd_no = 5;
}
}
if(rx_count_2 == 18)
{
if(rx_buffer_2[0] == 'U' && rx_buffer_2[1] == 'C')
{
rx_command_ready_2 = true;
rx_start_2 = false;
cmd_no = 2;
}
}
if(rx_count_2 == 16)
{
if(rx_buffer_2[0] == 'S' && rx_buffer_2[1] == 'D')
{
rx_command_ready_2 = true;
rx_start_2 = false;
cmd_no = 3;
}
}
if(rx_count_2 > 18)
{
clear_uart_2_rx_buffer();
cmd_no = 0;
}
}
rx_interrupt = false;
}
if(tx_interrupt==true)
{
tx_interrupt=false;
}
}
void process_serial_command_2(void)
{
unsigned int i,length = 0;
// long temp_read_pointer;
unsigned char checksum = 0;
long err_flag;
if(rx_command_ready_2 == true)
{
switch (cmd_no)
{
case 1:
tx_buffer_2[0] = 'C';
tx_buffer_2[1] = 'O';
tx_buffer_2[2] = 'O';
tx_buffer_2[3] = 'K';
for(i = 0 ; i < 4 ; i++)
{
UARTCharPutNonBlocking(UART2_BASE, tx_buffer_2[i]);
}
break;
case 2:
ascii_to_digit(2,2,18);
err_flag = InsertDelTimeZone(rx_buffer_2);
if(err_flag == 0) //SUCCESS;
{
tx_buffer_2[0] = 'U';
tx_buffer_2[1] = 'C';
tx_buffer_2[2] = 'O';
tx_buffer_2[3] = 'K';
for(i = 0 ; i < 4 ; i++)
{
UARTCharPutNonBlocking(UART2_BASE, tx_buffer_2[i]);
}
}
else if(err_flag == -1) //FAILURE;
{
tx_buffer_2[0] = 'U';
tx_buffer_2[1] = 'C';
tx_buffer_2[2] = 'E';
tx_buffer_2[3] = 'R';
tx_buffer_2[3] = 'R';
for(i = 0 ; i < 5 ; i++)
{
UARTCharPutNonBlocking(UART2_BASE, tx_buffer_2[i]);
}
}
else if(err_flag == -2) //MEMORY_FULL;
{
tx_buffer_2[0] = 'U';
tx_buffer_2[1] = 'C';
tx_buffer_2[2] = 'E';
tx_buffer_2[3] = 'R';
tx_buffer_2[3] = 'R';
for(i = 0 ; i < 5 ; i++)
{
UARTCharPutNonBlocking(UART2_BASE, tx_buffer_2[i]);
}
}
break;
case 3:
ascii_to_digit(2,2,16);
new_present_time.date = (rx_buffer_2[2] * 10);
new_present_time.date = (new_present_time.date + rx_buffer_2[3]);
new_present_time.month = (rx_buffer_2[4] * 10);
new_present_time.month = (new_present_time.month + rx_buffer_2[5]);
new_present_time.year = (rx_buffer_2[8] * 10);
new_present_time.year = (new_present_time.year + rx_buffer_2[9]);
new_present_time.hour = (rx_buffer_2[10] * 10);
new_present_time.hour = (new_present_time.hour + rx_buffer_2[11]);
new_present_time.min = (rx_buffer_2[12] * 10);
new_present_time.min = (new_present_time.min + rx_buffer_2[13]);
new_present_time.sec = (rx_buffer_2[14] * 10);
new_present_time.sec = (new_present_time.sec + rx_buffer_2[15]);
err_flag = set_Current_Date_Time(&new_present_time);
insert_attendence_log(DateTime_Set,0,0);
if(err_flag == 0) //SUCCESS;
{
tx_buffer_2[0] = 'S';
tx_buffer_2[1] = 'D';
tx_buffer_2[2] = 'O';
tx_buffer_2[3] = 'K';
for(i = 0 ; i < 4 ; i++)
{
UARTCharPutNonBlocking(UART2_BASE, tx_buffer_2[i]);
}
}
else if(err_flag == -1) //FAILURE;
{
tx_buffer_2[0] = 'S';
tx_buffer_2[1] = 'D';
tx_buffer_2[2] = 'E';
tx_buffer_2[3] = 'R';
tx_buffer_2[3] = 'R';
for(i = 0 ; i < 5 ; i++)
{
UARTCharPutNonBlocking(UART2_BASE, tx_buffer_2[i]);
}
}
break;
case 4:
tx_buffer_2[0] = 'G';
tx_buffer_2[1] = 'D';
sprintf(tx_buffer_2+2,"%02d",date_time_variable.date);
sprintf(tx_buffer_2+4,"%02d",date_time_variable.month);
sprintf(tx_buffer_2+6,"%02d",date_time_variable.year);
sprintf(tx_buffer_2+8,"%02d",date_time_variable.hour);
sprintf(tx_buffer_2+10,"%02d",date_time_variable.min);
sprintf(tx_buffer_2+12,"%02d",date_time_variable.sec);
for(i = 0 ; i < 14 ; i++)
{
UARTCharPutNonBlocking(UART2_BASE, tx_buffer_2[i]);
}
break;
case 5:
tx_buffer_2[0] = 'G';
tx_buffer_2[1] = 'L';
SendAllEvent();
for(i = 0 ; i < 3000 ; i++)
{
if(tx_buffer_2[i] == 0)
{}
else
{
length++;
}
}
for(i = 0 ; i < length ; i++) //2690
{
UARTCharPutNonBlocking(UART2_BASE, tx_buffer_2[i]);
mili_sec(5);
}
break;
default:
break;
}
clear_uart_2_rx_buffer();
rx_command_ready_2 = false;
}
}
Have written driver files for serial UART2 for PC communication
The files can be downloaded from the link provided at the end of this page.
Board can be connected to software using 3 wires Rx, Tx and GND
6965 has 256KB of internal flash. I am using the same flash for storing Employee data and logs.
typedef struct
{
unsigned long empid;
unsigned char exp_date; //card expiry date,month and year
unsigned char exp_month;
unsigned char exp_year;
unsigned char reserve;
unsigned short int nextrec;
// structure padding
unsigned char reserved[6];
}employee_rec;
typedef struct
{
unsigned char event;
unsigned char source;
unsigned char year;
unsigned char month;
unsigned char date;
unsigned char hour;
unsigned char min;
unsigned char sec;
unsigned long empid;
unsigned char read_status;
unsigned char reserved[3];
// structure padding
}event_rec;
This structure has to be kept in multiple of 8.
Nextrec in employee is used for jumping to next location if employee data is reinserted
. So it helps in fast searching.
#define PARAM_1B_PAGES ((sizeof(param_1b)*MAX_PARAM_1B)/PAGE_SIZE)+1
#define PARAM_1B_REC_PER_PAGE PAGE_SIZE/sizeof(param_1b)
#define PARAM_4B_PAGES ((sizeof(param_4b)*MAX_PARAM_4B)/PAGE_SIZE)+1
#define PARAM_4B_REC_PER_PAGE PAGE_SIZE/sizeof(param_4b)
#define EVENT_PAGES ((sizeof(event_rec)*MAX_EVENT_REC)/PAGE_SIZE)+1
#define EVENT_REC_PER_PAGE PAGE_SIZE/sizeof(event_rec)
#define EMPLOYEE_PAGES ((sizeof(employee_rec)*MAX_EMPLOYEE)/PAGE_SIZE)+1
#define EMPLOYEE_REC_PER_PAGE PAGE_SIZE/sizeof(employee_rec)
#define PARAM_1B_START (param_1b *)0x00019400
#define PARAM_4B_START (param_4b *)((unsigned long)(PARAM_1B_START) + ((PARAM_1B_PAGES)*PAGE_SIZE) + BUFFER)
#define EVENT_START (event_rec *)((unsigned long)(PARAM_4B_START) + ((PARAM_4B_PAGES)*PAGE_SIZE) + BUFFER)
#define EMPLOYEE_START (employee_rec *)((unsigned long)(EVENT_START) + ((EVENT_PAGES)*PAGE_SIZE) + BU
Param are used for storing various 1 byte and 4 byte data which is required to be stored and retained in non volatile flash.
int read_attd_log_complete(void)
{
event_rec cur_rec;
int writeerr;
memset(&cur_rec,0xff,sizeof(event_rec));
writeerr = -1; /* error by default */
if(read_pointer != write_pointer)
{
/* record modification is required */
memcpy(&cur_rec,read_pointer,sizeof(event_rec));
if(cur_rec.event != 0xff)
{
cur_rec.read_status = 0x00;
writeerr = FlashProgram((unsigned long *)&cur_rec,(unsigned long )read_pointer,sizeof(event_rec));
}
if((unsigned long)((unsigned long)read_pointer + sizeof(event_rec)) == (unsigned long)((unsigned long)EVENT_START + sizeof(event_rec)* MAX_EVENT_REC))
{
read_pointer = EVENT_START;
}
else
{
read_pointer++;
}
}
return (writeerr);
}
event_rec* read_attd_log(void)
{
event_rec *ret;
if(read_pointer != write_pointer)
{
if(read_pointer->event == 0xff || read_pointer->read_status == 0x00)
{
init_attd_pointers();
}
if(read_pointer == write_pointer)
{
ret = NULL;
}else
{
ret = read_pointer;
}
}
else
{
ret = NULL;
}
return(ret);
}
long init_attd_pointers(void)
{
event_rec *search;
int count;
unsigned char read_found = 0,write_found = 0,temp_read = 0;
event_log_count = 0;
search = EVENT_START;
for(count = 1; count <= MAX_EVENT_REC; count++)
{
/*Write Pointer */
if(write_found == 0)
{
if(search->event == 0xff)
{
write_pointer = search;
write_found = 1;
}
else
{
event_log_count++;
}
if(count == MAX_EVENT_REC && write_found == 0)/*Memory corrput case */
{
//clear_all_logs();
read_pointer = EVENT_START;
write_pointer = EVENT_START;
read_found = 1;
write_found = 1;
}
}
/*Read pointer */
if(read_found == 0)
{
/*Flash has overflowed once */
if(g_sParameters.attd_flash_cycle_complete == 1)
{
if(temp_read == 0)
{
if(search->event != 0xff)
{
if(search->read_status == 0xff)
{
temp_read = 3;
}
else if(search->read_status == 0x00)
{
temp_read = 1;
}else
{
temp_read = 0;
}
}
else if(search->event == 0xff)
{
temp_read = 2;
}else
{
temp_read = 0;
}
}
else if(temp_read == 1)
{
if(search->event == 0xff)
{
read_pointer = search;
read_found = 1;
}else
{
}
if(search->event != 0xff)
{
if(search->read_status == 0xff)
{
read_pointer = search;
read_found = 1;
}else
{
}
}else
{
}
}
else if(temp_read == 2)
{
if(count == EVENT_REC_PER_PAGE+1)
{
if(search->event == 0xff)/*Memory corrupt case */
{
//clear_all_logs();
read_pointer = EVENT_START;
write_pointer = EVENT_START;
read_found = 1;
write_found = 1;
}
else
{
/*Search read pointer normally */
if(search->read_status == 0xff)
{
read_pointer = search;
read_found = 1;
}
else if(search->read_status == 0x00)
{
temp_read = 1;
}else
{
}
}
}else
{
}
}
else if(temp_read == 3)
{
if(search->event == 0xff)
{
temp_read = 4;
}else
{
}
}
else if(temp_read == 4)
{
if(search->event != 0xff)
{
if(search->read_status == 0xff)
{
read_pointer = search;
read_found = 1;
}
else if(search->read_status == 0x00)
{
temp_read = 5;
}else
{
}
}else
{
}
}
else if(temp_read == 5)
{
if(search->event != 0xff && search->read_status == 0xff)
{
read_pointer = search;
read_found = 1;
}else
{
}
}else
{
}
}
else/*Flash has not been full yet */
{
if(temp_read == 0)
{
if(search->event != 0xff)
{
if(search->read_status == 0xff)
{
read_pointer = search;
read_found = 1;
}
else if(search->read_status == 0x00)
{
temp_read = 1;
}else
{
}
}else if(search->event == 0xff)/*Normal case when all the flash is blank */
{ /*or Unusual case if valid read or unread records are found after first page */
temp_read = 2;
}else
{
}
}
else if(temp_read == 1)/*Some read log is found and searches for a unread log */
{
if(search->event == 0xff)
{
read_pointer = search;
read_found = 1;
}
else if(search->event != 0xff)
{
if(search->read_status == 0xff)
{
read_pointer = search;
read_found = 1;
}else
{
}
}
}
else if(temp_read == 2)
{
if(count == EVENT_REC_PER_PAGE+1)
{
if(search->event == 0xff)
{
read_pointer = EVENT_START;
read_found = 1;
}
else
{
/*Search read pointer normally */
if(search->read_status == 0xff)
{
read_pointer = search;
read_found = 1;
}
else if(search->read_status == 0x00)
{
temp_read = 1;
}
}
}else
{
}
}else
{
}
}
}else
{
}
search++;
if ((count % (EVENT_REC_PER_PAGE)) == 0) /* count starts with 1 */
{
if(write_found == 0)
{
latest_pagewrite_start = search;
event_log_count = 0;
}else
{
}
}else
{
}
if((read_found == 1) && (write_found == 1))
{
break;
}else
{
}
}
return 1;
}
long add_attendence_rec(event_rec* pbuffer)
{
event_rec cur_rec,prev_rec,*temp_addr;
long writeerr;
unsigned long address = 0;
writeerr = -1; /* error by default */
memset(&cur_rec,0xff,sizeof(event_rec));
memset(&prev_rec,0xff,sizeof(event_rec));
if(write_pointer == EVENT_START)
{
if(g_sParameters.attd_flash_cycle_complete)
{
temp_addr = (event_rec*)((unsigned long)EVENT_START + ((EVENT_PAGES-1)*PAGE_SIZE)-sizeof(event_rec));
memcpy(&prev_rec,temp_addr,sizeof(event_rec));
memcpy(&cur_rec,write_pointer,sizeof(event_rec));
if(cur_rec.event != 0xff || prev_rec.event == 0xff)
{
init_attd_pointers();
}
}
}
else
{
memcpy(&prev_rec,write_pointer-1,sizeof(event_rec));
memcpy(&cur_rec,write_pointer,sizeof(event_rec));
if(cur_rec.event != 0xff || prev_rec.event == 0xff)
{
init_attd_pointers();
}
}
if(event_log_count == ((EVENT_REC_PER_PAGE)-1))
{
if((unsigned long)((unsigned long)write_pointer+sizeof(event_rec)) == (unsigned long)((unsigned long)EVENT_START + sizeof(event_rec)* MAX_EVENT_REC))
{
address = (unsigned long)EVENT_START;
writeerr = FlashErase(address);
writeerr = FlashProgram((unsigned long *)pbuffer, (unsigned long)write_pointer, sizeof(event_rec));
write_pointer = EVENT_START;
latest_pagewrite_start = write_pointer;
event_log_count = 0;
if(g_sParameters.attd_flash_cycle_complete == 0)
{
g_sParameters.attd_flash_cycle_complete = 1;
SaveParam1b(ATTD_FLASH_ID);
}
}
else
{
address = (unsigned long)((unsigned long)latest_pagewrite_start + PAGE_SIZE);
writeerr = FlashErase(address);
writeerr = FlashProgram((unsigned long *)pbuffer, (unsigned long)write_pointer, sizeof(event_rec));
write_pointer++;
latest_pagewrite_start = write_pointer;
event_log_count = 0;
}
if((read_pointer >= write_pointer) && ((unsigned long)read_pointer < (unsigned long)((unsigned long)write_pointer+PAGE_SIZE)))
{
read_pointer = (event_rec*)((unsigned long)write_pointer+PAGE_SIZE);
}
}
else
{
writeerr = FlashProgram((unsigned long *)pbuffer, (unsigned long)write_pointer, sizeof(event_rec));
write_pointer++;
event_log_count++; /*take care what happens when it becomes greater than 32 */
}
return(writeerr);
}
These function are required as in flash we can't erase byte but having to erase entire page of 1KB and flash has fixed number of read write cycles.
int update_bankstatus_employee(void)
{
int count,pageno,free_pageno;
employee_rec *cur_rec;
employee_current_page.free = 0;
employee_current_page.deleted = 0;
employee_current_page.active = 0;
employee_maxfree_page.free = 0;
employee_maxfree_page.deleted = 0;
employee_maxfree_page.active = 0;
free_pageno = 0;
pageno = 0;
cur_rec = EMPLOYEE_START;
for(count = 1; count <= MAX_EMPLOYEE; count++)
{
if (cur_rec->empid != 0xffffffff)
{
if (cur_rec->nextrec != 0xffff)
{
employee_current_page.deleted++;
}else
{
employee_current_page.active++;
}
}else
{
employee_current_page.free++;
}
cur_rec++;
if ((count % (TIMEZONE_REC_PER_PAGE)) == 0) // count starts with 1
{
if (employee_current_page.deleted > employee_maxfree_page.deleted)
{
employee_maxfree_page.free = employee_current_page.free;
employee_maxfree_page.deleted = employee_current_page.deleted;
employee_maxfree_page.active = employee_current_page.active;
free_pageno = pageno;
}
employee_current_page.free = 0;
employee_current_page.deleted = 0;
employee_current_page.active = 0;
pageno++;
}
}
if (employee_current_page.deleted > employee_maxfree_page.deleted)
{
employee_maxfree_page.free = employee_current_page.free;
employee_maxfree_page.deleted = employee_current_page.deleted;
employee_maxfree_page.active = employee_current_page.active;
free_pageno = pageno;
}
return (free_pageno);
}
employee_rec * defragment_timezone(void)
{
int count, pageno;
employee_rec *cur_rec;
unsigned char temp_page[PAGE_SIZE];
unsigned char *temp_page_start;
//temp_page = (unsigned char *)malloc(PAGE_SIZE);
temp_page_start = temp_page;
memset(temp_page,0xff,PAGE_SIZE);
pageno = update_bankstatus_employee();
cur_rec = NULL;
if (employee_maxfree_page.deleted > 0)
{
cur_rec = (employee_rec *)((unsigned long)TIMEZONE_START + (pageno * PAGE_SIZE));
for(count = 1; count <= TIMEZONE_REC_PER_PAGE; count++)
{
if (cur_rec->nextrec == 0xffff)
{
memcpy(temp_page_start,(unsigned char *)cur_rec,sizeof(employee_rec));
}else
{
memset(temp_page_start,0xff,sizeof(employee_rec));
}
cur_rec++;
temp_page_start += sizeof(employee_rec);
}
cur_rec = (employee_rec *)((unsigned long)TIMEZONE_START + (pageno * PAGE_SIZE));
FlashErase((unsigned long )cur_rec);
FlashProgram((unsigned long *)temp_page,(unsigned long)cur_rec,PAGE_SIZE);
cur_rec = (employee_rec *)((unsigned long)TIMEZONE_START + (pageno * PAGE_SIZE));
for(count = 1; count <= TIMEZONE_REC_PER_PAGE; count++)
{
if ((cur_rec->empid == 0xffffffff) && (cur_rec->nextrec == 0xffff))
{
break;
}
cur_rec++;
}
if (count > TIMEZONE_REC_PER_PAGE)
{
cur_rec = NULL;
}
}
// free(temp_page);
return(cur_rec);
}
employee_rec * get_free_employee(void)
{
employee_rec *search;
int count, found;
search = TIMEZONE_START;
found = -1;
for (count = 1; count <= MAX_EMPLOYEE; count++)
{
if (search->empid == 0xffffffff && search->nextrec == 0xffff)
{
found = count;
break;
}
search++;
}
if (found < 0)
{
search = defragment_timezone();
}
return(search);
}
employee_rec * check_employee(employee_rec *pbuffer)
{
int found;
int count,prev_count;
employee_rec *reference,*prev_reference;
reference = TIMEZONE_START;
found = -1;
for(count = 1; count <= MAX_EMPLOYEE; count++)
{
if (reference->empid == pbuffer->empid)
{
if(reference->nextrec == 0xffff)
{
found = count;
break;
}
else if(reference->nextrec != 0x0000)
{
prev_count = count;
prev_reference = reference;
count = (reference->nextrec);
reference = (employee_rec*)((unsigned long)(TIMEZONE_START) + ((reference->nextrec)*sizeof(employee_rec)));
if(reference->empid != pbuffer->empid)
{
count = prev_count;
reference = prev_reference;
reference++;
}
}
else
{
reference++;
}
}
else
{
reference++;
}
if(reference > (employee_rec*)((unsigned long)(TIMEZONE_START) +((MAX_EMPLOYEE)*sizeof(employee_rec))))
{
break;
}
}
if (found < 0)
{
reference = NULL;
}
return(reference);
}
long add_employee(employee_rec *pbuffer)
{
int compare;
long writeerr;
employee_rec *newrec ;
employee_rec *tmprec ;
employee_rec *temp_rec;
unsigned long *temp_char;
unsigned char temp_page[PAGE_SIZE]; // temprary page of 1K
int pageno, offset;
temp_rec = (employee_rec *) malloc(sizeof(employee_rec));
//temp_page = (unsigned long *)((unsigned char *)malloc(PAGE_SIZE));
offset = sizeof(employee_rec);
writeerr = -1; // error by default
newrec = check_employee(pbuffer);
if (newrec != NULL)
{
if (pbuffer->nextrec != 0xffff)// delete exisiting record
{
// update existing record
writeerr = FlashProgram((unsigned long *)pbuffer,(unsigned long)newrec,sizeof(employee_rec));
}else
{
// record found in bank
compare = memcmp(pbuffer,newrec,sizeof(employee_rec));
if (compare != 0)
{
// record modification is required
memcpy(temp_rec , newrec , sizeof(employee_rec));
tmprec = newrec;
newrec = get_free_employee();
if (newrec != NULL)
{
temp_rec->nextrec = ((unsigned long)newrec - (unsigned long)TIMEZONE_START)/sizeof(employee_rec);
writeerr = FlashProgram((unsigned long *)temp_rec,(unsigned long )tmprec,sizeof(employee_rec));
writeerr = FlashProgram((unsigned long *)pbuffer,(unsigned long)newrec,sizeof(employee_rec));
}else
{
// copy entire page in ram
// modify contents of struct required
// erase page
// write page back to memory from ram
newrec = tmprec;
pageno = ((unsigned long)newrec - (unsigned long)TIMEZONE_START)/PAGE_SIZE;
temp_char = (unsigned long *)((unsigned long)TIMEZONE_START + (pageno * PAGE_SIZE));
offset = (unsigned long)newrec - (unsigned long)temp_char;
memcpy((unsigned char *)temp_page,(unsigned char *)temp_char,PAGE_SIZE);
newrec = (employee_rec *)((unsigned long)temp_page + offset);
memcpy(newrec,pbuffer,sizeof(employee_rec));
writeerr = FlashErase((unsigned long)tmprec);
writeerr = FlashProgram((unsigned long *)temp_page,(unsigned long)temp_char,PAGE_SIZE);
}
}else
{
// matching record already exists
writeerr = 0;// return (0);
}
}
}else
{
if (pbuffer->nextrec == 0xffff)
{
// no record found in bank
newrec = get_free_employee();
if (newrec != NULL)
{
writeerr = FlashProgram((unsigned long *)pbuffer, (unsigned long)newrec, sizeof(employee_rec));
}else
{
writeerr = -2; // buffer full
}
}else
{
writeerr = 0;// no record found to delete
}
}
free(temp_rec);
//free(temp_page);
return(writeerr);
}
void SendAllEvent()
{
event_rec *reference;
unsigned long count = 0x00000000;
unsigned int byte_no,i;
unsigned char checksum;
reference = EVENT_START + count; /// Incrementing reference as to point to start location
count = count + 1;
byte_no = 2;
for(; count <= MAX_EVENT_REC; count++)
{
if (reference->event == 0xFF)
{
reference++;
}
else
{
sprintf(tx_buffer_2+byte_no,"%01d",reference->event);
sprintf(tx_buffer_2+byte_no+1,"%02d",reference->year);
sprintf(tx_buffer_2+byte_no+3,"%02d",reference->month);
sprintf(tx_buffer_2+byte_no+5,"%02d",reference->date);
sprintf(tx_buffer_2+byte_no+7,"%02d",reference->hour);
sprintf(tx_buffer_2+byte_no+9,"%02d",reference->min);
sprintf(tx_buffer_2+byte_no+11,"%02d",reference->sec);;
sprintf(tx_buffer_2+byte_no+13,"%08d",reference->empid);
if(count == MAX_EVENT_REC)
{}
else
{
tx_buffer_2[byte_no+21] = ',';
}
byte_no += 22;
reference++;
}
}
}
unsigned char SendTimeZoneCount(void)
{
time_zone_rec *reference;
unsigned int i,count;
reference = TIMEZONE_START;
count = 0;
for(i = 1; i <= MAX_TIME_ZONE; i++)
{
if (reference->empid != 0xffffffff)
{
if(reference->nextrec == 0xffff)
{
count++;
}
}
reference++;
}
return(count);
}
/*----------------------------------------------------------------------------------------------- */
long InsertDelTimeZone(unsigned char* tcp_rcv)
{
time_zone_rec time_zone_temp;
long adderr;
unsigned char i;
time_zone_temp.empid = 0;
time_zone_temp.empid = (tcp_rcv[2] * 10000000);
time_zone_temp.empid = time_zone_temp.empid + (tcp_rcv[3] * 1000000);
time_zone_temp.empid = time_zone_temp.empid + (tcp_rcv[4] * 100000);
time_zone_temp.empid = time_zone_temp.empid + (tcp_rcv[5] * 10000) ;
time_zone_temp.empid = time_zone_temp.empid + (tcp_rcv[6] * 1000) ;
time_zone_temp.empid = time_zone_temp.empid + (tcp_rcv[7] * 100);
time_zone_temp.empid = time_zone_temp.empid + (tcp_rcv[8] * 10) ;
time_zone_temp.empid = time_zone_temp.empid + (tcp_rcv[9]) ;
time_zone_temp.exp_date = (tcp_rcv[10] * 10) ;
time_zone_temp.exp_date = time_zone_temp.exp_date + (tcp_rcv[11]) ;
time_zone_temp.exp_month =(tcp_rcv[12] * 10) ;
time_zone_temp.exp_month = time_zone_temp.exp_month + (tcp_rcv[13]) ;
time_zone_temp.exp_year = (tcp_rcv[16] * 10) ;
time_zone_temp.exp_year = time_zone_temp.exp_year + (tcp_rcv[17]) ;
insert_attendence_log(Access_bank_upload,0,time_zone_temp.empid);
if(tcp_rcv[1] == 'C')
{
time_zone_temp.nextrec = 0xffff;
}
else if (tcp_rcv[1] == 'D') ///For deleting record
{
time_zone_temp.nextrec = 0x0000;
adderr = add_time_zone(&time_zone_temp);
return(adderr);
}
for(i=0;i<=5;i++)
{
time_zone_temp.reserved[i] = 0x00;
}
time_zone_temp.reserve = 0x00;
adderr = add_time_zone(&time_zone_temp);
return(adderr);
}
/*----------------------------------------------------------------------------------------------- */
long DelAllTimeZone(void)
{
long ret_val = -1;
unsigned long totalpages;
unsigned long address;
totalpages = (TIMEZONE_PAGES);
address = (unsigned long )TIMEZONE_START;
while(totalpages--)
{
ret_val = FlashErase(address);
address += PAGE_SIZE;
}
return(ret_val);//-1 = Error, 0 = Success
}