21#include <boost/lexical_cast.hpp>
22#include <boost/range/adaptor/map.hpp>
23#include <boost/range/algorithm/copy.hpp>
27#include <unordered_map>
87 const std::unordered_map<std::string, std::string>&
parameters = this->getParameters();
88 std::unordered_map<std::string, std::string>::const_iterator it;
90 uint32_t slave_addr = (boost::lexical_cast<timing::stoul<uint32_t>>(it->second) & 0x7f);
100 std::unordered_map<std::string, I2CSlave*>::iterator it;
109std::vector<std::string>
112 std::vector<std::string> slaves;
123 std::unordered_map<std::string, uint8_t>::const_iterator it =
126 throw I2CDeviceNotFound(
ERS_HERE, getId(), name);
136 std::unordered_map<std::string, I2CSlave*>::const_iterator it =
m_i2c_devices.find(name);
138 throw I2CDeviceNotFound(
ERS_HERE, getId(), name);
140 return *(it->second);
153 return this->read_i2cArray(i2c_device_address, i2c_reg_address, 1)[0];
160 uint32_t i2c_reg_address,
162 bool send_stop)
const
169 this->
write_i2cArray(i2c_device_address, i2c_reg_address, { data }, send_stop);
176 uint32_t i2c_reg_address,
177 uint32_t number_of_words)
const
180 std::vector<uint8_t> lArray{ (uint8_t)(i2c_reg_address & 0xff) };
181 this->write_block_i2c(i2c_device_address, lArray);
183 return this->read_block_i2c(i2c_device_address, number_of_words);
190 uint32_t i2c_reg_address,
191 std::vector<uint8_t> data,
192 bool send_stop)
const
196 std::vector<uint8_t> block(data.size() + 1);
197 block[0] = (i2c_reg_address & 0xff);
199 for (
size_t i(0); i < data.size(); ++i)
200 block[i + 1] = data[i];
210 return this->read_block_i2c(i2c_device_address, number_of_bytes);
217 const std::vector<uint8_t>& data,
218 bool send_stop)
const
227 const std::vector<uint8_t>& data,
228 bool send_stop)
const
251 for (
unsigned ibyte = 0; ibyte < data.size(); ibyte++) {
254 uint8_t cmd = (((ibyte == data.size() - 1) && send_stop) ?
kStopCmd : 0x0);
285 send_i2c_command_and_write_data(kStartCmd, (i2c_device_address << 1) | 0x01);
287 std::vector<uint8_t> lArray;
288 for (
unsigned ibyte = 0; ibyte < number_of_bytes; ibyte++) {
290 uint8_t cmd = ((ibyte == number_of_bytes - 1) ? (kStopCmd | kAckCmd) : 0x0);
293 lArray.push_back(send_i2c_command_and_read_data(cmd));
307 send_i2c_command_and_write_data(kStartCmd, (i2c_device_address << 1) | 0x01);
308 send_i2c_command_and_read_data(kStopCmd | kAckCmd);
310 }
catch (
const timing::I2CException& excp) {
321 std::vector<uint8_t> address_vector;
326 for (uint8_t iaddr(0); iaddr < 0x7f; ++iaddr) {
331 }
catch (
const timing::I2CException& excp) {
335 address_vector.push_back(iaddr);
339 return address_vector;
358 getClient().dispatch();
360 bool full_reset(
false);
367 getClient().dispatch();
376 getClient().dispatch();
380 getClient().dispatch();
385 getClient().dispatch();
395 assert(!(command & kWriteToSlaveCmd));
397 uint8_t full_cmd = command | kReadFromSlaveCmd;
401 getNode(kCmdNode).write(full_cmd);
402 getClient().dispatch();
405 wait_until_finished(
false, command & kStopCmd);
408 uhal::ValWord<uint32_t> result = getNode(kRxNode).read();
409 getClient().dispatch();
413 return (result & 0xff);
423 assert(!(command & kReadFromSlaveCmd));
425 uint8_t full_cmd = command | kWriteToSlaveCmd;
426 std::stringstream debug_stream;
427 debug_stream <<
">> sending write cmd = " << std::showbase << std::hex << (uint32_t)full_cmd
428 <<
" data = " << std::showbase << std::hex << (uint32_t)data;
432 getNode(kTxNode).write(data);
433 getClient().dispatch();
436 getNode(kCmdNode).write(full_cmd);
439 getClient().dispatch();
443 wait_until_finished(
true, command & kStopCmd);
457 const unsigned max_retry = 20;
458 unsigned attempt = 1;
459 bool received_acknowledge, busy;
461 const uhal::Node& status_node = getNode(
kStatusNode);
463 while (attempt <= max_retry) {
466 uhal::ValWord<uint32_t> i2c_status = status_node.read();
467 getClient().dispatch();
474 if (arbitration_lost) {
476 throw I2CBusArbitrationLost(
ERS_HERE, getId());
479 if (!transfer_in_progress) {
493 if (attempt > max_retry) {
494 throw I2CTransactionTimeout(
ERS_HERE, getId());
497 if (require_acknowledgement && !received_acknowledge) {
498 throw I2CNoAcknowledgeReceived(
ERS_HERE, getId());
501 if (require_bus_idle_at_end && busy) {
502 throw I2CTransferFinishedBusStillBusy(
ERS_HERE, getId());
OpenCode I2C interface to a ipbus node.
virtual std::vector< uint8_t > read_block_i2c(uint8_t i2c_device_address, uint32_t number_of_bytes) const
std::unordered_map< std::string, uint8_t > m_i2c_device_addresses
Slaves.
static const std::string kCtrlNode
static const std::string kStatusNode
void send_i2c_command_and_write_data(uint8_t command, uint8_t data) const
virtual void write_i2c(uint8_t i2c_device_address, uint32_t i2c_reg_address, uint8_t data, bool send_stop=true) const
static const uint8_t kStopCmd
std::vector< uint8_t > scan() const
I2CMasterNode(const uhal::Node &node)
virtual void write_i2cPrimitive(uint8_t i2c_device_address, const std::vector< uint8_t > &data, bool send_stop=true) const
static const std::string kCmdNode
static const std::string kPreHiNode
IPBus register names for i2c bus.
virtual std::vector< uint8_t > read_i2cArray(uint8_t i2c_device_address, uint32_t i2c_reg_address, uint32_t number_of_words) const
uint16_t m_clock_prescale
clock prescale factor
static const uint8_t kStartCmd
static const uint8_t kInProgressBit
static const std::string kPreLoNode
static const uint8_t kAckCmd
static const uint8_t kArbitrationLostBit
virtual uint8_t get_slave_address(const std::string &name) const
uint8_t send_i2c_command_and_read_data(uint8_t command) const
std::unordered_map< std::string, I2CSlave * > m_i2c_devices
I2C slaves attached to this node.
virtual std::vector< uint8_t > read_i2cPrimitive(uint8_t i2c_device_address, uint32_t number_of_bytes) const
static const uint8_t kWriteToSlaveCmd
virtual uint8_t read_i2c(uint8_t i2c_device_address, uint32_t i2c_reg_address) const
commodity functions
virtual std::vector< std::string > get_slaves() const
static const std::string kTxNode
static const uint8_t kBusyBit
virtual void write_i2cArray(uint8_t i2c_device_address, uint32_t i2c_reg_address, std::vector< uint8_t > data, bool send_stop=true) const
static const uint8_t kInterruptBit
static const uint8_t kReceivedAckBit
virtual const I2CSlave & get_slave(const std::string &name) const
virtual void write_block_i2c(uint8_t i2c_device_address, const std::vector< uint8_t > &data, bool send_stop=true) const
void wait_until_finished(bool require_acknowledgement=true, bool require_bus_idle_at_end=false) const
static const uint8_t kReadFromSlaveCmd
bool ping(uint8_t i2c_device_address) const
static const std::string kRxNode
static const uint8_t kInterruptAck
#define TLOG_DEBUG(lvl,...)
std::string format_reg_value(T reg_value, uint32_t base)
Cannot create std::string fatal Incorrect parameters