/*******************************************************************************
 * ON Semiconductor                                                            *
 * NCV7383 Evaluation KIT                                                      *
 *                                                                             *
 * Interrupts.c                                                                *
 * Interrupt service routine functions                                         *
 *                                                                             *
 * Created by: Filip Brtan                                                     *
 * Date: 30.07.2012                                                            *
 *******************************************************************************/

/* S12X derivative information */ 
#include "mc9s12xf512.h"     

/* Macro definitions for general purpose I/O handling  */
#include "GPIO_macros.h"

/* Variable types and common definitions */
#include "typedefs.h"   

/* UNIFIED driver implementation */         
#include "Fr_UNIFIED.h"

/* FlexRay communication controller function prototypes */
#include "FlexRay_BD.h" 

/* FlexRay bus driver function prototypes */
#include "FlexRay_CC.h" 

/* CAN channel definitions and function prototypes  */
#include "CAN.h"

/* Host command module */
#include "Host.h" 

/* CPU definitions */
#include "cpu.h"



/* Auxiliary variables */
byte counter;
byte ext_flag; 

Fr_bd_status_register bd_status_register;

#define BTN_DEBOUNCE_STANDBY 64

#define VBAT_PWM_LOW 10000
#define VBAT_PWM_HIGH 14096
#define PWM_MIN 0x0000
#define PWM_MAX 0x7FFF
#define PWM_MID 0x0FFF

/*******************************************************************************/
/* Real Time Interrupt service routine                                         */
/*******************************************************************************/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt RTI_Isr(void)
{     
    word temp;
    word i;
    CRGFLG_RTIF = 1;    /* Clear the real time interrupt flag */ 
    XGSWT= 0x0101;      /* Software trigger to the XGATE */   
    
    /* Store new Battery voltage value to FlexRay buffer */
    tx_data[FR_TX_BUFFER_1][FR_SIGNAL_VOLTAGE] = voltage_VBAT;
    
    /*/ Update LED1 Intensity according to VBAT voltage */
    PMFENCA_LDOKA = 0;
    if (voltage_VBAT < VBAT_PWM_HIGH)
    {
      if (voltage_VBAT > VBAT_PWM_LOW) 
      {
        PMFVAL0 = (VBAT_PWM_HIGH - voltage_VBAT) * 8;
      }
      else PMFVAL0 = PWM_MAX;
    } else
    {
      PMFVAL0 = PWM_MIN;
    }    
    PMFENCA_LDOKA = 1;

    /* if IRQ button is released clear counter, LED2 = Full Intensity */
    /* Update FlexRay buffer with actual IRQ button state             */
    if (BTN_IRQ == 1) 
    {

      PMFENCA_LDOKA = 0;
      PMFVAL1 = PWM_MIN; 
      PMFENCA_LDOKA = 1;

      counter = 0; 
      tx_data[FR_TX_BUFFER_1][FR_SIGNAL_GENERAL] &= ~FR_SIGNAL_GENERAL_BTN_IRQ_DOWN;
    } else 
    { /* if IRQ button is pressed incremment counter               */
      /* While button is pressed keep decreasing LED2 intensity    */
      /* Update FlexRay buffer with actual IRQ button state        */
      PMFENCA_LDOKA = 0;
      
      PMFVAL1 += 512;
      if(PMFVAL1 >= PWM_MAX) 
      {
        PMFVAL1 = PWM_MAX;
      }
      PMFENCA_LDOKA = 1;
      
      tx_data[FR_TX_BUFFER_1][FR_SIGNAL_GENERAL] |= FR_SIGNAL_GENERAL_BTN_IRQ_DOWN;
      if (counter < BTN_DEBOUNCE_STANDBY) counter++;
    }

    /* When counter overflow, update FlexRay transmit buffer with GO_TO_STANDBY signal */
    if (counter == BTN_DEBOUNCE_STANDBY) 
    {
      counter++;
      tx_data[FR_TX_BUFFER_1][FR_SIGNAL_MODES] = FR_SIGNAL_MODES_BD_GO_TO_STANDBY;
    }
    
    /* Update LED3 according to received signal FR_SIGNAL_GENERAL_BTN_IRQ_DOWN */
    temp = 0;
    for (i=0;i<5;i++)
      temp |= (rx_data[i][FR_SIGNAL_GENERAL] & FR_SIGNAL_GENERAL_BTN_IRQ_DOWN);
    LED3 = (temp == 0) ? 1 : 0;
    
    /* Update LED4 - LED8 according to receive buffer status */
    if (LEDS & LED4_MASK) LED_TOGGLE(LED4);
    if (LEDS & LED5_MASK) LED_TOGGLE(LED5);
    if (LEDS & LED6_MASK) LED_TOGGLE(LED6);
    if (LEDS & LED7_MASK) LED_TOGGLE(LED7);
    if (LEDS & LED8_MASK) LED_TOGGLE(LED8); 
    LEDS = 0;   
  
}
#pragma CODE_SEG RTI_ISR_CODE


/*******************************************************************************/
/* External IRQ Interrupt Service Routine                                      */
/*******************************************************************************/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt External_IRQ_Isr(void)
{ 
  // API OFF                
  VREGAPICL_APIFE = 0;
  // Exit the STOP mode (in main loop)
  Enter_STOP_MODE = FALSE;
}
#pragma CODE_SEG EXTERNAL_IRQ_ISR_CODE


/*******************************************************************************/
/* FlexRay Transmission Message Buffer Interrupt Service Routine               */
/*******************************************************************************/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt FLEXRAY_TX_Isr(void)
{   
    Fr_interrupt_handler(); 
}
#pragma CODE_SEG FLEXRAY_TX_ISR_CODE 

/*******************************************************************************/
/* FlexRay Reception Message Buffer Interrupt Service Routine                  */
/*******************************************************************************/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt FLEXRAY_RX_Isr(void)
{          
    Fr_interrupt_handler();  
}
#pragma CODE_SEG FLEXRAY_RX_ISR_CODE

/*******************************************************************************/
/* FlexRay Remote WakeUp Interrupt Service Routine                             */
/*******************************************************************************/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt FLEXRAY_Wakeup_Isr(void)
{          
    Fr_interrupt_handler();  
}
#pragma CODE_SEG FLEXRAY_WAKEUP_ISR_CODE

/*******************************************************************************/
/* FlexRay Protocol Interrupt Service Routine                                  */
/*******************************************************************************/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt FLEXRAY_Protocol_Isr(void)
{      
    Fr_interrupt_handler(); 
}
#pragma CODE_SEG FLEXRAY_PROTOCOL_ISR_CODE




/*******************************************************************************/
/* Autonomous Periodical Interrupt Service Routine                             */
/*******************************************************************************/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt API_Isr(void)
{      
  // Clear the interrupt flag 
  VREGAPICL_APIF = 1;
  
  // Indicate the pressent STOP mode by LED8  
  LED_TOGGLE(LED8);
  // If Remote Wakeup detected, exit STOP mode 
  if ((FR_ERRN_A == 0) || (FR_ERRN_B == 0)) 
  {
    // API OFF                
    VREGAPICL_APIFE = 0;
    Enter_STOP_MODE = FALSE;
  }            
}
#pragma CODE_SEG API_ISR_CODE





            
