Skip to content
Snippets Groups Projects
Forked from Berkeley Lab / labRemote
332 commits behind the upstream repository.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
MCP3428.cpp 2.91 KiB
#include "MCP3428.h"

#include "LinearCalibration.h"
#include "OutOfRangeException.h"

#include <cmath>

MCP3428::MCP3428(Resolution bit_res, ConversionMode conv_mode, Gain gain, std::shared_ptr<I2CCom> com)
  : ADCDevice(std::make_shared<LinearCalibration>(2.048/pow(2,static_cast<int>(gain)),
						  (uint16_t)pow(2,bit_res - 1))),
    m_resolution(bit_res), m_conv_mode(conv_mode), m_gain(gain), m_com(com)
{ }

MCP3428::MCP3428(std::shared_ptr<I2CCom> com)
  : ADCDevice(std::make_shared<LinearCalibration>(2.048/pow(2,static_cast<int>(Gain::x1)),
						  (uint16_t)pow(2,Resolution::bit16 - 1))),
    m_resolution(Resolution::bit16), m_conv_mode(ConversionMode::Shot), m_gain(Gain::x1), m_com(com)
{ }

MCP3428::~MCP3428()
{ }

void MCP3428::setGain(Gain gain)
{ m_gain=gain; }

//Default read on device on ch0
int32_t  MCP3428::readCount()
{
  //Resolution bit
  uint8_t bit;
  switch(m_resolution)
    {
    case bit12:
      bit = 0;
      break;
    case bit14:
      bit = 1;
      break;
    case bit16:
      bit = 2;
      break;
    default:
      bit = 0;
      break;
    }

  //Configuration register
  uint8_t vConfig = 0x80|(m_conv_mode << 4)|(bit << 2)|m_gain;

  //Write on configuration register
  m_com->write_reg8(vConfig);

  //Read the regsiter
  std::vector<uint8_t>data(3);

  //Wait until the read value is not ready
  bool ready = false;
  while(!ready)
    {
      m_com->read_block(0x7F&vConfig,data);

      //Test if the conversion result is ready
      if ((data[2]&0x80) == 0x00)
	ready = true;
    }

  int16_t chcount = (data[0]<<8)|(data[1]<<0);
  return chcount;
}
int32_t MCP3428::readCount(uint8_t ch)
{ 
  //Check if Channel exist
  if (ch >= m_numChannels)
    throw OutOfRangeException(ch,0,m_numChannels-1);

  //Resolution bit
  uint8_t bit;
  switch(m_resolution)
    {
    case bit12:
      bit = 0;
      break;
    case bit14:
      bit = 1;
      break;
    case bit16:
      bit = 2;
      break;
    default:
      bit = 0;
      break;
    }

  //Configuration register
  uint8_t vConfig = 0;
  vConfig = 0x80|(ch<<5)|(m_conv_mode << 4)|(bit << 2)|m_gain;

  //Write on configuration register
  m_com->write_reg8(vConfig);
      
  //Read the regsiter
  std::vector<uint8_t>data(3);

  //Wait until the read value is not ready
  bool ready = false;
  while(!ready)
    {
      m_com->read_block(0x7F&vConfig,data);

      //Test if the conversion result is ready
      if ((data[2]&0x80) == 0x00)
	ready = true;
    }
    
  int16_t chcount = (data[0]<<8)|(data[1]<<0);
  return chcount;
}

void MCP3428::readCount(const std::vector<uint8_t>& chs, std::vector<int32_t>& counts)
{
  //Clear counts table
  counts.clear();

  //Data table
  std::vector<uint8_t>data(2);

  //Do the Voltage measurement sequence
  for(uint8_t i=0; i<chs.size(); i++)
    {
      //Check if Channel exist
      if (chs[i] >= m_numChannels)
	throw OutOfRangeException(chs[i],0,m_numChannels-1);

      counts[i]=readCount(chs[i]);
    }   
}