⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 TDK 6521 SOC 芯片 DEMO程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************
 * 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 + -