- Hardware & Machines
- Computers and Hardware
- LinuxCNC-RIO - RealtimeIO for LinuxCNC based on FPGA (ICE40 / ECP5)
LinuxCNC-RIO - RealtimeIO for LinuxCNC based on FPGA (ICE40 / ECP5)
- DMNZ
- Offline
- New Member
-
Less
More
- Posts: 11
- Thank you received: 3
19 Jun 2025 11:34 #330497
by DMNZ
Replied by DMNZ on topic LinuxCNC-RIO - RealtimeIO for LinuxCNC based on FPGA (ICE40 / ECP5)
wow, great answer thank you. i was close in my thoughts, since there is no cpu and in rio.c you compile riocomp i thought that there must be something like fixed data frame structure adjusted for each config, but you made it very clear.
do you do anything about noise? like CRC (checksum) maybe for each frame in case it gets corrupted?
do you do anything about noise? like CRC (checksum) maybe for each frame in case it gets corrupted?
Please Log in or Create an account to join the conversation.
- meister
- Away
- Platinum Member
-
Less
More
- Posts: 569
- Thank you received: 348
19 Jun 2025 17:42 #330523
by meister
Replied by meister on topic LinuxCNC-RIO - RealtimeIO for LinuxCNC based on FPGA (ICE40 / ECP5)
no checksum for SPI, it's only for short distance. only the UDP and RS485/RS422 connections have checksum
Please Log in or Create an account to join the conversation.
- meister
- Away
- Platinum Member
-
Less
More
- Posts: 569
- Thank you received: 348
20 Jun 2025 06:22 #330550
by meister
Replied by meister on topic LinuxCNC-RIO - RealtimeIO for LinuxCNC based on FPGA (ICE40 / ECP5)
Here is an output from the generator using the Tangbob configuration as an example:
github.com/multigcs/riocore/tree/dev/doc/example-output/Tangbob
and here is a kind of documentation of the generated gateware:
www.multixmedia.org/Tangbob-Gateware/
github.com/multigcs/riocore/tree/dev/doc/example-output/Tangbob
and here is a kind of documentation of the generated gateware:
www.multixmedia.org/Tangbob-Gateware/
Please Log in or Create an account to join the conversation.
- meister
- Away
- Platinum Member
-
Less
More
- Posts: 569
- Thank you received: 348
20 Jun 2025 07:12 - 20 Jun 2025 07:12 #330552
by meister
Replied by meister on topic LinuxCNC-RIO - RealtimeIO for LinuxCNC based on FPGA (ICE40 / ECP5)
here i can also show the structure of the frames or the rio.v:
this is the 'top' verilog module, the main module:
github.com/multigcs/riocore/blob/dev/doc...ngbob/Gateware/rio.v
there is a block in which the RX frames are split into individual 'output signals':
and a block in which the ‘input signals’ are assembled to the TX frame:
in the case of the Tangbob, the two frames ‘rx_data’ and ‘tx_data’ are passed to the w5500 module, which then takes care of the data exchange with the host computer:
Now let's take a look at the signals from one of the Stepdir module instances:
the input/output signals have the following naming scheme: VAR[DIRECTION][SIZE]_[MODULE_INSTANCE]_[SIGNALNAME]
* VAROUT32_STEPDIR0_VELOCITY : a 32 bit output value for the specified velocity (steprate)
* VAROUT1_STEPDIR0_ENABLE : a 1 bit output value to activate the stepper (enable signal)
* VARIN32_STEPDIR0_POSITION : a 32 bit input value to return the current position (step counter)
the pin signals have the following naming scheme: PIN[DIRECTION]_[MODULE_INSTANCE]_[PINNAME]
however, they can also have suffixes, such as. _RAW / _INVERTED / _DEBOUNCED / ...
this is due to the modifiers pipeline that can be configured for each pin.
this is the 'top' verilog module, the main module:
github.com/multigcs/riocore/blob/dev/doc...ngbob/Gateware/rio.v
there is a block in which the RX frames are split into individual 'output signals':
// PC -> FPGA (330 + FILL)
// assign header_rx = {rx_data[327:320], rx_data[335:328], rx_data[343:336], rx_data[351:344]};
assign VAROUT128_MODBUS0_TXDATA = {rx_data[199:192], rx_data[207:200], rx_data[215:208], rx_data[223:216], rx_data[231:224], rx_data[239:232], rx_data[247:240], rx_data[255:248], rx_data[263:256], rx_data[271:264], rx_data[279:272], rx_data[287:280], rx_data[295:288], rx_data[303:296], rx_data[311:304], rx_data[319:312]};
assign VAROUT32_PWMOUT0_DTY = {rx_data[167:160], rx_data[175:168], rx_data[183:176], rx_data[191:184]};
assign VAROUT32_STEPDIR0_VELOCITY = {rx_data[135:128], rx_data[143:136], rx_data[151:144], rx_data[159:152]};
assign VAROUT32_STEPDIR1_VELOCITY = {rx_data[103:96], rx_data[111:104], rx_data[119:112], rx_data[127:120]};
assign VAROUT32_STEPDIR2_VELOCITY = {rx_data[71:64], rx_data[79:72], rx_data[87:80], rx_data[95:88]};
assign VAROUT32_STEPDIR3_VELOCITY = {rx_data[39:32], rx_data[47:40], rx_data[55:48], rx_data[63:56]};
assign VAROUT1_WLED0_0_GREEN = {rx_data[31]};
assign VAROUT1_WLED0_0_BLUE = {rx_data[30]};
assign VAROUT1_WLED0_0_RED = {rx_data[29]};
assign VAROUT1_BITOUT0_BIT = {rx_data[28]};
assign VAROUT1_BITOUT1_BIT = {rx_data[27]};
assign VAROUT1_PWMOUT0_ENABLE = {rx_data[26]};
assign VAROUT1_STEPDIR0_ENABLE = {rx_data[25]};
assign VAROUT1_STEPDIR1_ENABLE = {rx_data[24]};
assign VAROUT1_STEPDIR2_ENABLE = {rx_data[23]};
assign VAROUT1_STEPDIR3_ENABLE = {rx_data[22]};
// assign FILL = rx_data[21:0];
and a block in which the ‘input signals’ are assembled to the TX frame:
// FPGA -> PC (349 + FILL)
assign tx_data = {
header_tx[7:0], header_tx[15:8], header_tx[23:16], header_tx[31:24],
timestamp[7:0], timestamp[15:8], timestamp[23:16], timestamp[31:24],
MULTIPLEXED_INPUT_VALUE[7:0], MULTIPLEXED_INPUT_VALUE[15:8],
MULTIPLEXED_INPUT_ID[7:0],
VARIN128_MODBUS0_RXDATA[7:0], VARIN128_MODBUS0_RXDATA[15:8], VARIN128_MODBUS0_RXDATA[23:16], VARIN128_MODBUS0_RXDATA[31:24], VARIN128_MODBUS0_RXDATA[39:32], VARIN128_MODBUS0_RXDATA[47:40], VARIN128_MODBUS0_RXDATA[55:48], VARIN128_MODBUS0_RXDATA[63:56], VARIN128_MODBUS0_RXDATA[71:64], VARIN128_MODBUS0_RXDATA[79:72], VARIN128_MODBUS0_RXDATA[87:80], VARIN128_MODBUS0_RXDATA[95:88], VARIN128_MODBUS0_RXDATA[103:96], VARIN128_MODBUS0_RXDATA[111:104], VARIN128_MODBUS0_RXDATA[119:112], VARIN128_MODBUS0_RXDATA[127:120],
VARIN32_STEPDIR0_POSITION[7:0], VARIN32_STEPDIR0_POSITION[15:8], VARIN32_STEPDIR0_POSITION[23:16], VARIN32_STEPDIR0_POSITION[31:24],
VARIN32_STEPDIR1_POSITION[7:0], VARIN32_STEPDIR1_POSITION[15:8], VARIN32_STEPDIR1_POSITION[23:16], VARIN32_STEPDIR1_POSITION[31:24],
VARIN32_STEPDIR2_POSITION[7:0], VARIN32_STEPDIR2_POSITION[15:8], VARIN32_STEPDIR2_POSITION[23:16], VARIN32_STEPDIR2_POSITION[31:24],
VARIN32_STEPDIR3_POSITION[7:0], VARIN32_STEPDIR3_POSITION[15:8], VARIN32_STEPDIR3_POSITION[23:16], VARIN32_STEPDIR3_POSITION[31:24],
VARIN1_BITIN0_BIT,
VARIN1_BITIN1_BIT,
VARIN1_BITIN2_BIT,
VARIN1_BITIN3_BIT,
VARIN1_BITIN4_BIT,
3'd0
};
in the case of the Tangbob, the two frames ‘rx_data’ and ‘tx_data’ are passed to the w5500 module, which then takes care of the data exchange with the host computer:
w5500 #(
.MAC_ADDR({8'hAA, 8'hAF, 8'hFA, 8'hCC, 8'hE3, 8'h1C}),
.IP_ADDR({8'd192, 8'd168, 8'd10, 8'd194}),
.NET_MASK({8'd255, 8'd255, 8'd255, 8'd0}),
.GW_ADDR({8'd192, 8'd168, 8'd10, 8'd1}),
.PORT(2390),
.BUFFER_SIZE(BUFFER_SIZE),
.MSGID(32'h74697277),
.DIVIDER(0)
) w55000 (
.clk(sysclk),
.mosi(PINOUT_W55000_MOSI_RAW),
.miso(PININ_W55000_MISO),
.sclk(PINOUT_W55000_SCLK_RAW),
.sel(PINOUT_W55000_SEL_RAW),
.intr(1'd0),
.rx_data(rx_data),
.tx_data(tx_data),
.sync(INTERFACE_SYNC)
);
Now let's take a look at the signals from one of the Stepdir module instances:
the input/output signals have the following naming scheme: VAR[DIRECTION][SIZE]_[MODULE_INSTANCE]_[SIGNALNAME]
* VAROUT32_STEPDIR0_VELOCITY : a 32 bit output value for the specified velocity (steprate)
* VAROUT1_STEPDIR0_ENABLE : a 1 bit output value to activate the stepper (enable signal)
* VARIN32_STEPDIR0_POSITION : a 32 bit input value to return the current position (step counter)
stepdir #(
.PULSE_LEN(108),
.DIR_DELAY(18)
) stepdir0 (
.clk(sysclk),
.step(PINOUT_STEPDIR0_STEP_RAW),
.dir(PINOUT_STEPDIR0_DIR_RAW),
.velocity(VAROUT32_STEPDIR0_VELOCITY),
.enable(VAROUT1_STEPDIR0_ENABLE & ~ERROR),
.position(VARIN32_STEPDIR0_POSITION)
);
the pin signals have the following naming scheme: PIN[DIRECTION]_[MODULE_INSTANCE]_[PINNAME]
however, they can also have suffixes, such as. _RAW / _INVERTED / _DEBOUNCED / ...
this is due to the modifiers pipeline that can be configured for each pin.
Last edit: 20 Jun 2025 07:12 by meister.
Please Log in or Create an account to join the conversation.
- Hardware & Machines
- Computers and Hardware
- LinuxCNC-RIO - RealtimeIO for LinuxCNC based on FPGA (ICE40 / ECP5)
Time to create page: 0.147 seconds