#include "soft_test.h"
#include "main.h"
#include "tim.h"
#include "soft_can.h"
#include "soft_uart.h"
#include "can.h"
#include "usart.h"
#include "soft_terrain.h"
#include "soft_obstacle.h"
#include "soft_p_2_c.h"
#include "soft_flash.h"
#include "soft_obstacle.h"
#include "string.h"
#include "can_debug.h"
#include "soft_version.h"
#include "config.h"

/******************************************************************
 * ****************测试程序*****************************************
 * ****************************************************************/
uint8_t UART3_send_buf[8] = {0, 1, 2, 3, 4, 5, 6, 7}; //DMA发送 不能用局部变量  可以使用static局部变量
void uart_send_msg(void)
{
  static uint32_t uart_time = 0;
  if (HAL_GetTick() - uart_time < 100)
  {
    return;
  }
  else
  {
    uart_time = HAL_GetTick();
  }

  uint32_t cur_time = HAL_GetTick();
  memcpy(&UART3_send_buf[0],&cur_time,4);
  //HAL_UART_Transmit(&huart3,&UART3_send_buf[i],1,0xFFFF);
  //HAL_UART_Transmit_DMA(&huart2, UART2_send_buf, 8); //DMA发送数据
  //HAL_UART_Transmit(&huart2,&UART2_send_buf[i],1,0xFFFF);
  /*
	while (huart3.gState == HAL_UART_STATE_READY)
	{
		assd++;
	}
  */
  HAL_UART_Transmit_DMA(&huart3, UART3_send_buf, 4);
}


void ttest_func(void)
{
    /*
  if (HAL_GetTick() - led_time > 1000 && HAL_GetTick() > 10000)
  {
    HAL_GPIO_TogglePin(GPIOA,LED2_Pin);
    led_time = HAL_GetTick();
  }
  
  if ((HAL_GetTick() > 5000) && (a == 1))
  {
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 1300);
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 1700);
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 1700);
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 1700);
    a = 0;
  }
  */
  //5HZ 发送CAN

  //uart_send_msg();

  //HAL_GPIO_WritePin(GPIOA, LED1_Pin, SET); //蓝色
  //HAL_GPIO_WritePin(GPIOA, LED2_Pin, SET); //红色
  //HAL_GPIO_WritePin(GPIOA, LED3_Pin, SET); //绿色
}

uint32_t led_time_green = 0;
uint32_t led_time_purple = 0;
uint32_t led_time_blue = 0;
uint32_t led_time_yellow = 0;

bool led_green = false;
bool led_purple = false;
bool led_blue = false;
bool led_yellow = false;

bool only_star_one_green = false;
bool only_star_one_purple = false;
bool only_star_one_blue = false;
bool only_star_one_yellow = false;

bool no_led_star = false;



/**
  * @file    pmu_inside_led
  * @brief   板载LED灯
  * @param   None
  * @details 绿：正常 --紫色：仿地 --蓝：前避 -- 黄：后避
  * @author  Zhang Sir 
 **/
