--- In l..., "amit kankaran"
wrote:
>
> Hi all,
>
> I am Having a problem with CAN on LPC2129/01 series.
> Whenever i recieve a CAN frame , the control is not coming out of
ISR,
> but when i reset the CAN controller ,the control is
coming out ,but
> after that i am not able to recieve next CAN frame . if i enable CAN
> controller again in main function ,it is continously switching b/w
ISR
> and main()
> Following is my code
>
> #include
> #define wait 1000000 //count to give delay
> #define OEM_NO *((unsigned long*)0x40003FFC)
> #define IDENTIFIER 0x00010002
>
> #define StandardFilter0 (*((volatile unsigned long *) 0xE0038000))
> #define StandardFilter1 (*((volatile unsigned long *) 0xE0038004))
>
> void CAN1IRQ (void) __attribute__ ((interrupt("IRQ")));
>
> typedef union CAN_DATA{
>
> unsigned char string[8];
> unsigned int two_int[2];
>
> }CAN_DATA;
>
> typedef struct CAN_FRAME
> {
> unsigned long TFI;
> unsigned long ID;
> CAN_DATA Can_Data;
> }CAN_FRAME;
>
> CAN_DATA GSend_OEM_Frame = { {"SND_OEM"} };
> CAN_DATA GSend_IDN_Frame = { {"SND_IDN"} };
> void Decode(CAN_DATA * pData_Frame);
> unsigned int Compare(CAN_DATA* pData_Frame1,CAN_DATA* pData_Frame2);
> void can_init(void);
> void filter(void)
> {
> AFMR = 0x00000001; //Disable the Acceptance
filters to allow setup
> of the table
> StandardFilter0 =0x00010002; //0X10010002;
> StandardFilter1 =0x10031004;//0X10031004;
> SFF_sa = 0x00000000; //Set start address of Standard
table
> SFF_GRP_sa = 0x00000008; //Set start address of
Standard group table
> EFF_sa = 0x00000008; //Set start address of
Extended table
> EFF_GRP_sa = 0x00000008; //Set start address of
Extended group table
> ENDofTable = 0x00000008; //Set end of table
address
> AFMR = 0x00000000; //Enable Acceptance filters
> }
>
> void print(unsigned long int p,unsigned long q)
> {
> int i=0;
> VPBDIV=0x00000002;
> PINSEL0 |= 0x00010001; /* Enable UART TxD0
Txd1 */
> U0LCR = 0x00000083; /* 8 bits, no
Parity, 1
Stop bit */
> U0DLL = 0x000000C2; /* 9600 Baud
Rate @
30MHz VPB Clock */
> U0LCR = 0x00000003; /* DLAB = 0
*/
>
> for (i=0;i<4;i++)
> {
> while (!(U0LSR & 0x20));
> U0THR =p;
> p=p>>8;
> }
> for (i=0;i<4;i++)
> {
> while (!(U0LSR & 0x20));
> U0THR =q;
> q=q>>8;
> }
> C1CMR=0X00000004; // release the
buffer
> }
>
> void delay(void)
> {
> volatile unsigned int i;
> for(i=0;i
> }
>
> void CAN1IRQ(void)
> {
> // CAN_DATA Recieved_can_data;
>
>
>
> // Recieved_can_data.two_int[0] = C1RDA;
> // Recieved_can_data.two_int[1] = C1RDB;
>
> // Decode(&Recieved_can_data);
>
> print(C1RDA,C1RDB);
>
> IO1PIN 0X00000000; // /* Turn on LED
> delay(); // call wait
function
> IO1PIN = 0X00F00000;
// Turn
off LED
> delay();
> IO1PIN = 0X00000000;
>
> C1CMR=0X00000004;
//release the recieve buffer
> VICVectAddr = 0x00000000;
>
> C1MOD = 0x01; // Disable Can Controller
>
> }
> void can2tx(CAN_FRAME* ptr)
> {
> C1MOD = 0x00; // Enable Can
Controller
> while(!(C2SR&0X00000004)); // wait till tx
buffer 1 is free
> C2TFI1=ptr->TFI;
> C2TID1=ptr->ID;
> C2TDA1=ptr->Can_Data.two_int[0];
> C2TDB1=ptr->Can_Data.two_int[1];
>
> C2CMR=0x00000021; //request
transmission
> // print(C2TDA1,C2TDB1);
> }
> void can_init(void)
> {
> C2MODOD=0X00000001;
> C2BTRTR=0X001C001D; //for 125k
bit rate
> PINSEL1=0X00050000; //select
can1 rx and can2 tx
> C1IER=0X00000001;
//enable can1 rx interrupt
> C2MODOD=0X00000000;
> VICVectCntl0=0X00000003A;
> VICVectAddr0=(unsigned)CAN1IRQ; //assign address
of isr to
> vic 0 channel
> VICIntEnable=0X04000000; //enable can1
rx interrupt
> }
>
> CAN_FRAME temp_frame = {0x00080000,IDENTIFIER};
> int main()
> {
> IODIR1=0X00FF0000;
> temp_frame.Can_Data = GSend_OEM_Frame;
> // OEM_NO = 0x000000100;
> can_init();
> filter();
>
> can2tx(&temp_frame);
> while(1)
> {
>
> C1MOD = 0x00; // Enable Can Controller
> IO1PIN = 0x00000000;
> delay();
> IO1PIN = 0x00070000;
> delay();
> }
>
> }
> With Regards,
> Amit Chaudhary
>
A couple of things:
In the /01 parts they have put in the newer CAN controller as used in
the LPC2468, etc. This has an issue when you let the RX buffer
fill ... It locks the CAN controller and you need to do the reset you
mention. (see the LPC2129/01 - Errata v1.0 - 27th July 2007)
Also, this won't be helped by the fact you have put delays in the
interrupt handler !!! You need to do the MINIMUM amount of work in
the handler (i.e. get the message and store it somewhere and set a
flag for the main loop to process this message).
Simon.