Documente Academic
Documente Profesional
Documente Cultură
State machine consists of 6 states which are exit, un_set, set, entry, alarm and prog_mode. At the
beginning when program start first task is creating key. After that program goes into the state machine
and initially starts with unset_mode.In the unset mode user can activate any zone by using left most
switches (first switch is devoted for entry/exit mode), if the user enter the code they have two option
exit mode and program mode. If user enters the ‘#’ then program goes into the program mode and
program requesting changing exit period time, after change is finished and enter ‘#’, this time program
requesting changing entry period time. After this change is finished this time program asking changing
passcode. Entering final ‘#’ program goes back to the unset_mode. If user enter ’*’ then program goes
to the exit period and countdown starts begin.
End of the countdown program goes the set mode and all the sensors are starting being observed. If
any sensors which were activated in unset mode senses any movement then program goes to the alarm
mode and siren goes off and led starts flashing until the correct code being entered. If the users wants
to enter the zone then they have to activate entry/exit zone switches (left most switches on the board)
and enter the right key and this time program goes to the entry mode. In entry mode if users fails to
enter correct code in the entry period of time then program goes to the alarm mode again.
Set_key()
To create user password, set_key() function was created. When the main program call the set key function
firstly the function also call the getKey function, and getKey function read the character and send to the set
key function. In the set key function there is 1 for loop and it call the getKey function 4 times. If the character
is ‘ ‘ then the decrement the cursor by 1 ,thus program stay in the for loop until to read character except
space ‘ ‘. If we want to delete the character then we need to press ‘#’ and this make cursor put one step
back in the lcd display. As the code is seen below, there is a nested if-else statement created. Every time only
one if statement is executed others is ignored. If the number is entered then the final else statement is
executed. At the end, program get into the while loop end stay there until ‘* ‘ character is being entered.
static void setKey(void) // set user key code - this is the password
{
lcd_rst(); lcd_puts("Please create 4 digit key.");
lcd_xy(1, 2); lcd_puts("Code:____ ");
char ch;
int cursor;
if(ch == ' ') //if no char enter then stay in the for loop
//indefinitely.
cursor = cursor-1;
else if(ch == '#')
{
if(cursor == 0 )
cursor = cursor-1;
else
{
cursor = cursor-1;
code[cursor] = 0;
lcd_xy(6+cursor,2); lcd_putc('_');
cursor = cursor-1
}
}
else
{
code[cursor] += ch;/ assign the char. into the array.
lcd_xy(6+cursor,2);
lcd_putc('*');
Test_Code()
In the test code mainly switch case statement was used. Program reads the character and decided
what to do. Again if nothing is entered, then the program stays in for loop. If ‘#’ is entered then this
makes turn the cursor previous position and delete the character presently. Cursor starts on the
second line of the display and 6. Position on the second line, as the first underscore ‘_’ is placed
that position. Default mode of the switch statement is to enter the character into the array, then there
is for loop to compare that array with the other array that stores the real passcode. After the for loop
program get into the infinite while loop and there is only two option to escape from it. One is ‘*’ for
used to select unset mode, other is ‘#’ to select program mode. At the end of the function, it return
value defined accepted that will be used in the unset mode. If the return value return have number 4,
that means all for number that were entered is correct and program can go to the unset mode. If the
accepted has a value 5 then the program will go to the program mode. If the accepted has less then
value 4 which indicate that the passcode entered is wrong and the alarm will burst 250ms and
program ask the another go for user enter the code.
int testCode()
{
int compare;
char ch;
int cursor;
int accepted = 0;
char passwrdEnter[4] = 0;
lcd_xy(1,2); lcd_puts("Code:____ ");
for (cursor=0; cursor<4; cursor++)
{
ch = getKey();// read the key
switch(ch)
{
case ' ':// if it is space then stay in the for loop
cursor = cursor-1;
break;
case '#': // if the character is '#' then delete what you
entered.
if (cursor==0)
{
cursor = cursor-1;
}
else
{
cursor = cursor-1;
passwrdEnter[cursor] = 0;
lcd_xy(6+cursor,2); lcd_putc('_');
cursor = cursor-1;
}
break;
default:
passwrdEnter[cursor] += ch;
lcd_xy(6+cursor,2); lcd_putc('*');
}
}
for (compare=0; compare<4; compare++)
{
if (passwrdEnter[compare] == code[compare])
{
accepted++;
}
}
while (1)
{
if(getKey() == '#') // if it is true then go to program mode.
{
accepted++;
break;
}
if (getKey()== '*')
break;
lcd_xy(1,2); lcd_puts("Press * to set ");
}
return(accepted);
}
To change delay time, timer interruption mechanism was used. For activation of it, appropriate line in
the IRQ.ASM file should be changed for setting up interrupt vector sequence of address.
int_tim_cnt1_ufl DC $tick_handler??
For timer reload value initialisation the code showed below also need to be added.
rg . tim . cnt1_ld = timer_reload_value;
Next process is choosing system clock. In the task it was used LOW_REF clock which is 32.7 kHz by
adding,
fd.ssm.clk_en.low_pll = 0;
And the code below was also added to select one clock output from the divider chains. According to
the table in the pdf document 7-System support module, number 3 need to be assigned the code to get
.97 milliseconds delay.
rg.ssm.tap_sel2 =3;
Finally initial countsown point is entered and it is placed into the time_delay_ms_unit()
the rg . tim . cnt1_ld =65535.
Now we can get about 1 msecond delay. If we call the time_delay_ms_unit() function and assign it 5 we
can get 5 millisecond. The function was added below.
/*=============================================================================
Copyright University of Essex 2006
Author: Steve Wood
FILE - main.c
eCOG1 application.
DESCRIPTION
alarm laboratory
Cyan Ecog based eval boards and alarm 1 laboratory hardware.
Use a terminal program such as 'HyperTerminal' to communicate with the application.
The serial port configuration is shown below.
9600 Baud
8 data bits
No parity bits
One stop bit
No hardware flow control
MODIFICATION DETAILS
Based on techniques used in the eCOG1 eval board example projects
(led, eval_pcb, duart_irq), and the test routines for the alarm board.
An adapted version of driver_lib.h must be used for the #include statement.
==============================================================================*/
/******************************************************************************
Project level include files.
******************************************************************************/
#include <ecog1.h>
#include <stdio.h>
#include "driver_lib.h"
#include "util.h"
//keypad decode
#define key_0 7
#define key_1 0
#define key_2 4
#define key_3 8
#define key_4 1
#define key_5 5
#define key_6 9
#define key_7 2
#define key_8 6
#define key_9 10
#define key_ast 3
#define key_hash 11
/******************************************************************************
Declaration of static functions.
******************************************************************************/
static void alarm_short_period(int x);
static void alarm_state(int);
static void delay_5ms(void);
static int countdown_entry(void);
static int countdown_exit(void);
/******************************************************************************
Module global variables.
******************************************************************************/
static unsigned int do_pattern;
char code[4] = 0; // The password
static int exitTime = 10; // exit period multipier for countdown loop
int wrong;
int z= 0;
int p_mode=0;
//int mode_select=4;
/******************************************************************************
/*=============================================================================
Cyan Technology Limited
FILE - main.c
DESCRIPTION
Initiates the Finite State Machine
=============================================================================*/
//locals
int sw;
//INIT
alarmConfig();
// Start tick timer and enable interrupt
rg.tim.ctrl_en = TIM_CTRL_EN_CNT1_CNT_MASK;
rg.tim.int_en1 = TIM_INT_EN1_CNT1_EXP_MASK;
rg.ssm.tap_sel2 =3; // by choosing it we can get about 1 ms delay
fd.ssm.clk_en.low_pll = 0; // low pll chosen 32khz clock frequency
while (1)
{
if (1 == do_pattern)
{
//update leds from switches
sw = pio_in(PIOA); // PIOA CORRESPONDS FOR SWITCHES
sw = (sw & 0xFF00) >> 8;
pio_out(PIOB, sw);
sw = (sw & 0x007); // mask required switches (only first 3 switches required)
}
alarm_state(sw); // FSM routine
}
return (0);
}
//#######################################################################################
###########
enum State {exit, un_set, set, entry, alarm, report,prog_mode}; // take values of 0,1,2,3,4
int alarmcount;
static previous;
static State = un_set; // Initial state
pio_out(PIOB, s | State << 5); // takes the enum state value and bit shifts them
// ready to output onto the leds along with switch indicators
switch(State)
{
/*--------------------------------------------------------------------------------
UN_SET STATE (STATE 0)
un_set led enabled
Internal sounder disabledabled
Sensors not monitored.
---------------------------------------------------------------------------------*/
case un_set:
lcd_rst(); lcd_puts("Unset Mode");
previous = State;
if (getKey() != ' ')
{
if(testCode() == 4)
{
State = exit;
wrong = 0; // failure counter reset
//break;
}
else if(testCode() == 5)
{
State = prog_mode;
wrong =0;
//break;
}
else
{
if(wrong == 3)
{
State = alarm;
wrong = 0; // failure counter reset
}
else
{
pio_out(PIOB, 144); // LED6 AND LED9 ARE ON AND
HERE LED9 IS LIT FOR A DELAY TIME()
}
//break;
}
}
break;
/*------------------------------------------------------------------------------
PROGRAM MODE
--------------------------------------------------------------------------------*/
case prog_mode :
switch(z)
{
case 0:
prog(z); // for change the entry period
break;
case 2:
change_Key(); // change the key.
break;
case 3:
break;
}
State = un_set;
break;
//--------------------------------------------------------------------------------
// EXIT STATE (STATE 1)
// un_set led flashes
//Internal sounder enabled for 250msec every 500msec.
case exit:
if(previous!=State) // if the previous state does not change then dont rewrite it on the
screen.
{
lcd_rst();
lcd_puts("EXIT MODE");
}
previous = State;
switch(countdown_exit())
{
case 2:
State = alarm;
break;
case 1:
State = un_set;
break;
case 0:
State = set;
break;
}
break;
/*--------------------------------------------------------------------------------
SET STATE (STATE 2)
set led enabled
Internal sounder disabled.
---------------------------------------------------------------------------------*/
case set:
if(previous!=State)
{
lcd_rst();
lcd_puts("SET MODE");
}
previous = State;
s = pio_in(PIOA);
s = s & 0xFF00;
s = s >> 8;
pio_out(PIOB, s);
break;
/*--------------------------------------------------------------------------------
ENTRY STATE (STATE 3)
un_set led flashes
Internal sounder enabled for 250ms every 500ms.
---------------------------------------------------------------------------------*/
case entry:
if(previous!=State) // if previous state did not change then dont
{ // refreshing the lcd.
lcd_clr(); lcd_puts("ENTRY MODE");
}
previous = State;
switch(countdown_entry())
{
case 2:
State = alarm;
break;
case 1:
State = un_set;
break;
case 0:
State = alarm;
break;
}
break;
/*--------------------------------------------------------------------------------
ALARM STATE (STATE 4)
alarm led enabled
Internal and External sounders enabled.
---------------------------------------------------------------------------------*/
case alarm:
if(previous!=State)
{
lcd_rst();
lcd_clr();
lcd_puts("ALARM MODE");
}
previous = State;
while (State == alarm) // it was while (alarmcount <= 60000 && State == alarm)
{
// external sounder config and enable ******************
ssm_pwm1_clk(SSM_LOW_PLL, 9);
rg.tim.pwm1_ld = 2;
rg.tim.pwm1_val = 1;
fd.tim.pwm1_cfg.pol = 1;
fd.tim.pwm1_cfg.sw_reload = 1;
rg.tim.cmd = TIM_CMD_PWM1_LD_MASK;
rg.tim.ctrl_en = TIM_CTRL_EN_PWM1_CNT_MASK
|TIM_CTRL_EN_PWM1_AUTO_RE_LD_MASK;
//******************************************************
alarmcount++;
delay_5ms();
pio_out(PIOB, 128);
if (getKey() != ' ')
{
if(testCode() == 4) // All 4 characters match
{
rg.ssm.rst_set = SSM_RST_SET_PWM1_MASK; // disable external
sounder
wrong =0; // failure counter reset
State = un_set;
}
else
{
if(wrong == 3) // 3 times try to find code if the user fail 4th times
goes to alarm state
{
State = alarm;
wrong = 0; // failure counter reset
}
else
{
++wrong; // failure counter incremented
State = alarm;
}
}
}
}
rg.ssm.rst_set = SSM_RST_SET_PWM1_MASK; // disable external sounder
pio_out(PIOB, 128);
if (getKey() != ' ')
{
if(testCode() == 4) // All 4 characters match
{
wrong =0; // failure counter reset
State = un_set;
alarmcount = 0;
}
else
{
if(wrong == 3) // 3 times try to find code if the user fail 4th
times goes to alarm state
{
State = alarm;
wrong = 0; // failure counter reset
}
else
{
++wrong; // failure counter incremented
State = alarm;
}
}
}
break;
}
}
//#######################################################################################
###########
void prog(int z)
int cursor=0;
char ch;
lcd_rst(); lcd_puts("Prog Mode");
if(z==0)
{lcd_xy(1, 2);lcd_puts("Entry: 10s");}
if(z==1)
{lcd_xy(1, 2);lcd_puts("Exit: 10s");}
switch(ch)
{
case ' ':
cursor--; // stops no inputs from being read as characters
break;
case '#':
if (cursor==0)
{
cursor--;
}
else
{
cursor -= 1;
lcd_xy(8+cursor,2); lcd_putc('_');
cursor--;
}
break;
default:
if(cursor ==0)
{
lcd_xy(8+cursor,2);
lcd_putc(ch);
if( (ch-'0') >= 1 && (ch-'0') <= 6)
dummy_exit_time = (ch-'0')*10;
else
cursor--;
}
if(cursor == 1)
{
lcd_xy(8+cursor,2);
lcd_putc(ch);
}
}
if(z ==0)
entryTime =dummy_exit_time;
if(z==1)
exitTime =dummy_exit_time;
lcd_rst(); lcd_putc(exitTime);
lcd_rst(); lcd_puts("time changed");
lcd_xy(1,2); lcd_puts("Press # ");
while (getKey() != '#') // shows the message below until enter the '*'
{
//#######################################################################################
############
int testCode()
{
int compare;
char ch;
int cursor;
int s;
int accepted = 0;
char passwrdEnter[4] = 0;
lcd_xy(1,2); lcd_puts("Code:____ ");
for (cursor=0; cursor<4; cursor++)
{
ch = getKey();// read the key
switch(ch)
{
case ' ':// if it is space then stay in the for loop
cursor = cursor-1;
break;
case '#': // if the character is '#' then delete what you entered.
if (cursor==0)
{
cursor = cursor-1;
}
else
{
cursor = cursor-1;
passwrdEnter[cursor] = 0;
lcd_xy(6+cursor,2); lcd_putc('_');
cursor = cursor-1;
}
break;
default:
passwrdEnter[cursor] += ch;
lcd_xy(6+cursor,2); lcd_putc('*');
}
}
for (compare=0; compare<4; compare++)
{
if (passwrdEnter[compare] == code[compare])
{
accepted++;
}
}
while (1)
{
if(getKey() == '#') // if it is true then go to program mode.
{
accepted++;
break;
}
if (getKey()== '*')
break;
lcd_xy(1,2); lcd_puts("Press * to set ");
}
return(accepted);
}
/**********************************************************************************
Delays for exit timer and switch de-bounce
**********************************************************************************/
//locals
unsigned int h;
case 8:
c = entryTime; // end loop count
cancel = 2; // cancellation indicator
break;
case 4:
c = entryTime; // end loop count
cancel = 2; // cancellation indicator
break;
default:
if (getKey() == ' ')
{
cancel = 0;
}
else
{
if (testCode() == 4)
{
wrong = 0;
c = entryTime; // end loop count
cancel = 1; // cancellation indicator
}
else
{
if(wrong == 2) // Fail to match code > 3 times
{
c = entryTime;
cancel = 2;
}
else
{
wrong++; // failure counter incremented
}
}
}
break;
}
}
return cancel;
}
case 8:
c = exitTime; // end loop count
cancel = 2; // cancellation indicator
break;
case 4:
c = exitTime; // end loop count
cancel = 2; // cancellation indicator
break;
default:
if (getKey() == ' ')
{
cancel = 0;
}
else
{
if (testCode() == 4)
{
wrong = 0;
c = exitTime; // end loop count
cancel = 1; // cancellation indicator
}
else
{
if(wrong == 2) // Fail to match code > 3 times
{
c = exitTime;
cancel = 2;
}
else
{
wrong++; // failure counter incremented
}
}
}
break;
}
}
return cancel;
}
static void dBounce(void) // introduces delay between keys registered for switch de-bounce
{
//locals
unsigned int h;
/**********************************************************************************
Configurations
**********************************************************************************/
void alarmConfig(void)
{
//locals
int i;
/**********************************************************************************
Keypad functionality
**********************************************************************************/
}
}
gpio_cfg((i + col1), 1);
}
return ch;
}
static void setKey(void) // set user key code - this is the password
{
lcd_rst(); lcd_puts("Please create 4 digit key.");
lcd_xy(1, 2); lcd_puts("Code:____ ");
char ch;
int cursor;
if(ch == ' ') //if no char enter then stay in the for loop indefinitely.
cursor = cursor-1;
else if(ch == '#')
{
if(cursor == 0 )
cursor = cursor-1;
else
{
cursor = cursor-1;
code[cursor] = 0;
lcd_xy(6+cursor,2); lcd_putc('_');
cursor = cursor-1
}
}
else
{
code[cursor] += ch; // assign the charcacter into the array.
lcd_xy(6+cursor,2);
lcd_putc('*');
static void change_Key(void) // set user key code - this is the password
{
int cursor;
char ch;
lcd_rst(); lcd_puts("change the key?");
lcd_xy(1, 2); lcd_puts("Code:____ ");
for(cursor = 0; cursor < 4; cursor++) // pass through array elements
{
ch = getKey(); // read character from keypad and stored in ch
switch(ch)
{
case ' ':
cursor--; // stops no inputs from being read as characters
break;
case '#':
if (cursor==0)
{
cursor--;
}
else
{
cursor -= 1;
code[cursor] = 0;
lcd_xy(6+cursor,2); lcd_putc('_');
cursor--;
}
break;
default:
code[cursor] = ch; //put the character read from the getkey() into the array
lcd_xy(6+cursor,2);
lcd_putc('*');
break;
}
}
while (getKey() != '#') // shows the message below until enter the '#'
{
lcd_rst(); lcd_puts("change the key??");
lcd_xy(1,2); lcd_puts("Press # to set ");
}
}
rg.ssm.rst_set = SSM_RST_SET_PWM1_MASK;
}