This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EMAC TMS570LC4357 data Entry problem

Other Parts Discussed in Thread: TMS570LC4357, HALCOGEN

Hello,

I have a problem with the EMAC of the TMS570LC4357.

I modified the TMS570LC43x_EMAC_LoopBackMode demo project of halcogen, to send UDP-Packages from the MCU to my Windows-PC (loopbackmode and cache disabled in halcogen). I can see these packages in wireshark. Everything works fine sofar but after 260 packages, the TMS570 always throws a data entry (or data abort) exception.

When I compare the halcogen driver with the requirement for sending packages written in the user manual of ti, I I would say this should be complete and nothing is missing. I did not change anything of the ethernet driver, just configured the payload with ( ip + udp).

I really want a small implementation of the emac-driver, so the lwIP-Demo-Projekt is not a good starting point for me (don't need tcp etc. / footprint to big for my 4 mb flash). I really just want to send simple packages, so please do not simply refer to the lwIP-Demo-Project.

I did also analyse the code of the lwIP-project, but could not find any differences related to the drivers. ( EMACTransmit, hdkif transmit etc ... seems to do the same things)

The solution, I guess should be something simple like clearing a flag or freeing a buffer, but I was not able to find it.

Maybe there is something missing in the driver, which I did not recognize?

-> If I send raw ethernet frames by calling the EMACTransmit(&hdkif_data[0], &pack[0]) function in a loop, I have exactly the same behaviour (data Entry exception in  HL_sys_intvecs.asm)

I read nearly any post and comment about the EMAC in this community but did not find anything that could help me. This is the reason why I post this question now.

Does anyone of you use this MCU and Ethernet and could help me please?


Thank's for your help, already in advance!

Only for your interest: I am receiving FlexRay data on the TMS570 and want to put it into ethernet packages and forward it to my pc on which a software will visualize the data.

  • Hello Sebastian,

    There could be various reasons for a data abort, usually you get a data abort because the CPU tries to fetch data from an unimplemented address or because the MPU configuration denies access to a certain address.
    However, you should go and try to find the source of the abort. The easiest way to to is is to look at the LR register when the CPU enters the data abort, this usually points to the instruction which caused the abort. But there are usually much more information available about the abort, you could read out those via the CP15 registers. Please refer to the ARM Cortex-R5 TRM for a describtion of those, you could also find soem more information in this post: e2e.ti.com/.../686132

    Best Regards,
    Christian
  • Thank's for your quick answer Christian,

    As I can see, there are no protected areas and always the same data is written to this Funktion:

    EMACTransmit(&hdkif_data[0], &pack[0]) ->If would be an "MPU-Issue" it should throw an exception immediately and not after 100 packages ?

    ..But I agree with you, I definitely need to know, why the data Entry exception occurs. Thank's for your Iink. I tried to modify your attached "Data Abort Handler" for my project but failed. Maybe you could help me with that. Below please find the sourceCode of this demo-project.

    /* Include Files */
    #include "HL_sys_common.h"
    #include "HL_emac.h"
    #include "HL_hw_reg_access.h"
    #include "HL_system.h"
    #include "HL_sys_core.h"

    /* Globals */
    uint8 emacAddress[6U] = {0x00U, 0x08U, 0xEEU, 0x03U, 0xA6U, 0x6CU};
    uint32 emacPhyAddress = 1U;
    extern hdkif_t hdkif_data[1];
    pbuf_t pack[5];
    static uint8 data[5][100];
    uint32 size1 = 470,size2=94;

    / * Functions */
    void create_packet()
    {
    ...
    }

    /* Main */
    void main(void)
    {
    EMACHWInit(emacAddress);
    create_packet();
    //_enable_IRQ();

    while(1)
    {
    EMACTransmit(&hdkif_data[0], &pack[0]); // Does work a couple of times
    // before it crashes!
    }
    }

    However I hope there is an easier way to get this run permanently.

    Is there no easier way to solve this problem?

    I mean the LoopBack-Mode project is an offical demo from TI, there should be a lot of know how about it.

    Thank you very much Christian!
  • Sebastian,

    i did a quick analysis. The issue is, that a buffer "overflows" or actually that the last pointer in a linked list points to nowhere. But i have to look deeper into this to better understand the issue.

    For now, the issue appears to happen here:

     /* Copy pbuf information into TX buffer descriptors */

       q = pbuf;

       while(q != NULL)

       {

       /* Initialize the buffer pointer and length */

       /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "RHS is a pointer value required to be stored. - Advisory as per MISRA" */

       /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */  

       curr_bd->bufptr = EMACSwizzleData((uint32)(q->payload));

       /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */

       qLen = (uint16)(q->len);

       curr_bd->bufoff_len = (uint32)EMACSwizzleData(((uint32)(qLen) & 0xFFFFU));

       /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */      

       bd_end = curr_bd;

       /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */

       curr_bd = (emac_tx_bd_t *)EMACSwizzleData((uint32)curr_bd->next);

       q = q->next;

       }

    Best Regards,
    Christian

  • Sebastian,

    I identified two lines of code in the HL_emac.c file which lead to a incorrect pointer value written into the CPPI RAM.

    Those are:

    • Line 1145:
      • Original: last_txbd->next = txch_dma->free_head;
      • Change to: last_txbd->next = (emac_tx_bd_t *)EMACSwizzleData((uint32)txch_dma->free_head); /* TODO: Verify Change! */
    • Line 1488:
      • Original: curr_bd->next = active_head;
      • Change to: curr_bd->next = (emac_tx_bd_t *)EMACSwizzleData((uint32)active_head); /* TODO: Verify Change! */

    These pointers see the wrong data endianness, BE32 vs. LE and thus cause the CPU to try to write the wrong memory location.

    Please let me know if these changes work for you, as I currently don't have a setup to test this by myself.

    Thanks,
    Christian

  • Hello Christian,

    at first I want to thank you so much for analyzing the code!

    This is excactly such a kind of error, I would have expected.
    Unfortunately I was not able to find its location.

    Due to your information, I tried the following:

    while(1)
    {
    EMACDMAInit(&hdkif_data[0U]); // To initialize the TX-Buffer and free CCP-Ram
    EMACTransmit(&hdkif_data[0], &pack[0]);
    }

    This is not an elegant way, but seems to work more or less.
  • Christian,

    it seems that you really found the location which causes the problem.
    I changed the two lines of code in the EMAC driver and now no data Entry exceptions are thrown.

    Thank you so much!
  • I guess now you only have EMACTransmit() in the while loop and data is transmitted and received on the PC side as expected?

    I ask becuase I want to be sure that this was the solution before I submit a bug report.

    Thanks,
    Christian
  • Yes Christian,

    with your proposed changes it works fine by calling only the transmit function:
    while(1)
    {
    EMACTransmit()
    }

    Best regards,
    Sebastian
  • Hello Christian,

    I have still a problem with the EMAC-Driver.

    After I made your proposed changes, there are no data abort exceptions anymore. However another problem appears: After a while sending some packages, the program hangs in the following while-loop.

    /* Wait for the EOQ bit is set */
    while (EMAC_BUF_DESC_EOQ != (EMACSwizzleData(curr_bd->flags_pktlen) & EMAC_BUF_DESC_EOQ))
    {
    }

    inside the EMACTransmit(hdkif_t *hdkif, pbuf_t *pbuf) function.

    What could cause the problem?

    Again calling the EMACDMAInit(&hdkif_data[0U]); function solves the problem.
    As I need to send packages as quick as possible, this is no option for me.

    Do you have any clue what causes the problem?

    Thank's for your help!

    Best regards,
    Sebastian
  • Sebastian,

    I'm not sure what causes the issue, but here is the describtion of the EOQ bit which is polled by this part of the code:

    2.5.4.9 End-of-Queue (EOQ) Flag
    When set, this flag indicates that the descriptor in question was the last descriptor in the transmit queue
    for a given transmit channel, and that the transmitter has halted. This flag is initially cleared by the
    software application prior to adding the descriptor to the transmit queue. This bit is set by the EMAC when
    the EMAC identifies that a descriptor is the last for a given packet (the EOP flag is set), and there are no
    more descriptors in the transmit list (next descriptor pointer is NULL).
    The software application can use this bit to detect when the EMAC transmitter for the corresponding
    channel has halted. This is useful when the application appends additional packet descriptors to a transmit
    queue list that is already owned by the EMAC. Note that this flag is valid on EOP descriptors only.

    Could you please check if the EOP flag is set in the buffer where the program hangs.

    Please refer to the document SPRUE12E for a detailed description of the EMAC and especially CPPI RAM in question. Unfortunately the TRM is missing the CPPI part.

    Have you enabled the TX interrupt? It might be, that the EMAC gets not served in the right order and hangs because of that.

    Best Regards,
    Christian
  • Thank you Christian.
    It was my fault. I changed something and as a result the ISR was not executed.
    No it works fine !
  • Dear Christian,
    I have a new issue. I wanted to use the driver, which is working fine now in a project mit FreeRTOS.
    Therefore I created a project for FreeRTOS and TMS570 with HalCoGen. Again I make the changes in the "emac.c".

    Sending one package is working fine but if I try to send a second one the program runs again into "dataEntry".

    The EMAC interrupts are reached and the interrupts acknowledged the right way.

    I thought this could have something to do with the MPU-Settings in HalCoGen. I tried several configurations, but this did not work.
    Is there anything else changed in HalcoGen, which can lead to this error ?

    Even my old "code" does not run in this new project. Other programs, for example "toggle LEDs" does work.

    As you helped me a lot so far, I hope you have again some useful ideas !

    Thank you!
  • Hello Sebastian,

    I have no experiences with FreeRTOS and I'm not sure what could go wrong with it. You really have to debug the data abort with the help of the LR and CP15 (Data Fault Status Register and Data Fault Address Register) to get to the root cause.

    Best Regards,
    Christian