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.

ADC ADS1114 return NAK when pointing to Conversion Register

Other Parts Discussed in Thread: ADS1110, ADS1114, ADS1115

Hi, I am actually using ADC model ADS1110 with I2C communication on an active product.

To improve conversion stability vs temperature variation, I selected ADC ADS1114 to modify that existing product.

I have all proven I2C C language functions to communicate with existing ADS1110.

I am recycling the I2C functions to configure and read the new ADS1114.

I am refering to the datasheet SBAS444B (october 2009), page 11, section "Write to Pointer register".

When testing, the ADS1114 return a NAK (not acknowledge) right after sending "Second byte: 0b00000000 (points to Conversion register inside Read_ADS1114_Data_NR function)", while I expect an "ACK"), and while the previous "7-bits I2C address followed by a low read/write bit" returned an AK (acknowledge).

You may see below my i2c_write() function, written in CCS C and executed in a PIC18F67K22 Microchip.

While I review over and over my code for a "between the chair and the keyboard" mistake, I submit my question:

 "Can somebody see something wrong in the code ( inside Read_ADS1114_Data_NR function) that fail for a ADS1114 in this function, when I attempt writing the 2nd byte to point to Conversion register, even if the same i2c_write() function works well with ADS1110" ?

Thanks

 

Code sample:

[…]

//----------------------------------------------------------------------------

// Function     : Init_ADS1114

//

// Description : Initialize/Configure the ADS1114 A/D chip

//

// Input       : None

//

// Output       : None

//

// Return       : OK (0x00):           Operation completed OK

//                    : ERR_I2C (0x01): device not responding over i2c

//

// Globals     : None

//----------------------------------------------------------------------------

BYTE Init_ADS1114(void )

{

   BYTE byRet;

      

   //Write to Config Register

   byRet = Write_ADS1114_Cfg( OPTICS_BLCK_ADC_I2C_ADD, ADS1114_CFG );

//OPTICS_BLCK_ADC_I2C_ADD = 0x49 = 0b1001001 = byAdd                                                                                                                                                                                                                                                   

//ADS1114_CFG = 0x8483 = 0b0000010110000011 --> ADS1114 Config: BIT15:OS[1](0:no effect in //write;1:begin single conversion); BIT14-13-12:MUX INPUT[000](ADS1115 only) ; BIT11-10-//09:PGA[010](010:FS=+-2.048V (default)) ; BIT8:MODE[0](continuous conversion mode) ; BIT7-6-//5:DATA RATE[100](128SPS (default)) ; BIT4:COMP MODE[0](0:traditional comparator with hysteresis //(default)) ; BIT3:COMP POL[0](polarity, 0:active low (default)) ; BIT2:COMP LAT[0](non-latching //comparator (default)) ; BIT1-0:COMP QUEUE[11](11:disable comparator (default)

  

   if (byRet != OK)

   {

               return( ERR_I2C );         // unable to Write CFG_REG of ADS1114 chip

   }

   return( OK );

}

 

 

//----------------------------------------------------------------------------

// Function     : Write_ADS1114_Cfg

//

// Description : Write the Configuration register (16 bit) of A/D (ADS1114)

//

//                 This function RETRIES 2 times (3 attempts total)

//                 is case of error

//

//

// Input       : byADD         : Address of the ADS1114

//

//                 byCfg_Reg     : The byte value to write to Cfg_Reg

//

// Output       : None

//

// Return       : OK (0x00):           Operation completed OK

//                    : ERR_I2C (0x01): device not responding over i2c

//

// Globals     : None

//----------------------------------------------------------------------------

BYTE Write_ADS1114_Cfg( WORD byAdd, WORD byCfg_Reg )                   

{

   BYTE byRet;

   BYTE byRetry_Cnt;

 

   byRetry_Cnt = 3;

   do

   {

     byRet = Write_ADS1114_Cfg_NR( byAdd, byCfg_Reg );

     if (byRet != OK)

     {

                delay_ms(200);

                init_i2c_port();       // re-init i2c_1 port

     }

     byRetry_Cnt--;

   }

   while ( (byRet != OK) && (byRetry_Cnt) );

 

   if ( (byRet != OK) && (byRetry_Cnt == 0) )

     return( ERR_I2C );         // unable to Write ADS1114 chip

 

   return( OK );

}

 

 

//----------------------------------------------------------------------------

// Function     : Write_ADS1114_Cfg_NR   (No Retry)

//

// Description : Write the Configuration register (16 bit) of A/D (ADS1114)

//

//                 This function DOES NOT RETRY is case of error

//

//

// Input      : byADD         : Address of the ADS1114

//

//                 byCfg_Reg     : The byte value to wrtie to Cfg_Reg

//

// Output       : None

//

// Return       : OK (0x00):           Operation completed OK

//                    : ERR_I2C (0x00): device not responding over i2c

//

// Globals     : None

//----------------------------------------------------------------------------

BYTE Write_ADS1114_Cfg_NR( WORD byAdd, WORD byCfg_Reg )                                          

{

   BYTE byRet;

 

   byRet = i2c_start1();

   if (byRet != OK)

               return( ERR_I2C );         // unable to Write ADS1114 chip

 

   byRet = i2c_write1( ADS1114_I2C_W_CMD | (byAdd<<1) );  

//First byte = [low read/write bit] | [First 7-bit I2C address <<1 ]

// ADS1114_I2C_W_CMD = 0x00

  

if (byRet != I2C_ACK_OK)

{

                return( ERR_I2C );  

}

   byRet = i2c_write1( 0b00000001 );   //POINTS TO CONFIG REGISTER                     

   //Second byte = points to Config register

  

   if (byRet != I2C_ACK_OK)

   {

                return( ERR_I2C );

   }

 

   byRet = i2c_write1( ADS1114_CFG_MSB );                                       //WRITE TO CONFIG REGISTER  

   //Third byte = [MSB of the Config register]

  

   if (byRet != OK)

   {

                return( ERR_I2C );         // unable to Write ADS1114 chip after 2 retries (3 attempts total)

   }

 

   byRet = i2c_write1( ADS1114_CFG_LSB );                                          //WRITE TO CONFIG REGISTER

   //Fourth byte = [LSB of the Config register]

  

   if (byRet != OK)

               return( ERR_I2C );         // unable to Write ADS1114 chip

 

   byRet = i2c_stop1();

   if (byRet != OK)

               return( ERR_I2C );         // unable to Write ADS1114 chip

               

   return( OK );

}

 

 

//----------------------------------------------------------------------------

//  Function     : Read_ADS1114_Data

//

//  Description  : Read the Output register (16 bit) of A/D (ADS1114)

//

//                 This function RETRIES 2 times (3 attempts total)

//                 is case of error

//

//  Input        : byADD         : I2C Address of the ADS1114

//

//                 *pwAD_Data16  : pointer to a  WORD where read A/D result

//                  will be returned

//

//  Output       : *pwAD_Data16  : A/D result (16 bits)

//

//  Return       : OK      (0x00):      Operation completed OK

//                     : NAK    (0x01):      Error with Optics Block ADC ADS1114 chip occured

//

//  Globals      : None

//----------------------------------------------------------------------------

BYTE Read_ADS1114_Data( BYTE byAdd, WORD *pwAD_Data16 )

{

   BYTE byRet;

   BYTE byRetry_Cnt;

   byRetry_Cnt = 3;

   do

   {

      byRet = Read_ADS1114_Data_NR( byAdd, pwAD_Data16 );

                 

      if (byRet != OK)

      {

         delay_ms(200);

         init_i2c_port();     //re-init i2c port

      }

      byRetry_Cnt--;

   }

   while ( (byRet != OK) && (byRetry_Cnt) );

 

   if ( (byRet != OK) && (byRetry_Cnt == 0) )

      return( NAK );          //unable to Read ADS1114 chip

 

   return( OK );

}

 

 

//----------------------------------------------------------------------------

//  Function     : Read_ADS1114_Data_NR   (No Retry)

//

//  Description  : Read the Output register (16 bit) of A/D (ADS1114)

//

//                 This function DOES NOT RETRY is case of error

//

//  Input        : byADD         : I2C Address of the ADS1114

//

//                 *pwAD_Data16  : pointer to a  WORD where read A/D result

//                  will be stored

//

//  Output       : *pwAD_Data16  : A/D result (16 bits)

//

//  Return       : OK (0x00):           Operation completed OK

//

//                     : ERR_I2C(0x01):   device not responding over i2c

//                      : I2C_ACK_OK (0x01):  i2c error (...redundant)

//  Globals      : None

//----------------------------------------------------------------------------

BYTE Read_ADS1114_Data_NR( BYTE byAdd, WORD *pwAD_Data16 )                                                   

