Page 2 of 2

Re: How the EPSON S2D13A05 is connected and controlled by MAC7116 in preFL Convers+

Posted: 01 Jan 2020, 22:48
by Go4IT
This sub looks pretty much like what we are looking for:

Code: Select all

_WORD *sub_2358E()
{
  return dispctrl_memcp((_WORD *)0x20217700, (_WORD *)0x20200000);
}

Code: Select all

_WORD *__fastcall dispctrl_memcp(_WORD *src_ptr, _WORD *target_ptr)
{
  unsigned int v2; // r2

  v2 = 0;
  do
  {
    *target_ptr = *src_ptr;
    ++target_ptr;
    ++src_ptr;
    ++v2;
  }
  while ( v2 < 0xBB80 );
  return src_ptr;
}
As you see the was another frame buffer. Maybe the first address is used to draw the image off-screen and than get's transferred into the visible memory using this function. The memcp function transfers, in word-mode (=16 Bit because of the databus between MAC and EPSON) 0xBB80 words (*2 = 17.700 bytes = 1 frame) from source to target.

As you can see the framebuffer-copy method is called from a huge list of subs:
ida-pro_lcd_draw_xref.jpg
So let's call this routine "dispctrl_show_frame" or "refresh_frame".

The XREF leads to many many drawing routines for menus and single graphics. This is the one i've search and will investigate on!

Re: How the EPSON S2D13A05 is connected and controlled by MAC7116 in preFL Convers+

Posted: 02 Jan 2020, 00:16
by DGAlexandru
As for S1D13A05 vs S2D13A05, after some hours of researching over the Internet, I come to the conclusion they are the same :)
S1D13A05 was available at some time also in QFP5-128pin (36x2 + 28x2) as "our" S2D13A05 that is present in Convers+.

Image


Some German discussion about it: https://www.mikrocontroller.net/topic/68262

Also a PDF about this version of S1D13A05:
S1D13A05-1165589.pdf
And the reason for implementing RGB8:
At a color depth of 8 bpp, each byte of display buffer represents one pixel on the display. At this color depth the read-modify-write cycles are eliminated making the update of each pixel faster.

In the process of "decrypting" ASM and the resulted Pseodo-code, this example files should come in handy:
S1D13A05_Initialization_Source_Example.zip

Re: How the EPSON S2D13A05 is connected and controlled by MAC7116 in preFL Convers+

Posted: 02 Jan 2020, 12:15
by DGAlexandru
And I found an older version of "S1D13A05 Hardware Functional Specification" that still had the QFP5-128pin version of S1D13A05 so now we can see its pinout :D
S1D13A05F00A100-12522721_rev7.6.pdf
@GoIT upload the files you think are good for keeping to your WiKi and then we can delete them from here.

Re: How the EPSON S2D13A05 is connected and controlled by MAC7116 in preFL Convers+

Posted: 02 Jan 2020, 13:39
by Go4IT
Good job, @DGAlexandru! Yes, i will always try to cummulate all informations gathered here into the Wiki as a reference: https://mk4-wiki.denkdose.de/en/artikel ... 13a05f00a1
But it's a hell of a work to do for one person, even now where we are more in research phase... and still good headaches from new years eve party ;-)
epson_s1d13a05f00a1_qfp5-128_pinout.jpg
Note that the pins are not directly connected with the CPU but over a signal-buffer/level-shifter (to adopt the 5V level from the MAC to the 3.3V level of the EPSON and vice versa), seen in this picutre at (5), (6) and (7):
convers_vfl_mcu-area_explained.jpg
Meantime i managed to identify most of the routines using the framebuffer and it is like i thought before, there is a off-screen framebuffer starting at 0x20217700 area used to draw everything in advance and then it will memcopied over to the visual area at 0x20200000. This is mentioned also in the datasheet "Double Buffering/Multi-pages: provides smooth animation and instantaneous screen updates".

I also found the init-sequence of the EPSON in firmware:

Code: Select all

