Init commit
- Import assignment 1 files and repo - Assignment 2 code
This commit is contained in:
Submodule
+1
Submodule assignment_2/Libraries/STM32CubeF4 added at e00530150f
Submodule
+1
Submodule assignment_2/report/config added at ddb6624bbf
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 9.8 KiB |
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 9.7 KiB |
@@ -0,0 +1,289 @@
|
||||
/*!
|
||||
* \file
|
||||
* NUCLEO_F401RE.h
|
||||
* \brief
|
||||
* Nucleo F401RE port file. This file contain the implementation of driver
|
||||
* calls for F401RE board.
|
||||
*
|
||||
* Created on: May 23, 2020
|
||||
* Author: Christos Choutouridis AEM: 8997
|
||||
* email : <cchoutou@ece.auth.gr>
|
||||
*/
|
||||
#include "NUCLEO_F401RE.h"
|
||||
|
||||
/*
|
||||
* =============== System ===============
|
||||
*/
|
||||
|
||||
static clock_t volatile __ticks; //!< CPU time
|
||||
static time_t volatile __now; //!< Time in UNIX seconds past 1-Jan-70
|
||||
static clock_t volatile __sys_freq; //!< The CPU's time frequency (SysTick freq)
|
||||
|
||||
/*!
|
||||
* \brief
|
||||
* This is the SysTick ISR, micro-system time base service for CPU time.
|
||||
* \note
|
||||
* This service implements the SysTick callback function in order
|
||||
* to provide micro system - os like functionalities to an application
|
||||
* without RTOS
|
||||
*/
|
||||
void SysTick_Handler(void) {
|
||||
// Time
|
||||
++__ticks;
|
||||
if ( !(__ticks % __sys_freq ) )
|
||||
++__now; // Do not update __now when we have external time system
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief This function configures the source of the time base.
|
||||
* The time source is configured to have 1ms time base with a dedicated
|
||||
* Tick interrupt priority.
|
||||
* \param sf Tick interrupt frequency.
|
||||
* \retval HAL status
|
||||
*/
|
||||
__weak HAL_StatusTypeDef HAL_SysTick_Init(clock_t sf) {
|
||||
SystemCoreClockUpdate ();
|
||||
|
||||
/* Configure the SysTick to have interrupt in sf time basis */
|
||||
if (SysTick_Config (SystemCoreClock/sf) != 0)
|
||||
return HAL_ERROR;
|
||||
__sys_freq = sf;
|
||||
|
||||
/*Configure the SysTick IRQ priority */
|
||||
NVIC_SetPriority (SysTick_IRQn, 3U);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Select the system frequency without calling the Setting functionality
|
||||
* \param sf The desired value
|
||||
* \return The desired value (enable chaining)
|
||||
*/
|
||||
__INLINE clock_t HAL_SelectSysTickFreq (clock_t sf){
|
||||
return __sys_freq =sf;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Get the __sys_freq.
|
||||
*/
|
||||
__INLINE clock_t HAL_GetSysTickFreq (void){
|
||||
return __sys_freq;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Reconfigure the SysTick and update __sys_freq
|
||||
* \param sf Tick interrupt frequency (CPU time)
|
||||
* \return status of the operation
|
||||
* \arg 0 Success
|
||||
* \arg 1 Fail
|
||||
*/
|
||||
int HAL_SetSysTickFreq (clock_t sf) {
|
||||
/*Configure the SysTick to have interrupt in sf time basis*/
|
||||
if (__sys_freq != sf) {
|
||||
// Time base configuration
|
||||
SystemCoreClockUpdate ();
|
||||
if (SysTick_Config ( (SystemCoreClock>>3)/sf) != 0)
|
||||
return 1;
|
||||
else {
|
||||
__sys_freq = sf;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Take over control of SysTick from HAL library
|
||||
|
||||
//! disable HAL_InitTick implementation
|
||||
HAL_StatusTypeDef
|
||||
HAL_InitTick(uint32_t TickPriority) { return HAL_OK; }
|
||||
|
||||
//! Chain GetTick to our implementation
|
||||
uint32_t HAL_GetTick(void) { return clock(); }
|
||||
|
||||
/*!
|
||||
* \brief This function provides minimum delay (in CPU time) based
|
||||
* on variable incremented.
|
||||
* \param Delay specifies the delay time length, in CPU time.
|
||||
* \note
|
||||
* uint32_t is implicitly convertible to clock_t and vice versa.
|
||||
*/
|
||||
void HAL_Delay(uint32_t Delay) {
|
||||
uint32_t tickstart = clock();
|
||||
|
||||
while((clock() - tickstart) < Delay)
|
||||
;
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== OS like Functionalities ============
|
||||
*/
|
||||
|
||||
|
||||
//! SysTick frequency getter
|
||||
__INLINE clock_t get_freq (void) {
|
||||
return __sys_freq;
|
||||
}
|
||||
|
||||
//! SysTick frequency setter
|
||||
//! \return True on failure
|
||||
int set_freq (clock_t sf) {
|
||||
return HAL_SetSysTickFreq (sf);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief
|
||||
* determines the processor time.
|
||||
* \return
|
||||
* the implementation's best approximation to the processor time
|
||||
* used by the program since program invocation. The time in
|
||||
* seconds is the value returned divided by the value of the macro
|
||||
* CLK_TCK or CLOCKS_PER_SEC
|
||||
*/
|
||||
__INLINE clock_t clock (void) {
|
||||
return (clock_t) __ticks;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief
|
||||
* Set the processor time used.
|
||||
* \param c The new CPU time value
|
||||
* \return
|
||||
* The implementation's best approximation to the processor time
|
||||
* used by the program since program invocation. The time in
|
||||
* seconds is the value returned divided by the value of the macro
|
||||
* CLK_TCK or CLOCKS_PER_SEC
|
||||
*/
|
||||
clock_t setclock (clock_t c) {
|
||||
return __ticks = c;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief
|
||||
* determines the current calendar time. The encoding of the value is
|
||||
* unspecified.
|
||||
* \return
|
||||
* The implementations best approximation to the current calendar
|
||||
* time. If timer is not a null pointer, the return value
|
||||
* is also assigned to the object it points to.
|
||||
*/
|
||||
time_t time (time_t *timer) {
|
||||
if (timer)
|
||||
*timer = (time_t)__now;
|
||||
return (time_t)__now;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief
|
||||
* Sets the system's idea of the time and date. The time,
|
||||
* pointed to by t, is measured in seconds since the Epoch, 1970-01-01
|
||||
* 00:00:00 +0000 (UTC).
|
||||
* \param t Pointer to new system's time and date.
|
||||
* \return On success, zero is returned. On error, -1 is returned
|
||||
*/
|
||||
int settime (const time_t *t) {
|
||||
if (t) {
|
||||
__now = *t;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ============== Cycle count ==============
|
||||
*/
|
||||
/*!
|
||||
* Initialize CPU cycle measurement functionality based on DBG
|
||||
* \return The status of the operation
|
||||
* \arg LLD_OK Success
|
||||
* \arg LLD_ERROR Failure
|
||||
*/
|
||||
LLD_Status_en CYCLE_Init (void) {
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // enable trace
|
||||
//DWT->LAR = 0xC5ACCE55; // <-- added unlock access to DWT (ITM, etc.)registers
|
||||
DWT->CYCCNT = 0; // clear DWT cycle counter
|
||||
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; // enable DWT cycle counter
|
||||
return LLD_OK;
|
||||
}
|
||||
|
||||
//! CPU cycle getter
|
||||
__INLINE clock_t CYCLE_Get (void) {
|
||||
return (clock_t)DWT->CYCCNT;
|
||||
}
|
||||
|
||||
/*
|
||||
* =============== Digital I/O ===============
|
||||
* BTN -- PC13
|
||||
* LED -- PA5 (SB42 is in place) [SB29: PB13]
|
||||
*/
|
||||
|
||||
//! Helper digital input pin getter
|
||||
static __INLINE uint8_t _DINx (GPIO_TypeDef *port, uint32_t pin) {
|
||||
return ((port->IDR & pin) != 0) ? 1:0;
|
||||
}
|
||||
|
||||
//! Helper digital output pin setter
|
||||
static __INLINE uint8_t _DOUTx (GPIO_TypeDef *port, uint32_t pin, uint8_t st) {
|
||||
if (st) port->BSRR = (uint32_t)pin;
|
||||
else port->BSRR = (uint32_t)pin << 16;
|
||||
return st;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Initialize GPIO port pins for Nucleo Board
|
||||
* \return The status of the operation
|
||||
* \arg LLD_OK Success
|
||||
* \arg LLD_ERROR Failure
|
||||
*/
|
||||
LLD_Status_en Port_Init (void) {
|
||||
GPIO_InitTypeDef GPIO_InitType;
|
||||
|
||||
// Enable Port clock
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE ();
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE ();
|
||||
|
||||
// BTN port configuration
|
||||
GPIO_InitType.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitType.Pin = GPIO_PIN_13;
|
||||
GPIO_InitType.Pull = GPIO_NOPULL;
|
||||
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitType);
|
||||
|
||||
GPIO_InitType.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitType.Speed = GPIO_SPEED_LOW;
|
||||
GPIO_InitType.Pin = GPIO_PIN_5;
|
||||
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitType);
|
||||
|
||||
return LLD_OK;
|
||||
}
|
||||
|
||||
//! Nucleo's user button reader
|
||||
uint8_t BTN (void) {
|
||||
return _DINx (GPIOC, GPIO_PIN_13);
|
||||
}
|
||||
|
||||
//! Nucleo's LD2 led setter
|
||||
void LED (uint8_t on) {
|
||||
_DOUTx(GPIOA, GPIO_PIN_5, on);
|
||||
}
|
||||
|
||||
/*! Low level driver init functionality
|
||||
* \return The status of the operation
|
||||
* \arg LLD_OK Success
|
||||
* \arg LLD_ERROR Failure
|
||||
*/
|
||||
LLD_Status_en LLD_Init (clock_t sys_freq) {
|
||||
HAL_Init();
|
||||
HAL_SysTick_Init (sys_freq);
|
||||
CYCLE_Init ();
|
||||
Port_Init ();
|
||||
|
||||
return LLD_OK;
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*!
|
||||
* \file
|
||||
* NUCLEO_F401RE.h
|
||||
* \brief
|
||||
* Nucleo F401RE port file. This file contain the implementation of driver
|
||||
* calls for F401RE board.
|
||||
*
|
||||
* Created on: May 23, 2020
|
||||
* Author: Christos Choutouridis AEM: 8997
|
||||
* email : <cchoutou@ece.auth.gr>
|
||||
*/
|
||||
|
||||
#ifndef NUCLEO_F401RE_H_
|
||||
#define NUCLEO_F401RE_H_
|
||||
|
||||
#include <stm32f4xx.h>
|
||||
#include <stm32f4xx_hal.h>
|
||||
#include <core_cm4.h>
|
||||
|
||||
/*
|
||||
* ========= Data types ========
|
||||
*/
|
||||
|
||||
//! Driver status return type
|
||||
typedef enum {
|
||||
LLD_OK = 0, //!< Indicate successful operation
|
||||
LLD_ERROR //!< Indicate Error
|
||||
}LLD_Status_en;
|
||||
|
||||
typedef uint8_t din_t;
|
||||
//typedef int adc_t;
|
||||
|
||||
#define OFF (0)
|
||||
#define ON (!OFF)
|
||||
#ifndef FALSE
|
||||
#define FALSE (0)
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* =============== System ===============
|
||||
*/
|
||||
#if defined ( __GNUC__ ) && !defined (__CC_ARM)
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
* Also defined in types.h
|
||||
*/
|
||||
#ifndef _CLOCK_T_
|
||||
#define _CLOCK_T_ unsigned long /* clock() */
|
||||
typedef _CLOCK_T_ clock_t; /*!< CPU time type */
|
||||
#endif
|
||||
#ifndef _TIME_T_
|
||||
#define _TIME_T_ long /* time() */
|
||||
typedef _TIME_T_ time_t; /*!< date/time in unix secs past 1-Jan-70 type for 68 years*/
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Helper macros
|
||||
*/
|
||||
#define _CLOCK_T_MAX_VALUE_ (ULONG_MAX) //!< Helper macro for maximum signed CPU time calculations
|
||||
|
||||
/*!
|
||||
* Calculate the positive time difference of _t2_ and _t1_, where
|
||||
* _t1_, _t2_ are clock_t values
|
||||
* \note
|
||||
* _t2_ event comes is AFTER _t1_
|
||||
*
|
||||
* ex:
|
||||
* 0 1 2 3 4 5 6 7 8 9
|
||||
* ^ ^
|
||||
* | |
|
||||
* a b
|
||||
*
|
||||
* if : t1=a, t2=b then dt = b-a = t2 - t1
|
||||
* if : t1=b, t2=a then dt = 9 - (b-a) + 1 = UMAX - (t1-t2) + 1
|
||||
*
|
||||
*/
|
||||
#define _CLOCK_DIFF(_t2_, _t1_) ( ((_t2_)>(_t1_)) ? ((_t2_)-(_t1_)) : (_CLOCK_T_MAX_VALUE_ - ((_t1_) - (_t2_)) + 1) )
|
||||
|
||||
/*
|
||||
* CPU time macros
|
||||
*/
|
||||
#define msec2CPUtime(_ms_) (((_ms_) * get_freq()) / 1000)
|
||||
#define sec2CPUtime(_s_) ((_s_) * get_freq())
|
||||
|
||||
#define CPUtime2msec(_t_) (((_t_) * 1000) / get_freq())
|
||||
#define CPUtime2sec(_t_) ((_t_) / get_freq())
|
||||
|
||||
HAL_StatusTypeDef HAL_SysTick_Init(clock_t sf);
|
||||
|
||||
clock_t HAL_SelectSysTickFreq (clock_t sf);
|
||||
clock_t HAL_GetSysTickFreq (void);
|
||||
int HAL_SetSysTickFreq (clock_t sf);
|
||||
|
||||
/*
|
||||
* OS like Functionalities
|
||||
*/
|
||||
clock_t get_freq (void);
|
||||
int set_freq (clock_t sf);
|
||||
|
||||
clock_t clock (void);
|
||||
clock_t setclock (clock_t c);
|
||||
|
||||
time_t time (time_t *timer);
|
||||
int settime (const time_t *t);
|
||||
|
||||
|
||||
/*
|
||||
* ============== Cycle count ==============
|
||||
*/
|
||||
LLD_Status_en CYCLE_Init (void);
|
||||
clock_t CYCLE_Get (void);
|
||||
|
||||
/*
|
||||
* =============== Digital I/O ===============
|
||||
* BTN -- PC13
|
||||
* LED -- PA5 (SB42 is in place) [SB29: PB13]
|
||||
*/
|
||||
LLD_Status_en Port_Init (void);
|
||||
|
||||
uint8_t BTN (void);
|
||||
void LED (uint8_t on);
|
||||
|
||||
|
||||
/*
|
||||
* ============= Board Init ==============
|
||||
*/
|
||||
LLD_Status_en LLD_Init (clock_t sys_freq);
|
||||
|
||||
#endif /* NUCLEO_F401RE_H_ */
|
||||
@@ -0,0 +1,63 @@
|
||||
/*!
|
||||
* \file
|
||||
* assign2_impl.h
|
||||
* \brief
|
||||
* Assignment 2 application header
|
||||
*
|
||||
* Created on: May 23, 2020
|
||||
* Author: Christos Choutouridis AEM: 8997
|
||||
* email : <cchoutou@ece.auth.gr>
|
||||
*/
|
||||
|
||||
#ifndef ASSIGN2_IMPL_H_
|
||||
#define ASSIGN2_IMPL_H_
|
||||
|
||||
#include "NUCLEO_F401RE.h"
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
* ============= User defines ===============
|
||||
*/
|
||||
#define SYSTICK_FREQ (1000) //!< 1000Hz => 1msec accuracy
|
||||
|
||||
#define MODE_LEADING_EDGE (1) //!< Start counting as soon as the led is switched on
|
||||
#define MODE_TRAILING_EDGE (2) //!< Start counting as soon as the led is switched off (Motor sport style)
|
||||
|
||||
//! If there is no Pre-define MODE, select one here
|
||||
#ifndef MODE
|
||||
#define MODE MODE_TRAILING_EDGE
|
||||
#endif
|
||||
|
||||
#define MEASUREMENTS (5) //!< The number of measurements for each experiment
|
||||
|
||||
//! elect the maximum waiting time before the visual trigger.
|
||||
#define MAX_WAIT_TIME sec2CPUtime(10)
|
||||
|
||||
//! Select if we need cycle counting also.
|
||||
#define CYCLE_COUNTING (1)
|
||||
|
||||
/*
|
||||
* ============= Data types ===============
|
||||
*/
|
||||
//! Select the application wide accuracy of the floating point type.
|
||||
typedef float fp_data_t; //!< floating point data alias.
|
||||
|
||||
/*!
|
||||
* Statistical data structure
|
||||
*/
|
||||
typedef struct {
|
||||
fp_data_t average; //!< The average response time of the experiment
|
||||
fp_data_t median; //!< The median of the times
|
||||
fp_data_t std_dev; //!< Standard deviation
|
||||
} stats_t;
|
||||
|
||||
fp_data_t average (const clock_t *t, size_t n);
|
||||
fp_data_t median (const clock_t *t, size_t n);
|
||||
fp_data_t std_deviation (const clock_t* t, size_t n);
|
||||
|
||||
void leading (clock_t *out, size_t n);
|
||||
void trailing (clock_t *out, size_t n);
|
||||
|
||||
|
||||
#endif /* ASSIGN2_IMPL_H_ */
|
||||
@@ -0,0 +1,145 @@
|
||||
/*!
|
||||
* \file
|
||||
* main.c
|
||||
* \brief
|
||||
* Main application file
|
||||
*
|
||||
* Created on: May 23, 2020
|
||||
* Author: Christos Choutouridis AEM: 8997
|
||||
* email : <cchoutou@ece.auth.gr>
|
||||
*/
|
||||
#include "assign2_impl.h"
|
||||
|
||||
/*
|
||||
* Global data
|
||||
*/
|
||||
stats_t stats;
|
||||
|
||||
/*!
|
||||
* Compare functionality for qsort
|
||||
* \param a left hand site
|
||||
* \param b right hand site
|
||||
* \return stdlib requirements
|
||||
* \arg -1 a<b
|
||||
* \arg 0 a==b
|
||||
* \arg 1 a>b
|
||||
*/
|
||||
static int cmpfunc (const void * a, const void * b) {
|
||||
fp_data_t v = *(fp_data_t*)a - *(fp_data_t*)b;
|
||||
return (v < 0) ? -1 : (v > 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Calculates and return the average of an array of measurements
|
||||
* \param t Pointer to measurements
|
||||
* \param n Size of measurements array
|
||||
* \return The average
|
||||
*/
|
||||
fp_data_t average (const clock_t *t, size_t n) {
|
||||
fp_data_t ret =0;
|
||||
for (size_t i=0 ; i<n ; ++i)
|
||||
ret += t[i];
|
||||
return ret / n;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Calculates and return the median of an array of measurements
|
||||
* \param t Pointer to measurements
|
||||
* \param n Size of measurements array
|
||||
* \return The average
|
||||
*/
|
||||
fp_data_t median (const clock_t *t, size_t n) {
|
||||
qsort ((void*)t, n, sizeof(t[0]), cmpfunc);
|
||||
return (n % 2) ? t[n/2] : (t[n/2] + t[n/2 -1]) /2;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Calculates and return the std. deviation of an array of measurements
|
||||
* \param t Pointer to measurements
|
||||
* \param n Size of measurements array
|
||||
* \return The average
|
||||
*/
|
||||
fp_data_t std_deviation (const clock_t* t, size_t n) {
|
||||
fp_data_t av = average (t, n);
|
||||
fp_data_t s =0;
|
||||
for (size_t i=0 ; i<n ; ++i) {
|
||||
s += (t[i]-av)*(t[i]-av);
|
||||
}
|
||||
return sqrt (s/n);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Leading edge trigger experiment
|
||||
* \param out Pointer to array to store the measurements
|
||||
* \param n Number of measurements
|
||||
*/
|
||||
void leading (clock_t *out, size_t n) {
|
||||
srand(0);
|
||||
rand();
|
||||
|
||||
LED (OFF);
|
||||
for (size_t i =0 ; i<n ; ++i) {
|
||||
clock_t t1, t2;
|
||||
HAL_Delay(rand() % (MAX_WAIT_TIME + 1));
|
||||
LED(ON);
|
||||
t1 = clock ();
|
||||
while (BTN())
|
||||
;
|
||||
t2 = clock ();
|
||||
LED (OFF);
|
||||
out[i] = CPUtime2msec(_CLOCK_DIFF(t2, t1));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Trailing edge trigger experiment
|
||||
* \param out Pointer to array to store the measurements
|
||||
* \param n Number of measurements
|
||||
*/
|
||||
void trailing (clock_t *out, size_t n) {
|
||||
srand(0);
|
||||
rand();
|
||||
|
||||
LED (ON);
|
||||
for (size_t i =0 ; i<n ; ++i) {
|
||||
clock_t t1, t2;
|
||||
HAL_Delay(rand() % (MAX_WAIT_TIME + 1));
|
||||
LED(OFF);
|
||||
t1 = clock ();
|
||||
while (BTN())
|
||||
;
|
||||
t2 = clock ();
|
||||
LED (ON);
|
||||
out[i] = CPUtime2msec(_CLOCK_DIFF(t2, t1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Main
|
||||
*/
|
||||
int main(void) {
|
||||
clock_t times[MEASUREMENTS];
|
||||
|
||||
LLD_Init (SYSTICK_FREQ); // Initialize the board
|
||||
|
||||
// Experiment
|
||||
#if MODE == MODE_LEADING_EDGE
|
||||
leading (times, MEASUREMENTS);
|
||||
#elif MODE == MODE_TRAILING_EDGE
|
||||
trailing (times, MEASUREMENTS);
|
||||
#endif
|
||||
|
||||
// Get statistical data
|
||||
stats.average = average ((const clock_t*)times, MEASUREMENTS);
|
||||
stats.median = median ((const clock_t*)times, MEASUREMENTS);
|
||||
stats.std_dev = std_deviation((const clock_t*)times, MEASUREMENTS);
|
||||
|
||||
// Flash 10Hz to indicate the end of experiment
|
||||
while (1) {
|
||||
HAL_Delay(msec2CPUtime(50));
|
||||
LED (ON);
|
||||
HAL_Delay(msec2CPUtime(50));
|
||||
LED (OFF);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user