ATC_MiThermometer icon indicating copy to clipboard operation
ATC_MiThermometer copied to clipboard

Allow dumping original firmware via ATCtelink.py

Open znanev opened this issue 4 years ago • 75 comments

Hi @atc1441,

First I'd like to thank you for the impressive work that you've done reverse engineering the flashing protocol and giving us mortals the possibility to flash custom firmware via OTA :)

I own some of the other Mi BLE sensors - LYWSD02, CGG1 and MHO-C401. Inspired by your work, yesterday I opened the latest sensor in my collection - MHO-C401 (greyish square body with e-ink display) , and I just confirmed my suspicions that its built around TLSR8251 too:

IMG_20200907_173110

So, I'd like to start experimenting with it, but not having the hardware flashing tool, I'd have to rely on USB to UART flashing and OTA. But first I'd like to be able to dump its original firmware, so that I have a predictable starting point should anything breaks.

Is it possible to make the ATCtelink.py script dump the firmware of the attached device into a file?

znanev avatar Sep 08 '20 07:09 znanev

Good to see there is another one with the TLSR8251 the Mosquito repellent has an TLSR8261 so its a bit different.

The .py script is unfortunately only one way so only data can be pushed from the PC to the MCU but not in the other direction.

However it is possible to use this https://github.com/pvvx/TlsrTools or this tool https://github.com/pvvx/TlsrComProg to dump the flash of an TLSR8266 that one does not have the same SWS protocol so one aditional byte needs to be send like in my script.

Ordered one of the MHO-C401 to get into it when its here but it takes a while

It should also be possible to intercept the web requests when its asking for a new firmware and get the flash that way. can you please send me what data is in the BLE characteristics maybe its possible to emulate the MHO-C401 and i can get the update file for you

atc1441 avatar Sep 08 '20 07:09 atc1441

Thanks for this info, will look into the links that you provided!

Following are screenshots of all characteristics and their values of MHO-C401 sensor:

image image image

I couldn't find a way to get this information as plain text, hope the screenshots are fine?

znanev avatar Sep 08 '20 07:09 znanev

Thank you that does help, can you maybe as well send me one of the Advertising data packets?

The app does recognize the Model that way.

But as your firmware is 1.0.0 its very unlikely that there is one on Xiaomi servers :-( when i receive mine will definitely dump the firmware

atc1441 avatar Sep 08 '20 09:09 atc1441

Yeah, being a new device, that was exactly my thought - that there won't be a new firmware on Xiaomi's servers.

Anyway, here is a raw dump of two advertisements (some 15-20 minutes apart):

0x0201060F1695FE305887038937445338C1A40809094D484F2D43343031
0x0201060F1695FE305887039337445338C1A40809094D484F2D43343031

In fact this new device is quite similar (regarding BLE) to LYWSD03MMC - I added support for MHO-C401 to mitemp_bt custom component for Home Assistant a couple of weeks back, you can see details about the device ID and capabilities here.

znanev avatar Sep 08 '20 09:09 znanev

Thank you, with the help of that i was able to Emulate that thermometer and get the right Model name ZenMeasure

Model is: miaomiaoce.sensor_ht.h1

but unfortunately there is no update file available as i already guessed :-/ so waiting for the hardware is needed :D

atc1441 avatar Sep 08 '20 12:09 atc1441

Thanks for trying that out, though!

I'll wait for the firmware dump before trying to upload anything to my device. But my curiosity gets bigger with the hour, so I might ping you again when I start playing with TlsrTools :)

znanev avatar Sep 08 '20 12:09 znanev

Oh great. Do you own one ? @vevsvevs

atc1441 avatar Sep 08 '20 18:09 atc1441

Looks like the server only gives back update files if you fully added one to your account

atc1441 avatar Sep 08 '20 18:09 atc1441

Flashed that file to one of the LYWSD03MMC and it does fully work except the LCD of course. so temperature and humidity is showing in the mi home app, and activation worked as expected. So that means the I2C pins are on the same as the LYWSD03MMC.

@znanev can you maybe make some more picture including the back to trace some routes a bit more

Thank you @vevsvevs that way its already possible to reverse it a bit

atc1441 avatar Sep 08 '20 18:09 atc1441

Activation and flashing did directly worked with the Web Flasher, so in theory its no problem to flash a custom firmware, if one exists.

will do a logic analyzer run to get infos about the display controlling

it still not showing an update file even with the fully registered device, wondering where the file comes from :)

atc1441 avatar Sep 08 '20 19:09 atc1441

@znanev here you are. b0e28c6e5932bba59fb19290e626b138_upd_miaomiaoce.sensor_ht.h1.bin.zip

Wow, thanks a ton, @vevsvevs !

@atc1441 Here's the back of the PCB:

IMG_20200907_173427

I might try to flash it tomorrow with the firmware that @vevsvevs provided. I have another MHO-C401 ordered, so could sacrifice one for... research purposes ;)

znanev avatar Sep 08 '20 19:09 znanev

Just chiming back in to report, that I could't wait till tomorrow.. so I went ahead and flashed the custom firmware (ATC_Thermometer.bin). As expected, everything BLE-wise was working fine - I was able to read all characteristics, change values etc. The only thing not working was the display, as expected. It might be possible that the e-ink display uses SPI, or some other protocol, or just has another address if it uses I2C. I'll probably have to hold checking this out till the weekend.

Flashing back the stock firmware (thanks again, @vevsvevs !) brought the display back to life... so, I'm more than happy.

Thanks again for the wonderful work, I'll definitely dive into this deeper :)

Edit: just to confirm another observation (I saw it mentioned somewhere in this repo) - the custom firmware indeed reports the relative humidity 5% lower than the stock firmware. Is this calibration constant "hard", set at 5%, or is it somehow dependent on something else? Just curious ...

znanev avatar Sep 08 '20 21:09 znanev

Great to hear that.

The E-Ink display will be connected via spi plus busy, bs, reset and dc line. Most likely

The sensor data read in the custom firmware is simply what is comming from the sensor, so something is done by it on the stock firmware as its 5% different. I added the offset setting in the custom firmware if someone wants to make it these 5% off again.

atc1441 avatar Sep 09 '20 05:09 atc1441

Was able to find a software SPI function in the Firmware, and the pins also fit with the Chip pinout, so PB7 = SPI Mosi PD7 = SPI Clk

soft_spi

Also some init e-ink function is there, so most likely we will see these values again:

The first parameter of SPI pre seems to be for switching between data and command mode, but it does it via a pre clock pulse, dont know if that is correct

initEink

atc1441 avatar Sep 09 '20 06:09 atc1441

Whoa, impressive detective work, @atc1441 !

How did you get those display functions from the dump (i.e. what is the disassembler used) ? They look too pretty, with nice symbol names :)

znanev avatar Sep 09 '20 07:09 znanev

That is with Ghidra, but renamed the variables/functions of course, its without any debug names on stock. But looking at what registers it access it possible to get the functions reversed, also by comparing self compiled code its more easy to reverse. Using this modul https://github.com/rgov/Ghidra_TELink_TC32

atc1441 avatar Sep 09 '20 07:09 atc1441

@atc1441 You are waaay ahead of me! Tried the Telink-TC32 module for Ghidra, but didn't get any meaningful output, so I'm opting out from reverse engineering the original firmware :)

I hope I'll find some time during the weekend to hook some probes to the e-ink display to see what can I get. Sniffing the SPI bus with BusPirate is on my tasks list too :)

znanev avatar Sep 10 '20 13:09 znanev

Took a feew days to get into the TC32 and Ghidra

Good luck with sniffing the data :) waiting for any infos

atc1441 avatar Sep 10 '20 13:09 atc1441

Following some poking with the logic analyser during the weekend, here are the conclusions about the display in MHO-C401:

  1. The display is the same as the one used in the "dumber" version of this device - MHO-C201 (it just shows the temperature and humidity and doesn't have any radio built in). By display I mean the segmented EPD itself, without the driving IC.

  2. The EPD driver ICs in MHO-C401 and MHO-C201 are however different - so are the pin assignments on the 10-pin flat flex connectors:

MHO-C201

Pin # Function
1 VDL
2 VDH
3 GND
4 Vin
5 SHD_N
6 RST_N
7 SDA
8 SCL
9 CSB
10 BUSY_N

MHO-C401

Pin # Function Connected to
1 VDL C3 to GND
2 VDH C2 to GND
3 GND Ground
4 Vin +3V
5 SDA SPI_DO
6 CSB SPI_CK
7 SCL SPI_CS
8 ? PC4
9 ? PA6
10 BUSY_N PA5
  1. The protocol used to communicate with the EPD is 3-wire SPI (SPI enable - CSB, data - SDA and clock - SCL). Commands and data are denoted not by a dedicated wire (D/C as in other EPDs), but instead as first bit in the 9 bits sequence. Value of 0 denotes that following 8 bits are command byte. Value of 1 - following 8 bits are data byte. So SPI settings are as follows: Mode 0, 9-bits, MSB first. So this confirms @atc1441's suspicion above and matches the disassembly of function void init_E-Ink.

  2. The SPI commands and LUT data are quite different from those used in MHO-C201. I have 3 good update captures so far and intend to do much more, especially start up and full refresh.

  3. Found some really nice reverse-engineering resources for MHO-C201:

    Reverse Engineering a MHO-C201 Mostly c++ code examples

    Those gave me a good starting point and inspiration to reverse-engineer the MHO-C401 display protocol. So all credits about MHO-C201 go to those two resources above.

  4. I'll upload the SPI captures later. From the 3 updates I can clearly see a pattern of LUT tables load and data load, so knowing the exact commands meaning won't be necessary as long as it is clear how the segments are mapped in the data bytes. By the way those captures match exactly the code of init_E-Ink above. Most of the commands are the same in different EPD driver ICs implementations (Power on/off sequences, some LUT loads etc.), some are quite unique to MHO-C401's driver IC (0x18 seems to be the data load command) etc.

Hope my observations so far will be a good starting point in developing an EPD driver for MHO-C401 :)

Edited to add: Link to the TLSR8251 datasheet - the IC used in MHO-C401 is the 24-pin variant:

http://wiki.telink-semi.cn/doc/ds/DS_TLSR8251-E_Datasheet%20for%20Telink%20BLE+IEEE802.15.4%20Multi-Standard%20Wireless%20SoC%20TLSR8251.pdf

znanev avatar Sep 14 '20 09:09 znanev

These are some very nice infos. cool.

I didn't even knew the C201 does not have Bluetooth, good i didn't bought one

Still waiting for mine

EDIT:

As the 9th bit is indeed for D/C here is also the spi_send_pre function from the stock firmware.

spi_send_pre

atc1441 avatar Sep 14 '20 09:09 atc1441

Nice disassembly of send_spi_pre !

Here I'm uploading the 3 partial display updates captures. Excel came quite handy for the initial analysis - at lest it's easy to see with a quick glance what changes and what not :)

MHO-C401-SPI-PartialUpdates-Captures.xlsx

Looking at the init_E-Ink function again, the captures confirm what is sent over SPI! I'll try capturing full display update and start up sequences later.

znanev avatar Sep 14 '20 10:09 znanev

Just found more info on the extra bit for D/C

It looks like the BS pin on that Display is pulled high so the SPI is in 3-wire SPI mode.

that means the 9th bit is just simply DC but in the SPI data.

see here at page 30 https://www.waveshare.com/w/upload/6/6a/4.2inch-e-paper-specification.pdf so it seems to be still just normal EPD in general

The info about that is also very usefull for a different project right now so i am quite happy

atc1441 avatar Sep 14 '20 11:09 atc1441

Indeed this is the case, I confirmed it with the logic analyser, it's also visible in the Excel spreadsheet above - SPI is 9-bit ;)

I couldn't identify the manufacturer of the display or its particular driver IC however. Traversing the datasheets of different IC manufacturers, I was able to confirm that most of the "backbone" commands are the same - like 0x00, 0x02, 0x04 etc.). Also I suspect that commands 0x20, 0x23, 0x24, 0x25 and 0x26 just load static tables for the waveforms. It will be command 0x18 that will need more attention in order to decipher the segments mapping:

image

(picture is not mine - it comes from this repo.

znanev avatar Sep 14 '20 11:09 znanev

Ah yes sorry you did wrote it exactly that way, sorry for misunderstanding, just saw it because of the other project and that reminded me of the 9th bit here.

Reversing a 4.2" E-Paper Pricetag display a bit more right now

atc1441 avatar Sep 14 '20 11:09 atc1441

Ah, no probs, it was just a heads up so you don't do the same again and lose time in the process ;)

znanev avatar Sep 14 '20 12:09 znanev

@znanev replying here since your original comment mentioned other sensors. There is also the LYWSDCGQ, do you know if it contains the the TLSR8251? I did some searching and fcc id lookups but havent been able to find out.

There is a google sheet that maps the 4 sensors created by youtube user Chao-chao https://docs.google.com/spreadsheets/d/10qnYSn58TGHo94be__34PY7KUozqwq5Pr8S1KMtKvWY/edit#gid=934182368 I think it needs updated based on the work you guys are doing!

This has been great to follow!

apaperclip avatar Sep 18 '20 19:09 apaperclip

As far i know that one uses an nRF51 SOC. So in generall its possible to write a custom firmware but very different from this here

atc1441 avatar Sep 18 '20 19:09 atc1441

@apaperclip I personally don't own LYWSDCGQ, but have its "successor" - CGG1 (round body with e-ink display). Haven't opened it yet, but its turn will come soon, for sure!

Meanwhile I have good news about MHO-C401's display - I was able to capture all necessary communication from the MCU and have setup a quick proof of concept project using Wemos Mini (ESP8266 based board). I managed to map all the segments, so will publish my finding soon. Stay tuned!

znanev avatar Sep 18 '20 20:09 znanev

Thank you atc1441, i dont think it would even need a custom fw based on how well it seems to work and lack of encryption but wanted to check.

Great news znanev, I'm going to order something just trying to see what I should get. Things like lack of battery on screen or via ble seems like obvious gaps but then again, if it stops working - just replace the battery. I love the eink screen of the CGG1 but the reporting times are less than ideal based on that google doc.

apaperclip avatar Sep 18 '20 20:09 apaperclip