547 lines
16 KiB
C
547 lines
16 KiB
C
/**
|
|
* @file hal_timer.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 TIMER module.
|
|
*
|
|
*/
|
|
|
|
/******************************************************************************
|
|
* Include Header Files
|
|
******************************************************************************/
|
|
#include "map_hal.h"
|
|
#include "hal_timer.h"
|
|
|
|
/* CubeMX */
|
|
#include "tim.h"
|
|
|
|
/******************************************************************************
|
|
* Macro constant declarations
|
|
******************************************************************************/
|
|
#define HAL_TIMER_SEC_TO_MSEC 1000000uLL /**< Number of microseconds within a second */
|
|
|
|
/******************************************************************************
|
|
* Type declarations
|
|
******************************************************************************/
|
|
typedef struct
|
|
{
|
|
uint64 timerPeriod_u64;
|
|
uint64 downCounter_u64;
|
|
} HalTimerInstance_tst;
|
|
|
|
/******************************************************************************
|
|
* Module Global Variable Declarations
|
|
******************************************************************************/
|
|
static HalTimerInstance_tst instance_gast[MAP_HAL_TIMER_NUMBER] = {0};
|
|
static uint32 (*halTimerCallbacks[MAP_HAL_TIMER_NUMBER])(void);
|
|
|
|
/******************************************************************************
|
|
* Static Function Declarations
|
|
******************************************************************************/
|
|
static uint32 HalTimerComputeTimerPeriod(MapHalTimerModule_en timerModule_en, uint64 * timerPeriod_u64);
|
|
|
|
/******************************************************************************
|
|
* Extern Function Definition
|
|
******************************************************************************/
|
|
uint32 HalTimerInit(void)
|
|
{
|
|
uint32 error_u32 = NMS_ERR_NONE;
|
|
|
|
for(uint8 i_u8 = 0u; i_u8 < MAP_HAL_TIMER_NUMBER; i_u8++)
|
|
{
|
|
uint64 timerPeriod_u64 = 0uLL;
|
|
error_u32 = HalTimerComputeTimerPeriod((MapHalTimerModule_en)(i_u8), &timerPeriod_u64);
|
|
|
|
if (error_u32 == NMS_ERR_NONE)
|
|
{
|
|
instance_gast[i_u8].timerPeriod_u64 = timerPeriod_u64;
|
|
instance_gast[i_u8].downCounter_u64 = 0uLL;
|
|
}
|
|
}
|
|
|
|
return error_u32;
|
|
}
|
|
|
|
|
|
uint32_t HalTimerGetCounter(MapHalTimerModule_en timerModule_en)
|
|
{
|
|
TIM_HandleTypeDef *targetModule_pst = NULL;
|
|
|
|
/* Get the timer handle using MapHalTimerModule */
|
|
if (MapHalTimerModule(timerModule_en, &targetModule_pst) != NMS_ERR_NONE || targetModule_pst == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return (uint32)(targetModule_pst->Instance->CNT);
|
|
}
|
|
|
|
|
|
void HalTimerSetCounter(MapHalTimerModule_en timerModule_en, uint32 counter_u32)
|
|
{
|
|
TIM_HandleTypeDef *targetModule_pst = NULL;
|
|
|
|
if (MapHalTimerModule(timerModule_en, &targetModule_pst) != NMS_ERR_NONE || targetModule_pst == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
targetModule_pst->Instance->CNT = counter_u32;
|
|
}
|
|
|
|
|
|
void HalTimerSetCompare(MapHalTimerModule_en timerModule_en, uint32 channel_u32, uint32 compareValue_32)
|
|
{
|
|
TIM_HandleTypeDef *targetModule_pst = NULL;
|
|
|
|
if (MapHalTimerModule(timerModule_en, &targetModule_pst) != NMS_ERR_NONE || targetModule_pst == NULL)
|
|
{
|
|
/* Handle the error (e.g., log it or return early) */
|
|
return;
|
|
}
|
|
switch (channel_u32)
|
|
{
|
|
case TIM_CHANNEL_1:
|
|
targetModule_pst->Instance->CCR1 = compareValue_32; break;
|
|
|
|
case TIM_CHANNEL_2:
|
|
targetModule_pst->Instance->CCR2 = compareValue_32; break;
|
|
|
|
case TIM_CHANNEL_3:
|
|
targetModule_pst->Instance->CCR3 = compareValue_32; break;
|
|
|
|
case TIM_CHANNEL_4:
|
|
targetModule_pst->Instance->CCR4 = compareValue_32; break;
|
|
|
|
#ifdef TIM_CHANNEL_5
|
|
case TIM_CHANNEL_5:
|
|
targetModule_pst->Instance->CCR5 = compareValue_32; break;
|
|
#endif
|
|
|
|
#ifdef TIM_CHANNEL_6
|
|
case TIM_CHANNEL_6:
|
|
targetModule_pst->Instance->CCR6 = compareValue_32; break;
|
|
#endif
|
|
|
|
default:
|
|
/* Invalid channel case (log or handle the error) */
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
uint32 HalTimerGetAutoReload(MapHalTimerModule_en timerModule_en)
|
|
{
|
|
TIM_HandleTypeDef *targetModule_pst = NULL;
|
|
|
|
if (MapHalTimerModule(timerModule_en, &targetModule_pst) != NMS_ERR_NONE || targetModule_pst == NULL)
|
|
{
|
|
/* Error */
|
|
}
|
|
|
|
return (uint32)(targetModule_pst->Instance->ARR);
|
|
}
|
|
|
|
|
|
|
|
uint32 HalTimerEncoderStart(MapHalTimerModule_en timerModule_en)
|
|
{
|
|
uint32 error_u32 = NMS_ERR_DEFAULT;
|
|
|
|
HAL_StatusTypeDef halTimerStatus_en = NMS_ERR_NONE;
|
|
TIM_HandleTypeDef * targetModule_pst;
|
|
|
|
error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
|
|
|
|
if(error_u32 == NMS_ERR_NONE)
|
|
{
|
|
/* Start the requested timer */
|
|
halTimerStatus_en = HAL_TIM_Encoder_Start(targetModule_pst, TIM_CHANNEL_ALL);
|
|
|
|
switch(halTimerStatus_en)
|
|
{
|
|
case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
|
|
case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
|
|
case HAL_ERROR: error_u32 = NMS_ERR_UNKNOWN; break;
|
|
case HAL_OK: error_u32 = NMS_ERR_NONE; break;
|
|
default: error_u32 = NMS_ERR_UNKNOWN; break;
|
|
}
|
|
}
|
|
|
|
return error_u32;
|
|
}
|
|
|
|
|
|
uint32 HalTimerEncoderStop(MapHalTimerModule_en timerModule_en)
|
|
{
|
|
uint32 error_u32 = NMS_ERR_DEFAULT;
|
|
|
|
HAL_StatusTypeDef halTimerStatus_en = NMS_ERR_NONE;
|
|
TIM_HandleTypeDef * targetModule_pst;
|
|
|
|
error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
|
|
|
|
if(error_u32 == NMS_ERR_NONE)
|
|
{
|
|
/* Start the requested timer */
|
|
halTimerStatus_en = HAL_TIM_Encoder_Stop(targetModule_pst, TIM_CHANNEL_ALL);
|
|
|
|
switch(halTimerStatus_en)
|
|
{
|
|
case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
|
|
case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
|
|
case HAL_ERROR: error_u32 = NMS_ERR_UNKNOWN; break;
|
|
case HAL_OK: error_u32 = NMS_ERR_NONE; break;
|
|
default: error_u32 = NMS_ERR_UNKNOWN; break;
|
|
}
|
|
}
|
|
|
|
return error_u32;
|
|
}
|
|
|
|
|
|
uint32 HalTimerPwmStart(MapHalTimerModule_en timerModule_en, uint32 Channel_u32)
|
|
{
|
|
uint32 error_u32 = NMS_ERR_DEFAULT;
|
|
|
|
HAL_StatusTypeDef halTimerStatus_en = NMS_ERR_NONE;
|
|
TIM_HandleTypeDef * targetModule_pst;
|
|
|
|
error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
|
|
|
|
if(error_u32 == NMS_ERR_NONE)
|
|
{
|
|
/* Start the requested timer */
|
|
halTimerStatus_en = HAL_TIM_PWM_Start(targetModule_pst, Channel_u32);
|
|
|
|
switch(halTimerStatus_en)
|
|
{
|
|
case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
|
|
case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
|
|
case HAL_ERROR: error_u32 = NMS_ERR_UNKNOWN; break;
|
|
case HAL_OK: error_u32 = NMS_ERR_NONE; break;
|
|
default: error_u32 = NMS_ERR_UNKNOWN; break;
|
|
}
|
|
}
|
|
|
|
return error_u32;
|
|
}
|
|
|
|
|
|
uint32 HalTimerPwmStop(MapHalTimerModule_en timerModule_en, uint32 Channel_u32)
|
|
{
|
|
uint32 error_u32 = NMS_ERR_DEFAULT;
|
|
|
|
HAL_StatusTypeDef halTimerStatus_en = NMS_ERR_NONE;
|
|
TIM_HandleTypeDef * targetModule_pst;
|
|
|
|
error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
|
|
|
|
if(error_u32 == NMS_ERR_NONE)
|
|
{
|
|
/* Stop the requested timer */
|
|
halTimerStatus_en = HAL_TIM_PWM_Stop(targetModule_pst, Channel_u32);
|
|
|
|
switch(halTimerStatus_en)
|
|
{
|
|
case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
|
|
case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
|
|
case HAL_ERROR: error_u32 = NMS_ERR_UNKNOWN; break;
|
|
case HAL_OK: error_u32 = NMS_ERR_NONE; break;
|
|
default: error_u32 = NMS_ERR_UNKNOWN; break;
|
|
}
|
|
}
|
|
|
|
return error_u32;
|
|
}
|
|
|
|
|
|
uint32 HalTimerStart(MapHalTimerModule_en timerModule_en)
|
|
{
|
|
uint32 error_u32 = NMS_ERR_DEFAULT;
|
|
|
|
HAL_StatusTypeDef halTimerStatus_en = NMS_ERR_NONE;
|
|
TIM_HandleTypeDef * targetModule_pst;
|
|
|
|
error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
|
|
|
|
if(error_u32 == NMS_ERR_NONE)
|
|
{
|
|
/* Start the requested timer */
|
|
halTimerStatus_en = HAL_TIM_Base_Start_IT(targetModule_pst);
|
|
|
|
switch(halTimerStatus_en)
|
|
{
|
|
case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
|
|
case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
|
|
case HAL_ERROR: error_u32 = NMS_ERR_UNKNOWN; break;
|
|
case HAL_OK: error_u32 = NMS_ERR_NONE; break;
|
|
default: error_u32 = NMS_ERR_UNKNOWN; break;
|
|
}
|
|
}
|
|
|
|
return error_u32;
|
|
}
|
|
|
|
|
|
uint32 HalTimerStop(MapHalTimerModule_en timerModule_en)
|
|
{
|
|
uint32 error_u32 = NMS_ERR_DEFAULT;
|
|
HAL_StatusTypeDef halTimerStatus_en = NMS_ERR_NONE;
|
|
TIM_HandleTypeDef * targetModule_pst;
|
|
|
|
error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
|
|
|
|
if(error_u32 == NMS_ERR_NONE)
|
|
{
|
|
/* Stop the requested timer */
|
|
halTimerStatus_en = HAL_TIM_Base_Stop_IT(targetModule_pst);
|
|
|
|
switch(halTimerStatus_en)
|
|
{
|
|
case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
|
|
case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
|
|
case HAL_ERROR: error_u32 = NMS_ERR_UNKNOWN; break;
|
|
case HAL_OK: error_u32 = NMS_ERR_NONE; break;
|
|
default: error_u32 = NMS_ERR_UNKNOWN; break;
|
|
}
|
|
}
|
|
|
|
return error_u32;
|
|
}
|
|
|
|
|
|
uint32 HalTimerReloadUs(MapHalTimerModule_en timerModule_en, uint64 period_u64)
|
|
{
|
|
uint32 error_u32 = NMS_ERR_DEFAULT;
|
|
TIM_HandleTypeDef * targetModule_pst;
|
|
|
|
error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
|
|
|
|
if(error_u32 == NMS_ERR_NONE)
|
|
{
|
|
if(period_u64 == 0uLL)
|
|
{
|
|
error_u32 = NMS_ERR_UNKNOWN;
|
|
}
|
|
else
|
|
{
|
|
/* Compute the number of step that we need to count */
|
|
instance_gast[timerModule_en].downCounter_u64 = period_u64 / instance_gast[timerModule_en].timerPeriod_u64;
|
|
if((instance_gast[timerModule_en].downCounter_u64 * instance_gast[timerModule_en].timerPeriod_u64) < period_u64)
|
|
{
|
|
instance_gast[timerModule_en].downCounter_u64++;
|
|
}
|
|
else
|
|
{
|
|
error_u32 = NMS_ERR_UNKNOWN;
|
|
}
|
|
}
|
|
}
|
|
|
|
return error_u32;
|
|
}
|
|
|
|
|
|
uint32 HalTimerGetRemainingTimeUs(MapHalTimerModule_en timerModule_en, uint64 * remainingTime_pu64)
|
|
{
|
|
uint32 error_u32 = NMS_ERR_DEFAULT;
|
|
TIM_HandleTypeDef * targetModule_pst;
|
|
|
|
error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
|
|
|
|
if(error_u32 == NMS_ERR_NONE)
|
|
{
|
|
/* Add the time corresponding to the number of interruption left for this timer */
|
|
*remainingTime_pu64 = instance_gast[timerModule_en].downCounter_u64;
|
|
*remainingTime_pu64 *= instance_gast[timerModule_en].timerPeriod_u64;
|
|
}
|
|
else
|
|
{
|
|
error_u32 = NMS_ERR_UNKNOWN;
|
|
}
|
|
|
|
return error_u32;
|
|
}
|
|
|
|
|
|
uint32 HalTimerConfigureCallback(MapHalTimerModule_en timerModule_en, void (*callback_pfn)(void))
|
|
{
|
|
uint32 error_u32 = NMS_ERR_DEFAULT;
|
|
|
|
if (timerModule_en < MAP_HAL_TIMER_NUMBER )
|
|
{
|
|
halTimerCallbacks[timerModule_en] = callback_pfn;
|
|
error_u32 = NMS_ERR_NONE;
|
|
}
|
|
else
|
|
{
|
|
error_u32 = NMS_ERR_UNKNOWN;
|
|
}
|
|
|
|
return error_u32;
|
|
}
|
|
|
|
void HalTimerDeinit(MapHalTimerModule_en timerModule_en)
|
|
{
|
|
uint32 error_u32 = NMS_ERR_DEFAULT;
|
|
TIM_HandleTypeDef * targetModule_pst;
|
|
uint8 index_u8;
|
|
uint8 startIndex_u8;
|
|
uint8 iteration_u8 = 1u; /* Default to 1 loop iteration (deinit one module) */
|
|
|
|
if(timerModule_en == MAP_HAL_TIMER_NUMBER)
|
|
{
|
|
iteration_u8 = timerModule_en;
|
|
startIndex_u8 = 0u;
|
|
}
|
|
else
|
|
{
|
|
iteration_u8 += timerModule_en;
|
|
startIndex_u8 = timerModule_en;
|
|
}
|
|
|
|
for(index_u8 = startIndex_u8; index_u8 < iteration_u8; index_u8++)
|
|
{
|
|
error_u32 = MapHalTimerModule((MapHalTimerModule_en)index_u8, &targetModule_pst);
|
|
if(error_u32 == NMS_ERR_NONE)
|
|
{
|
|
HAL_TIM_Base_DeInit(targetModule_pst);
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Static Function Definitions
|
|
******************************************************************************/
|
|
|
|
/**
|
|
* @brief Compute the timerPeriod of the requested timer
|
|
*
|
|
* @param timerModule_en The timer module to use
|
|
*
|
|
* @return The value of the timer period. If the timer module is invalid, the
|
|
* value returned will be 0.
|
|
*
|
|
* @note CAUTION : The part to compute the actual time frequency is target
|
|
* dependant, do not forget to update it to fit your needs.
|
|
* This affects the calculation of the timerPeriod and so
|
|
* can change the resolution that has been computed by the
|
|
* user in cubeMX
|
|
*/
|
|
static uint32 HalTimerComputeTimerPeriod(MapHalTimerModule_en timerModule_en, uint64 * timerPeriod_u64)
|
|
{
|
|
uint32 error_u32 = NMS_ERR_DEFAULT;
|
|
uint32 timerFrequency_u32 = 0uL;
|
|
TIM_HandleTypeDef * targetModule_pst;
|
|
|
|
error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
|
|
|
|
if(error_u32 == NMS_ERR_NONE)
|
|
{
|
|
*timerPeriod_u64 = HAL_TIMER_SEC_TO_MSEC;
|
|
*timerPeriod_u64 *= (targetModule_pst->Instance->PSC + 1UL);
|
|
*timerPeriod_u64 *= (targetModule_pst->Instance->ARR + 1UL);
|
|
*timerPeriod_u64 /= timerFrequency_u32;
|
|
}
|
|
else
|
|
{
|
|
timerPeriod_u64 = 0uLL;
|
|
error_u32 = NMS_ERR_UNKNOWN;
|
|
}
|
|
|
|
return error_u32;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Callback Function Definitions
|
|
******************************************************************************/
|
|
|
|
/**
|
|
* @brief CubeMX timer period elapsed callback
|
|
*
|
|
* @param[in] htim pointer to a TIM_HandleTypeDef structure that contains
|
|
* the configuration information for the specified TIMER.
|
|
* @return Error code in case there is one during the process.
|
|
*/
|
|
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
|
|
{
|
|
MapHalTimerModule_en timerModule_en;
|
|
uint32 error_u32 = NMS_ERR_DEFAULT;
|
|
|
|
error_u32 = MapHalTimerCallback(&htim, &timerModule_en);
|
|
|
|
if (error_u32 == NMS_ERR_NONE)
|
|
{
|
|
/* Check if we reach the interrupt enough to reach the goal counter */
|
|
if(instance_gast[timerModule_en].downCounter_u64 == 0uLL)
|
|
{
|
|
if(halTimerCallbacks[timerModule_en] != NULL)
|
|
{
|
|
/* Call the user callback */
|
|
halTimerCallbacks[timerModule_en]();
|
|
}
|
|
else
|
|
{
|
|
error_u32 = NMS_ERR_UNKNOWN;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
instance_gast[timerModule_en].downCounter_u64--;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
error_u32 = NMS_ERR_UNKNOWN;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief CubeMX timer error callback
|
|
*
|
|
* @param[in] htim pointer to a TIM_HandleTypeDef structure that contains
|
|
* the configuration information for the specified TIMER.
|
|
* @return Error code in case there is one during the process.
|
|
*/
|
|
void HAL_TIM_ErrorCallback(TIM_HandleTypeDef * htim)
|
|
{
|
|
uint32 error_u32 = NMS_ERR_DEFAULT;
|
|
MapHalTimerModule_en timerModule_en;
|
|
|
|
error_u32 = MapHalTimerCallback(&htim, &timerModule_en);
|
|
|
|
if(error_u32 == NMS_ERR_NONE)
|
|
{
|
|
switch(htim->State)
|
|
{
|
|
case HAL_TIM_STATE_RESET:
|
|
error_u32 = NMS_ERR_NOT_INITIALIZED; break;
|
|
|
|
case HAL_TIM_STATE_BUSY:
|
|
error_u32 = NMS_ERR_BUSY;
|
|
break;
|
|
|
|
case HAL_TIM_STATE_TIMEOUT:
|
|
error_u32 = NMS_ERR_TIMEOUT; break;
|
|
|
|
case HAL_TIM_STATE_ERROR:
|
|
error_u32 = NMS_ERR_UNEXPECTED; break;
|
|
|
|
case HAL_TIM_STATE_READY:
|
|
error_u32 = NMS_ERR_NOT_RUNNING; break;
|
|
|
|
default:
|
|
error_u32 = NMS_ERR_UNKNOWN; break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
error_u32 = NMS_ERR_INVALID_ARGUMENT;
|
|
}
|
|
}
|