#!/bin/bash

if [ $# -ne 2 ] ; then
  echo 'usage: generate_spi_slave_image IMG.BIN APP.XE'
  exit 2
fi

if ! which xobjdump >/dev/null ; then
  echo 'XMOS tools not set up'
  exit 2
fi

tmpdir=/tmp/_generate_spi_slave_image_tmp_dir
mkdir -p ${tmpdir}

cp "$2" ${tmpdir}/a.xe
out="$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
cd ${tmpdir}
xobjdump --strip a.xe >/dev/null
xobjdump --split a.xe >/dev/null
xobjdump --split a.xb >/dev/null

pll_ctl=`xobjdump --resources a.xe | grep PLL | cut -d= -f2`
ref_clk_divider=`xobjdump --resources a.xe | grep reference | cut -d= -f2`
direction0=`xobjdump -D a.xe | grep dirBits0 -A1 | grep 0x | cut -d: -f2 | sed 's/ //g' | sed 's/\(..\)\(..\)\(..\)\(..\)/0x\4\3\2\1/'`
direction1=`xobjdump -D a.xe | grep dirBits1 -A1 | grep 0x | cut -d: -f2 | sed 's/ //g' | sed 's/\(..\)\(..\)\(..\)\(..\)/0x\4\3\2\1/'`

nb0=`wc -c < image_n0c0_2.bin`
nb1=`wc -c < image_n0c1_2.bin`

if [ $(($nb0 % 4)) -ne 0 -o $(($nb1 % 4)) -ne 0 ] ; then
  echo "application bin size must be word aligned"
  exit 1
fi

nw0=$(($nb0 / 4))
nw1=$(($nb1 / 4))

echo "SPI size (1w) + tile 0 image (${nw0}w) + tile 1 image (${nw1}w) + CRC (1w) = $((($nw0 + $nw1) * 4 + 8)) bytes"

function int_to_binary()
{
  printf '0: %.2x%.2x%.2x%.2x\n' $(($1 & 0xff)) $((($1 >> 8) & 0xff)) $((($1 >> 16) & 0xff)) $((($1 >> 24) & 0xff)) | xxd -r
}

function hex_to_binary()
{
  int_to_binary `echo "obase=10;ibase=16;$(echo $1 | tr '[a-z]' '[A-Z]' | sed s/0X//)" | bc -q`
}

int_to_binary $(($nw0 + $nw1)) > spi_size
int_to_binary $nw0 > custom_header
int_to_binary $nw1 >> custom_header
hex_to_binary $pll_ctl >> custom_header
hex_to_binary $ref_clk_divider >> custom_header
hex_to_binary $direction0 >> custom_header
hex_to_binary $direction1 >> custom_header
hex_to_binary 0x0D15AB1E > crc_disable_magic

cp image_n0c0_2.bin tile0_patched
cat custom_header | dd conv=notrunc bs=1 seek=4 of=tile0_patched 2>/dev/null
cat spi_size tile0_patched image_n0c1_2.bin crc_disable_magic > "$out"
