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 }
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 use super::*;
201 use pin::Position;
202 #[test]
204 fn no_file() {
205 let sample = Path::new(".samples/none.json");
206 let mcu = MCU::new(sample);
207 }
209
210 #[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}