#include "./inc/includes.h"

// APP软件两种加载模式（MAIN_APP_LOAD_MODE_DEFAULT和MAIN_APP_LOAD_MODE_BOOTLOADER）
static uint8 gMain_byAppLoadMode = MAIN_APP_LOAD_MODE_BOOTLOADER;

// 主函数入口
int main(void)
{
    main_app_start(gMain_byAppLoadMode);

    return 1;
}

// 主程序启动
// 启动地址:0x08080000,区块大小256K(0x40000)
uint8 main_app_start(uint8 byDebugMode)
{
    uint8 byFlag = 0;

    // APP由bootloader负责加载
    if (byDebugMode == MAIN_APP_LOAD_MODE_BOOTLOADER)
    {
        SCB->VTOR = FLASH_BASE | 0x80000; // 中断向量偏移512KB
        OPEN_INT();                       // 打开总中断
    }

    // 系统初始化失败
    byFlag = main_init();
    if (!byFlag)
    {
        return 0; // 初始化失败，系统退出
    }
    // 系统初始化成功
    else
    {
        main_init_ok();
    }

    // 业务主循环
    // driver_iwdg_init(3, 1000); // 初始化看门狗， 2秒超时复位
    while (1)
    {
        // 定时器服务处理接口
        timer_process_func(NULL);

        // 本地网管服务处理接口
        gui_process_func(NULL);

        // 网管中心服务处理接口
        nmc_process_func(NULL);

        // 同步模块后向处理
        syncback_process_func(NULL);

        // 喂狗
        // driver_iwdg_feed_dog(NULL);
    }

    return 1;
}

// 系统初始化
uint8 main_init()
{
    uint8 byFlag = 0;

    // 设置优先级分组（2组抢占优先级，2组响应优先级）
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    // 驱动初始化
    byFlag = main_driver_init();
    if (!byFlag)
    {
        return 0;
    }

    // 应用层初始化
    byFlag = main_app_init();
    if (!byFlag)
    {
        return 0;
    }

    return 1;
}

// 驱动初始
uint8 main_driver_init()
{
    uint8 byFlag = 0;

    // 初始化用户时钟
    sysrcc_config_user_clk();

    // 初始化延时定时器
    driver_delay_init();

    // 初始化状态灯
    driver_led_gpio_init();

    // 初始化定时器
    driver_timer_init();

    // 初始化串口
    driver_uart_init();
    driver_wifi_init(); // 初始化wifi模块(使用串口通信)
    driver_gui_init();  // 初始化gui模块(使用串口通信)

    // 初始化DAC端口
    driver_dacgpio_init();

    // PA初始化
    driver_pagpio_init();

    // 初始化ATT
    // driver_attgpio_init();

    // 同步模块SPI接口初始化
    driver_syncspi_init();

    // 同步发射模块SPI接口初始化
    driver_synctx_spi_init();

    // I2S接口驱动
    driver_i2s_init();

    // 初始化DAC寄存器
    byFlag = driverapp_dac_init();
    if (!byFlag)
    {
        char *pError = "dac init fail\r\n";
        driver_gui_send_data(pError, (uint16)SYS_STRLEN(pError));
        return 0;
    }

    // 初始化系统参数
    driverapp_cpuflash_init();

    return 1;
}

// 应用层初始化
uint8 main_app_init()
{
    uint8 byFlag = 0;

    ////协议栈两个模块
    ps_init();  // 初始化协议栈模块
    wmm_init(); // 初始化网管参数模块

    // 初始化同步模块
    byFlag = sync_init();
    if (!byFlag)
    {
        char *pError = "sync rx init fail\r\n";
        driver_gui_send_data(pError, (uint16)SYS_STRLEN(pError));
        return 0;
    }

    // 初始化同步发送模块
    byFlag = synctx_init();
    if (!byFlag)
    {
        char *pError = "sync tx init fail\r\n";
        driver_gui_send_data(pError, (uint16)SYS_STRLEN(pError));
        return 0;
    }

    // 初始化系统参数模块(该模块中会用到协议栈相关的数据结构，所以要放到协议栈模块后面初始化)
    byFlag = sysparam_init();
    if (!byFlag)
    {
        char *pError = "sysparam init fail\r\n";
        driver_gui_send_data(pError, (uint16)SYS_STRLEN(pError));
        return 0;
    }

    // 初始化定时器模块
    timer_init();

    // 初始化发送消息模块
    byFlag = ssm_init();
    if (!byFlag)
    {
        char *pError = "ssm init fail\r\n";
        driver_gui_send_data(pError, (uint16)SYS_STRLEN(pError));
        return 0;
    }

    // 初始化本地网管模块
    gui_init();

    // 初始化网管中心
    byFlag = nmc_init();
    if (!byFlag)
    {
        char *pError = "nmc init fail\r\n";
        driver_gui_send_data(pError, (uint16)SYS_STRLEN(pError));
        return 0;
    }

    // 初始化系统监听模块
    monitor_init();

    // 初始化外部中断(最后初始化外部中断)
    exti_init();

    return 1;
}

// 系统初始化成功
void main_init_ok()
{
    uint8 abySysInfo[32] = {0}; // 系统信息

    driver_led_switch(1); // 亮灯

    // 初始化成功
    char *pError = "sys init ok\r\n";
    driver_gui_send_data(pError, (uint16)SYS_STRLEN(pError));

    // 软件版本
    sprintf(abySysInfo, "%s%s", SOFTWARE_VERSION, "\r\n");
    driver_gui_send_data(abySysInfo, (uint16)SYS_STRLEN(abySysInfo));

    // 文件编译日期和时间
    memset(abySysInfo, 0, 32);
    sprintf(abySysInfo, "%s %s%s", __DATE__, __TIME__, "\r\n");
    driver_gui_send_data(abySysInfo, (uint16)SYS_STRLEN(abySysInfo));

    return;
}