int lcdctrl_init()
{
  int result; // r0

  MEMORY[0x20000000] = 0x2D3B;
  MEMORY[0x20000002] = 0x402D;
  result = 0;
  MEMORY[0x20000004] = 0;
  MEMORY[0x20000006] = 0;
  MEMORY[0x20000008] = 0;
  MEMORY[0x2000000A] = 3;
  MEMORY[0x2000000C] = 7;
  MEMORY[0x2000000E] = 97;
  MEMORY[0x20000010] = 192;
  MEMORY[0x20000012] = 8;
  MEMORY[0x20000014] = 0;
  MEMORY[0x20000016] = 0;
  MEMORY[0x20000018] = 0;
  MEMORY[0x2000001A] = 0;
  MEMORY[0x2000001C] = 252;
  MEMORY[0x2000001E] = -772;
  MEMORY[0x20000020] = 0;
  MEMORY[0x20000022] = 63;
  MEMORY[0x20000024] = 0;
  MEMORY[0x20000026] = 49;
  MEMORY[0x20000028] = 0;
  MEMORY[0x2000002A] = 91;
  MEMORY[0x2000002C] = 36;
  MEMORY[0x2000002E] = 10;
  MEMORY[0x20000030] = 0;
  MEMORY[0x20000032] = 262;
  MEMORY[0x20000034] = 0;
  MEMORY[0x20000036] = 239;
  MEMORY[0x20000038] = 0;
  MEMORY[0x2000003A] = 16;
  MEMORY[0x2000003C] = 0;
  MEMORY[0x2000003E] = 0;
  MEMORY[0x20000040] = 0;
  MEMORY[0x20000042] = 0;
  MEMORY[0x20000044] = 0;
  MEMORY[0x20000046] = 100;
  MEMORY[0x20000048] = 0;
  MEMORY[0x2000004A] = 0;
  MEMORY[0x2000004C] = 0;
  MEMORY[0x2000004E] = 0;
  MEMORY[0x20000050] = 0;
  MEMORY[0x20000052] = 0;
  MEMORY[0x20000054] = 0;
  MEMORY[0x20000056] = 0;
  MEMORY[0x20000058] = 0;
  MEMORY[0x2000005A] = 0;
  MEMORY[0x2000005C] = 0;
  MEMORY[0x2000005E] = 0;
  MEMORY[0x20000060] = 0;
  MEMORY[0x20000062] = 0;
  MEMORY[0x20000064] = 1;
  MEMORY[0x20000066] = 0;
  MEMORY[0x20000068] = 0;
  MEMORY[0x2000006A] = 0;
  MEMORY[0x2000006C] = 0;
  MEMORY[0x2000006E] = 0;
  MEMORY[0x2000007C] = 0;
  MEMORY[0x2000007E] = 300;
  MEMORY[0x20000080] = 0;
  MEMORY[0x20000082] = 50;
  MEMORY[0x20000084] = 0;
  MEMORY[0x20000086] = 100;
  MEMORY[0x20000088] = 0;
  MEMORY[0x2000008A] = 10;
  MEMORY[0x2000008C] = 0;
  MEMORY[0x2000008E] = 100;
  MEMORY[0x20000090] = 0;
  MEMORY[0x20000092] = 10;
  MEMORY[0x20000094] = 0;
  MEMORY[0x20000096] = 7;
  MEMORY[0x20000098] = 0;
  MEMORY[0x2000009A] = 0;
  MEMORY[0x2000009C] = (unsigned int)&unk_918;
  MEMORY[0x2000009E] = 3593;
  MEMORY[0x200000A0] = 0;
  MEMORY[0x200000A2] = 0;
  MEMORY[0x200000A4] = 0;
  MEMORY[0x200000A6] = 0;
  MEMORY[0x200000A8] = 0;
  MEMORY[0x200000AA] = 0;
  MEMORY[0x200000AC] = 0;
  MEMORY[0x200000AE] = 0;
  MEMORY[0x200000B0] = 0;
  MEMORY[0x200000B2] = 0;
  MEMORY[0x200000B4] = 0;
  MEMORY[0x200000B6] = 0;
  MEMORY[0x200000B8] = 0;
  MEMORY[0x200000BA] = 0;
  MEMORY[0x200000BC] = 0;
  MEMORY[0x200000BE] = 0;
  MEMORY[0x200000C0] = 0;
  MEMORY[0x200000C2] = 0;
  return result;
}
So we now know the this area is at 0x2000 0000 - 0x2000 00C4. I took a memory snapshot of this area using J-Link Mem:

