////////////////////////////////////////////////////////////////////////////////

/// main文件
///
///
/// 包含操作系统、设备驱动初始化及任务的创建 
/// @file    app.c 
/// @author  gkl 
/// @date    2017-05-25
/// @version v0.1 

////////////////////////////////////////////////////////////////////////////////

// 包含的头文件
#include  <includes.h>
#include "gd32f4xx.h"
#include "service_autoreturn.h"
#include "agent_hyt.h"
#include "enet_to_udp.h"
#include "pdebug.h"
#include "Lan8720.h"
#include "device_adc_collect.h"
#include "service_areascan.h" 
#include "service_presetbitscan.h"
#include "service_selfcheck.h"
#include "service_statusmonitor.h"
#include "service_update.h"
#include "ptz_struct.h"
#include "Usart.h"
#include "w25q128.h"
#include "device_interrupt.h"
#include "l6235d.h"
#include "device_dac_out.h"
#include "get_angle.h"
#include "speed_to_bldc.h"
#include "device_photoelectricswitch.h"
#include "device_adc_collect.h"
#include "rotate_bldc.h"
#include "angle_poweroffsave.h"
#include "device_wdog.h"
#include "comm_cfginfo.h"
#include "Restore_factory_set.h"
#include "ptz_struct.h"
#include "ptz_global_variable.h"
#include "beep.h"
#include "rotate_step.h"
#include "speed_to_step.h"
#include "systick.h"

