1*83169bfeSShawn McCarney /** 2*83169bfeSShawn McCarney * Copyright © 2020 IBM Corporation 3*83169bfeSShawn McCarney * 4*83169bfeSShawn McCarney * Licensed under the Apache License, Version 2.0 (the "License"); 5*83169bfeSShawn McCarney * you may not use this file except in compliance with the License. 6*83169bfeSShawn McCarney * You may obtain a copy of the License at 7*83169bfeSShawn McCarney * 8*83169bfeSShawn McCarney * http://www.apache.org/licenses/LICENSE-2.0 9*83169bfeSShawn McCarney * 10*83169bfeSShawn McCarney * Unless required by applicable law or agreed to in writing, software 11*83169bfeSShawn McCarney * distributed under the License is distributed on an "AS IS" BASIS, 12*83169bfeSShawn McCarney * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*83169bfeSShawn McCarney * See the License for the specific language governing permissions and 14*83169bfeSShawn McCarney * limitations under the License. 15*83169bfeSShawn McCarney */ 16*83169bfeSShawn McCarney #pragma once 17*83169bfeSShawn McCarney 18*83169bfeSShawn McCarney #include "action_environment.hpp" 19*83169bfeSShawn McCarney #include "i2c_action.hpp" 20*83169bfeSShawn McCarney 21*83169bfeSShawn McCarney #include <cstdint> 22*83169bfeSShawn McCarney #include <stdexcept> 23*83169bfeSShawn McCarney #include <string> 24*83169bfeSShawn McCarney #include <vector> 25*83169bfeSShawn McCarney 26*83169bfeSShawn McCarney namespace phosphor::power::regulators 27*83169bfeSShawn McCarney { 28*83169bfeSShawn McCarney 29*83169bfeSShawn McCarney /** 30*83169bfeSShawn McCarney * @class I2CWriteBytesAction 31*83169bfeSShawn McCarney * 32*83169bfeSShawn McCarney * Writes bytes to a device register. Communicates with the device directly 33*83169bfeSShawn McCarney * using the I2C interface. 34*83169bfeSShawn McCarney * 35*83169bfeSShawn McCarney * Implements the i2c_write_bytes action in the JSON config file. 36*83169bfeSShawn McCarney */ 37*83169bfeSShawn McCarney class I2CWriteBytesAction : public I2CAction 38*83169bfeSShawn McCarney { 39*83169bfeSShawn McCarney public: 40*83169bfeSShawn McCarney // Specify which compiler-generated methods we want 41*83169bfeSShawn McCarney I2CWriteBytesAction() = delete; 42*83169bfeSShawn McCarney I2CWriteBytesAction(const I2CWriteBytesAction&) = delete; 43*83169bfeSShawn McCarney I2CWriteBytesAction(I2CWriteBytesAction&&) = delete; 44*83169bfeSShawn McCarney I2CWriteBytesAction& operator=(const I2CWriteBytesAction&) = delete; 45*83169bfeSShawn McCarney I2CWriteBytesAction& operator=(I2CWriteBytesAction&&) = delete; 46*83169bfeSShawn McCarney virtual ~I2CWriteBytesAction() = default; 47*83169bfeSShawn McCarney 48*83169bfeSShawn McCarney /** 49*83169bfeSShawn McCarney * Constructor. 50*83169bfeSShawn McCarney * 51*83169bfeSShawn McCarney * Throws an exception if any of the input parameters are invalid. 52*83169bfeSShawn McCarney * 53*83169bfeSShawn McCarney * @param reg Device register address. Note: named 'reg' because 'register' 54*83169bfeSShawn McCarney * is a reserved keyword. 55*83169bfeSShawn McCarney * @param values One or more byte values to write. The bytes must be 56*83169bfeSShawn McCarney * specified in the order required by the device (e.g. in 57*83169bfeSShawn McCarney * little-endian order). 58*83169bfeSShawn McCarney */ I2CWriteBytesAction(uint8_t reg,const std::vector<uint8_t> & values)59*83169bfeSShawn McCarney explicit I2CWriteBytesAction(uint8_t reg, 60*83169bfeSShawn McCarney const std::vector<uint8_t>& values) : 61*83169bfeSShawn McCarney reg{reg}, 62*83169bfeSShawn McCarney values{values}, masks{} 63*83169bfeSShawn McCarney { 64*83169bfeSShawn McCarney // Values vector must not be empty 65*83169bfeSShawn McCarney if (values.size() < 1) 66*83169bfeSShawn McCarney { 67*83169bfeSShawn McCarney throw std::invalid_argument{"Values vector is empty"}; 68*83169bfeSShawn McCarney } 69*83169bfeSShawn McCarney } 70*83169bfeSShawn McCarney 71*83169bfeSShawn McCarney /** 72*83169bfeSShawn McCarney * Constructor. 73*83169bfeSShawn McCarney * 74*83169bfeSShawn McCarney * Throws an exception if any of the input parameters are invalid. 75*83169bfeSShawn McCarney * 76*83169bfeSShawn McCarney * @param reg Device register address. Note: named 'reg' because 'register' 77*83169bfeSShawn McCarney * is a reserved keyword. 78*83169bfeSShawn McCarney * @param values One or more byte values to write. The bytes must be 79*83169bfeSShawn McCarney * specified in the order required by the device (e.g. in 80*83169bfeSShawn McCarney * little-endian order). 81*83169bfeSShawn McCarney * @param masks One or more bit masks. The number of bit masks must match 82*83169bfeSShawn McCarney * the number of byte values to write. Each mask specifies 83*83169bfeSShawn McCarney * which bits to write within the corresponding byte value. 84*83169bfeSShawn McCarney * Only the bits with a value of 1 in the mask will be written. 85*83169bfeSShawn McCarney */ I2CWriteBytesAction(uint8_t reg,const std::vector<uint8_t> & values,const std::vector<uint8_t> & masks)86*83169bfeSShawn McCarney explicit I2CWriteBytesAction(uint8_t reg, 87*83169bfeSShawn McCarney const std::vector<uint8_t>& values, 88*83169bfeSShawn McCarney const std::vector<uint8_t>& masks) : 89*83169bfeSShawn McCarney reg{reg}, 90*83169bfeSShawn McCarney values{values}, masks{masks} 91*83169bfeSShawn McCarney { 92*83169bfeSShawn McCarney // Values vector must not be empty 93*83169bfeSShawn McCarney if (values.size() < 1) 94*83169bfeSShawn McCarney { 95*83169bfeSShawn McCarney throw std::invalid_argument{"Values vector is empty"}; 96*83169bfeSShawn McCarney } 97*83169bfeSShawn McCarney 98*83169bfeSShawn McCarney // Masks vector must have same size as values vector 99*83169bfeSShawn McCarney if (masks.size() != values.size()) 100*83169bfeSShawn McCarney { 101*83169bfeSShawn McCarney throw std::invalid_argument{"Masks vector has invalid size"}; 102*83169bfeSShawn McCarney } 103*83169bfeSShawn McCarney } 104*83169bfeSShawn McCarney 105*83169bfeSShawn McCarney /** 106*83169bfeSShawn McCarney * Executes this action. 107*83169bfeSShawn McCarney * 108*83169bfeSShawn McCarney * Writes bytes to a device register using the I2C interface. 109*83169bfeSShawn McCarney * 110*83169bfeSShawn McCarney * All of the bytes will be written in a single I2C operation. 111*83169bfeSShawn McCarney * 112*83169bfeSShawn McCarney * The device register, byte values, and bit masks (if any) were specified 113*83169bfeSShawn McCarney * in the constructor. 114*83169bfeSShawn McCarney * 115*83169bfeSShawn McCarney * The device is obtained from the specified action environment. 116*83169bfeSShawn McCarney * 117*83169bfeSShawn McCarney * Throws an exception if an error occurs. 118*83169bfeSShawn McCarney * 119*83169bfeSShawn McCarney * @param environment action execution environment 120*83169bfeSShawn McCarney * @return true 121*83169bfeSShawn McCarney */ 122*83169bfeSShawn McCarney virtual bool execute(ActionEnvironment& environment) override; 123*83169bfeSShawn McCarney 124*83169bfeSShawn McCarney /** 125*83169bfeSShawn McCarney * Returns the device register address. 126*83169bfeSShawn McCarney * 127*83169bfeSShawn McCarney * @return register address 128*83169bfeSShawn McCarney */ getRegister() const129*83169bfeSShawn McCarney uint8_t getRegister() const 130*83169bfeSShawn McCarney { 131*83169bfeSShawn McCarney return reg; 132*83169bfeSShawn McCarney } 133*83169bfeSShawn McCarney 134*83169bfeSShawn McCarney /** 135*83169bfeSShawn McCarney * Returns the byte values to write. 136*83169bfeSShawn McCarney * 137*83169bfeSShawn McCarney * @return values to write 138*83169bfeSShawn McCarney */ getValues() const139*83169bfeSShawn McCarney const std::vector<uint8_t>& getValues() const 140*83169bfeSShawn McCarney { 141*83169bfeSShawn McCarney return values; 142*83169bfeSShawn McCarney } 143*83169bfeSShawn McCarney 144*83169bfeSShawn McCarney /** 145*83169bfeSShawn McCarney * Returns the bit masks. 146*83169bfeSShawn McCarney * 147*83169bfeSShawn McCarney * Each mask specifies which bits to write within the corresponding byte 148*83169bfeSShawn McCarney * value. Only the bits with a value of 1 in the mask will be written. 149*83169bfeSShawn McCarney * 150*83169bfeSShawn McCarney * @return bit masks 151*83169bfeSShawn McCarney */ getMasks() const152*83169bfeSShawn McCarney const std::vector<uint8_t>& getMasks() const 153*83169bfeSShawn McCarney { 154*83169bfeSShawn McCarney return masks; 155*83169bfeSShawn McCarney } 156*83169bfeSShawn McCarney 157*83169bfeSShawn McCarney /** 158*83169bfeSShawn McCarney * Returns a string description of this action. 159*83169bfeSShawn McCarney * 160*83169bfeSShawn McCarney * @return description of action 161*83169bfeSShawn McCarney */ 162*83169bfeSShawn McCarney virtual std::string toString() const override; 163*83169bfeSShawn McCarney 164*83169bfeSShawn McCarney private: 165*83169bfeSShawn McCarney /** 166*83169bfeSShawn McCarney * Device register address. Note: named 'reg' because 'register' is a 167*83169bfeSShawn McCarney * reserved keyword. 168*83169bfeSShawn McCarney */ 169*83169bfeSShawn McCarney const uint8_t reg{0x00}; 170*83169bfeSShawn McCarney 171*83169bfeSShawn McCarney /** 172*83169bfeSShawn McCarney * Byte values to write. 173*83169bfeSShawn McCarney */ 174*83169bfeSShawn McCarney const std::vector<uint8_t> values{}; 175*83169bfeSShawn McCarney 176*83169bfeSShawn McCarney /** 177*83169bfeSShawn McCarney * Bit masks. Each mask specifies which bits to write within the 178*83169bfeSShawn McCarney * corresponding byte value. Only the bits with a value of 1 in the mask 179*83169bfeSShawn McCarney * will be written. 180*83169bfeSShawn McCarney */ 181*83169bfeSShawn McCarney const std::vector<uint8_t> masks{}; 182*83169bfeSShawn McCarney }; 183*83169bfeSShawn McCarney 184*83169bfeSShawn McCarney } // namespace phosphor::power::regulators 185