/**************************************************************************//**
 * @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 "spd1188.h"
#include <stdio.h>


uint32_t                    u32PWMPeriod;
uint8_t                     u8PREDRIID                                    = 0;                 /* PRE-DRIVER mode ID */
uint8_t                     u8PREDRIDATA;                                                       /* Data read from PRE-DRIVER */
ErrorStatus                 eErrorState;
uint32_t                    u32SSPBaundrate                               = 1000000;           /* The baundrate of SSP communicating with PRE-DRIVER mode */
uint32_t                    u32Timeout                                    = 500;               /* The number of times try to get PRE-DRIVER mode ID */
uint8_t                     u8Count;


 /*************************************************************************************************************************
 *
 * @brief      We set VDDG output 12V and set BOD protection threshold(14.1V~10V), and enable VDDG under-voltage triggering
 *             trip-zone, at last, we set VDDG output 9V. As we enable pre-driver self-shudown function, when VDDG under-voltage
 *             event happened, the logic will detect the event and trigger the trip-zone evnet, then pre-driver will shut down
 *             itself, as a result, the voltage of VCP PIN on board will comes from about 35V to 24V(if you VBAT is 24V).
 *
 *             Key point:
 *                 PRE-DRIVER init include two step��
 *                     <1> Init the communication circuits(SSP circyits) with MCU, we call this step 'Init PRE-DRIVER module'.
 *                     <2> Init PRE-DRIVER socket itself, we call this step 'Power up PRE-DRIVER mode'.
 *
 *************************************************************************************************************************/


