RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Please tell us which board you are using.
For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
mikeysklar
 
Posts: 14092
Joined: Mon Aug 01, 2016 8:10 pm

Re: RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Post by mikeysklar »

When uploading code from the Arduino IDE are you putting the Adafruit Feather RP2040 into bootloader mode? That is necessary to upload code. The COM port may or may not be there. Oddly enough the COM port being present is not important for this board. I believe the code is copied at the filesystem level which is why you need to be in bootloader mode.
The BOOTSEL button is used to enter the bootloader. To enter the bootloader, press and hold BOOTSEL and then power up the board (either by plugging it into USB or pressing RESET). The bootloader is used to install/update CircuitPython.
https://learn.adafruit.com/adafruit-fea ... in-3084847
If there is no serial Port available in the dropdown, or an invalid one appears - don't worry about it! The RP2040 does not actually use a serial port to upload, so its OK if it does not appear if in manual bootload mode. You will see a serial port appear after uploading your first sketch
https://learn.adafruit.com/adafruit-fea ... rd-3107193

The code has been changing on this project. It worked long enough for the guide to be made, but as the libraries evolve problems arise. You can spot the pioneers by the arrows in their backs.

Good job on taking care of the dot files.

User avatar
Laila_Mestari
 
Posts: 50
Joined: Wed Oct 12, 2022 8:00 pm

Re: RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Post by Laila_Mestari »

Hi,

Yes, I believe I did set my RP2040 on Bootloader mode but my code is still stock at "Failed to mount filesystem!"( which is even further back in the code that I was couple weeks ago). In order to find where I might be mistaking, here is a precise description of the steps I follow each time:

1- Set my wire circuit on breadboard with RP2040 and and screen
2- Plug the RP2040 on computer with USB-c data sync cable
3- Bootloader mode: holding down the BOOT/BOOTSEL button, and while continuing to hold it, press and release the reset button. Until I see a RPI-RP2 drive appear on my my computer
4- Drag and drop Nuke file (from Adafruit website) on the drive : drive icon disapeared for couple second and reappears
5- Drag and drop “adafruit-circuitpython-adafruit_feather_rp2040-en_US-7.3.3 (6).uf2” on the drive : drive icon disapeared for couple second and reappears as CIRCUITPY
6-Delete all invisible files from CIRCUITPY
7- Drag and drop "Arduino-Logo-320.gif" on CIRCUITPY. At this point, this is how it looks like:
Screen Shot 2022-10-12 at 6.34.34 PM.png
Screen Shot 2022-10-12 at 6.34.34 PM.png (96 KiB) Viewed 165 times
8-Open Arduino IDE 2.0.0 or Arduino 2. 8.15 (I always try both now)
9-update libraries
10-Go online and copy code from https://learn.adafruit.com/mini-gif-pla ... if-players and compile code
11- Upload code on Feather RP2040

On both Arduino and Arduino, I can upload the code on Fether but my serial monitor still shows this message:

Adafruit SPIFlash Animated GIF Example
Flash chip JEDEC ID: 0xC84017
Failed to mount filesystem!
Was CircuitPython loaded on the board first to create the filesystem?



***

On a side note, this is not as important but, I want to point out something going on with my switch in my circuit.

-When the witch is OFF, the white light behind my TFT screen is on and the Drive appears on my computer. Code can be uploaded on the drive.

-When the switch in ON, the white light behind my TFT screen is OFF and the the drive is being ejected/disconnecteed from my computer or DOESN'T appear. Code canNOT be uploaded on the drive.

I just want to know if this is normal


Again, thank you for your help

User avatar
mikeysklar
 
Posts: 14092
Joined: Mon Aug 01, 2016 8:10 pm

Re: RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Post by mikeysklar »

The Arduino release should be 1.8.19. You had mentioned version 8.15 which if you meant 1.8.15 would be 18 months old.

There could be something up with the filesystem causing the mount to fail. This would be a good time to use the "nuke" image.

https://learn.adafruit.com/mini-gif-pla ... f2-3091244

I see from the screenshot you are still using the renamed Arduino-Logo-320-B.gif. Please keep the default names to reduce changes from the stock code and example files.

It would probably be best to remove the battery and switch from Circuit at this time. They can be added back when you get a mounted filesystem and images displaying on the TFT.

User avatar
Laila_Mestari
 
Posts: 50
Joined: Wed Oct 12, 2022 8:00 pm

Re: RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Post by Laila_Mestari »

Thank you,

So I went through the exact same steps describe in the prior message but, this time, I used:
-Arduino 1.8.19
-the "Arduino-Logo-320.gif"
-and no battery and switch in the circuit

The serial monitor still shows me this message:

Adafruit SPIFlash Animated GIF Example
Flash chip JEDEC ID: 0xC84017
Failed to mount filesystem!
Was CircuitPython loaded on the board first to create the filesystem?

here is the screenshot of my drive before uploading the code
Screen Shot 2022-10-27 at 3.41.46 PM.png
Screen Shot 2022-10-27 at 3.41.46 PM.png (90.9 KiB) Viewed 159 times

User avatar
Laila_Mestari
 
Posts: 50
Joined: Wed Oct 12, 2022 8:00 pm

Re: RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Post by Laila_Mestari »

Just a precision: This message is the one I see on my serial monitor after uploading the code on the CIRCUITPY drive (exactly like last time)
+
Question: When you say that "there could be something up with the filesystem causing the mount to fail. This would be a good time to use the "nuke" image."

Do you mean that it would be a good time to drag and drop the "flash_nuke.uf2" file downloaded on https://learn.adafruit.com/mini-gif-pla ... cuitpython on my RP2040? Because that's what I do each time before drag and dropping Circuitpython on my RP2040. Is there another moment to do this? Like after uploading the code?

thank you

User avatar
mikeysklar
 
Posts: 14092
Joined: Mon Aug 01, 2016 8:10 pm

Re: RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Post by mikeysklar »

I have an RP2040. I'll go through the same process as you have been doing and see if I can get the passed the filesystem mount.

User avatar
Laila_Mestari
 
Posts: 50
Joined: Wed Oct 12, 2022 8:00 pm

Re: RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Post by Laila_Mestari »

That’s great, Thank you so much

User avatar
mikeysklar
 
Posts: 14092
Joined: Mon Aug 01, 2016 8:10 pm

Re: RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Post by mikeysklar »

I think you found something. I was able to reproduce with the same error on my Ubuntu laptop.
Screenshot from 2022-10-28 14-26-51.png
Screenshot from 2022-10-28 14-26-51.png (32.5 KiB) Viewed 153 times
A few "roll backs" to try:

1) Roll back the SPIFlash library as the error is most likely here since we cannot mount the flash.
2) PhilHower Core
3) Roll back to CircuitPython 6.x which is the last version the guide used instead of a 7.x.

Since the code builds and outputs to the console I'm guessing is a higher level library rather than a low level board issue.

User avatar
mikeysklar
 
Posts: 14092
Joined: Mon Aug 01, 2016 8:10 pm

Re: RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Post by mikeysklar »

I tried the latest versions off github and going back at least one from the default versions the Arduino installs:

1) Adafruit SdFat (Fork) - 2.2.1 / 1.5.1 / 1.4.0
2) Adafruit SPIFlash - 4.1.0 / 4.0.0 / 3.11.0
3) CircuitPython - 7.3.3 / 8.0.0-beta3
4) PhilHower Core Board File - 2.6.2 / 2.6.1 / 2.6.0

All fail to mount in the same way.
Adafruit SPIFlash Animated GIF Example
Flash chip JEDEC ID: 0xEF4017
Failed to mount filesystem!
Was CircuitPython loaded on the board first to create the filesystem?

