mirror of
https://github.com/fairwaves/UHD-Fairwaves.git
synced 2025-11-02 13:03:13 +00:00
Compare commits
187 Commits
LTE_30_72M
...
1.0.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a89674c56 | ||
|
|
77e9066bf8 | ||
|
|
1e43f04790 | ||
|
|
cbff81745b | ||
|
|
57d5ca4b51 | ||
|
|
b78ceeb9b1 | ||
|
|
fcd92d8f50 | ||
|
|
2727f62ab8 | ||
|
|
75c3380ccf | ||
|
|
80e65f35cf | ||
|
|
f16599cfa9 | ||
|
|
e6b82c85e6 | ||
|
|
8e5b9e8cba | ||
|
|
fc9ecf7709 | ||
|
|
913f19357b | ||
|
|
d96cea8000 | ||
|
|
c401071ea6 | ||
|
|
b5b351e535 | ||
|
|
1cf16e57f7 | ||
|
|
b78a96661a | ||
|
|
5452567fd9 | ||
|
|
47b3e1aaea | ||
|
|
1e042157be | ||
|
|
4cb89755bb | ||
|
|
efba897843 | ||
|
|
35ccac9f54 | ||
|
|
963f3e90dc | ||
|
|
0e8abb2068 | ||
|
|
e069b6d39c | ||
|
|
28f423567b | ||
|
|
67303bcbcc | ||
|
|
0fc60d2275 | ||
|
|
ce5f31f713 | ||
|
|
802b24c565 | ||
|
|
56c4174ad4 | ||
|
|
0073096b27 | ||
|
|
7727cd283c | ||
|
|
ff13c7d73a | ||
|
|
0bee662b81 | ||
|
|
7b955574a5 | ||
|
|
4b102f0c4c | ||
|
|
0d7b517923 | ||
|
|
aec754eb07 | ||
|
|
756cb9a74c | ||
|
|
0b105893a4 | ||
|
|
41b93944a0 | ||
|
|
a872102cd9 | ||
|
|
89277c6e56 | ||
|
|
1773223b81 | ||
|
|
24527ece28 | ||
|
|
7834aa4709 | ||
|
|
f61d102791 | ||
|
|
d8b282404b | ||
|
|
4cd94528aa | ||
|
|
fb59ec9bd2 | ||
|
|
9577f31bfb | ||
|
|
df513b81e5 | ||
|
|
471eedbb6a | ||
|
|
10e758be8c | ||
|
|
9c20b295d5 | ||
|
|
14e58af929 | ||
|
|
9a752069e7 | ||
|
|
283dae8214 | ||
|
|
df90e2b342 | ||
|
|
0b1c002f32 | ||
|
|
313488b2d3 | ||
|
|
189828f29c | ||
|
|
f913c39c0c | ||
|
|
84c5426fd8 | ||
|
|
ac22360125 | ||
|
|
6bf16b4e66 | ||
|
|
451cc221be | ||
|
|
73ab35d46c | ||
|
|
a189138078 | ||
|
|
2d83e6caed | ||
|
|
9becc6bdf8 | ||
|
|
a5cee8c757 | ||
|
|
5001cb8f95 | ||
|
|
1337b13d56 | ||
|
|
93aaef643d | ||
|
|
a33b3e92e4 | ||
|
|
08c05c5f1b | ||
|
|
000a874189 | ||
|
|
7b15bc857b | ||
|
|
e14c900821 | ||
|
|
271b8a045e | ||
|
|
30a4557825 | ||
|
|
32f82d646b | ||
|
|
c3754d5048 | ||
|
|
052a817f30 | ||
|
|
8e92e8ca43 | ||
|
|
e64d3d5940 | ||
|
|
158077c504 | ||
|
|
84ef0be96c | ||
|
|
84330517e5 | ||
|
|
72062b1466 | ||
|
|
453caf23e8 | ||
|
|
b671b8f8b1 | ||
|
|
b98d250be2 | ||
|
|
bf366bb7ae | ||
|
|
624f089dcb | ||
|
|
6af61a7cab | ||
|
|
99a409192e | ||
|
|
ce92a2f47a | ||
|
|
cbb5815fe0 | ||
|
|
108f250bf9 | ||
|
|
7e5cfac7af | ||
|
|
8b7cb405f1 | ||
|
|
6ded41c3fd | ||
|
|
fd2493f8fe | ||
|
|
e2ca1fef44 | ||
|
|
0e18fa9544 | ||
|
|
46f1e0522d | ||
|
|
f601bc41cf | ||
|
|
595446d536 | ||
|
|
1f2cdf5b51 | ||
|
|
d2acd75eb7 | ||
|
|
12e613bec2 | ||
|
|
efedd23e1f | ||
|
|
e94ffbc3a9 | ||
|
|
711523fb5a | ||
|
|
483e31af48 | ||
|
|
2d5c88d624 | ||
|
|
a837e84e89 | ||
|
|
6468121e16 | ||
|
|
4d7a11c21a | ||
|
|
3a41a46824 | ||
|
|
0a3dd778d0 | ||
|
|
171e9b83da | ||
|
|
f274d9da1c | ||
|
|
ca17c9da65 | ||
|
|
35522afed1 | ||
|
|
924dcf8d8a | ||
|
|
db0d59f936 | ||
|
|
20178f16fd | ||
|
|
6129113723 | ||
|
|
a37e4c74de | ||
|
|
4e3edded07 | ||
|
|
146ab25f66 | ||
|
|
eb69bb2a78 | ||
|
|
fc089a299e | ||
|
|
0509c7b35a | ||
|
|
f74ff5610d | ||
|
|
d0e136fb74 | ||
|
|
a5b5322b54 | ||
|
|
9745ae9bb9 | ||
|
|
e692e854cb | ||
|
|
064b7bcf28 | ||
|
|
13c76a80e7 | ||
|
|
e08b40758a | ||
|
|
90b619f4b9 | ||
|
|
34ac1cc22c | ||
|
|
3eb1fe8b46 | ||
|
|
ef99dbc9cb | ||
|
|
49921fe4ef | ||
|
|
04d08ea43b | ||
|
|
8a900aab52 | ||
|
|
12fe73a6dd | ||
|
|
ca98bfda97 | ||
|
|
96829b2e5a | ||
|
|
418ec3dc67 | ||
|
|
6a8624e36d | ||
|
|
fee641af8b | ||
|
|
197e2f01f9 | ||
|
|
1553c302e9 | ||
|
|
1cac684df3 | ||
|
|
1873ed92fa | ||
|
|
16eaf1182d | ||
|
|
f3ad225294 | ||
|
|
195da695ec | ||
|
|
fc309a340f | ||
|
|
2b79a428c0 | ||
|
|
3741147c33 | ||
|
|
1bb4b3f9a3 | ||
|
|
f592aa3738 | ||
|
|
6410efde3c | ||
|
|
13901ed852 | ||
|
|
909f35785e | ||
|
|
c08d216567 | ||
|
|
bffdc53167 | ||
|
|
2847334b62 | ||
|
|
9a6f088809 | ||
|
|
4fa97a15a2 | ||
|
|
e852d78e19 | ||
|
|
53ff2d5bf4 | ||
|
|
10d0a0594a | ||
|
|
17b33b98a3 |
30
debian/changelog
vendored
Normal file
30
debian/changelog
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
umtrx (1.0.5) trusty; urgency=low
|
||||
|
||||
* host: disable umtrx_fifo_ctrl cache of spi config
|
||||
* host: Fix getters in umtrx_property_tree.py.
|
||||
* debian: added firmware to package and umtrx_firmware script to handle it
|
||||
* fpga: created axi stream controled spi core
|
||||
* fpga: use axi stream spi core (still single dest)
|
||||
* fpga: connect both spi settings drivers
|
||||
* fpga: simplify spi setting regs with generate loop
|
||||
* fpga: updated 4x ddc image for spi work
|
||||
|
||||
-- Kirill Zakharenko <earwin@gmail.com> Mon, 23 Nov 2015 15:51:56 +0300
|
||||
|
||||
umtrx (1.0.4) unstable; urgency=low
|
||||
|
||||
* Do not add 'g' to a git id when creating a version string.
|
||||
* Proper debianization.
|
||||
* Add ability to set diversity switches position from UHD args.
|
||||
* By default route each Rx channel to it's own antenna.
|
||||
* JSON API to question/control property tree of a running UHD app. Useful for querying sensors and for debugging purposes.
|
||||
* Python utility to query VSWR from a running UHD app in real time using JSON API.
|
||||
* Fix DC and IQ calibration utilities.
|
||||
|
||||
-- Alexander Chemeris <Alexander.Chemeris@fairwaves.co> Tue, 21 Jul 2015 18:51:56 -0400
|
||||
|
||||
umtrx (1.0.3) unstable; urgency=low
|
||||
|
||||
* Created debian control files for 1.0.3 release of umtrx
|
||||
|
||||
-- Josh Blum <josh@pothosware.com> Sat, 20 Jun 2015 16:31:24 -0700
|
||||
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
@@ -0,0 +1 @@
|
||||
9
|
||||
33
debian/control
vendored
Normal file
33
debian/control
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
Source: umtrx
|
||||
Section: libs
|
||||
Priority: optional
|
||||
Maintainer: Josh Blum <josh@pothosware.com>
|
||||
Build-Depends:
|
||||
debhelper (>= 9.0.0),
|
||||
cmake (>= 2.8),
|
||||
libboost-all-dev,
|
||||
libuhd-dev (>= 3.7)
|
||||
Standards-Version: 3.9.5
|
||||
Homepage: http://umtrx.org/
|
||||
Vcs-Git: https://github.com/fairwaves/UHD-Fairwaves.git
|
||||
Vcs-Browser: https://github.com/fairwaves/UHD-Fairwaves
|
||||
|
||||
Package: umtrx
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Pre-Depends: multiarch-support, ${misc:Pre-Depends}
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, uhd-umtrx
|
||||
Conflicts: umtrx-uhd
|
||||
Replaces: umtrx-uhd
|
||||
Recommends: python
|
||||
Description: Fairwaves UmTRX driver - runtime utilities
|
||||
The industrial grade dual-channel wide-band SDR transceiver.
|
||||
|
||||
Package: uhd-umtrx
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Conflicts: umtrx-uhd
|
||||
Replaces: umtrx-uhd
|
||||
Description: Fairwaves UmTRX driver - UHD plugin module
|
||||
The industrial grade dual-channel wide-band SDR transceiver.
|
||||
12
debian/copyright
vendored
Normal file
12
debian/copyright
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: umtrx
|
||||
Source: https://github.com/fairwaves/UHD-Fairwaves
|
||||
|
||||
Files: *
|
||||
Copyright:
|
||||
Copyright 2012-2015 Fairwaves LLC
|
||||
Copyright 2010-2012 Ettus Research LLC
|
||||
License: GPL-3
|
||||
On Debian systems, the full text of the GNU General Public
|
||||
License version 3 can be found in the file
|
||||
`/usr/share/common-licenses/GPL-3'.
|
||||
1
debian/docs
vendored
Normal file
1
debian/docs
vendored
Normal file
@@ -0,0 +1 @@
|
||||
README
|
||||
18
debian/rules
vendored
Executable file
18
debian/rules
vendored
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
|
||||
DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
|
||||
export DEB_HOST_MULTIARCH
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
# This has to be exported to make some magic below work.
|
||||
export DH_OPTIONS
|
||||
|
||||
|
||||
%:
|
||||
dh $@ --buildsystem=cmake --parallel --sourcedirectory=host
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure -- -DLIB_SUFFIX="/$(DEB_HOST_MULTIARCH)"
|
||||
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@@ -0,0 +1 @@
|
||||
3.0 (native)
|
||||
1
debian/uhd-umtrx.install
vendored
Normal file
1
debian/uhd-umtrx.install
vendored
Normal file
@@ -0,0 +1 @@
|
||||
usr/lib/*/uhd/modules/
|
||||
2
debian/umtrx.install
vendored
Normal file
2
debian/umtrx.install
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
usr/bin
|
||||
images/u2plus_umtrx_v2.bin images/umtrx_txrx_uhd.bin usr/share/umtrx/firmware
|
||||
@@ -58,5 +58,6 @@ gpio_atr.v \
|
||||
user_settings.v \
|
||||
settings_fifo_ctrl.v \
|
||||
simple_spi_core.v \
|
||||
axis_spi_core.v \
|
||||
simple_i2c_core.v \
|
||||
))
|
||||
|
||||
243
fpga/control_lib/axis_spi_core.v
Normal file
243
fpga/control_lib/axis_spi_core.v
Normal file
@@ -0,0 +1,243 @@
|
||||
//
|
||||
// Copyright 2012 Ettus Research LLC
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
// Simple SPI core, the simplest, yet complete spi core I can think of
|
||||
|
||||
// Settings register controlled.
|
||||
// 2 settings regs, control and data
|
||||
// 1 32-bit readback and status signal
|
||||
|
||||
// Settings reg map:
|
||||
//
|
||||
// BASE+0 divider setting
|
||||
// bits [15:0] spi clock divider
|
||||
//
|
||||
// BASE+1 configuration input
|
||||
// bits [23:0] slave select, bit0 = slave0 enabled
|
||||
// bits [29:24] num bits (1 through 32)
|
||||
// bit [30] data input edge = in data bit latched on rising edge of clock
|
||||
// bit [31] data output edge = out data bit latched on rising edge of clock
|
||||
//
|
||||
// BASE+2 input data
|
||||
// Writing this register begins a spi transaction.
|
||||
// Bits are latched out from bit 0.
|
||||
// Therefore, load this register in reverse.
|
||||
//
|
||||
// Readback
|
||||
// Bits are latched into bit 0.
|
||||
// Therefore, data will be in-order.
|
||||
|
||||
module axis_spi_core
|
||||
#(
|
||||
//set to 1 for ILA
|
||||
parameter DEBUG = 0,
|
||||
|
||||
//tdest width for number of core users
|
||||
parameter DESTW = 1,
|
||||
|
||||
//width of serial enables (up to 24 is possible)
|
||||
parameter WIDTH = 8,
|
||||
|
||||
//idle state of the spi clock
|
||||
parameter CLK_IDLE = 0,
|
||||
|
||||
//idle state of the serial enables
|
||||
parameter SEN_IDLE = 24'hffffff
|
||||
)
|
||||
(
|
||||
//clock and synchronous reset
|
||||
input clock, input reset,
|
||||
|
||||
//configuration settings bus
|
||||
input [DESTW-1:0] CONFIG_tdest,
|
||||
input [79:0] CONFIG_tdata,
|
||||
input CONFIG_tvalid,
|
||||
output CONFIG_tready,
|
||||
|
||||
//32-bit data readback
|
||||
output reg [DESTW-1:0] READBACK_tdest,
|
||||
output [31:0] READBACK_tdata,
|
||||
output READBACK_tvalid,
|
||||
input READBACK_tready,
|
||||
|
||||
//spi interface, slave selects, clock, data in, data out
|
||||
output [WIDTH-1:0] sen,
|
||||
output sclk,
|
||||
output mosi,
|
||||
input miso
|
||||
);
|
||||
|
||||
//state
|
||||
localparam WAIT_CONFIG = 0;
|
||||
localparam PRE_IDLE = 1;
|
||||
localparam CLK_REG = 2;
|
||||
localparam CLK_INV = 3;
|
||||
localparam POST_IDLE = 4;
|
||||
localparam IDLE_SEN = 5;
|
||||
localparam WAIT_READBACK = 6;
|
||||
reg [2:0] state;
|
||||
|
||||
//configuration settings
|
||||
reg [15:0] sclk_divider;
|
||||
reg [23:0] slave_select;
|
||||
reg [5:0] num_bits;
|
||||
reg datain_edge, dataout_edge;
|
||||
|
||||
//output ready/valid signals
|
||||
assign CONFIG_tready = (state == WAIT_CONFIG);
|
||||
assign READBACK_tvalid = (state == WAIT_READBACK);
|
||||
|
||||
//serial clock either idles or is in one of two clock states
|
||||
reg sclk_reg;
|
||||
assign sclk = sclk_reg;
|
||||
|
||||
//serial enables either idle or enabled based on state
|
||||
wire sen_is_idle = (state == WAIT_CONFIG) || (state == IDLE_SEN);
|
||||
wire [23:0] sen24 = (sen_is_idle)? SEN_IDLE : (SEN_IDLE ^ slave_select);
|
||||
reg [WIDTH-1:0] sen_reg;
|
||||
always @(posedge clock) sen_reg <= sen24[WIDTH-1:0];
|
||||
assign sen = sen_reg;
|
||||
|
||||
//data output shift register
|
||||
reg [31:0] dataout_reg;
|
||||
wire [31:0] dataout_next = {dataout_reg[30:0], 1'b0};
|
||||
assign mosi = dataout_reg[31];
|
||||
|
||||
//data input shift register
|
||||
reg [31:0] datain_reg;
|
||||
wire [31:0] datain_next = {datain_reg[30:0], miso};
|
||||
assign READBACK_tdata = datain_reg;
|
||||
|
||||
//counter for spi clock
|
||||
reg [15:0] sclk_counter;
|
||||
wire sclk_counter_done = (sclk_counter == sclk_divider);
|
||||
wire [15:0] sclk_counter_next = (sclk_counter_done)? 0 : sclk_counter + 1;
|
||||
|
||||
//counter for latching bits miso/mosi
|
||||
reg [6:0] bit_counter;
|
||||
wire [6:0] bit_counter_next = bit_counter + 1;
|
||||
wire bit_counter_done = (bit_counter_next == num_bits);
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
state <= WAIT_CONFIG;
|
||||
sclk_reg <= CLK_IDLE;
|
||||
end
|
||||
else begin
|
||||
case (state)
|
||||
|
||||
WAIT_CONFIG: begin
|
||||
if (CONFIG_tvalid && CONFIG_tready) begin
|
||||
state <= PRE_IDLE;
|
||||
end
|
||||
{sclk_divider, dataout_edge, datain_edge, num_bits, slave_select, dataout_reg} <= CONFIG_tdata;
|
||||
READBACK_tdest <= CONFIG_tdest;
|
||||
sclk_counter <= 0;
|
||||
bit_counter <= 0;
|
||||
sclk_reg <= CLK_IDLE;
|
||||
end
|
||||
|
||||
PRE_IDLE: begin
|
||||
if (sclk_counter_done) state <= CLK_REG;
|
||||
sclk_counter <= sclk_counter_next;
|
||||
sclk_reg <= CLK_IDLE;
|
||||
end
|
||||
|
||||
CLK_REG: begin
|
||||
if (sclk_counter_done) begin
|
||||
state <= CLK_INV;
|
||||
if (datain_edge != CLK_IDLE) datain_reg <= datain_next;
|
||||
if (dataout_edge != CLK_IDLE && bit_counter != 0) dataout_reg <= dataout_next;
|
||||
sclk_reg <= ~CLK_IDLE; //transition to rising when CLK_IDLE == 0
|
||||
end
|
||||
sclk_counter <= sclk_counter_next;
|
||||
end
|
||||
|
||||
CLK_INV: begin
|
||||
if (sclk_counter_done) begin
|
||||
state <= (bit_counter_done)? POST_IDLE : CLK_REG;
|
||||
bit_counter <= bit_counter_next;
|
||||
if (datain_edge == CLK_IDLE) datain_reg <= datain_next;
|
||||
if (dataout_edge == CLK_IDLE && ~bit_counter_done) dataout_reg <= dataout_next;
|
||||
sclk_reg <= CLK_IDLE; //transition to falling when CLK_IDLE == 0
|
||||
end
|
||||
sclk_counter <= sclk_counter_next;
|
||||
end
|
||||
|
||||
POST_IDLE: begin
|
||||
if (sclk_counter_done) state <= IDLE_SEN;
|
||||
sclk_counter <= sclk_counter_next;
|
||||
sclk_reg <= CLK_IDLE;
|
||||
end
|
||||
|
||||
IDLE_SEN: begin
|
||||
if (sclk_counter_done) state <= WAIT_READBACK;
|
||||
sclk_counter <= sclk_counter_next;
|
||||
sclk_reg <= CLK_IDLE;
|
||||
end
|
||||
|
||||
WAIT_READBACK: begin
|
||||
if (READBACK_tready && READBACK_tvalid) begin
|
||||
state <= WAIT_CONFIG;
|
||||
end
|
||||
end
|
||||
|
||||
default: state <= WAIT_CONFIG;
|
||||
|
||||
endcase //state
|
||||
end
|
||||
end
|
||||
|
||||
/*******************************************************************
|
||||
* Debug
|
||||
******************************************************************/
|
||||
generate
|
||||
if (DEBUG == 1) begin
|
||||
wire [35:0] CONTROL0;
|
||||
chipscope_icon chipscope_icon
|
||||
(
|
||||
.CONTROL0(CONTROL0)
|
||||
);
|
||||
wire [255:0] DATA;
|
||||
wire [7:0] TRIG0;
|
||||
chipscope_ila chipscope_ila
|
||||
(
|
||||
.CONTROL(CONTROL0),
|
||||
.CLK(clock),
|
||||
.DATA(DATA),
|
||||
.TRIG0(TRIG0)
|
||||
);
|
||||
assign TRIG0 =
|
||||
{
|
||||
4'b0,
|
||||
CONFIG_tvalid, CONFIG_tready,
|
||||
READBACK_tvalid, READBACK_tready
|
||||
};
|
||||
|
||||
assign DATA[79:0] = CONFIG_tdata;
|
||||
assign DATA[111:80] = READBACK_tdata;
|
||||
|
||||
assign DATA[112] = CONFIG_tvalid;
|
||||
assign DATA[113] = CONFIG_tready;
|
||||
assign DATA[114] = READBACK_tvalid;
|
||||
assign DATA[115] = READBACK_tready;
|
||||
|
||||
assign DATA[127:120] = state;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule //axis_spi_core
|
||||
@@ -23,6 +23,8 @@ module s6_icap_wb
|
||||
input cyc_i, input stb_i, input we_i, output reg ack_o,
|
||||
input [31:0] dat_i, output reg[31:0] dat_o);//, output [31:0] debug_out);
|
||||
|
||||
reg slow_clk_icap;
|
||||
always @(posedge clk_icap) slow_clk_icap <= ~slow_clk_icap;
|
||||
|
||||
wire BUSY, CE, WRITE;
|
||||
wire[31:0] s1_dat_i;
|
||||
@@ -36,7 +38,7 @@ module s6_icap_wb
|
||||
fifo_xlnx_16x40_2clk icap_fifo
|
||||
(.rst(reset),
|
||||
.wr_clk(clk), .din(dat_i), .wr_en(we_i & stb_i & ~ack_o & ~full), .full(full),
|
||||
.rd_clk(clk_icap), .dout(s1_dat_i), .rd_en(~empty), .empty(empty));
|
||||
.rd_clk(slow_clk_icap), .dout(s1_dat_i), .rd_en(~empty), .empty(empty));
|
||||
|
||||
assign WRITE = empty;
|
||||
assign CE = empty;
|
||||
@@ -45,7 +47,7 @@ module s6_icap_wb
|
||||
(.BUSY(BUSY), // Busy output
|
||||
.O(s1_dat_o[15:0]), // 16-bit data output
|
||||
.CE(CE), // Clock enable input
|
||||
.CLK(clk_icap), // Clock input
|
||||
.CLK(slow_clk_icap), // Clock input
|
||||
.I(s1_dat_i[15:0]), // 16-bit data input
|
||||
.WRITE(WRITE) // Write input
|
||||
);
|
||||
|
||||
@@ -124,20 +124,13 @@ module simple_gemac_wrapper
|
||||
// TX FIFO Chain
|
||||
wire tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy;
|
||||
wire [7:0] tx_ll_data;
|
||||
wire [35:0] tx_f36_data_int0, tx_f36_data_int1, tx_f36_data_int2;
|
||||
wire tx_f36_src_rdy_int0, tx_f36_dst_rdy_int0, tx_f36_src_rdy_int1, tx_f36_dst_rdy_int1, tx_f36_src_rdy_int2, tx_f36_dst_rdy_int2;
|
||||
wire [35:0] tx_f36_data_int1, tx_f36_data_int2;
|
||||
wire tx_f36_src_rdy_int1, tx_f36_dst_rdy_int1, tx_f36_src_rdy_int2, tx_f36_dst_rdy_int2;
|
||||
|
||||
axi_fifo_2clk #(.WIDTH(36), .SIZE(0)) tx_2clk_fifo
|
||||
(.i_aclk(sys_clk), .i_tdata(tx_f36_data), .i_tvalid(tx_f36_src_rdy), .i_tready(tx_f36_dst_rdy),
|
||||
.o_aclk(tx_clk), .o_tdata(tx_f36_data_int0), .o_tvalid(tx_f36_src_rdy_int0), .o_tready(tx_f36_dst_rdy_int0),
|
||||
.reset(reset));
|
||||
|
||||
axi_packet_gate #(.WIDTH(36), .SIZE(TXFIFOSIZE)) fully_buffer_outgoing_eth_pkts
|
||||
(
|
||||
.clk(tx_clk), .reset(reset), .clear(0),
|
||||
.i_tdata(tx_f36_data_int0), .i_tvalid(tx_f36_src_rdy_int0), .i_tready(tx_f36_dst_rdy_int0), .i_tlast(tx_f36_data_int0[33]), .i_terror(0),
|
||||
.o_tdata(tx_f36_data_int1), .o_tvalid(tx_f36_src_rdy_int1), .o_tready(tx_f36_dst_rdy_int2), .o_tlast()
|
||||
);
|
||||
fifo_2clock_cascade #(.WIDTH(36), .SIZE(TXFIFOSIZE)) tx_2clk_fifo
|
||||
(.wclk(sys_clk), .datain(tx_f36_data), .src_rdy_i(tx_f36_src_rdy), .dst_rdy_o(tx_f36_dst_rdy), .space(),
|
||||
.rclk(tx_clk), .dataout(tx_f36_data_int1), .src_rdy_o(tx_f36_src_rdy_int1), .dst_rdy_i(tx_f36_dst_rdy_int1), .occupied(),
|
||||
.arst(reset));
|
||||
|
||||
ethtx_realign ethtx_realign
|
||||
(.clk(tx_clk), .reset(tx_reset), .clear(clear),
|
||||
|
||||
@@ -81,7 +81,7 @@ SYNTHESIZE_PROPERTIES = \
|
||||
"Use Clock Enable" Auto \
|
||||
"Use Synchronous Reset" Auto \
|
||||
"Use Synchronous Set" Auto \
|
||||
"Verilog Macros" "LVDS=1 | NO_SERDES=1 | UMTRX=1 | LMS602D_FRONTEND=1 | SPARTAN6=1 | LMS_DSP=1"
|
||||
"Verilog Macros" "LVDS=1 | NO_SERDES=1 | UMTRX=1 | LMS602D_FRONTEND=1 | SPARTAN6=1 | LMS_DSP=1 | NUMDDC=2 | NUMDUC=2"
|
||||
|
||||
TRANSLATE_PROPERTIES = \
|
||||
"Macro Search Path" "$(shell pwd)/../../coregen/"
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
##################################################
|
||||
# Project Setup
|
||||
##################################################
|
||||
TOP_MODULE = u2plus_umtrx
|
||||
BUILD_DIR = $(abspath build$(ISE)_UmTRX)
|
||||
TOP_MODULE = u2plus_umtrx_v2
|
||||
BUILD_DIR = $(abspath build$(ISE)_UmTRXv2_4DDC)
|
||||
|
||||
##################################################
|
||||
# Include other makefiles
|
||||
@@ -48,8 +48,20 @@ simulator "ISE Simulator (VHDL/Verilog)" \
|
||||
TOP_SRCS = \
|
||||
capture_ddrlvds.v \
|
||||
umtrx_core.v \
|
||||
u2plus_umtrx.v \
|
||||
u2plus_umtrx.ucf
|
||||
umtrx_tx_chain.v \
|
||||
umtrx_rx_chain.v \
|
||||
umtrx_router.v \
|
||||
umtrx_packet_dispatcher.v \
|
||||
coregen/chipscope_icon.v \
|
||||
coregen/chipscope_icon.xco \
|
||||
coregen/chipscope_ila.v \
|
||||
coregen/chipscope_ila.xco \
|
||||
coregen/fifo_short_2clk.v \
|
||||
coregen/fifo_short_2clk.xco \
|
||||
coregen/fifo_4k_2clk.v \
|
||||
coregen/fifo_4k_2clk.xco \
|
||||
u2plus_umtrx_v2.v \
|
||||
u2plus_umtrx_v2.ucf
|
||||
|
||||
SOURCES = $(abspath $(TOP_SRCS)) $(FIFO_SRCS) \
|
||||
$(CONTROL_LIB_SRCS) $(SDR_LIB_SRCS) $(SERDES_SRCS) \
|
||||
@@ -69,7 +81,7 @@ SYNTHESIZE_PROPERTIES = \
|
||||
"Use Clock Enable" Auto \
|
||||
"Use Synchronous Reset" Auto \
|
||||
"Use Synchronous Set" Auto \
|
||||
"Verilog Macros" "LVDS=1 | NO_SERDES=1 | UMTRX=1 | LMS602D_FRONTEND=1 | SPARTAN6=1 | LMS_DSP=1"
|
||||
"Verilog Macros" "LVDS=1 | NO_SERDES=1 | UMTRX=1 | LMS602D_FRONTEND=1 | SPARTAN6=1 | LMS_DSP=1 | NUMDDC=4 | NUMDUC=0"
|
||||
|
||||
TRANSLATE_PROPERTIES = \
|
||||
"Macro Search Path" "$(shell pwd)/../../coregen/"
|
||||
@@ -1,5 +1,5 @@
|
||||
defparam bootram.RAM0.INIT_00=256'h00000000_00000000_00000000_ddd80400_3a0b0b80_80eb940c_82700b0b_0b0b0b0b;
|
||||
defparam bootram.RAM0.INIT_01=256'h00000000_00000000_00000000_800c0400_880c840c_80dea22d_88080b0b_80088408;
|
||||
defparam bootram.RAM0.INIT_00=256'h00000000_00000000_00000000_dfcb0400_3a0b0b80_80eeb40c_82700b0b_0b0b0b0b;
|
||||
defparam bootram.RAM0.INIT_01=256'h00000000_00000000_00000000_800c0400_880c840c_80e0952d_88080b0b_80088408;
|
||||
defparam bootram.RAM0.INIT_02=256'h00000000_00000000_04000000_ffff0652_832b2a83_81058205_72830609_71fd0608;
|
||||
defparam bootram.RAM0.INIT_03=256'h83a70400_0b0b0b0b_7383ffff_2b2b0906_05820583_83060981_83ffff73_71fd0608;
|
||||
defparam bootram.RAM0.INIT_04=256'h00000000_00000000_53510400_070a8106_73097306_09060906_72057373_72098105;
|
||||
@@ -18,431 +18,431 @@ defparam bootram.RAM0.INIT_10=256'h00000000_00000000_00000000_00000000_00000000_
|
||||
defparam bootram.RAM0.INIT_11=256'h00000000_00000000_00000000_00000000_00000000_04000000_05055351_72720981;
|
||||
defparam bootram.RAM0.INIT_12=256'h00000000_00000000_00000000_00000000_00000000_07535104_73730906_72097206;
|
||||
defparam bootram.RAM0.INIT_13=256'h00000000_00000000_04000000_81ff0652_1010102a_81058305_72830609_71fc0608;
|
||||
defparam bootram.RAM0.INIT_14=256'h00000000_00000000_88aa0400_060b0b0b_10100508_80738306_0b0b80eb_71fc0608;
|
||||
defparam bootram.RAM0.INIT_15=256'h00000000_0c510400_0c840c80_80085688_f92d5050_0b0b80d4_88087575_80088408;
|
||||
defparam bootram.RAM0.INIT_16=256'h00000000_0c510400_0c840c80_80085688_ab2d5050_0b0b80d6_88087575_80088408;
|
||||
defparam bootram.RAM0.INIT_14=256'h00000000_00000000_88aa0400_060b0b0b_10100508_a0738306_0b0b80ee_71fc0608;
|
||||
defparam bootram.RAM0.INIT_15=256'h00000000_0c510400_0c840c80_80085688_ec2d5050_0b0b80d6_88087575_80088408;
|
||||
defparam bootram.RAM0.INIT_16=256'h00000000_0c510400_0c840c80_80085688_9e2d5050_0b0b80d8_88087575_80088408;
|
||||
defparam bootram.RAM0.INIT_17=256'h04000000_07515151_05ff0506_73097274_70547106_8106ff05_0509060a_72097081;
|
||||
defparam bootram.RAM0.INIT_18=256'h51040000_06075151_7405ff05_06730972_05705471_098106ff_0509060a_72097081;
|
||||
defparam bootram.RAM0.INIT_19=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_05ff0504;
|
||||
defparam bootram.RAM0.INIT_1A=256'h00000000_00000000_00000000_00000000_00000000_51040000_80eb900c_810b0b0b;
|
||||
defparam bootram.RAM0.INIT_1A=256'h00000000_00000000_00000000_00000000_00000000_51040000_80eeb00c_810b0b0b;
|
||||
defparam bootram.RAM0.INIT_1B=256'h00000000_00000000_00000000_00000000_00000000_00000000_04000000_71810552;
|
||||
defparam bootram.RAM0.INIT_1C=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM0.INIT_1D=256'h00000000_00000000_00000000_00000000_00000000_04000000_10100552_02840572;
|
||||
defparam bootram.RAM0.INIT_1E=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM0.INIT_1F=256'h00000000_00000000_00000000_00000000_00000000_020d0400_05715351_717105ff;
|
||||
defparam bootram.RAM0.INIT_20=256'h10101010_10101010_10101010_10101010_10101010_10101010_d69f3f04_82813f80;
|
||||
defparam bootram.RAM0.INIT_20=256'h10101010_10101010_10101010_10101010_10101010_10101010_d8923f04_82813f80;
|
||||
defparam bootram.RAM0.INIT_21=256'hfc060c51_102b0772_83051010_06098105_ff067383_51047381_10101053_10101010;
|
||||
defparam bootram.RAM0.INIT_22=256'h51535104_72ed3851_0a100a53_71105272_09720605_8106ff05_72728072_51043c04;
|
||||
defparam bootram.RAM0.INIT_23=256'h800b80eb_f00c82a0_0b0b80eb_8380800b_822ebd38_80eb9408_802ea438_80eb9008;
|
||||
defparam bootram.RAM0.INIT_24=256'h0b80ebf4_80808280_ebf00cf8_0b0b0b80_808080a4_f80c04f8_800b80eb_f40c8290;
|
||||
defparam bootram.RAM0.INIT_25=256'h940b80eb_80c0a880_80ebf00c_8c0b0b0b_80c0a880_ebf80c04_84800b80_0cf88080;
|
||||
defparam bootram.RAM0.INIT_26=256'h70085252_80eb9c08_5170a738_80ebfc33_04ff3d0d_80ebf80c_80ded40b_f40c0b0b;
|
||||
defparam bootram.RAM0.INIT_27=256'hfc34833d_810b80eb_5270ee38_08700852_2d80eb9c_eb9c0c70_38841280_70802e94;
|
||||
defparam bootram.RAM0.INIT_28=256'h38823d0d_09810685_800b802e_0b0b0b0b_802e8e38_80ebec08_3d0d0b0b_0d040480;
|
||||
defparam bootram.RAM0.INIT_29=256'h0b81e088_80ce3881_0d685a79_0404ee3d_3f823d0d_0b0bf5d4_ebec510b_040b0b80;
|
||||
defparam bootram.RAM0.INIT_2A=256'h7981e188_81e1800c_0c890a0b_7981e598_81e5940c_e48c0c79_880c7981_0c7981e4;
|
||||
defparam bootram.RAM0.INIT_2B=256'h81e2cc0c_0c890a0b_7981e290_81e2880c_0c890a0b_7981e2c8_81e2c00c_0c890a0b;
|
||||
defparam bootram.RAM0.INIT_2C=256'ha8953f89_0553425a_54973d84_08933d70_8238881a_8b6a2781_0c818839_7981e2d4;
|
||||
defparam bootram.RAM0.INIT_2D=256'h7b34811c_5b5b7933_7b1d7f1d_3d415e5c_0b883d99_5b5f4080_0284057b_923f8008;
|
||||
defparam bootram.RAM0.INIT_23=256'h800b80ef_900c82a0_0b0b80ef_8380800b_822ebd38_80eeb408_802ea438_80eeb008;
|
||||
defparam bootram.RAM0.INIT_24=256'h0b80ef94_80808280_ef900cf8_0b0b0b80_808080a4_980c04f8_800b80ef_940c8290;
|
||||
defparam bootram.RAM0.INIT_25=256'h940b80ef_80c0a880_80ef900c_8c0b0b0b_80c0a880_ef980c04_84800b80_0cf88080;
|
||||
defparam bootram.RAM0.INIT_26=256'h70085252_80eebc08_5170a738_80ef9c33_04ff3d0d_80ef980c_80e0c40b_940c0b0b;
|
||||
defparam bootram.RAM0.INIT_27=256'h9c34833d_810b80ef_5270ee38_08700852_2d80eebc_eebc0c70_38841280_70802e94;
|
||||
defparam bootram.RAM0.INIT_28=256'h38823d0d_09810685_800b802e_0b0b0b0b_802e8e38_80ef8c08_3d0d0b0b_0d040480;
|
||||
defparam bootram.RAM0.INIT_29=256'h0b81e088_80ce3881_0d685a79_0404ee3d_3f823d0d_0b0bf5d4_ef8c510b_040b0b80;
|
||||
defparam bootram.RAM0.INIT_2A=256'h7981e180_81e0f80c_0c890a0b_7981e598_81e5940c_e48c0c79_880c7981_0c7981e4;
|
||||
defparam bootram.RAM0.INIT_2B=256'h81e2e80c_0c890a0b_7981e2a0_81e2980c_0c890a0b_7981e1d0_81e1c80c_0c890a0b;
|
||||
defparam bootram.RAM0.INIT_2C=256'ha9b43f89_0553425a_54973d84_08933d70_8238881a_8b6a2781_0c818839_7981e2f0;
|
||||
defparam bootram.RAM0.INIT_2D=256'h7b34811c_5b5b7933_7b1d7f1d_3d415e5c_0b883d99_5b5f4080_0284057b_a83f8008;
|
||||
defparam bootram.RAM0.INIT_2E=256'h7c26ed38_811c5c88_79337b34_7d055b5b_7b1d963d_901f5e5c_ef38800b_5c887c26;
|
||||
defparam bootram.RAM0.INIT_2F=256'h611d5b5b_805c7b1e_7c26ef38_811c5c86_79337b34_601d5b5b_5e5c7b1d_800b881f;
|
||||
defparam bootram.RAM0.INIT_30=256'h5a588379_84120859_3d0d686a_3d0d04ee_998b3f94_7c26ef38_811c5c86_79337b34;
|
||||
defparam bootram.RAM0.INIT_31=256'hf55778a3_94833f80_80ded851_75538c52_802e8c38_2e943875_0856758c_279c3877;
|
||||
defparam bootram.RAM0.INIT_32=256'h75922682_ff981756_8818085d_8c5ba05c_f03fa057_dfa85193_53a45280_268e3878;
|
||||
defparam bootram.RAM0.INIT_33=256'h5c8c1808_983980da_08085e82_88a13f80_0480d55c_05567508_2980e198_ae387584;
|
||||
defparam bootram.RAM0.INIT_34=256'h39921822_065f81f5_0883ffff_aab73f80_38828239_75822e91_812e8938_5e7d5675;
|
||||
defparam bootram.RAM0.INIT_35=256'h1808538c_18335490_57765596_2e833884_577580f2_18335682_81eb3995_51aa853f;
|
||||
defparam bootram.RAM0.INIT_36=256'h81b3398d_5f80d35c_fe3f8008_57765194_2e833881_57577577_0b971933_18085280;
|
||||
defparam bootram.RAM0.INIT_37=256'h19538c19_3370548e_94398d18_3f80c95c_52568bb4_538c1933_953dea05_18337054;
|
||||
defparam bootram.RAM0.INIT_38=256'h80c23875_56758526_1833ff05_80ff3994_05b50534_5c750284_c13f80c8_3352568c;
|
||||
defparam bootram.RAM0.INIT_39=256'h0ca23992_90180877_225fa939_5fae3976_08047608_08585675_e4058c19_842980e1;
|
||||
defparam bootram.RAM0.INIT_3A=256'h08710c56_80059019_842980ec_568e3976_05700840_2980ec80_9b397684_18227723;
|
||||
defparam bootram.RAM0.INIT_30=256'h5a588379_84120859_3d0d686a_3d0d04ee_9aaa3f94_7c26ef38_811c5c86_79337b34;
|
||||
defparam bootram.RAM0.INIT_31=256'hf55778a3_95983f80_80e0c851_75538c52_802e8c38_2e943875_0856758c_279c3877;
|
||||
defparam bootram.RAM0.INIT_32=256'h75922682_ff981756_8818085d_8c5ba05c_853fa057_e1985195_53a45280_268e3878;
|
||||
defparam bootram.RAM0.INIT_33=256'h5c8c1808_983980da_08085e82_88b73f80_0480d55c_05567508_2980e388_ae387584;
|
||||
defparam bootram.RAM0.INIT_34=256'h39921822_065f81f5_0883ffff_abd63f80_38828239_75822e91_812e8938_5e7d5675;
|
||||
defparam bootram.RAM0.INIT_35=256'h1808538c_18335490_57765596_2e833884_577580f2_18335682_81eb3995_51aba43f;
|
||||
defparam bootram.RAM0.INIT_36=256'h81b3398d_5f80d35c_933f8008_57765196_2e833881_57577577_0b971933_18085280;
|
||||
defparam bootram.RAM0.INIT_37=256'h19538c19_3370548e_94398d18_3f80c95c_52568bca_538c1933_953dea05_18337054;
|
||||
defparam bootram.RAM0.INIT_38=256'h80c23875_56758526_1833ff05_80ff3994_05b50534_5c750284_983f80c8_3352568d;
|
||||
defparam bootram.RAM0.INIT_39=256'h0ca23992_90180877_225fa939_5fae3976_08047608_08585675_d4058c19_842980e3;
|
||||
defparam bootram.RAM0.INIT_3A=256'h08710c56_a0059019_842980ef_568e3976_05700840_2980efa0_9b397684_18227723;
|
||||
defparam bootram.RAM0.INIT_3B=256'h3d790557_58771996_0b833d5a_dc055480_0855943d_cc5c8c18_39785e80_80d25cad;
|
||||
defparam bootram.RAM0.INIT_3C=256'h5a587719_800b833d_3ddc0554_5ca45594_38a439a0_887826ed_34811858_57753377;
|
||||
defparam bootram.RAM0.INIT_3D=256'h04fd3d0d_3f943d0d_805199fa_ed388380_58887826_77348118_57577533_963d7905;
|
||||
defparam bootram.RAM0.INIT_3E=256'h52725186_80c05372_e82e8438_a0537387_802e9838_90f33f73_dff45254_75705380;
|
||||
defparam bootram.RAM0.INIT_3F=256'h0d81fa3f_0d04fa3d_9a3f853d_52735186_a23f80c0_52735186_3f9039a0_ae3f9a87;
|
||||
defparam bootram.RAM1.INIT_00=256'hec9c0caa_3f800b80_d05190a5_8c5280e0_5190ae3f_5280e0b0_87933f89_80e09451;
|
||||
defparam bootram.RAM1.INIT_01=256'h518ef73f_da3f8008_86aa3f84_518edd3f_863f8008_82d63f84_3f84dd3f_ca3f83f4;
|
||||
defparam bootram.RAM1.INIT_02=256'h08518cf0_80845280_84bd3f83_5193993f_73528008_5483e83f_ce3f8008_869e3f84;
|
||||
defparam bootram.RAM1.INIT_03=256'h83808251_80c68252_5193d53f_52838084_df3f8ab2_80805193_8c935283_3f93a33f;
|
||||
defparam bootram.RAM1.INIT_04=256'heb3f8008_fc05518c_bf3f883d_ab9a3fad_3f8fbd51_fb3f8cdb_809251a3_93ca3f83;
|
||||
defparam bootram.RAM1.INIT_05=256'h80e0f452_ad388453_2e098106_7382fdee_05225555_7680088e_2e80c938_56800880;
|
||||
defparam bootram.RAM1.INIT_06=256'h85823f73_548ddb3f_94167052_518eea3f_3880e0fc_3f80089a_5180cac9_80089005;
|
||||
defparam bootram.RAM1.INIT_07=256'h84cb3f90_39fe3d0d_ea3fff9e_a3d03f8a_3f8bf83f_75519984_88397452_5183fd3f;
|
||||
defparam bootram.RAM1.INIT_08=256'h89e13f84_3f82ac51_805183f7_9b3f9f52_52805184_86f23f9f_3f8aa23f_b23f85f6;
|
||||
defparam bootram.RAM1.INIT_09=256'h5183d03f_3f905290_ac5189c7_83dd3f82_88528851_5189d43f_ea3f82ac_52845183;
|
||||
defparam bootram.RAM1.INIT_0A=256'h80e45189_5183b43f_3f9f529c_e45189ab_83c13f80_9f528051_ba3f8253_82ac5189;
|
||||
defparam bootram.RAM1.INIT_0B=256'h843d0d04_810b800c_5183983f_3f9f5281_9e5183bc_df389f52_53728025_9e3fff13;
|
||||
defparam bootram.RAM1.INIT_0C=256'h86559054_3f750856_e45188e7_80760c80_5188f03f_585680e4_e0807008_fa3d0d81;
|
||||
defparam bootram.RAM1.INIT_0D=256'h5281518f_88805382_86559054_518d8a3f_5280e1fc_aa3f8008_5281518f_88805381;
|
||||
defparam bootram.RAM1.INIT_0E=256'h57578170_3d0d787a_3d0d04fa_0b800c88_a5d83f81_518cf23f_5280e298_923f8008;
|
||||
defparam bootram.RAM1.INIT_0F=256'h2e833880_527181ff_80547133_802e8338_33525270_38721770_7276279e_56548053;
|
||||
defparam bootram.RAM1.INIT_10=256'h0b80eca4_fe3d0d81_883d0d04_5170800c_2e833881_07517080_df397474_55811353;
|
||||
defparam bootram.RAM1.INIT_11=256'hbd38810b_a4335574_3d0d80ec_3d0d04f9_c5bb3f84_eba45180_e2b85280_34865380;
|
||||
defparam bootram.RAM1.INIT_12=256'h9d388652_5574802e_0881ff06_b4c03f80_5280d051_70545682_8654873d_80eca434;
|
||||
defparam bootram.RAM1.INIT_13=256'ha40b800c_f03f80eb_a45180c4_755280eb_8d388653_ff065574_3f800881_7551fef3;
|
||||
defparam bootram.RAM1.INIT_14=256'hb938810b_a0335574_3d0d80ec_a00c04fb_b40880eb_a03480e2_810b80ec_893d0d04;
|
||||
defparam bootram.RAM1.INIT_15=256'h99388452_5574802e_0881ff06_b3e03f80_5280d051_fc05538c_8454873d_80eca034;
|
||||
defparam bootram.RAM1.INIT_16=256'h873d0d04_a00b800c_a00c80eb_387580eb_06557486_800881ff_51fe903f_873dfc05;
|
||||
defparam bootram.RAM1.INIT_17=256'h750880eb_802e8d38_ff065574_3f800881_d051b2a6_538c5280_56845475_fb3d0d77;
|
||||
defparam bootram.RAM1.INIT_18=256'h06077080_80eca808_73750671_3d0d7309_3d0d0480_74800c87_80eca034_a00c810b;
|
||||
defparam bootram.RAM1.INIT_19=256'h80ecac0c_08060770_7180ecac_09737506_803d0d73_823d0d04_e08c0c51_eca80c81;
|
||||
defparam bootram.RAM1.INIT_1A=256'h843d0d04_3f72800c_805181c7_74705353_04fe3d0d_0481af3f_51823d0d_81e0980c;
|
||||
defparam bootram.RAM1.INIT_1B=256'h5472802e_81ff0654_56743370_0d777956_0d04fb3d_b63f833d_52805181_ff3d0d8a;
|
||||
defparam bootram.RAM1.INIT_1C=256'h73528051_04ff3d0d_0c873d0d_39800b80_81913fe5_53765255_7481ff06_90388115;
|
||||
defparam bootram.RAM1.INIT_1D=256'h0c843d0d_3f800b80_725180e7_bd3f8a52_705253ff_0d747653_0d04fe3d_cd3f833d;
|
||||
defparam bootram.RAM1.INIT_1E=256'h823d0d04_ebac1234_8f053380_0d725102_0d04803d_dd3f833d_73528051_04ff3d0d;
|
||||
defparam bootram.RAM1.INIT_1F=256'h0d805380_0d04fe3d_5351833d_7022720c_80e2c005_80057510_a0298290_ff3d0d73;
|
||||
defparam bootram.RAM1.INIT_20=256'h3d0d04fc_25e53884_13538273_51ce3f81_13335272_3f80ebb0_527251c6_ebac1333;
|
||||
defparam bootram.RAM1.INIT_21=256'h8d527351_81068738_72812e09_ac143353_953880eb_2e098106_5654748a_3d0d7678;
|
||||
defparam bootram.RAM1.INIT_22=256'h3d0d74a0_3d0d04fe_8c150c86_2ef83874_08537280_05548414_29829080_de3f73a0;
|
||||
defparam bootram.RAM1.INIT_23=256'hff3d0d80_843d0d04_5372800c_38901208_70802e85_5252ff53_05881108_29829080;
|
||||
defparam bootram.RAM1.INIT_24=256'h81a8880c_5181800b_81a8840c_0c70882a_0681a880_227081ff_0c80ebb8_0b81a888;
|
||||
defparam bootram.RAM1.INIT_25=256'h90087086_863881a8_71802e81_53548151_97053355_78028805_fd3d0d76_833d0d04;
|
||||
defparam bootram.RAM1.INIT_26=256'h0870812a_0c81a890_0b81a890_8c0c8190_810781a8_f1387210_51515170_2a708106;
|
||||
defparam bootram.RAM1.INIT_27=256'h2eba3871_51517080_81325151_70810670_0870872a_3881a890_515170f1_70810651;
|
||||
defparam bootram.RAM1.INIT_28=256'h06515151_812a7081_a8900870_a8900c81_a0517081_812e8338_80e85171_802eb138;
|
||||
defparam bootram.RAM1.INIT_29=256'ha8900c70_80c00b81_81518839_1252cc39_055634ff_70747081_a88c0851_70f13881;
|
||||
defparam bootram.RAM1.INIT_2A=256'h81065151_70862a70_81a89008_33555354_88059705_0d767802_0d04fd3d_800c853d;
|
||||
defparam bootram.RAM1.INIT_2B=256'h90087081_900c81a8_517081a8_84388190_5171802e_8c0c81d0_721081a8_5170f138;
|
||||
defparam bootram.RAM1.INIT_2C=256'h802e80cf_51515170_70813251_2a708106_90087087_f13881a8_51515170_2a708106;
|
||||
defparam bootram.RAM1.INIT_2D=256'h81a89008_81a8900c_38905170_71812e83_0c80d051_3381a88c_80c53873_3871802e;
|
||||
defparam bootram.RAM1.INIT_2E=256'h5170802e_32515151_81067081_70872a70_81a89008_5170f138_81065151_70812a70;
|
||||
defparam bootram.RAM1.INIT_2F=256'h3d0d04fd_70800c85_900c8051_c00b81a8_518a3980_ffb73981_ff135354_8e388114;
|
||||
defparam bootram.RAM1.INIT_30=256'h7127f138_5181cb8f_70733151_81b8ac08_b8ac0852_259b3881_80537274_3d0d7554;
|
||||
defparam bootram.RAM1.INIT_31=256'h80840cff_0cef0b82_0b828080_880c81e0_ff0b8280_04ff3d0d_39853d0d_811353e2;
|
||||
defparam bootram.RAM1.INIT_32=256'h3d0d04fb_25f13883_11517080_05540cff_cf727084_5287519d_0c80f6ec_0b82808c;
|
||||
defparam bootram.RAM1.INIT_33=256'h06527180_55557476_0b80f6ec_52805381_71065851_82808c08_88087009_3d0d8280;
|
||||
defparam bootram.RAM1.INIT_34=256'h25dc3887_55538773_15761057_39811384_808c0c8f_712d7482_51730852_2e8f3872;
|
||||
defparam bootram.RAM1.INIT_35=256'h09828088_81722b70_75710c51_80f6ec05_38718429_7187269f_3d0d7352_3d0d04ff;
|
||||
defparam bootram.RAM1.INIT_36=256'hc40c5281_700881e0_92052274_ff3d0d02_3d0d0404_53515283_8280880c_08707206;
|
||||
defparam bootram.RAM1.INIT_37=256'hf338820b_5170802e_70840651_81b8a008_81e0c00c_3d0d810b_3d0d0480_e0c80c83;
|
||||
defparam bootram.RAM1.INIT_38=256'h08757190_3881b8a0_72802e93_81065452_b8a00870_fe3d0d81_823d0d04_81e0c00c;
|
||||
defparam bootram.RAM1.INIT_39=256'hf8db3fff_80e2cc51_802e8b38_06515271_812a7081_529a3971_53818080_2a710c53;
|
||||
defparam bootram.RAM1.INIT_3A=256'h38818080_70802ef2_c0065151_a0087080_3d0d81b8_3d0d0480_71800c84_a63f7252;
|
||||
defparam bootram.RAM1.INIT_3B=256'h70900651_81b8a008_e0c00c52_2b880781_05227090_3d0d028e_3d0d04ff_0b800c82;
|
||||
defparam bootram.RAM1.INIT_3C=256'hba51f7ad_802e8638_54805372_fd3d0d75_833d0d04_81e0c00c_f338840b_5170802e;
|
||||
defparam bootram.RAM1.INIT_3D=256'h33568211_0d778311_0d04fb3d_e638853d_53857327_a83f8113_335252ac_3f721470;
|
||||
defparam bootram.RAM1.INIT_3E=256'h029005bb_7c7e6163_04f63d0d_3f873d0d_d05180ed_535680e2_33547033_33558111;
|
||||
defparam bootram.RAM1.INIT_3F=256'h782d7630_7952ad51_802e8a38_258f3875_59577680_5b5f5d5b_709f2a51_05337030;
|
||||
defparam bootram.RAM2.INIT_00=256'h51b4b53f_3f775276_0851ffbd_b49d3f80_77527651_78548053_94387955_57777726;
|
||||
defparam bootram.RAM2.INIT_01=256'h04f73d0d_3f823d0d_3351f695_0d028b05_0d04803d_782d8c3d_dc053351_800880e2;
|
||||
defparam bootram.RAM2.INIT_02=256'h81ff0656_81d13876_5775802e_81ff0657_58783370_a0ae5c5a_84055208_8c3d7070;
|
||||
defparam bootram.RAM2.INIT_03=256'h7580e32e_f024a038_fb387580_80f02e80_33575975_38811970_810680db_75a52e09;
|
||||
defparam bootram.RAM2.INIT_04=256'h80f52eac_818b3975_2e80c638_397580e4_9e388195_75802e81_e3248a38_b9387580;
|
||||
defparam bootram.RAM2.INIT_05=256'h19831233_ec397784_2eba3880_397580f8_db3880f5_80f32e80_248b3875_387580f5;
|
||||
defparam bootram.RAM2.INIT_06=256'h39778419_54805390_8055a0ae_08525956_77841971_2d80da39_52755179_52595680;
|
||||
defparam bootram.RAM2.INIT_07=256'h54805390_8055a0ae_08525956_77841971_8a529239_ae548153_568055a0_71085259;
|
||||
defparam bootram.RAM2.INIT_08=256'h81055833_80527670_802e8e38_76335675_08595956_77841971_d03f9e39_527551fd;
|
||||
defparam bootram.RAM2.INIT_09=256'h0d81b8b4_0c04803d_0b81e5e4_3d0d048a_0b800c8b_fea33980_39811959_51792dec;
|
||||
defparam bootram.RAM2.INIT_0A=256'h05337298_0288059b_3d0d797b_3d0d04fc_70ef3882_06515151_81327081_08708c2a;
|
||||
defparam bootram.RAM2.INIT_0B=256'h5170802e_70810651_5272822a_71810a07_802e8638_56545570_81065555_2b7b0772;
|
||||
defparam bootram.RAM2.INIT_0C=256'h73517380_81e5ec0c_e5e80c70_a93f7181_2b5151ff_75317971_0a0752a0_86387182;
|
||||
defparam bootram.RAM2.INIT_0D=256'h53727427_54555580_0d76787a_0d04fc3d_800c863d_80085170_953f81b8_2e8938ff;
|
||||
defparam bootram.RAM2.INIT_0E=256'hff067290_387183ff_70802e8d_71902a51_5351ee39_05811555_15702273_8f387210;
|
||||
defparam bootram.RAM2.INIT_0F=256'h0880ecbc_f03f7670_ecb451b5_53755280_fd3d0d86_863d0d04_3971800c_2a0552ec;
|
||||
defparam bootram.RAM2.INIT_10=256'h38833d0d_708025f3_ff125252_720c8812_52895180_0d80ecc4_0d04ff3d_0c54853d;
|
||||
defparam bootram.RAM2.INIT_11=256'h52528972_81128812_742e8e38_70225472_ecc05252_53800b80_02960522_04fd3d0d;
|
||||
defparam bootram.RAM2.INIT_12=256'h08802e89_56c73f80_ff065358_7a7183ff_fa3d0d78_853d0d04_5170800c_25ee3880;
|
||||
defparam bootram.RAM2.INIT_13=256'h802e8f38_15555271_55730888_ecc05555_ecc40b80_39800880_84050cad_38768008;
|
||||
defparam bootram.RAM2.INIT_14=256'h86705493_04f13d0d_0c883d0d_23768414_fa3f7573_25eb38a2_54558975_81158814;
|
||||
defparam bootram.RAM2.INIT_15=256'h028405a2_b03f9080_dc0551b4_0552913d_53923d88_b4bf3f73_d6055254_3d53923d;
|
||||
defparam bootram.RAM2.INIT_16=256'h052380c0_028405aa_23818080_800b8c3d_05a60523_23800284_800b8b3d_0523818a;
|
||||
defparam bootram.RAM2.INIT_17=256'h80080284_51fdb73f_913de405_80538a52_685d665e_05ae0523_23800284_910b8d3d;
|
||||
defparam bootram.RAM2.INIT_18=256'hbe0523ac_80028405_0b913d23_ba052380_22028405_3d23963d_983d2290_05ae0523;
|
||||
defparam bootram.RAM2.INIT_19=256'h0b973d23_0d805b80_0d04e83d_d93f913d_840551a4_c0298298_05526980_53913dd4;
|
||||
defparam bootram.RAM2.INIT_1A=256'h80f20522_b38f3f02_3df80551_ecb4529a_3f865380_0551b39d_529a3df2_86539b3d;
|
||||
defparam bootram.RAM2.INIT_1B=256'ha13d0845_05436e44_c41143f0_800b9b3d_8008585a_e23f8008_e20523f7_02840580;
|
||||
defparam bootram.RAM2.INIT_1C=256'h7508701a_3d568458_fc06408c_3d088305_3d085fa3_5d6e5ea1_59845c90_a33d0846;
|
||||
defparam bootram.RAM2.INIT_1D=256'h83065473_2e9a3873_08547380_73760c75_75278438_565a5573_80713151_787c3190;
|
||||
defparam bootram.RAM2.INIT_1E=256'h51a3ab3f_16085276_75085394_51efee3f_3880e2f8_73802e88_08830654_8c389416;
|
||||
defparam bootram.RAM2.INIT_1F=256'h51f6e83f_5978822a_843880c0_3878bf26_8025ffac_19595777_570817ff_75708405;
|
||||
defparam bootram.RAM2.INIT_20=256'hca052380_02840580_94055a79_3d237f1f_8a800b94_6e404081_ea3d0d6b_9a3d0d04;
|
||||
defparam bootram.RAM2.INIT_21=256'h80d20523_80028405_79963d23_c080075a_05236980_840580ce_81808002_0b953d23;
|
||||
defparam bootram.RAM2.INIT_22=256'hd2052391_02840580_08095a79_fae03f80_3d70525c_538a5293_46684780_80ecbc08;
|
||||
defparam bootram.RAM2.INIT_23=256'h7a51f6b6_51f7c23f_3880e3a4_065a7992_800881ff_5e8ac83f_3d70535c_3d705398;
|
||||
defparam bootram.RAM2.INIT_24=256'h1f5b5b79_5c7b1d7c_90805380_94557b54_586b575d_5a6d5960_a939027f_3feddd3f;
|
||||
defparam bootram.RAM2.INIT_25=256'h3d238d3d_ae05228a_0d7f5802_0d04f73d_893f983d_26ef38fd_1c5c867c_337b3481;
|
||||
defparam bootram.RAM2.INIT_26=256'h3df80553_5588548b_2377567e_8405a605_3d238002_1857768b_a2052388_22028405;
|
||||
defparam bootram.RAM2.INIT_27=256'h0b8f3d34_b2052386_80028405_8e3d2390_3d0d810b_3d0d04ee_fe9e3f8b_91527d51;
|
||||
defparam bootram.RAM2.INIT_28=256'hcc3feaf3_ec0551af_0852943d_3f865380_0523eaa3_028405b6_b5053481_84028405;
|
||||
defparam bootram.RAM2.INIT_29=256'h3f800808_c93fead7_f60551b0_8052943d_bc3f8653_f20551af_0852943d_3f845380;
|
||||
defparam bootram.RAM2.INIT_2A=256'hf01b337a_1c5a80e2_53805b7a_05549086_55943de4_5780569c_59805880_43025c80;
|
||||
defparam bootram.RAM2.INIT_2B=256'h90862e09_225f5d7d_3d088e11_d93d0daa_943d0d04_38fbcb3f_867b26ef_34811b5b;
|
||||
defparam bootram.RAM2.INIT_2C=256'ha03f86ee_e3d451f5_38795280_799b268d_f2055b5b_3d088429_38901dac_8106829d;
|
||||
defparam bootram.RAM2.INIT_2D=256'h1b225a79_86d43884_2e098106_5a799080_38821b22_810686e2_79812e09_397a225a;
|
||||
defparam bootram.RAM2.INIT_2E=256'h853fa81d_70524088_b9389e1d_09810686_5a79812e_38861b22_810686c6_8c842e09;
|
||||
defparam bootram.RAM2.INIT_2F=256'h08868f38_80085c80_51acfe3f_3dffa805_ecbc52a9_43845380_fd3f8008_70525f87;
|
||||
defparam bootram.RAM2.INIT_30=256'h23841b33_0580fe05_1b220284_a13d2382_dc3f7a22_527951ad_5380ecb4_a73d5a86;
|
||||
defparam bootram.RAM2.INIT_31=256'h0551ada9_52a93de4_23865379_05818205_34820284_05818105_1b330284_a23d3485;
|
||||
defparam bootram.RAM2.INIT_32=256'h8c3f7953_527a51ad_8653981d_818e055b_ad9b3f02_ea05525a_7f53aa3d_3f847054;
|
||||
defparam bootram.RAM2.INIT_33=256'h587c575d_5a7c597c_f43f027c_527e51ac_5f86537a_803f9e3d_f40551ad_7f52a93d;
|
||||
defparam bootram.RAM2.INIT_34=256'h993f84ee_26ef38f9_1c5c867c_337b3481_1d5b5b79_537b1d7f_dc05547d_9c55a93d;
|
||||
defparam bootram.RAM2.INIT_35=256'hd1387988_09810684_5b60842e_8c2a435b_1d702270_84e43890_2e098106_397d9080;
|
||||
defparam bootram.RAM2.INIT_36=256'h5e865380_84b4387e_ff065f7e_1b2280ff_84c03886_2e098106_515a7985_2a708f06;
|
||||
defparam bootram.RAM2.INIT_37=256'haaf73f80_70535b5c_80ecbc54_901c6255_38815e7e_3f800883_1d51ab8d_e2f05282;
|
||||
defparam bootram.RAM2.INIT_38=256'h22ec1140_1b33821c_84b83f89_529c1d51_8138881d_7b802e84_5c7d8738_08833881;
|
||||
defparam bootram.RAM2.INIT_39=256'h5d42407d_8411225d_7a08a41f_388c1b08_810683de_7f912e09_2e81bb38_5d407f81;
|
||||
defparam bootram.RAM2.INIT_3A=256'hf5c33f80_22535d5d_e41d821d_bd39ac1d_f1ef3f83_80e3f451_79537d52_7a2e8f38;
|
||||
defparam bootram.RAM2.INIT_3B=256'haaeb3f9c_7d527951_5f5a8853_9a3d993d_3d237f49_387a2299_802e83a6_08428008;
|
||||
defparam bootram.RAM2.INIT_3C=256'h51aaca3f_b4055279_53a93dff_23604788_1b22973d_aadf3f82_79527f51_3d408853;
|
||||
defparam bootram.RAM2.INIT_3D=256'h811c5c88_79337b34_7c1f5b5b_5e5c7b1d_557e843d_3f7b567c_7d51aac1_88537952;
|
||||
defparam bootram.RAM2.INIT_3E=256'h5a792d82_61840508_7b26ef38_811b5b88_84051c34_5a793302_805b7f1b_7c26ef38;
|
||||
defparam bootram.RAM2.INIT_3F=256'h335a7983_9539811a_81bb3882_387d882e_7d832e8a_33405b42_08a41e70_ad398c1b;
|
||||
defparam bootram.RAM3.INIT_00=256'h2251f481_81f4387c_2e098106_5e5c7991_8912335c_1d80c01e_81a238ac_2e098106;
|
||||
defparam bootram.RAM3.INIT_01=256'h88537a52_9b3d5c5e_794b983d_229b3d23_1c085a7c_80fe388c_8008802e_3f800841;
|
||||
defparam bootram.RAM3.INIT_02=256'h4d8853a9_9d3d2379_5a821d22_3f901c08_7f51a999_88537d52_3f963d40_7d51a9a5;
|
||||
defparam bootram.RAM3.INIT_03=256'h1d7c1f5b_3d5e5c7b_7e557e84_f83f7e56_527d51a8_3f88537a_7a51a981_3dcc0552;
|
||||
defparam bootram.RAM3.INIT_04=256'h887b26ef_34811b5b_0284051c_1b5a7933_38805b7f_887c26ef_34811c5c_5b79337b;
|
||||
defparam bootram.RAM3.INIT_05=256'h02840580_953d347e_1d5d5d7e_39ac1de4_a03f80de_80e951e5_085a792d_38608405;
|
||||
defparam bootram.RAM3.INIT_06=256'h53605294_d205237e_02840580_23861a22_1a22963d_ce052384_02840580_cd05347e;
|
||||
defparam bootram.RAM3.INIT_07=256'hce05237b_02840580_08095a79_f1c03f80_2a527c51_08537b81_f1cc3f80_3d70525b;
|
||||
defparam bootram.RAM3.INIT_08=256'h53727427_ed900855_0d800b80_0d04fc3d_f73fa93d_526151f5_547a537f_567c557d;
|
||||
defparam bootram.RAM3.INIT_09=256'h39811353_3872518b_09810685_5170752e_088c1353_54565171_0880ed98_a4387670;
|
||||
defparam bootram.RAM3.INIT_0A=256'h8025ba38_b93f8008_535755ff_0d777971_0d04fb3d_800c863d_38ff5170_737326e7;
|
||||
defparam bootram.RAM3.INIT_0B=256'h940c5473_870680ed_94088111_8e3980ed_80ed900c_89388114_54738726_80ed9008;
|
||||
defparam bootram.RAM3.INIT_0C=256'h80080554_39800810_9c145194_755280ed_51548653_ed98120c_2b760880_10147082;
|
||||
defparam bootram.RAM3.INIT_0D=256'h54738008_fed83f80_3d0d7551_3d0d04fd_a6bb3f87_ed9c0551_73842980_86537552;
|
||||
defparam bootram.RAM3.INIT_0E=256'h800c853d_3f815473_7651a691_ed9c0552_73842980_05548653_08108008_24993880;
|
||||
defparam bootram.RAM3.INIT_0F=256'h33710780_72078316_3370882b_2b078214_982b7190_81123371_0d757033_0d04fd3d;
|
||||
defparam bootram.RAM3.INIT_10=256'hffff068b_a8387383_56595776_80edf822_3d0d7d7f_3d0d04f9_56545285_0c525354;
|
||||
defparam bootram.RAM3.INIT_11=256'h742380c0_05515476_2980edfc_29147090_d3387390_73832680_31525654_3d227072;
|
||||
defparam bootram.RAM3.INIT_12=256'h3d527390_5488538a_74902915_8326ad38_57575474_22707231_ff068d3d_397383ff;
|
||||
defparam bootram.RAM3.INIT_13=256'h1656ec39_e3a53f81_53547451_75177033_78279138_3f805675_0551a581_2980edfc;
|
||||
defparam bootram.RAM3.INIT_14=256'h88140c80_23800b82_54548073_0b80edfc_edf82380_9a052280_fc3d0d02_893d0d04;
|
||||
defparam bootram.RAM3.INIT_15=256'hd938863d_54837427_82901454_9b3f8114_740551ef_80edf822_0cb48b52_0b828c14;
|
||||
defparam bootram.RAM3.INIT_16=256'h881a085b_be387582_51567581_32708106_847c2c81_edfc5a5c_0d800b80_0d04f43d;
|
||||
defparam bootram.RAM3.INIT_17=256'hff06708a_38800881_ff2e80c5_ea3f8008_5b7b51e2_781a8805_2680d638_5d7981ff;
|
||||
defparam bootram.RAM3.INIT_18=256'h777b7081_8338815d_5876802e_51595158_80250753_72802571_8d327030_32703072;
|
||||
defparam bootram.RAM3.INIT_19=256'h38828819_7a27ffb1_1a5a81ff_8c1a0c81_0c800b82_0582881a_88190881_055d3482;
|
||||
defparam bootram.RAM3.INIT_1A=256'h75802eab_38782256_8b7627bf_8c1b0c56_08811182_38828c19_d2387c91_08802e80;
|
||||
defparam bootram.RAM3.INIT_1B=256'h887826ef_34811858_57753377_1a781a57_3d5b5877_54800b83_08558819_38828819;
|
||||
defparam bootram.RAM3.INIT_1C=256'h5a5c837c_1c82901a_8c1a0c81_0c800b82_0b82881a_f2a83f80_227c0551_3880edf8;
|
||||
defparam bootram.RAM3.INIT_1D=256'h06538452_54759fff_23855590_7580f78c_9e052256_fb3d0d02_8e3d0d04_27fea938;
|
||||
defparam bootram.RAM3.INIT_1E=256'h06515153_812a7081_b0800870_fa3d0d81_22800c04_0480f78c_3f873d0d_8151eb8f;
|
||||
defparam bootram.RAM3.INIT_1F=256'h81a43880_8c9abe26_9f145372_0ce7a0a3_0b81b080_84085481_bd3881b0_72802e81;
|
||||
defparam bootram.RAM3.INIT_20=256'h52585153_ea807131_c00c98e5_2c7080eb_84057083_08317411_2980ebc0_ebc00888;
|
||||
defparam bootram.RAM3.INIT_21=256'h70902b70_80f6bc22_ffb1f053_f0258538_3972ffb1_ce90538c_25873880_80ce9073;
|
||||
defparam bootram.RAM3.INIT_22=256'hc0227090_732980f6_2b70902c_be227090_d00c80f6_167080f6_80f6d008_902c7529;
|
||||
defparam bootram.RAM3.INIT_23=256'h5b565156_55535155_872c5257_73180570_80f6cc0c_902c297f_087f3171_2b80f6cc;
|
||||
defparam bootram.RAM3.INIT_24=256'h065253fe_7083ffff_53908013_8438f081_72f08125_ff538a39_2586388f_548fff73;
|
||||
defparam bootram.RAM3.INIT_25=256'h5480c073_f6bc7054_e3ed3f80_d0528151_fdfa3fb7_0d908051_0d04fd3d_873f883d;
|
||||
defparam bootram.RAM3.INIT_26=256'h0b81b080_94150c81_150c800b_ea800b90_152398e5_82800b84_23907323_70820555;
|
||||
defparam bootram.RAM3.INIT_27=256'h55741770_059d0557_3f800284_68519994_5780c052_883d7054_04ea3d0d_0c853d0d;
|
||||
defparam bootram.RAM3.INIT_28=256'h09810685_7381992e_70335154_94387416_2e098106_387381aa_81ff2e9d_33515473;
|
||||
defparam bootram.RAM3.INIT_29=256'h54548452_0d863d70_0d04f93d_800c983d_38805473_be7527d1_39811555_3881548b;
|
||||
defparam bootram.RAM3.INIT_2A=256'h5574800c_06833881_752e0981_a43f8008_5273519e_5380e498_3f805584_795198c4;
|
||||
defparam bootram.RAM3.INIT_2B=256'he49c5255_06705380_800881ff_3f8eed3f_3d0d9282_940c04fc_810b81e0_893d0d04;
|
||||
defparam bootram.RAM3.INIT_2C=256'h81873974_80e4b451_54738838_81065151_708d2a70_81b8b408_518de33f_e5bb3f80;
|
||||
defparam bootram.RAM3.INIT_2D=256'h3f81518d_9851dc85_9c3880e5_8008802e_51feb63f_3f98800a_ec51dc99_b73880e4;
|
||||
defparam bootram.RAM3.INIT_2E=256'hfed83f80_8c800a51_51dbea3f_3f80e5d0_0a5183f9_74529880_51e0b83f_a93f82ac;
|
||||
defparam bootram.RAM3.INIT_2F=256'he6a451db_978e3f80_8c800a51_80ffff52_83808053_51dbd63f_3880e5f8_08802ebd;
|
||||
defparam bootram.RAM3.INIT_30=256'h83ab3f88_80528051_51dfe83f_b03f82ac_e6c851db_feda3f80_51dff83f_c03f82ac;
|
||||
defparam bootram.RAM3.INIT_31=256'h2e843880_537387e8_0d7554a0_0c04fd3d_7180f6d4_863d0d04_51db9a3f_3980e784;
|
||||
defparam bootram.RAM3.INIT_32=256'h7351722d_802e8538_d4085372_be3f80f6_527251d9_e3f33f72_80e7d051_c0537352;
|
||||
defparam bootram.RAM3.INIT_33=256'h802e8538_d4085372_9a3f80f6_528051d9_a23f80c0_528051d9_fe3d0da0_853d0d04;
|
||||
defparam bootram.RAM3.INIT_34=256'h81557180_06515354_862a7081_ff0b8008_518d983f_fc3d0d9a_843d0d04_8051722d;
|
||||
defparam bootram.RAM3.INIT_35=256'h8a547180_80248a38_9b387182_7182802e_5580e454_86800653_820b8008_2e80ec38;
|
||||
defparam bootram.RAM3.INIT_36=256'h3f71882a_85518ccb_3f800852_84518cd3_8338ff54_7184802e_3987e854_2e8e388a;
|
||||
defparam bootram.RAM3.INIT_37=256'h52d99a3f_55535154_0c80e888_7080f6e0_e8c81133_06720780_8a2c7083_8c068008;
|
||||
defparam bootram.RAM3.INIT_38=256'h74822ea6_80f6d80c_2e983874_80f6d808_d9b33f74_11085252_0680ebc4_71822b8c;
|
||||
defparam bootram.RAM3.INIT_39=256'h8e387380_f6dc082e_96387380_2e098106_9e397482_38feb93f_098106a3_3874812e;
|
||||
defparam bootram.RAM3.INIT_3A=256'h518bad3f_da3f8008_fd3d0dd5_863d0d04_518bd83f_fde83f99_9f3f7351_f6dc0cfe;
|
||||
defparam bootram.RAM3.INIT_3B=256'h9c518bd8_81ae8052_518be13f_3f8d5298_99518bb7_80f6dc0c_d80cff0b_800b80f6;
|
||||
defparam bootram.RAM3.INIT_3C=256'hbb3f8451_5484518b_9f067053_908007f4_9a3f8008_3f84518b_8451de9b_3fbd8852;
|
||||
defparam bootram.RAM3.INIT_3D=256'h84800752_ee3f8008_3f80518a_a051e189_735280e8_38800853_80082e8d_8b853f73;
|
||||
defparam bootram.RAM3.INIT_3E=256'h595683ff_81d00a07_7ed00a06_81d00a07_7cd00a06_04f63d0d_3f853d0d_80518b94;
|
||||
defparam bootram.RAM3.INIT_3F=256'h51dc803f_99770c8a_8a3f81ab_0c8a51dc_923f7177_578a51dc_8072710c_ff5282c0;
|
||||
defparam bootram.RAM4.INIT_00=256'hffff0670_e63f7583_0c7851db_81998677_80e1805a_51dbf43f_e6770c78_8a5982d4;
|
||||
defparam bootram.RAM4.INIT_01=256'h90067483_07077310_88067173_0672812a_71832a84_71872a07_852a8206_81ff0670;
|
||||
defparam bootram.RAM4.INIT_02=256'h07077a88_80067373_63067081_0677872b_852b80c0_81ff0676_73070770_2ba00671;
|
||||
defparam bootram.RAM4.INIT_03=256'h74832ba0_73109006_71730707_812a8806_2a840672_2a077183_82067187_2a70852a;
|
||||
defparam bootram.RAM4.INIT_04=256'h70882b7b_73730707_70818006_872b6d06_80c00677_0676852b_077081ff_06717307;
|
||||
defparam bootram.RAM4.INIT_05=256'h575d5653_53515752_5b515852_57525a55_44525351_5151586b_ff066d0c_077083ff;
|
||||
defparam bootram.RAM4.INIT_06=256'h077081ff_ff067073_902a7081_96800676_3f75902a_7851dab3_9981770c_dabd3f81;
|
||||
defparam bootram.RAM4.INIT_07=256'h74832ba0_73109006_71730707_812a8806_2a840672_2a077183_82067187_0670852a;
|
||||
defparam bootram.RAM4.INIT_08=256'h2a701090_ff067a88_2b077081_72077887_80c00670_0676852b_077081ff_06717307;
|
||||
defparam bootram.RAM4.INIT_09=256'h5b515155_51566740_7407680c_83fe8006_0770882b_0772872b_80c00671_0671852b;
|
||||
defparam bootram.RAM4.INIT_0A=256'h7783ffff_51d9a43f_85770c78_80568199_b23f81a1_515752d9_5a5a5751_53515852;
|
||||
defparam bootram.RAM4.INIT_0B=256'h73109006_71730707_812a8806_2a840672_2a077183_82067187_0670852a_067081ff;
|
||||
defparam bootram.RAM4.INIT_0C=256'h73730707_70818006_872b7f06_80c00677_0676852b_077081ff_06717307_74832ba0;
|
||||
defparam bootram.RAM4.INIT_0D=256'h90067483_07077310_88067173_0672812a_71832a84_71872a07_852a8206_7a882a70;
|
||||
defparam bootram.RAM4.INIT_0E=256'h07077088_80067373_69067081_0677872b_852b80c0_81ff0676_73070770_2ba00671;
|
||||
defparam bootram.RAM4.INIT_0F=256'h5752575c_58525351_5a555b51_53515752_586b4452_6d0c5151_83ffff06_2b7b0770;
|
||||
defparam bootram.RAM4.INIT_10=256'h7081ff06_0678902a_902a9680_d7ed3f77_770c7851_55819983_3f81c180_5653d7fb;
|
||||
defparam bootram.RAM4.INIT_11=256'h07077310_88067173_0672812a_71832a84_71872a07_852a8206_81ff0670_70730770;
|
||||
defparam bootram.RAM4.INIT_12=256'h80067373_61067081_0677872b_852b80c0_81ff0676_73070770_2ba00671_90067483;
|
||||
defparam bootram.RAM4.INIT_13=256'h077083ff_70882b75_71730707_872b6606_80c00672_0671852b_2a701090_07077a88;
|
||||
defparam bootram.RAM4.INIT_14=256'h99857078_52d6e43f_57515159_58525a5b_58525351_5a545b51_51526942_ff066a0c;
|
||||
defparam bootram.RAM4.INIT_15=256'h51d6c03f_f0770c78_d6c93f80_770c7851_d6d13f71_770c7851_d6d93f80_0c795252;
|
||||
defparam bootram.RAM4.INIT_16=256'h770c7851_d6a53f71_770c7851_d6ad3f71_770c7851_d6b53f71_0c795252_88807078;
|
||||
defparam bootram.RAM4.INIT_17=256'h800c873d_3f863d22_d051839a_53805280_873dfc05_3d0d8254_3d0d04fb_d69d3f8c;
|
||||
defparam bootram.RAM4.INIT_18=256'h82945280_90387753_77829326_08585957_3d088412_3d0880d7_3d0d80d5_0d04ffb2;
|
||||
defparam bootram.RAM4.INIT_19=256'h080480c1_a4055675_842980e9_81a23875_56759626_39ff9f16_983f81ac_e8d851da;
|
||||
defparam bootram.RAM4.INIT_1A=256'h39ff883f_c65c80fa_80085f80_5e8caa3f_a63f8008_818c398c_8008085e_5cced03f;
|
||||
defparam bootram.RAM4.INIT_1B=256'h80c55c80_5189d33f_5280f790_538c1708_39901708_d65c80ea_ff065e80_800883ff;
|
||||
defparam bootram.RAM4.INIT_1C=256'hb9399417_3980c25c_80c45cbe_802e8638_ff065675_3f800881_90518a98_d53980f7;
|
||||
defparam bootram.RAM4.INIT_1D=256'h8c170851_90170852_fe800553_3980d03d_80d75ca6_5188ba3f_528c1708_53901708;
|
||||
defparam bootram.RAM4.INIT_1E=256'hfdec0554_5580d03d_a05c8294_f83f8339_528051f7_80d35c80_d25c8f39_8bc63f80;
|
||||
defparam bootram.RAM4.INIT_1F=256'h808251e1_26ec3883_18588878_33773481_05575775_80d23d79_5a587719_800b833d;
|
||||
defparam bootram.RAM4.INIT_20=256'h7f5a5757_0d7a7c7f_f33ff83d_3fff5182_8051cf89_3d0d80ea_3d0d0480_b13f80d0;
|
||||
defparam bootram.RAM4.INIT_21=256'h05a10534_58330284_76708105_738a3d34_81175754_25b73875_56548074_5874ff16;
|
||||
defparam bootram.RAM4.INIT_22=256'h2e8538c1_a63f7380_548a51d3_0881ff06_d1f83f80_81ff0651_fc055277_82538a3d;
|
||||
defparam bootram.RAM4.INIT_23=256'h3d348154_dc567588_56748338_335580de_0d02a305_0d04fa3d_800c8a3d_39815473;
|
||||
defparam bootram.RAM4.INIT_24=256'h3d348153_ab053389_0d7c5702_0d04f93d_893f883d_80d051ff_5381f752_883dfc05;
|
||||
defparam bootram.RAM4.INIT_25=256'h80772597_802e9e38_70565473_0881ff06_d1983f80_33705256_5202a705_893dfc05;
|
||||
defparam bootram.RAM4.INIT_26=256'h893d0d04_5574800c_2e833881_56547380_81ff0670_db3f8008_527551cf_3876537b;
|
||||
defparam bootram.RAM4.INIT_27=256'hde2e0981_56567480_0b883d33_ffa03f80_5280d051_055381f7_54883dfc_fa3d0d81;
|
||||
defparam bootram.RAM4.INIT_28=256'hc0ac0c89_0ca60b81_0b81c080_940c80eb_990b81c0_883d0d04_5675800c_06833881;
|
||||
defparam bootram.RAM4.INIT_29=256'ha00c81c0_820b81c0_c0980c51_70810781_2bbe8006_3d0d7288_b00c0480_b00b81c0;
|
||||
defparam bootram.RAM4.INIT_2A=256'h882bbe80_803d0d72_823d0d04_a808800c_f13881c0_51515170_2a708106_a4087081;
|
||||
defparam bootram.RAM4.INIT_2B=256'h81065151_70812a70_81c0a408_81c0a00c_9c0c840b_517381c0_81c0980c_06708107;
|
||||
defparam bootram.RAM4.INIT_2C=256'h0652718a_91387583_55575771_72830655_0d787a7c_ff39fa3d_823d0d04_5170f138;
|
||||
defparam bootram.RAM4.INIT_2D=256'h2b771177_94387382_55737527_822a7255_88f93f72_86388151_5271802e_38728306;
|
||||
defparam bootram.RAM4.INIT_2E=256'hea8c1133_708f0680_7470842a_04fe3d0d_39883d0d_811454e9_0c525452_12700872;
|
||||
defparam bootram.RAM4.INIT_2F=256'he0900870_803d0d82_843d0d04_53cada3f_8c113352_8f0680ea_cae73f72_54515353;
|
||||
defparam bootram.RAM4.INIT_30=256'h80060780_ff067a8c_05337880_3d0d0293_3d0d04fe_70f13882_06515151_882a7081;
|
||||
defparam bootram.RAM4.INIT_31=256'he0900c75_800c7182_387682e0_515170f1_70810651_0870882a_5382e090_c0800753;
|
||||
defparam bootram.RAM4.INIT_32=256'h2a708106_90087088_963882e0_5172802e_e0900c72_82800782_e0980c71_81ff0682;
|
||||
defparam bootram.RAM4.INIT_33=256'h80558854_e0940c88_0d810b82_0d04fc3d_800c843d_80085170_f13882e0_51515170;
|
||||
defparam bootram.RAM4.INIT_34=256'hfef13f80_81528151_548a8053_88805590_04fc3d0d_3f863d0d_8051ff87_80538052;
|
||||
defparam bootram.RAM4.INIT_35=256'h3d0d0480_fed53f86_81528051_88548653_0d888055_0d04fc3d_800c863d_0881ff06;
|
||||
defparam bootram.RAM4.INIT_36=256'h802ef438_ff065170_3f800881_803d0deb_823d0d04_8106800c_80088132_3d0dca3f;
|
||||
defparam bootram.RAM4.INIT_37=256'h75fe9b0a_8055a054_ffb43f88_9b38dd3f_75800826_5685923f_fb3d0d77_823d0d04;
|
||||
defparam bootram.RAM4.INIT_38=256'hff115657_80cb3d08_80c93d08_ffba3d0d_873d0d04_51fe843f_53815280_069b0a07;
|
||||
defparam bootram.RAM4.INIT_39=256'h52883d70_805381ff_81a73882_73800826_5484ce3f_b4387517_81ff2681_57805573;
|
||||
defparam bootram.RAM4.INIT_3A=256'he0980c88_9f3f7482_fed43ffd_3ffefd3f_73518b99_cb3d0852_3f755380_52548cbe;
|
||||
defparam bootram.RAM4.INIT_3B=256'h82e0900c_0c88a00b_0b82e098_e0800c81_c00a0782_c00a0680_900c76fe_800b82e0;
|
||||
defparam bootram.RAM4.INIT_3C=256'h15700882_0c54fe84_0882e08c_fe801570_3d558f56_ef3f80c8_e0900cfc_8aa00b82;
|
||||
defparam bootram.RAM4.INIT_3D=256'he0900c8a_88800b82_e0800c54_15700882_0c54fe8c_0882e084_fe881570_e0880c54;
|
||||
defparam bootram.RAM4.INIT_3E=256'h5574800c_e0980c81_38800b82_8025ffbc_16565675_3fff1690_900cfcb0_800b82e0;
|
||||
defparam bootram.RAM4.INIT_3F=256'h38815774_082680cb_80577380_56838a3f_12575a56_797b7d72_04f93d0d_80c83d0d;
|
||||
defparam bootram.RAM5.INIT_00=256'h54775373_27833876_55577675_80743175_2ea23882_06547380_387581ff_802e80c3;
|
||||
defparam bootram.RAM5.INIT_01=256'h38828054_807527e1_38745482_74802e8e_31575956_74197676_eb3f7316_527551fd;
|
||||
defparam bootram.RAM5.INIT_02=256'h73135482_802e8d38_56545573_0d76787a_0d04fc3d_800c893d_3f815776_dc39fd8c;
|
||||
defparam bootram.RAM5.INIT_03=256'h30707406_fa3f8008_0ca63981_160c8075_0c800b84_800b8816_74279038_9c3f8008;
|
||||
defparam bootram.RAM5.INIT_04=256'h863d0d04_51fcc93f_88160c71_84160c71_760c7406_80083072_5281ec3f_ff165651;
|
||||
defparam bootram.RAM5.INIT_05=256'h082e9438_14088415_38815388_71802e9f_06705452_800881ff_54fc983f_fd3d0d75;
|
||||
defparam bootram.RAM5.INIT_06=256'h0d888055_0d04fc3d_800c853d_3f805372_0c51fc94_05708816_14088008_81b13f88;
|
||||
defparam bootram.RAM5.INIT_07=256'h80f6e408_04fb3d0d_0c863d0d_800a0680_3f8008fe_8151faa3_0a538152_a05481f9;
|
||||
defparam bootram.RAM5.INIT_08=256'h585154ce_80ea9c54_70567155_0881ff06_81ff0680_08882a70_38d43f80_557480c2;
|
||||
defparam bootram.RAM5.INIT_09=256'hc4db3f9c_80eab451_802e8a38_81065473_2e933874_557380c0_2e833881_9c3f73a0;
|
||||
defparam bootram.RAM5.INIT_0A=256'hf5a93f74_51cde23f_5280ead4_278d3874_55558274_e408ea11_e40c80f6_397580f6;
|
||||
defparam bootram.RAM5.INIT_0B=256'h04fefa3f_082b800c_3f810b80_800c04f2_ebbe0533_3f800880_0d04ff91_800c873d;
|
||||
defparam bootram.RAM5.INIT_0C=256'h0c8b0b82_0b82e090_980c8880_800b82e0_56f8e93f_f63d0d7d_2b800c04_810b8008;
|
||||
defparam bootram.RAM5.INIT_0D=256'h900cf8b8_a80b82e0_e0900c8a_88a80b82_82e0980c_800c810b_882b82e0_e0840c7c;
|
||||
defparam bootram.RAM5.INIT_0E=256'h82e08c08_0cf89d3f_0b82e090_900c8a80_800b82e0_80d33888_54737627_3f7e5580;
|
||||
defparam bootram.RAM5.INIT_0F=256'h83387053_53707327_31525790_883d7675_e080085b_84085a82_085982e0_5882e088;
|
||||
defparam bootram.RAM5.INIT_10=256'h39800b82_1454ffa9_52ec3972_57348112_75708105_17517033_27913871_80527173;
|
||||
defparam bootram.RAM5.INIT_11=256'h0508528c_538c088c_fd3d0d80_08028c0c_f6da3f8c_3d0d7251_3d0d0480_e0980c8c;
|
||||
defparam bootram.RAM5.INIT_12=256'h81538c08_0cfd3d0d_8c08028c_0d8c0c04_0c54853d_80087080_5182de3f_08880508;
|
||||
defparam bootram.RAM5.INIT_13=256'h8c0cf93d_048c0802_3d0d8c0c_800c5485_3f800870_085182b9_8c088805_8c050852;
|
||||
defparam bootram.RAM5.INIT_14=256'h800b8c08_0888050c_0508308c_388c0888_088025ab_8c088805_08fc050c_0d800b8c;
|
||||
defparam bootram.RAM5.INIT_15=256'h088c0508_fc050c8c_05088c08_0c8c08f4_8c08f405_8838810b_08fc0508_f4050c8c;
|
||||
defparam bootram.RAM5.INIT_16=256'h38810b8c_fc050888_050c8c08_0b8c08f0_8c050c80_08308c08_8c088c05_8025ab38;
|
||||
defparam bootram.RAM5.INIT_17=256'h81a73f80_88050851_08528c08_8c088c05_050c8053_088c08fc_8c08f005_08f0050c;
|
||||
defparam bootram.RAM5.INIT_18=256'h8c08f805_08f8050c_0508308c_388c08f8_08802e8c_8c08fc05_f8050c54_08708c08;
|
||||
defparam bootram.RAM5.INIT_19=256'h88050880_050c8c08_0b8c08fc_fb3d0d80_08028c0c_8c0c048c_54893d0d_0870800c;
|
||||
defparam bootram.RAM5.INIT_1A=256'h8c388c08_05088025_0c8c088c_8c08fc05_050c810b_308c0888_08880508_2593388c;
|
||||
defparam bootram.RAM5.INIT_1B=256'h8c08f805_3f800870_050851ad_528c0888_088c0508_0c81538c_8c088c05_8c050830;
|
||||
defparam bootram.RAM5.INIT_1C=256'h800c5487_f8050870_050c8c08_308c08f8_08f80508_2e8c388c_fc050880_0c548c08;
|
||||
defparam bootram.RAM5.INIT_1D=256'h088c0508_f8050c8c_800b8c08_08fc050c_0d810b8c_8c0cfd3d_048c0802_3d0d8c0c;
|
||||
defparam bootram.RAM5.INIT_1E=256'h088c0508_2499388c_088c0508_38800b8c_08802ea3_8c08fc05_0827ac38_8c088805;
|
||||
defparam bootram.RAM5.INIT_1F=256'h388c088c_802e80c9_08fc0508_0cc9398c_8c08fc05_fc050810_050c8c08_108c088c;
|
||||
defparam bootram.RAM5.INIT_20=256'hf805088c_050c8c08_318c0888_088c0508_8805088c_a1388c08_88050826_05088c08;
|
||||
defparam bootram.RAM5.INIT_21=256'h2a8c088c_8c050881_050c8c08_2a8c08fc_fc050881_050c8c08_078c08f8_08fc0508;
|
||||
defparam bootram.RAM5.INIT_22=256'h8c08f805_0c518d39_8c08f405_88050870_8f388c08_0508802e_398c0890_050cffaf;
|
||||
defparam bootram.RAM5.INIT_23=256'h56528372_78777956_04fc3d0d_3d0d8c0c_08800c85_8c08f405_f4050c51_08708c08;
|
||||
defparam bootram.RAM5.INIT_24=256'h72712e09_74335253_a0387433_5271ff2e_b038ff12_5170802e_74078306_278c3874;
|
||||
defparam bootram.RAM5.INIT_25=256'h04747454_0c863d0d_38800b80_098106e2_5571ff2e_ff145455_81158115_8106bd38;
|
||||
defparam bootram.RAM5.INIT_26=256'h55ffaf39_38707355_718326e9_14545451_118414fc_068f3884_082e0981_51700873;
|
||||
defparam bootram.RAM5.INIT_27=256'h83065170_38727507_8f72278c_55555555_7670797b_04fc3d0d_0c863d0d_72713180;
|
||||
defparam bootram.RAM5.INIT_28=256'hff2e0981_ff125271_81055634_54337470_72708105_ff2e9838_ff125271_802ea738;
|
||||
defparam bootram.RAM5.INIT_29=256'h54087170_72708405_8405530c_54087170_72708405_0d047451_800c863d_06ea3874;
|
||||
defparam bootram.RAM5.INIT_2A=256'hf0125271_8405530c_54087170_72708405_8405530c_54087170_72708405_8405530c;
|
||||
defparam bootram.RAM5.INIT_2B=256'h387054ff_718326ed_0cfc1252_70840553_05540871_38727084_83722795_8f26c938;
|
||||
defparam bootram.RAM5.INIT_2C=256'h802ea238_83065170_278a3874_53558372_05335755_028c059f_0d767971_8339fc3d;
|
||||
defparam bootram.RAM5.INIT_2D=256'h0c863d0d_ef387480_2e098106_125271ff_055534ff_73737081_ff2e9338_ff125271;
|
||||
defparam bootram.RAM5.INIT_2E=256'h71708405_05530c72_72717084_7227a538_5154518f_71902b07_2b750770_04747488;
|
||||
defparam bootram.RAM5.INIT_2F=256'h38727170_83722790_8f26dd38_f0125271_8405530c_0c727170_70840553_530c7271;
|
||||
defparam bootram.RAM5.INIT_30=256'h72802e80_54555552_787a7c70_39fa3d0d_7053ff90_8326f238_fc125271_8405530c;
|
||||
defparam bootram.RAM5.INIT_31=256'h74712e09_74335651_b1387133_5372ff2e_d438ff13_70802e80_07830651_d9387174;
|
||||
defparam bootram.RAM5.INIT_32=256'h555272ff_15ff1555_38811281_802e80fc_ff065170_87387081_72802e81_8106a938;
|
||||
defparam bootram.RAM5.INIT_33=256'h0c883d0d_52527080_71713151_7581ff06_7081ff06_74335651_d1387133_2e098106;
|
||||
defparam bootram.RAM5.INIT_34=256'h802eb138_fc135372_52ff9739_38747655_74082e88_88387108_55837327_04717457;
|
||||
defparam bootram.RAM5.INIT_35=256'h55837327_15841757_709a3884_06515151_84828180_120670f8_f7fbfdff_74087009;
|
||||
defparam bootram.RAM5.INIT_36=256'h0b80eb94_fd3d0d80_883d0d04_800b800c_52fedf39_38747655_76082ed0_d0387408;
|
||||
defparam bootram.RAM5.INIT_37=256'hb1fc3f80_528151ff_3f80ebd8_3fffaa8c_0cffaaf0_7380f6e8_812e9e38_08545472;
|
||||
defparam bootram.RAM5.INIT_38=256'h800851f6_ffb1df3f_d8528151_ef3f80eb_d33fffa9_e80cffaa_3f7280f6_0851f6a3;
|
||||
defparam bootram.RAM5.INIT_39=256'h08525270_2dfc1270_2e913870_525270ff_fc057008_80ebe00b_39ff3d0d_863f00ff;
|
||||
defparam bootram.RAM5.INIT_3A=256'h6f722069_21457272_00000040_04000000_ffaafe3f_3d0d0404_06f13883_ff2e0981;
|
||||
defparam bootram.RAM5.INIT_3B=256'h70656374_3a204578_646c6572_2068616e_636b6574_6c207061_6e74726f_6e20636f;
|
||||
defparam bootram.RAM5.INIT_3C=256'h62757420_25642c20_62657220_206e756d_6c697479_74696269_6f6d7061_65642063;
|
||||
defparam bootram.RAM5.INIT_3D=256'h636b6574_6c207061_6e74726f_6e20636f_6f722069_21457272_25640a00_676f7420;
|
||||
defparam bootram.RAM5.INIT_3E=256'h656e6774_6164206c_61796c6f_65642070_70656374_3a204578_646c6572_2068616e;
|
||||
defparam bootram.RAM5.INIT_3F=256'h6b206368_206c696e_0a657468_0a000000_74202564_7420676f_2c206275_68202564;
|
||||
defparam bootram.RAM6.INIT_00=256'h31302055_50204e32_0a555352_640a0000_203d2025_70656564_643a2073_616e6765;
|
||||
defparam bootram.RAM6.INIT_01=256'h62696c69_70617469_20636f6d_46504741_720a0000_6f616465_6f6f746c_44502062;
|
||||
defparam bootram.RAM6.INIT_02=256'h70617469_20636f6d_77617265_4669726d_640a0000_723a2025_756d6265_7479206e;
|
||||
defparam bootram.RAM6.INIT_03=256'h476f7420_00000000_61646472_640a0000_723a2025_756d6265_7479206e_62696c69;
|
||||
defparam bootram.RAM6.INIT_04=256'h000006df_000006f6_00000000_65743a20_7061636b_65727920_65636f76_69702072;
|
||||
defparam bootram.RAM6.INIT_05=256'h0000078f_0000078f_0000078f_0000078f_0000078f_00000765_0000078f_0000078f;
|
||||
defparam bootram.RAM6.INIT_06=256'h0000078f_0000078f_0000078f_0000078f_0000066d_0000078f_000006a7_00000713;
|
||||
defparam bootram.RAM6.INIT_07=256'h4c4d5331_00000753_00000746_0000073f_00000738_00000733_0000072e_0000067a;
|
||||
defparam bootram.RAM6.INIT_08=256'h20636869_4c4d5332_0a000000_30782578_6e203d20_7273696f_70207665_20636869;
|
||||
defparam bootram.RAM6.INIT_09=256'h3fff0000_0050c285_c0a80a02_0a000000_30782578_6e203d20_7273696f_70207665;
|
||||
defparam bootram.RAM6.INIT_0A=256'h30313233_2e256400_642e2564_25642e25_45000000_01c300e2_054a0387_15290a94;
|
||||
defparam bootram.RAM6.INIT_0B=256'h5f706b74_73656e64_ffff0000_ffffffff_00000000_43444546_38394142_34353637;
|
||||
defparam bootram.RAM6.INIT_0C=256'h72206275_6e642f6f_656e2061_6f66206c_656e7420_69676e6d_6420616c_3a206261;
|
||||
defparam bootram.RAM6.INIT_0D=256'h74206361_6f206869_65642074_6661696c_6f6e3a20_636f6d6d_6e65745f_66000000;
|
||||
defparam bootram.RAM6.INIT_0E=256'h6172703a_646c655f_0a68616e_00000000_666f7220_696e6720_6c6f6f6b_63686520;
|
||||
defparam bootram.RAM6.INIT_0F=256'h6e736973_696e636f_55445020_0a000000_3d202564_697a6520_72642073_20776569;
|
||||
defparam bootram.RAM6.INIT_10=256'h50726f64_0b0b0b0b_00000000_2025640a_3a202564_67746873_206c656e_74656e74;
|
||||
defparam bootram.RAM6.INIT_11=256'h20555352_74696e67_53746172_640a0000_203d2025_6d616765_6f6e2069_75637469;
|
||||
defparam bootram.RAM6.INIT_12=256'h66652066_67207361_6164696e_2e204c6f_6d6f6465_61666520_696e2073_50322b20;
|
||||
defparam bootram.RAM6.INIT_13=256'h69642070_2076616c_20666f72_6b696e67_43686563_00000000_6172652e_69726d77;
|
||||
defparam bootram.RAM6.INIT_14=256'h64207072_56616c69_2e2e2e00_6d616765_47412069_6e204650_6374696f_726f6475;
|
||||
defparam bootram.RAM6.INIT_15=256'h7474656d_642e2041_666f756e_61676520_4120696d_20465047_74696f6e_6f647563;
|
||||
defparam bootram.RAM6.INIT_16=256'h64756374_2070726f_616c6964_4e6f2076_742e0000_20626f6f_6720746f_7074696e;
|
||||
defparam bootram.RAM6.INIT_17=256'h64207072_56616c69_2e0a0000_6f756e64_67652066_20696d61_46504741_696f6e20;
|
||||
defparam bootram.RAM6.INIT_18=256'h64696e67_204c6f61_756e642e_6520666f_6d776172_20666972_74696f6e_6f647563;
|
||||
defparam bootram.RAM6.INIT_19=256'h6e672069_61727469_2e205374_64696e67_206c6f61_73686564_46696e69_2e2e2e00;
|
||||
defparam bootram.RAM6.INIT_1A=256'h61696e20_6f6d206d_6e206672_65747572_523a2052_4552524f_2e000000_6d616765;
|
||||
defparam bootram.RAM6.INIT_1B=256'h61707065_65722068_206e6576_6f756c64_73207368_20546869_72616d21_70726f67;
|
||||
defparam bootram.RAM6.INIT_1C=256'h77617265_6669726d_696f6e20_64756374_2070726f_616c6964_4e6f2076_6e210000;
|
||||
defparam bootram.RAM6.INIT_1D=256'h75696c74_746f2062_75676820_7468726f_696e6720_46616c6c_6e642e20_20666f75;
|
||||
defparam bootram.RAM6.INIT_1E=256'h2025640a_7420746f_64207365_53706565_2e000000_77617265_6669726d_2d696e20;
|
||||
defparam bootram.RAM6.INIT_1F=256'h53594d4d_58000000_57455f52_58000000_57455f54_00000000_4e4f4e45_00000000;
|
||||
defparam bootram.RAM6.INIT_20=256'h6c3a2000_6e74726f_7720636f_20666c6f_726e6574_65746865_43000000_45545249;
|
||||
defparam bootram.RAM6.INIT_21=256'h20676f74_7825782c_74652030_2077726f_4144563a_4e45475f_4155544f_5048595f;
|
||||
defparam bootram.RAM6.INIT_22=256'h6f722069_21457272_00030203_00000001_00030003_00000000_780a0000_20307825;
|
||||
defparam bootram.RAM6.INIT_23=256'h65637465_20457870_6c65723a_68616e64_6b657420_20706163_64617465_6e207570;
|
||||
defparam bootram.RAM6.INIT_24=256'h2025640a_20676f74_20627574_2025642c_6e677468_64206c65_796c6f61_64207061;
|
||||
defparam bootram.RAM6.INIT_25=256'h000023d4_0000234b_0000236d_00002382_000023d4_000023d4_0000233e_00000000;
|
||||
defparam bootram.RAM6.INIT_26=256'h000023d4_000023d4_000023d4_000023d4_000023d4_000023d4_000023d4_000023d4;
|
||||
defparam bootram.RAM6.INIT_27=256'h0000239e_0000235d_000023d4_000023d4_000023c8_000023b1_000023d4_000023d4;
|
||||
defparam bootram.RAM6.INIT_28=256'h0a666c61_43444546_38394142_34353637_30313233_00000000_6f72740a_0a0a6162;
|
||||
defparam bootram.RAM6.INIT_29=256'h6c617368_6e672066_0a57726f_25640a00_697a653d_25642073_7970653d_73682074;
|
||||
defparam bootram.RAM6.INIT_2A=256'h6c617368_6e672066_0a57726f_00000000_6e67210a_63687475_652e2041_20747970;
|
||||
defparam bootram.RAM6.INIT_2B=256'h65000000_792e6578_64756d6d_67210a00_6874756e_64204163_653a2025_2073697a;
|
||||
defparam bootram.RAM6.INIT_2C=256'h000035e8_00000000_00000000_00000000_ffffff00_ffff00ff_ff00ffff_00ffffff;
|
||||
defparam bootram.RAM6.INIT_2D=256'h000c0000_00190010_ffff0033_05050000_01010100_3fff0000_0050c285_c0a80a02;
|
||||
defparam bootram.RAM6.INIT_2E=256'hffffffff_00003574_10101200_000033fc_000033f4_000033ec_000033e4_03197500;
|
||||
defparam bootram.RAM6.INIT_2F=256'h00000000_00000000_00000000_00000000_00000000_00000000_ffffffff_00000000;
|
||||
defparam bootram.RAM6.INIT_30=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM6.INIT_31=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM6.INIT_32=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM6.INIT_33=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM6.INIT_34=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM6.INIT_35=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM6.INIT_36=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM6.INIT_37=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM6.INIT_38=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM6.INIT_39=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM6.INIT_3A=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM6.INIT_3B=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM6.INIT_3C=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM0.INIT_3D=256'h04fd3d0d_3f943d0d_80519b99_ed388380_58887826_77348118_57577533_963d7905;
|
||||
defparam bootram.RAM0.INIT_3E=256'h52725186_80c05372_e82e8438_a0537387_802e9838_92883f73_e1e45254_75705380;
|
||||
defparam bootram.RAM0.INIT_3F=256'h0d82903f_0d04fa3d_b03f853d_52735186_b83f80c0_52735186_3f9039a0_c43f9ba6;
|
||||
defparam bootram.RAM1.INIT_00=256'hefbc0cf9_3f820b80_c05191ba_8c5280e2_5191c33f_5280e2a0_87a93f89_80e28451;
|
||||
defparam bootram.RAM1.INIT_01=256'h9c0c82d6_800b81e0_81e09c0c_e93f810b_84803f84_0cabdf3f_0b80efb8_cd909299;
|
||||
defparam bootram.RAM1.INIT_02=256'h80085483_3f84ce3f_f63f869e_8008518f_3f84da3f_dc3f86aa_8008518f_3f84863f;
|
||||
defparam bootram.RAM1.INIT_03=256'h52838080_ac3f8c93_8def3f94_52800851_3f838084_a23f84bd_80085194_e83f7352;
|
||||
defparam bootram.RAM1.INIT_04=256'h51a5843f_3f838092_825194d3_a8528380_de3f80c7_80845194_8ab25283_5194e83f;
|
||||
defparam bootram.RAM1.INIT_05=256'hc9387680_08802e80_80085680_518dea3f_883dfc05_3faecf3f_bd51acaa_8dda3f8f;
|
||||
defparam bootram.RAM1.INIT_06=256'hcca63f80_90055180_e4528008_845380e2_8106ad38_fdee2e09_55557382_088e0522;
|
||||
defparam bootram.RAM1.INIT_07=256'h74527551_fd3f8839_3f735183_da3f8582_7052548e_e93f9416_e2ec518f_089a3880;
|
||||
defparam bootram.RAM1.INIT_08=256'ha13f86f2_85f63f8b_3f91b13f_3d0d84cb_ff9e39fe_3f8be93f_f73fa4d9_9a8d3f8c;
|
||||
defparam bootram.RAM1.INIT_09=256'h82ac518a_5183ea3f_3f845284_ac518ae0_83f73f82_9f528051_51849b3f_3f9f5280;
|
||||
defparam bootram.RAM1.INIT_0A=256'h82539f52_518ab93f_d03f82ac_52905183_8ac63f90_3f82ac51_885183dd_d33f8852;
|
||||
defparam bootram.RAM1.INIT_0B=256'h8025df38_ff135372_518a9d3f_b43f80e4_529c5183_8aaa3f9f_3f80e451_805183c1;
|
||||
defparam bootram.RAM1.INIT_0C=256'h5683760c_0d81e080_0d04fb3d_800c843d_983f810b_52815183_83bc3f9f_9f529e51;
|
||||
defparam bootram.RAM1.INIT_0D=256'h5190a93f_53815281_90548880_760c8655_89e63f83_0c80e451_ef3f8076_80e45189;
|
||||
defparam bootram.RAM1.INIT_0E=256'he488518d_80085280_5190913f_53825281_90548880_893f8655_e3ec518e_80085280;
|
||||
defparam bootram.RAM1.INIT_0F=256'h279e3872_80537276_81705654_787a5757_04fa3d0d_0c873d0d_3f810b80_f13fa6e1;
|
||||
defparam bootram.RAM1.INIT_10=256'h74740751_1353df39_38805581_81ff2e83_71335271_83388054_5270802e_17703352;
|
||||
defparam bootram.RAM1.INIT_11=256'h5280eec4_5380e4a8_efc43486_0d810b80_0d04fe3d_800c883d_38815170_70802e83;
|
||||
defparam bootram.RAM1.INIT_12=256'h873d7054_c4348654_810b80ef_5574bd38_80efc433_04f93d0d_3f843d0d_5180c798;
|
||||
defparam bootram.RAM1.INIT_13=256'h0881ff06_fef33f80_86527551_802e9d38_ff065574_3f800881_d051b5d0_56825280;
|
||||
defparam bootram.RAM1.INIT_14=256'h80efc034_0d04810b_800c893d_80eec40b_80c6cd3f_80eec451_86537552_55748d38;
|
||||
defparam bootram.RAM1.INIT_15=256'h873dfc05_c0348454_810b80ef_5574b938_80efc033_04fb3d0d_80eec00c_80e4a408;
|
||||
defparam bootram.RAM1.INIT_16=256'h903f8008_fc0551fe_8452873d_802e9938_ff065574_3f800881_d051b4f0_538c5280;
|
||||
defparam bootram.RAM1.INIT_17=256'h5475538c_0d775684_0d04fb3d_800c873d_80eec00b_80eec00c_74863875_81ff0655;
|
||||
defparam bootram.RAM1.INIT_18=256'hc0347480_810b80ef_80eec00c_8d387508_5574802e_0881ff06_b3b63f80_5280d051;
|
||||
defparam bootram.RAM1.INIT_19=256'h0c51823d_0c81e08c_7080efc8_c8080607_067180ef_73097375_04803d0d_0c873d0d;
|
||||
defparam bootram.RAM1.INIT_1A=256'h3d0d0481_980c5182_cc0c81e0_077080ef_efcc0806_75067180_0d730973_0d04803d;
|
||||
defparam bootram.RAM1.INIT_1B=256'h5181b63f_0d8a5280_0d04ff3d_800c843d_81c73f72_53538051_3d0d7470_af3f04fe;
|
||||
defparam bootram.RAM1.INIT_1C=256'hff065376_81157481_802e9038_06545472_337081ff_79565674_fb3d0d77_833d0d04;
|
||||
defparam bootram.RAM1.INIT_1D=256'hfe3d0d74_833d0d04_8051cd3f_3d0d7352_3d0d04ff_0b800c87_3fe53980_52558191;
|
||||
defparam bootram.RAM1.INIT_1E=256'h8051dd3f_3d0d7352_3d0d04ff_0b800c84_80e73f80_8a527251_53ffbd3f_76537052;
|
||||
defparam bootram.RAM1.INIT_1F=256'h82908005_0d73a029_0d04ff3d_1234823d_3380eecc_51028f05_803d0d72_833d0d04;
|
||||
defparam bootram.RAM1.INIT_20=256'h51c63f80_13335272_5380eecc_fe3d0d80_833d0d04_720c5351_b0057022_751080e4;
|
||||
defparam bootram.RAM1.INIT_21=256'h748a2e09_76785654_04fc3d0d_38843d0d_827325e5_3f811353_527251ce_eed01333;
|
||||
defparam bootram.RAM1.INIT_22=256'h90800554_73a02982_7351de3f_87388d52_2e098106_33537281_80eecc14_81069538;
|
||||
defparam bootram.RAM1.INIT_23=256'h11085252_90800588_74a02982_04fe3d0d_0c863d0d_38748c15_72802ef8_84140853;
|
||||
defparam bootram.RAM1.INIT_24=256'heed82270_a8880c80_0d800b81_0d04ff3d_800c843d_12085372_2e853890_ff537080;
|
||||
defparam bootram.RAM1.INIT_25=256'h0d787a02_0d04fb3d_880c833d_800b81a8_840c5181_882a81a8_a8800c70_81ff0681;
|
||||
defparam bootram.RAM1.INIT_26=256'h81065151_70862a70_81a89008_8386d053_2e81c738_81527380_33575556_88059f05;
|
||||
defparam bootram.RAM1.INIT_27=256'h81a88c0c_74108107_52819f39_fde53f72_80e4bc51_5372e938_9338ff13_5271802e;
|
||||
defparam bootram.RAM1.INIT_28=256'h38ff1353_71802e8e_06515152_812a7081_a8900870_86d05381_a8900c83_81900b81;
|
||||
defparam bootram.RAM1.INIT_29=256'h802e80cf_51515271_70813251_2a708106_90087087_ae3f81a8_e4d851fd_72e93880;
|
||||
defparam bootram.RAM1.INIT_2A=256'h90087081_d05381a8_900c8386_527181a8_2e8338a0_e8527381_80c53880_3873802e;
|
||||
defparam bootram.RAM1.INIT_2B=256'h08527176_3f81a88c_d851fcdf_e93880e4_ff135372_802e8e38_51515271_2a708106;
|
||||
defparam bootram.RAM1.INIT_2C=256'h04fb3d0d_0c873d0d_900c7180_c00b81a8_52883980_ffb73981_34ff1454_70810558;
|
||||
defparam bootram.RAM1.INIT_2D=256'h71802e93_06515152_862a7081_a8900870_86d05381_57555683_059f0533_787a0288;
|
||||
defparam bootram.RAM1.INIT_2E=256'h73802e84_0c81d052_1081a88c_81bb3974_8a3f7252_e4f851fc_72e93880_38ff1353;
|
||||
defparam bootram.RAM1.INIT_2F=256'h2e8e38ff_51527180_70810651_0870812a_5381a890_0c8386d0_7181a890_38819052;
|
||||
defparam bootram.RAM1.INIT_30=256'h5271802e_32515151_81067081_70872a70_81a89008_51fbcc3f_3880e4d8_135372e9;
|
||||
defparam bootram.RAM1.INIT_31=256'h900c8386_527181a8_2e833890_d0527381_a88c0c80_38753381_802e80d8_80e23873;
|
||||
defparam bootram.RAM1.INIT_32=256'hd851faf7_e93880e4_ff135372_802e8e38_51515271_2a708106_90087081_d05381a8;
|
||||
defparam bootram.RAM1.INIT_33=256'h56ffa439_16ff1555_2e8e3881_51527180_81325151_70810670_0870872a_3f81a890;
|
||||
defparam bootram.RAM1.INIT_34=256'h74259b38_54805372_fd3d0d75_873d0d04_5271800c_a8900c80_80c00b81_81528a39;
|
||||
defparam bootram.RAM1.INIT_35=256'h0d04ff3d_e239853d_38811353_8f7127f1_515181cb_08707331_5281b8ac_81b8ac08;
|
||||
defparam bootram.RAM1.INIT_36=256'h8c528751_8c0c80fa_ff0b8280_8280840c_800cef0b_e00b8280_80880c81_0dff0b82;
|
||||
defparam bootram.RAM1.INIT_37=256'h0982808c_80880870_fb3d0d82_833d0d04_8025f138_ff115170_8405540c_9ee47270;
|
||||
defparam bootram.RAM1.INIT_38=256'h52712d74_72517308_802e8f38_76065271_8c555574_810b80fa_51528053_08710658;
|
||||
defparam bootram.RAM1.INIT_39=256'h52718726_ff3d0d73_873d0d04_7325dc38_57555387_84157610_8f398113_82808c0c;
|
||||
defparam bootram.RAM1.INIT_3A=256'h0c535152_06828088_88087072_70098280_5181722b_0575710c_2980fa8c_9f387184;
|
||||
defparam bootram.RAM1.INIT_3B=256'h803d0d81_833d0d04_81e0c80c_e0c40c52_74700881_02920522_04ff3d0d_833d0d04;
|
||||
defparam bootram.RAM1.INIT_3C=256'h04fe3d0d_0c823d0d_0b81e0c0_2ef33882_51517080_08708406_0c81b8a0_0b81e0c0;
|
||||
defparam bootram.RAM1.INIT_3D=256'h80529a39_53538180_902a710c_a0087571_933881b8_5272802e_70810654_81b8a008;
|
||||
defparam bootram.RAM1.INIT_3E=256'h843d0d04_5271800c_ffa63f72_51f7dc3f_3880e594_71802e8b_81065152_71812a70;
|
||||
defparam bootram.RAM1.INIT_3F=256'hff3d0d02_823d0d04_800b800c_f2388180_5170802e_80c00651_b8a00870_803d0d81;
|
||||
defparam bootram.RAM2.INIT_00=256'h0b81e0c0_2ef33884_51517080_08709006_5281b8a0_81e0c00c_902b8807_8e052270;
|
||||
defparam bootram.RAM2.INIT_01=256'haccd3f81_70335252_ae3f7214_38ba51f6_72802e86_75548053_04fd3d0d_0c833d0d;
|
||||
defparam bootram.RAM2.INIT_02=256'h33535680_11335470_11335581_11335682_3d0d7783_3d0d04fb_27e63885_13538573;
|
||||
defparam bootram.RAM2.INIT_03=256'h515b5f5d_30709f2a_bb053370_63029005_0d7c7e61_0d04f63d_ed3f873d_e5985180;
|
||||
defparam bootram.RAM2.INIT_04=256'h55785480_26943879_30577777_51782d76_387952ad_75802e8a_80258f38_5b595776;
|
||||
defparam bootram.RAM2.INIT_05=256'h51782d8c_e5a40533_3f800880_7651b593_bd3f7752_800851ff_51b4fb3f_53775276;
|
||||
defparam bootram.RAM2.INIT_06=256'h08a1c35c_70840552_0d8c3d70_0d04f73d_963f823d_053351f5_3d0d028b_3d0d0480;
|
||||
defparam bootram.RAM2.INIT_07=256'hdb388119_09810680_5675a52e_7681ff06_2e81d138_57577580_7081ff06_5a587833;
|
||||
defparam bootram.RAM2.INIT_08=256'h3875802e_80e3248a_2eb93875_387580e3_80f024a0_80fb3875_7580f02e_70335759;
|
||||
defparam bootram.RAM2.INIT_09=256'h7580f32e_f5248b38_ac387580_7580f52e_38818b39_e42e80c6_95397580_819e3881;
|
||||
defparam bootram.RAM2.INIT_0A=256'h792d80da_80527551_33525956_84198312_80ec3977_f82eba38_f5397580_80db3880;
|
||||
defparam bootram.RAM2.INIT_0B=256'ha1c35481_59568055_19710852_90397784_c3548053_568055a1_71085259_39778419;
|
||||
defparam bootram.RAM2.INIT_0C=256'h39778419_fdd03f9e_90527551_c3548053_568055a1_71085259_39778419_538a5292;
|
||||
defparam bootram.RAM2.INIT_0D=256'h59fea339_ec398119_3351792d_70810558_38805276_75802e8e_56763356_71085959;
|
||||
defparam bootram.RAM2.INIT_0E=256'h81065151_2a813270_b408708c_3d0d81b8_e40c0480_8a0b81e5_8b3d0d04_800b800c;
|
||||
defparam bootram.RAM2.INIT_0F=256'h55575454_72810655_982b7b07_9b053372_7b028805_fc3d0d79_823d0d04_5170ef38;
|
||||
defparam bootram.RAM2.INIT_10=256'ha0743179_820a0752_2e863871_51517080_2a708106_07527282_3871810a_70802e86;
|
||||
defparam bootram.RAM2.INIT_11=256'h742bff05_ff953f81_802e9338_0c745174_7081e5ec_81e5e80c_ffa93f71_712b5151;
|
||||
defparam bootram.RAM2.INIT_12=256'h7274278f_55558053_76787a54_04fc3d0d_0c863d0d_52527080_70720651_81b88008;
|
||||
defparam bootram.RAM2.INIT_13=256'h0672902a_7183ffff_802e8d38_902a5170_51ee3971_81155553_70227305_38721015;
|
||||
defparam bootram.RAM2.INIT_14=256'h80efdc0c_3f767008_d451b6c4_755280ef_3d0d8653_3d0d04fd_71800c86_0552ec39;
|
||||
defparam bootram.RAM2.INIT_15=256'h833d0d04_8025f338_12525270_0c8812ff_89518072_80efe452_04ff3d0d_54853d0d;
|
||||
defparam bootram.RAM2.INIT_16=256'h52897225_12881252_2e8e3881_22547274_e0525270_800b80ef_96052253_fd3d0d02;
|
||||
defparam bootram.RAM2.INIT_17=256'h802e8938_c73f8008_06535856_7183ffff_3d0d787a_3d0d04fa_70800c85_ee388051;
|
||||
defparam bootram.RAM2.INIT_18=256'h2e8f3881_55527180_73088815_e0555555_e40b80ef_800880ef_050cad39_76800884;
|
||||
defparam bootram.RAM2.INIT_19=256'h7054933d_f13d0d86_883d0d04_7684140c_3f757323_eb38a381_55897525_15881454;
|
||||
defparam bootram.RAM2.INIT_1A=256'h8405a205_3f908002_0551b584_52913ddc_923d8805_933f7353_055254b5_53923dd6;
|
||||
defparam bootram.RAM2.INIT_1B=256'h2380c091_8405aa05_81808002_0b8c3d23_a6052380_80028405_0b8b3d23_23818a80;
|
||||
defparam bootram.RAM2.INIT_1C=256'h08028405_fdb73f80_3de40551_538a5291_5d665e80_ae052368_80028405_0b8d3d23;
|
||||
defparam bootram.RAM2.INIT_1D=256'h0523ac53_028405be_913d2380_0523800b_028405ba_23963d22_3d22903d_ae052398;
|
||||
defparam bootram.RAM2.INIT_1E=256'h973d2386_805b800b_04e83d0d_3f913d0d_0551a4f4_29829884_526980c0_913dd405;
|
||||
defparam bootram.RAM2.INIT_1F=256'hf2052202_e33f0280_f80551b3_d4529a3d_865380ef_51b3f13f_9a3df205_539b3d52;
|
||||
defparam bootram.RAM2.INIT_20=256'h3d0845a3_436e44a1_1143f005_0b9b3dc4_08585a80_3f800880_0523f7d8_840580e2;
|
||||
defparam bootram.RAM2.INIT_21=256'h08701a78_56845875_06408c3d_088305fc_085fa33d_6e5ea13d_845c905d_3d084659;
|
||||
defparam bootram.RAM2.INIT_22=256'h0654738c_9a387383_5473802e_760c7508_27843873_5a557375_71315156_7c319080;
|
||||
defparam bootram.RAM2.INIT_23=256'ha3c63f75_08527651_08539416_eee53f75_80e5c051_802e8838_83065473_38941608;
|
||||
defparam bootram.RAM2.INIT_24=256'hf6de3f9a_78822a51_3880c059_78bf2684_25ffac38_59577780_0817ff19_70840557;
|
||||
defparam bootram.RAM2.INIT_25=256'h0523800b_840580ca_055a7902_237f1f94_800b943d_4040818a_3d0d6b6e_3d0d04ea;
|
||||
defparam bootram.RAM2.INIT_26=256'hd2052380_02840580_963d2380_80075a79_236980c0_0580ce05_80800284_953d2381;
|
||||
defparam bootram.RAM2.INIT_27=256'h0523913d_840580d2_095a7902_e03f8008_70525cfa_8a52933d_68478053_efdc0846;
|
||||
defparam bootram.RAM2.INIT_28=256'h51f6ac3f_f7b83f7a_80e5ec51_5a799238_0881ff06_8ac83f80_70535c5e_7053983d;
|
||||
defparam bootram.RAM2.INIT_29=256'h5b5b7933_7b1d7c1f_8053805c_557b5490_6b575d94_6d596058_39027f5a_ecd43fa9;
|
||||
defparam bootram.RAM2.INIT_2A=256'h238d3d22_05228a3d_7f5802ae_04f73d0d_3f983d0d_ef38fd89_5c867c26_7b34811c;
|
||||
defparam bootram.RAM2.INIT_2B=256'hf8055391_88548b3d_77567e55_05a60523_23800284_57768b3d_05238818_028405a2;
|
||||
defparam bootram.RAM2.INIT_2C=256'h8f3d3484_0523860b_028405b2_3d239080_0d810b8e_0d04ee3d_9e3f8b3d_527d51fe;
|
||||
defparam bootram.RAM2.INIT_2D=256'h3fe9ea3f_0551b0a0_52943dec_86538008_23e99a3f_8405b605_05348102_028405b5;
|
||||
defparam bootram.RAM2.INIT_2E=256'h80080843_3fe9ce3f_0551b19d_52943df6_3f865380_0551b090_52943df2_84538008;
|
||||
defparam bootram.RAM2.INIT_2F=256'h1b337a34_5a80e5b8_805b7a1c_54908653_943de405_80569c55_80588057_025c8059;
|
||||
defparam bootram.RAM2.INIT_30=256'h862e0981_5f5d7d90_088e1122_3d0daa3d_3d0d04d9_fbcb3f94_7b26ef38_811b5b86;
|
||||
defparam bootram.RAM2.INIT_31=256'h3f86ee39_9c51f596_795280e6_9b268d38_055b5b79_088429f2_901dac3d_06829d38;
|
||||
defparam bootram.RAM2.INIT_32=256'h225a798c_d438841b_09810686_7990802e_821b225a_0686e238_812e0981_7a225a79;
|
||||
defparam bootram.RAM2.INIT_33=256'h3fa81d70_52408885_389e1d70_810686b9_79812e09_861b225a_0686c638_842e0981;
|
||||
defparam bootram.RAM2.INIT_34=256'h868f38a7_085c8008_add23f80_ffa80551_dc52a93d_845380ef_3f800843_525f87fd;
|
||||
defparam bootram.RAM2.INIT_35=256'h841b33a2_80fe0523_22028405_3d23821b_3f7a22a1_7951aeb0_80efd452_3d5a8653;
|
||||
defparam bootram.RAM2.INIT_36=256'h51adfd3f_a93de405_86537952_81820523_82028405_81810534_33028405_3d34851b;
|
||||
defparam bootram.RAM2.INIT_37=256'h3f79537f_7a51ade0_53981d52_8e055b86_ef3f0281_05525aad_53aa3dea_8470547f;
|
||||
defparam bootram.RAM2.INIT_38=256'h7c575d9c_7c597c58_3f027c5a_7e51adc8_86537a52_3f9e3d5f_0551add4_52a93df4;
|
||||
defparam bootram.RAM2.INIT_39=256'h3f84ee39_ef38f999_5c867c26_7b34811c_5b5b7933_7b1d7f1d_05547d53_55a93ddc;
|
||||
defparam bootram.RAM2.INIT_3A=256'h3879882a_810684d1_60842e09_2a435b5b_7022708c_e438901d_09810684_7d90802e;
|
||||
defparam bootram.RAM2.INIT_3B=256'h865380e5_b4387e5e_065f7e84_2280ffff_c038861b_09810684_5a79852e_708f0651;
|
||||
defparam bootram.RAM2.INIT_3C=256'hcb3f8008_535b5cab_efdc5470_1c625580_815e7e90_80088338_51abe13f_b852821d;
|
||||
defparam bootram.RAM2.INIT_3D=256'hec11405d_33821c22_b83f891b_9c1d5184_38881d52_802e8481_7d87387b_8338815c;
|
||||
defparam bootram.RAM2.INIT_3E=256'h42407d7a_11225d5d_08a41f84_8c1b087a_0683de38_912e0981_81bb387f_407f812e;
|
||||
defparam bootram.RAM2.INIT_3F=256'hc33f8008_535d5df5_1d821d22_39ac1de4_e53f83bd_e6bc51f1_537d5280_2e8f3879;
|
||||
defparam bootram.RAM3.INIT_00=256'hbf3f9c3d_527951ab_5a88537d_3d993d5f_237f499a_7a22993d_2e83a638_42800880;
|
||||
defparam bootram.RAM3.INIT_01=256'hab9e3f88_05527951_a93dffb4_60478853_22973d23_b33f821b_527f51ab_40885379;
|
||||
defparam bootram.RAM3.INIT_02=256'h1c5c887c_337b3481_1f5b5b79_5c7b1d7c_7e843d5e_7b567c55_51ab953f_5379527d;
|
||||
defparam bootram.RAM3.INIT_03=256'h792d82ad_8405085a_26ef3861_1b5b887b_051c3481_79330284_5b7f1b5a_26ef3880;
|
||||
defparam bootram.RAM3.INIT_04=256'h5a79832e_39811a33_bb388295_7d882e81_832e8a38_405b427d_a41e7033_398c1b08;
|
||||
defparam bootram.RAM3.INIT_05=256'h51f4813f_f4387c22_09810681_5c79912e_12335c5e_80c01e89_a238ac1d_09810681;
|
||||
defparam bootram.RAM3.INIT_06=256'h537a527d_3d5c5e88_4b983d9b_9b3d2379_085a7c22_fe388c1c_08802e80_80084180;
|
||||
defparam bootram.RAM3.INIT_07=256'h8853a93d_3d23794d_821d229d_901c085a_51a9ed3f_537d527f_963d4088_51a9f93f;
|
||||
defparam bootram.RAM3.INIT_08=256'h7c1f5b5b_5e5c7b1d_557e843d_3f7e567e_7d51a9cc_88537a52_51a9d53f_cc05527a;
|
||||
defparam bootram.RAM3.INIT_09=256'h7b26ef38_811b5b88_84051c34_5a793302_805b7f1b_7c26ef38_811c5c88_79337b34;
|
||||
defparam bootram.RAM3.INIT_0A=256'h840580cd_3d347e02_5d5d7e95_ac1de41d_3f80de39_e951e497_5a792d80_60840508;
|
||||
defparam bootram.RAM3.INIT_0B=256'h6052943d_05237e53_840580d2_861a2202_22963d23_0523841a_840580ce_05347e02;
|
||||
defparam bootram.RAM3.INIT_0C=256'h05237b56_840580ce_095a7902_c03f8008_527c51f1_537b812a_cc3f8008_70525bf1;
|
||||
defparam bootram.RAM3.INIT_0D=256'h727427a4_b0085553_800b80f0_04fc3d0d_3fa93d0d_6151f5f7_7a537f52_7c557d54;
|
||||
defparam bootram.RAM3.INIT_0E=256'h81135373_72518b39_81068538_70752e09_8c135351_56517108_80f0b854_38767008;
|
||||
defparam bootram.RAM3.INIT_0F=256'h25ba3880_3f800880_5755ffb9_77797153_04fb3d0d_0c863d0d_ff517080_7326e738;
|
||||
defparam bootram.RAM3.INIT_10=256'h0c547310_0680f0b4_08811187_3980f0b4_f0b00c8e_38811480_73872689_f0b00854;
|
||||
defparam bootram.RAM3.INIT_11=256'h08055486_80081080_14519439_5280f0bc_54865375_b8120c51_760880f0_1470822b;
|
||||
defparam bootram.RAM3.INIT_12=256'h73800824_d83f8054_0d7551fe_0d04fd3d_8f3f873d_bc0551a7_842980f0_53755273;
|
||||
defparam bootram.RAM3.INIT_13=256'h0c853d0d_81547380_51a6e53f_bc055276_842980f0_54865373_10800805_99388008;
|
||||
defparam bootram.RAM3.INIT_14=256'h7107800c_07831633_70882b72_07821433_2b71902b_12337198_75703381_04fd3d0d;
|
||||
defparam bootram.RAM3.INIT_15=256'hff068b3d_387383ff_595776a8_f1982256_0d7d7f80_0d04f93d_5452853d_52535456;
|
||||
defparam bootram.RAM3.INIT_16=256'h2380c039_51547674_80f19c05_14709029_38739029_832680d3_52565473_22707231;
|
||||
defparam bootram.RAM3.INIT_17=256'h52739029_88538a3d_90291554_26ad3874_57547483_70723157_068d3d22_7383ffff;
|
||||
defparam bootram.RAM3.INIT_18=256'h56ec3989_9c3f8116_547451e2_17703353_27913875_80567578_51a5d53f_80f19c05;
|
||||
defparam bootram.RAM3.INIT_19=256'h140c800b_800b8288_54807323_80f19c54_9823800b_052280f1_3d0d029a_3d0d04fc;
|
||||
defparam bootram.RAM3.INIT_1A=256'h38863d0d_837427d9_90145454_3f811482_0551ef9b_f1982274_b5aa5280_828c140c;
|
||||
defparam bootram.RAM3.INIT_1B=256'h1a085b5d_38758288_567581be_70810651_7c2c8132_9c5a5c82_800b80f1_04f43d0d;
|
||||
defparam bootram.RAM3.INIT_1C=256'h06708a32_800881ff_2e80c538_3f8008ff_7b51e1e1_1a88055b_80d63878_7981ff26;
|
||||
defparam bootram.RAM3.INIT_1D=256'h7b708105_38815d77_76802e83_59515858_25075351_80257180_32703072_7030728d;
|
||||
defparam bootram.RAM3.INIT_1E=256'h82881908_27ffb138_5a81ff7a_1a0c811a_800b828c_82881a0c_19088105_5d348288;
|
||||
defparam bootram.RAM3.INIT_1F=256'h802eab38_78225675_7627bf38_1b0c568b_8111828c_828c1908_387c9138_802e80d2;
|
||||
defparam bootram.RAM3.INIT_20=256'h7826ef38_81185888_75337734_781a5757_5b58771a_800b833d_55881954_82881908;
|
||||
defparam bootram.RAM3.INIT_21=256'h5c837c27_82901a5a_1a0c811c_800b828c_82881a0c_a83f800b_7c0551f2_80f19822;
|
||||
defparam bootram.RAM3.INIT_22=256'h53845281_759fff06_85559054_80faac23_05225675_3d0d029e_3d0d04fb_fea9388e;
|
||||
defparam bootram.RAM3.INIT_23=256'h51515372_2a708106_80087081_3d0d81b0_800c04fa_80faac22_873d0d04_51eb853f;
|
||||
defparam bootram.RAM3.INIT_24=256'ha43880ee_9abe2681_1453728c_e7a0a39f_81b0800c_0854810b_3881b084_802e81bd;
|
||||
defparam bootram.RAM3.INIT_25=256'h58515380_80713152_0c98e5ea_7080eee0_0570832c_31741184_80eee008_e0088829;
|
||||
defparam bootram.RAM3.INIT_26=256'h902b7090_f9dc2270_b1f05380_258538ff_72ffb1f0_90538c39_873880ce_ce907325;
|
||||
defparam bootram.RAM3.INIT_27=256'h2270902b_2980f9e0_70902c73_2270902b_0c80f9de_7080f9f0_f9f00816_2c752980;
|
||||
defparam bootram.RAM3.INIT_28=256'h56515654_5351555b_2c525755_18057087_f9ec0c73_2c297f80_7f317190_80f9ec08;
|
||||
defparam bootram.RAM3.INIT_29=256'h5253fe87_83ffff06_90801370_38f08153_f0812584_538a3972_86388fff_8fff7325;
|
||||
defparam bootram.RAM3.INIT_2A=256'h80c07370_dc705454_e33f80f9_528151e3_fa3fb8ef_908051fd_04fd3d0d_3f883d0d;
|
||||
defparam bootram.RAM3.INIT_2B=256'h81b0800c_150c810b_0c800b94_800b9015_2398e5ea_800b8415_90732382_82055523;
|
||||
defparam bootram.RAM3.INIT_2C=256'h74177033_9d055755_80028405_5199e83f_80c05268_3d705457_ea3d0d88_853d0d04;
|
||||
defparam bootram.RAM3.INIT_2D=256'h81068538_81992e09_33515473_38741670_09810694_7381aa2e_ff2e9d38_51547381;
|
||||
defparam bootram.RAM3.INIT_2E=256'h54845279_863d7054_04f93d0d_0c983d0d_80547380_7527d138_811555be_81548b39;
|
||||
defparam bootram.RAM3.INIT_2F=256'h74800c89_83388155_2e098106_3f800875_73519ef8_80e6e052_80558453_5199983f;
|
||||
defparam bootram.RAM3.INIT_30=256'h81ff0670_ed3f8008_dbc13f8e_80e6e451_0d92d63f_0c04fc3d_0b81e094_3d0d0481;
|
||||
defparam bootram.RAM3.INIT_31=256'h883880e7_51515473_2a708106_b408708d_e33f81b8_3f80518d_5255e5aa_5380e784;
|
||||
defparam bootram.RAM3.INIT_32=256'h80e7fc51_802e9c38_af3f8008_800a51fe_db893f98_80e7d051_3974b738_9c518187;
|
||||
defparam bootram.RAM3.INIT_33=256'hce398c80_e8b45180_83f93f80_98800a51_a73f7452_82ac51e0_518da93f_daf53f81;
|
||||
defparam bootram.RAM3.INIT_34=256'h0a5197db_ff528c80_805380ff_c63f8380_e8dc51da_2ebd3880_3f800880_0a51fed1;
|
||||
defparam bootram.RAM3.INIT_35=256'hd73f8052_82ac51df_51daa03f_3f80e9ac_e73ffed3_82ac51df_51dab03f_3f80e988;
|
||||
defparam bootram.RAM3.INIT_36=256'h54a05373_fd3d0d75_f9f40c04_0d047180_8a3f863d_e9e851da_3f883980_805183ab;
|
||||
defparam bootram.RAM3.INIT_37=256'h5372802e_80f9f408_51d8ae3f_3f725272_b451e3e2_735280ea_3880c053_87e82e84;
|
||||
defparam bootram.RAM3.INIT_38=256'h80f9f408_51d88a3f_80c05280_51d8923f_0da05280_0d04fe3d_722d853d_85387351;
|
||||
defparam bootram.RAM3.INIT_39=256'h70810651_8008862a_ac3fff0b_0d9a518d_0d04fc3d_722d843d_85388051_5372802e;
|
||||
defparam bootram.RAM3.INIT_3A=256'h71828024_802e9b38_e4547182_06535580_80088680_ec38820b_71802e80_53548155;
|
||||
defparam bootram.RAM3.INIT_3B=256'h08528551_8ce73f80_ff548451_802e8338_e8547184_388a3987_71802e8e_8a388a54;
|
||||
defparam bootram.RAM3.INIT_3C=256'heaec5553_fa800c80_11337080_0780ebac_70830672_80088a2c_882a8c06_8cdf3f71;
|
||||
defparam bootram.RAM3.INIT_3D=256'h387480f9_f8082e98_3f7480f9_5252d8a3_eee41108_2b8c0680_8a3f7182_515452d8;
|
||||
defparam bootram.RAM3.INIT_3E=256'h7380f9fc_81069638_74822e09_b93f9e39_06a338fe_812e0981_2ea63874_f80c7482;
|
||||
defparam bootram.RAM3.INIT_3F=256'h0dd4ca3f_0d04fd3d_ec3f863d_3f99518b_7351fde8_0cfe9f3f_7380f9fc_082e8e38;
|
||||
defparam bootram.RAM4.INIT_00=256'hf53f81ae_5298518b_8bcb3f8d_fc0c9951_ff0b80f9_80f9f80c_c13f800b_8008518b;
|
||||
defparam bootram.RAM4.INIT_01=256'h70535484_07f49f06_80089080_518bae3f_de8a3f84_ae528451_8bec3fbe_80529c51;
|
||||
defparam bootram.RAM4.INIT_02=256'h518b823f_e0f83f80_80eb8451_08537352_2e8d3880_3f738008_84518b99_518bcf3f;
|
||||
defparam bootram.RAM4.INIT_03=256'h0a0681d0_0a077ed0_0a0681d0_3d0d7cd0_3d0d04f6_8ba83f85_07528051_80088480;
|
||||
defparam bootram.RAM4.INIT_04=256'h81ab9977_51dbf93f_71770c8a_51dc813f_710c578a_82c08072_83ffff52_0a075956;
|
||||
defparam bootram.RAM4.INIT_05=256'h51dbd53f_86770c78_805a8199_e33f80e1_0c7851db_82d4e677_ef3f8a59_0c8a51db;
|
||||
defparam bootram.RAM4.INIT_06=256'h71730707_812a8806_2a840672_2a077183_82067187_0670852a_067081ff_7583ffff;
|
||||
defparam bootram.RAM4.INIT_07=256'h70818006_872b6306_80c00677_0676852b_077081ff_06717307_74832ba0_73109006;
|
||||
defparam bootram.RAM4.INIT_08=256'h07077310_88067173_0672812a_71832a84_71872a07_852a8206_7a882a70_73730707;
|
||||
defparam bootram.RAM4.INIT_09=256'h80067373_6d067081_0677872b_852b80c0_81ff0676_73070770_2ba00671_90067483;
|
||||
defparam bootram.RAM4.INIT_0A=256'h58525351_5a555b51_53515752_586b4452_6d0c5151_83ffff06_2b7b0770_07077088;
|
||||
defparam bootram.RAM4.INIT_0B=256'h7081ff06_0676902a_902a9680_daa23f75_770c7851_3f819981_5653daac_5752575d;
|
||||
defparam bootram.RAM4.INIT_0C=256'h07077310_88067173_0672812a_71832a84_71872a07_852a8206_81ff0670_70730770;
|
||||
defparam bootram.RAM4.INIT_0D=256'h7081ff06_78872b07_06707207_852b80c0_81ff0676_73070770_2ba00671_90067483;
|
||||
defparam bootram.RAM4.INIT_0E=256'h680c5156_80067407_882b83fe_872b0770_06710772_852b80c0_10900671_7a882a70;
|
||||
defparam bootram.RAM4.INIT_0F=256'h0c7851d9_81998577_81a18056_52d9a13f_57515157_58525a5a_51555351_67405b51;
|
||||
defparam bootram.RAM4.INIT_10=256'h88067173_0672812a_71832a84_71872a07_852a8206_81ff0670_ffff0670_933f7783;
|
||||
defparam bootram.RAM4.INIT_11=256'h7f067081_0677872b_852b80c0_81ff0676_73070770_2ba00671_90067483_07077310;
|
||||
defparam bootram.RAM4.INIT_12=256'h71730707_812a8806_2a840672_2a077183_82067187_2a70852a_07077a88_80067373;
|
||||
defparam bootram.RAM4.INIT_13=256'h70818006_872b6906_80c00677_0676852b_077081ff_06717307_74832ba0_73109006;
|
||||
defparam bootram.RAM4.INIT_14=256'h5b515852_57525a55_44525351_5151586b_ff066d0c_077083ff_70882b7b_73730707;
|
||||
defparam bootram.RAM4.INIT_15=256'h96800678_3f77902a_7851d7dc_9983770c_c1805581_d7ea3f81_575c5653_53515752;
|
||||
defparam bootram.RAM4.INIT_16=256'h812a8806_2a840672_2a077183_82067187_0670852a_077081ff_ff067073_902a7081;
|
||||
defparam bootram.RAM4.INIT_17=256'h872b6106_80c00677_0676852b_077081ff_06717307_74832ba0_73109006_71730707;
|
||||
defparam bootram.RAM4.INIT_18=256'h07077088_66067173_0672872b_852b80c0_10900671_7a882a70_73730707_70818006;
|
||||
defparam bootram.RAM4.INIT_19=256'h515952d6_5a5b5751_53515852_5b515852_69425a54_6a0c5152_83ffff06_2b750770;
|
||||
defparam bootram.RAM4.INIT_1A=256'h3f80f077_7851d6b8_3f71770c_7851d6c0_3f80770c_5252d6c8_70780c79_d33f9985;
|
||||
defparam bootram.RAM4.INIT_1B=256'h7851d694_3f71770c_7851d69c_3f71770c_5252d6a4_70780c79_af3f8880_0c7851d6;
|
||||
defparam bootram.RAM4.INIT_1C=256'h839a3f86_5280d051_fc055380_8254873d_04fb3d0d_3f8c3d0d_7851d68c_3f71770c;
|
||||
defparam bootram.RAM4.INIT_1D=256'h93269038_59577782_84120858_80d73d08_80d53d08_ffb23d0d_873d0d04_3d22800c;
|
||||
defparam bootram.RAM4.INIT_1E=256'h80ec8805_38758429_962681a2_9f165675_81ac39ff_51da873f_5280ebbc_77538294;
|
||||
defparam bootram.RAM4.INIT_1F=256'h5f80c65c_f73f8008_80085e8c_398cf33f_085e818c_c03f8008_80c15ccd_56750804;
|
||||
defparam bootram.RAM4.INIT_20=256'hfab0518a_17085280_1708538c_80ea3990_5e80d65c_83ffff06_883f8008_80fa39ff;
|
||||
defparam bootram.RAM4.INIT_21=256'h5cbe3980_863880c4_5675802e_0881ff06_8ae53f80_80fab051_5c80d539_a03f80c5;
|
||||
defparam bootram.RAM4.INIT_22=256'h05539017_d03dfe80_5ca63980_873f80d7_17085189_1708528c_94175390_c25cb939;
|
||||
defparam bootram.RAM4.INIT_23=256'h82945580_8339a05c_51f7f83f_5c805280_8f3980d3_3f80d25c_08518c93_08528c17;
|
||||
defparam bootram.RAM4.INIT_24=256'h887826ec_34811858_57753377_3d790557_771980d2_833d5a58_0554800b_d03dfdec;
|
||||
defparam bootram.RAM4.INIT_25=256'hf83d0d7a_5183873f_cdf93fff_80ece451_04803d0d_80d03d0d_51e1aa3f_38838082;
|
||||
defparam bootram.RAM4.INIT_26=256'h81055833_3d347670_5754738a_38758117_807425b7_ff165654_57575874_7c7f7f5a;
|
||||
defparam bootram.RAM4.INIT_27=256'h51d3953f_ff06548a_3f800881_0651d1a9_527781ff_8a3dfc05_05348253_028405a1;
|
||||
defparam bootram.RAM4.INIT_28=256'h8338dc56_80de5674_a3053355_fa3d0d02_8a3d0d04_5473800c_38c13981_73802e85;
|
||||
defparam bootram.RAM4.INIT_29=256'h5702ab05_f93d0d7c_883d0d04_51ff893f_f75280d0_fc055381_8154883d_75883d34;
|
||||
defparam bootram.RAM4.INIT_2A=256'h5473802e_ff067056_3f800881_5256d0c9_a7053370_fc055202_8153893d_33893d34;
|
||||
defparam bootram.RAM4.INIT_2B=256'h38815574_73802e83_06705654_800881ff_51cecb3f_537b5275_25973876_9e388077;
|
||||
defparam bootram.RAM4.INIT_2C=256'hff065574_3f800881_d051ffa0_81f75280_3dfc0553_0d815488_0d04fa3d_800c893d;
|
||||
defparam bootram.RAM4.INIT_2D=256'h56755574_06833881_de2e0981_56567480_0b883d33_3f953980_f051ccaf_8a3880ec;
|
||||
defparam bootram.RAM4.INIT_2E=256'h81c0b00c_0c89b00b_0b81c0ac_c0800ca6_80eb0b81_81c0940c_0d04990b_800c883d;
|
||||
defparam bootram.RAM4.INIT_2F=256'h70812a70_81c0a408_81c0a00c_0c51820b_0781c098_80067081_72882bbe_04803d0d;
|
||||
defparam bootram.RAM4.INIT_30=256'h810781c0_be800670_0d72882b_0d04803d_800c823d_81c0a808_5170f138_81065151;
|
||||
defparam bootram.RAM4.INIT_31=256'hf138823d_51515170_2a708106_a4087081_a00c81c0_840b81c0_81c09c0c_980c5173;
|
||||
defparam bootram.RAM4.INIT_32=256'h83065271_718a3872_75830652_57719138_06555557_7a7c7283_fa3d0d78_0d04ff39;
|
||||
defparam bootram.RAM4.INIT_33=256'h08720c52_11771270_73822b77_75279438_72555573_3f72822a_815189b2_802e8638;
|
||||
defparam bootram.RAM4.INIT_34=256'h5353c9c3_11335451_0680ed90_842a708f_3d0d7470_3d0d04fe_54e93988_54528114;
|
||||
defparam bootram.RAM4.INIT_35=256'h0870882a_5382e090_0d8386d0_0d04fe3d_b63f843d_335253c9_80ed9011_3f728f06;
|
||||
defparam bootram.RAM4.INIT_36=256'hfc3d0d02_843d0d04_51ca803f_3880eda0_135372e9_2e8e38ff_51527180_70810651;
|
||||
defparam bootram.RAM4.INIT_37=256'h2a708106_90087088_d05382e0_55558386_80c08007_8c800607_80ff067c_9b05337a;
|
||||
defparam bootram.RAM4.INIT_38=256'he0900c77_800c7382_3f7882e0_a051c9c3_e93880ed_ff135372_802e8e38_51515271;
|
||||
defparam bootram.RAM4.INIT_39=256'h90087088_d05382e0_a9388386_5274802e_e0900c74_82800782_e0980c73_81ff0682;
|
||||
defparam bootram.RAM4.INIT_3A=256'h08527180_3f82e080_a051c8ff_e93880ed_ff135372_802e8e38_51515271_2a708106;
|
||||
defparam bootram.RAM4.INIT_3B=256'h863d0d04_51fee13f_53805280_55885480_940c8880_810b82e0_04fc3d0d_0c863d0d;
|
||||
defparam bootram.RAM4.INIT_3C=256'h04fc3d0d_0c863d0d_81ff0680_cb3f8008_528151fe_8a805381_80559054_fc3d0d88;
|
||||
defparam bootram.RAM4.INIT_3D=256'h06800c82_08813281_0dca3f80_0d04803d_af3f863d_528051fe_54865381_88805588;
|
||||
defparam bootram.RAM4.INIT_3E=256'h85923f75_3d0d7756_3d0d04fb_2ef43882_06517080_800881ff_3d0deb3f_3d0d0480;
|
||||
defparam bootram.RAM4.INIT_3F=256'hfdde3f87_81528051_9b0a0753_fe9b0a06_55a05475_b43f8880_38dd3fff_8008269b;
|
||||
defparam bootram.RAM5.INIT_00=256'h38751754_ff2681b4_80557381_11565757_cb3d08ff_c93d0880_ba3d0d80_3d0d04ff;
|
||||
defparam bootram.RAM5.INIT_01=256'h3d085273_755380cb_548cbe3f_883d7052_5381ff52_a7388280_80082681_84ce3f73;
|
||||
defparam bootram.RAM5.INIT_02=256'h0a0680c0_0c76fec0_0b82e090_980c8880_3f7482e0_d43ffce6_fefd3ffe_518b993f;
|
||||
defparam bootram.RAM5.INIT_03=256'h3f80c83d_900cfcb6_a00b82e0_e0900c8a_88a00b82_82e0980c_800c810b_0a0782e0;
|
||||
defparam bootram.RAM5.INIT_04=256'h82e0840c_88157008_880c54fe_700882e0_54fe8415_82e08c0c_80157008_558f56fe;
|
||||
defparam bootram.RAM5.INIT_05=256'hff169016_0cfbf73f_0b82e090_900c8a80_800b82e0_800c5488_700882e0_54fe8c15;
|
||||
defparam bootram.RAM5.INIT_06=256'h7b7d7212_f93d0d79_c83d0d04_74800c80_980c8155_800b82e0_25ffbc38_56567580;
|
||||
defparam bootram.RAM5.INIT_07=256'h5473802e_7581ff06_2e80c338_81577480_2680cb38_57738008_838a3f80_575a5656;
|
||||
defparam bootram.RAM5.INIT_08=256'h19767631_3f731674_7551fdeb_77537352_83387654_57767527_74317555_a2388280;
|
||||
defparam bootram.RAM5.INIT_09=256'h0c893d0d_81577680_39fd8c3f_828054dc_7527e138_74548280_802e8e38_57595674;
|
||||
defparam bootram.RAM5.INIT_0A=256'h0b88160c_27903880_3f800874_1354829c_2e8d3873_54557380_76787a56_04fc3d0d;
|
||||
defparam bootram.RAM5.INIT_0B=256'h08307276_81ec3f80_16565152_707406ff_3f800830_a63981fa_0c80750c_800b8416;
|
||||
defparam bootram.RAM5.INIT_0C=256'h0881ff06_fc983f80_3d0d7554_3d0d04fd_fcc93f86_160c7151_160c7188_0c740684;
|
||||
defparam bootram.RAM5.INIT_0D=256'h7088160c_08800805_b13f8814_2e943881_08841508_81538814_802e9f38_70545271;
|
||||
defparam bootram.RAM5.INIT_0E=256'h51f9fd3f_53815281_5481f90a_888055a0_04fc3d0d_0c853d0d_80537280_51fc943f;
|
||||
defparam bootram.RAM5.INIT_0F=256'h882a7081_d43f8008_7480c238_fa840855_fb3d0d80_863d0d04_0a06800c_8008fe80;
|
||||
defparam bootram.RAM5.INIT_10=256'h7380c02e_83388155_3f73a02e_5154cdbe_edbc5458_56715580_81ff0670_ff068008;
|
||||
defparam bootram.RAM5.INIT_11=256'h08ea1155_0c80fa84_7580fa84_fe3f9c39_edd451c2_2e8a3880_06547380_93387481;
|
||||
defparam bootram.RAM5.INIT_12=256'h800880ee_04ff913f_0c873d0d_dc3f7480_cd843ff4_80edf451_8d387452_55827427;
|
||||
defparam bootram.RAM5.INIT_13=256'h3d0d7d56_800c04f6_0b80082b_fefa3f81_2b800c04_810b8008_0c04f23f_de053380;
|
||||
defparam bootram.RAM5.INIT_14=256'h0c810b82_2b82e080_840c7c88_8b0b82e0_82e0900c_0c88800b_0b82e098_f8b03f80;
|
||||
defparam bootram.RAM5.INIT_15=256'hd3388880_73762780_7e558054_0cf7ff3f_0b82e090_900c8aa8_a80b82e0_e0980c88;
|
||||
defparam bootram.RAM5.INIT_16=256'h085a82e0_5982e084_82e08808_e08c0858_f7e43f82_82e0900c_0c8a800b_0b82e090;
|
||||
defparam bootram.RAM5.INIT_17=256'h51703375_91387117_52717327_38705380_70732783_52579053_3d767531_80085b88;
|
||||
defparam bootram.RAM5.INIT_18=256'h0d7251f6_0d04803d_980c8c3d_800b82e0_54ffa939_ec397214_34811252_70810557;
|
||||
defparam bootram.RAM5.INIT_19=256'h0870800c_82de3f80_88050851_08528c08_8c088c05_3d0d8053_028c0cfd_a13f8c08;
|
||||
defparam bootram.RAM5.INIT_1A=256'h5182b93f_08880508_0508528c_538c088c_fd3d0d81_08028c0c_8c0c048c_54853d0d;
|
||||
defparam bootram.RAM5.INIT_1B=256'h08880508_fc050c8c_800b8c08_0cf93d0d_8c08028c_0d8c0c04_0c54853d_80087080;
|
||||
defparam bootram.RAM5.INIT_1C=256'h38810b8c_fc050888_050c8c08_0b8c08f4_88050c80_08308c08_8c088805_8025ab38;
|
||||
defparam bootram.RAM5.INIT_1D=256'h308c088c_088c0508_25ab388c_8c050880_050c8c08_088c08fc_8c08f405_08f4050c;
|
||||
defparam bootram.RAM5.INIT_1E=256'h8c08fc05_08f00508_f0050c8c_810b8c08_05088838_0c8c08fc_8c08f005_050c800b;
|
||||
defparam bootram.RAM5.INIT_1F=256'h08fc0508_050c548c_708c08f8_a73f8008_05085181_528c0888_088c0508_0c80538c;
|
||||
defparam bootram.RAM5.INIT_20=256'h0c048c08_893d0d8c_70800c54_08f80508_f8050c8c_08308c08_8c08f805_802e8c38;
|
||||
defparam bootram.RAM5.INIT_21=256'h8c088805_88050830_93388c08_05088025_0c8c0888_8c08fc05_3d0d800b_028c0cfb;
|
||||
defparam bootram.RAM5.INIT_22=256'h81538c08_088c050c_0508308c_388c088c_0880258c_8c088c05_08fc050c_0c810b8c;
|
||||
defparam bootram.RAM5.INIT_23=256'h8c388c08_0508802e_548c08fc_08f8050c_8008708c_0851ad3f_8c088805_8c050852;
|
||||
defparam bootram.RAM5.INIT_24=256'h0cfd3d0d_8c08028c_0d8c0c04_0c54873d_05087080_0c8c08f8_8c08f805_f8050830;
|
||||
defparam bootram.RAM5.INIT_25=256'h08fc0508_27ac388c_08880508_8c05088c_050c8c08_0b8c08f8_fc050c80_810b8c08;
|
||||
defparam bootram.RAM5.INIT_26=256'h0508108c_0c8c08fc_8c088c05_8c050810_99388c08_8c050824_800b8c08_802ea338;
|
||||
defparam bootram.RAM5.INIT_27=256'h388c0888_050826a1_088c0888_8c088c05_2e80c938_fc050880_c9398c08_08fc050c;
|
||||
defparam bootram.RAM5.INIT_28=256'h0c8c08fc_8c08f805_fc050807_05088c08_0c8c08f8_8c088805_8c050831_05088c08;
|
||||
defparam bootram.RAM5.INIT_29=256'h08802e8f_8c089005_0cffaf39_8c088c05_0508812a_0c8c088c_8c08fc05_0508812a;
|
||||
defparam bootram.RAM5.INIT_2A=256'h08f40508_050c518c_708c08f4_08f80508_518d398c_08f4050c_0508708c_388c0888;
|
||||
defparam bootram.RAM5.INIT_2B=256'h70802eb0_07830651_8c387474_52837227_77795656_fc3d0d78_0d8c0c04_800c853d;
|
||||
defparam bootram.RAM5.INIT_2C=256'h14545555_158115ff_06bd3881_712e0981_33525372_38743374_71ff2ea0_38ff1252;
|
||||
defparam bootram.RAM5.INIT_2D=256'h8f388411_2e098106_70087308_74745451_863d0d04_800b800c_8106e238_71ff2e09;
|
||||
defparam bootram.RAM5.INIT_2E=256'hfc3d0d76_863d0d04_7131800c_ffaf3972_70735555_8326e938_54545171_8414fc14;
|
||||
defparam bootram.RAM5.INIT_2F=256'h2e983872_125271ff_2ea738ff_06517080_72750783_72278c38_5555558f_70797b55;
|
||||
defparam bootram.RAM5.INIT_30=256'h04745172_0c863d0d_ea387480_2e098106_125271ff_055634ff_33747081_70810554;
|
||||
defparam bootram.RAM5.INIT_31=256'h08717084_70840554_05530c72_08717084_70840554_05530c72_08717084_70840554;
|
||||
defparam bootram.RAM5.INIT_32=256'h72708405_72279538_26c93883_1252718f_05530cf0_08717084_70840554_05530c72;
|
||||
defparam bootram.RAM5.INIT_33=256'h8c059f05_76797102_39fc3d0d_7054ff83_8326ed38_fc125271_8405530c_54087170;
|
||||
defparam bootram.RAM5.INIT_34=256'h73708105_2e933873_125271ff_2ea238ff_06517080_8a387483_55837227_33575553;
|
||||
defparam bootram.RAM5.INIT_35=256'h902b0751_75077071_7474882b_863d0d04_3874800c_098106ef_5271ff2e_5534ff12;
|
||||
defparam bootram.RAM5.INIT_36=256'h72717084_8405530c_0c727170_70840553_530c7271_71708405_27a53872_54518f72;
|
||||
defparam bootram.RAM5.INIT_37=256'h26f23870_12527183_05530cfc_72717084_72279038_26dd3883_1252718f_05530cf0;
|
||||
defparam bootram.RAM5.INIT_38=256'h802e80d4_83065170_38717407_802e80d9_55555272_7a7c7054_fa3d0d78_53ff9039;
|
||||
defparam bootram.RAM5.INIT_39=256'h387081ff_802e8187_06a93872_712e0981_33565174_38713374_72ff2eb1_38ff1353;
|
||||
defparam bootram.RAM5.INIT_3A=256'h33565170_38713374_098106d1_5272ff2e_ff155555_81128115_2e80fc38_06517080;
|
||||
defparam bootram.RAM5.INIT_3B=256'h38710874_83732788_71745755_883d0d04_5270800c_71315152_81ff0671_81ff0675;
|
||||
defparam bootram.RAM5.INIT_3C=256'h0670f884_fbfdff12_087009f7_2eb13874_13537280_ff9739fc_74765552_082e8838;
|
||||
defparam bootram.RAM5.INIT_3D=256'h74765552_082ed038_38740876_837327d0_84175755_9a388415_51515170_82818006;
|
||||
defparam bootram.RAM5.INIT_3E=256'h80fa880c_2e9e3873_54547281_80eeb408_3d0d800b_3d0d04fd_0b800c88_fedf3980;
|
||||
defparam bootram.RAM5.INIT_3F=256'h0cffa8e0_7280fa88_51f6a33f_893f8008_8151ffb0_80eef852_ffa8993f_ffa8fd3f;
|
||||
defparam bootram.RAM6.INIT_00=256'hef800bfc_ff3d0d80_3f00ff39_0851f686_afec3f80_528151ff_3f80eef8_3fffa7fc;
|
||||
defparam bootram.RAM6.INIT_01=256'h0d0404ff_f138833d_2e098106_525270ff_fc127008_9138702d_5270ff2e_05700852;
|
||||
defparam bootram.RAM6.INIT_02=256'h636b6574_6c207061_6e74726f_6e20636f_6f722069_21457272_00000040_a98b3f04;
|
||||
defparam bootram.RAM6.INIT_03=256'h6c697479_74696269_6f6d7061_65642063_70656374_3a204578_646c6572_2068616e;
|
||||
defparam bootram.RAM6.INIT_04=256'h6f722069_21457272_25640a00_676f7420_62757420_25642c20_62657220_206e756d;
|
||||
defparam bootram.RAM6.INIT_05=256'h70656374_3a204578_646c6572_2068616e_636b6574_6c207061_6e74726f_6e20636f;
|
||||
defparam bootram.RAM6.INIT_06=256'h74202564_7420676f_2c206275_68202564_656e6774_6164206c_61796c6f_65642070;
|
||||
defparam bootram.RAM6.INIT_07=256'h203d2025_70656564_643a2073_616e6765_6b206368_206c696e_0a657468_0a000000;
|
||||
defparam bootram.RAM6.INIT_08=256'h720a0000_6f616465_6f6f746c_44502062_31302055_50204e32_0a555352_640a0000;
|
||||
defparam bootram.RAM6.INIT_09=256'h640a0000_723a2025_756d6265_7479206e_62696c69_70617469_20636f6d_46504741;
|
||||
defparam bootram.RAM6.INIT_0A=256'h723a2025_756d6265_7479206e_62696c69_70617469_20636f6d_77617265_4669726d;
|
||||
defparam bootram.RAM6.INIT_0B=256'h7061636b_65727920_65636f76_69702072_476f7420_00000000_61646472_640a0000;
|
||||
defparam bootram.RAM6.INIT_0C=256'h0000078f_00000765_0000078f_0000078f_000006df_000006f6_00000000_65743a20;
|
||||
defparam bootram.RAM6.INIT_0D=256'h0000066d_0000078f_000006a7_00000713_0000078f_0000078f_0000078f_0000078f;
|
||||
defparam bootram.RAM6.INIT_0E=256'h00000738_00000733_0000072e_0000067a_0000078f_0000078f_0000078f_0000078f;
|
||||
defparam bootram.RAM6.INIT_0F=256'h6e203d20_7273696f_70207665_20636869_4c4d5331_00000753_00000746_0000073f;
|
||||
defparam bootram.RAM6.INIT_10=256'h30782578_6e203d20_7273696f_70207665_20636869_4c4d5332_0a000000_30782578;
|
||||
defparam bootram.RAM6.INIT_11=256'h6932635f_01c300e2_054a0387_15290a94_3fff0000_0050c285_c0a80a02_0a000000;
|
||||
defparam bootram.RAM6.INIT_12=256'h5f666f72_77616974_21000000_696c6564_47206661_4348444f_20574154_72656164;
|
||||
defparam bootram.RAM6.INIT_13=256'h77726974_6932635f_64210000_61696c65_4f472066_54434844_72205741_5f786665;
|
||||
defparam bootram.RAM6.INIT_14=256'h642e2564_25642e25_45000000_64210000_61696c65_4f472066_54434844_65205741;
|
||||
defparam bootram.RAM6.INIT_15=256'hffff0000_ffffffff_00000000_43444546_38394142_34353637_30313233_2e256400;
|
||||
defparam bootram.RAM6.INIT_16=256'h656e2061_6f66206c_656e7420_69676e6d_6420616c_3a206261_5f706b74_73656e64;
|
||||
defparam bootram.RAM6.INIT_17=256'h65642074_6661696c_6f6e3a20_636f6d6d_6e65745f_66000000_72206275_6e642f6f;
|
||||
defparam bootram.RAM6.INIT_18=256'h0a68616e_00000000_666f7220_696e6720_6c6f6f6b_63686520_74206361_6f206869;
|
||||
defparam bootram.RAM6.INIT_19=256'h55445020_0a000000_3d202564_697a6520_72642073_20776569_6172703a_646c655f;
|
||||
defparam bootram.RAM6.INIT_1A=256'h00000000_2025640a_3a202564_67746873_206c656e_74656e74_6e736973_696e636f;
|
||||
defparam bootram.RAM6.INIT_1B=256'h616c697a_6e697469_656e2069_73206265_68206861_466c6173_53504920_0b0b0b0b;
|
||||
defparam bootram.RAM6.INIT_1C=256'h53746172_640a0000_203d2025_6d616765_6f6e2069_75637469_50726f64_65640000;
|
||||
defparam bootram.RAM6.INIT_1D=256'h64696e67_204c6f61_6f64652e_6665206d_6e207361_52582069_20556d54_74696e67;
|
||||
defparam bootram.RAM6.INIT_1E=256'h2076616c_20666f72_6b696e67_43686563_72652e00_726d7761_65206669_20736166;
|
||||
defparam bootram.RAM6.INIT_1F=256'h56616c69_2e2e2e00_6d616765_47412069_6e204650_6374696f_726f6475_69642070;
|
||||
defparam bootram.RAM6.INIT_20=256'h642e2041_666f756e_61676520_4120696d_20465047_74696f6e_6f647563_64207072;
|
||||
defparam bootram.RAM6.INIT_21=256'h2070726f_616c6964_4e6f2076_742e0000_20626f6f_6720746f_7074696e_7474656d;
|
||||
defparam bootram.RAM6.INIT_22=256'h56616c69_2e0a0000_6f756e64_67652066_20696d61_46504741_696f6e20_64756374;
|
||||
defparam bootram.RAM6.INIT_23=256'h204c6f61_756e642e_6520666f_6d776172_20666972_74696f6e_6f647563_64207072;
|
||||
defparam bootram.RAM6.INIT_24=256'h61727469_2e205374_64696e67_206c6f61_73686564_46696e69_2e2e2e00_64696e67;
|
||||
defparam bootram.RAM6.INIT_25=256'h6f6d206d_6e206672_65747572_523a2052_4552524f_2e000000_6d616765_6e672069;
|
||||
defparam bootram.RAM6.INIT_26=256'h65722068_206e6576_6f756c64_73207368_20546869_72616d21_70726f67_61696e20;
|
||||
defparam bootram.RAM6.INIT_27=256'h6669726d_696f6e20_64756374_2070726f_616c6964_4e6f2076_6e210000_61707065;
|
||||
defparam bootram.RAM6.INIT_28=256'h746f2062_75676820_7468726f_696e6720_46616c6c_6e642e20_20666f75_77617265;
|
||||
defparam bootram.RAM6.INIT_29=256'h7420746f_64207365_53706565_2e000000_77617265_6669726d_2d696e20_75696c74;
|
||||
defparam bootram.RAM6.INIT_2A=256'h58000000_57455f52_58000000_57455f54_00000000_4e4f4e45_00000000_2025640a;
|
||||
defparam bootram.RAM6.INIT_2B=256'h6e74726f_7720636f_20666c6f_726e6574_65746865_43000000_45545249_53594d4d;
|
||||
defparam bootram.RAM6.INIT_2C=256'h7825782c_74652030_2077726f_4144563a_4e45475f_4155544f_5048595f_6c3a2000;
|
||||
defparam bootram.RAM6.INIT_2D=256'h21457272_00030203_00000001_00030003_00000000_780a0000_20307825_20676f74;
|
||||
defparam bootram.RAM6.INIT_2E=256'h20457870_6c65723a_68616e64_6b657420_20706163_64617465_6e207570_6f722069;
|
||||
defparam bootram.RAM6.INIT_2F=256'h20676f74_20627574_2025642c_6e677468_64206c65_796c6f61_64207061_65637465;
|
||||
defparam bootram.RAM6.INIT_30=256'h000023f1_00002413_00002428_0000247a_0000247a_000023e4_00000000_2025640a;
|
||||
defparam bootram.RAM6.INIT_31=256'h0000247a_0000247a_0000247a_0000247a_0000247a_0000247a_0000247a_0000247a;
|
||||
defparam bootram.RAM6.INIT_32=256'h00002403_0000247a_0000247a_0000246e_00002457_0000247a_0000247a_0000247a;
|
||||
defparam bootram.RAM6.INIT_33=256'h61642073_6f207265_65642074_4661696c_00000000_6f72740a_0a0a6162_00002444;
|
||||
defparam bootram.RAM6.INIT_34=256'h43444546_38394142_34353637_30313233_67000000_20666c61_626f6f74_61666520;
|
||||
defparam bootram.RAM6.INIT_35=256'h0a666c61_64210000_61696c65_4f472066_54434844_74205741_5f776169_73706966;
|
||||
defparam bootram.RAM6.INIT_36=256'h6c617368_6e672066_0a57726f_25640a00_697a653d_25642073_7970653d_73682074;
|
||||
defparam bootram.RAM6.INIT_37=256'h6c617368_6e672066_0a57726f_00000000_6e67210a_63687475_652e2041_20747970;
|
||||
defparam bootram.RAM6.INIT_38=256'h65000000_792e6578_64756d6d_67210a00_6874756e_64204163_653a2025_2073697a;
|
||||
defparam bootram.RAM6.INIT_39=256'h00003788_00000000_00000000_00000000_ffffff00_ffff00ff_ff00ffff_00ffffff;
|
||||
defparam bootram.RAM6.INIT_3A=256'h000c0000_00190010_ffff0033_04000400_01010100_3fff0000_0050c285_c0a80a02;
|
||||
defparam bootram.RAM6.INIT_3B=256'hffffffff_00003714_10101200_00003560_00003558_00003550_00003548_03197500;
|
||||
defparam bootram.RAM6.INIT_3C=256'h00000000_00000000_00000000_00000000_00000000_00000000_ffffffff_00000000;
|
||||
defparam bootram.RAM6.INIT_3D=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM6.INIT_3E=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
defparam bootram.RAM6.INIT_3F=256'h00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000;
|
||||
|
||||
@@ -1,312 +0,0 @@
|
||||
## Only for xc6slx75 in package fgg484 ver.A 2011/10/12
|
||||
|
||||
## ETH PHY
|
||||
NET "GMII_GTX_CLK" LOC = H21;
|
||||
NET "GMII_RX_CLK" LOC = H22;
|
||||
NET "GMII_TX_CLK" LOC = J22;
|
||||
NET "ETH_LED" LOC = W12;
|
||||
NET "ETH_LEDG" LOC = Y15;
|
||||
NET "GMII_RXD[0]" LOC = L20;
|
||||
NET "GMII_RXD[1]" LOC = K22;
|
||||
NET "GMII_RXD[2]" LOC = K21;
|
||||
NET "GMII_RXD[3]" LOC = F18;
|
||||
NET "GMII_RXD[4]" LOC = J20;
|
||||
NET "GMII_RXD[5]" LOC = F19;
|
||||
NET "GMII_RXD[6]" LOC = F20;
|
||||
NET "GMII_RXD[7]" LOC = G22;
|
||||
NET "GMII_RX_DV" LOC = L22;
|
||||
NET "GMII_RX_ER" LOC = M22;
|
||||
NET "GMII_TXD[0]" LOC = T22;
|
||||
NET "GMII_TXD[1]" LOC = T21;
|
||||
NET "GMII_TXD[2]" LOC = U22;
|
||||
NET "GMII_TXD[3]" LOC = U20;
|
||||
NET "GMII_TXD[4]" LOC = V22;
|
||||
NET "GMII_TXD[5]" LOC = V21;
|
||||
NET "GMII_TXD[6]" LOC = W22;
|
||||
NET "GMII_TXD[7]" LOC = W20;
|
||||
NET "GMII_TX_EN" LOC = T19;
|
||||
NET "GMII_COL" LOC = N22;
|
||||
NET "GMII_CRS" LOC = P20;
|
||||
NET "GMII_TX_ER" LOC = R22;
|
||||
NET "CLK_TO_MAC" LOC = G20;
|
||||
NET "MDIO" LOC = F21;
|
||||
NET "MDC" LOC = F22;
|
||||
NET "PHY_INTn" LOC = E22;
|
||||
NET "PHY_RESETn" LOC = R20;
|
||||
|
||||
## UARTS
|
||||
NET "RXD[1]" LOC = T17; // FPGA output -> FTDI input
|
||||
NET "RXD[2]" LOC = AB17; // FPGA output -> GPS input
|
||||
NET "TXD[1]" LOC = T18; // FPGA input <- FTDI output
|
||||
NET "TXD[2]" LOC = Y17; // FPGA input <- GPS output
|
||||
|
||||
## Global CLK
|
||||
NET "CLK_FPGA_N" LOC = L19; // POSSIBLE UNUSED IF LVCMOS25
|
||||
NET "CLK_FPGA_P" LOC = M20;
|
||||
NET "FPGA_RESET" LOC = AB4;
|
||||
|
||||
## LMS
|
||||
NET "RX1IQSEL" LOC = J4;//"RX_IQ_SEL_0"
|
||||
NET "RX2IQSEL" LOC = P8;//"RX_IQ_SEL_1"
|
||||
NET "TX1IQSEL" LOC = H6;//"TX_IQ_SEL_0"
|
||||
NET "TX2IQSEL" LOC = M5;//"TX_IQ_SEL_1"
|
||||
NET "RX1D[0]" LOC = J1;//"ADC_0[0]"
|
||||
NET "RX1D[1]" LOC = L6;//"ADC_0[1]"
|
||||
NET "RX1D[2]" LOC = H3;//"ADC_0[2]"
|
||||
NET "RX1D[3]" LOC = K6;//"ADC_0[3]"
|
||||
NET "RX1D[4]" LOC = K5;//"ADC_0[4]"
|
||||
NET "RX1D[5]" LOC = H2;//"ADC_0[5]"
|
||||
NET "RX1D[6]" LOC = J3;//"ADC_0[6]"
|
||||
NET "RX1D[7]" LOC = K4;//"ADC_0[7]"
|
||||
NET "RX1D[8]" LOC = J6;//"ADC_0[8]"
|
||||
NET "RX1D[9]" LOC = M8;//"ADC_0[9]"
|
||||
NET "RX1D[10]" LOC = J7;//"ADC_0[10]"
|
||||
NET "RX1D[11]" LOC = N7;//"ADC_0[11]"
|
||||
NET "RX2D[0]" LOC = T2;//"ADC_1[0]"
|
||||
NET "RX2D[1]" LOC = T3;//"ADC_1[1]"
|
||||
NET "RX2D[2]" LOC = U1;//"ADC_1[2]"
|
||||
NET "RX2D[3]" LOC = T4;//"ADC_1[3]"
|
||||
NET "RX2D[4]" LOC = V3;//"ADC_1[4]"
|
||||
NET "RX2D[5]" LOC = T1;//"ADC_1[5]"
|
||||
NET "RX2D[6]" LOC = U3;//"ADC_1[6]"
|
||||
NET "RX2D[7]" LOC = U4;//"ADC_1[7]"
|
||||
NET "RX2D[8]" LOC = V2;//"ADC_1[8]"
|
||||
NET "RX2D[9]" LOC = V1;//"ADC_1[9]"
|
||||
NET "RX2D[10]" LOC = W1;//"ADC_1[10]"
|
||||
NET "RX2D[11]" LOC = W3;//"ADC_1[11]"
|
||||
NET "ADC_CLK_O1" LOC = G3;//"RX1_CLK/2"
|
||||
NET "ADC_CLK_O2" LOC = N1;//"RX2_CLK/2"
|
||||
NET "RX1_EN" LOC = L1;//"ADC_EN_0"
|
||||
NET "RX2_EN" LOC = Y2;//"ADC_EN_1"
|
||||
|
||||
NET "TX1EN" LOC = G1;
|
||||
NET "TX2EN" LOC = N4;
|
||||
NET "TX1CLK" LOC = K3;//"DAC_CLK_0"
|
||||
NET "TX2CLK" LOC = M3;//"DAC_CLK_1"
|
||||
NET "TX1D[0]" LOC = H4;//"DAC_0[0]"
|
||||
NET "TX1D[1]" LOC = H8;//"DAC_0[1]"
|
||||
NET "TX1D[2]" LOC = G4;//"DAC_0[2]"
|
||||
NET "TX1D[3]" LOC = G7;//"DAC_0[3]"
|
||||
NET "TX1D[4]" LOC = F5;//"DAC_0[4]"
|
||||
NET "TX1D[5]" LOC = F7;//"DAC_0[5]"
|
||||
NET "TX1D[6]" LOC = G6;//"DAC_0[6]"
|
||||
NET "TX1D[7]" LOC = E5;//"DAC_0[7]"
|
||||
NET "TX1D[8]" LOC = F3;//"DAC_0[8]"
|
||||
NET "TX1D[9]" LOC = E4;//"DAC_0[9]"
|
||||
NET "TX1D[10]" LOC = H1;//"DAC_0[10]"
|
||||
NET "TX1D[11]" LOC = E6;//"DAC_0[11]"
|
||||
NET "TX2D[0]" LOC = R3;//"DAC_1[0]"
|
||||
NET "TX2D[1]" LOC = L4;//"DAC_1[1]"
|
||||
NET "TX2D[2]" LOC = R1;//"DAC_1[2]"
|
||||
NET "TX2D[3]" LOC = K7;//"DAC_1[3]"
|
||||
NET "TX2D[4]" LOC = P2;//"DAC_1[4]"
|
||||
NET "TX2D[5]" LOC = K8;//"DAC_1[5]"
|
||||
NET "TX2D[6]" LOC = P1;//"DAC_1[6]"
|
||||
NET "TX2D[7]" LOC = P4;//"DAC_1[7]"
|
||||
NET "TX2D[8]" LOC = P5;//"DAC_1[8]"
|
||||
NET "TX2D[9]" LOC = P6;//"DAC_1[9]"
|
||||
NET "TX2D[10]" LOC = P3;//"DAC_1[10]"
|
||||
NET "TX2D[11]" LOC = N3;//"DAC_1[11]"
|
||||
|
||||
NET "LMS1nRST" LOC = L3;//"LMS_RESET_0"
|
||||
NET "LMS2nRST" LOC = Y1;//"LMS_RESET_1"
|
||||
|
||||
NET "SCLK1" LOC = F1;//LMS_SACLK_0
|
||||
NET "SCLK2" LOC = H5;//LMS_SACLK_1
|
||||
|
||||
NET "MISO1" LOC = F2;//"LMS_SADIO_0"
|
||||
NET "MISO2" LOC = N6;//"LMS_SADIO_1"
|
||||
NET "MOSI1" LOC = E3;//"LMS_SADO_0"
|
||||
NET "MOSI2" LOC = M7;//"LMS_SADO_1"
|
||||
NET "SEN1" LOC = E1;//"LMS_SAEN_0"
|
||||
NET "SEN2" LOC = M4;//"LMS_SAEN_1"
|
||||
|
||||
|
||||
NET "DivSw1_N" LOC = K1;
|
||||
NET "DivSw1_P" LOC = K2;
|
||||
NET "DivSw2_N" LOC = M1;
|
||||
NET "DivSw2_P" LOC = M2;
|
||||
|
||||
## PPS
|
||||
NET "PPS_IN" LOC = AB18;
|
||||
|
||||
## SRAM
|
||||
NET "RAM_A[0]" LOC = A14;
|
||||
NET "RAM_A[1]" LOC = C14;
|
||||
NET "RAM_A[2]" LOC = A6;
|
||||
NET "RAM_A[3]" LOC = B6;
|
||||
NET "RAM_A[4]" LOC = D3;
|
||||
NET "RAM_A[5]" LOC = D1;
|
||||
NET "RAM_A[6]" LOC = D2;
|
||||
NET "RAM_A[7]" LOC = B18;
|
||||
NET "RAM_A[8]" LOC = A18;
|
||||
NET "RAM_A[9]" LOC = C17;
|
||||
NET "RAM_A[10]" LOC = A17;
|
||||
NET "RAM_A[11]" LOC = B16;
|
||||
NET "RAM_A[12]" LOC = A16;
|
||||
NET "RAM_A[13]" LOC = C16;
|
||||
NET "RAM_A[14]" LOC = A13;
|
||||
NET "RAM_A[15]" LOC = B12;
|
||||
NET "RAM_A[16]" LOC = A12;
|
||||
NET "RAM_A[17]" LOC = A11;
|
||||
NET "RAM_A[18]" LOC = C1;
|
||||
NET "RAM_A[19]" LOC = A15;
|
||||
NET "RAM_A[20]" LOC = B14;
|
||||
NET "RAM_BWn[0]" LOC = C4;
|
||||
NET "RAM_BWn[1]" LOC = A4;
|
||||
NET "RAM_BWn[2]" LOC = D7;
|
||||
NET "RAM_BWn[3]" LOC = A5;
|
||||
NET "RAM_CENn" LOC = C3;
|
||||
NET "RAM_CLK" LOC = B3;
|
||||
NET "RAM_LDn" LOC = B1;
|
||||
NET "RAM_OEn" LOC = B2;
|
||||
NET "RAM_WEn" LOC = A2;
|
||||
NET "RAM_ZZ" LOC = F16;
|
||||
NET "RAM_D[0]" LOC = E12;
|
||||
NET "RAM_D[1]" LOC = D12;
|
||||
NET "RAM_D[2]" LOC = D13;
|
||||
NET "RAM_D[3]" LOC = C12;
|
||||
NET "RAM_D[4]" LOC = D14;
|
||||
NET "RAM_D[5]" LOC = C13;
|
||||
NET "RAM_D[6]" LOC = D15;
|
||||
NET "RAM_D[7]" LOC = C15;
|
||||
NET "RAM_D[8]" LOC = D17;
|
||||
NET "RAM_D[9]" LOC = D11;
|
||||
NET "RAM_D[10]" LOC = D10;
|
||||
NET "RAM_D[11]" LOC = C10;
|
||||
NET "RAM_D[12]" LOC = D9;
|
||||
NET "RAM_D[13]" LOC = C8;
|
||||
NET "RAM_D[14]" LOC = C7;
|
||||
NET "RAM_D[15]" LOC = D6;
|
||||
NET "RAM_D[16]" LOC = C5;
|
||||
NET "RAM_D[17]" LOC = D5;
|
||||
NET "RAM_D[18]" LOC = A7;
|
||||
NET "RAM_D[19]" LOC = B8;
|
||||
NET "RAM_D[20]" LOC = A8;
|
||||
NET "RAM_D[21]" LOC = C9;
|
||||
NET "RAM_D[22]" LOC = D8;
|
||||
NET "RAM_D[23]" LOC = H13;
|
||||
NET "RAM_D[24]" LOC = F13;
|
||||
NET "RAM_D[25]" LOC = G13;
|
||||
NET "RAM_D[26]" LOC = C6;
|
||||
NET "RAM_D[27]" LOC = E14;
|
||||
NET "RAM_D[28]" LOC = F14;
|
||||
NET "RAM_D[29]" LOC = F15;
|
||||
NET "RAM_D[30]" LOC = E16;
|
||||
NET "RAM_D[31]" LOC = H14;
|
||||
NET "RAM_D[32]" LOC = A9;
|
||||
NET "RAM_D[33]" LOC = B10;
|
||||
NET "RAM_D[34]" LOC = A10;
|
||||
NET "RAM_D[35]" LOC = C11;
|
||||
|
||||
## I2C
|
||||
NET "SCL" LOC = AA14;
|
||||
NET "SDA" LOC = AA16;
|
||||
|
||||
# DAC
|
||||
NET "SCLK_DAC" LOC = AB19;
|
||||
NET "SEN_DAC" LOC = Y19;
|
||||
NET "MOSI_DAC" LOC = AA18;
|
||||
|
||||
## SPI Flash
|
||||
NET "flash_clk" LOC = Y21;
|
||||
NET "flash_cs" LOC = T5;
|
||||
NET "flash_miso" LOC = AA20;
|
||||
NET "flash_mosi" LOC = AB20;
|
||||
|
||||
## LEDS
|
||||
NET "leds[1]" LOC = Y3;
|
||||
NET "leds[2]" LOC = W4;
|
||||
NET "leds[3]" LOC = AB2;
|
||||
NET "leds[4]" LOC = Y4;
|
||||
NET "leds[5]" LOC = AA2;
|
||||
|
||||
### Debug
|
||||
NET "debug[0]" LOC = D22;
|
||||
NET "debug[1]" LOC = E20;
|
||||
NET "debug[2]" LOC = C22;
|
||||
NET "debug[3]" LOC = D21;
|
||||
NET "debug[4]" LOC = B22;
|
||||
NET "debug[5]" LOC = C20;
|
||||
NET "debug[6]" LOC = A21;
|
||||
NET "debug[7]" LOC = B21;
|
||||
NET "debug[8]" LOC = A20;
|
||||
NET "debug[9]" LOC = B20;
|
||||
NET "debug[10]" LOC = H20;
|
||||
NET "debug[11]" LOC = J19;
|
||||
NET "debug[12]" LOC = H18;
|
||||
NET "debug[13]" LOC = H19;
|
||||
NET "debug[14]" LOC = J16;
|
||||
NET "debug[15]" LOC = J17;
|
||||
NET "debug[16]" LOC = G19;
|
||||
NET "debug[17]" LOC = H16;
|
||||
NET "debug[18]" LOC = G16;
|
||||
NET "debug[19]" LOC = D20;
|
||||
NET "debug[20]" LOC = D19;
|
||||
NET "debug[21]" LOC = F17;
|
||||
NET "debug[22]" LOC = K17;
|
||||
NET "debug[23]" LOC = C19;
|
||||
NET "debug[24]" LOC = K19;
|
||||
NET "debug[25]" LOC = N20;
|
||||
NET "debug[26]" LOC = M19;
|
||||
NET "debug[27]" LOC = K20;
|
||||
NET "debug[28]" LOC = N19;
|
||||
NET "debug[29]" LOC = K18;
|
||||
NET "debug[30]" LOC = K16;
|
||||
NET "debug[31]" LOC = L17;
|
||||
NET "debug_clk[0]" LOC = L15;
|
||||
NET "debug_clk[1]" LOC = N16;
|
||||
|
||||
|
||||
#NET "CLK_FPGA_N" IOSTANDARD = LVPECL_25;// POSSIBLE LVCMOS25 OR UNUSED
|
||||
#NET "CLK_FPGA_P" IOSTANDARD = LVPECL_25;// POSSIBLE LVCMOS25
|
||||
|
||||
NET "FPGA_RESET" IOSTANDARD = LVCMOS33;
|
||||
NET "ETH_LED" IOSTANDARD = LVCMOS33;
|
||||
NET "ETH_LEDG" IOSTANDARD = LVCMOS33;
|
||||
NET "CLK_TO_MAC" IOSTANDARD = LVCMOS25;
|
||||
NET "GMII_GTX_CLK" IOSTANDARD = LVCMOS25;
|
||||
|
||||
NET "PPS_IN" IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "SCL" IOSTANDARD = LVCMOS33;
|
||||
NET "SDA" IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "flash_clk" IOSTANDARD = LVCMOS33;
|
||||
NET "flash_cs" IOSTANDARD = LVCMOS33;
|
||||
NET "flash_miso" IOSTANDARD = LVCMOS33;
|
||||
NET "flash_mosi" IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "leds[1]" IOSTANDARD = LVCMOS33;
|
||||
NET "leds[2]" IOSTANDARD = LVCMOS33;
|
||||
NET "leds[3]" IOSTANDARD = LVCMOS33;
|
||||
NET "leds[4]" IOSTANDARD = LVCMOS33;
|
||||
NET "leds[5]" IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "GMII_GTX_CLK" SLEW = SLOW;
|
||||
NET "flash_clk" SLEW = SLOW;
|
||||
|
||||
NET "SCLK_DAC" IOSTANDARD = LVCMOS33;
|
||||
NET "SEN_DAC" IOSTANDARD = LVCMOS33;
|
||||
NET "MOSI_DAC" IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "RXD[1]" IOSTANDARD = LVCMOS33;// FPGA output -> FTDI input
|
||||
NET "RXD[2]" IOSTANDARD = LVCMOS33;// FPGA output -> GPS input
|
||||
NET "RXD[3]" IOSTANDARD = LVCMOS33;
|
||||
NET "TXD[1]" IOSTANDARD = LVCMOS33;// FPGA input <- FTDI output
|
||||
NET "TXD[2]" IOSTANDARD = LVCMOS33;// FPGA input <- GPS output
|
||||
NET "TXD[3]" IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "DivSw1_N" IOSTANDARD = LVCMOS25;
|
||||
NET "DivSw1_P" IOSTANDARD = LVCMOS25;
|
||||
NET "DivSw2_N" IOSTANDARD = LVCMOS25;
|
||||
NET "DivSw2_P" IOSTANDARD = LVCMOS25;
|
||||
|
||||
NET "clk_fpga_p" TNM_NET = "clk_fpga_p";
|
||||
TIMESPEC TS_clk_fpga_p = PERIOD "clk_fpga_p" 38 ns HIGH 50 %;
|
||||
|
||||
NET "clk_to_mac" TNM_NET = "clk_to_mac";
|
||||
TIMESPEC TS_clk_to_mac = PERIOD "clk_to_mac" 8 ns HIGH 50 %;
|
||||
|
||||
NET "GMII_RX_CLK" TNM_NET = "GMII_RX_CLK";
|
||||
TIMESPEC TS_GMII_RX_CLK = PERIOD "GMII_RX_CLK" 8 ns HIGH 50 %;
|
||||
@@ -1,434 +0,0 @@
|
||||
//
|
||||
// Copyright 2011 Ettus Research LLC
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
//`define LVDS 1
|
||||
//`define DCM_FOR_RAMCLK
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module u2plus_umtrx
|
||||
(
|
||||
input CLK_FPGA_P, input CLK_FPGA_N, // Diff
|
||||
|
||||
// ADC 1
|
||||
input ADC_CLK_O1,
|
||||
input RX1IQSEL,
|
||||
output RX1_EN,
|
||||
input [11:0] RX1D,
|
||||
// ADC 2
|
||||
input ADC_CLK_O2,
|
||||
input RX2IQSEL,
|
||||
output RX2_EN,
|
||||
input [11:0] RX2D,
|
||||
// DAC 1
|
||||
input TX1CLK,
|
||||
output TX1EN,
|
||||
output reg TX1IQSEL,
|
||||
output reg [11:0] TX1D,
|
||||
// DAC 2
|
||||
input TX2CLK,
|
||||
output TX2EN,
|
||||
output reg TX2IQSEL,
|
||||
output reg [11:0] TX2D,
|
||||
//LMS 1 Control
|
||||
output SCLK1,
|
||||
output LMS1nRST,
|
||||
output SEN1,
|
||||
input MISO1,
|
||||
output MOSI1,
|
||||
//LMS 2 Control
|
||||
output SCLK2,
|
||||
output LMS2nRST,
|
||||
output SEN2,
|
||||
input MISO2,
|
||||
output MOSI2,
|
||||
|
||||
//Diversity switches
|
||||
output DivSw1_N,
|
||||
output DivSw1_P,
|
||||
output DivSw2_N,
|
||||
output DivSw2_P,
|
||||
|
||||
// Misc, debug
|
||||
output [5:1] leds, // LED4 is shared w/INIT_B
|
||||
input FPGA_RESET,
|
||||
output [1:0] debug_clk,
|
||||
output [31:0] debug,
|
||||
output [3:1] TXD, input [3:1] RXD, // UARTs
|
||||
|
||||
inout SCL, inout SDA, // I2C
|
||||
|
||||
// PPS
|
||||
input PPS_IN,
|
||||
|
||||
// SPI
|
||||
output SEN_DAC, output SCLK_DAC, output MOSI_DAC,
|
||||
|
||||
// GigE PHY
|
||||
input CLK_TO_MAC,
|
||||
|
||||
output reg [7:0] GMII_TXD,
|
||||
output reg GMII_TX_EN,
|
||||
output reg GMII_TX_ER,
|
||||
output GMII_GTX_CLK,
|
||||
input GMII_TX_CLK, // 100mbps clk
|
||||
|
||||
input GMII_RX_CLK,
|
||||
input [7:0] GMII_RXD,
|
||||
input GMII_RX_DV,
|
||||
input GMII_RX_ER,
|
||||
input GMII_COL,
|
||||
input GMII_CRS,
|
||||
|
||||
input PHY_INTn, // open drain
|
||||
inout MDIO,
|
||||
output MDC,
|
||||
output PHY_RESETn,
|
||||
output ETH_LED,
|
||||
output ETH_LEDG,
|
||||
|
||||
// SRAM
|
||||
inout [35:0] RAM_D,
|
||||
output [20:0] RAM_A,
|
||||
output [3:0] RAM_BWn,
|
||||
output RAM_ZZ,
|
||||
output RAM_LDn,
|
||||
output RAM_OEn,
|
||||
output RAM_WEn,
|
||||
output RAM_CENn,
|
||||
output RAM_CLK,
|
||||
|
||||
// SPI Flash
|
||||
output flash_cs,
|
||||
output flash_clk,
|
||||
output flash_mosi,
|
||||
input flash_miso
|
||||
);
|
||||
|
||||
wire CLK_TO_MAC_int, CLK_TO_MAC_int2;
|
||||
|
||||
// FPGA-specific pins connections
|
||||
wire clk_fpga, dsp_clk, clk_div, dcm_out, wb_clk, clk_icap, lms_clk, clock_ready;
|
||||
|
||||
wire DivSw1, DivSw2;
|
||||
OBUF DIVSW1_P_pin (.I(DivSw1),.O(DivSw1_P));
|
||||
OBUF DIVSW1_N_pin (.I(~DivSw1),.O(DivSw1_N));
|
||||
OBUF DIVSW2_P_pin (.I(DivSw2),.O(DivSw2_P));
|
||||
OBUF DIVSW2_N_pin (.I(~DivSw2),.O(DivSw2_N));
|
||||
|
||||
|
||||
wire exp_time_in;
|
||||
|
||||
wire exp_time_out;
|
||||
|
||||
wire exp_user_in;
|
||||
|
||||
wire exp_user_out;
|
||||
|
||||
reg [5:0] clock_ready_d;
|
||||
always @(posedge clk_fpga)
|
||||
clock_ready_d[5:0] <= {clock_ready_d[4:0],clock_ready};
|
||||
wire dcm_rst = ~&clock_ready_d & |clock_ready_d;
|
||||
|
||||
`ifdef LVDS
|
||||
wire [13:0] adc_a, adc_a_inv, adc_b;
|
||||
capture_ddrlvds #(.WIDTH(14)) capture_ddrlvds
|
||||
(.clk(dsp_clk), .ssclk_p(ADC_clkout_p), .ssclk_n(ADC_clkout_n),
|
||||
.in_p({{ADCA_12_p, ADCA_10_p, ADCA_8_p, ADCA_6_p, ADCA_4_p, ADCA_2_p, ADCA_0_p},
|
||||
{ADCB_12_p, ADCB_10_p, ADCB_8_p, ADCB_6_p, ADCB_4_p, ADCB_2_p, ADCB_0_p}}),
|
||||
.in_n({{ADCA_12_n, ADCA_10_n, ADCA_8_n, ADCA_6_n, ADCA_4_n, ADCA_2_n, ADCA_0_n},
|
||||
{ADCB_12_n, ADCB_10_n, ADCB_8_n, ADCB_6_n, ADCB_4_n, ADCB_2_n, ADCB_0_n}}),
|
||||
.out({adc_a_inv,adc_b}));
|
||||
assign adc_a = ~adc_a_inv;
|
||||
`else
|
||||
reg [13:0] adc_a, adc_b;
|
||||
always @(posedge dsp_clk)
|
||||
begin
|
||||
adc_a <= ~{ADCA_12_p,ADCA_12_n, ADCA_10_p,ADCA_10_n, ADCA_8_p,ADCA_8_n, ADCA_6_p,ADCA_6_n,
|
||||
ADCA_4_p,ADCA_4_n, ADCA_2_p,ADCA_2_n, ADCA_0_p,ADCA_0_n };
|
||||
adc_b <= {ADCB_12_p,ADCB_12_n, ADCB_10_p,ADCB_10_n, ADCB_8_p,ADCB_8_n, ADCB_6_p,ADCB_6_n,
|
||||
ADCB_4_p,ADCB_4_n, ADCB_2_p,ADCB_2_n, ADCB_0_p,ADCB_0_n };
|
||||
end
|
||||
`endif // !`ifdef LVDS
|
||||
// Interface to ADC of LMS
|
||||
reg [13:0] adc_a_0, adc_b_0, adc_a_1, adc_b_1;
|
||||
|
||||
assign RX1_EN = 1'b1;
|
||||
assign RX2_EN = 1'b1;
|
||||
|
||||
always @(posedge lms_clk)
|
||||
begin
|
||||
if (RX1IQSEL == 1'b1)
|
||||
adc_a_0 = {RX1D, 2'b00}; //ADC_I signal
|
||||
else
|
||||
adc_b_0 <= {RX1D, 2'b00}; // ADC_Q signal
|
||||
end
|
||||
always @(posedge lms_clk)
|
||||
begin
|
||||
if (RX2IQSEL == 1'b1)
|
||||
adc_a_1 = {RX2D, 2'b00}; //ADC_I signal
|
||||
else
|
||||
adc_b_1 <= {RX2D, 2'b00}; // ADC_Q signal
|
||||
end
|
||||
|
||||
// Handle Clocks
|
||||
|
||||
pll_clk pll_clk_instance
|
||||
(// Clock in ports
|
||||
.clk_in(CLK_FPGA_P), // IN
|
||||
// Clock out ports
|
||||
.wb_clk(wb_clk), // OUT 52 MHz
|
||||
.dsp_clk(dsp_clk), // OUT 104 MHz
|
||||
.clk270_100(clk270_100_buf), // OUT 104 MHz
|
||||
.clk_fpga(clk_fpga), // OUT 104 MHz
|
||||
.clk_icap(clk_icap), // OUT 13 MHz, 180 deg
|
||||
.lms_clk(lms_clk), // OUT 26 MHz
|
||||
// Status and control signals
|
||||
.LOCKED_OUT(LOCKED_OUT)); // OUT
|
||||
|
||||
pll_rx pll_rx_instance
|
||||
(// Clock in ports
|
||||
.gmii_rx_clk(GMII_RX_CLK), // IN
|
||||
// Clock out ports
|
||||
.clk_rx(clk_rx), // OUT
|
||||
.clk_to_mac(CLK_TO_MAC_int2), // OUT
|
||||
.clk_rx_180(clk_rx_180)); // OUT
|
||||
|
||||
|
||||
OFDDRRSE RAM_CLK_i1 (.Q(RAM_CLK),
|
||||
.C0(clk270_100_buf),
|
||||
.C1(~clk270_100_buf),
|
||||
.CE(1'b1),
|
||||
.D0(1'b1),
|
||||
.D1(1'b0),
|
||||
.R(1'b0),
|
||||
.S(1'b0));
|
||||
|
||||
// I2C -- Don't use external transistors for open drain, the FPGA implements this
|
||||
IOBUF scl_pin(.O(scl_pad_i), .IO(SCL), .I(scl_pad_o), .T(scl_pad_oen_o));
|
||||
IOBUF sda_pin(.O(sda_pad_i), .IO(SDA), .I(sda_pad_o), .T(sda_pad_oen_o));
|
||||
|
||||
// LEDs are active low outputs
|
||||
wire [6:0] leds_int;
|
||||
assign {ETH_LEDG,ETH_LED,leds} = {7'b0011111 ^ leds_int}; // drive low to turn on leds
|
||||
|
||||
// SPI
|
||||
wire miso, mosi, sclk;
|
||||
|
||||
assign {SCLK_DAC,MOSI_DAC} = ~SEN_DAC ? {sclk,mosi} : 2'B0;
|
||||
assign {SCLK1,MOSI1} = ~SEN1 ? {sclk,mosi} : 2'B0;
|
||||
assign {SCLK2,MOSI2} = ~SEN2 ? {sclk,mosi} : 2'B0;
|
||||
|
||||
assign miso = (~SEN1 & MISO1) | (~SEN2 & MISO2) ;
|
||||
|
||||
wire GMII_TX_EN_unreg, GMII_TX_ER_unreg;
|
||||
wire [7:0] GMII_TXD_unreg;
|
||||
wire GMII_GTX_CLK_int;
|
||||
|
||||
always @(posedge GMII_GTX_CLK_int)
|
||||
begin
|
||||
GMII_TX_EN <= GMII_TX_EN_unreg;
|
||||
GMII_TX_ER <= GMII_TX_ER_unreg;
|
||||
GMII_TXD <= GMII_TXD_unreg;
|
||||
end
|
||||
|
||||
OFDDRRSE OFDDRRSE_gmii_inst
|
||||
(.Q(GMII_GTX_CLK), // Data output (connect directly to top-level port)
|
||||
.C0(GMII_GTX_CLK_int), // 0 degree clock input
|
||||
.C1(~GMII_GTX_CLK_int), // 180 degree clock input
|
||||
.CE(1), // Clock enable input
|
||||
.D0(0), // Posedge data input
|
||||
.D1(1), // Negedge data input
|
||||
.R(0), // Synchronous reset input
|
||||
.S(0) // Synchronous preset input
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// Instantiate IO for Bidirectional bus to SRAM
|
||||
//
|
||||
wire [35:0] RAM_D_pi;
|
||||
wire [35:0] RAM_D_po;
|
||||
wire RAM_D_poe;
|
||||
|
||||
genvar i;
|
||||
|
||||
generate
|
||||
for (i=0;i<36;i=i+1)
|
||||
begin : gen_RAM_D_IO
|
||||
`ifndef NO_EXT_FIFO
|
||||
|
||||
IOBUF #(
|
||||
.DRIVE(12),
|
||||
.IOSTANDARD("LVCMOS25"),
|
||||
.SLEW("FAST")
|
||||
)
|
||||
RAM_D_i (
|
||||
.O(RAM_D_pi[i]),
|
||||
.I(RAM_D_po[i]),
|
||||
.IO(RAM_D[i]),
|
||||
.T(RAM_D_poe)
|
||||
);
|
||||
`endif // !`ifndef NO_EXT_FIFO
|
||||
end // block: gen_RAM_D_IO
|
||||
endgenerate
|
||||
|
||||
|
||||
|
||||
wire [11:0] dac_a_int1, dac_b_int1, dac_a_int2, dac_b_int2;
|
||||
// Interface to DAC of LMS
|
||||
|
||||
assign TX1EN = 1'b1;
|
||||
assign TX2EN = 1'b1;
|
||||
|
||||
reg dsp_clk_div2_tx=0; // DSP clock signal devided by 2
|
||||
always @(negedge lms_clk)
|
||||
begin
|
||||
dsp_clk_div2_tx = ~dsp_clk_div2_tx;
|
||||
if (dsp_clk_div2_tx)
|
||||
begin
|
||||
TX1D <= dac_a_int1[11:0]; //DAC_I signal
|
||||
TX1IQSEL = 1'b0;
|
||||
TX2D <= dac_a_int2[11:0]; //DAC_I signal
|
||||
TX2IQSEL = 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
TX1D <= dac_b_int1[11:0]; //DAC_Q signal
|
||||
TX1IQSEL = 1'b1;
|
||||
TX2D <= dac_b_int2[11:0]; //DAC_Q signal
|
||||
TX2IQSEL = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
wire pps;
|
||||
assign pps = PPS_IN;
|
||||
|
||||
|
||||
umtrx_core u2p_c(.dsp_clk (dsp_clk),
|
||||
.wb_clk (wb_clk),
|
||||
.lms_clk (clk_icap),
|
||||
.clk_icap (clk_icap),
|
||||
.clock_ready (clock_ready),
|
||||
.clk_to_mac (CLK_TO_MAC_int2),
|
||||
.pps_in (pps),
|
||||
.leds (leds_int),
|
||||
.debug (debug[31:0]),
|
||||
.debug_clk (debug_clk[1:0]),
|
||||
.exp_time_in (exp_time_in),
|
||||
.exp_time_out (exp_time_out),
|
||||
.GMII_COL (GMII_COL),
|
||||
.GMII_CRS (GMII_CRS),
|
||||
.GMII_TXD (GMII_TXD_unreg[7:0]),
|
||||
.GMII_TX_EN (GMII_TX_EN_unreg),
|
||||
.GMII_TX_ER (GMII_TX_ER_unreg),
|
||||
.GMII_GTX_CLK (GMII_GTX_CLK_int),
|
||||
.GMII_TX_CLK (GMII_TX_CLK),
|
||||
.GMII_RXD (GMII_RXD[7:0]),
|
||||
.GMII_RX_CLK (clk_rx),
|
||||
.GMII_RX_DV (GMII_RX_DV),
|
||||
.GMII_RX_ER (GMII_RX_ER),
|
||||
.MDIO (MDIO),
|
||||
.MDC (MDC),
|
||||
.PHY_INTn (PHY_INTn),
|
||||
.PHY_RESETn (PHY_RESETn),
|
||||
.ser_enable (),
|
||||
.ser_prbsen (),
|
||||
.ser_loopen (),
|
||||
.ser_rx_en (),
|
||||
.ser_tx_clk (),
|
||||
.ser_t (),
|
||||
.ser_tklsb (),
|
||||
.ser_tkmsb (),
|
||||
.ser_rx_clk (),
|
||||
.ser_r (),
|
||||
.ser_rklsb (),
|
||||
.ser_rkmsb (),
|
||||
.adc_a_0 (adc_a_0[13:0]),
|
||||
.adc_ovf_a_0 (1'b0),
|
||||
.adc_on_a_0 (),
|
||||
.adc_oe_a_0 (),
|
||||
.adc_b_0 (adc_b_0[13:0]),
|
||||
.adc_ovf_b_0 (1'b0),
|
||||
.adc_on_b_0 (),
|
||||
.adc_oe_b_0 (),
|
||||
.adc_a_1 (adc_a_1[13:0]),
|
||||
.adc_ovf_a_1 (1'b0),
|
||||
.adc_on_a_1 (),
|
||||
.adc_oe_a_1 (),
|
||||
.adc_b_1 (adc_b_1[13:0]),
|
||||
.adc_ovf_b_1 (1'b0),
|
||||
.adc_on_b_1 (),
|
||||
.adc_oe_b_1 (),
|
||||
.lms_res ({LMS2nRST,LMS1nRST}),
|
||||
.dac1_a (dac_a_int2),
|
||||
.dac1_b (dac_b_int2),
|
||||
.dac_a (dac_a_int1),
|
||||
.dac_b (dac_b_int1),
|
||||
.scl_pad_i (scl_pad_i),
|
||||
.scl_pad_o (scl_pad_o),
|
||||
.scl_pad_oen_o (scl_pad_oen_o),
|
||||
.sda_pad_i (sda_pad_i),
|
||||
.sda_pad_o (sda_pad_o),
|
||||
.sda_pad_oen_o (sda_pad_oen_o),
|
||||
.clk_en (),
|
||||
.clk_sel (),
|
||||
.clk_func (),
|
||||
.clk_status (),
|
||||
.sclk (sclk),
|
||||
.mosi (mosi),
|
||||
.miso (miso),
|
||||
.sen_dac (SEN_DAC),
|
||||
.sen_lms1 (SEN1),
|
||||
.sen_lms2 (SEN2),
|
||||
.io_tx (),
|
||||
.io_rx (),
|
||||
//Diversity switches
|
||||
.DivSw1(DivSw1),
|
||||
.DivSw2(DivSw2),
|
||||
`ifndef NO_EXT_FIFO
|
||||
.RAM_D_po (RAM_D_po),
|
||||
.RAM_D_pi (RAM_D_pi),
|
||||
.RAM_D_poe (RAM_D_poe),
|
||||
.RAM_A (RAM_A),
|
||||
.RAM_CE1n (RAM_CE1n),
|
||||
.RAM_CENn (RAM_CENn),
|
||||
.RAM_WEn (RAM_WEn),
|
||||
.RAM_OEn (RAM_OEn),
|
||||
.RAM_LDn (RAM_LDn),
|
||||
`endif // !`ifndef NO_EXT_FIFO
|
||||
.uart_tx_o (TXD[3:1]),
|
||||
.uart_rx_i ({1'b1,RXD[3:1]}),
|
||||
.uart_baud_o (),
|
||||
.sim_mode (1'b0),
|
||||
.clock_divider (2),
|
||||
.button (FPGA_RESET),
|
||||
.spiflash_cs (flash_cs),
|
||||
.spiflash_clk (flash_clk),
|
||||
.spiflash_miso (flash_miso),
|
||||
.spiflash_mosi (flash_mosi)
|
||||
);
|
||||
|
||||
`ifndef NO_EXT_FIFO
|
||||
// Drive low so that RAM does not sleep.
|
||||
assign RAM_ZZ = 0;
|
||||
// Byte Writes are qualified by the global write enable
|
||||
// Always do 36bit operations to extram.
|
||||
assign RAM_BWn = 4'b0000;
|
||||
`endif // !`ifndef NO_EXT_FIFO
|
||||
|
||||
endmodule // u2plus
|
||||
@@ -223,10 +223,16 @@ NET "AUX_SEN1" LOC = AA8; // ch1 ADF4350 load/enable
|
||||
NET "AUX_SEN2" LOC = AB11; // ch2 ADF4350 load/enable
|
||||
NET "AUX_LD1" LOC = AB6; // ch1 ADF4350 lock detect input
|
||||
NET "AUX_LD2" LOC = AB9; // ch2 ADF4350 lock detect input
|
||||
NET "AUX_XX" LOC = AA6; // empty awhile
|
||||
NET "AUX_SCL" LOC = AB7;// I2C clock (teperature sensor etc.)
|
||||
NET "AUX_SDA" LOC = AB10;// I2C data (teperature sensor etc.)
|
||||
|
||||
## PA control
|
||||
NET "ENPA2" LOC = AB21;
|
||||
NET "ENPA1" LOC = AA21;
|
||||
NET "LOWPA" LOC = Y12;
|
||||
NET "DCSYNC" LOC = AA6;
|
||||
|
||||
|
||||
## LEDS
|
||||
NET "leds[1]" LOC = Y3;
|
||||
NET "leds[2]" LOC = W4;
|
||||
@@ -234,7 +240,7 @@ NET "leds[3]" LOC = AB2;
|
||||
NET "leds[4]" LOC = Y4;
|
||||
NET "leds[5]" LOC = AA2;
|
||||
NET "led_stat" LOC = AB3; // output for clock status (or something else) front panel LED !!!
|
||||
// was stupid "master clock" LED indicator
|
||||
// was stupid "master clock" LED indicator
|
||||
|
||||
### Debug // a lot changes !!!
|
||||
NET "debug[0]" LOC = D22;
|
||||
@@ -274,7 +280,7 @@ NET "debug_clk_n" LOC = L19;// was "debug_clk[1]" LOC = N16; !!!
|
||||
|
||||
|
||||
// #NET "CLK_FPGA_N" IOSTANDARD = LVPECL_25;// LVCMOS25 - UNUSED !!!
|
||||
#NET "CLK_FPGA" IOSTANDARD = LVCMOS25;// !!!
|
||||
#NET "CLK_FPGA" IOSTANDARD = LVCMOS25;// !!!
|
||||
|
||||
NET "FPGA_RESET" IOSTANDARD = LVCMOS33;
|
||||
NET "ETH_LED" IOSTANDARD = LVCMOS33;
|
||||
@@ -314,6 +320,11 @@ NET "TXD[1]" IOSTANDARD = LVCMOS33;// FPGA input <- FTDI input !!! in v1a was o
|
||||
NET "TXD[2]" IOSTANDARD = LVCMOS33;// FPGA input <- GPS input !!! in v1a was output !!!
|
||||
NET "TXD[3]" IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "ENPA2" IOSTANDARD = LVCMOS33;
|
||||
NET "ENPA1" IOSTANDARD = LVCMOS33;
|
||||
NET "LOWPA" IOSTANDARD = LVCMOS33;
|
||||
NET "DCSYNC" IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "DivSw1_N" IOSTANDARD = LVCMOS25;
|
||||
NET "DivSw1_P" IOSTANDARD = LVCMOS25;
|
||||
NET "DivSw2_N" IOSTANDARD = LVCMOS25;
|
||||
@@ -328,7 +339,6 @@ NET "AUX_LD1" IOSTANDARD = LVCMOS33;// FPGA input !!!
|
||||
NET "AUX_LD2" IOSTANDARD = LVCMOS33;// FPGA input !!!
|
||||
NET "AUX_SDA" IOSTANDARD = LVCMOS33;// FPGA input !!!
|
||||
NET "AUX_SCL" IOSTANDARD = LVCMOS33;// FPGA input !!!
|
||||
NET "AUX_XX" IOSTANDARD = LVCMOS33;// FPGA input !!!
|
||||
|
||||
NET "CLK_FPGA_P" TNM_NET = "CLK_FPGA_P";
|
||||
TIMESPEC TS_clk_fpga_p = PERIOD "CLK_FPGA_P" 38 ns HIGH 50 %;
|
||||
@@ -337,4 +347,4 @@ NET "CLK_TO_MAC" TNM_NET = "CLK_TO_MAC";
|
||||
TIMESPEC TS_clk_to_mac = PERIOD "CLK_TO_MAC" 8 ns HIGH 50 %;
|
||||
|
||||
NET "GMII_RX_CLK" TNM_NET = "GMII_RX_CLK";
|
||||
TIMESPEC TS_GMII_RX_CLK = PERIOD "GMII_RX_CLK" 8 ns HIGH 50 %;
|
||||
TIMESPEC TS_GMII_RX_CLK = PERIOD "GMII_RX_CLK" 8 ns HIGH 50 %;
|
||||
|
||||
@@ -73,10 +73,16 @@ module u2plus_umtrx_v2
|
||||
output AUX_SEN2,
|
||||
input AUX_LD1,
|
||||
input AUX_LD2,
|
||||
input AUX_XX,
|
||||
//input AUX_XX,
|
||||
inout AUX_SCL,
|
||||
inout AUX_SDA,
|
||||
|
||||
//PA control
|
||||
output ENPA2,
|
||||
output ENPA1,
|
||||
output LOWPA,
|
||||
output DCSYNC,
|
||||
|
||||
// PPS
|
||||
input PPS_IN,
|
||||
output GPS_ON,
|
||||
@@ -305,7 +311,29 @@ wire DivSw1, DivSw2;
|
||||
assign GPS_ON = 1'b1;
|
||||
assign pps = PPS_IN;
|
||||
|
||||
wire enpa2_o, enpa1_o, lowpa_o;
|
||||
OBUF enpa2_pin (.I(enpa2_o),.O(ENPA2));
|
||||
OBUF enpa1_pin (.I(enpa1_o),.O(ENPA1));
|
||||
OBUF lowpa_pin (.I(lowpa_o),.O(LOWPA));
|
||||
|
||||
reg dcsync_o;
|
||||
wire en_dc_sync_o;
|
||||
|
||||
IOBUF DCSYNC_pin (.O(), .IO(DCSYNC), .I(dcsync_o), .T(~en_dc_sync_o));
|
||||
reg [5:0] dc_count;
|
||||
always @(posedge lms_clk) begin
|
||||
if (en_dc_sync_o == 1'b1) begin
|
||||
if (dc_count == 23) begin
|
||||
dcsync_o <= ~dcsync_o;
|
||||
dc_count <= 0;
|
||||
end else
|
||||
dc_count <= dc_count + 1;
|
||||
end else begin
|
||||
dc_count <= 0;
|
||||
dcsync_o <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
umtrx_core u2p_c(
|
||||
.sys_clk (dsp_clk),
|
||||
.dsp_clk (lms_clk),
|
||||
@@ -370,6 +398,11 @@ wire DivSw1, DivSw2;
|
||||
//Diversity switches
|
||||
.DivSw1(DivSw1),
|
||||
.DivSw2(DivSw2),
|
||||
//PA control
|
||||
.enpa2(enpa2_o),
|
||||
.enpa1(enpa1_o),
|
||||
.lowpa(lowpa_o),
|
||||
.en_dc_sync(en_dc_sync_o),
|
||||
`ifndef NO_EXT_FIFO
|
||||
.RAM_D_po (RAM_D_po),
|
||||
.RAM_D_pi (RAM_D_pi),
|
||||
|
||||
@@ -107,6 +107,12 @@ module umtrx_core
|
||||
input aux_ld1,
|
||||
input aux_ld2,
|
||||
|
||||
//PA control
|
||||
output enpa2,
|
||||
output enpa1,
|
||||
output lowpa,
|
||||
output en_dc_sync,
|
||||
|
||||
`ifndef NO_EXT_FIFO
|
||||
// External RAM
|
||||
input [35:0] RAM_D_pi,
|
||||
@@ -131,20 +137,20 @@ module umtrx_core
|
||||
output spiflash_cs, output spiflash_clk, input spiflash_miso, output spiflash_mosi
|
||||
);
|
||||
|
||||
localparam SR_MISC = 0; // 7 regs
|
||||
localparam SR_MISC = 0; // 8 regs
|
||||
localparam SR_TIME64 = 10; // 6
|
||||
localparam SR_BUF_POOL = 16; // 4
|
||||
|
||||
localparam SR_RX_FRONT0 = 20; // 5
|
||||
localparam SR_RX_FRONT1 = 25; // 5
|
||||
localparam SR_RX_CTRL0 = 32; // 9
|
||||
localparam SR_RX_DSP0 = 48; // 7
|
||||
localparam SR_RX_CTRL1 = 80; // 9
|
||||
localparam SR_RX_DSP1 = 96; // 7
|
||||
localparam SR_RX_CTRL2 = 66; // 9
|
||||
localparam SR_RX_DSP2 = 76; // 7
|
||||
localparam SR_RX_CTRL3 = 83; // 9
|
||||
localparam SR_RX_DSP3 = 93; // 7
|
||||
localparam SR_RX_CTRL0 = 30; // 9
|
||||
localparam SR_RX_DSP0 = 40; // 7
|
||||
localparam SR_RX_CTRL1 = 50; // 9
|
||||
localparam SR_RX_DSP1 = 60; // 7
|
||||
localparam SR_RX_CTRL2 = 70; // 9
|
||||
localparam SR_RX_DSP2 = 80; // 7
|
||||
localparam SR_RX_CTRL3 = 90; // 9
|
||||
localparam SR_RX_DSP3 = 100; // 7
|
||||
|
||||
localparam SR_TX_FRONT0 = 110; // ?
|
||||
localparam SR_TX_CTRL0 = 126; // 6
|
||||
@@ -160,17 +166,22 @@ module umtrx_core
|
||||
|
||||
// FIFO Sizes, 9 = 512 lines, 10 = 1024, 11 = 2048
|
||||
// all (most?) are 36 bits wide, so 9 is 1 BRAM, 10 is 2, 11 is 4 BRAMs
|
||||
localparam DSP_RX_FIFOSIZE = 10;
|
||||
localparam DSP_TX_FIFOSIZE = 10;
|
||||
localparam DSP_RX_FIFOSIZE = 9;
|
||||
localparam DSP_TX_FIFOSIZE = 9;
|
||||
localparam ETH_TX_FIFOSIZE = 9;
|
||||
localparam ETH_RX_FIFOSIZE = 11;
|
||||
|
||||
wire [7:0] set_addr, set_addr_dsp, set_addr_sys, set_addr_fe, set_addr_udp_wb, set_addr_udp_sys;
|
||||
wire [31:0] set_data, set_data_dsp, set_data_sys, set_data_fe, set_data_udp_wb, set_data_udp_sys;
|
||||
wire set_stb, set_stb_dsp, set_stb_sys, set_stb_fe, set_stb_udp_wb, set_stb_udp_sys;
|
||||
|
||||
wire set_stb_dsp0, set_stb_dsp1;
|
||||
wire [31:0] set_data_dsp0, set_data_dsp1;
|
||||
wire [7:0] set_addr_dsp0, set_addr_dsp1;
|
||||
|
||||
reg wb_rst;
|
||||
wire dsp_rst, sys_rst, fe_rst;
|
||||
wire net_clr;
|
||||
|
||||
wire [31:0] status;
|
||||
wire bus_error, spi_int, i2c_int, aux_i2c_int, pps_int, onetime_int, periodic_int;
|
||||
@@ -189,8 +200,6 @@ module umtrx_core
|
||||
|
||||
wire [31:0] irq;
|
||||
wire [63:0] vita_time, vita_time_pps;
|
||||
|
||||
wire run_rx0, run_rx1, run_tx0, run_tx1;
|
||||
|
||||
//generate sync reset signals for dsp and sys domains
|
||||
reset_sync sys_rst_sync(.clk(sys_clk), .reset_in(wb_rst), .reset_out(sys_rst));
|
||||
@@ -219,7 +228,7 @@ module umtrx_core
|
||||
wb_1master #(.decode_w(8),
|
||||
.s0_addr(8'b0000_0000),.s0_mask(8'b1100_0000), // Main RAM (0-16K)
|
||||
.s1_addr(8'b0100_0000),.s1_mask(8'b1111_0000), // Packet Router (16-20K)
|
||||
.s2_addr(8'b0101_0000),.s2_mask(8'b1111_1100), // SPI
|
||||
.s2_addr(8'b0101_0000),.s2_mask(8'b1111_1100), // Unused
|
||||
.s3_addr(8'b0101_0100),.s3_mask(8'b1111_1100), // I2C
|
||||
.s4_addr(8'b0101_1000),.s4_mask(8'b1111_1100), // GPSDO
|
||||
.s5_addr(8'b0101_1100),.s5_mask(8'b1111_1100), // Readback
|
||||
@@ -385,7 +394,7 @@ module umtrx_core
|
||||
.set_stb(set_stb_sys), .set_addr(set_addr_sys), .set_data(set_data_sys),
|
||||
.set_stb_udp(set_stb_udp_sys), .set_addr_udp(set_addr_udp_sys), .set_data_udp(set_data_udp_sys),
|
||||
|
||||
.stream_clk(sys_clk), .stream_rst(sys_rst), .stream_clr(1'b0),
|
||||
.stream_clk(sys_clk), .stream_rst(sys_rst), .stream_clr(net_clr),
|
||||
|
||||
.status(status),
|
||||
|
||||
@@ -407,17 +416,80 @@ module umtrx_core
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
// SPI -- Slave #2
|
||||
wire [31:0] spi_debug;
|
||||
wire [31:0] spi_readback;
|
||||
reg [31:0] spi_readback0;
|
||||
reg [31:0] spi_readback1;
|
||||
wire spi_ready;
|
||||
simple_spi_core #(.BASE(SR_SPI_CORE), .WIDTH(5)) shared_spi(
|
||||
|
||||
wire [0:0] AXIS_SPI_CONFIG_tdest;
|
||||
wire [79:0] AXIS_SPI_CONFIG_tdata;
|
||||
wire AXIS_SPI_CONFIG_tvalid;
|
||||
wire AXIS_SPI_CONFIG_tready;
|
||||
|
||||
wire [0:0] AXIS_SPI_READBACK_tdest;
|
||||
wire [31:0] AXIS_SPI_READBACK_tdata;
|
||||
wire AXIS_SPI_READBACK_tvalid;
|
||||
wire AXIS_SPI_READBACK_tready;
|
||||
|
||||
axis_spi_core #(.DESTW(1), .WIDTH(5), .DEBUG(0)) axis_shared_spi(
|
||||
.clock(dsp_clk), .reset(dsp_rst),
|
||||
.set_stb(set_stb_dsp), .set_addr(set_addr_dsp), .set_data(set_data_dsp),
|
||||
.readback(spi_readback), .ready(spi_ready),
|
||||
|
||||
.CONFIG_tdest(AXIS_SPI_CONFIG_tdest),
|
||||
.CONFIG_tdata(AXIS_SPI_CONFIG_tdata),
|
||||
.CONFIG_tvalid(AXIS_SPI_CONFIG_tvalid),
|
||||
.CONFIG_tready(AXIS_SPI_CONFIG_tready),
|
||||
|
||||
.READBACK_tdest(AXIS_SPI_READBACK_tdest),
|
||||
.READBACK_tdata(AXIS_SPI_READBACK_tdata),
|
||||
.READBACK_tvalid(AXIS_SPI_READBACK_tvalid),
|
||||
.READBACK_tready(AXIS_SPI_READBACK_tready),
|
||||
|
||||
.sen({aux_sen2,aux_sen1,sen_dac,sen_lms2,sen_lms1}),
|
||||
.sclk(sclk), .mosi(mosi), .miso(miso), .debug(spi_debug)
|
||||
.sclk(sclk), .mosi(mosi), .miso(miso)
|
||||
);
|
||||
|
||||
//setting register block for spi dest 0 (wishbone) and spi dest 1 (ctrl fifo)
|
||||
//Note: the strobes are exclusive (settings fifo cross clock)
|
||||
wire [79:0] spi_config [0:1];
|
||||
wire [0:1] spi_trigger;
|
||||
wire [0:1] set_stb_dsp_n = {set_stb_dsp0, set_stb_dsp1};
|
||||
genvar i;
|
||||
generate for (i=0; i <= 1; i=i+1) begin
|
||||
setting_reg #(.my_addr(SR_SPI_CORE+2),.width(32)) axis_shared_spi_sr0(
|
||||
.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp_n[i]),.addr(set_addr_dsp),.in(set_data_dsp),
|
||||
.out(spi_config[i][31:0]),.changed(spi_trigger[i]));
|
||||
|
||||
setting_reg #(.my_addr(SR_SPI_CORE+1),.width(32)) axis_shared_spi_sr1(
|
||||
.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp_n[i]),.addr(set_addr_dsp),.in(set_data_dsp),
|
||||
.out(spi_config[i][63:32]),.changed());
|
||||
|
||||
setting_reg #(.my_addr(SR_SPI_CORE+0),.width(16)) axis_shared_spi_sr2(
|
||||
.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp_n[i]),.addr(set_addr_dsp),.in(set_data_dsp),
|
||||
.out(spi_config[i][79:64]),.changed());
|
||||
end endgenerate
|
||||
|
||||
//assign config bus from setting register sources
|
||||
//Note: the triggers are exclusive (settings fifo cross clock)
|
||||
assign AXIS_SPI_CONFIG_tdest = (spi_trigger[0])?1'b0:1'b1;
|
||||
assign AXIS_SPI_CONFIG_tdata = (spi_trigger[0])?spi_config[0]:spi_config[1];
|
||||
assign AXIS_SPI_CONFIG_tvalid = (spi_trigger != 0);
|
||||
|
||||
//create spi ready to block the ctrl fifo ASAP
|
||||
wire spi_ready_now = AXIS_SPI_CONFIG_tready && !AXIS_SPI_CONFIG_tvalid;
|
||||
assign spi_ready = spi_ready_now && spi_ready_prev;
|
||||
reg spi_ready_prev;
|
||||
always @(posedge dsp_clk) begin
|
||||
spi_ready_prev <= spi_ready_now;
|
||||
end
|
||||
|
||||
//readback output bus latches values into readback register
|
||||
assign AXIS_SPI_READBACK_tready = 1'b1;
|
||||
always @(posedge dsp_clk) begin
|
||||
if (AXIS_SPI_READBACK_tvalid && AXIS_SPI_READBACK_tready) begin
|
||||
if (AXIS_SPI_READBACK_tdest == 1'b0) spi_readback0 <= AXIS_SPI_READBACK_tdata;
|
||||
if (AXIS_SPI_READBACK_tdest == 1'b1) spi_readback1 <= AXIS_SPI_READBACK_tdata;
|
||||
end
|
||||
end
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
// I2C -- Slave #3
|
||||
i2c_master_top #(.ARST_LVL(1))
|
||||
@@ -443,7 +515,7 @@ module umtrx_core
|
||||
// Buffer Pool Status -- Slave #5
|
||||
|
||||
//compatibility number -> increment when the fpga has been sufficiently altered
|
||||
localparam compat_num = {16'd9, 16'd0}; //major, minor
|
||||
localparam compat_num = {16'd9, 16'd2}; //major, minor
|
||||
|
||||
wire [31:0] irq_readback = {16'b0, aux_ld2, aux_ld1, button, spi_ready, 12'b0};
|
||||
|
||||
@@ -451,7 +523,7 @@ module umtrx_core
|
||||
(.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_stb_i(s5_stb),
|
||||
.wb_adr_i(s5_adr), .wb_dat_o(s5_dat_i), .wb_ack_o(s5_ack),
|
||||
|
||||
.word00(spi_readback),.word01(32'b0),.word02(32'b0),.word03(32'b0),
|
||||
.word00(spi_readback0),.word01(`NUMDDC),.word02(`NUMDUC),.word03(32'b0),
|
||||
.word04(32'b0),.word05(32'b0),.word06(32'b0),.word07(32'b0),
|
||||
.word08(status),.word09(32'b0),.word10(vita_time[63:32]),
|
||||
.word11(vita_time[31:0]),.word12(compat_num),.word13(irq_readback),
|
||||
@@ -463,7 +535,7 @@ module umtrx_core
|
||||
|
||||
simple_gemac_wrapper #(.RXFIFOSIZE(ETH_RX_FIFOSIZE),
|
||||
.TXFIFOSIZE(ETH_TX_FIFOSIZE)) simple_gemac_wrapper
|
||||
(.clk125(clk_to_mac), .reset(wb_rst),
|
||||
(.clk125(clk_to_mac), .reset(wb_rst | net_clr),
|
||||
.GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN),
|
||||
.GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD),
|
||||
.GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV),
|
||||
@@ -493,10 +565,6 @@ module umtrx_core
|
||||
(.clk_i(dsp_clk), .rst_i(dsp_rst), .set_stb_i(set_stb_dsp), .set_addr_i(set_addr_dsp), .set_data_i(set_data_dsp),
|
||||
.clk_o(fe_clk), .rst_o(fe_rst), .set_stb_o(set_stb_fe), .set_addr_o(set_addr_fe), .set_data_o(set_data_fe));
|
||||
|
||||
wire set_stb_dsp0, set_stb_dsp1;
|
||||
wire [31:0] set_data_dsp0, set_data_dsp1;
|
||||
wire [7:0] set_addr_dsp0, set_addr_dsp1;
|
||||
|
||||
//mux settings_bus_crossclock and settings_readback_bus_fifo_ctrl with prio
|
||||
assign set_stb_dsp = set_stb_dsp0 | set_stb_dsp1;
|
||||
assign set_addr_dsp = set_stb_dsp1? set_addr_dsp1 : set_addr_dsp0;
|
||||
@@ -537,7 +605,7 @@ module umtrx_core
|
||||
.in_data(ctrl_data_dsp), .in_valid(ctrl_valid_dsp), .in_ready(ctrl_ready_dsp),
|
||||
.out_data(resp_data_dsp), .out_valid(resp_valid_dsp), .out_ready(resp_ready_dsp),
|
||||
.strobe(set_stb_dsp1), .addr(set_addr_dsp1), .data(set_data_dsp1),
|
||||
.word00(spi_readback),.word01(32'b0),.word02(32'b0),.word03(32'b0),
|
||||
.word00(spi_readback1),.word01(32'b0),.word02(32'b0),.word03(32'b0),
|
||||
.word04(32'b0),.word05(32'b0),.word06(32'b0),.word07(32'b0),
|
||||
.word08(32'b0),.word09(32'b0),.word10(vita_time[63:32]),
|
||||
.word11(vita_time[31:0]),.word12(32'b0),.word13(irq_readback),
|
||||
@@ -548,9 +616,9 @@ module umtrx_core
|
||||
// Output control lines
|
||||
wire phy_reset;
|
||||
assign PHY_RESETn = ~phy_reset;
|
||||
|
||||
setting_reg #(.my_addr(SR_MISC+0),.width(2)) sr_lms_res
|
||||
(.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),.in(set_data),.out(lms_res),.changed());
|
||||
|
||||
setting_reg #(.my_addr(SR_MISC+0),.width(6)) sr_lms_res
|
||||
(.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),.in(set_data),.out({en_dc_sync, enpa2, enpa1, lowpa, lms_res}),.changed());
|
||||
|
||||
setting_reg #(.my_addr(SR_MISC+1),.width(1)) sr_clear_sfc
|
||||
(.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),.changed(sfc_clear));
|
||||
@@ -565,6 +633,9 @@ module umtrx_core
|
||||
setting_reg #(.my_addr(SR_MISC+5),.width(1)) sr_bld
|
||||
(.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),.in(set_data),.out(bldr_done),.changed());
|
||||
|
||||
setting_reg #(.my_addr(SR_MISC+7),.width(1)) net_reset_sr
|
||||
(.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),.in(set_data),.out(net_clr),.changed());
|
||||
|
||||
// Diversity switches
|
||||
setting_reg #(.my_addr(SR_DIVSW+0),.width(1), .at_reset(32'd1)) sr_divsw1
|
||||
(.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),.in(set_data),.out(DivSw1),.changed());
|
||||
@@ -579,7 +650,8 @@ module umtrx_core
|
||||
// In Rev3 there are only 6 leds, and the highest one is on the ETH connector
|
||||
|
||||
wire [7:0] led_src, led_sw;
|
||||
wire [7:0] led_hw = {run_tx0, run_rx0, run_tx1, run_rx1, 1'b0};
|
||||
wire LEDA, LEDB, LEDC, LEDE;
|
||||
wire [7:0] led_hw = {LEDA, LEDC, LEDE, LEDB, 1'b0};
|
||||
|
||||
setting_reg #(.my_addr(SR_MISC+3),.width(8)) sr_led
|
||||
(.clk(wb_clk),.rst(wb_rst),.strobe(set_stb),.addr(set_addr),.in(set_data),.out(led_sw),.changed());
|
||||
@@ -663,20 +735,20 @@ module umtrx_core
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
// RX Frontend
|
||||
wire [23:0] front0_i, front0_q;
|
||||
wire [23:0] rx_front0_i, rx_front0_q;
|
||||
rx_frontend #(.BASE(SR_RX_FRONT0)) rx_frontend0
|
||||
(
|
||||
.clk(fe_clk), .rst(fe_rst),
|
||||
.set_stb(set_stb_fe),.set_addr(set_addr_fe),.set_data(set_data_fe),
|
||||
.i_out(front0_i), .q_out(front0_q), .run(1'b1),
|
||||
.i_out(rx_front0_i), .q_out(rx_front0_q), .run(1'b1),
|
||||
.adc_a({adc0_a, 4'b0}), .adc_b({adc0_b, 4'b0})
|
||||
);
|
||||
wire [23:0] front1_i, front1_q;
|
||||
wire [23:0] rx_front1_i, rx_front1_q;
|
||||
rx_frontend #(.BASE(SR_RX_FRONT1)) rx_frontend1
|
||||
(
|
||||
.clk(fe_clk), .rst(fe_rst),
|
||||
.set_stb(set_stb_fe),.set_addr(set_addr_fe),.set_data(set_data_fe),
|
||||
.i_out(front1_i), .q_out(front1_q), .run(1'b1),
|
||||
.i_out(rx_front1_i), .q_out(rx_front1_q), .run(1'b1),
|
||||
.adc_a({adc1_a, 4'b0}), .adc_b({adc1_b, 4'b0})
|
||||
);
|
||||
|
||||
@@ -684,16 +756,13 @@ module umtrx_core
|
||||
// RX chains
|
||||
|
||||
//switch to select frontend used per DSP
|
||||
wire [3:0] run_rx_dsp;
|
||||
wire [3:0] rx_fe_sw;
|
||||
setting_reg #(.my_addr(SR_RX_FE_SW),.width(4)) sr_rx_fe_sw
|
||||
(.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),.out(rx_fe_sw),.changed());
|
||||
|
||||
//run logic to map running DSPs to active frontends
|
||||
wire [3:0] run_rx_dsp;
|
||||
assign run_rx0 = |((~run_rx_dsp) & rx_fe_sw);
|
||||
assign run_rx1 = |(run_rx_dsp & rx_fe_sw);
|
||||
|
||||
//*
|
||||
generate
|
||||
if (`NUMDDC > 0) begin
|
||||
umtrx_rx_chain
|
||||
#(
|
||||
.PROT_DEST(4),
|
||||
@@ -710,14 +779,18 @@ module umtrx_core
|
||||
.fe_clk(fe_clk), .fe_rst(fe_rst),
|
||||
.set_stb_dsp(set_stb_dsp), .set_addr_dsp(set_addr_dsp), .set_data_dsp(set_data_dsp),
|
||||
.set_stb_fe(set_stb_fe), .set_addr_fe(set_addr_fe), .set_data_fe(set_data_fe),
|
||||
.front_i(rx_fe_sw[0]?front1_i:front0_i),
|
||||
.front_q(rx_fe_sw[0]?front1_q:front0_q),
|
||||
.front_i(rx_fe_sw[0]?rx_front1_i:rx_front0_i),
|
||||
.front_q(rx_fe_sw[0]?rx_front1_q:rx_front0_q),
|
||||
.adc_stb(rx_fe_sw[0]?adc1_strobe:adc0_strobe),
|
||||
.run(run_rx_dsp[0]),
|
||||
.vita_data_sys(dsp_rx0_data), .vita_valid_sys(dsp_rx0_valid), .vita_ready_sys(dsp_rx0_ready),
|
||||
.vita_time(vita_time)
|
||||
);
|
||||
|
||||
end else begin
|
||||
assign dsp_rx0_valid = 0;
|
||||
assign run_rx_dsp[0] = 0;
|
||||
end
|
||||
if (`NUMDDC > 1) begin
|
||||
umtrx_rx_chain
|
||||
#(
|
||||
.PROT_DEST(5),
|
||||
@@ -733,19 +806,18 @@ module umtrx_core
|
||||
.fe_clk(fe_clk), .fe_rst(fe_rst),
|
||||
.set_stb_dsp(set_stb_dsp), .set_addr_dsp(set_addr_dsp), .set_data_dsp(set_data_dsp),
|
||||
.set_stb_fe(set_stb_fe), .set_addr_fe(set_addr_fe), .set_data_fe(set_data_fe),
|
||||
.front_i(rx_fe_sw[1]?front1_i:front0_i),
|
||||
.front_q(rx_fe_sw[1]?front1_q:front0_q),
|
||||
.front_i(rx_fe_sw[1]?rx_front1_i:rx_front0_i),
|
||||
.front_q(rx_fe_sw[1]?rx_front1_q:rx_front0_q),
|
||||
.adc_stb(rx_fe_sw[1]?adc1_strobe:adc0_strobe),
|
||||
.run(run_rx_dsp[1]),
|
||||
.vita_data_sys(dsp_rx1_data), .vita_valid_sys(dsp_rx1_valid), .vita_ready_sys(dsp_rx1_ready),
|
||||
.vita_time(vita_time)
|
||||
);
|
||||
//*/
|
||||
/*
|
||||
assign dsp_rx0_valid = 0;
|
||||
assign dsp_rx1_valid = 0;
|
||||
//*/
|
||||
/*
|
||||
end else begin
|
||||
assign dsp_rx1_valid = 0;
|
||||
assign run_rx_dsp[1] = 0;
|
||||
end
|
||||
if (`NUMDDC > 2) begin
|
||||
umtrx_rx_chain
|
||||
#(
|
||||
.PROT_DEST(6),
|
||||
@@ -761,14 +833,18 @@ assign dsp_rx1_valid = 0;
|
||||
.fe_clk(fe_clk), .fe_rst(fe_rst),
|
||||
.set_stb_dsp(set_stb_dsp), .set_addr_dsp(set_addr_dsp), .set_data_dsp(set_data_dsp),
|
||||
.set_stb_fe(set_stb_fe), .set_addr_fe(set_addr_fe), .set_data_fe(set_data_fe),
|
||||
.front_i(rx_fe_sw[2]?front1_i:front0_i),
|
||||
.front_q(rx_fe_sw[2]?front1_q:front0_q),
|
||||
.front_i(rx_fe_sw[2]?rx_front1_i:rx_front0_i),
|
||||
.front_q(rx_fe_sw[2]?rx_front1_q:rx_front0_q),
|
||||
.adc_stb(rx_fe_sw[2]?adc1_strobe:adc0_strobe),
|
||||
.run(run_rx_dsp[2]),
|
||||
.vita_data_sys(dsp_rx2_data), .vita_valid_sys(dsp_rx2_valid), .vita_ready_sys(dsp_rx2_ready),
|
||||
.vita_time(vita_time)
|
||||
);
|
||||
|
||||
end else begin
|
||||
assign dsp_rx2_valid = 0;
|
||||
assign run_rx_dsp[2] = 0;
|
||||
end
|
||||
if (`NUMDDC > 3) begin
|
||||
umtrx_rx_chain
|
||||
#(
|
||||
.PROT_DEST(7),
|
||||
@@ -784,24 +860,47 @@ assign dsp_rx1_valid = 0;
|
||||
.fe_clk(fe_clk), .fe_rst(fe_rst),
|
||||
.set_stb_dsp(set_stb_dsp), .set_addr_dsp(set_addr_dsp), .set_data_dsp(set_data_dsp),
|
||||
.set_stb_fe(set_stb_fe), .set_addr_fe(set_addr_fe), .set_data_fe(set_data_fe),
|
||||
.front_i(rx_fe_sw[3]?front1_i:front0_i),
|
||||
.front_q(rx_fe_sw[3]?front1_q:front0_q),
|
||||
.front_i(rx_fe_sw[3]?rx_front1_i:rx_front0_i),
|
||||
.front_q(rx_fe_sw[3]?rx_front1_q:rx_front0_q),
|
||||
.adc_stb(rx_fe_sw[3]?adc1_strobe:adc0_strobe),
|
||||
.run(run_rx_dsp[3]),
|
||||
.vita_data_sys(dsp_rx3_data), .vita_valid_sys(dsp_rx3_valid), .vita_ready_sys(dsp_rx3_ready),
|
||||
.vita_time(vita_time)
|
||||
);
|
||||
//*/
|
||||
//*
|
||||
assign dsp_rx2_valid = 0;
|
||||
assign dsp_rx3_valid = 0;
|
||||
//*/
|
||||
end else begin
|
||||
assign dsp_rx3_valid = 0;
|
||||
assign run_rx_dsp[3] = 0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
// TX Frontend
|
||||
wire [23:0] tx_front0_i, tx_front0_q;
|
||||
wire [3:0] dac0_a_pad, dac0_b_pad;
|
||||
tx_frontend #(.BASE(SR_TX_FRONT0)) tx_frontend0
|
||||
(
|
||||
.clk(fe_clk), .rst(fe_rst),
|
||||
.set_stb(set_stb_fe),.set_addr(set_addr_fe),.set_data(set_data_fe),
|
||||
.tx_i(tx_front0_i), .tx_q(tx_front0_q), .run(1'b1),
|
||||
.dac_a({dac0_a, dac0_a_pad}), .dac_b({dac0_b, dac0_b_pad})
|
||||
);
|
||||
|
||||
wire [23:0] tx_front1_i, tx_front1_q;
|
||||
wire [3:0] dac1_a_pad, dac1_b_pad;
|
||||
tx_frontend #(.BASE(SR_TX_FRONT1)) tx_frontend1
|
||||
(
|
||||
.clk(fe_clk), .rst(fe_rst),
|
||||
.set_stb(set_stb_fe),.set_addr(set_addr_fe),.set_data(set_data_fe),
|
||||
.tx_i(tx_front1_i), .tx_q(tx_front1_q), .run(1'b1),
|
||||
.dac_a({dac1_a, dac1_a_pad}), .dac_b({dac1_b, dac1_b_pad})
|
||||
);
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
// TX chains
|
||||
wire [35:0] sram0_data, sram1_data;
|
||||
wire sram0_valid, sram1_valid;
|
||||
wire sram0_ready, sram1_ready;
|
||||
wire run_tx_dsp0, run_tx_dsp1;
|
||||
|
||||
//switch to select frontend used per DSP
|
||||
wire tx_fe_sw;
|
||||
@@ -809,21 +908,17 @@ assign dsp_rx3_valid = 0;
|
||||
(.clk(dsp_clk),.rst(dsp_rst),.strobe(set_stb_dsp),.addr(set_addr_dsp),.in(set_data_dsp),.out(tx_fe_sw),.changed());
|
||||
|
||||
//assign dac switch
|
||||
wire [11:0] dac0_a_int, dac0_b_int;
|
||||
wire [11:0] dac1_a_int, dac1_b_int;
|
||||
assign {dac0_a, dac0_b} = (tx_fe_sw == 0)? {dac0_a_int, dac0_b_int} : {dac1_a_int, dac1_b_int};
|
||||
assign {dac1_a, dac1_b} = (tx_fe_sw == 1)? {dac0_a_int, dac0_b_int} : {dac1_a_int, dac1_b_int};
|
||||
wire [23:0] dac0_a_int, dac0_b_int;
|
||||
wire [23:0] dac1_a_int, dac1_b_int;
|
||||
assign {tx_front0_i, tx_front0_q} = (tx_fe_sw == 0)? {dac0_a_int, dac0_b_int} : {dac1_a_int, dac1_b_int};
|
||||
assign {tx_front1_i, tx_front1_q} = (tx_fe_sw == 1)? {dac0_a_int, dac0_b_int} : {dac1_a_int, dac1_b_int};
|
||||
|
||||
//assign leds
|
||||
wire run_tx_dsp0, run_tx_dsp1;
|
||||
assign {run_tx0, run_tx1} = (tx_fe_sw == 0)? {run_tx_dsp0, run_tx_dsp1} : {run_tx_dsp1, run_tx_dsp0};
|
||||
|
||||
//*
|
||||
generate
|
||||
if (`NUMDUC > 0) begin
|
||||
umtrx_tx_chain
|
||||
#(
|
||||
.PROT_DEST(0),
|
||||
.DSPNO(0),
|
||||
.FRONT_BASE(SR_TX_FRONT0),
|
||||
.DSP_BASE(SR_TX_DSP0),
|
||||
.CTRL_BASE(SR_TX_CTRL0),
|
||||
.FIFOSIZE(DSP_TX_FIFOSIZE)
|
||||
@@ -835,17 +930,21 @@ assign dsp_rx3_valid = 0;
|
||||
.fe_clk(fe_clk), .fe_rst(fe_rst),
|
||||
.set_stb_dsp(set_stb_dsp), .set_addr_dsp(set_addr_dsp), .set_data_dsp(set_data_dsp),
|
||||
.set_stb_fe(set_stb_fe), .set_addr_fe(set_addr_fe), .set_data_fe(set_data_fe),
|
||||
.dac_a(dac0_a_int), .dac_b(dac0_b_int), .dac_stb(dac0_strobe), .run(run_tx_dsp0),
|
||||
.front_i(dac0_a_int), .front_q(dac0_b_int), .dac_stb(dac0_strobe), .run(run_tx_dsp0),
|
||||
.vita_data_sys(sram0_data), .vita_valid_sys(sram0_valid), .vita_ready_sys(sram0_ready),
|
||||
.err_data_sys(err_tx0_data), .err_valid_sys(err_tx0_valid), .err_ready_sys(err_tx0_ready),
|
||||
.vita_time(vita_time)
|
||||
);
|
||||
|
||||
end else begin
|
||||
assign sram0_ready = 1;
|
||||
assign err_tx0_valid = 0;
|
||||
assign run_tx_dsp0 = 0;
|
||||
end
|
||||
if (`NUMDUC > 1) begin
|
||||
umtrx_tx_chain
|
||||
#(
|
||||
.PROT_DEST(1),
|
||||
.DSPNO(1),
|
||||
.FRONT_BASE(SR_TX_FRONT1),
|
||||
.DSP_BASE(SR_TX_DSP1),
|
||||
.CTRL_BASE(SR_TX_CTRL1),
|
||||
.FIFOSIZE(DSP_TX_FIFOSIZE)
|
||||
@@ -857,18 +956,33 @@ assign dsp_rx3_valid = 0;
|
||||
.fe_clk(fe_clk), .fe_rst(fe_rst),
|
||||
.set_stb_dsp(set_stb_dsp), .set_addr_dsp(set_addr_dsp), .set_data_dsp(set_data_dsp),
|
||||
.set_stb_fe(set_stb_fe), .set_addr_fe(set_addr_fe), .set_data_fe(set_data_fe),
|
||||
.dac_a(dac1_a_int), .dac_b(dac1_b_int), .dac_stb(dac1_strobe), .run(run_tx_dsp1),
|
||||
.front_i(dac1_a_int), .front_q(dac1_b_int), .dac_stb(dac1_strobe), .run(run_tx_dsp1),
|
||||
.vita_data_sys(sram1_data), .vita_valid_sys(sram1_valid), .vita_ready_sys(sram1_ready),
|
||||
.err_data_sys(err_tx1_data), .err_valid_sys(err_tx1_valid), .err_ready_sys(err_tx1_ready),
|
||||
.vita_time(vita_time)
|
||||
);
|
||||
//*/
|
||||
/*
|
||||
assign sram0_ready = 1;
|
||||
assign sram1_ready = 1;
|
||||
assign err_tx0_valid = 0;
|
||||
assign err_tx1_valid = 0;
|
||||
//*/
|
||||
end else begin
|
||||
assign sram1_ready = 1;
|
||||
assign err_tx1_valid = 0;
|
||||
assign run_tx_dsp1 = 0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
// configuration specific LED mapping
|
||||
|
||||
generate
|
||||
if (`NUMDUC == 0) begin
|
||||
//no tx case? -- each RX DSP gets a LED
|
||||
assign {LEDE, LEDB, LEDA, LEDC} = run_rx_dsp;
|
||||
end else begin
|
||||
//default -- map active frontends to LED based on which DSP is active and how they are mapped
|
||||
assign LEDC = |(run_rx_dsp & (~rx_fe_sw));
|
||||
assign LEDB = |(run_rx_dsp & rx_fe_sw);
|
||||
assign {LEDA, LEDE} = (tx_fe_sw == 0)? {run_tx_dsp0, run_tx_dsp1} : {run_tx_dsp1, run_tx_dsp0};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
// ///////////////////////////////////////////////////////////////////////////////////
|
||||
// DSP TX
|
||||
|
||||
@@ -104,13 +104,24 @@ module umtrx_rx_chain
|
||||
/*******************************************************************
|
||||
* Cross clock fifo from sys to dsp clock domain
|
||||
******************************************************************/
|
||||
wire [35:0] vita_data_sys0;
|
||||
wire vita_valid_sys0;
|
||||
wire vita_ready_sys0;
|
||||
|
||||
axi_fifo_2clk #(.WIDTH(36), .SIZE(0)) fifo_2clock_vita
|
||||
(
|
||||
.i_aclk(dsp_clk), .i_tdata(vita_data_dsp), .i_tvalid(vita_valid_dsp), .i_tready(vita_ready_dsp),
|
||||
.o_aclk(sys_clk), .o_tdata(vita_data_sys), .o_tvalid(vita_valid_sys), .o_tready(vita_ready_sys),
|
||||
.o_aclk(sys_clk), .o_tdata(vita_data_sys0), .o_tvalid(vita_valid_sys0), .o_tready(vita_ready_sys0),
|
||||
.reset(dsp_rst | sys_rst)
|
||||
);
|
||||
|
||||
axi_packet_gate #(.WIDTH(36), .SIZE(FIFOSIZE)) fully_buffer_sys_domain
|
||||
(
|
||||
.clk(sys_clk), .reset(sys_rst), .clear(0),
|
||||
.i_tdata(vita_data_sys0), .i_tvalid(vita_valid_sys0), .i_tready(vita_ready_sys0), .i_tlast(vita_data_sys0[33]), .i_terror(0),
|
||||
.o_tdata(vita_data_sys), .o_tvalid(vita_valid_sys), .o_tready(vita_ready_sys), .o_tlast()
|
||||
);
|
||||
|
||||
/*******************************************************************
|
||||
* Debug
|
||||
******************************************************************/
|
||||
|
||||
@@ -6,7 +6,6 @@ module umtrx_tx_chain
|
||||
#(
|
||||
parameter PROT_DEST = 0, //framer index
|
||||
parameter DSPNO = 0, //the dsp unit number: 0, 1, 2...
|
||||
parameter FRONT_BASE = 0,
|
||||
parameter DSP_BASE = 0,
|
||||
parameter CTRL_BASE = 0,
|
||||
parameter FIFOSIZE = 10,
|
||||
@@ -32,9 +31,9 @@ module umtrx_tx_chain
|
||||
input [7:0] set_addr_fe,
|
||||
input [31:0] set_data_fe,
|
||||
|
||||
//dsp clock domain
|
||||
output reg [11:0] dac_a,
|
||||
output reg [11:0] dac_b,
|
||||
//fe clock domain
|
||||
output [23:0] front_i,
|
||||
output [23:0] front_q,
|
||||
input dac_stb,
|
||||
output run,
|
||||
|
||||
@@ -52,28 +51,6 @@ module umtrx_tx_chain
|
||||
wire [63:0] vita_time
|
||||
);
|
||||
|
||||
/*******************************************************************
|
||||
* Cross DAC signals from fe to dsp clock domain
|
||||
* dac_a/b come from a register on the fe clock domain
|
||||
******************************************************************/
|
||||
wire [15:0] dac_a_16, dac_b_16;
|
||||
always @(posedge fe_clk) begin
|
||||
dac_a <= dac_a_16[15:4];
|
||||
dac_b <= dac_b_16[15:4];
|
||||
end
|
||||
|
||||
/*******************************************************************
|
||||
* TX frontend on fe clock domain
|
||||
******************************************************************/
|
||||
wire [23:0] front_i, front_q;
|
||||
tx_frontend #(.BASE(FRONT_BASE)) tx_frontend
|
||||
(
|
||||
.clk(fe_clk), .rst(fe_rst),
|
||||
.set_stb(set_stb_fe),.set_addr(set_addr_fe),.set_data(set_data_fe),
|
||||
.tx_i(front_i), .tx_q(front_q), .run(1'b1),
|
||||
.dac_a(dac_a_16), .dac_b(dac_b_16)
|
||||
);
|
||||
|
||||
/*******************************************************************
|
||||
* DUC chain on fe clock domain
|
||||
******************************************************************/
|
||||
@@ -180,8 +157,6 @@ module umtrx_tx_chain
|
||||
assign DATA[63:32] = vita_sample;
|
||||
assign DATA[95:64] = duc_sample;
|
||||
assign DATA[127:96] = {front_i[23:8], front_q[23:8]};
|
||||
assign DATA[159:128] = {dac_a_16, dac_b_16};
|
||||
assign DATA[191:160] = {dac_a, 4'b0, dac_b, 4'b0};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
@@ -19,19 +19,36 @@
|
||||
## Build the UmTRX UHD module
|
||||
########################################################################
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(UmTRX_UHD)
|
||||
project(UmTRX-UHD)
|
||||
|
||||
########################################################################
|
||||
# extract version info from git
|
||||
########################################################################
|
||||
include(${PROJECT_SOURCE_DIR}/cmake/GetGitRevisionDescription.cmake)
|
||||
git_describe(UMTRX_VERSION --dirty)
|
||||
string(REPLACE "g" "" UMTRX_VERSION ${UMTRX_VERSION}) #remove hash prefix g
|
||||
message(STATUS "UMTRX_VERSION: ${UMTRX_VERSION}")
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/umtrx_version.in.hpp"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/umtrx_version.hpp"
|
||||
IMMEDIATE @ONLY)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
########################################################################
|
||||
## Create a list of module sources
|
||||
########################################################################
|
||||
list(APPEND UMTRX_SOURCES
|
||||
umtrx_impl.cpp
|
||||
umtrx_monitor.cpp
|
||||
umtrx_io_impl.cpp
|
||||
umtrx_find.cpp
|
||||
umtrx_iface.cpp
|
||||
umtrx_eeprom.cpp
|
||||
lms6002d.cpp
|
||||
lms6002d_ctrl.cpp
|
||||
tmp102_ctrl.cpp
|
||||
ads1015_ctrl.cpp
|
||||
power_amp.cpp
|
||||
umtrx_fifo_ctrl.cpp
|
||||
missing/platform.cpp #not properly exported from uhd, so we had to copy it
|
||||
cores/rx_frontend_core_200.cpp
|
||||
@@ -104,6 +121,13 @@ MESSAGE(STATUS "Boost include directories: ${Boost_INCLUDE_DIRS}")
|
||||
MESSAGE(STATUS "Boost library directories: ${Boost_LIBRARY_DIRS}")
|
||||
MESSAGE(STATUS "Boost libraries: ${Boost_LIBRARIES}")
|
||||
|
||||
#additional pthread requirement that may not be automatically included by boost
|
||||
if (UNIX)
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD ON)
|
||||
find_package(Threads)
|
||||
list(APPEND UMTRX_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
# Helpful compiler flags
|
||||
########################################################################
|
||||
@@ -121,6 +145,20 @@ if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
# Look for device filter
|
||||
########################################################################
|
||||
message(STATUS "Checking uhd::device::register_device() API...")
|
||||
message(STATUS " Reading ${UHD_INCLUDE_DIRS}/uhd/device.hpp...")
|
||||
file(READ ${UHD_INCLUDE_DIRS}/uhd/device.hpp device_hpp)
|
||||
string(FIND "${device_hpp}" "device_filter_t" has_device_filter)
|
||||
if ("${has_device_filter}" STREQUAL "-1")
|
||||
message(STATUS " has original API")
|
||||
else()
|
||||
add_definitions(-DUHD_HAS_DEVICE_FILTER)
|
||||
message(STATUS " has filter API")
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
# Build the UmTRX module
|
||||
########################################################################
|
||||
@@ -137,3 +175,30 @@ install(
|
||||
)
|
||||
|
||||
add_subdirectory(utils)
|
||||
|
||||
########################################################################
|
||||
# uninstall target
|
||||
########################################################################
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
|
||||
########################################################################
|
||||
# package generator
|
||||
########################################################################
|
||||
if(NOT CPACK_GENERATOR)
|
||||
set(CPACK_GENERATOR DEB)
|
||||
endif()
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "UmTRX UHD support module")
|
||||
set(CPACK_PACKAGE_VENDOR "Fairwaves")
|
||||
set(CPACK_PACKAGE_CONTACT "http://fairwaves.co/wp/contact-us/")
|
||||
set(CPACK_PACKAGE_VERSION ${UMTRX_VERSION})
|
||||
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-all-dev, uhd")
|
||||
SET(CPACK_DEBIAN_PACKAGE_RECOMMENDS "python")
|
||||
SET(CPACK_PACKAGE_FILE_NAME "umtrx_${UMTRX_VERSION}_${CMAKE_SYSTEM_PROCESSOR}")
|
||||
SET(CPACK_SET_DESTDIR "ON")
|
||||
include(CPack) #include last
|
||||
|
||||
149
host/ads1015_ctrl.cpp
Normal file
149
host/ads1015_ctrl.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
//
|
||||
// Copyright 2014 Fairwaves LLC
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "ads1015_ctrl.hpp"
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1700)
|
||||
#define nan(arg) std::strtod("NAN()", (char**)NULL)
|
||||
#endif
|
||||
|
||||
using namespace uhd;
|
||||
|
||||
ads1015_ctrl::ads1015_ctrl()
|
||||
: _addr(ADS1015_NONE)
|
||||
, _config_reg(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ads1015_ctrl::check(const uhd::i2c_iface::sptr& iface, ads1015_addr addr)
|
||||
{
|
||||
byte_vector_t cmd = boost::assign::list_of(ADS1015_REG_LO_THRES);
|
||||
iface->write_i2c(addr, cmd);
|
||||
|
||||
byte_vector_t vec = iface->read_i2c(addr, 2);
|
||||
uint16_t res = (((uint16_t)vec.at(0)) << 8) | vec.at(1);
|
||||
if (res == 0 || ((res & 0xF) != 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cmd[0] = ADS1015_REG_HI_THRES;
|
||||
iface->write_i2c(addr, cmd);
|
||||
vec = iface->read_i2c(addr, 2);
|
||||
res = (((uint16_t)vec.at(0)) << 8) | vec.at(1);
|
||||
if (res == 0xFFFF || ((res & 0xF) != 0xF)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ads1015_ctrl::init(i2c_iface::sptr iface, ads1015_addr addr)
|
||||
{
|
||||
_iface = iface;
|
||||
_addr = addr;
|
||||
_config_reg = get_reg(ADS1015_REG_CONFIG);
|
||||
}
|
||||
|
||||
void ads1015_ctrl::set_input(ads1015_input input)
|
||||
{
|
||||
_config_reg = (_config_reg & ~ADS1015_CONF_MUX_MASK) |
|
||||
(input << ADS1015_CONF_MUX_OFFS);
|
||||
set_reg(ADS1015_REG_CONFIG, _config_reg);
|
||||
}
|
||||
|
||||
void ads1015_ctrl::set_pga(ads1015_pga pga)
|
||||
{
|
||||
_config_reg = (_config_reg & ~ADS1015_CONF_PGA_MASK) |
|
||||
(pga << ADS1015_CONF_PGA_OFFS);
|
||||
set_reg(ADS1015_REG_CONFIG, _config_reg);
|
||||
}
|
||||
|
||||
void ads1015_ctrl::set_mode(bool powerdown)
|
||||
{
|
||||
if (powerdown) {
|
||||
_config_reg |= ADS1015_CONF_MODE;
|
||||
} else {
|
||||
_config_reg &= ~ADS1015_CONF_MODE;
|
||||
}
|
||||
set_reg(ADS1015_REG_CONFIG, _config_reg);
|
||||
}
|
||||
|
||||
double ads1015_ctrl::get_value()
|
||||
{
|
||||
if (!_iface)
|
||||
return nan("");
|
||||
|
||||
struct coeffs {
|
||||
unsigned u;
|
||||
unsigned d;
|
||||
};
|
||||
|
||||
static const coeffs gain_cfs[] = {
|
||||
{2,3}, // 6
|
||||
{1,1}, // 4
|
||||
{2,1}, // 2
|
||||
{4,1}, // 1
|
||||
{8,1}, // 0.5
|
||||
{16,1}, // 0.25
|
||||
};
|
||||
|
||||
unsigned pga = (_config_reg & ADS1015_CONF_PGA_MASK) >> ADS1015_CONF_PGA_OFFS;
|
||||
if (pga > 5)
|
||||
pga = 5;
|
||||
|
||||
if ((_config_reg & ADS1015_CONF_MODE) == ADS1015_CONF_MODE) {
|
||||
// Power-down mode, start conversion
|
||||
set_reg(ADS1015_REG_CONFIG, _config_reg | ADS1015_CONF_OS);
|
||||
|
||||
// Wait for conversion ready
|
||||
unsigned i;
|
||||
for (i = 0; i < ADS1015_POLL_RDY_WATCHDOG; i++) {
|
||||
if (get_reg(ADS1015_REG_CONFIG) & ADS1015_CONF_OS)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ADS1015_POLL_RDY_WATCHDOG)
|
||||
return nan("");
|
||||
}
|
||||
|
||||
uint16_t raw = get_reg(ADS1015_REG_CONVERSION);
|
||||
double val = (raw >> 4);
|
||||
val = val * gain_cfs[pga].d * 2 / (1000 * gain_cfs[pga].u );
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
uint16_t ads1015_ctrl::get_reg(ads1015_regs reg)
|
||||
{
|
||||
byte_vector_t cmd = boost::assign::list_of(reg);
|
||||
_iface->write_i2c(_addr, cmd);
|
||||
|
||||
byte_vector_t vec = _iface->read_i2c(_addr, 2);
|
||||
uint16_t res = (((uint16_t)vec.at(0)) << 8) | vec.at(1);
|
||||
return res;
|
||||
}
|
||||
|
||||
void ads1015_ctrl::set_reg(ads1015_regs reg, uint16_t value)
|
||||
{
|
||||
byte_vector_t cmd = boost::assign::list_of((uint8_t)reg)((uint8_t)(value >> 8))((uint8_t)(value & 0xFF));
|
||||
_iface->write_i2c(_addr, cmd);
|
||||
}
|
||||
|
||||
132
host/ads1015_ctrl.hpp
Normal file
132
host/ads1015_ctrl.hpp
Normal file
@@ -0,0 +1,132 @@
|
||||
//
|
||||
// Copyright 2014 Fairwaves LLC
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#ifndef INCLUDED_ADS1015_CTRL_HPP
|
||||
#define INCLUDED_ADS1015_CTRL_HPP
|
||||
|
||||
#include <uhd/config.hpp>
|
||||
#include <uhd/types/serial.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
/**
|
||||
* @brief The ads1015_ctrl class
|
||||
*
|
||||
* Control of TI's ADS1015 12bit ADC with 4 muliplexers
|
||||
*/
|
||||
class ads1015_ctrl {
|
||||
public:
|
||||
enum ads1015_addr {
|
||||
ADS1015_NONE = 0,
|
||||
ADS1015_ADDR_GROUND = BOOST_BINARY( 1001000 ),
|
||||
ADS1015_ADDR_VDD = BOOST_BINARY( 1001001 ),
|
||||
ADS1015_ADDR_SDA = BOOST_BINARY( 1001010 ),
|
||||
ADS1015_ADDR_SCL = BOOST_BINARY( 1001011 )
|
||||
};
|
||||
|
||||
enum ads1015_input {
|
||||
ADS1015_CONF_AIN0_AIN1 = 0,
|
||||
ADS1015_CONF_AIN0_AIN3 = 1,
|
||||
ADS1015_CONF_AIN1_AIN1 = 2,
|
||||
ADS1015_CONF_AIN2_AIN1 = 3,
|
||||
|
||||
ADS1015_CONF_AIN0_GND = 4,
|
||||
ADS1015_CONF_AIN1_GND = 5,
|
||||
ADS1015_CONF_AIN2_GND = 6,
|
||||
ADS1015_CONF_AIN3_GND = 7,
|
||||
};
|
||||
|
||||
enum ads1015_pga {
|
||||
ADS1015_PGA_6_144V = 0,
|
||||
ADS1015_PGA_4_096V = 1,
|
||||
ADS1015_PGA_2_048V = 2,
|
||||
ADS1015_PGA_1_024V = 3,
|
||||
ADS1015_PGA_0_512V = 4,
|
||||
ADS1015_PGA_0_256V = 5,
|
||||
};
|
||||
|
||||
enum ads1015_rate {
|
||||
ADS1015_RATE_128SPS = 0,
|
||||
ADS1015_RATE_250SPS = 1,
|
||||
ADS1015_RATE_490SPS = 2,
|
||||
ADS1015_RATE_920SPS = 3,
|
||||
ADS1015_RATE_1600SPS = 4,
|
||||
ADS1015_RATE_2400SPS = 5,
|
||||
ADS1015_RATE_3300SPS = 6,
|
||||
};
|
||||
|
||||
enum ads1015_comp {
|
||||
ADS1015_COMP_QUE_1 = 0,
|
||||
ADS1015_COMP_QUE_2 = 1,
|
||||
ADS1015_COMP_QUE_4 = 2,
|
||||
ADS1015_COMP_QUE_DIS = 3,
|
||||
};
|
||||
|
||||
ads1015_ctrl();
|
||||
|
||||
void init(uhd::i2c_iface::sptr iface, ads1015_addr addr);
|
||||
|
||||
/** @brief check presence of device at @ref addr */
|
||||
static bool check(const uhd::i2c_iface::sptr& iface, ads1015_addr addr);
|
||||
|
||||
void set_input(ads1015_input input);
|
||||
void set_pga(ads1015_pga input);
|
||||
|
||||
double get_value();
|
||||
void set_mode(bool powerdown);
|
||||
|
||||
private:
|
||||
enum ads1015_regs {
|
||||
ADS1015_REG_CONVERSION = 0,
|
||||
ADS1015_REG_CONFIG = 1,
|
||||
ADS1015_REG_LO_THRES = 2,
|
||||
ADS1015_REG_HI_THRES = 3
|
||||
};
|
||||
|
||||
enum ads1015_config {
|
||||
ADS1015_CONF_OS = (1 << 15),
|
||||
ADS1015_CONF_MUX_OFFS = (12),
|
||||
ADS1015_CONF_MUX_MASK = (BOOST_BINARY( 111 ) << ADS1015_CONF_MUX_OFFS),
|
||||
ADS1015_CONF_PGA_OFFS = (9),
|
||||
ADS1015_CONF_PGA_MASK = (BOOST_BINARY( 111 ) << ADS1015_CONF_PGA_OFFS),
|
||||
ADS1015_CONF_MODE = (1 << 8), ///< 1 - Power-down single conversion mode
|
||||
ADS1015_CONF_DR_OFFS = (5),
|
||||
ADS1015_CONF_DR_MASK = (BOOST_BINARY( 111 ) << ADS1015_CONF_DR_OFFS),
|
||||
ADS1015_CONF_COMP_MODE= (1 << 4), ///< 1 - Window comparator
|
||||
ADS1015_CONF_COMP_POL = (1 << 3), ///< 1 - Active high
|
||||
ADS1015_CONF_COMP_LAT = (1 << 2), ///< 1 - Latching compartator
|
||||
ADS1015_COMP_QUE_OFFS = (0),
|
||||
ADS1015_CONF_QUE_MASK = (BOOST_BINARY( 11 ) << ADS1015_COMP_QUE_OFFS),
|
||||
};
|
||||
|
||||
enum {
|
||||
ADS1015_POLL_RDY_WATCHDOG = 1000
|
||||
};
|
||||
|
||||
uint16_t get_reg(ads1015_regs reg);
|
||||
void set_reg(ads1015_regs reg, uint16_t value);
|
||||
|
||||
uhd::i2c_iface::sptr _iface;
|
||||
ads1015_addr _addr;
|
||||
unsigned _config_reg;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
136
host/cmake/GetGitRevisionDescription.cmake
Normal file
136
host/cmake/GetGitRevisionDescription.cmake
Normal file
@@ -0,0 +1,136 @@
|
||||
# - Returns a version string from Git
|
||||
#
|
||||
# These functions force a re-configure on each git commit so that you can
|
||||
# trust the values of the variables in your build system.
|
||||
#
|
||||
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the refspec and sha hash of the current head revision
|
||||
#
|
||||
# git_describe(<var> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the results of git describe on the source tree, and adjusting
|
||||
# the output so that it tests false if an error occurs.
|
||||
#
|
||||
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the results of git describe --exact-match on the source tree,
|
||||
# and adjusting the output so that it tests false if there was no exact
|
||||
# matching tag.
|
||||
#
|
||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
# Iowa State University HCI Graduate Program/VRAC
|
||||
#
|
||||
# Copyright Iowa State University 2009-2010.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
if(__get_git_revision_description)
|
||||
return()
|
||||
endif()
|
||||
set(__get_git_revision_description YES)
|
||||
|
||||
# We must run the following at "include" time, not at function call time,
|
||||
# to find the path to this module rather than the path to a calling list file
|
||||
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
|
||||
|
||||
function(get_git_head_revision _refspecvar _hashvar)
|
||||
set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
|
||||
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
|
||||
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
|
||||
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
|
||||
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
|
||||
# We have reached the root directory, we are not in git
|
||||
set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
|
||||
set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
|
||||
endwhile()
|
||||
# check if this is a submodule
|
||||
if(NOT IS_DIRECTORY ${GIT_DIR})
|
||||
file(READ ${GIT_DIR} submodule)
|
||||
string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
|
||||
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
|
||||
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
|
||||
endif()
|
||||
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
|
||||
if(NOT EXISTS "${GIT_DATA}")
|
||||
file(MAKE_DIRECTORY "${GIT_DATA}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${GIT_DIR}/HEAD")
|
||||
return()
|
||||
endif()
|
||||
set(HEAD_FILE "${GIT_DATA}/HEAD")
|
||||
configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
|
||||
|
||||
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
|
||||
"${GIT_DATA}/grabRef.cmake"
|
||||
@ONLY)
|
||||
include("${GIT_DATA}/grabRef.cmake")
|
||||
|
||||
set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
|
||||
set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_describe _var)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
endif()
|
||||
get_git_head_revision(refspec hash)
|
||||
if(NOT GIT_FOUND)
|
||||
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
if(NOT hash)
|
||||
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# TODO sanitize
|
||||
#if((${ARGN}" MATCHES "&&") OR
|
||||
# (ARGN MATCHES "||") OR
|
||||
# (ARGN MATCHES "\\;"))
|
||||
# message("Please report the following error to the project!")
|
||||
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
|
||||
#endif()
|
||||
|
||||
#message(STATUS "Arguments to execute_process: ${ARGN}")
|
||||
|
||||
#support dirty option (hash cant be specified)
|
||||
list(FIND ARGN "--dirty" _index)
|
||||
if (${_index} GREATER -1)
|
||||
unset(hash)
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND
|
||||
"${GIT_EXECUTABLE}"
|
||||
describe
|
||||
${hash}
|
||||
${ARGN}
|
||||
WORKING_DIRECTORY
|
||||
"${CMAKE_SOURCE_DIR}"
|
||||
RESULT_VARIABLE
|
||||
res
|
||||
OUTPUT_VARIABLE
|
||||
out
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT res EQUAL 0)
|
||||
set(out "${out}-${res}-NOTFOUND")
|
||||
endif()
|
||||
|
||||
set(${_var} "${out}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_get_exact_tag _var)
|
||||
git_describe(out --exact-match ${ARGN})
|
||||
set(${_var} "${out}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
38
host/cmake/GetGitRevisionDescription.cmake.in
Normal file
38
host/cmake/GetGitRevisionDescription.cmake.in
Normal file
@@ -0,0 +1,38 @@
|
||||
#
|
||||
# Internal file for GetGitRevisionDescription.cmake
|
||||
#
|
||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
# Iowa State University HCI Graduate Program/VRAC
|
||||
#
|
||||
# Copyright Iowa State University 2009-2010.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
set(HEAD_HASH)
|
||||
|
||||
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
|
||||
|
||||
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
|
||||
if(HEAD_CONTENTS MATCHES "ref")
|
||||
# named branch
|
||||
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
|
||||
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
|
||||
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
|
||||
elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}")
|
||||
configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
|
||||
set(HEAD_HASH "${HEAD_REF}")
|
||||
endif()
|
||||
else()
|
||||
# detached HEAD
|
||||
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
|
||||
endif()
|
||||
|
||||
if(NOT HEAD_HASH)
|
||||
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
|
||||
string(STRIP "${HEAD_HASH}" HEAD_HASH)
|
||||
endif()
|
||||
21
host/cmake_uninstall.cmake.in
Normal file
21
host/cmake_uninstall.cmake.in
Normal file
@@ -0,0 +1,21 @@
|
||||
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
|
||||
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program(
|
||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif(NOT "${rm_retval}" STREQUAL 0)
|
||||
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
endforeach(file)
|
||||
@@ -105,7 +105,13 @@ static void apply_fe_corrections(
|
||||
|
||||
//make the calibration file path
|
||||
const fs::path cal_data_path = fs::path(uhd::get_app_path()) / ".uhd" / "cal" / (file_prefix + db_eeprom.serial + ".csv");
|
||||
if (not fs::exists(cal_data_path)) return;
|
||||
UHD_MSG(status) << "Looking for FE correction at: " << cal_data_path.c_str() << "... ";
|
||||
if (not fs::exists(cal_data_path)) {
|
||||
UHD_MSG(status) << "Not found" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
UHD_MSG(status) << "Found, loading... ";
|
||||
|
||||
//parse csv file or get from cache
|
||||
if (not fe_cal_cache.has_key(cal_data_path.string())){
|
||||
@@ -133,8 +139,9 @@ static void apply_fe_corrections(
|
||||
}
|
||||
std::sort(datas.begin(), datas.end(), fe_cal_comp);
|
||||
fe_cal_cache[cal_data_path.string()] = datas;
|
||||
UHD_MSG(status) << "Loaded " << cal_data_path.string() << std::endl;
|
||||
|
||||
UHD_MSG(status) << "Loaded" << std::endl;
|
||||
} else {
|
||||
UHD_MSG(status) << "Loaded from cache" << std::endl;
|
||||
}
|
||||
|
||||
sub_tree->access<std::complex<double> >(fe_path)
|
||||
|
||||
@@ -106,7 +106,7 @@ public:
|
||||
_task_barrier.resize(size);
|
||||
_task_handlers.resize(size);
|
||||
for (size_t i = 1/*skip 0*/; i < size; i++){
|
||||
_task_handlers[i] = task::make(boost::bind(&recv_packet_handler::converter_thread_task, this, i));
|
||||
//_task_handlers[i] = task::make(boost::bind(&recv_packet_handler::converter_thread_task, this, i));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -646,7 +646,7 @@ private:
|
||||
_convert_bytes_to_copy = bytes_to_copy;
|
||||
|
||||
//perform N channels of conversion
|
||||
converter_thread_task(0);
|
||||
for (size_t i = 0; i < this->size(); i++) this->converter_thread_task(i);
|
||||
|
||||
//update the copy buffer's availability
|
||||
info.data_bytes_to_copy -= bytes_to_copy;
|
||||
@@ -666,7 +666,7 @@ private:
|
||||
******************************************************************/
|
||||
UHD_INLINE void converter_thread_task(const size_t index)
|
||||
{
|
||||
_task_barrier.wait();
|
||||
//_task_barrier.wait();
|
||||
|
||||
//shortcut references to local data structures
|
||||
buffers_info_type &buff_info = get_curr_buffer_info();
|
||||
@@ -692,7 +692,7 @@ private:
|
||||
info.buff.reset(); //effectively a release
|
||||
}
|
||||
|
||||
if (index == 0) _task_barrier.wait_others();
|
||||
//if (index == 0) _task_barrier.wait_others();
|
||||
}
|
||||
|
||||
//! Shared variables for the worker threads
|
||||
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
_task_barrier.resize(size);
|
||||
_task_handlers.resize(size);
|
||||
for (size_t i = 1/*skip 0*/; i < size; i++){
|
||||
_task_handlers[i] = task::make(boost::bind(&send_packet_handler::converter_thread_task, this, i));
|
||||
//_task_handlers[i] = task::make(boost::bind(&send_packet_handler::converter_thread_task, this, i));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -377,7 +377,7 @@ private:
|
||||
_convert_if_packet_info = &if_packet_info;
|
||||
|
||||
//perform N channels of conversion
|
||||
converter_thread_task(0);
|
||||
for (size_t i = 0; i < this->size(); i++) this->converter_thread_task(i);
|
||||
|
||||
_next_packet_seq++; //increment sequence after commits
|
||||
return nsamps_per_buff;
|
||||
@@ -390,7 +390,7 @@ private:
|
||||
******************************************************************/
|
||||
UHD_INLINE void converter_thread_task(const size_t index)
|
||||
{
|
||||
_task_barrier.wait();
|
||||
//_task_barrier.wait();
|
||||
|
||||
//shortcut references to local data structures
|
||||
managed_send_buffer::sptr &buff = _props[index].buff;
|
||||
@@ -420,7 +420,7 @@ private:
|
||||
buff->commit(num_vita_words32*sizeof(boost::uint32_t));
|
||||
buff.reset(); //effectively a release
|
||||
|
||||
if (index == 0) _task_barrier.wait_others();
|
||||
//if (index == 0) _task_barrier.wait_others();
|
||||
}
|
||||
|
||||
//! Shared variables for the worker threads
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
//
|
||||
|
||||
#include "lms6002d.hpp"
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
#define usleep(x) boost::this_thread::sleep(boost::posix_time::microseconds(x))
|
||||
|
||||
static int verbosity = 0;
|
||||
|
||||
@@ -115,7 +118,7 @@ double lms6002d_dev::txrx_pll_tune(uint8_t reg, double ref_clock, double out_fre
|
||||
for (int i = 0; i < 64; i++) {
|
||||
// Update VCOCAP
|
||||
lms_write_bits(reg + 0x9, 0x3f, i);
|
||||
//usleep(50);
|
||||
usleep(50);
|
||||
|
||||
int comp = read_reg(reg + 0x0a);
|
||||
switch (comp >> 6) {
|
||||
@@ -164,16 +167,27 @@ void lms6002d_dev::init()
|
||||
write_reg(0x09, 0x00); // RXOUTSW (disabled), CLK_EN (all disabled)
|
||||
write_reg(0x17, 0xE0);
|
||||
write_reg(0x27, 0xE3);
|
||||
write_reg(0x64, 0x32);
|
||||
write_reg(0x70, 0x01);
|
||||
write_reg(0x79, 0x37);
|
||||
write_reg(0x59, 0x09);
|
||||
write_reg(0x47, 0x40);
|
||||
|
||||
// FAQ v1.0r12, 5.27:
|
||||
write_reg(0x47, 0x40); // Improving Tx spurious emission performance
|
||||
write_reg(0x59, 0x29); // Improving ADC’s performance
|
||||
write_reg(0x64, 0x36); // Common Mode Voltage For ADC’s
|
||||
write_reg(0x79, 0x37); // Higher LNA Gain
|
||||
|
||||
// Power down DC comparators to improve the receiver linearity
|
||||
// (see FAQ v1.0r12, 5.26)
|
||||
lms_set_bits(0x6E, (0x3 << 6));
|
||||
lms_set_bits(0x5F, (0x1 << 7));
|
||||
|
||||
// Disable AUX PA
|
||||
// PA_EN[0]:AUXPA = 0 (powered up) - for mask set v1
|
||||
// PD_DRVAUX = 0 (powered up) - for mask set v0, test mode only
|
||||
lms_set_bits(0x44, (3 << 1));
|
||||
|
||||
// Icp=0.2mA
|
||||
// This gives much better results for the GMSK modulation
|
||||
lms_write_bits(0x16, 0x1f, 0x02);
|
||||
}
|
||||
|
||||
void lms6002d_dev::set_txrx_polarity_and_interleaving(int rx_fsync_polarity,
|
||||
@@ -211,7 +225,7 @@ int lms6002d_dev::general_dc_calibration_loop(uint8_t dc_addr, uint8_t calibrati
|
||||
if (verbosity > 1) printf("cnt=%d\n", try_cnt_limit);
|
||||
|
||||
// Wait for 6.4(1.6) us
|
||||
//usleep(6.4);
|
||||
usleep(6.4);
|
||||
|
||||
// Read DC_CLBR_DONE
|
||||
reg_val = read_reg(calibration_reg_base+0x01);
|
||||
@@ -241,6 +255,10 @@ int lms6002d_dev::general_dc_calibration_loop(uint8_t dc_addr, uint8_t calibrati
|
||||
|
||||
int lms6002d_dev::general_dc_calibration(uint8_t dc_addr, uint8_t calibration_reg_base)
|
||||
{
|
||||
// Power up DC comparators
|
||||
lms_clear_bits(0x6E, (0x3 << 6));
|
||||
lms_clear_bits(0x5F, (0x1 << 7));
|
||||
|
||||
// Set DC_REGVAL to 31
|
||||
write_reg(calibration_reg_base+0x00, 31);
|
||||
// Run the calibration first time
|
||||
@@ -264,6 +282,11 @@ int lms6002d_dev::general_dc_calibration(uint8_t dc_addr, uint8_t calibration_re
|
||||
}
|
||||
}
|
||||
|
||||
// Power down DC comparators to improve the receiver linearity
|
||||
// (see FAQ v1.0r12, 5.26)
|
||||
lms_set_bits(0x6E, (0x3 << 6));
|
||||
lms_set_bits(0x5F, (0x1 << 7));
|
||||
|
||||
if (verbosity > 0) printf("Successful DC Offset Calibration for register bank 0x%X, DC addr %d. Result: 0x%X\n",
|
||||
calibration_reg_base, dc_addr, DC_REGVAL);
|
||||
return DC_REGVAL;
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
#define INCLUDED_LMS6002D_HPP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <cmath>
|
||||
|
||||
/*!
|
||||
* LMS6002D control class
|
||||
@@ -91,6 +92,14 @@ public:
|
||||
lms_clear_bits(0x09, (1 << 2));
|
||||
}
|
||||
|
||||
bool get_tx_pll_locked() {
|
||||
return get_txrx_pll_locked(0x10);
|
||||
}
|
||||
|
||||
bool get_rx_pll_locked() {
|
||||
return get_txrx_pll_locked(0x20);
|
||||
}
|
||||
|
||||
uint8_t get_tx_pa() {
|
||||
return lms_read_shift(0x44, (0x07 << 3), 3);
|
||||
}
|
||||
@@ -121,9 +130,9 @@ public:
|
||||
gain is in [-4 .. -35] dB range
|
||||
Returns the old gain value */
|
||||
int8_t set_tx_vga1gain(int8_t gain) {
|
||||
/* Safety check */
|
||||
if (not(-35 <= gain and gain <= -4))
|
||||
gain = -35;
|
||||
//clip
|
||||
if (gain < -35) gain = -35;
|
||||
if (gain > -4) gain = -4;
|
||||
int8_t old_bits = lms_write_bits(0x41, 0x1f, 35 + gain);
|
||||
return (old_bits & 0x1f) - 35;
|
||||
}
|
||||
@@ -134,30 +143,56 @@ public:
|
||||
return lms_read_shift(0x41, 0x1f, 0) - 35;
|
||||
}
|
||||
|
||||
/** Set Rx VGA1 gain.
|
||||
gain is raw values [0 .. 127]
|
||||
/** Set Rx VGA1 gain raw value
|
||||
gain is raw values [0 .. 120]
|
||||
Returns the old gain value */
|
||||
int8_t set_rx_vga1gain(int8_t gain){
|
||||
if (gain < 0) // according to standard max value of int8_t is always 127
|
||||
int8_t set_rx_vga1gain_int(int8_t gain){
|
||||
if (gain < 0 || gain >120)
|
||||
gain = 0;
|
||||
int8_t old_bits = lms_write_bits(0x76, 0x7f, gain);
|
||||
return old_bits & 0x7f;
|
||||
}
|
||||
|
||||
/** Get Rx VGA1 gain in dB.
|
||||
gain is in [0 .. 127] range of abstract values
|
||||
/** Get Rx VGA1 gain raw value
|
||||
gain is in [0 .. 120] range of abstract values
|
||||
Returns the gain value */
|
||||
int8_t get_rx_vga1gain(){
|
||||
int8_t get_rx_vga1gain_int(){
|
||||
return lms_read_shift(0x76, 0x7f, 0);
|
||||
}
|
||||
|
||||
/** Converts Rx VGA1 raw values to absolute dBs
|
||||
code must be in [0 .. 120] range */
|
||||
double rxvga1_int_to_db(int8_t code){
|
||||
return 5.0 + 20*log10(127.0/(127.0-code));
|
||||
}
|
||||
|
||||
/** Converts Rx VGA1 gain into raw integer values
|
||||
db must be in [5 .. 30.17] dB range */
|
||||
int8_t rxvga1_db_to_int(double db){
|
||||
return (int8_t)(127.5 - 127 / pow(10, (db-5.0)/20));
|
||||
}
|
||||
|
||||
/** Set Rx VGA1 gain in dB
|
||||
gain is in [5 .. 30.17] dB range
|
||||
Returns the old gain value */
|
||||
double set_rx_vga1gain(double gain){
|
||||
int8_t code = rxvga1_db_to_int(gain);
|
||||
return rxvga1_int_to_db(set_rx_vga1gain_int(code));
|
||||
}
|
||||
|
||||
/** Get Rx VGA1 gain in dB
|
||||
Returns the gain value in [5 .. 30.17] dB range */
|
||||
double get_rx_vga1gain(){
|
||||
return rxvga1_int_to_db(get_rx_vga1gain_int());
|
||||
}
|
||||
|
||||
/** Set VGA2 gain.
|
||||
gain is in dB [0 .. 25]
|
||||
Returns the old gain value */
|
||||
int8_t set_tx_vga2gain(int8_t gain) {
|
||||
/* Safety check */
|
||||
if (not(0 <= gain and gain <= 25))
|
||||
gain = 0;
|
||||
//clip
|
||||
if (gain < 0) gain = 0;
|
||||
if (gain > 25) gain = 25;
|
||||
int8_t old_bits = lms_write_bits(0x45, (0x1f << 3), (gain << 3));
|
||||
return old_bits >> 3;
|
||||
}
|
||||
@@ -175,9 +210,9 @@ public:
|
||||
gain is in dB [0 .. 60]
|
||||
Returns the old gain value */
|
||||
int8_t set_rx_vga2gain(int8_t gain) {
|
||||
/* Safety check */
|
||||
if (not (0 <= gain and gain <= 60))
|
||||
gain = 0;
|
||||
//clip
|
||||
if (gain < 0) gain = 0;
|
||||
if (gain > 60) gain = 60;
|
||||
int8_t old_bits = lms_write_bits(0x65, 0x1f, gain/3);
|
||||
return (old_bits & 0x1f) * 3;
|
||||
}
|
||||
@@ -472,6 +507,14 @@ public:
|
||||
protected:
|
||||
double txrx_pll_tune(uint8_t reg, double ref_clock, double out_freq);
|
||||
|
||||
bool get_txrx_pll_locked(uint8_t reg) {
|
||||
int comp = read_reg(reg + 0x0a) >> 6;
|
||||
if (comp == 0x00)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void lms_set_bits(uint8_t address, uint8_t mask) {
|
||||
write_reg(address, read_reg(address) | (mask));
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/math/special_functions/round.hpp>
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
#include <utility>
|
||||
#include <cmath>
|
||||
#include <cfloat>
|
||||
@@ -61,14 +62,42 @@ static const std::vector<std::string> lms_tx_antennas = list_of("TX0")("TX1")("T
|
||||
static const std::vector<std::string> lms_rx_antennas = list_of("RX0")("RX1")("RX2")("RX3")("CAL");
|
||||
|
||||
static const uhd::dict<std::string, gain_range_t> lms_tx_gain_ranges = map_list_of
|
||||
// ("VGA1", gain_range_t(-35, -4, double(1.0)))
|
||||
// ("VGA2", gain_range_t(0, 25, double(1.0)))
|
||||
//listing VGA2 first means that overall gain is first distributed to VGA2
|
||||
("VGA2", gain_range_t(0, 25, double(1.0)))
|
||||
("VGA1", gain_range_t(-35, -4, double(1.0)))
|
||||
// Use a single control to manually control how VGA1/VGA2 are set
|
||||
("VGA", gain_range_t(-35+0, -4+25, double(1.0)))
|
||||
// ("VGA", gain_range_t(-35+0, -4+25, double(1.0)))
|
||||
;
|
||||
|
||||
static const uhd::dict<std::string, gain_range_t> lms_rx_gain_ranges = map_list_of
|
||||
("VGA1", gain_range_t(0, 126, double(1.0)))
|
||||
// VGA1 follows the approximation of [dB] = 5 + 20*log10(127/(127-Code)) where 0 <= Code <= 120
|
||||
("VGA1", gain_range_t( list_of
|
||||
(range_t(5.00))(range_t(5.07))(range_t(5.14))(range_t(5.21))(range_t(5.28))
|
||||
(range_t(5.35))(range_t(5.42))(range_t(5.49))(range_t(5.57))(range_t(5.64))
|
||||
(range_t(5.71))(range_t(5.79))(range_t(5.86))(range_t(5.94))(range_t(6.01))
|
||||
(range_t(6.09))(range_t(6.17))(range_t(6.25))(range_t(6.33))(range_t(6.41))
|
||||
(range_t(6.49))(range_t(6.57))(range_t(6.65))(range_t(6.74))(range_t(6.82))
|
||||
(range_t(6.90))(range_t(6.99))(range_t(7.08))(range_t(7.16))(range_t(7.25))
|
||||
(range_t(7.34))(range_t(7.43))(range_t(7.52))(range_t(7.61))(range_t(7.71))
|
||||
(range_t(7.80))(range_t(7.90))(range_t(7.99))(range_t(8.09))(range_t(8.19))
|
||||
(range_t(8.29))(range_t(8.39))(range_t(8.49))(range_t(8.59))(range_t(8.69))
|
||||
(range_t(8.80))(range_t(8.91))(range_t(9.01))(range_t(9.12))(range_t(9.23))
|
||||
(range_t(9.35))(range_t(9.46))(range_t(9.57))(range_t(9.69))(range_t(9.81))
|
||||
(range_t(9.93))(range_t(10.05))(range_t(10.17))(range_t(10.30))(range_t(10.43))
|
||||
(range_t(10.55))(range_t(10.69))(range_t(10.82))(range_t(10.95))(range_t(11.09))
|
||||
(range_t(11.23))(range_t(11.37))(range_t(11.51))(range_t(11.66))(range_t(11.81))
|
||||
(range_t(11.96))(range_t(12.11))(range_t(12.27))(range_t(12.43))(range_t(12.59))
|
||||
(range_t(12.76))(range_t(12.92))(range_t(13.10))(range_t(13.27))(range_t(13.45))
|
||||
(range_t(13.63))(range_t(13.82))(range_t(14.01))(range_t(14.21))(range_t(14.41))
|
||||
(range_t(14.61))(range_t(14.82))(range_t(15.03))(range_t(15.25))(range_t(15.48))
|
||||
(range_t(15.71))(range_t(15.95))(range_t(16.19))(range_t(16.45))(range_t(16.71))
|
||||
(range_t(16.97))(range_t(17.25))(range_t(17.53))(range_t(17.83))(range_t(18.13))
|
||||
(range_t(18.45))(range_t(18.78))(range_t(19.12))(range_t(19.47))(range_t(19.84))
|
||||
(range_t(20.23))(range_t(20.63))(range_t(21.06))(range_t(21.50))(range_t(21.97))
|
||||
(range_t(22.47))(range_t(22.99))(range_t(23.55))(range_t(24.15))(range_t(24.80))
|
||||
(range_t(25.49))(range_t(26.25))(range_t(27.08))(range_t(27.99))(range_t(29.01))
|
||||
(range_t(30.17))
|
||||
))
|
||||
// We limit Rx VGA2 to 30dB, as docs say higher values are dangerous
|
||||
("VGA2", gain_range_t(0, 30, double(3.0)))
|
||||
// ToDo: Add LNA control here
|
||||
@@ -86,14 +115,14 @@ public:
|
||||
umtrx_lms6002d_dev(uhd::spi_iface::sptr spiface, const int slaveno) : _spiface(spiface), _slaveno(slaveno) {};
|
||||
|
||||
virtual void write_reg(uint8_t addr, uint8_t data) {
|
||||
if (verbosity>2) printf("lms6002d_ctrl_impl::write_reg(addr=0x%x, data=0x%x)\n", addr, data);
|
||||
if (verbosity>2) printf("umtrx_lms6002d_dev::write_reg(addr=0x%x, data=0x%x)\n", addr, data);
|
||||
uint16_t command = (((uint16_t)0x80 | (uint16_t)addr) << 8) | (uint16_t)data;
|
||||
_spiface->write_spi(_slaveno, spi_config_t::EDGE_RISE, command, 16);
|
||||
}
|
||||
virtual uint8_t read_reg(uint8_t addr) {
|
||||
if(addr > 127) return 0; // incorrect address, 7 bit long expected
|
||||
uint8_t data = _spiface->read_spi(_slaveno, spi_config_t::EDGE_RISE, addr << 8, 16);
|
||||
if (verbosity>2) printf("lms6002d_ctrl_impl::read_reg(addr=0x%x) data=0x%x\n", addr, data);
|
||||
if (verbosity>2) printf("umtrx_lms6002d_dev::read_reg(addr=0x%x) data=0x%x\n", addr, data);
|
||||
return data;
|
||||
}
|
||||
};
|
||||
@@ -124,6 +153,18 @@ public:
|
||||
return this->set_enabled(dboard_iface::UNIT_TX, enb);
|
||||
}
|
||||
|
||||
uhd::sensor_value_t get_rx_pll_locked()
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock l(_mutex);
|
||||
return uhd::sensor_value_t("LO", lms.get_rx_pll_locked(), "locked", "unlocked");
|
||||
}
|
||||
|
||||
uhd::sensor_value_t get_tx_pll_locked()
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock l(_mutex);
|
||||
return uhd::sensor_value_t("LO", lms.get_tx_pll_locked(), "locked", "unlocked");
|
||||
}
|
||||
|
||||
uhd::freq_range_t get_rx_bw_range(void)
|
||||
{
|
||||
return lms_bandwidth_range;
|
||||
@@ -176,15 +217,20 @@ public:
|
||||
|
||||
uint8_t get_tx_vga1dc_i_int(void)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock l(_mutex);
|
||||
return lms.get_tx_vga1dc_i_int();
|
||||
}
|
||||
|
||||
uint8_t get_tx_vga1dc_q_int(void)
|
||||
{
|
||||
return lms.get_tx_vga1dc_i_int();
|
||||
boost::recursive_mutex::scoped_lock l(_mutex);
|
||||
return lms.get_tx_vga1dc_q_int();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
double set_freq(dboard_iface::unit_t unit, double f) {
|
||||
boost::recursive_mutex::scoped_lock l(_mutex);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_freq(%f)\n", f);
|
||||
unsigned ref_freq = _clock_rate;
|
||||
double actual_freq = 0;
|
||||
@@ -214,6 +260,7 @@ public:
|
||||
}
|
||||
|
||||
bool set_enabled(dboard_iface::unit_t unit, bool en) {
|
||||
boost::recursive_mutex::scoped_lock l(_mutex);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_enabled(%d)\n", en);
|
||||
if (unit==dboard_iface::UNIT_RX) {
|
||||
if (en)
|
||||
@@ -231,17 +278,21 @@ public:
|
||||
}
|
||||
|
||||
double set_rx_gain(double gain, const std::string &name) {
|
||||
boost::recursive_mutex::scoped_lock l(_mutex);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_rx_gain(%f, %s)\n", gain, name.c_str());
|
||||
assert_has(lms_rx_gain_ranges.keys(), name, "LMS6002D rx gain name");
|
||||
if(name == "VGA1"){
|
||||
if(name == "VGA1"){
|
||||
lms.set_rx_vga1gain(gain);
|
||||
} else if(name == "VGA2"){
|
||||
return lms.get_rx_vga1gain();
|
||||
} else if(name == "VGA2"){
|
||||
lms.set_rx_vga2gain(gain);
|
||||
return lms.get_rx_vga2gain();
|
||||
} else UHD_THROW_INVALID_CODE_PATH();
|
||||
return gain;
|
||||
}
|
||||
|
||||
void set_rx_ant(const std::string &ant) {
|
||||
boost::recursive_mutex::scoped_lock l(_mutex);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_rx_ant(%s)\n", ant.c_str());
|
||||
//validate input
|
||||
assert_has(lms_rx_antennas, ant, "LMS6002D rx antenna name");
|
||||
@@ -275,6 +326,7 @@ public:
|
||||
}
|
||||
|
||||
double set_rx_bandwidth(double bandwidth) {
|
||||
boost::recursive_mutex::scoped_lock l(_mutex);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_rx_bandwidth(%f)\n", bandwidth);
|
||||
// Get the closest available bandwidth
|
||||
bandwidth = lms_bandwidth_range.clip(bandwidth);
|
||||
@@ -286,27 +338,19 @@ public:
|
||||
}
|
||||
|
||||
double set_tx_gain(double gain, const std::string &name) {
|
||||
boost::recursive_mutex::scoped_lock l(_mutex);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_tx_gain(%f, %s)\n", gain, name.c_str());
|
||||
//validate input
|
||||
assert_has(lms_tx_gain_ranges.keys(), name, "LMS6002D tx gain name");
|
||||
|
||||
if (name == "VGA") {
|
||||
// Calculate the best combination of VGA1 and VGA2 gains.
|
||||
// For simplicity we just try to use VGA2 as much as possible
|
||||
// and only then engage VGA1.
|
||||
int desired_vga2 = int(gain) - tx_vga1gain;
|
||||
if (desired_vga2 < 0)
|
||||
tx_vga2gain = 0;
|
||||
else if (desired_vga2 > 25)
|
||||
tx_vga2gain = 25;
|
||||
else
|
||||
tx_vga2gain = desired_vga2;
|
||||
tx_vga1gain = int(gain) - tx_vga2gain;
|
||||
|
||||
// Set the gains in hardware
|
||||
if (verbosity>1) printf("lms6002d_ctrl_impl::set_tx_gain() VGA1=%d VGA2=%d\n", tx_vga1gain, tx_vga2gain);
|
||||
lms.set_tx_vga1gain(tx_vga1gain);
|
||||
lms.set_tx_vga2gain(tx_vga2gain);
|
||||
if (name == "VGA1") {
|
||||
if (verbosity>1) printf("db_lms6002d::set_tx_gain() VGA1=%d\n", int(gain));
|
||||
lms.set_tx_vga1gain(int(gain));
|
||||
return lms.get_tx_vga1gain();
|
||||
} else if (name == "VGA2") {
|
||||
if (verbosity>1) printf("db_lms6002d::set_tx_gain() VGA2=%d\n", int(gain));
|
||||
lms.set_tx_vga2gain(int(gain));
|
||||
return lms.get_tx_vga2gain();
|
||||
} else {
|
||||
UHD_THROW_INVALID_CODE_PATH();
|
||||
}
|
||||
@@ -316,6 +360,7 @@ public:
|
||||
}
|
||||
|
||||
void set_tx_ant(const std::string &ant) {
|
||||
boost::recursive_mutex::scoped_lock l(_mutex);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_tx_ant(%s)\n", ant.c_str());
|
||||
//validate input
|
||||
assert_has(lms_tx_antennas, ant, "LMS6002D tx antenna ant");
|
||||
@@ -335,6 +380,7 @@ public:
|
||||
}
|
||||
|
||||
double set_tx_bandwidth(double bandwidth) {
|
||||
boost::recursive_mutex::scoped_lock l(_mutex);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_tx_bandwidth(%f)\n", bandwidth);
|
||||
// Get the closest available bandwidth
|
||||
bandwidth = lms_bandwidth_range.clip(bandwidth);
|
||||
@@ -346,12 +392,14 @@ public:
|
||||
}
|
||||
|
||||
uint8_t _set_tx_vga1dc_i_int(uint8_t offset) {
|
||||
boost::recursive_mutex::scoped_lock l(_mutex);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_tx_vga1dc_i_int(%d)\n", offset);
|
||||
lms.set_tx_vga1dc_i_int(offset);
|
||||
return offset;
|
||||
}
|
||||
|
||||
uint8_t _set_tx_vga1dc_q_int(uint8_t offset) {
|
||||
boost::recursive_mutex::scoped_lock l(_mutex);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_tx_vga1dc_q_int(%d)\n", offset);
|
||||
lms.set_tx_vga1dc_q_int(offset);
|
||||
return offset;
|
||||
@@ -369,6 +417,8 @@ private:
|
||||
const int _lms_spi_number;
|
||||
const int _adf4350_spi_number;
|
||||
const double _clock_rate;
|
||||
|
||||
boost::recursive_mutex _mutex;
|
||||
};
|
||||
|
||||
lms6002d_ctrl::sptr lms6002d_ctrl::make(uhd::spi_iface::sptr spiface, const int lms_spi_number, const int adf4350_spi_number, const double clock_rate)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <uhd/types/ranges.hpp>
|
||||
#include <uhd/types/serial.hpp>
|
||||
#include <uhd/types/sensors.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@@ -22,6 +23,9 @@ public:
|
||||
virtual bool set_rx_enabled(const bool enb) = 0;
|
||||
virtual bool set_tx_enabled(const bool enb) = 0;
|
||||
|
||||
virtual uhd::sensor_value_t get_rx_pll_locked() = 0;
|
||||
virtual uhd::sensor_value_t get_tx_pll_locked() = 0;
|
||||
|
||||
virtual double set_rx_gain(const double gain, const std::string &name) = 0;
|
||||
virtual double set_tx_gain(const double gain, const std::string &name) = 0;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include <uhd/utils/platform.hpp>
|
||||
#include "platform.hpp"
|
||||
#include <uhd/config.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#ifdef UHD_PLATFORM_WIN32
|
||||
|
||||
36
host/missing/platform.hpp
Normal file
36
host/missing/platform.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// Copyright 2010,2012 Ettus Research LLC
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#ifndef INCLUDED_UHD_UTILS_PLATFORM_HPP_COPY
|
||||
#define INCLUDED_UHD_UTILS_PLATFORM_HPP_COPY
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
namespace uhd {
|
||||
|
||||
/* Returns the process ID of the current process */
|
||||
boost::int32_t get_process_id();
|
||||
|
||||
/* Returns a unique identifier for the current machine */
|
||||
boost::uint32_t get_host_id();
|
||||
|
||||
/* Get a unique identifier for the current machine and process */
|
||||
boost::uint32_t get_process_hash();
|
||||
|
||||
} //namespace uhd
|
||||
|
||||
#endif /* INCLUDED_UHD_UTILS_PLATFORM_HPP_COPY */
|
||||
280
host/power_amp.cpp
Normal file
280
host/power_amp.cpp
Normal file
@@ -0,0 +1,280 @@
|
||||
#include "power_amp.hpp"
|
||||
#include <uhd/utils/msg.hpp>
|
||||
#include <uhd/exception.hpp>
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <cmath>
|
||||
|
||||
using namespace uhd;
|
||||
|
||||
/***********************************************************************
|
||||
* Declarations
|
||||
**********************************************************************/
|
||||
|
||||
class power_amp_impl : public power_amp {
|
||||
public:
|
||||
|
||||
// Voltage to Watts curves
|
||||
typedef std::map<double,double> pa_curve_t;
|
||||
|
||||
power_amp_impl(pa_type_t pa_type, const pa_curve_t &v2w, const pa_curve_t &w2v);
|
||||
virtual ~power_amp_impl();
|
||||
|
||||
// Get the PA type
|
||||
virtual pa_type_t get_pa_type() const {return _pa_type;}
|
||||
|
||||
// Get the PA type as a string
|
||||
virtual std::string get_pa_type_str() const {return pa_type_to_str(_pa_type);}
|
||||
|
||||
// Minimum and maximum supported output power in watts
|
||||
virtual double min_power_w() const;
|
||||
virtual double max_power_w() const;
|
||||
// Minimum and maximum supported output power in dBm
|
||||
virtual double min_power_dBm() const;
|
||||
virtual double max_power_dBm() const;
|
||||
|
||||
// Get output power in watts for a given voltage
|
||||
virtual double v2w(double v) const;
|
||||
// Get input voltage required to generate given output power (in watts)
|
||||
virtual double w2v(double w) const;
|
||||
// Get output power in dBm for a given voltage
|
||||
virtual double v2dBm(double v) const;
|
||||
// Get input voltage required to generate given output power (in dBm)
|
||||
virtual double dBm2v(double dBm) const;
|
||||
|
||||
protected:
|
||||
|
||||
// The PA type
|
||||
pa_type_t _pa_type;
|
||||
|
||||
// Curves
|
||||
const pa_curve_t &_v2w_curve;
|
||||
const pa_curve_t _w2v_curve;
|
||||
};
|
||||
|
||||
// Interpolate curve values
|
||||
static double pa_interpolate_curve(const power_amp_impl::pa_curve_t &curve, double v);
|
||||
// Convert an A->B map into a B->A map
|
||||
template<typename map_t> static map_t map_reverse(map_t curve);
|
||||
|
||||
/***********************************************************************
|
||||
* Constants
|
||||
**********************************************************************/
|
||||
|
||||
// NOTE: All names MUST be uppercase for pa_str_to_type() to work correctly
|
||||
const power_amp::pa_type_map_pair_t power_amp::_pa_type_map[] = {
|
||||
{power_amp::PA_NONE, "NONE"}, // Also serves as the default
|
||||
{power_amp::PA_EPA881F40A, "EPA881F40A"},
|
||||
{power_amp::PA_EPA942H40A, "EPA942H40A"},
|
||||
{power_amp::PA_EPA1800F37A, "EPA1800F37A"}
|
||||
};
|
||||
|
||||
const power_amp_impl::pa_curve_t EPA942H40A_v2w_curve = boost::assign::map_list_of
|
||||
(9.5, 1.15)
|
||||
(10, 1.31)
|
||||
(11, 1.6)
|
||||
(12, 1.9)
|
||||
(12.5, 2.1)
|
||||
(13, 2.25)
|
||||
(13.5, 2.44)
|
||||
(14, 2.6)
|
||||
(14.5, 2.8)
|
||||
(15, 3.0)
|
||||
(15.5, 3.2)
|
||||
(16, 3.45)
|
||||
(16.5, 3.7)
|
||||
(17, 3.9)
|
||||
(17.5, 4.1)
|
||||
(18, 4.35)
|
||||
(18.5, 4.6)
|
||||
(19, 4.8)
|
||||
(19.5, 5.1)
|
||||
(20, 5.4)
|
||||
(20.5, 5.65)
|
||||
(21.1, 6.0)
|
||||
(21.6, 6.2)
|
||||
(22.1, 6.5)
|
||||
(22.6, 6.8)
|
||||
(23.1, 7.1)
|
||||
(23.4, 7.25)
|
||||
(23.7, 7.4)
|
||||
(24, 7.55)
|
||||
(24.2, 7.7)
|
||||
(24.5, 7.9)
|
||||
(24.8, 8.0)
|
||||
(25.2, 8.25)
|
||||
(25.5, 8.45)
|
||||
(25.9, 8.65)
|
||||
(26.2, 8.9)
|
||||
(26.6, 9.1)
|
||||
(28, 10.0);
|
||||
|
||||
/***********************************************************************
|
||||
* Static functions
|
||||
**********************************************************************/
|
||||
|
||||
template<typename map_t>
|
||||
static map_t map_reverse(map_t curve)
|
||||
{
|
||||
map_t reversed;
|
||||
|
||||
for (typename map_t::iterator i = curve.begin(); i != curve.end(); ++i)
|
||||
reversed[i->second] = i->first;
|
||||
|
||||
return reversed;
|
||||
}
|
||||
|
||||
static double pa_interpolate_curve(const power_amp_impl::pa_curve_t &curve, double v)
|
||||
{
|
||||
power_amp_impl::pa_curve_t::const_iterator i = curve.upper_bound(v);
|
||||
if (i == curve.end())
|
||||
{
|
||||
return (--i)->second;
|
||||
}
|
||||
if (i == curve.begin())
|
||||
{
|
||||
return i->second;
|
||||
}
|
||||
power_amp_impl::pa_curve_t::const_iterator l=i;
|
||||
--l;
|
||||
|
||||
const double delta=(v - l->first) / (i->first - l->first);
|
||||
return delta*i->second + (1-delta)*l->second;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Make
|
||||
**********************************************************************/
|
||||
power_amp::sptr power_amp::make(pa_type_t pa_type) {
|
||||
switch (pa_type) {
|
||||
case PA_NONE:
|
||||
return power_amp::sptr();
|
||||
case PA_EPA881F40A:
|
||||
case PA_EPA942H40A:
|
||||
case PA_EPA1800F37A:
|
||||
default:
|
||||
return power_amp::sptr(new power_amp_impl(pa_type, EPA942H40A_v2w_curve,
|
||||
map_reverse(EPA942H40A_v2w_curve)));
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* power_amp methods
|
||||
**********************************************************************/
|
||||
|
||||
power_amp::~power_amp()
|
||||
{
|
||||
}
|
||||
|
||||
std::string power_amp::pa_type_to_str(pa_type_t pa)
|
||||
{
|
||||
BOOST_FOREACH(const power_amp::pa_type_map_pair_t &pa_map_pair, _pa_type_map)
|
||||
{
|
||||
if (pa_map_pair.type == pa)
|
||||
return pa_map_pair.name;
|
||||
}
|
||||
throw uhd::environment_error("Can't map PA type to a string.");
|
||||
return "NONE";
|
||||
}
|
||||
|
||||
power_amp::pa_type_t power_amp::pa_str_to_type(const std::string &pa_str)
|
||||
{
|
||||
std::string pa_str_upper = boost::to_upper_copy(pa_str);
|
||||
BOOST_FOREACH(const power_amp::pa_type_map_pair_t &pa_map_pair, _pa_type_map)
|
||||
{
|
||||
if (pa_map_pair.name == pa_str_upper)
|
||||
return pa_map_pair.type;
|
||||
}
|
||||
UHD_MSG(error) << "PA name " << pa_str << " is not recognized. "
|
||||
<< "Setting PA type to NONE." << std::endl;
|
||||
return power_amp::PA_NONE;
|
||||
}
|
||||
|
||||
std::list<power_amp::pa_type_t> power_amp::list_pa_type()
|
||||
{
|
||||
std::list<power_amp::pa_type_t> list;
|
||||
|
||||
BOOST_FOREACH(const power_amp::pa_type_map_pair_t &pa_map_pair, _pa_type_map) {
|
||||
list.push_back(pa_map_pair.type);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
std::list<std::string> power_amp::list_pa_str()
|
||||
{
|
||||
std::list<std::string> list;
|
||||
|
||||
BOOST_FOREACH(const power_amp::pa_type_map_pair_t &pa_map_pair, _pa_type_map) {
|
||||
list.push_back(pa_map_pair.name);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
double power_amp::w2dBm(double w)
|
||||
{
|
||||
return 10*log10(w) + 30;
|
||||
}
|
||||
|
||||
double power_amp::dBm2w(double dBm)
|
||||
{
|
||||
return pow(10, (dBm-30)/10);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* power_amp_impl methods
|
||||
**********************************************************************/
|
||||
|
||||
power_amp_impl::power_amp_impl(pa_type_t pa_type, const pa_curve_t &v2w, const pa_curve_t &w2v)
|
||||
: _pa_type(pa_type)
|
||||
, _v2w_curve(v2w)
|
||||
, _w2v_curve(w2v)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
power_amp_impl::~power_amp_impl()
|
||||
{
|
||||
}
|
||||
|
||||
double power_amp_impl::min_power_w() const
|
||||
{
|
||||
return _w2v_curve.begin()->first;
|
||||
}
|
||||
|
||||
double power_amp_impl::max_power_w() const
|
||||
{
|
||||
return _w2v_curve.rbegin()->first;
|
||||
}
|
||||
|
||||
double power_amp_impl::min_power_dBm() const
|
||||
{
|
||||
return w2dBm(min_power_w());
|
||||
}
|
||||
|
||||
double power_amp_impl::max_power_dBm() const
|
||||
{
|
||||
return w2dBm(max_power_w());
|
||||
}
|
||||
|
||||
double power_amp_impl::v2w(double v) const
|
||||
{
|
||||
return pa_interpolate_curve(_v2w_curve, v);
|
||||
}
|
||||
|
||||
double power_amp_impl::w2v(double w) const
|
||||
{
|
||||
return pa_interpolate_curve(_w2v_curve, w);
|
||||
}
|
||||
|
||||
double power_amp_impl::v2dBm(double v) const
|
||||
{
|
||||
return w2dBm(v2w(v));
|
||||
}
|
||||
|
||||
double power_amp_impl::dBm2v(double dBm) const
|
||||
{
|
||||
return w2v(dBm2w(dBm));
|
||||
}
|
||||
75
host/power_amp.hpp
Normal file
75
host/power_amp.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#ifndef POWER_AMP_HPP
|
||||
#define POWER_AMP_HPP
|
||||
|
||||
#include <uhd/config.hpp>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace uhd {
|
||||
|
||||
class power_amp {
|
||||
public:
|
||||
|
||||
// Supported Power Amplifiers
|
||||
enum pa_type_t {
|
||||
PA_NONE, // No PA connected
|
||||
PA_EPA881F40A, // EPA881F40A GSM850
|
||||
PA_EPA942H40A, // EPA942H40A EGSM900
|
||||
PA_EPA1800F37A // EPA1800F37A DCS1800
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<power_amp> sptr;
|
||||
static power_amp::sptr make(pa_type_t pa_type);
|
||||
virtual ~power_amp();
|
||||
|
||||
// Get the PA type
|
||||
virtual pa_type_t get_pa_type() const =0;
|
||||
// Get the PA type as a string
|
||||
virtual std::string get_pa_type_str() const =0;
|
||||
|
||||
// Convert PA type to a string
|
||||
static std::string pa_type_to_str(pa_type_t pa);
|
||||
// Convert a string to a PA type
|
||||
static pa_type_t pa_str_to_type(const std::string &pa_str);
|
||||
|
||||
// Return a list of PA types
|
||||
static std::list<pa_type_t> list_pa_type();
|
||||
// Return a list of PA type strings
|
||||
static std::list<std::string> list_pa_str();
|
||||
|
||||
// Convert watts -> dBm
|
||||
static double w2dBm(double w);
|
||||
// Convert dBm -> watts
|
||||
static double dBm2w(double dBm);
|
||||
|
||||
// Minimum and maximum supported output power in watts
|
||||
virtual double min_power_w() const =0;
|
||||
virtual double max_power_w() const =0;
|
||||
// Minimum and maximum supported output power in dBm
|
||||
virtual double min_power_dBm() const =0;
|
||||
virtual double max_power_dBm() const =0;
|
||||
|
||||
// Get output power in watts for a given voltage
|
||||
virtual double v2w(double v) const =0;
|
||||
// Get input voltage required to generate given output power (in watts)
|
||||
virtual double w2v(double w) const =0;
|
||||
// Get output power in dBm for a given voltage
|
||||
virtual double v2dBm(double v) const =0;
|
||||
// Get input voltage required to generate given output power (in dBm)
|
||||
virtual double dBm2v(double dBm) const =0;
|
||||
|
||||
protected:
|
||||
|
||||
// Map PA types to string names
|
||||
struct pa_type_map_pair_t {
|
||||
pa_type_t type;
|
||||
std::string name;
|
||||
};
|
||||
static const pa_type_map_pair_t _pa_type_map[];
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // POWER_AMP_HPP
|
||||
124
host/tmp102_ctrl.cpp
Normal file
124
host/tmp102_ctrl.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
//
|
||||
// Copyright 2014 Fairwaves LLC
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "tmp102_ctrl.hpp"
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1700)
|
||||
#define nan(arg) std::strtod("NAN()", (char**)NULL)
|
||||
#endif
|
||||
|
||||
using namespace uhd;
|
||||
|
||||
tmp102_ctrl::tmp102_ctrl()
|
||||
: _addr(TMP102_NONE)
|
||||
, _config(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool tmp102_ctrl::check(const uhd::i2c_iface::sptr& iface, tmp102_addr addr)
|
||||
{
|
||||
byte_vector_t cmd = boost::assign::list_of(REG_CONF);
|
||||
iface->write_i2c(addr, cmd);
|
||||
|
||||
byte_vector_t vec = iface->read_i2c(addr, 2);
|
||||
uint16_t res = (((uint16_t)vec.at(0)) << 8) | vec.at(1);
|
||||
// Resolution bits are always set
|
||||
if (((res & CONF_R_MASK) != CONF_R_MASK) || ((res & 0xF) != 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void tmp102_ctrl::init(i2c_iface::sptr iface, tmp102_addr addr)
|
||||
{
|
||||
_iface = iface;
|
||||
_addr = addr;
|
||||
_config = get_reg(REG_CONF);
|
||||
}
|
||||
|
||||
double tmp102_ctrl::get_temp()
|
||||
{
|
||||
if (!_iface)
|
||||
return nan("");
|
||||
|
||||
if (_config & CONF_SD) {
|
||||
// Start conversion in shutdown mode
|
||||
set_reg(REG_CONF, _config | CONF_OS);
|
||||
|
||||
// Wait for conversion ready
|
||||
unsigned i;
|
||||
for (i = 0; i < TMP102_POLL_RDY_WATCHDOG; i++) {
|
||||
if (get_reg(REG_CONF) & CONF_OS)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == TMP102_POLL_RDY_WATCHDOG)
|
||||
return nan("");
|
||||
}
|
||||
int16_t tmp = (int16_t)get_reg(REG_TEMP);
|
||||
if (tmp & 0x001) {
|
||||
tmp >>= 3;
|
||||
} else {
|
||||
tmp >>= 4;
|
||||
}
|
||||
return 0.0625 * (double)tmp;
|
||||
}
|
||||
|
||||
void tmp102_ctrl::set_update_rate(conversion_rate rate)
|
||||
{
|
||||
_config &= ~CONF_CR_MASK;
|
||||
_config |= (rate << CONF_CR_OFFS) & CONF_CR_MASK;
|
||||
set_reg(REG_CONF, _config);
|
||||
}
|
||||
|
||||
void tmp102_ctrl::set_ex_mode(bool ex_mode)
|
||||
{
|
||||
if (ex_mode)
|
||||
_config |= CONF_EM;
|
||||
else
|
||||
_config &= ~CONF_EM;
|
||||
set_reg(REG_CONF, _config);
|
||||
}
|
||||
|
||||
void tmp102_ctrl::set_shutdown_mode(bool shutdown_mode)
|
||||
{
|
||||
if (shutdown_mode)
|
||||
_config |= CONF_SD;
|
||||
else
|
||||
_config &= ~CONF_SD;
|
||||
set_reg(REG_CONF, _config);
|
||||
}
|
||||
|
||||
uint16_t tmp102_ctrl::get_reg(tmp102_regs reg)
|
||||
{
|
||||
byte_vector_t cmd = boost::assign::list_of(reg);
|
||||
_iface->write_i2c(_addr, cmd);
|
||||
|
||||
byte_vector_t vec = _iface->read_i2c(_addr, 2);
|
||||
uint16_t res = ((uint16_t)vec.at(0) << 8) | vec.at(1);
|
||||
return res;
|
||||
}
|
||||
|
||||
void tmp102_ctrl::set_reg(tmp102_regs reg, uint16_t value)
|
||||
{
|
||||
byte_vector_t cmd = boost::assign::list_of((uint8_t)reg)((uint8_t)(value >> 8))((uint8_t)(value & 0xFF));
|
||||
_iface->write_i2c(_addr, cmd);
|
||||
}
|
||||
97
host/tmp102_ctrl.hpp
Normal file
97
host/tmp102_ctrl.hpp
Normal file
@@ -0,0 +1,97 @@
|
||||
//
|
||||
// Copyright 2014 Fairwaves LLC
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#ifndef INCLUDED_TMP102_CTRL_HPP
|
||||
#define INCLUDED_TMP102_CTRL_HPP
|
||||
|
||||
#include <uhd/config.hpp>
|
||||
#include <uhd/types/serial.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
/**
|
||||
* @brief The tmp102_ctrl class
|
||||
*
|
||||
* Control of TI's TMP102 temperature sensors
|
||||
*/
|
||||
class tmp102_ctrl {
|
||||
public:
|
||||
enum conversion_rate {
|
||||
TMP102_CR_025HZ = 0,
|
||||
TMP102_CR_1HZ = 1,
|
||||
TMP102_CR_4HZ = 2, // Default
|
||||
TMP102_CR_8HZ = 3
|
||||
};
|
||||
|
||||
enum tmp102_addr {
|
||||
TMP102_NONE = 0,
|
||||
TMP102_GROUND = BOOST_BINARY( 1001000 ),
|
||||
TMP102_VDD = BOOST_BINARY( 1001001 ),
|
||||
TMP102_SDA = BOOST_BINARY( 1001010 ),
|
||||
TMP102_SCL = BOOST_BINARY( 1001011 )
|
||||
};
|
||||
|
||||
tmp102_ctrl();
|
||||
|
||||
/** @brief check presence of device at @ref addr */
|
||||
static bool check(const uhd::i2c_iface::sptr& iface, tmp102_addr addr);
|
||||
|
||||
void init(uhd::i2c_iface::sptr iface, tmp102_addr addr);
|
||||
|
||||
void set_update_rate(conversion_rate rate);
|
||||
void set_ex_mode(bool ex_mode);
|
||||
void set_shutdown_mode(bool shutdown_mode);
|
||||
|
||||
double get_temp();
|
||||
|
||||
private:
|
||||
enum tmp102_regs {
|
||||
REG_TEMP = 0,
|
||||
REG_CONF = 1,
|
||||
REG_TLOW = 2,
|
||||
REG_THIGH = 3
|
||||
};
|
||||
|
||||
enum config_reg {
|
||||
CONF_OS = (1 << 15),
|
||||
CONF_R_OFFS = (13), // Read only for TMP102
|
||||
CONF_R_MASK = (BOOST_BINARY( 11 ) << CONF_R_OFFS),
|
||||
CONF_F_OFFS = (11), // Fault queue
|
||||
CONF_F_MASK = (BOOST_BINARY( 11 ) << CONF_F_OFFS),
|
||||
CONF_POL = (1 << 10),
|
||||
CONF_TM = (1 << 9), // Thermostat mode
|
||||
CONF_SD = (1 << 8),
|
||||
CONF_CR_OFFS = (6), // see conversion_rate
|
||||
CONF_CR_MASK = (BOOST_BINARY( 11 ) << CONF_CR_OFFS),
|
||||
CONF_AL = (1 << 5),
|
||||
CONF_EM = (1 << 4) // Extended temp mode up to +150C
|
||||
};
|
||||
|
||||
enum {
|
||||
TMP102_POLL_RDY_WATCHDOG = 1000
|
||||
};
|
||||
|
||||
uint16_t get_reg(tmp102_regs reg);
|
||||
void set_reg(tmp102_regs reg, uint16_t value);
|
||||
|
||||
uhd::i2c_iface::sptr _iface;
|
||||
tmp102_addr _addr;
|
||||
uint16_t _config;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -55,9 +55,13 @@ static const uhd::dict<std::string, boost::uint8_t> UMTRX_OFFSETS = boost::assig
|
||||
("tcxo-dac", 0xFF-3) // 2 bytes
|
||||
("tx2-vga1-dc-i", 0xFF-4) // 1 byte
|
||||
("tx2-vga1-dc-q", 0xFF-5) // 1 byte
|
||||
("pa_dcdc_r", 0xFF-6) // 1 byte
|
||||
("pa_low", 0xFF-7) // 1 byte
|
||||
("pa_en1", 0xFF-8) // 1 byte
|
||||
("pa_en2", 0xFF-9) // 1 byte
|
||||
;
|
||||
|
||||
#if 0x18 + SERIAL_LEN + NAME_MAX_LEN >= 0xFF-5
|
||||
#if 0x18 + SERIAL_LEN + NAME_MAX_LEN >= 0xFF-7
|
||||
# error EEPROM address overlap! Get a bigger EEPROM.
|
||||
#endif
|
||||
|
||||
@@ -87,6 +91,23 @@ void load_umtrx_eeprom(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
|
||||
mb_eeprom["tcxo-dac"] = uint16_bytes_to_string(
|
||||
iface.read_eeprom(N100_EEPROM_ADDR, UMTRX_OFFSETS["tcxo-dac"], 2)
|
||||
);
|
||||
|
||||
mb_eeprom["pa_dcdc_r"] =
|
||||
boost::lexical_cast<std::string>(unsigned(iface.read_eeprom(N100_EEPROM_ADDR, UMTRX_OFFSETS["pa_dcdc_r"], 1).at(0)));
|
||||
|
||||
{
|
||||
uint8_t val = int(iface.read_eeprom(N100_EEPROM_ADDR, UMTRX_OFFSETS["pa_low"], 1).at(0));
|
||||
mb_eeprom["pa_low"] = (val==255)?"":boost::lexical_cast<std::string>(int(val));
|
||||
}
|
||||
|
||||
{
|
||||
uint8_t val = int(iface.read_eeprom(N100_EEPROM_ADDR, UMTRX_OFFSETS["pa_en1"], 1).at(0));
|
||||
mb_eeprom["pa_en1"] = (val != 0) ?"1":"0";
|
||||
}
|
||||
{
|
||||
uint8_t val = int(iface.read_eeprom(N100_EEPROM_ADDR, UMTRX_OFFSETS["pa_en2"], 1).at(0));
|
||||
mb_eeprom["pa_en2"] = (val != 0) ?"1":"0";
|
||||
}
|
||||
}
|
||||
|
||||
void store_umtrx_eeprom(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
|
||||
@@ -115,4 +136,24 @@ void store_umtrx_eeprom(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
|
||||
N100_EEPROM_ADDR, UMTRX_OFFSETS["tcxo-dac"],
|
||||
string_to_uint16_bytes(mb_eeprom["tcxo-dac"])
|
||||
);
|
||||
|
||||
if (mb_eeprom.has_key("pa_dcdc_r")) iface.write_eeprom(
|
||||
N100_EEPROM_ADDR, UMTRX_OFFSETS["pa_dcdc_r"],
|
||||
byte_vector_t(1, boost::lexical_cast<unsigned>(mb_eeprom["pa_dcdc_r"]))
|
||||
);
|
||||
|
||||
if (mb_eeprom.has_key("pa_low")) iface.write_eeprom(
|
||||
N100_EEPROM_ADDR, UMTRX_OFFSETS["pa_low"],
|
||||
byte_vector_t(1, boost::lexical_cast<int>(mb_eeprom["pa_low"]))
|
||||
);
|
||||
|
||||
if (mb_eeprom.has_key("pa_en1")) iface.write_eeprom(
|
||||
N100_EEPROM_ADDR, UMTRX_OFFSETS["pa_en1"],
|
||||
byte_vector_t(1, boost::lexical_cast<int>(mb_eeprom["pa_en1"]))
|
||||
);
|
||||
|
||||
if (mb_eeprom.has_key("pa_en2")) iface.write_eeprom(
|
||||
N100_EEPROM_ADDR, UMTRX_OFFSETS["pa_en2"],
|
||||
byte_vector_t(1, boost::lexical_cast<int>(mb_eeprom["pa_en2"]))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -39,18 +39,20 @@ static const boost::uint32_t MAX_SEQS_OUT = 15;
|
||||
#define SPI_CTRL SR_SPI_CORE + 1
|
||||
#define SPI_DATA SR_SPI_CORE + 2
|
||||
// spi clock rate = master_clock/(div+1)/2
|
||||
#define SPI_DIVIDER 4
|
||||
#define SPI_DIVIDER 16
|
||||
|
||||
class umtrx_fifo_ctrl_impl : public umtrx_fifo_ctrl{
|
||||
public:
|
||||
|
||||
umtrx_fifo_ctrl_impl(zero_copy_if::sptr xport, const boost::uint32_t sid):
|
||||
umtrx_fifo_ctrl_impl(zero_copy_if::sptr xport, const boost::uint32_t sid, const boost::uint32_t window_size):
|
||||
_xport(xport),
|
||||
_sid(sid),
|
||||
_window_size(std::min(window_size, MAX_SEQS_OUT)),
|
||||
_seq_out(0),
|
||||
_seq_ack(0),
|
||||
_timeout(ACK_TIMEOUT)
|
||||
{
|
||||
UHD_MSG(status) << "fifo_ctrl.window_size = " << _window_size << std::endl;
|
||||
while (_xport->get_recv_buff(0.0)){} //flush
|
||||
this->set_time(uhd::time_spec_t(0.0));
|
||||
this->set_tick_rate(1.0); //something possible but bogus
|
||||
@@ -72,7 +74,7 @@ public:
|
||||
|
||||
this->send_pkt((addr - SETTING_REGS_BASE)/4, data, POKE32_CMD);
|
||||
|
||||
this->wait_for_ack(_seq_out-MAX_SEQS_OUT);
|
||||
this->wait_for_ack(_seq_out-_window_size);
|
||||
}
|
||||
|
||||
boost::uint32_t peek32(wb_addr_type addr){
|
||||
@@ -101,7 +103,7 @@ public:
|
||||
boost::mutex::scoped_lock lock(_mutex);
|
||||
|
||||
this->send_pkt(SPI_DIV, SPI_DIVIDER, POKE32_CMD);
|
||||
this->wait_for_ack(_seq_out-MAX_SEQS_OUT);
|
||||
this->wait_for_ack(_seq_out-_window_size);
|
||||
|
||||
_ctrl_word_cache = 0; // force update first time around
|
||||
}
|
||||
@@ -128,13 +130,13 @@ public:
|
||||
//conditionally send control word
|
||||
if (_ctrl_word_cache != ctrl_word){
|
||||
this->send_pkt(SPI_CTRL, ctrl_word, POKE32_CMD);
|
||||
this->wait_for_ack(_seq_out-MAX_SEQS_OUT);
|
||||
this->wait_for_ack(_seq_out-_window_size);
|
||||
_ctrl_word_cache = ctrl_word;
|
||||
}
|
||||
|
||||
//send data word
|
||||
this->send_pkt(SPI_DATA, data_out, POKE32_CMD);
|
||||
this->wait_for_ack(_seq_out-MAX_SEQS_OUT);
|
||||
this->wait_for_ack(_seq_out-_window_size);
|
||||
|
||||
//conditional readback
|
||||
if (readback){
|
||||
@@ -230,6 +232,7 @@ private:
|
||||
|
||||
zero_copy_if::sptr _xport;
|
||||
const boost::uint32_t _sid;
|
||||
const boost::uint32_t _window_size;
|
||||
boost::mutex _mutex;
|
||||
boost::uint16_t _seq_out;
|
||||
boost::uint16_t _seq_ack;
|
||||
@@ -241,6 +244,6 @@ private:
|
||||
};
|
||||
|
||||
|
||||
umtrx_fifo_ctrl::sptr umtrx_fifo_ctrl::make(zero_copy_if::sptr xport, const boost::uint32_t sid){
|
||||
return sptr(new umtrx_fifo_ctrl_impl(xport, sid));
|
||||
umtrx_fifo_ctrl::sptr umtrx_fifo_ctrl::make(zero_copy_if::sptr xport, const boost::uint32_t sid, const size_t window_size){
|
||||
return sptr(new umtrx_fifo_ctrl_impl(xport, sid, boost::uint32_t(window_size)));
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
typedef boost::shared_ptr<umtrx_fifo_ctrl> sptr;
|
||||
|
||||
//! Make a new FIFO control object
|
||||
static sptr make(uhd::transport::zero_copy_if::sptr xport, const boost::uint32_t sid);
|
||||
static sptr make(uhd::transport::zero_copy_if::sptr xport, const boost::uint32_t sid, const size_t window_size);
|
||||
|
||||
//! Set the command time that will activate
|
||||
virtual void set_time(const uhd::time_spec_t &time) = 0;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "umtrx_iface.hpp"
|
||||
#include <uhd/exception.hpp>
|
||||
#include <uhd/utils/msg.hpp>
|
||||
#include <uhd/utils/platform.hpp>
|
||||
#include "missing/platform.hpp"
|
||||
#include <uhd/utils/tasks.hpp>
|
||||
#include <uhd/utils/safe_call.hpp>
|
||||
#include <uhd/types/dict.hpp>
|
||||
@@ -354,7 +354,8 @@ public:
|
||||
|
||||
const std::string get_fw_version_string(void){
|
||||
boost::uint32_t minor = this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FW_PEEK32>(U2_FW_REG_VER_MINOR);
|
||||
return str(boost::format("%u.%u") % _protocol_compat % minor);
|
||||
boost::uint32_t githash = this->get_reg<boost::uint32_t, USRP2_REG_ACTION_FW_PEEK32>(U2_FW_REG_GIT_HASH);
|
||||
return str(boost::format("%u.%u-g%x") % _protocol_compat % minor % githash);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -17,13 +17,14 @@
|
||||
|
||||
#include "umtrx_impl.hpp"
|
||||
#include "umtrx_regs.hpp"
|
||||
#include "umtrx_version.hpp"
|
||||
#include "cores/apply_corrections.hpp"
|
||||
#include <uhd/utils/log.hpp>
|
||||
#include <uhd/utils/msg.hpp>
|
||||
#include <uhd/types/sensors.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/thread.hpp> //sleep
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
static int verbosity = 0;
|
||||
|
||||
@@ -32,6 +33,55 @@ using namespace uhd::usrp;
|
||||
using namespace uhd::transport;
|
||||
namespace asio = boost::asio;
|
||||
|
||||
// Values recommended by Andrey Sviyazov
|
||||
const int umtrx_impl::UMTRX_VGA1_DEF = -20;
|
||||
const int umtrx_impl::UMTRX_VGA2_DEF = 22;
|
||||
const int umtrx_impl::UMTRX_VGA2_MIN = 0;
|
||||
|
||||
static const double _dcdc_val_to_volt_init[256] =
|
||||
{
|
||||
9.38, 9.38, 9.40, 9.42, 9.42, 9.44, 9.46, 9.46, 9.48, 9.50, // 10
|
||||
9.50, 9.52, 9.54, 9.54, 9.56, 9.58, 9.58, 9.60, 9.60, 9.62, // 20
|
||||
9.64, 9.66, 9.66, 9.68, 9.70, 9.70, 9.72, 9.74, 9.76, 9.76, // 30
|
||||
9.78, 9.80, 9.82, 9.82, 9.84, 9.86, 9.88, 9.90, 9.92, 9.92, // 40
|
||||
9.94, 9.96, 9.98, 9.98, 10.00, 10.02, 10.04, 10.06, 10.06, 10.08, // 50
|
||||
10.10, 10.12, 10.14, 10.16, 10.18, 10.20, 10.20, 10.24, 10.24, 10.28, // 60
|
||||
10.30, 10.32, 10.34, 10.34, 10.36, 10.38, 10.40, 10.42, 10.44, 10.46, // 70
|
||||
10.48, 10.50, 10.52, 10.54, 10.56, 10.60, 10.62, 10.64, 10.66, 10.68, // 80
|
||||
10.70, 10.72, 10.74, 10.76, 10.78, 10.80, 10.84, 10.86, 10.88, 10.90, // 90
|
||||
10.94, 10.96, 10.98, 11.00, 11.02, 11.06, 11.06, 11.10, 11.12, 11.16, // 100
|
||||
11.18, 11.20, 11.24, 11.26, 11.28, 11.32, 11.34, 11.38, 11.40, 11.44, // 110
|
||||
11.46, 11.50, 11.50, 11.54, 11.58, 11.60, 11.64, 11.66, 11.70, 11.74, // 120
|
||||
11.76, 11.80, 11.84, 11.86, 11.90, 11.94, 11.98, 12.00, 12.02, 12.06, // 130
|
||||
12.10, 12.14, 12.18, 12.22, 12.26, 12.28, 12.32, 12.36, 12.40, 12.44, // 140
|
||||
12.48, 12.54, 12.58, 12.62, 12.64, 12.68, 12.72, 12.76, 12.82, 12.86, // 150
|
||||
12.90, 12.96, 13.00, 13.04, 13.10, 13.14, 13.20, 13.24, 13.30, 13.34, // 160
|
||||
13.38, 13.44, 13.48, 13.54, 13.60, 13.66, 13.72, 13.76, 13.82, 13.88, // 170
|
||||
13.94, 14.02, 14.06, 14.14, 14.20, 14.26, 14.30, 14.36, 14.42, 14.50, // 180
|
||||
14.56, 14.64, 14.72, 14.78, 14.86, 14.92, 15.00, 15.08, 15.16, 15.24, // 190
|
||||
15.32, 15.40, 15.46, 15.54, 15.62, 15.72, 15.80, 15.90, 16.00, 16.08, // 200
|
||||
16.18, 16.28, 16.38, 16.48, 16.58, 16.68, 16.80, 16.90, 16.96, 17.08, // 210
|
||||
17.20, 17.32, 17.44, 17.56, 17.68, 17.82, 17.94, 18.06, 18.20, 18.36, // 220
|
||||
18.48, 18.64, 18.78, 18.94, 19.02, 19.18, 19.34, 19.50, 19.68, 19.84, // 230
|
||||
20.02, 20.20, 20.38, 20.58, 20.76, 20.96, 21.18, 21.38, 21.60, 21.82, // 240
|
||||
21.92, 22.16, 22.40, 22.66, 22.92, 23.18, 23.46, 23.74, 24.02, 24.30, // 250
|
||||
24.62, 24.94, 25.28, 25.62, 25.98, 26.34
|
||||
};
|
||||
const std::vector<double> umtrx_impl::_dcdc_val_to_volt(_dcdc_val_to_volt_init, &_dcdc_val_to_volt_init[256]);
|
||||
|
||||
/***********************************************************************
|
||||
* Property tree "alias" function
|
||||
**********************************************************************/
|
||||
|
||||
template <typename T> property<T> &property_alias(uhd::property_tree::sptr &_tree,
|
||||
const uhd::fs_path &orig, const uhd::fs_path &alias)
|
||||
{
|
||||
// By default route each chanel to its own antenna
|
||||
return _tree->create<T>(alias)
|
||||
.subscribe(boost::bind(&uhd::property<T>::set, boost::ref(_tree->access<T>(orig)), _1))
|
||||
.publish(boost::bind(&uhd::property<T>::get, boost::ref(_tree->access<T>(orig))));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Make
|
||||
**********************************************************************/
|
||||
@@ -42,7 +92,11 @@ static device::sptr umtrx_make(const device_addr_t &device_addr){
|
||||
device_addrs_t umtrx_find(const device_addr_t &hint);
|
||||
|
||||
UHD_STATIC_BLOCK(register_umtrx_device){
|
||||
#ifdef UHD_HAS_DEVICE_FILTER
|
||||
device::register_device(&umtrx_find, &umtrx_make, device::USRP);
|
||||
#else
|
||||
device::register_device(&umtrx_find, &umtrx_make);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -52,6 +106,12 @@ struct mtu_result_t{
|
||||
size_t recv_mtu, send_mtu;
|
||||
};
|
||||
|
||||
static std::vector<std::string> power_sensors =
|
||||
boost::assign::list_of("PR1")("PF1")("PR2")("PF2");
|
||||
|
||||
static std::vector<std::string> dc_sensors =
|
||||
boost::assign::list_of("zero")("Vin")("VinPA")("DCOUT");
|
||||
|
||||
static mtu_result_t determine_mtu(const std::string &addr, const mtu_result_t &user_mtu){
|
||||
udp_simple::sptr udp_sock = udp_simple::make_connected(
|
||||
addr, BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT)
|
||||
@@ -120,6 +180,7 @@ static mtu_result_t determine_mtu(const std::string &addr, const mtu_result_t &u
|
||||
umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
|
||||
{
|
||||
_device_ip_addr = device_addr["addr"];
|
||||
UHD_MSG(status) << "UmTRX driver version: " << UMTRX_VERSION << std::endl;
|
||||
UHD_MSG(status) << "Opening a UmTRX device... " << _device_ip_addr << std::endl;
|
||||
|
||||
//mtu self check -- not really doing anything with it
|
||||
@@ -171,7 +232,8 @@ umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
|
||||
// high performance settings control
|
||||
////////////////////////////////////////////////////////////////
|
||||
_iface->poke32(U2_REG_MISC_CTRL_SFC_CLEAR, 1); //clear settings fifo control state machine
|
||||
_ctrl = umtrx_fifo_ctrl::make(this->make_xport(UMTRX_CTRL_FRAMER, device_addr_t()), UMTRX_CTRL_SID);
|
||||
const size_t fifo_ctrl_window(device_addr.cast<size_t>("fifo_ctrl_window", 1024)); //default gets clipped to hardware maximum
|
||||
_ctrl = umtrx_fifo_ctrl::make(this->make_xport(UMTRX_CTRL_FRAMER, device_addr_t()), UMTRX_CTRL_SID, fifo_ctrl_window);
|
||||
_ctrl->peek32(0); //test readback
|
||||
_tree->create<time_spec_t>(mb_path / "time/cmd")
|
||||
.subscribe(boost::bind(&umtrx_fifo_ctrl::set_time, _ctrl, _1));
|
||||
@@ -201,6 +263,83 @@ umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
|
||||
_iface->poke32(U2_REG_MISC_LMS_RES, 0);
|
||||
_iface->poke32(U2_REG_MISC_LMS_RES, LMS1_RESET | LMS2_RESET);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// autodetect umtrx hardware rev and initialize rev. specific sensors
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
detect_hw_rev(mb_path);
|
||||
_tree->create<std::string>(mb_path / "hwrev").set(get_hw_rev());
|
||||
UHD_MSG(status) << "Detected UmTRX " << get_hw_rev() << std::endl;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// configure diversity switches
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// note: the control is also aliased to RF frontend later
|
||||
_tree->create<bool>(mb_path / "divsw1")
|
||||
.subscribe(boost::bind(&umtrx_impl::set_diversity, this, _1, 0))
|
||||
.set(device_addr.cast<bool>("divsw1", false));
|
||||
UHD_MSG(status) << "Diversity switch for channel 1: "
|
||||
<< (_tree->access<bool>(mb_path / "divsw1").get()?"true":"false")
|
||||
<< std::endl;
|
||||
_tree->create<bool>(mb_path / "divsw2")
|
||||
.subscribe(boost::bind(&umtrx_impl::set_diversity, this, _1, 1))
|
||||
.set(device_addr.cast<bool>("divsw2", false));
|
||||
UHD_MSG(status) << "Diversity switch for channel 2: "
|
||||
<< (_tree->access<bool>(mb_path / "divsw2").get()?"true":"false")
|
||||
<< std::endl;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// set PLL divider
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: Add EEPROM cell to manually override this
|
||||
_pll_div = 1;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// get the atached PA type
|
||||
////////////////////////////////////////////////////////////////////
|
||||
std::list<std::string> pa_types = power_amp::list_pa_str();
|
||||
std::string pa_list_str;
|
||||
BOOST_FOREACH(const std::string &pa_str, pa_types)
|
||||
{
|
||||
pa_list_str += pa_str + " ";
|
||||
}
|
||||
UHD_MSG(status) << "Known PA types: " << pa_list_str << std::endl;
|
||||
|
||||
power_amp::pa_type_t pa_type = power_amp::pa_str_to_type(device_addr.cast<std::string>("pa", "NONE"));
|
||||
if (_hw_rev < UMTRX_VER_2_3_1 and pa_type != power_amp::PA_NONE)
|
||||
{
|
||||
UHD_MSG(error) << "PA type " << power_amp::pa_type_to_str(pa_type) << " is not supported for UmTRX "
|
||||
<< get_hw_rev() << ". Setting PA type to NONE." << std::endl;
|
||||
pa_type = power_amp::PA_NONE;
|
||||
}
|
||||
|
||||
for (char name = 'A'; name <= 'B'; name++)
|
||||
{
|
||||
std::string name_str = std::string(1, name);
|
||||
_pa[name_str] = power_amp::make(pa_type);
|
||||
UHD_MSG(status) << "Installed PA for side" << name_str << ": " << power_amp::pa_type_to_str(pa_type) << std::endl;
|
||||
}
|
||||
|
||||
if (_pa["A"])
|
||||
{
|
||||
_pa_power_max_dBm = _pa["A"]->max_power_dBm();
|
||||
|
||||
double limit_w = device_addr.cast<double>("pa_power_max_w", _pa["A"]->max_power_w());
|
||||
if (limit_w != _pa["A"]->max_power_w()) {
|
||||
_pa_power_max_dBm = power_amp::w2dBm(limit_w);
|
||||
}
|
||||
|
||||
double limit_dbm = device_addr.cast<double>("pa_power_max_dbm", _pa["A"]->max_power_dBm());
|
||||
if (limit_dbm != _pa["A"]->max_power_dBm()) {
|
||||
_pa_power_max_dBm = limit_dbm;
|
||||
}
|
||||
|
||||
if (_pa_power_max_dBm != _pa["A"]->max_power_dBm()) {
|
||||
UHD_MSG(status) << "Limiting PA output power to: " << _pa_power_max_dBm << "dBm (" << power_amp::dBm2w(_pa_power_max_dBm) << "W)" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// create codec control objects
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -215,11 +354,6 @@ umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
|
||||
_tree->create<int>(tx_codec_path / "gains"); //empty cuz gains are in frontend
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// sensors on the mboard
|
||||
////////////////////////////////////////////////////////////////
|
||||
_tree->create<sensor_value_t>(mb_path / "sensors"); //phony property so this dir exists
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// create frontend control objects
|
||||
////////////////////////////////////////////////////////////////
|
||||
@@ -253,21 +387,27 @@ umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
|
||||
.set(true);
|
||||
_tree->create<std::complex<double> >(rx_fe_path / "iq_balance" / "value")
|
||||
.subscribe(boost::bind(&rx_frontend_core_200::set_iq_balance, rx_fe, _1))
|
||||
.set(std::polar<double>(1.0, 0.0));
|
||||
.set(std::polar<double>(0.0, 0.0));
|
||||
/*
|
||||
_tree->create<std::complex<double> >(tx_fe_path / "dc_offset" / "value")
|
||||
.coerce(boost::bind(&tx_frontend_core_200::set_dc_offset, tx_fe, _1))
|
||||
.set(std::complex<double>(0.0, 0.0));
|
||||
*/
|
||||
_tree->create<std::complex<double> >(tx_fe_path / "iq_balance" / "value")
|
||||
.subscribe(boost::bind(&tx_frontend_core_200::set_iq_balance, tx_fe, _1))
|
||||
.set(std::polar<double>(1.0, 0.0));
|
||||
.set(std::polar<double>(0.0, 0.0));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// create rx dsp control objects
|
||||
////////////////////////////////////////////////////////////////
|
||||
_rx_dsps.resize(2);
|
||||
_rx_dsps[0] = rx_dsp_core_200::make(_ctrl, U2_REG_SR_ADDR(SR_RX_DSP0), U2_REG_SR_ADDR(SR_RX_CTRL0), UMTRX_DSP_RX0_SID, true);
|
||||
_rx_dsps[1] = rx_dsp_core_200::make(_ctrl, U2_REG_SR_ADDR(SR_RX_DSP1), U2_REG_SR_ADDR(SR_RX_CTRL1), UMTRX_DSP_RX1_SID, true);
|
||||
_rx_dsps.resize(_iface->peek32(U2_REG_NUM_DDC));
|
||||
if (_rx_dsps.size() < 2) throw uhd::runtime_error(str(boost::format("umtrx rx_dsps %u -- (unsupported FPGA image?)") % _rx_dsps.size()));
|
||||
if (_rx_dsps.size() > 0) _rx_dsps[0] = rx_dsp_core_200::make(_ctrl, U2_REG_SR_ADDR(SR_RX_DSP0), U2_REG_SR_ADDR(SR_RX_CTRL0), UMTRX_DSP_RX0_SID, true);
|
||||
if (_rx_dsps.size() > 1) _rx_dsps[1] = rx_dsp_core_200::make(_ctrl, U2_REG_SR_ADDR(SR_RX_DSP1), U2_REG_SR_ADDR(SR_RX_CTRL1), UMTRX_DSP_RX1_SID, true);
|
||||
if (_rx_dsps.size() > 2) _rx_dsps[2] = rx_dsp_core_200::make(_ctrl, U2_REG_SR_ADDR(SR_RX_DSP2), U2_REG_SR_ADDR(SR_RX_CTRL2), UMTRX_DSP_RX2_SID, true);
|
||||
if (_rx_dsps.size() > 3) _rx_dsps[3] = rx_dsp_core_200::make(_ctrl, U2_REG_SR_ADDR(SR_RX_DSP3), U2_REG_SR_ADDR(SR_RX_CTRL3), UMTRX_DSP_RX3_SID, true);
|
||||
_tree->create<sensor_value_t>(mb_path / "rx_dsps"); //phony property so this dir exists
|
||||
|
||||
for (size_t dspno = 0; dspno < _rx_dsps.size(); dspno++){
|
||||
_rx_dsps[dspno]->set_mux("IQ", false/*no swap*/);
|
||||
@@ -294,9 +434,11 @@ umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
|
||||
////////////////////////////////////////////////////////////////
|
||||
// create tx dsp control objects
|
||||
////////////////////////////////////////////////////////////////
|
||||
_tx_dsps.resize(2);
|
||||
_tx_dsps[0] = tx_dsp_core_200::make(_ctrl, U2_REG_SR_ADDR(SR_TX_DSP0), U2_REG_SR_ADDR(SR_TX_CTRL0), UMTRX_DSP_TX0_SID);
|
||||
_tx_dsps[1] = tx_dsp_core_200::make(_ctrl, U2_REG_SR_ADDR(SR_TX_DSP1), U2_REG_SR_ADDR(SR_TX_CTRL1), UMTRX_DSP_TX1_SID);
|
||||
_tx_dsps.resize(_iface->peek32(U2_REG_NUM_DUC));
|
||||
if (_tx_dsps.empty()) _tx_dsps.resize(1); //uhd cant support empty sides
|
||||
if (_tx_dsps.size() > 0) _tx_dsps[0] = tx_dsp_core_200::make(_ctrl, U2_REG_SR_ADDR(SR_TX_DSP0), U2_REG_SR_ADDR(SR_TX_CTRL0), UMTRX_DSP_TX0_SID);
|
||||
if (_tx_dsps.size() > 1) _tx_dsps[1] = tx_dsp_core_200::make(_ctrl, U2_REG_SR_ADDR(SR_TX_DSP1), U2_REG_SR_ADDR(SR_TX_CTRL1), UMTRX_DSP_TX1_SID);
|
||||
_tree->create<sensor_value_t>(mb_path / "tx_dsps"); //phony property so this dir exists
|
||||
|
||||
for (size_t dspno = 0; dspno < _tx_dsps.size(); dspno++){
|
||||
_tx_dsps[dspno]->set_link_rate(UMTRX_LINK_RATE_BPS);
|
||||
@@ -348,8 +490,8 @@ umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// create RF frontend interfacing
|
||||
////////////////////////////////////////////////////////////////////
|
||||
_lms_ctrl["A"] = lms6002d_ctrl::make(_ctrl/*spi*/, SPI_SS_LMS1, SPI_SS_AUX1, this->get_master_clock_rate());
|
||||
_lms_ctrl["B"] = lms6002d_ctrl::make(_ctrl/*spi*/, SPI_SS_LMS2, SPI_SS_AUX2, this->get_master_clock_rate());
|
||||
_lms_ctrl["A"] = lms6002d_ctrl::make(_ctrl/*spi*/, SPI_SS_LMS1, SPI_SS_AUX1, this->get_master_clock_rate() / _pll_div);
|
||||
_lms_ctrl["B"] = lms6002d_ctrl::make(_ctrl/*spi*/, SPI_SS_LMS2, SPI_SS_AUX2, this->get_master_clock_rate() / _pll_div);
|
||||
|
||||
// LMS dboard do not have physical eeprom so we just hardcode values from host/lib/usrp/dboard/db_lms.cpp
|
||||
dboard_eeprom_t rx_db_eeprom, tx_db_eeprom, gdb_db_eeprom;
|
||||
@@ -381,9 +523,9 @@ umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
|
||||
|
||||
//sensors -- always say locked
|
||||
_tree->create<sensor_value_t>(rx_rf_fe_path / "sensors" / "lo_locked")
|
||||
.set(sensor_value_t("LO", true, "locked", "unlocked"));
|
||||
.publish(boost::bind(&lms6002d_ctrl::get_rx_pll_locked, ctrl));
|
||||
_tree->create<sensor_value_t>(tx_rf_fe_path / "sensors" / "lo_locked")
|
||||
.set(sensor_value_t("LO", true, "locked", "unlocked"));
|
||||
.publish(boost::bind(&lms6002d_ctrl::get_tx_pll_locked, ctrl));
|
||||
|
||||
//rx gains
|
||||
BOOST_FOREACH(const std::string &name, ctrl->get_rx_gains())
|
||||
@@ -397,14 +539,33 @@ umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
|
||||
}
|
||||
|
||||
//tx gains
|
||||
BOOST_FOREACH(const std::string &name, ctrl->get_tx_gains())
|
||||
if (!_pa[fe_name])
|
||||
{
|
||||
_tree->create<meta_range_t>(tx_rf_fe_path / "gains" / name / "range")
|
||||
.publish(boost::bind(&lms6002d_ctrl::get_tx_gain_range, ctrl, name));
|
||||
// Use internal LMS gain control if we don't have a PA
|
||||
BOOST_FOREACH(const std::string &name, ctrl->get_tx_gains())
|
||||
{
|
||||
_tree->create<meta_range_t>(tx_rf_fe_path / "gains" / name / "range")
|
||||
.publish(boost::bind(&lms6002d_ctrl::get_tx_gain_range, ctrl, name));
|
||||
|
||||
_tree->create<double>(tx_rf_fe_path / "gains" / name / "value")
|
||||
.coerce(boost::bind(&lms6002d_ctrl::set_tx_gain, ctrl, _1, name))
|
||||
.set((ctrl->get_tx_gain_range(name).start() + ctrl->get_tx_gain_range(name).stop())/2.0);
|
||||
}
|
||||
} else {
|
||||
// Set LMS internal VGA1 gain to optimal value
|
||||
// VGA2 will be set in the set_tx_power()
|
||||
ctrl->set_tx_gain(UMTRX_VGA1_DEF, "VGA1");
|
||||
_tx_power_range[fe_name] = generate_tx_power_range(fe_name);
|
||||
|
||||
// Use PA control to control output power
|
||||
_tree->create<meta_range_t>(tx_rf_fe_path / "gains" / "PA" / "range")
|
||||
.publish(boost::bind(&umtrx_impl::get_tx_power_range, this, fe_name));
|
||||
|
||||
_tree->create<double>(tx_rf_fe_path / "gains" / "PA" / "value")
|
||||
.coerce(boost::bind(&umtrx_impl::set_tx_power, this, _1, fe_name))
|
||||
// Set default output power to maximum
|
||||
.set(get_tx_power_range(fe_name).stop());
|
||||
|
||||
_tree->create<double>(tx_rf_fe_path / "gains" / name / "value")
|
||||
.coerce(boost::bind(&lms6002d_ctrl::set_tx_gain, ctrl, _1, name))
|
||||
.set((ctrl->get_tx_gain_range(name).start() + ctrl->get_tx_gain_range(name).stop())/2.0);
|
||||
}
|
||||
|
||||
//rx freq
|
||||
@@ -459,8 +620,10 @@ umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
|
||||
|
||||
//bind frontend corrections to the dboard freq props
|
||||
_tree->access<double>(tx_rf_fe_path / "freq" / "value")
|
||||
.set(0.0) //default value
|
||||
.subscribe(boost::bind(&umtrx_impl::set_tx_fe_corrections, this, "0", fe_name, _1));
|
||||
_tree->access<double>(rx_rf_fe_path / "freq" / "value")
|
||||
.set(0.0) //default value
|
||||
.subscribe(boost::bind(&umtrx_impl::set_rx_fe_corrections, this, "0", fe_name, _1));
|
||||
|
||||
//tx cal props
|
||||
@@ -473,12 +636,19 @@ umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
|
||||
|
||||
//set Tx DC calibration values, which are read from mboard EEPROM
|
||||
std::string tx_name = (fe_name=="A")?"tx1":"tx2";
|
||||
const std::string dc_i = _iface->mb_eeprom.get(tx_name+"-vga1-dc-i", "");
|
||||
const std::string dc_q = _iface->mb_eeprom.get(tx_name+"-vga1-dc-q", "");
|
||||
if (not dc_i.empty()) _tree->access<uint8_t>(tx_rf_fe_path / "lms6002d" / "tx_dc_i" / "value")
|
||||
.set(boost::lexical_cast<int>(dc_i));
|
||||
if (not dc_q.empty()) _tree->access<uint8_t>(tx_rf_fe_path / "lms6002d" / "tx_dc_q" / "value")
|
||||
.set(boost::lexical_cast<int>(dc_q));
|
||||
const std::string dc_i_str = _iface->mb_eeprom.get(tx_name+"-vga1-dc-i", "");
|
||||
const std::string dc_q_str = _iface->mb_eeprom.get(tx_name+"-vga1-dc-q", "");
|
||||
double dc_i = dc_i_str.empty() ? 0.0 : dc_offset_int2double(boost::lexical_cast<int>(dc_i_str));
|
||||
double dc_q = dc_q_str.empty() ? 0.0 : dc_offset_int2double(boost::lexical_cast<int>(dc_q_str));
|
||||
|
||||
//plugin dc_offset from lms into the frontend corrections
|
||||
_tree->create<std::complex<double> >(mb_path / "tx_frontends" / fe_name / "dc_offset" / "value")
|
||||
.publish(boost::bind(&umtrx_impl::get_dc_offset_correction, this, fe_name))
|
||||
.subscribe(boost::bind(&umtrx_impl::set_dc_offset_correction, this, fe_name, _1))
|
||||
.set(std::complex<double>(dc_i, dc_q));
|
||||
|
||||
// Alias diversity switch control from mb_path
|
||||
property_alias<bool>(_tree, mb_path / "divsw"+(fe_name=="A"?"1":"2"), rx_rf_fe_path / "diversity");
|
||||
}
|
||||
|
||||
//set TCXO DAC calibration value, which is read from mboard EEPROM
|
||||
@@ -495,25 +665,153 @@ umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
|
||||
_tree->access<double>(mb_path / "dsp_rate")
|
||||
.set(this->get_master_dsp_rate());
|
||||
this->time64_self_test();
|
||||
|
||||
//reset cordic rates and their properties to zero
|
||||
BOOST_FOREACH(const std::string &name, _tree->list(mb_path / "rx_dsps"))
|
||||
{
|
||||
_tree->access<double>(mb_path / "rx_dsps" / name / "freq" / "value").set(0.0);
|
||||
}
|
||||
BOOST_FOREACH(const std::string &name, _tree->list(mb_path / "tx_dsps"))
|
||||
{
|
||||
_tree->access<double>(mb_path / "tx_dsps" / name / "freq" / "value").set(0.0);
|
||||
}
|
||||
|
||||
_rx_streamers.resize(_rx_dsps.size());
|
||||
_tx_streamers.resize(_tx_dsps.size());
|
||||
|
||||
_tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec").set(subdev_spec_t("A:0 B:0"));
|
||||
_tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(subdev_spec_t("A:0 B:0"));
|
||||
subdev_spec_t rx_spec("A:0 B:0 A:0 B:0");
|
||||
rx_spec.resize(_rx_dsps.size());
|
||||
_tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec").set(rx_spec);
|
||||
|
||||
subdev_spec_t tx_spec("A:0 B:0 A:0 B:0");
|
||||
tx_spec.resize(_tx_dsps.size());
|
||||
_tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(tx_spec);
|
||||
|
||||
_tree->access<std::string>(mb_path / "clock_source" / "value").set("internal");
|
||||
_tree->access<std::string>(mb_path / "time_source" / "value").set("none");
|
||||
|
||||
//create status monitor and client handler
|
||||
this->status_monitor_start(device_addr);
|
||||
}
|
||||
|
||||
umtrx_impl::~umtrx_impl(void){
|
||||
//TODO
|
||||
umtrx_impl::~umtrx_impl(void)
|
||||
{
|
||||
this->status_monitor_stop();
|
||||
|
||||
BOOST_FOREACH(const std::string &fe_name, _lms_ctrl.keys())
|
||||
{
|
||||
lms6002d_ctrl::sptr ctrl = _lms_ctrl[fe_name];
|
||||
try
|
||||
{
|
||||
ctrl->set_rx_enabled(false);
|
||||
ctrl->set_tx_enabled(false);
|
||||
}
|
||||
catch (...){}
|
||||
}
|
||||
}
|
||||
|
||||
int umtrx_impl::volt_to_dcdc_r(double v)
|
||||
{
|
||||
if (v <= _dcdc_val_to_volt[0])
|
||||
return 0;
|
||||
else if (v >= _dcdc_val_to_volt[255])
|
||||
return 255;
|
||||
else
|
||||
return std::lower_bound(_dcdc_val_to_volt.begin(), _dcdc_val_to_volt.end(), v) - _dcdc_val_to_volt.begin();
|
||||
}
|
||||
|
||||
void umtrx_impl::set_pa_dcdc_r(uint8_t val)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock l(_i2c_mutex);
|
||||
// AD5245 control
|
||||
if (_hw_rev >= UMTRX_VER_2_3_1)
|
||||
{
|
||||
_pa_dcdc_r = val;
|
||||
_iface->write_i2c(BOOST_BINARY(0101100), boost::assign::list_of(0)(val));
|
||||
}
|
||||
}
|
||||
|
||||
uhd::gain_range_t umtrx_impl::generate_tx_power_range(const std::string &which) const
|
||||
{
|
||||
// Native PA range plus LMS6 VGA2 control. We keep LMS6 VGA1 constant to
|
||||
// maintain high signal quality.
|
||||
uhd::gain_range_t pa_range = generate_pa_power_range(which);
|
||||
// UHD_MSG(status) << "Original PA output power range: " << pa_range.to_pp_string() << std::endl;
|
||||
uhd::gain_range_t vga_range(pa_range.start() - (UMTRX_VGA2_DEF-UMTRX_VGA2_MIN), pa_range.start()-1, 1.0);
|
||||
uhd::gain_range_t res_range(vga_range);
|
||||
res_range.insert(res_range.end(), pa_range.begin(), pa_range.end());
|
||||
// UHD_MSG(status) << "Generated Tx output power range: " << res_range.to_pp_string() << std::endl;
|
||||
return res_range;
|
||||
}
|
||||
|
||||
uhd::gain_range_t umtrx_impl::generate_pa_power_range(const std::string &which) const
|
||||
{
|
||||
double min_power = _pa[which]->min_power_dBm();
|
||||
double max_power = _pa_power_max_dBm;
|
||||
return uhd::gain_range_t(min_power, max_power, 0.1);
|
||||
}
|
||||
|
||||
const uhd::gain_range_t &umtrx_impl::get_tx_power_range(const std::string &which) const
|
||||
{
|
||||
return _tx_power_range[which];
|
||||
}
|
||||
|
||||
double umtrx_impl::set_tx_power(double power, const std::string &which)
|
||||
{
|
||||
double min_pa_power = _pa[which]->min_power_dBm();
|
||||
double actual_power;
|
||||
|
||||
if (power >= min_pa_power)
|
||||
{
|
||||
UHD_MSG(status) << "Setting Tx power using PA (VGA2=" << UMTRX_VGA2_DEF << ", PA=" << power << ")" << std::endl;
|
||||
// Set VGA2 to the recommended value and use PA to control Tx power
|
||||
_lms_ctrl[which]->set_tx_gain(UMTRX_VGA2_DEF, "VGA2");
|
||||
actual_power = set_pa_power(power, which);
|
||||
} else {
|
||||
double vga2_gain = UMTRX_VGA2_DEF - (min_pa_power-power);
|
||||
UHD_MSG(status) << "Setting Tx power using VGA2 (VGA2=" << vga2_gain << ", PA=" << min_pa_power << ")" << std::endl;
|
||||
// Set PA output power to minimum and use VGA2 to control Tx power
|
||||
actual_power = _lms_ctrl[which]->set_tx_gain(vga2_gain, "VGA2");
|
||||
actual_power = set_pa_power(min_pa_power, which) - (UMTRX_VGA2_DEF-actual_power);
|
||||
}
|
||||
|
||||
return actual_power;
|
||||
}
|
||||
|
||||
double umtrx_impl::set_pa_power(double power, const std::string &which)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock l(_i2c_mutex);
|
||||
// TODO:: Use DCDC bypass for maximum output power
|
||||
// TODO:: Limit output power for UmSITE-TM3
|
||||
|
||||
// Find voltage required for the requested output power
|
||||
double v = _pa[which]->dBm2v(power);
|
||||
uint8_t dcdc_val = volt_to_dcdc_r(v);
|
||||
// Set the value
|
||||
set_nlow(true);
|
||||
set_pa_dcdc_r(dcdc_val);
|
||||
|
||||
// Check what power do we actually have by reading the DCDC voltage
|
||||
// and converting it to the PA power
|
||||
double v_actual = read_dc_v("DCOUT").to_real();
|
||||
double power_actual = _pa[which]->v2dBm(v_actual);
|
||||
|
||||
// TODO:: Check that power is actually there by reading VSWR sensor.
|
||||
|
||||
UHD_MSG(status) << "Setting PA power: Requested: " << power << "dBm = " << power_amp::dBm2w(power) << "W "
|
||||
<< "(" << v << "V dcdc_r=" << int(dcdc_val) << "). "
|
||||
<< "Actual: " << power_actual << "dBm = " << power_amp::dBm2w(power_actual) <<"W "
|
||||
<< "(" << v_actual << "V)" << std::endl;
|
||||
|
||||
return power_actual;
|
||||
}
|
||||
|
||||
void umtrx_impl::set_mb_eeprom(const uhd::i2c_iface::sptr &iface, const uhd::usrp::mboard_eeprom_t &eeprom)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock l(_i2c_mutex);
|
||||
store_umtrx_eeprom(eeprom, *iface);
|
||||
}
|
||||
|
||||
|
||||
void umtrx_impl::time64_self_test(void)
|
||||
{
|
||||
//check the the ticks elapsed across a sleep is within an expected range
|
||||
@@ -549,3 +847,217 @@ uint16_t umtrx_impl::get_tcxo_dac(const umtrx_iface::sptr &iface){
|
||||
if (verbosity>0) printf("umtrx_impl::get_tcxo_dac(): %d\n", val);
|
||||
return (uint16_t)val;
|
||||
}
|
||||
|
||||
std::complex<double> umtrx_impl::get_dc_offset_correction(const std::string &which) const
|
||||
{
|
||||
return std::complex<double>(
|
||||
dc_offset_int2double(_lms_ctrl[which]->get_tx_vga1dc_i_int()),
|
||||
dc_offset_int2double(_lms_ctrl[which]->get_tx_vga1dc_q_int()));
|
||||
}
|
||||
|
||||
void umtrx_impl::set_dc_offset_correction(const std::string &which, const std::complex<double> &corr)
|
||||
{
|
||||
_lms_ctrl[which]->_set_tx_vga1dc_i_int(dc_offset_double2int(corr.real()));
|
||||
_lms_ctrl[which]->_set_tx_vga1dc_q_int(dc_offset_double2int(corr.imag()));
|
||||
}
|
||||
|
||||
double umtrx_impl::dc_offset_int2double(uint8_t corr)
|
||||
{
|
||||
return (corr-128)/128.0;
|
||||
}
|
||||
|
||||
uint8_t umtrx_impl::dc_offset_double2int(double corr)
|
||||
{
|
||||
return (int)(corr*128 + 128.5);
|
||||
}
|
||||
|
||||
uhd::sensor_value_t umtrx_impl::read_temp_c(const std::string &which)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock l(_i2c_mutex);
|
||||
double temp = (which == "A") ? _temp_side_a.get_temp() :
|
||||
_temp_side_b.get_temp();
|
||||
return uhd::sensor_value_t("Temp"+which, temp, "C");
|
||||
}
|
||||
|
||||
uhd::sensor_value_t umtrx_impl::read_pa_v(const std::string &which)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock l(_i2c_mutex);
|
||||
unsigned i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (which == power_sensors[i])
|
||||
break;
|
||||
}
|
||||
UHD_ASSERT_THROW(i < 4);
|
||||
|
||||
_sense_pwr.set_input((ads1015_ctrl::ads1015_input)
|
||||
(ads1015_ctrl::ADS1015_CONF_AIN0_GND + i));
|
||||
double val = _sense_pwr.get_value() * 10;
|
||||
return uhd::sensor_value_t("Voltage"+which, val, "V");
|
||||
}
|
||||
|
||||
uhd::sensor_value_t umtrx_impl::read_dc_v(const std::string &which)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock l(_i2c_mutex);
|
||||
unsigned i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (which == dc_sensors[i])
|
||||
break;
|
||||
}
|
||||
UHD_ASSERT_THROW(i < 4);
|
||||
|
||||
_sense_dc.set_input((ads1015_ctrl::ads1015_input)
|
||||
(ads1015_ctrl::ADS1015_CONF_AIN0_GND + i));
|
||||
double val = _sense_dc.get_value() * 40;
|
||||
return uhd::sensor_value_t("Voltage"+which, val, "V");
|
||||
}
|
||||
|
||||
void umtrx_impl::detect_hw_rev(const fs_path& mb_path)
|
||||
{
|
||||
//UmTRX v2.0 doesn't have temp sensors
|
||||
//UmTRX v2.1 has a temp sensor only on A side
|
||||
//UmTRX v2.2 has both temp sensor
|
||||
//UmTRX v2.3.0 has power sensors ADC
|
||||
//UmTRX v2.3.1 has power supply ADC & programmed resistor array
|
||||
|
||||
if (!tmp102_ctrl::check(_iface, tmp102_ctrl::TMP102_SDA)) {
|
||||
_tree->create<sensor_value_t>(mb_path / "sensors"); //phony property so this dir exists
|
||||
_hw_rev = UMTRX_VER_2_0;
|
||||
return;
|
||||
}
|
||||
// Initialize side A temp sensor
|
||||
_temp_side_a.init(_iface, tmp102_ctrl::TMP102_SDA);
|
||||
_temp_side_a.set_ex_mode(true);
|
||||
_tree->create<sensor_value_t>(mb_path / "sensors" / "tempA")
|
||||
.publish(boost::bind(&umtrx_impl::read_temp_c, this, "A"));
|
||||
UHD_MSG(status) << this->read_temp_c("A").to_pp_string() << std::endl;
|
||||
|
||||
if (!tmp102_ctrl::check(_iface, tmp102_ctrl::TMP102_SCL)) {
|
||||
_hw_rev = UMTRX_VER_2_1;
|
||||
return;
|
||||
}
|
||||
// Initialize side B temp sensor
|
||||
_temp_side_b.init(_iface, tmp102_ctrl::TMP102_SCL);
|
||||
_temp_side_b.set_ex_mode(true);
|
||||
_tree->create<sensor_value_t>(mb_path / "sensors" / "tempB")
|
||||
.publish(boost::bind(&umtrx_impl::read_temp_c, this, "B"));
|
||||
UHD_MSG(status) << this->read_temp_c("B").to_pp_string() << std::endl;
|
||||
|
||||
if (!ads1015_ctrl::check(_iface, ads1015_ctrl::ADS1015_ADDR_VDD)) {
|
||||
_hw_rev = UMTRX_VER_2_2;
|
||||
return;
|
||||
}
|
||||
//Initialize PA sense ADC
|
||||
_sense_pwr.init(_iface, ads1015_ctrl::ADS1015_ADDR_VDD);
|
||||
_sense_pwr.set_mode(true);
|
||||
_sense_pwr.set_pga(ads1015_ctrl::ADS1015_PGA_2_048V);
|
||||
for (unsigned i = 0; i < power_sensors.size(); i++) {
|
||||
_tree->create<sensor_value_t>(mb_path / "sensors" / "voltage"+power_sensors[i])
|
||||
.publish(boost::bind(&umtrx_impl::read_pa_v, this, power_sensors[i]));
|
||||
UHD_MSG(status) << this->read_pa_v(power_sensors[i]).to_pp_string() << std::endl;
|
||||
}
|
||||
|
||||
if (!ads1015_ctrl::check(_iface, ads1015_ctrl::ADS1015_ADDR_GROUND)) {
|
||||
_hw_rev = UMTRX_VER_2_3_0;
|
||||
return;
|
||||
}
|
||||
_sense_dc.init(_iface, ads1015_ctrl::ADS1015_ADDR_GROUND);
|
||||
_sense_dc.set_mode(true);
|
||||
_sense_dc.set_pga(ads1015_ctrl::ADS1015_PGA_1_024V);
|
||||
for (unsigned i = 0; i < power_sensors.size(); i++) {
|
||||
_tree->create<sensor_value_t>(mb_path / "sensors" / "voltage"+dc_sensors[i])
|
||||
.publish(boost::bind(&umtrx_impl::read_dc_v, this, dc_sensors[i]));
|
||||
UHD_MSG(status) << this->read_dc_v(dc_sensors[i]).to_pp_string() << std::endl;
|
||||
}
|
||||
|
||||
_hw_rev = UMTRX_VER_2_3_1;
|
||||
_tree->create<uint8_t>(mb_path / "pa_dcdc_r")
|
||||
.subscribe(boost::bind(&umtrx_impl::set_pa_dcdc_r, this, _1));
|
||||
|
||||
std::string pa_dcdc_r = _iface->mb_eeprom.get("pa_dcdc_r", "");
|
||||
char* pa_dcdc_r_env = getenv("UMTRX_PA_DCDC_R");
|
||||
if (pa_dcdc_r_env) {
|
||||
UHD_MSG(status) << "EEPROM value of pa_dcdc_r:" << pa_dcdc_r.c_str()
|
||||
<< " is overriden with env UMTRX_PA_DCDC_R:"
|
||||
<< pa_dcdc_r_env << std::endl;
|
||||
pa_dcdc_r = pa_dcdc_r_env;
|
||||
}
|
||||
if (pa_dcdc_r.empty())
|
||||
set_pa_dcdc_r(0);
|
||||
else
|
||||
set_pa_dcdc_r(boost::lexical_cast<unsigned>(pa_dcdc_r));
|
||||
|
||||
_pa_en1 = (boost::lexical_cast<int>(_iface->mb_eeprom.get("pa_en1", "1")) == 1);
|
||||
_pa_en2 = (boost::lexical_cast<int>(_iface->mb_eeprom.get("pa_en2", "1")) == 1);
|
||||
|
||||
if (getenv("UMTRX_PA_EN1")) _pa_en1 = (boost::lexical_cast<int>(getenv("UMTRX_PA_EN1")) != 0);
|
||||
if (getenv("UMTRX_PA_EN2")) _pa_en2 = (boost::lexical_cast<int>(getenv("UMTRX_PA_EN2")) != 0);
|
||||
|
||||
std::string pa_low = _iface->mb_eeprom.get("pa_low", "");
|
||||
char* pa_low_env = getenv("UMTRX_PA_LOW");
|
||||
if (pa_low_env) {
|
||||
UHD_MSG(status) << "EEPROM value of pa_low:" << pa_low.c_str()
|
||||
<< " is overriden with env UMTRX_PA_LOW:"
|
||||
<< pa_low_env << std::endl;
|
||||
pa_low = pa_low_env;
|
||||
}
|
||||
if (pa_low.empty())
|
||||
_pa_nlow = false;
|
||||
else
|
||||
_pa_nlow = (boost::lexical_cast<int>(pa_low) == 0);
|
||||
|
||||
_tree->create<bool>(mb_path / "pa_en1")
|
||||
.subscribe(boost::bind(&umtrx_impl::set_enpa1, this, _1));
|
||||
_tree->create<bool>(mb_path / "pa_en2")
|
||||
.subscribe(boost::bind(&umtrx_impl::set_enpa2, this, _1));
|
||||
_tree->create<bool>(mb_path / "pa_nlow")
|
||||
.subscribe(boost::bind(&umtrx_impl::set_nlow, this, _1));
|
||||
|
||||
commit_pa_state();
|
||||
UHD_MSG(status) << "PA low=`" << pa_low.c_str()
|
||||
<< "` PA dcdc_r=`" << pa_dcdc_r.c_str()
|
||||
<< "`" << std::endl;
|
||||
}
|
||||
|
||||
void umtrx_impl::commit_pa_state()
|
||||
{
|
||||
if (_hw_rev >= UMTRX_VER_2_3_1)
|
||||
_iface->poke32(U2_REG_MISC_LMS_RES, LMS1_RESET | LMS2_RESET
|
||||
| PAREG_ENDCSYNC
|
||||
| ((_pa_nlow) ? PAREG_NLOW_PA : 0)
|
||||
| ((_pa_en1) ? PAREG_ENPA1 : 0)
|
||||
| ((_pa_en2) ? PAREG_ENPA2 : 0));
|
||||
}
|
||||
|
||||
void umtrx_impl::set_enpa1(bool en)
|
||||
{
|
||||
_pa_en1 = en; commit_pa_state();
|
||||
}
|
||||
|
||||
void umtrx_impl::set_enpa2(bool en)
|
||||
{
|
||||
_pa_en2 = en; commit_pa_state();
|
||||
}
|
||||
|
||||
void umtrx_impl::set_nlow(bool en)
|
||||
{
|
||||
_pa_nlow = en; commit_pa_state();
|
||||
}
|
||||
|
||||
void umtrx_impl::set_diversity(bool en, int chan)
|
||||
{
|
||||
// chan 0 has inversed switch polarity
|
||||
// chan 1 has straight switch polarity
|
||||
_iface->poke32(U2_REG_SR_ADDR(SR_DIVSW+chan), (en != (chan==1)) ? 0 : 1);
|
||||
}
|
||||
|
||||
const char* umtrx_impl::get_hw_rev() const
|
||||
{
|
||||
switch (_hw_rev) {
|
||||
case UMTRX_VER_2_0: return "2.0";
|
||||
case UMTRX_VER_2_1: return "2.1";
|
||||
case UMTRX_VER_2_2: return "2.2";
|
||||
case UMTRX_VER_2_3_0: return "2.3.0";
|
||||
case UMTRX_VER_2_3_1: return "2.3.1";
|
||||
default: return "[unknown]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#include "cores/rx_dsp_core_200.hpp"
|
||||
#include "cores/tx_dsp_core_200.hpp"
|
||||
#include "cores/time64_core_200.hpp"
|
||||
#include "ads1015_ctrl.hpp"
|
||||
#include "tmp102_ctrl.hpp"
|
||||
#include "power_amp.hpp"
|
||||
#include <uhd/usrp/mboard_eeprom.hpp>
|
||||
#include <uhd/property_tree.hpp>
|
||||
#include <uhd/device.hpp>
|
||||
@@ -35,6 +38,7 @@
|
||||
#include <uhd/utils/byteswap.hpp>
|
||||
#include <uhd/types/dict.hpp>
|
||||
#include <uhd/types/stream_cmd.hpp>
|
||||
#include <uhd/types/sensors.hpp>
|
||||
#include <uhd/types/clock_config.hpp>
|
||||
#include <uhd/usrp/dboard_eeprom.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
@@ -44,6 +48,8 @@
|
||||
#include <uhd/transport/udp_simple.hpp>
|
||||
#include <uhd/transport/udp_zero_copy.hpp>
|
||||
#include <uhd/transport/bounded_buffer.hpp>
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <uhd/types/ranges.hpp>
|
||||
#include <uhd/exception.hpp>
|
||||
#include <uhd/utils/static.hpp>
|
||||
@@ -53,6 +59,9 @@
|
||||
#include <uhd/usrp/subdev_spec.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <uhd/utils/tasks.hpp>
|
||||
|
||||
|
||||
// Halfthe size of USRP2 SRAM, because we split the same SRAM into buffers for two Tx channels instead of one.
|
||||
static const size_t UMTRX_SRAM_BYTES = size_t(1 << 19);
|
||||
@@ -76,6 +85,8 @@ static const boost::uint32_t UMTRX_DSP_TX1_SID = 3;
|
||||
//RX stream IDs -- random -- no relevance to FPGA config
|
||||
static const boost::uint32_t UMTRX_DSP_RX0_SID = 0x20;
|
||||
static const boost::uint32_t UMTRX_DSP_RX1_SID = 0x21;
|
||||
static const boost::uint32_t UMTRX_DSP_RX2_SID = 0x22;
|
||||
static const boost::uint32_t UMTRX_DSP_RX3_SID = 0x23;
|
||||
|
||||
//! load and store for umtrx mboard eeprom map
|
||||
void load_umtrx_eeprom(uhd::usrp::mboard_eeprom_t &mb_eeprom, uhd::i2c_iface &iface);
|
||||
@@ -99,6 +110,43 @@ public:
|
||||
boost::shared_ptr<async_md_type> _old_async_queue;
|
||||
|
||||
private:
|
||||
enum umtrx_hw_rev {
|
||||
UMTRX_VER_2_0,
|
||||
UMTRX_VER_2_1,
|
||||
UMTRX_VER_2_2,
|
||||
UMTRX_VER_2_3_0,
|
||||
UMTRX_VER_2_3_1
|
||||
};
|
||||
|
||||
// hardware revision
|
||||
umtrx_hw_rev _hw_rev;
|
||||
unsigned _pll_div;
|
||||
const char* get_hw_rev() const;
|
||||
|
||||
// Optimal VGA settings for GSM signal, according to our measurements.
|
||||
static const int UMTRX_VGA1_DEF;
|
||||
static const int UMTRX_VGA2_DEF;
|
||||
static const int UMTRX_VGA2_MIN;
|
||||
|
||||
// Conversion table for converting DCDC_R values to actual voltages.
|
||||
static const std::vector<double> _dcdc_val_to_volt;
|
||||
// Find a dcdc_r value to approximate requested Vout voltage
|
||||
static int volt_to_dcdc_r(double v);
|
||||
|
||||
ads1015_ctrl _sense_pwr;
|
||||
ads1015_ctrl _sense_dc;
|
||||
tmp102_ctrl _temp_side_a;
|
||||
tmp102_ctrl _temp_side_b;
|
||||
|
||||
//PA control
|
||||
bool _pa_nlow;
|
||||
bool _pa_en1;
|
||||
bool _pa_en2;
|
||||
uint8_t _pa_dcdc_r;
|
||||
double _pa_power_max_dBm; // Artifical PA output power limit, dBm
|
||||
|
||||
void set_pa_dcdc_r(uint8_t val);
|
||||
uint8_t get_pa_dcdc_r() const {return _pa_dcdc_r;}
|
||||
|
||||
//communication interfaces
|
||||
std::string _device_ip_addr;
|
||||
@@ -107,6 +155,8 @@ private:
|
||||
|
||||
//controls for perifs
|
||||
uhd::dict<std::string, lms6002d_ctrl::sptr> _lms_ctrl;
|
||||
uhd::dict<std::string, uhd::power_amp::sptr> _pa;
|
||||
uhd::dict<std::string, uhd::gain_range_t> _tx_power_range; // Tx output power range
|
||||
|
||||
//control for FPGA cores
|
||||
std::vector<rx_frontend_core_200::sptr> _rx_fes;
|
||||
@@ -130,12 +180,49 @@ private:
|
||||
void set_rx_fe_corrections(const std::string &mb, const std::string &board, const double);
|
||||
void set_tx_fe_corrections(const std::string &mb, const std::string &board, const double);
|
||||
void set_tcxo_dac(const umtrx_iface::sptr &, const uint16_t val);
|
||||
void detect_hw_rev(const uhd::fs_path &mb_path);
|
||||
void commit_pa_state();
|
||||
void set_enpa1(bool en);
|
||||
void set_enpa2(bool en);
|
||||
void set_nlow(bool en);
|
||||
void set_diversity(bool en, int chan);
|
||||
uhd::gain_range_t generate_tx_power_range(const std::string &which) const;
|
||||
uhd::gain_range_t generate_pa_power_range(const std::string &which) const;
|
||||
const uhd::gain_range_t &get_tx_power_range(const std::string &which) const;
|
||||
double set_tx_power(double power, const std::string &which);
|
||||
double set_pa_power(double power, const std::string &which);
|
||||
uint16_t get_tcxo_dac(const umtrx_iface::sptr &);
|
||||
uhd::transport::zero_copy_if::sptr make_xport(const size_t which, const uhd::device_addr_t &args);
|
||||
std::complex<double> get_dc_offset_correction(const std::string &which) const;
|
||||
void set_dc_offset_correction(const std::string &which, const std::complex<double> &corr);
|
||||
|
||||
static double dc_offset_int2double(uint8_t corr);
|
||||
static uint8_t dc_offset_double2int(double corr);
|
||||
|
||||
//temp sensors read values in degC
|
||||
uhd::sensor_value_t read_temp_c(const std::string &which);
|
||||
uhd::sensor_value_t read_pa_v(const std::string &which);
|
||||
uhd::sensor_value_t read_dc_v(const std::string &which);
|
||||
boost::recursive_mutex _i2c_mutex;
|
||||
|
||||
//status monitoring
|
||||
void status_monitor_start(const uhd::device_addr_t &device_addr);
|
||||
void status_monitor_stop(void);
|
||||
uhd::task::sptr _status_monitor_task;
|
||||
void status_monitor_handler(void);
|
||||
|
||||
//tcp query server
|
||||
uhd::task::sptr _server_query_task;
|
||||
void server_query_handler(void);
|
||||
boost::asio::io_service _server_query_io_service;
|
||||
boost::shared_ptr<boost::asio::ip::tcp::acceptor> _server_query_tcp_acceptor;
|
||||
void client_query_handle(boost::shared_ptr<boost::asio::ip::tcp::socket>);
|
||||
void client_query_handle1(const boost::property_tree::ptree &request, boost::property_tree::ptree &response);
|
||||
|
||||
//streaming
|
||||
std::vector<boost::weak_ptr<uhd::rx_streamer> > _rx_streamers;
|
||||
std::vector<boost::weak_ptr<uhd::tx_streamer> > _tx_streamers;
|
||||
boost::mutex _setupMutex;
|
||||
};
|
||||
|
||||
#endif /* INCLUDED_UMTRX_IMPL_HPP */
|
||||
|
||||
@@ -73,7 +73,6 @@ void umtrx_impl::update_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec)
|
||||
|
||||
void umtrx_impl::update_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec)
|
||||
{
|
||||
//sanity checking
|
||||
validate_subdev_spec(_tree, spec, "tx");
|
||||
boost::uint32_t tx_fe_sw = 0;
|
||||
for (size_t i = 0; i < spec.size(); i++)
|
||||
@@ -185,6 +184,7 @@ uhd::transport::zero_copy_if::sptr umtrx_impl::make_xport(const size_t which, co
|
||||
**********************************************************************/
|
||||
uhd::rx_streamer::sptr umtrx_impl::get_rx_stream(const uhd::stream_args_t &args_)
|
||||
{
|
||||
boost::mutex::scoped_lock l(_setupMutex);
|
||||
stream_args_t args = args_;
|
||||
|
||||
//setup defaults for unspecified values
|
||||
@@ -404,7 +404,12 @@ static void handle_tx_async_msgs(
|
||||
}
|
||||
|
||||
stop_flow_control();
|
||||
while (not xport->get_recv_buff()){};//flush after fc off
|
||||
//flush after fc off, max time of 1s
|
||||
size_t i = 0;
|
||||
while (not xport->get_recv_buff(0.01))
|
||||
{
|
||||
if (i++ > 100) break;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -412,6 +417,7 @@ static void handle_tx_async_msgs(
|
||||
**********************************************************************/
|
||||
uhd::tx_streamer::sptr umtrx_impl::get_tx_stream(const uhd::stream_args_t &args_)
|
||||
{
|
||||
boost::mutex::scoped_lock l(_setupMutex);
|
||||
stream_args_t args = args_;
|
||||
|
||||
//setup defaults for unspecified values
|
||||
|
||||
246
host/umtrx_monitor.cpp
Normal file
246
host/umtrx_monitor.cpp
Normal file
@@ -0,0 +1,246 @@
|
||||
//
|
||||
// Copyright 2015-2015 Fairwaves LLC
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "umtrx_impl.hpp"
|
||||
#include <uhd/utils/msg.hpp>
|
||||
#include <uhd/types/sensors.hpp>
|
||||
#include <uhd/types/ranges.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
using namespace uhd;
|
||||
using namespace uhd::usrp;
|
||||
namespace asio = boost::asio;
|
||||
|
||||
/*!
|
||||
* Querying sensors using the status monitor server.
|
||||
* Requests are encoded in JSON and end in a newline.
|
||||
* Responses are encoded in JSON and end in a newline.
|
||||
*
|
||||
* Start UmTRX driver with status_port set in args
|
||||
* ./some_application --args="status_port=12345"
|
||||
*
|
||||
* import json
|
||||
* import socket
|
||||
* s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
* s.connect(("localhost", 12345))
|
||||
* f = s.makefile() #gives us readline()
|
||||
*
|
||||
* #list branches in the property tree
|
||||
* s.send(json.dumps(dict(action='LIST', path='/mboards/0/sensors'))+'\n')
|
||||
* print json.loads(f.readline())
|
||||
* {u'result': [u'tempA']}
|
||||
*
|
||||
* #check if the specified path exists
|
||||
* s.send(json.dumps(dict(action='HAS', path='/mboards/0/sensors/tempA'))+'\n')
|
||||
* print json.loads(f.readline())
|
||||
* {u'result': u'true'}
|
||||
*
|
||||
* #get the value of a tree entry, types can be BOOL, INT, DOUBLE, SENSOR, RANGE
|
||||
* s.send(json.dumps(dict(action='GET', path='/mboards/0/sensors/tempA', type='SENSOR'))+'\n')
|
||||
* print json.loads(f.readline())
|
||||
* {u'result': {u'unit': u'C', u'name': u'TempA', u'value': u'61.625000'}}
|
||||
*
|
||||
* #set the value of a tree entry, types can be BOOL, INT, DOUBLE
|
||||
* s.send(json.dumps(dict(action='SET', path='/mboards/0/dboards/A/rx_frontends/0/freq/value', type='DOUBLE', value=1e9))+'\n')
|
||||
* print json.loads(f.readline())
|
||||
* {} #empty response means no error
|
||||
*/
|
||||
|
||||
void umtrx_impl::status_monitor_start(const uhd::device_addr_t &device_addr)
|
||||
{
|
||||
if (device_addr.has_key("status_port"))
|
||||
{
|
||||
UHD_MSG(status) << "Creating TCP monitor on port " << device_addr.get("status_port") << std::endl;
|
||||
_server_query_tcp_acceptor.reset(new asio::ip::tcp::acceptor(
|
||||
_server_query_io_service, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), device_addr.cast<int>("status_port", 0))));
|
||||
_server_query_task = task::make(boost::bind(&umtrx_impl::server_query_handler, this));
|
||||
}
|
||||
_status_monitor_task = task::make(boost::bind(&umtrx_impl::status_monitor_handler, this));
|
||||
}
|
||||
|
||||
void umtrx_impl::status_monitor_stop(void)
|
||||
{
|
||||
_status_monitor_task.reset();
|
||||
_server_query_task.reset();
|
||||
}
|
||||
|
||||
static bool wait_read_sockfd(const int sockfd, const size_t timeoutMs)
|
||||
{
|
||||
//setup timeval for timeout
|
||||
timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = timeoutMs*1000;
|
||||
|
||||
//setup rset for timeout
|
||||
fd_set rset;
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(sockfd, &rset);
|
||||
|
||||
//call select with timeout on receive socket
|
||||
return ::select(sockfd+1, &rset, NULL, NULL, &tv) > 0;
|
||||
}
|
||||
|
||||
void umtrx_impl::status_monitor_handler(void)
|
||||
{
|
||||
//TODO read the sensors and react...
|
||||
//read_dc_v, etc...
|
||||
//UHD_MSG(status) << this->read_temp_c("A").to_pp_string() << std::endl;
|
||||
|
||||
//TODO shutdown frontend when temp > thresh
|
||||
//ctrl->set_rx_enabled(false);
|
||||
//ctrl->set_tx_enabled(false);
|
||||
|
||||
//this sleep defines the polling time between status checks
|
||||
//when the handler completes, it will be called again asap
|
||||
//if the task is canceled, this sleep in interrupted for exit
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(1500));
|
||||
}
|
||||
|
||||
void umtrx_impl::server_query_handler(void)
|
||||
{
|
||||
//accept the client socket (timeout is 100 ms, task is called again)
|
||||
if (not wait_read_sockfd(_server_query_tcp_acceptor->native(), 100)) return;
|
||||
boost::shared_ptr<asio::ip::tcp::socket> socket(new asio::ip::tcp::socket(_server_query_io_service));
|
||||
_server_query_tcp_acceptor->accept(*socket);
|
||||
|
||||
//create a new thread to handle the client
|
||||
boost::thread handler(boost::bind(&umtrx_impl::client_query_handle, this, socket));
|
||||
handler.detach();
|
||||
}
|
||||
|
||||
void umtrx_impl::client_query_handle(boost::shared_ptr<boost::asio::ip::tcp::socket> socket)
|
||||
{
|
||||
while (not boost::this_thread::interruption_requested())
|
||||
{
|
||||
boost::property_tree::ptree request, response;
|
||||
|
||||
//receive the request in JSON markup
|
||||
boost::asio::streambuf requestBuff;
|
||||
try
|
||||
{
|
||||
boost::asio::read_until(*socket, requestBuff, "\n");
|
||||
std::istream is(&requestBuff);
|
||||
boost::property_tree::read_json(is, request);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
if (requestBuff.size() == 0) return; //client ended
|
||||
response.put("error", "request parser error: " + std::string(ex.what()));
|
||||
}
|
||||
|
||||
//handle the request
|
||||
try
|
||||
{
|
||||
this->client_query_handle1(request, response);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
response.put("error", "failed to handle request: " + std::string(ex.what()));
|
||||
}
|
||||
|
||||
//send the response
|
||||
boost::asio::streambuf responseBuff;
|
||||
std::ostream os(&responseBuff);
|
||||
try
|
||||
{
|
||||
boost::property_tree::write_json(os, response, false/*not pretty required*/);
|
||||
boost::asio::write(*socket, responseBuff);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
UHD_MSG(error) << "client_query_handle send response failed, exit client thread: " << ex.what() << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void umtrx_impl::client_query_handle1(const boost::property_tree::ptree &request, boost::property_tree::ptree &response)
|
||||
{
|
||||
const std::string action = request.get("action", "");
|
||||
const std::string path = request.get("path", "");
|
||||
if (response.count("error") != 0)
|
||||
{
|
||||
//already in error
|
||||
}
|
||||
else if (path.empty())
|
||||
{
|
||||
response.put("error", "path field not specified");
|
||||
}
|
||||
else if (action.empty())
|
||||
{
|
||||
response.put("error", "action field not specified: GET, SET, HAS, LIST");
|
||||
}
|
||||
else if (action == "GET")
|
||||
{
|
||||
const std::string type = request.get("type", "");
|
||||
if (type.empty()) response.put("error", "type field not specified: BOOL, INT, DOUBLE, SENSOR, RANGE");
|
||||
else if (type == "BOOL") response.put("result", _tree->access<bool>(path).get());
|
||||
else if (type == "INT") response.put("result", _tree->access<int>(path).get());
|
||||
else if (type == "DOUBLE") response.put("result", _tree->access<double>(path).get());
|
||||
else if (type == "SENSOR")
|
||||
{
|
||||
boost::property_tree::ptree result;
|
||||
const sensor_value_t sensor = _tree->access<sensor_value_t>(path).get();
|
||||
result.put("name", sensor.name);
|
||||
result.put("value", sensor.value);
|
||||
result.put("unit", sensor.unit);
|
||||
response.add_child("result", result);
|
||||
}
|
||||
else if (type == "RANGE")
|
||||
{
|
||||
boost::property_tree::ptree result;
|
||||
BOOST_FOREACH(const range_t &range, _tree->access<meta_range_t>(path).get())
|
||||
{
|
||||
boost::property_tree::ptree rangeData;
|
||||
rangeData.put("start", range.start());
|
||||
rangeData.put("stop", range.stop());
|
||||
rangeData.put("step", range.step());
|
||||
result.push_back(std::make_pair("", rangeData));
|
||||
}
|
||||
response.add_child("result", result);
|
||||
}
|
||||
else response.put("error", "unknown type: " + type);
|
||||
}
|
||||
else if (action == "SET")
|
||||
{
|
||||
const std::string type = request.get("type", "");
|
||||
if (type.empty()) response.put("error", "type field not specified: BOOL, INT, DOUBLE");
|
||||
else if (type == "BOOL") _tree->access<bool>(path).set(request.get<bool>("value"));
|
||||
else if (type == "INT") _tree->access<int>(path).set(request.get<int>("value"));
|
||||
else if (type == "DOUBLE") _tree->access<double>(path).set(request.get<double>("value"));
|
||||
else response.put("error", "unknown type: " + type);
|
||||
}
|
||||
else if (action == "HAS")
|
||||
{
|
||||
response.put("result", _tree->exists(path));
|
||||
}
|
||||
else if (action == "LIST")
|
||||
{
|
||||
boost::property_tree::ptree result;
|
||||
BOOST_FOREACH(const std::string &branchName, _tree->list(path))
|
||||
{
|
||||
boost::property_tree::ptree branchData;
|
||||
branchData.put("", branchName);
|
||||
result.push_back(std::make_pair("", branchData));
|
||||
}
|
||||
response.add_child("result", result);
|
||||
}
|
||||
else
|
||||
{
|
||||
response.put("error", "unknown action: " + action);
|
||||
}
|
||||
}
|
||||
@@ -39,20 +39,20 @@
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Setting register offsets
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
localparam SR_MISC = 0; // 7 regs
|
||||
localparam SR_MISC = 0; // 9 regs
|
||||
localparam SR_TIME64 = 10; // 6
|
||||
localparam SR_BUF_POOL = 16; // 4
|
||||
|
||||
localparam SR_RX_FRONT0 = 20; // 5
|
||||
localparam SR_RX_FRONT1 = 25; // 5
|
||||
localparam SR_RX_CTRL0 = 32; // 9
|
||||
localparam SR_RX_DSP0 = 48; // 7
|
||||
localparam SR_RX_CTRL1 = 80; // 9
|
||||
localparam SR_RX_DSP1 = 96; // 7
|
||||
localparam SR_RX_CTRL2 = 66; // 9
|
||||
localparam SR_RX_DSP2 = 76; // 7
|
||||
localparam SR_RX_CTRL3 = 83; // 9
|
||||
localparam SR_RX_DSP3 = 93; // 7
|
||||
localparam SR_RX_CTRL0 = 30; // 9
|
||||
localparam SR_RX_DSP0 = 40; // 7
|
||||
localparam SR_RX_CTRL1 = 50; // 9
|
||||
localparam SR_RX_DSP1 = 60; // 7
|
||||
localparam SR_RX_CTRL2 = 70; // 9
|
||||
localparam SR_RX_DSP2 = 80; // 7
|
||||
localparam SR_RX_CTRL3 = 90; // 9
|
||||
localparam SR_RX_DSP3 = 100; // 7
|
||||
|
||||
localparam SR_TX_FRONT0 = 110; // ?
|
||||
localparam SR_TX_CTRL0 = 126; // 6
|
||||
@@ -94,10 +94,9 @@ localparam SR_SPI_CORE = 185; // 3
|
||||
// Readback regs
|
||||
////////////////////////////////////////////////
|
||||
#define U2_REG_SPI_RB READBACK_BASE + 4*0
|
||||
#define U2_REG_ADC0 READBACK_BASE + 4*6
|
||||
#define U2_REG_ADC1 READBACK_BASE + 4*7
|
||||
#define U2_REG_NUM_DDC READBACK_BASE + 4*1
|
||||
#define U2_REG_NUM_DUC READBACK_BASE + 4*2
|
||||
#define U2_REG_STATUS READBACK_BASE + 4*8
|
||||
#define U2_REG_GPIO_RB READBACK_BASE + 4*9
|
||||
#define U2_REG_TIME64_HI_RB_IMM READBACK_BASE + 4*10
|
||||
#define U2_REG_TIME64_LO_RB_IMM READBACK_BASE + 4*11
|
||||
#define U2_REG_COMPAT_NUM_RB READBACK_BASE + 4*12
|
||||
@@ -124,4 +123,10 @@ localparam SR_SPI_CORE = 185; // 3
|
||||
#define LMS1_RESET (1<<0)
|
||||
#define LMS2_RESET (1<<1)
|
||||
|
||||
// Defined for the U2_REG_MISC_LMS_RES register
|
||||
#define PAREG_NLOW_PA (1<<2)
|
||||
#define PAREG_ENPA1 (1<<3)
|
||||
#define PAREG_ENPA2 (1<<4)
|
||||
#define PAREG_ENDCSYNC (1<<5)
|
||||
|
||||
#endif
|
||||
|
||||
1
host/umtrx_version.in.hpp
Normal file
1
host/umtrx_version.in.hpp
Normal file
@@ -0,0 +1 @@
|
||||
#define UMTRX_VERSION "@UMTRX_VERSION@"
|
||||
@@ -32,7 +32,7 @@ extern "C" {
|
||||
//fpga and firmware compatibility numbers
|
||||
#define USRP2_FPGA_COMPAT_NUM 9
|
||||
#define USRP2_FW_COMPAT_NUM 12
|
||||
#define USRP2_FW_VER_MINOR 0
|
||||
#define USRP2_FW_VER_MINOR 2
|
||||
|
||||
//used to differentiate control packets over data port
|
||||
#define USRP2_INVALID_VRT_HEADER 0
|
||||
@@ -55,6 +55,7 @@ typedef struct{
|
||||
#define U2_FW_REG_LOCK_TIME 0
|
||||
#define U2_FW_REG_LOCK_GPID 1
|
||||
#define U2_FW_REG_VER_MINOR 7
|
||||
#define U2_FW_REG_GIT_HASH 6
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// I2C addresses
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
########################################################################
|
||||
INSTALL(PROGRAMS
|
||||
umtrx_net_burner
|
||||
umtrx_nmea
|
||||
umtrx_gps_coord
|
||||
umtrx_auto_calibration
|
||||
umtrx_firmware
|
||||
DESTINATION bin
|
||||
)
|
||||
|
||||
@@ -10,6 +14,19 @@ add_executable(umtrx_test_chains umtrx_test_chains.cpp)
|
||||
target_link_libraries(umtrx_test_chains ${UMTRX_LIBRARIES})
|
||||
install(TARGETS umtrx_test_chains DESTINATION bin)
|
||||
|
||||
add_executable(umtrx_test_gains umtrx_test_gains.cpp)
|
||||
target_link_libraries(umtrx_test_gains ${UMTRX_LIBRARIES})
|
||||
install(TARGETS umtrx_test_gains DESTINATION bin)
|
||||
|
||||
add_executable(umtrx_cal_tx_dc_offset umtrx_cal_tx_dc_offset.cpp)
|
||||
target_link_libraries(umtrx_cal_tx_dc_offset ${UMTRX_LIBRARIES})
|
||||
install(TARGETS umtrx_cal_tx_dc_offset DESTINATION bin)
|
||||
|
||||
add_executable(umtrx_cal_tx_iq_balance umtrx_cal_tx_iq_balance.cpp)
|
||||
target_link_libraries(umtrx_cal_tx_iq_balance ${UMTRX_LIBRARIES})
|
||||
install(TARGETS umtrx_cal_tx_iq_balance DESTINATION bin)
|
||||
|
||||
add_executable(umtrx_pa_ctrl umtrx_pa_ctrl.cpp)
|
||||
target_link_libraries(umtrx_pa_ctrl ${UMTRX_LIBRARIES})
|
||||
install(TARGETS umtrx_pa_ctrl DESTINATION bin)
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ def plot_csv(file_path):
|
||||
if not i: continue #skip titles
|
||||
tx_lo, icor, qcor, meadured, delta = row
|
||||
tx_lo = float(tx_lo)/1e9
|
||||
icor = int(icor)
|
||||
qcor = int(qcor)
|
||||
icor = float(icor)
|
||||
qcor = float(qcor)
|
||||
freq_vals.append(tx_lo)
|
||||
dc_i_vals.append(icor)
|
||||
dc_q_vals.append(qcor)
|
||||
@@ -34,7 +34,7 @@ def plot_csv(file_path):
|
||||
plt.figure(1)
|
||||
plt.subplot(311)
|
||||
plt.plot(freq_vals, dc_i_vals, freq_vals, dc_q_vals,)
|
||||
plt.ylim(0, 250)
|
||||
#plt.ylim(0, 250)
|
||||
plt.title("Freq (GHz) vs raw IQ corrections")
|
||||
#plt.xlabel('Freq (GHz)')
|
||||
plt.grid(True)
|
||||
@@ -45,7 +45,7 @@ def plot_csv(file_path):
|
||||
dc_i_std = [np.std(dc_i_vals_per_freq[f]) for f in freqs]
|
||||
dc_q_std = [np.std(dc_q_vals_per_freq[f]) for f in freqs]
|
||||
plt.plot(freqs, dc_i_std, freqs, dc_q_std)
|
||||
plt.ylim(0, 150)
|
||||
#plt.ylim(0, 150)
|
||||
plt.title("Freq (GHz) vs stddev IQ corrections")
|
||||
#plt.xlabel('Freq (GHz)')
|
||||
plt.grid(True)
|
||||
@@ -70,7 +70,7 @@ def plot_csv(file_path):
|
||||
dc_i_avg = [np.mean(dc_i_vals_per_freq[f]) for f in freqs]
|
||||
dc_q_avg = [np.mean(dc_q_vals_per_freq[f]) for f in freqs]
|
||||
plt.plot(freqs, dc_i_avg, freqs, dc_q_avg)
|
||||
plt.ylim(0, 250)
|
||||
#plt.ylim(0, 250)
|
||||
plt.title("Freq (GHz) vs averaged IQ corrections")
|
||||
#plt.xlabel('Freq (GHz)')
|
||||
plt.grid(True)
|
||||
|
||||
134
host/utils/umtrx_auto_calibration
Executable file
134
host/utils/umtrx_auto_calibration
Executable file
@@ -0,0 +1,134 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$#" -lt "1" ] ; then
|
||||
echo "Automatic calibration of an UmTRX for a set of given presets (bands)."
|
||||
echo
|
||||
echo "Usage:"
|
||||
echo " umtrx_cal <preset> [<preset>] [<preset>] ..."
|
||||
echo
|
||||
echo " preset - GSM850, EGSM900 (same as GSM900), GSM1800 (same as DCS1800), GSM1900 (same as PCS1900)."
|
||||
echo
|
||||
echo "Calibrations to be performed:"
|
||||
echo " - Tx DC offset calibration"
|
||||
echo " - Tx IQ balance calibration"
|
||||
echo
|
||||
echo "The result of the calibration is stored in the DIR/.uhd/cal/ directory. DIR is one of the \$APPDATA, \$HOME and /tmp,"
|
||||
echo "whichever is defined. Make sure you run calibration from the same user as the one who runs applications or define"
|
||||
echo "\$APPDATA or \$HOME appropriately. Calibration files will be loaded by the application automatically on startup."
|
||||
echo "Old calibration files are renamed when you run a calibration to avoid overwriting."
|
||||
echo
|
||||
echo "Calibration is permanent and only depends on temperature. If the temperature of the system is stable, you need to"
|
||||
echo "run the calibration only once."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
presets=$*
|
||||
|
||||
sides="A B"
|
||||
uhd_args="--args=fifo_ctrl_window=0"
|
||||
report=""
|
||||
|
||||
run_cal() {
|
||||
what=$1 ; shift
|
||||
freq_start=$1 ; shift
|
||||
freq_stop=$1 ; shift
|
||||
other_args=$*
|
||||
|
||||
freq_step=$(python -c "print $freq_stop - $freq_start if $freq_stop != $freq_start else 1e3")
|
||||
|
||||
if [ "$what" = "dc" ] ; then
|
||||
cmd="umtrx_cal_tx_dc_offset"
|
||||
elif [ "$what" = "iq" ] ; then
|
||||
cmd="umtrx_cal_tx_iq_balance"
|
||||
else
|
||||
echo "Unknown calibration type \"$what\""
|
||||
return 1
|
||||
fi
|
||||
|
||||
for side in $sides ; do
|
||||
|
||||
echo
|
||||
echo "------------------------------------------------------------------"
|
||||
echo " Calibrating $what from $freq_start to $freq_stop for side $side"
|
||||
echo "------------------------------------------------------------------"
|
||||
echo
|
||||
|
||||
res=255
|
||||
i=0
|
||||
while [ $i -lt 10 -a $res -ne 0 ] ; do
|
||||
i=$(expr $i + 1)
|
||||
cmd_full="$cmd $uhd_args --freq_start $freq_start --freq_stop $freq_stop --freq_step $freq_step --which $side $other_args"
|
||||
echo $cmd_full
|
||||
$cmd_full
|
||||
res=$(echo $?)
|
||||
done
|
||||
|
||||
text_res="Calibration type $what side $side from $freq_start to $freq_stop:"
|
||||
if [ $res -ne 0 ] ; then
|
||||
text_res="$text_res FAIL"
|
||||
else
|
||||
text_res="$text_res SUCCESS"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "$text_res"
|
||||
echo
|
||||
|
||||
report="$report$text_res\n"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
run_preset() {
|
||||
preset=$1
|
||||
|
||||
echo
|
||||
echo "===================================================================="
|
||||
echo " Running preset $preset"
|
||||
echo "===================================================================="
|
||||
echo
|
||||
|
||||
case $preset in
|
||||
GSM850)
|
||||
run_cal dc 869e6 894e6
|
||||
# The band completely falls into the 810-930 VCO range
|
||||
run_cal iq 869e6 894e6
|
||||
;;
|
||||
|
||||
GSM900|EGSM900)
|
||||
run_cal dc 925e6 960e6
|
||||
# The band spans VCO ranges 810-930 and 930-11425
|
||||
run_cal iq 925e6 930e6
|
||||
run_cal iq 930.001e6 960e6 --append
|
||||
;;
|
||||
|
||||
GSM1800|DCS1800)
|
||||
run_cal dc 1805e6 1880e6
|
||||
# The band spans VCO ranges 1620-1860 and 1860-2285
|
||||
run_cal iq 1805e6 1860e6
|
||||
run_cal iq 1860.001e6 1880e6 --append
|
||||
;;
|
||||
|
||||
GSM1900|PCS1900)
|
||||
run_cal dc 1930e6 1990e6
|
||||
# The band completely falls into the 1860-2285 VCO range
|
||||
run_cal iq 1930e6 1990e6
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown preset"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
for preset in $presets ; do
|
||||
run_preset $preset
|
||||
done
|
||||
|
||||
echo
|
||||
echo "===================================================================="
|
||||
echo " Result"
|
||||
echo "===================================================================="
|
||||
echo
|
||||
echo "$report"
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// Copyright 2010 Ettus Research LLC
|
||||
// Copyright 2012 Fairwaves LLC
|
||||
// Copyright 2012-1015 Fairwaves, Inc
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -17,16 +17,10 @@
|
||||
//
|
||||
|
||||
#include "usrp_cal_utils.hpp"
|
||||
#include <uhd/utils/thread_priority.hpp>
|
||||
#include <uhd/utils/safe_main.hpp>
|
||||
#include <uhd/utils/paths.hpp>
|
||||
#include <uhd/utils/algorithm.hpp>
|
||||
#include <uhd/usrp/multi_usrp.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/math/special_functions/round.hpp>
|
||||
#include <boost/random.hpp>
|
||||
#include <iostream>
|
||||
#include <complex>
|
||||
#include <cmath>
|
||||
@@ -35,77 +29,271 @@
|
||||
namespace po = boost::program_options;
|
||||
|
||||
/***********************************************************************
|
||||
* Transmit thread
|
||||
* Calibration utility class
|
||||
**********************************************************************/
|
||||
static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, const double tx_wave_freq, const double tx_wave_ampl){
|
||||
uhd::set_thread_priority_safe();
|
||||
class dc_cal_t {
|
||||
public:
|
||||
dc_cal_t(uhd::property<uint8_t> &dc_i_prop, uhd::property<uint8_t> &dc_q_prop,
|
||||
uhd::rx_streamer::sptr rx_stream,
|
||||
const size_t nsamps,
|
||||
double bb_dc_freq,
|
||||
double rx_rate,
|
||||
int verbose,
|
||||
bool debug_raw_data,
|
||||
int init_dc_i=128, int init_dc_q=128);
|
||||
|
||||
//create a transmit streamer
|
||||
uhd::stream_args_t stream_args("fc32"); //complex floats
|
||||
uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args);
|
||||
double init();
|
||||
void run_q(int dc_q);
|
||||
void run_i(int dc_i);
|
||||
void run_iq(int dc_i, int dc_q);
|
||||
|
||||
//setup variables and allocate buffer
|
||||
uhd::tx_metadata_t md;
|
||||
md.has_time_spec = false;
|
||||
std::vector<samp_type> buff(tx_stream->get_max_num_samps()*10);
|
||||
void set_dc_i(double i) {prop_set_check(_dc_i_prop, i);}
|
||||
void set_dc_q(double q) {prop_set_check(_dc_q_prop, q);}
|
||||
void set_dc_i_best() {set_dc_i(_best_dc_i);}
|
||||
void set_dc_q_best() {set_dc_q(_best_dc_q);}
|
||||
|
||||
//values for the wave table lookup
|
||||
size_t index = 0;
|
||||
const double tx_rate = usrp->get_tx_rate();
|
||||
const size_t step = boost::math::iround(wave_table_len * tx_wave_freq/tx_rate);
|
||||
wave_table table(tx_wave_ampl);
|
||||
double get_lowest_offset() const {return _lowest_offset;}
|
||||
int get_best_dc_i() const {return _best_dc_i;}
|
||||
int get_best_dc_q() const {return _best_dc_q;}
|
||||
|
||||
//fill buff and send until interrupted
|
||||
while (not boost::this_thread::interruption_requested()){
|
||||
for (size_t i = 0; i < buff.size(); i++){
|
||||
buff[i] = table(index += step);
|
||||
buff[i] = samp_type(0, 0); //using no-power transmit to cal with
|
||||
protected:
|
||||
double _lowest_offset;
|
||||
int _best_dc_i;
|
||||
int _best_dc_q;
|
||||
uhd::property<uint8_t> &_dc_i_prop;
|
||||
uhd::property<uint8_t> &_dc_q_prop;
|
||||
|
||||
uhd::rx_streamer::sptr _rx_stream;
|
||||
std::vector<samp_type> _buff;
|
||||
const size_t _nsamps;
|
||||
double _bb_dc_freq;
|
||||
double _rx_rate;
|
||||
int _verbose;
|
||||
bool _debug_raw_data;
|
||||
|
||||
void prop_set_check(uhd::property<uint8_t> &prop, uint8_t val);
|
||||
|
||||
double get_dbrms();
|
||||
bool run_x();
|
||||
};
|
||||
|
||||
dc_cal_t::dc_cal_t(uhd::property<uint8_t> &dc_i_prop, uhd::property<uint8_t> &dc_q_prop,
|
||||
uhd::rx_streamer::sptr rx_stream,
|
||||
const size_t nsamps,
|
||||
double bb_dc_freq,
|
||||
double rx_rate,
|
||||
int verbose,
|
||||
bool debug_raw_data,
|
||||
int init_dc_i,
|
||||
int init_dc_q)
|
||||
: _best_dc_i(init_dc_i), _best_dc_q(init_dc_q)
|
||||
, _dc_i_prop(dc_i_prop), _dc_q_prop(dc_q_prop)
|
||||
, _rx_stream(rx_stream)
|
||||
, _nsamps(nsamps)
|
||||
, _bb_dc_freq(bb_dc_freq)
|
||||
, _rx_rate(rx_rate)
|
||||
, _verbose(verbose)
|
||||
, _debug_raw_data(debug_raw_data)
|
||||
{
|
||||
}
|
||||
|
||||
double dc_cal_t::init()
|
||||
{
|
||||
set_dc_i_best();
|
||||
set_dc_q_best();
|
||||
|
||||
//get the DC offset tone size
|
||||
_lowest_offset = get_dbrms();
|
||||
|
||||
if (_verbose) printf("initial_dc_dbrms = %2.0f dB\n", _lowest_offset);
|
||||
if (_debug_raw_data) write_samples_to_file(_buff, "initial_samples.dat");
|
||||
|
||||
return _lowest_offset;
|
||||
}
|
||||
|
||||
void dc_cal_t::run_q(int dc_q)
|
||||
{
|
||||
if (_verbose) printf(" dc_q = %d", dc_q);
|
||||
set_dc_q(dc_q);
|
||||
if (run_x())
|
||||
_best_dc_q = dc_q;
|
||||
}
|
||||
|
||||
void dc_cal_t::run_i(int dc_i)
|
||||
{
|
||||
if (_verbose) printf(" dc_i = %d", dc_i);
|
||||
set_dc_i(dc_i);
|
||||
if (run_x())
|
||||
_best_dc_i = dc_i;
|
||||
}
|
||||
|
||||
void dc_cal_t::run_iq(int dc_i, int dc_q)
|
||||
{
|
||||
if (_verbose) printf(" dc_i = %d dc_q = %d", dc_i, dc_q);
|
||||
set_dc_i(dc_i);
|
||||
set_dc_q(dc_q);
|
||||
if (run_x()) {
|
||||
_best_dc_i = dc_i;
|
||||
_best_dc_q = dc_q;
|
||||
}
|
||||
}
|
||||
|
||||
void dc_cal_t::prop_set_check(uhd::property<uint8_t> &prop, uint8_t val)
|
||||
{
|
||||
prop.set(val);
|
||||
uint8_t val_read = prop.get();
|
||||
if (val_read != val)
|
||||
throw std::runtime_error(
|
||||
str(boost::format("Calibration property sets incorrectly. Requested %d, read back %d")
|
||||
% int(val) % int(val_read)));
|
||||
}
|
||||
|
||||
double dc_cal_t::get_dbrms()
|
||||
{
|
||||
//receive some samples
|
||||
capture_samples(_rx_stream, _buff, _nsamps);
|
||||
//calculate dB rms
|
||||
return compute_tone_dbrms(_buff, _bb_dc_freq/_rx_rate);
|
||||
}
|
||||
|
||||
bool dc_cal_t::run_x()
|
||||
{
|
||||
bool better = false;
|
||||
|
||||
//get the DC offset tone size
|
||||
const double dc_dbrms = get_dbrms();
|
||||
if (_verbose) printf(" dc_dbrms = %2.0f dB", dc_dbrms);
|
||||
|
||||
if (dc_dbrms < _lowest_offset){
|
||||
_lowest_offset = dc_dbrms;
|
||||
better = true;
|
||||
if (_verbose) printf(" *");
|
||||
if (_debug_raw_data) write_samples_to_file(_buff, "best_samples.dat");
|
||||
}
|
||||
if (_verbose) printf("\n");
|
||||
|
||||
return better;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Calibration method: Downhill
|
||||
**********************************************************************/
|
||||
static result_t calibrate_downhill(dc_cal_t &dc_cal,
|
||||
double tx_lo,
|
||||
int verbose)
|
||||
{
|
||||
//bounds and results from searching
|
||||
int dc_i_start, dc_i_stop, dc_i_step;
|
||||
int dc_q_start, dc_q_stop, dc_q_step;
|
||||
|
||||
//capture initial uncorrected value
|
||||
const double initial_dc_dbrms = dc_cal.init();
|
||||
|
||||
for (size_t i = 0; i < 6; i++)
|
||||
{
|
||||
if (verbose) printf(" iteration %ld best_i = %d best_q = %d\n", i, dc_cal.get_best_dc_i(), dc_cal.get_best_dc_q());
|
||||
|
||||
switch (i) {
|
||||
case 0:
|
||||
dc_i_start = 0;
|
||||
dc_i_stop = 256;
|
||||
dc_q_start = 0;
|
||||
dc_q_stop = 256;
|
||||
dc_i_step = 10;
|
||||
dc_q_step = 10;
|
||||
break;
|
||||
case 1:
|
||||
dc_i_start = dc_cal.get_best_dc_i() - 15;
|
||||
dc_i_stop = dc_cal.get_best_dc_i() + 15;
|
||||
dc_q_start = dc_cal.get_best_dc_q() - 15;
|
||||
dc_q_stop = dc_cal.get_best_dc_q() + 15;
|
||||
dc_i_step = 1;
|
||||
dc_q_step = 1;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
dc_i_start = dc_cal.get_best_dc_i() - 3;
|
||||
dc_i_stop = dc_cal.get_best_dc_i() + 3;
|
||||
dc_q_start = dc_cal.get_best_dc_q() - 3;
|
||||
dc_q_stop = dc_cal.get_best_dc_q() + 3;
|
||||
dc_i_step = 1;
|
||||
dc_q_step = 1;
|
||||
break;
|
||||
default:
|
||||
dc_i_start = dc_cal.get_best_dc_i() - 1;
|
||||
dc_i_stop = dc_cal.get_best_dc_i() + 1;
|
||||
dc_q_start = dc_cal.get_best_dc_q() - 1;
|
||||
dc_q_stop = dc_cal.get_best_dc_q() + 1;
|
||||
dc_i_step = 1;
|
||||
dc_q_step = 1;
|
||||
break;
|
||||
};
|
||||
|
||||
if (i <= 2) {
|
||||
// Itereate through I and Q sequentially
|
||||
|
||||
if (verbose) printf(" I in [%d; %d] step %d Q = %d\n",
|
||||
dc_i_start, dc_i_stop, dc_i_step, dc_cal.get_best_dc_q());
|
||||
dc_cal.set_dc_q_best();
|
||||
for (int dc_i = dc_i_start; dc_i <= dc_i_stop; dc_i += dc_i_step){
|
||||
dc_cal.run_i(dc_i);
|
||||
}
|
||||
|
||||
if (verbose) printf(" I = %d Q in [%d; %d] step %d\n",
|
||||
dc_cal.get_best_dc_i(), dc_q_start, dc_q_stop, dc_q_step);
|
||||
dc_cal.set_dc_i_best();
|
||||
for (int dc_q = dc_q_start; dc_q <= dc_q_stop; dc_q += dc_q_step){
|
||||
dc_cal.run_q(dc_q);
|
||||
}
|
||||
} else {
|
||||
// Itereate through all combinations of I and Q
|
||||
|
||||
if (verbose) printf(" I in [%d; %d] step %d Q in [%d; %d] step %d\n",
|
||||
dc_i_start, dc_i_stop, dc_i_step,
|
||||
dc_q_start, dc_q_stop, dc_q_step);
|
||||
for (int dc_i = dc_i_start; dc_i <= dc_i_stop; dc_i += dc_i_step) {
|
||||
for (int dc_q = dc_q_start; dc_q <= dc_q_stop; dc_q += dc_q_step) {
|
||||
dc_cal.run_iq(dc_i, dc_q);
|
||||
}
|
||||
}
|
||||
}
|
||||
tx_stream->send(&buff.front(), buff.size(), md);
|
||||
|
||||
}
|
||||
|
||||
//send a mini EOB packet
|
||||
md.end_of_burst = true;
|
||||
tx_stream->send("", 0, md);
|
||||
}
|
||||
// Calibration result
|
||||
result_t result;
|
||||
result.freq = tx_lo;
|
||||
result.real_corr = dc_cal.get_best_dc_i();
|
||||
result.imag_corr = dc_cal.get_best_dc_q();
|
||||
result.best = dc_cal.get_lowest_offset();
|
||||
result.delta = initial_dc_dbrms - result.best;
|
||||
|
||||
/***********************************************************************
|
||||
* Tune RX and TX routine
|
||||
**********************************************************************/
|
||||
static double tune_rx_and_tx(uhd::usrp::multi_usrp::sptr usrp, const double tx_lo_freq, const double rx_offset){
|
||||
//tune the transmitter with no cordic
|
||||
uhd::tune_request_t tx_tune_req(tx_lo_freq);
|
||||
tx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL;
|
||||
tx_tune_req.dsp_freq = 0;
|
||||
usrp->set_tx_freq(tx_tune_req);
|
||||
// Output to console
|
||||
std::cout
|
||||
<< result.freq/1e6 << " MHz "
|
||||
<< "I/Q = " << result.real_corr << "/" << result.imag_corr << " "
|
||||
<< "(" << dc_offset_int2double(result.real_corr) << "/"
|
||||
<< dc_offset_int2double(result.imag_corr) << ") "
|
||||
<< "leakage = " << result.best << " dB, "
|
||||
<< "improvement = " << result.delta << " dB\n"
|
||||
<< std::flush
|
||||
;
|
||||
|
||||
//tune the receiver
|
||||
usrp->set_rx_freq(uhd::tune_request_t(usrp->get_tx_freq(), rx_offset));
|
||||
|
||||
boost::this_thread::sleep_for(boost::chrono::milliseconds(10));
|
||||
return usrp->get_tx_freq();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* random uniform int
|
||||
**********************************************************************/
|
||||
static int uniform_rand(const int low, const int high)
|
||||
{
|
||||
static boost::random::mt19937 rng;
|
||||
boost::random::uniform_int_distribution<> dist(low, high);
|
||||
return dist(rng);
|
||||
return result;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Main
|
||||
**********************************************************************/
|
||||
int UHD_SAFE_MAIN(int argc, char *argv[]){
|
||||
std::string args;
|
||||
std::string args, which, serial;
|
||||
int verbose;
|
||||
int vga1_gain, vga2_gain, rx_gain;
|
||||
double tx_wave_freq, tx_wave_ampl, rx_offset;
|
||||
double freq_start, freq_stop, freq_step;
|
||||
size_t nsamps;
|
||||
size_t ntrials;
|
||||
std::string which;
|
||||
int single_test_i, single_test_q;
|
||||
|
||||
po::options_description desc("Allowed options");
|
||||
desc.add_options()
|
||||
@@ -113,15 +301,22 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
|
||||
("verbose", "enable some verbose")
|
||||
("debug_raw_data", "save raw captured signals to files")
|
||||
("args", po::value<std::string>(&args)->default_value(""), "device address args [default = \"\"]")
|
||||
("which", po::value<std::string>(&which)->default_value("A"), "Which chain A or B?")
|
||||
("vga1", po::value<int>(&vga1_gain)->default_value(-20), "LMS6002D Tx VGA1 gain [-35 to -4]")
|
||||
("vga2", po::value<int>(&vga2_gain)->default_value(22), "LMS6002D Tx VGA2 gain [0 to 25]")
|
||||
("rx_gain", po::value<int>(&rx_gain)->default_value(50), "LMS6002D Rx combined gain [0 to 156]")
|
||||
("tx_wave_freq", po::value<double>(&tx_wave_freq)->default_value(50e3), "Transmit wave frequency in Hz")
|
||||
("tx_wave_ampl", po::value<double>(&tx_wave_ampl)->default_value(0.7), "Transmit wave amplitude in counts")
|
||||
("rx_offset", po::value<double>(&rx_offset)->default_value(.9344e6), "RX LO offset from the TX LO in Hz")
|
||||
("rx_offset", po::value<double>(&rx_offset)->default_value(300e3), "RX LO offset from the TX LO in Hz")
|
||||
("freq_start", po::value<double>(&freq_start), "Frequency start in Hz (do not specify for default)")
|
||||
("freq_stop", po::value<double>(&freq_stop), "Frequency stop in Hz (do not specify for default)")
|
||||
("freq_step", po::value<double>(&freq_step)->default_value(default_freq_step), "Step size for LO sweep in Hz")
|
||||
("nsamps", po::value<size_t>(&nsamps)->default_value(default_num_samps), "Samples per data capture")
|
||||
("ntrials", po::value<size_t>(&ntrials)->default_value(1), "Num trials per TX LO")
|
||||
("which", po::value<std::string>(&which)->default_value("A"), "Which chain A or B?")
|
||||
("single_test", "Perform a single measurement and exit (freq = freq_start, I = single_test_i, Q = single_test_q]")
|
||||
("single_test_i", po::value<int>(&single_test_i)->default_value(128), "Only in the single test mode! I channel calibration value [0 to 255]")
|
||||
("single_test_q", po::value<int>(&single_test_q)->default_value(128), "Only in the single test mode! Q channel calibration value [0 to 255]")
|
||||
("append", "Append measurements to the calibratoin file instead of rewriting [default=overwrite]")
|
||||
;
|
||||
|
||||
po::variables_map vm;
|
||||
@@ -130,31 +325,17 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
|
||||
|
||||
//print the help message
|
||||
if (vm.count("help")){
|
||||
std::cout << boost::format("USRP Generate TX DC Offset Calibration Table %s") % desc << std::endl;
|
||||
std::cout << boost::format("UmTRX Generate TX DC Offset Calibration Table %s") % desc << std::endl;
|
||||
std::cout <<
|
||||
"This application measures leakage between RX and TX on an XCVR daughterboard to self-calibrate.\n"
|
||||
"This application measures leakage between RX and TX using LMS6002D internal RF loopback to self-calibrate.\n"
|
||||
<< std::endl;
|
||||
return ~0;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
//create a usrp device
|
||||
std::cout << std::endl;
|
||||
std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl;
|
||||
uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
|
||||
verbose = vm.count("verbose");
|
||||
|
||||
//set subdev spec
|
||||
usrp->set_rx_subdev_spec(which+":0");
|
||||
usrp->set_tx_subdev_spec(which+":0");
|
||||
|
||||
//set the antennas to cal
|
||||
if (not uhd::has(usrp->get_rx_antennas(), "CAL") or not uhd::has(usrp->get_tx_antennas(), "CAL")){
|
||||
throw std::runtime_error("This board does not have the CAL antenna option, cannot self-calibrate.");
|
||||
}
|
||||
usrp->set_rx_antenna("CAL");
|
||||
usrp->set_tx_antenna("CAL");
|
||||
|
||||
//set optimum defaults
|
||||
set_optimum_defaults(usrp);
|
||||
// Create a USRP device
|
||||
uhd::usrp::multi_usrp::sptr usrp = setup_usrp_for_cal(args, which, serial, vga1_gain, vga2_gain, rx_gain, verbose);
|
||||
|
||||
//create a receive streamer
|
||||
uhd::stream_args_t stream_args("fc32"); //complex floats
|
||||
@@ -164,18 +345,18 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
|
||||
boost::thread_group threads;
|
||||
threads.create_thread(boost::bind(&tx_thread, usrp, tx_wave_freq, tx_wave_ampl));
|
||||
|
||||
//re-usable buffer for samples
|
||||
std::vector<samp_type> buff;
|
||||
|
||||
//store the results here
|
||||
std::vector<result_t> results;
|
||||
|
||||
uhd::property_tree::sptr tree = usrp->get_device()->get_tree();
|
||||
const uhd::fs_path tx_fe_path = "/mboards/0/dboards/"+which+"/tx_frontends/0";
|
||||
uhd::property<uint8_t> &dc_i_prop = usrp->get_device()->get_tree()->access<uint8_t>(tx_fe_path / "lms6002d/tx_dc_i/value");
|
||||
uhd::property<uint8_t> &dc_q_prop = usrp->get_device()->get_tree()->access<uint8_t>(tx_fe_path / "lms6002d/tx_dc_q/value");
|
||||
uhd::property<uint8_t> &dc_i_prop = tree->access<uint8_t>(tx_fe_path / "lms6002d/tx_dc_i/value");
|
||||
uhd::property<uint8_t> &dc_q_prop = tree->access<uint8_t>(tx_fe_path / "lms6002d/tx_dc_q/value");
|
||||
|
||||
if (not vm.count("freq_start")) freq_start = usrp->get_tx_freq_range().start() + 50e6;
|
||||
if (not vm.count("freq_stop")) freq_stop = usrp->get_tx_freq_range().stop() - 50e6;
|
||||
UHD_MSG(status) << boost::format("Calibration frequency type: DC offset") << std::endl;
|
||||
UHD_MSG(status) << boost::format("Calibration frequency range: %d MHz -> %d MHz") % (freq_start/1e6) % (freq_stop/1e6) << std::endl;
|
||||
|
||||
for (double tx_lo_i = freq_start; tx_lo_i <= freq_stop; tx_lo_i += freq_step){
|
||||
const double tx_lo = tune_rx_and_tx(usrp, tx_lo_i, rx_offset);
|
||||
@@ -185,77 +366,37 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
|
||||
const double actual_tx_freq = usrp->get_tx_freq();
|
||||
const double actual_rx_freq = usrp->get_rx_freq();
|
||||
const double bb_dc_freq = actual_tx_freq - actual_rx_freq;
|
||||
if (vm.count("verbose")) printf("actual_rx_rate = %0.2f MHz\n", actual_rx_rate/1e6);
|
||||
if (vm.count("verbose")) printf("actual_tx_freq = %0.2f MHz\n", actual_tx_freq/1e6);
|
||||
if (vm.count("verbose")) printf("actual_rx_freq = %0.2f MHz\n", actual_rx_freq/1e6);
|
||||
if (vm.count("verbose")) printf("bb_dc_freq = %0.2f MHz\n", bb_dc_freq/1e6);
|
||||
if (verbose) printf("actual_rx_rate = %0.2f MHz\n", actual_rx_rate/1e6);
|
||||
if (verbose) printf("actual_tx_freq = %0.2f MHz\n", actual_tx_freq/1e6);
|
||||
if (verbose) printf("actual_rx_freq = %0.2f MHz\n", actual_rx_freq/1e6);
|
||||
if (verbose) printf("bb_dc_freq = %0.2f MHz\n", bb_dc_freq/1e6);
|
||||
|
||||
for (size_t trial_no = 0; trial_no < ntrials; trial_no++)
|
||||
{
|
||||
//bounds and results from searching
|
||||
double lowest_offset;
|
||||
int best_dc_i = 128, best_dc_q = 128;
|
||||
|
||||
//capture initial uncorrected value
|
||||
dc_i_prop.set(best_dc_i);
|
||||
dc_q_prop.set(best_dc_q);
|
||||
capture_samples(rx_stream, buff, nsamps);
|
||||
const double initial_dc_dbrms = compute_tone_dbrms(buff, bb_dc_freq/actual_rx_rate);
|
||||
lowest_offset = initial_dc_dbrms;
|
||||
if (vm.count("verbose")) printf("initial_dc_dbrms = %2.0f dB\n", initial_dc_dbrms);
|
||||
|
||||
if (vm.count("debug_raw_data")) write_samples_to_file(buff, "initial_samples.dat");
|
||||
|
||||
for (int bound = 256; bound >= 8; bound /= 2) //how many bits of precision to care about for the search
|
||||
if (vm.count("single_test"))
|
||||
{
|
||||
if (vm.count("verbose")) printf(" iteration %du\n", bound);
|
||||
dc_cal_t dc_cal(dc_i_prop, dc_q_prop,
|
||||
rx_stream,
|
||||
nsamps,
|
||||
bb_dc_freq,
|
||||
actual_rx_rate,
|
||||
verbose,
|
||||
vm.count("debug_raw_data"),
|
||||
single_test_i, single_test_q);
|
||||
|
||||
bool has_improvement = false;
|
||||
for (int rand_search_no = 0; rand_search_no < bound/4; rand_search_no++) //how many random points to inspect
|
||||
{
|
||||
int dc_i = uniform_rand(std::max(0, best_dc_i-bound/2), std::min(256, best_dc_i+bound/2));
|
||||
int dc_q = uniform_rand(std::max(0, best_dc_q-bound/2), std::min(256, best_dc_q+bound/2));
|
||||
if (vm.count("verbose")) std::cout << "bound " << bound << " dc_i " << dc_i << " dc_q " << dc_q << std::endl;
|
||||
|
||||
dc_i_prop.set(dc_i);
|
||||
dc_q_prop.set(dc_q);
|
||||
|
||||
//receive some samples
|
||||
capture_samples(rx_stream, buff, nsamps);
|
||||
|
||||
const double dc_dbrms = compute_tone_dbrms(buff, bb_dc_freq/actual_rx_rate);
|
||||
if (vm.count("verbose")) printf(" dc_dbrms = %2.0f dB", dc_dbrms);
|
||||
|
||||
if (dc_dbrms < lowest_offset){
|
||||
lowest_offset = dc_dbrms;
|
||||
best_dc_i = dc_i;
|
||||
best_dc_q = dc_q;
|
||||
has_improvement = true;
|
||||
if (vm.count("verbose")) printf(" *");
|
||||
if (vm.count("debug_raw_data")) write_samples_to_file(buff, "best_samples.dat");
|
||||
}
|
||||
if (vm.count("verbose")) printf("\n");
|
||||
}
|
||||
|
||||
// Stop iterating if no imprevement, but do at least 3 iterations
|
||||
if (!has_improvement and bound < 64) break;
|
||||
}
|
||||
|
||||
if (vm.count("verbose")) printf(" best_dc_i = %d best_dc_q = %d", best_dc_i, best_dc_q);
|
||||
if (vm.count("verbose")) printf(" lowest_offset = %2.0f dB delta = %2.0f dB\n", lowest_offset, initial_dc_dbrms - lowest_offset);
|
||||
|
||||
if (lowest_offset < initial_dc_dbrms){ //most likely valid, keep result
|
||||
result_t result;
|
||||
result.freq = tx_lo;
|
||||
result.real_corr = best_dc_i;
|
||||
result.imag_corr = best_dc_q;
|
||||
result.best = lowest_offset;
|
||||
result.delta = initial_dc_dbrms - lowest_offset;
|
||||
results.push_back(result);
|
||||
if (vm.count("verbose")){
|
||||
std::cout << boost::format("TX DC: %f MHz: lowest offset %f dB, corrected %f dB") % (tx_lo/1e6) % result.best % result.delta << std::endl;
|
||||
}
|
||||
else std::cout << "." << std::flush;
|
||||
const double dc_dbrms = dc_cal.init();;
|
||||
printf("I = %d Q = %d ", single_test_i, single_test_q);
|
||||
printf("dc_dbrms = %2.1f dB\n", dc_dbrms);
|
||||
} else {
|
||||
dc_cal_t dc_cal(dc_i_prop, dc_q_prop,
|
||||
rx_stream,
|
||||
nsamps,
|
||||
bb_dc_freq,
|
||||
actual_rx_rate,
|
||||
verbose,
|
||||
vm.count("debug_raw_data"));
|
||||
// Perform normal calibration
|
||||
results.push_back(calibrate_downhill(dc_cal, tx_lo, verbose));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,7 +406,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
|
||||
threads.interrupt_all();
|
||||
threads.join_all();
|
||||
|
||||
store_results(usrp, results, "TX", "tx", "lms_dc", which);
|
||||
if (not vm.count("single_test"))
|
||||
store_results(usrp, results, "tx", "dc", vm.count("append"));
|
||||
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
243
host/utils/umtrx_cal_tx_dc_offset.py
Normal file
243
host/utils/umtrx_cal_tx_dc_offset.py
Normal file
@@ -0,0 +1,243 @@
|
||||
import SoapySDR
|
||||
from SoapySDR import *
|
||||
import math
|
||||
import numpy
|
||||
import matplotlib.pyplot as plt
|
||||
from scipy import signal
|
||||
import random
|
||||
import time
|
||||
import os
|
||||
from optparse import OptionParser
|
||||
|
||||
SAMP_RATE = 13e6/4
|
||||
FREQ_OFFSET = 0.3e6
|
||||
FREQ_START = 700e6
|
||||
FREQ_STOP = 1200e6
|
||||
FREQ_STEP = 7e6
|
||||
FREQ_VALIDATION_STEP = 2e6
|
||||
SIDE = "A"
|
||||
|
||||
import numpy as np
|
||||
def find_nearest(array,value):
|
||||
idx = (np.abs(array-value)).argmin()
|
||||
return array[idx]
|
||||
|
||||
def calcAvgPs(umtrx, rxStream, fftSize = 4096, numFFT = 10, numSkips=2):
|
||||
samps = numpy.array([0]*fftSize, numpy.complex64)
|
||||
avgFFT = numpy.array([0]*fftSize, numpy.complex64)
|
||||
|
||||
while umtrx.readStream(rxStream, [samps], fftSize, 0, 1000).ret != SOAPY_SDR_TIMEOUT: pass #read until timeout
|
||||
umtrx.activateStream(rxStream, SOAPY_SDR_END_BURST, 0, fftSize*(numFFT+numSkips))
|
||||
|
||||
numActualFFTs = 0
|
||||
for i in range(numFFT+numSkips):
|
||||
if umtrx.readStream(rxStream, [samps], fftSize).ret != fftSize:
|
||||
print 'D'
|
||||
return calcAvgPs(umtrx, rxStream, fftSize, numFFT, numSkips)
|
||||
if i < numSkips: continue #skip first for transients
|
||||
samps *= signal.flattop(fftSize)
|
||||
avgFFT += numpy.fft.fft(samps)
|
||||
numActualFFTs += 1
|
||||
avgFFT /= numActualFFTs
|
||||
assert(len(avgFFT) == fftSize)
|
||||
|
||||
ps = 10*numpy.log10(numpy.abs(avgFFT)) - 20*math.log10(fftSize)
|
||||
freqs = numpy.fft.fftfreq(fftSize, 1.0/SAMP_RATE)
|
||||
return ps, freqs
|
||||
|
||||
def measureToneFromPs(ps_freqs, toneFreq, BW=SAMP_RATE/25):
|
||||
ps, freqs = ps_freqs
|
||||
tonePower = None
|
||||
for idx in range(len(ps)):
|
||||
if freqs[idx] > toneFreq-BW/2 and freqs[idx] < toneFreq+BW/2:
|
||||
if tonePower is None: tonePower = ps[idx]
|
||||
tonePower = max(ps[idx], tonePower)
|
||||
return tonePower
|
||||
|
||||
def validateWithMeasurements(umtrx, rxStream, toneFreq, numAvgPts=5):
|
||||
powers = list()
|
||||
for i in range(numAvgPts):
|
||||
ps, freqs = calcAvgPs(umtrx, rxStream)
|
||||
powers.append(measureToneFromPs((ps, freqs), toneFreq))
|
||||
return 10*numpy.log(numpy.average(numpy.exp(numpy.array(powers)/10))), numpy.std(powers)
|
||||
|
||||
def main():
|
||||
umtrx = SoapySDR.Device(dict(driver='uhd', type='umtrx'))
|
||||
|
||||
#frontend map selects side on ch0
|
||||
umtrx.setFrontendMapping(SOAPY_SDR_RX, SIDE+":0")
|
||||
umtrx.setFrontendMapping(SOAPY_SDR_TX, SIDE+":0")
|
||||
|
||||
#print cal file we will use
|
||||
serial = umtrx.getHardwareInfo()['tx0_serial']
|
||||
cal_dest = os.path.join(os.path.expanduser("~"), '.uhd', 'cal', "tx_dc_cal_v0.2_%s.csv"%serial)
|
||||
print 'going to write calibration data to:', cal_dest
|
||||
|
||||
#cal antennas for loopback
|
||||
umtrx.setAntenna(SOAPY_SDR_RX, 0, "CAL")
|
||||
umtrx.setAntenna(SOAPY_SDR_TX, 0, "CAL")
|
||||
|
||||
#set a low sample rate
|
||||
umtrx.setSampleRate(SOAPY_SDR_RX, 0, SAMP_RATE)
|
||||
umtrx.setSampleRate(SOAPY_SDR_TX, 0, SAMP_RATE)
|
||||
|
||||
rxStream = umtrx.setupStream(SOAPY_SDR_RX, "CF32")
|
||||
|
||||
#calibrate out dc offset at select frequencies
|
||||
best_correction_per_freq = dict()
|
||||
best_dc_power_per_freq = dict()
|
||||
initial_dc_power_per_freq = dict()
|
||||
stddev_dc_power_per_freq = dict()
|
||||
average_dc_power_per_freq = dict()
|
||||
|
||||
for freq in numpy.arange(FREQ_START, FREQ_STOP, FREQ_STEP):
|
||||
|
||||
print 'Doing freq:', freq/1e6, 'MHz'
|
||||
|
||||
#tune rx with offset so we can see tx DC
|
||||
umtrx.setFrequency(SOAPY_SDR_TX, 0, freq)
|
||||
umtrx.setFrequency(SOAPY_SDR_RX, 0, freq + FREQ_OFFSET)
|
||||
umtrx.getHardwareTime() #readback so commands are processed
|
||||
|
||||
best_correction = 0.0
|
||||
best_dc_power = None
|
||||
|
||||
#grab values before correction
|
||||
umtrx.setDCOffset(SOAPY_SDR_TX, 0, best_correction)
|
||||
averagePowers, stddevPowers = validateWithMeasurements(umtrx, rxStream, -FREQ_OFFSET)
|
||||
initial_dc_power_per_freq[freq] = averagePowers
|
||||
|
||||
for bound in (0.1, 0.05, 0.01):
|
||||
this_correction = best_correction
|
||||
|
||||
for searchNo in range(50):
|
||||
|
||||
#print 'searchNo',searchNo
|
||||
|
||||
corr_i = random.uniform(this_correction.real-bound, this_correction.real+bound)
|
||||
corr_q = random.uniform(this_correction.imag-bound, this_correction.imag+bound)
|
||||
|
||||
correction = complex(min(max(corr_i, -1), 1), min(max(corr_q, -1), 1))
|
||||
|
||||
umtrx.setDCOffset(SOAPY_SDR_TX, 0, correction)
|
||||
|
||||
ps, freqs = calcAvgPs(umtrx, rxStream)
|
||||
dc_power = measureToneFromPs((ps, freqs), -FREQ_OFFSET)
|
||||
|
||||
if best_dc_power is None or best_dc_power > dc_power:
|
||||
best_dc_power = dc_power
|
||||
best_correction = correction
|
||||
|
||||
print 'best_dc_power', best_dc_power, ' best_correction', best_correction
|
||||
|
||||
#prove that its really the best...
|
||||
umtrx.setDCOffset(SOAPY_SDR_TX, 0, best_correction)
|
||||
averagePowers, stddevPowers = validateWithMeasurements(umtrx, rxStream, -FREQ_OFFSET)
|
||||
print 'averagePowers', averagePowers
|
||||
print 'stddevPowers', stddevPowers
|
||||
|
||||
best_correction_per_freq[freq] = best_correction
|
||||
best_dc_power_per_freq[freq] = best_dc_power
|
||||
stddev_dc_power_per_freq[freq] = stddevPowers
|
||||
average_dc_power_per_freq[freq] = averagePowers
|
||||
|
||||
########################################################################
|
||||
## produce tx cal serial format
|
||||
########################################################################
|
||||
cal_data = open(cal_dest, 'w')
|
||||
|
||||
cal_data.write("name, TX Frontend Calibration\n")
|
||||
cal_data.write("serial, %s\n"%serial)
|
||||
cal_data.write("timestamp, %d\n"%int(time.time()))
|
||||
cal_data.write("version, 0, 1\n")
|
||||
cal_data.write("DATA STARTS HERE\n")
|
||||
cal_data.write("lo_frequency, correction_real, correction_imag, measured, delta\n")
|
||||
for freq in sorted(best_correction_per_freq.keys()):
|
||||
cal_data.write(', '.join(map(str, [
|
||||
freq,
|
||||
best_correction_per_freq[freq].real,
|
||||
best_correction_per_freq[freq].imag,
|
||||
best_dc_power_per_freq[freq],
|
||||
initial_dc_power_per_freq[freq]-best_dc_power_per_freq[freq],
|
||||
])) + '\n')
|
||||
print ('wrote cal data to %s'%cal_dest)
|
||||
|
||||
"""
|
||||
#recollect dc offsets with corrections applied:
|
||||
validation_average_dc_offsets_per_freq = dict()
|
||||
validation_stddev_dc_offsets_per_freq = dict()
|
||||
original_dc_power_per_freq = dict()
|
||||
|
||||
for freq in numpy.arange(FREQ_START, FREQ_STOP, FREQ_VALIDATION_STEP):
|
||||
|
||||
#tune rx with offset so we can see tx DC
|
||||
umtrx.setFrequency(SOAPY_SDR_TX, 0, freq)
|
||||
umtrx.setFrequency(SOAPY_SDR_RX, 0, freq + FREQ_OFFSET)
|
||||
umtrx.getHardwareTime() #readback so commands are processed
|
||||
|
||||
umtrx.setDCOffset(SOAPY_SDR_TX, 0, 0.0)
|
||||
|
||||
#get the original value before corrections
|
||||
averagePowers, stddevPowers = validateWithMeasurements(umtrx, rxStream, -FREQ_OFFSET)
|
||||
original_dc_power_per_freq[freq] = averagePowers
|
||||
|
||||
#pick the correction to use (closest in freq)
|
||||
correction_freq = find_nearest(best_correction_per_freq.keys(), freq)
|
||||
correction = best_correction_per_freq[correction_freq]
|
||||
|
||||
#perform the measurements again
|
||||
umtrx.setDCOffset(SOAPY_SDR_TX, 0, correction)
|
||||
averagePowers, stddevPowers = validateWithMeasurements(umtrx, rxStream, -FREQ_OFFSET)
|
||||
|
||||
validation_average_dc_offsets_per_freq[freq] = averagePowers
|
||||
validation_stddev_dc_offsets_per_freq[freq] = stddevPowers
|
||||
|
||||
umtrx.closeStream(rxStream)
|
||||
|
||||
plt.figure(1)
|
||||
|
||||
plt.subplot(311)
|
||||
freqs = sorted(average_dc_power_per_freq.keys())
|
||||
vals = [average_dc_power_per_freq[f] for f in freqs]
|
||||
cor_data = plt.plot(numpy.array(freqs)/1e6, vals, label='Correction')
|
||||
freqs = sorted(validation_average_dc_offsets_per_freq.keys())
|
||||
vals = [validation_average_dc_offsets_per_freq[f] for f in freqs]
|
||||
val_data = plt.plot(numpy.array(freqs)/1e6, vals, label='Validation')
|
||||
legend = plt.legend(loc='upper right', shadow=True)
|
||||
plt.title("Freq (MHz) vs average power (dB)")
|
||||
plt.grid(True)
|
||||
|
||||
plt.subplot(312)
|
||||
freqs = sorted(stddev_dc_power_per_freq.keys())
|
||||
vals = [stddev_dc_power_per_freq[f] for f in freqs]
|
||||
cor_data = plt.plot(numpy.array(freqs)/1e6, vals, label='Correction')
|
||||
freqs = sorted(validation_stddev_dc_offsets_per_freq.keys())
|
||||
vals = [validation_stddev_dc_offsets_per_freq[f] for f in freqs]
|
||||
val_data = plt.plot(numpy.array(freqs)/1e6, vals, label='Validation')
|
||||
legend = plt.legend(loc='upper right', shadow=True)
|
||||
plt.title("Freq (MHz) vs stddev power (dB)")
|
||||
plt.grid(True)
|
||||
|
||||
plt.subplot(313)
|
||||
freqs = sorted(original_dc_power_per_freq.keys())
|
||||
vals = [abs(original_dc_power_per_freq[f]-validation_average_dc_offsets_per_freq[f]) for f in freqs]
|
||||
plt.plot(numpy.array(freqs)/1e6, vals, label='Correction')
|
||||
plt.title("Freq (MHz) vs correction (dB)")
|
||||
plt.grid(True)
|
||||
|
||||
plt.show()
|
||||
"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = OptionParser()
|
||||
parser.add_option("--side", dest="side", default=SIDE, help="A or B [default: %default]")
|
||||
parser.add_option("--freq-start", dest="freq_start", default=FREQ_START, type="float", help="frequency start point in Hz [default: %default]")
|
||||
parser.add_option("--freq-stop", dest="freq_stop", default=FREQ_STOP, type="float", help="frequency stop point in Hz [default: %default]")
|
||||
parser.add_option("--freq-step", dest="freq_step", default=FREQ_STEP, type="float", help="frequency step size in Hz [default: %default]")
|
||||
(options, args) = parser.parse_args()
|
||||
SIDE = options.side
|
||||
FREQ_START = options.freq_start
|
||||
FREQ_STOP = options.freq_stop
|
||||
FREQ_STEP = options.freq_step
|
||||
|
||||
main()
|
||||
187
host/utils/umtrx_cal_tx_iq_balance.cpp
Normal file
187
host/utils/umtrx_cal_tx_iq_balance.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
//
|
||||
// Copyright 2010,2012 Ettus Research LLC
|
||||
// Copyright 2015 Fairwaves, Inc
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "usrp_cal_utils.hpp"
|
||||
#include <uhd/utils/safe_main.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/math/special_functions/round.hpp>
|
||||
#include <iostream>
|
||||
#include <complex>
|
||||
#include <ctime>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace po = boost::program_options;
|
||||
|
||||
static const size_t num_search_steps = 5;
|
||||
static const size_t num_search_iters = 7;
|
||||
|
||||
/***********************************************************************
|
||||
* Main
|
||||
**********************************************************************/
|
||||
int UHD_SAFE_MAIN(int argc, char *argv[]){
|
||||
std::string args, which, serial;
|
||||
int verbose;
|
||||
int vga1_gain, vga2_gain, rx_gain;
|
||||
double tx_wave_freq, tx_wave_ampl, rx_offset;
|
||||
double freq_start, freq_stop, freq_step;
|
||||
size_t nsamps;
|
||||
|
||||
po::options_description desc("Allowed options");
|
||||
desc.add_options()
|
||||
("help", "help message")
|
||||
("verbose", "enable some verbose")
|
||||
("args", po::value<std::string>(&args)->default_value(""), "device address args [default = \"\"]")
|
||||
("which", po::value<std::string>(&which)->default_value("A"), "Which chain A or B?")
|
||||
("vga1", po::value<int>(&vga1_gain)->default_value(-20), "LMS6002D Tx VGA1 gain [-35 to -4]")
|
||||
("vga2", po::value<int>(&vga2_gain)->default_value(22), "LMS6002D Tx VGA2 gain [0 to 25]")
|
||||
("rx_gain", po::value<int>(&rx_gain)->default_value(50), "LMS6002D Rx combined gain [0 to 156]")
|
||||
("tx_wave_freq", po::value<double>(&tx_wave_freq)->default_value(50e3), "Transmit wave frequency in Hz")
|
||||
("tx_wave_ampl", po::value<double>(&tx_wave_ampl)->default_value(0.7), "Transmit wave amplitude in counts")
|
||||
("rx_offset", po::value<double>(&rx_offset)->default_value(300e3), "RX LO offset from the TX LO in Hz")
|
||||
("freq_start", po::value<double>(&freq_start), "Frequency start in Hz (do not specify for default)")
|
||||
("freq_stop", po::value<double>(&freq_stop), "Frequency stop in Hz (do not specify for default)")
|
||||
("freq_step", po::value<double>(&freq_step)->default_value(default_freq_step), "Step size for LO sweep in Hz")
|
||||
("nsamps", po::value<size_t>(&nsamps)->default_value(default_num_samps), "Samples per data capture")
|
||||
("append", "Append measurements to the calibratoin file instead of rewriting [default=overwrite]")
|
||||
;
|
||||
|
||||
po::variables_map vm;
|
||||
po::store(po::parse_command_line(argc, argv, desc), vm);
|
||||
po::notify(vm);
|
||||
|
||||
//print the help message
|
||||
if (vm.count("help")){
|
||||
std::cout << boost::format("UmTRX Generate TX IQ Balance Calibration Table %s") % desc << std::endl;
|
||||
std::cout <<
|
||||
"This application measures leakage between RX and TX using LMS6002D internal RF loopback to self-calibrate.\n"
|
||||
<< std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
verbose = vm.count("verbose");
|
||||
|
||||
// Create a USRP device
|
||||
uhd::usrp::multi_usrp::sptr usrp = setup_usrp_for_cal(args, which, serial, vga1_gain, vga2_gain, rx_gain, verbose);
|
||||
|
||||
//create a receive streamer
|
||||
uhd::stream_args_t stream_args("fc32"); //complex floats
|
||||
uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args);
|
||||
|
||||
//create a transmitter thread
|
||||
boost::thread_group threads;
|
||||
threads.create_thread(boost::bind(&tx_thread, usrp, tx_wave_freq, tx_wave_ampl));
|
||||
|
||||
//re-usable buffer for samples
|
||||
std::vector<samp_type> buff;
|
||||
|
||||
//store the results here
|
||||
std::vector<result_t> results;
|
||||
|
||||
uhd::property_tree::sptr tree = usrp->get_device()->get_tree();
|
||||
const uhd::fs_path tx_fe_path = "/mboards/0/tx_frontends/"+which;
|
||||
uhd::property<std::complex<double> > &iq_prop = tree->access<std::complex<double> >(tx_fe_path / "iq_balance" / "value");
|
||||
|
||||
if (not vm.count("freq_start")) freq_start = usrp->get_tx_freq_range().start() + 50e6;
|
||||
if (not vm.count("freq_stop")) freq_stop = usrp->get_tx_freq_range().stop() - 50e6;
|
||||
UHD_MSG(status) << boost::format("Calibration frequency type: IQ balance") << std::endl;
|
||||
UHD_MSG(status) << boost::format("Calibration frequency range: %d MHz -> %d MHz") % (freq_start/1e6) % (freq_stop/1e6) << std::endl;
|
||||
|
||||
for (double tx_lo_i = freq_start; tx_lo_i <= freq_stop; tx_lo_i += freq_step){
|
||||
const double tx_lo = tune_rx_and_tx(usrp, tx_lo_i, rx_offset);
|
||||
|
||||
//frequency constants for this tune event
|
||||
const double actual_rx_rate = usrp->get_rx_rate();
|
||||
const double actual_tx_freq = usrp->get_tx_freq();
|
||||
const double actual_rx_freq = usrp->get_rx_freq();
|
||||
const double bb_tone_freq = actual_tx_freq + tx_wave_freq - actual_rx_freq;
|
||||
const double bb_imag_freq = actual_tx_freq - tx_wave_freq - actual_rx_freq;
|
||||
|
||||
//capture initial uncorrected value
|
||||
iq_prop.set(0.0);
|
||||
capture_samples(rx_stream, buff, nsamps);
|
||||
const double initial_suppression = compute_tone_dbrms(buff, bb_tone_freq/actual_rx_rate) - compute_tone_dbrms(buff, bb_imag_freq/actual_rx_rate);
|
||||
|
||||
//bounds and results from searching
|
||||
std::complex<double> best_correction;
|
||||
double phase_corr_start = -.3, phase_corr_stop = .3, phase_corr_step;
|
||||
double ampl_corr_start = -.3, ampl_corr_stop = .3, ampl_corr_step;
|
||||
double best_suppression = 0, best_phase_corr = 0, best_ampl_corr = 0;
|
||||
|
||||
for (size_t i = 0; i < num_search_iters; i++){
|
||||
|
||||
phase_corr_step = (phase_corr_stop - phase_corr_start)/(num_search_steps-1);
|
||||
ampl_corr_step = (ampl_corr_stop - ampl_corr_start)/(num_search_steps-1);
|
||||
|
||||
for (double phase_corr = phase_corr_start; phase_corr <= phase_corr_stop + phase_corr_step/2; phase_corr += phase_corr_step){
|
||||
for (double ampl_corr = ampl_corr_start; ampl_corr <= ampl_corr_stop + ampl_corr_step/2; ampl_corr += ampl_corr_step){
|
||||
|
||||
const std::complex<double> correction(ampl_corr, phase_corr);
|
||||
iq_prop.set(correction);
|
||||
|
||||
//receive some samples
|
||||
capture_samples(rx_stream, buff, nsamps);
|
||||
|
||||
const double tone_dbrms = compute_tone_dbrms(buff, bb_tone_freq/actual_rx_rate);
|
||||
const double imag_dbrms = compute_tone_dbrms(buff, bb_imag_freq/actual_rx_rate);
|
||||
const double suppression = tone_dbrms - imag_dbrms;
|
||||
|
||||
if (suppression > best_suppression){
|
||||
best_correction = correction;
|
||||
best_suppression = suppression;
|
||||
best_phase_corr = phase_corr;
|
||||
best_ampl_corr = ampl_corr;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
if (verbose) std::cout << "best_phase_corr " << best_phase_corr << std::endl;
|
||||
if (verbose) std::cout << "best_ampl_corr " << best_ampl_corr << std::endl;
|
||||
if (verbose) std::cout << "best_suppression " << best_suppression << std::endl;
|
||||
|
||||
phase_corr_start = best_phase_corr - phase_corr_step;
|
||||
phase_corr_stop = best_phase_corr + phase_corr_step;
|
||||
ampl_corr_start = best_ampl_corr - ampl_corr_step;
|
||||
ampl_corr_stop = best_ampl_corr + ampl_corr_step;
|
||||
}
|
||||
|
||||
if (best_suppression > 30){ //most likely valid, keep result
|
||||
result_t result;
|
||||
result.freq = tx_lo;
|
||||
result.real_corr = best_correction.real();
|
||||
result.imag_corr = best_correction.imag();
|
||||
result.best = best_suppression;
|
||||
result.delta = best_suppression - initial_suppression;
|
||||
results.push_back(result);
|
||||
if (verbose){
|
||||
std::cout << boost::format("TX IQ: %f MHz: best suppression %f dB, corrected %f dB") % (tx_lo/1e6) % result.best % result.delta << std::endl;
|
||||
}
|
||||
else std::cout << "." << std::flush;
|
||||
}
|
||||
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
//stop the transmitter
|
||||
threads.interrupt_all();
|
||||
threads.join_all();
|
||||
|
||||
store_results(usrp, results, "tx", "iq", vm.count("append"));
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
16
host/utils/umtrx_firmware
Executable file
16
host/utils/umtrx_firmware
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
case word in
|
||||
flash )
|
||||
umtrx_net_burner --addr=192.168.10.2 --fpga=/usr/share/umtrx/firmware/u2plus_umtrx_v2.bin --fw=/usr/share/umtrx/firmware/umtrx_txrx_uhd.bin --reset
|
||||
;;
|
||||
check )
|
||||
;;
|
||||
* )
|
||||
cat <<-EOF
|
||||
Usage:
|
||||
$0 flash - burn packaged firmware to umtrx
|
||||
$0 check - compare versions of packaged firmware and one installed on umtrx
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
22
host/utils/umtrx_gps_coord
Executable file
22
host/utils/umtrx_gps_coord
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "x$1" = "x-h" -o "x$1" = "x--help" ] ; then
|
||||
echo "Usage:"
|
||||
echo " umtrx_gps_coord [umtrx_ip]"
|
||||
echo
|
||||
echo " umtrx_ip - (optional) UmTRX IP address [default=192.168.10.2]"
|
||||
echo
|
||||
echo "Output:"
|
||||
echo " hh:mm:ss.SSS UTC <lat>N <lon>W <altitude> m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $# -eq 0 ] ; then
|
||||
UMTRX_ADDR="192.168.10.2"
|
||||
else
|
||||
UMTRX_ADDR=$1
|
||||
fi
|
||||
|
||||
echo . | nc -u $UMTRX_ADDR 49171 | \
|
||||
awk -F, '/\$GPGGA/ {print substr($2,0,3) ":" substr($2,3,2) ":" substr($2,5,2) "." substr($2,8,3) " UTC", (substr($3,0,2) + (substr($3,3) / 60.0)) $4, (substr($5,0,3) + (substr($5,4) / 60.0)) $6, $10 " m"; fflush();}'
|
||||
|
||||
@@ -137,25 +137,14 @@ def is_valid_fw_image(fw_image):
|
||||
########################################################################
|
||||
# interface discovery and device enumeration
|
||||
########################################################################
|
||||
def command(*args):
|
||||
p = subprocess.Popen(
|
||||
args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
ret = p.wait()
|
||||
verbose = p.stdout.read().decode()
|
||||
if ret != 0: raise Exception(verbose)
|
||||
return verbose
|
||||
|
||||
def get_interfaces():
|
||||
if(platform.system() is "Windows"): return win_get_interfaces()
|
||||
else: return unix_get_interfaces()
|
||||
|
||||
def unix_get_interfaces():
|
||||
ifconfig = command("/sbin/ifconfig")
|
||||
ip_addr_re = "cast\D*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"
|
||||
bcasts = re.findall(ip_addr_re, ifconfig)
|
||||
ipint = subprocess.check_output(["/sbin/ip", "-4", "a", "s", "up"])
|
||||
ip_addr_re = "brd\D*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"
|
||||
bcasts = re.findall(ip_addr_re, ipint)
|
||||
return bcasts
|
||||
|
||||
def win_get_interfaces():
|
||||
|
||||
17
host/utils/umtrx_nmea
Executable file
17
host/utils/umtrx_nmea
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "x$1" = "x-h" -o "x$1" = "x--help" ] ; then
|
||||
echo "Usage:"
|
||||
echo " umtrx_nmea [umtrx_ip]"
|
||||
echo
|
||||
echo " umtrx_ip - (optional) UmTRX IP address [default=192.168.10.2]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $# -eq 0 ] ; then
|
||||
UMTRX_ADDR="192.168.10.2"
|
||||
else
|
||||
UMTRX_ADDR=$1
|
||||
fi
|
||||
|
||||
echo . | nc -u $UMTRX_ADDR 49171
|
||||
124
host/utils/umtrx_pa_ctrl.cpp
Normal file
124
host/utils/umtrx_pa_ctrl.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
//
|
||||
// Copyright 2014 Fairwaves LLC
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include <uhd/utils/thread_priority.hpp>
|
||||
#include <uhd/utils/safe_main.hpp>
|
||||
#include <uhd/utils/paths.hpp>
|
||||
#include <uhd/utils/algorithm.hpp>
|
||||
#include <uhd/usrp/multi_usrp.hpp>
|
||||
#include <uhd/types/sensors.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/math/special_functions/round.hpp>
|
||||
#include <boost/random.hpp>
|
||||
#include <iostream>
|
||||
#include <complex>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
|
||||
namespace po = boost::program_options;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Main
|
||||
**********************************************************************/
|
||||
int UHD_SAFE_MAIN(int argc, char *argv[]){
|
||||
std::string args;
|
||||
unsigned pa_dcdc_r = 0;
|
||||
int divsw1 = -1;
|
||||
int divsw2 = -1;
|
||||
|
||||
po::options_description desc("Allowed options");
|
||||
desc.add_options()
|
||||
("help,h", "help message")
|
||||
("verbose", "enable some verbose")
|
||||
("debug_raw_data", "save raw captured signals to files")
|
||||
("args", po::value<std::string>(&args)->default_value(""), "device address args [default = \"\"]")
|
||||
("dcdc_cal,C", "Calibrate DC/DC")
|
||||
("paen1", "Enable PA1")
|
||||
("paen2", "Enable PA2")
|
||||
("padis1", "Disable PA1")
|
||||
("padis2", "Disable PA2")
|
||||
("divsw1", po::value<int>(&divsw1), "1 - Enable / 0 - Disable DivSW1")
|
||||
("divsw2", po::value<int>(&divsw2), "1 - Enable / 0 - Disable DivSW2")
|
||||
("palow", "Turn off internal DC/DC")
|
||||
("pa_dcdc_r", po::value<unsigned>(&pa_dcdc_r),"Turn on internal DC/DC")
|
||||
;
|
||||
|
||||
po::variables_map vm;
|
||||
po::store(po::parse_command_line(argc, argv, desc), vm);
|
||||
po::notify(vm);
|
||||
|
||||
//print the help message
|
||||
if (vm.count("help")){
|
||||
std::cout << desc << std::endl;
|
||||
return ~0;
|
||||
}
|
||||
|
||||
//create a usrp device
|
||||
std::cout << std::endl;
|
||||
std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl;
|
||||
uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
|
||||
uhd::property_tree::sptr tree = usrp->get_device()->get_tree();
|
||||
const uhd::fs_path mb_path = "/mboards/0";
|
||||
|
||||
if (vm.count("paen1")) {
|
||||
tree->access<bool>(mb_path / "pa_en1").set(true);
|
||||
}
|
||||
if (vm.count("paen2")) {
|
||||
tree->access<bool>(mb_path / "pa_en2").set(true);
|
||||
}
|
||||
if (vm.count("palow")) {
|
||||
tree->access<bool>(mb_path / "pa_nlow").set(false);
|
||||
}
|
||||
if (vm.count("padis1")) {
|
||||
tree->access<bool>(mb_path / "pa_en1").set(false);
|
||||
}
|
||||
if (vm.count("padis2")) {
|
||||
tree->access<bool>(mb_path / "pa_en2").set(false);
|
||||
}
|
||||
if (vm.count("pa_dcdc_r")) {
|
||||
tree->access<bool>(mb_path / "pa_nlow").set(true);
|
||||
tree->access<uint8_t>(mb_path / "pa_dcdc_r").set(pa_dcdc_r);
|
||||
}
|
||||
|
||||
if (vm.count("dcdc_cal")) {
|
||||
tree->access<bool>(mb_path / "pa_nlow").set(true);
|
||||
unsigned i;
|
||||
for (i = 0; i < 256; i++) {
|
||||
tree->access<uint8_t>(mb_path / "pa_dcdc_r").set(i);
|
||||
if (i == 0) {
|
||||
boost::this_thread::sleep(boost::posix_time::seconds(1));
|
||||
}
|
||||
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(100)); // Wait for value to settle
|
||||
|
||||
std::cout << "[" << std::setw(3) << i << "]="
|
||||
<< tree->access<uhd::sensor_value_t>(mb_path / "sensors" / "voltageDCOUT").get().to_pp_string().c_str()
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
if (vm.count("divsw1")) {
|
||||
tree->access<bool>(mb_path / "dboards" / "A" / "rx_frontends" / "0" / "diversiy").set(divsw1 ? 1 : 0);
|
||||
}
|
||||
if (vm.count("divsw2")) {
|
||||
tree->access<bool>(mb_path / "dboards" / "B" / "rx_frontends" / "0" / "diversiy").set(divsw1 ? 1 : 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
112
host/utils/umtrx_property_tree.py
Normal file
112
host/utils/umtrx_property_tree.py
Normal file
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################
|
||||
### Property tree API
|
||||
##########################
|
||||
|
||||
import socket
|
||||
import json
|
||||
|
||||
class umtrx_property_tree:
|
||||
|
||||
def connect(self, host="localhost", port=12345):
|
||||
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.s.connect((host, port))
|
||||
self.f = self.s.makefile()
|
||||
|
||||
def close(self):
|
||||
self.s.close()
|
||||
|
||||
#
|
||||
# Helper methods
|
||||
#
|
||||
|
||||
def _send_request(self, action, path, value_type=None, value=None):
|
||||
d = dict(action=action, path=path)
|
||||
if value_type is not None: d['type'] = value_type
|
||||
if value is not None: d['value'] = value
|
||||
return self.s.send(json.dumps(d)+'\n')
|
||||
|
||||
def _recv_response(self):
|
||||
resp = self.f.readline().strip()
|
||||
if len(resp)>0:
|
||||
return json.loads(resp)
|
||||
else:
|
||||
return None
|
||||
|
||||
#
|
||||
# Getters (raw)
|
||||
#
|
||||
|
||||
def query_bool_raw(self, path):
|
||||
self._send_request('GET', path, value_type='BOOL')
|
||||
return self._recv_response()
|
||||
|
||||
def query_int_raw(self, path):
|
||||
self._send_request('GET', path, value_type='INT')
|
||||
return self._recv_response()
|
||||
|
||||
def query_double_raw(self, path):
|
||||
self._send_request('GET', path, value_type='DOUBLE')
|
||||
return self._recv_response()
|
||||
|
||||
def query_sensor_raw(self, path):
|
||||
self._send_request('GET', path, value_type='SENSOR')
|
||||
return self._recv_response()
|
||||
|
||||
def query_range_raw(self, path):
|
||||
self._send_request('GET', path, value_type='RANGE')
|
||||
return self._recv_response()
|
||||
|
||||
#
|
||||
# Getters (value)
|
||||
#
|
||||
|
||||
def query_bool_value(self, path):
|
||||
res = self.query_bool_raw(path)
|
||||
return res['result']['value']
|
||||
|
||||
def query_int_value(self, path):
|
||||
res = self.query_int_raw(path)
|
||||
return res['result']['value']
|
||||
|
||||
def query_double_value(self, path):
|
||||
res = self.query_double_raw(path)
|
||||
return res['result']['value']
|
||||
|
||||
def query_sensor_value(self, path):
|
||||
res = self.query_sensor_raw(path)
|
||||
return res['result']['value']
|
||||
|
||||
def query_range_value(self, path):
|
||||
res = self.query_range_raw(path)
|
||||
return res['result']
|
||||
|
||||
#
|
||||
# Setters
|
||||
#
|
||||
|
||||
def set_bool(self, path, val):
|
||||
self._send_request('SET', path, value_type='BOOL', value=val)
|
||||
return self._recv_response()
|
||||
|
||||
def set_int(self, path, val):
|
||||
self._send_request('SET', path, value_type='INT', value=val)
|
||||
return self._recv_response()
|
||||
|
||||
def set_double(self, path, val):
|
||||
self._send_request('SET', path, value_type='DOUBLE', value=val)
|
||||
return self._recv_response()
|
||||
|
||||
#
|
||||
# Check path presence and list paths
|
||||
#
|
||||
|
||||
def has_path_raw(self, path):
|
||||
self._send_request('HAS', path)
|
||||
return self._recv_response()
|
||||
|
||||
def list_path_raw(self, path):
|
||||
self._send_request('LIST', path)
|
||||
return self._recv_response()
|
||||
49
host/utils/umtrx_query_sensors.py
Executable file
49
host/utils/umtrx_query_sensors.py
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################
|
||||
### Query sensors
|
||||
##########################
|
||||
|
||||
from umtrx_property_tree import umtrx_property_tree
|
||||
from umtrx_vswr import umtrx_vswr
|
||||
|
||||
s = umtrx_property_tree()
|
||||
s.connect()
|
||||
|
||||
sensors_path="/mboards/0/sensors"
|
||||
res = s.list_path_raw(sensors_path)
|
||||
sensors_list = res.get('result', [])
|
||||
|
||||
print "Sensors:"
|
||||
for sensor in sensors_list:
|
||||
reply = s.query_sensor_raw(sensors_path+"/"+sensor)
|
||||
if reply.has_key('result'):
|
||||
res = reply['result']
|
||||
print " %15s = %9s %s" % (res['name'], res['value'], res['unit'])
|
||||
else:
|
||||
print "Can't read sensor %s" % sensor
|
||||
|
||||
#vswr_calibration = TM10_VSWR_cal
|
||||
#vswr_calibration = TM3_VSWR_cal
|
||||
vswr_calibration = 0
|
||||
for num in [1, 2]:
|
||||
vpr_name = 'voltagePR'+str(num)
|
||||
vpf_name = 'voltagePF'+str(num)
|
||||
if vpr_name in sensors_list and vpf_name in sensors_list:
|
||||
vpr = float(s.query_sensor_value(sensors_path+'/'+vpr_name))
|
||||
vpf = float(s.query_sensor_value(sensors_path+'/'+vpf_name))
|
||||
vswr = umtrx_vswr(vpf, vpr, vswr_calibration)
|
||||
print "TRX %d power detector:" % num
|
||||
print " VPF = %5.2f V" % vpf
|
||||
print " PF = %5.1f dBm" % vswr.pf()
|
||||
print " VPR = %5.2f V" % vpr
|
||||
print " PR = %5.1f dBm" % vswr.pr()
|
||||
print " VSWR = %6.2f" % vswr.vswr()
|
||||
print " Gamma = %5.3f" % vswr.gamma()
|
||||
print " Return Loss = %5.1f dB" % vswr.return_loss()
|
||||
print " Mismatch Loss = %5.3f dB" % vswr.mismatch_loss()
|
||||
print " Through power = %5.2f %%" % (100.0*vswr.pf_rate())
|
||||
print " Reflected power = %5.2f %%" % (100.0*vswr.pr_rate())
|
||||
|
||||
s.close()
|
||||
@@ -176,47 +176,55 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
|
||||
uhd::i2c_iface::sptr i2c = usrp->get_device()->get_tree()->access<uhd::i2c_iface::sptr>("/mboards/0/i2c_iface").get();
|
||||
|
||||
//set the tx sample rate
|
||||
std::cout << boost::format("Setting TX Rate: %f Msps...") % (tx_rate/1e6) << std::endl;
|
||||
usrp->set_tx_rate(tx_rate);
|
||||
std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate()/1e6) << std::endl << std::endl;
|
||||
if (usrp->get_tx_num_channels() > 0)
|
||||
{
|
||||
std::cout << boost::format("Setting TX Rate: %f Msps...") % (tx_rate/1e6) << std::endl;
|
||||
usrp->set_tx_rate(tx_rate);
|
||||
std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate()/1e6) << std::endl << std::endl;
|
||||
}
|
||||
|
||||
//set the rx sample rate
|
||||
std::cout << boost::format("Setting RX Rate: %f Msps...") % (rx_rate/1e6) << std::endl;
|
||||
usrp->set_rx_rate(rx_rate);
|
||||
std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate()/1e6) << std::endl << std::endl;
|
||||
if (usrp->get_rx_num_channels() > 0)
|
||||
{
|
||||
std::cout << boost::format("Setting RX Rate: %f Msps...") % (rx_rate/1e6) << std::endl;
|
||||
usrp->set_rx_rate(rx_rate);
|
||||
std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate()/1e6) << std::endl << std::endl;
|
||||
}
|
||||
|
||||
std::cout << boost::format("Setting device timestamp to 0...") << std::endl;
|
||||
usrp->set_time_now(uhd::time_spec_t(0.0));
|
||||
|
||||
//test tx chains
|
||||
for (size_t i = 0; i < 2; i++)
|
||||
//*
|
||||
for (size_t i = 0; i < usrp->get_tx_num_channels(); i++)
|
||||
{
|
||||
std::cout << "TX test with DSP " << i << std::endl;
|
||||
std::cout << "===> TX test with DSP " << i << std::endl;
|
||||
uhd::stream_args_t stream_args("fc32");
|
||||
stream_args.channels.push_back(i);
|
||||
test_tx_chain(usrp, stream_args, ampl, begin_delta, num_samps);
|
||||
}
|
||||
if (usrp->get_tx_num_channels() >= 2)
|
||||
{
|
||||
std::cout << "TX test dual DSP " << std::endl;
|
||||
std::cout << "===> TX test all DSP " << std::endl;
|
||||
uhd::stream_args_t stream_args("fc32");
|
||||
stream_args.channels.push_back(0);
|
||||
stream_args.channels.push_back(1);
|
||||
for (size_t i = 0; i < usrp->get_tx_num_channels(); i++) stream_args.channels.push_back(i);
|
||||
test_tx_chain(usrp, stream_args, ampl, begin_delta, num_samps);
|
||||
}
|
||||
//*/
|
||||
|
||||
//test rx chains
|
||||
for (size_t i = 0; i < 2; i++)
|
||||
for (size_t i = 0; i < usrp->get_rx_num_channels(); i++)
|
||||
{
|
||||
std::cout << "RX test with DSP " << i << std::endl;
|
||||
std::cout << "===> RX test with DSP " << i << std::endl;
|
||||
uhd::stream_args_t stream_args("fc32");
|
||||
stream_args.channels.push_back(i);
|
||||
test_rx_chain(usrp, stream_args, begin_delta, num_samps);
|
||||
}
|
||||
if (usrp->get_rx_num_channels() >= 2)
|
||||
{
|
||||
std::cout << "RX test dual DSP " << std::endl;
|
||||
std::cout << "===> RX test all DSP " << std::endl;
|
||||
uhd::stream_args_t stream_args("fc32");
|
||||
stream_args.channels.push_back(0);
|
||||
stream_args.channels.push_back(1);
|
||||
for (size_t i = 0; i < usrp->get_rx_num_channels(); i++) stream_args.channels.push_back(i);
|
||||
test_rx_chain(usrp, stream_args, begin_delta, num_samps);
|
||||
}
|
||||
|
||||
|
||||
134
host/utils/umtrx_test_gains.cpp
Normal file
134
host/utils/umtrx_test_gains.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
//
|
||||
// Copyright 2015 Fairwaves LLC
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include <uhd/utils/thread_priority.hpp>
|
||||
#include <uhd/utils/safe_main.hpp>
|
||||
#include <uhd/utils/paths.hpp>
|
||||
#include <uhd/utils/algorithm.hpp>
|
||||
#include <uhd/usrp/multi_usrp.hpp>
|
||||
#include <uhd/types/sensors.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/math/special_functions/round.hpp>
|
||||
#include <boost/random.hpp>
|
||||
#include <iostream>
|
||||
#include <complex>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
|
||||
namespace po = boost::program_options;
|
||||
|
||||
static size_t failCount = 0;
|
||||
|
||||
#define CHECK(expr, expected) { \
|
||||
const double actual = expr; \
|
||||
const bool ok = (actual == expected); \
|
||||
if (not ok) failCount++; \
|
||||
std::cout << "Check: " << #expr << " == " << #expected << "\t\t\t" << ((ok)?"OK":"FAIL") << std::endl; \
|
||||
if (not ok) std::cout << "\t FAIL: actual = " << actual << std::endl; }
|
||||
|
||||
/***********************************************************************
|
||||
* Main
|
||||
**********************************************************************/
|
||||
int UHD_SAFE_MAIN(int argc, char *argv[])
|
||||
{
|
||||
std::string args;
|
||||
|
||||
po::options_description desc("Allowed options");
|
||||
desc.add_options()
|
||||
("help,h", "help message")
|
||||
("args", po::value<std::string>(&args)->default_value(""), "device address args [default = \"\"]")
|
||||
;
|
||||
|
||||
po::variables_map vm;
|
||||
po::store(po::parse_command_line(argc, argv, desc), vm);
|
||||
po::notify(vm);
|
||||
|
||||
//print the help message
|
||||
if (vm.count("help")){
|
||||
std::cout << desc << std::endl;
|
||||
return ~0;
|
||||
}
|
||||
|
||||
//create a usrp device
|
||||
std::cout << std::endl;
|
||||
std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl;
|
||||
uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
|
||||
uhd::property_tree::sptr tree = usrp->get_device()->get_tree();
|
||||
const uhd::fs_path mb_path = "/mboards/0";
|
||||
|
||||
//get the spi-interface to check gain values
|
||||
uhd::spi_iface::sptr spiface = tree->access<uhd::spi_iface::sptr>(mb_path / "spi_iface").get();
|
||||
|
||||
for (size_t ch = 0; ch <= 1; ch++)
|
||||
{
|
||||
std::cout << std::endl << "==== Testing channel: " << ch << std::endl;
|
||||
|
||||
std::cout << std::endl << "Check RX gain ranges:" << std::endl;
|
||||
CHECK(usrp->get_rx_gain_range("VGA1", ch).start(), 0);
|
||||
CHECK(usrp->get_rx_gain_range("VGA1", ch).stop(), 126);
|
||||
CHECK(usrp->get_rx_gain_range("VGA2", ch).start(), 0);
|
||||
CHECK(usrp->get_rx_gain_range("VGA2", ch).stop(), 30);
|
||||
CHECK(usrp->get_rx_gain_range(ch).start(), 0);
|
||||
CHECK(usrp->get_rx_gain_range(ch).stop(), 156);
|
||||
|
||||
std::cout << std::endl << "Check TX gain ranges:" << std::endl;
|
||||
CHECK(usrp->get_tx_gain_range("VGA1", ch).start(), -35);
|
||||
CHECK(usrp->get_tx_gain_range("VGA1", ch).stop(), -4);
|
||||
CHECK(usrp->get_tx_gain_range("VGA2", ch).start(), 0);
|
||||
CHECK(usrp->get_tx_gain_range("VGA2", ch).stop(), 25);
|
||||
CHECK(usrp->get_tx_gain_range(ch).start(), -35);
|
||||
CHECK(usrp->get_tx_gain_range(ch).stop(), 21);
|
||||
|
||||
std::cout << std::endl << "Test RX gain distribution:" << std::endl;
|
||||
usrp->set_rx_gain(0, ch);
|
||||
CHECK(usrp->get_rx_gain(ch), 0);
|
||||
CHECK(usrp->get_rx_gain("VGA1", ch), 0);
|
||||
CHECK(usrp->get_rx_gain("VGA2", ch), 0);
|
||||
usrp->set_rx_gain(15, ch);
|
||||
CHECK(usrp->get_rx_gain(ch), 15);
|
||||
CHECK(usrp->get_rx_gain("VGA1", ch), 15);
|
||||
CHECK(usrp->get_rx_gain("VGA2", ch), 0);
|
||||
usrp->set_rx_gain(129, ch);
|
||||
CHECK(usrp->get_rx_gain(ch), 129);
|
||||
CHECK(usrp->get_rx_gain("VGA1", ch), 126);
|
||||
CHECK(usrp->get_rx_gain("VGA2", ch), 3);
|
||||
|
||||
std::cout << std::endl << "Test TX gain distribution:" << std::endl;
|
||||
usrp->set_tx_gain(-35, ch);
|
||||
CHECK(usrp->get_tx_gain(ch), -35);
|
||||
CHECK(usrp->get_tx_gain("VGA2", ch), 0);
|
||||
CHECK(usrp->get_tx_gain("VGA1", ch), -35);
|
||||
usrp->set_tx_gain(-10, ch);
|
||||
CHECK(usrp->get_tx_gain(ch), -10);
|
||||
CHECK(usrp->get_tx_gain("VGA2", ch), 0);
|
||||
CHECK(usrp->get_tx_gain("VGA1", ch), -10);
|
||||
usrp->set_tx_gain(10, ch);
|
||||
CHECK(usrp->get_tx_gain(ch), 10);
|
||||
CHECK(usrp->get_tx_gain("VGA2", ch), 14);
|
||||
CHECK(usrp->get_tx_gain("VGA1", ch), -4);
|
||||
}
|
||||
|
||||
//print status
|
||||
std::cout << std::endl;
|
||||
const bool fail = failCount > 0;
|
||||
if (fail) std::cerr << std::endl << failCount << " TESTS FAILED!!!" << std::endl;
|
||||
else std::cout << std::endl << "ALL TESTS PASSED" << std::endl;
|
||||
std::cout << "Done!" << std::endl;
|
||||
return fail?EXIT_FAILURE:EXIT_SUCCESS;
|
||||
}
|
||||
68
host/utils/umtrx_vswr.py
Normal file
68
host/utils/umtrx_vswr.py
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################
|
||||
### VSWR calculations
|
||||
##########################
|
||||
|
||||
# Implemented as described at:
|
||||
# http://www.markimicrowave.com/assets/data/return%20loss%20to%20vswr.pdf
|
||||
|
||||
import math
|
||||
|
||||
# TODO: requires better calibration
|
||||
TM10_VSWR_cal=0.3/2
|
||||
|
||||
class umtrx_vswr:
|
||||
def __init__(self, VPF, VPR, calibration=0, coef=0.05):
|
||||
self.vpf = VPF
|
||||
self.vpr = VPR
|
||||
self.calibration = calibration
|
||||
self.coef = coef
|
||||
self._gamma = self._calc_gamma()
|
||||
|
||||
def _calc_gamma(self):
|
||||
''' Internal function: calculate Gamma '''
|
||||
return math.pow(10, -self.return_loss()/20.0)
|
||||
|
||||
def pf(self):
|
||||
''' Estimated through power, dBm '''
|
||||
return (self.vpf-self.calibration)/self.coef
|
||||
|
||||
def pr(self):
|
||||
''' Estimated reflected power, dBm '''
|
||||
return (self.vpr-self.calibration)/self.coef
|
||||
|
||||
def return_loss(self):
|
||||
''' Estimated return loss, dB '''
|
||||
return self.pf()-self.pr()
|
||||
|
||||
def gamma(self):
|
||||
''' Estimated Gamma '''
|
||||
return self._gamma
|
||||
|
||||
def vswr(self):
|
||||
''' Estimated VSWR '''
|
||||
gamma = self._gamma
|
||||
if gamma == 1.0:
|
||||
return float("inf")
|
||||
else:
|
||||
return (1+gamma)/(1-gamma)
|
||||
|
||||
def mismatch_loss(self):
|
||||
''' Estimated mismatch loss, dB '''
|
||||
gamma = self._gamma
|
||||
if gamma == 1.0:
|
||||
return float("-inf")
|
||||
else:
|
||||
return -10.0 * math.log(1.0-gamma*gamma, 10)
|
||||
|
||||
def pf_rate(self):
|
||||
''' Estimated reflected power rate, % '''
|
||||
gamma = self._gamma
|
||||
return 1.0 - gamma*gamma
|
||||
|
||||
def pr_rate(self):
|
||||
''' Estimated reflected power rate, % '''
|
||||
gamma = self._gamma
|
||||
return gamma*gamma
|
||||
@@ -16,10 +16,16 @@
|
||||
//
|
||||
|
||||
#include <uhd/utils/paths.hpp>
|
||||
#include <uhd/utils/thread_priority.hpp>
|
||||
#include <uhd/utils/algorithm.hpp>
|
||||
#include <uhd/utils/msg.hpp>
|
||||
#include <uhd/property_tree.hpp>
|
||||
#include <uhd/usrp/multi_usrp.hpp>
|
||||
#include <uhd/usrp/dboard_eeprom.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/math/special_functions/round.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <complex>
|
||||
@@ -37,67 +43,9 @@ typedef std::complex<float> samp_type;
|
||||
**********************************************************************/
|
||||
static const double tau = 6.28318531;
|
||||
static const size_t wave_table_len = 8192;
|
||||
static const size_t num_search_steps = 5;
|
||||
static const size_t num_search_iters = 7;
|
||||
static const double default_freq_step = 1e6;
|
||||
static const size_t default_num_samps = 10000;
|
||||
|
||||
/***********************************************************************
|
||||
* Set standard defaults for devices
|
||||
**********************************************************************/
|
||||
static inline void set_optimum_defaults(uhd::usrp::multi_usrp::sptr usrp){
|
||||
uhd::property_tree::sptr tree = usrp->get_device()->get_tree();
|
||||
|
||||
const uhd::fs_path mb_path = "/mboards/0";
|
||||
const std::string mb_name = tree->access<std::string>(mb_path / "name").get();
|
||||
if (mb_name.find("USRP2") != std::string::npos or mb_name.find("N200") != std::string::npos or mb_name.find("N210") != std::string::npos){
|
||||
usrp->set_tx_rate(12.5e6);
|
||||
usrp->set_rx_rate(12.5e6);
|
||||
}
|
||||
else if (mb_name.find("UMTRX") != std::string::npos){
|
||||
usrp->set_tx_rate(13e6/2);
|
||||
usrp->set_tx_bandwidth(5e6);
|
||||
usrp->set_rx_rate(13e6/2);
|
||||
usrp->set_rx_bandwidth(5e6);
|
||||
}
|
||||
else if (mb_name.find("B100") != std::string::npos){
|
||||
usrp->set_tx_rate(4e6);
|
||||
usrp->set_rx_rate(4e6);
|
||||
}
|
||||
else if (mb_name.find("E100") != std::string::npos or mb_name.find("E110") != std::string::npos){
|
||||
usrp->set_tx_rate(4e6);
|
||||
usrp->set_rx_rate(8e6);
|
||||
}
|
||||
else{
|
||||
throw std::runtime_error("self-calibration is not supported for this hardware");
|
||||
}
|
||||
|
||||
const uhd::fs_path tx_fe_path = "/mboards/0/dboards/A/tx_frontends/0";
|
||||
const std::string tx_name = tree->access<std::string>(tx_fe_path / "name").get();
|
||||
if (tx_name.find("WBX") != std::string::npos or tx_name.find("SBX") != std::string::npos){
|
||||
usrp->set_tx_gain(0);
|
||||
}
|
||||
else if (tx_name.find("LMS6002D") != std::string::npos){
|
||||
usrp->set_tx_gain(10);
|
||||
}
|
||||
else{
|
||||
throw std::runtime_error("self-calibration is not supported for this hardware");
|
||||
}
|
||||
|
||||
const uhd::fs_path rx_fe_path = "/mboards/0/dboards/A/tx_frontends/0";
|
||||
const std::string rx_name = tree->access<std::string>(rx_fe_path / "name").get();
|
||||
if (rx_name.find("WBX") != std::string::npos or rx_name.find("SBX") != std::string::npos){
|
||||
usrp->set_rx_gain(25);
|
||||
}
|
||||
else if (rx_name.find("LMS6002D") != std::string::npos){
|
||||
usrp->set_rx_gain(10);
|
||||
}
|
||||
else{
|
||||
throw std::runtime_error("self-calibration is not supported for this hardware");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Sinusoid wave table
|
||||
**********************************************************************/
|
||||
@@ -146,50 +94,91 @@ static inline void write_samples_to_file(
|
||||
outfile.close();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Retrieve d'board serial
|
||||
**********************************************************************/
|
||||
static std::string get_serial(
|
||||
uhd::usrp::multi_usrp::sptr usrp,
|
||||
const std::string &tx_rx
|
||||
){
|
||||
uhd::property_tree::sptr tree = usrp->get_device()->get_tree();
|
||||
// Will work on 1st subdev, top-level must make sure it's the right one
|
||||
uhd::usrp::subdev_spec_t subdev_spec = usrp->get_rx_subdev_spec();
|
||||
const uhd::fs_path db_path = "/mboards/0/dboards/" + subdev_spec[0].db_name + "/" + tx_rx + "_eeprom";
|
||||
const uhd::usrp::dboard_eeprom_t db_eeprom = tree->access<uhd::usrp::dboard_eeprom_t>(db_path).get();
|
||||
return db_eeprom.serial;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Convert integer calibration values to floats
|
||||
**********************************************************************/
|
||||
static double dc_offset_int2double(uint8_t corr)
|
||||
{
|
||||
return (corr-128)/128.0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Store data to file
|
||||
**********************************************************************/
|
||||
static void store_results(
|
||||
uhd::usrp::multi_usrp::sptr usrp,
|
||||
const std::vector<result_t> &results,
|
||||
const std::string &XX,
|
||||
const std::string &xx,
|
||||
const std::string &what,
|
||||
const std::string &which
|
||||
const std::string &rx_tx, // "tx" or "rx"
|
||||
const std::string &what, // Type of test, e.g. "iq"
|
||||
bool append
|
||||
){
|
||||
//extract eeprom serial
|
||||
uhd::property_tree::sptr tree = usrp->get_device()->get_tree();
|
||||
const uhd::fs_path db_path = "/mboards/0/dboards/"+which+"/" + xx + "_eeprom";
|
||||
const uhd::usrp::dboard_eeprom_t db_eeprom = tree->access<uhd::usrp::dboard_eeprom_t>(db_path).get();
|
||||
if (db_eeprom.serial.empty()) throw std::runtime_error(XX + " dboard has empty serial!");
|
||||
std::ofstream cal_data;
|
||||
bool write_header=true;
|
||||
std::string rx_tx_upper = boost::to_upper_copy(rx_tx);
|
||||
std::string serial = get_serial(usrp, rx_tx);
|
||||
|
||||
//make the calibration file path
|
||||
fs::path cal_data_path = fs::path(uhd::get_app_path()) / ".uhd";
|
||||
fs::create_directory(cal_data_path);
|
||||
cal_data_path = cal_data_path / "cal";
|
||||
fs::create_directory(cal_data_path);
|
||||
cal_data_path = cal_data_path / str(boost::format("%s_%s_cal_v0.1_%s.csv") % xx % what % db_eeprom.serial);
|
||||
cal_data_path = cal_data_path / str(boost::format("%s_%s_cal_v0.2_%s.csv") % rx_tx % what % serial);
|
||||
if (fs::exists(cal_data_path)){
|
||||
fs::rename(cal_data_path, cal_data_path.string() + str(boost::format(".%d") % time(NULL)));
|
||||
if (append)
|
||||
write_header = false;
|
||||
else
|
||||
fs::rename(cal_data_path, cal_data_path.string() + str(boost::format(".%d") % time(NULL)));
|
||||
}
|
||||
|
||||
//fill the calibration file
|
||||
std::ofstream cal_data(cal_data_path.string().c_str());
|
||||
cal_data << boost::format("name, %s Frontend Calibration\n") % XX;
|
||||
cal_data << boost::format("serial, %s\n") % db_eeprom.serial;
|
||||
cal_data << boost::format("timestamp, %d\n") % time(NULL);
|
||||
cal_data << boost::format("version, 0, 1\n");
|
||||
cal_data << boost::format("DATA STARTS HERE\n");
|
||||
cal_data << "lo_frequency, correction_real, correction_imag, measured, delta\n";
|
||||
cal_data.open(cal_data_path.string().c_str(), std::ofstream::out | std::ofstream::app);
|
||||
|
||||
if (write_header)
|
||||
{
|
||||
//fill the calibration file
|
||||
cal_data << boost::format("name, %s Frontend Calibration\n") % rx_tx_upper;
|
||||
cal_data << boost::format("serial, %s\n") % serial;
|
||||
cal_data << boost::format("timestamp, %d\n") % time(NULL);
|
||||
cal_data << boost::format("version, 0, 1\n");
|
||||
cal_data << boost::format("DATA STARTS HERE\n");
|
||||
// For DC calibration we also store LMS6002D integer values
|
||||
if (what == "dc")
|
||||
cal_data << "lo_frequency, correction_real, correction_imag, measured, delta, int_i, int_q\n";
|
||||
else
|
||||
cal_data << "lo_frequency, correction_real, correction_imag, measured, delta\n";
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < results.size(); i++){
|
||||
cal_data
|
||||
<< results[i].freq << ", "
|
||||
<< results[i].real_corr << ", "
|
||||
<< results[i].imag_corr << ", "
|
||||
<< results[i].best << ", "
|
||||
<< results[i].delta << "\n"
|
||||
;
|
||||
// Write to file
|
||||
cal_data << results[i].freq;
|
||||
if (what == "dc") {
|
||||
cal_data << ", " << dc_offset_int2double(results[i].real_corr);
|
||||
cal_data << ", " << dc_offset_int2double(results[i].imag_corr);
|
||||
} else {
|
||||
cal_data << ", " << results[i].real_corr;
|
||||
cal_data << ", " << results[i].imag_corr;
|
||||
}
|
||||
cal_data << ", " << results[i].best;
|
||||
cal_data << ", " << results[i].delta;
|
||||
if (what == "dc") {
|
||||
cal_data << ", " << results[i].real_corr;
|
||||
cal_data << ", " << results[i].imag_corr;
|
||||
}
|
||||
cal_data << "\n";
|
||||
}
|
||||
|
||||
std::cout << "wrote cal data to " << cal_data_path << std::endl;
|
||||
@@ -234,3 +223,105 @@ static void capture_samples(
|
||||
throw std::runtime_error("did not get all the samples requested");
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Transmit thread
|
||||
**********************************************************************/
|
||||
static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, const double tx_wave_freq, const double tx_wave_ampl){
|
||||
uhd::set_thread_priority_safe();
|
||||
|
||||
//create a transmit streamer
|
||||
uhd::stream_args_t stream_args("fc32"); //complex floats
|
||||
uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args);
|
||||
|
||||
//setup variables and allocate buffer
|
||||
uhd::tx_metadata_t md;
|
||||
md.has_time_spec = false;
|
||||
std::vector<samp_type> buff(tx_stream->get_max_num_samps()*10);
|
||||
|
||||
//values for the wave table lookup
|
||||
size_t index = 0;
|
||||
const double tx_rate = usrp->get_tx_rate();
|
||||
const size_t step = boost::math::iround(wave_table_len * tx_wave_freq/tx_rate);
|
||||
wave_table table(tx_wave_ampl);
|
||||
|
||||
//fill buff and send until interrupted
|
||||
while (not boost::this_thread::interruption_requested()){
|
||||
for (size_t i = 0; i < buff.size(); i++){
|
||||
buff[i] = table(index += step);
|
||||
}
|
||||
tx_stream->send(&buff.front(), buff.size(), md);
|
||||
}
|
||||
|
||||
//send a mini EOB packet
|
||||
md.end_of_burst = true;
|
||||
tx_stream->send("", 0, md);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Tune RX and TX routine
|
||||
**********************************************************************/
|
||||
static double tune_rx_and_tx(uhd::usrp::multi_usrp::sptr usrp, const double tx_lo_freq, const double rx_offset){
|
||||
//tune the transmitter with no cordic
|
||||
uhd::tune_request_t tx_tune_req(tx_lo_freq);
|
||||
tx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL;
|
||||
tx_tune_req.dsp_freq = 0;
|
||||
usrp->set_tx_freq(tx_tune_req);
|
||||
|
||||
//tune the receiver
|
||||
usrp->set_rx_freq(uhd::tune_request_t(usrp->get_tx_freq(), rx_offset));
|
||||
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
|
||||
return usrp->get_tx_freq();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Setup function
|
||||
**********************************************************************/
|
||||
static uhd::usrp::multi_usrp::sptr setup_usrp_for_cal(const std::string &args, const std::string &which, std::string &serial,
|
||||
int vga1_gain, int vga2_gain, int rx_gain, int verbose)
|
||||
{
|
||||
std::cout << std::endl;
|
||||
std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl;
|
||||
uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
|
||||
|
||||
// Do we have an UmTRX here?
|
||||
uhd::property_tree::sptr tree = usrp->get_device()->get_tree();
|
||||
const uhd::fs_path mb_path = "/mboards/0";
|
||||
const std::string mb_name = tree->access<std::string>(mb_path / "name").get();
|
||||
if (mb_name.find("UMTRX") == std::string::npos){
|
||||
throw std::runtime_error("This utility supports only UmTRX hardware.");
|
||||
}
|
||||
|
||||
//set subdev spec
|
||||
usrp->set_rx_subdev_spec(which+":0");
|
||||
usrp->set_tx_subdev_spec(which+":0");
|
||||
|
||||
UHD_MSG(status) << "Running calibration for " << usrp->get_tx_subdev_name(0) << std::endl;
|
||||
serial = get_serial(usrp, "tx");
|
||||
UHD_MSG(status) << "Daughterboard serial: " << serial << std::endl;
|
||||
|
||||
//set the antennas to cal
|
||||
if (not uhd::has(usrp->get_rx_antennas(), "CAL") or not uhd::has(usrp->get_tx_antennas(), "CAL")){
|
||||
throw std::runtime_error("This board does not have the CAL antenna option, cannot self-calibrate.");
|
||||
}
|
||||
usrp->set_rx_antenna("CAL");
|
||||
usrp->set_tx_antenna("CAL");
|
||||
|
||||
//set optimum defaults
|
||||
// GSM symbol rate * 4
|
||||
usrp->set_tx_rate(13e6/12);
|
||||
usrp->set_rx_rate(13e6/12);
|
||||
// 500kHz LPF
|
||||
usrp->set_tx_bandwidth(1e6);
|
||||
usrp->set_rx_bandwidth(1e6);
|
||||
// Our recommended VGA1/VGA2
|
||||
usrp->set_tx_gain(vga1_gain, "VGA1");
|
||||
usrp->set_tx_gain(vga2_gain, "VGA2");
|
||||
usrp->set_rx_gain(rx_gain);
|
||||
if (verbose) printf("actual Tx VGA1 gain = %.0f dB\n", usrp->get_tx_gain("VGA1"));
|
||||
if (verbose) printf("actual Tx VGA2 gain = %.0f dB\n", usrp->get_tx_gain("VGA2"));
|
||||
if (verbose) printf("actual Rx gain = %.0f dB\n", usrp->get_rx_gain());
|
||||
|
||||
return usrp;
|
||||
}
|
||||
|
||||
Binary file not shown.
BIN
images/u2plus_umtrx_v2_4ddc.bin
Normal file
BIN
images/u2plus_umtrx_v2_4ddc.bin
Normal file
Binary file not shown.
Binary file not shown.
@@ -25,6 +25,14 @@ SET(CMAKE_SYSTEM_NAME Generic)
|
||||
CMAKE_FORCE_C_COMPILER(zpu-elf-gcc GNU)
|
||||
PROJECT(USRP_NXXX_FW C)
|
||||
|
||||
########################################################################
|
||||
# extract the git hash
|
||||
########################################################################
|
||||
include(${PROJECT_SOURCE_DIR}/cmake/GetGitRevisionDescription.cmake)
|
||||
get_git_head_revision(GITREFSPEC GITHASH)
|
||||
string(SUBSTRING "${GITHASH}" 0 8 GITHASH)
|
||||
add_definitions(-DGITHASH=0x${GITHASH})
|
||||
|
||||
########################################################################
|
||||
# lwIP header include dirs
|
||||
########################################################################
|
||||
|
||||
@@ -323,6 +323,7 @@ main(void)
|
||||
|
||||
//init readback for firmware minor version number
|
||||
fw_regs[U2_FW_REG_VER_MINOR] = USRP2_FW_VER_MINOR;
|
||||
fw_regs[U2_FW_REG_GIT_HASH] = GITHASH;
|
||||
|
||||
#ifdef BOOTLOADER
|
||||
//load the production FPGA image or firmware if appropriate
|
||||
@@ -333,6 +334,9 @@ main(void)
|
||||
#endif
|
||||
|
||||
#ifdef UMTRX
|
||||
//cause net reset...
|
||||
wb_poke32(_SR_ADDR(7), 1);
|
||||
wb_poke32(_SR_ADDR(7), 0);
|
||||
umtrx_init();
|
||||
#endif
|
||||
|
||||
|
||||
130
zpu/cmake/GetGitRevisionDescription.cmake
Normal file
130
zpu/cmake/GetGitRevisionDescription.cmake
Normal file
@@ -0,0 +1,130 @@
|
||||
# - Returns a version string from Git
|
||||
#
|
||||
# These functions force a re-configure on each git commit so that you can
|
||||
# trust the values of the variables in your build system.
|
||||
#
|
||||
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the refspec and sha hash of the current head revision
|
||||
#
|
||||
# git_describe(<var> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the results of git describe on the source tree, and adjusting
|
||||
# the output so that it tests false if an error occurs.
|
||||
#
|
||||
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the results of git describe --exact-match on the source tree,
|
||||
# and adjusting the output so that it tests false if there was no exact
|
||||
# matching tag.
|
||||
#
|
||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
# Iowa State University HCI Graduate Program/VRAC
|
||||
#
|
||||
# Copyright Iowa State University 2009-2010.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
if(__get_git_revision_description)
|
||||
return()
|
||||
endif()
|
||||
set(__get_git_revision_description YES)
|
||||
|
||||
# We must run the following at "include" time, not at function call time,
|
||||
# to find the path to this module rather than the path to a calling list file
|
||||
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
|
||||
|
||||
function(get_git_head_revision _refspecvar _hashvar)
|
||||
set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
|
||||
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
|
||||
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
|
||||
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
|
||||
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
|
||||
# We have reached the root directory, we are not in git
|
||||
set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
|
||||
set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
|
||||
endwhile()
|
||||
# check if this is a submodule
|
||||
if(NOT IS_DIRECTORY ${GIT_DIR})
|
||||
file(READ ${GIT_DIR} submodule)
|
||||
string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
|
||||
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
|
||||
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
|
||||
endif()
|
||||
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
|
||||
if(NOT EXISTS "${GIT_DATA}")
|
||||
file(MAKE_DIRECTORY "${GIT_DATA}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${GIT_DIR}/HEAD")
|
||||
return()
|
||||
endif()
|
||||
set(HEAD_FILE "${GIT_DATA}/HEAD")
|
||||
configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
|
||||
|
||||
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
|
||||
"${GIT_DATA}/grabRef.cmake"
|
||||
@ONLY)
|
||||
include("${GIT_DATA}/grabRef.cmake")
|
||||
|
||||
set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
|
||||
set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_describe _var)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
endif()
|
||||
get_git_head_revision(refspec hash)
|
||||
if(NOT GIT_FOUND)
|
||||
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
if(NOT hash)
|
||||
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# TODO sanitize
|
||||
#if((${ARGN}" MATCHES "&&") OR
|
||||
# (ARGN MATCHES "||") OR
|
||||
# (ARGN MATCHES "\\;"))
|
||||
# message("Please report the following error to the project!")
|
||||
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
|
||||
#endif()
|
||||
|
||||
#message(STATUS "Arguments to execute_process: ${ARGN}")
|
||||
|
||||
execute_process(COMMAND
|
||||
"${GIT_EXECUTABLE}"
|
||||
describe
|
||||
${hash}
|
||||
${ARGN}
|
||||
WORKING_DIRECTORY
|
||||
"${CMAKE_SOURCE_DIR}"
|
||||
RESULT_VARIABLE
|
||||
res
|
||||
OUTPUT_VARIABLE
|
||||
out
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT res EQUAL 0)
|
||||
set(out "${out}-${res}-NOTFOUND")
|
||||
endif()
|
||||
|
||||
set(${_var} "${out}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_get_exact_tag _var)
|
||||
git_describe(out --exact-match ${ARGN})
|
||||
set(${_var} "${out}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
38
zpu/cmake/GetGitRevisionDescription.cmake.in
Normal file
38
zpu/cmake/GetGitRevisionDescription.cmake.in
Normal file
@@ -0,0 +1,38 @@
|
||||
#
|
||||
# Internal file for GetGitRevisionDescription.cmake
|
||||
#
|
||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
# Iowa State University HCI Graduate Program/VRAC
|
||||
#
|
||||
# Copyright Iowa State University 2009-2010.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
set(HEAD_HASH)
|
||||
|
||||
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
|
||||
|
||||
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
|
||||
if(HEAD_CONTENTS MATCHES "ref")
|
||||
# named branch
|
||||
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
|
||||
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
|
||||
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
|
||||
elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}")
|
||||
configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
|
||||
set(HEAD_HASH "${HEAD_REF}")
|
||||
endif()
|
||||
else()
|
||||
# detached HEAD
|
||||
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
|
||||
endif()
|
||||
|
||||
if(NOT HEAD_HASH)
|
||||
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
|
||||
string(STRIP "${HEAD_HASH}" HEAD_HASH)
|
||||
endif()
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "i2c.h"
|
||||
#include "mdelay.h"
|
||||
#include "usrp2/fw_common.h"
|
||||
#include "nonstdio.h"
|
||||
|
||||
static const int EEPROM_PAGESIZE = 16;
|
||||
|
||||
@@ -26,7 +27,11 @@ bool find_safe_booted_flag(void) {
|
||||
return 0;
|
||||
#else
|
||||
unsigned char flag_byte;
|
||||
eeprom_read(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_BOOTLOADER_FLAGS, &flag_byte, 1);
|
||||
if (!eeprom_read(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_BOOTLOADER_FLAGS, &flag_byte, 1)) {
|
||||
puts("Failed to read safe boot flag");
|
||||
return false;
|
||||
}
|
||||
|
||||
return (flag_byte == 0x5E);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -58,8 +58,8 @@ static char uart_mode[4] = {
|
||||
};
|
||||
|
||||
static char uart_speeds[4] = {
|
||||
[UART_DEBUG] = US_230400,
|
||||
[UART_EXP] = US_230400,
|
||||
[UART_DEBUG] = US_115200,
|
||||
[UART_EXP] = US_115200,
|
||||
[UART_GPS] = US_9600
|
||||
};
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@ static uint16_t prescaler_values[MAX_WB_DIV+1] = {
|
||||
PRESCALER(4), // 4: 25 MHz
|
||||
};
|
||||
|
||||
#define WATCHDOG 50000
|
||||
|
||||
void
|
||||
i2c_init(void)
|
||||
{
|
||||
@@ -58,8 +60,13 @@ i2c_init(void)
|
||||
static inline void
|
||||
wait_for_xfer(void)
|
||||
{
|
||||
while (i2c_regs->cmd_status & I2C_ST_TIP) // wait for xfer to complete
|
||||
;
|
||||
unsigned i = WATCHDOG;
|
||||
while ((i != 0) && (i2c_regs->cmd_status & I2C_ST_TIP)) // wait for xfer to complete
|
||||
--i;
|
||||
|
||||
if (i == 0) {
|
||||
puts("wait_for_xfer WATCHDOG failed!");
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
@@ -79,8 +86,13 @@ i2c_read (unsigned char i2c_addr, unsigned char *buf, unsigned int len)
|
||||
if (len == 0) // reading zero bytes always works
|
||||
return true;
|
||||
|
||||
while (i2c_regs->cmd_status & I2C_ST_BUSY)
|
||||
;
|
||||
unsigned i = WATCHDOG;
|
||||
while ((i != 0) && (i2c_regs->cmd_status & I2C_ST_BUSY))
|
||||
--i;
|
||||
if (i == 0) {
|
||||
puts("i2c_read WATCHDOG failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
i2c_regs->data = (i2c_addr << 1) | 1; // 7 bit address and read bit (1)
|
||||
// generate START and write addr
|
||||
@@ -104,8 +116,13 @@ i2c_read (unsigned char i2c_addr, unsigned char *buf, unsigned int len)
|
||||
bool
|
||||
i2c_write(unsigned char i2c_addr, const unsigned char *buf, unsigned int len)
|
||||
{
|
||||
while (i2c_regs->cmd_status & I2C_ST_BUSY)
|
||||
;
|
||||
unsigned i = WATCHDOG;
|
||||
while ((i != 0) && (i2c_regs->cmd_status & I2C_ST_BUSY))
|
||||
--i;
|
||||
if (i == 0) {
|
||||
puts("i2c_write WATCHDOG failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
i2c_regs->data = (i2c_addr << 1) | 0; // 7 bit address and write bit (0)
|
||||
|
||||
|
||||
@@ -241,20 +241,20 @@ typedef struct {
|
||||
////////////////////////////////////////////////////
|
||||
#define localparam static const int
|
||||
|
||||
localparam SR_MISC = 0; // 7 regs
|
||||
localparam SR_MISC = 0; // 8 regs
|
||||
localparam SR_TIME64 = 10; // 6
|
||||
localparam SR_BUF_POOL = 16; // 4
|
||||
|
||||
localparam SR_RX_FRONT0 = 20; // 5
|
||||
localparam SR_RX_FRONT1 = 25; // 5
|
||||
localparam SR_RX_CTRL0 = 32; // 9
|
||||
localparam SR_RX_DSP0 = 48; // 7
|
||||
localparam SR_RX_CTRL1 = 80; // 9
|
||||
localparam SR_RX_DSP1 = 96; // 7
|
||||
localparam SR_RX_CTRL2 = 66; // 9
|
||||
localparam SR_RX_DSP2 = 76; // 7
|
||||
localparam SR_RX_CTRL3 = 83; // 9
|
||||
localparam SR_RX_DSP3 = 93; // 7
|
||||
localparam SR_RX_CTRL0 = 30; // 9
|
||||
localparam SR_RX_DSP0 = 40; // 7
|
||||
localparam SR_RX_CTRL1 = 50; // 9
|
||||
localparam SR_RX_DSP1 = 60; // 7
|
||||
localparam SR_RX_CTRL2 = 70; // 9
|
||||
localparam SR_RX_DSP2 = 80; // 7
|
||||
localparam SR_RX_CTRL3 = 90; // 9
|
||||
localparam SR_RX_DSP3 = 100; // 7
|
||||
|
||||
localparam SR_TX_FRONT0 = 110; // ?
|
||||
localparam SR_TX_CTRL0 = 126; // 6
|
||||
@@ -264,6 +264,8 @@ localparam SR_TX_CTRL1 = 161; // 6
|
||||
localparam SR_TX_DSP1 = 170; // 5
|
||||
|
||||
localparam SR_DIVSW = 180; // 2
|
||||
localparam SR_RX_FE_SW = 183; // 1
|
||||
localparam SR_TX_FE_SW = 184; // 1
|
||||
localparam SR_SPI_CORE = 185; // 3
|
||||
|
||||
#define _SR_ADDR(sr) (SETTING_REGS_BASE + (sr) * sizeof(uint32_t))
|
||||
|
||||
@@ -51,5 +51,5 @@ uint32_t spi_transact(bool readback, int slave, uint32_t data, int length, uint3
|
||||
if (!readback) return 0;
|
||||
|
||||
spi_wait();
|
||||
return readback_mux->spi;
|
||||
return readback_mux->spi & ((1 << length)-1);
|
||||
}
|
||||
|
||||
@@ -37,11 +37,11 @@ umtrx_init(void)
|
||||
uint32_t res;
|
||||
|
||||
//issue a reset to the LMS chips
|
||||
output_regs->lms_res == (LMS1_RESET | LMS2_RESET); // reset pins of lms chips switched to 1
|
||||
output_regs->lms_res = (LMS1_RESET | LMS2_RESET); // reset pins of lms chips switched to 1
|
||||
mdelay(100);
|
||||
output_regs->lms_res = 0; // reset pins of lms chips switched to 0
|
||||
mdelay(100);
|
||||
output_regs->lms_res == (LMS1_RESET | LMS2_RESET); // reset pins of lms chips switched to 1
|
||||
output_regs->lms_res = (LMS1_RESET | LMS2_RESET); // reset pins of lms chips switched to 1
|
||||
|
||||
// Check LMS presense
|
||||
res = spi_transact(SPI_TXRX, SPI_SS_LMS1, LMS_RD_CMD(0x04), 16, SPI_PUSH_FALL|SPI_LATCH_RISE);
|
||||
|
||||
@@ -59,18 +59,20 @@ void start_program(void)
|
||||
|
||||
void do_the_bootload_thing(void) {
|
||||
#ifdef NO_FLASH
|
||||
puts("Starting USRP2+ without flash.");
|
||||
puts("Starting UmTRX without flash.");
|
||||
return;
|
||||
#else
|
||||
spif_init(); //initialize SPI flash clock
|
||||
|
||||
bool production_image = find_safe_booted_flag();
|
||||
puts("SPI Flash has been initialized");
|
||||
|
||||
bool production_image = find_safe_booted_flag();
|
||||
printf("Production image = %d\n", production_image);
|
||||
set_safe_booted_flag(0); //haven't booted yet
|
||||
|
||||
if(BUTTON_PUSHED) { //see memory_map.h
|
||||
puts("Starting USRP2+ in safe mode. Loading safe firmware.");
|
||||
return;
|
||||
puts("Starting UmTRX in safe mode. Loading safe firmware.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!production_image) {
|
||||
@@ -86,7 +88,7 @@ void do_the_bootload_thing(void) {
|
||||
#endif
|
||||
}
|
||||
puts("No valid production FPGA image found.\n");
|
||||
// return;
|
||||
return;
|
||||
}
|
||||
if(is_valid_fw_image(PROD_FW_IMAGE_LOCATION_ADDR)) {
|
||||
puts("Valid production firmware found. Loading...");
|
||||
@@ -105,22 +107,5 @@ void do_the_bootload_thing(void) {
|
||||
return;
|
||||
}
|
||||
puts("No valid production firmware found. Falling through to built-in firmware.");
|
||||
/*
|
||||
if(is_valid_fw_image(SAFE_FW_IMAGE_LOCATION_ADDR)) {
|
||||
spi_flash_read(SAFE_FW_IMAGE_LOCATION_ADDR, FW_IMAGE_SIZE_BYTES, (void *)RAM_BASE);
|
||||
puts("Finished loading. Starting image.");
|
||||
mdelay(300);
|
||||
start_program();
|
||||
puts("ERROR: return from main program! This should never happen!");
|
||||
mdelay(300);
|
||||
#ifdef SPARTAN6
|
||||
icap_s6_reload_fpga(SAFE_FPGA_IMAGE_LOCATION_ADDR, SAFE_FPGA_IMAGE_LOCATION_ADDR);
|
||||
#else
|
||||
icap_s3_reload_fpga(SAFE_FPGA_IMAGE_LOCATION_ADDR);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
puts("ERROR: no safe firmware image available. Falling through to built-in firmware.");
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#include "spi_flash.h"
|
||||
#include "memory_map.h"
|
||||
|
||||
#define WATCHDOG 50000
|
||||
#include <nonstdio.h>
|
||||
|
||||
void
|
||||
spif_init(void)
|
||||
{
|
||||
@@ -39,8 +42,11 @@ spif_init(void)
|
||||
inline void
|
||||
spif_wait(void)
|
||||
{
|
||||
while (spif_regs->ctrl & SPI_CTRL_GO_BSY)
|
||||
;
|
||||
unsigned i = WATCHDOG;
|
||||
while ((i != 0) && (spif_regs->ctrl & SPI_CTRL_GO_BSY))
|
||||
--i;
|
||||
if (i == 0)
|
||||
puts("spif_wait WATCHDOG failed!");
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
||||
Reference in New Issue
Block a user