1 #pragma once
2 
3 #include <algorithm>
4 #include <experimental/filesystem>
5 #include <map>
6 #include <vector>
7 #include "device.hpp"
8 #include "gpio.hpp"
9 #include "pmbus.hpp"
10 #include "types.hpp"
11 
12 namespace witherspoon
13 {
14 namespace power
15 {
16 
17 /**
18  * @class UCD90160
19  *
20  * This class implements fault analysis for the UCD90160
21  * power sequencer device.
22  *
23  */
24 class UCD90160 : public Device
25 {
26     public:
27 
28         UCD90160() = delete;
29         ~UCD90160() = default;
30         UCD90160(const UCD90160&) = delete;
31         UCD90160& operator=(const UCD90160&) = delete;
32         UCD90160(UCD90160&&) = default;
33         UCD90160& operator=(UCD90160&&) = default;
34 
35         /**
36          * Constructor
37          *
38          * @param[in] instance - the device instance number
39          */
40         UCD90160(size_t instance);
41 
42         /**
43          * Analyzes the device for errors when the device is
44          * known to be in an error state.  A log will be created.
45          */
46         void onFailure() override;
47 
48         /**
49          * Checks the device for errors and only creates a log
50          * if one is found.
51          */
52         void analyze() override;
53 
54         /**
55          * Clears faults in the device
56          */
57         void clearFaults() override
58         {
59         }
60 
61     private:
62 
63         /**
64          * Finds the GPIO device path for this device
65          */
66         void findGPIODevice();
67 
68         /**
69          * Checks for VOUT faults on the device.
70          *
71          * This device can monitor voltages of its dependent
72          * devices, and VOUT faults are voltage faults
73          * on these devices.
74          *
75          * @return bool - true if an error log was created
76          */
77         bool checkVOUTFaults();
78 
79         /**
80          * Checks for PGOOD faults on the device.
81          *
82          * This device can monitor the PGOOD signals of its dependent
83          * devices, and this check will look for faults of
84          * those PGOODs.
85          *
86          * @param[in] polling - If this is running while polling for errors,
87          *                      as opposing to analyzing a fail condition.
88          *
89          * @return bool - true if an error log was created
90          */
91          bool checkPGOODFaults(bool polling);
92 
93         /**
94          * Creates an error log when the device has an error
95          * but it isn't a PGOOD or voltage failure.
96          */
97         void createPowerFaultLog();
98 
99         /**
100          * Reads the status_word register
101          *
102          * @return uint16_t - the register contents
103          */
104         uint16_t readStatusWord();
105 
106         /**
107          * Reads the mfr_status register
108          *
109          * @return uint32_t - the register contents
110          */
111         uint32_t readMFRStatus();
112 
113         /**
114          * Says if we've already logged a Vout fault
115          *
116          * The policy is only 1 of the same error will
117          * be logged for the duration of a class instance.
118          *
119          * @param[in] page - the page to check
120          *
121          * @return bool - if we've already logged a fault against
122          *                this page
123          */
124         inline bool isVoutFaultLogged(uint32_t page) const
125         {
126             return std::find(voutErrors.begin(),
127                              voutErrors.end(),
128                              page) != voutErrors.end();
129         }
130 
131         /**
132          * Saves that a Vout fault has been logged
133          *
134          * @param[in] page - the page the error was logged against
135          */
136         inline void setVoutFaultLogged(uint32_t page)
137         {
138             voutErrors.push_back(page);
139         }
140 
141         /**
142          * Says if we've already logged a PGOOD fault
143          *
144          * The policy is only 1 of the same errors will
145          * be logged for the duration of a class instance.
146          *
147          * @param[in] input - the input to check
148          *
149          * @return bool - if we've already logged a fault against
150          *                this input
151          */
152         inline bool isPGOODFaultLogged(uint32_t input) const
153         {
154             return std::find(pgoodErrors.begin(),
155                              pgoodErrors.end(),
156                              input) != pgoodErrors.end();
157         }
158 
159         /**
160          * Saves that a PGOOD fault has been logged
161          *
162          * @param[in] input - the input the error was logged against
163          */
164         inline void setPGOODFaultLogged(uint32_t input)
165         {
166             pgoodErrors.push_back(input);
167         }
168 
169         /**
170          * List of pages that Vout errors have
171          * already been logged against
172          */
173         std::vector<uint32_t> voutErrors;
174 
175         /**
176          * List of inputs that PGOOD errors have
177          * already been logged against
178          */
179         std::vector<uint32_t> pgoodErrors;
180 
181         /**
182          * The read/write interface to this hardware
183          */
184         pmbus::PMBus interface;
185 
186         /**
187          * A map of GPI pin IDs to the GPIO object
188          * used to access them
189          */
190         std::map<size_t, std::unique_ptr<gpio::GPIO>> gpios;
191 
192         /**
193          * Keeps track of device access errors to avoid repeatedly
194          * logging errors for bad hardware
195          */
196         bool accessError = false;
197 
198         /**
199          * The path to the GPIO device used to read
200          * the GPI (PGOOD) status
201          */
202         std::experimental::filesystem::path gpioDevice;
203 
204         /**
205          * Map of device instance to the instance specific data
206          */
207         static const ucd90160::DeviceMap deviceMap;
208 };
209 
210 }
211 }
212