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.

AM2434: System Time in EtherCAT Slave Controller Register 0x0910-0x0917

Part Number: AM2434
Other Parts Discussed in Thread: TIDEP-01032

Dear TI Experts,

we are developing an application with an EtherCAT interface on an AM2434 microcontroller. We are using the Industrial Communication SDK V11.00.00. 

For our application we need a timestamp. Our prefered solution would be to use the EtherCAT system time. We are trying to read this information from the EherCAT Slave Control Registers 0x0910-0x0917. However, there is unexpected behaviour. I am not sure if I am missing something or if there is another problem.

Two questions/problems have come up:

  1. The values in the registers 0x0914-0x0917 are not updated. The device is connected to an EtherCAT master (Beckhoff IPC) and is running in DC Sync mode. I see that the values in the registers are set initially as I switch the system to run mode. Afterwards, only the values in 0x0910-0x0913 are changing. There should be an overflow every ~4 seconds leading to a change in the higher registers, but this does not happen.
    I also tried reading the register values of our slave device using TwinCAT. Here, the values are updated. After I read the registers, I can also see updated values in the registers, if I read the values in our controller application.
    Do I need to call any function in order to update the System Time registers 0x0914-0x0917? Or am I missing something else?
  2. If our device is not connected to any EtherCAT master, the system time always shows 0. Is this normal bevaviour? I would have expected that there is a "local time" of the device, which starts at zero.

I´ve tried two ways of reading the register:

  1. Direct access using a pointer to the register address
  2. Using the EtherCAT Slave API function EC_API_SLV_readDoubleWordEscRegister() from ecSlvApi_esc.h 

The behaviour is identical in both ways.

Thanks a lot in advance for your support!

Best regards,
Christian

  • Do I need to call any function in order to update the System Time registers 0x0914-0x0917? Or am I missing something else?

    Can you try using AM243x INDUSTRIAL COMMUNICATIONS SDK: Timer APIs for EtherCAT stack bsp_get_local_sys_time

  • Thanks for your response! 
    I also tried this function, but it gives me an exception (data abort, obviously within the function). I´ve seen there are several other bsp_xx functions for initializing. Are these neccesarry to to be called before? There seems to happen a lot of basic initialization, which I think must have happened before anyway.

  • Hi Christian, 

    So I tried the logging the System Time registers (0x910 - 0x917) with the EtherCAT SubDevice Beckhoff SSC Demo using the bsp_get_local_sys_time() API:

    ====== EtherCAT System Time Reading ======
    System Time Low:  0x2b19adb3
    System Time High: 0x0b5eb047
    Complete Time: 0x0b5eb0472b19adb3
    ======================================
    ====== EtherCAT System Time Reading ======
    System Time Low:  0x676b81cc
    System Time High: 0x0b5eb047
    Complete Time: 0x0b5eb047676b81cc
    ======================================
    ====== EtherCAT System Time Reading ======
    System Time Low:  0xa3bd77ac
    System Time High: 0x0b5eb047
    Complete Time: 0x0b5eb047a3bd77ac
    ======================================
    ====== EtherCAT System Time Reading ======
    System Time Low:  0xe00f6341
    System Time High: 0x0b5eb047
    Complete Time: 0x0b5eb047e00f6341
    ======================================
    ====== EtherCAT System Time Reading ======
    System Time Low:  0x1c614870
    System Time High: 0x0b5eb048
    Complete Time: 0x0b5eb0481c614870
    ======================================
    ====== EtherCAT System Time Reading ======
    System Time Low:  0x58b32f4e
    System Time High: 0x0b5eb048
    Complete Time: 0x0b5eb04858b32f4e
    ======================================
    ====== EtherCAT System Time Reading ======
    System Time Low:  0x95050e36
    System Time High: 0x0b5eb048
    Complete Time: 0x0b5eb04895050e36
    ======================================
    ====== EtherCAT System Time Reading ======
    System Time Low:  0xd156f0ed
    System Time High: 0x0b5eb048
    Complete Time: 0x0b5eb048d156f0ed
    ======================================
    ====== EtherCAT System Time Reading ======
    System Time Low:  0x0da8d28c
    System Time High: 0x0b5eb049
    Complete Time: 0x0b5eb0490da8d28c
    ======================================
    ====== EtherCAT System Time Reading ======
    System Time Low:  0x49fabcc3
    System Time High: 0x0b5eb049
    Complete Time: 0x0b5eb04949fabcc3
    ======================================
    ====== EtherCAT System Time Reading ======
    System Time Low:  0x864c7d76
    System Time High: 0x0b5eb049
    Complete Time: 0x0b5eb049864c7d76
    ======================================
    ====== EtherCAT System Time Reading ======
    System Time Low:  0xc29e856f
    System Time High: 0x0b5eb049
    Complete Time: 0x0b5eb049c29e856f
    ======================================
    ====== EtherCAT System Time Reading ======
    System Time Low:  0xfef04008
    System Time High: 0x0b5eb049
    Complete Time: 0x0b5eb049fef04008
    ======================================
    ====== EtherCAT System Time Reading ======
    System Time Low:  0x3b424aec
    System Time High: 0x0b5eb04a
    Complete Time: 0x0b5eb04a3b424aec
    ======================================

    I've also read the registers using bsp_read_byte() API and I observe 0x914-0x917 is incrementing after 0x910-0x913 overflows. This confirms that the firmware is handling 0x914-0x917 correctly.

    Direct access using a pointer to the register address

    I've tried reading the registers using pointer with the following code and see the expected result:

        // Get base address of shared RAM
        uint8_t *pEscBase = (uint8_t *)(((PRUICSS_HwAttrs *)(pruIcssHandle->hwAttrs))->baseAddr + PRUICSS_SHARED_RAM);
        
        // Create pointers to the system time registers
        uint32_t *pSysTimeLow = (uint32_t *)(pEscBase + 0x910);
        uint32_t *pSysTimeHigh = (uint32_t *)(pEscBase + 0x914);
        
        // Read values using pointer dereferencing
        uint32_t ptr_systime_low = *pSysTimeLow;
        uint32_t ptr_systime_high = *pSysTimeHigh;
        
        // Print header for the pointer-based reading
        DebugP_log("==== System Time via Pointer Access ====\n\r");
        
        // Print the low part (32 bits)
        DebugP_log("System Time Low:  0x%08x\n\r", ptr_systime_low);
        
        // Print the high part (32 bits)
        DebugP_log("System Time High: 0x%08x\n\r", ptr_systime_high);
        
        // Print the complete 64-bit time as a summary
        DebugP_log("Complete Time: 0x%08x%08x\n\r", ptr_systime_high, ptr_systime_low);
        DebugP_log("======================================\n\r");

    Can you share the code you tried to read the System Time. I can try running the same from my side as well.

    Regards,
    Aaron

  • Hi Aaron,

    thanks for your response. Very interesting... basically your code is not much different than mine. I´ve tried two versions, both leading to the same result:

    First Version (ESL_controller_register::OFFSET = 0x30090000):

        volatile uint32_t* esc32 = (volatile uint32_t*) ESL_controller_register::OFFSET;
        // Read registers
        volatile uint32_t lo1 = esc32[0x0910u / 4u]; // 0x0910..0x0913
        volatile uint32_t hi  = esc32[0x0914u / 4u]; // 0x0914..0x0917
        volatile uint32_t lo2 = esc32[0x0910u / 4u]; // read again for overflow detection
        // Overflow during read?
        if (lo2 < lo1)
        {
            hi  = esc32[0x0914u / 4u];
            lo1 = lo2;
        }
        uint64_t t = ((uint64_t) hi << 32) | lo1;
        debugPrint(MessageLevelEnum::status, DebugSourceEnum::EVENTHANDLER, "Hi: %u, Lo: %u, Time %llu\r\n", hi, lo1, t);
    Second version:
        uint32_t low  = 0;
        uint32_t high = 0;
        EC_API_SLV_readDoubleWordEscRegister(p_ethercat_stack->get_ec_slv_handle(), 0x0910, &low);
        EC_API_SLV_readDoubleWordEscRegister(p_ethercat_stack->get_ec_slv_handle(), 0x0914, &high);
     
    I can not really believe, that there is a problem reading the register values. As mentioned, I get correct values for the timepoint of certain "events" (connecting our slave to the master, reading the register values using TwinCAT). Our application is based on the "TIDEP-01032 EtherCAT-Connected Single-Chip Dual-Servo Motor Drive Reference Design". We only use the Kunbus wrapper for controlling the EtherCAT interface, the bsp_xx functions are not used anywhere in our code. Do you think there might be a difference due to that?
    Best regards,
    Christian
  • Hi Christian,

    Looks like the thread got "Resolved" by mistake?

    As mentioned, I get correct values for the timepoint of certain "events" (connecting our slave to the master, reading the register values using TwinCAT)

    Can you provide the network topology? Do you have multiple EtherCAT nodes in the network? Is the first node considered as the DUT here?

    Also, when you say the values are getting updated after doing a TwinCAT read to the corresponding space, are you doing a one-time read or reading continuously (Auto Reload)?

    Do you think there might be a difference due to that?

    I don't expect any issue with the APIs as the pointer read itself is not returning the expected values. I suspect if the System Time is getting updated as expected, based on the topology. Could you also monitor the System Time register (0x30090910 - 0x30090917) from the CCS Memory Browser (View -> Memory Browser):

    Make sure to enable "Continous Refresh" in the view. This will provide an insight if the values are getting updated without any interference.

    Also, if possible, please share the ICSS memory dump:

    • 0x30080000 - 0x300C0000 for ICSSG1
    • 0x30000000 - 0x30040000 for ICSSG0

    Based on the topology of your test environment, I can provide more details.

    Regards,
    Aaron

  • Dear Araron,

    yep, I accidently checked "This resolved my issue", sorry! Problem still exists.

    The topology is as follows: Beckhoff IPC (master) => Beckhoff Axis Controller (first slave) => Our device (second slave)

    I was unfortunately not able to find time to deal with the problem. I just did a quick test and debuged the application to check on the registers. During the debug session, it actually looked like it was working in the way it should. The tests before were all done while booting a release build from flash. I guess you did your tests also with a debug build? 

    I need to have a closer look on this after christmas holidays. I´ll be back in office on January 7th and provide the other information requested by you.

    Thanks again for your great support! I wish you a wonderful christmas time.

    Best regards
    Christian

  • Hi Christian,

    Sure, I'll update the thread with more details.

    Happy Holidays & Happy New Year!

    Regards,
    Aaron

  • Hi Christian,

    So to give a background on the System time working, the MainDevice (TwinCAT) sends 4 bytes ARMW, which will read System Time of first (reference) node and then write that data to the remaining nodes.

    Since a read is issued to the first node, the ESC updates all 8 bytes of the ESC Register from IEP register internally.
    For the remaining nodes, the write action only updates 4 bytes (since datagram length if 4 bytes), hence, 0x914 - 0x917 registers not getting updated. 0x914-0x917 is only updated if a read datagram is issued to the non-reference node (read from TwinCAT), and that is why you see the higher 32-bits are updated when read from the MainDevice.

    Beckhoff IPC (master) => Beckhoff Axis Controller (first slave) => Our device (second slave)

    To add on, with the following topology: Beckhoff IPC (master) => AM243x (first slave or reference slave) => Beckhoff Axis Controller (second slave), you will see that 0x910 - 0x917 Registers are getting updated on AM243x.

    I believe this clarifies the System time implementation. Let me know if you have further queries for the same.

    Regards,
    Aaron

  • Hi Aaron,

    thanks a lot for the additional information. This was very helpful and solves the question. I can see exactly this behaviour with our device.

    Thread can be closed. Thanks for your great support!

    Best regards,
    Christian