OpenEtherCATsociety / SOEM

Simple Open Source EtherCAT Master
Other
1.3k stars 668 forks source link

Cannot configure Distributed Clocks SYNC0 #29

Closed ghost closed 8 years ago

ghost commented 8 years ago

I've noticed there aren't any example applications that demonstrate Distributed Clocks functionality.

When trying to make a simple example application using SYNC0 (by modifying simple_test) the EtherCAT slave (in this case, an AM3359 ICEv2 evaluation board) continues to use PDO sync, and does not trigger SYNC0 at all. I've put the line "ec_dcsync0(1, TRUE, 1000000U, 0);" before trying to set the slave state to Operational.

TwinCAT v2.11 is able to successfully configure the EtherCAT slave in Distributed Clocks mode and cause the SYNC0 triggers.

What is the proper way of configuring and initializing Distributed Clocks with SOEM? When is the function "ec_dcsync0" supposed to be called?

mheden commented 8 years ago

The ec_dcsync0 could be used after you configured the DC of the slaves (i.e. after ec_configdc() if you use the simple_test example).

If you are sniffing the network you should see something like the following sequence:

  1. read ECT_REG_DCSYSTIME (0x0910)
  2. write start time to ECT_REG_DCSTART0 (0x0990) (in your case it should something in the area of the previous read value + 1_000_000)
  3. write cycle time to ECT_REG_DCCYCLE0 (0x09A0) (i.e. 1_000_000)
  4. activate the DC sync0 by writing 3 (bit 0 and 1) to ECT_REG_DCSYNCACT (0x0981)
ghost commented 8 years ago

Thanks for getting back to me.

I did observe the sequence you laid out in Wireshark, although for step 2 ECT_REG_DCSTART0 is approximately 100_000_000 greater than the value read from register 0x0910 (due to the '#define SyncDelay' in ethercatdc.c)

Unfortunately this procedure did not enable D.C., and the AM3359 ICE board continued to trigger on PDO reception. Hooked up to an oscilloscope I did not see the SYNC0 pin pulse.

This could be because ec_configdc and/or ec_dcsync0 are called while the EcSlaves should be in Safe-Op (ec_config_map() pushes slaves into this state), while Table 3 of ETG.2200 states that initialization of DC clock synchronization is done on the transition from INIT to PRE-OP.

Has this procedure been verified to properly configure D.C. on other EtherCAT slaves?

mheden commented 8 years ago

I haven't seen any problems with configuring the clocks in SAFE_OP but maybe the Sitara is picky about this. If you move ec_configdc() before ec_config_map() the DC configuration will be done in PRE_OPat least, maybe this will work better.

mheden commented 8 years ago

One other thing, according to this page (http://processors.wiki.ti.com/index.php/AM335x_SYSBIOS_Industrial_SDK_01.01.00.10_Release_Notes#Known_Issues_And_Limitations) the Sitara seem to have problems with the way SOEM maps up the process data frame (together with the LRW command SOEM uses by default for process data).

If you see any problems regarding this you can change the LRW to a LRD / LWR combo instead. To do that you set ec_slave[<slave index>].blockLRW to 1 before calling ec_config_map().

ghost commented 8 years ago

Unfortunately changing the call of ec_configdc() + ec_dcsync0() to before ec_config_map() also didn't do the trick, nor did explicitly blocking LRW.

The only other observation that may provide insight into this problem: when I increased the timeout in simple_test to wait for all EcSlaves to get into OP, the EcSlave(s) eventually report they are in SAFEOP+ERROR, with StatusCode = 0x2d (No sync error).

It seems as if the EcSlave application is being configured to use DC-SYNC0, but the actual SYNC0 pulses never occur. Is there any configuration that could prevent the SYNC0 HW line from pulsing?

mheden commented 8 years ago

I'm not sure what kind of software you are running on the AM3359 but do you have an ESI file for it? There could be some settings in there that TwinCAT is doing but since SOEM relies on the information provided from the slave it might be missing something.

If you have the possibility to pull a Wireshark log (with only the AM3359 on the bus) of both TwinCAT and SOEM I can take a quick look at it.

ghost commented 8 years ago

I could not upload files to this issue, so I put all relevant files in a new GitHub repository: https://github.com/AversanJeff/SoemDistributedClockIssue

I've included the TI Example EtherCAT Slave Application ESI (TiEtherCATLib.xml) as I also tested using that, and it did not work.

I noticed in the TwinCAT capture there is some configuration done with the EEPROM, and according to the 'Hardware Data Sheet Section I - Technology', "The Sync/Latch signals are not driven (high-impedance) by some ESCs until the SII EEPROM is successfully loaded." (page I-60)... I'm currently investigating this.

For reference, I've also raised an issue on the TI forums

mheden commented 8 years ago

From the wireshark dump it looks like TwinCAT is activating the SYNC0 unit (packet 6414) after going to PRE_OP (packet 6205). So that should probably be alright in SOEM as well.

Anyway, I suggest you move the ec_configdc after ec_config_init (because otherwise a lot of the internal structures are not set up yet).

I can't see any obvious problems in the SOEM dump either. For example the write to Sync unit activation (0x0981) returns an updated workingcounter so the slave accepts the command.

mheden commented 8 years ago

Also, isn't your EEPROM a bit strange? In the ESI-file the configdata looks like it starts with 0x8000 which should make everything in register 0x0141 disabled (does not explain why it works with TwinCAT though)?

ghost commented 8 years ago

I changed the EEPROM header file to start the ConfigData section with 0x0480 (setting 'Distributed Clocks SYNC Out Unit' to Enabled) and verified no change in behaviour -- seems like this has no effect on the AM3359.

Are there any other ideas as to what could be missing for DC config? Has anyone verified SOEM works with an AM3359 slave device?

ghost commented 8 years ago

Looking at the TwinCAT Wireshark capture again, maybe I was mistaken -- perhaps D.C. doesn't work with AM3359...

Packet #6470 commands the EcSlave into Operational Mode (acknowledged by Packet #6472), however after that every read of the AL Status Register (0x130) returns a value of 4, Safe-Op.

Yet despite this, the board had the EtherCAT RUN LED on (at least it appeared to be always on), no errors were thrown, and I saw the SYNC pin pulse on the oscilloscope...

Any comment on these observations?

mheden commented 8 years ago

It seems like the ESC is defect/buggy if the RUN led is always on at the same time as the AL Status is 0x04 (at least if the LED is controlled by the ESC which I assume it's the case on the AM3359).

Unfortunately I don't have any good suggestions what to do so let's hope you get some good response from the folks at TI.

ghost commented 8 years ago

Okay, thanks. I'll post updates here as this issue progresses.

ghost commented 8 years ago

I managed to get the SYNC0 pulses happening SOMETIMES, but still not reliably -- my EEPROM SII settings for Word 3 (which populates registers 0x982:0x983, the Sync Impulse Length) was 0, which set the DC Sync's to 'Acknowledge Mode' instead of cyclic operation. By changing this to non-0 (I set mine to '0xA') I now occasionally see a stream of Sync Pulses and can get into OP mode.

Unfortunately this is still not reliable, so investigation is still on-going.

ghost commented 8 years ago

I was lucky enough to have Arhur Ketels (one of the original SOEM developers) notice my TI forum post, and he provided some advice that has greatly improved my situation. Here is his full comment:

I'm the programmer of SOEM. Via your thread on ETG I found this post. A common mistake when implementing DC mode with SOEM is to use the simple example code.

Most DC slaves expect a stable and syncronised PDO transfer during safe-OP. Only when the LRW or LRD/LWR sequence has "proven" to the slave in question it is in sync with the SYNC0 signal the slave will allow transition to OP.

So your SOEM application has to:

  • configure the slave
  • map the slave
  • configure distributed clock
  • go to safe-op
  • start pdo data transfer (LRW or LRD/LWR) at the desired DC interval (for example 1ms)
  • check for stable DC clock in all slaves (difference timer)
  • check for stable master clock (digital PLL locked to reference slave)
  • only then request OP

An example how to do this is in red_test.c in the soem test map.

I'm still finalizing my code, as it's not 100% reliably getting the Sync Pulses to start, but once I'm done perhaps we (I?) should put together a "dc_test" application for SOEM...

matwey commented 8 years ago

@AversanJeff do you have some working example? I am trying to reach DC synchronisation, but no luck yet.

ghost commented 8 years ago

I haven't had a chance to make a stand-alone Distributed Clocks example yet, no.

For my specific application, I had to launch a separate thread which would attempt to take care of all D.C. configuration, ping the slaves to make sure D.C. has begun, and attempt to re-try configuration in case it didn't work.

Meanwhile the main thread would receive a periodic signal, and ensure the PDO's are sent out cyclically (every 1ms, aka1000Hz). Having the main thread focus on PDO's while a separate thread focused on D.C. is what finally fixed my issue.

Note: I used a TI AM3359 EtherCAT Slave, and I noticed it consistantly took 200ms to get into OP mode, which in my case meant 200 requests into OP mode (AFTER D.C. pulses have begun). For PDO sync, it would only take 3ms (3 requests) to get into OP mode.

LuciusMagnus commented 7 years ago

i'm also having problems with Distributed clocks. Can anyone let me know what lines should be added to the simple_test function (simple_test.c file, from SOEM library) in order to configure the distributed clocks? I want to control a servo motor (beckhoff AM8131-0F20-0000) which is connected to the servo drive terminal EL7211-0010. The drive terminal is connected to the bus coupler EK1100. I've read some stuff online and it's said that the reference clock and local clocks need to configured to synchronize the process data between master and slaves. I'm using a linux PC as master. Please, help me. I don't know much about it.

LuciusMagnus commented 7 years ago

On 12 Apr 2016, Mr. Ghost mentioned 8 steps for configuration of distributed clocks. Can anyone show me very simply how to code 1, 2 and 3, or at least indicate where I can find them in red_test.c example. Many thanks.

1) start pdo data transfer (LRW or LRD/LWR) at the desired DC interval (for example 1ms) 2) check for stable DC clock in all slaves (difference timer) 3) check for stable master clock (digital PLL locked to reference slave)