Collect2.exe: error: ld returned 1 , Linker Error

Hi All
Ive had “collect2.exe: error: ld returned 1” linker errors beore but im stuck again.

Below is my lastest problem. Im guessing it is in my MyISR.h file but i cant find it.

Note: this is part of a bigger project, i have stripped it back to Main.cpp, MyISR.cpp, MyISP.h to try and isolate the issue.

Im using “<Portenta_H7_ISR_Timer.h>” from “GitHub - khoih-prog/Portenta_H7_TimerInterrupt: This library enables you to use Interrupt from Hardware Timers on an STM32H7-based Portenta_H7 board. It now supports 16 ISR-based timers, while consuming only 1 Hardware Timer. Timers' interval is very long (ulong millisecs). The most important feature is they're ISR-based timers. Therefore, their executions are not blocked by bad-behaving functions or tasks. This important feature is absolutely necessary for mission-critical tasks. These hardware timers, using interrupt, still work even if other functions are blocking. Moreover, they are much more precise (certainly depending on clock frequency accuracy) than other software timers using millis() or micros(). That's necessary if you need to measure some data requiring better accuracy” and it has a refference to

// To be included only in main(), .ino with setup() to avoid Multiple Definitions Linker Error
#include <Portenta_H7_ISR_Timer.h>

I have played with this but still no luck.

My log File

 *  Executing task in folder PH7_12_ISR_test: C:\Users\bucko\.platformio\penv\Scripts\platformio.exe run 

Processing portenta_h7_m7 (platform: ststm32; board: portenta_h7_m7; framework: arduino)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/ststm32/portenta_h7_m7.html
PLATFORM: ST STM32 (15.6.0) > Arduino Portenta H7 (M7 core)
HARDWARE: STM32H747XIH6 480MHz, 511.35KB RAM, 768KB Flash
DEBUG: Current (stlink) External (cmsis-dap, jlink, stlink)
PACKAGES:
 - framework-arduino-mbed @ 4.0.2
 - toolchain-gccarmnoneeabi @ 1.70201.0 (7.2.1)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 46 compatible libraries
Scanning dependencies...
Dependency Graph
|-- Arduino_PortentaBreakout @ 1.0.1
|-- Portenta_H7_TimerInterrupt @ 1.4.0
Building in release mode
Compiling .pio\build\portenta_h7_m7\src\MyIRS.cpp.o
In file included from src\MyIRS.cpp:33:0:
.pio\libdeps\portenta_h7_m7\Portenta_H7_TimerInterrupt\src/Portenta_H7_TimerInterrupt.h:31:4: warning: #warning Use MBED ARDUINO_PORTENTA_H7 and LittleFS [-Wcpp]
   #warning Use MBED ARDUINO_PORTENTA_H7 and LittleFS
    ^~~~~~~
.pio\libdeps\portenta_h7_m7\Portenta_H7_TimerInterrupt\src/Portenta_H7_TimerInterrupt.h:38:6: warning: #warning Using Portenta H7 M7 core [-Wcpp]
     #warning Using Portenta H7 M7 core
      ^~~~~~~
In file included from src\MyIRS.cpp:35:0:
include/MyISR.h:26:0: warning: "_TIMERINTERRUPT_LOGLEVEL_" redefined
     #define _TIMERINTERRUPT_LOGLEVEL_     4

In file included from .pio\libdeps\portenta_h7_m7\Portenta_H7_TimerInterrupt\src/Portenta_H7_TimerInterrupt.h:74:0,
                 from src\MyIRS.cpp:33:
.pio\libdeps\portenta_h7_m7\Portenta_H7_TimerInterrupt\src/TimerInterrupt_Generic_Debug.h:44:0: note: this is the location of the previous definition
   #define _TIMERINTERRUPT_LOGLEVEL_       1

In file included from src\MyIRS.cpp:35:0:
include/MyISR.h:62:36: warning: 'ITimer' initialized and declared 'extern'
     extern Portenta_H7_Timer ITimer(TIM12);
                                    ^
src\MyIRS.cpp:38:29: error: redefinition of 'Portenta_H7_Timer ITimer'
     Portenta_H7_Timer ITimer(TIM12);
                             ^
In file included from src\MyIRS.cpp:35:0:
include/MyISR.h:62:30: note: 'Portenta_H7_Timer ITimer' previously declared here
     extern Portenta_H7_Timer ITimer(TIM12);
                              ^~~~~~
