1 Star 0 Fork 0

梅花三弄再回首/smbus-cpp

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
SMBus.cpp 6.59 KB
一键复制 编辑 原始数据 按行查看 历史
梅花三弄再回首 提交于 2024-10-10 14:28 +08:00 . 更换了数组结束符
/**
* @file SMBus.h
* @brief smbus-cpp项目头文件,包含所有类定义
* @author 梅花
* @data 2024年10月9日22:32:48
* @version 0.1
* @copyright 梅花
*/
#include "SMBus.h"
void SMBus::close()
{
if ((this->fd != -1) && (::close(this->fd) == -1))
{
throw std::ios_base::failure("I/O error!");
}
this->fd = -1;
this->addr = -1;
this->pec = 0;
}
void SMBus::open(int bus)
{
char path[MAXPATH];
if (snprintf(path, MAXPATH, "/dev/i2c-%d", bus) >= MAXPATH)
{
throw std::logic_error("Bus number is invalid.");
}
if ((this->fd = ::open(path, O_RDWR, 0)) == -1)
{
throw std::ios_base::failure("I/O error!");
}
}
SMBus::SMBus(int bus)
{
if (bus >= 0)
{
this->open(bus);
}
}
void SMBus::set_addr(int addr)
{
int ret = 0;
if (this->addr != addr)
{
ret = ioctl(this->fd, I2C_SLAVE, addr);
this->addr = addr;
}
if (ret)
throw std::ios_base::failure("I/O error!");
}
void SMBus::write_quick(int addr)
{
this->set_addr(addr);
if (i2c_smbus_write_quick(this->fd, I2C_SMBUS_WRITE))
{
throw std::ios_base::failure("I/O error!");
}
}
long SMBus::read_byte(int addr)
{
__s32 result = i2c_smbus_read_byte(this->fd);
if (result < 0)
throw std::ios_base::failure(std::string("I/O error! error code: ") + std::to_string(result));
return result;
}
void SMBus::write_byte(int addr, int val)
{
this->set_addr(addr);
__s32 result = i2c_smbus_write_byte(this->fd, (__u8)val);
if (result < 0)
{
throw std::ios_base::failure(std::string("I/O error! error code: ") + std::to_string(result));
}
}
long SMBus::read_byte_data(int addr, int cmd)
{
this->set_addr(addr);
__s32 result = i2c_smbus_read_byte_data(this->fd, (__u8)cmd);
if (result < 0)
{
throw std::ios_base::failure(std::string("I/O error! error code: ") + std::to_string(result));
}
return (long)result;
}
void SMBus::write_byte_data(int addr, int cmd, int val)
{
this->set_addr(addr);
__s32 result = i2c_smbus_write_byte_data(this->fd,
(__u8)cmd,
(__u8)val);
if (result < 0)
{
throw std::ios_base::failure(std::string("I/O error! error code: ") + std::to_string(result));
}
}
long SMBus::read_word_data(int addr, int cmd)
{
this->set_addr(addr);
__s32 result = i2c_smbus_read_word_data(this->fd, (__u8)cmd);
if (result < 0)
{
throw std::ios_base::failure(std::string("I/O error! error code: ") + std::to_string(result));
}
return (long)result;
}
void SMBus::write_word_data(int addr, int cmd, int val)
{
this->set_addr(addr);
__s32 result = i2c_smbus_write_word_data(this->fd,
(__u8)cmd,
(__u16)val);
if (result < 0)
{
throw std::ios_base::failure(std::string("I/O error! error code: ") + std::to_string(result));
}
}
void SMBus::process_call(int addr, int cmd, int val)
{
this->set_addr(addr);
__s32 result = i2c_smbus_process_call(this->fd,
(__u8)cmd,
(__u16)val);
if (result < 0)
{
throw std::ios_base::failure(std::string("I/O error! error code: ") + std::to_string(result));
}
}
long* SMBus::read_block_data(int addr, int cmd)
{
union i2c_smbus_data data;
this->set_addr(addr);
/* save a bit of code by calling the access function directly */
if (i2c_smbus_access(this->fd, I2C_SMBUS_READ, (__u8)cmd,
I2C_SMBUS_BLOCK_DATA,
&data))
{
throw std::ios_base::failure("I/O error!");
}
/* first byte of the block contains (remaining) data length */
return this->buf_to_array(&data.block[1], data.block[0]);
}
void SMBus::write_block_data(int addr, int cmd, long* vals, int len)
{
union i2c_smbus_data data;
this->array_to_data(vals, len, &data);
this->set_addr(addr);
/* save a bit of code by calling the access function directly */
if (i2c_smbus_access(this->fd, I2C_SMBUS_WRITE,
(__u8)cmd,
I2C_SMBUS_BLOCK_DATA,
&data))
{
throw std::ios_base::failure("I/O error!");
}
}
long* SMBus::block_process_call(int addr, int cmd, long* vals, int len)
{
union i2c_smbus_data data;
this->array_to_data(vals, len, &data);
this->set_addr(addr);
/* save a bit of code by calling the access function directly */
if (i2c_smbus_access(this->fd,
I2C_SMBUS_WRITE,
(__u8)cmd,
I2C_SMBUS_BLOCK_PROC_CALL,
&data))
{
throw std::ios_base::failure("I/O error!");
}
/* first byte of the block contains (remaining) data length */
return this->buf_to_array(&data.block[1], data.block[0]);
}
long* SMBus::read_i2c_block_data(int addr, int cmd, int len)
{
union i2c_smbus_data data;
this->set_addr(addr);
data.block[0] = len;
/* save a bit of code by calling the access function directly */
if (i2c_smbus_access(this->fd,
I2C_SMBUS_READ,
(__u8)cmd,
len == 32 ?
I2C_SMBUS_I2C_BLOCK_BROKEN : I2C_SMBUS_I2C_BLOCK_DATA,
&data))
{
throw std::ios_base::failure("I/O error!");
}
/* first byte of the block contains (remaining) data length */
return this->buf_to_array(&data.block[1], data.block[0]);
}
void SMBus::i2c_block_data(int addr, int cmd, long* vals, int len)
{
union i2c_smbus_data data;
this->array_to_data(vals, len, &data);
this->set_addr(addr);
/* save a bit of code by calling the access function directly */
if (i2c_smbus_access(this->fd,
I2C_SMBUS_WRITE,
(__u8)cmd,
I2C_SMBUS_I2C_BLOCK_BROKEN,
&data))
{
throw std::ios_base::failure("I/O error!");
}
}
void SMBus::set_pec(bool pec)
{
if (this->pec != pec)
{
if (ioctl(this->fd, I2C_PEC, pec))
throw std::ios_base::failure("I/O error!");
this->pec = pec;
}
}
long* SMBus::buf_to_array(__u8 const* buf, int len)
{
long* list = new long[len + 1];
int ii;
if (list == NULL)
return NULL;
for (ii = 0; ii < len; ii++)
{
auto val = (long)buf[ii];
list[ii] = val;
}
list[len] = ARRAY_END;
return list;
}
void SMBus::array_to_data(long* list, int list_len, union i2c_smbus_data* data)
{
static auto msg = "Third argument must be a list of at least one, "
"but not more than 32 integers";
auto& len = list_len;
if (len > 32)
{
throw std::logic_error(msg);
}
/* first byte is the length */
data->block[0] = (__u8)len;
for (int ii = 0; ii < len; ii++)
{
auto val = list[ii];
data->block[ii + 1] = (__u8)val;
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/PlumBlossomMaid/smbus-cpp.git
git@gitee.com:PlumBlossomMaid/smbus-cpp.git
PlumBlossomMaid
smbus-cpp
smbus-cpp
master

搜索帮助