/**************************************************************************//**
 * @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>


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      This case show how to set the BUCKG FREQ as a dithering FREQ. you can observe a dithering waveform with a
 *             osciloscope connecting to the SWG PAD of the chip.
 *
 *                                                                 VDDG(12V by default,100~200mA)
 *                                                                 / \
 *                                                                  |       SPD1188  Chip
 *                                        --------------------------|----------------------------
 *                                       |    High Voltage Part     |                            |
 *                                       |    -----------------     |                            |
 *                                       |   |      -------    |    |                            |
 *                                VBAT---|---|---->|       |---|----                             |        SWG
 *                                       |   |     | BUCKG | | |                                 |        ---
 *                                       |   |      -------  | |                                 |-------| X |
 *                                       |   |          -----  |            Low voltage part     |        ---
 *                                       |   |         |       |          --------------------   |
 *                                       |   |        \ /      |         |                    |  |
 *                                       |   |      -------    |   1.2V  |                    |  |
 *                                       |   |     |       |---|-------->|         MCU        |  |
 *                                       |   |     | BUCK3 |---|----     |                    |  |
 *                                       |   |     |       |   |    |    |                    |  |
 *                                       |   |      -------    |    |    |                    |  |
 *                                       |    -----------------     |     --------------------   |
 *                                        --------------------------|----------------------------
 *                                                                  |
 *                                                                 \ /
 *                                                                 VDDC(3.3V,500mA)
 *
 *             In PFM mode, dithering FREQ is not easy to observe the dithering state of the waveform. So, there give a
 *             diagram about BUCKG in PWM mode(but PWM mode is not recommanded in real production). The 'spread-spectrum
 *             amplitude' in SSCRL register change the 'change time'(showed in diagram).'spread-spectrum period' in SSCTL
 *             means how fast to change the 'change time'.
 *
 *                                          -----      ----     ---    --   -    --     ---      ----
 *                                         |     |    |    |   |   |  |  | | |  |  |   |   |    |    |
 *                                         |     |    |    |   |   |  |  | | |  |  |   |   |    |    |
 *                                         |     |    |    |   |   |  |  | | |  |  |   |   |    |    |
 *                                         |     |    |    |   |   |  |  | | |  |  |   |   |    |    |
 *                                                ----      ---     --    -   --    ---     ----
 *                                               |             |
 *                                               |<-Change---->| 
 *                                               |    time     |
 *             Key point :
 *                        BUCKG FREQ amplitude is 0~VBAT.
 *             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);
  }

  /* Read the value BUCKGCTL0 had haven */
  eErrorState = HV_ReadReg(HV_REG_BUCKGCTL0, &u8PREDRIDATA);
  if(eErrorState == ERROR)
  {
    printf("Read BUCKGCTL0 FAIL\n");
    return 0;
  }

  /* 
   * Force BUCKG into PWM mode. 
   * PFM mode is hard to see dithering frequence, so we need to force BUCKG into PWM mode, but keep
   * in mind that PWM mode is not recommanded in real production.
   *
   * Keep in mind, PWM mode is not recommanded in real production. We use PWM mode just for demo.
   */
  eErrorState = HV_WriteReg(HV_REG_BUCKGCTL0, (u8PREDRIDATA & (~0x10)) | BUCKGCTL0_ALL_FRCPWM_FORCE);
  if(eErrorState == ERROR)
  {
    printf("Force BUCKG into PWM mode FAIL\n");
    return ERROR;
  }

  /* Read the value SSCTL had haven */
  eErrorState = HV_ReadReg(HV_REG_SSCTL, &u8PREDRIDATA);
  if(eErrorState == ERROR)
  {
    printf("Read SSCTL FAIL\n");
    return 0;
  }

  /* Enable BUCKG dithering and set amplitude */
  eErrorState = HV_WriteReg(HV_REG_SSCTL, u8PREDRIDATA | SSCTL_ALL_BUCKGSSEN_ENABLE
                                                                     | SSCTL_ALL_BUCKGSSAMP_0_TO_511
                                                                     | SSCTL_ALL_BUCKGSSPRD_2X);
  if(eErrorState == ERROR)
  {
    printf("Set BUCKG FREQ dithering FAIL\n");
    return ERROR;
  }

  /* 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);

  while(1)
  {

  }
}
