Closed el-samiyel closed 8 months ago
If your LCD and SD card are sharing the same SPI bus, then using DMA could potentially have both devices trying to access the bus at the same time. Try it without DMA (change the tft.writePixels parameters)
I see, yes they are sharing the same SPI bus, I have changed the DMA settings to false but still no luck: tft.writePixels(pDraw->pPixels, pDraw->iWidth * pDraw->iHeight, false, false); // Use DMA, big-endian
Are there any other areas I could explore in order to rectify?
Many Thanks
Do the white bars mean that the image is corrupt from that point down? Any data corruption in reading JPEG data usually means the rest of the image is garbage from that point onward. If you see white bars, but the rest of the image decodes properly, it probably means something is interfering with writing pixels to the LCD or the memory used for storing the pixels is being overwritten. Does it only happen on certain images, or on every image?
Its actually the latter, so I get: Good decoding for about an eighth of the image > white bar full width > good decode > 2 x white bar > good decode half the width of the image.
The white bars appear to be random in nature. I also tested with a T4 on an ILI9341 and get the same results, but the bars are in a different position.
This happens on very image, I also downloaded a fresh set of images ensuring they were baseline but got the same result.
What's interesting is that if I run the examples with images created out of C code, they load up just fine.
I can test this on the same hardware. I'll let you know what I find.
@bitbank2 I met same problem...
Can you send me the full code you're using to decode the image? It looks like an internal memory corruption problem.
It is the callback function. I use the default SD.h lib from the arduino of rp2040, and two independent SPI for screen and sdcard. The e-ink screen driver is the GxEPD2. Thank you for your reply, I will try to split the bloated code and post a complete example. @bitbank2
void convert_rgb_565_to_rgb(uint16_t rgb565, uint16_t *r, uint16_t *g, uint16_t *b) {
*r = (rgb565 & 0xF800) >> 8;
*g = (rgb565 & 0x07E0) >> 3;
*b = (rgb565 & 0x001F) << 3;
}
int JPEGDraw_callback(JPEGDRAW *pDraw) {
yield();
bool _with_color = true;
uint16_t red, green, blue;
bool whitish = false;
bool colored = false;
uint16_t color = GxEPD_WHITE;
int x = pDraw->x;
int y = pDraw->y;
int w = pDraw->iWidth;
int h = pDraw->iHeight;
for (int16_t i = 0; i < w; i++) {
for (int16_t j = 0; j < h; j++) {
no_block_thread();
convert_rgb_565_to_rgb(pDraw->pPixels[i + j * w], &red, &green, &blue);
whitish = _with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0));
color = ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ((blue & 0xF8) >> 3);
if (_with_color) {
// keep color
} else if (whitish) {
color = GxEPD_WHITE;
} else if (colored && _with_color) {
color = GxEPD_COLORED;
} else {
color = GxEPD_BLACK;
}
display.drawPixel((x + i), (y + j) , color);
} // for j
} // for i
return 1;
} /* JPEGDraw() */
The above code is extremely inefficient, but not necessarily wrong. I would like to see the rest of the app before I make any conclusions.
Hi Larry,
After some support with an issue I am having, probably something I am doing wrong. When drawing from the SD card, I am getting horizontal white bars across the screen.
I have checked that I am drawing baseline jpgs and checked the return codes but cant see any immediate errors.
`#include "Adafruit_GFX.h"
include
include
include
define TFT_CS 13
define TFT_DC 5
define TFT_RST 12
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST); JPEGDEC jpeg;
void setup() {
Serial.begin(115200); tft.init(240, 240); tft.setRotation(3); tft.fillScreen(ST77XX_BLACK); tft.setTextColor(ST77XX_YELLOW); tft.setTextSize(2); tft.println("Waiting for Arduino Serial Monitor...");
while (!Serial && millis() < 3000) ; // wait up to 3 seconds for Arduino Serial Monitor Serial.println("ILI9341 Slideshow"); tft.fillScreen(ST77XX_BLACK); tft.setCursor(0, 0);
while (!SD.begin(2)) { Serial.println("Unable to access SD Card"); tft.println("Unable to access SD Card"); delay(1000); } tft.startWrite(); }
// Functions to access a file on the SD card File myfile;
void myOpen(const char filename, int32_t size) { myfile = SD.open(filename); size = myfile.size(); return &myfile; } void myClose(void handle) { if (myfile) myfile.close(); } int32_t myRead(JPEGFILE handle, uint8_t buffer, int32_t length) { if (!myfile) return 0; return myfile.read(buffer, length); } int32_t mySeek(JPEGFILE handle, int32_t position) { if (!myfile) return 0; return myfile.seek(position); }
// Function to draw pixels to the display int JPEGDraw(JPEGDRAW pDraw) { Serial.printf("jpeg draw: x,y=%d,%d, cx,cy = %d,%d\n", pDraw->x, pDraw->y, pDraw->iWidth, pDraw->iHeight); tft.startWrite(); tft.setAddrWindow(pDraw->x, pDraw->y, pDraw->iWidth, pDraw->iHeight); tft.writePixels(pDraw->pPixels, pDraw->iWidth pDraw->iHeight, true, false); // Use DMA, big-endian return 1; }
// Main loop, scan for all .JPG files on the card and display them void loop() { int filecount = 0; tft.setCursor(0, 0); File dir = SD.open("/"); while (true) { File entry = dir.openNextFile(); if (!entry) break; if (entry.isDirectory() == false) { const char name = entry.name(); const int len = strlen(name); if (len > 3 && strcasecmp(name + len - 3, "JPG") == 0) { Serial.print("File: "); Serial.println(name); tft.print("File: "); tft.println(name); jpeg.open((const char )name, myOpen, myClose, myRead, mySeek, JPEGDraw); jpeg.decode(0, 0, 0); jpeg.close(); filecount = filecount + 1; } } entry.close(); } if (filecount == 0) { Serial.println("No .JPG files found"); tft.println("No .JPG files found"); delay(2000); } }`
I modified your t3 example to work with that adafruit ST7789. A point in the right direction will be most appreciated.
Hardware: [Adafruit Feather M4 Express) SAMD51 120mhz.
Many Thanks