This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADS1191: error while reading adc value

Part Number: ADS1191

ads1191.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/spi/spi.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>
#include <linux/clk.h>
#include <linux/errno.h>
#include <linux/irq.h>
#include <linux/list.h>
//#include <mach/hardware.h>
#include <asm/delay.h>
#include <asm/pmu.h>
#include <asm/gpio.h>
//#include <mach/gpio.h>
#include <linux/gpio.h>
#include <asm/io.h>
#include "ads1191.h"
#include "Am335x_gpio.h"
#define DEBUG_ENABLE 1
#define CS GPIO_TO_PIN(3, 26) 
#define Set(X,V) gpio_set_value(X,V)

static unsigned char TransBuf[8];
static unsigned char RecvBuf[18];
long AdsResult;
struct ads1191_bus {
	struct spi_message Pmsg;
	struct spi_transfer Pxfer[2];
};
struct spi_device *ads1191spi;
int ads1191init(void);
void ads1191ConvertRaw(void);
unsigned char ads1191ReadReg(unsigned char );
unsigned char ads1191ReadRegID(unsigned char );
void ads1191WriteReg(unsigned char ,unsigned char );
unsigned char Msb2Lsb(unsigned char Data);
static int ads1191_user_read(struct file *file, unsigned int *buf, size_t count, loff_t *ppos)
{
	int p=0;
	Set(CS,0);	// CHIP_SELECT LOW
	while(p <= count)
	{
		ads1191ConvertRaw();
		if(AdsResult>0) 
			buf[p++] = AdsResult;
	}
	Set(CS,1);	// CHIP_SELECT HIGH
	return 0;
}
static long ads1191_user_ioctl(struct file *file, int arg)
{
	int p;
	long adcval=0;
	char chnum;
	chnum = arg;
	Set(CS,0);	// CHIP_SELECT LOW
	chnum=0;
	for(p=0; p<10; p++)
	{
		ads1191ConvertRaw();
		if(AdsResult>0)
			adcval = adcval+AdsResult;
		else chnum++;
	}
	adcval = adcval/(10 - chnum);
	printk("adcval value in ioctl=%d\n",adcval);
	Set(CS,1);	// CHIP_SELECT HIGH
	return adcval;
}
int ads1191init(void)
{
	unsigned char  ID=0,LOFF=0;    
	Set(CS,0);	// CHIP_SELECT LOW
	TransBuf[0] = RESET;
	spi_write_then_read(ads1191spi,TransBuf, 1,NULL,0);
	mdelay(50);
	TransBuf[0] = SDATAC;
	spi_write_then_read(ads1191spi,TransBuf, 1,NULL,0);
	mdelay(5);
	ID=0;	// 0 previous
	ID=ads1191ReadRegID(ADS1191_ID_REG);
#ifdef DEBUG_ENABLE
	printk("\n.......Ads1191 ID in INIT= %d",ID);
#endif
	if(ID != ADS1191_ID)
	{
		printk("\n.......Ads1191 ID = %d",ID);
		mdelay(10);
		ID=0;
		ID=ads1191ReadRegID(ADS1191_ID_REG);
		if(ID != ADS1191_ID)
		{
			printk("\n.......Ads1191 ID = %d",ID);
#ifdef DEBUG_ENABLE
			printk("\nAds1191 ID Not Matched/Device not Detected");
#endif
			//return -1;
		}
	}
	ads1191WriteReg(ADS1191_CONFIG1, 0x02);		//Single-Short with 125 SPS=0x80 old, continous=0x00
	ads1191WriteReg(ADS1191_CONFIG2, 0xB0);		//0x80	//old 0xB0
	ads1191WriteReg(ADS1191_CH1SET, 0x10);		//0x00	//old 0x10
	ads1191WriteReg(ADS1191_CH2SET, 0x80);		//0x00	//old 0x80
	ads1191WriteReg(ADS1191_MISC1, 0x02);		
	ads1191WriteReg(ADS1191_GPIO, 0x0C);
	ads1191WriteReg(ADS1191_LOFF_STAT, 0x00);	//	fclk=512 fmod=fclk/4 
	TransBuf[0] = SDATAC;
	spi_write_then_read(ads1191spi,TransBuf, 1,NULL,0);
	mdelay(5);	
	LOFF=ads1191ReadReg(ADS1191_LOFF);
#ifdef DEBUG_ENABLE
	printk("\nAds1191 LOFF = %d\n",LOFF);
#endif
	printk("\n- Reg Read... ");
	for(ID=0;ID<12;ID++)
	{
		memset(RecvBuf, 0x00, sizeof(RecvBuf));	
		TransBuf[0] = ADS1191_REG_READ | ID;
		TransBuf[1] = 0x00;
		spi_write_then_read(ads1191spi,TransBuf, 2,RecvBuf,1);
		//printk("[%02x %02x %02x %02x]",RecvBuf[0],RecvBuf[1],RecvBuf[2],RecvBuf[3]); 
		printk("[%02x] ",RecvBuf[0]); 
	}
	ads1191ConvertRaw();
	Set(CS,1);	// CHIP_SELECT HIGH
	return 1;
}
void ads1191ConvertRaw(void)
{
	unsigned char p,val=0x00;
	AdsResult = 0x00;
	TransBuf[0] = START;
	spi_write_then_read(ads1191spi,TransBuf, 1,NULL,0);
	mdelay(4); /*5*/
	for(p=0;p<2;p++) /*10*/
	{
		memset(RecvBuf, 0x00, sizeof(RecvBuf));	
		TransBuf[0] = ADS1191_REG_READ | ADS1191_GPIO;
		TransBuf[1] = 0x00;
		spi_write_then_read(ads1191spi,TransBuf, 2,RecvBuf,1);
		//printk("\n-GPIO Read... %02x \n",RecvBuf[0]);
		val=RecvBuf[0];
		if(!(val&0x02))
		{
			//printk("\n DREADY LOW...\n");
			memset(RecvBuf, 0x00, sizeof(RecvBuf));
			TransBuf[0] = RDATA;
			spi_write_then_read(ads1191spi,TransBuf, 1,RecvBuf,6);
			//printk("ADC Value [0x%02x 0x%02x]",RecvBuf[2],RecvBuf[3]); 
			break;
		}
	}
	AdsResult = RecvBuf[2];
	AdsResult <<= 8;//bits a2d11 to a2d4
	AdsResult |= RecvBuf[3]; //bits a2d3 to a2d0 + 4 dummy bits
#ifdef DEBUG_ENABLE
	//	printk("\nAdsResult = 0x%x %ld\n",AdsResult,AdsResult);
	//printk("\nAdsResult = 0x%x %f\n",AdsResult,(AdsResult*12.099)/(2*32768));
#endif
}
unsigned char Msb2Lsb(unsigned char Data)
{
	unsigned char k,tmp1,tmp=0x00;
	tmp1 = Data;
	for(k=0;k<8;k++)
	{
		tmp = tmp << 1;
		tmp |= tmp1&0x01;
		tmp1 = tmp1 >> 1;
	}
	return tmp;
}
unsigned char ads1191ReadRegID(unsigned char reg)
{
	unsigned char data = 0x00;

	TransBuf[0] = ADS1191_REG_READ | reg;
	TransBuf[1] = 0x01;    //0x00 old
	//printk("\n Reg to be Read... %02x ",TransBuf[0]);
	spi_write_then_read(ads1191spi,TransBuf, 2,RecvBuf,1);
	data = RecvBuf[0];
	//data = 0X50;
	printk("\n Value Read... %02x %02x %02x %02x",RecvBuf[0],RecvBuf[1],RecvBuf[2],RecvBuf[3]);
	printk("\n Msb2Lsb ...   %02x %02x %02x %02x",Msb2Lsb(RecvBuf[0]),Msb2Lsb(RecvBuf[1]),Msb2Lsb(RecvBuf[2]),Msb2Lsb(RecvBuf[3]));
	return data;
}
unsigned char ads1191ReadReg(unsigned char reg)
{
	unsigned char data = 0xff;

	TransBuf[0] = ADS1191_REG_READ | reg;
	TransBuf[1] = 0x00;
	//printk("\n Reg to be Read... %02x ",TransBuf[0]);
	spi_write_then_read(ads1191spi,TransBuf, 1,RecvBuf,1);
	data = RecvBuf[0];
	//printk("\n Value Read... %02x ",RecvBuf[0]);
	return data;
}
void ads1191WriteReg(unsigned char reg,unsigned char value)
{
	TransBuf[0] = ADS1191_REG_WRITE | reg;
	TransBuf[1] = 0x00;
	TransBuf[2] = value;
	spi_write_then_read(ads1191spi,TransBuf, 3,NULL,0);
}

