[LNIV Xilinx](index.html)
# Razvojna plošča [Red Pitaya](https://www.redpitaya.com/)
Red Pitaya je odprtokodna merilna platforma, ki temelji na SoC Xilinx Zynq. Strojne komponente so opisane v jeziku System Verilog in so dostopne na spletnem repozitoriju [GitHub](https://github.com/RedPitaya/RedPitaya). Uporabili bomo projekt classic, ki vsebuje osciloskop, signalni generator (ASG) in regulator PID. Glavna komponenta [red_pitaya_top.sv](https://github.com/RedPitaya/RedPitaya/blob/master/fpga/prj/classic/rtl/red_pitaya_top.sv) povezuje procesorski del (PS) s perifernimi komponentami. Projekt je primeren za STEMlab_125-xx_OS_0.98-696, ki ga namestimo na SD kartico iz
[downloads](https://downloads.redpitaya.com/downloads/STEMlab-125-1x/old/) repozitorija starejših projektov.
![](./img/RP_classic.png)
Procesor dostopa do zunanjih enot po vodilu AXI, kjer je naslovni prostor razdeljen na posamezne segmente.
![](./img/RP_mmap.png)
Modul Housekeeping (red_pitaya_id.v) skrbi za ID in osnovne funkcije. Npr. Digital Loopback je na naslovu ```0x40 000 00C```.
Celoten seznam registrov vsebuje [Redpitaya Developer Guide](https://redpitaya.readthedocs.io/en/latest/developerGuide/fpga.html).
## Projekt za Vivado 2019
- Razširi arhiv: [redpitaya-classic.zip](https://lniv.fe.uni-lj.si/courses/div/redpitaya-classic.zip) v svojo projektno mapo. Izvorne datoteke v strojno-opisnem jeziku se nahajajo v podmapi rtl.
- Alternativni arhiv s komponento [filt](filt/filt.png) : [redpitaya-filt.zip](filt/redpitaya-filt.zip) in nastavitev [nastavi.sh](filt/nastavi.sh)
- Odpri program Vivado in se v konzoli postavi v projektno mapo, nato pa izvedi skripto:
```
cd c:/proj/redpitaja
source ./make_project.tcl
```
- Skripta naredi vse korake izdelave projekta, blokovnega diagrama in vključi datoteke. Odpri datoteko red_pitaya_top.sv in preglej kodo. Projekt programa Vivado se nahaja v podmapi project, po prevajanju pa dobimo datoteko red_pitaya_top.bit v project\redpitaya.runs\impl_1.
## Prenos na Red Pitayo
- V laboratoriju LRNV bomo Red Pitayo priklopili kar neposredno na računalnikovo drugo omrežno kartico, ki jo nastavimo na lokalni naslov: 192.168.1.101. Red Pitaya bo dostopna na naslovu 192.168.1.15 v konzoli SSH programa PuTTY (ime: root, geslo: root).
- S programom [WinSCP](https://winscp.net/eng/download.php) prenesemo datoteko red_pitaya_top.bit v lokalno mapo na Red Pitayo (root) in jo preimenujemo v divs.bit.
Nastavitve aplikacije ScopeGen naj bodo narejene tako, da se v FPGA naloži ta datoteka (nastavitve so opisane v: ```/opt/redpitaya/www/apps/scopegenpro/fpga.conf```).
- V spletni brskalnik napišemo naslov: 192.168.1.15 in poženemo aplikacijo Oscilloscope. Najprej preverimo delovanje vgrajene kode tako, da nastavimo en izhod signalnega generatorja.
Kliknemo na kolešček pri OUT1 in nato ON. Oscilogram bo prikazal sinusni izhod funkcijskega generatorja. Najprej bomo nastavili register Digital Loopback na 1, da bo signal generatorja povezan na vhod osciloskopa.
V programu Putty zapišemo ukaz:
```
monitor 0x4000000c 1
```
- Sedaj lahko ugasnemo signalni generator in preizkusimo delovanje našega vezja. Vezje, ki smo ga naredili namesto komponente PID ima registre na naslovih od ```0x40300000``` naprej.
![](./img/RP_zaga.jpg)
## Programska koda
Aplikacijo za nastavljanje registrov napišemo v jeziku C. Uporabimo lahko orodje Xilinx SDK, kjer v projektu nastavimo OS Platform: Linux, ali pa keterikoli urejevalnik kode in prevajalnik na Red Pitayi.
V tem primeru prenesemo izvorno kodo na Red Pitayo, kjer v konzoli prevedemo in poženemo aplikacijo:
```
gcc -o app app.c
./app
```
Primer programa, ki nastavi Digital Loopback na 1:
```C
#include
#include
#include
#include
#include
#include
void Out32(void *adr, int offset, int value)
{
*((uint32_t *)(adr+offset)) = value;
}
int In32(void *adr, int offset)
{
return *((uint32_t *)(adr+offset));
}
int main(int argc, char **argv)
{
int fd;
int BASE = 0x40000000; // Housekeeping base address;
void *adr;
char *name = "/dev/mem";
/* open memory device */
if((fd = open(name, O_RDWR)) < 0) {
perror("open");
return 1;
}
/* map the memory, start from BASE address, size: _SC_PAGESIZE = 4k */
adr = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, BASE);
printf("Loop back is: %d\n", In32(adr, 0x0c));
/* write to loop back register */
Out32(adr, 0x0c, 1);
printf("Loop back set to: %d\n", In32(adr, 0x0c));
munmap(adr, sysconf(_SC_PAGESIZE));
return 0;
}
```