LPC546 MCAN TX FIFO mode

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

LPC546 MCAN TX FIFO mode

跳至解决方案
2,614 次查看
Patrick88
Contributor II

Hi, I'm using LPC54618 with mcan module. In SDK demos, there is only demos of sending can data with "dedicated buffers", while the real sending sequence is determined by CAN ID, But I need send CAN frames sequentially, as in a FIFO way.

I find there is "tx FIFO/queue" way of sending data, but no demos or APIs. Is there any demo or brief about how to use MCAN "tx FIFO/queue" method, or can anyone give me some tips. Thanks!

标签 (1)
0 项奖励
回复
1 解答
2,601 次查看
RaRo
NXP TechSupport
NXP TechSupport

Hello @Patrick88,

Unfortunately, as you mention there is not an example to start with TX FIFO/QUEUE with MCAN module. Nonetheless, next we list information could be useful to take a look at:

Best regards, Raul.

在原帖中查看解决方案

0 项奖励
回复
4 回复数
2,510 次查看
Patrick88
Contributor II

HI.@Raul,

Thank you for your advice, I've found a solution for my question.

①In MCAN initialization code, set TX FIFO configuration : 

    mcan_tx_buffer_config_t txBuffer =
    {
        .address = TX_BUFFER_OFS,
        .dedicatedSize = 0U,
        .fqSize = 32,
        .mode = kMCAN_txFifo,
        .datafieldSize = 64,
    };
②In application code :
uint8_t idx_arr[32];
uint8_t idx_idx;

bool MCAN_SendWithFifo(CAN_Type* base, mcan_tx_buffer_frame_t* tx)
{
    /*check if TX FIFO is full*/
    if(base->TXFQS & CAN_TXFQS_TFQF_MASK)
        return false;

    /*get TX FIFO put index*/
    uint8_t idx = ((base->TXFQS & CAN_TXFQS_TFQPI_MASK) >> CAN_TXFQS_TFQPI_SHIFT);
    idx_arr[idx_idx] = idx;
    idx_idx = (idx_idx+1)%32;
    mcan_buffer_transfer_t xfer =
    {
        .bufferIdx = idx,
        .frame = tx,
    };

    /*actually copy data to TX buffer, and add request to send message out*/
    status_t err = MCAN_TransferSendNonBlocking(base, CANFD_Channels[ch].CANHandle, &xfer);
    if(kStatus_Success == err)
        return true;
    else
        return false;
}
③In MCAN ISR code, as I use only TX FIFO and no TX BUFFER or TX QUEUE, I do the following change :
 
void MCAN_TransferHandleIRQ(CAN_Type *base, mcan_handle_t *handle)
{
...............................
        else if (0U != (valueIR & (uint32_t)kMCAN_TxTransmitCompleteFlag))
        {
            /* Solve Tx interrupt. */
            uint8_t idx = 0U;
            // for (; idx < (uint8_t)((base->TXBC & CAN_TXBC_NDTB_MASK) >> CAN_TXBC_NDTB_SHIFT); idx++)
            for(; idx < (uint8_t)((base->TXBC & CAN_TXBC_TFQS_MASK) >> CAN_TXBC_TFQS_SHIFT); idx++)
            {
                /* Get the lowest unhandled Tx Message Buffer */
                if (0U != MCAN_IsTransmitOccurred(base, idx))
                {
                    if ((base->TXBTIE & ((uint32_t)1U << idx)) != 0U)
                    {
                        MCAN_TransferAbortSend(base, handle, idx);
                    }
                }
            }
            result = (uint32_t)kMCAN_TxTransmitCompleteFlag;
            status = kStatus_MCAN_TxIdle;
        }
...............................
}
 
Above all, MCAN TX FIFO mode is now working. I think this solution is not good enough, but works for my project, hopefully someone can give a better one, or an official solution soon.
 
Thank You Again!
2,602 次查看
RaRo
NXP TechSupport
NXP TechSupport

Hello @Patrick88,

Unfortunately, as you mention there is not an example to start with TX FIFO/QUEUE with MCAN module. Nonetheless, next we list information could be useful to take a look at:

Best regards, Raul.

0 项奖励
回复
2,434 次查看
Patrick88
Contributor II

Hi.@Raul,

With your tips, I finally found a slotion as below.

①in MCAN initialization code, configure TX Buffer:

    mcan_tx_buffer_config_t txBuffer =
    {
        .address = TX_BUFFER_OFS,
        .dedicatedSize = 0U,
        .fqSize = 32,
        .mode = kMCAN_txFifo,
        .datafieldSize = 64,
    };
②in application code:
 
uint8_t idx_arr[32];
uint8_t idx_idx;

bool MCAN_SendWithFifo(CAN_Type* base, mcan_tx_buffer_frame_t* tx)
{
    /*check if TX FIFO is full*/
    if(base->TXFQS & CAN_TXFQS_TFQF_MASK)
        return false;

    /*get TX FIFO put index*/
    uint8_t idx = ((base->TXFQS & CAN_TXFQS_TFQPI_MASK) >> CAN_TXFQS_TFQPI_SHIFT);
    idx_arr[idx_idx] = idx;
    idx_idx = (idx_idx+1)%32;
    mcan_buffer_transfer_t xfer =
    {
        .bufferIdx = idx,
        .frame = tx,
    };

    /*actually copy data to TX buffer, and add request to send message out*/
    status_t err = MCAN_TransferSendNonBlocking(base, CANFD_Channels[ch].CANHandle, &xfer);
    if(kStatus_Success == err)
        return true;
    else
        return false;
}
 
③In MCAN ISR code, as I use TX FIFO only and no TX BUFFER or TX QUEUE, I did some change:
 
.................
        else if (0U != (valueIR & (uint32_t)kMCAN_TxTransmitCompleteFlag))
        {
            /* Solve Tx interrupt. */
            uint8_t idx = 0U;
            // for (; idx < (uint8_t)((base->TXBC & CAN_TXBC_NDTB_MASK) >> CAN_TXBC_NDTB_SHIFT); idx++)
            for(; idx < (uint8_t)((base->TXBC & CAN_TXBC_TFQS_MASK) >> CAN_TXBC_TFQS_SHIFT); idx++)
            {
                /* Get the lowest unhandled Tx Message Buffer */
                if (0U != MCAN_IsTransmitOccurred(base, idx))
                {
                    if ((base->TXBTIE & ((uint32_t)1U << idx)) != 0U)
                    {
                        MCAN_TransferAbortSend(base, handle, idx);
                    }
                }
            }
            result = (uint32_t)kMCAN_TxTransmitCompleteFlag;
            status = kStatus_MCAN_TxIdle;
        }
.................
 
Above all, mcan now works with TXFIFO mode, and sends messages sequentially. I think this solution is not good enough, but it works for my project, and hopefully someone can give a better solution or an official solution soon.
 
Thank you!
2,582 次查看
Patrick88
Contributor II

Thank.@Raul,

I will look into the files you mentioned above, and post the solution if I find any.

0 项奖励
回复