/**
 * @file	   hal_timer.h
 *
 * @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.
 *
 */


#ifndef __HAL_TIMER_H_
#define __HAL_TIMER_H_

/******************************************************************************
 * Include Header Files
 ******************************************************************************/
#include "nms_types.h"
#include "map_hal.h"

/******************************************************************************
 * Type declarations
 ******************************************************************************/

/******************************************************************************
 * Extern Function Declarations
 ******************************************************************************/
/**
 * @brief   Initializes the HAL timer module.
 *
 * @return  Error code: 0 if successful, nonzero otherwise.
 */
uint32 HalTimerInit(void);

/**
 * @brief   Retrieves the current value of the TIM counter register.
 *
 * @param   htim  Pointer to the TIM handle containing the TIM instance.
 *
 * @return  The 16-bit or 32-bit value of the timer counter register (TIMx_CNT).
 */
uint32 HalTimerGetCounter(MapHalTimerModule_en timerModule_en);

/**
 * @brief   Sets a specific value to the TIM counter register.
 *
 * @param   htim        Pointer to the TIM handle containing the TIM instance.
 * @param   counter_u32 Value to set in the TIM counter register.
 */
void HalTimerSetCounter(MapHalTimerModule_en timerModule_en, uint32 counter_u32);

/**
 * @brief   Set the compare value for a given timer channel.
 *
 * @param   timerModule_en  Timer module.
 * 			channel      	Timer channel (e.g., TIM_CHANNEL_1, TIM_CHANNEL_2).
 *			compareValue 	Value to set in the compare register.
 *
 * @note    This function abstracts the STM32 HAL macro __HAL_TIM_SET_COMPARE.
 */
void HalTimerSetCompare(MapHalTimerModule_en timerModule_en, uint32 channel_u32, uint32 compareValue_32);

/**
 * @brief   Get the Auto-Reload value of the specified timer module.
 *
 * @param   timerModule_en  Timer module selection from MapHalTimerModule_en.
 *
 * @return  The auto-reload value of the selected timer module.
 *          Returns 0 if the timer module is invalid.
 */
uint32 HalTimerGetAutoReload(MapHalTimerModule_en timerModule_en);

/**
 * @brief   Starts the specified timer module in encoder mode.
 *
 * @param   timerModule_en  Timer module to be started in encoder mode.
 *
 * @return  Error code: 0 if successful, nonzero otherwise.
 */
uint32 HalTimerEncoderStart(MapHalTimerModule_en timerModule_en);

/**
 * @brief   Stops the specified timer module in encoder mode.
 *
 * @param   timerModule_en  Timer module to be stopped in encoder mode.
 *
 * @return  Error code: 0 if successful, nonzero otherwise.
 */
uint32 HalTimerEncoderStop(MapHalTimerModule_en timerModule_en);

/**
 * @brief   Stops the specified timer module in PWM mode.
 *
 * @param   timerModule_en  Timer module to be stopped in encoder mode.
 *
 * @return  Error code: 0 if successful, nonzero otherwise.
 */
uint32 HalTimerPwmStart(MapHalTimerModule_en timerModule_en, uint32 Channel_u32);

/**
 * @brief   Stops the specified timer module in PWM mode.
 *
 * @param   timerModule_en  Timer module to be stopped in encoder mode.
 *
 * @return  Error code: 0 if successful, nonzero otherwise.
 */
uint32 HalTimerPwmStop(MapHalTimerModule_en timerModule_en, uint32 Channel_u32);

/**
 * @brief   Starts the specified timer module.
 *
 * @param   timerModule_en  Timer module to be started.
 *
 * @return  Error code: 0 if successful, nonzero otherwise.
 */
uint32 HalTimerStart(MapHalTimerModule_en timerModule_en);

/**
 * @brief   Stops the specified timer module.
 *
 * @param   timerModule_en  Timer module to be stopped.
 *
 * @return  Error code: 0 if successful, nonzero otherwise.
 */
uint32 HalTimerStop(MapHalTimerModule_en timerModule_en);

/**
 * @brief   Updates the timer's prescaler and counter value based on the given period.
 *
 * @param   timerModule_en  Timer module to configure.
 * @param   period_u64      Timer refresh period in microseconds.
 *                          The value is rounded up to the nearest resolution divider.
 *
 * @note    The period cannot be 0, as it would imply an immediate event.
 *          Instead, execute the event directly or call the stop function manually.
 *
 * @return  Error code: 0 if successful, nonzero otherwise.
 */
uint32 HalTimerReloadUs(MapHalTimerModule_en timerModule_en, uint64 period_u64);

/**
 * @brief   Retrieves the remaining time for the specified timer in microseconds.
 *
 * @param   timerModule_en      Timer module to query.
 * @param   remainingTime_u64   Pointer to store the remaining time in microseconds.
 *                              The value is rounded up to the nearest resolution divider.
 *
 * @return  Error code: 0 if successful, nonzero otherwise.
 */
uint32 HalTimerGetRemainingTimeUs(MapHalTimerModule_en timerModule_en, uint64 *remainingTime_u64);

/**
 * @brief   Configures a callback function for the specified timer module.
 *
 * @param   timerModule_en  Timer module for which the callback is being set.
 * @param   callback_pfn    Pointer to the callback function.
 *
 * @return  Error code: 0 if successful, nonzero otherwise.
 */
uint32 HalTimerConfigureCallback(MapHalTimerModule_en timerModule_en, void (*callback_pfn)(void));

/**
 * @brief   Deinitializes the specified timer module, stopping all active timers.
 *          This is useful for transitioning between application and bootloader.
 *
 * @param   timerModule_en  Timer module to be deinitialized.
 */
void HalTimerDeinit(MapHalTimerModule_en timerModule_en);

#endif /* __HAL_TIMER_H_ */
