create_advanced/
create_advanced.rs

1//  _  _       _             _  _
2// | || |  ___| |_ _ __ ___ | || |
3// | || |_/ __| __| '_ ` _ \| || |_
4// |__   _\__ | |_| | | | | |__   _|
5//   |_| |___/\__|_|_|_| |_|  |_|
6//! # ehatrom — EEPROM HAT library for Raspberry Pi HATs
7//! - [Documentation (docs.rs)](https://docs.rs/ehatrom)
8//! - [GitHub](https://github.com/4stm4/ehatrom)
9//!
10// Advanced EEPROM creation example with Device Tree blob
11use ehatrom::*;
12
13fn main() {
14    println!("🚀 Creating advanced EEPROM with Device Tree support...");
15
16    // Create a vendor info atom with detailed information
17    let vendor_atom = VendorInfoAtom::new(
18        0x414C, // vendor_id (example: "AL" for AleksejZaharčenko)
19        0x2024, // product_id (year)
20        1,      // product_ver
21        "4STM4 Ocultum",
22        "Advanced HAT Demo",
23        [
24            // UUID for this specific HAT
25            0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54,
26            0x32, 0x10,
27        ],
28    );
29
30    // Create GPIO map for bank 0 with specific pin configurations
31    let mut gpio_pins = [0u8; 28];
32
33    // Configure some pins as outputs (value 1)
34    gpio_pins[18] = 1; // GPIO 18 as output
35    gpio_pins[19] = 1; // GPIO 19 as output
36    gpio_pins[20] = 1; // GPIO 20 as output
37    gpio_pins[21] = 1; // GPIO 21 as output
38
39    // Other pins remain as inputs (value 0)
40
41    let gpio_atom = GpioMapAtom {
42        flags: 0x0001, // Set some flags
43        pins: gpio_pins,
44    };
45
46    // Create a simple Device Tree blob (minimal example)
47    // In real use, this would be a proper compiled device tree
48    let dt_blob_data = b"# Simple Device Tree overlay for demo HAT
49/dts-v1/;
50/plugin/;
51
52/ {
53    compatible = \"brcm,bcm2835\";
54    
55    fragment@0 {
56        target = <&gpio>;
57        __overlay__ {
58            demo_pins: demo_pins {
59                brcm,pins = <18 19 20 21>;
60                brcm,function = <1>; /* GPIO_OUT */
61            };
62        };
63    };
64    
65    fragment@1 {
66        target-path = \"/\";
67        __overlay__ {
68            demo_hat {
69                compatible = \"4stm4,demo-hat\";
70                pinctrl-names = \"default\";
71                pinctrl-0 = <&demo_pins>;
72                status = \"okay\";
73            };
74        };
75    };
76};"
77    .to_vec();
78
79    // Create EEPROM structure with all components
80    #[cfg(feature = "alloc")]
81    let mut eeprom = Eeprom {
82        header: EepromHeader::new(),
83        vendor_info: vendor_atom,
84        gpio_map_bank0: gpio_atom,
85        dt_blob: Some(dt_blob_data), // dt_blob is Option<Vec<u8>>
86        gpio_map_bank1: None,        // Not used in this example
87        custom_atoms: Vec::new(),
88    };
89
90    #[cfg(not(feature = "alloc"))]
91    // Для no_std режима создаем статические данные
92    let mut eeprom = {
93        // Для no_std нам нужны статические данные, это просто заглушка
94        static DT_BLOB_DATA: [u8; 1] = [0];
95        static CUSTOM_ATOMS: [(u8, &[u8]); 0] = [];
96        Eeprom {
97            header: EepromHeader::new(),
98            vendor_info: vendor_atom,
99            gpio_map_bank0: gpio_atom,
100            dt_blob: Some(&DT_BLOB_DATA), // dt_blob is Option<&[u8]> в no_std
101            gpio_map_bank1: None,
102            custom_atoms: &CUSTOM_ATOMS,
103        }
104    };
105
106    // Update header with correct counts and length
107    eeprom.update_header();
108
109    // Serialize with CRC
110    #[cfg(feature = "alloc")]
111    let serialized = eeprom.serialize_with_crc();
112
113    #[cfg(not(feature = "alloc"))]
114    // Создаем буфер и вектор для копирования данных
115    let serialized = {
116        let mut buffer = [0u8; 4096]; // Больший буфер для DT blob
117        let size = eeprom
118            .serialize_with_crc_to_slice(&mut buffer)
119            .expect("Failed to serialize EEPROM");
120        // Копируем данные в новый вектор
121        buffer[..size].to_vec()
122    };
123    let filename = "tests/data/advanced.bin";
124
125    // Create output directory if it doesn't exist
126    if std::fs::metadata("tests/data").is_err() {
127        std::fs::create_dir_all("tests/data").expect("Failed to create tests/data directory");
128    }
129
130    std::fs::write(filename, &serialized).expect("Failed to write advanced EEPROM file");
131
132    println!("✅ Created {} ({} bytes)", filename, serialized.len());
133    println!("📊 EEPROM structure:");
134    println!("   • Header: 12 bytes");
135    println!(
136        "   • Vendor Info: {} bytes",
137        std::mem::size_of::<VendorInfoAtom>() + "4STM4 Ocultum".len() + "Advanced HAT Demo".len()
138    );
139    println!(
140        "   • GPIO Map Bank 0: {} bytes",
141        std::mem::size_of::<GpioMapAtom>()
142    );
143    println!(
144        "   • Device Tree Blob: {} bytes",
145        serialized.len()
146            - 12
147            - std::mem::size_of::<VendorInfoAtom>()
148            - "4STM4 Ocultum".len()
149            - "Advanced HAT Demo".len()
150            - std::mem::size_of::<GpioMapAtom>()
151            - 4
152    );
153    println!("   • CRC32: 4 bytes");
154
155    // Verify the created file
156    if Eeprom::verify_crc(&serialized) {
157        println!("✅ CRC32 verification passed");
158    } else {
159        println!("❌ CRC32 verification failed");
160    }
161
162    println!("🎯 Use './target/release/ehatrom show {filename}' to analyze the created EEPROM");
163}