Close
0%
0%

Color Open Source Smartwatch

Reverse engineering the SMA-Q2 smartwatch to run open source firmware on it

Similar projects worth following
SMA-Q2 also known as SMA TIME is a Chinese smartwatch featuring a color Memory LCD, heart rate sensor and a NRF52832 Bluetooth SoC to drive it all.

Its low price, cool features and simple construction make it look like a prefect platform for an open source smartwatch firmware.

Firmware

Original firmware

The original firmware runs on S132 SoftDevice ver 2.0.1.

The device contains an OTA bootloader that can be used with the generic Nordic upload tool, so new firmware can be uploaded safely.

Custom firmware

The chip is locked, so if you want to use your own firmware you have to use the built-in OTA bootloader or erase the whole chip to remove the lock.

Hardware

Hardware Components

NRF52832-QFAAB0
Main SoC
LP2985 (?)      
 3.3V LDO for everything
LP2985 (?)
3.3V LDO for heart rate sensor module
RT9526 (?)
Battery charger
KX022-10203-Axis accelerometer
PAH8002Heart rate sensor
GD25Q16C16Mbit SPI flash
LPM013M126A176×176 Japan Display Color memory LCD   

Main MCU

Nordic Semiconductor NRF52832.
32-bit ARM Cortex-M4F CPU with 512kB flash and 64kB RAM and of course Bluetooth.

MCU pinout:

Pin

Description

P0.02

LCD SCLK

P0.03

LCD SI

P0.05

LCD SCS

P0.06

LCD EXTCOMIN

P0.07

LCD DISP



P0.04

Battery voltage measurement (x0.25 divider)



P0.08

BACKLIGHT ON



P0.09

BUTTON BACK

P0.27

BUTTON UP

P0.28

BUTTON OK

P0.29

BUTTON DOWN



P0.11

FLASH MISO

P0.12

FLASH CS

P0.13

FLASH MOSI

P0.14

FLASH CLK



P0.25

UART RX

P0.26

UART TX



P0.30

VIBRATOR ON



P0.15

ACCEL INT ?

P0.16

ACCEL POWER

P0.17

ACCEL SDA

P0.18

ACCEL SCL



P0.19

HRM SDA

P0.20

HRM SCL

P0.22

HRM INT ?

P0.10

HRM RESET ?

P0.31

HRM POWER ON



P0.23 CHARGER STATUS ?
P0.24 CHARGER POWER GOOD ?

3.3V LDO for system

Unknown chip, but similar to LP2985. Powers the whole thing

3.3V LDO for heart rate sensor module

Same as above. Powers the PAH8002 heart rate sensor module.
Enable pin controlled by the MCU.

Battery charger

Unknown chip, seems like a generic linear li-ion battery charger IC.

Possibly a Richtek RT9526, the pinout seems to match.

Accelerometer

Kionix KX022-1020 3-axis accelerometer.
Communication over I2C. Powered from an MCU pin!

Heart rate sensor

PAH8002 heart rate sensor with green and infrared LEDs. Mounted on the back plate of the watch, connects to the mainboard with a ribbon cable.
Communicates over I2C.
I have managed to dig up the complete datasheet and application note.

External Flash

GigaDevices GD25Q16C 16Mbit (2MB) SPI Flash.

LCD

LPM013M126A 176×176 Japan Display Color memory LCD.

Driven with SPI. Has a LED backlight controlled...

Read more »

  • A bit of bad news

    emeryth04/08/2018 at 15:48 2 comments

    A few months after release, the watch has received a slight silent mechanical redesign.

    Most noticeably, the buttons are now oval instead of round (and feel nicer).

    Unfortunately for the hardware hackers, the screws on the back that held the watch together are now GONE!

    Left: old watch, right: current version

    I don't see any seams on the back, I'm afraid the watch is now glued together and has to be disassembled from the LCD "glass" side.

    I'm pretty sure the electronics remain the same, because there is no mention of different watch versions when downloading firmware.

    Still, the watch remains entirely hackable without disassembling.

    You can upload your own firmware through OTG, you just have to be more careful.

    If you soft brick it somehow, you will have to wait for the battery to die to let you reset and go into the bootloader again.

  • Dumping the internal flash

    emeryth03/19/2018 at 18:34 0 comments

    The MCU on board is locked, which means you can't do anything over the debug interface unless you do a total chip erase.

    I wanted to dump the internal flash to get the bootloader and perhaps some other interesting stuff.

    Since I already have the ability to upload my own firmware, dumping the flash over UART seemed straightforward, but turned out to be not so simple.

    For some reason I just could not receive the full dump without interruption.

    At first, I blamed the notoriously flaky NRF52 UART when used without flow control. But even when I added flow control by using the SPI flash testpoints, it wouldn't work.

    Many hacks later I realized it's the MCU that's resetting periodically.

    Turns out the bootloader is enabling the watchdog!

    With a reload value of 0x50000 it gives you exactly 10 seconds.

    Once I fed it properly (via the RR0 register), I could get the full dump.



    The flash layout is standard - Softdevice, followed by user firmware, followed by the OTA bootloader at 0x76000.

    There is a tiny bit of data between the firmware and bootloader, that may be the persistent app data partition.

    The UICR registers are also unused, except for the bootloader addres and bootloader data page.

    NRFFW[0]:00076000
    NRFFW[1]:0007E000

  • Dumping the external flash

    emeryth03/13/2018 at 19:14 1 comment

    Yesterday I dumped the external flash. You can find the image in the owncloud archive.
    Turns out most of it is used to store an almost complete 16-bit Unicode font.

    I figured that out by converting the binary to an image and looking for repeating or familiar patterns.
    A good tool for that is ImageMagick.

    With the following command:

    convert -depth 1 -size 16x2048 gray:flash_dump.bin flash.png 

    you can turn the binary into binary (heh) images.

    Using a width of 16 pixels reveals that most of the space is taken by a font.

    But you can see that some of the characters are messed up. It's not a problem with the dump or some offset, the problems clearly happen on smaller characters, so the font must not be of fixed 16x16 size. We cannot decode the glyphs without knowing their width!

    In memory, the glyphs follow a rather large area with some other data, it must be some kind data structure for the font, perhaps with info about the width of every character.

    0000:2000 | 55 46 4C 11  54 F0 12 00  01 10 FF 3F  62 77 00 00 | UFL.Tð....ÿ?bw..
    0000:2010 | 20 00 E6 FF  18 00 00 00  34 FF 03 10  44 FF 03 10 |  .æÿ....4ÿ..Dÿ..
    0000:2020 | 54 FF 03 18  64 FF 03 24  84 FF 03 24  A4 FF 03 38 | Tÿ..dÿ.$.ÿ.$¤ÿ.8

    The data starts with a magic header "UFL", unfortunately, even with that, I was unable to find any info about this font format.

    So I had to dig deeper.



    The strings in the original watch firmware refer to something called 'arialuni_U16.bin'.
    That turns out to be a font file with unicode characters used by a Chinese modification for GRUB4DOS.
    When I downloaded the file from Google Code it turned out to be of the same binary format! (not identical though)

    Lots of searching and translating later I have found what seems to be a blog of the author of a Chinese font creation tool called FontMaker that seems to be the source of the format.

    There I found a simple explanation (that google translates amazingly well) of the format:

    http://blog.sina.com.cn/s/blog_5d8cc6410100dkko.html

    C. Unicode
    
    00000000h: 55 46 4C 10 28 AB 07 00 01 10 81 00 00 00 00 00
    00000010h: 20 00 FF FF 18 00 00 00 98 FF 03 10 A8 FF 03 10
    ...
    0003ff90h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0003ffa0h: 00 00 00 00 00 00 00 00 00 00 40 40 40 40 40 40
    0003ffb0h: 40 40 00 40 40 00 00 00 00 48 48 48 48 00 00
    ...
    
    
    Analyze as follows:
    1). File header (first 16 Byte)
    
    55 46 4C 10 -- Marker to determine if it is a valid font file.
    55 = 'U', indicates that the file is a font file in unicode encoding format.
    46 = 'F', 4C = 'L'
    10 indicates that the font file version information is: Version 1.0
    28 AB 07 00 -- Total file length
    01 -- contains several Sections. 1- 1 Section (without CJK, it is divided into 3 Sections)
    10 -- font height 0x10 == 16
    81 00 -- The selected character set flag. 1-ID selection, 0-ID not selected. Therefore, the current selection is: Japanese + Western European character set.
    00 00 00 00 -- reserved bytes
    
    2). Segment information (n section * sizeof(FL_SECTION_INF) = 1 * 8 = 8))
    20 00 -- First character
    FF FF -- Last character
    18 00 00 00 -- OffAddr;
    
    3). Search table ((Section[0].Last - Section[0].First + 1) * 4 + (Section[n-1].Last - Section[n-1].First + 1) * 4)
    Each 4 bytes represents one character of search information, starting with the character Section[0].First. So the character 0x20 search information (start address =
    (character unicode code - Section[x].First) × 4 + Section[x].OffAddr, x is the current section character in the section index value, can be judged. ): 98 FF 03 10
    That is, a 32-bit number is obtained: 0x1003FF98 (hexadecimal) --- (00010000 00000011 11111111 10011000).
    The high 6 indicates the width of the current character. Therefore, we get 000100 -- 4 (font size is 4)
    The lower 26 bits indicate the offset address of the dot matrix information of the current character. Therefore, we get 0000000011 11111111 10011000 -- 0x3FF98 (starting address of dot matrix information is 0x3FF98)
    ...
    Read more »

View all 3 project logs

Enjoy this project?

Share

Discussions

ddavidmelo wrote 03/14/2018 at 21:53 point

I have this watch and I think with a good firmware can be better than pebble. Keep going with this work, I would love to see the something cool in the end.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates