summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/MemoryAnalysis.md4
-rw-r--r--doc/bootloader/boot.pngbin0 -> 22268 bytes
-rw-r--r--doc/bootloader/boot.puml19
-rw-r--r--doc/bootloader/recover.pngbin0 -> 24165 bytes
-rw-r--r--doc/bootloader/recover.puml17
-rw-r--r--doc/bootloader/upgrade.pngbin0 -> 38616 bytes
-rw-r--r--doc/bootloader/upgrade.puml21
-rw-r--r--doc/buildAndProgram.md36
-rw-r--r--doc/buildWithDocker.md33
-rw-r--r--doc/companionapps/Amazfish.md15
-rw-r--r--doc/companionapps/Gadgetbridge.md13
-rw-r--r--doc/companionapps/NrfconnectOTA.md12
-rw-r--r--doc/companionapps/firmwareNoValidated.jpgbin0 -> 191501 bytes
-rw-r--r--doc/companionapps/firmwareValidated.jpgbin0 -> 212743 bytes
-rw-r--r--doc/companionapps/firmwareValidationApp.jpgbin0 -> 179828 bytes
-rw-r--r--doc/contribute.md22
-rw-r--r--doc/filesInReleaseNotes.md4
-rw-r--r--doc/openOCD.md105
18 files changed, 278 insertions, 23 deletions
diff --git a/doc/MemoryAnalysis.md b/doc/MemoryAnalysis.md
index 1bf6e24d..95bd611c 100644
--- a/doc/MemoryAnalysis.md
+++ b/doc/MemoryAnalysis.md
@@ -1,6 +1,6 @@
# Memory analysis
## FreeRTOS heap and task stack
-FreeRTOS statically allocate its own heap buffer in a global variable named `ucHeap`. This is an aray of *uint8_t*. Its size is specified by the definition `configTOTAL_HEAP_SIZE` in *FreeRTOSConfig.h*
+FreeRTOS statically allocate its own heap buffer in a global variable named `ucHeap`. This is an array of *uint8_t*. Its size is specified by the definition `configTOTAL_HEAP_SIZE` in *FreeRTOSConfig.h*
FreeRTOS uses this buffer to allocate memory for tasks stack and all the RTOS object created during runtime (timers, mutexes,...).
The function `xPortGetFreeHeapSize()` returns the amount of memory available in this *ucHeap* buffer. If this value reaches 0, FreeRTOS runs out of memory.
@@ -75,4 +75,4 @@ add_definitions(-D__STACK_SIZE=8192)
*TODO*
#Tools
- - https://github.com/eliotstock/memory : display the memory usage (FLASH/RAM) using the .map file from GCC. \ No newline at end of file
+ - https://github.com/eliotstock/memory : display the memory usage (FLASH/RAM) using the .map file from GCC.
diff --git a/doc/bootloader/boot.png b/doc/bootloader/boot.png
new file mode 100644
index 00000000..713f7151
--- /dev/null
+++ b/doc/bootloader/boot.png
Binary files differ
diff --git a/doc/bootloader/boot.puml b/doc/bootloader/boot.puml
new file mode 100644
index 00000000..00790d75
--- /dev/null
+++ b/doc/bootloader/boot.puml
@@ -0,0 +1,19 @@
+@startuml
+
+MCU -> Bootloader: reset
+activate Bootloader
+Bootloader -> Bootloader: Recover? (no)
+Bootloader -> Bootloader: New version? (no)
+Bootloader -> Application: Jump to primary slot
+deactivate Bootloader
+
+activate Application
+note right: This is the current version of the firmware
+Application -> Application: OTA procedure
+note right: Download a new firmware version and\n store it in secondary slot
+Application -> MCU: Reset
+deactivate Application
+
+
+
+@enduml \ No newline at end of file
diff --git a/doc/bootloader/recover.png b/doc/bootloader/recover.png
new file mode 100644
index 00000000..6c6a940e
--- /dev/null
+++ b/doc/bootloader/recover.png
Binary files differ
diff --git a/doc/bootloader/recover.puml b/doc/bootloader/recover.puml
new file mode 100644
index 00000000..3f5bafb1
--- /dev/null
+++ b/doc/bootloader/recover.puml
@@ -0,0 +1,17 @@
+@startuml
+
+MCU -> Bootloader: reset
+activate Bootloader
+Bootloader -> Bootloader: Recover? (yes)
+Bootloader -> Bootloader: Restore previous firmware
+note left: Copy the previous firmware from secondary to primary slot
+Bootloader -> Application: Jump to primary slot
+deactivate Bootloader
+
+activate Application
+note right: This is the previous version\nof the firmware
+Application -> Application: Normal Operation
+Application -> MCU: Reset
+deactivate Application
+
+@enduml \ No newline at end of file
diff --git a/doc/bootloader/upgrade.png b/doc/bootloader/upgrade.png
new file mode 100644
index 00000000..ac77d422
--- /dev/null
+++ b/doc/bootloader/upgrade.png
Binary files differ
diff --git a/doc/bootloader/upgrade.puml b/doc/bootloader/upgrade.puml
new file mode 100644
index 00000000..c31b9111
--- /dev/null
+++ b/doc/bootloader/upgrade.puml
@@ -0,0 +1,21 @@
+@startuml
+
+MCU -> Bootloader: reset
+activate Bootloader
+Bootloader -> Bootloader: Recover? (no)
+Bootloader -> Bootloader: New version? (yes)
+Bootloader -> Bootloader: Swap firmwares
+note left: Copy current firmware from primary to secondary\nand copy the new firmware from secondary to primary
+Bootloader -> Application: Jump to primary slot
+deactivate Bootloader
+
+
+activate Application
+note right: This is the new version of the firmware
+Application -> Application: Write the valid bit in flash memory
+note right: The application should provide a way to\ncheck that it is running correctly\n(selftest, user confirmation,...)\nbefore setting the valid bit.
+Application -> Application: Normal operations...
+Application -> MCU: Reset
+deactivate Application
+
+@enduml \ No newline at end of file
diff --git a/doc/buildAndProgram.md b/doc/buildAndProgram.md
index 77fee33b..72870e3d 100644
--- a/doc/buildAndProgram.md
+++ b/doc/buildAndProgram.md
@@ -1,24 +1,24 @@
# Build
-##Dependencies
+## Dependencies
To build this project, you'll need:
- - A cross-compiler : [gcc-arm-none-eabi-8-2019-q3-update](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads/8-2019q3-update)
- - The NRF52 SDK 15.3.0 : [nRF5_SDK_15.3.0_59ac345](https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/nRF5_SDK_15.3.0_59ac345.zip)
+ - A cross-compiler : [ARM-GCC (9-2020-q2-update)](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads/9-2020-q2-update)
+ - The NRF52 SDK 15.3.0 : [nRF-SDK v15.3.0](https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/nRF5_SDK_15.3.0_59ac345.zip)
- A reasonably recent version of CMake (I use 3.16.5)
-##Build steps
-###Clone the repo
+## Build steps
+### Clone the repo
```
git clone https://github.com/JF002/Pinetime.git
cd Pinetime
mkdir build
cd build
```
-###Project generation using CMake
+### Project generation using CMake
CMake configures the project according to variables you specify the command line. The variables are:
Variable | Description | Example|
----------|-------------|--------|
-**ARM_NONE_EABI_TOOLCHAIN_PATH**|path to the toolchain directory|`-DARM_NONE_EABI_TOOLCHAIN_PATH=/home/jf/nrf52/gcc-arm-none-eabi-9-2019-q4-major/`|
+**ARM_NONE_EABI_TOOLCHAIN_PATH**|path to the toolchain directory|`-DARM_NONE_EABI_TOOLCHAIN_PATH=/home/jf/nrf52/gcc-arm-none-eabi-9-2020-q2-update/`|
**NRF5_SDK_PATH**|path to the NRF52 SDK|`-DNRF5_SDK_PATH=/home/jf/nrf52/Pinetime/sdk`|
**USE_JLINK, USE_GDB_CLIENT and USE_OPENOCD**|Enable *JLink* mode, *GDB Client* (Black Magic Probe) mode or *OpenOCD* mode (set the one you want to use to `1`)|`-DUSE_JLINK=1`
**CMAKE_BUILD_TYPE**| Build type (Release or Debug). Release is applied by default if this variable is not specified.|`-DCMAKE_BUILD_TYPE=Debug`
@@ -27,22 +27,22 @@ CMake configures the project according to variables you specify the command line
**GDB_CLIENT_TARGET_REMOTE**|Target remote connection string. Used only if `USE_GDB_CLIENT` is 1.|`-DGDB_CLIENT_TARGET_REMOTE=/dev/ttyACM0`
-####CMake command line for JLink
+#### CMake command line for JLink
```
cmake -DCMAKE_BUILD_TYPE=Debug -DARM_NONE_EABI_TOOLCHAIN_PATH=... -DNRF5_SDK_PATH=... -DUSE_JLINK=1 -DNRFJPROG=... ../
```
-####CMake command line for GDB Client (Black Magic Probe)
+#### CMake command line for GDB Client (Black Magic Probe)
```
cmake -DARM_NONE_EABI_TOOLCHAIN_PATH=... -DNRF5_SDK_PATH=... -DUSE_GDB_CLIENT=1 -DGDB_CLIENT_BIN_PATH=... -DGDB_CLIENT_TARGET_REMOTE=... ../
```
-####CMake command line for OpenOCD
+#### CMake command line for OpenOCD
```
cmake -DARM_NONE_EABI_TOOLCHAIN_PATH=... -DNRF5_SDK_PATH=... -DUSE_OPENOCD=1 -DGDB_CLIENT_BIN_PATH=[optional] ../
```
-###Build the project
+### Build the project
During the project generation, CMake created the following targets:
- FLASH_ERASE : mass erase the flash memory of the NRF52.
- FLASH_pinetime-app : flash the firmware into the NRF52.
@@ -50,7 +50,7 @@ During the project generation, CMake created the following targets:
- pinetime-mcuboot-app : build the firmware with the support of the bootloader (based on MCUBoot).
- pinetime-graphics : small firmware that writes the boot graphics into the SPI flash.
-If you just want to build the project and run it on the Pinetime, using *pinetime-app* is recommanded. See ???? for more info about bootloader support.
+If you just want to build the project and run it on the Pinetime, using *pinetime-app* is recommanded. See [this page](../bootloader/README.md) for more info about bootloader support.
Build:
```
@@ -66,8 +66,8 @@ Binary files are generated into the folder `src`:
- **pinetime-graphics.bin, .hex and .out** : firmware for the boot graphic in bin, hex and out formats.
- **pinetime-graphics.map** : map file
-###Program and run
-####Using CMake targets
+### Program and run
+#### Using CMake targets
These target have been configured during the project generation by CMake according to the parameters you provided to the command line.
Mass erase:
@@ -80,7 +80,7 @@ Flash the application:
make FLASH_pinetime-app
```
-###Using JLink
+### Using JLink
Start JLinkExe:
```
$ /opt/SEGGER/JLink/JLinkExe -device nrf52 -if swd -speed 4000 -autoconnect 1
@@ -146,7 +146,7 @@ Reset: Reset device via AIRCR.SYSRESETREQ.
J-Link>g
```
-####JLink RTT
+#### JLink RTT
RTT is a feature from Segger's JLink devices that allows bidirectionnal communication between the debugger and the target. This feature can be used to get the logs from the embedded software on the development computer.
- Program the MCU with the code (see above)
@@ -161,7 +161,7 @@ Start JLinkRTTClient
$ JLinkRTTClient
```
-###Using GDB and Black Magic Probe (BMP)
+### Using GDB and Black Magic Probe (BMP)
Enter the following command into GDB:
```
@@ -206,4 +206,4 @@ Loading section .sec6, size 0x10000 lma 0x30000
Loading section .sec7, size 0xdf08 lma 0x40000
Start address 0x0, load size 314200
Transfer rate: 45 KB/sec, 969 bytes/write.
-``` \ No newline at end of file
+```
diff --git a/doc/buildWithDocker.md b/doc/buildWithDocker.md
new file mode 100644
index 00000000..705c6d99
--- /dev/null
+++ b/doc/buildWithDocker.md
@@ -0,0 +1,33 @@
+# Build the project using Docker
+A [Docker image (Dockerfile)](../docker) containing all the build environment is available for X86_64 and AMD64 architectures. This image makes the build of the firmware and the generation of the DFU file for OTA.
+
+## Build the image
+The image is not (yet) available on DockerHub, you need to build it yourself, which is quite easy. The following commands must be run from the root of the project.
+
+If you are running on a x86_64 computer :
+```
+docker image build -t infinitime-build --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) docker/x86_64/
+```
+
+And if your are running on an ARM64 device (tested on RaspberryPi4 and Pine64 PineBookPro):
+```
+docker image build -t infinitime-build --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) docker/arm64/
+```
+
+This operation will take some time. It builds a Docker image based on Ubuntu, install some packages, download the ARM toolchain, the NRF SDK, MCUBoot and adafruit-nrfutil.
+
+When this is done, a new image named *infinitime-build* is available.
+
+## Run a container to build the project:
+
+```
+docker run --rm -v <project_root>:/sources infinitime-build
+```
+
+Replace *<project_root>* by the path of the root of the project on your computer. For example:
+
+```
+docker run --rm -v /home/jf/git/PineTime:/sources infinitime-build
+```
+
+This will start a container, build the firmware and generate the MCUBoot image and the DFU file. The output of the build is stored in **<project_root>/built/output**. \ No newline at end of file
diff --git a/doc/companionapps/Amazfish.md b/doc/companionapps/Amazfish.md
new file mode 100644
index 00000000..eb9daa04
--- /dev/null
+++ b/doc/companionapps/Amazfish.md
@@ -0,0 +1,15 @@
+# Amazfish
+[Amazfish](https://openrepos.net/content/piggz/amazfish) is a companion app that supports many smartwatches and activity trackers running on [SailfishOS](https://sailfishos.org/).
+
+## Features
+The following features are implemented:
+ - Scanning & detection of Pinetime-JF / InfiniTime
+ - Connection / disconnection
+ - Time synchronization
+ - Notifications
+ - Music control
+
+## Demo
+[This video](https://seafile.codingfield.com/f/21c5d023452740279e36/) shows how to connect to the Pinetime and control the playback of the music on the phone.
+Amazfish and Sailfish OS are running on the [Pinephone](https://www.pine64.org/pinephone/), another awesome device from Pine64.
+ \ No newline at end of file
diff --git a/doc/companionapps/Gadgetbridge.md b/doc/companionapps/Gadgetbridge.md
new file mode 100644
index 00000000..1a25069c
--- /dev/null
+++ b/doc/companionapps/Gadgetbridge.md
@@ -0,0 +1,13 @@
+# Integration with Gadgetbridge
+[Gadgetbridge](https://gadgetbridge.org/) is an Android application that supports many smartwatches and fitness trackers.
+
+The integration of InfiniTime (previously Pinetime-JF) is now merged into the master branch (https://codeberg.org/Freeyourgadget/Gadgetbridge/).
+
+## Features
+The following features are implemented:
+ - Scanning & detection of Pinetime-JF / InfiniTime
+ - Connection / disconnection
+ - Notifications
+
+## Demo
+[This video](https://seafile.codingfield.com/f/0a2920b9d765462385e4/) shows how to scan, connect, send notification (using the debug screen) and disconnect from the Pinetime.
diff --git a/doc/companionapps/NrfconnectOTA.md b/doc/companionapps/NrfconnectOTA.md
new file mode 100644
index 00000000..0fa3cd03
--- /dev/null
+++ b/doc/companionapps/NrfconnectOTA.md
@@ -0,0 +1,12 @@
+# OTA using NRFConnect
+[NRFConnect](https://www.nordicsemi.com/Software-and-tools/Development-Tools/nRF-Connect-for-mobile) is a powerful application (running on Android and iOS) which allows to scan and connect to BLE devices.
+
+## Features
+ - Scanning, connect, disconnect
+ - Time synchronization
+ - OTA
+
+InfiniTime implements the Nordic DFU protocol for the OTA functionality. NRFConnect also supports this protocol.
+
+# Demo
+[This video](https://seafile.codingfield.com/f/a52b69683a05472a90c7/) shows how to use NRFConnect to update the firmware running on the Pinetime. \ No newline at end of file
diff --git a/doc/companionapps/firmwareNoValidated.jpg b/doc/companionapps/firmwareNoValidated.jpg
new file mode 100644
index 00000000..28df7eaa
--- /dev/null
+++ b/doc/companionapps/firmwareNoValidated.jpg
Binary files differ
diff --git a/doc/companionapps/firmwareValidated.jpg b/doc/companionapps/firmwareValidated.jpg
new file mode 100644
index 00000000..0d6f99b5
--- /dev/null
+++ b/doc/companionapps/firmwareValidated.jpg
Binary files differ
diff --git a/doc/companionapps/firmwareValidationApp.jpg b/doc/companionapps/firmwareValidationApp.jpg
new file mode 100644
index 00000000..d78ad0c1
--- /dev/null
+++ b/doc/companionapps/firmwareValidationApp.jpg
Binary files differ
diff --git a/doc/contribute.md b/doc/contribute.md
index 53c6ac06..40441cd2 100644
--- a/doc/contribute.md
+++ b/doc/contribute.md
@@ -21,4 +21,24 @@ Then, you can submit a pull-request for review. Try to describe your pull reques
Other contributors can post comments about the pull request, maybe ask for more info or adjustements in the code.
-Once the pull request is reviewed an accepted, it'll be merge in **develop** and will be released in the next release version of the firmware. \ No newline at end of file
+Once the pull request is reviewed an accepted, it'll be merge in **develop** and will be released in the next release version of the firmware.
+
+# Coding convention
+## Language
+The language of this project is **C++**, and all new code must be written in C++. (Modern) C++ provides a lot of useful tools and functionalities that are beneficial for embedded software development like `constexpr`, `template` and anything that provides zero-cost abstraction.
+
+It's OK to include C code if this code comes from another library like FreeRTOS, NimBLE, LVGL or the NRF-SDK.
+
+## Coding style
+The most important rule to follow is to try to keep the code as easy to read and maintain as possible.
+
+ - **Identation** : 2 spaces, no tabulation
+ - **Opening brace** at the end of the line
+ - **Naming** : Choose self-describing variable name
+ - **class** : PascalCase
+ - **namespace** : PascalCase
+ - **variable** : camelCase, **no** prefix/suffix ('_', 'm_',...) for class members
+ - **Include guard** : `#pragma once` (no `#ifdef __MODULE__ / #define __MODULE__ / #endif`)
+ - **Includes** :
+ - files from the project : `#include "relative/path/to/the/file.h"`
+ - external files and std : `#include <file.h>` \ No newline at end of file
diff --git a/doc/filesInReleaseNotes.md b/doc/filesInReleaseNotes.md
index e9dadb24..2fdfadf4 100644
--- a/doc/filesInReleaseNotes.md
+++ b/doc/filesInReleaseNotes.md
@@ -18,7 +18,7 @@ This firmware is standalone, meaning that it does not need a bootloader to actua
**This firmware must be flashed at address 0x00 in the main flash memory**
### Bootloader
-The bootloader is maintained by [lupyuen](https://github.com/lupyuen) and is a binary version of [this release](https://github.com/lupyuen/pinetime-rust-mynewt/releases/tag/v4.1.7).
+The bootloader is maintained by [lupyuen](https://github.com/lupyuen) and is a binary version of [this release](https://github.com/lupyuen/pinetime-rust-mynewt/releases/tag/v5.0.4).
- **bootloader.hex** : Firmware in Intel HEX file format.
@@ -42,7 +42,7 @@ This firmware is intended to be used with our [MCUBoot-based bootloader](../boot
The following files are not directly usable by the bootloader:
- - **pinetime-mcuboot-app.bin** : Output file of GCC containing debug symbols, useful is you want to debug the firmware using GDB.
+ - **pinetime-mcuboot-app.out** : Output file of GCC containing debug symbols, useful is you want to debug the firmware using GDB.
- **pinetime-mcuboot-app.hex** : Firmware in Intel HEX file format.
- **pinetime-mcuboot-app.bin** : Firmware in binary format.
- **pinetime-mcuboot-app.map** : Map file containing all the symbols, addresses in memory,...
diff --git a/doc/openOCD.md b/doc/openOCD.md
new file mode 100644
index 00000000..a199bd7a
--- /dev/null
+++ b/doc/openOCD.md
@@ -0,0 +1,105 @@
+# OpenOCD and STLink
+OpenOCD (**Open O**n **C**hip **D**ebugger) is an open source tool that interfaces with many SWD/JTAG debugger to provide debugging and *in-system* programming for embedded target devices.
+
+It supports the **NRF52** (the CPU of the PineTime) and the **STLinkV2**, a cheap SWD debugger.
+
+It works on X86 computers, as well as ARM/ARM64 computers and SBC (like the RaspberryPi and Pine64 Pinebook Pro) !
+
+## Installation
+We will build OpenOCD from sources, as packages from Linux distributions are most of the time outdated and do not support the NRF52 correctly.
+
+ - Fetch the sources from GIT, and build and install it:
+
+```
+git clone https://git.code.sf.net/p/openocd/code openocd-code
+
+cd openocd-code
+
+./bootstrap
+./configure --enable-stlink
+make -j 4
+sudo make install
+```
+
+ - Configure UDEV to allow OpenOCD to open the interface to your STLinkV2:
+```
+sudo cp contrib/60-openocd.rules /etc/udev/rules.d/
+sudo udevadm control --reload-rules
+```
+
+ - You can now plug your STLinkV2 in a USB port and run OpenOCD to see if it's working correctly:
+
+```
+$ openocd -f interface/stlink.cfg -f target/nrf52.cfg
+Open On-Chip Debugger 0.10.0+dev-01411-g051e80812-dirty (2020-09-28-20:16)
+Licensed under GNU GPL v2
+For bug reports, read
+ http://openocd.org/doc/doxygen/bugs.html
+Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
+Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
+
+nRF52 device has a CTRL-AP dedicated to recover the device from AP lock.
+A high level adapter (like a ST-Link) you are currently using cannot access
+the CTRL-AP so 'nrf52_recover' command will not work.
+Do not enable UICR APPROTECT.
+
+Info : Listening on port 6666 for tcl connections
+Info : Listening on port 4444 for telnet connections
+Info : clock speed 1000 kHz
+Info : STLINK V2J34S7 (API v2) VID:PID 0483:3748
+Info : Target voltage: 3.294340
+Error: init mode failed (unable to connect to the target)
+```
+Ok, OpenOCD is running and it detects my STLinkV2. The last error shows that I've not connected the STLinkV2 to the PineTime.
+
+## Configuration files
+OpenOCD is configured using configuration files.
+First, we need a common configuration file for the project : **openocd-stlink.ocd**:
+```
+source [find interface/stlink.cfg]
+
+gdb_flash_program enable
+gdb_breakpoint_override hard
+
+source [find target/nrf52.cfg]
+```
+This file specifies to OpenOCD which debugger and target it will be connected to..
+
+Then, we use various *user files* to use OpenOCD to flash InfiniTime binary files.
+
+This files flashes the bootloader and the application firmware : **flash_bootloader_app.ocd**:
+```
+init
+
+program <build directory>/bootloader.bin verify 0x00000000
+program <build directory>/image-0.8.2.bin verify 0x00008000
+
+reset
+```
+
+And this one flashes the graphics flasher (it writes the bootloader graphics into the SPI NOR flash memory) : **flash_graphics.ocd**:
+```
+init
+
+program <build directory>/pinetime-graphics-0.8.2.bin verify 0x00000000
+
+reset
+```
+
+## Examples
+### Flash bootloader and application
+```
+openocd -f ./openocd-stlink.cfg -f ./flash_bootloader_app.ocd
+```
+
+### Flash graphics flasher
+```
+openocd -f ./openocd-stlink.cfg -f ./flash_graphics.ocd
+```
+
+## Connect the STLinkV2 to the PineTime
+Here is an example using the pogo pins:
+![SWD pinout](../images/swd_pinout.jpg)
+![Pogo pins](../images/pogopins.jpg)
+
+You can find more information about the SWD wiring [on the wiki](https://wiki.pine64.org/index.php?title=PineTime_devkit_wiring). \ No newline at end of file