boot_can.c

来自「ccp」· C语言 代码 · 共 199 行

C
199
字号
/*******************************************************************************

  File Name   : boot_can.c
  Date        : 14.08.2001
  Version     : 1.0
  Desciption  : free CAN driver for CCP without using interrupts

*******************************************************************************/


// -----------------------------------------------------------------------------
// INCLUDE FILES
// -----------------------------------------------------------------------------
#include <iod60.h>               // standard HC12 IO
#include "ccppar.h"              // CPP config file
#include "boot_can.h"            // CAN driver
// -----------------------------------------------------------------------------


// -----------------------------------------------------------------------------
// DEFINES
// -----------------------------------------------------------------------------

#define CAN_BTR0         0x0043         // CAN-Bus-Timing
#define CAN_BTR1         0x0014         // 500 KBaud

#define SYNCH            0x0010         // SYNCH-Bit
#define RXF              0x0001         // receive buffer
#define TXE0             0x0001         // transmit buffer 0

#define REG_BLOCK_ADR    0x0000         // address of register block
#define REG_BLOCK_OFFSET 0x0100         // offset to CAN register

#define msCAN12 (*((t_msCAN12*)(REG_BLOCK_ADR + REG_BLOCK_OFFSET)))
// -----------------------------------------------------------------------------




// -----------------------------------------------------------------------------
// VARIABLES and Structs
// -----------------------------------------------------------------------------
unsigned int g_ccp_dto_id;              // global DTO-ID
unsigned int g_ccp_cro_id;              // global CRO-ID

typedef volatile struct
{
   WORD  Id;              // ID
   BYTE  IdEx1;           // Extended ID bytes; not used
   BYTE  IdEx2;
   BYTE  DataFld[8];      // Data 0 .. 7
   BYTE  DLC;             // Data length reg.:  X X X X DLC3 DLC2 DLC1 DLC0
   BYTE  PRIO;            // TxBuf priority reg.
   BYTE  unused[2];
} t_MsgObject;


typedef volatile struct
{
  BYTE      CMCR0;        // 0 0 CSWAI SYNCH TLNKEN SLPAK SLPRQ SFTRES
  BYTE      CMCR1;        // 0 0 0 0 0 LOOPB WUPM CLKSRC
  BYTE      CBTR0;        // SJW1 SJW0 BRP5 ... BRP0
  BYTE      CBTR1;        // SAMP TSEG22 TSEG21 TSEG20 TSEG13 ... TSEG10
  BYTE      CRFLG;        // WUPIF RWRNIF TWRNIF RERRIF TERRIF BOFFIF OVRIF RXF
  BYTE      CRIER;        // WUPIE RWRNIE TWRNIE RERRIE TERRIE BOFFIE OVRIE RXE
  BYTE      CTFLG;        // 0 ABTAK2 ABTAK1 ABTAK0 0 TXE2 TXE1 TXE0
  BYTE      CTCR;         // 0 ABTRQ2 ABTRQ1 ABTRQ0 0 TXEIE2 TXEIE1 TXEIE0
  BYTE      CIDAC;        // 0 0 IDAM1 IDAM0 0 0 IDHIT1 IDHIT0
  BYTE      reserved1[5];
  BYTE      CRXERR;       // RXERR7 ... RXERR0
  BYTE      CTXERR;       // TXERR7 ... TXERR0
  BYTE      CIDAR0;       // Filter Masks 0..3
  BYTE      CIDAR1;
  BYTE      CIDAR2;
  BYTE      CIDAR3;
  BYTE      CIDMR0;
  BYTE      CIDMR1;
  BYTE      CIDMR2;
  BYTE      CIDMR3;
  BYTE      CIDAR4;       // Filter Masks 4..7
  BYTE      CIDAR5;
  BYTE      CIDAR6;
  BYTE      CIDAR7;
  BYTE      CIDMR4;
  BYTE      CIDMR5;
  BYTE      CIDMR6;
  BYTE      CIDMR7;
  BYTE      reserved2[29];
  BYTE      PCTLCAN;      // 0 0 0 0 0 0 PUECAN
  BYTE      PORTCAN;      // PCAN7 ... PCAN0
  BYTE      DDRCAN;       // DDRCAN7 ... DDRCAN0
  t_MsgObject   RxBuf;    // Rx-Msg Object
  t_MsgObject   TxBuf[3]; // Tx-Msg Objects
} t_msCAN12;
/* STOPSINGLE_OF_MULTIPLE */

// -----------------------------------------------------------------------------



// -----------------------------------------------------------------------------
// CAN INITIALISATION
// -----------------------------------------------------------------------------
void ccpBootInit (int cro_id, int dto_id)
{
  g_ccp_dto_id = dto_id;       // handover IDs (CRO, DTO)
  g_ccp_cro_id = cro_id;

  msCAN12.CMCR0  |= 0x01;      // enter soft reset state
  msCAN12.CMCR1  |= 0x01;      // set timing reg.
  msCAN12.CBTR0  = CAN_BTR0;   // baud rate
  msCAN12.CBTR1  = CAN_BTR1;
  msCAN12.CRIER  = 0x00;       // disable receive interrupt
  msCAN12.CIDAC  = 0x00;       // set filter, twice 32-bit
  msCAN12.CIDAR0 = 0x00;       // set ID acceptance register 0..3
  msCAN12.CIDAR1 = 0x00;
  msCAN12.CIDAR2 = 0x00;
  msCAN12.CIDAR3 = 0x00;
  msCAN12.CIDMR0 = 0xFF;       // filter full open
  msCAN12.CIDMR1 = 0xFF;
  msCAN12.CIDMR2 = 0xFF;
  msCAN12.CIDMR3 = 0xFF;
  msCAN12.CIDAR4 = 0x00;       // set ID acceptance register 4..7
  msCAN12.CIDAR5 = 0x00;
  msCAN12.CIDAR6 = 0x00;
  msCAN12.CIDAR7 = 0x00;
  msCAN12.CIDMR4 = 0xFF;       // filter full open
  msCAN12.CIDMR5 = 0xFF;
  msCAN12.CIDMR6 = 0xFF;;
  msCAN12.CIDMR7 = 0xFF;
  msCAN12.CTCR  &= 0x00;       // and disable appropriate TX-interrupt
  msCAN12.CMCR0 &= 0xFE;       // quit soft reset mode, clear bit 0
// -----------------------------------------------------------------------------
} /* ccpBootInit */




// -----------------------------------------------------------------------------
// CAN TRANSMIT (Data Frame)
// -----------------------------------------------------------------------------
int ccpBootTransmitCrmPossible( void ) {

  return ((msCAN12.CTFLG & TXE0) == 1);        // return 1 if so
}
// -----------------------------------------------------------------------------
void ccpBootTransmitCrm (unsigned char *msg)
{
   if ((msCAN12.CMCR0 & SYNCH) == 0)return;    // check if bus is snychronized
   if ((msCAN12.CTFLG & TXE0) == 0) return;    // check if buffer is empty

   msCAN12.TxBuf[0].Id = (g_ccp_dto_id<<5);    // convert id for id register

   msCAN12.TxBuf[0].PRIO = 0;                  // priority high!
   msCAN12.TxBuf[0].DLC  = 8;                  // data length 8 byte
   msCAN12.TxBuf[0].DataFld[0] = *msg++;       // store message
   msCAN12.TxBuf[0].DataFld[1] = *msg++;
   msCAN12.TxBuf[0].DataFld[2] = *msg++;
   msCAN12.TxBuf[0].DataFld[3] = *msg++;
   msCAN12.TxBuf[0].DataFld[4] = *msg++;
   msCAN12.TxBuf[0].DataFld[5] = *msg++;
   msCAN12.TxBuf[0].DataFld[6] = *msg++;
   msCAN12.TxBuf[0].DataFld[7] = *msg++;

   msCAN12.CTFLG = TXE0;                       // signal for hc12 to send buffer_0

} /* ccpBootTransmitCrm */
// -----------------------------------------------------------------------------



// -----------------------------------------------------------------------------
// CAN RECEIVE (Data Frame)
// -----------------------------------------------------------------------------
int ccpBootReceiveCro (unsigned char *msg)
{
  WORD id;

  if ((msCAN12.CRFLG & RXF) == 0) return 0;    // check if receive buffer is full

  id = msCAN12.RxBuf.Id >> 5;

  *msg++ = msCAN12.RxBuf.DataFld[0];           // store received message in buffer
  *msg++ = msCAN12.RxBuf.DataFld[1];
  *msg++ = msCAN12.RxBuf.DataFld[2];
  *msg++ = msCAN12.RxBuf.DataFld[3];
  *msg++ = msCAN12.RxBuf.DataFld[4];
  *msg++ = msCAN12.RxBuf.DataFld[5];
  *msg++ = msCAN12.RxBuf.DataFld[6];
  *msg++ = msCAN12.RxBuf.DataFld[7];

  msCAN12.CRFLG = RXF;                         // signal for hc12 to release buffer

  if (id == g_ccp_cro_id) return 1;            // if correctly received, return 1
  return 0;

} /* ccpBootReceiveCro */
// -----------------------------------------------------------------------------

⌨️ 快捷键说明

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