MCF51AC256: CAN bus problem - overruns, CANRFLG_RXF never clears

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

MCF51AC256: CAN bus problem - overruns, CANRFLG_RXF never clears

ソリューションへジャンプ
3,236件の閲覧回数
StefanM
Contributor I

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;}
ラベル(1)
0 件の賞賛
返信
1 解決策
1,647件の閲覧回数
TomE
Specialist II

Yes, that one is obvious:

 

CANCTL1

Bit Field Values:
...
    LISTEN    bits[  4:4  ] = 1 Activated

 

From the Manual:

 

Table 15-2. CANCTL1 Register Field DescriptionsListen Only Mode — This bit configures the MSCAN as a CAN bus monitor.When LISTEN is set, all valid CAN messages with matching ID arereceived, but no acknowledgement or error frames are sent out (seeSection 15.5.4.4, “Listen-Only Mode”). In addition, the errorcounters are frozen. Listen only mode supports applicationswhich require “hot plugging” or throughput

CAN requires a sender and at least one non-listen-mode receiver on the bus.

 

Since your device can't send the "ACK" bit back to the PC, its transmitter thinks it has had an error (as nothing on the bus told it that the freme had been recieved correctly), so it continuously transmits the frame - again and again - back to back. This happens independent of the PC. It thinks it has sent one frame, except it won't have received notice of the successful transmission of that frame, and won't be able to send any new ones.

 

So just get rid of the "listen" bit and it will get a lot more sensible.

 

You have a "hard loop" receiving the frames, so CANRFLG_RXF shouldn't be "always set", but should only be set once per received frame at whatever baud rate you're running at. Likewise you shouldn't be getting overruns.

 

That assumes you're basing your assertions on a "running system" and not one that is stopped in the debugger.


Since the PC end is continuously transmitting frames, stopping the CPU in the debugger and then reading the CAN registers will always show overruns and RXF flags - but that's got nothing to do with the running system.

 

I'd suggest you attach an oscilloscope to the CAN bus so you can see what's going on. If you don't have one, just wire up a LED to the CAN bus so you have an indication of what's really happening.

 

Tom

 

元の投稿で解決策を見る

0 件の賞賛
返信
2 返答(返信)
1,648件の閲覧回数
TomE
Specialist II

Yes, that one is obvious:

 

CANCTL1

Bit Field Values:
...
    LISTEN    bits[  4:4  ] = 1 Activated

 

From the Manual:

 

Table 15-2. CANCTL1 Register Field DescriptionsListen Only Mode — This bit configures the MSCAN as a CAN bus monitor.When LISTEN is set, all valid CAN messages with matching ID arereceived, but no acknowledgement or error frames are sent out (seeSection 15.5.4.4, “Listen-Only Mode”). In addition, the errorcounters are frozen. Listen only mode supports applicationswhich require “hot plugging” or throughput

CAN requires a sender and at least one non-listen-mode receiver on the bus.

 

Since your device can't send the "ACK" bit back to the PC, its transmitter thinks it has had an error (as nothing on the bus told it that the freme had been recieved correctly), so it continuously transmits the frame - again and again - back to back. This happens independent of the PC. It thinks it has sent one frame, except it won't have received notice of the successful transmission of that frame, and won't be able to send any new ones.

 

So just get rid of the "listen" bit and it will get a lot more sensible.

 

You have a "hard loop" receiving the frames, so CANRFLG_RXF shouldn't be "always set", but should only be set once per received frame at whatever baud rate you're running at. Likewise you shouldn't be getting overruns.

 

That assumes you're basing your assertions on a "running system" and not one that is stopped in the debugger.


Since the PC end is continuously transmitting frames, stopping the CPU in the debugger and then reading the CAN registers will always show overruns and RXF flags - but that's got nothing to do with the running system.

 

I'd suggest you attach an oscilloscope to the CAN bus so you can see what's going on. If you don't have one, just wire up a LED to the CAN bus so you have an indication of what's really happening.

 

Tom

 

0 件の賞賛
返信
1,647件の閲覧回数
StefanM
Contributor I

Thanks, Tom! I can't believe I did not see this...

0 件の賞賛
返信