Skip to content
Snippets Groups Projects
Commit 0ddb4feb authored by Armin Co's avatar Armin Co
Browse files

I2C implemented

parent 841bd8d2
No related branches found
No related tags found
No related merge requests found
#include "Node.hpp"
#include <asm/ioctl.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <spdlog/spdlog.h>
using namespace i2c;
Node::Node(char dev_id, const char* i2c_device_name) : m_address{dev_id}
Node::Node(uint8_t node_address)
: m_address{node_address}
, m_device{-1}
{
open();
}
}
bool Node::write(std::vector<char> data)
Node::~Node()
{
bool success {true};
close(m_device);
}
bool Node::open_device(const char* i2c_device_name)
{
auto fd = open(i2c_device_name, O_RDWR);
if (fd < 0)
{
// error creating file descriptor
success = false;
spdlog::error("Failed to open device {}", i2c_device_name);
return false;
}
auto success_selecting_device = ioctl(fd, I2C_SLAVE, m_address);
if (success_selecting_device < 0)
{
spdlog::error("Failed to select i2c node {}", m_address);
return false;
}
m_device = fd;
return true;
}
bool Node::send(uint8_t* data, size_t size)
{
auto bytes_written = write(m_device, data, size);
if (bytes_written != size)
{
spdlog::error("Error while writing bytes. Written {} bytes instead of {}!", bytes_written, size);
return false;
}
return true;
}
bool Node::send(std::vector<uint8_t> &data)
{
return send(data.data(), data.size());
}
bool Node::send(std::array<uint8_t, 2> &data)
{
return send(data.data(), data.size());
}
bool Node::send(uint8_t reg, uint8_t val)
{
uint8_t data[2] {reg, val};
return send(data, 2);
}
int Node::read(char reg_addr)
constexpr uint8_t i2c_smbus_max_block_size = 32;
struct i2c_smbus_data
{
uint8_t block [i2c_smbus_max_block_size + 2];
};
struct i2c_smbus_ioctl_data
{
char read_write;
uint8_t command;
int size;
i2c_smbus_data* data;
};
int Node::read16(uint8_t reg_addr)
{
i2c_smbus_data data;
i2c_smbus_ioctl_data args;
args.read_write = 1; // rw
args.command = reg_addr;
args.size = 3; // byte = 2; word = 3 (because of address); only byte: 1 -> command = 0;
args.data = &data;
auto success = ioctl(m_device, I2C_SMBUS, &args);
if (success != 0)
{
// error
spdlog::error("Error while reading data.");
return -1;
}
else
{
int answer {0};
answer |= static_cast<int>(data.block[0] << 8); // MSB
answer |= static_cast<int>(data.block[1] << 0); // LSB
spdlog::debug("Received data: {} {} converted to {}.", data.block[0], data.block[1], answer);
return answer;
}
}
\ No newline at end of file
......@@ -8,6 +8,8 @@
#ifndef I2C_NODE_HEADER
#define I2C_NODE_HEADER
#include <stdint.h>
#include <array>
#include <vector>
namespace i2c
......@@ -20,9 +22,17 @@ class Node
public:
/// @brief Create node device
///
/// @param devId address of the node device
/// @param node_address Address to talk to.
///
Node(char dev_id, const char* i2c_device_name);
Node(uint8_t node_address);
~Node();
/// @brief Open i2c device
///
/// @param device_name Name of the i2c device to use: e.g. "/dev/i2c-1"
/// @return Returns wether opening of the device was successfull.
///
bool open_device(const char* i2c_device_name);
/// @brief Write vector of values to node
......@@ -30,8 +40,10 @@ public:
/// @param data Data that should be written
/// @return If write operation was successfull
//
bool write(std::vector<char> data);
bool send(uint8_t* data, size_t size);
bool send(std::vector<uint8_t> & data);
bool send(std::array<uint8_t, 2> &data);
bool send(uint8_t reg, uint8_t val);
/// @brief Read from node
///
......@@ -39,10 +51,11 @@ public:
/// read from
/// @return Returns the received value from the register
///
int read(char reg_addr);
int read16(uint8_t reg_addr);
private:
char m_address; ///< Adress of the node device
uint8_t m_address; ///< Adress of the node.
int m_device; ///< File descriptor of i2c device.
};
} // i2c namespace
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment