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!