Reading CAN msgs upon Wakeup

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

Reading CAN msgs upon Wakeup

ソリューションへジャンプ
1,552件の閲覧回数
petertang
Contributor I

I'm playing around with an S12 micro to help me understand how to use CAN interrupts with a sleeping uP.

 

What I have in place is an infinite loop - while(1) - that puts the micro to sleep.

I (think I) have only enabled the CAN RXFIE - Receiver Full Interrupt Enable.

When the uP wakes up due to an inbound CAN msg, I get it to read the msg and then send a msg based on the contents of the received message.

The uP then goes to sleep again due to the loop.

 

Here's the problem - the msgs sent by the uP are not the ones I expected.

Upon startup it doesn't seem to always respond to my first few command msgs.

After a few msgs are sent, it then seems to lag behind my commands by 4 msgs.

 

Obviously I want it to respond to the command I just sent...

Does anyone know why this is the case? Have I just setup something wrong, or am I going about it the wrong way?

 

Thanks

ラベル(1)
タグ(2)
0 件の賞賛
返信
1 解決策
1,427件の閲覧回数
kef2
Senior Contributor V

Aha. There are five hardware Rx buffers mappable to the same address CAN0RXIDRx etc. Each time you service Rx interrupt clearing RXF flag, next Rx buffer gets mapped to CPU address space. And this explains why you "receive" garbage 4 times. You need to copy Rx data to RAM in your ISR routine before clearing RXF flag. Use this data to fill Tx buffer.

元の投稿で解決策を見る

0 件の賞賛
返信
10 返答(返信)
1,427件の閲覧回数
kef2
Senior Contributor V

CAN needs clock for operation. Without clock it is not possible to receive CAN messages. So what power saving mode are you using and what happens to oscilator when you put MCU to sleep? Oscilator needs some time to wake. It easily can make you unable to receive first message. Try using wait mode or maybe pseudostop mode. You should have no problems receiving all messages waking up from wait.

.

0 件の賞賛
返信
1,427件の閲覧回数
petertang
Contributor I

Thanks Edward.

I have looked through my code and can confirm I am using the asm(WAI) command to put the MCU to sleep.

Your answer seems to imply that this would be an appropriate method; is this true?

Perhaps it will help if I supply more information.

Please find a CAN trace snippet below of what I am seeing upon the initial start of the MCU:

2084.0  Rx     010  8  FF 01 00 00 00 00 00 00
2085.2  Rx     201  8  59 DF 01 01 00 77 4E DF
2184.0  Rx     010  8  FF 02 00 00 00 00 00 00
2185.1  Rx     201  8  59 DF 02 02 00 00 03 A5
2284.1  Rx     010  8  FF 03 00 00 00 00 00 00
2285.2  Rx     201  8  27 DE 03 03 12 7E EF 30
2384.1  Rx     010  8  FF 04 00 00 00 00 00 00
2385.2  Rx     201  8  27 DE 04 04 03 5B E9 91
2484.2  Rx     010  8  FF 05 00 00 00 00 00 00
2485.4  Rx     201  8  FF 01 05 05 00 00 00 10
2584.2  Rx     010  8  FF 06 00 00 00 00 00 00
2585.4  Rx     201  8  FF 02 06 06 00 00 00 10
2684.2  Rx     010  8  FF 07 00 00 00 00 00 00
2685.5  Rx     201  8  FF 03 07 07 00 00 00 10

0x010 is my "command msg" - Bytes 0 and 1 are to be echoed back on Bytes 0 and 1 on the MCU's ack msg (0x201) - all other Bytes are set to 0x00

In Bytes 2 and 3 of the ack msg, the MCU should write its internal "wakeup counter" i.e. the number of times that it is woken up. Bytes 4, 5, 6 and 7 is the CAN ID of the msg that it just received.

This is why I am confused. The MCU clearly sends its ack msg as expected, but it's data is... corrupt?

Only after 4 cmd msgs have been sent does the MCU ack msg appear to do what I expect, but even then it seems to be 4 msgs behind according to Byte 1...

Further suggestions would be greatly appreciated.

0 件の賞賛
返信
1,427件の閲覧回数
kef2
Senior Contributor V

"I have looked through my code and can confirm I am using the asm(WAI) command to put the MCU to sleep.

Your answer seems to imply that this would be an appropriate method; is this true?"

Yes, I'm using WAI and no messages are lost.

It looks like some weird software issue. Isn't it some Rx queue which you forgot to clear at initialization?

0 件の賞賛
返信
1,427件の閲覧回数
petertang
Contributor I

Ok...

I wasn't aware that I would have to flush the buffers.

I haven't seen anything explicitly mentioned in the documentation.

Do you or anyone else know have suggestions how to do this?

0 件の賞賛
返信
1,425件の閲覧回数
kef2
Senior Contributor V

I mean software fifo buffer, not hardware buffers. Hardware receive buffers are properly emptied on chip reset.

0 件の賞賛
返信
1,425件の閲覧回数
petertang
Contributor I

Is this FIFO buffer implicitly created?

I ask because I haven't set anything up.

All I have done is to read the CAN0RXDSR1 byte directly and piped this to the ack msg mentioned above.

0 件の賞賛
返信
1,425件の閲覧回数
kef2
Senior Contributor V

Could you show your code? If not your own software FIFO, then something else is wrong. It is not hardware issue (unless you have very odd CAN logger).

0 件の賞賛
返信
1,425件の閲覧回数
petertang
Contributor I

Sure

  /* loop forever */

  while(1) {

    asm (WAI);

   

    counter++;

 

    /* Formats Standard CAN ID */

    canID.b.b0 = CAN0RXIDR0;

    canID.b.b1 = CAN0RXIDR1;

    canID.b.b2 = CAN0RXIDR2;

    canID.b.b3 = CAN0RXIDR3;

    canID.d >>= 21;

 

    /* Data values */

    data.b[0] = CAN0RXDSR0;

    data.b[1] = CAN0RXDSR1;

    data.b[2] = counter;

    data.b[3] = counter;

    data.d[1] = canID.d;

 

    /* Send CAN msg */

    (void)SendFrameExt(0x201,0,8,data.b);

  }

Like I said, the main loop itself doesn't do much at all - just sends a msg.

Other low level initialisation has been done using an auto-code generator - CodeWarrior's Device Init

I am using a PCAN logger to record/view my trace.

Any ideas?

0 件の賞賛
返信
1,428件の閲覧回数
kef2
Senior Contributor V

Aha. There are five hardware Rx buffers mappable to the same address CAN0RXIDRx etc. Each time you service Rx interrupt clearing RXF flag, next Rx buffer gets mapped to CPU address space. And this explains why you "receive" garbage 4 times. You need to copy Rx data to RAM in your ISR routine before clearing RXF flag. Use this data to fill Tx buffer.

0 件の賞賛
返信
1,425件の閲覧回数
petertang
Contributor I

Brilliant! :smileyhappy:

That works. I didn't know this was the case.

Thank you Edward.

0 件の賞賛
返信