Meretas Gelang Kebugaran Murah

Ini adalah terjemahan. Artikel diterbitkan 27 Mei 2018


Pelacak kebugaran sebelum dan sesudah pembongkaran

Ketika saya datang ke perusahaan saat ini, pada hari pertama saya dengan ramah diberikan satu set hadiah. Di antara mereka ada gelang dengan pelacak kebugaran. Terlepas dari kesukaan Anda berolahraga, ini adalah gadget yang sangat keren dari sudut pandang teknis:

  • faktor bentuk sangat kecil (sekitar 15 × 40 mm);
  • Bluetooth low energy (BLE);
  • Tampilan OLED (96 × 32 piksel);
  • baterai
  • Biaya USB
  • akselerometer;
  • motor getaran;
  • harganya sekitar $ 10 (!).

Di luar, satu-satunya pengidentifikasi di panel belakang adalah stiker "FCC ID: 2AHFTID115". Jika Anda google itu, tampaknya sesuai dengan perangkat ID115 dan Anda bahkan dapat menemukan beberapa foto bagian dalamnya. Melihat kembali salah satu dari foto-foto ini , jika Anda berusaha keras, Anda dapat melihat nama sirkuit terpadu terbesar (IC): N51822. Ini menunjukkan bahwa mungkin ada mikrokontroler Nordic (MCU) nRF51822 , prosesor 32-bit ARM M0 dengan dukungan BLE bawaan, yang secara teoritis mudah diprogram untuk hal-hal lain yang harus dilakukan gelang.

Sebelum membongkar gadget, saya sedikit Google dan menemukan bahwa di beberapa gelang serupa chip yang sama diinstal, dan orang-orang berhasil memprogramnya.

Membuka kasing itu tidak mudah. Penutup plastik hitam terpaku pada latar belakang abu-abu. Saya mencoba pengering rambut untuk melembutkan lem, dan dengan sabar memotongnya dengan pisau kecil, berusaha untuk tidak merusak plastik terlalu banyak. Setelah dibuka, saya memastikan benar-benar ada nRF51822. Kemudian saya membeli gelang MCU yang hampir identik dari Texas Instrument. Perlu diingat bahwa ada opsi.


nRF51822 dan pulpen untuk skala

Menemukan cara untuk berkomunikasi


Dokumentasi mengatakan bahwa chip dapat diprogram / didebug menggunakan antarmuka dua pin ARM Serial Wire Debug (SWD). Jika kita ingin membuat saluran komunikasi dengan sebuah chip, ini berarti dua hal:

  • Kami memerlukan programmer SWD (misalnya, Segger J-Link ).
  • Kita akan membutuhkan akses ke dua pin SWD pada mikrokontroler, yaitu SWDIO (data) dan SWDCLK (pulsa clock).

Untungnya, ada beberapa bantalan yang tersedia di papan tulis. Meskipun keberadaan mereka jelas dijelaskan oleh kebutuhan untuk debugging, pengujian dan verifikasi, saya lebih suka berpikir bahwa beberapa insinyur keren meninggalkan mereka di sana sebagai hadiah kecil untuk orang-orang seperti kita. Tidak semuanya diberi label dengan benar, jadi saya sarankan kode berikut:




Sisi depan dan belakang papan sirkuit. Ballpoint pen untuk skala dan nama semi-arbitrer untuk bantalan terbuka

Dengan menggunakan mikroskop USB murah yang sama , saya mengambil beberapa gambar dari sisi depan dan belakang papan dan mencoba melacak jejak dari mikrokontroler ke bantalan.




Melacak ke pin SWDIO dan SWDCLK di bagian depan dan belakang papan

Harap dicatat bahwa ini adalah papan sirkuit cetak multi-layer dengan lubang berlubang, jadi Anda harus memeriksa trek di kedua sisi papan. Dari foto-foto ini, Anda dapat melacak trek dari kontak SWDIO dan SWDCLK pada chip ke bantalan IO dan CLK. Jadi kami akan memastikan bahwa tanda CLK di papan sesuai dengan SWDCLK pada MCU, dan kontak yang tidak berlabel adalah pin SWDIO. Sekarang Anda dapat menyiapkan tabel pemetaan pertama kami:

