From aa38e5c1f48e31213ee349aa5cd6f06c85bda70d Mon Sep 17 00:00:00 2001 From: android <android@lingyun.com> Date: Tue, 25 Jun 2024 21:49:39 +0800 Subject: [PATCH] Add GD32F103RCT6 ADC converter board SDK source code --- mcu_sdk/gd32f103/rk_eFire/Utiles/Utilities/timeServer.c | 386 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 386 insertions(+), 0 deletions(-) diff --git a/mcu_sdk/gd32f103/rk_eFire/Utiles/Utilities/timeServer.c b/mcu_sdk/gd32f103/rk_eFire/Utiles/Utilities/timeServer.c new file mode 100644 index 0000000..5b39b01 --- /dev/null +++ b/mcu_sdk/gd32f103/rk_eFire/Utiles/Utilities/timeServer.c @@ -0,0 +1,386 @@ +/*! + * \file timer.c + * + * \brief Timer objects and scheduling management implementation + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + */ +#include "rtc.h" +#include "timeServer.h" +#include "board_common.h" + +/*! + * Safely execute call back + */ +#define ExecuteCallBack( _callback_, context ) \ + do \ + { \ + if( _callback_ == NULL ) \ + { \ + while( 1 ); \ + } \ + else \ + { \ + _callback_( context ); \ + } \ + }while( 0 ); + +/*! + * Timers list head pointer + */ +static TimerEvent_t *TimerListHead = NULL; + +/*! + * \brief Adds or replace the head timer of the list. + * + * \remark The list is automatically sorted. The list head always contains the + * next timer to expire. + * + * \param [IN] obj Timer object to be become the new head + * \param [IN] remainingTime Remaining time of the previous head to be replaced + */ +static void TimerInsertNewHeadTimer( TimerEvent_t *obj ); + +/*! + * \brief Adds a timer to the list. + * + * \remark The list is automatically sorted. The list head always contains the + * next timer to expire. + * + * \param [IN] obj Timer object to be added to the list + * \param [IN] remainingTime Remaining time of the running head after which the object may be added + */ +static void TimerInsertTimer( TimerEvent_t *obj ); + +/*! + * \brief Sets a timeout with the duration "timestamp" + * + * \param [IN] timestamp Delay duration + */ +static void TimerSetTimeout( TimerEvent_t *obj ); + +/*! + * \brief Check if the Object to be added is not already in the list + * + * \param [IN] timestamp Delay duration + * \retval true (the object is already in the list) or false + */ +static bool TimerExists( TimerEvent_t *obj ); + +void TimerInit( TimerEvent_t *obj, void ( *callback )( void *context ) ) +{ + obj->Timestamp = 0; + obj->ReloadValue = 0; + obj->IsStarted = false; + obj->IsNext2Expire = false; + obj->Callback = callback; + obj->Context = NULL; + obj->Next = NULL; +} + +void TimerSetContext( TimerEvent_t *obj, void* context ) +{ + obj->Context = context; +} + +void TimerStart( TimerEvent_t *obj ) +{ + uint32_t elapsedTime = 0; + + BACKUP_PRIMASK( ); + DISABLE_IRQ( ); + + if( ( obj == NULL ) || ( TimerExists( obj ) == true ) ) + { + RESTORE_PRIMASK( ); + return; + } + + obj->Timestamp = obj->ReloadValue; + obj->IsStarted = true; + obj->IsNext2Expire = false; + + if( TimerListHead == NULL ) + { + RtcSetTimerContext( ); + // Inserts a timer at time now + obj->Timestamp + TimerInsertNewHeadTimer( obj ); + } + else + { + elapsedTime = RtcGetTimerElapsedTime( ); + obj->Timestamp += elapsedTime; + + if( obj->Timestamp < TimerListHead->Timestamp ) + { + TimerInsertNewHeadTimer( obj ); + } + else + { + TimerInsertTimer( obj ); + } + } + RESTORE_PRIMASK( ); +} + +static void TimerInsertTimer( TimerEvent_t *obj ) +{ + TimerEvent_t* cur = TimerListHead; + TimerEvent_t* next = TimerListHead->Next; + + while( cur->Next != NULL ) + { + if( obj->Timestamp > next->Timestamp ) + { + cur = next; + next = next->Next; + } + else + { + cur->Next = obj; + obj->Next = next; + return; + } + } + cur->Next = obj; + obj->Next = NULL; +} + +static void TimerInsertNewHeadTimer( TimerEvent_t *obj ) +{ + TimerEvent_t* cur = TimerListHead; + + if( cur != NULL ) + { + cur->IsNext2Expire = false; + } + + obj->Next = cur; + TimerListHead = obj; + TimerSetTimeout( TimerListHead ); +} + +bool TimerIsStarted( TimerEvent_t *obj ) +{ + return obj->IsStarted; +} + +void TimerIrqHandler( void ) +{ + TimerEvent_t* cur; + TimerEvent_t* next; + + uint32_t old = RtcGetTimerContext( ); + uint32_t now = RtcSetTimerContext( ); + uint32_t deltaContext = now - old; // intentional wrap around + + // Update timeStamp based upon new Time Reference + // because delta context should never exceed 2^32 + if( TimerListHead != NULL ) + { + for( cur = TimerListHead; cur->Next != NULL; cur = cur->Next ) + { + next = cur->Next; + if( next->Timestamp > deltaContext ) + { + next->Timestamp -= deltaContext; + } + else + { + next->Timestamp = 0; + } + } + } + + // Execute immediately the alarm callback + if ( TimerListHead != NULL ) + { + cur = TimerListHead; + TimerListHead = TimerListHead->Next; + cur->IsStarted = false; + ExecuteCallBack( cur->Callback, cur->Context ); + } + + // Remove all the expired object from the list + while( ( TimerListHead != NULL ) && ( TimerListHead->Timestamp < RtcGetTimerElapsedTime( ) ) ) + { + cur = TimerListHead; + TimerListHead = TimerListHead->Next; + cur->IsStarted = false; + ExecuteCallBack( cur->Callback, cur->Context ); + } + + // Start the next TimerListHead if it exists AND NOT running + if( ( TimerListHead != NULL ) && ( TimerListHead->IsNext2Expire == false ) ) + { + TimerSetTimeout( TimerListHead ); + } +} + +void TimerStop( TimerEvent_t *obj ) +{ + BACKUP_PRIMASK( ); + DISABLE_IRQ( ); + + TimerEvent_t* prev = TimerListHead; + TimerEvent_t* cur = TimerListHead; + + // List is empty or the obj to stop does not exist + if( ( TimerListHead == NULL ) || ( obj == NULL ) ) + { + RESTORE_PRIMASK( ); + return; + } + + obj->IsStarted = false; + + if( TimerListHead == obj ) // Stop the Head + { + if( TimerListHead->IsNext2Expire == true ) // The head is already running + { + TimerListHead->IsNext2Expire = false; + if( TimerListHead->Next != NULL ) + { + TimerListHead = TimerListHead->Next; + TimerSetTimeout( TimerListHead ); + } + else + { + RtcStopAlarm( ); + TimerListHead = NULL; + } + } + else // Stop the head before it is started + { + if( TimerListHead->Next != NULL ) + { + TimerListHead = TimerListHead->Next; + } + else + { + TimerListHead = NULL; + } + } + } + else // Stop an object within the list + { + while( cur != NULL ) + { + if( cur == obj ) + { + if( cur->Next != NULL ) + { + cur = cur->Next; + prev->Next = cur; + } + else + { + cur = NULL; + prev->Next = cur; + } + break; + } + else + { + prev = cur; + cur = cur->Next; + } + } + } + RESTORE_PRIMASK( ); +} + +static bool TimerExists( TimerEvent_t *obj ) +{ + TimerEvent_t* cur = TimerListHead; + + while( cur != NULL ) + { + if( cur == obj ) + { + return true; + } + cur = cur->Next; + } + return false; +} + +void TimerReset( TimerEvent_t *obj ) +{ + TimerStop( obj ); + TimerStart( obj ); +} + +void TimerSetValue( TimerEvent_t *obj, uint32_t value ) +{ + uint32_t minValue = 0; + uint32_t ticks = RtcMs2Tick( value ); + TimerStop( obj ); + + minValue = RtcGetMinimumTimeout( ); + + if( ticks < minValue ) + { + ticks = minValue; + } + + obj->Timestamp = ticks; + obj->ReloadValue = ticks; +} + +TimerTime_t TimerGetCurrentTime( void ) +{ + uint32_t now = RtcGetTimerValue( ); + return RtcTick2Ms( now ); +} + +TimerTime_t TimerGetElapsedTime( TimerTime_t past ) +{ + if ( past == 0 ) + { + return 0; + } + uint32_t nowInTicks = RtcGetTimerValue( ); + uint32_t pastInTicks = RtcMs2Tick( past ); + + // Intentional wrap around. Works Ok if tick duration below 1ms + return RtcTick2Ms( nowInTicks - pastInTicks ); +} + +static void TimerSetTimeout( TimerEvent_t *obj ) +{ + int32_t minTicks= RtcGetMinimumTimeout( ); + obj->IsNext2Expire = true; + + // In case deadline too soon + if( obj->Timestamp < ( RtcGetTimerElapsedTime( ) + minTicks ) ) + { + obj->Timestamp = RtcGetTimerElapsedTime( ) + minTicks; + } + RtcSetAlarm( obj->Timestamp ); +} + +TimerTime_t TimerTempCompensation( TimerTime_t period, float temperature ) +{ + return RtcTempCompensation( period, temperature ); +} + +void TimerProcess( void ) +{ + RtcProcess( ); +} -- Gitblit v1.9.1