Code: Select all

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  2D 3B 40 2D 00 00 00 00 00 00 00 03 00 07 00 61  -;@-...........a
00000010  00 40 00 08 00 00 00 00 00 00 00 00 00 FC FC FC  .@...........üüü
00000020  00 00 00 3F 00 00 00 31 00 00 00 5B 00 24 00 0A  ...?...1...[.$..
00000030  00 00 01 06 00 00 00 EF 00 00 00 10 00 00 00 00  .......ï........
00000040  00 00 00 00 00 00 00 64 00 00 00 00 00 00 00 00  .......d........
00000050  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000060  00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00  ................
00000070  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000080  00 00 00 32 00 00 00 64 00 00 00 0A 00 00 00 00  ...2...d........
00000090  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000100  2D 3B 40 2D 00 00 00 00 00 00 00 03 00 07 00 61  -;@-...........a
00000110  00 40 00 08 00 00 00 00 00 00 00 00 00 FC FC FC  .@...........üüü
00000120  00 00 00 3F 00 00 00 31 00 00 00 5B 00 24 00 0A  ...?...1...[.$..
00000130  00 00 01 06 00 00 00 EF 00 00 00 10 00 00 00 00  .......ï........
00000140  00 00 00 00 00 00 00 64 00 00 00 00 00 00 00 00  .......d........
00000150  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000160  00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00  ................
00000170  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000180  00 00 00 32 00 00 00 64 00 00 00 0A 00 00 00 00  ...2...d........
00000190  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000001A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000001B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000001C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000001D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
You can see the it seems to be mirroried every 0x100, so only 8 address-bits are used for the registers.
epson_s1d13a05f00a1_register_overview.jpg
Bits 16-22 of the first 32-bit register at 0x2000 0000 reflects the CNF-STATUS signal pins of the chip: 0x2D3B402D = 0b001011 01 0 0111011 01000000 001011 01
That means: 01 1 1011 = Generic #1, Big Endian, WAIT# is active low, CLKI to BCLK divide ratio is 1:1

And this lead to the MPU-Connection type:
epson_s1d13a05f00a1_generic1_bigendian_interface.png

Re: How the EPSON S2D13A05 is connected and controlled by MAC7116 in preFL Convers+

Posted: 02 Jan 2020, 14:40
by DGAlexandru
I had some spare time :P so I could search for the connections between EPSON and LCD, for PreFaceLift Convers+:
EPSON_2_LCD.jpg
Also, we have the following configuration for EPSON:
CNF2 and CNF6 pins are connected to GND (VSS)
CNF0, 1, 3, 4 and CNF5 are connected to IOVDD
=> it is configured as "Generic #1, Big Endian", WAIT# is active low and CLKI to BCLK divide ratio 1:1
Which is exactly how you discovered from the FW :D

Couldn't find where GPIO0 is connected, but found the chip that enables power for the TFT part of LCD.


You should remove the PDF files:
s2d13513_hwspec.pdf
s2d13513_product_brief.pdf
s1d13700_epson_embedded_lcd-controller.pdf
as they are not needed any more and add the PDF files from this thread

Re: How the EPSON S2D13A05 is connected and controlled by MAC7116 in preFL Convers+

Posted: 02 Jan 2020, 15:08
by Go4IT
Overlaying the picture with the pinout was a really nice idea :-)
We should also do this "pathfinding" for the MCU<–>EPSON interface.

Re: How the EPSON S2D13A05 is connected and controlled by MAC7116 in preFL Convers+

Posted: 02 Jan 2020, 15:34
by Go4IT
Interesting register is 0x2000 0018 (LUT). It is used to write the color lookuptable to the EPSON. Datasheet says: "S1D13A05 has three 256-position, 6-bit wide LUTs, one for each of red, green, and blue".

I found two subs writing a LUT, one with a fixed LUT-Pointer:

Code: Select all

void lcd_write_lut2()
{
  unsigned int v0; // r0
  int v1; // r1

  v0 = 0;
  do
  {
    v1 = dword_62EC4[v0];
    MEMORY[0x20000018] = ((_WORD)v0 << 8) | (unsigned __int8)dword_62EC4[v0];
    MEMORY[0x2000001A] = ((v1 & 0xFF0000u) >> 16) | v1 & 0xFF00;
    v0 = (v0 + 1) & 0xFFFF;
  }
  while ( v0 <= 0xFF );
  byte_40004BDD = 2;
  JUMPOUT(&loc_27B6A);
}
and another one with a variable pointer, taken from a RAM global variable:

Code: Select all

char *lcd_write_lut()
{
  unsigned int v0; // r0
  int v1; // r1
  char *result; // r0

  v0 = 0;
  do
  {
    v1 = dword_40001AF8[v0];
    MEMORY[0x20000018] = ((_WORD)v0 << 8) | (unsigned __int8)dword_40001AF8[v0];
    MEMORY[0x2000001A] = ((v1 & 0xFF0000u) >> 16) | v1 & 0xFF00;
    v0 = (v0 + 1) & 0xFFFF;
  }
  while ( v0 <= 0xFF );
  result = &byte_40004BDC;
  byte_40004BDE = 2;
  return result;
}