ESP32-S3 LCD and I2S FULL documentation

Baldhead
Posts: 433
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Mon Mar 28, 2022 9:46 pm

?????

ESP_Sprite
Posts: 8921
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby ESP_Sprite » Tue Mar 29, 2022 3:49 am

I have no clue, sorry. The ESP_LCD RGB driver does quite a similar thing and does not have the problem of having corruption, so the hardware itself is OK, I think. One thing I know the ESP_LCD driver does is align the PSRAM data to a cache line (64 bytes), but I'm not sure how much that matters outside of speed.

Baldhead
Posts: 433
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Tue Mar 29, 2022 11:26 pm

ESP_Sprite wrote:
Tue Mar 29, 2022 3:49 am
I have no clue, sorry. The ESP_LCD RGB driver does quite a similar thing and does not have the problem of having corruption, so the hardware itself is OK, I think. One thing I know the ESP_LCD driver does is align the PSRAM data to a cache line (64 bytes), but I'm not sure how much that matters outside of speed.
i aligned the PSRAM data to a cache line (64 bytes) and not solve the problem.

May be a cache coherence problem ?

is there any attribute to make a buffer coherent ?
ex: uint16_t __attribute__((coherent)) buffer_a[BUFFER_LENGTH] ;

How can i disable cache for testing ?

ESP_Sprite
Posts: 8921
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby ESP_Sprite » Wed Mar 30, 2022 12:51 am

You may be on to something wrt caching being the issue. To answer your questions: You can't disable cache. You also can't make it coherent wrt edma. What you need to do is make sure the data is written back to the PSRAM after you write it (using the CPU) and before it is read by DMA. You can use the Cache_WriteBack_Addr() function for that.

Baldhead
Posts: 433
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Wed Mar 30, 2022 7:57 pm

ESP_Sprite wrote:
Wed Mar 30, 2022 12:51 am
You may be on to something wrt caching being the issue. To answer your questions: You can't disable cache. You also can't make it coherent wrt edma. What you need to do is make sure the data is written back to the PSRAM after you write it (using the CPU) and before it is read by DMA. You can use the Cache_WriteBack_Addr() function for that.
@ESP_Sprite,

I know very little about cache memory.
Could you give me a link so i can try to understand the cache memory further(in low level way) ?

I didn't find documentation about this function "Cache_WriteBack_Addr()".

**************************************************************************************************************
Test 1:

The code below, when i send only the first 2 bytes by dma, the io output is 0xffff and not 0x1234.

Code: Select all

#define pixels_size 153600

for( uint32_t i = 0 ; i < pixels_size ; i++ )
{      
    p_buffer_a[ i ] = 0xffff; 
}

p_buffer_a[ 0 ] = 0x1234;

The code below, when i send only the first 2 bytes by dma, the io output is 0x1234.

Code: Select all

#define pixels_size 153600

p_buffer_a[ 0 ] = 0x1234;

for( uint32_t i = 1 ; i < pixels_size ; i++ )
{      
    p_buffer_a[ i ] = 0xffff; 
}
Is this a cache issue ?

********************************************************************************************************
Test 2A: Filling all buffer positions with 0xffff.
153600 uint16_t buffer size

The other problem still persists. When i send all 153600 * 2 bytes by dma, the data at end of the buffer is corrupted.
Maybe a cache issue too, for now i don't know.

Config Data cache size = 32kB or 64kB.
Until sending by dma 145414 * 2 bytes, apparently all data is ok ( 0xffff ).
From 145415 * 2 bytes onwards it starts to corrupt the information, when i send 145415 * 2 only the last 2 bytes are corrupted.


Test 2B: Filling all buffer positions with 0xffff.
76800 uint16_t buffer size

Config Data cache size = 32kB or 64kB.
Until sending by dma 60422 * 2 bytes, apparently all data is ok ( 0xffff ).
From 60423 * 2 bytes onwards it starts to corrupt the information, when i send 60423 * 2 only the last 2 bytes are corrupted.

"Magic numbers" :)

Baldhead
Posts: 433
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Wed Mar 30, 2022 10:45 pm

@ESP_Sprite,

If the buffers are big:

How do i know when the cache has finished updating the PSRAM ?

If cache already updated a part of the buffer in psram and i call this function, will the cache update the entire buffer again in psram ? or just the part that hasn't been updated yet ?

Please do not call this function in your SDK application ?????