void pmu_inside_led()
{
  if (led_green == false && led_purple == false && led_blue == false && led_green == false && led_yellow == false)
  {
    no_led_star = true;
  }
  else
  {
    no_led_star = false;
  }

  //正常闪绿灯  设备连接后依次闪其他颜色
  if ((HAL_GetTick() - led_time_green > 2500) && (no_led_star == true) &&
      (only_star_one_green == false))
  {
    HAL_GPIO_WritePin(GPIOA, LED3_Pin, GPIO_PIN_RESET);
    led_time_green = HAL_GetTick();
    led_green = true;

    only_star_one_green = true;
    only_star_one_purple = true;
    only_star_one_blue = true;
    only_star_one_yellow = true;
  }
  else if (terrain_is_link == true && no_led_star == true && only_star_one_purple == true)
  {
    HAL_GPIO_WritePin(GPIOA, LED2_Pin, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOA, LED1_Pin, GPIO_PIN_RESET);
    led_time_purple = HAL_GetTick();
    led_purple = true;
  }
  else if (obs_f_is_link == true && no_led_star == true && only_star_one_blue == true)
  {
    HAL_GPIO_WritePin(GPIOA, LED1_Pin, GPIO_PIN_RESET);
    led_time_blue = HAL_GetTick();
    led_blue = true;
  }
  else if (obs_b_is_link == true && no_led_star == true && only_star_one_yellow == true)
  {
    HAL_GPIO_WritePin(GPIOA, LED3_Pin, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOA, LED2_Pin, GPIO_PIN_RESET);
    led_time_yellow = HAL_GetTick();
    led_yellow = true;
  }

  //灭灯
  if ((HAL_GetTick() - led_time_green >= 500) && led_green == true)
  {
    HAL_GPIO_WritePin(GPIOA, LED3_Pin, GPIO_PIN_SET);
    led_green = false;
    only_star_one_green = false;
  }
  if ((HAL_GetTick() - led_time_purple >= 500) && led_purple == true)
  {
    HAL_GPIO_WritePin(GPIOA, LED2_Pin, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOA, LED1_Pin, GPIO_PIN_SET);
    led_purple = false;
    only_star_one_purple = false;
  }
  if ((HAL_GetTick() - led_time_blue >= 500) && led_blue == true)
  {
    HAL_GPIO_WritePin(GPIOA, LED1_Pin, GPIO_PIN_SET);
    led_blue = false;
    only_star_one_blue = false;
  }
  if ((HAL_GetTick() - led_time_yellow >= 500) && led_yellow == true)
  {
    HAL_GPIO_WritePin(GPIOA, LED2_Pin, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOA, LED3_Pin, GPIO_PIN_SET);
    led_yellow = false;
    only_star_one_yellow = false;
  }
  //ttest_func();

}

/**
  * @file    user_init
  * @brief   初始化参数
  * @param   None
  * @details 串口 can口 pwm rkfifo flash读取
  * @author  Zhang Sir 
 **/
uint8_t recv_vk_protocol[MAX_UART_BUF] = {0};
uint8_t candebug_protocol[MAX_UART_BUF] = {0};
uint8_t send_uart_buffer[ MAX_UART_BUF * 3 ] = {0};
void user_init(void)
{
  //can pwm uart 初始化
  can_start_init();

  UART_Init();

  pwm_init();

  //PVD_Config();

  //上电读内存参数
  flash_read_funcktion();
  
  //上电亮绿灯
  HAL_GPIO_WritePin(GPIOA, LED3_Pin, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET); //使能PWM

  //初始化缓存区
  rkfifo_init(&recv_rkfifo, recv_vk_protocol, sizeof(recv_vk_protocol), 1);
  rkfifo_init(&candebug_rkfifo, candebug_protocol, sizeof(candebug_protocol), 1);
  rkfifo_init(&send_uart_rkfifo, send_uart_buffer, sizeof(send_uart_buffer), 1);

  //注册PMU
  Int2String(serial.num,dev_pmu.sn,9);
  Int2String(APP_VERSION,dev_pmu.soft_serial,6);
  regist_dev_info(&dev_pmu,DEVICE_PMU,false,dev_pmu.sn,9,dev_pmu.soft_serial,6,NULL,0,"vk",3);
}

