Kinetis K22: Automatically repeat a CAN message if bus arbitration fails

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

Kinetis K22: Automatically repeat a CAN message if bus arbitration fails

跳至解决方案
1,729 次查看
thomas_k1
Contributor II

I did setup a project for testing CAN with K22. I do use latest Processor Expert and WinIDA from iSystems.

Using the attached project I tested sending CAN messages. Everything worked fine until I added another node sending messages. My procedure was like this

  1. Timer Interrupt with 1 millisecond cycle time sends Message 1 using mailbox 1. Message1SentCounter++
  2. TX Buffer Free Event sends Message 2 using Mailbox 2. Message2SentCounter++

Both counters incremented synchronously. When I caused the second node sending cyclic messages then Message2SentCounter increments less than Message1SentCounter.

I checked with a CANalyzer that this was true - message 2 wasn't sent often enough. But even Message 1 was not sent es often as I expected. And this makes sense because if message 1 is not sent I won't get the TX Buffer Free Event. Please note that I tried to send 3 messages in 1 ms at a bitrate of 1 Mhz. This is more than enough time.

Ok, next thing I tried was checking for the error value the function. It returned ERR_BUSY and I made this to work around my problem. 

RepeatCounter = 0;
do
{
  Error = CAN1_SendFrame (CAN1_DeviceData, TransmitBuffer_Tlg_1, &Frame);
  RepeatCounter++;
}
while((Error != ERR_OK) && (RepeatCounter < 1000));

This works - that basically is great.

And here comes my questions. 

I give a message to mailbox 1. I expect that the CAN controller sends this message as soon as possible. If it can't access the bus than it should wait until the bus is empty and repeat automatically the message. If bus arbitration fails again it tries next free bus time. I do not expect that I do this by software as I did it int the above source snipped. I do not want to wast my processor time at this loop.

I assume that I make a configuration error. Could anybody help me with this?

Thank you

Best regards

Thomas

标签 (1)
0 项奖励
回复
1 解答
1,388 次查看
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Thomas,

First of all, sorry for the later reply.

I don't think there need to checking the TX and RX flags before copying data to a message box.

Please check below MCUXpresso SDK FlexCAN driver FLEXCAN_WriteTxMb() function,

There doesn't check the CAN_ESR1 the status of TX and the RX bit.

It just need to check MB itself status if the MB is active.

status_t FLEXCAN_WriteTxMb(CAN_Type *base, uint8_t mbIdx, const flexcan_frame_t *txFrame)
{
    /* Assertion. */
    assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
    assert(txFrame);
    assert(txFrame->length <= 8);
    assert(!FLEXCAN_IsMbOccupied(base, mbIdx));

    uint32_t cs_temp = 0;

    /* Check if Message Buffer is available. */
    if (CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) != (base->MB[mbIdx].CS & CAN_CS_CODE_MASK))
    {
        /* Inactive Tx Message Buffer. */
        base->MB[mbIdx].CS = (base->MB[mbIdx].CS & ~CAN_CS_CODE_MASK) | CAN_CS_CODE(kFLEXCAN_TxMbInactive);

        /* Fill Message ID field. */
        base->MB[mbIdx].ID = txFrame->id;

        /* Fill Message Format field. */
        if (kFLEXCAN_FrameFormatExtend == txFrame->format)
        {
            cs_temp |= CAN_CS_SRR_MASK | CAN_CS_IDE_MASK;
        }

        /* Fill Message Type field. */
        if (kFLEXCAN_FrameTypeRemote == txFrame->type)
        {
            cs_temp |= CAN_CS_RTR_MASK;
        }

        cs_temp |= CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) | CAN_CS_DLC(txFrame->length);

        /* Load Message Payload. */
        base->MB[mbIdx].WORD0 = txFrame->dataWord0;
        base->MB[mbIdx].WORD1 = txFrame->dataWord1;

        /* Activate Tx Message Buffer. */
        base->MB[mbIdx].CS = cs_temp;

#if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641)
        base->MB[FLEXCAN_GetFirstValidMb(base)].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
        base->MB[FLEXCAN_GetFirstValidMb(base)].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
#endif

        return kStatus_Success;
    }
    else
    {
        /* Tx Message Buffer is activated, return immediately. */
        return kStatus_Fail;
    }
}

You could download MCUXpresso SDK software from here.

Thank you for the attention.


Have a great day,
Mike

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

在原帖中查看解决方案

4 回复数
1,388 次查看
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Thomas,

First of all, sorry for the delay reply.

We had done some tests about how to reduce FlexCAN TX MB communication interval.

