Compare commits
No commits in common. "master" and "kernel-config" have entirely different histories.
master
...
kernel-con
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1 @@
|
|||||||
__pycache__
|
|
||||||
result
|
result
|
21
README.md
21
README.md
@ -1,21 +0,0 @@
|
|||||||
# Firmware for the Sinara 8462 Fast-Servo
|
|
||||||
## Building
|
|
||||||
### Reproducible build with Nix
|
|
||||||
1. Run `nix build .#packages.armv7l-linux.fast-servo-sd-image` to build the sd card image.
|
|
||||||
2. Run `nix develop` to build a dev shell to access the GUI.
|
|
||||||
|
|
||||||
### Flashing
|
|
||||||
1. Plug in your SD card to your computer and run `lsblk` to locate SD card
|
|
||||||
2. If there are any partitions on the SD card, run `umount <mount point>` all the related mount points.
|
|
||||||
3. Run `sudo dd if=<path to the SD Card Image> of=/dev/<SD Card Device Name in lsblk> bs=4M status=progress oflag=sync`
|
|
||||||
4. Eject the SD Card before removal
|
|
||||||
|
|
||||||
### Usage
|
|
||||||
1. Make sure the onboard DIP Switch is in the following condition.
|
|
||||||
- EN: OFF
|
|
||||||
- MODE: ON
|
|
||||||
2. Install the SD Card, power up the board via the power jack or PoE and plug in the RJ45 Ethernet cable.
|
|
||||||
3. Wait for all the front panel LEDs except the termination status LEDs to turn off. It can take a minutes or two for first boot. If it does not boot up, try to flash the SD Card again.
|
|
||||||
4. Run `ssh <fast servo ip address> -p 3030` to ssh into fast-servo and run `linien-server run` to start the linien server.
|
|
||||||
5. In the dev shell, run `linien` to launch the GUI. Add new device. Username is `root` and it does not take any password to log in. You leave the password field with any text.
|
|
||||||
6. Select the newly added device and click connect in the GUI to connect and start the GUI.
|
|
@ -1,66 +0,0 @@
|
|||||||
diff --git a/gateware/logic/autolock.py b/gateware/logic/autolock.py
|
|
||||||
index a6dc764..1a8407f 100644
|
|
||||||
--- a/gateware/logic/autolock.py
|
|
||||||
+++ b/gateware/logic/autolock.py
|
|
||||||
@@ -148,14 +148,17 @@ class RobustAutolock(Module, AutoCSR):
|
|
||||||
final_waited_for = Signal(bits_for(N_points))
|
|
||||||
|
|
||||||
# this is the signal that's used for detecting peaks
|
|
||||||
- sum_diff = Signal((len(self.sum_diff_calculator.output), True))
|
|
||||||
- abs_sum_diff = Signal.like(sum_diff)
|
|
||||||
+ self.sum_diff = Signal((len(self.sum_diff_calculator.output), True))
|
|
||||||
+ abs_sum_diff = Signal.like(self.sum_diff)
|
|
||||||
self.comb += [
|
|
||||||
self.sum_diff_calculator.writing_data_now.eq(self.writing_data_now),
|
|
||||||
self.sum_diff_calculator.restart.eq(self.at_start),
|
|
||||||
self.sum_diff_calculator.input.eq(self.input),
|
|
||||||
self.sum_diff_calculator.delay_value.eq(self.time_scale.storage),
|
|
||||||
- sum_diff.eq(self.sum_diff_calculator.output),
|
|
||||||
+ ]
|
|
||||||
+
|
|
||||||
+ self.sync += [
|
|
||||||
+ self.sum_diff.eq(self.sum_diff_calculator.output),
|
|
||||||
]
|
|
||||||
|
|
||||||
# has this signal at the moment the same sign as the peak we are looking for?
|
|
||||||
@@ -168,16 +171,17 @@ class RobustAutolock(Module, AutoCSR):
|
|
||||||
all_instructions_triggered = Signal()
|
|
||||||
|
|
||||||
self.comb += [
|
|
||||||
- sign_equal.eq((sum_diff > 0) == (current_peak_height > 0)),
|
|
||||||
- If(sum_diff >= 0, abs_sum_diff.eq(sum_diff)).Else(
|
|
||||||
- abs_sum_diff.eq(-1 * sum_diff)
|
|
||||||
+ sign_equal.eq((self.sum_diff > 0) == (current_peak_height > 0)),
|
|
||||||
+ If(self.sum_diff >= 0, abs_sum_diff.eq(self.sum_diff)).Else(
|
|
||||||
+ abs_sum_diff.eq(-1 * self.sum_diff)
|
|
||||||
),
|
|
||||||
If(
|
|
||||||
current_peak_height >= 0,
|
|
||||||
abs_current_peak_height.eq(current_peak_height),
|
|
||||||
).Else(abs_current_peak_height.eq(-1 * current_peak_height)),
|
|
||||||
over_threshold.eq(abs_sum_diff >= abs_current_peak_height),
|
|
||||||
- waited_long_enough.eq(waited_for > current_wait_for),
|
|
||||||
+ # HACK: To compensate the lock position output for the pipeline delay
|
|
||||||
+ waited_long_enough.eq((waited_for >= current_wait_for - 1) & (waited_for != 2 ** bits_for(N_points) - 1) & (current_wait_for - 1 != 2 ** bits_for(N_points) - 1)),
|
|
||||||
all_instructions_triggered.eq(
|
|
||||||
self.current_instruction_idx >= self.N_instructions.storage
|
|
||||||
),
|
|
||||||
@@ -190,7 +194,7 @@ class RobustAutolock(Module, AutoCSR):
|
|
||||||
self.sync += [
|
|
||||||
If(
|
|
||||||
self.at_start,
|
|
||||||
- waited_for.eq(0),
|
|
||||||
+ waited_for.eq(-1),
|
|
||||||
# fpga robust autolock algorithm registeres trigger events delayed.
|
|
||||||
# Therefore, we give it a head start for `final_waited_for`
|
|
||||||
final_waited_for.eq(ROBUST_AUTOLOCK_FPGA_DELAY),
|
|
||||||
@@ -213,7 +217,8 @@ class RobustAutolock(Module, AutoCSR):
|
|
||||||
self.current_instruction_idx.eq(
|
|
||||||
self.current_instruction_idx + 1
|
|
||||||
),
|
|
||||||
- waited_for.eq(0),
|
|
||||||
+ # HACK: To compensate the lock position output for the pipeline delay
|
|
||||||
+ waited_for.eq(-1),
|
|
||||||
).Else(waited_for.eq(waited_for + 1)),
|
|
||||||
),
|
|
||||||
If(
|
|
@ -1,706 +0,0 @@
|
|||||||
# 0 "system-top.dts"
|
|
||||||
# 0 "<built-in>"
|
|
||||||
# 0 "<command-line>"
|
|
||||||
# 1 "system-top.dts"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/dts-v1/;
|
|
||||||
# 1 "zynq-7000.dtsi" 1
|
|
||||||
# 15 "zynq-7000.dtsi"
|
|
||||||
/ {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
compatible = "xlnx,zynq-7000";
|
|
||||||
|
|
||||||
cpus {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
|
|
||||||
cpu0: cpu@0 {
|
|
||||||
compatible = "arm,cortex-a9";
|
|
||||||
device_type = "cpu";
|
|
||||||
reg = <0>;
|
|
||||||
clocks = <&clkc 3>;
|
|
||||||
clock-latency = <1000>;
|
|
||||||
cpu0-supply = <®ulator_vccpint>;
|
|
||||||
operating-points = <
|
|
||||||
|
|
||||||
666667 1000000
|
|
||||||
333334 1000000
|
|
||||||
>;
|
|
||||||
};
|
|
||||||
|
|
||||||
cpu1: cpu@1 {
|
|
||||||
compatible = "arm,cortex-a9";
|
|
||||||
device_type = "cpu";
|
|
||||||
reg = <1>;
|
|
||||||
clocks = <&clkc 3>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
fpga_full: fpga-full {
|
|
||||||
compatible = "fpga-region";
|
|
||||||
fpga-mgr = <&devcfg>;
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
ranges;
|
|
||||||
};
|
|
||||||
|
|
||||||
pmu@f8891000 {
|
|
||||||
compatible = "arm,cortex-a9-pmu";
|
|
||||||
interrupts = <0 5 4>, <0 6 4>;
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
reg = < 0xf8891000 0x1000 0xf8893000 0x1000 >;
|
|
||||||
};
|
|
||||||
|
|
||||||
regulator_vccpint: fixedregulator {
|
|
||||||
compatible = "regulator-fixed";
|
|
||||||
regulator-name = "VCCPINT";
|
|
||||||
regulator-min-microvolt = <1000000>;
|
|
||||||
regulator-max-microvolt = <1000000>;
|
|
||||||
regulator-boot-on;
|
|
||||||
regulator-always-on;
|
|
||||||
};
|
|
||||||
|
|
||||||
replicator {
|
|
||||||
compatible = "arm,coresight-static-replicator";
|
|
||||||
clocks = <&clkc 27>, <&clkc 46>, <&clkc 47>;
|
|
||||||
clock-names = "apb_pclk", "dbg_trc", "dbg_apb";
|
|
||||||
|
|
||||||
out-ports {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
|
|
||||||
|
|
||||||
port@0 {
|
|
||||||
reg = <0>;
|
|
||||||
replicator_out_port0: endpoint {
|
|
||||||
remote-endpoint = <&tpiu_in_port>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
port@1 {
|
|
||||||
reg = <1>;
|
|
||||||
replicator_out_port1: endpoint {
|
|
||||||
remote-endpoint = <&etb_in_port>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in-ports {
|
|
||||||
|
|
||||||
port {
|
|
||||||
replicator_in_port0: endpoint {
|
|
||||||
remote-endpoint = <&funnel_out_port>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
amba: axi {
|
|
||||||
u-boot,dm-pre-reloc;
|
|
||||||
compatible = "simple-bus";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
ranges;
|
|
||||||
|
|
||||||
adc: adc@f8007100 {
|
|
||||||
compatible = "xlnx,zynq-xadc-1.00.a";
|
|
||||||
reg = <0xf8007100 0x20>;
|
|
||||||
interrupts = <0 7 4>;
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
clocks = <&clkc 12>;
|
|
||||||
};
|
|
||||||
|
|
||||||
can0: can@e0008000 {
|
|
||||||
compatible = "xlnx,zynq-can-1.0";
|
|
||||||
status = "disabled";
|
|
||||||
clocks = <&clkc 19>, <&clkc 36>;
|
|
||||||
clock-names = "can_clk", "pclk";
|
|
||||||
reg = <0xe0008000 0x1000>;
|
|
||||||
interrupts = <0 28 4>;
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
tx-fifo-depth = <0x40>;
|
|
||||||
rx-fifo-depth = <0x40>;
|
|
||||||
};
|
|
||||||
|
|
||||||
can1: can@e0009000 {
|
|
||||||
compatible = "xlnx,zynq-can-1.0";
|
|
||||||
status = "disabled";
|
|
||||||
clocks = <&clkc 20>, <&clkc 37>;
|
|
||||||
clock-names = "can_clk", "pclk";
|
|
||||||
reg = <0xe0009000 0x1000>;
|
|
||||||
interrupts = <0 51 4>;
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
tx-fifo-depth = <0x40>;
|
|
||||||
rx-fifo-depth = <0x40>;
|
|
||||||
};
|
|
||||||
|
|
||||||
gpio0: gpio@e000a000 {
|
|
||||||
compatible = "xlnx,zynq-gpio-1.0";
|
|
||||||
#gpio-cells = <2>;
|
|
||||||
clocks = <&clkc 42>;
|
|
||||||
gpio-controller;
|
|
||||||
interrupt-controller;
|
|
||||||
#interrupt-cells = <2>;
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 20 4>;
|
|
||||||
reg = <0xe000a000 0x1000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
i2c0: i2c@e0004000 {
|
|
||||||
compatible = "cdns,i2c-r1p10";
|
|
||||||
status = "disabled";
|
|
||||||
clocks = <&clkc 38>;
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 25 4>;
|
|
||||||
reg = <0xe0004000 0x1000>;
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
i2c1: i2c@e0005000 {
|
|
||||||
compatible = "cdns,i2c-r1p10";
|
|
||||||
status = "disabled";
|
|
||||||
clocks = <&clkc 39>;
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 48 4>;
|
|
||||||
reg = <0xe0005000 0x1000>;
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
intc: interrupt-controller@f8f01000 {
|
|
||||||
compatible = "arm,cortex-a9-gic";
|
|
||||||
#interrupt-cells = <3>;
|
|
||||||
interrupt-controller;
|
|
||||||
reg = <0xF8F01000 0x1000>,
|
|
||||||
<0xF8F00100 0x100>;
|
|
||||||
};
|
|
||||||
|
|
||||||
L2: cache-controller@f8f02000 {
|
|
||||||
compatible = "arm,pl310-cache";
|
|
||||||
reg = <0xF8F02000 0x1000>;
|
|
||||||
interrupts = <0 2 4>;
|
|
||||||
arm,data-latency = <3 2 2>;
|
|
||||||
arm,tag-latency = <2 2 2>;
|
|
||||||
cache-unified;
|
|
||||||
cache-level = <2>;
|
|
||||||
};
|
|
||||||
|
|
||||||
mc: memory-controller@f8006000 {
|
|
||||||
compatible = "xlnx,zynq-ddrc-a05";
|
|
||||||
reg = <0xf8006000 0x1000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
ocm: sram@fffc0000 {
|
|
||||||
compatible = "mmio-sram";
|
|
||||||
reg = <0xfffc0000 0x10000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
uart0: serial@e0000000 {
|
|
||||||
compatible = "xlnx,xuartps", "cdns,uart-r1p8";
|
|
||||||
status = "disabled";
|
|
||||||
clocks = <&clkc 23>, <&clkc 40>;
|
|
||||||
clock-names = "uart_clk", "pclk";
|
|
||||||
reg = <0xE0000000 0x1000>;
|
|
||||||
interrupts = <0 27 4>;
|
|
||||||
};
|
|
||||||
|
|
||||||
uart1: serial@e0001000 {
|
|
||||||
compatible = "xlnx,xuartps", "cdns,uart-r1p8";
|
|
||||||
status = "disabled";
|
|
||||||
clocks = <&clkc 24>, <&clkc 41>;
|
|
||||||
clock-names = "uart_clk", "pclk";
|
|
||||||
reg = <0xE0001000 0x1000>;
|
|
||||||
interrupts = <0 50 4>;
|
|
||||||
};
|
|
||||||
|
|
||||||
spi0: spi@e0006000 {
|
|
||||||
compatible = "xlnx,zynq-spi-r1p6";
|
|
||||||
reg = <0xe0006000 0x1000>;
|
|
||||||
status = "disabled";
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 26 4>;
|
|
||||||
clocks = <&clkc 25>, <&clkc 34>;
|
|
||||||
clock-names = "ref_clk", "pclk";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
spi1: spi@e0007000 {
|
|
||||||
compatible = "xlnx,zynq-spi-r1p6";
|
|
||||||
reg = <0xe0007000 0x1000>;
|
|
||||||
status = "disabled";
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 49 4>;
|
|
||||||
clocks = <&clkc 26>, <&clkc 35>;
|
|
||||||
clock-names = "ref_clk", "pclk";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
qspi: spi@e000d000 {
|
|
||||||
clock-names = "ref_clk", "pclk";
|
|
||||||
clocks = <&clkc 10>, <&clkc 43>;
|
|
||||||
compatible = "xlnx,zynq-qspi-1.0";
|
|
||||||
status = "disabled";
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 19 4>;
|
|
||||||
reg = <0xe000d000 0x1000>;
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
gem0: ethernet@e000b000 {
|
|
||||||
compatible = "xlnx,zynq-gem", "cdns,zynq-gem", "cdns,gem";
|
|
||||||
reg = <0xe000b000 0x1000>;
|
|
||||||
status = "disabled";
|
|
||||||
interrupts = <0 22 4>;
|
|
||||||
clocks = <&clkc 30>, <&clkc 30>, <&clkc 13>;
|
|
||||||
clock-names = "pclk", "hclk", "tx_clk";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
gem1: ethernet@e000c000 {
|
|
||||||
compatible = "xlnx,zynq-gem", "cdns,zynq-gem", "cdns,gem";
|
|
||||||
reg = <0xe000c000 0x1000>;
|
|
||||||
status = "disabled";
|
|
||||||
interrupts = <0 45 4>;
|
|
||||||
clocks = <&clkc 31>, <&clkc 31>, <&clkc 14>;
|
|
||||||
clock-names = "pclk", "hclk", "tx_clk";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
smcc: memory-controller@e000e000 {
|
|
||||||
compatible = "arm,pl353-smc-r2p1", "arm,primecell";
|
|
||||||
reg = <0xe000e000 0x0001000>;
|
|
||||||
status = "disabled";
|
|
||||||
clock-names = "memclk", "apb_pclk";
|
|
||||||
clocks = <&clkc 11>, <&clkc 44>;
|
|
||||||
ranges = <0x0 0x0 0xe1000000 0x1000000
|
|
||||||
0x1 0x0 0xe2000000 0x2000000
|
|
||||||
0x2 0x0 0xe4000000 0x2000000>;
|
|
||||||
#address-cells = <2>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 18 4>;
|
|
||||||
nfc0: nand-controller@0,0 {
|
|
||||||
compatible = "arm,pl353-nand-r2p1";
|
|
||||||
reg = <0 0 0x1000000>;
|
|
||||||
status = "disabled";
|
|
||||||
#address-cells = <0x1>;
|
|
||||||
#size-cells = <0x0>;
|
|
||||||
};
|
|
||||||
nor0: flash@1,0 {
|
|
||||||
status = "disabled";
|
|
||||||
compatible = "cfi-flash";
|
|
||||||
reg = <1 0 0x2000000>;
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sdhci0: mmc@e0100000 {
|
|
||||||
compatible = "arasan,sdhci-8.9a";
|
|
||||||
status = "disabled";
|
|
||||||
clock-names = "clk_xin", "clk_ahb";
|
|
||||||
clocks = <&clkc 21>, <&clkc 32>;
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 24 4>;
|
|
||||||
reg = <0xe0100000 0x1000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
sdhci1: mmc@e0101000 {
|
|
||||||
compatible = "arasan,sdhci-8.9a";
|
|
||||||
status = "disabled";
|
|
||||||
clock-names = "clk_xin", "clk_ahb";
|
|
||||||
clocks = <&clkc 22>, <&clkc 33>;
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 47 4>;
|
|
||||||
reg = <0xe0101000 0x1000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
slcr: slcr@f8000000 {
|
|
||||||
u-boot,dm-pre-reloc;
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
compatible = "xlnx,zynq-slcr", "syscon", "simple-mfd";
|
|
||||||
reg = <0xF8000000 0x1000>;
|
|
||||||
ranges;
|
|
||||||
clkc: clkc@100 {
|
|
||||||
u-boot,dm-pre-reloc;
|
|
||||||
#clock-cells = <1>;
|
|
||||||
compatible = "xlnx,ps7-clkc";
|
|
||||||
fclk-enable = <0xf>;
|
|
||||||
clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x",
|
|
||||||
"cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x",
|
|
||||||
"dci", "lqspi", "smc", "pcap", "gem0", "gem1",
|
|
||||||
"fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1",
|
|
||||||
"sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1",
|
|
||||||
"dma", "usb0_aper", "usb1_aper", "gem0_aper",
|
|
||||||
"gem1_aper", "sdio0_aper", "sdio1_aper",
|
|
||||||
"spi0_aper", "spi1_aper", "can0_aper", "can1_aper",
|
|
||||||
"i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper",
|
|
||||||
"gpio_aper", "lqspi_aper", "smc_aper", "swdt",
|
|
||||||
"dbg_trc", "dbg_apb";
|
|
||||||
reg = <0x100 0x100>;
|
|
||||||
};
|
|
||||||
|
|
||||||
rstc: rstc@200 {
|
|
||||||
compatible = "xlnx,zynq-reset";
|
|
||||||
reg = <0x200 0x48>;
|
|
||||||
#reset-cells = <1>;
|
|
||||||
syscon = <&slcr>;
|
|
||||||
};
|
|
||||||
|
|
||||||
pinctrl0: pinctrl@700 {
|
|
||||||
compatible = "xlnx,pinctrl-zynq";
|
|
||||||
reg = <0x700 0x200>;
|
|
||||||
syscon = <&slcr>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
dmac_s: dmac@f8003000 {
|
|
||||||
compatible = "arm,pl330", "arm,primecell";
|
|
||||||
reg = <0xf8003000 0x1000>;
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3",
|
|
||||||
"dma4", "dma5", "dma6", "dma7";
|
|
||||||
interrupts = <0 13 4>,
|
|
||||||
<0 14 4>, <0 15 4>,
|
|
||||||
<0 16 4>, <0 17 4>,
|
|
||||||
<0 40 4>, <0 41 4>,
|
|
||||||
<0 42 4>, <0 43 4>;
|
|
||||||
#dma-cells = <1>;
|
|
||||||
#dma-channels = <8>;
|
|
||||||
#dma-requests = <4>;
|
|
||||||
clocks = <&clkc 27>;
|
|
||||||
clock-names = "apb_pclk";
|
|
||||||
};
|
|
||||||
|
|
||||||
devcfg: devcfg@f8007000 {
|
|
||||||
compatible = "xlnx,zynq-devcfg-1.0";
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 8 4>;
|
|
||||||
reg = <0xf8007000 0x100>;
|
|
||||||
clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
|
|
||||||
clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
|
|
||||||
syscon = <&slcr>;
|
|
||||||
};
|
|
||||||
|
|
||||||
efuse: efuse@f800d000 {
|
|
||||||
compatible = "xlnx,zynq-efuse";
|
|
||||||
reg = <0xf800d000 0x20>;
|
|
||||||
};
|
|
||||||
|
|
||||||
global_timer: timer@f8f00200 {
|
|
||||||
compatible = "arm,cortex-a9-global-timer";
|
|
||||||
reg = <0xf8f00200 0x20>;
|
|
||||||
interrupts = <1 11 0x301>;
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
clocks = <&clkc 4>;
|
|
||||||
};
|
|
||||||
|
|
||||||
ttc0: timer@f8001000 {
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
|
|
||||||
compatible = "cdns,ttc";
|
|
||||||
clocks = <&clkc 6>;
|
|
||||||
reg = <0xF8001000 0x1000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
ttc1: timer@f8002000 {
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 37 4>, <0 38 4>, <0 39 4>;
|
|
||||||
compatible = "cdns,ttc";
|
|
||||||
clocks = <&clkc 6>;
|
|
||||||
reg = <0xF8002000 0x1000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
scutimer: timer@f8f00600 {
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <1 13 0x301>;
|
|
||||||
compatible = "arm,cortex-a9-twd-timer";
|
|
||||||
reg = <0xf8f00600 0x20>;
|
|
||||||
clocks = <&clkc 4>;
|
|
||||||
};
|
|
||||||
|
|
||||||
usb0: usb@e0002000 {
|
|
||||||
compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
|
|
||||||
status = "disabled";
|
|
||||||
clocks = <&clkc 28>;
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 21 4>;
|
|
||||||
reg = <0xe0002000 0x1000>;
|
|
||||||
phy_type = "ulpi";
|
|
||||||
};
|
|
||||||
|
|
||||||
usb1: usb@e0003000 {
|
|
||||||
compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
|
|
||||||
status = "disabled";
|
|
||||||
clocks = <&clkc 29>;
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 44 4>;
|
|
||||||
reg = <0xe0003000 0x1000>;
|
|
||||||
phy_type = "ulpi";
|
|
||||||
};
|
|
||||||
|
|
||||||
watchdog0: watchdog@f8005000 {
|
|
||||||
clocks = <&clkc 45>;
|
|
||||||
compatible = "cdns,wdt-r1p2";
|
|
||||||
interrupt-parent = <&intc>;
|
|
||||||
interrupts = <0 9 1>;
|
|
||||||
reg = <0xf8005000 0x1000>;
|
|
||||||
timeout-sec = <10>;
|
|
||||||
};
|
|
||||||
|
|
||||||
etb@f8801000 {
|
|
||||||
compatible = "arm,coresight-etb10", "arm,primecell";
|
|
||||||
reg = <0xf8801000 0x1000>;
|
|
||||||
clocks = <&clkc 27>, <&clkc 46>, <&clkc 47>;
|
|
||||||
clock-names = "apb_pclk", "dbg_trc", "dbg_apb";
|
|
||||||
in-ports {
|
|
||||||
port {
|
|
||||||
etb_in_port: endpoint {
|
|
||||||
remote-endpoint = <&replicator_out_port1>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
tpiu@f8803000 {
|
|
||||||
compatible = "arm,coresight-tpiu", "arm,primecell";
|
|
||||||
reg = <0xf8803000 0x1000>;
|
|
||||||
clocks = <&clkc 27>, <&clkc 46>, <&clkc 47>;
|
|
||||||
clock-names = "apb_pclk", "dbg_trc", "dbg_apb";
|
|
||||||
in-ports {
|
|
||||||
port {
|
|
||||||
tpiu_in_port: endpoint {
|
|
||||||
remote-endpoint = <&replicator_out_port0>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
funnel@f8804000 {
|
|
||||||
compatible = "arm,coresight-static-funnel", "arm,primecell";
|
|
||||||
reg = <0xf8804000 0x1000>;
|
|
||||||
clocks = <&clkc 27>, <&clkc 46>, <&clkc 47>;
|
|
||||||
clock-names = "apb_pclk", "dbg_trc", "dbg_apb";
|
|
||||||
|
|
||||||
|
|
||||||
out-ports {
|
|
||||||
port {
|
|
||||||
funnel_out_port: endpoint {
|
|
||||||
remote-endpoint =
|
|
||||||
<&replicator_in_port0>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
in-ports {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
|
|
||||||
|
|
||||||
port@0 {
|
|
||||||
reg = <0>;
|
|
||||||
funnel0_in_port0: endpoint {
|
|
||||||
remote-endpoint = <&ptm0_out_port>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
port@1 {
|
|
||||||
reg = <1>;
|
|
||||||
funnel0_in_port1: endpoint {
|
|
||||||
remote-endpoint = <&ptm1_out_port>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
port@2 {
|
|
||||||
reg = <2>;
|
|
||||||
funnel0_in_port2: endpoint {
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
ptm@f889c000 {
|
|
||||||
compatible = "arm,coresight-etm3x", "arm,primecell";
|
|
||||||
reg = <0xf889c000 0x1000>;
|
|
||||||
clocks = <&clkc 27>, <&clkc 46>, <&clkc 47>;
|
|
||||||
clock-names = "apb_pclk", "dbg_trc", "dbg_apb";
|
|
||||||
cpu = <&cpu0>;
|
|
||||||
out-ports {
|
|
||||||
port {
|
|
||||||
ptm0_out_port: endpoint {
|
|
||||||
remote-endpoint = <&funnel0_in_port0>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
ptm@f889d000 {
|
|
||||||
compatible = "arm,coresight-etm3x", "arm,primecell";
|
|
||||||
reg = <0xf889d000 0x1000>;
|
|
||||||
clocks = <&clkc 27>, <&clkc 46>, <&clkc 47>;
|
|
||||||
clock-names = "apb_pclk", "dbg_trc", "dbg_apb";
|
|
||||||
cpu = <&cpu1>;
|
|
||||||
out-ports {
|
|
||||||
port {
|
|
||||||
ptm1_out_port: endpoint {
|
|
||||||
remote-endpoint = <&funnel0_in_port1>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# 10 "system-top.dts" 2
|
|
||||||
# 1 "pcw.dtsi" 1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/ {
|
|
||||||
cpus {
|
|
||||||
cpu@0 {
|
|
||||||
operating-points = <500000 1000000 250000 1000000>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
&gem0 {
|
|
||||||
enet-reset = <&gpio0 50 0>;
|
|
||||||
phy-mode = "rgmii-id";
|
|
||||||
status = "okay";
|
|
||||||
xlnx,ptp-enet-clock = <0x4f790d8>;
|
|
||||||
};
|
|
||||||
&gpio0 {
|
|
||||||
emio-gpio-width = <64>;
|
|
||||||
gpio-mask-high = <0x0>;
|
|
||||||
gpio-mask-low = <0x5600>;
|
|
||||||
};
|
|
||||||
&i2c0 {
|
|
||||||
clock-frequency = <400000>;
|
|
||||||
status = "okay";
|
|
||||||
};
|
|
||||||
&i2c1 {
|
|
||||||
clock-frequency = <400000>;
|
|
||||||
status = "okay";
|
|
||||||
};
|
|
||||||
&intc {
|
|
||||||
num_cpus = <2>;
|
|
||||||
num_interrupts = <96>;
|
|
||||||
};
|
|
||||||
&qspi {
|
|
||||||
is-dual = <0>;
|
|
||||||
num-cs = <1>;
|
|
||||||
spi-rx-bus-width = <4>;
|
|
||||||
spi-tx-bus-width = <4>;
|
|
||||||
status = "okay";
|
|
||||||
};
|
|
||||||
&sdhci0 {
|
|
||||||
status = "okay";
|
|
||||||
xlnx,has-cd = <0x0>;
|
|
||||||
xlnx,has-power = <0x0>;
|
|
||||||
xlnx,has-wp = <0x0>;
|
|
||||||
};
|
|
||||||
&spi0 {
|
|
||||||
is-decoded-cs = <0>;
|
|
||||||
num-cs = <3>;
|
|
||||||
status = "okay";
|
|
||||||
};
|
|
||||||
&spi1 {
|
|
||||||
is-decoded-cs = <0>;
|
|
||||||
num-cs = <3>;
|
|
||||||
status = "okay";
|
|
||||||
};
|
|
||||||
&uart0 {
|
|
||||||
cts-override ;
|
|
||||||
device_type = "serial";
|
|
||||||
port-number = <0>;
|
|
||||||
status = "okay";
|
|
||||||
};
|
|
||||||
&usb0 {
|
|
||||||
phy_type = "ulpi";
|
|
||||||
status = "okay";
|
|
||||||
usb-reset = <&gpio0 51 0>;
|
|
||||||
};
|
|
||||||
&clkc {
|
|
||||||
fclk-enable = <0x0>;
|
|
||||||
ps-clk-frequency = <33333333>;
|
|
||||||
};
|
|
||||||
# 11 "system-top.dts" 2
|
|
||||||
# 1 "system-user.dtsi" 1
|
|
||||||
|
|
||||||
|
|
||||||
&spi0 {
|
|
||||||
is-decoded-cs = <1>;
|
|
||||||
num-cs = <4>;
|
|
||||||
|
|
||||||
spidev@1 {
|
|
||||||
compatible = "rohm,dh2228fv";
|
|
||||||
spi-max-frequency = <50000000>;
|
|
||||||
reg = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
spidev@2 {
|
|
||||||
compatible = "rohm,dh2228fv";
|
|
||||||
spi-max-frequency = <50000000>;
|
|
||||||
reg = <2>;
|
|
||||||
};
|
|
||||||
|
|
||||||
spidev@3 {
|
|
||||||
compatible = "rohm,dh2228fv";
|
|
||||||
spi-max-frequency = <50000000>;
|
|
||||||
reg = <3>;
|
|
||||||
};
|
|
||||||
|
|
||||||
spidev@4 {
|
|
||||||
compatible = "rohm,dh2228fv";
|
|
||||||
spi-max-frequency = <50000000>;
|
|
||||||
reg = <4>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
&spi1 {
|
|
||||||
|
|
||||||
spidev@0 {
|
|
||||||
compatible = "rohm,dh2228fv";
|
|
||||||
spi-max-frequency = <50000000>;
|
|
||||||
reg = <0>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# 12 "system-top.dts" 2
|
|
||||||
/ {
|
|
||||||
model = "Sinara Fast Servo board";
|
|
||||||
chosen {
|
|
||||||
bootargs = "earlycon";
|
|
||||||
stdout-path = "serial0:115200n8";
|
|
||||||
};
|
|
||||||
aliases {
|
|
||||||
ethernet0 = &gem0;
|
|
||||||
i2c0 = &i2c0;
|
|
||||||
i2c1 = &i2c1;
|
|
||||||
serial0 = &uart0;
|
|
||||||
mmc0 = &sdhci0;
|
|
||||||
spi0 = &qspi;
|
|
||||||
spi1 = &spi0;
|
|
||||||
spi2 = &spi1;
|
|
||||||
};
|
|
||||||
memory {
|
|
||||||
device_type = "memory";
|
|
||||||
reg = <0x0 0x40000000>;
|
|
||||||
};
|
|
||||||
};
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,241 +0,0 @@
|
|||||||
diff --git a/lib/sw_apps/zynq_fsbl/misc/fast-servo/ps7_init.h b/lib/sw_apps/zynq_fsbl/misc/fast-servo/ps7_init.h
|
|
||||||
index 9572636306..2f3816271e 100644
|
|
||||||
--- a/lib/sw_apps/zynq_fsbl/misc/fast-servo/ps7_init.h
|
|
||||||
+++ b/lib/sw_apps/zynq_fsbl/misc/fast-servo/ps7_init.h
|
|
||||||
@@ -67,20 +67,20 @@ extern unsigned long * ps7_peripherals_init_data;
|
|
||||||
|
|
||||||
/* Freq of all peripherals */
|
|
||||||
|
|
||||||
-#define APU_FREQ 666666687
|
|
||||||
+#define APU_FREQ 500000000
|
|
||||||
#define DDR_FREQ 533333374
|
|
||||||
#define DCI_FREQ 10158730
|
|
||||||
#define QSPI_FREQ 200000000
|
|
||||||
#define SMC_FREQ 10000000
|
|
||||||
-#define ENET0_FREQ 25000000
|
|
||||||
+#define ENET0_FREQ 125000000
|
|
||||||
#define ENET1_FREQ 10000000
|
|
||||||
#define USB0_FREQ 60000000
|
|
||||||
#define USB1_FREQ 60000000
|
|
||||||
-#define SDIO_FREQ 50000000
|
|
||||||
-#define UART_FREQ 50000000
|
|
||||||
-#define SPI_FREQ 10000000
|
|
||||||
-#define I2C_FREQ 111111115
|
|
||||||
-#define WDT_FREQ 111111115
|
|
||||||
+#define SDIO_FREQ 100000000
|
|
||||||
+#define UART_FREQ 100000000
|
|
||||||
+#define SPI_FREQ 166666672
|
|
||||||
+#define I2C_FREQ 83333336
|
|
||||||
+#define WDT_FREQ 83333336
|
|
||||||
#define TTC_FREQ 50000000
|
|
||||||
#define CAN_FREQ 10000000
|
|
||||||
#define PCAP_FREQ 200000000
|
|
||||||
diff --git a/lib/sw_apps/zynq_fsbl/misc/fast-servo/ps7_init_gpl.h b/lib/sw_apps/zynq_fsbl/misc/fast-servo/ps7_init_gpl.h
|
|
||||||
index 8962bed427..df2f16adec 100644
|
|
||||||
--- a/lib/sw_apps/zynq_fsbl/misc/fast-servo/ps7_init_gpl.h
|
|
||||||
+++ b/lib/sw_apps/zynq_fsbl/misc/fast-servo/ps7_init_gpl.h
|
|
||||||
@@ -81,20 +81,20 @@ extern unsigned long * ps7_peripherals_init_data;
|
|
||||||
|
|
||||||
/* Freq of all peripherals */
|
|
||||||
|
|
||||||
-#define APU_FREQ 666666687
|
|
||||||
+#define APU_FREQ 500000000
|
|
||||||
#define DDR_FREQ 533333374
|
|
||||||
#define DCI_FREQ 10158730
|
|
||||||
#define QSPI_FREQ 200000000
|
|
||||||
#define SMC_FREQ 10000000
|
|
||||||
-#define ENET0_FREQ 25000000
|
|
||||||
+#define ENET0_FREQ 125000000
|
|
||||||
#define ENET1_FREQ 10000000
|
|
||||||
#define USB0_FREQ 60000000
|
|
||||||
#define USB1_FREQ 60000000
|
|
||||||
-#define SDIO_FREQ 50000000
|
|
||||||
-#define UART_FREQ 50000000
|
|
||||||
-#define SPI_FREQ 10000000
|
|
||||||
-#define I2C_FREQ 111111115
|
|
||||||
-#define WDT_FREQ 111111115
|
|
||||||
+#define SDIO_FREQ 100000000
|
|
||||||
+#define UART_FREQ 100000000
|
|
||||||
+#define SPI_FREQ 166666672
|
|
||||||
+#define I2C_FREQ 83333336
|
|
||||||
+#define WDT_FREQ 83333336
|
|
||||||
#define TTC_FREQ 50000000
|
|
||||||
#define CAN_FREQ 10000000
|
|
||||||
#define PCAP_FREQ 200000000
|
|
||||||
diff --git a/lib/sw_apps/zynq_fsbl/misc/fast-servo/xparameters.h b/lib/sw_apps/zynq_fsbl/misc/fast-servo/xparameters.h
|
|
||||||
index 997a982ca1..5461fbb477 100644
|
|
||||||
--- a/lib/sw_apps/zynq_fsbl/misc/fast-servo/xparameters.h
|
|
||||||
+++ b/lib/sw_apps/zynq_fsbl/misc/fast-servo/xparameters.h
|
|
||||||
@@ -9,21 +9,26 @@
|
|
||||||
#define XPAR_CPU_ID 0U
|
|
||||||
|
|
||||||
/* Definitions for peripheral PS7_CORTEXA9_0 */
|
|
||||||
-#define XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ 666666687
|
|
||||||
+#define XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ 500000000
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************/
|
|
||||||
|
|
||||||
/* Canonical definitions for peripheral PS7_CORTEXA9_0 */
|
|
||||||
-#define XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ 666666687
|
|
||||||
+#define XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ 500000000
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************/
|
|
||||||
|
|
||||||
+
|
|
||||||
+/* Definitions for interface M_AXI_GP0 */
|
|
||||||
+#define XPAR_M_AXI_GP0_BASEADDR 0x40000000
|
|
||||||
+#define XPAR_M_AXI_GP0_HIGHADDR 0x40001FFF
|
|
||||||
+
|
|
||||||
#include "xparameters_ps.h"
|
|
||||||
|
|
||||||
-#define STDIN_BASEADDRESS 0xE0001000
|
|
||||||
-#define STDOUT_BASEADDRESS 0xE0001000
|
|
||||||
+#define STDIN_BASEADDRESS 0xE0000000
|
|
||||||
+#define STDOUT_BASEADDRESS 0xE0000000
|
|
||||||
|
|
||||||
/******************************************************************/
|
|
||||||
|
|
||||||
@@ -120,7 +125,7 @@
|
|
||||||
#define XPAR_PS7_ETHERNET_0_DEVICE_ID 0
|
|
||||||
#define XPAR_PS7_ETHERNET_0_BASEADDR 0xE000B000
|
|
||||||
#define XPAR_PS7_ETHERNET_0_HIGHADDR 0xE000BFFF
|
|
||||||
-#define XPAR_PS7_ETHERNET_0_ENET_CLK_FREQ_HZ 25000000
|
|
||||||
+#define XPAR_PS7_ETHERNET_0_ENET_CLK_FREQ_HZ 125000000
|
|
||||||
#define XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0 8
|
|
||||||
#define XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV1 1
|
|
||||||
#define XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0 8
|
|
||||||
@@ -138,7 +143,7 @@
|
|
||||||
#define XPAR_XEMACPS_0_DEVICE_ID XPAR_PS7_ETHERNET_0_DEVICE_ID
|
|
||||||
#define XPAR_XEMACPS_0_BASEADDR 0xE000B000
|
|
||||||
#define XPAR_XEMACPS_0_HIGHADDR 0xE000BFFF
|
|
||||||
-#define XPAR_XEMACPS_0_ENET_CLK_FREQ_HZ 25000000
|
|
||||||
+#define XPAR_XEMACPS_0_ENET_CLK_FREQ_HZ 125000000
|
|
||||||
#define XPAR_XEMACPS_0_ENET_SLCR_1000Mbps_DIV0 8
|
|
||||||
#define XPAR_XEMACPS_0_ENET_SLCR_1000Mbps_DIV1 1
|
|
||||||
#define XPAR_XEMACPS_0_ENET_SLCR_100Mbps_DIV0 8
|
|
||||||
@@ -265,13 +270,13 @@
|
|
||||||
/******************************************************************/
|
|
||||||
|
|
||||||
/* Definitions for driver IICPS */
|
|
||||||
-#define XPAR_XIICPS_NUM_INSTANCES 1
|
|
||||||
+#define XPAR_XIICPS_NUM_INSTANCES 2
|
|
||||||
|
|
||||||
/* Definitions for peripheral PS7_I2C_0 */
|
|
||||||
#define XPAR_PS7_I2C_0_DEVICE_ID 0
|
|
||||||
#define XPAR_PS7_I2C_0_BASEADDR 0xE0004000
|
|
||||||
#define XPAR_PS7_I2C_0_HIGHADDR 0xE0004FFF
|
|
||||||
-#define XPAR_PS7_I2C_0_I2C_CLK_FREQ_HZ 111111115
|
|
||||||
+#define XPAR_PS7_I2C_0_I2C_CLK_FREQ_HZ 83333336
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************/
|
|
||||||
@@ -280,7 +285,7 @@
|
|
||||||
#define XPAR_XIICPS_0_DEVICE_ID XPAR_PS7_I2C_0_DEVICE_ID
|
|
||||||
#define XPAR_XIICPS_0_BASEADDR 0xE0004000
|
|
||||||
#define XPAR_XIICPS_0_HIGHADDR 0xE0004FFF
|
|
||||||
-#define XPAR_XIICPS_0_I2C_CLK_FREQ_HZ 111111115
|
|
||||||
+#define XPAR_XIICPS_0_I2C_CLK_FREQ_HZ 83333336
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************/
|
|
||||||
@@ -376,9 +381,9 @@
|
|
||||||
#define XPAR_PS7_SD_0_DEVICE_ID 0
|
|
||||||
#define XPAR_PS7_SD_0_BASEADDR 0xE0100000
|
|
||||||
#define XPAR_PS7_SD_0_HIGHADDR 0xE0100FFF
|
|
||||||
-#define XPAR_PS7_SD_0_SDIO_CLK_FREQ_HZ 50000000
|
|
||||||
-#define XPAR_PS7_SD_0_HAS_CD 1
|
|
||||||
-#define XPAR_PS7_SD_0_HAS_WP 1
|
|
||||||
+#define XPAR_PS7_SD_0_SDIO_CLK_FREQ_HZ 100000000
|
|
||||||
+#define XPAR_PS7_SD_0_HAS_CD 0
|
|
||||||
+#define XPAR_PS7_SD_0_HAS_WP 0
|
|
||||||
#define XPAR_PS7_SD_0_BUS_WIDTH 0
|
|
||||||
#define XPAR_PS7_SD_0_MIO_BANK 0
|
|
||||||
#define XPAR_PS7_SD_0_HAS_EMIO 0
|
|
||||||
@@ -398,9 +403,9 @@
|
|
||||||
#define XPAR_XSDPS_0_DEVICE_ID XPAR_PS7_SD_0_DEVICE_ID
|
|
||||||
#define XPAR_XSDPS_0_BASEADDR 0xE0100000
|
|
||||||
#define XPAR_XSDPS_0_HIGHADDR 0xE0100FFF
|
|
||||||
-#define XPAR_XSDPS_0_SDIO_CLK_FREQ_HZ 50000000
|
|
||||||
-#define XPAR_XSDPS_0_HAS_CD 1
|
|
||||||
-#define XPAR_XSDPS_0_HAS_WP 1
|
|
||||||
+#define XPAR_XSDPS_0_SDIO_CLK_FREQ_HZ 100000000
|
|
||||||
+#define XPAR_XSDPS_0_HAS_CD 0
|
|
||||||
+#define XPAR_XSDPS_0_HAS_WP 0
|
|
||||||
#define XPAR_XSDPS_0_BUS_WIDTH 0
|
|
||||||
#define XPAR_XSDPS_0_MIO_BANK 0
|
|
||||||
#define XPAR_XSDPS_0_HAS_EMIO 0
|
|
||||||
@@ -422,15 +427,15 @@
|
|
||||||
/* Definitions for peripheral PS7_TTC_0 */
|
|
||||||
#define XPAR_PS7_TTC_0_DEVICE_ID 0U
|
|
||||||
#define XPAR_PS7_TTC_0_BASEADDR 0XF8001000U
|
|
||||||
-#define XPAR_PS7_TTC_0_TTC_CLK_FREQ_HZ 111111115U
|
|
||||||
+#define XPAR_PS7_TTC_0_TTC_CLK_FREQ_HZ 83333336U
|
|
||||||
#define XPAR_PS7_TTC_0_TTC_CLK_CLKSRC 0U
|
|
||||||
#define XPAR_PS7_TTC_1_DEVICE_ID 1U
|
|
||||||
#define XPAR_PS7_TTC_1_BASEADDR 0XF8001004U
|
|
||||||
-#define XPAR_PS7_TTC_1_TTC_CLK_FREQ_HZ 111111115U
|
|
||||||
+#define XPAR_PS7_TTC_1_TTC_CLK_FREQ_HZ 83333336U
|
|
||||||
#define XPAR_PS7_TTC_1_TTC_CLK_CLKSRC 0U
|
|
||||||
#define XPAR_PS7_TTC_2_DEVICE_ID 2U
|
|
||||||
#define XPAR_PS7_TTC_2_BASEADDR 0XF8001008U
|
|
||||||
-#define XPAR_PS7_TTC_2_TTC_CLK_FREQ_HZ 111111115U
|
|
||||||
+#define XPAR_PS7_TTC_2_TTC_CLK_FREQ_HZ 83333336U
|
|
||||||
#define XPAR_PS7_TTC_2_TTC_CLK_CLKSRC 0U
|
|
||||||
|
|
||||||
|
|
||||||
@@ -439,17 +444,17 @@
|
|
||||||
/* Canonical definitions for peripheral PS7_TTC_0 */
|
|
||||||
#define XPAR_XTTCPS_0_DEVICE_ID XPAR_PS7_TTC_0_DEVICE_ID
|
|
||||||
#define XPAR_XTTCPS_0_BASEADDR 0xF8001000U
|
|
||||||
-#define XPAR_XTTCPS_0_TTC_CLK_FREQ_HZ 111111115U
|
|
||||||
+#define XPAR_XTTCPS_0_TTC_CLK_FREQ_HZ 83333336U
|
|
||||||
#define XPAR_XTTCPS_0_TTC_CLK_CLKSRC 0U
|
|
||||||
|
|
||||||
#define XPAR_XTTCPS_1_DEVICE_ID XPAR_PS7_TTC_1_DEVICE_ID
|
|
||||||
#define XPAR_XTTCPS_1_BASEADDR 0xF8001004U
|
|
||||||
-#define XPAR_XTTCPS_1_TTC_CLK_FREQ_HZ 111111115U
|
|
||||||
+#define XPAR_XTTCPS_1_TTC_CLK_FREQ_HZ 83333336U
|
|
||||||
#define XPAR_XTTCPS_1_TTC_CLK_CLKSRC 0U
|
|
||||||
|
|
||||||
#define XPAR_XTTCPS_2_DEVICE_ID XPAR_PS7_TTC_2_DEVICE_ID
|
|
||||||
#define XPAR_XTTCPS_2_BASEADDR 0xF8001008U
|
|
||||||
-#define XPAR_XTTCPS_2_TTC_CLK_FREQ_HZ 111111115U
|
|
||||||
+#define XPAR_XTTCPS_2_TTC_CLK_FREQ_HZ 83333336U
|
|
||||||
#define XPAR_XTTCPS_2_TTC_CLK_CLKSRC 0U
|
|
||||||
|
|
||||||
|
|
||||||
@@ -458,21 +463,21 @@
|
|
||||||
/* Definitions for driver UARTPS */
|
|
||||||
#define XPAR_XUARTPS_NUM_INSTANCES 1
|
|
||||||
|
|
||||||
-/* Definitions for peripheral PS7_UART_1 */
|
|
||||||
-#define XPAR_PS7_UART_1_DEVICE_ID 0
|
|
||||||
-#define XPAR_PS7_UART_1_BASEADDR 0xE0001000
|
|
||||||
-#define XPAR_PS7_UART_1_HIGHADDR 0xE0001FFF
|
|
||||||
-#define XPAR_PS7_UART_1_UART_CLK_FREQ_HZ 50000000
|
|
||||||
-#define XPAR_PS7_UART_1_HAS_MODEM 0
|
|
||||||
+/* Definitions for peripheral PS7_UART_0 */
|
|
||||||
+#define XPAR_PS7_UART_0_DEVICE_ID 0
|
|
||||||
+#define XPAR_PS7_UART_0_BASEADDR 0xE0000000
|
|
||||||
+#define XPAR_PS7_UART_0_HIGHADDR 0xE0000FFF
|
|
||||||
+#define XPAR_PS7_UART_0_UART_CLK_FREQ_HZ 100000000
|
|
||||||
+#define XPAR_PS7_UART_0_HAS_MODEM 0
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************/
|
|
||||||
|
|
||||||
-/* Canonical definitions for peripheral PS7_UART_1 */
|
|
||||||
-#define XPAR_XUARTPS_0_DEVICE_ID XPAR_PS7_UART_1_DEVICE_ID
|
|
||||||
-#define XPAR_XUARTPS_0_BASEADDR 0xE0001000
|
|
||||||
-#define XPAR_XUARTPS_0_HIGHADDR 0xE0001FFF
|
|
||||||
-#define XPAR_XUARTPS_0_UART_CLK_FREQ_HZ 50000000
|
|
||||||
+/* Canonical definitions for peripheral PS7_UART_0 */
|
|
||||||
+#define XPAR_XUARTPS_0_DEVICE_ID XPAR_PS7_UART_0_DEVICE_ID
|
|
||||||
+#define XPAR_XUARTPS_0_BASEADDR 0xE0000000
|
|
||||||
+#define XPAR_XUARTPS_0_HIGHADDR 0xE0000FFF
|
|
||||||
+#define XPAR_XUARTPS_0_UART_CLK_FREQ_HZ 100000000
|
|
||||||
#define XPAR_XUARTPS_0_HAS_MODEM 0
|
|
||||||
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/gateware/logic/iir.py b/gateware/logic/iir.py
|
|
||||||
index 2380dd7..60bfeb7 100644
|
|
||||||
--- a/gateware/logic/iir.py
|
|
||||||
+++ b/gateware/logic/iir.py
|
|
||||||
@@ -89,7 +89,7 @@ class Iir(Filter):
|
|
||||||
zr = Signal.like(z)
|
|
||||||
self.sync += zr.eq(z)
|
|
||||||
z = Signal.like(zr)
|
|
||||||
- self.comb += z.eq(zr + signal * c[coeff])
|
|
||||||
+ self.sync += z.eq(zr + signal * c[coeff])
|
|
||||||
self.comb += y_next.eq(z)
|
|
||||||
self.latency.value = Constant(order + 1)
|
|
||||||
self.interval.value = Constant(1)
|
|
@ -1,31 +0,0 @@
|
|||||||
diff --git a/linien-client/linien_client/deploy.py b/linien-client/linien_client/deploy.py
|
|
||||||
index df6683f..7355cc3 100644
|
|
||||||
--- a/linien-client/linien_client/deploy.py
|
|
||||||
+++ b/linien-client/linien_client/deploy.py
|
|
||||||
@@ -34,7 +34,7 @@ logger.setLevel(logging.DEBUG)
|
|
||||||
|
|
||||||
|
|
||||||
def read_remote_version(
|
|
||||||
- device: Device, ssh_port: int = 22, out_stream=sys.stdout
|
|
||||||
+ device: Device, ssh_port: int = 3030, out_stream=sys.stdout
|
|
||||||
) -> str:
|
|
||||||
"""Read the remote version of linien."""
|
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ def read_remote_version(
|
|
||||||
|
|
||||||
|
|
||||||
def start_remote_server(
|
|
||||||
- device: Device, ssh_port: int = 22, out_stream=sys.stdout
|
|
||||||
+ device: Device, ssh_port: int = 3030, out_stream=sys.stdout
|
|
||||||
) -> None:
|
|
||||||
"""Start the remote linien server."""
|
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ def start_remote_server(
|
|
||||||
|
|
||||||
|
|
||||||
def install_remote_server(
|
|
||||||
- device: Device, ssh_port: int = 22, out_stream=sys.stdout
|
|
||||||
+ device: Device, ssh_port: int = 3030, out_stream=sys.stdout
|
|
||||||
) -> None:
|
|
||||||
"""Install the remote linien server."""
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
|||||||
diff --git a/linien-common/linien_common/common.py b/linien-common/linien_common/common.py
|
|
||||||
index 854d776..a310dbe 100644
|
|
||||||
--- a/linien-common/linien_common/common.py
|
|
||||||
+++ b/linien-common/linien_common/common.py
|
|
||||||
@@ -25,8 +25,8 @@ from typing import Dict, Iterable, List, Tuple, Union
|
|
||||||
import numpy as np
|
|
||||||
from scipy.signal import correlate, resample
|
|
||||||
|
|
||||||
-MHz = 0x10000000 / 8
|
|
||||||
-Vpp = ((1 << 14) - 1) / 4
|
|
||||||
+MHz = 0x10000000 / 8 * 125 / 100
|
|
||||||
+Vpp = (1 << 14) * 0.5 / 0.425 - 1
|
|
||||||
# conversion of bits to V
|
|
||||||
ANALOG_OUT_V = 1.8 / ((2**15) - 1)
|
|
||||||
|
|
@ -1,629 +0,0 @@
|
|||||||
# diff from elhep/Fast-Servo-Firmmware commit ID 7fae40c:
|
|
||||||
# https://github.com/elhep/Fast-Servo-Firmware/commit/7fae40c0f872a91218be378f8289b98b1e366729
|
|
||||||
# Fix for migen add_source deprecation and removed xilinx bootgen command
|
|
||||||
# .bin file is being generated by bit2bin.py from Linien repository
|
|
||||||
# https://github.com/linien-org/linien/blob/master/gateware/bit2bin.py
|
|
||||||
|
|
||||||
diff --git a/fast_servo/gateware/fast_servo_platform.py b/fast_servo/gateware/fast_servo_platform.py
|
|
||||||
index 13b4aa3..89a8103 100644
|
|
||||||
--- a/fast_servo/gateware/fast_servo_platform.py
|
|
||||||
+++ b/fast_servo/gateware/fast_servo_platform.py
|
|
||||||
@@ -324,7 +324,12 @@ class Platform(XilinxPlatform):
|
|
||||||
self.ps7_config = ps7_config
|
|
||||||
|
|
||||||
verilog_sources = os.listdir(verilog_dir)
|
|
||||||
- self.add_sources(verilog_dir, *verilog_sources)
|
|
||||||
+ self.add_source_dir(verilog_dir)
|
|
||||||
+
|
|
||||||
+ def build(self, *args, **kwargs):
|
|
||||||
+ build_dir = kwargs.get('build_dir', 'build')
|
|
||||||
+ self.copy_sources(build_dir)
|
|
||||||
+ super().build(*args, **kwargs)
|
|
||||||
|
|
||||||
def do_finalize(self, fragment):
|
|
||||||
try:
|
|
||||||
diff --git a/fast_servo/gateware/fast_servo_soc.py b/fast_servo/gateware/fast_servo_soc.py
|
|
||||||
index 02128f5..abfc583 100644
|
|
||||||
--- a/fast_servo/gateware/fast_servo_soc.py
|
|
||||||
+++ b/fast_servo/gateware/fast_servo_soc.py
|
|
||||||
@@ -282,9 +282,3 @@ if __name__ == "__main__":
|
|
||||||
os.chdir(os.path.join(root_path, build_dir))
|
|
||||||
with open(f"{build_name}.bif", "w") as f:
|
|
||||||
f.write(f"all:\n{{\n\t{build_name}.bit\n}}")
|
|
||||||
-
|
|
||||||
- cmd = f"bootgen -image {build_name}.bif -arch zynq -process_bitstream bin -w on".split(" ")
|
|
||||||
- subprocess.run(cmd)
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
|
|
||||||
# diff between linen-org/linien commit ID 93f1f50:
|
|
||||||
# https://github.com/linien-org/linien/commit/93f1f50ebd86fe3314cab5a549462d0fcbf6a658
|
|
||||||
# and elhep/linien commit ID b73eea0:
|
|
||||||
# https://github.com/elhep/linien/commit/b73eea07889dda8b55f0cf4c2afde96cf4c3efd1
|
|
||||||
|
|
||||||
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
|
|
||||||
index b3f3683..98c6e51 100644
|
|
||||||
--- a/.pre-commit-config.yaml
|
|
||||||
+++ b/.pre-commit-config.yaml
|
|
||||||
@@ -3,7 +3,7 @@ repos:
|
|
||||||
rev: 23.11.0
|
|
||||||
hooks:
|
|
||||||
- id: black
|
|
||||||
- exclude: ^(gateware/logic/|gateware/lowlevel/|gateware/linien_module.py|linien-server/linien_server/csrmap.py)
|
|
||||||
+ exclude: ^(gateware/logic/|gateware/lowlevel/|gateware/linien_module.py|linien-server/linien_server/csrmap.py|gateware/targets)
|
|
||||||
|
|
||||||
- repo: https://github.com/pycqa/isort
|
|
||||||
rev: 5.12.0
|
|
||||||
diff --git a/gateware/fpga_image_helper.py b/gateware/fpga_image_helper.py
|
|
||||||
index c3e20e7..ebead1d 100644
|
|
||||||
--- a/gateware/fpga_image_helper.py
|
|
||||||
+++ b/gateware/fpga_image_helper.py
|
|
||||||
@@ -1,6 +1,7 @@
|
|
||||||
# This file is part of Linien and based on redpid.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2016-2024 Linien Authors (https://github.com/linien-org/linien#license)
|
|
||||||
+# Copyright 2023 Jakub Matyas <jakubk.m@gmail.com>
|
|
||||||
#
|
|
||||||
# Linien is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
@@ -20,16 +21,18 @@
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from .bit2bin import bit2bin
|
|
||||||
-from .hw_platform import Platform
|
|
||||||
-from .linien_module import RootModule
|
|
||||||
|
|
||||||
REPO_ROOT_DIR = Path(__file__).resolve().parents[1]
|
|
||||||
|
|
||||||
|
|
||||||
def py_csrconstants(map, fil):
|
|
||||||
fil.write("csr_constants = {\n")
|
|
||||||
- for k, v in root.linien.csrbanks.constants:
|
|
||||||
- fil.write(" '{}_{}': {},\n".format(k, v.name, v.value.value))
|
|
||||||
+ for k, v in root.csrbanks.constants:
|
|
||||||
+ if k == "linien":
|
|
||||||
+ # compaitbility layer
|
|
||||||
+ fil.write(" '{}': {},\n".format(v.name, v.value.value))
|
|
||||||
+ else:
|
|
||||||
+ fil.write(" '{}_{}': {},\n".format(k, v.name, v.value.value))
|
|
||||||
fil.write("}\n\n")
|
|
||||||
|
|
||||||
|
|
||||||
@@ -51,26 +54,51 @@ def get_csrmap(banks):
|
|
||||||
def py_csrmap(it, fil):
|
|
||||||
fil.write("csr = {\n")
|
|
||||||
for reg in it:
|
|
||||||
- fil.write(" '{}_{}': ({}, 0x{:03x}, {}, {}),\n".format(*reg))
|
|
||||||
+ main_name = reg[0]
|
|
||||||
+ secondary_name = reg[1]
|
|
||||||
+ # compaitbility layer
|
|
||||||
+ if main_name == "linien" or secondary_name.startswith(main_name):
|
|
||||||
+ fil.write(" '{}': ({}, 0x{:03x}, {}, {}),\n".format(*reg[1:]))
|
|
||||||
+ else:
|
|
||||||
+ fil.write(" '{}_{}': ({}, 0x{:03x}, {}, {}),\n".format(*reg))
|
|
||||||
fil.write("}\n")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
- platform = Platform()
|
|
||||||
- root = RootModule(platform)
|
|
||||||
+ import argparse
|
|
||||||
+
|
|
||||||
+ parser = argparse.ArgumentParser()
|
|
||||||
+ parser.add_argument("-p", "--platform", default=None)
|
|
||||||
+ args = parser.parse_args()
|
|
||||||
+ if args.platform is None or args.platform.lower() == "redpitaya":
|
|
||||||
+ from gateware.hw_platform import Platform
|
|
||||||
+ from gateware.targets.red_pitaya import PitayaSoC
|
|
||||||
+
|
|
||||||
+ platform = Platform()
|
|
||||||
+ root = PitayaSoC(platform)
|
|
||||||
+ elif args.platform.lower() == "fastservo":
|
|
||||||
+ from fast_servo.gateware.fast_servo_platform import Platform
|
|
||||||
+
|
|
||||||
+ from gateware.targets.fast_servo import LinienFastServo
|
|
||||||
+
|
|
||||||
+ platform = Platform()
|
|
||||||
+ root = LinienFastServo(platform)
|
|
||||||
+ else:
|
|
||||||
+ raise ValueError("Unknown platform")
|
|
||||||
+
|
|
||||||
+ platform.add_source_dir(REPO_ROOT_DIR / "gateware" / "verilog")
|
|
||||||
+ build_dir = REPO_ROOT_DIR / "gateware" / "build"
|
|
||||||
+ platform.build(root, build_name="top", build_dir=build_dir, run=True)
|
|
||||||
|
|
||||||
with open(
|
|
||||||
REPO_ROOT_DIR / "linien-server" / "linien_server" / "csrmap.py", "w"
|
|
||||||
) as fil:
|
|
||||||
- py_csrconstants(root.linien.csrbanks.constants, fil)
|
|
||||||
- csr = get_csrmap(root.linien.csrbanks.banks)
|
|
||||||
+ py_csrconstants(root.csrbanks.constants, fil)
|
|
||||||
+ csr = get_csrmap([*root.csrbanks.banks, *root.linien.csrbanks.banks])
|
|
||||||
py_csrmap(csr, fil)
|
|
||||||
fil.write("states = {}\n".format(repr(root.linien.state_names)))
|
|
||||||
fil.write("signals = {}\n".format(repr(root.linien.signal_names)))
|
|
||||||
|
|
||||||
- platform.add_source_dir(REPO_ROOT_DIR / "gateware" / "verilog")
|
|
||||||
- build_dir = REPO_ROOT_DIR / "gateware" / "build"
|
|
||||||
- platform.build(root, build_name="top", build_dir=build_dir)
|
|
||||||
bit2bin(
|
|
||||||
build_dir / "top.bit",
|
|
||||||
REPO_ROOT_DIR / "linien-server" / "linien_server" / "gateware.bin",
|
|
||||||
diff --git a/gateware/linien_module.py b/gateware/linien_module.py
|
|
||||||
index 16ca186..6905ac0 100644
|
|
||||||
--- a/gateware/linien_module.py
|
|
||||||
+++ b/gateware/linien_module.py
|
|
||||||
@@ -1,6 +1,7 @@
|
|
||||||
# This file is part of Linien and based on redpid.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2016-2024 Linien Authors (https://github.com/linien-org/linien#license)
|
|
||||||
+# Copyright 2023 Jakub Matyas <jakubk.m@gmail.com>
|
|
||||||
#
|
|
||||||
# Linien is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
@@ -36,19 +37,13 @@ from misoc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage
|
|
||||||
from .logic.autolock import FPGAAutolock
|
|
||||||
from .logic.chains import FastChain, SlowChain, cross_connect
|
|
||||||
from .logic.decimation import Decimate
|
|
||||||
-from .logic.delta_sigma import DeltaSigma
|
|
||||||
from .logic.iir import Iir
|
|
||||||
from .logic.limit import LimitCSR
|
|
||||||
from .logic.modulate import Modulate
|
|
||||||
from .logic.pid import PID
|
|
||||||
from .logic.sweep import SweepCSR
|
|
||||||
-from .lowlevel.analog import PitayaAnalog
|
|
||||||
-from .lowlevel.crg import CRG
|
|
||||||
-from .lowlevel.dna import DNA
|
|
||||||
-from .lowlevel.gpio import Gpio
|
|
||||||
-from .lowlevel.pitaya_ps import PitayaPS, Sys2CSR, SysCDC, SysInterconnect
|
|
||||||
+from .lowlevel.pitaya_ps import Sys2CSR
|
|
||||||
from .lowlevel.scopegen import ScopeGen
|
|
||||||
-from .lowlevel.xadc import XADC
|
|
||||||
|
|
||||||
|
|
||||||
class LinienLogic(Module, AutoCSR):
|
|
||||||
@@ -156,45 +151,24 @@ class LinienLogic(Module, AutoCSR):
|
|
||||||
|
|
||||||
|
|
||||||
class LinienModule(Module, AutoCSR):
|
|
||||||
- def __init__(self, platform):
|
|
||||||
+ def __init__(self, soc):
|
|
||||||
width = 14
|
|
||||||
signal_width = 25
|
|
||||||
coeff_width = 25
|
|
||||||
chain_factor_bits = 8
|
|
||||||
|
|
||||||
self.init_submodules(
|
|
||||||
- width, signal_width, coeff_width, chain_factor_bits, platform
|
|
||||||
+ width, signal_width, coeff_width, chain_factor_bits, soc
|
|
||||||
)
|
|
||||||
- self.connect_everything(width, signal_width, coeff_width, chain_factor_bits)
|
|
||||||
+ self.connect_everything(width, signal_width, coeff_width, chain_factor_bits, soc)
|
|
||||||
|
|
||||||
def init_submodules(
|
|
||||||
- self, width, signal_width, coeff_width, chain_factor_bits, platform
|
|
||||||
+ self, width, signal_width, coeff_width, chain_factor_bits, soc
|
|
||||||
):
|
|
||||||
- sys_double = ClockDomainsRenamer("sys_double")
|
|
||||||
|
|
||||||
self.submodules.logic = LinienLogic(
|
|
||||||
coeff_width=coeff_width, chain_factor_width=chain_factor_bits
|
|
||||||
)
|
|
||||||
- self.submodules.analog = PitayaAnalog(
|
|
||||||
- platform.request("adc"), platform.request("dac")
|
|
||||||
- )
|
|
||||||
- self.submodules.xadc = XADC(platform.request("xadc"))
|
|
||||||
-
|
|
||||||
- for i in range(4):
|
|
||||||
- pwm = platform.request("pwm", i)
|
|
||||||
- ds = sys_double(DeltaSigma(width=15))
|
|
||||||
- self.comb += pwm.eq(ds.out)
|
|
||||||
- setattr(self.submodules, f"ds{i}", ds)
|
|
||||||
-
|
|
||||||
- exp = platform.request("exp")
|
|
||||||
- self.submodules.gpio_n = Gpio(exp.n)
|
|
||||||
- self.submodules.gpio_p = Gpio(exp.p)
|
|
||||||
-
|
|
||||||
- leds = Cat(*(platform.request("user_led", i) for i in range(8)))
|
|
||||||
- self.comb += leds.eq(self.gpio_n.o)
|
|
||||||
-
|
|
||||||
- self.submodules.dna = DNA(version=2)
|
|
||||||
-
|
|
||||||
self.submodules.fast_a = FastChain(
|
|
||||||
width,
|
|
||||||
signal_width,
|
|
||||||
@@ -210,18 +184,22 @@ class LinienModule(Module, AutoCSR):
|
|
||||||
offset_signal=self.logic.chain_b_offset_signed,
|
|
||||||
)
|
|
||||||
|
|
||||||
+ # FIXME: does it do anything?!
|
|
||||||
_ = ClockDomainsRenamer("sys_slow")
|
|
||||||
sys_double = ClockDomainsRenamer("sys_double")
|
|
||||||
max_decimation = 16
|
|
||||||
self.submodules.decimate = sys_double(Decimate(max_decimation))
|
|
||||||
self.clock_domains.cd_decimated_clock = ClockDomain()
|
|
||||||
decimated_clock = ClockDomainsRenamer("decimated_clock")
|
|
||||||
+ # TODO: No support for slow Analog Out on Fast Servo
|
|
||||||
self.submodules.slow_chain = decimated_clock(SlowChain())
|
|
||||||
-
|
|
||||||
self.submodules.scopegen = ScopeGen(signal_width)
|
|
||||||
|
|
||||||
+ soc.add_interconnect_slave(self.scopegen.scope_sys)
|
|
||||||
+ soc.add_interconnect_slave(self.scopegen.asg_sys)
|
|
||||||
+
|
|
||||||
self.state_names, self.signal_names = cross_connect(
|
|
||||||
- self.gpio_n,
|
|
||||||
+ soc.gpio_n,
|
|
||||||
[
|
|
||||||
("fast_a", self.fast_a),
|
|
||||||
("fast_b", self.fast_b),
|
|
||||||
@@ -233,10 +211,6 @@ class LinienModule(Module, AutoCSR):
|
|
||||||
)
|
|
||||||
|
|
||||||
csr_map = {
|
|
||||||
- "dna": 28,
|
|
||||||
- "xadc": 29,
|
|
||||||
- "gpio_n": 30,
|
|
||||||
- "gpio_p": 31,
|
|
||||||
"fast_a": 0,
|
|
||||||
"fast_b": 1,
|
|
||||||
"slow_chain": 2,
|
|
||||||
@@ -251,19 +225,13 @@ class LinienModule(Module, AutoCSR):
|
|
||||||
name if mem is None else name + "_" + mem.name_override
|
|
||||||
],
|
|
||||||
)
|
|
||||||
- self.submodules.sys2csr = Sys2CSR()
|
|
||||||
- self.submodules.csrcon = csr_bus.Interconnect(
|
|
||||||
- self.sys2csr.csr, self.csrbanks.get_buses()
|
|
||||||
- )
|
|
||||||
- self.submodules.syscdc = SysCDC()
|
|
||||||
- self.comb += self.syscdc.target.connect(self.sys2csr.sys)
|
|
||||||
|
|
||||||
- def connect_everything(self, width, signal_width, coeff_width, chain_factor_bits):
|
|
||||||
+ def connect_everything(self, width, signal_width, coeff_width, chain_factor_bits, soc):
|
|
||||||
s = signal_width - width
|
|
||||||
|
|
||||||
self.comb += [
|
|
||||||
- self.fast_a.adc.eq(self.analog.adc_a),
|
|
||||||
- self.fast_b.adc.eq(self.analog.adc_b),
|
|
||||||
+ self.fast_a.adc.eq(soc.analog.adc_a),
|
|
||||||
+ self.fast_b.adc.eq(soc.analog.adc_b),
|
|
||||||
]
|
|
||||||
|
|
||||||
# now, we combine the output of the two paths, with a variable factor each.
|
|
||||||
@@ -297,7 +265,7 @@ class LinienModule(Module, AutoCSR):
|
|
||||||
self.comb += [
|
|
||||||
If(
|
|
||||||
self.logic.pid_only_mode.storage,
|
|
||||||
- self.logic.pid.input.eq(self.analog.adc_a << s),
|
|
||||||
+ self.logic.pid.input.eq(soc.analog.adc_a << s),
|
|
||||||
).Else(
|
|
||||||
self.logic.pid.input.eq(mixed_limited),
|
|
||||||
),
|
|
||||||
@@ -347,40 +315,42 @@ class LinienModule(Module, AutoCSR):
|
|
||||||
# ANALOG OUTPUTS ---------------------------------------------------------------
|
|
||||||
# ANALOG OUT 0 gets a special treatment because it may contain signal of slow
|
|
||||||
# pid or sweep
|
|
||||||
- analog_out = Signal((width + 3, True))
|
|
||||||
- self.comb += [
|
|
||||||
- analog_out.eq(
|
|
||||||
- Mux(
|
|
||||||
- self.logic.sweep_channel.storage == OutputChannel.ANALOG_OUT0,
|
|
||||||
- self.logic.sweep.y,
|
|
||||||
- 0,
|
|
||||||
- )
|
|
||||||
- + Mux(
|
|
||||||
- self.logic.sweep_channel.storage == OutputChannel.ANALOG_OUT0,
|
|
||||||
- self.logic.out_offset_signed,
|
|
||||||
- 0,
|
|
||||||
- )
|
|
||||||
- + Mux(
|
|
||||||
- self.logic.slow_control_channel.storage
|
|
||||||
+
|
|
||||||
+ if soc.soc_name == "RedPitaya":
|
|
||||||
+ analog_out = Signal((width + 3, True))
|
|
||||||
+ self.comb += [
|
|
||||||
+ analog_out.eq(
|
|
||||||
+ Mux(
|
|
||||||
+ self.logic.sweep_channel.storage == OutputChannel.ANALOG_OUT0,
|
|
||||||
+ self.logic.sweep.y,
|
|
||||||
+ 0,
|
|
||||||
+ )
|
|
||||||
+ + Mux(
|
|
||||||
+ self.logic.sweep_channel.storage == OutputChannel.ANALOG_OUT0,
|
|
||||||
+ self.logic.out_offset_signed,
|
|
||||||
+ 0,
|
|
||||||
+ )
|
|
||||||
+ + Mux(
|
|
||||||
+ self.logic.slow_control_channel.storage
|
|
||||||
== OutputChannel.ANALOG_OUT0,
|
|
||||||
self.slow_chain.output,
|
|
||||||
- 0,
|
|
||||||
- )
|
|
||||||
- ),
|
|
||||||
- ]
|
|
||||||
- # NOTE: not sure why limit is used
|
|
||||||
- self.comb += self.slow_chain.limit.x.eq(analog_out)
|
|
||||||
- # ds0 apparently has 16 bit, but only allowing positive values --> "15 bit"?
|
|
||||||
- slow_out_shifted = Signal(15)
|
|
||||||
- self.sync += slow_out_shifted.eq((self.slow_chain.limit.y << 1) + (1 << 14))
|
|
||||||
- self.comb += self.ds0.data.eq(slow_out_shifted)
|
|
||||||
-
|
|
||||||
- # connect other analog outputs
|
|
||||||
- self.comb += [
|
|
||||||
- self.ds1.data.eq(self.logic.analog_out_1.storage),
|
|
||||||
- self.ds2.data.eq(self.logic.analog_out_2.storage),
|
|
||||||
- self.ds3.data.eq(self.logic.analog_out_3.storage),
|
|
||||||
- ]
|
|
||||||
+ 0,
|
|
||||||
+ )
|
|
||||||
+ ),
|
|
||||||
+ ]
|
|
||||||
+ # NOTE: not sure why limit is used
|
|
||||||
+ self.comb += self.slow_chain.limit.x.eq(analog_out)
|
|
||||||
+ # ds0 apparently has 16 bit, but only allowing positive values --> "15 bit"?
|
|
||||||
+ slow_out_shifted = Signal(15)
|
|
||||||
+ self.sync += slow_out_shifted.eq((self.slow_chain.limit.y << 1) + (1 << 14))
|
|
||||||
+ self.comb += soc.ds0.data.eq(slow_out_shifted)
|
|
||||||
+
|
|
||||||
+ # connect other analog outputs
|
|
||||||
+ self.comb += [
|
|
||||||
+ soc.ds1.data.eq(self.logic.analog_out_1.storage),
|
|
||||||
+ soc.ds2.data.eq(self.logic.analog_out_2.storage),
|
|
||||||
+ soc.ds3.data.eq(self.logic.analog_out_3.storage),
|
|
||||||
+ ]
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
@@ -395,7 +365,7 @@ class LinienModule(Module, AutoCSR):
|
|
||||||
|
|
||||||
self.comb += [
|
|
||||||
self.logic.autolock.robust.at_start.eq(self.logic.sweep.sweep.trigger),
|
|
||||||
- self.scopegen.gpio_trigger.eq(self.gpio_p.i[0]),
|
|
||||||
+ self.scopegen.gpio_trigger.eq(soc.gpio_p.i[0]),
|
|
||||||
self.scopegen.sweep_trigger.eq(self.logic.sweep.sweep.trigger),
|
|
||||||
self.scopegen.automatically_rearm.eq(
|
|
||||||
self.logic.autolock.request_lock.storage
|
|
||||||
@@ -404,8 +374,8 @@ class LinienModule(Module, AutoCSR):
|
|
||||||
self.scopegen.automatically_trigger.eq(
|
|
||||||
self.logic.autolock.lock_running.status
|
|
||||||
),
|
|
||||||
- self.analog.dac_a.eq(self.logic.limit_fast1.y),
|
|
||||||
- self.analog.dac_b.eq(self.logic.limit_fast2.y),
|
|
||||||
+ soc.analog.dac_a.eq(self.logic.limit_fast1.y),
|
|
||||||
+ soc.analog.dac_b.eq(self.logic.limit_fast2.y),
|
|
||||||
]
|
|
||||||
|
|
||||||
# Having this in a comb statement caused errors. See PR #251.
|
|
||||||
@@ -428,23 +398,4 @@ class DummyHK(Module, AutoCSR):
|
|
||||||
self.submodules.csrcon = csr_bus.Interconnect(
|
|
||||||
self.sys2csr.csr, self.csrbanks.get_buses()
|
|
||||||
)
|
|
||||||
- self.sys = self.sys2csr.sys
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-class RootModule(Module):
|
|
||||||
- def __init__(self, platform):
|
|
||||||
- self.submodules.ps = PitayaPS(platform.request("cpu"))
|
|
||||||
- self.submodules.crg = CRG(
|
|
||||||
- platform.request("clk125"), self.ps.fclk[0], ~self.ps.frstn[0]
|
|
||||||
- )
|
|
||||||
- self.submodules.linien = LinienModule(platform)
|
|
||||||
-
|
|
||||||
- self.submodules.hk = ClockDomainsRenamer("sys_ps")(DummyHK())
|
|
||||||
-
|
|
||||||
- self.submodules.ic = SysInterconnect(
|
|
||||||
- self.ps.axi.sys,
|
|
||||||
- self.hk.sys,
|
|
||||||
- self.linien.scopegen.scope_sys,
|
|
||||||
- self.linien.scopegen.asg_sys,
|
|
||||||
- self.linien.syscdc.source,
|
|
||||||
- )
|
|
||||||
+ self.sys = self.sys2csr.sys
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/gateware/targets/__init__.py b/gateware/targets/__init__.py
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..e69de29
|
|
||||||
diff --git a/gateware/targets/fast_servo.py b/gateware/targets/fast_servo.py
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..da5bf3b
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/gateware/targets/fast_servo.py
|
|
||||||
@@ -0,0 +1,85 @@
|
|
||||||
+# Copyright 2023 Jakub Matyas <jakubk.m@gmail.com>
|
|
||||||
+# Warsaw University of Technology
|
|
||||||
+#
|
|
||||||
+# This file is part of Linien and provides support for Linien on
|
|
||||||
+# Fast Servo platform.
|
|
||||||
+#
|
|
||||||
+# Linien 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.
|
|
||||||
+#
|
|
||||||
+# Linien 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 Linien. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
+
|
|
||||||
+from fast_servo.gateware.fast_servo_soc import BaseSoC
|
|
||||||
+from migen import *
|
|
||||||
+from misoc.interconnect import csr_bus
|
|
||||||
+
|
|
||||||
+from gateware.linien_module import DummyHK, LinienModule
|
|
||||||
+from gateware.lowlevel.dna import DNA
|
|
||||||
+from gateware.lowlevel.gpio import Gpio
|
|
||||||
+from gateware.lowlevel.pitaya_ps import SysInterconnect
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+class FastServoAnalog(Module):
|
|
||||||
+ def __init__(self, adc, dac):
|
|
||||||
+ size = 14 # length of DAC
|
|
||||||
+
|
|
||||||
+ self.adc_a = Signal(size)
|
|
||||||
+ self.adc_b = Signal(size)
|
|
||||||
+ self.dac_a = Signal(size)
|
|
||||||
+ self.dac_b = Signal(size)
|
|
||||||
+
|
|
||||||
+ self.comb += [
|
|
||||||
+ self.adc_a.eq(adc.data_out[0][2:]),
|
|
||||||
+ self.adc_b.eq(adc.data_out[1][2:]),
|
|
||||||
+ ]
|
|
||||||
+
|
|
||||||
+ self.sync += [
|
|
||||||
+ dac.data_in[0].eq(self.dac_a),
|
|
||||||
+ dac.data_in[1].eq(self.dac_b),
|
|
||||||
+ ]
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+class LinienFastServo(BaseSoC):
|
|
||||||
+ def __init__(self, platform):
|
|
||||||
+ super().__init__(platform)
|
|
||||||
+
|
|
||||||
+ self.submodules.dna = DNA(version=2)
|
|
||||||
+
|
|
||||||
+ self.submodules.analog = FastServoAnalog(self.adc, self.dac)
|
|
||||||
+ gpios = platform.request("gpio")
|
|
||||||
+ self.submodules.gpio_n = Gpio(gpios.n)
|
|
||||||
+ # self.csr_devices.append("gpio_n")
|
|
||||||
+ self.submodules.gpio_p = Gpio(gpios.p)
|
|
||||||
+ # self.csr_devices.append("gpio_p")
|
|
||||||
+ self.csr_map.update({
|
|
||||||
+ "dna": 28,
|
|
||||||
+ "gpio_n": 30,
|
|
||||||
+ "gpio_p": 31,
|
|
||||||
+ })
|
|
||||||
+
|
|
||||||
+ # ---------------------------------------------
|
|
||||||
+ #
|
|
||||||
+ # FIXME - passing self to LinienModule
|
|
||||||
+ self.submodules.linien = LinienModule(self)
|
|
||||||
+
|
|
||||||
+ def soc_finalize(self):
|
|
||||||
+ self.add_interconnect_slave(self.syscdc.source)
|
|
||||||
+ self.submodules.csrbanks = csr_bus.CSRBankArray(self,
|
|
||||||
+ self.get_csr_dev_address)
|
|
||||||
+ self.submodules.csrcon = csr_bus.Interconnect(
|
|
||||||
+ self.sys2csr.csr, [*self.csrbanks.get_buses(), *self.linien.csrbanks.get_buses()]
|
|
||||||
+ )
|
|
||||||
+ self.submodules.hk = DummyHK()
|
|
||||||
+ self.submodules.interconnect = SysInterconnect(
|
|
||||||
+ self.axi2sys.sys,
|
|
||||||
+ self.hk.sys,
|
|
||||||
+ *self.interconnect_slaves
|
|
||||||
+ )
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/gateware/targets/red_pitaya.py b/gateware/targets/red_pitaya.py
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..c029e81
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/gateware/targets/red_pitaya.py
|
|
||||||
@@ -0,0 +1,103 @@
|
|
||||||
+# Copyright 2014-2015 Robert Jördens <jordens@gmail.com>
|
|
||||||
+# Copyright 2018-2022 Benjamin Wiegand <benjamin.wiegand@physik.hu-berlin.de>
|
|
||||||
+# Copyright 2021-2023 Bastian Leykauf <leykauf@physik.hu-berlin.de>
|
|
||||||
+# Copyright 2022 Christian Freier <christian.freier@nomadatomics.com>
|
|
||||||
+# Copyright 2023 Jakub Matyas <jakubk.m@gmail.com>
|
|
||||||
+#
|
|
||||||
+# This file is part of Linien and based on redpid.
|
|
||||||
+#
|
|
||||||
+# Linien 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.
|
|
||||||
+#
|
|
||||||
+# Linien 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 Linien. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
+
|
|
||||||
+from migen import *
|
|
||||||
+from misoc.interconnect import csr_bus
|
|
||||||
+from misoc.interconnect.csr import AutoCSR
|
|
||||||
+
|
|
||||||
+from gateware.linien_module import DummyHK, LinienModule
|
|
||||||
+from gateware.logic.delta_sigma import DeltaSigma
|
|
||||||
+from gateware.lowlevel.analog import PitayaAnalog
|
|
||||||
+from gateware.lowlevel.crg import CRG
|
|
||||||
+from gateware.lowlevel.dna import DNA
|
|
||||||
+from gateware.lowlevel.gpio import Gpio
|
|
||||||
+from gateware.lowlevel.pitaya_ps import PitayaPS, Sys2CSR, SysCDC, SysInterconnect
|
|
||||||
+from gateware.lowlevel.xadc import XADC
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+class PitayaSoC(Module, AutoCSR):
|
|
||||||
+ def __init__(self, platform):
|
|
||||||
+ self.csr_map = {
|
|
||||||
+ "gpio_n": 30,
|
|
||||||
+ "gpio_p": 31,
|
|
||||||
+ "dna": 28,
|
|
||||||
+ "xadc": 29,
|
|
||||||
+ }
|
|
||||||
+ self.soc_name = "RedPitaya"
|
|
||||||
+ self.interconnect_slaves = []
|
|
||||||
+
|
|
||||||
+ self.submodules.ps = PitayaPS(platform.request("cpu"))
|
|
||||||
+ self.submodules.crg = CRG(
|
|
||||||
+ platform.request("clk125"), self.ps.fclk[0], ~self.ps.frstn[0]
|
|
||||||
+ )
|
|
||||||
+ self.submodules.sys2csr = Sys2CSR()
|
|
||||||
+ self.submodules.syscdc = SysCDC()
|
|
||||||
+ self.comb += self.syscdc.target.connect(self.sys2csr.sys)
|
|
||||||
+
|
|
||||||
+ self.submodules.xadc = XADC(platform.request("xadc"))
|
|
||||||
+ self.submodules.analog = PitayaAnalog(platform.request("adc"), platform.request("dac"))
|
|
||||||
+
|
|
||||||
+ for i in range(4):
|
|
||||||
+ pwm = platform.request("pwm", i)
|
|
||||||
+ ds = ClockDomainsRenamer("sys_double")(DeltaSigma(width=15))
|
|
||||||
+ self.comb += pwm.eq(ds.out)
|
|
||||||
+ setattr(self.submodules, f"ds{i}", ds)
|
|
||||||
+
|
|
||||||
+ exp = platform.request("exp")
|
|
||||||
+ self.submodules.gpio_n = Gpio(exp.n)
|
|
||||||
+ self.submodules.gpio_p = Gpio(exp.p)
|
|
||||||
+
|
|
||||||
+ leds = Cat(*(platform.request("user_led", i) for i in range(8)))
|
|
||||||
+ self.comb += leds.eq(self.gpio_n.o)
|
|
||||||
+
|
|
||||||
+ self.submodules.dna = DNA(version=2)
|
|
||||||
+
|
|
||||||
+ # ---------------------------------------------
|
|
||||||
+ #
|
|
||||||
+ # FIXME - passing self to LinienModule
|
|
||||||
+ self.submodules.linien = LinienModule(self)
|
|
||||||
+ self.add_interconnect_slave(self.syscdc.source)
|
|
||||||
+ self.run_finalize()
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+ def add_interconnect_slave(self, slave):
|
|
||||||
+ self.interconnect_slaves.append(slave)
|
|
||||||
+
|
|
||||||
+ def get_csr_dev_address(self, name, memory):
|
|
||||||
+ if memory is not None:
|
|
||||||
+ name = name + "_" + memory.name_override
|
|
||||||
+ try:
|
|
||||||
+ return self.csr_map[name]
|
|
||||||
+ except KeyError:
|
|
||||||
+ return None
|
|
||||||
+
|
|
||||||
+ def run_finalize(self):
|
|
||||||
+ self.submodules.csrbanks = csr_bus.CSRBankArray(self,
|
|
||||||
+ self.get_csr_dev_address)
|
|
||||||
+ self.submodules.csrcon = csr_bus.Interconnect(
|
|
||||||
+ self.sys2csr.csr, [*self.csrbanks.get_buses(), *self.linien.csrbanks.get_buses()]
|
|
||||||
+ )
|
|
||||||
+ self.submodules.hk = DummyHK()
|
|
||||||
+ self.submodules.interconnect = SysInterconnect(
|
|
||||||
+ self.ps.axi.sys,
|
|
||||||
+ self.hk.sys,
|
|
||||||
+ *self.interconnect_slaves
|
|
||||||
+ )
|
|
||||||
\ No newline at end of file
|
|
@ -1,5 +0,0 @@
|
|||||||
## Source Repository
|
|
||||||
Files in this directory were copied from [elhep/Fast-Servo-Firmware](https://github.com/elhep/Fast-Servo-Firmware/tree/master/fast_servo/gateware).
|
|
||||||
|
|
||||||
## Commit ID
|
|
||||||
The files were copied from commit ID [7fae40c](https://github.com/elhep/Fast-Servo-Firmware/commit/7fae40c0f872a91218be378f8289b98b1e366729).
|
|
@ -1,3 +0,0 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
verilog_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "verilog")
|
|
@ -1,219 +0,0 @@
|
|||||||
# This file is part of Fast Servo Software Package.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2023 Jakub Matyas
|
|
||||||
# Warsaw University of Technology <jakubk.m@gmail.com>
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#
|
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
from migen import *
|
|
||||||
from migen.genlib.cdc import MultiReg
|
|
||||||
from misoc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage
|
|
||||||
from misoc.interconnect.stream import AsyncFIFO
|
|
||||||
|
|
||||||
|
|
||||||
class CRG(Module):
|
|
||||||
def __init__(self, platform, dco_clk, dco_freq=200e6):
|
|
||||||
self.clock_domains.cd_dco = ClockDomain()
|
|
||||||
self.clock_domains.cd_dco2x = ClockDomain()
|
|
||||||
self.clock_domains.cd_dco2d = ClockDomain()
|
|
||||||
self.clock_domains.cd_dco2d_45_degree = ClockDomain()
|
|
||||||
dco_clk_p, dco_clk_n = dco_clk
|
|
||||||
|
|
||||||
dco_clk_buf = Signal()
|
|
||||||
self.specials += Instance(
|
|
||||||
"IBUFGDS", i_I=dco_clk_p, i_IB=dco_clk_n, o_O=dco_clk_buf
|
|
||||||
)
|
|
||||||
|
|
||||||
# # #
|
|
||||||
clk_feedback = Signal()
|
|
||||||
clk_feedback_buf = Signal()
|
|
||||||
|
|
||||||
clk_dco = Signal()
|
|
||||||
clk_dco2x = Signal()
|
|
||||||
clk_dco2d = Signal()
|
|
||||||
clk_dco2d_45_degree = Signal()
|
|
||||||
mmcm_ps_psdone = Signal()
|
|
||||||
|
|
||||||
self.locked = Signal()
|
|
||||||
self.mmcm_rst = Signal()
|
|
||||||
self.ddr_clk_phase_shift_en = Signal()
|
|
||||||
self.ddr_clk_phase_incdec = Signal()
|
|
||||||
|
|
||||||
platform.add_period_constraint(dco_clk_p, 1e9 / dco_freq)
|
|
||||||
self.specials += [
|
|
||||||
Instance(
|
|
||||||
"MMCME2_ADV",
|
|
||||||
p_BANDWIDTH="OPTIMIZED",
|
|
||||||
p_DIVCLK_DIVIDE=1,
|
|
||||||
p_CLKFBOUT_PHASE=0.0,
|
|
||||||
p_CLKFBOUT_MULT_F=4, # VCO @ 800 MHz
|
|
||||||
p_CLKIN1_PERIOD=(1e9 / dco_freq),
|
|
||||||
p_REF_JITTER1=0.01,
|
|
||||||
p_STARTUP_WAIT="FALSE",
|
|
||||||
i_CLKIN1=dco_clk_buf,
|
|
||||||
i_PWRDWN=0,
|
|
||||||
i_RST=ResetSignal("sys") | self.mmcm_rst,
|
|
||||||
i_CLKFBIN=clk_feedback_buf,
|
|
||||||
o_CLKFBOUT=clk_feedback,
|
|
||||||
|
|
||||||
p_CLKOUT0_USE_FINE_PS="TRUE",
|
|
||||||
p_CLKOUT0_DIVIDE_F=8,
|
|
||||||
p_CLKOUT0_PHASE=45.0,
|
|
||||||
p_CLKOUT0_DUTY_CYCLE=0.5,
|
|
||||||
o_CLKOUT0=clk_dco2d_45_degree, # 100 MHz <- dco_clk / 2 = 200 MHz / 2
|
|
||||||
o_LOCKED=self.locked,
|
|
||||||
|
|
||||||
p_CLKOUT1_DIVIDE=2,
|
|
||||||
p_CLKOUT1_PHASE=0.0,
|
|
||||||
p_CLKOUT1_DUTY_CYCLE=0.5,
|
|
||||||
o_CLKOUT1=clk_dco2x, # 400 MHZ <- 2 * dco_clk = 2*200 MHz
|
|
||||||
|
|
||||||
p_CLKOUT2_DIVIDE=8,
|
|
||||||
p_CLKOUT2_PHASE=0.0,
|
|
||||||
p_CLKOUT2_DUTY_CYCLE=0.5,
|
|
||||||
o_CLKOUT2=clk_dco2d, # 100 MHz <- dco_clk / 2 = 200 MHz / 2
|
|
||||||
|
|
||||||
p_CLKOUT3_DIVIDE=4,
|
|
||||||
p_CLKOUT3_PHASE=0.0,
|
|
||||||
p_CLKOUT3_DUTY_CYCLE=0.5,
|
|
||||||
o_CLKOUT3=clk_dco, # 200 MHz <- dco_clk
|
|
||||||
|
|
||||||
i_PSCLK=ClockSignal(),
|
|
||||||
i_PSEN=self.ddr_clk_phase_shift_en,
|
|
||||||
i_PSINCDEC=self.ddr_clk_phase_incdec,
|
|
||||||
o_PSDONE=mmcm_ps_psdone,
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
self.specials += Instance("BUFG", i_I=clk_feedback, o_O=clk_feedback_buf)
|
|
||||||
self.specials += Instance("BUFG", i_I=clk_dco, o_O=self.cd_dco.clk)
|
|
||||||
self.specials += Instance("BUFG", i_I=clk_dco2d, o_O=self.cd_dco2d.clk)
|
|
||||||
self.specials += Instance("BUFG", i_I=clk_dco2d_45_degree, o_O=self.cd_dco2d_45_degree.clk)
|
|
||||||
self.specials += Instance("BUFG", i_I=clk_dco2x, o_O=self.cd_dco2x.clk)
|
|
||||||
|
|
||||||
# Ignore dco2d to mmcm dco_clk path created by SoC's rst.
|
|
||||||
platform.add_false_path_constraints(self.cd_dco2d.clk, dco_clk_buf)
|
|
||||||
self.specials += Instance("FD", p_INIT=1, i_D=~self.locked, i_C=self.cd_dco2d.clk, o_Q=self.cd_dco2d.rst)
|
|
||||||
|
|
||||||
class ADC(Module, AutoCSR):
|
|
||||||
def __init__(self, platform, dco_freq=200e6):
|
|
||||||
adc_pads = platform.request("adc")
|
|
||||||
afe_pads = platform.request("adc_afe")
|
|
||||||
|
|
||||||
self.frame_csr = CSRStatus(5)
|
|
||||||
self.data_ch0 = CSRStatus(16)
|
|
||||||
self.data_ch1 = CSRStatus(16)
|
|
||||||
|
|
||||||
self.tap_delay = CSRStorage(5)
|
|
||||||
self.bitslip_csr = CSRStorage(1)
|
|
||||||
|
|
||||||
self.afe_ctrl = CSRStorage(7)
|
|
||||||
|
|
||||||
tap_delay_val = Signal(5)
|
|
||||||
bitslip = Signal()
|
|
||||||
bitslip_re_dco_2d = Signal()
|
|
||||||
|
|
||||||
ch1_gain_x10 = Signal()
|
|
||||||
ch2_gain_x10 = Signal()
|
|
||||||
ch1_shdn = Signal()
|
|
||||||
ch2_shdn = Signal()
|
|
||||||
|
|
||||||
self.data_out = [Signal(16, reset_less=True), Signal(16, reset_less=True)]
|
|
||||||
self.data_out_cdc = [Signal(16, reset_less=True), Signal(16, reset_less=True)]
|
|
||||||
self.s_frame = Signal(4)
|
|
||||||
self.s_frame_cdc = Signal(4)
|
|
||||||
|
|
||||||
self.submodules.cdc_fifo = ClockDomainsRenamer({"write": "dco2d", "read": "sys"})(AsyncFIFO([("data", 36)], 4))
|
|
||||||
self.comb += [
|
|
||||||
self.cdc_fifo.sink.data.eq(Cat(self.data_out_cdc[0], self.data_out_cdc[1], self.s_frame_cdc)),
|
|
||||||
self.cdc_fifo.sink.stb.eq(~ResetSignal("dco2d")),
|
|
||||||
Cat(self.data_out[0], self.data_out[1], self.s_frame).eq(self.cdc_fifo.source.data),
|
|
||||||
self.cdc_fifo.source.ack.eq(~ResetSignal("sys")),
|
|
||||||
]
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
# DCO clock coming from LTC2195
|
|
||||||
# dco_clk = Record([("p", 1), ("n", 1)])
|
|
||||||
dco_clk =(adc_pads.dco_p, adc_pads.dco_n)
|
|
||||||
self.comb += [
|
|
||||||
# dco_clk.p.eq(adc_pads.dco_p),
|
|
||||||
# dco_clk.n.eq(adc_pads.dco_n),
|
|
||||||
tap_delay_val.eq(self.tap_delay.storage),
|
|
||||||
Cat(ch1_gain_x10, ch2_gain_x10, ch1_shdn, ch2_shdn).eq(
|
|
||||||
self.afe_ctrl.storage[0:4]
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
self.submodules.crg = CRG(platform, dco_clk, dco_freq)
|
|
||||||
self.comb += self.afe_ctrl.storage[4].eq(self.crg.mmcm_rst)
|
|
||||||
self.comb += self.afe_ctrl.storage[5].eq(self.crg.ddr_clk_phase_shift_en)
|
|
||||||
self.comb += self.afe_ctrl.storage[6].eq(self.crg.ddr_clk_phase_incdec)
|
|
||||||
|
|
||||||
self.specials += MultiReg(self.bitslip_csr.re, bitslip_re_dco_2d, "dco2d")
|
|
||||||
self.sync.dco2d += [
|
|
||||||
bitslip.eq(Mux(bitslip_re_dco_2d, self.bitslip_csr.storage, 0))
|
|
||||||
]
|
|
||||||
|
|
||||||
self.comb += [
|
|
||||||
self.frame_csr.status[0:4].eq(self.s_frame[0:4]),
|
|
||||||
self.frame_csr.status[4].eq(self.crg.locked),
|
|
||||||
self.data_ch0.status.eq(self.data_out[0]),
|
|
||||||
self.data_ch1.status.eq(self.data_out[1]),
|
|
||||||
]
|
|
||||||
|
|
||||||
self.comb += [
|
|
||||||
afe_pads.ch1_gain.eq(ch1_gain_x10),
|
|
||||||
afe_pads.ch2_gain.eq(ch2_gain_x10),
|
|
||||||
afe_pads.nshdn_ch1.eq(~ch1_shdn),
|
|
||||||
afe_pads.nshdn_ch2.eq(~ch2_shdn),
|
|
||||||
]
|
|
||||||
|
|
||||||
dummy = Signal(8)
|
|
||||||
dummy_idelay_rdy = Signal()
|
|
||||||
|
|
||||||
self.specials += Instance(
|
|
||||||
"LTC2195",
|
|
||||||
i_rst_in=ResetSignal("dco2d"),
|
|
||||||
i_clk200=ClockSignal("idelay"),
|
|
||||||
i_DCO=ClockSignal("dco"),
|
|
||||||
i_DCO_2D=ClockSignal("dco2d"),
|
|
||||||
i_FR_in_p=adc_pads.frame_p,
|
|
||||||
i_FR_in_n=adc_pads.frame_n,
|
|
||||||
i_D0_in_p=adc_pads.data0_p,
|
|
||||||
i_D0_in_n=adc_pads.data0_n,
|
|
||||||
i_D1_in_p=adc_pads.data1_p,
|
|
||||||
i_D1_in_n=adc_pads.data1_n,
|
|
||||||
i_bitslip=bitslip,
|
|
||||||
i_delay_val=tap_delay_val,
|
|
||||||
o_ADC0_out=self.data_out_cdc[1], # LANES swapped on hardware
|
|
||||||
o_ADC1_out=self.data_out_cdc[0],
|
|
||||||
o_FR_out=self.s_frame_cdc,
|
|
||||||
o_o_data_from_pins=dummy,
|
|
||||||
o_idelay_rdy=dummy_idelay_rdy,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class AUX_ADC_CTRL(Module, AutoCSR):
|
|
||||||
def __init__(self, platform):
|
|
||||||
adc_aux_pads = platform.request("aux_adc")
|
|
||||||
|
|
||||||
self.adc_aux_ctrl = CSRStorage(5)
|
|
||||||
|
|
||||||
self.comb += [
|
|
||||||
adc_aux_pads.diff_n.eq(~self.adc_aux_ctrl.storage[0]),
|
|
||||||
adc_aux_pads.a.eq(self.adc_aux_ctrl.storage[1:4]),
|
|
||||||
adc_aux_pads.range.eq(self.adc_aux_ctrl.storage[4]),
|
|
||||||
]
|
|
@ -1,99 +0,0 @@
|
|||||||
# This file is part of Fast Servo Software Package.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2023 Jakub Matyas
|
|
||||||
# Warsaw University of Technology <jakubk.m@gmail.com>
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#
|
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
from migen import *
|
|
||||||
from misoc.interconnect.csr import AutoCSR, CSRStorage
|
|
||||||
from migen.genlib.io import DDROutput
|
|
||||||
from misoc.interconnect.stream import AsyncFIFO
|
|
||||||
|
|
||||||
|
|
||||||
class DAC(Module, AutoCSR):
|
|
||||||
def __init__(self, platform):
|
|
||||||
dac_pads = platform.request("dac")
|
|
||||||
dac_afe_pads = platform.request("dac_afe")
|
|
||||||
self.dac_ctrl = CSRStorage(3)
|
|
||||||
self.output_value_ch0 = CSRStorage(14)
|
|
||||||
self.output_value_ch1 = CSRStorage(14)
|
|
||||||
|
|
||||||
manual_override = Signal()
|
|
||||||
ch0_pd = Signal()
|
|
||||||
ch1_pd = Signal()
|
|
||||||
|
|
||||||
output_data_ch0 = Signal(14)
|
|
||||||
output_data_ch1 = Signal(14)
|
|
||||||
|
|
||||||
self.data_in = [Signal(14, reset_less=True), Signal(14, reset_less=True)]
|
|
||||||
self.data_in_csr = [Signal(14, reset_less=True), Signal(14, reset_less=True)]
|
|
||||||
|
|
||||||
self.data_in_cdc = [Signal(14, reset_less=True), Signal(14, reset_less=True)]
|
|
||||||
self.data_in_csr_cdc = [Signal(14, reset_less=True), Signal(14, reset_less=True)]
|
|
||||||
platform.add_period_constraint(dac_pads.dclkio, 10.0)
|
|
||||||
|
|
||||||
self.submodules.cdc_fifo = ClockDomainsRenamer({"write": "sys", "read": "dco2d"})(AsyncFIFO([("data", 56)], 4))
|
|
||||||
self.comb += [
|
|
||||||
self.data_in_csr[0].eq(self.output_value_ch0.storage),
|
|
||||||
self.data_in_csr[1].eq(self.output_value_ch1.storage),
|
|
||||||
self.cdc_fifo.sink.data.eq(Cat(self.data_in[0], self.data_in[1], self.data_in_csr[0], self.data_in_csr[1])),
|
|
||||||
self.cdc_fifo.sink.stb.eq(~ResetSignal("sys")),
|
|
||||||
Cat(self.data_in_cdc[0], self.data_in_cdc[1], self.data_in_csr_cdc[0], self.data_in_csr_cdc[1]).eq(self.cdc_fifo.source.data),
|
|
||||||
self.cdc_fifo.source.ack.eq(~ResetSignal("dco2d")),
|
|
||||||
]
|
|
||||||
|
|
||||||
self.comb += [
|
|
||||||
Cat(manual_override, ch0_pd, ch1_pd).eq(self.dac_ctrl.storage),
|
|
||||||
dac_pads.rst.eq(ResetSignal("dco2d")),
|
|
||||||
dac_afe_pads.ch1_pd_n.eq(~ch0_pd),
|
|
||||||
dac_afe_pads.ch2_pd_n.eq(~ch1_pd),
|
|
||||||
output_data_ch0.eq(
|
|
||||||
Mux(manual_override, self.data_in_csr_cdc[0], self.data_in_cdc[0])
|
|
||||||
),
|
|
||||||
output_data_ch1.eq(
|
|
||||||
Mux(manual_override, self.data_in_csr_cdc[1], self.data_in_cdc[1])
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
self.specials += [
|
|
||||||
Instance("ODDR",
|
|
||||||
i_C=ClockSignal("dco2d"),
|
|
||||||
i_CE=~ResetSignal("dco2d"),
|
|
||||||
i_D1=output_data_ch0[lane], # DDR CLK Rising Edge
|
|
||||||
i_D2=output_data_ch1[lane], # DDR CLK Falling Edge
|
|
||||||
o_Q=dac_pads.data[lane],
|
|
||||||
p_DDR_CLK_EDGE="SAME_EDGE")
|
|
||||||
for lane in range(14)]
|
|
||||||
self.specials += Instance("ODDR",
|
|
||||||
i_C=ClockSignal("dco2d_45_degree"),
|
|
||||||
i_CE=~ResetSignal("dco2d"),
|
|
||||||
i_D1=0,
|
|
||||||
i_D2=1,
|
|
||||||
o_Q=dac_pads.dclkio,
|
|
||||||
p_DDR_CLK_EDGE="SAME_EDGE")
|
|
||||||
|
|
||||||
|
|
||||||
class AUX_DAC_CTRL(Module, AutoCSR):
|
|
||||||
def __init__(self, platform):
|
|
||||||
dac_aux_pads = platform.request("aux_dac")
|
|
||||||
|
|
||||||
self.dac_aux_ctrl = CSRStorage(3)
|
|
||||||
|
|
||||||
self.comb += [
|
|
||||||
dac_aux_pads.nclr.eq(~self.dac_aux_ctrl.storage[0]),
|
|
||||||
dac_aux_pads.bin.eq(self.dac_aux_ctrl.storage[1]),
|
|
||||||
dac_aux_pads.nldac.eq(~self.dac_aux_ctrl.storage[2]),
|
|
||||||
]
|
|
@ -1,385 +0,0 @@
|
|||||||
# Copyright 2014-2015 Robert Jördens <jordens@gmail.com>
|
|
||||||
# Copyright 2018-2022 Benjamin Wiegand <benjamin.wiegand@physik.hu-berlin.de>
|
|
||||||
# Copyright 2021-2022 Bastian Leykauf <leykauf@physik.hu-berlin.de>
|
|
||||||
# Copyright 2023 Jakub Matyas
|
|
||||||
# Warsaw University of Technology <jakubk.m@gmail.com>
|
|
||||||
#
|
|
||||||
# This file is part of Fast Servo Software Package and is based on Linien.
|
|
||||||
#
|
|
||||||
# Linien 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.
|
|
||||||
#
|
|
||||||
# Linien 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 Linien. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
from functools import reduce
|
|
||||||
from operator import or_
|
|
||||||
|
|
||||||
from migen import (
|
|
||||||
DIR_M_TO_S,
|
|
||||||
DIR_S_TO_M,
|
|
||||||
Cat,
|
|
||||||
ClockSignal,
|
|
||||||
If,
|
|
||||||
Instance,
|
|
||||||
Module,
|
|
||||||
Record,
|
|
||||||
Replicate,
|
|
||||||
ResetSignal,
|
|
||||||
Signal,
|
|
||||||
)
|
|
||||||
from misoc.interconnect import csr_bus, wishbone
|
|
||||||
|
|
||||||
sys_layout = [
|
|
||||||
("rstn", 1, DIR_M_TO_S),
|
|
||||||
("clk", 1, DIR_M_TO_S),
|
|
||||||
("addr", 32, DIR_M_TO_S),
|
|
||||||
("wdata", 32, DIR_M_TO_S),
|
|
||||||
("sel", 4, DIR_M_TO_S),
|
|
||||||
("wen", 1, DIR_M_TO_S),
|
|
||||||
("ren", 1, DIR_M_TO_S),
|
|
||||||
("rdata", 32, DIR_S_TO_M),
|
|
||||||
("err", 1, DIR_S_TO_M),
|
|
||||||
("ack", 1, DIR_S_TO_M),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
axi_layout = [
|
|
||||||
("arvalid", 1),
|
|
||||||
("awvalid", 1),
|
|
||||||
("bready", 1),
|
|
||||||
("rready", 1),
|
|
||||||
("wlast", 1),
|
|
||||||
("wvalid", 1),
|
|
||||||
("arid", 12),
|
|
||||||
("awid", 12),
|
|
||||||
("wid", 12),
|
|
||||||
("arburst", 2),
|
|
||||||
("arlock", 2),
|
|
||||||
("arsize", 3),
|
|
||||||
("awburst", 2),
|
|
||||||
("awlock", 2),
|
|
||||||
("awsize", 3),
|
|
||||||
("arprot", 3),
|
|
||||||
("awprot", 3),
|
|
||||||
("araddr", 32),
|
|
||||||
("awaddr", 32),
|
|
||||||
("wdata", 32),
|
|
||||||
("arcache", 4),
|
|
||||||
("arlen", 4),
|
|
||||||
("arqos", 4),
|
|
||||||
("awcache", 4),
|
|
||||||
("awlen", 4),
|
|
||||||
("awqos", 4),
|
|
||||||
("wstrb", 4),
|
|
||||||
("aclk", 1),
|
|
||||||
("arready", 1),
|
|
||||||
("awready", 1),
|
|
||||||
("bvalid", 1),
|
|
||||||
("rlast", 1),
|
|
||||||
("rvalid", 1),
|
|
||||||
("wready", 1),
|
|
||||||
("bid", 12),
|
|
||||||
("rid", 12),
|
|
||||||
("bresp", 2),
|
|
||||||
("rresp", 2),
|
|
||||||
("rdata", 32),
|
|
||||||
("arstn", 1),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class PitayaPS(Module):
|
|
||||||
def __init__(self, cpu):
|
|
||||||
self.fclk = Signal(4)
|
|
||||||
self.frstn = Signal(4)
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
self.submodules.axi = Axi2Sys()
|
|
||||||
axi = self.axi.axi
|
|
||||||
self.comb += [
|
|
||||||
axi.aclk.eq(self.fclk[0]),
|
|
||||||
axi.arstn.eq(self.frstn[0]),
|
|
||||||
]
|
|
||||||
|
|
||||||
self.specials += Instance(
|
|
||||||
"system_processing_system7_0_0",
|
|
||||||
io_MIO=cpu.mio,
|
|
||||||
io_PS_CLK=cpu.ps_clk,
|
|
||||||
io_PS_PORB=cpu.ps_porb,
|
|
||||||
io_PS_SRSTB=cpu.ps_srstb,
|
|
||||||
io_DDR_Addr=cpu.DDR_addr,
|
|
||||||
io_DDR_BankAddr=cpu.DDR_ba,
|
|
||||||
io_DDR_CAS_n=cpu.DDR_cas_n,
|
|
||||||
io_DDR_Clk_n=cpu.DDR_ck_n,
|
|
||||||
io_DDR_Clk=cpu.DDR_ck_p,
|
|
||||||
io_DDR_CKE=cpu.DDR_cke,
|
|
||||||
io_DDR_CS_n=cpu.DDR_cs_n,
|
|
||||||
io_DDR_DM=cpu.DDR_dm,
|
|
||||||
io_DDR_DQ=cpu.DDR_dq,
|
|
||||||
io_DDR_DQS_n=cpu.DDR_dqs_n,
|
|
||||||
io_DDR_DQS=cpu.DDR_dqs_p,
|
|
||||||
io_DDR_ODT=cpu.DDR_odt,
|
|
||||||
io_DDR_RAS_n=cpu.DDR_ras_n,
|
|
||||||
io_DDR_DRSTB=cpu.DDR_reset_n,
|
|
||||||
io_DDR_WEB=cpu.DDR_we_n,
|
|
||||||
io_DDR_VRN=cpu.ddr_vrn,
|
|
||||||
io_DDR_VRP=cpu.ddr_vrp,
|
|
||||||
o_FCLK_CLK0=self.fclk[0],
|
|
||||||
o_FCLK_CLK1=self.fclk[1],
|
|
||||||
o_FCLK_CLK2=self.fclk[2],
|
|
||||||
o_FCLK_CLK3=self.fclk[3],
|
|
||||||
o_FCLK_RESET0_N=self.frstn[0],
|
|
||||||
o_FCLK_RESET1_N=self.frstn[1],
|
|
||||||
o_FCLK_RESET2_N=self.frstn[2],
|
|
||||||
o_FCLK_RESET3_N=self.frstn[3],
|
|
||||||
i_M_AXI_GP0_ACLK=axi.aclk,
|
|
||||||
o_M_AXI_GP0_ARVALID=axi.arvalid,
|
|
||||||
o_M_AXI_GP0_AWVALID=axi.awvalid,
|
|
||||||
o_M_AXI_GP0_BREADY=axi.bready,
|
|
||||||
o_M_AXI_GP0_RREADY=axi.rready,
|
|
||||||
o_M_AXI_GP0_WLAST=axi.wlast,
|
|
||||||
o_M_AXI_GP0_WVALID=axi.wvalid,
|
|
||||||
o_M_AXI_GP0_ARID=axi.arid,
|
|
||||||
o_M_AXI_GP0_AWID=axi.awid,
|
|
||||||
o_M_AXI_GP0_WID=axi.wid,
|
|
||||||
o_M_AXI_GP0_ARBURST=axi.arburst,
|
|
||||||
o_M_AXI_GP0_ARLOCK=axi.arlock,
|
|
||||||
o_M_AXI_GP0_ARSIZE=axi.arsize,
|
|
||||||
o_M_AXI_GP0_AWBURST=axi.awburst,
|
|
||||||
o_M_AXI_GP0_AWLOCK=axi.awlock,
|
|
||||||
o_M_AXI_GP0_AWSIZE=axi.awsize,
|
|
||||||
o_M_AXI_GP0_ARPROT=axi.arprot,
|
|
||||||
o_M_AXI_GP0_AWPROT=axi.awprot,
|
|
||||||
o_M_AXI_GP0_ARADDR=axi.araddr,
|
|
||||||
o_M_AXI_GP0_AWADDR=axi.awaddr,
|
|
||||||
o_M_AXI_GP0_WDATA=axi.wdata,
|
|
||||||
o_M_AXI_GP0_ARCACHE=axi.arcache,
|
|
||||||
o_M_AXI_GP0_ARLEN=axi.arlen,
|
|
||||||
o_M_AXI_GP0_ARQOS=axi.arqos,
|
|
||||||
o_M_AXI_GP0_AWCACHE=axi.awcache,
|
|
||||||
o_M_AXI_GP0_AWLEN=axi.awlen,
|
|
||||||
o_M_AXI_GP0_AWQOS=axi.awqos,
|
|
||||||
o_M_AXI_GP0_WSTRB=axi.wstrb,
|
|
||||||
i_M_AXI_GP0_ARREADY=axi.arready,
|
|
||||||
i_M_AXI_GP0_AWREADY=axi.awready,
|
|
||||||
i_M_AXI_GP0_BVALID=axi.bvalid,
|
|
||||||
i_M_AXI_GP0_RLAST=axi.rlast,
|
|
||||||
i_M_AXI_GP0_RVALID=axi.rvalid,
|
|
||||||
i_M_AXI_GP0_WREADY=axi.wready,
|
|
||||||
i_M_AXI_GP0_BID=axi.bid,
|
|
||||||
i_M_AXI_GP0_RID=axi.rid,
|
|
||||||
i_M_AXI_GP0_BRESP=axi.bresp,
|
|
||||||
i_M_AXI_GP0_RRESP=axi.rresp,
|
|
||||||
i_M_AXI_GP0_RDATA=axi.rdata,
|
|
||||||
i_SPI0_SS_I=0,
|
|
||||||
# i_SPI0_SS_I=spi.ss_i,
|
|
||||||
# o_SPI0_SS_O=spi.ss_o,
|
|
||||||
# o_SPI0_SS_T=spi.ss_t,
|
|
||||||
# o_SPI0_SS1_O=spi.ss1_o,
|
|
||||||
# o_SPI0_SS2_O=spi.ss2_o,
|
|
||||||
i_SPI0_SCLK_I=0,
|
|
||||||
# i_SPI0_SCLK_I=spi.sclk_i,
|
|
||||||
# o_SPI0_SCLK_O=spi.sclk_o,
|
|
||||||
# o_SPI0_SCLK_T=spi.sclk_t,
|
|
||||||
i_SPI0_MOSI_I=0,
|
|
||||||
# i_SPI0_MOSI_I=spi.mosi_i,
|
|
||||||
# o_SPI0_MOSI_O=spi.mosi_o,
|
|
||||||
# o_SPI0_MOSI_T=spi.mosi_t,
|
|
||||||
i_SPI0_MISO_I=0,
|
|
||||||
# i_SPI0_MISO_I=spi.miso_i,
|
|
||||||
# o_SPI0_MISO_O=spi.miso_o,
|
|
||||||
# o_SPI0_MISO_T=spi.miso_t,
|
|
||||||
i_USB0_VBUS_PWRFAULT=0,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Axi2Sys(Module):
|
|
||||||
def __init__(self):
|
|
||||||
self.sys = Record(sys_layout)
|
|
||||||
self.axi = Record(axi_layout)
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
self.comb += [self.sys.clk.eq(self.axi.aclk), self.sys.rstn.eq(self.axi.arstn)]
|
|
||||||
|
|
||||||
self.specials += Instance(
|
|
||||||
"axi_slave",
|
|
||||||
p_AXI_DW=32,
|
|
||||||
p_AXI_AW=32,
|
|
||||||
p_AXI_IW=12,
|
|
||||||
i_axi_clk_i=self.axi.aclk,
|
|
||||||
i_axi_rstn_i=self.axi.arstn,
|
|
||||||
i_axi_awid_i=self.axi.awid,
|
|
||||||
i_axi_awaddr_i=self.axi.awaddr,
|
|
||||||
i_axi_awlen_i=self.axi.awlen,
|
|
||||||
i_axi_awsize_i=self.axi.awsize,
|
|
||||||
i_axi_awburst_i=self.axi.awburst,
|
|
||||||
i_axi_awlock_i=self.axi.awlock,
|
|
||||||
i_axi_awcache_i=self.axi.awcache,
|
|
||||||
i_axi_awprot_i=self.axi.awprot,
|
|
||||||
i_axi_awvalid_i=self.axi.awvalid,
|
|
||||||
o_axi_awready_o=self.axi.awready,
|
|
||||||
i_axi_wid_i=self.axi.wid,
|
|
||||||
i_axi_wdata_i=self.axi.wdata,
|
|
||||||
i_axi_wstrb_i=self.axi.wstrb,
|
|
||||||
i_axi_wlast_i=self.axi.wlast,
|
|
||||||
i_axi_wvalid_i=self.axi.wvalid,
|
|
||||||
o_axi_wready_o=self.axi.wready,
|
|
||||||
o_axi_bid_o=self.axi.bid,
|
|
||||||
o_axi_bresp_o=self.axi.bresp,
|
|
||||||
o_axi_bvalid_o=self.axi.bvalid,
|
|
||||||
i_axi_bready_i=self.axi.bready,
|
|
||||||
i_axi_arid_i=self.axi.arid,
|
|
||||||
i_axi_araddr_i=self.axi.araddr,
|
|
||||||
i_axi_arlen_i=self.axi.arlen,
|
|
||||||
i_axi_arsize_i=self.axi.arsize,
|
|
||||||
i_axi_arburst_i=self.axi.arburst,
|
|
||||||
i_axi_arlock_i=self.axi.arlock,
|
|
||||||
i_axi_arcache_i=self.axi.arcache,
|
|
||||||
i_axi_arprot_i=self.axi.arprot,
|
|
||||||
i_axi_arvalid_i=self.axi.arvalid,
|
|
||||||
o_axi_arready_o=self.axi.arready,
|
|
||||||
o_axi_rid_o=self.axi.rid,
|
|
||||||
o_axi_rdata_o=self.axi.rdata,
|
|
||||||
o_axi_rresp_o=self.axi.rresp,
|
|
||||||
o_axi_rlast_o=self.axi.rlast,
|
|
||||||
o_axi_rvalid_o=self.axi.rvalid,
|
|
||||||
i_axi_rready_i=self.axi.rready,
|
|
||||||
o_sys_addr_o=self.sys.addr,
|
|
||||||
o_sys_wdata_o=self.sys.wdata,
|
|
||||||
o_sys_sel_o=self.sys.sel,
|
|
||||||
o_sys_wen_o=self.sys.wen,
|
|
||||||
o_sys_ren_o=self.sys.ren,
|
|
||||||
i_sys_rdata_i=self.sys.rdata,
|
|
||||||
i_sys_err_i=self.sys.err,
|
|
||||||
i_sys_ack_i=self.sys.ack,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class SysInterconnect(Module):
|
|
||||||
def __init__(self, master, *slaves):
|
|
||||||
cs = Signal(max=len(slaves)) if len(slaves) != 1 else Signal()
|
|
||||||
self.comb += cs.eq(master.addr[20:23])
|
|
||||||
rets = []
|
|
||||||
for i, s in enumerate(slaves):
|
|
||||||
sel = Signal()
|
|
||||||
self.comb += [
|
|
||||||
sel.eq(cs == i),
|
|
||||||
s.clk.eq(master.clk),
|
|
||||||
s.rstn.eq(master.rstn),
|
|
||||||
s.addr.eq(master.addr),
|
|
||||||
s.wdata.eq(master.wdata),
|
|
||||||
s.sel.eq(master.sel),
|
|
||||||
s.wen.eq(sel & master.wen),
|
|
||||||
s.ren.eq(sel & master.ren),
|
|
||||||
]
|
|
||||||
ret = Cat(s.err, s.ack, s.rdata)
|
|
||||||
rets.append(Replicate(sel, len(ret)) & ret)
|
|
||||||
self.comb += Cat(master.err, master.ack, master.rdata).eq(reduce(or_, rets))
|
|
||||||
|
|
||||||
|
|
||||||
class Sys2Wishbone(Module):
|
|
||||||
def __init__(self):
|
|
||||||
self.wishbone = wb = wishbone.Interface()
|
|
||||||
self.sys = sys = Record(sys_layout)
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
sys2 = Record(sys_layout)
|
|
||||||
|
|
||||||
self.specials += Instance(
|
|
||||||
"bus_clk_bridge",
|
|
||||||
i_sys_clk_i=sys.clk,
|
|
||||||
i_sys_rstn_i=sys.rstn,
|
|
||||||
i_sys_addr_i=sys.addr,
|
|
||||||
i_sys_wdata_i=sys.wdata,
|
|
||||||
i_sys_sel_i=sys.sel,
|
|
||||||
i_sys_wen_i=sys.wen,
|
|
||||||
i_sys_ren_i=sys.ren,
|
|
||||||
o_sys_rdata_o=sys.rdata,
|
|
||||||
o_sys_err_o=sys.err,
|
|
||||||
o_sys_ack_o=sys.ack,
|
|
||||||
i_clk_i=ClockSignal(),
|
|
||||||
i_rstn_i=~ResetSignal(),
|
|
||||||
o_addr_o=sys2.addr,
|
|
||||||
o_wen_o=sys2.wen,
|
|
||||||
o_ren_o=sys2.ren,
|
|
||||||
o_wdata_o=sys2.wdata,
|
|
||||||
i_rdata_i=sys2.rdata,
|
|
||||||
i_err_i=sys2.err,
|
|
||||||
i_ack_i=sys2.ack,
|
|
||||||
)
|
|
||||||
self.sync += [
|
|
||||||
If(
|
|
||||||
sys2.ren | sys2.wen,
|
|
||||||
wb.cyc.eq(1),
|
|
||||||
wb.adr.eq(sys2.addr[2:]),
|
|
||||||
wb.we.eq(sys2.wen),
|
|
||||||
wb.dat_w.eq(sys2.wdata),
|
|
||||||
).Elif(wb.ack, wb.cyc.eq(0))
|
|
||||||
]
|
|
||||||
self.comb += [
|
|
||||||
wb.stb.eq(wb.cyc),
|
|
||||||
sys2.rdata.eq(wb.dat_r),
|
|
||||||
sys2.ack.eq(wb.ack),
|
|
||||||
sys2.err.eq(wb.err),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class SysCDC(Module):
|
|
||||||
def __init__(self, cd_target="sys"):
|
|
||||||
self.source = Record(sys_layout)
|
|
||||||
self.target = Record(sys_layout)
|
|
||||||
|
|
||||||
self.specials += Instance(
|
|
||||||
"bus_clk_bridge",
|
|
||||||
i_sys_clk_i=self.source.clk,
|
|
||||||
i_sys_rstn_i=self.source.rstn,
|
|
||||||
i_sys_addr_i=self.source.addr,
|
|
||||||
i_sys_wdata_i=self.source.wdata,
|
|
||||||
i_sys_sel_i=self.source.sel,
|
|
||||||
i_sys_wen_i=self.source.wen,
|
|
||||||
i_sys_ren_i=self.source.ren,
|
|
||||||
o_sys_rdata_o=self.source.rdata,
|
|
||||||
o_sys_err_o=self.source.err,
|
|
||||||
o_sys_ack_o=self.source.ack,
|
|
||||||
i_clk_i=self.target.clk,
|
|
||||||
i_rstn_i=self.target.rstn,
|
|
||||||
o_addr_o=self.target.addr,
|
|
||||||
o_wdata_o=self.target.wdata,
|
|
||||||
o_wen_o=self.target.wen,
|
|
||||||
o_ren_o=self.target.ren,
|
|
||||||
i_rdata_i=self.target.rdata,
|
|
||||||
i_err_i=self.target.err,
|
|
||||||
i_ack_i=self.target.ack,
|
|
||||||
)
|
|
||||||
self.comb += [
|
|
||||||
self.target.clk.eq(ClockSignal(cd_target)),
|
|
||||||
self.target.rstn.eq(~ResetSignal(cd_target)),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class Sys2CSR(Module):
|
|
||||||
def __init__(self):
|
|
||||||
self.csr = csr_bus.Interface()
|
|
||||||
self.sys = Record(sys_layout)
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
stb = Signal()
|
|
||||||
self.sync += [
|
|
||||||
stb.eq(self.sys.wen | self.sys.ren),
|
|
||||||
self.csr.adr.eq(self.sys.addr[2:]),
|
|
||||||
self.csr.we.eq(self.sys.wen),
|
|
||||||
self.csr.dat_w.eq(self.sys.wdata),
|
|
||||||
self.sys.ack.eq(stb),
|
|
||||||
self.sys.rdata.eq(self.csr.dat_r),
|
|
||||||
]
|
|
@ -1,193 +0,0 @@
|
|||||||
# This file is part of Fast Servo Software Package.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2023 Jakub Matyas
|
|
||||||
# Warsaw University of Technology <jakubk.m@gmail.com>
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#
|
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
from migen import *
|
|
||||||
|
|
||||||
|
|
||||||
class PS7(Module):
|
|
||||||
def __init__(self, platform, ps7_name=None):
|
|
||||||
self.frstn = Signal()
|
|
||||||
self.ps7_tcl = []
|
|
||||||
self.platform = platform
|
|
||||||
|
|
||||||
self.ps7_name = "Zynq" if ps7_name is None else ps7_name
|
|
||||||
|
|
||||||
ps7_clk = platform.request("ps7_clk")
|
|
||||||
ps7_porb = platform.request("ps7_porb")
|
|
||||||
ps7_srstb = platform.request("ps7_srstb")
|
|
||||||
ps7_mio = platform.request("ps7_mio")
|
|
||||||
ps7_ddram = platform.request("ps7_ddram")
|
|
||||||
|
|
||||||
self.cpu_params = dict(
|
|
||||||
# Clk / Rst.
|
|
||||||
io_PS_CLK = ps7_clk,
|
|
||||||
io_PS_PORB = ps7_porb,
|
|
||||||
io_PS_SRSTB = ps7_srstb,
|
|
||||||
|
|
||||||
# MIO.
|
|
||||||
io_MIO = ps7_mio,
|
|
||||||
|
|
||||||
# DDRAM.
|
|
||||||
io_DDR_Addr = ps7_ddram.addr,
|
|
||||||
io_DDR_BankAddr = ps7_ddram.ba,
|
|
||||||
io_DDR_CAS_n = ps7_ddram.cas_n,
|
|
||||||
io_DDR_Clk_n = ps7_ddram.ck_n,
|
|
||||||
io_DDR_Clk = ps7_ddram.ck_p,
|
|
||||||
io_DDR_CKE = ps7_ddram.cke,
|
|
||||||
io_DDR_CS_n = ps7_ddram.cs_n,
|
|
||||||
io_DDR_DM = ps7_ddram.dm,
|
|
||||||
io_DDR_DQ = ps7_ddram.dq,
|
|
||||||
io_DDR_DQS_n = ps7_ddram.dqs_n,
|
|
||||||
io_DDR_DQS = ps7_ddram.dqs_p,
|
|
||||||
io_DDR_ODT = ps7_ddram.odt,
|
|
||||||
io_DDR_RAS_n = ps7_ddram.ras_n,
|
|
||||||
io_DDR_DRSTB = ps7_ddram.reset_n,
|
|
||||||
io_DDR_WEB = ps7_ddram.we_n,
|
|
||||||
io_DDR_VRN = ps7_ddram.vrn,
|
|
||||||
io_DDR_VRP = ps7_ddram.vrp,
|
|
||||||
|
|
||||||
# USB0.
|
|
||||||
# i_USB0_VBUS_PWRFAULT = 0,
|
|
||||||
|
|
||||||
# Fabric Clk / Rst.
|
|
||||||
# o_FCLK_CLK0 = ClockSignal("ps7"),
|
|
||||||
o_FCLK_RESET0_N = self.frstn
|
|
||||||
)
|
|
||||||
|
|
||||||
self.set_ps7(name=self.ps7_name,
|
|
||||||
config={
|
|
||||||
**self.platform.ps7_config
|
|
||||||
})
|
|
||||||
|
|
||||||
def add_ps7_config(self, config):
|
|
||||||
# Config must be provided as a config, value dict.
|
|
||||||
assert isinstance(config, dict)
|
|
||||||
# Add configs to PS7.
|
|
||||||
self.ps7_tcl.append("set_property -dict [list \\")
|
|
||||||
for config, value in config.items():
|
|
||||||
self.ps7_tcl.append("CONFIG.{} {} \\".format(config, '{{' + str(value) + '}}'))
|
|
||||||
self.ps7_tcl.append(f"] [get_ips {self.ps7_name}]")
|
|
||||||
|
|
||||||
def set_ps7(self, name=None, config=None, preset=None):
|
|
||||||
self.ps7_name = name
|
|
||||||
self.ps7_tcl.append(f"set ps7 [create_ip -vendor xilinx.com -name processing_system7 -module_name {self.ps7_name}]")
|
|
||||||
self.add_ps7_config(config)
|
|
||||||
|
|
||||||
def add_axi_gp_master(self, interface):
|
|
||||||
# assert type(interface) is Axi2Sys
|
|
||||||
|
|
||||||
axi_interface = interface
|
|
||||||
|
|
||||||
self.cpu_params.update({
|
|
||||||
# AXI GP clk.
|
|
||||||
f"i_M_AXI_GP0_ACLK" : axi_interface.aclk,
|
|
||||||
|
|
||||||
# AXI GP aw.
|
|
||||||
f"o_M_AXI_GP0_AWVALID" : axi_interface.awvalid,
|
|
||||||
f"i_M_AXI_GP0_AWREADY" : axi_interface.awready,
|
|
||||||
f"o_M_AXI_GP0_AWADDR" : axi_interface.awaddr,
|
|
||||||
f"o_M_AXI_GP0_AWBURST" : axi_interface.awburst,
|
|
||||||
f"o_M_AXI_GP0_AWLEN" : axi_interface.awlen,
|
|
||||||
f"o_M_AXI_GP0_AWSIZE" : axi_interface.awsize,
|
|
||||||
f"o_M_AXI_GP0_AWID" : axi_interface.awid,
|
|
||||||
f"o_M_AXI_GP0_AWLOCK" : axi_interface.awlock,
|
|
||||||
f"o_M_AXI_GP0_AWPROT" : axi_interface.awprot,
|
|
||||||
f"o_M_AXI_GP0_AWCACHE" : axi_interface.awcache,
|
|
||||||
f"o_M_AXI_GP0_AWQOS" : axi_interface.awqos,
|
|
||||||
|
|
||||||
# AXI GP w.
|
|
||||||
f"o_M_AXI_GP0_WVALID" : axi_interface.wvalid,
|
|
||||||
f"o_M_AXI_GP0_WLAST" : axi_interface.wlast,
|
|
||||||
f"i_M_AXI_GP0_WREADY" : axi_interface.wready,
|
|
||||||
f"o_M_AXI_GP0_WID" : axi_interface.wid,
|
|
||||||
f"o_M_AXI_GP0_WDATA" : axi_interface.wdata,
|
|
||||||
f"o_M_AXI_GP0_WSTRB" : axi_interface.wstrb,
|
|
||||||
|
|
||||||
# AXI GP b.
|
|
||||||
f"i_M_AXI_GP0_BVALID" : axi_interface.bvalid,
|
|
||||||
f"o_M_AXI_GP0_BREADY" : axi_interface.bready,
|
|
||||||
f"i_M_AXI_GP0_BID" : axi_interface.bid,
|
|
||||||
f"i_M_AXI_GP0_BRESP" : axi_interface.bresp,
|
|
||||||
|
|
||||||
# AXI GP ar.
|
|
||||||
f"o_M_AXI_GP0_ARVALID" : axi_interface.arvalid,
|
|
||||||
f"i_M_AXI_GP0_ARREADY" : axi_interface.arready,
|
|
||||||
f"o_M_AXI_GP0_ARADDR" : axi_interface.araddr,
|
|
||||||
f"o_M_AXI_GP0_ARBURST" : axi_interface.arburst,
|
|
||||||
f"o_M_AXI_GP0_ARLEN" : axi_interface.arlen,
|
|
||||||
f"o_M_AXI_GP0_ARID" : axi_interface.arid,
|
|
||||||
f"o_M_AXI_GP0_ARLOCK" : axi_interface.arlock,
|
|
||||||
f"o_M_AXI_GP0_ARSIZE" : axi_interface.arsize,
|
|
||||||
f"o_M_AXI_GP0_ARPROT" : axi_interface.arprot,
|
|
||||||
f"o_M_AXI_GP0_ARCACHE" : axi_interface.arcache,
|
|
||||||
f"o_M_AXI_GP0_ARQOS" : axi_interface.arqos,
|
|
||||||
|
|
||||||
# AXI GP r.
|
|
||||||
f"i_M_AXI_GP0_RVALID" : axi_interface.rvalid,
|
|
||||||
f"o_M_AXI_GP0_RREADY" : axi_interface.rready,
|
|
||||||
f"i_M_AXI_GP0_RLAST" : axi_interface.rlast,
|
|
||||||
f"i_M_AXI_GP0_RID" : axi_interface.rid,
|
|
||||||
f"i_M_AXI_GP0_RRESP" : axi_interface.rresp,
|
|
||||||
f"i_M_AXI_GP0_RDATA" : axi_interface.rdata,
|
|
||||||
})
|
|
||||||
|
|
||||||
def add_i2c_emio(self, platform, i2c_name, i2c_number):
|
|
||||||
ps7_i2c_pads = platform.request(i2c_name, i2c_number) #, loose=True)
|
|
||||||
if ps7_i2c_pads is not None:
|
|
||||||
o_i2c_scl = Signal()
|
|
||||||
i_i2c_scl = Signal()
|
|
||||||
t_i2c_scl = Signal()
|
|
||||||
o_i2c_sda = Signal()
|
|
||||||
i_i2c_sda = Signal()
|
|
||||||
t_i2c_sda = Signal()
|
|
||||||
|
|
||||||
self.specials += Instance("IOBUF",
|
|
||||||
i_T = t_i2c_sda,
|
|
||||||
i_I = o_i2c_sda,
|
|
||||||
io_IO = ps7_i2c_pads.sda,
|
|
||||||
o_O = i_i2c_sda,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.specials += Instance("IOBUF",
|
|
||||||
i_T = t_i2c_scl,
|
|
||||||
i_I = o_i2c_scl,
|
|
||||||
io_IO = ps7_i2c_pads.scl,
|
|
||||||
o_O = i_i2c_scl,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.cpu_params.update({
|
|
||||||
f"i_I2C{i2c_number}_SCL_I" : i_i2c_scl,
|
|
||||||
f"o_I2C{i2c_number}_SCL_T" : t_i2c_scl,
|
|
||||||
f"o_I2C{i2c_number}_SCL_O" : o_i2c_scl,
|
|
||||||
|
|
||||||
f"i_I2C{i2c_number}_SDA_I" : i_i2c_sda,
|
|
||||||
f"o_I2C{i2c_number}_SDA_T" : t_i2c_sda,
|
|
||||||
f"o_I2C{i2c_number}_SDA_O" : o_i2c_sda,
|
|
||||||
})
|
|
||||||
|
|
||||||
def do_finalize(self):
|
|
||||||
if len(self.ps7_tcl):
|
|
||||||
self.ps7_tcl += [
|
|
||||||
f"upgrade_ip [get_ips {self.ps7_name}]",
|
|
||||||
f"generate_target all [get_ips {self.ps7_name}]",
|
|
||||||
f"synth_ip [get_ips {self.ps7_name}]"
|
|
||||||
]
|
|
||||||
self.platform.toolchain.pre_synthesis_commands += self.ps7_tcl
|
|
||||||
|
|
||||||
self.specials += Instance(self.ps7_name, **self.cpu_params)
|
|
@ -1,141 +0,0 @@
|
|||||||
# This file is part of Fast Servo Software Package.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2023 Jakub Matyas
|
|
||||||
# Warsaw University of Technology <jakubk.m@gmail.com>
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#
|
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
from migen import *
|
|
||||||
|
|
||||||
|
|
||||||
class SpiInterface(Enum):
|
|
||||||
ADC = 0
|
|
||||||
DAC = 1
|
|
||||||
|
|
||||||
|
|
||||||
class SpiPhy(Module):
|
|
||||||
def __init__(self, spi_type, ps7_spi_pads):
|
|
||||||
assert isinstance(spi_type, SpiInterface)
|
|
||||||
|
|
||||||
self.ps_ss = Signal(3, reset_less=True)
|
|
||||||
|
|
||||||
self.ps_miso_o = Signal()
|
|
||||||
self.ps_miso_t = Signal()
|
|
||||||
self.ps_mosi_o = Signal()
|
|
||||||
self.ps_mosi_t = Signal()
|
|
||||||
self.ps_sclk_o = Signal()
|
|
||||||
self.ps_sclk_t = Signal()
|
|
||||||
self.ps_sclk_i = Signal()
|
|
||||||
self.ps_mosi_i = Signal()
|
|
||||||
self.ps_miso_i = Signal()
|
|
||||||
self.ps_ss_i = Signal()
|
|
||||||
self.ps_ss_t = Signal()
|
|
||||||
|
|
||||||
if spi_type.name == "ADC":
|
|
||||||
|
|
||||||
cs_translated = Signal(4, reset_less=True)
|
|
||||||
|
|
||||||
main_adc_miso = Signal(reset_less=True)
|
|
||||||
aux_adc_miso_a = Signal(reset_less=True)
|
|
||||||
aux_adc_miso_b = Signal(reset_less=True)
|
|
||||||
aux_dac_miso = Signal(reset_less=True)
|
|
||||||
|
|
||||||
miso_signals = [main_adc_miso, aux_adc_miso_a, aux_adc_miso_b, aux_dac_miso]
|
|
||||||
|
|
||||||
# MAIN ADC
|
|
||||||
self.specials += Instance("OBUFT", i_I=self.ps_sclk_o, i_T=self.ps_sclk_t, o_O=ps7_spi_pads.sclk)
|
|
||||||
self.specials += Instance("OBUFT", i_I=self.ps_mosi_o, i_T=self.ps_mosi_t, o_O=ps7_spi_pads.mosi)
|
|
||||||
self.specials += Instance("IBUF", i_I=ps7_spi_pads.miso, o_O=main_adc_miso)
|
|
||||||
|
|
||||||
# AUX ADC
|
|
||||||
self.specials += Instance("OBUFT", i_I=self.ps_sclk_o, i_T=self.ps_sclk_t, o_O=ps7_spi_pads.aux_adc_sclk)
|
|
||||||
self.specials += Instance("IBUF", i_I=ps7_spi_pads.aux_adc_miso_a, o_O=aux_adc_miso_a)
|
|
||||||
self.specials += Instance("IBUF", i_I=ps7_spi_pads.aux_adc_miso_b, o_O=aux_adc_miso_b)
|
|
||||||
|
|
||||||
# AUX DAC
|
|
||||||
self.specials += Instance("OBUFT", i_I=self.ps_sclk_o, i_T=self.ps_sclk_t, o_O=ps7_spi_pads.aux_dac_sclk)
|
|
||||||
self.specials += Instance("OBUFT", i_I=self.ps_mosi_o, i_T=self.ps_mosi_t, o_O=ps7_spi_pads.aux_dac_mosi)
|
|
||||||
self.specials += Instance("IBUF", i_I=ps7_spi_pads.aux_dac_miso, o_O=aux_dac_miso)
|
|
||||||
|
|
||||||
cases = {}
|
|
||||||
# for i in range(4):
|
|
||||||
# case_mask = ~(1 << i) & 0xF
|
|
||||||
# print(f"Case mask: 0b{case_mask:04b}")
|
|
||||||
# cases[i + 1] = [
|
|
||||||
# cs_translated.eq(case_mask),
|
|
||||||
# self.ps_miso_i.eq(miso_signals[i])
|
|
||||||
# ]
|
|
||||||
|
|
||||||
cases[0b001] = [
|
|
||||||
cs_translated.eq(0b1110),
|
|
||||||
self.ps_miso_i.eq(main_adc_miso),
|
|
||||||
]
|
|
||||||
|
|
||||||
cases[0b010] = [
|
|
||||||
cs_translated.eq(0b1101),
|
|
||||||
self.ps_miso_i.eq(aux_adc_miso_a),
|
|
||||||
]
|
|
||||||
|
|
||||||
cases[0b011] = [
|
|
||||||
cs_translated.eq(0b1011),
|
|
||||||
self.ps_miso_i.eq(aux_adc_miso_b),
|
|
||||||
]
|
|
||||||
cases[0b100] = [
|
|
||||||
cs_translated.eq(0b0111),
|
|
||||||
self.ps_miso_i.eq(aux_dac_miso),
|
|
||||||
]
|
|
||||||
|
|
||||||
cases["default"] = [
|
|
||||||
cs_translated.eq(0b1111),
|
|
||||||
self.ps_miso_i.eq(0b1),
|
|
||||||
]
|
|
||||||
|
|
||||||
self.comb += [
|
|
||||||
self.ps_ss_i.eq(1),
|
|
||||||
Case(self.ps_ss, cases),
|
|
||||||
|
|
||||||
ps7_spi_pads.cs.eq(cs_translated[0]),
|
|
||||||
|
|
||||||
# only one CS line physically available to AUX ADC
|
|
||||||
ps7_spi_pads.aux_adc_cs.eq(cs_translated[1] & cs_translated[2]),
|
|
||||||
ps7_spi_pads.aux_dac_miso.eq(cs_translated[3]),
|
|
||||||
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
self.specials += Instance(
|
|
||||||
"spi2threewire",
|
|
||||||
o_ps_sclk_i = self.ps_sclk_i,
|
|
||||||
i_ps_sclk_o = self.ps_sclk_o,
|
|
||||||
i_ps_sclk_t = self.ps_sclk_t,
|
|
||||||
|
|
||||||
o_ps_mosi_i = self.ps_mosi_i,
|
|
||||||
i_ps_mosi_o = self.ps_mosi_o,
|
|
||||||
i_ps_mosi_t = self.ps_mosi_t,
|
|
||||||
|
|
||||||
o_ps_miso_i = self.ps_miso_i,
|
|
||||||
i_ps_miso_o = self.ps_miso_o,
|
|
||||||
i_ps_miso_t = self.ps_miso_t,
|
|
||||||
|
|
||||||
o_ps_ss_i = self.ps_ss_i,
|
|
||||||
i_ps_ss = self.ps_ss,
|
|
||||||
i_ps_ss_t = self.ps_ss_t,
|
|
||||||
|
|
||||||
o_o_ss = ps7_spi_pads.cs,
|
|
||||||
o_o_sclk = ps7_spi_pads.sclk,
|
|
||||||
io_sdio = ps7_spi_pads.sdio,
|
|
||||||
)
|
|
||||||
|
|
@ -1,336 +0,0 @@
|
|||||||
# This file is part of Fast Servo Software Package.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2022-2023 Jakub Matyas
|
|
||||||
# Warsaw University of Technology <jakubk.m@gmail.com>
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#
|
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
from migen.build.generic_platform import *
|
|
||||||
from migen.build.xilinx import XilinxPlatform
|
|
||||||
|
|
||||||
import os
|
|
||||||
from fast_servo.gateware import verilog_dir
|
|
||||||
|
|
||||||
|
|
||||||
# IOs ----------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
_io = [
|
|
||||||
# Front panel LEDs
|
|
||||||
("fp_led", 0, Pins("G7"), IOStandard("LVCMOS25")),
|
|
||||||
("fp_led", 1, Pins("G8"), IOStandard("LVCMOS25")),
|
|
||||||
("fp_led", 2, Pins("G2"), IOStandard("LVCMOS25")),
|
|
||||||
("fp_led", 3, Pins("G3"), IOStandard("LVCMOS25")),
|
|
||||||
|
|
||||||
# LEDs
|
|
||||||
("user_led", 0, Pins("AB16"), IOStandard("LVCMOS33")),
|
|
||||||
("user_led", 1, Pins("AA14"), IOStandard("LVCMOS33")),
|
|
||||||
("user_led", 2, Pins("AA15"), IOStandard("LVCMOS33")),
|
|
||||||
|
|
||||||
# ETH LEDs
|
|
||||||
("eth_led", 0, Pins("V11"), IOStandard("LVCMOS33")),
|
|
||||||
("eth_led", 1, Pins("U13"), IOStandard("LVCMOS33")),
|
|
||||||
|
|
||||||
("from_eth_phy", 0, Pins("J3"), IOStandard("LVCMOS18")),
|
|
||||||
("from_eth_phy", 1, Pins("K8"), IOStandard("LVCMOS18")),
|
|
||||||
|
|
||||||
|
|
||||||
# CLK 100 MHz from oscillator
|
|
||||||
("clk100", 0, Pins("Y14"), IOStandard("LVCMOS33")),
|
|
||||||
|
|
||||||
# MGT clk from on-board Si5338A
|
|
||||||
("mgt_clk1", 0,
|
|
||||||
Subsignal("p", Pins("U5")),
|
|
||||||
Subsignal("n", Pins("V5")),
|
|
||||||
IOStandard("LVDS_25"),
|
|
||||||
),
|
|
||||||
|
|
||||||
# FCLK125 from on-board Si5338A
|
|
||||||
("fclk125", 0, Pins("K2"), IOStandard("LVCMOS18")),
|
|
||||||
|
|
||||||
# # ADC CLK
|
|
||||||
# ("fpga_clk", 0,
|
|
||||||
# Subsignal("p", Pins("C6")),
|
|
||||||
# Subsignal("n", Pins("C5")),
|
|
||||||
# IOStandard("LVDS_25"),
|
|
||||||
# ),
|
|
||||||
|
|
||||||
# DAC CLK
|
|
||||||
("fpga_clk", 1,
|
|
||||||
Subsignal("p", Pins("J7")),
|
|
||||||
Subsignal("n", Pins("J6")),
|
|
||||||
IOStandard("LVDS_25"),
|
|
||||||
),
|
|
||||||
|
|
||||||
# MAIN ADC LT2195
|
|
||||||
("adc", 0,
|
|
||||||
Subsignal("data0_p", Pins("F7 B7 E4 D1"), IOStandard("LVDS_25")),
|
|
||||||
Subsignal("data0_n", Pins("E7 B6 E3 C1"), IOStandard("LVDS_25")),
|
|
||||||
Subsignal("data1_p", Pins("A2 D5 F2 D7"), IOStandard("LVDS_25")),
|
|
||||||
Subsignal("data1_n", Pins("A1 C4 F1 D6"), IOStandard("LVDS_25")),
|
|
||||||
Subsignal("dco_p", Pins("B4"), IOStandard("LVDS_25")),
|
|
||||||
Subsignal("dco_n", Pins("B3"), IOStandard("LVDS_25")),
|
|
||||||
Subsignal("frame_p", Pins("B2"), IOStandard("LVDS_25")),
|
|
||||||
Subsignal("frame_n", Pins("B1"), IOStandard("LVDS_25"))
|
|
||||||
),
|
|
||||||
|
|
||||||
# ADC AFE
|
|
||||||
("adc_afe", 0,
|
|
||||||
Subsignal("ch1_gain", Pins("AA12"), IOStandard("LVCMOS33")),
|
|
||||||
Subsignal("ch2_gain", Pins("AB11"), IOStandard("LVCMOS33")),
|
|
||||||
Subsignal("nshdn_ch1", Pins("G4"), IOStandard("LVCMOS25")),
|
|
||||||
Subsignal("nshdn_ch2", Pins("F4"), IOStandard("LVCMOS25")),
|
|
||||||
),
|
|
||||||
|
|
||||||
# P5 R5 N1 N4 L2 P6 N3 R4 P1 L1 M3 M4 U2 T2
|
|
||||||
# MAIN DAC AD9117
|
|
||||||
("dac", 0,
|
|
||||||
Subsignal("data",
|
|
||||||
Pins("T2 U2 M4 M3 L1 P1 R4 N3 P6 L2 N4 N1 R5 P5"),
|
|
||||||
IOStandard("LVCMOS18")),
|
|
||||||
Subsignal("dclkio", Pins("U1"), IOStandard("LVCMOS18")),
|
|
||||||
Subsignal("rst", Pins("T1"), IOStandard("LVCMOS18")),
|
|
||||||
),
|
|
||||||
|
|
||||||
# DAC AFE
|
|
||||||
("dac_afe", 0,
|
|
||||||
Subsignal("ch1_pd_n", Pins("L5")),
|
|
||||||
Subsignal("ch2_pd_n", Pins("L4")),
|
|
||||||
IOStandard("LVCMOS18"),
|
|
||||||
),
|
|
||||||
|
|
||||||
# AUXILIARY ADC
|
|
||||||
("aux_adc", 0,
|
|
||||||
Subsignal("diff_n", Pins("W18")),
|
|
||||||
Subsignal("a", Pins("AB18 AB19 W17")),
|
|
||||||
Subsignal("range", Pins("U19")),
|
|
||||||
IOStandard("LVCMOS33")
|
|
||||||
),
|
|
||||||
|
|
||||||
# AUXILIARY DAC
|
|
||||||
("aux_dac", 0,
|
|
||||||
Subsignal("nclr", Pins("V19")),
|
|
||||||
Subsignal("bin", Pins("AA19")),
|
|
||||||
Subsignal("nldac", Pins("AB21")),
|
|
||||||
IOStandard("LVCMOS33")
|
|
||||||
),
|
|
||||||
|
|
||||||
# ADC SPI
|
|
||||||
("spi", 0,
|
|
||||||
Subsignal("sclk", Pins("J1"), IOStandard("LVCMOS18")),
|
|
||||||
Subsignal("mosi", Pins("J5"), IOStandard("LVCMOS18")),
|
|
||||||
Subsignal("miso", Pins("K5"), IOStandard("LVCMOS18")),
|
|
||||||
Subsignal("cs", Pins("J2"), IOStandard("LVCMOS18")),
|
|
||||||
Subsignal("aux_adc_sclk", Pins("AB22"), IOStandard("LVCMOS33")),
|
|
||||||
Subsignal("aux_adc_miso_a", Pins("Y18"), IOStandard("LVCMOS33")),
|
|
||||||
Subsignal("aux_adc_miso_b", Pins("AA16"), IOStandard("LVCMOS33")),
|
|
||||||
Subsignal("aux_adc_cs", Pins("Y19"), IOStandard("LVCMOS33")),
|
|
||||||
Subsignal("aux_dac_sclk", Pins("V18"), IOStandard("LVCMOS33")),
|
|
||||||
Subsignal("aux_dac_mosi", Pins("U17"), IOStandard("LVCMOS33")),
|
|
||||||
Subsignal("aux_dac_miso", Pins("U18"), IOStandard("LVCMOS33")),
|
|
||||||
Subsignal("aux_dac_cs", Pins("AA20"), IOStandard("LVCMOS33")),
|
|
||||||
),
|
|
||||||
|
|
||||||
# DAC SPI
|
|
||||||
("spi", 1,
|
|
||||||
Subsignal("sclk", Pins("K3"), IOStandard("LVCMOS18")),
|
|
||||||
Subsignal("sdio", Pins("R2"), IOStandard("LVCMOS18")),
|
|
||||||
Subsignal("cs", Pins("R3"), IOStandard("LVCMOS18")),
|
|
||||||
# Subsignal("sclk_aux", Pins("V18"), IOStandard("LVCMOS33")),
|
|
||||||
# Subsignal("mosi_aux", Pins("U17"), IOStandard("LVCMOS33")),
|
|
||||||
# Subsignal("miso_aux", Pins("U18"), IOStandard("LVCMOS33")),
|
|
||||||
# Subsignal("cs_aux", Pins("AA20"), IOStandard("LVCMOS33")),
|
|
||||||
),
|
|
||||||
#Pins("Y15 AB14 AB13 V13 V14 V15 U12 W13 W12 R17 W15 AB17 Y12 Y13 V16 W16 AA17 Y17"),
|
|
||||||
("gpio", 0,
|
|
||||||
Subsignal("n", Pins("Y15 AB14 AB13 V13 V14 V15 U12 W13"), IOStandard("LVCMOS33")),
|
|
||||||
Subsignal("p", Pins("W12 R17 W15 AB17 Y12 Y13 V16 W16"), IOStandard("LVCMOS33")),
|
|
||||||
),
|
|
||||||
|
|
||||||
# PS7
|
|
||||||
("ps7_clk", 0, Pins("_" * 1)),
|
|
||||||
("ps7_porb", 0, Pins("_" * 1)),
|
|
||||||
("ps7_srstb", 0, Pins("_" * 1)),
|
|
||||||
("ps7_mio", 0, Pins("_" * 54)),
|
|
||||||
("ps7_ddram", 0,
|
|
||||||
Subsignal("addr", Pins("_" * 15)),
|
|
||||||
Subsignal("ba", Pins("_" * 3)),
|
|
||||||
Subsignal("cas_n", Pins("_" * 1)),
|
|
||||||
Subsignal("ck_n", Pins("_" * 1)),
|
|
||||||
Subsignal("ck_p", Pins("_" * 1)),
|
|
||||||
Subsignal("cke", Pins("_" * 1)),
|
|
||||||
Subsignal("cs_n", Pins("_" * 1)),
|
|
||||||
Subsignal("dm", Pins("_" * 4)),
|
|
||||||
Subsignal("dq", Pins("_" * 32)),
|
|
||||||
Subsignal("dqs_n", Pins("_" * 4)),
|
|
||||||
Subsignal("dqs_p", Pins("_" * 4)),
|
|
||||||
Subsignal("odt", Pins("_" * 1)),
|
|
||||||
Subsignal("ras_n", Pins("_" * 1)),
|
|
||||||
Subsignal("reset_n", Pins("_" * 1)),
|
|
||||||
Subsignal("we_n", Pins("_" * 1)),
|
|
||||||
Subsignal("vrn", Pins("_" * 1)),
|
|
||||||
Subsignal("vrp", Pins("_" * 1)),
|
|
||||||
|
|
||||||
),
|
|
||||||
|
|
||||||
# I2C0 to Si5340 on Fast Servo
|
|
||||||
("ps7_i2c", 0,
|
|
||||||
Subsignal("sda", Pins("M2")),
|
|
||||||
Subsignal("scl", Pins("M1")),
|
|
||||||
IOStandard("LVCMOS18")
|
|
||||||
),
|
|
||||||
|
|
||||||
# Si540 nRST
|
|
||||||
("nrst", 0, Pins("M7"), IOStandard("LVCMOS18")),
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_connector_eem = [
|
|
||||||
("eem", {
|
|
||||||
"d0_cc_n": "C3",
|
|
||||||
"d0_cc_p": "D3",
|
|
||||||
"d1_n": "A4",
|
|
||||||
"d1_p": "A5",
|
|
||||||
"d2_n": "F6",
|
|
||||||
"d2_p": "G6",
|
|
||||||
"d3_n": "A6",
|
|
||||||
"d3_p": "A7",
|
|
||||||
"d4_n": "E5",
|
|
||||||
"d4_p": "F5",
|
|
||||||
"d5_n": "H3",
|
|
||||||
"d5_p": "H4",
|
|
||||||
"d6_n": "B8",
|
|
||||||
"d6_p": "C8",
|
|
||||||
"d7_n": "D8",
|
|
||||||
"d7_p": "E8",
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
|
|
||||||
_connector_gpio = [
|
|
||||||
("gpio", {
|
|
||||||
"qspi_io3": "Y15",
|
|
||||||
"qspi_io2": "AB14",
|
|
||||||
"qspi_io1": "AB13",
|
|
||||||
"qspi_io0": "V13",
|
|
||||||
"qspi_clk": "V14",
|
|
||||||
"qspi_ncs": "V15",
|
|
||||||
"hrtim_che1": "U12",
|
|
||||||
"hrtim_che2": "W13",
|
|
||||||
"hrtim_cha1": "W12",
|
|
||||||
"hrtim_cha2": "R17",
|
|
||||||
"lptim2_out": "W15",
|
|
||||||
"uart4_tx": "AB17",
|
|
||||||
"spi1_mosi": "Y12",
|
|
||||||
"spi1_miso": "Y13",
|
|
||||||
"spi1_nss": "V16",
|
|
||||||
"spi1_sck": "W16",
|
|
||||||
"i2c1_sda": "AA17",
|
|
||||||
"i2c1_scl": "Y17",
|
|
||||||
})
|
|
||||||
]
|
|
||||||
|
|
||||||
# PS7 config ---------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
ps7_config_board_preset = {
|
|
||||||
"PCW_PRESET_BANK0_VOLTAGE" : "LVCMOS 3.3V",
|
|
||||||
"PCW_PRESET_BANK1_VOLTAGE" : "LVCMOS 1.8V",
|
|
||||||
"PCW_CRYSTAL_PERIPHERAL_FREQMHZ" : "33.333333",
|
|
||||||
"PCW_QSPI_PERIPHERAL_ENABLE" : "1",
|
|
||||||
"PCW_QSPI_GRP_SINGLE_SS_ENABLE" : "1",
|
|
||||||
"PCW_SINGLE_QSPI_DATA_MODE" : "x4",
|
|
||||||
"PCW_QSPI_QSPI_IO" : "MIO 1 .. 6",
|
|
||||||
"PCW_QSPI_GRP_FBCLK_ENABLE" : "1",
|
|
||||||
|
|
||||||
# SD Card
|
|
||||||
"PCW_SD0_PERIPHERAL_ENABLE" : "1",
|
|
||||||
"PCW_SD0_SD0_IO" : "MIO 40 .. 45",
|
|
||||||
"PCW_MIO_40_PULLUP" : "disabled",
|
|
||||||
"PCW_MIO_41_PULLUP" : "disabled",
|
|
||||||
"PCW_MIO_42_PULLUP" : "disabled",
|
|
||||||
"PCW_MIO_43_PULLUP" : "disabled",
|
|
||||||
"PCW_MIO_44_PULLUP" : "disabled",
|
|
||||||
"PCW_MIO_45_PULLUP" : "disabled",
|
|
||||||
|
|
||||||
# UART
|
|
||||||
"PCW_UART0_PERIPHERAL_ENABLE" : "1",
|
|
||||||
"PCW_UART0_UART0_IO" : "MIO 10 .. 11",
|
|
||||||
|
|
||||||
# ETHERNET
|
|
||||||
"PCW_ACT_ENET0_PERIPHERAL_FREQMHZ" : "125",
|
|
||||||
"PCW_ENET0_PERIPHERAL_CLKSRC" : "ARM PLL",
|
|
||||||
"PCW_ENET0_PERIPHERAL_ENABLE" : "1",
|
|
||||||
"PCW_ENET0_ENET0_IO" : "MIO 16 .. 27",
|
|
||||||
"PCW_ENET0_GRP_MDIO_ENABLE" : "1",
|
|
||||||
"PCW_ENET0_GRP_MDIO_IO" : "MIO 52 .. 53",
|
|
||||||
"PCW_ENET_RESET_ENABLE" : "1",
|
|
||||||
"PCW_ENET0_RESET_ENABLE" : "1",
|
|
||||||
"PCW_ENET0_RESET_IO" : "MIO 50",
|
|
||||||
|
|
||||||
# USB
|
|
||||||
"PCW_USB0_PERIPHERAL_ENABLE" : "1",
|
|
||||||
"PCW_USB0_USB0_IO" : "MIO 28 .. 39",
|
|
||||||
"PCW_USB_RESET_ENABLE" : "1",
|
|
||||||
"PCW_USB0_RESET_ENABLE" : "1",
|
|
||||||
"PCW_USB0_RESET_IO" : "MIO 51",
|
|
||||||
|
|
||||||
"PCW_WDT_PERIPHERAL_ENABLE" : "1",
|
|
||||||
"PCW_TTC0_PERIPHERAL_ENABLE" : "1", # TTC0 required for Linux
|
|
||||||
|
|
||||||
# I2C
|
|
||||||
"PCW_I2C_RESET_ENABLE" : "0",
|
|
||||||
"PCW_I2C_RESET_POLARITY" : "Active Low",
|
|
||||||
|
|
||||||
# I2C0
|
|
||||||
"PCW_I2C0_I2C0_IO" : "EMIO",
|
|
||||||
"PCW_I2C0_PERIPHERAL_ENABLE" : "1",
|
|
||||||
"PCW_I2C0_GRP_INT_ENABLE" : "1",
|
|
||||||
"PCW_I2C0_GRP_INT_IO" : "EMIO",
|
|
||||||
|
|
||||||
# I2C1
|
|
||||||
"PCW_I2C1_PERIPHERAL_ENABLE" : "1",
|
|
||||||
"PCW_I2C1_I2C1_IO" : "MIO 48 .. 49",
|
|
||||||
"PCW_I2C1_I2C1_IO" : "MIO 12 .. 13",
|
|
||||||
"PCW_I2C1_PERIPHERAL_ENABLE" : "1",
|
|
||||||
|
|
||||||
"PCW_UIPARAM_DDR_MEMORY_TYPE" : "DDR 3 (Low Voltage)",
|
|
||||||
"PCW_UIPARAM_DDR_PARTNO" : "MT41J256M16 RE-125",
|
|
||||||
"PCW_GPIO_MIO_GPIO_ENABLE" : "1",
|
|
||||||
|
|
||||||
"PCW_FPGA0_PERIPHERAL_FREQMHZ" : "100",
|
|
||||||
"PCW_EN_CLK0_PORT" : "0", # dont use FCLK0
|
|
||||||
}
|
|
||||||
|
|
||||||
class Platform(XilinxPlatform):
|
|
||||||
default_clk_name = "clk100"
|
|
||||||
default_clk_period = 10.0
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
XilinxPlatform.__init__(self, "xc7z015-clg485-1", _io, _connector_gpio + _connector_eem, toolchain="vivado")
|
|
||||||
ps7_config = ps7_config_board_preset
|
|
||||||
self.ps7_config = ps7_config
|
|
||||||
|
|
||||||
verilog_sources = os.listdir(verilog_dir)
|
|
||||||
self.add_sources(verilog_dir, *verilog_sources)
|
|
||||||
|
|
||||||
def do_finalize(self, fragment):
|
|
||||||
try:
|
|
||||||
XilinxPlatform.do_finalize(self, fragment)
|
|
||||||
self.add_period_constraint(self.lookup_request(self.default_clk_name, loose=True), self.default_clk_period)
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
except ConstraintError:
|
|
||||||
pass
|
|
@ -1,291 +0,0 @@
|
|||||||
# This file is part of Fast Servo Software Package.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2023 Jakub Matyas
|
|
||||||
# Warsaw University of Technology <jakubk.m@gmail.com>
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#
|
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
from migen import *
|
|
||||||
from misoc.interconnect import csr_bus
|
|
||||||
from misoc.interconnect.csr import AutoCSR, CSRStorage
|
|
||||||
|
|
||||||
from fast_servo.gateware.cores.adc import ADC, AUX_ADC_CTRL
|
|
||||||
from fast_servo.gateware.cores.dac import AUX_DAC_CTRL, DAC
|
|
||||||
from fast_servo.gateware.cores.pitaya_ps import Axi2Sys, Sys2CSR, SysCDC, SysInterconnect
|
|
||||||
from fast_servo.gateware.cores.ps7 import PS7
|
|
||||||
from fast_servo.gateware.cores.spi_phy import SpiInterface, SpiPhy
|
|
||||||
|
|
||||||
|
|
||||||
class CRG(Module):
|
|
||||||
def __init__(self, platform):
|
|
||||||
self.ps_rst = Signal()
|
|
||||||
self.locked = Signal()
|
|
||||||
self.clock_domains.cd_sys = ClockDomain()
|
|
||||||
self.clock_domains.cd_sys_double = ClockDomain()
|
|
||||||
self.clock_domains.cd_idelay = ClockDomain()
|
|
||||||
|
|
||||||
# # #
|
|
||||||
|
|
||||||
# Clk.
|
|
||||||
clk100 = platform.request("clk100")
|
|
||||||
platform.add_period_constraint(clk100, 10.0)
|
|
||||||
self.clkin = clk100
|
|
||||||
clk100_buf = Signal()
|
|
||||||
self.specials += Instance("IBUFG", i_I=clk100, o_O=clk100_buf)
|
|
||||||
|
|
||||||
clk_feedback = Signal()
|
|
||||||
clk_feedback_buf = Signal()
|
|
||||||
|
|
||||||
clk_sys = Signal()
|
|
||||||
clk_idelay = Signal()
|
|
||||||
|
|
||||||
self.specials += [
|
|
||||||
Instance(
|
|
||||||
"PLLE2_BASE",
|
|
||||||
p_BANDWIDTH="OPTIMIZED",
|
|
||||||
p_DIVCLK_DIVIDE=1,
|
|
||||||
p_CLKFBOUT_PHASE=0.0,
|
|
||||||
p_CLKFBOUT_MULT=10,
|
|
||||||
p_CLKIN1_PERIOD=10.0,
|
|
||||||
p_REF_JITTER1=0.01,
|
|
||||||
p_STARTUP_WAIT="FALSE",
|
|
||||||
i_CLKIN1=clk100_buf,
|
|
||||||
i_PWRDWN=0,
|
|
||||||
i_RST=self.ps_rst,
|
|
||||||
i_CLKFBIN=clk_feedback_buf,
|
|
||||||
o_CLKFBOUT=clk_feedback,
|
|
||||||
p_CLKOUT0_DIVIDE=10,
|
|
||||||
p_CLKOUT0_PHASE=0.0,
|
|
||||||
p_CLKOUT0_DUTY_CYCLE=0.5,
|
|
||||||
o_CLKOUT0=clk_sys, # 100 MHz <- sys_clk
|
|
||||||
p_CLKOUT1_DIVIDE=5,
|
|
||||||
p_CLKOUT1_PHASE=0.0,
|
|
||||||
p_CLKOUT1_DUTY_CYCLE=0.5,
|
|
||||||
o_CLKOUT1=clk_idelay, # 200 MHZ <- 2 * sys_clk = 2*100 MHz
|
|
||||||
o_LOCKED=self.locked,
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
self.specials += Instance("BUFG", i_I=clk_feedback, o_O=clk_feedback_buf)
|
|
||||||
self.specials += Instance("BUFG", i_I=clk_sys, o_O=self.cd_sys.clk)
|
|
||||||
self.specials += Instance("BUFG", i_I=clk_idelay, o_O=self.cd_idelay.clk)
|
|
||||||
self.specials += Instance("BUFG", i_I=clk_idelay, o_O=self.cd_sys_double.clk)
|
|
||||||
|
|
||||||
|
|
||||||
# Ignore sys_clk to pll clkin path created by SoC's rst.
|
|
||||||
platform.add_false_path_constraints(self.cd_sys.clk, self.clkin)
|
|
||||||
|
|
||||||
self.specials += Instance("FD", p_INIT=1, i_D=~self.locked, i_C=self.cd_sys.clk, o_Q=self.cd_sys.rst)
|
|
||||||
|
|
||||||
|
|
||||||
class BaseSoC(PS7, AutoCSR):
|
|
||||||
def __init__(self, platform, passthrouh=False):
|
|
||||||
PS7.__init__(self, platform)
|
|
||||||
|
|
||||||
# TODO:
|
|
||||||
# LINIEN SPECIFIC csr_map - in the future should be moved
|
|
||||||
# to csr_devices list
|
|
||||||
self.csr_map = {
|
|
||||||
"adc": 9,
|
|
||||||
"fp_led0": 10,
|
|
||||||
"fp_led1": 11,
|
|
||||||
"fp_led2": 12,
|
|
||||||
"fp_led3": 13,
|
|
||||||
"dac": 14,
|
|
||||||
"adc_aux_ctrl": 15,
|
|
||||||
"dac_aux_ctrl": 16,
|
|
||||||
}
|
|
||||||
self.soc_name = "FastServo"
|
|
||||||
self.interconnect_slaves = []
|
|
||||||
self.csr_devices = []
|
|
||||||
|
|
||||||
self.platform = platform
|
|
||||||
|
|
||||||
self.submodules.crg = CRG(platform)
|
|
||||||
|
|
||||||
# # # AXI to system bus bridge
|
|
||||||
self.submodules.axi2sys = Axi2Sys()
|
|
||||||
self.submodules.sys2csr = Sys2CSR()
|
|
||||||
self.submodules.syscdc = SysCDC()
|
|
||||||
self.add_axi_gp_master(self.axi2sys.axi)
|
|
||||||
|
|
||||||
self.comb += [
|
|
||||||
self.axi2sys.axi.aclk.eq(ClockSignal("sys")),
|
|
||||||
self.axi2sys.axi.arstn.eq(self.frstn),
|
|
||||||
self.syscdc.target.connect(self.sys2csr.sys),
|
|
||||||
]
|
|
||||||
|
|
||||||
# ETH LEDS
|
|
||||||
self.comb += [
|
|
||||||
platform.request("eth_led", 0).eq(platform.request("from_eth_phy", 0)),
|
|
||||||
platform.request("eth_led", 1).eq(platform.request("from_eth_phy", 1)),
|
|
||||||
]
|
|
||||||
|
|
||||||
# I2C0 to Si5340 on Fast Servo
|
|
||||||
self.add_i2c_emio(platform, "ps7_i2c", 0)
|
|
||||||
|
|
||||||
# SPI0 - interface to main ADC and auxiliary ADC
|
|
||||||
self.add_spi_interface(platform, SpiInterface.ADC)
|
|
||||||
|
|
||||||
# SPI1 - interface to main DAC and auxiliary DAC
|
|
||||||
self.add_spi_interface(platform, SpiInterface.DAC)
|
|
||||||
|
|
||||||
# self.add_main_adc(platform)
|
|
||||||
self.submodules.adc = ADC(platform)
|
|
||||||
self.csr_devices.append("adc")
|
|
||||||
platform.add_false_path_constraints(self.crg.cd_sys.clk, self.adc.crg.cd_dco2d.clk)
|
|
||||||
|
|
||||||
# self.add_main_dac(platform)
|
|
||||||
self.submodules.dac = DAC(platform)
|
|
||||||
self.csr_devices.append("dac")
|
|
||||||
|
|
||||||
# DEBUG
|
|
||||||
if passthrouh:
|
|
||||||
DAC_DATA_WIDTH = 14
|
|
||||||
for ch in range(2):
|
|
||||||
saturate = Signal()
|
|
||||||
adc_signal = self.adc.data_out[ch]
|
|
||||||
self.comb += [
|
|
||||||
saturate.eq(adc_signal[-3:] != Replicate(adc_signal[-1], 3)),
|
|
||||||
self.dac.data_in[ch].eq(Mux(saturate,
|
|
||||||
Cat(Replicate(~adc_signal[-1], DAC_DATA_WIDTH-1), adc_signal[-1]),
|
|
||||||
adc_signal[:-2]))
|
|
||||||
]
|
|
||||||
|
|
||||||
si_5340_nrst = platform.request("nrst")
|
|
||||||
self.comb += si_5340_nrst.eq(1)
|
|
||||||
|
|
||||||
for i in range(4):
|
|
||||||
led_pin = platform.request("fp_led", i)
|
|
||||||
setattr(self.submodules, f"fp_led{i}", LED(led_pin))
|
|
||||||
self.csr_devices.append(f"fp_led{i}")
|
|
||||||
|
|
||||||
self.submodules.adc_aux_ctrl = AUX_ADC_CTRL(platform)
|
|
||||||
self.csr_devices.append("adc_aux_ctrl")
|
|
||||||
|
|
||||||
self.submodules.dac_aux_ctrl = AUX_DAC_CTRL(platform)
|
|
||||||
self.csr_devices.append("dac_aux_ctrl")
|
|
||||||
|
|
||||||
def add_spi_interface(self, platform, spi_type):
|
|
||||||
assert isinstance(spi_type, SpiInterface)
|
|
||||||
n = spi_type.value
|
|
||||||
|
|
||||||
ps7_spi_pads = platform.request("spi", spi_type.value)
|
|
||||||
spi_phy = SpiPhy(spi_type, ps7_spi_pads)
|
|
||||||
self.submodules += spi_phy
|
|
||||||
|
|
||||||
ps7_config_spi = {
|
|
||||||
f"PCW_SPI{n}_GRP_SS0_ENABLE" : "1",
|
|
||||||
f"PCW_SPI{n}_GRP_SS0_IO" : "EMIO",
|
|
||||||
f"PCW_SPI{n}_GRP_SS1_ENABLE" : "1",
|
|
||||||
f"PCW_SPI{n}_GRP_SS1_IO" : "EMIO",
|
|
||||||
f"PCW_SPI{n}_GRP_SS2_ENABLE" : "1",
|
|
||||||
f"PCW_SPI{n}_GRP_SS2_IO" : "EMIO",
|
|
||||||
f"PCW_SPI{n}_PERIPHERAL_ENABLE" : "1",
|
|
||||||
f"PCW_SPI{n}_SPI{n}_IO" : "EMIO",
|
|
||||||
f"PCW_SPI_PERIPHERAL_CLKSRC" : "IO PLL",
|
|
||||||
f"PCW_SPI_PERIPHERAL_DIVISOR0" : "10",
|
|
||||||
f"PCW_SPI_PERIPHERAL_FREQMHZ" : "166.666666",
|
|
||||||
}
|
|
||||||
self.add_ps7_config(ps7_config_spi)
|
|
||||||
|
|
||||||
self.cpu_params.update({
|
|
||||||
f"o_SPI{n}_MISO_O" : spi_phy.ps_miso_o,
|
|
||||||
f"o_SPI{n}_MISO_T" : spi_phy.ps_miso_t,
|
|
||||||
f"o_SPI{n}_MOSI_O" : spi_phy.ps_mosi_o,
|
|
||||||
f"o_SPI{n}_MOSI_T" : spi_phy.ps_mosi_t,
|
|
||||||
f"o_SPI{n}_SCLK_O" : spi_phy.ps_sclk_o,
|
|
||||||
f"o_SPI{n}_SCLK_T" : spi_phy.ps_sclk_t,
|
|
||||||
|
|
||||||
f"i_SPI{n}_SCLK_I" : spi_phy.ps_sclk_i,
|
|
||||||
f"i_SPI{n}_MOSI_I" : spi_phy.ps_mosi_i,
|
|
||||||
f"i_SPI{n}_MISO_I" : spi_phy.ps_miso_i,
|
|
||||||
f"i_SPI{n}_SS_I" : spi_phy.ps_ss_i,
|
|
||||||
f"o_SPI{n}_SS_O" : spi_phy.ps_ss[0],
|
|
||||||
f"o_SPI{n}_SS1_O" : spi_phy.ps_ss[1],
|
|
||||||
f"o_SPI{n}_SS2_O" : spi_phy.ps_ss[2],
|
|
||||||
f"o_SPI{n}_SS_T" : spi_phy.ps_ss_t,
|
|
||||||
})
|
|
||||||
|
|
||||||
def add_interconnect_slave(self, slave):
|
|
||||||
self.interconnect_slaves.append(slave)
|
|
||||||
|
|
||||||
def get_csr_dev_address(self, name, memory):
|
|
||||||
# TODO: switch to MiSoC-like address retriving from
|
|
||||||
# the list of CSR devices
|
|
||||||
if memory is not None:
|
|
||||||
name = name + "_" + memory.name_override
|
|
||||||
try:
|
|
||||||
return self.csr_map[name]
|
|
||||||
except KeyError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def soc_finalize(self):
|
|
||||||
# Overload this method to customize SystemInterconnect
|
|
||||||
# and csrbanks - especially useful in Linien
|
|
||||||
self.add_interconnect_slave(self.syscdc.source)
|
|
||||||
self.submodules.interconnect = SysInterconnect(
|
|
||||||
self.axi2sys.sys,
|
|
||||||
*self.interconnect_slaves
|
|
||||||
)
|
|
||||||
self.submodules.csrbanks = csr_bus.CSRBankArray(self,
|
|
||||||
self.get_csr_dev_address)
|
|
||||||
self.submodules.csrcon = csr_bus.Interconnect(
|
|
||||||
self.sys2csr.csr, self.csrbanks.get_buses()
|
|
||||||
)
|
|
||||||
|
|
||||||
def do_finalize(self):
|
|
||||||
self.soc_finalize()
|
|
||||||
PS7.do_finalize(self)
|
|
||||||
|
|
||||||
def build(self, *args, **kwargs):
|
|
||||||
self.platform.build(self, *args, **kwargs)
|
|
||||||
|
|
||||||
class LED(Module, AutoCSR):
|
|
||||||
def __init__(self, led):
|
|
||||||
|
|
||||||
self.led_out = CSRStorage(1)
|
|
||||||
|
|
||||||
self.comb += led.eq(self.led_out.storage)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import subprocess
|
|
||||||
from fast_servo.gateware.fast_servo_platform import Platform
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument("--debug", action="store_true", default=False, help="Hardwire ADC data to DAC")
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
root_path = os.getcwd()
|
|
||||||
platform = Platform()
|
|
||||||
fast_servo = BaseSoC(platform, passthrouh=args.debug)
|
|
||||||
|
|
||||||
build_dir = "builds/fast_servo_gw_debug" if args.debug else"builds/fast_servo_gw"
|
|
||||||
build_name = "top"
|
|
||||||
fast_servo.build(build_dir=build_dir, build_name=build_name, run=True)
|
|
||||||
os.chdir(os.path.join(root_path, build_dir))
|
|
||||||
with open(f"{build_name}.bif", "w") as f:
|
|
||||||
f.write(f"all:\n{{\n\t{build_name}.bit\n}}")
|
|
||||||
|
|
||||||
cmd = f"bootgen -image {build_name}.bif -arch zynq -process_bitstream bin -w on".split(" ")
|
|
||||||
subprocess.run(cmd)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,162 +0,0 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// LTC2195.v
|
|
||||||
//
|
|
||||||
// 8/03/21
|
|
||||||
// Jakub Matyas
|
|
||||||
//
|
|
||||||
// LTC2195 controller.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// `include "timescale.v"
|
|
||||||
`timescale 1ns/1ps // this was in the SelectIO design
|
|
||||||
|
|
||||||
module LTC2195(
|
|
||||||
input rst_in,
|
|
||||||
input clk200,
|
|
||||||
input DCO,
|
|
||||||
input DCO_2D,
|
|
||||||
input FR_in_p,
|
|
||||||
input FR_in_n,
|
|
||||||
input [3:0] D0_in_p,
|
|
||||||
input [3:0] D0_in_n,
|
|
||||||
input [3:0] D1_in_p,
|
|
||||||
input [3:0] D1_in_n,
|
|
||||||
input bitslip,
|
|
||||||
input [4:0] delay_val,
|
|
||||||
|
|
||||||
output reg [15:0] ADC0_out,
|
|
||||||
output reg [15:0] ADC1_out,
|
|
||||||
output reg [3:0] FR_out,
|
|
||||||
output wire [8:0] o_data_from_pins,
|
|
||||||
output idelay_rdy
|
|
||||||
);
|
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// // LVDS inputs
|
|
||||||
|
|
||||||
localparam N_BITS = 4;
|
|
||||||
localparam N_LANES = 9; // for each channel 4 lanes + 1 lane for FRAME
|
|
||||||
wire [N_LANES-1:0] data_in_p, data_in_n, data_in_from_pins, data_in_from_pins_delay;
|
|
||||||
assign data_in_p = {FR_in_p, D1_in_p, D0_in_p};
|
|
||||||
assign data_in_n = {FR_in_n, D1_in_n, D0_in_n};
|
|
||||||
assign o_data_from_pins = data_in_from_pins_delay;
|
|
||||||
|
|
||||||
|
|
||||||
wire [N_LANES*4 -1:0] data_out;
|
|
||||||
wire [35:0 ]data_out_mod;
|
|
||||||
|
|
||||||
|
|
||||||
assign data_out_mod = {~data_out[35:24], data_out[23:20], ~data_out[19:16], data_out[15:0]};
|
|
||||||
|
|
||||||
|
|
||||||
always @(posedge DCO_2D) begin
|
|
||||||
ADC0_out <= {
|
|
||||||
data_out_mod[0], data_out_mod[4], data_out_mod[1], data_out_mod[5],
|
|
||||||
data_out_mod[2], data_out_mod[6], data_out_mod[3], data_out_mod[7],
|
|
||||||
data_out_mod[8], data_out_mod[12], data_out_mod[9], data_out_mod[13],
|
|
||||||
data_out_mod[10], data_out_mod[14], data_out_mod[11], data_out_mod[15]
|
|
||||||
};
|
|
||||||
|
|
||||||
ADC1_out <= {
|
|
||||||
data_out_mod[16 + 0], data_out_mod[16 + 4], data_out_mod[16 + 1], data_out_mod[16 + 5],
|
|
||||||
data_out_mod[16 + 2], data_out_mod[16 + 6], data_out_mod[16 + 3], data_out_mod[16 + 7],
|
|
||||||
data_out_mod[16 + 8], data_out_mod[16 + 12], data_out_mod[16 + 9], data_out_mod[16 + 13],
|
|
||||||
data_out_mod[16 + 10], data_out_mod[16 + 14], data_out_mod[16 + 11], data_out_mod[16 + 15]
|
|
||||||
};
|
|
||||||
FR_out <= {data_out_mod[32], data_out_mod[33], data_out_mod[34], data_out_mod[35]}; // value that arrived first is LSB, therefore reversing order
|
|
||||||
end
|
|
||||||
|
|
||||||
wire s_idelay_rdy;
|
|
||||||
IDELAYCTRL IDELAYCTRL_inst (
|
|
||||||
.RDY(s_idelay_rdy), // 1-bit output: Ready output
|
|
||||||
.REFCLK(clk200), // 1-bit input: Reference clock input
|
|
||||||
.RST(s_rst) // 1-bit input: Active high reset input
|
|
||||||
);
|
|
||||||
|
|
||||||
assign idelay_rdy = s_idelay_rdy;
|
|
||||||
|
|
||||||
|
|
||||||
reg s_rst;
|
|
||||||
reg [5:0] rst_cnt;
|
|
||||||
wire serdes_o;
|
|
||||||
|
|
||||||
always @(posedge DCO_2D) begin
|
|
||||||
if (rst_in) begin
|
|
||||||
s_rst <= 1'b1;
|
|
||||||
rst_cnt <= 'b0;
|
|
||||||
end else begin
|
|
||||||
if (rst_cnt == 22)
|
|
||||||
s_rst <= 'b0;
|
|
||||||
else
|
|
||||||
rst_cnt <= rst_cnt + 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
genvar lane;
|
|
||||||
generate for (lane=0; lane<N_LANES; lane=lane+1) begin
|
|
||||||
IBUFDS #(
|
|
||||||
.DIFF_TERM("TRUE")
|
|
||||||
)
|
|
||||||
ibufds_inst (
|
|
||||||
.I(data_in_p[lane]),
|
|
||||||
.IB(data_in_n[lane]),
|
|
||||||
.O(data_in_from_pins[lane])
|
|
||||||
);
|
|
||||||
IDELAYE2 #(
|
|
||||||
.CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE)
|
|
||||||
.DELAY_SRC("IDATAIN"), // Delay input (IDATAIN, DATAIN)
|
|
||||||
.HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
|
|
||||||
.IDELAY_TYPE("VAR_LOAD"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
|
|
||||||
.IDELAY_VALUE(0), // Input delay tap setting (0-31)
|
|
||||||
.PIPE_SEL("FALSE"), // Select pipelined mode, FALSE, TRUE
|
|
||||||
.REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
|
|
||||||
.SIGNAL_PATTERN("DATA") // DATA, CLOCK input signal
|
|
||||||
)
|
|
||||||
IDELAYE2_inst (
|
|
||||||
.C(clk200),
|
|
||||||
.CE('b0),
|
|
||||||
.CNTVALUEIN(delay_val),
|
|
||||||
.LD(1'b1),
|
|
||||||
.DATAOUT(data_in_from_pins_delay[lane]), // 1-bit output: Delayed data output
|
|
||||||
.IDATAIN(data_in_from_pins[lane]), // 1-bit input: Data input from the I/O
|
|
||||||
.LDPIPEEN (1'b0),
|
|
||||||
.REGRST (1'b0),
|
|
||||||
.CINVCTRL (1'b0)
|
|
||||||
);
|
|
||||||
|
|
||||||
ISERDESE2 #(
|
|
||||||
.DATA_RATE("DDR"),
|
|
||||||
.DATA_WIDTH(3'd4),
|
|
||||||
.INTERFACE_TYPE("NETWORKING"),
|
|
||||||
.IOBDELAY("BOTH"),
|
|
||||||
.SERDES_MODE("MASTER"),
|
|
||||||
.NUM_CE(2'd2)
|
|
||||||
)
|
|
||||||
iserdes_inst (
|
|
||||||
.CE1(1'd1),
|
|
||||||
.CE2(1'd1),
|
|
||||||
.DYNCLKDIVSEL('b0),
|
|
||||||
.DYNCLKSEL('b0),
|
|
||||||
.CLK(DCO),
|
|
||||||
.CLKB(!DCO),
|
|
||||||
.CLKDIV(DCO_2D),
|
|
||||||
// .D(data_in_from_pins[lane]),
|
|
||||||
.DDLY(data_in_from_pins_delay[lane]),
|
|
||||||
.RST(s_rst),
|
|
||||||
.BITSLIP(bitslip),
|
|
||||||
// DATA is MSB first and OUTA is LANE0, so in case of OUTA:
|
|
||||||
// Q1 = D9
|
|
||||||
// Q2 = D11
|
|
||||||
// Q3 = D13
|
|
||||||
// Q4 = D15
|
|
||||||
.Q1(data_out[lane*N_BITS + 3]),
|
|
||||||
.Q2(data_out[lane*N_BITS + 2]),
|
|
||||||
.Q3(data_out[lane*N_BITS + 1]),
|
|
||||||
.Q4(data_out[lane*N_BITS + 0])
|
|
||||||
);
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
endmodule
|
|
@ -1,265 +0,0 @@
|
|||||||
/**
|
|
||||||
* $Id: axi_slave.v 961 2014-01-21 11:40:39Z matej.oblak $
|
|
||||||
*
|
|
||||||
* @brief Red Pitaya symplified AXI slave.
|
|
||||||
*
|
|
||||||
* @Author Matej Oblak
|
|
||||||
*
|
|
||||||
* (c) Red Pitaya http://www.redpitaya.com
|
|
||||||
*
|
|
||||||
* This part of code is written in Verilog hardware description language (HDL).
|
|
||||||
* Please visit http://en.wikipedia.org/wiki/Verilog
|
|
||||||
* for more details on the language used herein.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GENERAL DESCRIPTION:
|
|
||||||
*
|
|
||||||
* AXI slave used also for simple bus master.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* /------\
|
|
||||||
* WR ADDRESS ----> | WR |
|
|
||||||
* WR DATA ----> | | -----------
|
|
||||||
* WR RESPONSE <---- | CH | |
|
|
||||||
* \------/ /--------\
|
|
||||||
* | SIMPLE | ---> WR/RD ADDRRESS
|
|
||||||
* AXI | | ---> WR DATA
|
|
||||||
* | RP | <--- RD DATA
|
|
||||||
* | BUS | <--- ACKNOWLEDGE
|
|
||||||
* /------\ \--------/
|
|
||||||
* RD ADDRESS ----> | RD | |
|
|
||||||
* RD DATA <---- | CH | -----------
|
|
||||||
* \------/
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Because AXI bus is quite complex simplier bus was created.
|
|
||||||
*
|
|
||||||
* It combines write and read channel, where write has bigger priority. Command
|
|
||||||
* is then send forward to red pitaya bus. When wite or read acknowledge is
|
|
||||||
* received AXI response is created and new AXI is accepted.
|
|
||||||
*
|
|
||||||
* To prevent AXI lockups because no response is received, this slave creates its
|
|
||||||
* own after 32 cycles (ack_cnt).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module axi_slave
|
|
||||||
#(
|
|
||||||
parameter AXI_DW = 64 , // data width (8,16,...,1024)
|
|
||||||
parameter AXI_AW = 32 , // address width
|
|
||||||
parameter AXI_IW = 8 , // ID width
|
|
||||||
parameter AXI_SW = AXI_DW >> 3 // strobe width - 1 bit for every data byte
|
|
||||||
)
|
|
||||||
(
|
|
||||||
// global signals
|
|
||||||
input axi_clk_i , //!< AXI global clock
|
|
||||||
input axi_rstn_i , //!< AXI global reset
|
|
||||||
|
|
||||||
// axi write address channel
|
|
||||||
input [ AXI_IW-1: 0] axi_awid_i , //!< AXI write address ID
|
|
||||||
input [ AXI_AW-1: 0] axi_awaddr_i , //!< AXI write address
|
|
||||||
input [ 4-1: 0] axi_awlen_i , //!< AXI write burst length
|
|
||||||
input [ 3-1: 0] axi_awsize_i , //!< AXI write burst size
|
|
||||||
input [ 2-1: 0] axi_awburst_i , //!< AXI write burst type
|
|
||||||
input [ 2-1: 0] axi_awlock_i , //!< AXI write lock type
|
|
||||||
input [ 4-1: 0] axi_awcache_i , //!< AXI write cache type
|
|
||||||
input [ 3-1: 0] axi_awprot_i , //!< AXI write protection type
|
|
||||||
input axi_awvalid_i , //!< AXI write address valid
|
|
||||||
output axi_awready_o , //!< AXI write ready
|
|
||||||
|
|
||||||
// axi write data channel
|
|
||||||
input [ AXI_IW-1: 0] axi_wid_i , //!< AXI write data ID
|
|
||||||
input [ AXI_DW-1: 0] axi_wdata_i , //!< AXI write data
|
|
||||||
input [ AXI_SW-1: 0] axi_wstrb_i , //!< AXI write strobes
|
|
||||||
input axi_wlast_i , //!< AXI write last
|
|
||||||
input axi_wvalid_i , //!< AXI write valid
|
|
||||||
output axi_wready_o , //!< AXI write ready
|
|
||||||
|
|
||||||
// axi write response channel
|
|
||||||
output [ AXI_IW-1: 0] axi_bid_o , //!< AXI write response ID
|
|
||||||
output reg [ 2-1: 0] axi_bresp_o , //!< AXI write response
|
|
||||||
output reg axi_bvalid_o , //!< AXI write response valid
|
|
||||||
input axi_bready_i , //!< AXI write response ready
|
|
||||||
|
|
||||||
// axi read address channel
|
|
||||||
input [ AXI_IW-1: 0] axi_arid_i , //!< AXI read address ID
|
|
||||||
input [ AXI_AW-1: 0] axi_araddr_i , //!< AXI read address
|
|
||||||
input [ 4-1: 0] axi_arlen_i , //!< AXI read burst length
|
|
||||||
input [ 3-1: 0] axi_arsize_i , //!< AXI read burst size
|
|
||||||
input [ 2-1: 0] axi_arburst_i , //!< AXI read burst type
|
|
||||||
input [ 2-1: 0] axi_arlock_i , //!< AXI read lock type
|
|
||||||
input [ 4-1: 0] axi_arcache_i , //!< AXI read cache type
|
|
||||||
input [ 3-1: 0] axi_arprot_i , //!< AXI read protection type
|
|
||||||
input axi_arvalid_i , //!< AXI read address valid
|
|
||||||
output axi_arready_o , //!< AXI read address ready
|
|
||||||
|
|
||||||
// axi read data channel
|
|
||||||
output [ AXI_IW-1: 0] axi_rid_o , //!< AXI read response ID
|
|
||||||
output reg [ AXI_DW-1: 0] axi_rdata_o , //!< AXI read data
|
|
||||||
output reg [ 2-1: 0] axi_rresp_o , //!< AXI read response
|
|
||||||
output reg axi_rlast_o , //!< AXI read last
|
|
||||||
output reg axi_rvalid_o , //!< AXI read response valid
|
|
||||||
input axi_rready_i , //!< AXI read response ready
|
|
||||||
|
|
||||||
// RP system read/write channel
|
|
||||||
output [ AXI_AW-1: 0] sys_addr_o , //!< system bus read/write address.
|
|
||||||
output [ AXI_DW-1: 0] sys_wdata_o , //!< system bus write data.
|
|
||||||
output reg [ AXI_SW-1: 0] sys_sel_o , //!< system bus write byte select.
|
|
||||||
output reg sys_wen_o , //!< system bus write enable.
|
|
||||||
output reg sys_ren_o , //!< system bus read enable.
|
|
||||||
input [ AXI_DW-1: 0] sys_rdata_i , //!< system bus read data.
|
|
||||||
input sys_err_i , //!< system bus error indicator.
|
|
||||||
input sys_ack_i //!< system bus acknowledge signal.
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// AXI slave Module
|
|
||||||
wire ack ;
|
|
||||||
reg [ 6-1: 0] ack_cnt ;
|
|
||||||
|
|
||||||
reg rd_do ;
|
|
||||||
reg [ AXI_IW-1: 0] rd_arid ;
|
|
||||||
reg [ AXI_AW-1: 0] rd_araddr ;
|
|
||||||
reg rd_error ;
|
|
||||||
wire rd_errorw ;
|
|
||||||
|
|
||||||
reg wr_do ;
|
|
||||||
reg [ AXI_IW-1: 0] wr_awid ;
|
|
||||||
reg [ AXI_AW-1: 0] wr_awaddr ;
|
|
||||||
reg [ AXI_IW-1: 0] wr_wid ;
|
|
||||||
reg [ AXI_DW-1: 0] wr_wdata ;
|
|
||||||
reg wr_error ;
|
|
||||||
wire wr_errorw ;
|
|
||||||
|
|
||||||
assign wr_errorw = (axi_awlen_i != 4'h0) || (axi_awsize_i != 3'b010); // error if write burst and more/less than 4B transfer
|
|
||||||
assign rd_errorw = (axi_arlen_i != 4'h0) || (axi_arsize_i != 3'b010); // error if read burst and more/less than 4B transfer
|
|
||||||
|
|
||||||
always @(posedge axi_clk_i) begin
|
|
||||||
if (axi_rstn_i == 1'b0) begin
|
|
||||||
rd_do <= 1'b0 ;
|
|
||||||
rd_error <= 1'b0 ;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
if (axi_arvalid_i && !rd_do && !axi_awvalid_i && !wr_do) // accept just one read request - write has priority
|
|
||||||
rd_do <= 1'b1 ;
|
|
||||||
else if (axi_rready_i && rd_do && ack)
|
|
||||||
rd_do <= 1'b0 ;
|
|
||||||
|
|
||||||
if (axi_arvalid_i && axi_arready_o) begin // latch ID and address
|
|
||||||
rd_arid <= axi_arid_i ;
|
|
||||||
rd_araddr <= axi_araddr_i ;
|
|
||||||
rd_error <= rd_errorw ;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
always @(posedge axi_clk_i) begin
|
|
||||||
if (axi_rstn_i == 1'b0) begin
|
|
||||||
wr_do <= 1'b0 ;
|
|
||||||
wr_error <= 1'b0 ;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
if (axi_awvalid_i && !wr_do && !rd_do) // accept just one write request - if idle
|
|
||||||
wr_do <= 1'b1 ;
|
|
||||||
else if (axi_bready_i && wr_do && ack)
|
|
||||||
wr_do <= 1'b0 ;
|
|
||||||
|
|
||||||
if (axi_awvalid_i && axi_awready_o) begin // latch ID and address
|
|
||||||
wr_awid <= axi_awid_i ;
|
|
||||||
wr_awaddr <= axi_awaddr_i ;
|
|
||||||
wr_error <= wr_errorw ;
|
|
||||||
end
|
|
||||||
|
|
||||||
if (axi_wvalid_i && wr_do) begin // latch ID and write data
|
|
||||||
wr_wid <= axi_wid_i ;
|
|
||||||
wr_wdata <= axi_wdata_i ;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assign axi_awready_o = !wr_do && !rd_do ;
|
|
||||||
assign axi_wready_o = (wr_do && axi_wvalid_i) || (wr_errorw && axi_wvalid_i) ;
|
|
||||||
assign axi_bid_o = wr_awid ;
|
|
||||||
//assign axi_bresp_o = {wr_error,1'b0} ; // 2'b10 SLVERR
|
|
||||||
//assign axi_bvalid_o = (sys_wen_o && axi_bready_i) || (wr_error && axi_bready_i) ;
|
|
||||||
|
|
||||||
assign axi_arready_o = !rd_do && !wr_do && !axi_awvalid_i ;
|
|
||||||
assign axi_rid_o = rd_arid ;
|
|
||||||
//assign axi_rdata_o = sys_rdata_i ;
|
|
||||||
|
|
||||||
always @(posedge axi_clk_i) begin
|
|
||||||
if (axi_rstn_i == 1'b0) begin
|
|
||||||
axi_bvalid_o <= 1'b0 ;
|
|
||||||
axi_bresp_o <= 2'h0 ;
|
|
||||||
axi_rlast_o <= 1'b0 ;
|
|
||||||
axi_rvalid_o <= 1'b0 ;
|
|
||||||
axi_rresp_o <= 2'h0 ;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
axi_bvalid_o <= wr_do && ack ;
|
|
||||||
axi_bresp_o <= {(wr_error || ack_cnt[5]),1'b0} ; // 2'b10 SLVERR 2'b00 OK
|
|
||||||
axi_rlast_o <= rd_do && ack ;
|
|
||||||
axi_rvalid_o <= rd_do && ack ;
|
|
||||||
axi_rresp_o <= {(rd_error || ack_cnt[5]),1'b0} ; // 2'b10 SLVERR 2'b00 OK
|
|
||||||
axi_rdata_o <= sys_rdata_i ;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
// acknowledge protection
|
|
||||||
always @(posedge axi_clk_i) begin
|
|
||||||
if (axi_rstn_i == 1'b0) begin
|
|
||||||
ack_cnt <= 6'h0 ;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
if ((axi_arvalid_i && axi_arready_o) || (axi_awvalid_i && axi_awready_o)) // rd || wr request
|
|
||||||
ack_cnt <= 6'h1 ;
|
|
||||||
else if (ack)
|
|
||||||
ack_cnt <= 6'h0 ;
|
|
||||||
else if (|ack_cnt)
|
|
||||||
ack_cnt <= ack_cnt + 6'h1 ;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assign ack = sys_ack_i || ack_cnt[5] || (rd_do && rd_errorw) || (wr_do && wr_errorw); // bus acknowledge or timeout or error
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------
|
|
||||||
// Simple slave interface
|
|
||||||
|
|
||||||
always @(posedge axi_clk_i) begin
|
|
||||||
if (axi_rstn_i == 1'b0) begin
|
|
||||||
sys_wen_o <= 1'b0 ;
|
|
||||||
sys_ren_o <= 1'b0 ;
|
|
||||||
sys_sel_o <= {AXI_SW{1'b0}} ;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
sys_wen_o <= wr_do && axi_wvalid_i && !wr_errorw ;
|
|
||||||
sys_ren_o <= axi_arvalid_i && axi_arready_o && !rd_errorw ;
|
|
||||||
sys_sel_o <= {AXI_SW{1'b1}} ;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assign sys_addr_o = rd_do ? rd_araddr : wr_awaddr ;
|
|
||||||
assign sys_wdata_o = wr_wdata ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
|
@ -1,128 +0,0 @@
|
|||||||
/**
|
|
||||||
* $Id: bus_clk_bridge.v 961 2014-01-21 11:40:39Z matej.oblak $
|
|
||||||
*
|
|
||||||
* @brief Red Pitaya system bus clock crossing bridge.
|
|
||||||
*
|
|
||||||
* @Author Matej Oblak
|
|
||||||
*
|
|
||||||
* (c) Red Pitaya http://www.redpitaya.com
|
|
||||||
*
|
|
||||||
* This part of code is written in Verilog hardware description language (HDL).
|
|
||||||
* Please visit http://en.wikipedia.org/wiki/Verilog
|
|
||||||
* for more details on the language used herein.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GENERAL DESCRIPTION:
|
|
||||||
*
|
|
||||||
* Clock domain bridge for system bus.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* /------\
|
|
||||||
* SYSTEM | | PROCESSING
|
|
||||||
* BUS <-----> | SYNC | <-----> BUS
|
|
||||||
* | |
|
|
||||||
* \------/
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* System bus runs on one clock domain while processing runs on separate. To
|
|
||||||
* simplify transition of writing and reading data this bridge was created.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module bus_clk_bridge
|
|
||||||
(
|
|
||||||
// system bus
|
|
||||||
input sys_clk_i , //!< bus clock
|
|
||||||
input sys_rstn_i , //!< bus reset - active low
|
|
||||||
input [ 32-1: 0] sys_addr_i , //!< bus address
|
|
||||||
input [ 32-1: 0] sys_wdata_i , //!< bus write data
|
|
||||||
input [ 4-1: 0] sys_sel_i , //!< bus write byte select
|
|
||||||
input sys_wen_i , //!< bus write enable
|
|
||||||
input sys_ren_i , //!< bus read enable
|
|
||||||
output [ 32-1: 0] sys_rdata_o , //!< bus read data
|
|
||||||
output sys_err_o , //!< bus error indicator
|
|
||||||
output sys_ack_o , //!< bus acknowledge signal
|
|
||||||
|
|
||||||
|
|
||||||
// Destination bus
|
|
||||||
input clk_i , //!< clock
|
|
||||||
input rstn_i , //!< reset - active low
|
|
||||||
output reg [ 32-1: 0] addr_o , //!< address
|
|
||||||
output reg [ 32-1: 0] wdata_o , //!< write data
|
|
||||||
output wen_o , //!< write enable
|
|
||||||
output ren_o , //!< read enable
|
|
||||||
input [ 32-1: 0] rdata_i , //!< read data
|
|
||||||
input err_i , //!< error indicator
|
|
||||||
input ack_i //!< acknowledge signal
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
|
||||||
// Synchronize signals between clock domains
|
|
||||||
|
|
||||||
reg sys_rd ;
|
|
||||||
reg sys_wr ;
|
|
||||||
reg sys_do ;
|
|
||||||
reg [ 2-1: 0] sys_sync ;
|
|
||||||
reg sys_done ;
|
|
||||||
reg dst_do ;
|
|
||||||
reg [ 2-1: 0] dst_sync ;
|
|
||||||
reg dst_done ;
|
|
||||||
|
|
||||||
always @(posedge sys_clk_i) begin
|
|
||||||
if (sys_rstn_i == 1'b0) begin
|
|
||||||
sys_rd <= 1'b0 ;
|
|
||||||
sys_wr <= 1'b0 ;
|
|
||||||
sys_do <= 1'b0 ;
|
|
||||||
sys_sync <= 2'h0 ;
|
|
||||||
sys_done <= 1'b0 ;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
|
|
||||||
if ((sys_do == sys_done) && (sys_wen_i || sys_ren_i)) begin
|
|
||||||
addr_o <= sys_addr_i ;
|
|
||||||
wdata_o <= sys_wdata_i ;
|
|
||||||
sys_rd <= sys_ren_i ;
|
|
||||||
sys_wr <= sys_wen_i ;
|
|
||||||
sys_do <= !sys_do ;
|
|
||||||
end
|
|
||||||
|
|
||||||
sys_sync <= {sys_sync[0], dst_done};
|
|
||||||
sys_done <= sys_sync[1];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
always @(posedge clk_i) begin
|
|
||||||
if (rstn_i == 1'b0) begin
|
|
||||||
dst_do <= 1'b0 ;
|
|
||||||
dst_sync <= 2'h0 ;
|
|
||||||
dst_done <= 1'b0 ;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
dst_sync <= {dst_sync[0], sys_do};
|
|
||||||
dst_do <= dst_sync[1];
|
|
||||||
|
|
||||||
if (ack_i && (dst_do != dst_done))
|
|
||||||
dst_done <= dst_do;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assign ren_o = sys_rd && (dst_sync[1]^dst_do);
|
|
||||||
assign wen_o = sys_wr && (dst_sync[1]^dst_do);
|
|
||||||
|
|
||||||
|
|
||||||
assign sys_rdata_o = rdata_i ;
|
|
||||||
assign sys_err_o = err_i ;
|
|
||||||
assign sys_ack_o = sys_done ^ sys_sync[1] ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
|
@ -1,111 +0,0 @@
|
|||||||
`timescale 1ns / 1ps
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Company: WUT
|
|
||||||
// Engineer: Jakub Matyas
|
|
||||||
//
|
|
||||||
// Create Date: 03/02/2023 01:39:08 PM
|
|
||||||
// Design Name:
|
|
||||||
// Module Name: spi2threewire
|
|
||||||
// Project Name:
|
|
||||||
// Target Devices:
|
|
||||||
// Tool Versions:
|
|
||||||
// Description:
|
|
||||||
//
|
|
||||||
// Dependencies:
|
|
||||||
//
|
|
||||||
// Revision:
|
|
||||||
// Revision 0.01 - File Created
|
|
||||||
// Additional Comments:
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
module spi2threewire (
|
|
||||||
output ps_sclk_i,
|
|
||||||
input ps_sclk_o,
|
|
||||||
input ps_sclk_t,
|
|
||||||
|
|
||||||
output ps_mosi_i,
|
|
||||||
input ps_mosi_o,
|
|
||||||
input ps_mosi_t,
|
|
||||||
|
|
||||||
output ps_miso_i,
|
|
||||||
input ps_miso_o,
|
|
||||||
input ps_miso_t,
|
|
||||||
|
|
||||||
output ps_ss_i,
|
|
||||||
input [2:0] ps_ss,
|
|
||||||
input ps_ss_t,
|
|
||||||
|
|
||||||
output o_ss,
|
|
||||||
output o_sclk,
|
|
||||||
inout sdio
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
assign ps_sclk_i = 1'b0;
|
|
||||||
assign ps_mosi_i = 1'b0;
|
|
||||||
assign ps_ss_i = 1'b1;
|
|
||||||
|
|
||||||
|
|
||||||
reg [3:0] bit_count = 'd0;
|
|
||||||
|
|
||||||
// rd_wr_n - whether it will be READ transaction or WRITE
|
|
||||||
// first bit of the command
|
|
||||||
reg rd_wr_n = 'd0;
|
|
||||||
reg sdio_buffer_direction = 'd0;
|
|
||||||
|
|
||||||
wire s_sclk;
|
|
||||||
wire s_csn;
|
|
||||||
wire s_sdio_buffer_direction;
|
|
||||||
|
|
||||||
assign s_sclk = ps_sclk_o;
|
|
||||||
assign s_csn = ps_ss[0];
|
|
||||||
assign o_ss = s_csn;
|
|
||||||
|
|
||||||
// 1 if there is a SPI tranmsission going on (CS_N is LOW)
|
|
||||||
// AND transmission is of READ type
|
|
||||||
// 0 otherwise
|
|
||||||
assign s_sdio_buffer_direction = sdio_buffer_direction & ~s_csn;
|
|
||||||
|
|
||||||
always @(posedge s_sclk or posedge s_csn) begin
|
|
||||||
if (s_csn == 1'b1) begin
|
|
||||||
// after the transmission, fill bit counter with ZEROS
|
|
||||||
// and zero transmission type (rd_wr_n)
|
|
||||||
bit_count <= 4'd0;
|
|
||||||
rd_wr_n <= 1'b0;
|
|
||||||
end else begin
|
|
||||||
// on every rising edge increment bit counter
|
|
||||||
// sample first bit to get the knowledge of the transmission type
|
|
||||||
bit_count <= (bit_count < 4'd15) ? bit_count + 1'b1 : bit_count;
|
|
||||||
if (bit_count == 4'b0)
|
|
||||||
rd_wr_n <= ps_mosi_o;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(negedge s_sclk or posedge s_csn) begin
|
|
||||||
if (s_csn == 1'b1)
|
|
||||||
sdio_buffer_direction <= 1'b0;
|
|
||||||
else begin
|
|
||||||
if (bit_count == 4'd8)
|
|
||||||
// after the 8th bit, on falling edge,
|
|
||||||
// set the SDIO buffer direction
|
|
||||||
// accordingly to the transmission type
|
|
||||||
sdio_buffer_direction <= rd_wr_n;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
IOBUF IOBUF_inst (
|
|
||||||
.O(ps_miso_i),
|
|
||||||
.IO(sdio),
|
|
||||||
.I(ps_mosi_o),
|
|
||||||
.T(s_sdio_buffer_direction) // 3-state enable input, high=input (from ext), low=output
|
|
||||||
);
|
|
||||||
|
|
||||||
OBUFT sclk_buf (
|
|
||||||
.O(o_sclk),
|
|
||||||
.I(ps_sclk_o),
|
|
||||||
.T('b0)
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule
|
|
@ -1,227 +0,0 @@
|
|||||||
diff --git a/linien-gui/linien_gui/ui/general_panel.ui b/linien_gui/ui/general_panel.ui
|
|
||||||
index 7cf74a7..6c2bd45 100644
|
|
||||||
--- a/linien-gui/linien_gui/ui/general_panel.ui
|
|
||||||
+++ b/linien_gui/ui/general_panel.ui
|
|
||||||
@@ -128,11 +128,6 @@
|
|
||||||
<string>FAST OUT 2</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
- <item>
|
|
||||||
- <property name="text">
|
|
||||||
- <string>ANALOG OUT 0</string>
|
|
||||||
- </property>
|
|
||||||
- </item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
@@ -213,11 +208,6 @@
|
|
||||||
<string>FAST OUT 2</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
- <item>
|
|
||||||
- <property name="text">
|
|
||||||
- <string>ANALOG OUT 0</string>
|
|
||||||
- </property>
|
|
||||||
- </item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>disabled</string>
|
|
||||||
@@ -389,6 +379,9 @@
|
|
||||||
<property name="text">
|
|
||||||
<string>ANALOG OUT 0</string>
|
|
||||||
</property>
|
|
||||||
+ <property name="visible">
|
|
||||||
+ <bool>false</bool>
|
|
||||||
+ </property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
@@ -399,6 +392,9 @@
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
+ <property name="visible">
|
|
||||||
+ <bool>false</bool>
|
|
||||||
+ </property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>positive</string>
|
|
||||||
@@ -619,6 +615,9 @@
|
|
||||||
<property name="title">
|
|
||||||
<string>Slow Analog Outputs (0-1.8V)</string>
|
|
||||||
</property>
|
|
||||||
+ <property name="visible">
|
|
||||||
+ <bool>false</bool>
|
|
||||||
+ </property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_20">
|
|
||||||
diff --git a/linien-gui/linien_gui/ui/main_window.ui b/linien_gui/ui/main_window.ui
|
|
||||||
index 3d8b8bf..72f6159 100644
|
|
||||||
--- a/linien-gui/linien_gui/ui/main_window.ui
|
|
||||||
+++ b/linien_gui/ui/main_window.ui
|
|
||||||
@@ -145,10 +145,10 @@ p, li { white-space: pre-wrap; }
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
- <double>-1.000000000000000</double>
|
|
||||||
+ <double>-0.500000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
- <double>1.000000000000000</double>
|
|
||||||
+ <double>0.500000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.100000000000000</double>
|
|
||||||
@@ -199,13 +199,13 @@ p, li { white-space: pre-wrap; }lin
|
|
||||||
<double>0.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
- <double>1.000000000000000</double>
|
|
||||||
+ <double>0.500000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.100000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
- <double>1.000000000000000</double>
|
|
||||||
+ <double>0.500000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
@@ -242,7 +242,6 @@ p, li { white-space: pre-wrap; }
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
- <weight>75</weight>
|
|
||||||
<bold>true</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
@@ -278,7 +277,6 @@ p, li { white-space: pre-wrap; }
|
|
||||||
<widget class="QLabel" name="label_5">
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
- <weight>75</weight>
|
|
||||||
<bold>true</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
@@ -366,7 +364,6 @@ p, li { white-space: pre-wrap; }
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
- <weight>75</weight>
|
|
||||||
<bold>true</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
diff --git a/linien-gui/linien_gui/ui/modulation_sweep_panel.ui b/linien_gui/ui/modulation_sweep_panel.ui
|
|
||||||
index 6d8af14..29c8a63 100644
|
|
||||||
--- a/linien-gui/linien_gui/ui/modulation_sweep_panel.ui
|
|
||||||
+++ b/linien_gui/ui/modulation_sweep_panel.ui
|
|
||||||
@@ -68,7 +68,7 @@
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
- <double>2.000000000000000</double>
|
|
||||||
+ <double>0.500000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.100000000000000</double>
|
|
||||||
@@ -105,82 +105,82 @@
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>3.8 kHz</string>
|
|
||||||
+ <string>3.04 kHz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>1.9 kHz</string>
|
|
||||||
+ <string>1.52 kHz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>954 Hz</string>
|
|
||||||
+ <string>763 Hz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>477 Hz</string>
|
|
||||||
+ <string>382 Hz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>238 Hz</string>
|
|
||||||
+ <string>190 Hz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>119 Hz</string>
|
|
||||||
+ <string>95 Hz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>59 Hz</string>
|
|
||||||
+ <string>47 Hz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>30 Hz</string>
|
|
||||||
+ <string>24 Hz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>15 Hz</string>
|
|
||||||
+ <string>12 Hz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>7.5 Hz</string>
|
|
||||||
+ <string>6 Hz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>3.7 Hz</string>
|
|
||||||
+ <string>2.96 Hz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>1.9 Hz</string>
|
|
||||||
+ <string>1.52 Hz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>0.93 Hz</string>
|
|
||||||
+ <string>0.74 Hz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>0.47 Hz</string>
|
|
||||||
+ <string>0.38 Hz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>0.23 Hz</string>
|
|
||||||
+ <string>0.18 Hz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
- <string>0.12 Hz</string>
|
|
||||||
+ <string>0.10 Hz</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
@ -1,43 +0,0 @@
|
|||||||
diff --git a/linien_gui/ui/device_manager.py b/linien_gui/ui/device_manager.py
|
|
||||||
index e584825..16994ad 100644
|
|
||||||
--- a/linien_gui/ui/device_manager.py
|
|
||||||
+++ b/linien_gui/ui/device_manager.py
|
|
||||||
@@ -109,19 +109,13 @@ class DeviceManager(QtWidgets.QMainWindow):
|
|
||||||
) -> None:
|
|
||||||
loading_dialog.hide()
|
|
||||||
if not aborted:
|
|
||||||
- display_question = (
|
|
||||||
+ # Fast Servo does not support OTA Update
|
|
||||||
+ display_error = (
|
|
||||||
f"Server version ({remote_version}) does not match the client "
|
|
||||||
- f"({client_version}) version. Should the corresponding server "
|
|
||||||
- f"version be installed?"
|
|
||||||
+ f"({client_version}) version."
|
|
||||||
+ f"Please install a matching server and client version"
|
|
||||||
)
|
|
||||||
- if question_dialog(
|
|
||||||
- self, display_question, "Install corresponding version?"
|
|
||||||
- ):
|
|
||||||
- show_installation_progress_widget(
|
|
||||||
- parent=self,
|
|
||||||
- device=device,
|
|
||||||
- callback=lambda: self.connect_to_device(device),
|
|
||||||
- )
|
|
||||||
+ error_dialog(self, display_error)
|
|
||||||
|
|
||||||
def handle_authentication_exception():
|
|
||||||
loading_dialog.hide()
|
|
||||||
diff --git a/linien_gui/ui/main_window.py b/linien_gui/ui/main_window.py
|
|
||||||
index dad465e..8d6a0b4 100644
|
|
||||||
--- a/linien_gui/ui/main_window.py
|
|
||||||
+++ b/linien_gui/ui/main_window.py
|
|
||||||
@@ -202,7 +202,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
||||||
super().closeEvent(*args, **kwargs)
|
|
||||||
|
|
||||||
def show_new_version_available(self):
|
|
||||||
- self.newVersionAvailableLabel.show()
|
|
||||||
+ # Fast Servo does not support OTA Update
|
|
||||||
+ pass
|
|
||||||
|
|
||||||
def handle_key_press(self, key):
|
|
||||||
logger.debug(f"key pressed {key}")
|
|
@ -1,95 +0,0 @@
|
|||||||
# Fix for bus error issues when compiling cpython extensions in pyrp3 v1.2.0+
|
|
||||||
# Patch sourced from: https://github.com/linien-org/pyrp3/tree/e6688acf8bd79d2dbe1d192d09c1a1baf1f6c67b (setup.py & monitor/Makefile)
|
|
||||||
# Reference: https://github.com/elhep/Fast-Servo-Firmware/blob/master/OS/scripts/linien_install_requirements.sh#L28
|
|
||||||
|
|
||||||
diff --git a/monitor/Makefile b/monitor/Makefile
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..0c9bb53
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/monitor/Makefile
|
|
||||||
@@ -0,0 +1,31 @@
|
|
||||||
+# Makefile for libmonitor
|
|
||||||
+
|
|
||||||
+OBJS = monitor.o
|
|
||||||
+SRCS = $(subst .o,.c, $(OBJS)))
|
|
||||||
+OSOBJS = monitor.os
|
|
||||||
+TARGETLIB=libmonitor.so
|
|
||||||
+CFLAGS=-g -std=gnu99 -Wall -Werror
|
|
||||||
+LIBS=-lm -lpthread
|
|
||||||
+
|
|
||||||
+# Use CROSS_COMPILE=arm-linux-gnueabi-
|
|
||||||
+CC=$(CROSS_COMPILE)gcc
|
|
||||||
+INSTALL_DIR ?= .
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+all: $(TARGETLIB)
|
|
||||||
+lib: $(TARGETLIB)
|
|
||||||
+
|
|
||||||
+%.os: %.c
|
|
||||||
+ $(CC) -c -fPIC $(CFLAGS) $< -o $@
|
|
||||||
+
|
|
||||||
+$(TARGETLIB): $(OSOBJS)
|
|
||||||
+ $(CC) -o $@ -shared $^ $(CFLAGS) $(LIBS)
|
|
||||||
+
|
|
||||||
+clean:
|
|
||||||
+ rm -f $(TARGETLIB) *.o *.os
|
|
||||||
+
|
|
||||||
+# Install target - creates 'lib/' sub-directory in $(INSTALL_DIR) and copies all
|
|
||||||
+# executables to that location.
|
|
||||||
+install:
|
|
||||||
+ mkdir -p $(INSTALL_DIR)/lib
|
|
||||||
+ cp $(TARGETLIB) $(INSTALL_DIR)/lib
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/pyrp3/raw_memory.py b/pyrp3/raw_memory.py
|
|
||||||
index ce1b28e..233b82a 100644
|
|
||||||
--- a/pyrp3/raw_memory.py
|
|
||||||
+++ b/pyrp3/raw_memory.py
|
|
||||||
@@ -1,12 +1,9 @@
|
|
||||||
from ctypes import POINTER, c_uint32, cast, cdll, create_string_buffer, sizeof
|
|
||||||
-from importlib.machinery import EXTENSION_SUFFIXES
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
-libmonitor_file = str(
|
|
||||||
- Path(__file__).parent / ".." / "monitor{}".format(EXTENSION_SUFFIXES[0])
|
|
||||||
-)
|
|
||||||
+libmonitor_file = 'libmonitor.so'
|
|
||||||
|
|
||||||
libmonitor = cdll.LoadLibrary(libmonitor_file)
|
|
||||||
libmonitor.read_value.restype = c_uint32
|
|
||||||
diff --git a/setup.py b/setup.py
|
|
||||||
index 9302177..2258ddc 100644
|
|
||||||
--- a/setup.py
|
|
||||||
+++ b/setup.py
|
|
||||||
@@ -1,4 +1,28 @@
|
|
||||||
-from distutils.core import Extension, setup
|
|
||||||
+import os
|
|
||||||
+from distutils.core import setup
|
|
||||||
+from distutils.command.build import build
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+build_dir = "monitor/"
|
|
||||||
+
|
|
||||||
+def compile_libmonitor():
|
|
||||||
+ cwd = os.getcwd() # get current directory
|
|
||||||
+ try:
|
|
||||||
+ os.chdir(build_dir)
|
|
||||||
+ os.system("make clean")
|
|
||||||
+ os.system("make all")
|
|
||||||
+ finally:
|
|
||||||
+ os.chdir(cwd)
|
|
||||||
+
|
|
||||||
+class lib_build(build):
|
|
||||||
+ def run(self):
|
|
||||||
+ compile_libmonitor()
|
|
||||||
+ build.run(self)
|
|
||||||
+
|
|
||||||
+setup_args = dict(
|
|
||||||
+ cmdclass={
|
|
||||||
+ "build": lib_build
|
|
||||||
+ }
|
|
||||||
+)
|
|
||||||
|
|
||||||
-setup_args = dict(ext_modules=[Extension("monitor", ["monitor/monitor.c"])])
|
|
||||||
setup(**setup_args)
|
|
@ -1,22 +0,0 @@
|
|||||||
diff --git a/linien-server/linien_server/parameters.py b/linien-server/linien_server/parameters.py
|
|
||||||
index 12f16ed..287f304 100644
|
|
||||||
--- a/linien-server/linien_server/parameters.py
|
|
||||||
+++ b/linien-server/linien_server/parameters.py
|
|
||||||
@@ -311,7 +311,7 @@ class Parameters:
|
|
||||||
# ------------------- MODULATION PARAMETERS ------------------------------------
|
|
||||||
|
|
||||||
self.modulation_amplitude = Parameter(
|
|
||||||
- min_=0, max_=(1 << 14) - 1, start=1 * Vpp, restorable=True, loggable=True
|
|
||||||
+ min_=0, max_=(1 << 14) - 1, start=0.1 * Vpp, restorable=True, loggable=True
|
|
||||||
)
|
|
||||||
"""
|
|
||||||
The amplitude of the modulation in internal units. Use Vpp for conversion to
|
|
||||||
@@ -320,7 +320,7 @@ class Parameters:
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.modulation_frequency = Parameter(
|
|
||||||
- min_=0, max_=0xFFFFFFFF, start=15 * MHz, restorable=True, loggable=True
|
|
||||||
+ min_=0, max_=0xFFFFFFFF, start=1 * MHz, restorable=True, loggable=True
|
|
||||||
)
|
|
||||||
"""
|
|
||||||
Frequency of the modulation in internal units. Use MHz for conversion to
|
|
@ -1,26 +0,0 @@
|
|||||||
diff --git a/linien-server/linien_server/cli.py b/linien-server/linien_server/cli.py
|
|
||||||
index 98539b2..7781c74 100644
|
|
||||||
--- a/linien-server/linien_server/cli.py
|
|
||||||
+++ b/linien-server/linien_server/cli.py
|
|
||||||
@@ -83,18 +83,9 @@ class LinienServerCLI:
|
|
||||||
else:
|
|
||||||
control = RedPitayaControlService(host=host)
|
|
||||||
|
|
||||||
- if fake or host:
|
|
||||||
- authenticator = no_authenticator
|
|
||||||
- else:
|
|
||||||
- authenticator = username_and_password_authenticator
|
|
||||||
-
|
|
||||||
- try:
|
|
||||||
- if not (fake or host): # only available on RP
|
|
||||||
- mdio_tool.disable_ethernet_blinking()
|
|
||||||
- run_threaded_server(control, authenticator=authenticator)
|
|
||||||
- finally:
|
|
||||||
- if not (fake or host): # only available on RP
|
|
||||||
- mdio_tool.enable_ethernet_blinking()
|
|
||||||
+ authenticator = no_authenticator
|
|
||||||
+
|
|
||||||
+ run_threaded_server(control, authenticator=authenticator)
|
|
||||||
|
|
||||||
def enable(self) -> None:
|
|
||||||
"""Enable the Linien server to start on boot."""
|
|
@ -1,57 +0,0 @@
|
|||||||
diff --git a/gateware/linien_module.py b/gateware/linien_module.py
|
|
||||||
index a958896..a64714c 100644
|
|
||||||
--- a/gateware/linien_module.py
|
|
||||||
+++ b/gateware/linien_module.py
|
|
||||||
@@ -233,23 +233,46 @@ class LinienModule(Module, AutoCSR):
|
|
||||||
self.fast_a.adc.eq(soc.analog.adc_a),
|
|
||||||
self.fast_b.adc.eq(soc.analog.adc_b),
|
|
||||||
]
|
|
||||||
-
|
|
||||||
+
|
|
||||||
# now, we combine the output of the two paths, with a variable factor each.
|
|
||||||
mixed = Signal(
|
|
||||||
(2 + ((signal_width + 1) + self.logic.chain_a_factor.size), True)
|
|
||||||
)
|
|
||||||
+
|
|
||||||
+ chain_a_factor_mult_fast_a_out_i = Signal(
|
|
||||||
+ (2 + ((signal_width + 1) + self.logic.chain_a_factor.size), True)
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ chain_b_factor_mult_fast_b_out_i = Signal(
|
|
||||||
+ (2 + ((signal_width + 1) + self.logic.chain_a_factor.size), True)
|
|
||||||
+ )
|
|
||||||
+ combined_offset_signed_left_shifted = Signal(
|
|
||||||
+ (2 + ((signal_width + 1) + self.logic.chain_a_factor.size), True)
|
|
||||||
+ )
|
|
||||||
+ fast_a_out_i_left_shifted = Signal(
|
|
||||||
+ (2 + ((signal_width + 1) + self.logic.chain_a_factor.size), True)
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ self.sync += [
|
|
||||||
+ chain_a_factor_mult_fast_a_out_i.eq(self.logic.chain_a_factor.storage * self.fast_a.out_i),
|
|
||||||
+ chain_b_factor_mult_fast_b_out_i.eq(self.logic.chain_b_factor.storage * self.fast_b.out_i),
|
|
||||||
+ combined_offset_signed_left_shifted.eq(self.logic.combined_offset_signed << (chain_factor_bits + s)),
|
|
||||||
+ fast_a_out_i_left_shifted.eq(self.fast_a.out_i << chain_factor_bits),
|
|
||||||
+ ]
|
|
||||||
+
|
|
||||||
+
|
|
||||||
self.comb += [
|
|
||||||
If(
|
|
||||||
self.logic.dual_channel.storage,
|
|
||||||
mixed.eq(
|
|
||||||
- (self.logic.chain_a_factor.storage * self.fast_a.out_i)
|
|
||||||
- + (self.logic.chain_b_factor.storage * self.fast_b.out_i)
|
|
||||||
- + (self.logic.combined_offset_signed << (chain_factor_bits + s))
|
|
||||||
+ chain_a_factor_mult_fast_a_out_i
|
|
||||||
+ + chain_b_factor_mult_fast_b_out_i
|
|
||||||
+ + combined_offset_signed_left_shifted
|
|
||||||
),
|
|
||||||
).Else(
|
|
||||||
mixed.eq(
|
|
||||||
- (self.fast_a.out_i << chain_factor_bits)
|
|
||||||
- + (self.logic.combined_offset_signed << (chain_factor_bits + s))
|
|
||||||
+ fast_a_out_i_left_shifted
|
|
||||||
+ + combined_offset_signed_left_shifted
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]
|
|
@ -1,19 +0,0 @@
|
|||||||
diff --git a/gateware/logic/pid.py b/gateware/logic/pid.py
|
|
||||||
index e737577..f1a4096 100644
|
|
||||||
--- a/gateware/logic/pid.py
|
|
||||||
+++ b/gateware/logic/pid.py
|
|
||||||
@@ -43,10 +43,12 @@ class PID(Module, AutoCSR):
|
|
||||||
self.comb += [setpoint_signed.eq(self.setpoint.storage)]
|
|
||||||
|
|
||||||
self.error = Signal((self.width + 1, True))
|
|
||||||
+ error_reg = Signal((self.width + 1, True))
|
|
||||||
+ self.sync += self.error.eq(error_reg)
|
|
||||||
|
|
||||||
self.comb += [
|
|
||||||
- If(self.running, self.error.eq(self.input - self.setpoint.storage)).Else(
|
|
||||||
- self.error.eq(0)
|
|
||||||
+ If(self.running, error_reg.eq(self.input - self.setpoint.storage)).Else(
|
|
||||||
+ error_reg.eq(0)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
|||||||
diff --git a/gateware/logic/pid.py b/gateware/logic/pid.py
|
|
||||||
index 4320f94..e737577 100644
|
|
||||||
--- a/gateware/logic/pid.py
|
|
||||||
+++ b/gateware/logic/pid.py
|
|
||||||
@@ -56,10 +56,13 @@ class PID(Module, AutoCSR):
|
|
||||||
self.comb += [kp_signed.eq(self.kp.storage)]
|
|
||||||
|
|
||||||
kp_mult = Signal((self.width + self.coeff_width, True))
|
|
||||||
- self.comb += [kp_mult.eq(self.error * kp_signed)]
|
|
||||||
+ kp_mult_reg = Signal((self.width + self.coeff_width, True))
|
|
||||||
+ self.sync += kp_mult.eq(kp_mult_reg >> (self.coeff_width - 2))
|
|
||||||
+
|
|
||||||
+ self.comb += [kp_mult_reg.eq(self.error * kp_signed)]
|
|
||||||
|
|
||||||
self.output_p = Signal((self.width, True))
|
|
||||||
- self.comb += [self.output_p.eq(kp_mult >> (self.coeff_width - 2))]
|
|
||||||
+ self.comb += [self.output_p.eq(kp_mult)]
|
|
||||||
|
|
||||||
self.kp_mult = kp_mult
|
|
||||||
|
|
||||||
@@ -71,8 +74,10 @@ class PID(Module, AutoCSR):
|
|
||||||
self.comb += [ki_signed.eq(self.ki.storage)]
|
|
||||||
|
|
||||||
self.ki_mult = Signal((1 + self.width + self.coeff_width, True))
|
|
||||||
+ self.ki_mult_reg = Signal((1 + self.width + self.coeff_width, True))
|
|
||||||
+ self.sync += self.ki_mult.eq(self.ki_mult_reg)
|
|
||||||
+ self.comb += self.ki_mult_reg.eq((self.error * ki_signed) >> 4)
|
|
||||||
|
|
||||||
- self.comb += [self.ki_mult.eq((self.error * ki_signed) >> 4)]
|
|
||||||
|
|
||||||
int_reg_width = self.width + self.coeff_width + 4
|
|
||||||
extra_width = int_reg_width - self.width
|
|
||||||
@@ -110,15 +115,17 @@ class PID(Module, AutoCSR):
|
|
||||||
self.kd = CSRStorage(self.coeff_width)
|
|
||||||
kd_signed = Signal((self.coeff_width, True))
|
|
||||||
kd_mult = Signal((mult_width, True))
|
|
||||||
+ kd_mult_reg = Signal((mult_width, True))
|
|
||||||
+ self.sync += kd_mult.eq(kd_mult_reg)
|
|
||||||
|
|
||||||
- self.comb += [kd_signed.eq(self.kd.storage), kd_mult.eq(self.error * kd_signed)]
|
|
||||||
+ self.comb += [kd_signed.eq(self.kd.storage), kd_mult_reg.eq(self.error * kd_signed >> (self.coeff_width - self.d_shift))]
|
|
||||||
|
|
||||||
kd_reg = Signal((out_width, True))
|
|
||||||
kd_reg_r = Signal((out_width, True))
|
|
||||||
|
|
||||||
self.output_d = Signal((out_width, True))
|
|
||||||
self.sync += [
|
|
||||||
- kd_reg.eq(kd_mult >> (self.coeff_width - self.d_shift)),
|
|
||||||
+ kd_reg.eq(kd_mult),
|
|
||||||
kd_reg_r.eq(kd_reg),
|
|
||||||
self.output_d.eq(kd_reg - kd_reg_r),
|
|
||||||
]
|
|
||||||
@@ -143,4 +150,10 @@ class PID(Module, AutoCSR):
|
|
||||||
|
|
||||||
# sync is required here, otherwise we get artifacts when one of the
|
|
||||||
# signals changes sign
|
|
||||||
- self.sync += [self.pid_sum.eq(self.output_p + self.int_out + self.output_d)]
|
|
||||||
+ self.sync += [
|
|
||||||
+ If(
|
|
||||||
+ self.running,
|
|
||||||
+ self.pid_sum.eq(self.output_p + self.int_out + self.output_d),
|
|
||||||
+ )
|
|
||||||
+ .Else(self.pid_sum.eq(0))
|
|
||||||
+ ]
|
|
@ -1,5 +0,0 @@
|
|||||||
## Source Repository
|
|
||||||
Files in this directory were copied from [elhep/Fast-Servo-Firmware](https://github.com/elhep/Fast-Servo-Firmware/tree/master/fast_servo/pythonscripts).
|
|
||||||
|
|
||||||
## Commit ID
|
|
||||||
The files were copied from commit ID [7fae40c](https://github.com/elhep/Fast-Servo-Firmware/commit/7fae40c0f872a91218be378f8289b98b1e366729).
|
|
@ -1,224 +0,0 @@
|
|||||||
# This file is part of Fast Servo Software Package.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2023 Jakub Matyas
|
|
||||||
# Warsaw University of Technology <jakubk.m@gmail.com>
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#
|
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import time
|
|
||||||
import spidev
|
|
||||||
from pyfastservo.common import (
|
|
||||||
ADC_AFE_CTRL_ADDR,
|
|
||||||
ADC_BITSLIP_ADDR,
|
|
||||||
ADC_CH0_HIGH_ADDR,
|
|
||||||
ADC_CH0_LOW_ADDR,
|
|
||||||
ADC_CH1_HIGH_ADDR,
|
|
||||||
ADC_CH1_LOW_ADDR,
|
|
||||||
ADC_DELAY_ADDR,
|
|
||||||
ADC_FRAME_ADDR,
|
|
||||||
AUX_ADC_ADDR,
|
|
||||||
MAP_MASK,
|
|
||||||
PAGESIZE,
|
|
||||||
write_to_memory,
|
|
||||||
read_from_memory
|
|
||||||
)
|
|
||||||
|
|
||||||
# /dev/spidev1.0 <=> spidev<BUS>.<DEVICE>
|
|
||||||
MAIN_ADC_BUS = 1
|
|
||||||
MAIN_ADC_DEVICE = 1
|
|
||||||
|
|
||||||
AUX_ADC_BUS = 1
|
|
||||||
AUX_ADC_PORT_A = 2
|
|
||||||
AUX_ADC_PORT_B = 3
|
|
||||||
|
|
||||||
|
|
||||||
def spi_write(spi, address, value):
|
|
||||||
spi.xfer2([address, value])
|
|
||||||
|
|
||||||
def spi_read(spi, address):
|
|
||||||
rx_buffer = spi.xfer2([0x80 | address, 0x00])
|
|
||||||
return rx_buffer[1]
|
|
||||||
|
|
||||||
def main_adc_config(spi, test_pattern):
|
|
||||||
high_word = (test_pattern & 0xFF00) >> 8
|
|
||||||
low_word = test_pattern & 0xFF
|
|
||||||
|
|
||||||
spi_write(spi, 0x00, 0x80) # reset
|
|
||||||
spi_write(spi, 0x01, 0x20) # REGISTER A1: set to Two's complement Data Format
|
|
||||||
spi_write(spi, 0x02, 0x15) # REGISTER A2: set to LVDS output, set 4 data lanes and turn on test mode
|
|
||||||
spi_write(spi, 0x03, high_word) # REGISTER A3: test pattern high word
|
|
||||||
spi_write(spi, 0x04, low_word) # REGISTER A4: test pattern low word
|
|
||||||
|
|
||||||
def main_adc_test_mode(spi, enable):
|
|
||||||
reg_contents = 0x15 if enable else 0x11 # set to LVDS output, set 4 data lanes and turn on or off test mode
|
|
||||||
spi_write(spi, 0x02, reg_contents)
|
|
||||||
|
|
||||||
def verify_adc_registers(spi, reg_to_check):
|
|
||||||
for register, expected_value in reg_to_check.items():
|
|
||||||
value = spi_read(spi, register)
|
|
||||||
print(f"Spi readback register 0x{register:02x}: 0x{value:02x}")
|
|
||||||
if value != expected_value:
|
|
||||||
print(f"Different value read than sent in reg 0x{register:02x}")
|
|
||||||
|
|
||||||
def read_frame():
|
|
||||||
return read_from_memory(ADC_FRAME_ADDR, 1)[0]
|
|
||||||
|
|
||||||
def perform_bitslip():
|
|
||||||
for i in range(4):
|
|
||||||
current_frame = read_frame()
|
|
||||||
if current_frame & 0x0F != 0x0C:
|
|
||||||
print(f"Performing bitslip (iteration: {i}). Current frame: 0x{current_frame:02x}")
|
|
||||||
write_to_memory(ADC_BITSLIP_ADDR, 1)
|
|
||||||
else:
|
|
||||||
print(f"No bitslip required; Current frame: 0x{current_frame:02x}")
|
|
||||||
return
|
|
||||||
|
|
||||||
def mmcm_rst():
|
|
||||||
curr_cfg = read_from_memory(ADC_AFE_CTRL_ADDR, 1)[0] & 0x0F
|
|
||||||
write_to_memory(ADC_AFE_CTRL_ADDR, 0x10 | curr_cfg) # Reset MMCM
|
|
||||||
write_to_memory(ADC_AFE_CTRL_ADDR, 0x00 | curr_cfg) # Release MMCM Reset
|
|
||||||
while not(read_frame() & 0x10):
|
|
||||||
print(f"Waiting for MMCM to lock")
|
|
||||||
time.sleep(0.001)
|
|
||||||
|
|
||||||
def inc_ddr_clk_phase():
|
|
||||||
curr_cfg = read_from_memory(ADC_AFE_CTRL_ADDR, 1)[0] & 0x1F
|
|
||||||
write_to_memory(ADC_AFE_CTRL_ADDR, 0x40 | curr_cfg) # Set MMCM Phase Shift to be INC
|
|
||||||
write_to_memory(ADC_AFE_CTRL_ADDR, 0x60 | curr_cfg) # Assert MMCM Phase Shift EN High
|
|
||||||
write_to_memory(ADC_AFE_CTRL_ADDR, curr_cfg) # Deassert MMCM Phase Shift EN High
|
|
||||||
|
|
||||||
def dec_ddr_clk_phase():
|
|
||||||
curr_cfg = read_from_memory(ADC_AFE_CTRL_ADDR, 1)[0] & 0x1F
|
|
||||||
write_to_memory(ADC_AFE_CTRL_ADDR, 0x00 | curr_cfg) # Set MMCM Phase Shift to be DEC
|
|
||||||
write_to_memory(ADC_AFE_CTRL_ADDR, 0x20 | curr_cfg) # Assert MMCM Phase Shift EN High
|
|
||||||
write_to_memory(ADC_AFE_CTRL_ADDR, curr_cfg) # Deassert MMCM Phase Shift EN High
|
|
||||||
|
|
||||||
def find_edge():
|
|
||||||
prev_frame = read_frame()
|
|
||||||
for tap_delay in range(32):
|
|
||||||
write_to_memory(ADC_DELAY_ADDR, tap_delay)
|
|
||||||
current_frame = read_frame()
|
|
||||||
|
|
||||||
print(f"Tap delay: {tap_delay}, Current frame: 0x{current_frame:02x}")
|
|
||||||
print(f"prev_frame: 0x{prev_frame:02x}")
|
|
||||||
|
|
||||||
if current_frame != prev_frame:
|
|
||||||
final_delay = ((tap_delay+1) // 2) + 2
|
|
||||||
print(f"Edge detected; setting iDelay to: {final_delay}")
|
|
||||||
write_to_memory(ADC_DELAY_ADDR, final_delay)
|
|
||||||
return
|
|
||||||
|
|
||||||
prev_frame = current_frame
|
|
||||||
|
|
||||||
# If no edge detected
|
|
||||||
final_delay = 11
|
|
||||||
print(f"No edge detected; setting iDelay to: {final_delay}")
|
|
||||||
write_to_memory(ADC_DELAY_ADDR, final_delay)
|
|
||||||
|
|
||||||
def read_adc_channel(high_addr, low_addr):
|
|
||||||
return (read_from_memory(high_addr, 1)[0] << 8) | read_from_memory(low_addr, 1)[0]
|
|
||||||
|
|
||||||
def print_adc_channels():
|
|
||||||
adc_ch0 = read_adc_channel(ADC_CH0_HIGH_ADDR, ADC_CH0_LOW_ADDR)
|
|
||||||
adc_ch1 = read_adc_channel(ADC_CH1_HIGH_ADDR, ADC_CH1_LOW_ADDR)
|
|
||||||
print(f"Final ADC_CH0: 0x{adc_ch0:04x}")
|
|
||||||
print(f"Final ADC_CH1: 0x{adc_ch1:04x}")
|
|
||||||
|
|
||||||
def enable_adc_afe(ch1_x10=False, ch2_x10=False):
|
|
||||||
ctrl_value = (ch2_x10 << 1) | ch1_x10
|
|
||||||
write_to_memory(ADC_AFE_CTRL_ADDR, ctrl_value)
|
|
||||||
afe_ctrl = read_from_memory(ADC_AFE_CTRL_ADDR, 1)[0]
|
|
||||||
print(f"ADC_AFE_CTRL: 0x{afe_ctrl:02X}")
|
|
||||||
return afe_ctrl
|
|
||||||
|
|
||||||
def search_edge():
|
|
||||||
for tap_delay in range(32):
|
|
||||||
print(f"iDelay to: {tap_delay}")
|
|
||||||
write_to_memory(ADC_DELAY_ADDR, tap_delay)
|
|
||||||
time.sleep(1)
|
|
||||||
current_frame = read_frame()
|
|
||||||
print(f"Tap delay: {tap_delay}, Current frame: 0x{current_frame:02x}")
|
|
||||||
print_adc_channels()
|
|
||||||
|
|
||||||
def print_adc_channel(ch):
|
|
||||||
if ch == 0:
|
|
||||||
adc_ch0 = read_adc_channel(ADC_CH0_HIGH_ADDR, ADC_CH0_LOW_ADDR)
|
|
||||||
print(f"Final ADC_CH0: 0x{adc_ch0:04x}")
|
|
||||||
if ch == 1:
|
|
||||||
adc_ch1 = read_adc_channel(ADC_CH1_HIGH_ADDR, ADC_CH1_LOW_ADDR)
|
|
||||||
print(f"Final ADC_CH1: 0x{adc_ch1:04x}")
|
|
||||||
|
|
||||||
def find_min_max_ch(ch):
|
|
||||||
test = []
|
|
||||||
for i in range(100):
|
|
||||||
if ch == 0:
|
|
||||||
test.append(read_adc_channel(ADC_CH0_HIGH_ADDR, ADC_CH0_LOW_ADDR))
|
|
||||||
else:
|
|
||||||
test.append(read_adc_channel(ADC_CH1_HIGH_ADDR, ADC_CH1_LOW_ADDR))
|
|
||||||
print("ch", ch, hex(test[-1]))
|
|
||||||
print("Min:", hex(min(test)))
|
|
||||||
print("Max:", hex(max(test)))
|
|
||||||
print("Diff:", hex(max(test)-min(test)))
|
|
||||||
|
|
||||||
|
|
||||||
def configure_ltc2195():
|
|
||||||
spi = spidev.SpiDev()
|
|
||||||
try:
|
|
||||||
spi.open(MAIN_ADC_BUS, MAIN_ADC_DEVICE)
|
|
||||||
spi.max_speed_hz = 50000
|
|
||||||
spi.mode = 0b00 # CPOL = 0 CPHA = 0
|
|
||||||
spi.cshigh = False
|
|
||||||
|
|
||||||
test_pattern = 0x811F
|
|
||||||
main_adc_config(spi, test_pattern)
|
|
||||||
|
|
||||||
verify_adc_registers(spi, {
|
|
||||||
0x01: 0x20,
|
|
||||||
0x02: 0x15,
|
|
||||||
0x03: (test_pattern & 0xFF00) >> 8,
|
|
||||||
0x04: test_pattern & 0xFF
|
|
||||||
})
|
|
||||||
|
|
||||||
# ADC software reset put its PLL to sleep momentarily. Thus, MMCM needs to be reset as well.
|
|
||||||
mmcm_rst()
|
|
||||||
|
|
||||||
# Performing Word Align
|
|
||||||
perform_bitslip()
|
|
||||||
find_edge()
|
|
||||||
|
|
||||||
# Printing it once is not enough to check whether the alignment is correct.
|
|
||||||
for i in range(100):
|
|
||||||
print_adc_channels()
|
|
||||||
|
|
||||||
main_adc_test_mode(spi, False)
|
|
||||||
verify_adc_registers(spi, {0x02: 0x11}) # Verify test mode is off
|
|
||||||
|
|
||||||
# FIXME: AFE Gain 1x is not functional on that batch of fast servo under development
|
|
||||||
enable_adc_afe(ch1_x10=1, ch2_x10=1)
|
|
||||||
|
|
||||||
#find_min_max_ch(0)
|
|
||||||
#find_min_max_ch(1)
|
|
||||||
|
|
||||||
#for i in range(10):
|
|
||||||
# print_adc_channel(0)
|
|
||||||
|
|
||||||
#for i in range(10):
|
|
||||||
# print_adc_channel(1)
|
|
||||||
|
|
||||||
finally:
|
|
||||||
spi.close()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
configure_ltc2195()
|
|
@ -1,120 +0,0 @@
|
|||||||
# This file is part of Fast Servo Software Package.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2023 Jakub Matyas
|
|
||||||
# Warsaw University of Technology <jakubk.m@gmail.com>
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#
|
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import os
|
|
||||||
import mmap
|
|
||||||
|
|
||||||
CSR_SIZE = 0x800
|
|
||||||
MAP_SIZE = 0x1000
|
|
||||||
MAP_MASK = 0xFFF
|
|
||||||
PAGESIZE = 0x1000
|
|
||||||
|
|
||||||
# LINIEN_OFFSET = 0x0
|
|
||||||
LINIEN_OFFSET = 0x300000
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
|
||||||
# FRONT PANEL LEDS REGISTER ADDRESSES
|
|
||||||
LED0_BASE_ADDR = 0x40005000 + LINIEN_OFFSET
|
|
||||||
LED1_BASE_ADDR = 0x40005800 + LINIEN_OFFSET
|
|
||||||
LED2_BASE_ADDR = 0x40006000 + LINIEN_OFFSET
|
|
||||||
LED3_BASE_ADDR = 0x40006800 + LINIEN_OFFSET
|
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
|
||||||
# DAC REGISTER ADDRESSES
|
|
||||||
ADC_BASE_ADDR = 0x40004800 + LINIEN_OFFSET
|
|
||||||
ADC_FRAME_OFFSET = 0x0
|
|
||||||
ADC_CH0_HIGH_OFFSET = 0x4
|
|
||||||
ADC_CH0_LOW_OFFSET = 0x8
|
|
||||||
ADC_CH1_HIGH_OFFSET = 0xC
|
|
||||||
ADC_CH1_LOW_OFFSET = 0x10
|
|
||||||
ADC_TAP_DELAY_OFFSET = 0x14
|
|
||||||
ADC_BITSLIP_OFFSET = 0x18
|
|
||||||
ADC_AFE_CTRL_OFFSET = 0x1C
|
|
||||||
|
|
||||||
|
|
||||||
ADC_FRAME_ADDR = ADC_BASE_ADDR + ADC_FRAME_OFFSET
|
|
||||||
ADC_CH0_HIGH_ADDR = ADC_BASE_ADDR + ADC_CH0_HIGH_OFFSET
|
|
||||||
ADC_CH0_LOW_ADDR = ADC_BASE_ADDR + ADC_CH0_LOW_OFFSET
|
|
||||||
ADC_CH1_HIGH_ADDR = ADC_BASE_ADDR + ADC_CH1_HIGH_OFFSET
|
|
||||||
ADC_CH1_LOW_ADDR = ADC_BASE_ADDR + ADC_CH1_LOW_OFFSET
|
|
||||||
ADC_DELAY_ADDR = ADC_BASE_ADDR + ADC_TAP_DELAY_OFFSET
|
|
||||||
ADC_BITSLIP_ADDR = ADC_BASE_ADDR + ADC_BITSLIP_OFFSET
|
|
||||||
ADC_AFE_CTRL_ADDR = ADC_BASE_ADDR + ADC_AFE_CTRL_OFFSET
|
|
||||||
|
|
||||||
AUX_ADC_ADDR = 0x40007800 + LINIEN_OFFSET
|
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
|
||||||
# DAC REGISTER ADDRESSES
|
|
||||||
DAC_BASE_ADDR = 0x40007000 + LINIEN_OFFSET
|
|
||||||
CTRL_OFFSET = 0x0
|
|
||||||
CH0_HIGH_WORD_OFFSET = 0x4
|
|
||||||
CH0_LOW_WORD_OFFSET = 0x8
|
|
||||||
CH1_HIGH_WORD_OFFSET = 0xC
|
|
||||||
CH1_LOW_WORD_OFFSET = 0x10
|
|
||||||
|
|
||||||
CTRL_ADDR = DAC_BASE_ADDR + CTRL_OFFSET
|
|
||||||
CH0_HIGH_WORD_ADDR = DAC_BASE_ADDR + CH0_HIGH_WORD_OFFSET
|
|
||||||
CH0_LOW_WORD_ADDR = DAC_BASE_ADDR + CH0_LOW_WORD_OFFSET
|
|
||||||
CH1_HIGH_WORD_ADDR = DAC_BASE_ADDR + CH1_HIGH_WORD_OFFSET
|
|
||||||
CH1_LOW_WORD_ADDR = DAC_BASE_ADDR + CH1_LOW_WORD_OFFSET
|
|
||||||
|
|
||||||
|
|
||||||
def read_from_memory(address, n_bytes):
|
|
||||||
assert n_bytes <= 4
|
|
||||||
addr = address
|
|
||||||
|
|
||||||
try:
|
|
||||||
f = os.open("/dev/mem", os.O_SYNC | os.O_RDWR)
|
|
||||||
with mmap.mmap(
|
|
||||||
f,
|
|
||||||
PAGESIZE,
|
|
||||||
mmap.MAP_SHARED,
|
|
||||||
mmap.PROT_READ | mmap.PROT_WRITE,
|
|
||||||
offset=addr & ~MAP_MASK,
|
|
||||||
) as mem:
|
|
||||||
start_addr = addr & MAP_MASK
|
|
||||||
stop_addr = start_addr + 4
|
|
||||||
contents = mem[start_addr:stop_addr]
|
|
||||||
read_value = list(contents)[:n_bytes]
|
|
||||||
finally:
|
|
||||||
os.close(f)
|
|
||||||
|
|
||||||
return read_value
|
|
||||||
|
|
||||||
def write_to_memory(address, value):
|
|
||||||
value_bytes = value.to_bytes(4, "little")
|
|
||||||
addr = address
|
|
||||||
|
|
||||||
try:
|
|
||||||
f = os.open("/dev/mem", os.O_SYNC | os.O_RDWR)
|
|
||||||
with mmap.mmap(
|
|
||||||
f,
|
|
||||||
PAGESIZE,
|
|
||||||
mmap.MAP_SHARED,
|
|
||||||
mmap.PROT_READ | mmap.PROT_WRITE,
|
|
||||||
offset=addr & ~MAP_MASK,
|
|
||||||
) as mem:
|
|
||||||
start_addr = addr & MAP_MASK
|
|
||||||
stop_addr = start_addr + 4
|
|
||||||
mem[start_addr:stop_addr] = value_bytes
|
|
||||||
contents = mem[start_addr:stop_addr]
|
|
||||||
finally:
|
|
||||||
os.close(f)
|
|
@ -1,168 +0,0 @@
|
|||||||
# This file is part of Fast Servo Software Package.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2023 Jakub Matyas
|
|
||||||
# Warsaw University of Technology <jakubk.m@gmail.com>
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#
|
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import time
|
|
||||||
|
|
||||||
import spidev
|
|
||||||
from pyfastservo.common import (
|
|
||||||
CH0_HIGH_WORD_ADDR,
|
|
||||||
CH0_LOW_WORD_ADDR,
|
|
||||||
CH1_HIGH_WORD_ADDR,
|
|
||||||
CH1_LOW_WORD_ADDR,
|
|
||||||
CTRL_ADDR,
|
|
||||||
MAP_MASK,
|
|
||||||
PAGESIZE,
|
|
||||||
write_to_memory,
|
|
||||||
read_from_memory
|
|
||||||
)
|
|
||||||
|
|
||||||
# /dev/spidev2.0 <=> spidev<BUS>.<DEVICE>
|
|
||||||
MAIN_DAC_BUS = 2
|
|
||||||
MAIN_DAC_DEVICE = 0
|
|
||||||
DAC_VERSION = 0x0A
|
|
||||||
|
|
||||||
|
|
||||||
def spi_write(spi, address, value):
|
|
||||||
spi.xfer2([address, value])
|
|
||||||
|
|
||||||
def spi_read(spi, address):
|
|
||||||
rx_buffer = spi.xfer2([0x80 | address, 0x00])
|
|
||||||
return rx_buffer[1]
|
|
||||||
|
|
||||||
def soft_reset(spi):
|
|
||||||
spi_write(spi, 0x00, 0x10) # Software reset
|
|
||||||
spi_write(spi, 0x00, 0x00) # Release software reset
|
|
||||||
spi_read(spi, 0x00) # Read reset address (necessary for reset to take effect)
|
|
||||||
|
|
||||||
def check_version(spi):
|
|
||||||
version = spi_read(spi, 0x1F)
|
|
||||||
print(f"DAC version: 0x{version:02X}")
|
|
||||||
return version == DAC_VERSION
|
|
||||||
|
|
||||||
def configure_dac(spi):
|
|
||||||
power_down_reg = spi_read(spi, 0x01)
|
|
||||||
spi_write(spi, 0x01, power_down_reg & ~(1 << 0)) # Clear EXTREF bit for internal reference
|
|
||||||
spi_write(spi, 0x0D, 0x00) # Set RREF to 10 kΩ for 1.0V reference
|
|
||||||
spi_write(spi, 0x04, 0xA0) # Enable on-chip IRSET (1.6 kΩ for 20mA output)
|
|
||||||
spi_write(spi, 0x07, 0xA0) # Enable on-chip QRSET (1.6 kΩ for 20mA output)
|
|
||||||
spi_write(spi, 0x05, 0x00) # Disable internal IRCML
|
|
||||||
spi_write(spi, 0x08, 0x00) # Disable internal QRCML
|
|
||||||
spi_write(spi, 0x02, 0xB4) # Enable 2's complement, IFirst: True, IRising: True, DCI_EN: Enabled
|
|
||||||
spi_write(spi, 0x14, 0x00)
|
|
||||||
spi_write(spi, 0x14, 0x08) # Trigger the retimer to reacquire the clock relationship
|
|
||||||
spi_write(spi, 0x14, 0x00)
|
|
||||||
|
|
||||||
def dac_self_calibration(spi):
|
|
||||||
spi_write(spi, 0x12, 0x00) # Reset calibration status
|
|
||||||
spi_write(spi, 0x0E, 0x08) # Enable calibration clock, default divide ratio
|
|
||||||
spi_write(spi, 0x0E, 0x38) # CALSELI = 1, CALSELQ = 1, CALCLK = 1
|
|
||||||
spi_write(spi, 0x12, 0x10) # Set CALEN bit
|
|
||||||
|
|
||||||
while True:
|
|
||||||
status = spi_read(spi, 0x0F)
|
|
||||||
if status & 0xC0 == 0xC0: # Both CALSTATI and CALSTATQ are 1
|
|
||||||
break
|
|
||||||
time.sleep(0.01)
|
|
||||||
|
|
||||||
spi_write(spi, 0x12, 0x00) # Clear calibration bits
|
|
||||||
spi_write(spi, 0x0E, 0x30) # Keep CALSELI and CALSELQ set, clear CALCLK
|
|
||||||
print("DAC self-calibration completed")
|
|
||||||
|
|
||||||
def manual_override(enable=True):
|
|
||||||
reg_contents = read_from_memory(CTRL_ADDR, 1)[0]
|
|
||||||
to_write = reg_contents | 0b1 if enable else reg_contents & 0b110
|
|
||||||
write_to_memory(CTRL_ADDR, to_write)
|
|
||||||
print(f"Set DAC Output Manual Override: {enable}")
|
|
||||||
|
|
||||||
def power_down_afe(channel, power_down=True):
|
|
||||||
assert channel in (0, 1)
|
|
||||||
|
|
||||||
bitmask = 1 << (channel + 1) & 0b111
|
|
||||||
reg_contents = read_from_memory(CTRL_ADDR, 1)[0]
|
|
||||||
value = (1 if power_down else 0) << (channel + 1)
|
|
||||||
reg_contents &= ~bitmask
|
|
||||||
|
|
||||||
to_write = reg_contents | value
|
|
||||||
write_to_memory(CTRL_ADDR, to_write)
|
|
||||||
reg_contents = read_from_memory(CTRL_ADDR, 1)[0]
|
|
||||||
print(f"Power Down DAC AFE Ch{channel}: {power_down}")
|
|
||||||
|
|
||||||
def set_dac_output(value):
|
|
||||||
value = min(value, 0x3FFF)
|
|
||||||
low_word = value & 0xFF
|
|
||||||
high_word = (value >> 8) & 0x3F
|
|
||||||
|
|
||||||
# Note: DAC HIGH word and LOW word output are not updated
|
|
||||||
# at the same time. On scope, you will see more than one step
|
|
||||||
# of value changed.
|
|
||||||
write_to_memory(CH0_HIGH_WORD_ADDR, high_word)
|
|
||||||
write_to_memory(CH0_LOW_WORD_ADDR, low_word)
|
|
||||||
write_to_memory(CH1_HIGH_WORD_ADDR, high_word)
|
|
||||||
write_to_memory(CH1_LOW_WORD_ADDR, low_word)
|
|
||||||
print(f"DAC output set to: 0x{value:04X}")
|
|
||||||
|
|
||||||
def check_clk_relationship(spi):
|
|
||||||
clkmode_reg = spi_read(spi, 0x14)
|
|
||||||
print(f"CLKMODE reg: 0x{clkmode_reg:02X}")
|
|
||||||
if clkmode_reg & 0b00010000:
|
|
||||||
print("Clock relationship is not found")
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
print("Clock relationship is found")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def configure_ad9117():
|
|
||||||
spi = spidev.SpiDev()
|
|
||||||
spi.open(MAIN_DAC_BUS, MAIN_DAC_DEVICE)
|
|
||||||
spi.max_speed_hz = 5000
|
|
||||||
spi.mode = 0b00 # CPOL = 0 CPHA = 0
|
|
||||||
spi.cshigh = False
|
|
||||||
|
|
||||||
try:
|
|
||||||
soft_reset(spi)
|
|
||||||
if not check_version(spi):
|
|
||||||
print("Unrecognized DAC version")
|
|
||||||
return False
|
|
||||||
|
|
||||||
power_down_afe(0, True)
|
|
||||||
power_down_afe(1, True)
|
|
||||||
|
|
||||||
configure_dac(spi)
|
|
||||||
check_clk_relationship(spi)
|
|
||||||
dac_self_calibration(spi)
|
|
||||||
|
|
||||||
# Enable DAC outputs
|
|
||||||
spi_write(spi, 0x01, spi_read(spi, 0x01) & ~((1 << 4) | (1 << 3)))
|
|
||||||
|
|
||||||
power_down_afe(0, False)
|
|
||||||
power_down_afe(1, False)
|
|
||||||
manual_override(False)
|
|
||||||
|
|
||||||
print("AD9117 configuration completed successfully")
|
|
||||||
return True
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error configuring AD9117: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
finally:
|
|
||||||
spi.close()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
configure_ad9117()
|
|
@ -1,66 +0,0 @@
|
|||||||
# This file is part of Fast Servo Software Package.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2023 Jakub Matyas
|
|
||||||
# Warsaw University of Technology <jakubk.m@gmail.com>
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#
|
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import mmap
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
|
|
||||||
from pyfastservo.common import (
|
|
||||||
LED0_BASE_ADDR,
|
|
||||||
LED1_BASE_ADDR,
|
|
||||||
LED2_BASE_ADDR,
|
|
||||||
LED3_BASE_ADDR,
|
|
||||||
MAP_MASK,
|
|
||||||
PAGESIZE,
|
|
||||||
)
|
|
||||||
|
|
||||||
ON = 1
|
|
||||||
OFF = 0
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
addrs = [LED0_BASE_ADDR, LED1_BASE_ADDR, LED2_BASE_ADDR, LED3_BASE_ADDR]
|
|
||||||
|
|
||||||
f = os.open("/dev/mem", os.O_SYNC | os.O_RDWR)
|
|
||||||
for addr in addrs:
|
|
||||||
with mmap.mmap(
|
|
||||||
f,
|
|
||||||
PAGESIZE,
|
|
||||||
mmap.MAP_SHARED,
|
|
||||||
mmap.PROT_READ | mmap.PROT_WRITE,
|
|
||||||
offset=addr & ~MAP_MASK,
|
|
||||||
) as mem:
|
|
||||||
for i in range(6):
|
|
||||||
start_addr = addr & MAP_MASK
|
|
||||||
stop_addr = start_addr + 4
|
|
||||||
print(
|
|
||||||
f"addr: 0x{addr:x}\tstart_addr: 0x{start_addr}\tstop_addr: 0x{stop_addr}"
|
|
||||||
)
|
|
||||||
mem[start_addr:stop_addr] = ON.to_bytes(4, "little")
|
|
||||||
contents = mem[start_addr:stop_addr]
|
|
||||||
time.sleep(0.5)
|
|
||||||
mem[start_addr:stop_addr] = OFF.to_bytes(4, "little")
|
|
||||||
contents = mem[start_addr:stop_addr]
|
|
||||||
time.sleep(0.5)
|
|
||||||
|
|
||||||
os.close(f)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
@ -1,28 +0,0 @@
|
|||||||
# This file is part of Fast Servo Software Package.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2023 Jakub Matyas
|
|
||||||
# Warsaw University of Technology <jakubk.m@gmail.com>
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#
|
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
from pyfastservo import adc, si5340, dac
|
|
||||||
|
|
||||||
def main():
|
|
||||||
si5340.configure_si5340()
|
|
||||||
adc.configure_ltc2195()
|
|
||||||
dac.configure_ad9117()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
@ -1,280 +0,0 @@
|
|||||||
# This file is part of Fast Servo Software Package.
|
|
||||||
#
|
|
||||||
# Copyright (C) 2023 Jakub Matyas
|
|
||||||
# Warsaw University of Technology <jakubk.m@gmail.com>
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#
|
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# Additional Reference:
|
|
||||||
# https://github.com/torvalds/linux/blob/master/drivers/clk/clk-si5341.c
|
|
||||||
|
|
||||||
import time
|
|
||||||
from smbus2 import SMBus
|
|
||||||
|
|
||||||
BUS_NO = 0
|
|
||||||
IC_ADDR = 0x74
|
|
||||||
|
|
||||||
DEVICE_READY = 0x00FE
|
|
||||||
PLL_M_DEN = 0x023B
|
|
||||||
STATUS = 0x000C
|
|
||||||
STATUS_STICKY = 0x0011
|
|
||||||
|
|
||||||
STATUS_LOSREF = 0x04
|
|
||||||
STATUS_LOL = 0x08
|
|
||||||
|
|
||||||
|
|
||||||
def write_register(bus, address, value):
|
|
||||||
page = address >> 8
|
|
||||||
register = address & 0xFF
|
|
||||||
bus.write_byte_data(IC_ADDR, 0x01, page)
|
|
||||||
try:
|
|
||||||
bus.write_byte_data(IC_ADDR, register, value)
|
|
||||||
except Exception as e:
|
|
||||||
raise Exception(f"Write failed 0x{value:02X} at 0x{address:04X}: {e}")
|
|
||||||
|
|
||||||
def write_preamble(bus):
|
|
||||||
preamble = [
|
|
||||||
(0x0B24, 0xC0),
|
|
||||||
(0x0B25, 0x00),
|
|
||||||
(0x0502, 0x01),
|
|
||||||
(0x0505, 0x03),
|
|
||||||
(0x0957, 0x17),
|
|
||||||
(0x0B4E, 0x1A),
|
|
||||||
]
|
|
||||||
for address, value in preamble:
|
|
||||||
write_register(bus, address, value)
|
|
||||||
|
|
||||||
def write_postamble(bus):
|
|
||||||
postamble = [
|
|
||||||
(0x001C, 0x01), # Soft reset
|
|
||||||
(0x0B24, 0xC3),
|
|
||||||
(0x0B25, 0x02),
|
|
||||||
]
|
|
||||||
for address, value in postamble:
|
|
||||||
write_register(bus, address, value)
|
|
||||||
|
|
||||||
def wait_device_ready(bus):
|
|
||||||
for _ in range(15):
|
|
||||||
if bus.read_byte_data(IC_ADDR, DEVICE_READY) == 0x0F:
|
|
||||||
return True
|
|
||||||
time.sleep(0.02)
|
|
||||||
return False
|
|
||||||
|
|
||||||
def wait_for_lock(bus):
|
|
||||||
for _ in range(10):
|
|
||||||
status = bus.read_byte_data(IC_ADDR, STATUS)
|
|
||||||
if not (status & (STATUS_LOSREF | STATUS_LOL)):
|
|
||||||
return True
|
|
||||||
time.sleep(0.01)
|
|
||||||
return False
|
|
||||||
|
|
||||||
def check_pll_status(bus):
|
|
||||||
pll_status = bus.read_byte_data(IC_ADDR, 0x0C)
|
|
||||||
pll_locked = not (pll_status & STATUS_LOL)
|
|
||||||
print(f"PLL {'locked' if pll_locked else 'unlocked'}")
|
|
||||||
return pll_locked
|
|
||||||
|
|
||||||
def check_los_status(bus):
|
|
||||||
los_status = bus.read_byte_data(IC_ADDR, 0x0D)
|
|
||||||
xaxb_los = (los_status & 0x10) != 0
|
|
||||||
print(f"XA/XB LOS {'asserted' if xaxb_los else 'deasserted'}")
|
|
||||||
return not xaxb_los
|
|
||||||
|
|
||||||
def configure_si5340():
|
|
||||||
with SMBus(BUS_NO) as bus:
|
|
||||||
if not wait_device_ready(bus):
|
|
||||||
print("Device not ready. Aborting.")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Programming sequence from ClockBuilder Pro, default settings
|
|
||||||
# to initialize system using XTAL input
|
|
||||||
main_config = [
|
|
||||||
(0x0006, 0x00), # TOOL_VERSION
|
|
||||||
(0x0007, 0x00), # Not in datasheet
|
|
||||||
(0x0008, 0x00), # Not in datasheet
|
|
||||||
(0x000B, 0x74), # I2C_ADDR
|
|
||||||
(0x0017, 0xD0), # INT mask (disable interrupts)
|
|
||||||
(0x0018, 0xFF), # INT mask
|
|
||||||
(0x0021, 0x0F), # Select XTAL as input
|
|
||||||
(0x0022, 0x00), # Not in datasheet
|
|
||||||
(0x002B, 0x02), # SPI config
|
|
||||||
(0x002C, 0x20), # LOS enable for XTAL
|
|
||||||
(0x002D, 0x00), # LOS timing
|
|
||||||
(0x002E, 0x00), # LOS trigger (thresholds)
|
|
||||||
(0x002F, 0x00),
|
|
||||||
(0x0030, 0x00),
|
|
||||||
(0x0031, 0x00),
|
|
||||||
(0x0032, 0x00),
|
|
||||||
(0x0033, 0x00),
|
|
||||||
(0x0034, 0x00),
|
|
||||||
(0x0035, 0x00), # LOS trigger (thresholds) end
|
|
||||||
(0x0036, 0x00), # LOS clear (thresholds)
|
|
||||||
(0x0037, 0x00),
|
|
||||||
(0x0038, 0x00),
|
|
||||||
(0x0039, 0x00),
|
|
||||||
(0x003A, 0x00),
|
|
||||||
(0x003B, 0x00),
|
|
||||||
(0x003C, 0x00),
|
|
||||||
(0x003D, 0x00), # LOS clear (thresholds) end
|
|
||||||
(0x0041, 0x00), # LOS0_DIV_SEL
|
|
||||||
(0x0042, 0x00), # LOS1_DIV_SEL
|
|
||||||
(0x0043, 0x00), # LOS2_DIV_SEL
|
|
||||||
(0x0044, 0x00), # LOS3_DIV_SEL
|
|
||||||
(0x009E, 0x00), # LOL_SET_THR
|
|
||||||
(0x0102, 0x01), # Enable outputs
|
|
||||||
(0x013F, 0x00), # OUTX_ALWAYS_ON
|
|
||||||
(0x0140, 0x00), # OUTX_ALWAYS_ON
|
|
||||||
(0x0141, 0x40), # OUT_DIS_LOL_MSK, OUT_DIS_MSK_LOS_PFD
|
|
||||||
(0x0202, 0x00), # XAXB_FREQ_OFFSET (=0)
|
|
||||||
|
|
||||||
# PLL Configuration
|
|
||||||
(0x0235, 0x00), # M_NUM
|
|
||||||
(0x0236, 0x00),
|
|
||||||
(0x0237, 0x00),
|
|
||||||
(0x0238, 0x80),
|
|
||||||
(0x0239, 0x89),
|
|
||||||
(0x023A, 0x00),
|
|
||||||
(0x023B, 0x00), # M_DEN
|
|
||||||
(0x023C, 0x00),
|
|
||||||
(0x023D, 0x00),
|
|
||||||
(0x023E, 0x80),
|
|
||||||
|
|
||||||
# Synthesizer configuration
|
|
||||||
(0x0302, 0x00), # N0_NUM
|
|
||||||
(0x0303, 0x00),
|
|
||||||
(0x0304, 0x00),
|
|
||||||
(0x0305, 0x00),
|
|
||||||
(0x0306, 0x21),
|
|
||||||
(0x0307, 0x00),
|
|
||||||
(0x0308, 0x00), # N0_DEN
|
|
||||||
(0x0309, 0x00),
|
|
||||||
(0x030A, 0x00),
|
|
||||||
(0x030B, 0x80),
|
|
||||||
(0x030C, 0x01), # N0_UPDATE
|
|
||||||
|
|
||||||
# N1 Configuration (1:1 ratio)
|
|
||||||
(0x030D, 0x00), # N1_NUM
|
|
||||||
(0x030E, 0x00),
|
|
||||||
(0x030F, 0x00),
|
|
||||||
(0x0310, 0x00),
|
|
||||||
(0x0311, 0x00),
|
|
||||||
(0x0312, 0x01),
|
|
||||||
(0x0313, 0x00), # N1_DEN
|
|
||||||
(0x0314, 0x00),
|
|
||||||
(0x0315, 0x00),
|
|
||||||
(0x0316, 0x01),
|
|
||||||
(0x0317, 0x01), # N1_UPDATE
|
|
||||||
|
|
||||||
# N2 Configuration (1:1 ratio)
|
|
||||||
(0x0318, 0x00), # N2_NUM
|
|
||||||
(0x0319, 0x00),
|
|
||||||
(0x031A, 0x00),
|
|
||||||
(0x031B, 0x00),
|
|
||||||
(0x031C, 0x00),
|
|
||||||
(0x031D, 0x01),
|
|
||||||
(0x031E, 0x00), # N2_DEN
|
|
||||||
(0x031F, 0x00),
|
|
||||||
(0x0320, 0x00),
|
|
||||||
(0x0321, 0x01),
|
|
||||||
(0x0322, 0x01), # N2_UPDATE
|
|
||||||
|
|
||||||
# N3 Configuration (1:1 ratio)
|
|
||||||
(0x0323, 0x00), # N3_NUM
|
|
||||||
(0x0324, 0x00),
|
|
||||||
(0x0325, 0x00),
|
|
||||||
(0x0326, 0x00),
|
|
||||||
(0x0327, 0x00),
|
|
||||||
(0x0328, 0x01),
|
|
||||||
(0x0329, 0x00), # N3_DEN
|
|
||||||
(0x032A, 0x00),
|
|
||||||
(0x032B, 0x00),
|
|
||||||
(0x032C, 0x01),
|
|
||||||
(0x032D, 0x01), # N3_UPDATE
|
|
||||||
|
|
||||||
# Output configuration
|
|
||||||
(0x0112, 0x06), # OUT0 config
|
|
||||||
(0x0113, 0x09), # OUT0 format
|
|
||||||
(0x0114, 0x3B), # OUT0 CM/AMPL
|
|
||||||
(0x0115, 0x28), # OUT0 MUX_SEL
|
|
||||||
|
|
||||||
(0x0117, 0x06), # OUT1 config
|
|
||||||
(0x0118, 0x09), # OUT1 format
|
|
||||||
(0x0119, 0x3B), # OUT1 CM/AMPL
|
|
||||||
(0x011A, 0x28), # OUT1 MUX_SEL
|
|
||||||
|
|
||||||
(0x0126, 0x06), # OUT2 config
|
|
||||||
(0x0127, 0x09), # OUT2 format
|
|
||||||
(0x0128, 0x3B), # OUT2 CM/AMPL
|
|
||||||
(0x0129, 0x28), # OUT2 MUX_SEL
|
|
||||||
|
|
||||||
(0x012B, 0x06), # OUT3 config
|
|
||||||
(0x012C, 0xCC), # OUT3 format
|
|
||||||
(0x012D, 0x00), # OUT3 CM/AMPL
|
|
||||||
(0x012E, 0x58), # OUT3 MUX_SEL
|
|
||||||
|
|
||||||
# Miscellaneous configuration
|
|
||||||
(0x090E, 0x02), # XAXB_EXTCLK_EN=0 XAXB_PDNB=1 (use XTAL)
|
|
||||||
(0x091C, 0x04), # ZDM_EN=4 (Normal mode)
|
|
||||||
(0x0943, 0x00), # IO_VDD_SEL
|
|
||||||
(0x0949, 0x00), # IN_EN (disable input clocks)
|
|
||||||
(0x094A, 0x00), # INx_TO_PFD_EN (disabled)
|
|
||||||
(0x094E, 0x49), # REFCLK_HYS_SEL (set by CBPro)
|
|
||||||
(0x094F, 0x02), # Not in datasheet
|
|
||||||
(0x095E, 0x00), # M_INTEGER (set by CBPro)
|
|
||||||
(0x0A02, 0x00), # N_ADD_0P5 (set by CBPro)
|
|
||||||
(0x0A03, 0x01), # N_CLK_TO_OUTX_EN
|
|
||||||
(0x0A04, 0x01), # N_PIBYP
|
|
||||||
(0x0A05, 0x01), # N_PDNB
|
|
||||||
(0x0A14, 0x00), # N0_HIGH_FREQ (set by CBPro)
|
|
||||||
(0x0A1A, 0x00), # N1_HIGH_FREQ (set by CBPro)
|
|
||||||
(0x0A20, 0x00), # N2_HIGH_FREQ (set by CBPro)
|
|
||||||
(0x0A26, 0x00), # N3_HIGH_FREQ (set by CBPro)
|
|
||||||
(0x0B44, 0x0F), # PDIV_ENB (set by CBPro)
|
|
||||||
(0x0B4A, 0x0E), # N_CLK_DIS
|
|
||||||
(0x0B57, 0x0E), # VCO_RESET_CALCODE (set by CBPro)
|
|
||||||
(0x0B58, 0x01), # VCO_RESET_CALCODE (set by CBPro)
|
|
||||||
]
|
|
||||||
|
|
||||||
write_preamble(bus)
|
|
||||||
|
|
||||||
time.sleep(0.3)
|
|
||||||
|
|
||||||
print("Writing main configuration...")
|
|
||||||
for address, value in main_config:
|
|
||||||
write_register(bus, address, value)
|
|
||||||
print("Main configuration written")
|
|
||||||
|
|
||||||
write_postamble(bus)
|
|
||||||
|
|
||||||
if not wait_for_lock(bus):
|
|
||||||
print("Error waiting for input clock or PLL lock")
|
|
||||||
else:
|
|
||||||
print("Input clock present and PLL locked")
|
|
||||||
|
|
||||||
bus.write_byte_data(IC_ADDR, STATUS_STICKY, 0)
|
|
||||||
|
|
||||||
# Final status check
|
|
||||||
pll_locked = check_pll_status(bus)
|
|
||||||
xaxb_signal_present = check_los_status(bus)
|
|
||||||
|
|
||||||
if not pll_locked:
|
|
||||||
print("Error: PLL is not locked")
|
|
||||||
elif not xaxb_signal_present:
|
|
||||||
print("Error: XA/XB signal is lost")
|
|
||||||
else:
|
|
||||||
print("Si5340 configuration completed successfully")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
configure_si5340()
|
|
@ -1,31 +0,0 @@
|
|||||||
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
|
|
||||||
index 480269fa60..64b20e4200 100644
|
|
||||||
--- a/arch/arm/dts/Makefile
|
|
||||||
+++ b/arch/arm/dts/Makefile
|
|
||||||
@@ -339,6 +339,7 @@ dtb-$(CONFIG_ARCH_ZYNQ) += \
|
|
||||||
zynq-cse-nor.dtb \
|
|
||||||
zynq-cse-qspi-single.dtb \
|
|
||||||
zynq-dlc20-rev1.0.dtb \
|
|
||||||
+ zynq-fast-servo.dtb \
|
|
||||||
zynq-microzed.dtb \
|
|
||||||
zynq-minized.dtb \
|
|
||||||
zynq-picozed.dtb \
|
|
||||||
diff --git a/configs/xilinx_zynq_virt_defconfig b/configs/xilinx_zynq_virt_defconfig
|
|
||||||
index 474abc7f6b..6e6bbd4aab 100644
|
|
||||||
--- a/configs/xilinx_zynq_virt_defconfig
|
|
||||||
+++ b/configs/xilinx_zynq_virt_defconfig
|
|
||||||
@@ -80,6 +80,7 @@ CONFIG_CMD_MTDPARTS_SPREAD=y
|
|
||||||
CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES=y
|
|
||||||
CONFIG_CMD_UBI=y
|
|
||||||
CONFIG_OF_BOARD=y
|
|
||||||
+CONFIG_SYS_CONFIG_NAME="zynq-fast-servo"
|
|
||||||
CONFIG_OF_LIST="zynq-zc702 zynq-zc706 zynq-zc770-xm010 zynq-zc770-xm011 zynq-zc770-xm011-x16 zynq-zc770-xm012 zynq-zc770-xm013 zynq-cc108 zynq-microzed zynq-minized zynq-picozed zynq-zed zynq-zturn zynq-zturn-v5 zynq-zybo zynq-zybo-z7 zynq-dlc20-rev1.0"
|
|
||||||
CONFIG_ENV_IS_NOWHERE=y
|
|
||||||
CONFIG_ENV_IS_IN_FAT=y
|
|
||||||
diff --git a/include/configs/zynq-fast-servo.h b/include/configs/zynq-fast-servo.h
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000..0aa486a2b7
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/include/configs/zynq-fast-servo.h
|
|
||||||
@@ -0,0 +1 @@
|
|
||||||
+#include <configs/zynq-common.h>
|
|
46
flake.lock
generated
46
flake.lock
generated
@ -18,16 +18,16 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1734323986,
|
"lastModified": 1703961334,
|
||||||
"narHash": "sha256-m/lh6hYMIWDYHCAsn81CDAiXoT3gmxXI9J987W5tZrE=",
|
"narHash": "sha256-M1mV/Cq+pgjk0rt6VxoyyD+O8cOUiai8t9Q6Yyq4noY=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "394571358ce82dff7411395829aa6a3aad45b907",
|
"rev": "b0d36bd0a420ecee3bc916c91886caca87c894e9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"ref": "nixos-24.11",
|
"ref": "nixos-unstable",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
@ -56,43 +56,7 @@
|
|||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"not-os": "not-os",
|
"not-os": "not-os"
|
||||||
"src-migen": "src-migen",
|
|
||||||
"src-misoc": "src-misoc"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"src-migen": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1727677091,
|
|
||||||
"narHash": "sha256-Zg3SQnTwMM/VkOGKogbPyuCC2NhLy8HB2SPEUWWNgCU=",
|
|
||||||
"owner": "m-labs",
|
|
||||||
"repo": "migen",
|
|
||||||
"rev": "c19ae9f8ae162ffe2d310a92bfce53ac2a821bc8",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "m-labs",
|
|
||||||
"repo": "migen",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"src-misoc": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1729234629,
|
|
||||||
"narHash": "sha256-TLsTCXV5AC2xh+bS7EhBVBKqdqIU3eKrnlWcFF9LtAM=",
|
|
||||||
"ref": "refs/heads/master",
|
|
||||||
"rev": "6085a312bca26adeca6584e37d08c8ba2e1d6e38",
|
|
||||||
"revCount": 2460,
|
|
||||||
"submodules": true,
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/m-labs/misoc.git"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"submodules": true,
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/m-labs/misoc.git"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
872
flake.nix
872
flake.nix
@ -1,379 +1,138 @@
|
|||||||
{
|
{
|
||||||
description = "Firmware for Sinara Fast-Servo based on Not-OS and Linien";
|
description = "Firmware for Sinara Fast-Servo based on Not-OS and Linien";
|
||||||
|
|
||||||
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-24.11;
|
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable;
|
||||||
inputs.not-os.url = github:cleverca22/not-os;
|
inputs.not-os.url = github:cleverca22/not-os;
|
||||||
inputs.not-os.inputs.nixpkgs.follows = "nixpkgs";
|
inputs.not-os.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
|
||||||
inputs.src-migen = { url = github:m-labs/migen; flake = false; };
|
outputs = { self, nixpkgs, not-os }:
|
||||||
inputs.src-misoc = { type = "git"; url = "https://github.com/m-labs/misoc.git"; submodules = true; flake = false; };
|
|
||||||
|
|
||||||
outputs = { self, nixpkgs, not-os, src-migen, src-misoc }:
|
|
||||||
let
|
let
|
||||||
pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ crosspkgs-overlay ]; };
|
pkgs = import nixpkgs { system = "x86_64-linux"; };
|
||||||
pkgs-armv7l = pkgs.pkgsCross.zynq-armv7l-linux;
|
not-os-cfg = not-os-configured.config.system;
|
||||||
fsbl-support = ./fast-servo/fsbl-support;
|
|
||||||
|
|
||||||
version = "2.1.0";
|
|
||||||
linien-src = pkgs.applyPatches {
|
|
||||||
name = "linien-src";
|
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "linien-org";
|
|
||||||
repo = "linien";
|
|
||||||
rev = "v" + version;
|
|
||||||
sha256 = "sha256-j6oiP/usLfV5HZtKLcXQ5pHhhxRG05kP2FMwingiWm0=";
|
|
||||||
};
|
|
||||||
prePatch = ''
|
|
||||||
mkdir -p fast_servo/gateware
|
|
||||||
cp -r ${./fast-servo/linien-gateware}/. fast_servo/gateware
|
|
||||||
'';
|
|
||||||
patches = [
|
|
||||||
./fast-servo/linien-common-fast-servo-hardware-specific.patch
|
|
||||||
./fast-servo/linien-server-fast-servo-hardware-specific.patch
|
|
||||||
./fast-servo/linien-gui-fast-servo-hardware-specific.patch
|
|
||||||
./fast-servo/linien-client-ssh-port-change.patch
|
|
||||||
./fast-servo/linien-server-fast-servo.patch
|
|
||||||
./fast-servo/linien-gateware-fast-servo.patch
|
|
||||||
./fast-servo/autolock_pipeline.patch
|
|
||||||
./fast-servo/iir_pipeline.patch
|
|
||||||
./fast-servo/linien_module_pipeline.patch
|
|
||||||
./fast-servo/pid_pipeline.patch
|
|
||||||
./fast-servo/pid_err_sig_pipeline.patch
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
patched-not-os = pkgs.applyPatches {
|
patched-not-os = pkgs.applyPatches {
|
||||||
name = "not-os-patched";
|
name = "not-os-patched";
|
||||||
src = not-os;
|
src = not-os;
|
||||||
patches = [
|
patches = [
|
||||||
./not-os-patches/network.patch
|
./network.patch
|
||||||
./not-os-patches/pr-28.patch
|
./pr-28.patch
|
||||||
./not-os-patches/pr-29.patch
|
./pr-29.patch
|
||||||
./not-os-patches/pr-30.patch
|
./pr-30.patch
|
||||||
./not-os-patches/pr-31.patch
|
|
||||||
./not-os-patches/pr-33.patch
|
|
||||||
./not-os-patches/iproute2.patch
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
crossSystem = {
|
gnu-platform = "arm-none-eabi";
|
||||||
system = "armv7l-linux";
|
|
||||||
linux-kernel = {
|
binutils-pkg = { zlib, extraConfigureFlags ? [] }: pkgs.stdenv.mkDerivation rec {
|
||||||
name = "zynq";
|
basename = "binutils";
|
||||||
baseConfig = "multi_v7_defconfig";
|
version = "2.30";
|
||||||
target = "uImage";
|
name = "${basename}-${gnu-platform}-${version}";
|
||||||
installTarget = "uImage";
|
src = pkgs.fetchurl {
|
||||||
autoModules = false;
|
url = "https://ftp.gnu.org/gnu/binutils/binutils-${version}.tar.bz2";
|
||||||
DTB = true;
|
sha256 = "028cklfqaab24glva1ks2aqa1zxa6w6xmc8q34zs1sb7h22dxspg";
|
||||||
makeFlags = [ "LOADADDR=0x8000" ];
|
};
|
||||||
|
configureFlags = [
|
||||||
|
"--enable-deterministic-archives"
|
||||||
|
"--target=${gnu-platform}"
|
||||||
|
"--with-cpu=cortex-a9"
|
||||||
|
"--with-fpu=vfpv3"
|
||||||
|
"--with-float=hard"
|
||||||
|
"--with-mode=thumb"
|
||||||
|
] ++ extraConfigureFlags;
|
||||||
|
outputs = [ "out" "info" "man" ];
|
||||||
|
depsBuildBuild = [ pkgs.buildPackages.stdenv.cc ];
|
||||||
|
buildInputs = [ zlib ];
|
||||||
|
enableParallelBuilding = true;
|
||||||
|
meta = {
|
||||||
|
description = "Tools for manipulating binaries (linker, assembler, etc.)";
|
||||||
|
longDescription = ''
|
||||||
|
The GNU Binutils are a collection of binary tools. The main
|
||||||
|
ones are `ld' (the GNU linker) and `as' (the GNU assembler).
|
||||||
|
They also include the BFD (Binary File Descriptor) library,
|
||||||
|
`gprof', `nm', `strip', etc.
|
||||||
|
'';
|
||||||
|
homepage = http://www.gnu.org/software/binutils/;
|
||||||
|
license = pkgs.lib.licenses.gpl3Plus;
|
||||||
|
/* Give binutils a lower priority than gcc-wrapper to prevent a
|
||||||
|
collision due to the ld/as wrappers/symlinks in the latter. */
|
||||||
|
priority = "10";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
crosspkgs-overlay = (self: super: {
|
gcc-pkg = { gmp, mpfr, libmpc, platform-binutils, extraConfigureFlags ? [] }: pkgs.stdenv.mkDerivation rec {
|
||||||
pkgsCross = super.pkgsCross // {
|
basename = "gcc";
|
||||||
zynq-baremetal = import super.path {
|
version = "9.1.0";
|
||||||
system = "x86_64-linux";
|
name = "${basename}-${gnu-platform}-${version}";
|
||||||
crossSystem = {
|
src = pkgs.fetchurl {
|
||||||
config = "arm-none-eabihf";
|
url = "https://ftp.gnu.org/gnu/gcc/gcc-${version}/gcc-${version}.tar.xz";
|
||||||
libc = "newlib";
|
sha256 = "1817nc2bqdc251k0lpc51cimna7v68xjrnvqzvc50q3ax4s6i9kr";
|
||||||
gcc.cpu = "cortex-a9";
|
|
||||||
gcc.fpu = "vfpv3";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
zynq-armv7l-linux = import super.path {
|
|
||||||
system = "x86_64-linux";
|
|
||||||
inherit crossSystem;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
});
|
preConfigure = ''
|
||||||
|
mkdir build
|
||||||
migen = pkgs.python3Packages.buildPythonPackage rec {
|
cd build
|
||||||
name = "migen";
|
'';
|
||||||
src = src-migen;
|
configureScript = "../configure";
|
||||||
format = "pyproject";
|
configureFlags = [
|
||||||
nativeBuildInputs = [ pkgs.python3Packages.setuptools ];
|
"--target=${gnu-platform}"
|
||||||
propagatedBuildInputs = [ pkgs.python3Packages.colorama ];
|
"--with-arch=armv7-a"
|
||||||
|
"--with-tune=cortex-a9"
|
||||||
|
"--with-fpu=vfpv3"
|
||||||
|
"--with-float=hard"
|
||||||
|
"--disable-libssp"
|
||||||
|
"--enable-languages=c"
|
||||||
|
"--with-as=${platform-binutils}/bin/${gnu-platform}-as"
|
||||||
|
"--with-ld=${platform-binutils}/bin/${gnu-platform}-ld" ] ++ extraConfigureFlags;
|
||||||
|
outputs = [ "out" "info" "man" ];
|
||||||
|
hardeningDisable = [ "format" "pie" ];
|
||||||
|
propagatedBuildInputs = [ gmp mpfr libmpc platform-binutils ];
|
||||||
|
enableParallelBuilding = true;
|
||||||
|
dontFixup = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
misoc = pkgs.python3Packages.buildPythonPackage {
|
newlib-pkg = { platform-binutils, platform-gcc }: pkgs.stdenv.mkDerivation rec {
|
||||||
name = "misoc";
|
pname = "newlib";
|
||||||
src = src-misoc;
|
version = "3.1.0";
|
||||||
propagatedBuildInputs = with pkgs.python3Packages; [ jinja2 numpy migen pyserial asyncserial ];
|
src = pkgs.fetchurl {
|
||||||
};
|
url = "ftp://sourceware.org/pub/newlib/newlib-${version}.tar.gz";
|
||||||
|
sha256 = "0ahh3n079zjp7d9wynggwrnrs27440aac04340chf1p9476a2kzv";
|
||||||
vivado = pkgs.buildFHSEnv {
|
|
||||||
name = "vivado";
|
|
||||||
targetPkgs = pkgs: with pkgs; let
|
|
||||||
# Apply patch from https://github.com/nix-community/nix-environments/pull/54
|
|
||||||
# to fix ncurses libtinfo.so's soname issue
|
|
||||||
ncurses' = ncurses5.overrideAttrs (old: {
|
|
||||||
configureFlags = old.configureFlags ++ [ "--with-termlib" ];
|
|
||||||
postFixup = "";
|
|
||||||
});
|
|
||||||
in [
|
|
||||||
libxcrypt-legacy
|
|
||||||
(ncurses'.override { unicodeSupport = false; })
|
|
||||||
zlib
|
|
||||||
libuuid
|
|
||||||
xorg.libSM
|
|
||||||
xorg.libICE
|
|
||||||
xorg.libXrender
|
|
||||||
xorg.libX11
|
|
||||||
xorg.libXext
|
|
||||||
xorg.libXtst
|
|
||||||
xorg.libXi
|
|
||||||
freetype
|
|
||||||
fontconfig
|
|
||||||
];
|
|
||||||
profile = "set -e; source /opt/Xilinx/Vivado/2024.2/settings64.sh";
|
|
||||||
runScript = "vivado";
|
|
||||||
};
|
|
||||||
|
|
||||||
cma = pkgs-armv7l.python3Packages.buildPythonPackage rec {
|
|
||||||
pname = "cma";
|
|
||||||
version = "3.3.0";
|
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "CMA-ES";
|
|
||||||
repo = "pycma";
|
|
||||||
rev = "refs/tags/r${version}";
|
|
||||||
hash = "sha256-+UJI3hDVbDMfRF4bkwHED3eJCHzxS2hO4YPUzJqcoQI=";
|
|
||||||
};
|
};
|
||||||
|
nativeBuildInputs = [ platform-binutils platform-gcc ];
|
||||||
|
configureFlags = [
|
||||||
|
"--target=${gnu-platform}"
|
||||||
|
|
||||||
propagatedBuildInputs = [ pkgs-armv7l.python3Packages.numpy ];
|
"--with-cpu=cortex-a9"
|
||||||
|
"--with-fpu=vfpv3"
|
||||||
|
"--with-float=hard"
|
||||||
|
"--with-mode=thumb"
|
||||||
|
"--enable-interwork"
|
||||||
|
"--disable-multilib"
|
||||||
|
|
||||||
pythonImportsCheck = [ "cma" ];
|
"--disable-newlib-supplied-syscalls"
|
||||||
|
"--with-gnu-ld"
|
||||||
checkPhase = ''
|
"--with-gnu-as"
|
||||||
# At least one doctest fails, thus only limited amount of files is tested
|
"--disable-newlib-io-float"
|
||||||
python -m cma.test interfaces.py purecma.py logger.py optimization_tools.py transformations.py
|
"--disable-werror"
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
pyrp3 = pkgs-armv7l.python3Packages.buildPythonPackage rec {
|
|
||||||
pname = "pyrp3";
|
|
||||||
version = "2.1.0";
|
|
||||||
format = "pyproject";
|
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "linien-org";
|
|
||||||
repo = "pyrp3";
|
|
||||||
rev = "v${version}";
|
|
||||||
hash = "sha256-ol1QGXyCOei94iIPIocuTRHBxa5jKSH5RzjzROfZaBI=";
|
|
||||||
};
|
|
||||||
patches = ./fast-servo/linien-pyrp3-monitor.patch;
|
|
||||||
nativeBuildInputs = [
|
|
||||||
pkgs-armv7l.python3Packages.setuptools
|
|
||||||
pkgs-armv7l.gcc
|
|
||||||
];
|
];
|
||||||
postInstall = ''
|
dontFixup = true;
|
||||||
cp monitor/libmonitor.so $out/lib
|
|
||||||
'';
|
|
||||||
postFixup = ''
|
|
||||||
substituteInPlace $out/${pkgs.python3.sitePackages}/pyrp3/raw_memory.py \
|
|
||||||
--replace "libmonitor.so" "$out/lib/libmonitor.so"
|
|
||||||
'';
|
|
||||||
propagatedBuildInputs = with pkgs-armv7l.python3Packages; [
|
|
||||||
cached-property
|
|
||||||
numpy
|
|
||||||
rpyc
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
linien-common = pkgs.python3Packages.buildPythonPackage rec {
|
|
||||||
pname = "linien-common";
|
|
||||||
inherit version;
|
|
||||||
pyproject = true;
|
|
||||||
|
|
||||||
src = linien-src;
|
|
||||||
|
|
||||||
sourceRoot = "${src.name}/linien-common";
|
|
||||||
|
|
||||||
preBuild = ''
|
|
||||||
export HOME=$(mktemp -d)
|
|
||||||
'';
|
|
||||||
|
|
||||||
nativeBuildInputs = [ pkgs.python3Packages.setuptools ];
|
|
||||||
|
|
||||||
pythonRelaxDeps = [ "importlib-metadata" ];
|
|
||||||
|
|
||||||
propagatedBuildInputs = with pkgs.python3Packages; [
|
|
||||||
importlib-metadata
|
|
||||||
numpy
|
|
||||||
rpyc
|
|
||||||
scipy
|
|
||||||
appdirs
|
|
||||||
];
|
|
||||||
|
|
||||||
pythonImportsCheck = [ "linien_common" ];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
linien-common-armv7l = pkgs-armv7l.python3Packages.buildPythonPackage rec {
|
gnutoolchain = rec {
|
||||||
pname = "linien-common-armv7l";
|
binutils-bootstrap = pkgs.callPackage binutils-pkg { };
|
||||||
inherit version;
|
gcc-bootstrap = pkgs.callPackage gcc-pkg {
|
||||||
pyproject = true;
|
platform-binutils = binutils-bootstrap;
|
||||||
|
extraConfigureFlags = [ "--disable-libgcc" ];
|
||||||
src = linien-src;
|
};
|
||||||
|
newlib = pkgs.callPackage newlib-pkg {
|
||||||
sourceRoot = "${src.name}/linien-common";
|
platform-binutils = binutils-bootstrap;
|
||||||
|
platform-gcc = gcc-bootstrap;
|
||||||
preBuild = ''
|
};
|
||||||
export HOME=$(mktemp -d)
|
binutils = pkgs.callPackage binutils-pkg {
|
||||||
'';
|
extraConfigureFlags = [ "--with-lib-path=${newlib}/arm-none-eabi/lib" ];
|
||||||
|
};
|
||||||
nativeBuildInputs = [ pkgs-armv7l.python3Packages.setuptools ];
|
gcc = pkgs.callPackage gcc-pkg {
|
||||||
|
platform-binutils = binutils;
|
||||||
pythonRelaxDeps = [ "importlib-metadata" ];
|
extraConfigureFlags = [ "--enable-newlib" "--with-headers=${newlib}/arm-none-eabi/include" ];
|
||||||
|
|
||||||
propagatedBuildInputs = with pkgs-armv7l.python3Packages; [
|
|
||||||
importlib-metadata
|
|
||||||
numpy
|
|
||||||
rpyc
|
|
||||||
scipy
|
|
||||||
appdirs
|
|
||||||
];
|
|
||||||
|
|
||||||
pythonImportsCheck = [ "linien_common" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
linien-client = pkgs.python3Packages.buildPythonPackage rec {
|
|
||||||
pname = "linien-client";
|
|
||||||
inherit version;
|
|
||||||
src = linien-src;
|
|
||||||
|
|
||||||
pyproject = true;
|
|
||||||
|
|
||||||
sourceRoot = "${src.name}/linien-client";
|
|
||||||
|
|
||||||
preBuild = ''
|
|
||||||
export HOME=$(mktemp -d)
|
|
||||||
'';
|
|
||||||
|
|
||||||
nativeBuildInputs = [ pkgs.python3Packages.setuptools ];
|
|
||||||
|
|
||||||
doInstallCheck = false;
|
|
||||||
doCheck = false;
|
|
||||||
propagatedBuildInputs = with pkgs.python3Packages; [
|
|
||||||
fabric
|
|
||||||
typing-extensions
|
|
||||||
] ++ [ linien-common ];
|
|
||||||
|
|
||||||
pythonImportsCheck = [ "linien_client" ];
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
linien-gui = pkgs.python3Packages.buildPythonApplication rec {
|
|
||||||
pname = "linien-gui";
|
|
||||||
inherit version;
|
|
||||||
src = linien-src;
|
|
||||||
pyproject = true;
|
|
||||||
|
|
||||||
sourceRoot = "${src.name}/linien-gui";
|
|
||||||
nativeBuildInputs = with pkgs.python3Packages; [
|
|
||||||
setuptools
|
|
||||||
] ++ [
|
|
||||||
pkgs.qt5.wrapQtAppsHook
|
|
||||||
];
|
|
||||||
|
|
||||||
patches = [
|
|
||||||
./fast-servo/linien-gui-fast-servo-rm-ota-update.patch
|
|
||||||
];
|
|
||||||
|
|
||||||
# Makes qt-wayland appear in the qt paths injected by the wrapper - helps users
|
|
||||||
# with `QT_QPA_PLATFORM=wayland` in their environment.
|
|
||||||
buildInputs = [
|
|
||||||
pkgs.qt5.qtwayland
|
|
||||||
];
|
|
||||||
|
|
||||||
propagatedBuildInputs = with pkgs.python3Packages; [
|
|
||||||
click
|
|
||||||
pyqtgraph
|
|
||||||
pyqt5
|
|
||||||
requests
|
|
||||||
superqt
|
|
||||||
] ++ [ linien-client ];
|
|
||||||
|
|
||||||
dontWrapQtApps = true;
|
|
||||||
|
|
||||||
preFixup = ''
|
|
||||||
makeWrapperArgs+=("''${qtWrapperArgs[@]}")
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
linien-server = pkgs-armv7l.python3Packages.buildPythonPackage rec {
|
|
||||||
pname = "linien-server";
|
|
||||||
inherit version;
|
|
||||||
src = linien-src;
|
|
||||||
pyproject = true;
|
|
||||||
|
|
||||||
sourceRoot = "${src.name}/linien-server";
|
|
||||||
|
|
||||||
postPatch = ''
|
|
||||||
cp ${fast-servo-gateware}/csrmap.py linien_server/csrmap.py
|
|
||||||
substituteInPlace linien_server/acquisition.py \
|
|
||||||
--replace " start_nginx()" "" \
|
|
||||||
--replace " stop_nginx()" "" \
|
|
||||||
--replace " flash_fpga()" ""
|
|
||||||
'';
|
|
||||||
nativeBuildInputs = [ pkgs-armv7l.python3Packages.setuptools ];
|
|
||||||
propagatedBuildInputs = with pkgs-armv7l.python3Packages; [
|
|
||||||
fire
|
|
||||||
influxdb-client
|
|
||||||
pylpsd
|
|
||||||
] ++ [
|
|
||||||
linien-common-armv7l
|
|
||||||
cma
|
|
||||||
pyrp3
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
fast-servo-gateware = pkgs.stdenv.mkDerivation rec {
|
|
||||||
name = "fast-servo-gateware";
|
|
||||||
src = linien-src;
|
|
||||||
nativeBuildInputs = [
|
|
||||||
(pkgs.python3.withPackages(ps: [
|
|
||||||
migen misoc
|
|
||||||
(ps.linien-common.overrideAttrs(oa: {
|
|
||||||
# config.py tries to access $HOME, but we do not need it for building gateware
|
|
||||||
postPatch = ''
|
|
||||||
echo > linien_common/config.py
|
|
||||||
echo > linien_common/__init__.py
|
|
||||||
'';
|
|
||||||
doCheck = false;
|
|
||||||
}))
|
|
||||||
]))
|
|
||||||
vivado
|
|
||||||
];
|
|
||||||
buildPhase = ''
|
|
||||||
python -m gateware.fpga_image_helper -p fastservo
|
|
||||||
'';
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out $out/nix-support
|
|
||||||
cp gateware/build/top.bit $out
|
|
||||||
cp linien-server/linien_server/gateware.bin $out
|
|
||||||
cp linien-server/linien_server/csrmap.py $out
|
|
||||||
echo file binary-dist $out/top.bit >> $out/nix-support/hydra-build-products
|
|
||||||
echo file binary-dist $out/gateware.bin >> $out/nix-support/hydra-build-products
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
pyfastservo = pkgs-armv7l.python3Packages.buildPythonPackage rec {
|
|
||||||
name = "pyfastservo";
|
|
||||||
src = ./fast-servo;
|
|
||||||
preBuild = ''
|
|
||||||
cat > setup.py << EOF
|
|
||||||
from setuptools import setup
|
|
||||||
|
|
||||||
setup(
|
|
||||||
name="pyfastservo",
|
|
||||||
packages=["pyfastservo"],
|
|
||||||
install_requires=["spidev", "smbus2"],
|
|
||||||
entry_points = {"console_scripts": ["fp_leds=pyfastservo.fp_leds:main"]},
|
|
||||||
)
|
|
||||||
EOF
|
|
||||||
'';
|
|
||||||
propagatedBuildInputs = with pkgs-armv7l.python3Packages; [
|
|
||||||
spidev
|
|
||||||
smbus2
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mkbootimage = pkgs.stdenv.mkDerivation {
|
mkbootimage = pkgs.stdenv.mkDerivation {
|
||||||
@ -399,262 +158,201 @@
|
|||||||
hardeningDisable = [ "fortify" ];
|
hardeningDisable = [ "fortify" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
board-package-set = { board }: let
|
fsbl = { board ? "zc706" }: pkgs.stdenv.mkDerivation {
|
||||||
not-os-configured = (import patched-not-os {
|
name = "${board}-fsbl";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "Xilinx";
|
||||||
|
repo = "embeddedsw";
|
||||||
|
rev = "65c849ed46c88c67457e1fc742744f96db968ff1";
|
||||||
|
sha256 = "1rvl06ha40dzd6s9aa4sylmksh4xb9dqaxq462lffv1fdk342pda";
|
||||||
|
};
|
||||||
|
patches = [ ./fsbl.patch ];
|
||||||
|
nativeBuildInputs = [
|
||||||
|
pkgs.gnumake
|
||||||
|
gnutoolchain.binutils
|
||||||
|
gnutoolchain.gcc
|
||||||
|
];
|
||||||
|
patchPhase = ''
|
||||||
|
patch -p1 -i ${./fsbl.patch}
|
||||||
|
patchShebangs lib/sw_apps/zynq_fsbl/misc/copy_bsp.sh
|
||||||
|
echo 'SEARCH_DIR("${gnutoolchain.newlib}/arm-none-eabi/lib");' >> lib/sw_apps/zynq_fsbl/src/lscript.ld
|
||||||
|
'';
|
||||||
|
buildPhase = ''
|
||||||
|
cd lib/sw_apps/zynq_fsbl/src
|
||||||
|
make BOARD=${board} "CFLAGS=-DFSBL_DEBUG_INFO -g"
|
||||||
|
'';
|
||||||
|
installPhase = ''
|
||||||
|
mkdir $out
|
||||||
|
cp fsbl.elf $out
|
||||||
|
'';
|
||||||
|
doCheck = false;
|
||||||
|
dontFixup = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
u-boot = { board ? "zc706" }: pkgs.pkgsCross.armv7l-hf-multiplatform.buildUBoot {
|
||||||
|
defconfig = "xilinx_zynq_virt_defconfig";
|
||||||
|
preConfigure = ''
|
||||||
|
export DEVICE_TREE=zynq-${board}
|
||||||
|
'';
|
||||||
|
extraConfig = ''
|
||||||
|
CONFIG_AUTOBOOT=y
|
||||||
|
CONFIG_BOOTCOMMAND="${builtins.replaceStrings [ "\n" ] [ "; " ] ''
|
||||||
|
setenv bootargs 'root=/dev/mmcblk0p2 console=ttyPS0,115200n8 systemConfig=${builtins.unsafeDiscardStringContext not-os-cfg.build.toplevel}'
|
||||||
|
fatload mmc 0 0x6400000 uImage
|
||||||
|
fatload mmc 0 0x8000000 devicetree.dtb
|
||||||
|
fatload mmc 0 0xA400000 uRamdisk.image.gz
|
||||||
|
bootm 0x6400000 0xA400000 0x8000000
|
||||||
|
''}"
|
||||||
|
CONFIG_BOOTDELAY=0
|
||||||
|
CONFIG_USE_BOOTCOMMAND=y
|
||||||
|
'';
|
||||||
|
extraMeta.platforms = [ "armv7l-linux" ];
|
||||||
|
filesToInstall = [ "u-boot.elf" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
bootimage = { board ? "zc706" }: pkgs.runCommand "${board}-bootimage"
|
||||||
|
{
|
||||||
|
buildInputs = [ mkbootimage ];
|
||||||
|
}
|
||||||
|
''
|
||||||
|
bifdir=`mktemp -d`
|
||||||
|
cd $bifdir
|
||||||
|
ln -s ${fsbl { inherit board; }}/fsbl.elf fsbl.elf
|
||||||
|
ln -s ${u-boot { inherit board; }}/u-boot.elf u-boot.elf
|
||||||
|
cat > boot.bif << EOF
|
||||||
|
the_ROM_image:
|
||||||
|
{
|
||||||
|
[bootloader]fsbl.elf
|
||||||
|
u-boot.elf
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
mkdir $out $out/nix-support
|
||||||
|
mkbootimage boot.bif $out/boot.bin
|
||||||
|
echo file binary-dist $out/boot.bin >> $out/nix-support/hydra-build-products
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Pinned qemu version due to networking errors in recent version 8.2.0
|
||||||
|
qemu = pkgs.qemu.overrideAttrs (oldAttrs: rec {
|
||||||
|
version = "8.1.3";
|
||||||
|
src = pkgs.fetchurl {
|
||||||
|
url = "https://download.qemu.org/qemu-${version}.tar.xz";
|
||||||
|
hash = "sha256-Q8wXaAQQVYb3T5A5jzTp+FeH3/QA07ZA2B93efviZbs=";
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
not-os-configured = (import patched-not-os {
|
||||||
inherit nixpkgs;
|
inherit nixpkgs;
|
||||||
extraModules = [
|
extraModules = [
|
||||||
"${patched-not-os}/zynq_image.nix"
|
"${patched-not-os}/zynq_image.nix"
|
||||||
] ++ pkgs.lib.optionals (board == "fast-servo") [
|
];
|
||||||
({ config, pkgs, lib, ... }: {
|
|
||||||
environment.systemPackages = [
|
|
||||||
linien-server
|
|
||||||
(pkgs.python3.withPackages(ps: [ pyfastservo ]))
|
|
||||||
];
|
|
||||||
boot.postBootCommands = lib.mkAfter ''
|
|
||||||
|
|
||||||
# Program the FPGA
|
|
||||||
set +x
|
|
||||||
echo "Loading bitstream into SRAM..."
|
|
||||||
echo 0 > /sys/class/fpga_manager/fpga0/flags
|
|
||||||
mkdir -p /lib/firmware
|
|
||||||
cp ${fast-servo-gateware}/gateware.bin /lib/firmware/
|
|
||||||
echo gateware.bin > /sys/class/fpga_manager/fpga0/firmware
|
|
||||||
|
|
||||||
# Run device init scripts
|
|
||||||
echo "Initializing clock generator, ADC, and DAC..."
|
|
||||||
python3 -m pyfastservo.initialize
|
|
||||||
'';
|
|
||||||
})];
|
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
inherit crossSystem;
|
crossSystem.system = "armv7l-linux";
|
||||||
});
|
});
|
||||||
|
|
||||||
not-os-build = not-os-configured.config.system.build;
|
not-os-qemu = { board ? "zc706" }: let
|
||||||
|
qemuScript = ''
|
||||||
|
#!/bin/bash
|
||||||
|
export PATH=${qemu}/bin:$PATH
|
||||||
|
IMGDIR=$(mktemp -d /tmp/not-os-qemu-XXXXXX)
|
||||||
|
BASE=$(realpath $(dirname $0))
|
||||||
|
qemu-img create -F raw -f qcow2 -b $BASE/sd-image.img $IMGDIR/sd-overlay.qcow2 512M
|
||||||
|
|
||||||
fsbl = pkgs.stdenv.mkDerivation {
|
# Some command arguments are based from samples in Xilinx QEMU User Documentation
|
||||||
name = "${board}-fsbl";
|
# See: https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/821854273/Running+Bare+Metal+Applications+on+QEMU
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "Xilinx";
|
|
||||||
repo = "embeddedsw";
|
|
||||||
rev = "xilinx_v2022.2";
|
|
||||||
sha256 = "sha256-UDz9KK/Hw3qM1BAeKif30rE8Bi6C2uvuZlvyvtJCMfw=";
|
|
||||||
};
|
|
||||||
nativeBuildInputs = [
|
|
||||||
pkgs.pkgsCross.zynq-baremetal.buildPackages.binutils
|
|
||||||
pkgs.pkgsCross.zynq-baremetal.buildPackages.gcc
|
|
||||||
];
|
|
||||||
postUnpack = ''
|
|
||||||
mkdir -p $sourceRoot/lib/sw_apps/zynq_fsbl/misc/fast-servo
|
|
||||||
cp $sourceRoot/lib/sw_apps/zynq_fsbl/misc/zc706/* $sourceRoot/lib/sw_apps/zynq_fsbl/misc/fast-servo
|
|
||||||
cp ${fsbl-support}/* $sourceRoot/lib/sw_apps/zynq_fsbl/misc/fast-servo
|
|
||||||
'';
|
|
||||||
patches = [] ++ pkgs.lib.optional (board == "fast-servo") ./fast-servo/fsbl.patch;
|
|
||||||
postPatch = ''
|
|
||||||
patchShebangs lib/sw_apps/zynq_fsbl/misc/copy_bsp.sh
|
|
||||||
|
|
||||||
for x in lib/sw_apps/zynq_fsbl/src/Makefile lib/sw_apps/zynq_fsbl/misc/copy_bsp.sh lib/bsp/standalone/src/arm/cortexa9/gcc/Makefile; do
|
qemu-system-arm \
|
||||||
substituteInPlace $x \
|
-M xilinx-zynq-a9 \
|
||||||
--replace "arm-none-eabi-" "arm-none-eabihf-"
|
-serial /dev/null \
|
||||||
done
|
-serial stdio \
|
||||||
'';
|
-display none \
|
||||||
buildPhase = ''
|
-dtb $BASE/devicetree.dtb \
|
||||||
cd lib/sw_apps/zynq_fsbl/src
|
-kernel $BASE/uImage \
|
||||||
make BOARD=${board} "CFLAGS=-DFSBL_DEBUG_INFO -g"
|
-initrd $BASE/uRamdisk.image.gz \
|
||||||
'';
|
-drive file=$IMGDIR/sd-overlay.qcow2,if=sd,format=qcow2 \
|
||||||
installPhase = ''
|
-append "root=/dev/mmcblk0p2 console=ttyPS0,115200n8 systemConfig=${builtins.unsafeDiscardStringContext not-os-cfg.build.toplevel}";
|
||||||
mkdir $out
|
|
||||||
cp fsbl.elf $out
|
rm -rf $IMGDIR
|
||||||
'';
|
'';
|
||||||
doCheck = false;
|
in pkgs.runCommand "not-os-qemu" {
|
||||||
dontFixup = true;
|
inherit qemuScript;
|
||||||
|
passAsFile = [ "qemuScript" ];
|
||||||
|
preferLocalBuild = true;
|
||||||
|
}
|
||||||
|
''
|
||||||
|
mkdir $out
|
||||||
|
cd $out
|
||||||
|
cp -s ${not-os-cfg.build.kernel}/uImage .
|
||||||
|
cp -s ${not-os-cfg.build.uRamdisk}/initrd uRamdisk.image.gz
|
||||||
|
cp -s ${not-os-cfg.build.kernel}/dtbs/zynq-zc706.dtb devicetree.dtb
|
||||||
|
cp -s ${sd-image { inherit board; }}/sd-image/sd-image.img .
|
||||||
|
ln -sv ${not-os-cfg.build.toplevel} toplevel
|
||||||
|
cp $qemuScriptPath qemu-script
|
||||||
|
chmod +x qemu-script
|
||||||
|
patchShebangs qemu-script
|
||||||
|
'';
|
||||||
|
|
||||||
|
sd-image = { board ? "zc706" }: let
|
||||||
|
rootfsImage = pkgs.callPackage (pkgs.path + "/nixos/lib/make-ext4-fs.nix") {
|
||||||
|
storePaths = [ not-os-cfg.build.toplevel ];
|
||||||
|
volumeLabel = "ROOT";
|
||||||
};
|
};
|
||||||
|
# Current firmware (kernel, bootimage, etc..) takes ~18MB
|
||||||
|
firmwareSize = 30;
|
||||||
|
firmwarePartitionOffset = 8;
|
||||||
|
in pkgs.stdenv.mkDerivation {
|
||||||
|
name = "sd-image";
|
||||||
|
nativeBuildInputs = with pkgs; [ dosfstools mtools libfaketime util-linux parted ];
|
||||||
|
buildCommand = ''
|
||||||
|
mkdir -p $out/nix-support $out/sd-image
|
||||||
|
export img=$out/sd-image/sd-image.img
|
||||||
|
|
||||||
u-boot = (pkgs-armv7l.buildUBoot {
|
echo "${pkgs.stdenv.buildPlatform.system}" > $out/nix-support/system
|
||||||
name = "${board}-u-boot";
|
echo "file sd-image $img" >> $out/nix-support/hydra-build-products
|
||||||
defconfig = "xilinx_zynq_virt_defconfig";
|
|
||||||
patches = [] ++ pkgs.lib.optional (board == "fast-servo") ./fast-servo/u-boot.patch;
|
|
||||||
preConfigure = ''
|
|
||||||
export DEVICE_TREE=zynq-${board}
|
|
||||||
'';
|
|
||||||
extraConfig = ''
|
|
||||||
CONFIG_SYS_PROMPT="${board}-boot> "
|
|
||||||
CONFIG_AUTOBOOT=y
|
|
||||||
CONFIG_BOOTCOMMAND="${builtins.replaceStrings [ "\n" ] [ "; " ] ''
|
|
||||||
setenv bootargs 'root=/dev/mmcblk0p2 console=ttyPS0,115200n8 systemConfig=${builtins.unsafeDiscardStringContext not-os-build.toplevel}'
|
|
||||||
fatload mmc 0 0x6400000 uImage
|
|
||||||
fatload mmc 0 0x8000000 ${board}.dtb
|
|
||||||
fatload mmc 0 0xA400000 uRamdisk.image.gz
|
|
||||||
bootm 0x6400000 0xA400000 0x8000000
|
|
||||||
''}"
|
|
||||||
CONFIG_BOOTDELAY=0
|
|
||||||
CONFIG_USE_BOOTCOMMAND=y
|
|
||||||
'';
|
|
||||||
extraMeta.platforms = [ "armv7l-linux" ];
|
|
||||||
filesToInstall = [ "u-boot.elf" ];
|
|
||||||
}).overrideAttrs (oldAttrs: {
|
|
||||||
postUnpack = ''
|
|
||||||
cp ${fast-servo/fast-servo.dts} $sourceRoot/arch/arm/dts/zynq-fast-servo.dts
|
|
||||||
'';
|
|
||||||
postInstall = ''
|
|
||||||
mkdir -p $out/dts
|
|
||||||
cp arch/arm/dts/zynq-fast-servo.dts $out/dts
|
|
||||||
cp arch/arm/dts/zynq-zc706.dts $out/dts
|
|
||||||
cp arch/arm/dts/zynq-7000.dtsi $out/dts
|
|
||||||
'';
|
|
||||||
});
|
|
||||||
|
|
||||||
bootimage = pkgs.runCommand "${board}-bootimage"
|
gap=${toString firmwarePartitionOffset}
|
||||||
{
|
|
||||||
buildInputs = [ mkbootimage ];
|
rootSizeBlocks=$(du -B 512 --apparent-size ${rootfsImage} | awk '{ print $1 }')
|
||||||
}
|
firmwareSizeBlocks=$((${toString firmwareSize} * 1024 * 1024 / 512))
|
||||||
''
|
imageSize=$((rootSizeBlocks * 512 + firmwareSizeBlocks * 512 + gap * 1024 * 1024))
|
||||||
bifdir=`mktemp -d`
|
truncate -s $imageSize $img
|
||||||
cd $bifdir
|
|
||||||
ln -s ${fsbl}/fsbl.elf fsbl.elf
|
fat32Start="$((gap))MB"
|
||||||
ln -s ${u-boot}/u-boot.elf u-boot.elf
|
fat32End="$((gap + ${toString firmwareSize}))MB"
|
||||||
cat > boot.bif << EOF
|
|
||||||
the_ROM_image:
|
parted $img mklabel msdos
|
||||||
{
|
parted $img mkpart primary fat32 $fat32Start $fat32End
|
||||||
[bootloader]fsbl.elf
|
parted $img mkpart primary ext4 $fat32End 100%
|
||||||
u-boot.elf
|
parted $img set 1 boot on
|
||||||
}
|
|
||||||
EOF
|
eval $(partx $img -o START,SECTORS --nr 2 --pairs)
|
||||||
mkdir $out $out/nix-support
|
dd conv=notrunc if=${rootfsImage} of=$img seek=$START count=$SECTORS
|
||||||
mkbootimage boot.bif $out/boot.bin
|
|
||||||
echo file binary-dist $out/boot.bin >> $out/nix-support/hydra-build-products
|
eval $(partx $img -o START,SECTORS --nr 1 --pairs)
|
||||||
|
truncate -s $((SECTORS * 512)) firmware_part.img
|
||||||
|
faketime "1970-01-01 00:00:00" mkfs.vfat -n BOOT firmware_part.img
|
||||||
|
|
||||||
|
mkdir firmware
|
||||||
|
cp ${bootimage { inherit board; }}/boot.bin firmware/
|
||||||
|
cp ${not-os-cfg.build.kernel}/uImage firmware/
|
||||||
|
cp ${not-os-cfg.build.uRamdisk}/initrd firmware/uRamdisk.image.gz
|
||||||
|
cp ${not-os-cfg.build.kernel}/dtbs/zynq-zc706.dtb firmware/devicetree.dtb
|
||||||
|
|
||||||
|
(cd firmware; mcopy -psvm -i ../firmware_part.img ./* ::)
|
||||||
|
dd conv=notrunc if=firmware_part.img of=$img seek=$START count=$SECTORS
|
||||||
'';
|
'';
|
||||||
|
};
|
||||||
dtb = pkgs.runCommand "${board}-dtb"
|
|
||||||
{
|
|
||||||
buildInputs = [ pkgs.gcc pkgs.dtc ];
|
|
||||||
}
|
|
||||||
''
|
|
||||||
mkdir -p $out
|
|
||||||
cp ${u-boot}/dts/zynq-${board}.dts .
|
|
||||||
|
|
||||||
if [ ${board} == "zc706" ]; then
|
|
||||||
mv zynq-${board}.dts zynq-${board}-top.dts
|
|
||||||
cp ${u-boot}/dts/zynq-7000.dtsi .
|
|
||||||
gcc -E -nostdinc -undef -D__DTS__ -x assembler-with-cpp -o zynq-${board}.dts zynq-${board}-top.dts
|
|
||||||
fi
|
|
||||||
|
|
||||||
dtc -I dts -O dtb -o ${board}.dtb zynq-${board}.dts
|
|
||||||
cp ${board}.dtb $out
|
|
||||||
'';
|
|
||||||
|
|
||||||
sd-image = let
|
|
||||||
rootfsImage = pkgs.callPackage (pkgs.path + "/nixos/lib/make-ext4-fs.nix") {
|
|
||||||
storePaths = [ not-os-build.toplevel ];
|
|
||||||
volumeLabel = "ROOT";
|
|
||||||
};
|
|
||||||
# Current firmware (kernel, bootimage, etc..) takes ~18MB
|
|
||||||
firmwareSize = 30;
|
|
||||||
firmwarePartitionOffset = 8;
|
|
||||||
in pkgs.stdenv.mkDerivation {
|
|
||||||
name = "${board}-sd-image";
|
|
||||||
nativeBuildInputs = with pkgs; [ dosfstools mtools libfaketime util-linux parted ];
|
|
||||||
buildCommand = ''
|
|
||||||
mkdir -p $out/nix-support $out/sd-image
|
|
||||||
export img=$out/sd-image/sd-image.img
|
|
||||||
|
|
||||||
echo "${pkgs.stdenv.buildPlatform.system}" > $out/nix-support/system
|
|
||||||
echo "file sd-image $img" >> $out/nix-support/hydra-build-products
|
|
||||||
|
|
||||||
gap=${toString firmwarePartitionOffset}
|
|
||||||
|
|
||||||
rootSizeBlocks=$(du -B 512 --apparent-size ${rootfsImage} | awk '{ print $1 }')
|
|
||||||
firmwareSizeBlocks=$((${toString firmwareSize} * 1024 * 1024 / 512))
|
|
||||||
imageSize=$((rootSizeBlocks * 512 + firmwareSizeBlocks * 512 + gap * 1024 * 1024))
|
|
||||||
truncate -s $imageSize $img
|
|
||||||
|
|
||||||
fat32Start="$((gap))MB"
|
|
||||||
fat32End="$((gap + ${toString firmwareSize}))MB"
|
|
||||||
|
|
||||||
parted $img mklabel msdos
|
|
||||||
parted $img mkpart primary fat32 $fat32Start $fat32End
|
|
||||||
parted $img mkpart primary ext4 $fat32End 100%
|
|
||||||
parted $img set 1 boot on
|
|
||||||
|
|
||||||
eval $(partx $img -o START,SECTORS --nr 2 --pairs)
|
|
||||||
dd conv=notrunc if=${rootfsImage} of=$img seek=$START count=$SECTORS
|
|
||||||
|
|
||||||
eval $(partx $img -o START,SECTORS --nr 1 --pairs)
|
|
||||||
truncate -s $((SECTORS * 512)) firmware_part.img
|
|
||||||
faketime "1970-01-01 00:00:00" mkfs.vfat -n BOOT firmware_part.img
|
|
||||||
|
|
||||||
mkdir firmware
|
|
||||||
cp ${bootimage}/boot.bin firmware/
|
|
||||||
cp ${dtb}/${board}.dtb firmware/
|
|
||||||
cp ${not-os-build.kernel}/uImage firmware/
|
|
||||||
cp ${not-os-build.uRamdisk}/initrd firmware/uRamdisk.image.gz
|
|
||||||
|
|
||||||
(cd firmware; mcopy -psvm -i ../firmware_part.img ./* ::)
|
|
||||||
dd conv=notrunc if=firmware_part.img of=$img seek=$START count=$SECTORS
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
not-os-qemu = let
|
|
||||||
qemuScript = ''
|
|
||||||
#!/bin/bash
|
|
||||||
export PATH=${pkgs.qemu}/bin:$PATH
|
|
||||||
IMGDIR=$(mktemp -d /tmp/not-os-qemu-XXXXXX)
|
|
||||||
BASE=$(realpath $(dirname $0))
|
|
||||||
|
|
||||||
qemu-img convert -O qcow2 -f raw -o preallocation=metadata $BASE/sd-image.img $IMGDIR/sd-sparse.qcow2
|
|
||||||
qemu-img create -F qcow2 -f qcow2 -b $IMGDIR/sd-sparse.qcow2 $IMGDIR/sd-overlay.qcow2 2G
|
|
||||||
|
|
||||||
# Some command arguments are based from samples in Xilinx QEMU User Documentation
|
|
||||||
# See: https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/821854273/Running+Bare+Metal+Applications+on+QEMU
|
|
||||||
|
|
||||||
qemu-system-arm \
|
|
||||||
-M xilinx-zynq-a9 \
|
|
||||||
-m 1024 \
|
|
||||||
$([ ${board} = "zc706" ] && echo "-serial /dev/null") -serial stdio \
|
|
||||||
-display none \
|
|
||||||
-kernel $BASE/u-boot.elf \
|
|
||||||
-sd $IMGDIR/sd-overlay.qcow2
|
|
||||||
|
|
||||||
rm -rf $IMGDIR
|
|
||||||
'';
|
|
||||||
in pkgs.runCommand "${board}-qemu" {
|
|
||||||
inherit qemuScript;
|
|
||||||
passAsFile = [ "qemuScript" ];
|
|
||||||
preferLocalBuild = true;
|
|
||||||
}
|
|
||||||
''
|
|
||||||
mkdir $out
|
|
||||||
cd $out
|
|
||||||
cp -s ${u-boot}/u-boot.elf .
|
|
||||||
cp -s ${sd-image}/sd-image/sd-image.img .
|
|
||||||
cp $qemuScriptPath qemu-script
|
|
||||||
chmod +x qemu-script
|
|
||||||
patchShebangs qemu-script
|
|
||||||
'';
|
|
||||||
in {
|
|
||||||
"${board}-fsbl" = fsbl;
|
|
||||||
"${board}-u-boot" = u-boot;
|
|
||||||
"${board}-bootimage" = bootimage;
|
|
||||||
"${board}-dtb" = dtb;
|
|
||||||
"${board}-sd-image" = sd-image;
|
|
||||||
"${board}-qemu" = not-os-qemu;
|
|
||||||
};
|
|
||||||
in rec {
|
in rec {
|
||||||
devShell.x86_64-linux = pkgs.mkShell {
|
|
||||||
name = "nix-servo-dev_shell";
|
|
||||||
buildInputs = with pkgs.python3Packages; [
|
|
||||||
matplotlib
|
|
||||||
] ++ [ linien-common linien-client linien-gui ];
|
|
||||||
};
|
|
||||||
|
|
||||||
packages.x86_64-linux = {
|
packages.x86_64-linux = {
|
||||||
inherit mkbootimage;
|
inherit mkbootimage;
|
||||||
inherit migen misoc vivado;
|
|
||||||
};
|
};
|
||||||
packages.armv7l-linux = {
|
packages.armv7l-linux = {
|
||||||
inherit fast-servo-gateware linien-server;
|
zc706-u-boot = u-boot { board = "zc706"; };
|
||||||
} //
|
zc706-fsbl = fsbl { board = "zc706"; };
|
||||||
(board-package-set { board = "zc706"; }) //
|
zc706-bootimage = bootimage { board = "zc706"; };
|
||||||
(board-package-set { board = "fast-servo"; });
|
zc706-qemu = not-os-qemu { board = "zc706"; };
|
||||||
|
zc706-sd-image = sd-image { board = "zc706"; };
|
||||||
|
zc706-not-os = not-os-cfg.build.zynq_image;
|
||||||
|
};
|
||||||
hydraJobs = packages.x86_64-linux // packages.armv7l-linux;
|
hydraJobs = packages.x86_64-linux // packages.armv7l-linux;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
31
fsbl.patch
Normal file
31
fsbl.patch
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
diff --git a/lib/sw_apps/zynq_fsbl/src/Makefile b/lib/sw_apps/zynq_fsbl/src/Makefile
|
||||||
|
index 0e3ccdf1c5..a5b02f386e 100644
|
||||||
|
--- a/lib/sw_apps/zynq_fsbl/src/Makefile
|
||||||
|
+++ b/lib/sw_apps/zynq_fsbl/src/Makefile
|
||||||
|
@@ -71,11 +71,14 @@ endif
|
||||||
|
all: $(EXEC)
|
||||||
|
|
||||||
|
$(EXEC): $(LIBS) $(OBJS) $(INCLUDES)
|
||||||
|
- cp $(BSP_DIR)/$(BOARD)/ps7_init.* .
|
||||||
|
$(LINKER) $(LD1FLAGS) -o $@ $(OBJS) $(LDFLAGS)
|
||||||
|
rm -rf $(OBJS)
|
||||||
|
-
|
||||||
|
-
|
||||||
|
+
|
||||||
|
+.PHONY: ps7_init
|
||||||
|
+
|
||||||
|
+ps7_init:
|
||||||
|
+ cp $(BSP_DIR)/$(BOARD)/ps7_init.* .
|
||||||
|
+
|
||||||
|
$(LIBS):
|
||||||
|
echo "Copying BSP files"
|
||||||
|
$(BSP_DIR)/copy_bsp.sh $(BOARD) $(CC)
|
||||||
|
@@ -86,7 +89,7 @@ $(LIBS):
|
||||||
|
make -C $(BSP_DIR) -k all "CC=armcc" "AR=armar" "C_FLAGS= -O2 -c" "EC_FLAGS=--debug --wchar32"; \
|
||||||
|
fi;
|
||||||
|
|
||||||
|
-%.o:%.c
|
||||||
|
+%.o:%.c ps7_init
|
||||||
|
$(CC) $(CC_FLAGS) $(CFLAGS) $(ECFLAGS) -c $< -o $@ $(INCLUDEPATH)
|
||||||
|
|
||||||
|
%.o:%.S
|
@ -1,14 +1,21 @@
|
|||||||
|
diff --git a/base.nix b/base.nix
|
||||||
|
index 7eaee32..be5a47c 100644
|
||||||
|
--- a/base.nix
|
||||||
|
+++ b/base.nix
|
||||||
|
@@ -95,7 +95,7 @@ with lib;
|
||||||
|
'';
|
||||||
|
bashrc.text = "export PATH=/run/current-system/sw/bin";
|
||||||
|
profile.text = "export PATH=/run/current-system/sw/bin";
|
||||||
|
- "resolv.conf".text = "nameserver 10.0.2.3";
|
||||||
|
+ "resolv.conf".text = "nameserver 192.168.1.1";
|
||||||
|
passwd.text = ''
|
||||||
|
root:x:0:0:System administrator:/root:/run/current-system/sw/bin/bash
|
||||||
|
sshd:x:498:65534:SSH privilege separation user:/var/empty:/run/current-system/sw/bin/nologin
|
||||||
diff --git a/configuration.nix b/configuration.nix
|
diff --git a/configuration.nix b/configuration.nix
|
||||||
index 010c487..2d08009 100644
|
index 010c487..37f6aaa 100644
|
||||||
--- a/configuration.nix
|
--- a/configuration.nix
|
||||||
+++ b/configuration.nix
|
+++ b/configuration.nix
|
||||||
@@ -1,4 +1,4 @@
|
@@ -7,8 +7,10 @@
|
||||||
-{ pkgs, ... }:
|
|
||||||
+{ pkgs, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [ ./qemu.nix ];
|
|
||||||
@@ -7,10 +7,16 @@
|
|
||||||
environment.etc = {
|
environment.etc = {
|
||||||
"ssh/authorized_keys.d/root" = {
|
"ssh/authorized_keys.d/root" = {
|
||||||
text = ''
|
text = ''
|
||||||
@ -18,25 +25,15 @@ index 010c487..2d08009 100644
|
|||||||
+ ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBNdIiLvP2hmDUFyyE0oLOIXrjrMdWWpBV9/gPR5m4AiARx4JkufIDZzmptdYQ5FhJORJ4lluPqp7dAmahoSwg4lv9Di0iNQpHMJvNGZLHYKM1H1FWCCFIEDJ8bD4SVfrDg== root
|
+ ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBNdIiLvP2hmDUFyyE0oLOIXrjrMdWWpBV9/gPR5m4AiARx4JkufIDZzmptdYQ5FhJORJ4lluPqp7dAmahoSwg4lv9Di0iNQpHMJvNGZLHYKM1H1FWCCFIEDJ8bD4SVfrDg== root
|
||||||
+ ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF/YybP+fQ0J+bNqM5Vgx5vDmVqVWsgUdF1moUxghv7d73GZAFaM6IFBdrXTAa33AwnWwDPMrTgP1V6SXBkb3ciJo/lD1urJGbydbSI5Ksq9d59wvOeANvyWYrQw6+eqTQ== sb
|
+ ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF/YybP+fQ0J+bNqM5Vgx5vDmVqVWsgUdF1moUxghv7d73GZAFaM6IFBdrXTAa33AwnWwDPMrTgP1V6SXBkb3ciJo/lD1urJGbydbSI5Ksq9d59wvOeANvyWYrQw6+eqTQ== sb
|
||||||
+ ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBFkmOCQ3BQh3qUjLtfdqyeBsx8rkk/QYlzB0TMrnfn6waLN6yKfPC3WVFv4zN5kNKb/OayvqDa+zfkKe85e/oIPQQKflF7GrCHdssz33DCnW90cz532E6iqG1pjeZjID2A== flo
|
+ ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBFkmOCQ3BQh3qUjLtfdqyeBsx8rkk/QYlzB0TMrnfn6waLN6yKfPC3WVFv4zN5kNKb/OayvqDa+zfkKe85e/oIPQQKflF7GrCHdssz33DCnW90cz532E6iqG1pjeZjID2A== flo
|
||||||
+ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICAranL376soiSJ0kxdYNrwElcaZPW1heLFjs8Y7n0jT linuswck
|
|
||||||
'';
|
'';
|
||||||
mode = "0444";
|
mode = "0444";
|
||||||
};
|
};
|
||||||
+ "resolv.conf".text = lib.mkForce ''
|
|
||||||
+ nameserver 192.168.1.1
|
|
||||||
+ '';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
diff --git a/runit.nix b/runit.nix
|
diff --git a/runit.nix b/runit.nix
|
||||||
index d7b0bf3..14dd437 100644
|
index d7b0bf3..67cff43 100644
|
||||||
--- a/runit.nix
|
--- a/runit.nix
|
||||||
+++ b/runit.nix
|
+++ b/runit.nix
|
||||||
@@ -4,11 +4,11 @@ let
|
@@ -7,8 +7,8 @@ let
|
||||||
sshd_config = pkgs.writeText "sshd_config" ''
|
Port 22
|
||||||
HostKey /etc/ssh/ssh_host_rsa_key
|
|
||||||
HostKey /etc/ssh/ssh_host_ed25519_key
|
|
||||||
- Port 22
|
|
||||||
+ Port 3030
|
|
||||||
PidFile /run/sshd.pid
|
PidFile /run/sshd.pid
|
||||||
Protocol 2
|
Protocol 2
|
||||||
- PermitRootLogin yes
|
- PermitRootLogin yes
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/system-path.nix b/system-path.nix
|
|
||||||
index 490197d..93e940a 100644
|
|
||||||
--- a/system-path.nix
|
|
||||||
+++ b/system-path.nix
|
|
||||||
@@ -6,7 +6,7 @@
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
- requiredPackages = with pkgs; [ utillinux coreutils iproute iputils procps bashInteractive runit ];
|
|
||||||
+ requiredPackages = with pkgs; [ utillinux coreutils iproute2 iputils procps bashInteractive runit ];
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options = {
|
|
@ -1,28 +0,0 @@
|
|||||||
diff --git a/runit.nix b/runit.nix
|
|
||||||
index d7b0bf3..64f99f2 100644
|
|
||||||
--- a/runit.nix
|
|
||||||
+++ b/runit.nix
|
|
||||||
@@ -57,6 +57,23 @@ in
|
|
||||||
'';
|
|
||||||
"runit/3".source = pkgs.writeScript "3" ''
|
|
||||||
#!${pkgs.runtimeShell}
|
|
||||||
+ echo Waiting for services to stop...
|
|
||||||
+ sv force-stop /etc/service/*
|
|
||||||
+ sv exit /etc/service/*
|
|
||||||
+
|
|
||||||
+ echo Sending TERM signal to processes...
|
|
||||||
+ pkill --inverse -s0,1 -TERM
|
|
||||||
+ sleep 1
|
|
||||||
+ echo Sending KILL signal to processes...
|
|
||||||
+ pkill --inverse -s0,1 -KILL
|
|
||||||
+
|
|
||||||
+ echo Unmounting filesystems, disabling swap...
|
|
||||||
+ swapoff -a
|
|
||||||
+ umount -r -a -t nosysfs,noproc,nodevtmpfs,notmpfs
|
|
||||||
+ echo Remounting rootfs read-only...
|
|
||||||
+ mount -o remount,ro /
|
|
||||||
+
|
|
||||||
+ sync
|
|
||||||
echo and down we go
|
|
||||||
'';
|
|
||||||
"service/sshd/run".source = pkgs.writeScript "sshd_run" ''
|
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
diff --git a/base.nix b/base.nix
|
diff --git a/base.nix b/base.nix
|
||||||
index 7eaee32..9aa338e 100644
|
index 7eaee32..f767d5e 100644
|
||||||
--- a/base.nix
|
--- a/base.nix
|
||||||
+++ b/base.nix
|
+++ b/base.nix
|
||||||
@@ -27,6 +27,11 @@ with lib;
|
@@ -27,6 +27,11 @@ with lib;
|
||||||
@ -14,67 +14,11 @@ index 7eaee32..9aa338e 100644
|
|||||||
not-os.simpleStaticIp = mkOption {
|
not-os.simpleStaticIp = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
@@ -84,17 +89,25 @@ with lib;
|
|
||||||
};
|
|
||||||
environment.etc = {
|
|
||||||
"nix/nix.conf".source = pkgs.runCommand "nix.conf" {} ''
|
|
||||||
- extraPaths=$(for i in $(cat ${pkgs.writeReferencesToFile pkgs.runtimeShell}); do if test -d $i; then echo $i; fi; done)
|
|
||||||
+ extraPaths=$(for i in $(cat ${pkgs.writeClosure [ pkgs.bash ]}); do if test -d $i; then echo $i; fi; done)
|
|
||||||
cat > $out << EOF
|
|
||||||
- build-use-sandbox = true
|
|
||||||
+ auto-optimise-store = true
|
|
||||||
build-users-group = nixbld
|
|
||||||
- build-sandbox-paths = /bin/sh=${pkgs.runtimeShell} $(echo $extraPaths)
|
|
||||||
- build-max-jobs = 1
|
|
||||||
- build-cores = 4
|
|
||||||
+ cores = 0
|
|
||||||
+ extra-sandbox-paths = /bin/sh=${pkgs.runtimeShell} $(echo $extraPaths)
|
|
||||||
+ max-jobs = auto
|
|
||||||
+ sandbox = true
|
|
||||||
+ trusted-users = root
|
|
||||||
EOF
|
|
||||||
'';
|
|
||||||
+ "ssl/certs/ca-certificates.crt".source = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
|
|
||||||
+ "ssl/certs/ca-bundle.crt".source = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
|
|
||||||
bashrc.text = "export PATH=/run/current-system/sw/bin";
|
|
||||||
- profile.text = "export PATH=/run/current-system/sw/bin";
|
|
||||||
+ profile.text = ''
|
|
||||||
+ export PATH=/run/current-system/sw/bin
|
|
||||||
+ export EDITOR=nano
|
|
||||||
+ export NIX_PATH="nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels"
|
|
||||||
+ '';
|
|
||||||
"resolv.conf".text = "nameserver 10.0.2.3";
|
|
||||||
passwd.text = ''
|
|
||||||
root:x:0:0:System administrator:/root:/run/current-system/sw/bin/bash
|
|
||||||
diff --git a/runit.nix b/runit.nix
|
|
||||||
index d7b0bf3..70353a1 100644
|
|
||||||
--- a/runit.nix
|
|
||||||
+++ b/runit.nix
|
|
||||||
@@ -65,7 +65,6 @@ in
|
|
||||||
'';
|
|
||||||
"service/nix/run".source = pkgs.writeScript "nix" ''
|
|
||||||
#!${pkgs.runtimeShell}
|
|
||||||
- nix-store --load-db < /nix/store/nix-path-registration
|
|
||||||
nix-daemon
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
diff --git a/stage-1.nix b/stage-1.nix
|
diff --git a/stage-1.nix b/stage-1.nix
|
||||||
index 331fecd..aa5148e 100644
|
index 331fecd..85fda30 100644
|
||||||
--- a/stage-1.nix
|
--- a/stage-1.nix
|
||||||
+++ b/stage-1.nix
|
+++ b/stage-1.nix
|
||||||
@@ -117,11 +117,6 @@ let
|
@@ -164,7 +164,9 @@ let
|
||||||
plymouth --show-splash
|
|
||||||
''}
|
|
||||||
|
|
||||||
-
|
|
||||||
- for x in ${lib.concatStringsSep " " config.boot.initrd.kernelModules}; do
|
|
||||||
- modprobe $x
|
|
||||||
- done
|
|
||||||
-
|
|
||||||
root=/dev/vda
|
|
||||||
realroot=tmpfs
|
|
||||||
for o in $(cat /proc/cmdline); do
|
|
||||||
@@ -164,7 +159,9 @@ let
|
|
||||||
mkdir -p /mnt/nix/store/
|
mkdir -p /mnt/nix/store/
|
||||||
|
|
||||||
|
|
||||||
@ -85,7 +29,7 @@ index 331fecd..aa5148e 100644
|
|||||||
# make the store writeable
|
# make the store writeable
|
||||||
mkdir -p /mnt/nix/.ro-store /mnt/nix/.overlay-store /mnt/nix/store
|
mkdir -p /mnt/nix/.ro-store /mnt/nix/.overlay-store /mnt/nix/store
|
||||||
mount $root /mnt/nix/.ro-store -t squashfs
|
mount $root /mnt/nix/.ro-store -t squashfs
|
||||||
@@ -190,6 +187,11 @@ let
|
@@ -190,6 +192,11 @@ let
|
||||||
initialRamdisk = pkgs.makeInitrd {
|
initialRamdisk = pkgs.makeInitrd {
|
||||||
contents = [ { object = bootStage1; symlink = "/init"; } ];
|
contents = [ { object = bootStage1; symlink = "/init"; } ];
|
||||||
};
|
};
|
||||||
@ -97,7 +41,7 @@ index 331fecd..aa5148e 100644
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
@@ -205,6 +207,7 @@ in
|
@@ -205,6 +212,7 @@ in
|
||||||
config = {
|
config = {
|
||||||
system.build.bootStage1 = bootStage1;
|
system.build.bootStage1 = bootStage1;
|
||||||
system.build.initialRamdisk = initialRamdisk;
|
system.build.initialRamdisk = initialRamdisk;
|
||||||
@ -152,10 +96,10 @@ index c61f9d6..fbdf0fd 100644
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
diff --git a/zynq_image.nix b/zynq_image.nix
|
diff --git a/zynq_image.nix b/zynq_image.nix
|
||||||
index 3fa23ab..069fe89 100644
|
index 3fa23ab..9ea1df3 100644
|
||||||
--- a/zynq_image.nix
|
--- a/zynq_image.nix
|
||||||
+++ b/zynq_image.nix
|
+++ b/zynq_image.nix
|
||||||
@@ -1,66 +1,89 @@
|
@@ -1,66 +1,96 @@
|
||||||
-{ config, pkgs, ... }:
|
-{ config, pkgs, ... }:
|
||||||
+{ lib, config, pkgs, ... }:
|
+{ lib, config, pkgs, ... }:
|
||||||
|
|
||||||
@ -164,7 +108,22 @@ index 3fa23ab..069fe89 100644
|
|||||||
- # dont use overlays for the qemu, it causes a lot of wasted time on recompiles
|
- # dont use overlays for the qemu, it causes a lot of wasted time on recompiles
|
||||||
- x86pkgs = import pkgs.path { system = "x86_64-linux"; };
|
- x86pkgs = import pkgs.path { system = "x86_64-linux"; };
|
||||||
- customKernel = pkgs.linux.override {
|
- customKernel = pkgs.linux.override {
|
||||||
+ customKernel = (pkgs.linux_6_6.override {
|
+ crosspkgs = import pkgs.path {
|
||||||
|
+ system = "x86_64-linux";
|
||||||
|
+ crossSystem = {
|
||||||
|
+ system = "armv7l-linux";
|
||||||
|
+ linux-kernel = {
|
||||||
|
+ name = "zynq";
|
||||||
|
+ baseConfig = "multi_v7_defconfig";
|
||||||
|
+ target = "uImage";
|
||||||
|
+ installTarget = "uImage";
|
||||||
|
+ autoModules = false;
|
||||||
|
+ DTB = true;
|
||||||
|
+ makeFlags = [ "LOADADDR=0x8000" ];
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ customKernel = (crosspkgs.linux.override {
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
OVERLAY_FS y
|
OVERLAY_FS y
|
||||||
+ MEDIA_SUPPORT n
|
+ MEDIA_SUPPORT n
|
||||||
@ -173,23 +132,16 @@ index 3fa23ab..069fe89 100644
|
|||||||
+ SOUND n
|
+ SOUND n
|
||||||
+ SQUASHFS n
|
+ SQUASHFS n
|
||||||
+ BACKLIGHT_CLASS_DEVICE n
|
+ BACKLIGHT_CLASS_DEVICE n
|
||||||
+ FPGA y
|
|
||||||
+ FPGA_BRIDGE y
|
|
||||||
+ FPGA_REGION y
|
|
||||||
+ OF_FPGA_REGION y
|
|
||||||
+ FPGA_MGR_ZYNQ_FPGA y
|
|
||||||
+ OF_OVERLAY y
|
|
||||||
'';
|
'';
|
||||||
- };
|
- };
|
||||||
|
- customKernelPackages = pkgs.linuxPackagesFor customKernel;
|
||||||
+ }).overrideAttrs (oa: {
|
+ }).overrideAttrs (oa: {
|
||||||
+ postInstall = ''
|
+ postInstall = ''
|
||||||
+ if [ -e arch/arm/boot/uImage ]; then
|
+ cp arch/arm/boot/uImage $out
|
||||||
+ cp arch/arm/boot/uImage $out
|
|
||||||
+ fi
|
|
||||||
+ ${oa.postInstall}
|
+ ${oa.postInstall}
|
||||||
+ '';
|
+ '';
|
||||||
+ });
|
+ });
|
||||||
customKernelPackages = pkgs.linuxPackagesFor customKernel;
|
+ customKernelPackages = crosspkgs.linuxPackagesFor customKernel;
|
||||||
in {
|
in {
|
||||||
imports = [ ./arm32-cross-fixes.nix ];
|
imports = [ ./arm32-cross-fixes.nix ];
|
||||||
boot.kernelPackages = customKernelPackages;
|
boot.kernelPackages = customKernelPackages;
|
||||||
@ -240,17 +192,17 @@ index 3fa23ab..069fe89 100644
|
|||||||
- chmod +x qemu-script
|
- chmod +x qemu-script
|
||||||
- patchShebangs qemu-script
|
- patchShebangs qemu-script
|
||||||
- ls -ltrh
|
- ls -ltrh
|
||||||
- '';
|
'';
|
||||||
- system.build.rpi_image_tar = pkgs.runCommand "dist.tar" {} ''
|
- system.build.rpi_image_tar = pkgs.runCommand "dist.tar" {} ''
|
||||||
- mkdir -p $out/nix-support
|
- mkdir -p $out/nix-support
|
||||||
- tar -cvf $out/dist.tar ${config.system.build.rpi_image}
|
- tar -cvf $out/dist.tar ${config.system.build.rpi_image}
|
||||||
- echo "file binary-dist $out/dist.tar" >> $out/nix-support/hydra-build-products
|
- echo "file binary-dist $out/dist.tar" >> $out/nix-support/hydra-build-products
|
||||||
'';
|
- '';
|
||||||
- environment.systemPackages = [ pkgs.strace ];
|
- environment.systemPackages = [ pkgs.strace ];
|
||||||
- environment.etc."service/getty/run".source = pkgs.writeShellScript "getty" ''
|
- environment.etc."service/getty/run".source = pkgs.writeShellScript "getty" ''
|
||||||
- agetty ttyPS0 115200
|
- agetty ttyPS0 115200
|
||||||
+ environment = {
|
+ environment = {
|
||||||
+ systemPackages = with pkgs; [ inetutils wget gnugrep nano vim ];
|
+ systemPackages = with pkgs; [ inetutils wget ];
|
||||||
+ etc = {
|
+ etc = {
|
||||||
+ "service/getty/run".source = pkgs.writeShellScript "getty" ''
|
+ "service/getty/run".source = pkgs.writeShellScript "getty" ''
|
||||||
+ hostname ${config.networking.hostName}
|
+ hostname ${config.networking.hostName}
|
Loading…
Reference in New Issue
Block a user