/*********************************************************
*Copyright (C), 2018, Shanghai Eastsoft Microelectronics Co., Ltd.
*文件名:  main.c
*作  者:  AE Team
*版  本:  V1.00
*日  期:  2022/07/25
*描  述:  Bootloader演示程序
          RXD - PA24  TXD - PA25  BootPin：PB0
          波特率：自适应  校验位：偶校验  停止位：1位
          演示方法请参考文档 AN112_应用笔记_ES8P系列MCU bootloader
 * @note
 *          Change Logs:
 *          Date            Author          Notes
 *          25 July 2022    AE Team         change license to Apache-2.0
 *
 * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 **********************************************************************************
 */
 
 
#include "ES8P5066.h"
#include "macro.h"
#include "typedef.h"
#include "lib_flashiap.h"

extern isp_data_t   g_isp_data;
extern uint32_t     g_boot_timer;
extern uint8_t      g_boot;

void uart_init(UART_TypeDef *uartx);
void uart_proc_fsm(void);
void fsm_init(void);
void JumpToApp(uint32_t addr);

volatile uint32_t DATA;

/***************************************************************
函数名：systick_init
描  述: Systick初始化
输入值：无
输出值：无
返回值：无
***************************************************************/
void systick_init(void)
{
    SysTick->CTRL = 0x07;   /* 处理器时钟，计数到零产生中断 */
    SysTick->LOAD = 16000;  /* 系统时钟16M，1ms产生一次中断 */
    SysTick->VAL = 0;
}

/***************************************************************
函数名：gpio_init
描  述: GPIO初始化
输入值：无
输出值：无
返回值：无
***************************************************************/
void gpio_init(void)
{
    SCU->PROT.Word = 0X55AA6996;
    SCU->PCLKEN.GPIO_EN = 1;
    SCU->PCLKEN.UART0_EN = 1;

    /* BootPIN:PB0 */
    GPIO->PBTYP.Word |= 1;          /* TTL */
    GPIO->PBDIR.DIR_0 = 1;          /* 输出关闭 */
    GPIO->PBINEB.INEB_0 = 0;        /* 输入打开 */
    GPIO->PBFUNC0.PB0 = 0;          /* FUNC0 GPIO */
    GPIO->PBPDE.Word |= 1UL;        /* 弱下拉打开 */
    GPIO->PBPUE.Word &= (~1UL);     /* 弱上拉关闭 */

    /* RX:PA24 */
    GPIO->PATYP.Word |= 1 << 24;        /* TTL */
    GPIO->PADIR.DIR_24 = 1;             /* 输出关闭 */
    GPIO->PAINEB.INEB_24 = 0;           /* 输入打开 */
    GPIO->PAFUNC3.PA24 = 2;             /* FUNC2 RXD */
    GPIO->PAPDE.Word &= (~(1uL << 24)); /* 弱下拉关闭 */
    GPIO->PAPUE.Word &= (~(1uL << 24)); /* 弱上拉关闭 */

    /* TX:PA25 */
    GPIO->PATYP.Word |= 1 << 25;        /* TTL */
    GPIO->PADIR.DIR_25 = 0;             /* 输出打开 */
    GPIO->PAINEB.INEB_25 = 1;           /* 输入关闭 */
    GPIO->PAFUNC3.PA25 = 2;             /* FUNC2 TXD */
    GPIO->PAPDE.Word &= (~(1uL << 25)); /* 弱下拉关闭 */
    GPIO->PAPUE.Word &= (~(1uL << 25)); /* 弱上拉关闭 */
    GPIO->PADS.Word  |= ((1uL << 25));  /* 输出强电流 */
    GPIO->PAODE.Word &= (~(1uL << 25)); /* 推挽输出 */
}

int SystemInit(void)
{
    return 0;
}

void IWDTInit()
{
    IWDT->LOCK.Word = 0x1ACCE551;

    IWDT->LOAD.LOAD = 64000000;
    IWDT->CON.CLKS = 0x0;
    IWDT->CON.IE = 0x01;
    IWDT->CON.RSTEN = 0x01;

    IWDT->LOCK.Word = 0x0;

    return;
}

/***************************************************************
函数名：main
描  述: boot 主函数
输入值：无
输出值：无
返回值：无
***************************************************************/
int main(void)
{
    g_isp_data.syn = 0; /* 尚未完成启动 */
    gpio_init();
    uart_init(UART0);

    systick_init();
    fsm_init();  /* 状态机初始化 */

    NVIC_EnableIRQ(UART0_IRQn);

    while (1)
    {
        IWDT->LOCK.Word = 0x1ACCE551;
        IWDT->INTCLR.Word = 0xFFFFFFFF; /* 清狗 */

        if (g_isp_data.triger == 1)
        {
            __disable_irq();  /* 临界段代码保护 */

            while (g_isp_data.triger == 1)
            {
                uart_proc_fsm();  /* isp命令状态机处理 */
            }

            __enable_irq();
        }

        if (g_boot == 1) /* 需要引导程序到flash */
        {
            JumpToApp(APP_ADDR);
        }
    }
}

/*************************END OF FILE**********************/