Code: Select all

 // First call begin to mount the filesystem.  Check that it returns true
  // to make sure the filesystem was mounted.
  if (!fatfs.begin(&flash)) {
    Serial.println("Failed to mount filesystem!");
    
I will inform engineering.

User avatar
Laila_Mestari
 
Posts: 50
Joined: Wed Oct 12, 2022 8:00 pm

Re: RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Post by Laila_Mestari »

Thank you fo going through the process on your side.

Does that mean that there is a problem somewhere in the project itself?
Also, did you mean that you you will talk about this with with Engineering?

User avatar
mikeysklar
 
Posts: 14092
Joined: Mon Aug 01, 2016 8:10 pm

Re: RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Post by mikeysklar »

The problem is one of these, but I'm not sure which.

* the instructions (process / order of operations)
* the current library releases not being compatible (three were updated in the last two weeks)
* the user code not being compatible with library updates

I requested that engineering look into this since I was able to reproduce the error and sent them a summary email. Normally the guide engineer gets involved, but resolution can take a while to determine and publish.

User avatar
Laila_Mestari
 
Posts: 50
Joined: Wed Oct 12, 2022 8:00 pm

Re: RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Post by Laila_Mestari »

Hi,

Do you know approximately how long this could take?

Also, could you please notify me as soon as you find something?


Thank you

User avatar
hathach
 
Posts: 1270
Joined: Tue Apr 23, 2013 1:02 am

Re: RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Post by hathach »

hihi, sorry for the issue, we have made some changes lately to the SPIFlash library. In short, previously rp2040 only support layout formatted by Circuitpython, later version it better support dynamic flash layout from IDE menu (Flash Size). Can you change the code like this PR https://github.com/adafruit/Adafruit_Le ... 2316/files

Basically from

Adafruit_FlashTransport_RP2040 flashTransport;

to (with _CPY)

Code: Select all

  Adafruit_FlashTransport_RP2040_CPY flashTransport;

User avatar
Laila_Mestari
 
Posts: 50
Joined: Wed Oct 12, 2022 8:00 pm

Re: RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Post by Laila_Mestari »

Hi,

So, if I understand well, I should got through the exact same steps than before but, when copying the code, I should use this code instead? https://github.com/adafruit/Adafruit_Le ... 2316/files

When I verify this on Arduino IDE, I recieve this eror message:

/private/var/folders/yk/d_49jtd56hzg5226czjtrvcm0000gn/T/.arduinoIDE-unsaved2022931-86323-1o0nrs1.w1ndj/sketch_oct31a/sketch_oct31a.ino:44:38: error: conflicting declaration 'Adafruit_FlashTransport_RP2040_CPY flashTransport'
44 | Adafruit_FlashTransport_RP2040_CPY flashTransport;
| ^~~~~~~~~~~~~~
/private/var/folders/yk/d_49jtd56hzg5226czjtrvcm0000gn/T/.arduinoIDE-unsaved2022931-86323-1o0nrs1.w1ndj/sketch_oct31a/sketch_oct31a.ino:27:34: note: previous declaration as 'Adafruit_FlashTransport_RP2040 flashTransport'
27 | Adafruit_FlashTransport_RP2040 flashTransport;
| ^~~~~~~~~~~~~~
Multiple libraries were found for "SdFat.h"
Used: /Users/admin/Documents/Arduino/libraries/SdFat_-_Adafruit_Fork
Not used: /Users/admin/Library/Arduino15/packages/rp2040/hardware/rp2040/2.6.1/libraries/ESP8266SdFat
exit status 1

Compilation error: conflicting declaration 'Adafruit_FlashTransport_RP2040_CPY flashTransport'

User avatar
mikeysklar
 
Posts: 14092
Joined: Mon Aug 01, 2016 8:10 pm

Re: RP2040 and TFT, Mini GIF player "Error opening file" (black screen)

Post by mikeysklar »

I used the current version of the Mini_GIF_Players.ino (updated 6 hours ago).

It compiled and ran for me.

https://raw.githubusercontent.com/adafr ... layers.ino

Code: Select all

Adafruit SPIFlash Animated GIF Example

Flash chip JEDEC ID: 0xEF4017
Mounted filesystem!
         0 2020-01-01 00:00 .fseventsd/
         0 2020-01-01 00:00 .metadata_never_index
         0 2020-01-01 00:00 .Trashes
        22 2020-01-01 00:00 code.py
         0 2020-01-01 00:00 lib/
       144 2020-01-01 00:00 boot_out.txt
    142692 2022-10-28 21:05 Arduino-Logo-320.gif
         0 2020-01-01 00:00 .fseventsd/
         0 2020-01-01 00:00 .metadata_never_index
         0 2020-01-01 00:00 .Trashes
        22 2020-01-01 00:00 code.py
         0 2020-01-01 00:00 lib/
       144 2020-01-01 00:00 boot_out.txt
    142692 2022-10-28 21:05 Arduino-Logo-320.gif
Successfully opened GIF Arduino-Logo-320.gif; Canvas size = 320 x 170
frame count: 1
duration: 40 ms
max delay: 40 ms
min delay: 10000 ms

Code: Select all

// SPDX-FileCopyrightText: 2022 Limor Fried for Adafruit Industries
//
// SPDX-License-Identifier: MIT

#include <AnimatedGIF.h>
#include <SdFat.h>
#include <Adafruit_SPIFlash.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789

#define TFT_CS         5
#define TFT_DC         6
#define TFT_RST        9

#define DISPLAY_WIDTH 320
#define DISPLAY_HEIGHT 174

#define GIFDIRNAME "/"
#define NUM_LOOPS 5

#if defined(ARDUINO_ARCH_ESP32)
  // ESP32 use same flash device that store code.
  // Therefore there is no need to specify the SPI and SS
  Adafruit_FlashTransport_ESP32 flashTransport;

#elif defined(ARDUINO_ARCH_RP2040)
  // RP2040 use same flash device that store code for file system. Therefore we
  // only need to specify start address and size (no need SPI or SS)
  // By default (start=0, size=0), values that match file system setting in
  // 'Tools->Flash Size' menu selection will be used.
  // Adafruit_FlashTransport_RP2040 flashTransport;

  // To be compatible with CircuitPython partition scheme (start_address = 1 MB,
  // size = total flash - 1 MB) use const value (CPY_START_ADDR, CPY_SIZE) or
  // subclass Adafruit_FlashTransport_RP2040_CPY. Un-comment either of the
  // following line:
  //  Adafruit_FlashTransport_RP2040
  //    flashTransport(Adafruit_FlashTransport_RP2040::CPY_START_ADDR,
  //                   Adafruit_FlashTransport_RP2040::CPY_SIZE);
  Adafruit_FlashTransport_RP2040_CPY flashTransport;

#else
  // On-board external flash (QSPI or SPI) macros should already
  // defined in your board variant if supported
  // - EXTERNAL_FLASH_USE_QSPI
  // - EXTERNAL_FLASH_USE_CS/EXTERNAL_FLASH_USE_SPI
  #if defined(EXTERNAL_FLASH_USE_QSPI)
    Adafruit_FlashTransport_QSPI flashTransport;

  #elif defined(EXTERNAL_FLASH_USE_SPI)
    Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS, EXTERNAL_FLASH_USE_SPI);

  #else
    #error No QSPI/SPI flash are defined on your board variant.h !
  #endif
#endif

Adafruit_SPIFlash flash(&flashTransport);

// file system object from SdFat
FatFileSystem fatfs;

Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
AnimatedGIF gif;
File32 f, root;

void * GIFOpenFile(const char *fname, int32_t *pSize)
{
  f = fatfs.open(fname);
  if (f)
  {
    *pSize = f.size();
    return (void *)&f;
  }
  return NULL;
} /* GIFOpenFile() */

void GIFCloseFile(void *pHandle)
{
  File32 *f = static_cast<File32 *>(pHandle);
  if (f != NULL)
     f->close();
} /* GIFCloseFile() */

int32_t GIFReadFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen)
{
    int32_t iBytesRead;
    iBytesRead = iLen;
    File32 *f = static_cast<File32 *>(pFile->fHandle);
    // Note: If you read a file all the way to the last byte, seek() stops working
    if ((pFile->iSize - pFile->iPos) < iLen)
       iBytesRead = pFile->iSize - pFile->iPos - 1; // <-- ugly work-around
    if (iBytesRead <= 0)
       return 0;
    iBytesRead = (int32_t)f->read(pBuf, iBytesRead);
    pFile->iPos = f->position();
    return iBytesRead;
} /* GIFReadFile() */

int32_t GIFSeekFile(GIFFILE *pFile, int32_t iPosition)
{ 
  int i = micros();
  File32 *f = static_cast<File32 *>(pFile->fHandle);
  f->seek(iPosition);
  pFile->iPos = (int32_t)f->position();
  i = micros() - i;
//  Serial.printf("Seek time = %d us\n", i);
  return pFile->iPos;
} /* GIFSeekFile() */

// Draw a line of image directly on the LCD
void GIFDraw(GIFDRAW *pDraw)
{
    uint8_t *s;
    uint16_t *d, *usPalette, usTemp[320];
    int x, y, iWidth;

    iWidth = pDraw->iWidth;
    // Serial.printf("Drawing %d pixels\n", iWidth);

    if (iWidth + pDraw->iX > DISPLAY_WIDTH)
       iWidth = DISPLAY_WIDTH - pDraw->iX;
    usPalette = pDraw->pPalette;
    y = pDraw->iY + pDraw->y; // current line
    if (y >= DISPLAY_HEIGHT || pDraw->iX >= DISPLAY_WIDTH || iWidth < 1)
       return; 
    s = pDraw->pPixels;
    if (pDraw->ucDisposalMethod == 2) // restore to background color
    {
      for (x=0; x<iWidth; x++)
      {
        if (s[x] == pDraw->ucTransparent)
           s[x] = pDraw->ucBackground;
      }
      pDraw->ucHasTransparency = 0;
    }

    // Apply the new pixels to the main image
    if (pDraw->ucHasTransparency) // if transparency used
    {
      uint8_t *pEnd, c, ucTransparent = pDraw->ucTransparent;
      int x, iCount;
      pEnd = s + iWidth;
      x = 0;
      iCount = 0; // count non-transparent pixels
      while(x < iWidth)
      {
        c = ucTransparent-1;
        d = usTemp;
        while (c != ucTransparent && s < pEnd)
        {
          c = *s++;
          if (c == ucTransparent) // done, stop
          {
            s--; // back up to treat it like transparent
          }
          else // opaque
          {
             *d++ = usPalette[c];
             iCount++;
          }
        } // while looking for opaque pixels
        if (iCount) // any opaque pixels?
        {
          tft.startWrite();
          tft.setAddrWindow(pDraw->iX+x, y, iCount, 1);
          tft.writePixels(usTemp, iCount, false, false);
          tft.endWrite();
          x += iCount;
          iCount = 0;
        }
        // no, look for a run of transparent pixels
        c = ucTransparent;
        while (c == ucTransparent && s < pEnd)
        {
          c = *s++;
          if (c == ucTransparent)
             iCount++;
          else
             s--; 
        }
        if (iCount)
        {
          x += iCount; // skip these
          iCount = 0;
        }
      }
    }
    else
    {
      s = pDraw->pPixels;
      // Translate the 8-bit pixels through the RGB565 palette (already byte reversed)
      for (x=0; x<iWidth; x++)
        usTemp[x] = usPalette[*s++];
      tft.startWrite();
      tft.setAddrWindow(pDraw->iX, y, iWidth, 1);
      tft.writePixels(usTemp, iWidth, false, false);
      tft.endWrite();
    }
} /* GIFDraw() */


void setup() {
  Serial.begin(115200);
  while (!Serial);

  Serial.println("Adafruit SPIFlash Animated GIF Example");

  // Initialize flash library and check its chip ID.
  if (!flash.begin()) {
    Serial.println("Error, failed to initialize flash chip!");
    while(1);
  }
  Serial.print("Flash chip JEDEC ID: 0x"); Serial.println(flash.getJEDECID(), HEX);

  // First call begin to mount the filesystem.  Check that it returns true
  // to make sure the filesystem was mounted.
  if (!fatfs.begin(&flash)) {
    Serial.println("Failed to mount filesystem!");
    Serial.println("Was CircuitPython loaded on the board first to create the filesystem?");
    while(1);
  }
  Serial.println("Mounted filesystem!");

  if (!root.open(GIFDIRNAME)) {
    Serial.println("Open dir failed");
  }
  while (f.openNext(&root, O_RDONLY)) {
    f.printFileSize(&Serial);
    Serial.write(' ');
    f.printModifyDateTime(&Serial);
    Serial.write(' ');
    f.printName(&Serial);
    if (f.isDir()) {
      // Indicate a directory.
      Serial.write('/');
    }
    Serial.println();
    f.close();
  }
  root.close();
  
  tft.init(DISPLAY_HEIGHT, DISPLAY_WIDTH);
  tft.fillScreen(ST77XX_BLUE);
  tft.setRotation(1);
  gif.begin(LITTLE_ENDIAN_PIXELS);
}

void loop() {
  char thefilename[80];
  
  if (!root.open(GIFDIRNAME)) {
    Serial.println("Open GIF directory failed");
    while (1);
  }
  while (f.openNext(&root, O_RDONLY)) {
    f.printFileSize(&Serial);
    Serial.write(' ');
    f.printModifyDateTime(&Serial);
    Serial.write(' ');
    f.printName(&Serial);
    if (f.isDir()) {
      // Indicate a directory.
      Serial.write('/');
    }
    Serial.println();
    f.getName(thefilename, sizeof(thefilename)-1);
    f.close();
    if (strstr(thefilename, ".gif") || strstr(thefilename, ".GIF")) {
      // found a gif mebe!
      if (gif.open(thefilename, GIFOpenFile, GIFCloseFile, GIFReadFile, GIFSeekFile, GIFDraw)) {
        GIFINFO gi;
        Serial.printf("Successfully opened GIF %s; Canvas size = %d x %d\n",  thefilename, gif.getCanvasWidth(), gif.getCanvasHeight());
        if (gif.getInfo(&gi)) {
          Serial.printf("frame count: %d\n", gi.iFrameCount);
          Serial.printf("duration: %d ms\n", gi.iDuration);
          Serial.printf("max delay: %d ms\n", gi.iMaxDelay);
          Serial.printf("min delay: %d ms\n", gi.iMinDelay);
        }
        // play thru n times
        for (int loops=0; loops<NUM_LOOPS; loops++) {
          while (gif.playFrame(true, NULL));
          gif.reset();
        }
        gif.close();
      } else {
        Serial.printf("Error opening file %s = %d\n", thefilename, gif.getLastError());
      }
    }
  }
  root.close();
}

Locked
Please be positive and constructive with your questions and comments.

Return to “Feather - Adafruit's lightweight platform”