Timer and interrupts for multiple SPI using arduino nano 33 BLE Sense REV2 Board

Hello,
I am programming by arduino nano 33 BLE sense REV2 board, for two SPI to communicate with two AFEs. For driving two AFEs, I am trying to generate two 8MHz clock for each AFE, but I am getting one clock of 8MHz and the other is just 4kHz.
Moreover, I am trying to use the interrupts for SPIs but it just work for one AFE and also on 'LOW' not on 'FALLING'.
I looked for solution on arduino forums and think that it is due to timer and external interrupts may be, I am not sure. does anyone have a solution for this?

Thanks in advance.

Here is the sketch:

#include <SPI.h>
#include <stdio.h>
#include <stdlib.h>
#include <nrf.h>
#include <NRF52_MBED_TimerInterrupt.h> // TimerInterrupt_Generic library

NRF52_MBED_Timer ITimer; // Timer object


#define CLOCK_OUTPUT_PIN1 4 // P0.04 (8 MHz clock on pin A0)
#define CLOCK_OUTPUT_PIN2 30 // P0.30 (8 MHz clock on pin A2)


#define SPI_CLOCK 4000000    // 4 MHz SPI clock
#define SPI_MODE SPI_MODE0   // SPI mode
#define SPI_ORDER MSBFIRST   // Most Significant Bit First

#define true 1
#define false 0

// Pin definitions for AFE1 (SPI0)
#define MOSI_1 11
#define MISO_1 12
#define SCK_1 13
#define SS_1 10
#define PDNZ_1 9       // Custom PDNZ pin
#define ADC_RDY_1 8    // Custom ADC_RDY pin

// Pin definitions for AFE2 (SPI1)
#define SS_2 7
#define PDNZ_2 6       // Custom PDNZ pin
#define ADC_RDY_2 5    // ADC_RDY pin for AFE2

volatile bool readDataFlag1 = false; // Flag for AFE1
volatile bool readDataFlag2 = false; // Flag for AFE2

void AFE_Set_Register(byte csPin, byte thisRegister, unsigned long data);



