Avr Code

The following is the code developed for the ATtiny2313 for this project.
Phone.asm => contains the decoder system interface
CurtainStepper.c => contains the code to run the stepper motor for the Curtain Actuation system
HomeAutomation.c => contains the decoder system interface that is being rewritten in C for easy portability

Phone.asm

; DTMF Decoder
.include "tn2313def.inc" ; The Tiny2313 definitions file (Required to program a ATTiny2313 AVR)
.def ax = R16 ; Defines Register R16 the name ax
.def valid = R17 ; Defines Register R17 the name valid
.def TOE = R18 ; Defines Register R18 the name TOE
.def OFF = R19 ; Defines Register R19 the name OFF
.def CODE1 = R20 ; Defines Register R20 the name CODE1
.def CODE2 = R21 ; Defines Register R20 the name CODE2
.def CODE3 = R22 ; Defines Register R20 the name CODE3
.def bx = R23
;* Code Segment **
.cseg
.org 0x0000 ; Places the following code in address 0x0000
rjmp RESET ; Take a Relative Jump to the RESET Label
;

; Set up the Stack, Define Ports Directions and Constants
;
RESET: ; Reset Label
;
* STACK *
cli ; Disable global interrupts
ldi ax, Low(RAMEND) ; The Stack pointer is at the lower end of RAM
out SPL, ax ; The Stack starts at the end of SRAM
;*
;*
;*
; THIS IS THE CODE in the order it must be entered *
ldi CODE1, 0b00000001 ; 1
ldi CODE2, 0b00000010 ; 2
ldi CODE3, 0b00000011 ; 3
;
*
;
*
;
*
;
*
ldi ax, 0b11111111 ; Store 11111111 in R16
out DDRB, ax ; Store AX in The PORTB Data direction Register making it an Output port
ldi ax, 0b01010000 ; MAKE PortD Inputs, Pin D6 is an OUTPUT for reseting the DTMF decoder chip, connecte to TOE
out DDRD, ax ; Pin D4 is an output to trigger the 555 timer lockout, or software sleep
; ldi upper, 0b11110000 ; Upper PINS
; ldi lower, 0b00001111 ; Lower PINS
ldi TOE, 0b01000000 ; To Ground TOE on DTMF decoder through NPN transistor & renable DTMF decoding
ldi valid, 0b00100000 ; To Check for valid DTMF code, Connects to STD on CM8870
ldi OFF, 0b00000000 ; To turn of all PINS on a PORT low
;
*
; The MAIN program loop begins here
;
*
Main:
clz ; Clear the Zero Flag to prevent erors
; Check for a valid button press
in ax, PIND ; Read in Port D
andi ax, 0b00100000 ; mask all but pin D4
cp ax, valid ; Check for valid DTMF code
breq DTMF ; If valid code is found jump to DTMF, to copy DTMF tone to inside of ATtiny2313
rjmp Main ; If no valid DTMF code is found keep waiting for one
;
*
; A valid DTMF signal came in Determine If part of code
;
***
DTMF:
clz ; Clear the Zero Flag
in ax, PIND ; read in to AX the decoded DTMF binary value on Port D
andi ax, 0b00001111 ; Mask all but the lower 4 bits
cpi ax, 0b00000001 ; Was 1 pressed? If so jump to one
breq one
cpi ax, 0b00000010 ; Was 2 pressed? If so jump to two
breq two
cpi ax, 0b00000011 ; Was 3 pressed? If so jump to three
breq three
cpi ax, 0b00000100 ; Was 4 pressed? If so jump to four
breq four
cpi ax, 0b00000101 ; Was 5 pressed? If so jump to five
breq five
cpi ax, 0b00000110 ; Was 6 pressed? If so jump to six
breq six
cpi ax, 0b00000111 ; Was 7 pressed? If so jump to seven
breq seven
cpi ax, 0b00001000 ; Was 8 pressed? If so jump to eight
breq eight
cpi ax, 0b00001001 ; Was 9 pressed? If so jump to nine
breq nine
cpi ax, 0b00001010 ; Was 0 pressed? If so jump to zero
breq zero
cpi ax, 0b00001011 ; Was * pressed? If so jump to star
breq star
cpi ax, 0b00001100 ; Was # pressed? If so jump to pound
breq pound

