1*7f9d41ddSJagpal Singh Gill #pragma once 2*7f9d41ddSJagpal Singh Gill 3*7f9d41ddSJagpal Singh Gill #include "modbus/modbus.hpp" 4*7f9d41ddSJagpal Singh Gill 5*7f9d41ddSJagpal Singh Gill #include <phosphor-logging/lg2.hpp> 6*7f9d41ddSJagpal Singh Gill #include <sdbusplus/async.hpp> 7*7f9d41ddSJagpal Singh Gill #include <xyz/openbmc_project/Configuration/USBPort/client.hpp> 8*7f9d41ddSJagpal Singh Gill 9*7f9d41ddSJagpal Singh Gill #include <concepts> 10*7f9d41ddSJagpal Singh Gill 11*7f9d41ddSJagpal Singh Gill namespace phosphor::modbus::rtu::port 12*7f9d41ddSJagpal Singh Gill { 13*7f9d41ddSJagpal Singh Gill 14*7f9d41ddSJagpal Singh Gill using ModbusIntf = phosphor::modbus::rtu::Modbus; 15*7f9d41ddSJagpal Singh Gill 16*7f9d41ddSJagpal Singh Gill namespace config 17*7f9d41ddSJagpal Singh Gill { 18*7f9d41ddSJagpal Singh Gill 19*7f9d41ddSJagpal Singh Gill enum class PortMode 20*7f9d41ddSJagpal Singh Gill { 21*7f9d41ddSJagpal Singh Gill rs232, 22*7f9d41ddSJagpal Singh Gill rs485, 23*7f9d41ddSJagpal Singh Gill unknown 24*7f9d41ddSJagpal Singh Gill }; 25*7f9d41ddSJagpal Singh Gill 26*7f9d41ddSJagpal Singh Gill static constexpr std::array<std::pair<std::string_view, PortMode>, 2> 27*7f9d41ddSJagpal Singh Gill validPortModes = {{{"RS232", PortMode::rs232}, {"RS485", PortMode::rs485}}}; 28*7f9d41ddSJagpal Singh Gill 29*7f9d41ddSJagpal Singh Gill struct Config 30*7f9d41ddSJagpal Singh Gill { 31*7f9d41ddSJagpal Singh Gill std::string name = "unknown"; 32*7f9d41ddSJagpal Singh Gill PortMode portMode = PortMode::unknown; 33*7f9d41ddSJagpal Singh Gill uint32_t baudRate = 0; 34*7f9d41ddSJagpal Singh Gill uint16_t rtsDelay = 0; 35*7f9d41ddSJagpal Singh Gill }; 36*7f9d41ddSJagpal Singh Gill 37*7f9d41ddSJagpal Singh Gill template <typename T> 38*7f9d41ddSJagpal Singh Gill concept HasPropertiesMembers = requires(T properties) { 39*7f9d41ddSJagpal Singh Gill { 40*7f9d41ddSJagpal Singh Gill properties.name 41*7f9d41ddSJagpal Singh Gill } -> std::same_as<std::string&>; 42*7f9d41ddSJagpal Singh Gill { 43*7f9d41ddSJagpal Singh Gill properties.mode 44*7f9d41ddSJagpal Singh Gill } -> std::same_as<std::string&>; 45*7f9d41ddSJagpal Singh Gill { 46*7f9d41ddSJagpal Singh Gill properties.baud_rate 47*7f9d41ddSJagpal Singh Gill } -> std::same_as<uint64_t&>; 48*7f9d41ddSJagpal Singh Gill { 49*7f9d41ddSJagpal Singh Gill properties.rts_delay 50*7f9d41ddSJagpal Singh Gill } -> std::same_as<uint64_t&>; 51*7f9d41ddSJagpal Singh Gill }; 52*7f9d41ddSJagpal Singh Gill 53*7f9d41ddSJagpal Singh Gill template <typename T> 54*7f9d41ddSJagpal Singh Gill concept HasConfigMembers = requires(T config) { 55*7f9d41ddSJagpal Singh Gill { config.name } -> std::same_as<std::string&>; 56*7f9d41ddSJagpal Singh Gill { config.portMode } -> std::same_as<PortMode&>; 57*7f9d41ddSJagpal Singh Gill { config.baudRate } -> std::same_as<uint32_t&>; 58*7f9d41ddSJagpal Singh Gill { config.rtsDelay } -> std::same_as<uint16_t&>; 59*7f9d41ddSJagpal Singh Gill }; 60*7f9d41ddSJagpal Singh Gill 61*7f9d41ddSJagpal Singh Gill template <HasConfigMembers BaseConfig, HasPropertiesMembers BaseProperties> 62*7f9d41ddSJagpal Singh Gill auto updateBaseConfig(BaseConfig& config, const BaseProperties& properties) 63*7f9d41ddSJagpal Singh Gill -> bool 64*7f9d41ddSJagpal Singh Gill { 65*7f9d41ddSJagpal Singh Gill PHOSPHOR_LOG2_USING; 66*7f9d41ddSJagpal Singh Gill 67*7f9d41ddSJagpal Singh Gill config.name = properties.name; 68*7f9d41ddSJagpal Singh Gill config.baudRate = static_cast<uint32_t>(properties.baud_rate); 69*7f9d41ddSJagpal Singh Gill config.rtsDelay = static_cast<uint16_t>(properties.rts_delay); 70*7f9d41ddSJagpal Singh Gill 71*7f9d41ddSJagpal Singh Gill for (const auto& [modeStr, portMode] : config::validPortModes) 72*7f9d41ddSJagpal Singh Gill { 73*7f9d41ddSJagpal Singh Gill if (modeStr == properties.mode) 74*7f9d41ddSJagpal Singh Gill { 75*7f9d41ddSJagpal Singh Gill config.portMode = portMode; 76*7f9d41ddSJagpal Singh Gill break; 77*7f9d41ddSJagpal Singh Gill } 78*7f9d41ddSJagpal Singh Gill } 79*7f9d41ddSJagpal Singh Gill if (config.portMode == PortMode::unknown) 80*7f9d41ddSJagpal Singh Gill { 81*7f9d41ddSJagpal Singh Gill error("Invalid port mode {PORT_MODE} for {NAME}", "PORT_MODE", 82*7f9d41ddSJagpal Singh Gill properties.mode, "NAME", properties.name); 83*7f9d41ddSJagpal Singh Gill return false; 84*7f9d41ddSJagpal Singh Gill } 85*7f9d41ddSJagpal Singh Gill 86*7f9d41ddSJagpal Singh Gill debug("Base Port config: {NAME} {PORT_MODE} {BAUD_RATE} {RTS_DELAY}", 87*7f9d41ddSJagpal Singh Gill "NAME", config.name, "PORT_MODE", config.portMode, "BAUD_RATE", 88*7f9d41ddSJagpal Singh Gill config.baudRate, "RTS_DELAY", config.rtsDelay); 89*7f9d41ddSJagpal Singh Gill 90*7f9d41ddSJagpal Singh Gill return true; 91*7f9d41ddSJagpal Singh Gill } 92*7f9d41ddSJagpal Singh Gill 93*7f9d41ddSJagpal Singh Gill } // namespace config 94*7f9d41ddSJagpal Singh Gill 95*7f9d41ddSJagpal Singh Gill class BasePort 96*7f9d41ddSJagpal Singh Gill { 97*7f9d41ddSJagpal Singh Gill public: 98*7f9d41ddSJagpal Singh Gill explicit BasePort(sdbusplus::async::context& ctx, 99*7f9d41ddSJagpal Singh Gill const config::Config& config, 100*7f9d41ddSJagpal Singh Gill const std::string& devicePath); 101*7f9d41ddSJagpal Singh Gill 102*7f9d41ddSJagpal Singh Gill auto readHoldingRegisters(uint8_t deviceAddress, uint16_t registerOffset, 103*7f9d41ddSJagpal Singh Gill uint32_t baudRate, Parity parity, 104*7f9d41ddSJagpal Singh Gill std::vector<uint16_t>& registers) 105*7f9d41ddSJagpal Singh Gill -> sdbusplus::async::task<bool>; 106*7f9d41ddSJagpal Singh Gill 107*7f9d41ddSJagpal Singh Gill private: 108*7f9d41ddSJagpal Singh Gill std::string name; 109*7f9d41ddSJagpal Singh Gill int fd = -1; 110*7f9d41ddSJagpal Singh Gill std::unique_ptr<ModbusIntf> modbus; 111*7f9d41ddSJagpal Singh Gill sdbusplus::async::mutex mutex; 112*7f9d41ddSJagpal Singh Gill }; 113*7f9d41ddSJagpal Singh Gill 114*7f9d41ddSJagpal Singh Gill } // namespace phosphor::modbus::rtu::port 115