Multiple timers

How to run multiple timers at the same time ?
I need to use 3 timers.

Mark

Hi Mark,

I don’t see a problem here… Why not just call adl_tmrSubscribe() three times?

Best Regards,
Jan

Yes, limitation is around 30 timers at the same time… no problem with 3 timers !!

…and if you do need >30 (or whatever) timers, just use the standard approach of having one “real” ADL timer to generate your timebase “tick”, and maintain a number of counters clocked by that “tick” to implement your other timed requirements…

Another good reason is the need of retriggerable timers.
My app is “presetting” the counter to its initial val - unfortunately the ADL timers do not provide this funcionality.

Heinz

Absolutely!

It is a very major omission that Open-AT does not provide retrigerable timers!! :open_mouth: :angry:

The retrigerable timer is such a fundamental requirement for any comms protocol work (ie, timeouts), that it is quite incredible that Open-AT doesn’t provide them!! :open_mouth: :open_mouth: :angry:

So there’s a new functionality request: wavecom.com/modules/movie/sc … php?p=4902

Since it is quite simple, but lot of work to write I’m going to share 8)

/****************************************************************************
 *
 *	File:	timer.h
 *
 *  Object:	header file for timer system
 *
 ****************************************************************************
 *
 * ----------+--------+----------------+-------------------------------------
 *  06/11/05 | HLI    | 1.0            | Initial revision.                  
 * ----------+--------+----------------+-------------------------------------
 *
 ***************************************************************************/

#ifndef __TIMER_H__
#define __TIMER_H__

#include "adl_global.h"

#define MAX_TIMERS		40

typedef enum TimerStatus_e
{
	TIMER_FREE = 0,
	TIMER_RUNNING,
	TIMER_EXPIRED,
	TIMER_STOPPED
} TimerStatus_e;

typedef enum TimerType_e
{
	TIMER_NONE = 0,
	TIMER_ONESHOT,
	TIMER_CYCLIC
} TimerType_e;

typedef struct //sw_timers_t
{
	s8				timer;
	TimerStatus_e	state;
	TimerType_e		type;
	u32				reload;
	void			(*callback)( s8 timer );
	u32				count;
} sw_timers_t;

void	timer_init ( void );
void	timer_remove ( void );

// sw realized timer system
void	SwTmr_Init			( void );
s8		SwTmr_StartTimer	( s8 timer, TimerType_e type, u32 timeout, void (*callback)( s8 timer ) );
void	SwTmr_SetStatus		( s8 timer, TimerStatus_e status );
void	SwTmr_StopTimer		( s8 timer );
void	SwTmr_ContinueTimer ( s8 timer );
void	SwTmr_KillTimer		( s8 timer );
void	SwTmr_RetriggerTimer( s8 timer );
void	SwTmr_SetInterval ( s8 timer, u16 new_interval );
#endif

and

/****************************************************************************
 *
 *	File:	timer.c
 *
 *  Object:	functions related to the timer subsystem
 *
 ****************************************************************************
 *
 * ----------+--------+----------------+-------------------------------------
 *  06/11/05 | HLI    | 1.0            | Initial revision.                  
 * ----------+--------+----------------+-------------------------------------
 *
 ***************************************************************************/

#include "adl_global.h"
#include "timer.h"
#include "tcp_all.h"
#include "dtl_all.h"
#include "grl_all.h"

/*===========================================================================
 * some global var's for timing issues 
 *=========================================================================*/
adl_tmr_t * myHWTimer;						// wavecom system timer 100ms
sw_timers_t	TIMERS[ MAX_TIMERS ];			// SW timer system


/*===========================================================================
 *	Function:	Tmr_FindTimer 
 *  Descr.:     find the correct timer in array list
 *=========================================================================*/
s8 SwTmr_FindTimer( s8 timer ) 
{
	u8	i;
	for( i = 0; i < MAX_TIMERS; i++ )
	{
		if ( TIMERS[ i ].timer == timer )
		{
			return ( i );
		}
	}
	return ( -1 );
}


/*===========================================================================
 *	Function:	SwTmr_KillTimer 
 *  Descr.:     cancel a running timer
 *=========================================================================*/
void SwTmr_KillTimer( s8 timer )
{
	s8	i = SwTmr_FindTimer( timer );
	if ( i != -1 )
	{
		TIMERS[ i ].timer		= -1;
		TIMERS[ i ].reload		= 0L;
		TIMERS[ i ].state		= TIMER_FREE;
		TIMERS[ i ].callback	= 0;
		TIMERS[ i ].count		= 0L;
	}
}


/*===========================================================================
 *	Function:	SwTmr_StopTimer 
 *  Descr.:     suspend a running sw timer
 *=========================================================================*/
void SwTmr_StopTimer( s8 timer )
{
	s8	i = SwTmr_FindTimer( timer );
	if ( i != -1 )
	{
		TIMERS[ i ].state	= TIMER_STOPPED;
	}
}


/*===========================================================================
 *	Function:	SwTmr_ContinueTimer 
 *  Descr.:     continue a previous suspended timer
 *=========================================================================*/
