scrapyard_core/
pins.rs

1use pin::Pin;
2
3// Pins class
4//
5//    Holds configuration for all the pins. All pin modifications are connected to slots of this class.
6//
7//    \sa Peripheral, Pin
8#[derive(Serialize, Deserialize, Debug)]
9pub struct Pins {
10    pub pins: Vec<Pin>,
11}
12
13impl Pins {
14    pub fn pins(&self) -> &Vec<Pin> {
15        &self.pins
16    }
17
18    pub fn pins_mut(&mut self) -> &Vec<Pin> {
19        &mut self.pins
20    }
21
22    pub fn find_pin(&self, name: &str) -> Vec<usize> {
23        let mut pins: Vec<usize> = vec![];
24
25        for (idx, pin) in self.pins.iter().enumerate() {
26            if pin.name() == name {
27                pins.push(idx);
28            } else {
29                match pin.params() {
30                    Some(params) => {
31                        match params.signals().iter().position(|ref s| s.contains(name)) {
32                            Some(_) => pins.push(idx),
33                            None => (),
34                        }
35                    }
36                    None => (),
37                }
38            }
39        }
40
41        pins
42    }
43
44    pub fn find_alternate_pins(&self, pin_idx: usize, name: &str) -> Vec<usize> {
45        let mut pins: Vec<usize> = vec![];
46
47        for (idx, pin) in self.pins.iter().enumerate() {
48            match pin.params() {
49                Some(params) => match params.signals().iter().position(|ref s| s.contains(name)) {
50                    Some(_) => if idx != pin_idx {
51                        pins.push(idx)
52                    },
53                    None => (),
54                },
55                None => (),
56            }
57        }
58
59        pins
60    }
61
62    // Configures or resets pins belonging to peripheral
63
64    //    Handles the configuration of pin with signals \p peripheralPins. Iterates through pins until finds pin with corresponding peripheral signal. Parameter \p state either sets the alternate signal on the pin if it's reset or resets the pin if it's configured with the same alternate signal.
65
66    //    \param peripheralPins List of alternate functions to configure
67    //    \param state Configure or reset the pin
68    //
69    //fn peripheral_pins() {}
70    //void Pins::onPeripheralPins(QList<QString> peripheralPins, Pin::PinState state)
71    //{
72
73    //    Pin::AlternateFunction alternateFunction;
74
75    //    bool configured;
76
77    //    // TODO: Handle when the are no pins available for configuration
78    //    foreach (QString value, peripheralPins) {
79
80    //        configured = false;
81
82    //        foreach (pin, pins) {
83
84    //            foreach (alternateFunction, pin->getAlternateFunctions()) {
85
86    //                if (alternateFunction.name == value) {
87
88    //                    if (state == Pin::PIN_ASSIGNED) {
89
90    //                        if (pin->isReset()) {
91
92    //                            //pin->setGpioMode(GPIOStr::gpioModeStr[3]);
93    //                            pin->selectAlternateFunction(value);
94
95    //                            //emit pinFunctionChanged (pin->getName(), state, value);
96
97    //                            configured = true;
98
99    //                            break;
100    //                            }
101    //                        }
102    //                    else {
103
104    //                        if (pin->getAlternateFunction().name == value) {
105
106    //                            pin->resetPin();
107
108    //                            //emit pinFunctionChanged (pin->getName(), Pin::Pins_RESET, "");
109
110    //                            configured = true;
111
112    //                            break;
113    //                            }
114    //                        }
115    //                    }
116    //                }
117
118    //            if (configured){
119
120    //                break;
121    //                }
122    //            }
123    //        }
124    //}
125}
126
127#[cfg(test)]
128mod tests {
129
130    use std::path::Path;
131    use mcu::MCU;
132
133    #[test]
134    fn load_pins_ok() {
135        let sample = Path::new("./samples/STM32F030C6Tx.json");
136        let mcu = MCU::new(sample).unwrap();
137
138        let mcu_conf = mcu.finish();
139        let _pins = mcu_conf.get_pins();
140    }
141
142    #[test]
143    fn find_pin_ok() {
144        let sample = Path::new("./samples/STM32F030C6Tx.json");
145        let mcu = MCU::new(sample).unwrap();
146
147        let mcu_conf = mcu.finish();
148        let pins = mcu_conf.get_pins();
149
150        let found = pins.find_pin("PA2");
151
152        assert_eq!(vec![11], found);
153    }
154
155    #[test]
156    fn find_signal_ok() {
157        let sample = Path::new("./samples/STM32F030C6Tx.json");
158        let mcu = MCU::new(sample).unwrap();
159
160        let mcu_conf = mcu.finish();
161        let pins = mcu_conf.get_pins();
162
163        let found = pins.find_pin("USART1_DE");
164
165        assert_eq!(vec![10, 32], found);
166    }
167
168    #[test]
169    fn find_signal_empty() {
170        let sample = Path::new("./samples/STM32F030C6Tx.json");
171        let mcu = MCU::new(sample).unwrap();
172
173        let mcu_conf = mcu.finish();
174        let pins = mcu_conf.get_pins();
175
176        let found = pins.find_pin("XXXX");
177
178        let empty: Vec<usize> = Vec::new();
179        assert_eq!(empty, found);
180    }
181
182    #[test]
183    fn find_alternative_pins_multiple() {
184        let sample = Path::new("./samples/STM32F030C6Tx.json");
185        let mcu = MCU::new(sample).unwrap();
186
187        let mcu_conf = mcu.finish();
188        let pins = mcu_conf.get_pins();
189
190        let found = pins.find_alternate_pins(13, "SPI1_NSS");
191
192        assert_eq!(vec![24, 37], found);
193    }
194
195    #[test]
196    fn find_alternative_pins_none() {
197        let sample = Path::new("./samples/STM32F030C6Tx.json");
198        let mcu = MCU::new(sample).unwrap();
199
200        let mcu_conf = mcu.finish();
201        let pins = mcu_conf.get_pins();
202
203        let found = pins.find_alternate_pins(2, "RCC_OSC32_IN");
204
205        assert_eq!(Vec::<usize>::new(), found);
206    }
207}