Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pin does not exist #16

Closed
tuxcnc opened this issue May 14, 2023 · 20 comments
Closed

Pin does not exist #16

tuxcnc opened this issue May 14, 2023 · 20 comments

Comments

@tuxcnc
Copy link

tuxcnc commented May 14, 2023

I have LinuxCNC version 2.9 on Debian Bookworm, all (including LiteX-CNC) installed or compilled without warnings or errors.
Today I was try the 5a-75e-hello-gpio.json from examples.
I get:

user@debian:~/temp$ halrun -I test_gpio_blink.hal.
Note: Using POSIX realtime
litexcnc: Loading Litex CNC driver version 1.1.0
litexcnc: loading litexCNC etherbone driver version 0.02
litexcnc: Connecting to board at address: 192.168.0.99:1234.
litexcnc: Setting up modules...
litexcnc: - Watchdog
litexcnc: - Wallclock
litexcnc: - GPIO
litexcnc: - PWM
litexcnc: - Stepgen
litexcnc: - Encoder
litexcnc: Creating read and write buffers...
litexcnc: - Write buffer: 8 bytes)
litexcnc: - Read buffer: 16 bytes)
litexcnc: Exporting functions...
test_gpio_blink.hal:14: Pin 'test_PWM_GPIO.gpio.j1:1.out' does not exist
halcmd:.

I have no idea what happened...

@tuxcnc
Copy link
Author

tuxcnc commented May 14, 2023

I tried to reinstall litexcnc from sources :

root@debian:/usr/src/python3.11# pip uninstall litexcnc
Found existing installation: litexcnc 0.9.0a5
Uninstalling litexcnc-0.9.0a5:
Would remove:
/usr/local/bin/litexcnc
/usr/local/lib/python3.11/dist-packages/litexcnc-0.9.0a5.dist-info/*
/usr/local/lib/python3.11/dist-packages/litexcnc/*
Would not remove (might be manually added):
/usr/local/lib/python3.11/dist-packages/litexcnc/firmware/boards/rv901t.py.orig
Proceed (Y/n)?
Successfully uninstalled litexcnc-0.9.0a5
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
root@debian:/usr/src/python3.11# git clone https://github.com/Peter-van-Tol/LiteX-CNC.git
Klonowanie do „LiteX-CNC”...
remote: Enumerating objects: 1861, done.
remote: Counting objects: 100% (235/235), done.
remote: Compressing objects: 100% (51/51), done.
remote: Total 1861 (delta 198), reused 198 (delta 175), pack-reused 1626
Pobieranie obiektów: 100% (1861/1861), 4.60 MiB | 349.00 KiB/s, gotowe.
Rozwiązywanie delt: 100% (1204/1204), gotowe.
root@debian:/usr/src/python3.11# cd LiteX-CNC
root@debian:/usr/src/python3.11/LiteX-CNC# git checkout 11-add-external-extensions-to-litexcnc
branch '11-add-external-extensions-to-litexcnc' set up to track 'origin/11-add-external-extensions-to-litexcnc'.
Przełączono na nową gałąź „11-add-external-extensions-to-litexcnc”
root@debian:/usr/src/python3.11/LiteX-CNC# pip3 install ./ litexcnc[cli]
Processing /usr/src/python3.11/LiteX-CNC
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Requirement already satisfied: packaging<22.0,>=21.3 in /usr/local/lib/python3.11/dist-packages (from litexcnc==0.9.0a5) (21.3)
Requirement already satisfied: pydantic<2.0.0,>=1.10.2 in /usr/local/lib/python3.11/dist-packages (from litexcnc==0.9.0a5) (1.10.5)
Requirement already satisfied: chardet<6.0.0,>=5.0.0 in /usr/lib/python3/dist-packages (from litexcnc==0.9.0a5) (5.1.0)
Requirement already satisfied: click<9.0.0,>=8.1.3 in /usr/local/lib/python3.11/dist-packages (from litexcnc==0.9.0a5) (8.1.3)
Requirement already satisfied: meson<0.65.0,>=0.64.1 in /usr/local/lib/python3.11/dist-packages (from litexcnc==0.9.0a5) (0.64.1)
Requirement already satisfied: ninja<2.0.0,>=1.11.1 in /usr/local/lib/python3.11/dist-packages (from litexcnc==0.9.0a5) (1.11.1)
Requirement already satisfied: requests<3.0.0,>=2.28.1 in /usr/local/lib/python3.11/dist-packages (from litexcnc==0.9.0a5) (2.28.2)
Requirement already satisfied: yapps<3.0.0,>=2.2.0 in /usr/local/lib/python3.11/dist-packages (from litexcnc==0.9.0a5) (2.2.0)
Requirement already satisfied: pyparsing!=3.0.5,>=2.0.2 in /usr/lib/python3/dist-packages (from packaging<22.0,>=21.3->litexcnc==0.9.0a5) (3.0.9)
Requirement already satisfied: typing-extensions>=4.2.0 in /usr/local/lib/python3.11/dist-packages (from pydantic<2.0.0,>=1.10.2->litexcnc==0.9.0a5) (4.5.0)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/lib/python3/dist-packages (from requests<3.0.0,>=2.28.1->litexcnc==0.9.0a5) (3.0.1)
Requirement already satisfied: idna<4,>=2.5 in /usr/lib/python3/dist-packages (from requests<3.0.0,>=2.28.1->litexcnc==0.9.0a5) (3.3)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/lib/python3/dist-packages (from requests<3.0.0,>=2.28.1->litexcnc==0.9.0a5) (1.26.12)
Requirement already satisfied: certifi>=2017.4.17 in /usr/lib/python3/dist-packages (from requests<3.0.0,>=2.28.1->litexcnc==0.9.0a5) (2022.9.24)
Building wheels for collected packages: litexcnc
Building wheel for litexcnc (pyproject.toml) ... done
Created wheel for litexcnc: filename=litexcnc-0.9.0a5-py3-none-any.whl size=136421 sha256=888abfb01fc5b8cf01d185e5b5142905c9ca69143dc902605314128ae83077ce
Stored in directory: /root/.cache/pip/wheels/a9/39/f9/3b98c66169131c2dc9a00a5d24dde4237177a0f97e82966be3
Successfully built litexcnc
Installing collected packages: litexcnc
Successfully installed litexcnc-0.9.0a5
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
root@debian:/usr/src/python3.11/LiteX-CNC# litexcnc install_driver
INFO: Retrieving default driver files to compile...
Copying file 'watchdog.c'
Copying file 'wallclock.c'
Copying file 'litexcnc.c'
Copying file 'pos2vel.c'
Copying file 'litexcnc_encoder.c'
Copying file 'litexcnc_gpio.c'
Copying file 'litexcnc_stepgen.c'
Copying file 'litexcnc_pwm.c'
Copying file 'etherbone.c'
Copying file 'litexcnc_eth.c'
Copying file 'wallclock.h'
Copying file 'litexcnc.h'
Copying file 'watchdog.h'
Copying file 'pos2vel.h'
Copying file 'litexcnc_encoder.h'
Copying file 'litexcnc_stepgen.h'
Copying file 'litexcnc_gpio.h'
Copying file 'litexcnc_pwm.h'
Copying file 'etherbone.h'
Copying file 'litexcnc_eth.h'
INFO: Compiling LitexCNC driver...
Compiling realtime litexcnc.c
litexcnc.c: In function ‘litexcnc_register’:
litexcnc.c:512:1: warning: label ‘fail0’ defined but not used [-Wunused-label]
512 | fail0:
| ^~~~~
litexcnc.c: In function ‘register_module’:
litexcnc.c:539:22: error: ‘LINELEN’ undeclared (first use in this function)
539 | char module_path[LINELEN+1];
| ^~~~~~~
litexcnc.c:539:22: note: each undeclared identifier is reported only once for each function it appears in
litexcnc.c:548:10: warning: unused variable ‘register_name’ [-Wunused-variable]
548 | char register_name[LINELEN+1];
| ^~~~~~~~~~~~~
litexcnc.c:539:10: warning: unused variable ‘module_path’ [-Wunused-variable]
539 | char module_path[LINELEN+1];
| ^~~~~~~~~~~
litexcnc.c: In function ‘register_driver’:
litexcnc.c:574:22: error: ‘LINELEN’ undeclared (first use in this function)
574 | char driver_path[LINELEN+1];
| ^~~~~~~
litexcnc.c:583:10: warning: unused variable ‘register_name’ [-Wunused-variable]
583 | char register_name[LINELEN+1];
| ^~~~~~~~~~~~~
litexcnc.c:574:10: warning: unused variable ‘driver_path’ [-Wunused-variable]
574 | char driver_path[LINELEN+1];
| ^~~~~~~~~~~
make: *** [/usr/share/linuxcnc/Makefile.modinc:115: litexcnc.o] Błąd 1
Error: Compilation of the driver failed.

As you see, litexcnc driver is not compiling on Debian Bookworm.

@tuxcnc
Copy link
Author

tuxcnc commented May 15, 2023

I compilled LiteX-CNC again, but without " git checkout 11-add-external-extensions-to-litexcnc".
I installed litexcnc_driver without errors or warnings, but I get "Pin 'test_PWM_GPIO.gpio.j1:1.out' does not exist" when run test_gpio_blink.hal example.
No other messages, no idea what happened.

BTW. What Debian with what Linuxcnc is used for testing LiteX-CNC ?
I installed new system from linuxcnc-2.8.4-buster.iso, but it is RTAI, not RT-PREEMPT...

@kubabuda
Copy link

I bet its preeempt:

kernel-mode RTAI installation can not be used with Mesa Ethernet-interfaced cards.
https://linuxcnc.org/downloads/

@tuxcnc
Copy link
Author

tuxcnc commented May 15, 2023

I found.

After changing "net blink siggen.0.clock => test_PWM_GPIO.gpio.j1:1.out" to "net blink siggen.0.clock => test_PWM_GPIO.gpio.00.out" (00 instead j1:1) example works and I got "blink" signal on expected pin.
It seems cJSON can't read names, so procedure in gpio.c assigned numbers not names, I suppose.

@Peter-van-Tol
Copy link
Owner

Thanks for pointing this out. Here the documentation is lagging behind the development I'm afraid:

  • please use the Add (external) extensions to LitexCNC #11 branch
  • cJSON is not used anymore in the driver, the card contains all information on the loaded modules
  • to convert the numbers to their respective names, the build_firmware command can create a alias file for HAL.

With above mentioned branch, one can build the firmware as follows:

litexcnc build_firmware <config_file>.json --build -a 

In above command:

  • --build means it will be build. For this option is required to have the ECP5 toolchain (Yosys / OSSCAD) installed on your system
  • -a means an alias file will be created inside the build folder.

Also, the structure of the HAL file has changed a little as well, see example below:

# Connection to the board
loadrt litexcnc connections="eth:10.0.0.10"

The connections is a comma-separated list with connections (yes, you can add multiple cards if you would like, just name both cards differently in that case). The format of a connection string is eth:<IP-ADDRESS>:<PORT-NUMBER>. If you omit the port number, the default port number 1234 is used.

@tuxcnc
Copy link
Author

tuxcnc commented May 23, 2023

* please use the [Add (external) extensions to LitexCNC #11](https://github.com/Peter-van-Tol/LiteX-CNC/issues/11) branch

Used and compiled/install Litex-CNC with extensions.

Now, when try litexcnc --build, I got :

ValueError: Field board_type is requierd.

@tuxcnc
Copy link
Author

tuxcnc commented May 23, 2023

* please use the [Add (external) extensions to LitexCNC #11](https://github.com/Peter-van-Tol/LiteX-CNC/issues/11) branch

Yesterday you wrote post #17 (comment) with json config example.
There are "modules", "module_type", "instances", but there are NOT this words in example configs.
When I add line "board_type": "5A-75B v8.0", to my config file I got no ValueError: Field board_type is requierd. but KeyError: 'modules'

Did you change the syntax of the configuration files?

@tuxcnc
Copy link
Author

tuxcnc commented May 23, 2023

@ Author

I got it.
I wrote and compiled without errors :

{
"board_name": "pintest",
"board_type": "5A-75B v8.0",
"baseclass": "litexcnc.firmware.boards.ColorLight_5A_75B_V8_0",
"clock_frequency": 50000000,
"ethphy": {
"tx_delay": 0
},
"etherbone": {
"ip_address": "192.168.0.99",
"mac_address": "0x10e2d5000000"
},
"modules": [
{
"module_type": "stepgen",
"instances": [
{
"pins" : {
"stepgen_type": "step_dir_differential",
"step_pos_pin": "j3:6", "name": "_step_pos_pin",
"step_neg_pin": "j3:5", "name": "_step_neg_pin",
"dir_pos_pin": "j3:4", "name": "_dir_pos_pin",
"dir_neg_pin": "j3:2", "name": "_dir_neg_pin"
},
"soft_stop": true
}

        ]
    }
]

}

There are two problems.

  1. The alias.hal file is empty.

  2. I can't write gpio code, because I'm not clairvoyant.
    How do I know what else you've invented?

Could you write a short file with the new rules, but using all the modules.
Because now, without any documentation, Litex-CNC with extensions is completely useless...

@Peter-van-Tol
Copy link
Owner

Please fin below a working example of my lathe.

{
    "board_name": "EMCO5",
    "board_type": "5A-75E v6.0",
    "clock_frequency": 35000000,
    "ethphy": {
        "tx_delay": 0
    },
    "etherbone": {
        "ip_address": "10.0.0.10",
        "mac_address": "0x10e2d5000000"
    },
    "modules": [
        {
            "module_type": "gpio",
            "instances": [ 
                {"direction": "in",  "pin":"j1:0",  "name":"home-x"},
                {"direction": "in",  "pin":"j1:1",  "name":"home-z"},
                {"direction": "in",  "pin":"j1:5",  "name":"reset-feed-override"},
                {"direction": "in",  "pin":"j2:2",  "name":"reset-rapid-override"},
                {"direction": "in",  "pin":"j2:6",  "name":"reset-spindle-override"},
                {"direction": "in",  "pin":"j3:0",  "name":"axis-x-selected"},
                {"direction": "in",  "pin":"j3:1",  "name":"axis-z-selected"},
                {"direction": "in",  "pin":"j3:2"},
                {"direction": "in",  "pin":"j3:4"},
                {"direction": "in",  "pin":"j3:5"},
                {"direction": "in",  "pin":"j3:6"},
                {"direction": "in",  "pin":"j4:0",  "name":"speed1-selected"},
                {"direction": "in",  "pin":"j4:1",  "name":"speed2-selected"},
                {"direction": "in",  "pin":"j4:2",  "name":"speed3-selected"},
                {"direction": "in",  "pin":"j4:4",  "name":"start-button"},
                {"direction": "in",  "pin":"j4:5",  "name":"feed-hold-button"},
                {"direction": "in",  "pin":"j4:6",  "name":"stop-button"},
                {"direction": "in",  "pin":"j6:0"},
                {"direction": "in",  "pin":"j6:1"},
                {"direction": "in",  "pin":"j6:2"},
                {"direction": "in",  "pin":"j6:4",  "name":"alarm-spindle"},
                {"direction": "in",  "pin":"j6:5",  "name":"alarm-z"},
                {"direction": "in",  "pin":"j6:6",  "name":"alarm-x"},
                {"direction": "out", "pin":"j15:0", "name":"rapid-override-LED"},
                {"direction": "out", "pin":"j15:1", "name":"feed-override-LED"},
                {"direction": "out", "pin":"j15:2", "name":"spindle-override-LED"},
                {"direction": "out", "pin":"j15:4"},
                {"direction": "out", "pin":"j15:5"},
                {"direction": "out", "pin":"j15:6"},
                {"direction": "out",  "pin":"j16:0", "name":"stop-LED"},
                {"direction": "out",  "pin":"j16:1", "name":"pause-LED"},
                {"direction": "out",  "pin":"j16:2", "name":"start-LED"},
                {"direction": "out",  "pin":"j16:4"}
            ]
        }, {
            "module_type": "encoder",
            "instances": [
                {"name":"rapid-override",   "pin_A":"j1:4", "pin_B":"j1:2"},
                {"name":"feed-override",    "pin_A":"j1:6", "pin_B":"j2:1"},
                {"name":"spindle-override", "pin_A":"j2:5", "pin_B":"j2:4"},
                {"name":"mpg",              "pin_A":"j8:0", "pin_B":"j8:1"},
                {"name":"spindle",          "pin_A":"j8:4", "pin_B":"j8:5", "pin_Z":"j8:6"}
            ]
        }, {
            "module_type": "stepgen",
            "instances": [
                {
                    "pins" : {
                        "stepgen_type": "step_dir_differential",
                        "step_pos_pin": "j9:6",
                        "step_neg_pin": "j9:5",
                        "dir_pos_pin": "j9:4",
                        "dir_neg_pin": "j9:2"
                    },
                    "soft_stop": true
                }, {
                    "pins" : {
                        "stepgen_type": "step_dir_differential",
                        "step_pos_pin": "j9:1",
                        "step_neg_pin": "j9:0",
                        "dir_pos_pin": "j10:6",
                        "dir_neg_pin": "j10:5"
                    },
                    "soft_stop": true
                }, {
                    "pins" : {
                        "stepgen_type": "step_dir_differential",
                        "step_pos_pin": "j10:4",
                        "step_neg_pin": "j10:2",
                        "dir_pos_pin": "j10:1",
                        "dir_neg_pin": "j10:0"
                    },
                    "soft_stop": true
                }                
            ]
        }
    ]
}

You cannot rename a pin of the stepgen, but you can rename the stepgen instance, i.e:

{
...
"module_type": "stepgen",
"instances": [
{
"name": "x-axis", 
"pins" : {
"stepgen_type": "step_dir_differential",
"step_pos_pin": "j3:6", "name": "_step_pos_pin",
"step_neg_pin": "j3:5", "name": "_step_neg_pin",
"dir_pos_pin": "j3:4", "name": "_dir_pos_pin",
"dir_neg_pin": "j3:2", "name": "_dir_neg_pin"
},
"soft_stop": true
...
}

@tuxcnc
Copy link
Author

tuxcnc commented May 24, 2023

Please fin below a working example of my lathe.

Thanks, but the code below doesn't work.

TypeError: can only concatenate tuple (not "int") to tuple

       {
        "module_type": "encoder",
        "instances": [
            {"name":"rapid-override",   "pin_A":"j1:4", "pin_B":"j1:2"},
            {"name":"feed-override",    "pin_A":"j1:6", "pin_B":"j2:1"},
            {"name":"spindle-override", "pin_A":"j2:5", "pin_B":"j2:4"},
            {"name":"mpg",              "pin_A":"j8:0", "pin_B":"j8:1"},
            {"name":"spindle",          "pin_A":"j8:4", "pin_B":"j8:5", "pin_Z":"j8:6"}
        ]
    },

@Peter-van-Tol
Copy link
Owner

Can you provide a stacktrace? Judging from the error, it originates from Python.

Also, could you provide a pip freeze , as it might originate from a version being bumped somewhere.

@tuxcnc
Copy link
Author

tuxcnc commented May 25, 2023

Can you provide a stacktrace? Judging from the error, it originates from Python.

Also, could you provide a pip freeze , as it might originate from a version being bumped somewhere.

root@debian:~# cat /etc/debian_version
12.0

root@debian:~# python3 --version
Python 3.11.2

root@debian:~# pip freeze
bcrypt==3.2.2
beautifulsoup4==4.11.2
blinker==1.5
Brlapi==0.8.4
Brotli==1.0.9
certifi==2022.9.24
chardet==5.1.0
charset-normalizer==3.0.1
click==8.1.3
colorama==0.4.6
configobj==5.0.8
cryptography==38.0.4
cupshelpers==1.0
dbus-python==1.3.2
distro==1.8.0
distro-info==1.5
duplicity==0.8.22
fasteners==0.17.3
feedparser==6.0.10
fuse-python==1.0.5
future==0.18.2
galternatives==1.0.9
gpg==1.18.0
html5lib==1.1
httplib2==0.20.4
idna==3.3
importlib-metadata==6.6.0
invoke==2.0.0
lazr.restfulclient==0.14.5
lazr.uri==1.0.6
-e git+https://github.com/enjoy-digital/litedram.git@2b8af870c581f0d5da5ab2c67bb7188ff06f8f40#egg=litedram
-e git+https://github.com/enjoy-digital/liteeth.git@e2c1b81cd3f82f7637e9311980c8b414a2482846#egg=liteeth
-e git+https://github.com/enjoy-digital/liteiclink.git@a5c0433622da7a318aa7b0e2f360c2b1181ef9d6#egg=liteiclink
-e git+https://github.com/enjoy-digital/litejesd204b.git@2b07d2c61425c32318667822b34940947002c7f5#egg=litejesd204b
-e git+https://github.com/enjoy-digital/litepcie.git@4d9e07c73d7f24eabe3f3f8fe6a062b25be841cf#egg=litepcie
-e git+https://github.com/enjoy-digital/litesata.git@3a625fa6025e6b4ecc2cdded28e42a3e9f9356a8#egg=litesata
-e git+https://github.com/enjoy-digital/litescope.git@878f21a6472ce9f55aac2623a7810600d6281bab#egg=litescope
-e git+https://github.com/enjoy-digital/litesdcard.git@3750889e1473f649ff3d3142f3e3978c00cc53a8#egg=litesdcard
-e git+https://github.com/litex-hub/litespi.git@28a17d801d588f1cd43ac8c38b98faa603eba45e#egg=litespi
-e git+https://github.com/enjoy-digital/litex.git@a4cc859df0ea77f2a25c02aea3f3eb5d4329f4b6#egg=litex
-e git+https://github.com/litex-hub/litex-boards.git@28da4f83ebfbcdb41ec54b3f09dd0696537bb050#egg=litex_boards
litexcnc @ file:///usr/src/python3.11/LiteX-CNC
lockfile==0.12.2
louis==3.24.0
lxml==4.9.2
Mako==1.2.4.dev0
MarkupSafe==2.1.2
meson==0.64.1
meteo-qt==3.3
-e git+https://github.com/m-labs/migen.git@ccaee68e14d3636e1d8fb2e0864dd89b1b1f7384#egg=migen
monotonic==1.6
musicbrainzngs==0.7.1
mutagen==1.46.0
ninja==1.11.1
numpy==1.24.2
oauthlib==3.2.2
olefile==0.46
packaging==21.3
paramiko==2.12.0
pexpect==4.8.0
Pillow==9.4.0
ply==3.11
psutil==5.9.4
ptyprocess==0.7.0
pycairo==1.20.1
pycryptodomex==3.11.0
pycups==2.0.1
pycurl==7.45.2
pydantic==1.10.5
PyGObject==3.42.2
pyinotify==0.9.6
PyJWT==2.6.0
pylibacl==0.6.0
PyNaCl==1.5.0
PyOpenGL==3.1.6
pyparsing==3.0.9
PyQt5==5.15.9
PyQt5-sip==12.11.1
pyserial==3.5
PySimpleSOAP==1.16.2
pysmbc==1.0.23
python-apt==2.5.3
python-dateutil==2.8.2
python-debian==0.1.49
python-debianbts==4.0.1
python-espeak==0.5
python-pam==2.0.2
python-poppler-qt5==21.3.0
python-xlib==0.33
-e git+https://github.com/litex-hub/pythondata-cpu-lm32.git@594f2068e32a6faa84f05f9b443b58c3c4658113#egg=pythondata_cpu_lm32
-e git+https://github.com/litex-hub/pythondata-cpu-mor1kx.git@92628ec323dcce464185ad9e0f58a788c2be6989#egg=pythondata_cpu_mor1kx
-e git+https://github.com/litex-hub/pythondata-cpu-naxriscv.git@64b2fc1988b223f0ea6aa964201cd9da81ac0d14#egg=pythondata_cpu_naxriscv
-e git+https://github.com/litex-hub/pythondata-cpu-serv.git@cdede3b5e35e0c8c385ff10d783905d95cd864ab#egg=pythondata_cpu_serv
-e git+https://github.com/litex-hub/pythondata-cpu-vexriscv.git@a36d99eeea984c261e16b744fc1d287c81099777#egg=pythondata_cpu_vexriscv
-e git+https://github.com/litex-hub/pythondata-cpu-vexriscv-smp.git@98d6db6d44e0b543715ac3af4fb6fa415284fb24#egg=pythondata_cpu_vexriscv_smp
-e git+https://github.com/litex-hub/pythondata-misc-tapcfg.git@fbcb02422940bbb97c492f0c970959d262b33632#egg=pythondata_misc_tapcfg
-e git+https://github.com/litex-hub/pythondata-misc-usb_ohci.git@1f9c77314d3b91fe3194245c3e3197a075803199#egg=pythondata_misc_usb_ohci
-e git+https://github.com/litex-hub/pythondata-software-compiler_rt.git@fcb03245613ccf3079cc833a701f13d0beaae09d#egg=pythondata_software_compiler_rt
-e git+https://github.com/litex-hub/pythondata-software-picolibc.git@a5e11229885a87083ec54034f8d693ba52ea2718#egg=pythondata_software_picolibc
pytz==2022.7.1
pyxattr==0.8.1
pyxdg==0.28
PyYAML==6.0
QScintilla==2.13.3
quodlibet==4.5.0
reportbug==12.0.0
requests==2.28.2
setproctitle==1.3.1
sgmllib3k==1.0.0
sip==6.7.7
six==1.16.0
soupsieve==2.3.2
tinycss==0.4
tinycss2==1.2.1
toml==0.10.2
tornado==6.2
typing_extensions==4.5.0
urllib3==1.26.12
-e git+https://github.com/litex-hub/valentyusb.git@0b534ccfccfcdcb7a5db219743f0c0b20e5ec412#egg=valentyusb
wadllib==1.3.6
webencodings==0.5.1
websockets==10.4
xdg==5
xlrd==1.2.0
Yapps==2.2.0
Yapps2==2.2.1
yt-dlp==2023.3.4
zipp==3.15.0

root@debian:~# cat /root/litex-cnc/emco5/emco5.json
{
"board_name": "EMCO5",
"board_type": "5A-75E v6.0",
"clock_frequency": 35000000,
"ethphy": {
"tx_delay": 0
},
"etherbone": {
"ip_address": "10.0.0.10",
"mac_address": "0x10e2d5000000"
},
"modules": [
{
"module_type": "gpio",
"instances": [
{"direction": "in", "pin":"j1:0", "name":"home-x"},
{"direction": "in", "pin":"j1:1", "name":"home-z"},
{"direction": "in", "pin":"j1:5", "name":"reset-feed-override"},
{"direction": "in", "pin":"j2:2", "name":"reset-rapid-override"},
{"direction": "in", "pin":"j2:6", "name":"reset-spindle-override"},
{"direction": "in", "pin":"j3:0", "name":"axis-x-selected"},
{"direction": "in", "pin":"j3:1", "name":"axis-z-selected"},
{"direction": "in", "pin":"j3:2"},
{"direction": "in", "pin":"j3:4"},
{"direction": "in", "pin":"j3:5"},
{"direction": "in", "pin":"j3:6"},
{"direction": "in", "pin":"j4:0", "name":"speed1-selected"},
{"direction": "in", "pin":"j4:1", "name":"speed2-selected"},
{"direction": "in", "pin":"j4:2", "name":"speed3-selected"},
{"direction": "in", "pin":"j4:4", "name":"start-button"},
{"direction": "in", "pin":"j4:5", "name":"feed-hold-button"},
{"direction": "in", "pin":"j4:6", "name":"stop-button"},
{"direction": "in", "pin":"j6:0"},
{"direction": "in", "pin":"j6:1"},
{"direction": "in", "pin":"j6:2"},
{"direction": "in", "pin":"j6:4", "name":"alarm-spindle"},
{"direction": "in", "pin":"j6:5", "name":"alarm-z"},
{"direction": "in", "pin":"j6:6", "name":"alarm-x"},
{"direction": "out", "pin":"j15:0", "name":"rapid-override-LED"},
{"direction": "out", "pin":"j15:1", "name":"feed-override-LED"},
{"direction": "out", "pin":"j15:2", "name":"spindle-override-LED"},
{"direction": "out", "pin":"j15:4"},
{"direction": "out", "pin":"j15:5"},
{"direction": "out", "pin":"j15:6"},
{"direction": "out", "pin":"j16:0", "name":"stop-LED"},
{"direction": "out", "pin":"j16:1", "name":"pause-LED"},
{"direction": "out", "pin":"j16:2", "name":"start-LED"},
{"direction": "out", "pin":"j16:4"}
]
}, {
"module_type": "encoder",
"instances": [
{"name":"rapid-override", "pin_A":"j1:4", "pin_B":"j1:2"},
{"name":"feed-override", "pin_A":"j1:6", "pin_B":"j2:1"},
{"name":"spindle-override", "pin_A":"j2:5", "pin_B":"j2:4"},
{"name":"mpg", "pin_A":"j8:0", "pin_B":"j8:1"},
{"name":"spindle", "pin_A":"j8:4", "pin_B":"j8:5", "pin_Z":"j8:6"}
]
}, {
"module_type": "stepgen",
"instances": [
{
"pins" : {
"stepgen_type": "step_dir_differential",
"step_pos_pin": "j9:6",
"step_neg_pin": "j9:5",
"dir_pos_pin": "j9:4",
"dir_neg_pin": "j9:2"
},
"soft_stop": true
}, {
"pins" : {
"stepgen_type": "step_dir_differential",
"step_pos_pin": "j9:1",
"step_neg_pin": "j9:0",
"dir_pos_pin": "j10:6",
"dir_neg_pin": "j10:5"
},
"soft_stop": true
}, {
"pins" : {
"stepgen_type": "step_dir_differential",
"step_pos_pin": "j10:4",
"step_neg_pin": "j10:2",
"dir_pos_pin": "j10:1",
"dir_neg_pin": "j10:0"
},
"soft_stop": true
}
]
}
]
}

root@debian:/litex-cnc/emco5#
root@debian:
/litex-cnc# litexcnc build_firmware emco5/emco5.json --build -a
INFO:SoC: __ _ __ _ __
INFO:SoC: / / () /___ | |//
INFO:SoC: / /__/ / __/ -
)> <
INFO:SoC: ///_/_//|_|
INFO:SoC: Build your hardware, easily!
INFO:SoC:--------------------------------------------------------------------------------
INFO:SoC:Creating SoC... (2023-05-25 22:44:54)
INFO:SoC:--------------------------------------------------------------------------------
INFO:SoC:FPGA device : LFE5U-25F-6BG256C.
INFO:SoC:System clock: 35.000MHz.
INFO:SoCBusHandler:Creating Bus Handler...
INFO:SoCBusHandler:32-bit wishbone Bus, 4.0GiB Address Space.
INFO:SoCBusHandler:Adding reserved Bus Regions...
INFO:SoCBusHandler:Bus Handler created.
INFO:SoCCSRHandler:Creating CSR Handler...
INFO:SoCCSRHandler:32-bit CSR Bus, 32-bit Aligned, 16.0KiB Address Space, 2048B Paging, big Ordering (Up to 32 Locations).
INFO:SoCCSRHandler:Adding reserved CSRs...
INFO:SoCCSRHandler:CSR Handler created.
INFO:SoCIRQHandler:Creating IRQ Handler...
INFO:SoCIRQHandler:IRQ Handler (up to 32 Locations).
INFO:SoCIRQHandler:Adding reserved IRQs...
INFO:SoCIRQHandler:IRQ Handler created.
INFO:SoC:--------------------------------------------------------------------------------
INFO:SoC:Initial SoC:
INFO:SoC:--------------------------------------------------------------------------------
INFO:SoC:32-bit wishbone Bus, 4.0GiB Address Space.
INFO:SoC:32-bit CSR Bus, 32-bit Aligned, 16.0KiB Address Space, 2048B Paging, big Ordering (Up to 32 Locations).
INFO:SoC:IRQ Handler (up to 32 Locations).
INFO:SoC:--------------------------------------------------------------------------------
INFO:SoC:Controller ctrl added.
INFO:SoC:CPU None added.
INFO:SoC:CPU None adding IO Region 0 at 0x00000000 (Size: 0x100000000).
INFO:SoCBusHandler:io0 Region added at Origin: 0x00000000, Size: 0x100000000, Mode: RW, Cached: False Linker: False.
INFO:ECP5PLL:Creating ECP5PLL.
INFO:ECP5PLL:Registering Single Ended ClkIn of 25.00MHz.
INFO:ECP5PLL:Creating ClkOut0 sys of 35.00MHz (+-10000.00ppm).
INFO:ECP5PLL:Creating ClkOut1 sys_ps of 35.00MHz (+-10000.00ppm).
INFO:SoCBusHandler:master0 added as Bus Master.
INFO:ECP5PLL:Config:
clki_div : 1
clkfb : 2
clko0_freq : 35.00MHz
clko0_div : 15
clko0_phase: 0.00°
clko1_freq : 35.00MHz
clko1_div : 15
clko1_phase: 180.00°
clko2_div : 1
vco : 525.00MHz
clkfb_div : 21
INFO:SoC:CSR Bridge csr added.
INFO:SoCBusHandler:csr Region added at Origin: 0x00000000, Size: 0x00010000, Mode: RW, Cached: False Linker: False.
INFO:SoCBusHandler:csr added as Bus Slave.
INFO:SoCCSRHandler:csr added as CSR Master.
INFO:SoCBusHandler:Interconnect: InterconnectPointToPoint (1 <-> 1).
INFO:SoCCSRHandler:MMIO_inst CSR allocated at Location 0.
Traceback (most recent call last):
File "/usr/local/bin/litexcnc", line 8, in
sys.exit(cli())
^^^^^
File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 1130, in call
return self.main(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 1055, in main
rv = self.invoke(ctx)
^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 1657, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 1404, in invoke
return ctx.invoke(self.callback, **ctx.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 760, in invoke
return __callback(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/litexcnc/cli/build_firmware.py", line 58, in cli
builder.build(run=build)
File "/opt/litex/litex/litex/soc/integration/builder.py", line 317, in build
self.soc.finalize()
File "/opt/litex/migen/migen/fhdl/module.py", line 157, in finalize
self.do_finalize(*args, **kwargs)
File "/opt/litex/litex/litex/soc/integration/soc_core.py", line 286, in do_finalize
SoC.do_finalize(self)
File "/opt/litex/litex/litex/soc/integration/soc.py", line 1117, in do_finalize
self.submodules.csr_bankarray = csr_bus.CSRBankArray(self,
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/litex/litex/litex/soc/interconnect/csr_bus.py", line 215, in init
self.scan(ifargs, ifkwargs)
File "/opt/litex/litex/litex/soc/interconnect/csr_bus.py", line 252, in scan
rmap = CSRBank(csrs, mapaddr,
^^^^^^^^^^^^^^^^^^^^^^
File "/opt/litex/litex/litex/soc/interconnect/csr_bus.py", line 177, in init
csr.GenericBank.init(self,
File "/opt/litex/litex/litex/soc/interconnect/csr.py", line 512, in init
c.finalize(busword, ordering)
File "/opt/litex/migen/migen/fhdl/module.py", line 157, in finalize
self.do_finalize(*args, **kwargs)
File "/opt/litex/litex/litex/soc/interconnect/csr.py", line 308, in do_finalize
nwords = (self.size + busword - 1)//busword
~~~~~~~~~~^~~~~~~~~
TypeError: can only concatenate tuple (not "int") to tuple

@tuxcnc
Copy link
Author

tuxcnc commented May 25, 2023

@Peter-van-Tol
I'm sorry, the "Add code" not works as expected, I don't know why...
The compiled source is copy/paste from your post.
I can compile it after removing "encoder" section, but compilation failed with this fragment.

@tuxcnc
Copy link
Author

tuxcnc commented May 28, 2023

I tried Debian 10 with Python 3.7 (installed today).
The same "TypeError: can only concatenate tuple (not "int") to tuple".

@Peter-van-Tol
Copy link
Owner

All tests are passing here (using the example as posted above). Is suspect an update somewhere, starting to update all packages.

INFO:SoC:        __   _ __      _  __  
INFO:SoC:       / /  (_) /____ | |/_/  
INFO:SoC:      / /__/ / __/ -_)>  <    
INFO:SoC:     /____/_/\__/\__/_/|_|  
INFO:SoC:  Build your hardware, easily!
INFO:SoC:--------------------------------------------------------------------------------
INFO:SoC:Creating SoC... (2023-06-04 19:27:27)
INFO:SoC:--------------------------------------------------------------------------------
INFO:SoC:FPGA device : LFE5U-25F-6BG256C.
INFO:SoC:System clock: 35.000MHz.
INFO:SoCBusHandler:Creating Bus Handler...
INFO:SoCBusHandler:32-bit wishbone Bus, 4.0GiB Address Space.
INFO:SoCBusHandler:Adding reserved Bus Regions...
INFO:SoCBusHandler:Bus Handler created.
INFO:SoCCSRHandler:Creating CSR Handler...
INFO:SoCCSRHandler:32-bit CSR Bus, 32-bit Aligned, 16.0KiB Address Space, 2048B Paging, big Ordering (Up to 32 Locations).
INFO:SoCCSRHandler:Adding reserved CSRs...
INFO:SoCCSRHandler:CSR Handler created.
INFO:SoCIRQHandler:Creating IRQ Handler...
INFO:SoCIRQHandler:IRQ Handler (up to 32 Locations).
INFO:SoCIRQHandler:Adding reserved IRQs...
INFO:SoCIRQHandler:IRQ Handler created.
INFO:SoC:--------------------------------------------------------------------------------
INFO:SoC:Initial SoC:
INFO:SoC:--------------------------------------------------------------------------------
INFO:SoC:32-bit wishbone Bus, 4.0GiB Address Space.
INFO:SoC:32-bit CSR Bus, 32-bit Aligned, 16.0KiB Address Space, 2048B Paging, big Ordering (Up to 32 Locations).
INFO:SoC:IRQ Handler (up to 32 Locations).
INFO:SoC:--------------------------------------------------------------------------------
INFO:SoC:Controller ctrl added.
INFO:SoC:CPU None added.
INFO:SoC:CPU None adding IO Region 0 at 0x00000000 (Size: 0x100000000).
INFO:SoCBusHandler:io0 Region added at Origin: 0x00000000, Size: 0x100000000, Mode: RW, Cached: False Linker: False.
INFO:ECP5PLL:Creating ECP5PLL.
INFO:ECP5PLL:Registering Single Ended ClkIn of 25.00MHz.
INFO:ECP5PLL:Creating ClkOut0 sys of 35.00MHz (+-10000.00ppm).
INFO:ECP5PLL:Creating ClkOut1 sys_ps of 35.00MHz (+-10000.00ppm).
INFO:SoCBusHandler:master0 added as Bus Master.
INFO:ECP5PLL:Config:
clki_div   : 1
clkfb      : 2
clko0_freq : 35.00MHz
clko0_div  : 15
clko0_phase: 0.00°
clko1_freq : 35.00MHz
clko1_div  : 15
clko1_phase: 180.00°
clko2_div  : 1
vco        : 525.00MHz
clkfb_div  : 21
INFO:SoC:CSR Bridge csr added.
INFO:SoCBusHandler:csr Region added at Origin: 0x00000000, Size: 0x00010000, Mode: RW, Cached: False Linker: False.
INFO:SoCBusHandler:csr added as Bus Slave.
INFO:SoCCSRHandler:csr added as CSR Master.
INFO:SoCBusHandler:Interconnect: InterconnectPointToPoint (1 <-> 1).
INFO:SoCCSRHandler:MMIO_inst CSR allocated at Location 0.
INFO:SoCCSRHandler:ctrl CSR allocated at Location 1.
INFO:SoCCSRHandler:ethphy CSR allocated at Location 2.
INFO:SoCCSRHandler:identifier_mem CSR allocated at Location 3.
INFO:SoC:--------------------------------------------------------------------------------
INFO:SoC:Finalized SoC:
INFO:SoC:--------------------------------------------------------------------------------
INFO:SoC:32-bit wishbone Bus, 4.0GiB Address Space.
IO Regions: (1)
io0                 : Origin: 0x00000000, Size: 0x100000000, Mode: RW, Cached: False Linker: False
Bus Regions: (1)
csr                 : Origin: 0x00000000, Size: 0x00010000, Mode: RW, Cached: False Linker: False
Bus Masters: (1)
- master0
Bus Slaves: (1)
- csr
INFO:SoC:32-bit CSR Bus, 32-bit Aligned, 16.0KiB Address Space, 2048B Paging, big Ordering (Up to 32 Locations).
CSR Locations: (4)
- MMIO_inst      : 0
- ctrl           : 1
- ethphy         : 2
- identifier_mem : 3
INFO:SoC:IRQ Handler (up to 32 Locations).
INFO:SoC:--------------------------------------------------------------------------------
INFO: Firmware created in test

@tuxcnc
Copy link
Author

tuxcnc commented Jun 4, 2023

All tests are passing here (using the example as posted above).

What Linux are you using?

@Peter-van-Tol
Copy link
Owner

Mij environment which I use to build the firmware is a Docker container:
Debian Stretch (9) - 5.10.102.1-microsoft-standard-WSL2
Python 3.8

For reference, here is a list of packages installed (pip freeze):

alabaster==0.7.13
Babel==2.11.0
certifi==2022.12.7
chardet==5.1.0
charset-normalizer==3.0.1
click==8.1.3
colorama==0.4.6
docutils==0.18.1
idna==3.4
imagesize==1.4.1
importlib-metadata==6.0.0
Jinja2==3.1.2
-e git+https://github.com/enjoy-digital/litedram.git@2b8af870c581f0d5da5ab2c67bb7188ff06f8f40#egg=litedram
-e git+https://github.com/enjoy-digital/liteeth.git@e2c1b81cd3f82f7637e9311980c8b414a2482846#egg=liteeth
-e git+https://github.com/enjoy-digital/liteiclink.git@a5c0433622da7a318aa7b0e2f360c2b1181ef9d6#egg=liteiclink
-e git+https://github.com/enjoy-digital/litejesd204b.git@2b07d2c61425c32318667822b34940947002c7f5#egg=litejesd204b
-e git+https://github.com/enjoy-digital/litepcie.git@4d9e07c73d7f24eabe3f3f8fe6a062b25be841cf#egg=litepcie
-e git+https://github.com/enjoy-digital/litesata.git@3a625fa6025e6b4ecc2cdded28e42a3e9f9356a8#egg=litesata
-e git+https://github.com/enjoy-digital/litescope.git@878f21a6472ce9f55aac2623a7810600d6281bab#egg=litescope
-e git+https://github.com/enjoy-digital/litesdcard.git@3750889e1473f649ff3d3142f3e3978c00cc53a8#egg=litesdcard
-e git+https://github.com/litex-hub/litespi.git@28a17d801d588f1cd43ac8c38b98faa603eba45e#egg=litespi
-e git+https://github.com/enjoy-digital/litex.git@a4cc859df0ea77f2a25c02aea3f3eb5d4329f4b6#egg=litex
-e git+https://github.com/litex-hub/litex-boards.git@28da4f83ebfbcdb41ec54b3f09dd0696537bb050#egg=litex_boards
-e git+https://github.com/Peter-van-Tol/LiteX-CNC.git@362c4818db481080efddd79b68dd83c95c991a0e#egg=litexcnc
MarkupSafe==2.1.2
meson==0.64.1
-e git+https://github.com/m-labs/migen.git@ccaee68e14d3636e1d8fb2e0864dd89b1b1f7384#egg=migen
ninja==1.11.1
packaging==21.3
pydantic==1.10.5
Pygments==2.14.0
pyparsing==3.0.9
pyserial==3.5
-e git+https://github.com/litex-hub/pythondata-cpu-lm32.git@594f2068e32a6faa84f05f9b443b58c3c4658113#egg=pythondata_cpu_lm32
-e git+https://github.com/litex-hub/pythondata-cpu-mor1kx.git@92628ec323dcce464185ad9e0f58a788c2be6989#egg=pythondata_cpu_mor1kx
-e git+https://github.com/litex-hub/pythondata-cpu-naxriscv.git@1124b408a4af609494ad4faa380e737948e8b74c#egg=pythondata_cpu_naxriscv
-e git+https://github.com/litex-hub/pythondata-cpu-serv.git@cdede3b5e35e0c8c385ff10d783905d95cd864ab#egg=pythondata_cpu_serv
-e git+https://github.com/litex-hub/pythondata-cpu-vexriscv.git@e75700dff2ab9662f3e26dd89ab59a5f6da65687#egg=pythondata_cpu_vexriscv
-e git+https://github.com/litex-hub/pythondata-cpu-vexriscv-smp.git@e8ce95bbff2742226e838a37a88e4153bd04178a#egg=pythondata_cpu_vexriscv_smp
-e git+https://github.com/litex-hub/pythondata-misc-tapcfg.git@fbcb02422940bbb97c492f0c970959d262b33632#egg=pythondata_misc_tapcfg
-e git+https://github.com/litex-hub/pythondata-misc-usb_ohci.git@1f9c77314d3b91fe3194245c3e3197a075803199#egg=pythondata_misc_usb_ohci
-e git+https://github.com/litex-hub/pythondata-software-compiler_rt.git@fcb03245613ccf3079cc833a701f13d0beaae09d#egg=pythondata_software_compiler_rt
-e git+https://github.com/litex-hub/pythondata-software-picolibc.git@a5e11229885a87083ec54034f8d693ba52ea2718#egg=pythondata_software_picolibc
pytz==2022.7.1
PyYAML==6.0
requests==2.28.2
snowballstemmer==2.2.0
Sphinx==5.3.0
sphinx-rtd-theme==1.2.0
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jquery==2.0.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
typing_extensions==4.5.0
urllib3==1.26.14
-e git+https://github.com/litex-hub/valentyusb.git@0b534ccfccfcdcb7a5db219743f0c0b20e5ec412#egg=valentyusb
Yapps==2.2.0
zipp==3.15.0

The most obvious difference between the systems are the following entries:

  • pythondata-cpu-naxriscv -> newer version
  • pythondata-cpu-serv -> newer version
  • pythondata-cpu-vexriscv -> newer version
  • pythondata-cpu-vexriscv-smp -> newer version

however, I don't think it is due to one of these.

I can see that you installed Litex-CNC from file, so I cannot verify of this installation has been correct and whether that version is up-to-date.

The supported Python version are 3.8 to 3.10 (3.11 is untested so far), so it should not have been possible to install it on Debian 10 with Python 3.7 installed. Have to look into how pip allows this to happen in your case.

@tuxcnc
Copy link
Author

tuxcnc commented Jun 7, 2023

I tried at Xubuntu 20.04 (Python 3.8) and it doesn't work either.
I give up.
The program, which works only on one computer with exotic and not available for others software, is completely useless, and its writing is a waste of time.

@Peter-van-Tol
Copy link
Owner

I can understand the way you are feeling when things are not working. HOWEVER: the way you respond in this issue and the other issues is disrespectful in my opinion and does not reflect the willingness of others to help you with your problem. If you want to have all solutions handed over on a silver platter, please feel free to buy a commercial off the shelve product.

@Peter-van-Tol
Copy link
Owner

Side note on the error:
TypeError: can only concatenate tuple (not "int") to tuple

This error is produced due to signed integers on the FPGA. It took a while to debug this problem, because it did not occur on all kernels. It did not occur on the WSL2 kernel I use for developing this project. Yesterday I finally received my RPi4 and moved development to that board (i.e. all test are now running on the Rpi4). Finally I could reproduce the error.

It is solved in #11

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants