Tool/software:
Hi,
TCAN in my system works fine as long as there is ACK on CAN. If there is no ACK I got SPIERR. Sometimes it happens after hundreds of ms sometimes after around a minute but it never happens when ACK is on CAN. Strange thing is that it seems to be dependent of working time of the system. For example after a couple of hours this error happens after about a minute and then with every try it happens faster (sometimes hundreds ms).
- I use SPI CLK set at 16 MHz, but I have tried at 8, 4, 2 MHz and nothing changed.
- 20 MHz crystal with 10 pF. I have also tried 18 pF and 40 MHz and nothing changed.
- When I read register 0x0008 I got 0x00110201.
- TCAN does not send any messages to TCAN. (So TCAN RX is empty)
- I clear M_RAM at the beggining.
- My M_RAM does not overlap and is configured properly. (Rx0NumElements 64, TxBufferNumElements 32, all other elements size 0, all ElementSize 8 byte data, TX as FIFO)
- The error only happens if DAR is set to 0. When I set it to 1 SPIERR does not occur. I need DAR to be 0.
// TxRoutine Pseudo Code
// Step 1: Read the Transmit FIFO/Queue Status register
TXFQS = readRegister(0x10C4) // TXFQS: Transmit FIFO/Queue Status
// Step 2: Check if Tx FIFO is not full and free level grater than zero
if (TXFQS.TFQF == 0 && TXFQS.TFFL > 0) {
// Step 3: Calculate the base address to write the message
// 0x8400 is the start address of the Tx FIFO (after RX0)
// Each Tx buffer is 16 bytes
address = 0x8400 + (16 * TXFQS.TFQPI)
// Step 4: Write the message to the calculated Tx buffer address
write(address, sizeof(4 * u32), msgBuff)
// Step 5: Set TxBar
tmpTxBar = 0
tmpTxBar = 1 << TXFQS.TFQPI // Set bit corresponding to Tx FIFO Put Index
// Step 6: Trigger the transmission by TxBar
write(0x10D0, sizeof(u32), tmpTxBar)
}
As you can see I do not add messages if FIFO is full and it will be if there will be no ACK.
So I will add messages and TFFL will be decresing and TFQPI will be increasing until TFFL will be 0, TFQPI will go back to 0 and TFQF will be 1. So I will be only reading TXFQS = readRegister(0x10C4).
(Although sometimes I saw TFGI incremented when no ACK so how was that possible?)
And then after some time I got interrupt - dev_ir 0x88 (SPIERR, GLOBALERR), mcan_ir 0x9810000 (TSW, EP, EW, PEA).
Then I handle SPIERR by first reading statusReg (0x000C) and it is 0xA00000C (Read_fifo_empty, Internal_error_log_write, Internal_error_interrupt, Internal_access_active).
Then I read 0x0010 and is it 0x0. Then I write 0xFFFFFFFF to statusReg (0x000C). Next I read 0x000C and it is 0x8.
Next I read EcrReg (0x1040) to clear CEL (CAN Error Logging).
I also read PSR (0x1040) to see BO, EP, EW and it is equal to 0x7E5 so BO (Bus Off) flag is set. Then I read CCCR (0x1018) and it is 0x1. Then I write 0x0 to CCCR (0x1018).
Now I clear interrupts so I write value of this dev_ir and mcan_ir to them. After this for debug I read them again and 0x4000 TXFF
After this TXFQF is all 0 so there is an error there because if TFFL == 0 then TFQF must be 1.
I do not know why SPIERR happens when no ACK and how to handle it. Why does it affect TXFQF? Looking forward for your response!
Regards,
Mateusz