rjmp NewDTMF ; No valid entry (A,B,C,D or a short occoured, reset Decoder)
one:
push ax
rjmp NewDTMF ; Get Next DTMF Character
two:
push ax
rjmp NewDTMF ; Get Next DTMF Character
three:
push ax
rjmp NewDTMF ; Get Next DTMF Character
four:
push ax
rjmp NewDTMF ; Get Next DTMF Character
five:
push ax
rjmp NewDTMF ; Get Next DTMF Character
six:
push ax
rjmp NewDTMF ; Get Next DTMF Character
seven:
push ax
rjmp NewDTMF ; Get Next DTMF Character
eight:
push ax
rjmp NewDTMF ; Get Next DTMF Character
nine:
push ax
rjmp NewDTMF ; Get Next DTMF Character
zero:
push ax
rjmp NewDTMF ; Get Next DTMF Character
star:
push ax
rjmp NewDTMF ; Get Next DTMF Character
pound:
rjmp Validate
rjmp NewDTMF ; Get Next DTMF Character

;
; Reset The DTMF decoder Chip by grounding it's PIN # 10 (TOE)
;

NewDTMF:
out PORTD, TOE ; Ground TOE on DTMF decoder through transistor to reset it
NOP ; simulated wait state for DTMF decoder to reset
NOP
NOP
NOP
NOP
NOP
out PORTD, OFF ; Unground TOE on DTMF decoder
out PORTB, OFF
rjmp Main ; return to the main program loop
;
; Validate the code by POPPING the stack and reading the values
; if a propper value was entered pop again and look again, continue
; until the valid code has been revealed, or if invalid return to main
;

Validate:
clz
pop ax
cp ax, CODE3 ; Compare registers & skip next instruction if they are equal
breq Valid2
rjmp Wrong ; The Code was wrong increment the wrong counter
Valid2:
clz
pop ax
cp ax, CODE2
rjmp Valid1
rjmp Wrong
Valid1:
clz
pop ax
cp ax, CODE1
rjmp Access
rjmp Wrong
Access:
rjmp Correct
;
; The Wrong Code was entered increment the wrong counter, if 3
; wrong codes are entered, trigger the 555 timer to enter lockdown
; and disallow functioning for X amount of time, where X is
; determined by the 555 timer circuit
;

Wrong:
ldi ax, 0b00110011
out PORTB, ax

rjmp NewDTMF
;
; The correct code was entered, make stuff happen, press 9,0,*, or #
; on the phone to exit this mode
;
;

Correct:
out PORTD, TOE ; Reset the Input
NOP ; simulated wait state for DTMF decoder to reset
out PORTD, OFF
DoWhat: ; Wait for a choice (1-8) to be made on phone
clz ; Clear the zero flag
in ax, PIND ; Read in Port D
andi ax, 0b00100000 ; mask all but pin D5
cp ax, valid ; Check for valid DTMF code
breq Which ; If valid code is found jump to CopyIt
rjmp DoWhat
Which: ; Which Choice was made?
clz ; Clear the Zero Flag
in ax, PIND ; read in to AX the decoded DTMF binary value on Port D
andi ax, 0b00001111 ; Mask all but the lower 4 bits
cpi ax, 0b00000001 ; Was 1 pressed? If so jump to one1
breq one1
cpi ax, 0b00000010 ; Was 2 pressed? If so jump to two1
breq two1
cpi ax, 0b00000011 ; Was 3 pressed? If so jump to three1
breq three1
cpi ax, 0b00000100 ; Was 4 pressed? If so jump to four1
breq four1
cpi ax, 0b00000101 ; Was 5 pressed? If so jump to five1
breq five1
cpi ax, 0b00000110 ; Was 6 pressed? If so jump to six1
breq six1
cpi ax, 0b00000111 ; Was 7 pressed? If so jump to seven1
breq seven1
cpi ax, 0b00001000 ; Was 8 pressed? If so jump to eight1
breq eight1
cpi ax, 0b00001001 ; Was 9 pressed? If so jump to nine1
breq nine1
cpi ax, 0b00001010 ; Was 0 pressed? If so jump to zero1
breq zero1
cpi ax, 0b00001011 ; Was * pressed? If so jump to star1
breq star1
cpi ax, 0b00001100 ; Was # pressed? If so jump to pound1
breq pound1

rjmp Correct ; No valid entry (A,B,C,D or a short occoured, reset Decoder)

one1:
ldi ax, 0b00000001
out PINB, ax
rjmp Correct ; Get Next DTMF Character
two1:
ldi ax, 0b00000010
out PINB, ax
rjmp Correct ; Get Next DTMF Character
three1:
ldi ax, 0b00000100
out PINB, ax
rjmp Correct ; Get Next DTMF Character
four1:
ldi ax, 0b00001000
out PINB, ax
rjmp Correct ; Get Next DTMF Character
five1:
ldi ax, 0b00010000
out PINB, ax
rjmp Correct ; Get Next DTMF Character
six1:
ldi ax, 0b00100000
out PINB, ax
rjmp Correct ; Get Next DTMF Character
seven1:
ldi ax, 0b01000000
out PINB, ax
rjmp Correct ; Get Next DTMF Character
eight1:
ldi ax, 0b10000000
out PINB, ax
rjmp Correct ; Get Next DTMF Character
nine1:
zero1:
star1:
pound1:
out PINB, OFF
NOP
NOP
; rjmp NewDTMF ; Get Next DTMF Character
rjmp Correct
;*
; THE END
;
*
finish: ; Return to the main loop
rjmp Main

CurtainStepper.c




Curtain Stepper Driver



This program creates the control signal for a Stepper
// Motor. The output is generalized for half, single, and
// torque stepping modes. Delay (rotation speed), Rotation
// Direction, Enable/Disable, are given by input pins
// extrnally
//
// Coil outputs are fed to an H-Bridge for Biploar Motors or
// to a ULN2803 (or ULN2003) Darlington Array chip, which
// drive the coils directly

This program was made to Control the opening and
// closing of a curtain, or a set of blinds. This is
// accomplished by controlling a geared Stepper Motor.
// The Stepper motor drives a nut along the length of
// a threaded rod which is attached to the curtain
// pull string or will drive the blind rod directly.

Inputs-
// Firmware Defined:
// Rotation Speed => delay - Time between steps
// Steps Taken => rotations - not individual steps, walks through entire array.
// If 'rotations' == 12 the motor will complete 1 rotation
// To rely wholly on Limit Switches set Rotations high

Defined by Input Pins:
// PD0 => (0x01): ccw - rotation direction
// PD1 => (0x02): singlep - halfstep vs (single or torque)
// PD2 => (0x04): torquep - single vs torque
// PD3 => (0x08): Delay - low = 1ms; high = 500ms
// PD4 => (0x10): Limit Switch #1 - indicates the end of clockwise movement
// PD5 => (0x20): Limit Switch #2 - indicates the end of counter-clockwise
// movement
// PD6 => (0x40): NewJob - Signal enables motor to turn defined ammount.

Outputs-
// Motor Turns to predefined position

PB0 => (0x01): Coil 4 -
// PB1 => (0x02): Coil 3 -
// PB2 => (0x04): Coil 2 -
// PB3 => (0x08): Coil 1 -
// PB4 => (0x10):
// PB5 => (0x20):
// PB6 => (0x40):
// PB7 => (0x80):




//**


#Includes

