/******************************************************************************
*
* Copyright 2006-2015 Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
*
******************************************************************************/
#include <string.h>

#include "freemaster.h"
#include "freemaster_example.h"
#include "adConv1.h"
#include "ets.h"
#include "pin_mux.h"

/****************************************************************************
 *
 * Test variables, will be displayed in the FreeMASTER application
 *   
 */
unsigned char DemoOnline;
volatile unsigned char  DemoVersion;
volatile unsigned long  PortA;
volatile unsigned long  PortB;
volatile unsigned long  PortC;
volatile unsigned long  PortD;
volatile unsigned long  PortE;
volatile unsigned char  var8;
volatile unsigned char  var8rw;
volatile unsigned char  var8inc = 1;
volatile unsigned short var16;
volatile unsigned short var16rw;
const unsigned short var16rwconst = 0x55AA;
volatile unsigned short var16inc = 1;
volatile unsigned long  var32;
volatile unsigned long  var32rw;
volatile unsigned long  var32inc = 100;

volatile unsigned char  frac8;
volatile unsigned short frac16;
volatile unsigned long  frac32;

volatile unsigned char  ufrac8;
volatile unsigned short ufrac16;
volatile unsigned long  ufrac32;

volatile unsigned long*  PortAptr = &PortA;
volatile unsigned long*  PortBptr = &PortB;
volatile unsigned long*  PortCptr = &PortC;
volatile unsigned long*  PortDptr = &PortD;
volatile unsigned long*  PortEptr = &PortE;
volatile unsigned char*  var8ptr = &var8;
volatile unsigned short* var16ptr = &var16;
volatile unsigned long*  var32ptr = &var32;

#define ARR_SIZE 10
volatile unsigned short arr_size = ARR_SIZE;
volatile unsigned char  arr8[ARR_SIZE];
volatile unsigned short arr16[ARR_SIZE];
volatile unsigned long  arr32[ARR_SIZE];

#if FMSTR_DEMO_SUPPORT_I64
volatile unsigned long long var64;
volatile unsigned long long var64rw;
volatile unsigned long long var64inc = 10000;
volatile unsigned long long arr64[ARR_SIZE];
volatile unsigned long long frac64;
volatile unsigned long long ufrac64;
#endif

#if FMSTR_DEMO_SUPPORT_FLT
volatile float varFLT;
volatile float varFLTrw;
volatile float varFLTinc = 1.0;
volatile float arrFLT[ARR_SIZE];
#endif

#if FMSTR_DEMO_SUPPORT_DBL
volatile double varDBL;
volatile double varDBLrw;
volatile double varDBLinc = 1.0;
volatile double arrDBL[ARR_SIZE];
#endif

volatile unsigned char  nAppCmdCounter;
volatile uint16_t Potentiometer; /* Variable of the Potentiometer value */
volatile unsigned short* Potentiometerptr = &Potentiometer;

#define ADC_INSTANCE        0UL
#define ADC_CHN             3U
#define ADC_NR_SAMPLES      72

extern uint8_t electrodeTouchQualifiedThrBased[NUMBER_OF_ELECTRODES];

/****************************************************************************
 *
 * Test structure types - demonstrates the "TSA" feature thanks to which the
 * FreeMASTER is able to load a variable and type information directly from
 * the embedded application.
 *
 */

typedef struct {

  unsigned short  aa;
  unsigned long   bb[2];
  unsigned short  cc;
  unsigned long   dd[3];
  unsigned char   ee;
  unsigned char   ff[5];
} INNER_STRUCT;

typedef struct {

  unsigned short  a;
  unsigned long   b;
  INNER_STRUCT    inA[4];
  INNER_STRUCT    inB;
} OUTER_STRUCT;

/* Structure type information will be available in the FreeMASTER application 
  (TSA demonstration) */
volatile OUTER_STRUCT so1, so2;
volatile INNER_STRUCT si1, si2;

/****************************************************************************
 * The following lines declare variables which hold correct size and offset 
 * values to be compared with the ones retrieved from TSA or ELF symbols.
 * The demo application does not make use of any of these variables, but 
 * they may be used for advanced testing of FreeMASTER address resolution logic.
 */

