From 0b133be504b411755bf87ff069fa410ba8f6e3bb Mon Sep 17 00:00:00 2001 From: bcostm Date: Tue, 10 Jul 2018 13:21:42 +0200 Subject: [PATCH] stm32 ticker: change th eplace where timer init in done, fix overflow issue with 16-bit timer - Move back the 16/32bit timer initialization in HAL_InitTick() and not in us_ticker_init() - Use ticker_read_us() and us_ticker_read() in HAL_GetTick() to fix potential overflow issue with the 16bit timer ==> These corrections allow timer, rtc, sleep, tick tests to PASS --- targets/TARGET_STM/hal_tick_overrides.c | 46 ++++++++++++++-- targets/TARGET_STM/us_ticker.c | 70 ++++++++++++------------- 2 files changed, 77 insertions(+), 39 deletions(-) diff --git a/targets/TARGET_STM/hal_tick_overrides.c b/targets/TARGET_STM/hal_tick_overrides.c index d5aac77fdf..af0f1347c2 100644 --- a/targets/TARGET_STM/hal_tick_overrides.c +++ b/targets/TARGET_STM/hal_tick_overrides.c @@ -1,5 +1,5 @@ /* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited + * Copyright (c) 2006-2018 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,18 +14,58 @@ * limitations under the License. */ #include "hal/us_ticker_api.h" +#include "us_ticker_data.h" + +// This variable is set to 1 at the of mbed_sdk_init function. +// The ticker_read_us function must not be called until the mbed_sdk_init is terminated. +extern int mbed_sdk_inited; + +// Defined in us_ticker.c +void init_16bit_timer(void); +void init_32bit_timer(void); + +#if TIM_MST_BIT_WIDTH == 16 +// Variables also reset in us_ticker_init() +uint32_t prev_time = 0; +uint32_t elapsed_time = 0; +#endif // Overwrite default HAL functions defined as "weak" HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) { - us_ticker_init(); +#if TIM_MST_BIT_WIDTH == 16 + init_16bit_timer(); +#else + init_32bit_timer(); +#endif return HAL_OK; } uint32_t HAL_GetTick() { - return 0; +#if TIM_MST_BIT_WIDTH == 16 + uint32_t new_time; + if (mbed_sdk_inited) { + // Apply the latest time recorded just before the sdk is inited + new_time = ticker_read_us(get_us_ticker_data()) + prev_time; + prev_time = 0; // Use this time only once + return (new_time / 1000); + } + else { + new_time = us_ticker_read(); + elapsed_time += (new_time - prev_time) & 0xFFFF; // Only use the lower 16 bits + prev_time = new_time; + return (elapsed_time / 1000); + } +#else // 32-bit timer + if (mbed_sdk_inited) { + return (ticker_read_us(get_us_ticker_data()) / 1000); + } + else { + return (us_ticker_read() / 1000); + } +#endif } void HAL_SuspendTick(void) diff --git a/targets/TARGET_STM/us_ticker.c b/targets/TARGET_STM/us_ticker.c index 3aef2a0a9e..a04f70527d 100644 --- a/targets/TARGET_STM/us_ticker.c +++ b/targets/TARGET_STM/us_ticker.c @@ -1,5 +1,5 @@ /* mbed Microcontroller Library - * Copyright (c) 2006-2016 ARM Limited + * Copyright (c) 2006-2018 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,9 @@ TIM_HandleTypeDef TimMasterHandle; -bool us_ticker_initialized = false; +uint32_t timer_cnt_reg; +uint32_t timer_ccr1_reg; +uint32_t timer_dier_reg; const ticker_info_t *us_ticker_get_info() { @@ -36,6 +38,9 @@ void us_ticker_irq_handler(void); // ************************************ 16-bit timer ************************************ #if TIM_MST_BIT_WIDTH == 16 +extern uint32_t prev_time; +extern uint32_t elapsed_time; + #if defined(TARGET_STM32F0) void timer_update_irq_handler(void) { @@ -60,32 +65,8 @@ void timer_oc_irq_handler(void) } } -// ************************************ 32-bit timer ************************************ -#else - -void timer_irq_handler(void) +void init_16bit_timer(void) { - TimMasterHandle.Instance = TIM_MST; - if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1) == SET) { - if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_CC1) == SET) { - __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC1); - us_ticker_irq_handler(); - } - } -} - -#endif // 16-bit/32-bit timer - -void us_ticker_init(void) -{ - if (us_ticker_initialized) { - __HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC1); - __HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC1); - return; - } - -// ************************************ 16-bit timer ************************************ -#if TIM_MST_BIT_WIDTH == 16 // Enable timer clock TIM_MST_RCC; @@ -137,9 +118,27 @@ void us_ticker_init(void) __HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC1); + // Used by HAL_GetTick() + prev_time = 0; + elapsed_time = 0; +} + // ************************************ 32-bit timer ************************************ #else +void timer_irq_handler(void) +{ + TimMasterHandle.Instance = TIM_MST; + if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1) == SET) { + if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_CC1) == SET) { + __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC1); + us_ticker_irq_handler(); + } + } +} + +void init_32bit_timer(void) +{ RCC_ClkInitTypeDef RCC_ClkInitStruct; uint32_t PclkFreq; @@ -162,8 +161,8 @@ void us_ticker_init(void) TIM_MST_RESET_OFF; // Configure time base - TimMasterHandle.Instance = TIM_MST; - TimMasterHandle.Init.Period = 0xFFFFFFFF; + TimMasterHandle.Instance = TIM_MST; + TimMasterHandle.Init.Period = 0xFFFFFFFF; // TIMxCLK = PCLKx when the APB prescaler = 1 else TIMxCLK = 2 * PCLKx #if TIM_MST_PCLK == 1 @@ -199,11 +198,14 @@ void us_ticker_init(void) #endif __HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC1); +} #endif // 16-bit/32-bit timer - us_ticker_initialized = true; - +void us_ticker_init(void) +{ + // Timer is already initialized in HAL_InitTick() + __HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC1); } uint32_t us_ticker_read() @@ -241,10 +243,6 @@ void us_ticker_clear_interrupt(void) __HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC1); } -uint32_t timer_cnt_reg; -uint32_t timer_ccr1_reg; -uint32_t timer_dier_reg; - void save_timer_ctx(void) { timer_cnt_reg = __HAL_TIM_GET_COUNTER(&TimMasterHandle); @@ -257,4 +255,4 @@ void restore_timer_ctx(void) __HAL_TIM_SET_COUNTER(&TimMasterHandle, timer_cnt_reg); __HAL_TIM_SET_COMPARE(&TimMasterHandle, TIM_CHANNEL_1, timer_ccr1_reg); TIM_MST->DIER = timer_dier_reg; -} \ No newline at end of file +}