HXC Client Shield Repository.

Dependencies:   mbed

Committer:
kashish_mbed
Date:
Mon Apr 19 17:43:09 2021 +0000
Revision:
3:5e1a54378107
Parent:
0:bacc6e701fb4
Successful Build file with CmdProcess Functionality

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kashish_mbed 0:bacc6e701fb4 1 /*
kashish_mbed 0:bacc6e701fb4 2 / _____) _ | |
kashish_mbed 0:bacc6e701fb4 3 ( (____ _____ ____ _| |_ _____ ____| |__
kashish_mbed 0:bacc6e701fb4 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
kashish_mbed 0:bacc6e701fb4 5 _____) ) ____| | | || |_| ____( (___| | | |
kashish_mbed 0:bacc6e701fb4 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
kashish_mbed 0:bacc6e701fb4 7 (C)2013 Semtech
kashish_mbed 0:bacc6e701fb4 8
kashish_mbed 0:bacc6e701fb4 9 Description: Generic lora driver implementation
kashish_mbed 0:bacc6e701fb4 10
kashish_mbed 0:bacc6e701fb4 11 License: Revised BSD License, see LICENSE.TXT file include in the project
kashish_mbed 0:bacc6e701fb4 12
kashish_mbed 0:bacc6e701fb4 13 Maintainer: Miguel Luis, Gregory Cristian and Wael Guibene
kashish_mbed 0:bacc6e701fb4 14 */
kashish_mbed 0:bacc6e701fb4 15 /******************************************************************************
kashish_mbed 0:bacc6e701fb4 16 * @file time_server.c
kashish_mbed 0:bacc6e701fb4 17 * @author MCD Application Team
kashish_mbed 0:bacc6e701fb4 18 * @version V1.1.4
kashish_mbed 0:bacc6e701fb4 19 * @date 08-January-2018
kashish_mbed 0:bacc6e701fb4 20 * @brief Time server infrastructure
kashish_mbed 0:bacc6e701fb4 21 ******************************************************************************
kashish_mbed 0:bacc6e701fb4 22 * @attention
kashish_mbed 0:bacc6e701fb4 23 *
kashish_mbed 0:bacc6e701fb4 24 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics International N.V.
kashish_mbed 0:bacc6e701fb4 25 * All rights reserved.</center></h2>
kashish_mbed 0:bacc6e701fb4 26 *
kashish_mbed 0:bacc6e701fb4 27 * Redistribution and use in source and binary forms, with or without
kashish_mbed 0:bacc6e701fb4 28 * modification, are permitted, provided that the following conditions are met:
kashish_mbed 0:bacc6e701fb4 29 *
kashish_mbed 0:bacc6e701fb4 30 * 1. Redistribution of source code must retain the above copyright notice,
kashish_mbed 0:bacc6e701fb4 31 * this list of conditions and the following disclaimer.
kashish_mbed 0:bacc6e701fb4 32 * 2. Redistributions in binary form must reproduce the above copyright notice,
kashish_mbed 0:bacc6e701fb4 33 * this list of conditions and the following disclaimer in the documentation
kashish_mbed 0:bacc6e701fb4 34 * and/or other materials provided with the distribution.
kashish_mbed 0:bacc6e701fb4 35 * 3. Neither the name of STMicroelectronics nor the names of other
kashish_mbed 0:bacc6e701fb4 36 * contributors to this software may be used to endorse or promote products
kashish_mbed 0:bacc6e701fb4 37 * derived from this software without specific written permission.
kashish_mbed 0:bacc6e701fb4 38 * 4. This software, including modifications and/or derivative works of this
kashish_mbed 0:bacc6e701fb4 39 * software, must execute solely and exclusively on microcontroller or
kashish_mbed 0:bacc6e701fb4 40 * microprocessor devices manufactured by or for STMicroelectronics.
kashish_mbed 0:bacc6e701fb4 41 * 5. Redistribution and use of this software other than as permitted under
kashish_mbed 0:bacc6e701fb4 42 * this license is void and will automatically terminate your rights under
kashish_mbed 0:bacc6e701fb4 43 * this license.
kashish_mbed 0:bacc6e701fb4 44 *
kashish_mbed 0:bacc6e701fb4 45 * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
kashish_mbed 0:bacc6e701fb4 46 * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
kashish_mbed 0:bacc6e701fb4 47 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
kashish_mbed 0:bacc6e701fb4 48 * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
kashish_mbed 0:bacc6e701fb4 49 * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
kashish_mbed 0:bacc6e701fb4 50 * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
kashish_mbed 0:bacc6e701fb4 51 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
kashish_mbed 0:bacc6e701fb4 52 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
kashish_mbed 0:bacc6e701fb4 53 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
kashish_mbed 0:bacc6e701fb4 54 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
kashish_mbed 0:bacc6e701fb4 55 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
kashish_mbed 0:bacc6e701fb4 56 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
kashish_mbed 0:bacc6e701fb4 57 *
kashish_mbed 0:bacc6e701fb4 58 ******************************************************************************
kashish_mbed 0:bacc6e701fb4 59 */
kashish_mbed 0:bacc6e701fb4 60
kashish_mbed 0:bacc6e701fb4 61 /* Includes ------------------------------------------------------------------*/
kashish_mbed 0:bacc6e701fb4 62 #include <time.h>
kashish_mbed 0:bacc6e701fb4 63 #include "hw_rtc.h"
kashish_mbed 0:bacc6e701fb4 64 #include "time_server.h"
kashish_mbed 0:bacc6e701fb4 65
kashish_mbed 0:bacc6e701fb4 66
kashish_mbed 0:bacc6e701fb4 67 /*!
kashish_mbed 0:bacc6e701fb4 68 * safely execute call back
kashish_mbed 0:bacc6e701fb4 69 */
kashish_mbed 0:bacc6e701fb4 70 #define exec_cb( _callback_ ) \
kashish_mbed 0:bacc6e701fb4 71 do { \
kashish_mbed 0:bacc6e701fb4 72 if( _callback_ != NULL ) \
kashish_mbed 0:bacc6e701fb4 73 { \
kashish_mbed 0:bacc6e701fb4 74 _callback_( ); \
kashish_mbed 0:bacc6e701fb4 75 } \
kashish_mbed 0:bacc6e701fb4 76 } while(0);
kashish_mbed 0:bacc6e701fb4 77
kashish_mbed 0:bacc6e701fb4 78
kashish_mbed 0:bacc6e701fb4 79
kashish_mbed 0:bacc6e701fb4 80 /*!
kashish_mbed 0:bacc6e701fb4 81 * Timers list head pointer
kashish_mbed 0:bacc6e701fb4 82 */
kashish_mbed 0:bacc6e701fb4 83 static TimerEvent_t *TimerListHead = NULL;
kashish_mbed 0:bacc6e701fb4 84
kashish_mbed 0:bacc6e701fb4 85 /*!
kashish_mbed 0:bacc6e701fb4 86 * \brief Adds or replace the head timer of the list.
kashish_mbed 0:bacc6e701fb4 87 *
kashish_mbed 0:bacc6e701fb4 88 * \remark The list is automatically sorted. The list head always contains the
kashish_mbed 0:bacc6e701fb4 89 * next timer to expire.
kashish_mbed 0:bacc6e701fb4 90 *
kashish_mbed 0:bacc6e701fb4 91 * \param [IN] obj Timer object to be become the new head
kashish_mbed 0:bacc6e701fb4 92 * \param [IN] remainingTime Remaining time of the previous head to be replaced
kashish_mbed 0:bacc6e701fb4 93 */
kashish_mbed 0:bacc6e701fb4 94 static void TimerInsertNewHeadTimer( TimerEvent_t *obj );
kashish_mbed 0:bacc6e701fb4 95
kashish_mbed 0:bacc6e701fb4 96 /*!
kashish_mbed 0:bacc6e701fb4 97 * \brief Adds a timer to the list.
kashish_mbed 0:bacc6e701fb4 98 *
kashish_mbed 0:bacc6e701fb4 99 * \remark The list is automatically sorted. The list head always contains the
kashish_mbed 0:bacc6e701fb4 100 * next timer to expire.
kashish_mbed 0:bacc6e701fb4 101 *
kashish_mbed 0:bacc6e701fb4 102 * \param [IN] obj Timer object to be added to the list
kashish_mbed 0:bacc6e701fb4 103 * \param [IN] remainingTime Remaining time of the running head after which the object may be added
kashish_mbed 0:bacc6e701fb4 104 */
kashish_mbed 0:bacc6e701fb4 105 static void TimerInsertTimer( TimerEvent_t *obj );
kashish_mbed 0:bacc6e701fb4 106
kashish_mbed 0:bacc6e701fb4 107 /*!
kashish_mbed 0:bacc6e701fb4 108 * \brief Sets a timeout with the duration "timestamp"
kashish_mbed 0:bacc6e701fb4 109 *
kashish_mbed 0:bacc6e701fb4 110 * \param [IN] timestamp Delay duration
kashish_mbed 0:bacc6e701fb4 111 */
kashish_mbed 0:bacc6e701fb4 112 static void TimerSetTimeout( TimerEvent_t *obj );
kashish_mbed 0:bacc6e701fb4 113
kashish_mbed 0:bacc6e701fb4 114 /*!
kashish_mbed 0:bacc6e701fb4 115 * \brief Check if the Object to be added is not already in the list
kashish_mbed 0:bacc6e701fb4 116 *
kashish_mbed 0:bacc6e701fb4 117 * \param [IN] timestamp Delay duration
kashish_mbed 0:bacc6e701fb4 118 * \retval true (the object is already in the list) or false
kashish_mbed 0:bacc6e701fb4 119 */
kashish_mbed 0:bacc6e701fb4 120 static bool TimerExists( TimerEvent_t *obj );
kashish_mbed 0:bacc6e701fb4 121
kashish_mbed 0:bacc6e701fb4 122 static void TimerIrqHandler( void );
kashish_mbed 0:bacc6e701fb4 123
kashish_mbed 0:bacc6e701fb4 124
kashish_mbed 0:bacc6e701fb4 125
kashish_mbed 0:bacc6e701fb4 126 void TimerInit( TimerEvent_t *obj, void ( *callback )( void ) )
kashish_mbed 0:bacc6e701fb4 127 {
kashish_mbed 0:bacc6e701fb4 128 obj->Timestamp = 0;
kashish_mbed 0:bacc6e701fb4 129 obj->ReloadValue = 0;
kashish_mbed 0:bacc6e701fb4 130 obj->IsRunning = false;
kashish_mbed 0:bacc6e701fb4 131 obj->Callback = callback;
kashish_mbed 0:bacc6e701fb4 132 obj->Next = NULL;
kashish_mbed 0:bacc6e701fb4 133 }
kashish_mbed 0:bacc6e701fb4 134
kashish_mbed 0:bacc6e701fb4 135 void TimerStart( TimerEvent_t *obj)
kashish_mbed 0:bacc6e701fb4 136 {
kashish_mbed 0:bacc6e701fb4 137 uint32_t elapsedTime = 0;
kashish_mbed 0:bacc6e701fb4 138
kashish_mbed 0:bacc6e701fb4 139 BACKUP_PRIMASK();
kashish_mbed 0:bacc6e701fb4 140
kashish_mbed 0:bacc6e701fb4 141 DISABLE_IRQ( );
kashish_mbed 0:bacc6e701fb4 142
kashish_mbed 0:bacc6e701fb4 143
kashish_mbed 0:bacc6e701fb4 144 if( ( obj == NULL ) || ( TimerExists( obj ) == true ) )
kashish_mbed 0:bacc6e701fb4 145 {
kashish_mbed 0:bacc6e701fb4 146 RESTORE_PRIMASK( );
kashish_mbed 0:bacc6e701fb4 147 return;
kashish_mbed 0:bacc6e701fb4 148 }
kashish_mbed 0:bacc6e701fb4 149 obj->Timestamp = obj->ReloadValue;
kashish_mbed 0:bacc6e701fb4 150 obj->IsRunning = false;
kashish_mbed 0:bacc6e701fb4 151
kashish_mbed 0:bacc6e701fb4 152 if( TimerListHead == NULL )
kashish_mbed 0:bacc6e701fb4 153 {
kashish_mbed 0:bacc6e701fb4 154 HW_RTC_SetTimerContext( );
kashish_mbed 0:bacc6e701fb4 155 TimerInsertNewHeadTimer( obj ); // insert a timeout at now+obj->Timestamp
kashish_mbed 0:bacc6e701fb4 156 }
kashish_mbed 0:bacc6e701fb4 157 else
kashish_mbed 0:bacc6e701fb4 158 {
kashish_mbed 0:bacc6e701fb4 159 elapsedTime = HW_RTC_GetTimerElapsedTime( );
kashish_mbed 0:bacc6e701fb4 160 obj->Timestamp += elapsedTime;
kashish_mbed 0:bacc6e701fb4 161
kashish_mbed 0:bacc6e701fb4 162 if( obj->Timestamp < TimerListHead->Timestamp )
kashish_mbed 0:bacc6e701fb4 163 {
kashish_mbed 0:bacc6e701fb4 164 TimerInsertNewHeadTimer( obj);
kashish_mbed 0:bacc6e701fb4 165 }
kashish_mbed 0:bacc6e701fb4 166 else
kashish_mbed 0:bacc6e701fb4 167 {
kashish_mbed 0:bacc6e701fb4 168 TimerInsertTimer( obj );
kashish_mbed 0:bacc6e701fb4 169 }
kashish_mbed 0:bacc6e701fb4 170 }
kashish_mbed 0:bacc6e701fb4 171 RESTORE_PRIMASK( );
kashish_mbed 0:bacc6e701fb4 172 }
kashish_mbed 0:bacc6e701fb4 173
kashish_mbed 0:bacc6e701fb4 174 static void TimerInsertTimer( TimerEvent_t *obj)
kashish_mbed 0:bacc6e701fb4 175 {
kashish_mbed 0:bacc6e701fb4 176 TimerEvent_t* cur = TimerListHead;
kashish_mbed 0:bacc6e701fb4 177 TimerEvent_t* next = TimerListHead->Next;
kashish_mbed 0:bacc6e701fb4 178
kashish_mbed 0:bacc6e701fb4 179 while (cur->Next != NULL )
kashish_mbed 0:bacc6e701fb4 180 {
kashish_mbed 0:bacc6e701fb4 181 if( obj->Timestamp > next->Timestamp )
kashish_mbed 0:bacc6e701fb4 182 {
kashish_mbed 0:bacc6e701fb4 183 cur = next;
kashish_mbed 0:bacc6e701fb4 184 next = next->Next;
kashish_mbed 0:bacc6e701fb4 185 }
kashish_mbed 0:bacc6e701fb4 186 else
kashish_mbed 0:bacc6e701fb4 187 {
kashish_mbed 0:bacc6e701fb4 188 cur->Next = obj;
kashish_mbed 0:bacc6e701fb4 189 obj->Next = next;
kashish_mbed 0:bacc6e701fb4 190 return;
kashish_mbed 0:bacc6e701fb4 191 }
kashish_mbed 0:bacc6e701fb4 192 }
kashish_mbed 0:bacc6e701fb4 193 cur->Next = obj;
kashish_mbed 0:bacc6e701fb4 194 obj->Next = NULL;
kashish_mbed 0:bacc6e701fb4 195 }
kashish_mbed 0:bacc6e701fb4 196
kashish_mbed 0:bacc6e701fb4 197 static void TimerInsertNewHeadTimer( TimerEvent_t *obj )
kashish_mbed 0:bacc6e701fb4 198 {
kashish_mbed 0:bacc6e701fb4 199 TimerEvent_t* cur = TimerListHead;
kashish_mbed 0:bacc6e701fb4 200
kashish_mbed 0:bacc6e701fb4 201 if( cur != NULL )
kashish_mbed 0:bacc6e701fb4 202 {
kashish_mbed 0:bacc6e701fb4 203 cur->IsRunning = false;
kashish_mbed 0:bacc6e701fb4 204 }
kashish_mbed 0:bacc6e701fb4 205
kashish_mbed 0:bacc6e701fb4 206 obj->Next = cur;
kashish_mbed 0:bacc6e701fb4 207 TimerListHead = obj;
kashish_mbed 0:bacc6e701fb4 208 TimerSetTimeout( TimerListHead );
kashish_mbed 0:bacc6e701fb4 209 }
kashish_mbed 0:bacc6e701fb4 210
kashish_mbed 0:bacc6e701fb4 211 /**
kashish_mbed 0:bacc6e701fb4 212 * @brief Alarm A callback.
kashish_mbed 0:bacc6e701fb4 213 * @param hrtc: RTC handle
kashish_mbed 0:bacc6e701fb4 214 * @retval None
kashish_mbed 0:bacc6e701fb4 215 */
kashish_mbed 0:bacc6e701fb4 216 void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
kashish_mbed 0:bacc6e701fb4 217 {
kashish_mbed 0:bacc6e701fb4 218 TimerIrqHandler( );
kashish_mbed 0:bacc6e701fb4 219 }
kashish_mbed 0:bacc6e701fb4 220
kashish_mbed 0:bacc6e701fb4 221
kashish_mbed 0:bacc6e701fb4 222 /*!
kashish_mbed 0:bacc6e701fb4 223 * \brief Timer IRQ event handler
kashish_mbed 0:bacc6e701fb4 224 * \note Head Timer Object is automatically removed from the List
kashish_mbed 0:bacc6e701fb4 225 * \note e.g. it is not needed to stop it
kashish_mbed 0:bacc6e701fb4 226 */
kashish_mbed 0:bacc6e701fb4 227 static void TimerIrqHandler( void )
kashish_mbed 0:bacc6e701fb4 228 {
kashish_mbed 0:bacc6e701fb4 229 TimerEvent_t* cur;
kashish_mbed 0:bacc6e701fb4 230 TimerEvent_t* next;
kashish_mbed 0:bacc6e701fb4 231
kashish_mbed 0:bacc6e701fb4 232
kashish_mbed 0:bacc6e701fb4 233
kashish_mbed 0:bacc6e701fb4 234 uint32_t old = HW_RTC_GetTimerContext( );
kashish_mbed 0:bacc6e701fb4 235 uint32_t now = HW_RTC_SetTimerContext( );
kashish_mbed 0:bacc6e701fb4 236 uint32_t DeltaContext = now - old; //Intentional wrap around
kashish_mbed 0:bacc6e701fb4 237
kashish_mbed 0:bacc6e701fb4 238 /* update timeStamp based upon new Time Reference
kashish_mbed 0:bacc6e701fb4 239 * Because delta context should never exceed 2^32
kashish_mbed 0:bacc6e701fb4 240 */
kashish_mbed 0:bacc6e701fb4 241 if ( TimerListHead != NULL )
kashish_mbed 0:bacc6e701fb4 242 {
kashish_mbed 0:bacc6e701fb4 243 for (cur=TimerListHead; cur->Next != NULL; cur= cur->Next)
kashish_mbed 0:bacc6e701fb4 244 {
kashish_mbed 0:bacc6e701fb4 245 next =cur->Next;
kashish_mbed 0:bacc6e701fb4 246 if (next->Timestamp > DeltaContext)
kashish_mbed 0:bacc6e701fb4 247 {
kashish_mbed 0:bacc6e701fb4 248 next->Timestamp -= DeltaContext;
kashish_mbed 0:bacc6e701fb4 249 }
kashish_mbed 0:bacc6e701fb4 250 else
kashish_mbed 0:bacc6e701fb4 251 {
kashish_mbed 0:bacc6e701fb4 252 next->Timestamp = 0 ;
kashish_mbed 0:bacc6e701fb4 253 }
kashish_mbed 0:bacc6e701fb4 254 }
kashish_mbed 0:bacc6e701fb4 255 }
kashish_mbed 0:bacc6e701fb4 256
kashish_mbed 0:bacc6e701fb4 257 /* execute immediately the alarm callback */
kashish_mbed 0:bacc6e701fb4 258 if ( TimerListHead != NULL )
kashish_mbed 0:bacc6e701fb4 259 {
kashish_mbed 0:bacc6e701fb4 260 cur = TimerListHead;
kashish_mbed 0:bacc6e701fb4 261 TimerListHead = TimerListHead->Next;
kashish_mbed 0:bacc6e701fb4 262 cur->IsRunning = false;
kashish_mbed 0:bacc6e701fb4 263 exec_cb( cur->Callback );
kashish_mbed 0:bacc6e701fb4 264 }
kashish_mbed 0:bacc6e701fb4 265
kashish_mbed 0:bacc6e701fb4 266
kashish_mbed 0:bacc6e701fb4 267 // remove all the expired object from the list
kashish_mbed 0:bacc6e701fb4 268 while( ( TimerListHead != NULL ) && ( TimerListHead->Timestamp < HW_RTC_GetTimerElapsedTime( ) ))
kashish_mbed 0:bacc6e701fb4 269 {
kashish_mbed 0:bacc6e701fb4 270 cur = TimerListHead;
kashish_mbed 0:bacc6e701fb4 271 TimerListHead = TimerListHead->Next;
kashish_mbed 0:bacc6e701fb4 272 cur->IsRunning = false;
kashish_mbed 0:bacc6e701fb4 273 exec_cb( cur->Callback );
kashish_mbed 0:bacc6e701fb4 274 }
kashish_mbed 0:bacc6e701fb4 275
kashish_mbed 0:bacc6e701fb4 276 /* start the next TimerListHead if it exists AND NOT running */
kashish_mbed 0:bacc6e701fb4 277 if(( TimerListHead != NULL ) && (TimerListHead->IsRunning == false))
kashish_mbed 0:bacc6e701fb4 278 {
kashish_mbed 0:bacc6e701fb4 279 TimerSetTimeout( TimerListHead );
kashish_mbed 0:bacc6e701fb4 280 }
kashish_mbed 0:bacc6e701fb4 281 }
kashish_mbed 0:bacc6e701fb4 282
kashish_mbed 0:bacc6e701fb4 283 void TimerStop( TimerEvent_t *obj )
kashish_mbed 0:bacc6e701fb4 284 {
kashish_mbed 0:bacc6e701fb4 285 BACKUP_PRIMASK();
kashish_mbed 0:bacc6e701fb4 286
kashish_mbed 0:bacc6e701fb4 287 DISABLE_IRQ( );
kashish_mbed 0:bacc6e701fb4 288
kashish_mbed 0:bacc6e701fb4 289 TimerEvent_t* prev = TimerListHead;
kashish_mbed 0:bacc6e701fb4 290 TimerEvent_t* cur = TimerListHead;
kashish_mbed 0:bacc6e701fb4 291
kashish_mbed 0:bacc6e701fb4 292 // List is empty or the Obj to stop does not exist
kashish_mbed 0:bacc6e701fb4 293 if( ( TimerListHead == NULL ) || ( obj == NULL ) )
kashish_mbed 0:bacc6e701fb4 294 {
kashish_mbed 0:bacc6e701fb4 295 RESTORE_PRIMASK( );
kashish_mbed 0:bacc6e701fb4 296 return;
kashish_mbed 0:bacc6e701fb4 297 }
kashish_mbed 0:bacc6e701fb4 298
kashish_mbed 0:bacc6e701fb4 299 if( TimerListHead == obj ) // Stop the Head
kashish_mbed 0:bacc6e701fb4 300 {
kashish_mbed 0:bacc6e701fb4 301 if( TimerListHead->IsRunning == true ) // The head is already running
kashish_mbed 0:bacc6e701fb4 302 {
kashish_mbed 0:bacc6e701fb4 303 if( TimerListHead->Next != NULL )
kashish_mbed 0:bacc6e701fb4 304 {
kashish_mbed 0:bacc6e701fb4 305 TimerListHead->IsRunning = false;
kashish_mbed 0:bacc6e701fb4 306 TimerListHead = TimerListHead->Next;
kashish_mbed 0:bacc6e701fb4 307 TimerSetTimeout( TimerListHead );
kashish_mbed 0:bacc6e701fb4 308 }
kashish_mbed 0:bacc6e701fb4 309 else
kashish_mbed 0:bacc6e701fb4 310 {
kashish_mbed 0:bacc6e701fb4 311 HW_RTC_StopAlarm( );
kashish_mbed 0:bacc6e701fb4 312 TimerListHead = NULL;
kashish_mbed 0:bacc6e701fb4 313 }
kashish_mbed 0:bacc6e701fb4 314 }
kashish_mbed 0:bacc6e701fb4 315 else // Stop the head before it is started
kashish_mbed 0:bacc6e701fb4 316 {
kashish_mbed 0:bacc6e701fb4 317 if( TimerListHead->Next != NULL )
kashish_mbed 0:bacc6e701fb4 318 {
kashish_mbed 0:bacc6e701fb4 319 TimerListHead = TimerListHead->Next;
kashish_mbed 0:bacc6e701fb4 320 }
kashish_mbed 0:bacc6e701fb4 321 else
kashish_mbed 0:bacc6e701fb4 322 {
kashish_mbed 0:bacc6e701fb4 323 TimerListHead = NULL;
kashish_mbed 0:bacc6e701fb4 324 }
kashish_mbed 0:bacc6e701fb4 325 }
kashish_mbed 0:bacc6e701fb4 326 }
kashish_mbed 0:bacc6e701fb4 327 else // Stop an object within the list
kashish_mbed 0:bacc6e701fb4 328 {
kashish_mbed 0:bacc6e701fb4 329 while( cur != NULL )
kashish_mbed 0:bacc6e701fb4 330 {
kashish_mbed 0:bacc6e701fb4 331 if( cur == obj )
kashish_mbed 0:bacc6e701fb4 332 {
kashish_mbed 0:bacc6e701fb4 333 if( cur->Next != NULL )
kashish_mbed 0:bacc6e701fb4 334 {
kashish_mbed 0:bacc6e701fb4 335 cur = cur->Next;
kashish_mbed 0:bacc6e701fb4 336 prev->Next = cur;
kashish_mbed 0:bacc6e701fb4 337 }
kashish_mbed 0:bacc6e701fb4 338 else
kashish_mbed 0:bacc6e701fb4 339 {
kashish_mbed 0:bacc6e701fb4 340 cur = NULL;
kashish_mbed 0:bacc6e701fb4 341 prev->Next = cur;
kashish_mbed 0:bacc6e701fb4 342 }
kashish_mbed 0:bacc6e701fb4 343 break;
kashish_mbed 0:bacc6e701fb4 344 }
kashish_mbed 0:bacc6e701fb4 345 else
kashish_mbed 0:bacc6e701fb4 346 {
kashish_mbed 0:bacc6e701fb4 347 prev = cur;
kashish_mbed 0:bacc6e701fb4 348 cur = cur->Next;
kashish_mbed 0:bacc6e701fb4 349 }
kashish_mbed 0:bacc6e701fb4 350 }
kashish_mbed 0:bacc6e701fb4 351 }
kashish_mbed 0:bacc6e701fb4 352
kashish_mbed 0:bacc6e701fb4 353 RESTORE_PRIMASK( );
kashish_mbed 0:bacc6e701fb4 354 }
kashish_mbed 0:bacc6e701fb4 355
kashish_mbed 0:bacc6e701fb4 356 static bool TimerExists( TimerEvent_t *obj )
kashish_mbed 0:bacc6e701fb4 357 {
kashish_mbed 0:bacc6e701fb4 358 TimerEvent_t* cur = TimerListHead;
kashish_mbed 0:bacc6e701fb4 359
kashish_mbed 0:bacc6e701fb4 360 while( cur != NULL )
kashish_mbed 0:bacc6e701fb4 361 {
kashish_mbed 0:bacc6e701fb4 362 if( cur == obj )
kashish_mbed 0:bacc6e701fb4 363 {
kashish_mbed 0:bacc6e701fb4 364 return true;
kashish_mbed 0:bacc6e701fb4 365 }
kashish_mbed 0:bacc6e701fb4 366 cur = cur->Next;
kashish_mbed 0:bacc6e701fb4 367 }
kashish_mbed 0:bacc6e701fb4 368 return false;
kashish_mbed 0:bacc6e701fb4 369 }
kashish_mbed 0:bacc6e701fb4 370
kashish_mbed 0:bacc6e701fb4 371 void TimerReset( TimerEvent_t *obj )
kashish_mbed 0:bacc6e701fb4 372 {
kashish_mbed 0:bacc6e701fb4 373 TimerStop( obj );
kashish_mbed 0:bacc6e701fb4 374 TimerStart( obj );
kashish_mbed 0:bacc6e701fb4 375 }
kashish_mbed 0:bacc6e701fb4 376
kashish_mbed 0:bacc6e701fb4 377 /******************************************************************************
kashish_mbed 0:bacc6e701fb4 378 * @Brief : Set timer new timeout value
kashish_mbed 0:bacc6e701fb4 379 * @Param : obj - pointer to TimerEvent object
kashish_mbed 0:bacc6e701fb4 380 * value - timeout value
kashish_mbed 0:bacc6e701fb4 381 * @Return : None
kashish_mbed 0:bacc6e701fb4 382 ******************************************************************************/
kashish_mbed 0:bacc6e701fb4 383 void TimerSetValue( TimerEvent_t *obj, uint32_t timeoutMs )
kashish_mbed 0:bacc6e701fb4 384 {
kashish_mbed 0:bacc6e701fb4 385 uint32_t minValue = 0;
kashish_mbed 0:bacc6e701fb4 386 uint32_t ticks = HW_RTC_ms2Tick( timeoutMs );
kashish_mbed 0:bacc6e701fb4 387
kashish_mbed 0:bacc6e701fb4 388 TimerStop( obj );
kashish_mbed 0:bacc6e701fb4 389
kashish_mbed 0:bacc6e701fb4 390 minValue = HW_RTC_GetMinimumTimeout( );
kashish_mbed 0:bacc6e701fb4 391
kashish_mbed 0:bacc6e701fb4 392 if( ticks < minValue )
kashish_mbed 0:bacc6e701fb4 393 {
kashish_mbed 0:bacc6e701fb4 394 ticks = minValue;
kashish_mbed 0:bacc6e701fb4 395 }
kashish_mbed 0:bacc6e701fb4 396
kashish_mbed 0:bacc6e701fb4 397 obj->Timestamp = ticks;
kashish_mbed 0:bacc6e701fb4 398 obj->ReloadValue = ticks;
kashish_mbed 0:bacc6e701fb4 399 }
kashish_mbed 0:bacc6e701fb4 400
kashish_mbed 0:bacc6e701fb4 401 /******************************************************************************
kashish_mbed 0:bacc6e701fb4 402 * @Brief : Get current time in millisecond
kashish_mbed 0:bacc6e701fb4 403 * @Param : void
kashish_mbed 0:bacc6e701fb4 404 * @Return : current ms
kashish_mbed 0:bacc6e701fb4 405 ******************************************************************************/
kashish_mbed 0:bacc6e701fb4 406 uint32_t TimerGetCurrentTime( void )
kashish_mbed 0:bacc6e701fb4 407 {
kashish_mbed 0:bacc6e701fb4 408 uint32_t now = HW_RTC_GetTimerValue( );
kashish_mbed 0:bacc6e701fb4 409 return HW_RTC_Tick2ms(now);
kashish_mbed 0:bacc6e701fb4 410 }
kashish_mbed 0:bacc6e701fb4 411
kashish_mbed 0:bacc6e701fb4 412 uint32_t TimerGetElapsedTime( uint32_t past )
kashish_mbed 0:bacc6e701fb4 413 {
kashish_mbed 0:bacc6e701fb4 414 uint32_t nowInTicks = HW_RTC_GetTimerValue( );
kashish_mbed 0:bacc6e701fb4 415 uint32_t pastInTicks = HW_RTC_ms2Tick( past );
kashish_mbed 0:bacc6e701fb4 416 /* intentional wrap around. Works OK if tick duration below 1ms */
kashish_mbed 0:bacc6e701fb4 417 return HW_RTC_Tick2ms( nowInTicks- pastInTicks );
kashish_mbed 0:bacc6e701fb4 418 }
kashish_mbed 0:bacc6e701fb4 419
kashish_mbed 0:bacc6e701fb4 420 static void TimerSetTimeout( TimerEvent_t *obj )
kashish_mbed 0:bacc6e701fb4 421 {
kashish_mbed 0:bacc6e701fb4 422 int32_t minTicks= HW_RTC_GetMinimumTimeout( );
kashish_mbed 0:bacc6e701fb4 423 obj->IsRunning = true;
kashish_mbed 0:bacc6e701fb4 424
kashish_mbed 0:bacc6e701fb4 425 //in case deadline too soon
kashish_mbed 0:bacc6e701fb4 426 if(obj->Timestamp < (HW_RTC_GetTimerElapsedTime( ) + minTicks) )
kashish_mbed 0:bacc6e701fb4 427 {
kashish_mbed 0:bacc6e701fb4 428 obj->Timestamp = HW_RTC_GetTimerElapsedTime( ) + minTicks;
kashish_mbed 0:bacc6e701fb4 429 }
kashish_mbed 0:bacc6e701fb4 430 HW_RTC_SetAlarm( obj->Timestamp );
kashish_mbed 0:bacc6e701fb4 431 }
kashish_mbed 0:bacc6e701fb4 432 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
kashish_mbed 0:bacc6e701fb4 433