Skip to content

Commit c6334bf

Browse files
authored
ci/fpga-boss: add SDMux implementation for usbsdmux (#2143)
* ci/fpga-boss: add SDMux implementation for usbsdmux Signed-off-by: leongross <leon.gross@9elements.com>
1 parent 499ed38 commit c6334bf

5 files changed

Lines changed: 203 additions & 40 deletions

File tree

ci-tools/fpga-boss/README.md

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ You need:
1313

1414
To use the flashing feature, you will need
1515

16-
* An [SDWire](https://wiki.tizen.org/SDWire) SD mux or compatible clone.
16+
* An [SDWire](https://wiki.tizen.org/SDWire) SD mux or compatible clone or an [usbsdmux](https://github.com/linux-automation/usbsdmux/).
1717

1818
## How do I determine the `--zcu104` parameter for my hardware?
1919

@@ -29,6 +29,20 @@ sudo dmesg | grep 'idVendor=0403, idProduct=6011'
2929
In this case, the USB path is `1-14.3`.
3030

3131

32+
## How do I determine the `--usbsdmux` parameter for my hardware?
33+
34+
If you use the `usbsdmux` please refer to the official documentation and follow all the required steps to set up the udev rules and cli tools appropriately.
35+
36+
When set up, the connected `usbsdmux` device(s) will be exposed in `/dev/usb-sd-mux/`.
37+
38+
```sh
39+
$ ls /dev/usb-sd-mux/
40+
total 0
41+
lrwxrwxrwx 1 root plugdev 1 Jan 01 00:00 id-00048.00643
42+
```
43+
44+
Note this file name and trim the `id` to get the ID needed for the `--usbsdmux` cli parameter.
45+
3246
## How do I determine the `--sdwire` parameter for my hardware?
3347

3448
This is the USB port path of the USB hub built into the SDWire0 (SDWire contains
@@ -68,7 +82,12 @@ $ sudo bash build.sh
6882

6983
```
7084
$ cd ci-tools/fpga-boss
85+
# SDwire
7186
$ cargo run -- --zcu104 1-14.3 --sdwire 1-14.6 flash ../fpga-image/out/image.img
87+
88+
# usbsdmux
89+
# $ cargo run -- --zcu104 1-14.3 --usbsdmux 00048.00643 flash ../fpga-image/out/image.img
90+
7291
Block device associated with 1-14.2.1 is /dev/sda
7392
Flashing ../fpga-image/out/image.img to /dev/sda
7493
Waiting for attached sd card to be noticed by OS
@@ -80,8 +99,9 @@ fpga-boss as root.
8099

81100
### To observe the UART output of the now booting FPGA:
82101

102+
Example for `sdwire`
83103
```
84-
$ cargo run -- --zcu104 1-14.3 --sdwire 1-14.2 console
104+
$ cargo run -- --zcu104 1-14.3 --sdwire 1-14.6 console
85105
To exit terminal type Ctrl-T then Q
86106
87107
@@ -99,6 +119,7 @@ We have four zcu104 boards connected to a Raspberry pi running four instances of
99119

100120
```
101121
# fpga-boss --zcu104 x-x.x --sdwire x-x.x serve image.img -- /path/to/rtool receive_jitconfig
122+
# fpga-boss --zcu104 x-x.x --usbsdmux xxxxx.xxxxx serve image.img -- /path/to/rtool receive_jitconfig
102123
```
103124

104125
The serve subcommand runs in a loop that does the following:

ci-tools/fpga-boss/src/ftdi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub enum BitMode {
2424
BitBang = 0x01,
2525
CBus = 0x20,
2626
}
27+
2728
pub struct FtdiCtx {
2829
ctx: *mut libftdi1_sys::ftdi_context,
2930
port_path: UsbPortPath,

ci-tools/fpga-boss/src/main.rs

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ mod tty;
99
mod usb_port_path;
1010

1111
use anyhow::{anyhow, Context};
12-
use find_usb_block_device::find_usb_block_device;
1312

1413
use clap::{arg, value_parser};
1514
use libftdi1_sys::ftdi_interface;
@@ -24,15 +23,18 @@ use std::{
2423

2524
pub(crate) use fpga_jtag::{FpgaJtag, FpgaReset};
2625
pub(crate) use ftdi::FtdiCtx;
27-
pub(crate) use sd_mux::{SdMux, SdMuxTarget};
26+
use sd_mux::{SDWire, SdMux, SdMuxTarget, UsbsdMux};
2827
pub(crate) use usb_port_path::UsbPortPath;
2928

3029
fn cli() -> clap::Command<'static> {
3130
clap::Command::new("fpga-boss")
3231
.about("FPGA boss tool")
3332
.arg(
3433
arg!(--"sdwire" [PORT_PATH] "USB port path to the hub chip on the SDWire (ex: 3-1.2)")
35-
.value_parser(value_parser!(UsbPortPath))
34+
.value_parser(value_parser!(OsString)))
35+
.arg(
36+
arg!(--"usbsdmux" [USBID] "USB unique ID for the usbsdmux device (ex: 00048.00643)")
37+
.value_parser(value_parser!(OsString))
3638
)
3739
.arg(
3840
arg!(--"zcu104" [PORT_PATH] "USB port path to the FTDI chip on the ZCU104 dev board (ex: 3-1.2)")
@@ -93,21 +95,21 @@ fn open_block_dev(path: &Path) -> std::io::Result<File> {
9395
}
9496
}
9597

96-
/// Returns true if the device alread contains the image.
98+
/// Returns true if the device already contains the image.
9799
fn verify_image(dev: &mut File, image: &mut File) -> std::io::Result<bool> {
98100
dev.seek(SeekFrom::Start(0))?;
99101
let file_len = image.metadata()?.len();
100-
let mut buf1 = vec![0_u8; 1024 * 1024];
101-
let mut buf2 = vec![0_u8; 1024 * 1024];
102+
let mut want = vec![0_u8; 1024 * 1024];
103+
let mut have = vec![0_u8; 1024 * 1024];
102104
let mut total_read: u64 = 0;
103105
let start_time = Instant::now();
104106
loop {
105-
let bytes_read = image.read(&mut buf1)?;
107+
let bytes_read = image.read(&mut want)?;
106108
if bytes_read == 0 {
107109
return Ok(true);
108110
}
109-
dev.read_exact(&mut buf2[..bytes_read])?;
110-
if buf1[..bytes_read] != buf2[..bytes_read] {
111+
dev.read_exact(&mut have[..bytes_read])?;
112+
if want[..bytes_read] != have[..bytes_read] {
111113
return Ok(false);
112114
}
113115
total_read += u64::try_from(bytes_read).unwrap();
@@ -162,7 +164,10 @@ fn active_runner_error_checks(input: &str) -> std::io::Result<()> {
162164
/// to recover the FPGA.
163165
fn check_for_github_runner_exception(input: &str) -> std::io::Result<()> {
164166
if input.contains("Unhandled exception") {
165-
Err(Error::new(ErrorKind::BrokenPipe, "Github runner had an unhandled exception"))?;
167+
Err(Error::new(
168+
ErrorKind::BrokenPipe,
169+
"Github runner had an unhandled exception",
170+
))?;
166171
}
167172
Ok(())
168173
}
@@ -232,7 +237,9 @@ fn log_uart_until_helper<R: BufRead>(
232237

233238
fn main_impl() -> anyhow::Result<()> {
234239
let matches = cli().get_matches();
235-
let sdwire_hub_path = matches.get_one::<UsbPortPath>("sdwire");
240+
let sdwire = matches.get_one::<OsString>("sdwire");
241+
let usbsdmux = matches.get_one::<OsString>("usbsdmux");
242+
236243
let zcu104_path = matches.get_one::<UsbPortPath>("zcu104");
237244
let boss_ftdi_path = matches.get_one::<UsbPortPath>("boss_ftdi");
238245

@@ -251,28 +258,21 @@ fn main_impl() -> anyhow::Result<()> {
251258
.ok_or(anyhow!("--zcu104 flag required"))
252259
.cloned()
253260
};
254-
let get_sd_mux = || {
255-
SdMux::open(
256-
sdwire_hub_path
257-
.ok_or(anyhow!("--sdwire flag required"))?
258-
.child(2),
259-
)
260-
};
261-
let get_fpga_ftdi = || FpgaJtag::open(get_zcu104_path()?);
262-
let get_sd_dev_path = || {
263-
let sdwire_hub_path = sdwire_hub_path.ok_or(anyhow!("--sdwire flag required"))?;
264-
find_usb_block_device(&sdwire_hub_path.child(1)).with_context(|| {
265-
format!(
266-
"Could not find block device associated with {}",
267-
sdwire_hub_path.child(1)
268-
)
269-
})
261+
262+
let mut sd_mux: Box<dyn SdMux> = match (sdwire, usbsdmux) {
263+
(Some(sdwire), None) => {
264+
Box::new(SDWire::open(String::from(sdwire.to_str().unwrap()))?) as Box<dyn SdMux>
265+
}
266+
(None, Some(usbsdmux)) => {
267+
Box::new(UsbsdMux::open(String::from(usbsdmux.to_str().unwrap()))?) as Box<dyn SdMux>
268+
}
269+
_ => return Err(anyhow!("One of --sdwire or --usbsdmux required")),
270270
};
271271

272+
let get_fpga_ftdi = || FpgaJtag::open(get_zcu104_path()?);
272273
match matches.subcommand() {
273274
Some(("mode", sub_matches)) => {
274275
let mut fpga = get_fpga_ftdi();
275-
let mut sd_mux = get_sd_mux()?;
276276
match sub_matches.get_one::<SdMuxTarget>("MODE").unwrap() {
277277
SdMuxTarget::Dut => {
278278
if let Ok(fpga) = &mut fpga {
@@ -335,8 +335,7 @@ fn main_impl() -> anyhow::Result<()> {
335335
}
336336
Some(("flash", sub_matches)) => {
337337
let mut fpga = get_fpga_ftdi();
338-
let mut sd_mux = get_sd_mux()?;
339-
let sd_dev_path = get_sd_dev_path()?;
338+
let sd_dev_path = sd_mux.get_sd_dev_path()?;
340339
if let Ok(fpga) = &mut fpga {
341340
fpga.set_reset(FpgaReset::Reset)?;
342341
}
@@ -362,14 +361,14 @@ fn main_impl() -> anyhow::Result<()> {
362361
fpga.set_reset(FpgaReset::Run)?
363362
}
364363
}
364+
365365
Some(("serve", sub_matches)) => {
366366
// Reuse the previous token if we never connect to GitHub.
367367
// This avoids creating a bunch of offline runners if the FPGA fails to establish a
368368
// connection.
369369
let mut cached_token: Option<Vec<u8>> = None;
370370
let mut fpga = get_fpga_ftdi()?;
371-
let mut sd_mux = get_sd_mux()?;
372-
let sd_dev_path = get_sd_dev_path()?;
371+
let sd_dev_path = sd_mux.get_sd_dev_path()?;
373372
'outer: loop {
374373
println!("Putting FPGA into reset");
375374
fpga.set_reset(FpgaReset::Reset)?;

0 commit comments

Comments
 (0)