/**
* \file INCAN16X.C
*
* \author Axel Wolf, SCI Cupertino
* \author Dr. Jens Barrenscheen, HL MC PD, Munich
* \author Hubert Piontek, University of Ulm
*
* Routine for initializing the CAN module of the C166
*
* Most of this is based von the Infineon/Siemens Application Note AP2922.
* Some additions made at University of Ulm, February 2003.
*
* This CAN driver is mainly meant to be used by the publisher/subscriber
* library developed at the University of Ulm, 1999-2003.
*/
/*********************************************************************
* Program name: "INCAN16X.C" *
* Compiler used: BSO/Tasking C166 *
* Task: Source File for procedure can_init_16x *
* belonging to Siemens ApNote AP2922 *
* "'C' CAN Driver Routines for the C166 family" *
* *
* Last modifications: April 28nd 1997 *
* Version: 1.0 *
* Authors: Axel Wolf, SCI Cupertino *
* Dr. Jens Barrenscheen, HL MC PD, Munich *
*********************************************************************/
/* ----------------------------------- include files: -------------- */
#include <REG167.H> /* register definitions C167 */
#include <CANR_16X.H> /* CAN control register definitions */
#include <intrins.h>
/**
* \defgroup baudrates Bit Timing values
*/
/*@{*/
/// Bit timing for 50kBit/s
#define BTR_VALUE_50KBAUD 0x7aC9
/// Bit timing for 125kBit/s
#define BTR_VALUE_125KBAUD 0x7aC3
/// Bit timing for 250kBit/s
#define BTR_VALUE_250KBAUD 0x7aC1
/// Bit timing for 500kBit/s
#define BTR_VALUE_500KBAUD 0x7aC0
/// Bit timing for 1MBit/s
#define BTR_VALUE_1MBAUD 0x25c0
/*@}*/
/**
* \defgroup msgsfrs SFRs for the message objects
*/
/*@{*/
/// Message IDs; pointers to the UARs (see C166 manuals)
unsigned int *id_ptr_16x[16];
/// First data bytes
unsigned char *db0_ptr_16x[16];
/// Message Control registers
unsigned int *msgctrl_ptr_16x[16];
/// Message Configuration registers
unsigned char *msgconf_ptr_16x[16];
/*@}*/
/**
* \defgroup globs Global variables for the CAN driver.
*/
/*@{*/
/// Stores the directions (transmit or receive) of all message objects
unsigned char dir_bit_16x[16];
/// Stores the frame format (extended or standard) of all message objects
unsigned char xtd_bit_16x[16];
/// Stores the data length configurations of all message objects
unsigned char dlc_16x[16];
/*@}*/
/**
* This function must be called before any CAN communication can take place. It resets the CAN controller, sets
* the baud rate and enables interrupts (if specified) for errors, status changes, and globally for the CAN controller.
*
* \param baud_rate Baud rate in kBit/s. You can specify 50, 125, 250, 500 or 1000.
* If you specify anything else, the CAN bus will be set to 500kBit/s as a default.
* \param eie Flag whether to enable Error Interrupts (see C166 manuals)
* \param sie Flag whether to enable Status Change Interrupts (see C166 manuals)
* \param ie Flag whether to enable Interrupt propagation from the CAN module to the C166 core
*/
void init_can_16x(unsigned int baud_rate, unsigned char eie,
unsigned char sie, unsigned char ie)
{
unsigned char i, n;
unsigned char *dummy_dbptr;
/* Initialization PORT4 (CAN) (P4.6 to output; P4.5 to input): */
_bfld_ (P4, 0x0060, 0x0060);
_bfld_ (DP4, 0x0060, 0x0040);
/* Load C167 pointers: */
for (i=1;i<16;i++) {
/* set pointers to data bytes 0 of MO 1..15 */
db0_ptr_16x[i] = (unsigned char *)(0xef07+i*16);
/* set pointers to id's of MO 1..15 (UARs) */
id_ptr_16x[i] = (unsigned int *)(0xef02+i*16);
/* set pointers to Message Conf. Registers of MO 1..15 */
msgconf_ptr_16x[i] = (unsigned char *)(0xef06+i*16);
/* set pointers to Message Control Registers of MO 1..15 */
msgctrl_ptr_16x[i] = (unsigned int *)(0xef00+i*16);
dir_bit_16x[i] = 0; /* clear DIR bit array */
xtd_bit_16x[i] = 0; /* clear XTD bit array */
dlc_16x[i] = 0; /* clear data length code array */
}
/* Load General CAN-Registers: */
CR=0x41; /* set CCE and INIT in Control Register (EF00h) */
SR=0x00; /* Clear Status Partition (EF01h) */
switch (baud_rate) {
case 50: BTR=BTR_VALUE_50KBAUD;
break;
case 125: BTR=BTR_VALUE_125KBAUD;
break;
case 250: BTR=BTR_VALUE_250KBAUD;
break;
case 500: BTR=BTR_VALUE_500KBAUD;
break;
case 1000: BTR=BTR_VALUE_1MBAUD;
break;
default: BTR=BTR_VALUE_500KBAUD;
break;
}
/* 0 1 1 1 1 0 1 0 1 1 0 0 0 0 0 0 = 500 kBit/s @ 20MHz */
/* - TSEG2 TSEG1 SJW|<-- BRP -->| */
/* each bit of standard ID must match to store mess. */
GMS=0xe0ff; /* Global Mask Short (EF06h) */
/* each bit of extended ID must match to store mess. */
UGML=0xffff; /* Upper Global Mask Long (EF08h) */
LGML=0xf8ff; /* Lower Global Mask Long (EF0Ah) */
/* every message into MO 15 (Basic CAN Feature)*/
UMLM=0x0000; /* Upper Mask of Last Message (EF0Ch) */
LMLM=0x0000; /* Lower Mask of Last Message (EF0Eh) */
/* reset all elements incl MSGVAL in all Message Object Ctrl. Reg.: */
for (i=1;i<16;i++) *msgctrl_ptr_16x[i] = 0x5555;
/* reset all data bytes in all Message Objects: */
for (i=1;i<16;i++) {
dummy_dbptr=db0_ptr_16x[i];
for (n=0;n<8;n++)
*dummy_dbptr++ = 0x00;
}
/* end initialization (CCE=0, INIT=0); Interrupts EIE, SIE, IE=user: */
CR = (0x00 | (eie<<3) | (sie<<2) | (ie<<1));
}