Interrupts Using M7 vs M4 Core

Dear all,

I am hoping to utilize the Portenta M4 core to send instructions to a slow stepper motor, and use the M7 core to run other faster tasks in parallel, taking advantage of the M7 higher clock speed.

The precise details are not important, however generally speaking, the stepper motor will control a linear ball screw with a stage attached. I want this stage to move until a certain requirement is met, e.g. until a magnet attached to the stage meets an active-low Hall probe, and then an interrupt is triggered on the falling edge as this Hall probe input goes low, which causes the stepper motor to stop.

#define Stage_MotorSTEP_CW 8 //  Pin assigned to clockwise step pin on stepper motor driver

#define Stage_MotorSTEP_CCW 7 // Pin assigned to counterclockwise step pin on stepper motor driver

#define Stage_Motor_Disable 6 // Pin assigned to 'disable' pin on stepper motor driver

#define DigitalHallProbe1 9 // Pin assigned to Hall probe signal input

void setup() {

  pinMode(Stage_MotorSTEP_CW, OUTPUT);  // Output for sending pulses to tell stepper driver to move one step CW

  pinMode(Stage_MotorSTEP_CCW, OUTPUT); // Output for sending pulses to tell stepper driver to move one step CCW

  pinMode(Stage_Motor_Disable, OUTPUT); // Output sends pulse to driver to disable stepper motor

  pinMode(DigitalHallProbe1, INPUT_PULLUP); // Digital Hall probe input (this model of Hall probe is active low)


/*Assign interrupt variable to interrupt routine. Interrupt routine disables stepper motor when magnet reaches Hall Probe face and DigitalHallProbe1 switches from 3.3 V to 0V. Triggered on falling edge. */


  attachInterrupt(digitalPinToInterrupt(DigitalHallProbe1), Hall_Switch_End_Limit1, FALLING);
}

void Hall_Switch_End_Limit1() { digitalWrite(Stage_Motor_Disable, HIGH); }

/* Stepper motor takes one step every 400 microseconds in the clockwise direction unless interrupt condition met*/

void loop() {

  digitalWrite(Stage_MotorSTEP_CW, HIGH);
  delayMicroseconds(400);
  digitalWrite(Stage_MotorSTEP_CW, LOW);
  delayMicroseconds(400);
}

This loop and interrupt code works absolutely fine when run on the M7 core. If I then switch this code to run on the M4 and then use the M7 to do something different, like blink an LED as shown in the code below, the loop part of the code on both cores works fine but the interrupt on M4 does not.

void setup() {
    // initialize digital pin LED_BUILTIN as an output.
    pinMode(LEDG, OUTPUT);
    bootM4();
}

// the loop function runs over and over again forever
void loop() {
   digitalWrite(LEDB, LOW); // turn the LED on (LOW is the voltage level)
   delay(400); // wait for a second
   digitalWrite(LEDB, HIGH); // turn the LED off by making the voltage HIGH
   delay(400); // wait for a second
}

Is it because the M7 is the 'master core' that M4 cannot handle interrupts?

If this simply won't ever work, is it a reasonable alternative to use interrupts in the code that runs on M7 which stops M4 code? (an 'anti-bootM4() function if you will)?

All the best,
Ryan

1 Like

So I've asked the folks at Arduino technical support about this and have radio silence for now after some initial correspondence. Hopefully this means that it is being looked into.

All the best,
Ryan

Dear user,

Thank you for sharing the problem with the Arduino community and sorry for the delay on replying to this post.

As explained privately in the technical support platform, an issue has been found when triggering interrupts from M4.

The hardware team is actively working on a solution and it will be shared here so all members of Arduino community can see it as soon as its available.

Sorry for the inconvenience.

Regards!

Hi @thejerseychemist,
I dug a bit in the sources and found that a recent change in STM32Cube software prevented the M4 to trigger any interrupt.
The issue should be solved by this PR Portenta: M4: recompile core by facchinm · Pull Request #68 · arduino/ArduinoCore-mbed · GitHub

It would be awesome if you could test it before core release.

Thanks
M

Dear nachoherrera and facchinm,

Many thanks for looking into this.

I will test this as soon as possible and let you know what happens.

All the best,
Ryan

facchinm:
Hi @thejerseychemist,
I dug a bit in the sources and found that a recent change in STM32Cube software prevented the M4 to trigger any interrupt.
The issue should be solved by this PR Portenta: M4: recompile core by facchinm · Pull Request #68 · arduino/ArduinoCore-mbed · GitHub

It would be awesome if you could test it before core release.

Thanks
M

I can confirm that this does now work. Thanks. If I encounter any more issues now when advancing with my code, I'll let you know.
Have a great weekend.
All the best,
Ryan