Skip to content

Commit a08c8d7

Browse files
authored
Merge pull request stm32duino#477 from fpistm/delay
[Time] Review delay
2 parents ca6956f + 32dc53f commit a08c8d7

File tree

8 files changed

+186
-22
lines changed

8 files changed

+186
-22
lines changed

cores/arduino/board.h

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "clock.h"
1111
#include "core_callback.h"
1212
#include "digital_io.h"
13+
#include "dwt.h"
1314
#include "hw_config.h"
1415
#include "low_power.h"
1516
#include "rtc.h"

cores/arduino/stm32/clock.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ extern "C" {
4848
* @param None
4949
* @retval None
5050
*/
51-
uint32_t GetCurrentMicro(void)
51+
uint32_t getCurrentMicros(void)
5252
{
5353
/* Ensure COUNTFLAG is reset by reading SysTick control and status register */
5454
LL_SYSTICK_IsActiveCounterFlag();
@@ -66,7 +66,7 @@ uint32_t GetCurrentMicro(void)
6666
* @param None
6767
* @retval None
6868
*/
69-
uint32_t GetCurrentMilli(void)
69+
uint32_t getCurrentMillis(void)
7070
{
7171
return HAL_GetTick();
7272
}
@@ -78,7 +78,7 @@ void noOsSystickHandler()
7878

7979
void osSystickHandler() __attribute__((weak, alias("noOsSystickHandler")));
8080
/**
81-
* @brief Function called when t he tick interruption falls
81+
* @brief Function called when the tick interruption falls
8282
* @param None
8383
* @retval None
8484
*/

cores/arduino/stm32/clock.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ typedef enum {
5858
/* Exported constants --------------------------------------------------------*/
5959
/* Exported macro ------------------------------------------------------------*/
6060
/* Exported functions ------------------------------------------------------- */
61-
uint32_t GetCurrentMilli(void);
62-
uint32_t GetCurrentMicro(void);
61+
uint32_t getCurrentMillis(void);
62+
uint32_t getCurrentMicros(void);
6363

6464
void enableClock(sourceClock_t source);
6565
#ifdef __cplusplus

cores/arduino/stm32/dwt.c

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/**
2+
******************************************************************************
3+
* @file dwt.c
4+
* @author Frederic Pillon
5+
* @brief Provide Data Watchpoint and Trace services
6+
******************************************************************************
7+
* @attention
8+
*
9+
* Copyright (c) 2019, STMicroelectronics
10+
* All rights reserved.
11+
*
12+
* This software component is licensed by ST under BSD 3-Clause license,
13+
* the "License"; You may not use this file except in compliance with the
14+
* License. You may obtain a copy of the License at:
15+
* opensource.org/licenses/BSD-3-Clause
16+
*
17+
******************************************************************************
18+
*/
19+
20+
#include "dwt.h"
21+
22+
#ifdef DWT_BASE
23+
#ifdef __cplusplus
24+
extern "C" {
25+
#endif
26+
27+
28+
uint32_t dwt_init(void)
29+
{
30+
31+
/* Enable use of DWT */
32+
if (!(CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk)) {
33+
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
34+
}
35+
36+
/* Unlock */
37+
dwt_access(true);
38+
39+
/* Reset the clock cycle counter value */
40+
DWT->CYCCNT = 0;
41+
42+
/* Enable clock cycle counter */
43+
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
44+
45+
/* 3 NO OPERATION instructions */
46+
asm volatile(" nop \n\t"
47+
" nop \n\t"
48+
" nop \n\t");
49+
50+
/* Check if clock cycle counter has started */
51+
return (DWT->CYCCNT) ? 0 : 1;
52+
}
53+
54+
void dwt_access(bool ena)
55+
{
56+
#if (__CORTEX_M == 0x07U)
57+
/*
58+
* Define DWT LSR mask which is (currentuly) not defined by the CMSIS.
59+
* Same as ITM LSR one.
60+
*/
61+
#if !defined DWT_LSR_Present_Msk
62+
#define DWT_LSR_Present_Msk ITM_LSR_Present_Msk
63+
#endif
64+
#if !defined DWT_LSR_Access_Msk
65+
#define DWT_LSR_Access_Msk ITM_LSR_Access_Msk
66+
#endif
67+
uint32_t lsr = DWT->LSR;
68+
69+
if ((lsr & DWT_LSR_Present_Msk) != 0) {
70+
if (ena) {
71+
if ((lsr & DWT_LSR_Access_Msk) != 0) { //locked
72+
DWT->LAR = 0xC5ACCE55;
73+
}
74+
} else {
75+
if ((lsr & DWT_LSR_Access_Msk) == 0) { //unlocked
76+
DWT->LAR = 0;
77+
}
78+
}
79+
}
80+
#else /* __CORTEX_M */
81+
UNUSED(ena);
82+
#endif /* __CORTEX_M */
83+
}
84+
85+
#ifdef __cplusplus
86+
}
87+
#endif
88+
89+
#endif

cores/arduino/stm32/dwt.h

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
******************************************************************************
3+
* @file dwt.h
4+
* @author Frederic Pillon
5+
* @brief Header for dwt.c module
6+
******************************************************************************
7+
* @attention
8+
*
9+
* Copyright (c) 2019, STMicroelectronics
10+
* All rights reserved.
11+
*
12+
* This software component is licensed by ST under BSD 3-Clause license,
13+
* the "License"; You may not use this file except in compliance with the
14+
* License. You may obtain a copy of the License at:
15+
* opensource.org/licenses/BSD-3-Clause
16+
*
17+
******************************************************************************
18+
*/
19+
20+
/* Define to prevent recursive inclusion -------------------------------------*/
21+
#ifndef _DWT_H_
22+
#define _DWT_H_
23+
24+
#include "stm32_def.h"
25+
#include <stdbool.h>
26+
27+
#ifdef DWT_BASE
28+
29+
#ifdef __cplusplus
30+
extern "C" {
31+
#endif
32+
33+
uint32_t dwt_init(void);
34+
void dwt_access(bool ena);
35+
36+
static inline uint32_t dwt_max_sec(void)
37+
{
38+
return (UINT32_MAX / SystemCoreClock);
39+
};
40+
41+
static inline uint32_t dwt_max_msec(void)
42+
{
43+
return (UINT32_MAX / (SystemCoreClock / 1000));
44+
};
45+
46+
static inline uint32_t dwt_max_usec(void)
47+
{
48+
return (UINT32_MAX / (SystemCoreClock / 1000000));
49+
};
50+
51+
static inline uint32_t dwt_getCycles(void)
52+
{
53+
return (DWT->CYCCNT);
54+
};
55+
56+
#ifdef __cplusplus
57+
}
58+
#endif
59+
60+
#endif /* DWT_BASE */
61+
#endif /* _DWT_H_ */

cores/arduino/stm32/hw_config.c

+9-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "stm32_def.h"
3939
#include "hw_config.h"
4040
#include "usbd_if.h"
41+
#include "dwt.h"
4142

4243
#ifdef __cplusplus
4344
extern "C" {
@@ -50,15 +51,21 @@ extern "C" {
5051
*/
5152
void hw_config_init(void)
5253
{
53-
//Initialize the HAL
54+
/* Init DWT if present */
55+
#ifdef DWT_BASE
56+
dwt_init();
57+
#endif
58+
59+
/* Initialize the HAL */
5460
HAL_Init();
5561

56-
// Configure the system clock
62+
/* Configure the system clock */
5763
SystemClock_Config();
5864

5965
#if defined (USBCON) && defined(USBD_USE_CDC)
6066
USBD_CDC_init();
6167
#endif
68+
6269
}
6370
#ifdef __cplusplus
6471
}

cores/arduino/wiring_time.c

+8-9
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,24 @@ extern "C" {
2424

2525
uint32_t millis(void)
2626
{
27-
// todo: ensure no interrupts
28-
return GetCurrentMilli() ;
27+
// ToDo: ensure no interrupts
28+
return getCurrentMillis();
2929
}
3030

3131
// Interrupt-compatible version of micros
3232
uint32_t micros(void)
3333
{
34-
return GetCurrentMicro();
34+
return getCurrentMicros();
3535
}
3636

3737
void delay(uint32_t ms)
3838
{
39-
if (ms == 0) {
40-
return;
39+
if (ms != 0) {
40+
uint32_t start = getCurrentMillis();
41+
do {
42+
yield();
43+
} while (getCurrentMillis() - start < ms);
4144
}
42-
uint32_t start = GetCurrentMilli();
43-
do {
44-
yield();
45-
} while (GetCurrentMilli() - start < ms);
4645
}
4746

4847
#ifdef __cplusplus

cores/arduino/wiring_time.h

+13-6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define _WIRING_TIME_H_
2222

2323
#include "clock.h"
24+
#include "dwt.h"
2425

2526
#ifdef __cplusplus
2627
extern "C" {
@@ -50,21 +51,27 @@ extern uint32_t micros(void) ;
5051
* \brief Pauses the program for the amount of time (in miliseconds) specified as parameter.
5152
* (There are 1000 milliseconds in a second.)
5253
*
53-
* \param dwMs the number of milliseconds to pause (uint32_t)
54+
* \param ms the number of milliseconds to pause (uint32_t)
5455
*/
55-
extern void delay(uint32_t dwMs) ;
56+
extern void delay(uint32_t ms) ;
5657

5758
/**
5859
* \brief Pauses the program for the amount of time (in microseconds) specified as parameter.
5960
*
60-
* \param dwUs the number of microseconds to pause (uint32_t)
61+
* \param us the number of microseconds to pause (uint32_t)
6162
*/
6263
static inline void delayMicroseconds(uint32_t) __attribute__((always_inline, unused));
63-
static inline void delayMicroseconds(uint32_t usec)
64+
static inline void delayMicroseconds(uint32_t us)
6465
{
65-
uint32_t start = GetCurrentMicro();
66+
#if defined(DWT_BASE) && !defined(DWT_DELAY_DISABLED)
67+
int32_t start = dwt_getCycles();
68+
int32_t cycles = us * (SystemCoreClock / 1000000);
6669

67-
while ((start + usec) > GetCurrentMicro());
70+
while ((int32_t)dwt_getCycles() - start < cycles);
71+
#else
72+
uint32_t start = getCurrentMicros();
73+
while (getCurrentMicros() - start < us);
74+
#endif
6875
}
6976

7077
#ifdef __cplusplus

0 commit comments

Comments
 (0)