Compare commits

...

56 Commits

Author SHA1 Message Date
634e66e2be flake: update dependencies 2025-01-15 23:03:38 +08:00
4ac5d66a77 typo 2025-01-15 22:51:44 +08:00
30579dfc60 gui: Do not use OpenGL for pyqtgraph
- Fix Painter path exceeds +/-32767 pixels bug
- Plotting with OpenGL has worse performance
    - See pyqtgraph Issue #2227
2025-01-15 18:06:49 +08:00
a3eb78d39a gui: add afe gain combo boxes for gain selection 2025-01-15 15:44:00 +08:00
2618724aeb server: add afe ctrl regs to parameters 2025-01-15 15:43:38 +08:00
7d732c0b87 Increase CPU Freq 500MHz -> 666.667MHz(max) 2025-01-15 15:29:59 +08:00
a6665d0c06 Start linien-server as a service in boot stage 2025-01-14 17:14:42 +08:00
d6169c87e1 gui: Patch Vpp and Frequency back to 125MHz 2025-01-13 15:49:16 +08:00
92c990289e gateware: Fix timing violation 2025-01-13 13:14:43 +08:00
ef395bf81f Fix spi bus error at boot stage 2025-01-13 11:21:02 +08:00
fd125a506f gateware: sys freq 100MHz -> 125MHz 2025-01-13 11:20:48 +08:00
0ca6ac1354 gateware: use LTC2195 dco clk as PL only clock source 2025-01-13 11:17:42 +08:00
d9d44fa9e8 gateware: use si5340 to generate PL's rst 2025-01-13 11:17:42 +08:00
bec032ab75 gateware: Add sys_clk_double clk domain 2025-01-13 11:17:23 +08:00
7eb4cbb0aa gateware: Add pipeline to Demodulation
- Fix timing violations at 125MHz sys frequency
2025-01-13 11:17:14 +08:00
546725dff0 gateware: Add pipeline to fast_chain calculation
- Fix timing violations at 125MHz sys frequency
2025-01-13 11:17:14 +08:00
6f2ac2826f gateaware: Add pipeline to autolock
- Fix timing violation at 125MHz sys frequency
2025-01-13 11:17:14 +08:00
bd27e93a73 gateware: Revert IIR Coeff Width to 18bit
- Revert commit 25dd0db. Related Issue: #40.
- Fail to meet timing for IIR Filter's Multiply and Add operation as
    multiplication operation cannot be fitted inside a single DSP
    Slice (25b x 18b). Thus, multiple DSPs are needed for multiplication.
    This causes timing violation at 100MHz and 125MHz sys frequency.
2025-01-13 11:16:35 +08:00
67e7bf4af2 Add instructions for firmware development 2024-12-20 17:40:08 +08:00
b87fad5ed4 Add hardware specific patch to linien
- Correct MHz and Voltage Scaling
- Hide Analog Out related GUI Elements
- Change default amplitude and frequency values
2024-12-20 16:29:17 +08:00
372aac6a44 Reorganize flake.nix
- No functional change
2024-12-20 16:29:04 +08:00
e05f31b70c Disable OTA Update on client and gui 2024-12-20 16:28:53 +08:00
67cba47a3f Change ssh port from 22 to 3030 2024-12-18 14:02:36 +08:00
a87a0a224f Upgrade linien from v1.0.0 to v2.1.0
- Add linien GUI dev shell for fast servo platform
2024-12-18 12:43:12 +08:00
eb0d01d339 nixos 24.11 2024-12-17 16:41:29 +08:00
b631c1fa4a pid: add pipeline on error signal computation 2024-12-11 15:24:27 +08:00
bc5d24a69a Fix malformed pid_pipeline patch 2024-12-11 12:36:02 +08:00
0f15e0ef70 Add patches to fix timing errors in gateware 2024-12-11 11:01:15 +08:00
5816c070ef flake: update dependencies 2024-12-04 23:02:47 +08:00
322d61d436 iproute -> iproute2 2024-12-04 23:02:39 +08:00
3be72cd2dc update vivado 2024-12-04 22:14:08 +08:00
77643909ef pyfastservo: add note for dac output override 2024-11-15 15:42:25 +08:00
a5dc232be4 gateware: add cdc fifo for dac output value override csr 2024-11-15 15:42:25 +08:00
87059eef2b gateware: async fifo with depth of 2 is broken
- Changing depth to 4 has resolved cdc issue
2024-11-15 15:42:25 +08:00
8a40bb4f21 gateware: Add cdc fifo for adc and dac
- dco2d and sys clk use two different clock sources
2024-11-13 15:43:35 +08:00
bbe09de52c pyfastservo adc: Add helper fn for phase shifting the dac ddr clock 2024-11-08 16:37:29 +08:00
9f2e609b6e pyfastservo dac: Change debug MSG 2024-11-08 16:37:16 +08:00
6705b182d5 pyfastservo dac: power_down -> power_down_afe 2024-11-08 16:35:52 +08:00
51c8b755d2 pyfastservo dac: hard_reset -> soft_reset 2024-11-08 16:35:52 +08:00
5d55ab4c9c pyfastservo dac: reacquire clk relationship at init 2024-11-08 16:35:52 +08:00
560b28508c pyfastservo dac: turn off manual override by default 2024-11-08 16:35:52 +08:00
b1a9fa0ad4 pyfastservo adc: Set default afe gain to 10x 2024-11-08 16:35:52 +08:00
5343b3d45a pyfastservo adc: print 100 times to check test pattern 2024-11-08 16:35:52 +08:00
4940ee52cc pyfastservo adc: Add mmcm rst after ADC is rst 2024-11-08 16:35:52 +08:00
382e8467d9 pyfastservo adc: Fix find edge bug
- Fix: if frame changed at 31 tap delay, edge would not get detected
2024-11-08 16:35:52 +08:00
6cef418756 gateware: Add CSR Ctrl to PL's MMCM
- Generate 45 Degree Phase Shifted DDR Clock
- PLLE2_Base -> MMCM_ADV for ddr clock dynamic phase shift
- Add mmcm_rst, ddr_clk_ps, mmcm_locked status to CSR
- Generate dco2d rst signal from mmcm and connect to the related logic
2024-11-08 16:33:17 +08:00
e708696b5d add grep and vim 2024-10-31 19:06:59 +08:00
3cf9a721cf add linuswck ssh key 2024-10-31 14:54:14 +08:00
8b20379427 remove nixos armv7l unofficial binary cache 2024-08-22 14:14:51 +08:00
15a66c01fa dac: fix initialization order 2024-08-20 16:35:49 +08:00
2d75b4112e flake: update dependencies 2024-08-19 22:03:51 +08:00
ed816517cf si5340: implement paged register writes
Signed-off-by: Florian Agbuya <fa@m-labs.ph>
2024-07-31 16:44:39 +08:00
f5729d3bdb pyfastservo: update initialize script 2024-07-10 16:11:17 +08:00
e3b1525125 pyfastservo: fix adc init script and cleanup 2024-07-10 16:11:17 +08:00
b92d401f2b pyfastservo: fix dac init script and cleanup 2024-07-10 16:11:17 +08:00
eed43e3fe3 pyfastservo: transfer common functions to common 2024-07-10 16:11:17 +08:00
41 changed files with 1757 additions and 828 deletions

30
README.md Normal file
View File

@ -0,0 +1,30 @@
# 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. By default, linien-server starts up automatically. In case linien-server crashes, it will restart itself. Logs are stored in `/root/linien-server-log`. Here are some commands to interact with the linien-server service once you `ssh <fast servo ip address> -p 3030` into fast-servo.
| Description | Command |
|------------------------------------------------------|-----------------------------------------|
| Start the linien-server service | `linien-server start` |
| Stop the linien-server service | `linien-server stop` |
| Check if the linien-server service is running | `linien-server status` |
| Set the linien-server service to start at bootup | `linien-server enable` |
| Set the linien-server service not to start at bootup | `linien-server disable` |
4. 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.
5. Select the newly added device and click connect in the GUI to connect and start the GUI.

View File

@ -576,7 +576,7 @@
/ { / {
cpus { cpus {
cpu@0 { cpu@0 {
operating-points = <500000 1000000 250000 1000000>; operating-points = <666667 1000000 333334 1000000>;
}; };
}; };
}; };

View File

@ -25,23 +25,23 @@ unsigned long ps7_pll_init_data_3_0[] = {
// .. FINISH: SLCR SETTINGS // .. FINISH: SLCR SETTINGS
// .. START: PLL SLCR REGISTERS // .. START: PLL SLCR REGISTERS
// .. .. START: ARM PLL INIT // .. .. START: ARM PLL INIT
// .. .. PLL_RES = 0xc // .. .. PLL_RES = 0x2
// .. .. ==> 0XF8000110[7:4] = 0x0000000CU // .. .. ==> 0XF8000110[7:4] = 0x00000002U
// .. .. ==> MASK : 0x000000F0U VAL : 0x000000C0U // .. .. ==> MASK : 0x000000F0U VAL : 0x00000020U
// .. .. PLL_CP = 0x2 // .. .. PLL_CP = 0x2
// .. .. ==> 0XF8000110[11:8] = 0x00000002U // .. .. ==> 0XF8000110[11:8] = 0x00000002U
// .. .. ==> MASK : 0x00000F00U VAL : 0x00000200U // .. .. ==> MASK : 0x00000F00U VAL : 0x00000200U
// .. .. LOCK_CNT = 0x145 // .. .. LOCK_CNT = 0xfa
// .. .. ==> 0XF8000110[21:12] = 0x00000145U // .. .. ==> 0XF8000110[21:12] = 0x000000FAU
// .. .. ==> MASK : 0x003FF000U VAL : 0x00145000U // .. .. ==> MASK : 0x003FF000U VAL : 0x000FA000U
// .. .. // .. ..
EMIT_MASKWRITE(0XF8000110, 0x003FFFF0U ,0x001452C0U), EMIT_MASKWRITE(0XF8000110, 0x003FFFF0U ,0x000FA220U),
// .. .. .. START: UPDATE FB_DIV // .. .. .. START: UPDATE FB_DIV
// .. .. .. PLL_FDIV = 0x1e // .. .. .. PLL_FDIV = 0x28
// .. .. .. ==> 0XF8000100[18:12] = 0x0000001EU // .. .. .. ==> 0XF8000100[18:12] = 0x00000028U
// .. .. .. ==> MASK : 0x0007F000U VAL : 0x0001E000U // .. .. .. ==> MASK : 0x0007F000U VAL : 0x00028000U
// .. .. .. // .. .. ..
EMIT_MASKWRITE(0XF8000100, 0x0007F000U ,0x0001E000U), EMIT_MASKWRITE(0XF8000100, 0x0007F000U ,0x00028000U),
// .. .. .. FINISH: UPDATE FB_DIV // .. .. .. FINISH: UPDATE FB_DIV
// .. .. .. START: BY PASS PLL // .. .. .. START: BY PASS PLL
// .. .. .. PLL_BYPASS_FORCE = 1 // .. .. .. PLL_BYPASS_FORCE = 1
@ -273,9 +273,9 @@ unsigned long ps7_clock_init_data_3_0[] = {
// .. CLKACT = 0x1 // .. CLKACT = 0x1
// .. ==> 0XF8000140[0:0] = 0x00000001U // .. ==> 0XF8000140[0:0] = 0x00000001U
// .. ==> MASK : 0x00000001U VAL : 0x00000001U // .. ==> MASK : 0x00000001U VAL : 0x00000001U
// .. SRCSEL = 0x2 // .. SRCSEL = 0x0
// .. ==> 0XF8000140[6:4] = 0x00000002U // .. ==> 0XF8000140[6:4] = 0x00000000U
// .. ==> MASK : 0x00000070U VAL : 0x00000020U // .. ==> MASK : 0x00000070U VAL : 0x00000000U
// .. DIVISOR = 0x8 // .. DIVISOR = 0x8
// .. ==> 0XF8000140[13:8] = 0x00000008U // .. ==> 0XF8000140[13:8] = 0x00000008U
// .. ==> MASK : 0x00003F00U VAL : 0x00000800U // .. ==> MASK : 0x00003F00U VAL : 0x00000800U
@ -283,7 +283,7 @@ unsigned long ps7_clock_init_data_3_0[] = {
// .. ==> 0XF8000140[25:20] = 0x00000001U // .. ==> 0XF8000140[25:20] = 0x00000001U
// .. ==> MASK : 0x03F00000U VAL : 0x00100000U // .. ==> MASK : 0x03F00000U VAL : 0x00100000U
// .. // ..
EMIT_MASKWRITE(0XF8000140, 0x03F03F71U ,0x00100821U), EMIT_MASKWRITE(0XF8000140, 0x03F03F71U ,0x00100801U),
// .. CLKACT = 0x1 // .. CLKACT = 0x1
// .. ==> 0XF800014C[0:0] = 0x00000001U // .. ==> 0XF800014C[0:0] = 0x00000001U
// .. ==> MASK : 0x00000001U VAL : 0x00000001U // .. ==> MASK : 0x00000001U VAL : 0x00000001U
@ -4054,23 +4054,23 @@ unsigned long ps7_pll_init_data_2_0[] = {
// .. FINISH: SLCR SETTINGS // .. FINISH: SLCR SETTINGS
// .. START: PLL SLCR REGISTERS // .. START: PLL SLCR REGISTERS
// .. .. START: ARM PLL INIT // .. .. START: ARM PLL INIT
// .. .. PLL_RES = 0xc // .. .. PLL_RES = 0x2
// .. .. ==> 0XF8000110[7:4] = 0x0000000CU // .. .. ==> 0XF8000110[7:4] = 0x00000002U
// .. .. ==> MASK : 0x000000F0U VAL : 0x000000C0U // .. .. ==> MASK : 0x000000F0U VAL : 0x00000020U
// .. .. PLL_CP = 0x2 // .. .. PLL_CP = 0x2
// .. .. ==> 0XF8000110[11:8] = 0x00000002U // .. .. ==> 0XF8000110[11:8] = 0x00000002U
// .. .. ==> MASK : 0x00000F00U VAL : 0x00000200U // .. .. ==> MASK : 0x00000F00U VAL : 0x00000200U
// .. .. LOCK_CNT = 0x145 // .. .. LOCK_CNT = 0xfa
// .. .. ==> 0XF8000110[21:12] = 0x00000145U // .. .. ==> 0XF8000110[21:12] = 0x000000FAU
// .. .. ==> MASK : 0x003FF000U VAL : 0x00145000U // .. .. ==> MASK : 0x003FF000U VAL : 0x000FA000U
// .. .. // .. ..
EMIT_MASKWRITE(0XF8000110, 0x003FFFF0U ,0x001452C0U), EMIT_MASKWRITE(0XF8000110, 0x003FFFF0U ,0x000FA220U),
// .. .. .. START: UPDATE FB_DIV // .. .. .. START: UPDATE FB_DIV
// .. .. .. PLL_FDIV = 0x1e // .. .. .. PLL_FDIV = 0x28
// .. .. .. ==> 0XF8000100[18:12] = 0x0000001EU // .. .. .. ==> 0XF8000100[18:12] = 0x00000028U
// .. .. .. ==> MASK : 0x0007F000U VAL : 0x0001E000U // .. .. .. ==> MASK : 0x0007F000U VAL : 0x00028000U
// .. .. .. // .. .. ..
EMIT_MASKWRITE(0XF8000100, 0x0007F000U ,0x0001E000U), EMIT_MASKWRITE(0XF8000100, 0x0007F000U ,0x00028000U),
// .. .. .. FINISH: UPDATE FB_DIV // .. .. .. FINISH: UPDATE FB_DIV
// .. .. .. START: BY PASS PLL // .. .. .. START: BY PASS PLL
// .. .. .. PLL_BYPASS_FORCE = 1 // .. .. .. PLL_BYPASS_FORCE = 1
@ -4302,9 +4302,9 @@ unsigned long ps7_clock_init_data_2_0[] = {
// .. CLKACT = 0x1 // .. CLKACT = 0x1
// .. ==> 0XF8000140[0:0] = 0x00000001U // .. ==> 0XF8000140[0:0] = 0x00000001U
// .. ==> MASK : 0x00000001U VAL : 0x00000001U // .. ==> MASK : 0x00000001U VAL : 0x00000001U
// .. SRCSEL = 0x2 // .. SRCSEL = 0x0
// .. ==> 0XF8000140[6:4] = 0x00000002U // .. ==> 0XF8000140[6:4] = 0x00000000U
// .. ==> MASK : 0x00000070U VAL : 0x00000020U // .. ==> MASK : 0x00000070U VAL : 0x00000000U
// .. DIVISOR = 0x8 // .. DIVISOR = 0x8
// .. ==> 0XF8000140[13:8] = 0x00000008U // .. ==> 0XF8000140[13:8] = 0x00000008U
// .. ==> MASK : 0x00003F00U VAL : 0x00000800U // .. ==> MASK : 0x00003F00U VAL : 0x00000800U
@ -4312,7 +4312,7 @@ unsigned long ps7_clock_init_data_2_0[] = {
// .. ==> 0XF8000140[25:20] = 0x00000001U // .. ==> 0XF8000140[25:20] = 0x00000001U
// .. ==> MASK : 0x03F00000U VAL : 0x00100000U // .. ==> MASK : 0x03F00000U VAL : 0x00100000U
// .. // ..
EMIT_MASKWRITE(0XF8000140, 0x03F03F71U ,0x00100821U), EMIT_MASKWRITE(0XF8000140, 0x03F03F71U ,0x00100801U),
// .. CLKACT = 0x1 // .. CLKACT = 0x1
// .. ==> 0XF800014C[0:0] = 0x00000001U // .. ==> 0XF800014C[0:0] = 0x00000001U
// .. ==> MASK : 0x00000001U VAL : 0x00000001U // .. ==> MASK : 0x00000001U VAL : 0x00000001U
@ -8236,23 +8236,23 @@ unsigned long ps7_pll_init_data_1_0[] = {
// .. FINISH: SLCR SETTINGS // .. FINISH: SLCR SETTINGS
// .. START: PLL SLCR REGISTERS // .. START: PLL SLCR REGISTERS
// .. .. START: ARM PLL INIT // .. .. START: ARM PLL INIT
// .. .. PLL_RES = 0xc // .. .. PLL_RES = 0x2
// .. .. ==> 0XF8000110[7:4] = 0x0000000CU // .. .. ==> 0XF8000110[7:4] = 0x00000002U
// .. .. ==> MASK : 0x000000F0U VAL : 0x000000C0U // .. .. ==> MASK : 0x000000F0U VAL : 0x00000020U
// .. .. PLL_CP = 0x2 // .. .. PLL_CP = 0x2
// .. .. ==> 0XF8000110[11:8] = 0x00000002U // .. .. ==> 0XF8000110[11:8] = 0x00000002U
// .. .. ==> MASK : 0x00000F00U VAL : 0x00000200U // .. .. ==> MASK : 0x00000F00U VAL : 0x00000200U
// .. .. LOCK_CNT = 0x145 // .. .. LOCK_CNT = 0xfa
// .. .. ==> 0XF8000110[21:12] = 0x00000145U // .. .. ==> 0XF8000110[21:12] = 0x000000FAU
// .. .. ==> MASK : 0x003FF000U VAL : 0x00145000U // .. .. ==> MASK : 0x003FF000U VAL : 0x000FA000U
// .. .. // .. ..
EMIT_MASKWRITE(0XF8000110, 0x003FFFF0U ,0x001452C0U), EMIT_MASKWRITE(0XF8000110, 0x003FFFF0U ,0x000FA220U),
// .. .. .. START: UPDATE FB_DIV // .. .. .. START: UPDATE FB_DIV
// .. .. .. PLL_FDIV = 0x1e // .. .. .. PLL_FDIV = 0x28
// .. .. .. ==> 0XF8000100[18:12] = 0x0000001EU // .. .. .. ==> 0XF8000100[18:12] = 0x00000028U
// .. .. .. ==> MASK : 0x0007F000U VAL : 0x0001E000U // .. .. .. ==> MASK : 0x0007F000U VAL : 0x00028000U
// .. .. .. // .. .. ..
EMIT_MASKWRITE(0XF8000100, 0x0007F000U ,0x0001E000U), EMIT_MASKWRITE(0XF8000100, 0x0007F000U ,0x00028000U),
// .. .. .. FINISH: UPDATE FB_DIV // .. .. .. FINISH: UPDATE FB_DIV
// .. .. .. START: BY PASS PLL // .. .. .. START: BY PASS PLL
// .. .. .. PLL_BYPASS_FORCE = 1 // .. .. .. PLL_BYPASS_FORCE = 1
@ -8484,9 +8484,9 @@ unsigned long ps7_clock_init_data_1_0[] = {
// .. CLKACT = 0x1 // .. CLKACT = 0x1
// .. ==> 0XF8000140[0:0] = 0x00000001U // .. ==> 0XF8000140[0:0] = 0x00000001U
// .. ==> MASK : 0x00000001U VAL : 0x00000001U // .. ==> MASK : 0x00000001U VAL : 0x00000001U
// .. SRCSEL = 0x2 // .. SRCSEL = 0x0
// .. ==> 0XF8000140[6:4] = 0x00000002U // .. ==> 0XF8000140[6:4] = 0x00000000U
// .. ==> MASK : 0x00000070U VAL : 0x00000020U // .. ==> MASK : 0x00000070U VAL : 0x00000000U
// .. DIVISOR = 0x8 // .. DIVISOR = 0x8
// .. ==> 0XF8000140[13:8] = 0x00000008U // .. ==> 0XF8000140[13:8] = 0x00000008U
// .. ==> MASK : 0x00003F00U VAL : 0x00000800U // .. ==> MASK : 0x00003F00U VAL : 0x00000800U
@ -8494,7 +8494,7 @@ unsigned long ps7_clock_init_data_1_0[] = {
// .. ==> 0XF8000140[25:20] = 0x00000001U // .. ==> 0XF8000140[25:20] = 0x00000001U
// .. ==> MASK : 0x03F00000U VAL : 0x00100000U // .. ==> MASK : 0x03F00000U VAL : 0x00100000U
// .. // ..
EMIT_MASKWRITE(0XF8000140, 0x03F03F71U ,0x00100821U), EMIT_MASKWRITE(0XF8000140, 0x03F03F71U ,0x00100801U),
// .. CLKACT = 0x1 // .. CLKACT = 0x1
// .. ==> 0XF800014C[0:0] = 0x00000001U // .. ==> 0XF800014C[0:0] = 0x00000001U
// .. ==> MASK : 0x00000001U VAL : 0x00000001U // .. ==> MASK : 0x00000001U VAL : 0x00000001U

View File

@ -38,23 +38,23 @@ unsigned long ps7_pll_init_data_3_0[] = {
// .. FINISH: SLCR SETTINGS // .. FINISH: SLCR SETTINGS
// .. START: PLL SLCR REGISTERS // .. START: PLL SLCR REGISTERS
// .. .. START: ARM PLL INIT // .. .. START: ARM PLL INIT
// .. .. PLL_RES = 0xc // .. .. PLL_RES = 0x2
// .. .. ==> 0XF8000110[7:4] = 0x0000000CU // .. .. ==> 0XF8000110[7:4] = 0x00000002U
// .. .. ==> MASK : 0x000000F0U VAL : 0x000000C0U // .. .. ==> MASK : 0x000000F0U VAL : 0x00000020U
// .. .. PLL_CP = 0x2 // .. .. PLL_CP = 0x2
// .. .. ==> 0XF8000110[11:8] = 0x00000002U // .. .. ==> 0XF8000110[11:8] = 0x00000002U
// .. .. ==> MASK : 0x00000F00U VAL : 0x00000200U // .. .. ==> MASK : 0x00000F00U VAL : 0x00000200U
// .. .. LOCK_CNT = 0x145 // .. .. LOCK_CNT = 0xfa
// .. .. ==> 0XF8000110[21:12] = 0x00000145U // .. .. ==> 0XF8000110[21:12] = 0x000000FAU
// .. .. ==> MASK : 0x003FF000U VAL : 0x00145000U // .. .. ==> MASK : 0x003FF000U VAL : 0x000FA000U
// .. .. // .. ..
EMIT_MASKWRITE(0XF8000110, 0x003FFFF0U ,0x001452C0U), EMIT_MASKWRITE(0XF8000110, 0x003FFFF0U ,0x000FA220U),
// .. .. .. START: UPDATE FB_DIV // .. .. .. START: UPDATE FB_DIV
// .. .. .. PLL_FDIV = 0x1e // .. .. .. PLL_FDIV = 0x28
// .. .. .. ==> 0XF8000100[18:12] = 0x0000001EU // .. .. .. ==> 0XF8000100[18:12] = 0x00000028U
// .. .. .. ==> MASK : 0x0007F000U VAL : 0x0001E000U // .. .. .. ==> MASK : 0x0007F000U VAL : 0x00028000U
// .. .. .. // .. .. ..
EMIT_MASKWRITE(0XF8000100, 0x0007F000U ,0x0001E000U), EMIT_MASKWRITE(0XF8000100, 0x0007F000U ,0x00028000U),
// .. .. .. FINISH: UPDATE FB_DIV // .. .. .. FINISH: UPDATE FB_DIV
// .. .. .. START: BY PASS PLL // .. .. .. START: BY PASS PLL
// .. .. .. PLL_BYPASS_FORCE = 1 // .. .. .. PLL_BYPASS_FORCE = 1
@ -286,9 +286,9 @@ unsigned long ps7_clock_init_data_3_0[] = {
// .. CLKACT = 0x1 // .. CLKACT = 0x1
// .. ==> 0XF8000140[0:0] = 0x00000001U // .. ==> 0XF8000140[0:0] = 0x00000001U
// .. ==> MASK : 0x00000001U VAL : 0x00000001U // .. ==> MASK : 0x00000001U VAL : 0x00000001U
// .. SRCSEL = 0x2 // .. SRCSEL = 0x0
// .. ==> 0XF8000140[6:4] = 0x00000002U // .. ==> 0XF8000140[6:4] = 0x00000000U
// .. ==> MASK : 0x00000070U VAL : 0x00000020U // .. ==> MASK : 0x00000070U VAL : 0x00000000U
// .. DIVISOR = 0x8 // .. DIVISOR = 0x8
// .. ==> 0XF8000140[13:8] = 0x00000008U // .. ==> 0XF8000140[13:8] = 0x00000008U
// .. ==> MASK : 0x00003F00U VAL : 0x00000800U // .. ==> MASK : 0x00003F00U VAL : 0x00000800U
@ -296,7 +296,7 @@ unsigned long ps7_clock_init_data_3_0[] = {
// .. ==> 0XF8000140[25:20] = 0x00000001U // .. ==> 0XF8000140[25:20] = 0x00000001U
// .. ==> MASK : 0x03F00000U VAL : 0x00100000U // .. ==> MASK : 0x03F00000U VAL : 0x00100000U
// .. // ..
EMIT_MASKWRITE(0XF8000140, 0x03F03F71U ,0x00100821U), EMIT_MASKWRITE(0XF8000140, 0x03F03F71U ,0x00100801U),
// .. CLKACT = 0x1 // .. CLKACT = 0x1
// .. ==> 0XF800014C[0:0] = 0x00000001U // .. ==> 0XF800014C[0:0] = 0x00000001U
// .. ==> MASK : 0x00000001U VAL : 0x00000001U // .. ==> MASK : 0x00000001U VAL : 0x00000001U
@ -4067,23 +4067,23 @@ unsigned long ps7_pll_init_data_2_0[] = {
// .. FINISH: SLCR SETTINGS // .. FINISH: SLCR SETTINGS
// .. START: PLL SLCR REGISTERS // .. START: PLL SLCR REGISTERS
// .. .. START: ARM PLL INIT // .. .. START: ARM PLL INIT
// .. .. PLL_RES = 0xc // .. .. PLL_RES = 0x2
// .. .. ==> 0XF8000110[7:4] = 0x0000000CU // .. .. ==> 0XF8000110[7:4] = 0x00000002U
// .. .. ==> MASK : 0x000000F0U VAL : 0x000000C0U // .. .. ==> MASK : 0x000000F0U VAL : 0x00000020U
// .. .. PLL_CP = 0x2 // .. .. PLL_CP = 0x2
// .. .. ==> 0XF8000110[11:8] = 0x00000002U // .. .. ==> 0XF8000110[11:8] = 0x00000002U
// .. .. ==> MASK : 0x00000F00U VAL : 0x00000200U // .. .. ==> MASK : 0x00000F00U VAL : 0x00000200U
// .. .. LOCK_CNT = 0x145 // .. .. LOCK_CNT = 0xfa
// .. .. ==> 0XF8000110[21:12] = 0x00000145U // .. .. ==> 0XF8000110[21:12] = 0x000000FAU
// .. .. ==> MASK : 0x003FF000U VAL : 0x00145000U // .. .. ==> MASK : 0x003FF000U VAL : 0x000FA000U
// .. .. // .. ..
EMIT_MASKWRITE(0XF8000110, 0x003FFFF0U ,0x001452C0U), EMIT_MASKWRITE(0XF8000110, 0x003FFFF0U ,0x000FA220U),
// .. .. .. START: UPDATE FB_DIV // .. .. .. START: UPDATE FB_DIV
// .. .. .. PLL_FDIV = 0x1e // .. .. .. PLL_FDIV = 0x28
// .. .. .. ==> 0XF8000100[18:12] = 0x0000001EU // .. .. .. ==> 0XF8000100[18:12] = 0x00000028U
// .. .. .. ==> MASK : 0x0007F000U VAL : 0x0001E000U // .. .. .. ==> MASK : 0x0007F000U VAL : 0x00028000U
// .. .. .. // .. .. ..
EMIT_MASKWRITE(0XF8000100, 0x0007F000U ,0x0001E000U), EMIT_MASKWRITE(0XF8000100, 0x0007F000U ,0x00028000U),
// .. .. .. FINISH: UPDATE FB_DIV // .. .. .. FINISH: UPDATE FB_DIV
// .. .. .. START: BY PASS PLL // .. .. .. START: BY PASS PLL
// .. .. .. PLL_BYPASS_FORCE = 1 // .. .. .. PLL_BYPASS_FORCE = 1
@ -4315,9 +4315,9 @@ unsigned long ps7_clock_init_data_2_0[] = {
// .. CLKACT = 0x1 // .. CLKACT = 0x1
// .. ==> 0XF8000140[0:0] = 0x00000001U // .. ==> 0XF8000140[0:0] = 0x00000001U
// .. ==> MASK : 0x00000001U VAL : 0x00000001U // .. ==> MASK : 0x00000001U VAL : 0x00000001U
// .. SRCSEL = 0x2 // .. SRCSEL = 0x0
// .. ==> 0XF8000140[6:4] = 0x00000002U // .. ==> 0XF8000140[6:4] = 0x00000000U
// .. ==> MASK : 0x00000070U VAL : 0x00000020U // .. ==> MASK : 0x00000070U VAL : 0x00000000U
// .. DIVISOR = 0x8 // .. DIVISOR = 0x8
// .. ==> 0XF8000140[13:8] = 0x00000008U // .. ==> 0XF8000140[13:8] = 0x00000008U
// .. ==> MASK : 0x00003F00U VAL : 0x00000800U // .. ==> MASK : 0x00003F00U VAL : 0x00000800U
@ -4325,7 +4325,7 @@ unsigned long ps7_clock_init_data_2_0[] = {
// .. ==> 0XF8000140[25:20] = 0x00000001U // .. ==> 0XF8000140[25:20] = 0x00000001U
// .. ==> MASK : 0x03F00000U VAL : 0x00100000U // .. ==> MASK : 0x03F00000U VAL : 0x00100000U
// .. // ..
EMIT_MASKWRITE(0XF8000140, 0x03F03F71U ,0x00100821U), EMIT_MASKWRITE(0XF8000140, 0x03F03F71U ,0x00100801U),
// .. CLKACT = 0x1 // .. CLKACT = 0x1
// .. ==> 0XF800014C[0:0] = 0x00000001U // .. ==> 0XF800014C[0:0] = 0x00000001U
// .. ==> MASK : 0x00000001U VAL : 0x00000001U // .. ==> MASK : 0x00000001U VAL : 0x00000001U
@ -8249,23 +8249,23 @@ unsigned long ps7_pll_init_data_1_0[] = {
// .. FINISH: SLCR SETTINGS // .. FINISH: SLCR SETTINGS
// .. START: PLL SLCR REGISTERS // .. START: PLL SLCR REGISTERS
// .. .. START: ARM PLL INIT // .. .. START: ARM PLL INIT
// .. .. PLL_RES = 0xc // .. .. PLL_RES = 0x2
// .. .. ==> 0XF8000110[7:4] = 0x0000000CU // .. .. ==> 0XF8000110[7:4] = 0x00000002U
// .. .. ==> MASK : 0x000000F0U VAL : 0x000000C0U // .. .. ==> MASK : 0x000000F0U VAL : 0x00000020U
// .. .. PLL_CP = 0x2 // .. .. PLL_CP = 0x2
// .. .. ==> 0XF8000110[11:8] = 0x00000002U // .. .. ==> 0XF8000110[11:8] = 0x00000002U
// .. .. ==> MASK : 0x00000F00U VAL : 0x00000200U // .. .. ==> MASK : 0x00000F00U VAL : 0x00000200U
// .. .. LOCK_CNT = 0x145 // .. .. LOCK_CNT = 0xfa
// .. .. ==> 0XF8000110[21:12] = 0x00000145U // .. .. ==> 0XF8000110[21:12] = 0x000000FAU
// .. .. ==> MASK : 0x003FF000U VAL : 0x00145000U // .. .. ==> MASK : 0x003FF000U VAL : 0x000FA000U
// .. .. // .. ..
EMIT_MASKWRITE(0XF8000110, 0x003FFFF0U ,0x001452C0U), EMIT_MASKWRITE(0XF8000110, 0x003FFFF0U ,0x000FA220U),
// .. .. .. START: UPDATE FB_DIV // .. .. .. START: UPDATE FB_DIV
// .. .. .. PLL_FDIV = 0x1e // .. .. .. PLL_FDIV = 0x28
// .. .. .. ==> 0XF8000100[18:12] = 0x0000001EU // .. .. .. ==> 0XF8000100[18:12] = 0x00000028U
// .. .. .. ==> MASK : 0x0007F000U VAL : 0x0001E000U // .. .. .. ==> MASK : 0x0007F000U VAL : 0x00028000U
// .. .. .. // .. .. ..
EMIT_MASKWRITE(0XF8000100, 0x0007F000U ,0x0001E000U), EMIT_MASKWRITE(0XF8000100, 0x0007F000U ,0x00028000U),
// .. .. .. FINISH: UPDATE FB_DIV // .. .. .. FINISH: UPDATE FB_DIV
// .. .. .. START: BY PASS PLL // .. .. .. START: BY PASS PLL
// .. .. .. PLL_BYPASS_FORCE = 1 // .. .. .. PLL_BYPASS_FORCE = 1
@ -8497,9 +8497,9 @@ unsigned long ps7_clock_init_data_1_0[] = {
// .. CLKACT = 0x1 // .. CLKACT = 0x1
// .. ==> 0XF8000140[0:0] = 0x00000001U // .. ==> 0XF8000140[0:0] = 0x00000001U
// .. ==> MASK : 0x00000001U VAL : 0x00000001U // .. ==> MASK : 0x00000001U VAL : 0x00000001U
// .. SRCSEL = 0x2 // .. SRCSEL = 0x0
// .. ==> 0XF8000140[6:4] = 0x00000002U // .. ==> 0XF8000140[6:4] = 0x00000000U
// .. ==> MASK : 0x00000070U VAL : 0x00000020U // .. ==> MASK : 0x00000070U VAL : 0x00000000U
// .. DIVISOR = 0x8 // .. DIVISOR = 0x8
// .. ==> 0XF8000140[13:8] = 0x00000008U // .. ==> 0XF8000140[13:8] = 0x00000008U
// .. ==> MASK : 0x00003F00U VAL : 0x00000800U // .. ==> MASK : 0x00003F00U VAL : 0x00000800U
@ -8507,7 +8507,7 @@ unsigned long ps7_clock_init_data_1_0[] = {
// .. ==> 0XF8000140[25:20] = 0x00000001U // .. ==> 0XF8000140[25:20] = 0x00000001U
// .. ==> MASK : 0x03F00000U VAL : 0x00100000U // .. ==> MASK : 0x03F00000U VAL : 0x00100000U
// .. // ..
EMIT_MASKWRITE(0XF8000140, 0x03F03F71U ,0x00100821U), EMIT_MASKWRITE(0XF8000140, 0x03F03F71U ,0x00100801U),
// .. CLKACT = 0x1 // .. CLKACT = 0x1
// .. ==> 0XF800014C[0:0] = 0x00000001U // .. ==> 0XF800014C[0:0] = 0x00000001U
// .. ==> MASK : 0x00000001U VAL : 0x00000001U // .. ==> MASK : 0x00000001U VAL : 0x00000001U

View File

@ -1,14 +1,8 @@
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 diff --git a/lib/sw_apps/zynq_fsbl/misc/zc706/ps7_init.h b/lib/sw_apps/zynq_fsbl/misc/zc706/ps7_init.h
index 9572636306..2f3816271e 100644 index 9572636..1d79314 100644
--- a/lib/sw_apps/zynq_fsbl/misc/fast-servo/ps7_init.h --- a/lib/sw_apps/zynq_fsbl/misc/zc706/ps7_init.h
+++ b/lib/sw_apps/zynq_fsbl/misc/fast-servo/ps7_init.h +++ b/lib/sw_apps/zynq_fsbl/misc/zc706/ps7_init.h
@@ -67,20 +67,20 @@ extern unsigned long * ps7_peripherals_init_data; @@ -72,20 +72,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 DCI_FREQ 10158730
#define QSPI_FREQ 200000000 #define QSPI_FREQ 200000000
#define SMC_FREQ 10000000 #define SMC_FREQ 10000000
@ -20,27 +14,25 @@ index 9572636306..2f3816271e 100644
-#define SDIO_FREQ 50000000 -#define SDIO_FREQ 50000000
-#define UART_FREQ 50000000 -#define UART_FREQ 50000000
-#define SPI_FREQ 10000000 -#define SPI_FREQ 10000000
-#define I2C_FREQ 111111115
-#define WDT_FREQ 111111115
+#define SDIO_FREQ 100000000 +#define SDIO_FREQ 100000000
+#define UART_FREQ 100000000 +#define UART_FREQ 100000000
+#define SPI_FREQ 166666672 +#define SPI_FREQ 166666672
+#define I2C_FREQ 83333336 #define I2C_FREQ 111111115
+#define WDT_FREQ 83333336 #define WDT_FREQ 111111115
#define TTC_FREQ 50000000 #define TTC_FREQ 50000000
#define CAN_FREQ 10000000 #define CAN_FREQ 10000000
#define PCAP_FREQ 200000000 #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 #define TPIU_FREQ 200000000
index 8962bed427..df2f16adec 100644 -#define FPGA0_FREQ 50000000
--- a/lib/sw_apps/zynq_fsbl/misc/fast-servo/ps7_init_gpl.h +#define FPGA0_FREQ 10000000
+++ b/lib/sw_apps/zynq_fsbl/misc/fast-servo/ps7_init_gpl.h #define FPGA1_FREQ 10000000
@@ -81,20 +81,20 @@ extern unsigned long * ps7_peripherals_init_data; #define FPGA2_FREQ 10000000
#define FPGA3_FREQ 10000000
/* Freq of all peripherals */ diff --git a/lib/sw_apps/zynq_fsbl/misc/zc706/ps7_init_gpl.h b/lib/sw_apps/zynq_fsbl/misc/zc706/ps7_init_gpl.h
index 8962bed..562d5b5 100644
-#define APU_FREQ 666666687 --- a/lib/sw_apps/zynq_fsbl/misc/zc706/ps7_init_gpl.h
+#define APU_FREQ 500000000 +++ b/lib/sw_apps/zynq_fsbl/misc/zc706/ps7_init_gpl.h
#define DDR_FREQ 533333374 @@ -86,20 +86,20 @@ extern unsigned long * ps7_peripherals_init_data;
#define DCI_FREQ 10158730 #define DCI_FREQ 10158730
#define QSPI_FREQ 200000000 #define QSPI_FREQ 200000000
#define SMC_FREQ 10000000 #define SMC_FREQ 10000000
@ -52,33 +44,37 @@ index 8962bed427..df2f16adec 100644
-#define SDIO_FREQ 50000000 -#define SDIO_FREQ 50000000
-#define UART_FREQ 50000000 -#define UART_FREQ 50000000
-#define SPI_FREQ 10000000 -#define SPI_FREQ 10000000
-#define I2C_FREQ 111111115
-#define WDT_FREQ 111111115
+#define SDIO_FREQ 100000000 +#define SDIO_FREQ 100000000
+#define UART_FREQ 100000000 +#define UART_FREQ 100000000
+#define SPI_FREQ 166666672 +#define SPI_FREQ 166666672
+#define I2C_FREQ 83333336 #define I2C_FREQ 111111115
+#define WDT_FREQ 83333336 #define WDT_FREQ 111111115
#define TTC_FREQ 50000000 #define TTC_FREQ 50000000
#define CAN_FREQ 10000000 #define CAN_FREQ 10000000
#define PCAP_FREQ 200000000 #define PCAP_FREQ 200000000
#define TPIU_FREQ 200000000
-#define FPGA0_FREQ 50000000
+#define FPGA0_FREQ 10000000
#define FPGA1_FREQ 10000000
#define FPGA2_FREQ 10000000
#define FPGA3_FREQ 10000000
diff --git a/lib/sw_apps/zynq_fsbl/misc/fast-servo/xparameters.h b/lib/sw_apps/zynq_fsbl/misc/fast-servo/xparameters.h 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 index 997a982ca1..5461fbb477 100644
--- a/lib/sw_apps/zynq_fsbl/misc/fast-servo/xparameters.h --- a/lib/sw_apps/zynq_fsbl/misc/fast-servo/xparameters
+++ b/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 @@ @@ -9,21 +9,26 @@
#define XPAR_CPU_ID 0U #define XPAR_CPU_ID 0U
/* Definitions for peripheral PS7_CORTEXA9_0 */ /* 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 666666687
+#define XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ 500000000 +#define XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ 666666687
/******************************************************************/ /******************************************************************/
/* Canonical definitions for peripheral PS7_CORTEXA9_0 */ /* 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 666666687
+#define XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ 500000000 +#define XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ 666666687
/******************************************************************/ /******************************************************************/

View File

@ -0,0 +1,31 @@
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."""

View File

@ -0,0 +1,15 @@
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
+Vpp = (1 << 14 - 1) / 0.355 * 0.85
# conversion of bits to V
ANALOG_OUT_V = 1.8 / ((2**15) - 1)

View File

@ -0,0 +1,21 @@
diff --git a/gateware/logic/modulate.py b/gateware/logic/modulate.py
index c750306..ffba1b2 100644
--- a/gateware/logic/modulate.py
+++ b/gateware/logic/modulate.py
@@ -45,12 +45,14 @@ class Demodulate(Module, AutoCSR):
cordic_mode="rotate",
func_mode="circular",
)
- self.comb += [
+ self.sync += [
# cordic input
self.cordic.xi.eq(self.x),
self.cordic.zi.eq(
((self.phase * self.multiplier.storage) + self.delay.storage) << 1
- ),
+ )
+ ]
+ self.comb += [
# cordic output
self.i.eq(self.cordic.xo >> 1),
self.q.eq(self.cordic.yo >> 1),

View File

@ -1,38 +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)
-
-
-

View File

@ -0,0 +1,88 @@
diff --git a/gateware/logic/autolock.py b/gateware/logic/autolock.py
index a6dc764..975b23f 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?
@@ -167,36 +170,41 @@ class RobustAutolock(Module, AutoCSR):
# have we detected all peaks (and can turn on the lock)?
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)
- ),
- If(
- current_peak_height >= 0,
+ self.sync += [
+ 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),
all_instructions_triggered.eq(
self.current_instruction_idx >= self.N_instructions.storage
),
+ ]
+ self.comb += [
+ 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)
+ ),
+ over_threshold.eq(abs_sum_diff >= abs_current_peak_height),
+ waited_long_enough.eq(waited_for > current_wait_for),
self.turn_on_lock.eq(
all_instructions_triggered
& (final_waited_for >= self.final_wait_time.storage)
),
]
+ watching_reg = Signal()
self.sync += [
+ watching.eq(watching_reg),
If(
self.at_start,
- waited_for.eq(0),
+ # Compensate pipeline delay
+ 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),
self.current_instruction_idx.eq(0),
- If(self.request_lock, watching.eq(1)).Else(watching.eq(0)),
+ If(self.request_lock, watching_reg.eq(1)).Else(watching.eq(0), watching_reg.eq(0)),
).Else(
+ # Compensate pipeline delay
# not at start
If(
~self.request_lock,
@@ -213,7 +221,8 @@ class RobustAutolock(Module, AutoCSR):
self.current_instruction_idx.eq(
self.current_instruction_idx + 1
),
- waited_for.eq(0),
+ # Compensate pipeline delay
+ waited_for.eq(1),
).Else(waited_for.eq(waited_for + 1)),
),
If(

View File

@ -0,0 +1,35 @@
diff --git a/gateware/logic/chains.py b/gateware/logic/chains.py
index a890849..3461a78 100644
--- a/gateware/logic/chains.py
+++ b/gateware/logic/chains.py
@@ -93,7 +93,6 @@ class FastChain(Module, AutoCSR):
self.comb += [
x_limit.x.eq(([self.demod.i, self.demod.q][sub_channel_idx] << s) + dx),
- iir_c.x.eq(x_limit.y),
iir_c.hold.eq(0),
iir_c.clear.eq(0),
iir_d.x.eq(iir_c.y),
@@ -101,14 +100,20 @@ class FastChain(Module, AutoCSR):
iir_d.clear.eq(0),
]
+ self.sync += [
+ iir_c.x.eq(x_limit.y)
+ ]
+
ys = Array([iir_c.x, iir_c.y, iir_d.y])
output_signal_this_channel = (self.out_i, self.out_q)[sub_channel_idx]
- self.comb += [
+ self.sync += [
y_limit.x.eq(
Mux(self.invert.storage, -1, 1)
* (ys[self.y_tap.storage] + (ya << s) + (offset_signal << s))
- ),
+ )
+ ]
+ self.comb += [
output_signal_this_channel.eq(y_limit.y),
]

View File

@ -1,3 +1,42 @@
# 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: # diff between linen-org/linien commit ID 93f1f50:
# https://github.com/linien-org/linien/commit/93f1f50ebd86fe3314cab5a549462d0fcbf6a658 # https://github.com/linien-org/linien/commit/93f1f50ebd86fe3314cab5a549462d0fcbf6a658
# and elhep/linien commit ID b73eea0: # and elhep/linien commit ID b73eea0:
@ -16,41 +55,27 @@ index b3f3683..98c6e51 100644
- repo: https://github.com/pycqa/isort - repo: https://github.com/pycqa/isort
rev: 5.12.0 rev: 5.12.0
diff --git a/gateware/build_fpga_image.sh b/gateware/build_fpga_image.sh
index f822402..be7401c 100644
--- a/gateware/build_fpga_image.sh
+++ b/gateware/build_fpga_image.sh
@@ -16,4 +16,9 @@ export PATH=$VIVADOPATH:$PATH
rm linien-server/linien_server/gateware.bin -f
# run with -m option to avoid errors related to relative imports without breaking pytest
-python3 -m gateware.fpga_image_helper
\ No newline at end of file
+
+if [ -z "$1" ]; then
+ python3 -m gateware.fpga_image_helper
+else
+ python3 -m gateware.fpga_image_helper -p $1
+fi
\ No newline at end of file
diff --git a/gateware/fpga_image_helper.py b/gateware/fpga_image_helper.py diff --git a/gateware/fpga_image_helper.py b/gateware/fpga_image_helper.py
index 6c34429..a0b12d0 100644 index c3e20e7..ebead1d 100644
--- a/gateware/fpga_image_helper.py --- a/gateware/fpga_image_helper.py
+++ b/gateware/fpga_image_helper.py +++ b/gateware/fpga_image_helper.py
@@ -1,5 +1,6 @@ @@ -1,6 +1,7 @@
# Copyright 2014-2015 Robert Jördens <jordens@gmail.com>
# Copyright 2018-2022 Benjamin Wiegand <benjamin.wiegand@physik.hu-berlin.de>
+# Copyright 2023 Jakub Matyas <jakubk.m@gmail.com>
#
# This file is part of Linien and based on redpid. # This file is part of Linien and based on redpid.
# #
@@ -23,14 +24,16 @@ from pathlib import Path # Copyright (C) 2016-2024 Linien Authors (https://github.com/linien-org/linien#license)
REPO_ROOT_DIR = Path(__file__).resolve().parents[1] +# 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 .bit2bin import bit2bin
-from .hw_platform import Platform -from .hw_platform import Platform
-from .linien_module import RootModule -from .linien_module import RootModule
REPO_ROOT_DIR = Path(__file__).resolve().parents[1]
def py_csrconstants(map, fil): def py_csrconstants(map, fil):
fil.write("csr_constants = {\n") fil.write("csr_constants = {\n")
@ -65,7 +90,7 @@ index 6c34429..a0b12d0 100644
fil.write("}\n\n") fil.write("}\n\n")
@@ -52,26 +55,49 @@ def get_csrmap(banks): @@ -51,26 +54,51 @@ def get_csrmap(banks):
def py_csrmap(it, fil): def py_csrmap(it, fil):
fil.write("csr = {\n") fil.write("csr = {\n")
for reg in it: for reg in it:
@ -84,7 +109,7 @@ index 6c34429..a0b12d0 100644
- platform = Platform() - platform = Platform()
- root = RootModule(platform) - root = RootModule(platform)
+ import argparse + import argparse
+
+ parser = argparse.ArgumentParser() + parser = argparse.ArgumentParser()
+ parser.add_argument("-p", "--platform", default=None) + parser.add_argument("-p", "--platform", default=None)
+ args = parser.parse_args() + args = parser.parse_args()
@ -107,6 +132,7 @@ index 6c34429..a0b12d0 100644
+ platform.add_source_dir(REPO_ROOT_DIR / "gateware" / "verilog") + platform.add_source_dir(REPO_ROOT_DIR / "gateware" / "verilog")
+ build_dir = REPO_ROOT_DIR / "gateware" / "build" + build_dir = REPO_ROOT_DIR / "gateware" / "build"
+ platform.build(root, build_name="top", build_dir=build_dir, run=True) + platform.build(root, build_name="top", build_dir=build_dir, run=True)
with open( with open(
REPO_ROOT_DIR / "linien-server" / "linien_server" / "csrmap.py", "w" REPO_ROOT_DIR / "linien-server" / "linien_server" / "csrmap.py", "w"
) as fil: ) as fil:
@ -117,7 +143,7 @@ index 6c34429..a0b12d0 100644
py_csrmap(csr, fil) py_csrmap(csr, fil)
fil.write("states = {}\n".format(repr(root.linien.state_names))) fil.write("states = {}\n".format(repr(root.linien.state_names)))
fil.write("signals = {}\n".format(repr(root.linien.signal_names))) fil.write("signals = {}\n".format(repr(root.linien.signal_names)))
-
- platform.add_source_dir(REPO_ROOT_DIR / "gateware" / "verilog") - platform.add_source_dir(REPO_ROOT_DIR / "gateware" / "verilog")
- build_dir = REPO_ROOT_DIR / "gateware" / "build" - build_dir = REPO_ROOT_DIR / "gateware" / "build"
- platform.build(root, build_name="top", build_dir=build_dir) - platform.build(root, build_name="top", build_dir=build_dir)
@ -128,14 +154,14 @@ diff --git a/gateware/linien_module.py b/gateware/linien_module.py
index 16ca186..6905ac0 100644 index 16ca186..6905ac0 100644
--- a/gateware/linien_module.py --- a/gateware/linien_module.py
+++ b/gateware/linien_module.py +++ b/gateware/linien_module.py
@@ -2,6 +2,7 @@ @@ -1,6 +1,7 @@
# 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. # 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 @@ -36,19 +37,13 @@ from misoc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage
from .logic.autolock import FPGAAutolock from .logic.autolock import FPGAAutolock
from .logic.chains import FastChain, SlowChain, cross_connect from .logic.chains import FastChain, SlowChain, cross_connect

View File

@ -20,80 +20,21 @@
from migen import * from migen import *
from migen.genlib.cdc import MultiReg from migen.genlib.cdc import MultiReg
from misoc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage 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()
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()
self.locked = Signal()
platform.add_period_constraint(dco_clk_p, 1e9 / dco_freq)
self.specials += [
Instance(
"PLLE2_BASE",
p_BANDWIDTH="OPTIMIZED",
p_DIVCLK_DIVIDE=1,
p_CLKFBOUT_PHASE=0.0,
p_CLKFBOUT_MULT=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"),
i_CLKFBIN=clk_feedback_buf,
o_CLKFBOUT=clk_feedback,
p_CLKOUT0_DIVIDE=4,
p_CLKOUT0_PHASE=0.0,
p_CLKOUT0_DUTY_CYCLE=0.5,
o_CLKOUT0=clk_dco, # 200 MHz <- dco_clk
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
o_LOCKED=self.locked,
)
]
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_dco2x, o_O=self.cd_dco2x.clk)
class ADC(Module, AutoCSR): class ADC(Module, AutoCSR):
def __init__(self, platform, dco_freq=200e6): def __init__(self, platform):
adc_pads = platform.request("adc") adc_pads = platform.request("adc")
afe_pads = platform.request("adc_afe") afe_pads = platform.request("adc_afe")
self.frame_csr = CSRStatus(4) self.frame_csr = CSRStatus(5)
self.data_ch0 = CSRStatus(16) self.data_ch0 = CSRStatus(16)
self.data_ch1 = CSRStatus(16) self.data_ch1 = CSRStatus(16)
self.tap_delay = CSRStorage(5) self.tap_delay = CSRStorage(5)
self.bitslip_csr = CSRStorage(1) self.bitslip_csr = CSRStorage(1)
self.afe_ctrl = CSRStorage(4) self.afe_ctrl = CSRStorage(7)
tap_delay_val = Signal(5) tap_delay_val = Signal(5)
bitslip = Signal() bitslip = Signal()
@ -107,29 +48,25 @@ class ADC(Module, AutoCSR):
self.data_out = [Signal(16, reset_less=True), Signal(16, reset_less=True)] self.data_out = [Signal(16, reset_less=True), Signal(16, reset_less=True)]
self.s_frame = Signal(4) self.s_frame = Signal(4)
###
# DCO clock coming from LTC2195
# dco_clk = Record([("p", 1), ("n", 1)])
dco_clk =(adc_pads.dco_p, adc_pads.dco_n)
self.comb += [ 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), tap_delay_val.eq(self.tap_delay.storage),
Cat(ch1_gain_x10, ch2_gain_x10, ch1_shdn, ch2_shdn).eq( Cat(ch1_gain_x10, ch2_gain_x10, ch1_shdn, ch2_shdn).eq(
self.afe_ctrl.storage 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.specials += MultiReg(self.bitslip_csr.re, bitslip_re_dco_2d, "sys")
self.sync.dco2d += [ self.sync.sys += [
bitslip.eq(Mux(bitslip_re_dco_2d, self.bitslip_csr.storage, 0)) bitslip.eq(Mux(bitslip_re_dco_2d, self.bitslip_csr.storage, 0))
] ]
self.comb += [ self.comb += [
self.frame_csr.status.eq(self.s_frame), 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_ch0.status.eq(self.data_out[0]),
self.data_ch1.status.eq(self.data_out[1]), self.data_ch1.status.eq(self.data_out[1]),
] ]
@ -148,8 +85,8 @@ class ADC(Module, AutoCSR):
"LTC2195", "LTC2195",
i_rst_in=ResetSignal("sys"), i_rst_in=ResetSignal("sys"),
i_clk200=ClockSignal("idelay"), i_clk200=ClockSignal("idelay"),
i_DCO=ClockSignal("dco"), i_DCO=ClockSignal("sys_double"),
i_DCO_2D=ClockSignal("dco2d"), i_DCO_2D=ClockSignal("sys"),
i_FR_in_p=adc_pads.frame_p, i_FR_in_p=adc_pads.frame_p,
i_FR_in_n=adc_pads.frame_n, i_FR_in_n=adc_pads.frame_n,
i_D0_in_p=adc_pads.data0_p, i_D0_in_p=adc_pads.data0_p,

View File

@ -20,13 +20,17 @@
from migen import * from migen import *
from misoc.interconnect.csr import AutoCSR, CSRStorage from misoc.interconnect.csr import AutoCSR, CSRStorage
from migen.genlib.io import DDROutput from migen.genlib.io import DDROutput
from misoc.interconnect.stream import AsyncFIFO
class DAC(Module, AutoCSR): class DAC(Module, AutoCSR):
def __init__(self, platform): def __init__(self, platform, phase_shift_ctrl):
dac_pads = platform.request("dac") dac_pads = platform.request("dac")
dac_afe_pads = platform.request("dac_afe") dac_afe_pads = platform.request("dac_afe")
self.dac_ctrl = CSRStorage(3)
phase_shift_en, phase_shift_dir = phase_shift_ctrl
self.dac_ctrl = CSRStorage(5)
self.output_value_ch0 = CSRStorage(14) self.output_value_ch0 = CSRStorage(14)
self.output_value_ch1 = CSRStorage(14) self.output_value_ch1 = CSRStorage(14)
@ -38,37 +42,42 @@ class DAC(Module, AutoCSR):
output_data_ch1 = Signal(14) output_data_ch1 = Signal(14)
self.data_in = [Signal(14, reset_less=True), Signal(14, reset_less=True)] self.data_in = [Signal(14, reset_less=True), Signal(14, reset_less=True)]
platform.add_period_constraint(dac_pads.dclkio, 10.0) self.data_in_csr = [Signal(14, reset_less=True), Signal(14, reset_less=True)]
self.comb += [ self.comb += [
Cat(manual_override, ch0_pd, ch1_pd).eq(self.dac_ctrl.storage), self.data_in_csr[0].eq(self.output_value_ch0.storage),
self.data_in_csr[1].eq(self.output_value_ch1.storage),
]
self.comb += [
Cat(manual_override, ch0_pd, ch1_pd, phase_shift_en, phase_shift_dir).eq(self.dac_ctrl.storage),
dac_pads.rst.eq(ResetSignal("sys")), dac_pads.rst.eq(ResetSignal("sys")),
dac_afe_pads.ch1_pd_n.eq(~ch0_pd), dac_afe_pads.ch1_pd_n.eq(~ch0_pd),
dac_afe_pads.ch2_pd_n.eq(~ch1_pd), dac_afe_pads.ch2_pd_n.eq(~ch1_pd),
output_data_ch0.eq( output_data_ch0.eq(
Mux(manual_override, self.output_value_ch0.storage, self.data_in[0]) Mux(manual_override, self.data_in_csr[0], self.data_in[0])
), ),
output_data_ch1.eq( output_data_ch1.eq(
Mux(manual_override, self.output_value_ch1.storage, self.data_in[1]) Mux(manual_override, self.data_in_csr[1], self.data_in[1])
), ),
] ]
# data self.specials += [
for lane in range(14): Instance("ODDR",
self.specials += DDROutput( i_C=ClockSignal("sys"),
i1 = output_data_ch0[lane], i_CE=~ResetSignal("sys"),
i2 = output_data_ch1[lane], i_D1=output_data_ch0[lane], # DDR CLK Rising Edge
o = dac_pads.data[lane], i_D2=output_data_ch1[lane], # DDR CLK Falling Edge
clk = ClockSignal("dco2d") o_Q=dac_pads.data[lane],
) p_DDR_CLK_EDGE="SAME_EDGE")
for lane in range(14)]
# clock forwarding self.specials += Instance("ODDR",
self.specials += DDROutput( i_C=ClockSignal("sys_45_degree"),
i1 = 0b0, i_CE=~ResetSignal("sys"),
i2 = 0b1, i_D1=0,
o = dac_pads.dclkio, i_D2=1,
clk = ClockSignal("dco2d"), o_Q=dac_pads.dclkio,
) p_DDR_CLK_EDGE="SAME_EDGE")
class AUX_DAC_CTRL(Module, AutoCSR): class AUX_DAC_CTRL(Module, AutoCSR):

View File

@ -80,11 +80,13 @@ _io = [
Subsignal("data0_n", Pins("E7 B6 E3 C1"), 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_p", Pins("A2 D5 F2 D7"), IOStandard("LVDS_25")),
Subsignal("data1_n", Pins("A1 C4 F1 D6"), 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_p", Pins("B2"), IOStandard("LVDS_25")),
Subsignal("frame_n", Pins("B1"), IOStandard("LVDS_25")) Subsignal("frame_n", Pins("B1"), IOStandard("LVDS_25"))
), ),
("adc_dco_clk", 0 ,
Subsignal("p", Pins("B4"), IOStandard("LVDS_25")),
Subsignal("n", Pins("B3"), IOStandard("LVDS_25")),
),
# ADC AFE # ADC AFE
("adc_afe", 0, ("adc_afe", 0,
@ -194,7 +196,7 @@ _io = [
# Si540 nRST # Si540 nRST
("nrst", 0, Pins("M7"), IOStandard("LVCMOS18")), ("nrst", 0, Pins("M7"), IOStandard("LVCMOS18")),
("si5340_nlol", 0, Pins("P2"),IOStandard("LVCMOS18")),
] ]
@ -271,7 +273,7 @@ ps7_config_board_preset = {
# ETHERNET # ETHERNET
"PCW_ACT_ENET0_PERIPHERAL_FREQMHZ" : "125", "PCW_ACT_ENET0_PERIPHERAL_FREQMHZ" : "125",
"PCW_ENET0_PERIPHERAL_CLKSRC" : "ARM PLL", "PCW_ENET0_PERIPHERAL_CLKSRC" : "IO PLL",
"PCW_ENET0_PERIPHERAL_ENABLE" : "1", "PCW_ENET0_PERIPHERAL_ENABLE" : "1",
"PCW_ENET0_ENET0_IO" : "MIO 16 .. 27", "PCW_ENET0_ENET0_IO" : "MIO 16 .. 27",
"PCW_ENET0_GRP_MDIO_ENABLE" : "1", "PCW_ENET0_GRP_MDIO_ENABLE" : "1",
@ -315,21 +317,23 @@ ps7_config_board_preset = {
} }
class Platform(XilinxPlatform): class Platform(XilinxPlatform):
default_clk_name = "clk100" default_clk_name = "adc_dco_clk_p"
default_clk_period = 10.0 default_clk_period = 4.0
def __init__(self): def __init__(self):
XilinxPlatform.__init__(self, "xc7z015-clg485-1", _io, _connector_gpio + _connector_eem, toolchain="vivado") XilinxPlatform.__init__(self, "xc7z015-clg485-1", _io, _connector_gpio + _connector_eem, toolchain="vivado")
ps7_config = ps7_config_board_preset ps7_config = ps7_config_board_preset
self.ps7_config = ps7_config self.ps7_config = ps7_config
self.toolchain.with_phys_opt = True
verilog_sources = os.listdir(verilog_dir) verilog_sources = os.listdir(verilog_dir)
self.add_sources(verilog_dir, *verilog_sources) self.add_sources(verilog_dir, *verilog_sources)
def do_finalize(self, fragment): def do_finalize(self, fragment):
try: try:
XilinxPlatform.do_finalize(self, fragment) XilinxPlatform.do_finalize(self, fragment)
self.add_period_constraint(self.lookup_request(self.default_clk_name, loose=True), self.default_clk_period) self.add_period_constraint(self.lookup_request(self.default_clk_name), self.default_clk_period)
except ValueError: except ValueError:
pass pass
except ConstraintError: except ConstraintError:

View File

@ -31,63 +31,91 @@ from fast_servo.gateware.cores.spi_phy import SpiInterface, SpiPhy
class CRG(Module): class CRG(Module):
def __init__(self, platform): def __init__(self, platform, dco_freq=250e6):
self.ps_rst = Signal() self.ps_rst = Signal()
self.locked = Signal() self.locked = Signal()
dco_clk = platform.request("adc_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
)
self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_sys_45_degree = ClockDomain()
self.clock_domains.cd_sys_double = ClockDomain() self.clock_domains.cd_sys_double = ClockDomain()
self.clock_domains.cd_idelay = 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 = Signal()
clk_feedback_buf = Signal() clk_feedback_buf = Signal()
clk_sys = Signal() clk_sys = Signal()
clk_sys_45_degree = Signal()
clk_sys_double = Signal()
clk_idelay = Signal() clk_idelay = Signal()
self.ddr_clk_phase_shift_en = Signal()
self.ddr_clk_phase_incdec = Signal()
self.mmcm_ps_psdone = Signal()
si5340_nlol = platform.request("si5340_nlol")
si5340_nlol_buf = Signal()
self.specials += Instance("IBUF", i_I=si5340_nlol, o_O=si5340_nlol_buf)
platform.add_period_constraint(dco_clk.p, 1e9 / dco_freq)
self.specials += [ self.specials += [
Instance( Instance(
"PLLE2_BASE", "MMCME2_ADV",
p_BANDWIDTH="OPTIMIZED", p_BANDWIDTH="OPTIMIZED",
p_DIVCLK_DIVIDE=1, p_DIVCLK_DIVIDE=1,
p_CLKFBOUT_PHASE=0.0, p_CLKFBOUT_PHASE=0.0,
p_CLKFBOUT_MULT=10, p_CLKFBOUT_MULT_F=4, # VCO @ 1000 MHz
p_CLKIN1_PERIOD=10.0, p_CLKIN1_PERIOD=(1e9 / dco_freq),
p_REF_JITTER1=0.01, p_REF_JITTER1=0.06, # From LTC2195 Datasheet
p_STARTUP_WAIT="FALSE", p_STARTUP_WAIT="FALSE",
i_CLKIN1=clk100_buf, i_CLKIN1=dco_clk_buf,
i_PWRDWN=0, i_PWRDWN=0,
i_RST=self.ps_rst, i_RST=self.ps_rst | ~si5340_nlol_buf,
i_CLKFBIN=clk_feedback_buf, i_CLKFBIN=clk_feedback_buf,
o_CLKFBOUT=clk_feedback, o_CLKFBOUT=clk_feedback,
p_CLKOUT0_DIVIDE=10,
p_CLKOUT0_PHASE=0.0, p_CLKOUT0_USE_FINE_PS="True",
p_CLKOUT0_DIVIDE_F=8,
p_CLKOUT0_PHASE=45.0,
p_CLKOUT0_DUTY_CYCLE=0.5, p_CLKOUT0_DUTY_CYCLE=0.5,
o_CLKOUT0=clk_sys, # 100 MHz <- sys_clk o_CLKOUT0=clk_sys_45_degree, # 1000MHz / 8 -> 125MHz
p_CLKOUT1_DIVIDE=5, o_LOCKED=self.locked,
p_CLKOUT1_DIVIDE=8,
p_CLKOUT1_PHASE=0.0, p_CLKOUT1_PHASE=0.0,
p_CLKOUT1_DUTY_CYCLE=0.5, p_CLKOUT1_DUTY_CYCLE=0.5,
o_CLKOUT1=clk_idelay, # 200 MHZ <- 2 * sys_clk = 2*100 MHz o_CLKOUT1=clk_sys, # 1000MHz / 8 -> 120MHz
o_LOCKED=self.locked,
p_CLKOUT2_DIVIDE=4,
p_CLKOUT2_PHASE=0.0,
p_CLKOUT2_DUTY_CYCLE=0.5,
o_CLKOUT2=clk_sys_double, # 1000MHz / 4 -> 250MHz
p_CLKOUT3_DIVIDE=5,
p_CLKOUT3_PHASE=0.0,
p_CLKOUT3_DUTY_CYCLE=0.5,
o_CLKOUT3=clk_idelay, # 1000MHz / 5 -> 200MHz
i_PSCLK=ClockSignal(),
i_PSEN=self.ddr_clk_phase_shift_en,
i_PSINCDEC=self.ddr_clk_phase_incdec,
o_PSDONE=self.mmcm_ps_psdone,
) )
] ]
self.specials += Instance("BUFG", i_I=clk_feedback, o_O=clk_feedback_buf) 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_sys, o_O=self.cd_sys.clk)
self.specials += Instance("BUFG", i_I=clk_sys_45_degree, o_O=self.cd_sys_45_degree.clk)
self.specials += Instance("BUFG", i_I=clk_sys_double, o_O=self.cd_sys_double.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_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. # Ignore sys_clk to pll clkin path created by SoC's rst.
platform.add_false_path_constraints(self.cd_sys.clk, self.clkin) platform.add_false_path_constraints(self.cd_sys.clk, dco_clk)
self.specials += Instance("FD", p_INIT=1, i_D=~self.locked, i_C=self.cd_sys.clk, o_Q=self.cd_sys.rst) self.specials += Instance("FD", p_INIT=1, i_D=~self.locked, i_C=self.cd_sys.clk, o_Q=self.cd_sys.rst)
@ -117,6 +145,10 @@ class BaseSoC(PS7, AutoCSR):
self.submodules.crg = CRG(platform) self.submodules.crg = CRG(platform)
# 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)
# # # AXI to system bus bridge # # # AXI to system bus bridge
self.submodules.axi2sys = Axi2Sys() self.submodules.axi2sys = Axi2Sys()
self.submodules.sys2csr = Sys2CSR() self.submodules.sys2csr = Sys2CSR()
@ -147,9 +179,10 @@ class BaseSoC(PS7, AutoCSR):
# self.add_main_adc(platform) # self.add_main_adc(platform)
self.submodules.adc = ADC(platform) self.submodules.adc = ADC(platform)
self.csr_devices.append("adc") 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.add_main_dac(platform)
self.submodules.dac = DAC(platform) self.submodules.dac = DAC(platform, [self.crg.ddr_clk_phase_shift_en, self.crg.ddr_clk_phase_incdec,])
self.csr_devices.append("dac") self.csr_devices.append("dac")
# DEBUG # DEBUG

View File

@ -0,0 +1,132 @@
diff --git a/linien-gui/linien_gui/ui/general_panel.py b/linien-gui/linien_gui/ui/general_panel.py
index cad2d91..499146d 100644
--- a/linien-gui/linien_gui/ui/general_panel.py
+++ b/linien-gui/linien_gui/ui/general_panel.py
@@ -48,6 +48,8 @@ class GeneralPanel(QtWidgets.QWidget):
polarityContainerFastOut2: QtWidgets.QWidget
polarityComboBoxFastOut2: QtWidgets.QComboBox
modulationChannelComboBox: QtWidgets.QComboBox
+ afeGainComboBoxFastIn1: QtWidgets.QComboBox
+ afeGainComboBoxFastIn2: QtWidgets.QComboBox
def __init__(self, *args, **kwargs) -> None:
super(GeneralPanel, self).__init__(*args, **kwargs)
@@ -80,6 +82,14 @@ class GeneralPanel(QtWidgets.QWidget):
self.on_polarity_analog_out0_changed
)
+ self.afeGainComboBoxFastIn1.currentIndexChanged.connect(
+ self.on_afe_gain_in1_changed
+ )
+
+ self.afeGainComboBoxFastIn2.currentIndexChanged.connect(
+ self.on_afe_gain_in2_changed
+ )
+
for idx in range(1, 4):
element: CustomDoubleSpinBoxNoSign = getattr(
self, f"analogOutComboBox{idx}"
@@ -126,6 +136,9 @@ class GeneralPanel(QtWidgets.QWidget):
param2ui(self.parameters.polarity_fast_out2, self.polarityComboBoxFastOut2)
param2ui(self.parameters.polarity_analog_out0, self.polarityComboBoxAnalogOut0)
+ param2ui(self.parameters.adc_afe_10x_gain_1, self.afeGainComboBoxFastIn1)
+ param2ui(self.parameters.adc_afe_10x_gain_2, self.afeGainComboBoxFastIn2)
+
self.parameters.control_channel.add_callback(self.show_polarity_settings)
self.parameters.sweep_channel.add_callback(self.show_polarity_settings)
self.parameters.mod_channel.add_callback(self.show_polarity_settings)
@@ -211,6 +224,14 @@ class GeneralPanel(QtWidgets.QWidget):
self.parameters.polarity_analog_out0.value = bool(polarity)
self.control.write_registers()
+ def on_afe_gain_in1_changed(self, polarity):
+ self.parameters.adc_afe_10x_gain_1.value = bool(polarity)
+ self.control.write_registers()
+
+ def on_afe_gain_in2_changed(self, polarity):
+ self.parameters.adc_afe_10x_gain_2.value = bool(polarity)
+ self.control.write_registers()
+
def show_polarity_settings(self, *args):
used_channels = {
self.parameters.control_channel.value,
diff --git a/linien-gui/linien_gui/ui/general_panel.ui b/linien-gui/linien_gui/ui/general_panel.ui
index 6c2bd45..79f4580 100644
--- a/linien-gui/linien_gui/ui/general_panel.ui
+++ b/linien-gui/linien_gui/ui/general_panel.ui
@@ -508,6 +508,74 @@
</property>
</widget>
</item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_13">
+ <item>
+ <widget class="QLabel" name="label_22">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;FAST IN 1 GAIN&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::AutoText</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="afeGainComboBoxFastIn1">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <item>
+ <property name="text">
+ <string>1x</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>10x</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_14">
+ <item>
+ <widget class="QLabel" name="label_24">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;FAST IN 2 GAIN&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::AutoText</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="afeGainComboBoxFastIn2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <item>
+ <property name="text">
+ <string>1x</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>10x</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
<item>
<widget class="QGroupBox" name="dualChannelMixingGroupBox">
<property name="title">

View File

@ -0,0 +1,13 @@
diff --git a/linien-gui/linien_gui/ui/plot_widget.py b/linien-gui/linien_gui/ui/plot_widget.py
index f3b81ce..7d865a3 100644
--- a/linien-gui/linien_gui/ui/plot_widget.py
+++ b/linien-gui/linien_gui/ui/plot_widget.py
@@ -40,7 +40,7 @@ from pyqtgraph.Qt import QtCore
# NOTE: this is required for using a pen_width > 1. There is a bug though that causes
# the plot to be way too small. Therefore, we call PlotWidget.resize() after a while
pg.setConfigOptions(
- useOpenGL=True,
+ useOpenGL=False,
# by default, pyqtgraph tries to clean some things up using atexit. This causes
# problems with rpyc objects as their connection is already closed. Therefore, we
# disable this cleanup.

View File

@ -0,0 +1,128 @@
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>

View File

@ -0,0 +1,43 @@
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}")

View File

@ -0,0 +1,22 @@
diff --git a/gateware/linien_module.py b/gateware/linien_module.py
index a64714c..1d905de 100644
--- a/gateware/linien_module.py
+++ b/gateware/linien_module.py
@@ -47,7 +47,7 @@ from .lowlevel.scopegen import ScopeGen
class LinienLogic(Module, AutoCSR):
- def __init__(self, width=14, signal_width=25, chain_factor_width=8, coeff_width=25):
+ def __init__(self, width=14, signal_width=25, chain_factor_width=8, coeff_width=18):
self.init_csr(width, chain_factor_width)
self.init_submodules(width, signal_width)
self.connect_pid()
@@ -154,7 +154,7 @@ class LinienModule(Module, AutoCSR):
def __init__(self, soc):
width = 14
signal_width = 25
- coeff_width = 25
+ coeff_width = 18
chain_factor_bits = 8
self.init_submodules(

View File

@ -4,14 +4,14 @@
diff --git a/monitor/Makefile b/monitor/Makefile diff --git a/monitor/Makefile b/monitor/Makefile
new file mode 100644 new file mode 100644
index 0000000..044d88e index 0000000..0c9bb53
--- /dev/null --- /dev/null
+++ b/monitor/Makefile +++ b/monitor/Makefile
@@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
+# Makefile for libmonitor +# Makefile for libmonitor
+ +
+OBJS = monitor.o +OBJS = monitor.o
+SRCS = $(subst .o,.c, $(OBJS)) +SRCS = $(subst .o,.c, $(OBJS)))
+OSOBJS = monitor.os +OSOBJS = monitor.os
+TARGETLIB=libmonitor.so +TARGETLIB=libmonitor.so
+CFLAGS=-g -std=gnu99 -Wall -Werror +CFLAGS=-g -std=gnu99 -Wall -Werror
@ -59,27 +59,16 @@ index ce1b28e..233b82a 100644
libmonitor = cdll.LoadLibrary(libmonitor_file) libmonitor = cdll.LoadLibrary(libmonitor_file)
libmonitor.read_value.restype = c_uint32 libmonitor.read_value.restype = c_uint32
diff --git a/setup.py b/setup.py diff --git a/setup.py b/setup.py
index 98bdaee..b0a8af4 100644 index 9302177..2258ddc 100644
--- a/setup.py --- a/setup.py
+++ b/setup.py +++ b/setup.py
@@ -1,5 +1,10 @@ @@ -1,4 +1,28 @@
import re
-from distutils.core import Extension, setup -from distutils.core import Extension, setup
+import os +import os
+
+from distutils.core import setup +from distutils.core import setup
+from distutils.command.build import build +from distutils.command.build import build
+from distutils.command.install import install
+ +
from pathlib import Path
# from https://stackoverflow.com/a/7071358/2750945
@@ -11,9 +16,50 @@ if mo:
verstr = mo.group(1)
else:
raise RuntimeError("Unable to find version string in %s." % (VERSIONFILE,))
+ +
+# Patch from https://github.com/linien-org/pyrp3/blob/e6688acf8bd79d2dbe1d192d09c1a1baf1f6c67b/setup.py#L16-L55
+build_dir = "monitor/" +build_dir = "monitor/"
+ +
+def compile_libmonitor(): +def compile_libmonitor():
@ -91,51 +80,16 @@ index 98bdaee..b0a8af4 100644
+ finally: + finally:
+ os.chdir(cwd) + os.chdir(cwd)
+ +
+
+def install_libmonitor(prefix=""):
+ cwd = os.getcwd() # get current directory
+ try:
+ os.chdir(build_dir)
+ os.system("make install INSTALL_DIR={prefix}".format(prefix=prefix))
+ finally:
+ os.chdir(cwd)
+
+
+class lib_build(build): +class lib_build(build):
+ def run(self): + def run(self):
+ compile_libmonitor() + compile_libmonitor()
+ build.run(self) + build.run(self)
+ +
+ +setup_args = dict(
+class lib_install(install): + cmdclass={
+ def run(self):
+ compile_libmonitor()
+ install_libmonitor(self.prefix)
+ # install.run(self)
+
+# Will use nix to install libmonitor
+cmdclass = {
+ "build": lib_build + "build": lib_build
+} + }
+ +)
this_directory = Path(__file__).parent
long_description = (this_directory / "README.rst").read_text()
+ -setup_args = dict(ext_modules=[Extension("monitor", ["monitor/monitor.c"])])
setup( setup(**setup_args)
name="pyrp3",
version=verstr,
@@ -32,6 +78,7 @@ setup(
"cached_property>=1.5.2",
"numpy>=1.11.0",
],
+ cmdclass=cmdclass,
classifiers=[
"Intended Audience :: Developers",
"Intended Audience :: Education",
@@ -45,5 +92,4 @@ setup(
"Topic :: Software Development :: Libraries :: Python Modules",
],
keywords=["redpitaya", "FPGA", "zynq"],
- ext_modules=[Extension("monitor", ["monitor/monitor.c"])],
)

View File

@ -0,0 +1,34 @@
diff --git a/linien-server/linien_server/parameters.py b/linien-server/linien_server/parameters.py
index 287f304..fe482d7 100644
--- a/linien-server/linien_server/parameters.py
+++ b/linien-server/linien_server/parameters.py
@@ -154,6 +154,16 @@ class Parameters:
`error_signal_2_max`.
"""
+ # ------------------- FAST SERVO PARAMETERS ---------------------------------------
+ self.adc_afe_10x_gain_1 = Parameter(start=0, min_=0, max_=1, restorable=True)
+ self.adc_afe_10x_gain_2 = Parameter(start=0, min_=0, max_=1, restorable=True)
+ """
+ Configures Fast INs AFE Gain:
+ 0 --> 1x Gain
+ 1 --> 10x Gain
+ """
+
+
# ------------------- GENERAL PARAMETERS ---------------------------------------
self.mod_channel = Parameter(start=0, min_=0, max_=1, restorable=True)
diff --git a/linien-server/linien_server/registers.py b/linien-server/linien_server/registers.py
index 365c254..2b8f697 100644
--- a/linien-server/linien_server/registers.py
+++ b/linien-server/linien_server/registers.py
@@ -173,6 +173,8 @@ class Registers:
gpio_n_do0_en=csrmap.signals.index("zero"),
gpio_n_do1_en=csrmap.signals.index("zero"),
logic_slow_decimation=16,
+ # Fast Servo Paramters
+ adc_afe_ctrl=(self.parameters.adc_afe_10x_gain_2.value << 1 | self.parameters.adc_afe_10x_gain_1.value)
)
for instruction_idx, [wait_for, peak_height] in enumerate(

View File

@ -0,0 +1,73 @@
diff --git a/linien-client/linien_client/deploy.py b/linien-client/linien_client/deploy.py
index 7355cc3..876f1ec 100644
--- a/linien-client/linien_client/deploy.py
+++ b/linien-client/linien_client/deploy.py
@@ -83,14 +83,14 @@ def start_remote_server(
if (local_version != remote_version) and not ("dev" in local_version):
raise InvalidServerVersionException(local_version, remote_version)
- logger.debug("Sending credentials")
- conn.run(
- 'python3 -c "from linien_common.communication import write_hash_to_file;'
- f"write_hash_to_file('{hash_username_and_password(device.username, device.password)}')\"", # noqa E501
- out_stream=out_stream,
- err_stream=out_stream,
- warn=True,
- )
+ # logger.debug("Sending credentials")
+ # conn.run(
+ # 'python3 -c "from linien_common.communication import write_hash_to_file;'
+ # f"write_hash_to_file('{hash_username_and_password(device.username, device.password)}')\"", # noqa E501
+ # out_stream=out_stream,
+ # err_stream=out_stream,
+ # warn=True,
+ # )
logger.debug("Starting server")
conn.run(
diff --git a/linien-server/linien_server/cli.py b/linien-server/linien_server/cli.py
index 7781c74..827d04f 100644
--- a/linien-server/linien_server/cli.py
+++ b/linien-server/linien_server/cli.py
@@ -44,20 +44,19 @@ class LinienServerCLI:
def start(self) -> None:
"""Start the Linien server as a systemd service."""
- copy_systemd_service_file()
logger.info("Starting Linien server")
- subprocess.run(["systemctl", "start", "linien-server.service"])
+ subprocess.run(["sv", "up", "/etc/service/linien-server"])
logger.info("Started Linien server")
def stop(self) -> None:
"""Stop the Linien server running as a systemd service."""
logger.info("Stopping Linien server")
- subprocess.run(["systemctl", "stop", "linien-server.service"])
+ subprocess.run(["sv", "down", "/etc/service/linien-server"])
logger.info("Stopped Linien server")
def status(self) -> None:
"""Check the status of the Linien server."""
- subprocess.run(["journalctl", "-u", "linien-server.service"])
+ subprocess.run(["sv", "status", "/etc/service/linien-server"])
def run(self, fake: bool = False, host: Optional[str] = None) -> None:
"""
@@ -89,15 +88,14 @@ class LinienServerCLI:
def enable(self) -> None:
"""Enable the Linien server to start on boot."""
- copy_systemd_service_file()
logger.info("Enabling Linien server")
- subprocess.run(["systemctl", "enable", "linien-server.service"])
+ subprocess.run(["rm", "/etc/service/linien-server/down"])
logger.info("Enabled Linien server")
def disable(self) -> None:
"""Disable the Linien server from starting on boot."""
logger.info("Disabling Linien server")
- subprocess.run(["systemctl", "disable", "linien-server.service"])
+ subprocess.run(["touch", "/etc/service/linien-server/down"])
logger.info("Disabled Linien server")

View File

@ -0,0 +1,22 @@
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

View File

@ -0,0 +1,26 @@
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."""

View File

@ -0,0 +1,66 @@
diff --git a/gateware/linien_module.py b/gateware/linien_module.py
index 54b6285..c3f8d14 100644
--- a/gateware/linien_module.py
+++ b/gateware/linien_module.py
@@ -233,30 +233,52 @@ 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) >> chain_factor_bits
),
).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) >> chain_factor_bits
+ ),
)
]
mixed_limited = Signal((signal_width, True))
- self.comb += [
- self.logic.limit_error_signal.x.eq(mixed >> chain_factor_bits),
+ self.sync += [
+ self.logic.limit_error_signal.x.eq(mixed),
mixed_limited.eq(self.logic.limit_error_signal.y),
]

View File

@ -0,0 +1,19 @@
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)
)
]

View File

@ -0,0 +1,64 @@
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))
+ ]

View File

@ -17,9 +17,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
import mmap import time
import os
import spidev import spidev
from pyfastservo.common import ( from pyfastservo.common import (
ADC_AFE_CTRL_ADDR, ADC_AFE_CTRL_ADDR,
@ -33,6 +31,8 @@ from pyfastservo.common import (
AUX_ADC_ADDR, AUX_ADC_ADDR,
MAP_MASK, MAP_MASK,
PAGESIZE, PAGESIZE,
write_to_memory,
read_from_memory
) )
# /dev/spidev1.0 <=> spidev<BUS>.<DEVICE> # /dev/spidev1.0 <=> spidev<BUS>.<DEVICE>
@ -44,276 +44,158 @@ AUX_ADC_PORT_A = 2
AUX_ADC_PORT_B = 3 AUX_ADC_PORT_B = 3
def main_adc_config(test_pattern): 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 high_word = (test_pattern & 0xFF00) >> 8
low_word = test_pattern & 0xFF low_word = test_pattern & 0xFF
spi = spidev.SpiDev() 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
try: def main_adc_test_mode(spi, enable):
spi.open(MAIN_ADC_BUS, MAIN_ADC_DEVICE) reg_contents = 0x15 if enable else 0x11 # set to LVDS output, set 4 data lanes and turn on or off test mode
spi.max_speed_hz = 50000 spi_write(spi, 0x02, reg_contents)
spi.mode = 0b00 # CPOL = 0 CPHA = 0
spi.cshigh = False
# spi.read0 = False
spi_buffer = [0x00, 0x80] # reset def verify_adc_registers(spi, reg_to_check):
rx_buffer = [0x00, 0x00] 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}")
spi.xfer2(spi_buffer) def read_frame():
return read_from_memory(ADC_FRAME_ADDR, 1)[0]
# REGISTER A1
spi_buffer = [0x01, 0x20] # set to Two's complement Data Format
spi.xfer2(spi_buffer)
# read values back
spi_buffer = [0x81, 0x00]
rx_buffer = spi.xfer2(spi_buffer)
print(f"Spi readback register 0x01: 0x{rx_buffer[1]:02x}")
if rx_buffer[1] != 0x20:
print("Different value read than sent in reg 0x02")
# REGISTER A2
spi_buffer = [
0x02,
0x15,
] # set to LVDS output, set 4 data lanes and turn on test mode
spi.xfer2(spi_buffer)
# read values back
spi_buffer = [0x82, 0x00]
rx_buffer = spi.xfer2(spi_buffer)
print(f"Spi readback register 0x02: 0x{rx_buffer[1]:02x}")
if rx_buffer[1] != 0x15:
print("Different value read than sent in reg 0x02")
# REGISTER A3
# test pattern high word
spi_buffer = [0x03, high_word]
spi.xfer2(spi_buffer)
# read balues back
spi_buffer = [0x83, 0x00]
rx_buffer = spi.xfer2(spi_buffer)
print(f"Spi readback register 0x03: 0x{rx_buffer[1]:02x}")
if rx_buffer[1] != high_word:
print("Different value read than sent in reg 0x03")
# REGISTER A4
# test pattern low word
spi_buffer = [0x04, low_word]
spi.xfer2(spi_buffer)
# read balues back
spi_buffer = [0x84, 0x00]
rx_buffer = spi.xfer2(spi_buffer)
print(f"Spi readback register 0x04: 0x{rx_buffer[1]:02x}")
if rx_buffer[1] != low_word:
print("Different value read than sent in reg 0x04")
finally:
spi.close()
def main_adc_test_mode(enable):
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
# spi.read0 = True
reg_contents = (
0x15 if enable else 0x11
) # set to LVDS output, set 4 data lanes and turn on or off test mode
spi_buffer = [0x02, reg_contents]
spi.xfer2(spi_buffer)
# read values back
spi_buffer = [0x82, 0x00]
rx_buffer = spi.xfer2(spi_buffer)
print(f"Spi readback register 0x02: 0x{rx_buffer[1]:02x}")
if rx_buffer[1] != reg_contents:
print("Different value read than sent in reg 0x02")
finally:
spi.close()
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
# print(f"addr: 0x{addr:x}\tstart_addr: 0x{start_addr}\tstop_addr: 0x{stop_addr}")
contents = mem[start_addr:stop_addr]
read_value = list(contents)[:n_bytes]
# print("Read value: ", read_value)
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
# print(f"addr: 0x{addr:x}\tstart_addr: 0x{start_addr}\tstop_addr: 0x{stop_addr}")
mem[start_addr:stop_addr] = value_bytes
contents = mem[start_addr:stop_addr]
# print("Read value: ", list(contents), " written value: ", list(value_bytes))
finally:
os.close(f)
def word_align():
value = 0
edge_detected = False
transition = False
tap_delay = 0
def perform_bitslip():
for i in range(4): for i in range(4):
current_frame = read_from_memory(ADC_FRAME_ADDR, 1)[0] current_frame = read_frame()
if current_frame != 0x0C: if current_frame & 0x0F != 0x0C:
print( print(f"Performing bitslip (iteration: {i}). Current frame: 0x{current_frame:02x}")
f"Performing bitslip (bitslip iteration: {i}). Reason: current_frame is 0x{current_frame:02x} instead of 0x0C"
)
write_to_memory(ADC_BITSLIP_ADDR, 1) write_to_memory(ADC_BITSLIP_ADDR, 1)
else: else:
print(f"No bitslip required; Currernt frame = 0x{current_frame:02x}") print(f"No bitslip required; Current frame: 0x{current_frame:02x}")
break return
current_frame = read_from_memory(ADC_FRAME_ADDR, 1)[0] def find_edge():
prev_frame = current_frame prev_frame = read_frame()
for tap_delay in range(32):
for i in range(32):
write_to_memory(ADC_DELAY_ADDR, tap_delay) write_to_memory(ADC_DELAY_ADDR, tap_delay)
if edge_detected == 1: current_frame = read_frame()
break
current_frame = read_from_memory(ADC_FRAME_ADDR, 1)[0]
print(f"Tap delay: {tap_delay}") print(f"Tap delay: {tap_delay}, Current frame: 0x{current_frame:02x}")
print(f"Current frame: 0x{current_frame:02x}") print(f"prev_frame: 0x{prev_frame:02x}")
if current_frame == prev_frame: if current_frame != prev_frame:
tap_delay += 1 final_delay = ((tap_delay+1) // 2) + 2
elif not transition: print(f"Edge detected; setting iDelay to: {final_delay}")
tap_delay += 1 write_to_memory(ADC_DELAY_ADDR, final_delay)
transition = True return
elif transition:
tap_delay = i // 2
edge_detected = True
prev_frame = current_frame prev_frame = current_frame
if not edge_detected: # If no edge detected
tap_delay = 11 # empirically tested to work best final_delay = 11
write_to_memory(ADC_DELAY_ADDR, tap_delay) print(f"No edge detected; setting iDelay to: {final_delay}")
print(f"No edge detected; setting iDelay to: {tap_delay}") write_to_memory(ADC_DELAY_ADDR, final_delay)
if edge_detected:
write_to_memory(ADC_DELAY_ADDR, tap_delay + 2)
print(f"Edge detected; setting iDelay to (tap_delay + 2): {tap_delay} + 2")
adc_ch0 = read_from_memory(ADC_CH0_HIGH_ADDR, 4) def read_adc_channel(high_addr, low_addr):
print(f"ADC_CH0: 0x{adc_ch0}") return (read_from_memory(high_addr, 1)[0] << 8) | read_from_memory(low_addr, 1)[0]
adc_ch0 = (read_from_memory(ADC_CH0_HIGH_ADDR, 1)[0] << 8) | read_from_memory( def print_adc_channels():
ADC_CH0_LOW_ADDR, 1 adc_ch0 = read_adc_channel(ADC_CH0_HIGH_ADDR, ADC_CH0_LOW_ADDR)
)[0] adc_ch1 = read_adc_channel(ADC_CH1_HIGH_ADDR, ADC_CH1_LOW_ADDR)
adc_ch1 = (read_from_memory(ADC_CH1_HIGH_ADDR, 1)[0] << 8) | read_from_memory(
ADC_CH1_LOW_ADDR, 1
)[0]
print(f"Final ADC_CH0: 0x{adc_ch0:04x}") print(f"Final ADC_CH0: 0x{adc_ch0:04x}")
print(f"Final ADC_CH1: 0x{adc_ch1: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 modify_bit(original_value, position, bit_value): def search_edge():
mask = 1 << position for tap_delay in range(32):
return (original_value & ~mask) | (bit_value << position) 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 adc_aux_config(): def configure_ltc2195():
# MSB to LSB
# | RANGE | ADDR [2:0] | DIFF |
# DIFF = 0 => configure as single ended (it is negated in gateware)
# RANGE = 0 => configure as 0-2.5 Vref
to_write = 0b00000
write_to_memory(AUX_ADC_ADDR, to_write)
def adc_aux_read(port, type, pin):
# port:
# 1 - port A
# 2 - port B
# type:
# 0 - single-ended
# 1 - differential
# pin:
# 0b000 - VA1/VB1
# 0b001 - VA2/VB2
# 0b010 - VA3/VB3
# 0b011 - VA4/VB4
assert type in (0, 1)
assert port in (1, 2)
write_buffer = [0, 0]
read_buffer = [0, 0]
aux_config_reg = read_from_memory(AUX_ADC_ADDR, 1)[0]
aux_config = (aux_config_reg & 0b10001) | pin << 1
write_to_memory(AUX_ADC_ADDR, aux_config)
spi = spidev.SpiDev() spi = spidev.SpiDev()
try: try:
spi.open(1, 3) # AUX ADC 1? spi.open(MAIN_ADC_BUS, MAIN_ADC_DEVICE)
spi.max_speed_hz = 5000 spi.max_speed_hz = 50000
spi.mode = 0b00 spi.mode = 0b00 # CPOL = 0 CPHA = 0
spi.cshigh = False spi.cshigh = False
read_buffer = spi.xfer2(write_buffer) test_pattern = 0x811F
mu_voltage = read_buffer[0] << 8 | read_buffer[1] >> 2 main_adc_config(spi, test_pattern)
print(f"MU_voltage: 0x{mu_voltage:04X}")
print(f"Read_buffer[0]: 0x{read_buffer[0]:02X}") verify_adc_registers(spi, {
print(f"Read_buffer[1]: 0x{read_buffer[1]:02X}") 0x01: 0x20,
return mu_voltage * 2.5 / 4096 0x02: 0x15,
0x03: (test_pattern & 0xFF00) >> 8,
0x04: test_pattern & 0xFF
})
# 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: finally:
spi.close() spi.close()
def main():
main_adc_config(0x811F)
word_align()
main_adc_test_mode(False)
write_to_memory(ADC_AFE_CTRL_ADDR, 0b1100) # {-, -, ch2_X10, ch1_X10}
print(read_from_memory(ADC_AFE_CTRL_ADDR, 1)[0])
if __name__ == "__main__": if __name__ == "__main__":
main() configure_ltc2195()

View File

@ -17,6 +17,9 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
import os
import mmap
CSR_SIZE = 0x800 CSR_SIZE = 0x800
MAP_SIZE = 0x1000 MAP_SIZE = 0x1000
MAP_MASK = 0xFFF MAP_MASK = 0xFFF
@ -72,3 +75,46 @@ CH0_HIGH_WORD_ADDR = DAC_BASE_ADDR + CH0_HIGH_WORD_OFFSET
CH0_LOW_WORD_ADDR = DAC_BASE_ADDR + CH0_LOW_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_HIGH_WORD_ADDR = DAC_BASE_ADDR + CH1_HIGH_WORD_OFFSET
CH1_LOW_WORD_ADDR = DAC_BASE_ADDR + CH1_LOW_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)

View File

@ -17,8 +17,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
import mmap import time
import os
import spidev import spidev
from pyfastservo.common import ( from pyfastservo.common import (
@ -29,117 +28,80 @@ from pyfastservo.common import (
CTRL_ADDR, CTRL_ADDR,
MAP_MASK, MAP_MASK,
PAGESIZE, PAGESIZE,
write_to_memory,
read_from_memory
) )
# /dev/spidev2.0 <=> spidev<BUS>.<DEVICE> # /dev/spidev2.0 <=> spidev<BUS>.<DEVICE>
MAIN_DAC_BUS = 2 MAIN_DAC_BUS = 2
MAIN_DAC_DEVICE = 0 MAIN_DAC_DEVICE = 0
DAC_VERSION = 0x0A DAC_VERSION = 0x0A
def inc_ddr_clk_phase():
curr_cfg = read_from_memory(CTRL_ADDR, 1)[0] & 0x07
write_to_memory(CTRL_ADDR, 0x10 | curr_cfg) # Set MMCM Phase Shift to be INC
write_to_memory(CTRL_ADDR, 0x18 | curr_cfg) # Assert MMCM Phase Shift EN High
write_to_memory(CTRL_ADDR, curr_cfg) # Deassert MMCM Phase Shift EN High
def main_dac_init(): def dec_ddr_clk_phase():
spi = spidev.SpiDev() curr_cfg = read_from_memory(CTRL_ADDR, 1)[0] & 0x07
write_to_memory(CTRL_ADDR, 0x00 | curr_cfg) # Set MMCM Phase Shift to be DEC
write_to_memory(CTRL_ADDR, 0x08 | curr_cfg) # Assert MMCM Phase Shift EN High
write_to_memory(CTRL_ADDR, curr_cfg) # Deassert MMCM Phase Shift EN High
try: def spi_write(spi, address, value):
spi.open(MAIN_DAC_BUS, MAIN_DAC_DEVICE) spi.xfer2([address, value])
spi.max_speed_hz = 5000
spi.mode = 0b00 # CPOL = 0 CPHA = 0
spi.cshigh = False
spi_buffer = [0x00, 0x10] # software reset def spi_read(spi, address):
spi.xfer2(spi_buffer) rx_buffer = spi.xfer2([0x80 | address, 0x00])
return rx_buffer[1]
spi_buffer = [0x00, 0x00] # release software reset def soft_reset(spi):
spi.xfer2(spi_buffer) 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)
spi_buffer = [ def check_version(spi):
0x80, version = spi_read(spi, 0x1F)
0x00, print(f"DAC version: 0x{version:02X}")
] # for some reason it is needed to read the reset address for reset to actually reset return version == DAC_VERSION
rx_buffer = spi.xfer2(spi_buffer)
spi_buffer = [0x9F, 0x00] # hardware version def configure_dac(spi):
rx_buffer = spi.xfer2(spi_buffer) power_down_reg = spi_read(spi, 0x01)
if rx_buffer[1] != DAC_VERSION: spi_write(spi, 0x01, power_down_reg & ~(1 << 0)) # Clear EXTREF bit for internal reference
print(f"Unrecognized device: 0x{rx_buffer[1]:02X}") 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)
print("=== Contents of spi buffer after DAC VERSION read back: ===") def dac_self_calibration(spi):
print(f"0x{rx_buffer[0]:02X}{rx_buffer[1]:02X}") 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
spi_buffer = [0x82, 00] while True:
rx_buffer = spi.xfer2(spi_buffer) status = spi_read(spi, 0x0F)
print(f"0x{rx_buffer[0]:02X}{rx_buffer[1]:02X}") if status & 0xC0 == 0xC0: # Both CALSTATI and CALSTATQ are 1
break
# set to 2's complement and I to be first of pair on data input pads time.sleep(0.01)
spi_buffer = [0x02, 0xB4]
rx_buffer = spi.xfer2(spi_buffer)
spi_buffer = [0x82, 00]
rx_buffer = spi.xfer2(spi_buffer)
print(f"0x{rx_buffer[0]:02X}{rx_buffer[1]:02X}")
for i in range(10):
spi_buffer = [0x94, 0x00]
rx_buffer = spi.xfer2(spi_buffer)
print(f"0x{rx_buffer[0]:02X}{rx_buffer[1]:02X}")
finally:
spi.close()
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
# print(f"addr: 0x{addr:x}\tstart_addr: 0x{start_addr}\tstop_addr: 0x{stop_addr}")
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)
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): def manual_override(enable=True):
reg_contents = read_from_memory(CTRL_ADDR, 1)[0] reg_contents = read_from_memory(CTRL_ADDR, 1)[0]
print(f"REG contents: 0b{reg_contents:03b}")
to_write = reg_contents | 0b1 if enable else reg_contents & 0b110 to_write = reg_contents | 0b1 if enable else reg_contents & 0b110
write_to_memory(CTRL_ADDR, to_write) write_to_memory(CTRL_ADDR, to_write)
print(f"Set DAC Output Manual Override: {enable}")
def power_down_afe(channel, power_down=True):
def power_down(channel, power_down=True):
assert channel in (0, 1) assert channel in (0, 1)
bitmask = 1 << (channel + 1) & 0b111 bitmask = 1 << (channel + 1) & 0b111
@ -150,33 +112,68 @@ def power_down(channel, power_down=True):
to_write = reg_contents | value to_write = reg_contents | value
write_to_memory(CTRL_ADDR, to_write) write_to_memory(CTRL_ADDR, to_write)
reg_contents = read_from_memory(CTRL_ADDR, 1)[0] reg_contents = read_from_memory(CTRL_ADDR, 1)[0]
print(f"REG contents: 0b{reg_contents:03b}") 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
def write_sample(channel, sample): # Note: DAC HIGH word and LOW word output are not updated
assert channel in (0, 1) # at the same time. On scope, you will see more than one step
if channel == 0: # of value changed.
addresses = [CH0_HIGH_WORD_ADDR, CH0_LOW_WORD_ADDR] 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: else:
addresses = [CH1_HIGH_WORD_ADDR, CH1_LOW_WORD_ADDR] print("Clock relationship is found")
return True
low_word_value = sample & 0xFF def configure_ad9117():
high_word_value = (sample >> 8) & 0x3F spi = spidev.SpiDev()
values = [high_word_value, low_word_value] spi.open(MAIN_DAC_BUS, MAIN_DAC_DEVICE)
for addr, value in zip(addresses, values): spi.max_speed_hz = 5000
write_to_memory(addr, value) 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
def write_ramp(): power_down_afe(0, True)
signal = [i for i in range(16384)] power_down_afe(1, True)
for value in signal: configure_dac(spi)
write_sample(0, value) check_clk_relationship(spi)
dac_self_calibration(spi)
def main(): # Enable DAC outputs
main_dac_init() spi_write(spi, 0x01, spi_read(spi, 0x01) & ~((1 << 4) | (1 << 3)))
power_down(0, False)
power_down(1, False) 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__": if __name__ == "__main__":
main() configure_ad9117()

View File

@ -21,8 +21,8 @@ from pyfastservo import adc, si5340, dac
def main(): def main():
si5340.configure_si5340() si5340.configure_si5340()
adc.main() adc.configure_ltc2195()
dac.main() dac.configure_ad9117()
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -35,6 +35,15 @@ STATUS_LOSREF = 0x04
STATUS_LOL = 0x08 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): def write_preamble(bus):
preamble = [ preamble = [
(0x0B24, 0xC0), (0x0B24, 0xC0),
@ -45,7 +54,7 @@ def write_preamble(bus):
(0x0B4E, 0x1A), (0x0B4E, 0x1A),
] ]
for address, value in preamble: for address, value in preamble:
bus.write_byte_data(IC_ADDR, address, value) write_register(bus, address, value)
def write_postamble(bus): def write_postamble(bus):
postamble = [ postamble = [
@ -54,7 +63,7 @@ def write_postamble(bus):
(0x0B25, 0x02), (0x0B25, 0x02),
] ]
for address, value in postamble: for address, value in postamble:
bus.write_byte_data(IC_ADDR, address, value) write_register(bus, address, value)
def wait_device_ready(bus): def wait_device_ready(bus):
for _ in range(15): for _ in range(15):
@ -134,8 +143,8 @@ def configure_si5340():
(0x0235, 0x00), # M_NUM (0x0235, 0x00), # M_NUM
(0x0236, 0x00), (0x0236, 0x00),
(0x0237, 0x00), (0x0237, 0x00),
(0x0238, 0x80), (0x0238, 0xA0),
(0x0239, 0x89), (0x0239, 0x8C),
(0x023A, 0x00), (0x023A, 0x00),
(0x023B, 0x00), # M_DEN (0x023B, 0x00), # M_DEN
(0x023C, 0x00), (0x023C, 0x00),
@ -147,7 +156,7 @@ def configure_si5340():
(0x0303, 0x00), (0x0303, 0x00),
(0x0304, 0x00), (0x0304, 0x00),
(0x0305, 0x00), (0x0305, 0x00),
(0x0306, 0x21), (0x0306, 0x1B),
(0x0307, 0x00), (0x0307, 0x00),
(0x0308, 0x00), # N0_DEN (0x0308, 0x00), # N0_DEN
(0x0309, 0x00), (0x0309, 0x00),
@ -161,11 +170,11 @@ def configure_si5340():
(0x030F, 0x00), (0x030F, 0x00),
(0x0310, 0x00), (0x0310, 0x00),
(0x0311, 0x00), (0x0311, 0x00),
(0x0312, 0x01), (0x0312, 0x00),
(0x0313, 0x00), # N1_DEN (0x0313, 0x00), # N1_DEN
(0x0314, 0x00), (0x0314, 0x00),
(0x0315, 0x00), (0x0315, 0x00),
(0x0316, 0x01), (0x0316, 0x00),
(0x0317, 0x01), # N1_UPDATE (0x0317, 0x01), # N1_UPDATE
# N2 Configuration (1:1 ratio) # N2 Configuration (1:1 ratio)
@ -174,11 +183,11 @@ def configure_si5340():
(0x031A, 0x00), (0x031A, 0x00),
(0x031B, 0x00), (0x031B, 0x00),
(0x031C, 0x00), (0x031C, 0x00),
(0x031D, 0x01), (0x031D, 0x00),
(0x031E, 0x00), # N2_DEN (0x031E, 0x00), # N2_DEN
(0x031F, 0x00), (0x031F, 0x00),
(0x0320, 0x00), (0x0320, 0x00),
(0x0321, 0x01), (0x0321, 0x00),
(0x0322, 0x01), # N2_UPDATE (0x0322, 0x01), # N2_UPDATE
# N3 Configuration (1:1 ratio) # N3 Configuration (1:1 ratio)
@ -187,11 +196,11 @@ def configure_si5340():
(0x0325, 0x00), (0x0325, 0x00),
(0x0326, 0x00), (0x0326, 0x00),
(0x0327, 0x00), (0x0327, 0x00),
(0x0328, 0x01), (0x0328, 0x00),
(0x0329, 0x00), # N3_DEN (0x0329, 0x00), # N3_DEN
(0x032A, 0x00), (0x032A, 0x00),
(0x032B, 0x00), (0x032B, 0x00),
(0x032C, 0x01), (0x032C, 0x00),
(0x032D, 0x01), # N3_UPDATE (0x032D, 0x01), # N3_UPDATE
# Output configuration # Output configuration
@ -244,7 +253,7 @@ def configure_si5340():
print("Writing main configuration...") print("Writing main configuration...")
for address, value in main_config: for address, value in main_config:
bus.write_byte_data(IC_ADDR, address, value) write_register(bus, address, value)
print("Main configuration written") print("Main configuration written")
write_postamble(bus) write_postamble(bus)

28
flake.lock generated
View File

@ -18,16 +18,16 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1719838683, "lastModified": 1736867362,
"narHash": "sha256-Zw9rQjHz1ilNIimEXFeVa1ERNRBF8DoXDhLAZq5B4pE=", "narHash": "sha256-i/UJ5I7HoqmFMwZEH6vAvBxOrjjOJNU739lnZnhUln8=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "d032c1a6dfad4eedec7e35e91986becc699d7d69", "rev": "9c6b49aeac36e2ed73a8c472f1546f6d9cf1addc",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-24.05", "ref": "nixos-24.11",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@ -40,11 +40,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1699416673, "lastModified": 1736697818,
"narHash": "sha256-uJ6QnU7hFUYZsz6J/HIBEpLW0bS7GLQOo6ccKtoZ68k=", "narHash": "sha256-JqqQO9W2s64vt6q2XrAY1ml0l7ff+7HbY5xCUhJJFmM=",
"owner": "cleverca22", "owner": "cleverca22",
"repo": "not-os", "repo": "not-os",
"rev": "79ff6e6fe0b64bf8b8d38363b2bb0dea0cd5a686", "rev": "c556294ad82fb256082ca0a787cc5da7cb4e91e3",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -64,11 +64,11 @@
"src-migen": { "src-migen": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1715484909, "lastModified": 1735131698,
"narHash": "sha256-4DCHBUBfc/VA+7NW2Hr0+JP4NnKPru2uVJyZjCCk0Ws=", "narHash": "sha256-P4vaF+9iVekRAC2/mc9G7IwI6baBpPAxiDQ8uye4sAs=",
"owner": "m-labs", "owner": "m-labs",
"repo": "migen", "repo": "migen",
"rev": "4790bb577681a8c3a8d226bc196a4e5deb39e4df", "rev": "4c2ae8dfeea37f235b52acb8166f12acaaae4f7c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -80,11 +80,11 @@
"src-misoc": { "src-misoc": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1715647536, "lastModified": 1736416570,
"narHash": "sha256-q+USDcaKHABwW56Jzq8u94iGPWlyLXMyVt0j/Gyg+IE=", "narHash": "sha256-tbcN/fzejZIaYbTbwk8Ir1glYevESqMinMeDB3z8oxg=",
"ref": "refs/heads/master", "ref": "refs/heads/master",
"rev": "fea9de558c730bc394a5936094ae95bb9d6fa726", "rev": "1f5318e9edc1085ac77e9b85b8f5e03371dba54c",
"revCount": 2455, "revCount": 2464,
"submodules": true, "submodules": true,
"type": "git", "type": "git",
"url": "https://github.com/m-labs/misoc.git" "url": "https://github.com/m-labs/misoc.git"

255
flake.nix
View File

@ -1,7 +1,7 @@
{ {
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.05; inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-24.11;
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";
@ -14,6 +14,40 @@
pkgs-armv7l = pkgs.pkgsCross.zynq-armv7l-linux; pkgs-armv7l = pkgs.pkgsCross.zynq-armv7l-linux;
fsbl-support = ./fast-servo/fsbl-support; 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-gui-add-afe_gain-combo-boxes.patch
./fast-servo/linien-gui-do-not-use-opengl.patch
./fast-servo/linien-client-ssh-port-change.patch
./fast-servo/linien-server-fast-servo.patch
./fast-servo/linien-server-cli.patch
./fast-servo/linien-server-add-afe_ctrl-regs.patch
./fast-servo/linien-gateware-fast-servo.patch
./fast-servo/linien-gateware-autolock-pipeline.patch
./fast-servo/linien-module-iir-coeff-width-set-to-18bit.patch
./fast-servo/linien_module_pipeline.patch
./fast-servo/pid_pipeline.patch
./fast-servo/pid_err_sig_pipeline.patch
./fast-servo/linien-gateware-chain-pipeline.patch
./fast-servo/linien-demodulate_add_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;
@ -24,6 +58,8 @@
./not-os-patches/pr-30.patch ./not-os-patches/pr-30.patch
./not-os-patches/pr-31.patch ./not-os-patches/pr-31.patch
./not-os-patches/pr-33.patch ./not-os-patches/pr-33.patch
./not-os-patches/pr-34.patch
./not-os-patches/iproute2.patch
]; ];
}; };
@ -96,29 +132,44 @@
freetype freetype
fontconfig fontconfig
]; ];
profile = "set -e; source /opt/Xilinx/Vivado/2022.2/settings64.sh"; profile = "set -e; source /opt/Xilinx/Vivado/2024.2/settings64.sh";
runScript = "vivado"; 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=";
};
propagatedBuildInputs = [ pkgs-armv7l.python3Packages.numpy ];
pythonImportsCheck = [ "cma" ];
checkPhase = ''
# At least one doctest fails, thus only limited amount of files is tested
python -m cma.test interfaces.py purecma.py logger.py optimization_tools.py transformations.py
'';
};
pyrp3 = pkgs-armv7l.python3Packages.buildPythonPackage rec { pyrp3 = pkgs-armv7l.python3Packages.buildPythonPackage rec {
pname = "pyrp3"; pname = "pyrp3";
version = "1.2.0"; version = "2.1.0";
pyproject = true; format = "pyproject";
src = pkgs.fetchFromGitHub { src = pkgs.fetchFromGitHub {
owner = "linien-org"; owner = "linien-org";
repo = "pyrp3"; repo = "pyrp3";
rev = "v${version}"; rev = "v${version}";
hash = "sha256-43TTlpJ5SMAjQM71bNVvrWQyciRXM3zpuA/Dw41AEgU="; hash = "sha256-ol1QGXyCOei94iIPIocuTRHBxa5jKSH5RzjzROfZaBI=";
}; };
patches = ./fast-servo/linien-pyrp3-monitor.patch; patches = ./fast-servo/linien-pyrp3-monitor.patch;
nativeBuildInputs = with pkgs-armv7l.python3Packages; [ nativeBuildInputs = [
setuptools wheel setuptools-scm pkgs-armv7l.python3Packages.setuptools
] ++ (with pkgs-armv7l; [ gcc gnumake ]); pkgs-armv7l.gcc
propagatedBuildInputs = with pkgs-armv7l.python3Packages; [
myhdl
rpyc4
cached-property
numpy
]; ];
postInstall = '' postInstall = ''
cp monitor/libmonitor.so $out/lib cp monitor/libmonitor.so $out/lib
@ -127,13 +178,141 @@
substituteInPlace $out/${pkgs.python3.sitePackages}/pyrp3/raw_memory.py \ substituteInPlace $out/${pkgs.python3.sitePackages}/pyrp3/raw_memory.py \
--replace "libmonitor.so" "$out/lib/libmonitor.so" --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 {
pname = "linien-common-armv7l";
inherit version;
pyproject = true;
src = linien-src;
sourceRoot = "${src.name}/linien-common";
preBuild = ''
export HOME=$(mktemp -d)
'';
nativeBuildInputs = [ pkgs-armv7l.python3Packages.setuptools ];
pythonRelaxDeps = [ "importlib-metadata" ];
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 { linien-server = pkgs-armv7l.python3Packages.buildPythonPackage rec {
pname = "linien-server"; pname = "linien-server";
inherit version;
src = linien-src;
pyproject = true; pyproject = true;
inherit (pkgs.python3Packages.linien-common) src version;
sourceRoot = "source/linien-server"; sourceRoot = "${src.name}/linien-server";
postPatch = '' postPatch = ''
cp ${fast-servo-gateware}/csrmap.py linien_server/csrmap.py cp ${fast-servo-gateware}/csrmap.py linien_server/csrmap.py
substituteInPlace linien_server/acquisition.py \ substituteInPlace linien_server/acquisition.py \
@ -143,28 +322,19 @@
''; '';
nativeBuildInputs = [ pkgs-armv7l.python3Packages.setuptools ]; nativeBuildInputs = [ pkgs-armv7l.python3Packages.setuptools ];
propagatedBuildInputs = with pkgs-armv7l.python3Packages; [ propagatedBuildInputs = with pkgs-armv7l.python3Packages; [
appdirs fire
certifi influxdb-client
click
cma
pylpsd pylpsd
] ++ [
linien-common-armv7l
cma
pyrp3 pyrp3
requests
linien-common
]; ];
}; };
fast-servo-gateware = pkgs.stdenv.mkDerivation rec { fast-servo-gateware = pkgs.stdenv.mkDerivation rec {
name = "fast-servo-gateware"; name = "fast-servo-gateware";
inherit (pkgs.python3Packages.linien-common) src; src = linien-src;
prePatch = ''
mkdir -p fast_servo/gateware
cp -r ${./fast-servo/linien-gateware}/. fast_servo/gateware
'';
patches = [
fast-servo/linien-fast-servo-gateware.patch
fast-servo/linien-fast-servo-server.patch
];
nativeBuildInputs = [ nativeBuildInputs = [
(pkgs.python3.withPackages(ps: [ (pkgs.python3.withPackages(ps: [
migen misoc migen misoc
@ -185,6 +355,7 @@
installPhase = '' installPhase = ''
mkdir -p $out $out/nix-support mkdir -p $out $out/nix-support
cp gateware/build/top.bit $out cp gateware/build/top.bit $out
cp gateware/build $out -r
cp linien-server/linien_server/gateware.bin $out cp linien-server/linien_server/gateware.bin $out
cp linien-server/linien_server/csrmap.py $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/top.bit >> $out/nix-support/hydra-build-products
@ -257,9 +428,17 @@
cp ${fast-servo-gateware}/gateware.bin /lib/firmware/ cp ${fast-servo-gateware}/gateware.bin /lib/firmware/
echo gateware.bin > /sys/class/fpga_manager/fpga0/firmware echo gateware.bin > /sys/class/fpga_manager/fpga0/firmware
# Run device init scripts # Reset the PL and initialize PL, ADC and DAC clock
echo "Initializing clock generator, ADC, and DAC..." echo "Configuring Si5340 to generate Clocks"
python3 -m pyfastservo.initialize python3 -m pyfastservo.si5340
# Iniailize ADC
echo "Initialize ADC"
python3 -m pyfastservo.adc
# Initialize DAC
echo "Initialize DAC"
python3 -m pyfastservo.dac
''; '';
})]; })];
system = "x86_64-linux"; system = "x86_64-linux";
@ -476,6 +655,16 @@
"${board}-qemu" = not-os-qemu; "${board}-qemu" = not-os-qemu;
}; };
in rec { in rec {
devShell.x86_64-linux = pkgs.mkShell {
name = "nix-servo-dev_shell";
packages = [
vivado
];
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; inherit migen misoc vivado;

View File

@ -0,0 +1,13 @@
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 = {

View File

@ -1,5 +1,5 @@
diff --git a/configuration.nix b/configuration.nix diff --git a/configuration.nix b/configuration.nix
index 010c487..e1e85ba 100644 index 010c487..2d08009 100644
--- a/configuration.nix --- a/configuration.nix
+++ b/configuration.nix +++ b/configuration.nix
@@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
@ -8,7 +8,7 @@ index 010c487..e1e85ba 100644
{ {
imports = [ ./qemu.nix ]; imports = [ ./qemu.nix ];
@@ -7,10 +7,15 @@ @@ -7,10 +7,16 @@
environment.etc = { environment.etc = {
"ssh/authorized_keys.d/root" = { "ssh/authorized_keys.d/root" = {
text = '' text = ''
@ -18,6 +18,7 @@ index 010c487..e1e85ba 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";
}; };
@ -27,11 +28,15 @@ index 010c487..e1e85ba 100644
}; };
} }
diff --git a/runit.nix b/runit.nix diff --git a/runit.nix b/runit.nix
index d7b0bf3..67cff43 100644 index d7b0bf3..14dd437 100644
--- a/runit.nix --- a/runit.nix
+++ b/runit.nix +++ b/runit.nix
@@ -7,8 +7,8 @@ let @@ -4,11 +4,11 @@ let
Port 22 sshd_config = pkgs.writeText "sshd_config" ''
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

View File

@ -1,5 +1,5 @@
diff --git a/base.nix b/base.nix diff --git a/base.nix b/base.nix
index 7eaee32..3ade454 100644 index 7eaee32..9aa338e 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,7 +14,7 @@ index 7eaee32..3ade454 100644
not-os.simpleStaticIp = mkOption { not-os.simpleStaticIp = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
@@ -84,17 +89,27 @@ with lib; @@ -84,17 +89,25 @@ with lib;
}; };
environment.etc = { environment.etc = {
"nix/nix.conf".source = pkgs.runCommand "nix.conf" {} '' "nix/nix.conf".source = pkgs.runCommand "nix.conf" {} ''
@ -31,8 +31,6 @@ index 7eaee32..3ade454 100644
+ extra-sandbox-paths = /bin/sh=${pkgs.runtimeShell} $(echo $extraPaths) + extra-sandbox-paths = /bin/sh=${pkgs.runtimeShell} $(echo $extraPaths)
+ max-jobs = auto + max-jobs = auto
+ sandbox = true + sandbox = true
+ substituters = https://cache.armv7l.xyz
+ trusted-public-keys = cache.armv7l.xyz-1:kBY/eGnBAYiqYfg0fy0inWhshUo+pGFM3Pj7kIkmlBk=
+ trusted-users = root + trusted-users = root
EOF EOF
''; '';
@ -154,7 +152,7 @@ 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..d5c5eda 100644 index 3fa23ab..069fe89 100644
--- a/zynq_image.nix --- a/zynq_image.nix
+++ b/zynq_image.nix +++ b/zynq_image.nix
@@ -1,66 +1,89 @@ @@ -1,66 +1,89 @@
@ -252,7 +250,7 @@ index 3fa23ab..d5c5eda 100644
- 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 nano ]; + systemPackages = with pkgs; [ inetutils wget gnugrep nano vim ];
+ etc = { + etc = {
+ "service/getty/run".source = pkgs.writeShellScript "getty" '' + "service/getty/run".source = pkgs.writeShellScript "getty" ''
+ hostname ${config.networking.hostName} + hostname ${config.networking.hostName}

View File

@ -26,16 +26,3 @@ index 7eaee32..c1881cb 100644
# nix-build -A system.build.toplevel && du -h $(nix-store -qR result) --max=0 -BM|sort -n # nix-build -A system.build.toplevel && du -h $(nix-store -qR result) --max=0 -BM|sort -n
system.build.toplevel = pkgs.runCommand "not-os" { system.build.toplevel = pkgs.runCommand "not-os" {
diff --git a/systemd-compat.nix b/systemd-compat.nix
index 11464c6..cb223b8 100644
--- a/systemd-compat.nix
+++ b/systemd-compat.nix
@@ -9,6 +9,8 @@ with lib;
};
systemd.user = mkOption {
};
+ systemd.tmpfiles = mkOption {
+ };
};
config = {
};

View File

@ -0,0 +1,20 @@
diff --git a/zynq_image.nix b/zynq_image.nix
index 069fe89..979b760 100644
--- a/zynq_image.nix
+++ b/zynq_image.nix
@@ -51,6 +51,15 @@ in {
hostname ${config.networking.hostName}
exec setsid agetty ttyPS0 115200
'';
+ "service/linien-server/run".source = pkgs.writeShellScript "linien-server" ''
+ exec 2>&1
+ exec setsid linien-server run
+ '';
+ "service/linien-server/log/run".source = pkgs.writeShellScript "linien-server-logger" ''
+ exec 2>&1
+ mkdir -p /root/linien-server-log
+ exec svlogd -tt /root/linien-server-log
+ '';
"pam.d/other".text = ''
auth sufficient pam_permit.so
account required pam_permit.so