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.

Determining when it is safe to write the a transmit mailbox in the eCAN module



The CANTA register indicates when a message was sent but it doesn't indicate that a mailbox is ready after power up. The demo code does this:

 

 do

     {

       ECanaShadow.CANTA.all = ECanaRegs.CANTA.all;

     } while(ECanaShadow.CANTA.bit.TA25 == 0 );   // Wait for TA5 bit to be set..

 

This code assumes that nothing was written to the mailbox to begin with and waits until it is sent before it moves on to write more data.

 

I can't wait for the bit and I can't necessarily assume it is empty to begin with. Seems there should be a flag to indicate the mailbox is empty. Perhaps I am missing something. What is the best practice for this?

 

To get around it in my code, I always check if the CANTA bit is set before writing to the mailbox. I get the bit set initially by writing some arbitrary message after power up. I don't particularly like this solution. What is the best way to handle this?

 

Thanks

  • I am not quite sure what your point is.

    Here is my point of view:

    A transmit mailbox is actually never "empty", there are always data in the mailbox buffer.

    The sequence to send CAN data is:

    (1) write new data into the mailbox buffer; mailbox is full.

    (2) set TRS to start the transmission. At this moment the mailbox is, if you like,  marked as "full". Since it is your instruction, which sets TRS, the "full" status can be monitored by your code. As long as you do not set TRS, you can always change the mailbox data content. 

    (3) wait for TA (or use a mailbox Interrupt Service) to inform your software, that the data have been transmitted. At this moment, the mailbox is again "empty".  The mailbox-buffer is actually not "empty", it still holds the data from the last message. So "empty"  does not mean that the buffer is cleared, it says that you can write new data into the mailbox.

    After a RESET there are random data in all mailbox buffers, but since TRS was never set before, it does not make sense to wait for TA. So what's wrong with going directly into the sequence (1),(2),(3) from above for the 1st transmission?

    If you are inside your control loop and you would like to send new (next) data, then you must apply a state machine to your code. State machine: if a previous TRS is not acknowledged by the corresponding TA or an mailbox-ISR, then you  cannot copy the new data into the mailbox, because the previous data are still pending. You can prioritize the new data against the old data by using TRR and AA for the old message, but that is another topic.

     

     

     

     

     

     

     

     

     

  • I was just looking for a best practice.

    On a UART, I can always check to see if the holding register is empty. If it is, I can write. With this eCAN module you can't do that. Like you said, you have to have a state machine.

    Something like...

     

    static int state = 0;


    switch(state)
    {
    case 0: // mailbox has never been written to
    WriteToCAN(bytes);
    state++;
    break;

    case 1: // mailbox has been written to before
    if (CheckTABit() == SENT)
    WriteToCAN(bytes);
    break;

    }

     

    Just seems a bit awkward to me. Not really a big deal, just wanted to make sure I wasn't missing something.

     

    Thanks