void SwTmr_ContinueTimer( s8 timer )
{
	s8	i = SwTmr_FindTimer( timer );
	if ( i != -1 )
	{
		TIMERS[ i ].state	= TIMER_RUNNING;
	}
}


/*===========================================================================
 *	Function:	SwTmr_RetriggerTimer 
 *  Descr.:     refresh the time of a running timer
 *=========================================================================*/
void SwTmr_RetriggerTimer( s8 timer )
{
	s8	i = SwTmr_FindTimer( timer );
	if ( i != -1 )
	{
		TIMERS[ i ].count = TIMERS[ i ].reload;
	}
}


/*===========================================================================
 *	Function:	SwTmr_Init 
 *  Descr.:     initialize the software timer system
 *=========================================================================*/
void SwTmr_Init( void )
{
	u8 i;
	for( i = 0; i < MAX_TIMERS; i++ )
	{
		TIMERS[ i ].timer		= -1;
		TIMERS[ i ].count		= 0L;
		TIMERS[ i ].state		= TIMER_FREE;
		TIMERS[ i ].type		= TIMER_NONE;
		TIMERS[ i ].callback	= NULL;
		TIMERS[ i ].reload		= 0L;
	}
}


/*===========================================================================
 *	Function:	SwTmr_SetStatus 
 *  Descr.:     set the status of an existing timer
 *=========================================================================*/
void SwTmr_SetStatus( s8 timer, TimerStatus_e status )
{
	s8	i = SwTmr_FindTimer( timer );
	if ( i != -1 )
	{
		TIMERS[ i ].state	= status;
		return;
	}
}

/*===========================================================================
 *	Function:	SwTmr_Control 
 *  Descr.:     function which is called by OS timing system to provide
 *              retriggerable sw timer system
 *=========================================================================*/
void SwTmr_Control( u8 hwtmr )
{
	// ignore hwtmr cause there is only one
	u8	i;
	if ( hwtmr == myHWTimer->TimerId )
	{
		for( i = 0; i < MAX_TIMERS; i++ )
		{
			if ( TIMERS[ i ].state == TIMER_RUNNING )
			{
				if ( TIMERS[ i ].count-- == 0 )
				{
					TIMERS[ i ].state = TIMER_EXPIRED;
					TIMERS[ i ].callback ( TIMERS[ i ].timer );
					if ( TIMERS[ i ].type == TIMER_CYCLIC )
					{
						TIMERS[ i ].count	= TIMERS[ i ].reload;
						TIMERS[ i ].state = TIMER_RUNNING;
						break;
					}
					else
					{
						SwTmr_KillTimer ( i );				
					}
				}
			}
		}
	}
}


/*===========================================================================
 *	Function:	SwTmr_Status 
 *  Descr.:     read the status of a sw defined timer
 *=========================================================================*/
TimerStatus_e SwTmr_Status( u8 timer )
{
	s8	i = SwTmr_FindTimer( timer );
	if ( i != -1 )
	{
		return ( TIMERS[ timer ].state );
	}
	return ( TIMER_FREE );
}

/*===========================================================================
 *	Function:	SwTmr_StartTimer 
 *  Descr.:     start a sw defined n*1s timer
 *=========================================================================*/
s8 SwTmr_StartTimer( s8 timer, TimerType_e type, u32 timeout, void (*callback)( s8 timer ) )
{
	s8	i = SwTmr_FindTimer( timer );
	if ( i == -1 )
	{
		i = SwTmr_FindTimer( -1 );
		if ( i == -1 )
		{
			TRACE ((1, "##### PANIC: No more sw timers! #####" ));
			return ( -1 );
		}
	}
	TIMERS[ i ].timer		= timer;
	TIMERS[ i ].type		= type;
	TIMERS[ i ].count		= timeout;
	TIMERS[ i ].callback	= callback;
	TIMERS[ i ].reload		= TIMERS[ i ].count = timeout;
	TIMERS[ i ].state		= TIMER_RUNNING;
	return ( i );
}


/*===========================================================================
 *	Function:	SwTmr_SetInterval 
 *  Descr.:     set a new timer interval
 *=========================================================================*/
void SwTmr_SetInterval ( s8 timer, u16 new_interval )
{
	s8	i = SwTmr_FindTimer( timer );
	if ( i != -1 )
	{
		TIMERS[ i ].reload	= new_interval;
		return;
	}
}


/*===========================================================================
 *	Function:	timer_init 
 *  Descr.:     initialize timer handling
 *=========================================================================*/
void timer_init ( void )
{
	SwTmr_Init();
	
	// subscribe a OS timer every 10*100ms for the SW defined timing funcs
	myHWTimer = adl_tmrSubscribe ( TRUE, (u32)10, ADL_TMR_TYPE_100MS, (void*) SwTmr_Control  );
}


/*===========================================================================
 *	Function:	timer_remove 
 *  Descr.:     remove the OS driven timing feature, therefore also
 *              the driven timing system stops!
 *=========================================================================*/
void timer_remove ( void )
{
	adl_tmrUnSubscribe ( myHWTimer, (void*) SwTmr_Control, ADL_TMR_TYPE_100MS  );
}

I’m using typically 1sec intervals, but it simply can be changed by changing the values in timer_init.

Regards,
Heinz