int main(void)
{
  FLASH_WALLOW();
  FLASH_SetTiming(200000000);
  /* Disable flash write access after flash operation had done */
  FLASH_WDIS();

  CLOCK_InitWithRCO(CLOCK_HCLK_200MHZ);

  Delay_Init();

  /*
   * Init the UART
   *
   * 1.Set the GPIO34/35 as UART FUNC
   *
   * 2.Enable the UART CLK
   *
   * 3.Set the rest para
   */
  GPIO_SetPinChannel(GPIO_34,GPIO34_UART_TXD);
  GPIO_SetPinChannel(GPIO_35,GPIO35_UART_RXD);
  CLOCK_EnableModule(UART_MODULE);
  UART_Init(UART,38400);

  /* Init PRE-DRIVER module(this step means 'Init PRE-DRIVER module') and get the ID */
  eErrorState = HV_Init(u32SSPBaundrate, &u8PREDRIID, u32Timeout);
  if(eErrorState == ERROR)
  {
    printf("Init PRE-DRIVER mode FAIL\n");
    return 0;
  }
  else
  {
    printf("Init PRE-DRIVER mode SUCCESS[ID:%d]\n",u8PREDRIID);
  }

  /* Before set BUCKGCTL1 register, read out the old value first */
  eErrorState = HV_ReadReg(HV_REG_BUCKGCTL1, &u8PREDRIDATA);
  if(eErrorState == ERROR)
  {
    printf("Read BUCKGCTL1 FAIL\n");
    return 0;
  }

  /* Set VDDG output 12V */
  eErrorState = HV_WriteReg(HV_REG_BUCKGCTL1, (u8PREDRIDATA & (~0xe0)) | BUCKGCTL1_ALL_VOUTSEL_12_V);
  if(eErrorState == ERROR)
  {
    printf("Set VDDG output value to 12V FAIL\n");
    return 0;
  }

  /* 
   * Set VDDG protection high and low threshold, VDDG default value is 10V, so the max and min value of the threshold
   * must keep enough range to aviod error over-flow/under-flow signal.
   */
  eErrorState = HV_WriteReg(HV_REG_BODVDDGVTH, BODVDDGVTH_ALL_VMAX_14dot1_V | BODVDDGVTH_ALL_VMIN_10dot0_V);
  if(eErrorState == ERROR)
  {
    printf("Set VDDG threshold FAIL\n");
    return 0;
  }

  /* PDRVCTL register can only be writable when CTLKEY=0x99 */
  eErrorState = HV_WriteReg(HV_REG_CTLKEY, CTLKEY_ALL_KEY_BUCKEN);
  if(eErrorState == ERROR)
  {
    printf("Write CTLKEY register FAIL\n");
    return 0;
  }

  /* Power up PRE-DRIVER mode(this step means 'Power up PRE-DRIVER mode') */
  eErrorState = HV_WriteReg(HV_REG_PDRVCTL, PDRVCTL_ALL_EN_ENABLE);
  if(eErrorState == ERROR)
  {
    printf("Power up PRE-DRIVER FAIL\n");
    return 0;
  }

  /* Delay 100us to wait for the VDDG LDO ready */
  Delay_Us(100);

  /* Wait for PRE-DRIVER mode become enable */
  u8Count = 0;
  do{
    eErrorState = HV_ReadReg(HV_REG_GLBSTS0, &u8PREDRIDATA);
    if(eErrorState == ERROR)
    {
      printf("PRE-DRIVER enable FAIL[%02x]\n",u8PREDRIDATA);
      return 0;
    }
    
    u8Count++;
    
    if(u8Count >= 10)
    {
      printf("PRE-DRIVER enable timeout\n");
      return 0;
    }
  }while(((u8PREDRIDATA & GLBSTS0_ALL_CPRDY_READY) == 0) && (u8Count < 10));

  /* additional delay after VDDG ready, for final power settling */
  Delay_Us(100);

  /* 
   * Clear status register before we start to read the status register.
   *
   * The reasons for VDDG:
   * <1> the unpredictable too high latched flag caused by BOD open pulse voltage
   * <2> the unpredictable too low latched flag caused when VDDG across 7.7V(the default under-voltage level)
   */
  eErrorState = HV_WriteReg(HV_REG_GLBSTSCLR0, GLBSTSCLR0_ALL_VBATL_CLEAR
                                                           | GLBSTSCLR0_ALL_VBATH_CLEAR
                                                           | GLBSTSCLR0_ALL_VDDGL_CLEAR
                                                           | GLBSTSCLR0_ALL_VDDGH_CLEAR);
  if(eErrorState == ERROR)
  {
    printf("Clear status FAIL\n");
    return 0;
  }

  /* Select VDDG over-voltage as the TZ0 trigger event */
  eErrorState = HV_WriteReg(HV_REG_PDRVTZ0SEL0, PDRVTZ0SEL0_ALL_VBATL_DISABLE
                                                            | PDRVTZ0SEL0_ALL_VBATH_DISABLE
                                                            | PDRVTZ0SEL0_ALL_VDDGL_ENABLE
                                                            | PDRVTZ0SEL0_ALL_VDDGH_DISABLE);
  if(eErrorState == ERROR)
  {
    printf("Select VDDG over-voltage as the TZ0 trigger event FAIL\n");
    return 0;
  }

  /* PDRVCTL register TZ0EN bit can only be writable when CTLKEY=0x99 */
  eErrorState = HV_WriteReg(HV_REG_CTLKEY, CTLKEY_ALL_KEY_BUCKEN);
  if(eErrorState == ERROR)
  {
    printf("Write CTLKEY register FAIL\n");
    return 0;
  }

  /* Before write PDRVVTL register a new value, we must read out the old value first */
  eErrorState = HV_ReadReg(HV_REG_PDRVCTL, &u8PREDRIDATA);
  if(eErrorState == ERROR)
  {
    printf("Read PDRVVTL FAIL\n");
    return 0;
  }

  /* Enbale pre-driver sefl-shudown function */
  eErrorState = HV_WriteReg(HV_REG_PDRVCTL, u8PREDRIDATA | PDRVCTL_ALL_TZ0EN_ENABLE);
  if(eErrorState == ERROR)
  {
    printf("Enable pre-driver self-shutdown function FAIL\n");
    return 0;
  }

  /* Wait for 4s, then set VDDG below 9V to trigger Trip-zone */
  Delay_Ms(4000);

  /*
   * Set the output voltage of VDDG as 9V to check if BOD can detect the too low voltage condition,
   * and trigger trip-zone.
   */
  eErrorState = HV_WriteReg(HV_REG_BUCKGCTL1, BUCKGCTL1_ALL_VOUTSEL_9_V);
  if(eErrorState == ERROR)
  {
    printf("Set VDDG voltage FAIL\n");
    return 0;
  }

  while(1)
  {

  }
}
