/*********************************************************/
/* ON Semiconductor                                      */
/* NCV7383 Evaluation KIT                                */
/*                                                       */
/* CAN_HOST.C                                            */
/* Host command processor                                */
/*                                                       */
/* Originally created by: Jozef Polak                    */
/* Modified by: Filip Brtan                              */
/* Date: 30.07.2012                                      */
/*********************************************************/

// NOTES:
// - Using a function table for command processing is quite neat.
//   Commands in the same group usually have a lot in common so they can be processed in one function with common local variables, etc.
// - There is a limitation to function pointers: Functions cannot have more parameters than will fit in registers.
//   That is why I use the global variables for the command data.

// REFERENCES:
// [1] Keil Software, Inc. Function Pointers in C51. Application Note 129.
//     http://www.keil.com/appnotes/files/apnt_129.pdf.

#include <stddef.h> 
/** S12X derivative information */ 
#include "mc9s12xf512.h"  
#include "typedefs.h"
#include "GPIO_macros.h"
#include "CAN.h"
#include "CAN_Host.h"

/** Standard and driver types */
#include "Fr_UNIFIED_types.h"  

/** UNIFIED driver implementation */         
#include "Fr_UNIFIED.h"        
         
/** Configuration data for the FlexRay node */
#include "Fr_UNIFIED_cfg.h"

/** FlexRay CC function prototypes */
#include "FlexRay_CC.h"

/** FlexRay Bus Driver definitions*/
#include "FlexRay_BD.h"

#include "ADC.h"

#include "Interrupts.h"

#pragma DATA_SEG CAN_HOST_DATA
#pragma CODE_SEG CAN_HOST_CODE

/***********************************/
/* Communication Packet Definition */
/***********************************/

/*** Command Group ***/
#define CMG_CAN_RESERVED                   0x00
#define CMG_CAN_GENERAL                    0x01



/*** Commands ***/

// Group: GENERAL
#define CMD_CAN_GENERAL_READ_SIGNATURE     0x81
#define CMD_CAN_GENERAL_READ_NODE_ADDRESS  0x82


/*** Command Processing Functions ***/
static void CAN_hostcomm_command_general    (byte command);


// NOTE:
// I wanted to use the typedef-ed function types to directly define the functions:
//   static THOST_COMMANDGROUP hostcomm_command_spi;
// instead of the direct declaration:
//   static void hostcomm_command_spi (byte command);
// Doing so causes a number mysterious problems:
// - It is not possible to mix the typedef-ed and the direct declaration. The compiler creates different symbols for them (one has "_", one does not)
//   and the linker then isn't able to match them (unresolved external).
// - The typedef-ed declaration does weird things to local vairables of such a function. 
//   By default, they are in "x constant" mspace (nobody seems to know what that is). If declared explicitly as data, they are compiled as static variables.
// These are the reasons why I abandoned this approach.

/* Table of Command Processing Function Pointers */
// NOTE: The table must be stored in CODE space! This ensures that the compiler/linker build correct overlay tree, see [1]. 
CAN_THOST_COMMANDGROUP *can_host_command [] = {
  NULL,
  CAN_hostcomm_command_general
};

/* Data for the Command Processing */
TBUFFER_DATA * can_host_prxdata;      // received command-specific data (see documentation) for the received command
TBUFFER_DATA * can_host_ptxdata;      // command-specific data (see documentation) for the response
byte           can_host_rxlength;     // length of received command-specific data


/**********************/
/* Command Processing */
/**********************/


/* Group: GENERAL */
static void CAN_hostcomm_command_general (byte command) {
  switch (command) {
    case CMD_CAN_GENERAL_READ_SIGNATURE :
      *can_host_ptxdata++ = 'O';
      *can_host_ptxdata++ = 'N';
      *can_host_ptxdata++ = 'S';
      *can_host_ptxdata++ = 'E';
      *can_host_ptxdata++ = 'M';
      *can_host_ptxdata++ = 'I';
      *can_host_ptxdata++ = 'N';
      *can_host_ptxdata++ = 'C';
      *can_host_ptxdata++ = 'V';
      *can_host_ptxdata++ = '7';
      *can_host_ptxdata++ = '3';
      *can_host_ptxdata++ = '8';
      *can_host_ptxdata++ = '3';
      *can_host_ptxdata++ = 'A';
      *can_host_ptxdata++ = 'P';
      *can_host_ptxdata++ = 'P';
      *can_host_ptxdata++ = 'V';
      *can_host_ptxdata++ = '1';                
      break;

    case CMD_CAN_GENERAL_READ_NODE_ADDRESS:
      *can_host_ptxdata++ = SW_ADDRESS;           
      break;
      
    default: break;
  }
}


#pragma CODE_SEG DEFAULT



     









