Shouldn't CAN FIFO Clear itself?

I implemented the following code to check the CAN FIFO if it’s full before attempting to transmit.

static bool IsFifoFull(string canController)
        IntPtr reg = canController.CompareTo(SC20260.CanBus.Can1) == 0 ? (IntPtr)0x4000A0C4 : (IntPtr)0x4000A4C4;

        int v = Marshal.ReadInt32(reg) & (1 << 21);

        return v != 0;

So basically I while loop on that function before attempting to send. However, I am hitting situations where the value is 0x00200000 (raw register value is 0x00260600)

My question is, shouldn’t the CAN perph transmit until the CAN FIFO is clear? I think the CAN may be locking up without any error.

SC2060 Portal Rev C

Thanks in advance

it clear by itself. That code only check status of fifo, dont clear.

That’s the issue. I’m not trying to clear it… It’s reporting full, even though the device isn’t transmitting, therefore it just sits in an endless loop checking that register.

I think there is a bug in the lower level that is locking up the CAN peripheral

No, if fifo is full then it will throw a Busy exception, not lock up.

How to deal with this exception, it is your way.

The fifo register will clear by self once there is room for another msg.

The code above just wait till available space in fifo.

Right. What I’m saying is that the FIFO is not clearing. I have a while loop checking that function, and it gets stuck in an endless loop.

So the FIFO is reporting full even though the device isn’t sending any messages.

For reference, I’m sending several blocks of about 400 messages.

Corrected, if device sent messages then FIFO wont stay in full forever.

Clear after message sent. If device couldn’t send and fifo clear then it is a big problem :))

You decided to wait till message send. The message couldn’t be sent, you wait forever which is correct.

You can stop your loop anytime, the system is not locked up.

And why is it happened? This is different story, Fifo clear or not clear, doesn’t help you in this case.

You can check speed, configuration…

If you are polling for a value to change, it is good practice to sleep a bit between checks.

Here is the actual code where I am checking the FIFO. Once the message goes into the FIFO then the CAN Peripheral should send this message on its own? Therefore, an endless loop here should not be possible… Right?

while (IsFifoFull(SC20260.CanBus.Can1))
                // this is where the endless loop happens

If I can’t rely on the FIFO to transmit all the messages in it, then what is the correct point of action?

Correct. the message will be send if your setup is correct.

Remove that code, do you still get messages in receiver?

That code works 90% of the time, and the messages are sent as expected.

At random times it gets stuck in that loop and TFQF is 1 and TFFL[5:0] is zero, which would indicate the FIFO is full, but the CAN peripheral isn’t transmitting what’s in the FIFO nor is a Error bubbling up.

No really sure how to debug :confused:

You can Disable and Re-Enable.

But I don’t know problem is sender or receiver. How fast your receiver can handle?

Try to short terminal jumper??

Still trying to figure this out. I assume most of the CAN registers are locked out? I’m trying to see what is causing the CAN hardware fault.


I don’t think those are correct registers, that why you got Argument exception.

ECR I believe should be 0x4000A040, not 0x4000A02C.

0x4000A12C is invalid register, not FDCAN that why you got exception. Max offset register is 0xFC, not sure how you have 0x12C which is out of range.

And we are talking to CAN1, CAN2 has different also.

The FDCAN_TTOST in the datasheet calls for an offset of 0x012C, so I figured base address is 0x4000A000 + 0x12C = 0x4000A12C - If that isn’t correct, what would the correct address be for TTOST? I’m going to have to get PSR and INIT as well.

The memory map also shows
0x4000A000 - 0x4000A3FF FDCAN1 (CAN1) as valid

Ignore ECR, I was just seeing what was in TOCV and reused that variable :slight_smile:

Those are all register you can access. TTOST is not on this list. And I don’t think you can find out something by this register which is only for CAN1.

