Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DIG_process in interrupt #4

Open
qiayuanl opened this issue Dec 6, 2022 · 12 comments
Open

DIG_process in interrupt #4

qiayuanl opened this issue Dec 6, 2022 · 12 comments

Comments

@qiayuanl
Copy link

qiayuanl commented Dec 6, 2022

Your code and documents are awesome! Thank you for your sharing.

Following your SOES_CIA402_AX58100 code, I wrote my code using CubeMX(HAL) and successfully ran it in NUCLEO-F401RE and AX58100-REF-1 without CIA402 applications.

After success, I try to call the DIG_process in the interrupt callback. The code is shown below:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
 if (GPIO_Pin == ESC_INT_Pin) {
    ESC_updateALevent();
    if (ESCvar.ALevent & ESCREG_ALEVENT_SM2) {
      if (ESCvar.dcsync == 0)  // If DC sync is not active, run the application, all except for the Watchdog
        DIG_process(DIG_PROCESS_OUTPUTS_FLAG | DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
      else  // If DC sync is active, call output handler only
        DIG_process(DIG_PROCESS_OUTPUTS_FLAG);
    }
  } else if (GPIO_Pin == ESC_SYNC_Pin) {
      ESC_updateALevent();
      DIG_process(DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
   }
}

However, after getting into the Operational state, the ESI stops sending PDI to interrupt MCU. As a result, MCU no longer processes the output.

Have you tried what I mentioned above? Why do we need to process the interrupt in the while()?

@kubabuda
Copy link
Owner

kubabuda commented Jan 7, 2023

Hi, have a look at https://rt-labs.com/refman/ethercat-sdk_refman.pdf page 38:

In addition to SM2 add SMCHANGE, EEP(if EEPROM emulated), ALCONTROL, SM0 and
SM1 to the mask to generate PDI interrupt

Have you done this?

@qiayuanl
Copy link
Author

qiayuanl commented Jan 7, 2023

What you mentioned is about Interrupt mode. I use the Mixed Polling/Interrupt (SM or DC Synchronous) mode.

@kubabuda
Copy link
Owner

kubabuda commented Jan 9, 2023

Ah, I had not tried this yet. I just ported some example code to STM32 and have not looked into it more.
Sounds like good idea to try it out at some point

@kubabuda
Copy link
Owner

Hey, have you figured it out that you are closing issue?
Now as I read your original post, it looks like you tried to call stack handler from interrupt, while stack was in mixed mode. This sounds wrong. SOES stack originally was really intended to be used in polled mode, if you want it's handler in interrupt then configure it and call in interrupt mode

@qiayuanl
Copy link
Author

I think the original problem is the interrupt priority. All ESC relative interrupts should be in the same priority, if not, the ESC_write and ESC_read will be interrupted. However, I don't remember too much since there are tons of new code after this issue.

@qiayuanl
Copy link
Author

I meet this problem again, a clearer description should be:
"The PDI interrupt will randomly disappear when the bus running high frequency (1khz~4khz)."

Here is some behavior:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
  if (GPIO_Pin == ESC_INT_Pin) {
    ESC_updateALevent();
    if (ESCvar.dcsync == 0)  // If DC sync is not active, run the application, all except for the Watchdog
      DIG_process(DIG_PROCESS_OUTPUTS_FLAG | DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
    else  // If DC sync is active, call output handler only
      DIG_process(DIG_PROCESS_OUTPUTS_FLAG);
  } else if (GPIO_Pin == ESC_SYNC_Pin) {
    ESC_updateALevent();
    DIG_process(DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
  }
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
  if (htim == &TIM_ESC) {
    ecat_slv_poll();
    DIG_process(DIG_PROCESS_WD_FLAG);
  }
}
  • For slave, there are two interrupts from ESC and a timer interrupt for polling and watchdog (the priorities are all the same)
  • For master, I use red_test.c in SOEM, this small program can auto-detect the loss of slave and auto-recover, also easy to change the cycletime.
  • In high frequency, the PDI interrupt sometimes disappears, then without feeding the dog in DIG_process(DIG_PROCESS_OUTPUTS_FLAG), the watchdog was triggered and the slave got into safeoperation.
  • The red_test.c might be able to reset the slave back to operation, but sometimes the PDI disappears immediately and the watchdog triggers again.
  • Unplug and plug the ethernet cable during the test (to test the loss of slave) got the same result, the slave can recover in low PDO frequency (100Hz), but when at 4kHz, lots of recover fail because the missing of PDI.
  • Using pdi_irq_flag and sync0_irq_flag in the callback function and process everything in main() like your example got the same result.
  • Using ecat_slv() for everything without interrupts work perfectly
  • I try change the DIG_process after ecat_slv_poll() to DIG_process(DIG_PROCESS_WD_FLAG | DIG_PROCESS_OUTPUTS_FLAG); and it works perfectly (the watchdog protection is also working)

I am very confused, not sure if you can reproduce this problem.

@qiayuanl qiayuanl reopened this Apr 15, 2024
@kubabuda
Copy link
Owner

Hello, good you were able to localize problem.
Looks like I was testing my code with TwinCAT at 500 Hz, will check with 1 KHz or more, and SOES red_test

I have some STM32F401 board somewhere, and spare AX58100 breakout. If you can publish your firmware I should be able to reproduce your setup (and problem)

First potential problem I see: looks like you are running mixed mode code but using it in interrupt operation. ecat_slv_poll is meant to be polled, running in some kind of main function. The way it is done in SOES mixed mode examples:
https://github.com/OpenEtherCATsociety/SOES/blob/8f3841e3cefd83c48d866ffaeb2d92c146bf3cd7/applications/tiesc_am335x/main.c#L77
Look at slv_poll implementation, it is doing a lot of stuff starting with reading local time from ESC (over SPI in our case). You do not want this in interrupt handler, that must finish quickly.
Per docs, for running in interrupt you want ecat_slv_worker (and still
Do you have a copy of SOES docs - ethercat-sdk_refman.pdf ?

Another possibility is wrong interrupt priority. My example had equal priority and subpriority on SYNC and PDI IRQ EXTI, I think this should be OK - test with master in higher frequency should tell.

@qiayuanl
Copy link
Author

Putting ecat_slv_poll to main() does change the result, the reason I put it in timer interrupt is to control the watchdog timeout.

I don't have ethercat-sdk_refman.pdf

@kubabuda
Copy link
Owner

kubabuda commented Apr 18, 2024

Have a look at tiesc_am335x
example, watchdog kick is done in main too. The same setup in examples in docs PDF.

Manual PDF used to be available, now you need to log in on rt-labs page

@qiayuanl
Copy link
Author

That is what I mean, whether the

    ecat_slv_poll();
    DIG_process(DIG_PROCESS_WD_FLAG);

inside the main loop or not does not affect the result. The problem I describe still remains.

@kubabuda
Copy link
Owner

I tried SOEM red_test (on old thinkpad laptop with Linux if that even matters) with SOES_CIA402_AX58100 code.
I tested cycletime from 1000 down to 100 us and could not reproduce the problem. Slave just kept working, and after RJ45 cable disconnect+reconnect it recovered to OP every time.

I will now try with ecat_slv_poll();\r\n DIG_process(DIG_PROCESS_WD_FLAG); in IRQ handler but if you want me to really reproduce your setup, I am going to need your F401 code

What HW are you using for ethercat master, by the way?

@qiayuanl
Copy link
Author

qiayuanl commented May 2, 2024

I am using a ThinkPad laptop for ethercat master. I can share some code privately. However, my newest code is running on H755 (AX58400), can you port it to f401 or let me find some old code (one year ago)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants