mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Revision:
186:707f6e361f3e
Parent:
182:a56a73fd2a6f
--- a/targets/TARGET_Maxim/TARGET_MAX32625/us_ticker.c	Thu Apr 19 17:12:19 2018 +0100
+++ b/targets/TARGET_Maxim/TARGET_MAX32625/us_ticker.c	Fri Jun 22 16:45:37 2018 +0100
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
+ * Copyright (c) 2016,2018 Maxim Integrated Products, Inc., All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -32,251 +32,81 @@
  */
 
 #include <stddef.h>
-#include "mbed_error.h"
-#include "mbed_critical.h"
 #include "us_ticker_api.h"
-#include "PeripheralNames.h"
 #include "tmr.h"
-#include "assert.h"
-
-#define US_TIMER        MXC_TMR0
-#define US_TIMER_IRQn   TMR0_0_IRQn
-
-static int us_ticker_inited = 0;
-static uint32_t ticks_per_us;
-static uint32_t tick_win;
-static volatile uint64_t current_cnt;   // Hold the current ticks
-static volatile uint64_t event_cnt;     // Holds the value of the next event
-
-#define MAX_TICK_VAL    ((uint64_t)0xFFFFFFFF * ticks_per_us)
-
-//******************************************************************************
-static inline void inc_current_cnt_no_crit(uint32_t inc)
-{
-    // Overflow the ticker when the us ticker overflows
-    current_cnt += inc;
-    if (current_cnt > MAX_TICK_VAL) {
-        current_cnt -= (MAX_TICK_VAL + 1);
-    }
-}
-
-//******************************************************************************
-static inline void inc_current_cnt(uint32_t inc)
-{
-    core_util_critical_section_enter();
-    inc_current_cnt_no_crit(inc);
-    core_util_critical_section_exit();
-}
-
-//******************************************************************************
-static inline int event_passed(uint64_t current, uint64_t event)
-{
-    // Determine if the event has already happened.
-    // If the event is behind the current ticker, within a window,
-    // then the event has already happened.
-    if (((current < tick_win) && ((event < current) ||
-                                  (event > (MAX_TICK_VAL - (tick_win - current))))) ||
-            ((event < current) && (event > (current - tick_win)))) {
-        return 1;
-    }
 
-    return 0;
-}
-
-//******************************************************************************
-static inline uint64_t event_diff(uint64_t current, uint64_t event)
-{
-    // Check to see if the ticker will overflow before the event
-    if(current <= event) {
-        return (event - current);
-    }
-
-    return ((MAX_TICK_VAL - current) + event);
-}
-
-//******************************************************************************
-static void tmr_handler(void)
-{
-    uint32_t cmp = TMR32_GetCompare(US_TIMER);
-    TMR32_SetCompare(US_TIMER, 0xFFFFFFFF); // reset to max value to prevent further interrupts
-    if (TMR32_GetFlag(US_TIMER)) {
-        inc_current_cnt_no_crit(cmp);
-    }
-    TMR32_ClearFlag(US_TIMER);
-    NVIC_ClearPendingIRQ(US_TIMER_IRQn);
-
-    if (event_passed(current_cnt + TMR32_GetCount(US_TIMER), event_cnt)) {
-        // the timestamp has expired
-        event_cnt = 0xFFFFFFFFFFFFFFFFULL;  // reset to max value
-        us_ticker_irq_handler();
-    } else {
-        uint64_t diff = event_diff(current_cnt, event_cnt);
-        if (diff < (uint64_t)0xFFFFFFFF) {
-            // the event occurs before the next overflow
-            TMR32_SetCompare(US_TIMER, diff);
-
-            // Since the timer keeps counting after the terminal value is reached, it is possible that the new
-            // terminal value is in the past.
-            if (TMR32_GetCompare(US_TIMER) < TMR32_GetCount(US_TIMER)) {
-                // the timestamp has expired
-                TMR32_SetCompare(US_TIMER, 0xFFFFFFFF); // reset to max value to prevent further interrupts
-                TMR32_ClearFlag(US_TIMER);
-                NVIC_ClearPendingIRQ(US_TIMER_IRQn);
-                event_cnt = 0xFFFFFFFFFFFFFFFFULL;  // reset to max value
-                us_ticker_irq_handler();
-            }
-        }
-    }
-}
+#define US_TIMER          MXC_TMR0
+#define US_TIMER_IRQn     TMR0_0_IRQn
+#define US_TIMER_PRESCALE TMR_PRESCALE_DIV_2_5
+#define US_TIMER_MODE     TMR32_MODE_COMPARE
+#define US_TIMER_WIDTH    32
 
 //******************************************************************************
 void us_ticker_init(void)
 {
-    if (us_ticker_inited) {
-        return;
-    }
-
-    us_ticker_inited = 1;
-    current_cnt = 0;
-    event_cnt = 0xFFFFFFFFFFFFFFFFULL;          // reset to max value
-    ticks_per_us = SystemCoreClock / 1000000;
-    tick_win = SystemCoreClock / 100;           // Set the tick window to 10ms
+    // Disable and deconfigure
+    US_TIMER->ctrl = 0;
+    US_TIMER->term_cnt32 = 0;
+    US_TIMER->inten = 0;
+    US_TIMER->intfl = MXC_F_TMR_INTFL_TIMER0;
 
-    int retval = TMR_Init(US_TIMER, TMR_PRESCALE_DIV_2_0, NULL);
-    MBED_ASSERT(retval == E_NO_ERROR);
+    // Configure and enable
+    US_TIMER->ctrl = MXC_F_TMR_CTRL_ENABLE0 |
+                     (US_TIMER_MODE << MXC_F_TMR_CTRL_MODE_POS) |
+                     (US_TIMER_PRESCALE << MXC_F_TMR_CTRL_PRESCALE_POS);
 
-    tmr32_cfg_t cfg;
-    cfg.mode = TMR32_MODE_CONTINUOUS;
-    cfg.polarity = TMR_POLARITY_UNUSED;
-    cfg.compareCount = 0xFFFFFFFF;
-    TMR32_Config(US_TIMER, &cfg);
-
-    NVIC_SetVector(US_TIMER_IRQn, (uint32_t)tmr_handler);
+    NVIC_SetVector(US_TIMER_IRQn, (uint32_t)us_ticker_irq_handler);
     NVIC_EnableIRQ(US_TIMER_IRQn);
-    TMR32_EnableINT(US_TIMER);
-
-    TMR32_Start(US_TIMER);
 }
 
 //******************************************************************************
