Difference between revisions of "PineTime"

From Dejvino's Knowledge Base
Jump to navigation Jump to search
Line 7: Line 7:
  
 
== Bluetooth ==
 
== Bluetooth ==
=== Time Sync ===
 
 
You can use 'bluetoothctl' to manually interact (connect/pair/read/write) with a bluetooth device.
 
You can use 'bluetoothctl' to manually interact (connect/pair/read/write) with a bluetooth device.
 
<syntaxhighlight>
 
<syntaxhighlight>
Line 14: Line 13:
 
[bluetooth] scan on
 
[bluetooth] scan on
 
...
 
...
 +
[bluetooth] pair AA:BB:CC:DD:EE:FF
 
[bluetooth] connect AA:BB:CC:DD:EE:FF
 
[bluetooth] connect AA:BB:CC:DD:EE:FF
 
[PineTime] menu gatt
 
[PineTime] menu gatt
Line 19: Line 19:
 
[PineTime] write "0xe4 0x07 0x08 0x30 0x21 0x36 0x2c 0x00 0x01"
 
[PineTime] write "0xe4 0x07 0x08 0x30 0x21 0x36 0x2c 0x00 0x01"
 
[PineTime] read
 
[PineTime] read
 +
</syntaxhighlight>
 +
 +
=== Time Sync ===
 +
This [[Python]] script pushes the current time to the device:
 +
<syntaxhighlight lang="python">
 +
import datetime
 +
import pydbus
 +
from gi.repository import GLib
 +
 +
# Setup of device specific values
 +
dev_id = 'AA:BB:CC:DD:EE:FF'
 +
char_uuid = '00002a2b-0000-1000-8000-00805f9b34fb'
 +
 +
# DBus object paths
 +
bluez_service = 'org.bluez'
 +
adapter_path = '/org/bluez/hci0'
 +
device_path = f"{adapter_path}/dev_{dev_id.replace(':', '_')}"
 +
 +
bus = pydbus.SystemBus()
 +
adapter = bus.get(bluez_service, adapter_path)
 +
device = bus.get(bluez_service, device_path)
 +
mngr = bus.get(bluez_service, '/')
 +
 +
# Assume device has been paired already so can use connect
 +
device.Connect()
 +
 +
def get_characteristic_path(dev_path, uuid):
 +
    mng_objs = mngr.GetManagedObjects()
 +
    for path in mng_objs:
 +
        chr_uuid = mng_objs[path].get('org.bluez.GattCharacteristic1', {}).get('UUID')
 +
        if path.startswith(dev_path) and chr_uuid == uuid:
 +
          return path
 +
 +
char_path = get_characteristic_path(device._path, char_uuid)
 +
cts = bus.get(bluez_service, char_path)
 +
print('Old value: \t', cts.ReadValue({}))
 +
 +
now = datetime.datetime.now()
 +
data = bytearray(int(now.year).to_bytes(2, byteorder='little'))
 +
data.append(now.month)
 +
data.append(now.day)
 +
data.append(now.hour)
 +
data.append(now.minute)
 +
data.append(now.second)
 +
data.append(0) # millis
 +
data.append(1) # reason
 +
cts.WriteValue(data, {})
 +
 +
print('New value: \t', cts.ReadValue({}))
 +
 +
device.Disconnect()
 
</syntaxhighlight>
 
</syntaxhighlight>
  

Revision as of 20:58, 30 August 2020

Open smartwatch from Pine64.

Hardware

TODO: Copy from the official page

Bluetooth

You can use 'bluetoothctl' to manually interact (connect/pair/read/write) with a bluetooth device.

# bluetoothctl
[bluetooth] power on
[bluetooth] scan on
...
[bluetooth] pair AA:BB:CC:DD:EE:FF
[bluetooth] connect AA:BB:CC:DD:EE:FF
[PineTime] menu gatt
[PineTime] select-attribute /org/bluez/hci0/dev_AA_BB_CC_DD_EE_FF/service0015/char0016
[PineTime] write "0xe4 0x07 0x08 0x30 0x21 0x36 0x2c 0x00 0x01"
[PineTime] read

Time Sync

This Python script pushes the current time to the device:

import datetime
import pydbus
from gi.repository import GLib

# Setup of device specific values
dev_id = 'AA:BB:CC:DD:EE:FF'
char_uuid = '00002a2b-0000-1000-8000-00805f9b34fb'

# DBus object paths
bluez_service = 'org.bluez'
adapter_path = '/org/bluez/hci0'
device_path = f"{adapter_path}/dev_{dev_id.replace(':', '_')}"

bus = pydbus.SystemBus()
adapter = bus.get(bluez_service, adapter_path)
device = bus.get(bluez_service, device_path)
mngr = bus.get(bluez_service, '/')

# Assume device has been paired already so can use connect
device.Connect()

def get_characteristic_path(dev_path, uuid):
    mng_objs = mngr.GetManagedObjects()
    for path in mng_objs:
        chr_uuid = mng_objs[path].get('org.bluez.GattCharacteristic1', {}).get('UUID')
        if path.startswith(dev_path) and chr_uuid == uuid:
           return path

char_path = get_characteristic_path(device._path, char_uuid)
cts = bus.get(bluez_service, char_path)
print('Old value: \t', cts.ReadValue({}))

now = datetime.datetime.now()
data = bytearray(int(now.year).to_bytes(2, byteorder='little'))
data.append(now.month)
data.append(now.day)
data.append(now.hour)
data.append(now.minute)
data.append(now.second)
data.append(0) # millis
data.append(1) # reason
cts.WriteValue(data, {})

print('New value: \t', cts.ReadValue({}))

device.Disconnect()

Structure of a Current Time Service packet:

          uint16_t year;
          uint8_t month;
          uint8_t dayofmonth;
          uint8_t hour;
          uint8_t minute;
          uint8_t second;
          uint8_t millis;
          uint8_t reason;

Flashing

JLinkExe without nrfjprog

#!/bin/bash
# Resources: https://www.silabs.com/community/mcu/32-bit/knowledge-base.entry.html/2014/10/22/using_jlink_commande-YYdy
#
# == Manual Steps ==
#
# (SWD mode)
# J-Link>si 1
# 
# (transfer speed)
# J-Link>speed 4000
#
# (select the PineTime CPU)
# J-Link>device NRF52832_XXAA
#
# (clear the flash)
# J-Link>erase
#
# (flash the binary image)
# J-Link>loadbin src/pinetime-app.bin
#
# (reset)
# J-Link>r
#
# (start program execution)
# J-Link>g
#

cat <<EOF | /opt/SEGGER/JLink/JLinkExe
si 1
speed 4000
device NRF52832_XXAA
erase
loadbin src/pinetime-app.bin 0x0
r
g
q
EOF

External Links