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

📄 stm.c

📁 TDK 6521 SOC 芯片 DEMO程序
💻 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 - software timers
//  This multiplexes a hardware timer to make many software timers.
//  The interface is made to be like that of the hardware timers.
//  Derived from timers.c by MTF; the algorithms are the same.
//  However, the hardware timer interface is factored out, and
//  the data and routines are named by data types.
//  There's also an "auto restart" option so a software timer can run
//  indefinitely.
//
//  AUTHOR:  RGV, MTF
//
//  HISTORY: See end of file
//
//**************************************************************************
//
//  File: STM.C
//
#include "options.h"
#if TIMERS
#include "irq.h"   // interrupt disable logic
#include "tmr0.h"  // it should also work with tmr1, unchanged
#include "stm.h"

#define STM_COUNT 8                    // count of software timer structures.

/*** Private variables declared within this module ***/
static uint8_t tick_count;

uint16_t tick_counts[ STM_COUNT ];
uint16_t restart_tick_counts[ STM_COUNT ];
void (*fn_ptrs[ STM_COUNT ]) (void);

// wait for a count of ticks, using a software timer
#if EXTRAS  || SERIAL0_CLI || SERIAL1_CLI
void stm_wait (uint16_t tick_count)
{
   STM stm;
                                        
   stm = stm_start (tick_count, FALSE, NULL);

   if (stm != NULL) // don't hang
   {
       while ( stm_running(stm) )            // Wait 'tick_count' ticks.
           stm_run ();                   // run the software timers
   }
}
#endif

#pragma save
#pragma NOAREGS
// this is the software timer's interrupt code
// Just setting a flag tends to run slow because of
// counts lost when stm-run is not called promptly.
void stm_int(void) small reentrant
{
   tick_count += 1;  // it does almost nothing; a low real-time burden!
}

#pragma restore

// Start a software timer.
// This has arguments very like the hardware timer functions
// to leverage the experience.
#pragma save
#pragma NOAREGS
uint16x_t *stm_start (uint16_t tick_count, uint8_t restart, void (*fn_ptr) (void)) small reentrant
{
    IRQ_DEFINES;
    uint8_t stm_index;
    uint16_t stm_tick_count;

    // search for an empty software timer structure
    for (stm_index = 0; stm_index < STM_COUNT; ++stm_index)
    {
        stm_tick_count = tick_counts[stm_index]; 
        IRQ_DISABLE();  // start critical region
        if (0 == stm_tick_count) 
        { // found a free software timer structure
            tick_counts[stm_index] = tick_count;  // Set timer structure values.
            IRQ_ENABLE(); // end critical region
            if (restart == 0)
                restart_tick_counts[stm_index] = 0; // no restart
            else
                restart_tick_counts[stm_index] = tick_count; // set the restart value
            fn_ptrs[ stm_index ] = fn_ptr;

            // If there are no software timers, the hardware timer
            // is stopped to save power.  This restarts it.
            if (!tmr_running()) // from the timer hardware abstraction layer
            {
                // run every ten milliseconds
                tmr_start(milliseconds2tmr_reg(10), TRUE, stm_int);
            }
            return (&(tick_counts[stm_index]));
        }
        else
        {
            IRQ_ENABLE(); // end critical region
        }
    }

    return (NULL);
}
#pragma restore

// stop and deallocate a software timer.
// This has arguments very like the hardware timer functions
#pragma save
#pragma NOAREGS
void stm_stop (STM stm_ptr) small reentrant
{                    // 'stm_ptr' is value returned by 'stm_start'.
   if (stm_ptr)
      *stm_ptr = 0; // it's now removed.
}
#pragma restore

// run the timer system- this should be called from a main loop
void stm_run (void)
{
    uint8_t stm_index, my_tick_count;

    if (tick_count != 0) // did the timer interrupt occur?
    {
        bool running = FALSE;

        irq_disable();  // begin critical section; disable timer's interrupt
        my_tick_count = tick_count; // get the interrupt's tick count
        tick_count = 0;
        irq_enable();  // end critical section; enable timer's interrupt

        for (stm_index = 0; stm_index < STM_COUNT; ++stm_index)
        {
            uint16_t tmp;

            tmp = tick_counts[stm_index];
            if (tmp)  // if the timer is running
            {
                running = TRUE;
                if (my_tick_count < tmp) // Timer expired?
                {
                    // no, count timer down.
                    tick_counts[stm_index] = tmp - my_tick_count;
                } 
                else 
                {
                    // The tick_count has expired.
                    // Restart or halt the software timer
                    // This is before the expire function, so the function
                    // can get another timer, or whatever
                    tick_counts[stm_index] = restart_tick_counts[stm_index];

                    if (fn_ptrs[stm_index])        // if there's an expire function.
                        (*(fn_ptrs[stm_index])) (); // call it

                }   
            }
        }

        // If there aren't any active software timers,
        // stop the hardware timer to save power.
        if (!running)        // if there are no active software timers
        {                    // Stop the hardware timer to save power.
            tmr_stop();
        }   
    }
}

// initialize the software timers
void stm_init(void)
{
    uint16_t istm;

    for (istm = 0; istm < STM_COUNT; ++istm)
        stm_stop ( &tick_counts[ istm ] );
}

#endif

/***************************************************************************
 * History:
 * $Log: stm.c,v $
 * Revision 1.26  2006/09/09 01:16:02  gmikef
 * *** empty log message ***
 *
 * Revision 1.25  2006/06/09 01:08:43  tvander
 * P. Bui discovered an issue that could cause a hang.  Fixed it.
 * Discovered (By inspection) a new reentrancy defect, and fixed it.
 *
 * Revision 1.24  2006/04/13 17:58:50  tvander
 * Updated stm.c to circumvent compiler bug and reduce size, unit-tested.
 *
 * Revision 1.23  2006/03/08 00:10:54  tvander
 * Clean build
 *
 * Revision 1.22  2006/03/06 03:42:56  Michael T. Fischer
 * More 6530 prep.
 *
 * Revision 1.21  2006/02/08 03:43:27  tvander
 * Made "import" the default power measurement mode, rather than net-metering
 *
 * Revision 1.20  2006/01/10 04:13:56  gmikef
 * Added PDATA support for CE Outputs.
 *
 * Revision 1.18  2005/12/21 01:37:10  tvander
 * 6513
 *
 * Revision 1.17  2005/10/28 02:23:56  gmikef
 * *** empty log message ***
 *
 * Revision 1.16  2005/10/15 00:20:30  tvander
 * Moved GUI into FLAG
 * Modified STM.C in util to use main interrupt-disable flag
 *
 * Revision 1.15  2005/09/22 23:45:30  tvander
 * Clean build all models and unit tests, updated copyright to be fore Teridian
 *
 * Revision 1.14  2005/09/11 00:34:09  tvander
 * Clean compiles
 *
 * Revision 1.13  2005/08/30 18:23:34  gmikef
 * *** empty log message ***
 *
 * Revision 1.12  2005/08/23 02:13:17  gmikef
 * *** empty log message ***
 *
 * Revision 1.11  2005/08/09 18:58:26  tvander
 * typo
 *
 * Revision 1.10  2005/08/09 18:51:06  tvander
 * Incorporated Mike Fischer's (MTF) improvement to the 6515 software timer system,
 * that disables only the timer interrupt, not everything.
 *
 * Revision 1.9  2005/07/01 00:43:56  tvander
 * Reduced the use of idata.
 *
 * Revision 1.8  2005/05/26 21:54:39  tvander
 * Flag is grossly working with GUI: signs on, reads, writes both xdata and idata, interlocks with CE cycle, and timeouts work.
 *
 * Revision 1.7  2005/05/13 00:34:49  tvander
 * 6511/32k works
 * Integrated and debugged self-calibration.
 * The build has one unused segment, and no other errors or warnings.
 * default LCD and pulse displays appear OK.
 * EEPROM, software timers and hardware timers are all integrated.
 *
 * Revision 1.6  2005/05/03 00:39:48  tvander
 * Incorporated event reporting in tmr0,tmr1 and unit tests.
 * Retested stm, trm0, tmr1.
 * Incorporated untested changes in io651x.h
 *
 * Revision 1.5  2005/04/30 02:21:10  gmikef
 * *** empty log message ***
 *
 * Revision 1.5  2005/04/27 21:38:19  gmikef
 * *** empty log message ***
 *
 * Revision 1.3  2005/04/26 17:48:07  tvander
 * Successful test of software timers.
 *
 * Revision 1.2  2005/04/21 02:09:43  gmikef
 * *** empty log message ***
 *
 *
 * Revision 1.1  2005/03/23 19:18:12  tvander
 * *** empty log message ***
 *
 * Revision 1.4  2005/03/08 19:06:53  tvander
 * Self calibration in all software models
 *
 * Revision 1.2  2005/02/17 18:32:40  tvander
 * Added automatic check-in logging to all source code.
 *
 * Copyright (C) 2005 Teridian Semiconductor Corp. All Rights Reserved.    *
 * this program is fully protected by the United States copyright          *
 * laws and is the property of Teridian Semiconductor Corporation.         *
 ***************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -