⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccp.c

📁 ccp
💻 C
📖 第 1 页 / 共 3 页
字号:
/*----------------------------------------------------------------------------
| File:
|   ccp.c
|
| Project:
|   CCP driver
|
| Description:
|   CCP driver main module
|
 ----------------------------------------------------------------------------*/

/* CCP Definitions and Parameters */
#include "ccp.h"

#ifndef C_DISABLE_CCP

/* Version History:

   V1.29, 24.9.2000
    - new define CCP_CHECKSUM_BLOCKSIZE
   V1.30, 29.11.2000
    - #ifndef CCP_EXTERNAL_STATION_ID
   V1.31, 08.02.2001,
    - new define CCP_DAQ_BASE_ADDR
    - new function ccpGetDaqPointer
   V1.32, 30.05.2001,
    - Reserved word "data" in KEIL Compiler for C5x5
    - Prefix CCP_ for all #defines
   V1.33, 14.09.2001
    - #define CCP_ODT_ENTRY_SIZE
    - #define CCP_INTEL,CCP_MOTOROLA
   V1.34, 28.10.2001
    - ccpSend return value removed
      Transmission error handling should be done by the user
   V1.35, 8.4.2002
    - #define CCP_CPUTYPE_32BIT
    - Max checksum block size is DWORD on 32 bit CPUs
   V1.36, 2.6.2002
    - #undef CCP_DAQ for drivers without DAQ fixed
    - double - float conversion for SHORT_UPLOAD, DNLOAD and DAQ
   V1.37, 17.7.2002
    - Fixed the version nr. because the version was in the comment 1.36 but 135
    - was define.
    - Set #define CCP_DRIVER_VERSION to 137
*/

#define CCP_DRIVER_VERSION 137




/*--------------------------------------------------------------------------*/
/* Performance measurements */

#ifndef CCP_PROFILE

  #define SET_PORT_BIT(i)
  #define RST_PORT_BIT(i)

#else

  /*
  t[0] - ccpCommand
  t[1] - ccpCallBack
  t[2] - ccpBackground
  t[3] - ccpDaq
  */
  unsigned int t0[4],t[4];
  #define SET_PORT_BIT(i) t0[i-1]=ccpGetTimestamp();
  #define RST_PORT_BIT(i) t[i-1]=T3-t0[i-1];

#endif


/*--------------------------------------------------------------------------*/
/* Test */

#ifdef CCP_TESTMODE
  #include <stdio.h>
  static void ccpPrintCANapeSettings( void );
  static void ccpPrintDaqList( CCP_BYTE daq );
#endif


/*--------------------------------------------------------------------------*/
/* ROM */
/*--------------------------------------------------------------------------*/

/*
   Identification
   Must be 0 terminated !!

   This string is used by CANape as the ASAP2 database filename
   The extension .A2L or .DB is added by CANape
*/
#ifdef CCP_EXTERNAL_STATION_ID
  extern ROM CCP_BYTE ccpStationId[];
#else
  CCP_ROM CCP_BYTE ccpStationId[] = CCP_STATION_ID;
#endif


/*--------------------------------------------------------------------------*/
/* RAM */
/*--------------------------------------------------------------------------*/

/*
   The following structure containes all RAM locations needed by the CCP driver
   It has to be word aligned on a C167 !!!
*/

CCP_RAM struct ccp ccp;


/*--------------------------------------------------------------------------*/
/* CODE */
/*--------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------*/
/* Transmit */
/*--------------------------------------------------------------------------*/

/* Send a CRM, if no other message is pending */
void ccpSendCrm( void ) {

  CCP_DISABLE_INTERRUPT;

  if (ccp.SendStatus&CCP_SEND_PENDING) {

    ccp.SendStatus |= CCP_CRM_REQUEST;

  } else {

    ccp.SendStatus |= CCP_CRM_PENDING;
    ccpSend(ccp.Crm);

  }

  CCP_ENABLE_INTERRUPT;
}


