Михаил Юдин

Прошивка тачскрина ft5316

Прошивка тачскрина ft5316

Началось всё с того, что мой смартфон ZOPO zp980+ как и у многих его владельцев фантомил при зарядке или перегреве. Фантомы это такие произвольные нажатия на экране, когда сам ничего не делаешь, а на смартфоне что-то делается. Это очень мешает пользоваться устройством. Поэтому полазив на форуме 4PDA решил сменить прошивку в чипе тачскрина FocalTech ft5316.

Несмотря на предостережение красным шрифтом, всё же рискнул. Прошил, перезапустил смартфон и вуаля. Что могло случиться, гарантированно случилось. Фантомы исчезли, а вместе с этим и тачскрин совсем перестал работать.

Просьба о помощи или источник вдохновения

Нужно было восстанавливать, т.к. цена тачскрина была непозволительно большой: половина стоимости телефона.

Начал пробовать прошить разными приложениями под Android, но ничего не выходило, хоть порой и писалось, что всё ок. Но это разработчик просто не учёл, что могло и не прошиться.

Стоило искать другой путь. Отчаивался, пытался купить у людей, чей смартфон был в нерабочем состоянии, а тачскрин с экраном цел. Но безуспешно.

Обратился за помощью к уважаемому Timmnum, пользователю форума 4PDA:

Приветствую! Хотел узнать у Вас, что можно сделать с тачем, у меня ft5316… Прошил чужим бинарником, в итоге определяется как 0x0, после прошивки бинарника, который до этого шился - отображает 0x7 в обоих полях. Тест поинт (контакты 28/30) замыкал на землю как в момент перевтыкания шлейфа, так и в момент прошивки с воткнутым шлейфом. Результата не достиг. Нашел бинарник под этот чип, тоже не ставится ни в какую. Само устройство zp980+, видел на china-iphone под другой 980 модифицированное ядро, цианогенмод11, в котором шьется, но объединить сие для 980+ не могу, спецификация другая. Прошу направить меня на путь истинный=) — fagci

Я бы с радостью…) Но заполучить убитый 5316 мне не удавалось. Есть вариант прошивки через COM - UART. Но тут нужен дамп с рабочего… — Timmnum

А тот бинарник, который ранее шил, работал, его не удастся поставить через COM?..хотя затруднительно будет подпаяться к ногам.. Спасибо большое за разъяснения, попробую тоже провтыкать=).. — fagci

Был ещё вариант - собрать из исходников CyanogenMod для zp980+, но нужно сначала найти всё нужное, местами подправить, компилить…Компилилось без остановки на ноуте дня два. В итоге не завелось и забил.

Далее была переписка с ув. Timmnum, оставил только ключевые моменты и вырезал сообщения Timmnum во избежание жалоб, мало ли =)

А для нас пока и ЦМ нет… В общем, ковырять-неперековырять=)) — fagci

В преобразователях, которые заказал, стоит чип cp2102, у него есть только DSR\RTS DTR\CTS… Я себе заказал Arduino, на нем есть MISO\MOSI и SDA\SCL, как я понял, SDA это аналоговый выход. Поэтому сдается мне, что лучше приспособить arduino для общения с контроллером. Видел, как с помощью него можно прошить другой arduino=) — fagci

Тут недавно пришли нужные детали для коннекта к шлейфу, попробовал запитать контроллер прямо от 3.3в от переходника, чип на нем греется, померил в телефоне какое питание подходит - там 2.8в вообще..теперь непонятно, как быть с этим, может питание вообще взять как-то с тела.. А в даташите написано что operating voltage 2.8-3.6 =) Запитал от пришедшего с breadboard адаптера питания с “кренкой”, на контроллере около 2.8в — fagci

Читаются только нули пока… То есть получается, ответа с контроллера нет… — fagci

С питанием вообще понять не могу=)… До этого подключал неверно, полярность попутал… Пины шлейфа правильно промаркировал, поэтому в расположении VDDA уверен=) Подключаю с верной полярностью, напряжение проседает до 1.3в, контроллер греется при этом Самое странное, что при том же питании с телефона контроллер то не греется=) — fagci

Тут уже было отчаялся совсем, но появилась надежда:

Я ваще наоборот припаял разъем поэтому пины 1..8 = 8..1 =)) — fagci

Теперь пока Device not respond. Соединил dtr, cts напрямую к sda Уже и через arduino при помощи такой штуки http://playground.arduino.cc/Code/I2CEEPROM читаю, данных нет, одни FF — fagci

Когда замыкал reset на землю, нули не читались, значит контроллер еще жив=)) — fagci

Походу что-то не так делаю, ACK же получаю..не сгорел же=( — fagci

Снова руки опускались, но я не сдавался!

На данный момент имею ардуинку в режиме мастера, которая общается через I2C с контроллером. Только вчера заюзал кастом драйвер от Paolo (для ft5316 под CM для zp980), модифицировал под arduino и не представляешь, уже читаются НЕ нули=)..и даже не то что отправлял, значит кушает=) Осталось дело за кропотливым..переписать индусокод более тщательно, чтобы ничего не забыть, подцепить SD карточку и можно уже будет передавать прошивку. Останется только решить проблему с памятью под прошивку, придется читать побайтово, или маленькими пачечками, а то у ардуинки не хватит места для всей=) — fagci

Питание подаю на ардуинку 3.3в, хотя надо 5..интерфейсы оказались согласованными=) ACK до этого принимал, значит был контакт уже=) Уже думал, что спалил тач, а оказалось, что еще надо ввести в нужный режим девайс и не обязательно использовать WAKE. Кстати, у этого контроллера INT на том же пине, что и WAKE=) — fagci

Кстати, самое странное, что WAKE не теребил вовсе. только ресет и потом чуть иначе команды шлются=) — fagci

Что получилось в итоге

#include <Wire.h>
#include <SD.h>

#define VCC_PIN 3
#define RST_PIN 2
#define DEV_ADDR 0x38
#define FTS_PACKET_LENGTH 2

File myFile;

void initSD(){

  Serial.print("Initializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
  // or the SD library functions will not work. 
   pinMode(10, OUTPUT);
   
  if (!SD.begin(4)) {Serial.println("initialization failed!");return;}
  Serial.println("initialization done.");

  myFile = SD.open("fw.bin");
  if (myFile) {
  	fts_ctpm_fw_upgrade();
    // read from the file until there's nothing else in it:
    myFile.close();
  } else {
  	// if the file didn't open, print an error:
    Serial.println("error opening");
  }


}

void setup(){
	Wire.begin();
  	Serial.begin(9600);
  	init_device();
  	initSD();
  	
}

void loop(){}

void init_device() {
  pinMode(VCC_PIN, OUTPUT);
  pinMode(RST_PIN, OUTPUT);
  digitalWrite(RST_PIN, HIGH);
  digitalWrite(VCC_PIN, HIGH);
}

int cmd_write(byte *a, int n){
        Wire.beginTransmission(DEV_ADDR);
        Wire.write(a,n);
        assert(Wire.endTransmission(DEV_ADDR));
}
 
int byte_read(byte* pbt_buf, int bt_len){
        int r=0;
        byte d=0xFF;
        Wire.requestFrom(DEV_ADDR, bt_len);
        while(Wire.available()){
                d=Wire.read();
                pbt_buf[r]=d;
                Serial.print(d,HEX);
                r++;
        }
}

byte i2c_smbus_read_i2c_block_data(byte command, int length, byte *values)
{
	byte r=0, d=0xFF;
  Wire.beginTransmission(DEV_ADDR);
  Wire.write(command);
  assert(Wire.endTransmission(DEV_ADDR));
  Wire.requestFrom(DEV_ADDR, length);
  while (Wire.available()) {
  	d=Wire.read();
  	values[r]=d;
    Serial.print(d, HEX);
    r++;
  }
}
 
void assert(int e){ if(e){ Serial.print("[E");Serial.print(e);Serial.print("]"); } }

/*
while (myFile.available() && i++<10) {
    	Serial.print(myFile.read(),HEX);Serial.println(" ");
    }
    // close the file:
    
*/

boolean  fts_ctpm_fw_upgrade(/*byte* pbt_buf, unsigned int dw_lenth*/){
	unsigned int dw_lenth = myFile.size();
    byte reg_val[2] = {0};
    byte tmpData[4] = {0,0,0,0};
    unsigned int i = 0;
 
    unsigned int  packet_number;
    unsigned int  j;
    unsigned int  temp;
    unsigned int  lenght;
    byte  packet_buf[FTS_PACKET_LENGTH + 6];
    byte  auc_i2c_write_buf[10];
    byte bt_ecc;
    int i_ret;
        int ret;
        unsigned char ver;
 
    /*********Step 1:Reset  CTPM *****/
        pinMode(RST_PIN, OUTPUT);
    digitalWrite(RST_PIN, LOW);  
    delay(10);  
    pinMode(RST_PIN, OUTPUT);
    digitalWrite(RST_PIN, HIGH);
    Serial.println("[TSP] Step 1: Reset CTPM test");
   
    delay(50);  
    /*********Step 2:Enter upgrade mode *****/
    auc_i2c_write_buf[0] = 0x55;
    auc_i2c_write_buf[1] = 0xaa;
    do{
        i ++;
        i_ret = cmd_write(auc_i2c_write_buf, 2);
        delay(5);
    }while(i_ret <= 0 && i < 5 );
    Serial.println("[TSP] Step 2: Enter upgrade mode");
 
    /*********Step 3:check READ-ID***********************/
    tmpData[0]=0x90;
    cmd_write(tmpData,4);
        i=0;
        i_ret=0;
    do{
        i ++;
        i_ret = byte_read(reg_val,2);
        delay(10);
    }while(i_ret <= 0 && i < 5 );
    Serial.print("[TSP] Step 3: check ID: ");
    Serial.print(reg_val[0],HEX);
    Serial.print(", ");
    Serial.print(reg_val[1],HEX);
        Serial.println(" ");
 
    /*********Step 4:erase app*******************************/
    tmpData[0]=0x61;
    ret = cmd_write(tmpData,1);
   
    delay(1500);
    Serial.print("[TSP] Step 4: erase.ret=");
        Serial.print(ret);
        Serial.println(" ");
 
    /*********Step 5:write firmware(FW) to ctpm flash*********/
    bt_ecc = 0;
        Serial.println("[TSP] Step 5: start upgrade.");
    dw_lenth = dw_lenth - 8;
    packet_number = (dw_lenth) / FTS_PACKET_LENGTH;
    packet_buf[0] = 0xbf;
    packet_buf[1] = 0x00;
    for (j=0;j<packet_number;j++){
        temp = j * FTS_PACKET_LENGTH;
        packet_buf[2] = (byte)(temp>>8);
        packet_buf[3] = (byte)temp;
        lenght = FTS_PACKET_LENGTH;
        packet_buf[4] = (byte)(lenght>>8);
        packet_buf[5] = (byte)lenght;
 
        for (i=0;i<FTS_PACKET_LENGTH;i++){
        	myFile.seek(j*FTS_PACKET_LENGTH + i);
            packet_buf[6+i] = myFile.read();
            bt_ecc ^= packet_buf[6+i];
        }
       
        ret=cmd_write( &packet_buf[0],FTS_PACKET_LENGTH + 6);
        if ((j * FTS_PACKET_LENGTH % 1024) == 0){
              Serial.print("[TSP] upgrade the 0x");
              Serial.print(((unsigned int)j) * FTS_PACKET_LENGTH);
              Serial.println(" th byte.");
        }
    }
 
    if ((dw_lenth) % FTS_PACKET_LENGTH > 0){
        temp = packet_number * FTS_PACKET_LENGTH;
        packet_buf[2] = (byte)(temp>>8);
        packet_buf[3] = (byte)temp;
 
        temp = (dw_lenth) % FTS_PACKET_LENGTH;
        packet_buf[4] = (byte)(temp>>8);
        packet_buf[5] = (byte)temp;
 
        for (i=0;i<temp;i++){
        	myFile.seek(packet_number*FTS_PACKET_LENGTH + i);
            packet_buf[6+i] = myFile.read();
            bt_ecc ^= packet_buf[6+i];
        }
             // printk("[TSP]temp 0x%x \n", temp);
        ret = cmd_write( &packet_buf[0],temp+6);    
              //printk("[TSP] 222 ret 0x%x \n", ret);
        delay(20);
    }
 
    //send the last six byte
    for (i = 0; i<6; i++){
        temp = 0x6ffa + i;
        packet_buf[2] = (byte)(temp>>8);
        packet_buf[3] = (byte)temp;
        temp =1;
        packet_buf[4] = (byte)(temp>>8);
        packet_buf[5] = (byte)temp;
        myFile.seek(dw_lenth + i);
        packet_buf[6] = myFile.read();

        bt_ecc ^= packet_buf[6];
 
        cmd_write(&packet_buf[0],7);  
        delay(20);
    }
 
    /*********Step 6: read out checksum***********************/
 
    i2c_smbus_read_i2c_block_data(0xcc, 1, &(reg_val[0]));
    Serial.print("[TSP] Step 6:  ecc read 0x");
    Serial.print(reg_val[0]);
    Serial.print(", new firmware 0x");
    Serial.print(bt_ecc);
    Serial.println(".");
    if(reg_val[0] != bt_ecc){
        //return ERR_ECC;
    }
 
    /*********Step 7: reset the new FW***********************/
    pinMode(RST_PIN, OUTPUT);
    digitalWrite(RST_PIN, LOW);  
    delay(1);  
    pinMode(RST_PIN, OUTPUT);
    digitalWrite(RST_PIN, HIGH);
 
    return true;
}

Больше так делать не буду. Возможно =)

С этого я получил несколько важных уроков:

  • никогда нельзя опускать руки, особенно когда кажется, что все методы перепробованы;
  • если хоть кто-нибудь говорит на форумах, что бесполезно искать решение — не поддаваться;
  • всё можно сделать самому, важно верить в свои силы, даже когда их нет!

Всем, кому пригодится данный материал, желаю успехов в восстановлении и чтобы ничего не ломалось, а только улучшалось. А если и ломается, то восстанавливалось! Это бесценный опыт.

Ещё почитать

Нет фото

Стоит ли менять термопасту процессора ноутбука на КПТ-8

STM32f103 ADC with DMA

STM32f103 ADC with DMA

STM32 ILI9341 SPI with DMA

STM32 ILI9341 SPI with DMA