Program Listing

(text file)

// Neal Frager
// Chun Chieh (Jack) Chuang
// April 8-29, 2002
// ECE 476 - Microcontrollers
// Lab 7
// Home Security System

#include <Mega163.h>
#include <stdio.h> //for debugging using printf, etc
#include <delay.h>
#include <string.h> 
#include <stdlib.h>

//char length of LCD screen
#define LCDwidth 16

/* Use an 1x16 alphanumeric LCD connected
to PORTC as follows:

[LCD] [AT90S8515 DIP40]
1 GND- 20 GND
2 +5V- 40 VCC
3 VLC 10k trimpot wiper (trimpot ends go to +5 and gnd) 
4 RS - 21 PC0
5 RD - 22 PC1
6 EN - 23 PC2
11 D4 - 25 PC4
12 D5 - 26 PC5
13 D6 - 27 PC6
14 D7 - 28 PC7 
*/

#asm
.equ __lcd_port=0x15
#endasm
#include <lcd.h> // LCD driver routines

#define maxkeys 14

//Debounce States
#define NOPUSH 0
#define MAYBEPUSH 1
#define PUSHED 2
#define MAYBENOPUSH 3

//User States
#define WELCOME 0
#define MAIN_MENU 1
#define NEWCODES_MENU 2
#define ALARM_MENU 3
#define ARM_MENU 4
#define ENTERCODE 5
#define WAITFORENTER 6
#define ALARM_ARMED 7
#define ALARM_OFF 8
#define POLICE 9

//Main Menu Options
#define NEWCODES 1
#define ALARM 2
#define ARM 3
#define RET_MAIN_MENU 4 

//Newcodes and Arm Menu Options
#define SYS_MAIN 1
#define SYS_A 2
#define SYS_B 3
#define SYS_C 4
#define SYS_D 5
#define SYS_E 6
#define SYS_F 7
#define RET_MAIN 8

//Alarm Menu Options
#define DISABLE 1
#define AUDIO 2
#define SILENT 3
#define RETURN 4

//timeout values for each task
#define t1 30
#define t4 50
#define t5 30

//the subroutines
void task1(void); //test for keypad button press
void task2(void); //day:hrs:min clock
void task3(void); //check security code 
void task4(void); //interpret security input
void task5(void); //turn on alarm on security breach
void initialize(void); //all the usual mcu stuff

void print_menu(void); //prints menu for security manager
void print_listmenu(void);
void print_silentmenu(void);

void gets_int(void); //reset UART for input


unsigned char reload; //timer 0 reload to set 1 mSec
unsigned char time1, time4, time5; //task scheduleing timeout counters 
unsigned int secs, mins, hrs, days; //clock counters
unsigned char key, butnum, maybebutnum; //keypad debouncing
unsigned char PushFlag; //Button Pressed
unsigned char codebuf[6]; //user security code
unsigned char codenum; //current code input
unsigned char endcode; //end of user code entry
unsigned char dbstate; //debounce state
unsigned char userstate; //user state
unsigned char menuline; //menu line number
char lcd_buffer[17]; //LCD display buffer
unsigned char alarm; //alarm state 
unsigned char audio, silent; //alarms sounding?
unsigned char armed; //alarm is armed?
unsigned char user;

//UART interrupt variables
unsigned char r_index, r_buffer[16], r_ready, r_char; //UART input
unsigned char menu_level; //which menu is security manager in?

//security code table
unsigned char security_codes[7][6];
unsigned char security_length[7];

//key pad scan table
flash unsigned char keytbl[14]={0xd7, 0xee, 0xde, 0xbe, 0xed,
0xdd, 0xbd, 0xeb, 0xdb, 0xbb,
0x7e, 0x7d, 0x7b, 0x77};


//**********************************************************
//timer 0 overflow ISR
interrupt [TIM0_OVF] void timer0_overflow(void)
{
//reload to force 1 mSec overflow
TCNT0=reload;

if(audio == 1) { //audio alarm is on
PORTB = (PORTB ^ 0xff);
}

//Decrement the three times if they are not already zero
if (time1>0) --time1; 
if (time4>0) --time4;
if (time5>0) --time5; 


//**********************************************************
//timer 1 compare-match A ISR
interrupt [TIM1_COMPA] void cmpA_overflow(void) 

if (secs>0) secs--;


//**********************************************************
//UART ISR
interrupt [UART_RXC] void UART_rcv(void)
{
r_char = UDR;
UDR = r_char; //echo char to hyperterm
if((r_char != '\r') && (r_index < 16)) r_buffer[r_index++] = r_char;
else {
putchar('\n');
r_buffer[r_index] = 0x00;
r_ready = 1;
UCSRB.7 = 0;
}


//********************************************************** 
//Entry point and task scheduler loop
void main(void)
{
initialize();
print_menu();

while(1)

if(time1 == 0) task1(); 
if(secs == 0) task2();
if(endcode > 0) task3();
if(time4 == 0) task4();
if(time5 == 0) task5(); 
}
}


//********************************************************** 
//Task 1 - detects which button on keypad has been pushed
// and debounces the button press 
void task1(void)
{
int i;
time1 = t1;

//get lower nibble
DDRA = 0x0f;
PORTA = 0xf0; 
delay_us(5);
key = PINA;

//get upper nibble
DDRA = 0xf0;
PORTA = 0x0f; 
delay_us(5);
key = key | PINA;

//find matching keycode in keytbl
if(key != 0xff)

for(maybebutnum=0; maybebutnum<maxkeys; maybebutnum++)

if(keytbl[maybebutnum]==key) break; //break loop when key found 
}
if(maybebutnum == maxkeys) maybebutnum=-1; //invalid key press

else maybebutnum=-1; //no button has been pressed 

if(PushFlag) {
switch(userstate) {
case WELCOME:
if((butnum < 10) & (codenum < 6)) {
codebuf[codenum] = butnum; 
codenum++;
lcd_gotoxy(9+codenum,1);
sprintf(lcd_buffer, "%-i", butnum);
lcd_puts(lcd_buffer);
}
if((butnum == 12) && (codenum > 0)) { //back space
lcd_gotoxy(9+codenum, 1);
lcd_putsf(" ");
codenum--;

if((butnum == 13) & (codenum >= 4)) { //end code entry with enter
endcode = 1;
}
break;
case MAIN_MENU:
if((butnum == 10) && (menuline > 1)) {
menuline--;
}
if(user == SYS_MAIN) {
if((butnum == 11) && (menuline < 3)) {
menuline++;
}
}
else {
if((butnum == 11) && (menuline < 4)) {
menuline++;
}
}

lcd_clear();
lcd_gotoxy(0,0);
if(user == SYS_MAIN) {
lcd_putsf("Main Menu");
}
else {
lcd_putsf("User Menu");
}
lcd_gotoxy(0,1);

if(menuline == 1) {
lcd_putsf("1)New Codes");
}
if(menuline == 2) {
lcd_putsf("2)Alarm Setting");
}
if(menuline == 3) {
lcd_putsf("3)Arm System");
}
if(menuline == 4) {
lcd_putsf("4)Main Menu");
}

if(user == SYS_MAIN) {
if((butnum >= 1) && (butnum <= 3)) { //end code with hot key
endcode = butnum;
}
}
else {
if((butnum >= 1) && (butnum <= 4)) { //end code with hot key
endcode = butnum;
}
}

if(butnum == 13) { //end code with enter key
endcode = menuline;
}
break;
case NEWCODES_MENU:
if(user == SYS_MAIN) {
if((butnum == 10) && (menuline > 1)) {
menuline--;
}
if((butnum == 11) && (menuline < 8)) {
menuline++;
}
}
else {
if((butnum == 10) && (menuline == 8)) {
menuline = user;
}
if((butnum == 11) && (menuline == user)) {
menuline = 8;
}
}

lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("New Codes Menu");
lcd_gotoxy(0,1);

if(menuline == 1) {
lcd_putsf("1)Main:");
for(i=0;i<security_length[0];i++) {
sprintf(lcd_buffer, "%-i", security_codes[0][i]);
lcd_gotoxy(8+i, 1);
lcd_puts(lcd_buffer);

}
if(menuline == 2) {
lcd_putsf("2)Code A:");
if(security_length[1] > 0) {
for(i=0;i<security_length[1];i++) {
sprintf(lcd_buffer, "%-i", security_codes[1][i]);
lcd_gotoxy(10+i, 1);
lcd_puts(lcd_buffer);
}
}
else {
lcd_gotoxy(10, 1);
lcd_putsf("Empty");
}
}
if(menuline == 3) {
lcd_putsf("3)Code B:");
if(security_length[2] > 0) {
for(i=0;i<security_length[2];i++) {
sprintf(lcd_buffer, "%-i", security_codes[2][i]);
lcd_gotoxy(10+i, 1);
lcd_puts(lcd_buffer);
}
}
else {
lcd_gotoxy(10, 1);
lcd_putsf("Empty");
}
}
if(menuline == 4) {
lcd_putsf("4)Code C:");
if(security_length[3] > 0) {
for(i=0;i<security_length[3];i++) {
sprintf(lcd_buffer, "%-i", security_codes[3][i]);
lcd_gotoxy(10+i, 1);
lcd_puts(lcd_buffer);
}
}
else {
lcd_gotoxy(10, 1);
lcd_putsf("Empty");
}
}
if(menuline == 5) {
lcd_putsf("5)Code D:");
if(security_length[4] > 0) {
for(i=0;i<security_length[4];i++) {
sprintf(lcd_buffer, "%-i", security_codes[4][i]);
lcd_gotoxy(10+i, 1);
lcd_puts(lcd_buffer);
}
}
else {
lcd_gotoxy(10, 1);
lcd_putsf("Empty");
}
}
if(menuline == 6) {
lcd_putsf("6)Code E:");
if(security_length[5] > 0) {
for(i=0;i<security_length[5];i++) {
sprintf(lcd_buffer, "%-i", security_codes[5][i]);
lcd_gotoxy(10+i, 1);
lcd_puts(lcd_buffer);
}
}
else {
lcd_gotoxy(10, 1);
lcd_putsf("Empty");
}
}
if(menuline == 7) {
lcd_putsf("7)Code F:");
if(security_length[6] > 0) {
for(i=0;i<security_length[6];i++) {
sprintf(lcd_buffer, "%-i", security_codes[6][i]);
lcd_gotoxy(10+i, 1);
lcd_puts(lcd_buffer);
}
}
else {
lcd_gotoxy(10, 1);
lcd_putsf("Empty");
}
}
if(menuline == 8) {
lcd_putsf("8)Return to Main");
}

if(user == SYS_MAIN) {
if((butnum >= 1) && (butnum <= 8)) { //end code with hot key
endcode = butnum;
}
}
else {
if((butnum == user) || (butnum == 8)) { //end code with hot key
endcode = butnum;
}
}

if(butnum == 13) { //end code with enter key
endcode = menuline;
}
break;
case ALARM_MENU:
if((butnum == 10) && (menuline > 1)) {
menuline--;
}
if((butnum == 11) && (menuline < 4)) {
menuline++;
}

lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Alarm Menu");
lcd_gotoxy(0,1);

if(menuline == 1) {
lcd_putsf("1)Disable Alarm");
}
if(menuline == 2) {
lcd_putsf("2)Enable Audio");
}
if(menuline == 3) {
lcd_putsf("3)Enable Silent");
}
if(menuline == 4) {
lcd_putsf("4)Return to Main");
}

if((butnum >= 1) && (butnum <= 4)) { //end code with hot key
endcode = butnum;
}
if(butnum == 13) { //end code with enter key
endcode = menuline;
}
break;
case ARM_MENU:
if(user == SYS_MAIN) {
if((butnum == 10) && (menuline > 1)) {
menuline--;
}
if((butnum == 11) && (menuline < 8)) {
menuline++;
}
}
else {
if((butnum == 10) && (menuline == 8)) {
menuline = user;
}
if((butnum == 11) && (menuline == user)) {
menuline = 8;
}
}

lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Arm Menu");
lcd_gotoxy(0,1);

if(menuline == 1) {
lcd_putsf("1)Main System");
}
if(menuline == 2) {
lcd_putsf("2)System A");
}
if(menuline == 3) {
lcd_putsf("3)System B");
}
if(menuline == 4) {
lcd_putsf("4)System C");
}
if(menuline == 5) {
lcd_putsf("5)System D");
}
if(menuline == 6) {
lcd_putsf("6)System E");
}
if(menuline == 7) {
lcd_putsf("7)System F");
}
if(menuline == 8) {
lcd_putsf("8)Return to Main");
}

if(user == SYS_MAIN) {
if((butnum >= 1) && (butnum <= 8)) { //end code with hot key
endcode = butnum;
}
}
else {
if((butnum == user) || (butnum == 8)) { //end code with hot key
endcode = butnum;
}
}
if(butnum == 13) { //end code with enter key
endcode = menuline;
}
break;
case ENTERCODE:
if((butnum < 10) & (codenum < 6)) {
codebuf[codenum] = butnum; 
codenum++;
lcd_gotoxy(9+codenum,1);
sprintf(lcd_buffer, "%-i", butnum);
lcd_puts(lcd_buffer);
}
if((butnum == 12) && (codenum > 0)) { //back space
lcd_gotoxy(9+codenum, 1);
lcd_putsf(" ");
codenum--;

if((butnum == 13) & (codenum >= 4)) { //end code entry with enter
endcode = menuline;
}
break;
case WAITFORENTER:
if(butnum == 13) { //enter pushed
endcode = 1;
}
break;
case ALARM_ARMED:
if((butnum < 10) & (codenum < 6)) {
codebuf[codenum] = butnum; 
codenum++;
lcd_gotoxy(5+codenum,1);
lcd_putsf("*");
}
if((butnum == 12) && (codenum > 0)) { //back space
lcd_gotoxy(5+codenum, 1);
lcd_putsf(" ");
codenum--;

if((butnum == 13) & (codenum >= 4)) { //end code entry with enter
endcode = menuline;
}
break;
case ALARM_OFF:
if((butnum < 10) & (codenum < 6)) {
codebuf[codenum] = butnum; 
codenum++;
lcd_gotoxy(5+codenum,1);
lcd_putsf("*");
}
if((butnum == 12) && (codenum > 0)) { //back space
lcd_gotoxy(5+codenum, 1);
lcd_putsf(" ");
codenum--;

if((butnum == 13) & (codenum >= 4)) { //end code entry with enter
endcode = menuline;
}
break;
case POLICE:
if((butnum < 10) & (codenum < 6)) {
codebuf[codenum] = butnum; 
codenum++;
lcd_gotoxy(5+codenum,1);
lcd_putsf("*");
}
if((butnum == 12) && (codenum > 0)) { //back space
lcd_gotoxy(5+codenum, 1);
lcd_putsf(" ");
codenum--;

if((butnum == 13) & (codenum >= 4)) { //end code entry with enter
endcode = menuline;
}
break;
}
PushFlag = 0;
}

switch(dbstate) {
case NOPUSH: if(maybebutnum != -1) { //valid key press
butnum = maybebutnum;
dbstate = MAYBEPUSH;
}
else {
dbstate = NOPUSH;
}
break;
case MAYBEPUSH: if(maybebutnum != -1) { //valid key press
if(maybebutnum == butnum) {
PushFlag = 1;
dbstate = PUSHED;
}
else {
butnum = maybebutnum;
dbstate = MAYBEPUSH;
}
}
else {
dbstate = NOPUSH;
}
break;
case PUSHED: if((maybebutnum != -1) | (PushFlag == 1)) { //valid key press 
dbstate = PUSHED;
}
else {
dbstate = MAYBENOPUSH;
}
break;
case MAYBENOPUSH: if(maybebutnum != -1) { //valid key press 
dbstate = PUSHED;
}
else {
dbstate = NOPUSH;
}
break;
}

switch(alarm) {
case AUDIO:
lcd_gotoxy(14,0);
lcd_putsf("|)");
break;
case SILENT:
lcd_gotoxy(14,0);
lcd_putsf("zz");
break;
}



//********************************************************** 
//Task 2 - day:hrs:min clock
void task2(void) 

secs = 60;
mins++; 

if(mins >= 60)

mins=0;
hrs++;
}

if(hrs >= 24)
{
hrs=0;
days++;
}

if(days > 365)
{
days = 1;

}


//**********************************************************
void task3(void)
{
int i;
char function;
function = endcode;
endcode = 0; 

switch(userstate) {
case WELCOME:
for(i=0;i<codenum;i++) {
security_codes[0][i] = codebuf[i];
}
security_length[0] = codenum;
codenum = 0;
userstate = MAIN_MENU;
menuline = 1;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Main Menu");
lcd_gotoxy(0,1);
lcd_putsf("1)New Codes");
break;
case MAIN_MENU:
switch(function) {
case NEWCODES: 
userstate = NEWCODES_MENU;
menuline = user;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("New Codes Menu");
lcd_gotoxy(0,1);
switch(user) {
case SYS_MAIN: 
lcd_putsf("1)Main:");
break;
case SYS_A:
lcd_putsf("2)Code A:");
break;
case SYS_B:
lcd_putsf("3)Code B:");
break;
case SYS_C:
lcd_putsf("4)Code C:");
break;
case SYS_D:
lcd_putsf("5)Code D:");
break;
case SYS_E:
lcd_putsf("6)Code E:");
break;
case SYS_F:
lcd_putsf("7)Code F:");
break;


for(i=0;i<security_length[user-1];i++) {
sprintf(lcd_buffer, "%-i", security_codes[user-1][i]);
if(user == SYS_MAIN) {
lcd_gotoxy(8+i, 1);
}
else {
lcd_gotoxy(10+i, 1);
}
lcd_puts(lcd_buffer);

break;
case ALARM: 
userstate = ALARM_MENU;
menuline = 1;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Alarm Menu");
lcd_gotoxy(0,1);
lcd_putsf("1)Disable Alarm"); 
break;
case ARM: 
userstate = ARM_MENU;
menuline = user;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Arm Menu");
lcd_gotoxy(0,1);
switch(user) {
case SYS_MAIN: 
lcd_putsf("1)Main System");
break;
case SYS_A:
lcd_putsf("2)System A");
break;
case SYS_B:
lcd_putsf("3)System B");
break;
case SYS_C:
lcd_putsf("4)System C");
break;
case SYS_D:
lcd_putsf("5)System D");
break;
case SYS_E:
lcd_putsf("6)System E");
break;
case SYS_F:
lcd_putsf("7)System F");
break;

break;
case RET_MAIN_MENU:
userstate = ALARM_OFF;
menuline = 4;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Return to Main");
lcd_gotoxy(0,1);
lcd_putsf("Main:");
break;
}
break;
case NEWCODES_MENU:
if(function < 8) {
userstate = ENTERCODE;
menuline = function;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Old Code:");
if(security_length[menuline-1] > 0) {
for(i=0;i<security_length[menuline-1];i++) {
sprintf(lcd_buffer, "%-i", security_codes[menuline-1][i]); 
lcd_gotoxy(10+i, 0);
lcd_puts(lcd_buffer);
}
}
else {
lcd_gotoxy(10, 0);
lcd_putsf("Empty");
}
lcd_gotoxy(0,1);
lcd_putsf("New code:");

else {
userstate = MAIN_MENU;
menuline = 1;
lcd_clear();
lcd_gotoxy(0,0);
if(user == SYS_MAIN) {
lcd_putsf("Main Menu");
}
else {
lcd_putsf("User Menu");
}
lcd_gotoxy(0,1);
lcd_putsf("1)New Codes");
}
break;
case ALARM_MENU:
if(function < 4) {
alarm = function;
userstate = WAITFORENTER;
menuline = 2;
lcd_clear();
lcd_gotoxy(0,0);
switch(function) {
case DISABLE:
lcd_putsf("Alarm Disabled");
break;
case AUDIO:
lcd_putsf("Audio Alarm");
lcd_gotoxy(0,1);
lcd_putsf("Enabled");
break;
case SILENT:
lcd_putsf("Silent Alarm");
lcd_gotoxy(0,1);
lcd_putsf("Enabled");
break;
}
}
else {
userstate = MAIN_MENU;
menuline = 2;
lcd_clear();
lcd_gotoxy(0,0);
if(user == SYS_MAIN) {
lcd_putsf("Main Menu");
}
else {
lcd_putsf("User Menu");
}
lcd_gotoxy(0,1);
lcd_putsf("2)Alarm Setting");
}
break;
case ARM_MENU:
if(alarm != DISABLE) {
switch(function) {
case SYS_MAIN:
userstate = ALARM_ARMED;
armed = 1;
menuline = 1;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Main Sys Armed");
lcd_gotoxy(0,1);
lcd_putsf("Code:"); 
break;
case SYS_A:
userstate = ALARM_ARMED;
armed = 1;
menuline = 2;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf(" System A Armed");
lcd_gotoxy(0,1);
lcd_putsf("Code:"); 
break;
case SYS_B:
userstate = ALARM_ARMED;
armed = 1;
menuline = 3;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("System B Armed");
lcd_gotoxy(0,1);
lcd_putsf("Code:"); 
break;
case SYS_C:
userstate = ALARM_ARMED;
armed = 1;
menuline = 4;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("System C Armed");
lcd_gotoxy(0,1);
lcd_putsf("Code:"); 
break;
case SYS_D:
userstate = ALARM_ARMED;
armed = 1;
menuline = 5;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("System D Armed");
lcd_gotoxy(0,1);
lcd_putsf("Code:"); 
break;
case SYS_E:
userstate = ALARM_ARMED;
armed = 1;
menuline = 6;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("System E Armed");
lcd_gotoxy(0,1);
lcd_putsf("Code:"); 
break;
case SYS_F:
userstate = ALARM_ARMED;
armed = 1;
menuline = 7;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("System F Armed");
lcd_gotoxy(0,1);
lcd_putsf("Code:"); 
break;
case RET_MAIN:
userstate = MAIN_MENU;
menuline = 3;
lcd_clear();
lcd_gotoxy(0,0);
if(user == SYS_MAIN) {
lcd_putsf("Main Menu");
}
else {
lcd_putsf("User Menu");
}
lcd_gotoxy(0,1);
lcd_putsf("3)Arm System");
break;
}
}
else { //alarm is disabled
if(function < RET_MAIN) {
userstate = WAITFORENTER;
menuline = 3;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Alarm Disabled");
}
else {
userstate = MAIN_MENU;
menuline = 3;
lcd_clear();
lcd_gotoxy(0,0);
if(user == SYS_MAIN) {
lcd_putsf("Main Menu");
}
else {
lcd_putsf("User Menu");
}
lcd_gotoxy(0,1);
lcd_putsf("3)Arm System");
}
}
break;
case ENTERCODE:
for(i=0;i<codenum;i++) {
security_codes[menuline-1][i] = codebuf[i];
}
security_length[menuline-1] = codenum;
codenum = 0;

userstate = NEWCODES_MENU;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("New Codes Menu");
lcd_gotoxy(0,1);
switch(menuline) {
case SYS_MAIN:
lcd_putsf("1)Main:");
for(i=0;i<security_length[0];i++) {
sprintf(lcd_buffer, "%-i", security_codes[0][i]);
lcd_gotoxy(8+i, 1);
lcd_puts(lcd_buffer);
}
break;
case SYS_A: 
lcd_putsf("2)Code A:");
for(i=0;i<security_length[1];i++) {
sprintf(lcd_buffer, "%-i", security_codes[1][i]);
lcd_gotoxy(10+i, 1);
lcd_puts(lcd_buffer);
}
break;
case SYS_B: 
lcd_putsf("3)Code B:");
for(i=0;i<security_length[2];i++) {
sprintf(lcd_buffer, "%-i", security_codes[2][i]);
lcd_gotoxy(10+i, 1);
lcd_puts(lcd_buffer);
}
break;
case SYS_C: 
lcd_putsf("4)Code C:");
for(i=0;i<security_length[3];i++) {
sprintf(lcd_buffer, "%-i", security_codes[3][i]);
lcd_gotoxy(10+i, 1);
lcd_puts(lcd_buffer);
}
break;
case SYS_D: 
lcd_putsf("5)Code D:");
for(i=0;i<security_length[4];i++) {
sprintf(lcd_buffer, "%-i", security_codes[4][i]);
lcd_gotoxy(10+i, 1);
lcd_puts(lcd_buffer);
}
break;
case SYS_E: 
lcd_putsf("6)Code E:");
for(i=0;i<security_length[5];i++) {
sprintf(lcd_buffer, "%-i", security_codes[5][i]);
lcd_gotoxy(10+i, 1);
lcd_puts(lcd_buffer);
}
break;
case SYS_F: 
lcd_putsf("7)Code F:");
for(i=0;i<security_length[6];i++) {
sprintf(lcd_buffer, "%-i", security_codes[6][i]);
lcd_gotoxy(10+i, 1);
lcd_puts(lcd_buffer);
}
break;
}
break; 
case WAITFORENTER:
switch(menuline) {
case 1:
userstate = MAIN_MENU;
lcd_clear();
lcd_gotoxy(0,0);
if(user == SYS_MAIN) {
lcd_putsf("Main Menu");
}
else {
lcd_putsf("User Menu");
}
lcd_gotoxy(0,1);
lcd_putsf("1)New Codes");
break;
case 2:
userstate = MAIN_MENU;
lcd_clear();
lcd_gotoxy(0,0);
if(user == SYS_MAIN) {
lcd_putsf("Main Menu");
}
else {
lcd_putsf("User Menu");
}
lcd_gotoxy(0,1);
lcd_putsf("2)Alarm Setting");
break;
case 3:
userstate = MAIN_MENU;
lcd_clear();
lcd_gotoxy(0,0);
if(user == SYS_MAIN) {
lcd_putsf("Main Menu");
}
else {
lcd_putsf("User Menu");
}
lcd_gotoxy(0,1);
lcd_putsf("3)Arm System");
break;
case 4:
userstate = MAIN_MENU;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("User Menu");
lcd_gotoxy(0,1);
lcd_putsf("4)Main Menu");
break;
default: //Invalid code entry
if(armed) { //alarm is armed
userstate = ALARM_ARMED;
menuline = menuline - 4;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("System Armed");
lcd_gotoxy(0,1);
lcd_putsf("Code:");
}
else { //failed to enter main menu
userstate = MAIN_MENU;
menuline = 4;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("User Menu");
lcd_gotoxy(0,1);
lcd_putsf("4)Main Menu");
}
break;
}
break;
case ALARM_ARMED:
i = 0;
if(codenum == security_length[0]) {
for(i=0; i<codenum; i++) {
if(codebuf[i] != security_codes[0][i]) break;
}
if(i == codenum) { //main code entered
audio = 0;
silent = 0;
userstate = MAIN_MENU;
armed = 0;
menuline = 1;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Main Menu");
lcd_gotoxy(0,1);
lcd_putsf("1)New Codes Menu");
}
}
if((codenum != security_length[0]) || (i != codenum)) {
if(codenum == security_length[menuline-1]) {
for(i=0; i<codenum; i++) {
if(codebuf[i] != security_codes[menuline-1][i]) break;
}
if(i == codenum) { //specific code entered - turn off alarm
audio = 0;
silent = 0;
armed = 0;
user = menuline;
userstate = MAIN_MENU;
menuline = 1;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("User Menu");
lcd_gotoxy(0,1);
lcd_putsf("1)New Codes Menu");
}
}
}
if(i != codenum) {
userstate = WAITFORENTER;
menuline = menuline + 4;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Invalid entry");
}
codenum = 0;
break; 
case ALARM_OFF:
i = 0;
if(codenum == security_length[0]) {
for(i=0; i<codenum; i++) {
if(codebuf[i] != security_codes[0][i]) break;
}
if(i == codenum) { //main code entered
user = SYS_MAIN;
userstate = MAIN_MENU;
menuline = 1;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Main Menu");
lcd_gotoxy(0,1);
lcd_putsf("1)New Codes Menu");
}
}
if(i != codenum) {
userstate = WAITFORENTER;
menuline = menuline + 4;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Invalid entry");
}
codenum = 0;
break; 
case POLICE:
i = 0;
if(codenum == security_length[0]) {
for(i=0; i<codenum; i++) {
if(codebuf[i] != security_codes[0][i]) break;
}
if(i == codenum) { //main code entered
audio = 0;
silent = 0;
userstate = MAIN_MENU;
armed = 0;
menuline = 1;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Main Menu");
lcd_gotoxy(0,1);
lcd_putsf("1)New Codes Menu");
printf("\n\rSecurity Problem Resolved!!!\n\r");
if(menu_level == 9) {
print_listmenu();
gets_int();
}
else {
menu_level = 0;
print_menu();
gets_int();
}
}
}
if((codenum != security_length[0]) || (i != codenum)) {
if(codenum == security_length[menuline-1]) {
for(i=0; i<codenum; i++) {
if(codebuf[i] != security_codes[menuline-1][i]) break;
}
if(i == codenum) { //specific code entered - turn off alarm
audio = 0;
silent = 0;
armed = 0;
user = menuline;
userstate = MAIN_MENU;
menuline = 1;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("User Menu");
lcd_gotoxy(0,1);
lcd_putsf("1)New Codes Menu");
printf("Security Problem Resolved!!!\n\r");
}
}
}
if(i != codenum) {
userstate = POLICE;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Police Coming");
lcd_gotoxy(0,1);
lcd_putsf("Code:");
}
codenum = 0;
break; 
}

// for(i=0; i<8; i++) {
// if(codenum == security_length[i]) {
// for(j=0; j<security_length[i]; j++) {
// if(codebuf[j] != security_codes[i][j]) break;
// }
// if(j == security_length[i]) break;
// }
// }

// if(j == security_length[i]) {
// PORTB = 0xfe;
// printf("\n\rSecurity correct = %d%d%d%d", codebuf[0], codebuf[1], 
// codebuf[2], codebuf[3]);
// printf("Day:%d Hour:%d Min:%d Sec:%d\n\r", days, hrs, mins, 60-secs);
// incorrect_cnt = 0;
// } 
// else {
// PORTB = 0x7f;
// incorrect_cnt++;
// printf("\n\rSecurity incorrect = %d%d%d%d*\n\r", codebuf[0], codebuf[1], 
// codebuf[2], codebuf[3]);
// printf("Day:%d Hour:%d Min:%d Sec:%d\n\r", days, hrs, mins, 60-secs);
// }
}


//**********************************************************
void task4(void)
{
int i, j;
int d, h, m;
time4 = t4;

if(silent && !r_ready && (menu_level != 8) && (userstate != POLICE)) { //silent alarm menu
menu_level = 8;
print_silentmenu();
gets_int();
}

if(!silent && !r_ready && (menu_level == 8)) { //silent alarm turned off while in silent menu
menu_level = 0;
print_menu();
gets_int();
}

if(r_ready) { 
if(menu_level == 0) { //Main Menu User Input
if(strcmpf(r_buffer,"1") == 0) {
//list security code
print_listmenu();
menu_level = 9;
gets_int(); 
}
else if(strcmpf(r_buffer,"2") == 0) {
//force an unlock
endcode = 0;
alarm = DISABLE;
armed = 0;
audio = 0;
silent = 0;
user = SYS_MAIN;
userstate = MAIN_MENU;
menuline = 1;
codenum = 0;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Main Menu");
lcd_gotoxy(0,1);
lcd_putsf("1)New Codes");
}
else if(strcmpf(r_buffer,"3") == 0) {
//force a lock
endcode = 0;
alarm = AUDIO;
armed = 1;
user = SYS_MAIN;
userstate = ALARM_ARMED;
menuline = 1;
codenum = 0;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Main Sys Armed");
lcd_gotoxy(0,1);
lcd_putsf("Code:");
}
else if(strcmpf(r_buffer,"4") == 0) {
//enter day and time
printf("Enter Day (1 to 365 or q to quit): ");
menu_level = 10;
gets_int();
}
else if(strcmpf(r_buffer,"5") == 0) {
//display day and time
printf("Day:%d Hour:%d Min:%d Sec:%d\n\r", days, hrs, mins, 60-secs);
}
else printf("Invalid command = %s\n\r", r_buffer); 

if(menu_level == 0) {
print_menu();
gets_int();
}
}
else if((menu_level >= 1) && (menu_level <= 7)) { //enter a security code
for(i=0; i<6; i++) {
if((r_buffer[i] < '0') || (r_buffer[i] > '9')) break;
else security_codes[menu_level-1][i] = r_buffer[i] - 0x30;
}
if(i<4) { //code is invalid - erase
for(j=0; j<i; j++) {
security_codes[menu_level-1][j] = 'A';
}
}
else {
security_length[menu_level-1] = i;
}
menu_level = 9;
print_listmenu();
gets_int();
}
else if(menu_level == 8) { //silent alarm menu
if(strcmpf(r_buffer,"1") == 0) {
//send police
endcode = 0;
codenum = 0;
userstate = POLICE;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Police Coming");
lcd_gotoxy(0,1);
lcd_putsf("Code:");
menu_level = 0;
print_menu();
gets_int(); 

else if(strcmpf(r_buffer,"2") == 0) {
//force an unlock
endcode = 0;
alarm = DISABLE;
armed = 0;
audio = 0;
silent = 0;
user = SYS_MAIN;
userstate = MAIN_MENU;
menuline = 1;
codenum = 0;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Main Menu");
lcd_gotoxy(0,1);
lcd_putsf("1)New Codes");
menu_level = 0;
print_menu();
gets_int();
}
}
else if(menu_level == 9) { //security code list menu
if(strcmpf(r_buffer,"1") == 0) {
printf("Enter security code: ");
menu_level = 1;
gets_int(); 
}
else if(strcmpf(r_buffer,"2") == 0) {
printf("Enter security code: ");
menu_level = 2;
gets_int(); 
}
else if(strcmpf(r_buffer,"3") == 0) {
printf("Enter security code: ");
menu_level = 3;
gets_int(); 
}
else if(strcmpf(r_buffer,"4") == 0) {
printf("Enter security code: ");
menu_level = 4;
gets_int(); 
}
else if(strcmpf(r_buffer,"5") == 0) {
printf("Enter security code: ");
menu_level = 5;
gets_int(); 
}
else if(strcmpf(r_buffer,"6") == 0) {
printf("Enter security code: ");
menu_level = 6;
gets_int(); 
}
else if(strcmpf(r_buffer,"7") == 0) {
printf("Enter security code: ");
menu_level = 7;
gets_int(); 
}
else if(strcmpf(r_buffer,"8") == 0) {
print_menu();
menu_level = 0;
gets_int(); 
}
else printf("Invalid command = %s\n\r", r_buffer); 

if(menu_level == 9) {
print_listmenu();
gets_int();
}
}
else if(menu_level == 10) { //enter number of days
d = atoi(r_buffer);
if((d > 0) && (d <= 365)) {
days = d;
printf("Enter Hour (0 to 23 or q to quit): ");
menu_level = 11;
gets_int();
}
else if((strcmpf(r_buffer,"q") == 0) || (strcmpf(r_buffer,"Q") == 0)) {
print_menu();
menu_level = 0;
gets_int();
}
else 
{
printf("Invalid command = %s\n\r", r_buffer);
printf("Enter Day (1 to 365 or q to quit): ");
menu_level = 10;
gets_int();
}
}
else if(menu_level == 11) { //enter number of hours
h = atoi(r_buffer);
if(((h > 0) && (h <= 23)) || ((h == 0) && (strcmpf(r_buffer,"0") == 0))) {
hrs = h;
printf("Enter Min (0 to 59 or q to quit): ");
menu_level = 12;
gets_int();
}
else if((strcmpf(r_buffer,"q") == 0) || (strcmpf(r_buffer,"Q") == 0)) {
print_menu();
menu_level = 0;
gets_int();
}
else 
{
printf("Invalid command = %s\n\r", r_buffer);
printf("Enter Hour (0 to 23 or q to quit): ");
menu_level = 11;
gets_int();
}
}
else if(menu_level == 12) { //enter number of minutes
m = atoi(r_buffer);
if(((m > 0) && (m <= 59)) || ((m == 0) && (strcmpf(r_buffer,"0") == 0))) {
mins = m;
print_menu();
menu_level = 0;
gets_int();
}
else if((strcmpf(r_buffer,"q") == 0) || (strcmpf(r_buffer,"Q") == 0)) {
print_menu();
menu_level = 0;
gets_int();
}
else 
{
printf("Invalid command = %s\n\r", r_buffer);
printf("Enter Min (0 to 59 or q to quit): ");
menu_level = 12;
gets_int();
}

}



//**********************************************************
void task5(void)
{
time5 = t5;

if(userstate == ALARM_ARMED) {
switch(menuline) {
case SYS_MAIN:
if((PIND.7 == 0) || (PIND.6 == 0) || (PIND.5 == 0) ||
(PIND.4 == 0) || (PIND.3 == 0) || (PIND.2 == 0)) {
if(alarm == SILENT) silent = 1;
if(alarm == AUDIO) audio = 1;
}
break;
case SYS_A:
if(PIND.2 == 0) {
if(alarm == SILENT) silent = 1;
if(alarm == AUDIO) audio = 1;
}
break;
case SYS_B:
if(PIND.3 == 0) {
if(alarm == SILENT) silent = 1;
if(alarm == AUDIO) audio = 1;
}
break;
case SYS_C:
if(PIND.4 == 0) {
if(alarm == SILENT) silent = 1;
if(alarm == AUDIO) audio = 1;
}
break;
case SYS_D:
if(PIND.5 == 0) {
if(alarm == SILENT) silent = 1;
if(alarm == AUDIO) audio = 1;
}
break;
case SYS_E:
if(PIND.6 == 0) {
if(alarm == SILENT) silent = 1;
if(alarm == AUDIO) audio = 1;
}
break;
case SYS_F:
if(PIND.7 == 0) {
if(alarm == SILENT) silent = 1;
if(alarm == AUDIO) audio = 1;
}
break;
}
}
}


//********************************************************** 
//Set it all up
void initialize(void)
{
int i, j;

//set up the ports
DDRA=0xff; //PORT A is an input/output for keypad 
DDRB=0xff; //PORT B is an output for leds and alarm
DDRC=0x00; //PORT C is an input for the LCD 
DDRD=0x00; //PORT D is an input for UART and security checks

PORTB=0xff; //all LEDs and alarm off

//serial setop for debugging using printf, etc. 
UCSRB = 0x18;
UBRR = 25;

//set up timer 0 
reload=256-62; //value for 1 Msec 
TCNT0=reload; //preload timer 1 so that is interrupts after 1 mSec.
TCCR0=3; //prescalar to 64
TIMSK=1; //turn on timer 0 overflow ISR 

//set up timer 1
TIMSK=TIMSK | 0x10; //turn on timer 1 compare match interrupt 
TCCR1B = 12; //enable timer 1 with prescalar value of 256 
TCNT1 = 0; //and zero the timer 
OCR1A = 15625; //To check that Timer1=OCR1A every 1s.

//init the task timers
time1 = t1;
time4 = t4;
time5 = t5;

//init debounce
dbstate = NOPUSH;
PushFlag = 0;

//init user state
userstate = WELCOME;
menuline = 1; 

//init day:hrs:min clock
secs = 60; 
mins = 0;
hrs = 0;
days = 1;

//init UART interrupt
menu_level = 0;
gets_int();

//initialize security codes
for(i=0; i<7; i++) {
for(j=0; j<6; j++) {
security_codes[i][j] = 'A'; //empty code value
}
security_length[i] = 0;


//init LCD
lcd_init(LCDwidth);
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Welcome User");
lcd_gotoxy(0,1);
lcd_putsf("New code:");

//init alarm
alarm = DISABLE;
audio = 0;
silent = 0;
armed = 0;

//init user
user = SYS_MAIN;

//crank up the ISRs
#asm
sei
#endasm 



//**********************************************************
//print the security menu of the system
void print_menu(void)
{
printf("\n\rSecurity Main Menu\n\r");
printf(" 1. Add, delete and list home security codes.\n\r");
printf(" 2. Force an unlock.\n\r");
printf(" 3. Force a lockdown.\n\r");
printf(" 4. Set the time and day.\n\r");
printf(" 5. Display the time and day.\n\r");
printf("Enter choice: ");
}


//**********************************************************
//print the silent alarm menu
void print_silentmenu(void)
{
printf("\n\rSilent Alarm Activated!!!\n\r");
printf(" 1. Send Police.\n\r");
printf(" 2. Force an unlock.\n\r");
printf("Enter choice: ");
}


//**********************************************************
//print the security code list menu
void print_listmenu(void)
{
int i;

printf("\n\rSecurity Code List\n\r"); 
for(i=0; i<7; i++) {
if(security_codes[i][0] == 'A')
printf("%d. Empty\n\r",i+1);
else if(security_length[i] == 4) {
printf("%d. %d%d%d%d\n\r", i+1, security_codes[i][0], security_codes[i][1],
security_codes[i][2], security_codes[i][3]);
}
else if(security_length[i] == 5) {
printf("%d. %d%d%d%d%d\n\r", i+1, security_codes[i][0], security_codes[i][1],
security_codes[i][2], security_codes[i][3],
security_codes[i][4]);
}
else if(security_length[i] == 6) {
printf("%d. %d%d%d%d%d%d\n\r", i+1, security_codes[i][0], security_codes[i][1],
security_codes[i][2], security_codes[i][3],
security_codes[i][4], security_codes[i][5]);

}
printf(" 8. Go back to main menu.\n\r");
printf("Enter choice: ");
}


//********************************************************** 
void gets_int(void) { //reset UART interrupt
r_ready = 0;
r_index = 0;
UCSRB.7 = 1;
}