This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi there,
For the IF2 command register DCAN1IF2CMD, I understand that I have to set TxRqst/NewDat bit #18 to 1 before set to MsgNo to start the IF transfer, to request a clear of NWDATxx at the end of a read operation. However, the said bit for the MsgNo never get cleared, so the application just can't help but read data from CAN interface continuously.
I check DCAN1NWDATxx in order to know whether there is new data.
Am I missing something?
Thanks.
Chuck,
The attached example shows what is needed to send and receive a message.
Thanks and regards,
Zhaohong
Thanks Zhaohong,
I'm working with the polling mode, not ISR.
That is what I've performed, according to TRM para. 16.10.9, the CPU will write first 0x7F to bits [23:16] and then the number of the message object to bits [7:0] of the Command Register. That combination will transfer the whole received message from the Message RAM into the Interface Register set. Additionally, the bits NewDat and IntPnd are cleared in the Message RAM (not in the Interface Register set).
My understanding is that this should clear the corresponding message bit in th eDCAN1NWDATxx register, but it doesn't! So the software is thinking that there is always new data in this given mailbox and can't stop reading it.
Just one details, I transfer 0x7F together with the MsgNo with one Command Register write, could this be the problem? Should I write in two separate transfer to the Command Register?
Thanks.
Hi Zhaohong,
Anything for me on this? I'm stuck on my development now because whenever I received one CAN message, since the application software cannot clear the NewDat, it keeps reading the same data over and over again.
This is true even when the external CAN transmitter has transmitted only one message. The NewDat flag remains ON. I read good data though.
Thanks.
Chuck,
Can you share the source code about how you actually did this?
Thanks and regards,
Zhaohong
Zhaohong,
Thanks for this quick one. Below is my CAN RX module:
void tagCan::rxCan1Msg(u8 msgNo, u32 *data) // receive data from CAN1
{
/* Note from TMS570 TRM para 16.10.9
=================================
The CPU will write first 0x7F to bits [23:16] and then the number of the
message object to bits [7:0] of the Command Register. That combination will
transfer the whole received message from the Message RAM into the Interface
Register set. Additionally, the bits NewDat and IntPnd are cleared in the
Message RAM (not in the Interface Register set).
0x7F is expressed as below:
*/
dcan1if2cmd_bit.WR_RD = 0; // direction: IF1 register read<-message object
dcan1if2cmd_bit.Mask = 1; // access mask bits
dcan1if2cmd_bit.Arb = 1; // transfer arbitration details
dcan1if2cmd_bit.Control = 1; // transfer message control details
dcan1if2cmd_bit.ClrIntPnd = 1; // clear interrupt pending bit
dcan1if2cmd_bit.TxRqst_NewDat = 1; // clear NewDat bit
dcan1if2cmd_bit.DataA = 1; // update data A register
dcan1if2cmd_bit.DataB = 1; // update data B register
dcan1if2cmd_bit.MessageNumber = msgNo; // set message object number
// wait for end of busy signal for interface registers set 2 (IF2)
// tbd: set timeout to detect CAN device not ready problems
while (DCAN1IF2CMD_bit.Busy) // interface registers are protected
continue; // by this command busy bit
DCAN1IF2CMD = dcan1if2cmd; // start the reading process
// wait for end of busy signal for interface registers set 2 (IF2)
// tbd: set timeout to detect CAN device not ready problems
while (DCAN1IF2CMD_bit.Busy) // interface registers are protected
continue; // by this command busy bit
tagA429DataWord word;
word.byte[0] = DCAN1IF2DATA_bit.Data0;
word.byte[1] = DCAN1IF2DATA_bit.Data1;
word.byte[2] = DCAN1IF2DATA_bit.Data2;
word.byte[3] = DCAN1IF2DATA_bit.Data3;
data[0] = word.data;
word.byte[0] = DCAN1IF2DATB_bit.Data4;
word.byte[1] = DCAN1IF2DATB_bit.Data5;
word.byte[2] = DCAN1IF2DATB_bit.Data6;
word.byte[3] = DCAN1IF2DATB_bit.Data7;
data[1] = word.data;
}
Zhaohong,
Just want to add a note: When you see capital letter register name like DCAN1IF2CMD=xxx, it actually write to the memory address (IAR EW); when this same name is in lower letter (dcan1if2cmd=xxx), it is a local variable only. I use the local variable to construct my register value before actually writing to the memory.
Regards.
Chuck,
I have the following suggestions.
This is not needed
while (DCAN1IF2CMD_bit.Busy) // interface registers are protected
continue; // by this command busy bit
Please check in the disassembly window a value of 0x007f0000 + mailbox ID is written to offset address 0x120.
DCAN1IF2CMD = dcan1if2cmd; // start the reading process
// wait for end of busy signal for interface registers set 2 (IF2)
// tbd: set timeout to detect CAN device not ready problems
while (DCAN1IF2CMD_bit.Busy) // interface registers are protected
continue; // by this command busy bit
From debugger memory window, check the change in all message handler registers during above operation. need to refresh display window each time.
Thanks and regards,
Zhaohong
Zhaohong,
The DCAN1IF2CMD memory address is 0xFFF7DD20. I'm receiving CAN message at position 33 (starting at 1) or or message number 32 (0x20). I read good data from the mailbox.
The figure below (red arrows) show the debugging window immediately after writing to the DCAN1IF2CMD register. You can see the bit #0 of register DCAN1NWDAT34 remains at 1, which is the problem.
Just another note: when after stepping the line for DCAN1IF2CMD=xxx line, there is no change whatsoever in the registers window. Registers should be highlighted in RED when there is change, but now they are all black.
Is it possible that I'm able to write to the command register, but something else prevents from resetting the NewDat register?
Chuck,
You read from mailbox 32 (0x20) and you should check bit 31 of NewData register12.
Thanks and regards,
Zhaohong
Zhaohong,
That might be my problem. Are you saying that the MsgNo starts at 1 rather than 0? So when I configure mailbox 0, it actually configures mailbox 64 in the TMS570LS20x?
Another question is that why don't I have to check the BUSY signal of IFCMD register before using the IF?
Thanks.
Chuck,
(1) The mail box number starts at 1. Zero is not a valid number.
(2) If you have not used IF2 interface registers before, why worry about the busy bit?
Thanks and regards,
Zhaohong
Zhaohong,
1) Confirmed. CAN mailbox no. starts at 1.
2) So you mean that I can read IF2DATA and IF2DATB immediately after issuing IF2CMD write (second while waiting loop in my code)?
Thanks.
Chuck,
If you issue any IF2CMD write, you have wait for the busy bit gets cleared.
Thanks and regards,
Zhaohong