Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 2 additions & 13 deletions crates/fbuild-build-arm/src/rp2040/orchestrator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,13 +361,7 @@ impl BuildOrchestrator for Rp2040Orchestrator {
)
})?;
let uf2 = elf.with_extension("uf2");
convert_elf_to_uf2(
&picotool.executable(),
elf,
&uf2,
&board_mcu,
)
.await?;
convert_elf_to_uf2(&picotool.executable(), elf, &uf2, &board_mcu).await?;
build_result.firmware_path = Some(uf2);
}

Expand All @@ -391,12 +385,7 @@ impl BuildOrchestrator for Rp2040Orchestrator {
}
}

async fn convert_elf_to_uf2(
picotool: &Path,
elf: &Path,
uf2: &Path,
mcu: &str,
) -> Result<()> {
async fn convert_elf_to_uf2(picotool: &Path, elf: &Path, uf2: &Path, mcu: &str) -> Result<()> {
let family = if mcu.to_ascii_lowercase().starts_with("rp2350") {
"rp2350-arm-s"
} else {
Expand Down
62 changes: 49 additions & 13 deletions crates/fbuild-core/src/usb/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,26 +225,56 @@ pub fn try_install_online_cache(path: &Path) -> bool {
// the canonical FastLED/boards {"Vendor name":..., "PIDs":[{pid:name}]}
// shape. Keeping this compatibility at the boundary lets boards remain
// the single source of truth without a second generated fbuild file.
let vendor = value.get("vendor").and_then(Value::as_str)
let vendor = value
.get("vendor")
.and_then(Value::as_str)
.or_else(|| value.get("Vendor name").and_then(Value::as_str))
.unwrap_or("Unknown USB vendor");
if let Some(products) = value.get("products").and_then(Value::as_array) {
for pair in products {
let Some(items) = pair.as_array() else { continue };
if items.len() != 2 { continue; }
let Some(pid_str) = items[0].as_str() else { continue };
let Some(product_name) = items[1].as_str() else { continue };
let Some(pid) = parse_hex_u16(pid_str) else { continue; };
packed.insert(pack(vid, pid), UsbInfo { vendor: vendor.to_string(), product: product_name.to_string() });
let Some(items) = pair.as_array() else {
continue;
};
if items.len() != 2 {
continue;
}
let Some(pid_str) = items[0].as_str() else {
continue;
};
let Some(product_name) = items[1].as_str() else {
continue;
};
let Some(pid) = parse_hex_u16(pid_str) else {
continue;
};
packed.insert(
pack(vid, pid),
UsbInfo {
vendor: vendor.to_string(),
product: product_name.to_string(),
},
);
}
}
if let Some(products) = value.get("PIDs").and_then(Value::as_array) {
for item in products {
let Some(map) = item.as_object() else { continue };
let Some(map) = item.as_object() else {
continue;
};
for (pid_str, product_name) in map {
let Some(product_name) = product_name.as_str() else { continue };
let Some(pid) = parse_hex_u16(pid_str) else { continue; };
packed.insert(pack(vid, pid), UsbInfo { vendor: vendor.to_string(), product: product_name.to_string() });
let Some(product_name) = product_name.as_str() else {
continue;
};
let Some(pid) = parse_hex_u16(pid_str) else {
continue;
};
packed.insert(
pack(vid, pid),
UsbInfo {
vendor: vendor.to_string(),
product: product_name.to_string(),
},
);
}
}
}
Expand Down Expand Up @@ -693,8 +723,14 @@ mod tests {
)
.unwrap();
assert!(try_install_online_cache(&path));
assert_eq!(lookup(0x2e8a, 0x0003).unwrap().product, "Raspberry Pi RP2 BOOTSEL");
assert_eq!(lookup(0x2e8a, 0x000f).unwrap().product, "Raspberry Pi Pico 2");
assert_eq!(
lookup(0x2e8a, 0x0003).unwrap().product,
"Raspberry Pi RP2 BOOTSEL"
);
assert_eq!(
lookup(0x2e8a, 0x000f).unwrap().product,
"Raspberry Pi Pico 2"
);
clear_online_cache_for_tests();
}
}
23 changes: 13 additions & 10 deletions crates/fbuild-daemon/src/handlers/operations/deploy_port.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ pub(super) fn choose_deploy_port(
.vid
.zip(device.pid)
.and_then(|(vid, pid)| fbuild_core::usb::try_resolve(vid, pid));
identity_matches_rp_generation(identity.as_ref(), expected_generation).then_some(PortCandidate {
port: device.port,
vid: device.vid,
pid: device.pid,
description: device.description,
})
identity_matches_rp_generation(identity.as_ref(), expected_generation).then_some(
PortCandidate {
port: device.port,
vid: device.vid,
pid: device.pid,
description: device.description,
},
)
})
.collect();
matches.sort_by(|a, b| a.port.cmp(&b.port));
Expand Down Expand Up @@ -157,9 +159,7 @@ fn identity_matches_rp_generation(
classify_rp_generation(identity) == Some(expected)
}

fn classify_rp_generation(
identity: Option<&fbuild_core::usb::UsbInfo>,
) -> Option<RpGeneration> {
fn classify_rp_generation(identity: Option<&fbuild_core::usb::UsbInfo>) -> Option<RpGeneration> {
let product = identity?.product.to_ascii_lowercase();
if product.contains("rp2350") || product.contains("pico 2") {
Some(RpGeneration::Rp2350)
Expand Down Expand Up @@ -307,7 +307,10 @@ mod tests {
None,
Platform::RaspberryPi,
None,
vec![device("COM1", None, None), device("COM11", Some(0x10C4), Some(0xEA60))],
vec![
device("COM1", None, None),
device("COM11", Some(0x10C4), Some(0xEA60)),
],
);
assert!(choice.port.is_none());
assert!(choice.warning.is_none());
Expand Down
19 changes: 15 additions & 4 deletions crates/fbuild-deploy/src/rp2040.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,11 @@ fn validate_uf2(bytes: &[u8], expected_family: u32) -> Result<()> {
};
for (index, block) in bytes.chunks_exact(UF2_BLOCK_SIZE).enumerate() {
let field = |offset: usize| {
u32::from_le_bytes(block[offset..offset + 4].try_into().expect("four-byte UF2 field"))
u32::from_le_bytes(
block[offset..offset + 4]
.try_into()
.expect("four-byte UF2 field"),
)
};
if field(0) != UF2_MAGIC_START0
|| field(4) != UF2_MAGIC_START1
Expand Down Expand Up @@ -436,7 +440,9 @@ impl Rp2040Deployer {

fn catalogue_pico_cdc_ports(expected_family: u32) -> Result<Vec<String>> {
let ports = fbuild_serial::ports::available_ports().map_err(|error| {
FbuildError::SerialError(format!("failed to enumerate post-deploy serial ports: {error}"))
FbuildError::SerialError(format!(
"failed to enumerate post-deploy serial ports: {error}"
))
})?;
let mut names: Vec<String> = ports
.into_iter()
Expand Down Expand Up @@ -704,7 +710,10 @@ mod tests {
assert_eq!(destination.file_name().unwrap(), "NEW.UF2");
let artifact = firmware.with_extension("uf2");
assert!(artifact.is_file());
assert_eq!(fs::read(&artifact).unwrap(), fs::read(&destination).unwrap());
assert_eq!(
fs::read(&artifact).unwrap(),
fs::read(&destination).unwrap()
);
assert_eq!(
fs::metadata(destination).unwrap().len(),
UF2_BLOCK_SIZE as u64
Expand Down Expand Up @@ -749,7 +758,9 @@ mod tests {
&["COM12".to_string(), "COM13".to_string()],
)
.unwrap_err();
assert!(error.to_string().contains("multiple new Raspberry Pi CDC ports"));
assert!(error
.to_string()
.contains("multiple new Raspberry Pi CDC ports"));
}

#[test]
Expand Down
Loading