static int ads1191_probe(struct spi_device *spi)
{
	int err;
	spi->bits_per_word = 8;
	spi->mode = SPI_MODE_1;//RAISE/FALL is COnnected to GND so MODE_2
	err = spi_setup(spi);
	if (err < 0)
		return err;
	Gpio_set_value(CS,"adc_cs",1,1);
	ads1191spi = spi;
	if(ads1191init() < 0)
	{
#ifdef DEBUG_ENABLE
		printk("\n>>>>>> Failed to detect ads1191");
#endif
		return -1; 
	}
#ifdef DEBUG_ENABLE
	printk("\n>>>>>>ads1191 detect success<<<<<<<");
#endif
	return 0;
}
static const struct of_device_id ads_match_table[] = {
	{.compatible = "ads1191_ADC",},
	{ },
};
static struct spi_driver ads1191Driver = {
	.driver = {
		.name = "ads1191",
		.bus = &spi_bus_type,
		.owner = THIS_MODULE,
		.of_match_table = of_match_ptr(ads_match_table),
	},
	.probe = ads1191_probe,
};

static  struct file_operations ads1191_user_file_ops = {
	.owner 	 = THIS_MODULE,
	.read    = ads1191_user_read,
	.unlocked_ioctl   = ads1191_user_ioctl,
};

