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.
Hello
In TI provideded file bl_can.c
C:\ti\simplelink_msp432e4_sdk_4_20_00_12\source\ti\devices\msp432e4\boot_loader\
At
function
CANMessageGetRx(uint8_t *pui8Data, uint32_t *pui32MsgID)
I'm finding that once CAN_IF1MCTL_MSGLST is set, it is stuck there and won't clear.
What's the right way to clear it?
I tried at line 381:
if((ui16MsgCtrl & CAN_IF1MCTL_MSGLST) == CAN_IF1MCTL_MSGLST)
{
CAN0->IF2CMSK = CAN_IF1CMSK_NEWDAT;
CAN0->IF2CRQ = MSG_OBJ_BCAST_RX_ID;
CAN0->IF2MCTL &= 0x3FFF; // clear newdat & lost
while(CAN0->IF2CRQ & CAN_IF2CRQ_BUSY)
{
}
}
Hi,
I think you want to first find out why the MSGLST is set. It means that your incoming message is arriving while the last message has not been processed yet.
if((ui16MsgCtrl & CAN_IF1MCTL_MSGLST) == CAN_IF1MCTL_MSGLST)
{
CAN0->IF2CMSK = CAN_IF1CMSK_NEWDAT;
CAN0->IF2CRQ = MSG_OBJ_BCAST_RX_ID;
CAN0->IF2MCTL &= 0x3FFF; // clear newdat & lost
while(CAN0->IF2CRQ & CAN_IF2CRQ_BUSY)
{
I don't really see a problem here. Have you tried it and what did you see?
Hello, the overrun happens because the flash burning takes time. There's other CAN traffic and I can't use a filter for reasons I won't go into. When running under debugger, once I hit the breakpoint in the code shown, I never again hit a breakpoint in the preceding NOT LOST code, but keeping hitting this code. This makes me believe I am not correctly clearing the MSGLST. The TRM is vague about how to clear it,
Hi John,
Are you in interrupt mode? Other than message list, do you see any errors on CANSTS and CANERR registers?
Perhaps I should also ask what is your intention for the below code. You have already lost a prior message. Are you trying to read the new message? If you are trying to clear the newdat & msglst bits then why would you use &= with F? If newdat & msglst are 1, doing a &= does not clear the bits to 0.
if((ui16MsgCtrl & CAN_IF1MCTL_MSGLST) == CAN_IF1MCTL_MSGLST)
{
CAN0->IF2CMSK = CAN_IF1CMSK_NEWDAT;
CAN0->IF2CRQ = MSG_OBJ_BCAST_RX_ID;
CAN0->IF2MCTL &= 0x3FFF; // clear newdat & lost
while(CAN0->IF2CRQ & CAN_IF2CRQ_BUSY)
{
Hello
Again refer to the bl_can.c file from the simplelink sdk
When I have fallen into the else block at line 380
CAN0->ERR = 0
CAN0->STS = 0x0018
CAN0->IF2MCTL = 0xD084
This is a non-interrupt bootloader that is re-flashing the application area of the chip based on blocks of data sent in through CAN.
The next data block isn't sent to me until I send an acknowledgement. The other traffic that caused the overrun is irrelevant to me at that time.
The intention of the code block is to be able to recover from the overrun, discard lost incoming CAN frames and resume communication.
The problem is, it doesn't recover, it gets stuck forever falling into that else block at line 380.
Maybe I need to implement an interrupt service routine, could you point me to an example.
The CAN0->IF2MCTL &= 0x3FFF
does clear CAN_IF1MCTL_NEWDAT (0x8000) and CAN_IF1MCTL_MSGLST ((0x4000)
0011 1111 1111 1111
&
1101 0000 1000 0100
=
0001 0000 1000 0100
And I can see this happen in the CCS registers window
Hi John,
Indeed, the link is broken and posted 15 years ago. I copy and paste the reply.
The MSG_OBJ_DATA_LOST bit is cleared by writing the bit to a zero in the message object. This requires a read/modify/write sequence using the IFn registers when you are directly accessing the CAN registers as there are many other very important bits in this register so you cannot just clear it.
If you are using the DriverLib CAN APIs, a call to CANMessageSet() with the results of your CANMessageGet() call will clear the MSG_OBJ_DATA_LOST flag for you. Here is a little code snippet that will do the trick.
Code: |
|