{

   BYTE byAD_Reg[3];

   BYTE byRet;

 

   byRet = i2c_start1();

   if (byRet != OK)

                return( ERR_I2C );            //i2c start error

 

   byRet = i2c_write1( ADS1114_I2C_R_CMD | (byAdd<<1) );  

   //First byte = [high read/write bit] | [First 7-bit I2C address <<1 ]  

   // ADS1114_I2C_R_CMD = 0x01

 

   if (byRet != I2C_ACK_OK)

                return( ERR_I2C );            //i2c start error */

 

   byRet = i2c_write1( ADS1114_I2C_W_CMD | (byAdd<<1) );  

   //WRITE TO POINTER REGISTER   //First byte = [low read/write bit] | [First 7-bit I2C address<<1]

  

   if (byRet != I2C_ACK_OK)

   {

                return( ERR_I2C );        

   // unable to Write ADS1114 chip after 2 retries (3 attempts total)

   }

  

   byRet = i2c_write1( 0b00000000 );                         

   //Second byte = points to Conversion register

  

   if (byRet != I2C_ACK_OK)

   {

//Here is where it stop working.  The code always enter in this loop

//ADS1114 always return 0x01 (NAK), while I expect 0x00 (ACK)

//and the PIC get out of the function before reading the ADC result into the conversion register.

//Even if I put in comment this error trap, I receive a NAK after the following “i2c_write1(…)”

   return( ERR_I2C ); 

   }

 

   byRet = i2c_write1( ADS1114_I2C_R_CMD | (byAdd<<1) );  

   //READ CONVERSION REGISTER    //First byte = [high read/write bit] | [First 7-bit I2C address<<1]

  

   if (byRet != I2C_ACK_OK)

   {

                return( ERR_I2C );         // unable to Write ADS1114 chip

   }

 

   byRet = i2c_read1( &byAD_Reg[0], I2C_ACK_ADS1114_AFTER_RD );     

   //READ CONVERSION REGISTER             

   //Second byte = ADS1114 response with [MSB of the Conversion register]

   if (byRet != OK)

                return( ERR_I2C );            //i2c start error

 

   byRet = i2c_read1( &byAD_Reg[1], I2C_ACK_ADS1114_AFTER_RD );     

   //READ CONVERSION REGISTER              

//Third byte = ADS1114 response with [LSB of the Conversion register]

 

   if (byRet != OK)

                 return( ERR_I2C );            //i2c start error

 

   byRet = i2c_stop1();

   if (byRet != OK)

                return( ERR_I2C );            //i2c start error

 

   *(BYTE *)pwAD_Data16 = byAD_Reg[1];    //LSB portion

 

   *pwAD_Data16 = byAD_Reg[0];    //MSB portion

   *pwAD_Data16 = (WORD)(*pwAD_Data16<<8) | (WORD)byAD_Reg[1];

  

   return( OK );

}

 

 

//----------------------------------------------------------------------------

//  Function     : i2c_write1

//

//  Description  : Sends a single byte over the I2C port 1

//

//  Input        : bData : the byte to send

//

//  Return       : The ACK bit generated by the slave i2c device.

//                        or WCOL error.

//

//                 Usefull #define:

//                   I2C_ACK_OK     0x00        // ACK received OK from i2c slave

//                   I2C_NOACK      0x01        // No ACK Received from i2c slave

//                   I2C_WCOL_ERR   0x02        // A i2c write to SSPxBUF was...

//                                              // attempted while i2c were...

//                                              // not valid for Tx

//                   ERR_I2C_WR_TIMEOUT (0x04):   I2C transmit timeout

//

//  Globals      : None

//----------------------------------------------------------------------------

BYTE i2c_write1( BYTE bData )

{

   WORD wTimeout;

   BYTE bAckState;

 

   WCOL1 = 0;              // clear bit

   SSP1IF = 0;                // clear bit

   SSPBUF = bData;

 

   if (WCOL1)

   {

                return( I2C_WCOL_ERR );

   }

 

   wTimeout=0x0444;                 //timeout: 1ms (or longer, approx for PIC18 Fosc=40MHz)

   do

   {

                wTimeout--;

   }

   while( (SSP1IF==0) && wTimeout); // wait for transmit to complete

 

   if ( wTimeout )

   {

                bAckState = ACKSTAT1;         // I2C_ACK_OK(0) or I2C_NOACK(1)

                return(bAckState);

   }

   else

   {

                return( ERR_I2C_WR_TIMEOUT );     // timeout error

   }

}

