infineon4engineers Facebook

infineon@google+ Google+

infineon@linkedin linkedin

infineon4engi@twitter twitter

infineon@youtube youtube

+ Reply to Thread
Results 1 to 6 of 6

Thread: XMC4500 multiCAN, getting MSGLST in a RXFIFO configuration

  1. #1
    Beginner Beginner OMR will become famous soon enough
    Join Date
    Apr 2013
    Posts
    95
    Points
    129.58984375

    XMC4500 multiCAN, getting MSGLST in a RXFIFO configuration

    Hello.

    Just wanted to check if anyone else is seeing this problem.

    We have set up a Gateway node connecting 2 CANnets.
    Since the HW Gateway has it quirks http://see https://www.infineonforum...4400-Multican?, we opted for setting up 4 RX FIFOs and let the irq routines do the data shuffling.

    This scheme works almost OK, but we are experiencing MSGLST from a MO in the RXFIFO even though the FIFO is not full.
    The CAN_RXOF irq is enabled (and tested OK), but is not asserted in these MSGLST cases.
    Fault rate is about 1-2 messages in about 40 millions, so the FIFOs wrapps around numerous times. We also have a FIFO highwater-mark monitor, and it shows that the FIFO is filled with max 2 unread messages at the time MSGLST is set.
    FIFO sizes vary from 8 to 20 MOs.
    Have also implemented a test command where the RX irq routine can skip n readouts, hence filling the FIFO, and that also works fine. Next irq that reads, empties the FIFO.

    We are using the MSIMASK/MSID HW registers to find out which FIFO to read from.

    In all the multiCAN examples we have come across, there is no examples on how to empty multiple RXFIFO using the MSIMASK/MSID HW registers.

    Hoping someone can chime in on this one.

    Here is our irq routine:

    Code:
        bool receive(CanMessage* msg)
        {
            uint32_t pendingIndex;
            int i;
    //        printf("%s:\n", m_owner);
    //        printf("MSPND:   %08x %08x\n", CAN->MSPND[1], CAN->MSPND[0]);
    //        printf("MSIMASK: %08x %08x\n", m_msimask[1], m_msimask[0]);
    
            if (m_irqOwner != (uint32_t)(PPB->ICSR & PPB_ICSR_VECTACTIVE_Msk) - 16) {
                Can *can = Can::getInstance();
                can->s_wrongIRQ++;
                return false;
            }
    
            for (i=0; i<2; i++) {
                CAN->MSIMASK = m_msimask[i];
                pendingIndex = CAN->MSID[i];
    //            printf("%-15s[%d] %d\n", "pendingIndex", i, pendingIndex);
    
                if (pendingIndex == CAN_MSI_NO_PENDING) {
                    if (i == 1) {
                        return false;
                    }
                    else {
                        continue;
                    }
                }
                CLR_BIT(CAN->MSPND[i], pendingIndex);
                pendingIndex += 32*i;
                break;
            }
    //        printf("%-15s %d\n", "pendingIndex", pendingIndex);
            uint8_t baseIndex = m_messageObjects.front().getNumber();
            XMC_CAN_MO_t* baseMoPtr = m_messageObjects.front().getMoPtr();
            XMC_CAN_FIFO_SetSELMO(baseMoPtr, pendingIndex);
            //printf("%-15s %d\n", "baseIndex", baseIndex);        
            return m_messageObjects[pendingIndex - baseIndex].receive(msg);
        }
    
        bool receive(CanMessage* msg)
        {
            uint32_t mo_message_lost = (uint32_t)((m_xmcCanMo.can_mo_ptr->MOSTAT) & CAN_MO_MOSTAT_MSGLST_Msk) >> CAN_MO_MOSTAT_MSGLST_Pos;
    checkAgain:
            m_xmcCanMo.can_mo_ptr->MOCTR = CAN_MO_MOCTR_RESNEWDAT_Msk | CAN_MO_MOCTR_RESRXPND_Msk; // reset NEWDAT & RXPND
    
            if ((((m_xmcCanMo.can_mo_ptr->MOAR) & CAN_MO_MOAR_IDE_Msk) >> CAN_MO_MOAR_IDE_Pos) == 1U) { // 29-bit ID
                uint32_t identifier = (m_xmcCanMo.can_mo_ptr->MOAR & CAN_MO_MOAR_ID_Msk);
                newCanMessage(msg, identifier & 0x000000ff);
                msg->size       = (uint8_t)((uint32_t)((m_xmcCanMo.can_mo_ptr->MOFCR) & CAN_MO_MOFCR_DLC_Msk) >> CAN_MO_MOFCR_DLC_Pos);
                msg->identifier = identifier;
                msg->nodeNum    = (identifier & 0x0000ff00) >> 8;
                uint32_t* dataPtr = reinterpret_cast<uint32_t*>(msg->data);
                if (msg->size > 0) {
                    dataPtr[0] = m_xmcCanMo.can_mo_ptr->MODATAL;
                }
                if (msg->size > 4) {
                    dataPtr[1] = m_xmcCanMo.can_mo_ptr->MODATAH;
                }
            }
    
            uint32_t mo_new_data_available = (uint32_t)((m_xmcCanMo.can_mo_ptr->MOSTAT) & CAN_MO_MOSTAT_NEWDAT_Msk) >> CAN_MO_MOSTAT_NEWDAT_Pos;
            uint32_t mo_recepcion_ongoing = (uint32_t)((m_xmcCanMo.can_mo_ptr->MOSTAT) & CAN_MO_MOSTAT_RXUPD_Msk) >> CAN_MO_MOSTAT_RXUPD_Pos;
    
            if ((mo_new_data_available) || (mo_recepcion_ongoing)) {
                Can::s_checkedAgain++;
                goto checkAgain;
            }
    
            if (mo_message_lost) {
                m_xmcCanMo.can_mo_ptr->MOCTR = CAN_MO_MOCTR_RESMSGLST_Msk; // reset lost bit
                if (Can::s_gatewayEnabled) {
                    if ((m_number>=CAN_RX12_MOSTART) && (m_number<=CAN_RX12_MOEND)) {
                        Can::s_lostCntr1++;
                    } else {
                        if ((m_number>=CAN_RX2_MOSTART) && (m_number<=CAN_RX2_MOEND)) {
                            Can::s_lostCntr2++;
                        }
                    }
                } else {
                    if ((m_number>=CAN_RX_MOSTART) && (m_number<=CAN_RX_MOEND)) {
                        Can::s_lostCntr1++;
                    }
                }
                //            panic_printf(PANIC_USER, "CAN MSG LOST, MO%02d, idle %d%%", m_number, getIdlePercent());
                ////            panic_printf(PANIC_USER, "LOST MO%02d %08x %08x", m_number, CAN->MSPND[1], CAN->MSPND[0]);
                ////            printf("\n\nLOST MO%02d %08x %08x\n\n", m_number, CAN->MSPND[1], CAN->MSPND[0]);
                //            return false;
            }
    
    
            //        if (mo_recepcion_ongoing) {
            //            panic_printf(PANIC_USER, "CAN MSG RX BUSY, MO%02d", m_number);
            //        }
    
            return true;
        }
    (Also opened a support case: Case:3740999)
    Last edited by OMR; May 1st, 2018 at 11:20 PM.

  2. #2
    Intermediate Intermediate frankvh2 is on a distinguished road
    Join Date
    Jan 2018
    Posts
    21
    Points
    325
    I've done a bunch of testing of CAN code, running packets for days straight, without issues. Although I'm not using the DAVE libraries; we're using our own code. But we haven't seen problems of dropped packets.

    One thing that's noticeable about your code is you're doing a lot in the ISR, including changing variables which seem to be part of some other classes. I assume they're declared as "volatile"? But it makes me wonder if perhaps what you're seeing is some race condition. Is it possible that in some, rare, condition, the ISR triggers at just the right time to confuse some variable (ie, in the middle of a read - modify - write operation) and that's producing the symptom you're seeing?

  3. #3
    Beginner Beginner OMR will become famous soon enough
    Join Date
    Apr 2013
    Posts
    95
    Points
    129.58984375
    Seems like we smoked this one out :-)
    Problem was our FIFO MO allocation and the use of the MSIMASK register to obtain a pendingIndex from MSID[i].
    We had 4 RX FIFOs (and 2 TX MOs. MO0 & MO32), 2 FIFOs had allocated 8 MOs and 2 had 20 MOs.
    They were allocated sequentially from the pool, and one FIFO ended up with MOs in the upper 0-31 range and the lower 32-63.
    Hence, we checked twice for an pending index and there is were it went wrong. Some messages (~1 per million) was not read by the irq routine, and produced a MSGLST when the FIFO wrapped into it.
    Just re-allocating the MOs so that no FIFO belonged to both the 0-31 and the 32-63 range fixed the problem. MSIMASK produced a consistent pending index in just one MSI[] register.
    Our FIFO allocation now looks like this:

    Code:
    CAN RX FIFO: CAN_RX          length:  8, CAN1, filterID: 03002300, filterMask: FFFFFF80, msiMask: 00000000 000001FE, irq: 7, irqOF: 6
    CAN RX FIFO: CAN_RX2         length: 23, CAN2, filterID: 00000000, filterMask: 00000000, msiMask: 00000000 FFFFFE00, irq: 1, irqOF: 6
    CAN RX FIFO: CAN_RXGL        length:  8, CAN1, filterID: 03000000, filterMask: FFFFFF80, msiMask: 000001FE 00000000, irq: 4, irqOF: 6
    CAN RX FIFO: CAN_RX12        length: 20, CAN1, filterID: 03000000, filterMask: FFFF0080, msiMask: 1FFFFE00 00000000, irq: 3, irqOF: 6

  4. #4
    Intermediate Intermediate frankvh2 is on a distinguished road
    Join Date
    Jan 2018
    Posts
    21
    Points
    325
    Good catch.

  5. #5
    Beginner Beginner OMR will become famous soon enough
    Join Date
    Apr 2013
    Posts
    95
    Points
    129.58984375
    This was not the silver bullet we hoped for.
    Our problem with 'false' MSG_LOST continued.
    Then we realised we were on version 2.1.8 of XMClib.
    Stepping to 2.1.18 with the change introduced to void XMC_CAN_MO_Config(const XMC_CAN_MO_t *const can_mo) seemed to do the trick.

    Problem was that TX events was enabled on RX MOs and visa versa. That was why this problem was only an issue on our gateway nodes. They have a lot of continuous TX & RX, on both the CAN1 & CAN2 modules.
    Last edited by OMR; Jun 11th, 2018 at 07:01 AM.

  6. #6
    Beginner Beginner OMR will become famous soon enough
    Join Date
    Apr 2013
    Posts
    95
    Points
    129.58984375
    And still we are getting MSG_LOST a few times every day. (SW FIFO scheme)
    Unsure of what to try next.

    We have a FIFO high-water mark logging scheme and it never uses more than 1 MO.
    We have a test were we can skip n IRQ readings of the FIFO, so that it gets filled. It is emptied OK on the n+1 IRQ.
    We have a IRQ time measurement. It is always in the 14-20us range.

    Fault is only seen on the gateway node with 'simultaneous' TX and RX on both CAN1 & CAN2.
    On nodes with just CAN1 it is not a problem.

    We use systems with 4-7 gateway nodes, and the problem appears on a random node(s) and stays on that node. Other nodes are OK.

    Any suggestions on how to proceed would be most welcome.

+ Reply to Thread

Tags for this Thread

Disclaimer

All content and materials on this site are provided “as is“. Infineon makes no warranties or representations with regard to this content and these materials of any kind, whether express or implied, including without limitation, warranties or representations of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. No license, whether express or implied, is granted by Infineon. Use of the information on this site may require a license from a third party, or a license from Infineon.


Infineon accepts no liability for the content and materials on this site being accurate, complete or up- to-date or for the contents of external links. Infineon distances itself expressly from the contents of the linked pages, over the structure of which Infineon has no control.


Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Usage Terms of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Usage Terms of this site. Infineon reserves the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.