NorthStar-Endurance-TestBench/EnduranceTestBench/nms-hal/hal_system.c

250 lines
7.5 KiB
C

/**
* @file hal_system.c
* @copyright Nehemis SARL reserves all rights even in the event of industrial
* property rights. We reserve all rights of disposal such as
* copying and passing on to third parties.
*
*
* @brief HAL layer for the SYSTEM module.
* - The system reset cause such as :
* 1. Software reset
* 2. Watchdog reset
* 3. Power on reset
* 4. Optional byte load reset
* 5. Low power reset
* 6. Pin reset
* - The NVIC enable/disable interrupts.
* - The serial number of the MCU.
*/
/******************************************************************************
* Include Header Files
******************************************************************************/
#include "hal_system.h"
/* cubeMX */
#include "main.h"
/******************************************************************************
* Macro Constant Declarations
******************************************************************************/
#define HAL_SYSTEM_STACK_GUARD 0xCDu
/******************************************************************************
* Module Global Variable Declarations
******************************************************************************/
static uint64 systemStepCounter_gu64;
static uint64 systemPeriodMsToUs_gu64;
static uint64 systemTickLoadValue_gu64;
static uint32 resetStatusRegister_gu32;
/******************************************************************************
* Static Function Declarations
******************************************************************************/
/******************************************************************************
* Extern Function Definitions
******************************************************************************/
uint32 HalSystemInit(void)
{
uint32 error_u32 = NMS_ERR_NONE;
resetStatusRegister_gu32 = RCC->CSR;
RCC->CSR |= RCC_CSR_RMVF; /* RMVF = ReMoVe Flag. Reset the reset cause register for the next reboot. */
systemPeriodMsToUs_gu64 = HAL_GetTickFreq() * 1000uLL;
systemTickLoadValue_gu64 = (uint64)(SysTick->LOAD);
systemStepCounter_gu64 = 0uLL;
return error_u32;
}
uint32 HalSystemGetRunTimeUs(uint64 * resultUs_pu64)
{
static uint64 previousTimeUs_u64 = 0uLL;
uint32 error_u32 = NMS_ERR_NONE;
uint64 timeUs_u64 = 0uLL;
/* Make a copy in case of multiple function instance at the same time */
uint64 copySystemStepCounter_u64 = systemStepCounter_gu64;
/* First make a copy of the systemStepCounter to be able to check rollback further on.
* Also copy current value of the System Tick Timer to avoid any dynamic update during calculation.
* Then translate in microsecond & sum both timing information (step counter + tick value) to get the most
* accurate resolution of the system runtime.
*/
uint64 copyPreviousTimeUs_u64 = previousTimeUs_u64;
uint64 tickValue_u64 = (uint64)(SysTick->VAL);
timeUs_u64 = copySystemStepCounter_u64 * systemPeriodMsToUs_gu64;
timeUs_u64 += ((systemTickLoadValue_gu64 - tickValue_u64) * systemPeriodMsToUs_gu64) / systemTickLoadValue_gu64;
/* We check here if the interruption of the systick happened during our operations and correct it accordingly */
if(timeUs_u64 <= (uint64)(systemStepCounter_gu64 * systemPeriodMsToUs_gu64))
{
copySystemStepCounter_u64 = systemStepCounter_gu64;
tickValue_u64 = (uint64)(SysTick->VAL);
timeUs_u64 = copySystemStepCounter_u64 * systemPeriodMsToUs_gu64;
timeUs_u64 += ((systemTickLoadValue_gu64 - tickValue_u64) * systemPeriodMsToUs_gu64) / systemTickLoadValue_gu64;
/* The timer interruption is too fast, no time to process */
if(timeUs_u64 <= (uint64)(systemStepCounter_gu64 * systemPeriodMsToUs_gu64))
{
error_u32 = NMS_ERR_OVERRUN;
}
}
/* Should never happen if this timer interruption is set to highest priority */
if(copyPreviousTimeUs_u64 > timeUs_u64)
{
error_u32 = NMS_ERR_UNKNOWN;
}
else
{
*resultUs_pu64 = previousTimeUs_u64;
}
/* This condition has been added to prevent trouble overflow with interruptions
on the medium and high optimizations options */
*resultUs_pu64 = (timeUs_u64 > previousTimeUs_u64) ? timeUs_u64 : *resultUs_pu64;
return error_u32;
}
/* This function should not call the log, since it uses the system runtime. */
uint32 HalSystemGetRunTimeMs(uint64 * resultMs_pu64)
{
*resultMs_pu64 = systemStepCounter_gu64;
return NMS_ERR_NONE;
}
void HalSystemGetSerialId(uint8 * serialIdBuffer_pu8)
{
uint32 serialIdW0_u32, serialIdW1_u32, serialIdW2_u32;
/* Get the three parts of the UID */
serialIdW0_u32 = HAL_GetUIDw0();
serialIdW1_u32 = HAL_GetUIDw1();
serialIdW2_u32 = HAL_GetUIDw2();
/* Copy the values into the serial ID buffer */
memcpy(&serialIdBuffer_pu8[0], &serialIdW0_u32, sizeof(serialIdW0_u32));
memcpy(&serialIdBuffer_pu8[4], &serialIdW1_u32, sizeof(serialIdW1_u32));
memcpy(&serialIdBuffer_pu8[8], &serialIdW2_u32, sizeof(serialIdW2_u32));
}
uint32 HalSystemGetResetCause( HalSystemResetCauseEn resetCauseSelector_en, uint32 * causes_pu32 )
{
uint32 error_u32 = NMS_ERR_DEFAULT;
uint32 mask_u32 = 0uL;
if (causes_pu32 == NULL)
{
error_u32 = NMS_ERR_NULL_POINTER;
}
else
{
switch(resetCauseSelector_en)
{
case HAL_SYSTEM_RESET_CAUSE_OPTION_BYTE_LOADER:
mask_u32 = RCC_CSR_OBLRSTF_Msk;
error_u32 = NMS_ERR_NONE;
break;
case HAL_SYSTEM_RESET_CAUSE_EXTERNAL_PIN_RESET:
mask_u32 = RCC_CSR_PINRSTF_Msk;
error_u32 = NMS_ERR_NONE;
break;
case HAL_SYSTEM_RESET_CAUSE_BROWNOUT_RESET:
mask_u32 = RCC_CSR_BORRSTF_Msk;
error_u32 = NMS_ERR_NONE;
break;
case HAL_SYSTEM_RESET_CAUSE_SOFTWARE_RESET:
mask_u32 = RCC_CSR_SFTRSTF_Msk;
error_u32 = NMS_ERR_NONE;
break;
case HAL_SYSTEM_RESET_CAUSE_WATCH_DOG_TIMER:
mask_u32 = RCC_CSR_IWDGRSTF_Msk;
error_u32 = NMS_ERR_NONE;
break;
case HAL_SYSTEM_RESET_CAUSE_WINDOW_WATCH_DOG:
mask_u32 = RCC_CSR_WWDGRSTF_Msk;
error_u32 = NMS_ERR_NONE;
break;
case HAL_SYSTEM_RESET_CAUSE_LOW_POWER:
mask_u32 = RCC_CSR_LPWRRSTF_Msk;
error_u32 = NMS_ERR_NONE;
break;
case HAL_SYSTEM_RESET_CAUSE_ALL_CAUSES:
mask_u32 = RCC_CSR_IWDGRSTF_Msk
| RCC_CSR_WWDGRSTF_Msk
| RCC_CSR_SFTRSTF_Msk
| RCC_CSR_PINRSTF_Msk
| RCC_CSR_LPWRRSTF_Msk
| RCC_CSR_BORRSTF_Msk;
error_u32 = NMS_ERR_NONE;
break;
default:
error_u32 = NMS_ERR_UNKNOWN;
break;
}
*causes_pu32 = resetStatusRegister_gu32 & mask_u32;
}
return error_u32;
}
void HalSystemDisableInterrupts(void)
{
__disable_irq();
}
void HalSystemEnableInterrupts(void)
{
__enable_irq();
}
void HalSystemReset(void)
{
HAL_NVIC_SystemReset();
}
/******************************************************************************
* Callback Function Definitions
******************************************************************************/
/**
* @brief Count the number of milliseconds that elapsed since the start
*
* @note Function called by low-level functions of cubeMX
*/
void HAL_IncTick(void)
{
systemStepCounter_gu64++;
}
/**
* @brief Provides a tick value in millisecond.
*
* @return The number of elapsed tick.
*/
uint32 HAL_GetTick(void)
{
return (uint32)systemStepCounter_gu64;
}