#include <avr/interrupt.h> // Defines pins, ports, etc to make programs easier to read
#define F_CPU 20000000UL // Sets up the default speed for delay.h
#include <util/delay.h> // Allows for delay to be used
#include <avr/io.h> // Enables IO
#include <inttypes.h> // ??? Interrupts ???

#defines Pin Definitions

#define B1 _BV(PB0)

Function Prototypes

int SetDelay(int);
int halfstep(int, int, int);
int singlestep(int, int, int);
void WaitState(int);
int torquestep(int, int, int);

// Main Program

int main(){
* Define IO *
DDRB = 0xFF; _BV(PB4); // enable output on port B, pin 4
DDRD = 0x00; // PortD is an INPORT
PORTB = 0x00; // Set PortB = 0
* Variable Declarations

int ccw; // 1 = clockwise, 0 = ccw
int steps = 7; // number to steps to walk through the array minus 1
int singlep; // To set half stepping leave low PD1, to set torque or single
stepping set PD1 high
int torquep; // To set single stepping leave PD2 low, to set torque stepping set PD2 high
int delay = 1; // initial value for delay, can be changed
int NewJob = 0; // Waits for a high, then turns once recieved
int multiplier = 50; // 50 = 12 complete turns of the shaft = 1/2 inch
int rotations = multiplier*12-1; // # of times to repeat step loop (12-1 times = 1 rotation)
// // (x*12-1) = x rotations
* MAIN Loop *

while(1) // Endless loop, same as "for(;;)"
{
// Read PD0 - Turn Clockwise or counter clockwise?
singlep = (PIND & 0x02);
Read PD1 - Do single stepping or half stepping (single = 1, half = 0)
torquep = (PIND & 0x04);
Read PD2 - Torque stepping or single stepping (torque = 1, single = 0 )
NewJob = (PIND & 0x40); // Read PD6 - New Job start turning
delay = SetDelay(delay);

if(NewJob == 0x40) // If PD6 == 1 begin turning
{
ccw = (PIND & 0x01);
/*if(singlep != 0x02) // HALF STEPPING
{
halfstep(ccw, rotations, delay); // * Function Call returns a "1" *
}
else if((singlep == 0x02) && (torquep == 0x04)) // TORQUE STEPPING
{
torquestep(ccw, rotations, delay); // * Function Call returns a "1" *
}
else // (Singlep == 0x02) && (torquep == 0x00) // SINGLE STEPPING
{
*/// ** To travel the entire Rod Test *
for(int count = 0; count < 55; count++)
{
singlestep(ccw, rotations, delay); // *** Function Call returns a "1"
}
//}
}
PORTB = 0x00; // Turn off the current to the coils when finished
} // End of While loop
return(0);
}


Set the Delay
//

int SetDelay(int delay)
{

int determine;
determine = (PIND & 0x08); // Read PD3 & PD4 - Delay pins
if(determine == 0x00) // Pins read - (0,0) - (pd4,pd3)
{
delay = 100;
}
/*(else if(determine == 0x08) // Pins read - (0,1) - (pd4,pd3)
{
delay = 10;
}
else if(determine == 0x10) // Pins read - (1,0) - (pd4,pd3)
{
delay = 500;
}*/
else // if (determine == 0x08) // Pins read - (1,1) - (pd4,pd3)
{
delay = 100;
}

return (delay);
}


Simulated WaitState
//

void WaitState(int delay)
{
for(int i = 0; i < delay ; i++)
{
for(int j = 0; j < delay ; j++)
{
for(int k = 0; k < delay ; k++)
{
}
}
}
for(int i = 0; i < delay ; i++)
{
for(int j = 0; j < delay ; j++)
{
for(int k = 0; k < delay ; k++)
{
}
}
}
for(int i = 0; i < delay ; i++)
{
for(int j = 0; j < delay ; j++)
{
for(int k = 0; k < delay ; k++)
{
}
}
}

}

Half Stepping

/*
int halfstep(int ccw, int rotations, int delay)
{
Half stepping, set steps = 7
const uint8_t clockwise[] = {0x08, 0x0c, 0x04, 0x06, 0x02, 0x03, 0x01, 0x09};
int steps = 7; // # of variables in the clockwise array
int LS1 = 0; // Limit Switch PD5 == 0x0
int LS2 = 0;
if (ccw == 0x01) // If PD0 == 1 turn clockwise
{
for(int x = 0; (x <= rotations); x++) // # of times to do step sequence
{
LS1 = (PIND & 0x10); // read the limit switch
if(LS1 == 0x10)
{
return (1);
}
for(int i = steps; i >= 0; i— ) // Turn Clockwise
{
PORTB = clockwise[i];
_delay_ms(delay);
}
}
}
else // If PD0 == 0 turn counterclockwise
{
for(int x = 0; (x <= rotations); x++) // # of times to do step sequence
{
LS2 = (PIND & 0x20); // read the limit switch
if(LS2 == 0x20)
{
return (1);
}

for(int i = 0; i <= steps; i++ ) // Turn Counter-Clockwise
{
PORTB = clockwise[i];
_delay_ms(delay);
}
}
}
return (1);
}
*/

Single Stepping
//

int singlestep(int ccw, int rotations, int delay)
{
const uint8_t single[] = {0x08, 0x04, 0x02, 0x01}; // Single stepping, set steps = 3
int steps = 3; // # of variables in the clockwise array
int LS1 = 0; // Limit Switch PD5 == 0x0
int LS2 = 0;
if (ccw == 0x01) // If PD0 == 1 turn clockwise
{
for(int x = 0; x <= rotations; x++) // # of times to do step sequence
{
LS1 = (PIND & 0x10); // read the limit switch PD5
if(LS1 == 0x10)
{
return (1);
}
for(int i = steps; i >= 0; i— ) // Turn Clockwise
{
PORTB = single[i];
//WaitState(delay);
for (int ii = 0; ii < 13; ii++)
{
_delay_us(delay);
}
}
}
}
else // If PD0 == 0 turn counterclockwise
{
for(int x = 0; x <= rotations; x++) // # of times to do step sequence
{
LS2 = (PIND & 0x20); // Read the limit switch PD5
if(LS2 == 0x20)
{
return (1);
}
for(int i = 0; i <= steps; i++ ) // Turn Counter-Clockwise
{
PORTB = single[i];
//WaitState(delay);
for (int ii = 0; ii < 13; ii++)
{
_delay_us(delay);
}
}
}
}
return (1);
}


Torque Stepping
//

/*int torquestep(int ccw, int rotations, int delay)
{
const uint8_t torque[] = {0x0c, 0x06, 0x03, 0x09}; // Torque stepping, set steps = 3
int steps = 3; // # of variables in the clockwise array
int LS1 = 0; // Limit Switch PD5 == 0x0
int LS2 = 0;
if (ccw == 0x01) // If PD0 == 1 turn clockwise
{
for(int x = 0; x <= rotations; x++) // # of times to do step sequence
{
LS1 = (PIND & 0x10); // read the limit switch PD5
if(LS1 == 0x10)
{
return (1);
}
for(int i = steps; i >= 0; i— ) // Turn Clockwise
{
PORTB = torque[i];
_delay_ms(delay);
}
}
}
else // If PD0 == 0 turn counterclockwise
{
for(int x = 0; x <= rotations; x++) // # of times to do step sequence
{
LS2 = (PIND & 0x20); // read the limit switch PD5
if(LS2 == 0x20)
{
return (1);
}
for(int i = 0; i <= steps; i++ ) // Turn Counter-Clockwise
{
PORTB = torque[i];
_delay_ms(delay);
}
}
}

return (1);
}
*/

HomeAutomation.c




Home Automation



This program controls a Remote Home Automation System
// that has a ATtiny2313 uP at its core. The code is
// intended to be easily ported to other products in the
// ATMEL AVR family & so all port names are given in the
// #define section.

