Hi,
Thanks for the example which is very helpful - it worked perfectly with the suggested changes on my Nano33 BLE.
I have been attempting to extend the functionality to include an analogue read and an SPI transaction within the ISR. My eventual aim is to create a datalogger with as fast and consistent a sample rate as I can achieve, hence the plan to do it under interrupt control.
As a first-step on this project I have programmed my device to read analogue values from the ADC and write them to a serial flash memory device. Unfortunately it seems that attempting either an 'analogueRead()' or an 'SPI.transfer()' from within the ISR causes problems. The program below is a simple modification of the original example but with a couple more variables and some additional lines inside the ISR which demonstrate the problem(s).
/*
* Investigation of interrupt problems with AI and SPI transactions within ISR
* based on (https://forum.arduino.cc/index.php?topic=664425.0)
*/
// define global variables
int sensorPin = A0; // select the input pin for the sensor
const int slaveSelectPin = 10; // set pin 10 as the slave select
byte dummy_reg; // variable for SPI transaction
volatile int flag = 0;
volatile unsigned int rawInput;
// include the SPI library
#include <SPI.h>
extern "C"
{
void TIMER1_IRQHandler_v()
{
if (NRF_TIMER1->EVENTS_COMPARE[0] == 1)
{
// Read value from the input
// rawInput = analogRead(sensorPin);
// Attempt SPI transaction (write disable, Microchip SST25VF080B serial flash)
digitalWrite(slaveSelectPin, LOW); // take the SS pin low to select the chip
// dummy_reg = SPI.transfer(0x04);
digitalWrite(slaveSelectPin, HIGH); // take the SS pin high to de-select the chip
flag++;
NRF_TIMER1->EVENTS_COMPARE[0] = 0;
}
}
}
void setup() {
// setup digital output pins
pinMode(slaveSelectPin, OUTPUT); // set & initialise SPI slaveSelectPin as an output:
digitalWrite(slaveSelectPin, LOW);
// Set the ADC resolution to 12-bit (0..4095)
analogReadResolution(12); // Can be 8, 10, 12 or 14
// initialize SPI:
Serial.println("Initialising SPI ...");
SPI.begin();
SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
Serial.begin(115200);
Serial.println("Configuring timer");
NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
NRF_TIMER1->PRESCALER = 4 << TIMER_PRESCALER_PRESCALER_Pos;
NRF_TIMER1->CC[0] = 10000;
NRF_TIMER1->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;
NRF_TIMER1->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos;
NVIC_EnableIRQ(TIMER1_IRQn);
NRF_TIMER1->TASKS_START = 1;
}
void loop() {
Serial.print(flag);
Serial.print(" ");
Serial.println(rawInput);
}
Line 23 is an analogue read, and line 27 is an SPI output command to the flash device If lines 23 & 27 are both commented-out then the program compiles and runs fine - the value of 'flag' is output to the serial monitor (together with a zero value for raw input) and the digital output (pin 10) can be observed on a scope.
If line 23 only is un-commented then I would expect the raw ADC value to be output to the serial monitor along with the value of 'flag'. What actually happens is the program compiles and uploads correctly but no activity observed on pin 10. Port selection in 'Tools' menu is greyed-out and serial monitor cannot be opened (error message 'Board at COM8 is not available' is displayed). To restore correct operation I need to double-press the reset button and upload the sketch with the offending line commented-out again.
Line 27 is an output to the serial flash which doesn't return anything. So if I un-comment this line I don't expect the program to do anything observably different, but it does serve to demonstrate the problem. If line 27 only is un-commented then the behaviour is exactly the same as for un-commenting line 23.
I suppose strictly speaking this is two problems, one with analogue read and another with SPI, but the symptom is the same and I am assuming (rightly or wrongly) that they might have the same cause or at least be related.
In my setup I have a 10k potentiometer driving the analogue input, and a serial Flash device connected (Microchip SST25VF080B 8Mbit SPI Serial Flash). I don't think this matters for the example program but I have included a sketch of the circuit for completeness.
I've had some success with Uno and Nano projects but the Nano33 BLE is completely new to me. An explanation as to why the system is behaving in this way, or any other assistance you could give me would be very much appreciated.