To use the TX mailboxes like a TX FIFO in KSDK 1.3, you need to override the default behaviour of the drivers.
It would be better to write your own TX drivers but here's how to do it if you are not inclined to do that.
This example is written in MQX but it's probably relatively easy to do the same thing in baremetal.
The IRQ Handler:
You need to now service your own flags for the mailboxes (since the TxDone flag only works with a single active mailbox)
void MQX_CAN0_ORed_Message_buffer_IRQHandler(void)
{
volatile uint32_t flag_reg;
uint32_t temp;
/* Get the interrupts that are enabled and ready */
flag_reg = ((FLEXCAN_HAL_GetAllMsgBuffIntStatusFlag(CAN0_BASE_PTR)) & CAN_IMASK1_BUFLM_MASK) & CAN_RD_IMASK1(CAN0_BASE_PTR);
for (uint32_t i = MB_OFFSET_TX ; i < ( MB_OFFSET_TX + NUMBER_OF_TX_MB ) ; i++ )
{
temp = (1 << i);
if (flag_reg & temp)
{
/* Complete transmit data */
mailbox_flags[0] &= ~temp;
/* Disable the transmitter data register empty interrupt */
FLEXCAN_HAL_SetMsgBuffIntCmd(CAN0_BASE_PTR, i, false);
/* Disable error interrupts */
FLEXCAN_HAL_SetErrIntCmd(CAN0_BASE_PTR,kFlexCanIntErr,false);
FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(CAN0_BASE_PTR, temp & flag_reg);
}
}
/* Get the interrupts that are enabled and ready */
FLEXCAN_DRV_IRQHandler(0);
}
Transmitting a message:
Create a ring buffer of the flags and set the mailbox flag of the mailbox you are transmitting to
We are popping messages off of a message queue in a task, but the important stuff is between the _int_disable and enable
You can see that I am overriding the isTxBusy flag, this is so that the FLEXCAN_DRV_Send doesn't ignore the message
void can_send ( uint8_t chnl )
{
// calculate which mb to use
uint32_t mb_to_send = (flexcan_mb_counter[chnl])+MB_OFFSET_TX;
if ( mailbox_flags[chnl] & ( 1 << mb_to_send ) )
{
// _time_delay_ticks(1);
return;
}
if ( _msgq_get_count( can_channels[chnl].txq ) == 0 )
{
return;
}
// get flexcan message from private queue
can_dequeue_tx(chnl, &tx_frame[chnl]);
// tx info has two parameters, data length and frame size (std vs ext), this sets datalen
tx_info.data_length = (tx_frame[chnl].cs >> 16) & 0xF;
// send the can message on the hardware
_int_disable();
FLEXCAN_DRV_ConfigTxMb(chnl, mb_to_send, &tx_info, tx_frame[chnl].msgId);
can_channel_state[chnl].isTxBusy = false;
mailbox_flags[chnl] |= ( 1 << mb_to_send );
FLEXCAN_DRV_Send(chnl, mb_to_send, &tx_info, tx_frame[chnl].msgId, tx_frame[chnl].data);
_int_enable();
// update the mb counter
flexcan_mb_counter[chnl] = (++flexcan_mb_counter[chnl])%NUMBER_OF_TX_MB;
}