Merge branch 'timer-l0-#816' of https://github.com/BartSX/mbed into BartSX-timer-l0-#816

pull/1824/head
0xc0170 2016-05-23 13:59:40 +01:00
commit 2b44bfbcc6
2 changed files with 36 additions and 19 deletions

View File

@ -40,7 +40,7 @@ uint32_t PreviousVal = 0;
void us_ticker_irq_handler(void); void us_ticker_irq_handler(void);
void set_compare(uint16_t count); void set_compare(uint16_t count);
extern volatile uint32_t SlaveCounter; extern volatile uint16_t SlaveCounter;
extern volatile uint32_t oc_int_part; extern volatile uint32_t oc_int_part;
extern volatile uint16_t oc_rem_part; extern volatile uint16_t oc_rem_part;

View File

@ -26,6 +26,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <stddef.h> #include <stddef.h>
#include <stdbool.h>
#include "us_ticker_api.h" #include "us_ticker_api.h"
#include "PeripheralNames.h" #include "PeripheralNames.h"
@ -34,8 +35,9 @@
static TIM_HandleTypeDef TimMasterHandle; static TIM_HandleTypeDef TimMasterHandle;
static int us_ticker_inited = 0; static int us_ticker_inited = 0;
static bool us_ticker_stabilized = false;
volatile uint32_t SlaveCounter = 0; volatile uint16_t SlaveCounter = 0;
volatile uint32_t oc_int_part = 0; volatile uint32_t oc_int_part = 0;
volatile uint16_t oc_rem_part = 0; volatile uint16_t oc_rem_part = 0;
@ -58,24 +60,39 @@ void us_ticker_init(void)
uint32_t us_ticker_read() uint32_t us_ticker_read()
{ {
uint32_t counter, counter2; volatile uint16_t cntH_old, cntH, cntL;
if (!us_ticker_inited) us_ticker_init(); if (!us_ticker_inited) us_ticker_init();
// A situation might appear when Master overflows right after Slave is read and before the
// new (overflowed) value of Master is read. Which would make the code below consider the // There's a situation where the first tick still may overflow and to avoid
// previous (incorrect) value of Slave and the new value of Master, which would return a // it we need to check if our ticker has stabilized and due to that we need
// value in the past. Avoid this by computing consecutive values of the timer until they // to return only the lower part of your 32 bit software timer.
// are properly ordered. if (us_ticker_stabilized) {
counter = (uint32_t)(SlaveCounter << 16); do {
counter += TIM_MST->CNT; // For some reason on L0xx series we need to read and clear the
while (1) { // overflow flag which give extra time to propelry handle possible
counter2 = (uint32_t)(SlaveCounter << 16); // hiccup after ~60s
counter2 += TIM_MST->CNT; if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1OF) == SET) {
if (counter2 > counter) { __HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC1OF);
break; }
} cntH_old = SlaveCounter;
counter = counter2; if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_UPDATE) == SET) {
cntH_old += 1;
}
cntL = TIM_MST->CNT;
cntH = SlaveCounter;
if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_UPDATE) == SET) {
cntH += 1;
}
} while(cntH_old != cntH);
} else {
us_ticker_stabilized = true;
return (uint32_t) TIM_MST->CNT;
} }
return counter2;
// Glue the upper and lower part together to get a 32 bit timer
return (uint32_t)(cntH << 16 | cntL);
} }
void us_ticker_set_interrupt(timestamp_t timestamp) void us_ticker_set_interrupt(timestamp_t timestamp)