Skip to content

Commit 840df6c

Browse files
committed
[NUCLEO_L053R8] Fix issue #816
NUCLEO_L053R8 is using a 16 bit timer as a internal ticker but the mBed ticker needs a 32 bit timer, so the upper upart of that timer is being calculated in software. Continous HIGH/LOW voltage levels were observerd for 65ms due to timer overflow, so to narrow down the issue, it was decided to switch to 16 bit values and glue them to get a 32 bit timer. Change-Id: I54a06d5aa0f8ddabd8abc194470845a2509e0c55
1 parent 1d1f7ab commit 840df6c

File tree

2 files changed

+36
-19
lines changed
  • libraries/mbed/targets

2 files changed

+36
-19
lines changed

libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/hal_tick.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ uint32_t PreviousVal = 0;
4040
void us_ticker_irq_handler(void);
4141
void set_compare(uint16_t count);
4242

43-
extern volatile uint32_t SlaveCounter;
43+
extern volatile uint16_t SlaveCounter;
4444
extern volatile uint32_t oc_int_part;
4545
extern volatile uint16_t oc_rem_part;
4646

libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32L0/us_ticker.c

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2727
*/
2828
#include <stddef.h>
29+
#include <stdbool.h>
2930
#include "us_ticker_api.h"
3031
#include "PeripheralNames.h"
3132

@@ -34,8 +35,9 @@
3435

3536
static TIM_HandleTypeDef TimMasterHandle;
3637
static int us_ticker_inited = 0;
38+
static bool us_ticker_stabilized = false;
3739

38-
volatile uint32_t SlaveCounter = 0;
40+
volatile uint16_t SlaveCounter = 0;
3941
volatile uint32_t oc_int_part = 0;
4042
volatile uint16_t oc_rem_part = 0;
4143

@@ -58,24 +60,39 @@ void us_ticker_init(void)
5860

5961
uint32_t us_ticker_read()
6062
{
61-
uint32_t counter, counter2;
63+
volatile uint16_t cntH_old, cntH, cntL;
64+
6265
if (!us_ticker_inited) us_ticker_init();
63-
// A situation might appear when Master overflows right after Slave is read and before the
64-
// new (overflowed) value of Master is read. Which would make the code below consider the
65-
// previous (incorrect) value of Slave and the new value of Master, which would return a
66-
// value in the past. Avoid this by computing consecutive values of the timer until they
67-
// are properly ordered.
68-
counter = (uint32_t)(SlaveCounter << 16);
69-
counter += TIM_MST->CNT;
70-
while (1) {
71-
counter2 = (uint32_t)(SlaveCounter << 16);
72-
counter2 += TIM_MST->CNT;
73-
if (counter2 > counter) {
74-
break;
75-
}
76-
counter = counter2;
77-
}
78-
return counter2;
66+
67+
// There's a situation where the first tick still may overflow and to avoid
68+
// it we need to check if our ticker has stabilized and due to that we need
69+
// to return only the lower part of your 32 bit software timer.
70+
if (us_ticker_stabilized) {
71+
do {
72+
// For some reason on L0xx series we need to read and clear the
73+
// overflow flag which give extra time to propelry handle possible
74+
// hiccup after ~60s
75+
if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1OF) == SET) {
76+
__HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC1OF);
77+
}
78+
cntH_old = SlaveCounter;
79+
if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_UPDATE) == SET) {
80+
cntH_old += 1;
81+
}
82+
cntL = TIM_MST->CNT;
83+
84+
cntH = SlaveCounter;
85+
if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_UPDATE) == SET) {
86+
cntH += 1;
87+
}
88+
} while(cntH_old != cntH);
89+
} else {
90+
us_ticker_stabilized = true;
91+
return (uint32_t) TIM_MST->CNT;
92+
}
93+
94+
// Glue the upper and lower part together to get a 32 bit timer
95+
return (uint32_t)(cntH << 16 | cntL);
7996
}
8097

8198
void us_ticker_set_interrupt(timestamp_t timestamp)

0 commit comments

Comments
 (0)