/** ###################################################################
**     THIS BEAN MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT.
**     Filename  : PC_M1.C
**     Project   : voltmeter_led
**     Processor : MC56F8006_48_LQFP
**     Beantype  : PC_Master
**     Version   : Bean 01.036, Driver 01.15, CPU db: 3.00.177
**     Compiler  : Metrowerks DSP C Compiler
**     Date/Time : 11/26/2008, 3:06 PM
**     Abstract  :
**          The PC master software application is a software tool initially created
**          for developers of Motor Control applications but it may be extended to any
**          application development. This tool allows control of an application remotely
**          from a user-friendly graphical environment running on a PC.
**     Settings  :
**          AsynchroSerial                       : Inhr1
**
**          Initialization:
**              Recorder buffer length           : 40
**              Command buffer length            : 4
**              Data buffer size                 : 60
**              Recorder timebase                : 32816
**              Board firmware major number      : 0
**              Board firmware minor number      : 0
**              Device identification string     : PC Master communication !
**     Contents  :
**         pcmasterdrvInit - Word16 PC_M1_pcmasterdrvInit(sPCMasterComm *p_sPCMasterComm);
**         pcmasterdrvIsr  - void PC_M1_pcmasterdrvIsr(void);
**
**     (c) Freescale Semiconductor
**     2004 All Rights Reserved
**
**     (c) Copyright UNIS, a.s. 1997-2008
**     UNIS, a.s.
**     Jundrovska 33
**     624 00 Brno
**     Czech Republic
**     http      : www.processorexpert.com
**     mail      : info@processorexpert.com
** ###################################################################*/

/* MODULE PC_M1. */

#include "PC_M1.h"
#include "bit.h"
#include "arch.h"
#include "port.h"
#include "string.h"

/*--------------------------------------------------
        define which commands will be compiled
  --------------------------------------------------*/
#define PCMDRV_INCLUDE_CMD_SCOPE       /* read scope, setup scope */
#define PCMDRV_INCLUDE_CMD_RECORDER    /* setup recorder, get recorder buffer info,*/
                                       /* start recorder, stop recorder get recorder status */
#define PCMDRV_INCLUDE_CMD_APPCMD      /* call app comd, app comd get status */
#undef PCMDRV_INCLUDE_CMD_GETINFOBRIEF /* enable getinfobrief command   */
                                       /* (default = getinfo command)   */

/* call user application command status */
/* no application command called (board after reset) */
#define PCMDRV_APPCMD_NOCMD         0xFF
/* application command not finished */
#define PCMDRV_APPCMD_RUNNING       0xFE

/* status byte masks (used with 'status' variable) */
/* receiving started, beginning of message already detected ('+') */
#define ST_STARTED                0x0010
/* last received char was '+' */
#define ST_ST_CHAR_REC            0x0020
/* received message is standard command (for length decoding) */
#define ST_STD_CMD                0x0040
/* recorder is running (trigger already detected) */
#define ST_RECRUNNING             0x0100
/* recorder is activated (waiting for trigger) */
#define ST_RECACTIVATED           0x0200
/* read pretrigger samples before waiting for trigger */
#define ST_REC_READ_PRETRIG       0x0400
/* response is being send to PC */
#define ST_SENDING                0x1000
/* last sent char was '+' */
#define ST_ST_SENT                0x2000
/* checksum already added to the message */
#define ST_CS_ADDED               0x4000

#define START         '+'              /* start of message */

/* types of recorder trigger variables */
#define  REC_CHAR_UNSIGNED        0x0002
#define  REC_CHAR_SIGNED          0x0003
#define  REC_WORD_UNSIGNED        0x0004
#define  REC_WORD_SIGNED          0x0005
#define  REC_LONG_UNSIGNED        0x0008
#define  REC_LONG_SIGNED          0x0009

/*--------------------------------------
    Macros
  --------------------------------------*/
/* save data for response to PC */
#define respPrepare(sts, len) {response.status = sts; response.length = len;}

/* application command call status */
static unsigned char pcmdrvAppCmdSts;

/******************************************************************************/
/*                      SCI MACROS - !!! core dependent !!!                   */
/******************************************************************************/
#define INT_DISABLE      0
#define INT_ENABLE       1
#define SCIread(data) \
          {Inhr1_RecvChar(&data);}
#define SCIwrite(data) \
          {Inhr1_SendChar(data);}
#define SCItxEmptyIsr(param) \
        {if (param==INT_ENABLE) \
                      {PC_M1_SCITxEmptyInt = INT_ENABLE;}\
         else if (param==INT_DISABLE) \
                      {PC_M1_SCITxEmptyInt = INT_DISABLE;} }
#define SCIrxFullIsr(param) \
        {if (param==INT_ENABLE) \
                      {PC_M1_SCIRxFullInt = INT_ENABLE;}\
         else if (param==INT_DISABLE) \
                      {PC_M1_SCIRxFullInt = INT_DISABLE;} }

/******************************************************************************/
/*                    MEMORY ACCESS - !!! core dependent !!!                  */
/******************************************************************************/
#define  POINT32_LEN    2
#define  BYTE_LEN       1
#define  WORD_LEN       2
#define  LONG_LEN       4

/********************************************************/
/* PC Master Communication protocol commands data types */
/********************************************************/

/* read variable */
typedef struct{
        unsigned char cmd;
        unsigned char addrByte[4];     /* address of variable */
} sReadVarEx;

/* response structure type (this structure is used to save
the parameters of response to be sent to PC) */
typedef struct{
        unsigned char status;          /* status byte of response */
        unsigned char length;          /* length of the whole response */
} sResponse;

/* standard commands */
/* read memory */
typedef struct{
        unsigned char cmd;
        unsigned char cmdLen;
        unsigned char size;            /* size of data block in bytes */
        unsigned char addrByte[4];     /* address of data */
} sReadMemEx;

/* write memory */
typedef struct{
        unsigned char cmd;
        unsigned char cmdLen;
        unsigned char size;            /* size of data block in bytes */
        unsigned char addrByte[4];     /* address of data */
        unsigned char data[1];         /* data */
} sWriteMemEx;

/* setup scope */
typedef struct{
        unsigned char cmd;
        unsigned char cmdLen;
        unsigned char varCnt;          /* number of variables */
        unsigned char dataByte[1];     /* address of variable */
} sSetupScopeEx;

/* setup recorder */
typedef struct{
        UWord16  cmd;
        UWord16  cmdLen;
        UWord16  trgMode;
        UWord16  totalSmps;
        UWord16  postTrigger;
        UWord16  timeDiv;              /* Time Base unit multiplier  */
        UWord32  trgVarAddr[1];
        UWord16  trgVarSize;
        UWord16  trgVarSigned;
        union {
            UInt8          uch;
            Int8           ch;
            UWord16        uw;
            Word16         sw;
            UWord32        ud;
            Word32         sd;
        } trgThreshold;                /* trigger comparing threshold */
        UWord16        varCnt;         /* number of variables */
        struct{
            UWord16     varSize;       /* size of variable in bytes */
            UWord32     varAddr[1];    /* address of variable    */
        } varDef[8];
} sSetupRec;

/* call user application command */
typedef struct{
        UInt8       cmd;
        UInt8       cmdLen;
        UInt8       appCmdData[1];     /* application command data */
} sCallAppCmd;

/* return any data */
typedef struct{
        unsigned char reserved;        /* status code */
        unsigned char data[1];         /* data to PC */
} sReturnData;

/* currently read input char (it contains checksum at the end of message) */
static UInt8 inChar;
/* position in buffer (0,1,2,...) */
static unsigned int pos;
/* length of data in a message used for receiving and transmitting (includes checksum) */
static UInt8 length;

/* variable for checksum accumulation */
static unsigned int checkSum;

/* pointer to sciComm structure passed in initialization */
static sPCMasterComm *PCMasterComm;

static sResponse response;             /* variable with response data */

static UWord16 recPretrigCount;        /* recorder pretrigger counter   */

/* send one byte from output buffer */
static void sendBuffer(void);
/* prepare data for transmitting
(response.status -> status code, len -> length of data) */
static void sendResponse(sResponse *resp) ;
/* sample recorder data */
static asm void readSample(int *Addr, int *DestAddr);
static UWord16 readRecSample(UWord16 position);
/* decoding of incoming message after the last byte was received */
static void messageDecode(void);

/* routine callled after filtering doubled SOM */
static void messageData(UWord16 startOfMessage);
/* all functions that begins with Cmd execute
   the command and place the right data in dataBuff */
inline static void cmdGetInfoBrief(void);
static UWord16 memCopy(register volatile unsigned char * srcAddr,
                       register volatile unsigned char * destAddr,
                       register volatile char size);
/*---------------------------------------
  SCI communication algotithm variables
  --------------------------------------- */
static unsigned int status;            /* status word of receiver */
static unsigned int PC_M1_SCIRxFullInt; /* internal status register of interrupt */
static unsigned int PC_M1_SCITxEmptyInt; /* internal status register of interrupt */


/*
** ===================================================================
**     Method      :  PC_M1_pcmasterdrvInit (bean PC_Master)
**
**     Description :
**         Initialization of PC Master Communication Algorithm. This
**         function must be called first, before start of
**         communication.
**     Parameters  :
**         NAME            - DESCRIPTION
**       * p_sPCMasterComm - Pointer to
**                           structure with SCI communication
**                           settings.
**     Returns     :
**         ---             - The function returns the PASS (0).
** ===================================================================
*/
Word16 PC_M1_pcmasterdrvInit(sPCMasterComm *p_sPCMasterComm)
{
  /* store sPCMasterComm structure address */
  PCMasterComm=(sPCMasterComm *)p_sPCMasterComm;

  inChar = 1;
  status = 0; /* reset receiver */

  #ifdef PCMDRV_INCLUDE_CMD_SCOPE
    /* reset scope */
    ((pcmdrv_sScope *)(PCMasterComm->p_scope))->varCnt=0;
  #endif

  #ifdef PCMDRV_INCLUDE_CMD_RECORDER
    /* reset recorder */
    ((pcmdrv_sScope *)(PCMasterComm->p_recorder))->varCnt=0;
  #endif

  #ifdef PCMDRV_INCLUDE_CMD_APPCMD
    /* initialize application command status */
    pcmdrvAppCmdSts = PCMDRV_APPCMD_NOCMD;
  #endif

  return(0);
}

/*
** ===================================================================
**     Method      :  PC_M1_pcmasterdrvIsr (bean PC_Master)
**
**     Description :
**         Main PC Master Communication routine which provide
**         receiving, decoding of incoming message and sending
**         response to PC.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void PC_M1_pcmasterdrvIsr(void)
{
  if (status & ST_SENDING) {           /* message is transmitting */
    sendBuffer();                      /* send data */
    return;                            /* response is sending to PC */
  }
  SCIread(inChar);                     /* read received character */
  if ((status & ST_ST_CHAR_REC) == 0) { /* last byte was not '+' */
    if (inChar == '+') {               /* '+' received */
      bitSet(ST_ST_CHAR_REC,status);
    }
    else {                             /* any byte received */
      messageData(0);                  /* byte received */
    }
  }
  else {                               /* the last byte was '+' */
    if (inChar == '+') {               /* doubled '+' (this is the second one) */
      messageData(0);                  /* byte received */
    }
    else {                             /* start of message */
      messageData(1);                  /* byte received */
    }
    bitClear(ST_ST_CHAR_REC,status);   /* clear flag */
  }
}

