Package: un0usb
How to setup the board using only a usb cableBeware! If you use this, you just need to have a usb cable plugged in.Install jumpers and connectors as indicated in the figure below. Jumpers necessary are the white and the green ones.InstallationPreparing PythonLet's install what is requiredpip3 install un0usbIf you face issues, you can still download the rest of the main modules.pip3 install pyftdi matplotlib numpy scipyInstalling iceprog to flash the fpgaiceprog is the software used to put the fpga on the flash storage on the board, which will be read by the fpga on boot. The easiest way is to :sudo apt install fpga-icestormIf this doesn’t work, then this may work:sudo apt-get install libftdi-dev git gcc 
git clone https://github.com/cliffordwolf/icestorm.git
cd iceprog
make 
sudo make installThis will create and install the iceprog utility, used to flash the fpga program (bitstream).FTDI rules.Notes for Linux: Create a file /etc/udev/rules.d/53-lattice-ftdi.rules with the following line in it to allow uploading bit-streams as unprivileged user:ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", MODE="0660", GROUP="plugdev", TAG+="uaccess"This should solve usb access rules.Board specific install filesDownload theinstall packor bywget https://github.com/kelu124/un0rick/raw/master/usb/install_pack.zipConnect the usb cableCheck that the FTDI device is well created by typing:dmesgProgramming itUnzip it, inside, there's the bin to program the fpga :iceprog usb.binRunning pythonTestThere is a test bench for the python lib matching the usb firmware, from thepippackage. Installation is as follows.wget https://github.com/kelu124/python-usb-un0rick/raw/master/usb.bin
iceprog usb.binwhich will flash the board.Using the python libImportsTo import the lib:import un0usb as USBI encourage the reader to go insidethis libs source, which is already documented.Create the devicethen connect to the FPGA# Check the versionUSB.__version__# init FTDI devicefpga=USB.FpgaControl('ftdi://ftdi:2232:/',spi_freq=8E6)# reload configuration (optional step - just to fill BRAM (DACGAIN registers) with initial values)fpga.reload()# reset fpgafpga.reset()Run acqsTo play with custom gain and pulse parameters:fpga.set_pulseform(initDelay=5,POn=16,PInter=16,Poff=5000)gain=[int(100+((1000-100)*x*x*x/32/32/32))forxinrange(32)]acq_res=fpga.do_acquisition(acq_lines=2,gain=gain,double_rate=True)plt.plot(acq_res[0])Save acqs# Let's save the previous acquisitionfpga.save("Test")# And display it in more detailsplot=USB.FView()plot.readfile('Test.npz')Pulser controlTo control the waveform, one would set thefpga.csr.ponw,fpga.csr.interwandfpga.csr.poffw, that are respectively integers for setting the width (timing) of the pulse, width of a relaxation period before damping, and then duration of damping. Unit are (1/128us).Thefpga.csr.initdelregister is the delay between the beginning of the acquisiton and the pulse.fpga.csr.initdel = InitDel
fpga.csr.ponw = PONWidth
fpga.csr.interw = INTERWidth
fpga.csr.poffw = PDAMPBelow is plotted amplitude of an echo as a function of thefpga.csr.ponwfor a 4MHz transducer. One sees that a setting at16provides most(Seefull experiment here).Gain and acquisitionsAnd do acquisitions withacq_res = fpga.do_acquisition(acq_lines=32, gain=gain, double_rate=True)which will return an array ofacq_linesacquisitions, of length 256us at 64Msps.double_rate=Trueprovides a half clock offset to odd lines, so that one can interleave two subsequent acquisition to have, in a fixed setting, a 128Msps acquisition.Thegainsetting is an array of integers, of length 32, that can range from 0 to 1023, controlling gain for each of the 32 8us-segment of acquisition within the 256us line.Other registersfpga.csr.led3 = 0sets LED3 off. led1, led2, led3 are possible, can be set to 0 or 1.fpga.csr.topturnXreads input 1 to 3 on the input header.fpga.csr.jumperXreads jumper 1 to 3 close to the programming jumper.fpga.csr.outXicewrites/reads output 1 to 3.fpga.csr.nblines = acq_lines - 1is the register controlling the number of lines acquired.fpga.csr.dacoutreads the DAC/TGC/VGA level outside of acquisitions.fpga.csr.acqstart = 1to start the acquisitionfpga.csr.drmode = int(double_rate)triggers the interleaving mode.fpga.csr.acqstart = 1to start the acquisitionfpga.csr.acqdoneis equal to 0 during acquisitions.fpga.csr.authorreads the ID of the author of the binary.fpga.csr.versionreads the ID of the author's binary.Example of acquisitonsRaw signal, with DACThe signal is in blue, the gain levels are in green. Here there are 32 visible steps, of 8us each.Detail of an echoInterleaved acquisiton mode = ONDoublign acquisition speed (yellow and red dots below)LicenseThis work is based on two previous TAPR projects,the echOmods project, and theun0rick project- its boards are open hardware and software, developped with open-source elements as much as possible.Copyright Kelu124 (kelu124@gmail.com) 2020.The hardware is licensed under TAPR Open Hardware License (www.tapr.org/OHL)The software components are free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.The documentation is licensed under aCreative Commons Attribution-ShareAlike 3.0 Unported License.DisclaimerThis project is distributed WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE.Changelog0.2.7: Solving: Savefile naming issue