/* Send a DTM, if no other message is pending */
#ifdef CCP_DAQ
#ifndef CCP_SEND_QUEUE
static void ccpSendDtm( void ) {

  CCP_DISABLE_INTERRUPT;

  if (ccp.SendStatus&CCP_SEND_PENDING) {

    ccp.SendStatus |= CCP_DTM_REQUEST;

  } else {

    ccp.SendStatus |= CCP_DTM_PENDING;
    ccpSend(ccp.Dtm);

  }

  CCP_ENABLE_INTERRUPT;
}
#endif
#endif


/*--------------------------------------------------------------------------*/
/* Transmit Queue */
/*--------------------------------------------------------------------------*/
#ifdef CCP_SEND_QUEUE

void ccpQueueInit(void) {

  ccp.Queue.len = 0;
  ccp.Queue.rp = 0;
}

CCP_BYTE ccpQueueWrite(ccpMsg_t *msg) {

  if (ccp.Queue.len>=CCP_SEND_QUEUE_SIZE) return 0;
  ccp.Queue.msg[(ccp.Queue.rp+ccp.Queue.len)%CCP_SEND_QUEUE_SIZE] = *msg;
  ccp.Queue.len++;
  return 1;
}

#endif


/*--------------------------------------------------------------------------*/
/* Handle MTAs (Memory-Transfer-Address) */
/*--------------------------------------------------------------------------*/

/* Assign a pointer to a MTA */
#define ccpSetMTA(n,p) ccp.MTA[n] = p;

/* Write n bytes */
static CCP_BYTE ccpWriteMTA( CCP_BYTE n, CCP_BYTE size, CCP_BYTEPTR d ) {

  /* EEPROM write access */
  #ifdef CCP_WRITE_EEPROM
    CCP_BYTE r = ccpCheckWriteEEPROM(ccp.MTA[n],size,d);
    if (r) { /* EEPROM write access */
      ccp.MTA[n] += size;
      return r;
    }
  #endif

  /* Checked ram memory write access */
  #ifdef CCP_WRITE_PROTECTION
    if (!ccpCheckWriteAccess(ccp.MTA[n],size)) {
      ccp.MTA[n] += size;
      return CCP_WRITE_DENIED;
    }
  #endif

   /* double conversion */
   #ifdef CCP_DOUBLE_FLOAT
     if (size==8) {
       *(double*)ccp.MTA[n] = *(float*)d;
       #ifdef CCP_TESTMODE
         if (gDebugLevel>=2) CCPPRINT("[ccpWriteMTA] conversion -> double %g\n",*(double*)ccp.MTA[n]);
       #endif
       ccp.MTA[n] += 8;
       return CCP_WRITE_OK;
     }
   #endif

   while (size-->0) {
     /* COSMIC Compiler Bug: *(ccp.MTA[n]++) = *(d++);  */
     *(ccp.MTA[n]) = *d;
     ccp.MTA[n]++;
     d++;
   }
   return CCP_WRITE_OK;
}

/* Read n bytes */
static void ccpReadMTA( CCP_BYTE n, CCP_BYTE size, CCP_BYTEPTR d ) {

  /* EEPROM read access */
  #ifdef CCP_READ_EEPROM
    if (ccpCheckReadEEPROM(ccp.MTA[n],size,d)) {
      ccp.MTA[n] += size;
      return;
    }
  #endif

  /* double conversion */
  #ifdef CCP_DOUBLE_FLOAT
    if (size==8) {
      *(float*)d = (float)(*(double*)(ccp.MTA[n]));
      #ifdef CCP_TESTMODE
        if (gDebugLevel>=2) CCPPRINT("[ccpReadMTA] conversion -> float %g\n",(double)(*(float*)d));
      #endif
      return;
    }
  #endif

  while (size-->0) {
    *d = *(ccp.MTA[n]);
    d++;
    ccp.MTA[n]++;
  }
}


/*--------------------------------------------------------------------------*/
/* Data Aquisition Setup */
/*--------------------------------------------------------------------------*/

#ifdef CCP_DAQ