#define DEFINE_SYM_INFO(var) \
  volatile void* var##_addr = &var; \
  unsigned long var##_size = (unsigned long)sizeof(var)

DEFINE_SYM_INFO(so1);
DEFINE_SYM_INFO(so2);
DEFINE_SYM_INFO(si1);
DEFINE_SYM_INFO(si2);
DEFINE_SYM_INFO(PortA);
DEFINE_SYM_INFO(PortB);
DEFINE_SYM_INFO(PortC);
DEFINE_SYM_INFO(PortD);
DEFINE_SYM_INFO(PortE);
DEFINE_SYM_INFO(var8);
DEFINE_SYM_INFO(var16);
DEFINE_SYM_INFO(var32);
DEFINE_SYM_INFO(arr8);
DEFINE_SYM_INFO(electrodeTouchQualifiedThrBased);
DEFINE_SYM_INFO(arr16);
DEFINE_SYM_INFO(arr32);

#if FMSTR_DEMO_SUPPORT_I64
DEFINE_SYM_INFO(var64);
DEFINE_SYM_INFO(arr64);
#endif
#if FMSTR_DEMO_SUPPORT_FLT
DEFINE_SYM_INFO(varFLT);
#endif
#if FMSTR_DEMO_SUPPORT_DBL
DEFINE_SYM_INFO(varDBL);
#endif

#define DEFINE_MEMB_INFO(type, memb) \
  volatile void* type##_##memb##_offset = &(((type*)0)->memb); \
  unsigned long type##_##memb##_size = (unsigned long)sizeof(((type*)0)->memb)

DEFINE_MEMB_INFO(INNER_STRUCT, aa);
DEFINE_MEMB_INFO(INNER_STRUCT, bb);
DEFINE_MEMB_INFO(INNER_STRUCT, cc);
DEFINE_MEMB_INFO(INNER_STRUCT, dd);
DEFINE_MEMB_INFO(INNER_STRUCT, ee);
DEFINE_MEMB_INFO(INNER_STRUCT, ff);

DEFINE_MEMB_INFO(OUTER_STRUCT, a);
DEFINE_MEMB_INFO(OUTER_STRUCT, b);
DEFINE_MEMB_INFO(OUTER_STRUCT, inA);
DEFINE_MEMB_INFO(OUTER_STRUCT, inB);

/****************************************************************************
 *
 * The HCS12X platform supports small, banked and large memory models. 
 * The following variables are used to test access using paged and banked 
 * addresses specified in TSA table or ELF file.
 */
 
#if defined(__HCS12X__) && defined(__LARGE__)
/* Testing variable in paged RAM */
#pragma DATA_SEG PAGED_RAM
Word paged_var16 = 100;
Word paged_var16inc = 0;
#pragma DATA_SEG DEFAULT

/* these two sections are defined in PRM file to test this driver */

#pragma DATA_SEG FMTEST_RAM_FB
Word ramfb_var16;
#pragma DATA_SEG DEFAULT

#pragma CONST_SEG FMTEST_ROM_FB
const Word romfb_var16 = 2;
#pragma CONST_SEG DEFAULT
#endif

/****************************************************************************
 *
 * With TSA enabled, the user describes the global and static variables using
 * so-called TSA tables. There can be any number of tables defined in
 * the project files. Each table does have the identifier which should be
 * unique across the project.
 *
 * Note that you can declare variables as Read-Only or Read-Write.
 * The FreeMASTER driver denies any write access to the Read-Only variables
 * when TSA_SAFETY is enabled.
 */

