Issues with ISR on F103 STM32

I have a small project which is expected to count interrupts coming in on PB12 and PB13 of a Blue Pill board.
The incoming signals are formatted externally in hardware in pulses of about 9ms period toggling between 0 and 5V. These signals are confirmed on an oscilloscope. The data is then sent to an ST7920 where the count is updated every 2 seconds.

The code is rather simple but obviously I am missing something because the display stays stuck at 0000. Here is the code:

#include <Arduino.h>
#include <U8g2lib.h>
#include <SPI.h>
#include <Wire.h>

const int ledPin = PC13;
const int cyl1 = PB12;
const int cyl2 = PB13;
//const int cyl3 = PB14;
//const int cyl4 = PB15;
volatile unsigned int cyl1Counter = 0;
volatile unsigned int cyl2Counter = 0;
unsigned int cyl1CounterCopy;
unsigned int cyl2CounterCopy;
char buffer[30];


U8G2_ST7920_128X64_F_HW_SPI u8g2(U8G2_R0, /* CS/RS=*/ PA4, /* reset/RST=*/ PA0);

void setup() {
  // put your setup code here, to run once:
  u8g2.begin();
  u8g2.clearBuffer();
  u8g2.drawXBM(0,0, u8g_logo_width, u8g_logo_height, u8g_logo_bits );
  u8g2.sendBuffer();
  u8g2.setFont(u8g2_font_ncenB10_tr);

  pinMode(ledPin, OUTPUT);
  pinMode(cyl1, INPUT);
  attachInterrupt(digitalPinToInterrupt(cyl1),cyl1_ISR, FALLING);
  pinMode(cyl2, INPUT);
  attachInterrupt(digitalPinToInterrupt(cyl2),cyl2_ISR, FALLING);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(ledPin, LOW);

  // block interrupts to ensure no copy errors whilst parsing the variables
  noInterrupts();
  cyl1CounterCopy = cyl1Counter;
  cyl2CounterCopy = cyl2Counter;
  interrupts();

  u8g2.clearBuffer();

  u8g2.drawStr(0,13, "Cyl 1 -");
  sprintf(buffer,"%04u",cyl1CounterCopy);
  u8g2.setCursor(50,13);
  u8g2.printf(buffer);

  u8g2.drawStr(0,29, "Cyl 2 -");
  sprintf(buffer,"%04u",cyl2CounterCopy);
  u8g2.setCursor(50,29);
  u8g2.printf(buffer);

  u8g2.drawStr(0,45, "Cyl 3 -");
  u8g2.drawStr(50,45, "buffer");

  u8g2.drawStr(0,61, "Cyl 4 -");

  u8g2.sendBuffer();
  delay(1000);
  digitalWrite(ledPin, HIGH);
  delay(1000);

}

//interrupt service routines
void cyl1_ISR() {
  cyl1Counter++;
}

void cyl2_ISR() {
  cyl2Counter++;
}

any suggestions please?

The U8G2 code is just adding clutter and complexity. The first thing I'd do is pull it all out and make a much simpler test just printing the results to the Serial Monitor instead.

Unrelated to your problem, but this should not be necessary. On an STM32 those copies should be atomic operations, so interrupts won't affect them.

[edit]
Doing some further research, I may be wrong on that. C++ load/store is not guaranteed atomic (but it usually is). So keep your nointerrupt/interrupt structure if you want to be extra safe.
For anyone else interested in the subject, I found this: c - Which variable types/sizes are atomic on STM32 microcontrollers? - Stack Overflow

Apologies for the somewhat OT post :wink:

Thanks for your replies.

Since my message, I discovered that the issue was hardware after all. The software was ok. Basically, due to the nature of my circuitry B12, B13 only toggle and generate interrupts if the Blue Pill is earthed.
I am still intrigue about teh point you made about "atomic operations". I will going through the link you suggested but if there are other takes on this issue I would love to hear about.

Regards

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.