EmbeddedRelated.com
Forums

CANbus initialization --> C167CR (Infineon)

Started by Howard March 23, 2004
Hello.

We are currently having a school project, which involves using the
built-in CAN-module in the C167CR �C from Infineon.

But we're having trouble already at the stage of initializing the
CAN-module.

The initialization is done by using the higher-level functions from
Infineon, given in appnote AP2922.

Problem starts at this code-line, where the program halts (in the
CANinit-function):

init_can_16x(MY_BAUD_RATE, EIE_BIT, SIE_BIT, IE_BIT);

We have tried:

- using direct numbers instead of variables in the function
init_can_16x.
- using low-level language to implement this CAN init procedure.
- manually setting the INIT- and CCE-bit in the CAN Control Register
(Though we are pretty sure that this is handed by the routines from
Infineon. But it is actually not mentioned by any words in the
appnote).

The compiler used is the Tasking EDE - and we have doublechecked that
we've marked the option for including the CAN-library.

Code given below.

We are relying on your help �

Thanks.

Howard






/************************************************/
/*		MAIN PROGRAM				*/
/************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <reg167.h>
#include <canr_16x.h>					/* CAN registers 									*/
#include <can_ext.h>					/* CAN function prototypes							*/


void can_init(void);					/* Prototype */


								/* Interrupts from CAN mod. (CPU side) = no				*/
#define MY_XP0IC_VALUE		0x00	
 								/* XP0IE = 0; ILVL = 0; GL = 0						*/
								
#define MY_BAUD_RATE		50			/* 50 kbit/s on the CAN bus (legal:
50,125,250,500,1000)		*/
#define IE_BIT			0			/* no interrupts from CAN module						*/
#define EIE_BIT			0	    		/* no error interrupts from the CAN
module				*/
#define SIE_BIT			0			/* no status interrupts from the CAN
module				*/

								/* Specify Message Object (MO) Features					*/
								/* (RF=Remote Frame, DF = Data Frame)					*/

								/* MO1 - Send Object                      				*/

#define MO1_XTD_BIT		0			/* MO1 uses 11 bit ID								*/
#define MO1_ID			0x204			/* 11-bit identifier of MO1							*/
#define MO1_DIR_BIT		1			/* MO1 transmits DF, receives RF						*/
#define MO1_DLC			8			/* MO1 data length = 8 bytes							*/
#define MO1_TXIE_BIT		0			/* MO1 gen. no transmit interrupts						*/
#define MO1_RXIE_BIT		0			/* MO1 gen. no receive interrupts						*/

								/* MO2 - Receive Object   							*/

#define MO2_XTD_BIT		0			/* MO2 uses 11 bit ID								*/
#define MO2_ID			0x205			/* 11-bit identifier of MO2							*/
#define MO2_DIR_BIT		0			/* MO2 receives DF, transmits RF						*/
#define MO2_DLC			8			/* MO2 data length = 8 byte							*/
#define MO2_TXIE_BIT		0			/* MO2 gen. no transmit interrupts						*/
#define MO2_RXIE_BIT		0			/* MO2 gen. no receive interrupts						*/



void main(void)
{
	unsigned char upload_data_buf[8] =  { 0, 1, 2, 3, 4, 5, 6, 7 };

	can_init();

	while(1)
	{
		ld_modata_16x(1, upload_data_buf);						
		send_mo_16x(1);				/* Send message object 1 */
	}
}



/****************************************************************************************
|*
|*	FUNCTION:		can_init
|*
|*	RETURN VALUE:	non
|*
|*	DESCRIPTION:	initialize the CAN bus
|*			
*****************************************************************************************/

void can_init(void)
{
	unsigned char upload_data_buf[8] =  { 0, 1, 2, 3, 4, 5, 6, 7 };
	unsigned long i=0;

	init_can_16x(MY_BAUD_RATE, EIE_BIT, SIE_BIT, IE_BIT);
	
	def_mo_16x(1, MO1_XTD_BIT, MO1_ID, MO1_DIR_BIT, MO1_DLC,
MO1_TXIE_BIT, MO1_RXIE_BIT);
	def_mo_16x(2, MO2_XTD_BIT, MO2_ID, MO2_DIR_BIT, MO2_DLC,
MO2_TXIE_BIT, MO2_RXIE_BIT);

	XP0IC=MY_XP0IC_VALUE;		      	/* load CAN-Module Interrupt
Register					*/

	IEN = 1;			   			/* global interrupt enable 							*/
}
>Problem starts at this code-line, where the program halts (in the >CANinit-function): > >init_can_16x(MY_BAUD_RATE, EIE_BIT, SIE_BIT, IE_BIT); >
Where is it halting in the function? What does the function prototype you are using for it look like?
garykato@aol.com (Gary Kato) wrote in message news:<20040323121748.26926.00000242@mb-m21.aol.com>...
> >Problem starts at this code-line, where the program halts (in the > >CANinit-function): > > > >init_can_16x(MY_BAUD_RATE, EIE_BIT, SIE_BIT, IE_BIT); > > > > Where is it halting in the function? What does the function prototype you are > using for it look like?
yes, sorry I forgot. the prototype for the function is given like this (in the can_ext.h): extern _USMLIB void init_can_16x( unsigned int baud_rate, unsigned char eie, unsigned char sie, unsigned char ie ); And the actual implementation of the function is given like this (INCAN16X.c from Infineon, included in the appnote 2992): /* ----------------------------------------- header: ----------------*/ /********************************************************************* * 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 */ #define BTR_VALUE_50KBAUD 0x7aC9 #define BTR_VALUE_125KBAUD 0x7aC3 #define BTR_VALUE_250KBAUD 0x7aC1 #define BTR_VALUE_500KBAUD 0x7aC0 #define BTR_VALUE_1MBAUD 0x25c0 /* ----------------------------------- externals, prototypes: ------ */ void init_can_16x(unsigned int baud_rate, unsigned char eie, unsigned char sie, unsigned char ie); /* Initialization of CAN-Module: (baud_rate, eie, sie, ie) */ /* ----------------------------------- PEC, Register: -------------- */ /* ----------------------------------- global bit/byte/word data: -- */ #pragma global /* C167CR variables: */ unsigned int *id_ptr_16x[16]; /* pointer to message id's (UAReg) */ unsigned char *db0_ptr_16x[16]; /* pointer to 'databyte 0's */ unsigned int *msgctrl_ptr_16x[16]; /* pointer to msg. contrl. regs */ unsigned char *msgconf_ptr_16x[16]; /* pointer to msg. conf. regs */ unsigned char dir_bit_16x[16]; /* DIR bits MO 1...15 */ unsigned char xtd_bit_16x[16]; /* XTD bits MO 1...15 */ unsigned char dlc_16x[16]; /* data byte lengths MO 1...15 */ #pragma public /* ----------------------------------- code ------------------------ */ void init_can_16x(unsigned int baud_rate, unsigned char eie, unsigned char sie, unsigned char ie) /* Initialization of CAN-Module: (baud rate, eie, sie, ie) */ { /* -------------------------------- local byte/word/bit data: -- */ unsigned char i, n; unsigned char *dummy_dbptr; /* -------------------------------- program: -------------------- */ /* 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++) { db0_ptr_16x[i] = (unsigned char *)(0xef07+i*16); /* set pointers to data bytes 0 of MO 1..15 */ id_ptr_16x[i] = (unsigned int *)(0xef02+i*16); /* set pointers to id's of MO 1..15 (UARs) */ msgconf_ptr_16x[i] = (unsigned char *)(0xef06+i*16); /* set pointers to Message Conf. Registers of MO 1..15 */ msgctrl_ptr_16x[i] = (unsigned int *)(0xef00+i*16); /* set pointers to Message Control Registers of MO 1..15 */ 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 -->| */ } GMS=0xe0ff; /* Global Mask Short (EF06h) */ /* each bit of standard ID must match to store mess. */ UGML=0xffff; /* Upper Global Mask Long (EF08h) */ LGML=0xf8ff; /* Lower Global Mask Long (EF0Ah) */ /* each bit of extended ID must match to store mess. */ UMLM=0x0000; /* Upper Mask of Last Message (EF0Ch) */ LMLM=0x0000; /* Lower Mask of Last Message (EF0Eh) */ /* every message into MO 15 (Basic CAN Feature)*/ /* 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)); } The debugger included in Tasking shows normal execution, but "manually" debugging (using a LED to indicate) shows that the function halts at the following codeline: msgctrl_ptr_16x[i] = (unsigned int *)(0xef00+i*16); /* set pointers to Message Control Registers of MO 1..15 */ This is in the part where the C167 pointers are loaded. I would be grateful for any help. Howard
>The debugger included in Tasking shows normal execution, but >"manually" debugging (using a LED to indicate) shows that the function >halts at the following codeline: > > msgctrl_ptr_16x[i] = (unsigned int *)(0xef00+i*16); /* set >pointers to Message Control Registers of MO 1..15 */
Hmm. Not much has happened at this point. The pins that the CAN Bus Controller use are set to input and output. Then a loop is entered which initializes a bunch of global variables which I assume the CANLIB code will use. Note that the hardware is not touched in this loop. It is only loading global variables with values. If your code is truly stopping at this point, then the problem could possibly be with your linker script (or however you tell the TASKING development code where RAM is). It could be trying to initialize msgctrl_ptr_16x[1] but there's no RAM there so it hangs (on some CPUs you would get a Bus Error indicating that something on the bus is not responding). One thing I would do is to setup your trap vectors so that if such a thing occurs, you could print out a message or light the LED or just loop forever so that you could see which trap is executing.
garykato@aol.com (Gary Kato) wrote in message news:<20040324105911.09495.00000019@mb-m24.aol.com>...
> >The debugger included in Tasking shows normal execution, but > >"manually" debugging (using a LED to indicate) shows that the function > >halts at the following codeline: > > > > msgctrl_ptr_16x[i] = (unsigned int *)(0xef00+i*16); /* set > >pointers to Message Control Registers of MO 1..15 */ > > Hmm. Not much has happened at this point. The pins that the CAN Bus Controller > use are set to input and output. Then a loop is entered which initializes a > bunch of global variables which I assume the CANLIB code will use. Note that > the hardware is not touched in this loop. It is only loading global variables > with values. If your code is truly stopping at this point, then the problem > could possibly be with your linker script (or however you tell the TASKING > development code where RAM is). It could be trying to initialize > msgctrl_ptr_16x[1] but there's no RAM there so it hangs (on some CPUs you would > get a Bus Error indicating that something on the bus is not responding). > > One thing I would do is to setup your trap vectors so that if such a thing > occurs, you could print out a message or light the LED or just loop forever so > that you could see which trap is executing.
Hi. Yes, I've actually thought about something like that myself - that there is not any ram there where msgctrl_ptr_16x[1] is set up to. I have an impression of that C167 is without a CAN-module, while C167CR does have it (I might be wrong, but that is not the point). And the CAN registers are placed at the end of the regular memory/registers, I think I remember. So therefore I thougt I had found the solution when I saw that Tasking was set up with C167 as the cpu, and not the C167CR. I changed this, but it didn't work. I'm not so much into the interrupts in the C167CR. That is; I've read that the processor has three different setups regarding each interrupt. And I only know how to set up the regular interrupt vector and the belonging ISR. But I suppose this is enough to check out what kind of error that is occuring, as you mentioned? Will I then have to set up for every possible happening interrupt? What interrupts are of current interrest? You mentioned a possibly error with the linker script. Is there anything I can do about this? You mean that it depends on the options that I've set in the Tasking environment, so that I have to look over those options one more time? Thank you for your time and help. Howard
>You mentioned a possibly error with the linker script. Is there >anything I can do about this? You mean that it depends on the options >that I've set in the Tasking environment, so that I have to look over >those options one more time? >
Yes. Linker scripts usually allow the user to specify where ROM and RAM are. I don't know how Tasking does this. It could be that you pick C167CR from a menu and it knows where to put everything. Or maybe there is some linker script file that you need to modify. For example, in Microchip's MPLAB development system, I choose which microcontroller I will use, however that is more for how the IDE should display registers. The linker uses a script file that needs to be modified for whatever version of the controller I use. There might be a directory of linker files to match whatever version that is being used. It looks like you want to setup a Trap B interrupt routine to catch things like trying to access non-existent memory, so read up on that. Another thing to do is to look at the assembly language that is generated by your C code to see if the RAM addresses are correct. You should be able to see this in the debugger. You might also see if there is a map file generated when linking. A linker map file shows where the various memory addresses that the linker knows about.
This link might help also. I found it searching Google with keywords: C167CR
TASKING.

http://www.hitex.co.uk/c166/xram.html
garykato@aol.com (Gary Kato) wrote in message news:<20040325061302.16057.00000031@mb-m04.aol.com>...
> This link might help also. I found it searching Google with keywords: C167CR > TASKING. > > http://www.hitex.co.uk/c166/xram.html
Hi again Gary. Sorry for not responding so fast on that last one. We've spent alot of time figuring out what was wrong, and now the solution is here. It's just as you said; something about the memory mapping. It could be seen from the .map-file that the variables (the pointers pointing to the CAN-registers, and where the program halted) were actually placed in ROM. So to put them in RAM we had to define the memory area for the class CNEAR in Tasking, which holds these variables. And now it works. Thank you very much for you help. Best regards from Howard