hex_to_uf2/
block.rs

1const UF2_MAGIC_START0: u32 = 0x0A324655; // "UF2\n"
2const UF2_MAGIC_START1: u32 = 0x9E5D5157;
3const UF2_MAGIC_END: u32 = 0x0AB16F30;
4
5/// uf2 Block
6pub struct Block {
7    /// address inside uf2 file
8    pub address: u32,
9    /// data
10    pub bytes: [u8; 256],
11}
12
13impl Block {
14    pub fn new(address: u32) -> Self {
15        Self {
16            address,
17            bytes: [0; 256],
18        }
19    }
20
21    /// encode this block to uf2
22    pub fn encode(&self, block_no: u32, number_of_blocks: u32, family_id: Option<u32>) -> Vec<u8> {
23        let flags: u32 = match family_id {
24            Some(0x0) => 0x0,
25            Some(_) => 0x2000,
26            None => 0x0,
27        };
28
29        let mut header = vec![];
30        header.extend_from_slice(&UF2_MAGIC_START0.to_le_bytes());
31        header.extend_from_slice(&UF2_MAGIC_START1.to_le_bytes());
32        header.extend_from_slice(&flags.to_le_bytes());
33        header.extend_from_slice(&self.address.to_le_bytes());
34        header.extend_from_slice(&(256u32).to_le_bytes()); // Fixed size
35        header.extend_from_slice(&block_no.to_le_bytes());
36        header.extend_from_slice(&number_of_blocks.to_le_bytes());
37        if let Some(family_id) = family_id {
38            header.extend_from_slice(&family_id.to_le_bytes());
39        } else {
40            header.extend_from_slice(&(0x00_u32).to_le_bytes());
41        }
42
43        // Add the block's data
44        header.extend_from_slice(&self.bytes);
45
46        // Pad with 0x00 to make it 512 bytes - 4 (for the footer)
47        while header.len() < 512 - 4 {
48            header.push(0x00);
49        }
50
51        header.extend_from_slice(&UF2_MAGIC_END.to_le_bytes());
52
53        header
54    }
55}