Skip to content

[Time] Review delay #477

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cores/arduino/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "clock.h"
#include "core_callback.h"
#include "digital_io.h"
#include "dwt.h"
#include "hw_config.h"
#include "low_power.h"
#include "rtc.h"
Expand Down
6 changes: 3 additions & 3 deletions cores/arduino/stm32/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ extern "C" {
* @param None
* @retval None
*/
uint32_t GetCurrentMicro(void)
uint32_t getCurrentMicros(void)
{
/* Ensure COUNTFLAG is reset by reading SysTick control and status register */
LL_SYSTICK_IsActiveCounterFlag();
Expand All @@ -66,7 +66,7 @@ uint32_t GetCurrentMicro(void)
* @param None
* @retval None
*/
uint32_t GetCurrentMilli(void)
uint32_t getCurrentMillis(void)
{
return HAL_GetTick();
}
Expand All @@ -78,7 +78,7 @@ void noOsSystickHandler()

void osSystickHandler() __attribute__((weak, alias("noOsSystickHandler")));
/**
* @brief Function called when t he tick interruption falls
* @brief Function called when the tick interruption falls
* @param None
* @retval None
*/
Expand Down
4 changes: 2 additions & 2 deletions cores/arduino/stm32/clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ typedef enum {
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
uint32_t GetCurrentMilli(void);
uint32_t GetCurrentMicro(void);
uint32_t getCurrentMillis(void);
uint32_t getCurrentMicros(void);

void enableClock(sourceClock_t source);
#ifdef __cplusplus
Expand Down
89 changes: 89 additions & 0 deletions cores/arduino/stm32/dwt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
******************************************************************************
* @file dwt.c
* @author Frederic Pillon
* @brief Provide Data Watchpoint and Trace services
******************************************************************************
* @attention
*
* Copyright (c) 2019, STMicroelectronics
* All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/

#include "dwt.h"

#ifdef DWT_BASE
#ifdef __cplusplus
extern "C" {
#endif


uint32_t dwt_init(void)
{

/* Enable use of DWT */
if (!(CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk)) {
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
}

/* Unlock */
dwt_access(true);

/* Reset the clock cycle counter value */
DWT->CYCCNT = 0;

/* Enable clock cycle counter */
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;

/* 3 NO OPERATION instructions */
asm volatile(" nop \n\t"
" nop \n\t"
" nop \n\t");

/* Check if clock cycle counter has started */
return (DWT->CYCCNT) ? 0 : 1;
}

void dwt_access(bool ena)
{
#if (__CORTEX_M == 0x07U)
/*
* Define DWT LSR mask which is (currentuly) not defined by the CMSIS.
* Same as ITM LSR one.
*/
#if !defined DWT_LSR_Present_Msk
#define DWT_LSR_Present_Msk ITM_LSR_Present_Msk
#endif
#if !defined DWT_LSR_Access_Msk
#define DWT_LSR_Access_Msk ITM_LSR_Access_Msk
#endif
uint32_t lsr = DWT->LSR;

if ((lsr & DWT_LSR_Present_Msk) != 0) {
if (ena) {
if ((lsr & DWT_LSR_Access_Msk) != 0) { //locked
DWT->LAR = 0xC5ACCE55;
}
} else {
if ((lsr & DWT_LSR_Access_Msk) == 0) { //unlocked
DWT->LAR = 0;
}
}
}
#else /* __CORTEX_M */
UNUSED(ena);
#endif /* __CORTEX_M */
}

#ifdef __cplusplus
}
#endif

#endif
61 changes: 61 additions & 0 deletions cores/arduino/stm32/dwt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
******************************************************************************
* @file dwt.h
* @author Frederic Pillon
* @brief Header for dwt.c module
******************************************************************************
* @attention
*
* Copyright (c) 2019, STMicroelectronics
* All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _DWT_H_
#define _DWT_H_

#include "stm32_def.h"
#include <stdbool.h>

#ifdef DWT_BASE

#ifdef __cplusplus
extern "C" {
#endif

uint32_t dwt_init(void);
void dwt_access(bool ena);

static inline uint32_t dwt_max_sec(void)
{
return (UINT32_MAX / SystemCoreClock);
};

static inline uint32_t dwt_max_msec(void)
{
return (UINT32_MAX / (SystemCoreClock / 1000));
};

static inline uint32_t dwt_max_usec(void)
{
return (UINT32_MAX / (SystemCoreClock / 1000000));
};

static inline uint32_t dwt_getCycles(void)
{
return (DWT->CYCCNT);
};

#ifdef __cplusplus
}
#endif

#endif /* DWT_BASE */
#endif /* _DWT_H_ */
11 changes: 9 additions & 2 deletions cores/arduino/stm32/hw_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "stm32_def.h"
#include "hw_config.h"
#include "usbd_if.h"
#include "dwt.h"

#ifdef __cplusplus
extern "C" {
Expand All @@ -50,15 +51,21 @@ extern "C" {
*/
void hw_config_init(void)
{
//Initialize the HAL
/* Init DWT if present */
#ifdef DWT_BASE
dwt_init();
#endif

/* Initialize the HAL */
HAL_Init();

// Configure the system clock
/* Configure the system clock */
SystemClock_Config();

#if defined (USBCON) && defined(USBD_USE_CDC)
USBD_CDC_init();
#endif

}
#ifdef __cplusplus
}
Expand Down
17 changes: 8 additions & 9 deletions cores/arduino/wiring_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,24 @@ extern "C" {

uint32_t millis(void)
{
// todo: ensure no interrupts
return GetCurrentMilli() ;
// ToDo: ensure no interrupts
return getCurrentMillis();
}

// Interrupt-compatible version of micros
uint32_t micros(void)
{
return GetCurrentMicro();
return getCurrentMicros();
}

void delay(uint32_t ms)
{
if (ms == 0) {
return;
if (ms != 0) {
uint32_t start = getCurrentMillis();
do {
yield();
} while (getCurrentMillis() - start < ms);
}
uint32_t start = GetCurrentMilli();
do {
yield();
} while (GetCurrentMilli() - start < ms);
}

#ifdef __cplusplus
Expand Down
19 changes: 13 additions & 6 deletions cores/arduino/wiring_time.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define _WIRING_TIME_H_

#include "clock.h"
#include "dwt.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -50,21 +51,27 @@ extern uint32_t micros(void) ;
* \brief Pauses the program for the amount of time (in miliseconds) specified as parameter.
* (There are 1000 milliseconds in a second.)
*
* \param dwMs the number of milliseconds to pause (uint32_t)
* \param ms the number of milliseconds to pause (uint32_t)
*/
extern void delay(uint32_t dwMs) ;
extern void delay(uint32_t ms) ;

/**
* \brief Pauses the program for the amount of time (in microseconds) specified as parameter.
*
* \param dwUs the number of microseconds to pause (uint32_t)
* \param us the number of microseconds to pause (uint32_t)
*/
static inline void delayMicroseconds(uint32_t) __attribute__((always_inline, unused));
static inline void delayMicroseconds(uint32_t usec)
static inline void delayMicroseconds(uint32_t us)
{
uint32_t start = GetCurrentMicro();
#if defined(DWT_BASE) && !defined(DWT_DELAY_DISABLED)
int32_t start = dwt_getCycles();
int32_t cycles = us * (SystemCoreClock / 1000000);

while ((start + usec) > GetCurrentMicro());
while ((int32_t)dwt_getCycles() - start < cycles);
#else
uint32_t start = getCurrentMicros();
while (getCurrentMicros() - start < us);
#endif
}

#ifdef __cplusplus
Expand Down