/* ###################################################################
**     Filename    : main.c
**     Processor   : S32K1xx
**     Abstract    :
**         Main module.
**         This module contains user's application code.
**     Settings    :
**     Contents    :
**         No public methods
**
** ###################################################################*/
/*!
** @file main.c
** @version 01.00
** @brief
**         Main module.
**         This module contains user's application code.
*/         
/*!
**  @addtogroup main_module main module documentation
**  @{
*/         
/* MODULE main */


/* Including necessary module. Cpu.h contains other modules needed for compiling.*/
#include "Cpu.h"
#include "boot_api.h"
#include "string.h"

volatile int exit_code = 0;

/* User includes (#include below this line is not maintained by Processor Expert) */

int counter1 = 0;
int counter2 = 0;
int flag = 0;

uint8_t buf_tx[] = "Application is Running! \r\n";

uint8_t buf[64] = "download";
uint16_t result;
uint16_t res_api;

/**
 * ymodem_crc16
 * @brief
 * @param
 * @retval None
 */
uint16_t crc16(uint8_t * buf, uint16_t size)
{
  uint16_t chsum;
  uint16_t stat;
  uint16_t i;
  uint8_t * in_ptr;

  in_ptr = buf;
  chsum = 0;
  for (stat = size; stat > 0; stat--) {
    chsum = chsum ^ ( uint16_t ) (*in_ptr++) << 8;
    for (i = 8; i != 0; i--) {
      if (chsum & 0x8000) {
        chsum = chsum << 1 ^ 0x1021;
      } else {
        chsum = chsum << 1;
      }
    }
  }
  return chsum;
}


/*! 
  \brief The main function for the project.
  \details The startup initialization sequence is the following:
 * - startup asm routine
 * - main()
*/
int main(void)
{
  /* Write your local variable definition here */
  CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT, g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
  CLOCK_SYS_UpdateConfiguration(0, CLOCK_MANAGER_POLICY_FORCIBLE);

  /* Add power_manager components for run at 96MHz */
  POWER_SYS_Init(&powerConfigsArr, POWER_MANAGER_CONFIG_CNT, &powerStaticCallbacksConfigsArr, POWER_MANAGER_CALLBACK_CNT);
  POWER_SYS_SetMode(0, POWER_MANAGER_POLICY_FORCIBLE);

  /* All pins initialization */
  PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr);

  /* lpuart1 initialization */
  LPUART_DRV_Init(INST_LPUART1, &lpuart1_State, &lpuart1_InitConfig0);
  LPUART_DRV_Callback_Init(INST_LPUART1, &UART1_Callback_Data);

  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
  #ifdef PEX_RTOS_INIT
    PEX_RTOS_INIT();                   /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of Processor Expert internal initialization.                    ***/

  /* Write your code here */
  /* For example: for(;;) { } */

  res_api = sum_add(5,4);           /* res_api is 9 */

  result  = crc16(buf, 8);          /* result  is 0x550c  */
  res_api = ymodem_crc16(buf, 8);   /* res_api is 0x550c  */

  buf[8] = result >> 8;             /* YModem CRC16 L */
  buf[9] = result;                  /* YModem CRC16 H */
  UART1_User_Rx_In = 0;
  LPUART_DRV_SendData(1,  (const uint8_t *)"\r\n", 2);

  for(;;) {
    /* blink a LED */
    if(counter1++ > 500){
      counter1 = 0;
      if(counter2++ > 1000){
        counter2 = 0;
        PINS_DRV_TogglePins(PTD, 1UL << 16);
        LPUART_DRV_SendData(1, buf_tx, sizeof(buf_tx)-1);
      }
    }
    /* software tool send "download" command with crc16 to restart update application program to update */
    if (UART1_User_Rx_In == 10){
      result = strcmp((const char *)buf, (const char *)UART1_User_Rx_Buf);
    }
    /* system soft reset to update */
    if (result == 0){
      SystemSoftwareReset();
    }
    /* below code is keep, or complier warring */
    if(exit_code != 0) {
      break;
    }
  }

  /*** Don't write any code pass this line, or it will be deleted during code generation. ***/
  /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
  #ifdef PEX_RTOS_START
    PEX_RTOS_START();                  /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of RTOS startup code.  ***/
  /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
  for(;;) {
    if(exit_code != 0) {
      break;
    }
  }
  return exit_code;
  /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

/* END main */
/*!
** @}
*/
/*
** ###################################################################
**
**     This file was created by Processor Expert 10.1 [05.21]
**     for the NXP S32K series of microcontrollers.
**
** ###################################################################
*/
