AT90CAN128 & CAN - strange behaviour [SOLVED]

Go To Last Post
27 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,
I'm facing a strange problem by testing remote frames. I have discovered following: As soon as a remote frame was sent out from a mob a frame is received to this mob immediately. Example: I stop the code execution on the line which writes the TX command to the CANCDMOB register. After execution of the command the CANSTMOB indicates TXOK, corresponding SIT is set, CANIDT keeps. The code is still stopped on line bellow the STS instruction which writes the TX command to the CANCDMOB (note, this is an ISR section with disabled interrupts). Now I put a message to the CAN bus and this message is then received to this mob but without any RX command for the mob (the code is still stopped a line bellow the STS). The SIT keeps, but the CANIDT now follows the ID of the message and CANSTMOB indicates RXOK (no more TXOK). The effect occurs only when the RTRTAG is set. When cleared, everything goes well.
Is this behavior (unsolicited reception after remote frame was sent) an intention or error or I'm doing something wrong.... ?

Thanks for information.

(debug via JTAG on JTAGICE MKII and AVRSTUDIO 5; tested on MOb 0)

Last Edited: Thu. Nov 21, 2019 - 11:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No ideas what could be wrong?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Setting the CANCMDOB.RPLV bit to a one for a Rx Remote Frame MOb will Rx a Remote CAN frame and then automatically reply with a CAN Data Frame Tx. This will end with a TXOK, not an RXOK. Make sure your RPLV bit is not set.

col369 wrote:
Now I put a message to the CAN bus and this message is then received to this mob but without any RX command for the mob (the code is still stopped a line bellow the STS).
How do you “ put a message to the CAN bus” when your code execution is stopped?Your description is confusing me. Do you mean you are sending a CAN Tx from a different CAN node?

Now a different MOb number may be setup to Rx CAN frames, the CAN state machine will probably continue to work, and Rx CAN bus frames, even though your code execution is stopped.

Try reading back the CANCDMOB bit values after you write your Tx MOb CANCDMOB command. Make sure it is still a CAN Tx command.

If the Tx command is corrupted and becoming a Rx command, change your code so you write a deliberate CAN disable command after any RXOK or TXOK is processed and CANSTMOB is cleared. An older CAN operation may have confused the CAN state machine and caused CANCDMOB command corruption upon the next CANCDMOB write. Forcing a redundant (the RXOK/TXOK already disabled the MOb) deliberate disable command would probably prevent any CAN state machine corruption.

CANCDMOB &= ~((1 << CONMOB1) | (1 << CONMOB0));  // deliberate disable

BTW, AVRstudio 5 is known to be buggy and should be updated to the current version of AVRstudio 6. Testing with buggy IDE software makes all your testing questionable. If you want you could downgrade to AVRstudio 4.19 instead for CAN testing.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, thanks for the answer!

RPLV is not set. It is not intended at this moment. Of course it could be done by an accident. But the IO viewer told me, the RPLV isn't set.... Regardless it, the consequence is reverse. First I'm TXing then unsolicited RX occurs. The TX is first use of the MOB 0 after reset.

Sorry for confusing. Yes, the message is sent from another CAN node.

Yes, the CAN periphery continues its job even the code is stopped. And there is one MOB able to receive all IDs, but the message seems to be received to the MOB 0. The reasons for such conclusion are: a) setting the mask (CANIDM) of MOB 0 to the value which together with MOB ID is unable to produce any match with IDs running on BUS before switching it to the first TX will prevent the unsolicited RX... b) In the code every MOB is associated with a fifo. Based on RXOK or TXOK flag the ISR decides between fetching frem fifo (TXOK) and writing to the fifo (RXOK). Currently the MOB 0 is dedicated for TXing and it is supposed that after initial TX command the response of CAN periphery will be either TXOK or an error or nothing not RXOK... But the MOB 0 fifo is getting filled by received messages even if the code is running of debug session....

Quote:

Try reading back the CANCDMOB bit values after you write your Tx MOb CANCDMOB command. Make sure it is still a CAN Tx command.

Yes, it is (and CANSIT is indicating)... unless I put a message to CAN (by another node). After that (and update of IO viewer) I got a message received to the MOB 0. Corresponding bit in CANSIT keeps active, but flag is now RXOK, ID is accoroding the received message etc...