uint CREL;         /*!< FDCAN Core Release register,                                     Address offset: 0x000 */
uint ENDN;         /*!< FDCAN Endian register,                                           Address offset: 0x004 */
uint RESERVED1;    /*!< Reserved,                                                                        0x008 */
uint DBTP;         /*!< FDCAN Data Bit Timing & Prescaler register,                      Address offset: 0x00C */
uint TEST;         /*!< FDCAN Test register,                                             Address offset: 0x010 */
uint RWD;          /*!< FDCAN RAM Watchdog register,                                     Address offset: 0x014 */
uint CCCR;         /*!< FDCAN CC Control register,                                       Address offset: 0x018 */
uint NBTP;         /*!< FDCAN Nominal Bit Timing & Prescaler register,                   Address offset: 0x01C */
uint TSCC;         /*!< FDCAN Timestamp Counter Configuration register,                  Address offset: 0x020 */
uint TSCV;         /*!< FDCAN Timestamp Counter Value register,                          Address offset: 0x024 */
uint TOCC;         /*!< FDCAN Timeout Counter Configuration register,                    Address offset: 0x028 */
uint TOCV;         /*!< FDCAN Timeout Counter Value register,                            Address offset: 0x02C */
uint RESERVED2[4]; /*!< Reserved,                                                                0x030 - 0x03C */
uint ECR;          /*!< FDCAN Error Counter register,                                    Address offset: 0x040 */
uint PSR;          /*!< FDCAN Protocol Status register,                                  Address offset: 0x044 */
uint TDCR;         /*!< FDCAN Transmitter Delay Compensation register,                   Address offset: 0x048 */
uint RESERVED3;    /*!< Reserved,                                                                        0x04C */
uint IR;           /*!< FDCAN Interrupt register,                                        Address offset: 0x050 */
uint IE;           /*!< FDCAN Interrupt Enable register,                                 Address offset: 0x054 */
uint ILS;          /*!< FDCAN Interrupt Line Select register,                            Address offset: 0x058 */
uint ILE;          /*!< FDCAN Interrupt Line Enable register,                            Address offset: 0x05C */
uint RESERVED4[8]; /*!< Reserved,                                                                0x060 - 0x07C */
uint GFC;          /*!< FDCAN Global Filter Configuration register,                      Address offset: 0x080 */
uint SIDFC;        /*!< FDCAN Standard ID Filter Configuration register,                 Address offset: 0x084 */
uint XIDFC;        /*!< FDCAN Extended ID Filter Configuration register,                 Address offset: 0x088 */
uint RESERVED5;    /*!< Reserved,                                                                        0x08C */
uint XIDAM;        /*!< FDCAN Extended ID AND Mask register,                             Address offset: 0x090 */
uint HPMS;         /*!< FDCAN High Priority Message Status register,                     Address offset: 0x094 */
uint NDAT1;        /*!< FDCAN New Data 1 register,                                       Address offset: 0x098 */
uint NDAT2;        /*!< FDCAN New Data 2 register,                                       Address offset: 0x09C */
uint RXF0C;        /*!< FDCAN Rx FIFO 0 Configuration register,                          Address offset: 0x0A0 */
uint RXF0S;        /*!< FDCAN Rx FIFO 0 Status register,                                 Address offset: 0x0A4 */
uint RXF0A;        /*!< FDCAN Rx FIFO 0 Acknowledge register,                            Address offset: 0x0A8 */
uint RXBC;         /*!< FDCAN Rx Buffer Configuration register,                          Address offset: 0x0AC */
uint RXF1C;        /*!< FDCAN Rx FIFO 1 Configuration register,                          Address offset: 0x0B0 */
uint RXF1S;        /*!< FDCAN Rx FIFO 1 Status register,                                 Address offset: 0x0B4 */
uint RXF1A;        /*!< FDCAN Rx FIFO 1 Acknowledge register,                            Address offset: 0x0B8 */
uint RXESC;        /*!< FDCAN Rx Buffer/FIFO Element Size Configuration register,        Address offset: 0x0BC */
uint TXBC;         /*!< FDCAN Tx Buffer Configuration register,                          Address offset: 0x0C0 */
uint TXFQS;        /*!< FDCAN Tx FIFO/Queue Status register,                             Address offset: 0x0C4 */
uint TXESC;        /*!< FDCAN Tx Buffer Element Size Configuration register,             Address offset: 0x0C8 */
uint TXBRP;        /*!< FDCAN Tx Buffer Request Pending register,                        Address offset: 0x0CC */
uint TXBAR;        /*!< FDCAN Tx Buffer Add Request register,                            Address offset: 0x0D0 */
uint TXBCR;        /*!< FDCAN Tx Buffer Cancellation Request register,                   Address offset: 0x0D4 */
uint TXBTO;        /*!< FDCAN Tx Buffer Transmission Occurred register,                  Address offset: 0x0D8 */
uint TXBCF;        /*!< FDCAN Tx Buffer Cancellation Finished register,                  Address offset: 0x0DC */
uint TXBTIE;       /*!< FDCAN Tx Buffer Transmission Interrupt Enable register,          Address offset: 0x0E0 */
uint TXBCIE;       /*!< FDCAN Tx Buffer Cancellation Finished Interrupt Enable register, Address offset: 0x0E4 */
uint RESERVED6[2]; /*!< Reserved,                                                                0x0E8 - 0x0EC */
uint TXEFC;        /*!< FDCAN Tx Event FIFO Configuration register,                      Address offset: 0x0F0 */
uint TXEFS;        /*!< FDCAN Tx Event FIFO Status register,                             Address offset: 0x0F4 */
uint TXEFA;        /*!< FDCAN Tx Event FIFO Acknowledge register,                        Address offset: 0x0F8 */
uint RESERVED7;    /*!< Reserved,                                                                        0x0FC */

Try to set this registers FDCAN_IE (offset 0x54)

var value = Read(FDCAN_IE);

value |= (1 << 23) | (1 << 24) | (1 << 25) | (1 << 28);

Write(FDCAN_IE, value);

Then poll FDCAN_IR(offset 0x50) to see what error is.