/*
** ===================================================================
**     Method      :  memCopy (bean PC_Master)
**
**     Description :
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static UWord16 memCopy(register volatile char unsigned *srcAddr,
                       register volatile unsigned char *destAddr,
                       register volatile char size)
{
  while ((--size) >= 0) {
    *destAddr++ = *srcAddr++;
  }
  return(0);
}

/*
** ===================================================================
**     Method      :  sendBuffer (bean PC_Master)
**
**     Description :
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
inline static void sendBuffer(void)
{
  if (pos <= length) {                 /* is it end of message ? */
    Inhr1_SendChar((PCMasterComm)->p_dataBuff[pos]); /* send one char to SCI */
    if ((PCMasterComm)->p_dataBuff[pos] != '+') { /* current character is not '+' */
      checkSum += (PCMasterComm)->p_dataBuff[pos]; /* accumulate checksum */
      pos++;
    }
    else {                             /* current character is '+' */
      if (status & ST_ST_SENT) {       /* the last sent char was '+' */
        bitClear(ST_ST_SENT,status);
        checkSum += (PCMasterComm)->p_dataBuff[pos]; /* accumulate checksum */
        pos++;
      }
      else {                           /* the last sent byte was not '+' */
        bitSet(ST_ST_SENT,status);
      }
    }
    if ((pos == length) && !(status & ST_CS_ADDED)) { /* the last byte before cs was sent, now add the checksum */
      checkSum = (-checkSum) & 0x00FF; /* compute checksum */
      (PCMasterComm)->p_dataBuff[pos] = (UInt8)checkSum;
      bitSet(ST_CS_ADDED,status);      /* set flag */
    }
  }
  else {                               /* end of transmitting */
    bitClear(ST_SENDING | ST_CS_ADDED,status); /* reset transmitter (switch to receiving mode) */
    SCItxEmptyIsr(INT_DISABLE);        /* disable SCI Tx Empty Interrupt */
    SCIrxFullIsr(INT_ENABLE);          /* enable SCI Rx Full Interrupt */
  }
}

/*
** ===================================================================
**     Method      :  sendResponse (bean PC_Master)
**
**     Description :
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void sendResponse(sResponse *resp)
{
  bitSet(ST_SENDING,status);           /* set flag */
  (PCMasterComm)->p_dataBuff[0] = resp->status; /* status of trasmitted message */
  length=resp->length;                 /* length of message */
  pos=0;                               /* position in the message */

  /* send start of message */
  inChar = '+';
  SCIwrite(inChar);                    /* send start character */

  SCIrxFullIsr(INT_DISABLE);           /* disable SCI Rx Full Interrupt */
  SCItxEmptyIsr(INT_ENABLE);           /* enable SCI Tx Empty Interrupt */
  checkSum = 0;                        /* reset checksum */
}