Pin NRF51822Taman bermainDeskripsi
SWDIOIOOutput data untuk pemrograman SWD
SWDCLKCLKOutput clock untuk pemrograman SWD

Operasi post-mortem


Setelah mendapatkan akses ke dua bantalan SWD, saya menyolder kabel yang sangat tipis ke mereka dan ke semua kontak lain yang tersedia.



Berkedip sedikit


Tugas selanjutnya adalah mencoba memprogram perangkat untuk beberapa tugas. Untuk menjalankan program yang paling sederhana, kita perlu memastikan hal-hal berikut:

  • Kami melacak kontak SWDIO / SWDCLK dengan benar.
  • Pemrogram SWD sedang berjalan dan komputer dapat mengeluarkan perintah.
  • Kita dapat mengkompilasi program Arm dan menggunakan SDK Nordic dengan benar.
  • Kita dapat mem-flash program yang dikompilasi ke dalam chip.
  • Chip bekerja dengan benar dan memuat program kami.

Dalam hal ini, "halo, dunia" bisa menjadi program yang menyalakan dan mematikan LED. Dan bahkan ini bukan SD, karena tidak ada LED bawaan di papan, dan jika Anda menambahkan yang eksternal, Anda masih perlu mencari tahu apa yang harus dihubungkan. Ini menambah dimensi lain pada model spasial masalah. Menurut kurangnya teorema keju gratis, saya hanya menghubungkan dua LED ke pin P1 dan P2 dengan harapan bahwa kita bisa sampai ke pembalut ini dengan MCU.


Hari yang buruk

Program driver dan command line untuk programmer J-Link SWD terdapat di situs web Segger . Jika Anda menggunakan MacOS dan menggunakan Homebrew, cari rumus Cask di caskroom/drivers/segger-jlink . Komunikasi dengan programmer SWD dibentuk dari JLinkExe baris perintah JLinkExe .

Kemudian saya mengunduh Nordic nRF5 SDK (saya menggunakan versi 12.3.0 ). Dari contoh SDK, jelas bahwa kita memerlukan kompiler yang mampu mengkompilasi program Arm. Jadi saya menginstal gcc-arm-embedded (juga tersedia di Homebrew).

Setelah memeriksa dokumentasi SDK dan forum pengembang Nordik, saya menemukan bahwa SDK mereka paling sering digunakan dengan papan pengembangan seperti ini . SDK telah dikonfigurasikan sebelumnya untuk beberapa varian papan tersebut. Karena kami berhubungan langsung dengan controller, Anda harus mengkonfigurasi beberapa parameter SDK.

Saya menghabiskan banyak waktu untuk memahami ekosistem nRF5, tetapi pada akhirnya saya masih dapat menjalankan program pada sebuah chip! Video menunjukkan dua LED yang berkedip. Pada titik ini, saya membuat repositori Github dan membuang program dengan Makefile berfungsi di Makefile . Salah satu rahasia utama adalah bahwa sebenarnya ada beberapa opsi untuk nRF51822, dan di tambang saya hanya ada 16 KB memori. Jadi saya masih harus memperbaiki skrip linker .

Input / output digital


Seperti yang sudah saya katakan, tugas mem-flash LED memberikan beberapa harapan dan metode poke, yang mana dari kontak MCU mengarah ke P1 dan P2 , di mana LED terhubung. Strategi paling sederhana adalah menghubungkan semua output secara bergantian dan menerapkan tegangan tinggi dan rendah secara bergantian. Yang mengejutkan saya, kedua LED menyala! Saya bahkan lebih terkejut ketika vibromotor mulai bekerja!

Jadi, metode poke ditambahkan ke tabel:

Pin NRF51822Taman bermainDeskripsi
P0.30P1GPIO digital
P0.00P2GPIO digital
P0.01-Motor getaran

printf


Kemampuan untuk mentransfer data ke komputer sangat diperlukan untuk debugging. Programmer J-Link mendukung transmisi waktu nyata (RTT) untuk mengirim dan menerima data dari chip. Untuk menggunakan RTT, Anda harus #include "SEGGER_RTT.h" dan memanggil SEGGER_RTT_WriteString() . Untuk menerima data di komputer, hubungi jlinkrttlogger baris perintah jlinkrttlogger , yang disediakan dengan J-Link.

OLED


Tantangan lain adalah membuat OLED bekerja. OLED yang paling umum di pasaran menjalankan driver / controller ssd1306 , dan biasanya komunikasi dengan MCU adalah melalui antarmuka serial menggunakan SPI atau I²C . Ini adalah contoh dari Adafruit .

Saya tidak menemukan tampilan seperti itu di salah satu toko biasa. Dan ukuran 96 × 32 adalah non-standar. Pencarian dengan pengidentifikasi QT1316P01A pada layar memberikan situs China seperti Aliexpress , tetapi tidak ada dokumentasi kecuali untuk nama-nama kesimpulan:


Penamaan pin OLED dengan Aliexpress

Jika daftar tidak berbohong, maka kontak SCL , SDA dan RES# memberi tahu kami bahwa ini adalah opsi I²C. Jika ada trek antara tiga pin nRF51822 dan tiga pin OLED ini, maka kita akan mengambil langkah maju. Ayo kembali ke mikroskop.




Track Kontak Data OLED

Kami memperbarui tabel korespondensi:

Pin NRF51822Taman bermainDeskripsi
P0.21-Output SDA OLED
P0.22-Pin OLED SCL
P0.24-Output OLED RES #

Protokol I²C jauh lebih maju daripada protokol serial sederhana seperti UART . Salah satu kelebihannya adalah mendukung beberapa perangkat master dan slave pada bus yang sama. Ini sedikit rumit: paling tidak Anda perlu memberi tahu MCU tentang perintah slave yang dikeluarkan. Jadi pada tingkat tinggi, selain kontak fisik, ada juga alamat "logis" dari layar OLED.

Untungnya, salah satu contoh dalam nRF5 SDK adalah pemindai I²C. Dia menginterogasi dari semua kemungkinan alamat dan laporan logis jika ada sesuatu yang diinstal di sana. Versi modifikasi saya ada di sini . Ini menghasilkan log berikut:

$ make
# ...
$ make flash
# ...
$ make log
# ...
TWI scanner.
TWI device detected at 0x3c.


Berita bagus! Kami memiliki alasan kuat untuk meyakini bahwa tampilan diidentifikasi dengan benar dan memang merupakan varian I²C. Pencarian 0x3c mengatakan 0x3c adalah alamat khas untuk perangkat tersebut.

Sekarang kami siap mengirim beberapa piksel ke layar. Pada tingkat ini, tidak ada abstraksi melalui perpustakaan. Lihat dokumentasi ssd1306 untuk cara tingkat rendah untuk mentransfer data. Proses ini terdiri dari urutan perintah konfigurasi yang mengatur orientasi tampilan, mode perekaman, ukuran, dll. Kemudian, urutan byte yang ditampilkan di layar dikirim ke memori tampilan grafik (GDDRAM).

Untuk konfigurasi yang benar, saya mempelajari perpustakaan ssd1306 dari Adafruit dan mencoba meniru perintah yang sama. Itulah yang menjadi bagian terbesar dari waktu dalam proyek ini. Menemukan semua detail ternyata menjadi tugas yang sangat memakan waktu, dan masih saya tidak bisa menjelaskan beberapa hal. Namun, itu berhasil!


Menampilkan bitmap hard-coded

Kode untuk contoh ini ada di sini .

Dengan pengaturan ini, tampilan dibagi menjadi 4 baris (halaman) dan 96 kolom. Jadi halaman tingginya 8 piksel. Byte pertama yang dikirim akan ditempatkan "vertikal" di kolom pertama dari halaman pertama. Byte kedua akan menempati kolom kedua, lalu yang ketiga dan seterusnya, sampai ke kolom ke-96, ketika kembali dan dimulai dari kolom pertama di halaman kedua.

Inilah perilaku yang diharapkan . Seperti yang ditunjukkan dalam video , perilaku yang diamati berbeda: pertama kolom aneh diisi, lalu yang genap, dan baru kemudian kembali ke halaman kedua.

Saya menghabiskan banyak waktu untuk memahami alasan perilaku tampilan yang bodoh, dan kemudian lebih banyak waktu untuk mengkonfigurasinya untuk memperbaikinya. Pada akhirnya, saya menelan harga diri saya dan masih menerapkan logika rendering yang aneh dalam program untuk menyelesaikannya.

Perjalanan ke Arduino


Menggali perpustakaan Adafruit ssd1306 untuk Arduino, saya selalu berpikir akan menyenangkan untuk memiliki cara untuk "mensimulasikan" bit Arduino tertentu untuk mengujinya di nRF51822. Ternyata orang yang lebih berpengalaman juga memikirkan topik ini - inilah yang dilakukan oleh proyek sandeepmistry / arduino - nRF5 yang menakjubkan. Ini mengimplementasikan perpustakaan Arduino utama menggunakan nRF5 SDK.

Dengan proyek ini, kita dapat membuka IDE Arduino, memilih papan nRF5, dan menggunakan ekosistem Arduino yang kaya. Saya memotong proyek dan menambahkan dukungan untuk papan dari gelang kami. Anda dapat memilihnya dari menu tarik-turun Tools > Board > ID115 Fitness Bracelet (nRF51822) .




Pustaka Adafruit ssd1306 dalam bentuk aslinya (di atas) dan dengan tambalan (di bawah)

Ini juga berarti bahwa sekarang kita dapat menggunakan perpustakaan OLED Adafruit . Yang mengejutkan dan melegakan saya, perilaku aneh yang sama terjadi dengan mengisi kolom aneh dan bahkan OLED terlebih dahulu! Saya senang bercabang perpustakaan dan menerapkan hack yang sama. Dibandingkan dengan pendekatan tingkat rendah, kami sekarang memiliki akses ke berbagai abstraksi keren, seperti keluaran teks:


"Halo, dunia!" Yang lebih akrab.

Input / output analog


Selain sinyal on / off digital, nRF51822 memiliki 10 pin untuk input analog. Ini berguna, misalnya, untuk membaca pengisian daya baterai saat ini. Dilihat oleh dokumentasi, membaca kontak analog menghasilkan nilai 10-bit. Oleh karena itu, jika ada 0V pada input, maka kita akan membaca 0 , dan jika ada VCC , kita akan membaca 1023 dengan nilai antara.

Secara berkala saya membaca nilai input analog dan memplot sinyal yang paling menarik:




Efek papan goyang dan pengisian baterai sesuai dengan data dari input analog

Saya yakin bahwa kontak P0.05 mengacu pada pengisian daya baterai, karena nilainya bertambah dan berkurang saat diisi dan dibuang. Saya menduga pin P0.26 terhubung ke salah satu output dari accelerometer, karena itu menjadi gila ketika Anda menggoyang papan. Kontak P0.03 dan P0.04 juga dapat dihubungkan ke berbagai output akselerometer, tetapi di sini efek orde kedua tertentu kemungkinan besar ditumpangkan pada sinyal dari input. Misalnya, pada grafik pertama, perhatikan bagaimana level baterai (pin 5) berubah ketika accelerometer membutuhkan lebih banyak energi. Ini adalah contoh efek urutan kedua.

Kode dapat ditemukan dalam sketsa ini . Sumber data dan skrip grafik ada di sini . Sekarang kita dapat menambahkan beberapa baris ke tabel korespondensi kami:

Pin NRF51822Taman bermainDeskripsi
P0.05-Input Analog - Terhubung ke Baterai
P0.26-Input Analog - One Axis Accelerometer
P0.03-Input analog - satu sumbu accelerometer (kemungkinan)
P0.04-Input analog - satu sumbu accelerometer (kemungkinan)

Tombol


Dalam firmware asli, menyentuh gelang pada titik tertentu akan menyalakan layar. Memegang titik ini memulai kronometer, jika saya ingat dengan benar. Ini bukan tombol fisik, tetapi semacam sentuhan kapasitif yang bekerja dengan sangat baik. Menggunakan pendekatan yang sama seperti untuk mencari keluaran digital, saya menemukan tempat untuk terhubung ke MCU (video) .

Kodenya ada di sini .

Pin NRF51822Taman bermainDeskripsi
P0.10-Input Digital - Tombol Bawaan

Bluetooth low energy (BLE)


Fungsionalitas BLE pada chip nRF5 diimplementasikan melalui sesuatu yang disebut SoftDevice . Ini adalah biner yang dikompilasi dengan tumpukan BLE. Itu dijahit terlepas dari aplikasi. Ada banyak versi SoftDevice, tergantung pada versi SDK dan versi chip.

Dokumentasi menyediakan matriks dependensi tertentu (sayangnya, Anda tidak dapat menempatkan tautan langsung ke sana). Ini menunjukkan SDK mana versi yang berbeda dari chip datang - dan versi SoftDevice apa itu. Dalam kasus kami, chip ditandai QFAAH0, chip ini memiliki 256 KB memori flash, 16 KB RAM dan kompatibilitas dengan SoftDevice s130 dinyatakan.

SDK versi 12.3 saya sudah berisi beberapa contoh penggunaan SoftDevice s130. Dibandingkan dengan program sebelumnya yang langsung ditransfer ke microchip dari alamat 0x0 , sekarang Anda perlu mem-flash SoftDevice dari alamat 0x0 , dan program itu sendiri dari alamat 0x1b000 . Setelah memuat dan inisialisasi, file biner SoftDevice akan pergi ke alamat ini dan mentransfer kontrol ke program kami. Sebagai ilustrasi, saya mengambil contoh yang sama dengan LED berkedip, tetapi mengubahnya untuk firmware SoftDevice ( kode ). Perilaku yang diamati tidak berubah, kecuali bahwa Anda harus melakukan pra-flash SoftDevice:

$ make
# ...
$ make flash-softdevice
# ...
$ make flash
# ...
$ make log
# ...
Hello, world!


Mungkin aplikasi paling sederhana untuk Bluetooth adalah mengubah perangkat menjadi suar . Perangkat hanya menyiarkan keberadaannya. Salah satu contohnya adalah di SDK yang disebut ble_app_beacon . Diasumsikan bahwa SoftDevice s130 sudah di-flash.

Di sini juga, komunikasi tingkat rendah dengan chip mempersulit segalanya dibandingkan dengan pemrograman melalui SDK. Selain menyesuaikan ukuran RAM (pengetahuan ini sulit bagi saya dalam contoh dengan LED), masalah sulit lainnya dilacak. Ternyata, tumpukan BLE menggunakan generator jam untuk melakukan tugas yang sensitif terhadap waktu. Dalam contoh SDK, osilator kristal eksternal diasumsikan. Ketika saya menyadari hal ini setelah ribuan upaya untuk printf , saya mengubah flag konfigurasi untuk menggunakan generator jam sintetis, dan masalahnya terpecahkan. Kode sumber suar ada di sini .

BLE + Arduino


Ketika contoh BLE bekerja dengan nRF5 SDK, mengetahui tentang jebakan dengan RAM dan generator, saya melihat kembali pada lingkungan Arduino. Dan lagi, ada proyek sandeepmistry / arduino-BLE yang mulia (dari orang yang sama dengan arduino-nRF5!), Yang memberikan abstraksi yang sangat baik di atas pengaturan BLE internal.

Yang mengejutkan saya, saya bahkan tidak perlu membayar perpustakaan. Penulis proyek arduino-nrf5 menghabiskan waktu dan menambahkan konfigurasi semua papan dan pengaturan, jadi sekarang memilih generator jam yang tepat untuk SoftDevice diturunkan ke pilihan sederhana dari menu drop-down Tools > Low Frequency Clock > Synthesized . Luar biasa. Saya dengan cepat menulis contoh dengan LED hijau menyala melalui Bluetooth (dengan aplikasi ini ). Karyanya ditampilkan dalam video .

Rencana selanjutnya


Setelah sibuk dengan papan ini selama berjam-jam yang tak terhitung jumlahnya, tangan saya gatal selama beberapa minggu untuk menempelkannya lebih jauh ke dalam mesin cuci dan melupakannya sebentar.

Source: https://habr.com/ru/post/id413895/


All Articles