machine_check_avr/
util.rs

1use machine_check::{Bitvector, BitvectorArray};
2
3#[doc(hidden)]
4pub fn read_hex_into_progmem<const I: u32>(progmem: &mut BitvectorArray<I, 16>, hex: &str) {
5    let reader = ihex::Reader::new(hex);
6
7    let progmem_size = u64::pow(2, I);
8
9    for record in reader {
10        let record = match record {
11            Ok(ok) => ok,
12            Err(err) => panic!("Hex file read error: {}", err),
13        };
14        match record {
15            ihex::Record::Data { offset, value } => {
16                // offset is given in bytes
17                if offset % 2 != 0 {
18                    panic!("Unexpected noneven offset in record data");
19                }
20                if value.len() % 2 != 0 {
21                    panic!("Unexpected noneven number of bytes in record data");
22                }
23                let word_offset = offset / 2;
24                let mut word_index = word_offset as u64;
25                for (lo, hi) in value
26                    .iter()
27                    .cloned()
28                    .step_by(2)
29                    .zip(value.iter().cloned().skip(1).step_by(2))
30                {
31                    // AVR has progmem words specified in little-endian order
32                    let word = u16::from_le_bytes([lo, hi]);
33                    if word_index >= progmem_size {
34                        panic!("Hex file location is outside program memory");
35                    }
36                    let index = Bitvector::new(word_index);
37                    progmem[index] = Bitvector::new(word as u64);
38                    word_index += 1;
39                }
40            }
41            ihex::Record::ExtendedSegmentAddress(offset) => {
42                if offset != 0 {
43                    panic!("Unexpected nonzero extended segment address");
44                }
45            }
46            ihex::Record::EndOfFile => {}
47            _ => panic!("Unexpected type of record {:#?}", record),
48        }
49    }
50}