├── CI └── file_check.sh ├── LICENSE ├── Makefile ├── README.md ├── ad936x-dbfs-initalize.sh ├── adi_rebuild_devicetrees.sh ├── adi_update_boot.sh ├── adi_update_tools.sh ├── adrv9009_multichip_sync.sh ├── azure-pipelines.yml ├── bad_monitor.sh ├── dds_buf_random.sh ├── dds_set_scale.sh ├── dds_sweep.sh ├── dds_test_scales.sh ├── enable_dhcp.sh ├── enable_dummy_display.sh ├── enable_static_ip.sh ├── erase_fru_eeprom.sh ├── fix-display-port.service ├── fix_DP_audio.sh ├── fix_x11.sh ├── fw_env.config ├── input-event-daemon.conf.rfsombox ├── jupiter_scripts ├── fan-control └── fan-control.service ├── lightdm_timeout.conf ├── pll_tx_sweep.sh ├── power-service ├── adi-power.service ├── adi_power.py └── stingray_power.py ├── regcompare.sh ├── regdump.sh ├── swap_to ├── test_ADRV9371-N.sh ├── test_ADRV9371-W.sh ├── test_adrv9002_fh.sh ├── test_ensm_pinctrl.sh ├── test_fmcadc2.sh ├── test_fmcdaq2.sh ├── test_fmcdaq3.sh ├── test_fmcomms2.sh ├── test_fmcomms4.sh ├── test_fmcomms5.sh ├── test_freqcvt1.sh ├── test_mgc_pinctrl.sh ├── test_pzsdr2_2400tdd.sh ├── test_rx_fastlock_pinctrl.sh ├── test_trxboost1.sh ├── test_tx_fastlock_pinctrl.sh ├── ttyGS0.conf ├── usb-gadget-service ├── defaults │ ├── iiod │ └── usb_gadget ├── install_gt.sh ├── schemes │ ├── iio_acm_generic.scheme │ ├── iio_acmx2_rndis.scheme │ └── iio_ncm.scheme ├── scripts │ ├── iiod_context.sh │ └── usb_gadget.sh ├── systemd │ ├── dev-iio_ffs.mount │ ├── gt-start.service │ ├── gt.service │ ├── gt.target │ ├── iiod_context_attr.service │ └── iiod_ffs.service └── udev │ └── 99-udc.rules ├── usb_otg.sh ├── verify_ad9361_spi └── verify_ad9361_temp /CI/file_check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | FILENAME=$1 4 | DEST="\$(DESTDIR)" 5 | 6 | while IFS= read -r LINE_VAL; do 7 | LINE=$(echo $LINE_VAL | xargs) 8 | IFS=' ' 9 | read -a COMMAND_ARGUMENTS <<< $LINE 10 | LENGTH=${#COMMAND_ARGUMENTS[@]} 11 | case $LINE in 12 | "DESTDIR="*) #save value of variable DESTDIR 13 | IFS='=' 14 | read -a DESTDIR_VALUE <<< $LINE 15 | ;; 16 | "install -d"*) #creates directory from the PATH given as agrument 17 | if [[ ! ${COMMAND_ARGUMENTS[$LENGTH-1]} == *"(DESTDIR)"* ]]; then 18 | if [[ ! -d ${COMMAND_ARGUMENTS[$LENGTH-1]} ]]; then 19 | echo "Directory ${COMMAND_ARGUMENTS[$LENGTH-1]} DOES NOT exists." 20 | exit 1 21 | else 22 | echo "Directory ${COMMAND_ARGUMENTS[$LENGTH-1]} exists." 23 | fi 24 | else 25 | if [[ ! -d ${COMMAND_ARGUMENTS[$LENGTH-1]/$DEST/${DESTDIR_VALUE[1]}} ]]; then 26 | echo "Directory ${COMMAND_ARGUMENTS[$LENGTH-1]/$DEST/${DESTDIR_VALUE[1]}} DOES NOT exists." 27 | exit 1 28 | else 29 | echo "Directory ${COMMAND_ARGUMENTS[$LENGTH-1]/$DEST/${DESTDIR_VALUE[1]}} exists." 30 | fi 31 | fi 32 | ;; 33 | "install -D -m"*) #copy file from specified location to given PATH 34 | FILE_PATH=${COMMAND_ARGUMENTS[$LENGTH-1]} 35 | 36 | if [[ ${FILE_PATH} == *"/" ]]; then 37 | IFS='/' 38 | read -a COPIED_FILE <<< ${COMMAND_ARGUMENTS[$LENGTH-2]} 39 | LENGTH=${#COPIED_FILE[@]} 40 | 41 | if [[ ! -f $FILE_PATH${COPIED_FILE[$LENGTH-1]} ]]; then 42 | echo "File $FILE_PATH${COPIED_FILE[$LENGTH-1]} DOES NOT exists" 43 | exit 1 44 | else 45 | echo "File $FILE_PATH${COPIED_FILE[$LENGTH-1]} exists" 46 | fi 47 | else 48 | if [[ ! -f ${FILE_PATH} ]]; then #if the PATH where to copy ends with a file, the content of the file will be modified with the one we want to copy 49 | echo "File ${FILE_PATH} DOES NOT exists" 50 | exit 1 51 | else 52 | echo "File ${FILE_PATH} exists" 53 | fi 54 | fi 55 | IFS='' 56 | ;; 57 | "systemctl enable"*".service"*) #enables sepecified serices as command arguments, but we check the status of those ended in .service 58 | LENGTH=$(wc -w <<< $LINE) 59 | NEWLINE=$(cut -d " " -f 3-$LENGTH <<< $LINE) 60 | IFS=' ' 61 | read -a COMMAND_ARGUMENTS <<< $NEWLINE 62 | 63 | for ARGUMENT in ${COMMAND_ARGUMENTS[@]}; do 64 | if [[ $ARGUMENT == *".service" ]]; then 65 | if [[ ! $(sudo systemctl status $ARGUMENT | grep 'Loaded' | grep -q 'enabled') ]]; then 66 | echo "Service $ARGUMENT is enabled" 67 | else 68 | echo "Service $ARGUMENT is NOT enabled" 69 | exit 1 70 | fi 71 | fi 72 | done 73 | ;; 74 | *) 75 | ;; 76 | esac 77 | done < $FILENAME 78 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Analog Devices Inc. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DESTDIR=/usr/local 2 | 3 | install: 4 | install -d $(DESTDIR)/bin 5 | install ./*.sh $(DESTDIR)/bin/ 6 | 7 | install -D -m 0644 ./power-service/adi-power.service /etc/systemd/system/ 8 | install -D -m 0644 ./power-service/adi_power.py /usr/share/systemd/ 9 | install -D -m 0644 ./power-service/stingray_power.py /usr/share/systemd/ 10 | 11 | install -D -m 0644 ./lightdm_timeout.conf /etc/systemd/system/lightdm.service.d/timeout.conf 12 | 13 | install -D -m 0644 ./jupiter_scripts/fan-control.service /etc/systemd/system/fan-control.service 14 | install -D -m 0744 ./jupiter_scripts/fan-control /usr/bin/fan-control 15 | 16 | install -D -m 0644 ./fix-display-port.service /etc/systemd/system/fix-display-port.service 17 | 18 | systemctl daemon-reload 19 | systemctl enable adi-power.service 20 | systemctl enable fan-control.service 21 | systemctl enable fix-display-port.service 22 | 23 | /bin/sh usb-gadget-service/install_gt.sh 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ADI Scripts for Linux images 2 | ============================ 3 | 4 | This is a semi-random collection of small shell scripts which 5 | run on various Linux images (on various platforms) which talk 6 | to a varity of different ADI boards and parts. 7 | 8 | All scripts in this collection are copyright Analog Devices Inc, 9 | and are released under a BSD-like license. Please see the LICENSE 10 | file for more info. 11 | 12 | If you have issues with these, please ask for help on: 13 | http://ez.analog.com/community/linux-device-drivers/linux-software-drivers 14 | -------------------------------------------------------------------------------- /ad936x-dbfs-initalize.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$1" == "" ]; then 4 | echo "usage: $0 [ ]" 5 | exit 6 | fi; 7 | 8 | rxlo=`iio_attr -q -u ip:$1 -c ad9361-phy altvoltage0 frequency` 9 | txlo=`iio_attr -q -u ip:$1 -c ad9361-phy altvoltage1 frequency` 10 | rxgcm=`iio_attr -q -i -u ip:$1 -c ad9361-phy voltage0 gain_control_mode` 11 | rxsamp=`iio_attr -q -i -u ip:$1 -c ad9361-phy voltage0 sampling_frequency` 12 | rxbw=`iio_attr -q -i -u ip:$1 -c ad9361-phy voltage0 rf_bandwidth` 13 | txbw=`iio_attr -q -o -u ip:$1 -c ad9361-phy voltage0 rf_bandwidth` 14 | rxport=`iio_attr -q -i -u ip:$1 -c ad9361-phy voltage0 rf_port_select` 15 | txport=`iio_attr -q -o -u ip:$1 -c ad9361-phy voltage0 rf_port_select` 16 | rxgain=`iio_attr -q -i -u ip:$1 -c ad9361-phy voltage0 hardwaregain | cut -f1 -d ' '` 17 | txgain=`iio_attr -q -o -u ip:$1 -c ad9361-phy voltage0 hardwaregain | cut -f1 -d ' '` 18 | 19 | 20 | if [ "$2" != "" ] && [ "$3" != "" ]; then 21 | iio_attr -q -u ip:$1 -D ad9361-phy $2 $3 > /dev/null 22 | echo "wrote $2 = $3" 23 | fi 24 | 25 | iio_attr -q -o -u ip:$1 -D ad9361-phy initialize 1 > /dev/null 26 | 27 | iio_attr -q -i -u ip:$1 -c ad9361-phy voltage0 rf_port_select $rxport > /dev/null 28 | iio_attr -q -o -u ip:$1 -c ad9361-phy voltage0 rf_port_select $txport > /dev/null 29 | iio_attr -q -u ip:$1 -c ad9361-phy altvoltage0 frequency $rxlo > /dev/null 30 | iio_attr -q -u ip:$1 -c ad9361-phy altvoltage1 frequency $txlo > /dev/null 31 | iio_attr -q -i -u ip:$1 -c ad9361-phy voltage0 sampling_frequency $rxsamp > /dev/null 32 | iio_attr -q -i -u ip:$1 -c ad9361-phy voltage0 rf_bandwidth $rxbw > /dev/null 33 | iio_attr -q -o -u ip:$1 -c ad9361-phy voltage0 rf_bandwidth $txbw > /dev/null 34 | iio_attr -q -i -u ip:$1 -c ad9361-phy voltage0 gain_control_mode $rxgcm > /dev/null 35 | iio_attr -q -i -u ip:$1 -c ad9361-phy voltage0 hardwaregain $rxgain > /dev/null 36 | iio_attr -q -o -u ip:$1 -c ad9361-phy voltage0 hardwaregain $txgain > /dev/null 37 | -------------------------------------------------------------------------------- /adi_rebuild_devicetrees.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | find_current_setup () 4 | { 5 | key=`md5sum $1/devicetree.dtb | awk '{print $1}'` 6 | 7 | for file in $1/* ; do 8 | if [ -d $file ] ; then 9 | if [ -f $file/devicetree.dtb ] ; then 10 | t=`md5sum $file/devicetree.dtb | awk '{print $1}'` 11 | if [ "$t" = "$key" ] ; then 12 | echo $file 13 | exit 14 | fi 15 | fi 16 | fi 17 | done 18 | } 19 | 20 | FAT_MOUNT=/media/boot 21 | 22 | mkdir $FAT_MOUNT 2>/dev/null 23 | umount /dev/mmcblk0p1 2>/dev/null 24 | mount /dev/mmcblk0p1 $FAT_MOUNT 25 | 26 | if [ $? -ne 0 ] 27 | then 28 | echo "Mounting /dev/mmcblk0p1 failed - already mounted?" 1>&2 29 | exit 1 30 | fi 31 | 32 | # Try to restore current BOOT.BIN and devicetree.dtb 33 | CURRENT_CONFIG=`find_current_setup $FAT_MOUNT` 34 | echo "CURRENT BOARD CONFIG: $CURRENT_CONFIG" 35 | 36 | for i in $(find $FAT_MOUNT -type d 2>/dev/null) 37 | do 38 | cd $i 39 | if [ -f *.dts ] 40 | then 41 | dtc -O dtb -o devicetree.dtb *.dts 42 | fi 43 | done 44 | 45 | if [ "$CURRENT_CONFIG" != "" ] 46 | then 47 | echo "Updating $CURRENT_CONFIG/devicetree.dtb -> $FAT_MOUNT/devicetree.dtb" 48 | cp $CURRENT_CONFIG/devicetree.dtb $FAT_MOUNT/devicetree.dtb 49 | fi 50 | 51 | cd ~ 52 | sync 53 | umount $FAT_MOUNT 54 | echo "DONE" 55 | -------------------------------------------------------------------------------- /adi_update_boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | shopt -s extglob # activate extended pattern matching 3 | 4 | ### Set global variables 5 | REPO="linux_image_ADI-scripts" 6 | BRANCH="origin/main" 7 | SERVER="http://swdownloads.analog.com" 8 | SPATH="cse/boot_partition_files" 9 | RPI_SPATH="cse/linux_rpi" 10 | ARCHIVE_NAME="latest_boot_partition.tar.gz" 11 | 12 | # Whenever 'latest' and 'previous' are updated, need to update also conditions from next if 13 | LATEST_RELEASE="2023_r2" 14 | RELEASE=$LATEST_RELEASE 15 | LATEST_RPI_BRANCH="rpi-6.1.y" 16 | RPI_BRANCH=$LATEST_RPI_BRANCH 17 | FILE="latest_boot.txt" 18 | RPI_FILE="rpi_archives_properties.txt" 19 | 20 | ### Allow selective builds. By default use the latest release 21 | if [ "$1" = "help" -o "$1" = "-h" ]; then 22 | echo "This script can be called with a parameter to select the release:" 23 | echo " There can be used 'dev'(or 'master' or 'main') for boot files from main," 24 | echo " or a specific release (for example '2022_R2') for specific boot files." 25 | echo " By default will use latest released version (right now being $LATEST_RELEASE)." 26 | exit 0 27 | elif [ "$1" = "dev" -o "$1" = "master" -o "$1" = "main" ]; then 28 | RELEASE="main" 29 | RPI_BRANCH="rpi-6.1.y" 30 | elif [ "$1" = "2021_R1" -o "$1" = "2021_r1" ]; then 31 | RELEASE="2021_r1" 32 | RPI_BRANCH="rpi-5.10.y" 33 | elif [ "$1" = "2021_R2" -o "$1" = "2021_r2" ]; then 34 | RELEASE="2021_r2" 35 | RPI_BRANCH="rpi-5.10.y" 36 | elif [ "$1" = "2022_R2" -o "$1" = "2022_r2" ]; then 37 | RELEASE="2022_r2" 38 | RPI_BRANCH="rpi-5.15.y" 39 | elif [ "$1" = "2023_R2" -o "$1" = "2023_r2" ]; then 40 | RELEASE="2023_r2" 41 | RPI_BRANCH="rpi-6.1.y" 42 | fi 43 | 44 | ### Verify if current script is latest version 45 | echo -e "\nVerifying if ./adi_update_boot.sh is up to date..." 46 | cd /usr/local/src 47 | if [ -d $REPO ]; then 48 | cd ./$REPO 49 | git checkout -f $BRANCH 50 | git fetch 51 | git checkout -f $BRANCH 2>/dev/null 52 | cd .. 53 | else 54 | git clone https://github.com/analogdevicesinc/$REPO.git || continue 55 | fi 56 | cd ./$REPO 57 | md5_self=`md5sum $0 | awk '{print $1}'` 58 | md5_new=`md5sum ./adi_update_boot.sh | awk '{print $1}'` 59 | if [ $md5_new != $md5_self ]; then 60 | echo -e "./adi_update_boot.sh has been updated, installing and switching to new one...\n" 61 | make install 62 | ./adi_update_boot.sh $@ 63 | exit 64 | else 65 | echo -e "./adi_update_boot.sh is up to date, continuing...\n" 66 | fi 67 | 68 | ### Check if script is ran as root 69 | if [ `id -u` != "0" ]; then 70 | echo -e "\nThis script must be run as root" 1>&2 71 | exit 1 72 | fi 73 | 74 | ### Check mount point of boot partition. 75 | # Mount it if doesn't exist, exit if mounting failed 76 | # Depending on carrier, by default it can be /boot or /media/boot 77 | mmc_mounted=$(mount | grep -i 'mmcblk0p1') 78 | if [[ "$mmc_mounted" == "" ]]; then 79 | FAT_MOUNT="/media/boot" 80 | mkdir -p $FAT_MOUNT 2>/dev/null 81 | mount /dev/mmcblk0p1 $FAT_MOUNT 82 | if [ $? -ne 0 ]; then 83 | echo "Mounting /dev/mmcblk0p1 failed" 1>&2 84 | exit 1 85 | fi 86 | else 87 | FAT_MOUNT=$(mount | grep 'mmcblk0p1' | cut -d' ' -f3) 88 | fi 89 | fatsize=`df | grep /dev/mmcblk0p1 | sed -n '1p' | awk '{print $2}'` 90 | if [ $fatsize -lt 300000 ]; then 91 | echo -e "\n==== WARNING ====\n" 92 | echo "Old SD Card Image detected. Please update!" 93 | echo "See http://wiki.analog.com/resources/tools-software/linux-software/zynq_images" 94 | echo -e "=================" 95 | umount $FAT_MOUNT 96 | exit 1 97 | fi 98 | 99 | ### Download new descriptor file 100 | rm $FILE 2>/dev/null 101 | echo -e "\nCheck latest available version..." 102 | wget --no-check-certificate "$SERVER/$SPATH/$RELEASE/$FILE" 103 | if [ $? -ne 0 ]; then 104 | echo -e "\nDownloading $SERVER/$SPATH/$RELEASE/$FILE failed - Aborting." 1>&2 105 | umount $FAT_MOUNT 106 | exit 1 107 | fi 108 | 109 | ### Convert any windows characters from descriptor file in unix format 110 | sed -i 's/\r$//' $FILE 111 | 112 | ### Extract version and release from downloaded file (latest_boot.txt) 113 | # First line can be boot_master_ or boot__ 114 | nr=$(sed -n 1p $FILE | tr -cd '_' | wc -c) 115 | if [ $nr -lt 5 ]; then 116 | new_version=$(sed -n 1p $FILE|sed 's/_/ /1'|sed 's/_/ /1'|cut -d' ' -f3) 117 | new_release=$(sed -n 1p $FILE|sed 's/_/ /1'|sed 's/_/ /1'|cut -d' ' -f2) 118 | else 119 | new_version=$(sed -n 1p $FILE|sed 's/_/ /1'|sed 's/_/ /2'|cut -d' ' -f3) 120 | new_release=$(sed -n 1p $FILE|sed 's/_/ /1'|sed 's/_/ /2'|cut -d' ' -f2) 121 | fi 122 | new_url=$(sed -n 2p $FILE) 123 | new_md5=$(sed -n 3p $FILE | cut -d' ' -f2) 124 | echo -e "\nLatest version available: $new_version" 125 | echo -e "Release: $new_release\n" 126 | 127 | ### Extract current version and release 128 | CURRENT_VERSION_FILE="$FAT_MOUNT/VERSION.txt" 129 | if [ -f $CURRENT_VERSION_FILE ]; then 130 | # If there is VERSION.txt - first line has next format: "Boot partition: [] " 131 | # Check first if contains also by counting number of spaces 132 | nr=$(sed -n 1p $CURRENT_VERSION_FILE | tr -cd ' ' | wc -c) 133 | if [ "$nr" -gt "2" ]; then 134 | current_version=$(sed -n 1p $CURRENT_VERSION_FILE | cut -d' ' -f4 | cut -d'-' -f1) 135 | current_release=$(sed -n 1p $CURRENT_VERSION_FILE | cut -d' ' -f3 | cut -d'-' -f1) 136 | else 137 | current_version=$(sed -n 1p $CURRENT_VERSION_FILE | cut -d' ' -f3 | cut -d'-' -f1) 138 | current_release=$(sed -n 8p $CURRENT_VERSION_FILE); current_release=${current_release##* } 139 | fi 140 | elif [ -f "$FAT_MOUNT/VERSION" ]; then 141 | # If there is VERSION (no .txt extension/used for older releases) there is "boot__" 142 | current_release=$(sed -n 1p $FAT_MOUNT/VERSION|sed 's/_/ /1'|sed 's/_/ /2'|cut -d' ' -f2) 143 | current_version=$(sed -n 1p $FAT_MOUNT/VERSION|sed 's/_/ /3'|cut -d' ' -f2) 144 | else 145 | echo -e "\nWarning! No VERSION or VERSION.txt file found in boot partition, current version of files cannot be extracted." 146 | echo "Please update whole SD card by following steps from http://wiki.analog.com/resources/tools-software/linux-software/zynq_images" 147 | umount $FAT_MOUNT 148 | rm $FILE 149 | exit 0 150 | fi 151 | echo -e "\nCurrent version detected: $current_version" 152 | echo -e "Release: $current_release\n" 153 | 154 | ### Compare old and new releases and versions 155 | current_release=$(echo $current_release | tr '[:upper:]' '[:lower:]') 156 | new_release=$(echo $new_release | tr '[:upper:]' '[:lower:]') 157 | if [ "$current_release" != "$new_release" ]; then 158 | echo -e "\nWarning! You want to update boot files from a different release: $new_release (current release: $current_release)" 159 | echo "In this case there may appear compatibility issues with root file system." 160 | while true 161 | do 162 | read -r -p 'Are you sure you want to continue?(y/n) ' answer 163 | case "$answer" in 164 | n) 165 | echo "Done." 166 | rm $FILE 167 | umount $FAT_MOUNT 168 | exit 0 169 | ;; 170 | y) 171 | echo -e "Continuing...\n" 172 | break 173 | ;; 174 | *) 175 | echo "Valid answers: y/n" 176 | ;; 177 | esac 178 | done 179 | fi 180 | 181 | # Transform current and new versions in 'date' datatype and compare them 182 | current_version_date=$(date -d $(echo "$current_version" | sed 's/_/-/g') +"%Y%m%d") 183 | new_version_date=$(date -d $(echo "$new_version" | sed 's/_/-/g') +"%Y%m%d") 184 | if [ $new_version_date -le $current_version_date ]; then 185 | echo "Already up to date!" 186 | rm $FILE 187 | umount $FAT_MOUNT 188 | exit 0 189 | fi 190 | 191 | ### Download new boot files archive and check md5sum 192 | echo -e "\nStart downloading $ARCHIVE_NAME ..." 193 | rm -rf $ARCHIVE_NAME 194 | wget --no-check-certificate -nc $new_url 195 | if [ $? -ne 0 ]; then 196 | echo "Download failed - aborting" 1>&2 197 | rm -f $FILE 198 | umount $FAT_MOUNT 199 | exit 1 200 | else 201 | key=`md5sum $ARCHIVE_NAME | awk '{print $1}'` 202 | if [ $key != $new_md5 ]; then 203 | echo "MD5SUM Error" 1>&2 204 | rm -rf $ARCHIVE_NAME 205 | rm -f $FILE 206 | umount $FAT_MOUNT 207 | exit 1 208 | fi 209 | fi 210 | 211 | ### Download RPI boot files (kernels and modules) and check md5 212 | 213 | rm -rf $RPI_FILE 214 | wget --no-check-certificate "$SERVER/$RPI_SPATH/$RPI_BRANCH/$RPI_FILE" 215 | if [ $? -ne 0 ]; then 216 | echo -e "\nDownloading $SERVER/$RPI_SPATH/$RPI_BRANCH/$RPI_FILE failed - Aborting." 1>&2 217 | umount $FAT_MOUNT 218 | exit 1 219 | fi 220 | 221 | ### Extract information from RPI_FILE: 222 | # line #2 is path to rpi_modules.tar.gz 223 | # line #3 is path to rpi_latest_boot.tar.gz 224 | # line #4 is checksum of modules archive 225 | # line #5 is checksum of boot archive 226 | 227 | rpi_modules_url=$(sed -n 2p $RPI_FILE) 228 | rpi_boot_url=$(sed -n 3p $RPI_FILE) 229 | rpi_modules_key=$(sed -n 4p $RPI_FILE | cut -d'=' -f2) 230 | rpi_boot_key=$(sed -n 5p $RPI_FILE | cut -d'=' -f2) 231 | 232 | RPI_MODULES_ARCHIVE_NAME="rpi_modules.tar.gz" 233 | echo -e "\nStart downloading $RPI_MODULES_ARCHIVE_NAME..." 234 | rm -rf $RPI_MODULES_ARCHIVE_NAME 235 | wget --no-check-certificate -nc $rpi_modules_url 236 | if [ $? -ne 0 ]; then 237 | echo "Download failed - aborting" 1>&2 238 | rm -rf $FILE $RPI_FILE $RPI_MODULES_ARCHIVE_NAME 239 | umount $FAT_MOUNT 240 | exit 1 241 | else 242 | key=`md5sum $RPI_MODULES_ARCHIVE_NAME | awk '{print $1}'` 243 | if [ $key != $rpi_modules_key ]; then 244 | echo "MD5SUM Error" 1>&2 245 | rm -rf $FILE $RPI_FILE $RPI_MODULES_ARCHIVE_NAME 246 | umount $FAT_MOUNT 247 | exit 1 248 | fi 249 | fi 250 | 251 | RPI_BOOT_ARCHIVE_NAME="rpi_latest_boot.tar.gz" 252 | echo -e "\nStart downloading $RPI_BOOT_ARCHIVE_NAME..." 253 | rm -rf $RPI_BOOT_ARCHIVE_NAME 254 | wget --no-check-certificate -nc $rpi_boot_url 255 | if [ $? -ne 0 ]; then 256 | echo "Download failed - aborting" 1>&2 257 | rm -rf $FILE $RPI_FILE $RPI_BOOT_ARCHIVE_NAME 258 | umount $FAT_MOUNT 259 | exit 1 260 | else 261 | key=`md5sum $RPI_BOOT_ARCHIVE_NAME | awk '{print $1}'` 262 | if [ $key != $rpi_boot_key ]; then 263 | echo "MD5SUM Error" 1>&2 264 | rm -rf $FILE $RPI_FILE $RPI_BOOT_ARCHIVE_NAME 265 | umount $FAT_MOUNT 266 | exit 1 267 | fi 268 | fi 269 | 270 | ############# Restoring boot config methods ############# 271 | 272 | ### Define "find_current_setup" method - find current setup by device tree md5sum 273 | find_current_setup () 274 | { 275 | # There may be devicetree.dtb, system.dtb, socfpga.dtb etc, depending on setup - get the file name 276 | dtb_file_name=$(basename $(ls $1/socfpg*.dtb 2>/dev/null) 2>/dev/null) 277 | if [[ "$dtb_file_name" == "" ]];then 278 | dtb_file_name=$(basename $(ls $1/devicetree.dtb 2>/dev/null) 2>/dev/null) 279 | if [[ "$dtb_file_name" == "" ]];then 280 | dtb_file_name=$(basename $(ls $1/system.dtb 2>/dev/null) 2>/dev/null) 281 | if [[ "$dtb_file_name" == "" ]];then 282 | exit 283 | fi 284 | fi 285 | fi 286 | key=`md5sum $1/$dtb_file_name | awk '{print $1}'` 287 | matching_files=$(find $1/ -name "$dtb_file_name") 288 | for file in $matching_files ; do 289 | t=`md5sum $file | awk '{print $1}'` 290 | if [ "$t" == "$key" ] ; then 291 | echo "$(dirname $file)" 292 | exit 293 | fi 294 | done 295 | } 296 | 297 | ### Define "restoring_boot_bin" method - try to restore BOOT.BIN 298 | restoring_boot_bin() 299 | { 300 | if [[ "$1" == *"zynq-"* ]] || [[ "$1" == *"zynqmp"* ]] || [[ "$1" == *"versal"* ]]; then 301 | echo -e "\nRestoring BOOT.BIN..." 302 | if [ -e "$1/BOOT.BIN" ]; then # BOOT.BIN may be 1 or 2 level up 303 | cp $1/BOOT.BIN $FAT_MOUNT/ 304 | else 305 | CURRENT_FOLDER=$(dirname $1) 306 | if [ -e "$CURRENT_FOLDER/BOOT.BIN" ]; then 307 | cp $CURRENT_FOLDER/BOOT.BIN $FAT_MOUNT/ 308 | else 309 | $CURRENT_FOLDER=$(dirname $CURRENT_FOLDER) 310 | if [ -e "$CURRENT_FOLDER/BOOT.BIN" ]; then 311 | cp $CURRENT_FOLDER/BOOT.BIN $FAT_MOUNT/ 312 | else 313 | echo "Warning! BOOT.BIN cannot be restored. " 314 | echo "You will have to manually copy specific boot files in boot partition root (see boot partition Readme.txt)" 315 | exit 1 316 | fi 317 | fi 318 | echo "BOOT.BIN restored." 319 | fi 320 | elif [[ "$1" == *"arria10"* ]]; then 321 | echo -e "\nRestoring socfpga_arria10_socdk.rbf/fit_spl_fpga.itb..." 322 | if [ -e $1/fit_spl_fpga.itb ]; then 323 | cp $1/fit_spl_fpga.itb $FAT_MOUNT/ 324 | else 325 | echo "Warning! fit_spl_fpga.itb (equivalent of rbf file for a10soc) cannot be restored. " 326 | echo "You will have to manually copy specific boot files in boot partition root (see boot partition Readme.txt)" 327 | exit 1 328 | fi 329 | echo "socfpga_arria10_socdk.rbf/fit_spl_fpga.itb restored." 330 | elif [[ "$1" == *"cyclone5"* ]]; then 331 | echo -e "\nRestoring soc_system.rbf..." 332 | if [ -e $1/soc_system.rbf ]; then 333 | cp $1/soc_system.rbf $FAT_MOUNT/ 334 | else 335 | echo "Warning! soc_system.rbf cannot be restored. " 336 | echo "You will have to manually copy specific boot files in boot partition root (see boot partition Readme.txt)" 337 | exit 1 338 | fi 339 | echo "soc_system.rbf restored." 340 | fi 341 | } 342 | 343 | ### Define "restoring_device_tree" method - try to restore device_tree 344 | restoring_device_tree() 345 | { 346 | echo -e "\nRestoring device tree..." 347 | if [[ "$1" == *"zynq-"* ]]; then 348 | device_tree_name="devicetree.dtb" 349 | elif [[ "$1" == *"zynqmp"* ]] || [[ "$1" == *"versal"* ]]; then 350 | device_tree_name="system.dtb" 351 | elif [[ "$1" == *"arria10"* ]]; then 352 | device_tree_name="socfpga_arria10_socdk_sdmmc.dtb" 353 | elif [[ "$1" == *"cyclone5"* ]]; then 354 | device_tree_name="socfpga.dtb" 355 | else 356 | echo "Warning! Device tree cannot be restored." 357 | echo "You will have to manually copy specific boot files in boot partition root (see boot partition Readme.txt)" 358 | exit 1 359 | fi 360 | if [ -e "$1/$device_tree_name" ]; then 361 | cp $1/$device_tree_name $FAT_MOUNT/ 362 | else 363 | echo "Warning! Device tree cannot be restored." 364 | echo "You will have to manually copy specific boot files in boot partition root (see boot partition Readme.txt)" 365 | exit 1 366 | fi 367 | echo "$device_tree_name restored." 368 | } 369 | 370 | ### Define "restoring_image" method - try to restore image 371 | restoring_image() 372 | { 373 | echo -e "\nRestoring image..." 374 | zynq_image="$FAT_MOUNT/zynq-common/uImage" 375 | zynqmp_image="$FAT_MOUNT/zynqmp-common/Image" 376 | versal_image="$FAT_MOUNT/versal-common/Image" 377 | a10soc_image="$FAT_MOUNT/socfpga_arria10_common/zImage" 378 | c5soc_image="$FAT_MOUNT/socfpga_cyclone5_common/zImage" 379 | de10nano_image="$FAT_MOUNT/socfpga_cyclone5_common/zImage" 380 | if [[ "$1" == *"zynq-"* ]]; then 381 | image=$zynq_image 382 | elif [[ "$1" == *"zynqmp"* ]]; then 383 | image=$zynqmp_image 384 | elif [[ "$1" == *"versal"* ]]; then 385 | image=$versal_image 386 | elif [[ "$1" == *"arria10"* ]]; then 387 | image=$a10soc_image 388 | elif [[ "$1" == *"de10"* ]]; then 389 | image=$de10nano_image 390 | elif [[ "$1" == *"cyclone5"* ]]; then 391 | image=$c5soc_image 392 | else 393 | echo "Warning! Image cannot be restored." 394 | echo "You will have to manually copy specific boot files in boot partition root (see boot partition Readme.txt)" 395 | exit 1 396 | fi 397 | if [ -e "$image" ]; then 398 | cp $image $FAT_MOUNT/ 399 | else 400 | echo "Warning! Image cannot be restored." 401 | echo "You will have to manually copy specific boot files in boot partition root (see boot partition Readme.txt)" 402 | exit 1 403 | fi 404 | echo -e "Image restored." 405 | } 406 | 407 | restoring_u-boot_file() 408 | { 409 | if [[ "$1" == *"u-boot.img" ]]; then 410 | echo -e "\nRestoring u-boot.img (specific to arria10soc projects starting with 2021_r1 release)..." 411 | FILE="u-boot.img" 412 | else 413 | echo -e "\nRestoring u-boot.scr (specific to cyclone5 projects)..." 414 | FILE="u-boot.scr" 415 | fi 416 | if [ -e $1 ]; then 417 | cp $1 $FAT_MOUNT/ 418 | else 419 | echo "Warning! $FILE cannot be restored." 420 | echo "You will have to manually copy specific boot files in boot partition root (see boot partition Readme.txt)" 421 | exit 1 422 | fi 423 | echo "$FILE restored." 424 | } 425 | 426 | restoring_extlinux() 427 | { 428 | echo -e "\nRestoring extlinux/extlinux.conf (specific to cyclone5 and arria10soc projects starting with 2021_r1 release)..." 429 | if [ -e "$1/extlinux.conf" ]; then 430 | mkdir -p $FAT_MOUNT/extlinux; 431 | cp $1/extlinux.conf $FAT_MOUNT/extlinux/ 432 | else 433 | echo "Warning! extlinux.conf cannot be restored." 434 | echo "You will have to manually copy specific boot files in boot partition root (see boot partition Readme.txt)" 435 | exit 1 436 | fi 437 | echo "extlinux.conf restored." 438 | } 439 | 440 | ### Define "restoring_extra_files" method - used for exceptions 441 | restoring_extra_files() 442 | { 443 | if [[ "$1" == *"cyclone5"* ]]; then 444 | restoring_u-boot_file "$1/u-boot.scr" 445 | restoring_extlinux $1 446 | elif [[ "$1" == *"arria10"* ]]; then 447 | restoring_u-boot_file "$1/u-boot.img" 448 | restoring_extlinux $1 449 | fi 450 | } 451 | 452 | ### Define "write_preloader" method - restore preloader for intel projests 453 | write_preloader() 454 | { 455 | if [[ "$1" == *"arria10"* ]]||[[ "$1" == *"cyclone5"* ]]; then 456 | # Preloader name depends on carrier and release 457 | echo -e "\nWriting preloader..." 458 | if [[ "$1" == *"arria10"* ]]; then 459 | preloader="u-boot-splx4.sfp" 460 | elif [[ "$1" == *"cyclone5"* ]]; then 461 | preloader="u-boot-with-spl.bin" 462 | fi 463 | if [ -e "$1/$preloader" ]; then 464 | cp $1/$preloader . 465 | dd if=$preloader of=/dev/mmcblk0p3 466 | if [ $? -ne 0 ];then 467 | echo "Writing preloader ($preloader) failed - aborting" 468 | echo "You will have to manually write it (see boot partition Readme.txt)" 469 | fi 470 | else 471 | echo "Warning! Preloader ($preloader) cannot be restored. " 472 | echo "You will have to manually write it (see boot partition Readme.txt)" 473 | exit 1 474 | fi 475 | echo "Preloader restored." 476 | fi 477 | } 478 | ################################################################### 479 | ### Check first if there is only one dtb in boot partition root, and if yes- detect configuration 480 | echo -e "First detecting current boot configuration..." 481 | socfpga_dtb=$(ls $FAT_MOUNT/socfpg*.dtb 2>/dev/null | wc -l) 482 | zynq_dtb=$(ls $FAT_MOUNT/devicetree.dtb 2>/dev/null | wc -l) 483 | zynqmp_dtb=$(ls $FAT_MOUNT/system.dtb 2>/dev/null | wc -l) 484 | number_of_dtb_files=$(( $socfpga_dtb + $zynq_dtb + $zynqmp_dtb )) 485 | #echo -e "\n socfpga_dtb: $socfpga_dtb\n zynq_dtb: $zynq_dtb\n zynqmp_dtb: $zynqmp_dtb\n sum: $number_of_dtb_files" 486 | if [ "$number_of_dtb_files" -ne 1 ]; then 487 | CURRENT_CONFIG="" 488 | else 489 | CURRENT_CONFIG=`find_current_setup $FAT_MOUNT` # CURRENT_CONFIG can be empty from here too 490 | fi 491 | if [ "$CURRENT_CONFIG" == "" ]; then 492 | echo -e "\nWarning! There is no or multiple device tree files in boot partition root in current setup." 493 | echo -e "You will have to manually copy specific boot files in boot partition root (see boot partition Readme.txt)\n" 494 | else 495 | echo -e "Current configuration: $CURRENT_CONFIG\n" 496 | fi 497 | 498 | default_files="fixup*.dat|start*.elf|bootcode.bin|cmdline.txt|config.txt|LICENCE.*|COPYING.linux|issue.txt" 499 | 500 | # Before proceeding with deleting files from /boot, check if unpacked files will fit 501 | 502 | # Size, in bytes, of uncompressed files from latest_boot_partition.tar.gz 503 | extracted_boot_files_size=$(echo $(gzip -l $ARCHIVE_NAME) | cut -d' ' -f'6') 504 | 505 | # Size, in bytes, of uncompressed files from rpi_latest_boot.tar.gz 506 | extracted_rpi_files_size=$(echo $(gzip -l $RPI_BOOT_ARCHIVE_NAME) | cut -d' ' -f'6') 507 | 508 | # Size, in bytes, of files that won't be deleted from /boot 509 | cd $FAT_MOUNT 510 | # Next line replace '|' with space in variable 'default_files', run 'du -cs' on the list of files then cut the total size from command output 511 | kuiper_rpi_files_size=$(echo $(du -cs $(echo $default_files | sed 's/|/ /g')) | rev | cut -d' ' -f'2' | rev) 512 | cd - 2>&1 >/dev/null 513 | 514 | # Computing required size by adding all previous values plus a buffer of 100 MB 515 | required_space=$(( $extracted_boot_files_size + $extracted_rpi_files_size + $kuiper_rpi_files_size + 104857600 )) 516 | 517 | # Computing size of /boot in bytes using 'df -B1' 518 | boot_partition_size=$(echo $(df -B1 $MOUNT_POINT) | cut -d' ' -f'9') 519 | 520 | if [[ ${required_space} -ge ${boot_partition_size} ]]; then 521 | echo "Downloaded archives cannot be extracted on $MOUNT_POINT because there is not enough space." 522 | echo "Please update whole SD card by following steps from http://wiki.analog.com/resources/tools-software/linux-software/zynq_images" 523 | rm -rf $FILE $RPI_FILE $ARCHIVE_NAME $RPI_BOOT_ARCHIVE_NAME $RPI_MODULES_ARCHIVE_NAME 524 | umount $FAT_MOUNT 525 | exit 0 526 | fi 527 | 528 | ### Replace files on boot partition 529 | echo -e "\n\nATTENTION!\nNext step will delete files from /boot. Make sure you backup modified files on another partition (rootfs for example) before proceeding next!!!\n" 530 | while true 531 | do 532 | read -r -p 'Are you sure you want to continue? (y/n) ' answer 533 | case "$answer" in 534 | n) 535 | umount $FAT_MOUNT 536 | exit 0 537 | ;; 538 | y) 539 | ### Remove boot partition 540 | echo "Removing boot files from /boot..." 541 | cd "$FAT_MOUNT" || exit 1 542 | rm -rf !($default_files) 543 | rm -rf ./overlays/*.dtbo 544 | cd - 2>&1 >/dev/null 545 | ### Extract new files 546 | echo -e "\nExtracting files from $ARCHIVE_NAME in boot partition... be patient!" 547 | tar -C $FAT_MOUNT -xzf ./$ARCHIVE_NAME --no-same-owner --checkpoint=.1000 548 | if [ $? -ne 0 ]; then 549 | echo "Extraction failed - aborting" 1>&2 550 | umount $FAT_MOUNT 551 | exit 1 552 | fi 553 | echo -e "\nExtracting files from $RPI_BOOT_ARCHIVE_NAME in boot partition... be patient!" 554 | tar -C $FAT_MOUNT -xvf ./$RPI_BOOT_ARCHIVE_NAME --no-same-owner --checkpoint=.1000 555 | if [ $? -ne 0 ]; then 556 | echo "Extraction failed - aborting" 1>&2 557 | umount $FAT_MOUNT 558 | exit 1 559 | fi 560 | echo -e "\nExtracting files from $RPI_MODULES_ARCHIVE_NAME in /lib/modules... be patient!" 561 | tar -C /lib/modules -xvf ./$RPI_MODULES_ARCHIVE_NAME --no-same-owner --checkpoint=.1000 562 | if [ $? -ne 0 ]; then 563 | echo "Extraction failed - aborting" 1>&2 564 | umount $FAT_MOUNT 565 | exit 1 566 | fi 567 | echo -e "\nBoot partition files were updated successfully." 568 | break 569 | ;; 570 | *) 571 | echo 'Valid answers: y/n' 572 | ;; 573 | esac 574 | done 575 | 576 | if [ "$CURRENT_CONFIG" != "" ]; then 577 | echo -e "\nNext step tries to restore boot configuration (overwrite boot files directly on boot partition root)." 578 | while true 579 | do 580 | read -r -p 'Are you sure you want to continue?(y/n) ' answer 581 | case "$answer" in 582 | n) 583 | echo "Done." 584 | umount $FAT_MOUNT 585 | exit 0 586 | ;; 587 | y) 588 | echo -e "\nTry to restore boot files configuration (BOOT.BIN, device tree, image etc)..." 589 | ### Call methods that try to restore current configuration 590 | restoring_boot_bin $CURRENT_CONFIG 591 | restoring_device_tree $CURRENT_CONFIG 592 | restoring_image $CURRENT_CONFIG 593 | restoring_extra_files $CURRENT_CONFIG 594 | write_preloader $CURRENT_CONFIG 595 | echo -e "\nDone\nNext reboot will use new files for booting." 596 | break 597 | ;; 598 | *) 599 | echo "Valid answers: y/n" 600 | ;; 601 | esac 602 | done 603 | fi 604 | 605 | echo -e "\nRemoving temporary files..." 606 | sync 607 | 608 | rm -rf $FILE $RPI_FILE 609 | rm -rf $ARCHIVE_NAME $RPI_BOOT_ARCHIVE_NAME $RPI_MODULES_ARCHIVE_NAME 610 | umount $FAT_MOUNT 611 | echo -e "\nDONE" 612 | exit 0 613 | -------------------------------------------------------------------------------- /adi_update_tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$(id -u)" != "0" ] ; then 4 | echo "This script must be run as root" 5 | exit 1 6 | fi 7 | 8 | wget --spider -nv http://github.com/analogdevicesinc 9 | EC=$? 10 | if [ $EC -ne 0 ];then 11 | ifconfig 12 | echo "\n\nNetwork Connection: FAILED\n" 13 | exit $EC 14 | fi 15 | 16 | #find md5of this file 17 | md5_self=`md5sum $0` 18 | 19 | # Keeps the scripts as the first thing, so we can check for updated 20 | # scripts ... 21 | # repository:branch:make_target 22 | 23 | BUILDS_DEV="linux_image_ADI-scripts:origin/main \ 24 | libiio:origin/main \ 25 | libad9361-iio:origin/main \ 26 | libad9166-iio:origin/main \ 27 | iio-oscilloscope:origin/main \ 28 | fru_tools:origin/main \ 29 | iio-fm-radio:origin/main \ 30 | jesd-eye-scan-gtk:origin/main \ 31 | diagnostic_report:origin/main \ 32 | wiki-scripts:origin/main \ 33 | colorimeter:origin/main" 34 | 35 | BUILDS_NEXT_STABLE="linux_image_ADI-scripts:origin/main \ 36 | libiio:origin/next_stable \ 37 | libad9361-iio:origin/next_stable \ 38 | libad9166-iio:origin/next_stable \ 39 | iio-oscilloscope:origin/next_stable \ 40 | fru_tools:origin/main \ 41 | iio-fm-radio:origin/main \ 42 | jesd-eye-scan-gtk:origin/main \ 43 | diagnostic_report:origin/main \ 44 | wiki-scripts:origin/main \ 45 | colorimeter:origin/2023_R2" 46 | 47 | BUILDS_2021_R1="linux_image_ADI-scripts:origin/main \ 48 | libiio:origin/2021_R1 \ 49 | libad9361-iio:origin/2021_R1 \ 50 | libad9166-iio:origin/main \ 51 | iio-oscilloscope:origin/2021_R1\ 52 | fru_tools:origin/2021_R1 \ 53 | iio-fm-radio:origin/main \ 54 | wiki-scripts:origin/main \ 55 | jesd-eye-scan-gtk:origin/2021_R1 \ 56 | diagnostic_report:origin/main \ 57 | colorimeter:origin/2021_R1" 58 | 59 | BUILDS_2021_R2="linux_image_ADI-scripts:origin/main \ 60 | libiio:origin/2021_R2 \ 61 | libad9361-iio:origin/2021_R2 \ 62 | libad9166-iio:origin/main \ 63 | iio-oscilloscope:origin/2021_R2\ 64 | fru_tools:origin/2021_R2 \ 65 | iio-fm-radio:origin/main \ 66 | wiki-scripts:origin/main \ 67 | jesd-eye-scan-gtk:origin/2021_R2 \ 68 | diagnostic_report:origin/main \ 69 | colorimeter:origin/2021_R2" 70 | 71 | BUILDS_2022_R2="linux_image_ADI-scripts:origin/main \ 72 | libiio:origin/2022_R2 \ 73 | libad9361-iio:origin/2022_R2 \ 74 | libad9166-iio:origin/2022_R2 \ 75 | iio-oscilloscope:origin/2022_R2\ 76 | fru_tools:origin/2022_R2 \ 77 | iio-fm-radio:origin/main \ 78 | wiki-scripts:origin/main \ 79 | jesd-eye-scan-gtk:origin/2022_R2 \ 80 | diagnostic_report:origin/main \ 81 | colorimeter:origin/2022_R2" 82 | 83 | BUILDS_2023_R2="linux_image_ADI-scripts:origin/main \ 84 | libiio:origin/2023_R2 \ 85 | libad9361-iio:origin/2023_R2 \ 86 | libad9166-iio:origin/2023_R2 \ 87 | iio-oscilloscope:origin/2023_R2\ 88 | fru_tools:origin/2023_R2 \ 89 | iio-fm-radio:origin/main \ 90 | wiki-scripts:origin/main \ 91 | jesd-eye-scan-gtk:origin/2023_R2 \ 92 | diagnostic_report:origin/main \ 93 | colorimeter:origin/2023_R2" 94 | 95 | # Define file where to save git info 96 | VERSION="/ADI_repos_git_info.txt" 97 | [ -f $VERSION ] && rm -rf $VERSION 98 | touch $VERSION 99 | 100 | write_git_info() 101 | { 102 | local git_link="https://github.com/analogdevicesinc/$1" 103 | local git_branch=$2 104 | echo "Repo : $git_link" >> $VERSION 105 | echo "Branch : $git_branch" >> $VERSION 106 | echo "Git_sha: $(git rev-parse --short HEAD)\n" >> $VERSION 107 | } 108 | 109 | 110 | do_build () 111 | { 112 | local prj=$1 113 | local target=$2 114 | make clean; 115 | make -j $(nproc) $target && make install && echo "\n Building $prj target $target finished Successfully\n" || 116 | echo "Building $prj Failed\n" 117 | } 118 | 119 | rfsom_box () 120 | { 121 | cd /usr/local/src 122 | 123 | if [ -d "input-event-daemon" ] ; then 124 | cd ./input-event-daemon 125 | git pull 126 | else 127 | git clone https://github.com/gandro/input-event-daemon.git 128 | cd ./input-event-daemon 129 | fi 130 | make clean 131 | make input-event-daemon 132 | make install 133 | if [ "$(grep input-event-daemon /etc/rc.local | wc -l)" -eq "0" ] ; then 134 | # add /usr/bin/input-event-daemon to /etc/rc.local 135 | sed -i '0,/^exit 0$/s/^exit 0.*/\/usr\/bin\/input-event-daemon\n&/' /etc/rc.local 136 | fi 137 | 138 | cp $1/input-event-daemon.conf.rfsombox /etc/input-event-daemon.conf 139 | 140 | cd /usr/local/src 141 | 142 | sudo apt-get -y install qt5-default gpsd python-gps gpsd-clients libmozjs-24-bin \ 143 | mplayer libx264-142 libncurses5 libreadline5 libreadline-dev libexif12 \ 144 | libexif-dev python3-scipy sox 145 | 146 | curl -L http://github.com/micha/jsawk/raw/master/jsawk > /tmp/jsawk 147 | mv /tmp/jsawk /usr/bin/jsawk 148 | chmod 777 /usr/bin/jsawk 149 | ln -s /usr/bin/js24 /usr/bin/js 150 | 151 | if [ -d "rfsom-box-gui" ] ; then 152 | cd ./rfsom-box-gui 153 | for i in $(find ./ -name Makefile -exec -exec dirname {} \; ) ; do 154 | pushd $(pwd) 155 | cd ${i} 156 | if [ $(grep "uninstall:" Makefile | wc -l) -ne "0" ] ; then 157 | make uninstall 2>/dev/null 158 | fi 159 | popd 160 | done 161 | git clean -f -d -x 162 | git fetch 163 | git checkout -f master 164 | git pull 165 | else 166 | git clone https://github.com/analogdevicesinc/rfsom-box-gui.git 167 | cd ./rfsom-box-gui 168 | fi 169 | 170 | write_git_info "rfsom-box-gui" "master" 171 | 172 | if [ ! -d ./build_packrf ] ; then 173 | mkdir ./build_packrf 174 | fi 175 | cd ./build_packrf 176 | qmake .. 177 | make && make install 178 | cd .. 179 | 180 | sudo systemctl daemon-reload 181 | #auto-start packrf 182 | sudo systemctl enable packrf.service 183 | 184 | if [ ! -d ./build_fft ] ; then 185 | mkdir ./build_fft 186 | fi 187 | cd ./build_fft 188 | cmake ../fft-plot 189 | make && make install 190 | 191 | cd ../tun_tap 192 | make && make install 193 | cd .. 194 | 195 | #install ffmpeg, if needed 196 | if [ $(which ffmpeg | wc -l) -eq "0" ] ; then 197 | if [ "$(arch)" = "armv7l" ] ; then 198 | cd /usr/local/src 199 | wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-armhf-32bit-static.tar.xz 200 | mkdir ffmpeg-release-armhf-32bit 201 | cd ffmpeg-release-armhf-32bit 202 | # skip first level 203 | tar xvf ../ffmpeg-release-armhf-32bit-static.tar.xz --strip 1 204 | rm ../ffmpeg-release-armhf-32bit-static.tar.xz 205 | ln -s /usr/local/src/ffmpeg-release-armhf-32bit/ffmpeg \ 206 | /usr/local/bin/ffmpeg 207 | fi 208 | # should support 64-bit, but not yet 209 | fi 210 | 211 | #install fim 212 | # FIM (Fbi IMproved) image viewer program 213 | if [ $(which fim | wc -l) -eq "0" ] ; then 214 | cd /usr/local/src 215 | wget http://download.savannah.nongnu.org/releases/fbi-improved/fim-0.6-trunk.tar.gz 216 | tar xvf fim-0.6-trunk.tar.gz 217 | cd fim-0.6-trunk 218 | ./configure 219 | make && make install 220 | 221 | rm /usr/local/src/fim-0.6-trunk.tar.gz 222 | fi 223 | 224 | cd /usr/local/src/ 225 | #install plutosdr-scripts 226 | git clone https://github.com/analogdevicesinc/plutosdr_scripts 227 | cd plutosdr_scripts 228 | 229 | write_git_info "plutosdr_scripts" "master" 230 | 231 | make 232 | cp cal_ad9361 /usr/local/bin 233 | 234 | /usr/local/src/rfsom-box-gui/wpa-supplicant/install.sh 235 | 236 | # install a low end terminal (bterm) for /dev/fb 237 | apt-get -y install libbogl-dev bogl-bterm fonts-droid otf2bdf 238 | # create a bitmap font, from the true-type font 239 | otf2bdf -p 8 -d 140 \ 240 | -o /usr/share/fonts/truetype/droid/DroidSansMono.bdf \ 241 | /usr/share/fonts/truetype/droid/DroidSansMono.ttf 242 | # create a font for the terminal 243 | # https://manpages.debian.org/jessie/libbogl-dev/bdftobogl.1.en.html 244 | bdftobogl -b /usr/share/fonts/truetype/droid/DroidSansMono.bdf > \ 245 | /usr/share/fonts/truetype/droid/DroidSansMono.bgf 246 | 247 | } 248 | 249 | # Allow selective builds by default build the latest release branches 250 | if [[ "$1" =~ "dev" ]] || [[ "$1" = "main" ]] 251 | then 252 | BUILDS=$BUILDS_DEV 253 | elif [[ "$1" = "2018_R2" ]] || [[ "$1" = "2018_r2" ]] || \ 254 | [[ "$1" = "2019_R1" ]] || [[ "$1" = "2019_r1" ]] || \ 255 | [[ "$1" = "2019_R2" ]] || [[ "$1" = "2019_r2" ]] 256 | then 257 | echo "Only last two releases are supported for update." 258 | exit 1 259 | elif [[ "$1" = "2021_R1" ]] || [[ "$1" = "2021_r1" ]] 260 | then 261 | BUILDS=$BUILDS_2021_R1 262 | elif [[ "$1" = "2021_R2" ]] || [[ "$1" = "2021_r2" ]] 263 | then 264 | BUILDS=$BUILDS_2021_R2 265 | elif [[ "$1" = "2022_R2" ]] || [[ "$1" = "2022_r2" ]] 266 | then 267 | BUILDS=$BUILDS_2022_R2 268 | elif [[ "$1" = "2023_R2" ]] || [[ "$1" = "2023_r2" ]] 269 | then 270 | BUILDS=$BUILDS_2023_R2 271 | elif [[ "$1" = "NEXT_STABLE" ]] || [[ "$1" = "next_stable" ]] 272 | then 273 | BUILDS=$BUILDS_NEXT_STABLE 274 | elif [ -n "$1" ] 275 | then 276 | BUILDS=$1 277 | else 278 | BUILDS=$BUILDS_2023_R2 279 | fi 280 | 281 | for i in $BUILDS 282 | do 283 | REPO=`echo $i | cut -d':' -f1` 284 | BRANCH=`echo $i | cut -s -d':' -f2` 285 | TARGET=`echo $i | cut -s -d':' -f3` 286 | 287 | # selective build without branch? use main 288 | if [ -z $BRANCH ] 289 | then 290 | echo HERE 291 | BRANCH=origin/main 292 | TARGET="" 293 | fi 294 | 295 | cd /usr/local/src 296 | 297 | if [ -d $REPO ] 298 | then 299 | cd ./$REPO 300 | echo "\n *** Updating $REPO BRANCH $BRANCH ***" 301 | dirty=`git diff --shortstat 2> /dev/null | tail -n1` 302 | if [ "$dirty" != "" ] 303 | then 304 | echo "Tree is dirty - generating branch" `date +"%F"` 305 | git branch `date +"%F"` 306 | fi 307 | git checkout -f $BRANCH 308 | make uninstall 2>/dev/null 309 | git fetch 310 | git checkout -f $BRANCH 2>/dev/null 311 | else 312 | echo "\n *** Cloning $REPO/$BRANCH ***" 313 | git clone https://github.com/analogdevicesinc/$REPO.git || continue 314 | cd ./$REPO 315 | git checkout $BRANCH || continue 316 | fi 317 | 318 | write_git_info "$REPO" "$BRANCH" 319 | 320 | echo "\n *** Building $REPO ***" 321 | 322 | # Handle some specialties here 323 | if [ $REPO = "linux_image_ADI-scripts" ] 324 | then 325 | new=`md5sum ./adi_update_tools.sh` 326 | if [ "$new" = "$md5_self" ] 327 | then 328 | echo ./adi_update_tools.sh script is the same, continuing 329 | # Now we are sure we are using the latest, make sure the pre-reqs 330 | # are installed. If someone reports an error, fix the list. 331 | apt-get -y install libgtk2.0-dev libmatio-dev \ 332 | libfftw3-dev libxml2 libxml2-dev bison flex libavahi-common-dev \ 333 | libavahi-client-dev libcurl4-openssl-dev libjansson-dev cmake libaio-dev ncurses-dev \ 334 | libserialport-dev libcdk5-dev 335 | if [ "$?" -ne "0" ] ; then 336 | echo Catastrophic error in prerequisite packages, please report error to: 337 | echo https://ez.analog.com/community/linux-device-drivers/linux-software-drivers 338 | exit 339 | else 340 | # Non-essential applications, which help out sometime 341 | apt-get -y install gpsd gpsd-clients u-boot-tools evtest 342 | 343 | if [ ! -f /etc/fw_env.config ] 344 | then 345 | cp ./fw_env.config /etc/ 346 | fi 347 | 348 | REFCLK=$(fw_printenv -n ad9361_ext_refclk) 349 | if [ $? -eq 0 ]; then 350 | echo $REFCLK | grep '^<.*>$' 351 | if [ $? -ne 0 ]; then 352 | REFCLK="<${REFCLK}>" 353 | fw_setenv ad9361_ext_refclk ${REFCLK} 354 | fi 355 | fi 356 | 357 | p=$(pwd) 358 | grep -q "RFSOM-BOX" /sys/firmware/devicetree/base/model && rfsom_box $p 359 | cd $p 360 | fi 361 | #Misc fixup: 362 | sed -i 's/wiki.analog.org/wiki.analog.com/g' /etc/update-motd.d/10-help-text 363 | sed -i 's/ analog.com/ www.wiki.analog.com www.analog.com/g' /etc/network/if-up.d/htpdate 364 | else 365 | # run the new one instead, and then just quit 366 | echo ./adi_update_tools.sh has been updated, switching to new one 367 | ./adi_update_tools.sh $@ 368 | exit 369 | fi 370 | elif [ $REPO = "libiio" ] 371 | then 372 | # Just in case an old version is still under /usr/local 373 | rm -f /usr/local/lib/libiio.so* /usr/local/sbin/iiod \ 374 | /usr/local/bin/iio_* /usr/local/include/iio.h \ 375 | /usr/local/lib/pkgconfig/libiio.pc 376 | 377 | # Remove old services file 378 | rm -f /etc/avahi/services/iio.service 379 | 380 | # Remove old init.d links if they exist 381 | if [ -f /etc/init.d/iiod.sh ] ; then 382 | rm -f /etc/init.d/iiod.sh 383 | update-rc.d -f iiod.sh remove 384 | fi 385 | if [ -f /etc/init.d/iiod ] ; then 386 | rm -f /etc/init.d/iiod 387 | update-rc.d -f iiod remove 388 | fi 389 | 390 | # New libiio versions install to /usr/lib/arm-linux-gnueabihf; 391 | # remove the old ones that might still be inside /usr/lib 392 | rm -f /usr/lib/libiio.so* 393 | 394 | grep -q usb_functionfs_descs_head_v2 /usr/include/linux/usb/functionfs.h 395 | if [ "$?" -eq "1" ] ; then 396 | # Get a more recent version of functionfs.h, allowing libiio to build 397 | # the IIOD USB backend 398 | wget -O /usr/include/linux/usb/functionfs.h http://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/usb/functionfs.h 399 | fi 400 | 401 | rm -rf build 402 | 403 | # Apparently, under undetermined circumstances CMake will output the build 404 | # files to the source directory instead of the current directory. 405 | # Here we use the undocumented -B and -H options to force the directory 406 | # where the build files are generated. 407 | if grep -Fxq "/lib/systemd" /sbin/init 408 | then 409 | EXTRA_CMAKE=$EXTRA_CMAKE" -DWITH_SYSTEMD=ON" 410 | elif grep -Fxq "upstart" /sbin/init 411 | then 412 | EXTRA_CMAKE=$EXTRA_CMAKE" -DWITH_UPSTART=ON" 413 | else 414 | EXTRA_CMAKE=$EXTRA_CMAKE" -DWITH_SYSVINIT=ON" 415 | fi 416 | 417 | cmake ${EXTRA_CMAKE} -DWITH_HWMON=ON -DWITH_SERIAL_BACKEND=ON -DWITH_MAN=ON -DWITH_EXAMPLES=ON \ 418 | -DPYTHON_BINDINGS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_COLOR_MAKEFILE=OFF -Bbuild -H. 419 | cd build 420 | elif [ $REPO = "libad9361-iio" ] 421 | then 422 | rm -rf build 423 | 424 | # Same as above 425 | cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DCMAKE_COLOR_MAKEFILE=OFF -Bbuild -H. 426 | cd build 427 | elif [ $REPO = "libad9166-iio" ] 428 | then 429 | rm -rf build 430 | 431 | cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DCMAKE_COLOR_MAKEFILE=OFF \ 432 | -DPYTHON_BINDINGS=ON -Bbuild -H. 433 | cd build 434 | elif [ $REPO = "mathworks_tools" ] 435 | then 436 | cd ./motor_control/linux_utils/ 437 | elif [ $REPO = "iio-oscilloscope" ] 438 | then 439 | rm -rf build 440 | cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_COLOR_MAKEFILE=OFF -Bbuild -H. 441 | cd build 442 | elif [ $REPO = "wiki-scripts" ] 443 | then 444 | cd iio/iio_jesd204_fsm_sync 445 | rm -rf build 446 | cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_COLOR_MAKEFILE=OFF -Bbuild -H. 447 | cd build 448 | fi 449 | 450 | do_build $REPO $TARGET 451 | done 452 | -------------------------------------------------------------------------------- /adrv9009_multichip_sync.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Turn off continous SYSREF, and enable GPI SYSREF request 4 | iio_reg hmc7044 0x5a 0 5 | 6 | for i in {0..11} 7 | do 8 | echo Performing MCS step: $i 9 | 10 | iio_attr -q -d adrv9009-phy multichip_sync $i >/dev/null 2>&1 11 | iio_attr -q -d adrv9009-phy-b multichip_sync $i >/dev/null 2>&1 12 | 13 | done 14 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | trigger: 2 | - master 3 | - main 4 | - kuiper2.0 5 | 6 | pr: 7 | - master 8 | - main 9 | - kuiper2.0 10 | 11 | pool: 12 | vmImage: ubuntu-latest 13 | 14 | steps: 15 | - checkout: self 16 | fetchDepth: 1 17 | clean: true 18 | 19 | - script: | 20 | make 21 | sudo make install 22 | displayName: 'Run make and make install' 23 | 24 | - script: | 25 | bash CI/file_check.sh Makefile 26 | bash CI/file_check.sh usb-gadget-service/install_gt.sh 27 | displayName: 'Check existing files' 28 | -------------------------------------------------------------------------------- /bad_monitor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "\ndmesg\n=======" > ~/bad.monitor 4 | dmesg >> ~/bad.monitor 5 | echo "\ndpms\n=======" >> ~/bad.monitor 6 | cat /sys/class/drm/card0-HDMI-A-1/dpms >> ~/bad.monitor 7 | echo "\nstatus\n=======" >> ~/bad.monitor 8 | cat /sys/class/drm/card0-HDMI-A-1/status >> ~/bad.monitor 9 | echo "\nenabled\n=======" >> ~/bad.monitor 10 | cat /sys/class/drm/card0-HDMI-A-1/enabled >> ~/bad.monitor 11 | echo "\nmodes\n=======" >> ~/bad.monitor 12 | cat /sys/class/drm/card0-HDMI-A-1/modes >> ~/bad.monitor 13 | echo "\nregmap\n" >> ~/bad.monitor 14 | cat /sys/kernel/debug/regmap/*/registers >> ~/bad.monitor 15 | echo "\nedid\n=======" >> ~/bad.monitor 16 | hexdump -C /sys/class/drm/card0-HDMI-A-1/edid >> ~/bad.monitor 17 | gzip ~/bad.monitor 18 | -------------------------------------------------------------------------------- /dds_buf_random.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # buffer size, let's use 512 samples, or 1024 bytes 4 | buffer_size=1024 5 | 6 | # find the DAC 7 | for i in $(find -L /sys/bus/iio/devices -maxdepth 2 -name name) 8 | do 9 | dev_name=$(cat $i) 10 | if [ "$dev_name" = "cf-ad9122-core-lpc" ] || [ "$dev_name" = "axi-ad9144-hpc" ] || [ "$dev_name" = "cf-ad9361-dds-core-lpc" ] ; then 11 | dac_path=$(echo $i | sed 's:/name$::') 12 | break 13 | fi 14 | done 15 | 16 | # Get the associated dev file 17 | dev=/dev/$(echo $dac_path | awk -F "/" '{print $NF}') 18 | if [ ! -c $dev ] ; then 19 | echo "Can't find device $dev" 20 | exit 21 | fi 22 | 23 | # set the buffer size 24 | echo $buffer_size > $dac_path/buffer/length 25 | 26 | # generate the random data, and give it to the DAC 27 | dd if=/dev/urandom of=$dev bs=$buffer_size count=1 28 | 29 | #enable things 30 | echo 1 > $dac_path/buffer/enable 31 | 32 | #Wait 5 seconds 33 | sleep 5 34 | 35 | #turn if off before we bring down everyone's WiFi 36 | echo 0 > $dac_path/buffer/enable 37 | 38 | -------------------------------------------------------------------------------- /dds_set_scale.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #check in the input 4 | if [ $1 -le -1 ] ; then 5 | echo "input out of range, (needs to be 0-15)" 6 | exit 7 | fi 8 | 9 | if [ $1 -ge 16 ] ; then 10 | echo "input out of range (needs to be 0-15)" 11 | exit 12 | fi 13 | 14 | # find the DAC 15 | for i in $(find -L /sys/bus/iio/devices -maxdepth 2 -name name) 16 | do 17 | dev_name=$(cat $i) 18 | if [ "$dev_name" = "cf-ad9122-core-lpc" ] || [ "$dev_name" = "axi-ad9144-hpc" ] || [ "$dev_name" = "axi-ad9152-hpc" ]; then 19 | dac_path=$(echo $i | sed 's:/name$::') 20 | attrs="out_altvoltage0_1A_scale \ 21 | out_altvoltage1_1B_scale \ 22 | out_altvoltage2_2A_scale \ 23 | out_altvoltage3_2B_scale" 24 | elif [ "$dev_name" = "cf-ad9361-dds-core-lpc" ] ; then 25 | dac_path=$(echo $i | sed 's:/name$::') 26 | attrs="out_altvoltage0_TX1_I_F1_scale \ 27 | out_altvoltage1_TX1_I_F2_scale \ 28 | out_altvoltage2_TX1_Q_F1_scale \ 29 | out_altvoltage3_TX1_Q_F2_scale \ 30 | out_altvoltage4_TX2_I_F1_scale \ 31 | out_altvoltage5_TX2_I_F2_scale \ 32 | out_altvoltage6_TX2_Q_F1_scale \ 33 | out_altvoltage7_TX2_Q_F2_scale" 34 | fi 35 | done 36 | 37 | mag=$(echo "scale=6; 1 / ( 2 ^ $1 )" | bc) 38 | for attr in $attrs 39 | do 40 | echo $mag > $dac_path/$attr 41 | done 42 | 43 | echo -n "amplitude set to " 44 | cat $dac_path/$(echo $attrs | cut -d" " -f 1) 45 | -------------------------------------------------------------------------------- /dds_sweep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for i in $(find -L /sys/bus/iio/devices -maxdepth 2 -name name) 4 | do 5 | dev_name=$(cat $i) 6 | # find the DAC on FMComms1 7 | if [ "$dev_name" = "cf-ad9122-core-lpc" ] || [ "$dev_name" = "axi-ad9144-hpc" ] ; then 8 | dac_path=$(echo $i | sed 's:/name$::') 9 | A1=out_altvoltage0_1A_frequency 10 | A2=out_altvoltage2_2A_frequency 11 | B1=out_altvoltage1_1B_frequency 12 | B2=out_altvoltage3_2B_frequency 13 | sampl=`cat $dac_path/out_altvoltage_sampling_frequency` 14 | break 15 | fi 16 | 17 | # if that didn't work, try FMComms2/3 18 | if [ "$dev_name" = "cf-ad9361-dds-core-lpc" ] ; then 19 | dac_path=$(echo $i | sed 's:/name$::') 20 | A1=out_altvoltage0_TX1_I_F1_frequency 21 | B1=out_altvoltage1_TX1_I_F2_frequency 22 | A2=out_altvoltage2_TX1_Q_F1_frequency 23 | B2=out_altvoltage3_TX1_Q_F2_frequency 24 | A3=out_altvoltage4_TX2_I_F1_frequency 25 | B3=out_altvoltage5_TX2_I_F2_frequency 26 | A4=out_altvoltage6_TX2_Q_F1_frequency 27 | B4=out_altvoltage7_TX2_Q_F2_frequency 28 | sampl=`cat $dac_path/out_altvoltage_sampling_frequency` 29 | break 30 | fi 31 | done 32 | 33 | if [ -z $dac_path ] ; then 34 | echo Could not find any DDS to set 35 | exit 36 | fi 37 | 38 | ny=`expr $sampl / 2` 39 | 40 | #save the current settings 41 | init=`cat $dac_path/$A1` 42 | 43 | # Set DDSn_A 44 | freq_A(){ 45 | if [ ! -z $A1 ] ; then echo $1 > $dac_path/$A1; fi 46 | if [ ! -z $A2 ] ; then echo $1 > $dac_path/$A2; fi 47 | if [ ! -z $A3 ] ; then echo $1 > $dac_path/$A3; fi 48 | if [ ! -z $A4 ] ; then echo $1 > $dac_path/$A4; fi 49 | } 50 | 51 | # Set DDSn_B 52 | freq_B(){ 53 | if [ ! -z $B1 ] ; then echo $1 > $dac_path/$B1; fi 54 | if [ ! -z $B2 ] ; then echo $1 > $dac_path/$B2; fi 55 | if [ ! -z $B3 ] ; then echo $1 > $dac_path/$B3; fi 56 | if [ ! -z $B4 ] ; then echo $1 > $dac_path/$B4; fi 57 | } 58 | 59 | for i in `seq 1000000 1000000 $ny` 60 | do 61 | freq_A $i 62 | freq_B `expr $ny - $i` 63 | echo $i 64 | sleep 1 65 | done 66 | 67 | freq_A $init 68 | freq_B $init 69 | -------------------------------------------------------------------------------- /dds_test_scales.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # find the DAC 4 | for i in $(find -L /sys/bus/iio/devices -maxdepth 2 -name name) 5 | do 6 | dev_name=$(cat $i) 7 | if [ "$dev_name" = "cf-ad9122-core-lpc" ] || [ "$dev_name" = "axi-ad9144-hpc" ] ; then 8 | dac_path=$(echo $i | sed 's:/name$::') 9 | attrs="out_altvoltage0_1A_scale \ 10 | out_altvoltage1_1B_scale \ 11 | out_altvoltage2_2A_scale \ 12 | out_altvoltage3_2B_scale" 13 | elif [ "$dev_name" = "cf-ad9361-dds-core-lpc" ] ; then 14 | dac_path=$(echo $i | sed 's:/name$::') 15 | attrs="out_altvoltage0_TX1_I_F1_scale \ 16 | out_altvoltage1_TX1_I_F2_scale \ 17 | out_altvoltage2_TX1_Q_F1_scale \ 18 | out_altvoltage3_TX1_Q_F2_scale \ 19 | out_altvoltage4_TX2_I_F1_scale \ 20 | out_altvoltage5_TX2_I_F2_scale \ 21 | out_altvoltage6_TX2_Q_F1_scale \ 22 | out_altvoltage7_TX2_Q_F2_scale" 23 | fi 24 | done 25 | 26 | for mag in 1.000000 0.500000 0.250000 0.125000 0.062500 0.031250 0.015625 0.007812 0.003906 0.001953 0.000976 0.000488 0.000244 0.000122 0.000061 0.000030; 27 | do 28 | for attr in $attrs 29 | do 30 | echo $mag > $dac_path/$attr 31 | done 32 | echo $mag 33 | sleep 1 34 | done 35 | 36 | mag=0.250000 37 | for attr in $attrs 38 | do 39 | echo $mag > $dac_path/$attr 40 | done 41 | -------------------------------------------------------------------------------- /enable_dhcp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Re-enable the default DHCP-based NetworkManager support. Use to revert the 4 | # static IP configuration performed by the enable_static_ip.sh script. 5 | # 6 | # Example usage: 7 | # enable_dhcp.sh 8 | # 9 | # WARNING: Do not use this script if there is a custom network configuration 10 | # set up in /etc/network/interfaces as it will be overwritten. 11 | 12 | set -e 13 | 14 | if [[ ${UID} -ne 0 ]]; then 15 | echo "This script must be run as root!" 16 | exit 1 17 | fi 18 | 19 | if grep -qi kuiper "/etc/os-release"; then 20 | cat <<-EOF > /etc/dhcpcd.conf 21 | hostname 22 | EOF 23 | systemctl daemon-reload 24 | systemctl restart dhcpcd.service 25 | else 26 | echo "Re-enabling DHCP via NetworkManager for all network interfaces" 27 | 28 | cat <<-EOF > /etc/network/interfaces 29 | # interfaces(5) file used by ifup(8) and ifdown(8) 30 | # Include files from /etc/network/interfaces.d: 31 | source-directory /etc/network/interfaces.d 32 | EOF 33 | 34 | # enable DHCP via NetworkManager (assumes the config file hasn't been touched much) 35 | sed -i 's/^managed=true/managed=false/' /etc/NetworkManager/NetworkManager.conf 36 | 37 | service network-manager restart 38 | fi -------------------------------------------------------------------------------- /enable_dummy_display.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | if [[ ! -d "/usr/share/X11/xorg.conf.d/" ]]; then 4 | mkdir -p "/usr/share/X11/xorg.conf.d" 5 | fi 6 | 7 | echo 'Section "Device" 8 | Identifier "Configured Video Device" 9 | Driver "dummy" 10 | EndSection 11 | 12 | Section "Monitor" 13 | Identifier "Configured Monitor" 14 | HorizSync 31.5-48.5 15 | VertRefresh 50-70 16 | EndSection 17 | 18 | Section "Screen" 19 | Identifier "Default Screen" 20 | Monitor "Configured Monitor" 21 | Device "Configured Video Device" 22 | DefaultDepth 24 23 | SubSection "Display" 24 | Depth 24 25 | Modes "1280x720" 26 | EndSubSection 27 | EndSection' > /usr/share/X11/xorg.conf.d/xorg.conf 28 | -------------------------------------------------------------------------------- /enable_static_ip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Enable a static IP for eth0 (or another interface) on Ubuntu-based setups. 4 | # Note that the wanted IP address should be specified as the first argument; 5 | # otherwise, it defaults to 192.168.0.101. Also, the interface can be specified 6 | # as the second argument if the default (eth0) isn't wanted. 7 | # 8 | # Example usage: 9 | # enable_static_ip.sh [10.66.99.101] [eth1] 10 | # 11 | # WARNING: Do not use this script if there is a custom network configuration 12 | # set up in /etc/network/interfaces as it will be overwritten. 13 | 14 | set -e 15 | 16 | IP_ADDR=${1:-192.168.0.101} 17 | ETH_DEV=${2:-eth0} 18 | 19 | if [[ ${UID} -ne 0 ]]; then 20 | echo "This script must be run as root!" 21 | exit 1 22 | fi 23 | 24 | echo "Enabling the static IP address ${IP_ADDR} on ${ETH_DEV}" 25 | 26 | if grep -qi kuiper "/etc/os-release"; then 27 | cat <<-EOF > /etc/dhcpcd.conf 28 | interface ${ETH_DEV} 29 | static ip_address=${IP_ADDR}/24 30 | EOF 31 | systemctl daemon-reload 32 | systemctl restart dhcpcd.service 33 | else 34 | # disable NetworkManager (assumes the config file hasn't been touched much) 35 | sed -i 's/^managed=false/managed=true/' /etc/NetworkManager/NetworkManager.conf 36 | 37 | # set up loopback and add static IP config for ${ETH_DEV} (defaults to eth0) 38 | cat <<-EOF > /etc/network/interfaces 39 | auto lo 40 | iface lo inet loopback 41 | 42 | auto ${ETH_DEV} 43 | iface ${ETH_DEV} inet static 44 | address ${IP_ADDR} 45 | netmask 255.255.255.0 46 | EOF 47 | 48 | service network-manager restart 49 | fi -------------------------------------------------------------------------------- /erase_fru_eeprom.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$(id -u)" != "0" ] ; then 4 | echo "This script must be run as root" 5 | exit 1 6 | fi 7 | 8 | for i in $(find /sys/ -name eeprom) 9 | do 10 | if [ `stat -c %s $i` -ne "256" ] ; then 11 | continue; 12 | fi 13 | 14 | yn=foo 15 | while [[ "$yn" != "yes" && "$yn" != "no" ]] 16 | do 17 | echo $i 18 | read -p "erase that file? " yn 19 | done 20 | 21 | if [ "$yn" != "yes" ] ; then 22 | echo Did not erase $i 23 | continue 24 | fi 25 | 26 | echo erasing $i 27 | dd if=/dev/zero of=$i bs=256 count=1 28 | done 29 | -------------------------------------------------------------------------------- /fix-display-port.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Fix DP audio and X11 for Jupiter 3 | 4 | [Service] 5 | Type=oneshot 6 | ExecStart=/bin/bash -c "fix_x11.sh; fix_DP_audio.sh" 7 | 8 | [Install] 9 | WantedBy=multi-user.target 10 | -------------------------------------------------------------------------------- /fix_DP_audio.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if grep -qi -e "ZCU102" -e "ADRV9009-ZU" -e "Jupiter SDR" /sys/firmware/devicetree/base/model; then 4 | # modify audio default sampling rate 5 | sed -i '/default-sample-rate/c\default-sample-rate = 48000' /etc/pulse/daemon.conf 2>/dev/null || true 6 | fi 7 | -------------------------------------------------------------------------------- /fix_x11.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if grep -qi -e "ZCU102" -e "ADRV9009-ZU" -e "Jupiter SDR" /sys/firmware/devicetree/base/model; then 4 | # create X11 xorg.conf 5 | printf "Section \"Device\"\n Identifier \"myfb\"\n Driver \"fbdev\"\n Option \"fbdev\" \"/dev/fb0\"\nEndSection\n" \ 6 | > /etc/X11/xorg.conf 7 | 8 | # delete xorg.conf created by enable_dummy_display if exists 9 | rm -f /usr/share/X11/xorg.conf.d/xorg.conf 10 | else 11 | rm -f /etc/X11/xorg.conf 12 | fi 13 | -------------------------------------------------------------------------------- /fw_env.config: -------------------------------------------------------------------------------- 1 | # MTD device name Device offset Env. size Flash sector size 2 | /dev/mtd1 0x0000 0x20000 0x20000 3 | -------------------------------------------------------------------------------- /input-event-daemon.conf.rfsombox: -------------------------------------------------------------------------------- 1 | # 2 | # this file needs to be relocated to: 3 | # /etc/input-event-daemon.conf 4 | # 5 | 6 | [Global] 7 | listen = /dev/input/by-path/platform-gpio-keys-power-event 8 | listen = /dev/input/by-path/platform-fpga-axi@0:pzsdr_sound-event 9 | 10 | 11 | [Keys] 12 | # connect the LTC2955 INTterupt pin 13 | # The LTC2955 asserts the INT pin low when it receives the turn-off command 14 | # from the pushbutton, so power things off. 15 | POWER = poweroff 16 | MEDIA = amixer sset 'Capture' toggle 17 | VOLUMEDOWN = amixer sset 'Headphone' 3- unmute 18 | VOLUMEUP = amixer sset 'Headphone' 3+ unmute 19 | -------------------------------------------------------------------------------- /jupiter_scripts/fan-control: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | GPIO_CHIP=334 4 | FAN_CTL=145 5 | USER_LED=14 6 | SLEEP_INTERVAL=1 7 | 8 | TEMP_LOW=73000 9 | TEMP_HIGH=78000 10 | TEMP_POWEROFF=100000 11 | 12 | gpio_export() { 13 | if [ ! -d /sys/class/gpio/gpio$(expr $GPIO_CHIP + $FAN_CTL) ]; then 14 | echo $(expr $GPIO_CHIP + $FAN_CTL) > /sys/class/gpio/export 15 | echo "out" > /sys/class/gpio/gpio$(expr $GPIO_CHIP + $FAN_CTL)/direction 16 | echo $(expr $GPIO_CHIP + $USER_LED) > /sys/class/gpio/export 17 | echo "out" > /sys/class/gpio/gpio$(expr $GPIO_CHIP + $USER_LED)/direction 18 | fi 19 | } 20 | 21 | fan_low() { 22 | echo "0" > /sys/class/gpio/gpio$(expr $GPIO_CHIP + $FAN_CTL)/value 23 | } 24 | 25 | fan_high() { 26 | echo "1" > /sys/class/gpio/gpio$(expr $GPIO_CHIP + $FAN_CTL)/value 27 | } 28 | 29 | led_toggle() { 30 | if [ $(cat /sys/class/gpio/gpio$(expr $GPIO_CHIP + $USER_LED)/value) -eq "1" ]; then 31 | echo "0" > /sys/class/gpio/gpio$(expr $GPIO_CHIP + $USER_LED)/value 32 | else 33 | echo "1" > /sys/class/gpio/gpio$(expr $GPIO_CHIP + $USER_LED)/value 34 | fi 35 | } 36 | 37 | temp() { 38 | echo $(iio_attr -c adrv9002-phy temp0 input) 39 | } 40 | 41 | last_five=() 42 | 43 | daemon() { 44 | while :; do 45 | led_toggle 46 | current_temp=$(temp) 47 | 48 | last_five=("${last_five[@]:1}") 49 | last_five+=("$current_temp") 50 | 51 | average=0 52 | for i in ${last_five[@]}; do 53 | let average+=$i 54 | done 55 | average=$(expr $average / 5) 56 | 57 | if [[ $average -ge $TEMP_POWEROFF ]]; then 58 | poweroff 59 | fi 60 | 61 | if [[ $average -le $TEMP_LOW ]]; then 62 | fan_low 63 | fi 64 | if [[ $average -ge $TEMP_HIGH ]]; then 65 | fan_high 66 | fi 67 | 68 | sleep $SLEEP_INTERVAL 69 | done 70 | } 71 | 72 | last_five=() 73 | last_five+=("$(temp)") 74 | last_five+=("$(temp)") 75 | last_five+=("$(temp)") 76 | last_five+=("$(temp)") 77 | last_five+=("$(temp)") 78 | 79 | gpio_export 80 | 81 | daemon 82 | -------------------------------------------------------------------------------- /jupiter_scripts/fan-control.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=fan-control 3 | 4 | [Service] 5 | Type=simple 6 | ExecStart=/bin/sh -c 'grep -i -e "Jupiter SDR" /sys/firmware/devicetree/base/model && /usr/bin/fan-control' 7 | 8 | [Install] 9 | WantedBy=multi-user.target 10 | -------------------------------------------------------------------------------- /lightdm_timeout.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | TimeoutStopSec=5 3 | -------------------------------------------------------------------------------- /pll_tx_sweep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "$0 " 3 | 4 | start=$1 5 | end=$2 6 | inc=$3 7 | pause=$4 8 | 9 | if [ -z $inc ] ; then 10 | inc=5 11 | fi 12 | 13 | if [ -z $pause ] ; then 14 | pause=1 15 | fi 16 | 17 | # find the TX LO generator 18 | for i in $(find /sys -name name) 19 | do 20 | if [ "`cat $i`" = "adf4351-tx-lpc" ] ; then 21 | tx_lo_path=$(echo $i | sed 's:/name$::') 22 | if [ -z $start ] ; then 23 | start=400 24 | fi 25 | if [ -z $end ] ; then 26 | end=4000 27 | fi 28 | pll=out_altvoltage0_frequency 29 | break 30 | fi 31 | if [ "`cat $i`" = "ad9361-phy" ] ; then 32 | tx_lo_path=$(echo $i | sed 's:/name$::') 33 | if [ -z $start ] ; then 34 | start=100 35 | fi 36 | if [ -z $end ] ; then 37 | end=6000 38 | fi 39 | pll=out_altvoltage1_TX_LO_frequency 40 | break 41 | fi 42 | done 43 | 44 | if [ -z $tx_lo_path ] ; then 45 | echo "Can't find PLL" 46 | exit 1 47 | fi 48 | 49 | 50 | freq_tx() { 51 | echo $1 > $tx_lo_path/$pll 52 | } 53 | 54 | for i in `seq $start $inc $end`; 55 | do 56 | echo $i 57 | freq_tx `expr $i \\* 1000000` 58 | sleep $pause 59 | done 60 | -------------------------------------------------------------------------------- /power-service/adi-power.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Analog Devices power up/down sequence 3 | 4 | [Service] 5 | Type=oneshot 6 | RemainAfterExit=true 7 | ExecStart=/usr/bin/python3 /usr/share/systemd/adi_power.py up 8 | ExecStop=/usr/bin/python3 /usr/share/systemd/adi_power.py down 9 | 10 | [Install] 11 | WantedBy=multi-user.target 12 | -------------------------------------------------------------------------------- /power-service/adi_power.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import subprocess 3 | 4 | MODEL_PATH = '/sys/firmware/devicetree/base/model' 5 | 6 | def read_file(path): 7 | with open(path, 'r') as file: 8 | return file.read() 9 | 10 | def read_model_file(): 11 | # Device tree strings are null-terminated 12 | return read_file(MODEL_PATH).strip('\0') 13 | 14 | def run_py_script(path, args): 15 | subprocess.run(['python3', path, *args]) 16 | 17 | if __name__ == '__main__': 18 | model = read_model_file() 19 | 20 | print(f'Found model name: {model}') 21 | 22 | SYSTEMD_PATH = '/usr/share/systemd' 23 | 24 | STINGRAY_POWER_PATH = f'{SYSTEMD_PATH}/stingray_power.py' 25 | STINGRAY_V1_0_MODEL = 'Stingray ZynqMP ZCU102 Rev1.0' 26 | 27 | if model == STINGRAY_V1_0_MODEL: 28 | run_py_script(STINGRAY_POWER_PATH, [sys.argv[1]]) 29 | -------------------------------------------------------------------------------- /power-service/stingray_power.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from time import sleep 4 | 5 | class IIO: 6 | def write_reg(self, dev_name, reg, val): 7 | # print('iio_reg ' + dev_name + ' ' + str(reg) + ' ' + str(val)) 8 | value = os.popen('iio_reg ' + dev_name + ' ' + str(reg) + ' ' + str(val)).read() 9 | if value == '': 10 | return '' 11 | return int(value, 16) 12 | 13 | def read_reg(self, dev_name, reg): 14 | value = os.popen('iio_reg ' + dev_name + ' ' + str(reg)).read() 15 | if value == '': 16 | return '' 17 | return int(value, 16) 18 | 19 | def write_dev_attr(self, dev_name, attr, val): 20 | # print('iio_attr -d ' + dev_name + ' ' + str(attr) + ' ' + str(val)) 21 | value = os.popen('iio_attr -d ' + dev_name + ' ' + str(attr) + ' ' + str(val)).read() 22 | if value == '': 23 | return '' 24 | return int(value, 10) 25 | 26 | def read_dev_attr(self, dev_name, attr): 27 | value = os.popen('iio_attr -d ' + dev_name + ' ' + str(attr)).read() 28 | if value == '': 29 | return '' 30 | return int(value, 10) 31 | 32 | def write_dev_ch_attr(self, dev_name, channel, attr, val, dir = ''): 33 | value = os.popen('iio_attr -c ' + dir + ' ' + dev_name + ' ' + str(channel) + ' ' + str(attr) + ' ' + str(val)).read() 34 | if value == '': 35 | return '' 36 | try: 37 | return int(value, 10) 38 | except ValueError: 39 | return value 40 | 41 | def read_dev_ch_attr(self, dev_name, channel, attr): 42 | value = os.popen('iio_attr -c ' + dev_name + ' ' + str(channel) + ' ' + str(attr)).read() 43 | if value == '': 44 | return '' 45 | return int(value, 10) 46 | 47 | class Ltc2992: 48 | _dev_name='ltc2992' 49 | _gpio_name='' 50 | 51 | def __init__(self): 52 | self.export_gpios() 53 | self.get_gpio() 54 | 55 | def export_gpios(self): 56 | device = '' 57 | devices = os.popen('grep "" /sys/class/gpio/gpiochip*/device/name').read() 58 | devices = devices.split(sep="\n") 59 | for line in devices: 60 | if self._dev_name in line: 61 | device = line 62 | break 63 | if device == '': 64 | return 65 | device = device.split(sep="/") 66 | for line in device: 67 | if 'gpiochip' in line: 68 | device = line 69 | break 70 | if device == '': 71 | return 72 | device = device.replace('gpiochip', '') 73 | gpio = int(device, 10) 74 | os.popen('echo ' + str(gpio + 0) + ' > /sys/class/gpio/export').read() 75 | os.popen('echo ' + str(gpio + 1) + ' > /sys/class/gpio/export').read() 76 | os.popen('echo ' + str(gpio + 2) + ' > /sys/class/gpio/export').read() 77 | os.popen('echo ' + str(gpio + 3) + ' > /sys/class/gpio/export').read() 78 | 79 | def get_gpio(self): 80 | device = '' 81 | devices = os.popen('ls /sys/class/gpio').read() 82 | devices = devices.split(sep="\n") 83 | for line in devices: 84 | if (self._dev_name in line) & ('GPIO1' in line): 85 | device = line 86 | break 87 | device = device.replace('GPIO1', 'GPIO') 88 | if device == '': 89 | raise SystemError('Stingray power: Cant get GPIOs') 90 | self._gpio_name = device 91 | 92 | def power_sequencer_enable(self): 93 | value = os.popen('cat /sys/class/gpio/' + self._gpio_name + '1/value').read() 94 | if value == '': 95 | return 0 96 | val = int(value, 10) 97 | return val == 0 98 | 99 | def p5v_enable(self): 100 | value = os.popen('cat /sys/class/gpio/' + self._gpio_name + '2/value').read() 101 | if value == '': 102 | return 0 103 | val = int(value, 10) 104 | return val == 0 105 | 106 | def power_sequencer_power_good(self): 107 | value = os.popen('cat /sys/class/gpio/' + self._gpio_name + '3/value').read() 108 | if value == '': 109 | return 0 110 | val = int(value, 10) 111 | return val == 0 112 | 113 | def p5v_power_good(self): 114 | value = os.popen('cat /sys/class/gpio/' + self._gpio_name + '4/value').read() 115 | if value == '': 116 | return 0 117 | val = int(value, 10) 118 | return val == 0 119 | 120 | class GPIOS: 121 | P5V_CTRL_PIN = 4 122 | PWR_UP_DOWN_PIN = 5 123 | 124 | def get_device(self, dev_label): 125 | devices = os.popen('grep "" /sys/bus/iio/devices/iio\:device*/label').read() 126 | devices = devices.split(sep="\n") 127 | for line in devices: 128 | if dev_label in line: 129 | device = line 130 | break 131 | 132 | device = device.split(sep="/") 133 | for line in device: 134 | if 'iio:device' in line: 135 | device = line 136 | break 137 | 138 | return device 139 | 140 | def gpio_pulse(self, iio, ch): 141 | device = self.get_device(dev_label='stingray_control') 142 | iio.write_dev_ch_attr(dev_name = device, channel = 'voltage' + str(ch), attr = 'raw', val = 1) 143 | iio.write_dev_ch_attr(dev_name = device, channel = 'voltage' + str(ch), attr = 'raw', val = 0) 144 | 145 | class Stingray: 146 | """ Class for Stingray board control. """ 147 | _revision = 'B' 148 | _POWER_DELAY = 0.2 149 | _fully_powered = False 150 | _devices = list() 151 | 152 | def __init__(self): 153 | self._iio = IIO() 154 | self._ltc = Ltc2992() 155 | self._gpio = GPIOS() 156 | 157 | class Adar1000: 158 | _channels = 4 159 | _BIAS_CODE_TO_VOLTAGE_SCALE = -0.018824 160 | 161 | INTERFACE_CONFIG_A_REG = 0x0000 162 | SCRATCHPAD_REG = 0x000A 163 | LD_WRK_REGS_REG = 0x0028 164 | PA1_BIAS_ON_REG = 0x0029 165 | PA2_BIAS_ON_REG = 0x002A 166 | PA3_BIAS_ON_REG = 0x002B 167 | PA4_BIAS_ON_REG = 0x002C 168 | LNA_BIAS_ON_REG = 0x002D 169 | RX_ENABLES_REG = 0x002E 170 | TX_ENABLES_REG = 0x002F 171 | MISC_ENABLES_REG = 0x0030 172 | SW_CTRL_REG = 0x0031 173 | ADC_CTRL_REG = 0x0032 174 | ADC_OUTPUT_REG = 0x0033 175 | BIAS_CURRENT_RX_LNA_REG = 0x0034 176 | BIAS_CURRENT_RX_REG = 0x0035 177 | BIAS_CURRENT_TX_REG = 0x0036 178 | BIAS_CURRENT_TX_DRV_REG = 0x0037 179 | MEM_CTRL_REG = 0x0038 180 | RX_BEAM_COMMON_REG = 0x0039 181 | TX_BEAM_COMMON_REG = 0x003A 182 | PA1_BIAS_OFF_REG = 0x0046 183 | PA2_BIAS_OFF_REG = 0x0047 184 | PA3_BIAS_OFF_REG = 0x0048 185 | PA4_BIAS_OFF_REG = 0x0049 186 | LNA_BIAS_OFF_REG = 0x004A 187 | TX_TO_RX_DELAY_REG = 0x004B 188 | RX_TO_TX_DELAY_REG = 0x004C 189 | TX_BEAM_STEP_START_REG = 0x004D 190 | TX_BEAM_STEP_STOP_REG = 0x004E 191 | RX_BEAM_STEP_START_REG = 0x004F 192 | RX_BEAM_STEP_STOP_REG = 0x0050 193 | RX_BIAS_RAM_CTL_REG = 0x0051 194 | TX_BIAS_RAM_CTL_REG = 0x0052 195 | 196 | def __init__(self, name): 197 | self._name = name 198 | 199 | def initialize(self, iio, pa_off=-2.5, pa_on=-2.5, lna_off=-2, lna_on=-2): 200 | # print('Initialize device: ' + self._name) 201 | # Set the bias currents 202 | iio.write_reg(self._name, self.BIAS_CURRENT_RX_LNA_REG, 0x08) 203 | iio.write_reg(self._name, self.BIAS_CURRENT_RX_REG, 0x55) 204 | iio.write_reg(self._name, self.BIAS_CURRENT_TX_REG, 0x2D) 205 | iio.write_reg(self._name, self.BIAS_CURRENT_TX_DRV_REG, 0x06) 206 | 207 | # Disable RAM control 208 | iio.write_dev_attr(self._name, 'beam_mem_enable', 0) 209 | iio.write_dev_attr(self._name, 'bias_mem_enable', 0) 210 | iio.write_dev_attr(self._name, 'common_mem_enable', 0) 211 | 212 | # Enable all internal amplifiers 213 | iio.write_dev_attr(self._name, 'rx_vga_enable', 1) 214 | iio.write_dev_attr(self._name, 'rx_vm_enable', 1) 215 | iio.write_dev_attr(self._name, 'rx_lna_enable', 1) 216 | iio.write_dev_attr(self._name, 'tx_vga_enable', 1) 217 | iio.write_dev_attr(self._name, 'tx_vm_enable', 1) 218 | iio.write_dev_attr(self._name, 'tx_drv_enable', 1) 219 | 220 | # Disable Tx/Rx paths 221 | iio.write_dev_attr(self._name, 'tx_en', 0) 222 | iio.write_dev_attr(self._name, 'rx_en', 0) 223 | iio.write_dev_attr(self._name, 'tr_source', 0) 224 | 225 | # Enable the PA/LNA bias DACs 226 | iio.write_dev_attr(self._name, 'bias_enable', 1) 227 | iio.write_dev_attr(self._name, 'lna_bias_out_enable', 1) 228 | iio.write_dev_attr(self._name, 'bias_ctrl', 1) 229 | 230 | # Configure the external switch control 231 | iio.write_dev_attr(self._name, 'sw_drv_tr_state', 1) 232 | iio.write_dev_attr(self._name, 'sw_drv_en_tr', 1) 233 | 234 | # Set the default LNA bias 235 | dac_code = int(lna_on / self._BIAS_CODE_TO_VOLTAGE_SCALE) 236 | val = iio.write_dev_attr(self._name, 'lna_bias_on', dac_code) 237 | if val != dac_code: 238 | raise SystemError('Cant write device attribute') 239 | 240 | dac_code = int(lna_off / self._BIAS_CODE_TO_VOLTAGE_SCALE) 241 | val = iio.write_dev_attr(self._name, 'lna_bias_off', dac_code) 242 | if val != dac_code: 243 | raise SystemError('Stingray power: Cant write device attribute') 244 | 245 | # Settings for each channel 246 | for i in range(self._channels): 247 | # Default channel enable 248 | val = iio.write_dev_ch_attr(self._name, 'voltage' + str(i), 'powerdown', 1, '-i') #RX 249 | if val != 1: 250 | raise SystemError('Stingray power: Cant write device attribute') 251 | val = iio.write_dev_ch_attr(self._name, 'voltage' + str(i), 'powerdown', 1, '-o') #TX 252 | if val != 1: 253 | raise SystemError('Stingray power: Cant write device attribute') 254 | 255 | # Default PA bias 256 | dac_code = int(pa_on / self._BIAS_CODE_TO_VOLTAGE_SCALE) 257 | val = iio.write_dev_ch_attr(self._name, 'voltage' + str(i), 'pa_bias_on', dac_code) 258 | if val != dac_code: 259 | raise SystemError('Stingray power: Cant write device attribute') 260 | 261 | dac_code = int(pa_off / self._BIAS_CODE_TO_VOLTAGE_SCALE) 262 | val = iio.write_dev_ch_attr(self._name, 'voltage' + str(i), 'pa_bias_off', dac_code) 263 | if val != dac_code: 264 | raise SystemError('Stingray power: Cant write device attribute') 265 | 266 | 267 | iio.write_dev_ch_attr(self._name, 'voltage' + str(i), 'hardwaregain', -0.127, '-i') #RX 268 | val = iio.write_dev_ch_attr(self._name, 'voltage' + str(i), 'phase', 0, '-i') #RX 269 | 270 | val = iio.write_dev_ch_attr(self._name, 'voltage' + str(i), 'hardwaregain', -0.127, '-o') #TX 271 | val = iio.write_dev_ch_attr(self._name, 'voltage' + str(i), 'phase', 0, '-o') #TX 272 | 273 | def pulse_power_pin(self, which): 274 | if which.lower() == 'pwr_up_down': 275 | self._gpio.gpio_pulse(self._iio, self._gpio.PWR_UP_DOWN_PIN) 276 | elif which.lower() == '5v_ctrl': 277 | self._gpio.gpio_pulse(self._iio, self._gpio.P5V_CTRL_PIN) 278 | else: 279 | raise ValueError("Can't pulse the pin:" + which.lower()) 280 | 281 | def partially_powered(self): 282 | """ Status of the board's power tree connected to the ADM1186 """ 283 | 284 | # If Rev.A, there's no way to check on the rails directly, we have to rely on SPI readback 285 | if self._revision == 'A': 286 | devices = os.popen('grep "" /sys/bus/iio/devices/iio\:device*/name').read() 287 | devices = devices.split(sep="\n") 288 | for line in devices: 289 | if 'adar1000' in line: 290 | return True 291 | 292 | return False 293 | else: 294 | # If Rev.B, we can directly read the sequencer's EN and PG status. 295 | return bool(self._ltc.power_sequencer_enable() & self._ltc.power_sequencer_power_good()) 296 | 297 | def fully_powered(self): 298 | """ Status of the board's full power tree """ 299 | 300 | # If Rev.A, we have to rely on the flags 301 | if self._revision == 'A': 302 | return bool(self.partially_powered() & self._fully_powered) 303 | 304 | # If Rev.B, we can directly read the EN and status signals. 305 | else: 306 | return bool(self.partially_powered() & self._ltc.p5v_enable() & self._ltc.p5v_power_good()) 307 | 308 | def get_devices(self): 309 | devices = os.popen('grep "" /sys/bus/iio/devices/iio\:device*/name').read() 310 | devices = devices.split(sep="\n") 311 | for line in devices: 312 | if 'adar1000' in line: 313 | device = line 314 | device = device.split(sep="/") 315 | for line in device: 316 | if 'iio:device' in line: 317 | a = self.Adar1000(line) 318 | self._devices.append(a) 319 | 320 | def initialize_devices(self, pa_off=-2.5, pa_on=-2.5, lna_off=-2, lna_on=-2): 321 | """ Initialize the devices to allow for safe powerup of the board 322 | 323 | Args: 324 | pa_off (float): Voltage to set the PA_BIAS_OFF values to during initialization 325 | pa_on (float): Voltage to set the PA_BIAS_ON values to during initialization 326 | lna_off (float): Voltage to set the LNA_BIAS_OFF values to during initialization 327 | lna_on (float): Voltage to set the LNA_BIAS_ON values to during initialization 328 | """ 329 | for adar in self._devices: 330 | adar.initialize(self._iio, pa_off, pa_on, lna_off, lna_on) 331 | 332 | def powerdown(self): 333 | self.get_devices() 334 | print('Stingray power: Found ' + str(len(self._devices)) + ' ADAR1000 devices') 335 | 336 | # If the +5V rail is up 337 | if self.fully_powered(): 338 | # Turn on a single PA to help bring this down faster 339 | self._iio.write_dev_attr(self._devices[1]._name, 'rx_en', 0) 340 | self._iio.write_dev_attr(self._devices[1]._name, 'tr_source', 0) 341 | self._iio.write_dev_attr(self._devices[1]._name, 'tx_en', 1) 342 | 343 | dac_code = int(-1.1 / self._devices[1]._BIAS_CODE_TO_VOLTAGE_SCALE) 344 | self._iio.write_dev_ch_attr(self._devices[1]._name, 'voltage' + str(0), 'pa_bias_on', dac_code) 345 | 346 | # Send a signal to power down the +5V rail 347 | self.pulse_power_pin('5v_ctrl') 348 | # Wait for the +5V rail to come down 349 | if self._revision == 'A': 350 | sleep(self._POWER_DELAY / 4) 351 | else: 352 | while self.fully_powered() > 0.5: 353 | sleep(0.01) 354 | else: 355 | print("Stingray power: Board not powered") 356 | 357 | # If the board is partially powered up 358 | if self.partially_powered(): 359 | # Turn on a single cell's LNAs to help bring this down faster 360 | self._iio.write_dev_attr(self._devices[1]._name, 'lna_bias_out_enable', 0) 361 | 362 | # Send a signal to power down the Stingray board's sequenced rails 363 | self.pulse_power_pin('pwr_up_down') 364 | 365 | # Wait for the rest of the rails to come down 366 | if self._revision == 'A': 367 | sleep(self._POWER_DELAY) 368 | else: 369 | while self.partially_powered(): 370 | sleep(0.01) 371 | 372 | print("Stingray power: Power down sequence succeeded") 373 | 374 | def bind_devices(self): 375 | os.popen('echo -n "spi1.1" > /sys/bus/spi/drivers/adar1000/unbind').read() 376 | os.popen('echo -n "spi1.1" > /sys/bus/spi/drivers/adar1000/bind').read() 377 | 378 | os.popen('echo -n "spi1.2" > /sys/bus/spi/drivers/adar1000/unbind').read() 379 | os.popen('echo -n "spi1.2" > /sys/bus/spi/drivers/adar1000/bind').read() 380 | 381 | os.popen('echo -n "spi1.3" > /sys/bus/spi/drivers/adar1000/unbind').read() 382 | os.popen('echo -n "spi1.3" > /sys/bus/spi/drivers/adar1000/bind').read() 383 | 384 | os.popen('echo -n "spi1.4" > /sys/bus/spi/drivers/adar1000/unbind').read() 385 | os.popen('echo -n "spi1.4" > /sys/bus/spi/drivers/adar1000/bind').read() 386 | 387 | os.popen('systemctl restart iiod').read() 388 | 389 | def powerup(self, enable_5v=True, **kwargs): 390 | # Get any keywords that were given 391 | pa_off = kwargs.get('pa_off', -2.5) 392 | pa_on = kwargs.get('pa_on', -2.5) 393 | lna_off = kwargs.get('lna_off', -2) 394 | lna_on = kwargs.get('lna_on', -2) 395 | 396 | if self.fully_powered(): 397 | return 398 | 399 | # If the board is powered down 400 | if not self.partially_powered(): 401 | self.pulse_power_pin('pwr_up_down') 402 | 403 | # Wait for supplies to settle 404 | if self._revision == 'A': 405 | sleep(self._POWER_DELAY) 406 | else: 407 | loops = 0 408 | while not self._ltc.power_sequencer_power_good(): 409 | sleep(0.01) 410 | loops += 1 411 | 412 | if loops > 50: 413 | raise SystemError("Stingray power: Power sequencer PG pin never went high, something's wrong") 414 | 415 | self.bind_devices() 416 | 417 | if not self.partially_powered: 418 | raise SystemError("Stingray power: Board didn't power up!") 419 | 420 | self.get_devices() 421 | if len(self._devices) == 0: 422 | raise SystemError("Stingray power: No ADAR1000 devices found") 423 | else: 424 | print('Stingray power: Found ' + str(len(self._devices)) + ' ADAR1000 devices') 425 | 426 | # Initialize all the ADAR1000s 427 | self.initialize_devices(pa_off=pa_off, pa_on=pa_on, lna_off=lna_off, lna_on=lna_on) 428 | 429 | # Send a signal to power up the +5V rail 430 | if enable_5v and not self.fully_powered(): 431 | self.pulse_power_pin('5v_ctrl') 432 | if not self.fully_powered(): 433 | print("Stingray power: Power up sequence failed") 434 | else: 435 | print("Stingray power: Power up sequence succeeded") 436 | 437 | if __name__ == '__main__': 438 | try: 439 | if sys.argv[1] == 'up': 440 | print("Stingray power: Start power up sequence") 441 | stingray = Stingray() 442 | stingray.powerup(enable_5v=True) 443 | elif sys.argv[1] == 'partial': 444 | print("Stingray power: Start partial power up sequence") 445 | stingray = Stingray() 446 | stingray.powerup(enable_5v=False) 447 | elif sys.argv[1] == 'down': 448 | print("Stingray power: Start power down sequence") 449 | stingray = Stingray() 450 | stingray.powerdown() 451 | else: 452 | print('Stingray power: Please specify "up", "partial" or "down" option') 453 | except IndexError: 454 | print('Stingray power: Please specify "up" or "down" option') 455 | -------------------------------------------------------------------------------- /regcompare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Wraps the regdump.sh script allowing for snapshot comparisons between device 4 | # register states. It can be passed the same device name and number of register 5 | # values that regdump.sh accepts since it just passes all arguments on to 6 | # regdump.sh to handle. 7 | # 8 | # If register values change between the two states, a side-by-side diff is 9 | # shown between the previous and current values. Note that the diff currently 10 | # uses static spacing for the columns so make sure the terminal sized properly 11 | # to view the differences without linewraps. If no values change, a message 12 | # relating that no changes occurred is returned instead. 13 | # 14 | # To exit the script at anytime, hit Ctrl-C and the temporary files used to 15 | # store the register value states will be removed. 16 | 17 | trap cleanup SIGINT 18 | 19 | cleanup() { 20 | rm -f "${PREVIOUS}" "${CURRENT}" 21 | echo 22 | exit 23 | } 24 | 25 | echoerr() { echo "$@" 1>&2; } 26 | 27 | if [[ ${UID} -ne 0 ]]; then 28 | echoerr "This script must be run as root!" 29 | exit 1 30 | fi 31 | 32 | if [[ ! -x $(type -P regdump.sh) ]]; then 33 | echoerr "Can't find the regdump.sh script!" 34 | exit 1 35 | fi 36 | 37 | PREVIOUS=$(mktemp) 38 | CURRENT=$(mktemp) 39 | 40 | regdump.sh $@ > "${PREVIOUS}" 41 | ret=$? 42 | [[ ${ret} -ne 0 ]] && exit ${ret} 43 | 44 | while true; do 45 | read -p "Hit enter to diff registers (and Ctrl-C to quit)" 46 | regdump.sh $@ > "${CURRENT}" 47 | ret=$? 48 | [[ ${ret} -ne 0 ]] && exit ${ret} 49 | CHANGES=$(diff --suppress-common-lines -y "${PREVIOUS}" "${CURRENT}") 50 | if [[ -z ${CHANGES} ]]; then 51 | echo "No register value changes" 52 | else 53 | printf "%-62s%s\n" "===========" "==========" 54 | printf "%-62s%s\n" "Previous" "Current" 55 | printf "%-62s%s\n" "-----------" "----------" 56 | echo "${CHANGES}" 57 | printf "%-62s%s\n" "===========" "==========" 58 | fi 59 | cp "${CURRENT}" "${PREVIOUS}" 60 | done 61 | -------------------------------------------------------------------------------- /regdump.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Dumps the register values of an iio device to stdout. 4 | # 5 | # A specific device name can be passed as the first argument and the number of 6 | # registers as the second argument. It defaults trying to dump 256 registers 7 | # from the axi-ad6676-hpc device. 8 | # 9 | # reg-dump.sh [device name] [number of registers to dump] 10 | 11 | DEV_NAME=${1:-axi-ad6676-hpc} 12 | NUM_REG=${2:-256} 13 | DEV_NODE= 14 | 15 | echoerr() { echo "$@" 1>&2; } 16 | 17 | if [[ ${UID} -ne 0 ]]; then 18 | echoerr "This script must be run as root!" 19 | exit 1 20 | fi 21 | 22 | for dev in /sys/bus/iio/devices/*; do 23 | [[ $(<"${dev}/name") == "${DEV_NAME}" ]] && DEV_NODE=$(basename ${dev}) 24 | done 25 | 26 | if [[ -z ${DEV_NODE} ]]; then 27 | echoerr "Device node not found for iio device \"${DEV_NAME}\"!" 28 | echoerr 29 | echoerr "Available iio devices:" 30 | echoerr "$(cat /sys/bus/iio/devices/*/name)" 31 | exit 1 32 | fi 33 | 34 | if [[ ! -f /sys/kernel/debug/iio/${DEV_NODE}/direct_reg_access ]]; then 35 | echoerr "${DEV_NAME} lacks direct register access debugfs support!" 36 | exit 1 37 | fi 38 | 39 | for reg in $(seq 0 $((NUM_REG-1))); do 40 | echo ${reg} > /sys/kernel/debug/iio/${DEV_NODE}/direct_reg_access 41 | hex_addr=$(printf "%x" ${reg}) 42 | val=$(&2 8 | exit 1 9 | fi 10 | 11 | if [ "$(grep mmcblk0p1 /proc/mounts | wc -l)" -eq "0" ] ; then 12 | mount /dev/mmcblk0p1 /media/boot 13 | fi 14 | 15 | DIR=$(grep mmcblk0p1 /proc/mounts | awk '{print $2}') 16 | 17 | if [ $(cat /proc/cpuinfo | grep -i zynq | wc -l) -gt 0 ] ; then 18 | ZYNQ=1 19 | fi 20 | 21 | if [ -z ${1} ] ; then 22 | if [ "${ZYNQ}" = "1" ] ; then 23 | ls -d ${DIR}/zynq* 24 | else 25 | ls -d ${DIR}/ 26 | fi 27 | fi 28 | 29 | find_match () { 30 | needle=$(basename $1) 31 | match=$(md5sum -b $1|awk '{print $1}') 32 | haystack_dir=$(dirname $1) 33 | for i in $(find ${haystack_dir} -mindepth 2 -name ${needle}) ; do 34 | temp=$(md5sum -b $i|awk '{print $1}') 35 | if [ "${temp}" = "${match}" ] ; then 36 | echo not backing up ${needle}, match ${i} 37 | return 38 | fi 39 | done 40 | echo making backup of $1 in ${DIR}/backup_swap_from 41 | mkdir -p ${DIR}/backup_swap_from 42 | cp ${1} ${DIR}/backup_swap_from/ 43 | } 44 | 45 | missing_file() { 46 | echo missing file $1 47 | echo SD card may not be bootable 48 | exit 49 | } 50 | 51 | if [ ! -z ${1} ] ; then 52 | if [ -d ${DIR}/${1} ] ; then 53 | # if they are not on the drive, back them up 54 | echo "### backing up existing files ###" 55 | find_match ${DIR}/BOOT.BIN 56 | find_match ${DIR}/devicetree.dtb 57 | find_match ${DIR}/uImage 58 | 59 | echo 60 | echo "### copying files to BOOT partion ###" 61 | 62 | if [ -f ${DIR}/${1}/BOOT.BIN ] ; then 63 | echo copying ${DIR}/${1}/BOOT.BIN 64 | cp ${DIR}/${1}/BOOT.BIN ${DIR}/ 65 | else 66 | missing_file BOOT.BIN 67 | fi 68 | if [ -f ${DIR}/${1}/devicetree.dtb ] ; then 69 | echo copying ${DIR}/${1}/devicetree.dtb 70 | cp ${DIR}/${1}/devicetree.dtb ${DIR}/ 71 | else 72 | missing_file devicetree.dtb 73 | fi 74 | if [ -f ${DIR}/${1}/uImage ] ; then 75 | echo copying ${DIR}/${1}/uImage 76 | cp ${DIR}/${1}/uImage ${DIR}/ 77 | else 78 | if [ "${ZYNQ}" = "1" ] ; then 79 | echo copying ${DIR}/zynq-common/uImage 80 | cp ${DIR}/zynq-common/uImage ${DIR}/ 81 | fi 82 | fi 83 | else 84 | echo could not find ${DIR}/${1} 85 | fi 86 | fi 87 | umount $DIR 88 | 89 | -------------------------------------------------------------------------------- /test_ADRV9371-N.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #rsync the files in the background 4 | rsync -azr -e "ssh -i /root/.ssh/id_rsa" /root/osc-logs test_results@romlx1:~/AD9371-N & 5 | 6 | OSC_FORCE_PLUGIN=scpi /usr/local/bin/osc -p /usr/local/lib/osc/profiles/ADRV9371_test.ini 2&>1 > osc_run.txt 7 | rc=$? 8 | 9 | # save marker logs & pngs 10 | serial=$(find /sys -name eeprom -size 256c | while read eeprom 11 | do 12 | ser=$(fru-dump "${eeprom}" -b 2>&1 | awk '/^Serial Number/ {print $NF}') 13 | if [ ! -z {$ser} ] ; then 14 | echo ${ser} 15 | break; 16 | fi 17 | done;) 18 | 19 | if [[ ${rc} -eq 0 ]] ; then 20 | serial=${serial}-PASS 21 | else 22 | serial=${serial}-FAIL 23 | fi 24 | 25 | # Make sure the directory exists 26 | [[ -d /root/osc-logs ]] || mkdir -p /root/osc-logs 27 | 28 | #Is this the first time we tested this board? 29 | if [[ -f /root/osc-logs/AD9371-N-"${serial}"-00.tar.gz ]] ; then 30 | num=$(ls -l /root/osc-logs/AD9371-N-${serial}* | sort -g | sed -n 1p | awk -F "-" '{print $NF}' | awk -F "." '{print $1}') 31 | new=`printf "%02d" $(expr $num + 1)` 32 | else 33 | new='00' 34 | fi 35 | serial=${serial}-${new} 36 | 37 | #stick everything into a tar file 38 | tar -czf /root/osc-logs/AD9371-N-"${serial}".tar.gz osc_run.txt markers.log ADRV*.png 39 | rm -f markers.log ADRV*.png osc_run.txt 40 | 41 | 42 | /sbin/shutdown -h now 43 | -------------------------------------------------------------------------------- /test_ADRV9371-W.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #rsync the files in the background 4 | rsync -azr -e "ssh -i /root/.ssh/id_rsa" /root/osc-logs test_results@romlx1:~/AD9371-W & 5 | 6 | OSC_FORCE_PLUGIN=scpi /usr/local/bin/osc -p /usr/local/lib/osc/profiles/ADRV9371_test.ini 2&>1 > osc_run.txt 7 | rc=$? 8 | 9 | # save marker logs & pngs 10 | serial=$(find /sys -name eeprom -size 256c | while read eeprom 11 | do 12 | ser=$(fru-dump "${eeprom}" -b 2>&1 | awk '/^Serial Number/ {print $NF}') 13 | if [ ! -z {$ser} ] ; then 14 | echo ${ser} 15 | break; 16 | fi 17 | done;) 18 | 19 | if [[ ${rc} -eq 0 ]] ; then 20 | serial=${serial}-PASS 21 | else 22 | serial=${serial}-FAIL 23 | fi 24 | 25 | # Make sure the directory exists 26 | [[ -d /root/osc-logs ]] || mkdir -p /root/osc-logs 27 | 28 | #Is this the first time we tested this board? 29 | if [[ -f /root/osc-logs/AD9371-W-"${serial}"-00.tar.gz ]] ; then 30 | num=$(ls -l /root/osc-logs/AD9371-W-${serial}* | sort -g | sed -n 1p | awk -F "-" '{print $NF}' | awk -F "." '{print $1}') 31 | new=`printf "%02d" $(expr $num + 1)` 32 | else 33 | new='00' 34 | fi 35 | serial=${serial}-${new} 36 | 37 | #stick everything into a tar file 38 | tar -czf /root/osc-logs/AD9371-W-"${serial}".tar.gz osc_run.txt markers.log ADRV*.png 39 | rm -f markers.log ADRV*.png osc_run.txt 40 | 41 | 42 | /sbin/shutdown -h now 43 | -------------------------------------------------------------------------------- /test_adrv9002_fh.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # This is a test script for testing fast frequency hopping in ADRV9002 designs. 5 | # It depends on libiio (and tools) and realpath (which is installed by default in almost every distribution). 6 | # The script provides some configurability but also enforces some defaults: 7 | # * HOP signal 1 will control RX1/TX1. 8 | # * HOP signal 2 will control RX2/TX2. 9 | # * If HOP1 is given we default to Frequency Hopping mode: LO_RETUNE_REALTIME_PROCESS 10 | # * If HOP2 is given we default to Frequency Hopping mode: LO_RETUNE_REALTIME_PROCESS_DUAL_HOP 11 | # * As a consequence of the above item, the max table size is 32. 12 | # * DGPIO_2 will be used to control the hop signal. 13 | # * DGPIO_3 is the base for the gpio's used when the index table control is set to gpio. 14 | # * The script only tests one port on each call and the port to test is deduced from the hop signal and --rx 15 | # flag parameter (eg: hop signal 1 without --rx will run the test on TX1). 16 | set -euo pipefail 17 | 18 | profile="" 19 | stream="" 20 | tbl_a="" 21 | tbl_b="" 22 | tbl_sz_a=0 23 | tbl_sz_b=0 24 | tbl_ctl="gpio" 25 | tbl_ngpio=0 26 | max_tbl_sz=64 27 | # start of gpios for index table control 28 | dgpio_3=0 29 | rx="false" 30 | hop=1 31 | hop_en=0 32 | dev_name="adrv9002-phy" 33 | iio_dev="" 34 | port_en=0 35 | verbose="n" 36 | # number of times we loop through the hopping tables 37 | n_run=5 38 | # false if we can't export the enable pins and the driver is in control of those 39 | export_en_pin=y 40 | 41 | usage() { 42 | printf "Usage: $0 [options] TABLE_A [TABLE_B] 43 | Script to test fast frequency hopping for ADRV9002 devices. At least 44 | one table must be given. The second one is optional. 45 | 46 | Options: 47 | -n, --n-run number of times we loop through the hopping tables [defaults to 5]. 48 | -p, --profile profile to load on the device. it takes two arguments being the 49 | first the stream file and the second the profile. 50 | [only mandatory if a FH enabled profile is not already loaded]. 51 | -c, --table-ctl how to control table indexing [defaults to gpio]: 52 | gpio use gpios to control the indexes. 53 | loop automatically increment through the indexes. 54 | ping-pong automatically switch tables when the last index is reached. 55 | -s, --hop-signal which hop signal to use [must be either 1 or 2]. combined 56 | with the --rx flag controls which port will be tested. 57 | -r, --rx test on a rx port [defaults to 1]. 58 | -d, --debug verbose on. 59 | -h, --help display this help and exit. 60 | \n" 61 | exit 2 62 | } 63 | 64 | error() { 65 | [[ ${#} -gt "0" ]] && echo "[ERROR]: "${*} 66 | exit 1 67 | } 68 | 69 | info() { 70 | [[ ${#} -gt "0" ]] && echo "[INFO]: "${*} 71 | 72 | return 0 73 | } 74 | 75 | debug() { 76 | [[ ${#} -gt "0" && ${verbose} == "y" ]] && echo "[DEBUG]: "${*} 77 | 78 | return 0 79 | } 80 | 81 | file_exists() { 82 | [[ ! -f ${1} ]] && error "\"${1}\" does not exist..." 83 | 84 | return 0 85 | } 86 | 87 | validate_tbl() { 88 | local tbl_sz=0 89 | local tbl_type=${2} 90 | 91 | file_exists "${1}" 92 | 93 | tbl_sz=$(cat "${1}" | egrep -v '<.*>|^#|^$' | wc -l) 94 | [[ ${tbl_sz} -gt ${max_tbl_sz} ]] && error "\"${1}\" has more than ${max_tbl_sz} entries(${tbl_sz})..." 95 | 96 | [[ ${tbl_type} == "a" ]] && tbl_sz_a=${tbl_sz} || tbl_sz_b=${tbl_sz} 97 | 98 | return 0 99 | } 100 | 101 | get_ngpios() { 102 | local max_gpios=6 103 | local i=1; 104 | local n=1; 105 | local tbl_sz=$((tbl_sz_a > tbl_sz_b ? tbl_sz_a : tbl_sz_b)) 106 | 107 | [[ ${tbl_ctl} != "gpio" ]] && { echo 0; return 0; } 108 | 109 | while [[ ${i} -le ${max_gpios} ]]; do 110 | n=$((${n} * 2)) 111 | if [[ ${n} -ge ${tbl_sz} ]]; then 112 | echo ${i} 113 | break 114 | fi 115 | 116 | let i+=1 117 | done 118 | 119 | return 0 120 | } 121 | 122 | do_set_gpio_idx() { 123 | local gpio=0 124 | local g=0 125 | local idx=${1} 126 | 127 | [[ ${tbl_ctl} != "gpio" ]] && return 0 128 | 129 | debug "Set gpios for idx=${idx}" 130 | for ((g=0; g<${tbl_ngpio}; g++)); do 131 | gpio=$((${dgpio_3} + ${g})) 132 | # unset the gpio first so we make sure we get the exact index we want 133 | echo 0 > "/sys/class/gpio/gpio${gpio}/value" 134 | if [[ "$((${idx} & $((1<<${g}))))" != 0 ]]; then 135 | debug "Set gpio${gpio}" 136 | echo 1 > "/sys/class/gpio/gpio${gpio}/value" 137 | fi 138 | done 139 | 140 | return 0 141 | } 142 | 143 | do_gpios_export() { 144 | local model=$(tr -d \\0 "/sys/class/gpio/export" 2>/dev/null && { 198 | echo low > "/sys/class/gpio/gpio${port_en}/direction" 199 | } || { 200 | # We could redirect stderr to a file and look for "Device or resource busy". But, 201 | # meh, not going with that. Just assume that in case of error we can control the pin 202 | # over the device ensm interface. If we can't, the script will fail later on anyways. 203 | export_en_pin="n" 204 | } 205 | } 206 | 207 | # export hop pin 208 | [[ ! -e /sys/class/gpio/gpio${hop_en} ]] && { \ 209 | debug "Export GPIO; ${hop_en}" 210 | echo ${hop_en} > "/sys/class/gpio/export" 211 | echo low > "/sys/class/gpio/gpio${hop_en}/direction" 212 | } 213 | 214 | # export gpios for table control 215 | for ((g=0; g<${tbl_ngpio}; g++)); do 216 | gpio=$((${dgpio_3} + ${g})) 217 | 218 | [[ ! -e /sys/class/gpio/gpio${gpio} ]] && { 219 | debug "Export GPIO; ${gpio}" 220 | echo ${gpio} > "/sys/class/gpio/export" 221 | echo low > "/sys/class/gpio/gpio${gpio}/direction" 222 | } 223 | done 224 | 225 | return 0 226 | } 227 | 228 | do_gpios_unexport() { 229 | local g=0 230 | local gpio=0 231 | 232 | debug "Unexporting GPIOS: ${hop_en}" 233 | [[ ${export_en_pin} == "y" ]] && { 234 | debug "Unexporting GPIOS: ${port_en}" 235 | echo ${port_en} > "/sys/class/gpio/unexport" 236 | } 237 | echo ${hop_en} > "/sys/class/gpio/unexport" 238 | 239 | for ((g=0; g<${tbl_ngpio}; g++)); do 240 | gpio=$((${dgpio_3} + ${g})) 241 | 242 | debug "Unexporting GPIOS: ${gpio}" 243 | echo ${gpio} > "/sys/class/gpio/unexport" 244 | done 245 | 246 | return 0 247 | } 248 | 249 | do_config() { 250 | local p 251 | # first we will do all static/forced configurations 252 | # unset all pins so there's no possibility of overlapping 253 | iio_attr -D ${dev_name} fh_hop1_table_select_pin_set 0 1>/dev/null 254 | iio_attr -D ${dev_name} fh_hop2_table_select_pin_set 0 1>/dev/null 255 | iio_attr -D ${dev_name} fh_hop1_pin_set 0 1>/dev/null 256 | iio_attr -D ${dev_name} fh_hop2_pin_set 0 1>/dev/null 257 | iio_attr -D ${dev_name} fh_table_index_control_npins 0 1>/dev/null 258 | # force hop mappings. HOP1 = [RX1 TX1], HOP2 = [RX2 TX2] 259 | iio_attr -D ${dev_name} fh_rx0_port_hop_signal 0 1>/dev/null 260 | iio_attr -D ${dev_name} fh_tx0_port_hop_signal 0 1>/dev/null 261 | iio_attr -D ${dev_name} fh_rx1_port_hop_signal 1 1>/dev/null 262 | iio_attr -D ${dev_name} fh_tx1_port_hop_signal 1 1>/dev/null 263 | # force it to dual hop if using hop signal 2. This also means that the 264 | # table size cannot be bigger than 32 entries 265 | [[ ${hop} == 2 ]] && iio_attr -D ${dev_name} fh_mode 3 1>/dev/null || \ 266 | iio_attr -D ${dev_name} fh_mode 2 1>/dev/null 267 | # force maximum lo range 268 | iio_attr -D ${dev_name} fh_min_lo_freq_hz 30000000 1>/dev/null 269 | iio_attr -D ${dev_name} fh_max_lo_freq_hz 6000000000 1>/dev/null 270 | # let's do now the actual config set by the user 271 | # dgpio_2 for hop signal 272 | iio_attr -D ${dev_name} fh_hop${hop}_pin_set 3 1>/dev/null 273 | if [[ ${tbl_ctl} == "gpio" ]]; then 274 | iio_attr -D ${dev_name} fh_table_index_control_mode 2 1>/dev/null 275 | elif [[ ${tbl_ctl} == "ping-pong" ]]; then 276 | iio_attr -D ${dev_name} fh_table_index_control_mode 1 1>/dev/null 277 | else 278 | iio_attr -D ${dev_name} fh_table_index_control_mode 0 1>/dev/null 279 | fi 280 | 281 | tbl_ngpio=$(get_ngpios) 282 | debug "Got ngpios=${tbl_ngpio}" 283 | iio_attr -D ${dev_name} fh_table_index_control_npins ${tbl_ngpio} 1>/dev/null 284 | for p in $(seq 1 ${tbl_ngpio}); do 285 | # we start at dgpio3 so pin4 286 | iio_attr -D ${dev_name} fh_table_index_control_pin${p} $((${p} + 3)) 1>/dev/null 287 | done 288 | 289 | return 0 290 | } 291 | 292 | do_dev_init() { 293 | local fh=$(iio_attr -d ${dev_name} profile_config | grep "FH enable" | cut -d ":" -f2 | tr -d " ") 294 | 295 | iio_dev=$(iio_attr -c | grep ${dev_name} | cut -d"," -f1 | tr -d "\t") 296 | if [[ -n ${profile} ]]; then 297 | # if a profile is given, well, we assume FH is enabled! 298 | info "Loading new profile..." 299 | cat "${stream}" > "/sys/bus/iio/devices/${iio_dev}/stream_config" 300 | cat "${profile}" > "/sys/bus/iio/devices/${iio_dev}/profile_config" 301 | else 302 | [[ ${fh} == 0 ]] && error "Frequency hopping not enabled and profile not given..." 303 | info "Initializing the device..." 304 | iio_attr -D ${dev_name} initialize 1 >/dev/null 2>&1 305 | fi 306 | 307 | return 0 308 | } 309 | 310 | do_tbl_hop() { 311 | local i 312 | 313 | for ((i=0; i<${1}; i++)); do 314 | do_set_gpio_idx ${i} 315 | # the table index get's fetched by the device when we assert the port pin 316 | [[ ${export_en_pin} == "y" ]] && { 317 | echo 1 > "/sys/class/gpio/gpio${port_en}/value" 318 | } || { 319 | if [[ ${rx} == "true" ]]; then 320 | iio_attr -c ${dev_name} -i voltage$((${hop} - 1)) ensm_mode rf_enabled >/dev/null 321 | else 322 | iio_attr -c ${dev_name} -o voltage$((${hop} - 1)) ensm_mode rf_enabled >/dev/null 323 | fi 324 | } 325 | # trigger the hop signal. the frame should start on the next hop edge 326 | echo 1 > "/sys/class/gpio/gpio${hop_en}/value" 327 | sleep 0.1 328 | [[ ${export_en_pin} == "y" ]] && { 329 | echo 0 > "/sys/class/gpio/gpio${port_en}/value" 330 | } || { 331 | if [[ ${rx} == "true" ]]; then 332 | iio_attr -c ${dev_name} -i voltage$((${hop} - 1)) ensm_mode primed >/dev/null 333 | else 334 | iio_attr -c ${dev_name} -o voltage$((${hop} - 1)) ensm_mode primed >/dev/null 335 | fi 336 | } 337 | echo 0 > "/sys/class/gpio/gpio${hop_en}/value" 338 | done 339 | } 340 | 341 | do_hopping() { 342 | local i=0 343 | 344 | # let's load the table 345 | cat "${tbl_a}" >> "/sys/bus/iio/devices/${iio_dev}/frequency_hopping_hop${hop}_table_a" 346 | [[ -n ${tbl_b} ]] && cat "${tbl_b}" >> "/sys/bus/iio/devices/${iio_dev}/frequency_hopping_hop${hop}_table_b" 347 | [[ ${rx} == "true" ]] && iio_attr -c ${dev_name} -i voltage$((${hop} - 1)) port_en_mode pin 1>/dev/null || \ 348 | iio_attr -c ${dev_name} -o voltage$((${hop} - 1)) port_en_mode pin 1>/dev/null 349 | 350 | info "Start hopping, tbl_ctl: ${tbl_ctl}, tbl_sz_a: ${tbl_sz_a}, tbl_sz_b: ${tbl_sz_b}, hop: ${hop}, \ 351 | rx: ${rx}, repetitions: ${n_run}" 352 | while [[ ${i} -lt ${n_run} ]]; do 353 | do_tbl_hop ${tbl_sz_a} 354 | if [[ -n ${tbl_b} ]]; then 355 | # if ping-pong, the device should automatically switch tables... 356 | [[ ${tbl_ctl} != "ping-pong" ]] && \ 357 | iio_attr -d ${dev_name} frequency_hopping_hop${hop}_table_select "TABLE_B" 1>/dev/null 358 | do_tbl_hop ${tbl_sz_b} 359 | # switch back to table a 360 | [[ ${tbl_ctl} != "ping-pong" ]] && \ 361 | iio_attr -d ${dev_name} frequency_hopping_hop${hop}_table_select "TABLE_A" 1>/dev/null 362 | fi 363 | 364 | let i+=1 365 | done 366 | 367 | return 0 368 | } 369 | 370 | # make sure iio tools are available 371 | command -v iio_info >/dev/null 2>&1 || error "libiio and it's tools must be installed..." 372 | command -v realpath >/dev/null 2>&1 || error "realpath not found..." 373 | 374 | while [[ ${#} -gt 0 ]]; do 375 | case "${1}" in 376 | -n|--n-run) 377 | n_run="${2}" 378 | shift 2 379 | ;; 380 | -p|--profile) 381 | # we must always give a valid stream for the profile 382 | file_exists "${2}" 383 | file_exists "${3}" 384 | stream="$(realpath "${2}")" 385 | profile="$(realpath "${3}")" 386 | shift 3 387 | ;; 388 | -c|--table-ctl) 389 | [[ ${2} != "gpio" && ${2} != "loop" && ${2} != "ping-pong" ]] && \ 390 | error "Invalid table control mode: \"${2}\"" 391 | tbl_ctl=${2} 392 | shift 2 393 | ;; 394 | -s|--hop-signal) 395 | [[ ${2} != 1 && ${2} != 2 ]] && error "Invalid hop signal: \"${2}\"" 396 | hop=${2} 397 | [[ ${hop} == 2 ]] && max_tbl_sz=32 398 | shift 2 399 | ;; 400 | -r|--rx) 401 | rx="true" 402 | shift 403 | ;; 404 | -d|--debug) 405 | verbose="y" 406 | shift 407 | ;; 408 | -h|--help) 409 | usage 410 | ;; 411 | *) 412 | [[ -n ${tbl_a} && -n ${tbl_b} ]] && error "Both tables given already... Unknown option: \"${1}\"" 413 | [[ -z ${tbl_a} ]] && tbl_a="$(realpath "${1}")" || tbl_b="$(realpath "${1}")" 414 | shift 415 | ;; 416 | esac 417 | done 418 | 419 | # we just validate the tables now as it's size depends on the hop signal selected 420 | validate_tbl ${tbl_a} "a" 421 | [[ -n ${tbl_b} ]] && validate_tbl ${tbl_b} "b" 422 | 423 | do_config 424 | do_dev_init 425 | do_gpios_export 426 | do_hopping 427 | do_gpios_unexport 428 | -------------------------------------------------------------------------------- /test_ensm_pinctrl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | find_zynq_base_gpio () { 4 | for i in /sys/class/gpio/gpiochip*; do 5 | if [ "zynq_gpio" = `cat $i/label` ]; then 6 | return `echo $i | sed 's/^[^0-9]\+//'` 7 | break 8 | fi 9 | done 10 | return -1 11 | } 12 | 13 | fdd_pin_control_test () { 14 | echo Running FDD Pin Control Test 15 | while true; do 16 | echo high > $ENABLE # RX&TX ON 17 | 18 | sleep 1 19 | 20 | echo low > $ENABLE # RX&TX OFF 21 | 22 | sleep 1 23 | 24 | done 25 | } 26 | 27 | fdd_independant_mode_pin_control_test () { 28 | echo Running FDD Independant Pin Control Test 29 | while true; do 30 | echo high > $ENABLE # RX ON 31 | echo low > $TXNRX # TX OFF 32 | 33 | sleep 1 34 | 35 | echo high > $TXNRX #TX ON 36 | 37 | sleep 1 38 | 39 | done 40 | } 41 | 42 | tdd_pin_control_test () { 43 | 44 | echo Running TDD Pin Control Test 45 | while true; do 46 | 47 | # RX 48 | echo low > $ENABLE 49 | echo low > $TXNRX 50 | echo low > $TXNRX # add some extra delay required for VCO cal in single synthesizer mode. 51 | echo high > $ENABLE 52 | 53 | sleep 1 54 | 55 | # TX 56 | echo low > $ENABLE 57 | echo high > $TXNRX 58 | echo high > $TXNRX # add some extra delay required for VCO cal in single synthesizer mode. 59 | echo high > $ENABLE 60 | 61 | sleep 1 62 | done 63 | } 64 | 65 | if [ `id -u` != "0" ] 66 | then 67 | echo "This script must be run as root" 1>&2 68 | exit 1 69 | fi 70 | 71 | for i in $(find -L /sys/bus/iio/devices -maxdepth 2 -name name) 72 | do 73 | dev_name=$(cat $i) 74 | if [ "$dev_name" = "ad9361-phy" ]; then 75 | phy_path=$(echo $i | sed 's:/name$::') 76 | ensm_modes=$(cat $phy_path/ensm_mode_available) 77 | break 78 | fi 79 | done 80 | 81 | if [ "$dev_name" != "ad9361-phy" ]; then 82 | echo "This test if for FMCOMMS2/3/4 only" 83 | exit 84 | fi 85 | 86 | find_zynq_base_gpio 87 | GPIO_BASE=$? 88 | 89 | cd /sys/class/gpio 90 | 91 | if [ $GPIO_BASE -ge 0 ] 92 | then 93 | GPIO_ENABLE=`expr $GPIO_BASE + 101` 94 | GPIO_TXNRX=`expr $GPIO_BASE + 102` 95 | #Export the CTRL_IN GPIOs 96 | echo $GPIO_ENABLE > export 2> /dev/null 97 | echo $GPIO_TXNRX > export 2> /dev/null 98 | else 99 | echo ERROR: Wrong board? 100 | exit 101 | fi 102 | 103 | ENABLE=gpio${GPIO_ENABLE}/direction 104 | TXNRX=gpio${GPIO_TXNRX}/direction 105 | 106 | echo low > $ENABLE 107 | echo low > $TXNRX 108 | 109 | echo Press CTRL-C to exit 110 | 111 | case "$ensm_modes" in 112 | *fdd*) 113 | echo "Type: 0 for FDD Pin Control Mode" 114 | echo "Type: 1 for FDD Independant Pin Control Mode" 115 | 116 | read mode 117 | 118 | if [ $mode = "1" ]; then 119 | echo pinctrl_fdd_indep > $phy_path/ensm_mode #Enable Pincontrol Mode 120 | fdd_independant_mode_pin_control_test 121 | else 122 | echo pinctrl > $phy_path/ensm_mode #Enable Pincontrol Mode 123 | fdd_pin_control_test 124 | fi 125 | 126 | ;; 127 | *rx*) 128 | echo pinctrl > $phy_path/ensm_mode #Enable Pincontrol Mode 129 | tdd_pin_control_test 130 | ;; 131 | esac 132 | -------------------------------------------------------------------------------- /test_fmcadc2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | tmpdir=$(mktemp -d --tmpdir=/tmp fmcadc2-test.XXXXXX) 4 | pushd ${tmpdir} >/dev/null 5 | OSC_FORCE_PLUGIN=scpi /usr/local/bin/osc -p /usr/local/lib/osc/profiles/AD-FMCADC2_test.ini 6 | rc=$? 7 | popd >/dev/null 8 | 9 | # save test output 10 | serial="$(find /sys -name eeprom -size 256c | xargs fru-dump -b -i | awk '/^Serial Number/ {print $NF}')" 11 | if [[ -n ${serial} ]]; then 12 | # failing cards have log dirs named ${serial}-failed 13 | [[ ${rc} -eq 0 ]] || serial+="-failed" 14 | mkdir -p "/root/osc-logs/${serial}" 15 | if [[ ! -d "/root/osc-logs/${serial}" ]]; then 16 | mv ${tmpdir} "/root/osc-logs/${serial}" 17 | else 18 | # serial number collision 19 | rand=$(basename ${tmpdir}) 20 | rand=${rand##*.} 21 | mv ${tmpdir} "/root/osc-logs/${serial}.${rand}" 22 | fi 23 | fi 24 | 25 | /sbin/shutdown -h now 26 | -------------------------------------------------------------------------------- /test_fmcdaq2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # initialize scale to workaround dBFS GUI reload issue 4 | /usr/local/bin/dds_set_scale.sh 0 >/dev/null 5 | 6 | tmpdir=$(mktemp -d --tmpdir=/tmp fmcdaq2-test.XXXXXX) 7 | pushd ${tmpdir} >/dev/null 8 | /usr/local/bin/osc -p /usr/local/lib/osc/profiles/AD-FMCDAQ2_test.ini 9 | rc=$? 10 | popd >/dev/null 11 | 12 | # save test output 13 | serial="$(find /sys -name eeprom -size 256c | xargs fru-dump -b -i | awk '/^Serial Number/ {print $NF}')" 14 | if [[ -n ${serial} ]]; then 15 | # failing cards have log dirs named ${serial}-failed 16 | [[ ${rc} -eq 0 ]] || serial+="-failed" 17 | mkdir -p "/root/osc-logs/${serial}" 18 | if [[ ! -d "/root/osc-logs/${serial}" ]]; then 19 | mv ${tmpdir} "/root/osc-logs/${serial}" 20 | else 21 | # serial number collision 22 | rand=$(basename ${tmpdir}) 23 | rand=${rand##*.} 24 | mv ${tmpdir} "/root/osc-logs/${serial}.${rand}" 25 | fi 26 | fi 27 | 28 | /sbin/shutdown -h now 29 | -------------------------------------------------------------------------------- /test_fmcdaq3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # initialize scale to workaround dBFS GUI reload issue 4 | /usr/local/bin/dds_set_scale.sh 0 >/dev/null 5 | 6 | tmpdir=$(mktemp -d --tmpdir=/tmp fmcdaq3-test.XXXXXX) 7 | pushd ${tmpdir} >/dev/null 8 | /usr/local/bin/osc -p /usr/local/lib/osc/profiles/AD-FMCDAQ3_test.ini 9 | rc=$? 10 | popd >/dev/null 11 | 12 | # save test output 13 | serial="$(find /sys -name eeprom -size 256c | xargs fru-dump -b -i | awk '/^Serial Number/ {print $NF}')" 14 | if [[ -n ${serial} ]]; then 15 | # failing cards have log dirs named ${serial}-failed 16 | [[ ${rc} -eq 0 ]] || serial+="-failed" 17 | mkdir -p "/root/osc-logs/${serial}" 18 | if [[ ! -d "/root/osc-logs/${serial}" ]]; then 19 | mv ${tmpdir} "/root/osc-logs/${serial}" 20 | else 21 | # serial number collision 22 | rand=$(basename ${tmpdir}) 23 | rand=${rand##*.} 24 | mv ${tmpdir} "/root/osc-logs/${serial}.${rand}" 25 | fi 26 | fi 27 | 28 | /sbin/shutdown -h now -------------------------------------------------------------------------------- /test_fmcomms2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | OSC_FORCE_PLUGIN=scpi /usr/local/bin/osc -p /usr/local/lib/osc/profiles/FMComms2_test.ini 4 | rc=$? 5 | 6 | if [[ "$rc" = "0" ]] ; then 7 | /sbin/shutdown -h now 8 | fi 9 | -------------------------------------------------------------------------------- /test_fmcomms4.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | OSC_FORCE_PLUGIN=scpi /usr/local/bin/osc -p /usr/local/lib/osc/profiles/FMComms4_test.ini 4 | rc=$? 5 | 6 | if [[ "$rc" = "0" ]] ; then 7 | /sbin/shutdown -h now 8 | fi 9 | -------------------------------------------------------------------------------- /test_fmcomms5.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | OSC_FORCE_PLUGIN=scpi /usr/local/bin/osc -p /usr/local/lib/osc/profiles/FMComms5_test.ini 4 | rc=$? 5 | 6 | # save marker logs 7 | if [[ ${rc} -eq 0 ]] ; then 8 | eeprom=$(find /sys -name eeprom -size 256c) 9 | serial=$(fru-dump "${eeprom}" -b | awk '/^Serial Number/ {print $NF}') 10 | [[ -d /root/osc-logs ]] || mkdir -p /root/osc-logs 11 | mv log.txt /root/osc-logs/"${serial}"-log.txt 12 | fi 13 | 14 | /sbin/shutdown -h now 15 | -------------------------------------------------------------------------------- /test_freqcvt1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | /usr/local/bin/osc -p /usr/local/lib/osc/profiles/AD-FREQCVT1_test.ini 4 | ret=$? 5 | 6 | if [[ ${ret} -eq 0 ]] ; then 7 | /sbin/shutdown -h now 8 | fi 9 | -------------------------------------------------------------------------------- /test_mgc_pinctrl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | find_zynq_base_gpio () { 4 | for i in /sys/class/gpio/gpiochip*; do 5 | if [ "zynq_gpio" = `cat $i/label` ]; then 6 | return `echo $i | sed 's/^[^0-9]\+//'` 7 | break 8 | fi 9 | done 10 | return -1 11 | } 12 | 13 | if [ `id -u` != "0" ] 14 | then 15 | echo "This script must be run as root" 1>&2 16 | exit 1 17 | fi 18 | 19 | if [ `iio_attr -q -D ad9361-phy adi,mgc-rx1-ctrl-inp-enable` = "0" ];then 20 | #Enable Pin Control Mode 21 | iio_attr -D ad9361-phy adi,mgc-rx1-ctrl-inp-enable 1 > export 2> /dev/null 22 | iio_attr -D ad9361-phy adi,mgc-rx2-ctrl-inp-enable 1 > export 2> /dev/null 23 | iio_attr -D ad9361-phy initialize 1 > export 2> /dev/null 24 | 25 | sleep 1 26 | fi 27 | 28 | iio_attr -c ad9361-phy voltage0 gain_control_mode manual > export 2> /dev/null 29 | iio_attr -c ad9361-phy voltage1 gain_control_mode manual > export 2> /dev/null 30 | 31 | find_zynq_base_gpio 32 | GPIO_BASE=$? 33 | cd /sys/class/gpio 34 | 35 | if [ $GPIO_BASE -ge 0 ] 36 | then 37 | GPIO_CTRL_IN0=`expr $GPIO_BASE + 94` 38 | GPIO_CTRL_IN1=`expr $GPIO_BASE + 95` 39 | GPIO_CTRL_IN2=`expr $GPIO_BASE + 96` 40 | GPIO_CTRL_IN3=`expr $GPIO_BASE + 97` 41 | #Export the CTRL_IN GPIOs 42 | echo $GPIO_CTRL_IN0 > export 2> /dev/null 43 | echo $GPIO_CTRL_IN1 > export 2> /dev/null 44 | echo $GPIO_CTRL_IN2 > export 2> /dev/null 45 | echo $GPIO_CTRL_IN3 > export 2> /dev/null 46 | else 47 | echo ERROR: Wrong board? 48 | exit 49 | fi 50 | 51 | CTRL_IN0=gpio${GPIO_CTRL_IN0}/direction 52 | CTRL_IN1=gpio${GPIO_CTRL_IN1}/direction 53 | CTRL_IN2=gpio${GPIO_CTRL_IN2}/direction 54 | CTRL_IN3=gpio${GPIO_CTRL_IN3}/direction 55 | 56 | if [ "$1" = "1" ];then 57 | iio_attr -i -c ad9361-phy voltage0 hardwaregain 58 | 59 | if [ "$2" = "up" ];then 60 | echo low > $CTRL_IN0 61 | echo high > $CTRL_IN0 62 | elif [ "$2" = "down" ];then 63 | echo low > $CTRL_IN1 64 | echo high > $CTRL_IN1 65 | else 66 | echo "usage: $0 <1|2> " 67 | exit 68 | fi 69 | iio_attr -i -c ad9361-phy voltage0 hardwaregain 70 | 71 | elif [ "$1" = "2" ];then 72 | iio_attr -i -c ad9361-phy voltage1 hardwaregain 73 | if [ "$2" = "up" ];then 74 | echo low > $CTRL_IN2 75 | echo high > $CTRL_IN2 76 | elif [ "$2" = "down" ];then 77 | echo low > $CTRL_IN3 78 | echo high > $CTRL_IN3 79 | else 80 | echo "usage: $0 <1|2> " 81 | exit 82 | fi 83 | iio_attr -i -c ad9361-phy voltage1 hardwaregain 84 | else 85 | echo "usage: $0 <1|2> " 86 | exit 87 | fi 88 | -------------------------------------------------------------------------------- /test_pzsdr2_2400tdd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | /usr/local/bin/osc -p /usr/local/lib/osc/profiles/PZSDR2_2400TDD_test.ini 4 | ret=$? 5 | 6 | if [[ ${ret} -eq 0 ]] ; then 7 | /sbin/shutdown -h now 8 | fi 9 | -------------------------------------------------------------------------------- /test_rx_fastlock_pinctrl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | find_zynq_base_gpio () { 4 | for i in /sys/class/gpio/gpiochip*; do 5 | if [ "zynq_gpio" = `cat $i/label` ]; then 6 | return `echo $i | sed 's/^[^0-9]\+//'` 7 | break 8 | fi 9 | done 10 | return -1 11 | } 12 | 13 | if [ `id -u` != "0" ] 14 | then 15 | echo "This script must be run as root" 1>&2 16 | exit 1 17 | fi 18 | 19 | for i in $(find -L /sys/bus/iio/devices -maxdepth 2 -name name) 20 | do 21 | dev_name=$(cat $i) 22 | if [ "$dev_name" = "ad9361-phy" ]; then 23 | phy_path=$(echo $i | sed 's:/name$::') 24 | cd $phy_path 25 | break 26 | fi 27 | done 28 | 29 | if [ "$dev_name" != "ad9361-phy" ]; then 30 | exit 31 | fi 32 | 33 | #Setup 8 Profiles 10MHz spaced 34 | for i in `seq 0 7` 35 | do 36 | echo $((2400000000 + $i * 100000)) > out_altvoltage0_RX_LO_frequency 37 | echo "Initializing PROFILE $i at $((2400000000 + $i * 100000)) MHz" 38 | echo $i > out_altvoltage0_RX_LO_fastlock_store 39 | done 40 | 41 | #Enable Fastlock Mode 42 | iio_attr -D ad9361-phy adi,rx-fastlock-pincontrol-enable 1 43 | echo 0 > out_altvoltage0_RX_LO_fastlock_recall 44 | 45 | find_zynq_base_gpio 46 | GPIO_BASE=$? 47 | 48 | cd /sys/class/gpio 49 | 50 | if [ $GPIO_BASE -ge 0 ] 51 | then 52 | GPIO_CTRL_IN1=`expr $GPIO_BASE + 95` 53 | GPIO_CTRL_IN2=`expr $GPIO_BASE + 96` 54 | GPIO_CTRL_IN3=`expr $GPIO_BASE + 97` 55 | #Export the CTRL_IN GPIOs 56 | echo $GPIO_CTRL_IN1 > export 2> /dev/null 57 | echo $GPIO_CTRL_IN2 > export 2> /dev/null 58 | echo $GPIO_CTRL_IN3 > export 2> /dev/null 59 | else 60 | echo ERROR: Wrong board? 61 | exit 62 | fi 63 | 64 | CTRL_IN1=gpio${GPIO_CTRL_IN1}/direction 65 | CTRL_IN2=gpio${GPIO_CTRL_IN2}/direction 66 | CTRL_IN3=gpio${GPIO_CTRL_IN3}/direction 67 | 68 | for i in `seq 0 7` 69 | do 70 | echo Setting PROFILE $i 71 | # BIT 0 72 | if [ $(($i & 1)) -gt 0 ] 73 | then 74 | echo CTRL_IN1:1 75 | echo high > $CTRL_IN1 76 | else 77 | echo CTRL_IN1:0 78 | echo low > $CTRL_IN1 79 | fi 80 | 81 | # BIT 1 82 | if [ $(($i & 2)) -gt 0 ] 83 | then 84 | echo CTRL_IN2:1 85 | echo high > $CTRL_IN2 86 | else 87 | echo CTRL_IN2:0 88 | echo low > $CTRL_IN2 89 | fi 90 | 91 | # BIT 2 92 | if [ $(($i & 4)) -gt 0 ] 93 | then 94 | echo CTRL_IN3:1 95 | echo high > $CTRL_IN3 96 | else 97 | echo CTRL_IN3:0 98 | echo low > $CTRL_IN3 99 | fi 100 | 101 | sleep 1 102 | done 103 | -------------------------------------------------------------------------------- /test_trxboost1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | /usr/local/bin/osc -p /usr/local/lib/osc/profiles/AD-TRXBOOST1_test.ini 4 | ret=$? 5 | 6 | if [[ ${ret} -eq 0 ]] ; then 7 | /sbin/shutdown -h now 8 | fi 9 | -------------------------------------------------------------------------------- /test_tx_fastlock_pinctrl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | find_zynq_base_gpio () { 4 | for i in /sys/class/gpio/gpiochip*; do 5 | if [ "zynq_gpio" = `cat $i/label` ]; then 6 | return `echo $i | sed 's/^[^0-9]\+//'` 7 | break 8 | fi 9 | done 10 | return -1 11 | } 12 | 13 | if [ `id -u` != "0" ] 14 | then 15 | echo "This script must be run as root" 1>&2 16 | exit 1 17 | fi 18 | 19 | for i in $(find -L /sys/bus/iio/devices -maxdepth 2 -name name) 20 | do 21 | dev_name=$(cat $i) 22 | if [ "$dev_name" = "ad9361-phy" ]; then 23 | phy_path=$(echo $i | sed 's:/name$::') 24 | cd $phy_path 25 | break 26 | fi 27 | done 28 | 29 | if [ "$dev_name" != "ad9361-phy" ]; then 30 | exit 31 | fi 32 | 33 | #Setup 8 Profiles 10MHz spaced 34 | for i in `seq 0 7` 35 | do 36 | echo $((2400000000 + $i * 10000000)) > out_altvoltage1_TX_LO_frequency 37 | echo "Initializing PROFILE $i at $((2400000000 + $i * 10000000)) MHz" 38 | echo $i > out_altvoltage1_TX_LO_fastlock_store 39 | done 40 | 41 | #Enable Fastlock Mode 42 | iio_attr -D ad9361-phy adi,tx-fastlock-pincontrol-enable 1 43 | echo 0 > out_altvoltage1_TX_LO_fastlock_recall 44 | 45 | find_zynq_base_gpio 46 | GPIO_BASE=$? 47 | 48 | cd /sys/class/gpio 49 | 50 | if [ $GPIO_BASE -ge 0 ] 51 | then 52 | GPIO_CTRL_IN1=`expr $GPIO_BASE + 95` 53 | GPIO_CTRL_IN2=`expr $GPIO_BASE + 96` 54 | GPIO_CTRL_IN3=`expr $GPIO_BASE + 97` 55 | #Export the CTRL_IN GPIOs 56 | echo $GPIO_CTRL_IN1 > export 2> /dev/null 57 | echo $GPIO_CTRL_IN2 > export 2> /dev/null 58 | echo $GPIO_CTRL_IN3 > export 2> /dev/null 59 | else 60 | echo ERROR: Wrong board? 61 | exit 62 | fi 63 | 64 | CTRL_IN1=gpio${GPIO_CTRL_IN1}/direction 65 | CTRL_IN2=gpio${GPIO_CTRL_IN2}/direction 66 | CTRL_IN3=gpio${GPIO_CTRL_IN3}/direction 67 | 68 | for i in `seq 0 7` 69 | do 70 | echo Setting PROFILE $i 71 | # BIT 0 72 | if [ $(($i & 1)) -gt 0 ] 73 | then 74 | echo CTRL_IN1:1 75 | echo high > $CTRL_IN1 76 | else 77 | echo CTRL_IN1:0 78 | echo low > $CTRL_IN1 79 | fi 80 | 81 | # BIT 1 82 | if [ $(($i & 2)) -gt 0 ] 83 | then 84 | echo CTRL_IN2:1 85 | echo high > $CTRL_IN2 86 | else 87 | echo CTRL_IN2:0 88 | echo low > $CTRL_IN2 89 | fi 90 | 91 | # BIT 2 92 | if [ $(($i & 4)) -gt 0 ] 93 | then 94 | echo CTRL_IN3:1 95 | echo high > $CTRL_IN3 96 | else 97 | echo CTRL_IN3:0 98 | echo low > $CTRL_IN3 99 | fi 100 | 101 | sleep 1 102 | done 103 | -------------------------------------------------------------------------------- /ttyGS0.conf: -------------------------------------------------------------------------------- 1 | # ttyGS0 - getty 2 | # 3 | # This service maintains a getty on ttyGS0 from the point the system is 4 | # started until it is shut down again. 5 | start on stopped rc RUNLEVEL=[2345] 6 | stop on runlevel [!2345] 7 | 8 | pre-start script 9 | [ -e /dev/ttyGS0 ] || { stop; exit 0; } 10 | end script 11 | 12 | respawn 13 | exec /sbin/getty -L 115200 ttyGS0 vt102 14 | -------------------------------------------------------------------------------- /usb-gadget-service/defaults/iiod: -------------------------------------------------------------------------------- 1 | IIOD_EXTRA_FFS_OPTS="-n 3 -F /dev/iio_ffs" 2 | -------------------------------------------------------------------------------- /usb-gadget-service/defaults/usb_gadget: -------------------------------------------------------------------------------- 1 | GT_DEFAULT_SCHEME=/usr/local/etc/gt/adi/iio_acm_generic.scheme 2 | -------------------------------------------------------------------------------- /usb-gadget-service/install_gt.sh: -------------------------------------------------------------------------------- 1 | if [ "$(id -u)" != "0" ] ; then 2 | echo "This script must be run as root" 3 | exit 1 4 | fi 5 | 6 | SCRIPT_PATH=$(dirname $(readlink -f $0)) 7 | 8 | apt-get -y install libconfig-dev 9 | 10 | cd /usr/local/src 11 | 12 | if [ ! -d libusbgx ] ; then 13 | git clone https://github.com/linux-usb-gadgets/libusbgx.git 14 | cd libusbgx 15 | else 16 | cd libusbgx 17 | git pull 18 | fi 19 | 20 | autoreconf -i 21 | ./configure 22 | make && make install 23 | cd - 24 | 25 | if [ ! -d gt ] ; then 26 | git clone https://github.com/linux-usb-gadgets/gt.git 27 | cd gt 28 | else 29 | cd gt 30 | git pull 31 | fi 32 | 33 | cd source 34 | cmake -DENABLE_MANUAL_PAGE=off . 35 | make && make install 36 | cd - 37 | 38 | ldconfig 39 | 40 | cd $SCRIPT_PATH 41 | 42 | install -D -m 0644 systemd/gt.service /etc/systemd/system/ 43 | install -D -m 0644 systemd/gt-start.service /etc/systemd/system/ 44 | install -D -m 0644 systemd/gt.target /etc/systemd/system/ 45 | install -D -m 0644 systemd/iiod_ffs.service /etc/systemd/system/ 46 | install -D -m 0644 systemd/dev-iio_ffs.mount /etc/systemd/system/ 47 | install -D -m 0644 systemd/iiod_context_attr.service /etc/systemd/system/ 48 | 49 | install -D -m 0644 -C defaults/usb_gadget /etc/default/ 50 | install -D -m 0644 -C defaults/iiod /etc/default/ 51 | 52 | install -d /usr/local/etc/gt/adi/ 53 | install -D -m 0644 schemes/iio_acm_generic.scheme /usr/local/etc/gt/adi/ 54 | install -D -m 0644 schemes/iio_ncm.scheme /usr/local/etc/gt/adi/ 55 | install -D -m 0644 schemes/iio_acmx2_rndis.scheme /usr/local/etc/gt/adi/ 56 | 57 | install -D -m 0744 scripts/iiod_context.sh /usr/local/bin/ 58 | install -D -m 0744 scripts/usb_gadget.sh /usr/local/bin/ 59 | 60 | install -D -m 0644 udev/99-udc.rules /etc/udev/rules.d/ 61 | 62 | systemctl daemon-reload 63 | systemctl enable iiod_context_attr.service gt.service dev-iio_ffs.mount iiod_ffs.service gt-start.service gt.target 64 | 65 | udevadm control --reload-rules 66 | udevadm trigger 67 | -------------------------------------------------------------------------------- /usb-gadget-service/schemes/iio_acm_generic.scheme: -------------------------------------------------------------------------------- 1 | attrs : 2 | { 3 | idVendor = 0x0456; 4 | idProduct = 0xb671; 5 | }; 6 | strings = ( 7 | { 8 | lang = 0x409; 9 | manufacturer = "Analog Devices Inc."; 10 | product = "IIO-USB-CDC-ACM"; 11 | serialnumber = "12345678"; 12 | } 13 | ); 14 | functions : 15 | { 16 | iio_ffs : 17 | { 18 | instance = "iio_ffs"; 19 | type = "ffs"; 20 | }; 21 | 22 | acm_usb0 : 23 | { 24 | instance = "usb0"; 25 | type = "acm"; 26 | }; 27 | }; 28 | configs = ( 29 | { 30 | id = 1; 31 | name = "c"; 32 | attrs : 33 | { 34 | bmAttributes = 0x80; 35 | bMaxPower = 500; 36 | }; 37 | functions = ( 38 | { 39 | name = "ffs.iio_ffs"; 40 | function = "iio_ffs"; 41 | }, 42 | { 43 | name = "acm.usb0"; 44 | function = "acm_usb0"; 45 | }); 46 | } ); 47 | -------------------------------------------------------------------------------- /usb-gadget-service/schemes/iio_acmx2_rndis.scheme: -------------------------------------------------------------------------------- 1 | attrs : 2 | { 3 | idVendor = 0x0456; 4 | idProduct = 0xb678; 5 | }; 6 | strings = ( 7 | { 8 | lang = 0x409; 9 | manufacturer = "Analog Devices Inc."; 10 | product = "ADI Linux Platform"; 11 | } 12 | ); 13 | functions : 14 | { 15 | iio_ffs : 16 | { 17 | instance = "iio_ffs"; 18 | type = "ffs"; 19 | }; 20 | 21 | acm_usb0 : 22 | { 23 | instance = "usb0"; 24 | type = "acm"; 25 | }; 26 | acm_usb1 : 27 | { 28 | instance = "usb1"; 29 | type = "acm"; 30 | }; 31 | rndis_usb0 : 32 | { 33 | instance = "usb0"; 34 | type = "rndis"; 35 | os_descs = ( 36 | { 37 | interface = "rndis"; 38 | compatible_id = "RNDIS"; 39 | sub_compatible_id = "5162001"; 40 | } ); 41 | }; 42 | }; 43 | configs = ( 44 | { 45 | id = 1; 46 | name = "c"; 47 | functions = ( 48 | { 49 | name = "rndis.usb0"; 50 | function = "rndis_usb0"; 51 | }, 52 | { 53 | name = "acm.usb0"; 54 | function = "acm_usb0"; 55 | }, 56 | { 57 | name = "acm.usb1"; 58 | function = "acm_usb1"; 59 | }, 60 | { 61 | name = "ffs.iio_ffs"; 62 | function = "iio_ffs"; 63 | } ); 64 | } ); 65 | 66 | -------------------------------------------------------------------------------- /usb-gadget-service/schemes/iio_ncm.scheme: -------------------------------------------------------------------------------- 1 | attrs : 2 | { 3 | idVendor = 0x0456; 4 | idProduct = 0xb671; 5 | }; 6 | strings = ( 7 | { 8 | lang = 0x409; 9 | manufacturer = "Analog Devices Inc."; 10 | product = "IIO-USB-NCM"; 11 | } 12 | ); 13 | functions : 14 | { 15 | ncm_usb0 : 16 | { 17 | instance = "usb0"; 18 | type = "ncm"; 19 | }; 20 | 21 | iio_ffs : 22 | { 23 | instance = "iio_ffs"; 24 | type = "ffs"; 25 | }; 26 | 27 | }; 28 | configs = ( 29 | { 30 | id = 1; 31 | name = "c"; 32 | functions = ( 33 | { 34 | name = "ncm.usb0"; 35 | function = "ncm_usb0"; 36 | }, 37 | { 38 | name = "ffs.iio_ffs"; 39 | function = "iio_ffs"; 40 | } ); 41 | } ); -------------------------------------------------------------------------------- /usb-gadget-service/scripts/iiod_context.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | INI_FILE=/etc/libiio.ini 4 | 5 | # Point people to the correct thing. 6 | SELF=$0 7 | [ -r "$SELF" ] || SELF=$( 8 | IFS=:; set -f 9 | for i in ${PATH-$(getconf PATH)}""; do 10 | case $i in 11 | "") p=$SELF;; 12 | */) p=$i$SELF;; 13 | *) p=$i/$SELF 14 | esac 15 | [ -r "$p" ] && exec printf '%s\n' "$p" 16 | done 17 | exit 1 18 | ) && SELF=$(readlink -e -- "$SELF") || SELF=unknown 19 | 20 | #some systems have null in the device tree, so replace those with spaces 21 | #some systems include non-printable chars, or color codes so also remove those. 22 | sanitize_str() { 23 | echo "$@" | tr '\0' ' ' | sed -e 's/ $//g' -e 's/\\x1b\[[0-9;]*m//g' | tr -cd '[:print:]\n' 24 | } 25 | sanitize() { 26 | cat $1 | tr '\0' ' ' | sed -e 's/ $//g' -e 's/\\x1b\[[0-9;]*m//g' | tr -cd '[:print:]\n' 27 | } 28 | 29 | #run on x86 and ARM 30 | MODEL="/proc/device-tree/model" 31 | DMI="/sys/class/dmi/id/board_vendor" 32 | if [ -f "${MODEL}" ] ; then 33 | # Most ARM systems will fill /sys/firmware; 34 | BASE=$(sanitize $MODEL) 35 | elif [ -f "${DMI}" ] ; then 36 | # most x86 will fill out Desktop Management Interface 37 | BASE=$(sanitize "/sys/class/dmi/id/product_name") 38 | VENDOR=$(sanitize "${DMI}") 39 | fi 40 | 41 | SYSID=$(sanitize_str $(dmesg | grep axi_sysid | grep git | head -1 | cut -f2- -d":" | sed -e 's/^[[:space:]]*//' | sed -e 's//]/g')) 42 | 43 | UNIQUE_ID=$(sanitize_str $(dmesg | grep SPI-NOR-UniqueID | head -1)) 44 | UNIQUE_ID=${UNIQUE_ID#*SPI-NOR-UniqueID } 45 | 46 | # If this is an FMC Board, capture the data 47 | command fru-dump -h >/dev/null 2>&1 48 | if [ "$?" = "0" ] ; then 49 | for i in $(find /sys/ -name eeprom) 50 | do 51 | fru-dump $i > /dev/null 2>&1 52 | if [ $? -eq "0" ] ; then 53 | BOARD=$(fru-dump $i -b | grep "Part Number" | awk -F: '{print $2}' | sed 's/^[[:space:]]*//') 54 | SERIAL=$(fru-dump $i -b | grep "Serial Number" | awk -F: '{print $2}' | sed 's/^[[:space:]]*//') 55 | NAME=$(fru-dump $i -b | grep "Product Name" | awk -F: '{print $2}' | sed 's/^[[:space:]]*//') 56 | VENDOR=$(fru-dump $i -b | grep "Manufacturer" | awk -F: '{print $2}' | sed 's/^[[:space:]]*//') 57 | break 58 | fi 59 | done 60 | fi 61 | 62 | # If you are a Raspberry Pi HAT, add that 63 | if [ -d "/sys/firmware/devicetree/base/hat" ] ; then 64 | BOARD=$(sanitize "/sys/firmware/devicetree/base/hat/product_id") 65 | SERIAL=$(sanitize "/sys/firmware/devicetree/base/hat/uuid") 66 | NAME=$(sanitize "/sys/firmware/devicetree/base/hat/product") 67 | VENDOR=$(sanitize "/sys/firmware/devicetree/base/hat/vendor") 68 | fi 69 | 70 | #Find the overlays that are added 71 | if [ "$(echo ${BASE} | grep Raspberry | wc -c)" -gt "1" ] ; then 72 | OVERLAY=$(grep ^dtoverlay /boot/config.txt | \ 73 | sed -e 's/,.*$//' -e 's/^.*=//' | \ 74 | tr '\n' ',' | sed 's/,$/\n/g') 75 | fi 76 | 77 | # remove this from the file, to make sure stale data isn't hanging around 78 | remove() { 79 | # If this is called with something that is blank, don't do anything. 80 | if [ ${#1} -eq 0 ] ; then 81 | return 82 | fi 83 | if [ ! -f ${INI_FILE} ] ; then 84 | return 85 | fi 86 | sed -i "/^${1}=/d" ${INI_FILE} 87 | } 88 | 89 | # build up ${INI_FILE} or add to it if it is not there 90 | replace_or_add() { 91 | if [ ${#1} -eq 0 ] ; then 92 | return 93 | fi 94 | if [ ${#2} -eq 0 ] ; then 95 | remove $1 96 | return 97 | fi 98 | if grep -q "^$1=" ${INI_FILE} ; then 99 | sed -i -e "/^$1=/c $1=$2" ${INI_FILE} 100 | else 101 | echo "$1=$2" >> ${INI_FILE} 102 | fi 103 | } 104 | 105 | if [ "$1" = "clean" ] ; then 106 | rm ${INI_FILE} 107 | fi 108 | 109 | #prep the file 110 | if [ ! -f ${INI_FILE} ] ; then 111 | echo "# This file is autogenerated from:\n#\t${SELF}\n[Context Attributes]" > ${INI_FILE} 112 | else 113 | if [ $(grep "autogenerated from /etc/init.d/iiod" ${INI_FILE} | wc -c) -gt 1 ] ; then 114 | #old file, update 115 | sed -i "/autogenerated from \/etc\/init.d\/iiod/d" ${INI_FILE} 116 | sed -i "1,1s|^|# This file is autogenerated from:\n#\t${SELF}\n|" ${INI_FILE} 117 | fi 118 | if [ $(grep autodate ${INI_FILE} | wc -c) -eq 0 ] ; then 119 | sed -i '2a# autodate' ${INI_FILE} 120 | fi 121 | fi 122 | sed -i -e "/autodate/c # autodate $(date)" ${INI_FILE} 123 | grep -q '\[Context Attributes\]' ${INI_FILE} || echo "[Context Attributes]" >> ${INI_FILE} 124 | 125 | # save all we learned into the file 126 | replace_or_add hdl_system_id "${SYSID}" 127 | if [ "${BOARD+x}x" != "x" -a "${BASE}x" != "x" ] ; then 128 | replace_or_add hw_model "${BOARD} on ${BASE}" 129 | fi 130 | replace_or_add hw_carrier "${BASE}" 131 | replace_or_add hw_mezzanine "${BOARD}" 132 | replace_or_add hw_name "${NAME}" 133 | replace_or_add hw_vendor "${VENDOR}" 134 | replace_or_add hw_serial "${SERIAL}" 135 | replace_or_add unique_id "${UNIQUE_ID}" 136 | replace_or_add dtoverlay "${OVERLAY}" 137 | 138 | EXTRA_EEPROM_BOARDS="EVAL-CN0511-RPIZ" 139 | EXTRA_EEPROM_FILE="/sys/devices/platform/soc/fe804000.i2c/i2c-1/1-0051/eeprom" 140 | CAN_READ_EXTRA_EEPROM=0 141 | 142 | if echo "$EXTRA_EEPROM_BOARDS" | grep -w -q "$NAME"; then 143 | CAN_READ_EXTRA_EEPROM=1 144 | fi 145 | 146 | if [ "$CAN_READ_EXTRA_EEPROM" = "1" -a -f "$EXTRA_EEPROM_FILE" ]; then 147 | while read -r LINE; do 148 | IFS='=' read -r KEY VALUE <<-EOF 149 | $LINE 150 | EOF 151 | if [ -n "$KEY" -a -n "$VALUE" ]; then 152 | replace_or_add "$KEY" "$VALUE" 153 | fi 154 | done < "$EXTRA_EEPROM_FILE" 155 | fi 156 | 157 | exit 0 158 | -------------------------------------------------------------------------------- /usb-gadget-service/scripts/usb_gadget.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | UNIQUE_ID=$(dmesg | grep SPI-NOR-UniqueID | head -1) 5 | UNIQUE_ID=${UNIQUE_ID#*SPI-NOR-UniqueID } 6 | 7 | sha1=`echo $UNIQUE_ID | sha1sum` 8 | 9 | host_addr=`echo -n 00:E0:22; echo $sha1 | dd bs=1 count=6 2>/dev/null | hexdump -v -e '/1 ":%01c""%c"'` 10 | dev_addr=`echo -n 00:05:F7; echo $sha1 | dd bs=1 count=6 skip=6 2>/dev/null | hexdump -v -e '/1 ":%01c""%c"'` 11 | 12 | replace_or_add() { 13 | if [ ${#1} -eq 0 ] ; then 14 | return 15 | fi 16 | if [ ${#2} -eq 0 ] ; then 17 | return 18 | fi 19 | if [ ! -f /etc/defaults/adi_usb_gadget ] ; then 20 | echo "# Defaults for the ADI USB composite gadget" > /etc/defaults/adi_usb_gadget 21 | fi 22 | if grep -q $1 /etc/defaults/adi_usb_gadget ; then 23 | sed -i -e "/$1/c $1=$2" /etc/defaults/adi_usb_gadget 24 | else 25 | echo "$1=$2" >> /etc/defaults/adi_usb_gadget 26 | fi 27 | } 28 | 29 | replace_or_add host_addr $host_addr 30 | replace_or_add dev_addr $dev_addr 31 | replace_or_add serial $UNIQUE_ID 32 | 33 | exit 0 34 | -------------------------------------------------------------------------------- /usb-gadget-service/systemd/dev-iio_ffs.mount: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: LGPL-2.1+ 2 | # 3 | # dev-iio_ffs.mount - Systemd init script 4 | # 5 | # Copyright (C) 2021 Analog Devices Inc. 6 | 7 | [Unit] 8 | Description=Mount FunctionFS instance 9 | Requires=gt.service 10 | After=gt.service 11 | Before=iiod_ffs.service 12 | 13 | [Mount] 14 | # "device" name (FunctionFS instance name) 15 | What=iio_ffs 16 | Where=/dev/iio_ffs 17 | Type=functionfs 18 | Options=defaults 19 | TimeoutSec=5 20 | 21 | [Install] 22 | WantedBy=gt.target -------------------------------------------------------------------------------- /usb-gadget-service/systemd/gt-start.service: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: LGPL-2.1+ 2 | # 3 | # gt-start - Systemd init script 4 | # 5 | # Copyright (C) 2021 Analog Devices Inc. 6 | 7 | [Unit] 8 | Description=Start USB gadget scheme 9 | Requires=iiod_ffs.service 10 | After=iiod_ffs.service 11 | 12 | [Service] 13 | ExecStartPre=/bin/sleep 2 14 | ExecStart=/usr/local/bin/gt enable adi_usb_gadget 15 | RemainAfterExit=yes 16 | ExecStop=/usr/local/bin/gt disable adi_usb_gadget 17 | Type=oneshot 18 | 19 | [Install] 20 | WantedBy=gt.target 21 | -------------------------------------------------------------------------------- /usb-gadget-service/systemd/gt.service: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: LGPL-2.1+ 2 | # 3 | # gt.service - Systemd init script 4 | # 5 | # Copyright (C) 2021 Analog Devices Inc. 6 | 7 | [Unit] 8 | Description=Load USB gadget scheme 9 | Requires=sys-kernel-config.mount 10 | After=sys-kernel-config.mount network.target 11 | 12 | [Service] 13 | EnvironmentFile=-/etc/default/usb_gadget 14 | ExecStart=/usr/local/bin/gt load -o $GT_DEFAULT_SCHEME adi_usb_gadget 15 | RemainAfterExit=yes 16 | ExecStop=/usr/local/bin/gt rm -rf adi_usb_gadget 17 | Type=oneshot 18 | 19 | [Install] 20 | WantedBy=gt.target 21 | -------------------------------------------------------------------------------- /usb-gadget-service/systemd/gt.target: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: LGPL-2.1+ 2 | # 3 | # iiod - Systemd init script 4 | # 5 | # Copyright (C) 2021 Analog Devices Inc. 6 | 7 | [Unit] 8 | Description=Hardware activated USB gadget 9 | -------------------------------------------------------------------------------- /usb-gadget-service/systemd/iiod_context_attr.service: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: LGPL-2.1+ 2 | # 3 | # iiod Context Attribute - Systemd init script 4 | # 5 | # Copyright (C) 2021 Analog Devices Inc. 6 | 7 | [Unit] 8 | Description=Creating IIOD Context Attributes... 9 | ConditionPathExists=/sys/bus/iio 10 | Before=iiod.service iiod_ffs.service 11 | 12 | [Service] 13 | ExecStart=/bin/sh /usr/local/bin/iiod_context.sh 14 | RemainAfterExit=yes 15 | Type=oneshot 16 | 17 | [Install] 18 | WantedBy=multi-user.target 19 | -------------------------------------------------------------------------------- /usb-gadget-service/systemd/iiod_ffs.service: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: LGPL-2.1+ 2 | # 3 | # iiod - Systemd init script 4 | # 5 | # Copyright (C) 2021 Analog Devices Inc. 6 | 7 | [Unit] 8 | Description=IIO Daemon with USB FFS support 9 | ConditionPathExists=/sys/bus/iio 10 | ConditionPathIsMountPoint=/dev/iio_ffs 11 | Requires=dev-iio_ffs.mount systemd-udev-settle.service 12 | After=dev-iio_ffs.mount systemd-udev-settle.service 13 | Before=gt-start.service 14 | 15 | [Service] 16 | EnvironmentFile=-/etc/default/iiod 17 | ExecStartPre=/bin/sh -c 'systemctl -q is-active iiod.service && systemctl stop iiod.service' 18 | ExecStart=/usr/sbin/iiod $IIOD_EXTRA_OPTS $IIOD_EXTRA_FFS_OPTS 19 | KillMode=process 20 | Restart=on-failure 21 | 22 | [Install] 23 | WantedBy=gt.target 24 | -------------------------------------------------------------------------------- /usb-gadget-service/udev/99-udc.rules: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MIT or LGPL-2.1+ 2 | # 3 | # Copyright 2019 Collabora Ltd 4 | # 5 | SUBSYSTEM=="udc", ACTION=="add", TAG+="systemd", ENV{SYSTEMD_WANTS}+="gt.target" 6 | -------------------------------------------------------------------------------- /usb_otg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2021-22 Analog Devices, Inc. All Rights Reserved. 4 | # This software is proprietary to Analog Devices, Inc. and its licensors. 5 | # By using this software you agree to the terms of the associated 6 | # Analog Devices Software License Agreement. 7 | 8 | # Manages USB OtG configuration in devicetree for supported platforms 9 | 10 | 11 | is_compatible() { 12 | echo $COMP | grep -q $1 13 | return $? 14 | } 15 | 16 | check_platform() { 17 | # Most ARM systems will fill /sys/firmware. 18 | COMPATIBLE="/proc/device-tree/compatible" 19 | if [ -f "${COMPATIBLE}" ] ; then 20 | COMP=$(strings /proc/device-tree/compatible) 21 | echo "Compatible=$COMP" 22 | else 23 | echo "[ERROR] No Model information in devicetree" 24 | exit 1 25 | fi 26 | 27 | if $(is_compatible "xlnx,zynq-7000"); then 28 | fdtget -p /boot/devicetree.dtb /axi > /dev/null 2>&1 && USB="/axi/usb@e0002000" || USB="/amba/usb@e0002000" 29 | DTB="/boot/devicetree.dtb" 30 | elif $(is_compatible "xlnx,zynqmp"); then 31 | fdtget -p /boot/system.dtb /axi > /dev/null 2>&1 && USB="/axi/usb@ff9d0000/usb@fe200000" || USB="/amba/usb@ff9d0000/usb@fe200000" 32 | DTB="/boot/system.dtb" 33 | elif $(is_compatible "altr,socfpga-cyclone5"); then 34 | USB="/soc/usb@ffb40000" 35 | DTB="/boot/socfpga.dtb" 36 | else 37 | # All other platform are not supported 38 | echo "USB OtG Supported=No" 39 | exit 1 40 | fi 41 | echo "USB OtG Supported=Yes" 42 | } 43 | 44 | show_status() { 45 | echo "USB dr_mode=" $(fdtget --default "Not Specified: per usb/generic.txt dr_mode should default to otg" --type s $DTB $USB dr_mode) 46 | } 47 | 48 | case "$1" in 49 | enable) 50 | check_platform 51 | fdtput -t s $DTB $USB dr_mode otg 52 | show_status 53 | ;; 54 | 55 | disable) 56 | check_platform 57 | fdtput -t s $DTB $USB dr_mode host 58 | show_status 59 | ;; 60 | 61 | delete_dr_mode) 62 | check_platform 63 | fdtput -d $DTB $USB dr_mode 64 | show_status 65 | ;; 66 | 67 | status) 68 | check_platform 69 | show_status 70 | ;; 71 | 72 | *) 73 | echo "Usage: $0 {enable|disable|delete_dr_mode|status}" 74 | exit 1 75 | ;; 76 | esac 77 | 78 | -------------------------------------------------------------------------------- /verify_ad9361_spi: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #finds the AD9361 device 4 | for i in $(find -L /sys/bus/iio/devices -maxdepth 2 -name name) 5 | do 6 | dev_name=$(cat $i) 7 | if [ "$dev_name" = "ad9361-phy" ] ; then 8 | ad9361=$(echo $i | sed 's:/name$::') 9 | break 10 | fi 11 | done 12 | 13 | if [ "x$ad9361" = "x" ] ; then 14 | echo can not find ad9361 in /sys 15 | exit 16 | fi 17 | 18 | # does a walking ones/zeros on the SPI bus. 19 | # register 0x28 is 'GPO0 Rx delay' 20 | cd $ad9361 21 | expect=0x1 22 | up=1 23 | reg=0x28 24 | echo $reg $expect > ./direct_reg_access 25 | echo $reg > ./direct_reg_access 26 | i=0 27 | k=0 28 | echo "preforming walking one/zero tests on SPI register $reg" 29 | trap 'printf "\nread %d times\n" $k; exit 0' 2 30 | echo -n 1 31 | while [ 1 ] 32 | do 33 | # sleep .5 34 | i=`expr $i + 1` 35 | k=`expr $k + 1` 36 | foo=$(cat ./direct_reg_access) 37 | #echo $i $expect $foo 38 | if [ "$foo" != "$expect" ] ; then 39 | echo -n "$foo is not equal to '$expect' " 40 | date 41 | fi 42 | if [ $i -gt 999 ] ; then 43 | #echo 1000 reads of $expect worked 44 | j=`printf "%d" $expect` 45 | if [ $up -eq 1 ] ; then 46 | if [ $j -eq 0 ] ; then 47 | up=0; 48 | echo -n 0 49 | fi 50 | if [ $j -eq 255 ] ; then 51 | j=1 52 | else 53 | j=`expr '(' $j '*' 2 ')' % 256` 54 | fi 55 | expect=`printf "0x%X" $j` 56 | else 57 | if [ $j -eq 255 ] ; then 58 | up=1 59 | echo -n 1 60 | fi 61 | if [ $j -eq 0 ] ; then 62 | j=127 63 | else 64 | j=`expr '(' $j '/' 2 ')' + 128` 65 | fi 66 | expect=`printf "0x%X" $j` 67 | fi 68 | echo $reg $expect > ./direct_reg_access 69 | i=0 70 | fi 71 | done 72 | 73 | -------------------------------------------------------------------------------- /verify_ad9361_temp: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for i in $(find -L /sys/bus/iio/devices -maxdepth 2 -name name) 4 | do 5 | dev_name=$(cat $i) 6 | if [ "$dev_name" = "ad9361-phy" ] ; then 7 | ad9361=$(echo $i | sed 's:/name$::') 8 | break 9 | fi 10 | done 11 | 12 | if [ "x$ad9361" = "x" ] ; then 13 | echo can not find ad9361 in /sys 14 | exit 15 | fi 16 | 17 | cd $ad9361 18 | bbpll=$(cat rx_path_rates | sed -e 's|^BBPLL:||' -e 's| .*$||') 19 | device=$(echo $ad9361 | awk -F '/' '{print $NF}') 20 | # determine the time for new temperatures to be added - can't get something faster than I should 21 | if [ -d /sys/kernel/debug/iio/$device ] ; then 22 | echo 0x00D > /sys/kernel/debug/iio/$device/direct_reg_access 23 | len=$(printf "%d" `cat /sys/kernel/debug/iio/$device/direct_reg_access`) 24 | else 25 | len=127 26 | fi 27 | # (2^29 + 10%) = 5905580032 28 | len=$(expr '(' $len '/' 2 ')' '*' 5905580032 '/' $bbpll) 29 | len=$(printf "%d.%d\n" `expr $len '/' 10` `expr $len - '(' $len '/' 10 '*' 10 ')'`) 30 | 31 | avg=$(cat in_temp0_input) 32 | # tolerance of the temp sensor is +/- 3C 33 | tolerance=3000 34 | max=`expr $avg + $tolerance` 35 | min=`expr $avg - $tolerance` 36 | echo "found $ad9361, starting temp ${avg}, reading every $len seconds" 37 | start=`date +%s` 38 | last_err=-1 39 | while [ 1 ] 40 | do 41 | sleep $len 42 | temp=$(cat in_temp0_input) 43 | # echo checking $temp against $max and $min, avg $avg 44 | if [ $temp -gt $max ] ; then 45 | if [ $last_err -ne $temp ] ; then 46 | last_err=$temp 47 | echo -n "read $temp, exceeds max of $max, avg = $avg " 48 | err=`date +%s` 49 | sec=`expr $err - $start` 50 | hrs=`expr $sec / 3600` 51 | min=`expr '(' $sec - '(' $hrs '*' 60 ')' ')' / 60` 52 | sec=`expr $sec % 60` 53 | printf "%d:%d:%02d elapsed\n" $hrs $min $sec 54 | fi 55 | else 56 | if [ $temp -lt $min ] ; then 57 | if [ $last_err -ne $temp ] ; then 58 | last_err=$temp 59 | echo -n "read $temp, under min of $min, avg = $avg " 60 | err=`date +%s` 61 | sec=`expr $err - $start` 62 | hrs=`expr $sec / 3600` 63 | min=`expr '(' $sec - '(' $hrs '*' 60 ')' ')' / 60` 64 | sec=`expr $sec % 60` 65 | printf "%d:%d:%02d elapsed\n" $hrs $min $sec 66 | fi 67 | else 68 | avg=`expr '(' $avg + $temp ')' / 2` 69 | max=`expr $avg + $tolerance` 70 | min=`expr $avg - $tolerance` 71 | fi 72 | fi 73 | done 74 | 75 | --------------------------------------------------------------------------------