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.

ADS1148: Interfacing with Controller TMS320F28377D

Part Number: ADS1148
Other Parts Discussed in Thread: TMS320F28377D, , MSP-EXP430F5529LP, ADS1605, REF5020

Hello All,


I want interface ADS1148 with controller TMS320F28377D with the SPI communication. It will be really helpful if I can get the code for that. And is it okay to leave pins IEXC0 and IEXC1 open? And I also wanted to know if I am dealing with 0V-3.3V as operating supply voltage ranges what should I connect to pins REFP0 and REFN0 for AIN0 and AIN1?

Is there any other ADC available which is compatible with same controller and have sampling in MSPS?

  • Ami,


    I don't know of any code specifically for the TMS320F28377D. However, the following link should have some firmware example code for the ADS1x4x devices.

    www.ti.com/.../sbac144

    The code itself was developed using the Launchpad MSP-EXP430F5529LP, but it is likely a good starting point for you.

    As for the other questions, it is ok to leave IEXC0 and IEXC1 open. If you are not using REFP0 and REFN0 as external references, and are using the internal reference or REFP1 and REFN1 for an external reference, you should be able to leave REFP0 and REFN0 open as well.

    I don't think there are converters similar to the ADS1148 that have speeds that are in the MSPS range. From the delta-sigma type of devices that I support, the ADS1605 is one of the few that has that kind of speed (5MSPS), but is a single channel and doesn't have a mux or other features seen on the ADS1148. There may be other SAR type devices that might be helpful to you. If you have a particular application in mind, just describe it and we may be able to match something to your needs.


    Joseph Wu

  • Thank you Joseph,

    So I am connecting AVdd to 3.3V and AVss to ground with 0.1uf capacitor and same with DVdd and DGnd pins and connecting 1uf capacitor between VREFOUT and VREFCOM. And I also wanted to know that what should I do to provide internal reference on REFP0 and REFN0 pins? And it would not damage the TMS320F28377D controller due to any current rating of ADS1148  on pins of controller? And what is role of PGA setting?

    Regards,

    Ami

  • Ami,


    For any ADC, the analog input is compared against a reference voltage, and the output data is a number that represents a that ratio. For the ADS1148 you can select the internal reference voltage of 2.048V or you can select an external reference voltage.

    If you decide to use the internal reference voltage, then you need to enable the reference which is set by the VREFCON bits, and select the internal reference voltage for measurement which is set by the REFSELT bits. These bits can be found in the MUX1 register.

    If you decide to use an external reference voltage (either using something like the REF5020, or other external voltage), then you can need to use the REFP0/REFN0 pins, or the REFP1/REFN1 pins. You don't need to turn on the internal reference unless you need it for some other function (like IDAC current sources or system monitor functions). As before, selecting the reference is set by the REFSELT bits.

    The ADS1148 has a PGA (programmable gain amplifier). This PGA is able to amplify the analog input (in gains of 1 to 128, in factors of 2). This allows the device to measure very small signals, with high resolution. The PGA is constructed similar to an instrumentation amplifier. Note that the PGA has certain input and output limitations, which are outlined in the datasheet.

    I don't think there should be any concerns connecting the TMS320F28377D with the ADS1148 as long as the connections are correct. Normally you wouldn't have high currents passing between the devices.

    Out of curiosity, what are you trying to measure? If you have a particular application in mind, perhaps there are designs available that you can review.


    Joseph Wu
  • Thank you Joseph Wu,

    I have prepared the code according to the pseudo code as written in datasheet. The connections are made according to the serial communication of SPI. I want to check the 3.3V from potentiometer from the AIN0 and AIN1 pins, we are communicating with TMS320F28377D in CCS. We are not getting DRDY pin low for data transmission even by setting the baud rate low. The code is not getting inside transmit ISR loop. What should be the problem?

    Regards,
    Ami
  • Ami,


    The first two pins I would check are the /RESET and START pins. Both should be high for the device to be in operation. If either are low, the device is either in a reset state, where the device is not operating, or the device is basically in a sleep mode.

    If you are checking the data ready with the DOUT/DRDY pin, then make sure that /CS is low while you are checking. If the /CS is not low, the DOUT/DRDY pin is in a high-impedance state.

    Are you able to read the registers from the device? This would be a good test to see that the communications are correct.

    If you aren't able to read the registers, I would get a scope shot of the SPI communications showing the detail of DIN, DOUT, /CS, and SCLK.


    Joseph Wu

  • Thank you Joseph,

                 I have checked the connections, they are all good. Yes I can read  the registers. The only problem for communication is when the DRDY pin will be low I will be getting the data, but it is not getting low at any instance. I have inserted the code below please have a look where I am going wrong and let me know of corrections.

    ads1148.c
    //
    #include "F28x_Project.h"
    
    //
    // Globals
    //
    //Uint16 sdata[2];     // Send data buffer
    //Uint16 rdata[2];     // Receive data buffer
    //Uint16 rdata_point;  // Keep track of where we are
    // in the data stream to check received data
    
    //
    // Function Prototypes
    //
    interrupt void SPIA_TX_ISR(void);
    interrupt void SPIA_RX_ISR(void);
    void delay_loop(void);
    void spi_init(void);
    void error();
    void SPITX_INTERRUPT_Service();
    void adc_enable();
    void Sdata_command();
    void Wreg_command1();
    void Wreg_command2();
    void Wreg_command3();
    void Wreg_command4();
    void Wreg_command5();
    void Rreg_command1();
    void Rreg_command2();
    void Sync();
    void main_loop();
    void disable_fun();
    
    
    //
    // Main
    //
    int i, index, adc_flag,SPI_TX_RX,data;
    
    
    void main(void)
    {
    
    //
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file.
    //
    	InitSysCtrl();
    
    //
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // Setup only the GP I/O only for SPI-A functionality
    //
    	InitGpio();
    	GPIO_SetupPinMux(40, GPIO_MUX_CPU1, 0);                      //drdy
    	GPIO_SetupPinOptions(40, GPIO_INPUT, GPIO_PUSHPULL);
    	GPIO_SetupPinMux(42, GPIO_MUX_CPU1, 0);                      //reset
    	GPIO_SetupPinOptions(42, GPIO_OUTPUT, GPIO_PUSHPULL);
    	GPIO_SetupPinMux(48, GPIO_MUX_CPU1, 0);                      //start
    	GPIO_SetupPinOptions(48, GPIO_OUTPUT, GPIO_PUSHPULL);
    	InitSpiaGpio();
    	GpioCtrlRegs.GPBMUX1.bit.GPIO40 = 0;
    	GpioCtrlRegs.GPBGMUX1.bit.GPIO40 = 0;
    	GpioCtrlRegs.GPBDIR.bit.GPIO40 = 0;
    
    	GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 0;
    	GpioCtrlRegs.GPAGMUX2.bit.GPIO19 = 0;
    	GpioCtrlRegs.GPADIR.bit.GPIO19 = 1;
    	GpioDataRegs.GPACLEAR.bit.GPIO19 = 1;
    
    // Step 3. Initialize PIE vector table:
    // Disable and clear all CPU interrupts
    //
    	DINT;
    	IER = 0x0000;
    	IFR = 0x0000;
    
    //
    // Initialize PIE control registers to their default state:
    // This function is found in the F2837xD_PieCtrl.c file.
    //
    	InitPieCtrl();
    
    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_PieVect.c.
    //
    	InitPieVectTable();
    
    //
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    //
    	EALLOW;
    	// This is needed to write to EALLOW protected registers
    	PieVectTable.SPIA_RX_INT = &SPIA_RX_ISR;
    	PieVectTable.SPIA_TX_INT = &SPIA_TX_ISR;
    	EDIS;
    	// This is needed to disable write to EALLOW protected registers
    
    //
    // Step 4. Initialize the Device Peripherals:
    //
    	spi_init();   // Initialize the SPI only
    	for (i = 0; i < 32000; i++)
    	{
    
    	}
    
    	GPIO_WritePin(42, 1);
    	GPIO_WritePin(48, 1);
    
    	/*for (i = 0; i < 32000; i++)
    	{
    
    	}*/
    //		adc_flag=1;
    //		index=1;
    //		adc_enable();
    
    
    	// Enable Global Interrupts
    
    	//SPITX_INTERRUPT_Service();
    //
    // Step 5. User specific code, enable interrupts:
    //
    
    //
    // Initialize the send data buffer
    //
    	/* for(i=0; i<2; i++)
    	 {
    	 sdata[i] = i;
    	 }
    	 rdata_point = 0;
    	 */
    
    //
    // Enable interrupts required for this example
    //
    	PieCtrlRegs.PIECTRL.bit.ENPIE = 1;     // Enable the PIE block
    	PieCtrlRegs.PIEIER6.bit.INTx1 = 1;     // Enable PIE Group 6, INT 1
    	PieCtrlRegs.PIEIER6.bit.INTx2 = 1;     // Enable PIE Group 6, INT 2
    
    	IFR = 0x00;
    	IER = 0x20;    // Enable CPU INT6
    	EINT;
    	PieCtrlRegs.PIEACK.all = 0xFFFF;				//Clear all ACK bits before starting back ground loop.
    
    	for (i = 0; i < 32000; i++);
    
    	adc_flag=1;
    	index=1;
    	adc_enable();
    
    //
    // Step 6. IDLE loop. Just sit and loop forever (optional):
    //
    	for (;;);
    
    }
    
    //
    // delay_loop - Function to provide delay
    //
    /*void delay_loop()
     {
     long i;
     for (i = 0; i < 1000000; i++) {}
     }*/
    
    //
    // error - Function to halt debugger on error
    //
    void error(void)
    {
    	asm("     ESTOP0");
    	//Test failed!! Stop!
    	for (;;);
    }
    
    //
    // spi_fifo_init - Initialize SPI FIFO
    //
    void spi_init()
    {
    	 EALLOW;
    
    		   SpiaRegs.SPICCR.bit.SPISWRESET = 0;     	// 7    SPI SW Reset
    		   SpiaRegs.SPICCR.bit.SPICHAR = 0x7;	 	//      Character length of 8-bits.To facilate insturction code and data bytes of EEPROM.
    		   SpiaRegs.SPICCR.bit.SPILBK     = 0;     	// 4    Loop-back is disable.
    		   SpiaRegs.SPICCR.bit.CLKPOLARITY= 0;     	// 6    Data is shifted out on falling edge of clock.And recieved on
    		   						        		    //       rising edge of clk to make compatibility with EEPROM.
    		   SpiaRegs.SPIBRR.all = 0x0063;            //       Baud rate
    		   SpiaRegs.SPICTL.bit.SPIINTENA    = 1;   // 0      Interrupts(SPIRXINT & SPITXINT)are enable.
    		   SpiaRegs.SPICTL.bit.TALK         = 1;   // 1      Slave transmit is enable for EEPROM but must be
    		   										   //        stop in case of DAC writting or donot read Rx for DAC.
    		   SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;   // 2      SPI work as master.
    		   SpiaRegs.SPICTL.bit.CLK_PHASE    = 1;   // 3      Output Data on clock.
    		   SpiaRegs.SPICTL.bit.OVERRUNINTENA= 0;   // 4      Overrun interrupt is Disable as there is complete control on EEPROM. and no data from DAC.
    
    		   SpiaRegs.SPIRXEMU	= 0x0000;		   // Dummy of SPIRXBUF clear to zero.
    		   SpiaRegs.SPITXBUF	= 0x0000;		   // SPITXBUF clear to zero.
    		   SpiaRegs.SPIRXBUF	= 0x0000;		   // SPIRXBUF clear to zero.
    		   SpiaRegs.SPIDAT		= 0x0000;		   // clear initially to zero.
               SpiaRegs.SPIFFTX.bit.SPIFFENA   = 0;	//FIFo Feature is Disabled.
    		   SpiaRegs.SPIPRI.bit.FREE    = 1;        // 4      Free emulation mode control is selected.
    		   SpiaRegs.SPIPRI.bit.SOFT    = 1;        // 5      Soft emulation mode control is selected.
    		   SpiaRegs.SPICCR.bit.SPISWRESET = 1;     // 7      SPI SW Out of reset.
    
    		EDIS;
    
    
    }
    
    //
    // spiTxFifoIsr - ISR for SPI transmit FIFO
    //
    interrupt void SPIA_TX_ISR(void)
    {
    
    	//SPITX_INTERRUPT_Service();
    	PieCtrlRegs.PIEACK.bit.ACK6 = 1;
    }
    
    void SPITX_INTERRUPT_Service()
    {
    
    	if (index == 1 && adc_flag == 1)
    	{
    		adc_enable();
    	}
    
    	else if (index == 2)
    	{
    		Sdata_command();
    	}
    
    	else if (index == 3)
    	{
    		Wreg_command1();
    	}
    
    	else if (index == 4)
    	{
    		Wreg_command2();
    	}
    
    	else if (index == 5)
    	{
    		Wreg_command3();
    	}
    
    	else if (index == 6)
    		{
    			Wreg_command4();
    		}
    
    
    	else if (index == 7)
    		{
    			Wreg_command5();
    		}
    
    	else if (index == 8)
    		{
    			Rreg_command1();
    		}
    
    	else if (index == 9)
    		{
    			Rreg_command2();
    		}
    
    	else if (index == 10)
    		{
    			Sync();
    		}
    
    	else if (index == 11)
    		{
    			main_loop();
    		}
    
    	else if (index == 12)
    		{
    			disable_fun();
    		}
    
    	else
    		{
    			index = 1;
    		}
    
    }
    
    void adc_enable()
    {
    
    	//adc_flag = 0;
    	GPIO_WritePin(19, 0);     //cs
    	asm(" NOP");
    	asm(" NOP");
    	SpiaRegs.SPIDAT = 0x06;
    	SPI_TX_RX = 1;
    	index = 2;
    
    }
    
    void Sdata_command()
    {
    	for (i = 0; i < 12000; i++);
    	SpiaRegs.SPIDAT = 0x0016;
    	index = 3;
    }
    
    void Wreg_command1()
    {
    	SpiaRegs.SPIDAT = 0x0040;
    	index = 4;
    }
    
    void Wreg_command2()
    {
    	SpiaRegs.SPIDAT = 0x0003;
    	index = 5;
    }
    
    void Wreg_command3()
    {
    	SpiaRegs.SPIDAT = 0x0001;
    	index = 6;
    }
    
    void Wreg_command4()
    {
    	SpiaRegs.SPIDAT = 0x0003;
    	index = 7;
    }
    
    void Wreg_command5()
    {
    	SpiaRegs.SPIDAT = 0x005F;
    	index = 8;
    }
    
    void Rreg_command1()
    {
    	SpiaRegs.SPIDAT = 0x0020;
    	index = 9;
    }
    
    void Rreg_command2()
    {
    	SpiaRegs.SPIDAT = 0x0003;
    	index = 10;
    }
    
    void Sync()
    {
    	SpiaRegs.SPIDAT = 0x0004;
    
    	for (i = 0; i < 34; i++);
    	//GPIO_WritePin(19, 1);
    	index = 11;
    
    }
    
    void main_loop()
    {
    
    	while(GpioDataRegs.GPBDAT.bit.GPIO40==0)
    	{
    
        }
    
    	//GPIO_WritePin(19, 0);
    
    /*	while(GpioDataRegs.GPADAT.bit.GPIO19==0)
    	{
    		done1=1;
    	}
    */
    
    	asm(" NOP");
    	asm(" NOP");
    	SpiaRegs.SPIDAT = 0x0012;
    	asm(" NOP");
    	data = SpiaRegs.SPITXBUF;
    	for (i = 0; i < 34; i++);
    
    	index = 12;
    }
    
    void disable_fun(void)
    {
    	GPIO_WritePin(19, 0);
    	asm(" NOP");
    	asm(" NOP");
    	SpiaRegs.SPIDAT = 0x0002;
    	adc_flag = 0;
    }
    
    /*{
     Uint16 i;
     for(i=0;i<2;i++)
     {
     SpiaRegs.SPITXBUF=i;      // Send data
     }
    
     for(i=0;i<2;i++)                    // Increment data for next cycle
     {
     sdata = ;
     }
    
     SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1;  // Clear Interrupt flag
     PieCtrlRegs.PIEACK.all|=0x20;       // Issue PIE ACK
     }*/
    
    
    //
    // spiRxFifoIsr - ISR for SPI receive FIFO
    //
    interrupt void SPIA_RX_ISR(void)
    {
    
    
    
    	 /*for(i=0; i<2; i++)
    	 {
    	 rdata[i]=SpiaRegs.SPIRXBUF;     // Read data
    	 }
    
    	 for(i=0; i<2; i++)                  // Check received data
    	 {
    	 if(rdata[i] != rdata_point+i)
    	 {
    	 error();
    	 }
    	 }*/
    
    	 i = SpiaRegs.SPIRXBUF;     // Read data
    
    
    
       if (SPI_TX_RX == 0)
    	{
    		//	spib_rx_interupt_service();
    	}
    	else
    	{
    		SPITX_INTERRUPT_Service();
    	}
    
    	SpiaRegs.SPIFFRX.bit.RXFFOVFCLR = 1;  // Clear Overflow flag
    	SpiaRegs.SPIFFRX.bit.RXFFINTCLR = 1;  // Clear Interrupt flag
    	//PieCtrlRegs.PIEACK.all |= 0x20;       // Issue PIE ack
    	PieCtrlRegs.PIEACK.bit.ACK6 = 1;
    
    	//PieCtrlRegs.PIEACK.bit.ACK6 = 1;
    	//SPITX_INTERRUPT_Service();
    }
    
    //
    // End of file
    //
    
    

  • Ami,

    The ADS1148 should power up to an operational state. Just to take a quick look, I used the ADS1148EVM. Below is a picture of the device with a few important nodes:

    Here, all I do is connect +5V to AVDD, DVDD, START and /RESET. Then I connect 0V to GND and AVSS. There's no connection to a master, and I don't try to read out data.

    This is what I get back when I look at /DRDY:

    The device powers up into operation and I'm getting back a data ready signal that occurs every 200ms (at a data rate of 5SPS). As long as I don't put the device into power-down, RESET or keep START low, it should be making conversions.

    I don't see anything in your code that would stop the device, but I may have missed something. Regardless, the device should have powered up on it's own unless there is a bad connection on the board or a bad SPI communication.

    Joseph Wu

  • Joseph,

             Thank you for checking on evm board Joseph. Is it compulsory to provide differential input on AIN0 and AIN1? If I am giving 3.3V unipolar supply to AIN0 and ground to AIN1 is it going to be wrong way? Can you recommend whether any other thing I am missing out in connection side.

    Regards,

    Ami Bhadauria

  • Ami,


    To check general communications, you don't even need the AINx pins connected. For the last post that I show, I didn't have any of the analog inputs connected.

    However, if you do want to check some basic measurements, I generally will tie the inputs to mid-supply first to check the offset. It's unlikely going to be exactly 0V. I wouldn't tie the inputs to AVDD and AVSS (your 3.3V and 0V points). This would over-range the modulator (but shouldn't hurt the device). It should give a reading of 7FFFh.

    One thing that you can read would be the temperature sensor. When enabled you should get an ADC reading equivalent to 118mV. This is a good non-zero value to check.

    If you're still having problems with just getting /DRDY out, I would suggest that you check your schematic and verify all the connections to make sure there isn't anything that isn't misconnected. If you want, post your schematic so that I can look it over.



    Joseph Wu

  • Hello Joseph,

            In above picture I have shown roughly how I have connected my pins.

    Regards,

    Ami

  • Ami,


    I'm not sure what is wrong. I have fewer connections to the ADS1148 than you have in your set up, and I can see my /DRDY rise and fall with the new data. My setup is as basic as it gets.

    I would first verify that you don't have some sort of bad connection. Check all pins on the pin diagram to make sure you haven't made a mistake in pin order. Make sure you don't have a bad solder connection. I would also check the state of all digital connections to the microprocessor. Maybe you have a GPIO set as an output that should be an input (or vice versa).

    If you are able to read from and write to the registers, I would set the DRDY mode to 1 (IDAC0 register bit3) and observe the DOUT/DRDY pin when /CS is low just to see if the /DRDY coming out there.

    At this point, I'd also consider removing all the resistors connecting the device to the microprocessor, just to see that the ADS1148 is working. I would also consider replacing the device if you think there's even the possibility of it being damaged.


    Joseph Wu
  • Ami,


    Have you looked through my last post and performed some of the tests that I described? As I mentioned, I think it should be moderately easy to see the /DRDY pin status unless there is some problem with the board or the device.

    Since you haven't posted back with a response, I'll close the post for now. However, if you want to follow up, feel free to repost to the thread. After some time the thread will lock out. If that does, just start another post.


    Joseph Wu