├── LICENSE
├── Makefile
├── README
├── alpine
├── apps
│ ├── css
│ │ ├── main.css
│ │ └── pygments.css
│ ├── index.html
│ ├── server
│ │ ├── Makefile
│ │ └── server.c
│ └── stop.sh
├── etc
│ ├── avahi
│ │ └── services
│ │ │ ├── http.service
│ │ │ ├── sftp-ssh.service
│ │ │ └── ssh.service
│ ├── chrony
│ │ └── chrony.conf
│ ├── conf.d
│ │ ├── gpsd
│ │ ├── hostname
│ │ ├── modloop
│ │ └── syslog
│ ├── dhcpcd.conf
│ ├── dhcpcd.exit-hook
│ ├── dnsmasq.d
│ │ └── ap.conf
│ ├── hostapd
│ │ └── hostapd.conf
│ ├── iptables
│ │ └── rules-save
│ ├── local.d
│ │ └── apps.start
│ └── wpa_supplicant
│ │ └── wpa_supplicant.conf
└── wifi
│ ├── client.sh
│ └── hotspot.sh
├── cfg
├── clocks.xdc
├── dds.mem
├── ports.tcl
├── ports.xdc
└── qmtech_xc7z020.xml
├── cores
├── axi_hub.py
├── axi_hub.v
├── axis_adc_ddr.v
├── axis_fifo.v
├── axis_maxabs_finder.v
├── axis_pps_counter.v
├── axis_variable.v
├── dds.v
├── dsp48.v
└── port_slicer.v
├── dts
├── common.dts
└── initrd.dts
├── helpers
├── build-all.sh
├── build-cores.tcl
└── dds-mem.py
├── mac.txt
├── modules
├── inout_buffer.v
├── input_buffer.v
└── output_buffer.v
├── patches
├── cma.c
├── fsbl.patch
├── initramfs.patch
├── linux-6.6.patch
├── qmtech_xc7z020_fsbl_hooks.c
├── xilinx_devcfg.c
└── xilinx_zynq_defconfig
├── projects
├── common_tools
│ ├── app
│ │ ├── Makefile
│ │ ├── enable-adc.sh
│ │ ├── measure-corr.c
│ │ ├── measure-level.c
│ │ ├── setup-adc.c
│ │ ├── sleep-rand.c
│ │ ├── sleep-to-59.c
│ │ └── update-corr.sh
│ └── block_design.tcl
├── led_blinker_77_76
│ ├── app
│ │ ├── index.html
│ │ └── start.sh
│ ├── block_design.tcl
│ └── ports.xdc
├── sdr_receiver_77_76
│ ├── app
│ │ ├── index.html
│ │ ├── start.sh
│ │ └── stop.sh
│ ├── block_design.tcl
│ ├── client
│ │ ├── convert.py
│ │ └── record.py
│ ├── filters
│ │ └── rx_fir_0.r
│ ├── ports.xdc
│ ├── rx.tcl
│ └── server
│ │ ├── Makefile
│ │ └── sdr-receiver.c
├── sdr_receiver_ft8_77_76
│ ├── app
│ │ ├── Makefile
│ │ ├── decode-ft8.sh
│ │ ├── ft8.cron
│ │ ├── index.html
│ │ ├── start.sh
│ │ ├── stop.sh
│ │ ├── upload-ft8.sh
│ │ ├── upload-to-pskreporter.c
│ │ ├── write-c2-files.c
│ │ └── write-c2-files.cfg
│ ├── block_design.tcl
│ ├── filters
│ │ └── rx_fir_0.r
│ ├── ports.xdc
│ └── rx.tcl
├── sdr_receiver_hpsdr_77_76
│ ├── app
│ │ ├── index.html
│ │ ├── start.sh
│ │ └── stop.sh
│ ├── block_design.tcl
│ ├── filters
│ │ └── rx_fir_0.r
│ ├── ports.xdc
│ ├── rx.tcl
│ └── server
│ │ ├── Makefile
│ │ └── sdr-receiver-hpsdr.c
└── sdr_receiver_wspr_77_76
│ ├── app
│ ├── Makefile
│ ├── decode-wspr.sh
│ ├── index.html
│ ├── start.sh
│ ├── stop.sh
│ ├── write-c2-files.c
│ ├── write-c2-files.cfg
│ └── wspr.cron
│ ├── block_design.tcl
│ ├── filters
│ └── rx_fir_0.r
│ ├── ports.xdc
│ └── rx.tcl
└── scripts
├── alpine.sh
├── bitstream.tcl
├── core.tcl
├── devicetree.tcl
├── fsbl.tcl
├── hwdef.tcl
└── project.tcl
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2024 Pavel Demin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # 'make' builds everything
2 | # 'make clean' deletes everything except source files and Makefile
3 | #
4 | # You need to set NAME, PART and PROC for your project.
5 | # NAME is the base name for most of the generated files.
6 |
7 | NAME = led_blinker
8 | PART = xc7z020clg484-1
9 | PROC = ps7_cortexa9_0
10 |
11 | FILES = $(wildcard cores/*.v)
12 | CORES = $(FILES:.v=)
13 |
14 | VIVADO = vivado -nolog -nojournal -mode batch
15 | XSCT = xsct
16 | RM = rm -rf
17 |
18 | INITRAMFS_TAG = 3.20
19 | LINUX_TAG = 6.6
20 | DTREE_TAG = xilinx_v2023.1
21 |
22 | INITRAMFS_DIR = tmp/initramfs-$(INITRAMFS_TAG)
23 | LINUX_DIR = tmp/linux-$(LINUX_TAG)
24 | DTREE_DIR = tmp/device-tree-xlnx-$(DTREE_TAG)
25 |
26 | LINUX_TAR = tmp/linux-$(LINUX_TAG).tar.xz
27 | DTREE_TAR = tmp/device-tree-xlnx-$(DTREE_TAG).tar.gz
28 |
29 | INITRAMFS_URL = https://dl-cdn.alpinelinux.org/alpine/v$(INITRAMFS_TAG)/releases/armv7/netboot/initramfs-lts
30 | LINUX_URL = https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-$(LINUX_TAG).44.tar.xz
31 | DTREE_URL = https://github.com/Xilinx/device-tree-xlnx/archive/$(DTREE_TAG).tar.gz
32 |
33 | SSBL_URL = https://github.com/pavel-demin/ssbl/releases/latest/download/ssbl.elf
34 |
35 | RTL8188_TAR = tmp/rtl8188eu-main.tar.gz
36 | RTL8188_URL = https://github.com/pavel-demin/rtl8188eu/archive/main.tar.gz
37 |
38 | .PRECIOUS: tmp/cores/% tmp/%.xpr tmp/%.xsa tmp/%.bit tmp/%.fsbl/executable.elf tmp/%.tree/system-top.dts
39 |
40 | all: tmp/$(NAME).bit boot.bin
41 |
42 | cores: $(addprefix tmp/, $(CORES))
43 |
44 | xpr: tmp/$(NAME).xpr
45 |
46 | bit: tmp/$(NAME).bit
47 |
48 | $(LINUX_TAR):
49 | mkdir -p $(@D)
50 | curl -L $(LINUX_URL) -o $@
51 |
52 | $(DTREE_TAR):
53 | mkdir -p $(@D)
54 | curl -L $(DTREE_URL) -o $@
55 |
56 | $(RTL8188_TAR):
57 | mkdir -p $(@D)
58 | curl -L $(RTL8188_URL) -o $@
59 |
60 | $(INITRAMFS_DIR):
61 | mkdir -p $@
62 | curl -L $(INITRAMFS_URL) | gunzip | cpio -id --directory=$@
63 | patch -d $@ -p 0 < patches/initramfs.patch
64 | rm -rf $@/etc/modprobe.d $@/lib/firmware $@/lib/modules $@/var
65 |
66 | $(LINUX_DIR): $(LINUX_TAR) $(RTL8188_TAR)
67 | mkdir -p $@
68 | tar -Jxf $< --strip-components=1 --directory=$@
69 | mkdir -p $@/drivers/net/wireless/realtek/rtl8188eu
70 | tar -zxf $(RTL8188_TAR) --strip-components=1 --directory=$@/drivers/net/wireless/realtek/rtl8188eu
71 | patch -d tmp -p 0 < patches/linux-$(LINUX_TAG).patch
72 | cp patches/cma.c $@/drivers/char
73 | cp patches/xilinx_devcfg.c $@/drivers/char
74 | cp patches/xilinx_zynq_defconfig $@/arch/arm/configs
75 |
76 | $(DTREE_DIR): $(DTREE_TAR)
77 | mkdir -p $@
78 | tar -zxf $< --strip-components=1 --directory=$@
79 |
80 | tmp/ssbl.elf:
81 | mkdir -p $(@D)
82 | curl -L $(SSBL_URL) -o $@
83 |
84 | zImage.bin: $(LINUX_DIR)
85 | make -C $< mrproper
86 | make -C $< ARCH=arm -j $(shell nproc 2> /dev/null || echo 1) \
87 | CROSS_COMPILE=arm-linux-gnueabihf- LOADADDR=0x8000 \
88 | xilinx_zynq_defconfig zImage modules
89 | cp $ ../../$@
93 | truncate -s 4M $@
94 |
95 | boot.bin: tmp/$(NAME).fsbl/executable.elf tmp/ssbl.elf initrd.dtb zImage.bin initrd.bin
96 | echo "img:{[bootloader] tmp/$(NAME).fsbl/executable.elf tmp/ssbl.elf [load=0x2000000] initrd.dtb [load=0x2008000] zImage.bin [load=0x3000000] initrd.bin}" > tmp/boot.bif
97 | bootgen -image tmp/boot.bif -w -o $@
98 |
99 | initrd.dtb: tmp/$(NAME).tree/system-top.dts
100 | dtc -I dts -O dtb -o $@ -i tmp/$(NAME).tree -i dts dts/initrd.dts
101 |
102 | tmp/cores/%: cores/%.v
103 | mkdir -p $(@D)
104 | $(VIVADO) -source scripts/core.tcl -tclargs $* $(PART)
105 |
106 | tmp/%.xpr: projects/% $(addprefix tmp/, $(CORES))
107 | mkdir -p $(@D)
108 | $(VIVADO) -source scripts/project.tcl -tclargs $* $(PART)
109 |
110 | tmp/%.xsa: tmp/%.xpr
111 | mkdir -p $(@D)
112 | $(VIVADO) -source scripts/hwdef.tcl -tclargs $*
113 |
114 | tmp/%.bit: tmp/%.xpr
115 | mkdir -p $(@D)
116 | $(VIVADO) -source scripts/bitstream.tcl -tclargs $*
117 |
118 | tmp/%.fsbl/executable.elf: tmp/%.xsa
119 | mkdir -p $(@D)
120 | $(XSCT) scripts/fsbl.tcl $* $(PROC)
121 | cp patches/qmtech_xc7z020_fsbl_hooks.c $(@D)
122 | patch $(@D)/fsbl_hooks.c patches/fsbl.patch
123 | make -C $(@D)
124 |
125 | tmp/%.tree/system-top.dts: tmp/%.xsa $(DTREE_DIR)
126 | mkdir -p $(@D)
127 | $(XSCT) scripts/devicetree.tcl $* $(PROC) $(DTREE_DIR)
128 | sed -i 's|#include|/include/|' $@
129 |
130 | clean:
131 | $(RM) zImage.bin initrd.bin boot.bin initrd.dtb tmp
132 | $(RM) .Xil usage_statistics_webtalk.html usage_statistics_webtalk.xml
133 | $(RM) vivado*.jou vivado*.log
134 | $(RM) webtalk*.jou webtalk*.log
135 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | Notes on the QMTECH ZYNQ XC7Z020 starter kit
2 |
3 | https://pavel-demin.github.io/qmtech-xc7z020-notes/
4 |
--------------------------------------------------------------------------------
/alpine/apps/css/main.css:
--------------------------------------------------------------------------------
1 | body { font-family: Calibri, Verdana, Liberation Sans, DejaVu Sans, sans-serif; background-color: #f5f5f5; max-width: 800px; line-height: 1.4; margin-left: auto; margin-right: auto; padding-bottom: 3em; }
2 | h1, h2, h3, h4 { font-weight: normal; }
3 | a { color: #bf2334; text-decoration: none; }
4 | a:hover { text-decoration: underline; }
5 | pre, code { font-family: Consolas, Menlo, Liberation Mono, DejaVu Sans Mono, monospace; background: #f5f5f5; border-radius: 0.3em }
6 | code { padding: 0 0.3em; white-space: nowrap; }
7 | pre { padding: 0.1em 0.3em; overflow-x: auto; }
8 | pre > code { padding: 0; background: 0; white-space: pre }
9 | td, th { border: 1px solid #d3d3d3; padding: 0.1em 0.3em; }
10 | th { text-align: left; background-color: #f5f5f5; }
11 | tr.even td { background-color: #f5f5f5; }
12 | img { max-width: 100%; }
13 |
14 | #header { color: #bf2334; padding: 0 1em; }
15 | #header a { color: #bf2334; text-decoration: none; }
16 | #logo { margin-bottom: -1.4em; }
17 | #menu { padding-bottom: 0.3em; text-align: right; }
18 | #menu a { padding-left: 1em; }
19 | #content { background-color: #fff; padding: 1em 1em; border-radius: 0.6em; }
20 |
21 | @media print { #header { display: none; } }
22 |
--------------------------------------------------------------------------------
/alpine/apps/css/pygments.css:
--------------------------------------------------------------------------------
1 | .highlight .c { color: #008800; font-style: italic }
2 | .highlight .err { color: #a61717; background-color: #e3d2d2 }
3 | .highlight .k { color: #000080; font-weight: bold }
4 | .highlight .cm { color: #008800; font-style: italic }
5 | .highlight .cp { color: #008080 }
6 | .highlight .c1 { color: #008800; font-style: italic }
7 | .highlight .cs { color: #008800; font-weight: bold }
8 | .highlight .gd { color: #000000; background-color: #ffdddd }
9 | .highlight .ge { font-style: italic }
10 | .highlight .gr { color: #aa0000 }
11 | .highlight .gh { color: #999999 }
12 | .highlight .gi { color: #000000; background-color: #ddffdd }
13 | .highlight .go { color: #888888 }
14 | .highlight .gp { color: #555555 }
15 | .highlight .gs { font-weight: bold }
16 | .highlight .gu { color: #aaaaaa }
17 | .highlight .gt { color: #aa0000 }
18 | .highlight .kc { color: #000080; font-weight: bold }
19 | .highlight .kd { color: #000080; font-weight: bold }
20 | .highlight .kn { color: #000080; font-weight: bold }
21 | .highlight .kp { color: #000080; font-weight: bold }
22 | .highlight .kr { color: #000080; font-weight: bold }
23 | .highlight .kt { color: #000080; font-weight: bold }
24 | .highlight .m { color: #0000ff }
25 | .highlight .s { color: #0000ff }
26 | .highlight .na { color: #ff0000 }
27 | .highlight .nt { color: #000080; font-weight: bold }
28 | .highlight .ow { font-weight: bold }
29 | .highlight .w { color: #bbbbbb }
30 | .highlight .mf { color: #0000ff }
31 | .highlight .mh { color: #0000ff }
32 | .highlight .mi { color: #0000ff }
33 | .highlight .mo { color: #0000ff }
34 | .highlight .sb { color: #0000ff }
35 | .highlight .sc { color: #800080 }
36 | .highlight .sd { color: #0000ff }
37 | .highlight .s2 { color: #0000ff }
38 | .highlight .se { color: #0000ff }
39 | .highlight .sh { color: #0000ff }
40 | .highlight .si { color: #0000ff }
41 | .highlight .sx { color: #0000ff }
42 | .highlight .sr { color: #0000ff }
43 | .highlight .s1 { color: #0000ff }
44 | .highlight .ss { color: #0000ff }
45 | .highlight .il { color: #0000ff }
46 |
--------------------------------------------------------------------------------
/alpine/apps/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | QMTECH XC7Z020 Apps
6 |
7 |
8 |
9 |
18 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/alpine/apps/server/Makefile:
--------------------------------------------------------------------------------
1 | all: server
2 |
3 | server: server.c
4 | gcc -o $@ $^
5 |
6 | clean:
7 | rm -f server
8 |
--------------------------------------------------------------------------------
/alpine/apps/server/server.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #define DIR "/sys/bus/iio/devices/iio:device0/"
8 |
9 | const char *directory = "/media/mmcblk0p1/apps";
10 | const char *forbidden = "HTTP/1.0 403 Forbidden\n\n";
11 | const char *redirect = "HTTP/1.0 302 Found\nLocation: /\n\n";
12 | const char *okheader = "HTTP/1.0 200 OK\n\n";
13 |
14 | void detach(char *path)
15 | {
16 | int pid = fork();
17 | if(pid != 0) return;
18 | close(STDIN_FILENO);
19 | close(STDOUT_FILENO);
20 | close(STDERR_FILENO);
21 | execlp(path, path, NULL);
22 | exit(0);
23 | }
24 |
25 | float read_value(char *name)
26 | {
27 | FILE *fp;
28 | char buffer[64];
29 |
30 | if((fp = fopen(name, "r")) == NULL)
31 | {
32 | printf("Cannot open %s.\n", name);
33 | exit(1);
34 | }
35 |
36 | fgets(buffer, sizeof(buffer), fp);
37 | fclose(fp);
38 |
39 | return atof(buffer);
40 | }
41 |
42 | int main()
43 | {
44 | FILE *fp;
45 | int i, j;
46 | float off, raw, scl;
47 | struct stat sb;
48 | size_t size;
49 | char buffer[256];
50 | char path[284];
51 |
52 | if(fgets(buffer, 256, stdin) == NULL)
53 | {
54 | fwrite(forbidden, 24, 1, stdout);
55 | return 1;
56 | }
57 |
58 | if(buffer[4] != '/')
59 | {
60 | fwrite(forbidden, 24, 1, stdout);
61 | return 1;
62 | }
63 |
64 | if(strncmp(buffer, "GET ", 4) && strncmp(buffer, "get ", 4))
65 | {
66 | fwrite(forbidden, 24, 1, stdout);
67 | return 1;
68 | }
69 |
70 | for(i = 5; i < 255; ++i)
71 | {
72 | if(buffer[i] == ' ')
73 | {
74 | buffer[i] = 0;
75 | break;
76 | }
77 | }
78 |
79 | for(j = 5; j < i - 1; ++j)
80 | {
81 | if(buffer[j] == '.' && buffer[j + 1] == '.')
82 | {
83 | fwrite(forbidden, 24, 1, stdout);
84 | return 1;
85 | }
86 | }
87 |
88 | if(i == 10 && strncmp(buffer + 5, "temp0", 5) == 0)
89 | {
90 | fwrite(okheader, 17, 1, stdout);
91 | off = read_value(DIR "in_temp0_offset");
92 | raw = read_value(DIR "in_temp0_raw");
93 | scl = read_value(DIR "in_temp0_scale");
94 | printf("%.1f\n", (off + raw) * scl / 1000);
95 | return 0;
96 | }
97 |
98 | memcpy(path, directory, 21);
99 | memcpy(path + 21, buffer + 4, i - 3);
100 |
101 | if(stat(path, &sb) < 0)
102 | {
103 | fwrite(redirect, 32, 1, stdout);
104 | return 1;
105 | }
106 |
107 | if(S_ISDIR(sb.st_mode))
108 | {
109 | memcpy(path + 21 + i - 4, "/start.sh", 10);
110 | detach(path);
111 | memcpy(path + 21 + i - 4, "/index.html", 12);
112 | }
113 |
114 | fp = fopen(path, "r");
115 |
116 | if(fp == NULL)
117 | {
118 | fwrite(redirect, 32, 1, stdout);
119 | return 1;
120 | }
121 |
122 | fwrite(okheader, 17, 1, stdout);
123 |
124 | while((size = fread(buffer, 1, 256, fp)) > 0)
125 | {
126 | if(!fwrite(buffer, size, 1, stdout)) break;
127 | }
128 |
129 | return 0;
130 | }
131 |
--------------------------------------------------------------------------------
/alpine/apps/stop.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | for script in /media/mmcblk0p1/apps/*/stop.sh
4 | do
5 | $script &
6 | done
7 |
8 | wait
9 |
--------------------------------------------------------------------------------
/alpine/etc/avahi/services/http.service:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %h HTTP
7 |
8 |
9 | _http._tcp
10 | 80
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/alpine/etc/avahi/services/sftp-ssh.service:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %h SFTP-SSH
7 |
8 |
9 | _sftp-ssh._tcp
10 | 22
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/alpine/etc/avahi/services/ssh.service:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %h SSH
7 |
8 |
9 | _ssh._tcp
10 | 22
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/alpine/etc/chrony/chrony.conf:
--------------------------------------------------------------------------------
1 | refclock SHM 2 refid PPS precision 1e-9
2 | pool pool.ntp.org iburst offline
3 | makestep 1 -1
4 | driftfile /var/lib/chrony/chrony.drift
5 |
--------------------------------------------------------------------------------
/alpine/etc/conf.d/gpsd:
--------------------------------------------------------------------------------
1 | GPSD_OPTIONS="-n"
2 | DEVICES="/dev/ttyPS1 /dev/pps0"
3 | GPSD_SOCKET="/var/run/gpsd.sock"
4 |
--------------------------------------------------------------------------------
/alpine/etc/conf.d/hostname:
--------------------------------------------------------------------------------
1 | awk -F : '{print "sdr-"$4$5$6}' /sys/class/net/eth0/address > /etc/hostname
2 |
--------------------------------------------------------------------------------
/alpine/etc/conf.d/modloop:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pavel-demin/qmtech-xc7z020-notes/1b255b7624033c0004926dea01875e07adcc5587/alpine/etc/conf.d/modloop
--------------------------------------------------------------------------------
/alpine/etc/conf.d/syslog:
--------------------------------------------------------------------------------
1 | SYSLOGD_OPTS=""
2 |
--------------------------------------------------------------------------------
/alpine/etc/dhcpcd.conf:
--------------------------------------------------------------------------------
1 | # Inform the DHCP server of our hostname for DDNS.
2 | hostname
3 |
4 | # Use the hardware address of the interface for the Client ID.
5 | clientid
6 |
7 | # Rapid commit support.
8 | # Safe to enable by default because it requires the equivalent option set
9 | # on the server to actually work.
10 | option rapid_commit
11 |
12 | # A list of options to request from the DHCP server.
13 | option domain_name_servers, domain_name, domain_search, host_name
14 | option classless_static_routes
15 | # Most distributions have NTP support.
16 | option ntp_servers
17 | # Respect the network MTU. This is applied to DHCP routes.
18 | option interface_mtu
19 |
20 | # A ServerID is required by RFC2131.
21 | require dhcp_server_identifier
22 |
23 | # Generate Stable Private IPv6 Addresses instead of hardware based ones.
24 | slaac private
25 |
26 | # Don't send any ARP requests.
27 | noarp
28 |
29 | # Only configure IPv4.
30 | ipv4only
31 |
32 | # Wait 20 seconds before falling back to static profile.
33 | reboot 20
34 |
35 | # Configure loopback interface.
36 | interface lo
37 | static ip_address=127.0.0.1/8
38 |
39 | # Define static profile for eth0.
40 | profile static_eth0
41 | static ip_address=192.168.1.100/24
42 | static routers=192.168.1.1
43 | static domain_name_servers=192.168.1.1
44 |
45 | # Fallback to static profile on eth0.
46 | interface eth0
47 | fallback static_eth0
48 |
49 | # Define static profile for mvl0.
50 | profile static_mvl0
51 | static ip_address=192.168.1.101/24
52 | static routers=192.168.1.1
53 | static domain_name_servers=192.168.1.1
54 |
55 | # Fallback to static profile on mvl0.
56 | interface mvl0
57 | fallback static_mvl0
58 |
59 | # Static IP address for Wi-Fi access point.
60 | interface wlan0
61 | static ip_address=192.168.42.1/24
62 |
--------------------------------------------------------------------------------
/alpine/etc/dhcpcd.exit-hook:
--------------------------------------------------------------------------------
1 | if [ "$interface" = wlan0 ]; then
2 | case "$reason" in
3 | PREINIT) (sleep 3; openrc wifi > /dev/null 2>&1) & ;;
4 | DEPARTED) (sleep 3; openrc default > /dev/null 2>&1) & ;;
5 | esac
6 | fi
7 |
8 | if [ "$interface" = eth0 ] && [ "$reason" = PREINIT ]; then
9 | addr=`cat /media/mmcblk0p1/mac.txt`
10 | name=`echo $addr | awk -F : '{print "sdr-" tolower($4$5$6)}'`
11 | ip link set dev eth0 down
12 | ip link set dev eth0 address $addr
13 | ip link set dev eth0 up
14 | hostname $name
15 | fi
16 |
17 | if $if_up; then
18 | (sleep 3; chronyc online > /dev/null 2>&1) &
19 | fi
20 |
--------------------------------------------------------------------------------
/alpine/etc/dnsmasq.d/ap.conf:
--------------------------------------------------------------------------------
1 | interface=wlan0
2 | dhcp-range=192.168.42.20,192.168.42.254,12h
3 |
--------------------------------------------------------------------------------
/alpine/etc/hostapd/hostapd.conf:
--------------------------------------------------------------------------------
1 | interface=wlan0
2 | ssid=QMTECH XC7Z020
3 | driver=nl80211
4 | hw_mode=g
5 | channel=6
6 | auth_algs=1
7 | wpa=2
8 | wpa_passphrase=QMTECH XC7Z020
9 | wpa_key_mgmt=WPA-PSK
10 | wpa_pairwise=CCMP
11 | rsn_pairwise=CCMP
12 |
--------------------------------------------------------------------------------
/alpine/etc/iptables/rules-save:
--------------------------------------------------------------------------------
1 | *nat
2 | :PREROUTING ACCEPT [0:0]
3 | :INPUT ACCEPT [0:0]
4 | :OUTPUT ACCEPT [0:0]
5 | :POSTROUTING ACCEPT [0:0]
6 | -A POSTROUTING -o eth0 -j MASQUERADE
7 | COMMIT
8 | *mangle
9 | :PREROUTING ACCEPT [0:0]
10 | :INPUT ACCEPT [0:0]
11 | :FORWARD ACCEPT [0:0]
12 | :OUTPUT ACCEPT [0:0]
13 | :POSTROUTING ACCEPT [0:0]
14 | COMMIT
15 | *filter
16 | :INPUT ACCEPT [0:0]
17 | :FORWARD ACCEPT [0:0]
18 | :OUTPUT ACCEPT [0:0]
19 | -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
20 | -A FORWARD -i wlan0 -o eth0 -j ACCEPT
21 | COMMIT
22 |
--------------------------------------------------------------------------------
/alpine/etc/local.d/apps.start:
--------------------------------------------------------------------------------
1 | tcpserver -H -l 0 0 80 /media/mmcblk0p1/apps/server/server &
2 | /media/mmcblk0p1/start.sh &
3 |
--------------------------------------------------------------------------------
/alpine/etc/wpa_supplicant/wpa_supplicant.conf:
--------------------------------------------------------------------------------
1 | network={
2 | ssid="QMTECH XC7Z020"
3 | #psk="QMTECH XC7Z020"
4 | psk=965fa13b638ffb1f275132c897b923339b4aaa9b913afa5670c15e1173eaf9d1
5 | }
6 |
--------------------------------------------------------------------------------
/alpine/wifi/client.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | openrc default
4 |
5 | rc-update del iptables wifi
6 | rc-update del dnsmasq wifi
7 | rc-update del hostapd wifi
8 |
9 | rc-update add wpa_supplicant wifi
10 |
11 | sed -i '/^interface wlan0/{s/^interface/#interface/;n;s/^static/#static/}' /etc/dhcpcd.conf
12 |
13 | service dhcpcd restart
14 |
--------------------------------------------------------------------------------
/alpine/wifi/hotspot.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | openrc default
4 |
5 | rc-update del wpa_supplicant wifi
6 |
7 | rc-update add iptables wifi
8 | rc-update add dnsmasq wifi
9 | rc-update add hostapd wifi
10 |
11 | sed -i '/^#interface wlan0/{s/^#interface/interface/;n;s/^#static/static/}' /etc/dhcpcd.conf
12 |
13 | service dhcpcd restart
14 |
--------------------------------------------------------------------------------
/cfg/clocks.xdc:
--------------------------------------------------------------------------------
1 | create_clock -period 20 -waveform {0 10} [get_ports clk_i]
2 |
--------------------------------------------------------------------------------
/cfg/ports.tcl:
--------------------------------------------------------------------------------
1 | ### clock input
2 |
3 | create_bd_port -dir I clk_i
4 |
5 | ### LED
6 |
7 | create_bd_port -dir O led_o
8 |
9 | ### PPS
10 |
11 | create_bd_port -dir I pps_i
12 |
--------------------------------------------------------------------------------
/cfg/ports.xdc:
--------------------------------------------------------------------------------
1 | ### clock input
2 |
3 | set_property IOSTANDARD LVCMOS33 [get_ports clk_i]
4 | set_property PACKAGE_PIN M19 [get_ports clk_i]
5 |
6 | ### LED
7 |
8 | set_property IOSTANDARD LVCMOS33 [get_ports led_o]
9 | set_property SLEW SLOW [get_ports led_o]
10 | set_property DRIVE 4 [get_ports led_o]
11 |
12 | set_property PACKAGE_PIN P22 [get_ports led_o]
13 |
14 | ### PPS
15 |
16 | set_property IOSTANDARD LVCMOS33 [get_ports pps_i]
17 | set_property PACKAGE_PIN L22 [get_ports pps_i]
18 |
--------------------------------------------------------------------------------
/cfg/qmtech_xc7z020.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/cores/axi_hub.py:
--------------------------------------------------------------------------------
1 | hub_size = 6
2 | source = """
3 | `timescale 1 ns / 1 ps
4 |
5 | module axi_hub #
6 | (
7 | parameter integer CFG_DATA_WIDTH = 1024,
8 | parameter integer STS_DATA_WIDTH = 1024
9 | )
10 | (
11 | input wire aclk,
12 | input wire aresetn,
13 |
14 | input wire [11:0] s_axi_awid,
15 | input wire [31:0] s_axi_awaddr,
16 | input wire s_axi_awvalid,
17 | output wire s_axi_awready,
18 |
19 | input wire [3:0] s_axi_wstrb,
20 | input wire s_axi_wlast,
21 | input wire [31:0] s_axi_wdata,
22 | input wire s_axi_wvalid,
23 | output wire s_axi_wready,
24 |
25 | output wire [11:0] s_axi_bid,
26 | output wire s_axi_bvalid,
27 | input wire s_axi_bready,
28 |
29 | input wire [11:0] s_axi_arid,
30 | input wire [3:0] s_axi_arlen,
31 | input wire [31:0] s_axi_araddr,
32 | input wire s_axi_arvalid,
33 | output wire s_axi_arready,
34 |
35 | output wire [11:0] s_axi_rid,
36 | output wire s_axi_rlast,
37 | output wire [31:0] s_axi_rdata,
38 | output wire s_axi_rvalid,
39 | input wire s_axi_rready,
40 |
41 | output wire [CFG_DATA_WIDTH-1:0] cfg_data,
42 |
43 | input wire [STS_DATA_WIDTH-1:0] sts_data,
44 | {% for i in range(hub_size) -%}
45 | {% set index = "%02d" % i %}
46 | (* X_INTERFACE_INFO = "xilinx.com:interface:bram:1.0 b{{index}}_bram CLK" *)
47 | output wire b{{index}}_bram_clk,
48 | (* X_INTERFACE_INFO = "xilinx.com:interface:bram:1.0 b{{index}}_bram RST" *)
49 | output wire b{{index}}_bram_rst,
50 | (* X_INTERFACE_INFO = "xilinx.com:interface:bram:1.0 b{{index}}_bram EN" *)
51 | output wire b{{index}}_bram_en,
52 | (* X_INTERFACE_INFO = "xilinx.com:interface:bram:1.0 b{{index}}_bram WE" *)
53 | output wire [3:0] b{{index}}_bram_we,
54 | (* X_INTERFACE_INFO = "xilinx.com:interface:bram:1.0 b{{index}}_bram ADDR" *)
55 | output wire [21:0] b{{index}}_bram_addr,
56 | (* X_INTERFACE_INFO = "xilinx.com:interface:bram:1.0 b{{index}}_bram DIN" *)
57 | output wire [31:0] b{{index}}_bram_wdata,
58 | (* X_INTERFACE_INFO = "xilinx.com:interface:bram:1.0 b{{index}}_bram DOUT" *)
59 | input wire [31:0] b{{index}}_bram_rdata,
60 |
61 | input wire [31:0] s{{index}}_axis_tdata,
62 | input wire s{{index}}_axis_tvalid,
63 | output wire s{{index}}_axis_tready,
64 |
65 | output wire [31:0] m{{index}}_axis_tdata,
66 | output wire m{{index}}_axis_tvalid,
67 | input wire m{{index}}_axis_tready{% if not loop.last %},{% endif %}
68 | {% endfor -%}
69 | );
70 |
71 | localparam integer HUB_SIZE = {{hub_size}};
72 | localparam integer MUX_SIZE = HUB_SIZE + 2;
73 | localparam integer CFG_SIZE = CFG_DATA_WIDTH / 32;
74 | localparam integer CFG_WIDTH = CFG_SIZE > 1 ? $clog2(CFG_SIZE) : 1;
75 | localparam integer STS_SIZE = STS_DATA_WIDTH / 32;
76 | localparam integer STS_WIDTH = STS_SIZE > 1 ? $clog2(STS_SIZE) : 1;
77 |
78 | reg [3:0] int_awcntr_reg, int_awcntr_next;
79 | reg [3:0] int_arcntr_reg, int_arcntr_next;
80 |
81 | wire int_awvalid_wire, int_awready_wire;
82 | wire int_wvalid_wire, int_wready_wire;
83 | wire int_bvalid_wire, int_bready_wire;
84 | wire int_arvalid_wire, int_arready_wire;
85 | wire int_rvalid_wire, int_rready_wire;
86 |
87 | wire [11:0] int_awid_wire;
88 | wire [31:0] int_awaddr_wire;
89 |
90 | wire [3:0] int_wstrb_wire;
91 | wire int_wlast_wire;
92 | wire [31:0] int_wdata_wire;
93 |
94 | wire [11:0] int_arid_wire;
95 | wire [3:0] int_arlen_wire;
96 | wire [31:0] int_araddr_wire;
97 |
98 | wire [11:0] int_rid_wire;
99 | wire int_rlast_wire;
100 | wire [31:0] int_rdata_wire [MUX_SIZE-1:0];
101 |
102 | wire [31:0] int_sdata_wire [HUB_SIZE-1:0];
103 | wire [31:0] int_mdata_wire [HUB_SIZE-1:0];
104 | wire [HUB_SIZE-1:0] int_svalid_wire, int_sready_wire;
105 | wire [HUB_SIZE-1:0] int_mvalid_wire, int_mready_wire;
106 |
107 | wire [31:0] int_bdata_wire [HUB_SIZE-1:0];
108 |
109 | wire [21:0] int_waddr_wire;
110 | wire [21:0] int_raddr_wire;
111 |
112 | wire [31:0] int_cfg_mux [CFG_SIZE-1:0];
113 | wire [31:0] int_sts_mux [STS_SIZE-1:0];
114 |
115 | wire [31:0] int_rdata_mux [MUX_SIZE-1:0];
116 | wire [MUX_SIZE-1:0] int_wsel_wire, int_rsel_wire;
117 |
118 | wire [HUB_SIZE-1:0] int_bsel_wire;
119 |
120 | wire [CFG_SIZE-1:0] int_ce_wire;
121 | wire int_we_wire, int_re_wire;
122 |
123 | genvar j, k;
124 |
125 | assign int_awready_wire = int_bready_wire & int_wvalid_wire & int_wlast_wire;
126 | assign int_wready_wire = int_bready_wire & int_awvalid_wire;
127 | assign int_bvalid_wire = int_awvalid_wire & int_wvalid_wire & int_wlast_wire;
128 |
129 | assign int_arready_wire = int_rready_wire & int_rlast_wire;
130 | assign int_rvalid_wire = int_arvalid_wire;
131 | assign int_rlast_wire = int_arcntr_reg == int_arlen_wire;
132 |
133 | assign int_we_wire = int_bready_wire & int_awvalid_wire & int_wvalid_wire;
134 | assign int_re_wire = int_rready_wire & int_arvalid_wire;
135 |
136 | assign int_waddr_wire = int_awaddr_wire[23:2] + int_awcntr_reg;
137 | assign int_raddr_wire = int_araddr_wire[23:2] + int_arcntr_reg;
138 |
139 | assign int_rdata_wire[0] = int_rdata_mux[int_araddr_wire[27:24]];
140 |
141 | assign int_rdata_mux[0] = int_cfg_mux[int_raddr_wire[CFG_WIDTH-1:0]];
142 | assign int_rdata_mux[1] = int_sts_mux[int_raddr_wire[STS_WIDTH-1:0]];
143 |
144 | generate
145 | for(j = 0; j < HUB_SIZE; j = j + 1)
146 | begin : MUXES
147 | assign int_rdata_mux[j+2] = int_svalid_wire[j] ? int_sdata_wire[j] : 32'd0;
148 | assign int_rdata_wire[j+2] = int_bsel_wire[j] ? int_bdata_wire[j] : 32'd0;
149 | assign int_mdata_wire[j] = int_wdata_wire;
150 | assign int_mvalid_wire[j] = int_wsel_wire[j+2];
151 | assign int_sready_wire[j] = int_rsel_wire[j+2];
152 | end
153 | endgenerate
154 |
155 | generate
156 | for(j = 0; j < MUX_SIZE; j = j + 1)
157 | begin : SELECTS
158 | assign int_wsel_wire[j] = int_we_wire & (int_awaddr_wire[27:24] == j);
159 | assign int_rsel_wire[j] = int_re_wire & (int_araddr_wire[27:24] == j);
160 | end
161 | endgenerate
162 |
163 | generate
164 | for(j = 0; j < CFG_SIZE; j = j + 1)
165 | begin : CFG_WORDS
166 | assign int_cfg_mux[j] = cfg_data[j*32+31:j*32];
167 | assign int_ce_wire[j] = int_wsel_wire[0] & (int_waddr_wire[CFG_WIDTH-1:0] == j);
168 | for(k = 0; k < 32; k = k + 1)
169 | begin : CFG_BITS
170 | FDRE #(
171 | .INIT(1'b0)
172 | ) FDRE_inst (
173 | .CE(int_ce_wire[j] & int_wstrb_wire[k/8]),
174 | .C(aclk),
175 | .R(~aresetn),
176 | .D(int_wdata_wire[k]),
177 | .Q(cfg_data[j*32 + k])
178 | );
179 | end
180 | end
181 | endgenerate
182 |
183 | generate
184 | for(j = 0; j < STS_SIZE; j = j + 1)
185 | begin : STS_WORDS
186 | assign int_sts_mux[j] = sts_data[j*32+31:j*32];
187 | end
188 | endgenerate
189 |
190 | always @(posedge aclk)
191 | begin
192 | if(~aresetn)
193 | begin
194 | int_awcntr_reg <= 4'd0;
195 | int_arcntr_reg <= 4'd0;
196 | end
197 | else
198 | begin
199 | int_awcntr_reg <= int_awcntr_next;
200 | int_arcntr_reg <= int_arcntr_next;
201 | end
202 | end
203 |
204 | always @*
205 | begin
206 | int_awcntr_next = int_awcntr_reg;
207 | int_arcntr_next = int_arcntr_reg;
208 |
209 | if(int_awvalid_wire & int_awready_wire)
210 | begin
211 | int_awcntr_next = 4'd0;
212 | end
213 |
214 | if(int_arvalid_wire & int_arready_wire)
215 | begin
216 | int_arcntr_next = 4'd0;
217 | end
218 |
219 | if(~int_wlast_wire & int_we_wire)
220 | begin
221 | int_awcntr_next = int_awcntr_reg + 1'b1;
222 | end
223 |
224 | if(~int_rlast_wire & int_re_wire)
225 | begin
226 | int_arcntr_next = int_arcntr_reg + 1'b1;
227 | end
228 | end
229 |
230 | inout_buffer #(
231 | .DATA_WIDTH(44)
232 | ) buf_0 (
233 | .aclk(aclk), .aresetn(aresetn),
234 | .in_data({s_axi_awid, s_axi_awaddr}),
235 | .in_valid(s_axi_awvalid), .in_ready(s_axi_awready),
236 | .out_data({int_awid_wire, int_awaddr_wire}),
237 | .out_valid(int_awvalid_wire), .out_ready(int_awready_wire)
238 | );
239 |
240 | inout_buffer #(
241 | .DATA_WIDTH(37)
242 | ) buf_1 (
243 | .aclk(aclk), .aresetn(aresetn),
244 | .in_data({s_axi_wstrb, s_axi_wlast, s_axi_wdata}),
245 | .in_valid(s_axi_wvalid), .in_ready(s_axi_wready),
246 | .out_data({int_wstrb_wire, int_wlast_wire, int_wdata_wire}),
247 | .out_valid(int_wvalid_wire), .out_ready(int_wready_wire)
248 | );
249 |
250 | output_buffer #(
251 | .DATA_WIDTH(12)
252 | ) buf_2 (
253 | .aclk(aclk), .aresetn(aresetn),
254 | .in_data(int_awid_wire), .in_valid(int_bvalid_wire), .in_ready(int_bready_wire),
255 | .out_data(s_axi_bid), .out_valid(s_axi_bvalid), .out_ready(s_axi_bready)
256 | );
257 |
258 | inout_buffer #(
259 | .DATA_WIDTH(48)
260 | ) buf_3 (
261 | .aclk(aclk), .aresetn(aresetn),
262 | .in_data({s_axi_arid, s_axi_arlen, s_axi_araddr}),
263 | .in_valid(s_axi_arvalid), .in_ready(s_axi_arready),
264 | .out_data({int_arid_wire, int_arlen_wire, int_araddr_wire}),
265 | .out_valid(int_arvalid_wire), .out_ready(int_arready_wire)
266 | );
267 |
268 | output_buffer #(
269 | .DATA_WIDTH(HUB_SIZE + 45)
270 | ) buf_4 (
271 | .aclk(aclk), .aresetn(aresetn),
272 | .in_data({int_rsel_wire[MUX_SIZE-1:2] & ~int_svalid_wire, int_arid_wire, int_rlast_wire, int_rdata_wire[0]}),
273 | .in_valid(int_rvalid_wire), .in_ready(int_rready_wire),
274 | .out_data({int_bsel_wire, s_axi_rid, s_axi_rlast, int_rdata_wire[1]}),
275 | .out_valid(s_axi_rvalid), .out_ready(s_axi_rready)
276 | );
277 |
278 | assign s_axi_rdata = {{s_axi_rdata(hub_size)}};
279 | {% for i in range(hub_size) -%}
280 | {% set index = "%02d" % i %}
281 | assign int_bdata_wire[{{i}}] = b{{index}}_bram_rdata;
282 | assign b{{index}}_bram_clk = aclk;
283 | assign b{{index}}_bram_rst = ~aresetn;
284 | assign b{{index}}_bram_en = int_rsel_wire[{{i+2}}] | int_wsel_wire[{{i+2}}];
285 | assign b{{index}}_bram_we = int_wsel_wire[{{i+2}}] ? int_wstrb_wire : 4'd0;
286 | assign b{{index}}_bram_addr = int_we_wire ? int_waddr_wire : int_raddr_wire;
287 | assign b{{index}}_bram_wdata = int_wdata_wire;
288 |
289 | assign int_sdata_wire[{{i}}] = s{{index}}_axis_tdata;
290 | assign int_svalid_wire[{{i}}] = s{{index}}_axis_tvalid;
291 | assign s{{index}}_axis_tready = int_sready_wire[{{i}}];
292 |
293 | inout_buffer #(
294 | .DATA_WIDTH(32)
295 | ) mbuf_{{i}} (
296 | .aclk(aclk), .aresetn(aresetn),
297 | .in_data(int_mdata_wire[{{i}}]), .in_valid(int_mvalid_wire[{{i}}]), .in_ready(int_mready_wire[{{i}}]),
298 | .out_data(m{{index}}_axis_tdata), .out_valid(m{{index}}_axis_tvalid), .out_ready(m{{index}}_axis_tready)
299 | );
300 | {% endfor %}
301 | endmodule
302 | """
303 |
304 | import jinja2
305 |
306 |
307 | def s_axi_rdata(n):
308 | return " | ".join(map(lambda i: "int_rdata_wire[%d]" % i, range(1, n + 2)))
309 |
310 |
311 | print(jinja2.Template(source).render(hub_size=hub_size, s_axi_rdata=s_axi_rdata))
312 |
--------------------------------------------------------------------------------
/cores/axis_adc_ddr.v:
--------------------------------------------------------------------------------
1 |
2 | `timescale 1 ns / 1 ps
3 |
4 | module axis_adc_ddr #
5 | (
6 | parameter integer ADC_DATA_WIDTH = 7,
7 | parameter integer AXIS_TDATA_WIDTH = 16
8 | )
9 | (
10 | // System signals
11 | input wire aclk,
12 |
13 | // ADC signals
14 | input wire [ADC_DATA_WIDTH-1:0] adc_data,
15 |
16 | // Master side
17 | output wire [AXIS_TDATA_WIDTH-1:0] m_axis_tdata,
18 | output wire m_axis_tvalid
19 | );
20 | localparam PADDING_WIDTH = AXIS_TDATA_WIDTH - ADC_DATA_WIDTH*2;
21 |
22 | wire [ADC_DATA_WIDTH*2-1:0] int_data_wire;
23 |
24 | genvar j;
25 |
26 | generate
27 | for(j = 0; j < ADC_DATA_WIDTH; j = j + 1)
28 | begin : ADC_DATA
29 | IDDR #(
30 | .DDR_CLK_EDGE("SAME_EDGE_PIPELINED")
31 | ) IDDR_inst (
32 | .Q1(int_data_wire[j*2+0]),
33 | .Q2(int_data_wire[j*2+1]),
34 | .D(adc_data[j]),
35 | .C(aclk),
36 | .CE(1'b1),
37 | .R(1'b0),
38 | .S(1'b0)
39 | );
40 | end
41 | endgenerate
42 |
43 | assign m_axis_tvalid = 1'b1;
44 |
45 | assign m_axis_tdata = {{(PADDING_WIDTH+1){int_data_wire[ADC_DATA_WIDTH*2-1]}}, int_data_wire[ADC_DATA_WIDTH*2-2:0]};
46 |
47 | endmodule
48 |
--------------------------------------------------------------------------------
/cores/axis_fifo.v:
--------------------------------------------------------------------------------
1 |
2 | `timescale 1 ns / 1 ps
3 |
4 | module axis_fifo #
5 | (
6 | parameter integer S_AXIS_TDATA_WIDTH = 32,
7 | parameter integer M_AXIS_TDATA_WIDTH = 32,
8 | parameter integer WRITE_DEPTH = 512,
9 | parameter ALWAYS_READY = "FALSE",
10 | parameter ALWAYS_VALID = "FALSE"
11 | )
12 | (
13 | // System signals
14 | input wire aclk,
15 | input wire aresetn,
16 |
17 | // FIFO status
18 | output wire [15:0] write_count,
19 | output wire [15:0] read_count,
20 |
21 | // Slave side
22 | input wire [S_AXIS_TDATA_WIDTH-1:0] s_axis_tdata,
23 | input wire s_axis_tvalid,
24 | output wire s_axis_tready,
25 |
26 | // Master side
27 | output wire [M_AXIS_TDATA_WIDTH-1:0] m_axis_tdata,
28 | output wire m_axis_tvalid,
29 | input wire m_axis_tready
30 | );
31 |
32 | localparam integer WRITE_COUNT_WIDTH = $clog2(WRITE_DEPTH) + 1;
33 | localparam integer READ_COUNT_WIDTH = $clog2(WRITE_DEPTH * S_AXIS_TDATA_WIDTH / M_AXIS_TDATA_WIDTH) + 1;
34 |
35 | wire [M_AXIS_TDATA_WIDTH-1:0] int_data_wire;
36 | wire int_empty_wire, int_full_wire;
37 |
38 | xpm_fifo_sync #(
39 | .WRITE_DATA_WIDTH(S_AXIS_TDATA_WIDTH),
40 | .FIFO_WRITE_DEPTH(WRITE_DEPTH),
41 | .READ_DATA_WIDTH(M_AXIS_TDATA_WIDTH),
42 | .READ_MODE("fwft"),
43 | .FIFO_READ_LATENCY(0),
44 | .FIFO_MEMORY_TYPE("block"),
45 | .USE_ADV_FEATURES("0404"),
46 | .WR_DATA_COUNT_WIDTH(WRITE_COUNT_WIDTH),
47 | .RD_DATA_COUNT_WIDTH(READ_COUNT_WIDTH)
48 | ) fifo_0 (
49 | .empty(int_empty_wire),
50 | .full(int_full_wire),
51 | .wr_data_count(write_count),
52 | .rd_data_count(read_count),
53 | .rst(~aresetn),
54 | .wr_clk(aclk),
55 | .wr_en(s_axis_tvalid),
56 | .din(s_axis_tdata),
57 | .rd_en(m_axis_tready),
58 | .dout(int_data_wire)
59 | );
60 |
61 | generate
62 | if(ALWAYS_READY == "TRUE")
63 | begin : READY_INPUT
64 | assign s_axis_tready = 1'b1;
65 | end
66 | else
67 | begin : BLOCKING_INPUT
68 | assign s_axis_tready = ~int_full_wire;
69 | end
70 | endgenerate
71 |
72 | generate
73 | if(ALWAYS_VALID == "TRUE")
74 | begin : VALID_OUTPUT
75 | assign m_axis_tdata = int_empty_wire ? {(M_AXIS_TDATA_WIDTH){1'b0}} : int_data_wire;
76 | assign m_axis_tvalid = 1'b1;
77 | end
78 | else
79 | begin : BLOCKING_OUTPUT
80 | assign m_axis_tdata = int_data_wire;
81 | assign m_axis_tvalid = ~int_empty_wire;
82 | end
83 | endgenerate
84 |
85 | endmodule
86 |
--------------------------------------------------------------------------------
/cores/axis_maxabs_finder.v:
--------------------------------------------------------------------------------
1 |
2 | `timescale 1 ns / 1 ps
3 |
4 | module axis_maxabs_finder #
5 | (
6 | parameter integer AXIS_TDATA_WIDTH = 16,
7 | parameter integer CNTR_WIDTH = 32
8 | )
9 | (
10 | // System signals
11 | input wire aclk,
12 | input wire aresetn,
13 |
14 | input wire [CNTR_WIDTH-1:0] cfg_data,
15 |
16 | // Slave side
17 | output wire s_axis_tready,
18 | input wire [AXIS_TDATA_WIDTH-1:0] s_axis_tdata,
19 | input wire s_axis_tvalid,
20 |
21 | // Master side
22 | input wire m_axis_tready,
23 | output wire [AXIS_TDATA_WIDTH-1:0] m_axis_tdata,
24 | output wire m_axis_tvalid
25 | );
26 |
27 | reg [AXIS_TDATA_WIDTH-1:0] int_max_reg, int_max_next;
28 | reg [AXIS_TDATA_WIDTH-1:0] int_tdata_reg, int_tdata_next;
29 | reg [CNTR_WIDTH-1:0] int_cntr_reg, int_cntr_next;
30 | reg int_tvalid_reg, int_tvalid_next;
31 |
32 | wire [AXIS_TDATA_WIDTH-1:0] int_abs_wire;
33 | wire int_comp_wire;
34 |
35 | always @(posedge aclk)
36 | begin
37 | if(~aresetn)
38 | begin
39 | int_max_reg <= {(AXIS_TDATA_WIDTH){1'b0}};
40 | int_tdata_reg <= {(AXIS_TDATA_WIDTH){1'b0}};
41 | int_cntr_reg <= {(CNTR_WIDTH){1'b0}};
42 | int_tvalid_reg <= 1'b0;
43 | end
44 | else
45 | begin
46 | int_max_reg <= int_max_next;
47 | int_tdata_reg <= int_tdata_next;
48 | int_cntr_reg <= int_cntr_next;
49 | int_tvalid_reg <= int_tvalid_next;
50 | end
51 | end
52 |
53 | assign int_comp_wire = int_cntr_reg < cfg_data;
54 | assign int_abs_wire = s_axis_tdata[AXIS_TDATA_WIDTH-1] ? ~s_axis_tdata : s_axis_tdata;
55 |
56 | always @*
57 | begin
58 | int_max_next = int_max_reg;
59 | int_tdata_next = int_tdata_reg;
60 | int_cntr_next = int_cntr_reg;
61 | int_tvalid_next = int_tvalid_reg;
62 |
63 | if(s_axis_tvalid & int_comp_wire)
64 | begin
65 | int_max_next = int_abs_wire > int_max_reg ? int_abs_wire : int_max_reg;
66 | int_cntr_next = int_cntr_reg + 1'b1;
67 | end
68 |
69 | if(s_axis_tvalid & ~int_comp_wire)
70 | begin
71 | int_max_next = {(AXIS_TDATA_WIDTH){1'b0}};
72 | int_tdata_next = int_max_reg;
73 | int_cntr_next = {(CNTR_WIDTH){1'b0}};
74 | int_tvalid_next = 1'b1;
75 | end
76 |
77 | if(m_axis_tready & int_tvalid_reg)
78 | begin
79 | int_tvalid_next = 1'b0;
80 | end
81 | end
82 |
83 | assign s_axis_tready = 1'b1;
84 | assign m_axis_tdata = int_tdata_reg;
85 | assign m_axis_tvalid = int_tvalid_reg;
86 |
87 | endmodule
88 |
--------------------------------------------------------------------------------
/cores/axis_pps_counter.v:
--------------------------------------------------------------------------------
1 | `timescale 1 ns / 1 ps
2 |
3 | module axis_pps_counter #
4 | (
5 | parameter integer AXIS_TDATA_WIDTH = 32,
6 | parameter integer CNTR_WIDTH = 32
7 | )
8 | (
9 | // System signals
10 | input wire aclk,
11 | input wire aresetn,
12 |
13 | input wire pps_data,
14 |
15 | // Master side
16 | output wire [AXIS_TDATA_WIDTH-1:0] m_axis_tdata,
17 | output wire m_axis_tvalid
18 | );
19 |
20 | reg [CNTR_WIDTH-1:0] int_cntr_reg;
21 | reg int_enbl_reg;
22 | reg [1:0] int_data_reg;
23 |
24 | wire int_edge_wire, int_pps_wire;
25 |
26 | xpm_cdc_single #(
27 | .DEST_SYNC_FF(4),
28 | .INIT_SYNC_FF(0),
29 | .SRC_INPUT_REG(0),
30 | .SIM_ASSERT_CHK(0)
31 | ) cdc_0 (
32 | .src_in(pps_data),
33 | .src_clk(),
34 | .dest_out(int_pps_wire),
35 | .dest_clk(aclk)
36 | );
37 |
38 | always @(posedge aclk)
39 | begin
40 | if(~aresetn)
41 | begin
42 | int_cntr_reg <= {(CNTR_WIDTH){1'b0}};
43 | int_enbl_reg <= 1'b0;
44 | int_data_reg <= 2'd0;
45 | end
46 | else
47 | begin
48 | int_cntr_reg <= int_edge_wire ? {(CNTR_WIDTH){1'b0}} : int_cntr_reg + 1'b1;
49 | int_enbl_reg <= int_edge_wire ? 1'b1 : int_enbl_reg;
50 | int_data_reg <= {int_data_reg[0], ~int_pps_wire};
51 | end
52 | end
53 |
54 | assign int_edge_wire = int_data_reg[1] & ~int_data_reg[0];
55 |
56 | assign m_axis_tdata = {{(AXIS_TDATA_WIDTH-CNTR_WIDTH){1'b0}}, int_cntr_reg};
57 | assign m_axis_tvalid = int_enbl_reg & int_edge_wire;
58 |
59 | endmodule
60 |
--------------------------------------------------------------------------------
/cores/axis_variable.v:
--------------------------------------------------------------------------------
1 |
2 | `timescale 1 ns / 1 ps
3 |
4 | module axis_variable #
5 | (
6 | parameter integer AXIS_TDATA_WIDTH = 32
7 | )
8 | (
9 | // System signals
10 | input wire aclk,
11 | input wire aresetn,
12 |
13 | input wire [AXIS_TDATA_WIDTH-1:0] cfg_data,
14 |
15 | // Master side
16 | input wire m_axis_tready,
17 | output wire [AXIS_TDATA_WIDTH-1:0] m_axis_tdata,
18 | output wire m_axis_tvalid
19 | );
20 |
21 | reg [AXIS_TDATA_WIDTH-1:0] int_tdata_reg;
22 | reg int_tvalid_reg;
23 |
24 | always @(posedge aclk)
25 | begin
26 | if(~aresetn)
27 | begin
28 | int_tdata_reg <= {(AXIS_TDATA_WIDTH){1'b0}};
29 | int_tvalid_reg <= 1'b0;
30 | end
31 | else
32 | begin
33 | int_tdata_reg <= cfg_data;
34 | int_tvalid_reg <= (int_tdata_reg != cfg_data) | (int_tvalid_reg & ~m_axis_tready);
35 | end
36 | end
37 |
38 | assign m_axis_tdata = int_tdata_reg;
39 | assign m_axis_tvalid = int_tvalid_reg;
40 |
41 | endmodule
42 |
--------------------------------------------------------------------------------
/cores/dds.v:
--------------------------------------------------------------------------------
1 |
2 | `timescale 1 ns / 1 ps
3 |
4 | module dds #
5 | (
6 | parameter NEGATIVE_SINE = "FALSE"
7 | )
8 | (
9 | input wire aclk,
10 | input wire aresetn,
11 |
12 | input wire [31:0] pinc,
13 |
14 | output wire [47:0] dout
15 | );
16 |
17 | reg [31:0] int_cntr_reg;
18 | reg [23:0] int_cos_reg, int_sin_reg;
19 | reg [10:0] int_addr_reg;
20 | reg [1:0] int_sign_reg [2:0];
21 |
22 | wire [47:0] int_p_wire [2:0];
23 | wire [31:0] int_cntr_wire;
24 | wire [29:0] int_cos_wire, int_sin_wire;
25 | wire [22:0] int_lut_wire [1:0];
26 | wire [17:0] int_corr_wire;
27 | wire [2:0] int_pbd_wire;
28 |
29 | assign int_cos_wire = int_sign_reg[2][0] ? {7'h7f, -int_lut_wire[0]} : {7'h00, int_lut_wire[0]};
30 | assign int_sin_wire = int_sign_reg[2][1] ? {7'h7f, -int_lut_wire[1]} : {7'h00, int_lut_wire[1]};
31 |
32 | assign int_corr_wire = {int_p_wire[0][34:18], int_p_wire[0][17] | int_pbd_wire[0]};
33 |
34 | generate
35 | if(NEGATIVE_SINE == "TRUE")
36 | begin : NEGATIVE
37 | assign int_cntr_wire = int_cntr_reg - pinc;
38 | end
39 | else
40 | begin : POSITIVE
41 | assign int_cntr_wire = int_cntr_reg + pinc;
42 | end
43 | endgenerate
44 |
45 | always @(posedge aclk)
46 | begin
47 | if(~aresetn)
48 | begin
49 | int_cntr_reg <= 32'd0;
50 | int_cos_reg <= 24'd0;
51 | int_sin_reg <= 24'd0;
52 | int_addr_reg <= 11'd0;
53 | int_sign_reg[0] <= 2'd0;
54 | int_sign_reg[1] <= 2'd0;
55 | int_sign_reg[2] <= 2'd0;
56 | end
57 | else
58 | begin
59 | int_cntr_reg <= int_cntr_wire;
60 | int_cos_reg <= int_cos_wire[23:0];
61 | int_sin_reg <= int_sin_wire[23:0];
62 | int_addr_reg <= int_cntr_reg[29:19];
63 | int_sign_reg[0] <= {int_cntr_reg[31], int_cntr_reg[30]};
64 | int_sign_reg[1] <= {int_sign_reg[0][1], int_sign_reg[0][1] ^ int_sign_reg[0][0]};
65 | int_sign_reg[2] <= int_sign_reg[1];
66 | end
67 | end
68 |
69 | xpm_memory_dprom #(
70 | .MEMORY_PRIMITIVE("block"),
71 | .MEMORY_SIZE(47104),
72 | .ADDR_WIDTH_A(11),
73 | .ADDR_WIDTH_B(11),
74 | .READ_DATA_WIDTH_A(23),
75 | .READ_DATA_WIDTH_B(23),
76 | .READ_LATENCY_A(2),
77 | .READ_LATENCY_B(2),
78 | .MEMORY_INIT_PARAM(""),
79 | .MEMORY_INIT_FILE("dds.mem")
80 | ) rom_0 (
81 | .clka(aclk),
82 | .clkb(aclk),
83 | .rsta(1'b0),
84 | .rstb(1'b0),
85 | .ena(1'b1),
86 | .enb(1'b1),
87 | .regcea(1'b1),
88 | .regceb(1'b1),
89 | .addra(int_sign_reg[0][0] ? ~int_addr_reg : int_addr_reg),
90 | .addrb(int_sign_reg[0][0] ? int_addr_reg : ~int_addr_reg),
91 | .douta(int_lut_wire[0]),
92 | .doutb(int_lut_wire[1])
93 | );
94 |
95 | DSP48E1 #(
96 | .ALUMODEREG(0), .CARRYINSELREG(0), .INMODEREG(0), .OPMODEREG(0),
97 | .BREG(0), .BCASCREG(0), .CREG(0), .CARRYINREG(0),
98 | .USE_PATTERN_DETECT("PATDET"), .MASK(48'hfffffffe0000)
99 | ) dsp_0 (
100 | .CLK(aclk),
101 | .RSTA(1'b0), .RSTM(1'b0), .RSTP(1'b0),
102 | .CEA2(1'b1), .CED(1'b0), .CEAD(1'b0), .CEM(1'b1), .CEP(1'b1),
103 | .ALUMODE(4'b0000), .CARRYINSEL(3'b000), .INMODE(5'b00000), .OPMODE(7'b0110101),
104 | .A({{(12){~int_cntr_reg[18]}}, int_cntr_reg[17:0]}),
105 | .B(18'd3217),
106 | .C(48'hffff),
107 | .CARRYIN(1'b0),
108 | .PATTERNBDETECT(int_pbd_wire[0]),
109 | .P(int_p_wire[0])
110 | );
111 |
112 | DSP48E1 #(
113 | .ALUMODEREG(0), .CARRYINSELREG(0), .INMODEREG(0), .OPMODEREG(0),
114 | .CARRYINREG(0),
115 | .USE_PATTERN_DETECT("PATDET"), .MASK(48'hffffff000000)
116 | ) dsp_1 (
117 | .CLK(aclk),
118 | .RSTA(1'b0), .RSTB(1'b0), .RSTC(1'b0), .RSTM(1'b0), .RSTP(1'b0),
119 | .CEA2(1'b1), .CEB2(1'b1), .CEC(1'b1), .CED(1'b0), .CEAD(1'b0), .CEM(1'b1), .CEP(1'b1),
120 | .ALUMODE(4'b0011), .CARRYINSEL(3'b000), .INMODE(5'b00000), .OPMODE(7'b0110101),
121 | .A(int_sin_wire),
122 | .B(int_corr_wire),
123 | .C({int_cos_reg, 24'h7fffff}),
124 | .CARRYIN(1'b0),
125 | .PATTERNBDETECT(int_pbd_wire[1]),
126 | .P(int_p_wire[1])
127 | );
128 |
129 | DSP48E1 #(
130 | .ALUMODEREG(0), .CARRYINSELREG(0), .INMODEREG(0), .OPMODEREG(0),
131 | .CARRYINREG(0),
132 | .USE_PATTERN_DETECT("PATDET"), .MASK(48'hffffff000000)
133 | ) dsp_2 (
134 | .CLK(aclk),
135 | .RSTA(1'b0), .RSTB(1'b0), .RSTC(1'b0), .RSTM(1'b0), .RSTP(1'b0),
136 | .CEA2(1'b1), .CEB2(1'b1), .CEC(1'b1), .CED(1'b0), .CEAD(1'b0), .CEM(1'b1), .CEP(1'b1),
137 | .ALUMODE(4'b0000), .CARRYINSEL(3'b000), .INMODE(5'b00000), .OPMODE(7'b0110101),
138 | .A(int_cos_wire),
139 | .B(int_corr_wire),
140 | .C({int_sin_reg, 24'h7fffff}),
141 | .CARRYIN(1'b0),
142 | .PATTERNBDETECT(int_pbd_wire[2]),
143 | .P(int_p_wire[2])
144 | );
145 |
146 | assign dout = {int_p_wire[2][47:25], int_p_wire[2][24] | int_pbd_wire[2], int_p_wire[1][47:25], int_p_wire[1][24] | int_pbd_wire[1]};
147 |
148 | endmodule
149 |
--------------------------------------------------------------------------------
/cores/dsp48.v:
--------------------------------------------------------------------------------
1 |
2 | `timescale 1 ns / 1 ps
3 |
4 | module dsp48 #
5 | (
6 | parameter integer A_WIDTH = 24,
7 | parameter integer B_WIDTH = 16,
8 | parameter integer P_WIDTH = 24
9 | )
10 | (
11 | input wire CLK,
12 |
13 | input wire [A_WIDTH-1:0] A,
14 | input wire [B_WIDTH-1:0] B,
15 |
16 | output wire [P_WIDTH-1:0] P
17 | );
18 |
19 | localparam integer SHIFT = A_WIDTH + B_WIDTH - P_WIDTH - 1;
20 | localparam integer ONES = SHIFT - 1;
21 |
22 | wire [47:0] int_p_wire;
23 | wire int_pbd_wire;
24 |
25 | DSP48E1 #(
26 | .ALUMODEREG(0), .CARRYINSELREG(0), .INMODEREG(0), .OPMODEREG(0),
27 | .CREG(0), .CARRYINREG(0), .MREG(1), .PREG(1),
28 | .USE_PATTERN_DETECT("PATDET"), .SEL_MASK("ROUNDING_MODE1")
29 | ) dsp_0 (
30 | .CLK(CLK),
31 | .RSTA(1'b0), .RSTB(1'b0), .RSTM(1'b0), .RSTP(1'b0),
32 | .CEA2(1'b1), .CEB2(1'b1), .CED(1'b0), .CEAD(1'b0), .CEM(1'b1), .CEP(1'b1),
33 | .ALUMODE(4'b0000), .CARRYINSEL(3'b000), .INMODE(5'b00000), .OPMODE(7'b0110101),
34 | .A({{(30-A_WIDTH){A[A_WIDTH-1]}}, A}),
35 | .B({{(18-B_WIDTH){B[B_WIDTH-1]}}, B}),
36 | .C({{(48-ONES){1'b0}}, {(ONES){1'b1}}}),
37 | .CARRYIN(1'b0),
38 | .PATTERNBDETECT(int_pbd_wire),
39 | .P(int_p_wire)
40 | );
41 |
42 | assign P = {int_p_wire[SHIFT+P_WIDTH-1:SHIFT+1], int_p_wire[SHIFT] | int_pbd_wire};
43 |
44 | endmodule
45 |
--------------------------------------------------------------------------------
/cores/port_slicer.v:
--------------------------------------------------------------------------------
1 |
2 | `timescale 1 ns / 1 ps
3 |
4 | module port_slicer #
5 | (
6 | parameter integer DIN_WIDTH = 32,
7 | parameter integer DIN_FROM = 31,
8 | parameter integer DIN_TO = 0
9 | )
10 | (
11 | input wire [DIN_WIDTH-1:0] din,
12 | output wire [DIN_FROM-DIN_TO:0] dout
13 | );
14 |
15 | assign dout = din[DIN_FROM:DIN_TO];
16 |
17 | endmodule
18 |
--------------------------------------------------------------------------------
/dts/common.dts:
--------------------------------------------------------------------------------
1 | / {
2 | usb_phy0: phy0 {
3 | #phy-cells = <0>;
4 | compatible = "ulpi-phy";
5 | reg = <0xe0002000 0x1000>;
6 | view-port = <0x0170>;
7 | drv-vbus;
8 | };
9 | pps {
10 | compatible = "pps-gpio";
11 | gpios = <&gpio0 54 0>;
12 | capture-clear;
13 | };
14 | };
15 |
16 | &gem0 {
17 | phy-handle = <ðernet_phy>;
18 | ethernet_phy: ethernet-phy@1 {
19 | reg = <1>;
20 | };
21 | };
22 |
23 | &usb0 {
24 | dr_mode = "host";
25 | usb-phy = <&usb_phy0>;
26 | xlnx,phy-reset-gpio = <&gpio0 46 0>;
27 | };
28 |
29 | &spi0 {
30 | spidev@0 {
31 | compatible = "ltc2488";
32 | reg = <0x0>;
33 | spi-max-frequency = <10000000>;
34 | };
35 | spidev@1 {
36 | compatible = "ltc2488";
37 | reg = <0x1>;
38 | spi-max-frequency = <10000000>;
39 | };
40 | spidev@2 {
41 | compatible = "ltc2488";
42 | reg = <0x2>;
43 | spi-max-frequency = <10000000>;
44 | };
45 | };
46 |
--------------------------------------------------------------------------------
/dts/initrd.dts:
--------------------------------------------------------------------------------
1 | /dts-v1/;
2 |
3 | /include/ "system-top.dts"
4 | /include/ "common.dts"
5 |
6 | / {
7 | chosen {
8 | bootargs = "console=ttyPS0,115200 earlycon earlyprintk initrd=0x3000000,4M modloop=modloop cma=36M";
9 | };
10 | };
11 |
--------------------------------------------------------------------------------
/helpers/build-all.sh:
--------------------------------------------------------------------------------
1 | source /opt/Xilinx/Vitis/2023.1/settings64.sh
2 |
3 | JOBS=`nproc 2> /dev/null || echo 1`
4 |
5 | make -j $JOBS cores
6 |
7 | make NAME=led_blinker_77_76 all
8 |
9 | PRJS="sdr_receiver_77_76 sdr_receiver_ft8_77_76 sdr_receiver_hpsdr_77_76 sdr_receiver_wspr_77_76"
10 |
11 | printf "%s\n" $PRJS | xargs -n 1 -P $JOBS -I {} make NAME={} bit
12 |
13 | sudo sh scripts/alpine.sh
14 |
--------------------------------------------------------------------------------
/helpers/build-cores.tcl:
--------------------------------------------------------------------------------
1 | set files [glob -nocomplain cores/*.v]
2 |
3 | set part_name xc7z020clg484-1
4 |
5 | foreach file_name $files {
6 | set core_name [file rootname [file tail $file_name]]
7 | set argv [list $core_name $part_name]
8 | source scripts/core.tcl
9 | }
10 |
--------------------------------------------------------------------------------
/helpers/dds-mem.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | a = 2**23 - 2
4 |
5 | x = (np.arange(2048) + 0.5) / 4096
6 | lut = np.round(a * np.cos(np.pi * x)).astype(np.uint32)
7 |
8 | print("\n".join([format(v, "06x") for v in lut]))
9 |
--------------------------------------------------------------------------------
/mac.txt:
--------------------------------------------------------------------------------
1 | 52:54:C0:A8:01:64
2 |
--------------------------------------------------------------------------------
/modules/inout_buffer.v:
--------------------------------------------------------------------------------
1 |
2 | `timescale 1 ns / 1 ps
3 |
4 | module inout_buffer #
5 | (
6 | parameter integer DATA_WIDTH = 32
7 | )
8 | (
9 | input wire aclk,
10 | input wire aresetn,
11 |
12 | input wire [DATA_WIDTH-1:0] in_data,
13 | input wire in_valid,
14 | output wire in_ready,
15 |
16 | output wire [DATA_WIDTH-1:0] out_data,
17 | output wire out_valid,
18 | input wire out_ready
19 | );
20 |
21 | wire [DATA_WIDTH-1:0] int_data_wire;
22 | wire int_valid_wire, int_ready_wire;
23 |
24 | input_buffer #(
25 | .DATA_WIDTH(DATA_WIDTH)
26 | ) buf_0 (
27 | .aclk(aclk), .aresetn(aresetn),
28 | .in_data(in_data), .in_valid(in_valid), .in_ready(in_ready),
29 | .out_data(int_data_wire), .out_valid(int_valid_wire), .out_ready(int_ready_wire)
30 | );
31 |
32 | output_buffer #(
33 | .DATA_WIDTH(DATA_WIDTH)
34 | ) buf_1 (
35 | .aclk(aclk), .aresetn(aresetn),
36 | .in_data(int_data_wire), .in_valid(int_valid_wire), .in_ready(int_ready_wire),
37 | .out_data(out_data), .out_valid(out_valid), .out_ready(out_ready)
38 | );
39 |
40 | endmodule
41 |
--------------------------------------------------------------------------------
/modules/input_buffer.v:
--------------------------------------------------------------------------------
1 |
2 | `timescale 1 ns / 1 ps
3 |
4 | module input_buffer #
5 | (
6 | parameter integer DATA_WIDTH = 32
7 | )
8 | (
9 | input wire aclk,
10 | input wire aresetn,
11 |
12 | input wire [DATA_WIDTH-1:0] in_data,
13 | input wire in_valid,
14 | output wire in_ready,
15 |
16 | output wire [DATA_WIDTH-1:0] out_data,
17 | output wire out_valid,
18 | input wire out_ready
19 | );
20 |
21 | reg [DATA_WIDTH-1:0] int_data_reg;
22 | reg int_ready_reg = 1'b1;
23 |
24 | wire int_valid_wire = ~int_ready_reg | in_valid;
25 |
26 | always @(posedge aclk)
27 | begin
28 | if(~aresetn)
29 | begin
30 | int_ready_reg <= 1'b1;
31 | end
32 | else if(int_valid_wire)
33 | begin
34 | int_ready_reg <= out_ready;
35 | end
36 |
37 | if(int_ready_reg)
38 | begin
39 | int_data_reg <= in_data;
40 | end
41 | end
42 |
43 | assign in_ready = int_ready_reg;
44 |
45 | assign out_data = int_ready_reg ? in_data : int_data_reg;
46 | assign out_valid = int_valid_wire;
47 |
48 | endmodule
49 |
--------------------------------------------------------------------------------
/modules/output_buffer.v:
--------------------------------------------------------------------------------
1 |
2 | `timescale 1 ns / 1 ps
3 |
4 | module output_buffer #
5 | (
6 | parameter integer DATA_WIDTH = 32
7 | )
8 | (
9 | input wire aclk,
10 | input wire aresetn,
11 |
12 | input wire [DATA_WIDTH-1:0] in_data,
13 | input wire in_valid,
14 | output wire in_ready,
15 |
16 | output wire [DATA_WIDTH-1:0] out_data,
17 | output wire out_valid,
18 | input wire out_ready
19 | );
20 |
21 | reg [DATA_WIDTH-1:0] int_data_reg;
22 | reg int_valid_reg = 1'b0;
23 |
24 | wire int_ready_wire = ~int_valid_reg | out_ready;
25 |
26 | always @(posedge aclk)
27 | begin
28 | if(~aresetn)
29 | begin
30 | int_valid_reg <= 1'b0;
31 | end
32 | else if(int_ready_wire)
33 | begin
34 | int_valid_reg <= in_valid;
35 | end
36 |
37 | if(int_ready_wire)
38 | begin
39 | int_data_reg <= in_data;
40 | end
41 | end
42 |
43 | assign in_ready = int_ready_wire;
44 |
45 | assign out_data = int_data_reg;
46 | assign out_valid = int_valid_reg;
47 |
48 | endmodule
49 |
--------------------------------------------------------------------------------
/patches/cma.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #define CMA_ALLOC _IOWR('Z', 0, u32)
8 |
9 | static struct device *dma_device = NULL;
10 | static size_t dma_size = 0;
11 | static void *cpu_addr = NULL;
12 | static dma_addr_t dma_addr;
13 |
14 | static void cma_free(void)
15 | {
16 | if(!cpu_addr) return;
17 | dma_free_coherent(dma_device, dma_size, cpu_addr, dma_addr);
18 | cpu_addr = NULL;
19 | }
20 |
21 | static long cma_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
22 | {
23 | long rc;
24 | u32 buffer;
25 |
26 | if(cmd != CMA_ALLOC) return -ENOTTY;
27 |
28 | rc = copy_from_user(&buffer, (void __user *)arg, sizeof(buffer));
29 | if(rc) return rc;
30 |
31 | cma_free();
32 |
33 | dma_size = buffer;
34 | cpu_addr = dma_alloc_coherent(dma_device, dma_size, &dma_addr, GFP_KERNEL);
35 |
36 | if(IS_ERR_OR_NULL(cpu_addr))
37 | {
38 | rc = PTR_ERR(cpu_addr);
39 | if(rc == 0) rc = -ENOMEM;
40 | cpu_addr = NULL;
41 | return rc;
42 | }
43 |
44 | buffer = dma_addr;
45 | return copy_to_user((void __user *)arg, &buffer, sizeof(buffer));
46 | }
47 |
48 | static int cma_mmap(struct file *file, struct vm_area_struct *vma)
49 | {
50 | return dma_mmap_coherent(dma_device, vma, cpu_addr, dma_addr, dma_size);
51 | }
52 |
53 | static int cma_release(struct inode *inode, struct file *file)
54 | {
55 | cma_free();
56 | return 0;
57 | }
58 |
59 | static struct file_operations cma_fops =
60 | {
61 | .unlocked_ioctl = cma_ioctl,
62 | .mmap = cma_mmap,
63 | .release = cma_release
64 | };
65 |
66 | struct miscdevice cma_device =
67 | {
68 | .minor = MISC_DYNAMIC_MINOR,
69 | .name = "cma",
70 | .fops = &cma_fops
71 | };
72 |
73 | static int __init cma_init(void)
74 | {
75 | int rc;
76 |
77 | rc = misc_register(&cma_device);
78 | if(rc) return rc;
79 |
80 | dma_device = cma_device.this_device;
81 |
82 | dma_device->dma_coherent = true;
83 | dma_device->coherent_dma_mask = DMA_BIT_MASK(32);
84 |
85 | return 0;
86 | }
87 |
88 | static void __exit cma_exit(void)
89 | {
90 | cma_free();
91 | misc_deregister(&cma_device);
92 | }
93 |
94 | module_init(cma_init);
95 | module_exit(cma_exit);
96 | MODULE_LICENSE("MIT");
97 |
--------------------------------------------------------------------------------
/patches/fsbl.patch:
--------------------------------------------------------------------------------
1 | --- fsbl_hooks.c.old
2 | +++ fsbl_hooks.c
3 | @@ -34,6 +34,7 @@
4 |
5 | /************************** Function Prototypes ******************************/
6 |
7 | +u32 SetMacAddress();
8 |
9 | /******************************************************************************
10 | * This function is the hook which will be called before the bitstream download.
11 | @@ -112,6 +113,7 @@ u32 FsblHookBeforeHandoff(void)
12 | * Errors to be stored in the status variable and returned
13 | */
14 | fsbl_printf(DEBUG_INFO,"In FsblHookBeforeHandoff function \r\n");
15 | + Status = SetMacAddress();
16 |
17 | return (Status);
18 | }
19 |
--------------------------------------------------------------------------------
/patches/initramfs.patch:
--------------------------------------------------------------------------------
1 | --- init.old
2 | +++ init
3 | @@ -715,10 +715,9 @@ fi
4 |
5 | # locate boot media and mount it
6 | ebegin "Mounting boot media"
7 | -$MOCK nlplug-findfs $cryptopts -p /sbin/mdev ${KOPT_debug_init:+-d} \
8 | - ${KOPT_usbdelay:+-t $(( $KOPT_usbdelay * 1000 ))} \
9 | - ${KOPT_uevent_buf_size:+-U $KOPT_uevent_buf_size} \
10 | - $repoopts -a "$ROOT"/tmp/apkovls
11 | +mkdir -p /media/mmcblk0p1
12 | +mount -o ro /dev/mmcblk0p1 /media/mmcblk0p1
13 | +ls /media/mmcblk0p1/*.apkovl.tar.gz > /tmp/apkovls
14 | eend $?
15 |
16 | # Setup network interfaces
17 |
--------------------------------------------------------------------------------
/patches/linux-6.6.patch:
--------------------------------------------------------------------------------
1 | diff -rupN old/linux-6.6/drivers/char/Kconfig linux-6.6/drivers/char/Kconfig
2 | --- old/linux-6.6/drivers/char/Kconfig
3 | +++ linux-6.6/drivers/char/Kconfig
4 | @@ -422,4 +422,12 @@ config ADI
5 | and SSM (Silicon Secured Memory). Intended consumers of this
6 | driver include crash and makedumpfile.
7 |
8 | +config DEVCMA
9 | + bool "/dev/cma virtual device support"
10 | + default y
11 | +
12 | +config XILINX_DEVCFG
13 | + tristate "Xilinx Device Configuration"
14 | + depends on ARCH_ZYNQ
15 | +
16 | endmenu
17 | diff -rupN old/linux-6.6/drivers/char/Makefile linux-6.6/drivers/char/Makefile
18 | --- old/linux-6.6/drivers/char/Makefile
19 | +++ linux-6.6/drivers/char/Makefile
20 | @@ -44,3 +44,5 @@ obj-$(CONFIG_PS3_FLASH) += ps3flash.o
21 | obj-$(CONFIG_XILLYBUS_CLASS) += xillybus/
22 | obj-$(CONFIG_POWERNV_OP_PANEL) += powernv-op-panel.o
23 | obj-$(CONFIG_ADI) += adi.o
24 | +obj-$(CONFIG_DEVCMA) += cma.o
25 | +obj-$(CONFIG_XILINX_DEVCFG) += xilinx_devcfg.o
26 | diff -rupN old/linux-6.6/drivers/net/wireless/realtek/Kconfig linux-6.6/drivers/net/wireless/realtek/Kconfig
27 | --- old/linux-6.6/drivers/net/wireless/realtek/Kconfig
28 | +++ linux-6.6/drivers/net/wireless/realtek/Kconfig
29 | @@ -13,9 +13,9 @@ config WLAN_VENDOR_REALTEK
30 | if WLAN_VENDOR_REALTEK
31 |
32 | source "drivers/net/wireless/realtek/rtl818x/Kconfig"
33 | -source "drivers/net/wireless/realtek/rtlwifi/Kconfig"
34 | source "drivers/net/wireless/realtek/rtl8xxxu/Kconfig"
35 | source "drivers/net/wireless/realtek/rtw88/Kconfig"
36 | source "drivers/net/wireless/realtek/rtw89/Kconfig"
37 | +source "drivers/net/wireless/realtek/rtl8188eu/Kconfig"
38 |
39 | endif # WLAN_VENDOR_REALTEK
40 | diff -rupN old/linux-6.6/drivers/net/wireless/realtek/Makefile linux-6.6/drivers/net/wireless/realtek/Makefile
41 | --- old/linux-6.6/drivers/net/wireless/realtek/Makefile
42 | +++ linux-6.6/drivers/net/wireless/realtek/Makefile
43 | @@ -5,8 +5,8 @@
44 |
45 | obj-$(CONFIG_RTL8180) += rtl818x/
46 | obj-$(CONFIG_RTL8187) += rtl818x/
47 | -obj-$(CONFIG_RTLWIFI) += rtlwifi/
48 | obj-$(CONFIG_RTL8XXXU) += rtl8xxxu/
49 | obj-$(CONFIG_RTW88) += rtw88/
50 | obj-$(CONFIG_RTW89) += rtw89/
51 | +obj-$(CONFIG_RTL8188EU) += rtl8188eu/
52 |
53 | diff -rupN old/linux-6.6/drivers/pps/clients/pps-gpio.c linux-6.6/drivers/pps/clients/pps-gpio.c
54 | --- old/linux-6.6/drivers/pps/clients/pps-gpio.c
55 | +++ linux-6.6/drivers/pps/clients/pps-gpio.c
56 | @@ -113,6 +113,9 @@ static int pps_gpio_setup(struct device
57 | data->assert_falling_edge =
58 | device_property_read_bool(dev, "assert-falling-edge");
59 |
60 | + data->capture_clear =
61 | + device_property_read_bool(dev, "capture-clear");
62 | +
63 | data->echo_pin = devm_gpiod_get_optional(dev, "echo", GPIOD_OUT_LOW);
64 | if (IS_ERR(data->echo_pin))
65 | return dev_err_probe(dev, PTR_ERR(data->echo_pin),
66 | diff -rupN old/linux-6.6/drivers/usb/chipidea/ci_hdrc_usb2.c linux-6.6/drivers/usb/chipidea/ci_hdrc_usb2.c
67 | --- old/linux-6.6/drivers/usb/chipidea/ci_hdrc_usb2.c
68 | +++ linux-6.6/drivers/usb/chipidea/ci_hdrc_usb2.c
69 | @@ -65,6 +65,14 @@ static int ci_hdrc_usb2_probe(struct pla
70 | if (match && match->data) {
71 | /* struct copy */
72 | *ci_pdata = *(struct ci_hdrc_platform_data *)match->data;
73 | + if (of_device_is_compatible(pdev->dev.of_node,
74 | + "xlnx,zynq-usb-2.20a")) {
75 | + ci_pdata->usb_phy = devm_usb_get_phy_by_phandle(dev,
76 | + "usb-phy",
77 | + 0);
78 | + if (IS_ERR(ci_pdata->usb_phy))
79 | + return PTR_ERR(ci_pdata->usb_phy);
80 | + }
81 | }
82 |
83 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
84 | diff -rupN old/linux-6.6/drivers/usb/chipidea/udc.c linux-6.6/drivers/usb/chipidea/udc.c
85 | --- old/linux-6.6/drivers/usb/chipidea/udc.c
86 | +++ linux-6.6/drivers/usb/chipidea/udc.c
87 | @@ -688,7 +688,8 @@ static int _hardware_dequeue(struct ci_h
88 | if ((TD_STATUS_ACTIVE & tmptoken) != 0) {
89 | int n = hw_ep_bit(hwep->num, hwep->dir);
90 |
91 | - if (ci->rev == CI_REVISION_24)
92 | + if (ci->rev == CI_REVISION_24 ||
93 | + ci->rev == CI_REVISION_22)
94 | if (!hw_read(ci, OP_ENDPTSTAT, BIT(n)))
95 | reprime_dtd(ci, hwep, node);
96 | hwreq->req.status = -EALREADY;
97 | diff -rupN old/linux-6.6/drivers/usb/phy/Kconfig linux-6.6/drivers/usb/phy/Kconfig
98 | --- old/linux-6.6/drivers/usb/phy/Kconfig
99 | +++ linux-6.6/drivers/usb/phy/Kconfig
100 | @@ -160,7 +160,7 @@ config USB_TEGRA_PHY
101 |
102 | config USB_ULPI
103 | bool "Generic ULPI Transceiver Driver"
104 | - depends on ARM || ARM64 || COMPILE_TEST
105 | + depends on ARM || ARM64 || COMPILE_TEST || USB_PHY
106 | select USB_ULPI_VIEWPORT
107 | help
108 | Enable this to support ULPI connected USB OTG transceivers which
109 | diff -rupN old/linux-6.6/drivers/usb/phy/phy-ulpi.c linux-6.6/drivers/usb/phy/phy-ulpi.c
110 | --- old/linux-6.6/drivers/usb/phy/phy-ulpi.c
111 | +++ linux-6.6/drivers/usb/phy/phy-ulpi.c
112 | @@ -13,9 +13,16 @@
113 | #include
114 | #include
115 | #include
116 | +#include
117 | +#include
118 | +#include
119 | +#include
120 | +#include
121 | +#include
122 | #include
123 | #include
124 | #include
125 | +#include
126 |
127 |
128 | struct ulpi_info {
129 | @@ -39,6 +46,13 @@ static struct ulpi_info ulpi_ids[] = {
130 | ULPI_INFO(ULPI_ID(0x0451, 0x1507), "TI TUSB1210"),
131 | };
132 |
133 | +struct ulpi_phy {
134 | + struct usb_phy *usb_phy;
135 | + void __iomem *regs;
136 | + unsigned int vp_offset;
137 | + unsigned int flags;
138 | +};
139 | +
140 | static int ulpi_set_otg_flags(struct usb_phy *phy)
141 | {
142 | unsigned int flags = ULPI_OTG_CTRL_DP_PULLDOWN |
143 | @@ -240,6 +254,23 @@ static int ulpi_set_vbus(struct usb_otg
144 | return usb_phy_io_write(phy, flags, ULPI_OTG_CTRL);
145 | }
146 |
147 | +static int usbphy_set_vbus(struct usb_phy *phy, int on)
148 | +{
149 | + unsigned int flags = usb_phy_io_read(phy, ULPI_OTG_CTRL);
150 | +
151 | + flags &= ~(ULPI_OTG_CTRL_DRVVBUS | ULPI_OTG_CTRL_DRVVBUS_EXT);
152 | +
153 | + if (on) {
154 | + if (phy->flags & ULPI_OTG_DRVVBUS)
155 | + flags |= ULPI_OTG_CTRL_DRVVBUS;
156 | +
157 | + if (phy->flags & ULPI_OTG_DRVVBUS_EXT)
158 | + flags |= ULPI_OTG_CTRL_DRVVBUS_EXT;
159 | + }
160 | +
161 | + return usb_phy_io_write(phy, flags, ULPI_OTG_CTRL);
162 | +}
163 | +
164 | static void otg_ulpi_init(struct usb_phy *phy, struct usb_otg *otg,
165 | struct usb_phy_io_ops *ops,
166 | unsigned int flags)
167 | @@ -249,6 +280,7 @@ static void otg_ulpi_init(struct usb_phy
168 | phy->io_ops = ops;
169 | phy->otg = otg;
170 | phy->init = ulpi_init;
171 | + phy->set_vbus = usbphy_set_vbus;
172 |
173 | otg->usb_phy = phy;
174 | otg->set_host = ulpi_set_host;
175 | @@ -301,3 +333,69 @@ devm_otg_ulpi_create(struct device *dev,
176 | return phy;
177 | }
178 | EXPORT_SYMBOL_GPL(devm_otg_ulpi_create);
179 | +
180 | +static int ulpi_phy_probe(struct platform_device *pdev)
181 | +{
182 | + struct device_node *np = pdev->dev.of_node;
183 | + struct resource *res;
184 | + struct ulpi_phy *uphy;
185 | + int ret;
186 | +
187 | + uphy = devm_kzalloc(&pdev->dev, sizeof(*uphy), GFP_KERNEL);
188 | + if (!uphy)
189 | + return -ENOMEM;
190 | +
191 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
192 | + if (!res) {
193 | + dev_err(&pdev->dev, "no phy I/O memory resource defined\n");
194 | + return -ENODEV;
195 | + }
196 | +
197 | + uphy->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
198 | + if (IS_ERR(uphy->regs))
199 | + return PTR_ERR(uphy->regs);
200 | +
201 | + if (of_property_read_bool(np, "external-drv-vbus") ||
202 | + of_property_read_bool(np, "drv-vbus"))
203 | + uphy->flags |= ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT;
204 | +
205 | + ret = of_property_read_u32(np, "view-port", &uphy->vp_offset);
206 | + if (ret)
207 | + return ret;
208 | +
209 | + uphy->usb_phy = otg_ulpi_create(&ulpi_viewport_access_ops, uphy->flags);
210 | + if (!uphy->usb_phy) {
211 | + dev_err(&pdev->dev, "Failed to create ULPI OTG\n");
212 | + return -ENOMEM;
213 | + }
214 | +
215 | + uphy->usb_phy->dev = &pdev->dev;
216 | + uphy->usb_phy->io_priv = uphy->regs + uphy->vp_offset;
217 | + return usb_add_phy_dev(uphy->usb_phy);
218 | +}
219 | +
220 | +static void ulpi_phy_remove(struct platform_device *pdev)
221 | +{
222 | + struct ulpi_phy *uphy = platform_get_drvdata(pdev);
223 | +
224 | + usb_remove_phy(uphy->usb_phy);
225 | +}
226 | +
227 | +static const struct of_device_id ulpi_phy_table[] = {
228 | + { .compatible = "ulpi-phy" },
229 | + { },
230 | +};
231 | +MODULE_DEVICE_TABLE(of, ulpi_phy_table);
232 | +
233 | +static struct platform_driver ulpi_phy_driver = {
234 | + .probe = ulpi_phy_probe,
235 | + .remove_new = ulpi_phy_remove,
236 | + .driver = {
237 | + .name = "ulpi-phy",
238 | + .of_match_table = ulpi_phy_table,
239 | + },
240 | +};
241 | +module_platform_driver(ulpi_phy_driver);
242 | +
243 | +MODULE_DESCRIPTION("ULPI PHY driver");
244 | +MODULE_LICENSE("GPL");
245 |
--------------------------------------------------------------------------------
/patches/qmtech_xc7z020_fsbl_hooks.c:
--------------------------------------------------------------------------------
1 | #include "xemacps.h"
2 |
3 | u32 SetMacAddress()
4 | {
5 | XEmacPs Emac;
6 | XEmacPs_Config *EmacConfig;
7 | u32 Status;
8 | u8 Buffer[6] = {0x52, 0x54, 0xC0, 0xA8, 0x01, 0x64};
9 |
10 | EmacConfig = XEmacPs_LookupConfig(XPAR_PS7_ETHERNET_0_DEVICE_ID);
11 | if(EmacConfig == NULL) return XST_FAILURE;
12 |
13 | Status = XEmacPs_CfgInitialize(&Emac, EmacConfig, EmacConfig->BaseAddress);
14 | if(Status != XST_SUCCESS) return XST_FAILURE;
15 |
16 | Status = XEmacPs_SetMacAddress(&Emac, Buffer, 1);
17 | if(Status != XST_SUCCESS) return XST_FAILURE;
18 |
19 | return Status;
20 | }
21 |
--------------------------------------------------------------------------------
/patches/xilinx_zynq_defconfig:
--------------------------------------------------------------------------------
1 | CONFIG_LOCALVERSION="-xilinx"
2 | CONFIG_SYSVIPC=y
3 | CONFIG_NO_HZ=y
4 | CONFIG_HIGH_RES_TIMERS=y
5 | CONFIG_PREEMPT=y
6 | CONFIG_IKCONFIG=y
7 | CONFIG_IKCONFIG_PROC=y
8 | CONFIG_LOG_BUF_SHIFT=14
9 | CONFIG_CGROUPS=y
10 | CONFIG_BLK_DEV_INITRD=y
11 | CONFIG_BPF_SYSCALL=y
12 | CONFIG_EXPERT=y
13 | # CONFIG_BUG is not set
14 | CONFIG_PERF_EVENTS=y
15 | CONFIG_ARCH_VEXPRESS=y
16 | CONFIG_ARCH_ZYNQ=y
17 | CONFIG_PL310_ERRATA_588369=y
18 | CONFIG_PL310_ERRATA_727915=y
19 | CONFIG_PL310_ERRATA_769419=y
20 | CONFIG_ARM_ERRATA_754322=y
21 | CONFIG_ARM_ERRATA_754327=y
22 | CONFIG_ARM_ERRATA_764369=y
23 | CONFIG_ARM_ERRATA_775420=y
24 | CONFIG_SMP=y
25 | CONFIG_SCHED_MC=y
26 | CONFIG_SCHED_SMT=y
27 | CONFIG_BIG_LITTLE=y
28 | CONFIG_BL_SWITCHER=y
29 | CONFIG_HIGHMEM=y
30 | CONFIG_CPU_FREQ=y
31 | CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
32 | CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
33 | CONFIG_CPU_FREQ_GOV_POWERSAVE=y
34 | CONFIG_CPU_FREQ_GOV_ONDEMAND=y
35 | CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
36 | CONFIG_CPU_IDLE=y
37 | CONFIG_ARM_ZYNQ_CPUIDLE=y
38 | CONFIG_VFP=y
39 | CONFIG_NEON=y
40 | CONFIG_MODULES=y
41 | CONFIG_MODULE_UNLOAD=y
42 | CONFIG_MODULE_FORCE_UNLOAD=y
43 | CONFIG_MODVERSIONS=y
44 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
45 | # CONFIG_COMPACTION is not set
46 | CONFIG_CMA=y
47 | CONFIG_NET=y
48 | CONFIG_PACKET=y
49 | CONFIG_UNIX=y
50 | CONFIG_INET=y
51 | CONFIG_IP_MULTICAST=y
52 | CONFIG_IP_PNP=y
53 | CONFIG_IP_PNP_DHCP=y
54 | CONFIG_IP_PNP_BOOTP=y
55 | CONFIG_IP_PNP_RARP=y
56 | CONFIG_NET_IPIP=m
57 | CONFIG_SYN_COOKIES=y
58 | CONFIG_BRIDGE=m
59 | CONFIG_VLAN_8021Q=m
60 | CONFIG_CAN=y
61 | CONFIG_PCI=y
62 | CONFIG_PCI_MSI=y
63 | CONFIG_PCIE_XILINX=y
64 | CONFIG_UEVENT_HELPER=y
65 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
66 | CONFIG_DEVTMPFS=y
67 | CONFIG_DEVTMPFS_MOUNT=y
68 | CONFIG_CONNECTOR=y
69 | CONFIG_MTD=y
70 | CONFIG_MTD_CMDLINE_PARTS=y
71 | CONFIG_MTD_BLOCK=y
72 | CONFIG_MTD_CFI=y
73 | CONFIG_MTD_CFI_AMDSTD=y
74 | CONFIG_MTD_PHYSMAP=y
75 | CONFIG_MTD_PHYSMAP_OF=y
76 | CONFIG_MTD_RAW_NAND=y
77 | CONFIG_MTD_NAND_PL35X=y
78 | CONFIG_MTD_SPI_NOR=y
79 | CONFIG_OF_OVERLAY=y
80 | CONFIG_BLK_DEV_LOOP=y
81 | CONFIG_BLK_DEV_RAM=y
82 | CONFIG_BLK_DEV_RAM_SIZE=16384
83 | CONFIG_EEPROM_AT24=y
84 | CONFIG_EEPROM_AT25=y
85 | CONFIG_SCSI=y
86 | CONFIG_BLK_DEV_SD=y
87 | CONFIG_CHR_DEV_SG=y
88 | CONFIG_NETDEVICES=y
89 | CONFIG_MACB=y
90 | # CONFIG_NET_VENDOR_CIRRUS is not set
91 | # CONFIG_NET_VENDOR_FARADAY is not set
92 | CONFIG_E1000E=y
93 | # CONFIG_NET_VENDOR_MARVELL is not set
94 | # CONFIG_NET_VENDOR_MICREL is not set
95 | # CONFIG_NET_VENDOR_MICROCHIP is not set
96 | # CONFIG_NET_VENDOR_NATSEMI is not set
97 | CONFIG_R8169=y
98 | # CONFIG_NET_VENDOR_SEEQ is not set
99 | # CONFIG_NET_VENDOR_SMSC is not set
100 | # CONFIG_NET_VENDOR_STMICRO is not set
101 | # CONFIG_NET_VENDOR_VIA is not set
102 | # CONFIG_NET_VENDOR_WIZNET is not set
103 | CONFIG_XILINX_EMACLITE=y
104 | CONFIG_XILINX_AXI_EMAC=y
105 | CONFIG_MARVELL_PHY=y
106 | CONFIG_VITESSE_PHY=y
107 | CONFIG_REALTEK_PHY=y
108 | CONFIG_CAN_XILINXCAN=y
109 | CONFIG_MDIO_BITBANG=y
110 | CONFIG_INPUT_SPARSEKMAP=y
111 | CONFIG_INPUT_EVDEV=y
112 | CONFIG_KEYBOARD_GPIO=y
113 | CONFIG_KEYBOARD_GPIO_POLLED=y
114 | # CONFIG_LEGACY_PTYS is not set
115 | CONFIG_SERIAL_XILINX_PS_UART=y
116 | CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
117 | # CONFIG_HW_RANDOM is not set
118 | CONFIG_XILINX_DEVCFG=y
119 | CONFIG_I2C_CHARDEV=y
120 | CONFIG_I2C_MUX=y
121 | CONFIG_I2C_MUX_PCA954x=y
122 | CONFIG_I2C_CADENCE=y
123 | CONFIG_I2C_XILINX=y
124 | CONFIG_SPI=y
125 | CONFIG_SPI_CADENCE=y
126 | CONFIG_SPI_XILINX=y
127 | CONFIG_SPI_ZYNQ_QSPI=y
128 | CONFIG_GPIO_SYSFS=y
129 | CONFIG_GPIO_XILINX=y
130 | CONFIG_GPIO_ZYNQ=y
131 | CONFIG_PMBUS=y
132 | CONFIG_SENSORS_UCD9000=y
133 | CONFIG_SENSORS_UCD9200=y
134 | CONFIG_THERMAL=y
135 | CONFIG_CPU_THERMAL=y
136 | CONFIG_WATCHDOG=y
137 | CONFIG_XILINX_WATCHDOG=y
138 | CONFIG_CADENCE_WATCHDOG=y
139 | CONFIG_REGULATOR=y
140 | CONFIG_MEDIA_SUPPORT=y
141 | CONFIG_V4L_PLATFORM_DRIVERS=y
142 | CONFIG_VIDEO_XILINX=y
143 | CONFIG_VIDEO_XILINX_TPG=y
144 | CONFIG_VIDEO_ADV7604=y
145 | CONFIG_DRM=y
146 | CONFIG_SOUND=y
147 | CONFIG_SND=y
148 | CONFIG_SND_SOC=y
149 | CONFIG_SND_SOC_ADI=y
150 | CONFIG_SND_SOC_ADI_AXI_I2S=y
151 | CONFIG_SND_SOC_ADI_AXI_SPDIF=y
152 | CONFIG_HID_MICROSOFT=y
153 | CONFIG_USB=y
154 | CONFIG_USB_EHCI_HCD=y
155 | CONFIG_USB_EHCI_TT_NEWSCHED=y
156 | CONFIG_USB_STORAGE=y
157 | CONFIG_USB_UAS=m
158 | CONFIG_USB_CHIPIDEA=y
159 | CONFIG_USB_CHIPIDEA_UDC=y
160 | CONFIG_USB_CHIPIDEA_HOST=y
161 | CONFIG_NOP_USB_XCEIV=y
162 | CONFIG_USB_ULPI=y
163 | CONFIG_USB_GADGET=y
164 | CONFIG_USB_GADGET_XILINX=y
165 | CONFIG_USB_CONFIGFS=m
166 | CONFIG_USB_CONFIGFS_MASS_STORAGE=y
167 | CONFIG_USB_ZERO=m
168 | CONFIG_MMC=y
169 | CONFIG_MMC_SDHCI=y
170 | CONFIG_MMC_SDHCI_PLTFM=y
171 | CONFIG_MMC_SDHCI_OF_ARASAN=y
172 | CONFIG_NEW_LEDS=y
173 | CONFIG_LEDS_CLASS=y
174 | CONFIG_LEDS_GPIO=y
175 | CONFIG_LEDS_TRIGGERS=y
176 | CONFIG_LEDS_TRIGGER_TIMER=y
177 | CONFIG_LEDS_TRIGGER_ONESHOT=y
178 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y
179 | CONFIG_LEDS_TRIGGER_BACKLIGHT=y
180 | CONFIG_LEDS_TRIGGER_CPU=y
181 | CONFIG_LEDS_TRIGGER_GPIO=y
182 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
183 | CONFIG_LEDS_TRIGGER_TRANSIENT=y
184 | CONFIG_LEDS_TRIGGER_CAMERA=y
185 | CONFIG_EDAC=y
186 | CONFIG_EDAC_SYNOPSYS=y
187 | CONFIG_RTC_CLASS=y
188 | CONFIG_RTC_DRV_PCF8563=y
189 | CONFIG_DMADEVICES=y
190 | CONFIG_PL330_DMA=y
191 | CONFIG_XILINX_DMA=y
192 | CONFIG_UIO=y
193 | CONFIG_UIO_PDRV_GENIRQ=y
194 | CONFIG_COMMON_CLK_SI570=y
195 | CONFIG_REMOTEPROC=y
196 | CONFIG_MEMORY=y
197 | CONFIG_IIO=y
198 | CONFIG_XILINX_XADC=y
199 | CONFIG_XILINX_INTC=y
200 | CONFIG_RAS=y
201 | CONFIG_EXT3_FS=y
202 | # CONFIG_DNOTIFY is not set
203 | CONFIG_MSDOS_FS=y
204 | CONFIG_VFAT_FS=y
205 | CONFIG_TMPFS=y
206 | CONFIG_JFFS2_FS=y
207 | CONFIG_JFFS2_SUMMARY=y
208 | CONFIG_NFS_FS=y
209 | CONFIG_ROOT_NFS=y
210 | CONFIG_NLS_CODEPAGE_437=y
211 | CONFIG_NLS_ASCII=y
212 | CONFIG_NLS_ISO8859_1=y
213 | CONFIG_DMA_CMA=y
214 | CONFIG_RCU_CPU_STALL_TIMEOUT=60
215 | # CONFIG_FTRACE is not set
216 | CONFIG_OVERLAY_FS=y
217 | CONFIG_SQUASHFS=y
218 | CONFIG_SQUASHFS_XZ=y
219 | CONFIG_WIRELESS=y
220 | CONFIG_CFG80211=m
221 | CONFIG_MAC80211=m
222 | CONFIG_RTL8188EU=m
223 | CONFIG_RT2X00=m
224 | CONFIG_RT2800USB=m
225 | CONFIG_RT2800USB_RT3573=y
226 | CONFIG_RT2800USB_RT53XX=y
227 | CONFIG_RT2800USB_RT55XX=y
228 | CONFIG_RT2800USB_UNKNOWN=y
229 | CONFIG_MT7601U=m
230 | CONFIG_ATH9K_HTC=m
231 | CONFIG_B43=m
232 | CONFIG_BRCMFMAC=m
233 | CONFIG_BRCMFMAC_USB=y
234 | CONFIG_PPP=m
235 | CONFIG_PPP_ASYNC=m
236 | CONFIG_PPP_BSDCOMP=m
237 | CONFIG_PPP_DEFLATE=m
238 | CONFIG_PPP_FILTER=y
239 | CONFIG_PPP_MULTILINK=y
240 | CONFIG_PPP_SYNC_TTY=m
241 | CONFIG_USB_USBNET=m
242 | CONFIG_USB_NET_CDC_EEM=m
243 | CONFIG_USB_NET_CDC_MBIM=m
244 | CONFIG_USB_NET_HUAWEI_CDC_NCM=m
245 | CONFIG_USB_NET_QMI_WWAN=m
246 | CONFIG_NAMESPACES=y
247 | CONFIG_NETFILTER=y
248 | CONFIG_NETFILTER_NETLINK=m
249 | CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
250 | CONFIG_NETFILTER_XT_MATCH_STATE=m
251 | CONFIG_NF_CONNTRACK=m
252 | CONFIG_NF_TABLES=m
253 | CONFIG_NF_TABLES_IPV4=y
254 | CONFIG_NFT_CT=m
255 | CONFIG_NFT_MASQ=m
256 | CONFIG_NFT_NAT=m
257 | CONFIG_NFT_COMPAT=m
258 | CONFIG_IP_NF_IPTABLES=m
259 | CONFIG_IP_NF_NAT=m
260 | CONFIG_IP_NF_TARGET_MASQUERADE=m
261 | CONFIG_IP_NF_FILTER=m
262 | CONFIG_IP_NF_MANGLE=m
263 | CONFIG_MACVLAN=m
264 | CONFIG_TUN=m
265 | CONFIG_FUSE_FS=m
266 | CONFIG_SPI_SPIDEV=m
267 | CONFIG_PPS_CLIENT_GPIO=m
268 | CONFIG_PPS_CLIENT_LDISC=m
269 | CONFIG_USB_GPIO_VBUS=y
270 | CONFIG_USB_ULPI_BUS=y
271 | CONFIG_SND_USB_AUDIO=m
272 | CONFIG_USB_SERIAL=m
273 | CONFIG_USB_SERIAL_GENERIC=y
274 | CONFIG_USB_SERIAL_OPTION=m
275 | CONFIG_USB_SERIAL_FTDI_SIO=m
276 | CONFIG_CIFS=m
277 | CONFIG_CIFS_STATS2=y
278 | CONFIG_CIFS_UPCALL=y
279 | CONFIG_CIFS_XATTR=y
280 | CONFIG_CIFS_POSIX=y
281 | CONFIG_CIFS_DFS_UPCALL=y
282 | CONFIG_USB_ACM=m
283 | CONFIG_USB_TMC=m
284 | CONFIG_VIDEOBUF2_VMALLOC=m
285 | CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=8
286 | CONFIG_U_SERIAL_CONSOLE=y
287 | CONFIG_USB_F_ACM=m
288 | CONFIG_USB_U_SERIAL=m
289 | CONFIG_USB_U_ETHER=m
290 | CONFIG_USB_F_SERIAL=m
291 | CONFIG_USB_F_OBEX=m
292 | CONFIG_USB_F_NCM=m
293 | CONFIG_USB_F_ECM=m
294 | CONFIG_USB_F_EEM=m
295 | CONFIG_USB_F_SUBSET=m
296 | CONFIG_USB_F_RNDIS=m
297 | CONFIG_USB_F_FS=m
298 | CONFIG_USB_F_UAC1=m
299 | CONFIG_USB_F_UAC2=m
300 | CONFIG_USB_F_UVC=m
301 | CONFIG_USB_F_MIDI=m
302 | CONFIG_USB_F_HID=m
303 | CONFIG_USB_F_PRINTER=m
304 | CONFIG_USB_CONFIGFS_SERIAL=y
305 | CONFIG_USB_CONFIGFS_ACM=y
306 | CONFIG_USB_CONFIGFS_OBEX=y
307 | CONFIG_USB_CONFIGFS_NCM=y
308 | CONFIG_USB_CONFIGFS_ECM=y
309 | CONFIG_USB_CONFIGFS_ECM_SUBSET=y
310 | CONFIG_USB_CONFIGFS_RNDIS=y
311 | CONFIG_USB_CONFIGFS_EEM=y
312 | CONFIG_USB_CONFIGFS_F_LB_SS=y
313 | CONFIG_USB_CONFIGFS_F_FS=y
314 | CONFIG_USB_CONFIGFS_F_UAC1=y
315 | CONFIG_USB_CONFIGFS_F_UAC2=y
316 | CONFIG_USB_CONFIGFS_F_MIDI=y
317 | CONFIG_USB_CONFIGFS_F_HID=y
318 | CONFIG_USB_CONFIGFS_F_UVC=y
319 | CONFIG_USB_CONFIGFS_F_PRINTER=y
320 | CONFIG_USB_AUDIO=m
321 | CONFIG_GADGET_UAC1=y
322 | CONFIG_USB_ETH=m
323 | CONFIG_USB_ETH_RNDIS=y
324 | CONFIG_USB_ETH_EEM=y
325 | CONFIG_USB_G_NCM=m
326 | CONFIG_USB_GADGETFS=m
327 | CONFIG_USB_FUNCTIONFS=m
328 | CONFIG_USB_FUNCTIONFS_ETH=y
329 | CONFIG_USB_FUNCTIONFS_RNDIS=y
330 | CONFIG_USB_FUNCTIONFS_GENERIC=y
331 | CONFIG_USB_MASS_STORAGE=m
332 | CONFIG_USB_G_SERIAL=m
333 | CONFIG_USB_MIDI_GADGET=m
334 | CONFIG_USB_G_PRINTER=m
335 | CONFIG_USB_CDC_COMPOSITE=m
336 | CONFIG_USB_G_ACM_MS=m
337 | CONFIG_USB_G_MULTI=m
338 | CONFIG_USB_G_MULTI_RNDIS=y
339 | CONFIG_USB_G_MULTI_CDC=y
340 | CONFIG_USB_G_HID=m
341 | CONFIG_USB_G_WEBCAM=m
342 |
--------------------------------------------------------------------------------
/projects/common_tools/app/Makefile:
--------------------------------------------------------------------------------
1 | CFLAGS = -O3 -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=hard
2 |
3 | all: measure-corr measure-level setup-adc sleep-rand sleep-to-59
4 |
5 | measure-corr: measure-corr.c
6 | gcc $(CFLAGS) -o $@ $^
7 |
8 | measure-level: measure-level.c
9 | gcc $(CFLAGS) -o $@ $^ -lm
10 |
11 | setup-adc: setup-adc.c
12 | gcc $(CFLAGS) -o $@ $^
13 |
14 | sleep-rand: sleep-rand.c
15 | gcc $(CFLAGS) -o $@ $^
16 |
17 | sleep-to-59: sleep-to-59.c
18 | gcc $(CFLAGS) -o $@ $^
19 |
20 | clean:
21 | rm -f measure-corr measure-level setup-adc sleep-rand sleep-to-59
22 |
--------------------------------------------------------------------------------
/projects/common_tools/app/enable-adc.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | echo 567 > /sys/class/gpio/export
4 | echo out > /sys/class/gpio/gpio567/direction
5 | echo 1 > /sys/class/gpio/gpio567/value
6 |
--------------------------------------------------------------------------------
/projects/common_tools/app/measure-corr.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | void usage()
11 | {
12 | fprintf(stderr, "Usage: measure-corr freq time\n");
13 | fprintf(stderr, " freq - frequency expressed in MHz (77.76, 100, 122.88 or 125),\n");
14 | fprintf(stderr, " time - measurement time expressed in seconds (from 1 to 30).\n");
15 | }
16 |
17 | int main(int argc, char *argv[])
18 | {
19 | int fd, i;
20 | char *end;
21 | volatile void *cfg, *sts;
22 | volatile uint32_t *fifo;
23 | volatile uint8_t *rst;
24 | volatile uint32_t *cntr;
25 | double freq;
26 | long time;
27 | uint32_t buffer;
28 | float corr;
29 |
30 | if(argc != 3)
31 | {
32 | usage();
33 | return EXIT_FAILURE;
34 | }
35 |
36 | errno = 0;
37 | freq = strtod(argv[1], &end);
38 | if(errno != 0 || end == argv[1] || (freq != 77.76 && freq != 100.0 && freq != 122.88 && freq != 125.0))
39 | {
40 | usage();
41 | return EXIT_FAILURE;
42 | }
43 |
44 | time = strtol(argv[2], &end, 10);
45 | if(errno != 0 || end == argv[2] || time < 1 || time > 30)
46 | {
47 | usage();
48 | return EXIT_FAILURE;
49 | }
50 |
51 | if((fd = open("/dev/mem", O_RDWR)) < 0)
52 | {
53 | fprintf(stderr, "Cannot open /dev/mem.\n");
54 | return EXIT_FAILURE;
55 | }
56 |
57 | cfg = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x80000000);
58 | sts = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x81000000);
59 | fifo = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x82000000);
60 |
61 | rst = (uint8_t *)(cfg + 0);
62 | cntr = (uint32_t *)(sts + 0);
63 |
64 | *rst &= ~1;
65 | *rst |= 1;
66 |
67 | sleep(time + 1);
68 |
69 | if(*cntr < time)
70 | {
71 | fprintf(stderr, "Not enough PPS pulses.\n");
72 | return EXIT_FAILURE;
73 | }
74 |
75 | buffer = 0;
76 |
77 | for(i = 0; i < time; ++i)
78 | {
79 | buffer += *fifo + 1;
80 | }
81 |
82 | corr = (freq * 1.0e6 * time / buffer - 1.0) * 1.0e6;
83 |
84 | if(corr < -100.0 || corr > 100.0)
85 | {
86 | fprintf(stderr, "Correction value is out of range.\n");
87 | return EXIT_FAILURE;
88 | }
89 |
90 | printf("%.2f\n", corr);
91 |
92 | return EXIT_SUCCESS;
93 | }
94 |
--------------------------------------------------------------------------------
/projects/common_tools/app/measure-level.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | int interrupted = 0;
13 |
14 | void signal_handler(int sig)
15 | {
16 | interrupted = 1;
17 | }
18 |
19 | void usage()
20 | {
21 | fprintf(stderr, "Usage: measure-level freq time\n");
22 | fprintf(stderr, " freq - frequency expressed in MHz (77.76, 100, 122.88 or 125),\n");
23 | fprintf(stderr, " time - measurement time expressed in seconds (from 1 to 30).\n");
24 | }
25 |
26 | int main(int argc, char *argv[])
27 | {
28 | int fd;
29 | char *end;
30 | volatile void *cfg, *sts;
31 | volatile uint8_t *rst;
32 | volatile uint16_t *cntr, *fifo;
33 | double freq, dbfs;
34 | long time;
35 | uint16_t level;
36 |
37 | if(argc != 3)
38 | {
39 | usage();
40 | return EXIT_FAILURE;
41 | }
42 |
43 | errno = 0;
44 | freq = strtod(argv[1], &end);
45 | if(errno != 0 || end == argv[1] || (freq != 77.76 && freq != 100.0 && freq != 122.88 && freq != 125.0))
46 | {
47 | usage();
48 | return EXIT_FAILURE;
49 | }
50 |
51 | errno = 0;
52 | time = strtol(argv[2], &end, 10);
53 | if(errno != 0 || end == argv[2] || time < 1 || time > 30)
54 | {
55 | usage();
56 | return EXIT_FAILURE;
57 | }
58 |
59 | if((fd = open("/dev/mem", O_RDWR)) < 0)
60 | {
61 | fprintf(stderr, "Cannot open /dev/mem.\n");
62 | return EXIT_FAILURE;
63 | }
64 |
65 | cfg = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x80000000);
66 | sts = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x81000000);
67 | fifo = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x83000000);
68 |
69 | rst = (uint8_t *)(cfg + 1);
70 | cntr = (uint16_t *)(sts + 2);
71 |
72 | *(uint32_t *)(cfg + 4) = (uint32_t)floor(freq * 1.0e6 * time + 0.5) - 1;
73 |
74 | *rst &= ~1;
75 | *rst |= 1;
76 |
77 | signal(SIGINT, signal_handler);
78 |
79 | while(!interrupted)
80 | {
81 | if(*cntr < 1)
82 | {
83 | usleep(1000);
84 | continue;
85 | }
86 |
87 | level = *fifo;
88 |
89 | dbfs = 20.0 * log10(1.0 * level / 8192);
90 |
91 | printf("%5.1f dBFS\n", dbfs);
92 | }
93 |
94 | *rst &= ~1;
95 |
96 | return EXIT_SUCCESS;
97 | }
98 |
--------------------------------------------------------------------------------
/projects/common_tools/app/setup-adc.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | int main()
10 | {
11 | int i, fd, value;
12 |
13 | uint8_t data[9] =
14 | {
15 | 0x00, 0x0B, 0x01,
16 | 0x00, 0x14, 0x41,
17 | 0x00, 0xFF, 0x01
18 | };
19 |
20 | fd = open("/dev/spidev0.0", O_RDWR);
21 |
22 | value = SPI_MODE_0;
23 | ioctl(fd, SPI_IOC_WR_MODE, &value);
24 |
25 | value = 8;
26 | ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &value);
27 |
28 | value = 1000000;
29 | ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &value);
30 |
31 | write(fd, data, 9);
32 |
33 | close(fd);
34 |
35 | return EXIT_SUCCESS;
36 | }
37 |
--------------------------------------------------------------------------------
/projects/common_tools/app/sleep-rand.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | int main(int argc, char *argv[])
7 | {
8 | char *end;
9 | long number;
10 | struct timespec t;
11 |
12 | errno = 0;
13 | number = (argc == 2) ? strtol(argv[1], &end, 10) : -1;
14 | if(errno != 0 || end == argv[1] || number < 1 || number > 3600)
15 | {
16 | fprintf(stderr, "Usage: sleep-rand [1-3600]\n");
17 | return EXIT_FAILURE;
18 | }
19 |
20 | clock_gettime(CLOCK_REALTIME, &t);
21 | srand(t.tv_nsec / 1000);
22 | t.tv_sec = rand() % number;
23 | t.tv_nsec = rand() % 1000 * 1000000L;
24 | nanosleep(&t, NULL);
25 | return EXIT_SUCCESS;
26 | }
27 |
--------------------------------------------------------------------------------
/projects/common_tools/app/sleep-to-59.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | int main()
6 | {
7 | struct timespec t;
8 | clock_gettime(CLOCK_REALTIME, &t);
9 | t.tv_sec = 58 - t.tv_sec % 60;
10 | t.tv_nsec = 999999999L - t.tv_nsec;
11 | nanosleep(&t, NULL);
12 | return EXIT_SUCCESS;
13 | }
14 |
--------------------------------------------------------------------------------
/projects/common_tools/app/update-corr.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | DIR=`readlink -f $0`
4 | DIR=`dirname $DIR`
5 |
6 | date
7 |
8 | CORR=`$DIR/measure-corr $1 30` || exit
9 |
10 | for file in *.cfg
11 | do
12 | sed -i "/^corr/s/=.*/= $CORR;/" $file
13 | done
14 |
--------------------------------------------------------------------------------
/projects/common_tools/block_design.tcl:
--------------------------------------------------------------------------------
1 | # HUB
2 |
3 | # Create axi_hub
4 | cell pavel-demin:user:axi_hub hub_0 {
5 | CFG_DATA_WIDTH 64
6 | STS_DATA_WIDTH 32
7 | } {
8 | S_AXI /ps_0/M_AXI_GP1
9 | aclk /pll_0/clk_out1
10 | aresetn /rst_0/peripheral_aresetn
11 | }
12 |
13 | cell pavel-demin:user:port_slicer rst_slice_0 {
14 | DIN_WIDTH 64 DIN_FROM 0 DIN_TO 0
15 | } {
16 | din hub_0/cfg_data
17 | }
18 |
19 | # Create port_slicer
20 | cell pavel-demin:user:port_slicer rst_slice_1 {
21 | DIN_WIDTH 64 DIN_FROM 8 DIN_TO 8
22 | } {
23 | din hub_0/cfg_data
24 | }
25 |
26 | # Create port_slicer
27 | cell pavel-demin:user:port_slicer cfg_slice_0 {
28 | DIN_WIDTH 64 DIN_FROM 63 DIN_TO 32
29 | } {
30 | din hub_0/cfg_data
31 | }
32 |
33 | # Create port_slicer
34 | cell pavel-demin:user:port_slicer pps_slice_0 {
35 | DIN_WIDTH 1 DIN_FROM 0 DIN_TO 0
36 | } {
37 | din /pps_i
38 | dout /ps_0/GPIO_I
39 | }
40 |
41 | # PPS
42 |
43 | # Create axis_pps_counter
44 | cell pavel-demin:user:axis_pps_counter cntr_0 {
45 | AXIS_TDATA_WIDTH 32
46 | CNTR_WIDTH 32
47 | } {
48 | pps_data pps_slice_0/dout
49 | aclk /pll_0/clk_out1
50 | aresetn rst_slice_0/dout
51 | }
52 |
53 | # Create axis_fifo
54 | cell pavel-demin:user:axis_fifo fifo_0 {
55 | S_AXIS_TDATA_WIDTH 32
56 | M_AXIS_TDATA_WIDTH 32
57 | WRITE_DEPTH 1024
58 | } {
59 | S_AXIS cntr_0/M_AXIS
60 | M_AXIS hub_0/S00_AXIS
61 | aclk /pll_0/clk_out1
62 | aresetn rst_slice_0/dout
63 | }
64 |
65 | # Level measurement
66 |
67 | # Create xlconstant
68 | cell xilinx.com:ip:xlconstant const_0
69 |
70 | # Create axis_decimator
71 | cell pavel-demin:user:axis_maxabs_finder maxabs_0 {
72 | AXIS_TDATA_WIDTH 16
73 | CNTR_WIDTH 32
74 | } {
75 | s_axis_tdata /adc_0/m_axis_tdata
76 | s_axis_tvalid const_0/dout
77 | cfg_data cfg_slice_0/dout
78 | aclk /pll_0/clk_out1
79 | aresetn rst_slice_1/dout
80 | }
81 |
82 | # Create axis_fifo
83 | cell pavel-demin:user:axis_fifo fifo_1 {
84 | S_AXIS_TDATA_WIDTH 16
85 | M_AXIS_TDATA_WIDTH 32
86 | WRITE_DEPTH 1024
87 | } {
88 | S_AXIS maxabs_0/M_AXIS
89 | M_AXIS hub_0/S01_AXIS
90 | aclk /pll_0/clk_out1
91 | aresetn rst_slice_1/dout
92 | }
93 |
94 | # Create xlconcat
95 | cell xilinx.com:ip:xlconcat concat_0 {
96 | NUM_PORTS 2
97 | IN0_WIDTH 16
98 | IN1_WIDTH 16
99 | } {
100 | In0 fifo_0/read_count
101 | In1 fifo_1/read_count
102 | dout hub_0/sts_data
103 | }
104 |
--------------------------------------------------------------------------------
/projects/led_blinker_77_76/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | LED blinker
6 |
7 |
8 |
9 |
10 |
19 |
20 |
LED blinker
21 |
The LED blinker application is ready.
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/projects/led_blinker_77_76/app/start.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | apps_dir=/media/mmcblk0p1/apps
4 |
5 | source $apps_dir/stop.sh
6 |
7 | cat $apps_dir/led_blinker_77_76/led_blinker_77_76.bit > /dev/xdevcfg
8 |
9 | $apps_dir/common_tools/setup-adc
10 | $apps_dir/common_tools/enable-adc.sh
11 |
--------------------------------------------------------------------------------
/projects/led_blinker_77_76/block_design.tcl:
--------------------------------------------------------------------------------
1 | # Create ports
2 | create_bd_port -dir I adc_clk_p_i
3 | create_bd_port -dir I adc_clk_n_i
4 |
5 | create_bd_port -dir O adc_spi_sclk
6 | create_bd_port -dir O adc_spi_sdio
7 | create_bd_port -dir O adc_spi_cs
8 |
9 | create_bd_port -dir O adc_oe
10 |
11 | # Create xlconstant
12 | cell xilinx.com:ip:xlconstant const_0
13 |
14 | # Create clk_wiz
15 | cell xilinx.com:ip:clk_wiz pll_0 {
16 | PRIMITIVE PLL
17 | PRIM_IN_FREQ.VALUE_SRC USER
18 | PRIM_IN_FREQ 77.76
19 | PRIM_SOURCE Differential_clock_capable_pin
20 | CLKOUT1_USED true
21 | CLKOUT1_REQUESTED_OUT_FREQ 77.76
22 | USE_RESET false
23 | } {
24 | clk_in1_p adc_clk_p_i
25 | clk_in1_n adc_clk_n_i
26 | }
27 |
28 | # Create processing_system7
29 | cell xilinx.com:ip:processing_system7 ps_0 {
30 | PCW_IMPORT_BOARD_PRESET cfg/qmtech_xc7z020.xml
31 | } {
32 | M_AXI_GP0_ACLK pll_0/clk_out1
33 | SPI0_SCLK_O adc_spi_sclk
34 | SPI0_MOSI_O adc_spi_sdio
35 | SPI0_SS_I const_0/dout
36 | SPI0_SS_O adc_spi_cs
37 | }
38 |
39 | # Create port_slicer
40 | cell pavel-demin:user:port_slicer slice_0 {
41 | DIN_WIDTH 64 DIN_FROM 1 DIN_TO 1
42 | } {
43 | din ps_0/GPIO_O
44 | dout adc_oe
45 | }
46 |
47 | # Create all required interconnections
48 | apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {
49 | make_external {FIXED_IO, DDR}
50 | Master Disable
51 | Slave Disable
52 | } [get_bd_cells ps_0]
53 |
54 | # LED
55 |
56 | # Create c_counter_binary
57 | cell xilinx.com:ip:c_counter_binary cntr_0 {
58 | Output_Width 32
59 | } {
60 | CLK pll_0/clk_out1
61 | }
62 |
63 | # Create xlslice
64 | cell xilinx.com:ip:xlslice slice_1 {
65 | DIN_WIDTH 32 DIN_FROM 25 DIN_TO 25 DOUT_WIDTH 1
66 | } {
67 | Din cntr_0/Q
68 | Dout led_o
69 | }
70 |
--------------------------------------------------------------------------------
/projects/led_blinker_77_76/ports.xdc:
--------------------------------------------------------------------------------
1 | # clock
2 |
3 | set_property IOSTANDARD LVDS_25 [get_ports adc_clk_p_i]
4 | set_property IOSTANDARD LVDS_25 [get_ports adc_clk_n_i]
5 |
6 | set_property DIFF_TERM TRUE [get_ports adc_clk_p_i]
7 | set_property DIFF_TERM TRUE [get_ports adc_clk_n_i]
8 |
9 | set_property PACKAGE_PIN Y19 [get_ports adc_clk_p_i]
10 | set_property PACKAGE_PIN AA19 [get_ports adc_clk_n_i]
11 |
12 | # SPI
13 |
14 | set_property IOSTANDARD LVCMOS25 [get_ports adc_spi_*]
15 |
16 | set_property PACKAGE_PIN AA13 [get_ports adc_spi_sclk]
17 | set_property PACKAGE_PIN Y13 [get_ports adc_spi_sdio]
18 | set_property PACKAGE_PIN U15 [get_ports adc_spi_cs]
19 |
20 | # output enable
21 |
22 | set_property IOSTANDARD LVCMOS25 [get_ports adc_oe]
23 |
24 | set_property PACKAGE_PIN Y20 [get_ports adc_oe]
25 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_77_76/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SDR receiver compatible with HPSDR
6 |
7 |
8 |
9 |
10 |
19 |
20 |
SDR receiver
21 |
The SDR receiver is ready.
22 |
Now you can run the SDR programs such as SDR#, HDSDR.
23 |
More details about this application can be found at this link .
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_77_76/app/start.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | apps_dir=/media/mmcblk0p1/apps
4 |
5 | source $apps_dir/stop.sh
6 |
7 | cat $apps_dir/sdr_receiver_77_76/sdr_receiver_77_76.bit > /dev/xdevcfg
8 |
9 | $apps_dir/common_tools/setup-adc
10 | $apps_dir/common_tools/enable-adc.sh
11 |
12 | address=`awk -F : '$5="FF"' OFS=: /sys/class/net/eth0/address`
13 |
14 | echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
15 | echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
16 | echo 2 > /proc/sys/net/ipv4/conf/all/rp_filter
17 |
18 | ip link add mvl0 link eth0 address $address type macvlan mode passthru
19 |
20 | $apps_dir/sdr_receiver_77_76/sdr-receiver eth0 &
21 | $apps_dir/sdr_receiver_77_76/sdr-receiver mvl0 &
22 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_77_76/app/stop.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | killall -q sdr-receiver
4 |
5 | ip link del mvl0
6 |
7 | echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
8 | echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
9 | echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
10 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_77_76/block_design.tcl:
--------------------------------------------------------------------------------
1 | # Create ports
2 | create_bd_port -dir I adc_clk_p_i
3 | create_bd_port -dir I adc_clk_n_i
4 |
5 | create_bd_port -dir I adc_ovr_p_i
6 | create_bd_port -dir I adc_ovr_n_i
7 |
8 | create_bd_port -dir I -from 6 -to 0 adc_dat_p_i
9 | create_bd_port -dir I -from 6 -to 0 adc_dat_n_i
10 |
11 | create_bd_port -dir O adc_spi_sclk
12 | create_bd_port -dir O adc_spi_sdio
13 | create_bd_port -dir O adc_spi_cs
14 |
15 | create_bd_port -dir O adc_oe
16 |
17 | # Create xlconstant
18 | cell xilinx.com:ip:xlconstant const_0
19 |
20 | # Create clk_wiz
21 | cell xilinx.com:ip:clk_wiz pll_0 {
22 | PRIMITIVE PLL
23 | PRIM_IN_FREQ.VALUE_SRC USER
24 | PRIM_IN_FREQ 77.76
25 | PRIM_SOURCE Differential_clock_capable_pin
26 | CLKOUT1_USED true
27 | CLKOUT1_REQUESTED_OUT_FREQ 77.76
28 | USE_RESET false
29 | } {
30 | clk_in1_p adc_clk_p_i
31 | clk_in1_n adc_clk_n_i
32 | }
33 |
34 | # Create processing_system7
35 | cell xilinx.com:ip:processing_system7 ps_0 {
36 | PCW_IMPORT_BOARD_PRESET cfg/qmtech_xc7z020.xml
37 | PCW_USE_M_AXI_GP1 1
38 | } {
39 | M_AXI_GP0_ACLK pll_0/clk_out1
40 | M_AXI_GP1_ACLK pll_0/clk_out1
41 | SPI0_SCLK_O adc_spi_sclk
42 | SPI0_MOSI_O adc_spi_sdio
43 | SPI0_SS_I const_0/dout
44 | SPI0_SS_O adc_spi_cs
45 | }
46 |
47 | # Create port_slicer
48 | cell pavel-demin:user:port_slicer slice_0 {
49 | DIN_WIDTH 64 DIN_FROM 1 DIN_TO 1
50 | } {
51 | din ps_0/GPIO_O
52 | dout adc_oe
53 | }
54 |
55 | # Create all required interconnections
56 | apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {
57 | make_external {FIXED_IO, DDR}
58 | Master Disable
59 | Slave Disable
60 | } [get_bd_cells ps_0]
61 |
62 | # Create proc_sys_reset
63 | cell xilinx.com:ip:proc_sys_reset rst_0 {} {
64 | ext_reset_in const_0/dout
65 | dcm_locked pll_0/locked
66 | slowest_sync_clk pll_0/clk_out1
67 | }
68 |
69 | # ADC
70 |
71 | # Create util_ds_buf
72 | cell xilinx.com:ip:util_ds_buf buf_0 {
73 | C_SIZE 7
74 | C_BUF_TYPE IBUFDS
75 | } {
76 | IBUF_DS_P adc_dat_p_i
77 | IBUF_DS_N adc_dat_n_i
78 | }
79 |
80 | # Create axis_adc_ddr
81 | cell pavel-demin:user:axis_adc_ddr adc_0 {
82 | ADC_DATA_WIDTH 7
83 | } {
84 | aclk pll_0/clk_out1
85 | adc_data buf_0/IBUF_OUT
86 | }
87 |
88 | # RX 0
89 |
90 | module rx_0 {
91 | source projects/sdr_receiver_77_76/rx.tcl
92 | } {
93 | hub_0/S_AXI ps_0/M_AXI_GP0
94 | }
95 |
96 | # RX 1
97 |
98 | module rx_1 {
99 | source projects/sdr_receiver_77_76/rx.tcl
100 | } {
101 | hub_0/S_AXI ps_0/M_AXI_GP1
102 | }
103 |
104 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_77_76/client/convert.py:
--------------------------------------------------------------------------------
1 | from argparse import ArgumentParser
2 | import numpy as np
3 | import scipy.io.wavfile as wf
4 |
5 | rates = [48000, 96000, 192000, 384000]
6 |
7 | parser = ArgumentParser()
8 |
9 | parser.add_argument("--file", help="input file", required=True)
10 | parser.add_argument("--rate", help="sample rate %s" % rates, type=int, required=True)
11 |
12 | args = parser.parse_args()
13 |
14 | if args.rate not in rates:
15 | parser.print_help()
16 | exit(1)
17 |
18 | data = np.fromfile(args.file, dtype=np.complex64)
19 |
20 | for i in range(8):
21 | channel = data[i::8].view("(2,)float32")
22 | wf.write("%d.wav" % i, args.rate, channel)
23 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_77_76/client/record.py:
--------------------------------------------------------------------------------
1 | from argparse import ArgumentParser
2 | from socket import socket, AF_INET, SOCK_STREAM
3 | from signal import signal, SIGINT
4 | from struct import pack
5 | from sys import exit
6 |
7 | rates = {48000: 0, 96000: 1, 192000: 2, 384000: 3}
8 |
9 | parser = ArgumentParser()
10 |
11 | parser.add_argument("--addr", help="IP address of the QMTECH XC7Z020 board", required=True)
12 | parser.add_argument("--freq", help="8 center frequencies in Hz [0 - 490000000]", nargs=8, type=int, required=True)
13 | parser.add_argument("--rate", help="sample rate %s" % list(rates.keys()), type=int, required=True)
14 | parser.add_argument("--corr", help="frequency correction in ppm [-100 - 100]", type=float, required=True)
15 | parser.add_argument("--file", help="output file", required=True)
16 |
17 | args = parser.parse_args()
18 |
19 | for f in args.freq:
20 | if f < 0 or f > 490000000:
21 | parser.print_help()
22 | exit(1)
23 |
24 | if args.rate not in rates:
25 | parser.print_help()
26 | exit(1)
27 |
28 | if args.corr < -100 or args.corr > 100:
29 | parser.print_help()
30 | exit(1)
31 |
32 | sock = socket(AF_INET, SOCK_STREAM)
33 | sock.settimeout(5)
34 | try:
35 | sock.connect((args.addr, 1001))
36 | except:
37 | print("error: could not connect to", args.addr)
38 | exit(1)
39 | sock.settimeout(None)
40 |
41 | sock.send(pack("<10I", 0, rates[args.rate], *[int((1.0 + 1e-6 * args.corr) * f) for f in args.freq]))
42 |
43 | interrupted = False
44 |
45 |
46 | def signal_handler(signal, frame):
47 | global interrupted
48 | interrupted = True
49 |
50 |
51 | signal(SIGINT, signal_handler)
52 |
53 | try:
54 | f = open(args.file, "wb")
55 | except:
56 | print("error: could not open", args.file)
57 | exit(1)
58 |
59 | data = sock.recv(4096)
60 | while data and not interrupted:
61 | f.write(data)
62 | data = sock.recv(4096)
63 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_77_76/filters/rx_fir_0.r:
--------------------------------------------------------------------------------
1 | library(signal)
2 |
3 | # CIC filter parameters
4 | R <- 81 # Decimation factor
5 | M <- 1 # Differential delay
6 | N <- 6 # Number of stages
7 |
8 | Fc <- 0.097 # cutoff frequency
9 | htbw <- 0.005 # half transition bandwidth
10 |
11 | # fir2 parameters
12 | k <- kaiserord(c(Fc-htbw, Fc+htbw), c(1, 0), 1/(2^16), 1)
13 | L <- k$n # Filter order
14 | Beta <- k$beta # Kaiser window parameter
15 |
16 | # FIR filter design using fir2
17 | s <- 0.001 # Step size
18 | fp <- seq(0.0, Fc-htbw, by=s) # Pass band frequency samples
19 | fs <- seq(Fc+htbw, 0.5, by=s) # Stop band frequency samples
20 | f <- c(fp, fs)*2 # Normalized frequency samples; 0<=f<=1
21 |
22 | Mp <- matrix(1, 1, length(fp)) # Pass band response; Mp[1]=1
23 | Mp[-1] <- abs(M*R*sin(pi*fp[-1]*2/R)/sin(pi*M*fp[-1]*2))^N
24 | Mf <- c(Mp, matrix(0, 1, length(fs)))
25 |
26 | h <- fir2(L, f, Mf, window=kaiser(L+1, Beta))
27 |
28 | h <- h / sum(h)
29 |
30 | # Print filter coefficients
31 | paste(sprintf("%.10e", h), collapse=", ")
32 |
33 | fh <- freqz(h)
34 |
35 | op <- par(mfrow = c(2, 1))
36 |
37 | plot(f, 20*log10(Mf), type = "b", ylab = "dB", xlab = "Frequency", xlim = c(0.20, 0.22), ylim = c(-125, 5))
38 | lines(fh$f / pi, 20*log10(abs(fh$h)), col = "blue")
39 | grid()
40 |
41 | plot(f, 20*log10(Mf), type = "b", ylab = "dB", xlab = "Frequency", xlim = c(0.18, 0.20), ylim = c(-5, 5))
42 | lines(fh$f / pi, 20*log10(abs(fh$h)), col = "blue")
43 | grid()
44 |
45 | par(op)
46 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_77_76/ports.xdc:
--------------------------------------------------------------------------------
1 | # clock
2 |
3 | set_property IOSTANDARD LVDS_25 [get_ports adc_clk_p_i]
4 | set_property IOSTANDARD LVDS_25 [get_ports adc_clk_n_i]
5 |
6 | set_property DIFF_TERM TRUE [get_ports adc_clk_p_i]
7 | set_property DIFF_TERM TRUE [get_ports adc_clk_n_i]
8 |
9 | set_property PACKAGE_PIN Y19 [get_ports adc_clk_p_i]
10 | set_property PACKAGE_PIN AA19 [get_ports adc_clk_n_i]
11 |
12 | # overrange
13 |
14 | set_property IOSTANDARD LVDS_25 [get_ports {adc_ovr_p_i}]
15 | set_property IOSTANDARD LVDS_25 [get_ports {adc_ovr_n_i}]
16 |
17 | set_property DIFF_TERM TRUE [get_ports {adc_ovr_p_i]}]
18 | set_property DIFF_TERM TRUE [get_ports {adc_ovr_n_i}]
19 |
20 | set_property PACKAGE_PIN U17 [get_ports {adc_ovr_p_i}]
21 | set_property PACKAGE_PIN V17 [get_ports {adc_ovr_n_i}]
22 |
23 | # data
24 |
25 | set_property IOSTANDARD LVDS_25 [get_ports {adc_dat_p_i[*]}]
26 | set_property IOSTANDARD LVDS_25 [get_ports {adc_dat_n_i[*]}]
27 |
28 | set_property DIFF_TERM TRUE [get_ports {adc_dat_p_i[*]}]
29 | set_property DIFF_TERM TRUE [get_ports {adc_dat_n_i[*]}]
30 |
31 | set_property PACKAGE_PIN AA17 [get_ports {adc_dat_p_i[0]}]
32 | set_property PACKAGE_PIN AB17 [get_ports {adc_dat_n_i[0]}]
33 |
34 | set_property PACKAGE_PIN AA16 [get_ports {adc_dat_p_i[1]}]
35 | set_property PACKAGE_PIN AB16 [get_ports {adc_dat_n_i[1]}]
36 |
37 | set_property PACKAGE_PIN AB14 [get_ports {adc_dat_p_i[2]}]
38 | set_property PACKAGE_PIN AB15 [get_ports {adc_dat_n_i[2]}]
39 |
40 | set_property PACKAGE_PIN Y18 [get_ports {adc_dat_p_i[3]}]
41 | set_property PACKAGE_PIN AA18 [get_ports {adc_dat_n_i[3]}]
42 |
43 | set_property PACKAGE_PIN W17 [get_ports {adc_dat_p_i[4]}]
44 | set_property PACKAGE_PIN W18 [get_ports {adc_dat_n_i[4]}]
45 |
46 | set_property PACKAGE_PIN W16 [get_ports {adc_dat_p_i[5]}]
47 | set_property PACKAGE_PIN Y16 [get_ports {adc_dat_n_i[5]}]
48 |
49 | set_property PACKAGE_PIN Y14 [get_ports {adc_dat_p_i[6]}]
50 | set_property PACKAGE_PIN AA14 [get_ports {adc_dat_n_i[6]}]
51 |
52 | # SPI
53 |
54 | set_property IOSTANDARD LVCMOS25 [get_ports adc_spi_*]
55 |
56 | set_property PACKAGE_PIN AA13 [get_ports adc_spi_sclk]
57 | set_property PACKAGE_PIN Y13 [get_ports adc_spi_sdio]
58 | set_property PACKAGE_PIN U15 [get_ports adc_spi_cs]
59 |
60 | # output enable
61 |
62 | set_property IOSTANDARD LVCMOS25 [get_ports adc_oe]
63 |
64 | set_property PACKAGE_PIN Y20 [get_ports adc_oe]
65 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_77_76/rx.tcl:
--------------------------------------------------------------------------------
1 | # Create axi_hub
2 | cell pavel-demin:user:axi_hub hub_0 {
3 | CFG_DATA_WIDTH 288
4 | STS_DATA_WIDTH 32
5 | } {
6 | aclk /pll_0/clk_out1
7 | aresetn /rst_0/peripheral_aresetn
8 | }
9 |
10 | # Create port_slicer
11 | cell pavel-demin:user:port_slicer slice_0 {
12 | DIN_WIDTH 288 DIN_FROM 0 DIN_TO 0
13 | } {
14 | din hub_0/cfg_data
15 | }
16 |
17 | # Create port_slicer
18 | cell pavel-demin:user:port_slicer slice_1 {
19 | DIN_WIDTH 288 DIN_FROM 31 DIN_TO 16
20 | } {
21 | din hub_0/cfg_data
22 | }
23 |
24 | for {set i 0} {$i <= 7} {incr i} {
25 |
26 | # Create port_slicer
27 | cell pavel-demin:user:port_slicer slice_[expr $i + 2] {
28 | DIN_WIDTH 288 DIN_FROM [expr 32 * $i + 63] DIN_TO [expr 32 * $i + 32]
29 | } {
30 | din hub_0/cfg_data
31 | }
32 |
33 | # Create dds
34 | cell pavel-demin:user:dds dds_$i {
35 | NEGATIVE_SINE TRUE
36 | } {
37 | pinc slice_[expr $i + 2]/dout
38 | aclk /pll_0/clk_out1
39 | aresetn /rst_0/peripheral_aresetn
40 | }
41 |
42 | }
43 |
44 | # Create xlconstant
45 | cell xilinx.com:ip:xlconstant const_0
46 |
47 | for {set i 0} {$i <= 15} {incr i} {
48 |
49 | # Create port_slicer
50 | cell pavel-demin:user:port_slicer dds_slice_$i {
51 | DIN_WIDTH 48 DIN_FROM [expr 24 * ($i % 2) + 23] DIN_TO [expr 24 * ($i % 2)]
52 | } {
53 | din dds_[expr $i / 2]/dout
54 | }
55 |
56 | # Create dsp48
57 | cell pavel-demin:user:dsp48 mult_$i {
58 | A_WIDTH 24
59 | B_WIDTH 14
60 | P_WIDTH 24
61 | } {
62 | A dds_slice_$i/dout
63 | B /adc_0/m_axis_tdata
64 | CLK /pll_0/clk_out1
65 | }
66 |
67 | # Create axis_variable
68 | cell pavel-demin:user:axis_variable rate_$i {
69 | AXIS_TDATA_WIDTH 16
70 | } {
71 | cfg_data slice_1/dout
72 | aclk /pll_0/clk_out1
73 | aresetn /rst_0/peripheral_aresetn
74 | }
75 |
76 | # Create cic_compiler
77 | cell xilinx.com:ip:cic_compiler cic_$i {
78 | INPUT_DATA_WIDTH.VALUE_SRC USER
79 | FILTER_TYPE Decimation
80 | NUMBER_OF_STAGES 6
81 | SAMPLE_RATE_CHANGES Programmable
82 | MINIMUM_RATE 81
83 | MAXIMUM_RATE 1296
84 | FIXED_OR_INITIAL_RATE 648
85 | INPUT_SAMPLE_FREQUENCY 77.76
86 | CLOCK_FREQUENCY 77.76
87 | INPUT_DATA_WIDTH 24
88 | QUANTIZATION Truncation
89 | OUTPUT_DATA_WIDTH 32
90 | USE_XTREME_DSP_SLICE false
91 | HAS_ARESETN true
92 | } {
93 | s_axis_data_tdata mult_$i/P
94 | s_axis_data_tvalid const_0/dout
95 | S_AXIS_CONFIG rate_$i/M_AXIS
96 | aclk /pll_0/clk_out1
97 | aresetn /rst_0/peripheral_aresetn
98 | }
99 |
100 | }
101 |
102 | # Create axis_combiner
103 | cell xilinx.com:ip:axis_combiner comb_0 {
104 | TDATA_NUM_BYTES.VALUE_SRC USER
105 | TDATA_NUM_BYTES 4
106 | NUM_SI 16
107 | } {
108 | S00_AXIS cic_0/M_AXIS_DATA
109 | S01_AXIS cic_1/M_AXIS_DATA
110 | S02_AXIS cic_2/M_AXIS_DATA
111 | S03_AXIS cic_3/M_AXIS_DATA
112 | S04_AXIS cic_4/M_AXIS_DATA
113 | S05_AXIS cic_5/M_AXIS_DATA
114 | S06_AXIS cic_6/M_AXIS_DATA
115 | S07_AXIS cic_7/M_AXIS_DATA
116 | S08_AXIS cic_8/M_AXIS_DATA
117 | S09_AXIS cic_9/M_AXIS_DATA
118 | S10_AXIS cic_10/M_AXIS_DATA
119 | S11_AXIS cic_11/M_AXIS_DATA
120 | S12_AXIS cic_12/M_AXIS_DATA
121 | S13_AXIS cic_13/M_AXIS_DATA
122 | S14_AXIS cic_14/M_AXIS_DATA
123 | S15_AXIS cic_15/M_AXIS_DATA
124 | aclk /pll_0/clk_out1
125 | aresetn /rst_0/peripheral_aresetn
126 | }
127 |
128 | # Create axis_dwidth_converter
129 | cell xilinx.com:ip:axis_dwidth_converter conv_0 {
130 | S_TDATA_NUM_BYTES.VALUE_SRC USER
131 | S_TDATA_NUM_BYTES 64
132 | M_TDATA_NUM_BYTES 4
133 | } {
134 | S_AXIS comb_0/M_AXIS
135 | aclk /pll_0/clk_out1
136 | aresetn /rst_0/peripheral_aresetn
137 | }
138 |
139 | # Create fir_compiler
140 | cell xilinx.com:ip:fir_compiler fir_0 {
141 | DATA_WIDTH.VALUE_SRC USER
142 | DATA_WIDTH 32
143 | COEFFICIENTVECTOR {8.6416634255e-09, 1.9787522479e-08, 2.5521203789e-08, 2.3638357357e-08, 1.4790149581e-08, 1.9719648224e-09, -1.1032338549e-08, -2.1355862813e-08, -2.7914377238e-08, -3.0931374243e-08, -3.0470610650e-08, -2.5069790691e-08, -1.1732378562e-08, 1.2106227398e-08, 4.5256582454e-08, 7.9934220054e-08, 1.0168998967e-07, 9.3590856156e-08, 4.4144966037e-08, -4.3922671719e-08, -1.4852200249e-07, -2.3083384546e-07, -2.4726320140e-07, -1.6800994993e-07, 4.5912166862e-09, 2.2678122505e-07, 4.2020376983e-07, 4.9631671575e-07, 3.9210438758e-07, 1.0401511886e-07, -2.9540946982e-07, -6.6974601177e-07, -8.6118574256e-07, -7.5179544934e-07, -3.2135153633e-07, 3.2363684057e-07, 9.6792135313e-07, 1.3542946906e-06, 1.2805958992e-06, 6.9217855668e-07, -2.6932495334e-07, -1.2887872597e-06, -1.9748299670e-06, -2.0041416687e-06, -1.2616531622e-06, 8.1045970371e-08, 1.5902969896e-06, 2.7034505382e-06, 2.9326808171e-06, 2.0677893719e-06, 2.9671782990e-07, -1.8153799542e-06, -3.4986916001e-06, -4.0537458905e-06, -3.1326541017e-06, -9.1621545700e-07, 1.8951789437e-06, 4.2945533398e-06, 5.3243068872e-06, 4.4510966031e-06, 1.8150145648e-06, -1.7570418369e-06, -5.0023771924e-06, -6.6656492920e-06, -5.9799678791e-06, -3.0028313096e-06, 1.3358282157e-06, 5.5163795673e-06, 7.9608658936e-06, 7.6277789306e-06, 4.4461154951e-06, -5.8984164425e-07, -5.7251392145e-06, -9.0581314802e-06, -9.2484912704e-06, -6.0541412073e-06, -4.8199458599e-07, 5.5262501707e-06, 9.7774958316e-06, 1.0637326831e-05, 7.6640662304e-06, 1.8181526672e-06, -4.8491693605e-06, -9.9277893079e-06, -1.1536455496e-05, -9.0334291964e-06, -3.2759450427e-06, 3.6790473433e-06, 9.3279777293e-06, 1.1646532779e-05, 9.8373152541e-06, 4.6141546613e-06, -2.0841283602e-06, -7.8366295707e-06, -1.0649202562e-05, -9.6766597871e-06, -5.4841491162e-06, 2.3935387332e-07, 5.3827746410e-06, 8.2348658276e-06, 8.0928618642e-06, 5.4248153015e-06, 1.5482305844e-06, -2.0058806216e-06, -4.1464815041e-06, -4.6028386086e-06, -3.8783946363e-06, -2.8311981110e-06, -2.1143317814e-06, -1.7787125841e-06, -1.2613202098e-06, 2.1404336279e-07, 3.0196794545e-06, 6.6285446608e-06, 9.5597769186e-06, 9.8970858249e-06, 6.2280706793e-06, -1.3999300558e-06, -1.1004079038e-05, -1.9029472380e-05, -2.1573387839e-05, -1.6082598930e-05, -2.8350137599e-06, 1.4518712779e-05, 2.9788917181e-05, 3.6356227405e-05, 2.9875585364e-05, 1.0516808093e-05, -1.6294026764e-05, -4.1195968302e-05, -5.4056581743e-05, -4.7949938310e-05, -2.2431204012e-05, 1.5335680685e-05, 5.2357533492e-05, 7.4172234233e-05, 7.0371097114e-05, 3.9214909546e-05, -1.0613325355e-05, -6.2159982313e-05, -9.5857297703e-05, -9.6843895010e-05, -6.1246116434e-05, 1.1596087820e-06, 6.9321939920e-05, 1.1790595196e-04, 1.2662552441e-04, 8.8507777460e-05, 1.3781498407e-05, -7.2510875641e-05, -1.3880280100e-04, -1.5849588836e-04, -1.2049046521e-04, -3.4625933141e-05, 7.0455194291e-05, 1.5677318467e-04, 1.9071963279e-04, 1.5606818885e-04, 6.1270662098e-05, -6.2125794971e-05, -1.6991125582e-04, -2.2107906371e-04, -1.9342374961e-04, -9.2934134104e-05, 4.6928443366e-05, 1.7633944720e-04, 2.4694245575e-04, 2.2999478843e-04, 1.2798765460e-04, -2.4941664121e-05, -1.7444600564e-04, -2.6542975109e-04, -2.6251833556e-04, -1.6386926905e-04, -2.9017345509e-06, 1.6309186966e-04, 2.7356222115e-04, 2.8705580527e-04, 1.9695561615e-04, 3.4555670489e-05, -1.4193230722e-04, -2.6855336886e-04, -2.9916488047e-04, -2.2256165500e-04, -6.6689937029e-05, 1.1170007522e-04, 2.4810655924e-04, 2.9410546207e-04, 2.3497584277e-04, 9.4530201531e-05, -7.4520222202e-05, -2.1079107961e-04, -2.6716055532e-04, -2.2762585917e-04, -1.1182026094e-04, 3.4129098118e-05, 1.5635447302e-04, 2.1391598199e-04, 1.9320383872e-04, 1.1071751871e-04, 3.7908910630e-06, -8.6209631786e-05, -1.3076687946e-04, -1.2404753376e-04, -8.1941203532e-05, -3.1493984650e-05, 3.7618482978e-06, 1.5327191471e-05, 1.2475457050e-05, 1.4900403573e-05, 3.9029838255e-05, 8.5212216095e-05, 1.3306952296e-04, 1.4875133947e-04, 1.0203253711e-04, -1.4244728473e-05, -1.7230750533e-04, -3.1296479335e-04, -3.6604545253e-04, -2.8133052368e-04, -5.7330371892e-05, 2.4606492228e-04, 5.2013232626e-04, 6.4430392795e-04, 5.3576204832e-04, 1.9220436978e-04, -2.9193714506e-04, -7.4731044440e-04, -9.8656619314e-04, -8.7815597539e-04, -4.0893233116e-04, 2.9200492514e-04, 9.8371803137e-04, 1.3934897225e-03, 1.3210162624e-03, 7.2799464557e-04, -2.2481558671e-04, -1.2147116076e-03, -1.8630079096e-03, -1.8763709734e-03, -1.1719555546e-03, 6.4921935546e-05, 1.4211556881e-03, 2.3897382217e-03, 2.5554049165e-03, 1.7653955158e-03, 2.1726375791e-04, -1.5792901757e-03, -2.9651397494e-03, -3.3691024975e-03, -2.5360356113e-03, -6.5682663411e-04, 1.6595757982e-03, 3.5770214428e-03, 4.3286963968e-03, 3.5160483017e-03, 1.2960357442e-03, -1.6254062809e-03, -4.2094376163e-03, -5.4471917717e-03, -4.7450324797e-03, -2.1878913494e-03, 1.4303547141e-03, 4.8420974952e-03, 6.7417004048e-03, 6.2749186441e-03, 3.4019773004e-03, -1.0139113090e-03, -5.4502911147e-03, -8.2390953251e-03, -8.1808578202e-03, -5.0376756147e-03, 2.9071387529e-04, 6.0016792136e-03, 9.9836955649e-03, 1.0579354406e-02, 7.2475257605e-03, 8.6880057823e-04, -6.4514589167e-03, -1.2054494720e-02, -1.3667770498e-02, -1.0289159644e-02, -2.6835541906e-03, 6.7274828446e-03, 1.4599435427e-02, 1.7811581265e-02, 1.4646249040e-02, 5.5728291554e-03, -6.6881265746e-03, -1.7916290000e-02, -2.3770141281e-02, -2.1362115622e-02, -1.0487921502e-02, 5.9634682621e-03, 2.2652378162e-02, 3.3374547837e-02, 3.3147252075e-02, 2.0139686562e-02, -3.2170050718e-03, -3.0392681085e-02, -5.2269158542e-02, -5.9644704750e-02, -4.6033325214e-02, -9.9174346067e-03, 4.4272248035e-02, 1.0682708940e-01, 1.6497706887e-01, 2.0608084740e-01, 2.2090784056e-01, 2.0608084740e-01, 1.6497706887e-01, 1.0682708940e-01, 4.4272248035e-02, -9.9174346067e-03, -4.6033325214e-02, -5.9644704750e-02, -5.2269158542e-02, -3.0392681085e-02, -3.2170050718e-03, 2.0139686562e-02, 3.3147252075e-02, 3.3374547837e-02, 2.2652378162e-02, 5.9634682621e-03, -1.0487921502e-02, -2.1362115622e-02, -2.3770141281e-02, -1.7916290000e-02, -6.6881265746e-03, 5.5728291554e-03, 1.4646249040e-02, 1.7811581265e-02, 1.4599435427e-02, 6.7274828446e-03, -2.6835541906e-03, -1.0289159644e-02, -1.3667770498e-02, -1.2054494720e-02, -6.4514589167e-03, 8.6880057823e-04, 7.2475257605e-03, 1.0579354406e-02, 9.9836955649e-03, 6.0016792136e-03, 2.9071387529e-04, -5.0376756147e-03, -8.1808578202e-03, -8.2390953251e-03, -5.4502911147e-03, -1.0139113090e-03, 3.4019773004e-03, 6.2749186441e-03, 6.7417004048e-03, 4.8420974952e-03, 1.4303547141e-03, -2.1878913494e-03, -4.7450324797e-03, -5.4471917717e-03, -4.2094376163e-03, -1.6254062809e-03, 1.2960357442e-03, 3.5160483017e-03, 4.3286963968e-03, 3.5770214428e-03, 1.6595757982e-03, -6.5682663411e-04, -2.5360356113e-03, -3.3691024975e-03, -2.9651397494e-03, -1.5792901757e-03, 2.1726375791e-04, 1.7653955158e-03, 2.5554049165e-03, 2.3897382217e-03, 1.4211556881e-03, 6.4921935546e-05, -1.1719555546e-03, -1.8763709734e-03, -1.8630079096e-03, -1.2147116076e-03, -2.2481558671e-04, 7.2799464557e-04, 1.3210162624e-03, 1.3934897225e-03, 9.8371803137e-04, 2.9200492514e-04, -4.0893233116e-04, -8.7815597539e-04, -9.8656619314e-04, -7.4731044440e-04, -2.9193714506e-04, 1.9220436978e-04, 5.3576204832e-04, 6.4430392795e-04, 5.2013232626e-04, 2.4606492228e-04, -5.7330371892e-05, -2.8133052368e-04, -3.6604545253e-04, -3.1296479335e-04, -1.7230750533e-04, -1.4244728473e-05, 1.0203253711e-04, 1.4875133947e-04, 1.3306952296e-04, 8.5212216095e-05, 3.9029838255e-05, 1.4900403573e-05, 1.2475457050e-05, 1.5327191471e-05, 3.7618482978e-06, -3.1493984650e-05, -8.1941203532e-05, -1.2404753376e-04, -1.3076687946e-04, -8.6209631786e-05, 3.7908910630e-06, 1.1071751871e-04, 1.9320383872e-04, 2.1391598199e-04, 1.5635447302e-04, 3.4129098118e-05, -1.1182026094e-04, -2.2762585917e-04, -2.6716055532e-04, -2.1079107961e-04, -7.4520222202e-05, 9.4530201531e-05, 2.3497584277e-04, 2.9410546207e-04, 2.4810655924e-04, 1.1170007522e-04, -6.6689937029e-05, -2.2256165500e-04, -2.9916488047e-04, -2.6855336886e-04, -1.4193230722e-04, 3.4555670489e-05, 1.9695561615e-04, 2.8705580527e-04, 2.7356222115e-04, 1.6309186966e-04, -2.9017345509e-06, -1.6386926905e-04, -2.6251833556e-04, -2.6542975109e-04, -1.7444600564e-04, -2.4941664121e-05, 1.2798765460e-04, 2.2999478843e-04, 2.4694245575e-04, 1.7633944720e-04, 4.6928443366e-05, -9.2934134104e-05, -1.9342374961e-04, -2.2107906371e-04, -1.6991125582e-04, -6.2125794971e-05, 6.1270662098e-05, 1.5606818885e-04, 1.9071963279e-04, 1.5677318467e-04, 7.0455194291e-05, -3.4625933141e-05, -1.2049046521e-04, -1.5849588836e-04, -1.3880280100e-04, -7.2510875641e-05, 1.3781498407e-05, 8.8507777460e-05, 1.2662552441e-04, 1.1790595196e-04, 6.9321939920e-05, 1.1596087820e-06, -6.1246116434e-05, -9.6843895010e-05, -9.5857297703e-05, -6.2159982313e-05, -1.0613325355e-05, 3.9214909546e-05, 7.0371097114e-05, 7.4172234233e-05, 5.2357533492e-05, 1.5335680685e-05, -2.2431204012e-05, -4.7949938310e-05, -5.4056581743e-05, -4.1195968302e-05, -1.6294026764e-05, 1.0516808093e-05, 2.9875585364e-05, 3.6356227405e-05, 2.9788917181e-05, 1.4518712779e-05, -2.8350137599e-06, -1.6082598930e-05, -2.1573387839e-05, -1.9029472380e-05, -1.1004079038e-05, -1.3999300558e-06, 6.2280706793e-06, 9.8970858249e-06, 9.5597769186e-06, 6.6285446608e-06, 3.0196794545e-06, 2.1404336279e-07, -1.2613202098e-06, -1.7787125841e-06, -2.1143317814e-06, -2.8311981110e-06, -3.8783946363e-06, -4.6028386086e-06, -4.1464815041e-06, -2.0058806216e-06, 1.5482305844e-06, 5.4248153015e-06, 8.0928618642e-06, 8.2348658276e-06, 5.3827746410e-06, 2.3935387332e-07, -5.4841491162e-06, -9.6766597871e-06, -1.0649202562e-05, -7.8366295707e-06, -2.0841283602e-06, 4.6141546613e-06, 9.8373152541e-06, 1.1646532779e-05, 9.3279777293e-06, 3.6790473433e-06, -3.2759450427e-06, -9.0334291964e-06, -1.1536455496e-05, -9.9277893079e-06, -4.8491693605e-06, 1.8181526672e-06, 7.6640662304e-06, 1.0637326831e-05, 9.7774958316e-06, 5.5262501707e-06, -4.8199458599e-07, -6.0541412073e-06, -9.2484912704e-06, -9.0581314802e-06, -5.7251392145e-06, -5.8984164425e-07, 4.4461154951e-06, 7.6277789306e-06, 7.9608658936e-06, 5.5163795673e-06, 1.3358282157e-06, -3.0028313096e-06, -5.9799678791e-06, -6.6656492920e-06, -5.0023771924e-06, -1.7570418369e-06, 1.8150145648e-06, 4.4510966031e-06, 5.3243068872e-06, 4.2945533398e-06, 1.8951789437e-06, -9.1621545700e-07, -3.1326541017e-06, -4.0537458905e-06, -3.4986916001e-06, -1.8153799542e-06, 2.9671782990e-07, 2.0677893719e-06, 2.9326808171e-06, 2.7034505382e-06, 1.5902969896e-06, 8.1045970371e-08, -1.2616531622e-06, -2.0041416687e-06, -1.9748299670e-06, -1.2887872597e-06, -2.6932495334e-07, 6.9217855668e-07, 1.2805958992e-06, 1.3542946906e-06, 9.6792135313e-07, 3.2363684057e-07, -3.2135153633e-07, -7.5179544934e-07, -8.6118574256e-07, -6.6974601177e-07, -2.9540946982e-07, 1.0401511886e-07, 3.9210438758e-07, 4.9631671575e-07, 4.2020376983e-07, 2.2678122505e-07, 4.5912166862e-09, -1.6800994993e-07, -2.4726320140e-07, -2.3083384546e-07, -1.4852200249e-07, -4.3922671719e-08, 4.4144966037e-08, 9.3590856156e-08, 1.0168998967e-07, 7.9934220054e-08, 4.5256582454e-08, 1.2106227398e-08, -1.1732378562e-08, -2.5069790691e-08, -3.0470610650e-08, -3.0931374243e-08, -2.7914377238e-08, -2.1355862813e-08, -1.1032338549e-08, 1.9719648224e-09, 1.4790149581e-08, 2.3638357357e-08, 2.5521203789e-08, 1.9787522478e-08, 8.6416634255e-09}
144 | COEFFICIENT_WIDTH 24
145 | QUANTIZATION Quantize_Only
146 | BESTPRECISION true
147 | FILTER_TYPE Decimation
148 | RATE_CHANGE_TYPE Fixed_Fractional
149 | INTERPOLATION_RATE 2
150 | DECIMATION_RATE 5
151 | NUMBER_CHANNELS 16
152 | NUMBER_PATHS 1
153 | SAMPLE_FREQUENCY 0.96
154 | CLOCK_FREQUENCY 77.76
155 | OUTPUT_ROUNDING_MODE Convergent_Rounding_to_Even
156 | OUTPUT_WIDTH 35
157 | HAS_ARESETN true
158 | } {
159 | S_AXIS_DATA conv_0/M_AXIS
160 | aclk /pll_0/clk_out1
161 | aresetn /rst_0/peripheral_aresetn
162 | }
163 |
164 | # Create axis_subset_converter
165 | cell xilinx.com:ip:axis_subset_converter subset_0 {
166 | S_TDATA_NUM_BYTES.VALUE_SRC USER
167 | M_TDATA_NUM_BYTES.VALUE_SRC USER
168 | S_TDATA_NUM_BYTES 5
169 | M_TDATA_NUM_BYTES 4
170 | TDATA_REMAP {tdata[31:0]}
171 | } {
172 | S_AXIS fir_0/M_AXIS_DATA
173 | aclk /pll_0/clk_out1
174 | aresetn /rst_0/peripheral_aresetn
175 | }
176 |
177 | # Create floating_point
178 | cell xilinx.com:ip:floating_point fp_0 {
179 | OPERATION_TYPE Fixed_to_float
180 | A_PRECISION_TYPE.VALUE_SRC USER
181 | C_A_EXPONENT_WIDTH.VALUE_SRC USER
182 | C_A_FRACTION_WIDTH.VALUE_SRC USER
183 | A_PRECISION_TYPE Custom
184 | C_A_EXPONENT_WIDTH 2
185 | C_A_FRACTION_WIDTH 30
186 | RESULT_PRECISION_TYPE Single
187 | HAS_ARESETN true
188 | } {
189 | S_AXIS_A subset_0/M_AXIS
190 | aclk /pll_0/clk_out1
191 | aresetn /rst_0/peripheral_aresetn
192 | }
193 |
194 | # Create axis_dwidth_converter
195 | cell xilinx.com:ip:axis_dwidth_converter conv_1 {
196 | S_TDATA_NUM_BYTES.VALUE_SRC USER
197 | S_TDATA_NUM_BYTES 4
198 | M_TDATA_NUM_BYTES 64
199 | } {
200 | S_AXIS fp_0/M_AXIS_RESULT
201 | aclk /pll_0/clk_out1
202 | aresetn /rst_0/peripheral_aresetn
203 | }
204 |
205 | # Create axis_fifo
206 | cell pavel-demin:user:axis_fifo fifo_0 {
207 | S_AXIS_TDATA_WIDTH 512
208 | M_AXIS_TDATA_WIDTH 512
209 | WRITE_DEPTH 2048
210 | ALWAYS_READY TRUE
211 | } {
212 | S_AXIS conv_1/M_AXIS
213 | read_count hub_0/sts_data
214 | aclk /pll_0/clk_out1
215 | aresetn slice_0/dout
216 | }
217 |
218 | # Create axis_dwidth_converter
219 | cell xilinx.com:ip:axis_dwidth_converter conv_2 {
220 | S_TDATA_NUM_BYTES.VALUE_SRC USER
221 | S_TDATA_NUM_BYTES 64
222 | M_TDATA_NUM_BYTES 4
223 | } {
224 | S_AXIS fifo_0/M_AXIS
225 | M_AXIS hub_0/S00_AXIS
226 | aclk /pll_0/clk_out1
227 | aresetn slice_0/dout
228 | }
229 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_77_76/server/Makefile:
--------------------------------------------------------------------------------
1 | CFLAGS = -O3 -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=hard -D_GNU_SOURCE
2 |
3 | all: sdr-receiver
4 |
5 | sdr-receiver: sdr-receiver.c
6 | gcc $(CFLAGS) -o $@ $^ -lm
7 |
8 | clean:
9 | rm -f sdr-receiver
10 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_77_76/server/sdr-receiver.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #define TCP_PORT 1001
16 |
17 | struct control
18 | {
19 | int32_t inps, rate;
20 | int32_t freq[8];
21 | };
22 |
23 | const int rates[4] = {648, 324, 162, 81};
24 |
25 | int interrupted = 0;
26 |
27 | void signal_handler(int sig)
28 | {
29 | interrupted = 1;
30 | }
31 |
32 | int main(int argc, char *argv[])
33 | {
34 | int fd, i;
35 | int sock_server, sock_client;
36 | volatile void *cfg, *sts, *fifo;
37 | volatile uint8_t *rx_rst;
38 | volatile uint16_t *rx_rate, *rx_cntr;
39 | volatile uint32_t *rx_freq;
40 | struct sockaddr_in addr;
41 | struct control ctrl;
42 | uint32_t size, n;
43 | double integral;
44 | void *buffer;
45 | int yes = 1;
46 |
47 | if(argc != 2)
48 | {
49 | fprintf(stderr, "Usage: sdr-receiver interface\n");
50 | return EXIT_FAILURE;
51 | }
52 |
53 | if((buffer = malloc(65536)) == NULL)
54 | {
55 | perror("malloc");
56 | return EXIT_FAILURE;
57 | }
58 |
59 | if((fd = open("/dev/mem", O_RDWR)) < 0)
60 | {
61 | perror("open");
62 | return EXIT_FAILURE;
63 | }
64 |
65 | if(strcmp(argv[1], "eth0") == 0)
66 | {
67 | cfg = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x40000000);
68 | sts = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x41000000);
69 | fifo = mmap(NULL, 32*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x42000000);
70 | }
71 | else
72 | {
73 | cfg = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x80000000);
74 | sts = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x81000000);
75 | fifo = mmap(NULL, 32*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x82000000);
76 | }
77 |
78 | rx_rst = (uint8_t *)(cfg + 0);
79 | rx_rate = (uint16_t *)(cfg + 2);
80 | rx_freq = (uint32_t *)(cfg + 4);
81 |
82 | rx_cntr = (uint16_t *)(sts + 0);
83 |
84 | if((sock_server = socket(AF_INET, SOCK_STREAM, 0)) < 0)
85 | {
86 | perror("socket");
87 | return EXIT_FAILURE;
88 | }
89 |
90 | setsockopt(sock_server, SOL_SOCKET, SO_REUSEADDR, (void *)&yes , sizeof(yes));
91 |
92 | if(setsockopt(sock_server, SOL_SOCKET, SO_BINDTODEVICE, argv[1], strlen(argv[1]) + 1) < 0)
93 | {
94 | perror("SO_BINDTODEVICE");
95 | return EXIT_FAILURE;
96 | }
97 |
98 | /* setup listening address */
99 | memset(&addr, 0, sizeof(addr));
100 | addr.sin_family = AF_INET;
101 | addr.sin_addr.s_addr = htonl(INADDR_ANY);
102 | addr.sin_port = htons(TCP_PORT);
103 |
104 | if(bind(sock_server, (struct sockaddr *)&addr, sizeof(addr)) < 0)
105 | {
106 | perror("bind");
107 | return EXIT_FAILURE;
108 | }
109 |
110 | listen(sock_server, 1024);
111 |
112 | while(!interrupted)
113 | {
114 | *rx_rst &= ~1;
115 | *rx_rate = 648;
116 | for(i = 0; i < 8; ++i)
117 | {
118 | rx_freq[i] = (uint32_t)floor(1000000 / 77.76e6 * 0xffffffff + 0.5);
119 | }
120 |
121 | if((sock_client = accept(sock_server, NULL, NULL)) < 0)
122 | {
123 | perror("accept");
124 | return EXIT_FAILURE;
125 | }
126 |
127 | signal(SIGINT, signal_handler);
128 |
129 | *rx_rst |= 1;
130 |
131 | while(!interrupted)
132 | {
133 | if(ioctl(sock_client, FIONREAD, &size) < 0) break;
134 |
135 | if(size >= sizeof(struct control))
136 | {
137 | if(recv(sock_client, (char *)&ctrl, sizeof(struct control), MSG_WAITALL) < 0) break;
138 |
139 | /* set rx sample rate */
140 | *rx_rate = rates[ctrl.rate & 3];
141 |
142 | /* set rx phase increments */
143 | for(i = 0; i < 8; ++i)
144 | {
145 | rx_freq[i] = (uint32_t)floor(modf(ctrl.freq[i] / 77.76e6, &integral) * 0xffffffff + 0.5);
146 | }
147 | }
148 |
149 | if(*rx_cntr >= 2048)
150 | {
151 | *rx_rst &= ~1;
152 | *rx_rst |= 1;
153 | }
154 |
155 | if(*rx_cntr >= 1024)
156 | {
157 | memcpy(buffer, fifo, 65536);
158 | if(send(sock_client, buffer, 65536, MSG_NOSIGNAL) < 0) break;
159 | }
160 | else
161 | {
162 | usleep(500);
163 | }
164 | }
165 |
166 | signal(SIGINT, SIG_DFL);
167 | close(sock_client);
168 | }
169 |
170 | *rx_rst &= ~1;
171 |
172 | close(sock_server);
173 |
174 | return EXIT_SUCCESS;
175 | }
176 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_ft8_77_76/app/Makefile:
--------------------------------------------------------------------------------
1 | CFLAGS = -O3 -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=hard -ffast-math -fsingle-precision-constant -mvectorize-with-neon-quad
2 |
3 | all: write-c2-files upload-to-pskreporter
4 |
5 | write-c2-files: write-c2-files.c
6 | gcc $(CFLAGS) -o $@ $^ -lm -lconfig
7 |
8 | upload-to-pskreporter: upload-to-pskreporter.c
9 | gcc $(CFLAGS) -D_GNU_SOURCE -o $@ $^
10 |
11 | clean:
12 | rm -rf write-c2-files upload-to-pskreporter
13 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_ft8_77_76/app/decode-ft8.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | JOBS=4
4 | NICE=10
5 |
6 | DIR=`readlink -f $0`
7 | DIR=`dirname $DIR`
8 |
9 | RECORDER=$DIR/write-c2-files
10 | CONFIG=write-c2-files.cfg
11 |
12 | DECODER=/media/mmcblk0p1/apps/ft8d/ft8d
13 | ALLMEPT=ALL_FT8.TXT
14 |
15 | SLEEP=/media/mmcblk0p1/apps/common_tools/sleep-to-59
16 |
17 | date
18 |
19 | test $DIR/$CONFIG -ot $CONFIG || cp $DIR/$CONFIG $CONFIG
20 |
21 | echo "Sleeping ..."
22 |
23 | $SLEEP
24 |
25 | sleep 1
26 |
27 | date
28 | TIMESTAMP=`date --utc +'%y%m%d_%H%M'`
29 |
30 | echo "Recording ..."
31 |
32 | killall -q $RECORDER
33 | $RECORDER $CONFIG
34 |
35 | echo "Decoding ..."
36 |
37 | for file in ft8_*_$TIMESTAMP.c2
38 | do
39 | while [ `pgrep $DECODER | wc -l` -ge $JOBS ]
40 | do
41 | sleep 1
42 | done
43 | nice -n $NICE $DECODER $file &
44 | done > decodes_$TIMESTAMP.txt
45 |
46 | wait
47 |
48 | rm -f ft8_*_$TIMESTAMP.c2
49 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_ft8_77_76/app/ft8.cron:
--------------------------------------------------------------------------------
1 | * * * * * cd /dev/shm && /media/mmcblk0p1/apps/sdr_receiver_ft8_77_76/decode-ft8.sh >> decode-ft8.log 2>&1 &
2 | */6 * * * * cd /dev/shm && /media/mmcblk0p1/apps/sdr_receiver_ft8_77_76/upload-ft8.sh >> upload-ft8.log 2>&1 &
3 | #* * * * * cd /dev/shm && /media/mmcblk0p1/apps/common_tools/update-corr.sh 77.76 >> update-corr.log 2>&1 &
4 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_ft8_77_76/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Multiband FT8 receiver
6 |
7 |
8 |
9 |
10 |
19 |
20 |
Multiband FT8 receiver
21 |
The multiband FT8 receiver is ready.
22 |
More details about this application can be found at this link .
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_ft8_77_76/app/start.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | apps_dir=/media/mmcblk0p1/apps
4 |
5 | source $apps_dir/stop.sh
6 |
7 | if grep -q '
' $apps_dir/sdr_receiver_ft8_77_76/upload-ft8.sh
8 | then
9 | mount -o rw,remount /media/mmcblk0p1
10 | dos2unix $apps_dir/sdr_receiver_ft8_77_76/upload-ft8.sh
11 | mount -o ro,remount /media/mmcblk0p1
12 | fi
13 |
14 | rm -rf /dev/shm/*
15 |
16 | cat $apps_dir/sdr_receiver_ft8_77_76/sdr_receiver_ft8_77_76.bit > /dev/xdevcfg
17 |
18 | $apps_dir/common_tools/setup-adc
19 | $apps_dir/common_tools/enable-adc.sh
20 |
21 | ln -sf $apps_dir/sdr_receiver_ft8_77_76/ft8.cron /etc/cron.d/ft8_77_76
22 |
23 | service dcron restart
24 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_ft8_77_76/app/stop.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | if test -e /etc/cron.d/ft8_77_76
4 | then
5 | rm -f /etc/cron.d/ft8_77_76
6 | service dcron restart
7 | killall -q decode-ft8.sh sleep-to-59 write-c2-files ft8d
8 | killall -q upload-ft8.sh sleep-rand
9 | killall -q update-corr.sh measure-corr measure-level
10 | fi
11 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_ft8_77_76/app/upload-ft8.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # CALL and GRID should be specified to enable uploads
4 | CALL=
5 | GRID=
6 |
7 | # optional antenna description
8 | ANTENNA=""
9 |
10 | DIR=`readlink -f $0`
11 | DIR=`dirname $DIR`
12 |
13 | UPLOADER=$DIR/upload-to-pskreporter
14 |
15 | SLEEP=/media/mmcblk0p1/apps/common_tools/sleep-rand
16 |
17 | date
18 |
19 | echo "Sleeping ..."
20 |
21 | $SLEEP 60
22 |
23 | date
24 | TIMESTAMP=`date --utc +'%y%m%d_%H%M'`
25 |
26 | echo "Processing ..."
27 |
28 | REPORT=report_$TIMESTAMP.txt
29 |
30 | for file in `find . -name decodes_\*.txt -mmin +1`
31 | do
32 | cat $file >> $REPORT
33 | rm -f $file
34 | done
35 |
36 | test -f $REPORT || exit
37 |
38 | # sort by highest SNR, then print unique band/call combinations,
39 | # and then sort them by date/time/frequency
40 | sort -nr -k 4,4 $REPORT | awk '!seen[int($6/1e6)"_"$7]{print} {++seen[int($6/1e6)"_"$7]}' | sort -n -k 1,1 -k 2,2 -k 6,6 -o $REPORT
41 |
42 | test -n "$CALL" -a -n "$GRID" || exit
43 |
44 | echo "Uploading ..."
45 |
46 | $UPLOADER $CALL $GRID "$ANTENNA" $REPORT
47 |
48 | rm -f $REPORT
49 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_ft8_77_76/app/upload-to-pskreporter.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | const char name[] = "report.pskreporter.info";
12 | const char soft[] = "QMTECH FT8 RX 1.0";
13 |
14 | int32_t read_int(char **pointer, int32_t *value)
15 | {
16 | char *start = *pointer;
17 | *value = strtol(start, pointer, 10);
18 | return start != *pointer;
19 | }
20 |
21 | int32_t read_dbl(char **pointer, double *value)
22 | {
23 | char *start = *pointer;
24 | *value = strtod(start, pointer);
25 | return start != *pointer;
26 | }
27 |
28 | int32_t read_time(char **pointer, struct tm *value)
29 | {
30 | *pointer = strptime(*pointer, "%y%m%d %H%M%S", value);
31 | return *pointer != NULL;
32 | }
33 |
34 | void copy_char(char **pointer, const char *value)
35 | {
36 | int8_t size = strlen(value);
37 | memcpy(*pointer, &size, 1);
38 | *pointer += 1;
39 | memcpy(*pointer, value, size);
40 | *pointer += size;
41 | }
42 |
43 | void copy_int1(char **pointer, int8_t value)
44 | {
45 | memcpy(*pointer, &value, 1);
46 | *pointer += 1;
47 | }
48 |
49 | void copy_int2(char **pointer, int16_t value)
50 | {
51 | value = htons(value);
52 | memcpy(*pointer, &value, 2);
53 | *pointer += 2;
54 | }
55 |
56 | void copy_int4(char **pointer, int32_t value)
57 | {
58 | value = htonl(value);
59 | memcpy(*pointer, &value, 4);
60 | *pointer += 4;
61 | }
62 |
63 | int main(int argc, char *argv[])
64 | {
65 | FILE *fp;
66 | int sock;
67 | struct hostent *host;
68 | struct sockaddr_in addr;
69 | struct tm tm;
70 | struct timespec ts;
71 | double sync, dt;
72 | int32_t snr, freq, counter, rc, padding, sequence, size;
73 | char buffer[512], line[64], call[16], grid[8], *src, *dst, *start;
74 | char header[] =
75 | {
76 | 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 |
79 | 0x00, 0x03, 0x00, 0x2C, 0x99, 0x92, 0x00, 0x04,
80 | 0x00, 0x00,
81 | 0x80, 0x02, 0xFF, 0xFF, 0x00, 0x00, 0x76, 0x8F,
82 | 0x80, 0x04, 0xFF, 0xFF, 0x00, 0x00, 0x76, 0x8F,
83 | 0x80, 0x08, 0xFF, 0xFF, 0x00, 0x00, 0x76, 0x8F,
84 | 0x80, 0x09, 0xFF, 0xFF, 0x00, 0x00, 0x76, 0x8F,
85 | 0x00, 0x00,
86 |
87 | 0x00, 0x02, 0x00, 0x3C, 0x99, 0x93, 0x00, 0x07,
88 | 0x80, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x76, 0x8F,
89 | 0x80, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x76, 0x8F,
90 | 0x80, 0x05, 0x00, 0x04, 0x00, 0x00, 0x76, 0x8F,
91 | 0x80, 0x06, 0x00, 0x01, 0x00, 0x00, 0x76, 0x8F,
92 | 0x80, 0x0A, 0xFF, 0xFF, 0x00, 0x00, 0x76, 0x8F,
93 | 0x80, 0x0B, 0x00, 0x01, 0x00, 0x00, 0x76, 0x8F,
94 | 0x00, 0x96, 0x00, 0x04
95 | };
96 |
97 | if(argc != 5)
98 | {
99 | fprintf(stderr, "Usage: upload-to-pskreporter call grid antenna file\n");
100 | return EXIT_FAILURE;
101 | }
102 |
103 | if(strlen(argv[1]) > 16)
104 | {
105 | fprintf(stderr, "Call sign is too long.\n");
106 | return EXIT_FAILURE;
107 | }
108 |
109 | if(strlen(argv[2]) > 6)
110 | {
111 | fprintf(stderr, "Grid locator is too long.\n");
112 | return EXIT_FAILURE;
113 | }
114 |
115 | if(strlen(argv[3]) > 64)
116 | {
117 | fprintf(stderr, "Antenna description is too long.\n");
118 | return EXIT_FAILURE;
119 | }
120 |
121 | if((fp = fopen(argv[4], "r")) == NULL)
122 | {
123 | fprintf(stderr, "Cannot open input file.\n");
124 | return EXIT_FAILURE;
125 | }
126 |
127 | if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
128 | {
129 | fprintf(stderr, "Cannot open socket.\n");
130 | return EXIT_FAILURE;
131 | }
132 |
133 | if((host = gethostbyname(name)) == NULL)
134 | {
135 | fprintf(stderr, "Cannot find remote host address.\n");
136 | return EXIT_FAILURE;
137 | }
138 |
139 | memset(&addr, 0, sizeof(addr));
140 | addr.sin_family = AF_INET;
141 | memcpy(&addr.sin_addr.s_addr, host->h_addr, host->h_length);
142 | addr.sin_port = htons(4739);
143 |
144 | clock_gettime(CLOCK_REALTIME, &ts);
145 | srand(ts.tv_nsec / 1000);
146 |
147 | dst = header + 12;
148 | copy_int4(&dst, rand());
149 |
150 | memcpy(buffer, header, sizeof(header));
151 |
152 | start = buffer + sizeof(header);
153 |
154 | dst = start + 4;
155 | copy_char(&dst, argv[1]);
156 | copy_char(&dst, argv[2]);
157 | copy_char(&dst, soft);
158 | copy_char(&dst, argv[3]);
159 |
160 | size = dst - start;
161 | padding = (4 - size % 4) % 4;
162 | size += padding;
163 | memset(dst, 0, padding);
164 |
165 | dst = start;
166 | copy_int2(&dst, 0x9992);
167 | copy_int2(&dst, size);
168 |
169 | start += size;
170 |
171 | counter = 0;
172 | sequence = 0;
173 | dst = start + 4;
174 | for(;;)
175 | {
176 | src = fgets(line, 64, fp);
177 |
178 | if(src != NULL)
179 | {
180 | call[0] = 0;
181 | grid[0] = 0;
182 | rc = read_time(&src, &tm)
183 | && read_dbl(&src, &sync)
184 | && read_int(&src, &snr)
185 | && read_dbl(&src, &dt)
186 | && read_int(&src, &freq)
187 | && sscanf(src, "%13s %4s", call, grid);
188 |
189 | if(!rc) continue;
190 |
191 | copy_char(&dst, call);
192 | copy_char(&dst, grid);
193 | copy_int4(&dst, freq);
194 | copy_int1(&dst, snr);
195 | copy_char(&dst, "FT8");
196 | copy_int1(&dst, 1);
197 | copy_int4(&dst, timegm(&tm) + 15);
198 |
199 | ++counter;
200 |
201 | if(counter < 10) continue;
202 | }
203 |
204 | if(counter > 0)
205 | {
206 | size = dst - start;
207 | padding = (4 - size % 4) % 4;
208 | size += padding;
209 | memset(dst, 0, padding);
210 |
211 | dst = start;
212 | copy_int2(&dst, 0x9993);
213 | copy_int2(&dst, size);
214 |
215 | dst = buffer + 2;
216 | size += start - buffer;
217 | copy_int2(&dst, size);
218 | copy_int4(&dst, time(NULL));
219 | copy_int4(&dst, sequence);
220 |
221 | sendto(sock, buffer, size, 0, (struct sockaddr *)&addr, sizeof(addr));
222 |
223 | counter = 0;
224 | ++sequence;
225 | dst = start + 4;
226 | }
227 |
228 | if(src == NULL) break;
229 | }
230 |
231 | return EXIT_SUCCESS;
232 | }
233 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_ft8_77_76/app/write-c2-files.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | int main(int argc, char *argv[])
13 | {
14 | FILE *fp;
15 | int fd, offset, length, i, j;
16 | time_t t;
17 | struct tm *gmt;
18 | volatile void *cfg, *sts;
19 | volatile uint64_t *fifo;
20 | volatile uint8_t *rst;
21 | volatile uint16_t *sel, *cntr;
22 | uint64_t *buffer;
23 | config_t config;
24 | config_setting_t *setting, *element;
25 | char date[12];
26 | char name[64];
27 | double corr, dialfreq, integral;
28 | double freq[16] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
29 |
30 | if(argc != 2)
31 | {
32 | fprintf(stderr, "Usage: write-c2-files config_file.cfg\n");
33 | return EXIT_FAILURE;
34 | }
35 |
36 | config_init(&config);
37 |
38 | if(!config_read_file(&config, argv[1]))
39 | {
40 | fprintf(stderr, "Error on line %d in configuration file.\n", config_error_line(&config));
41 | return EXIT_FAILURE;
42 | }
43 |
44 | if(!config_lookup_float(&config, "corr", &corr))
45 | {
46 | fprintf(stderr, "No 'corr' setting in configuration file.\n");
47 | return EXIT_FAILURE;
48 | }
49 |
50 | if(corr < -100.0 || corr > 100.0)
51 | {
52 | fprintf(stderr, "Wrong 'corr' setting in configuration file.\n");
53 | return EXIT_FAILURE;
54 | }
55 |
56 | setting = config_lookup(&config, "bands");
57 | if(setting == NULL)
58 | {
59 | fprintf(stderr, "No 'bands' setting in configuration file.\n");
60 | return EXIT_FAILURE;
61 | }
62 |
63 | length = config_setting_length(setting);
64 |
65 | if(length > 16)
66 | {
67 | fprintf(stderr, "More than 16 bands in configuration file.\n");
68 | return EXIT_FAILURE;
69 | }
70 |
71 | if(length < 1)
72 | {
73 | fprintf(stderr, "Less than 1 band in configuration file.\n");
74 | return EXIT_FAILURE;
75 | }
76 |
77 | for(i = 0; i < length; ++i)
78 | {
79 | element = config_setting_get_elem(setting, i);
80 |
81 | if(!config_setting_lookup_float(element, "freq", &freq[i]))
82 | {
83 | fprintf(stderr, "No 'freq' setting in element %d.\n", i);
84 | return EXIT_FAILURE;
85 | }
86 | }
87 |
88 | t = time(NULL);
89 | if((gmt = gmtime(&t)) == NULL)
90 | {
91 | fprintf(stderr, "Cannot convert time.\n");
92 | return EXIT_FAILURE;
93 | }
94 |
95 | if((fd = open("/dev/mem", O_RDWR)) < 0)
96 | {
97 | fprintf(stderr, "Cannot open /dev/mem.\n");
98 | return EXIT_FAILURE;
99 | }
100 |
101 | cfg = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x40000000);
102 | sts = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x41000000);
103 | fifo = mmap(NULL, 32*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x42000000);
104 |
105 | for(i = 0; i < 16; ++i)
106 | {
107 | *(uint32_t *)(cfg + 4 + i * 4) = (uint32_t)floor(modf((1.0 + 1.0e-6 * corr) * freq[i] / 77.76, &integral) * 0xffffffff + 0.5);
108 | }
109 |
110 | rst = (uint8_t *)(cfg + 0);
111 | cntr = (uint16_t *)(sts + 0);
112 |
113 | *rst &= ~1;
114 | *rst |= 1;
115 |
116 | offset = 0;
117 | buffer = malloc(240000 * 8 * 16);
118 | memset(buffer, 0, 240000 * 8 * 16);
119 |
120 | while(offset < 236000)
121 | {
122 | while(*cntr < 500) usleep(10000);
123 |
124 | for(i = 0; i < 250; ++i)
125 | {
126 | for(j = 0; j < 16; ++j)
127 | {
128 | buffer[j * 240000 + offset + i] = *fifo;
129 | }
130 | }
131 |
132 | offset += 250;
133 | }
134 |
135 | for(i = 0; i < length; ++i)
136 | {
137 | dialfreq = freq[i] * 1.0e6;
138 | strftime(date, 12, "%y%m%d_%H%M", gmt);
139 | sprintf(name, "ft8_%d_%d_%s.c2", i, (uint32_t)dialfreq, date);
140 | if((fp = fopen(name, "wb")) == NULL)
141 | {
142 | fprintf(stderr, "Cannot open output file %s.\n", name);
143 | return EXIT_FAILURE;
144 | }
145 | fwrite(&dialfreq, 1, 8, fp);
146 | fwrite(&buffer[i * 240000], 1, 240000 * 8, fp);
147 | fclose(fp);
148 | }
149 |
150 | return EXIT_SUCCESS;
151 | }
152 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_ft8_77_76/app/write-c2-files.cfg:
--------------------------------------------------------------------------------
1 | // frequency correction, from -100.0 ppm to +100.0 ppm
2 | corr = 0.0;
3 |
4 | // comma separated list of bands
5 | // trailing commas are not allowed
6 | bands = (
7 | { freq = 1.841500; },
8 | { freq = 3.574500; },
9 | { freq = 5.358500; },
10 | { freq = 7.075500; },
11 | { freq = 10.137500; },
12 | { freq = 14.075500; },
13 | { freq = 18.101500; },
14 | { freq = 21.075500; },
15 | { freq = 24.916500; },
16 | { freq = 28.075500; },
17 | { freq = 50.314500; }
18 | );
19 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_ft8_77_76/block_design.tcl:
--------------------------------------------------------------------------------
1 | # Create ports
2 | create_bd_port -dir I adc_clk_p_i
3 | create_bd_port -dir I adc_clk_n_i
4 |
5 | create_bd_port -dir I adc_ovr_p_i
6 | create_bd_port -dir I adc_ovr_n_i
7 |
8 | create_bd_port -dir I -from 6 -to 0 adc_dat_p_i
9 | create_bd_port -dir I -from 6 -to 0 adc_dat_n_i
10 |
11 | create_bd_port -dir O adc_spi_sclk
12 | create_bd_port -dir O adc_spi_sdio
13 | create_bd_port -dir O adc_spi_cs
14 |
15 | create_bd_port -dir O adc_oe
16 |
17 | # Create xlconstant
18 | cell xilinx.com:ip:xlconstant const_0
19 |
20 | # Create clk_wiz
21 | cell xilinx.com:ip:clk_wiz pll_0 {
22 | PRIMITIVE PLL
23 | PRIM_IN_FREQ.VALUE_SRC USER
24 | PRIM_IN_FREQ 77.76
25 | PRIM_SOURCE Differential_clock_capable_pin
26 | CLKOUT1_USED true
27 | CLKOUT1_REQUESTED_OUT_FREQ 77.76
28 | USE_RESET false
29 | } {
30 | clk_in1_p adc_clk_p_i
31 | clk_in1_n adc_clk_n_i
32 | }
33 |
34 | # Create processing_system7
35 | cell xilinx.com:ip:processing_system7 ps_0 {
36 | PCW_IMPORT_BOARD_PRESET cfg/qmtech_xc7z020.xml
37 | PCW_USE_M_AXI_GP1 1
38 | } {
39 | M_AXI_GP0_ACLK pll_0/clk_out1
40 | M_AXI_GP1_ACLK pll_0/clk_out1
41 | SPI0_SCLK_O adc_spi_sclk
42 | SPI0_MOSI_O adc_spi_sdio
43 | SPI0_SS_I const_0/dout
44 | SPI0_SS_O adc_spi_cs
45 | }
46 |
47 | # Create port_slicer
48 | cell pavel-demin:user:port_slicer slice_0 {
49 | DIN_WIDTH 64 DIN_FROM 1 DIN_TO 1
50 | } {
51 | din ps_0/GPIO_O
52 | dout adc_oe
53 | }
54 |
55 | # Create all required interconnections
56 | apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {
57 | make_external {FIXED_IO, DDR}
58 | Master Disable
59 | Slave Disable
60 | } [get_bd_cells ps_0]
61 |
62 | # Create proc_sys_reset
63 | cell xilinx.com:ip:proc_sys_reset rst_0 {} {
64 | ext_reset_in const_0/dout
65 | dcm_locked pll_0/locked
66 | slowest_sync_clk pll_0/clk_out1
67 | }
68 |
69 | # ADC
70 |
71 | # Create util_ds_buf
72 | cell xilinx.com:ip:util_ds_buf buf_0 {
73 | C_SIZE 7
74 | C_BUF_TYPE IBUFDS
75 | } {
76 | IBUF_DS_P adc_dat_p_i
77 | IBUF_DS_N adc_dat_n_i
78 | }
79 |
80 | # Create axis_adc_ddr
81 | cell pavel-demin:user:axis_adc_ddr adc_0 {
82 | ADC_DATA_WIDTH 7
83 | } {
84 | aclk pll_0/clk_out1
85 | adc_data buf_0/IBUF_OUT
86 | }
87 |
88 | # HUB
89 |
90 | # Create axi_hub
91 | cell pavel-demin:user:axi_hub hub_0 {
92 | CFG_DATA_WIDTH 544
93 | STS_DATA_WIDTH 32
94 | } {
95 | S_AXI ps_0/M_AXI_GP0
96 | aclk pll_0/clk_out1
97 | aresetn rst_0/peripheral_aresetn
98 | }
99 |
100 | # RX 0
101 |
102 | # Create port_slicer
103 | cell pavel-demin:user:port_slicer rst_slice_0 {
104 | DIN_WIDTH 544 DIN_FROM 7 DIN_TO 0
105 | } {
106 | din hub_0/cfg_data
107 | }
108 |
109 | # Create port_slicer
110 | cell pavel-demin:user:port_slicer cfg_slice_0 {
111 | DIN_WIDTH 544 DIN_FROM 543 DIN_TO 32
112 | } {
113 | din hub_0/cfg_data
114 | }
115 |
116 | module rx_0 {
117 | source projects/sdr_receiver_ft8_77_76/rx.tcl
118 | } {
119 | slice_0/din rst_slice_0/dout
120 | slice_1/din cfg_slice_0/dout
121 | slice_2/din cfg_slice_0/dout
122 | slice_3/din cfg_slice_0/dout
123 | slice_4/din cfg_slice_0/dout
124 | slice_5/din cfg_slice_0/dout
125 | slice_6/din cfg_slice_0/dout
126 | slice_7/din cfg_slice_0/dout
127 | slice_8/din cfg_slice_0/dout
128 | slice_9/din cfg_slice_0/dout
129 | slice_10/din cfg_slice_0/dout
130 | slice_11/din cfg_slice_0/dout
131 | slice_12/din cfg_slice_0/dout
132 | slice_13/din cfg_slice_0/dout
133 | slice_14/din cfg_slice_0/dout
134 | slice_15/din cfg_slice_0/dout
135 | slice_16/din cfg_slice_0/dout
136 | fifo_0/read_count hub_0/sts_data
137 | conv_2/M_AXIS hub_0/S00_AXIS
138 | }
139 |
140 | # PPS and level measurement
141 |
142 | module common_0 {
143 | source projects/common_tools/block_design.tcl
144 | }
145 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_ft8_77_76/filters/rx_fir_0.r:
--------------------------------------------------------------------------------
1 | library(signal)
2 |
3 | # CIC filter parameters
4 | R <- 120 # Decimation factor
5 | M <- 1 # Differential delay
6 | N <- 6 # Number of stages
7 |
8 | Fc <- 0.247 # cutoff frequency
9 | htbw <- 0.005 # half transition bandwidth
10 |
11 | # fir2 parameters
12 | k <- kaiserord(c(Fc-htbw, Fc+htbw), c(1, 0), 1/(2^16), 1)
13 | L <- k$n # Filter order
14 | Beta <- k$beta # Kaiser window parameter
15 |
16 | # FIR filter design using fir2
17 | s <- 0.001 # Step size
18 | fp <- seq(0.0, Fc-htbw, by=s) # Pass band frequency samples
19 | fs <- seq(Fc+htbw, 0.5, by=s) # Stop band frequency samples
20 | f <- c(fp, fs)*2 # Normalized frequency samples; 0<=f<=1
21 |
22 | Mp <- matrix(1, 1, length(fp)) # Pass band response; Mp[1]=1
23 | Mp[-1] <- abs(M*R*sin(pi*fp[-1]/R)/sin(pi*M*fp[-1]))^N
24 | Mf <- c(Mp, matrix(0, 1, length(fs)))
25 |
26 | h <- fir2(L, f, Mf, window=kaiser(L+1, Beta))
27 |
28 | h <- h / sum(h)
29 |
30 | # Print filter coefficients
31 | paste(sprintf("%.10e", h), collapse=", ")
32 |
33 | fh <- freqz(h)
34 |
35 | op <- par(mfrow = c(2, 1))
36 |
37 | plot(f, 20*log10(Mf), type = "b", ylab = "dB", xlab = "Frequency", xlim = c(0.51, 0.54), ylim = c(-125, 5))
38 | lines(fh$f / pi, 20*log10(abs(fh$h)), col = "blue")
39 | grid()
40 |
41 | plot(f, 20*log10(Mf), type = "b", ylab = "dB", xlab = "Frequency", xlim = c(0.46, 0.49), ylim = c(-5, 5))
42 | lines(fh$f / pi, 20*log10(abs(fh$h)), col = "blue")
43 | grid()
44 |
45 | par(op)
46 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_ft8_77_76/ports.xdc:
--------------------------------------------------------------------------------
1 | # clock
2 |
3 | set_property IOSTANDARD LVDS_25 [get_ports adc_clk_p_i]
4 | set_property IOSTANDARD LVDS_25 [get_ports adc_clk_n_i]
5 |
6 | set_property DIFF_TERM TRUE [get_ports adc_clk_p_i]
7 | set_property DIFF_TERM TRUE [get_ports adc_clk_n_i]
8 |
9 | set_property PACKAGE_PIN Y19 [get_ports adc_clk_p_i]
10 | set_property PACKAGE_PIN AA19 [get_ports adc_clk_n_i]
11 |
12 | # overrange
13 |
14 | set_property IOSTANDARD LVDS_25 [get_ports {adc_ovr_p_i}]
15 | set_property IOSTANDARD LVDS_25 [get_ports {adc_ovr_n_i}]
16 |
17 | set_property DIFF_TERM TRUE [get_ports {adc_ovr_p_i]}]
18 | set_property DIFF_TERM TRUE [get_ports {adc_ovr_n_i}]
19 |
20 | set_property PACKAGE_PIN U17 [get_ports {adc_ovr_p_i}]
21 | set_property PACKAGE_PIN V17 [get_ports {adc_ovr_n_i}]
22 |
23 | # data
24 |
25 | set_property IOSTANDARD LVDS_25 [get_ports {adc_dat_p_i[*]}]
26 | set_property IOSTANDARD LVDS_25 [get_ports {adc_dat_n_i[*]}]
27 |
28 | set_property DIFF_TERM TRUE [get_ports {adc_dat_p_i[*]}]
29 | set_property DIFF_TERM TRUE [get_ports {adc_dat_n_i[*]}]
30 |
31 | set_property PACKAGE_PIN AA17 [get_ports {adc_dat_p_i[0]}]
32 | set_property PACKAGE_PIN AB17 [get_ports {adc_dat_n_i[0]}]
33 |
34 | set_property PACKAGE_PIN AA16 [get_ports {adc_dat_p_i[1]}]
35 | set_property PACKAGE_PIN AB16 [get_ports {adc_dat_n_i[1]}]
36 |
37 | set_property PACKAGE_PIN AB14 [get_ports {adc_dat_p_i[2]}]
38 | set_property PACKAGE_PIN AB15 [get_ports {adc_dat_n_i[2]}]
39 |
40 | set_property PACKAGE_PIN Y18 [get_ports {adc_dat_p_i[3]}]
41 | set_property PACKAGE_PIN AA18 [get_ports {adc_dat_n_i[3]}]
42 |
43 | set_property PACKAGE_PIN W17 [get_ports {adc_dat_p_i[4]}]
44 | set_property PACKAGE_PIN W18 [get_ports {adc_dat_n_i[4]}]
45 |
46 | set_property PACKAGE_PIN W16 [get_ports {adc_dat_p_i[5]}]
47 | set_property PACKAGE_PIN Y16 [get_ports {adc_dat_n_i[5]}]
48 |
49 | set_property PACKAGE_PIN Y14 [get_ports {adc_dat_p_i[6]}]
50 | set_property PACKAGE_PIN AA14 [get_ports {adc_dat_n_i[6]}]
51 |
52 | # SPI
53 |
54 | set_property IOSTANDARD LVCMOS25 [get_ports adc_spi_*]
55 |
56 | set_property PACKAGE_PIN AA13 [get_ports adc_spi_sclk]
57 | set_property PACKAGE_PIN Y13 [get_ports adc_spi_sdio]
58 | set_property PACKAGE_PIN U15 [get_ports adc_spi_cs]
59 |
60 | # output enable
61 |
62 | set_property IOSTANDARD LVCMOS25 [get_ports adc_oe]
63 |
64 | set_property PACKAGE_PIN Y20 [get_ports adc_oe]
65 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_hpsdr_77_76/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SDR receiver compatible with HPSDR
6 |
7 |
8 |
9 |
10 |
19 |
20 |
SDR receiver compatible with HPSDR
21 |
The SDR receiver compatible with HPSDR is ready.
22 |
Now you can run the SDR programs that support the HPSDR /Metis protocol.
23 |
More details about this application can be found at this link .
24 |
SDR programs
25 |
Here is a list of the SDR programs that are known to work with this SDR receiver:
26 |
33 |
Running CW Skimmer Server
34 |
35 | Install CW Skimmer Server .
36 | Copy HermesIntf.dll to the CW Skimmer Server program directory (C:\Program Files (x86)\Afreet\SkimSrv).
37 | In the SkimSrv
directory, rename HermesIntf.dll
to HermestIntf_XXXX.dll
where XXXX
are the last four digits of the MAC address of the QMTECH XC7Z020 board.
38 | Make a copy of the SkimSrv
directory and rename the copy to SkimSrv2
.
39 | In the SkimSrv2
directory, rename SkimSrv.exe
to SkimSrv2.exe
and rename HermestIntf_XXXX.dll
to HermestIntf_FFXX.dll
.
40 | Install Reverse Beacon Network Aggregator .
41 | Start SkimSrv.exe
and SkimSrv2.exe
, configure frequencies and your call sign.
42 | Start Reverse Beacon Network Aggregator.
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_hpsdr_77_76/app/start.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | apps_dir=/media/mmcblk0p1/apps
4 |
5 | source $apps_dir/stop.sh
6 |
7 | cat $apps_dir/sdr_receiver_hpsdr_77_76/sdr_receiver_hpsdr_77_76.bit > /dev/xdevcfg
8 |
9 | $apps_dir/common_tools/setup-adc
10 | $apps_dir/common_tools/enable-adc.sh
11 |
12 | address=`awk -F : '$5="FF"' OFS=: /sys/class/net/eth0/address`
13 |
14 | echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
15 | echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
16 | echo 2 > /proc/sys/net/ipv4/conf/all/rp_filter
17 |
18 | ip link add mvl0 link eth0 address $address type macvlan mode passthru
19 |
20 | $apps_dir/sdr_receiver_hpsdr_77_76/sdr-receiver-hpsdr eth0 &
21 | $apps_dir/sdr_receiver_hpsdr_77_76/sdr-receiver-hpsdr mvl0 &
22 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_hpsdr_77_76/app/stop.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | killall -q sdr-receiver-hpsdr
4 |
5 | ip link del mvl0
6 |
7 | echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
8 | echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
9 | echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
10 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_hpsdr_77_76/block_design.tcl:
--------------------------------------------------------------------------------
1 | # Create ports
2 | create_bd_port -dir I adc_clk_p_i
3 | create_bd_port -dir I adc_clk_n_i
4 |
5 | create_bd_port -dir I adc_ovr_p_i
6 | create_bd_port -dir I adc_ovr_n_i
7 |
8 | create_bd_port -dir I -from 6 -to 0 adc_dat_p_i
9 | create_bd_port -dir I -from 6 -to 0 adc_dat_n_i
10 |
11 | create_bd_port -dir O adc_spi_sclk
12 | create_bd_port -dir O adc_spi_sdio
13 | create_bd_port -dir O adc_spi_cs
14 |
15 | create_bd_port -dir O adc_oe
16 |
17 | # Create xlconstant
18 | cell xilinx.com:ip:xlconstant const_0
19 |
20 | # Create clk_wiz
21 | cell xilinx.com:ip:clk_wiz pll_0 {
22 | PRIMITIVE PLL
23 | PRIM_IN_FREQ.VALUE_SRC USER
24 | PRIM_IN_FREQ 77.76
25 | PRIM_SOURCE Differential_clock_capable_pin
26 | CLKOUT1_USED true
27 | CLKOUT1_REQUESTED_OUT_FREQ 77.76
28 | USE_RESET false
29 | } {
30 | clk_in1_p adc_clk_p_i
31 | clk_in1_n adc_clk_n_i
32 | }
33 |
34 | # Create processing_system7
35 | cell xilinx.com:ip:processing_system7 ps_0 {
36 | PCW_IMPORT_BOARD_PRESET cfg/qmtech_xc7z020.xml
37 | PCW_USE_M_AXI_GP1 1
38 | } {
39 | M_AXI_GP0_ACLK pll_0/clk_out1
40 | M_AXI_GP1_ACLK pll_0/clk_out1
41 | SPI0_SCLK_O adc_spi_sclk
42 | SPI0_MOSI_O adc_spi_sdio
43 | SPI0_SS_I const_0/dout
44 | SPI0_SS_O adc_spi_cs
45 | }
46 |
47 | # Create port_slicer
48 | cell pavel-demin:user:port_slicer slice_0 {
49 | DIN_WIDTH 64 DIN_FROM 1 DIN_TO 1
50 | } {
51 | din ps_0/GPIO_O
52 | dout adc_oe
53 | }
54 |
55 | # Create all required interconnections
56 | apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {
57 | make_external {FIXED_IO, DDR}
58 | Master Disable
59 | Slave Disable
60 | } [get_bd_cells ps_0]
61 |
62 | # Create proc_sys_reset
63 | cell xilinx.com:ip:proc_sys_reset rst_0 {} {
64 | ext_reset_in const_0/dout
65 | dcm_locked pll_0/locked
66 | slowest_sync_clk pll_0/clk_out1
67 | }
68 |
69 | # ADC
70 |
71 | # Create util_ds_buf
72 | cell xilinx.com:ip:util_ds_buf buf_0 {
73 | C_SIZE 7
74 | C_BUF_TYPE IBUFDS
75 | } {
76 | IBUF_DS_P adc_dat_p_i
77 | IBUF_DS_N adc_dat_n_i
78 | }
79 |
80 | # Create axis_adc_ddr
81 | cell pavel-demin:user:axis_adc_ddr adc_0 {
82 | ADC_DATA_WIDTH 7
83 | } {
84 | aclk pll_0/clk_out1
85 | adc_data buf_0/IBUF_OUT
86 | }
87 |
88 | # RX 0
89 |
90 | module rx_0 {
91 | source projects/sdr_receiver_hpsdr_77_76/rx.tcl
92 | } {
93 | hub_0/S_AXI ps_0/M_AXI_GP0
94 | }
95 |
96 | # RX 1
97 |
98 | module rx_1 {
99 | source projects/sdr_receiver_hpsdr_77_76/rx.tcl
100 | } {
101 | hub_0/S_AXI ps_0/M_AXI_GP1
102 | }
103 |
104 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_hpsdr_77_76/filters/rx_fir_0.r:
--------------------------------------------------------------------------------
1 | library(signal)
2 |
3 | # CIC filter parameters
4 | R <- 81 # Decimation factor
5 | M <- 1 # Differential delay
6 | N <- 6 # Number of stages
7 |
8 | Fc <- 0.097 # cutoff frequency
9 | htbw <- 0.005 # half transition bandwidth
10 |
11 | # fir2 parameters
12 | k <- kaiserord(c(Fc-htbw, Fc+htbw), c(1, 0), 1/(2^16), 1)
13 | L <- k$n # Filter order
14 | Beta <- k$beta # Kaiser window parameter
15 |
16 | # FIR filter design using fir2
17 | s <- 0.001 # Step size
18 | fp <- seq(0.0, Fc-htbw, by=s) # Pass band frequency samples
19 | fs <- seq(Fc+htbw, 0.5, by=s) # Stop band frequency samples
20 | f <- c(fp, fs)*2 # Normalized frequency samples; 0<=f<=1
21 |
22 | Mp <- matrix(1, 1, length(fp)) # Pass band response; Mp[1]=1
23 | Mp[-1] <- abs(M*R*sin(pi*fp[-1]*2/R)/sin(pi*M*fp[-1]*2))^N
24 | Mf <- c(Mp, matrix(0, 1, length(fs)))
25 |
26 | h <- fir2(L, f, Mf, window=kaiser(L+1, Beta))
27 |
28 | h <- h / sum(h)
29 |
30 | # Print filter coefficients
31 | paste(sprintf("%.10e", h), collapse=", ")
32 |
33 | fh <- freqz(h)
34 |
35 | op <- par(mfrow = c(2, 1))
36 |
37 | plot(f, 20*log10(Mf), type = "b", ylab = "dB", xlab = "Frequency", xlim = c(0.20, 0.22), ylim = c(-125, 5))
38 | lines(fh$f / pi, 20*log10(abs(fh$h)), col = "blue")
39 | grid()
40 |
41 | plot(f, 20*log10(Mf), type = "b", ylab = "dB", xlab = "Frequency", xlim = c(0.18, 0.20), ylim = c(-5, 5))
42 | lines(fh$f / pi, 20*log10(abs(fh$h)), col = "blue")
43 | grid()
44 |
45 | par(op)
46 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_hpsdr_77_76/ports.xdc:
--------------------------------------------------------------------------------
1 | # clock
2 |
3 | set_property IOSTANDARD LVDS_25 [get_ports adc_clk_p_i]
4 | set_property IOSTANDARD LVDS_25 [get_ports adc_clk_n_i]
5 |
6 | set_property DIFF_TERM TRUE [get_ports adc_clk_p_i]
7 | set_property DIFF_TERM TRUE [get_ports adc_clk_n_i]
8 |
9 | set_property PACKAGE_PIN Y19 [get_ports adc_clk_p_i]
10 | set_property PACKAGE_PIN AA19 [get_ports adc_clk_n_i]
11 |
12 | # overrange
13 |
14 | set_property IOSTANDARD LVDS_25 [get_ports {adc_ovr_p_i}]
15 | set_property IOSTANDARD LVDS_25 [get_ports {adc_ovr_n_i}]
16 |
17 | set_property DIFF_TERM TRUE [get_ports {adc_ovr_p_i]}]
18 | set_property DIFF_TERM TRUE [get_ports {adc_ovr_n_i}]
19 |
20 | set_property PACKAGE_PIN U17 [get_ports {adc_ovr_p_i}]
21 | set_property PACKAGE_PIN V17 [get_ports {adc_ovr_n_i}]
22 |
23 | # data
24 |
25 | set_property IOSTANDARD LVDS_25 [get_ports {adc_dat_p_i[*]}]
26 | set_property IOSTANDARD LVDS_25 [get_ports {adc_dat_n_i[*]}]
27 |
28 | set_property DIFF_TERM TRUE [get_ports {adc_dat_p_i[*]}]
29 | set_property DIFF_TERM TRUE [get_ports {adc_dat_n_i[*]}]
30 |
31 | set_property PACKAGE_PIN AA17 [get_ports {adc_dat_p_i[0]}]
32 | set_property PACKAGE_PIN AB17 [get_ports {adc_dat_n_i[0]}]
33 |
34 | set_property PACKAGE_PIN AA16 [get_ports {adc_dat_p_i[1]}]
35 | set_property PACKAGE_PIN AB16 [get_ports {adc_dat_n_i[1]}]
36 |
37 | set_property PACKAGE_PIN AB14 [get_ports {adc_dat_p_i[2]}]
38 | set_property PACKAGE_PIN AB15 [get_ports {adc_dat_n_i[2]}]
39 |
40 | set_property PACKAGE_PIN Y18 [get_ports {adc_dat_p_i[3]}]
41 | set_property PACKAGE_PIN AA18 [get_ports {adc_dat_n_i[3]}]
42 |
43 | set_property PACKAGE_PIN W17 [get_ports {adc_dat_p_i[4]}]
44 | set_property PACKAGE_PIN W18 [get_ports {adc_dat_n_i[4]}]
45 |
46 | set_property PACKAGE_PIN W16 [get_ports {adc_dat_p_i[5]}]
47 | set_property PACKAGE_PIN Y16 [get_ports {adc_dat_n_i[5]}]
48 |
49 | set_property PACKAGE_PIN Y14 [get_ports {adc_dat_p_i[6]}]
50 | set_property PACKAGE_PIN AA14 [get_ports {adc_dat_n_i[6]}]
51 |
52 | # SPI
53 |
54 | set_property IOSTANDARD LVCMOS25 [get_ports adc_spi_*]
55 |
56 | set_property PACKAGE_PIN AA13 [get_ports adc_spi_sclk]
57 | set_property PACKAGE_PIN Y13 [get_ports adc_spi_sdio]
58 | set_property PACKAGE_PIN U15 [get_ports adc_spi_cs]
59 |
60 | # output enable
61 |
62 | set_property IOSTANDARD LVCMOS25 [get_ports adc_oe]
63 |
64 | set_property PACKAGE_PIN Y20 [get_ports adc_oe]
65 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_hpsdr_77_76/rx.tcl:
--------------------------------------------------------------------------------
1 | # Create axi_hub
2 | cell pavel-demin:user:axi_hub hub_0 {
3 | CFG_DATA_WIDTH 288
4 | STS_DATA_WIDTH 32
5 | } {
6 | aclk /pll_0/clk_out1
7 | aresetn /rst_0/peripheral_aresetn
8 | }
9 |
10 | # Create port_slicer
11 | cell pavel-demin:user:port_slicer slice_0 {
12 | DIN_WIDTH 288 DIN_FROM 0 DIN_TO 0
13 | } {
14 | din hub_0/cfg_data
15 | }
16 |
17 | # Create port_slicer
18 | cell pavel-demin:user:port_slicer slice_1 {
19 | DIN_WIDTH 288 DIN_FROM 31 DIN_TO 16
20 | } {
21 | din hub_0/cfg_data
22 | }
23 |
24 | for {set i 0} {$i <= 7} {incr i} {
25 |
26 | # Create port_slicer
27 | cell pavel-demin:user:port_slicer slice_[expr $i + 2] {
28 | DIN_WIDTH 288 DIN_FROM [expr 32 * $i + 63] DIN_TO [expr 32 * $i + 32]
29 | } {
30 | din hub_0/cfg_data
31 | }
32 |
33 | # Create dds
34 | cell pavel-demin:user:dds dds_$i {
35 | NEGATIVE_SINE TRUE
36 | } {
37 | pinc slice_[expr $i + 2]/dout
38 | aclk /pll_0/clk_out1
39 | aresetn /rst_0/peripheral_aresetn
40 | }
41 |
42 | }
43 |
44 | # Create xlconstant
45 | cell xilinx.com:ip:xlconstant const_0
46 |
47 | for {set i 0} {$i <= 15} {incr i} {
48 |
49 | # Create port_slicer
50 | cell pavel-demin:user:port_slicer dds_slice_$i {
51 | DIN_WIDTH 48 DIN_FROM [expr 24 * ($i % 2) + 23] DIN_TO [expr 24 * ($i % 2)]
52 | } {
53 | din dds_[expr $i / 2]/dout
54 | }
55 |
56 | # Create dsp48
57 | cell pavel-demin:user:dsp48 mult_$i {
58 | A_WIDTH 24
59 | B_WIDTH 14
60 | P_WIDTH 24
61 | } {
62 | A dds_slice_$i/dout
63 | B /adc_0/m_axis_tdata
64 | CLK /pll_0/clk_out1
65 | }
66 |
67 | # Create axis_variable
68 | cell pavel-demin:user:axis_variable rate_$i {
69 | AXIS_TDATA_WIDTH 16
70 | } {
71 | cfg_data slice_1/dout
72 | aclk /pll_0/clk_out1
73 | aresetn /rst_0/peripheral_aresetn
74 | }
75 |
76 | # Create cic_compiler
77 | cell xilinx.com:ip:cic_compiler cic_$i {
78 | INPUT_DATA_WIDTH.VALUE_SRC USER
79 | FILTER_TYPE Decimation
80 | NUMBER_OF_STAGES 6
81 | SAMPLE_RATE_CHANGES Programmable
82 | MINIMUM_RATE 81
83 | MAXIMUM_RATE 1296
84 | FIXED_OR_INITIAL_RATE 648
85 | INPUT_SAMPLE_FREQUENCY 77.76
86 | CLOCK_FREQUENCY 77.76
87 | INPUT_DATA_WIDTH 24
88 | QUANTIZATION Truncation
89 | OUTPUT_DATA_WIDTH 32
90 | USE_XTREME_DSP_SLICE false
91 | HAS_ARESETN true
92 | } {
93 | s_axis_data_tdata mult_$i/P
94 | s_axis_data_tvalid const_0/dout
95 | S_AXIS_CONFIG rate_$i/M_AXIS
96 | aclk /pll_0/clk_out1
97 | aresetn /rst_0/peripheral_aresetn
98 | }
99 |
100 | }
101 |
102 | # Create axis_combiner
103 | cell xilinx.com:ip:axis_combiner comb_0 {
104 | TDATA_NUM_BYTES.VALUE_SRC USER
105 | TDATA_NUM_BYTES 4
106 | NUM_SI 16
107 | } {
108 | S00_AXIS cic_0/M_AXIS_DATA
109 | S01_AXIS cic_1/M_AXIS_DATA
110 | S02_AXIS cic_2/M_AXIS_DATA
111 | S03_AXIS cic_3/M_AXIS_DATA
112 | S04_AXIS cic_4/M_AXIS_DATA
113 | S05_AXIS cic_5/M_AXIS_DATA
114 | S06_AXIS cic_6/M_AXIS_DATA
115 | S07_AXIS cic_7/M_AXIS_DATA
116 | S08_AXIS cic_8/M_AXIS_DATA
117 | S09_AXIS cic_9/M_AXIS_DATA
118 | S10_AXIS cic_10/M_AXIS_DATA
119 | S11_AXIS cic_11/M_AXIS_DATA
120 | S12_AXIS cic_12/M_AXIS_DATA
121 | S13_AXIS cic_13/M_AXIS_DATA
122 | S14_AXIS cic_14/M_AXIS_DATA
123 | S15_AXIS cic_15/M_AXIS_DATA
124 | aclk /pll_0/clk_out1
125 | aresetn /rst_0/peripheral_aresetn
126 | }
127 |
128 | # Create axis_dwidth_converter
129 | cell xilinx.com:ip:axis_dwidth_converter conv_0 {
130 | S_TDATA_NUM_BYTES.VALUE_SRC USER
131 | S_TDATA_NUM_BYTES 64
132 | M_TDATA_NUM_BYTES 4
133 | } {
134 | S_AXIS comb_0/M_AXIS
135 | aclk /pll_0/clk_out1
136 | aresetn /rst_0/peripheral_aresetn
137 | }
138 |
139 | # Create fir_compiler
140 | cell xilinx.com:ip:fir_compiler fir_0 {
141 | DATA_WIDTH.VALUE_SRC USER
142 | DATA_WIDTH 32
143 | COEFFICIENTVECTOR {8.6416634255e-09, 1.9787522479e-08, 2.5521203789e-08, 2.3638357357e-08, 1.4790149581e-08, 1.9719648224e-09, -1.1032338549e-08, -2.1355862813e-08, -2.7914377238e-08, -3.0931374243e-08, -3.0470610650e-08, -2.5069790691e-08, -1.1732378562e-08, 1.2106227398e-08, 4.5256582454e-08, 7.9934220054e-08, 1.0168998967e-07, 9.3590856156e-08, 4.4144966037e-08, -4.3922671719e-08, -1.4852200249e-07, -2.3083384546e-07, -2.4726320140e-07, -1.6800994993e-07, 4.5912166862e-09, 2.2678122505e-07, 4.2020376983e-07, 4.9631671575e-07, 3.9210438758e-07, 1.0401511886e-07, -2.9540946982e-07, -6.6974601177e-07, -8.6118574256e-07, -7.5179544934e-07, -3.2135153633e-07, 3.2363684057e-07, 9.6792135313e-07, 1.3542946906e-06, 1.2805958992e-06, 6.9217855668e-07, -2.6932495334e-07, -1.2887872597e-06, -1.9748299670e-06, -2.0041416687e-06, -1.2616531622e-06, 8.1045970371e-08, 1.5902969896e-06, 2.7034505382e-06, 2.9326808171e-06, 2.0677893719e-06, 2.9671782990e-07, -1.8153799542e-06, -3.4986916001e-06, -4.0537458905e-06, -3.1326541017e-06, -9.1621545700e-07, 1.8951789437e-06, 4.2945533398e-06, 5.3243068872e-06, 4.4510966031e-06, 1.8150145648e-06, -1.7570418369e-06, -5.0023771924e-06, -6.6656492920e-06, -5.9799678791e-06, -3.0028313096e-06, 1.3358282157e-06, 5.5163795673e-06, 7.9608658936e-06, 7.6277789306e-06, 4.4461154951e-06, -5.8984164425e-07, -5.7251392145e-06, -9.0581314802e-06, -9.2484912704e-06, -6.0541412073e-06, -4.8199458599e-07, 5.5262501707e-06, 9.7774958316e-06, 1.0637326831e-05, 7.6640662304e-06, 1.8181526672e-06, -4.8491693605e-06, -9.9277893079e-06, -1.1536455496e-05, -9.0334291964e-06, -3.2759450427e-06, 3.6790473433e-06, 9.3279777293e-06, 1.1646532779e-05, 9.8373152541e-06, 4.6141546613e-06, -2.0841283602e-06, -7.8366295707e-06, -1.0649202562e-05, -9.6766597871e-06, -5.4841491162e-06, 2.3935387332e-07, 5.3827746410e-06, 8.2348658276e-06, 8.0928618642e-06, 5.4248153015e-06, 1.5482305844e-06, -2.0058806216e-06, -4.1464815041e-06, -4.6028386086e-06, -3.8783946363e-06, -2.8311981110e-06, -2.1143317814e-06, -1.7787125841e-06, -1.2613202098e-06, 2.1404336279e-07, 3.0196794545e-06, 6.6285446608e-06, 9.5597769186e-06, 9.8970858249e-06, 6.2280706793e-06, -1.3999300558e-06, -1.1004079038e-05, -1.9029472380e-05, -2.1573387839e-05, -1.6082598930e-05, -2.8350137599e-06, 1.4518712779e-05, 2.9788917181e-05, 3.6356227405e-05, 2.9875585364e-05, 1.0516808093e-05, -1.6294026764e-05, -4.1195968302e-05, -5.4056581743e-05, -4.7949938310e-05, -2.2431204012e-05, 1.5335680685e-05, 5.2357533492e-05, 7.4172234233e-05, 7.0371097114e-05, 3.9214909546e-05, -1.0613325355e-05, -6.2159982313e-05, -9.5857297703e-05, -9.6843895010e-05, -6.1246116434e-05, 1.1596087820e-06, 6.9321939920e-05, 1.1790595196e-04, 1.2662552441e-04, 8.8507777460e-05, 1.3781498407e-05, -7.2510875641e-05, -1.3880280100e-04, -1.5849588836e-04, -1.2049046521e-04, -3.4625933141e-05, 7.0455194291e-05, 1.5677318467e-04, 1.9071963279e-04, 1.5606818885e-04, 6.1270662098e-05, -6.2125794971e-05, -1.6991125582e-04, -2.2107906371e-04, -1.9342374961e-04, -9.2934134104e-05, 4.6928443366e-05, 1.7633944720e-04, 2.4694245575e-04, 2.2999478843e-04, 1.2798765460e-04, -2.4941664121e-05, -1.7444600564e-04, -2.6542975109e-04, -2.6251833556e-04, -1.6386926905e-04, -2.9017345509e-06, 1.6309186966e-04, 2.7356222115e-04, 2.8705580527e-04, 1.9695561615e-04, 3.4555670489e-05, -1.4193230722e-04, -2.6855336886e-04, -2.9916488047e-04, -2.2256165500e-04, -6.6689937029e-05, 1.1170007522e-04, 2.4810655924e-04, 2.9410546207e-04, 2.3497584277e-04, 9.4530201531e-05, -7.4520222202e-05, -2.1079107961e-04, -2.6716055532e-04, -2.2762585917e-04, -1.1182026094e-04, 3.4129098118e-05, 1.5635447302e-04, 2.1391598199e-04, 1.9320383872e-04, 1.1071751871e-04, 3.7908910630e-06, -8.6209631786e-05, -1.3076687946e-04, -1.2404753376e-04, -8.1941203532e-05, -3.1493984650e-05, 3.7618482978e-06, 1.5327191471e-05, 1.2475457050e-05, 1.4900403573e-05, 3.9029838255e-05, 8.5212216095e-05, 1.3306952296e-04, 1.4875133947e-04, 1.0203253711e-04, -1.4244728473e-05, -1.7230750533e-04, -3.1296479335e-04, -3.6604545253e-04, -2.8133052368e-04, -5.7330371892e-05, 2.4606492228e-04, 5.2013232626e-04, 6.4430392795e-04, 5.3576204832e-04, 1.9220436978e-04, -2.9193714506e-04, -7.4731044440e-04, -9.8656619314e-04, -8.7815597539e-04, -4.0893233116e-04, 2.9200492514e-04, 9.8371803137e-04, 1.3934897225e-03, 1.3210162624e-03, 7.2799464557e-04, -2.2481558671e-04, -1.2147116076e-03, -1.8630079096e-03, -1.8763709734e-03, -1.1719555546e-03, 6.4921935546e-05, 1.4211556881e-03, 2.3897382217e-03, 2.5554049165e-03, 1.7653955158e-03, 2.1726375791e-04, -1.5792901757e-03, -2.9651397494e-03, -3.3691024975e-03, -2.5360356113e-03, -6.5682663411e-04, 1.6595757982e-03, 3.5770214428e-03, 4.3286963968e-03, 3.5160483017e-03, 1.2960357442e-03, -1.6254062809e-03, -4.2094376163e-03, -5.4471917717e-03, -4.7450324797e-03, -2.1878913494e-03, 1.4303547141e-03, 4.8420974952e-03, 6.7417004048e-03, 6.2749186441e-03, 3.4019773004e-03, -1.0139113090e-03, -5.4502911147e-03, -8.2390953251e-03, -8.1808578202e-03, -5.0376756147e-03, 2.9071387529e-04, 6.0016792136e-03, 9.9836955649e-03, 1.0579354406e-02, 7.2475257605e-03, 8.6880057823e-04, -6.4514589167e-03, -1.2054494720e-02, -1.3667770498e-02, -1.0289159644e-02, -2.6835541906e-03, 6.7274828446e-03, 1.4599435427e-02, 1.7811581265e-02, 1.4646249040e-02, 5.5728291554e-03, -6.6881265746e-03, -1.7916290000e-02, -2.3770141281e-02, -2.1362115622e-02, -1.0487921502e-02, 5.9634682621e-03, 2.2652378162e-02, 3.3374547837e-02, 3.3147252075e-02, 2.0139686562e-02, -3.2170050718e-03, -3.0392681085e-02, -5.2269158542e-02, -5.9644704750e-02, -4.6033325214e-02, -9.9174346067e-03, 4.4272248035e-02, 1.0682708940e-01, 1.6497706887e-01, 2.0608084740e-01, 2.2090784056e-01, 2.0608084740e-01, 1.6497706887e-01, 1.0682708940e-01, 4.4272248035e-02, -9.9174346067e-03, -4.6033325214e-02, -5.9644704750e-02, -5.2269158542e-02, -3.0392681085e-02, -3.2170050718e-03, 2.0139686562e-02, 3.3147252075e-02, 3.3374547837e-02, 2.2652378162e-02, 5.9634682621e-03, -1.0487921502e-02, -2.1362115622e-02, -2.3770141281e-02, -1.7916290000e-02, -6.6881265746e-03, 5.5728291554e-03, 1.4646249040e-02, 1.7811581265e-02, 1.4599435427e-02, 6.7274828446e-03, -2.6835541906e-03, -1.0289159644e-02, -1.3667770498e-02, -1.2054494720e-02, -6.4514589167e-03, 8.6880057823e-04, 7.2475257605e-03, 1.0579354406e-02, 9.9836955649e-03, 6.0016792136e-03, 2.9071387529e-04, -5.0376756147e-03, -8.1808578202e-03, -8.2390953251e-03, -5.4502911147e-03, -1.0139113090e-03, 3.4019773004e-03, 6.2749186441e-03, 6.7417004048e-03, 4.8420974952e-03, 1.4303547141e-03, -2.1878913494e-03, -4.7450324797e-03, -5.4471917717e-03, -4.2094376163e-03, -1.6254062809e-03, 1.2960357442e-03, 3.5160483017e-03, 4.3286963968e-03, 3.5770214428e-03, 1.6595757982e-03, -6.5682663411e-04, -2.5360356113e-03, -3.3691024975e-03, -2.9651397494e-03, -1.5792901757e-03, 2.1726375791e-04, 1.7653955158e-03, 2.5554049165e-03, 2.3897382217e-03, 1.4211556881e-03, 6.4921935546e-05, -1.1719555546e-03, -1.8763709734e-03, -1.8630079096e-03, -1.2147116076e-03, -2.2481558671e-04, 7.2799464557e-04, 1.3210162624e-03, 1.3934897225e-03, 9.8371803137e-04, 2.9200492514e-04, -4.0893233116e-04, -8.7815597539e-04, -9.8656619314e-04, -7.4731044440e-04, -2.9193714506e-04, 1.9220436978e-04, 5.3576204832e-04, 6.4430392795e-04, 5.2013232626e-04, 2.4606492228e-04, -5.7330371892e-05, -2.8133052368e-04, -3.6604545253e-04, -3.1296479335e-04, -1.7230750533e-04, -1.4244728473e-05, 1.0203253711e-04, 1.4875133947e-04, 1.3306952296e-04, 8.5212216095e-05, 3.9029838255e-05, 1.4900403573e-05, 1.2475457050e-05, 1.5327191471e-05, 3.7618482978e-06, -3.1493984650e-05, -8.1941203532e-05, -1.2404753376e-04, -1.3076687946e-04, -8.6209631786e-05, 3.7908910630e-06, 1.1071751871e-04, 1.9320383872e-04, 2.1391598199e-04, 1.5635447302e-04, 3.4129098118e-05, -1.1182026094e-04, -2.2762585917e-04, -2.6716055532e-04, -2.1079107961e-04, -7.4520222202e-05, 9.4530201531e-05, 2.3497584277e-04, 2.9410546207e-04, 2.4810655924e-04, 1.1170007522e-04, -6.6689937029e-05, -2.2256165500e-04, -2.9916488047e-04, -2.6855336886e-04, -1.4193230722e-04, 3.4555670489e-05, 1.9695561615e-04, 2.8705580527e-04, 2.7356222115e-04, 1.6309186966e-04, -2.9017345509e-06, -1.6386926905e-04, -2.6251833556e-04, -2.6542975109e-04, -1.7444600564e-04, -2.4941664121e-05, 1.2798765460e-04, 2.2999478843e-04, 2.4694245575e-04, 1.7633944720e-04, 4.6928443366e-05, -9.2934134104e-05, -1.9342374961e-04, -2.2107906371e-04, -1.6991125582e-04, -6.2125794971e-05, 6.1270662098e-05, 1.5606818885e-04, 1.9071963279e-04, 1.5677318467e-04, 7.0455194291e-05, -3.4625933141e-05, -1.2049046521e-04, -1.5849588836e-04, -1.3880280100e-04, -7.2510875641e-05, 1.3781498407e-05, 8.8507777460e-05, 1.2662552441e-04, 1.1790595196e-04, 6.9321939920e-05, 1.1596087820e-06, -6.1246116434e-05, -9.6843895010e-05, -9.5857297703e-05, -6.2159982313e-05, -1.0613325355e-05, 3.9214909546e-05, 7.0371097114e-05, 7.4172234233e-05, 5.2357533492e-05, 1.5335680685e-05, -2.2431204012e-05, -4.7949938310e-05, -5.4056581743e-05, -4.1195968302e-05, -1.6294026764e-05, 1.0516808093e-05, 2.9875585364e-05, 3.6356227405e-05, 2.9788917181e-05, 1.4518712779e-05, -2.8350137599e-06, -1.6082598930e-05, -2.1573387839e-05, -1.9029472380e-05, -1.1004079038e-05, -1.3999300558e-06, 6.2280706793e-06, 9.8970858249e-06, 9.5597769186e-06, 6.6285446608e-06, 3.0196794545e-06, 2.1404336279e-07, -1.2613202098e-06, -1.7787125841e-06, -2.1143317814e-06, -2.8311981110e-06, -3.8783946363e-06, -4.6028386086e-06, -4.1464815041e-06, -2.0058806216e-06, 1.5482305844e-06, 5.4248153015e-06, 8.0928618642e-06, 8.2348658276e-06, 5.3827746410e-06, 2.3935387332e-07, -5.4841491162e-06, -9.6766597871e-06, -1.0649202562e-05, -7.8366295707e-06, -2.0841283602e-06, 4.6141546613e-06, 9.8373152541e-06, 1.1646532779e-05, 9.3279777293e-06, 3.6790473433e-06, -3.2759450427e-06, -9.0334291964e-06, -1.1536455496e-05, -9.9277893079e-06, -4.8491693605e-06, 1.8181526672e-06, 7.6640662304e-06, 1.0637326831e-05, 9.7774958316e-06, 5.5262501707e-06, -4.8199458599e-07, -6.0541412073e-06, -9.2484912704e-06, -9.0581314802e-06, -5.7251392145e-06, -5.8984164425e-07, 4.4461154951e-06, 7.6277789306e-06, 7.9608658936e-06, 5.5163795673e-06, 1.3358282157e-06, -3.0028313096e-06, -5.9799678791e-06, -6.6656492920e-06, -5.0023771924e-06, -1.7570418369e-06, 1.8150145648e-06, 4.4510966031e-06, 5.3243068872e-06, 4.2945533398e-06, 1.8951789437e-06, -9.1621545700e-07, -3.1326541017e-06, -4.0537458905e-06, -3.4986916001e-06, -1.8153799542e-06, 2.9671782990e-07, 2.0677893719e-06, 2.9326808171e-06, 2.7034505382e-06, 1.5902969896e-06, 8.1045970371e-08, -1.2616531622e-06, -2.0041416687e-06, -1.9748299670e-06, -1.2887872597e-06, -2.6932495334e-07, 6.9217855668e-07, 1.2805958992e-06, 1.3542946906e-06, 9.6792135313e-07, 3.2363684057e-07, -3.2135153633e-07, -7.5179544934e-07, -8.6118574256e-07, -6.6974601177e-07, -2.9540946982e-07, 1.0401511886e-07, 3.9210438758e-07, 4.9631671575e-07, 4.2020376983e-07, 2.2678122505e-07, 4.5912166862e-09, -1.6800994993e-07, -2.4726320140e-07, -2.3083384546e-07, -1.4852200249e-07, -4.3922671719e-08, 4.4144966037e-08, 9.3590856156e-08, 1.0168998967e-07, 7.9934220054e-08, 4.5256582454e-08, 1.2106227398e-08, -1.1732378562e-08, -2.5069790691e-08, -3.0470610650e-08, -3.0931374243e-08, -2.7914377238e-08, -2.1355862813e-08, -1.1032338549e-08, 1.9719648224e-09, 1.4790149581e-08, 2.3638357357e-08, 2.5521203789e-08, 1.9787522478e-08, 8.6416634255e-09}
144 | COEFFICIENT_WIDTH 24
145 | QUANTIZATION Quantize_Only
146 | BESTPRECISION true
147 | FILTER_TYPE Decimation
148 | RATE_CHANGE_TYPE Fixed_Fractional
149 | INTERPOLATION_RATE 2
150 | DECIMATION_RATE 5
151 | NUMBER_CHANNELS 16
152 | NUMBER_PATHS 1
153 | SAMPLE_FREQUENCY 0.96
154 | CLOCK_FREQUENCY 77.76
155 | OUTPUT_ROUNDING_MODE Convergent_Rounding_to_Even
156 | OUTPUT_WIDTH 27
157 | HAS_ARESETN true
158 | } {
159 | S_AXIS_DATA conv_0/M_AXIS
160 | aclk /pll_0/clk_out1
161 | aresetn /rst_0/peripheral_aresetn
162 | }
163 |
164 | # Create axis_dwidth_converter
165 | cell xilinx.com:ip:axis_dwidth_converter conv_1 {
166 | S_TDATA_NUM_BYTES.VALUE_SRC USER
167 | S_TDATA_NUM_BYTES 4
168 | M_TDATA_NUM_BYTES 64
169 | } {
170 | S_AXIS fir_0/M_AXIS_DATA
171 | aclk /pll_0/clk_out1
172 | aresetn /rst_0/peripheral_aresetn
173 | }
174 |
175 | # Create axis_subset_converter
176 | cell xilinx.com:ip:axis_subset_converter subset_0 {
177 | S_TDATA_NUM_BYTES.VALUE_SRC USER
178 | M_TDATA_NUM_BYTES.VALUE_SRC USER
179 | S_TDATA_NUM_BYTES 64
180 | M_TDATA_NUM_BYTES 48
181 | TDATA_REMAP {tdata[455:448],tdata[463:456],tdata[471:464],tdata[487:480],tdata[495:488],tdata[503:496],tdata[391:384],tdata[399:392],tdata[407:400],tdata[423:416],tdata[431:424],tdata[439:432],tdata[327:320],tdata[335:328],tdata[343:336],tdata[359:352],tdata[367:360],tdata[375:368],tdata[263:256],tdata[271:264],tdata[279:272],tdata[295:288],tdata[303:296],tdata[311:304],tdata[199:192],tdata[207:200],tdata[215:208],tdata[231:224],tdata[239:232],tdata[247:240],tdata[135:128],tdata[143:136],tdata[151:144],tdata[167:160],tdata[175:168],tdata[183:176],tdata[71:64],tdata[79:72],tdata[87:80],tdata[103:96],tdata[111:104],tdata[119:112],tdata[7:0],tdata[15:8],tdata[23:16],tdata[39:32],tdata[47:40],tdata[55:48]}
182 | } {
183 | S_AXIS conv_1/M_AXIS
184 | aclk /pll_0/clk_out1
185 | aresetn /rst_0/peripheral_aresetn
186 | }
187 |
188 | # Create axis_fifo
189 | cell pavel-demin:user:axis_fifo fifo_0 {
190 | S_AXIS_TDATA_WIDTH 384
191 | M_AXIS_TDATA_WIDTH 384
192 | WRITE_DEPTH 2048
193 | ALWAYS_READY TRUE
194 | } {
195 | S_AXIS subset_0/M_AXIS
196 | read_count hub_0/sts_data
197 | aclk /pll_0/clk_out1
198 | aresetn slice_0/dout
199 | }
200 |
201 | # Create axis_dwidth_converter
202 | cell xilinx.com:ip:axis_dwidth_converter conv_2 {
203 | S_TDATA_NUM_BYTES.VALUE_SRC USER
204 | S_TDATA_NUM_BYTES 48
205 | M_TDATA_NUM_BYTES 4
206 | } {
207 | S_AXIS fifo_0/M_AXIS
208 | M_AXIS hub_0/S00_AXIS
209 | aclk /pll_0/clk_out1
210 | aresetn slice_0/dout
211 | }
212 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_hpsdr_77_76/server/Makefile:
--------------------------------------------------------------------------------
1 | CFLAGS = -O3 -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=hard -D_GNU_SOURCE
2 |
3 | all: sdr-receiver-hpsdr
4 |
5 | sdr-receiver-hpsdr: sdr-receiver-hpsdr.c
6 | gcc $(CFLAGS) -o $@ $^ -lm -lpthread
7 |
8 | clean:
9 | rm -f sdr-receiver-hpsdr
10 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_hpsdr_77_76/server/sdr-receiver-hpsdr.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | volatile uint32_t *rx_freq;
19 | volatile uint16_t *rx_rate, *rx_cntr;
20 | volatile uint8_t *rx_rst;
21 | volatile uint8_t *rx_data;
22 |
23 | int receivers = 1;
24 |
25 | int sock_ep2;
26 | struct sockaddr_in addr_ep6;
27 |
28 | int enable_thread = 0;
29 | int active_thread = 0;
30 |
31 | void process_ep2(uint8_t *frame);
32 | void *handler_ep6(void *arg);
33 |
34 | int main(int argc, char *argv[])
35 | {
36 | int fd, i;
37 | ssize_t size;
38 | pthread_t thread;
39 | volatile void *cfg, *sts;
40 | uint8_t buffer[1032];
41 | uint8_t reply[20] = {0xef, 0xfe, 2, 0, 0, 0, 0, 0, 0, 25, 1, 'R', '_', 'P', 'I', 'T', 'A', 'Y', 'A', 8};
42 | uint32_t code;
43 | struct ifreq hwaddr;
44 | struct sockaddr_in addr_ep2, addr_from;
45 | socklen_t size_from;
46 | int yes = 1;
47 |
48 | if(argc != 2)
49 | {
50 | fprintf(stderr, "Usage: sdr-receiver-hpsdr interface\n");
51 | return EXIT_FAILURE;
52 | }
53 |
54 | if((fd = open("/dev/mem", O_RDWR)) < 0)
55 | {
56 | perror("open");
57 | return EXIT_FAILURE;
58 | }
59 |
60 | if(strcmp(argv[1], "eth0") == 0)
61 | {
62 | cfg = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x40000000);
63 | sts = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x41000000);
64 | rx_data = mmap(NULL, 32*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x42000000);
65 | }
66 | else
67 | {
68 | cfg = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x80000000);
69 | sts = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x81000000);
70 | rx_data = mmap(NULL, 32*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x82000000);
71 | }
72 |
73 | rx_rst = (uint8_t *)(cfg + 0);
74 | rx_rate = (uint16_t *)(cfg + 2);
75 | rx_freq = (uint32_t *)(cfg + 4);
76 |
77 | rx_cntr = (uint16_t *)(sts + 0);
78 |
79 | /* set default rx phase increment */
80 | for(i = 0; i < 8; ++i)
81 | {
82 | rx_freq[i] = (uint32_t)floor(1000000 / 77.76e6 * 0xffffffff + 0.5);
83 | }
84 |
85 | /* set default rx sample rate */
86 | *rx_rate = 648;
87 |
88 | if((sock_ep2 = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
89 | {
90 | perror("socket");
91 | return EXIT_FAILURE;
92 | }
93 |
94 | memset(&hwaddr, 0, sizeof(hwaddr));
95 | strncpy(hwaddr.ifr_name, argv[1], IFNAMSIZ - 1);
96 | ioctl(sock_ep2, SIOCGIFHWADDR, &hwaddr);
97 | for(i = 0; i < 6; ++i) reply[i + 3] = hwaddr.ifr_addr.sa_data[i];
98 |
99 | setsockopt(sock_ep2, SOL_SOCKET, SO_REUSEADDR, (void *)&yes , sizeof(yes));
100 |
101 | if(setsockopt(sock_ep2, SOL_SOCKET, SO_BINDTODEVICE, argv[1], strlen(argv[1]) + 1) < 0)
102 | {
103 | perror("SO_BINDTODEVICE");
104 | return EXIT_FAILURE;
105 | }
106 |
107 | memset(&addr_ep2, 0, sizeof(addr_ep2));
108 | addr_ep2.sin_family = AF_INET;
109 | addr_ep2.sin_addr.s_addr = htonl(INADDR_ANY);
110 | addr_ep2.sin_port = htons(1024);
111 |
112 | if(bind(sock_ep2, (struct sockaddr *)&addr_ep2, sizeof(addr_ep2)) < 0)
113 | {
114 | perror("bind");
115 | return EXIT_FAILURE;
116 | }
117 |
118 | while(1)
119 | {
120 | size_from = sizeof(addr_from);
121 | size = recvfrom(sock_ep2, buffer, 1032, 0, (struct sockaddr *)&addr_from, &size_from);
122 | if(size < 0)
123 | {
124 | perror("recvfrom");
125 | return EXIT_FAILURE;
126 | }
127 |
128 | memcpy(&code, buffer, 4);
129 | switch(code)
130 | {
131 | case 0x0201feef:
132 | process_ep2(buffer + 11);
133 | process_ep2(buffer + 523);
134 | break;
135 | case 0x0002feef:
136 | reply[2] = 2 + active_thread;
137 | memset(buffer, 0, 60);
138 | memcpy(buffer, reply, 20);
139 | sendto(sock_ep2, buffer, 60, 0, (struct sockaddr *)&addr_from, size_from);
140 | break;
141 | case 0x0004feef:
142 | enable_thread = 0;
143 | while(active_thread) usleep(1000);
144 | break;
145 | case 0x0104feef:
146 | case 0x0204feef:
147 | case 0x0304feef:
148 | enable_thread = 0;
149 | while(active_thread) usleep(1000);
150 | memset(&addr_ep6, 0, sizeof(addr_ep6));
151 | addr_ep6.sin_family = AF_INET;
152 | addr_ep6.sin_addr.s_addr = addr_from.sin_addr.s_addr;
153 | addr_ep6.sin_port = addr_from.sin_port;
154 | enable_thread = 1;
155 | active_thread = 1;
156 | if(pthread_create(&thread, NULL, handler_ep6, NULL) < 0)
157 | {
158 | perror("pthread_create");
159 | return EXIT_FAILURE;
160 | }
161 | pthread_detach(thread);
162 | break;
163 | }
164 | }
165 |
166 | close(sock_ep2);
167 |
168 | return EXIT_SUCCESS;
169 | }
170 |
171 | void process_ep2(uint8_t *frame)
172 | {
173 | uint32_t freq;
174 | double integral;
175 |
176 | switch(frame[0])
177 | {
178 | case 0:
179 | case 1:
180 | receivers = ((frame[4] >> 3) & 7) + 1;
181 |
182 | /* set rx sample rate */
183 | switch(frame[1] & 3)
184 | {
185 | case 0:
186 | *rx_rate = 648;
187 | break;
188 | case 1:
189 | *rx_rate = 324;
190 | break;
191 | case 2:
192 | *rx_rate = 162;
193 | break;
194 | case 3:
195 | *rx_rate = 81;
196 | break;
197 | }
198 | break;
199 | case 4:
200 | case 5:
201 | /* set rx phase increment */
202 | freq = ntohl(*(uint32_t *)(frame + 1));
203 | rx_freq[0] = (uint32_t)floor(modf(freq / 77.76e6, &integral) * 0xffffffff + 0.5);
204 | break;
205 | case 6:
206 | case 7:
207 | /* set rx phase increment */
208 | freq = ntohl(*(uint32_t *)(frame + 1));
209 | rx_freq[1] = (uint32_t)floor(modf(freq / 77.76e6, &integral) * 0xffffffff + 0.5);
210 | break;
211 | case 8:
212 | case 9:
213 | /* set rx phase increment */
214 | freq = ntohl(*(uint32_t *)(frame + 1));
215 | rx_freq[2] = (uint32_t)floor(modf(freq / 77.76e6, &integral) * 0xffffffff + 0.5);
216 | break;
217 | case 10:
218 | case 11:
219 | /* set rx phase increment */
220 | freq = ntohl(*(uint32_t *)(frame + 1));
221 | rx_freq[3] = (uint32_t)floor(modf(freq / 77.76e6, &integral) * 0xffffffff + 0.5);
222 | break;
223 | case 12:
224 | case 13:
225 | /* set rx phase increment */
226 | freq = ntohl(*(uint32_t *)(frame + 1));
227 | rx_freq[4] = (uint32_t)floor(modf(freq / 77.76e6, &integral) * 0xffffffff + 0.5);
228 | break;
229 | case 14:
230 | case 15:
231 | /* set rx phase increment */
232 | freq = ntohl(*(uint32_t *)(frame + 1));
233 | rx_freq[5] = (uint32_t)floor(modf(freq / 77.76e6, &integral) * 0xffffffff + 0.5);
234 | break;
235 | case 16:
236 | case 17:
237 | /* set rx phase increment */
238 | freq = ntohl(*(uint32_t *)(frame + 1));
239 | rx_freq[6] = (uint32_t)floor(modf(freq / 77.76e6, &integral) * 0xffffffff + 0.5);
240 | break;
241 | case 36:
242 | case 37:
243 | /* set rx phase increment */
244 | freq = ntohl(*(uint32_t *)(frame + 1));
245 | rx_freq[7] = (uint32_t)floor(modf(freq / 77.76e6, &integral) * 0xffffffff + 0.5);
246 | break;
247 | }
248 | }
249 |
250 | void *handler_ep6(void *arg)
251 | {
252 | int i, j, n, m, size;
253 | int data_offset, header_offset;
254 | uint32_t counter;
255 | uint8_t data[6 * 4096];
256 | uint8_t buffer[25 * 1032];
257 | uint8_t *pointer;
258 | struct iovec iovec[25][1];
259 | struct mmsghdr datagram[25];
260 | uint8_t header[40] =
261 | {
262 | 127, 127, 127, 0, 0, 33, 17, 25,
263 | 127, 127, 127, 8, 0, 0, 0, 0,
264 | 127, 127, 127, 16, 0, 0, 0, 0,
265 | 127, 127, 127, 24, 0, 0, 0, 0,
266 | 127, 127, 127, 32, 66, 66, 66, 66
267 | };
268 |
269 | memset(iovec, 0, sizeof(iovec));
270 | memset(datagram, 0, sizeof(datagram));
271 |
272 | for(i = 0; i < 25; ++i)
273 | {
274 | *(uint32_t *)(buffer + i * 1032 + 0) = 0x0601feef;
275 | iovec[i][0].iov_base = buffer + i * 1032;
276 | iovec[i][0].iov_len = 1032;
277 | datagram[i].msg_hdr.msg_iov = iovec[i];
278 | datagram[i].msg_hdr.msg_iovlen = 1;
279 | datagram[i].msg_hdr.msg_name = &addr_ep6;
280 | datagram[i].msg_hdr.msg_namelen = sizeof(addr_ep6);
281 | }
282 |
283 | header_offset = 0;
284 | counter = 0;
285 |
286 | *rx_rst &= ~1;
287 | *rx_rst |= 1;
288 |
289 | while(1)
290 | {
291 | if(!enable_thread) break;
292 |
293 | size = receivers * 6 + 2;
294 | n = 504 / size;
295 | m = 256 / n;
296 |
297 | if(*rx_cntr >= 2048)
298 | {
299 | *rx_rst &= ~1;
300 | *rx_rst |= 1;
301 | }
302 |
303 | while(*rx_cntr < m * n * 2) usleep(1000);
304 |
305 | memcpy(data, rx_data, m * n * 96);
306 |
307 | data_offset = 0;
308 | for(i = 0; i < m; ++i)
309 | {
310 | *(uint32_t *)(buffer + i * 1032 + 4) = htonl(counter);
311 | ++counter;
312 | }
313 |
314 | for(i = 0; i < m * 2; ++i)
315 | {
316 | pointer = buffer + i * 516 - i % 2 * 4 + 8;
317 | memcpy(pointer, header + header_offset, 8);
318 | header_offset = header_offset >= 32 ? 0 : header_offset + 8;
319 |
320 | pointer += 8;
321 | memset(pointer, 0, 504);
322 | for(j = 0; j < n; ++j)
323 | {
324 | memcpy(pointer, data + data_offset, size - 2);
325 | data_offset += 48;
326 | pointer += size;
327 | }
328 | }
329 |
330 | sendmmsg(sock_ep2, datagram, m, 0);
331 | }
332 |
333 | active_thread = 0;
334 |
335 | return NULL;
336 | }
337 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_wspr_77_76/app/Makefile:
--------------------------------------------------------------------------------
1 | CFLAGS = -O3 -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=hard -ffast-math -fsingle-precision-constant -mvectorize-with-neon-quad
2 |
3 | all: write-c2-files
4 |
5 | write-c2-files: write-c2-files.c
6 | gcc $(CFLAGS) -o $@ $^ -lm -lconfig
7 |
8 | clean:
9 | rm -f write-c2-files
10 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_wspr_77_76/app/decode-wspr.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # CALL and GRID should be specified to enable uploads
4 | CALL=
5 | GRID=
6 |
7 | # version information
8 | VERSION=QMTECH
9 |
10 | JOBS=4
11 | NICE=10
12 |
13 | DIR=`readlink -f $0`
14 | DIR=`dirname $DIR`
15 |
16 | RECORDER=$DIR/write-c2-files
17 | CONFIG=write-c2-files.cfg
18 |
19 | DECODER=/media/mmcblk0p1/apps/wsprd/wsprd
20 | ALLMEPT=ALL_WSPR.TXT
21 |
22 | SLEEP=/media/mmcblk0p1/apps/common_tools/sleep-to-59
23 |
24 | date
25 |
26 | test $DIR/$CONFIG -ot $CONFIG || cp $DIR/$CONFIG $CONFIG
27 |
28 | echo "Sleeping ..."
29 |
30 | $SLEEP
31 |
32 | sleep 1
33 |
34 | date
35 | TIMESTAMP=`date --utc +'%y%m%d_%H%M'`
36 |
37 | echo "Recording ..."
38 |
39 | killall -q $RECORDER
40 | $RECORDER $CONFIG
41 |
42 | echo "Decoding ..."
43 |
44 | for file in wspr_*_$TIMESTAMP.c2
45 | do
46 | while [ `pgrep $DECODER | wc -l` -ge $JOBS ]
47 | do
48 | sleep 1
49 | done
50 | nice -n $NICE $DECODER -JC 2000 $file &
51 | done
52 |
53 | wait
54 |
55 | rm -f wspr_*_$TIMESTAMP.c2
56 |
57 | test -n "$CALL" -a -n "$GRID" -a -s $ALLMEPT || exit
58 |
59 | echo "Uploading ..."
60 |
61 | # sort by highest SNR, then print unique date/time/band/call combinations,
62 | # and then sort them by date/time/frequency
63 | sort -nr -k 3,3 $ALLMEPT | awk '!seen[$1"_"$2"_"int($5)"_"$7] {print} {++seen[$1"_"$2"_"int($5)"_"$7]}' | sort -n -k 1,1 -k 2,2 -k 5,5 -o $ALLMEPT
64 |
65 | curl -sS -m 30 -F allmept=@$ALLMEPT -F call=$CALL -F grid=$GRID -F version=$VERSION http://wsprnet.org/post > /dev/null
66 |
67 | rm -f $ALLMEPT
68 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_wspr_77_76/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Multiband WSPR receiver
6 |
7 |
8 |
9 |
10 |
19 |
20 |
Multiband WSPR receiver
21 |
The multiband WSPR receiver is ready.
22 |
More details about this application can be found at this link .
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_wspr_77_76/app/start.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | apps_dir=/media/mmcblk0p1/apps
4 |
5 | source $apps_dir/stop.sh
6 |
7 | if grep -q '
' $apps_dir/sdr_receiver_wspr_77_76/decode-wspr.sh
8 | then
9 | mount -o rw,remount /media/mmcblk0p1
10 | dos2unix $apps_dir/sdr_receiver_wspr_77_76/decode-wspr.sh
11 | mount -o ro,remount /media/mmcblk0p1
12 | fi
13 |
14 | rm -rf /dev/shm/*
15 |
16 | cat $apps_dir/sdr_receiver_wspr_77_76/sdr_receiver_wspr_77_76.bit > /dev/xdevcfg
17 |
18 | $apps_dir/common_tools/setup-adc
19 | $apps_dir/common_tools/enable-adc.sh
20 |
21 | ln -sf $apps_dir/sdr_receiver_wspr_77_76/wspr.cron /etc/cron.d/wspr_77_76
22 |
23 | service dcron restart
24 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_wspr_77_76/app/stop.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | if test -e /etc/cron.d/wspr_77_76
4 | then
5 | rm -f /etc/cron.d/wspr_77_76
6 | service dcron restart
7 | killall -q decode-wspr.sh sleep-to-59 write-c2-files wsprd
8 | killall -q update-corr.sh measure-corr measure-level
9 | fi
10 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_wspr_77_76/app/write-c2-files.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | int main(int argc, char *argv[])
13 | {
14 | FILE *fp;
15 | int fd, offset, length, i, j;
16 | time_t t;
17 | struct tm *gmt;
18 | volatile void *cfg, *sts;
19 | volatile uint64_t *fifo;
20 | volatile uint8_t *rst;
21 | volatile uint16_t *sel, *cntr;
22 | int32_t type = 2;
23 | uint64_t *buffer;
24 | config_t config;
25 | config_setting_t *setting, *element;
26 | char date[12];
27 | char name[64];
28 | char zeros[15] = "000000_0000.c2";
29 | double corr, dialfreq, integral;
30 | double freq[16] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
31 |
32 | if(argc != 2)
33 | {
34 | fprintf(stderr, "Usage: write-c2-files config_file.cfg\n");
35 | return EXIT_FAILURE;
36 | }
37 |
38 | config_init(&config);
39 |
40 | if(!config_read_file(&config, argv[1]))
41 | {
42 | fprintf(stderr, "Error on line %d in configuration file.\n", config_error_line(&config));
43 | return EXIT_FAILURE;
44 | }
45 |
46 | if(!config_lookup_float(&config, "corr", &corr))
47 | {
48 | fprintf(stderr, "No 'corr' setting in configuration file.\n");
49 | return EXIT_FAILURE;
50 | }
51 |
52 | if(corr < -100.0 || corr > 100.0)
53 | {
54 | fprintf(stderr, "Wrong 'corr' setting in configuration file.\n");
55 | return EXIT_FAILURE;
56 | }
57 |
58 | setting = config_lookup(&config, "bands");
59 | if(setting == NULL)
60 | {
61 | fprintf(stderr, "No 'bands' setting in configuration file.\n");
62 | return EXIT_FAILURE;
63 | }
64 |
65 | length = config_setting_length(setting);
66 |
67 | if(length > 16)
68 | {
69 | fprintf(stderr, "More than 16 bands in configuration file.\n");
70 | return EXIT_FAILURE;
71 | }
72 |
73 | if(length < 1)
74 | {
75 | fprintf(stderr, "Less than 1 band in configuration file.\n");
76 | return EXIT_FAILURE;
77 | }
78 |
79 | for(i = 0; i < length; ++i)
80 | {
81 | element = config_setting_get_elem(setting, i);
82 |
83 | if(!config_setting_lookup_float(element, "freq", &freq[i]))
84 | {
85 | fprintf(stderr, "No 'freq' setting in element %d.\n", i);
86 | return EXIT_FAILURE;
87 | }
88 | }
89 |
90 | t = time(NULL);
91 | if((gmt = gmtime(&t)) == NULL)
92 | {
93 | fprintf(stderr, "Cannot convert time.\n");
94 | return EXIT_FAILURE;
95 | }
96 |
97 | if((fd = open("/dev/mem", O_RDWR)) < 0)
98 | {
99 | fprintf(stderr, "Cannot open /dev/mem.\n");
100 | return EXIT_FAILURE;
101 | }
102 |
103 | cfg = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x40000000);
104 | sts = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x41000000);
105 | fifo = mmap(NULL, 32*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x42000000);
106 |
107 | for(i = 0; i < 16; ++i)
108 | {
109 | *(uint32_t *)(cfg + 4 + i * 4) = (uint32_t)floor(modf((1.0 + 1.0e-6 * corr) * freq[i] / 77.76, &integral) * 0xffffffff + 0.5);
110 | }
111 |
112 | rst = (uint8_t *)(cfg + 0);
113 | cntr = (uint16_t *)(sts + 0);
114 |
115 | *rst &= ~1;
116 | *rst |= 1;
117 |
118 | offset = 0;
119 | buffer = malloc(45000 * 8 * 16);
120 | memset(buffer, 0, 45000 * 8 * 16);
121 |
122 | while(offset < 42000)
123 | {
124 | while(*cntr < 500) usleep(300000);
125 |
126 | for(i = 0; i < 250; ++i)
127 | {
128 | for(j = 0; j < 16; ++j)
129 | {
130 | buffer[j * 45000 + offset + i] = *fifo;
131 | }
132 | }
133 |
134 | offset += 250;
135 | }
136 |
137 | for(i = 0; i < length; ++i)
138 | {
139 | dialfreq = freq[i] - 0.0015;
140 | strftime(date, 12, "%y%m%d_%H%M", gmt);
141 | sprintf(name, "wspr_%d_%d_%s.c2", i, (uint32_t)(dialfreq * 1.0e6), date);
142 | if((fp = fopen(name, "wb")) == NULL)
143 | {
144 | fprintf(stderr, "Cannot open output file %s.\n", name);
145 | return EXIT_FAILURE;
146 | }
147 | fwrite(zeros, 1, 14, fp);
148 | fwrite(&type, 1, 4, fp);
149 | fwrite(&dialfreq, 1, 8, fp);
150 | fwrite(&buffer[i * 45000], 1, 45000 * 8, fp);
151 | fclose(fp);
152 | }
153 |
154 | return EXIT_SUCCESS;
155 | }
156 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_wspr_77_76/app/write-c2-files.cfg:
--------------------------------------------------------------------------------
1 | // frequency correction, from -100.0 ppm to +100.0 ppm
2 | corr = 0.0;
3 |
4 | // comma separated list of bands
5 | // trailing commas are not allowed
6 | bands = (
7 | { freq = 0.137500; },
8 | { freq = 0.475700; },
9 | { freq = 1.838100; },
10 | { freq = 3.570100; },
11 | { freq = 5.288700; },
12 | { freq = 5.366200; },
13 | { freq = 7.040100; },
14 | { freq = 10.140200; },
15 | { freq = 14.097100; },
16 | { freq = 18.106100; },
17 | { freq = 21.096100; },
18 | { freq = 24.926100; },
19 | { freq = 28.126100; },
20 | { freq = 50.294500; }
21 | );
22 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_wspr_77_76/app/wspr.cron:
--------------------------------------------------------------------------------
1 | 1-59/2 * * * * cd /dev/shm && /media/mmcblk0p1/apps/sdr_receiver_wspr_77_76/decode-wspr.sh >> decode-wspr.log 2>&1 &
2 | #1-59/2 * * * * cd /dev/shm && /media/mmcblk0p1/apps/common_tools/update-corr.sh 77.76 >> update-corr.log 2>&1 &
3 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_wspr_77_76/block_design.tcl:
--------------------------------------------------------------------------------
1 | # Create ports
2 | create_bd_port -dir I adc_clk_p_i
3 | create_bd_port -dir I adc_clk_n_i
4 |
5 | create_bd_port -dir I adc_ovr_p_i
6 | create_bd_port -dir I adc_ovr_n_i
7 |
8 | create_bd_port -dir I -from 6 -to 0 adc_dat_p_i
9 | create_bd_port -dir I -from 6 -to 0 adc_dat_n_i
10 |
11 | create_bd_port -dir O adc_spi_sclk
12 | create_bd_port -dir O adc_spi_sdio
13 | create_bd_port -dir O adc_spi_cs
14 |
15 | create_bd_port -dir O adc_oe
16 |
17 | # Create xlconstant
18 | cell xilinx.com:ip:xlconstant const_0
19 |
20 | # Create clk_wiz
21 | cell xilinx.com:ip:clk_wiz pll_0 {
22 | PRIMITIVE PLL
23 | PRIM_IN_FREQ.VALUE_SRC USER
24 | PRIM_IN_FREQ 77.76
25 | PRIM_SOURCE Differential_clock_capable_pin
26 | CLKOUT1_USED true
27 | CLKOUT1_REQUESTED_OUT_FREQ 77.76
28 | USE_RESET false
29 | } {
30 | clk_in1_p adc_clk_p_i
31 | clk_in1_n adc_clk_n_i
32 | }
33 |
34 | # Create processing_system7
35 | cell xilinx.com:ip:processing_system7 ps_0 {
36 | PCW_IMPORT_BOARD_PRESET cfg/qmtech_xc7z020.xml
37 | PCW_USE_M_AXI_GP1 1
38 | } {
39 | M_AXI_GP0_ACLK pll_0/clk_out1
40 | M_AXI_GP1_ACLK pll_0/clk_out1
41 | SPI0_SCLK_O adc_spi_sclk
42 | SPI0_MOSI_O adc_spi_sdio
43 | SPI0_SS_I const_0/dout
44 | SPI0_SS_O adc_spi_cs
45 | }
46 |
47 | # Create port_slicer
48 | cell pavel-demin:user:port_slicer slice_0 {
49 | DIN_WIDTH 64 DIN_FROM 1 DIN_TO 1
50 | } {
51 | din ps_0/GPIO_O
52 | dout adc_oe
53 | }
54 |
55 | # Create all required interconnections
56 | apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {
57 | make_external {FIXED_IO, DDR}
58 | Master Disable
59 | Slave Disable
60 | } [get_bd_cells ps_0]
61 |
62 | # Create proc_sys_reset
63 | cell xilinx.com:ip:proc_sys_reset rst_0 {} {
64 | ext_reset_in const_0/dout
65 | dcm_locked pll_0/locked
66 | slowest_sync_clk pll_0/clk_out1
67 | }
68 |
69 | # ADC
70 |
71 | # Create util_ds_buf
72 | cell xilinx.com:ip:util_ds_buf buf_0 {
73 | C_SIZE 7
74 | C_BUF_TYPE IBUFDS
75 | } {
76 | IBUF_DS_P adc_dat_p_i
77 | IBUF_DS_N adc_dat_n_i
78 | }
79 |
80 | # Create axis_adc_ddr
81 | cell pavel-demin:user:axis_adc_ddr adc_0 {
82 | ADC_DATA_WIDTH 7
83 | } {
84 | aclk pll_0/clk_out1
85 | adc_data buf_0/IBUF_OUT
86 | }
87 |
88 | # HUB
89 |
90 | # Create axi_hub
91 | cell pavel-demin:user:axi_hub hub_0 {
92 | CFG_DATA_WIDTH 544
93 | STS_DATA_WIDTH 32
94 | } {
95 | S_AXI ps_0/M_AXI_GP0
96 | aclk pll_0/clk_out1
97 | aresetn rst_0/peripheral_aresetn
98 | }
99 |
100 | # RX 0
101 |
102 | # Create port_slicer
103 | cell pavel-demin:user:port_slicer rst_slice_0 {
104 | DIN_WIDTH 544 DIN_FROM 7 DIN_TO 0
105 | } {
106 | din hub_0/cfg_data
107 | }
108 |
109 | # Create port_slicer
110 | cell pavel-demin:user:port_slicer cfg_slice_0 {
111 | DIN_WIDTH 544 DIN_FROM 543 DIN_TO 32
112 | } {
113 | din hub_0/cfg_data
114 | }
115 |
116 | module rx_0 {
117 | source projects/sdr_receiver_wspr_77_76/rx.tcl
118 | } {
119 | slice_0/din rst_slice_0/dout
120 | slice_1/din cfg_slice_0/dout
121 | slice_2/din cfg_slice_0/dout
122 | slice_3/din cfg_slice_0/dout
123 | slice_4/din cfg_slice_0/dout
124 | slice_5/din cfg_slice_0/dout
125 | slice_6/din cfg_slice_0/dout
126 | slice_7/din cfg_slice_0/dout
127 | slice_8/din cfg_slice_0/dout
128 | slice_9/din cfg_slice_0/dout
129 | slice_10/din cfg_slice_0/dout
130 | slice_11/din cfg_slice_0/dout
131 | slice_12/din cfg_slice_0/dout
132 | slice_13/din cfg_slice_0/dout
133 | slice_14/din cfg_slice_0/dout
134 | slice_15/din cfg_slice_0/dout
135 | slice_16/din cfg_slice_0/dout
136 | fifo_0/read_count hub_0/sts_data
137 | conv_2/M_AXIS hub_0/S00_AXIS
138 | }
139 |
140 | # PPS and level measurement
141 |
142 | module common_0 {
143 | source projects/common_tools/block_design.tcl
144 | }
145 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_wspr_77_76/filters/rx_fir_0.r:
--------------------------------------------------------------------------------
1 | library(signal)
2 |
3 | # CIC filter parameters
4 | R <- 320 # Decimation factor
5 | M <- 1 # Differential delay
6 | N <- 6 # Number of stages
7 |
8 | Fc <- 0.247 # cutoff frequency
9 | htbw <- 0.005 # half transition bandwidth
10 |
11 | # fir2 parameters
12 | k <- kaiserord(c(Fc-htbw, Fc+htbw), c(1, 0), 1/(2^16), 1)
13 | L <- k$n # Filter order
14 | Beta <- k$beta # Kaiser window parameter
15 |
16 | # FIR filter design using fir2
17 | s <- 0.001 # Step size
18 | fp <- seq(0.0, Fc-htbw, by=s) # Pass band frequency samples
19 | fs <- seq(Fc+htbw, 0.5, by=s) # Stop band frequency samples
20 | f <- c(fp, fs)*2 # Normalized frequency samples; 0<=f<=1
21 |
22 | Mp <- matrix(1, 1, length(fp)) # Pass band response; Mp[1]=1
23 | Mp[-1] <- abs(M*R*sin(pi*fp[-1]/R)/sin(pi*M*fp[-1]))^N
24 | Mf <- c(Mp, matrix(0, 1, length(fs)))
25 |
26 | h <- fir2(L, f, Mf, window=kaiser(L+1, Beta))
27 |
28 | h <- h / sum(h)
29 |
30 | # Print filter coefficients
31 | paste(sprintf("%.10e", h), collapse=", ")
32 |
33 | fh <- freqz(h)
34 |
35 | op <- par(mfrow = c(2, 1))
36 |
37 | plot(f, 20*log10(Mf), type = "b", ylab = "dB", xlab = "Frequency", xlim = c(0.51, 0.54), ylim = c(-125, 5))
38 | lines(fh$f / pi, 20*log10(abs(fh$h)), col = "blue")
39 | grid()
40 |
41 | plot(f, 20*log10(Mf), type = "b", ylab = "dB", xlab = "Frequency", xlim = c(0.46, 0.49), ylim = c(-5, 5))
42 | lines(fh$f / pi, 20*log10(abs(fh$h)), col = "blue")
43 | grid()
44 |
45 | par(op)
46 |
--------------------------------------------------------------------------------
/projects/sdr_receiver_wspr_77_76/ports.xdc:
--------------------------------------------------------------------------------
1 | # clock
2 |
3 | set_property IOSTANDARD LVDS_25 [get_ports adc_clk_p_i]
4 | set_property IOSTANDARD LVDS_25 [get_ports adc_clk_n_i]
5 |
6 | set_property DIFF_TERM TRUE [get_ports adc_clk_p_i]
7 | set_property DIFF_TERM TRUE [get_ports adc_clk_n_i]
8 |
9 | set_property PACKAGE_PIN Y19 [get_ports adc_clk_p_i]
10 | set_property PACKAGE_PIN AA19 [get_ports adc_clk_n_i]
11 |
12 | # overrange
13 |
14 | set_property IOSTANDARD LVDS_25 [get_ports {adc_ovr_p_i}]
15 | set_property IOSTANDARD LVDS_25 [get_ports {adc_ovr_n_i}]
16 |
17 | set_property DIFF_TERM TRUE [get_ports {adc_ovr_p_i]}]
18 | set_property DIFF_TERM TRUE [get_ports {adc_ovr_n_i}]
19 |
20 | set_property PACKAGE_PIN U17 [get_ports {adc_ovr_p_i}]
21 | set_property PACKAGE_PIN V17 [get_ports {adc_ovr_n_i}]
22 |
23 | # data
24 |
25 | set_property IOSTANDARD LVDS_25 [get_ports {adc_dat_p_i[*]}]
26 | set_property IOSTANDARD LVDS_25 [get_ports {adc_dat_n_i[*]}]
27 |
28 | set_property DIFF_TERM TRUE [get_ports {adc_dat_p_i[*]}]
29 | set_property DIFF_TERM TRUE [get_ports {adc_dat_n_i[*]}]
30 |
31 | set_property PACKAGE_PIN AA17 [get_ports {adc_dat_p_i[0]}]
32 | set_property PACKAGE_PIN AB17 [get_ports {adc_dat_n_i[0]}]
33 |
34 | set_property PACKAGE_PIN AA16 [get_ports {adc_dat_p_i[1]}]
35 | set_property PACKAGE_PIN AB16 [get_ports {adc_dat_n_i[1]}]
36 |
37 | set_property PACKAGE_PIN AB14 [get_ports {adc_dat_p_i[2]}]
38 | set_property PACKAGE_PIN AB15 [get_ports {adc_dat_n_i[2]}]
39 |
40 | set_property PACKAGE_PIN Y18 [get_ports {adc_dat_p_i[3]}]
41 | set_property PACKAGE_PIN AA18 [get_ports {adc_dat_n_i[3]}]
42 |
43 | set_property PACKAGE_PIN W17 [get_ports {adc_dat_p_i[4]}]
44 | set_property PACKAGE_PIN W18 [get_ports {adc_dat_n_i[4]}]
45 |
46 | set_property PACKAGE_PIN W16 [get_ports {adc_dat_p_i[5]}]
47 | set_property PACKAGE_PIN Y16 [get_ports {adc_dat_n_i[5]}]
48 |
49 | set_property PACKAGE_PIN Y14 [get_ports {adc_dat_p_i[6]}]
50 | set_property PACKAGE_PIN AA14 [get_ports {adc_dat_n_i[6]}]
51 |
52 | # SPI
53 |
54 | set_property IOSTANDARD LVCMOS25 [get_ports adc_spi_*]
55 |
56 | set_property PACKAGE_PIN AA13 [get_ports adc_spi_sclk]
57 | set_property PACKAGE_PIN Y13 [get_ports adc_spi_sdio]
58 | set_property PACKAGE_PIN U15 [get_ports adc_spi_cs]
59 |
60 | # output enable
61 |
62 | set_property IOSTANDARD LVCMOS25 [get_ports adc_oe]
63 |
64 | set_property PACKAGE_PIN Y20 [get_ports adc_oe]
65 |
--------------------------------------------------------------------------------
/scripts/alpine.sh:
--------------------------------------------------------------------------------
1 | alpine_url=http://dl-cdn.alpinelinux.org/alpine/v3.20
2 |
3 | tools_tar=apk-tools-static-2.14.4-r1.apk
4 | tools_url=$alpine_url/main/armv7/$tools_tar
5 |
6 | firmware_tar=linux-firmware-other-20240811-r0.apk
7 | firmware_url=$alpine_url/main/armv7/$firmware_tar
8 |
9 | linux_dir=tmp/linux-6.6
10 | linux_ver=6.6.44-xilinx
11 |
12 | modules_dir=alpine-modloop/lib/modules/$linux_ver
13 |
14 | passwd=changeme
15 |
16 | test -f $tools_tar || curl -L $tools_url -o $tools_tar
17 |
18 | test -f $firmware_tar || curl -L $firmware_url -o $firmware_tar
19 |
20 | for tar in linux-firmware-ath9k_htc-20240811-r0.apk linux-firmware-brcm-20240811-r0.apk linux-firmware-cypress-20240811-r0.apk linux-firmware-rtlwifi-20240811-r0.apk
21 | do
22 | url=$alpine_url/main/armv7/$tar
23 | test -f $tar || curl -L $url -o $tar
24 | done
25 |
26 | mkdir alpine-apk
27 | tar -zxf $tools_tar --directory=alpine-apk --warning=no-unknown-keyword
28 |
29 | mkdir -p $modules_dir/kernel
30 |
31 | find $linux_dir -name \*.ko -printf '%P\0' | tar --directory=$linux_dir --owner=0 --group=0 --null --files-from=- -zcf - | tar -zxf - --directory=$modules_dir/kernel
32 |
33 | cp $linux_dir/modules.order $linux_dir/modules.builtin $modules_dir/
34 |
35 | depmod -a -b alpine-modloop $linux_ver
36 |
37 | tar -zxf $firmware_tar --directory=alpine-modloop/lib/modules --warning=no-unknown-keyword --strip-components=1 --wildcards lib/firmware/ar* lib/firmware/rt*
38 |
39 | for tar in linux-firmware-ath9k_htc-20240811-r0.apk linux-firmware-brcm-20240811-r0.apk linux-firmware-cypress-20240811-r0.apk linux-firmware-rtlwifi-20240811-r0.apk
40 | do
41 | tar -zxf $tar --directory=alpine-modloop/lib/modules --warning=no-unknown-keyword --strip-components=1
42 | done
43 |
44 | mksquashfs alpine-modloop/lib modloop -b 1048576 -comp xz -Xdict-size 100%
45 |
46 | rm -rf alpine-modloop
47 |
48 | root_dir=alpine-root
49 |
50 | mkdir -p $root_dir/usr/bin
51 | cp /usr/bin/qemu-arm-static $root_dir/usr/bin/
52 |
53 | mkdir -p $root_dir/etc
54 | cp /etc/resolv.conf $root_dir/etc/
55 |
56 | mkdir -p $root_dir/etc/apk
57 | mkdir -p $root_dir/media/mmcblk0p1/cache
58 | ln -s /media/mmcblk0p1/cache $root_dir/etc/apk/cache
59 |
60 | cp -r alpine/etc $root_dir/
61 | cp -r alpine/apps $root_dir/media/mmcblk0p1/
62 |
63 | projects="common_tools led_blinker_77_76 sdr_receiver_77_76 sdr_receiver_ft8_77_76 sdr_receiver_hpsdr_77_76 sdr_receiver_wspr_77_76"
64 |
65 | for p in $projects
66 | do
67 | mkdir -p $root_dir/media/mmcblk0p1/apps/$p
68 | cp -r projects/$p/server/* $root_dir/media/mmcblk0p1/apps/$p/
69 | cp -r projects/$p/app/* $root_dir/media/mmcblk0p1/apps/$p/
70 | cp tmp/$p.bit $root_dir/media/mmcblk0p1/apps/$p/
71 | done
72 |
73 | cp -r alpine-apk/sbin $root_dir/
74 |
75 | chroot $root_dir /sbin/apk.static --repository $alpine_url/main --update-cache --allow-untrusted --initdb add alpine-base
76 |
77 | echo $alpine_url/main > $root_dir/etc/apk/repositories
78 | echo $alpine_url/community >> $root_dir/etc/apk/repositories
79 |
80 | chroot $root_dir /bin/sh <<- EOF_CHROOT
81 |
82 | apk update
83 | apk add openssh ucspi-tcp6 iw wpa_supplicant dhcpcd dnsmasq hostapd iptables avahi dbus dcron chrony gpsd libgfortran musl-dev libconfig-dev alsa-lib-dev alsa-utils curl wget less nano bc dos2unix screen
84 |
85 | rc-update add bootmisc boot
86 | rc-update add hostname boot
87 | rc-update add swclock boot
88 | rc-update add sysctl boot
89 | rc-update add syslog boot
90 | rc-update add seedrng boot
91 |
92 | rc-update add killprocs shutdown
93 | rc-update add mount-ro shutdown
94 | rc-update add savecache shutdown
95 |
96 | rc-update add devfs sysinit
97 | rc-update add dmesg sysinit
98 | rc-update add mdev sysinit
99 | rc-update add hwdrivers sysinit
100 | rc-update add modloop sysinit
101 |
102 | rc-update add avahi-daemon default
103 | rc-update add chronyd default
104 | rc-update add dhcpcd default
105 | rc-update add local default
106 | rc-update add dcron default
107 | rc-update add sshd default
108 |
109 | mkdir -p etc/runlevels/wifi
110 | rc-update -s add default wifi
111 |
112 | rc-update add iptables wifi
113 | rc-update add dnsmasq wifi
114 | rc-update add hostapd wifi
115 |
116 | sed -i 's/^SAVE_ON_STOP=.*/SAVE_ON_STOP="no"/;s/^IPFORWARD=.*/IPFORWARD="yes"/' etc/conf.d/iptables
117 |
118 | sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/' etc/ssh/sshd_config
119 |
120 | echo root:$passwd | chpasswd
121 |
122 | hostname qmtech-xc7z020
123 |
124 | sed -i 's/^# LBU_MEDIA=.*/LBU_MEDIA=mmcblk0p1/' etc/lbu/lbu.conf
125 |
126 | cat <<- EOF_CAT > root/.profile
127 | alias rw='mount -o rw,remount /media/mmcblk0p1'
128 | alias ro='mount -o ro,remount /media/mmcblk0p1'
129 | EOF_CAT
130 |
131 | ln -s /media/mmcblk0p1/apps root/apps
132 | ln -s /media/mmcblk0p1/wifi root/wifi
133 |
134 | lbu add root
135 | lbu delete etc/resolv.conf
136 | lbu delete etc/cron.d/ft8_77_76
137 | lbu delete etc/cron.d/wspr_77_76
138 | lbu delete root/.ash_history
139 |
140 | lbu commit -d
141 |
142 | apk add make gcc gfortran linux-headers
143 |
144 | ft8d_dir=/media/mmcblk0p1/apps/ft8d
145 | ft8d_tar=/media/mmcblk0p1/apps/ft8d.tar.gz
146 | ft8d_url=https://github.com/pavel-demin/ft8d/archive/master.tar.gz
147 |
148 | curl -L \$ft8d_url -o \$ft8d_tar
149 | mkdir -p \$ft8d_dir
150 | tar -zxf \$ft8d_tar --strip-components=1 --directory=\$ft8d_dir
151 | rm \$ft8d_tar
152 | make -C \$ft8d_dir
153 |
154 | wsprd_dir=/media/mmcblk0p1/apps/wsprd
155 | wsprd_tar=/media/mmcblk0p1/apps/wsprd.tar.gz
156 | wsprd_url=https://github.com/pavel-demin/wsprd/archive/master.tar.gz
157 |
158 | curl -L \$wsprd_url -o \$wsprd_tar
159 | mkdir -p \$wsprd_dir
160 | tar -zxf \$wsprd_tar --strip-components=1 --directory=\$wsprd_dir
161 | rm \$wsprd_tar
162 | make -C \$wsprd_dir
163 |
164 | for p in server $projects
165 | do
166 | make -C /media/mmcblk0p1/apps/\$p clean
167 | make -C /media/mmcblk0p1/apps/\$p
168 | done
169 |
170 | EOF_CHROOT
171 |
172 | cp -r $root_dir/media/mmcblk0p1/apps .
173 | cp -r $root_dir/media/mmcblk0p1/cache .
174 | cp $root_dir/media/mmcblk0p1/qmtech-xc7z020.apkovl.tar.gz .
175 |
176 | cp -r alpine/wifi .
177 |
178 | hostname -F /etc/hostname
179 |
180 | rm -rf $root_dir alpine-apk
181 |
182 | zip -r qmtech-xc7z020-alpine-3.20-armv7-`date +%Y%m%d`.zip apps boot.bin cache mac.txt modloop qmtech-xc7z020.apkovl.tar.gz wifi
183 |
184 | rm -rf apps cache modloop qmtech-xc7z020.apkovl.tar.gz wifi
185 |
--------------------------------------------------------------------------------
/scripts/bitstream.tcl:
--------------------------------------------------------------------------------
1 |
2 | set project_name [lindex $argv 0]
3 |
4 | open_project tmp/$project_name.xpr
5 |
6 | if {[get_property PROGRESS [get_runs impl_1]] != "100%"} {
7 | launch_runs impl_1
8 | wait_on_run impl_1
9 | }
10 |
11 | open_run [get_runs impl_1]
12 |
13 | set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
14 |
15 | write_bitstream -force -file tmp/$project_name.bit
16 |
17 | close_project
18 |
--------------------------------------------------------------------------------
/scripts/core.tcl:
--------------------------------------------------------------------------------
1 |
2 | set core_name [lindex $argv 0]
3 |
4 | set part_name [lindex $argv 1]
5 |
6 | file delete -force tmp/cores/$core_name tmp/cores/$core_name.cache tmp/cores/$core_name.hw tmp/cores/$core_name.ip_user_files tmp/cores/$core_name.sim tmp/cores/$core_name.xpr
7 |
8 | create_project -part $part_name $core_name tmp/cores
9 |
10 | add_files -norecurse cores/$core_name.v
11 |
12 | set_property TOP $core_name [current_fileset]
13 |
14 | set files [glob -nocomplain modules/*.v]
15 | if {[llength $files] > 0} {
16 | add_files -norecurse $files
17 | }
18 |
19 | ipx::package_project -root_dir tmp/cores/$core_name
20 |
21 | set core [ipx::current_core]
22 |
23 | set_property VERSION {1.0} $core
24 | set_property NAME $core_name $core
25 | set_property LIBRARY {user} $core
26 | set_property VENDOR {pavel-demin} $core
27 | set_property VENDOR_DISPLAY_NAME {Pavel Demin} $core
28 | set_property COMPANY_URL {https://github.com/pavel-demin/qmtech-xc7z020-notes} $core
29 | set_property SUPPORTED_FAMILIES {zynq Production} $core
30 |
31 | ipx::create_xgui_files $core
32 | ipx::update_checksums $core
33 | ipx::save_core $core
34 |
35 | close_project
36 |
--------------------------------------------------------------------------------
/scripts/devicetree.tcl:
--------------------------------------------------------------------------------
1 |
2 | set project_name [lindex $argv 0]
3 |
4 | set proc_name [lindex $argv 1]
5 |
6 | set repo_path [lindex $argv 2]
7 |
8 | set hard_path tmp/$project_name.hard
9 | set tree_path tmp/$project_name.tree
10 |
11 | file mkdir $hard_path
12 | file copy -force tmp/$project_name.xsa $hard_path/$project_name.xsa
13 |
14 | hsi set_repo_path $repo_path
15 |
16 | hsi open_hw_design $hard_path/$project_name.xsa
17 | hsi create_sw_design -proc $proc_name -os device_tree devicetree
18 |
19 | hsi generate_target -dir $tree_path
20 |
21 | hsi close_sw_design [hsi current_sw_design]
22 | hsi close_hw_design [hsi current_hw_design]
23 |
--------------------------------------------------------------------------------
/scripts/fsbl.tcl:
--------------------------------------------------------------------------------
1 |
2 | set project_name [lindex $argv 0]
3 |
4 | set proc_name [lindex $argv 1]
5 |
6 | set hard_path tmp/$project_name.hard
7 | set fsbl_path tmp/$project_name.fsbl
8 |
9 | file mkdir $hard_path
10 | file copy -force tmp/$project_name.xsa $hard_path/$project_name.xsa
11 |
12 | hsi open_hw_design $hard_path/$project_name.xsa
13 | hsi create_sw_design -proc $proc_name -os standalone fsbl
14 |
15 | hsi add_library xilffs
16 | hsi add_library xilrsa
17 |
18 | hsi generate_app -proc $proc_name -app zynq_fsbl -dir $fsbl_path -compile
19 |
20 | hsi close_hw_design [hsi current_hw_design]
21 |
--------------------------------------------------------------------------------
/scripts/hwdef.tcl:
--------------------------------------------------------------------------------
1 |
2 | set project_name [lindex $argv 0]
3 |
4 | open_project tmp/$project_name.xpr
5 |
6 | write_hw_platform -fixed -force -file tmp/$project_name.xsa
7 |
8 | close_project
9 |
--------------------------------------------------------------------------------
/scripts/project.tcl:
--------------------------------------------------------------------------------
1 |
2 | package require fileutil
3 |
4 | set project_name [lindex $argv 0]
5 |
6 | set part_name [lindex $argv 1]
7 |
8 | file delete -force tmp/$project_name.cache tmp/$project_name.gen tmp/$project_name.hw tmp/$project_name.ip_user_files tmp/$project_name.runs tmp/$project_name.sim tmp/$project_name.srcs tmp/$project_name.xpr
9 |
10 | create_project -part $part_name $project_name tmp
11 |
12 | set_property IP_REPO_PATHS tmp/cores [current_project]
13 |
14 | update_ip_catalog
15 |
16 | proc wire {name1 name2} {
17 | set port1 [get_bd_pins $name1]
18 | set port2 [get_bd_pins $name2]
19 | if {[llength $port1] == 1 && [llength $port2] == 1} {
20 | connect_bd_net $port1 $port2
21 | return
22 | }
23 | set port1 [get_bd_intf_pins $name1]
24 | set port2 [get_bd_intf_pins $name2]
25 | if {[llength $port1] == 1 && [llength $port2] == 1} {
26 | connect_bd_intf_net $port1 $port2
27 | return
28 | }
29 | error "** ERROR: can't connect $name1 and $name2"
30 | }
31 |
32 | proc cell {cell_vlnv cell_name {cell_props {}} {cell_ports {}}} {
33 | set cell [create_bd_cell -type ip -vlnv $cell_vlnv $cell_name]
34 | set prop_list {}
35 | foreach {prop_name prop_value} [uplevel 1 [list subst $cell_props]] {
36 | lappend prop_list CONFIG.$prop_name $prop_value
37 | }
38 | if {[llength $prop_list] > 1} {
39 | set_property -dict $prop_list $cell
40 | }
41 | foreach {local_name remote_name} [uplevel 1 [list subst $cell_ports]] {
42 | wire $cell_name/$local_name $remote_name
43 | }
44 | }
45 |
46 | proc module {module_name module_body {module_ports {}}} {
47 | set instance [current_bd_instance .]
48 | current_bd_instance [create_bd_cell -type hier $module_name]
49 | eval $module_body
50 | current_bd_instance $instance
51 | foreach {local_name remote_name} [uplevel 1 [list subst $module_ports]] {
52 | wire $module_name/$local_name $remote_name
53 | }
54 | }
55 |
56 | proc design {design_name design_body} {
57 | set design [current_bd_design]
58 | create_bd_design $design_name
59 | eval $design_body
60 | validate_bd_design
61 | save_bd_design
62 | current_bd_design $design
63 | }
64 |
65 | proc container {container_name container_designs {container_ports {}}} {
66 | set reference [lindex $container_designs 0]
67 | set container [create_bd_cell -type container -reference $reference $container_name]
68 | foreach {local_name remote_name} [uplevel 1 [list subst $container_ports]] {
69 | wire $container_name/$local_name $remote_name
70 | }
71 | set list {}
72 | foreach item $container_designs {
73 | lappend list $item.bd
74 | }
75 | set list [join $list :]
76 | set_property CONFIG.ENABLE_DFX true $container
77 | set_property CONFIG.LIST_SYNTH_BD $list $container
78 | set_property CONFIG.LIST_SIM_BD $list $container
79 | }
80 |
81 | proc addr {offset range port master} {
82 | set object [get_bd_intf_pins $port]
83 | set segment [get_bd_addr_segs -of_objects $object]
84 | set config [list Master $master Clk Auto]
85 | apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config $config $object
86 | assign_bd_address -offset $offset -range $range $segment
87 | }
88 |
89 | create_bd_design system
90 |
91 | source cfg/ports.tcl
92 | source projects/$project_name/block_design.tcl
93 |
94 | rename wire {}
95 | rename cell {}
96 | rename module {}
97 | rename design {}
98 | rename container {}
99 | rename addr {}
100 |
101 | set system [get_files system.bd]
102 |
103 | set_property SYNTH_CHECKPOINT_MODE None $system
104 |
105 | generate_target all $system
106 | make_wrapper -files $system -top
107 |
108 | foreach ext {srcs gen} {
109 | set files [fileutil::findByPattern tmp/$project_name.$ext system_wrapper.v]
110 | if {[llength $files] > 0} {
111 | add_files -norecurse $files
112 | break
113 | }
114 | }
115 |
116 | set_property TOP system_wrapper [current_fileset]
117 |
118 | set files [glob -nocomplain cfg/*.mem projects/$project_name/*.v projects/$project_name/*.sv]
119 | if {[llength $files] > 0} {
120 | add_files -norecurse $files
121 | }
122 |
123 | set files [glob -nocomplain cfg/*.xdc projects/$project_name/*.xdc]
124 | if {[llength $files] > 0} {
125 | add_files -norecurse -fileset constrs_1 $files
126 | }
127 |
128 | set_property STRATEGY Flow_PerfOptimized_high [get_runs synth_1]
129 | set_property STRATEGY Performance_ExploreWithRemap [get_runs impl_1]
130 |
131 | close_project
132 |
--------------------------------------------------------------------------------