#include "DWT.h"

// 寄存器基地址
#define DWT_CR (*(uint32_t *)0xE0001000)
#define DWT_CYCCNT (*(uint32_t *)0xE0001004)
#define DEM_CR (*(uint32_t *)0xE000EDFC)

// 定义需使能位
#define DEM_CR_TRCENA (1 << 24)
#define DWT_CR_CYCCNTENA (1 << 0)

// DWT init
void DWT_init(void)
{
    DEM_CR |= (uint32_t)DEM_CR_TRCENA;
    DWT_CYCCNT = (uint32_t)0u;
    DWT_CR |= (uint32_t)DWT_CR_CYCCNTENA;
}
// get DWT count
uint32_t DWT_TS_GET(void)
{
    return ((uint32_t)DWT_CYCCNT);
}

// 使用DWT延时time_us微秒
void DWT_delay_us(uint32_t time_us)
{
    uint32_t old_counter, current_counter;
    uint32_t delay_us;

    old_counter = DWT_TS_GET();
    current_counter = DWT_TS_GET();
    delay_us = 0;
    while (delay_us < time_us)
    {
        current_counter = DWT_TS_GET();
        if (current_counter > old_counter)
            delay_us = (current_counter - old_counter) / (SystemCoreClock / 1000000);
        else
            delay_us = (current_counter + 0XFFFFFFFF - old_counter) / (SystemCoreClock / 1000000);
    }
}

// 使用DWT延时time_ms毫秒
void DWT_delay_ms(uint32_t time_ms)
{
    uint32_t old_counter, current_counter;
    uint32_t delay_ms;

    old_counter = DWT_TS_GET();
    current_counter = DWT_TS_GET();
    delay_ms = 0;
    while (delay_ms < time_ms)
    {
        current_counter = DWT_TS_GET();
        if (current_counter > old_counter)
            delay_ms = (current_counter - old_counter) / (SystemCoreClock / 1000);
        else
            delay_ms = (current_counter + 0XFFFFFFFF - old_counter) / (SystemCoreClock / 1000);
    }
}
