#include "delay.h"

/**
 * @brief NOP 延时因子
 * @note  针对 STM32F407 @ 168MHz 且关闭编译优化时的粗略估算。
 *        如果延时太快导致 IIC 通讯失败，请调大此值。
 */
#define US_FACTOR  45 

/**
 * @brief 微秒级主动等待
 * @note  使用 volatile 确保循环不被编译器优化掉
 */
void delay_us(uint32_t us)
{
    // 计算总循环次数
    // 168MHz 下，执行一圈循环约需要几个指令周期
    volatile uint32_t count = us * US_FACTOR;
    
    while(count--)
    {
        __nop(); 
    }
}

/**
 * @brief 毫秒级延时
 */
void delay_ms(uint32_t ms)
{
    // 如果 FreeRTOS 调度器已经运行，则使用 vTaskDelay 释放 CPU
    #if defined(INC_TASK_H)
    if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
    {
        vTaskDelay(pdMS_TO_TICKS(ms));
        return;
    }
    #endif

    // 调度器未运行，或未定义 FreeRTOS 时使用阻塞延时
    while(ms--)
    {
        delay_us(1000);
    }
}