Code: Select all

#include "esp32s3/rom/cache.h"

/**
  * @brief Writeback the Cache items(also clean the dirty bit) in the region from DCache.
  *        If the region is not in DCache addr room, nothing will be done.
  *        Please do not call this function in your SDK application.
  *
  * @param  uint32_t addr : writeback region start address.
  *
  * @param  uint32_t size : writeback region size.
  *
  * @return 0 for success
  *         1 for invalid argument
  */
int Cache_WriteBack_Addr(uint32_t addr, uint32_t size);

ESP_Sprite
Posts: 8921
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby ESP_Sprite » Thu Mar 31, 2022 1:17 am

Cache is described in section 3 of the TRM, but here's the Cliffs Notes: There's a certain amount (configurable, I think 32 or 16K) of cache between the CPU and the PSRAM/flash. The idea is that if you access a byte in psram, the cache loads not only that byte but an entire cache line (32 or 64 bytes) in its RAM. If you then need to modify this byte, re-read it, or read the bytes that are next to it (e.g. a memcpy loop), the cache can handle these requests and you don't need to wait for the relatively slow flash or PSRAM bus.

As cache is not of unlimited size, if it's full and you want to read new data, it needs to 'push out' old data. For flash data (which is seen as read-only), the cache simply throws it away, but for PSRAM data that has been modified (the term is that the cache line is 'dirty'), it needs to write back the cache line to PSRAM entirely.

Now, this mostly works entirely transparent; if all you use is the CPU to access PSRAM, you never have to worry about the cache; while there may be a discrepancy between what the CPU sees and what is actually in the PSRAM, the CPU can't access the PSRAM directly anyway, so who cares, right?

This changes when you start doing DMA from PSRAM. DMA accesses PSRAM directly, not through the cache. While this may initially sound stupid, there's a good reason for it: for instance, if you were to use PSRAM to store audio data to send to an I2S device and that would happen through the cache, the wave data would need to be read into the cache, only to be used exactly once, so the cache doesn't give you any real benefit... but at the same time, it would 'push out' data that probably would be useful to have in cache, so the net performance would be diminished by a lot.

So what you probably ran into is the following: you write a chunk of data that is many times the size of the cache. This means the cache fills up a few times, and when more than the size of the cache is written, every new write triggers a writeback of the old data. That happens all the way up to the final byte, at which state everything except what's currently in the cache (the last 5%, as you said?) is written back. Then you start up DMA, and all the data is read correctly... except for the last 5%, as it's still hanging around in the cache and never made it back to the PSRAM.

So, as I said, Cache_WriteBack_Addr solves this, as it forces a writeback of all data in a certain range. You call it with the starting address and the size of the buffer you wrote, and then the cache goes to work and sees if there's anything in that range that needs to be written back. From what I can tell, the call is blocking, so after it returns you can be sure the data made it to the PSRAM.

The reason that all the calls in that file are marked as 'do not use in the SDK' is that caching functions generally are a bit finnicky with regards to interrupts and multicore operation... while writeback is pretty innocuous, you also have functions like 'clean' (act like a cache line never has been written to) and 'invalidate' (throw away a cache line without writing it back). You can probably imagine that those ops can lead to data loss if one core does them while the other core is working on something in the same memory region. We still need to figure out how we can make these caching functions more accessible (as they're pretty useful if you want to speed up operations). For now, feel free to assume at least the writeback function is safe.

Does that make it understandable why you're getting the results you're getting?

Baldhead
Posts: 433
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Mon Apr 04, 2022 8:16 pm

@ESP_Sprite,

Can you help me with this ?
Could you pass it on to the responsible team ?
I'm stuck on it.

https://github.com/espressif/vscode-esp ... issues/688

Thank's.

ESP_Sprite
Posts: 8921
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby ESP_Sprite » Tue Apr 05, 2022 2:37 am

Have some patience please. That team has other things to do as well, additionally it's only been two days, and it's a holiday here in China.

Baldhead
Posts: 433
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Fri Apr 08, 2022 12:48 am

I'm having patience.

One week trying to solve that problem and nothing.

Most likely the problem is with the "ESP-IDF VS Code Extension".

I installed it on 2 different computers and the same problem.

And i'm not the only one using this vsc extension. It has more than 168 thousand downloads, is it just me having this problem ?

Who is online

Users browsing this forum: No registered users and 52 guests