nikthefix / General-queries-and-discussion

0 stars 0 forks source link

Problem with T-Display-S3-Amoled RM67162 display #1

Open twj42 opened 3 months ago

twj42 commented 3 months ago

Hi Nik, I'm having a problem with a T-Display-S3-Amoled (v1 I think) project I'm working on, and I wonder if you can help, given your knowledge of the rm67162. The project uses TFT_eSPI and your versions of the rm67162.* files. I'm working on trying to reduce the power consumption, and the problem I am having is that when I issue lcd_display_off (command x28), the display goes off, but I cannot switch it on again using lcd_display_on.

Sample code here:

// DisplayTest.ini - skeleton display .ino
//
// Testing display switch on / off
//

#include "rm67162.h"
#include "TFT_eSPI.h"

//
// Port Defines
#define PIN_LED       38

//
// Display Stuff
TFT_eSPI tft= TFT_eSPI();
TFT_eSprite spr_back = TFT_eSprite(&tft);

//
// Variables
String s_message;

//
// Setup
void setup()
{
  Serial.begin(115200);
//
// Configure I/O
  pinMode(PIN_LED,       OUTPUT);
  digitalWrite(PIN_LED,  LOW);
//
// Configure display
  rm67162_init();
  lcd_setRotation(1);
  spr_back.createSprite(TFT_HEIGHT, TFT_WIDTH);
  spr_back.setSwapBytes(1);

} // end of setup

//
// Loop
void loop()
{

// Switch screen on
  Serial.println("Display On");
  lcd_display_on();
  digitalWrite(PIN_LED,  HIGH);

// Clear screen
  spr_back.fillSprite(TFT_BLACK);

// Message
  s_message="DisplayTest1    ";
  Serial.println(s_message);
  spr_back.drawString(s_message,20,20,4);

// Display sprite
  lcd_PushColors(0, 0, TFT_HEIGHT, TFT_WIDTH, (uint16_t*)spr_back.getPointer());
  delay(4000);

// Switch screen off
  Serial.println("Display Off");
  lcd_display_off();
  digitalWrite(PIN_LED,  LOW);
  delay(4000);

} // end of loop

Am I missing something? Or doing something stupid? All help gratefully received. :-)

Cheers Tim

nikthefix commented 3 months ago

@twj42

Hi,

Yes Display Off does indeed power down the display hardware so after a Display On command the display is uninitialized therefore rm67162_init() needs to be called again. The datasheet is unclear about this as it suggests that all registers are unaffected by the power down state. However, this is clearly not the case. A re-init of the display on wake is the most power efficient approach with the added benefit that the display fades in gracefully with no tearing artifacts.

According to the datasheet, the command 0x10 (sleep in) is the most power saving as it shuts down the bus oscillators as well as the display hardware. But it seems to me that Display Off is doing this too.

I would add that unless your low power sleep requirements are critical then, this being an AMOLED, 90% of your power saving is available by simply blanking the screen. If you're wanting to go further to save power by sleeping the ESP32-S3 too then a re-init of the display would be necessary anyway.

In my experience the display datasheets cannot be taken as gospel. Partly because they always seem to be 'preliminary info' and also because it's unlikely your device uses a 'virgin' display / controller combination. More often than not the display package has been factory configured (One Time Programmable) for a large commercial order. What we often get on Aliexpress and likewise in our Lilygo products etc are these same (perhaps surplus) pre-configured units which may or may not include all the features outlined in the datasheet.

nik

twj42 commented 3 months ago

That is excellent Nik - added the rm67162_init and it works as expected. Bloody datasheet - must have read it 10 times to see if I was missing anything :-( Thanks again.

nikthefix commented 3 months ago

@twj42

Yes and there's no real overhead in calling the init function. It's probably wise to do it anyway after a power state change, just to be sure.

But it's great that you study the datasheets. I wish more makers did. There are often hidden gems.... (some of which might actually work!)

twj42 commented 3 months ago

Unfortunately spoke too soon, all looks OK until you check the serial monitor ...

Display On
DisplayTest1    
Display Off
E (9756) spi: spi_bus_initialize(768): SPI bus already initialized.
ESP_ERROR_CHECK failed: esp_err_t 0x103 (ESP_ERR_INVALID_STATE) at 0x4200211c
file: "D:\Data\Electronics\Boiler Control V2\DisplayTest\rm67162.cpp" line 135
func: void rm67162_init()
expression: ret

abort() was called at PC 0x4037c71b on core 1

Backtrace: 0x40377316:0x3fcebd70 0x4037c725:0x3fcebd90 0x40382279:0x3fcebdb0 0x4037c71b:0x3fcebe30 0x4200211c:0x3fcebe60 0x42001feb:0x3fcebee0 0x420094b8:0x3fcebf00 0x4037f2ca:0x3fcebf20

ELF file SHA256: 61fcd2c4a9122c79

Rebooting...
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0x18 (SPI_FAST_FLASH_BOOT)
Saved PC:0x40379c42
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3818,len:0x508
load:0x403c9700,len:0x4
load:0x403c9704,len:0xad0
load:0x403cc700,len:0x29e4
entry 0x403c9880
Display On
DisplayTest1    

Any ideas?

twj42 commented 3 months ago

Fixed it - created rm67162_init2 and excluded the qspi/spi init code.

nikthefix commented 3 months ago

/* Ignore this

Interesting! In what way did your rm67162_init2 routine differ from mine? And your serial monitor dump shows that you were stuck in a boot loop yet you had it working before? Does it only crash when the serial monitor is active? What happens if you set debug error level to 'none'? With the older configuration could you check that in the build options the PSRAM is set to OPI?

*/

On a side note, I've been having trouble recently uploading sketches using the latest version of the Arduino IDE. At times (but inconsistently) I can only succeed if the serial monitor is open.

Edit: Ah I think I see what's going on. You need to free the SPI object before you can call rm67162_init() again as this routine will try to redefine it resulting in the error. And you found the fix by just removing the qspi setup call from the display init function. So you call init1 on power up then init2 for subsequent display wakeups? Nice workaround!

So we'd be better of with init_qspi_bus() and init_display() as discrete functions in this case?

If you could confirm that this approach is working consistently for you then I'll modify my driver and update on github.

twj42 commented 3 months ago

I've certainly had inconsistency with uploads, but can't say definitively it is related to serial monitor. What I have noticed, is having to change the USB CDC on Boot to disabled to get any SM output. Set back to Enabled now after the latest update, and seems to be stable.

Yes, init_qspi_bus() and init_display() as discrete functions seems a good idea.

Publicising the datasheet omissions re the requirement for a display init after display_off and similar commands is not a bad idea either :-)