ARM Technical Support Knowledge Articles


Applies to: C166 C Compiler


Information in this article applies to:


Is there an updated version of CAN167.H that offers better support for the CAN registers in the C167CR?


Yes. It is called CANREGS.H and it is based on the previous version of CAN167.H. The changes are described in a comment at the top of the file. Three sets of new macros for msg_ctl have been added. They are easier to use than the x_MASK macros that were in CAN167.H. (Those macros are still in this file, as well.) Note that CAN_OBJ was deleted in favor of CAN_MSGOBJ.

/* (c) Copyright KEIL ELEKTRONIK GmbH.  1996, All rights reserved. */
/* CAN definitions for C167C                                       */
/* Modified April 1997:   (c) 1997 Keil Software, Inc.
   New macros for msg_ctl.
   Changed CAN_INTID to unsigned char.
   Replaced CAN_OBJ, which should be subscripted with 0-14, with CAN_MSGOBJ,
   which should be subscripted with 1-15, as in the data book.
   Added CAN_CTL and CAN_STAT.
   Added macros for bits in the Control/Status register.

/* Bits in the control portion (low byte) of the CAN control/status register */
#define CAN_INIT_  1
#define CAN_IE_    2
#define CAN_SIE_   4
#define CAN_EIE_   8
#define CAN_CCE_  64
/* Bits in the status portion (high byte) of the CAN control/status register
   These values are for accessing the status byte alone (CAN_STAT).  When
   accessing the full 16-bit control/status register (CAN_CTL_STAT), these
   values should be shifted left 8 bit positions.
#define CAN_LEC_    7
#define CAN_TXOK_   8
#define CAN_RXOK_  16
#define CAN_EWRN_  64
#define CAN_BOFF_ 128

/* Control/Status Register */
#define CAN_CTL_STAT   (*((unsigned int volatile sdata *) 0xEF00))
/* Control portion of Control/Status Register */
#define CAN_CTL        (*((unsigned char volatile sdata *) 0xEF00))
/* Status portion of Control/Status Register */
#define CAN_STAT       (*((unsigned char volatile sdata *) 0xEF01))

/* Interrupt Register
   The high byte is reserved, so only the low byte is read.
#define CAN_INTID      (*((unsigned char volatile sdata *) 0xEF02))

/* Bit Timing Register */
#define CAN_BIT_TIMING (*((unsigned int volatile sdata *) 0xEF04))

/* Global Mask Short */
#define CAN_MASK_SHORT (*((unsigned int volatile sdata *) 0xEF06))
/* Upper Global Mask Long */
#define CAN_UMASK_LONG (*((unsigned int volatile sdata *) 0xEF08))
/* Lower Global Mask Long */
#define CAN_LMASK_LONG (*((unsigned int volatile sdata *) 0xEF0A))
/* Upper Mask of Last Message */
#define CAN_UMASK_LAST (*((unsigned int volatile sdata *) 0xEF0C))
/* Lower Mask of Last Message */
#define CAN_LMASK_LAST (*((unsigned int volatile sdata *) 0xEF0E))

/* Initial values */
/* 1 MBit/s, valid for SILICONIX Si9200DY driver and a short bus 2..3 m */
#define BIT_TIMING              0x2440

/* Masks for testing field 'msg_ctl' of the 15 CAN objects */
/* These are used by reading the message control register of a CAN object,
   then bitwise-ANDing the value read with the appropriate mask.
   if (CAN_MSGOBJ[can_object_number].msg_ctl & NEWDAT_) {
      Actions to take when NEWDAT flag is true go here.
#define INTPND_                 0x0002u
#define RXIE_                   0x0008u
#define TXIE_                   0x0020u
#define MSGVAL_                 0x0080u
#define NEWDAT_                 0x0200u
#define MSGLST_                 0x0800u
#define CPUUPD_                 0x0800u
#define TXRQ_                   0x2000u
#define RMTPND_                 0x8000u

/* Masks for clearing (resetting) flags in field 'msg_ctl' of the 15 CAN objects */
/* To compute the value to write to the message control register of a CAN
   object to change some of its flags, bitwise-and together the appropriate
   macros (Chosen from the various *_CLR and *_SET macros).
   For example, this statement clears (resets) the CPUUPD flag and sets the
   NEWDAT and TXRQ flags, while leaving all the other flags unchanged:
   CAN_MSGOBJ[can_object_number].msg_ctl = CPUUPD_CLR & NEWDAT_SET & TXRQ_SET;
#define INTPND_CLR              (~INTPND_)
#define RXIE_CLR                (~RXIE_)
#define TXIE_CLR                (~TXIE_)
#define MSGVAL_CLR              (~MSGVAL_)
#define NEWDAT_CLR              (~NEWDAT_)
#define MSGLST_CLR              (~MSGLST_)
#define CPUUPD_CLR              (~CPUUPD_)
#define TXRQ_CLR                (~TXRQ_)
#define RMTPND_CLR              (~RMTPND_)

/* Masks for setting flags in field 'msg_ctl' of the 15 CAN objects */
/* See the comments for the preceding set of macros (INTPND_CLR, etc.)
   for explanation.
#define INTPND_SET              (~(INTPND_ >> 1))
#define RXIE_SET                (~(RXIE_ >> 1))
#define TXIE_SET                (~(TXIE_ >> 1))
#define MSGVAL_SET              (~(MSGVAL_ >> 1))
#define NEWDAT_SET              (~(NEWDAT_ >> 1))
#define MSGLST_SET              (~(MSGLST_ >> 1))
#define CPUUPD_SET              (~(CPUUPD_ >> 1))
#define TXRQ_SET                (~(TXRQ_ >> 1))
#define RMTPND_SET              (~(RMTPND_ >> 1))

/* Old Masks for field 'msg_ctl' of the 15 CAN objects */
/* These were defined in previous versions of the C166 tools, but they
   are awkward to use.  They are included for backward compatibility.
   For new programs, we recommend ignoring these and using the preceding
   three sets of macros instead.
#define INTPND_MASK             0x0001
#define RXIE_MASK               0x0004
#define TXIE_MASK               0x0010
#define MSGVAL_MASK             0x0040
#define NEWDAT_MASK             0x0100
#define MSGLST_MASK             0x0400
#define CPUUPD_MASK             0x0400
#define TXRQ_MASK               0x1000
#define RMTPND_MASK             0x4000

/* Masks for field 'msg_cfg' of the 15 CAN objects */
#define XTD_MASK                0x0004
#define DIR_MASK                0x0008

/* Structure for a single CAN object */
/* A total of 15 such object structures exists (starting at EF10H) */
struct can_obj {
  unsigned int  msg_ctl;   /* Message Control       */
  unsigned long arbitr;    /* Arbitration           */
  unsigned char msg_cfg;   /* Message Configuration */
  unsigned char msg[8];    /* Message Data 0 .. 7   */
  unsigned char dummy;     /* Reserved Byte         */

/* The C167 manual numbers the CAN message objects 1...15.  The CAN_MSGOBJ
   macro is designed for this convention.  The first message object is

   Don't use CAN_MSGOBJ[0], because it is not a message object; it is the CAN
   general registers.  Accessing these registers as if they were message objects
   will produce weird, undesirable results.
#define CAN_MSGOBJ ((struct can_obj volatile sdata *) 0xEF00)

Article last edited on: 2004-03-04 16:51:56

Rate this article

Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential