251 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			251 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"
 | |
| #include "string.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_INVALID_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;
 | |
| }
 |