rfm-bridge: fix FPWR gating (was inside Mode::Ticker so bridge never wrote SM2), single-point f(x) on D2000, dumb reflector echo, REP budget 1.5ms
This commit is contained in:
parent
b92484a86c
commit
3f29a86239
36
src/main.rs
36
src/main.rs
|
|
@ -1116,8 +1116,11 @@ async fn run(cfg: &Config) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
el6695_rt::rfm::barrier();
|
el6695_rt::rfm::barrier();
|
||||||
mb.magic = el6695_rt::rfm::MB_MAGIC;
|
mb.magic = el6695_rt::rfm::MB_MAGIC;
|
||||||
}
|
}
|
||||||
// Spin-poll REP for the remote-processed payload.
|
// Spin-poll REP for the remote-processed payload. The RFM hop
|
||||||
let deadline = Instant::now() + Duration::from_nanos(cycle_ns / 2);
|
// (~30-800us depending on scheduling) needs a budget larger
|
||||||
|
// than one PLC cycle; allow up to 1.5ms so the full-chain RTT
|
||||||
|
// is actually measured instead of timing out to local echo.
|
||||||
|
let deadline = Instant::now() + Duration::from_nanos(1_500_000);
|
||||||
let mut got = false;
|
let mut got = false;
|
||||||
loop {
|
loop {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
@ -1129,6 +1132,15 @@ async fn run(cfg: &Config) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
{
|
{
|
||||||
let m = SM_RX_PLD_LEN.min(el6695_rt::rfm::MB_MAX_PAYLOAD);
|
let m = SM_RX_PLD_LEN.min(el6695_rt::rfm::MB_MAX_PAYLOAD);
|
||||||
el6695_rt::rfm::dev_read(&mut tx_buf[..m], rep.payload.as_ptr());
|
el6695_rt::rfm::dev_read(&mut tx_buf[..m], rep.payload.as_ptr());
|
||||||
|
// Apply f(x)=x*7+3 to the echoed frame's tc_seq
|
||||||
|
// here on the D2000 side (single transform point,
|
||||||
|
// robust): the remote just reflects the frame, the
|
||||||
|
// PLC's echo check needs [0..8] = f(rx tc_seq).
|
||||||
|
if m >= 280 {
|
||||||
|
let rx_seq = u64::from_le_bytes(rx_buf[..8].try_into().unwrap_or([0; 8]));
|
||||||
|
let processed = rx_seq.wrapping_mul(7).wrapping_add(3);
|
||||||
|
tx_buf[..8].copy_from_slice(&processed.to_le_bytes());
|
||||||
|
}
|
||||||
bridge_rtt_st.push(el6695_rt::rfm::now_ns().saturating_sub(rep.ts_ns) as i64);
|
bridge_rtt_st.push(el6695_rt::rfm::now_ns().saturating_sub(rep.ts_ns) as i64);
|
||||||
got = true;
|
got = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1194,6 +1206,11 @@ async fn run(cfg: &Config) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// TX (FPWR) must run for BOTH ticker and rfm-bridge modes (it was
|
||||||
|
// previously gated inside Mode::Ticker, so rfm-bridge never wrote
|
||||||
|
// SM2 and the PLC read zeros). Probe mode stays read-only.
|
||||||
|
if cfg.mode != Mode::Probe {
|
||||||
if PAYLOAD_LEN >= 16 {
|
if PAYLOAD_LEN >= 16 {
|
||||||
tx_buf[8..16].copy_from_slice(&cyc.to_le_bytes());
|
tx_buf[8..16].copy_from_slice(&cyc.to_le_bytes());
|
||||||
}
|
}
|
||||||
|
|
@ -1615,18 +1632,9 @@ async fn rfm_mode_main(cfg: &Config) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
el6695_rt::rfm::dev_read(&mut buf[..n], req.payload.as_ptr());
|
el6695_rt::rfm::dev_read(&mut buf[..n], req.payload.as_ptr());
|
||||||
let rep = el6695_rt::rfm::Mailbox::at(mem_ptr, el6695_rt::rfm::MB_REP_OFF);
|
let rep = el6695_rt::rfm::Mailbox::at(mem_ptr, el6695_rt::rfm::MB_REP_OFF);
|
||||||
el6695_rt::rfm::dev_write(rep.payload.as_mut_ptr(), &buf[..n]);
|
el6695_rt::rfm::dev_write(rep.payload.as_mut_ptr(), &buf[..n]);
|
||||||
// Bridge frames (CX 800B payload): apply the same
|
// Echo is a dumb reflector: f(x) is applied by the
|
||||||
// f(x)=x*7+3 transform on tc_seq[0..8] that the local
|
// D2000 bridge (single transform point, avoids double
|
||||||
// ticker applies, so the PLC's echo check passes
|
// transform).
|
||||||
// through the RFM hop. Small ping frames pass through
|
|
||||||
// verbatim.
|
|
||||||
if (cur_len as usize) >= 280 {
|
|
||||||
let mut seq_bytes = [0u8; 8];
|
|
||||||
el6695_rt::rfm::dev_read(&mut seq_bytes, rep.payload.as_ptr());
|
|
||||||
let seq_val = u64::from_le_bytes(seq_bytes);
|
|
||||||
let processed = seq_val.wrapping_mul(7).wrapping_add(3);
|
|
||||||
el6695_rt::rfm::dev_write(rep.payload.as_mut_ptr(), &processed.to_le_bytes());
|
|
||||||
}
|
|
||||||
rep.len = cur_len;
|
rep.len = cur_len;
|
||||||
rep.ts_ns = cur_ts;
|
rep.ts_ns = cur_ts;
|
||||||
el6695_rt::rfm::barrier();
|
el6695_rt::rfm::barrier();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user