lexus2k / lcdgfx

Driver for LCD displays running on Arduino/Avr/ESP32/Linux (including Rasperry) platforms
MIT License
356 stars 51 forks source link

Arduino UNO: Reboot loop when enabling external interrupts via PCMSK1 #91

Open cof-celldeg opened 1 year ago

cof-celldeg commented 1 year ago

Describe the bug DisplaySH1106_128x64_I2C::begin() crashes when external interrupts are enabled.

To Reproduce Steps to reproduce the behavior:

  1. Create arduino sketch with following code
#include <HardwareSerial.h>
#include "lcdgfx.h"
#include "lcdgfx_gui.h"

constexpr float fVFac = 5.0f * ((220.0f + 33.0f) / 33.0f) * (1.0f / 1023.0f);

DisplaySH1106_128x64_I2C d = DisplaySH1106_128x64_I2C(-1);
volatile bool bPressed = false;
volatile uint16_t nDelayCnt = 0;

void setup() {

  Serial.begin(115200);
  Serial.println("*");

  PCICR |= (1 << PCIE1);
  // If these lines are uncommented, the program will die at the marked spot below and be stuck in a reboot loop
  //PCMSK1 = (1 << PCINT13);
  //EICRA |= (0 << ISC11) | (1 << ISC10); 

  Serial.println("begin...");
  delay(250);

  // This is the call that crashes 
  d.begin(); // Address 0x3C default

  Serial.println("set font...");
  delay(250);
  d.setFixedFont(ssd1306xled_font6x8);
  Serial.println("fill...");
  delay(250);
  d.fill( 0x00 );
  Serial.println("setup done!");
  delay(250);
}

void loop()
{
  float fAR = analogRead(A2);
  float fV = fVFac * fAR;
  uint8_t w = (100.0f / 18.0f) * fV;
  uint8_t v = floor(fV);
  uint8_t mv = 10 * (fV - v);
  char szText[5];
  sprintf(szText, "%2u.%1.1u V", v, mv);
  Serial.println("VCC: ");Serial.println(fV);
  Serial.println("set color...");
  delay(250);
  const char* p = szText;
  d.setColor(0);
  Serial.println("fill...");
  delay(250);
  d.fillRect(0, 0, 128, 64);
  Serial.println("set color...");
  delay(250);
  d.setColor(1);
  Serial.println("draw text...");
  delay(250);
  d.printFixed(0, 0, szText, STYLE_NORMAL);
  delay(1);
  if (nDelayCnt > 0) nDelayCnt--;
}

ISR(PCINT19_vect)
{
  Serial.print("X");
  if (nDelayCnt == 0)
  {
    bPressed = true;
    nDelayCnt = 200;
  }
}
  1. Uncommenting the two lines will cause a crash but otherwise the program works fine

Expected behavior As it appears to me, enabling the external interrupts causes the reboot loop. I need those to interface with buttons, and would like not to need polling. So hopefully there is a workaround that allows both to run at the same time.

Screenshots If applicable, add screenshots to help explain your problem.

Please complete the following information:

Additional context Switching lcdgfx init and the register change did not help

lexus2k commented 1 year ago

Hi The library uses standard Wire library for Arduino environment. So it has nothing specific related to the crash.