-void us_ticker_deinit(void)
+void us_ticker_free(void)
 {
-    TMR32_Stop(US_TIMER);
-    TMR32_DisableINT(US_TIMER);
-    TMR32_ClearFlag(US_TIMER);
-    us_ticker_inited = 0;
+    US_TIMER->ctrl = 0;
 }
 
 //******************************************************************************
 uint32_t us_ticker_read(void)
 {
-    uint64_t current_cnt1, current_cnt2;
-    uint32_t cmp, cnt;
-    uint32_t flag1, flag2;
-    static uint32_t last = 0;
-
-    if (!us_ticker_inited) {
-        us_ticker_init();
-    }
-
-    // Ensure coherency between current_cnt and TMR32_GetCount()
-    do {
-        current_cnt1 = current_cnt;
-        flag1 = TMR32_GetFlag(US_TIMER);
-        cmp = TMR32_GetCompare(US_TIMER);
-        cnt = TMR32_GetCount(US_TIMER);
-        flag2 = TMR32_GetFlag(US_TIMER);
-        current_cnt2 = current_cnt;
-    } while ((current_cnt1 != current_cnt2) || (flag1 != flag2));
-
-    // Account for an unserviced interrupt
-    if (flag1) {
-        // Clear peripheral interrupt flag; leaving NVIC pending set
-        TMR32_ClearFlag(US_TIMER);
-        // Advance global count
-        inc_current_cnt(cmp + cnt);
-
-        current_cnt1 += cmp;
-    }
-
-    current_cnt1 += cnt;
-
-    assert(last <= (current_cnt1 / ticks_per_us));
-    last = (current_cnt1 / ticks_per_us);
-    return last;
+    return US_TIMER->count32;
 }
 
 //******************************************************************************
 void us_ticker_set_interrupt(timestamp_t timestamp)
 {
-    // Note: interrupts are disabled before this function is called.
-
-    TMR32_Stop(US_TIMER);
-
-    if (TMR32_GetFlag(US_TIMER)) {
-        TMR32_ClearFlag(US_TIMER);
-        NVIC_ClearPendingIRQ(US_TIMER_IRQn);
-        inc_current_cnt(TMR32_GetCompare(US_TIMER));
-    }
-
-    // add and reset the current count value
-    inc_current_cnt(TMR32_GetCount(US_TIMER));
-    TMR32_SetCount(US_TIMER, 0);
-
-    // add the number of cycles that the timer is disabled here for
-    inc_current_cnt(200);
-
-    event_cnt = (uint64_t)timestamp * ticks_per_us;
-
-    // Check to see if the event has already passed
-    if (!event_passed(current_cnt, event_cnt)) {
-        uint64_t diff = event_diff(current_cnt, event_cnt);
-        if (diff < (uint64_t)0xFFFFFFFF) {
-            // the event occurs before the next overflow
-            TMR32_SetCompare(US_TIMER, diff);
-        } else {
-            // the event occurs after the next overflow
-            TMR32_SetCompare(US_TIMER, 0xFFFFFFFF);  // set to max
-        }
-    } else {
-        // the requested timestamp occurs in the past
-        // set the timer up to immediately expire
-        TMR32_SetCompare(US_TIMER, 1);
-    }
-
-    TMR32_Start(US_TIMER);
+    US_TIMER->ctrl = 0;
+    US_TIMER->term_cnt32 = (timestamp) ? timestamp : 1;
+    US_TIMER->inten = MXC_F_TMR_INTEN_TIMER0;
+    US_TIMER->ctrl = MXC_F_TMR_CTRL_ENABLE0 |
+                     (US_TIMER_MODE << MXC_F_TMR_CTRL_MODE_POS) |
+                     (US_TIMER_PRESCALE << MXC_F_TMR_CTRL_PRESCALE_POS);
 }
 
 //******************************************************************************
 void us_ticker_fire_interrupt(void)
 {
-    TMR32_SetCompare(US_TIMER, 1);
+    NVIC_SetPendingIRQ(US_TIMER_IRQn);
 }
 
 //******************************************************************************
 void us_ticker_disable_interrupt(void)
 {
-    // There are no more events, set timer overflow to the max
-    TMR32_SetCompare(US_TIMER, 0xFFFFFFFF);
+    US_TIMER->inten = 0;
 }
 
 //******************************************************************************
 void us_ticker_clear_interrupt(void)
 {
-    // cleared in the local handler
+    US_TIMER->intfl = MXC_F_TMR_INTFL_TIMER0;
 }
 
 //******************************************************************************
-void us_ticker_set(timestamp_t timestamp)
+const ticker_info_t* us_ticker_get_info(void)
 {
-    TMR32_Stop(US_TIMER);
-    current_cnt = (uint64_t)timestamp * ticks_per_us;
-    TMR32_SetCount(US_TIMER, 0);
-    TMR32_SetCompare(US_TIMER, 0xFFFFFFFF);
-    TMR32_Start(US_TIMER);
+    static const ticker_info_t info = {
+        RO_FREQ >> US_TIMER_PRESCALE,
+        US_TIMER_WIDTH
+    };
 
-    if (((uint64_t)timestamp * ticks_per_us) >= event_cnt) {
-        // The next timestamp has elapsed. Trigger the interrupt to handle it.
-        NVIC_SetPendingIRQ(US_TIMER_IRQn);
-    }
+    return &info;
 }