📄 tmtimers.c
字号:
/*
* Copyright (c) 1995,2000 TriMedia Technologies Inc.
*
* +------------------------------------------------------------------+
* | This software is furnished under a license and may only be used |
* | and copied in accordance with the terms and conditions of such |
* | a license and with the inclusion of this copyright notice. This |
* | software or any other copies of this software may not be provided|
* | or otherwise made available to any other person. The ownership |
* | and title of this software is not transferred. |
* | |
* | The information in this software is subject to change without |
* | any prior notice and should not be construed as a commitment by |
* | TriMedia Technologies. |
* | |
* | this code and information is provided "as is" without any |
* | warranty of any kind, either expressed or implied, including but |
* | not limited to the implied warranties of merchantability and/or |
* | fitness for any particular purpose. |
* +------------------------------------------------------------------+
*
* Module name : tmTimers.c 1.41
*
* Last update : 11:01:09 - 00/06/20
*
* Description :
* Trimedia Timers library.
*
* This header forms interface to the TM-1000 timers.
* Timers can be obtained by calling the timOpen function,
* which returns an arbitrary available timer (if any), and
* marks it as unavailable for subsequent calls to timOpen
* until it is given back to this library by a call to timClose.
*
* Opened timers can be setup to relatively constant settings,
* which are modulus, prescale, source and optional interrupt
* handler with interrupt priority. When no interrupt handler
* is required a null handler can be provided, otherwise the
* handler will be automatically installed usint the tmInterrupt
* library. Conversely, interrupt handlers will be automatically
* uninstalled for timers which are closed.
*
* The setup function can be repeatedly used to modify
* one or more of the timer's parameters; any changes
* will be correctly effectuated. When only a few of the
* parameters are to be changed, usually a call to the GetSetup
* function is necessary to get the current value of the
* other parameters.
*
* After the timer has been set up, the action functions
* for getting or setting the value, or for starting/stopping
* it can be called for 'operating' the timer.
*
* Revision :
*
*
*/
/*----------------------------- includes ------------------------------------*/
#include <tm1/tmTimersmmio.h>
#include <tm1/tmTimers.h>
#include <tm1/tmAssert.h>
#include <tm1/tmLibdevErr.h>
#include <tm1/tmProcessor.h>
#include <tm1/tmLibdevErr.h>
#include <limits.h>
#include "ops/custom_ops.h"
/*------------------------- local definitions -------------------------------*/
#define NROF_TIMERS 4
#define WORDSIZE sizeof(Pointer)
#define INTERRUPT_OF(instance) ((intInterrupt_t)(5+(instance)))
#define ALLOCATE(instance) (allocated |= (1<<(instance)))
#define DEALLOCATE(instance) (allocated &= ~(1<<(instance)))
#define IS_ALLOCATED(instance) ( ((instance) >=0 ) \
&& ((instance) < NROF_TIMERS ) \
&& (allocated & (1<<(instance))) \
)
#define NANOSECS_PER_SECOND 1000000000U
#define UINT32_MAX ((UInt32)UINT_MAX)
static timCapabilities_t capabilities =
{
/* version */ {MAJOR_VERSION, MINOR_VERSION, BUILD_VERSION},
/* numSupportedInstances */ NROF_TIMERS,
/* numCurrentInstances */ 0
};
static UInt allocated;
static timInstanceSetup_t timer_info[NROF_TIMERS];
/*--------------------- capability/parameter functions ----------------------*/
/*
* Function : Retrieve global capabilities.
* Parameters : cap (O) returned pointer to
* internal capabilities structure
* Function Result : resulting error condition
*/
extern tmLibdevErr_t
timGetCapabilities(ptimCapabilities_t * cap)
{
tmAssert(cap != Null, TMLIBDEV_ERR_NULL_PARAMETER);
*cap = &capabilities;
return TMLIBDEV_OK;
}
/*
* Function : Retrieve instance capabilities.
* Parameters : instance (I) instance to get capabilities from
* cap (O) pointer to buffer receiving
* returned capabilities
* Function Result : resulting error condition
*/
extern tmLibdevErr_t
timGetInstanceCapabilities(
Int instance,
timInstanceCapabilities_t * cap)
{
tmAssert(cap != Null, TMLIBDEV_ERR_NULL_PARAMETER);
tmAssert(IS_ALLOCATED(instance), TMLIBDEV_ERR_NOT_OWNER);
tmAssert(sizeof (*cap) == 1 * WORDSIZE, TIM_ERR_STRUCT_CHANGED);
cap->interrupt = INTERRUPT_OF(instance);
return TMLIBDEV_OK;
}
/*
* Function : Set/change instance parameters.
* Parameters : instance (I) instance to set parameters for
* setup (I) pointer to buffer
* holding new parameters
* Function Result : resulting error condition
*/
extern tmLibdevErr_t
timInstanceSetup(
Int instance,
timInstanceSetup_t * setup)
{
UInt ien;
tmAssert(setup != Null, TMLIBDEV_ERR_NULL_PARAMETER);
tmAssert(IS_ALLOCATED(instance), TMLIBDEV_ERR_NOT_OWNER);
if (!IS_ALLOCATED(instance))
return TMLIBDEV_ERR_NOT_OWNER;
ien = intCLEAR_IEN();
{
timDisableRUN(instance);
if (setup->handler != timer_info[instance].handler
|| setup->priority != timer_info[instance].priority) {
intInstanceSetup_t int_setup;
tmAssert(sizeof (int_setup) == 4 * WORDSIZE, TIM_ERR_STRUCT_CHANGED);
int_setup.handler = setup->handler;
int_setup.priority = setup->priority;
int_setup.level_triggered = False;
int_setup.enabled = True;
intInstanceSetup(INTERRUPT_OF(instance), &int_setup);
}
timSetMODULUS (instance, setup->modulus);
timSetSOURCE (instance, setup->source);
timSetPRESCALE (instance, setup->prescale);
if (setup->running) {
timEnableRUN(instance);
}
else {
timDisableRUN(instance);
}
timer_info[instance] = *setup;
}
intRESTORE_IEN(ien);
return TMLIBDEV_OK;
}
/*
* Function : Retrieve instance parameters.
* Parameters : instance (I) instance to get parameters from
* setup (O) pointer to buffer
* receiving returned parameters
* Function Result : resulting error condition
*/
extern tmLibdevErr_t
timGetInstanceSetup(
Int instance,
timInstanceSetup_t * setup)
{
UInt ien;
tmAssert(setup != Null, TMLIBDEV_ERR_NULL_PARAMETER);
tmAssert(IS_ALLOCATED(instance), TMLIBDEV_ERR_NOT_OWNER);
ien = intCLEAR_IEN();
{
*setup = timer_info[instance];
}
intRESTORE_IEN(ien);
return TMLIBDEV_OK;
}
/*--------------------- open/close functions ---------------------------------*/
/*
* Function : Assigns a unique timer instance for the caller.
* Parameters : instance (O) pointer to result variable
* Function Result : resulting error condition
* (TMLIBDEV_ERR_NO_MORE_INSTANCES)
*/
extern tmLibdevErr_t
timOpen(Int * instance)
{
Int timer;
tmAssert(instance != Null, TMLIBDEV_ERR_NULL_PARAMETER);
for (timer = 0; timer < NROF_TIMERS; timer++) {
UInt ien;
ien = intCLEAR_IEN();
{
if (!IS_ALLOCATED(timer)
&& intOpen(INTERRUPT_OF(timer)) == 0
) {
ALLOCATE(timer);
timSetVALUE(timer, 0);
*instance = (Int) timer;
capabilities.numCurrentInstances++;
intRESTORE_IEN(ien);
return TMLIBDEV_OK;
}
}
intRESTORE_IEN(ien);
}
return TMLIBDEV_ERR_NO_MORE_INSTANCES;
}
/*
* Function : Deallocates the timer instance,
* and uninstall its handler when it has one.
* Parameters : instance (I) instance to give up
* Function Result : resulting error condition
*/
extern tmLibdevErr_t
timClose(Int instance)
{
UInt ien;
tmAssert(IS_ALLOCATED(instance), TMLIBDEV_ERR_NOT_OWNER);
ien = intCLEAR_IEN();
{
timDisableRUN(instance);
intClose(INTERRUPT_OF(instance));
memset(&timer_info[instance], 0, sizeof (timer_info[instance]));
DEALLOCATE(instance);
capabilities.numCurrentInstances--;
}
intRESTORE_IEN(ien);
return TMLIBDEV_OK;
}
/*--------------------- timer access functions -------------------------------*/
/*
* Function : Retrieve current timer value.
* Parameters : instance (I) instance to get value from
* value (O) returned timer value
* Function Result : resulting error condition
*/
extern tmLibdevErr_t
timGetTimerValue(Int instance, UInt32 * value)
{
tmAssert(value != Null, TMLIBDEV_ERR_NULL_PARAMETER);
tmAssert(IS_ALLOCATED(instance), TMLIBDEV_ERR_NOT_OWNER);
*value = timGetVALUE(instance);
return TMLIBDEV_OK;
}
/*
* Function : Set/change timer value.
* Parameters : instance (I) instance to set value for
* value (O) new timer value
* Function Result : resulting error condition
*/
extern tmLibdevErr_t
timSetTimerValue(Int instance, UInt32 value)
{
tmAssert(IS_ALLOCATED(instance), TMLIBDEV_ERR_NOT_OWNER);
timSetVALUE(instance, value);
return TMLIBDEV_OK;
}
/*
* Function : Start / stop timer.
* Parameters : instance (I) instance to start/stop
* Function Result : resulting error condition
* NB : this function is redundant, since its
* effects can also be achieved using timInstanceSetup
*/
extern tmLibdevErr_t
timStart(Int instance)
{
tmAssert(IS_ALLOCATED(instance), TMLIBDEV_ERR_NOT_OWNER);
timEnableRUN(instance);
timer_info[instance].running = True;
return TMLIBDEV_OK;
}
extern tmLibdevErr_t
timStop(Int instance)
{
tmAssert(IS_ALLOCATED(instance), TMLIBDEV_ERR_NOT_OWNER);
timDisableRUN(instance);
timer_info[instance].running = False;
return TMLIBDEV_OK;
}
/*------------------- timer utility functions --------------------------------*/
static tmLibdevErr_t
nr_of_cycles(UInt32 val /* ns */ , UInt32 freq /* Hz */ , UInt32 * result)
/* result= val*freq EE-9 */
{
UInt work[2];
UInt EE9= 1000000000;
work[0]= val*freq;
work[1]= umulm(val,freq);
_long_udiv ( work, EE9 );
if (work[1] == 0) {
*result= work[0];
return TMLIBDEV_OK;
}
else {
return TIM_ERR_OVERFLOW;
}
}
static tmLibdevErr_t
nr_of_nanoseconds(UInt32 val /* cycles */ , UInt32 freq /* Hz */, UInt32 *result )
/* result= val EE9 /freq */
{
UInt work[2];
UInt EE9= 1000000000;
work[0]= val*EE9;
work[1]= umulm(val,EE9);
_long_udiv ( work, freq );
if (work[1] == 0) {
*result= work[0];
return TMLIBDEV_OK;
}
else {
return TIM_ERR_OVERFLOW;
}
}
/*
* Function : Convert nano seconds to cycles.
* Parameters : nanoseconds (I) 'real' time in nano seconds
* cycles (O) same time in cycles, given
* the current TM-1000 frequency
* Function Result : resulting error condition
* (TIM_ERR_OVERFLOW)
*/
extern tmLibdevErr_t
timToCycles(UInt32 nanoseconds, UInt32 * cycles)
{
pprocCapabilities_t caps;
procGetCapabilities(&caps);
tmAssert(cycles != Null, TMLIBDEV_ERR_NULL_PARAMETER);
return nr_of_cycles(nanoseconds, caps->cpuClockFrequency, cycles);
}
/*
* Function : Convert cycles to nano seconds.
* Parameters : cycles (I) time in cycles
* nanoseconds (O) same time in nano seconds,
* given the current TM-1000 frequency
* Function Result : resulting error condition
* (TIM_ERR_OVERFLOW)
*/
extern tmLibdevErr_t
timFromCycles(UInt32 cycles, UInt32 * nanoseconds)
{
pprocCapabilities_t caps;
procGetCapabilities(&caps);
tmAssert(nanoseconds != Null, TMLIBDEV_ERR_NULL_PARAMETER);
return nr_of_nanoseconds(cycles, caps->cpuClockFrequency, nanoseconds);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -