AD7172 library

ad7172.cpp

Committer:
mmdonatti
Date:
2020-05-08
Revision:
5:eeec01a423be
Parent:
4:c4a844a34c19
Child:
6:694cb68ae500

File content as of revision 5:eeec01a423be:

//////////////////////////////////////////////////////////////////////////////////
//   @file    AD717X.c
//   @brief   AD717X implementation file.
//   @devices AD7172-2, AD7172-4, AD7173-8, AD7175-2, AD7175-8, AD7176-2,
//            AD7177-2
//   @author  
//
// 		Mauricio Donatti - mauricio.donatti@lnls.br
//		Lucas Tanio - lucas.tanio@lnls.br
//
// 		LNLS - Brazilian Synchrotron Light Source
// 		GIE - Electronics Instrumentation Group
//
// 		2020, April
//
//	Future Implementation:
//			-CRC and Checksum Support
//
//////////////////////////////////////////////////////////////////////////////////

/*********************************************************************************
* Based on Analog Devices AD717X library, focused on performance improvements
*
* Special thanks to original authors:
*		acozma (andrei.cozma@analog.com)
*		dnechita (dan.nechita@analog.com)
* 
* Copyright 2015(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*  - Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*  - Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*  - Neither the name of Analog Devices, Inc. nor the names of its
*    contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*  - The use of this software may or may not infringe the patent rights
*    of one or more patent holders.  This license does not release you
*    from the requirement that you obtain separate licenses from these
*    patent holders to use this software.
*  - Use of the software either in source or binary form, must be run
*    on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#define DEBUG
#include "ad7172.h"

/******************************************************************************
* @AD7172 class constructor.
*
* @param spi - The handler of the instance of the driver.
* @param slave_select - The Slave Chip Select Id to be passed to the SPI calls.
*
*******************************************************************************/
AD7172::AD7172(SPI& p_spi,PinName slave_select,DigitalIn& p_rdy) 
	: _spi(p_spi), _rdy(p_rdy)
{
	
	_spi.format(8,3); // 8 bits ; POL=1 ; PHASE=1
	_spi.frequency(10000000); // 10 MHz SPI clock rate
	continuous_on = 0;
	cs = new DigitalOut(slave_select); // Define cs as digital out variable referred to slave_select pin

	Reset(); // Calling the AD7172-2 restart function
}

/******************************************************************************
* @AD7172 Enable Device - CS goes low.
*
*******************************************************************************/
void AD7172::enable(){
	*cs=0;	
}

/******************************************************************************
* @AD7172 Disable Device - CS goes high.
*
*******************************************************************************/
void AD7172::disable(){
	*cs=1;
}


/******************************************************************************
* @AD7172 Configure Continuous Convertion Mode
*
*******************************************************************************/
void AD7172::start_continuous()
{
    if(continuous_on == 0)
    {
	    data.data = (AD7172_IFMODE_REG_CONT_READ)|AD7172_IFMODE_REG_DATA_STAT;
	    AD7172_PRINTF("CONTCONV");
	    AD7172_PRINTF("Register: IFMODE\tWrite: 0x%04X",data.data);
	    WriteRegister(AD7172_IFMODE_REG,2); // Writing to IFMODE register
	    enable(); // *cs = 0
	    continuous_on = 1;
    }
}

/******************************************************************************
* @AD7172 Configure Continuous Convertion Mode
*
*******************************************************************************/
void AD7172::stop_continuous()
{
	if(continuous_on == 1)
	{
		*cs=0;
		while(_rdy == 1){}
		_spi.write(0x44);
		*cs=1;
		continuous_on =0;
	}
}

/******************************************************************************
* @AD7172 Read Device ID - Communication Test.
*
*******************************************************************************/
void AD7172::ReadID()
{
	*cs=0;
	_spi.write(0x40|AD7172_ID_REG);
	id.bytes[1] = _spi.write(0x00);
	id.bytes[0] = _spi.write(0x00);
	*cs=1;
}

/******************************************************************************
* @AD7172 Read Device Status.
*
*******************************************************************************/
void AD7172::ReadStatus()
{
	*cs=0;
	_spi.write(0x40|AD7172_STATUS_REG);
	status = _spi.write(0x00);
	sw_ready = (status>>7)^1;
	*cs=1;
}

/***************************************************************************//**
* @brief Reads the value of the specified register.
*
* @reg - The address of the register to be read. The value will be stored
*         inside the register structure that holds info about this register.
*
* @bytes - The number of bytes to be readed
*******************************************************************************/
void AD7172::ReadRegister(uint8_t reg, uint8_t bytes)
{
	data.data = 0;
	*cs = 0;
	_spi.write(0x40|reg);
	for(i=bytes-1;i>=0;i--)
	{
		data.bytes[i] = _spi.write(0x00);
	    //AD7172_PRINTF("Data: 0x%02X",data.bytes[i]);
	}
	
	//AD7172_PRINTF("data.data 0x%02X", data.data);
	*cs = 1;
}

/**************************************************************************//**
* @brief Reads the value of the specified register.
*
* @reg - The address of the register to be read. The value will be stored
*         inside the register structure that holds info about this register.
*
* @bytes - The number of bytes to be stored (data saved on data variable)
*******************************************************************************/
void AD7172::WriteRegister(uint8_t reg, uint8_t bytes)
{
	*cs = 0;
	_spi.write(reg);
	for(i=bytes-1;i>=0;i--)
		_spi.write(data.bytes[i]);
	*cs = 1;
}

/***************************************************************************//**
* @brief Resets the device.
*
*******************************************************************************/
void AD7172::Reset()
{
	*cs=0;
	for(i=0;i<=7;i++)
		_spi.write(0xFF);
	*cs=1;

}

/***************************************************************************//**
* @brief Waits until a new conversion result is available.
*
* @param device - The handler of the instance of the driver.
*
*******************************************************************************/
void AD7172::WaitForReady(uint32_t timeout)
{
	while(sw_ready==0 && --timeout)
	{
		//Read the value of the Status Register, updating ready variable
		ReadStatus();
	}
}

/***************************************************************************//****************************************************************************
* @brief Reads the conversion result from the device using data register.
*
*******************************************************************************/
void AD7172::ReadDataRegister()
{
	_spi.write(0x40|AD7172_DATA_REG);
	data.data=0;
	for(i=3;i>0;i--)
		data.bytes[i] = _spi.write(0x00);
}

/***************************************************************************//**
* @brief Reads the conversion result from the device using data register.
*
*******************************************************************************/
void AD7172::ReadDataRegisterStatus()
{
	_spi.write(0x40|AD7172_DATA_REG);
	data.data=0;
	for(i=3;i>0;i--)
		data.bytes[i] = _spi.write(0x00);
	status = _spi.write(0x00);
	channel = status&0b11;
}

/***************************************************************************//********************************************************************************
* @brief Reads the conversion result from the device for continuous read mode
*
*******************************************************************************/
void AD7172::ReadDataContinuous()
{
	data.data=0;
	for(i=3;i>0;i--)
		data.bytes[i] = _spi.write(0x00);
}

/***************************************************************************//**
* @brief Reads the conversion result from the device for continuous read mode if DATA_STAT bit set in IFMODE register
*
*******************************************************************************/
void AD7172::ReadDataContinuousStatus()
{
	data.data=0;
	for(i=3;i>0;i--)
		data.bytes[i] = _spi.write(0x00);
	status = _spi.write(0x00);
	channel = status&0b11;
}