UART Interrupt Service Routine with the XIAO nRF52840 Sense board

Hey all,

For some context, I’m working within FreeRTOS and allowing the user to interface with the device over serial. For example, the user may send a (firmware specific) recognized command like ‘print_data’ and the device would respond by sending some data over serial to the user. However, my issue stems from the serial communication tasks not running at the time data is actual transmitted over serial to the device.

My hope is that I can run an ISR to detect when data is sent over serial to then raise a flag and possibly intercept the serial data. I can then have another task set up to check if the flag is true and to have the data shared. This can then process the user’s requests in a more reliable fashion.

That being said, I’m looking for some examples/assistance in creating an interrupt service routine for when data is read over serial in the nRF52840 Sense board. I’ve read elsewhere that there is a function name specifically for UART Peripheral ISR with the nRF52480 processor, but haven’t had any luck in finding it.

Below is some pseudocode of what I’m trying to accomplish:

// Global vars
bool flag = false;
String serialBuffer;


void setup() {
  xTaskCreate(TaskPrintData);
  xTaskCreate(TaskOther);
  xTaskCreate(TaskAnother);
  xTaskCreate(TaskAndOneMore);
  vTaskStartScheduler();
}

void loop() {
// Nothing here in FreeRTOS!
}

// Example implementation
void UART_ISR_Handler(void)  {
  flag = true;
  serialBuffer = Serial.readString(); 
}

// Example data printing task
void TaskPrintData(void *PvParameters)  {
  (void)PvParameters;
  for (;;) {
    if (flag == true) {
      if (serialBuffer == "print_data") {
        Serial.println("flag is true");
      }
    }
    flag = false;
    serialBuffer = "";
  }
}

void TaskOther(void *PvParameters)  {
// code 
}

void TaskAnother(void *PvParameters)  {
// code 
}

void TaskAndOneMore(void *PvParameters)  {
// code 
}

Hi there,
Sure, sounds pretty straight,
Keep ISR’s short and sweet, in the ISR , just set a flag for the main code to do the work.
Check out the Tap Sleep Demo on here, Note the ISR’s and the part that actually prints the interrupt count out to Serial port. I’m sure it will help.
HTH
GL :slight_smile: PJ

Hey PJ, thank you for the response. I’m assuming you’re referring to this post you made a few months ago.

I’m not sure if this is exactly what I’m looking for. I’m more so checking if there’s been anything sent over serial and then triggering the software interrupt off of that. Do you have any ideas on where I could start (in terms of registers, for example)?

Thank you

Hi there,
Ok , well what about this to receive an interrupt when there is incoming serial data on the nRF52840 Xiao BLE MCU using Arduino IDE, you can use the attachInterrupt() function to trigger an interrupt when the RX pin receives data. Here’s a basic example to get you started:

#define RX_PIN 8  // Define your RX pin here P1.12

volatile bool serialDataReceived = false;  // Flag to indicate serial data received

void setup() {
  Serial.begin(9600);  // Initialize serial communication
  pinMode(RX_PIN, INPUT);  // Set RX pin as input

  // Attach an interrupt to the RX pin to trigger on falling edge (when data is received)
  attachInterrupt(digitalPinToInterrupt(RX_PIN), serialEvent, FALLING);
}

void loop() {
  // Your main code here
  if (serialDataReceived) {
    // Data has been received, process it
    // Example: Read and print the received data
    while (Serial.available() > 0) {
      char receivedChar = Serial.read();
      Serial.print(receivedChar);
    }
    // Reset the flag
    serialDataReceived = false;
  }
}

// Interrupt service routine for serial data received
void serialEvent() {
  serialDataReceived = true;
}

When data is received on the RX pin, the serialEvent() function is called, setting the serialDataReceived flag to true . In the loop() function, you can then check this flag to process the received data.
HTH
GL :slight_smile: PJ