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     private:
60 
61         /**
62          * Finds the GPIO device path for this device
63          */
64         void findGPIODevice();
65 
66         /**
67          * Checks for VOUT faults on the device.
68          *
69          * This device can monitor voltages of its dependent
70          * devices, and VOUT faults are voltage faults
71          * on these devices.
72          *
73          * @return bool - true if an error log was created
74          */
75         bool checkVOUTFaults();
76 
77         /**
78          * Checks for PGOOD faults on the device.
79          *
80          * This device can monitor the PGOOD signals of its dependent
81          * devices, and this check will look for faults of
82          * those PGOODs.
83          *
84          * @param[in] polling - If this is running while polling for errors,
85          *                      as opposing to analyzing a fail condition.
86          *
87          * @return bool - true if an error log was created
88          */
89          bool checkPGOODFaults(bool polling);
90 
91         /**
92          * Creates an error log when the device has an error
93          * but it isn't a PGOOD or voltage failure.
94          */
95         void createPowerFaultLog();
96 
97         /**
98          * Reads the status_word register
99          *
100          * @return uint16_t - the register contents
101          */
102         uint16_t readStatusWord();
103 
104         /**
105          * Reads the mfr_status register
106          *
107          * @return uint32_t - the register contents
108          */
109         uint32_t readMFRStatus();
110 
111         /**
112          * Says if we've already logged a Vout fault
113          *
114          * The policy is only 1 of the same error will
115          * be logged for the duration of a class instance.
116          *
117          * @param[in] page - the page to check
118          *
119          * @return bool - if we've already logged a fault against
120          *                this page
121          */
122         inline bool isVoutFaultLogged(uint32_t page) const
123         {
124             return std::find(voutErrors.begin(),
125                              voutErrors.end(),
126                              page) != voutErrors.end();
127         }
128 
129         /**
130          * Saves that a Vout fault has been logged
131          *
132          * @param[in] page - the page the error was logged against
133          */
134         inline void setVoutFaultLogged(uint32_t page)
135         {
136             voutErrors.push_back(page);
137         }
138 
139         /**
140          * Says if we've already logged a PGOOD fault
141          *
142          * The policy is only 1 of the same errors will
143          * be logged for the duration of a class instance.
144          *
145          * @param[in] input - the input to check
146          *
147          * @return bool - if we've already logged a fault against
148          *                this input
149          */
150         inline bool isPGOODFaultLogged(uint32_t input) const
151         {
152             return std::find(pgoodErrors.begin(),
153                              pgoodErrors.end(),
154                              input) != pgoodErrors.end();
155         }
156 
157         /**
158          * Saves that a PGOOD fault has been logged
159          *
160          * @param[in] input - the input the error was logged against
161          */
162         inline void setPGOODFaultLogged(uint32_t input)
163         {
164             pgoodErrors.push_back(input);
165         }
166 
167         /**
168          * List of pages that Vout errors have
169          * already been logged against
170          */
171         std::vector<uint32_t> voutErrors;
172 
173         /**
174          * List of inputs that PGOOD errors have
175          * already been logged against
176          */
177         std::vector<uint32_t> pgoodErrors;
178 
179         /**
180          * The read/write interface to this hardware
181          */
182         pmbus::PMBus interface;
183 
184         /**
185          * A map of GPI pin IDs to the GPIO object
186          * used to access them
187          */
188         std::map<size_t, std::unique_ptr<gpio::GPIO>> gpios;
189 
190         /**
191          * Keeps track of device access errors to avoid repeatedly
192          * logging errors for bad hardware
193          */
194         bool accessError = false;
195 
196         /**
197          * The path to the GPIO device used to read
198          * the GPI (PGOOD) status
199          */
200         std::experimental::filesystem::path gpioDevice;
201 
202         /**
203          * Map of device instance to the instance specific data
204          */
205         static const ucd90160::DeviceMap deviceMap;
206 };
207 
208 }
209 }
210