Hello, just want to make separate thread to share my findings for this project user interface. Lets start with Touscreen. HTC Desire has 3.7 capacitive touchscreen, and connector look like this:
consoleplug CP26051 for HTC Desire A8181 Touch Screen & Digitizer Original-A2.jpgpinout.png

SCL, SDA, IRQ need pullup (1-10K to 3.3 or 5.0V, stm32f429 is 5V tolerant so i can connect it directly with no external parts). Now, when you configure all registers, you can connect IRQ# to mcu interrupt line ( falling edge mean that it has coordinate for finger and you can start readout )
It use protocol like that:

 

For tp init (at power-up ), it sends 6 packets containing 16b of data like this:

[(80).<FF>,<10>]

[(80).<41>,<04>]

[(80).<44>,<0C>]

[(80).<FF>,<04>]

[(80).<F0>,<81>]

[(80).<F1>,<01>]

 

80 is address, and it writing (8 bit is zero) "[" is i2c start condition, and "]" is stop condition

Now comes the tricky part. Yes, it is data decode.

 

Packet to get data looks like this:

 

[(80,<00>[(81),<XX>,<XX>,<XX>,<XX>,<XX>,<XX>,<XX>,<XX>,<XX>,<XX>,<XX>,<XX>,<40>]
Here is example of screen capture ( again, big thanks for  element14 community for mso2024b, it is my best tool right now )

1382463525_1143_FT158286_tek00001.png

 

ok, now we need to decode data. first we get data to some array, when we done reading, we must apply math to get some data. To do this, i was researching HTC Desire source code ( htc done a good job by publishing all c files for this phone in htcdev website ) and extracted code for init as well as data decode ( to be fare, i get init code by probing phone, and it matched source code init function, what a surprise )

 

int x = buf[3] | (uint16_t)(buf[2] & 0x1f) << 8;

int y = buf[5] | (uint16_t)(buf[4] & 0x1f) << 8;

int z = buf[1];

int w = buf[0] >> 4;

int finger = buf[0] & 7;

and

int x2 = buf[3+6] | (uint16_t)(buf[2+6] & 0x1f) << 8;

int y2 = buf[5+6] | (uint16_t)(buf[4+6] & 0x1f) << 8;

int z2 = buf[1+6];

int w2 = buf[0+6] >> 4;

int finger2 = buf[0+6] & 7;

ok, now we get some data, now scale x and y for screen. simply i have to solve kx+b=c to get k and b constants ( x is real coordinate on screen, and c  is calculated x by applying math with buffer data )

Here is how interrupt code looks like on STM32F429

void EXTI2_IRQHandler(void)

{

  if(EXTI_GetITStatus(EXTI_Line2) != RESET)

  {

   

     char data[16];

     volatile int x0,y0,x1,y1,z0,z1,w0,w1,finger0,finger1;

     int i=0;

 

    I2C_start(sEEE_I2C, 0x80, I2C_Direction_Transmitter);

    delay(500);

    I2C_write(sEEE_I2C,0x00);

    delay(500);

    I2C_start2(sEEE_I2C, 0x80, I2C_Direction_Receiver);

    delay(500);

    while(i<13)

    {

      data[i]=I2C_read_ack(sEEE_I2C);

      i++;

      delay(500);

    }

    I2C_stop(sEEE_I2C);

 

    x0 = data[3] | (uint16_t)((data[2] & 0x1f) << 8);

    y0 = data[5] | (uint16_t)((data[4] & 0x1f) << 8);

    z0 = data[1];

    w0 = data[0] >> 4;

    finger0 = data[0] & 7;

 

    x1 = data[3+6] | (uint16_t)((data[2+6] & 0x1f) << 8);

    y1 = data[5+6] | (uint16_t)((data[4+6] & 0x1f) << 8);

    z1 = data[1+6];

    w1 = data[0+6] >> 4;

    finger1 = data[0+6] & 7;

   

    x0=(int)(x0/8.38);

    y0=(int)(800.0-(y0/8.23));

    if(x0>480)

      x0=480;

    if(y0>800)

      y0=800;

   

    LCD_DrawFullCircle(x0,y0,5); //painting

    if(finger0>1)

    {

      x1=(int)(x1/8.38);

      y1=(int)(800.0-(y1/8.23));

      if(x1>480)

        x1=480;

      if(y1>800)

        y1=800;

      LCD_DrawFullCircle(x1,y1,5);//painting

    }

    else

    {

      x1=y1=0;

    }

    EXTI_ClearITPendingBit(EXTI_Line2);

  }

}

i

 

 

And here is init function:

void TP_Init(void)

{

  volatile char temp = 0,i=0;

  sEEE_Init();

  spi_delay(0xFFFFF);

  I2C_AcknowledgeConfig(sEEE_I2C,ENABLE);

 

  I2C_start(sEEE_I2C, 0x80, I2C_Direction_Transmitter);

  spi_delay(D);

  I2C_write(sEEE_I2C,0xFF);

  spi_delay(D);

  I2C_write(sEEE_I2C,0x10);

  spi_delay(D);

  I2C_stop(sEEE_I2C);

  spi_delay(S);

 

  I2C_start(sEEE_I2C, 0x80, I2C_Direction_Transmitter);

  spi_delay(D);

  I2C_write(sEEE_I2C,0x41);

  spi_delay(D);

  I2C_write(sEEE_I2C,0x04);

  spi_delay(D);

  I2C_stop(sEEE_I2C);

  spi_delay(S);

 

  I2C_start(sEEE_I2C, 0x80, I2C_Direction_Transmitter);

  spi_delay(D);

  I2C_write(sEEE_I2C,0x44);

  spi_delay(D);

  I2C_write(sEEE_I2C,0x0C);

  spi_delay(D);

  I2C_stop(sEEE_I2C);

  spi_delay(S);

 

  I2C_start(sEEE_I2C, 0x80, I2C_Direction_Transmitter);

  spi_delay(D);

  I2C_write(sEEE_I2C,0xFF);

  spi_delay(D);

  I2C_write(sEEE_I2C,0x04);

  spi_delay(D);

  I2C_stop(sEEE_I2C);

  spi_delay(S);

 

  I2C_start(sEEE_I2C, 0x80, I2C_Direction_Transmitter);

  spi_delay(D);

  I2C_write(sEEE_I2C,0xF0);

  spi_delay(D);

  I2C_write(sEEE_I2C,0x81);

  spi_delay(D);

  I2C_stop(sEEE_I2C);

  spi_delay(S);

 

  I2C_start(sEEE_I2C, 0x80, I2C_Direction_Transmitter);

  spi_delay(D);

  I2C_write(sEEE_I2C,0xF1);

  spi_delay(D);

  I2C_write(sEEE_I2C,0x01);

  spi_delay(D);

  I2C_stop(sEEE_I2C);

  spi_delay(S);

  spi_delay(0xFFFF);

 

  I2C_start(sEEE_I2C, 0x80, I2C_Direction_Transmitter);

  spi_delay(D);

  I2C_write(sEEE_I2C,0x00);

  I2C_start2(sEEE_I2C, 0x80, I2C_Direction_Receiver);

  spi_delay(D);

  i=0;

  while(i<13)

  {

    temp=I2C_read_ack(sEEE_I2C);

    i++;

    spi_delay(D);

  }

    spi_delay(D);

  I2C_stop(sEEE_I2C);

}

 

 

( i will add c files to this post so you can download and try)

It looks a bit buggy, but that is painting function is what need more work, not touchscreen itself.  Touchscreen is silky smooth and can track 2 fingers at the same time.

 

Now with amoled is a bit different story, i have to work really hard to make it work. Mostly because it needs some strange power supply sequencing, also datasheet is impossible to find. But i did my research, paid real money but i get not only AMOLED screen datasheet, but controller too.

 

 

I attached datasheet for screen and controller to this blog post. This is code for amoled init

void LCD_WriteComand(uint8_t reg,uint8_t data)

{

    LCD_ChipSelect(DISABLE);

    SPI_I2S_SendData(LCD_SPI, 112);

    while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET);

    delay(10);

    SPI_I2S_SendData(LCD_SPI, reg);

    while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET);

    delay(100);

    LCD_ChipSelect(ENABLE);

    delay(1000);

    LCD_ChipSelect(DISABLE);

    SPI_I2S_SendData(LCD_SPI, 114);

    while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET);

    delay(10);

    SPI_I2S_SendData(LCD_SPI, data);

    while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET);

    delay(100);

    LCD_ChipSelect(ENABLE);

    delay(100);

}

 