static struct miscdevice ads1191_device = {
	55,
	"ads1191dev",
	&ads1191_user_file_ops,	
};

static int ads1191_init(void)
{
	int ret;
	ret = spi_register_driver(&ads1191Driver);
	if(ret < 0)
	{
		mdelay(10);
		ret = spi_register_driver(&ads1191Driver);	
	}
	ret = misc_register(&ads1191_device);
	return ret;
}
module_init(ads1191_init);
static void ads1191_exit(void)
{
	spi_unregister_driver(&ads1191Driver);
	misc_deregister(&ads1191_device);
}
module_exit(ads1191_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("RAVINDRANATH");
MODULE_DESCRIPTION("ADS 1191 INTERFACE");

In our custom board(IMX6ULL) we used ads1191-16bit ADC SPI interface , The Driver for the same is being probed but when we read  ADC value the output is zero even though giving (2V to 3.3V for AIN(4th pin)) when reading from the userspace using IOCTL call .

Kernel Version:4.1.1

dts declaration is,

&ecspi1 {
        status = "okay";
        pinctrl-names = "default";
        fsl,spi-num-chipselects = <1>;
        pinctrl-0 = <&ecspi1_pins>;
        ads1191dev@0 {
                status = "okay";
                pinctrl-names = "default";
                pinctrl-0 = <&printer2t_pins_default>;
                compatible = "ads1191_ADC";
                reg = <0>;
                spi-max-frequency = <512000>;   /* 16M  */
        };
};

ecspi1_pins:ecspi1_pins_default {
                        fsl,pins = <
                                MX6UL_PAD_CSI_DATA07__ECSPI1_MISO       0x70a1
                                MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI       0x79
                                MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK       0x70a1
                        >;
                };

printer2t_pins_default: printer2t_pins {
                        fsl,pins = <
                                MX6UL_PAD_CSI_DATA05__GPIO4_IO26        0x79

                        >;

               };

Getting below dmesg while inserting the driver.....

Value Read... ff 00 00 00
Msb2Lsb ...   ff 00 00 00
 .......Ads1191 ID in INIT= 255
 .......Ads1191 ID = 255
Value Read... ff 00 00 00
Msb2Lsb ...   ff 00 00 00
.......Ads1191 ID = 255
Ads1191 ID Not Matched/Device not Detected
Ads1191 LOFF = 255
- Reg Read...

>>>>>>ads1191 detect success<<<<<<<

Getting below dmesg when calling ioctl function....

Division by zero in kernel.
CPU: 0 PID: 815 Comm: test33V2 Not tainted 4.1.15-2.0.1+gb63f3f5 #75
Hardware name: Freescale i.MX6 Ultralite (Device Tree)
 [<80015d78>] (unwind_backtrace) from [<8001271c>] (show_stack+0x10/0x14)
 [<8001271c>] (show_stack) from [<8082d360>] (dump_stack+0x84/0xc4)
 [<8082d360>] (dump_stack) from [<802b1418>] (Ldiv0+0x8/0x10)
 [<802b1418>] (Ldiv0) from [<8063c12c>] (ads1191_user_ioctl+0x54/0x80)
 [<8063c12c>] (ads1191_user_ioctl) from [<800fb204>] (do_vfs_ioctl+0x3e8/0x608)
 [<800fb204>] (do_vfs_ioctl) from [<800fb458>] (SyS_ioctl+0x34/0x5c)
 [<800fb458>] (SyS_ioctl) from [<8000f480>] (ret_fast_syscall+0x0/0x3c)
 adcval value in ioctl=0

I am attaching driver ads1191.c , please go through them and the error log ,suggest me if any software and Hardware changes are required.