1
0
Fork 0
This commit is contained in:
rahix 2024-05-31 20:46:43 +02:00
commit b53b37845d
4 changed files with 544 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

325
Cargo.lock generated Normal file
View file

@ -0,0 +1,325 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "anstream"
version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
[[package]]
name = "anstyle-parse"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
dependencies = [
"anstyle",
"windows-sys",
]
[[package]]
name = "bitflags"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "bitvec"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
dependencies = [
"funty",
"radium",
"tap",
"wyz",
]
[[package]]
name = "colorchoice"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
[[package]]
name = "env_filter"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea"
dependencies = [
"log",
"regex",
]
[[package]]
name = "env_logger"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9"
dependencies = [
"anstream",
"anstyle",
"env_filter",
"humantime",
"log",
]
[[package]]
name = "funty"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
[[package]]
name = "libc"
version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "log"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "managed"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
[[package]]
name = "memchr"
version = "2.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
[[package]]
name = "process-image"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5af8362e66e347fba28d90c6569235402c7f1b7e41a4a67ed85ca29efade4b0"
[[package]]
name = "profirust"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "815ad0b21c66b9772b138d0040b36bc63fc893b780658eabceba417f9ba0d1b8"
dependencies = [
"bitflags 2.5.0",
"bitvec",
"libc",
"log",
"managed",
"rs485",
]
[[package]]
name = "radium"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]]
name = "regex"
version = "1.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
[[package]]
name = "rs485"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7491424ed2e9f9fa71ce0f6ec1df2aa6780297047803c4c468e5cb7a89ae835a"
dependencies = [
"bitflags 0.9.1",
"libc",
]
[[package]]
name = "tap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "test-jig-software"
version = "0.1.0"
dependencies = [
"env_logger",
"log",
"process-image",
"profirust",
]
[[package]]
name = "utf8parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
[[package]]
name = "windows_i686_gnu"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
[[package]]
name = "windows_i686_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
[[package]]
name = "wyz"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
dependencies = [
"tap",
]

10
Cargo.toml Normal file
View file

@ -0,0 +1,10 @@
[package]
name = "test-jig-software"
version = "0.1.0"
edition = "2021"
[dependencies]
env_logger = "0.11.3"
log = "0.4.21"
process-image = "0.2.0"
profirust = { version = "0.2.0", default-features = false, features = ["phy-linux", "std"] }

208
src/main.rs Normal file
View file

@ -0,0 +1,208 @@
use process_image as pi;
use profirust::dp;
use profirust::fdl;
use profirust::phy;
// Bus Parameters
const MASTER_ADDRESS: u8 = 3;
const BUS_DEVICE: &'static str = "/dev/ttyUSB0";
const BAUDRATE: profirust::Baudrate = profirust::Baudrate::B500000;
// Device Addresses
const RIO_ADDRESS: u8 = 42;
// Parameters
const CYCLE_TIME: u64 = 5000;
pi::process_image! {
struct Pii: 1024 {
pub bgb1: (X, 0, 0), // Left Limit Switch
pub bgb2: (X, 0, 1), // Right Limit Switch
pub bpb1: (X, 0, 2), // Pressure > 1.5 barg
pub want_run: (X, 0, 4), // Start/Stop Switch
pub connection_alive: (X, 64, 0),
}
}
pi::process_image! {
struct mut PiqMut: 1024 {
pub mbb1: (X, 0, 0), // Coil for turning cylinder to the left
pub mbb2: (X, 0, 1), // Coil for turning cylinder to the right
pub pza1_white: (X, 0, 2), // White status indicator light
pub pza1_blue: (X, 0, 3), // Blue status indicator light
pub pza1_orange: (X, 0, 4), // Orange status indicator light
pub pza1_alarm: (X, 0, 5), // Alarm buzzer
pub timer: (L, 104),
pub fault_time: (L, 112),
pub counter: (L, 120),
pub running: (X, 200, 0),
pub faulted: (X, 200, 1),
pub state: (X, 200, 2),
}
}
fn program(inp: Pii, mut out: PiqMut, now: profirust::time::Instant) {
let now = u64::try_from(now.total_millis()).unwrap();
let running = inp.want_run() && (*out.running() || inp.bpb1());
let mut faulted = *out.faulted() && running;
*out.pza1_orange() = faulted;
*out.pza1_blue() = !running && !faulted;
*out.pza1_white() = running && !faulted;
*out.pza1_alarm() = faulted && (now - *out.fault_time()) < 1000;
if running && !inp.connection_alive() {
faulted = true;
}
if running && !inp.bpb1() {
faulted = true;
}
if running && (inp.bgb1() | inp.bgb2()) {
faulted = true;
}
if !running || faulted {
*out.timer() = now;
*out.counter() = 0;
}
if (now - *out.timer()) > CYCLE_TIME && *out.state() {
*out.timer() = now;
*out.state() = false;
*out.counter() += 1;
log::info!("Load cycles: {}", *out.counter());
}
if (now - *out.timer()) > CYCLE_TIME && !*out.state() {
*out.timer() = now;
*out.state() = true;
*out.counter() += 1;
log::info!("Load cycles: {}", *out.counter());
}
let mbb1 = *out.state() && running && !faulted;
let mbb2 = !*out.state() && running && !faulted;
*out.mbb1() = mbb1;
*out.mbb2() = mbb2;
if !*out.faulted() && faulted {
*out.fault_time() = now;
}
*out.running() = running;
*out.faulted() = faulted;
}
fn main() {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"))
.format_timestamp_micros()
.init();
let mut dp_master = dp::DpMaster::new(vec![]);
// Options generated by `gsdtool` using "B751_P39.GSD"
let options = profirust::dp::PeripheralOptions {
// "WAGO 750-303 (FW: 01 ... 06) PRO" by "WAGO Kontakttechnik GmbH"
ident_number: 0xb751,
// Global Parameters:
// - Register-Interface.............: is not used
// - RESET on terminalbus failure...: POWER ON RESET
// - Terminalbus diagnostics........: disabled
// - Evaluation of Clear_Data.......: enabled
// - Diagnostics of binary modules..: is not mapped into PI
// - Extended PI-Update.............: according to PI-Update
// - Evaluation of complex modules..: process data only
// - Data format....................: MOTOROLA
// - Process image update...........: free running
// - Response to PROFIBUS failure...: Output image is cleared
// - Response to terminalbus failure: PROFIBUS communication stops
// - Maximum length of diagnostics..: 16 Byte
//
// Selected Modules:
// [0] 8 Bit binary inputs
// [1] 8 Bit binary outputs
user_parameters: Some(&[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x0a,
0x00,
]),
config: Some(&[0x10, 0x20]),
// Set max_tsdr depending on baudrate and assert
// that a supported baudrate is used.
max_tsdr: match BAUDRATE {
profirust::Baudrate::B9600 => 60,
profirust::Baudrate::B19200 => 60,
profirust::Baudrate::B93750 => 60,
profirust::Baudrate::B187500 => 60,
profirust::Baudrate::B500000 => 100,
profirust::Baudrate::B1500000 => 150,
profirust::Baudrate::B3000000 => 250,
profirust::Baudrate::B6000000 => 350,
profirust::Baudrate::B12000000 => 550,
b => panic!(
"Peripheral \"WAGO 750-303 (FW: 01 ... 06) PRO\" does not support baudrate {b:?}!"
),
},
fail_safe: false,
..Default::default()
};
let mut buffer_inputs = [0u8; 1];
let mut buffer_outputs = [0u8; 1];
let mut buffer_diagnostics = [0u8; 64];
let rio_handle = dp_master.add(
dp::Peripheral::new(
RIO_ADDRESS,
options,
&mut buffer_inputs,
&mut buffer_outputs,
)
.with_diag_buffer(&mut buffer_diagnostics),
);
let mut fdl_master = fdl::FdlMaster::new(
fdl::ParametersBuilder::new(MASTER_ADDRESS, BAUDRATE)
// We use a rather large T_slot time because USB-RS485 converters
// can induce large delays at times.
.slot_bits(2500)
.watchdog_timeout(profirust::time::Duration::from_secs(2))
.build_verified(&dp_master),
);
// We must not poll() too often or to little. T_slot / 2 seems to be a good compromise.
let sleep_time: std::time::Duration = (fdl_master.parameters().slot_time() / 2).into();
let mut phy = phy::LinuxRs485Phy::new(BUS_DEVICE, fdl_master.parameters().baudrate);
let start = profirust::time::Instant::now();
let mut pii = [0u8; 1024];
let mut piq = [0u8; 1024];
fdl_master.set_online();
dp_master.enter_operate();
loop {
let now = profirust::time::Instant::now();
let events = fdl_master.poll(now, &mut phy, &mut dp_master);
if events.cycle_completed {
let remoteio = dp_master.get_mut(rio_handle);
let rio_running = remoteio.is_running();
let rio_pii = remoteio.pi_i();
pii[0..rio_pii.len()].copy_from_slice(rio_pii);
*pi::tag_mut!(&mut pii, X, 64, 0) = rio_running;
program(Pii::from(&pii), PiqMut::from(&mut piq), now);
let remoteio = dp_master.get_mut(rio_handle);
let rio_piq = remoteio.pi_q_mut();
rio_piq.copy_from_slice(&piq[0..rio_piq.len()]);
}
std::thread::sleep(sleep_time);
}
}