/*
** ===================================================================
**     Method      :  messageDecode (bean PC_Master)
**
**     Description :
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void messageDecode(void)
{
  unsigned char *varaddr;
  #ifndef PCMDRV_INCLUDE_CMD_GETINFOBRIEF
  unsigned char cnt;
  #endif

  switch(PCMasterComm->p_dataBuff[0]) {
  /* -------------------------
  special format commands
  ------------------------- */
    case PCMDRV_CMD_READVAR8EX: {      /* read 8-bit variable */
        /* read address */
        memCopy(((sReadVarEx *)(PCMasterComm->p_dataBuff))->addrByte,
          (unsigned char *)&varaddr, POINT32_LEN);
        /* read data */
        memCopy(varaddr, ((sReturnData *)(PCMasterComm->p_dataBuff))->data, BYTE_LEN);
        respPrepare(PCMDRV_STC_OK, 2); /* OK */
    }break;
    case PCMDRV_CMD_READVAR16EX: {     /* read 16-bit variable */
        /* read address */
        memCopy(((sReadVarEx *)(PCMasterComm->p_dataBuff))->addrByte,
          (unsigned char *)&varaddr, POINT32_LEN);
        /* read data */
        memCopy(varaddr, ((sReturnData *)(PCMasterComm->p_dataBuff))->data, WORD_LEN);
        respPrepare(PCMDRV_STC_OK, 3); /* OK */
    }break;
    case PCMDRV_CMD_READVAR32EX: {     /* read 32-bit variable */
        /* read address */
        memCopy(((sReadVarEx *)(PCMasterComm->p_dataBuff))->addrByte,
          (unsigned char *)&varaddr, POINT32_LEN);
        /* read data */
        memCopy(varaddr, ((sReturnData *)(PCMasterComm->p_dataBuff))->data, LONG_LEN);
        respPrepare(PCMDRV_STC_OK, 5); /* OK */
    }break;
    #ifdef PCMDRV_INCLUDE_CMD_SCOPE
    case PCMDRV_CMD_READSCOPE: {       /* read scope variables */
        unsigned char i, cnt, index = 0;
        /* scope not configured */
        if (((pcmdrv_sScope *)(PCMasterComm->p_scope))->varCnt==0) {
          respPrepare(PCMDRV_STC_NOTINIT,1); /* scope not initialized */
        }
        else {                         /* scope configured */
          /* read number of variables */
          cnt = ((pcmdrv_sScope *)(PCMasterComm->p_scope))->varCnt;
          for (i=0; i < cnt; i++) {
            /* read size of variable */
            length = ((pcmdrv_sScope *)(PCMasterComm->p_scope))->varDef[i].varSize;
            /* read address of variable */
            memCopy( ((pcmdrv_sScope *)(PCMasterComm->p_scope))->varDef[i].addrByte,
              (unsigned char *)&varaddr, POINT32_LEN);
            /* copy data into the input/output buffer */
            memCopy( varaddr, (unsigned char *)&((sReturnData *)
            (PCMasterComm->p_dataBuff))->data[index], (Int8) length);
            index += length;
          }
          respPrepare(PCMDRV_STC_OK, (UInt8)(index +1)); /* OK */
        }
    }break;
    #endif
    #ifdef PCMDRV_INCLUDE_CMD_APPCMD
    case PCMDRV_CMD_GETAPPCMDSTS: {    /* get user application command call status */
        /* buffer is not initialized (zero length) */
        if (PCMasterComm->appCmdSize == 0) {
          respPrepare(PCMDRV_STC_INVCMD,1); /* invalid command */
          return;
        }
        /* copy status byte in the output buffer */
       ((sReturnData *)(PCMasterComm->p_dataBuff))->data[0] = pcmdrvAppCmdSts;
       respPrepare(PCMDRV_STC_OK,2);   /* OK */
    }break;
    #endif
    #ifdef PCMDRV_INCLUDE_CMD_GETINFOBRIEF
    case PCMDRV_CMD_GETINFOBRIEF: {    /* get brief info about hardware */
        cmdGetInfoBrief();             /* execute the command */
        respPrepare(PCMDRV_STC_OK,(1 + 6)); /* OK */
    }break;
    #endif
    #ifndef PCMDRV_INCLUDE_CMD_GETINFOBRIEF
    case PCMDRV_CMD_GETINFO: {         /* get info about hardware */
        /* protocol version  */
        ((sReturnData *)(PCMasterComm->p_dataBuff))->data[0] = PCMDRV_PROT_VER;
        /* CFG_FLAFGS  */
        ((sReturnData *)(PCMasterComm->p_dataBuff))->data[1] = PCMDRV_CFG_FLAFGS;
        /* dataBusWdt  */
        ((sReturnData *)(PCMasterComm->p_dataBuff))->data[2] = PCMDRV_DATABUSWDT;
        /* version  */
        ((sReturnData *)(PCMasterComm->p_dataBuff))->data[3] = PCMasterComm->globVerMajor;
        /* version  */
        ((sReturnData *)(PCMasterComm->p_dataBuff))->data[4] = PCMasterComm->globVerMinor;
        /* size of input buffer (without CMD, LENGTH)   */
        ((sReturnData *)(PCMasterComm->p_dataBuff))->data[5] = (UInt8)(((PCMasterComm->dataBuffSize) - 1));
        /* recorder buff size   */
        ((sReturnData *)(PCMasterComm->p_dataBuff))->data[6] = (UInt8)((PCMasterComm->recSize )      & 0x00ff);
        ((sReturnData *)(PCMasterComm->p_dataBuff))->data[7] = (UInt8)(((PCMasterComm->recSize)>>8)  & 0x00ff);
        /* period of Recorder routine launch   */
        ((sReturnData *)(PCMasterComm->p_dataBuff))->data[8] = (UInt8)((PCMasterComm->timeBase)      & 0x00ff);
        ((sReturnData *)(PCMasterComm->p_dataBuff))->data[9] = (UInt8)(((PCMasterComm->timeBase)>>8) & 0x00ff);
        /* copy identification string */
        for (cnt=0 ; cnt < PCMDRV_IDT_STRING_LEN ; cnt++) {
          ((sReturnData *)((PCMasterComm)->p_dataBuff))->data[10 + cnt] = PCMasterComm->idtString[cnt];
        }
        /* OK */
        respPrepare(PCMDRV_STC_OK,(1 + 10 + PCMDRV_IDT_STRING_LEN));
    }break;
    #endif
    #ifdef PCMDRV_INCLUDE_CMD_RECORDER
    case PCMDRV_CMD_STARTREC: {        /* start recorder */
        if (PCMasterComm->recSize==0) { /* recorder not implemented  */
          respPrepare(PCMDRV_STC_INVCMD,1); /* invalid command */
          return;
        }
        if(((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->varCnt) { /* recorder initialized      */
          if (!(status & ST_RECRUNNING)) { /* recorder not running      */
            bitClear(ST_RECRUNNING,status); /* stop recorder if it is running   */
            (((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->recTime) = /* initialize time div       */
              ((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->timeDiv; /* addr. of triggering variable  */
            varaddr=(unsigned char*)(((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->trgVarAddr);
            memCopy((UInt8*)(((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->trgVarAddr[0]),
              (UInt8*)(&(((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->recLastVal.ud)),
              (Int8)(((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->trgVarSize));
            bitSet(ST_RECACTIVATED,status); /* activate recorder to wait for trigger */
            respPrepare(PCMDRV_STC_OK,1); /* OK */
          }
          else {
            respPrepare(PCMDRV_STC_RECRUN,1); /* recorder is running  */
          }
        }
        else {                         /* recorder is not initialized   */
          respPrepare(PCMDRV_STC_NOTINIT,1); /* recorder not initialized   */
        }
    }break;
    #endif
    #ifdef PCMDRV_INCLUDE_CMD_RECORDER /* start recorder */
    case PCMDRV_CMD_STOPREC: {         /* stop recorder  */
        if (PCMasterComm->recSize==0) { /* recorder not implemented   */
          respPrepare(PCMDRV_STC_INVCMD,1); /* invalid command   */
          return;
        }
        if (((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->varCnt) { /* recorder initialized */
          if (status & ST_RECACTIVATED) { /* recorder activated   */
            if (status & ST_RECRUNNING) { /* recorder running     */
              respPrepare(PCMDRV_STC_RECDONE,1); /* recorder finished    */
            }
            else {                     /* recorder not running */
              /* initialize posttrigger value  */
              (((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->recToEnd)=
                (((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->postTrigger);
              bitSet(ST_RECRUNNING,status); /* manually trigger the recorder */
              respPrepare(PCMDRV_STC_OK,1); /* OK */
            }
          }
          else {                       /* recorder not activated  */
            respPrepare(PCMDRV_STC_RECDONE,1); /* recorder finished       */
          }
        }
        else {                         /* recorder not initialized*/
          respPrepare(PCMDRV_STC_NOTINIT,1);
        }
    }break;
    #endif
    #ifdef PCMDRV_INCLUDE_CMD_RECORDER /* start recorder          */
    case PCMDRV_CMD_GETRECBUFFEX: {    /* get recorder buffer     */
        UWord16        tmp;            /* temporary variable      */

        if (PCMasterComm->recSize==0) { /* recorder not implemented*/
          respPrepare(PCMDRV_STC_INVCMD,1);
          return;
        }
        if ((((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->varCnt) != 0) { /* recorder initialized */
          if (!(status & ST_RECRUNNING)) { /* recorder not running */
            /* recorder buffer address */
            memCopy((UInt8*)(&(PCMasterComm->p_recBuff)),(UInt8*)(&(PCMasterComm->p_dataBuff[1])),LONG_LEN);
            tmp=(((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->recPos)/
              (((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->recSetLen);
            (PCMasterComm)->p_dataBuff[5]= (UInt8)(tmp & 0x00FF); /* position of the last sample in rec.buff. LSB */
            (PCMasterComm)->p_dataBuff[6]= (UInt8)(tmp >> 8); /* position of the last sample in rec.buff. MSB */
            respPrepare(PCMDRV_STC_OK,7); /* OK */
          }
          else {                       /* recorder running  */
            respPrepare(PCMDRV_STC_SERVBUSY,1); /*  service busy     */
          }
        }
        else {                         /* recorder initialized */
          respPrepare(PCMDRV_STC_NOTINIT,1); /* recorder not initialized   */
        }
    }break;
    #endif
    #ifdef PCMDRV_INCLUDE_CMD_RECORDER /* recorder status            */
    case PCMDRV_CMD_GETRECSTS: {       /* get recorder status        */
        if (PCMasterComm->recSize==0) { /* recorder not implemented   */
          respPrepare(PCMDRV_STC_INVCMD,1); /* invalid command            */
          return;
        }
        if (((pcmdrv_sScope *)(PCMasterComm->p_recorder))->varCnt) { /* recorder is initialized    */
          if (!(status & ST_RECACTIVATED)) {
            respPrepare(PCMDRV_STC_RECDONE,1); /* recorder finished          */
          }
          else {
            respPrepare(PCMDRV_STC_RECRUN,1); /* recorder running           */
          }
        }
        else {                         /* recorder is not initialized*/
          respPrepare(PCMDRV_STC_NOTINIT,1); /* recorder not initialized   */
        }
    }break;
    #endif
    /* --------------------------
        standard format commands
       -------------------------- */
    #ifdef PCMDRV_INCLUDE_CMD_SCOPE
    case PCMDRV_CMD_SETUPSCOPEEX: {    /* setup scope */
        unsigned char cnt,i;

        cnt = (((sSetupScopeEx *)(PCMasterComm->p_dataBuff))->varCnt);
        if ( (cnt == 0) || (cnt > 8) ) {
          /* varCnt is zero or greater than 8 */
          respPrepare(PCMDRV_STC_INVBUFF,1); /* invalid buffer size */
          return;
        }
        /* read varCnt */
        ((pcmdrv_sScope *)(PCMasterComm->p_scope))->varCnt = cnt;
        for (i=0; i < cnt; i++) {
          /* read size of variable */
          ((pcmdrv_sScope *)(PCMasterComm->p_scope))->varDef[i].varSize =
          ((sSetupScopeEx *)(PCMasterComm->p_dataBuff))->dataByte[i*5];
          /* read address of variable */
          memCopy( (unsigned char *)&((sSetupScopeEx *)
            (PCMasterComm->p_dataBuff))->dataByte[1 + 5*i],
            ((pcmdrv_sScope *)(PCMasterComm->p_scope))->
            varDef[i].addrByte, POINT32_LEN);
        }
        /* check size of variable s */
        for(i=0 ; i<(((pcmdrv_sScope *)(PCMasterComm->p_scope))->varCnt) ; i++) {
          /* varSize is 0,3 or greater than 4 */
          if ( ((((pcmdrv_sScope *)(PCMasterComm->p_scope))->varDef[i].varSize) == 0) || \
            ((((pcmdrv_sScope *)(PCMasterComm->p_scope))->varDef[i].varSize) == 3) || \
            ((((pcmdrv_sScope *)(PCMasterComm->p_scope))->varDef[i].varSize) > 4) ) {
              /* invalid size of variable */
              respPrepare(PCMDRV_STC_INVSIZE,1);
              /* reset scope */
              (((pcmdrv_sScope *)(PCMasterComm->p_scope))->varCnt) = 0;
              return;
          }
        }
        respPrepare(PCMDRV_STC_OK,1);
    }break;
    #endif
    #ifdef PCMDRV_INCLUDE_CMD_RECORDER
    case PCMDRV_CMD_SETUPRECEX: {
        unsigned char i;               /* auxiliariy variables definition   */

        if (PCMasterComm->recSize==0) { /* recorder not implemented  */
          respPrepare(PCMDRV_STC_INVCMD,1); /* invalid command  */
          return;
        }
        /* reset the recorder */
        bitClear(ST_RECRUNNING | ST_RECACTIVATED,status);
        /* initialize recorder
        /* (copy data from dataBuff to Recorder structure) => copy structure form PCMasterComm->p_dataBuff to */
        /* PCMasterComm->p_recorder =>  copy and organize data  to recorder structure. It is necessary to do  */
        /* conversions byte variables to word by reason of arrange data to even address                       */
        /* read command             */
        ((sSetupRec *)(PCMasterComm->p_recorder))->cmd     = *((PCMasterComm->p_dataBuff)+0);
        /* read cmdLen              */
        ((sSetupRec *)(PCMasterComm->p_recorder))->cmdLen  = *((PCMasterComm->p_dataBuff)+1);
        /* read trigger mode        */
        ((sSetupRec *)(PCMasterComm->p_recorder))->trgMode = *((PCMasterComm->p_dataBuff)+2);
        if( ((sSetupRec *)(PCMasterComm->p_recorder))->trgMode > 2 ) { /* test value {0,1,2}       */
          respPrepare(PCMDRV_STC_INVBUFF,1); /* invalid trigger mode     */
          return;
        }
        /* read total samples        */
        memCopy((PCMasterComm->p_dataBuff)+3,
        (UInt8*)(&(((sSetupRec *)(PCMasterComm->p_recorder))->totalSmps)),WORD_LEN);
        /* read post tiger size      */
        memCopy((PCMasterComm->p_dataBuff)+5,
        (UInt8*)(&(((sSetupRec *)(PCMasterComm->p_recorder))->postTrigger)),WORD_LEN);
        /* read timeDiv             */
        memCopy((PCMasterComm->p_dataBuff)+7,
        (UInt8*)(&(((sSetupRec *)(PCMasterComm->p_recorder))->timeDiv)),WORD_LEN);
        /* read trig. variab. address*/
        memCopy((PCMasterComm->p_dataBuff)+9,
        (UInt8*)(&(((sSetupRec *)(PCMasterComm->p_recorder))->trgVarAddr[0])),POINT32_LEN);
        /* read trig. variab. size   */
        ((sSetupRec *)(PCMasterComm->p_recorder))->trgVarSize       = *((PCMasterComm->p_dataBuff)+13);
        if(!((((sSetupRec *)(PCMasterComm->p_recorder))->trgVarSize==1) || /* test trig. variab. size   */
          (((sSetupRec *)(PCMasterComm->p_recorder))->trgVarSize==2) ||
          (((sSetupRec *)(PCMasterComm->p_recorder))->trgVarSize==4))) {
            respPrepare(PCMDRV_STC_INVSIZE,1); /* invalid buffer size       */
            (((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->varCnt) =  0;
            return;
        }
        /* read trig. compare mode    */
        ((sSetupRec *)(PCMasterComm->p_recorder))->trgVarSigned     = *((PCMasterComm->p_dataBuff)+14);
        memCopy((PCMasterComm->p_dataBuff)+15,
          (UInt8*)(&(((sSetupRec *)(PCMasterComm->p_recorder))->trgThreshold.ud)),LONG_LEN);
        /* read variable definitions  */
        ((sSetupRec *)(PCMasterComm->p_recorder))->varCnt           = *((PCMasterComm->p_dataBuff)+19);
        if ( (((sSetupRec *)(PCMasterComm->p_recorder))->varCnt == 0) || /* testing of data correctness*/
          (((sSetupRec *)(PCMasterComm->p_recorder))->varCnt > 8) ) {
            respPrepare(PCMDRV_STC_INVBUFF,1); /* if varCnt is zero or greater than 8 => invalid buffer size */
            (((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->varCnt) =  0;
            return;
        }
        status = (status & 0xfff0) | ((((sSetupRec *)(PCMasterComm->p_recorder))->trgVarSize)<<1) +
          ((sSetupRec *)(PCMasterComm->p_recorder))->trgVarSigned; /* set status                 */
            for(i=0;i<((sSetupRec *)(PCMasterComm->p_recorder))->varCnt;i++) { /* data descriptions => scope */
              /* initialization             */
              /* read variable size         */
              ((sSetupRec *)(PCMasterComm->p_recorder))->varDef[i].varSize = *((PCMasterComm->p_dataBuff)+20+i*5);
              if((((sSetupRec *)(PCMasterComm->p_recorder))->varDef[i].varSize==0) ||
                (((sSetupRec *)(PCMasterComm->p_recorder))->varDef[i].varSize==3)) { /* test variable sizes        */
                  respPrepare(PCMDRV_STC_INVSIZE,1); /* invalid buffer size        */
                  (((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->varCnt) =  0;
                  return;
              }
              memCopy((PCMasterComm->p_dataBuff)+21+i*5,
                (UInt8*)(&(((sSetupRec *)(PCMasterComm->p_recorder))->varDef[i].varAddr[0])),POINT32_LEN);
            }
            /*  next samples position in recorder buffer - incremented by RecSetLen */
            status = (status & 0xfff0) | ((((sSetupRec *)(PCMasterComm->p_recorder))->trgVarSize)<<1) +
              ((sSetupRec *)(PCMasterComm->p_recorder))->trgVarSigned; /* set status                 */
            ((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->recPos = 0;
            /*  length of requiered variables set [Word] */
            ((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->recSetLen =   0;
            /*  position to end of buffer */
            ((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->recToEnd  =   1;
            /*  recorder time div         */
            ((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->recTime   =
               ((sSetupRec *)(PCMasterComm->p_recorder))->timeDiv;
            /* check if recorder buffer size is valid */
            ((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->recSetLen = 0; /* clear result before cycle  */
            for(i=0;i<((sSetupRec *)(PCMasterComm->p_recorder))->varCnt;i++) { /* get one set of samples [B] */
              ((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->recSetLen +=
              ((sSetupRec *)(PCMasterComm->p_recorder))->varDef[i].varSize;
            }
            ((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->totalSmps *= /* required buffer size [W]   */
              ((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->recSetLen;
            if(((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->totalSmps <= /* required buffer size is    */
              PCMasterComm->recSize) { /* smaller than record. buffer*/
                /* read last value of trig. variable   */
                memCopy((UInt8*)(((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->trgVarAddr[0]),
                  (UInt8*)(&(((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->recLastVal.ud)),
                  (Int8)(((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->trgVarSize));
                respPrepare(PCMDRV_STC_OK,1);
                bitSet(ST_RECACTIVATED,status); /* recorder activated  */
            }
            else {
              respPrepare(PCMDRV_STC_INVSIZE,1); /* invalid buffer size */
              (((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->varCnt) =  0;
              return;
            }
    }break;
    #endif
    case PCMDRV_CMD_READMEMEX: {       /* read block of memory */
        /* read size of data */
        memCopy(&(((sReadMemEx *)(PCMasterComm->p_dataBuff))->size),
          (unsigned char *)&length, BYTE_LEN);
        if (length <= ((PCMasterComm)->dataBuffSize)) {
          /* read address */
          memCopy(((sReadMemEx *)(PCMasterComm->p_dataBuff))->addrByte,
            (unsigned char *)&varaddr, POINT32_LEN);
          /* copy data */
          memCopy( varaddr,(((sReturnData *)(PCMasterComm->p_dataBuff))->data),(Int8) length);
          respPrepare(PCMDRV_STC_OK,(UInt8)(length+1)); /* OK */
        }
        else {
          /* response greater than buffer */
          /* response buffer overflow */
          respPrepare(PCMDRV_STC_RSPBUFFOVF,1);
        }
    }break;
    case PCMDRV_CMD_WRITEMEMEX: {      /* write block of memory */
        /* read length of memory block from the message */
        memCopy(&(((sWriteMemEx *)(PCMasterComm->p_dataBuff))->size),
          (unsigned char *)&length, BYTE_LEN);
        /* read address */
        memCopy((((sWriteMemEx *)(PCMasterComm->p_dataBuff))->addrByte),
          (unsigned char *)&varaddr, POINT32_LEN);
        /* copy data */
        memCopy((((sWriteMemEx *)(PCMasterComm->p_dataBuff))->data),
          varaddr, (Int8)length);
        respPrepare(PCMDRV_STC_OK,1);
    }break;
    case PCMDRV_CMD_WRITEMEMMASKEX: {  /* write to memory with mask */
        unsigned char i, tmpData;

        /* read length of memory block from the message */
        memCopy(&(((sWriteMemEx *)(PCMasterComm->p_dataBuff))->size),
          (unsigned char *)&length, BYTE_LEN);
        /* read address */
        memCopy((((sWriteMemEx *)(PCMasterComm->p_dataBuff))->addrByte),
          (unsigned char *)&varaddr, POINT32_LEN);
        for (i=0; i<length; i++) {
          /* read data */
          tmpData =  ((sWriteMemEx *)(PCMasterComm->p_dataBuff))->data[i]; /* read data */
          tmpData &= ((sWriteMemEx *)(PCMasterComm->p_dataBuff))->data[i + length]; /* read mask */
          archDisableInt();
          tmpData |= (*varaddr) & ~(((sWriteMemEx *)(PCMasterComm->p_dataBuff))->data[i + length]);
          *varaddr = tmpData;          /* write back modified data */
//          archEnableInt();
        }
        respPrepare(PCMDRV_STC_OK,1);  /* OK */
    }break;
    #ifdef PCMDRV_INCLUDE_CMD_APPCMD
    case PCMDRV_CMD_CALLAPPCMD: {      /* call user application command */
        if (PCMasterComm->appCmdSize == 0) { /* buffer is not initialized (zero length) */
          respPrepare(PCMDRV_STC_INVCMD,1); /* invalid command */
          break;
        }
        memCopy( (unsigned char *)&(((sCallAppCmd *)(PCMasterComm->p_dataBuff))->cmdLen),
          (unsigned char *)&length, BYTE_LEN);
        if ( length > PCMasterComm->appCmdSize) { /* check Application Command length */
          respPrepare(PCMDRV_STC_INVBUFF,1); /* invalid buffer size */
        }
        else {
          if (pcmdrvAppCmdSts == PCMDRV_APPCMD_RUNNING) { /* Application Command already called */
            respPrepare(PCMDRV_STC_SERVBUSY,1); /* service is busy  */
          }
          else {                       /* no Application Command was called */
            /* copy Application Command data to Application Command buffer */
            memCopy( (((sCallAppCmd *)(PCMasterComm->p_dataBuff))->appCmdData),
              PCMasterComm->p_appCmdBuff,(Int8) length);
            pcmdrvAppCmdSts = PCMDRV_APPCMD_RUNNING;
            respPrepare(PCMDRV_STC_OK,1); /* OK */
          }
        }
    }break;
    #endif
    default: {                         /* invalid command */
        respPrepare(PCMDRV_STC_INVCMD,1); /* invalid command */
    }break;
  }
}

/*
** ===================================================================
**     Method      :  messageData (bean PC_Master)
**
**     Description :
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void messageData(UWord16 startOfMessage)
{
  if (startOfMessage == 0) {           /* no start of message */
    if (status & ST_STARTED) {         /* start of message already detected */
      if (pos != length) {             /* read byte, accumulate checksum */
        (PCMasterComm)->p_dataBuff[pos] = (UInt8)inChar;
        checkSum += inChar;            /* checksum accumulation */
        pos++;                         /* next position in buffer */
        if (status & ST_STD_CMD) {     /* inChar contains length of standard format message */
          length = (UInt8)(inChar + 2); /* read length of message */
          bitClear(ST_STD_CMD,status); /* clear flag */
          if (length > ((PCMasterComm)->dataBuffSize)) { /* command is greater than input buffer */
            /* clear flag */
            bitClear(ST_STARTED | ST_ST_CHAR_REC,status);
            /* input buffer overflow */
            respPrepare(PCMDRV_STC_CMDBUFFOVF,1);
            /* send response to PC */
            sendResponse(&response);
          }
        }
      }
      else {                           /* end of message */
        checkSum += inChar;            /* accumulate checksum */
        if ((checkSum & 0x00FF) == 0) { /* correct checksum */
          messageDecode();
        }
        else {                         /* checksum error */
          /* checksum error response */
          respPrepare(PCMDRV_STC_CMDSERR,1);
        }
        /* clear flag */
        bitClear(ST_STARTED | ST_ST_CHAR_REC,status);
        sendResponse(&response);       /* send response to PC */
      }
    }
  }
  else {                               /* start of message */
    /* reset receiver, read first byte of message */
    bitSet(ST_STARTED,status);         /* message receiving */
    /* read byte, start of checksum accumulating */
    checkSum = (PCMasterComm)->p_dataBuff[0] = (UInt8)inChar;
    /* next position in buffer */
    pos = 1;
    /* value sufficient for standard format commands */
    length = 2;
    if (inChar >= 0xC0) {              /* special format command */
      length=(UInt8)(((inChar & 0x30) >> 3) + 1); /* length decoding */
    }
    else {                             /* standard format command (next byte will be length of the message) */
      bitSet(ST_STD_CMD,status);       /* wait for next character */
    }
  }
}

/*
** ===================================================================
**     Method      :  readRecSample (bean PC_Master)
**
**     Description :
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static UWord16 readRecSample(UWord16 position)
{
  Word16 i;

  for (i=0 ; i < (((pcmdrv_sRecorder *)(PCMasterComm->p_recorder))->varCnt) ; i++) { /* read each variable */
    /* read each variable */
    memCopy((UInt8*)(((sSetupRec *)(PCMasterComm->p_recorder))->varDef[i].varAddr[0]),
      (UInt8*)((PCMasterComm->p_recBuff)+position),
      (Int8)(((sSetupRec *)(PCMasterComm->p_recorder))->varDef[i].varSize));
    position += ((sSetupRec *)(PCMasterComm->p_recorder))->varDef[i].varSize;
  }
  return(position);
}

void Inhr1_OnError(void)
{
  Inhr1_TError Err;
  Inhr1_TComData c;

  Inhr1_GetError(&Err);
  if (Err.errName.OverRun)
    (void)Inhr1_RecvChar(&c);
}

void Inhr1_OnRxChar(void)
{
  if (PC_M1_SCIRxFullInt) PC_M1_pcmasterdrvIsr();
}

void Inhr1_OnTxChar(void)
{
  if (PC_M1_SCITxEmptyInt) PC_M1_pcmasterdrvIsr();
}

/*
** ===================================================================
**     Method      :  PC_M1_PE_Init (bean PC_Master)
**
**     Description :
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
void PC_M1_PE_Init(void)
{
  #if !defined(PCMDRV_BUFFER_SIZE)
    #define PCMDRV_BUFFER_SIZE                         60
  #endif

  #if !defined(PC_MASTER_REC_BUFF_LEN)
    /* Recorder buffer length */
    #define PC_MASTER_REC_BUFF_LEN                     40
  #endif
  #if !defined(PC_MASTER_APPCMD_BUFF_LEN)
    /* Application Command buffer length */
    #define PC_MASTER_APPCMD_BUFF_LEN                   5
  #endif


  static word pcmdrvDataBuff[(PCMDRV_BUFFER_SIZE / 2) + 1];
  static sPCMasterComm PCMSettings;    /* initialization structure */
  static pcmdrv_sScope pcmdrvScope;    /* scope config data */

  #if (PC_MASTER_REC_BUFF_LEN != 0)
    /* recorder buffer */
    static UWord16 PCMasterCommRecorderBuffer[PC_MASTER_REC_BUFF_LEN];
    static pcmdrv_sRecorder pcmdrvRecorder; /* recorder config and temp data */
  #endif
  #if (PC_MASTER_APPCMD_BUFF_LEN != 0)
    /* application command data buffer */
    static unsigned char PCMasterAppCmdBuff[PC_MASTER_APPCMD_BUFF_LEN];
  #endif
  #if (PC_MASTER_REC_BUFF_LEN != 0)
    /* address of buffer */
    PCMSettings.p_recBuff   = (unsigned char *)PCMasterCommRecorderBuffer;
    PCMSettings.p_recorder  = (unsigned char *)&pcmdrvRecorder;
  #endif

  /* address of input/output buffer */
  PCMSettings.p_dataBuff   = (unsigned char *)pcmdrvDataBuff;
  PCMSettings.dataBuffSize = PCMDRV_BUFFER_SIZE;
  /* buffer length */
  PCMSettings.recSize      = PC_MASTER_REC_BUFF_LEN;
  /* recorder time base */
  PCMSettings.timeBase     = PC_MASTER_RECORDER_TIME_BASE ;

  #if (PC_MASTER_APPCMD_BUFF_LEN != 0)
    /* address of buffer */
    PCMSettings.p_appCmdBuff = PCMasterAppCmdBuff;
  #endif

  PCMSettings.p_scope      = (unsigned char *)&pcmdrvScope;
  /* buffer length */
  PCMSettings.appCmdSize   = PC_MASTER_APPCMD_BUFF_LEN;
  /* board firmware version major number */
  PCMSettings.globVerMajor = PC_MASTER_GLOB_VERSION_MAJOR;
  /* board firmware version minor number */
  PCMSettings.globVerMinor = PC_MASTER_GLOB_VERSION_MINOR;
  /* device identification string */
  strcpy((char *)PCMSettings.idtString,PC_MASTER_IDT_STRING);
  /* SCI communication initialization */
  SCItxEmptyIsr(INT_DISABLE);          /* disable SCI Tx Empty Interrupt */
  SCIrxFullIsr(INT_ENABLE);
  pcmasterdrvInit(&PCMSettings);
}

/* END PC_M1. */

/*
** ###################################################################
**
**     This file was created by UNIS Processor Expert 2.99 [04.17]
**     for the Freescale 56800 series of microcontrollers.
**
** ###################################################################
*/
