/******************************************************************************
 * @file     main.c
 * @brief    Main program body
 * @version  V4.0.1
 * @date     30-July-2026
 *
 * @note
 * Copyright (C) 2022 Spintrol Electronic Technology (Shanghai) Co., Ltd.. All rights reserved.
 *
 * @attention
 * THIS SOFTWARE JUST PROVIDES CUSTOMERS WITH CODING INFORMATION REGARDING
 * THEIR PRODUCTS, WHICH AIMS AT SAVING TIME FOR THEM. SPINTROL SHALL NOT BE
 * LIABLE FOR THE USE OF THE SOFTWARE. SPINTROL DOES NOT GUARANTEE THE
 * CORRECTNESS OF THIS SOFTWARE AND RESERVES THE RIGHT TO MODIFY THE SOFTWARE
 * WITHOUT NOTIFICATION.
 *
 ******************************************************************************/

#include<stdio.h>
#include<stdlib.h>

#if defined(SPC1158)
#include "spc1158.h"
#elif defined(SPD1148)
#include "spd1148.h"
#elif defined(SPD1178)
#include "spd1178.h"
#elif defined(SPD1188)
#include "spd1188.h"
#elif defined(SPD1163)
#include "spd1163.h"
#else
#include "spc1168.h"
#endif


uint8_t autoBaud = 0;

/*************************************************************************************************************************
*
* @brief      In this case, After starting the ISP download tool, UART sends 0x1 data for the program to automatically
*             match the serial port baud rate, and other data sent by UART is invalid
*
*************************************************************************************************************************/


int main()
{
    FLASH_WALLOW();
#if defined(SPC1158)
    FLASH_SetTiming(100000000);
    /* Disable flash write access after flash operation had done */
    FLASH_WDIS();

    CLOCK_InitWithRCO(100000000UL);
#else
    FLASH_SetTiming(200000000);
    /* Disable flash write access after flash operation had done */
    FLASH_WDIS();

    CLOCK_InitWithRCO(200000000UL);
#endif

    Delay_Init();

    /* Configure GPIO pin as UART function */
    GPIO_SetPinChannel(GPIO_34, GPIO34_UART_TXD);
    GPIO_SetPinChannel(GPIO_35, GPIO35_UART_RXD);
    CLOCK_EnableModule(UART_MODULE);

AUTOBAUD:

    /* UART unit programs Divisor Latch registers */
    UART->UARTABR.bit.ABUP  = UARTABR_BIT_ABUP_UART_PROG_DIVISOR;
    /* Enable Autobuad lock interrupt */
    UART->UARTABR.bit.ABLIE = UARTABR_BIT_ABLIE_ENABLE;

    /* 8 databits */
    UART->UARTLCR.bit.WLS   = UARTLCR_BIT_WLS_8_DATA_BIT;
    /* 1 stop bit */
    UART->UARTLCR.bit.STB   = UARTLCR_BIT_STB_1_STOP_BIT;
    /* No parity  */
    UART->UARTLCR.bit.EPS   = UARTLCR_BIT_PEN_NO_PARITY;

    /* Enable UART unit */
    UART_Enable(UART);

    /* Enable Autobaud detect */
    UART->UARTABR.bit.ABE   = UARTABR_BIT_ABE_ENABLE;

    /* Enable UART interrupt in MCU side */
    NVIC_EnableIRQ(UART_IRQn);

    /* Enable UART interrupt */
    UART_EnableInt(UART);

    /* Wait auto-baud lock */
    while(autoBaud == 0);

    /* Disable auto-baud detect */
    UART->UARTABR.bit.ABE = 0;
    /* Disable auto-baud lock interrupt */
    UART->UARTABR.bit.ABLIE = 0;

    /* Wait data received */
    while(!UART_IsRxNotEmpty(UART));

    /* Read data and validate it */
    while(UART_ReadByte(UART) != 0x01)
    {
        UART_Disable(UART);
        goto AUTOBAUD;
    }

    printf("Auto-baud success!\n");

    /* Enable receive data available interrupt */
    UART_EnableRxDataAvailableInt(UART);


    while(1)
    {
        Delay_Ms(1000);
    }
}


void UART_IRQHandler(void)
{
    /* Auto-baud locked */
    if(UART->UARTIIR_UARTFCR.UARTIIR.bit.ABL == 1)
    {
        autoBaud = 1;
    }

    /* Receive data available */
    if(UART_GetRxDataAvailableIntStatus(UART))
    {
        /* Write data back */
        UART_WriteByte(UART, UART_ReadByte(UART));
    }
}

