Hello, the CAN Transmit Buffer Empty flag CANTFLG.TXE is set to 1 to clear it, after a write FIFO done to start the transmission, is that? Because from the example code below, after the TX FIFO is filled, CANTFLG = TxbufSel, at this time, TxbufSel is read from CANTBSEL, the bit of selected FIFO should be set.
byte CanTxFrame(CanMsg_t msg)
{
byte TxbufSel;
byte idx; // Index to data within the transmission buffer
if (!CANTFLG) // Retrun if Transmit Buffer is full
return ERR_BUFFER_FULL;
CANTBSEL = CANTFLG; // Select lowest empty buffer
TxbufSel = CANTBSEL; // Backup selected buffer
*((word *) ((word)(&CANTXIDR0)))= msg.ID<<5; // 11bit ID, RTR=0: data frame; IDE=0
// Load data to Data Segment Registers
for (idx=0; idx<(msg.DtLen); idx++) {
*(&CANTXDSR0 + idx) = (msg.data)[idx];
}
CANTXDLR = msg.DtLen; // set Data Length Code
CANTXTBPR = 0; // set highest priority
CANTFLG = TxbufSel; // Start transmission
while ( (CANTFLG&TxbufSel) != TxbufSel); // Wait for Transmission completion
return NO_ERR;
}
Yes, to start transmision you need to clear one of CANTFLG flags.
To fill Tx message buffer, you need to first map one of Tx buffer to address bus. This is what CANTBSEL register is used for. Even if you write 7 to CANTBSEL, only one CANTBSEL bit will read back as set at once, and only 1 out of 3 buffers can be mapped to address bus.
To send selected CANTBSEL buffer, you may just copy CANTBSEL to CANTFLG. Intermediate variable TxbufSel is not required.