/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : hal_stm32f4_delay.c
  * @brief          : STM32F4 specific Delay HAL implementation
  ******************************************************************************
  */
/* USER CODE END Header */

#include "hal.h"
#include "hal_delay.h"
#include "stm32f4xx_hal.h"

/**
 * @brief STM32F4 specific delay initialization
 */
void hal_stm32f4_delay_init(void) {
    /* Enable DWT (Data Watchpoint and Trace) */
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
    /* Reset DWT cycle counter */
    DWT->CYCCNT = 0;
    /* Enable DWT cycle counter */
    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}

/**
 * @brief STM32F4 specific delay in milliseconds
 * @param ms: Delay time in milliseconds
 */
void hal_stm32f4_delay_ms(uint32_t ms) {
    HAL_Delay(ms);
}

/**
 * @brief STM32F4 specific delay in microseconds
 * @param us: Delay time in microseconds
 */
void hal_stm32f4_delay_us(uint32_t us) {
    uint32_t ticks = 0;
    uint32_t start_tick = 0;
    uint32_t tick_freq = HAL_RCC_GetHCLKFreq() / 1000000;
    
    ticks = us * tick_freq;
    start_tick = DWT->CYCCNT;
    
    /* Wait for the specified number of ticks */
    while ((DWT->CYCCNT - start_tick) < ticks) {
        /* Busy wait */
    }
}

/**
 * @brief STM32F4 specific get tick implementation
 * @return Current tick count in milliseconds
 */
uint32_t hal_stm32f4_get_tick(void) {
    return HAL_GetTick();
}

/**
 * @brief Get current DWT cycle count
 * @return Current DWT cycle count
 */
uint32_t hal_stm32f4_get_dwt_tick(void) {
    return DWT->CYCCNT;
}
