added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
bogdanm
Date:
Thu Oct 01 15:25:22 2015 +0300
Revision:
0:9b334a45a8ff
Child:
50:a417edff4437
Initial commit on mbed-dev

Replaces mbed-src (now inactive)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 0:9b334a45a8ff 1 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 2 * @file rtc_api.c
bogdanm 0:9b334a45a8ff 3 *******************************************************************************
bogdanm 0:9b334a45a8ff 4 * @section License
bogdanm 0:9b334a45a8ff 5 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
bogdanm 0:9b334a45a8ff 6 *******************************************************************************
bogdanm 0:9b334a45a8ff 7 *
bogdanm 0:9b334a45a8ff 8 * Permission is granted to anyone to use this software for any purpose,
bogdanm 0:9b334a45a8ff 9 * including commercial applications, and to alter it and redistribute it
bogdanm 0:9b334a45a8ff 10 * freely, subject to the following restrictions:
bogdanm 0:9b334a45a8ff 11 *
bogdanm 0:9b334a45a8ff 12 * 1. The origin of this software must not be misrepresented; you must not
bogdanm 0:9b334a45a8ff 13 * claim that you wrote the original software.
bogdanm 0:9b334a45a8ff 14 * 2. Altered source versions must be plainly marked as such, and must not be
bogdanm 0:9b334a45a8ff 15 * misrepresented as being the original software.
bogdanm 0:9b334a45a8ff 16 * 3. This notice may not be removed or altered from any source distribution.
bogdanm 0:9b334a45a8ff 17 *
bogdanm 0:9b334a45a8ff 18 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
bogdanm 0:9b334a45a8ff 19 * obligation to support this Software. Silicon Labs is providing the
bogdanm 0:9b334a45a8ff 20 * Software "AS IS", with no express or implied warranties of any kind,
bogdanm 0:9b334a45a8ff 21 * including, but not limited to, any implied warranties of merchantability
bogdanm 0:9b334a45a8ff 22 * or fitness for any particular purpose or warranties against infringement
bogdanm 0:9b334a45a8ff 23 * of any proprietary rights of a third party.
bogdanm 0:9b334a45a8ff 24 *
bogdanm 0:9b334a45a8ff 25 * Silicon Labs will not be liable for any consequential, incidental, or
bogdanm 0:9b334a45a8ff 26 * special damages, or any other relief, or for any claim by any third party,
bogdanm 0:9b334a45a8ff 27 * arising from your use of this Software.
bogdanm 0:9b334a45a8ff 28 *
bogdanm 0:9b334a45a8ff 29 ******************************************************************************/
bogdanm 0:9b334a45a8ff 30
bogdanm 0:9b334a45a8ff 31 #include "device.h"
bogdanm 0:9b334a45a8ff 32 #if DEVICE_RTC
bogdanm 0:9b334a45a8ff 33
bogdanm 0:9b334a45a8ff 34 #include "rtc_api.h"
bogdanm 0:9b334a45a8ff 35 #include "rtc_api_HAL.h"
bogdanm 0:9b334a45a8ff 36 #include "em_cmu.h"
bogdanm 0:9b334a45a8ff 37 #include "em_rtc.h"
bogdanm 0:9b334a45a8ff 38 #include "sleep_api.h"
bogdanm 0:9b334a45a8ff 39 #include "sleepmodes.h"
bogdanm 0:9b334a45a8ff 40
bogdanm 0:9b334a45a8ff 41 static bool rtc_inited = false;
bogdanm 0:9b334a45a8ff 42 static time_t time_base = 0;
bogdanm 0:9b334a45a8ff 43 static uint32_t useflags = 0;
bogdanm 0:9b334a45a8ff 44 static uint32_t time_extend = 0;
bogdanm 0:9b334a45a8ff 45
bogdanm 0:9b334a45a8ff 46 static void (*comp0_handler)(void) = NULL;
bogdanm 0:9b334a45a8ff 47
bogdanm 0:9b334a45a8ff 48 #define RTC_LEAST_ACTIVE_SLEEPMODE EM2
bogdanm 0:9b334a45a8ff 49 #define RTC_NUM_BITS (24)
bogdanm 0:9b334a45a8ff 50
bogdanm 0:9b334a45a8ff 51 void RTC_IRQHandler(void)
bogdanm 0:9b334a45a8ff 52 {
bogdanm 0:9b334a45a8ff 53 uint32_t flags;
bogdanm 0:9b334a45a8ff 54 flags = RTC_IntGet();
bogdanm 0:9b334a45a8ff 55 if (flags & RTC_IF_OF) {
bogdanm 0:9b334a45a8ff 56 RTC_IntClear(RTC_IF_OF);
bogdanm 0:9b334a45a8ff 57 /* RTC has overflowed (24 bits). Use time_extend as software counter for 32 more bits. */
bogdanm 0:9b334a45a8ff 58 time_extend += 1;
bogdanm 0:9b334a45a8ff 59 }
bogdanm 0:9b334a45a8ff 60 if (flags & RTC_IF_COMP0) {
bogdanm 0:9b334a45a8ff 61 RTC_IntClear(RTC_IF_COMP0);
bogdanm 0:9b334a45a8ff 62 if (comp0_handler != NULL) {
bogdanm 0:9b334a45a8ff 63 comp0_handler();
bogdanm 0:9b334a45a8ff 64 }
bogdanm 0:9b334a45a8ff 65 }
bogdanm 0:9b334a45a8ff 66 }
bogdanm 0:9b334a45a8ff 67
bogdanm 0:9b334a45a8ff 68 uint32_t rtc_get_32bit(void)
bogdanm 0:9b334a45a8ff 69 {
bogdanm 0:9b334a45a8ff 70 return (RTC_CounterGet() + (time_extend << RTC_NUM_BITS));
bogdanm 0:9b334a45a8ff 71 }
bogdanm 0:9b334a45a8ff 72
bogdanm 0:9b334a45a8ff 73 uint64_t rtc_get_full(void)
bogdanm 0:9b334a45a8ff 74 {
bogdanm 0:9b334a45a8ff 75 uint64_t ticks = 0;
bogdanm 0:9b334a45a8ff 76 ticks += time_extend;
bogdanm 0:9b334a45a8ff 77 ticks = ticks << RTC_NUM_BITS;
bogdanm 0:9b334a45a8ff 78 ticks += RTC_CounterGet();
bogdanm 0:9b334a45a8ff 79 return ticks;
bogdanm 0:9b334a45a8ff 80 }
bogdanm 0:9b334a45a8ff 81
bogdanm 0:9b334a45a8ff 82 void rtc_set_comp0_handler(uint32_t handler)
bogdanm 0:9b334a45a8ff 83 {
bogdanm 0:9b334a45a8ff 84 comp0_handler = (void (*)(void)) handler;
bogdanm 0:9b334a45a8ff 85 }
bogdanm 0:9b334a45a8ff 86
bogdanm 0:9b334a45a8ff 87 void rtc_init(void)
bogdanm 0:9b334a45a8ff 88 {
bogdanm 0:9b334a45a8ff 89 /* Register that the RTC is used for timekeeping. */
bogdanm 0:9b334a45a8ff 90 rtc_init_real(RTC_INIT_RTC);
bogdanm 0:9b334a45a8ff 91 }
bogdanm 0:9b334a45a8ff 92
bogdanm 0:9b334a45a8ff 93
bogdanm 0:9b334a45a8ff 94 void rtc_init_real(uint32_t flags)
bogdanm 0:9b334a45a8ff 95 {
bogdanm 0:9b334a45a8ff 96 useflags |= flags;
bogdanm 0:9b334a45a8ff 97
bogdanm 0:9b334a45a8ff 98 if (!rtc_inited) {
bogdanm 0:9b334a45a8ff 99 CMU_ClockEnable(cmuClock_RTC, true);
bogdanm 0:9b334a45a8ff 100
bogdanm 0:9b334a45a8ff 101 /* Enable clock to the interface of the low energy modules */
bogdanm 0:9b334a45a8ff 102 CMU_ClockEnable(cmuClock_CORELE, true);
bogdanm 0:9b334a45a8ff 103
bogdanm 0:9b334a45a8ff 104 /* Scale clock to save power */
bogdanm 0:9b334a45a8ff 105 CMU_ClockDivSet(cmuClock_RTC, RTC_CLOCKDIV);
bogdanm 0:9b334a45a8ff 106
bogdanm 0:9b334a45a8ff 107 /* Initialize RTC */
bogdanm 0:9b334a45a8ff 108 RTC_Init_TypeDef init = RTC_INIT_DEFAULT;
bogdanm 0:9b334a45a8ff 109 init.enable = 1;
bogdanm 0:9b334a45a8ff 110 /* Don't use compare register 0 as top value */
bogdanm 0:9b334a45a8ff 111 init.comp0Top = 0;
bogdanm 0:9b334a45a8ff 112
bogdanm 0:9b334a45a8ff 113 /* Enable Interrupt from RTC */
bogdanm 0:9b334a45a8ff 114 RTC_IntEnable(RTC_IEN_OF);
bogdanm 0:9b334a45a8ff 115 NVIC_EnableIRQ(RTC_IRQn);
bogdanm 0:9b334a45a8ff 116 NVIC_SetVector(RTC_IRQn, (uint32_t)RTC_IRQHandler);
bogdanm 0:9b334a45a8ff 117
bogdanm 0:9b334a45a8ff 118 /* Initialize */
bogdanm 0:9b334a45a8ff 119 RTC_Init(&init);
bogdanm 0:9b334a45a8ff 120
bogdanm 0:9b334a45a8ff 121 blockSleepMode(RTC_LEAST_ACTIVE_SLEEPMODE);
bogdanm 0:9b334a45a8ff 122 rtc_inited = true;
bogdanm 0:9b334a45a8ff 123 }
bogdanm 0:9b334a45a8ff 124 }
bogdanm 0:9b334a45a8ff 125
bogdanm 0:9b334a45a8ff 126 void rtc_free(void)
bogdanm 0:9b334a45a8ff 127 {
bogdanm 0:9b334a45a8ff 128 rtc_free_real(RTC_INIT_RTC);
bogdanm 0:9b334a45a8ff 129 }
bogdanm 0:9b334a45a8ff 130
bogdanm 0:9b334a45a8ff 131 void rtc_free_real(uint32_t flags)
bogdanm 0:9b334a45a8ff 132 {
bogdanm 0:9b334a45a8ff 133 /* Clear use flag */
bogdanm 0:9b334a45a8ff 134 useflags &= ~flags;
bogdanm 0:9b334a45a8ff 135
bogdanm 0:9b334a45a8ff 136 /* Disable the RTC if it was inited and is no longer in use by anyone. */
bogdanm 0:9b334a45a8ff 137 if (rtc_inited && (useflags == 0)) {
bogdanm 0:9b334a45a8ff 138 NVIC_DisableIRQ(RTC_IRQn);
bogdanm 0:9b334a45a8ff 139 RTC_Reset();
bogdanm 0:9b334a45a8ff 140 CMU_ClockEnable(cmuClock_RTC, false);
bogdanm 0:9b334a45a8ff 141 unblockSleepMode(RTC_LEAST_ACTIVE_SLEEPMODE);
bogdanm 0:9b334a45a8ff 142 rtc_inited = false;
bogdanm 0:9b334a45a8ff 143 }
bogdanm 0:9b334a45a8ff 144 }
bogdanm 0:9b334a45a8ff 145
bogdanm 0:9b334a45a8ff 146 int rtc_isenabled(void)
bogdanm 0:9b334a45a8ff 147 {
bogdanm 0:9b334a45a8ff 148 return rtc_inited;
bogdanm 0:9b334a45a8ff 149 }
bogdanm 0:9b334a45a8ff 150
bogdanm 0:9b334a45a8ff 151 time_t rtc_read(void)
bogdanm 0:9b334a45a8ff 152 {
bogdanm 0:9b334a45a8ff 153 return (time_t) (rtc_get_full() >> RTC_FREQ_SHIFT) + time_base;
bogdanm 0:9b334a45a8ff 154 }
bogdanm 0:9b334a45a8ff 155
bogdanm 0:9b334a45a8ff 156 time_t rtc_read_uncompensated(void)
bogdanm 0:9b334a45a8ff 157 {
bogdanm 0:9b334a45a8ff 158 return (time_t) (rtc_get_full() >> RTC_FREQ_SHIFT);
bogdanm 0:9b334a45a8ff 159 }
bogdanm 0:9b334a45a8ff 160
bogdanm 0:9b334a45a8ff 161 void rtc_write(time_t t)
bogdanm 0:9b334a45a8ff 162 {
bogdanm 0:9b334a45a8ff 163 /* We have to check that the RTC did not tick while doing this. */
bogdanm 0:9b334a45a8ff 164 /* If the RTC ticks we just redo this. */
bogdanm 0:9b334a45a8ff 165 uint32_t time;
bogdanm 0:9b334a45a8ff 166 do {
bogdanm 0:9b334a45a8ff 167 time = rtc_read_uncompensated();
bogdanm 0:9b334a45a8ff 168 time_base = t - time;
bogdanm 0:9b334a45a8ff 169 } while (time != rtc_read_uncompensated());
bogdanm 0:9b334a45a8ff 170 }
bogdanm 0:9b334a45a8ff 171
bogdanm 0:9b334a45a8ff 172 #endif