FMSTR_TSA_TABLE_BEGIN(first_table)

    FMSTR_TSA_RW_VAR(DemoOnline, FMSTR_TSA_UINT8)
    FMSTR_TSA_RW_VAR(DemoVersion, FMSTR_TSA_UINT8)
    FMSTR_TSA_RW_VAR(PortA,    FMSTR_TSA_UINT32)
    FMSTR_TSA_RW_VAR(PortB,    FMSTR_TSA_UINT32)
    FMSTR_TSA_RW_VAR(PortC,    FMSTR_TSA_UINT32)
    FMSTR_TSA_RW_VAR(PortD,    FMSTR_TSA_UINT32)
    FMSTR_TSA_RW_VAR(PortE,    FMSTR_TSA_UINT32)
    FMSTR_TSA_RO_VAR(Potentiometer, FMSTR_TSA_UINT16)
    FMSTR_TSA_RO_VAR(electrodeTouchQualifiedThrBased, FMSTR_TSA_UINT8)

    FMSTR_TSA_RO_VAR(var8,     FMSTR_TSA_UINT8)
    FMSTR_TSA_RW_VAR(arr8,     FMSTR_TSA_UINT8)
    FMSTR_TSA_RW_VAR(var8rw,   FMSTR_TSA_UINT8)
    FMSTR_TSA_RW_VAR(var8inc,  FMSTR_TSA_UINT8)

    FMSTR_TSA_RO_VAR(var16,    FMSTR_TSA_UINT16)
    FMSTR_TSA_RW_VAR(arr16,    FMSTR_TSA_UINT16)
    FMSTR_TSA_RW_VAR(var16rw,  FMSTR_TSA_UINT16)
    FMSTR_TSA_RO_VAR(var16rwconst, FMSTR_TSA_UINT16)
    FMSTR_TSA_RW_VAR(var16inc, FMSTR_TSA_UINT16)

    FMSTR_TSA_RO_VAR(var32,    FMSTR_TSA_UINT32)
    FMSTR_TSA_RW_VAR(arr32,    FMSTR_TSA_UINT32)
    FMSTR_TSA_RW_VAR(var32rw,  FMSTR_TSA_UINT32)
    FMSTR_TSA_RW_VAR(var32inc, FMSTR_TSA_UINT32)

    FMSTR_TSA_RO_VAR(PortAptr,  FMSTR_TSA_POINTER)
    FMSTR_TSA_RO_VAR(PortBptr,  FMSTR_TSA_POINTER)
    FMSTR_TSA_RO_VAR(PortCptr,  FMSTR_TSA_POINTER)
    FMSTR_TSA_RO_VAR(PortDptr,  FMSTR_TSA_POINTER)
    FMSTR_TSA_RO_VAR(PortEptr,  FMSTR_TSA_POINTER)
    FMSTR_TSA_RO_VAR(var8ptr,   FMSTR_TSA_POINTER)
    FMSTR_TSA_RO_VAR(Potentiometerptr, FMSTR_TSA_POINTER)
    FMSTR_TSA_RO_VAR(var16ptr,  FMSTR_TSA_POINTER)
    FMSTR_TSA_RO_VAR(var32ptr,  FMSTR_TSA_POINTER)

    FMSTR_TSA_RW_VAR(frac8,  FMSTR_TSA_FRAC_Q(0,7))
    FMSTR_TSA_RW_VAR(frac16, FMSTR_TSA_FRAC_Q(3,12))
    FMSTR_TSA_RW_VAR(frac32, FMSTR_TSA_FRAC_Q(12,19))

    FMSTR_TSA_RW_VAR(ufrac8,  FMSTR_TSA_UFRAC_UQ(1,7))
    FMSTR_TSA_RW_VAR(ufrac16, FMSTR_TSA_UFRAC_UQ(4,12))
    FMSTR_TSA_RW_VAR(ufrac32, FMSTR_TSA_UFRAC_UQ(13,19))

#if FMSTR_DEMO_SUPPORT_I64
    FMSTR_TSA_RO_VAR(var64,    FMSTR_TSA_UINT64)
    FMSTR_TSA_RW_VAR(arr64,    FMSTR_TSA_UINT64)
    FMSTR_TSA_RW_VAR(var64rw,  FMSTR_TSA_UINT64)
    FMSTR_TSA_RW_VAR(var64inc, FMSTR_TSA_UINT64)
    FMSTR_TSA_RW_VAR(frac64,   FMSTR_TSA_FRAC_Q(8,55))
    FMSTR_TSA_RW_VAR(ufrac64,  FMSTR_TSA_UFRAC_UQ(9,55))
#endif

