mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Revision:
84:f54042cbc282
Parent:
76:aeb1df146756
Child:
87:085cde657901
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/us_ticker.c	Fri Jan 31 10:15:06 2014 +0000
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_L152RE/us_ticker.c	Mon Feb 03 09:30:05 2014 +0000
@@ -29,60 +29,68 @@
 #include "us_ticker_api.h"
 #include "PeripheralNames.h"
 
-// Timers selection:
-// The Master timer clocks the Slave timer
+// Timer selection:
+#define TIM_MST            TIM9
+#define TIM_MST_IRQ        TIM9_IRQn
+#define TIM_MST_RCC        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE)
 
-#define TIM_MST     TIM9
-#define TIM_MST_IRQ TIM9_IRQn
-#define TIM_MST_RCC RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE)
+static int      us_ticker_inited = 0;
+static uint32_t SlaveCounter = 0;
+static uint32_t us_ticker_int_counter = 0;
+static uint16_t us_ticker_int_remainder = 0;
+
+static void tim_update_oc_irq_handler(void) {
+    // Update interrupt: increment the slave counter
+    if (TIM_GetITStatus(TIM_MST, TIM_IT_Update) == SET) {
+        TIM_ClearITPendingBit(TIM_MST, TIM_IT_Update);
+        SlaveCounter++;
+    }
 
-#define TIM_SLV     TIM4
-#define TIM_SLV_IRQ TIM4_IRQn
-#define TIM_SLV_RCC RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE)
-
-#define MST_SLV_ITR TIM_TS_ITR3
+    // Output compare interrupt: used by interrupt system
+    if (TIM_GetITStatus(TIM_MST, TIM_IT_CC1) == SET) {
+        TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1);    
+        if (us_ticker_int_counter > 0) {
+            TIM_SetCompare1(TIM_MST, 0xFFFF);
+            us_ticker_int_counter--;
+        } else {
+            if (us_ticker_int_remainder > 0) {
+                TIM_SetCompare1(TIM_MST, us_ticker_int_remainder);
+                us_ticker_int_remainder = 0;
+            } else {
+                // This function is going to disable the interrupts if there are
+                // no other events in the queue
+                us_ticker_irq_handler();
+            }
+        }
+    }
+}
 
-int us_ticker_inited = 0;
-
-void us_ticker_init(void) {
-    
+void us_ticker_init(void) {    
     TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
-    TIM_OCInitTypeDef TIM_OCInitStructure;
-
+  
     if (us_ticker_inited) return;
     us_ticker_inited = 1;
   
-    // Enable Timers clock
+    // Enable Timer clock
     TIM_MST_RCC;
-    TIM_SLV_RCC;
   
-    // Master and Slave timers time base configuration
+    // Configure time base
     TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
     TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
     TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick
     TIM_TimeBaseStructure.TIM_ClockDivision = 0;
     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
     TIM_TimeBaseInit(TIM_MST, &TIM_TimeBaseStructure);
-    TIM_TimeBaseStructure.TIM_Prescaler = 0;
-    TIM_TimeBaseInit(TIM_SLV, &TIM_TimeBaseStructure);  
-
-    // Master timer configuration
-    TIM_OCStructInit(&TIM_OCInitStructure);
-    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
-    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
-    TIM_OCInitStructure.TIM_Pulse = 0;
-    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
-    TIM_OC1Init(TIM_MST, &TIM_OCInitStructure);
-    TIM_SelectMasterSlaveMode(TIM_MST, TIM_MasterSlaveMode_Enable);
-    TIM_SelectOutputTrigger(TIM_MST, TIM_TRGOSource_Update);
+    
+    // Configure interrupts
+    TIM_ITConfig(TIM_MST, TIM_IT_Update, ENABLE);
+    TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);
     
-    // Slave timer configuration
-    TIM_SelectSlaveMode(TIM_SLV, TIM_SlaveMode_External1);
-    // The connection between Master and Slave is done here
-    TIM_SelectInputTrigger(TIM_SLV, MST_SLV_ITR);
+    // For 32-bit counter and output compare
+    NVIC_SetVector(TIM_MST_IRQ, (uint32_t)tim_update_oc_irq_handler);
+    NVIC_EnableIRQ(TIM_MST_IRQ);
   
-    // Enable timers
-    TIM_Cmd(TIM_SLV, ENABLE);
+    // Enable timer
     TIM_Cmd(TIM_MST, ENABLE);
 }
 
@@ -94,10 +102,10 @@
     // previous (incorrect) value of Slave and the new value of Master, which would return a
     // value in the past. Avoid this by computing consecutive values of the timer until they
     // are properly ordered.
-    counter = (uint32_t)((uint32_t)TIM_GetCounter(TIM_SLV) << 16);
+    counter = (uint32_t)(SlaveCounter << 16);
     counter += (uint32_t)TIM_GetCounter(TIM_MST);
     while (1) {
-        counter2 = (uint32_t)((uint32_t)TIM_GetCounter(TIM_SLV) << 16);
+        counter2 = (uint32_t)(SlaveCounter << 16);
         counter2 += (uint32_t)TIM_GetCounter(TIM_MST);
         if (counter2 > counter) {
             break;
@@ -108,26 +116,31 @@
 }
 
 void us_ticker_set_interrupt(unsigned int timestamp) {
-    if (timestamp > 0xFFFF) {
-        TIM_SetCompare1(TIM_SLV, (uint16_t)((timestamp >> 16) & 0xFFFF));
-        TIM_ITConfig(TIM_SLV, TIM_IT_CC1, ENABLE);
-        NVIC_SetVector(TIM_SLV_IRQ, (uint32_t)us_ticker_irq_handler);
-        NVIC_EnableIRQ(TIM_SLV_IRQ);      
+    int delta = (int)(timestamp - us_ticker_read());
+
+    if (delta <= 0) { // This event was in the past
+        us_ticker_irq_handler();
+        return;
     }
     else {
-        TIM_SetCompare1(TIM_MST, (uint16_t)timestamp);
-        TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);  
-        NVIC_SetVector(TIM_MST_IRQ, (uint32_t)us_ticker_irq_handler);
-        NVIC_EnableIRQ(TIM_MST_IRQ);
+        us_ticker_int_counter   = (uint32_t)(delta >> 16);
+        us_ticker_int_remainder = (uint16_t)(delta & 0xFFFF);
+        if (us_ticker_int_counter > 0) { // means delta > 0xFFFF
+            TIM_SetCompare1(TIM_MST, 0xFFFF);
+            us_ticker_int_counter--;
+        } else {
+            TIM_SetCompare1(TIM_MST, us_ticker_int_remainder);
+            us_ticker_int_remainder = 0;
+        }
     }
 }
 
 void us_ticker_disable_interrupt(void) {
     TIM_ITConfig(TIM_MST, TIM_IT_CC1, DISABLE);
-    TIM_ITConfig(TIM_SLV, TIM_IT_CC1, DISABLE);
 }
 
 void us_ticker_clear_interrupt(void) {
-    TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1);
-    TIM_ClearITPendingBit(TIM_SLV, TIM_IT_CC1);
+    if (TIM_GetITStatus(TIM_MST, TIM_IT_CC1) == SET) {
+        TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1);
+    }
 }