adafruit / Adafruit_Arcada

Arduino library for gaming
Other
82 stars 22 forks source link

displayBegin in PlatformIO just freezes the PyGamer #44

Open UnsignedArduino opened 2 years ago

UnsignedArduino commented 2 years ago

Trying to use Adafruit Arcada in PlatformIO, arcada.displayBegin() causes the PyGamer to freeze.

Repro:

  1. Create PlatformIO project.
  2. Install Adafruit Arcada.
  3. Copy test sketch below to main.cpp.
  4. Go to .pio\libdeps\adafruit_pygamer_m4\Adafruit Arcada Library\Boards\Adafruit_Arcada_PyGamer.h and comment out #define ARCADA_USE_JSON as causes multiple errors in compiling.
  5. Add/change upload_port in platformio.ini if needed.
  6. Upload.

When I upload the sketch via PlatformIO I only get:

Arcada test
Successfully initiated Arcada

Which suggests arcada.displayBegin() freezes the board.

When I upload the sketch via Arduino IDE I get:

Arcada test
Successfully initiated Arcada
Began display
Set backlight to 128
Fill screen with blue
Success

The screen is blue on my PyGamer. Interestingly, displayBegin() takes quite a bit of time (~1 sec?) - don't remember that happening before.

What I've been doing is coding the program in an "Arduino sketch" (Directory with .ino file in it with the same name) so that I can get Git VCS and auto-complete and then use Arduino IDE to upload using the "Use external editor" option in Arduino preferences, although this isn't elegant.

It also appears that someone on the Adafruit Forums had this problem as well, with no responses to the post.

Test sketch:

#include <Arduino.h>
// Needed because Adafruit_Arcade needs Adafruit_ImageReader which needs Adafruit_EPD
#include <Adafruit_EPD.h>
#include <Adafruit_Arcada.h>

Adafruit_Arcada arcada;

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ;
  }
  Serial.println("Arcada test");

  if (!arcada.arcadaBegin()) {
    Serial.println("Failed to initiate Arcada");
    while (true) {
      ;
    }
  } else {
    Serial.println("Successfully initiated Arcada");
  }

  arcada.displayBegin(); 
  Serial.println("Began display");

  arcada.setBacklight(128);
  Serial.println("Set backlight to 128");

  arcada.display->fillScreen(ARCADA_BLUE);
  Serial.println("Fill screen with blue");

  Serial.println("Success");
}

void loop() {
  ;
}
UnsignedArduino commented 2 years ago

Going into .pio\libdeps\adafruit_pygamer_m4\Adafruit Arcada Library\Boards\Adafruit_Arcada_PyGamer.h and updating displayBegin(void) to:

  void displayBegin(void) {
    Adafruit_ST7735 *tft = new Adafruit_ST7735(&ARCADA_TFT_SPI, ARCADA_TFT_CS,
                                               ARCADA_TFT_DC, ARCADA_TFT_RST);
    Serial.println("Created new ST7735 object");
    tft->initR(INITR_BLACKTAB);
    Serial.println("Initiate ST7735");
    tft->setRotation(ARCADA_TFT_ROTATION);
    Serial.println("Set rotation");
    tft->fillScreen(ARCADA_TFT_DEFAULTFILL);
    Serial.println("Set default fill");
    display = tft;
  }

Prints this in Serial monitor:

Arcada test
Successfully initiated Arcada
Created new ST7735 object    
Initiate ST7735
Set rotation

Suggests that tft->fillScreen is hanging.

UnsignedArduino commented 2 years ago

Going into .pio\libdeps\adafruit_pygamer_m4\Adafruit GFX Library\Adafruit_GFX.cpp and changing fillScreen to:

void Adafruit_GFX::fillScreen(uint16_t color) {
  Serial.print("Fill screen from (0, 0) to (");
  Serial.print(_width);
  Serial.print(", ");
  Serial.print(_height);
  Serial.print(") with color 0x");
  Serial.println(color, HEX);
  fillRect(0, 0, _width, _height, color);
}

Gets me:

Arcada test
Successfully initiated Arcada
Created new ST7735 object
Initiate ST7735
Set rotation
Fill screen from (0, 0) to (160, 128) with color 0xFFFF

Continuing the rabbit hole, I change fillRect in .pio\libdeps\adafruit_pygamer_m4\Adafruit GFX Library\Adafruit_GFX.cpp to:

void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
                            uint16_t color) {
  Serial.println("Start fillRect");
  Serial.println("Start write");
  startWrite();
  for (int16_t i = x; i < x + w; i++) {
    Serial.print("Fast vline from (");
    Serial.print(i);
    Serial.print(", ");
    Serial.print(y);
    Serial.print(" with height ");
    Serial.print(h); 
    Serial.print(" with color 0x");
    Serial.println(color, HEX);
    writeFastVLine(i, y, h, color);
  }
  Serial.println("End write");
  endWrite();
  Serial.println("Finished fillRect");
}

I still only get:

Arcada test
Successfully initiated Arcada
Created new ST7735 object
Initiate ST7735
Set rotation
Fill screen from (0, 0) to (160, 128) with color 0xFFFF

Seems like this function isn't called at all.

ladyada commented 2 years ago

hmm what happens if you try in the arduino IDE? we dont test with platformio and don't have it set up so we couldn't test it very well

UnsignedArduino commented 2 years ago

Doing the modifications I did to the Arcada and GFX libraries in the PlatformIO project to the Arduino libraries gets me this:

Arcada test
Successfully initiated Arcada
Created new ST7735 object
Initiate ST7735
Set rotation
Fill screen from (0, 0) to (160, 128) with color 0xFFFF
Set default fill
Began display
Set backlight to 128
Fill screen from (0, 0) to (160, 128) with color 0x1F
Fill screen with blue
Success

Maybe there is an optimized version so the Adafruit_GFX version of fillRect isn't used...

UnsignedArduino commented 2 years ago

Actually, I'll just post the serial output instead after doing more serial printing - it will take up less space:

Arcada test
Successfully initiated Arcada
Adafruit_Arcada::displayBegin() start
Create new ST7735 object
Initiate ST7735
Set rotation
Set default fill
Adafruit_GFX::fillScreen() start
Adafruit_SPITFT::fillRect() start
Start write
Fill rect pre clipped
Adafruit_SPITFT::writeFillRectPreclipped() start
Set address window
Write color
Adafruit_SPITFT::writeColor() start
SAMD51 using SPI DMA
Starting DMA job
DMA busy

Looks like it's stuck waiting for DMA here...

UnsignedArduino commented 2 years ago

Disabling SPI DMA works for PlatformIO.

To disable, go to .pio\libdeps\adafruit_pygamer_m4\Adafruit GFX Library\Adafruit_SPITFT.h and comment out line 79.

UnsignedArduino commented 2 years ago

This is what you need to get Adafruit Arcada to work in PlatformIO:

#include <Arduino.h>
// Needed because Adafruit_Arcade needs Adafruit_ImageReader which needs Adafruit_EPD
#include <Adafruit_EPD.h>
// Go to .pio\libdeps\adafruit_pygamer_m4\Adafruit Arcada Library\Boards\Adafruit_Arcada_PyGamer.h
// (or your respective board) and comment out #define ARCADA_USE_JSON because it breaks compilation
// Go to .pio\libdeps\adafruit_pygamer_m4\Adafruit GFX Library\Adafruit_SPITFT.h
// and comment out #define USE_SPI_DMA because it does not work when compiled with PlatformIO
#include <Adafruit_Arcada.h>

Then everything else is the same. (Sorry for cluttering up this thread - I can delete and edit posts if you want me to merge some posts together)

dustinlacewell commented 9 months ago

Hello. I am trying to get a Pygamer working with Adafruit Arcada on Platformio and am running into the same exact issues.

However, commenting out #define USE_SPI_DMA does not fix the issue for me...

Can someone from Adafruit please take a look? I know Platformio is not your interest, but it is gaining popularity and is really the way to do Arduinio dev these days.