A library implementing IEEE 802.15.4 PHY functionality for the MCR20A transceiver. The PHY sublayer provides two services: the PHY data service and the PHY management service interfacing to the PHY sublayer management entity (PLME) service access point (SAP) (known as PLME-SAP). The PHY data service enables the transmission and reception of PHY protocol data units (PSDUs) over the media (radio).

Fork of fsl_phy_mcr20a by Freescale

The Freescale PHY Layer deals with the physical burst which is to be sent and/or received. It performs modulation and demodulation, transmitter and receiver switching, fragmentation, scrambling, interleaving, and error correction coding. The communication to the upper protocol layers is carried out through the Layer 1 Interface.

The PHY Layer is capable of executing the following sequences:

  • I (Idle)
  • R (Receive Sequence conditionally followed by a TxAck)
  • T (Transmit Sequence)
  • C (Standalone CCA)
  • CCCA (Continuous CCA)
  • TR (Transmit/Receive Sequence - transmit unconditionally followed by either an R or RxAck)

In addition to these sequences the PHY Layer also integrates a packet processor which determines whether the packet is MAC-compliant, and if it is, whether it is addressed to the end device. Another feature of the packet processor is Source Address Matching which can be viewed as an extension of packet filtering; however its function is very specific to its intended application (data-polling and indirect queue management by a PAN Coordinator).

Documentation

MCR20A PHY Reference Manual