#if FMSTR_DEMO_SUPPORT_FLT
    FMSTR_TSA_RO_VAR(varFLT,    FMSTR_TSA_FLOAT)
    FMSTR_TSA_RW_VAR(varFLTrw,  FMSTR_TSA_FLOAT)
    FMSTR_TSA_RW_VAR(arrFLT,    FMSTR_TSA_FLOAT)
    FMSTR_TSA_RW_VAR(varFLTinc, FMSTR_TSA_FLOAT)
#endif

#if FMSTR_DEMO_SUPPORT_DBL
    FMSTR_TSA_RO_VAR(varDBL,    FMSTR_TSA_DOUBLE)
    FMSTR_TSA_RW_VAR(arrDBL,    FMSTR_TSA_DOUBLE)
    FMSTR_TSA_RW_VAR(varDBLrw,  FMSTR_TSA_DOUBLE)
    FMSTR_TSA_RW_VAR(varDBLinc, FMSTR_TSA_DOUBLE)
#endif

    FMSTR_TSA_RO_VAR(arr_size, FMSTR_TSA_UINT16)

    FMSTR_TSA_RO_VAR(nAppCmdCounter, FMSTR_TSA_UINT8)

    FMSTR_TSA_RW_VAR(so1,      FMSTR_TSA_USERTYPE(OUTER_STRUCT))
    FMSTR_TSA_RW_VAR(si1,      FMSTR_TSA_USERTYPE(INNER_STRUCT))

    FMSTR_TSA_STRUCT(OUTER_STRUCT)
    FMSTR_TSA_MEMBER(OUTER_STRUCT, a,   FMSTR_TSA_UINT16)
    FMSTR_TSA_MEMBER(OUTER_STRUCT, b,   FMSTR_TSA_UINT32)
    FMSTR_TSA_MEMBER(OUTER_STRUCT, inA, FMSTR_TSA_USERTYPE(INNER_STRUCT))
    FMSTR_TSA_MEMBER(OUTER_STRUCT, inB, FMSTR_TSA_USERTYPE(INNER_STRUCT))

    FMSTR_TSA_STRUCT(INNER_STRUCT)
    FMSTR_TSA_MEMBER(INNER_STRUCT, aa, FMSTR_TSA_UINT16)
    FMSTR_TSA_MEMBER(INNER_STRUCT, bb, FMSTR_TSA_UINT32)
    FMSTR_TSA_MEMBER(INNER_STRUCT, cc, FMSTR_TSA_SINT16)
    FMSTR_TSA_MEMBER(INNER_STRUCT, dd, FMSTR_TSA_SINT32)
    FMSTR_TSA_MEMBER(INNER_STRUCT, ee, FMSTR_TSA_UINT8)
    FMSTR_TSA_MEMBER(INNER_STRUCT, ff, FMSTR_TSA_SINT8)

#if defined(__HCS12X__) && defined(__LARGE__)
    FMSTR_TSA_RW_VAR(paged_var16, FMSTR_TSA_UINT16)
    FMSTR_TSA_RW_VAR(paged_var16inc, FMSTR_TSA_UINT16)
    FMSTR_TSA_RW_VAR(ramfb_var16, FMSTR_TSA_UINT16)
    FMSTR_TSA_RW_VAR(romfb_var16, FMSTR_TSA_UINT16)
#endif

FMSTR_TSA_TABLE_END()

/*
 * This is an example of another TSA table. Typically, you put one table
 * to each .c file where your global or static variables are instantiated.
 */

FMSTR_TSA_TABLE_BEGIN(next_table)
    FMSTR_TSA_RO_VAR(so2, FMSTR_TSA_USERTYPE(OUTER_STRUCT))
    FMSTR_TSA_RO_VAR(si2, FMSTR_TSA_USERTYPE(INNER_STRUCT))
FMSTR_TSA_TABLE_END()

/****************************************************************************
 *
 * Another TSA table with specific information about in-memory files,
 * project files and related web-links. This feature requires FreeMASTER 
 * version 2.0 running on the PC Host to make use of this "Active Content" 
 *  
 */
FMSTR_TSA_TABLE_BEGIN(files_and_links)
    /* Project file stored online */
    FMSTR_TSA_PROJECT("{autorun}","http://www.nxp.com/assets/downloads/data/en/application-software/S32K142EVB_OOBE.pmpx")
