/*****************************************************************************
 * Copyright (c) 2019, Nations Technologies Inc.
 *
 * All rights reserved.
 * ****************************************************************************
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * Nations' name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ****************************************************************************/

/**
 * @file delay.c
 * @author Nations
 * @version v1.0.0
 *
 * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
 */
#include "delay.h"

static u32  fac_us=0; 
static u32  fac_ms=0;
static u8   max_ms=116;

//
void delay_init()
{
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
    fac_us=SystemCoreClock/1000000;
    fac_ms=fac_us*1000;
}


/**
 * @brief  us delay  program function.
 * @param nus: the setting us value.
 *   note: The system clock should be an integer multiple of 1M .
 *   It is ensure accuracy .
 */
void delay_us(u32 nus)
{
    u32 temp; 
    SysTick->LOAD=nus*fac_us;
    SysTick->VAL=0x00;
    SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;
    do
    {
        temp = SysTick->CTRL;
    }
    while((temp&0x01) && !(temp&(1<<16)));

    SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
    SysTick->VAL =0X00;
}
/**
 * @brief  ms delay  program function.
 * @param mus: the setting ms value.
 *   note: The system clock should be an integer multiple of 1M .
 *   It is ensure accuracy .
 * @note: SysTick->LOAD is 24bits, num<=(0xffffff/SYSCLK)*1000,when SYSCLK = 144MHz, nms<=116 
 */
void delay_ms(u32 nms)
{
    u32 temp;
    SysTick->LOAD=(u32)nms*fac_ms; 
    SysTick->VAL =0x00;
    SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;
    do
    {
        temp=SysTick->CTRL;
    }while((temp&0x01)&&!(temp&(1<<16)));
    SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
    SysTick->VAL =0X00;   
}

void delay_xms(u32 nms)
{
    u16 i;
    u16 count_1 = nms/max_ms;
    u16 count_2 = nms%max_ms;

    if(0 == count_1)
    {
        delay_ms(nms);
    }
    else
    {
        for(i=0;i<count_1;i++)
        {
            delay_ms(max_ms);
        }
        
        if(count_2 != 0)
        {
            delay_ms(count_2);
        }
    }     
}