*** [.pio\build\portenta_h7_m7\src\MyIRS.cpp.o] Error 1
=================================================================================================== [FAILED] Took 5.13 seconds ===================================================================================================

 *  The terminal process "C:\Users\bucko\.platformio\penv\Scripts\platformio.exe 'run'" terminated with exit code: 1. 
 *  Terminal will be reused by tasks, press any key to close it. 

 *  Executing task in folder PH7_12_ISR_test: C:\Users\bucko\.platformio\penv\Scripts\platformio.exe run 

Processing portenta_h7_m7 (platform: ststm32; board: portenta_h7_m7; framework: arduino)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/ststm32/portenta_h7_m7.html
PLATFORM: ST STM32 (15.6.0) > Arduino Portenta H7 (M7 core)
HARDWARE: STM32H747XIH6 480MHz, 511.35KB RAM, 768KB Flash
DEBUG: Current (stlink) External (cmsis-dap, jlink, stlink)
PACKAGES: 
 - framework-arduino-mbed @ 4.0.2
 - toolchain-gccarmnoneeabi @ 1.70201.0 (7.2.1)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 46 compatible libraries
Scanning dependencies...
Dependency Graph
|-- Arduino_PortentaBreakout @ 1.0.1
|-- Portenta_H7_TimerInterrupt @ 1.4.0
Building in release mode
Compiling .pio\build\portenta_h7_m7\src\MyIRS.cpp.o
Compiling .pio\build\portenta_h7_m7\src\main.cpp.o
In file included from include/MyISR.h:29:0,
                 from src\main.cpp:13:
.pio\libdeps\portenta_h7_m7\Portenta_H7_TimerInterrupt\src/Portenta_H7_TimerInterrupt.h:31:4: warning: #warning Use MBED ARDUINO_PORTENTA_H7 and LittleFS [-Wcpp]
   #warning Use MBED ARDUINO_PORTENTA_H7 and LittleFS
    ^~~~~~~
.pio\libdeps\portenta_h7_m7\Portenta_H7_TimerInterrupt\src/Portenta_H7_TimerInterrupt.h:38:6: warning: #warning Using Portenta H7 M7 core [-Wcpp]
     #warning Using Portenta H7 M7 core
      ^~~~~~~
In file included from src\MyIRS.cpp:33:0:
.pio\libdeps\portenta_h7_m7\Portenta_H7_TimerInterrupt\src/Portenta_H7_TimerInterrupt.h:31:4: warning: #warning Use MBED ARDUINO_PORTENTA_H7 and LittleFS [-Wcpp]
   #warning Use MBED ARDUINO_PORTENTA_H7 and LittleFS
    ^~~~~~~
.pio\libdeps\portenta_h7_m7\Portenta_H7_TimerInterrupt\src/Portenta_H7_TimerInterrupt.h:38:6: warning: #warning Using Portenta H7 M7 core [-Wcpp]
     #warning Using Portenta H7 M7 core
      ^~~~~~~
In file included from src\MyIRS.cpp:35:0:
include/MyISR.h:26:0: warning: "_TIMERINTERRUPT_LOGLEVEL_" redefined
     #define _TIMERINTERRUPT_LOGLEVEL_     4

In file included from .pio\libdeps\portenta_h7_m7\Portenta_H7_TimerInterrupt\src/Portenta_H7_TimerInterrupt.h:74:0,
                 from src\MyIRS.cpp:33:
.pio\libdeps\portenta_h7_m7\Portenta_H7_TimerInterrupt\src/TimerInterrupt_Generic_Debug.h:44:0: note: this is the location of the previous definition
   #define _TIMERINTERRUPT_LOGLEVEL_       1

