scrapyard_core/
mcu.rs

1use std::fs::File;
2use std::path::Path;
3
4use module::peripheral::Peripheral;
5use pin::Pin;
6use pins::Pins;
7use package::Package;
8
9use serde_json;
10use errors::*;
11use memory::Memory;
12
13#[derive(Serialize, Deserialize, Debug)]
14pub enum Platform {
15    STM32 { family: String, line: String },
16    STM8,
17    AVR,
18    MSP430,
19}
20
21#[derive(Serialize, Deserialize, Debug, PartialEq)]
22pub enum ARMCore {
23    CortexM0,
24    CortexM3,
25    CortexM4,
26    CortexM7,
27}
28
29#[derive(Serialize, Deserialize, Debug, PartialEq)]
30pub enum Core {
31    ARM(ARMCore),
32    AVR,
33    STM8,
34    MSP430,
35}
36
37#[derive(Serialize, Deserialize, Debug, PartialEq)]
38pub struct MemoryConfiguration {
39    stack_addr: u32,
40    stack_size: u32,
41    heap_addr: u32,
42    heap_size: u32,
43}
44
45#[derive(Serialize, Deserialize, Debug, PartialEq)]
46pub enum Frequency {
47    MHz(u16),
48}
49
50#[allow(non_snake_case)]
51#[derive(Serialize, Deserialize, Debug)]
52pub struct IP {
53    pub config_file: String,
54    pub name: String,
55}
56
57#[allow(non_snake_case)]
58#[derive(Serialize, Deserialize, Debug)]
59pub struct MCU {
60    pub memory: Vec<Memory>,
61    pub frequency: Frequency,
62    pub core: Core,
63    pub name: String,
64    pub package: Package,
65    pub ips: Vec<IP>,
66    pub pins: Vec<Pin>,
67    pub platform: Platform,
68}
69
70impl MCU {
71    pub fn new(path: &Path) -> Result<MCU> {
72        let file = File::open(path)?;
73        let mcu: MCU = serde_json::from_reader(file)?;
74
75        Ok(mcu)
76    }
77
78    fn process_peripherals(&self) -> Vec<Peripheral> {
79        let mut peripherals: Vec<Peripheral> = Vec::with_capacity(self.ips.len());
80
81        for ip in &self.ips {
82            match ip.name.as_ref() {
83                name @ "GPIO" => {
84                    println!("IO peripheral {}, {}", name, ip.config_file);
85                    //let pins = PinsBuilder::new(&ip.name, &ip.config_file, &mut self.mcu.pins);
86                    //peripherals.push(pins.finish());
87                }
88                name => {
89                    println!("Peripheral: {}, {}", name, ip.config_file);
90                    let peripheral = Peripheral::new(&name, &ip.config_file);
91                    peripheral.setup();
92                    peripherals.push(peripheral);
93                }
94            }
95        }
96
97        peripherals
98    }
99
100    pub fn finish(self) -> MCUConf {
101        let peripherals = self.process_peripherals();
102        let middlewares: Vec<String> = Vec::new();
103        let components: Vec<String> = Vec::new();
104
105        let memory_configuration = MemoryConfiguration {
106            stack_addr: 0,
107            stack_size: 0,
108            heap_addr: 0,
109            heap_size: 0,
110        };
111
112        MCUConf {
113            memory: self.memory,
114            memory_configuration: memory_configuration,
115            frequency: self.frequency,
116            platform: self.platform,
117            core: self.core,
118            name: self.name,
119            package: self.package,
120            periherals: peripherals,
121            middlewares: middlewares,
122            components: components,
123            pins: Pins { pins: self.pins },
124        }
125    }
126}
127
128#[derive(Serialize, Deserialize, Debug)]
129pub struct MCUConf {
130    memory: Vec<Memory>,
131    memory_configuration: MemoryConfiguration,
132    frequency: Frequency,
133    platform: Platform,
134    core: Core,
135    name: String,
136    package: Package,
137    periherals: Vec<Peripheral>,
138    middlewares: Vec<String>,
139    components: Vec<String>,
140    pins: Pins,
141}
142
143impl MCUConf {
144    pub fn get_name(&self) -> &str {
145        &self.name
146    }
147
148    pub fn get_pins(&self) -> &Pins {
149        &self.pins
150    }
151
152    pub fn get_pins_mut(&mut self) -> &mut Pins {
153        &mut self.pins
154    }
155
156    pub fn get_peripherals(&self) -> &Vec<Peripheral> {
157        &self.periherals
158    }
159
160    pub fn get_peripherals_mut(&mut self) -> &mut Vec<Peripheral> {
161        &mut self.periherals
162    }
163
164    pub fn get_package(&self) -> &Package {
165        &self.package
166    }
167
168    pub fn get_platform(&self) -> &Platform {
169        &self.platform
170    }
171
172    pub fn get_frequency(&self) -> &Frequency {
173        &self.frequency
174    }
175
176    pub fn get_core(&self) -> &Core {
177        &self.core
178    }
179
180    pub fn get_memory(&self) -> &Vec<Memory> {
181        &self.memory
182    }
183
184    pub fn get_memory_mut(&mut self) -> &mut Vec<Memory> {
185        &mut self.memory
186    }
187
188    pub fn get_memory_configuration(&self) -> &MemoryConfiguration {
189        &self.memory_configuration
190    }
191
192    pub fn get_memory_configuration_mut(&mut self) -> &mut MemoryConfiguration {
193        &mut self.memory_configuration
194    }
195}
196
197#[cfg(test)]
198mod tests {
199    // TODO: Check for memory and IPs
200    use super::*;
201    use pin::Position;
202    // TODO: Test for no file
203    #[test]
204    fn no_file() {
205        let sample = Path::new(".samples/none.json");
206        let mcu = MCU::new(sample);
207        //assert!(mcu.err(), Err(std::io::ErrorKind::NotFound));
208    }
209
210    // TODO: Test no file
211    // TODO: Test json error
212    #[test]
213    fn mcubuilder_load() {
214        let sample = Path::new("./samples/STM32F030C6Tx.json");
215        let mcu = MCU::new(sample).unwrap();
216
217        assert_eq!(mcu.core, Core::ARM(ARMCore::CortexM0));
218        assert_eq!(2, mcu.memory.len());
219        assert_eq!(
220            Memory::Flash {
221                start: 0x08000000,
222                size: 32768,
223            },
224            mcu.memory[0]
225        );
226        assert_eq!(
227            Memory::Ram {
228                start: 0x20000000,
229                size: 4096,
230            },
231            mcu.memory[1]
232        );
233        assert_eq!(mcu.frequency, Frequency::MHz(48));
234        assert_eq!(mcu.name, "STM32F030C6Tx");
235        assert_eq!(mcu.package, Package::LQFP(48));
236        assert_eq!(mcu.ips.len(), 19);
237    }
238
239    #[test]
240    fn mcubuilder_builder() {
241        let sample = Path::new("./samples/STM32F030C6Tx.json");
242        let mcu = MCU::new(sample).unwrap();
243
244        let mcu_conf = mcu.finish();
245
246        assert_eq!(mcu_conf.core, Core::ARM(ARMCore::CortexM0));
247        assert_eq!(2, mcu_conf.memory.len());
248        assert_eq!(
249            Memory::Flash {
250                start: 0x08000000,
251                size: 32768,
252            },
253            mcu_conf.memory[0]
254        );
255        assert_eq!(
256            Memory::Ram {
257                start: 0x20000000,
258                size: 4096,
259            },
260            mcu_conf.memory[1]
261        );
262        assert_eq!(mcu_conf.frequency, Frequency::MHz(48));
263        assert_eq!(mcu_conf.name, "STM32F030C6Tx");
264        match mcu_conf.package {
265            Package::LQFP(_) => assert!(true),
266            _ => assert!(false),
267        };
268    }
269
270    #[test]
271    fn ip_ok() {
272        let json = r#"{ "config_file" : "adc.conf",
273    					"name" : "ADC"}"#;
274
275        let ip: IP = serde_json::from_str(json).unwrap();
276
277        assert_eq!(ip.config_file, "adc.conf");
278        assert_eq!(ip.name, "ADC");
279    }
280
281    #[test]
282    fn pin_ok() {
283        let json = r#"{"POWER":{"name":"VSS","position":{"Linear":47}}}"#;
284
285        let pin: Pin = serde_json::from_str(json).unwrap();
286
287        assert_eq!(pin.name(), "VSS");
288        assert_eq!(*pin.position(), Position::Linear(47));
289        match pin {
290            Pin::POWER { .. } => assert!(true),
291            _ => assert!(false),
292        };
293    }
294}