/* Clear DAQ list */
static CCP_BYTE ccpClearDaqList( CCP_BYTE daq ) {

  CCP_BYTEPTR p;
  CCP_BYTEPTR pl;

  if (daq>=CCP_MAX_DAQ) return 0;

  /* Clear this daq list to zero */
  p = (CCP_BYTEPTR)&ccp.DaqList[daq];
  pl = p+sizeof(ccpDaqList_t);
  while (p<pl) *p++ = 0;

  /* @@@@ Not DAQ list specific */
  ccp.SessionStatus |= SS_DAQ;
  #ifdef CCP_SEND_SINGLE
    ccp.CurrentDaq = 0;
    ccp.CurrentOdt = 0;
  #endif
  #ifdef CCP_SEND_QUEUE
    ccpQueueInit();
  #endif

  return CCP_MAX_ODT;
}

/* Prepare DAQ */
static CCP_BYTE ccpPrepareDaq(  CCP_BYTE daq, CCP_BYTE last, CCP_BYTE eventChannel, CCP_WORD prescaler ) {

  if (daq>=CCP_MAX_DAQ) return 0;

  ccp.DaqList[daq].eventChannel = eventChannel;
  if (prescaler==0) prescaler = 1;
  ccp.DaqList[daq].prescaler = prescaler;
  ccp.DaqList[daq].cycle = 1;
  ccp.DaqList[daq].last = last;
  ccp.DaqList[daq].flags = DAQ_FLAG_PREPARED;
  return 1;
}

/* Start DAQ */
static CCP_BYTE ccpStartDaq( CCP_BYTE daq ) {

  if (daq>=CCP_MAX_DAQ) return 0;

  ccp.DaqList[daq].flags = DAQ_FLAG_START;
  ccp.SessionStatus |= SS_RUN;

  #ifdef CCP_TIMESTAMPING
    ccpClearTimestamp();
  #endif

  return 1;
}

/* Start all prepared DAQs */
static void ccpStartAllPreparedDaq(void) {

  CCP_BYTE q;

  for (q=0;q<CCP_MAX_DAQ;q++) {
    if (ccp.DaqList[q].flags==DAQ_FLAG_PREPARED) ccp.DaqList[q].flags = DAQ_FLAG_START;
  }
  ccp.SessionStatus |= SS_RUN;

  #ifdef CCP_TIMESTAMPING
    ccpClearTimestamp();
  #endif
}

/* Stop DAQ */
static void ccpStopDaq ( CCP_BYTE daq ) {

  CCP_BYTE i;

  if (daq>=CCP_MAX_DAQ) return;
  ccp.DaqList[daq].flags = 0;

  /* check if all DAQ lists are stopped */
  for (i=0;i<CCP_MAX_DAQ;i++) {
    if (ccp.DaqList[i].flags&DAQ_FLAG_START) return;
  }

  ccp.SessionStatus &= ~SS_RUN;
}

/* Stop all DAQs */
static void ccpStopAllDaq( void ) {

  CCP_BYTE q;

  for (q=0;q<CCP_MAX_DAQ;q++) ccp.DaqList[q].flags = 0;
  ccp.SessionStatus &= ~SS_RUN;
}


/*--------------------------------------------------------------------------*/
/* Data Aquisition Processor */
/*--------------------------------------------------------------------------*/

#ifndef CCP_SEND_SINGLE