[…]

 

 

 

  • Hi Marc,

    Welcome to the forum!  It is hard for me to discern what you are trying to do as you issue that there is a device read, but I don't see that you actually read.  Then you issue a write, but I have no idea if a STOP/Repeated START was issued.  Is there any chance you can send us logic analyzer/scope shots of this code segment?

    Thanks,

    Bob B

  • Hi Bob,

    I attached "Read_I2C return NAK 4 MHz, 20 M Samples [28].txt."

    Please, download Saleae Logic 1.2.7 Beta software to load the logic analyser capture file.

    Then change the extension of the file  from  "*.txt"  to  "*.logicdata"

    To resume, the problem is that the ADC ADS1114 is returning NAK when I read the conversion register. 

    You may observe the NAK after "read_I2C" at 1s:899.5ms on the logic analyser attached capture file.

    I reproduced the suggested sequence, as described on page #11 of datasheet SBAS444B (device ADC ADS1114).

    Write to Config register:

    At 1s:790.8ms, First byte:  I setup write to "0x92" (...first 7-bits I2C address followed by low read/write bit) + ACK.

    At 1s:790.9ms, 2nd byte:  I send "0b00000001" (points to Config register).

    At 1s:791.0ms, 3rd byte:  I send "0x84" (MSB of the Config register to be written).

    At 1s:791.1ms, 4th byte:  I send "0x83" (LSB of the Config register to be written).

    Write to Pointer register:

    At 1s:865.6ms, First byte:  I setup write to "0x92" (...first 7-bits I2C address followed by low read/write bit) + ACK.

    At 1s:865.7ms, 2nd byte:  I send "0b00000000" (points to Conversion register).

    Read Conversion register:

    At 1s:867.8ms, First byte:  I setup write to "0x93" (...first 7-bits I2C address followed by high read/write bit) + ACK.

    At 1s:899.5ms, 2nd byte:  I read MSB of the Conversion register (0xFF+ NAK)

    At 1s:899.6ms, 3th byte:  I read LSB of the Conversion register (0xFF+ NAK)

     

    Now I investigate the code to understand why the SDA line switch to high level at 1s:895.2ms ?

    The PIC code will trigger a "timeout" on the main state machine loop after 26ms.

    Is it normal that the ADC ADS1114 take more than 26ms to return the conversion response?

    Suggestions welcome.

    Thanks.

     

    
    
    Data save2T	=-1��Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g����Cy;�g���	Channel 0�?�?�Cy;�g���E�	Channel 1@�Cy;�g����Bleu  2�?�?�Cy;�g�����	Channel 3�?�?�Cy;�g�����	Channel 4�?�?�Cy;�g����	Channel 5�?�?�Cy;�g����	Channel 6�?�?�Cy;�g��� ��Brown 7�?�?TTTT-1T-1�T�Cy;�g��@2@2@2TTTTT	=�Cy;�g��T@2T@2@2@2@2@2@2@2@2@2i.��~~~&���������!���������!���������!���������#���������!���������!����������#���������!���������!����������#���������!���������!����������#���������!���������!���������&���������!���������!���������!���������#���������!���������$������������������#���������!�#���������!���������!���������!%���������!���������!���������!���������#���������!���������!����������$��������� ���������$������������������#���������!&���������!���������!���������!���������#���������!���������$������������������#���������"�#���������!���������!���������!&���������!���������!���������!���������#���������!���������!����������$���������!���������$������������������#��������(�!&���������!���������!���������!���������#���������!���������#������������������#���������!�"���������!���������!���������"&���������!���������!���������!���������#���������!���������!��������� �$���������!���������$������������������#��������%�!&���������!���������!���������!���������$���������!���������$������������������#���������!�#���������!���������!���������"&���������"���������!���������!����������������؏�؏�׏��؏�؏��؏�؏f�:�i�2������0���}���Gk0��}���Y���}���30��}���X���}���10��}���X����������f�:G�:
    	#�:�:ψ:('��:21{�:<;J�:FE��:H��:I��:I"�:J�:TSܝ:^]��:hg��:rqW�:|{��:��h�:��D�:���:���:����:���:��Ч:����:����:��X�:����:��f�:��C�:�:�:��:&%�:(oLm)PMm32,Nm=<�NmGF�OmQP�Pm[Z�QmedSRmon�Rmq�bmr�bmrC�qs!�q}|��q����q��g�q�gr�Fr���r���s���s��}�s��L�s����s��x�s��T�s��$�s���s����s�s6xtyt�yt�zt$#�{t.-n|t87J}tBA~tLKb~tN:�tON�tO;yP
    yZY�
    ydc�ynm�yxwpy���y��y��Zy��*y��qy�q$y�P%y���%y��{��{��h{��7{���{�������΂������y��
    I��%���)(=��+��,)��,��-��76��A@U�KJ��Q�'�R�(�\[t)�	cU�d	%�nm�xw����8������������������_�����
    ��
    Ϡ��������{����W����&��������ҥ����	��	�3�
    �4�|5�L6�('(7�21�7�<;79�FE:�PO�:�ZY�;�dc�;�	f�K�g	�L�qp}M�x:�y�:����;����<���@=�
    �sZ��
    T[���0\����\����]����^����_���W`����`�
    �wp��
    �p��[���9��������������^��������('���21k��<;���FE���POs��ZYC��dc��nm���xw&��y~y�z_z���;{���
    |����|����}����~���b��������������Q
    ��/�����������������������
    	q�@���
     �%�!
    f&�+*'�2��3n�=<V�GF%�QP��V�3'W�4'a`�5'kj|6'utY7'~(8'��9'���9'��:'��I'�	J'���+���+����+��c�+����+���+���+����+�d�-�3�-���-����-��F�-��-
    	��-��-��-('m�-21��-3�R.4�S.>=�T.HG�U.RQeV.\[5W.feX.po�X.zy)Y.|i.}@2@2@2+i.�����&�S�T�T��*��}��*�+*�#�S�}���*�#�S�}��+�}��*�#�S�}��U�~��*�#�S�}��+��*&�S�T�T��*��~��*�**#�S�T�T��+$�T�S�*�#�T�}��+�}�*�~�*&�S�T�T��*��}��+�**#�S�}��+��*�$�T�S�T��*$�S�T�*&�S�T�T��*��}��+�**#�S�T�T��*$�T�S�*�#�S�}��*�~�*�~�*&�T�T�U��*��~��*�*+#�T�}��+��*�#�T�T�U��*$�S�T�*&�T�S�T��+��~��*�**#�S�T�T��+$�T�T�*�"�T�}��+�~�*�}�*&�T�S�T��+��~��*�**#�T�}��+��*�$�T�S�U��*$�S�T�*&�T�S�T��+��~��*�**$�T�S�U��*$�S�T�*�#�T�}��+�}�*�~�*%�S�T�T��*��}��+�**KKK#���ww$����w#���x֏���$���ww֏k�$��w֏���#���ww֏g�$��x֏���$���ww֏K�$��w֏���$��R�:�?�2�n��{����}�|�k0�x}�p�/���}�p�	0��}�z�/���}�|�0��}�z�/�������������R�:��:�:��:
    M�:(�:
    ��:��:��:��:*�:5�:��:Ǣ:#�:$�:(��:)ܧ:1֨:2�:	6֪:7	�:
    ?�:@
    r�:B�:C�:D[LmENmL&OmM�Om
    OUPmP
    1QmRRmS�RmV�bmW�bmW/�qX��q_K�q`}�qaSrb�rg>�s��sh��so��sp�sy"xtz�yt��zt�u{t�|t��|t��}t�x~t�:�t�d�t�'y��
    y��y�Ny��y��y���y�Uy��y�]$y��%y�J�z�{��{���������ȃ��P�������҅������S�� ���� ?������\�!����!�"��'��"K)�	��ӱ#	Z��#|�$�v��$��
    �ڟ��
    ���%�����%.��&�ԣ��&���'�����'0��(���(����3��S5�)�M6��)�6�*�L8��*[:�e:�+�;�+<�,�K�,UM�
    ���-,=�-V=�
    _Z�
    \�.*]�.�]�/Y^�/5_�0`�0�`�1 wp�!1�p�!G��"���2)c��*2���3+k�,3��1U��4���24��59��:5;��Cjy�D{�6K5|�L6�|�7Nd}�O7@~�8Q�R8��9U���V9���V=
    �W��:\��]:d�;_��`;��ji��<jk�k<��=ls%�m=�&�r`��>��s>��s�3't�5'?{�6'|?/7'@~�7'@�8'A��9'�A2:'B��I'�BJ'���+�j�+C���+�C�+D���+�DZ�+�Ԇ-Ei�-�E��-F���-�F��-��R.��T.G��U.�G<V.H��V.�H�W.I��X.�I?Y.J�i.�J@2@2�Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g���Cy;�g��	=I2Cj22 serialization::archive 10 17 SaleaeI2CAnalyzer 0 21 17351076086178988961 6 1 17351076086178988961 4 1 2I2C#T	�������������?T)T
    Timing Marker PairA1A2TT

  • Hi Bob.

    After many trial and error, I am now able to read the data from ADS1114.

    A NAK by Master was wrongly removed by me after reading the LSB (2nd byte) of conversion register.

    I also added a i2c_repeat_start(), just before sending the i2c_read().

    I also changed the hardware address of ADS1114, from 0x49 to 0x48, both on my circuit and in the code.

    I am not sure yet which combination of these 3 changes is the effective solution.

    I will isolate each manuver when I will assemble another prototype with previous 0x49 address.

    At least, now I can read it.

    Thanks anyway for the inspiration.

    Marc