void LCD_PowerOn(void)

{

    LCD_WriteComand(0x40 , 0x00 );

    LCD_WriteComand(0x41 , 0x3F );

    LCD_WriteComand(0x42 , 0x2F );

    LCD_WriteComand(0x43 , 0x29 );

    LCD_WriteComand(0x44 , 0x2A );

    LCD_WriteComand(0x45 , 0x23 );

    LCD_WriteComand(0x46 , 0x2F );

    LCD_WriteComand(0x50 , 0x00 );

    LCD_WriteComand(0x51 , 0x00 );

    LCD_WriteComand(0x52 , 0x00 );

    LCD_WriteComand(0x53 , 0x25 );

    LCD_WriteComand(0x54 , 0x28 );

    LCD_WriteComand(0x55 , 0x23 );

    LCD_WriteComand(0x56 , 0x2E );

    LCD_WriteComand(0x60 , 0x00 );

    LCD_WriteComand(0x61 , 0x3F );

    LCD_WriteComand(0x62 , 0x2E );

    LCD_WriteComand(0x63 , 0x28 );

    LCD_WriteComand(0x64 , 0x28 );

 

    delay(0xFFFF);

 

    LCD_WriteComand(0x65 , 0x20 );

    LCD_WriteComand(0x66 , 0x3F );

    LCD_WriteComand(0x39 , 0x44 );

 

    LCD_ChipSelect(DISABLE);

    SPI_I2S_SendData(LCD_SPI, 112);

    while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET);

    delay(10);

    SPI_I2S_SendData(LCD_SPI, 0xEF);

    while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET);

    delay(10);

    LCD_ChipSelect(ENABLE);

    delay(10);

    LCD_ChipSelect(DISABLE);

    SPI_I2S_SendData(LCD_SPI, 114);

    while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET);

    delay(10);

    SPI_I2S_SendData(LCD_SPI, 0xD0);

    while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET);

    delay(10);

    LCD_ChipSelect(ENABLE);

    delay(10);

    LCD_ChipSelect(DISABLE);

    SPI_I2S_SendData(LCD_SPI, 114);

    while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET);

    delay(10);

    SPI_I2S_SendData(LCD_SPI, 0xE8);

    while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET);

    delay(10);

    LCD_ChipSelect(ENABLE);

    delay(10);

 

    LCD_WriteComand(0x31 , 0x08 );

    LCD_WriteComand(0x32 , 0x14 );

    LCD_WriteComand(0x30 , 0x02 );

    LCD_WriteComand(0x27 , 0x01 );

    LCD_WriteComand(0x12 , 0x08 );

    LCD_WriteComand(0x13 , 0x08 );

    LCD_WriteComand(0x15 , 0x00 );

    LCD_WriteComand(0x16 , 0x00 );

    LCD_WriteComand(0x16 , 0x02 );

    LCD_WriteComand(0x39 , 0x56 );

    LCD_WriteComand(0x17 , 0x22 );

    LCD_WriteComand(0x18 , 0x55 );

    LCD_WriteComand(0x19 , 0x05 );

    LCD_WriteComand(0x1A , 0x03 );

    LCD_WriteComand(0x1B , 0x7D );

    LCD_WriteComand(0x1C , 0x0A );

    LCD_WriteComand(0x22 , 0xA2 );

    LCD_WriteComand(0x23 , 0x00 );

    LCD_WriteComand(0x26 , 0xA0 );

    delay(0xFFFF);

 

    LCD_WriteComand(0x1D,0xA0);

 

    delay(0xFFFFF);

 

    LCD_WriteComand(0x14,0x03);

 

    delay(0xFFFFF);

  

}

And after that, all data is fed by RGB565 interface , again code is attached, so you can try it out with your own stm32f429i-disco !

 

 

1383832927_1143_FT158621_imgp2451.jpg

 

I hope to see amoled screens used with micro controllers, they are cheap, and quality is just :O

No pcb can be made without connectors. I was unable to find exact one, but i find similar pair, so all you have to do is remove original and solder one from molex catalog .

501594-1011  // touscreen

501591-1011 // touscreen

 

502426-4010 // AMOLED Screen

502430-4010 // AMOLED Screen

583751.jpg

Soldering tip: apply solder so pad with iron ( pcb must have soldermask, but that was no trouble for home made pcb ), put some high quality flux, put connector on top, and use hot air gun to melt solder on pads, it will drag pins to correct location, and job is done. Don't forget to use microscope to inspect solder-joint

IMAG0854.jpg

 

If you like this project, please vote for it, every vote helps
Vote for Your Favourite Smarter Life Project! << Smart Solder Reflow Oven