#include "service_error_count.h"
//
/// 起始任务 
///
/// 初始化硬件及相关模块 
/// @param  none   
/// @param  none
/// @return none 
/// @note   修改日志
///         gkl于2017-05-27创建      
//uint32_t ck_f = 0U;
static  void  task_start (void *p_arg)
{
      (void)p_arg; 
      BSP_Init();
      // 初始化系统tick
      BSP_Tick_Init(); 
      systick_config();
    #if (OS_TASK_STAT_EN > 0)
      OSStatInit();
    #endif
      rcu_periph_clock_enable(RCU_SYSCFG);//将系统时钟使能放最前面
      //看门狗初始化
      init_wdog_module();  
      //初始化终端串口
      init_term_uart();
      term_printf("\n\n/**********************************************\r\n");
      term_printf("\n               Hello HYT Terminal         \r\n\r\n");
      term_printf("* @ Build:      %s %s\r\n",__DATE__,__TIME__);
      term_printf("* @ Version:    v2.0\r\n");
      term_printf("* @ Copyright:  Huiyuan \r\n");
      term_printf("**********************************************/\r\n\r\n");
      //默认打开回复
      g_ptz.cmd_reply_switch = CMD_REPLY;
      
      g_ptz.hori_repeat_locate_switch = 1;//重复定位打开
      g_ptz.vert_repeat_locate_switch = 1;//重复定位打开
      
      
//      /*临时调试*/
//      g_ptz.hori_self_check = 255;
//      g_ptz.vert_self_check = 255;
//      
//      g_ptz.hori_angleP.angle_allow_max = 360.0;
//      g_ptz.hori_angleP.angle_allow_min = 0.0;
//      
//      g_ptz.vert_angleP.angle_allow_max = 90.0;
//      g_ptz.vert_angleP.angle_allow_min = -90.0;
//      g_ptz.vert_ps_sw1_state = 1;
//      g_ptz.vert_ps_sw2_state = 1;
//      /**********/
      
      //蜂鸣器初始化
      beep_init();
      term_printf("\n               beep init         \r\n\r\n");
//      ck_f=rcu_clock_freq_get(CK_APB1);
      OSTimeDlyHMSM(0u, 0u, 0u, 100u);
      //蜂鸣器开，初始化开始
      beep_enable();
      
      //flash引脚初始化
      Flash_GPIO_Init();
      //获取配置文件
      get_system_config_from_file();
         
      //顶部开关引脚初始化
      ptz_aux_switch_init();
      term_printf("\n               ptz aux switch init        \r\n\r\n");
      //以太网初始化
      init_udp_module();
      term_printf("\n               udp init        \r\n\r\n");
      OSTimeDlyHMSM(0u, 0u, 0u, 100u);
      
      //DAC输出初始化
      init_dac_out_module();
      term_printf("\n               dac out init        \r\n\r\n");
      OSTimeDlyHMSM(0u, 0u, 0u, 50u);
            
      //光电开关初始化
      init_photoelectric_switch_module();
      term_printf("\n               photoelectric switch init        \r\n\r\n");
      //转动控制模块初始化
      init_rotate_monitor_module();
      term_printf("\n               rotate mode init        \r\n\r\n");
      OSTimeDlyHMSM(0u, 0u, 0u, 100u);
      //速度计算初始化
      init_speed_module();
      term_printf("\n               speed init        \r\n\r\n");
      //区域扫描模块初始化
      init_area_scan_module();
      term_printf("\n               area scan init        \r\n\r\n");
      //预置位扫描模块初始化
      init_preset_bit_scan_module();
      term_printf("\n               preset bit init        \r\n\r\n");
      //状态检测模块初始化
      init_status_monitor_module();
      term_printf("\n               status init        \r\n\r\n");
      //软件更新模块初始化
      init_update_module();
      term_printf("\n               update init        \r\n\r\n");
      OSTimeDlyHMSM(0u, 0u, 0u, 100u);
      //按键恢复出厂设置
      init_reset_module();
      term_printf("\n               reset init        \r\n\r\n");
      //初始化自动回传模块
      init_auto_return_module();
      term_printf("\n               auto return init        \r\n\r\n");
      OSTimeDlyHMSM(0u, 0u, 0u, 50u);
       //代理层初始化
      init_agent_module();
      term_printf("\n               agent init        \r\n\r\n");
      //继电器开关初始化
      init_relay_module();
      
      //外部中断初始化
      EXTI_IRQ_init();
      term_printf("\n               exti irq init        \r\n\r\n");
      
      //掉电保护初始化
      init_power_off_module();
      term_printf("\n               power off init        \r\n\r\n");
      
      //数据采集初始化电压、电流、温度
      init_data_collect_module();
      term_printf("\n               data collect init        \r\n\r\n");
      
      OSTimeDlyHMSM(0u, 0u, 0u, 500u);
      v_tmc2160_power_on();//为了不让驱动器的两个电容同时上电，驱动器初始化分别进行
      OSTimeDlyHMSM(0u, 0u, 0u, 500u);
      
#ifdef PTZ_PHOTOELECTRIC_SWITCH
      g_ptz.vert_ps_sw1_down_fall  = 0;
      g_ptz.vert_ps_sw1_up_rise    = 0;
      g_ptz.vert_ps_sw2_up_fall    = 0;
      g_ptz.vert_ps_sw2_down_rise  = 0;
      g_ptz.hori_ps_sw3_right_fall = 0;
      g_ptz.hori_ps_sw3_right_rise = 0;
      g_ptz.hori_ps_sw3_left_fall  = 0;
      g_ptz.hori_ps_sw3_left_rise  = 0;
#endif
      //角度计算模块初始化
      init_angle_module();
      term_printf("\n               angle init        \r\n\r\n");
      
      
      //自检模块初始化
      init_self_check_module();
      term_printf("\n               self check bit init        \r\n\r\n");
      init_error_count_task();//创建误差计算任务
      //蜂鸣器关，初始化结束
      beep_disable();
      
      while (DEF_TRUE) {        
        OSTimeDlyHMSM(0u, 0u, 1u, 0u);
        OSTaskDel(OS_PRIO_SELF);
      }
}

