Matt Spinler | df797f2 | 2019-07-09 15:39:51 -0500 | [diff] [blame] | 1 | #pragma once |
| 2 | #include "stream.hpp" |
| 3 | |
| 4 | #include <chrono> |
| 5 | |
| 6 | namespace openpower |
| 7 | { |
| 8 | namespace pels |
| 9 | { |
| 10 | |
| 11 | /** |
| 12 | * @brief A structure that contains a PEL timestamp in BCD. |
| 13 | */ |
| 14 | struct BCDTime |
| 15 | { |
| 16 | uint8_t yearMSB; |
| 17 | uint8_t yearLSB; |
| 18 | uint8_t month; |
| 19 | uint8_t day; |
| 20 | uint8_t hour; |
| 21 | uint8_t minutes; |
| 22 | uint8_t seconds; |
| 23 | uint8_t hundredths; |
| 24 | |
Matt Spinler | 86c7036 | 2019-12-02 15:37:21 -0600 | [diff] [blame] | 25 | BCDTime() : |
| 26 | yearMSB(0), yearLSB(0), month(0), day(0), hour(0), minutes(0), |
| 27 | seconds(0), hundredths(0) |
Patrick Williams | 2544b41 | 2022-10-04 08:41:06 -0500 | [diff] [blame] | 28 | {} |
Matt Spinler | 86c7036 | 2019-12-02 15:37:21 -0600 | [diff] [blame] | 29 | |
| 30 | BCDTime(uint8_t yearMSB, uint8_t yearLSB, uint8_t month, uint8_t day, |
| 31 | uint8_t hour, uint8_t minutes, uint8_t seconds, |
| 32 | uint8_t hundredths) : |
| 33 | yearMSB(yearMSB), |
| 34 | yearLSB(yearLSB), month(month), day(day), hour(hour), minutes(minutes), |
| 35 | seconds(seconds), hundredths(hundredths) |
Patrick Williams | 2544b41 | 2022-10-04 08:41:06 -0500 | [diff] [blame] | 36 | {} |
Matt Spinler | 86c7036 | 2019-12-02 15:37:21 -0600 | [diff] [blame] | 37 | |
Matt Spinler | df797f2 | 2019-07-09 15:39:51 -0500 | [diff] [blame] | 38 | bool operator==(const BCDTime& right) const; |
| 39 | bool operator!=(const BCDTime& right) const; |
| 40 | |
| 41 | } __attribute__((packed)); |
| 42 | |
| 43 | /** |
| 44 | * @brief Converts a time_point into a BCD time |
| 45 | * |
| 46 | * @param[in] time - the time_point to convert |
| 47 | * @return BCDTime - the BCD time |
| 48 | */ |
| 49 | BCDTime getBCDTime(std::chrono::time_point<std::chrono::system_clock>& time); |
| 50 | |
| 51 | /** |
Matt Spinler | 5fa87f0 | 2019-08-27 16:31:57 -0500 | [diff] [blame] | 52 | * @brief Converts the number of milliseconds since the epoch into BCD time |
| 53 | * |
| 54 | * @param[in] milliseconds - Number of milliseconds since the epoch |
| 55 | * @return BCDTime - the BCD time |
| 56 | */ |
| 57 | BCDTime getBCDTime(uint64_t milliseconds); |
| 58 | |
| 59 | /** |
Matt Spinler | 0bf04b5 | 2023-04-28 10:30:26 -0500 | [diff] [blame] | 60 | * @brief Convert a BCDTime value into the number of |
| 61 | * milliseconds since the epoch (1/1/1970). |
| 62 | * |
| 63 | * @param[in] bcdTime - The BCD time value |
| 64 | * @return uint64_t - The milliseconds value |
| 65 | */ |
| 66 | uint64_t getMillisecondsSinceEpoch(const BCDTime& bcdTime); |
| 67 | |
| 68 | /** |
Matt Spinler | df797f2 | 2019-07-09 15:39:51 -0500 | [diff] [blame] | 69 | * @brief Converts a number to a BCD. |
| 70 | * |
| 71 | * For example 32 -> 0x32. |
| 72 | * |
| 73 | * Source: PLDM repository |
| 74 | * |
| 75 | * @param[in] value - the value to convert. |
| 76 | * |
| 77 | * @return T - the BCD value |
| 78 | */ |
| 79 | template <typename T> |
| 80 | T toBCD(T decimal) |
| 81 | { |
| 82 | T bcd = 0; |
| 83 | T remainder = 0; |
| 84 | auto count = 0; |
| 85 | |
| 86 | while (decimal) |
| 87 | { |
| 88 | remainder = decimal % 10; |
| 89 | bcd = bcd + (remainder << count); |
| 90 | decimal = decimal / 10; |
| 91 | count += 4; |
| 92 | } |
| 93 | |
| 94 | return bcd; |
| 95 | } |
| 96 | |
| 97 | /** |
Matt Spinler | 0bf04b5 | 2023-04-28 10:30:26 -0500 | [diff] [blame] | 98 | * @brief Converts a BCD byte to a decimal number. |
| 99 | * |
| 100 | * For example 0x22 -> 22. |
| 101 | * |
| 102 | * @param[in] bcd - The value in BCD |
| 103 | * @return int - The number in decimal |
| 104 | */ |
| 105 | inline int fromBCD(uint8_t bcd) |
| 106 | { |
| 107 | return (((bcd & 0xF0) >> 4) * 10) + (bcd & 0xF); |
| 108 | } |
| 109 | |
| 110 | /** |
Matt Spinler | df797f2 | 2019-07-09 15:39:51 -0500 | [diff] [blame] | 111 | * @brief Stream extraction operator for BCDTime |
| 112 | * |
| 113 | * @param[in] s - the Stream |
| 114 | * @param[out] time - the BCD time |
| 115 | * |
| 116 | * @return Stream& |
| 117 | */ |
| 118 | Stream& operator>>(Stream& s, BCDTime& time); |
| 119 | |
| 120 | /** |
| 121 | * @brief Stream insertion operator for BCDTime |
| 122 | * |
| 123 | * @param[in/out] s - the Stream |
| 124 | * @param[in] time - the BCD time |
| 125 | * |
| 126 | * @return Stream& |
| 127 | */ |
Matt Spinler | d7b004b | 2019-11-06 10:23:34 -0600 | [diff] [blame] | 128 | Stream& operator<<(Stream& s, const BCDTime& time); |
Matt Spinler | df797f2 | 2019-07-09 15:39:51 -0500 | [diff] [blame] | 129 | |
| 130 | } // namespace pels |
| 131 | } // namespace openpower |