/* Sample and transmit a DTM */
static int ccpSampleAndTransmitDtm( CCP_BYTE pid, CCP_BYTE daq, CCP_BYTE odt ) {

  #ifdef CCP_SEND_QUEUE
    CCP_BYTE dtm[8];
  #else
    #define dtm ccp.Dtm
  #endif
  #ifdef CCP_DAQ_BASE_ADDR
    CCP_BYTEPTR p;
  #else
    CCP_DAQBYTEPTR p;
  #endif
  #ifdef CCP_ODT_ENTRY_SIZE
    CCP_BYTE s;
    CCP_BYTE *d,*dl;
    ccpOdtEntry_t *e,*el;
  #else
    CCP_BYTE i;
    ccpOdtEntry_t *e;
  #endif

  /* PID */
  dtm[0] = pid;

  /* Assure data consistency */
  CCP_DISABLE_INTERRUPT;

  /* Sample */
  #ifdef CCP_ODT_ENTRY_SIZE

    e = &ccp.DaqList[daq].odt[odt][0];
    el = e+8;
    d = &dtm[1];
    dl = d+7;
    while (d<dl && e<el && e->ptr) {
      #ifdef CCP_DAQ_BASE_ADDR
        p = (CCP_BYTEPTR)( e->ptr ) + CCP_DAQ_BASE_ADDR;
      #else
        p = e->ptr;
      #endif
      s = e->siz;
      #ifdef CCP_DOUBLE_FLOAT
        if (s==8) {
           *(float*)d = (float)(*(double*)p);
          s = 4;
          #ifdef CCP_TESTMODE
           if (gDebugLevel>=2) CCPPRINT("[ccpSampleAndTransmitDtm] conversion -> float %g\n",*(float*)d);
          #endif
        } else
      #endif
      if (s==4) {
        *(CCP_DWORD*)d = *(CCP_DWORD*)p;
      } else if (s==2) {
        *(CCP_WORD*)d = *(CCP_WORD*)p;
      } else {
        *d = *p;
      }
      d += s;
      e++;
    }

  #else

    e =  &ccp.DaqList[daq].odt[odt][0];
    for (i=1;i<8;i++) {
      #ifdef CCP_DAQ_BASE_ADDR
        p = (CCP_BYTEPTR)( (e++)->ptr ) + CCP_DAQ_BASE_ADDR;
      #else
        p = (e++)->ptr;
      #endif
      if (p) dtm[i] = *p;
    }

  #endif

  /* Optional for CANape: Put a timestamp in the first ODT (Byte6+7) of each DAQ */
  #ifdef CCP_TIMESTAMPING
    if (odt==0) {
      *(CCP_WORD*)&dtm[6] = ccpGetTimestamp();
    }
  #endif

  /* Queue or transmit the DTM */
  #ifdef CCP_SEND_QUEUE

    if (ccp.SendStatus&CCP_SEND_PENDING) {
      if (!ccpQueueWrite((ccpMsg_t*)dtm)) {
        /* Overun */
        CCP_ENABLE_INTERRUPT;
        return 0;
      }
    } else {
      ccp.SendStatus |= CCP_DTM_PENDING;
      ccpSend(dtm);
    }

  #else

    if (ccp.SendStatus&CCP_DTM_REQUEST) {
      /* Overun */
      CCP_ENABLE_INTERRUPT;
      return 0;
    }
    if (ccp.SendStatus&CCP_SEND_PENDING) {
      ccp.SendStatus |= CCP_DTM_REQUEST;
    } else {
      ccp.SendStatus |= CCP_DTM_PENDING;
      ccpSend(dtm);
    }

  #endif

  CCP_ENABLE_INTERRUPT;
  return 1;

}


#else


/* Sample and transmit the next DTM in SEND_SINGLE mode */
static void ccpSampleAndSendNextDtm( void ) {

  CCP_BYTE i,j;
  CCP_DAQBYTEPTR p;
  ccpOdtEntry_t *e;

  /* Request for DTM transmission pending */
  if (ccp.SendStatus&CCP_DTM_REQUEST) return;

  /* Find a DAQ list marked for transmission */
  for (i=0;i<CCP_MAX_DAQ;i++) {

    if (ccp.DaqList[ccp.CurrentDaq].flags&DAQ_FLAG_SEND) {

      /* PID */
      ccp.Dtm[0] = ccp.CurrentDaq*CCP_MAX_ODT+ccp.CurrentOdt;

      /* Sample */
      e =  &ccp.DaqList[ccp.CurrentDaq].odt[ccp.CurrentOdt][0];
      for (j=1;j<8;j++) {
        p = (e++)->ptr;
        if (p) ccp.Dtm[j] = *p;
      }

      /* Send */
      ccpSendDtm();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -