250 lines
7.5 KiB
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;
|
|
}
|