Skip to content
Browse files

boards: intel_s1000_crb: Image download scripts

Python scripts to download a zephyr binary image (zephyr.bin) to
Intel S1000 from a linux host.
The linux host's SPI master and GPIOs shall be connected to the
corresponding SPI slave and I/Os respectively.

Signed-off-by: Sathish Kuttan <>
  • Loading branch information...
sathishkuttan authored and nashif committed May 21, 2019
1 parent d714f64 commit 8075de7b94162e91ca584a1511a2937c84937329
@@ -0,0 +1,124 @@
#!/usr/bin/env python3
# Copyright (c) 2019 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
# Author: Sathish Kuttan <>

# This file defines device class that contains functions to
# setup/cconfigure SPI master device and GPIO pins required
# to communicate with the target.
# Member functions are provided to send and receive messages
# over the SPI bus

import yaml
import time
import periphery
import sys
import os

class Device:
Device class containing the interface methods for communicating
with the target using SPI bus and GPIOs
def __init__(self):
Read config file and determine the SPI device, speed, mode
GPIO pin assignments, etc.
Initialize data structures accordingly.
config_file = os.path.dirname(__file__)
config_file += '/config.yml'
with open(config_file, 'r') as ymlfile:
config = yaml.safe_load(ymlfile) = config['general']['name']
self.spi_device = config['spi']['device']
self.spi_speed = config['spi']['max_speed']
self.spi_mode = None
self.gpio_reset = config['gpio']['reset']
self.gpio_wake = config['gpio']['wake']
self.gpio_irq = config['gpio']['irq']
self.spi = None
self.reset_pin = None
self.wake_pin = None
self.irq_pin = None

def print_config(self):
Print configuration information that was read from config file
print('%s Device on %s' %(, self.spi_device))
print('Max SPI Frequency: %2.1f MHz' % self.spi_speed)
print('Reset GPIO: %d' % self.gpio_reset)
print('Wake GPIO : %d' % self.gpio_wake)
print('IRQ GPIO : %d' % self.gpio_irq)

def configure_device(self, spi_mode, order, bits):
Configure the SPI device and GPIOs for communication with target
self.reset_pin = periphery.GPIO(self.gpio_reset, 'out')
self.wake_pin = periphery.GPIO(self.gpio_wake, 'out')
self.irq_pin = periphery.GPIO(self.gpio_irq, 'in')
self.spi = periphery.SPI(self.spi_device, spi_mode,
self.spi_speed * 1e6)
self.spi.bit_order = order
self.spi.bits_per_word = bits
print('Configured SPI %s for %s.' % (self.spi_device,
print('Configured GPIO %d for %s Reset.' % (self.gpio_reset,
print('Configured GPIO %d for %s Wake.' % (self.gpio_wake,
print('Configured GPIO %d for %s IRQ.' % (self.gpio_irq,

def check_device_ready(self):
Check whether the target is ready to accept a command as follows:
Wait a minimum time and check whether IRQ is asserted by the target
If IRQ is not asserted, wait maximum time and check again.
Device is ready if IRQ is asserted
min_wait = 0.001 # 1 ms
max_wait = 0.1 # 100 ms
ready =
if ready == False:
ready =
if ready == False:
print('Error: Device not ready', file=sys.stderr)
return ready

def reset_device(self):
Assert the GPIO and deassert after a short duration to reset
the target.
print('Resetting %s ...' %

def send_receive(self, data, wait = True):
Transmit and receive full duplex data over SPI
If requested to wait, wait for device to become ready
before return.
rx_data = self.spi.transfer(data)
if wait == True:
return rx_data

def send_bulk(self, data):
Send a byte stream of data without checking for device readiness.

def close(self):
Close the device handle
@@ -0,0 +1,133 @@
#!/usr/bin/env python3
# Copyright (c) 2019 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
# Author: Sathish Kuttan <>

# This script is the top level script that an user can invoke to
# download a Zephyr application binary from a Linux host connected
# over SPI to Intel Sue Creek S1000 target during development.

import os
import sys
import hashlib
import device
import messenger

sue_creek = device.Device()
msg = messenger.Message()

def check_arguments():
Check whether file name is provided.
If not print usage instruction and exit.
if len(sys.argv) != 2:
print('Usage: python3 %s <zephyr.bin>' % sys.argv[0])
return sys.argv[1]

def calc_firmware_sha(file):
Open firmware image file and calculate file size
Pad file size to a multiple of 64 bytes
Caculate SHA256 hash of the padded contents
with open(file, 'rb') as firmware:, 2)
size = firmware.tell()

# pad firmware to round upto 64 byte boundary
padding = (size % 64)
if padding != 0:
padding = (64 - padding)
size += padding, 0)
sha256 = hashlib.sha256()
for block in iter(lambda:, b""):

if padding != 0:
sha256.update(b'\0' * padding)
print('Firmware (%s): %d bytes, will be padded to %d bytes.'
% (os.path.basename(file), size - padding, size))
print('Firmware file size: %d bytes.' % size)
print('SHA: ' + sha256.hexdigest())
return (size, padding, sha256.digest())

def setup_device():
Configure SPI master device
Reset target and send initialization commands
sue_creek.configure_device(spi_mode = 3, order = 'msb', bits = 8)

command = msg.create_memwrite_cmd((0x71d14, 0, 0x71d24, 0,
0x304628, 0xd, 0x71fd0, 0x3))
response = sue_creek.send_receive(command)

def load_firmware(file, size, padding, sha):
Send command to load firmware
Transfer binary file contents including padding
command = msg.create_loadfw_cmd(size, sha)
response = sue_creek.send_receive(command)

with open(file, 'rb') as firmware:, 0)
block_size = msg.get_bulk_message_size()
transferred = 0
for block in iter(lambda:, b""):
if len(block) < block_size:
block += b'\0' * padding
bulk_msg = msg.create_bulk_message(block)
transferred += len(bulk_msg)
sys.stdout.write('\r%d of %d bytes transferred to %s.'
% (transferred, size,


command = msg.create_null_cmd()
response = sue_creek.send_receive(command)

def execute_firmware():
Send command to start execution
command = msg.create_memwrite_cmd((0x71d10, 0, 0x71d20, 0))
response = sue_creek.send_receive(command)

command = msg.create_execfw_cmd()
response = sue_creek.send_receive(command, wait = False)

def main():
Check arguments to ensure binary file is provided.
Calculate SHA of the binary image
Setup the SPI master device and GPIOs on the host
Download Firmware
file = check_arguments()
(size, padding, sha) = calc_firmware_sha(file)
load_firmware(file, size, padding, sha)

if __name__ == '__main__':

0 comments on commit 8075de7

Please sign in to comment.
You can’t perform that action at this time.