void setup() {
  Serial.begin(9600);


  // Configure GPIO pins for clock outputs
  NRF_P0->PIN_CNF[CLOCK_OUTPUT_PIN1] = (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) |
                                       (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) |
                                       (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
                                       (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
                                       (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);

  NRF_P0->PIN_CNF[CLOCK_OUTPUT_PIN2] = (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) |
                                       (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) |
                                       (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
                                       (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
                                       (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);


  // Configure TIMER4 for 8 MHz clock on CLOCK_OUTPUT_PIN1
  NRF_TIMER4->MODE = TIMER_MODE_MODE_Timer; // Set as Timer
  NRF_TIMER4->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos; // 16-bit Timer
  NRF_TIMER4->PRESCALER = 0; // Prescaler 0 -> Full Speed (16 MHz base clock)
  NRF_TIMER4->CC[0] = 1; // Toggle every 1 cycle (16 MHz / 2 = 8 MHz)
  NRF_TIMER4->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos;


  // Configure GPIOTE for toggling CLOCK_OUTPUT_PIN1
  NRF_GPIOTE->CONFIG[0] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
                          (CLOCK_OUTPUT_PIN1 << GPIOTE_CONFIG_PSEL_Pos) |
                          (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);


  // Configure TIMER3 for 8 MHz clock on CLOCK_OUTPUT_PIN2
  NRF_TIMER3->MODE = TIMER_MODE_MODE_Timer; // Set as Timer
  NRF_TIMER3->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos; // 16-bit Timer
  NRF_TIMER3->PRESCALER = 0; // Prescaler 0 -> Full Speed (16 MHz base clock)
  NRF_TIMER3->CC[0] = 1; // Toggle every 1 cycle (16 MHz / 2 = 8 MHz)
  NRF_TIMER3->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos;


  // Configure GPIOTE for toggling CLOCK_OUTPUT_PIN2
  NRF_GPIOTE->CONFIG[1] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
                          (CLOCK_OUTPUT_PIN2 << GPIOTE_CONFIG_PSEL_Pos) |
                          (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);


  // Configure PPI to connect TIMER4 to CLOCK_OUTPUT_PIN1
  NRF_PPI->CH[0].EEP = (uint32_t)&NRF_TIMER4->EVENTS_COMPARE[0];
  NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[0];


  // Configure PPI to connect TIMER3 to CLOCK_OUTPUT_PIN2
  NRF_PPI->CH[1].EEP = (uint32_t)&NRF_TIMER3->EVENTS_COMPARE[0];
  NRF_PPI->CH[1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[1];


  // Start TIMER4 for CLOCK_OUTPUT_PIN1
  NRF_TIMER4->TASKS_CLEAR = 1; // Clear Timer 4
  NRF_TIMER4->TASKS_START = 1; // Start Timer 4


  // Start TIMER3 for CLOCK_OUTPUT_PIN2
  NRF_TIMER3->TASKS_CLEAR = 1; // Clear Timer 3
  NRF_TIMER3->TASKS_START = 1; // Start Timer 3

  // Enable PPI channels after timers start

  NRF_PPI->CHENSET = (1 << 0) | (1 << 1); // Enable both PPI channels



  // Initialize pins for AFE1
  pinMode(SS_1, OUTPUT);
  digitalWrite(SS_1, HIGH);
  pinMode(PDNZ_1, OUTPUT);
  digitalWrite(PDNZ_1, HIGH);
  pinMode(ADC_RDY_1, INPUT);

  // Initialize pins for AFE2
  pinMode(SS_2, OUTPUT);
  digitalWrite(SS_2, HIGH);
  pinMode(PDNZ_2, OUTPUT);
  digitalWrite(PDNZ_2, HIGH);
  pinMode(ADC_RDY_2, INPUT);

  // Initialize SPI
  SPI.begin();
  SPI.beginTransaction(SPISettings(SPI_CLOCK, SPI_ORDER, SPI_MODE));

  // Initialize AFE1 and AFE2
  initializeAFE_1();
  initializeAFE_2();

  // Start Timer Interrupt
  if (ITimer.attachInterruptInterval(2000, timerISR)) { // 2000 microseconds = 2ms
    Serial.println("Timer started successfully!");
  } 
  else {
    Serial.println("Failed to start timer!");
  }

  AFE_Set_READABLE(SS_1);
  AFE_Set_READABLE(SS_2);

}


void loop() {
  if (readDataFlag1) {
    readDataFlag1 = false; // Reset the flag
    uint32_t receivedVal1 = AFE_Read_Register(SS_1, 42); // Read GREEN_LED data from AFE1
    //Serial.print("AFE1 GREEN_LED Data: ");
    Serial.print(receivedVal1);
  }

  if (readDataFlag2) {
    readDataFlag2 = false; // Reset the flag
    uint32_t receivedVal2 = AFE_Read_Register(SS_2, 42); // Read GREEN_LED data from AFE2
    Serial.print("\t");
    Serial.print(receivedVal2);
    Serial.print("\n");
  }
}


void initializeAFE_1() {
  AFE_Set_Register(SS_1, 0, 8);     // Control 0 Reset 
  AFE_Set_Register(SS_1, 1, 6050);  // LED2STC
  AFE_Set_Register(SS_1, 2, 7998);  // LED2ENDC
  AFE_Set_Register(SS_1, 3, 6000);  // LED2LEDSTC
  AFE_Set_Register(SS_1, 4, 7999);  // LED2LEDENDC
  AFE_Set_Register(SS_1, 5, 50);    // ALED2STC
  AFE_Set_Register(SS_1, 6, 1998);  // ALED2ENDC
  AFE_Set_Register(SS_1, 7, 2050);  // LED1STC
  AFE_Set_Register(SS_1, 8, 3998);  // LED1ENDC
  AFE_Set_Register(SS_1, 9, 2000);  // LED1LEDSTC
  AFE_Set_Register(SS_1, 10, 3999); // LED1LEDENDC
  AFE_Set_Register(SS_1, 11, 4050); // ALED1STC
  AFE_Set_Register(SS_1, 12, 5998); // ALED1ENDC
  AFE_Set_Register(SS_1, 13, 4);    // LED2CONVST
  AFE_Set_Register(SS_1, 14, 1999); // LED2CONVEND
  AFE_Set_Register(SS_1, 15, 2004); // ALED2CONVST
  AFE_Set_Register(SS_1, 16, 3999); // ALED2CONVEND
  AFE_Set_Register(SS_1, 17, 4004); // LED1CONVST
  AFE_Set_Register(SS_1, 18, 5999); // LED1CONVEND
  AFE_Set_Register(SS_1, 19, 6004); // ALED1CONVST
  AFE_Set_Register(SS_1, 20, 7999); // ALED1CONVEND

  AFE_Set_Register(SS_1, 21, 0);    // ADCRSTSTXT0
  AFE_Set_Register(SS_1, 22, 3);    // ADCRSTENDCT0
  AFE_Set_Register(SS_1, 23, 2000); // ADCRSTSTCT1
  AFE_Set_Register(SS_1, 24, 2003); // ADCRSTENDCT1
  AFE_Set_Register(SS_1, 25, 4000); // ADCRSTSTCT2
  AFE_Set_Register(SS_1, 26, 4003); // ADCRSTENDCT2
  AFE_Set_Register(SS_1, 27, 6000); // ADCRSTSTCT3
  AFE_Set_Register(SS_1, 28, 6003); // ADCRSTENDCT3

  AFE_Set_Register(SS_1, 29, 7999);   // PRPCOUNT
  AFE_Set_Register(SS_1, 30, 0x107);  // CONTROL1
  AFE_Set_Register(SS_1, 32, 0x08002); // TIA_GAIN-----IR
  AFE_Set_Register(SS_1, 33, 0x24402); // TIA_AMB_GAIN------GREEN/RED
  AFE_Set_Register(SS_1, 34, 0x10014); // LEDCNTRL
  AFE_Set_Register(SS_1, 35, 0x40000); // CONTROL2
  AFE_Set_Register(SS_1, 49, 0x08000); // CONTROL3

  digitalWrite(SS_1, HIGH);
}

void initializeAFE_2() {
  AFE_Set_Register(SS_2, 0, 8);     // Control 0 Reset 
  AFE_Set_Register(SS_2, 1, 6050);  // LED2STC
  AFE_Set_Register(SS_2, 2, 7998);  // LED2ENDC
  AFE_Set_Register(SS_2, 3, 6000);  // LED2LEDSTC
  AFE_Set_Register(SS_2, 4, 7999);  // LED2LEDENDC
  AFE_Set_Register(SS_2, 5, 50);    // ALED2STC
  AFE_Set_Register(SS_2, 6, 1998);  // ALED2ENDC
  AFE_Set_Register(SS_2, 7, 2050);  // LED1STC
  AFE_Set_Register(SS_2, 8, 3998);  // LED1ENDC
  AFE_Set_Register(SS_2, 9, 2000);  // LED1LEDSTC
  AFE_Set_Register(SS_2, 10, 3999); // LED1LEDENDC
  AFE_Set_Register(SS_2, 11, 4050); // ALED1STC
  AFE_Set_Register(SS_2, 12, 5998); // ALED1ENDC
  AFE_Set_Register(SS_2, 13, 4);    // LED2CONVST
  AFE_Set_Register(SS_2, 14, 1999); // LED2CONVEND
  AFE_Set_Register(SS_2, 15, 2004); // ALED2CONVST
  AFE_Set_Register(SS_2, 16, 3999); // ALED2CONVEND
  AFE_Set_Register(SS_2, 17, 4004); // LED1CONVST
  AFE_Set_Register(SS_2, 18, 5999); // LED1CONVEND
  AFE_Set_Register(SS_2, 19, 6004); // ALED1CONVST
  AFE_Set_Register(SS_2, 20, 7999); // ALED1CONVEND

  AFE_Set_Register(SS_2, 21, 0);    // ADCRSTSTXT0
  AFE_Set_Register(SS_2, 22, 3);    // ADCRSTENDCT0
  AFE_Set_Register(SS_2, 23, 2000); // ADCRSTSTCT1
  AFE_Set_Register(SS_2, 24, 2003); // ADCRSTENDCT1
  AFE_Set_Register(SS_2, 25, 4000); // ADCRSTSTCT2
  AFE_Set_Register(SS_2, 26, 4003); // ADCRSTENDCT2
  AFE_Set_Register(SS_2, 27, 6000); // ADCRSTSTCT3
  AFE_Set_Register(SS_2, 28, 6003); // ADCRSTENDCT3

  AFE_Set_Register(SS_2, 29, 7999);   // PRPCOUNT
  AFE_Set_Register(SS_2, 30, 0x107);  // CONTROL1
  AFE_Set_Register(SS_2, 32, 0x08002); // TIA_GAIN-----IR
  AFE_Set_Register(SS_2, 33, 0x24402); // TIA_AMB_GAIN------GREEN/RED
  AFE_Set_Register(SS_2, 34, 0x10014); // LEDCNTRL
  AFE_Set_Register(SS_2, 35, 0x40000); // CONTROL2
  AFE_Set_Register(SS_2, 49, 0x08000); // CONTROL3

  digitalWrite(SS_2, HIGH);
}

void timerISR() {
  // Check ADC_RDY pins and set flags accordingly
  if (digitalRead(ADC_RDY_1) == FALLING) {
    readDataFlag1 = true;
  }
  if (digitalRead(ADC_RDY_2) == FALLING) {
    readDataFlag2 = true;
  }
}

void AFE_Set_Register(byte csPin, byte thisRegister, unsigned long data) {
  digitalWrite(csPin, LOW);
  SPI.transfer(thisRegister);
  SPI.transfer((data >> 16) & 0xFF);
  SPI.transfer((data >> 8) & 0xFF);
  SPI.transfer(data & 0xFF);
  digitalWrite(csPin, HIGH);
}

unsigned long AFE_Read_Register(byte csPin, byte addrToRead) {
  unsigned long result = 0;
  digitalWrite(csPin, LOW);
  SPI.transfer(addrToRead);
  result |= (SPI.transfer(0x00) << 16);
  result |= (SPI.transfer(0x00) << 8);
  result |= SPI.transfer(0x00);
  digitalWrite(csPin, HIGH);
  return result;
}

void AFE_Set_READABLE(byte csPin) {
  byte toWrite[3] = {0x00, 0x00, 0x01}; // Data to write to CONTROL0 register
  writeAFERegister(csPin, 0x00, toWrite);
}

void writeAFERegister(byte cs, byte thisRegister, byte AFEValue[]) {
digitalWrite(SS, LOW);
  byte addrToSend = thisRegister;
  SPI.transfer(addrToSend);
  SPI.transfer(AFEValue[0]);
  SPI.transfer(AFEValue[1]);
  SPI.transfer(AFEValue[2]);
  //delayMicroseconds(1);
  digitalWrite(SS, HIGH);
}

I have been searching for days for the syntax.

Where did you find the syntax?

Sorry for the bother.

Mike