Atmel website | ARM Community | AVR freaks | Technical Support
Banner
 FAQ •  Search •  Register •  Login 

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Can't make CAN to recieve messages : AT91SAM7X
PostPosted: Fri Jul 06, 2007 12:50 pm 
Offline

Joined: Tue Oct 10, 2006 9:04 am
Posts: 9
Hi All,

I am trying to make data communication with CAN automobile blocks.
CAN seems does not initialize and I can't recieve data messages.


The system is :
CANBlock -> Philips 82C215 - >ADUM1200 (5V - >3.3V) -> Atmel

AT91SAM7X with 18.432 Mhz, MCK - 48Mhz.

CAN bus speed is: 500Kbp/s

From datasheet and other sources I calculated the CAN Baudrate to be
CAN_BR = 0x53255 (BRP - 5, SJW - 3, PRS - 2, PHS1 - 5, PHS2 - 5)


The initialization steps are following:

1. Cfg PIO - enable PA19 and PA20 pins
2. Cfg CAN PMC - enable clock for CAN
3. AT91F_AIC_ConfigureIt - enalbe interrups for CAN.
4. Set baudrate - CAN_BR = 0x53255;
5. Enable CAN_WAKEUP interrupt
6. Turn on CAN - CAN_MR = CANEN;
7. Wait for CAN_WAKEUP interrupt !!

comes on,! but same time the status register
has AT91C_CAN_ERRA bit set, why?

8. Enable MB0 intterupt and Initialize Mailbox 0 with MIDvA = 0x110, etc.
wait for data. !

Stuck!. no data! :(


BUT, CAN block repeatedely sends messages on the bus, this is verified
with other USB-CAN adapter.

I have checked with oscillograph, the CAN bus signal is correct at
PA19 pin of Atmel.

What is wrong here?


Please help.
I can paste the C code also.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 06, 2007 1:09 pm 
Offline

Joined: Mon May 02, 2005 12:17 pm
Posts: 137
Location: Germany
Hi hzn,

last week i posted a can sample which does exactly what you want!!!

http://www.at91.com/phpbb/viewtopic.php?t=3405

Forget ERRA, this only shows that your CAN is now in Error Active Mode. That's no error (read in PDFl...)!! Your speed config is OK, just compare the rest with the sample and it should work.

HTH,
GSNT


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 06, 2007 1:58 pm 
Offline

Joined: Mon May 02, 2005 12:17 pm
Posts: 137
Location: Germany
BTW:

if you set your ID to zero, the mailbox is receiving everything...

Code:
//mailbox 2
AT91C_BASE_CAN->CAN_MB2.CAN_MB_MID=0x000<<18;   //11 bit Part A ID
AT91C_BASE_CAN->CAN_MB2.CAN_MB_MAM=0x00000000;   //accept all
AT91C_BASE_CAN->CAN_MB2.CAN_MB_MMR=0x02<<24;   //receice/over 


if you are listening to automotive CAN use ABM , so you don't acknowledge incoming messages.

Code:
AT91C_BASE_CAN->CAN_MR = AT91C_CAN_ABM | AT91C_CAN_CANEN;      


and last not least: set your mailbox before enabling interrupts.

HTH,
GSNT


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 06, 2007 10:17 pm 
Offline

Joined: Tue Oct 10, 2006 9:04 am
Posts: 9
Thanks GSNT for good points, and quick reply... But I still have no luck ....
Review the code please ...


Code:
   

      // Enable CAN PIOs
      AT91F_CAN_CfgPIO();

      // Enable CAN Clock
      AT91F_CAN_CfgPMC();

      // Init CAN Interrupt Source Level
      AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,       // CAN base address
         AT91C_ID_CAN,                            // CAN ID
         AT91C_AIC_PRIOR_HIGHEST,                  // Max priority
         AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,        // Level sensitive
         AT91F_CAN_Handler);                     // C Handler

      AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_CAN);

      // Set Baudrate
      AT91F_CAN_CfgBaudrateReg(AT91C_BASE_CAN,  0x53255); // 500kbs

      //////////////////////////////////////////////////////////////
      unsigned int tick=0;

      //////////////////////////////////////////////////////////////
      // Enable WakeUp Interrupt
      AT91F_CAN_EnableIt(AT91C_BASE_CAN, AT91C_CAN_WAKEUP);


      ///////////////////////////////////////////////////////////////
      // Configure Mailbox0, RX
      AT91F_InitMailboxRegisters(AT91C_BASE_CAN_MB0,
         AT91C_CAN_MOT_RXOVERWRITE,         // Mailbox Mode Reg
         0x000 << 18,                   // Mailbox Acceptance Mask Reg
         0x000 << 18,                    // Mailbox ID Reg
         0x00000000,                        // Mailbox Data Low Reg
         0x00000000,                        // Mailbox Data High Reg
         0x00000000);                       // Mailbox Control Reg



      // Enable Reception Mailbox 0 interrupt
      AT91F_CAN_EnableIt(AT91C_BASE_CAN, AT91C_CAN_MB0);

      // Enable CAN
      AT91F_CAN_CfgModeReg(AT91C_BASE_CAN, AT91C_CAN_CANEN|AT91C_CAN_ABM);

      // Wait for WAKEUP flag raising
      ......

      while(1); // recieve data forever
      



