LPC546 MCAN TX FIFO mode

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

LPC546 MCAN TX FIFO mode

ソリューションへジャンプ
2,714件の閲覧回数
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,701件の閲覧回数
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,610件の閲覧回数
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,702件の閲覧回数
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,534件の閲覧回数
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,682件の閲覧回数
Patrick88
Contributor II

Thank.@Raul,

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

0 件の賞賛
返信