/* ###################################################################
**     Filename    : main.c
**     Project     : G4XS_KL25Z_ParseStatusData
**     Processor   : MKL25Z128VLK4
**     Version     : Driver 01.01
**     Compiler    : GNU C Compiler
**     Date/Time   : 2015-06-22, 14:27, # CodeGen: 0
**     Abstract    :
**         Main module.
**         This module contains user's application code.
**     Settings    :
**     Contents    :
**         No public methods
**
** ###################################################################*/
/*!
** @file main.c
** @version 01.01
** @brief
**         Main module.
**         This module contains user's application code.
*/         
/*!
**  @addtogroup main_module main module documentation
**  @{
*/         
/* MODULE main */


/* Including needed modules to compile this module/procedure */
#include "Cpu.h"
#include "Events.h"
#include "G4XS1.h"
#include "RSTBPin1.h"
#include "CLK1.h"
#include "SPI_Device1.h"
#include "CSpin1.h"
#include "TU1.h"
#include "SM1.h"
#include "CsIO1.h"
#include "IO1.h"
/* Including shared modules, which are used for whole project */
#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"
/* User includes (#include below this line is not maintained by Processor Expert) */
#include <stdio.h>
#include "Helpers.h"
#include "FSL_Wait.h"

/**
 * Gets and parses quick status data.
 */
void ParseQuickStatusData(void) {
  G4XS1_TError Error;
  uint16_t StatusData;

  Error = G4XS1_GetQuickStatus(0, &StatusData);
  if (Error != ERR_OK) {
    printf("G4XS1_GetQuickStatus failed with error %u\n", Error);
  }
  else {
    if (G4XS_GET_QSF1(StatusData)) {
      printf("QSF flag is present. Some of (OC | OTW | OTS | OLON | OLOFF) events occurred on channel 1.\n");
    }
    if (G4XS_GET_QSF2(StatusData)) {
      printf("QSF flag is present. Some of (OC | OTW | OTS | OLON | OLOFF) events occurred on channel 2.\n");
    }
    if (G4XS_GET_QSF3(StatusData)) {
      printf("QSF flag is present. Some of (OC | OTW | OTS | OLON | OLOFF) events occurred on channel 3.\n");
    }
    if (G4XS_GET_QSF4(StatusData)) {
      printf("QSF flag is present. Some of (OC | OTW | OTS | OLON | OLOFF) events occurred on channel 4.\n");
    }
    if (G4XS_GET_QSF5(StatusData)) {
      printf("QSF flag is present. Some of (OC | OTW | OTS | OLON | OLOFF) events occurred on channel 5.\n");
    }
    if (G4XS_GET_CLKF(StatusData)) {
      printf("CLKF flag is present. PWM clock failed.\n");
    }
    if (G4XS_GET_RCF(StatusData)) {
      printf("RCF flag is present. Registers have been cleared.\n");
    }
    if (G4XS_GET_CPF(StatusData)) {
      printf("CPF flag is present. Charge pump failed.\n");
    }
  }
}

/**
 * Gets and parses channel 1-5 status data.
 */
void ParseChannelStatusData(void) {
  G4XS1_TError Error;
  uint16_t StatusData[5] = {0};
  char str_bin[33];

  Error = G4XS1_GetChannelStatus(0, StatusData);
  if (Error != ERR_OK) {
    printf("G4XS1_GetChannelStatus failed with error %u\n", Error);
  }

  for (uint8_t ch = 0, sd = 0; ch < 5; ch++) {
    if (G4XS1_CH_MASK_GET(G4XS1_DeviceDataPtr->ChUsedMask[0], ch)) {
      if (G4XS_GET_OLOFFX(StatusData[sd])) {
        printf("OLOFF flag is present. Open load in OFF state was detected on channel %d.\n", ch + 1);
      }
      if (G4XS_GET_OLONX(StatusData[sd])) {
        printf("OLON flag is present. Open load in ON state was detected on channel %d.\n", ch + 1);
      }
      switch (G4XS_GET_OCX(StatusData[sd])) {
        case 1:
          printf("OCHI1 level on channel %d.\n", ch + 1);
          break;
	    case 2:
	      printf("OCHI2 level on channel %d.\n", ch + 1);
	      break;
	    case 3:
	      printf("OCHI3 level on channel %d.\n", ch + 1);
	      break;
	    case 4:
	      printf("OCLO level on channel %d.\n", ch + 1);
	      break;
	    case 5:
	      printf("OCHIOD level on channel %d.\n", ch + 1);
	      break;
	    case 6:
	      printf("SSC - severe short circuit was detected on channel %d.\n", ch + 1);
	      break;
	    default:
	      break;
	  }
	  if (G4XS_GET_OTWX(StatusData[sd])) {
	    printf("OTW flag is present. Over-temperature warning on channel %d.\n", ch + 1);
	  }
	  if (G4XS_GET_OTSX(StatusData[sd])) {
	    printf("OTS flag is present. Over-temperature shutdown on channel %d.\n", ch + 1);
	  }
	  sd++;
    }
  }
}

/**
 * Gets and parses IO status data.
 */
void ParseIOStatusData(void) {
  G4XS1_TError Error;
  uint16_t StatusData;

  Error = G4XS1_GetIOStatus(0, &StatusData);
  if (Error != ERR_OK) {
    printf("G4XS1_GetIOStatus failed with error %u\n", Error);
  }
  else {
    if (G4XS_GET_OUT1(StatusData)) {
      printf("OUT1 flag is present. Channel 1 is turned on.\n");
    }
    if (G4XS_GET_OUT2(StatusData)) {
      printf("OUT2 flag is present. Channel 2 is turned on.\n");
    }
    if (G4XS_GET_OUT3(StatusData)) {
      printf("OUT3 flag is present. Channel 3 is turned on.\n");
    }
    if (G4XS_GET_OUT4(StatusData)) {
      printf("OUT4 flag is present. Channel 4 is turned on.\n");
     }
    if (G4XS_GET_OUT5(StatusData)) {
      printf("OUT5 flag is present. Channel 5 is turned on.\n");
    }
  }
}

/**
 * Gets and parses device status data.
 */
void ParseDeviceStatusData(void) {
  G4XS1_TError Error;
  uint16_t StatusData;

  Error = G4XS1_GetDeviceStatus(0, &StatusData);
  if (Error != ERR_OK) {
    printf("G4XS1_GetDeviceStatus failed with error %u\n", Error);
  }
  else {
    if (G4XS_GET_ILIMP(StatusData)) {
      printf("ILIMP flag is present. ILIMP input is at high level.\n");
    }
    if (G4XS_GET_SPIF(StatusData)) {
      printf("SPIF flag is present. SPI failed.\n");
    }
    if (G4XS_GET_UVF(StatusData)) {
      printf("UVF flag is present. Under-voltage was detected.\n");
    }
    if (G4XS_GET_OVF(StatusData)) {
      printf("OVF flag is present. Over-voltage was detected.\n");
    }
  }
}

/**
 * Gets and parses device type, family and design status.
 */
void ParseDeviceID(void) {
  G4XS1_TError Error;
  uint16_t StatusData;

  Error = G4XS1_ReadRegister(0, sorDEVICE_ID, &StatusData);
  if (Error != ERR_OK) {
    printf("G4XS1_ReadRegister failed with error %u\n", Error);
  }
  else {
    switch (G4XS_GET_DEV_TYPE(StatusData)) {
      case 0:
        printf("G4XS Device Type : Penta 3/2.\n");
	    break;
	  case 1:
	    printf("G4XS Device Type : Penta 0/5.\n");
	    break;
	  case 2:
	    printf("G4XS Device Type : Quad 2/2.\n");
	    break;
	  case 3:
	    printf("G4XS Device Type : Quad 0/4.\n");
	    break;
	  case 4:
	    printf("G4XS Device Type : Triple 1/2.\n");
	    break;
	  case 5:
	    printf("G4XS Device Type : Triple 0/3.\n");
	    break;
	  default:
	    break;
	}

	printf("G4XS Device Family : %d.\n", G4XS_GET_DEV_FAMILY(StatusData));
    printf("G4XS Device Design Status : %d.\n", G4XS_GET_DEV_STATUS(StatusData));
  }
}

/**
 * Prints all status registers in raw format.
 */
void PrintStatusRegisters(void) {
  G4XS1_TError Error;
  uint16_t RegVal;
  char str_bin[33];

  const char *G4XS_so_names[] = {"QUICK_STATUS", "CH1_STATUS", "CH2_STATUS", "CH3_STATUS", "CH4_STATUS", "CH5_STATUS", "DEVICE_STATUS", "IO_STATUS", "DEVICE_ID"};

  for (uint8_t i = sorQUICK_STATUS; i < sorDEVICE_ID; i++) {
    Error =  G4XS1_ReadRegister(0, i, &RegVal);
    if (Error != ERR_OK) {
      printf("PrintStatusRegisters: G4XS_ReadRegister failed with error %u\n", Error);
      break;
    }
    printf("SO (%s) : (%s)\n", G4XS_so_names[i], uint16ToBinary(str_bin, RegVal));
    if (i == (G4XS1_SO_NUM - 1)) {
      printf("\n\n");
    }
  }
}

/*lint -save  -e970 Disable MISRA rule (6.3) checking. */
int main(void)
/*lint -restore Enable MISRA rule (6.3) checking. */
{
  /* Write your local variable definition here */

  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
  PE_low_level_init();
  /*** End of Processor Expert internal initialization.                    ***/

  printf("32VeXtremeSwitch\n");

  if (G4XS1_Init(NULL) == ERR_OK) {
	printf("Initialization was successful.\n");
  }
  else {
    printf("Initialization failed.\n");
  }

  ParseDeviceID();
  ParseIOStatusData();

  while (1) {
    printf("\n<G4XS Status Report>\n\n");

    PrintStatusRegisters();

    ParseQuickStatusData();
    ParseChannelStatusData();
    ParseDeviceStatusData();

    for (uint8_t i = 0; i < 40; i++) { /* waits for 2 sec */
      WaitMS(10);
      G4XS1_FeedWatchdog();
    }
  }

  /*** 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(;;){}
  /*** 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.5 [05.21]
**     for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/