the interrupt handler:

Code:
   void AT91F_CAN_Handler(void)
   {
      volatile unsigned int status;
      
      status = AT91F_CAN_GetStatus(AT91C_BASE_CAN);
      status &= AT91F_CAN_GetInterruptMaskStatus(AT91C_BASE_CAN);
      
      if(status & AT91C_CAN_WAKEUP) {
         AT91F_CAN_DisableIt(AT91C_BASE_CAN,status);
         TRACE("\n\r=> CAN WAKEUP ");
          ... set some flag
      }
      
      if(status & AT91C_CAN_MB0) {
         TRACE("\n\r=> CAN MB0 Interrupt");
      }
   }


And I never get MB0 interrupt call...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 06, 2007 11:34 pm 
Offline

Joined: Mon May 02, 2005 12:17 pm
Posts: 137
Location: Germany
Oh MAN!!!

You're driving me crazy with all this LIB stuff!!

If you compare it with my (working) code, you can see that your int-handler is reading the SR register to check for received messages.
But my sample is checking the Mailbox-MSR register ?????????

Code:
//new data  in mailbox 2?
if(AT91C_BASE_CAN->CAN_MB2.CAN_MB_MSR & AT91C_CAN_MRDY)



Don't know why I did that, but can't be wrong. Try it and let me know. I'll test it, too.

HTH,
GSNT


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 07, 2007 4:49 am 
Offline

Joined: Mon May 02, 2005 12:17 pm
Posts: 137
Location: Germany
Hi hzn,

after crawling deep into your lib stuff now i know you're right! Your code isn't working.

1. If you compare it with my sample:
You can read CAN_SR or CAN_MSRx to detect a new message. But you have always to trigger a new reception with MTCR. Without this trigger the reception is not completed and Message Ready (MRDY) is not cleared.

Code:
//AT91C_BASE_CAN->CAN_MB2.CAN_MB_MCR =AT91C_CAN_MTCR;


Quote:
Datasheet:

37.7.3.1 Receive Handling
...
Message data are stored in the mailbox data register until the software application notifies that data processing has ended. This is done by asking for a new transfer command, setting the MTCR flag in the CAN_MCRx register. This automatically clears the MRDY signal.


2. If your CAN is initialized and receives messages at the same time your

Code:
if(status & AT91C_CAN_WAKEUP) {
         AT91F_CAN_DisableIt(AT91C_BASE_CAN,status);


could get WAKEUP and MBx after enabling and then disable them both again. Disabling just AT91C_CAN_WAKEUP should solve this.

HTH,
GSNT


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 07, 2007 7:16 am 
Offline

Joined: Tue Oct 10, 2006 9:04 am
Posts: 9
THanks again,

1. I do aggree, and I was doing something similar
Code:
AT91C_BASE_CAN->CAN_TCR = AT91C_CAN_MB0;


2. Agree, but still I was seeing by tracing the value of status variable,
that MB0 bit was zero, when wakeup was triggered.

I did changed that as you pointed.


Stilll no luck....

One more thing, I will rewrite the code with no lib calls...


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 07, 2007 7:48 am 
Offline

Joined: Tue Oct 10, 2006 9:04 am
Posts: 9
The same code without lib calls

Code:
// Enable CAN PIOs
AT91C_BASE_PIOA->PIO_ASR = AT91C_PA19_CANRX|AT91C_PA20_CANTX;
AT91C_BASE_PIOA->PIO_PDR = AT91C_PA19_CANRX|AT91C_PA20_CANTX;

// Enable CAN Clock
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_CAN;

// Init CAN Interrupt
AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_CAN;
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_CAN] = 0x7;
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_CAN] = (unsigned int) CAN_Handler;

AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_CAN;
AT91C_BASE_AIC->AIC_ICCR = 1 << AT91C_ID_CAN;

// Set baudrate
AT91C_BASE_CAN->CAN_BR = 0x53255; // 500kbs

// Enable WakeUp Interrupt
AT91C_BASE_CAN->CAN_IER = AT91C_CAN_WAKEUP;

// Configure Mailbox 0, RX
AT91C_BASE_CAN_MB0->CAN_MB_MCR    = 0x0;
AT91C_BASE_CAN_MB0->CAN_MB_MMR    = 0x2 << 24; // RX with ovr
AT91C_BASE_CAN_MB0->CAN_MB_MAM    = 0x000 << 18;
AT91C_BASE_CAN_MB0->CAN_MB_MID    = 0x000 << 18;
AT91C_BASE_CAN_MB0->CAN_MB_MDL    = 0;       
AT91C_BASE_CAN_MB0->CAN_MB_MDH    = 0;

