📄 acprd_main.c
字号:
//=============================================================================
// File: ACPRD_MAIN.C - V1.00
// Rem.: The ACPRD Project Page on the Web -> http://hc12web.de/acprd
//=============================================================================
//-- Includes -----------------------------------------------------------------
#include <stdio.h>
#include "datatypes.h"
#include "hcs12dp256.h"
#include "s12_atd.h"
#include "s12_crg.h"
#include "s12_eets.h"
#include "s12_sci.h"
#include "s12_spi.h"
#include "s12co_spiio.h"
#include "s12co_led.h"
#include "t6963.h"
#include "display.h"
#include "timedate.h"
#include "acprd_timer.h"
#include "acprd_encoder.h"
#include "acprd_freqout.h"
#include "acprd_song.h"
#include "acprd_keyb.h"
#include "acprd_main.h"
//-- Defines ------------------------------------------------------------------
//-- Static Data --------------------------------------------------------------
//-- software counters --
//
volatile UINT16 cnt0010; // Free Running Counter period = 10ms
volatile UINT16 mdc0030; // Modulus Down Counter period = 30ms
volatile UINT16 mdc0100; // Modulus Down Counter period = 100ms
volatile UINT16 mdc0101; // Modulus Down Counter period = 100ms
volatile UINT16 mdc0200; // Modulus Down Counter period = 200ms
volatile UINT16 mdc1000; // Modulus Down Counter period = 1000ms
//-- hardware shadow registers --
//
UINT8 shadow_spipo; // SPI Parallel Out shadow
UINT8 shadow_spipi; // SPI Parallel In shadow
UINT16 shadow_atd0[ATD_MAX_CHANNELS]; // ATD0 (average) shadow
struct tm *shadow_tm; // pointer to time/date structure
BOOL shadow_tm_disable; // disables update of clock
//-- alarm configuration and status variables --
//
UINT8 al_system_armed; // flag for global "armed" status
#define AL_MAX_LINES 4 // number of Alarm Lines (LINE0 = LIN)
#define AL_EXITDLY_S 30 // time for exit delay
#define AL_STAT_OKAY 0x00 // no alarm (loop resistance within limits)
#define AL_STAT_ALARM 0x01 // normal alarm (switch opened)
#define AL_STAT_TAMPER 0x02 // tamper alarm (loop opened or shorted)
#define AL_STAT_ENTRY 0x04 // alarm, but entry time is still running
#define AL_STAT_SILENT 0x10 // alarm line triggers silent alarm only
UINT8 al_line_status[AL_MAX_LINES]; // current input status of each line
UINT8 al_line_exitdly[AL_MAX_LINES]; // exit delay of each line
UINT8 al_alarm_status[AL_MAX_LINES]; // latched/evaluated status of each line
UINT8 al_system_status; // flag for global "alarm" status
#define AL_LTYP_SILENT 0x01 // alarm line triggers silent alarm only
#define AL_LTYP_DELAY 0x02 // alarm line reacts after a delay
#define AL_LTYP_DISABLE 0x04 // alarm line enabled
UINT8 al_line_type[AL_MAX_LINES]; // behaviour of each line
UINT16 al_delay_time; // delay time (in s) for delayed alarm type
UINT16 al_duration_time; // duration (in s) of audible alarm
BOOL al_blinkled; // blink LED on alarm
BOOL al_buzzer; // sound buzzer on alarm
BOOL al_siren; // sound siren on alarm
BOOL al_flashlight; // flashlight on alarm
//-- misc vars --
//
BOOL acprd_emode; // "Entertainment Mode"
BOOL toggle;
//-- Constants ----------------------------------------------------------------
// user font definition in const UINT8 my_font[];
#include "font1.c"
// user song definition in const UINT16 my_song[];
#include "song1.c"
//#include "song2.c"
//-- Code ---------------------------------------------------------------------
// this function is called by the C-Startup Module
//
void _HC12Setup(void) {
COPCTL = 0; // disable Watchdog
// enable Port Pullups to prevent...
}
//-----------------------------------------------------------------------------
void delay(UINT16 msec) {
UINT16 t;
t = cnt0010 + msec/10;
while(t != cnt0010) ;
}
//-----------------------------------------------------------------------------
void buzz(void) {
UINT8 n;
for(n=0; n<3; n++) {
setFreqOut(5000); // 200Hz
delay(70);
setFreqOut(0);
delay(20);
}
}
//-----------------------------------------------------------------------------
// Background "Task"
// Caution: this func is part of the 10ms interrupt handler!
//
void every10ms(void) {
UINT8 stat;
cnt0010++; // period = 10ms
ENABLE_INTERRUPTS(); // give way to other (more frequent
// or more important) tasks
scanKeyb();
putSPIPO(shadow_spipo);
shadow_spipi = getSPIPI();
if(++mdc0030 == 3) { // period = 30ms
mdc0030 = 0;
handleSong();
handleATD0(shadow_atd0);
}
if(++mdc0100 == 10) { // period = 100ms
mdc0100 = 0;
refreshT6963a(disp_buf);
}
if(++mdc0101 == 10) { // period = 100ms
mdc0101 = 0;
refreshT6963c(disp_buf);
}
if(++mdc0200 == 20) { // period = 200ms
mdc0200 = 0;
stat = checkAlarm();
if(al_system_armed && (stat & AL_STAT_ALARM)) {
al_system_status = stat;
}
else {
al_system_status = AL_STAT_OKAY;
}
if(al_system_status & AL_STAT_ALARM) { // alarm
al_blinkled = TRUE;
toggleLED();
toggle ^= 1;
if(!(stat & AL_STAT_SILENT)) { // audible
al_buzzer = TRUE;
al_siren = TRUE;
al_flashlight = TRUE;
shadow_spipo |= 0x0c;
if(toggle) setFreqOut(5000);
else setFreqOut(3000);
}
}
else { // no alarm
if(al_blinkled == TRUE) {
offLED();
al_blinkled = FALSE;
}
if(al_buzzer == TRUE) {
setFreqOut(0);
al_buzzer = FALSE;
}
if(al_siren == TRUE) {
shadow_spipo &= ~0x08;
al_siren = FALSE;
}
if(al_flashlight == TRUE) {
shadow_spipo &= ~0x04;
al_flashlight = FALSE;
}
if(acprd_emode) toggleLED();
}
}
if(++mdc1000 == 100) { // period = 1000ms
mdc1000 = 0;
if(!shadow_tm_disable)
shadow_tm = gmtime(gettimep());
inctime();
if(al_line_exitdly[0]) al_line_exitdly[0]--;
if(al_line_exitdly[1]) al_line_exitdly[1]--;
if(al_line_exitdly[2]) al_line_exitdly[2]--;
if(al_line_exitdly[3]) al_line_exitdly[3]--;
}
}
//-----------------------------------------------------------------------------
void initACPRD(void) {
UINT8 n, k;
initLED();
initPLL();
initEETS();
initTimer(every10ms);
initSCI0(BAUD_19K2_24000);
initSCI1(BAUD_9600_24000);
initSPI0(SPIBD_500K_24000, 0, 0);
initATD0();
initSPIIO();
initT6963(my_font);
initDisp();
initKeyb();
initEncoder();
initFreqOut();
initSong();
// all static vars are set to 0 in C-startup module, so
// only vars with a default value != 0 will be handled here
//
systime = 0x386d4380L - 10L; // 10sec before 00:00:00 2000/01/01
mdc0100 = 1;
mdc1000 = 99;
shadow_spipo = 0x01;
startATD0();
for(n=0; n<20; n++) { // fill average buffers
k = 0;
while(++k) ;
handleATD0(shadow_atd0);
}
}
//-----------------------------------------------------------------------------
void armLines(void) {
UINT8 n = 0;
do {
if(al_line_type[n] & AL_LTYP_DELAY) al_line_exitdly[n] = AL_EXITDLY_S;
n++;
} while(n < AL_MAX_LINES);
}
//-----------------------------------------------------------------------------
void resetLines(void) {
al_alarm_status[0] = AL_STAT_OKAY;
al_alarm_status[1] = AL_STAT_OKAY;
al_alarm_status[2] = AL_STAT_OKAY;
al_alarm_status[3] = AL_STAT_OKAY;
al_system_status = AL_STAT_OKAY;
}
//-----------------------------------------------------------------------------
UINT8 checkAlarm(void) {
UINT8 n, stat;
UINT16 v;
// get line status
for(n=0; n<AL_MAX_LINES; n++) {
v = shadow_atd0[n+1];
if(v < 0x0b00) stat = AL_STAT_TAMPER;
else if(v < 0x0e00) stat = AL_STAT_OKAY;
else if(v < 0x1a00) stat = AL_STAT_ALARM;
else stat = AL_STAT_TAMPER;
al_line_status[n] = stat;
}
// line status -> alarm status
for(n=0; n<AL_MAX_LINES; n++) {
if((al_line_type[n] & AL_LTYP_DISABLE) == 0) {
stat = al_line_status[n];
// alarm not valid if exit delay running
if(al_line_exitdly[n]) stat &= ~AL_STAT_ALARM;
if((stat & AL_STAT_ALARM) || (stat & AL_STAT_TAMPER)) {
if(al_line_type[n] & AL_LTYP_SILENT) stat = AL_STAT_SILENT;
al_alarm_status[n] = stat | AL_STAT_ALARM;
}
}
}
// alarm status -> system status
for(n=0; n<AL_MAX_LINES; n++) {
stat = al_alarm_status[n];
if(stat & AL_STAT_ALARM) return stat;
}
return AL_STAT_OKAY;
}
//-----------------------------------------------------------------------------
// retrieve Alarm Line Configuration from EEPROM
//
void getLineConfig(void) {
struct { UINT8 x0, x1, x2, x3; } item;
readItemEETS(0, &item);
al_line_type[0] = ~item.x0;
al_line_type[1] = ~item.x1;
al_line_type[2] = ~item.x2;
al_line_type[3] = ~item.x3;
}
//-----------------------------------------------------------------------------
// save Alarm Line Configuration to EEPROM
//
void saveLineConfig(void) {
struct { UINT8 x0, x1, x2, x3; } item;
item.x0 = ~al_line_type[0];
item.x1 = ~al_line_type[1];
item.x2 = ~al_line_type[2];
item.x3 = ~al_line_type[3];
writeItemEETS(0, &item);
}
//-----------------------------------------------------------------------------
// subroutines for the handling of display objects
#include "acprd_dobj.c"
//-----------------------------------------------------------------------------
void setTimDat(void) {
INT8 item, i;
time_t newtime;
const UINT8 *sav0 = dobj_keys_label[0];
const UINT8 *sav1 = dobj_keys_label[1];
const UINT8 *sav2 = dobj_keys_label[2];
const UINT8 *sav3 = dobj_keys_label[3];
dobj_keys_label[0] = key_empty;
dobj_keys_label[1] = key_empty;
dobj_keys_label[2] = key_empty;
dobj_keys_label[3] = key_empty;
drawAll();
shadow_tm_disable = TRUE; // disable clock update
item = 0;
do {
if(hasEncoder()) {
i = (getEncoder() < 0) ? -1 : 1;
switch(item) {
case 0:
shadow_tm->tm_hour += i;
if(shadow_tm->tm_hour == 24) shadow_tm->tm_hour = 0;
else if(shadow_tm->tm_hour > 24) shadow_tm->tm_hour = 23;
break;
case 1:
shadow_tm->tm_min += i;
if(shadow_tm->tm_min == 60) shadow_tm->tm_min = 0;
else if(shadow_tm->tm_min > 60) shadow_tm->tm_min = 59;
break;
case 2:
shadow_tm->tm_sec += i;
if(shadow_tm->tm_sec == 60) shadow_tm->tm_sec = 0;
else if(shadow_tm->tm_sec > 60) shadow_tm->tm_sec = 59;
break;
case 3:
shadow_tm->tm_year += i;
if(shadow_tm->tm_year > 199) shadow_tm->tm_year = 199;
else if(shadow_tm->tm_year < 70) shadow_tm->tm_year = 70;
break;
case 4:
shadow_tm->tm_mon += i;
if(shadow_tm->tm_mon == 12) shadow_tm->tm_mon = 0;
else if(shadow_tm->tm_mon > 12) shadow_tm->tm_mon = 11;
break;
case 5:
shadow_tm->tm_mday += i;
if(shadow_tm->tm_mday == 32) shadow_tm->tm_mday = 1;
else if(shadow_tm->tm_mday < 1) shadow_tm->tm_mday = 31;
break;
default:
break;
}
}
if(hasKeyb()) {
if(getKeyb() == KEYB_KC5) {
item++;
if(item == 6) item = -1;
}
}
dobj_timedate_sel = item;
drawAll();
} while(item != -1);
newtime = mktime(shadow_tm); // convert struct to seconds
stime(&newtime); // set systime accordingly
shadow_tm_disable = FALSE; // allow clock updates
dobj_keys_label[0] = sav0;
dobj_keys_label[1] = sav1;
dobj_keys_label[2] = sav2;
dobj_keys_label[3] = sav3;
}
//-----------------------------------------------------------------------------
void setupLines(void) {
INT8 item;
UINT8 k, x;
const UINT8 *sav0 = dobj_keys_label[0];
const UINT8 *sav1 = dobj_keys_label[1];
const UINT8 *sav2 = dobj_keys_label[2];
const UINT8 *sav3 = dobj_keys_label[3];
dobj_keys_label[0] = key_line1;
dobj_keys_label[1] = key_line2;
dobj_keys_label[2] = key_line3;
dobj_keys_label[3] = key_line4;
item = 0;
do {
if(hasEncoder()) {
if(getEncoder() < 0) {
x = (al_line_type[item] - 1) & 0x07;
if(x == 7) x = 5;
else if(x == 4) x = 3;
}
else {
x = (al_line_type[item] + 1) & 0x07;
if(x == 4) x = 5;
else if(x == 6) x = 0;
}
al_line_type[item] = x;
}
if(hasKeyb()) {
k = getKeyb();
switch(k) {
case KEYB_KC1:
case KEYB_KC2:
case KEYB_KC3:
case KEYB_KC4:
item = k-1;
break;
case KEYB_KC5:
item++;
if(item == 4) item = -1;
break;
default:
break;
}
}
dobj_asl_sel = item;
drawAll();
} while(item != -1);
saveLineConfig();
dobj_keys_label[0] = sav0;
dobj_keys_label[1] = sav1;
dobj_keys_label[2] = sav2;
dobj_keys_label[3] = sav3;
}
//-----------------------------------------------------------------------------
void doMenu(UINT8 k) {
INT8 sel;
switch(k) {
case KEYB_KC2: // UP
dobj_jogmenu_sel -= 1;
if(dobj_jogmenu_sel < 0) dobj_jogmenu_sel = 0;
break;
case KEYB_KC3: // DOWN
dobj_jogmenu_sel += 1;
if(dobj_jogmenu_sel > 5) dobj_jogmenu_sel = 5;
break;
case KEYB_KC1: // ARM
dobj_jogmenu_sel = 0;
drawAll();
case KEYB_KC4: // ENT
case KEYB_KC5:
gotoxyDisp(28, dobj_jogmenu_y+dobj_jogmenu_sel);
prDispMult(11, TA_NORMAL);
delay(200);
gotoxyDisp(28, dobj_jogmenu_y+dobj_jogmenu_sel);
prDispMult(11, TA_REVERS);
delay(200);
if(al_system_armed && (dobj_jogmenu_sel != 0)) {
buzz();
return;
}
sel = dobj_jogmenu_sel;
dobj_jogmenu_sel = -1;
switch(sel) {
case 0: // Arm/Disable
//in a real system, ask for PIN code before disable
al_system_armed ^= 1;
if(al_system_armed) armLines();
break;
case 1: // Reset Lines
resetLines();
break;
case 2: // Setup Lines
setupLines();
break;
case 3: // Set Tim/Dat
setTimDat();
break;
case 4: // Remote Ctrl
//### TBD
buzz();
break;
case 5: // EntertainMe
if(acprd_emode == FALSE) {
acprd_emode = TRUE;
startSong(my_song);
shadow_spipo |= 0xf8;
}
else {
acprd_emode = FALSE;
startSong(NULL);
shadow_spipo &= ~0xf8;
offLED();
}
break;
default:
break;
}
getEncoder(); // flush
flushKeyb(); // flush
dobj_jogmenu_sel = sel;
break;
default:
break;
}
}
//-----------------------------------------------------------------------------
void main(void) {
UINT8 k;
initACPRD(); // initialize system
ENABLE_INTERRUPTS(); // global interrupt enable
getLineConfig(); // read Alarm Line Config from EEPROM
drawInit(); // initialize display objects
while(1) {
drawAll();
k = 0;
if(hasEncoder()) k = (getEncoder() < 0) ? KEYB_KC3 : KEYB_KC2;
else if(hasKeyb()) k = getKeyb();
if(k) doMenu(k);
}
}
//=============================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -