From: kishor on
Hi friends,
I am working on 16 - channel data acquisition project, Silab C8051F310
+ ADS1255 + external multiplexer.

ADC crystal is 7.643 MHz.
SPI clock freq is 1.58 MHz

Hardware interface-
CS --> permanently tied to ground
3 wire SPI (SCK, MOSI, MISO)
DRDY as external interrupt source

When I debug the code by step by step it works most of the time.
But in normal case it does not.

Whether my command sequence or delay between command is wrong.
Or something else i am missing.


Source code


/**
* @brief Write data to ADS1255 registers at specified address \a
lbAddress
* of specified length \a lbLength from pointer \a lpSource.
*
* @param lbLength - Specifies the number of Bytes to write
* @param lbAddress - Specifies the destination ADS1255 register
address
* @param lpSource - Byte pointer to write data to ADS1255
*
*/
void Wr_ADS1255_Reg ( Byte lbLength, Byte lbAddress, Byte * lpSource )
{
SELECT_ADS1255(); // Select ADS1255

SPI_Write ( 0x50 | lbAddress ); // Address with Write command
SPI_Write ( lbLength - 1 ); // No of registers to write

do
{
SPI_Write ( *lpSource++ ); // Write the data
}
while ( --lbLength );

Wait_Clk ( 16 ); // Wait for 16 clock
}

/**
* @brief Read data from ADS1255 registers from specified address \a
lbAddress
* of specified length \a lbLength to pointer \a lpDest
*
* @param lbLength - Specifies the number of Bytes to read
* @param lbAddress - Specifies the address of ADS1255 register
* @param lpDest - Byte pointer to store data from ADS1255
*
*/
void Rd_ADS1255_Reg ( Byte lbLength, Byte lbAddress, Byte * lpDest )
{
SELECT_ADS1255(); // Select ADS1255

SPI_Write ( lbAddress | 0x10 ); // Write Address with read command

SPI_Write ( lbLength - 1 ); // No of registers to read

Wait_Clk ( 80 ); // Wait for 80 clock

do
{
*lpDest++ = SPI_Read(); // Read data from ADS1255
}
while ( --lbLength );

Wait_Clk ( 16 ); // Wait for 16 clock

}


void Init_ADS1255 ( void)
{

SELECT_ADS1255();

Send_SPI ( enWAKEUP ); // Wakeup the Ads1255.
Wait_Clk ( 48 ); // Wait for 48 clocks

Send_SPI ( enRESET ); // Reset the ADS1255.
Wait_Clk ( 48 ); // Wait for 48 clocks

// Read the registers to verify the communication
Rd_ADS1255_Reg ( sizeof ( stRdReg ), 0, ( Byte * ) &stRdReg );

stWrReg.Status = 0x04; // Auto calibration is enabled
stWrReg.MUX = 0x08; // Single ended channel 0
stWrReg.ADCON = 0;
stWrReg.IO = 0xE0; // IO register
stWrReg.DRate = 0xF0; // 30K SPS

Wr_ADS1255_Reg ( 5, 0, ( Byte * ) &stWrReg );

SPI_Write ( enSYNC ); // Syncronize the ADC

SPI_Write ( enWAKEUP ); // Wakeup the Adc


Rd_ADS1255_Reg ( sizeof ( stRdReg ), 0, ( Byte * ) &stRdReg );


SPI_Write ( enSELFCAL ); // perform Self calibration

}

From: Frnak McKenney on
On Fri, 5 Mar 2010 03:41:28 -0800 (PST), kishor <kiishor(a)gmail.com> wrote:
> Hi friends,
> I am working on 16 - channel data acquisition project, Silab C8051F310
> + ADS1255 + external multiplexer.
>
> ADC crystal is 7.643 MHz.
> SPI clock freq is 1.58 MHz
>
> Hardware interface-
> CS --> permanently tied to ground
> 3 wire SPI (SCK, MOSI, MISO)
> DRDY as external interrupt source
>
> When I debug the code by step by step it works most of the time.
> But in normal case it does not.
>
> Whether my command sequence or delay between command is wrong.
> Or something else i am missing.

First, without more detail on what you mean when you say "works" or
"doesn't work", it will be hard for anyone to offer any specific
recommendations. What do you expect to happen when it works? What do
you observe that leads you to conclude that it isn't working?

Based on your report that it works (mostly) when you step through the
code with your debugger, it sounds like a timing issue to me. These
can be extremely difficult to diagnose because you are attempting to
examine in seconds or tens of seconds events that occur in microseconds.

At this point I'd suggest that you re-read the ADC datasheet carefully
with special attention to minimum and maximum timings. Your debugger
slows down the CPU's actions relative to the ADC, so I'd start with the
minimum timings and check them against your hand-calculated instruction
timings for your '8051 code.

Good luck!


Frank McKenney
--
Youth is much more capable of amusing itself than is now
supposed, and in much less mortal need of being amused. The
only real warning against solitude and stagnation which needs
to be uttered is that you really need to be rather young and
strong in order to get the fun out of them.
-- G.K. Chesterton: On the Thrills of Boredom (1932)
--
Frank McKenney, McKenney Associates
Richmond, Virginia / (804) 320-4887
Munged E-mail: frank uscore mckenney ayut mined spring dawt cahm (y'all)
From: Hans-Bernhard Bröker on
kishor wrote:
> Hi friends,
> I am working on 16 - channel data acquisition project, Silab C8051F310
> + ADS1255 + external multiplexer.
>
> ADC crystal is 7.643 MHz.
> SPI clock freq is 1.58 MHz
>
> Hardware interface-
> CS --> permanently tied to ground

That's _wrong_. SPI uses edges of the CS line to signal the beginning
of a transaction. It can't work without it.

From: MK on

"Hans-Bernhard Br�ker" <HBBroeker(a)t-online.de> wrote in message
news:hmrmg1$qbh$00$1(a)news.t-online.com...
> kishor wrote:
>> Hi friends,
>> I am working on 16 - channel data acquisition project, Silab C8051F310
>> + ADS1255 + external multiplexer.
>>
>> ADC crystal is 7.643 MHz.
>> SPI clock freq is 1.58 MHz
>>
>> Hardware interface-
>> CS --> permanently tied to ground
>
> That's _wrong_. SPI uses edges of the CS line to signal the beginning of
> a transaction. It can't work without it.
>

The OP needs to re-visit the data sheet. TI do offer a mode of operation for
this part with CS tied to ground but of course it's not SPI - it's a two
wire mode with DataIn and DataOut on th same pin and not all the chip
functions are supported.

Since the Silab part has proper SPI why not use it ?

Michael Kellett


From: karthikbalaguru on
On Mar 5, 4:41 pm, kishor <kiis...(a)gmail.com> wrote:
> Hi friends,
> I am working on 16 - channel data acquisition project, Silab C8051F310
> + ADS1255 + external multiplexer.
>
> ADC crystal is 7.643 MHz.
> SPI clock freq is 1.58 MHz
>
> Hardware interface-
>         CS -->  permanently tied to ground
>         3 wire SPI (SCK, MOSI, MISO)
>         DRDY as external interrupt source
>
> When I debug the code by step by step it works most of the time.
> But in normal case it does not.
>
> Whether my command sequence or delay between command is wrong.
> Or something else i am missing.
>
> Source code
>
> /**
>  * @brief       Write data to ADS1255 registers at specified address \a
> lbAddress
>  *              of specified length \a lbLength from pointer \a lpSource.
>  *
>  * @param       lbLength - Specifies the number of Bytes to write
>  * @param       lbAddress - Specifies the destination ADS1255 register
> address
>  * @param       lpSource - Byte pointer to write data to ADS1255
>  *
>  */
> void Wr_ADS1255_Reg ( Byte lbLength, Byte lbAddress, Byte * lpSource )
> {
>         SELECT_ADS1255();                               // Select ADS1255
>
>         SPI_Write ( 0x50 | lbAddress );                 // Address with Write command
>         SPI_Write ( lbLength - 1 );                     // No of registers to write
>
>         do
>         {
>                 SPI_Write ( *lpSource++ );              // Write the data
>         }
>         while ( --lbLength );
>
>         Wait_Clk ( 16 );                                        // Wait for 16 clock
>
> }
>
> /**
>  * @brief       Read data from ADS1255 registers from specified address \a
> lbAddress
>  *              of specified length \a lbLength to pointer \a lpDest
>  *
>  * @param       lbLength - Specifies the number of Bytes to read
>  * @param       lbAddress - Specifies the address of ADS1255 register
>  * @param       lpDest - Byte pointer to store data from ADS1255
>  *
>  */
> void Rd_ADS1255_Reg ( Byte lbLength, Byte lbAddress, Byte * lpDest )
> {
>         SELECT_ADS1255();                       // Select ADS1255
>
>         SPI_Write ( lbAddress | 0x10 );         // Write Address with read command
>
>         SPI_Write ( lbLength - 1 );             // No of registers to read
>
>         Wait_Clk ( 80 );                                // Wait for 80 clock
>
>         do
>         {
>                 *lpDest++ = SPI_Read();         // Read data from ADS1255
>         }
>         while ( --lbLength );
>
>         Wait_Clk ( 16 );                                // Wait for 16 clock
>
> }
>
> void Init_ADS1255 ( void)
> {
>
>         SELECT_ADS1255();
>
>         Send_SPI ( enWAKEUP );          // Wakeup the Ads1255.
>         Wait_Clk ( 48 );                                // Wait for 48 clocks
>
>         Send_SPI ( enRESET );                   // Reset the ADS1255.
>         Wait_Clk ( 48 );                                // Wait for 48 clocks
>
>         // Read the registers to verify the communication
>         Rd_ADS1255_Reg ( sizeof ( stRdReg ), 0, ( Byte * ) &stRdReg );
>
>         stWrReg.Status  = 0x04;         // Auto calibration is enabled
>         stWrReg.MUX             = 0x08;         // Single ended channel 0
>         stWrReg.ADCON           = 0;
>         stWrReg.IO              = 0xE0;         // IO register
>         stWrReg.DRate           = 0xF0;         // 30K SPS
>
>         Wr_ADS1255_Reg ( 5, 0, ( Byte * ) &stWrReg );
>
>         SPI_Write ( enSYNC );                           // Syncronize the ADC
>
>         SPI_Write ( enWAKEUP );                 // Wakeup the Adc
>
>         Rd_ADS1255_Reg ( sizeof ( stRdReg ), 0, ( Byte * ) &stRdReg );
>
>         SPI_Write ( enSELFCAL );                // perform Self calibration
>
>
>
> }- Hide quoted text -
>
> - Show quoted text -


Since it works while you go in slowly, it should
be a delay factor that is affecting the operation.

Just as other pointed out, it would be better if
you are clear of the operation from the datasheet.

BR,
Karthik Balaguru