This code is based on 'Phone.asm' written by me durring
// the summer of 2007, but with Portability in mind. And is
// interfaced with a Phone through a CM8870 DTMF decoder
// circuit as well as various subsystems of my own design.

Written By: David McDougall
// Date: 2/29/08


//**


#Includes
//

#include <avr/interrupt.h> // Defines pins, ports, etc to make programs easier to read
#define F_CPU 8000000UL // Sets up the default speed for delay.h
#include <util/delay.h> // Allows for delay to be used
#include <avr/io.h> // Enables IO
#include "lcd.h" // Header file for controlling a HD44780 compatible LCD on a 2313
#include "lcdor.h"


#defines for porting to new uP
//

//#define B1 _BV(PB0)
#define Bit1 1
#define Bit2 2
#define Bit3 3
#define Bit4 4

#define STD (PIND & 0x10) // Pin D5 is connected to STD on CM8870
#define TOE 0b01000000 // Pin D6 is connected to TOE on CM8870
#define CodeMask 0x0F // Mask for the lower nibble on PORTD to obtain validated code
#define Subs (PORTB) // For portable code, PORTB on Attiny2313
#define DDR_Subs (DDRB) // Data Direction Register for subsystems
#define Phone (PORTD) // For portable code, PortD on Attiny2313
#define DDR_Phone (DDRD) // Data direction register for
#define DTMF ((PIND & CodeMask)) // Decoded DTMF tone input on PortD
#define true 1
#define false 0


Function Prototypes
//

void Reset_CM8870(void); // enable next DTMF tone
int validate(int*); // Compare entered sequence & code return 1 if valid, 0 if invalid
void Lockdown(void); // 3 minute sleeper mode to discourage unauthorized entry
void RESET_uP(void); // Reset the Microprocessor by grounding RST pin through transistor


Main Program

int main()
{
Define I/O
DDR_Subs = 0xFF; // PortB is an OUTPORT for triggering Subsystems
DDR_Phone = 0b01010000; // PortD is an INPORT, Pin D6 is an OUTPUT for reseting the
// DTMF decoder chip
// Pin D4 is an OUTPUT for restting the Tiny2313 uP
Subs = 0x00; // Set PortB = 0; so that no Subsystems will trigger
Phone = 0b01010000; // Set TOE high, set PD4 (RESET Control) high

// Initializations
int CODE[4] = {0,0,0,0}; // holds the bit sequence that is entered by the user
int CODE_digit = 0; // tells what digit in the CODE array is being addressed
int Invalid = 0; // Counts the number of invalid attempts to enter code, if > 3
// enter 3 min lockdown
/
// Wait for valid code signal from STD pin on CM8870
// If STD == 1 decode which button was pressed.
// If invalid code (A,B,C,D, noisy line)
/
DDRB = 0xff; //output
DDRD = 0x00; //input
while(1) // Endless loop, same as "for(;;)"
{
// if(CODE_digit >= 4) // If array pointer is out of bounds Reset it
// { // This will over-write old data.
// CODE_digit = 0;
// }
PORTB = (PIND & 0x0f);
/*
if(STD) // IS there a valid code? IF yes STD == 1
{
if( DTMF == 0x01 ) // was 1 pressed
{
Subs = 0x01;
CODE[CODE_digit] = 0x01; // Store Which digit was entered
CODE_digit += 1; // increment Code_digit
}
else if(DTMF == 0x02) // was 2 pressed
{
Subs = 0x02;
CODE[CODE_digit] = 0x02; // Store Which digit was entered
CODE_digit += 1; // increment Code_digit
}
else if(DTMF == 0x03) // was 3 pressed
{
Subs = 0x03;
CODE[CODE_digit] = 0x03; // Store Which digit was entered
CODE_digit += 1; // increment Code_digit
}
else if(DTMF == 0x04) // was 4 pressed
{
Subs = 0x04;
CODE[CODE_digit] = 0x04; // Store Which digit was entered
CODE_digit += 1; // increment Code_digit
}
else if(DTMF == 0x05) // was 5 pressed
{
Subs = 0x05;
CODE[CODE_digit] = 0x05; // Store Which digit was entered
CODE_digit += 1; // increment Code_digit
}
else if(DTMF == 0x06) // was 6 pressed
{
Subs = 0x06;
CODE[CODE_digit] = 0x06; // Store Which digit was entered
CODE_digit += 1; // increment Code_digit
}
else if(DTMF == 0x07) // was 7 pressed
{
Subs = 0x07;
CODE[CODE_digit] = 0x07; // Store Which digit was entered
CODE_digit += 1; // increment Code_digit
}
else if(DTMF == 0x08) // was 8 pressed
{
Subs = 0x08;
CODE[CODE_digit] = 0x08; // Store Which digit was entered
CODE_digit += 1; // increment Code_digit
}
else if(DTMF == 0x09) // was 9 pressed
{
Subs = 0x09;
CODE[CODE_digit] = 0x09; // Store Which digit was entered
CODE_digit += 1; // increment Code_digit
}
else if(DTMF == 0x0A) // was 0 pressed
{
Subs = 0x0A;
CODE[CODE_digit] = 0x0A; // Store Which digit was entered
CODE_digit += 1; // increment Code_digit
}
else if(DTMF == 0x0B) // was * pressed, if so clear entries
{
Subs = 0x0B;
for(int i = 0; i < 4; i++)
{
CODE[i] = 0x00; // Clear the Contents of CODE
}
CODE_digit = 0; // Reset Code_digit to point at the first block of
// the CODE array
}
else if(DTMF == 0x0C) // was # pressed, If so Check for valid Code
{ // Check to see if the input sequence matches the stored code
for(int i = 0; i < 4 ; i++)
{
Subs = (CODE[i] & 0x0f); // Display each digit for 1
// second Then display the next
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
}
/*if(true == validate(CODE)) // If Code matches call subroutines
{
}
else // Invalid Code record # & enter lockdown if > 3;
{
Invalid += 1; // Increment Invalid

if(Invalid >= 3) // Too Many Invalid Characters entered, { // Enter Lockdown Mode
Lockdown(); // Call the Lockdown Function
}
}
}
else // No valid entry (A,B,C,D or a short occurred,
{ // reset Decoder by toggling TOE)
Reset_CM8870();
} // END if
//Reset_CM8870();
Get next digit
} // END If
*/
} // END While
return(0); // Never reached
}
/
*
*
FUNCTIONS
*
*
/
//
// Function Brings TOE low to reset CM8870 and enable
// the input of new DTMF tones
//
void Reset_CM8870()
{
Phone = !(TOE);
_delay_ms(10);
Phone = (TOE);
}
//
// Function Checks for a valid code entry
// If valid returns 1 else returns 0
//
int validate(int* code)
{
int Cypher[4] = {Bit1, Bit2, Bit3, Bit4};
for(int i=0; i < 4 ; i++) // Look at all bits in the sequence
{
if(code[i] != Cypher[i]) // Sequence entered doesn't match Code
{
return(0); // Invalid Code
}
}
return(1); // Valid Code
}
//
// Function Checks for a valid code entry
// If valid returns 1 else returns 0
//
void Lockdown() // 3 minute sleeper mode to discourage unauthorized entry
{
for(int i = 0; i < 180; i++) // wait 1 second on each loop
{
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
}
RESET_uP(); // Reset the Microprocessor & reinitialize the system
}

// Function Checks for a valid code entry
// If valid returns 1 else returns 0
//
void RESET_uP() // Reset the Microprocessor by grounding RST pin (done by bringing pinD4 low)
{
Subs = 0x00; // Make sure that no subsystems are active
Phone = 0x00; // Reset the microprocessor
for(int i = 0; i < 5; i++) // wait 1 second on each loop
{
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
}
}

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License