?? main.c
字號:
/***************************************************************************
* This code and information is provided "as is" without warranty of any *
* kind, either expressed or implied, including but not limited to the *
* implied warranties of merchantability and/or fitness for a particular *
* purpose. *
* *
* Copyright (C) 2005 Teridian Semiconductor Corp. All Rights Reserved. *
***************************************************************************/
//**************************************************************************
// DESCRIPTION: 71M652x POWER METER - Main.
//
// AUTHOR: MTF/RGV
//
// HISTORY: See end of file.
//**************************************************************************
// File: MAIN.C
//
#include "options.h" // compile flags and system constants
#include "irq.h" // interrupt disabling logic
#include "library.h" // data copying functions
#include "batmodes.h" // battery mode logic
#include "wd.h" // software watchdogs
#include "stm.h" // software timers
#include "error.h" // error recording
#include "ce.h" // compute engine hardware access
#if SERIAL0
#include "ser0.h" // uart 0 hardware access
#endif
#if SERIAL1
#include "ser1.h" // uart 1 hardware access
#endif
#include "rtc.h" // real time clock hardware access
#include "lcd.h" // liquid crystal display
#include "meter.h" // meter logic
#include "defaults.h" // default data tables
#include "pcnt.h" // meter pulse counting (normally disabled)
#include "psoft.h" // meter software pulse outputs (normally disabled)
#include "calibration.h" // meter calibration logic
#include "cal_ldr.h" // calibration loader protocol
#include "flag0.h" // FLAG protocol(s)
#include "flag1.h"
#include "cli.h" // command line interface- parsing commands
#include "io.h" // command line interface- io routines
#include "ser0cli.h" // queued serial buffering for uart 0
#include "ser1cli.h" // queued serial buffering for uart 1
#include "sercli.h" // shared tables and logic for serial
#include "delay.h" // shared delay loop
//#include "oscope.h" // scope loop debugging code
#include "main.h" // Test the interface in main.h vs. main.c
/*** Public variables declared within this module ***/
// None.
/*** Private functions declared within this module ***/
void main_init (void);
void main_run (void);
/*** Private variables declared within this module ***/
// None.
#if BROWNOUT_BATMODE || CLI || M6520
// This routine is called when you want to "fake" a power on reset w/o really doing one.
// It sets all the I/O registers to their power-on state,
// and ensures that any pending interrupts are cleared.
//
// Inputs: None.
//
// Outputs: None.
//
static void null_int (void) interrupt 31
{ // '31' is a dummy interrupt,..
} // ..it forces 'RET' compiled into a 'RETI'.
#pragma save
#pragma NOAREGS
void main_soft_reset (void) small reentrant
{
IE = 0; // Turn ALL interrupts OFF.
#if HARD_RESET_USABLE
// assumes that the hard reset is a wire from DIO_8 to RESET.
USER1 =0xFF; // DIO_8 is bit 0 of port 1
DIR1 = 0x01; // set DIO_8 as an output; should reset right here
for(px = 10; px > 0; --px)
{
USER1 += 1; // but just in case, toggle the bit for awhile
}
#endif
// so, if it falls through? Do a soft reset anyway.
#if M6520
// Interrupt enable registers
IEN0 = 0;
IEN1 = 0;
IEN2 = 0;
memset_x ((uint8x_t *)0x2000, 0, 0x80); // 2000..207F
*(uint8x_t *)0x2080 = 0xff; // PLS_WIDTH
memset_x ((uint8x_t *)0x2081, 0, 0x27); // 2081..20A7
*(uint8x_t *)0x20A8 = 31; // CE_LCTN
*(uint8x_t *)0x20A9 = 1; // WAKE_PRD
*(uint8x_t *)0x20AA = 0x02; // TMUX; the hardware's default
memset_x ((uint8x_t *)0x20AB, 0, 0x54); // 20AB..20FF
// Initialize all 652x specific internal SFRs.
DIR0 = 0; // init direction first
USER0 = 0xFF;
DIR1 = 0;
USER1 = 0xFF;
DIR2 = 0;
USER2 = 0x00;
P3 = 0xFF;
EEDATA = 0;
EECTRL = 0;
FCTRL = 0x00; // Init FLASH SFRs.
FPAGE = 0x00;
ERASE = 0x00;
// Initialize remaining standard 80515 SFRs.
// Interrupt priority registers
IP = 0;
IP1 = 0;
// Peripheral control and interrupt registers
CKCON = 1;
PCON = 0;
TCON = 0;
T2CON = 0;
TMOD = 0;
SCON = 0;
S1CON = 0;
WDCON = 0;
// Interrupt registers
IRCON = 0;
DPL1 = 0; // Initialize all standard 80515 SFRs.
DPH1 = 0;
WDTREL = 0;
TH0 = 0;
TL0 = 0;
TH1 = 0;
TL1 = 0;
DPS = 0;
S1RELL = 0;
S0RELL = 0xD9;
S0RELH = 3;
S1RELH = 3;
PSW = 0;
((void (code *) (void)) null_int) (); // Clear 1st priority level.
((void (code *) (void)) null_int) (); // Clear 2nd priority level.
((void (code *) (void)) null_int) (); // Clear 3rd priority level.
((void (code *) (void)) null_int) (); // Clear 4th priority level.
B = 0;
DPH = 0;
DPL = 0;
SP = 5; // two less than default 7; call below, will fix this
PSW = 0;
ACC = 0;
((void (code *) (void)) 0x0000) (); // Jump to 0x0000.
#elif TRACE10
//defaults for IO
// Disable interrupts
IEN0 = 0;
IEN1 = 0;
IEN2 = 0;
// initialize the IO ram
memset_x ((uint8x_t *)0x2000, 0, 0x100); // 2000..20FF
// Initialize all specific internal SFRs.
DIR0 = 0; // init direction first
USER0 = 0xFF; // P0
DIR1 = 0;
USER1 = 0xFF;
DIR2 = 0;
USER2 = 0x00;
P3 = 0xFF;
EEDATA = 0;
EECTRL = 0;
FCTRL = 0x00; // Init FLASH SFRs.
FPAGE = 0x00;
ERASE = 0x00;
// Initialize remaining standard 80515 SFRs.
// Interrupt priority registers
IPH = 0;
IPL = 0;
// initialize the control and interrupt registers
CKCON = 1;
PCON = 0;
TCON = 0;
T2CON = 0;
TMOD = 0;
SCON = 0;
S1CON = 0;
WDCON = 0;
// Other interrupt registers
IRCON = 0;
DPL1 = 0; // Initialize all standard 80515 SFRs.
DPH1 = 0;
WDTREL = 0;
TH0 = 0;
TL0 = 0;
TH1 = 0;
TL1 = 0;
DPS = 0;
S1RELL = 0;
S0RELL = 0xD9;
S0RELH = 3;
S1RELH = 3;
PSW = 0;
((void (code *) (void)) null_int) (); // Clear 1st priority level.
((void (code *) (void)) null_int) (); // Clear 2nd priority level.
((void (code *) (void)) null_int) (); // Clear 3rd priority level.
((void (code *) (void)) null_int) (); // Clear 4th priority level.
B = 0;
DPH = 0;
DPL = 0;
SP = 5; // two less than default 7; call below, will fix this
PSW = 0;
ACC = 0;
((void (code *) (void)) 0x0000) (); // Jump to 0x0000.
#else
#error unhandled device type
#endif
}
#pragma restore
#endif // battery modes are defined
//===========================================================================//
static void default_setup(void)
{
set_defaults (); // Set most default values.
#if LCD_ACTIVE
LCD_Hello (); // LCD reads 'HELLO'.
#endif
RESET_WD(); // Reset watchdog.
#if BROWNOUT_BATMODE
if ( !batmode_is_brownout() ) // eeprom reads are slow
{
#endif
meter_initialize (); // prepare the power meter logic
#if PULSE_CNT
pcnt_init (); // prepare to count pulses
#endif
#if BROWNOUT_BATMODE
}
#endif
CE2 |= EX_RTC; // The 1 second interrupt always runs
// clear both flags at once, forcing an edge to cause interrupt 6
// If this is not done, the unit can deadlock at reset.
IFLAGS = ~(IE_XFER_ | IE_RTC_);
if (0 != cal_i0) // if the compute engine is set-up
CE_ENABLE(); // start the compute engine
#ifdef OSCOPE_H
OSCOPE_INIT;
#endif
}
//===========================================================================//
static void main_init (void)
{
// system interrupt priorities are assembled in main\options_gbl.h
// Interrupt priorities are best set one place, before any interrupts
// should be possible.
IPH = SYSTEM_PRIORITY >> 8; // set interrupt priorities.
IPL = SYSTEM_PRIORITY & 0xFF;
irq_init (); // initialize the interrupt disable logic
#if TIMERS
stm_init (); // initalize the software timers
#endif
#if BROWNOUT_BATMODE || LCD_BATMODE || SLEEP_BATMODE
batmode_init (); // initialize the battery mode management
#endif
// Initializes most I/O functions that control the hardware.
#if WATCHDOG
wd_destroy (WD_ALL); // Delete all the software watchdogs.
#endif
#ifdef WD_MAIN_LOOP
wd_create (WD_MAIN_LOOP); // Add a software watchdog
#endif
default_setup(); // standard set up; reads power regs.
irq_enable (); // enable interrupts
#if CAL_SAVE
#if BROWNOUT_BATMODE
if ( !batmode_is_brownout () ) // no need for calibration, etc.
{
#endif
if (0 == cal_restore()) // Restore saved calibration.
{ // if it failed
irq_disable ();
Status |= CAL_BAD;
default_setup ();
irq_enable (); // enable interrupts
}
#if AUTOCAL | (!CLI && CAL_LDR)
// Self-calibrate or call the calibration loader
// On the 6511 and 6513, hold sw2 on the debug PCB and press reset.
// On the 6520, hold the push button and push reset.
// if the CLI is in, access the cal loader via its CLI command: CLC
// The cal loader ignores the CLC if invoked here.
if (BUTTON_PRESSED /* && add an anti-tampering test here */ )
{
// If needed, calibration loader first to give more control
// in a manufacturing cycle. It can set changed defaults,
// etc. After autocalibration and a reset, the calibration loader
// can read or modify the meter's cal. data.
// With auto. test equip., the cal. loader can read registers,
// so the ATE can can calculate and set calibrations.
// #if CAL_LDR
// cal_ldr ();
// #endif
#if AUTOCAL
cal_begin();
#endif
// The operation does not proceed until the button is released.
while (BUTTON_PRESSED) // wait for the jumper to be removed
{
RESET_WD(); // Reset watchdog.
delay_clks (3); // Delay before next time.
}
}
#endif
#if BROWNOUT_BATMODE
} // if not brownout mode
#endif
#endif // Calibration.
#if REAL_TIME_DATE
RTClk_Reset (); // Reset RTC to defaults, if necessary.
#endif
#if ERROR_RECORDING
Error_Init (); // Initialize error recording
#endif
#if CLI
send_crlf ();
send_copyright ();
send_a_result (OK_ID);
#endif
} // Start CE_BUSYZ, XFER_BUSYZ & RTC interrupts.
// guts of the main loop
static void main_run (void)
{
main_background ();
#if CLI
// This is the command line interface.
if (cmd_pending ()) cli();
#elif CAL_LDR
// The calibration loader is run here in order to read and
// write during operation, to better demonstrate chip operation.
// For a production meter, it makes more sense to run the
// calibration loader optionally, just after reset. See above.
// The calibration loader can be invoked from the CLI using "CLC"
if (cmd_pending ()) cal_ldr ();
#endif
// execute a subroutine on behalf of the flag logic
#if FLAG0
flag0_run (); // run flag0
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -