added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Revision:
50:a417edff4437
Parent:
0:9b334a45a8ff
Child:
144:ef7eb2e8f9f7
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/rtc_api.c	Wed Jan 13 12:45:11 2016 +0000
+++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/rtc_api.c	Fri Jan 15 07:45:16 2016 +0000
@@ -34,10 +34,17 @@
 #include "rtc_api.h"
 #include "rtc_api_HAL.h"
 #include "em_cmu.h"
-#include "em_rtc.h"
 #include "sleep_api.h"
 #include "sleepmodes.h"
 
+#if (defined RTC_COUNT) && (RTC_COUNT > 0)
+#include "em_rtc.h"
+#endif
+
+#if (defined RTCC_COUNT) && (RTCC_COUNT > 0)
+#include "em_rtcc.h"
+#endif
+
 static bool         rtc_inited  = false;
 static time_t       time_base   = 0;
 static uint32_t     useflags    = 0;
@@ -45,6 +52,10 @@
 
 static void (*comp0_handler)(void) = NULL;
 
+#ifndef RTCC_COUNT
+
+/* Using RTC API */
+
 #define RTC_LEAST_ACTIVE_SLEEPMODE  EM2
 #define RTC_NUM_BITS                (24)
 
@@ -65,12 +76,12 @@
     }
 }
 
-uint32_t rtc_get_32bit(void) 
+uint32_t rtc_get_32bit(void)
 {
     return (RTC_CounterGet() + (time_extend << RTC_NUM_BITS));
 }
 
-uint64_t rtc_get_full(void) 
+uint64_t rtc_get_full(void)
 {
     uint64_t ticks = 0;
     ticks += time_extend;
@@ -79,18 +90,6 @@
     return ticks;
 }
 
-void rtc_set_comp0_handler(uint32_t handler)
-{
-    comp0_handler = (void (*)(void)) handler;
-}
-
-void rtc_init(void)
-{
-    /* Register that the RTC is used for timekeeping. */
-    rtc_init_real(RTC_INIT_RTC);
-}
-
-
 void rtc_init_real(uint32_t flags)
 {
     useflags |= flags;
@@ -143,6 +142,113 @@
     }
 }
 
+#else
+
+/* Using RTCC API */
+
+#define RTCC_LEAST_ACTIVE_SLEEPMODE  EM2
+#define RTCC_NUM_BITS                (32)
+
+void RTCC_IRQHandler(void)
+{
+    uint32_t flags;
+    flags = RTCC_IntGet();
+
+    if (flags & RTCC_IF_OF) {
+        RTCC_IntClear(RTCC_IF_OF);
+        /* RTC has overflowed (32 bits). Use time_extend as software counter for 32 more bits. */
+        time_extend += 1;
+    }
+
+    if (flags & RTCC_IF_CC0) {
+        RTCC_IntClear(RTCC_IF_CC0);
+        if (comp0_handler != NULL) {
+            comp0_handler();
+        }
+    }
+}
+
+uint32_t rtc_get_32bit(void)
+{
+    return RTCC_CounterGet();
+}
+
+uint64_t rtc_get_full(void)
+{
+    uint64_t ticks = 0;
+    ticks += time_extend;
+    ticks = ticks << RTCC_NUM_BITS;
+    ticks += RTCC_CounterGet();
+    return ticks;
+}
+
+void rtc_init_real(uint32_t flags)
+{
+    useflags |= flags;
+
+    if (!rtc_inited) {
+        CMU_ClockEnable(cmuClock_RTCC, true);
+
+        /* Enable clock to the interface of the low energy modules */
+        CMU_ClockEnable(cmuClock_CORELE, true);
+
+        /* Initialize RTC */
+        RTCC_Init_TypeDef init = RTCC_INIT_DEFAULT;
+        init.enable = 1;
+        init.precntWrapOnCCV0 = false;
+        init.cntWrapOnCCV1 = false;
+#if RTC_CLOCKDIV_INT == 8
+        init.presc = rtccCntPresc_8;
+#else
+#error invalid prescaler value RTC_CLOCKDIV_INT
+#endif
+
+        /* Enable Interrupt from RTC */
+        RTCC_IntEnable(RTCC_IEN_OF);
+        NVIC_EnableIRQ(RTCC_IRQn);
+        NVIC_SetVector(RTCC_IRQn, (uint32_t)RTCC_IRQHandler);
+
+        /* Initialize */
+        RTCC_Init(&init);
+
+        blockSleepMode(RTCC_LEAST_ACTIVE_SLEEPMODE);
+        rtc_inited = true;
+    }
+}
+
+void rtc_free(void)
+{
+    rtc_free_real(RTC_INIT_RTC);
+}
+
+void rtc_free_real(uint32_t flags)
+{
+    /* Clear use flag */
+    useflags &= ~flags;
+
+    /* Disable the RTC if it was inited and is no longer in use by anyone. */
+    if (rtc_inited && (useflags == 0)) {
+        NVIC_DisableIRQ(RTCC_IRQn);
+        RTCC_Reset();
+        CMU_ClockEnable(cmuClock_RTCC, false);
+        unblockSleepMode(RTCC_LEAST_ACTIVE_SLEEPMODE);
+        rtc_inited = false;
+    }
+}
+
+#endif /* RTCC_COUNT */
+
+void rtc_set_comp0_handler(uint32_t handler)
+{
+    comp0_handler = (void (*)(void)) handler;
+}
+
+void rtc_init(void)
+{
+    /* Register that the RTC is used for timekeeping. */
+    rtc_init_real(RTC_INIT_RTC);
+}
+
 int rtc_isenabled(void)
 {
     return rtc_inited;
@@ -153,7 +259,7 @@
     return (time_t) (rtc_get_full() >> RTC_FREQ_SHIFT) + time_base;
 }
 
-time_t rtc_read_uncompensated(void) 
+time_t rtc_read_uncompensated(void)
 {
     return (time_t) (rtc_get_full() >> RTC_FREQ_SHIFT);
 }
@@ -166,7 +272,7 @@
     do {
         time = rtc_read_uncompensated();
         time_base = t - time;
-    } while (time != rtc_read_uncompensated());
+    } while (time != (uint32_t)rtc_read_uncompensated());
 }
 
 #endif