Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of fsl_phy_mcr20a by
PhyTime.c
00001 /*! 00002 * Copyright (c) 2015, Freescale Semiconductor, Inc. 00003 * All rights reserved. 00004 * 00005 * \file PhyTime.c 00006 * 00007 * Redistribution and use in source and binary forms, with or without modification, 00008 * are permitted provided that the following conditions are met: 00009 * 00010 * o Redistributions of source code must retain the above copyright notice, this list 00011 * of conditions and the following disclaimer. 00012 * 00013 * o Redistributions in binary form must reproduce the above copyright notice, this 00014 * list of conditions and the following disclaimer in the documentation and/or 00015 * other materials provided with the distribution. 00016 * 00017 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its 00018 * contributors may be used to endorse or promote products derived from this 00019 * software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00022 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00023 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00024 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00025 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00026 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00027 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00028 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00029 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 00033 00034 /************************************************************************************ 00035 ************************************************************************************* 00036 * Include 00037 ************************************************************************************* 00038 ************************************************************************************/ 00039 #include "EmbeddedTypes.h " 00040 //#include "fsl_os_abstraction.h" 00041 #include "MCR20Drv.h " 00042 #include "MCR20Reg.h" 00043 #include "Phy.h " 00044 00045 #include "FunctionLib.h " 00046 00047 /************************************************************************************ 00048 ************************************************************************************* 00049 * Private macros 00050 ************************************************************************************* 00051 ************************************************************************************/ 00052 #define gPhyTimeMinSetupTime_c (10) /* symbols */ 00053 00054 /************************************************************************************ 00055 ************************************************************************************* 00056 * Public memory declarations 00057 ************************************************************************************* 00058 ************************************************************************************/ 00059 void (*gpfPhyTimeNotify)(void) = NULL; 00060 00061 /************************************************************************************ 00062 ************************************************************************************* 00063 * Private memory declarations 00064 ************************************************************************************* 00065 ************************************************************************************/ 00066 static phyTimeEvent_t mPhyTimers[gMaxPhyTimers_c]; 00067 static phyTimeEvent_t *pNextEvent; 00068 volatile uint32_t mPhySeqTimeout; 00069 volatile uint64_t gPhyTimerOverflow; 00070 00071 /************************************************************************************ 00072 ************************************************************************************* 00073 * Private prototypes 00074 ************************************************************************************* 00075 ************************************************************************************/ 00076 static void PhyTime_OverflowCB( uint32_t param ); 00077 static phyTimeEvent_t* PhyTime_GetNextEvent( void ); 00078 00079 /************************************************************************************ 00080 ************************************************************************************* 00081 * Public functions 00082 ************************************************************************************* 00083 ************************************************************************************/ 00084 00085 /*! ********************************************************************************* 00086 * \brief Sets the start time of a sequence 00087 * 00088 * \param[in] startTime the start time for a sequence 00089 * 00090 ********************************************************************************** */ 00091 void PhyTimeSetEventTrigger 00092 ( 00093 uint32_t startTime 00094 ) 00095 { 00096 uint8_t phyReg, phyCtrl3Reg; 00097 00098 OSA_EnterCritical(kCriticalDisableInt); 00099 00100 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL1); 00101 phyReg |= cPHY_CTRL1_TMRTRIGEN; // enable autosequence start by TC2 match 00102 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL1, phyReg); 00103 00104 phyCtrl3Reg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3); 00105 phyCtrl3Reg &= ~(cPHY_CTRL3_TMR2CMP_EN);// disable TMR2 compare 00106 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg); 00107 00108 MCR20Drv_DirectAccessSPIMultiByteWrite( (uint8_t) T2PRIMECMP_LSB, (uint8_t *) &startTime, 2); 00109 00110 phyReg = MCR20Drv_DirectAccessSPIRead(IRQSTS3); 00111 phyReg &= 0xF0; // do not change other IRQs status 00112 phyReg &= ~(cIRQSTS3_TMR2MSK); // unmask TMR2 interrupt 00113 phyReg |= (cIRQSTS3_TMR2IRQ); // aknowledge TMR2 IRQ 00114 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, phyReg); 00115 00116 // TC2PRIME_EN must be enabled in PHY_CTRL4 register 00117 phyCtrl3Reg |= cPHY_CTRL3_TMR2CMP_EN; // enable TMR2 compare 00118 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg); 00119 00120 OSA_ExitCritical(kCriticalDisableInt); 00121 } 00122 00123 /*! ********************************************************************************* 00124 * \brief Disable the time trigger for a sequence. 00125 * 00126 * \remarks The sequence will start asap 00127 * 00128 ********************************************************************************** */ 00129 void PhyTimeDisableEventTrigger 00130 ( 00131 void 00132 ) 00133 { 00134 uint8_t phyReg; 00135 00136 OSA_EnterCritical(kCriticalDisableInt); 00137 00138 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL1); 00139 phyReg &= ~(cPHY_CTRL1_TMRTRIGEN); // disable autosequence start by TC2 match 00140 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL1, phyReg); 00141 00142 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3); 00143 phyReg &= ~(cPHY_CTRL3_TMR2CMP_EN);// disable TMR2 compare 00144 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyReg); 00145 00146 phyReg = MCR20Drv_DirectAccessSPIRead(IRQSTS3); 00147 phyReg &= 0xF0; // do not change other IRQs status 00148 phyReg |= (cIRQSTS3_TMR2MSK); // mask TMR2 interrupt 00149 phyReg |= (cIRQSTS3_TMR2IRQ); // aknowledge TMR2 IRQ 00150 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, phyReg); 00151 00152 OSA_ExitCritical(kCriticalDisableInt); 00153 } 00154 00155 /*! ********************************************************************************* 00156 * \brief Sets the timeout value for a sequence 00157 * 00158 * \param[in] pEndTime the absolute time when a sequence should terminate 00159 * 00160 * \remarks If the sequence does not finish until the timeout, it will be aborted 00161 * 00162 ********************************************************************************** */ 00163 void PhyTimeSetEventTimeout 00164 ( 00165 uint32_t *pEndTime 00166 ) 00167 { 00168 uint8_t phyReg, phyCtrl3Reg; 00169 00170 #ifdef PHY_PARAMETERS_VALIDATION 00171 if(NULL == pEndTime) 00172 { 00173 return; 00174 } 00175 #endif // PHY_PARAMETERS_VALIDATION 00176 00177 OSA_EnterCritical(kCriticalDisableInt); 00178 00179 phyCtrl3Reg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3); 00180 phyCtrl3Reg &= ~(cPHY_CTRL3_TMR3CMP_EN);// disable TMR3 compare 00181 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg); 00182 00183 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL4); 00184 phyReg |= cPHY_CTRL4_TC3TMOUT; // enable autosequence stop by TC3 match 00185 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL4, phyReg); 00186 00187 mPhySeqTimeout = *pEndTime & 0x00FFFFFF; 00188 MCR20Drv_DirectAccessSPIMultiByteWrite( (uint8_t) T3CMP_LSB, (uint8_t *) pEndTime, 3); 00189 00190 phyReg = MCR20Drv_DirectAccessSPIRead(IRQSTS3); 00191 phyReg &= 0xF0; // do not change IRQ status 00192 // phyReg &= ~(cIRQSTS3_TMR3MSK); // unmask TMR3 interrupt 00193 phyReg |= (cIRQSTS3_TMR3IRQ); // aknowledge TMR3 IRQ 00194 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, phyReg); 00195 00196 phyCtrl3Reg |= cPHY_CTRL3_TMR3CMP_EN; // enable TMR3 compare 00197 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg); 00198 00199 OSA_ExitCritical(kCriticalDisableInt); 00200 } 00201 00202 /*! ********************************************************************************* 00203 * \brief Return the timeout value for the current sequence 00204 * 00205 * \return uint32_t the timeout value 00206 * 00207 ********************************************************************************** */ 00208 uint32_t PhyTimeGetEventTimeout( void ) 00209 { 00210 return mPhySeqTimeout; 00211 } 00212 00213 /*! ********************************************************************************* 00214 * \brief Disables the sequence timeout 00215 * 00216 ********************************************************************************** */ 00217 void PhyTimeDisableEventTimeout 00218 ( 00219 void 00220 ) 00221 { 00222 uint8_t phyReg; 00223 00224 OSA_EnterCritical(kCriticalDisableInt); 00225 00226 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL4); 00227 phyReg &= ~(cPHY_CTRL4_TC3TMOUT); // disable autosequence stop by TC3 match 00228 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL4, phyReg); 00229 00230 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3); 00231 phyReg &= ~(cPHY_CTRL3_TMR3CMP_EN);// disable TMR3 compare 00232 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyReg); 00233 00234 phyReg = MCR20Drv_DirectAccessSPIRead(IRQSTS3); 00235 phyReg &= 0xF0; // do not change IRQ status 00236 phyReg |= cIRQSTS3_TMR3IRQ; // aknowledge TMR3 IRQ 00237 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, phyReg); 00238 00239 OSA_ExitCritical(kCriticalDisableInt); 00240 } 00241 00242 /*! ********************************************************************************* 00243 * \brief Reads the absolute clock from the radio 00244 * 00245 * \param[out] pRetClk pointer to a location where the current clock will be stored 00246 * 00247 ********************************************************************************** */ 00248 void PhyTimeReadClock 00249 ( 00250 uint32_t *pRetClk 00251 ) 00252 { 00253 #ifdef PHY_PARAMETERS_VALIDATION 00254 if(NULL == pRetClk) 00255 { 00256 return; 00257 } 00258 #endif // PHY_PARAMETERS_VALIDATION 00259 00260 OSA_EnterCritical(kCriticalDisableInt); 00261 00262 MCR20Drv_DirectAccessSPIMultiByteRead( (uint8_t) EVENT_TMR_LSB, (uint8_t *) pRetClk, 3); 00263 *(((uint8_t *)pRetClk) + 3) = 0; 00264 00265 OSA_ExitCritical(kCriticalDisableInt); 00266 00267 } 00268 00269 /*! ********************************************************************************* 00270 * \brief Initialize the Event Timer 00271 * 00272 * \param[in] pAbsTime pointer to the location where the new time is stored 00273 * 00274 ********************************************************************************** */ 00275 void PhyTimeInitEventTimer 00276 ( 00277 uint32_t *pAbsTime 00278 ) 00279 { 00280 uint8_t phyCtrl4Reg; 00281 00282 #ifdef PHY_PARAMETERS_VALIDATION 00283 if(NULL == pAbsTime) 00284 { 00285 return; 00286 } 00287 #endif // PHY_PARAMETERS_VALIDATION 00288 00289 OSA_EnterCritical(kCriticalDisableInt); 00290 00291 phyCtrl4Reg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL4); 00292 phyCtrl4Reg |= cPHY_CTRL4_TMRLOAD; // self clearing bit 00293 00294 MCR20Drv_DirectAccessSPIMultiByteWrite( (uint8_t) T1CMP_LSB, (uint8_t *) pAbsTime, 3); 00295 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL4, phyCtrl4Reg); 00296 00297 OSA_ExitCritical(kCriticalDisableInt); 00298 } 00299 00300 /*! ********************************************************************************* 00301 * \brief Set TMR1 timeout value 00302 * 00303 * \param[in] pWaitTimeout the timeout value 00304 * 00305 ********************************************************************************** */ 00306 void PhyTimeSetWaitTimeout 00307 ( 00308 uint32_t *pWaitTimeout 00309 ) 00310 { 00311 uint8_t phyCtrl3Reg, irqSts3Reg; 00312 00313 OSA_EnterCritical(kCriticalDisableInt); 00314 00315 phyCtrl3Reg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3); 00316 phyCtrl3Reg &= ~(cPHY_CTRL3_TMR1CMP_EN);// disable TMR1 compare 00317 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg); 00318 00319 MCR20Drv_DirectAccessSPIMultiByteWrite( (uint8_t) T1CMP_LSB, (uint8_t *) pWaitTimeout, 3); 00320 00321 irqSts3Reg = MCR20Drv_DirectAccessSPIRead(IRQSTS3); 00322 irqSts3Reg &= ~(cIRQSTS3_TMR1MSK); // unmask TMR1 interrupt 00323 irqSts3Reg &= 0xF0; // do not change other IRQs status 00324 irqSts3Reg |= (cIRQSTS3_TMR1IRQ); // aknowledge TMR1 IRQ 00325 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, irqSts3Reg); 00326 00327 phyCtrl3Reg |= cPHY_CTRL3_TMR1CMP_EN; // enable TMR1 compare 00328 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg); 00329 00330 OSA_ExitCritical(kCriticalDisableInt); 00331 00332 } 00333 00334 /*! ********************************************************************************* 00335 * \brief Disable the TMR1 timeout 00336 * 00337 ********************************************************************************** */ 00338 void PhyTimeDisableWaitTimeout 00339 ( 00340 void 00341 ) 00342 { 00343 uint8_t phyReg; 00344 00345 OSA_EnterCritical(kCriticalDisableInt); 00346 00347 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3); 00348 phyReg &= ~(cPHY_CTRL3_TMR1CMP_EN);// disable TMR1 compare 00349 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyReg); 00350 00351 phyReg = MCR20Drv_DirectAccessSPIRead(IRQSTS3); 00352 phyReg &= 0xF0; // do not change IRQ status 00353 phyReg |= cIRQSTS3_TMR1IRQ; // aknowledge TMR1 IRQ 00354 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, phyReg); 00355 00356 OSA_ExitCritical(kCriticalDisableInt); 00357 } 00358 00359 /*! ********************************************************************************* 00360 * \brief Set TMR4 timeout value 00361 * 00362 * \param[in] pWakeUpTime absolute time 00363 * 00364 ********************************************************************************** */ 00365 void PhyTimeSetWakeUpTime 00366 ( 00367 uint32_t *pWakeUpTime 00368 ) 00369 { 00370 uint8_t phyCtrl3Reg, irqSts3Reg; 00371 00372 OSA_EnterCritical(kCriticalDisableInt); 00373 00374 phyCtrl3Reg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3); 00375 // phyCtrl3Reg &= ~(cPHY_CTRL3_TMR4CMP_EN);// disable TMR4 compare 00376 // MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg); 00377 00378 MCR20Drv_DirectAccessSPIMultiByteWrite( (uint8_t) T4CMP_LSB, (uint8_t *) pWakeUpTime, 3); 00379 00380 irqSts3Reg = MCR20Drv_DirectAccessSPIRead(IRQSTS3); 00381 irqSts3Reg &= ~(cIRQSTS3_TMR4MSK); // unmask TMR4 interrupt 00382 irqSts3Reg &= 0xF0; // do not change other IRQs status 00383 irqSts3Reg |= (cIRQSTS3_TMR4IRQ); // aknowledge TMR4 IRQ 00384 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, irqSts3Reg); 00385 00386 phyCtrl3Reg |= cPHY_CTRL3_TMR4CMP_EN; // enable TMR4 compare 00387 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg); 00388 00389 OSA_ExitCritical(kCriticalDisableInt); 00390 } 00391 00392 /*! ********************************************************************************* 00393 * \brief Check if TMR4 IRQ occured, and aknowledge it 00394 * 00395 * \return TRUE if TMR4 IRQ occured 00396 * 00397 ********************************************************************************** */ 00398 bool_t PhyTimeIsWakeUpTimeExpired 00399 ( 00400 void 00401 ) 00402 { 00403 bool_t wakeUpIrq = FALSE; 00404 uint8_t phyReg; 00405 00406 OSA_EnterCritical(kCriticalDisableInt); 00407 00408 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3); 00409 phyReg &= ~(cPHY_CTRL3_TMR4CMP_EN);// disable TMR4 compare 00410 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyReg); 00411 00412 phyReg = MCR20Drv_DirectAccessSPIRead(IRQSTS3); 00413 00414 if( (phyReg & cIRQSTS3_TMR4IRQ) == cIRQSTS3_TMR4IRQ ) 00415 { 00416 wakeUpIrq = TRUE; 00417 } 00418 00419 phyReg &= ~(cIRQSTS3_TMR4MSK); // unmask TMR4 interrupt 00420 phyReg &= 0xF0; // do not change other IRQs status 00421 phyReg |= (cIRQSTS3_TMR4IRQ); // aknowledge TMR2 IRQ 00422 00423 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, phyReg); 00424 00425 OSA_ExitCritical(kCriticalDisableInt); 00426 00427 return wakeUpIrq; 00428 } 00429 00430 00431 /*! ********************************************************************************* 00432 * \brief PHY Timer Interrupt Service Routine 00433 * 00434 ********************************************************************************** */ 00435 void PhyTime_ISR(void) 00436 { 00437 if( pNextEvent->callback == PhyTime_OverflowCB ) 00438 { 00439 gPhyTimerOverflow++; 00440 } 00441 00442 if( gpfPhyTimeNotify ) 00443 { 00444 gpfPhyTimeNotify(); 00445 } 00446 else 00447 { 00448 PhyTime_RunCallback(); 00449 PhyTime_Maintenance(); 00450 } 00451 } 00452 00453 /*! ********************************************************************************* 00454 * \brief Initialize the PHY Timer module 00455 * 00456 * \return phyTimeStatus_t 00457 * 00458 ********************************************************************************** */ 00459 phyTimeStatus_t PhyTime_TimerInit( void (*cb)(void) ) 00460 { 00461 if( gpfPhyTimeNotify ) 00462 return gPhyTimeError_c; 00463 00464 gpfPhyTimeNotify = cb; 00465 gPhyTimerOverflow = 0; 00466 FLib_MemSet( mPhyTimers, 0, sizeof(mPhyTimers) ); 00467 00468 /* Schedule Overflow Calback */ 00469 pNextEvent = &mPhyTimers[0]; 00470 pNextEvent->callback = PhyTime_OverflowCB; 00471 pNextEvent->timestamp = (gPhyTimerOverflow+1) << gPhyTimeShift_c; 00472 PhyTimeSetWaitTimeout( (uint32_t*)&pNextEvent->timestamp ); 00473 00474 return gPhyTimeOk_c; 00475 } 00476 00477 /*! ********************************************************************************* 00478 * \brief Returns a 64bit timestamp value to be used by the MAC Layer 00479 * 00480 * \return phyTimeTimestamp_t PHY timestamp 00481 * 00482 ********************************************************************************** */ 00483 phyTimeTimestamp_t PhyTime_GetTimestamp(void) 00484 { 00485 phyTimeTimestamp_t time = 0; 00486 00487 OSA_EnterCritical(kCriticalDisableInt); 00488 PhyTimeReadClock( (uint32_t*)&time ); 00489 time |= (gPhyTimerOverflow << gPhyTimeShift_c); 00490 OSA_ExitCritical(kCriticalDisableInt); 00491 00492 return time; 00493 } 00494 00495 /*! ********************************************************************************* 00496 * \brief Schedules an event 00497 * 00498 * \param[in] pEvent event to be scheduled 00499 * 00500 * \return phyTimeTimerId_t the id of the alocated timer 00501 * 00502 ********************************************************************************** */ 00503 phyTimeTimerId_t PhyTime_ScheduleEvent( phyTimeEvent_t *pEvent ) 00504 { 00505 phyTimeTimerId_t tmr; 00506 00507 /* Parameter validation */ 00508 if( NULL == pEvent->callback ) 00509 { 00510 return gInvalidTimerId_c; 00511 } 00512 00513 /* Search for a free slot (slot 0 is reserved for the Overflow calback) */ 00514 OSA_EnterCritical(kCriticalDisableInt); 00515 for( tmr=1; tmr<gMaxPhyTimers_c; tmr++ ) 00516 { 00517 if( mPhyTimers[tmr].callback == NULL ) 00518 { 00519 mPhyTimers[tmr] = *pEvent; 00520 break; 00521 } 00522 } 00523 OSA_ExitCritical(kCriticalDisableInt); 00524 00525 if( tmr >= gMaxPhyTimers_c ) 00526 return gInvalidTimerId_c; 00527 00528 /* Program the next event */ 00529 if((NULL == pNextEvent) || 00530 (NULL != pNextEvent && mPhyTimers[tmr].timestamp < pNextEvent->timestamp)) 00531 { 00532 PhyTime_Maintenance(); 00533 } 00534 00535 return tmr; 00536 } 00537 00538 /*! ********************************************************************************* 00539 * \brief Cancel an event 00540 * 00541 * \param[in] timerId the Id of the timer 00542 * 00543 * \return phyTimeStatus_t 00544 * 00545 ********************************************************************************** */ 00546 phyTimeStatus_t PhyTime_CancelEvent( phyTimeTimerId_t timerId ) 00547 { 00548 if( (timerId == 0) || (timerId >= gMaxPhyTimers_c) || (NULL == mPhyTimers[timerId].callback) ) 00549 { 00550 return gPhyTimeNotFound_c; 00551 } 00552 00553 OSA_EnterCritical(kCriticalDisableInt); 00554 if( pNextEvent == &mPhyTimers[timerId] ) 00555 pNextEvent = NULL; 00556 00557 mPhyTimers[timerId].callback = NULL; 00558 OSA_ExitCritical(kCriticalDisableInt); 00559 00560 return gPhyTimeOk_c; 00561 } 00562 00563 /*! ********************************************************************************* 00564 * \brief Cancel all event with the specified paameter 00565 * 00566 * \param[in] param event parameter 00567 * 00568 * \return phyTimeStatus_t 00569 * 00570 ********************************************************************************** */ 00571 phyTimeStatus_t PhyTime_CancelEventsWithParam ( uint32_t param ) 00572 { 00573 uint32_t i; 00574 phyTimeStatus_t status = gPhyTimeNotFound_c; 00575 00576 OSA_EnterCritical(kCriticalDisableInt); 00577 for( i=1; i<gMaxPhyTimers_c; i++ ) 00578 { 00579 if( mPhyTimers[i].callback && (param == mPhyTimers[i].parameter) ) 00580 { 00581 status = gPhyTimeOk_c; 00582 mPhyTimers[i].callback = NULL; 00583 if( pNextEvent == &mPhyTimers[i] ) 00584 pNextEvent = NULL; 00585 } 00586 } 00587 OSA_ExitCritical(kCriticalDisableInt); 00588 00589 return status; 00590 } 00591 00592 /*! ********************************************************************************* 00593 * \brief Run the callback for the recently expired event 00594 * 00595 ********************************************************************************** */ 00596 void PhyTime_RunCallback( void ) 00597 { 00598 uint32_t param; 00599 phyTimeCallback_t cb; 00600 00601 if( pNextEvent ) 00602 { 00603 OSA_EnterCritical(kCriticalDisableInt); 00604 00605 param = pNextEvent->parameter; 00606 cb = pNextEvent->callback; 00607 pNextEvent->callback = NULL; 00608 pNextEvent = NULL; 00609 00610 OSA_ExitCritical(kCriticalDisableInt); 00611 00612 cb(param); 00613 } 00614 } 00615 00616 /*! ********************************************************************************* 00617 * \brief Expire events too close to be scheduled. 00618 * Program the next event 00619 * 00620 ********************************************************************************** */ 00621 void PhyTime_Maintenance( void ) 00622 { 00623 phyTimeTimestamp_t currentTime; 00624 phyTimeEvent_t *pEv; 00625 00626 PhyTimeDisableWaitTimeout(); 00627 00628 while(1) 00629 { 00630 OSA_EnterCritical(kCriticalDisableInt); 00631 00632 pEv = PhyTime_GetNextEvent(); 00633 currentTime = PhyTime_GetTimestamp(); 00634 00635 /* Program next event if exists */ 00636 if( pEv ) 00637 { 00638 pNextEvent = pEv; 00639 00640 if( pEv->timestamp > (currentTime + gPhyTimeMinSetupTime_c) ) 00641 { 00642 PhyTimeSetWaitTimeout( (uint32_t*)&pEv->timestamp ); 00643 pEv = NULL; 00644 } 00645 } 00646 00647 OSA_ExitCritical(kCriticalDisableInt); 00648 00649 if( !pEv ) 00650 break; 00651 00652 PhyTime_RunCallback(); 00653 } 00654 00655 } 00656 00657 00658 /*! ********************************************************************************* 00659 * \brief Timer Overflow callback 00660 * 00661 * \param[in] param 00662 * 00663 ********************************************************************************** */ 00664 static void PhyTime_OverflowCB( uint32_t param ) 00665 { 00666 (void)param; 00667 00668 /* Reprogram the next overflow callback */ 00669 mPhyTimers[0].callback = PhyTime_OverflowCB; 00670 mPhyTimers[0].timestamp = (gPhyTimerOverflow+1) << 24; 00671 } 00672 00673 /*! ********************************************************************************* 00674 * \brief Search for the next event to be scheduled 00675 * 00676 * \return phyTimeEvent_t pointer to the next event to be scheduled 00677 * 00678 ********************************************************************************** */ 00679 static phyTimeEvent_t* PhyTime_GetNextEvent( void ) 00680 { 00681 phyTimeEvent_t *pEv = NULL; 00682 uint32_t i; 00683 00684 /* Search for the next event to be serviced */ 00685 for( i=0; i<gMaxPhyTimers_c; i++ ) 00686 { 00687 if( NULL != mPhyTimers[i].callback ) 00688 { 00689 if( NULL == pEv ) 00690 { 00691 pEv = &mPhyTimers[i]; 00692 } 00693 /* Check which event expires first */ 00694 else if( mPhyTimers[i].timestamp < pEv->timestamp ) 00695 { 00696 pEv = &mPhyTimers[i]; 00697 } 00698 } 00699 } 00700 00701 return pEv; 00702 }
Generated on Fri Jul 15 2022 21:41:17 by