FMSTR_TSA_TABLE_END()

/* RAM buffer for runtime definition of the TSA table
 * up to 5 variables will be enabled to register dynamically */
static unsigned char tsa_dyn_table_storage[5*sizeof(FMSTR_TSA_ENTRY)]; 

/****************************************************************************
 *
 * This list describes all TSA tables which should be exported to the
 * FreeMASTER application.
 *  
 */
 
FMSTR_TSA_TABLE_LIST_BEGIN()
    FMSTR_TSA_TABLE(first_table)
    FMSTR_TSA_TABLE(next_table)
    FMSTR_TSA_TABLE(files_and_links)
FMSTR_TSA_TABLE_LIST_END()

/****************************************************************************
 *
 * This function is registered as an application command handler (see the
 * initialization code below. It gets automatically invoked when the
 * FreeMASTER PC Host tool sends appropriate application command.
 *  
 */

static FMSTR_APPCMD_RESULT my_appcmd_handler(FMSTR_APPCMD_CODE nAppcmd, FMSTR_APPCMD_PDATA pData, FMSTR_SIZE nDataLen)
{
    /* The return value is used as the application command result code */
    return 0x10;
}

/* A tiny strlen for our own purposes */
static FMSTR_PIPE_SIZE my_strlen(char* psz)
{
    FMSTR_PIPE_SIZE len = 0;
    while(*psz++)
        len++;
    return len;
}

/****************************************************************************
 *
 * This function is registered as a pipe communication handler (see the
 * initialization code below. It gets automatically invoked when the
 * FreeMASTER PC Host tool services the open pipe. This handler is called
 * any time the pipe receives the data or when PC probes if pipe has anything
 * to transmit.
 *  
 */

static void my_pipe_handler(FMSTR_HPIPE hpipe)
{
    static const char* names[10] =
    {
            "zero", "one", "two", "three", "four",
            "five", "six", "seven", "eight", "nine"
    };

    static char buff[4];
    char* n;
    char c;

    /* This simple handler translates the digits into number names.
     * Other characters are just echoed back.  */
    while(FMSTR_PipeRead(hpipe, (FMSTR_ADDR)buff, 1, 0))
    {
        c = buff[0];

        if(c >= '0' && c <= '9')
        {
            /* A tiny strlen */
            n = (char*) names[c-'0'];
            FMSTR_PipeWrite(hpipe, (FMSTR_ADDR)n, my_strlen(n), 0);
        }
        else
        {
            /* Echo */
            FMSTR_PipeWrite(hpipe, (FMSTR_ADDR)buff, 1, 0);
        }
    }
}

static void my_pipe_math(FMSTR_HPIPE hpipe)
{
    unsigned long result;
    unsigned long buff[2];

    /* We want to receive both operands at once (we do not want to do any caching here).
     * The 'granularity' argument can be used for this purpose. */
    while(FMSTR_PipeRead(hpipe, (FMSTR_ADDR)&buff, 8, 8) == 8)
    {
        result = buff[0]*buff[1];
        /* To be sure the result was sent, we should check also
         * the return value of the PipeWrite.  In this simple case
         * we just believe... */
        FMSTR_PipeWrite(hpipe, (FMSTR_ADDR)&result, 4, 4);
    }
}

/* Pipe buffers and welcome strings */

static unsigned char pipe1_rxb[10];
static unsigned char pipe1_txb[100];
static unsigned char pipe2_rxb[10];
static unsigned char pipe2_txb[100];
static unsigned char pipe3_rxb[8];
static unsigned char pipe3_txb[4];

static char* sz_pipe1_hello = "Hello from embedded application! Pipe 1. ";
static char* sz_pipe2_hello = "Kind regards from from embedded application! Pipe 2. ";
static char* sz_pipe_other = "Send me numbers 0-5 and will echo it back to you on the same pipe ";


/****************************************************************************
 * General initialization of FreeMASTER example */

