99mod usb_port_path;
1010
1111use anyhow:: { anyhow, Context } ;
12- use find_usb_block_device:: find_usb_block_device;
1312
1413use clap:: { arg, value_parser} ;
1514use libftdi1_sys:: ftdi_interface;
@@ -24,15 +23,18 @@ use std::{
2423
2524pub ( crate ) use fpga_jtag:: { FpgaJtag , FpgaReset } ;
2625pub ( crate ) use ftdi:: FtdiCtx ;
27- pub ( crate ) use sd_mux:: { SdMux , SdMuxTarget } ;
26+ use sd_mux:: { SDWire , SdMux , SdMuxTarget , UsbsdMux } ;
2827pub ( crate ) use usb_port_path:: UsbPortPath ;
2928
3029fn 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.
9799fn 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.
163165fn 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
233238fn 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