Skip to content

Instantly share code, notes, and snippets.

@frazei
Last active May 3, 2023 07:12
Show Gist options
  • Save frazei/9c310637d7b12cc20a53f4407f116991 to your computer and use it in GitHub Desktop.
Save frazei/9c310637d7b12cc20a53f4407f116991 to your computer and use it in GitHub Desktop.
Hacking the P8 Smartwatch

Introduzione

Ho comprato su aliexpress lo smartwatch denominato P8. Si trova di varie "marche" tra cui UTELITE, Colmi, Sitlos e Lige ma alla fine sembrerebbe che sia sempre lo stesso coso. L'unica cosa di cui non sono sicuro è che differenza ci sia tra il modello denominato "SE" e quello senza sigla...

Sullo smartwatch gira un firmware (non bruttissimo a dire il vero) con le funzioni base, lato android si interfaccia con l'applicazione Da Fit fatta dallo sviluppatore "CRREPA". Nel menu info dello smartwatch questi sono i dati che riporta:

P8b
MOY-TON5-1.8.4

Il mio obiettivo è quello di "trasformarlo" in un PineTime con cui, da quel che ho capito, condivide gran parte dell'hardware.

Riguardo questo orologio si direbbe che il massimo esperto sia Aaron Christophel che sul suo canale YouTube ed il suo blog ha diversi video dove mostra come hackerare questo ed altri smartwatch cinesi. Il problema principale è che non ho trovato un vero e proprio how-to ma piuttosto una serie di informazioni frammentarie.

Ho trovato anche il suo canale discord in cui c'è (come sempre in discord) un sacco di casino incomprensibile.

Comunque la prima informazione importante è sapere che la versione "b" del P8 ha delle differenze da quella base. Questo l'ho dedotto da un commento presente in questo video di Aaron. Alla domanda Hello friend, your job is really cool. Is the colmi P8b compatible? lui risponde Yes it is but it has a different movement sensor that is not supported right now in general everything else works.

La seconda informazione è che esistono decine di diverse versioni dell'orologio. Quella che ho io, la versione "MOY-TON5" del firmware richiede una particolare attenzione nella procedura di sostituzione del firmware come è scritto nella pagina github sempre di Aaron perchè dal punto di vista hardware non include il 32kHz crystal oscillator. Per questo serve una versione patchata del nordic bootloader altrimenti lo smartwatch si bricka al primo colpo.

Riguardo le guide come detto non ho trovato una che vinca sulle altre. Ho trovato questa pagina che ha un po' di informazioni utili ma non è particolarmente chiara/aggiornata. La migliore guida alla fine è questa che riguarda eucWatch che è un firmware basato su Espruino per P8. Serve per controllare un monociclo elettrico ma nella sostanza gli step iniziali sono quelli che mi interessano ed ha delle specifiche istruzioni riguardo il "MOY-TON5".

Quindi mi limiterò a prendere un po' di pezzi qua e là...

Elenco dei firmware (forse) compatibili

  • ATCwatchP8 È il firmware fatto da atc1441 che poi è sempre Aaron Christophel. È più che altro una demo!
  • Infinitime-P8 Qui c'è proprio un commento che spiega i vari passaggi per installarlo sul P8.
  • WaspOs Dovrebbe funzionare sul P8
  • Espruino https://github.com/jeffmer/P8Apps

Ottenimento dei files

Pronti via, c'è già un problema. Le app fatte da Aaron per flashare via bluetooth il firmware e per gestire le notifiche non sono più disponibili sul Play Store per problemi con le policy di Google che Aaron sta cercando di risolvere:

Fortunatamente per il momento ho trovato DaFlasher su apkpure.

Dalla pagina di eucWatch c'è un bel mirror con tutti i files necessari ma comunque cercherò di usare quelli "originali" che magari nel frattempo c'è stato un qualche aggiornamento... non si sa mai.

ATCwatchP8

Step 1

Per prima cosa mi serve un bootloader con cui sovrascrivere il firmware stock DaFit. Quello compatibile con il "MOY-TON5" dovrebbe essere p8-bootloader-sdk14-dafit.bin fatto dall'utente fanoush. Tramite l'app DaFlasher ho selezionato il P8b e cliccato su "Select File". Lo smartwatch fa un po' di operazioni di scrittura e poi riparte ma con il display nero (è normale per il TON5).

Step 2

Dall'app cerco di nuovo i dispositivi e ne trovo uno che si chiama dfutarg. Ho cliccato su "Do DFU Update". Ho lasciato selezionate le voci "Use Nordic Bootloader" e "Toggle Bluetooth". A questo punto mi serve il firmware FitBootloaderDFU2.0.1.zip. La prima volta si è bloccato con l'upload a 0% ma dopo aver chiuso l'app e riavviato il bluetooth tutto a funzionato a dovere. Al termine della procedura sullo schermo compare un quadrato rosso con sotto la scritta "ATCnetz.de".

Step 3

A questo punto sempre in DaFlasher ho un dispositivo che si chiama ATCdfu. Decido come prima prova di installare ATCwatchP8 ovvero ATCwatchP8.ino.zip: come ho scritto sopra si tratta praticamente di una demo e poco più. In realtà poi i sensori sul mio non funzionano (né i passi né il battito).

Infinitime-P8

Dopo aver testato per qualche minuto ATCwatch ho provato a fare il salto verso Infinitime seguendo le istruzioni che ho trovato in questo commento. Ho installato via DFU reloader-factory.zip ma sembra che qualcosa non abbia funzionato visto che il display è diventato nero ed il dispositivo non è più disponibile in BLE. Il P8 è ufficialmente brickato...

Recuperare il P8 tramite SWD

A questo punto non mi rimane altro da fare se non passare alle maniere forti:

  • ho aperto il P8 con un cutter come indicato in questo video. Rimuovere la batteria è meno facile del previsto perchè è ben incollata sulla scheda e quindi ci vuole molta pazienza.
  • ho collegato 4 fili ai contatti come riportato in questo video.
  • ho preso un Raspberry Pi 2 su cui ho installato Raspberry Pi OS da zero.
  • ho installato pinetime-updater sul RPi
  • collegare i 4 fili al RPi nel posto giusto è stato un po' un casino perchè sui contatti c'è un scritta in cinese: tenendo la batteria sulla sinistra, i connettori sono GND - 3.3v - SWDCLK - SWDIO. Li ho quindi collegati al RPi alla GPIO con questa associazione: SWDCLK => SPSCLK (fila 12, 23° pin) e SWDIO => SPMOSI (fila 10, 19° pin); GND e 3v ovviamente sui contatti della GPIO contrassegnati con questi valori.
  • per testare che tutto sia collegato correttamente faccio così:
$ cd pinetime-updater
$ ./scripts/flash-unprotect.sh

Se viene scritto Flash is already unprotected vuol dire che è collegato correttamente.

Adesso posso utilizzare il lo script run.sh che mi consentirebbe in teoria di fare tutto ciò che può servire per ripristinare un pinetime brickato ma nel mio caso non funziona! L'unica cosa che funziona è "Program bootloader logo" che mi fa comparire per provare a riprodurre i singoli step:

$ cd ~
$ wget https://github.com/JF002/Pinetime/releases/download/0.7.1/pinetime-graphics.bin
$ cd pinetime-updater
$ openocd-spi/bin/openocd -f scripts/swd-pi.ocd

apro su un'altra shell il telnet e lancio i seguenti comandi:

$ telnet localhost 4444
> init
> targets
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* nrf52.cpu          cortex_m   little nrf52.cpu          running
> reset halt
> program /home/pi/pinetime-graphics.bin verify 0x0
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x0002334c msp: 0x20004a20
** Programming Started **
Adding extra erase range, 0x000228f0 .. 0x00022fff
** Programming Finished **
** Verify Started **
** Verified OK **
> targets
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* nrf52.cpu          cortex_m   little nrf52.cpu          halted
> reset init
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x00000668 msp: 0x20010000
> resume
> targets
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* nrf52.cpu          cortex_m   little nrf52.cpu          running
> shutdown

Fortunatamente mi sono fatto aiutare canale discord e mi hanno fornito due immagini estratte direttamente da uno smartwatch e le ho potute flashare sul mio dispositivo:

> nrf5 mass_erase
> flash write_bank 0 /home/pi/pinetime_full_flash.bin
> flash write_bank 1 /home/pi/pinetime_full_uicr.bin
> flash banks                                            
#0 : nrf52.flash (nrf5) at 0x00000000, size 0x00080000, buswidth 1, chipwidth 1
#1 : nrf52.uicr (nrf5) at 0x10001000, size 0x00001000, buswidth 1, chipwidth 1

A questo punto il P8 si è acceso con il bootloader di atc1441 in DFU. Da Android ho installato ATCwatchP8 (come sopra al punto 3) ed ora sono tornato al punto in cui il P8 funziona.

Per scrupolo mi sono fatto io stesso una immagine per poter tornare comodamente (via SWD) a questa condizione:

> flash read_bank 0 /home/pi/fritto_full_flash.bin 0x0000
> flash read_bank 1 /home/pi/fritto_full_uicr.bin 0x0000

Il file fritto_full_flash.bin è di 512K mentre fritto_full_uicr.bin è di 4K.

WaspOs

Tramite DFU ho installato bootloader-daflasher.zip e dopo il riavvio l'orologio parte in DFU con il logo dell'ape e del bluetooth sullo schermo. Da qui in teoria dovrei installare micropython.zip ma dopo il riavvio l'orologio parte con lo schermo nero.

È il 27 giugno 2021 e mi sono onestamente rotto le palle, rimetto l'orologio nella scatola non si sa mai che mi venga voglia di riprovare a farci qualcosa.

È il 1° maggio 2023 e riprendo in mano la cosa perchè ho trovato questa interessante pagina dove si parla approfonditamente del P8 e come installarci sopra InfiniTime e questo post in cui un utente fornisce il bootloader e l'immagine di WaspOs per il P8b.

Ho ricaricato completamente il mio P8b ed è felicemente ripartito in ATCwatchP8. Per sicurezza ho ricollegato l'orologio tramite SWD per controllare che tutto andasse bene e mi sono accorto che nei miei appunti avevo invertito due cavi.. poco male ho corretto anche questa guida.

A questo punto ho scaricato da questo post bootloader.hex e micropython.zip (è così che si chiama l'immagine di WaspOs) e li ho caricati.

Per prima cosa ho creato un file elenedeath-bootloader.sh in /pinetime-updater/scripts:

#!/usr/bin/env bash
#  Flash to nRF52 with ST-Link

set -e  #  Exit when any command fails.
set -x  #  Echo all commands.

openocd-spi/bin/openocd \
    -f scripts/swd-pi.ocd \
    -f scripts/elenedeath-bootloader.ocd

Poi ho creato il file elenedeath-bootloader.ocd sempre in /pinetime-updater/scripts:

# OpenOCD script that connects ST-Link or Raspberry Pi to nRF52 and flashes the ROM.
# Assumes that $filename (e.g. a.img) and $address (e.g. 0x8000) are set.

# From https://devzone.nordicsemi.com/f/nordic-q-a/42824/flashing-nrf5832-using-only-st-link-v2-and-openocd
gdb_flash_program enable
gdb_breakpoint_override hard

$_TARGETNAME configure -event reset-init {
    # Arm Semihosting is used to show debug console output and may only be enabled after init event.  We wait for the event and enable Arm Semihosting.
    echo "Enabled ARM Semihosting to show debug output"
    arm semihosting enable
}

# Connect to the device.
init

echo "Stopping..."
reset halt

echo "Nrf5 erase..."
nrf5 mass_erase

echo "Installing wasp bootloader..."
program /home/pi/elenedeath/bootloader.hex verify

# Restart the device and start the bootloader.
echo "Restarting..."
reset run

echo "Done!"
exit

Ed ho lanciato lo script:

$ cd /home/pi/pinetime-updater
$ ./scripts/elenedeath-bootloader.sh

Il P8 si è messo in DFU e ho trovato il MAC ADDRESS in BLE. Quindi ho lanciato l'installazione di WaspOs tramite BLE:

$ sudo hcitool lescan
$ /home/pi/wasp-os/wasp-os-0.4.1/tools/ota-dfu/dfu.py -z /home/pi/elenedeath/micropython.zip -a C7:17:C8:F6:44:21 --legacy

L'orologio si è riavviato e ora segna le 03:00 come descritto nella guida di WaspOS!

@IvanViale
Copy link

Ciao Francesco, devo realizzare un progetto customizzando completamente uno smartwatch, hai portato avanti questo progetto? Pagando potresti sviluppare un'applicazione secondo mie specifiche o aiutarmi con il mio progetto? Se si interessato mi puoi contattare tramite la mia mail ivanviale1@alice.it, grazie

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment