opentitanlib/transport/common/
fpga.rs1use anyhow::Result;
6use std::time::Duration;
7
8use crate::app::TransportWrapper;
9use crate::io::gpio::GpioPin;
10use crate::io::uart::Uart;
11use crate::transport::ProgressIndicator;
12use crate::util::rom_detect::RomDetect;
13
14pub struct FpgaProgram<'a> {
16 pub bitstream: Vec<u8>,
18 pub rom_reset_pulse: Duration,
20 pub rom_timeout: Duration,
22 pub progress: Box<dyn ProgressIndicator + 'a>,
25}
26
27impl FpgaProgram<'_> {
28 fn check_correct_version(&self, uart: &dyn Uart, reset_pin: &dyn GpioPin) -> Result<bool> {
29 let mut rd = RomDetect::new(&self.bitstream, Some(self.rom_timeout))?;
30
31 reset_pin.write(false)?;
34 std::thread::sleep(self.rom_reset_pulse);
35 uart.clear_rx_buffer()?;
37 reset_pin.write(true)?;
38
39 if rd.detect(uart)? {
41 log::info!("Already running the correct bitstream. Skip loading bitstream.");
42 return Ok(true);
45 }
46 Ok(false)
47 }
48
49 fn skip(&self) -> bool {
50 self.bitstream.starts_with(b"__skip__")
51 }
52
53 pub fn should_skip(&self, transport: &TransportWrapper) -> Result<bool> {
54 let uart = transport.uart("CONSOLE")?;
57 let reset_pin = transport.gpio_pin("RESET")?;
58 if self.skip() {
59 log::info!("Skip loading the __skip__ bitstream.");
60 return Ok(true);
61 }
62 if self.check_correct_version(&*uart, &*reset_pin)? {
63 return Ok(true);
64 }
65 Ok(false)
66 }
67}
68
69pub struct ClearBitstream;