Yes, I was thinking also about corruption of the commands. But I'm debugging the first write to the MOB 0 and before it, the CANCDMOB sate indicates a disabled MOB as it should be. Then the TX followed by RX is done in few amount of code steps (all of them are done in ISR, there is no chance for other code parts to write anything to the CAN periphery)... Of course the potentially buggy AVRSTUDIO debug session can do it. But it is strange that the code running out of debug session behaves according the facts discovered by the debug session.

OK, i will test the version of AVS you have suggested and I'll try to make a small simple code which will try to reproduce the problem... The current driver code is quite general and has ca 1500 lines making it a little bit knotty for this bug catching.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What I have seen in the past with JTAGICE MKII was writing a Tx command to CANCDMOB caused the CANCDMOB bits to be a Rx command. Literally, I wrote the CANCDMOB command bits to 01 - enable transmission and the JTAGICE reported the command bits as 10 - enable reception after the CANCDMB register write. The register data used for the write was the correct 01 Tx command bit values, but the CAN state machine caused the incorrect 10 Rx command bits to set instead and the JTAGICE MKII reported the actual Rx value in CANCDMOB (even though a Tx had been written, it still showed the insane rogue Rx command result). The problem persisted when all breakpoints were removed and the code was run without debugging, so it did not appear to be a JTAGICE caused problem.

Other than this strange behavior, I have never seen any Tx MOb that is capable of returning a RXOK. Using AVRStudio in dis-assembler view with a break point set just before the CANCDMOB Tx command write, single step through the CANCDMOB write and see if the CANCDMOB command bits are corrupted when you write the Tx command. You could also read the CANCDMOB value after the Tx command write and see if it magically turned itself into a Rx command. This behavior is not logical, not sane and knowing what you actually attempted to write to CANCDMOB does not matter. You have to look at what is written with JTAGICE or read after the CANCDMOB write. You might put in code with a break point if MOb 0 CANCDMOB is ever set to Rx (after your Tx write)?

Anyway, in another thread another AVR CAN user just proved a disable MOb command is required after the MOb automatically disables from a MOb CANSTMOB RXOK. He was seeing a Rx MOb that was only RXOK automatically disabled (the MOb CANEN bit was cleared), but the disabled MOb was corrupting the MOb CANMSG buffer about every 50,000 CAN bus messages. It appears the CAN hardware really needs the redundant MOb disable command after the automatic RXOK disable.

It appears the automatic MOb disables are not effective even though the MOb CANEN busy bit is cleared, and a deliberate MOb disable command is required to follow up the automatic MOb disable. Automaticly disabled MObs are RXOK, TXOK or any CAN bus Tx error if/when in TTC mode. This redundant deliberate MOb disable command seems to return sanity to the CAN state machine.

If you are seeing an actual uncorrupted CANCMDOB Tx command return a RXOK, then I have never seen this behavior.

Of course when you initialize the CAN (before the ENASTB=1 write), all the MObs (even the MObs you never use) in the CAN chip must already have all the CANCDMOB and CANSTMOB registers set to zero first. None of the MOb registers have any reset default values, so explicit initialization is required for all the CANCDMOB and CANSTMOB registers to start up the CAN hardware in a stable configuration.

Do not make multiple writes to CANCDMOB while setting up the same new command. Every write to CANCDMOB is acted on by the CAN state machine hardware as a new command. Just setup the command bits, IDE, RPLV and DLC values for any start a new MOb single command write. For example:

CANCMDOB |= (1 << IDE);

is a disaster that not only set the IDE bit, but just started a new MOb command with whatever happens to be in the CANCDMOB command bits. Keep in mind the CAN state machine hardware does not always respond to new commands when it is already using the CAN bus (this is called ongoing communication). So, if you issued an accidental MOb command with a bad CANCDMOB write like the example, just issuing the correct command may not be enough to clear up the problem if any ongoing communication was already in progress when you finally issued the correct MOb command.

When setting up any Tx command, I always zero all the CANIDM bits since CANIDM is not used for Tx and I want the reserved bits cleared anyway, since the data sheet said to clear them.

Actually in a Rx MOb the acceptance filter (see the data sheet) decides which MOb number matches and diverts the live CAN data stream bits into the correct MOb registers. This will fill CANMSG bytes starting with the first live CAN data byte sent into the first CANMSG byte, then the second live CAN data byte sent into the second CANMSG byte, and so on.

When a Tx sends CAN data, the first live CAN data byte is the first CANMSG byte, and so on.

The CANPAGE.INDXn 3 bit bit value points at the CANMSG byte being accessed by the software for reading or writing CANMSG bytes. When CANPAGE.AINC=0, any access of CANMSG will automatically increment the CANPAGE.INDXn 3 bit value pointer. When AINC=0 do not use any read. modify write operations (i.e. |= or &=, etc.) on the CANMSG register or you will double increment CANPAGE.INDXn.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, thanks for answer again.

Regarding paragraph 2:
This is exactly what I'm doing... I never see any weird RX command, I see only the result - received message.
Here are my steps:
0) page 0 selected
1) everything is prepared (ID, RTRTAG etc...)
2) page 0 deselected
3) code runs, some job with other pages
4) page 0 selected
5) break point here; CANCDMOB is written with the TX command
6) only one step is made to write the TX command (a STS instr.)
7) everything seems to be OK, TXOK, CANSIT etc... the MOB registers CANIDT contain right data
8. I start sending messages from CAN another node
9) I make next code step - an unimportant instruction (or I simply update the IO viewer)
10) Now I see received message in MOB 0. TXOK is no more active, but the RXOK is. CANIDTs are rewritten according to he received message, DLC updated.

Note that the weird behavior occurs only if RTRTAG is set. With RTRTAG cleared everything goes well.

Yes, I have all mobs disabled and flags cleared before enabling the CAN periphery.

The only thing is I'm using the read-modify write on the CANCDMOB register, but only when it is disabled. I never write back anything different from DISABLED, except the last step which changes DISABLED to TX command. This is because the transmit control is in other part of code (reason is an intention to change the prioritized MOBs sending to the "fifoed" MOBs sending).

Tomorrow I'll test small simple code trying to reproduce the problem by simplest possible way.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, here it is.....

Test code - this code is preceded by CAN pheriphery reset, MOb disabling, IDT and mask clearing, timing definition, periphery enabling and waiting for got it enabled:

#define SET_RTR
#define ONE_SHOT_CANCDMOB
while (1)
    {
        #asm ("cli");  
        CANPAGE  =  0xd0;
        CANCDMOB =  0x81;   /*RX to mob 0x0d*/
        CANPAGE  =  0x00; /*canpage 0, autoinc, zero idx*/   
#ifndef ONE_SHOT_CANCDMOB    
        CANCDMOB =  0x05; /*disabled, no rplv, no ide, dlc=5*/
#endif    
#ifdef SET_RTR    
        CANIDT4  =  0x04; /*RTR tag*/
#endif    
        //CANIDT4  =  0x00; /*NO RTR tag*/
        CANIDT2  =  0x00; /*ID = 130h*/
        CANIDT1  =  0x26;
#ifndef ONE_SHOT_CANCDMOB    
        CANCDMOB |= 0x00;            
        CANCDMOB |= 0x40; /*TX !*/
#else 
        CANCDMOB  = 0x45; /*TX with dlc 5!*/
#endif        
    
        while(1)
        {
            /*discover CANCDMOB on LED1/3*/
            if(CANCDMOB & 0x40) LED1_ON; /*Tx cmd bit is set*/
            else LED1_OFF;
            if(CANCDMOB & 0x80) LED3_ON; /*Rx cmd bit is set*/
            else LED3_OFF;
            
            /*discover CANSTMOB on LED0/2*/
            if(CANSTMOB & 0x40) LED0_ON;
            else LED0_OFF;
            if(CANSTMOB & 0x20) LED2_ON;
            else LED2_OFF;
        }
        #asm("sei"); 
    }

When running with RTRTAG set the result in while(1) trap is:
1) CANCDMOB = 0x98; CANSTMOB = 0xA0; CANEN2 = 0x00; CANHPMOB = 0x00; on condition there is traffic from other nodes on the CAN

2) CANCDMOB = 0x85; CANSTMOB = 0x40; CANEN2 = 0x01; CANHPMOB = 0x00; on condition there is NO traffic on the CAN

3) CANCDMOB = 0x45; CANSTMOB = 0x01; CANEN2 = 0x01; CANHPMOB = 0x00; on condition the node is disconnected from other nodes on the CAN.

My conclusion:
1)
It is an autoreceive feature (not mentioned in the manual) after TXing with RTRTAG set. The MOb which has sent the RTR message is automatically set to RX and is waiting for reply. In case the mask is not set, the MOb will receive the first message appeared on the CAN. This is what happens... Unfortunatelly, there is probably no way to switch this feature off. It doesn't fit the concept of my CAN driver. :(

2) the r-m-w operation over CANCDMOB seems to have no fatal effect when applied on DISABLED MOb.

Hmm. Any ideas of workarounding?
I have no idea of a smart workaround.... It seems the only thing I can do is set the mask for exact match and to try catching the TXOK and cancel the auto RX command. As the TXOK is cancelled by RXOK and I can't guaratee ISR execution (catching the TXOK) before answer comes, I will have to add a restriction for using of the driver - there has to be a RX dedicated MOb for catching the rtr answers with higher prirority than the MOb sending the requests... :roll:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your example code makes no sense. You code never checks for any CANSTMOB activity to indicate MOb 0 ever did anything, yet you show CANSTMOB activity in your results. Where did you clear CANSTMOB before this code is run?

col369 wrote:
When running with RTRTAG set the result in while(1) trap is:
1) CANCDMOB = 0x98; CANSTMOB = 0xA0; CANEN2 = 0x00; CANHPMOB = 0x00; on condition there is traffic from other nodes on the CAN

2) CANCDMOB = 0x85; CANSTMOB = 0x40; CANEN2 = 0x01; CANHPMOB = 0x00; on condition there is NO traffic on the CAN

3) CANCDMOB = 0x45; CANSTMOB = 0x01; CANEN2 = 0x01; CANHPMOB = 0x00; on condition the node is disconnected from other nodes on the CAN.

I assume this is all from MOb 0. Well 1) and 2) are both Rx commands. As expected 1) is a CANSTMOB.RXOK with a CANSTMOB.DLCW. Definitely not expected is 2) indicates a CANSTMOB.TXOK flag on a Rx command. The 3) is a Tx command with a CANSTMOB.AERR.

1) Rx 29 bit ID with 8 bytes, RXOK/DLCW are set and MOb 0 is disabled. Looks fine.

2) Rx 11 bit ID with 5 bytes, MOb 0 is still enabled and you have an impossible TXOK flag set, yet the MOb is not disabled.

3) Tx 11 bit ID with 5 bytes, MOb 0 is still enabled and you have an AERR. Looks fine.

It looks like 2) has an old bogus CANSTMOB value that was never cleared and MOb 0 is really still trying to Rx with meaningless garbage data in CANSTMOB left over.

You are mixing 11 bit and 29 bit IDs, which is OK if that was what you were trying to do.

None of your results show a Tx command with a CANSTMOB.RXOK set. I think your are letting your code run with incorrectly setup CAN registers (specifically CANSTMOB). In fact you have a Rx command in 1) and 2), yet I thought MOb 0 was only Tx?

If you see this differently please tell me what you see.

The idea is:

1) set CANPAGE.

2) clear CANSTMOB. This automatically clears the read only CANSIT MOb bit which causes CANHPMOB to change. This first clear is usually from the CAN initialization code.

3) send the CANCDMOB command to the CANPAGE selected MOb.

4) poll or use the CAN IT to detect when any MOb enabled CANSTMOB bits are set. The CAN hardware will set the CANSTMOB bits for you and any enabled bits will set the CANSIT MOb bit, which causes CANHPMOB to change.

5) when detected check the CANSTMOB result. This is where your results reporting should be.

6) clear CANSTMOB. This automatically clears the read only CANSIT MOb bit which causes CANHPMOB to change.

7) if a CANSTMOB RXOK or TXOK was set, immediately issue a CANCDMOB deliberate MOb disable command (this is an important fix). Now your polling or CAN IT ISR is finished.

8 ) you are now ready for another new MOb command.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Where did you clear CANSTMOB before this code is run?

During the initialization of the pheriphery (not shown in code), this code (and whole program now) sends only one message then it enteres while(1) trap with indication. There is nothing else to do. CANSTMOB is definetly cleared before this small code runs.
There is no neccesity to check the CANSTMOB as there wasn't any CAN operation between the CAN init and the posted code. And the CANSTMOB is really zero before entering the posted code.

Yes, every operation I have analyzed was made on MOb0.
Yes, I'm working with both long and short IDs and I'm aware about it.

Quote:

None of your results show a Tx command with a CANSTMOB.RXOK set.

I don't agree, result 1) Shows TXOK set! EDIT: RXOK set! of course...
The "results" are results of code run under different circumstances. What the code is trying to do is clear (send RTR message with dlc 5, ID 130h (11 bit)). I will take the results from back:

3) the node is disconnected, the CAN periphery is not able send the message correctly (there is no ACK from another node). There is an ACK error and the mob is still active with the TX command (can be seen in the registers)

2) the node is connected to CAN BUS and there is no trafic from other nodes. The message was sent and was observed on the CAN bus. CANSTMOB reports TXOK, BUT a RX command have appeared in CANCDMOB without any code activity! But this RX command can't be completed as there is no activity on the CAN bus.

1) the node is connected to the CAN bus with traffic. Similar to the point 2) but: as there is a traffic and no mask is set, first message (after TX command is completed) is received. TXOK is cleared, RXOK is set, ID is according to the received message, DLCW is set because the received message has different datalegthh form value of 5. etc....

These facts lead me to the conslusion I have made yesterday.

Yes, I can modify the code according your ideas, but I don't suppose any change in the periphery behavior.

The only real difference between your ideas and my code is waitinig for an action completion (eg. SIT polling). Yes, it is crucial for real code, but no for this example. In case od debugigng the code step by step the action (TX) is done before I have entered the while(1) trap (the preiphery runs independent on the code, thus the action is done before I'm able to press the "step" key on my keyboard). In case of not stepping the code, the LEDs will indicate the topical state of the registers. For a very short time it will not show the result. But this is hard to catch by eyes. After these short period it will show the result. Also a transition from "result 2)" to "result 1)" can be observed by putting a message on the CAN bus.

Last Edited: Wed. Mar 20, 2013 - 02:07 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

col369 wrote:
I don't agree, result 1) Shows TXOK set!
Then:
col369 wrote:
1) CANCDMOB = 0x98; CANSTMOB = 0xA0
CANSTMOB flag values (see the data sheet 19.11.1 CAN MOb Status Register - CANSTMOB):
0x20 = RXOK
0x40 = TXOK
0x80 = DLCW

Lets take 1) CANSTMOB = 0xA0. The hex 0xA0 is a binary 1010 0000 (compare this binary to the data sheet picture of the CANSTMOB bit positions), this breaks down into two hex flags 0x80 DLCW and 0x20 RXOK. If result 1) was a TXOK it would be a hex 0x40 with both flags being CANSTMOB = 0xC0 (the DLCW flag is not possible with a TXOK anyway).

My question is how does a CANSTMOB = 0xA0 indicate a TXOK flag in any way at all?

We are not going to get anywhere if we cannot agree on the meaning of the flag values.

BTW, for example this:

if (CANSTMOB & 0x40)

is easier to read as:

if (CANSTMOB & (1 << TXOK))
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,
I'm sorry. It was a typing error.... I have written TXOK set! but I meant RXOK set!. Sorry for confusing.
Of course there should be RXOK set! as it is a reply to your objection:

Quote:
None of your results show a Tx command with a CANSTMOB.RXOK set

I'll correct it. But what about the rest of the post?
I hope there is no more typing errors. :-)

BTW:
In bug catching codes I prefer

if (CANSTMOB & 0x40) 

over

if (CANSTMOB & (1 << TXOK)) 

It is because the reader (which is supposed to be deep in the problem in that case) instantly knows which bit is examined. It is not necessary to examine if TXOK is well defined..... Of course for a real application I prefer the second one (because the general reader skimming the code is not supposed to be aware about meaning of eg. 0x40).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

About the rest of my post:

Mike B wrote:
1) Rx 29 bit ID with 8 bytes, RXOK/DLCW are set and MOb 0 is disabled. Looks fine.

2) Rx 11 bit ID with 5 bytes, MOb 0 is still enabled and you have an impossible TXOK flag set, yet the MOb is not disabled.

3) Tx 11 bit ID with 5 bytes, MOb 0 is still enabled and you have an AERR. Looks fine.

Without typos :) do you disagree with any of this?

What I am seeing in 1) is a MOb 0 Rx command that ended with a RXOK and the MOb 0 CANEN bit cleared. As soon as MOb 0 CANSTMOB is cleared the CANHPMOB value will change to 0xF0 if no other CANSIT bits are set. However, you say MOb 0 was only ever set to a Tx command. If true and MOb 0 was only ever set to a Tx command, then you are seeing the CAN state machine CANCDMOB command bit corruption I described in the first place.

In 2) the impossible TXOK behavior in a CANCDMOB Rx command is unknown to me. I have never seen it or heard of it. Since the MOb 0 CANEN bit is still set this Rx command is still active (busy), which is what you expect on condition there is NO traffic. I have never seen or heard of the CAN state machine setting CANSTMOB TXOK or RXOK bits while the CANEN MOb bit is still set to busy. This is why I think CANSTMOB has old left over garbage in it and the TXOK is false and not related with respect to the current CANCDMOB Rx command. Again, if MOb 0 was only ever set to Tx, this looks like another example of CANCDMOB command bit corruption.

In 3) it is a normal MOb 0 Tx command that is stuck in automatic error Acknowledge Error retry mode, which is what you expect on condition the node is disconnected. This is the only case that has no "issues".

The CANIDM register behavior you have described is consistent with Rx MOb 0 behavior and you have two examples of MOb 0 Rx commands. CANIDM has nothing to do with Tx commands.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Mike B wrote:
1) Rx 29 bit ID with 8 bytes, RXOK/DLCW are set and MOb 0 is disabled. Looks fine.

2) Rx 11 bit ID with 5 bytes, MOb 0 is still enabled and you have an impossible TXOK flag set, yet the MOb is not disabled.

3) Tx 11 bit ID with 5 bytes, MOb 0 is still enabled and you have an AERR. Looks fine.

Let us assume that the three ponits are final states of the experiment. They depend on the circumstacies (CAN traffic and conectivity) on the CAN BUS.

ad 1) Yes. It looks fine... - at glance. The state looks fine - but not the way we get there. Don't forget that it is result of single TX command! RXOK after a TX command seems ok to you? Note: that it only happens when RTR TAG is set.

ad 2) I have another opinion here. The TXOK flag is nothing impossible - it is achievable result after issuing the TX command (the only one message i want to send (ID==130h, RTRTAG active, DLC=5)). The strange thing is the RX command in the CANCDMOB. What is this RX command arisen from??.... Note: When sending the test message without RTR tag set this strange RX command is missing!!
Note: I suppose the CANEN is not STILL set to busy, it is busy AGAIN !!

ad 3) Looks fine and is according to my assuption.

Of course, the CANIDM has nothing to do with the Tx commands. But it has much to do with the unintended reception which occurs after the Tx of a RTRmessage is done. When there is no messages (on the CAN) matching the mask filter I never got to the result 1) and hang in state 2)

Please read this:
I still think there is undescribed autoreceive feature after sending a message with RTRtag active. And it makes sense: You send the RTR ask and the mob automaticaly switches to receive the answer after send is done. Of course you have to set the mask for exact match in order to receive (only) the answer (it is supposed to have the same ID as the RTR ask). It could be complementary fuction to the autoreply - but it is undocumented. What do you think about it??? All the above mentioned results exactly match to this scenario....

Last Edited: Wed. Mar 20, 2013 - 04:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

col369 wrote:
ad 1) Yes. It looks fine... - at glance. The state looks fine - but not the way we get there. Don't forget that it is result of single TX command! RXOK after a TX command seems ok to you? Note: that it only hapens when RTR TAG is set.
Please recall what I originally described as CANCDMOB command bit corruption.

You write CANCDMOB with a Tx command, but the CANCDMOB bits set as a Rx command. This is CAN state machine CANCDMOB bit corruption. You do not go by the CANCDMOB Tx command you wrote, since the corruption changed it into a Rx command. After the corruption changes it from a Tx command into a Rx command, it behaves properly as a Rx MOb and it is never a Tx MOb like you expected/wanted.

Yes, if you had never set CANIDT4.RTRTAG=1 the CANCDMOB corruption would not have happened. But you did set RTRTAG and your Tx command got corrupted into a Rx command.

After any CANSTMOB.RXOK or CANSTMOB.TXOK, you must always write a deliberate MOb 0 CANCDMOB disable command to fix this. It is that simple.

Start over with your testing after you add the deliberate MOb 0 CANCDMOB disable command. This will fix so many problems, that we will be able to address Remote Fame CAN issues where CANIDT4.RTRTAG is set from a sane working CAN node starting point. Until you take this first step and fix the problem, your CAN node has no chance of working correctly.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
You write CANCDMOB with a Tx command, but the CANCDMOB bits set as a Rx command.

Where do I such thing?

Quote:
Yes, if you had never set CANIDT4.RTRTAG=1 the CANCDMOB corruption would not have happened. But you did set RTRTAG and your Tx command got corrupted into a Rx command.

I can't understand your idea.... I write the RTRtag before the TX command... I write it to the idle (just initialized) MOB with CANCDMOB=0, without RXOK nor TXOK set...

Quote:
After any CANSTMOB.RXOK or CANSTMOB.TXOK, you must always write a deliberate MOb 0 CANCDMOB disable command to fix this. It is that simple

Ok, I will implement that to the driver. Thanks for hint, but it can't have any influence on the sample code we are now discussing. Because there it is done by the CANinit porecedure! And then only one message is sent and it is the only operation (the only command)over MOB 0. So it can't be corrupted.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well yes, you setup the CANIDT registers including CANIDT4.RTRTAG first before you issue the CANCDMOB command Tx write. You need to write the RTRTAG value before the CANCDMOB Tx command.

The trouble is as soon as you get the CANSTMOB.TXOK set from any MOb 0 completed operation, you need to immediately write a deliberate MOb 0 CANCDMOB disable command, before you change any other MOb registers for future MOb 0 new commands.

The idea is after the TXOK, the deliberate MOb 0 CANCDMOB disable command stops the CAN state machine and prevents future CANCDMOB corruption while you setup any MOb 0 registers.

It should not be this way and the CANCDMOB command bits should never be corrupted, but guess what, it is this way. The CAN state machine is complex and it has a bug where it corrupts the CANCDMOB command bits under certain conditions (setting RTRTAG is only one of these conditions). Nothing will happen with the MOb until you finally write the CANCDMOB Tx command.

The idea is the CAN state machine reacts to the CANCDMOB command write when you write CANCDMOB, so all the other CAN MOb registers that you use (CANIDT, CANIDM and CANMSG) all get initialized first as needed before you write the final CANCDMOB command. If you write the other MOb registers (CANIDT, CANIDM or CANMSG) after a CANCDMOB command write, the CAN state machine could have already reacted to the old values. Also, when the MOb CANEN bit is set to busy and your software writes to the other MOb registers (CANIDT, CANIDM or CANMSG), you are creating a potential conflict with CAN state machine using these registers while your software is also writing these registers. This is why the CANCDMOB command write is the last thing after the other MOb registers are setup.

BTW, I left out the CANSTMOB MOb register from the description of other MOb registers (CANIDT, CANIDM or CANMSG) because clearing CANSTMOB is always part of the polling or CAN IT ISR handling. It always has to be taken care of no matter what.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

The trouble is as soon as you get the CANSTMOB.TXOK set from any MOb 0 completed operation, you need to immediately write a deliberate MOb 0 CANCDMOB disable command, before you change any other MOb registers for future MOb 0 new commands.

I understand and I agree. But don't forget this sample code is only "one-shot action" on MOB 0. And I study the result(s) of this one shot (tx of ID==130h;RTR; DLC==5) under different circumstances on CAN bus. This signle tx command is made over clear and previously unused MOB. After the TX command there is no write operation over whole CAN (note, that the test code runs under "cli" so nobody else can operate with the CAN).
Ok, is something wrong with initiation of the only one transmit in the sample code? If not - why I get result 1) or 2). I don't see nothing wrong with the sample one-shot code. You do? Remeber the purpose is only to send one message and then hang up in while (1).

I looked over whole driver and everywhere the command (TX or RX) is the last thing I do. I have even set the mob to idle after RXOK or TXOK. Also in the sample code is the command the last thing I do.... note: the rx command at the beginning of the sample code is made over different MOB (not MOB 0 but MOB 13)...

The problem we are still dealing with is:

1) you have just initialized CAN pheriphery, all mobs disabled, all flags and masks cleared etc...
2) you initiate a single tx command with rtr active. Lets assume the tx setup procedure was done in right order.
3) you got RXOK flag (and you got received a message to the MOB) when there is traffic on CAN. Instead of supposed TXOK...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Then I do not understand your 2) case where CANSTMOB has impossible garbage in it. If this was a freshly initialized MOb 0, then I would expect CANSTMOB to remain a zero value while the MOb 0 CANEN bit is still set (MOb 0 is busy). Everything else in 2) looks normal for a busy Rx command, except for the impossible CANSTMOB value. Look for any bugs in your setup. Maybe make a special copy of your source code and strip out the conditional cases you do not use. Eliminating this extra unused code and conditional defines may make debugging easier. If you miss-spelled a define name, maybe your code is not compiling how you think it is. Toss out this special edited source code copy when you are finally done testing.

Put in debug code and check the CANSTMOB value just before your CANCDMOB Tx command write. You need to really know for sure if it is the CAN hardware and not your software that is doing an impossible CANSTMOB value.

Double check all numeric constant values used to set register bits. Maybe you made an error? This is the other reason for using (1 << FLAG) bit types for source code register bit values. It is harder to accidentally get the bit value wrong when you have to type out its name :wink:.

Yes, I know I ignored the fact it should have not have been a Rx command, but it should not have been able to have TXOK set either. One problem at a time. If you try an fix all the problems all at the same time, you just get lost.

You may have a register write leak or unexpected CANCDMOB write before you write the final CANCDMOB actual Tx command. As noted before, an accidental bad CANCDMOB command write may not be correctable by simply writing a new CANCDMOB command later. Double check your numeric constants here also.

Make sure your source code variables used to initialize registers are unsigned characters (uint8_t) or unsigned integers (uint16_t).

What C compiler are you using? If needed I will write some very simple test code for you to try.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The code you see here is only test code. The conditional compilation is there only for easy switching between debug variants. The code we are examining is complied by the compiler well. I traced it many times. Yes, before writing the TX command we are speaking still about the MOB 0 is really fresh a cleared... All constants seems to be well - you can check it, there is no other non-zero constants expect these which can be seen here - in the sample code. Other constants used outside the scope of the part of the test code are only zeros used during init of CAN (except the timing constants). There is no unintended writes. Preventing it is one of the reason of putting the test code to the "cli" section. When entering the "cli" test-section the whole CAN periphery is in cleared state (all mobs etc...), only the timing registers are set to right values and the periphery is enabled (verified via CANGSTA/ENFG)....

If you have a CAN hardware and another CAN node, try to reproduce the error. Try to write you own simple testcode - the best code you can a tell me the result. The code should only send out a single message (ID==130h, DLC=5, RTR active). Before sending it set all the CANIDM to 0 - don't ask why, do it. Put a break point a line under the line where TX command will be written and observe what will happen (depending on traffic/no traffic on the CAN).
I think you will be surprised.

btw: Recently I got an information I'm not the only one who is facing this issue. But I haven't the another code up to now. So I can't judge it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It seems I was right. It is as I have supposed. Here is answer from Atmel support:

When RTRTAG is set, the frame which goes out, is considered as a Remote Frame. In that case, the AT90CAN128 device is expected to receive some data. When the data arrives, you see that the RXOK flag is set. This is the expected behavior.

Best Regards,
Jain Joseph
Atmel Technical Support Team

Yes, it is a good way how to hadle the remote frame replies. But it is completely undescribed feature...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello, I am having also strange issue when trying to send messages with an unconnected CAN.

Maybe col369 is still active and can provide some support?

Or maybe can I write to the ATMEL people as he did?

Do they even support AT90CAN128 anymore?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you just going to keep necromancing old CAN threads until someone pays attention to you?  That's not really how it works...

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Still having some questions about the behaviour of the CAN on the AT90CAN128. Where should I post them?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

bbogdanmircea wrote:
Where should I post them?
NOT on the end of every last existing thread about CAN !!

 

Moderator.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, please delete my post from here and leave the one for the CAN problem topic

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

bbogdanmircea wrote:
leave the one for the CAN problem topic

provide a link - for anyone who's interested to follow it ...

 

The post number gives a link to the specific post:

 

#CiteSpecificPost #LinkSpecificPost #ReferenceSpecificPost 

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Thu. Nov 21, 2019 - 10:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
Topic locked