uint8_t isLeapYear(uint16_t year)
{
    uint8_t res=0;

    if(year%4 == 0) // 能够被4整除
    {
        if(year%100 != 0 || year%400 == 0)  //能被4整除不能被100整除或者能够被400整除
        {
            res = 1;
        }
        else
        {
            res =0;
        }
    }
    return res;
}
// 将Unix时间戳转换为北京时间
// unixTime: 需要判断的Unix时间戳
// *tempBeijing:返回的北京时间
// return：none
// note：没对输入参数正确性做判断
rtc_time_t beijing_time;
void covUnixTimeStp2Beijing( uint32_t unixTime, rtc_time_t *tempBeijing )
{
    uint32_t totleDayNum = 0, totleSecNum = 0;
    uint16_t remainDayofYear = 0, tempYear = 0;
    uint8_t *pr = NULL;
    static uint8_t month_day[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //平年
    static uint8_t Leap_month_day[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //闰年


    totleDayNum = unixTime / ( 24 * 60 * 60 ); //总天数(注意加括号)
    totleSecNum = unixTime % ( 24 * 60 * 60 ); //当天剩余的秒速

    memset( tempBeijing, 0x00, sizeof( rtc_time_t ) );

    // 1.先计算时间 HH:MM:SS
    tempBeijing->ui8Hour = totleSecNum / 3600;
    tempBeijing->ui8Minute = ( totleSecNum % 3600 ) / 60; //error：变量搞错
    tempBeijing->ui8Second = ( totleSecNum % 3600 ) % 60;

    // 2.对时间进行时区调整（注意：这里可能造成日期 +1）
    tempBeijing->ui8Hour += TIMEZONE;
    if ( tempBeijing->ui8Hour > 23 )
    {
        //printf("modify day..\n");
        tempBeijing->ui8Hour -= 24;
        remainDayofYear++;  // 日期+1
    }

    // 3.计算哪一年
    tempBeijing->ui8Year = 1970 + ( totleDayNum / FOURYEARDAY ) * 4; // 4年为一个周期
    remainDayofYear += totleDayNum % FOURYEARDAY;

    //printf("year:%d, day:%d.\n", tempBeijing->ui8Year, remainDayofYear);
    tempYear = isLeapYear( tempBeijing->ui8Year ) ? 366 : 365;
    while ( remainDayofYear >= tempYear ) // 计算4年整数倍外的年。
    {
        tempBeijing->ui8Year++;
        remainDayofYear -= tempYear;
        tempYear = isLeapYear( tempBeijing->ui8Year ) ? 366 : 365;
    }

    // 4.计算哪一月的哪一天
    pr = isLeapYear( tempBeijing->ui8Year ) ? Leap_month_day : month_day;
    remainDayofYear++;          // 这里开始计算具体日期。remainDayofYear为 0 时其实是 1 号，所以这里要 +1
    while ( remainDayofYear > *( pr + tempBeijing->ui8Month ) )
    {
        remainDayofYear -= *( pr + tempBeijing->ui8Month );
        tempBeijing->ui8Month++;
    }
    //printf("year:%d, day:%d.\n", tempBeijing->ui8Year, remainDayofYear);
    tempBeijing->ui8Month++; //month
    tempBeijing->ui8DayOfMonth = remainDayofYear;  //day
    //printf("year:%d, day:%d.\n", tempBeijing->ui8Year, tempBeijing->ui8DayOfMonth);
}


void PVD_IRQHandler(void)
{
    HAL_PWR_PVD_IRQHandler();
}

void PVD_Config(void)
{
    /*##-1- Enable Power Clock #################################################*/
    __HAL_RCC_PWR_CLK_ENABLE();
 
    /*##-2- Configure the NVIC for PVD #########################################*/
    HAL_NVIC_SetPriority(PVD_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(PVD_IRQn);
 
    PWR_PVDTypeDef sConfigPVD;
    sConfigPVD.PVDLevel = PWR_PVDLEVEL_3;
    sConfigPVD.Mode = PWR_PVD_MODE_IT_RISING;
    HAL_PWR_ConfigPVD(&sConfigPVD);
 
    /* Enable the PVD Output */
    HAL_PWR_EnablePVD();

}

void HAL_PWR_PVDCallback(void)
{
    volinf._vol_flag = ( int16_t )0xA48A;
    //HAL_GPIO_WritePin(GPIOA, LED1_Pin, GPIO_PIN_RESET);
    volinf.cal_vol = 15;

     WriteFlashNBtye( FLASH_VOL_IFO, ( uint8_t * )&volinf, sizeof( volinf ) );
    
}
