AnsweredAssumed Answered

MCF51AC256: CAN bus problem - overruns, CANRFLG_RXF never clears

Question asked by Stefan Matting on Feb 22, 2012
Latest reply on Feb 29, 2012 by Stefan Matting

Hello Freescale Forum,
I'm trying to set up CAN communication between a PC and a MCF51AC256 via the the following polling scheme the MCU side.

void main(void) {    int msgs;        setup_clocks();    init_can();    msgs = 0;    for(;;){        /* Is Receiver FIFO not empty? */        if(CANRFLG & 0x1)        {            msgs++;            /* clear CANRFLG_RXF */            CANRFLG = 0x1;         }        __RESET_WATCHDOG();    }}

If I send a message from the PC it is received on the MCU end correctly(!), but CANRFLG_RXF is never cleared and there are overruns. So it looks as if the message is sent all the time (msgs grows). However the message is sent only once from the PC end! Debugging shows CANRXERR == 0x0 all the time, and the Receiver Flag Register CANRFLG always looks like this

CANRLGBit Field Values:    WUPIF     bits[  7:7  ] = 0 No wake-up activity    CSCIF     bits[  6:6  ] = 0 No change    RSTAT     bits[  5:4  ] = 0 RXOK:0less than or equal to RX error CNTless than =96    TSTAT     bits[  3:2  ] = 0 TXOK:0less than or equal to TX error CNTless than =96    OVRIF     bits[  1:1  ] = 1 A data overrun detected    RXF       bits[  0:0  ] = 1 Receiver FIFO not empty   

The configuration of clocks and bit rates _looks_ okay: When I debug the control registers always look like this:

CANCTL0Bit Field Values:    RXFRM     bits[  7:7  ] = 1 Valid message received    RXACT     bits[  6:6  ] = 1 Receiving a message    CSWAI     bits[  5:5  ] = 0 Module not affected by wait    SYNCH     bits[  4:4  ] = 1 MSCAN synch to CAN bus    TIME      bits[  3:3  ] = 0 Disable int MSCAN timer    WUPE      bits[  2:2  ] = 0 Disabled    SLPRQ     bits[  1:1  ] = 0 Running    INITRQ    bits[  0:0  ] = 0 Normal operationCANCTL1Bit Field Values:    CANE      bits[  7:7  ] = 1 Enabled    CLKSRC    bits[  6:6  ] = 0 Oscillator clock    LOOPB     bits[  5:5  ] = 0 Disabled    LISTEN    bits[  4:4  ] = 1 Activated    BORM      bits[  3:3  ] = 0 Automatic    WUPM      bits[  2:2  ] = 0 On any dominant level    SLPAK     bits[  1:1  ] = 0 Running    INITAK    bits[  0:0  ] = 0 Running

I guess that if PC and MCU hat different bit rate settings CANCTL0_SYNCH wouldn't be set.

 

On the PC end I'm using a PEAK usb interface and the bundled PCAN-View program to transmit. That's why I don't think the problem comes from this end either. In PCAN-View the status of the bus switches to "BUSHEAVY" immediately after the message is sent.

 

I can also exclude hardware problems - I sucessfully could get a CAN connection with the same CAN-USB interface on the same board with another program which was created with Processor Expert and using interrupts.

 

I carefully read the reference manual of the MCF51AC256 and I tried multiple variations/configurations - I always end up with the same problem. I guess I'm missing something very important that's why i would be happy for any kind of hints or suggestions!

 

Switching to interrupts is unfortunately not an option to me. It has to be a polling scheme. I also must not use the Processor Expert.

 

Thanks in advance!

Stefan

 

For completness here are the remaining functions:

/* Sorry no comments - I copied the configuration from code which was generated by Processor Expert however */void setup_clocks(void) {    SOPT2 = 0x28;    MCGC4 = 0x0;    MCGC2 = 0x26;     MCGC1 = 0x0A;    MCGC3 = 0x46;    while(!MCGSC_LOCK) {        __RESET_WATCHDOG();    }    FCDIV=0x4E;}

 

void init_can(void){    int id;        /* enable can */    CANCTL1_CANE = 1;    /* enter config mode */    CANCTL0_INITRQ = 1;    while(!CANCTL1_INITAK) { __RESET_WATCHDOG(); }    /* config bit rate 500 kbit/s */    /* select external crystal (4 Mhz) as reference*/    CANCTL1_CLKsrc=0;    /* synchronization jump Width = 2 Tq, Baudrate Prescaler = 1 */    CANBTR0 = 0x40;    /* SAMP=1, Time Segment 2 = 4 Tq, Time Segment 1 = 3 Tq */    CANBTR1 = 0xB2;    /* => Bit Time : 1 / 4e6  * (1 + 3 + 4) = 2e-6 */    /* => Bit Rate : 1 / 2e-6 = 0.5*e6 = 500k */    /* config two 32-bit filters */    CANIDAC = 0x00;        /* 1. filter: accept only extended id (bits 28-0) */    id = 0x0DEADBEE;    CANIDMR0 = 0x00;    CANIDMR1 = 0x00;    CANIDMR2 = 0x00;    CANIDMR3 = 0x00;    CANIDAR0 = (unsigned char)  (id >> (28-7)) & 0xFF;    CANIDAR1 = (unsigned char) (((id >> (20-7)) & 0xE0) | 0x18 | ((id >> (17-2)) & 0x07));    CANIDAR2 = (unsigned char)  (id >> (14-7)) & 0xFF;    CANIDAR3 = (unsigned char)  (id << (7-6)) & 0xFE;    /* 2. filter */    /* ignored for now */        /* enter normal mode */    CANCTL0_INITRQ = 0;    while(!CANCTL1_INITAK) { __RESET_WATCHDOG(); }        /* reset error flags */    CANRFLG |= 0xFE;    /* disable interrupts */    CANTIER = 0x00;    CANRIER = 0x00;}

Outcomes