void FMSTR_Example_Init(void)
{
    FMSTR_HPIPE hpipe;
    int i;

    DemoOnline = 0;
    DemoVersion = 0x01; /* OOBE version v1.0 */
    PortA = 0xFFFFFFFF;
    PortB = 0xFFFFFFFF;
    PortC = 0xFFFFFFFF;
    PortD = 0xFFFFFFFF;
    PortE = 0xFFFFFFFF;
    var8 = 0;
    var8rw = 0;
    var8inc = 1;
    var16 = 0;
    var16rw = 0;
    var16inc = 1;
    var32 = 0;
    var32rw = 0;
    var32inc = 100;

    frac8 = 0;
    frac16 = 0;
    frac32 = 0;
    ufrac8 = 0;
    ufrac16 = 0;
    ufrac32 = 0;

#if FMSTR_DEMO_SUPPORT_I64
    var64 = 0;
    var64rw = 0;
    var64inc = 10000;
    frac64 = 0;
    ufrac64 = 0;
#endif

#if FMSTR_DEMO_SUPPORT_FLT
    varFLT = 0;
    varFLTrw = 0;
    varFLTinc = 1.0;
#endif

#if FMSTR_DEMO_SUPPORT_DBL
    varDBL = 0;
    varDBLrw = 0;
    varDBLinc = 1.0;
#endif

    arr_size = ARR_SIZE;

    so1.a = 1;
    so2.a = 2;
    si1.aa = 1;
    si2.aa = 2;

    for(i=0; i<ARR_SIZE; i++)
    {
       arr8[i] = (unsigned char) i;
       arr16[i] = (unsigned short) i*10;
       arr32[i] = (unsigned long) i*100;
#if FMSTR_DEMO_SUPPORT_I64
       arr64[i] = (unsigned long long) i*1000;
#endif
#if FMSTR_DEMO_SUPPORT_FLT
       arrFLT[i] = ((float)i)/10;
#endif
#if FMSTR_DEMO_SUPPORT_DBL
       arrDBL[i] = ((double)i)/10;
#endif
    }

    /* FreeMASTER initialization */
    FMSTR_Init();

    /* Registering the App.Command handler */
    FMSTR_RegisterAppCmdCall(10, my_appcmd_handler);

    /* Example of dynamic TSA table definition in runtime */
    FMSTR_SetUpTsaBuff((FMSTR_ADDR)tsa_dyn_table_storage, sizeof(tsa_dyn_table_storage));
    FMSTR_TsaAddVar(FMSTR_TSATBL_STRPTR_CAST("var16_mirror"), FMSTR_TSATBL_STRPTR_CAST(FMSTR_TSA_UINT16), FMSTR_TSATBL_VOIDPTR_CAST(&var16), sizeof(var16), FMSTR_TSA_INFO_RO_VAR);
    FMSTR_TsaAddVar(FMSTR_TSATBL_STRPTR_CAST("var32_mirror"), FMSTR_TSATBL_STRPTR_CAST(FMSTR_TSA_UINT32), FMSTR_TSATBL_VOIDPTR_CAST(&var32), sizeof(var32), FMSTR_TSA_INFO_RO_VAR);

    /* Open pipes */
    hpipe = FMSTR_PipeOpen(1, my_pipe_handler,
        (FMSTR_ADDR)pipe1_rxb, sizeof(pipe1_rxb),
        (FMSTR_ADDR)pipe1_txb, sizeof(pipe1_txb));

    if(hpipe)
    {
        FMSTR_PipeWrite(hpipe, (FMSTR_ADDR)sz_pipe1_hello, my_strlen(sz_pipe1_hello), 0);
        FMSTR_PipeWrite(hpipe, (FMSTR_ADDR)sz_pipe_other, my_strlen(sz_pipe_other), 0);
    }

    hpipe = FMSTR_PipeOpen(2, my_pipe_handler,
        (FMSTR_ADDR)pipe2_rxb, sizeof(pipe2_rxb),
        (FMSTR_ADDR)pipe2_txb, sizeof(pipe2_txb));

    if(hpipe)
    {
        FMSTR_PipeWrite(hpipe, (FMSTR_ADDR)sz_pipe2_hello, my_strlen(sz_pipe2_hello), 0);
        FMSTR_PipeWrite(hpipe, (FMSTR_ADDR)sz_pipe_other, my_strlen(sz_pipe_other), 0);
    }

    /* Third pipe is a binary one at port 33 */
    FMSTR_PipeOpen(33, my_pipe_math,
        (FMSTR_ADDR)pipe3_rxb, sizeof(pipe3_rxb),
        (FMSTR_ADDR)pipe3_txb, sizeof(pipe3_txb));
}

/****************************************************************************
 *
 * Poll function of the FreeMASTER example, called periodically from the
 * main application 
 * 
 */

void FMSTR_Example_Poll(void)
{
    static unsigned short div;
    unsigned short nAppCmdCode;

    /* Scope variables, increment once a while */
    if(++div > 20)
    {
        var8 += var8inc;
        var16 += var16inc;
        var32 += var32inc;
        
#if FMSTR_DEMO_SUPPORT_I64
        var64 += var64inc;
#endif
#if FMSTR_DEMO_SUPPORT_FLT
        varFLT = varFLT + varFLTinc;
#endif
#if FMSTR_DEMO_SUPPORT_DBL
        varDBL = varDBL + varDBLinc;
#endif

        div = 0;
    }

#if defined(__HCS12X__) && defined(__LARGE__)
    paged_var16 += paged_var16inc;
    ramfb_var16 += romfb_var16;
#endif

    /* The application commands not registered with callback handlers
       can be detected and processed using the API calls below */

    /* First, check if a new command has been received */
    nAppCmdCode = FMSTR_GetAppCmd();

    /* When a new command arrives, the nAppCmdCode contains the application
       command code. In other case, the "NOCMD" special value is returned */
    if (nAppCmdCode != FMSTR_APPCMDRESULT_NOCMD)
    {
        nAppCmdCounter++;

        /* Each command may have different processing and different
           result code. The command processing is finished by
           calling FMSTR_AppCmdAck() with the result code value */
        switch(nAppCmdCode)
        {
            case 1: FMSTR_AppCmdAck(1); break;
            case 2: FMSTR_AppCmdAck(0xcd); break;
            default: FMSTR_AppCmdAck(0); break;
        }
    }
    /* S32K118EVB-Q064 board - Output Pins Control */
    if(PortA&0x00000004){PINS_DRV_SetPins(PTA,1<<2);}else{PINS_DRV_ClearPins (PTA,1<<2);} /* J1 connector, pin 01 */
    if(PortA&0x00000008){PINS_DRV_SetPins(PTA,1<<3);}else{PINS_DRV_ClearPins (PTA,1<<3);} /* J1 connector, pin 03 */
    if(PortA&0x00002000){PINS_DRV_SetPins(PTA,1<<13);}else{PINS_DRV_ClearPins(PTA,1<<13);} /* J1 connector, pin 05 */
    if(PortA&0x00001000){PINS_DRV_SetPins(PTA,1<<12);}else{PINS_DRV_ClearPins(PTA,1<<12);} /* J1 connector, pin 07 */
    if(PortD&0x00000001){PINS_DRV_SetPins(PTD,1<<0);}else{PINS_DRV_ClearPins (PTD,1<<0);} /* J1 connector, pin 09 */
    if(PortD&0x00000002){PINS_DRV_SetPins(PTD,1<<1);}else{PINS_DRV_ClearPins (PTD,1<<1);} /* J1 connector, pin 11 */
    if(PortD&0x00000004){PINS_DRV_SetPins(PTD,1<<2);}else{PINS_DRV_ClearPins (PTD,1<<2);} /* J1 connector, pin 13 */
    if(PortE&0x00000200){PINS_DRV_SetPins(PTE,1<<9);}else{PINS_DRV_ClearPins (PTE,1<<9);} /* J1 connector, pin 15 */
    if(PortE&0x00000400){PINS_DRV_SetPins(PTE,1<<10);}else{PINS_DRV_ClearPins (PTE,1<<10);} /* J1 connector, pin 02 */
    if(PortE&0x00000800){PINS_DRV_SetPins(PTE,1<<11);}else{PINS_DRV_ClearPins (PTE,1<<11);} /* J1 connector, pin 04 */
    if(PortE&0x00000001){PINS_DRV_SetPins(PTE,1<<0);}else{PINS_DRV_ClearPins(PTE,1<<0);} /* J1 connector, pin 06 */
    if(PortE&0x0000002){PINS_DRV_SetPins(PTE,1<<1);}else{PINS_DRV_ClearPins(PTE,1<<1);} /* J1 connector, pin 08 */
    if(PortE&0x00000040){PINS_DRV_SetPins(PTE,1<<6);}else{PINS_DRV_ClearPins (PTE,1<<6);} /* J1 connector, pin 10 */
    if(PortE&0x00000080){PINS_DRV_SetPins(PTE,1<<7);}else{PINS_DRV_ClearPins (PTE,1<<7);} /* J1 connector, pin 12 */
    if(PortD&0x00000008){PINS_DRV_SetPins(PTD,1<<3);}else{PINS_DRV_ClearPins (PTD,1<<3);} /* J1 connector, pin 14 */
    if(PortD&0x00000020){PINS_DRV_SetPins(PTD,1<<5);}else{PINS_DRV_ClearPins (PTD,1<<5);} /* J1 connector, pin 16 */
    if(PortB&0x00000004){PINS_DRV_SetPins(PTB,1<<2);}else{PINS_DRV_ClearPins(PTB,1<<2);} /* J2 connector, pin 06 */
    if(PortB&0x00000008){PINS_DRV_SetPins(PTB,1<<3);}else{PINS_DRV_ClearPins(PTB,1<<3);} /* J2 connector, pin 05 */
    if(PortB&0x00000010){PINS_DRV_SetPins(PTB,1<<4);}else{PINS_DRV_ClearPins(PTB,1<<4);} /* J2 connector, pin 04 */
    if(PortB&0x00000020){PINS_DRV_SetPins(PTB,1<<5);}else{PINS_DRV_ClearPins(PTB,1<<5);} /* J2 connector, pin 03 */
    if(PortC&0x00000008){PINS_DRV_SetPins(PTC,1<<3);}else{PINS_DRV_ClearPins(PTC,1<<3);} /* J2 connector, pin 02 */
    if(PortC&0x00000004){PINS_DRV_SetPins(PTC,1<<2);}else{PINS_DRV_ClearPins(PTC,1<<2);} /* J2 connector, pin 01 */

    /* S32K118EVB-Q064 board - Input Pins */
    PortA = (PortA & 0xFFFFF7BF) | (PINS_DRV_ReadPins(PTA) & 0x00000840); /* Input pins on PortA */
    PortB = (PortB & 0xFFFFCF3C) | (PINS_DRV_ReadPins(PTB) & 0x000030C3); /* Input pins on PortB */
    PortC = (PortC & 0xFFFC3C3C) | (PINS_DRV_ReadPins(PTC) & 0x0003C3C3); /* Input pins on PortC */
    PortD = (PortD & 0xFFFFFFC7) | (PINS_DRV_ReadPins(PTD) & 0x00000038 ); /* Input pins on PortD */
    PortE = (PortE & 0xFFFFFFCF) | (PINS_DRV_ReadPins(PTE) & 0x00000030); /* Input pins on PortE */

    /* S32K116EVB-Q048 board - LED Control */
    if(PortE&0x00000100){PINS_DRV_ClearPins(PTE,1<<8);}else{PINS_DRV_SetPins(PTE,1<<8);} /* Turn ON/OFF LED BLUE and J4 connector, pin 16*/
    if(PortD&0x00010000){PINS_DRV_ClearPins(PTD,1<<16);}else{PINS_DRV_SetPins(PTD,1<<16);} /* Turn ON/OFF LED RED and J4 connector, pin 14*/
    if(PortD&0x00008000){PINS_DRV_ClearPins(PTD,1<<15);}else{PINS_DRV_SetPins(PTD,1<<15);} /* Turn ON/OFF LED GREEN and J4 connector, pin 12 */


    /* This call should rather be placed in the timer interrupt or anywhere
       where the recorder sampling should occur. */
    FMSTR_Recorder();

    /* The FreeMASTER poll call must be called in the main application loop
       to handle the communication interface and protocol.
       In LONG_INTR FreeMASTER interrupt mode, all the processing is done
       during the communication interrupt routine and the FMSTR_Poll() is
       compiled empty. */

    FMSTR_Poll();
}
