
#include "main.h"
#include "sys.h"
#include "delay.h"

#include "QC12864B.h"
#include "Uart1.h"

unsigned int  SystemClockFreq;
cc Status0 , Status1 , Status2, Status3;

/****************************配置引脚**********************************/
/*
//APB1(低速外设)：电源接口、备份接口、CAN、USB、I2C1、I2C2、UART2、UART3、SPI2、窗口看门狗、Timer2、Timer3、Timer4。
//APB2(高速外设)：UART1、SPI1、Timer1、ADC1、ADC2、所有普通IO口(PA~PE)、第二功能IO口。

版本1.5
AHB :IO口(PA~PF)、TS、CRC、FLITF、SRAM、DMA1、DMA2
APB2:SYSCFG、USART6~8、ADC1、TIM1、SPI1、USART1、TIM15~17、DBGMCU
APB1:TIM2/3/6/7/14、WWDG、SPI2、USART2~5、I2C1~2、USB、CAN、CRS、PWR、DAC、CEC
*/
#define HAL_LED0	PAout->b4
#define HAL_TEST	PAout->b5

void GpioConfig_SYSLed ( void )
{
#if SYSLed_def
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_AHBPeriphClockCmd ( LED_RCC_CONFIG , ENABLE );
    /**
     *	LED -> PA4
     */
    GPIO_InitStructure.GPIO_Pin = LED_PIN_CONFIG;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_Init ( LED_PORT_CONFIG, &GPIO_InitStructure );
#endif
}

void GpioConfig_SR04 ( void )
{
#if HC_SR04_def
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_AHBPeriphClockCmd ( SR04_RCC_CONFIG , ENABLE );
    /**
     *	out -> PA5	in -> PA6
     */
    GPIO_InitStructure.GPIO_Pin = SR04_OUTPIN_CONFIG;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_Init ( SR04_PORT_CONFIG, &GPIO_InitStructure );
    //外部按键GPIO初始华，PA6
    GPIO_InitStructure.GPIO_Pin = SR04_INPIN_CONFIG;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //无上下拉
    GPIO_Init ( SR04_PORT_CONFIG, &GPIO_InitStructure );

    //将EXTI0指向PA0
    SYSCFG_EXTILineConfig ( EXTI_PortSourceGPIOA, EXTI_PinSource6 );
    //EXTI0中断线配置
    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line = EXTI_Line6;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //上下沿触发 EXTI_Trigger_Rising_Falling
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init ( &EXTI_InitStructure );

    //EXTI0中断向量配置
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_15_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = SR04_INPIN_Pre;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init ( &NVIC_InitStructure );

#endif
}


void GpioConfig_LCD ( void )
{
#if LCD_def
    GPIO_InitTypeDef  GPIO_InitStructure;

    /* Enable the GPIO_LED Clock */
    RCC_AHBPeriphClockCmd ( LCD_QC12864B_RCC, ENABLE );

    /* Configure the GPIO_LED pin */
    GPIO_InitStructure.GPIO_Pin = LCD_QC12864B_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
    GPIO_Init ( LCD_QC12864B_PORT, &GPIO_InitStructure );
#endif
}

//F030 只有高速TIM1，普通TIM3\14\16\17
void TIM3_Init ( void )
{
    TIM_TimeBaseInitTypeDef TimeBase;

    //TIM2 RCC
    RCC_APB1PeriphClockCmd ( RCC_APB1Periph_TIM3 , ENABLE );

    //Tim5.TIM_Prescaler=72-1; //1MHz ,计数1次为us
    //Tim5.TIM_Prescaler=720-1; //100KHz ,定时器计数100次为1ms

    TIM_DeInit ( TIM3 ); //使用缺省值初始化TIM外设寄存器
    TimeBase.TIM_Period = 1; //自动重装载寄存器值为1
    TimeBase.TIM_Prescaler = ( 42 - 1 ) * 100; //42MHz/42/10=0.01Mhz=0.1ms
    TimeBase.TIM_ClockDivision = TIM_CKD_DIV1; //采样分频倍数1,未明该语句作用。
    TimeBase.TIM_CounterMode = TIM_CounterMode_Up; //上升模式
    TIM_TimeBaseInit ( TIM3, &TimeBase );

    //TIM_ClearFlag(TIM3,TIM_FLAG_Update);//清除更新标志位
    //TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能中断
    //TIM_Cmd(TIM3,ENABLE);//使能TIM3定时器
}

u16 TIM3_CALC()
{
    u16 counter = 0;
    TIM_Cmd ( TIM3, ENABLE );
    TIM_SetCounter ( TIM3, counter ); //设置计数值

    while ( PAin->b6 )  //低电平停止
    {
        counter = TIM_GetCounter ( TIM3 );
    }

    TIM_Cmd ( TIM3, DISABLE );
    return counter;
}


void SysTick_Init ( int SYSTICK_TIME )
{
    RCC_ClocksTypeDef RCC_Clocks;
    RCC_GetClocksFreq ( &RCC_Clocks );
    SystemClockFreq = RCC_Clocks.SYSCLK_Frequency;

    if ( SysTick_Config ( SystemClockFreq / ( 1000000 / SYSTICK_TIME ) ) )
    {
        while ( 1 );
    }
}
/****************************配置结束**********************************/
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed ( uint8_t* file, uint32_t line )
{
    /* User can add his own implementation to report the file name and line number,
       ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

    /* Infinite loop */
    while ( 1 )
    {}
}
#endif

void sysLed_main ( void )
{
#if SYSLed_def
    static bool sysLedOn = false;
    //200ms
    sysLedOn = !sysLedOn;
    HAL_LED0 = sysLedOn;
#endif
}

u32 sys_100us = 0;
u32 sys_rtc_time = 0;
u32 TaskTime = 0;

#define SR04_dat_size 6
bool StartCalSR04 = false;
u32 SR04_100us = 0;
u32 SR04_dat[SR04_dat_size + 2];
u8 SR04_i = 0;
u32 adcGetVal()
{
    int i, j;
    SR04_dat[SR04_dat_size] = 0;
    SR04_dat[SR04_dat_size + 1] = 0xffffffff;

    for ( i = 0; i < SR04_dat_size; i++ )
    {
        for ( j = i; j < SR04_dat_size; j++ )
        {
            if ( SR04_dat[i] > SR04_dat[j] )
            {
                SR04_dat[SR04_dat_size] = SR04_dat[j];
                SR04_dat[j] = SR04_dat[i];
                SR04_dat[i] = SR04_dat[SR04_dat_size];
            }
        }
    }

    return SR04_dat[SR04_dat_size / 2];
}
void EXTI4_15_IRQHandler ( void )
{
    if ( EXTI_GetITStatus ( EXTI_Line6 ) != RESET ) //上升沿触发
    {
        if ( PAin->b6 )   	//上升沿
        {
            SR04_100us = 0;
            PBout->b1 = 1;
        }
        else  			//下降沿
        {
            PBout->b1 = 0;

            if ( SR04_i < SR04_dat_size )
            {
                SR04_dat[SR04_i] = SR04_100us;
                SR04_i++;
            }
            else
            {
                SR04_100us = adcGetVal();
                sprintf ( QC12864B_String[2], "时间:%.2f ms", SR04_100us * 1.0 / 10 );
                sprintf ( QC12864B_String[3], "距离:%.2f m", SR04_100us * 1.0 / 10 * 0.34 / 2 );
                SR04_i = 0;
            }
        }

        EXTI_ClearFlag ( EXTI_Line6 ); //退出中断时注意清除标志位
    }
}



void SysTick_Handler ( void )	//0.1ms
{
    SR04_100us++;
    sys_100us++;

    if ( 0 == ( sys_100us % 10000 ) )
    {
        sys_rtc_time++;			//1s
    }

    TaskTime++;

    if ( TaskTime % 20 == 0 )		System_Flag_2Ms = 1;

    if ( TaskTime % 100 == 0 )		System_Flag_10Ms = 1;

    if ( TaskTime % 1000 == 0 )		System_Flag_100Ms = 1;

    if ( TaskTime % 2000 == 0 )		System_Flag_200Ms = 1;

    if ( TaskTime % 5000 == 0 )		System_Flag_500Ms = 1;

    if ( TaskTime % 10000 == 0 )	System_Flag_1s = 1;

    if ( TaskTime % 80000 == 0 )	System_Flag_8s = 1;

    if ( TaskTime % 200000 == 0 )	System_Flag_20s = 1;

}

int main ( void )
{
    SystemInit();
    SysTick_Init ( 100 ); //us, 最小10us，推荐1000us
    TIM3_Init();

    GpioConfig_SYSLed();
    GpioConfig_SR04();
    GpioConfig_LCD();

    GpioConfig_Usart1();
    LcdInit();

    sprintf ( QC12864B_String[0], "欢迎0824" );
    //LcdPrint(1, "2017-05-26");
    //LcdPrint(1, "09:56");
    //LcdPrint(1, "hjq");

    while ( 1 )
    {
        if ( System_Flag_2Ms )
        {
            System_Flag_2Ms = 0;
        }

        if ( System_Flag_10Ms )
        {
            System_Flag_10Ms = 0;
            //按键扫描
            //KeyHander();
        }

        if ( System_Flag_100Ms )
        {
            System_Flag_100Ms = 0;
            //系统信号灯
            sysLed_main();
            //LCD刷新
            LcdRefresh();
        }

        if ( System_Flag_200Ms )
        {
            System_Flag_200Ms = 0;

            if ( IsUart1Rcv )
            {
                IsUart1Rcv = false;
                UartSend ( "i recv your msg:\n", 17 );
                UartSend ( ( char * ) RxBufferUart, RxCounterUart );
                RxCounterUart = 0;
            }

        }

        if ( System_Flag_500Ms )
        {
            System_Flag_500Ms = 0;

            //0.2~40m, 即波形1.176~235.294ms，0.5秒最大可测2次
            PAout->b5 = 1;
            PAout->b7 = 1;
            delay_us ( 20 ); //10us以上的周期
            PAout->b5 = 0;
            PAout->b7 = 0;
        }

        if ( System_Flag_1s )
        {
            System_Flag_1s = 0;
            sprintf ( QC12864B_String[1], "时钟:%04d s", sys_rtc_time % 10000 );
        }

        if ( System_Flag_8s )
        {
            System_Flag_8s = 0;
            UartSend ( "i send one msg", 14 );
        }

        if ( System_Flag_20s )
        {
            System_Flag_20s = 0;
        }

    }
}