/// 主函数 
///
/// 创建第一个任务，由该任务再创建其他功能任务 
/// @param  none   
/// @param  none
/// @return none 
/// @note   修改日志+
///         gkl于2017-05-26创建
static OS_STK task_start_stk[TASK_START_STK_SIZE];
int  main (void)
{ 
//  __enable_irq();
      //    __disable_fault_irq();
//  __set_FAULTMASK(0);
  
	CPU_INT08U  task_err;   
	CPU_INT08U  name_err;

	CPU_Init();
	Mem_Init();                                                   
	Math_Init();                                              
	BSP_IntDisAll();                                         
	OSInit();                                               

	task_err = OSTaskCreateExt((void (*)(void *)) task_start,          
			(void           *) 0,   
			(OS_STK         *)&task_start_stk[TASK_START_STK_SIZE - 1],
			(INT8U           ) TASK_START_PRIO,
			(INT16U          ) TASK_START_PRIO,
			(OS_STK         *)&task_start_stk[0],
			(INT32U          ) TASK_START_STK_SIZE, 
			(void           *) 0,
			(INT16U          )(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR));

    #if (OS_TASK_NAME_EN > 0)
	OSTaskNameSet(TASK_START_PRIO, "task start", &name_err);
    #endif
        
        if ((task_err == OS_ERR_NONE) && (name_err == OS_ERR_NONE)) {
          pdebug(DEBUG_LEVEL_INFO,"create main  success...\n\r");
	} else { 
          pdebug(DEBUG_LEVEL_FATAL,"create main  failed...\n\r");
	}
        

	OSStart();                                                  
	return (1);//OSCPUUsage
}







/*!
    \brief      none 串口打印任务堆栈信息
    \param[in]  none
    \param[out] none
    \retval     none
    \note       LH  @2022.10.26
*/
static void task_print()
{
  OS_TCB *p_tcb;
  OS_STK_DATA stkDat;
  p_tcb = &OSTCBTbl[0];
  
  char cpuusage = OSCPUUsage;
  /*  优先级  堆使用数量  堆空闲数量  使用率  CPU使用率  任务名字   */
  term_printf(" Prio      Used     Free    Per     cpuusage     TaskName\r\n");
  while(p_tcb != NULL)
  {
    OSTaskStkChk(p_tcb->OSTCBPrio, &stkDat);
    term_printf(" %2d      %5d     %5d    %02d%%     %d     %s\r\n ",p_tcb->OSTCBPrio, stkDat.OSUsed, stkDat.OSFree, (stkDat.OSUsed * 100)/(stkDat.OSUsed + stkDat.OSFree), cpuusage, p_tcb->OSTCBTaskName);              
    p_tcb = p_tcb->OSTCBPrev;
  }
  term_printf("\r\n");
  OSTimeDlyHMSM(0u, 0u, 1u, 0u);
}

static void task_print_task()
{
  while(1)
  {
    task_print();
  }
}

/*!
    \brief      none 打印任务创建
    \param[in]  none
    \param[out] none
    \retval     none
    \note       LH  @2022.10.11
*/
static OS_STK  task_printf_stk[TASK_PTZ_TASK_PRINTF_STK_SIZE];
static  void  creat_task_printf(void)
{ 
   CPU_INT08U  task_err;   
   CPU_INT08U  name_err;
   
   task_err = OSTaskCreateExt((void (*)(void *)) task_print_task,           
		   (void           *) 0,
		   (OS_STK         *)&task_printf_stk[TASK_PTZ_TASK_PRINTF_STK_SIZE - 1],
		   (INT8U           ) TASK_PTZ_TASK_PRINTF_PRIO,                   
		   (INT16U          ) TASK_PTZ_TASK_PRINTF_PRIO,
		   (OS_STK         *)&task_printf_stk[0],
		   (INT32U          ) TASK_PTZ_TASK_PRINTF_STK_SIZE,
		   (void           *) 0,
		   (INT16U          )(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR));     
    #if (OS_TASK_NAME_EN > 0)
    OSTaskNameSet(TASK_PTZ_TASK_PRINTF_PRIO, "task_print_task", &name_err);
    #endif
       
    if ((task_err == OS_ERR_NONE) && (name_err == OS_ERR_NONE)) {
          pdebug(DEBUG_LEVEL_INFO,"create task_print_task  success...\n\r");
	} else { 
          pdebug(DEBUG_LEVEL_FATAL,"create task_print_task  failed...\n\r");
	}
}


void task_printf_init()
{
  creat_task_printf();
}


