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