Linking .pio\build\portenta_h7_m7\firmware.elf
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::Portenta_H7_ISRTimer()':
main.cpp:(.text._ZN20Portenta_H7_ISRTimerC2Ev+0x0): multiple definition of `Portenta_H7_ISRTimer::Portenta_H7_ISRTimer()'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimerC2Ev+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::Portenta_H7_ISRTimer()':
main.cpp:(.text._ZN20Portenta_H7_ISRTimerC2Ev+0x0): multiple definition of `Portenta_H7_ISRTimer::Portenta_H7_ISRTimer()'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimerC2Ev+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::init()':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer4initEv+0x0): multiple definition of `Portenta_H7_ISRTimer::init()'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer4initEv+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::findFirstFreeSlot()':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer17findFirstFreeSlotEv+0x0): multiple definition of `Portenta_H7_ISRTimer::findFirstFreeSlot()'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer17findFirstFreeSlotEv+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::setupTimer(unsigned long, void*, void*, bool, unsigned int)':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer10setupTimerEmPvS0_bj+0x0): multiple definition of `Portenta_H7_ISRTimer::setupTimer(unsigned long, void*, void*, bool, unsigned int)'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer10setupTimerEmPvS0_bj+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::setTimer(unsigned long, void (*)(), unsigned int)':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer8setTimerEmPFvvEj+0x0): multiple definition of `Portenta_H7_ISRTimer::setTimer(unsigned long, void (*)(), unsigned int)'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer8setTimerEmPFvvEj+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::setTimer(unsigned long, void (*)(void*), void*, unsigned int)':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer8setTimerEmPFvPvES0_j+0x0): multiple definition of `Portenta_H7_ISRTimer::setTimer(unsigned long, void (*)(void*), void*, unsigned int)'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer8setTimerEmPFvPvES0_j+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::setInterval(unsigned long, void (*)())':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer11setIntervalEmPFvvE+0x0): multiple definition of `Portenta_H7_ISRTimer::setInterval(unsigned long, void (*)())'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer11setIntervalEmPFvvE+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::setInterval(unsigned long, void (*)(void*), void*)':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer11setIntervalEmPFvPvES0_+0x0): multiple definition of `Portenta_H7_ISRTimer::setInterval(unsigned long, void (*)(void*), void*)'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer11setIntervalEmPFvPvES0_+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::setTimeout(unsigned long, void (*)())':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer10setTimeoutEmPFvvE+0x0): multiple definition of `Portenta_H7_ISRTimer::setTimeout(unsigned long, void (*)())'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer10setTimeoutEmPFvvE+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::setTimeout(unsigned long, void (*)(void*), void*)':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer10setTimeoutEmPFvPvES0_+0x0): multiple definition of `Portenta_H7_ISRTimer::setTimeout(unsigned long, void (*)(void*), void*)'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer10setTimeoutEmPFvPvES0_+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::changeInterval(unsigned int, unsigned long)':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer14changeIntervalEjm+0x0): multiple definition of `Portenta_H7_ISRTimer::changeInterval(unsigned int, unsigned long)'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer14changeIntervalEjm+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::deleteTimer(unsigned int)':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer11deleteTimerEj+0x0): multiple definition of `Portenta_H7_ISRTimer::deleteTimer(unsigned int)'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer11deleteTimerEj+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::run()':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer3runEv+0x0): multiple definition of `Portenta_H7_ISRTimer::run()'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer3runEv+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::restartTimer(unsigned int)':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer12restartTimerEj+0x0): multiple definition of `Portenta_H7_ISRTimer::restartTimer(unsigned int)'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer12restartTimerEj+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::isEnabled(unsigned int)':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer9isEnabledEj+0x0): multiple definition of `Portenta_H7_ISRTimer::isEnabled(unsigned int)'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer9isEnabledEj+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::enable(unsigned int)':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer6enableEj+0x0): multiple definition of `Portenta_H7_ISRTimer::enable(unsigned int)'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer6enableEj+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::disable(unsigned int)':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer7disableEj+0x0): multiple definition of `Portenta_H7_ISRTimer::disable(unsigned int)'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer7disableEj+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::enableAll()':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer9enableAllEv+0x0): multiple definition of `Portenta_H7_ISRTimer::enableAll()'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer9enableAllEv+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::disableAll()':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer10disableAllEv+0x0): multiple definition of `Portenta_H7_ISRTimer::disableAll()'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer10disableAllEv+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::toggle(unsigned int)':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer6toggleEj+0x0): multiple definition of `Portenta_H7_ISRTimer::toggle(unsigned int)'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer6toggleEj+0x0): first defined here
.pio\build\portenta_h7_m7\src\main.cpp.o: In function `Portenta_H7_ISRTimer::getNumTimers()':
main.cpp:(.text._ZN20Portenta_H7_ISRTimer12getNumTimersEv+0x0): multiple definition of `Portenta_H7_ISRTimer::getNumTimers()'
.pio\build\portenta_h7_m7\src\MyIRS.cpp.o:MyIRS.cpp:(.text._ZN20Portenta_H7_ISRTimer12getNumTimersEv+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\portenta_h7_m7\firmware.elf] Error 1
=================================================================================================== [FAILED] Took 5.61 seconds ===================================================================================================

 *  The terminal process "C:\Users\bucko\.platformio\penv\Scripts\platformio.exe 'run'" terminated with exit code: 1. 
 *  Terminal will be reused by tasks, press any key to close it.

My ini

[env:portenta_h7_m7]

platform = ststm32

board = portenta_h7_m7

framework = arduino

debug_tool = stlink

upload_protocol = stlink

monitor_port = COM4

lib_deps =

https://github.com/maxgerhardt/Arduino_PortentaBreakout/archive/refs/heads/main.zip

khoih-prog/Portenta_H7_TimerInterrupt@^1.4.0

build_flags =

-I include

-D TARGET_PORTENTA_H7_M7

My Code
Main.cpp

#include <Arduino.h>
#include <Arduino_PortentaBreakout.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//#include <Portenta_H7_TimerInterrupt.h>
//#include <Portenta_H7_ISR_Timer.h>

//My h Files

#include "MyISR.h"
   void doingSomething1();
    void doingSomething2();
    void doingSomething3();

void setup() {

  isrSetUp();
 
}

void loop() {
}
  
void doingSomething1()
    {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    }

void doingSomething2()
    {
    digitalWrite(LED_BLUE, !digitalRead(LED_BLUE));
    }

void doingSomething3()
    {
    digitalWrite(LED_RED, !digitalRead(LED_RED));
    }

MyISR.cpp

/****************************************************************************************************************************
  TimerInterruptLEDDemo.ino
  For Portenta_H7 boards
  Written by Khoi Hoang

  Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_TimerInterrupt
  Licensed under MIT license

  Now even you use all these new 16 ISR-based timers,with their maximum interval practically unlimited (limited only by
  unsigned long miliseconds), you just consume only one Portenta_H7 STM32 timer and avoid conflicting with other cores' tasks.
  The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
  Therefore, their executions are not blocked by bad-behaving functions / tasks.
  This important feature is absolutely necessary for mission-critical tasks.
*****************************************************************************************************************************/

/*
   Notes:
   Special design is necessary to share data between interrupt code and the rest of your program.
   Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
   variable can not spontaneously change. Because your function may change variables while your program is using them,
   the compiler needs this hint. But volatile alone is often not enough.
   When accessing shared variables, usually interrupts must be disabled. Even with volatile,
   if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
   If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
   or the entire sequence of your code which accesses the data.
*/

// In Portenta_H7, avoid doing something fancy in ISR, for example Serial.print
// Or you can get this run-time error / crash

#include <Arduino.h>
#include <Arduino_PortentaBreakout.h>
#include <Portenta_H7_TimerInterrupt.h>
#include <Portenta_H7_ISR_Timer.h>
#include "MyISR.h"

// Init timer TIM12
    Portenta_H7_Timer ITimer(TIM12);

    // Init Portenta_H7_ISR_Timer
    // Each Portenta_H7_ISR_Timer can service 16 different ISR-based timers
    Portenta_H7_ISR_Timer ISR_Timer;

void TimerHandler()
    {
    ISR_Timer.run();
    }

// In STM32, avoid doing something fancy in ISR, for example complex Serial.print with String() argument
// The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
// Or you can get this run-time error / crash
void doingSomething1()
    {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    }

void doingSomething2()
    {
    digitalWrite(LED_BLUE, !digitalRead(LED_BLUE));
    }

void doingSomething3()
    {
    digitalWrite(LED_RED, !digitalRead(LED_RED));
    }

void isrSetUp()
{
    // configure pin in output mode
    //   pinMode(LED_BUILTIN,  OUTPUT);
    //   pinMode(LED_BLUE,     OUTPUT);
    //   pinMode(LED_RED,      OUTPUT);

    delay(100);

    Serial.print(F("\nStarting TimerInterruptLEDDemo on ")); Serial.println(BOARD_NAME);
    Serial.println(PORTENTA_H7_TIMER_INTERRUPT_VERSION);

    // Interval in microsecs
    if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_MS * 1000, TimerHandler))
    {
        Serial.print(F("Starting ITimer OK, millis() = ")); Serial.println(millis());
    }
    else
        Serial.println(F("Can't set ITimer. Select another freq. or timer"));

    // Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
    // You can use up to 16 timer for each ISR_Timer
    ISR_Timer.setInterval(TIMER_INTERVAL_0_5S,  doingSomething1);
    ISR_Timer.setInterval(TIMER_INTERVAL_1S,    doingSomething2);
    ISR_Timer.setInterval(TIMER_INTERVAL_1_5S,  doingSomething3);
}

MyISR.h

/*  BUCKOS HEADER FILE   MyISR.h
    Header file for      MyISR.cpp

    Version:   001
    Date:       19 Apr 2023
    Board:      Arduino Portenta H7 (PH7)
    Extra:      PH7 Breakoutboard
    uP:         ST STM-32
*/

// This header is for my BT setting 

//#pragma once
#ifndef MyISR
    #define MyISR

    #if !( ( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) && defined(ARDUINO_ARCH_MBED) )
    #error This code is designed to run on Portenta_H7 platform! Please check your Tools->Board setting.
    #endif
    #include <Arduino.h>
    #include <Arduino_PortentaBreakout.h>

    // These define's must be placed at the beginning before #include "Portenta_H7_TimerInterrupt.h"
    // _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
    // Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
    #define _TIMERINTERRUPT_LOGLEVEL_     4

    // Can be included as many times as necessary, without `Multiple Definitions` Linker Error
    #include <Portenta_H7_TimerInterrupt.h>

    // To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
    #include <Portenta_H7_ISR_Timer.h>

    #define TIMER_INTERVAL_MS         100
    #define HW_TIMER_INTERVAL_MS      50

    // Depending on the board, you can select STM32H7 Hardware Timer from TIM1-TIM22
    // If you select a Timer not correctly, you'll get a message from compiler
    // 'TIMxx' was not declared in this scope; did you mean 'TIMyy'? 

    // Portenta_H7 OK       : TIM1, TIM4, TIM7, TIM8, TIM12, TIM13, TIM14, TIM15, TIM16, TIM17
    // Portenta_H7 Not OK   : TIM2, TIM3, TIM5, TIM6, TIM18, TIM19, TIM20, TIM21, TIM22
    // Portenta_H7 No timer : TIM9, TIM10, TIM11. Only for STM32F2, STM32F4 and STM32L1 
    // Portenta_H7 No timer : TIM18, TIM19, TIM20, TIM21, TIM22

    // // Init timer TIM12
    extern Portenta_H7_Timer ITimer;

    // Init Portenta_H7_ISR_Timer
    // Each Portenta_H7_ISR_Timer can service 16 different ISR-based timers
    extern Portenta_H7_ISR_Timer ISR_Timer;

    #define TIMER_INTERVAL_0_5S           500L
    #define TIMER_INTERVAL_1S             1000L
    #define TIMER_INTERVAL_1_5S           1500L
    #define TIMER_INTERVAL_5S             5000L
    #define TIMER_INTERVAL_1min           60000L

    void TimerHandler();
    void doingSomething1();
    void doingSomething2();
    void doingSomething3();
    void isrSetUp();

#endif

So in main.cpp you include that header file which has

And also in MyISR.cpp you have the include

So it’s game over right there. Two .cpp files end up including that Timer header file.

Hi Thanks
So i dont need to include in Main.cpp.

That means that any routines running running in Main.cpp will be interupted via setups in myISR.h and .cpp

Is the correct flow then?

Main void loop() > ISR (in MyISR) > DoSomethingFunction > ISR (in MyISR) > Main void loop()

Hi
If this is the case how do i call the isrSetup() routine from main.cpp?

Do i just run a void setup() in MyISR? i like to explicitly call setups from Main.cpp

Cheers

You’ve programmed yourself into a corner there. I would suggest:

MyISR.h only has

#ifndef MyISR
#define MyISR

void isrSetUp();

#endif

as its content. That’s it. No other file needs to be knowing about that it uses a Portenta_H7_Timer or Portenta_H7_ISR_Timer internally, that all should be made static to the MyISR.cpp file. And thus, the

#include <Portenta_H7_TimerInterrupt.h>
#include <Portenta_H7_ISR_Timer.h>

only need to be inside MyISR.cpp.

If you want the function to be able to take a function callback as “the function to be executed inside the timer ISR”, then change isrSetUp() to accept a function pointer.

typedef void(*isr_callback_func_t)(void);

void isrSetUp(isr_callback_func_t callback);

The value of that can be saved inside a static variable in MyISR.cpp and then called into when the actual ISR function. The main.cpp would then do isrSetUp(&my_cool_callback_function); with

void my_cool_callback_function(void) {
  // some (ISR safe) code
}

Thanks for all of that and yes i have coded myself into a corner.
I think i follow. I will implement and let you know how i go.