Committer:
andreikovacs
Date:
Tue Aug 18 12:41:42 2015 +0000
Revision:
0:764779eedf2d
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andreikovacs 0:764779eedf2d 1 /*!
andreikovacs 0:764779eedf2d 2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
andreikovacs 0:764779eedf2d 3 * All rights reserved.
andreikovacs 0:764779eedf2d 4 *
andreikovacs 0:764779eedf2d 5 * \file PhyTime.c
andreikovacs 0:764779eedf2d 6 *
andreikovacs 0:764779eedf2d 7 * Redistribution and use in source and binary forms, with or without modification,
andreikovacs 0:764779eedf2d 8 * are permitted provided that the following conditions are met:
andreikovacs 0:764779eedf2d 9 *
andreikovacs 0:764779eedf2d 10 * o Redistributions of source code must retain the above copyright notice, this list
andreikovacs 0:764779eedf2d 11 * of conditions and the following disclaimer.
andreikovacs 0:764779eedf2d 12 *
andreikovacs 0:764779eedf2d 13 * o Redistributions in binary form must reproduce the above copyright notice, this
andreikovacs 0:764779eedf2d 14 * list of conditions and the following disclaimer in the documentation and/or
andreikovacs 0:764779eedf2d 15 * other materials provided with the distribution.
andreikovacs 0:764779eedf2d 16 *
andreikovacs 0:764779eedf2d 17 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
andreikovacs 0:764779eedf2d 18 * contributors may be used to endorse or promote products derived from this
andreikovacs 0:764779eedf2d 19 * software without specific prior written permission.
andreikovacs 0:764779eedf2d 20 *
andreikovacs 0:764779eedf2d 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
andreikovacs 0:764779eedf2d 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
andreikovacs 0:764779eedf2d 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
andreikovacs 0:764779eedf2d 24 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
andreikovacs 0:764779eedf2d 25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
andreikovacs 0:764779eedf2d 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
andreikovacs 0:764779eedf2d 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
andreikovacs 0:764779eedf2d 28 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
andreikovacs 0:764779eedf2d 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
andreikovacs 0:764779eedf2d 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
andreikovacs 0:764779eedf2d 31 */
andreikovacs 0:764779eedf2d 32
andreikovacs 0:764779eedf2d 33
andreikovacs 0:764779eedf2d 34 /************************************************************************************
andreikovacs 0:764779eedf2d 35 *************************************************************************************
andreikovacs 0:764779eedf2d 36 * Include
andreikovacs 0:764779eedf2d 37 *************************************************************************************
andreikovacs 0:764779eedf2d 38 ************************************************************************************/
andreikovacs 0:764779eedf2d 39 #include "EmbeddedTypes.h"
andreikovacs 0:764779eedf2d 40 //#include "fsl_os_abstraction.h"
andreikovacs 0:764779eedf2d 41 #include "MCR20Drv.h"
andreikovacs 0:764779eedf2d 42 #include "MCR20Reg.h"
andreikovacs 0:764779eedf2d 43 #include "Phy.h"
andreikovacs 0:764779eedf2d 44
andreikovacs 0:764779eedf2d 45 #include "FunctionLib.h"
andreikovacs 0:764779eedf2d 46
andreikovacs 0:764779eedf2d 47 /************************************************************************************
andreikovacs 0:764779eedf2d 48 *************************************************************************************
andreikovacs 0:764779eedf2d 49 * Private macros
andreikovacs 0:764779eedf2d 50 *************************************************************************************
andreikovacs 0:764779eedf2d 51 ************************************************************************************/
andreikovacs 0:764779eedf2d 52 #define gPhyTimeMinSetupTime_c (10) /* symbols */
andreikovacs 0:764779eedf2d 53
andreikovacs 0:764779eedf2d 54 /************************************************************************************
andreikovacs 0:764779eedf2d 55 *************************************************************************************
andreikovacs 0:764779eedf2d 56 * Public memory declarations
andreikovacs 0:764779eedf2d 57 *************************************************************************************
andreikovacs 0:764779eedf2d 58 ************************************************************************************/
andreikovacs 0:764779eedf2d 59 void (*gpfPhyTimeNotify)(void) = NULL;
andreikovacs 0:764779eedf2d 60
andreikovacs 0:764779eedf2d 61 /************************************************************************************
andreikovacs 0:764779eedf2d 62 *************************************************************************************
andreikovacs 0:764779eedf2d 63 * Private memory declarations
andreikovacs 0:764779eedf2d 64 *************************************************************************************
andreikovacs 0:764779eedf2d 65 ************************************************************************************/
andreikovacs 0:764779eedf2d 66 static phyTimeEvent_t mPhyTimers[gMaxPhyTimers_c];
andreikovacs 0:764779eedf2d 67 static phyTimeEvent_t *pNextEvent;
andreikovacs 0:764779eedf2d 68 volatile uint32_t mPhySeqTimeout;
andreikovacs 0:764779eedf2d 69 volatile uint64_t gPhyTimerOverflow;
andreikovacs 0:764779eedf2d 70
andreikovacs 0:764779eedf2d 71 /************************************************************************************
andreikovacs 0:764779eedf2d 72 *************************************************************************************
andreikovacs 0:764779eedf2d 73 * Private prototypes
andreikovacs 0:764779eedf2d 74 *************************************************************************************
andreikovacs 0:764779eedf2d 75 ************************************************************************************/
andreikovacs 0:764779eedf2d 76 static void PhyTime_OverflowCB( uint32_t param );
andreikovacs 0:764779eedf2d 77 static phyTimeEvent_t* PhyTime_GetNextEvent( void );
andreikovacs 0:764779eedf2d 78
andreikovacs 0:764779eedf2d 79 /************************************************************************************
andreikovacs 0:764779eedf2d 80 *************************************************************************************
andreikovacs 0:764779eedf2d 81 * Public functions
andreikovacs 0:764779eedf2d 82 *************************************************************************************
andreikovacs 0:764779eedf2d 83 ************************************************************************************/
andreikovacs 0:764779eedf2d 84
andreikovacs 0:764779eedf2d 85 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 86 * \brief Sets the start time of a sequence
andreikovacs 0:764779eedf2d 87 *
andreikovacs 0:764779eedf2d 88 * \param[in] startTime the start time for a sequence
andreikovacs 0:764779eedf2d 89 *
andreikovacs 0:764779eedf2d 90 ********************************************************************************** */
andreikovacs 0:764779eedf2d 91 void PhyTimeSetEventTrigger
andreikovacs 0:764779eedf2d 92 (
andreikovacs 0:764779eedf2d 93 uint32_t startTime
andreikovacs 0:764779eedf2d 94 )
andreikovacs 0:764779eedf2d 95 {
andreikovacs 0:764779eedf2d 96 uint8_t phyReg, phyCtrl3Reg;
andreikovacs 0:764779eedf2d 97
andreikovacs 0:764779eedf2d 98 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 99
andreikovacs 0:764779eedf2d 100 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL1);
andreikovacs 0:764779eedf2d 101 phyReg |= cPHY_CTRL1_TMRTRIGEN; // enable autosequence start by TC2 match
andreikovacs 0:764779eedf2d 102 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL1, phyReg);
andreikovacs 0:764779eedf2d 103
andreikovacs 0:764779eedf2d 104 phyCtrl3Reg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3);
andreikovacs 0:764779eedf2d 105 phyCtrl3Reg &= ~(cPHY_CTRL3_TMR2CMP_EN);// disable TMR2 compare
andreikovacs 0:764779eedf2d 106 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg);
andreikovacs 0:764779eedf2d 107
andreikovacs 0:764779eedf2d 108 MCR20Drv_DirectAccessSPIMultiByteWrite( (uint8_t) T2PRIMECMP_LSB, (uint8_t *) &startTime, 2);
andreikovacs 0:764779eedf2d 109
andreikovacs 0:764779eedf2d 110 phyReg = MCR20Drv_DirectAccessSPIRead(IRQSTS3);
andreikovacs 0:764779eedf2d 111 phyReg &= 0xF0; // do not change other IRQs status
andreikovacs 0:764779eedf2d 112 phyReg &= ~(cIRQSTS3_TMR2MSK); // unmask TMR2 interrupt
andreikovacs 0:764779eedf2d 113 phyReg |= (cIRQSTS3_TMR2IRQ); // aknowledge TMR2 IRQ
andreikovacs 0:764779eedf2d 114 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, phyReg);
andreikovacs 0:764779eedf2d 115
andreikovacs 0:764779eedf2d 116 // TC2PRIME_EN must be enabled in PHY_CTRL4 register
andreikovacs 0:764779eedf2d 117 phyCtrl3Reg |= cPHY_CTRL3_TMR2CMP_EN; // enable TMR2 compare
andreikovacs 0:764779eedf2d 118 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg);
andreikovacs 0:764779eedf2d 119
andreikovacs 0:764779eedf2d 120 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 121 }
andreikovacs 0:764779eedf2d 122
andreikovacs 0:764779eedf2d 123 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 124 * \brief Disable the time trigger for a sequence.
andreikovacs 0:764779eedf2d 125 *
andreikovacs 0:764779eedf2d 126 * \remarks The sequence will start asap
andreikovacs 0:764779eedf2d 127 *
andreikovacs 0:764779eedf2d 128 ********************************************************************************** */
andreikovacs 0:764779eedf2d 129 void PhyTimeDisableEventTrigger
andreikovacs 0:764779eedf2d 130 (
andreikovacs 0:764779eedf2d 131 void
andreikovacs 0:764779eedf2d 132 )
andreikovacs 0:764779eedf2d 133 {
andreikovacs 0:764779eedf2d 134 uint8_t phyReg;
andreikovacs 0:764779eedf2d 135
andreikovacs 0:764779eedf2d 136 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 137
andreikovacs 0:764779eedf2d 138 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL1);
andreikovacs 0:764779eedf2d 139 phyReg &= ~(cPHY_CTRL1_TMRTRIGEN); // disable autosequence start by TC2 match
andreikovacs 0:764779eedf2d 140 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL1, phyReg);
andreikovacs 0:764779eedf2d 141
andreikovacs 0:764779eedf2d 142 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3);
andreikovacs 0:764779eedf2d 143 phyReg &= ~(cPHY_CTRL3_TMR2CMP_EN);// disable TMR2 compare
andreikovacs 0:764779eedf2d 144 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyReg);
andreikovacs 0:764779eedf2d 145
andreikovacs 0:764779eedf2d 146 phyReg = MCR20Drv_DirectAccessSPIRead(IRQSTS3);
andreikovacs 0:764779eedf2d 147 phyReg &= 0xF0; // do not change other IRQs status
andreikovacs 0:764779eedf2d 148 phyReg |= (cIRQSTS3_TMR2MSK); // mask TMR2 interrupt
andreikovacs 0:764779eedf2d 149 phyReg |= (cIRQSTS3_TMR2IRQ); // aknowledge TMR2 IRQ
andreikovacs 0:764779eedf2d 150 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, phyReg);
andreikovacs 0:764779eedf2d 151
andreikovacs 0:764779eedf2d 152 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 153 }
andreikovacs 0:764779eedf2d 154
andreikovacs 0:764779eedf2d 155 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 156 * \brief Sets the timeout value for a sequence
andreikovacs 0:764779eedf2d 157 *
andreikovacs 0:764779eedf2d 158 * \param[in] pEndTime the absolute time when a sequence should terminate
andreikovacs 0:764779eedf2d 159 *
andreikovacs 0:764779eedf2d 160 * \remarks If the sequence does not finish until the timeout, it will be aborted
andreikovacs 0:764779eedf2d 161 *
andreikovacs 0:764779eedf2d 162 ********************************************************************************** */
andreikovacs 0:764779eedf2d 163 void PhyTimeSetEventTimeout
andreikovacs 0:764779eedf2d 164 (
andreikovacs 0:764779eedf2d 165 uint32_t *pEndTime
andreikovacs 0:764779eedf2d 166 )
andreikovacs 0:764779eedf2d 167 {
andreikovacs 0:764779eedf2d 168 uint8_t phyReg, phyCtrl3Reg;
andreikovacs 0:764779eedf2d 169
andreikovacs 0:764779eedf2d 170 #ifdef PHY_PARAMETERS_VALIDATION
andreikovacs 0:764779eedf2d 171 if(NULL == pEndTime)
andreikovacs 0:764779eedf2d 172 {
andreikovacs 0:764779eedf2d 173 return;
andreikovacs 0:764779eedf2d 174 }
andreikovacs 0:764779eedf2d 175 #endif // PHY_PARAMETERS_VALIDATION
andreikovacs 0:764779eedf2d 176
andreikovacs 0:764779eedf2d 177 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 178
andreikovacs 0:764779eedf2d 179 phyCtrl3Reg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3);
andreikovacs 0:764779eedf2d 180 phyCtrl3Reg &= ~(cPHY_CTRL3_TMR3CMP_EN);// disable TMR3 compare
andreikovacs 0:764779eedf2d 181 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg);
andreikovacs 0:764779eedf2d 182
andreikovacs 0:764779eedf2d 183 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL4);
andreikovacs 0:764779eedf2d 184 phyReg |= cPHY_CTRL4_TC3TMOUT; // enable autosequence stop by TC3 match
andreikovacs 0:764779eedf2d 185 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL4, phyReg);
andreikovacs 0:764779eedf2d 186
andreikovacs 0:764779eedf2d 187 mPhySeqTimeout = *pEndTime & 0x00FFFFFF;
andreikovacs 0:764779eedf2d 188 MCR20Drv_DirectAccessSPIMultiByteWrite( (uint8_t) T3CMP_LSB, (uint8_t *) pEndTime, 3);
andreikovacs 0:764779eedf2d 189
andreikovacs 0:764779eedf2d 190 phyReg = MCR20Drv_DirectAccessSPIRead(IRQSTS3);
andreikovacs 0:764779eedf2d 191 phyReg &= 0xF0; // do not change IRQ status
andreikovacs 0:764779eedf2d 192 // phyReg &= ~(cIRQSTS3_TMR3MSK); // unmask TMR3 interrupt
andreikovacs 0:764779eedf2d 193 phyReg |= (cIRQSTS3_TMR3IRQ); // aknowledge TMR3 IRQ
andreikovacs 0:764779eedf2d 194 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, phyReg);
andreikovacs 0:764779eedf2d 195
andreikovacs 0:764779eedf2d 196 phyCtrl3Reg |= cPHY_CTRL3_TMR3CMP_EN; // enable TMR3 compare
andreikovacs 0:764779eedf2d 197 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg);
andreikovacs 0:764779eedf2d 198
andreikovacs 0:764779eedf2d 199 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 200 }
andreikovacs 0:764779eedf2d 201
andreikovacs 0:764779eedf2d 202 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 203 * \brief Return the timeout value for the current sequence
andreikovacs 0:764779eedf2d 204 *
andreikovacs 0:764779eedf2d 205 * \return uint32_t the timeout value
andreikovacs 0:764779eedf2d 206 *
andreikovacs 0:764779eedf2d 207 ********************************************************************************** */
andreikovacs 0:764779eedf2d 208 uint32_t PhyTimeGetEventTimeout( void )
andreikovacs 0:764779eedf2d 209 {
andreikovacs 0:764779eedf2d 210 return mPhySeqTimeout;
andreikovacs 0:764779eedf2d 211 }
andreikovacs 0:764779eedf2d 212
andreikovacs 0:764779eedf2d 213 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 214 * \brief Disables the sequence timeout
andreikovacs 0:764779eedf2d 215 *
andreikovacs 0:764779eedf2d 216 ********************************************************************************** */
andreikovacs 0:764779eedf2d 217 void PhyTimeDisableEventTimeout
andreikovacs 0:764779eedf2d 218 (
andreikovacs 0:764779eedf2d 219 void
andreikovacs 0:764779eedf2d 220 )
andreikovacs 0:764779eedf2d 221 {
andreikovacs 0:764779eedf2d 222 uint8_t phyReg;
andreikovacs 0:764779eedf2d 223
andreikovacs 0:764779eedf2d 224 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 225
andreikovacs 0:764779eedf2d 226 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL4);
andreikovacs 0:764779eedf2d 227 phyReg &= ~(cPHY_CTRL4_TC3TMOUT); // disable autosequence stop by TC3 match
andreikovacs 0:764779eedf2d 228 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL4, phyReg);
andreikovacs 0:764779eedf2d 229
andreikovacs 0:764779eedf2d 230 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3);
andreikovacs 0:764779eedf2d 231 phyReg &= ~(cPHY_CTRL3_TMR3CMP_EN);// disable TMR3 compare
andreikovacs 0:764779eedf2d 232 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyReg);
andreikovacs 0:764779eedf2d 233
andreikovacs 0:764779eedf2d 234 phyReg = MCR20Drv_DirectAccessSPIRead(IRQSTS3);
andreikovacs 0:764779eedf2d 235 phyReg &= 0xF0; // do not change IRQ status
andreikovacs 0:764779eedf2d 236 phyReg |= cIRQSTS3_TMR3IRQ; // aknowledge TMR3 IRQ
andreikovacs 0:764779eedf2d 237 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, phyReg);
andreikovacs 0:764779eedf2d 238
andreikovacs 0:764779eedf2d 239 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 240 }
andreikovacs 0:764779eedf2d 241
andreikovacs 0:764779eedf2d 242 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 243 * \brief Reads the absolute clock from the radio
andreikovacs 0:764779eedf2d 244 *
andreikovacs 0:764779eedf2d 245 * \param[out] pRetClk pointer to a location where the current clock will be stored
andreikovacs 0:764779eedf2d 246 *
andreikovacs 0:764779eedf2d 247 ********************************************************************************** */
andreikovacs 0:764779eedf2d 248 void PhyTimeReadClock
andreikovacs 0:764779eedf2d 249 (
andreikovacs 0:764779eedf2d 250 uint32_t *pRetClk
andreikovacs 0:764779eedf2d 251 )
andreikovacs 0:764779eedf2d 252 {
andreikovacs 0:764779eedf2d 253 #ifdef PHY_PARAMETERS_VALIDATION
andreikovacs 0:764779eedf2d 254 if(NULL == pRetClk)
andreikovacs 0:764779eedf2d 255 {
andreikovacs 0:764779eedf2d 256 return;
andreikovacs 0:764779eedf2d 257 }
andreikovacs 0:764779eedf2d 258 #endif // PHY_PARAMETERS_VALIDATION
andreikovacs 0:764779eedf2d 259
andreikovacs 0:764779eedf2d 260 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 261
andreikovacs 0:764779eedf2d 262 MCR20Drv_DirectAccessSPIMultiByteRead( (uint8_t) EVENT_TMR_LSB, (uint8_t *) pRetClk, 3);
andreikovacs 0:764779eedf2d 263 *(((uint8_t *)pRetClk) + 3) = 0;
andreikovacs 0:764779eedf2d 264
andreikovacs 0:764779eedf2d 265 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 266
andreikovacs 0:764779eedf2d 267 }
andreikovacs 0:764779eedf2d 268
andreikovacs 0:764779eedf2d 269 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 270 * \brief Initialize the Event Timer
andreikovacs 0:764779eedf2d 271 *
andreikovacs 0:764779eedf2d 272 * \param[in] pAbsTime pointer to the location where the new time is stored
andreikovacs 0:764779eedf2d 273 *
andreikovacs 0:764779eedf2d 274 ********************************************************************************** */
andreikovacs 0:764779eedf2d 275 void PhyTimeInitEventTimer
andreikovacs 0:764779eedf2d 276 (
andreikovacs 0:764779eedf2d 277 uint32_t *pAbsTime
andreikovacs 0:764779eedf2d 278 )
andreikovacs 0:764779eedf2d 279 {
andreikovacs 0:764779eedf2d 280 uint8_t phyCtrl4Reg;
andreikovacs 0:764779eedf2d 281
andreikovacs 0:764779eedf2d 282 #ifdef PHY_PARAMETERS_VALIDATION
andreikovacs 0:764779eedf2d 283 if(NULL == pAbsTime)
andreikovacs 0:764779eedf2d 284 {
andreikovacs 0:764779eedf2d 285 return;
andreikovacs 0:764779eedf2d 286 }
andreikovacs 0:764779eedf2d 287 #endif // PHY_PARAMETERS_VALIDATION
andreikovacs 0:764779eedf2d 288
andreikovacs 0:764779eedf2d 289 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 290
andreikovacs 0:764779eedf2d 291 phyCtrl4Reg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL4);
andreikovacs 0:764779eedf2d 292 phyCtrl4Reg |= cPHY_CTRL4_TMRLOAD; // self clearing bit
andreikovacs 0:764779eedf2d 293
andreikovacs 0:764779eedf2d 294 MCR20Drv_DirectAccessSPIMultiByteWrite( (uint8_t) T1CMP_LSB, (uint8_t *) pAbsTime, 3);
andreikovacs 0:764779eedf2d 295 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL4, phyCtrl4Reg);
andreikovacs 0:764779eedf2d 296
andreikovacs 0:764779eedf2d 297 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 298 }
andreikovacs 0:764779eedf2d 299
andreikovacs 0:764779eedf2d 300 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 301 * \brief Set TMR1 timeout value
andreikovacs 0:764779eedf2d 302 *
andreikovacs 0:764779eedf2d 303 * \param[in] pWaitTimeout the timeout value
andreikovacs 0:764779eedf2d 304 *
andreikovacs 0:764779eedf2d 305 ********************************************************************************** */
andreikovacs 0:764779eedf2d 306 void PhyTimeSetWaitTimeout
andreikovacs 0:764779eedf2d 307 (
andreikovacs 0:764779eedf2d 308 uint32_t *pWaitTimeout
andreikovacs 0:764779eedf2d 309 )
andreikovacs 0:764779eedf2d 310 {
andreikovacs 0:764779eedf2d 311 uint8_t phyCtrl3Reg, irqSts3Reg;
andreikovacs 0:764779eedf2d 312
andreikovacs 0:764779eedf2d 313 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 314
andreikovacs 0:764779eedf2d 315 phyCtrl3Reg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3);
andreikovacs 0:764779eedf2d 316 phyCtrl3Reg &= ~(cPHY_CTRL3_TMR1CMP_EN);// disable TMR1 compare
andreikovacs 0:764779eedf2d 317 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg);
andreikovacs 0:764779eedf2d 318
andreikovacs 0:764779eedf2d 319 MCR20Drv_DirectAccessSPIMultiByteWrite( (uint8_t) T1CMP_LSB, (uint8_t *) pWaitTimeout, 3);
andreikovacs 0:764779eedf2d 320
andreikovacs 0:764779eedf2d 321 irqSts3Reg = MCR20Drv_DirectAccessSPIRead(IRQSTS3);
andreikovacs 0:764779eedf2d 322 irqSts3Reg &= ~(cIRQSTS3_TMR1MSK); // unmask TMR1 interrupt
andreikovacs 0:764779eedf2d 323 irqSts3Reg &= 0xF0; // do not change other IRQs status
andreikovacs 0:764779eedf2d 324 irqSts3Reg |= (cIRQSTS3_TMR1IRQ); // aknowledge TMR1 IRQ
andreikovacs 0:764779eedf2d 325 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, irqSts3Reg);
andreikovacs 0:764779eedf2d 326
andreikovacs 0:764779eedf2d 327 phyCtrl3Reg |= cPHY_CTRL3_TMR1CMP_EN; // enable TMR1 compare
andreikovacs 0:764779eedf2d 328 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg);
andreikovacs 0:764779eedf2d 329
andreikovacs 0:764779eedf2d 330 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 331
andreikovacs 0:764779eedf2d 332 }
andreikovacs 0:764779eedf2d 333
andreikovacs 0:764779eedf2d 334 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 335 * \brief Disable the TMR1 timeout
andreikovacs 0:764779eedf2d 336 *
andreikovacs 0:764779eedf2d 337 ********************************************************************************** */
andreikovacs 0:764779eedf2d 338 void PhyTimeDisableWaitTimeout
andreikovacs 0:764779eedf2d 339 (
andreikovacs 0:764779eedf2d 340 void
andreikovacs 0:764779eedf2d 341 )
andreikovacs 0:764779eedf2d 342 {
andreikovacs 0:764779eedf2d 343 uint8_t phyReg;
andreikovacs 0:764779eedf2d 344
andreikovacs 0:764779eedf2d 345 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 346
andreikovacs 0:764779eedf2d 347 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3);
andreikovacs 0:764779eedf2d 348 phyReg &= ~(cPHY_CTRL3_TMR1CMP_EN);// disable TMR1 compare
andreikovacs 0:764779eedf2d 349 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyReg);
andreikovacs 0:764779eedf2d 350
andreikovacs 0:764779eedf2d 351 phyReg = MCR20Drv_DirectAccessSPIRead(IRQSTS3);
andreikovacs 0:764779eedf2d 352 phyReg &= 0xF0; // do not change IRQ status
andreikovacs 0:764779eedf2d 353 phyReg |= cIRQSTS3_TMR1IRQ; // aknowledge TMR1 IRQ
andreikovacs 0:764779eedf2d 354 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, phyReg);
andreikovacs 0:764779eedf2d 355
andreikovacs 0:764779eedf2d 356 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 357 }
andreikovacs 0:764779eedf2d 358
andreikovacs 0:764779eedf2d 359 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 360 * \brief Set TMR4 timeout value
andreikovacs 0:764779eedf2d 361 *
andreikovacs 0:764779eedf2d 362 * \param[in] pWakeUpTime absolute time
andreikovacs 0:764779eedf2d 363 *
andreikovacs 0:764779eedf2d 364 ********************************************************************************** */
andreikovacs 0:764779eedf2d 365 void PhyTimeSetWakeUpTime
andreikovacs 0:764779eedf2d 366 (
andreikovacs 0:764779eedf2d 367 uint32_t *pWakeUpTime
andreikovacs 0:764779eedf2d 368 )
andreikovacs 0:764779eedf2d 369 {
andreikovacs 0:764779eedf2d 370 uint8_t phyCtrl3Reg, irqSts3Reg;
andreikovacs 0:764779eedf2d 371
andreikovacs 0:764779eedf2d 372 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 373
andreikovacs 0:764779eedf2d 374 phyCtrl3Reg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3);
andreikovacs 0:764779eedf2d 375 // phyCtrl3Reg &= ~(cPHY_CTRL3_TMR4CMP_EN);// disable TMR4 compare
andreikovacs 0:764779eedf2d 376 // MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg);
andreikovacs 0:764779eedf2d 377
andreikovacs 0:764779eedf2d 378 MCR20Drv_DirectAccessSPIMultiByteWrite( (uint8_t) T4CMP_LSB, (uint8_t *) pWakeUpTime, 3);
andreikovacs 0:764779eedf2d 379
andreikovacs 0:764779eedf2d 380 irqSts3Reg = MCR20Drv_DirectAccessSPIRead(IRQSTS3);
andreikovacs 0:764779eedf2d 381 irqSts3Reg &= ~(cIRQSTS3_TMR4MSK); // unmask TMR4 interrupt
andreikovacs 0:764779eedf2d 382 irqSts3Reg &= 0xF0; // do not change other IRQs status
andreikovacs 0:764779eedf2d 383 irqSts3Reg |= (cIRQSTS3_TMR4IRQ); // aknowledge TMR4 IRQ
andreikovacs 0:764779eedf2d 384 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, irqSts3Reg);
andreikovacs 0:764779eedf2d 385
andreikovacs 0:764779eedf2d 386 phyCtrl3Reg |= cPHY_CTRL3_TMR4CMP_EN; // enable TMR4 compare
andreikovacs 0:764779eedf2d 387 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyCtrl3Reg);
andreikovacs 0:764779eedf2d 388
andreikovacs 0:764779eedf2d 389 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 390 }
andreikovacs 0:764779eedf2d 391
andreikovacs 0:764779eedf2d 392 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 393 * \brief Check if TMR4 IRQ occured, and aknowledge it
andreikovacs 0:764779eedf2d 394 *
andreikovacs 0:764779eedf2d 395 * \return TRUE if TMR4 IRQ occured
andreikovacs 0:764779eedf2d 396 *
andreikovacs 0:764779eedf2d 397 ********************************************************************************** */
andreikovacs 0:764779eedf2d 398 bool_t PhyTimeIsWakeUpTimeExpired
andreikovacs 0:764779eedf2d 399 (
andreikovacs 0:764779eedf2d 400 void
andreikovacs 0:764779eedf2d 401 )
andreikovacs 0:764779eedf2d 402 {
andreikovacs 0:764779eedf2d 403 bool_t wakeUpIrq = FALSE;
andreikovacs 0:764779eedf2d 404 uint8_t phyReg;
andreikovacs 0:764779eedf2d 405
andreikovacs 0:764779eedf2d 406 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 407
andreikovacs 0:764779eedf2d 408 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL3);
andreikovacs 0:764779eedf2d 409 phyReg &= ~(cPHY_CTRL3_TMR4CMP_EN);// disable TMR4 compare
andreikovacs 0:764779eedf2d 410 MCR20Drv_DirectAccessSPIWrite( (uint8_t) PHY_CTRL3, phyReg);
andreikovacs 0:764779eedf2d 411
andreikovacs 0:764779eedf2d 412 phyReg = MCR20Drv_DirectAccessSPIRead(IRQSTS3);
andreikovacs 0:764779eedf2d 413
andreikovacs 0:764779eedf2d 414 if( (phyReg & cIRQSTS3_TMR4IRQ) == cIRQSTS3_TMR4IRQ )
andreikovacs 0:764779eedf2d 415 {
andreikovacs 0:764779eedf2d 416 wakeUpIrq = TRUE;
andreikovacs 0:764779eedf2d 417 }
andreikovacs 0:764779eedf2d 418
andreikovacs 0:764779eedf2d 419 phyReg &= ~(cIRQSTS3_TMR4MSK); // unmask TMR4 interrupt
andreikovacs 0:764779eedf2d 420 phyReg &= 0xF0; // do not change other IRQs status
andreikovacs 0:764779eedf2d 421 phyReg |= (cIRQSTS3_TMR4IRQ); // aknowledge TMR2 IRQ
andreikovacs 0:764779eedf2d 422
andreikovacs 0:764779eedf2d 423 MCR20Drv_DirectAccessSPIWrite( (uint8_t) IRQSTS3, phyReg);
andreikovacs 0:764779eedf2d 424
andreikovacs 0:764779eedf2d 425 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 426
andreikovacs 0:764779eedf2d 427 return wakeUpIrq;
andreikovacs 0:764779eedf2d 428 }
andreikovacs 0:764779eedf2d 429
andreikovacs 0:764779eedf2d 430
andreikovacs 0:764779eedf2d 431 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 432 * \brief PHY Timer Interrupt Service Routine
andreikovacs 0:764779eedf2d 433 *
andreikovacs 0:764779eedf2d 434 ********************************************************************************** */
andreikovacs 0:764779eedf2d 435 void PhyTime_ISR(void)
andreikovacs 0:764779eedf2d 436 {
andreikovacs 0:764779eedf2d 437 if( pNextEvent->callback == PhyTime_OverflowCB )
andreikovacs 0:764779eedf2d 438 {
andreikovacs 0:764779eedf2d 439 gPhyTimerOverflow++;
andreikovacs 0:764779eedf2d 440 }
andreikovacs 0:764779eedf2d 441
andreikovacs 0:764779eedf2d 442 if( gpfPhyTimeNotify )
andreikovacs 0:764779eedf2d 443 {
andreikovacs 0:764779eedf2d 444 gpfPhyTimeNotify();
andreikovacs 0:764779eedf2d 445 }
andreikovacs 0:764779eedf2d 446 else
andreikovacs 0:764779eedf2d 447 {
andreikovacs 0:764779eedf2d 448 PhyTime_RunCallback();
andreikovacs 0:764779eedf2d 449 PhyTime_Maintenance();
andreikovacs 0:764779eedf2d 450 }
andreikovacs 0:764779eedf2d 451 }
andreikovacs 0:764779eedf2d 452
andreikovacs 0:764779eedf2d 453 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 454 * \brief Initialize the PHY Timer module
andreikovacs 0:764779eedf2d 455 *
andreikovacs 0:764779eedf2d 456 * \return phyTimeStatus_t
andreikovacs 0:764779eedf2d 457 *
andreikovacs 0:764779eedf2d 458 ********************************************************************************** */
andreikovacs 0:764779eedf2d 459 phyTimeStatus_t PhyTime_TimerInit( void (*cb)(void) )
andreikovacs 0:764779eedf2d 460 {
andreikovacs 0:764779eedf2d 461 if( gpfPhyTimeNotify )
andreikovacs 0:764779eedf2d 462 return gPhyTimeError_c;
andreikovacs 0:764779eedf2d 463
andreikovacs 0:764779eedf2d 464 gpfPhyTimeNotify = cb;
andreikovacs 0:764779eedf2d 465 gPhyTimerOverflow = 0;
andreikovacs 0:764779eedf2d 466 FLib_MemSet( mPhyTimers, 0, sizeof(mPhyTimers) );
andreikovacs 0:764779eedf2d 467
andreikovacs 0:764779eedf2d 468 /* Schedule Overflow Calback */
andreikovacs 0:764779eedf2d 469 pNextEvent = &mPhyTimers[0];
andreikovacs 0:764779eedf2d 470 pNextEvent->callback = PhyTime_OverflowCB;
andreikovacs 0:764779eedf2d 471 pNextEvent->timestamp = (gPhyTimerOverflow+1) << gPhyTimeShift_c;
andreikovacs 0:764779eedf2d 472 PhyTimeSetWaitTimeout( (uint32_t*)&pNextEvent->timestamp );
andreikovacs 0:764779eedf2d 473
andreikovacs 0:764779eedf2d 474 return gPhyTimeOk_c;
andreikovacs 0:764779eedf2d 475 }
andreikovacs 0:764779eedf2d 476
andreikovacs 0:764779eedf2d 477 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 478 * \brief Returns a 64bit timestamp value to be used by the MAC Layer
andreikovacs 0:764779eedf2d 479 *
andreikovacs 0:764779eedf2d 480 * \return phyTimeTimestamp_t PHY timestamp
andreikovacs 0:764779eedf2d 481 *
andreikovacs 0:764779eedf2d 482 ********************************************************************************** */
andreikovacs 0:764779eedf2d 483 phyTimeTimestamp_t PhyTime_GetTimestamp(void)
andreikovacs 0:764779eedf2d 484 {
andreikovacs 0:764779eedf2d 485 phyTimeTimestamp_t time = 0;
andreikovacs 0:764779eedf2d 486
andreikovacs 0:764779eedf2d 487 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 488 PhyTimeReadClock( (uint32_t*)&time );
andreikovacs 0:764779eedf2d 489 time |= (gPhyTimerOverflow << gPhyTimeShift_c);
andreikovacs 0:764779eedf2d 490 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 491
andreikovacs 0:764779eedf2d 492 return time;
andreikovacs 0:764779eedf2d 493 }
andreikovacs 0:764779eedf2d 494
andreikovacs 0:764779eedf2d 495 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 496 * \brief Schedules an event
andreikovacs 0:764779eedf2d 497 *
andreikovacs 0:764779eedf2d 498 * \param[in] pEvent event to be scheduled
andreikovacs 0:764779eedf2d 499 *
andreikovacs 0:764779eedf2d 500 * \return phyTimeTimerId_t the id of the alocated timer
andreikovacs 0:764779eedf2d 501 *
andreikovacs 0:764779eedf2d 502 ********************************************************************************** */
andreikovacs 0:764779eedf2d 503 phyTimeTimerId_t PhyTime_ScheduleEvent( phyTimeEvent_t *pEvent )
andreikovacs 0:764779eedf2d 504 {
andreikovacs 0:764779eedf2d 505 phyTimeTimerId_t tmr;
andreikovacs 0:764779eedf2d 506
andreikovacs 0:764779eedf2d 507 /* Parameter validation */
andreikovacs 0:764779eedf2d 508 if( NULL == pEvent->callback )
andreikovacs 0:764779eedf2d 509 {
andreikovacs 0:764779eedf2d 510 return gInvalidTimerId_c;
andreikovacs 0:764779eedf2d 511 }
andreikovacs 0:764779eedf2d 512
andreikovacs 0:764779eedf2d 513 /* Search for a free slot (slot 0 is reserved for the Overflow calback) */
andreikovacs 0:764779eedf2d 514 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 515 for( tmr=1; tmr<gMaxPhyTimers_c; tmr++ )
andreikovacs 0:764779eedf2d 516 {
andreikovacs 0:764779eedf2d 517 if( mPhyTimers[tmr].callback == NULL )
andreikovacs 0:764779eedf2d 518 {
andreikovacs 0:764779eedf2d 519 mPhyTimers[tmr] = *pEvent;
andreikovacs 0:764779eedf2d 520 break;
andreikovacs 0:764779eedf2d 521 }
andreikovacs 0:764779eedf2d 522 }
andreikovacs 0:764779eedf2d 523 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 524
andreikovacs 0:764779eedf2d 525 if( tmr >= gMaxPhyTimers_c )
andreikovacs 0:764779eedf2d 526 return gInvalidTimerId_c;
andreikovacs 0:764779eedf2d 527
andreikovacs 0:764779eedf2d 528 /* Program the next event */
andreikovacs 0:764779eedf2d 529 if((NULL == pNextEvent) ||
andreikovacs 0:764779eedf2d 530 (NULL != pNextEvent && mPhyTimers[tmr].timestamp < pNextEvent->timestamp))
andreikovacs 0:764779eedf2d 531 {
andreikovacs 0:764779eedf2d 532 PhyTime_Maintenance();
andreikovacs 0:764779eedf2d 533 }
andreikovacs 0:764779eedf2d 534
andreikovacs 0:764779eedf2d 535 return tmr;
andreikovacs 0:764779eedf2d 536 }
andreikovacs 0:764779eedf2d 537
andreikovacs 0:764779eedf2d 538 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 539 * \brief Cancel an event
andreikovacs 0:764779eedf2d 540 *
andreikovacs 0:764779eedf2d 541 * \param[in] timerId the Id of the timer
andreikovacs 0:764779eedf2d 542 *
andreikovacs 0:764779eedf2d 543 * \return phyTimeStatus_t
andreikovacs 0:764779eedf2d 544 *
andreikovacs 0:764779eedf2d 545 ********************************************************************************** */
andreikovacs 0:764779eedf2d 546 phyTimeStatus_t PhyTime_CancelEvent( phyTimeTimerId_t timerId )
andreikovacs 0:764779eedf2d 547 {
andreikovacs 0:764779eedf2d 548 if( (timerId == 0) || (timerId >= gMaxPhyTimers_c) || (NULL == mPhyTimers[timerId].callback) )
andreikovacs 0:764779eedf2d 549 {
andreikovacs 0:764779eedf2d 550 return gPhyTimeNotFound_c;
andreikovacs 0:764779eedf2d 551 }
andreikovacs 0:764779eedf2d 552
andreikovacs 0:764779eedf2d 553 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 554 if( pNextEvent == &mPhyTimers[timerId] )
andreikovacs 0:764779eedf2d 555 pNextEvent = NULL;
andreikovacs 0:764779eedf2d 556
andreikovacs 0:764779eedf2d 557 mPhyTimers[timerId].callback = NULL;
andreikovacs 0:764779eedf2d 558 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 559
andreikovacs 0:764779eedf2d 560 return gPhyTimeOk_c;
andreikovacs 0:764779eedf2d 561 }
andreikovacs 0:764779eedf2d 562
andreikovacs 0:764779eedf2d 563 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 564 * \brief Cancel all event with the specified paameter
andreikovacs 0:764779eedf2d 565 *
andreikovacs 0:764779eedf2d 566 * \param[in] param event parameter
andreikovacs 0:764779eedf2d 567 *
andreikovacs 0:764779eedf2d 568 * \return phyTimeStatus_t
andreikovacs 0:764779eedf2d 569 *
andreikovacs 0:764779eedf2d 570 ********************************************************************************** */
andreikovacs 0:764779eedf2d 571 phyTimeStatus_t PhyTime_CancelEventsWithParam ( uint32_t param )
andreikovacs 0:764779eedf2d 572 {
andreikovacs 0:764779eedf2d 573 uint32_t i;
andreikovacs 0:764779eedf2d 574 phyTimeStatus_t status = gPhyTimeNotFound_c;
andreikovacs 0:764779eedf2d 575
andreikovacs 0:764779eedf2d 576 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 577 for( i=1; i<gMaxPhyTimers_c; i++ )
andreikovacs 0:764779eedf2d 578 {
andreikovacs 0:764779eedf2d 579 if( mPhyTimers[i].callback && (param == mPhyTimers[i].parameter) )
andreikovacs 0:764779eedf2d 580 {
andreikovacs 0:764779eedf2d 581 status = gPhyTimeOk_c;
andreikovacs 0:764779eedf2d 582 mPhyTimers[i].callback = NULL;
andreikovacs 0:764779eedf2d 583 if( pNextEvent == &mPhyTimers[i] )
andreikovacs 0:764779eedf2d 584 pNextEvent = NULL;
andreikovacs 0:764779eedf2d 585 }
andreikovacs 0:764779eedf2d 586 }
andreikovacs 0:764779eedf2d 587 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 588
andreikovacs 0:764779eedf2d 589 return status;
andreikovacs 0:764779eedf2d 590 }
andreikovacs 0:764779eedf2d 591
andreikovacs 0:764779eedf2d 592 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 593 * \brief Run the callback for the recently expired event
andreikovacs 0:764779eedf2d 594 *
andreikovacs 0:764779eedf2d 595 ********************************************************************************** */
andreikovacs 0:764779eedf2d 596 void PhyTime_RunCallback( void )
andreikovacs 0:764779eedf2d 597 {
andreikovacs 0:764779eedf2d 598 uint32_t param;
andreikovacs 0:764779eedf2d 599 phyTimeCallback_t cb;
andreikovacs 0:764779eedf2d 600
andreikovacs 0:764779eedf2d 601 if( pNextEvent )
andreikovacs 0:764779eedf2d 602 {
andreikovacs 0:764779eedf2d 603 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 604
andreikovacs 0:764779eedf2d 605 param = pNextEvent->parameter;
andreikovacs 0:764779eedf2d 606 cb = pNextEvent->callback;
andreikovacs 0:764779eedf2d 607 pNextEvent->callback = NULL;
andreikovacs 0:764779eedf2d 608 pNextEvent = NULL;
andreikovacs 0:764779eedf2d 609
andreikovacs 0:764779eedf2d 610 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 611
andreikovacs 0:764779eedf2d 612 cb(param);
andreikovacs 0:764779eedf2d 613 }
andreikovacs 0:764779eedf2d 614 }
andreikovacs 0:764779eedf2d 615
andreikovacs 0:764779eedf2d 616 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 617 * \brief Expire events too close to be scheduled.
andreikovacs 0:764779eedf2d 618 * Program the next event
andreikovacs 0:764779eedf2d 619 *
andreikovacs 0:764779eedf2d 620 ********************************************************************************** */
andreikovacs 0:764779eedf2d 621 void PhyTime_Maintenance( void )
andreikovacs 0:764779eedf2d 622 {
andreikovacs 0:764779eedf2d 623 phyTimeTimestamp_t currentTime;
andreikovacs 0:764779eedf2d 624 phyTimeEvent_t *pEv;
andreikovacs 0:764779eedf2d 625
andreikovacs 0:764779eedf2d 626 PhyTimeDisableWaitTimeout();
andreikovacs 0:764779eedf2d 627
andreikovacs 0:764779eedf2d 628 while(1)
andreikovacs 0:764779eedf2d 629 {
andreikovacs 0:764779eedf2d 630 OSA_EnterCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 631
andreikovacs 0:764779eedf2d 632 pEv = PhyTime_GetNextEvent();
andreikovacs 0:764779eedf2d 633 currentTime = PhyTime_GetTimestamp();
andreikovacs 0:764779eedf2d 634
andreikovacs 0:764779eedf2d 635 /* Program next event if exists */
andreikovacs 0:764779eedf2d 636 if( pEv )
andreikovacs 0:764779eedf2d 637 {
andreikovacs 0:764779eedf2d 638 pNextEvent = pEv;
andreikovacs 0:764779eedf2d 639
andreikovacs 0:764779eedf2d 640 if( pEv->timestamp > (currentTime + gPhyTimeMinSetupTime_c) )
andreikovacs 0:764779eedf2d 641 {
andreikovacs 0:764779eedf2d 642 PhyTimeSetWaitTimeout( (uint32_t*)&pEv->timestamp );
andreikovacs 0:764779eedf2d 643 pEv = NULL;
andreikovacs 0:764779eedf2d 644 }
andreikovacs 0:764779eedf2d 645 }
andreikovacs 0:764779eedf2d 646
andreikovacs 0:764779eedf2d 647 OSA_ExitCritical(kCriticalDisableInt);
andreikovacs 0:764779eedf2d 648
andreikovacs 0:764779eedf2d 649 if( !pEv )
andreikovacs 0:764779eedf2d 650 break;
andreikovacs 0:764779eedf2d 651
andreikovacs 0:764779eedf2d 652 PhyTime_RunCallback();
andreikovacs 0:764779eedf2d 653 }
andreikovacs 0:764779eedf2d 654
andreikovacs 0:764779eedf2d 655 }
andreikovacs 0:764779eedf2d 656
andreikovacs 0:764779eedf2d 657
andreikovacs 0:764779eedf2d 658 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 659 * \brief Timer Overflow callback
andreikovacs 0:764779eedf2d 660 *
andreikovacs 0:764779eedf2d 661 * \param[in] param
andreikovacs 0:764779eedf2d 662 *
andreikovacs 0:764779eedf2d 663 ********************************************************************************** */
andreikovacs 0:764779eedf2d 664 static void PhyTime_OverflowCB( uint32_t param )
andreikovacs 0:764779eedf2d 665 {
andreikovacs 0:764779eedf2d 666 (void)param;
andreikovacs 0:764779eedf2d 667
andreikovacs 0:764779eedf2d 668 /* Reprogram the next overflow callback */
andreikovacs 0:764779eedf2d 669 mPhyTimers[0].callback = PhyTime_OverflowCB;
andreikovacs 0:764779eedf2d 670 mPhyTimers[0].timestamp = (gPhyTimerOverflow+1) << 24;
andreikovacs 0:764779eedf2d 671 }
andreikovacs 0:764779eedf2d 672
andreikovacs 0:764779eedf2d 673 /*! *********************************************************************************
andreikovacs 0:764779eedf2d 674 * \brief Search for the next event to be scheduled
andreikovacs 0:764779eedf2d 675 *
andreikovacs 0:764779eedf2d 676 * \return phyTimeEvent_t pointer to the next event to be scheduled
andreikovacs 0:764779eedf2d 677 *
andreikovacs 0:764779eedf2d 678 ********************************************************************************** */
andreikovacs 0:764779eedf2d 679 static phyTimeEvent_t* PhyTime_GetNextEvent( void )
andreikovacs 0:764779eedf2d 680 {
andreikovacs 0:764779eedf2d 681 phyTimeEvent_t *pEv = NULL;
andreikovacs 0:764779eedf2d 682 uint32_t i;
andreikovacs 0:764779eedf2d 683
andreikovacs 0:764779eedf2d 684 /* Search for the next event to be serviced */
andreikovacs 0:764779eedf2d 685 for( i=0; i<gMaxPhyTimers_c; i++ )
andreikovacs 0:764779eedf2d 686 {
andreikovacs 0:764779eedf2d 687 if( NULL != mPhyTimers[i].callback )
andreikovacs 0:764779eedf2d 688 {
andreikovacs 0:764779eedf2d 689 if( NULL == pEv )
andreikovacs 0:764779eedf2d 690 {
andreikovacs 0:764779eedf2d 691 pEv = &mPhyTimers[i];
andreikovacs 0:764779eedf2d 692 }
andreikovacs 0:764779eedf2d 693 /* Check which event expires first */
andreikovacs 0:764779eedf2d 694 else if( mPhyTimers[i].timestamp < pEv->timestamp )
andreikovacs 0:764779eedf2d 695 {
andreikovacs 0:764779eedf2d 696 pEv = &mPhyTimers[i];
andreikovacs 0:764779eedf2d 697 }
andreikovacs 0:764779eedf2d 698 }
andreikovacs 0:764779eedf2d 699 }
andreikovacs 0:764779eedf2d 700
andreikovacs 0:764779eedf2d 701 return pEv;
andreikovacs 0:764779eedf2d 702 }