├── .gitignore ├── Config.in ├── README.md ├── board └── pluto │ ├── LICENSE.template │ ├── busybox-1.25.0.config │ ├── genimage-boot.cfg │ ├── genimage-msd.cfg │ ├── linux-c2041af164e263d852897cf90edb5cca9f677579.fragment │ ├── msd │ ├── .gitignore │ ├── LICENSE │ ├── img │ │ ├── ADI_Logo_AWP.png │ │ ├── GNURadio_logo.png │ │ ├── PlutoSDR.png │ │ ├── SDR-Sharp.png │ │ ├── download.png │ │ ├── ez.png │ │ ├── favicon.ico │ │ ├── fb.png │ │ ├── gp.png │ │ ├── ig.png │ │ ├── li.png │ │ ├── mathworks_logo.png │ │ ├── osc128.png │ │ ├── prof_blue.png │ │ ├── sdrangel.png │ │ ├── ss.png │ │ ├── style.css │ │ ├── sw.png │ │ ├── tw.png │ │ ├── version.js │ │ ├── yk.png │ │ └── yt.png │ └── index.html │ ├── overlay │ ├── etc │ │ ├── device_config │ │ ├── fw_env.config │ │ ├── init.d │ │ │ ├── S10mdev │ │ │ ├── S15watchdog │ │ │ ├── S20urandom │ │ │ ├── S21misc │ │ │ ├── S23udc │ │ │ ├── S40network │ │ │ ├── S41network │ │ │ └── S45msd │ │ ├── input-event-daemon.conf │ │ ├── mdev.conf │ │ ├── motd │ │ ├── network │ │ │ ├── if-down.d │ │ │ │ └── wpasupplicant │ │ │ ├── if-post-down.d │ │ │ │ └── wpasupplicant │ │ │ ├── if-pre-up.d │ │ │ │ └── wpasupplicant │ │ │ └── if-up.d │ │ │ │ └── wpasupplicant │ │ └── wpa_supplicant │ │ │ ├── action_wpa.sh │ │ │ ├── functions.sh │ │ │ └── ifupdown.sh │ ├── lib │ │ └── mdev │ │ │ ├── automounter.sh │ │ │ └── ifupdown.sh │ ├── opt │ │ └── VERSIONS │ ├── sbin │ │ ├── udc_handle_suspend.sh │ │ ├── update.sh │ │ └── update_frm.sh │ ├── usr │ │ └── sbin │ │ │ ├── device_reboot │ │ │ ├── pluto_reboot │ │ │ └── test_ensm_pinctrl.sh │ └── www │ │ ├── img │ │ ├── ADI_Logo_AWP.png │ │ ├── GNURadio_logo.png │ │ ├── PlutoSDR.png │ │ ├── SDR-Sharp.png │ │ ├── download.png │ │ ├── ez.png │ │ ├── favicon.ico │ │ ├── fb.png │ │ ├── gp.png │ │ ├── ig.png │ │ ├── li.png │ │ ├── mathworks_logo.png │ │ ├── osc128.png │ │ ├── prof_blue.png │ │ ├── sdrangel.png │ │ ├── ss.png │ │ ├── style.css │ │ ├── sw.png │ │ ├── tw.png │ │ ├── version.js │ │ ├── yk.png │ │ └── yt.png │ │ └── index.html │ ├── patches │ └── uboot │ │ └── 89d07540f9d489cc63460df5636174357af0a38f │ │ ├── 0001-add_pluto-sdr_hw_platform.patch │ │ ├── 0002-add_plutoSDR_include.patch │ │ └── 0003-update_plutoSDR_defconfig.patch │ ├── pluto.its │ ├── post-build.sh │ ├── post_image-uboot.sh │ ├── post_image.sh │ ├── target_mtd_info.key │ └── uboot-env.txt ├── configs ├── README.md ├── zynq_pluto_defconfig └── zynq_pluto_gnuradio_defconfig ├── doc ├── IMG_20200527_211928small.jpg ├── README.md ├── danger.pdf ├── gnuradio_on_RPi_English.pdf ├── gnuradio_on_RPi_English.tex ├── gnuradio_sur_RPi4_Francais.pdf ├── gnuradio_sur_RPi4_Francais.tex ├── host.pdf ├── host.png ├── movie_FM_to_0MQstream.ogv ├── picture.jpg ├── pluto_embedded.grc ├── pluto_pc.grc ├── target.pdf ├── target.png ├── top_block_for_PC.py └── top_block_for_pluto.py ├── external.desc ├── external.mk ├── package ├── ad936x_ref_cal │ ├── Config.in │ └── ad936x_ref_cal.mk ├── gr-iio │ ├── Config.in │ └── gr-iio.mk ├── libad9361-iio │ ├── Config.in │ └── libad9361-iio.mk ├── libiio-pluto │ ├── Config.in │ ├── S99iiod │ ├── libiio-pluto.hash │ └── libiio-pluto.mk ├── libini │ ├── Config.in │ └── libini.mk ├── pluto-system-top-bit │ ├── Config.in │ └── pluto-system-top-bit.mk └── poll_sysfs │ ├── Config.in │ ├── poll_sysfs.c │ └── poll_sysfs.mk └── sourceme.ggm /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | -------------------------------------------------------------------------------- /Config.in: -------------------------------------------------------------------------------- 1 | 2 | source "$BR2_EXTERNAL_PLUTOSDR_PATH/package/ad936x_ref_cal/Config.in" 3 | source "$BR2_EXTERNAL_PLUTOSDR_PATH/package/libad9361-iio/Config.in" 4 | source "$BR2_EXTERNAL_PLUTOSDR_PATH/package/libiio-pluto/Config.in" 5 | source "$BR2_EXTERNAL_PLUTOSDR_PATH/package/libini/Config.in" 6 | source "$BR2_EXTERNAL_PLUTOSDR_PATH/package/pluto-system-top-bit/Config.in" 7 | source "$BR2_EXTERNAL_PLUTOSDR_PATH/package/poll_sysfs/Config.in" 8 | source "$BR2_EXTERNAL_PLUTOSDR_PATH/package/gr-iio/Config.in" 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PlutoSDR 2 | BR2_EXTERNAL framework for Analog Device's PlutoSDR Zynq 3 | 4 | This repository provides buildroot based support for ADALM-pluto board (based on 5 | [Analog Device's plutosdr-fw](https://github.com/analogdevicesinc/plutosdr-fw)). 6 | 7 | At the moment, this repository provides support for rootfs, linux and bootloader. 8 | 9 | It uses the BR2_EXTERNAL mechanism to add this support to buildroot. 10 | 11 | This support has been tested with the latest stable release of buildroot (2018.11.1) and git master branch. 12 | 13 | How-to use it 14 | ============= 15 | 16 | ### With *Buildroot* tag **v2024.08** 17 | 18 | Download the tested buildroot tarball: 19 | ```bash 20 | wget https://buildroot.org/downloads/buildroot-2024.08.tar.gz 21 | ``` 22 | 23 | If you wish to rename the directory, do so *before* running ``make zynq_pluto_defconfig`` (below) since some links in the tree structure created by the configuration will break if renaming the directory name afterward. 24 | 25 | ### Configure, build and install 26 | 27 | Adding support for the PlutoSDR requires sourcing the **sourceme.ggm** file to add the **BR2_EXTERNAL** 28 | variable definition (alternatively, one might want to add export 29 | BR2_EXTERNAL=/somewhere/PlutoSDR to the *.bashrc* initialization file). 30 | 31 | In the buildroot directory 32 | ```bash 33 | make zynq_pluto_defconfig 34 | ``` 35 | will configure buildroot for minimal PlutoSDR support. More ambitious, after git cloning the 36 | latest release of buildroot, 37 | ```bash 38 | make zynq_pluto_gnuradio_defconfig 39 | ``` 40 | will configure buildroot for PlutoSDR support in addition to GNURadio. The default configuration is 41 | to not support Python, yielding a 13.4 MB image. Activating Python requires going to Target Packages --> Interpreter 42 | languages --> python and then Miscellaneous --> gnuradio --> python support. We also 43 | activate gr-zeromq support to stream I/Q coefficients from the PlutoSDR to the PC. Do not attempt adding Python 44 | support after compiling an image without Python support: the gnuradio packages would not be compiled properly. 45 | Start from scratch from a clean output directory (rm -rf output). For the resulting image to be 46 | smaller than 32 MB, we remove wpa_supplicant and associated 802.11 packages as well as avahi. 47 | 48 | Overall, make menuconfig allows for configuring 49 | additional settings of the buildroot environment, especially Target Packages, make builds 50 | the images to be found at the end of the compilation in output/images. 51 | 52 | The output/images/pluto.frm file is then copied to the mass storage mounted from the PlutoSDR (in 53 | most cases /dev/sdb1) 54 | and then written after ejecting the associated mass storage root (in this example sudo eject /dev/sdb) as 55 | explained at [Analog Device's PlutoSDR firmware information](https://wiki.analog.com/university/tools/pluto/users/firmware) 56 | 57 | In case of failure, DFU programming provides a backup solution. **MAKE SURE TO POWER THE DIO PIN OF THE FTDI INTERFACE 58 | WITH 1.8V and NOT the default 3.3 or 5V (that will definitely destroy the Zynq)** 59 | 60 | ![PlutoSDR picture](doc/picture.jpg) 61 | 62 | Doing so does not necessarily require the FTDI USB to R232 converter, although this peripheral will provide a prompt to check what 63 | is happening on the PlutoSDR. Switching to DFU mode is achieved by mounting the first mass storage partition (let's say /dev/sdb1), 64 | modifying config.txt to set dfu = 1, and saving the change + rebooting the board with sudo eject 65 | /dev/sdb. Once the board is in DFU mode, the DFU image is flashed with dfu-util -D /tmp/pluto.dfu -a firmware.dfu. 66 | 67 | GNU Radio on the PlutoSDR 68 | ========================= 69 | 70 | Listening to an FM station demodulated by the WBFM block running on the Zynq PS requires activating the 71 | second CPU core, extending the AD9363 carrier frequency band to those of the AD9364, and compiling fftw with 72 | speed optimization. With such considerations, the following [processing block](doc/top_block_for_pluto.py) runs on the PS of the Zynq to fetch samples from the AD9363 (local IIO connection), filter and demodulate the signal, and push to a 0MQ stream the sound signal at 24 or 48 kS/s. On the 0MQ receiver side, the following [processing block](doc/top_block_for_PC.py) is run on the PC to fetch data through a 0MQ socket and play sound on the PC speaker. 73 | 74 | [Here is a movie demonstrating](doc/movie_FM_to_0MQstream.ogv) the acquisition of a FM station in the commercial 75 | broadcast band, processing using the WBFM block running on the Zynq, streaming the data to the PC (at 24 kS/s rather 76 | than the >200 kS/s needed to demodulate FM) and using the PC as a sound card. 77 | 78 | Activating hard-floating point processing is mandatory to achieve continuous FM demodulated sound stream: indeed, lacking the 79 | [~40% processing gain](https://blog.paranoidpenguin.net/2017/09/hard-float-vs-soft-float-with-slackware-arm-on-the-rpi-3/) would 80 | result in discontinuous sound output due to insufficient computational power to run the WBFM block on the 81 | minimum 200-kS/s input stream. 82 | 83 | Custom bitstream on the PL 84 | ========================== 85 | 86 | Customizing the PL bitstream meets some requirement for full control of the PlutoSDR features: in [this example](https://github.com/oscimp/oscimpDigital/tree/master/doc/tutorials/plutosdr/99-gnuradio-audio), an ALSA-compatible 87 | audio output is added to make the PlutoSDR a fully autonomous FM-broadcast radio receiver. Adding such functionalities 88 | requires generating a new bitstream including the additional block, generating a new DFU image to send to the PlutoSDR, 89 | and telling GNU/Linux about the new reconfigurable hardware (devicetree entry). The [documentation](https://github.com/oscimp/oscimpDigital/blob/master/doc/tutorials/plutosdr/99-gnuradio-audio/1-gnuradio-audio.pdf) aims at describing all these steps. 90 | 91 | gnss-sdr on embedded platforms 92 | ============================== 93 | 94 | The BR2_EXTERNAL includes in the for_next branch packages that are not (yet) officially integrated in Buildroot, 95 | including UHD (USRP Hardware Device from Ettus Research). Because this package is not officially integrated in Buildroot, 96 | support for UHD in GNU Radio (which is officially supported in Buildroot) requires tuning the gnuradio package 97 | configuration. In ``package/gnuradio/gnuradio.mk`` of the official Buildroot release, add ``-DENABLE_GR_UHD=ON`` 98 | to the ``GNURADIO_CONF_OPTS`` variable. If GNU Radio was already compiled before setting this option, then 99 | ``make gnuradio-reconfigure``. This option is mandatory for activating UHD support in gnss-sdr as well for live decoding 100 | GNSS messages received by an USRP (e.g. B210). 101 | -------------------------------------------------------------------------------- /board/pluto/genimage-boot.cfg: -------------------------------------------------------------------------------- 1 | image boot.img { 2 | hdimage { 3 | } 4 | 5 | partition fsbl { 6 | in-partition-table = "no" 7 | image = "boot.bin" 8 | } 9 | 10 | partition uboot { 11 | in-partition-table = "no" 12 | image = "u-boot.img" 13 | offset = 256K 14 | } 15 | size = 1M 16 | } 17 | -------------------------------------------------------------------------------- /board/pluto/genimage-msd.cfg: -------------------------------------------------------------------------------- 1 | image boot.vfat { 2 | vfat { 3 | extraargs = "-n PlutoSDR" 4 | files = {"index.html", "LICENSE.html"} 5 | } 6 | size = 30M 7 | } 8 | 9 | image vfat.img { 10 | hdimage { 11 | } 12 | 13 | partition boot { 14 | partition-type = 0xC 15 | bootable = "false" 16 | image = "boot.vfat" 17 | } 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /board/pluto/linux-c2041af164e263d852897cf90edb5cca9f677579.fragment: -------------------------------------------------------------------------------- 1 | CONFIG_OF_OVERLAY=y 2 | CONFIG_OF_CONFIGFS=y 3 | -------------------------------------------------------------------------------- /board/pluto/msd/.gitignore: -------------------------------------------------------------------------------- 1 | LICENSE.html 2 | -------------------------------------------------------------------------------- /board/pluto/msd/img/ADI_Logo_AWP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/ADI_Logo_AWP.png -------------------------------------------------------------------------------- /board/pluto/msd/img/GNURadio_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/GNURadio_logo.png -------------------------------------------------------------------------------- /board/pluto/msd/img/PlutoSDR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/PlutoSDR.png -------------------------------------------------------------------------------- /board/pluto/msd/img/SDR-Sharp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/SDR-Sharp.png -------------------------------------------------------------------------------- /board/pluto/msd/img/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/download.png -------------------------------------------------------------------------------- /board/pluto/msd/img/ez.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/ez.png -------------------------------------------------------------------------------- /board/pluto/msd/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/favicon.ico -------------------------------------------------------------------------------- /board/pluto/msd/img/fb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/fb.png -------------------------------------------------------------------------------- /board/pluto/msd/img/gp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/gp.png -------------------------------------------------------------------------------- /board/pluto/msd/img/ig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/ig.png -------------------------------------------------------------------------------- /board/pluto/msd/img/li.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/li.png -------------------------------------------------------------------------------- /board/pluto/msd/img/mathworks_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/mathworks_logo.png -------------------------------------------------------------------------------- /board/pluto/msd/img/osc128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/osc128.png -------------------------------------------------------------------------------- /board/pluto/msd/img/prof_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/prof_blue.png -------------------------------------------------------------------------------- /board/pluto/msd/img/sdrangel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/sdrangel.png -------------------------------------------------------------------------------- /board/pluto/msd/img/ss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/ss.png -------------------------------------------------------------------------------- /board/pluto/msd/img/style.css: -------------------------------------------------------------------------------- 1 | body{ 2 | font-family: "Helvetica Neue", sans-serif; 3 | font-size: 16px; 4 | font-weight: normal; 5 | line-height: 1.3em; 6 | color: #636363; 7 | padding: 0 20px 0; 8 | max-width: 1024px; 9 | margin: auto; 10 | } 11 | hr{ 12 | color: #ccc; 13 | margin: 10px 0 20px; 14 | } 15 | h1, h3{ 16 | font-family: "Arial Regular", sans-serif; 17 | font-weight: bold; 18 | margin-bottom:0; 19 | } 20 | h1{ 21 | font-size: 32px; 22 | color: #1e4056; 23 | margin-bottom: 40px; 24 | } 25 | h3{ 26 | font-size: 24px; 27 | } 28 | header{ 29 | margin-bottom: 20px; 30 | } 31 | header img{ 32 | margin-top: 10px; 33 | width: 175px; 34 | } 35 | nav{ 36 | margin-bottom: 20px; 37 | } 38 | ul{ 39 | padding-left: 20px; 40 | } 41 | table{ 42 | width: 100%; 43 | } 44 | th{ 45 | background-color: #33b3ca; 46 | color: #fff; 47 | font-weight: normal; 48 | padding: 10px; 49 | text-align: left; 50 | } 51 | td{ 52 | background-color: #f5f5f5; 53 | font-size: 14px; 54 | padding: 5px 10px; 55 | } 56 | th:first-of-type, 57 | td:first-of-type{ 58 | width: 25%; 59 | font-weight: bold; 60 | } 61 | #versiontest{ 62 | color: #27B34F; 63 | } 64 | a{ 65 | color: #33b3ca; 66 | text-decoration: none; 67 | } 68 | .button{ 69 | background-color: #33b3ca; 70 | border-radius: 15px; 71 | color: #ffffff; 72 | margin: 15px 10px 15px 10px; 73 | padding: 5px 15px; 74 | cursor: pointer; 75 | } 76 | .dropdown { 77 | position: relative; 78 | text-align: left; 79 | display: inline-block; 80 | } 81 | .dropdown-content { 82 | display: none; 83 | position: absolute; 84 | background-color: #f9f9f9; 85 | min-width: 200px; 86 | border-radius: 15px; 87 | box-shadow: 0px 8px 24px 0px rgba(0,0,0,0.2); 88 | padding: 10px 10px; 89 | z-index: 1; 90 | } 91 | .dropdown:hover .dropdown-content { 92 | display: block; 93 | } 94 | .download{ 95 | background-image: url("download.png"); 96 | padding: 1em 1em .5em 70px; 97 | margin-bottom: 1.5em; 98 | min-height: 68px; 99 | background-position: 10px 50%; 100 | background-repeat: no-repeat; 101 | color: #000; 102 | overflow: hidden; 103 | box-sizing: border-box; 104 | background-color: #d6efc2; 105 | border-radius: 1.4em; 106 | } 107 | .quicklinks{ 108 | float: right; 109 | -webkit-column-count: 2; /* Chrome, Safari, Opera */ 110 | -moz-column-count: 2; /* Firefox */ 111 | column-count: 2; 112 | -webkit-column-gap: 20px; /* Chrome, Safari, Opera */ 113 | -moz-column-gap: 20px; /* Firefox */ 114 | column-gap: 20px; 115 | -webkit-column-rule: 1px solid lightblue; /* Chrome, Safari, Opera */ 116 | -moz-column-rule: 1px solid lightblue; /* Firefox */ 117 | column-rule: 1px solid lightblue; 118 | list-style: none; 119 | list-style-type: none; 120 | list-style-image: none; 121 | list-style-position: outside; 122 | font-size: 12px; 123 | line-height: 18px; 124 | font-family: Helvetica,Arial,sans-serif; 125 | margin-top: 2em; 126 | margin-bottom: 0em; 127 | } 128 | .colLeft, .colRight{ 129 | float: left; 130 | } 131 | .colLeft{ 132 | width: 60%; 133 | } 134 | .colRight{ 135 | width: 40%; 136 | text-align: center; 137 | } 138 | .anchor{ 139 | float: right; 140 | } 141 | .boxed { 142 | box-sizing: border-box; 143 | padding: 10px; 144 | border: 1px solid; 145 | border-color: #636363; 146 | border-radius: 5px; 147 | } 148 | pre { 149 | display: inline; 150 | margin: 0; 151 | } 152 | .xterm { 153 | color:#333; 154 | display:block; 155 | font-family:Monaco,Menlo,Consolas,"Courier New",monospace; 156 | padding:9.5px; 157 | margin:0 0 10px; 158 | font-size:13px; 159 | word-break:break-all; 160 | word-wrap:break-word; 161 | background-color:#f5f5f5; 162 | border:1px solid #ccc; 163 | border-radius:4px; 164 | } 165 | -------------------------------------------------------------------------------- /board/pluto/msd/img/sw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/sw.png -------------------------------------------------------------------------------- /board/pluto/msd/img/tw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/tw.png -------------------------------------------------------------------------------- /board/pluto/msd/img/version.js: -------------------------------------------------------------------------------- 1 | function OnTheWeb() { 2 | window.location.assign("https://wiki.analog.com/university/tools/pluto"); 3 | } 4 | 5 | function versionCompare(v1, v2) { 6 | var v1parts = ("" + v1).replace(/[a-zA-Z]/g, "").replace("-", ".").split("."), 7 | v2parts = ("" + v2).replace(/[a-zA-Z]/g, "").replace("-", ".").split("."), 8 | minLength = Math.min(v1parts.length, v2parts.length), 9 | p1, p2, i; 10 | console.log(v1parts + " || " + v2parts); 11 | for(i = 0; i < minLength; i++) { 12 | p1 = parseInt(v1parts[i], 10); 13 | p2 = parseInt(v2parts[i], 10); 14 | if (isNaN(p1)){ p1 = v1parts[i]; } 15 | if (isNaN(p2)){ p2 = v2parts[i]; } 16 | if (p1 == p2) { 17 | continue; 18 | }else if (p1 > p2) { 19 | return 1; 20 | }else if (p1 < p2) { 21 | return -1; 22 | } 23 | return NaN; 24 | } 25 | if (v1parts.length === v2parts.length) { 26 | return 0; 27 | } 28 | return (v1parts.length < v2parts.length) ? -1 : 1; 29 | } 30 | 31 | var latest_libiio; 32 | var mac = false; 33 | 34 | function GetDriverurl() { 35 | mac = navigator.platform.match(/Mac/i) ? true : false; 36 | if (mac) { 37 | var uAgent = navigator.userAgent.toLowerCase(); 38 | //uAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36".toLowerCase(); 39 | var test = uAgent.match(/mac os x 10_[0-9]*/); 40 | if (test) { 41 | mac = "darwin-" + test[0].match(/10_[0-9]*/)[0].replace("_", "."); 42 | } 43 | document.getElementById('prompt0').innerHTML = "adi-mm:tests analogdevices$"; 44 | document.getElementById('prompt1').innerHTML = "adi-mm:tests analogdevices$"; 45 | } else { 46 | document.getElementById('hidehorndis').style.display = "none"; 47 | } 48 | var win = navigator.platform.indexOf('Win') > -1 ? true : false; 49 | if (win) { 50 | document.getElementById('prompt0').innerHTML = "C:\>"; 51 | document.getElementById('prompt1').innerHTML = "C:\>"; 52 | } else 53 | document.getElementById('hidedriver').style.display = "none"; 54 | var linux = navigator.platform.indexOf('Linux') > -1 ? true : false; 55 | if (mac || win || linux) 56 | document.getElementById('hidelib').style.display = "inline"; 57 | else { 58 | if (navigator.platform.match(/(Linux|iPhone|iPod|iPad|Android)/i)) { 59 | document.getElementById('libtest').innerHTML = "Sorry, we don't support " + navigator.platform + " yet. Please ask."; 60 | jQuery('#libtest').attr ('href', "https://ez.analog.com/university-program"); 61 | } else 62 | document.getElementById('libtest').innerHTML = "Unsupported host \"" + navigator.platform + "\". Please check, and report an issue"; 63 | return; 64 | } 65 | 66 | var i; var j; 67 | 68 | var req = jQuery.getJSON("https://api.github.com/repos/analogdevicesinc/libiio/releases/latest"); 69 | req.fail(function() { 70 | document.getElementById('hidelib').style.display = "none"; 71 | latest_libiio = null; 72 | }); 73 | req.done(function(response) { 74 | latest_libiio = response; 75 | var select = document.getElementById("os-select"); 76 | var suffix = ""; 77 | for (i = 0; i < latest_libiio.assets.length; i++) { 78 | os = latest_libiio.assets[i].name.split('-')[2]; 79 | suffix = os.slice(-4); 80 | if (suffix == ".zip" ) { 81 | os = os.slice(0, os.length-4); 82 | } 83 | for (j = 0; j < select.length; j++) { 84 | if (os.match(select[j].value)) 85 | break; 86 | } 87 | if (j == select.length) { 88 | select.options[select.options.length] = new Option(os); 89 | if ((win && os == "Windows") || (mac && os == "darwin") || (linux && os == "ubuntu")) { 90 | select.value = os; 91 | libiio_type(); 92 | } 93 | } 94 | } 95 | if (latest_libiio.hasOwnProperty('tarball_url') || latest_libiio.hasOwnProperty('zipball_url')) 96 | select.options[select.options.length] = new Option("source"); 97 | }); 98 | if (win) { 99 | req = jQuery.getJSON("https://api.github.com/repos/analogdevicesinc/plutosdr-m2k-drivers-win/releases/latest"); 100 | req.done(function(response) { 101 | for (i = 0; i < response.assets.length; i++) { 102 | if (response.assets[i].content_type == "application/x-msdownload") { 103 | jQuery('#drivertest').attr ('href', response.assets[i].browser_download_url); 104 | document.getElementById('drivertest').innerHTML = response.name; 105 | } 106 | } 107 | }); 108 | } else if (mac) { 109 | req = jQuery.getJSON("https://api.github.com/repos/jwise/HoRNDIS/releases/latest"); 110 | req.done(function(response) { 111 | for (i = 0; i < response.assets.length; i++) { 112 | if (response.assets[i].content_type == "application/octet-stream" && 113 | response.assets[i].browser_download_url.slice(-4) == ".pkg") { 114 | jQuery('#horndistest').attr ('href', response.assets[i].browser_download_url); 115 | document.getElementById('horndistest').innerHTML = response.name; 116 | } 117 | } 118 | }); 119 | } else { 120 | document.getElementById('hidedriver').style.display = "none"; 121 | 122 | } 123 | } 124 | 125 | function libiio_type() { 126 | var select = document.getElementById("type-select"); 127 | var os = document.getElementById("os-select").value; 128 | select.onchange = null; 129 | var i; 130 | for (i = select.options.length - 1 ; i >= 0 ; i--) { 131 | select.remove(i); 132 | } 133 | var suffix = ""; 134 | for (i = 0; i < latest_libiio.assets.length; i++) { 135 | if (latest_libiio.assets[i].browser_download_url.match(os)) { 136 | suffix = latest_libiio.assets[i].browser_download_url.slice(-4); 137 | if (suffix == "r.gz" ) { 138 | suffix = ".tar.gz"; 139 | } 140 | for (j = 0; j < select.length; j++) { 141 | if (suffix.match(select[j].value)) 142 | break; 143 | } 144 | if (j == select.length) { 145 | select.options[select.options.length] = new Option(suffix); 146 | if (os.match('centos') && suffix.match('.rpm')) { 147 | select.value = suffix; 148 | } 149 | } 150 | } 151 | } 152 | if (os.match('source')) { 153 | if (latest_libiio.hasOwnProperty('tarball_url')) 154 | select.options[select.options.length] = new Option('.tar'); 155 | if (latest_libiio.hasOwnProperty('zipball_url')) 156 | select.options[select.options.length] = new Option('.zip'); 157 | } 158 | select.onchange = libiio_ver; 159 | libiio_ver(); 160 | } 161 | 162 | function libiio_ver() { 163 | var select = document.getElementById("ver-select"); 164 | var os = document.getElementById("os-select").value; 165 | var suffix = document.getElementById("type-select").value; 166 | select.onchange = null; 167 | var i; 168 | for (i = select.options.length - 1 ; i >= 0 ; i--) { 169 | select.remove(i); 170 | } 171 | for (i = 0; i < latest_libiio.assets.length; i++) { 172 | if (latest_libiio.assets[i].browser_download_url.match(os) && latest_libiio.assets[i].browser_download_url.match(suffix)) { 173 | var file = latest_libiio.assets[i].name.replace(/libiio-[0-9]*\.[0-9]*.[a-z0-9]*-/, ''); 174 | file = file.slice(0, file.length - suffix.length); 175 | select.options[select.options.length] = new Option(file); 176 | if (mac && (file.match(mac) || 177 | file.match(/darwin-10.[0-9]*/) < mac)) { 178 | select.value = file; 179 | console.log('hit'); 180 | } 181 | } 182 | } 183 | if (os.match('source')) { 184 | select.options[select.options.length] = new Option(latest_libiio.tag_name); 185 | } 186 | select.onchange = libiio_url; 187 | libiio_url(); 188 | } 189 | 190 | function libiio_url() { 191 | var os = document.getElementById("os-select").value; 192 | var suffix = document.getElementById("type-select").value; 193 | var ver = document.getElementById("ver-select").value; 194 | var i, url; 195 | for (i = 0; i < latest_libiio.assets.length; i++) { 196 | url = latest_libiio.assets[i].browser_download_url; 197 | if (url.match(ver) && url.match(os) && url.match(suffix)) { 198 | jQuery('#libtest').attr ('href', url); 199 | document.getElementById('libtest').innerHTML = latest_libiio.assets[i].name; 200 | } 201 | } 202 | if (os.match('source')) { 203 | if (suffix.match('.tar')) { 204 | document.getElementById('libtest').innerHTML = "Source code (tar)"; 205 | jQuery('#libtest').attr ('href', latest_libiio.tarball_url); 206 | } 207 | if (suffix.match('.zip')) { 208 | document.getElementById('libtest').innerHTML = "Source code (zip)"; 209 | jQuery('#libtest').attr ('href', latest_libiio.zipball_url); 210 | } 211 | 212 | } 213 | } 214 | 215 | function CheckFrmVersion() { 216 | GetDriverurl(); 217 | var req = jQuery.getJSON("https://api.github.com/repos/analogdevicesinc/plutosdr-fw/releases/latest"); 218 | req.fail(function() { 219 | document.getElementById('versiontest').innerHTML = "Can't check right now, try manually"; 220 | }); 221 | req.done(function(response) { 222 | var VerOnGithub = response.name; 223 | var res = versionCompare("#BUILD#", VerOnGithub); 224 | var message; 225 | if (res < 0) { 226 | message = "Newer version available online (Version " + VerOnGithub + " )"; 227 | document.getElementById('versionsection').className = "download"; 228 | } else if (res > 0) { 229 | message = "Wow! Your Pluto Firmware Version #BUILD# is newer than (" + VerOnGithub + ") on Github."; 230 | document.getElementById('versionsection').className = ""; 231 | document.getElementById('plutsdr-fw-download').style.visibility = "hidden"; 232 | document.getElementById('hideupgrade').style.display = "none"; 233 | } else if (res == 0) { 234 | message = "Pluto is using the same version as latest release!"; 235 | document.getElementById('versionsection').className = ""; 236 | document.getElementById('plutsdr-fw-download').style.visibility = "hidden"; 237 | document.getElementById('hideupgrade').style.display = "none"; 238 | } else { 239 | message = "Failure in comparing version, latest upstream is " + VerOnGithub; 240 | document.getElementById('versionsection').className = ""; 241 | } 242 | document.getElementById('versiontest').innerHTML = message; 243 | document.getElementById('plutsdr-fw-download').innerHTML = "Download version " + VerOnGithub; 244 | jQuery('#plutsdr-fw-download').attr ('href', response.assets[0].browser_download_url); 245 | }); 246 | } 247 | 248 | window.onload = CheckFrmVersion; 249 | -------------------------------------------------------------------------------- /board/pluto/msd/img/yk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/yk.png -------------------------------------------------------------------------------- /board/pluto/msd/img/yt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/msd/img/yt.png -------------------------------------------------------------------------------- /board/pluto/overlay/etc/device_config: -------------------------------------------------------------------------------- 1 | #S23udc 2 | PRODUCT="PlutoSDR (ADALM-PLUTO)" 3 | USBPID=0xb673 4 | ENDPOINTS=3 5 | 6 | #S40network / S41network 7 | UDHCPD_CONF=/etc/udhcpd.conf 8 | CONF=/opt/config.txt 9 | IFAC=/etc/network/interfaces 10 | 11 | #update.sh 12 | TARGET=plutosdr 13 | FIRMWARE=/mnt/pluto.frm 14 | FRM_MAGIC="ITB PlutoSDR (ADALM-PLUTO)" 15 | 16 | -------------------------------------------------------------------------------- /board/pluto/overlay/etc/fw_env.config: -------------------------------------------------------------------------------- 1 | # MTD device name Device offset Env. size Flash sector size 2 | /dev/mtd1 0x0000 0x20000 0x20000 3 | -------------------------------------------------------------------------------- /board/pluto/overlay/etc/init.d/S10mdev: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Start mdev.... 4 | # 5 | 6 | case "$1" in 7 | start) 8 | echo -n "Starting mdev: " 9 | echo /sbin/mdev >/proc/sys/kernel/hotplug 10 | /sbin/mdev -s 11 | # coldplug modules 12 | # find /sys/ -name modalias -print0 | xargs -0 sort -u -z | xargs -0 modprobe -abq 13 | [ $? = 0 ] && echo "OK" || echo "FAIL" 14 | ;; 15 | stop) 16 | ;; 17 | restart|reload) 18 | ;; 19 | *) 20 | echo "Usage: $0 {start|stop|restart}" 21 | exit 1 22 | esac 23 | 24 | exit $? 25 | -------------------------------------------------------------------------------- /board/pluto/overlay/etc/init.d/S15watchdog: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Start watchdog 4 | # 5 | 6 | case "$1" in 7 | start) 8 | echo -n "Starting watchdog: " 9 | watchdog -t 5 -T 10 /dev/watchdog 10 | [ $? = 0 ] && echo "OK" || echo "FAIL" 11 | ;; 12 | stop) 13 | ;; 14 | restart|reload) 15 | ;; 16 | *) 17 | echo "Usage: $0 {start|stop|restart}" 18 | exit 1 19 | esac 20 | 21 | exit $? 22 | -------------------------------------------------------------------------------- /board/pluto/overlay/etc/init.d/S20urandom: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # urandom This script saves the random seed between reboots. 4 | # It is called from the boot, halt and reboot scripts. 5 | # 6 | # Version: @(#)urandom 1.33 22-Jun-1998 miquels@cistron.nl 7 | # 8 | 9 | [ -c /dev/urandom ] || exit 0 10 | #. /etc/default/rcS 11 | 12 | case "$1" in 13 | start|"") 14 | echo -n "Starting initializing random number generator: " 15 | 16 | # Load and then save 512 bytes, 17 | # which is the size of the entropy pool 18 | 19 | dmesg | sha512sum > /dev/urandom 20 | [ $? = 0 ] && echo "OK" || echo "FAIL" 21 | ;; 22 | stop) 23 | 24 | ;; 25 | *) 26 | echo "Usage: urandom {start|stop}" >&2 27 | exit 1 28 | ;; 29 | esac 30 | -------------------------------------------------------------------------------- /board/pluto/overlay/etc/init.d/S21misc: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | xo_correction() { 4 | 5 | XO_ENV_VAL=`fw_printenv -n xo_correction 2> /dev/null` 6 | if [ $? -eq 0 ]; then 7 | 8 | for dev in /sys/bus/iio/devices/*; do 9 | [ `cat ${dev}/name` == "ad9361-phy" ] && DEV_NAME=`basename ${dev}` 10 | done 11 | 12 | echo ${XO_ENV_VAL} > /sys/bus/iio/devices/${DEV_NAME}/xo_correction 13 | fi 14 | } 15 | 16 | 17 | case "$1" in 18 | start|"") 19 | echo -n "Starting miscellaneous setup: " 20 | xo_correction 21 | MAX_BS=`fw_printenv -n iio_max_block_size 2> /dev/null || echo 67108864` 22 | echo ${MAX_BS} > /sys/module/industrialio_buffer_dma/parameters/max_block_size 23 | [ $? = 0 ] && echo "OK" || echo "FAIL" 24 | ;; 25 | stop) 26 | 27 | ;; 28 | *) 29 | echo "Usage: $0 {start|stop}" >&2 30 | exit 1 31 | ;; 32 | esac 33 | -------------------------------------------------------------------------------- /board/pluto/overlay/etc/init.d/S23udc: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | source /etc/device_config 4 | 5 | CONFIGFS=/sys/kernel/config/usb_gadget 6 | GADGET=$CONFIGFS/composite_gadget 7 | IIOD_OPTS="-D -n $ENDPOINTS -F /dev/iio_ffs" 8 | UDC_HANDLE_SUSPEND=`fw_printenv -n udc_handle_suspend 2> /dev/null || echo 0` 9 | 10 | create_iiod_context_attributes() { 11 | model=$1 12 | serial=$2 13 | model_variant=$3 14 | 15 | if [ "$USBPID" == "0xb673" ]; then 16 | # ADALM-PLUTO 17 | for dev in /sys/bus/iio/devices/*; do 18 | [ `cat ${dev}/name` == "ad9361-phy" ] && DEV_NAME=`basename ${dev}` 19 | done 20 | 21 | AD936X_TYPE=$(cat /sys/bus/iio/devices/${DEV_NAME}/of_node/compatible | sed 's/adi,//g') 22 | AD936X_TYPE_CAP=$(echo $AD936X_TYPE | tr a-z A-Z) 23 | MODEL=$(echo $model | sed "s/AD936[34]/$AD936X_TYPE_CAP/") 24 | else 25 | MODEL=$model 26 | fi 27 | 28 | echo "[Context Attributes]" > /etc/libiio.ini 29 | echo "hw_model=$MODEL" >> /etc/libiio.ini 30 | 31 | if [ "$model_variant" == "n25q256a" ] 32 | then 33 | echo "hw_model_variant=0" >> /etc/libiio.ini 34 | else 35 | echo "hw_model_variant=1" >> /etc/libiio.ini 36 | fi 37 | 38 | echo -e "hw_serial=$serial\n" >> /etc/libiio.ini 39 | echo "fw_version=`grep device-fw /opt/VERSIONS | cut -d ' ' -f 2`" >> /etc/libiio.ini 40 | if [ "$USBPID" == "0xb673" ]; then 41 | echo ad9361-phy,xo_correction=`cat /sys/bus/iio/devices/${DEV_NAME}/xo_correction` >> /etc/libiio.ini 42 | echo ad9361-phy,model=$AD936X_TYPE >> /etc/libiio.ini 43 | 44 | elif [ "$USBPID" == "0xb672" ]; then 45 | cat /opt/${CALIBFILENAME} | grep ^cal,* >> /etc/libiio.ini 46 | fi 47 | } 48 | 49 | case "$1" in 50 | start) 51 | echo -n "Starting UDC Gadgets: " 52 | mount configfs -t configfs /sys/kernel/config 2> /dev/null 53 | 54 | mkdir -p $GADGET 55 | 56 | model=`cat /sys/firmware/devicetree/base/model | tr / -` 57 | model_variant=`dmesg | grep m25p80 | grep Kbytes | cut -d ' ' -f 3` 58 | 59 | serial=`dmesg | grep SPI-NOR-UniqueID` 60 | serial=${serial#*SPI-NOR-UniqueID } 61 | 62 | create_iiod_context_attributes "$model" "$serial" "$model_variant" 63 | 64 | echo $serial > /etc/serial 65 | sha1=`echo $serial | sha1sum` 66 | 67 | echo 0x0456 > $GADGET/idVendor 68 | echo $USBPID > $GADGET/idProduct 69 | 70 | mkdir -p $GADGET/strings/0x409 71 | echo "Analog Devices Inc." > $GADGET/strings/0x409/manufacturer 72 | echo $PRODUCT > $GADGET/strings/0x409/product 73 | echo $serial > $GADGET/strings/0x409/serialnumber 74 | 75 | mkdir -p $GADGET/functions/ffs.iio_ffs 76 | mkdir -p $GADGET/functions/acm.usb0 77 | mkdir -p $GADGET/functions/rndis.0 78 | mkdir -p $GADGET/functions/mass_storage.0 79 | 80 | # echo /opt/vfat.img > $GADGET/functions/mass_storage.0/lun.0/file 81 | echo Y > $GADGET/functions/mass_storage.0/lun.0/removable 82 | 83 | host_addr=`echo -n 00:E0:22; echo $sha1 | dd bs=1 count=6 2>/dev/null | hexdump -v -e '/1 ":%01c""%c"'` 84 | 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"'` 85 | 86 | echo $host_addr > $GADGET/functions/rndis.0/host_addr 87 | echo $dev_addr > $GADGET/functions/rndis.0/dev_addr 88 | 89 | mkdir -p $GADGET/configs/c.1 90 | mkdir -p $GADGET/configs/c.1/strings/0x409 91 | echo "RNDIS/MSD/ACM/IIOUSBD" > $GADGET/configs/c.1/strings/0x409/configuration 92 | echo 500 > $GADGET/configs/c.1/MaxPower 93 | 94 | ln -s $GADGET/functions/rndis.0 $GADGET/configs/c.1 95 | ln -s $GADGET/functions/mass_storage.0 $GADGET/configs/c.1 96 | ln -s $GADGET/functions/acm.usb0 $GADGET/configs/c.1 97 | ln -s $GADGET/functions/ffs.iio_ffs $GADGET/configs/c.1/ffs.iio_ffs 98 | 99 | mkdir -p /dev/iio_ffs 100 | mount iio_ffs -t functionfs /dev/iio_ffs 2> /dev/null 101 | 102 | start-stop-daemon -S -b -q -m -p /var/run/iiod.pid -x /usr/sbin/iiod -- $IIOD_OPTS 103 | sleep 0.2 104 | 105 | echo ci_hdrc.0 > $GADGET/UDC 106 | 107 | [ $? = 0 ] && echo "OK" || echo "FAIL" 108 | 109 | if [ "$UDC_HANDLE_SUSPEND" == "1" ]; then 110 | start-stop-daemon -S -b -q -m -p /var/run/udc_handle_suspend.pid -x /sbin/udc_handle_suspend.sh 111 | fi 112 | 113 | ;; 114 | stop) 115 | echo "Stopping UDC Gadgets" 116 | 117 | if [ "$UDC_HANDLE_SUSPEND" == "1" ]; then 118 | start-stop-daemon -K -q -p /var/run/udc_handle_suspend.pid 2>/dev/null 119 | fi 120 | 121 | echo "" > $GADGET/UDC 122 | start-stop-daemon -K -q -p /var/run/iiod.pid 2>/dev/null 123 | 124 | rm $GADGET/configs/c.1/rndis.0 125 | rm $GADGET/configs/c.1/mass_storage.0 126 | rm $GADGET/configs/c.1/acm.usb0 127 | rm $GADGET/configs/c.1/ffs.iio_ffs 128 | 129 | rmdir $GADGET/strings/0x409 130 | rmdir $GADGET/configs/c.1/strings/0x409 131 | rmdir $GADGET/configs/c.1 132 | 133 | rmdir $GADGET/functions/ffs.iio_ffs 134 | #rmdir $GADGET/functions/acm.usb0 135 | rmdir $GADGET/functions/rndis.0 136 | rmdir $GADGET/functions/mass_storage.0 137 | 138 | rmdir $GADGET 2> /dev/null 139 | 140 | ;; 141 | restart|reload) 142 | "$0" stop 143 | "$0" start 144 | ;; 145 | *) 146 | echo "Usage: $0 {start|stop|restart}" 147 | exit 1 148 | esac 149 | 150 | exit $? 151 | 152 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /board/pluto/overlay/etc/init.d/S40network: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Start the network.... 4 | # 5 | 6 | # Debian ifupdown needs the /run/network lock directory 7 | 8 | source /etc/device_config 9 | 10 | create_system_files () { 11 | 12 | UDHCPD_CONF=/etc/udhcpd.conf 13 | CONF=/opt/config.txt 14 | IFAC=/etc/network/interfaces 15 | 16 | HOSTNAME=`fw_printenv -n hostname 2> /dev/null || cat /etc/hostname` 17 | echo $HOSTNAME > /etc/hostname 18 | 19 | IPADDR=`fw_printenv -n ipaddr 2> /dev/null || echo 192.168.2.1` 20 | IPADDR_HOST=`fw_printenv -n ipaddr_host 2> /dev/null || echo 192.168.2.10` 21 | NETMASK=`fw_printenv -n netmask 2> /dev/null || echo 255.255.255.0` 22 | 23 | ETH_IPADDR=`fw_printenv -n ipaddr_eth 2> /dev/null` 24 | ETH_NETMASK=`fw_printenv -n netmask_eth 2> /dev/null || echo 255.255.255.0` 25 | 26 | WLAN_SSID=`fw_printenv -n ssid_wlan 2> /dev/null` 27 | WLAN_PWD=`fw_printenv -n pwd_wlan 2> /dev/null` 28 | WLAN_IPADDR=`fw_printenv -n ipaddr_wlan 2> /dev/null` 29 | 30 | XO_CORRECTION=`fw_printenv -n xo_correction 2> /dev/null` 31 | UDC_HANDLE_SUSPEND=`fw_printenv -n udc_handle_suspend 2> /dev/null || echo 0` 32 | 33 | ### /etc/udhcpd.conf ### 34 | echo "start $IPADDR_HOST" > $UDHCPD_CONF 35 | echo "interface usb0" >> $UDHCPD_CONF 36 | echo "option subnet $NETMASK" >> $UDHCPD_CONF 37 | 38 | ### /etc/network/interfaces ### 39 | echo -e "auto lo\n""iface lo inet loopback\n" > $IFAC 40 | echo -e "auto usb0\n""iface usb0 inet static" >> $IFAC 41 | echo -e "\taddress $IPADDR\n""\tnetmask $NETMASK\n" >> $IFAC 42 | 43 | echo -e "auto eth0" >> $IFAC 44 | if [ -n "$ETH_IPADDR" ] 45 | then 46 | echo -e "iface eth0 inet static" >> $IFAC 47 | echo -e "\taddress $ETH_IPADDR\n""\tnetmask $ETH_NETMASK\n" >> $IFAC 48 | else 49 | echo -e "iface eth0 inet dhcp\n" >> $IFAC 50 | fi 51 | 52 | ### /etc/wpa.conf ### 53 | if [ -n "$WLAN_SSID" ] 54 | then 55 | if [ -n "$WLAN_PWD" ] 56 | then 57 | wpa_passphrase $WLAN_SSID $WLAN_PWD > /etc/wpa.conf 58 | else 59 | echo "network={" > /etc/wpa.conf 60 | echo " ssid=\"$WLAN_SSID\"" >> /etc/wpa.conf 61 | echo " key_mgmt=NONE" >> /etc/wpa.conf 62 | echo "}" >> /etc/wpa.conf 63 | fi 64 | 65 | echo -e "auto wlan0" >> $IFAC 66 | 67 | if [ -n "$WLAN_IPADDR" ] 68 | then 69 | echo -e "iface wlan0 inet static" >> $IFAC 70 | echo -e "\taddress $WLAN_IPADDR\n""\tnetmask 255.255.255.0" >> $IFAC 71 | else 72 | echo -e "iface wlan0 inet dhcp" >> $IFAC 73 | fi 74 | echo -e "\twpa-conf /etc/wpa.conf\n" >> $IFAC 75 | fi 76 | 77 | ### /opt/config.txt ### 78 | echo "# $(cat /sys/firmware/devicetree/base/model | tr / -)"$'\r' > $CONF 79 | echo "# Device Configuration File"$'\r' >> $CONF 80 | echo "# 1. Open with an Editor"$'\r' >> $CONF 81 | echo "# 2. Edit this file"$'\r' >> $CONF 82 | echo "# 3. Save this file on the device USB drive"$'\r' >> $CONF 83 | echo "# 4. Eject the device USB Drive"$'\r' >> $CONF 84 | echo "# Doc: https://wiki.analog.com/university/tools/pluto/users/customizing"$'\r' >> $CONF 85 | echo ""$'\r'>> $CONF 86 | echo "[NETWORK]"$'\r' >> $CONF 87 | echo "hostname = $HOSTNAME"$'\r' >> $CONF 88 | echo "ipaddr = $IPADDR"$'\r' >> $CONF 89 | echo "ipaddr_host = $IPADDR_HOST"$'\r' >> $CONF 90 | echo "netmask = $NETMASK"$'\r' >> $CONF 91 | echo ""$'\r'>> $CONF 92 | echo "[WLAN]"$'\r' >> $CONF 93 | echo "ssid_wlan = $WLAN_SSID"$'\r' >> $CONF 94 | echo "pwd_wlan = $WLAN_PWD"$'\r' >> $CONF 95 | echo "ipaddr_wlan = $WLAN_IPADDR"$'\r' >> $CONF 96 | echo ""$'\r'>> $CONF 97 | echo "[USB_ETHERNET]"$'\r' >> $CONF 98 | echo "ipaddr_eth = $ETH_IPADDR"$'\r' >> $CONF 99 | echo "netmask_eth = $ETH_NETMASK"$'\r' >> $CONF 100 | echo ""$'\r'>> $CONF 101 | echo "[SYSTEM]"$'\r' >> $CONF 102 | echo "xo_correction = $XO_CORRECTION"$'\r' >> $CONF 103 | echo "udc_handle_suspend = $UDC_HANDLE_SUSPEND"$'\r' >> $CONF 104 | echo ""$'\r'>> $CONF 105 | echo "[ACTIONS]"$'\r' >> $CONF 106 | echo "diagnostic_report = 0"$'\r' >> $CONF 107 | echo "dfu = 0"$'\r' >> $CONF 108 | echo "reset = 0"$'\r' >> $CONF 109 | echo "calibrate = 0"$'\r' >> $CONF 110 | echo ""$'\r'>> $CONF 111 | 112 | ### /www/index.html ### 113 | 114 | sed -i -e "s/#IP#/$IPADDR/g" -e "s/#HOSTIP#/$IPADDR_HOST/g" -e "s/#NETMASK#/$NETMASK/g" -e "s/#HOSTNAME#/$HOSTNAME/g" -e "s/#SSID_WLAN#/$WLAN_SSID/g" -e "s/#IPADDR_WLAN#/$WLAN_IPADDR/g" -e "s/#IPADDR_ETH#/$ETH_IPADDR/g" -e "s/#NETMASK_ETH#/$ETH_NETMASK/g" /www/index.html /www/img/index_*.html 115 | 116 | } 117 | 118 | mkdir -p /run/network 119 | 120 | case "$1" in 121 | start) 122 | create_system_files 123 | printf "Starting network: " 124 | /bin/hostname -F /etc/hostname 125 | /sbin/ifup -a 2>&1 | logger 126 | [ $? = 0 ] && echo "OK" || echo "FAIL" 127 | ;; 128 | stop) 129 | printf "Stopping network: " 130 | /sbin/ifdown -a 131 | [ $? = 0 ] && echo "OK" || echo "FAIL" 132 | ;; 133 | restart|reload) 134 | "$0" stop 135 | "$0" start 136 | ;; 137 | *) 138 | echo "Usage: $0 {start|stop|restart}" 139 | exit 1 140 | esac 141 | 142 | exit $? 143 | 144 | -------------------------------------------------------------------------------- /board/pluto/overlay/etc/init.d/S41network: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Server-side demuxing by default 3 | 4 | source /etc/device_config 5 | 6 | case "$1" in 7 | start) 8 | echo -n "Starting dhcpd Daemon & httpd Server: " 9 | start-stop-daemon -S -b -q -m -p /var/run/udhcpd.pid -x /usr/sbin/udhcpd -- $UDHCPD_CONF 10 | httpd -h /www 11 | [ $? = 0 ] && echo "OK" || echo "FAIL" 12 | ;; 13 | 14 | stop) 15 | echo -n "Stopping dhcpd Daemon & httpd Server: " 16 | killall -7 httpd 17 | start-stop-daemon -K -q -p /var/run/udhcpd.pid 2>/dev/null 18 | [ $? = 0 ] && echo "OK" || echo "FAIL" 19 | ;; 20 | 21 | restart) 22 | $0 stop 23 | sleep 1 24 | $0 start 25 | ;; 26 | 27 | *) 28 | echo "Usage: $0 {start|stop|restart}" 29 | exit 1 30 | esac 31 | -------------------------------------------------------------------------------- /board/pluto/overlay/etc/init.d/S45msd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Server-side demuxing by default 3 | 4 | source /etc/device_config 5 | 6 | CONF=/opt/config.txt 7 | file=/sys/kernel/config/usb_gadget/composite_gadget/functions/mass_storage.0/lun.0/file 8 | img=/opt/vfat.img 9 | 10 | patch_html_page() { 11 | LINUX=`uname -a | tr / - | tr '\n' ';' ; echo -n $(nproc) "core(s)"` 12 | MODEL=`cat /etc/libiio.ini | grep hw_model= | cut -d '=' -f 2` 13 | SERIAL=`cat /sys/kernel/config/usb_gadget/composite_gadget/strings/0x409/serialnumber` 14 | MACHOST=`cat /sys/kernel/config/usb_gadget/composite_gadget/functions/rndis.0/host_addr` 15 | MAC=`cat /sys/kernel/config/usb_gadget/composite_gadget/functions/rndis.0/dev_addr` 16 | IIO=`iio_info 2>/dev/null | grep "Library version:"` 17 | BUILD=`grep device-fw /opt/VERSIONS | cut -d ' ' -f 2` 18 | FPGA=`grep hdl /opt/VERSIONS | cut -d ' ' -f 2` 19 | ROOTFS=`grep buildroot /opt/VERSIONS | cut -d ' ' -f 2` 20 | UBOOT=`cat /proc/cmdline | tr "=" "\n" | grep "U-Boot"` 21 | 22 | sed -i -e "s/#LINUX#/$LINUX/g" -e "s/#MODEL#/$MODEL/g" -e "s/#SERIAL#/$SERIAL/g" -e "s/#MACHOST#/$MACHOST/g" -e "s/#MAC#/$MAC/g" -e "s/#IIO#/$IIO/g" -e "s/#BUILD#/$BUILD/g" -e "s/#FPGA#/$FPGA/g" -e "s/#ROOTFS#/$ROOTFS/g" -e "s/#UBOOT#/$UBOOT/g" $1 23 | 24 | sed -i -e "s/#BUILD#/$BUILD/g" $2 /etc/motd 25 | } 26 | 27 | 28 | case "$1" in 29 | start) 30 | echo -n "Starting MSD Daemon: " 31 | patch_html_page "/www/index.html /www/img/index_*.html" /www/img/version.js 32 | losetup /dev/loop7 $img -o 512 33 | mount /dev/loop7 /mnt 34 | 35 | if [ "$TARGET" == "m2k" ]; then 36 | cp /opt/${CALIBFILENAME} /mnt 37 | md5sum /mnt/${CALIBFILENAME} > /opt/${CALIBFILENAME}.md5 38 | fi 39 | 40 | cp $CONF /mnt 41 | md5sum /mnt/config.txt > /opt/config.md5 42 | 43 | cp -a /www/* /mnt/ 44 | mv /mnt/index.html /mnt/info.html 45 | sed -i -e "s/..\/index.html/..\/info.html/g" /mnt/img/index_*.html 46 | umount /mnt 47 | echo $img > $file 48 | 49 | start-stop-daemon -S -b -q -m -p /var/run/update.pid -x /bin/sh -- /sbin/update.sh 50 | [ $? = 0 ] && echo "OK" || echo "FAIL" 51 | ;; 52 | 53 | stop) 54 | echo -n "Stopping MSD Daemon: " 55 | start-stop-daemon -K -q -p /var/run/update.pid 2>/dev/null 56 | [ $? = 0 ] && echo "OK" || echo "FAIL" 57 | ;; 58 | 59 | restart) 60 | $0 stop 61 | sleep 1 62 | $0 start 63 | ;; 64 | 65 | *) 66 | echo "Usage: $0 {start|stop|restart}" 67 | exit 1 68 | esac 69 | -------------------------------------------------------------------------------- /board/pluto/overlay/etc/input-event-daemon.conf: -------------------------------------------------------------------------------- 1 | # 2 | # /etc/input-event-daemon.conf 3 | # 4 | 5 | [Global] 6 | listen = /dev/input/event0 7 | 8 | [Keys] 9 | BTN_0 = ACTION=remove_all /lib/mdev/automounter.sh 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /board/pluto/overlay/etc/mdev.conf: -------------------------------------------------------------------------------- 1 | # block devices 2 | sd[a-z] root:root 660 */lib/mdev/automounter.sh 3 | sd[a-z][0-9] root:root 660 */lib/mdev/automounter.sh 4 | # net devices 5 | wlan[0-9] root:root 660 */lib/mdev/ifupdown.sh 6 | usb[0-9] root:root 660 */lib/mdev/ifupdown.sh 7 | eth[0-9] root:root 660 */lib/mdev/ifupdown.sh 8 | -------------------------------------------------------------------------------- /board/pluto/overlay/etc/motd: -------------------------------------------------------------------------------- 1 | Welcome to: 2 | ______ _ _ _________________ 3 | | ___ \ | | | / ___| _ \ ___ \ 4 | | |_/ / |_ _| |_ ___ \ `--.| | | | |_/ / 5 | | __/| | | | | __/ _ \ `--. \ | | | / 6 | | | | | |_| | || (_) /\__/ / |/ /| |\ \ 7 | \_| |_|\__,_|\__\___/\____/|___/ \_| \_| 8 | 9 | #BUILD# 10 | http://wiki.analog.com/university/tools/pluto 11 | -------------------------------------------------------------------------------- /board/pluto/overlay/etc/network/if-down.d/wpasupplicant: -------------------------------------------------------------------------------- 1 | ../../wpa_supplicant/ifupdown.sh -------------------------------------------------------------------------------- /board/pluto/overlay/etc/network/if-post-down.d/wpasupplicant: -------------------------------------------------------------------------------- 1 | ../../wpa_supplicant/ifupdown.sh -------------------------------------------------------------------------------- /board/pluto/overlay/etc/network/if-pre-up.d/wpasupplicant: -------------------------------------------------------------------------------- 1 | ../../wpa_supplicant/ifupdown.sh -------------------------------------------------------------------------------- /board/pluto/overlay/etc/network/if-up.d/wpasupplicant: -------------------------------------------------------------------------------- 1 | ../../wpa_supplicant/ifupdown.sh -------------------------------------------------------------------------------- /board/pluto/overlay/etc/wpa_supplicant/action_wpa.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Action script to enable/disable wpa-roam interfaces in reaction to 4 | # ifplugd events. 5 | # 6 | # Copyright: Copyright (c) 2008-2010, Kel Modderman 7 | # License: GPL-2 8 | # 9 | 10 | PATH=/sbin:/usr/sbin:/bin:/usr/bin 11 | 12 | if [ ! -x /sbin/wpa_action ]; then 13 | exit 0 14 | fi 15 | 16 | # ifplugd(8) - 17 | # 18 | # If an ifplugd managed interface is brought up, disconnect any 19 | # wpa-roam managed interfaces so that only one "roaming" interface 20 | # remains active on the system. 21 | 22 | IFPLUGD_IFACE="${1}" 23 | 24 | case "${2}" in 25 | up) 26 | COMMAND=disconnect 27 | ;; 28 | down) 29 | COMMAND=reconnect 30 | ;; 31 | *) 32 | echo "$0: unknown arguments: ${@}" >&2 33 | exit 1 34 | ;; 35 | esac 36 | 37 | for CTRL in /run/wpa_supplicant/*; do 38 | [ -S "${CTRL}" ] || continue 39 | 40 | IFACE="${CTRL#/run/wpa_supplicant/}" 41 | 42 | # skip if ifplugd is managing this interface 43 | if [ "${IFPLUGD_IFACE}" = "${IFACE}" ]; then 44 | continue 45 | fi 46 | 47 | if wpa_action "${IFACE}" check; then 48 | wpa_cli -i "${IFACE}" "${COMMAND}" 49 | fi 50 | done 51 | -------------------------------------------------------------------------------- /board/pluto/overlay/etc/wpa_supplicant/ifupdown.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ##################################################################### 4 | ## Purpose 5 | # This file is executed by ifupdown in pre-up, post-up, pre-down and 6 | # post-down phases of network interface configuration. It allows 7 | # ifup(8), and ifdown(8) to manage wpa_supplicant(8) and wpa_cli(8) 8 | # processes running in daemon mode. 9 | # 10 | # /etc/wpa_supplicant/functions.sh is sourced by this file. 11 | # 12 | # This file is provided by the wpasupplicant package. 13 | 14 | ##################################################################### 15 | # Copyright (C) 2006 - 2009 Debian/Ubuntu wpasupplicant Maintainers 16 | # 17 | # 18 | # This program is free software; you can redistribute it and/or 19 | # modify it under the terms of the GNU General Public License 20 | # as published by the Free Software Foundation; either version 2 21 | # of the License, or (at your option) any later version. 22 | # 23 | # This program is distributed in the hope that it will be useful, 24 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 25 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 | # GNU General Public License for more details. 27 | # 28 | # On Debian GNU/Linux systems, the text of the GPL license, 29 | # version 2, can be found in /usr/share/common-licenses/GPL-2. 30 | 31 | if [ -n "$IF_WPA_MAINT_DEBUG" ]; then 32 | set -x 33 | fi 34 | 35 | # quit if we're called for the loopback 36 | if [ "$IFACE" = lo ]; then 37 | exit 0 38 | fi 39 | 40 | # allow wpa_supplicant interface to be specified via wpa-iface 41 | # useful for starting wpa_supplicant on one interface of a bridge 42 | if [ -n "$IF_WPA_IFACE" ]; then 43 | WPA_IFACE="$IF_WPA_IFACE" 44 | else 45 | WPA_IFACE="$IFACE" 46 | fi 47 | 48 | # source functions 49 | if [ -f /etc/wpa_supplicant/functions.sh ]; then 50 | . /etc/wpa_supplicant/functions.sh 51 | else 52 | exit 0 53 | fi 54 | 55 | # quit if executables are not installed 56 | if [ ! -x "$WPA_SUP_BIN" ] || [ ! -x "$WPA_CLI_BIN" ]; then 57 | exit 0 58 | fi 59 | 60 | do_start () { 61 | if test_wpa_cli; then 62 | # if wpa_action is active for this IFACE, do nothing 63 | ifupdown_locked && exit 0 64 | 65 | # if the administrator is calling ifup, say something useful 66 | if [ "$PHASE" = "pre-up" ]; then 67 | wpa_msg stderr "wpa_action is managing ifup/ifdown state of $WPA_IFACE" 68 | wpa_msg stderr "execute \`ifdown --force $WPA_IFACE' to stop wpa_action" 69 | fi 70 | exit 1 71 | elif ! set | grep -q "^IF_WPA"; then 72 | # no wpa- option defined for IFACE, do nothing 73 | exit 0 74 | fi 75 | 76 | # ensure stale ifupdown_lock marker is purged 77 | ifupdown_unlock 78 | 79 | # preliminary sanity checks for roaming daemon 80 | if [ -n "$IF_WPA_ROAM" ]; then 81 | if [ "$METHOD" != "manual" ]; then 82 | wpa_msg stderr "wpa-roam can only be used with the \"manual\" inet METHOD" 83 | exit 1 84 | fi 85 | if [ -n "$IF_WPA_MAPPING_SCRIPT" ]; then 86 | if ! type "$IF_WPA_MAPPING_SCRIPT" >/dev/null; then 87 | wpa_msg stderr "wpa-mapping-script \"$IF_WPA_MAPPING_SCRIPT\" is not valid" 88 | exit 1 89 | fi 90 | fi 91 | if [ -n "$IF_WPA_MAPPING_SCRIPT_PRIORITY" ] && [ -z "$IF_WPA_MAPPING_SCRIPT" ]; then 92 | wpa_msg stderr "\"wpa-mapping-script-priority 1\" is invalid without a wpa-mapping-script" 93 | exit 1 94 | fi 95 | IF_WPA_CONF="$IF_WPA_ROAM" 96 | WPA_ACTION_SCRIPT="/sbin/wpa_action" 97 | fi 98 | 99 | # master function; determines if ifupdown.sh should do something or not 100 | if [ -n "$IF_WPA_CONF" ] && [ "$IF_WPA_CONF" != "managed" ]; then 101 | if [ ! -s "$IF_WPA_CONF" ]; then 102 | wpa_msg stderr "cannot read contents of $IF_WPA_CONF" 103 | exit 1 104 | fi 105 | WPA_SUP_CONF_CTRL_DIR=$(sed -n -e 's/[[:space:]]*#.*//g' -e 's/[[:space:]]\+.*$//g' \ 106 | -e 's/^ctrl_interface=\(DIR=\)\?\(.*\)/\2/p' "$IF_WPA_CONF") 107 | if [ -n "$WPA_SUP_CONF_CTRL_DIR" ]; then 108 | WPA_CTRL_DIR="$WPA_SUP_CONF_CTRL_DIR" 109 | WPA_SUP_CONF="-c $IF_WPA_CONF" 110 | else 111 | # specify the default ctrl_interface since none was defined in 112 | # the given IF_WPA_CONF 113 | WPA_SUP_CONF="-c $IF_WPA_CONF -C $WPA_CTRL_DIR" 114 | fi 115 | else 116 | # specify the default ctrl_interface 117 | WPA_SUP_CONF="-C $WPA_CTRL_DIR" 118 | fi 119 | } 120 | 121 | do_stop () { 122 | if test_wpa_cli; then 123 | # if wpa_action is active for this IFACE and calling ifdown, 124 | # do nothing 125 | ifupdown_locked && exit 0 126 | elif test_wpa_supplicant; then 127 | # wpa_supplicant process exists for this IFACE, but wpa_cli 128 | # process does not. Allow stop mode to kill this process. 129 | : 130 | else 131 | exit 0 132 | fi 133 | } 134 | 135 | case "$MODE" in 136 | start) 137 | do_start 138 | case "$PHASE" in 139 | pre-up) 140 | kill_wpa_supplicant 141 | init_wpa_supplicant || exit 1 142 | conf_wpa_supplicant || { kill_wpa_supplicant; exit 1; } 143 | ;; 144 | post-up) 145 | init_wpa_cli || { kill_wpa_supplicant; exit 1; } 146 | ;; 147 | esac 148 | ;; 149 | 150 | stop) 151 | do_stop 152 | case "$PHASE" in 153 | pre-down) 154 | kill_wpa_cli 155 | ;; 156 | post-down) 157 | kill_wpa_supplicant 158 | ;; 159 | *) 160 | wpa_msg stderr "unknown phase: \"$PHASE\"" 161 | exit 1 162 | ;; 163 | esac 164 | ;; 165 | 166 | *) 167 | wpa_msg stderr "unknown mode: \"$MODE\"" 168 | exit 1 169 | ;; 170 | esac 171 | 172 | exit 0 173 | -------------------------------------------------------------------------------- /board/pluto/overlay/lib/mdev/automounter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | destdir=/media 4 | 5 | my_umount() 6 | { 7 | if grep -qs "^/dev/$1 " /proc/mounts ; then 8 | umount "${destdir}/$1"; 9 | echo heartbeat > /sys/class/leds/led0:green/trigger 10 | fi 11 | 12 | [ -d "${destdir}/$1" ] && rmdir "${destdir}/$1" 13 | } 14 | 15 | my_mount() 16 | { 17 | mkdir -p "${destdir}/$1" || exit 1 18 | 19 | if ! mount -t auto -o sync "/dev/$1" "${destdir}/$1"; then 20 | # failed to mount, clean up mountpoint 21 | rmdir "${destdir}/$1" 22 | exit 1 23 | fi 24 | 25 | echo default-on > /sys/class/leds/led0:green/trigger 26 | 27 | for i in ${destdir}/$1/runme??* ;do 28 | 29 | # Ignore dangling symlinks (if any). 30 | [ ! -f "$i" ] && continue 31 | 32 | case "$i" in 33 | *.sh) 34 | # Source shell script for speed. 35 | ( 36 | trap - INT QUIT TSTP 37 | set start 38 | . $i 39 | ) 40 | ;; 41 | *) 42 | # No sh extension, so fork subprocess. 43 | $i start 44 | ;; 45 | esac 46 | done 47 | } 48 | 49 | case "${ACTION}" in 50 | add|"") 51 | my_umount ${MDEV} 52 | my_mount ${MDEV} 53 | ;; 54 | remove) 55 | my_umount ${MDEV} 56 | ;; 57 | remove_all) 58 | for i in ${destdir}/??* 59 | do 60 | my_umount $(basename $i) 61 | done 62 | esac 63 | -------------------------------------------------------------------------------- /board/pluto/overlay/lib/mdev/ifupdown.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | case "${ACTION}" in 4 | add|"") 5 | ifconfig ${MDEV} up 6 | ifup ${MDEV} 7 | echo $(ip -f inet -o addr show ${MDEV}|cut -d\ -f 7 | cut -d/ -f 1) > /opt/ipaddr-${MDEV} 8 | ;; 9 | remove) 10 | ifdown ${MDEV} 11 | ;; 12 | esac 13 | -------------------------------------------------------------------------------- /board/pluto/overlay/opt/VERSIONS: -------------------------------------------------------------------------------- 1 | device-fw v0.29-1-g2e94 2 | hdl 2018_r1-1-gd79ca2 3 | buildroot v0.20-8405-g04dce 4 | linux xcomm_zynq-2013-04-19-320193-g2398d50 5 | u-boot-xlnx v0.20-PlutoSDR-10-gf5f001 6 | -------------------------------------------------------------------------------- /board/pluto/overlay/sbin/udc_handle_suspend.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | source /etc/device_config 4 | 5 | DEV_NAME= 6 | 7 | for dev in /sys/bus/iio/devices/*; do 8 | [ `cat ${dev}/name` == "ad9361-phy" ] && DEV_NAME=`basename ${dev}` 9 | done 10 | 11 | prev_ensm_mode=`cat /sys/bus/iio/devices/${DEV_NAME}/ensm_mode` 12 | 13 | while [ 1 ] 14 | do 15 | 16 | state=`/sbin/poll_sysfs /sys/class/udc/ci_hdrc.0/state` 17 | case "$state" in 18 | suspended) 19 | prev_ensm_mode=`cat /sys/bus/iio/devices/${DEV_NAME}/ensm_mode` 20 | echo sleep > /sys/bus/iio/devices/${DEV_NAME}/ensm_mode 21 | echo none > /sys/class/leds/led0:green/trigger 22 | echo "UDC: $state: $prev_ensm_mode -> sleep" | logger 23 | ;; 24 | *) 25 | current_ensm_mode=`cat /sys/bus/iio/devices/${DEV_NAME}/ensm_mode` 26 | echo heartbeat > /sys/class/leds/led0:green/trigger 27 | if [ "$current_ensm_mode" != "$prev_ensm_mode" ] 28 | then 29 | echo $prev_ensm_mode > /sys/bus/iio/devices/${DEV_NAME}/ensm_mode 30 | fi 31 | echo "UDC: $state: $current_ensm_mode -> $prev_ensm_mode" | logger 32 | ;; 33 | esac 34 | done 35 | -------------------------------------------------------------------------------- /board/pluto/overlay/sbin/update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | source /etc/device_config 4 | 5 | file=/sys/kernel/config/usb_gadget/composite_gadget/functions/mass_storage.0/lun.0/file 6 | bootimage=/mnt/boot.frm 7 | conf=/mnt/config.txt 8 | img=/opt/vfat.img 9 | 10 | ini_parser() { 11 | FILE=$1 12 | SECTION=$2 13 | eval `sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \ 14 | -e 's/[#;\`].*$//' \ 15 | -e 's/[[:space:]]*$//' \ 16 | -e 's/^[[:space:]]*//' \ 17 | -e "s/^\(.*\)=\([^\"']*\)$/\1=\"\2\"/" \ 18 | < $FILE \ 19 | | sed -n -e "/^\[$SECTION\]/,/^\s*\[/{/^[^;].*\=.*/p;}"` 20 | } 21 | 22 | reset() { 23 | echo "REBOOT/RESET using Watchdog timeout" 24 | flash_indication_off 25 | sync 26 | device_reboot reset 27 | sleep 10 28 | } 29 | 30 | dfu() { 31 | echo "Entering DFU mode using SW Reset" 32 | flash_indication_off 33 | sync 34 | device_reboot sf 35 | } 36 | 37 | flash_indication_on() { 38 | echo timer > /sys/class/leds/led0:green/trigger 39 | echo 40 > /sys/class/leds/led0:green/delay_off 40 | echo 40 > /sys/class/leds/led0:green/delay_on 41 | } 42 | 43 | flash_indication_off() { 44 | echo heartbeat > /sys/class/leds/led0:green/trigger 45 | } 46 | 47 | make_diagnostic_report () { 48 | FILE=$1 49 | cat /opt/VERSIONS /etc/os-release /var/log/messages /proc/cpuinfo /proc/interrupts /proc/iomem /proc/meminfo /proc/cmdline /sys/kernel/debug/clk/clk_summary > ${FILE} 50 | grep -r "" /sys/kernel/debug/regmap/ >> ${FILE} 2>&1 51 | iio_info >> ${FILE} 2>&1 52 | ifconfig -a >> ${FILE} 2>&1 53 | mount >> ${FILE} 2>&1 54 | top -b -n1 >> ${FILE} 2>&1 55 | fw_printenv >> ${FILE} 2>&1 56 | unix2dos ${FILE} 57 | } 58 | 59 | calibrate () { 60 | /usr/sbin/ad936x_ref_cal -e $1 ad9361-phy 61 | if [ $? -eq 0 ]; then 62 | 63 | for dev in /sys/bus/iio/devices/*; do 64 | [ `cat ${dev}/name` == "ad9361-phy" ] && DEV_NAME=`basename ${dev}` 65 | done 66 | NEW_XO=`cat /sys/bus/iio/devices/${DEV_NAME}/xo_correction` 67 | flash_indication_on 68 | fw_setenv xo_correction $NEW_XO 69 | flash_indication_off 70 | 71 | sed -i -e "s/^xo_correction .*$/xo_correction = $NEW_XO/" -e "s/^calibrate .*$/calibrate = 0/" $conf 72 | else 73 | sed -i -e "s/^calibrate .*$/calibrate = 0/" $conf 74 | fi 75 | } 76 | 77 | process_ini() { 78 | FILE=$1 79 | 80 | ini_parser $FILE "NETWORK" 81 | ini_parser $FILE "WLAN" 82 | ini_parser $FILE "SYSTEM" 83 | ini_parser $FILE "USB_ETHERNET" 84 | 85 | rm -f /mnt/SUCCESS_ENV_UPDATE /mnt/FAILED_INVALID_UBOOT_ENV /mnt/CAL_STATUS 86 | 87 | 88 | fw_printenv qspiboot 89 | if [ $? -eq 0 ]; then 90 | flash_indication_on 91 | echo "hostname $hostname" > /opt/fw_set.tmp 92 | echo "ipaddr $ipaddr" >> /opt/fw_set.tmp 93 | echo "ipaddr_host $ipaddr_host" >> /opt/fw_set.tmp 94 | echo "netmask $netmask" >> /opt/fw_set.tmp 95 | echo "ssid_wlan $ssid_wlan" >> /opt/fw_set.tmp 96 | echo "ipaddr_wlan $ipaddr_wlan" >> /opt/fw_set.tmp 97 | echo "pwd_wlan $pwd_wlan" >> /opt/fw_set.tmp 98 | echo "xo_correction $xo_correction" >> /opt/fw_set.tmp 99 | echo "udc_handle_suspend $udc_handle_suspend" >> /opt/fw_set.tmp 100 | echo "ipaddr_eth $ipaddr_eth" >> /opt/fw_set.tmp 101 | echo "netmask_eth $netmask_eth" >> /opt/fw_set.tmp 102 | fw_setenv -s /opt/fw_set.tmp 103 | rm /opt/fw_set.tmp 104 | flash_indication_off 105 | touch /mnt/SUCCESS_ENV_UPDATE 106 | else 107 | touch /mnt/FAILED_INVALID_UBOOT_ENV 108 | fi 109 | 110 | ini_parser $FILE "ACTIONS" 111 | 112 | if [ "$reset" == "1" ] 113 | then 114 | reset 115 | fi 116 | 117 | if [ "$dfu" == "1" ] 118 | then 119 | dfu 120 | fi 121 | 122 | if [ "$diagnostic_report" == "1" ] 123 | then 124 | make_diagnostic_report /mnt/diagnostic_report 125 | fi 126 | 127 | if [ "$calibrate" -gt "70000000" ] 128 | then 129 | calibrate $calibrate > /mnt/CAL_STATUS 130 | fi 131 | 132 | md5sum $FILE > /opt/config.md5 133 | } 134 | 135 | handle_boot_frm () { 136 | FILE="$1" 137 | rm -f /mnt/BOOT_SUCCESS /mnt/BOOT_FAILED /mnt/FAILED_MTD_PARTITION_ERROR /mnt/FAILED_BOOT_CHSUM_ERROR 138 | head -3 /proc/mtd | sed 's/00010000/00001000/g' > /opt/mtd 139 | 140 | md5=`tail -c 33 ${FILE}` 141 | head -c -33 ${FILE} > /opt/boot_and_env_and_mtdinfo.bin 142 | 143 | tail -c 1024 /opt/boot_and_env_and_mtdinfo.bin | head -3 > /opt/mtd-info.txt 144 | head -c -1024 /opt/boot_and_env_and_mtdinfo.bin > /opt/boot_and_env.bin 145 | 146 | tail -c 131072 /opt/boot_and_env.bin > /opt/u-boot-env.bin 147 | head -c -131072 /opt/boot_and_env.bin > /opt/boot.bin 148 | 149 | frm=`md5sum /opt/boot_and_env_and_mtdinfo.bin | cut -d ' ' -f 1` 150 | 151 | if [ "$frm" = "$md5" ] 152 | then 153 | diff -w /opt/mtd /opt/mtd-info.txt 154 | if [ $? -eq 0 ]; then 155 | flash_indication_on 156 | dd if=/opt/boot.bin of=/dev/mtdblock0 bs=64k && dd if=/opt/u-boot-env.bin of=/dev/mtdblock1 bs=64k && do_reset=1 && touch /mnt/BOOT_SUCCESS || touch /mnt/BOOT_FAILED 157 | flash_indication_off 158 | else 159 | cat /opt/mtd /opt/mtd-info.txt > /mnt/FAILED_MTD_PARTITION_ERROR 160 | do_reset=0 161 | fi 162 | else 163 | echo $md5 $frm > /mnt/FAILED_BOOT_CHSUM_ERROR 164 | do_reset=0 165 | fi 166 | 167 | rm -f ${FILE} /opt/boot_and_env_and_mtdinfo.bin /opt/mtd-info.txt /opt/boot_and_env.bin /opt/u-boot-env.bin /opt/boot.bin /opt/mtd 168 | } 169 | 170 | 171 | 172 | handle_frimware_frm () { 173 | FILE="$1" 174 | MAGIC="$2" 175 | rm -f /mnt/SUCCESS /mnt/FAILED /mnt/FAILED_FIRMWARE_CHSUM_ERROR 176 | md5=`tail -c 33 ${FILE}` 177 | head -c -33 ${FILE} > /opt/firmware.frm 178 | FRM_SIZE=`cat /opt/firmware.frm | wc -c | xargs printf "%X\n"` 179 | frm=`md5sum /opt/firmware.frm | cut -d ' ' -f 1` 180 | if [ "$frm" = "$md5" ] 181 | then 182 | flash_indication_on 183 | grep -q "${MAGIC}" /opt/firmware.frm && dd if=/opt/firmware.frm of=/dev/mtdblock3 bs=64k && fw_setenv fit_size ${FRM_SIZE} && do_reset=1 && touch /mnt/SUCCESS || touch /mnt/FAILED 184 | flash_indication_off 185 | else 186 | echo $frm $md5 > /mnt/FAILED_FIRMWARE_CHSUM_ERROR 187 | do_reset=0 188 | fi 189 | 190 | rm -f ${FILE} /opt/firmware.frm 191 | sync 192 | } 193 | 194 | while [ 1 ] 195 | do 196 | if [[ -r ${file} ]] 197 | then 198 | lun=`cat $file` 199 | if [ ${#lun} -eq 0 ] 200 | then 201 | do_reset=0 202 | losetup /dev/loop7 $img -o 512 203 | mount /dev/loop7 /mnt 204 | 205 | if [[ -s /mnt/$TARGET-fw-*.zip ]] 206 | then 207 | mv /mnt/$TARGET-fw-*.zip /opt/ 208 | unzip -o /opt/$TARGET-fw-*.zip *.frm -d /mnt 209 | rm /opt/$TARGET-fw-*.zip 210 | fi 211 | 212 | if [[ -s ${FIRMWARE} ]] 213 | then 214 | handle_frimware_frm "${FIRMWARE}" "${FRM_MAGIC}" 215 | fi 216 | 217 | if [[ -s ${bootimage} ]] 218 | then 219 | handle_boot_frm "${bootimage}" 220 | fi 221 | 222 | md5sum -c /opt/config.md5 || process_ini $conf 223 | 224 | if [ "$TARGET" == "m2k" ]; then 225 | if [[ -s /mnt/${CALIBFILENAME} ]]; then 226 | md5sum -c /opt/${CALIBFILENAME}.md5 227 | if [ $? -ne 0 ]; then 228 | cp /mnt/${CALIBFILENAME} /mnt_jffs2/${CALIBFILENAME} && do_reset=1 229 | fi 230 | 231 | else 232 | rm /mnt_jffs2/${CALIBFILENAME} && do_reset=1 233 | fi 234 | 235 | if [[ -s /mnt/${CALIBFILENAME_FACTORY} ]]; then 236 | if [[ ! -s /mnt_jffs2/${CALIBFILENAME_FACTORY} ]]; then 237 | cp /mnt/${CALIBFILENAME_FACTORY} /mnt_jffs2/${CALIBFILENAME_FACTORY} 238 | do_reset=1 239 | fi 240 | fi 241 | fi 242 | 243 | if [[ $do_reset = 1 ]] 244 | then 245 | reset 246 | fi 247 | 248 | cp /opt/ipaddr-* /mnt 2>/dev/null 249 | 250 | umount /mnt 251 | #losetup -d /dev/loop7 252 | echo $img > $file 253 | flash_indication_off 254 | sleep 1 255 | fi 256 | fi 257 | 258 | sleep 1 259 | 260 | done 261 | 262 | exit 1 263 | -------------------------------------------------------------------------------- /board/pluto/overlay/sbin/update_frm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #set -x 4 | 5 | source /etc/device_config 6 | 7 | FRM_FILE="$1" 8 | 9 | flash_indication_on() { 10 | echo timer > /sys/class/leds/led0:green/trigger 11 | echo 40 > /sys/class/leds/led0:green/delay_off 12 | echo 40 > /sys/class/leds/led0:green/delay_on 13 | } 14 | 15 | flash_indication_off() { 16 | echo heartbeat > /sys/class/leds/led0:green/trigger 17 | } 18 | 19 | handle_frimware_frm () { 20 | FILE="$1" 21 | MAGIC="$2" 22 | md5=`tail -c 33 ${FILE}` 23 | head -c -33 ${FILE} > /opt/firmware.frm 24 | FRM_SIZE=`cat /opt/firmware.frm | wc -c | xargs printf "%X\n"` 25 | frm=`md5sum /opt/firmware.frm | cut -d ' ' -f 1` 26 | if [ "$frm" = "$md5" ] 27 | then 28 | flash_indication_on 29 | grep -q "${MAGIC}" /opt/firmware.frm && dd if=/opt/firmware.frm of=/dev/mtdblock3 bs=64k && fw_setenv fit_size ${FRM_SIZE} && echo "Done" || echo "Failed" 30 | flash_indication_off 31 | rm -f /opt/firmware.frm 32 | sync 33 | exit 0 34 | else 35 | rm -f /opt/firmware.frm 36 | echo Failed Checksum error: $frm $md5 37 | exit 1 38 | fi 39 | } 40 | 41 | 42 | 43 | if [[ -f ${FRM_FILE} ]] && [[ ${FRM_FILE: -4} == ".frm" ]] && [[ -s ${FRM_FILE} ]] 44 | then 45 | handle_frimware_frm "${FRM_FILE}" "${FRM_MAGIC}" 46 | else 47 | echo "Failed" 48 | exit 1 49 | fi 50 | -------------------------------------------------------------------------------- /board/pluto/overlay/usr/sbin/device_reboot: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | case "$1" in 4 | ram) 5 | cause=7 6 | ;; 7 | sf) 8 | cause=3 9 | ;; 10 | verbose) 11 | cause=6 12 | ;; 13 | break) 14 | cause=2 15 | ;; 16 | reset) 17 | cause=0 18 | ;; 19 | 20 | *) 21 | echo "Usage: $0 {ram|sf|reset|verbose|break}" 22 | echo " sf : Reboot and enter Serial Flash DFU mode" 23 | echo " ram : Reboot and enter RAM DFU mode" 24 | echo " reset : Reboot" 25 | echo " verbose: Reboot and start serial console Verbose" 26 | echo " break : Reboot and HALT in u-boot" 27 | exit 1 28 | esac 29 | 30 | echo $cause > /sys/kernel/debug/zynq_rst/code && /sbin/reboot 31 | 32 | exit 0 33 | -------------------------------------------------------------------------------- /board/pluto/overlay/usr/sbin/pluto_reboot: -------------------------------------------------------------------------------- 1 | device_reboot -------------------------------------------------------------------------------- /board/pluto/overlay/usr/sbin/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 | 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 and pluto only" 83 | exit 84 | fi 85 | 86 | GPIO_BASE=$(find_zynq_base_gpio) 87 | 88 | cd /sys/class/gpio 89 | 90 | if [ $GPIO_BASE -ge 0 ] 91 | then 92 | GPIO_ENABLE=`expr $GPIO_BASE + 69` 93 | GPIO_TXNRX=`expr $GPIO_BASE + 70` 94 | #Export the CTRL_IN GPIOs 95 | echo $GPIO_ENABLE > export 2> /dev/null 96 | echo $GPIO_TXNRX > export 2> /dev/null 97 | else 98 | echo ERROR: Wrong board? 99 | exit 100 | fi 101 | 102 | ENABLE=gpio${GPIO_ENABLE}/direction 103 | TXNRX=gpio${GPIO_TXNRX}/direction 104 | 105 | echo low > $ENABLE 106 | echo low > $TXNRX 107 | 108 | echo Press CTRL-C to exit 109 | 110 | case "$ensm_modes" in 111 | *fdd*) 112 | echo "Type: 0 for FDD Pin Control Mode" 113 | echo "Type: 1 for FDD Independant Pin Control Mode" 114 | 115 | read mode 116 | 117 | if [ $mode = "1" ]; then 118 | echo pinctrl_fdd_indep > $phy_path/ensm_mode #Enable Pincontrol Mode 119 | fdd_independant_mode_pin_control_test 120 | else 121 | echo pinctrl > $phy_path/ensm_mode #Enable Pincontrol Mode 122 | fdd_pin_control_test 123 | fi 124 | 125 | ;; 126 | *rx*) 127 | echo pinctrl > $phy_path/ensm_mode #Enable Pincontrol Mode 128 | tdd_pin_control_test 129 | ;; 130 | esac 131 | -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/ADI_Logo_AWP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/ADI_Logo_AWP.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/GNURadio_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/GNURadio_logo.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/PlutoSDR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/PlutoSDR.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/SDR-Sharp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/SDR-Sharp.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/download.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/ez.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/ez.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/favicon.ico -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/fb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/fb.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/gp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/gp.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/ig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/ig.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/li.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/li.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/mathworks_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/mathworks_logo.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/osc128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/osc128.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/prof_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/prof_blue.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/sdrangel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/sdrangel.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/ss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/ss.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/style.css: -------------------------------------------------------------------------------- 1 | body{ 2 | font-family: "Helvetica Neue", sans-serif; 3 | font-size: 16px; 4 | font-weight: normal; 5 | line-height: 1.3em; 6 | color: #636363; 7 | padding: 0 20px 0; 8 | max-width: 1024px; 9 | margin: auto; 10 | } 11 | hr{ 12 | color: #ccc; 13 | margin: 10px 0 20px; 14 | } 15 | h1, h3{ 16 | font-family: "Arial Regular", sans-serif; 17 | font-weight: bold; 18 | margin-bottom:0; 19 | } 20 | h1{ 21 | font-size: 32px; 22 | color: #1e4056; 23 | margin-bottom: 40px; 24 | } 25 | h3{ 26 | font-size: 24px; 27 | } 28 | header{ 29 | margin-bottom: 20px; 30 | } 31 | header img{ 32 | margin-top: 10px; 33 | width: 175px; 34 | } 35 | nav{ 36 | margin-bottom: 20px; 37 | } 38 | ul{ 39 | padding-left: 20px; 40 | } 41 | table{ 42 | width: 100%; 43 | } 44 | th{ 45 | background-color: #33b3ca; 46 | color: #fff; 47 | font-weight: normal; 48 | padding: 10px; 49 | text-align: left; 50 | } 51 | td{ 52 | background-color: #f5f5f5; 53 | font-size: 14px; 54 | padding: 5px 10px; 55 | } 56 | th:first-of-type, 57 | td:first-of-type{ 58 | width: 25%; 59 | font-weight: bold; 60 | } 61 | #versiontest{ 62 | color: #27B34F; 63 | } 64 | a{ 65 | color: #33b3ca; 66 | text-decoration: none; 67 | } 68 | .button{ 69 | background-color: #33b3ca; 70 | border-radius: 15px; 71 | color: #ffffff; 72 | margin: 15px 10px 15px 10px; 73 | padding: 5px 15px; 74 | cursor: pointer; 75 | } 76 | .dropdown { 77 | position: relative; 78 | text-align: left; 79 | display: inline-block; 80 | } 81 | .dropdown-content { 82 | display: none; 83 | position: absolute; 84 | background-color: #f9f9f9; 85 | min-width: 200px; 86 | border-radius: 15px; 87 | box-shadow: 0px 8px 24px 0px rgba(0,0,0,0.2); 88 | padding: 10px 10px; 89 | z-index: 1; 90 | } 91 | .dropdown:hover .dropdown-content { 92 | display: block; 93 | } 94 | .download{ 95 | background-image: url("download.png"); 96 | padding: 1em 1em .5em 70px; 97 | margin-bottom: 1.5em; 98 | min-height: 68px; 99 | background-position: 10px 50%; 100 | background-repeat: no-repeat; 101 | color: #000; 102 | overflow: hidden; 103 | box-sizing: border-box; 104 | background-color: #d6efc2; 105 | border-radius: 1.4em; 106 | } 107 | .quicklinks{ 108 | float: right; 109 | -webkit-column-count: 2; /* Chrome, Safari, Opera */ 110 | -moz-column-count: 2; /* Firefox */ 111 | column-count: 2; 112 | -webkit-column-gap: 20px; /* Chrome, Safari, Opera */ 113 | -moz-column-gap: 20px; /* Firefox */ 114 | column-gap: 20px; 115 | -webkit-column-rule: 1px solid lightblue; /* Chrome, Safari, Opera */ 116 | -moz-column-rule: 1px solid lightblue; /* Firefox */ 117 | column-rule: 1px solid lightblue; 118 | list-style: none; 119 | list-style-type: none; 120 | list-style-image: none; 121 | list-style-position: outside; 122 | font-size: 12px; 123 | line-height: 18px; 124 | font-family: Helvetica,Arial,sans-serif; 125 | margin-top: 2em; 126 | margin-bottom: 0em; 127 | } 128 | .colLeft, .colRight{ 129 | float: left; 130 | } 131 | .colLeft{ 132 | width: 60%; 133 | } 134 | .colRight{ 135 | width: 40%; 136 | text-align: center; 137 | } 138 | .anchor{ 139 | float: right; 140 | } 141 | .boxed { 142 | box-sizing: border-box; 143 | padding: 10px; 144 | border: 1px solid; 145 | border-color: #636363; 146 | border-radius: 5px; 147 | } 148 | pre { 149 | display: inline; 150 | margin: 0; 151 | } 152 | .xterm { 153 | color:#333; 154 | display:block; 155 | font-family:Monaco,Menlo,Consolas,"Courier New",monospace; 156 | padding:9.5px; 157 | margin:0 0 10px; 158 | font-size:13px; 159 | word-break:break-all; 160 | word-wrap:break-word; 161 | background-color:#f5f5f5; 162 | border:1px solid #ccc; 163 | border-radius:4px; 164 | } 165 | -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/sw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/sw.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/tw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/tw.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/version.js: -------------------------------------------------------------------------------- 1 | function OnTheWeb() { 2 | window.location.assign("https://wiki.analog.com/university/tools/pluto"); 3 | } 4 | 5 | function versionCompare(v1, v2) { 6 | var v1parts = ("" + v1).replace(/[a-zA-Z]/g, "").replace("-", ".").split("."), 7 | v2parts = ("" + v2).replace(/[a-zA-Z]/g, "").replace("-", ".").split("."), 8 | minLength = Math.min(v1parts.length, v2parts.length), 9 | p1, p2, i; 10 | console.log(v1parts + " || " + v2parts); 11 | for(i = 0; i < minLength; i++) { 12 | p1 = parseInt(v1parts[i], 10); 13 | p2 = parseInt(v2parts[i], 10); 14 | if (isNaN(p1)){ p1 = v1parts[i]; } 15 | if (isNaN(p2)){ p2 = v2parts[i]; } 16 | if (p1 == p2) { 17 | continue; 18 | }else if (p1 > p2) { 19 | return 1; 20 | }else if (p1 < p2) { 21 | return -1; 22 | } 23 | return NaN; 24 | } 25 | if (v1parts.length === v2parts.length) { 26 | return 0; 27 | } 28 | return (v1parts.length < v2parts.length) ? -1 : 1; 29 | } 30 | 31 | var latest_libiio; 32 | var mac = false; 33 | 34 | function GetDriverurl() { 35 | mac = navigator.platform.match(/Mac/i) ? true : false; 36 | if (mac) { 37 | var uAgent = navigator.userAgent.toLowerCase(); 38 | //uAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36".toLowerCase(); 39 | var test = uAgent.match(/mac os x 10_[0-9]*/); 40 | if (test) { 41 | mac = "darwin-" + test[0].match(/10_[0-9]*/)[0].replace("_", "."); 42 | } 43 | document.getElementById('prompt0').innerHTML = "adi-mm:tests analogdevices$"; 44 | document.getElementById('prompt1').innerHTML = "adi-mm:tests analogdevices$"; 45 | } else { 46 | document.getElementById('hidehorndis').style.display = "none"; 47 | } 48 | var win = navigator.platform.indexOf('Win') > -1 ? true : false; 49 | if (win) { 50 | document.getElementById('prompt0').innerHTML = "C:\>"; 51 | document.getElementById('prompt1').innerHTML = "C:\>"; 52 | } else 53 | document.getElementById('hidedriver').style.display = "none"; 54 | var linux = navigator.platform.indexOf('Linux') > -1 ? true : false; 55 | if (mac || win || linux) 56 | document.getElementById('hidelib').style.display = "inline"; 57 | else { 58 | if (navigator.platform.match(/(Linux|iPhone|iPod|iPad|Android)/i)) { 59 | document.getElementById('libtest').innerHTML = "Sorry, we don't support " + navigator.platform + " yet. Please ask."; 60 | jQuery('#libtest').attr ('href', "https://ez.analog.com/university-program"); 61 | } else 62 | document.getElementById('libtest').innerHTML = "Unsupported host \"" + navigator.platform + "\". Please check, and report an issue"; 63 | return; 64 | } 65 | 66 | var i; var j; 67 | 68 | var req = jQuery.getJSON("https://api.github.com/repos/analogdevicesinc/libiio/releases/latest"); 69 | req.fail(function() { 70 | document.getElementById('hidelib').style.display = "none"; 71 | latest_libiio = null; 72 | }); 73 | req.done(function(response) { 74 | latest_libiio = response; 75 | var select = document.getElementById("os-select"); 76 | var suffix = ""; 77 | for (i = 0; i < latest_libiio.assets.length; i++) { 78 | os = latest_libiio.assets[i].name.split('-')[2]; 79 | suffix = os.slice(-4); 80 | if (suffix == ".zip" ) { 81 | os = os.slice(0, os.length-4); 82 | } 83 | for (j = 0; j < select.length; j++) { 84 | if (os.match(select[j].value)) 85 | break; 86 | } 87 | if (j == select.length) { 88 | select.options[select.options.length] = new Option(os); 89 | if ((win && os == "Windows") || (mac && os == "darwin") || (linux && os == "ubuntu")) { 90 | select.value = os; 91 | libiio_type(); 92 | } 93 | } 94 | } 95 | if (latest_libiio.hasOwnProperty('tarball_url') || latest_libiio.hasOwnProperty('zipball_url')) 96 | select.options[select.options.length] = new Option("source"); 97 | }); 98 | if (win) { 99 | req = jQuery.getJSON("https://api.github.com/repos/analogdevicesinc/plutosdr-m2k-drivers-win/releases/latest"); 100 | req.done(function(response) { 101 | for (i = 0; i < response.assets.length; i++) { 102 | if (response.assets[i].content_type == "application/x-msdownload") { 103 | jQuery('#drivertest').attr ('href', response.assets[i].browser_download_url); 104 | document.getElementById('drivertest').innerHTML = response.name; 105 | } 106 | } 107 | }); 108 | } else if (mac) { 109 | req = jQuery.getJSON("https://api.github.com/repos/jwise/HoRNDIS/releases/latest"); 110 | req.done(function(response) { 111 | for (i = 0; i < response.assets.length; i++) { 112 | if (response.assets[i].content_type == "application/octet-stream" && 113 | response.assets[i].browser_download_url.slice(-4) == ".pkg") { 114 | jQuery('#horndistest').attr ('href', response.assets[i].browser_download_url); 115 | document.getElementById('horndistest').innerHTML = response.name; 116 | } 117 | } 118 | }); 119 | } else { 120 | document.getElementById('hidedriver').style.display = "none"; 121 | 122 | } 123 | } 124 | 125 | function libiio_type() { 126 | var select = document.getElementById("type-select"); 127 | var os = document.getElementById("os-select").value; 128 | select.onchange = null; 129 | var i; 130 | for (i = select.options.length - 1 ; i >= 0 ; i--) { 131 | select.remove(i); 132 | } 133 | var suffix = ""; 134 | for (i = 0; i < latest_libiio.assets.length; i++) { 135 | if (latest_libiio.assets[i].browser_download_url.match(os)) { 136 | suffix = latest_libiio.assets[i].browser_download_url.slice(-4); 137 | if (suffix == "r.gz" ) { 138 | suffix = ".tar.gz"; 139 | } 140 | for (j = 0; j < select.length; j++) { 141 | if (suffix.match(select[j].value)) 142 | break; 143 | } 144 | if (j == select.length) { 145 | select.options[select.options.length] = new Option(suffix); 146 | if (os.match('centos') && suffix.match('.rpm')) { 147 | select.value = suffix; 148 | } 149 | } 150 | } 151 | } 152 | if (os.match('source')) { 153 | if (latest_libiio.hasOwnProperty('tarball_url')) 154 | select.options[select.options.length] = new Option('.tar'); 155 | if (latest_libiio.hasOwnProperty('zipball_url')) 156 | select.options[select.options.length] = new Option('.zip'); 157 | } 158 | select.onchange = libiio_ver; 159 | libiio_ver(); 160 | } 161 | 162 | function libiio_ver() { 163 | var select = document.getElementById("ver-select"); 164 | var os = document.getElementById("os-select").value; 165 | var suffix = document.getElementById("type-select").value; 166 | select.onchange = null; 167 | var i; 168 | for (i = select.options.length - 1 ; i >= 0 ; i--) { 169 | select.remove(i); 170 | } 171 | for (i = 0; i < latest_libiio.assets.length; i++) { 172 | if (latest_libiio.assets[i].browser_download_url.match(os) && latest_libiio.assets[i].browser_download_url.match(suffix)) { 173 | var file = latest_libiio.assets[i].name.replace(/libiio-[0-9]*\.[0-9]*.[a-z0-9]*-/, ''); 174 | file = file.slice(0, file.length - suffix.length); 175 | select.options[select.options.length] = new Option(file); 176 | if (mac && (file.match(mac) || 177 | file.match(/darwin-10.[0-9]*/) < mac)) { 178 | select.value = file; 179 | console.log('hit'); 180 | } 181 | } 182 | } 183 | if (os.match('source')) { 184 | select.options[select.options.length] = new Option(latest_libiio.tag_name); 185 | } 186 | select.onchange = libiio_url; 187 | libiio_url(); 188 | } 189 | 190 | function libiio_url() { 191 | var os = document.getElementById("os-select").value; 192 | var suffix = document.getElementById("type-select").value; 193 | var ver = document.getElementById("ver-select").value; 194 | var i, url; 195 | for (i = 0; i < latest_libiio.assets.length; i++) { 196 | url = latest_libiio.assets[i].browser_download_url; 197 | if (url.match(ver) && url.match(os) && url.match(suffix)) { 198 | jQuery('#libtest').attr ('href', url); 199 | document.getElementById('libtest').innerHTML = latest_libiio.assets[i].name; 200 | } 201 | } 202 | if (os.match('source')) { 203 | if (suffix.match('.tar')) { 204 | document.getElementById('libtest').innerHTML = "Source code (tar)"; 205 | jQuery('#libtest').attr ('href', latest_libiio.tarball_url); 206 | } 207 | if (suffix.match('.zip')) { 208 | document.getElementById('libtest').innerHTML = "Source code (zip)"; 209 | jQuery('#libtest').attr ('href', latest_libiio.zipball_url); 210 | } 211 | 212 | } 213 | } 214 | 215 | function CheckFrmVersion() { 216 | GetDriverurl(); 217 | var req = jQuery.getJSON("https://api.github.com/repos/analogdevicesinc/plutosdr-fw/releases/latest"); 218 | req.fail(function() { 219 | document.getElementById('versiontest').innerHTML = "Can't check right now, try manually"; 220 | }); 221 | req.done(function(response) { 222 | var VerOnGithub = response.name; 223 | var res = versionCompare("#BUILD#", VerOnGithub); 224 | var message; 225 | if (res < 0) { 226 | message = "Newer version available online (Version " + VerOnGithub + " )"; 227 | document.getElementById('versionsection').className = "download"; 228 | } else if (res > 0) { 229 | message = "Wow! Your Pluto Firmware Version #BUILD# is newer than (" + VerOnGithub + ") on Github."; 230 | document.getElementById('versionsection').className = ""; 231 | document.getElementById('plutsdr-fw-download').style.visibility = "hidden"; 232 | document.getElementById('hideupgrade').style.display = "none"; 233 | } else if (res == 0) { 234 | message = "Pluto is using the same version as latest release!"; 235 | document.getElementById('versionsection').className = ""; 236 | document.getElementById('plutsdr-fw-download').style.visibility = "hidden"; 237 | document.getElementById('hideupgrade').style.display = "none"; 238 | } else { 239 | message = "Failure in comparing version, latest upstream is " + VerOnGithub; 240 | document.getElementById('versionsection').className = ""; 241 | } 242 | document.getElementById('versiontest').innerHTML = message; 243 | document.getElementById('plutsdr-fw-download').innerHTML = "Download version " + VerOnGithub; 244 | jQuery('#plutsdr-fw-download').attr ('href', response.assets[0].browser_download_url); 245 | }); 246 | } 247 | 248 | window.onload = CheckFrmVersion; 249 | -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/yk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/yk.png -------------------------------------------------------------------------------- /board/pluto/overlay/www/img/yt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/board/pluto/overlay/www/img/yt.png -------------------------------------------------------------------------------- /board/pluto/patches/uboot/89d07540f9d489cc63460df5636174357af0a38f/0002-add_plutoSDR_include.patch: -------------------------------------------------------------------------------- 1 | Index: uboot-89d07540f9d489cc63460df5636174357af0a38f/include/configs/zynq_pluto-sdr.h 2 | =================================================================== 3 | --- /dev/null 4 | +++ uboot-89d07540f9d489cc63460df5636174357af0a38f/include/configs/zynq_pluto-sdr.h 5 | @@ -0,0 +1,32 @@ 6 | +/* 7 | + * (C) Copyright 2019 Gwenhael Goavec-Merou 8 | + * 9 | + * Configuration settings for the Xilinx Zynq Pluto SDR board 10 | + * See zynq-common.h for Zynq common configs 11 | + * 12 | + * SPDX-License-Identifier: GPL-2.0+ 13 | + */ 14 | + 15 | +#ifndef __CONFIG_ZYNQ_PLUTO_SDR_H 16 | +#define __CONFIG_ZYNQ_PLUTO_SDR_H 17 | + 18 | +#define CONFIG_ZYNQ_I2C0 19 | +#define CONFIG_ZYNQ_EEPROM 20 | +#define CONFIG_DFU_SF 21 | + 22 | +#include 23 | + 24 | +/* To maintain compatility with official 25 | + * SF map all uboot stuff must be 26 | + * between 0 and 0x100000 27 | + */ 28 | + 29 | +#undef CONFIG_SYS_SPI_U_BOOT_OFFS 30 | +#undef CONFIG_SYS_SPI_ARGS_OFFS 31 | +#undef CONFIG_SYS_SPI_ARGS_SIZE 32 | + 33 | +#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x40000 34 | +#define CONFIG_SYS_SPI_ARGS_OFFS 0x100000 35 | +#define CONFIG_SYS_SPI_ARGS_SIZE 0x20000 36 | + 37 | +#endif /* __CONFIG_ZYNQ_PLUTO_SDR_H */ 38 | -------------------------------------------------------------------------------- /board/pluto/patches/uboot/89d07540f9d489cc63460df5636174357af0a38f/0003-update_plutoSDR_defconfig.patch: -------------------------------------------------------------------------------- 1 | Index: uboot-89d07540f9d489cc63460df5636174357af0a38f/configs/zynq_pluto_defconfig 2 | =================================================================== 3 | --- uboot-89d07540f9d489cc63460df5636174357af0a38f.orig/configs/zynq_pluto_defconfig 4 | +++ uboot-89d07540f9d489cc63460df5636174357af0a38f/configs/zynq_pluto_defconfig 5 | @@ -1,5 +1,5 @@ 6 | CONFIG_ARM=y 7 | -CONFIG_SYS_CONFIG_NAME="zynq_zc70x" 8 | +CONFIG_SYS_CONFIG_NAME="zynq_pluto-sdr" 9 | CONFIG_ARCH_ZYNQ=y 10 | CONFIG_SYS_MALLOC_F_LEN=0x800 11 | CONFIG_DEFAULT_DEVICE_TREE="zynq-pluto-sdr" 12 | -------------------------------------------------------------------------------- /board/pluto/pluto.its: -------------------------------------------------------------------------------- 1 | /* 2 | * U-Boot uImage source file with multiple kernels, ramdisks and FDT blobs 3 | * This example makes use of the 'loadables' field 4 | */ 5 | 6 | /* 7 | * fdt get addr foo /images/fdt@1 data 8 | */ 9 | 10 | /dts-v1/; 11 | 12 | / { 13 | description = "Configuration to load fpga before Kernel"; 14 | magic = "ITB PlutoSDR (ADALM-PLUTO)"; 15 | #address-cells = <1>; 16 | 17 | images { 18 | 19 | fdt@1 { 20 | description = "zynq-pluto-sdr"; 21 | data = /incbin/("zynq-pluto-sdr.dtb"); 22 | type = "flat_dt"; 23 | arch = "arm"; 24 | compression = "none"; 25 | }; 26 | 27 | fdt@2 { 28 | description = "zynq-pluto-sdr-revb"; 29 | data = /incbin/("zynq-pluto-sdr-revb.dtb"); 30 | type = "flat_dt"; 31 | arch = "arm"; 32 | compression = "none"; 33 | }; 34 | 35 | fdt@3 { 36 | description = "zynq-pluto-sdr-revc"; 37 | data = /incbin/("zynq-pluto-sdr-revb.dtb"); 38 | type = "flat_dt"; 39 | arch = "arm"; 40 | compression = "none"; 41 | }; 42 | 43 | fpga@1 { 44 | description = "FPGA"; 45 | data = /incbin/("system_top.bit"); 46 | type = "fpga"; 47 | arch = "arm"; 48 | compression = "none"; 49 | load = <0xF000000>; 50 | hash@1 { 51 | algo = "md5"; 52 | }; 53 | }; 54 | 55 | linux_kernel@1 { 56 | description = "Linux"; 57 | data = /incbin/("zImage"); 58 | type = "kernel"; 59 | arch = "arm"; 60 | os = "linux"; 61 | compression = "none"; 62 | load = <0x8000>; 63 | entry = <0x8000>; 64 | hash@1 { 65 | algo = "md5"; 66 | }; 67 | }; 68 | ramdisk@1 { 69 | description = "Ramdisk"; 70 | data = /incbin/("rootfs.cpio.gz"); 71 | type = "ramdisk"; 72 | arch = "arm"; 73 | os = "linux"; 74 | compression = "gzip"; 75 | hash@1 { 76 | algo = "md5"; 77 | }; 78 | }; 79 | 80 | }; 81 | 82 | configurations { 83 | default = "config@0"; 84 | config@0 { 85 | description = "Linux with fpga RevA"; 86 | fdt = "fdt@1"; 87 | kernel = "linux_kernel@1"; 88 | ramdisk = "ramdisk@1"; 89 | fpga = "fpga@1"; 90 | }; 91 | 92 | /* all below is currently RevB ! */ 93 | 94 | config@1 { 95 | description = "Linux with fpga RevB"; 96 | fdt = "fdt@2"; 97 | kernel = "linux_kernel@1"; 98 | ramdisk = "ramdisk@1"; 99 | fpga = "fpga@1"; 100 | }; 101 | 102 | config@2 { 103 | description = "Linux with fpga RevB"; 104 | fdt = "fdt@2"; 105 | kernel = "linux_kernel@1"; 106 | ramdisk = "ramdisk@1"; 107 | fpga = "fpga@1"; 108 | }; 109 | 110 | config@3 { 111 | description = "Linux with fpga RevB"; 112 | fdt = "fdt@2"; 113 | kernel = "linux_kernel@1"; 114 | ramdisk = "ramdisk@1"; 115 | fpga = "fpga@1"; 116 | }; 117 | 118 | config@4 { 119 | description = "Linux with fpga RevB"; 120 | fdt = "fdt@2"; 121 | kernel = "linux_kernel@1"; 122 | ramdisk = "ramdisk@1"; 123 | fpga = "fpga@1"; 124 | }; 125 | 126 | config@5 { 127 | description = "Linux with fpga RevB"; 128 | fdt = "fdt@2"; 129 | kernel = "linux_kernel@1"; 130 | ramdisk = "ramdisk@1"; 131 | fpga = "fpga@1"; 132 | }; 133 | 134 | config@6 { 135 | description = "Linux with fpga RevB"; 136 | fdt = "fdt@2"; 137 | kernel = "linux_kernel@1"; 138 | ramdisk = "ramdisk@1"; 139 | fpga = "fpga@1"; 140 | }; 141 | 142 | 143 | config@7 { 144 | description = "Linux with fpga RevB"; 145 | fdt = "fdt@2"; 146 | kernel = "linux_kernel@1"; 147 | ramdisk = "ramdisk@1"; 148 | fpga = "fpga@1"; 149 | }; 150 | 151 | config@8 { /* This one is actually RevC */ 152 | description = "Linux with fpga RevC"; 153 | fdt = "fdt@3"; 154 | kernel = "linux_kernel@1"; 155 | ramdisk = "ramdisk@1"; 156 | fpga = "fpga@1"; 157 | }; 158 | 159 | config@9 { /* This one is actually RevB */ 160 | description = "Linux with fpga RevB"; 161 | fdt = "fdt@2"; 162 | kernel = "linux_kernel@1"; 163 | ramdisk = "ramdisk@1"; 164 | fpga = "fpga@1"; 165 | }; 166 | 167 | config@10 { 168 | description = "Linux with fpga RevB"; 169 | fdt = "fdt@2"; 170 | kernel = "linux_kernel@1"; 171 | ramdisk = "ramdisk@1"; 172 | fpga = "fpga@1"; 173 | }; 174 | }; 175 | }; 176 | -------------------------------------------------------------------------------- /board/pluto/post-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # args from BR2_ROOTFS_POST_SCRIPT_ARGS 3 | # $2 board name 4 | set -e 5 | 6 | BOARD_DIR=$(dirname ${0}) 7 | 8 | # Add a console on tty1 9 | grep -qE '^ttyGS0::' ${TARGET_DIR}/etc/inittab || \ 10 | sed -i '/GENERIC_SERIAL/a\ 11 | ttyGS0::respawn:/sbin/getty -L ttyGS0 0 vt100 # USB console' ${TARGET_DIR}/etc/inittab 12 | 13 | grep -qE '^::sysinit:/bin/mount -t debugfs' ${TARGET_DIR}/etc/inittab || \ 14 | sed -i '/hostname/a\ 15 | ::sysinit:/bin/mount -t debugfs none /sys/kernel/debug/' ${TARGET_DIR}/etc/inittab 16 | 17 | sed -i -e '/::sysinit:\/bin\/hostname -F \/etc\/hostname/d' ${TARGET_DIR}/etc/inittab 18 | 19 | # Prepare LICENSE.html 20 | if [ ! -e ${BINARIES_DIR}/msd ]; then 21 | mkdir ${BINARIES_DIR}/msd 22 | fi 23 | 24 | cp ${BOARD_DIR}/LICENSE.template ${BINARIES_DIR}/msd/LICENSE.html 25 | cp ${BOARD_DIR}/msd/index.html ${BINARIES_DIR}/msd/ 26 | LINUX_VERS=$(cat ${BR2_CONFIG} | grep '^BR2_LINUX_KERNEL_VERSION' | cut -d\" -f 2) 27 | UBOOT_VERS=$(cat ${BR2_CONFIG} | grep '^BR2_TARGET_UBOOT_VERSION' | cut -d\" -f 2) 28 | FW_VERSION=$(cd ${BOARD_DIR} && git describe --abbrev=4 --dirty --always --tags) 29 | sed -i s/##DEVICE_FW##/${FW_VERSION}/g ${BINARIES_DIR}/msd/LICENSE.html 30 | sed -i s/##LINUX_VERSION##/${LINUX_VERS}/g ${BINARIES_DIR}/msd/LICENSE.html 31 | sed -i s/##UBOOT_VERSION##/${UBOOT_VERS}/g ${BINARIES_DIR}/msd/LICENSE.html 32 | 33 | 34 | BOARD_DIR="$(dirname $0)" 35 | BOARD_NAME="$(basename ${BOARD_DIR})" 36 | GENIMAGE_CFG="${BOARD_DIR}/genimage-msd.cfg" 37 | GENIMAGE_TMP="${BUILD_DIR}/genimage.tmp" 38 | 39 | rm -rf "${GENIMAGE_TMP}" 40 | 41 | genimage \ 42 | --rootpath "${TARGET_DIR}" \ 43 | --tmppath "${GENIMAGE_TMP}" \ 44 | --inputpath "${BINARIES_DIR}/msd" \ 45 | --outputpath "${TARGET_DIR}/opt/" \ 46 | --config "${GENIMAGE_CFG}" 47 | 48 | rm -f ${TARGET_DIR}/opt/boot.vfat 49 | rm -f ${TARGET_DIR}/etc/init.d/S99iiod 50 | rm -rf ${BINARIES_DIR}/msd 51 | -------------------------------------------------------------------------------- /board/pluto/post_image-uboot.sh: -------------------------------------------------------------------------------- 1 | BOARD_DIR=$(dirname $0) 2 | BIN_DIR=$1 3 | dfu_suffix=$HOST_DIR/bin/dfu-suffix 4 | 5 | DEVICE_VID=0x0456 6 | DEVICE_PID=0xb673 7 | 8 | echo "generating the boot.img" 9 | 10 | GENIMAGE_CFG="${BOARD_DIR}/genimage-boot.cfg" 11 | GENIMAGE_TMP="${BUILD_DIR}/genimage.tmp" 12 | 13 | rm -rf "${GENIMAGE_TMP}" 14 | 15 | genimage \ 16 | --rootpath "${TARGET_DIR}" \ 17 | --tmppath "${GENIMAGE_TMP}" \ 18 | --inputpath "${BINARIES_DIR}" \ 19 | --outputpath "${BINARIES_DIR}" \ 20 | --config "${GENIMAGE_CFG}" 21 | 22 | echo "generating the boot.frm" 23 | cat $BIN_DIR/boot.img $BIN_DIR/uboot-env.bin $BOARD_DIR/target_mtd_info.key | \ 24 | tee $BIN_DIR/boot.frm | md5sum | cut -d ' ' -f1 | tee -a $BIN_DIR/boot.frm 25 | 26 | echo "generating boot.dfu" 27 | cp $BIN_DIR/boot.img $BIN_DIR/boot.bin.tmp 28 | $dfu_suffix -a $BIN_DIR/boot.bin.tmp -v $DEVICE_VID -p $DEVICE_PID 29 | mv $BIN_DIR/boot.bin.tmp $BIN_DIR/boot.dfu 30 | 31 | echo "generating uboot-env.dfu" 32 | cp $BIN_DIR/uboot-env.bin $BIN_DIR/uboot-env.bin.tmp 33 | $dfu_suffix -a $BIN_DIR/uboot-env.bin.tmp -v $DEVICE_VID -p $DEVICE_PID 34 | mv $BIN_DIR/uboot-env.bin.tmp $BIN_DIR/uboot-env.dfu 35 | 36 | 37 | -------------------------------------------------------------------------------- /board/pluto/post_image.sh: -------------------------------------------------------------------------------- 1 | TARGET=pluto 2 | BOARD_DIR=$(dirname $0) 3 | BIN_DIR=$1 4 | mkimage=$HOST_DIR/bin/mkimage 5 | dfu_suffix=$HOST_DIR/bin/dfu-suffix 6 | 7 | DEVICE_VID=0x0456 8 | DEVICE_PID=0xb673 9 | 10 | cp $BOARD_DIR/pluto.its $BIN_DIR/pluto.its 11 | 12 | echo "# entering $BIN_DIR for the next command" 13 | (cd $BIN_DIR && $mkimage -f pluto.its pluto.itb) 14 | 15 | echo "generating the pluto.frm" 16 | md5sum $BIN_DIR/pluto.itb | cut -d ' ' -f 1 > $BIN_DIR/pluto.md5 17 | cat $BIN_DIR/pluto.itb $BIN_DIR/pluto.md5 > $BIN_DIR/pluto.frm 18 | 19 | echo "generating pluto.dfu" 20 | $dfu_suffix -a $BIN_DIR/pluto.itb -v $DEVICE_VID -p $DEVICE_PID 21 | mv $BIN_DIR/pluto.itb $BIN_DIR/pluto.dfu 22 | 23 | rm -f $BIN_DIR/pluto.its $BIN_DIR/*.md5 24 | -------------------------------------------------------------------------------- /board/pluto/target_mtd_info.key: -------------------------------------------------------------------------------- 1 | dev: size erasesize name 2 | mtd0: 00100000 00001000 "qspi-fsbl-uboot" 3 | mtd1: 00020000 00001000 "qspi-uboot-env" 4 | mtd2: 000e0000 00001000 "qspi-nvmfs" 5 | mtd3: 01e00000 00001000 "qspi-linux" 6 | -------------------------------------------------------------------------------- /board/pluto/uboot-env.txt: -------------------------------------------------------------------------------- 1 | 2 | adi_loadvals=fdt addr ${fit_load_address} && fdt get value fdt_choosen /configurations/${fit_config}/ fdt && fdt get addr fdtaddr /images/${fdt_choosen} data && fdt addr ${fdtaddr}; if test -n ${ad936x_ext_refclk} && test ! -n ${ad936x_skip_ext_refclk}; then fdt set /clocks/clock@0 clock-frequency ${ad936x_ext_refclk}; fi; if test -n ${model}; then fdt set / model ${model}; fi; if test -n ${attr_name} && test -n ${attr_val}; then fdt set /amba/spi@e0006000/ad9361-phy@0 ${attr_name} ${attr_val}; fi 3 | baudrate=115200 4 | bitstream_image=system.bit.bin 5 | bitstream_size=0x400000 6 | bootcmd=run $modeboot 7 | bootdelay=0 8 | bootenv=uEnv.txt 9 | boot_image=BOOT.bin 10 | boot_size=0xF00000 11 | clear_reset_cause=mw f8000008 df0d && mw f8000258 00400000 && mw f8000004 767b 12 | devicetree_image=devicetree.dtb 13 | devicetree_load_address=0x2000000 14 | devicetree_size=0x20000 15 | dfu_ram=echo Entering DFU RAM mode ... && run dfu_ram_info && dfu 0 ram 0 16 | dfu_ram_info=set dfu_alt_info dummy.dfu ram 0 0\\;firmware.dfu ram ${fit_load_address} 0x1E00000 17 | dfu_sf=gpio set 15;set stdout serial@e0001000;echo Entering DFU SF mode ... && run dfu_sf_info && dfu 0 sf 0:0:40000000:0 && if test -n ${dfu_alt_num} && test ${dfu_alt_num} = 1; then set fit_size ${filesize} && set dfu_alt_num && env save; fi;gpio clear 15; 18 | dfu_sf_info=set dfu_alt_info boot.dfu raw 0x0 0x100000\\;firmware.dfu raw 0x200000 0x1E00000\\;uboot-extra-env.dfu raw 0xFF000 0x1000\\;uboot-env.dfu raw 0x100000 0x20000\\;spare.dfu raw 0x120000 0xE0000 19 | ethaddr=00:0a:35:00:01:22 20 | extraenv_load_address=0x207E000 21 | fdt_high=0x20000000 22 | fit_config=config@0 23 | fit_load_address=0x2080000 24 | fit_size=0x900000 25 | importbootenv=echo Importing environment from SD ...; env import -t ${loadbootenv_addr} $filesize 26 | initrd_high=0x20000000 27 | ipaddr=192.168.2.1 28 | ipaddr_host=192.168.2.10 29 | jtagboot=env default -a;sf probe && sf protect unlock 0 100000 && run dfu_sf; 30 | kernel_image=uImage 31 | loadbit_addr=0x100000 32 | loadbootenv_addr=0x2000000 33 | loadbootenv=load mmc 0 ${loadbootenv_addr} ${bootenv} 34 | maxcpus=1 35 | netmask=255.255.255.0 36 | preboot= 37 | preboot=if test $modeboot = sdboot && env run sd_uEnvtxt_existence_test; then if env run loadbootenv; then env run importbootenv; fi; fi; 38 | qspiboot_extraenv=sf read ${extraenv_load_address} 0xFF000 0x1000 && env import -c ${extraenv_load_address} 0x1000 || true 39 | qspiboot=set stdout nulldev;adi_hwref;test -n $PlutoRevA || gpio input 14 && set stdout serial@e0001000 && sf probe && sf protect lock 0 100000 && run dfu_sf; set stdout serial@e0001000;itest *f8000258 == 480003 && run clear_reset_cause && run dfu_sf; itest *f8000258 == 480007 && run clear_reset_cause && run ramboot_verbose; itest *f8000258 == 480006 && run clear_reset_cause && run qspiboot_verbose; itest *f8000258 == 480002 && run clear_reset_cause && exit; echo Booting silently && set stdout nulldev; run read_sf && run adi_loadvals; envversion;setenv bootargs console=ttyPS0,115200 maxcpus=${maxcpus} rootfstype=ramfs root=/dev/ram0 rw quiet loglevel=4 uboot="${uboot-version}" && bootm ${fit_load_address}#${fit_config} || set stdout serial@e0001000;echo BOOT failed entering DFU mode ... && sf protect lock 0 100000 && run dfu_sf 40 | qspiboot_verbose=adi_hwref;echo Copying Linux from QSPI flash to RAM... && run read_sf && if run adi_loadvals; then echo Loaded AD936x refclk frequency and model into devicetree; fi; envversion;setenv bootargs console=ttyPS0,115200 maxcpus=${maxcpus} rootfstype=ramfs root=/dev/ram0 rw earlyprintk uboot="${uboot-version}" && bootm ${fit_load_address}#${fit_config} || echo BOOT failed entering DFU mode ... && run dfu_sf 41 | ramboot_verbose=adi_hwref;echo Copying Linux from DFU to RAM... && run dfu_ram;if run adi_loadvals; then echo Loaded AD936x refclk frequency and model into devicetree; fi; envversion;setenv bootargs console=ttyPS0,115200 maxcpus=${maxcpus} rootfstype=ramfs root=/dev/ram0 rw earlyprintk uboot="${uboot-version}" && bootm ${fit_load_address}#${fit_config} 42 | ramdisk_image=uramdisk.image.gz 43 | ramdisk_load_address=0x4000000 44 | ramdisk_size=0x400000 45 | read_sf=sf probe 0:0 50000000 0 && run qspiboot_extraenv &&sf read ${fit_load_address} 0x200000 ${fit_size} && iminfo ${fit_load_address} || sf read ${fit_load_address} 0x200000 0x1E00000; 46 | sd_uEnvtxt_existence_test=test -e mmc 0 /uEnv.txt 47 | thor_ram=run dfu_ram_info && thordown 0 ram 0 48 | uenvboot=if run loadbootenv; then echo Loaded environment from ${bootenv}; run importbootenv; fi; if test -n $uenvcmd; then echo Running uenvcmd ...; run uenvcmd; fi 49 | usbboot=if usb start; then run uenvboot; echo Copying Linux from USB to RAM... && load usb 0 ${fit_load_address} ${kernel_image} && load usb 0 ${devicetree_load_address} ${devicetree_image} && load usb 0 ${ramdisk_load_address} ${ramdisk_image} && bootm ${fit_load_address} ${ramdisk_load_address} ${devicetree_load_address}; fi 50 | -------------------------------------------------------------------------------- /configs/README.md: -------------------------------------------------------------------------------- 1 | Buildroot configuration files for the PlutoSDR without (zynq_pluto_defconfig) 2 | and with (zynq_pluto_gnuradio_defconfig) GNU Radio support. 3 | -------------------------------------------------------------------------------- /configs/zynq_pluto_defconfig: -------------------------------------------------------------------------------- 1 | BR2_arm=y 2 | BR2_cortex_a9=y 3 | BR2_ARM_ENABLE_NEON=y 4 | BR2_ARM_ENABLE_VFP=y 5 | BR2_CCACHE=y 6 | BR2_GLOBAL_PATCH_DIR="${BR2_EXTERNAL_PLUTOSDR_PATH}/board/pluto/patches" 7 | BR2_KERNEL_HEADERS_4_9=y 8 | BR2_TOOLCHAIN_BUILDROOT_WCHAR=y 9 | BR2_TOOLCHAIN_BUILDROOT_CXX=y 10 | BR2_TARGET_GENERIC_HOSTNAME="pluto" 11 | BR2_TARGET_GENERIC_ISSUE="Welcome to Pluto" 12 | BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_MDEV=y 13 | BR2_TARGET_GENERIC_ROOT_PASSWD="analog" 14 | BR2_TARGET_GENERIC_GETTY_PORT="ttyPS0" 15 | BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_PLUTOSDR_PATH}/board/pluto/overlay" 16 | BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_PLUTOSDR_PATH}/board/pluto/post-build.sh" 17 | BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_PLUTOSDR_PATH}/board/pluto/post_image.sh ${BR2_EXTERNAL_PLUTOSDR_PATH}/board/pluto/post_image-uboot.sh" 18 | BR2_LINUX_KERNEL=y 19 | BR2_LINUX_KERNEL_CUSTOM_GIT=y 20 | BR2_LINUX_KERNEL_CUSTOM_REPO_URL="https://github.com/analogdevicesinc/linux.git" 21 | BR2_LINUX_KERNEL_CUSTOM_REPO_VERSION="c2041af164e263d852897cf90edb5cca9f677579" 22 | BR2_LINUX_KERNEL_DEFCONFIG="zynq_pluto" 23 | BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_PLUTOSDR_PATH)/board/pluto/linux-$(BR2_LINUX_KERNEL_VERSION).fragment" 24 | BR2_LINUX_KERNEL_DTS_SUPPORT=y 25 | BR2_LINUX_KERNEL_INTREE_DTS_NAME="zynq-pluto-sdr-revc zynq-pluto-sdr-revb zynq-pluto-sdr" 26 | BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT=y 27 | BR2_PACKAGE_BUSYBOX_CONFIG="${BR2_EXTERNAL_PLUTOSDR_PATH}/board/pluto/busybox-1.25.0.config" 28 | BR2_PACKAGE_STRACE=y 29 | BR2_PACKAGE_MTD=y 30 | # BR2_PACKAGE_MTD_NANDDUMP is not set 31 | # BR2_PACKAGE_MTD_NANDTEST is not set 32 | # BR2_PACKAGE_MTD_NANDWRITE is not set 33 | # BR2_PACKAGE_MTD_UBIATTACH is not set 34 | # BR2_PACKAGE_MTD_UBICRC32 is not set 35 | # BR2_PACKAGE_MTD_UBIDETACH is not set 36 | # BR2_PACKAGE_MTD_UBIFORMAT is not set 37 | # BR2_PACKAGE_MTD_UBIMKVOL is not set 38 | # BR2_PACKAGE_MTD_UBINFO is not set 39 | # BR2_PACKAGE_MTD_UBINIZE is not set 40 | # BR2_PACKAGE_MTD_UBIRENAME is not set 41 | # BR2_PACKAGE_MTD_UBIRMVOL is not set 42 | # BR2_PACKAGE_MTD_UBIRSVOL is not set 43 | # BR2_PACKAGE_MTD_UBIUPDATEVOL is not set 44 | # BR2_PACKAGE_MTD_UBIBLOCK is not set 45 | BR2_PACKAGE_LINUX_FIRMWARE=y 46 | BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT61=y 47 | BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT73=y 48 | BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT2XX=y 49 | BR2_PACKAGE_LINUX_FIRMWARE_RTL_81XX=y 50 | BR2_PACKAGE_LINUX_FIRMWARE_RTL_87XX=y 51 | BR2_PACKAGE_LINUX_FIRMWARE_RTL_88XX=y 52 | BR2_PACKAGE_INPUT_EVENT_DAEMON=y 53 | BR2_PACKAGE_UBOOT_TOOLS=y 54 | BR2_PACKAGE_ZLIB=y 55 | BR2_PACKAGE_AVAHI=y 56 | BR2_PACKAGE_AVAHI_DAEMON=y 57 | BR2_PACKAGE_AVAHI_LIBDNSSD_COMPATIBILITY=y 58 | BR2_PACKAGE_DROPBEAR=y 59 | # BR2_PACKAGE_DROPBEAR_CLIENT is not set 60 | BR2_PACKAGE_IW=y 61 | BR2_PACKAGE_WPA_SUPPLICANT=y 62 | BR2_PACKAGE_WPA_SUPPLICANT_CLI=y 63 | BR2_PACKAGE_WPA_SUPPLICANT_PASSPHRASE=y 64 | BR2_TARGET_ROOTFS_CPIO=y 65 | BR2_TARGET_ROOTFS_CPIO_GZIP=y 66 | BR2_TARGET_ROOTFS_CPIO_UIMAGE=y 67 | BR2_TARGET_UBOOT=y 68 | BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y 69 | BR2_TARGET_UBOOT_CUSTOM_GIT=y 70 | BR2_TARGET_UBOOT_CUSTOM_REPO_URL="https://github.com/analogdevicesinc/u-boot-xlnx.git" 71 | BR2_TARGET_UBOOT_CUSTOM_REPO_VERSION="89d07540f9d489cc63460df5636174357af0a38f" 72 | BR2_TARGET_UBOOT_BOARD_DEFCONFIG="zynq_pluto" 73 | BR2_TARGET_UBOOT_NEEDS_DTC=y 74 | BR2_TARGET_UBOOT_NEEDS_OPENSSL=y 75 | # BR2_TARGET_UBOOT_FORMAT_BIN is not set 76 | BR2_TARGET_UBOOT_FORMAT_IMG=y 77 | BR2_TARGET_UBOOT_SPL=y 78 | BR2_TARGET_UBOOT_SPL_NAME="spl/boot.bin" 79 | BR2_TARGET_UBOOT_ENVIMAGE=y 80 | BR2_TARGET_UBOOT_ENVIMAGE_SOURCE="${BR2_EXTERNAL_PLUTOSDR_PATH}/board/pluto/uboot-env.txt" 81 | BR2_TARGET_UBOOT_ENVIMAGE_SIZE="0x20000" 82 | BR2_PACKAGE_HOST_DFU_UTIL=y 83 | BR2_PACKAGE_HOST_DOSFSTOOLS=y 84 | BR2_PACKAGE_HOST_GENIMAGE=y 85 | BR2_PACKAGE_HOST_MTOOLS=y 86 | BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y 87 | BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y 88 | BR2_PACKAGE_AD936X_REF_CAL=y 89 | BR2_PACKAGE_LIBAD9361_IIO=y 90 | BR2_PACKAGE_LIBIIO_PLUTO_IIOD_USBD=y 91 | BR2_PACKAGE_LIBIIO_PLUTO_TESTS=y 92 | BR2_PACKAGE_LIBINI=y 93 | BR2_PACKAGE_PLUTO_SYSTEM_TOP_BIT=y 94 | BR2_PACKAGE_POLL_SYSFS=y 95 | -------------------------------------------------------------------------------- /configs/zynq_pluto_gnuradio_defconfig: -------------------------------------------------------------------------------- 1 | BR2_arm=y 2 | BR2_cortex_a9=y 3 | BR2_ARM_ENABLE_NEON=y 4 | BR2_ARM_ENABLE_VFP=y 5 | BR2_CCACHE=y 6 | BR2_GLOBAL_PATCH_DIR="${BR2_EXTERNAL_PLUTOSDR_PATH}/board/pluto/patches" 7 | BR2_KERNEL_HEADERS_4_9=y 8 | BR2_TOOLCHAIN_BUILDROOT_WCHAR=y 9 | BR2_TOOLCHAIN_BUILDROOT_CXX=y 10 | BR2_TARGET_GENERIC_HOSTNAME="pluto" 11 | BR2_TARGET_GENERIC_ISSUE="Welcome to Pluto" 12 | BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_MDEV=y 13 | BR2_TARGET_GENERIC_ROOT_PASSWD="analog" 14 | BR2_TARGET_GENERIC_GETTY_PORT="ttyPS0" 15 | BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_PLUTOSDR_PATH}/board/pluto/overlay" 16 | BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_PLUTOSDR_PATH}/board/pluto/post-build.sh" 17 | BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_PLUTOSDR_PATH}/board/pluto/post_image.sh ${BR2_EXTERNAL_PLUTOSDR_PATH}/board/pluto/post_image-uboot.sh" 18 | BR2_LINUX_KERNEL=y 19 | BR2_LINUX_KERNEL_CUSTOM_GIT=y 20 | BR2_LINUX_KERNEL_CUSTOM_REPO_URL="https://github.com/analogdevicesinc/linux.git" 21 | BR2_LINUX_KERNEL_CUSTOM_REPO_VERSION="c2041af164e263d852897cf90edb5cca9f677579" 22 | BR2_LINUX_KERNEL_DEFCONFIG="zynq_pluto" 23 | BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_PLUTOSDR_PATH)/board/pluto/linux-$(BR2_LINUX_KERNEL_VERSION).fragment" 24 | BR2_LINUX_KERNEL_DTS_SUPPORT=y 25 | BR2_LINUX_KERNEL_INTREE_DTS_NAME="zynq-pluto-sdr-revc zynq-pluto-sdr-revb zynq-pluto-sdr" 26 | BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT=y 27 | BR2_PACKAGE_BUSYBOX_CONFIG="${BR2_EXTERNAL_PLUTOSDR_PATH}/board/pluto/busybox-1.25.0.config" 28 | BR2_PACKAGE_STRACE=y 29 | BR2_PACKAGE_MTD=y 30 | # BR2_PACKAGE_MTD_NANDDUMP is not set 31 | # BR2_PACKAGE_MTD_NANDTEST is not set 32 | # BR2_PACKAGE_MTD_NANDWRITE is not set 33 | # BR2_PACKAGE_MTD_UBIATTACH is not set 34 | # BR2_PACKAGE_MTD_UBICRC32 is not set 35 | # BR2_PACKAGE_MTD_UBIDETACH is not set 36 | # BR2_PACKAGE_MTD_UBIFORMAT is not set 37 | # BR2_PACKAGE_MTD_UBIMKVOL is not set 38 | # BR2_PACKAGE_MTD_UBINFO is not set 39 | # BR2_PACKAGE_MTD_UBINIZE is not set 40 | # BR2_PACKAGE_MTD_UBIRENAME is not set 41 | # BR2_PACKAGE_MTD_UBIRMVOL is not set 42 | # BR2_PACKAGE_MTD_UBIRSVOL is not set 43 | # BR2_PACKAGE_MTD_UBIUPDATEVOL is not set 44 | # BR2_PACKAGE_MTD_UBIBLOCK is not set 45 | BR2_PACKAGE_INPUT_EVENT_DAEMON=y 46 | BR2_PACKAGE_UBOOT_TOOLS=y 47 | BR2_PACKAGE_PYTHON=y 48 | BR2_PACKAGE_ZLIB=y 49 | BR2_PACKAGE_LIBNL=y 50 | BR2_PACKAGE_BOOST_ATOMIC=y 51 | BR2_PACKAGE_FFTW_FAST=y 52 | BR2_PACKAGE_GSL=y 53 | BR2_PACKAGE_LIBDAEMON=y 54 | BR2_PACKAGE_GNURADIO_AUDIO=y 55 | BR2_PACKAGE_GNURADIO_PYTHON=y 56 | BR2_PACKAGE_GNURADIO_UTILS=y 57 | BR2_PACKAGE_GNURADIO_ZEROMQ=y 58 | BR2_PACKAGE_GNURADIO_DIGITAL=y 59 | BR2_PACKAGE_DROPBEAR=y 60 | # BR2_PACKAGE_DROPBEAR_CLIENT is not set 61 | BR2_TARGET_ROOTFS_CPIO=y 62 | BR2_TARGET_ROOTFS_CPIO_GZIP=y 63 | BR2_TARGET_ROOTFS_CPIO_UIMAGE=y 64 | BR2_TARGET_UBOOT=y 65 | BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y 66 | BR2_TARGET_UBOOT_CUSTOM_GIT=y 67 | BR2_TARGET_UBOOT_CUSTOM_REPO_URL="https://github.com/analogdevicesinc/u-boot-xlnx.git" 68 | BR2_TARGET_UBOOT_CUSTOM_REPO_VERSION="89d07540f9d489cc63460df5636174357af0a38f" 69 | BR2_TARGET_UBOOT_BOARD_DEFCONFIG="zynq_pluto" 70 | BR2_TARGET_UBOOT_NEEDS_DTC=y 71 | BR2_TARGET_UBOOT_NEEDS_OPENSSL=y 72 | # BR2_TARGET_UBOOT_FORMAT_BIN is not set 73 | BR2_TARGET_UBOOT_FORMAT_IMG=y 74 | BR2_TARGET_UBOOT_SPL=y 75 | BR2_TARGET_UBOOT_SPL_NAME="spl/boot.bin" 76 | BR2_TARGET_UBOOT_ENVIMAGE=y 77 | BR2_TARGET_UBOOT_ENVIMAGE_SOURCE="${BR2_EXTERNAL_PLUTOSDR_PATH}/board/pluto/uboot-env.txt" 78 | BR2_TARGET_UBOOT_ENVIMAGE_SIZE="0x20000" 79 | BR2_PACKAGE_HOST_DFU_UTIL=y 80 | BR2_PACKAGE_HOST_DOSFSTOOLS=y 81 | BR2_PACKAGE_HOST_GENIMAGE=y 82 | BR2_PACKAGE_HOST_MTOOLS=y 83 | BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y 84 | BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y 85 | BR2_PACKAGE_AD936X_REF_CAL=y 86 | BR2_PACKAGE_LIBAD9361_IIO=y 87 | BR2_PACKAGE_LIBIIO_PLUTO_IIOD_USBD=y 88 | BR2_PACKAGE_LIBIIO_PLUTO_BINDINGS_PYTHON=y 89 | BR2_PACKAGE_LIBINI=y 90 | BR2_PACKAGE_PLUTO_SYSTEM_TOP_BIT=y 91 | BR2_PACKAGE_POLL_SYSFS=y 92 | BR2_PACKAGE_GR_IIO=y 93 | -------------------------------------------------------------------------------- /doc/IMG_20200527_211928small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/doc/IMG_20200527_211928small.jpg -------------------------------------------------------------------------------- /doc/README.md: -------------------------------------------------------------------------------- 1 | **Buildroot for cross-compiling GNU Radio to embedded 2 | boards** 3 | 4 | The Raspberry Pi{3,4} (RPi) is a single board computer designed – for 5 | the characteristics we are interested in for Software Defined Radio 6 | applications – around a quad-core ARM processor clocked at 1.5 GHz with 7 | 1, 2 or 4 GB random access memory. The operating system is stored on a 8 | microSD card and is hence easily updated from the host computer (never 9 | *ever* compile on the target embedded board). Generating a 10 | dedicated toolchain – as opposed to using a readily available binary 11 | distribution – allows for optimizing instructions for the chipset 12 | available on the targeted platform. 13 | 14 | Our objective is to **execute GNU Radio on the RPi** in 15 | order to run some pre-processing on the embedded board before sending 16 | the processing result to the PC (e.g. receiving a broadcast FM station 17 | on the RPi and send the audio output to the PC through a Zero-MQ link). 18 | 19 | # Buildroot for RPi 20 | 21 | Buildroot is a framework providing a consistent set of 22 | 23 | - cross-compilation toolchain for the host (usually Intel x86/AMD64 24 | processor) 25 | 26 | - libraries and userspace applications for the ARM target, 27 | 28 | - Linux kernel for the target, 29 | 30 | - bootloader for embedded target board initialization in order to load 31 | the Linux kernel in charge of supervizing userspace applications. 32 | 33 | This consistency avoids many pitfalls when cross-compiling target 34 | applications or kernel modules on the host. Obviously the 35 | low-computational power target is *not* designed for 36 | intensive computational load such as compiling GNU Radio, and 37 | gcc should actually not even be available on the target, 38 | neither is the SD card with its finite number of write cycles designed 39 | for large compilation (at least make /tmp/ a RAM filesystem 40 | if trying such a compiltion on the target). 41 | 42 | Installing the result of Buildroot cross-compilation on the Raspberry 43 | Pi4 is described at 44 | 45 | but the documentation on this web page is not up to date (?\!): 46 | 47 | 1. git clone https://git.busybox.net/buildroot 48 | 49 | 2. cd buildroot 50 | 51 | 3. make raspberrypi4\_64\_defconfig 52 | 53 | fetches the Buildroot archive, and configures for the RaspberryPi4 in 54 | 64 bit mode (obviously for RPi3, select 55 | raspberrypi3\_64\_defconfig). Because Python support for 56 | GNU Radio will require the glibc library rather than the 57 | default uClibc, we must tune the default configuration 58 | 59 | 4. make menuconfig 60 | 61 | 5. Toolchain -> C library (uClibc-ng) -> glibc 62 | 63 | 6. Exit 64 | 65 | Once the proper C-library has been selected 66 | 67 | 7. make 68 | 69 | builds all tools needed for cross-compilation. This operation will take 70 | about 40 min on an 8-core 2.33 GHz Xeon CPU with fast internet connexion 71 | and require 7.4 GB of hard disk space. While compiling, Buildroot 72 | *only updates files stored* in the output 73 | directory. Thus, removing this directory (and sub-directories) will 74 | return to the original Buildroot configuration. All software related to 75 | the host computer – Intel x86/AMD64 architecture most of the time – is 76 | located in output/host, while all software related to the 77 | target (here ARM architecture) is stored in output/target. 78 | We shall not be interested in the content of the directory in which 79 | source files are stored but might have to erase some of its content to 80 | force re-compilation: such files are stored in the 81 | output/build directory. Finally, the last compilation stage 82 | will result in a complete image including bootloader, kernel, libraries 83 | and userspace applications: this file is stored in 84 | output/images. 85 | 86 | After completing buildroot compilation, we find in the 87 | output/images directory the file sdcard.img 88 | which holds the binary datastream (about 150 MB) to be stored on the 89 | microSD card holding the operating system to be run on the RPi. Here, 90 | “stored” doe not mean copying since we must clone each byte from the 91 | binary file to the storage medium. Such an operation is achieved under 92 | GNU/Linux with the Disk Dump dd command. 93 | 94 | /!\ The following line might definitely **corrupt a 95 | hard disk** if the wrong storage medium is selected. Alway 96 | **check** the name of the peripheral associated with the SD 97 | card (`dmesg | tail`) before running the dd command. 98 | 99 | The image resulting from Buildroot compilation is transfered to the 100 | microSD card with 101 | 102 |
103 | 104 | sudo dd if=output/images/sdcard.img of=/dev/sdc 105 | 106 |
107 | 108 | 109 | where we have on purpose selected the /dev/sdc peripheral 110 | name in this example since it is ever hardly used. Usually, the microSD 111 | card is accessed as /dev/sdb (second hard disk storage 112 | medium compatible with the Linux SCSI driver) or 113 | /dev/mmcblk0 (internal SD medium interface). 114 | 115 | In case a Desktop Manager or a File Manager is used, make sure the SD 116 | card is unmounted before executing dd, as these tools will 117 | interfere with the cloning process. 118 | 119 | Once the image has been flashed on the SD card, we can see two 120 | partitions: the first one is a VFAT (format compatible with Microsoft 121 | Windows) with the devicetree, the Linux kernel and the bootloader, and a 122 | second one holding the GNU/Linux userspace filesystem 123 | (rootfs). 124 | 125 | # Adding custom packages (GNU Radio and PlutoSDR/UHD 126 | 127 | So far we have compiled a standard Buildroot image without dedicated GNU 128 | Radio support. Dedicated packages not selected in the default 129 | configuration can be activated. This is achieved from the Buildroot 130 | directory with make menuconfig and selecting Target 131 | packages. Searching (“/” command as in vi) allows 132 | for quickly finding the appropriate package, such as GNU Radio. 133 | 134 | Up to now we have only worked with “official” Buildroot packages 135 | properly maintained by the Buildroot community. Some packages are not 136 | yet integrated in the official repository but can nevertheless be 137 | appended as external packages thanks to the BR2\_EXTERNAL 138 | mechanism. As an example of supporting the PlutoSDR thanks to 139 | gr-iio, this support is available thanks to the 140 | BR2\_EXTERNAL repository found at 141 | and most significantly its 142 | for\_next branch. Hence, after going to any directory out 143 | of the Buildroot source tree: 144 | 145 | 1. `git clone https://github.com/oscimp/PlutoSDR` 146 | 147 | 2. `cd PlutoSDR` 148 | 149 | 3. `git checkout for_next` 150 | 151 | 4. `source sourceme.ggm` 152 | 153 | Now that the BR2\_EXTERNAL has been cloned, the appropriate 154 | branch selected, and the environment variables set (last command), 155 | return in the Buildroot directory and make menuconfig. 156 | Running make menuconfig will now show a new menu named 157 | External options including gr-iio, 158 | libuhd or gnss-sdr. 159 | 160 | 1. `make menuconfig` 161 | 162 | 2. `/eudev` 163 | 164 | 3. Select the last item indicating 165 | BR2\_ROOTFS\_DEVICE\_CREATION\_DYNAMIC\_EUDEV and 166 | replace /dev management with Dynamic using 167 | devtmpfs + eudev 168 | 169 | 4. `/python3` 170 | 171 | 5. Select item (4) indicating BR2\_PACKAGE\_PYTHON3 172 | 173 | 6. `/gnuradio` 174 | 175 | 7. Select item (1) indicating BR2\_PACKAGE\_GNURADIO 176 | 177 | 8. Select additional GNU Radio functionalities as needed (we will need 178 | gr-zeromq support and python support) 179 | 180 | 9. `/osmosdr` 181 | 182 | 10. Select BR2\_PACKAGE\_GR\_OSMOSDR (with Python support 183 | and Osmocom RTLSDR support) 184 | 185 | 11. in External options select uhd and for the 186 | B210 b200 support and python API support, 187 | 188 | 12. in External options select gr-iio for 189 | PlutoSDR support. 190 | 191 | The resulting file will be about 550 MB, requiring increasing the 192 | configuration in .config with 193 | BR2\_TARGET\_ROOTFS\_EXT2\_SIZE="420M". 194 | 195 | Tuning the configuration prior to dd the SD card is 196 | possible by adding files in output/target, e.g. a 197 | etc/network/interfaces network configuration with a static 198 | IP for example, or copying the USRP firmware from the host PC in the 199 | usr/share/uhd/images subdirectory of 200 | output/target for these files to be available later on the 201 | target embedded board. After tuning the content of 202 | output/target, execute make in the Buildroot 203 | directory to re-build the output/images/sdcard.img file. 204 | 205 | # GNU Radio on RPi 206 | 207 | As a demonstration of the proper operation of GNU Radio on the embedded 208 | board, we generate using GNU Radio Companion on the host computer a 209 | command line interface (“No GUI”) processing flow since obviously no 210 | graphical interface is running on the embedded target, and will execute 211 | the resulting Python3 script on the Raspberry Pi. The audio stream 212 | resulting from broadcast FM demodulation will be streamed to the host PC 213 | for playing on the sound card. 214 | 215 | On the host computer, run GNU Radio Companion (as part of GNU Radio 3.8) 216 | and generate the following chart: 217 | 218 | ![image](target.png) 219 | 220 | The generated Python script will be transfered and run on the RPi 221 | platform. Make sure to adapt the 0-MQ TCP IP address to the RPi address: 222 | the server is running on the embedded board and being a 223 | Publish-Subscribe (like UDP broadcast) configuration, any client 224 | connecting to the server running on the embedded board will be streamed 225 | the dataflow. The IP address must match the subnet of the host PC for 226 | easier routing configuration, and the port might be anything above 1024. 227 | The only constraints on this flowgraph is to achieve a final sampling 228 | rate matching the PC sound card sampling rate (here 48 kHz) following an 229 | integer decimation, here tuned with an initial sampling rate of 230 | \(48\time 24\) kS/s. The first low-pass filter selects a unique FM 231 | broadcast station while still keeping enough bandwidth (\(\geq\)200 kHz) 232 | for wideband FM demodulation, and the FM demodulator add the second 233 | decimation stage. 234 | 235 | # Communication RPi to PC 236 | 237 | After processing the raw RF (I/Q) signal collected from the FM broadcast 238 | band by the RPi, and preprocessing FM demodulation on the embedded 239 | target board, the audio stream is sent PC over 0-MQ. 240 | 241 | ![image](host.png) ![image](IMG_20200527_211928small.jpg) Left: client 242 | flowchart, fetching a 0-MQ subscribe datastream and feeding the sound 243 | card of the host PC. Right: experimental testbed, with the RPi4 244 | connected though virtual serial port and Ethernet to the laptop PC. The 245 | RPi4 collects an I/Q stream from the DVB-T dongle tuned to an 246 | FM-broadcast station, streams the demodulated audio flow to the PC, 247 | allowing to listen to the program on the headset connected to the sound 248 | card output. Not heard on this figure is the excellent sound quality 249 | heard on the headset, demonstrating perfect functional capability of 250 | this setup. 251 | 252 | # Software development 253 | 254 | We are interested in tuning the gnss-sdr functionalities. 255 | The source code of the software has been downloaded in the 256 | output/build directory if selected and installed. The build 257 | directory for the target system is found in 258 | output/build/gnss-sdr-0.0.13/buildroot-build/ while a 259 | separate output/build/gnss-sdr-0.0.13/build allows for 260 | simultaneously testing source code modifications on the host PC. The 261 | output of compiling (make), either in 262 | buildroot-build (ARM target) or build (x86 263 | target), is found in src/main/gnss-sdr. 264 | -------------------------------------------------------------------------------- /doc/danger.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/doc/danger.pdf -------------------------------------------------------------------------------- /doc/gnuradio_on_RPi_English.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/doc/gnuradio_on_RPi_English.pdf -------------------------------------------------------------------------------- /doc/gnuradio_on_RPi_English.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper]{article} 2 | \usepackage{color} 3 | \definecolor{grey}{rgb}{0.95,0.95,0.95} 4 | \definecolor{keyword}{rgb}{0,0,0.95} 5 | \definecolor{comment}{rgb}{0.95,0,0} 6 | \definecolor{string}{rgb}{0,0.65,00.65} 7 | 8 | \usepackage{listings} 9 | \lstset{backgroundcolor=\color{grey}, 10 | language=C, 11 | numbers=left, 12 | numbersep=6pt, 13 | basicstyle=\small\ttfamily, 14 | extendedchars=true, 15 | tabsize=3, 16 | keywordstyle=\color{keyword}\bfseries, 17 | commentstyle=\color{comment}, 18 | stringstyle=\color{string}\itshape, 19 | columns=fullflexible, 20 | keepspaces=true, 21 | } 22 | \usepackage{fullpage,graphicx,url} 23 | \begin{document} 24 | \begin{center} 25 | {\bf\Large Buildroot for cross-compiling GNU Radio to embedded boards}\\ 26 | \today 27 | \end{center} 28 | The Raspberry Pi\{3,4\} (RPi) is a single board computer designed -- for the characteristics 29 | we are interested in for Software Defined Radio applications -- around a 30 | quad-core ARM processor clocked at 1.5~GHz with 1, 2 or 4~GB random access memory. 31 | The operating system is stored on a microSD card and is hence easily updated 32 | from the host computer (never {\em ever} compile on the target embedded board). Generating 33 | a dedicated toolchain -- as opposed to using a readily available binary distribution -- 34 | allows for optimizing instructions for the chipset available on the targeted platform. 35 | 36 | Our objective is to {\bf execute GNU Radio on the RPi} in order to run some 37 | pre-processing on the embedded board before sending the processing result to 38 | the PC (e.g. receiving a broadcast FM station on the RPi and send the audio 39 | output to the PC through a Zero-MQ link). 40 | 41 | \section{Buildroot for RPi} 42 | 43 | Buildroot is a framework providing a consistent set of 44 | \begin{itemize} 45 | \item cross-compilation toolchain for the host (usually Intel x86/AMD64 processor) 46 | \item libraries and userspace applications for the ARM target, 47 | \item Linux kernel for the target, 48 | \item bootloader for embedded target board initialization in order to load the Linux 49 | kernel in charge of supervizing userspace applications. 50 | \end{itemize} 51 | 52 | This consistency avoids many pitfalls when cross-compiling target applications 53 | or kernel modules on the host. Obviously the low-computational power target is 54 | {\em not} designed for intensive computational load such as compiling GNU Radio, and 55 | {\tt gcc} should actually not even be available on the target, neither is the SD 56 | card with its finite number of write cycles designed for large compilation (at least 57 | make {\tt /tmp/} a RAM filesystem if trying such a compiltion on the target). 58 | 59 | Installing the result of Buildroot cross-compilation on the Raspberry Pi4 is 60 | described at \url{https://github.com/buildroot/buildroot/tree/master/board/raspberrypi} but 61 | the documentation on this web page is not up to date (?!): 62 | \begin{enumerate} 63 | \item {\tt git clone https://git.busybox.net/buildroot} 64 | \item {\tt cd buildroot} 65 | \item {\tt make raspberrypi4\_64\_defconfig} 66 | \end{enumerate} 67 | fetches the Buildroot archive, and configures for the RaspberryPi4 in 64~bit mode (obviously 68 | for RPi3, select {\tt raspberrypi3\_64\_defconfig}). 69 | Because Python support for GNU Radio will require the {\tt glibc} library rather than the default 70 | {\tt uClibc}, we must tune the default configuration 71 | \begin{enumerate} 72 | \setcounter{enumi}{3} 73 | \item {\tt make menuconfig} 74 | \item Toolchain $\rightarrow$ C library (uClibc-ng) $\rightarrow$ glibc 75 | \item Exit 76 | \end{enumerate} 77 | 78 | Once the proper C-library has been selected 79 | \begin{enumerate} 80 | \setcounter{enumi}{6} 81 | \item {\tt make} 82 | \end{enumerate} 83 | builds all tools 84 | needed for cross-compilation. This operation will take about 40~min on an 8-core 2.33~GHz Xeon 85 | CPU with fast internet connexion and require 7.4~GB of hard disk space. While compiling, 86 | Buildroot {\em only updates files stored} in the 87 | {\tt output} directory. Thus, removing this directory (and sub-directories) will return to 88 | the original Buildroot configuration. All software related to the host computer -- Intel x86/AMD64 89 | architecture most of the time -- is located in {\tt output/host}, while all software related 90 | to the target (here ARM architecture) is stored in {\tt output/target}. We shall not be 91 | interested in the content of the directory in which source files are stored but might have 92 | to erase some of its content to force re-compilation: such files are stored in the {\tt output/build} 93 | directory. Finally, the last compilation stage will result in a complete image including bootloader, 94 | kernel, libraries and userspace applications: this file is stored in {\tt output/images}. 95 | 96 | After completing buildroot compilation, we find in the {\tt output/images} directory 97 | the file {\tt sdcard.img} which 98 | holds the binary datastream (about 150~MB) to be stored on the microSD card holding the 99 | operating system to 100 | be run on the RPi. Here, ``stored'' doe not mean copying since we must clone each byte from 101 | the binary file to the storage medium. Such an operation is achieved under GNU/Linux with the 102 | Disk Dump {\tt dd} command. 103 | 104 | \includegraphics[width=.7cm]{danger} 105 | The following line might definitely {\bf corrupt a hard disk} if the wrong storage 106 | medium is selected. Alway {\bf check} the name of the peripheral associated with 107 | the SD card (\verb~dmesg | tail~) before running the {\tt dd} command. 108 | 109 | The image resulting from Buildroot compilation is transfered to the microSD card with\\ 110 | \colorbox{white}{\begin{minipage}{0.9\textwidth} 111 | sudo dd if=output/images/sdcard.img of=/dev/sdc 112 | \end{minipage}} \\ 113 | where we have on purpose selected the {\tt /dev/sdc} peripheral name in this example 114 | since it is ever hardly used. Usually, the microSD card is accessed as {\tt /dev/sdb} 115 | (second hard disk storage medium compatible with the Linux SCSI driver) 116 | or {\tt /dev/mmcblk0} (internal SD medium interface). 117 | 118 | In case a Desktop Manager or a File Manager is used, make sure the SD card is unmounted 119 | before executing {\tt dd}, as these tools will interfere with the cloning process. 120 | 121 | \noindent\fbox{\parbox{\linewidth}{ 122 | \includegraphics[width=.7cm]{danger} %\danger 123 | {\bf Warning}: the content of the SD card, or any storage medium associated with 124 | the last argument of this command, will be {\bf definitely} lost. Make sure, double check, 125 | the name of the peripheral on which the Buildroot image will be stored.}} 126 | 127 | Once the image has been flashed on the SD card, we can see two partitions: the first one 128 | is a VFAT (format compatible with Microsoft Windows) with the devicetree, the Linux 129 | kernel and the bootloader, and a second one holding the GNU/Linux userspace filesystem 130 | ({\tt rootfs}). 131 | 132 | This basic image is missing basic functionalities such as secure network connection over 133 | {\tt ssh} or text editing on the remote target. We find most convenient to activate 134 | {\tt Target Packages}$\rightarrow${\tt Text editors and viewers}$\rightarrow${\tt nano} as 135 | text editor, {\tt Target Packages}$\rightarrow${\tt Shell and utilities}$\rightarrow${\tt screen} 136 | and {\tt Target Packages}$\rightarrow${\tt Networking applications}$\rightarrow${\tt dropbear} 137 | as {\tt ssh} server. Since Dropbear expects a password when logging in the target system, 138 | we must define the {\tt root} password (and not leave it empty as is the default configuration) 139 | using {\tt System configuration}$\rightarrow${\tt Root password} 140 | 141 | \section{Adding packages (GNU Radio)} 142 | 143 | So far we have compiled a standard Buildroot image without dedicated GNU Radio support. 144 | Dedicated packages not selected in the default configuration can be activated. This is 145 | achieved from the Buildroot directory with {\tt make menuconfig} and selecting {\tt Target 146 | packages}. Searching (``/'' command as in {\tt vi}) allows for quickly finding the appropriate 147 | package, such as GNU Radio. 148 | 149 | \begin{enumerate} 150 | \item \verb~make menuconfig~ 151 | \item \verb~/eudev~ 152 | \item Select the last item indicating {\tt BR2\_ROOTFS\_DEVICE\_CREATION\_DYNAMIC\_EUDEV} and 153 | replace {\tt /dev management} with {\tt Dynamic using devtmpfs + eudev} 154 | \item \verb~/python3~ 155 | \item Select item (4) indicating {\tt BR2\_PACKAGE\_PYTHON3} 156 | \item \verb~/gnuradio~ 157 | \item Select item (1) indicating {\tt BR2\_PACKAGE\_GNURADIO} 158 | \item Select additional GNU Radio functionalities as needed (we will need {\tt gr-zeromq support} 159 | and {\tt python support}) 160 | \item \verb~/osmosdr~ 161 | \item Select {\tt BR2\_PACKAGE\_GR\_OSMOSDR} (with Python support and Osmocom RTLSDR support) 162 | \end{enumerate} 163 | 164 | The resulting file will be about 550~MB, requiring increasing the configuration in {\tt .config} 165 | with {\tt BR2\_TARGET\_ROOTFS\_EXT2\_SIZE="1000M"}. 166 | 167 | Tuning the configuration prior to {\tt dd} the SD card is possible by adding files 168 | in {\tt output/target}, e.g. a {\tt etc/network/interfaces} network configuration with 169 | a static IP for example, or copying the USRP firmware from the host PC in the 170 | {\tt usr/share/uhd/images} subdirectory of {\tt output/target} for these files to be 171 | available later on the target embedded board. After tuning the content of {\tt output/target}, 172 | execute {\tt make} in the Buildroot directory to re-build the {\tt output/images/sdcard.img} 173 | file. 174 | 175 | Finally, a graphical display of Python processing results can be activated using 176 | {\tt matplotlib} which depends on Qt5: first activate {\tt BR2\_PACKAGE\_QT5} (accessible 177 | from {\tt Graphic libraries and applications} in {\tt Target packages}): now the 178 | {\tt qt display} option from {\tt python-matplotlib} in {\tt External python modules} is 179 | active and both should be selected. 180 | 181 | \section{Adding custom packages (gnss-sdr, PlutoSDR/UHD)} 182 | 183 | Up to now we have only worked with ``official'' Buildroot packages properly maintained by 184 | the Buildroot community. Some packages are not yet integrated in the official repository 185 | but can nevertheless be appended as external packages thanks to the {\tt BR2\_EXTERNAL} 186 | mechanism. As an example of supporting the PlutoSDR thanks to {\tt gr-iio}, this support 187 | is available thanks to the {\tt BR2\_EXTERNAL} repository found at 188 | \url{https://github.com/oscimp/PlutoSDR} and most significantly its {\tt for\_next} branch. 189 | Hence, after going to any directory out of the Buildroot source tree: 190 | \begin{enumerate} 191 | \item \verb~git clone https://github.com/oscimp/PlutoSDR~ 192 | \item \verb~cd PlutoSDR~ 193 | \item \verb~git checkout for_next~ 194 | \item \verb~source sourceme.ggm~ 195 | \end{enumerate} 196 | 197 | Now that the {\tt BR2\_EXTERNAL} has been cloned, the appropriate branch selected, and the 198 | environment variables set (last command), return to the Buildroot directory and 199 | {\tt make menuconfig}. Running {\tt make menuconfig} will now show a new menu named 200 | {\tt External options} including 201 | {\tt gr-iio}, {\tt libuhd}: 202 | \begin{itemize} 203 | \item in {\tt External options} select {\tt uhd} and for the B210 {\tt b200 support} and 204 | {\tt python API support}, 205 | \item in {\tt External options} select {\tt gr-iio} for PlutoSDR support. 206 | \end{itemize} 207 | 208 | Including {\tt gnss-sdr} requires activating Fortran in the Toolchain options for compiling 209 | Lapack which as needed for Armadillo, a dependence to {\tt gnss-sdr} ({\tt clapack} will not work 210 | with {\tt gnss-sdr}). 211 | 212 | Controlling the Raspberry Pi 4 GPIO is most easily achieved using the PiGPIO library, whose 213 | functioalitities are activated by setting {\tt PIGPIO} and {\tt PYTHON3\_PIGPIO} for calling 214 | from Python3 scripts. 215 | 216 | \section{GNU Radio on RPi} 217 | 218 | As a demonstration of the proper operation of GNU Radio on the embedded board, we 219 | generate using GNU Radio Companion on the host computer a command line interface (``No GUI'') processing flow 220 | since obviously no graphical interface is running on the embedded target, and will execute 221 | the resulting Python3 script on the Raspberry Pi. The audio stream resulting from broadcast 222 | FM demodulation will be streamed to the host PC for playing on the sound card. 223 | 224 | On the host computer, run GNU Radio Companion (as part of GNU Radio 3.8) and generate 225 | the following chart: 226 | 227 | \includegraphics[width=\linewidth]{target} 228 | 229 | The generated Python script will be transfered and run on the RPi platform. Make sure 230 | to adapt the 0-MQ TCP IP address to the RPi address: the server is running on the embedded board 231 | and being a Publish-Subscribe (like UDP broadcast) configuration, any client connecting to 232 | the server running on the embedded board will be streamed the dataflow. The IP address must 233 | match the subnet of the host PC for easier routing configuration, and the port might be 234 | anything above 1024. The only constraints on this flowgraph is to achieve a final sampling 235 | rate matching the PC sound card sampling rate (here 48~kHz) following an integer decimation, 236 | here tuned with an initial sampling rate of $48\time 24$~kS/s. The first low-pass filter selects 237 | a unique FM broadcast station while still keeping enough bandwidth ($\geq$200~kHz) for 238 | wideband FM demodulation, and the FM demodulator add the second decimation stage. 239 | 240 | \section{Communication RPi to PC} 241 | 242 | After processing the raw RF (I/Q) signal collected from the FM broadcast band 243 | by the RPi, 244 | and preprocessing FM demodulation on the embedded target board, the audio stream is 245 | sent PC over 0-MQ. 246 | 247 | \begin{center} 248 | \includegraphics[width=.65\linewidth]{host} 249 | \includegraphics[width=.33\linewidth]{IMG_20200527_211928small.jpg} 250 | \footnotesize{Left: client flowchart, fetching a 0-MQ subscribe datastream and feeding 251 | the sound card of the host PC. Right: experimental testbed, with the RPi4 connected 252 | though virtual serial port and Ethernet to the laptop PC. The RPi4 collects an I/Q stream 253 | from the DVB-T dongle tuned to an FM-broadcast station, streams the demodulated audio 254 | flow to the PC, allowing to listen to the program on the headset connected to the sound card 255 | output. Not heard on this figure is the excellent sound quality heard on the headset, demonstrating 256 | perfect functional capability of this setup.} 257 | \end{center} 258 | 259 | \section{Software development} 260 | 261 | We are interested in tuning the {\tt gnss-sdr} functionalities. The source code of 262 | the software has been downloaded in the {\tt output/build} directory if 263 | selected and installed. The build directory 264 | for the target system is found in \\ 265 | {\tt output/build/gnss-sdr-0.0.12/buildroot-build/} 266 | \\while 267 | a separate {\tt output/build/gnss-sdr-0.0.12/build} allows for simultaneously testing source 268 | code modifications on the host PC. The output of compiling ({\tt make}), either in 269 | {\tt buildroot-build} (ARM target) or {\tt build} (x86 target), is found in {\tt 270 | src/main/gnss-sdr}. 271 | \end{document} 272 | -------------------------------------------------------------------------------- /doc/gnuradio_sur_RPi4_Francais.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/doc/gnuradio_sur_RPi4_Francais.pdf -------------------------------------------------------------------------------- /doc/gnuradio_sur_RPi4_Francais.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper]{article} 2 | \usepackage{color} 3 | \definecolor{grey}{rgb}{0.95,0.95,0.95} 4 | \definecolor{keyword}{rgb}{0,0,0.95} 5 | \definecolor{comment}{rgb}{0.95,0,0} 6 | \definecolor{string}{rgb}{0,0.65,00.65} 7 | 8 | \usepackage{listings} 9 | \lstset{backgroundcolor=\color{grey}, 10 | language=C, 11 | numbers=left, 12 | numbersep=6pt, 13 | basicstyle=\small\ttfamily, 14 | extendedchars=true, 15 | tabsize=3, 16 | keywordstyle=\color{keyword}\bfseries, 17 | commentstyle=\color{comment}, 18 | stringstyle=\color{string}\itshape, 19 | columns=fullflexible, 20 | keepspaces=true, 21 | } 22 | 23 | \usepackage[french]{babel} 24 | 25 | \usepackage{fullpage,graphicx,url} 26 | \begin{document} 27 | \begin{center} 28 | {\bf\Large Buildroot pour la compilation crois\'ee de GNU Radio pour plateformes 29 | embarqu\'ees} 30 | \end{center} 31 | 32 | La Raspberry Pi \{3,4\} (RPi) est un ordinateur architectur\'e (pour les 33 | caract\'eristiques nous int\'eressant en radio logicielle) autour 34 | d'un processeur quad-c\oe urs ARM cadenc\'es \`a 1,5~GHz avec 1,2 ou 4~GB 35 | de m\'emoire volatile. Le syst\`eme d'exploitation est stock\'e sur 36 | carte uSD et sera donc simple \`a mettre \`a jour depuis un ordinateur (ne 37 | {\em jamais} compiler sur la cible embarqu\'ee). La g\'en\'eration d'une cha\^\i ne 38 | de compilation d\'edi\'ee -- contrairement \`a l'utilisation d'une distribution 39 | binaire -- permet d'optimiser le jeu d'instructions pour le processeur sp\'ecifique 40 | \`a la cible consid\'er\'ee. 41 | 42 | Notre objectif va \^etre d'{\bf ex\'ecuter GNU Radio sur RPi4} en vue d'effectuer 43 | un certain nombre de traitements sur la plateforme embarqu\'ee avant d'en envoyer 44 | le r\'esultat vers le PC (exemple~: recevoir une station FM sur la RPi et envoyer 45 | par une communication Zero-MQ le signal audio vers le PC). 46 | 47 | \section{Buildroot pour RPi} 48 | 49 | Buildroot est un environnement fournissant un ensemble coh\'erent de 50 | \begin{itemize} 51 | \item cha\^\i ne de compilation crois\'ee sur l'h\^ote ({\em host} Intel x86) 52 | \item biblioth\`eques et applications en espace utilisateur sur la cible ({\em target} ARM) 53 | \item noyau Linux sur la cible 54 | \item {\em bootloader} (s\'equence de d\'emarrage) pour initialiser le processeur et 55 | ses p\'eriph\'eriques sur la cible en vue de charger le noyau Linux qui supervisera les 56 | applications en espace utilisateur. 57 | \end{itemize} 58 | 59 | Cette coh\'erence \'evite bien des d\'eboires lors de la compilation sur l'h\^ote d'applications 60 | ou module noyau pour la cible (on ne compile {\bf jamais} sur la cible de ressources r\'eduites 61 | et dont la vocation est de contr\^oler un syst\`eme embarqu\'e et non d'\^etre muni d'un compilateur 62 | aussi lourd et complexe que {\tt gcc}). 63 | 64 | Pour installer Buildroot sur Raspberry Pi 4, tel que d\'ecrit \`a 65 | \url{https://github.com/buildroot/buildroot/tree/master/board/raspberrypi} mais la 66 | documentation de cette page n'est pas \`a jour (?!)~: 67 | \begin{enumerate} 68 | \item {\tt git clone https://github.com/buildroot/buildroot} 69 | \item {\tt cd buildroot} 70 | \item {\tt make raspberrypi4\_64\_defconfig} 71 | \end{enumerate} 72 | qui r\'ecup\`ere l'arborescence de Buildroot, et la configure pour la RaspberryPi4 en mode 64~bits (pour 73 | la RPi3, s\'electionner {\tt raspberrypi3\_64\_defconfig}). Puisque le support Python de GNU Radio n\'ecessitera 74 | la biblioth\`eque {\tt glibc} au lieu de {\tt uClibc} s\'electionn\'ee par d\'efaut, nous ajustons la 75 | configuration initiale par 76 | \begin{enumerate} 77 | \setcounter{enumi}{3} 78 | \item {\tt make menuconfig} 79 | \item Toolchain $\rightarrow$ C library (uClibc-ng) $\rightarrow$ glibc 80 | \item Exit 81 | \end{enumerate} 82 | Une fois la bonne biblioth\`eque s\'electionn\'ee 83 | \begin{enumerate} 84 | \setcounter{enumi}{6} 85 | \item {\tt make} 86 | \end{enumerate} 87 | compile l'ensemble des outils. Cette op\'eration prend environ 40~minutes sur un processeur Xeon \`a 8 c\oe urs 88 | cadenc\'es \`a 2,33~GHz avec une connexion internet rapide, et occupe environ 7.4~GB sur le disque dur. 89 | Au cours de la compilation, Buildroot n'affecte {\em que les fichiers contenus 90 | dans le r\'epertoire} {\tt output}. Ainsi, effacer ce r\'epertoire (et ses sous-r\'epertoires) 91 | permet de repartir d'une version propre de Buildroot. Dans {\tt output}, tout ce qui est 92 | relatif \`a l'h\^ote x86 se trouve dans {\tt host}, tout ce qui est relatif \`a la cible dans 93 | {\tt target}. Nous n'aurons pas ici besoin de regarder le contenu du r\'epertoire contenant 94 | les sources des outils compil\'es mais serons susceptibles d'en effacer certains contenus pour 95 | en forcer la recompilation dans {\tt build}. Enfin pour ce qui nous int\'eresse maintenant, 96 | le r\'esultat de la compilation se trouve dans {\tt images}. 97 | 98 | Dans ce r\'epertoire {\tt output/images}, nous trouvons {\tt sdcard.img} qui est l'image 99 | \`a transf\'erer sur la carte uSD en vue d'en ex\'ecuter le contenu sur RPi. Ici, 100 | ``transf\'erer'' ne signifie par copier car nous devons \'ecrire octet par octet le 101 | contenu du fichier .img sur la carte. Cette op\'eration est prise en charge sous GNU/Linux 102 | par {\tt dd}. 103 | 104 | \includegraphics[width=.7cm]{danger} 105 | La ligne qui va suivre peut {\bf corrompre le disque dur} si le 106 | mauvais p\'eriph\'erique est s\'electionn\'e. Toujours {\bf v\'erifier} le 107 | nom du p\'eriph\'erique associ\'e \`a la carte SD (\verb~dmesg | tail~) avant 108 | de lancer la commande {\tt dd}. 109 | 110 | L'image r\'esultant de la compilation est transf\'er\'ee sur la carte SD par\\ 111 | \colorbox{white}{\begin{minipage}{0.9\textwidth} 112 | sudo dd if=output/images/sdcard.img of=/dev/sdc 113 | \end{minipage}} \\ 114 | o\`u nous avons volontairement choisi le p\'eriph\'erique {\tt /dev/sdc} dans cet 115 | exemple car rarement utilis\'e~: en pratique, la carte SD sera souvent 116 | nomm\'ee {\tt /dev/sdb} (second disque dur compatible avec le pilote SCSI de 117 | Linux) ou {\tt /dev/mmcblk0} (cas du lecteur SD interne). 118 | 119 | En cas d'utilisation d'un gestionnaire de fichiers ou de bureau, bien v\'erifier 120 | que la carte SD n'est pas prise en charge par ces outils ({\em eject}) qui risquent 121 | d'interf\'erer avec {\tt dd}. 122 | 123 | \noindent\fbox{\parbox{\linewidth}{ 124 | \includegraphics[width=.7cm]{danger} %\danger 125 | {\bf Attention}~: le contenu de la 126 | carte SD, ou de tout support point\'e par le dernier argument de cette 127 | commande, sera {\bf irr\'em\'ediablement} perdu. V\'erifier \`a deux fois le 128 | nom du p\'eriph\'erique cible de l'image issue de buildroot.}} 129 | 130 | Une fois l'image flash\'ee sur la carte SD, nous constaterons deux partitions~: une 131 | premi\`ere en VFAT (format compatible Microsoft Windows) avec le devicetree, le noyau 132 | Linux et le bootloader, et une seconde partition contenant le syst\`eme GNU/Linux ({\tt 133 | rootfs}) 134 | 135 | \section{Ajouter des packages~: {\tt BR2\_EXTERNAL}} 136 | 137 | Pour le moment nous avons compil\'e une image standard Buildroot sans support de 138 | GNU Radio. Ces paquets d\'edi\'es ne sont pas s\'electionn\'es par d\'efaut mais 139 | peuvent \^etre activ\'es. Pour ce faire, ex\'ecuter dans le r\'epertoire de Buildroot 140 | la commande {\tt make menuconfig} et s\'electionner {\tt Target 141 | packages}. La recherche (``/'' comme dans {\tt vi}) permet de facilement trouver l'emplacement 142 | d'un paquet, par exemple GNU Radio. 143 | 144 | Jusqu'ici nous n'avons travaill\'e qu'avec les paquets Buildroot ``officiels'' maintenus 145 | par la communaut\'e des d\'eveloppeurs de Buildroot. Certains paquets ne sont pas encore 146 | int\'egr\'es sur le site officiel mais peuvent n\'eanmoins compl\'eter l'installation 147 | en cours gr\^ace au m\'ecanisme de {\tt BR2\_EXTERNAL}. Un exemple est le support 148 | de la PlutoSDR gr\^ace \`a {\tt gr-iio}, qui est fourni dans le d\'ep\^ot {\tt BR2\_EXTERNAL} 149 | disponible \`a \url{https://github.com/oscimp/PlutoSDR} et plus sp\'ecifiquement dans la branche 150 | {\tt for\_next}. Ainsi, apr\`es \^etre sorti du r\'epertoire Buildroot pour cr\'eer une nouvelle 151 | arborescence~: 152 | \begin{enumerate} 153 | \item \verb~git clone https://github.com/oscimp/PlutoSDR~ 154 | \item \verb~cd PlutoSDR~ 155 | \item \verb~git checkout for_next~ 156 | \item \verb~source sourceme.ggm~ 157 | \end{enumerate} 158 | 159 | Maintenant que le d\'ep\^ot {\tt BR2\_EXTERNAL} a \'et\'e t\'el\'echarg\'e, la branche 160 | appropri\'ee s\'electionn\'ee, et les variables d'environnement d\'efinies (derni\`ere commande), 161 | retourner dans le r\'epertoire de Buildroot et 162 | {\tt make menuconfig}. L'ex\'ecution de {\tt make menuconfig} donne maintenant acc\`es \`a un nouveau menu 163 | {\tt External options} qui inclut 164 | {\tt gr-iio}, {\tt libuhd} ou {\tt gnss-sdr}. 165 | 166 | \begin{enumerate} 167 | \item \verb~make menuconfig~ 168 | \item \verb~/eudev~ 169 | \item S\'electionner la derni\`ere option indiqu\'ee par {\tt BR2\_ROOTFS\_DEVICE\_CREATION\_DYNAMIC\_EUDEV} et 170 | remplacer {\tt /dev management} par {\tt Dynamic using devtmpfs + eudev} 171 | \item \verb~/python3~ 172 | \item S\'electionner l'option (4) indiqu\'ee par {\tt BR2\_PACKAGE\_PYTHON3} 173 | \item \verb~/gnuradio~ 174 | \item S\'electionner l'option (1) indiqu\'ee par {\tt BR2\_PACKAGE\_GNURADIO} 175 | \item S\'electionner les options additionnelles de GNU Radio selon les besoins (nous aurons besoin 176 | de {\tt gr-zeromq support} et {\tt python support}) 177 | \item \verb~/osmosdr~ 178 | \item S\'electionner {\tt BR2\_PACKAGE\_GR\_OSMOSDR} (avec support Python et support Osmocom RTLSDR) 179 | \item dans {\tt External options} s\'electionner {\tt uhd} et pour la B210 {\tt b200 support} et 180 | {\tt python API support}, 181 | \item dans {\tt External options} s\'electionner {\tt gr-iio} si la PlutoSDR est utilis\'ee. 182 | \end{enumerate} 183 | 184 | Le fichier r\'esultant fera environ 550~MB, n\'ecessitant d'augmenter la taille disponible dans {\tt .config} 185 | par {\tt BR2\_TARGET\_ROOTFS\_EXT2\_SIZE="420M"}. 186 | 187 | Nous pouvons ajuster la configuration avant de {\tt dd} l'image sur la carte SD en ajoutant des fichiers 188 | dans {\tt output/target}, par exemple une configuration statique du r\'eseau dans {\tt etc/network/interfaces}, 189 | ou copier les {\em firmware} des USRPs depuis le PC h\^ote dans le sous r\'epertoire {\tt usr/share/uhd/images} 190 | de {\tt output/target} afin que ces fichiers soient ult\'erieurement disponibles sur la cible embarqu\'ee. Une fois 191 | le contenu de {\tt output/target} convenablement ajust\'e, retourner dans le r\'epertoire racine de Buildroot 192 | et ex\'ecuter {\tt make} pour r\'eg\'en\'erer le fichier {\tt output/images/sdcard.img}. 193 | 194 | \section{GNU Radio sur RPi} 195 | 196 | \`A titre d'illustration de la fa\c con que nous abordons d'utiliser GNU Radio sur plateforme 197 | embarqu\'ee, nous g\'en\'erons en utilisant GNU Radio Companion sur le PC une application 198 | en ligne de commande (``No GUI'') puisque \'evidemment aucune interface graphique ne devrait 199 | \^etre disponible sur la cible embarqu\'ee. Le script Python3 r\'esultant sera ex\'ecut\'e sur 200 | la RPi. Le flux audio-fr\'equence r\'esultant de la d\'emodulation du signal de la bande FM 201 | commerciale sera transmis au PC pour \^etre jou\'e sur la carte son. 202 | 203 | Sur le PC, lancer GNU Radio Companion (fourni par GNU Radio 3.8) et g\'en\'erer la cha\^\i ne 204 | de traitement suivante~: 205 | 206 | \includegraphics[width=\linewidth]{target} 207 | 208 | Le script Python ainsi g\'en\'er\'e est transf\'er\'e \`a la RPi. Bien prendre soin 209 | d'adapter l'adresse IP de la liaison TCP sur 0-MQ \`a l'adresse de la RPi~: le serveur 210 | est ex\'ecut\'e sur la plateforme embarqu\'ee et en utilisant une liaison de type 211 | Publish-Subscribe (s'apparentant \`a une liaison UDP), tout client se connectant au serveur 212 | ex\'ecut\'e sur la cible embarqu\'ee peut recevoir le flux de donn\'ees. L'adresse IP 213 | se incluse id\'ealement dans le sous-r\'eseau du PC pour simplifier la configuration 214 | du routage, tandis que le port peut \^etre toute valeur au dessus de 1024. La seule 215 | contrainte sur cette cha\^\i ne de traitement est d'aboutir \`a la fin \`a une 216 | fr\'equence d'\'echantillonnage \'egale \`a une valeur compatible avec la cartes son du 217 | PC (ici 48~kHz) apr\`es une s\'equence de d\'ecimations par des facteurs entiers 218 | s\'electionn\'ee ici par le choix d'une fr\'equence d'\'echantillonnage initiale de 219 | $48\time 24$~kS/s. Le premier filtre passe-bas s\'electionne une unique station FM 220 | tout en gardant assez de bande passante ($\geq$200~kHz) pour la d\'emodulation FM 221 | \`a bande large, et le d\'emodulateur FM ajoute un second \'etage de d\'ecimation. 222 | 223 | \section{Communication RPi vers PC} 224 | 225 | Apr\`es traitement des donn\'ees radiofr\'equences brutes (I/Q) acquises sur la bande 226 | FM commerciale par la RPi, et avoir pr\'e-trait\'e le signal FM sur la plateforme 227 | embarqu\'ee, le flux audio-fr\'equence est transmis vers le PC par 0-MQ. 228 | 229 | \begin{center} 230 | \includegraphics[width=.59\linewidth]{host} 231 | \includegraphics[width=.39\linewidth]{IMG_20200527_211928small.jpg} 232 | \footnotesize{Gauche~: cha\^\i ne de traitement du client, qui r\'ecup\`ere un flux au format 233 | {\em subscribe} de 0-MQ et alimente la carte son du PC. Droite~: montage exp\'erimental, 234 | avec une RPi4 connect\'ee par un port s\'erie virtuel et par Ethernet au PC portable. La 235 | RPi4 \'echantillonne le flux de coefficients I/Q du r\'ecepteur de t\'el\'evision num\'erique 236 | terrestre utilis\'e comme source de radio logicielle en ajustant sa fr\'equence dans la bande 237 | FM, et transmet le flux audio-fr\'equence apr\`es d\'emodulation au PC, permettant d'\'ecouter 238 | le programme gr\^ace \`a un casque connect\'e \`a la sortie de la carte son. Cette figure ne 239 | permet pas d'illustrer l'excellente qualit\'e audio entendue \`a la sortie de la carte son, 240 | d\'emontrant le bon fonctionnement de ce montage.} 241 | \end{center} 242 | 243 | \section{D\'eveloppements logiciels} 244 | 245 | Nous nous int\'eressons \`a modifier les fonctionnalit\'es de {\tt gnss-sdr}. Le code source 246 | de ce logiciel a \'et\'e t\'el\'echarg\'e et plac\'e dans le r\'epertoire {\tt output/build} lors 247 | de sa s\'election et installation. Le r\'epertoire de compilation pour la cible se trouve 248 | \`a {\tt output/build/gnss-sdr-0.0.12/buildroot-build/} tandis qu'un r\'epertoire s\'epar\'e 249 | {\tt output/build/gnss-sdr-0.0.12/build} permet de simultan\'ement tester les modifications aux 250 | codes sources sur le PC h\^ote. Le r\'esultat de la compilation ({\tt make}), soit dans 251 | {\tt buildroot-build} (cible ARM) ou {\tt build} (cible x86), se trouve dans {\tt 252 | src/main/gnss-sdr}. 253 | \end{document} 254 | -------------------------------------------------------------------------------- /doc/host.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/doc/host.pdf -------------------------------------------------------------------------------- /doc/host.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/doc/host.png -------------------------------------------------------------------------------- /doc/movie_FM_to_0MQstream.ogv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/doc/movie_FM_to_0MQstream.ogv -------------------------------------------------------------------------------- /doc/picture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/doc/picture.jpg -------------------------------------------------------------------------------- /doc/pluto_embedded.grc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tue Dec 4 18:43:20 2018 5 | 6 | options 7 | 8 | author 9 | 10 | 11 | 12 | window_size 13 | 14 | 15 | 16 | category 17 | [GRC Hier Blocks] 18 | 19 | 20 | comment 21 | 22 | 23 | 24 | description 25 | 26 | 27 | 28 | _enabled 29 | True 30 | 31 | 32 | _coordinate 33 | (8, 12) 34 | 35 | 36 | _rotation 37 | 0 38 | 39 | 40 | generate_options 41 | no_gui 42 | 43 | 44 | hier_block_src_path 45 | .: 46 | 47 | 48 | id 49 | top_block 50 | 51 | 52 | max_nouts 53 | 0 54 | 55 | 56 | qt_qss_theme 57 | 58 | 59 | 60 | realtime_scheduling 61 | 62 | 63 | 64 | run_command 65 | {python} -u {filename} 66 | 67 | 68 | run_options 69 | prompt 70 | 71 | 72 | run 73 | True 74 | 75 | 76 | sizing_mode 77 | fixed 78 | 79 | 80 | thread_safe_setters 81 | 82 | 83 | 84 | title 85 | 86 | 87 | 88 | placement 89 | (0,0) 90 | 91 | 92 | 93 | variable 94 | 95 | comment 96 | 97 | 98 | 99 | _enabled 100 | True 101 | 102 | 103 | _coordinate 104 | (280, 12) 105 | 106 | 107 | _rotation 108 | 0 109 | 110 | 111 | id 112 | freq 113 | 114 | 115 | value 116 | int(96.9e6) 117 | 118 | 119 | 120 | variable 121 | 122 | comment 123 | 124 | 125 | 126 | _enabled 127 | True 128 | 129 | 130 | _coordinate 131 | (184, 12) 132 | 133 | 134 | _rotation 135 | 0 136 | 137 | 138 | id 139 | samp_rate 140 | 141 | 142 | value 143 | 48000*24 144 | 145 | 146 | 147 | analog_sig_source_x 148 | 149 | amp 150 | 1 151 | 152 | 153 | alias 154 | 155 | 156 | 157 | comment 158 | 159 | 160 | 161 | affinity 162 | 163 | 164 | 165 | _enabled 166 | 0 167 | 168 | 169 | freq 170 | 50000 171 | 172 | 173 | _coordinate 174 | (200, 88) 175 | 176 | 177 | _rotation 178 | 0 179 | 180 | 181 | id 182 | analog_sig_source_x_0 183 | 184 | 185 | maxoutbuf 186 | 0 187 | 188 | 189 | minoutbuf 190 | 0 191 | 192 | 193 | offset 194 | 0 195 | 196 | 197 | type 198 | complex 199 | 200 | 201 | samp_rate 202 | samp_rate 203 | 204 | 205 | waveform 206 | analog.GR_COS_WAVE 207 | 208 | 209 | 210 | analog_wfm_rcv 211 | 212 | audio_decimation 213 | 8 214 | 215 | 216 | alias 217 | 218 | 219 | 220 | comment 221 | 222 | 223 | 224 | affinity 225 | 226 | 227 | 228 | _enabled 229 | True 230 | 231 | 232 | _coordinate 233 | (416, 272) 234 | 235 | 236 | _rotation 237 | 0 238 | 239 | 240 | id 241 | analog_wfm_rcv_0 242 | 243 | 244 | maxoutbuf 245 | 0 246 | 247 | 248 | minoutbuf 249 | 0 250 | 251 | 252 | quad_rate 253 | samp_rate/6 254 | 255 | 256 | 257 | blocks_null_sink 258 | 259 | alias 260 | 261 | 262 | 263 | bus_conns 264 | [[0,],] 265 | 266 | 267 | comment 268 | 269 | 270 | 271 | affinity 272 | 273 | 274 | 275 | _enabled 276 | True 277 | 278 | 279 | _coordinate 280 | (632, 256) 281 | 282 | 283 | _rotation 284 | 0 285 | 286 | 287 | id 288 | blocks_null_sink_0 289 | 290 | 291 | type 292 | float 293 | 294 | 295 | num_inputs 296 | 1 297 | 298 | 299 | vlen 300 | 1 301 | 302 | 303 | 304 | low_pass_filter 305 | 306 | beta 307 | 6.76 308 | 309 | 310 | alias 311 | 312 | 313 | 314 | comment 315 | 316 | 317 | 318 | affinity 319 | 320 | 321 | 322 | cutoff_freq 323 | 100000 324 | 325 | 326 | decim 327 | 6 328 | 329 | 330 | _enabled 331 | True 332 | 333 | 334 | type 335 | fir_filter_ccf 336 | 337 | 338 | _coordinate 339 | (216, 232) 340 | 341 | 342 | _rotation 343 | 0 344 | 345 | 346 | gain 347 | 1 348 | 349 | 350 | id 351 | low_pass_filter_0 352 | 353 | 354 | interp 355 | 1 356 | 357 | 358 | maxoutbuf 359 | 0 360 | 361 | 362 | minoutbuf 363 | 0 364 | 365 | 366 | samp_rate 367 | samp_rate 368 | 369 | 370 | width 371 | 100000 372 | 373 | 374 | win 375 | firdes.WIN_HAMMING 376 | 377 | 378 | 379 | pluto_sink 380 | 381 | attenuation 382 | 0 383 | 384 | 385 | alias 386 | 387 | 388 | 389 | buffer_size 390 | 0x8000 391 | 392 | 393 | comment 394 | 395 | 396 | 397 | affinity 398 | 399 | 400 | 401 | cyclic 402 | True 403 | 404 | 405 | _enabled 406 | 0 407 | 408 | 409 | auto_filter 410 | True 411 | 412 | 413 | filter 414 | 415 | 416 | 417 | _coordinate 418 | (384, 56) 419 | 420 | 421 | _rotation 422 | 0 423 | 424 | 425 | id 426 | pluto_sink_0 427 | 428 | 429 | uri 430 | local: 431 | 432 | 433 | frequency 434 | freq 435 | 436 | 437 | bandwidth 438 | 20000000 439 | 440 | 441 | samplerate 442 | samp_rate 443 | 444 | 445 | 446 | pluto_source 447 | 448 | bbdc 449 | True 450 | 451 | 452 | alias 453 | 454 | 455 | 456 | buffer_size 457 | 0x8000 458 | 459 | 460 | comment 461 | 462 | 463 | 464 | affinity 465 | 466 | 467 | 468 | uri 469 | local: 470 | 471 | 472 | _enabled 473 | True 474 | 475 | 476 | auto_filter 477 | True 478 | 479 | 480 | filter 481 | 482 | 483 | 484 | _coordinate 485 | (8, 96) 486 | 487 | 488 | _rotation 489 | 0 490 | 491 | 492 | gain 493 | "manual" 494 | 495 | 496 | id 497 | pluto_source_0 498 | 499 | 500 | frequency 501 | freq 502 | 503 | 504 | manual_gain 505 | 55 506 | 507 | 508 | maxoutbuf 509 | 0 510 | 511 | 512 | minoutbuf 513 | 0 514 | 515 | 516 | quadrature 517 | True 518 | 519 | 520 | rfdc 521 | True 522 | 523 | 524 | bandwidth 525 | 20000000 526 | 527 | 528 | samplerate 529 | samp_rate 530 | 531 | 532 | 533 | zeromq_pub_sink 534 | 535 | address 536 | tcp://0.0.0.0:5555 537 | 538 | 539 | alias 540 | 541 | 542 | 543 | comment 544 | 545 | 546 | 547 | affinity 548 | 549 | 550 | 551 | _enabled 552 | True 553 | 554 | 555 | _coordinate 556 | (632, 296) 557 | 558 | 559 | _rotation 560 | 0 561 | 562 | 563 | hwm 564 | -1 565 | 566 | 567 | id 568 | zeromq_pub_sink_0 569 | 570 | 571 | type 572 | float 573 | 574 | 575 | pass_tags 576 | False 577 | 578 | 579 | timeout 580 | 100 581 | 582 | 583 | vlen 584 | 1 585 | 586 | 587 | 588 | analog_sig_source_x_0 589 | pluto_sink_0 590 | 0 591 | 0 592 | 593 | 594 | analog_wfm_rcv_0 595 | blocks_null_sink_0 596 | 0 597 | 0 598 | 599 | 600 | analog_wfm_rcv_0 601 | zeromq_pub_sink_0 602 | 0 603 | 0 604 | 605 | 606 | low_pass_filter_0 607 | analog_wfm_rcv_0 608 | 0 609 | 0 610 | 611 | 612 | pluto_source_0 613 | low_pass_filter_0 614 | 0 615 | 0 616 | 617 | 618 | -------------------------------------------------------------------------------- /doc/pluto_pc.grc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tue Dec 4 20:54:47 2018 5 | 6 | options 7 | 8 | author 9 | 10 | 11 | 12 | window_size 13 | 14 | 15 | 16 | category 17 | [GRC Hier Blocks] 18 | 19 | 20 | comment 21 | 22 | 23 | 24 | description 25 | 26 | 27 | 28 | _enabled 29 | True 30 | 31 | 32 | _coordinate 33 | (8, 8) 34 | 35 | 36 | _rotation 37 | 0 38 | 39 | 40 | generate_options 41 | qt_gui 42 | 43 | 44 | hier_block_src_path 45 | .: 46 | 47 | 48 | id 49 | top_block 50 | 51 | 52 | max_nouts 53 | 0 54 | 55 | 56 | qt_qss_theme 57 | 58 | 59 | 60 | realtime_scheduling 61 | 62 | 63 | 64 | run_command 65 | {python} -u {filename} 66 | 67 | 68 | run_options 69 | prompt 70 | 71 | 72 | run 73 | True 74 | 75 | 76 | sizing_mode 77 | fixed 78 | 79 | 80 | thread_safe_setters 81 | 82 | 83 | 84 | title 85 | 86 | 87 | 88 | placement 89 | (0,0) 90 | 91 | 92 | 93 | variable 94 | 95 | comment 96 | 97 | 98 | 99 | _enabled 100 | True 101 | 102 | 103 | _coordinate 104 | (232, 12) 105 | 106 | 107 | _rotation 108 | 0 109 | 110 | 111 | id 112 | samp_rate 113 | 114 | 115 | value 116 | 48000/2 117 | 118 | 119 | 120 | audio_sink 121 | 122 | alias 123 | 124 | 125 | 126 | comment 127 | 128 | 129 | 130 | affinity 131 | 132 | 133 | 134 | device_name 135 | 136 | 137 | 138 | _enabled 139 | True 140 | 141 | 142 | _coordinate 143 | (232, 92) 144 | 145 | 146 | _rotation 147 | 0 148 | 149 | 150 | id 151 | audio_sink_0 152 | 153 | 154 | num_inputs 155 | 1 156 | 157 | 158 | ok_to_block 159 | True 160 | 161 | 162 | samp_rate 163 | samp_rate 164 | 165 | 166 | 167 | qtgui_time_sink_x 168 | 169 | autoscale 170 | False 171 | 172 | 173 | axislabels 174 | True 175 | 176 | 177 | alias 178 | 179 | 180 | 181 | comment 182 | 183 | 184 | 185 | ctrlpanel 186 | False 187 | 188 | 189 | affinity 190 | 191 | 192 | 193 | entags 194 | True 195 | 196 | 197 | _enabled 198 | True 199 | 200 | 201 | _coordinate 202 | (256, 160) 203 | 204 | 205 | gui_hint 206 | 207 | 208 | 209 | _rotation 210 | 0 211 | 212 | 213 | grid 214 | False 215 | 216 | 217 | id 218 | qtgui_time_sink_x_0 219 | 220 | 221 | legend 222 | True 223 | 224 | 225 | alpha1 226 | 1.0 227 | 228 | 229 | color1 230 | "blue" 231 | 232 | 233 | label1 234 | 235 | 236 | 237 | marker1 238 | -1 239 | 240 | 241 | style1 242 | 1 243 | 244 | 245 | width1 246 | 1 247 | 248 | 249 | alpha10 250 | 1.0 251 | 252 | 253 | color10 254 | "blue" 255 | 256 | 257 | label10 258 | 259 | 260 | 261 | marker10 262 | -1 263 | 264 | 265 | style10 266 | 1 267 | 268 | 269 | width10 270 | 1 271 | 272 | 273 | alpha2 274 | 1.0 275 | 276 | 277 | color2 278 | "red" 279 | 280 | 281 | label2 282 | 283 | 284 | 285 | marker2 286 | -1 287 | 288 | 289 | style2 290 | 1 291 | 292 | 293 | width2 294 | 1 295 | 296 | 297 | alpha3 298 | 1.0 299 | 300 | 301 | color3 302 | "green" 303 | 304 | 305 | label3 306 | 307 | 308 | 309 | marker3 310 | -1 311 | 312 | 313 | style3 314 | 1 315 | 316 | 317 | width3 318 | 1 319 | 320 | 321 | alpha4 322 | 1.0 323 | 324 | 325 | color4 326 | "black" 327 | 328 | 329 | label4 330 | 331 | 332 | 333 | marker4 334 | -1 335 | 336 | 337 | style4 338 | 1 339 | 340 | 341 | width4 342 | 1 343 | 344 | 345 | alpha5 346 | 1.0 347 | 348 | 349 | color5 350 | "cyan" 351 | 352 | 353 | label5 354 | 355 | 356 | 357 | marker5 358 | -1 359 | 360 | 361 | style5 362 | 1 363 | 364 | 365 | width5 366 | 1 367 | 368 | 369 | alpha6 370 | 1.0 371 | 372 | 373 | color6 374 | "magenta" 375 | 376 | 377 | label6 378 | 379 | 380 | 381 | marker6 382 | -1 383 | 384 | 385 | style6 386 | 1 387 | 388 | 389 | width6 390 | 1 391 | 392 | 393 | alpha7 394 | 1.0 395 | 396 | 397 | color7 398 | "yellow" 399 | 400 | 401 | label7 402 | 403 | 404 | 405 | marker7 406 | -1 407 | 408 | 409 | style7 410 | 1 411 | 412 | 413 | width7 414 | 1 415 | 416 | 417 | alpha8 418 | 1.0 419 | 420 | 421 | color8 422 | "dark red" 423 | 424 | 425 | label8 426 | 427 | 428 | 429 | marker8 430 | -1 431 | 432 | 433 | style8 434 | 1 435 | 436 | 437 | width8 438 | 1 439 | 440 | 441 | alpha9 442 | 1.0 443 | 444 | 445 | color9 446 | "dark green" 447 | 448 | 449 | label9 450 | 451 | 452 | 453 | marker9 454 | -1 455 | 456 | 457 | style9 458 | 1 459 | 460 | 461 | width9 462 | 1 463 | 464 | 465 | name 466 | "" 467 | 468 | 469 | nconnections 470 | 1 471 | 472 | 473 | size 474 | 1024 475 | 476 | 477 | srate 478 | samp_rate 479 | 480 | 481 | stemplot 482 | False 483 | 484 | 485 | tr_chan 486 | 0 487 | 488 | 489 | tr_delay 490 | 0 491 | 492 | 493 | tr_level 494 | 0.0 495 | 496 | 497 | tr_mode 498 | qtgui.TRIG_MODE_FREE 499 | 500 | 501 | tr_slope 502 | qtgui.TRIG_SLOPE_POS 503 | 504 | 505 | tr_tag 506 | "" 507 | 508 | 509 | type 510 | float 511 | 512 | 513 | update_time 514 | 0.10 515 | 516 | 517 | ylabel 518 | Amplitude 519 | 520 | 521 | yunit 522 | "" 523 | 524 | 525 | ymax 526 | 1 527 | 528 | 529 | ymin 530 | -1 531 | 532 | 533 | 534 | zeromq_sub_source 535 | 536 | address 537 | tcp://192.168.2.1:5555 538 | 539 | 540 | alias 541 | 542 | 543 | 544 | comment 545 | 546 | 547 | 548 | affinity 549 | 550 | 551 | 552 | _enabled 553 | True 554 | 555 | 556 | _coordinate 557 | (8, 76) 558 | 559 | 560 | _rotation 561 | 0 562 | 563 | 564 | hwm 565 | -1 566 | 567 | 568 | id 569 | zeromq_sub_source_0 570 | 571 | 572 | type 573 | float 574 | 575 | 576 | maxoutbuf 577 | 0 578 | 579 | 580 | minoutbuf 581 | 0 582 | 583 | 584 | pass_tags 585 | False 586 | 587 | 588 | timeout 589 | 100 590 | 591 | 592 | vlen 593 | 1 594 | 595 | 596 | 597 | zeromq_sub_source_0 598 | audio_sink_0 599 | 0 600 | 0 601 | 602 | 603 | zeromq_sub_source_0 604 | qtgui_time_sink_x_0 605 | 0 606 | 0 607 | 608 | 609 | -------------------------------------------------------------------------------- /doc/target.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/doc/target.pdf -------------------------------------------------------------------------------- /doc/target.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscimp/PlutoSDR/e27ee3de39040e24ed6e77aecec8b2e8daf03960/doc/target.png -------------------------------------------------------------------------------- /doc/top_block_for_PC.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | ################################################## 4 | # GNU Radio Python Flow Graph 5 | # Title: Top Block 6 | # Generated: Wed Dec 5 19:39:16 2018 7 | ################################################## 8 | 9 | from distutils.version import StrictVersion 10 | 11 | if __name__ == '__main__': 12 | import ctypes 13 | import sys 14 | if sys.platform.startswith('linux'): 15 | try: 16 | x11 = ctypes.cdll.LoadLibrary('libX11.so') 17 | x11.XInitThreads() 18 | except: 19 | print "Warning: failed to XInitThreads()" 20 | 21 | from PyQt5 import Qt 22 | from PyQt5 import Qt, QtCore 23 | from gnuradio import audio 24 | from gnuradio import blocks 25 | from gnuradio import eng_notation 26 | from gnuradio import gr 27 | from gnuradio import qtgui 28 | from gnuradio import zeromq 29 | from gnuradio.eng_option import eng_option 30 | from gnuradio.filter import firdes 31 | from optparse import OptionParser 32 | import sip 33 | import sys 34 | from gnuradio import qtgui 35 | 36 | 37 | class top_block(gr.top_block, Qt.QWidget): 38 | 39 | def __init__(self): 40 | gr.top_block.__init__(self, "Top Block") 41 | Qt.QWidget.__init__(self) 42 | self.setWindowTitle("Top Block") 43 | qtgui.util.check_set_qss() 44 | try: 45 | self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) 46 | except: 47 | pass 48 | self.top_scroll_layout = Qt.QVBoxLayout() 49 | self.setLayout(self.top_scroll_layout) 50 | self.top_scroll = Qt.QScrollArea() 51 | self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) 52 | self.top_scroll_layout.addWidget(self.top_scroll) 53 | self.top_scroll.setWidgetResizable(True) 54 | self.top_widget = Qt.QWidget() 55 | self.top_scroll.setWidget(self.top_widget) 56 | self.top_layout = Qt.QVBoxLayout(self.top_widget) 57 | self.top_grid_layout = Qt.QGridLayout() 58 | self.top_layout.addLayout(self.top_grid_layout) 59 | 60 | self.settings = Qt.QSettings("GNU Radio", "top_block") 61 | self.restoreGeometry(self.settings.value("geometry", type=QtCore.QByteArray)) 62 | 63 | 64 | ################################################## 65 | # Variables 66 | ################################################## 67 | self.samp_rate = samp_rate = 48000/2 68 | 69 | ################################################## 70 | # Blocks 71 | ################################################## 72 | self.zeromq_sub_source_0 = zeromq.sub_source(gr.sizeof_float, 1, 'tcp://192.168.2.1:5555', 100, False, -1) 73 | self.qtgui_time_sink_x_0 = qtgui.time_sink_f( 74 | 1024, #size 75 | samp_rate, #samp_rate 76 | "", #name 77 | 1 #number of inputs 78 | ) 79 | self.qtgui_time_sink_x_0.set_update_time(0.10) 80 | self.qtgui_time_sink_x_0.set_y_axis(-1, 1) 81 | 82 | self.qtgui_time_sink_x_0.set_y_label('Amplitude', "") 83 | 84 | self.qtgui_time_sink_x_0.enable_tags(-1, True) 85 | self.qtgui_time_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "") 86 | self.qtgui_time_sink_x_0.enable_autoscale(False) 87 | self.qtgui_time_sink_x_0.enable_grid(False) 88 | self.qtgui_time_sink_x_0.enable_axis_labels(True) 89 | self.qtgui_time_sink_x_0.enable_control_panel(False) 90 | self.qtgui_time_sink_x_0.enable_stem_plot(False) 91 | 92 | if not True: 93 | self.qtgui_time_sink_x_0.disable_legend() 94 | 95 | labels = ['', '', '', '', '', 96 | '', '', '', '', ''] 97 | widths = [1, 1, 1, 1, 1, 98 | 1, 1, 1, 1, 1] 99 | colors = ["blue", "red", "green", "black", "cyan", 100 | "magenta", "yellow", "dark red", "dark green", "blue"] 101 | styles = [1, 1, 1, 1, 1, 102 | 1, 1, 1, 1, 1] 103 | markers = [-1, -1, -1, -1, -1, 104 | -1, -1, -1, -1, -1] 105 | alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 106 | 1.0, 1.0, 1.0, 1.0, 1.0] 107 | 108 | for i in xrange(1): 109 | if len(labels[i]) == 0: 110 | self.qtgui_time_sink_x_0.set_line_label(i, "Data {0}".format(i)) 111 | else: 112 | self.qtgui_time_sink_x_0.set_line_label(i, labels[i]) 113 | self.qtgui_time_sink_x_0.set_line_width(i, widths[i]) 114 | self.qtgui_time_sink_x_0.set_line_color(i, colors[i]) 115 | self.qtgui_time_sink_x_0.set_line_style(i, styles[i]) 116 | self.qtgui_time_sink_x_0.set_line_marker(i, markers[i]) 117 | self.qtgui_time_sink_x_0.set_line_alpha(i, alphas[i]) 118 | 119 | self._qtgui_time_sink_x_0_win = sip.wrapinstance(self.qtgui_time_sink_x_0.pyqwidget(), Qt.QWidget) 120 | self.top_grid_layout.addWidget(self._qtgui_time_sink_x_0_win) 121 | self.blocks_throttle_0 = blocks.throttle(gr.sizeof_float*1, samp_rate,True) 122 | self.audio_sink_0 = audio.sink(samp_rate, '', True) 123 | 124 | 125 | 126 | ################################################## 127 | # Connections 128 | ################################################## 129 | self.connect((self.blocks_throttle_0, 0), (self.audio_sink_0, 0)) 130 | self.connect((self.blocks_throttle_0, 0), (self.qtgui_time_sink_x_0, 0)) 131 | self.connect((self.zeromq_sub_source_0, 0), (self.blocks_throttle_0, 0)) 132 | 133 | def closeEvent(self, event): 134 | self.settings = Qt.QSettings("GNU Radio", "top_block") 135 | self.settings.setValue("geometry", self.saveGeometry()) 136 | event.accept() 137 | 138 | def get_samp_rate(self): 139 | return self.samp_rate 140 | 141 | def set_samp_rate(self, samp_rate): 142 | self.samp_rate = samp_rate 143 | self.qtgui_time_sink_x_0.set_samp_rate(self.samp_rate) 144 | self.blocks_throttle_0.set_sample_rate(self.samp_rate) 145 | 146 | 147 | def main(top_block_cls=top_block, options=None): 148 | 149 | qapp = Qt.QApplication(sys.argv) 150 | 151 | tb = top_block_cls() 152 | tb.start() 153 | tb.show() 154 | 155 | def quitting(): 156 | tb.stop() 157 | tb.wait() 158 | qapp.aboutToQuit.connect(quitting) 159 | qapp.exec_() 160 | 161 | 162 | if __name__ == '__main__': 163 | main() 164 | -------------------------------------------------------------------------------- /doc/top_block_for_pluto.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | ################################################## 4 | # GNU Radio Python Flow Graph 5 | # Title: Top Block 6 | # Generated: Wed Dec 5 19:37:37 2018 7 | ################################################## 8 | 9 | 10 | from gnuradio import analog 11 | from gnuradio import blocks 12 | from gnuradio import eng_notation 13 | from gnuradio import filter 14 | from gnuradio import gr 15 | from gnuradio import iio 16 | from gnuradio import zeromq 17 | from gnuradio.eng_option import eng_option 18 | from gnuradio.filter import firdes 19 | from optparse import OptionParser 20 | 21 | 22 | class top_block(gr.top_block): 23 | 24 | def __init__(self): 25 | gr.top_block.__init__(self, "Top Block") 26 | 27 | ################################################## 28 | # Variables 29 | ################################################## 30 | self.samp_rate = samp_rate = 48000*24 31 | self.freq = freq = int(96.9e6) 32 | 33 | ################################################## 34 | # Blocks 35 | ################################################## 36 | self.zeromq_pub_sink_0 = zeromq.pub_sink(gr.sizeof_float, 1, 'tcp://0.0.0.0:5555', 100, False, -1) 37 | self.pluto_source_0 = iio.pluto_source('local:', freq, samp_rate, 20000000, 0x8000, True, True, True, "manual", 55, '', True) 38 | self.low_pass_filter_0 = filter.fir_filter_ccf(6, firdes.low_pass( 39 | 1, samp_rate, 100000, 100000, firdes.WIN_HAMMING, 6.76)) 40 | self.blocks_null_sink_0 = blocks.null_sink(gr.sizeof_float*1) 41 | self.analog_wfm_rcv_0 = analog.wfm_rcv( 42 | quad_rate=samp_rate/6, 43 | audio_decimation=8, 44 | ) 45 | 46 | 47 | 48 | ################################################## 49 | # Connections 50 | ################################################## 51 | self.connect((self.analog_wfm_rcv_0, 0), (self.blocks_null_sink_0, 0)) 52 | self.connect((self.analog_wfm_rcv_0, 0), (self.zeromq_pub_sink_0, 0)) 53 | self.connect((self.low_pass_filter_0, 0), (self.analog_wfm_rcv_0, 0)) 54 | self.connect((self.pluto_source_0, 0), (self.low_pass_filter_0, 0)) 55 | 56 | def get_samp_rate(self): 57 | return self.samp_rate 58 | 59 | def set_samp_rate(self, samp_rate): 60 | self.samp_rate = samp_rate 61 | self.pluto_source_0.set_params(self.freq, self.samp_rate, 20000000, True, True, True, "manual", 55, '', True) 62 | self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.samp_rate, 100000, 100000, firdes.WIN_HAMMING, 6.76)) 63 | 64 | def get_freq(self): 65 | return self.freq 66 | 67 | def set_freq(self, freq): 68 | self.freq = freq 69 | self.pluto_source_0.set_params(self.freq, self.samp_rate, 20000000, True, True, True, "manual", 55, '', True) 70 | 71 | 72 | def main(top_block_cls=top_block, options=None): 73 | 74 | tb = top_block_cls() 75 | tb.start() 76 | try: 77 | raw_input('Press Enter to quit: ') 78 | except EOFError: 79 | pass 80 | tb.stop() 81 | tb.wait() 82 | 83 | 84 | if __name__ == '__main__': 85 | main() 86 | -------------------------------------------------------------------------------- /external.desc: -------------------------------------------------------------------------------- 1 | name: PLUTOSDR 2 | desc: BR2_EXTERNAL_PLUTOSDR tree 3 | -------------------------------------------------------------------------------- /external.mk: -------------------------------------------------------------------------------- 1 | include $(sort $(wildcard $(BR2_EXTERNAL_PLUTOSDR_PATH)/package/*/*.mk)) 2 | 3 | -------------------------------------------------------------------------------- /package/ad936x_ref_cal/Config.in: -------------------------------------------------------------------------------- 1 | config BR2_PACKAGE_AD936X_REF_CAL 2 | bool "Reference clock calibration utility for AD9361/3/4" 3 | depends on BR2_TOOLCHAIN_HAS_THREADS 4 | select BR2_PACKAGE_FFTW 5 | select BR2_PACKAGE_FFTW_DOUBLE 6 | select BR2_PACKAGE_LIBIIO_PLUTO 7 | help 8 | Reference clock calibration utility for AD9361/3/4 9 | -------------------------------------------------------------------------------- /package/ad936x_ref_cal/ad936x_ref_cal.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 3 | # ad936x_ref_cal 4 | # 5 | ################################################################################ 6 | 7 | 8 | AD936X_REF_CAL_VERSION = 01747db5cd60ff64115a73ac1f3bb97911f5c58e 9 | AD936X_REF_CAL_SITE = https://github.com/analogdevicesinc/plutosdr_scripts.git 10 | AD936X_REF_CAL_SITE_METHOD = git 11 | AD936X_REF_CAL_LICENSE = GPLv2 12 | AD936X_REF_CAL_LICENSE_FILES = LICENSE 13 | AD936X_REF_CAL_DEPENDENCIES = libiio-pluto fftw-double 14 | 15 | define AD936X_REF_CAL_BUILD_CMDS 16 | $(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_LDFLAGS) \ 17 | $(@D)/cal_ad9361.c -o $(@D)/ad936x_ref_cal -lm -lpthread -lfftw3 -liio 18 | endef 19 | 20 | define AD936X_REF_CAL_INSTALL_TARGET_CMDS 21 | $(INSTALL) -D -m 755 $(@D)/ad936x_ref_cal $(TARGET_DIR)/usr/sbin/ad936x_ref_cal 22 | endef 23 | 24 | $(eval $(generic-package)) 25 | -------------------------------------------------------------------------------- /package/gr-iio/Config.in: -------------------------------------------------------------------------------- 1 | config BR2_PACKAGE_GR_IIO 2 | bool "gr-iio" 3 | select BR2_PACKAGE_LIBAD9361_IIO 4 | select BR2_PACKAGE_GNURADIO 5 | select BR2_PACKAGE_GNURADIO_ANALOG 6 | select BR2_PACKAGE_GNURADIO_BLOCKS 7 | help 8 | GNU Radio IIO Blocks 9 | https://github.com/analogdevicesinc/gr-iio 10 | -------------------------------------------------------------------------------- /package/gr-iio/gr-iio.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 3 | # gr-iio 4 | # 5 | ################################################################################ 6 | GR_IIO_VERSION = e9d12b559c3efa085304fffba4a4310bb1297367 7 | GR_IIO_SITE = https://github.com/analogdevicesinc/gr-iio.git 8 | GR_IIO_SITE_METHOD = git 9 | 10 | GR_IIO_INSTALL_STAGING = YES 11 | GR_IIO_LICENSE = LGPL-2.1+ 12 | GR_IIO_LICENSE_FILES = LICENSE 13 | GR_IIO_DEPENDENCIES = libad9361-iio gnuradio 14 | 15 | $(eval $(cmake-package)) 16 | -------------------------------------------------------------------------------- /package/libad9361-iio/Config.in: -------------------------------------------------------------------------------- 1 | config BR2_PACKAGE_LIBAD9361_IIO 2 | bool "libad9361-iio" 3 | select BR2_PACKAGE_LIBIIO_PLUTO 4 | help 5 | This is a simple library used for userspace, which manages multi-chip sync, on platforms (FMCOMMS5) where multiple AD9361 devices are used. 6 | https://github.com/analogdevicesinc/libad9361-iio 7 | -------------------------------------------------------------------------------- /package/libad9361-iio/libad9361-iio.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 3 | # libad9361-iio 4 | # 5 | ################################################################################ 6 | LIBAD9361_IIO_VERSION = 0.2 7 | LIBAD9361_IIO_SITE = $(call github,analogdevicesinc,libad9361-iio,v$(LIBAD9361_IIO_VERSION)) 8 | 9 | LIBAD9361_IIO_INSTALL_STAGING = YES 10 | LIBAD9361_IIO_LICENSE = LGPL-2.1+ 11 | LIBAD9361_IIO_LICENSE_FILES = LICENSE 12 | LIBAD9361_IIO_DEPENDENCIES = libiio-pluto 13 | 14 | $(eval $(cmake-package)) 15 | -------------------------------------------------------------------------------- /package/libiio-pluto/Config.in: -------------------------------------------------------------------------------- 1 | config BR2_PACKAGE_LIBIIO_PLUTO 2 | bool "libiio" 3 | select BR2_PACKAGE_LIBIIO_PLUTO_LOCAL_BACKEND if !BR2_PACKAGE_LIBIIO_PLUTO_XML_BACKEND 4 | help 5 | Libiio is a library to ease the development of software 6 | interfacing Linux Industrial I/O (IIO) devices. 7 | 8 | http://wiki.analog.com/resources/tools-software/linux-software/libiio 9 | 10 | if BR2_PACKAGE_LIBIIO_PLUTO 11 | 12 | config BR2_PACKAGE_LIBIIO_PLUTO_LOCAL_BACKEND 13 | bool "Local backend" 14 | default y 15 | help 16 | Enable the local backend of the library. 17 | 18 | config BR2_PACKAGE_LIBIIO_PLUTO_LOCAL_CONFIG 19 | bool "Local context attributes" 20 | depends on BR2_PACKAGE_LIBINI 21 | default y 22 | help 23 | Read local context attributes from /etc/libiio.ini. 24 | 25 | config BR2_PACKAGE_LIBIIO_PLUTO_XML_BACKEND 26 | bool "XML backend" 27 | default y 28 | select BR2_PACKAGE_LIBXML2 29 | help 30 | Enable the XML backend of the library. 31 | 32 | config BR2_PACKAGE_LIBIIO_PLUTO_NETWORK_BACKEND 33 | bool "Network backend" 34 | default y 35 | select BR2_PACKAGE_LIBIIO_PLUTO_XML_BACKEND 36 | help 37 | Enable the network backend of the library. 38 | 39 | config BR2_PACKAGE_LIBIIO_PLUTO_USB_BACKEND 40 | bool "USB backend" 41 | default y 42 | depends on BR2_TOOLCHAIN_HAS_THREADS # from libusb 43 | select BR2_PACKAGE_LIBIIO_PLUTO_XML_BACKEND 44 | select BR2_PACKAGE_LIBUSB 45 | help 46 | Enable the USB backend of the library. 47 | 48 | comment "The USB backend needs a toolchain w/ threads" 49 | depends on !BR2_TOOLCHAIN_HAS_THREADS 50 | 51 | config BR2_PACKAGE_LIBIIO_PLUTO_SERIAL_BACKEND 52 | bool "Serial backend" 53 | default y 54 | select BR2_PACKAGE_LIBIIO_PLUTO_XML_BACKEND 55 | select BR2_PACKAGE_LIBSERIALPORT 56 | help 57 | Enable the serial backend of the library. 58 | 59 | config BR2_PACKAGE_LIBIIO_PLUTO_IIOD 60 | bool "IIO Daemon" 61 | default y 62 | depends on BR2_TOOLCHAIN_HAS_THREADS 63 | select BR2_PACKAGE_LIBIIO_PLUTO_LOCAL_BACKEND 64 | help 65 | Install the IIO Daemon. 66 | 67 | config BR2_PACKAGE_LIBIIO_PLUTO_IIOD_USBD 68 | bool "USB support in the IIO Daemon (FunctionFS)" 69 | depends on BR2_PACKAGE_LIBIIO_PLUTO_IIOD 70 | depends on BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_18 # usb_functionfs_descs_head_v2 71 | select BR2_PACKAGE_LIBAIO 72 | help 73 | Add support for USB through FunctionFS with IIOD. 74 | 75 | comment "USB support in the IIO Daemon requires libaio, headers >= 3.18" 76 | depends on BR2_PACKAGE_LIBIIO_PLUTO_IIOD 77 | depends on !BR2_PACKAGE_LIBAIO || \ 78 | !BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_18 79 | 80 | comment "IIO Daemon needs a toolchain w/ threads" 81 | depends on !BR2_TOOLCHAIN_HAS_THREADS 82 | 83 | config BR2_PACKAGE_LIBIIO_PLUTO_TESTS 84 | bool "Install test programs" 85 | depends on BR2_TOOLCHAIN_HAS_THREADS 86 | help 87 | Install the test programs (iio_info, iio_genxml, iio_readdev). 88 | 89 | comment "IIO test programs need a toolchain w/ threads" 90 | depends on !BR2_TOOLCHAIN_HAS_THREADS 91 | 92 | config BR2_PACKAGE_LIBIIO_PLUTO_BINDINGS_CSHARP 93 | bool "Install C# bindings" 94 | depends on BR2_PACKAGE_MONO 95 | help 96 | Install the C# bindings. 97 | 98 | config BR2_PACKAGE_LIBIIO_PLUTO_BINDINGS_PYTHON 99 | bool "Install Python bindings" 100 | depends on BR2_PACKAGE_PYTHON || BR2_PACKAGE_PYTHON3 101 | help 102 | Install the Python bindings. 103 | 104 | endif 105 | -------------------------------------------------------------------------------- /package/libiio-pluto/S99iiod: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Server-side demuxing by default 4 | IIOD_OPTS=-D 5 | 6 | [ -r /etc/default/iiod ] && . /etc/default/iiod 7 | 8 | case "$1" in 9 | start) 10 | echo "Starting IIO Server Daemon" 11 | start-stop-daemon -S -b -q -m -p /var/run/iiod.pid -x /usr/sbin/iiod -- $IIOD_OPTS 12 | exit $? 13 | ;; 14 | 15 | stop) 16 | echo "Stopping IIO Server Daemon" 17 | start-stop-daemon -K -q -p /var/run/iiod.pid 2>/dev/null 18 | exit $? 19 | ;; 20 | 21 | restart) 22 | $0 stop 23 | sleep 1 24 | $0 start 25 | ;; 26 | 27 | *) 28 | echo "Usage: $0 {start|stop|restart}" 29 | exit 1 30 | esac 31 | -------------------------------------------------------------------------------- /package/libiio-pluto/libiio-pluto.hash: -------------------------------------------------------------------------------- 1 | # From https://github.com/analogdevicesinc/libiio/archive/v0.7/ 2 | sha256 c2b02f1cb51870db52368fdaa8087dc2a4ec43f2bc3c3514d8214952f14c3f39 libiio-0.7.tar.gz 3 | sha256 b9e4fd97fbbb1cfdf48362aa156ab2e61b41b368467c952698aaf6999d5560b9 libiio-0.7.164de86.tar.gz 4 | sha256 08abe0ee09629c874d5c98daf0c0dab5cf7cd66f373a77eecfa992eddc877036 libiio-0.8.tar.gz 5 | sha256 b6184876d192fbfd51e3a0a29736fa1be2dbaf07370cf861797076f40a85f823 libiio-0.9.tar.gz 6 | sha256 002d57f35715821efae66479859bc5357b4d8d33bfff1446b4e17b02ae2c10d2 libiio-0.10.tar.gz 7 | sha256 0174111b028d84f18fb3716b22834a372a1f2575938f87e20e5cbd76747d0fdb libiio-0.11.tar.gz 8 | sha256 36e164fc00535762c819db209928ee2704fc81657d41060ea47873bccfd5c4bc libiio-0.12.tar.gz 9 | sha256 12063db7a9366aa00bfd789db30afaddb29686bc29b3ce1e5d4adfe1c3b42527 libiio-0.14.tar.gz 10 | sha256 a729f8ff48137ad271a3e2951f322b35c1bf2ec075b488d75c8bd071c693fd19 libiio-0.15.tar.gz 11 | sha256 5eb3ec24342eb01c49235a1d8a053462f930835a3002e687371b680a9bb150f6 libiio-0.16.tar.gz 12 | sha256 f591693b8759b6f159ab7afcc1325854a883a486adaf8a849acbdfe0def9db56 libiio-0.17.tar.gz 13 | -------------------------------------------------------------------------------- /package/libiio-pluto/libiio-pluto.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 3 | # libiio 4 | # 5 | ################################################################################ 6 | 7 | LIBIIO_PLUTO_VERSION = 0.17 8 | LIBIIO_PLUTO_SOURCE = libiio-$(LIBIIO_PLUTO_VERSION).tar.gz 9 | LIBIIO_PLUTO_SITE = $(call github,analogdevicesinc,libiio,v$(LIBIIO_PLUTO_VERSION)) 10 | 11 | #LIBIIO_PLUTO_VERSION = 60063cb20312c2f06cb8b33e8692e4a0a3546738 12 | #LIBIIO_PLUTO_SITE = https://github.com/analogdevicesinc/libiio.git 13 | #LIBIIO_PLUTO_SITE_METHOD = git 14 | 15 | LIBIIO_PLUTO_INSTALL_STAGING = YES 16 | LIBIIO_PLUTO_LICENSE = LGPL-2.1+ 17 | LIBIIO_PLUTO_LICENSE_FILES = COPYING.txt 18 | 19 | LIBIIO_PLUTO_CONF_OPTS = -DENABLE_IPV6=ON \ 20 | -DWITH_LOCAL_BACKEND=$(if $(BR2_PACKAGE_LIBIIO_PLUTO_LOCAL_BACKEND),ON,OFF) \ 21 | -DWITH_LOCAL_CONFIG=$(if $(BR2_PACKAGE_LIBIIO_PLUTO_LOCAL_CONFIG),ON,OFF) \ 22 | -DWITH_NETWORK_BACKEND=$(if $(BR2_PACKAGE_LIBIIO_PLUTO_NETWORK_BACKEND),ON,OFF) \ 23 | -DWITH_MATLAB_BINDINGS_API=OFF \ 24 | -DMATLAB_BINDINGS=OFF \ 25 | -DINSTALL_UDEV_RULE=$(if $(BR2_PACKAGE_HAS_UDEV),ON,OFF) \ 26 | -DWITH_TESTS=$(if $(BR2_PACKAGE_LIBIIO_PLUTO_TESTS),ON,OFF) \ 27 | -DWITH_DOC=OFF 28 | 29 | # -DLIBIIO_PLUTO_VERSION_GIT=60063cb \ 30 | 31 | ifeq ($(BR2_PACKAGE_LIBIIO_PLUTO_LOCAL_BACKEND),y) 32 | LIBIIO_PLUTO_DEPENDENCIES += libini 33 | endif 34 | 35 | ifeq ($(BR2_PACKAGE_LIBIIO_PLUTO_XML_BACKEND),y) 36 | LIBIIO_PLUTO_DEPENDENCIES += libxml2 37 | LIBIIO_PLUTO_CONF_OPTS += -DWITH_XML_BACKEND=ON 38 | else 39 | LIBIIO_PLUTO_CONF_OPTS += -DWITH_XML_BACKEND=OFF 40 | endif 41 | 42 | ifeq ($(BR2_PACKAGE_LIBIIO_PLUTO_USB_BACKEND),y) 43 | LIBIIO_PLUTO_DEPENDENCIES += libusb 44 | LIBIIO_PLUTO_CONF_OPTS += -DWITH_USB_BACKEND=ON 45 | else 46 | LIBIIO_PLUTO_CONF_OPTS += -DWITH_USB_BACKEND=OFF 47 | endif 48 | 49 | ifeq ($(BR2_PACKAGE_LIBIIO_PLUTO_SERIAL_BACKEND),y) 50 | LIBIIO_PLUTO_DEPENDENCIES += libserialport 51 | LIBIIO_PLUTO_CONF_OPTS += -DWITH_SERIAL_BACKEND=ON 52 | else 53 | LIBIIO_PLUTO_CONF_OPTS += -DWITH_SERIAL_BACKEND=OFF 54 | endif 55 | 56 | ifeq ($(BR2_PACKAGE_LIBIIO_PLUTO_IIOD),y) 57 | LIBIIO_PLUTO_DEPENDENCIES += host-flex host-bison libaio 58 | LIBIIO_PLUTO_CONF_OPTS += -DWITH_IIOD=ON -DWITH_AIO=ON 59 | else 60 | LIBIIO_PLUTO_CONF_OPTS += -DWITH_IIOD=OFF 61 | endif 62 | 63 | ifeq ($(BR2_PACKAGE_LIBIIO_PLUTO_IIOD_USBD),y) 64 | LIBIIO_PLUTO_DEPENDENCIES += libaio 65 | LIBIIO_PLUTO_CONF_OPTS += -DWITH_IIOD_USBD=ON 66 | else 67 | LIBIIO_PLUTO_CONF_OPTS += -DWITH_IIOD_USBD=OFF 68 | endif 69 | 70 | # Avahi support in libiio requires avahi-client, which needs avahi-daemon and dbus 71 | ifeq ($(BR2_PACKAGE_AVAHI_DAEMON)$(BR2_PACKAGE_DBUS),yy) 72 | LIBIIO_PLUTO_DEPENDENCIES += avahi 73 | endif 74 | 75 | ifeq ($(BR2_PACKAGE_LIBIIO_PLUTO_BINDINGS_PYTHON),y) 76 | ifeq ($(BR2_PACKAGE_PYTHON),y) 77 | LIBIIO_PLUTO_DEPENDENCIES += python 78 | else ifeq ($(BR2_PACKAGE_PYTHON3),y) 79 | LIBIIO_PLUTO_DEPENDENCIES += python3 80 | endif 81 | LIBIIO_PLUTO_CONF_OPTS += -DPYTHON_BINDINGS=ON 82 | else 83 | LIBIIO_PLUTO_CONF_OPTS += -DPYTHON_BINDINGS=OFF 84 | endif 85 | 86 | ifeq ($(BR2_PACKAGE_LIBIIO_PLUTO_BINDINGS_CSHARP),y) 87 | define LIBIIO_PLUTO_INSTALL_CSHARP_BINDINGS_TO_TARGET 88 | rm $(TARGET_DIR)/usr/lib/cli/libiio-sharp-$(LIBIIO_PLUTO_VERSION)/libiio-sharp.dll.mdb 89 | $(HOST_DIR)/bin/gacutil -root $(TARGET_DIR)/usr/lib -i \ 90 | $(TARGET_DIR)/usr/lib/cli/libiio-sharp-$(LIBIIO_PLUTO_VERSION)/libiio-sharp.dll 91 | endef 92 | define LIBIIO_PLUTO_INSTALL_CSHARP_BINDINGS_TO_STAGING 93 | $(HOST_DIR)/bin/gacutil -root $(STAGING_DIR)/usr/lib -i \ 94 | $(STAGING_DIR)/usr/lib/cli/libiio-sharp-$(LIBIIO_PLUTO_VERSION)/libiio-sharp.dll 95 | endef 96 | LIBIIO_PLUTO_POST_INSTALL_TARGET_HOOKS += LIBIIO_PLUTO_INSTALL_CSHARP_BINDINGS_TO_TARGET 97 | LIBIIO_PLUTO_POST_INSTALL_STAGING_HOOKS += LIBIIO_PLUTO_INSTALL_CSHARP_BINDINGS_TO_STAGING 98 | LIBIIO_PLUTO_DEPENDENCIES += mono 99 | LIBIIO_PLUTO_CONF_OPTS += -DCSHARP_BINDINGS=ON 100 | else 101 | LIBIIO_PLUTO_CONF_OPTS += -DCSHARP_BINDINGS=OFF 102 | endif 103 | 104 | ifeq ($(BR2_PACKAGE_LIBIIO_PLUTO_IIOD),y) 105 | define LIBIIO_PLUTO_INSTALL_INIT_SYSV 106 | $(INSTALL) -D -m 0755 package/libiio/S99iiod \ 107 | $(TARGET_DIR)/etc/init.d/S99iiod 108 | endef 109 | endif 110 | 111 | $(eval $(cmake-package)) 112 | -------------------------------------------------------------------------------- /package/libini/Config.in: -------------------------------------------------------------------------------- 1 | config BR2_PACKAGE_LIBINI 2 | bool "libini" 3 | help 4 | Libini is a simple library to read INI configuration files. 5 | 6 | See: https://github.com/pcercuei/libini/ 7 | -------------------------------------------------------------------------------- /package/libini/libini.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 3 | # libini 4 | # 5 | ################################################################################ 6 | 7 | LIBINI_VERSION = a467418 8 | LIBINI_SITE = https://github.com/pcercuei/libini.git 9 | LIBINI_SITE_METHOD = git 10 | 11 | LIBINI_INSTALL_STAGING = YES 12 | LIBINI_LICENSE = LGPLv2.1+ 13 | LIBINI_LICENSE_FILES = LICENSE.txt 14 | 15 | $(eval $(cmake-package)) 16 | -------------------------------------------------------------------------------- /package/pluto-system-top-bit/Config.in: -------------------------------------------------------------------------------- 1 | config BR2_PACKAGE_PLUTO_SYSTEM_TOP_BIT 2 | bool "pluto default system_top.bit" 3 | help 4 | PlutoSDR default sytem_top.bit 5 | 6 | http://ghttps://github.com/analogdevicesinc/plutosdr-fw 7 | -------------------------------------------------------------------------------- /package/pluto-system-top-bit/pluto-system-top-bit.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 3 | # pluto-system-top-bit 4 | # 5 | ################################################################################ 6 | 7 | PLUTO_SYSTEM_TOP_BIT_VERSION = v0.30 8 | PLUTO_SYSTEM_TOP_BIT_SOURCE = plutosdr-jtag-bootstrap-$(PLUTO_SYSTEM_TOP_BIT_VERSION).zip 9 | PLUTO_SYSTEM_TOP_BIT_SITE = http://github.com/analogdevicesinc/plutosdr-fw/releases/download/$(PLUTO_SYSTEM_TOP_BIT_VERSION) 10 | 11 | PLUTO_SYSTEM_TOP_BIT_INSTALL_IMAGES = YES 12 | PLUTO_SYSTEM_TOP_BIT_INSTALL_TARGET = NO 13 | 14 | define PLUTO_SYSTEM_TOP_BIT_EXTRACT_CMDS 15 | $(UNZIP) $(PLUTO_SYSTEM_TOP_BIT_DL_DIR)/$(PLUTO_SYSTEM_TOP_BIT_SOURCE) system_top.bit -d $(@D) 16 | endef 17 | 18 | define PLUTO_SYSTEM_TOP_BIT_INSTALL_IMAGES_CMDS 19 | cp $(@D)/system_top.bit $(BINARIES_DIR) 20 | endef 21 | 22 | $(eval $(generic-package)) 23 | -------------------------------------------------------------------------------- /package/poll_sysfs/Config.in: -------------------------------------------------------------------------------- 1 | config BR2_PACKAGE_POLL_SYSFS 2 | bool "poll_sysfs" 3 | help 4 | The sysfs poll utility. 5 | 6 | -------------------------------------------------------------------------------- /package/poll_sysfs/poll_sysfs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple sysfs poll 3 | * 4 | * Copyright 2017 Analog Devices Inc. 5 | * 6 | * Licensed under the GPL-2. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | int main(int argc, char *argv[]) { 17 | struct pollfd fdlist[1]; 18 | int fd, err; 19 | char buf[80]; 20 | 21 | if (argc < 2) 22 | return 1; 23 | 24 | fd = open(argv[1], O_RDONLY); 25 | 26 | fdlist[0].fd = fd; 27 | fdlist[0].events = POLLPRI | POLLERR; 28 | 29 | read(fdlist[0].fd, buf, sizeof(buf)); 30 | 31 | err = poll(fdlist, 1, -1); 32 | if (err < 0) { 33 | perror("poll"); 34 | return 1; 35 | } 36 | 37 | err = lseek(fdlist[0].fd, 0 , SEEK_SET); 38 | if (err < 0) { 39 | perror("lseek"); 40 | return 1; 41 | } 42 | 43 | err = read(fdlist[0].fd, buf, sizeof(buf)); 44 | if (err > 0) { 45 | buf[err] = 0; 46 | printf("%s", buf); 47 | close(fdlist[0].fd); 48 | return 0; 49 | } 50 | 51 | perror("read"); 52 | return 1; 53 | } 54 | -------------------------------------------------------------------------------- /package/poll_sysfs/poll_sysfs.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 3 | # poll_sysfs 4 | # 5 | ################################################################################ 6 | 7 | POLL_SYSFS_LICENSE = GPLv2 8 | 9 | 10 | define POLL_SYSFS_BUILD_CMDS 11 | $(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_LDFLAGS) \ 12 | ${BR2_EXTERNAL_PLUTOSDR_PATH}/package/poll_sysfs/poll_sysfs.c -o $(@D)/poll_sysfs 13 | endef 14 | 15 | define POLL_SYSFS_INSTALL_TARGET_CMDS 16 | $(INSTALL) -D -m 755 $(@D)/poll_sysfs $(TARGET_DIR)/sbin/poll_sysfs 17 | endef 18 | 19 | $(eval $(generic-package)) 20 | -------------------------------------------------------------------------------- /sourceme.ggm: -------------------------------------------------------------------------------- 1 | ABSOLUTE_PATH=$(cd `dirname "${BASH_SOURCE[0]}"` && pwd) 2 | unset LD_LIBRARY_PATH 3 | 4 | # Add this directory only if not already added to avoid problem 5 | # with Buildroot 6 | if [ -z "$(echo $BR2_EXTERNAL | grep $ABSOLUTE_PATH)" ]; then 7 | export BR2_EXTERNAL=$ABSOLUTE_PATH:$BR2_EXTERNAL 8 | fi 9 | --------------------------------------------------------------------------------