// Enable Reception Mailbox 0 interrupt
AT91C_BASE_CAN->CAN_IER = AT91C_CAN_MB0;

// Clear and trigger Transfer
AT91C_BASE_CAN->CAN_TCR = AT91C_CAN_MB0;
AT91C_BASE_CAN->CAN_MB0.CAN_MB_MCR = AT91C_CAN_MTCR;

// Enable CAN
AT91C_BASE_CAN->CAN_MR = AT91C_CAN_CANEN|AT91C_CAN_ABM;


Still does not work...


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 07, 2007 9:17 am 
Offline

Joined: Mon May 02, 2005 12:17 pm
Posts: 137
Location: Germany
Hmmmmmmmm...

...checked your code, it's working without WAKEUP-INT (=different int-handler)

Code:
// Enable WakeUp Interrupt
AT91C_BASE_CAN->CAN_IER = AT91C_CAN_WAKEUP;



Please post your complete INT-handler and i'll check it ,too.


HTH,
GSNT


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 07, 2007 2:15 pm 
Offline

Joined: Tue Oct 10, 2006 9:04 am
Posts: 9
Code:
#define CAN_TIMEOUT       1000000

volatile char           flagCAN = 0;


ok, here is the handler
Code:

void CAN_Handler(void)
{
   volatile unsigned int status;
   
   status = AT91C_BASE_CAN->CAN_SR;
   
   TRACE("\n\r=> INT: %X ", status);
   
   status &= AT91C_BASE_CAN->CAN_IMR;
   
   if(status & AT91C_CAN_WAKEUP) {
      AT91C_BASE_CAN->CAN_IDR = AT91C_CAN_WAKEUP;
      TRACE("\n\r=> CAN WAKEUP ");
      flagCAN = 1;
      
   }
   
   if(status & AT91C_CAN_MB0) {
      TRACE("\n\r=> CAN MB0 Interrupt");
      AT91C_BASE_CAN->CAN_MB0.CAN_MB_MCR = AT91C_CAN_MTCR;
   }
}




and the part that chekss the flag
Code:

   // Wait for WAKEUP flag
   unsigned int tick = 0;
   while( (flagCAN != 1) && (++tick < CAN_TIMEOUT) ) ;
   
   if (tick >= CAN_TIMEOUT)
      TRACE_ERROR("\n\r-E- CAN Initialisation FAILED !\n\r");
   else
      TRACE("\n\r-I- CAN Initialisation Completed !\n\r");



Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 07, 2007 2:31 pm 
Offline

Joined: Mon May 02, 2005 12:17 pm
Posts: 137
Location: Germany
Your Handler is working!!!

So are you really shure, that your hardware is working?
What CAN are you listening to?

HTH,
GSNT


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 07, 2007 3:39 pm 
Offline

Joined: Tue Oct 10, 2006 9:04 am
Posts: 9
hmmmm.,.... I dont' know what to say.

I have High speed CAN. 2.0A

Anyhow Thank you Gerd!, now I can be sure that ATMEL is correctly cofigured.
I was not sure before this.


I guess i have to check the hardware again and again.

Thanks once more...


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 07, 2007 4:13 pm 
Offline

Joined: Mon May 02, 2005 12:17 pm
Posts: 137
Location: Germany
Hmmmmmmmmmm..............

Please describe your exact problem again. If it's initializing correct, the CAN-controller should work. The SR should help you out. If there's no MDx event, it's time to check the transceiver (delivering a RX-Signal?) and CAN-connection (terminator / CANH-/CANL- lines, CAN-Speed).
If there is a lot of traffic try to reduce it to a few messages /sec. If you are not shure if your debug /display routine is fast enough, use some old fashioned LED's.
What about your (commercial?) board (MCK=48MHz)?

A lot of stupid questions, I know. But sometimes a good start to check and check and check.........


HTH,
GSNT


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 07, 2007 5:06 pm 
Offline

Joined: Tue Oct 10, 2006 9:04 am
Posts: 9
Thanks

the behavior is following,
I always get WAKEUP int, either the CAN is connected or not. This is strange.

I do not get any MBx event at all.

RE: schematic is that between CAN-H CAN-L I have 120 om resistance.


The board is commercial Argussoft test board.
The external oscillator is 18.432 Mhz.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 07, 2007 5:29 pm 
Offline

Joined: Mon May 02, 2005 12:17 pm
Posts: 137
Location: Germany
WAKEUP just shows you that the CAN-controller is working, connected or not. If there's no MBx event (and of course the program isn'nt stuck) the controller seems to get no message. So check your CANRX-Pin. If you can scope a signal there without MBx event check your CAN-transmitter (really transmitting 500 Kbit/s, CAN 2.0A = 11bit ID??).

HTH,
GSNT


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: