Skip to content

Commit

Permalink
fixed examples, fixed ethercat frame corruption on sending
Browse files Browse the repository at this point in the history
  • Loading branch information
jimy-byerley committed Oct 19, 2023
1 parent 6f22412 commit dbe5164
Show file tree
Hide file tree
Showing 14 changed files with 304 additions and 288 deletions.
116 changes: 56 additions & 60 deletions examples/dc_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use etherage::{
registers,
};
use ioprio::*;
use futures::stream::StreamExt;
use futures_concurrency::future::{Join, Race};


Expand All @@ -31,69 +32,64 @@ async fn main() -> Result<(), Box<dyn Error>> {

//Init master
let master = Arc::new(Master::new(EthernetSocket::new("eno1")?));
{
let m = master.clone();
std::thread::spawn(move || loop { unsafe {m.get_raw()}.receive().unwrap(); });
};
{
let m = master.clone();
std::thread::spawn(move || loop { unsafe {m.get_raw()}.send().unwrap(); });
};
master.switch(CommunicationState::Init).await.unwrap();
(
master.reset_addresses(),
master.reset_clock(),
master.reset_logical(),
// master.reset_mailboxes(),
unsafe {master.get_raw()}.bwr(etherage::registers::ports_errors, etherage::registers::PortsErrorCount::default()),
).join().await;

let mut tasks = Vec::new();
let mut iter = master.discover().await;
while let Some(mut s) = iter.next().await {
tasks.push(async move {
let SlaveAddress::AutoIncremented(i) = s.address()
else { panic!("slave already has a fixed address") };
s.set_address(i+1).await.unwrap();
s.init_mailbox().await.unwrap();
s.init_coe().await;
i+1
});
}
let slaves = tasks.join().await;

// initialize clocks and perform static drift
master.init_clock().await?;

master.switch(CommunicationState::PreOperational).await.unwrap();
// master.switch(CommunicationState::SafeOperational).await.unwrap();

let clock = master.clock().await;
// let mut interval = tokio::time::interval(Duration::from_millis(2));
// let mut interval2 = tokio::time::interval(Duration::from_micros(5_367));

use futures::stream::StreamExt;
let mut interval = tokio_timerfd::Interval::new_interval(Duration::from_millis(2)).unwrap();

(
// dynamic drift
clock.sync(),
// survey divergence
async { loop {
// interval.tick().await;
interval.next().await.unwrap().unwrap();

for &slave in &slaves {
print!("{} ", clock.divergence(slave));
// async { unsafe {master.get_raw()}.receive().await.unwrap() },
// async { unsafe {master.get_raw()}.send().await.unwrap() },
async {
master.switch(CommunicationState::Init).await.unwrap();
(
master.reset_addresses(),
master.reset_clock(),
master.reset_logical(),
// master.reset_mailboxes(),
unsafe {master.get_raw()}.bwr(etherage::registers::ports_errors, etherage::registers::PortsErrorCount::default()),
).join().await;

let mut tasks = Vec::new();
let mut iter = master.discover().await;
while let Some(mut s) = iter.next().await {
tasks.push(async move {
let SlaveAddress::AutoIncremented(i) = s.address()
else { panic!("slave already has a fixed address") };
s.set_address(i+1).await.unwrap();
s.init_mailbox().await.unwrap();
s.init_coe().await;
i+1
});
}
print!("\n");
}},
// // parasitic realtime data exchanges
// async { loop {
// interval2.tick().await;
// master.logical_exchange(etherage::Field::simple(0), [0u8; 64]).await;
// }},
).race().await?;
let slaves = tasks.join().await;

// initialize clocks and perform static drift
master.init_clock().await.unwrap();

master.switch(CommunicationState::PreOperational).await.unwrap();
// master.switch(CommunicationState::SafeOperational).await.unwrap();

let clock = master.clock().await;
let mut interval = tokio_timerfd::Interval::new_interval(Duration::from_millis(2)).unwrap();
let mut interval2 = tokio_timerfd::Interval::new_interval(Duration::from_millis(5_367)).unwrap();

(
// dynamic drift
clock.sync(),
// survey divergence
async { loop {
interval.next().await.unwrap().unwrap();

for &slave in &slaves {
print!("{} ", clock.divergence(slave));
}
print!("\n");
}},
// parasitic realtime data exchanges
async { loop {
interval2.next().await.unwrap().unwrap();
master.logical_exchange(etherage::Field::simple(0), [0u8; 64]).await;
}},
).race().await.unwrap();
},
).join().await;

Ok(())
}
Expand Down
41 changes: 14 additions & 27 deletions examples/pdu_exchange.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,27 @@ use etherage::{Field, EthernetSocket, RawMaster, EthercatResult};

#[tokio::main]
async fn main() -> EthercatResult<()> {
let master = Arc::new(RawMaster::new(EthernetSocket::new("eno1")?));
let master = RawMaster::new(EthernetSocket::new("eno1")?);

(
async { master.receive().await.unwrap() },
async { master.send().await.unwrap() },
async {
let reg = Field::<u16>::simple(0x1234);
let slave = 0;

let reg = Field::<u16>::simple(0x1234);
let slave = 0;
// test read/write
dbg!(1);
let received = master.aprd(slave, reg).await.one().unwrap();
dbg!(2);
master.apwr(slave, reg, received).await.one().unwrap();
dbg!(3);

// test read/write
dbg!(1);
// test simultaneous read/write
(
async {
let received = master.aprd(slave, reg).await.one().unwrap();
dbg!(2);
master.apwr(slave, reg, received).await.one().unwrap();
dbg!(3);

// test simultaneous read/write
(
async {
let received = master.aprd(slave, reg).await.one().unwrap();
master.apwr(slave, reg, received).await.one().unwrap();
},
async {
let received = master.aprd(slave, reg).await.one().unwrap();
master.apwr(slave, reg, received).await.one().unwrap();
},
).join().await;
},
async {
loop {
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
println!("running");
}
let received = master.aprd(slave, reg).await.one().unwrap();
master.apwr(slave, reg, received).await.one().unwrap();
},
).join().await;

Expand Down
52 changes: 37 additions & 15 deletions examples/plot_dc_divergence.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,43 @@
#!/usr/bin/python3

import sys
import matplotlib
from matplotlib import pyplot as plt
import numpy as np
import pyqtgraph as pg
from eve.apputils import *
from PyQt5.QtGui import QColor

source = sys.argv[1]
def style(color):
return dict(
pen = (color[0], color[1], color[2], 150),
symbol = 'o',
symbolSize = 3,
symbolBrush = color,
symbolPen = None,
)

record = []
for line in open(source, 'r').readlines():
groups = line.split()
frame = []
for group in groups:
try: frame.append(int(group))
except ValueError: break
else:
record.append(frame)
@qtschedule
def show():

matplotlib.use('qtagg')
plt.plot(record)
plt.show(block=True)
source = sys.argv[1]

record = []
for line in open(source, 'r').readlines():
groups = line.split()
frame = []
for group in groups:
try: frame.append(int(group))
except ValueError: break
else:
record.append(frame)
record = np.array(record)

pg.setConfigOptions(antialias=True)
win = qtwindow(pg.GraphicsLayoutWidget(title=source))
win.resize(1000, 300)
fig = win.addPlot()

colorcycle = [(100, 255, 100), (100, 100, 255), (100, 200, 200), (200, 200, 200), (200, 100, 255), (200, 255, 100)]
for i, slave in enumerate(record.transpose()):
fig.plot(slave, **style(colorcycle[i%len(colorcycle)]))

qtmain()
61 changes: 27 additions & 34 deletions examples/sdo_exchange.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,47 +11,40 @@ use bilge::prelude::u2;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let master = Arc::new(RawMaster::new(EthernetSocket::new("eno1")?));
let master = RawMaster::new(EthernetSocket::new("eno1")?);

(
async { master.receive().await.unwrap() },
async { master.send().await.unwrap() },
async {

let mut slave = Slave::raw(master.clone(), SlaveAddress::AutoIncremented(0));
slave.switch(CommunicationState::Init).await.unwrap();
slave.set_address(1).await.unwrap();
slave.init_mailbox().await.unwrap();
slave.init_coe().await;
let mut slave = Slave::raw(master.clone(), SlaveAddress::AutoIncremented(0));
slave.switch(CommunicationState::Init).await.unwrap();
slave.set_address(1).await.unwrap();
slave.init_mailbox().await.unwrap();
slave.init_coe().await;

slave.switch(CommunicationState::PreOperational).await.unwrap();
slave.switch(CommunicationState::PreOperational).await.unwrap();

let sdo = Sdo::<u32>::complete(0x1c12);
let priority = u2::new(1);
let sdo = Sdo::<u32>::complete(0x1c12);
let priority = u2::new(1);

// test read/write
// test read/write
let received = slave.coe().await.sdo_read(&sdo, priority).await.unwrap();
slave.coe().await.sdo_write(&sdo, priority, received).await.unwrap();

// test concurrent read/write
(
async {
println!("begin");
let received = slave.coe().await.sdo_read(&sdo, priority).await.unwrap();
println!("between");
slave.coe().await.sdo_write(&sdo, priority, received).await.unwrap();

// test concurrent read/write
(
async {
println!("begin");
let received = slave.coe().await.sdo_read(&sdo, priority).await.unwrap();
println!("between");
slave.coe().await.sdo_write(&sdo, priority, received).await.unwrap();
println!("end");
},
async {
println!("begin");
let received = slave.coe().await.sdo_read(&sdo, priority).await.unwrap();
println!("between");
slave.coe().await.sdo_write(&sdo, priority, received).await.unwrap();
println!("end");
},
).join().await;
println!("end");
},
async {
println!("begin");
let received = slave.coe().await.sdo_read(&sdo, priority).await.unwrap();
println!("between");
slave.coe().await.sdo_write(&sdo, priority, received).await.unwrap();
println!("end");
},
).join().await;

Ok(())
}
39 changes: 13 additions & 26 deletions examples/sdo_exchange_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,59 +11,46 @@ use bilge::prelude::u2;

#[tokio::main]
async fn main() -> std::io::Result<()> {
let master = Arc::new(RawMaster::new(EthernetSocket::new("eno1")?));
{
let master = master.clone();
std::thread::spawn(move || loop {
master.receive();
})};
{
let master = master.clone();
std::thread::spawn(move || loop {
master.send();
})};
std::thread::sleep(Duration::from_millis(500));
let master = RawMaster::new(EthernetSocket::new("eno1")?);

// set fixed addresses
master.apwr(0, registers::address::fixed, 1).await;
master.apwr(1, registers::address::fixed, 2).await;
master.apwr(0, registers::address::fixed, 1).await.one().unwrap();
master.apwr(1, registers::address::fixed, 2).await.one().unwrap();

let slave = 1;

// initialize mailbox
let mailbox = Arc::new(Mutex::new(Mailbox::new(&master, 1, 0x1000 .. 0x1103, 0x1104 .. 0x1200).await));
let mailbox = Arc::new(Mutex::new(Mailbox::new(master.clone(), 1, 0x1000 .. 0x1103, 0x1104 .. 0x1200).await.unwrap()));
let mut can = Can::new(mailbox);

master.fpwr(slave, registers::sii::access, {
let mut config = registers::SiiAccess::default();
config.set_owner(registers::SiiOwner::Pdi);
config
}).await.one();
}).await.one().unwrap();

// switch to preop
master.fpwr(slave, registers::al::control, {
let mut config = registers::AlControlRequest::default();
config.set_state(registers::AlState::PreOperational.into());
config.set_ack(true);
config
}).await.one();
}).await.one().unwrap();

loop {
let received = master.fprd(slave, registers::al::response).await;
assert_eq!(received.answers, 1);
if received.value.error() {
let received = master.fprd(slave, registers::al::error).await;
assert_eq!(received.answers, 1);
panic!("error on state change: {:?}", received.value);
let received = master.fprd(slave, registers::al::response).await.one().unwrap();
if received.error() {
let received = master.fprd(slave, registers::al::error).await.one().unwrap();
panic!("error on state change: {:?}", received);
}
if received.value.state() == registers::AlState::PreOperational.into() {break}
if received.state() == registers::AlState::PreOperational.into() {break}
}

let sdo = Sdo::<u16>::complete(0x6041);

// test read/write
let received = can.sdo_read(&sdo, u2::new(1)).await;
can.sdo_write(&sdo, u2::new(1), received).await;
let received = can.sdo_read(&sdo, u2::new(1)).await.unwrap();
can.sdo_write(&sdo, u2::new(1), received).await.unwrap();

Ok(())
}
Loading

0 comments on commit dbe5164

Please sign in to comment.