mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Oct 28 11:17:30 2016 +0100
Revision:
149:156823d33999
This updates the lib to the mbed lib v128

NOTE: This release includes a restructuring of the file and directory locations and thus some
include paths in your code may need updating accordingly.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 149:156823d33999 1 /**************************************************************************//**
<> 149:156823d33999 2 * @file timer.c
<> 149:156823d33999 3 * @version V3.00
<> 149:156823d33999 4 * $Revision: 6 $
<> 149:156823d33999 5 * $Date: 15/08/11 10:26a $
<> 149:156823d33999 6 * @brief M451 series Timer driver source file
<> 149:156823d33999 7 *
<> 149:156823d33999 8 * @note
<> 149:156823d33999 9 * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved.
<> 149:156823d33999 10 *****************************************************************************/
<> 149:156823d33999 11 #include "M451Series.h"
<> 149:156823d33999 12
<> 149:156823d33999 13
<> 149:156823d33999 14 /** @addtogroup Standard_Driver Standard Driver
<> 149:156823d33999 15 @{
<> 149:156823d33999 16 */
<> 149:156823d33999 17
<> 149:156823d33999 18 /** @addtogroup TIMER_Driver TIMER Driver
<> 149:156823d33999 19 @{
<> 149:156823d33999 20 */
<> 149:156823d33999 21
<> 149:156823d33999 22 /** @addtogroup TIMER_EXPORTED_FUNCTIONS TIMER Exported Functions
<> 149:156823d33999 23 @{
<> 149:156823d33999 24 */
<> 149:156823d33999 25
<> 149:156823d33999 26 /**
<> 149:156823d33999 27 * @brief Open Timer with Operate Mode and Frequency
<> 149:156823d33999 28 *
<> 149:156823d33999 29 * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
<> 149:156823d33999 30 * @param[in] u32Mode Operation mode. Possible options are
<> 149:156823d33999 31 * - \ref TIMER_ONESHOT_MODE
<> 149:156823d33999 32 * - \ref TIMER_PERIODIC_MODE
<> 149:156823d33999 33 * - \ref TIMER_TOGGLE_MODE
<> 149:156823d33999 34 * - \ref TIMER_CONTINUOUS_MODE
<> 149:156823d33999 35 * @param[in] u32Freq Target working frequency
<> 149:156823d33999 36 *
<> 149:156823d33999 37 * @return Real timer working frequency
<> 149:156823d33999 38 *
<> 149:156823d33999 39 * @details This API is used to configure timer to operate in specified mode and frequency.
<> 149:156823d33999 40 * If timer cannot work in target frequency, a closest frequency will be chose and returned.
<> 149:156823d33999 41 * @note After calling this API, Timer is \b NOT running yet. But could start timer running be calling
<> 149:156823d33999 42 * \ref TIMER_Start macro or program registers directly.
<> 149:156823d33999 43 */
<> 149:156823d33999 44 uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq)
<> 149:156823d33999 45 {
<> 149:156823d33999 46 uint32_t u32Clk = TIMER_GetModuleClock(timer);
<> 149:156823d33999 47 uint32_t u32Cmpr = 0, u32Prescale = 0;
<> 149:156823d33999 48
<> 149:156823d33999 49 // Fastest possible timer working freq is (u32Clk / 2). While cmpr = 2, pre-scale = 0.
<> 149:156823d33999 50 if(u32Freq > (u32Clk / 2))
<> 149:156823d33999 51 {
<> 149:156823d33999 52 u32Cmpr = 2;
<> 149:156823d33999 53 }
<> 149:156823d33999 54 else
<> 149:156823d33999 55 {
<> 149:156823d33999 56 if(u32Clk > 64000000)
<> 149:156823d33999 57 {
<> 149:156823d33999 58 u32Prescale = 7; // real prescaler value is 8
<> 149:156823d33999 59 u32Clk >>= 3;
<> 149:156823d33999 60 }
<> 149:156823d33999 61 else if(u32Clk > 32000000)
<> 149:156823d33999 62 {
<> 149:156823d33999 63 u32Prescale = 3; // real prescaler value is 4
<> 149:156823d33999 64 u32Clk >>= 2;
<> 149:156823d33999 65 }
<> 149:156823d33999 66 else if(u32Clk > 16000000)
<> 149:156823d33999 67 {
<> 149:156823d33999 68 u32Prescale = 1; // real prescaler value is 2
<> 149:156823d33999 69 u32Clk >>= 1;
<> 149:156823d33999 70 }
<> 149:156823d33999 71
<> 149:156823d33999 72 u32Cmpr = u32Clk / u32Freq;
<> 149:156823d33999 73 }
<> 149:156823d33999 74
<> 149:156823d33999 75 timer->CTL = u32Mode | u32Prescale;
<> 149:156823d33999 76 timer->CMP = u32Cmpr;
<> 149:156823d33999 77
<> 149:156823d33999 78 return(u32Clk / (u32Cmpr * (u32Prescale + 1)));
<> 149:156823d33999 79 }
<> 149:156823d33999 80
<> 149:156823d33999 81 /**
<> 149:156823d33999 82 * @brief Stop Timer Counting
<> 149:156823d33999 83 *
<> 149:156823d33999 84 * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
<> 149:156823d33999 85 *
<> 149:156823d33999 86 * @return None
<> 149:156823d33999 87 *
<> 149:156823d33999 88 * @details This API stops timer counting and disable all timer interrupt function.
<> 149:156823d33999 89 */
<> 149:156823d33999 90 void TIMER_Close(TIMER_T *timer)
<> 149:156823d33999 91 {
<> 149:156823d33999 92 timer->CTL = 0;
<> 149:156823d33999 93 timer->EXTCTL = 0;
<> 149:156823d33999 94 }
<> 149:156823d33999 95
<> 149:156823d33999 96 /**
<> 149:156823d33999 97 * @brief Create a specify Delay Time
<> 149:156823d33999 98 *
<> 149:156823d33999 99 * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
<> 149:156823d33999 100 * @param[in] u32Usec Delay period in micro seconds. Valid values are between 100~1000000 (100 micro second ~ 1 second).
<> 149:156823d33999 101 *
<> 149:156823d33999 102 * @return None
<> 149:156823d33999 103 *
<> 149:156823d33999 104 * @details This API is used to create a delay loop for u32usec micro seconds by using timer one-shot mode.
<> 149:156823d33999 105 * @note This API overwrites the register setting of the timer used to count the delay time.
<> 149:156823d33999 106 * @note This API use polling mode. So there is no need to enable interrupt for the timer module used to generate delay.
<> 149:156823d33999 107 */
<> 149:156823d33999 108 void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec)
<> 149:156823d33999 109 {
<> 149:156823d33999 110 uint32_t u32Clk = TIMER_GetModuleClock(timer);
<> 149:156823d33999 111 uint32_t u32Prescale = 0, delay = (SystemCoreClock / u32Clk) + 1;
<> 149:156823d33999 112 uint32_t u32Cmpr, u32NsecPerTick;
<> 149:156823d33999 113
<> 149:156823d33999 114 // Clear current timer configuration/
<> 149:156823d33999 115 timer->CTL = 0;
<> 149:156823d33999 116 timer->EXTCTL = 0;
<> 149:156823d33999 117
<> 149:156823d33999 118 if(u32Clk <= 1000000) // min delay is 1000 us if timer clock source is <= 1 MHz
<> 149:156823d33999 119 {
<> 149:156823d33999 120 if(u32Usec < 1000)
<> 149:156823d33999 121 u32Usec = 1000;
<> 149:156823d33999 122 if(u32Usec > 1000000)
<> 149:156823d33999 123 u32Usec = 1000000;
<> 149:156823d33999 124 }
<> 149:156823d33999 125 else
<> 149:156823d33999 126 {
<> 149:156823d33999 127 if(u32Usec < 100)
<> 149:156823d33999 128 u32Usec = 100;
<> 149:156823d33999 129 if(u32Usec > 1000000)
<> 149:156823d33999 130 u32Usec = 1000000;
<> 149:156823d33999 131 }
<> 149:156823d33999 132
<> 149:156823d33999 133 if(u32Clk <= 1000000)
<> 149:156823d33999 134 {
<> 149:156823d33999 135 u32Prescale = 0;
<> 149:156823d33999 136 u32NsecPerTick = 1000000000 / u32Clk;
<> 149:156823d33999 137 u32Cmpr = (u32Usec * 1000) / u32NsecPerTick;
<> 149:156823d33999 138 }
<> 149:156823d33999 139 else
<> 149:156823d33999 140 {
<> 149:156823d33999 141 if(u32Clk > 64000000)
<> 149:156823d33999 142 {
<> 149:156823d33999 143 u32Prescale = 7; // real prescaler value is 8
<> 149:156823d33999 144 u32Clk >>= 3;
<> 149:156823d33999 145 }
<> 149:156823d33999 146 else if(u32Clk > 32000000)
<> 149:156823d33999 147 {
<> 149:156823d33999 148 u32Prescale = 3; // real prescaler value is 4
<> 149:156823d33999 149 u32Clk >>= 2;
<> 149:156823d33999 150 }
<> 149:156823d33999 151 else if(u32Clk > 16000000)
<> 149:156823d33999 152 {
<> 149:156823d33999 153 u32Prescale = 1; // real prescaler value is 2
<> 149:156823d33999 154 u32Clk >>= 1;
<> 149:156823d33999 155 }
<> 149:156823d33999 156
<> 149:156823d33999 157 if(u32Usec < 250)
<> 149:156823d33999 158 {
<> 149:156823d33999 159 u32Cmpr = (u32Usec * u32Clk) / 1000000;
<> 149:156823d33999 160 }
<> 149:156823d33999 161 else
<> 149:156823d33999 162 {
<> 149:156823d33999 163 u32NsecPerTick = 1000000000 / u32Clk;
<> 149:156823d33999 164 u32Cmpr = (u32Usec * 1000) / u32NsecPerTick;
<> 149:156823d33999 165 }
<> 149:156823d33999 166 }
<> 149:156823d33999 167
<> 149:156823d33999 168 timer->CMP = u32Cmpr;
<> 149:156823d33999 169 timer->CTL = TIMER_CTL_CNTEN_Msk | TIMER_ONESHOT_MODE | u32Prescale;
<> 149:156823d33999 170
<> 149:156823d33999 171 // When system clock is faster than timer clock, it is possible timer active bit cannot set in time while we check it.
<> 149:156823d33999 172 // And the while loop below return immediately, so put a tiny delay here allowing timer start counting and raise active flag.
<> 149:156823d33999 173 for(; delay > 0; delay--)
<> 149:156823d33999 174 {
<> 149:156823d33999 175 __NOP();
<> 149:156823d33999 176 }
<> 149:156823d33999 177
<> 149:156823d33999 178 while(timer->CTL & TIMER_CTL_ACTSTS_Msk);
<> 149:156823d33999 179 }
<> 149:156823d33999 180
<> 149:156823d33999 181 /**
<> 149:156823d33999 182 * @brief Enable Timer Capture Function
<> 149:156823d33999 183 *
<> 149:156823d33999 184 * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
<> 149:156823d33999 185 * @param[in] u32CapMode Timer capture mode. Could be
<> 149:156823d33999 186 * - \ref TIMER_CAPTURE_FREE_COUNTING_MODE
<> 149:156823d33999 187 * - \ref TIMER_CAPTURE_COUNTER_RESET_MODE
<> 149:156823d33999 188 * @param[in] u32Edge Timer capture trigger edge. Possible values are
<> 149:156823d33999 189 * - \ref TIMER_CAPTURE_FALLING_EDGE
<> 149:156823d33999 190 * - \ref TIMER_CAPTURE_RISING_EDGE
<> 149:156823d33999 191 * - \ref TIMER_CAPTURE_FALLING_AND_RISING_EDGE
<> 149:156823d33999 192 *
<> 149:156823d33999 193 * @return None
<> 149:156823d33999 194 *
<> 149:156823d33999 195 * @details This API is used to enable timer capture function with specify capture trigger edge \n
<> 149:156823d33999 196 * to get current counter value or reset counter value to 0.
<> 149:156823d33999 197 * @note Timer frequency should be configured separately by using \ref TIMER_Open API, or program registers directly.
<> 149:156823d33999 198 */
<> 149:156823d33999 199 void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
<> 149:156823d33999 200 {
<> 149:156823d33999 201
<> 149:156823d33999 202 timer->EXTCTL = (timer->EXTCTL & ~(TIMER_EXTCTL_CAPFUNCS_Msk | TIMER_EXTCTL_CAPEDGE_Msk)) |
<> 149:156823d33999 203 u32CapMode | u32Edge | TIMER_EXTCTL_CAPEN_Msk;
<> 149:156823d33999 204 }
<> 149:156823d33999 205
<> 149:156823d33999 206 /**
<> 149:156823d33999 207 * @brief Disable Timer Capture Function
<> 149:156823d33999 208 *
<> 149:156823d33999 209 * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
<> 149:156823d33999 210 *
<> 149:156823d33999 211 * @return None
<> 149:156823d33999 212 *
<> 149:156823d33999 213 * @details This API is used to disable the timer capture function.
<> 149:156823d33999 214 */
<> 149:156823d33999 215 void TIMER_DisableCapture(TIMER_T *timer)
<> 149:156823d33999 216 {
<> 149:156823d33999 217 timer->EXTCTL &= ~TIMER_EXTCTL_CAPEN_Msk;
<> 149:156823d33999 218 }
<> 149:156823d33999 219
<> 149:156823d33999 220 /**
<> 149:156823d33999 221 * @brief Enable Timer Counter Function
<> 149:156823d33999 222 *
<> 149:156823d33999 223 * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
<> 149:156823d33999 224 * @param[in] u32Edge Detection edge of counter pin. Could be ether
<> 149:156823d33999 225 * - \ref TIMER_COUNTER_FALLING_EDGE, or
<> 149:156823d33999 226 * - \ref TIMER_COUNTER_RISING_EDGE
<> 149:156823d33999 227 *
<> 149:156823d33999 228 * @return None
<> 149:156823d33999 229 *
<> 149:156823d33999 230 * @details This function is used to enable the timer counter function with specify detection edge.
<> 149:156823d33999 231 * @note Timer compare value should be configured separately by using \ref TIMER_SET_CMP_VALUE macro or program registers directly.
<> 149:156823d33999 232 * @note While using event counter function, \ref TIMER_TOGGLE_MODE cannot set as timer operation mode.
<> 149:156823d33999 233 */
<> 149:156823d33999 234 void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge)
<> 149:156823d33999 235 {
<> 149:156823d33999 236 timer->EXTCTL = (timer->EXTCTL & ~TIMER_EXTCTL_CNTPHASE_Msk) | u32Edge;
<> 149:156823d33999 237 timer->CTL |= TIMER_CTL_EXTCNTEN_Msk;
<> 149:156823d33999 238 }
<> 149:156823d33999 239
<> 149:156823d33999 240 /**
<> 149:156823d33999 241 * @brief Disable Timer Counter Function
<> 149:156823d33999 242 *
<> 149:156823d33999 243 * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
<> 149:156823d33999 244 *
<> 149:156823d33999 245 * @return None
<> 149:156823d33999 246 *
<> 149:156823d33999 247 * @details This API is used to disable the timer event counter function.
<> 149:156823d33999 248 */
<> 149:156823d33999 249 void TIMER_DisableEventCounter(TIMER_T *timer)
<> 149:156823d33999 250 {
<> 149:156823d33999 251 timer->CTL &= ~TIMER_CTL_EXTCNTEN_Msk;
<> 149:156823d33999 252 }
<> 149:156823d33999 253
<> 149:156823d33999 254 /**
<> 149:156823d33999 255 * @brief Get Timer Clock Frequency
<> 149:156823d33999 256 *
<> 149:156823d33999 257 * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
<> 149:156823d33999 258 *
<> 149:156823d33999 259 * @return Timer clock frequency
<> 149:156823d33999 260 *
<> 149:156823d33999 261 * @details This API is used to get the timer clock frequency.
<> 149:156823d33999 262 * @note This API cannot return correct clock rate if timer source is from external clock input.
<> 149:156823d33999 263 */
<> 149:156823d33999 264 uint32_t TIMER_GetModuleClock(TIMER_T *timer)
<> 149:156823d33999 265 {
<> 149:156823d33999 266 uint32_t u32Src;
<> 149:156823d33999 267 const uint32_t au32Clk[] = {__HXT, __LXT, 0, 0, 0, __LIRC, 0, __HIRC};
<> 149:156823d33999 268
<> 149:156823d33999 269 if(timer == TIMER0)
<> 149:156823d33999 270 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0SEL_Msk) >> CLK_CLKSEL1_TMR0SEL_Pos;
<> 149:156823d33999 271 else if(timer == TIMER1)
<> 149:156823d33999 272 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1SEL_Msk) >> CLK_CLKSEL1_TMR1SEL_Pos;
<> 149:156823d33999 273 else if(timer == TIMER2)
<> 149:156823d33999 274 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR2SEL_Msk) >> CLK_CLKSEL1_TMR2SEL_Pos;
<> 149:156823d33999 275 else // Timer 3
<> 149:156823d33999 276 u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR3SEL_Msk) >> CLK_CLKSEL1_TMR3SEL_Pos;
<> 149:156823d33999 277
<> 149:156823d33999 278 if(u32Src == 2)
<> 149:156823d33999 279 {
<> 149:156823d33999 280 return (SystemCoreClock);
<> 149:156823d33999 281 }
<> 149:156823d33999 282
<> 149:156823d33999 283 return (au32Clk[u32Src]);
<> 149:156823d33999 284 }
<> 149:156823d33999 285
<> 149:156823d33999 286 /*@}*/ /* end of group TIMER_EXPORTED_FUNCTIONS */
<> 149:156823d33999 287
<> 149:156823d33999 288 /*@}*/ /* end of group TIMER_Driver */
<> 149:156823d33999 289
<> 149:156823d33999 290 /*@}*/ /* end of group Standard_Driver */
<> 149:156823d33999 291
<> 149:156823d33999 292 /*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/