diff --git a/fmcbridge/autosave_logs.sh b/fmcbridge/autosave_logs.sh new file mode 100644 index 0000000..9536a10 --- /dev/null +++ b/fmcbridge/autosave_logs.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +SCRIPT_DIR="$(readlink -f $(dirname $0))" + +source $SCRIPT_DIR/lib/utils.sh + +JIG_NAME="$(jigname)" + +while true ; do + + # take the first `autosave_logs` folder + dir=$(sudo find /media -type d -name SAVE_LOGS | head -1) + [ -z "$dir" ] || { + FILENAME="${dir}/${JIG_NAME}.$(date +%Y-%m-%d_%H-%M).tar.gz" + save_logfiles_to "$SCRIPT_DIR/log" "$FILENAME" &> /dev/null + pushd ${dir} &> /dev/null + # keep only 5 files + rm -f $(ls -1t . | tail -n +6) + popd &> /dev/null + sync &> /dev/null + sleep 60 + } + + sleep 5 +done diff --git a/fmcbridge/config.sh b/fmcbridge/config.sh new file mode 100644 index 0000000..f86970e --- /dev/null +++ b/fmcbridge/config.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +#----------------------------------# +# Global definitions section # +#----------------------------------# + +source $SCRIPT_DIR/vars.sh + +#----------------------------------# +# Utils # +#----------------------------------# +source $SCRIPT_DIR/lib/utils.sh + +enforce_root diff --git a/fmcbridge/init.sh b/fmcbridge/init.sh new file mode 100755 index 0000000..c01a3b6 --- /dev/null +++ b/fmcbridge/init.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# Wrapper script for initializing the board to a known/sane state. +# Requires sudo. +# +# Can be called with: ./init.sh +# + +SCRIPT_DIR="$(readlink -f $(dirname $0))" + +source $SCRIPT_DIR/config.sh diff --git a/fmcbridge/lib/failed.ascii b/fmcbridge/lib/failed.ascii new file mode 100644 index 0000000..64fa91c --- /dev/null +++ b/fmcbridge/lib/failed.ascii @@ -0,0 +1,8 @@ + +███████╗ █████╗ ██╗██╗ ███████╗██████╗ +██╔════╝██╔══██╗██║██║ ██╔════╝██╔══██╗ +█████╗ ███████║██║██║ █████╗ ██║ ██║ +██╔══╝ ██╔══██║██║██║ ██╔══╝ ██║ ██║ +██║ ██║ ██║██║███████╗███████╗██████╔╝ +╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚═════╝ + diff --git a/fmcbridge/lib/passed.ascii b/fmcbridge/lib/passed.ascii new file mode 100644 index 0000000..f18e907 --- /dev/null +++ b/fmcbridge/lib/passed.ascii @@ -0,0 +1,8 @@ + +██████╗ █████╗ ███████╗███████╗███████╗██████╗ +██╔══██╗██╔══██╗██╔════╝██╔════╝██╔════╝██╔══██╗ +██████╔╝███████║███████╗███████╗█████╗ ██║ ██║ +██╔═══╝ ██╔══██║╚════██║╚════██║██╔══╝ ██║ ██║ +██║ ██║ ██║███████║███████║███████╗██████╔╝ +╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═════╝ + diff --git a/fmcbridge/lib/production.sh b/fmcbridge/lib/production.sh new file mode 100644 index 0000000..c228969 --- /dev/null +++ b/fmcbridge/lib/production.sh @@ -0,0 +1,224 @@ +#!/bin/bash + +source $SCRIPT_DIR/config.sh + +#----------------------------------# +# Functions section # +#----------------------------------# + +show_ready_state() { + PROGRESS=0 + READY=1 +} + +show_start_state() { + PASSED=0 + READY=0 + FAILED=0 + PROGRESS=1 +} + +get_board_serial() { + BOARD_SERIAL=$(ssh_cmd "dmesg | grep SPI-NOR-UniqueID | cut -d' ' -f9 | tr -d '[:cntrl:]'") +} + +get_fmcomms_serial() { + BOARD_SERIAL=$(ssh_cmd "fru-dump -i /sys/devices/platform/amba/ff030000.i2c/i2c-1/i2c-8/8-0052/eeprom -b | grep 'Serial Number' | cut -d' ' -f3 | tr -d '[:cntrl:]'") +} + +dut_date_sync() { + CURR_DATE="@$(date +%s)" + ssh_cmd "sudo date -s '$CURR_DATE'" +} + +handle_error_state() { + local serial="$1" + FAILED=1 + inc_fail_stats "$serial" + console_ascii_failed + if [ -n "$serial" ] ; then + cat "$LOGFILE" > "$LOGDIR/failed_${serial}_${RUN_TIMESTAMP}.log" + else + cat "$LOGFILE" > "${ERRORSFILE}_${RUN_TIMESTAMP}" + fi + cat /dev/null > "$LOGFILE" +} + +need_to_read_eeprom() { + [ "$FAILED" == "1" ] || ! have_eeprom_vars_loaded +} + +inc_fail_stats() { + local serial="$1" + let FAILED_CNT='FAILED_CNT + 1' + echo "PASSED_CNT=$PASSED_CNT" > $STATSFILE + echo "FAILED_CNT=$FAILED_CNT" >> $STATSFILE + [ -z "$serial" ] || echo "FAILED $serial" >> $RESULTSFILE +} + +inc_pass_stats() { + local serial="$1" + let PASSED_CNT='PASSED_CNT + 1' + echo "PASSED_CNT=$PASSED_CNT" > $STATSFILE + echo "FAILED_CNT=$FAILED_CNT" >> $STATSFILE + echo "PASSED $serial" >> $RESULTSFILE + console_ascii_passed +} + +console_ascii_passed() { + echo_green "$(cat $SCRIPT_DIR/lib/passed.ascii)" +} + +console_ascii_failed() { + echo_red "$(cat $SCRIPT_DIR/lib/failed.ascii)" +} + +wait_for_eeprom_vars() { + DONT_SHOW_EEPROM_MESSAGES=1 + if need_to_read_eeprom ; then + echo_green "Loading settings from EEPROM" + eeprom_cfg load || { + echo_red "Failed to load settings from EEPROM." + echo_red "Plug in a board with EEPROM vars configured to continue..." + echo + } + while ! eeprom_cfg load &> /dev/null ; do + sleep 1 + continue + done + show_eeprom_vars + fi +} + +wait_for_firmware_files() { + local target="$1" + local ver_file="$SCRIPT_DIR/release/$target/version" + FW_VERSION="$(cat $ver_file)" + if ! have_all_firmware_files "$target" || [ -z "$FW_VERSION" ] ; then + echo_red "Firmware files not found, please add them to continue..." + while ! have_all_firmware_files "$target" || [ ! -f "$ver_file" ] + do + sleep 1 + done + fi + FW_VERSION="$(cat $ver_file)" +} + +check_conn(){ + while true; do + if ping -q -c3 -w50 analog.local &>/dev/null + then + echo_blue "Connection to DUT OK" + break + else + echo_red "Check ethernet connection to DUT" + fi + done +} + +start_gps_spoofing(){ + local GPSDIR=$SCRIPT_DIR/src/gps-sdr-sim/player + if ping -q -c2 pluto.local &>/dev/null + then + [ -d $GPSDIR ] || return 1 + pushd $GPSDIR + ./plutoplayer -t ../gpssim.bin -a -60 &>/dev/null & + popd + else + echo_red "Pluto GPS spoofer not connected to PI." + return 1 + fi +} + +stop_gps_spoofing(){ + pkill plutoplayer &>/dev/null +} + +#----------------------------------# +# Main section # +#----------------------------------# + +production() { + local TARGET="$1" + local MODE="$2" + local IIO_REMOTE=analog.local + + [ -n "$TARGET" ] || { + echo_red "No target specified" + return 1 + } + local target_upper=$(toupper "$TARGET") + + # State variables; are set during state transitions + local PASSED=0 + local FAILED=0 + local READY=0 + local PROGRESS=0 + + # This will store in a `log` directory the following files: + # * _results.log - each device that has passed or failed with S/N + # they will only show up here if they got a S/N, so this assumes + # that flashing worked + # * _errors.log - all errors that don't yet have a S/N + # * _stats.log - number of PASSED & FAILED + + local LOGDIR=$SCRIPT_DIR/log + # temp log to store stuff, before we know the S/N of device + local LOGFILE=$LOGDIR/temp.log + # errors that cannot be mapped to any device (because no S/N) + local ERRORSFILE=$LOGDIR/_errors.log + # stats ; how many passes/fails + local STATSFILE=$LOGDIR/_stats.log + # format is " = OK/FAILED" + local RESULTSFILE=$LOGDIR/_results.log + + # Remove temp log file start (if it exists) + rm -f "$LOGFILE" + + mkdir -p $LOGDIR + exec &> >(tee -a "$LOGFILE") + + sync + + # TBD ready state - connection, other settings + + RUN_TIMESTAMP="$(date +"%Y-%m-%d_%H-%M-%S")" + + case $MODE in + "ADRV Carrier Test") + $SCRIPT_DIR/adrv_crr_test/test_usb_periph.sh && + $SCRIPT_DIR/adrv_crr_test/test_uart.sh && + ssh_cmd "sudo /home/analog/adrv_crr_test/crr_test.sh" + if [ $? -ne 0 ]; then + handle_error_state "$BOARD_SERIAL" + fi + ;; + "ADRV SOM Test") + ssh_cmd "sudo /home/analog/adrv_som_test/som_test.sh" + if [ $? -ne 0 ]; then + handle_error_state "$BOARD_SERIAL" + fi + ;; + "ADRV FMCOMMS8 RF test") + ssh_cmd "sudo /home/analog/adrv_fmcomms8_test/fmcomms8_test.sh" + RESULT=$? + get_fmcomms_serial + python3 -m pytest --color yes $SCRIPT_DIR/work/pyadi-iio/test/test_adrv9009_zu11eg_fmcomms8.py -v + if [ $? -ne 0 ] || [ $RESULT -ne 0 ]; then + handle_error_state "$BOARD_SERIAL" + fi + ;; + *) echo "invalid option $MODE" ;; + esac + + if [ -f "$STATSFILE" ] ; then + source $STATSFILE + fi + + if [ "$FAILED" == "0" ] ; then + inc_pass_stats "$BOARD_SERIAL" + cat "$LOGFILE" > "$LOGDIR/passed_${BOARD_SERIAL}_${RUN_TIMESTAMP}.log" + cat /dev/null > "$LOGFILE" + fi +} + diff --git a/fmcbridge/lib/test_util.sh b/fmcbridge/lib/test_util.sh new file mode 100644 index 0000000..60f4662 --- /dev/null +++ b/fmcbridge/lib/test_util.sh @@ -0,0 +1,99 @@ +#!/bin/bash + +RED='\033[0;31m\033[1m' +GREEN='\033[0;32m\033[1m' +NC='\033[0m' + +TIMED_LOG_SUFFIX="" +function date_time() { +echo $(date --iso-8601=seconds) +} + +function timed_log() { + +timestamp=$(date_time) +echo -e [ $timestamp ] -- $TIMED_LOG_SUFFIX - $1 + +} + +function timed_log_no_newline() { + +timestamp=$(date_time) +echo -n -e [ $timestamp ] -- $TIMED_LOG_SUFFIX - $1 +} + +function YES_no() { +if [ -z "$1" ] +then + str="Are you sure ?" +else + str="$1" +fi +timed_log_no_newline "$str" +read -r -p "[Y/n]" response +case "$response" in + [nN][oO]|[nN]) + return 1 + ;; + *) + return 0 + ;; +esac +} + +function wait_enter() { +read -r -p "Press Enter when ready" +} + +function proceed_if_ok() { +if [ -z "$1" ] +then + echo "NO PARAM" + return +fi + +if [ $1 -ne 0 ] +then + if [ -z "$2" ] + then + str="An error occurred" + else + str=$2 + fi + timed_log "$str" +fi +if [ -n "$3" ] && [ $1 -eq 0 ] +then + timed_log "$3" +fi +} + +function run_test() { # params test_number short_desc test_cmd not_retest +TIMED_LOG_SUFFIX=$TEST_NAME"_"$1 +timed_log "$2" +eval "$3" +answer=$? + +if [ "$answer" -ne 0 ] && [ -z "$4" ] +then + until [ "$answer" -eq 0 ] + do + YES_no "${RED}TEST FAILED${NC} - Do you want to repeat test?" + if [ $? -eq 1 ] + then + YES_no "Do you want to close the test?" + if [ $? -eq 0 ] + then + exit 1 + else + break + fi + fi + eval "$3" + answer=$? + done + +fi + +proceed_if_ok $answer "${RED}FAIL${NC}" "${GREEN}OK${NC}" +} diff --git a/fmcbridge/lib/utils.sh b/fmcbridge/lib/utils.sh new file mode 100644 index 0000000..58ff3d1 --- /dev/null +++ b/fmcbridge/lib/utils.sh @@ -0,0 +1,433 @@ +#!/bin/bash + +#----------------------------------# +# Global definitions section # +#----------------------------------# + +LD_LIBRARY_PATH="$SCRIPT_DIR/work/libiio/build" +export LD_LIBRARY_PATH + +PATH="$SCRIPT_DIR/work/:$PATH" +export PATH + +export LC_ALL="C.UTF-8" + +#----------------------------------# +# Functions section # +#----------------------------------# + +echo_red() { printf "\033[1;31m$*\033[m\n"; } +echo_green() { printf "\033[1;32m$*\033[m\n"; } +echo_blue() { printf "\033[1;34m$*\033[m\n"; } + +__retry_common() { + while [ "$retries" -gt 0 ] ; do + # run the commands + $@ + [ "$?" == "0" ] && return 0 + [ -z "$failfunc" ] || $failfunc + echo_blue " Retrying command ($retries): $@" + sleep 1 + let retries='retries - 1' + done + echo_red "Command failed after $r1 retries: $@" + return 1 +} + +retry() { + local retries="$1" + local r1="$retries" + shift + __retry_common $@ +} + +retry_and_run_on_fail() { + local retries="$1" + local failfunc="$2" + shift + shift + __retry_common $@ +} + +is_ft4232h() { + lsusb -v -d 0456:f001 &> /dev/null +} + +tolower() { + echo "$1" | tr A-Z a-z +} + +toupper() { + echo "$1" | tr a-z A-Z +} + +valid_ftdi_channel() { + local channel="$(toupper $1)" + for chan in A B C D GPIO_EXP1 ; do + [ "$chan" == "$channel" ] && return 0 + done + return 1 +} + +pin_ctrl() { + local lockfile="/tmp/pin_ctrl_lock" + ( + flock -e 200 + ft4232h_pin_ctrl $@ + ) 200>$lockfile +} + +toggle_pins() { + local channel="$(toupper $1)" + valid_ftdi_channel "$channel" || return 1 + shift + if [ "$channel" == "GPIO_EXP1" ] ; then + pin_ctrl --channel B \ + --serial "$FT4232H_SERIAL" \ + --mode spi-gpio-exp $@ + return $? + fi + pin_ctrl --mode bitbang \ + --serial "$FT4232H_SERIAL" \ + --channel "$channel" $@ +} + +wait_pins() { + local channel="$1" + valid_ftdi_channel "$channel" || return 1 + shift + pin_ctrl --mode wait-gpio \ + --serial "$FT4232H_SERIAL" \ + --channel "$channel" $@ +} + +power_cycle_sleep() { + [ -z "$POWER_CYCLE_DELAY" ] || \ + sleep "$POWER_CYCLE_DELAY" +} + +disable_all_usb_ports() { + toggle_pins A # will set all pins to low +} + +enable_all_usb_ports() { + toggle_pins A pin5 pin6 +} + +enable_usb_data_port() { + toggle_pins A pin5 +} + +enable_usb_power_port() { + toggle_pins A pin6 +} + +self_test() { + local samples="${1:-1}" + ft4232h_pin_ctrl --mode spi-adc --channel B \ + --serial "$FT4232H_SERIAL" --opts "self-test,no-samples=$samples" +} + +have_eeprom_vars_loaded() { + local var + local value + for var in $EEPROM_VARS ; do + value="$(eval echo "\$$var")" + [ -n "$value" ] || return 1 + done + return 0 +} + +show_eeprom_vars() { + local color="${1:-green}" + local var + local value + for var in $EEPROM_VARS ; do + value="$(eval echo "\$$var")" + echo_${color} "${var}=${value}" + # only a single VREF can be defined + if [ "$var" == "VREF" ] ; then + continue + fi + # VOFF & VGAIN can be specified differently per channel + for ch in 0A 1A 2A 3A 4A 5A 6A 7A 0B 1B 2B 3B 4B 5B 6B 7B ; do + local value="$(eval echo \${${var}${ch}})" + [ -n "$value" ] || continue + echo_green "${var}${ch}=${value}" + done + done +} + +is_valid_number() { + local re='^-?[0-9]+([.][0-9]+)?$' + [ -n "$1" ] || return 1 + [[ $1 =~ $re ]] # note: this is bash-ism +} + +valid_numbers() { + local cnt="$1" + shift + while [ "$cnt" -gt 0 ] ; do + is_valid_number "$1" || return 1 + shift + let cnt='cnt - 1' + done + return 0 +} + +get_item_from_list() { + local idx=$1 + shift + while [ "$idx" -gt 0 ] ; do + let idx='idx - 1' + shift + done + echo $1 +} + +value_in_range() { + local val="$1" + local min="$2" + local max="$3" + + is_valid_number "$val" || { + echo_red "Compare value '$val' is not a valid number" + return 1 + } + + is_valid_number "$min" || { + echo_red "Min value '$min' is not a valid number" + return 1 + } + + is_valid_number "$val" || { + echo_red "Max value '$max' is not a valid number" + return 1 + } + + [ "$(echo "$min <= $val && $val <= $max" | bc -l)" == "1" ] +} + +check_system_requirements() { + type bc &> /dev/null || { + echo_red "You need 'bc' on your system" + exit 1 + } + type lsusb &> /dev/null || { + echo_red "You need 'lsusb' on your system ; please install libusb and/or usb-utils" + exit 1 + } + type openocd &> /dev/null || { + echo_red "You need to have OpenOCD installed on your system" + exit 1 + } + enforce_openocd_version + type dfu-util &> /dev/null || { + echo_red "You need to install 'dfu-util' on your system" + exit 1 + } + type expect &> /dev/null || { + echo_red "You need to have the 'expect' utility installed on your system" + exit 1 + } + type iio_attr &> /dev/null || { + echo_red "You need 'iio_attr' on your system ; please install libiio" + exit 1 + } + type sshpass &> /dev/null || { + echo_red "You need 'sshpass' installed on your system" + exit 1 + } + return 0 +} + +enforce_root() { + if [ `id -u` != "0" ] + then + echo_red "This script must be run as root" 1>&2 + exit 1 + fi +} + +ref_measure_ctl() { + local cmd="$(tolower $1)" + + # pin0 - select ref voltage - out-low == 10V, ough-high == 2.5V + # pin1 - GND_REF_SEL - must be out-low + # pin2 - REF_CH2_N_P_SEL - should be out-hi for now + # pin3 - REF_CH1_N_P_SEL - should be out-hi for now + # pin4 - EN_REF_MEASURE - active low + + if [ "$cmd" == "ref10v" ] ; then + toggle_pins GPIO_EXP1 pin2 pin3 # pin4 - out-lo, pin1 - out-low, pin0 - out-lo + elif [ "$cmd" == "ref2.5v" ] ; then + toggle_pins GPIO_EXP1 pin0 pin2 pin3 # # pin4 - out-lo, pin1 - out-low + elif [ "$cmd" == "disable" ] ; then + toggle_pins GPIO_EXP1 pin4 + else + echo_red "Unknown command '$cmd' ; valid commands are: ref10v, ref2.5v, enabled & disable" + return 1 + fi +} + +__get_hwserial() { + iio_attr -C $IIO_URI_MODE hw_serial 2> /dev/null | cut -d' ' -f2 +} + +get_hwserial() { + local timeout="$1" + if [ -z "$timeout" ] ; then + __get_hwserial + else + local serial + for _ in $(seq 1 $timeout) ; do + serial=$(__get_hwserial) + [ -z "$serial" ] || { + echo "$serial" + break + } + sleep 1 + done + fi + return 1 +} + +__get_phys_netdevs() { + for dev in /sys/class/net/*/device ; do echo $dev | cut -d'/' -f5 ; done +} + +pi_serial() { + cat /proc/cpuinfo | grep Serial | cut -d ' ' -f 2 +} + +jigname() { + local nm="$(cat /etc/hostname 2> /dev/null)" + [ -n "$nm" ] || nm="jig1" + local pi_serial="$(pi_serial)" + if [ -n "$pi_serial" ] ; then + echo "${nm}-${pi_serial}" + return + fi + local dev="$(__get_phys_netdevs | head -1)" + if [ -z "$dev" ] ; then + echo $nm + return + fi + local addr=$(cat /sys/class/net/$dev/address | sed 's/://g') + if [ -n "$addr" ] ; then + echo "${nm}-${addr}" + return + fi + echo $nm +} + +save_logfiles_to() { + local log_dir="$1" + local savefile="$2" + + local tmpfile="$(mktemp)" + tar -C "$log_dir" -zcvf "$tmpfile" . + mv -f "$tmpfile" "$savefile" +} + +check_and_reboot() { + local logfile="$1" + [ -n "$REBOOT_BUTTON" ] || return 1 + if type __check_and_reboot &> /dev/null ; then + __check_and_reboot $logfile + return $? + fi + return 1 +} + +__usbreset() { + local lsusb_entry="$1" + local bus="$(get_item_from_list 1 $lsusb_entry)" + local dev="$(get_item_from_list 3 $lsusb_entry | sed 's/://g')" + + $SCRIPT_DIR/work/usbreset /dev/bus/usb/$bus/$dev +} + +__usbreset_all() { + local entry + lsusb | while read -r entry ; do + __usbreset "$entry" + done +} + +usbreset() { + local vid="$1" + local did="$2" + + [ -n "$vid" ] || { + echo_red "No USB vendor ID provided" + return 1 + } + + if [ "$vid" == "all" ] ; then + __usbreset_all + return $? + fi + + [ -n "$did" ] || { + echo_red "No USB device ID provided" + return 1 + } + + local entry="$(lsusb -d ${vid}:${did})" + [ -n "$entry" ] || { + echo_blue "No USB device ${vid}:${did} found" + return 1 + } + + __usbreset "$entry" +} + +wait_for_board_offline() { + BOARD_ONLINE_TIMEOUT=${BOARD_ONLINE_TIMEOUT:-20} + local serial + for iter in $(seq $BOARD_ONLINE_TIMEOUT) ; do + serial=$(iio_attr -C $IIO_URI_MODE hw_serial 2> /dev/null | cut -d ' ' -f2) + [ -n "$serial" ] || return 0 + sleep 1 + done + return 1 +} + +ssh_cmd() { + local USER=analog + local CLIENT=analog + local PASS=analog + local CMD="$1" + + [ -n "$CMD" ] || { + echo "failed - no command" + exit 1 + } + + [ -z "$2" ] || { + $USER = $2 + } + + [ -z "$3" ] || { + $CLIENT = $3 + } + + [ -z "$4" ] || { + $PASS = $4 + } + + sshpass -p${PASS} ssh -q -t -oConnectTimeout=10 -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oCheckHostIP=no "$USER"@"$CLIENT" "$CMD" +} + +wait_for_board_online(){ + while true; do + if timeout 30 bash -c "until ping -q -c3 analog &>/dev/null; do false; done" + then + echo_blue "Connection to DUT OK" + break + else + echo_red "Check ethernet connection to DUT" + fi + done +} diff --git a/fmcbridge/misc/AD-FMCXMWBR1-EBZ-FRU.bin b/fmcbridge/misc/AD-FMCXMWBR1-EBZ-FRU.bin new file mode 100644 index 0000000..2987c88 Binary files /dev/null and b/fmcbridge/misc/AD-FMCXMWBR1-EBZ-FRU.bin differ diff --git a/fmcbridge/misc/BOOT.BIN b/fmcbridge/misc/BOOT.BIN new file mode 100644 index 0000000..9ea010b Binary files /dev/null and b/fmcbridge/misc/BOOT.BIN differ diff --git a/fmcbridge/misc/zynqmp-adrv9009-zu11eg-revb-adrv2crr-fmc-revb-jesd204-fsm-fmcbridge.dts b/fmcbridge/misc/zynqmp-adrv9009-zu11eg-revb-adrv2crr-fmc-revb-jesd204-fsm-fmcbridge.dts new file mode 100644 index 0000000..0254aaa --- /dev/null +++ b/fmcbridge/misc/zynqmp-adrv9009-zu11eg-revb-adrv2crr-fmc-revb-jesd204-fsm-fmcbridge.dts @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ADRV2CRR-FMC using ADRV9009-ZU11EG Rev.B System on Module + * + * https://wiki.analog.com/resources/eval/user-guides/adrv9009 + * https://wiki.analog.com/resources/tools-software/linux-drivers/iio-transceiver/adrv9009 + * https://wiki.analog.com/resources/tools-software/linux-software/adrv9009_advanced_plugin + * https://wiki.analog.com/resources/eval/user-guides/adrv9009-zu11eg/adrv2crr-fmc_carrier_board + * + * hdl_project: + * board_revision: + * + * Copyright (C) 2021 Analog Devices Inc. + */ + +#include "zynqmp-adrv9009-zu11eg-revb-adrv2crr-fmc-revb-jesd204-fsm.dts" + +&fpga_axi { + axi_i2c_1: i2c@83000000 { + #address-cells = <1>; + #size-cells = <0>; + clock-names = "s_axi_aclk"; + clocks = <&zynqmp_clk 71>; + compatible = "xlnx,axi-iic-2.0", "xlnx,xps-iic-2.00.a"; + interrupt-names = "iic2intc_irpt"; + interrupt-parent = <&gic>; + interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0 0x83000000 0x1000>; + }; + + axi_i2c_2: i2c@83100000 { + #address-cells = <1>; + #size-cells = <0>; + clock-names = "s_axi_aclk"; + clocks = <&zynqmp_clk 71>; + compatible = "xlnx,axi-iic-2.0", "xlnx,xps-iic-2.00.a"; + interrupt-names = "iic2intc_irpt"; + interrupt-parent = <&gic>; + interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0 0x83100000 0x1000>; + }; + + axi_spi_1: spi@84000000 { + #address-cells = <1>; + #size-cells = <0>; + bits-per-word = <8>; + compatible = "xlnx,xps-spi-2.00.a"; + reg = <0x0 0x84000000 0x1000>; + fifo-size = <16>; + interrupts = <0 92 IRQ_TYPE_EDGE_RISING>; + num-cs = <0x8>; + xlnx,num-ss-bits = <0x8>; + xlnx,spi-mode = <0>; + }; + + axi_spi_2: spi@84500000 { + #address-cells = <1>; + #size-cells = <0>; + bits-per-word = <8>; + compatible = "xlnx,xps-spi-2.00.a"; + reg = <0x0 0x84500000 0x1000>; + fifo-size = <16>; + interrupts = <0 93 IRQ_TYPE_EDGE_RISING>; + num-cs = <0x8>; + xlnx,num-ss-bits = <0x8>; + xlnx,spi-mode = <0>; + }; + + axi_gpio: gpio@86000000 { + #gpio-cells = <2>; + #interrupt-cells = <2>; + clock-names = "s_axi_aclk"; + clocks = <&zynqmp_clk 71>; + compatible = "xlnx,axi-gpio-2.0", "xlnx,xps-gpio-1.00.a"; + gpio-controller; + interrupt-controller; + interrupt-names = "ip2intc_irpt"; + interrupt-parent = <&gic>; + interrupts = <0 9 4>; + reg = <0x0 0x86000000 0x1000>; + xlnx,all-inputs = <0x0>; + xlnx,all-inputs-2 = <0x0>; + xlnx,all-outputs = <0x0>; + xlnx,all-outputs-2 = <0x0>; + xlnx,dout-default = <0x00000000>; + xlnx,dout-default-2 = <0x00000000>; + xlnx,gpio-width = <0x20>; + xlnx,gpio2-width = <0x20>; + xlnx,interrupt-present = <0x1>; + xlnx,is-dual = <0x1>; + xlnx,tri-default = <0xFFFFFFFF>; + xlnx,tri-default-2 = <0xFFFFFFFF>; + }; +}; + +&axi_i2c_1 { + ad7291_1@2f { + label = "ADC_I2C_1"; + compatible = "adi,ad7291"; + reg = <0x2f>; + }; +}; + +&axi_i2c_2 { + ad7291_2@2f { + label = "ADC_I2C_2"; + compatible = "adi,ad7291"; + reg = <0x2f>; + }; +}; + +&axi_spi_1 { + ad5721r_1@0 { + label = "DAC_SPI_1"; + compatible = "adi,ad5721r"; + reg = <0>; + spi-max-frequency = <500000>; + }; +}; + +&axi_spi_2 { + ad5721r_2@0 { + label = "DAC_SPI_2"; + compatible = "adi,ad5721r"; + reg = <0>; + spi-max-frequency = <500000>; + }; +}; + +&i2c_fmc { + eeprom@52 { + compatible = "at24,24c02"; + reg = <0x52>; + }; +}; diff --git a/fmcbridge/production_FMCBRIDGE.sh b/fmcbridge/production_FMCBRIDGE.sh new file mode 100755 index 0000000..73c6ed0 --- /dev/null +++ b/fmcbridge/production_FMCBRIDGE.sh @@ -0,0 +1,454 @@ +#!/bin/bash + +SCRIPT_DIR="$(readlink -f $(dirname $0))" + +source $SCRIPT_DIR/lib/utils.sh + +EEPROM_PATH="/sys/bus/i2c/devices/8-0052/eeprom" +MASTERFILE_PATH="/usr/local/src/fru_tools/masterfiles/AD-FMCXMWBR1-EBZ-FRU.bin" +SERIAL_NUMBER_PREFIX=$(date +"%m%Y") + +GPIO_ADDRESS=86000000 +SPI1_ADDRESS=84000000 +SPI2_ADDRESS=84500000 +I2C1_ADDRESS=83000000 +I2C2_ADDRESS=83100000 + +GPIO_FIRST=`ls -l /sys/class/gpio/ | grep " gpiochip" | grep "$GPIO_ADDRESS" | grep -Eo '[0-9]+$'` + +SPI1_DEVICE_NR=`ls -l /sys/bus/iio/devices/ | grep "$SPI1_ADDRESS" | grep -Eo '[0-9]+$'` +SPI2_DEVICE_NR=`ls -l /sys/bus/iio/devices/ | grep "$SPI2_ADDRESS" | grep -Eo '[0-9]+$'` +I2C1_DEVICE_NR=`ls -l /sys/bus/iio/devices/ | grep "$I2C1_ADDRESS" | grep -Eo '[0-9]+$'` +I2C2_DEVICE_NR=`ls -l /sys/bus/iio/devices/ | grep "$I2C2_ADDRESS" | grep -Eo '[0-9]+$'` + + +if [ $(id -u) -ne 0 ] ; then + echo "Please run as root" + exit 1 +fi + +#----------------------------------# +# Function section # +#----------------------------------# + +console_ascii_passed() { + echo_green "$(cat $SCRIPT_DIR/lib/passed.ascii)" +} + +console_ascii_failed() { + echo_red "$(cat $SCRIPT_DIR/lib/failed.ascii)" +} + +get_board_scan() { + IS_OKBOARD=1 + while [ $IS_OKBOARD -ne 0 ]; do + echo "Please use the scanner to scan the QR/Barcode on your carrier" + read BOARD_SERIAL + IS_OKBOARD=$? + BOARD_SERIAL=`echo $BOARD_SERIAL | tr -d ' ' | tr -d '-'` + echo "QR SCAN: $BOARD_SERIAL" + done +} + +check_req() { + if [ ! -e $EEPROM_PATH ] + then + echo "EEPROM file not found on SYSFS" + exit 1 + fi + + if [ ! -e $FRU_TOOLS_PATH ] + then + echo "FRU TOOLS path not correct or masterfile not available" + exit 1 + fi +} + +write_fru() { + check_req + if which fru-dump > /dev/null + then + fru-dump -i $MASTERFILE_PATH -o $EEPROM_PATH -d now -s $BOARD_SERIAL + return 0 + else + echo "fru-dump command not found. Check if you have it installed." + exit 1 + fi +} + +get_fmcbridge_serial() { + BOARD_SR_NR=`fru-dump -i /sys/bus/i2c/devices/8-0052/eeprom -b | grep 'Serial Number' | cut -d' ' -f3 | tr -d '[:cntrl:]'` + echo "Read Serial from EEPROM: $BOARD_SR_NR" +} + +gpio_initialization() { + echo "" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "~~~~~~~~~Initializing GPIOs~~~~~~~~~" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "" + for ((i=$GPIO_FIRST;i<=$GPIO_LAST;i++)) + do + echo "$i" > /sys/class/gpio/export 2>&1 + echo out > /sys/class/gpio/gpio$i/direction + done + echo "GPIO initialization done." +} + +gpio_test_spi1() { + echo "" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "~~~~~~~~~Start testing SPI1 GPIOS~~~~~~~~~" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "" + SPI1_GPIO_FIRST=$(($GPIO_FIRST + 7)) + GPIO_INPUT_SPI1=$(($GPIO_FIRST + 3)) + + echo in > /sys/class/gpio/gpio$GPIO_INPUT_SPI1/direction + + GPIO0=$(($GPIO_FIRST)) + GPIO1=$(($GPIO_FIRST+1)) + GPIO2=$(($GPIO_FIRST+2)) + + for ((i=1;i<8;i++)) + do + echo "" + + A0=$((($i>>0) & 1)) + A1=$((($i>>1) & 1)) + A2=$((($i>>2) & 1)) + + echo "Testing SPI1_CS${i}" + echo "A2:${A2} A1:${A1} A0:${A0}" + + echo $A2 > /sys/class/gpio/gpio$GPIO0/value + echo $A1 > /sys/class/gpio/gpio$GPIO1/value + echo $A0 > /sys/class/gpio/gpio$GPIO2/value + + SPI1_CS_GPIO=$(($SPI1_GPIO_FIRST + $i)) + + echo out > /sys/class/gpio/gpio$SPI1_CS_GPIO/direction + + echo "SPI1_CS${i} set high" + echo 1 > /sys/class/gpio/gpio$SPI1_CS_GPIO/value + + echo "Reading GPIO INPUT:" + GPIOIN_VAL=`cat /sys/class/gpio/gpio$GPIO_INPUT_SPI1/value` + if (( $GPIOIN_VAL == 1 )) + then + echo_green "SPI1_CS${i} test PASSED with value $GPIOIN_VAL" + else + echo_red "SPI1_CS${i} test FAILED." + STATUS=1 + fi + + echo "SPI1_CS${i} set low" + echo 0 > /sys/class/gpio/gpio$SPI1_CS_GPIO/value + + echo "Reading GPIO INPUT:" + GPIOIN_VAL=`cat /sys/class/gpio/gpio$GPIO_INPUT_SPI1/value` + if (( $GPIOIN_VAL == 0 )) + then + echo_green "SPI1_CS${i} test PASSED with value $GPIOIN_VAL" + else + echo_red "SPI1_CS${i} test FAILED." + STATUS=1 + fi + done +} + +gpio_test_spi2() { + echo "" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "~~~~~~~~~Start testing SPI2 GPIOS~~~~~~~~~" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "" + + SPI2_GPIO_FIRST=$(($SPI1_GPIO_FIRST + 7)) + GPIO_INPUT_SPI2=$(($GPIO_INPUT_SPI1 + 1)) + + echo in > /sys/class/gpio/gpio$GPIO_INPUT_SPI2/direction + + GPIO5=$(($GPIO_FIRST+5)) + GPIO6=$(($GPIO_FIRST+6)) + GPIO7=$(($GPIO_FIRST+7)) + + for ((i=1;i<8;i++)) + do + echo "" + + A0=$((($i>>0) & 1)) + A1=$((($i>>1) & 1)) + A2=$((($i>>2) & 1)) + + echo "Testing SPI2_CS${i}" + echo "A2:${A2} A1:${A1} A0:${A0}" + + echo $A2 > /sys/class/gpio/gpio$GPIO5/value + echo $A1 > /sys/class/gpio/gpio$GPIO6/value + echo $A0 > /sys/class/gpio/gpio$GPIO7/value + + SPI2_CS_GPIO=$(($SPI2_GPIO_FIRST + $i)) + + echo out > /sys/class/gpio/gpio$SPI2_CS_GPIO/direction + + echo "SPI2_CS${i} set high" + echo 1 > /sys/class/gpio/gpio$SPI2_CS_GPIO/value + + echo "Reading GPIO INPUT" + GPIOIN_VAL=`cat /sys/class/gpio/gpio$GPIO_INPUT_SPI2/value` + if (( $GPIOIN_VAL == 1 )) + then + echo_green "SPI2_CS${i} test PASSED with value $GPIOIN_VAL" + else + echo_red "SPI2_CS${i} test FAILED." + STATUS=1 + fi + + echo "SPI2_CS${i} set low" + echo 0 > /sys/class/gpio/gpio$SPI2_CS_GPIO/value + + echo "Reading GPIO INPUT:" + GPIOIN_VAL=`cat /sys/class/gpio/gpio$GPIO_INPUT_SPI2/value` + if (( $GPIOIN_VAL == 0 )) + then + echo_green "SPI2_CS${i} test PASSED with value $GPIOIN_VAL" + else + echo_red "SPI2_CS${i} test FAILED." + STATUS=1 + fi + done +} + +dac_test_spi1(){ + echo "" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "~~~~~~~~~Start testing DAC1~~~~~~~~~" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "" + + echo "Writing raw value 2000 to DAC1" + echo 2000 > /sys/bus/iio/devices/${SPI1_DEVICE}/out_voltage_raw + + echo "Reading raw value from DAC1:" + DAC1_VAL=`cat /sys/bus/iio/devices/${SPI1_DEVICE}/out_voltage_raw` + + if (( ($DAC1_VAL < 3000) || ($DAC1_VAL > 3100) )) + then + echo_red "DAC1 test FAILED with value: $DAC1_VAL" + STATUS=1 + else + echo_green "DAC1 test PASSED with value: $DAC1_VAL" + fi +} + +dac_test_spi2(){ + echo "" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "~~~~~~~~~Start testing DAC2~~~~~~~~~" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "" + + echo "Writing raw value 2000 to DAC2" + echo 2000 > /sys/bus/iio/devices/${SPI2_DEVICE}/out_voltage_raw + + echo "Reading raw value from DAC2:" + DAC2_VAL=`cat /sys/bus/iio/devices/${SPI2_DEVICE}/out_voltage_raw` + if (( ($DAC2_VAL < 3000) || ($DAC2_VAL > 3100) )) + then + echo_red "DAC1 test FAILED with value: $DAC2_VAL" + STATUS=1 + else + echo_green "DAC1 test PASSED with value: $DAC2_VAL" + fi +} + +adc_test_i2c1(){ + echo "" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "~~~~~~~~~Start testing ADC1~~~~~~~~~" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "" + + ADC1_RANGES=(700 1000 500 700 1500 2100 1500 2100 2400 3000 400 600 2000 2500) + + for ((i=0;i<=6;i++)) + do + echo "" + MIN_VAL=$i*2 + MAX_VAL=$i*2+1 + echo "Reading VIN${i}" + ADC_VAL=`cat /sys/bus/iio/devices/${I2C1_DEVICE}/in_voltage${i}_raw` + echo "VIN$1 RANGE: ${ADC1_RANGES[$MIN_VAL]} ${ADC1_RANGES[$MAX_VAL]}" + if (( ($ADC_VAL > ${ADC1_RANGES[$MIN_VAL]}) && ($ADC_VAL < ${ADC1_RANGES[$MAX_VAL]}) )) + then + echo_green "ADC1 VIN$i test PASSED with value:$ADC_VAL" + else + echo_red "ADC1 VIN$i test FAILED with value:$ADC_VAL" + STATUS=1 + fi + done +} + +adc_test_i2c2(){ + echo "" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "~~~~~~~~~Start testing ADC2~~~~~~~~~" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "" + + for ((i=0;i<=5;i++)) + do + echo "" + + GPIO=$(($GPIO_FIRST+$i)) + if (( $i > 2 )) + then + GPIO=$(($GPIO + 2)) + fi + + GPIO_INDEX=$(($GPIO - $GPIO_FIRST)) + + echo out > /sys/class/gpio/gpio$GPIO/direction + + echo "Set GPIO${GPIO_INDEX} high" + echo 1 > /sys/class/gpio/gpio$GPIO/value + + echo "Reading VIN${i}" + ADC_VAL=`cat /sys/bus/iio/devices/${I2C2_DEVICE}/in_voltage${i}_raw` + if (( $ADC_VAL > 2000 )) + then + echo_green "ADC2 test PASSED with value:$ADC_VAL" + else + echo_red "ADC2 test FAILED with value:$ADC_VAL" + STATUS=1 + fi + + echo "Set GPIO${GPIO_INDEX} low" + echo 0 > /sys/class/gpio/gpio$GPIO/value + + echo "Reading VIN${i}" + ADC_VAL=`cat /sys/bus/iio/devices/${I2C2_DEVICE}/in_voltage${i}_raw` + if (( $ADC_VAL < 2000 )) + then + echo_green "ADC2 test PASSED with value:$ADC_VAL" + else + echo_red "ADC2 test FAILED with value:$ADC_VAL" + STATUS=1 + fi + done +} + +prepare_logs() { + LOGDIR=$SCRIPT_DIR/log + mkdir -p $LOGDIR + RUN_TIMESTAMP="$(date +"%Y-%m-%d_%H-%M-%S")" + LOGFILE="${LOGDIR}/${BOARD_SERIAL}_${RUN_TIMESTAMP}.log" +} + +test_fmcbridge() { + STATUS=0 + + echo "" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "~~~~~~~Device Initialization~~~~~~~~" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "" + + echo "" + echo "~~~~~~~~~~~~GPIOs Test~~~~~~~~~~~~~~" + echo "" + if [ -z $GPIO_FIRST ]; then + echo_red "No GPIO node found!" + else + echo_green "GPIO initial offset found: $GPIO_FIRST" + GPIO_LAST=$(($GPIO_FIRST + 21)) + gpio_initialization + gpio_test_spi1 + gpio_test_spi2 + fi + + echo "" + echo "~~~~~~~~~SPI1 Device Test~~~~~~~~~~~" + echo "" + if [ -z $SPI1_DEVICE_NR ]; then + echo_red "AD5761_SPI1 not found." + else + SPI1_DEVICE="iio:device${SPI1_DEVICE_NR}" + echo_green "SPI device 1 found: ${SPI1_DEVICE}" + dac_test_spi1 + fi + + echo "" + echo "~~~~~~~~~SPI2 Device Test~~~~~~~~~~~" + echo "" + if [ -z $SPI2_DEVICE_NR ]; then + echo_red "AD5761_SPI12 not found." + else + SPI2_DEVICE="iio:device${SPI2_DEVICE_NR}" + echo_green "SPI device 2 found: ${SPI2_DEVICE}" + dac_test_spi2 + fi + + echo "" + echo "~~~~~~~~~I2C1 Device Test~~~~~~~~~~~" + echo "" + if [ -z $I2C1_DEVICE_NR ]; then + echo_red "AD7291_I2C1 not found." + else + I2C1_DEVICE="iio:device${I2C1_DEVICE_NR}" + echo_green "I2C device 1 found: ${I2C1_DEVICE}" + adc_test_i2c1 + fi + + echo "" + echo "~~~~~~~~~I2C2 Device Test~~~~~~~~~~~" + echo "" + if [ -z $I2C2_DEVICE_NR ]; then + echo_red "AD7291_I2C2 not found." + else + I2C2_DEVICE="iio:device${I2C2_DEVICE_NR}" + echo_green "I2C device 2 found: ${I2C2_DEVICE}" + adc_test_i2c2 + fi + + if [ "$STATUS" -eq 0 ] + then + echo_green "ALL TESTS HAVE PASSED" + console_ascii_passed + else + echo_red "TESTS HAVE FAILED" + console_ascii_failed + fi +} + + +#----------------------------------# +# Main section # +#----------------------------------# + +/etc/init.d/htpdate restart > /dev/null 2>&1 + +while true; do + + echo_blue "Please enter your choice: " + + options=("Start FMCBRIDGE Test" "Poweroff Board") + select opt in "${options[@]}"; do + case $REPLY in + 1) + echo_blue "Starting FMCBRIDGE Test" + get_board_scan + prepare_logs + test_fmcbridge | tee "${LOGFILE}" + write_fru + get_fmcbridge_serial + break ;; + 2) + enforce_root + poweroff + break 2 ;; + *) echo "invalid option $REPLY";; + esac + done +done diff --git a/fmcbridge/scp.sh b/fmcbridge/scp.sh new file mode 100755 index 0000000..b16efb8 --- /dev/null +++ b/fmcbridge/scp.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +SRC="$1" +DST="$2" +PASS="$3" + +[ -n "$SRC" ] || { + echo "failed - no src" + exit 1 +} + +[ -d "$SRC" ] && { + echo "Directory copy" + param="-r" +} + +[ -n "$DST" ] || { + echo "failed - no dst" + exit 1 +} + +cmd= + +[ -z "$PASS" ] || cmd="$cmd sshpass -p${PASS}" +cmd="$cmd scp $param -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oCheckHostIP=no" + +$cmd $SRC $DST &> /tmp/scp_command || { + echo "failed - scp command: $(cat /tmp/scp_command)" + rm -f /tmp/scp_command + exit 1 +} +exit 0 + diff --git a/fmcbridge/setup_env.sh b/fmcbridge/setup_env.sh new file mode 100755 index 0000000..a3d11b7 --- /dev/null +++ b/fmcbridge/setup_env.sh @@ -0,0 +1,329 @@ +#!/bin/bash +set -e + +#----------------------------------# +# Global definitions section # +#----------------------------------# + +SCRIPT_DIR="$(readlink -f $(dirname $0))" + +source $SCRIPT_DIR/lib/utils.sh + +SUPPORTED_BOARDS="FMCBRIDGE" + +INIT_PINS_SCRIPT="$SCRIPT_DIR"/init.sh + +#----------------------------------# +# Functions section # +#----------------------------------# + +sudo_required() { + type sudo &> /dev/null || { + echo_red "'sudo' utility required" + exit 1 + } +} + +setup_apt_install_prereqs() { + type apt-get &> /dev/null || { + echo "No 'apt-get' found; cannot install dependencies" + return 0 + } + sudo_required + sudo -s <<-EOF + apt-get -y update + apt-get -y install bc sshpass libfftw3-dev librsvg2-dev libgtk-3-dev \ + cmake build-essential git libxml2 libxml2-dev bison flex \ + expect usbutils dfu-util screen libaio-dev libglib2.0-dev picocom \ + wget unzip curl cups cups-bsd intltool itstool libxml2-utils \ + libusb-dev libusb-1.0-0-dev htpdate xfce4-terminal libiec16022-dev \ + openssh-server gpg dnsmasq libcurl4-gnutls-dev libqrencode-dev pv \ + python3-pytest python3-libiio python3-scapy python3-scipy + /etc/init.d/htpdate restart + EOF +} + +__common_build_tool() { + local c_files + mkdir -p work + + for c_file in $tool_c ; do + cp -f "src/$c_file" "work/$c_file" + c_files="$c_files work/$c_file" + done + gcc $c_files -o "work/$tool" $cflags $ldflags +} + +__download_github_common() { + local gh_prj="$1" + mkdir -p work + + local ver=$(get_latest_release analogdevicesinc/$gh_prj) + [ -d work/$gh_prj ] || { + if [ -z "$ver" ] ; then + echo_red "Could not get $gh_prj release tag; cloning repo" + git clone https://github.com/analogdevicesinc/$gh_prj work/$gh_prj + else + echo_green "Using latest released version '$ver' of '$gh_prj'" + download_and_unzip_to "https://github.com/analogdevicesinc/$gh_prj/archive/${ver}.zip" "work" || { + echo_red "Could not download $gh_prj..." + exit 1 + } + mv -f work/${gh_prj}* work/$gh_prj + fi + } +} + +setup_write_autostart_config() { + local autostart_path="$HOME/.config/autostart" + local configs_disable="blueman light-locker polkit-gnome-authentication-agent-1" + + configs_disable="$configs_disable print-applet pulseaudio snap-userd-autostart" + configs_disable="$configs_disable spice-vdagent update-notifier user-dirs-update-gtk xdg-user-dirs" + + mkdir -p $autostart_path + + for cfg in $configs_disable ; do + cat > $autostart_path/$cfg.desktop <<-EOF +[Desktop Entry] +Hidden=true + EOF + done + + local font_size="16" + if [ "$BOARD" == "pluto" ] ; then + font_size=14 + fi + + # FIXME: see about generalizing this to other desktops [Gnome, MATE, LXDE, etc] + cat > $autostart_path/test-jig-tool.desktop <<-EOF +[Desktop Entry] +Encoding=UTF-8 +Version=0.9.4 +Type=Application +Name=test-jig-tool +Comment=test-jig-tool +Exec=sudo xfce4-terminal --font="DejaVu Sans Mono $font_size" --fullscreen --hide-borders --hide-scrollbar --hide-menubar -x $SCRIPT_DIR/production_${BOARD}.sh +OnlyShowIn=XFCE;LXDE +StartupNotify=false +Terminal=false +Hidden=false + EOF + + cat > $autostart_path/auto-save-logs.desktop <<-EOF +[Desktop Entry] +Encoding=UTF-8 +Version=0.9.4 +Type=Application +Name=auto-save-logs +Comment=auto-save-logs +Exec=sudo /bin/bash $SCRIPT_DIR/autosave_logs.sh +StartupNotify=false +Terminal=false +Hidden=false + EOF + +} + +board_is_supported() { + local board="$1" + [ -n "$board" ] || return 1 + for b in $SUPPORTED_BOARDS ; do + [ "$b" != "$board" ] || return 0 + done + return 1 +} + +xfconf_has_cap() { + type xfconf-query &> /dev/null || return 1 + if xfconf-query -l | grep -q xfce4-power-manager ; then + return 0 + fi + return 1 +} + +setup_xfce4_power_manager_settings() { + local pm_sett="/xfce4-power-manager/blank-on-ac=0 + /xfce4-power-manager/blank-on-battery=0 + /xfce4-power-manager/brightness-switch=0 + /xfce4-power-manager/brightness-switch-restore-on-exit=1 + /xfce4-power-manager/dpms-enabled=false + /xfce4-power-manager/dpms-on-ac-off=60 + /xfce4-power-manager/dpms-on-ac-sleep=20 + /xfce4-power-manager/dpms-on-battery-off=30 + /xfce4-power-manager/dpms-on-battery-sleep=15 + /xfce4-power-manager/lock-screen-suspend-hibernate=true + /xfce4-power-manager/logind-handle-lid-switch=false + /xfce4-power-manager/power-button-action=4 + /xfce4-power-manager/show-panel-label=0" + xfconf_has_cap xfce4-power-manager || return 0 + for sett in $pm_sett ; do + local key="$(echo $sett | cut -d'=' -f1)" + local val="$(echo $sett | cut -d'=' -f2)" + xfconf-query -c xfce4-power-manager -p $key -s $val + done +} + +setup_disable_sudo_passwd() { + sudo_required + sudo -s <<-EOF + if ! grep -q $USER /etc/sudoers ; then + echo "$USER ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers + fi + EOF +} + +setup_thunar_volman() { + local configs="/autobrowse/enabled=false + /autoburn/enabled=false + /autoipod/enabled=false + /autokeyboard/enabled=false + /automount-drives/enabled=true + /automount-media/enabled=true + /automouse/enabled=false + /autoopen/enabled=false + /autophoto/enabled=false + /autoplay-audio-cds/enabled=false + /autoplay-video-cds/enabled=false + /autoprinter/enabled=false + /autorun/enabled=false + /autotablet/enabled=false" + xfconf_has_cap thunar-volman || return 0 + for sett in $configs ; do + local key="$(echo $sett | cut -d'=' -f1)" + local val="$(echo $sett | cut -d'=' -f2)" + xfconf-query -c thunar-volman -p $key -s $val + done +} + +setup_disable_lxde_automount() { + [ -d "$HOME/.config/pcmanfm" ] || return 0 + + pushd "$HOME/.config/pcmanfm/" + for cfg_file in $(find . -name pcmanfm.conf) ; do + sed 's/autorun=1/autorun=0/g' -i $cfg_file + done + + popd +} + +setup_pi_boot_config() { + [ "$BOARD" == "pluto" ] || return 0 + + [ -f /boot/config.txt ] || return 0 + + local tmp=$(mktemp) + cat >> $tmp <<-EOF +# --- added by setup_env.sh +hdmi_force_hotplug=1 +hdmi_group=2 +hdmi_mode=87 +hdmi_cvt=800 480 60 6 0 0 0 +hdmi_drive=1 +max_usb_current=1 + +dtoverlay=pi3-disable-wifi +dtoverlay=pi3-disable-bt +# --- end setup_env.sh + EOF + + sudo -s <<-EOF + sed -i -e "/^# --- added by setup_env.sh/,/^# --- end setup_env.sh/d" /boot/config.txt + cat $tmp >> /boot/config.txt + rm -f $tmp + EOF +} + +setup_disable_pi_screen_blanking() { + local pi_serial="$(pi_serial)" + [ -n "$pi_serial" ] || return 0 + + local tmp=$(mktemp) + cat >> $tmp <<-EOF +# --- added by setup_env.sh +[SeatDefaults] +xserver-command=X -s 0 -dpms +# --- end setup_env.sh + EOF + + sudo -s <<-EOF + sed -i -e "/^# --- added by setup_env.sh/,/^# --- end setup_env.sh/d" /etc/lightdm/lightdm.conf + cat $tmp >> /etc/lightdm/lightdm.conf + EOF +} + +setup_raspi_config() { + sudo -s <<-EOF + if type raspi-config &> /dev/null ; then + raspi-config nonint do_ssh 0 # enable SSH + fi + EOF +} + +setup_misc_profile_cleanup() { + touch $HOME/.hushlogin # tell login to not print system info + sudo -s <<-EOF + # Kind of hacky, but it works ; this will remove the warnings + # about the SSH password & Wi-Fi on console login + [ ! -f /etc/profile.d/sshpwd.sh ] || echo -n > /etc/profile.d/sshpwd.sh + [ ! -f /etc/profile.d/wifi-country.sh ] || echo -n > /etc/profile.d/wifi-country.sh + [ ! -f /etc/xdg/lxsession/LXDE-pi/sshpwd.sh ] || echo -n > /etc/xdg/lxsession/LXDE-pi/sshpwd.sh + EOF +} + + +setup_bashrc_update() { + sed -i -e "/^# --- added by setup_env.sh/,/^# --- end setup_env.sh/d" "$HOME/.bashrc" + + cat >> $HOME/.bashrc <<-EOF +# --- added by setup_env.sh +export SCRIPT_DIR="$SCRIPT_DIR" +source "$SCRIPT_DIR/vars.sh" +export IIOD_REMOTE=analog.local +export PATH=/usr/lib/:$PATH +# --- end setup_env.sh + EOF +} + +#----------------------------------# +# Main section # +#----------------------------------# + +BOARD="$1" +TARGET="$2" + +if [ `id -u` == "0" ] +then + echo_red "This script should not be run as root" 1>&2 + exit 1 +fi + +board_is_supported "$BOARD" || { + echo_red "Board '$BOARD' is not supported by this script" + echo_red " Supported boards are '$SUPPORTED_BOARDS'" + exit 1 +} + +pushd $SCRIPT_DIR + +STEPS="bashrc_update disable_sudo_passwd misc_profile_cleanup raspi_config xfce4_power_manager_settings" +STEPS="$STEPS thunar_volman disable_lxde_automount apt_install_prereqs" +STEPS="$STEPS write_autostart_config" +STEPS="$STEPS pi_boot_config disable_pi_screen_blanking" + +RAN_ONCE=0 +for step in $STEPS ; do + if [ "$TARGET" == "$step" ] || [ "$TARGET" == "jig" ] ; then + setup_$step + RAN_ONCE=1 + fi +done + +if [ "$RAN_ONCE" == "0" ] ; then + echo_red "Invalid build target '$TARGET'; valid targets are 'jig' or:" + for step in $STEPS ; do + echo_red " $step" + done +fi + +popd diff --git a/fmcbridge/update_boot.sh b/fmcbridge/update_boot.sh new file mode 100755 index 0000000..eac91c0 --- /dev/null +++ b/fmcbridge/update_boot.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Script used for update of BOOT partition on carrier SD card +# +# Can be called with: ./update_boot.sh +# + +SCRIPT_DIR="$(readlink -f $(dirname $0))" + +source $SCRIPT_DIR/lib/utils.sh + +wait_for_board_online +ssh_cmd "sudo mount /dev/mmcblk0p1 /boot" +$SCRIPT_DIR/scp.sh $SCRIPT_DIR/misc/* analog@analog:/boot/ analog + +echo_blue "Select what type of SD card you want to create: " +options=("zu11eg-revb-4.14" "zu11eg-revb-4.19" "fmcomms8") +select opt in "${options[@]}"; do + case $REPLY in + 1) + SRC_DIR="zynqmp-adrv9009-zu11eg-revb-adrv2crr-fmc-revb" + 2) + SRC_DIR="zynqmp-adrv9009-zu11eg-revb-adrv2crr-fmc-revb-4.19" + 3) + SRC_DIR="fmcomms8_boot" + esac +done + +ssh_cmd "sudo cp /boot/$SRC_DIR/* /boot/" +ssh_cmd "sudo sync" +ssh_cmd "sudo umount /boot" diff --git a/fmcbridge/vars.sh b/fmcbridge/vars.sh new file mode 100644 index 0000000..cd05fce --- /dev/null +++ b/fmcbridge/vars.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +#----------------------------------# +# Global definitions section # +#----------------------------------# + +LD_LIBRARY_PATH="$SCRIPT_DIR/work/libiio/build" +PATH="$SCRIPT_DIR/work/libiio/build/tests:$PATH" + +export LD_LIBRARY_PATH +export PATH + +# This can be increased to a higher value, and then multiple measurements +# will be made and averaged +NUM_SAMPLES=1 + +IIO_URI_MODE="-u ip:192.168.2.1" +BOARD_ONLINE_TIMEOUT=20 # seconds