Backpack Board Usage Guide

Introduction

BACKPACK (V1.1) Board is built to extend the functionality of the SyncSign D75R e-ink display.

With BACKPACK, Developers will be able to design their own communication module, decide how to fetch the information, and when to show them on the e-ink screen.

The BACKPACK should contain batteries and serve as a power source. It will communicate with the CPU on the D75R via a standard UART port.

Board Layout

../_images/backpack_board.png

Board Description

Developers may design their own Extension Module and install it onto the BACKPACK board. By this way, the Extension Module will decide what to render on the e-ink screen, then control the power of D75R, and send the data over UART port.

As a demonstration, the BACKPACK provides a micro USB port. Please connect it to a host computer and install the CP2102 driver. Then, your computer will serve as the same function of the Extension Module.

../_images/backpack_chart.png

Demonstration & Test

Prepare (hardware)

  • Set the SW2 to OFF

  • Install all the jumpers on J10

  • Connect the USB cable to host computer

Prepare (software)

  • Better to use a host computer which runs Mac/Linux, or WSL of Windows

  • Install the Python3 interpreters

  • Install the pip3 tool

  • Install the python library: pip3 install pyserial

  • Connect the USB port to your Linux/Mac host (You may required to install the CP2102 driver)

  • Check the serial port, e.g., /dev/ttyS1, /dev/SLAB_USBtoUART and modify the define in the example code

Test Procedure

  • Run the example.py: python3 example.py

  • When you see: [ MANUAL OPERATION ]: Control target power as ON now. Please switch the SW2 to ON

  • The D75R will send “HELLO” and “READDATA” to example.py

  • Then the example.py will send the render document to D75R, you should notice the e-ink screen is refreshing to the new content.

  • The D75R will send “BYE” when it’s done

  • Set the SW2 to OFF to turn off the power of D75R

Build Your Extension Module

The Extension Module should contain:

  • A MCU/CPU which can run in low power mode

  • A communication module, e.g. NB-IoT, LTE-M(eMTC).

  • A DC/DC, convert input from 5V/6V to a required voltage of extension module

Prepare the BACKPACK:

  • Set the SW2 to OFF

  • Remove all the jumpers on J10

  • Install 4 x AA batteries

  • Disconnect the USB cable to host computer

  • Install your Extension Module onto J5 & J9

Design of software:

  • When the Extension Module receives the screen data, it should turn on the power of the D75R (Just like switch the SW2 to on) by setting the CTRL-POWER pin to high level

  • Then, wait for the D75R sends HELLO and READDATA command

  • The Extension Module sends the render document to the D75R and wait for it completes the rendering. Then set the CTRL-POWER to low level

  • Note: the serial communication use SLIP protocol, please see buildSlipPacket() in example.py

Attachments

Circuit Schematic:

../_images/d75r_backpack_v1.1_schematic.png

Example Code:

'''
**** SyncSign Backpack Testing ****

This is a demo code runs on Linux/Mac.

Prepare:
1. Connect the USB port to your Linux/Mac host (You may required to install the CP2102 driver)
2. Check the serial port, e.g., /dev/ttyS1, /dev/SLAB_USBtoUART and modify the define in the code
3. Install the python library: `pip3 install pyserial`

How to test:
1. Manually set the power pin to HIGH on the demo board, then
2. `python3 example.py`
'''

import serial
import binascii
import struct

UARTPORT = '/dev/cu.SLAB_USBtoUART'

ser = None
CHECKSUM_MAGIC      = 0xEF

SS_HELLO            = 0xA0
SS_BYEBYE           = 0xA1
SS_READ_DATA        = 0x3F

layoutDocument = u"""
{
"items": [
    {
    "type": "TEXT",
    "data": {
        "text": "HELLO WORLD",
        "font": "YANONE_KAFFEESATZ_44_B",
        "block": { "x": 24, "y": 30, "w": 496, "h": 60 }
    }
    }
]
}
"""

""" Calculate checksum of a blob """
def checksum(data, state=CHECKSUM_MAGIC):
    for b in data:
        if type(b) is int:  # python 2/3 compat
            state ^= b
        else:
            state ^= ord(b)
    return state

def buildSlipPacket(cmd=None, data=b""):
    chk = checksum(data)
    packet = struct.pack(b'<BBHI', 0x01, cmd, len(data), chk) + data
    buf = b'\xc0' \
            + (packet.replace(b'\xdb',b'\xdb\xdd').replace(b'\xc0',b'\xdb\xdc')) \
            + b'\xc0'
    return buf

def readOnePacket():
    cachedData = b""
    packetReceived = bytearray()
    startReceived = False
    while not packetReceived:
        b = ser.read()          # read one byte (timeout)
        if b == b'\xc0':
            if not startReceived:
                startReceived = True
            else:
                packetReceived[:] = cachedData
        elif startReceived:
            cachedData += b
    return packetReceived

def powerCtrl(on):
    print("[ MANUAL OPERATION ]: Control target power as", "ON" if on else "OFF", "now.")

def run():
    global ser
    ser = serial.Serial(UARTPORT, 115200, timeout=1)
    powerCtrl(True)
    print('waiting for HELLO command')
    data = readOnePacket()
    if data == b'\x00\xa0\x00\x00\xef\x00\x00\x00':
        print("    >>> HELLO command received")
        ser.write(buildSlipPacket(SS_HELLO)) # say HELLO
        print('waiting for READDATA command')
        data = readOnePacket()
        if data == b'\x00\x3f\x00\x00\xef\x00\x00\x00':
            print("    >>> READDATA command received")
            ser.write(buildSlipPacket(SS_READ_DATA, bytes(layoutDocument, "utf-8"))) # say HELLO
            print('waiting for BYE command')
            data = readOnePacket()
            if data == b'\x00\xa1\x08\x00\xef\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff':
                print("    >>> BYE command received")
                powerCtrl(False)

if __name__ == '__main__':
    run()

Example Code:

  • calc_checksum.py

CHECKSUM_MAGIC      = 0xEF

""" Calculate checksum of a blob """
def checksum(data, state=CHECKSUM_MAGIC):
    for b in data:
        if type(b) is int:  # python 2/3 compat
            state ^= b
        else:
            state ^= ord(b)
    return state


data = b'1234567890\xFF'
print(hex(checksum(data)))
  • calc_checksum.c

#include <stdint.h>
#include <stdio.h>
#define CHECKSUM_MAGIC 0xEF

// Calculate checksum of a blob
uint8_t checksum(uint8_t *data, uint32_t len)
{
    uint8_t state = CHECKSUM_MAGIC;
    for (int i=0; i<len; i++) {
        state ^= data[i];
    }
    return state;
}

int main()
{
    uint8_t data[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0xFF };
    printf("0x%X\n", checksum(data, sizeof(data)));
}