bitluni / ESP32Lib

http://bitluni.net/esp32-vga/
441 stars 78 forks source link

[Heads Up] Lib no longer working on ESP-VGA32 #64

Closed WacKEDmaN closed 3 years ago

WacKEDmaN commented 3 years ago

Board: LilyGO TTGO VGA32 V1.4 Arduino: 1.18.13 ESP32 Core; 2.0.0-alpha1

previously worked in 6bit mode and lower with vga32 custom pin layout

firstly the "release" lib fails to compile on ESP32 2.0.0-alpha1 core.. i updated to latest dev branch, it compiles and uploads fine, but no output on screen! going back to ESP32 Core 1.0.6, and 0.3.3 release version,but 6bit mode still fails to output (VGA3Bit works fine)

//VGA Device
VGA6Bit vga;

//pin configuration
const int redPins[] = {22,21};
const int greenPins[] = {19, 18};
const int bluePins[] = {5,4};
const int hsyncPin = 23;
const int vsyncPin = 15;

vga.init(vga.MODE320x200, redPins, greenPins, bluePins, hsyncPin, vsyncPin);
Martin-Laclaustra commented 3 years ago

I would really appreciate more complete information. Please set several Serial.println("mark 1"); before and after init and at several places in the sketch to detect stalling. There could be some variability between chips and we need to gather information. Would you mind systematically testing development branch with the following modes in several Cores?

3Bit, 6Bit, 14Bit. vga.init(vga.MODE320x200, redPins, greenPins, bluePins, hsyncPin, vsyncPin, -1, true); will work for the three of them (you will always get output in the first pins of the pin arrays.

Cores: ESP32 2.0.0-alpha1 ESP32 Core 1.0.6 ESP32 Core 1.0.4

Thanks

WacKEDmaN commented 3 years ago

hmm i grabbed the latest dev branch and seems all modes are compiling now, but still having issues...

heres the code im testing...

//This example shows a rendering of Julia set. Please change the pinConfig if you are using a different board to PicoVGA
//cc by-sa 4.0 license
//bitluni

//include libraries
#include <ESP32Video.h>
#include <Ressources/Font6x8.h>

//VGA Device
VGA6Bit videodisplay;
//Pin presets are avaialable for: VGAv01, VGABlackEdition, VGAWhiteEdition, PicoVGA
//const PinConfig &pinConfig = VGA6Bit::PicoVGA;
//pin configuration
const int redPins[] = {22,21};
const int greenPins[] = {19, 18};
const int bluePins[] = {5,4};
const int hsyncPin = 23;
const int vsyncPin = 15;

int taskData[2][3] = 
  {
    {0, 0, 160},
    {0, 160, 320} 
  };

static float v = -1.5;
static float vs = 0.001;

//https://en.wikipedia.org/wiki/Julia_set#Pseudocode_for_normal_Julia_sets
int julia(int x, int y, float cx, float cy)
{
  Serial.println("julia..");
  int zx = ((x - 159.5f) * (1.f / 320.f * 5.0f)) * (1 << 12);
  int zy = ((y - 99.5f) * (1.f / 200.f * 3.0f)) * (1 << 12);
  int i = 0;
  const int maxi = 17;
  int cxi = cx ;
  int cyi = cy * (1 << 12);
  while(zx * zx + zy * zy < (4 << 24) && i < maxi) 
  {
    int xtemp = (zx * zx - zy * zy) >> 12;
    zy = ((zx * zy) >> 11) + cyi; 
    zx = xtemp + cxi;
    i++;
  }
  return i;
}

int colors[] = {
  0b110001, 0b110010, 0b110011, 0b100011, 0b010011,
  0b000011, 0b000111, 0b001011, 0b001111, 0b001110, 0b001101, 
  0b001100, 0b011100, 0b101100, 0b111100, 0b111000, 0b110100, 
  0b110000};

void renderTask(void *param)
{
  Serial.println("rendertask..");
  int *data = (int*)param;
  while(true)
  {
    while(!data[0]) delay(1);
    for(int y = 0; y < 100; y++)
      for(int x = data[1]; x < data[2]; x++)
      {
        int c = colors[julia(x, y, -0.74543f, v)];
        videodisplay.dotFast(x, y, c);
        videodisplay.dotFast(319 - x, 199 - y, c);
      }
    data[0] = 0;
  }
}

//initial setup
void setup()
{
  Serial.begin(115200);
    //initializing i2s vga (with only one framebuffer)
  Serial.println("stating video..");
    videodisplay.init(VGAMode::MODE320x200, redPins, greenPins, bluePins, hsyncPin, vsyncPin, -1, true);
  Serial.println("vid started..");
  TaskHandle_t xHandle = NULL;
  xTaskCreatePinnedToCore(renderTask, "Render1", 2000, taskData[0],  ( 2 | portPRIVILEGE_BIT ), &xHandle, 0);
  xTaskCreatePinnedToCore(renderTask, "Render2", 2000, taskData[1],  ( 2 | portPRIVILEGE_BIT ), &xHandle, 1);
}

//just draw each frame
void loop()
{
  Serial.println("loop!");
  static unsigned long ot = 0;
  unsigned long t = millis();
  unsigned long dt =  t - ot;
  ot = t;
  taskData[0][0] = 1;
  taskData[1][0] = 1;
  //waiting for task to finish
  while(taskData[0][0] || taskData[1][0]) delay(1);
  v += vs * dt;
  if(v > 1.5f)
  {
    v = 1.5f;
    vs = -vs;
  }
  if(v < -1.5f)
  {
    v = -1.5f;
    vs = -vs;
  }
}

im just changing between VGA6bit, VGA3Bit, and VGA14 bit... (changed pins to singles for 3bit)
all 3 modes compile for both 1.0.6 and 2.0.0-alpha1, 6bit and 3bit have no output/serial stops at 'starting video...' 14bit works but only has 2 colors (red and black)

raytracer demo on 2.0.0-alpha1 with only pin config changes.. i get exceptions with all modes..

Rebooting...
Guru Meditation Error: Core  1 panic'ed (StoreProhibited). Exception was unhandled.

Core  1 register dump:
PC      : 0x400d73d6  PS      : 0x00060d30  A0      : 0x800da176  A1      : 0x3ffb2770  
A2      : 0x3ffc00f0  A3      : 0x000000a0  A4      : 0x3ffb9620  A5      : 0x00000171  
A6      : 0x00000000  A7      : 0x00000280  A8      : 0x800d73b8  A9      : 0x00000000  
A10     : 0x00000280  A11     : 0x0000001a  A12     : 0x400d9bb0  A13     : 0x00000000  
A14     : 0x00000008  A15     : 0x00000000  SAR     : 0x0000001c  EXCCAUSE: 0x0000001d  
EXCVADDR: 0x00000000  LBEG    : 0x40085e2d  LEND    : 0x40085e3d  LCOUNT  : 0xfffffff9  

Backtrace:0x400d73d3:0x3ffb27700x400da173:0x3ffb2820 

ELF file SHA256: 0000000000000000

TextMode fails to output anything also...but no exception..

VGAHighRes works!..i havent tested others yet...

this is the board im using.... https://ae01.alicdn.com/kf/H76eebd74dfa54dff9a2c0c2e931e09ebe.jpg

Martin-Laclaustra commented 3 years ago

heres the code im testing...

This is not the best "multimode" example because "color" is feed to the functions in the 6 bits format and this has not an easy amendment (the array colors[] should be written by the program with the appropriate colors: i.e. replacing 0b110001 by the result of videodisplay.RGB(255,0,63), 0b110010, by videodisplay.RGB(255,0,127), etc.). "Hellowolrd" is better to test all modes.

im just changing between VGA6bit, VGA3Bit, and VGA14 bit... (changed pins to singles for 3bit) all 3 modes compile for both 1.0.6 and 2.0.0-alpha1, 6bit and 3bit have no output/serial stops at 'starting video...'

I was suspecting this. This is quite difficult to pinpoint because it does not happen with all chips. It is essential to test whether this worked with previous cores: ESP32 Core 1.0.5, ESP32 Core 1.0.4... If so, a detailed bug report could be written upstream, because it is I2S 8bit modes what stopped working in "particular" chips (which we will need to identify too... more on that when we advance on the investigation).

14bit works but only has 2 colors (red and black)

That is because of the "color" problem in this example that I described above.

raytracer demo on 2.0.0-alpha1 with only pin config changes.. i get exceptions with all modes..

That looks like an Out of memory problem. Maybe this core version leaves less free memory? I'll have a look. In the meantime, try 'videodisplay.setFrameBufferCount(1);'.

TextMode fails to output anything also...but no exception..

This is consistent because this mode outputs through 8bit paralel I2S. Please test it too with a previous core if other modes (3bit) work there.

VGAHighRes works!..i havent tested others yet...

Things get complicated here, because this outputs too through 8bit I2S. Then the suspect problem is a combination of output frequency (works for that of MODE800x600, 36000000Hz, but not for that of MODE320x240, 12587500Hz), chip (this should be investigated further), and output bits (works for 16bit parallel I2S but not for 8bit parallel I2S).

May be the ESP32 Core deverlopers patched something with respect to I2S APLL and something broke. If we succeed in delimiting the problem as much as possible (which core it started, etc.) then we might be able to find the culprit commit.

this is the board im using.... https://ae01.alicdn.com/kf/H76eebd74dfa54dff9a2c0c2e931e09ebe.jpg

We will need details of the chip with esptool, which provides the type and revision.

Thank you for your help. It is much appreciated. I feel that this problem will be very difficult to solve if more collaborators do not join in.

WacKEDmaN commented 3 years ago

ok.. firstly the esp32 specs...

Chip is ESP32-PICO-D4 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, Embedded Flash, VRef calibration in efuse, Coding Scheme None
Auto-detected Flash size: 4MB

it also has a PSRAM: external 8MB chip

installed 1.0.5 Core... raytracer still crashes, with any resolution, even with the setBufferCount(1)... (i had it runnin on older version of the your lib with limited colors) TextMode, MODE320x240 doesnt display a screen, but MODE640x480 does!.. but the text is unreadable... MODE400x300 works!! perfect! (even in the 6bitMode example!)... VGA2DFeatures example also working in 6bitMode with the 400x300 res.. (14bit exceptions)

reinstalled 2.0.0-alpha1... using saved code working in 1.0.5 TextMode working at 400x300 6bitMode... also working at 400x300 VGA2DFeatures .. exceptions in both 14bit and 6bit modes...(raytracer exceptions too with any res)

hmm so really its looking like some display modes are not working with my monitor.... but there still seems to be memory issues...and exceptions with code on 2.0.0-alpha1 core that worked with 1.0.5 core

Martin-Laclaustra commented 3 years ago

esp32 specs...

I checked my chips and I have two identical (in esptool) but only one of them works in all modes.

it also has a PSRAM: external 8MB chip

That sounds like an interesting feature to test, in particular for "interrupt-based modes" (It might require creating special code to copy chunks from a big video buffer in psram to regular memory or DMA memory - but that could not be within a DMA interrupt, because SPI causes incompatibility during ISR).

installed 1.0.5 Core... raytracer still crashes, with any resolution, even with the setBufferCount(1)... (i had it runnin on older version of the your lib with limited colors)

I just tested it in the 2.0.0-alpha1, and after videodisplay.setFrameBufferCount(1); it works. (leave VGA14bit and the resolution as it is in the example). It even works for 400x300 if you change to VGA6bit.

TextMode, MODE320x240 doesnt display a screen, but MODE640x480 does!.. but the text is unreadable...

Interrupt-based modes have a limit on what can be done during rendering of each line, thus hiqh-frequency resolutions only allow for buffer copying, not for text rendering.

MODE400x300 works!! perfect! (even in the 6bitMode example!)... VGA2DFeatures example also working in 6bitMode with the 400x300 res.. (14bit exceptions)

It works for VGA14bit with videodisplay.setFrameBufferCount(1); .

reinstalled 2.0.0-alpha1... using saved code working in 1.0.5 TextMode working at 400x300 6bitMode... also working at 400x300 VGA2DFeatures .. exceptions in both 14bit and 6bit modes...(raytracer exceptions too with any res)

It works for VGA14bit with videodisplay.setFrameBufferCount(1); . For other modes, try reducing horizontal resolution (in my tests it worked for VGA6bit with 400x150 videodisplay.setFrameBufferCount(2); ).

so really its looking like some display modes are not working with my monitor.... but there still seems to be memory issues...and exceptions with code on 2.0.0-alpha1 core that worked with 1.0.5 core

I tested all examples on 2.0.0-alpha1 core (in one of the chips with "problems"). All that are based on VGA14bit worked, except for lower memory availability in: Raytracer and VGA2DFeatures, which worked without double buffering. All other modes worked at 400x300 or 400x150, if there were memory shortage. VGAFonts was one of these that needed reduction of the resolution.

VGANoFrameBuffer needs updating in the development branch and it does not work at all.

In summary, there are two different problems here (we should split them in two issues):

  1. Some chips have trouble outputting parallel 8bit I2S at particular frequencies. I still think that this probably depends on a particular persistent-state, possibly related to wifi. See https://github.com/bitluni/ESP32Lib/issues/21 . In fact two of my chips from the same batch behave differently (I might have run a particular sketch that set that "state" in the one that works). I do not know how to advance this. Can you confirm the statement of the OP "previously worked in 6bit mode and lower with vga32 custom pin layout"? Can you make that work again going back in the setup to the one that works? Or you may have seen it working with a different chip?
  2. Reduced memory availability in ESP32 2.0.0-alpha1 core. We will have to wait to a more advanced release before modifying anything. I also know that development is a bit less memory efficient than the last official release, but there are many advantages of current code structure. Fixing is in the list with low priority.
WacKEDmaN commented 3 years ago

omg!.. i missed videodisplay.setFrameBufferCount(1); i was adding it after init without seeing it above... :eyeroll: and my ide is doing weird things your lib ..... i tried going back to release but nothing would compile (on 2.0.0-alpha1).. i ended up deleted library folders and reinstalled your development branch ...

raytracer now working... in 14bit 320x240!.. and 6bit 400x300 with buffercount set correctly!..SMH sorry to send you on a wild goose chase... other 14bit examples are working with the framebuffer set lower aswell...seems i can use other resolutions aswell (depending on memory!) ..and double framebuffer is working at 200x150 with VGA3DEngine example!,..

so yeah seems alpha1 uses some more memory.. and dev branch is working OK!... sorry again... ...ill go hang my head in shame now! :P

edit: VGANoFrameBuffer example fails to compile with.."'I2S_OUT_EOF_DES_ADDR_REG' was not declared in this scope"