The CANx_CTRL2[TASD] btis value will affect the MBs internal arbitration. If TX MB has been configured completed before previous CAN frame in CRC checking field, the TX MB will jump the arbitration phase and start TX immediately.

I would recommend customer to set the MB1 during CAN bus in busy status.

Then after CAN bus is idle, the MB1 will transfer the message with min. CAN frame interval.

Wish it helps.


Have a great day,
Mike

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 项奖励
回复
1,388 次查看
thomas_k1
Contributor II

Dear Mike,

let me come back to the topic. I'm a lot under pressure do finish my work and therefor I still didn't read the lot of information in the manual regarding FlexCAN - and I'm really sorry for that. But I was trying a bit for checking some assumption.

Ok, I have a CAN controller containing at least 16 message boxes. Of course only one message can be transmitted at the CAN medium at once. Please assume that I want to send a single CAN message using one message box. Let us assume as well that the last message was send successfully.

Now I try to put a new message to that send message box. The code of Processor Expert makes this:

if ((StatusReg & (CAN_PDD_RECEIVING_MESSAGE | CAN_PDD_TRANSMITTING_MESSAGE)) != 0x00U)  { /* Are both IDLE and TX/RX bits of the status register cleared?*/
    return ERR_BUSY;                   /* If yes then error */
  }

It does check in the CAN_ESR1 the status of TX and the RX bit. This is a FlexCAN global register, not part of the message box structure. Why does the function checks whether another message box is receiving a frame and aborts in this case filling in the send message box data with ERR_BUSY? It would make sense if I directly access the CAN medium. But this isn't the case, is it?

Even checking TX does not make sense unless I corrupt data of the specific message box which is sending a frame right now. Why do I have message boxes then there is no buffering provided with it?

Is there really a need for checking the TX and RX flags before copying data to a message box?

Thank you

Best regards

Thomas

0 项奖励
回复
1,389 次查看
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Thomas,

First of all, sorry for the later reply.

I don't think there need to checking the TX and RX flags before copying data to a message box.

Please check below MCUXpresso SDK FlexCAN driver FLEXCAN_WriteTxMb() function,

There doesn't check the CAN_ESR1 the status of TX and the RX bit.

It just need to check MB itself status if the MB is active.

status_t FLEXCAN_WriteTxMb(CAN_Type *base, uint8_t mbIdx, const flexcan_frame_t *txFrame)
{
    /* Assertion. */
    assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
    assert(txFrame);
    assert(txFrame->length <= 8);
    assert(!FLEXCAN_IsMbOccupied(base, mbIdx));

    uint32_t cs_temp = 0;

    /* Check if Message Buffer is available. */
    if (CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) != (base->MB[mbIdx].CS & CAN_CS_CODE_MASK))
    {
        /* Inactive Tx Message Buffer. */
        base->MB[mbIdx].CS = (base->MB[mbIdx].CS & ~CAN_CS_CODE_MASK) | CAN_CS_CODE(kFLEXCAN_TxMbInactive);

        /* Fill Message ID field. */
        base->MB[mbIdx].ID = txFrame->id;

        /* Fill Message Format field. */
        if (kFLEXCAN_FrameFormatExtend == txFrame->format)
        {
            cs_temp |= CAN_CS_SRR_MASK | CAN_CS_IDE_MASK;
        }

        /* Fill Message Type field. */
        if (kFLEXCAN_FrameTypeRemote == txFrame->type)
        {
            cs_temp |= CAN_CS_RTR_MASK;
        }

        cs_temp |= CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) | CAN_CS_DLC(txFrame->length);

        /* Load Message Payload. */
        base->MB[mbIdx].WORD0 = txFrame->dataWord0;
        base->MB[mbIdx].WORD1 = txFrame->dataWord1;

        /* Activate Tx Message Buffer. */
        base->MB[mbIdx].CS = cs_temp;

#if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641)
        base->MB[FLEXCAN_GetFirstValidMb(base)].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
        base->MB[FLEXCAN_GetFirstValidMb(base)].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
#endif

        return kStatus_Success;
    }
    else
    {
        /* Tx Message Buffer is activated, return immediately. */
        return kStatus_Fail;
    }
}

You could download MCUXpresso SDK software from here.

Thank you for the attention.


Have a great day,
Mike

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,388 次查看
thomas_k1
Contributor II

Hello Mike,

thank your for your reply and the work behind it.

I'm not sure whether ot not it will help me. I know that TASD will affect arbitration, but maybe this is not the point here. However, I' ll take some time for understanding your information and give a you a feed-back A.S.A.P

Thanks again

Thomas

0 项奖励
回复