[opentitantool] Set programming speed before loading bitstream
On firmwares that support variable programming speed (1.0.0+), make sure that it is configured to a high speed (20MHz)
Signed-off-by: Jorge Prendes <jorge.prendes@gmail.com>
diff --git a/sw/host/opentitanlib/src/transport/cw310/usb.rs b/sw/host/opentitanlib/src/transport/cw310/usb.rs
index f5b5835..f5b8524 100644
--- a/sw/host/opentitanlib/src/transport/cw310/usb.rs
+++ b/sw/host/opentitanlib/src/transport/cw310/usb.rs
@@ -31,6 +31,9 @@
fvco: u32,
}
+#[derive(Ord, PartialOrd, Eq, PartialEq, Debug, Clone)]
+pub struct FirmwareVersion(u8, u8, u8);
+
impl Backend {
/// Commands for the CW310 board.
pub const CMD_FW_VERSION: u8 = 0x17;
@@ -134,10 +137,10 @@
}
/// Get the firmware version.
- pub fn get_firmware_version(&self) -> Result<[u8; 3]> {
+ pub fn get_firmware_version(&self) -> Result<FirmwareVersion> {
let mut buf = [0u8; 3];
self.read_ctrl(Backend::CMD_FW_VERSION, 0, &mut buf)?;
- Ok(buf)
+ Ok(FirmwareVersion(buf[0], buf[1], buf[2]))
}
/// Set GPIO `pinname` to either output or input mode.
@@ -298,9 +301,19 @@
Ok(status[0] & 0x01 != 0)
}
- // Erase the FPGA and prepare for programming.
- fn fpga_erase(&self) -> Result<()> {
- self.send_ctrl(Backend::CMD_FPGA_PROGRAM, Backend::PROGRAM_INIT, &[])?;
+ // Set the FPGA download speed and prepare for programming.
+ fn fpga_prepare(&self, speed_hz: u32) -> Result<()> {
+ let supports_variable_speed = self.get_firmware_version()? >= FirmwareVersion(1, 0, 0);
+ let speed_hz = speed_hz.to_le_bytes();
+ self.send_ctrl(
+ Backend::CMD_FPGA_PROGRAM,
+ Backend::PROGRAM_INIT,
+ if supports_variable_speed {
+ &speed_hz
+ } else {
+ &[]
+ },
+ )?;
std::thread::sleep(Duration::from_millis(1));
self.send_ctrl(Backend::CMD_FPGA_PROGRAM, Backend::PROGRAM_PREPARE, &[])?;
std::thread::sleep(Duration::from_millis(1));
@@ -334,7 +347,7 @@
bitstream: &[u8],
progress: Option<&dyn Fn(u32, u32)>,
) -> Result<()> {
- self.fpga_erase()?;
+ self.fpga_prepare(20_000_000)?;
let result = self.fpga_download(bitstream, progress);
let mut status = false;