Technical discussions about the TI C6000 DSPs (including the c62x, c64x and c67x DSPs).
Post a new Thread
C6713: I2C master transmitter and NACK - Bernhard 'Gustl' Bauer - Jul 5 3:23:00 2005
Hi,
I have a problem with I2C again :-)
I send some bytes to a slave transmitter and the last one is answered
with a NACK. When this happens I2C stops. If I send this to a slave
which answers the last byte with a ACK all is fine.
I have no EDMA, no IRQ and no csl for this. So I must do it by polling
the registers. Any idea how I should treat this situation?
AFAIK it is possible for an I2C slave to answer the last byte (if it
knew its the last one) with an NACK. The I2C module should be able to
deal with this.
TIA Gustl
This is my code:
----------------
far void pipe_data(unsigned char *typ_string)
{
unsigned char *hw_ptr;
unsigned int i,help;
unsigned char dest[10];
unsigned char address=typ_string[1];
unsigned char number=typ_string[2];
unsigned char ret_number=typ_string[3];
unsigned char *source;
source=&typ_string[4];
send_byte=(void(*)(unsigned char))(0x00000CC8);
// I2C open/reset
I2C_RSET(I2COAR0,I2C_I2COAR_DEFAULT);
I2C_RSET(I2CIMR0,I2C_I2CIMR_DEFAULT);
I2C_RSET(I2CCLKL0,I2C_I2CCLKL_DEFAULT);
I2C_RSET(I2CCLKH0,I2C_I2CCLKH_DEFAULT);
I2C_RSET(I2CCNT0,I2C_I2CCNT_DEFAULT);
I2C_RSET(I2CSAR0,I2C_I2CSAR_DEFAULT);
I2C_RSET(I2CMDR0,I2C_I2CMDR_DEFAULT);
I2C_RSET(I2CPSC0,I2C_I2CPSC_DEFAULT);
// I2c_init
I2C_RSET(I2COAR0,I2C_I2COAR_RMK(I2C_I2COAR_A_OF(0)));
I2C_RSET(I2CIMR0,I2C_I2CIMR_RMK(I2C_I2CIMR_ICXRDY_MSK,
I2C_I2CIMR_ICRRDY_MSK,
I2C_I2CIMR_ARDY_MSK,
I2C_I2CIMR_NACK_MSK,
I2C_I2CIMR_AL_MSK));
I2C_RSET(I2CCLKL0,I2C_I2CCLKL_RMK(I2C_I2CCLKL_ICCL_OF(12-6)));
I2C_RSET(I2CCLKH0,I2C_I2CCLKH_RMK(I2C_I2CCLKH_ICCH_OF(12-6)));
I2C_RSET(I2CCNT0,I2C_I2CCNT_RMK(I2C_I2CCNT_ICDC_OF(0)));
I2C_RSET(I2CSAR0,I2C_I2CSAR_RMK(I2C_I2CSAR_A_OF(0)));
I2C_RSET(I2CMDR0,I2C_I2CMDR_RMK(I2C_I2CMDR_NACKMOD_ACK,
I2C_I2CMDR_FREE_BSTOP,
I2C_I2CMDR_STT_NONE,
I2C_I2CMDR_STP_NONE,
I2C_I2CMDR_MST_MASTER,
I2C_I2CMDR_TRX_XMT,
I2C_I2CMDR_XA_7BIT,
I2C_I2CMDR_RM_NONE,
I2C_I2CMDR_DLB_NONE,
I2C_I2CMDR_IRS_RST,
I2C_I2CMDR_STB_NONE,
I2C_I2CMDR_FDF_NONE,
I2C_I2CMDR_BC_BIT8FDF));
I2C_RSET(I2CPSC0,I2C_I2CPSC_RMK(I2C_I2CPSC_IPSC_OF(10-1)));
// I2C out of reset
I2C_RSET(I2CMDR0,I2C_RGET(I2CMDR0)|_I2C_I2CMDR_IRS_MASK);
// clear BB in case of malfunction slave device
I2C_RSET(I2CSTR0,_I2C_I2CSTR_BB_MASK);
// prepare send
I2C_RSET(I2CSAR0,I2C_I2CSAR_RMK(I2C_I2CSAR_A_OF(address)));
I2C_RSET(I2CCNT0,I2C_I2CCNT_RMK(I2C_I2CCNT_ICDC_OF(number)));
I2C_RSET(I2CDXR0,I2C_I2CDXR_RMK(I2C_I2CDXR_OF(*source)));
source++;
number--;
// starting I2C
I2C_RSET(I2CMDR0,I2C_I2CMDR_RMK(I2C_I2CMDR_NACKMOD_ACK,
I2C_I2CMDR_FREE_BSTOP,
I2C_I2CMDR_STT_NONE,
I2C_I2CMDR_STP_NONE,
I2C_I2CMDR_MST_MASTER,
I2C_I2CMDR_TRX_XMT,
I2C_I2CMDR_XA_7BIT,
I2C_I2CMDR_RM_NONE,
I2C_I2CMDR_DLB_NONE,
I2C_I2CMDR_IRS_NRST,
I2C_I2CMDR_STB_NONE,
I2C_I2CMDR_FDF_NONE,
I2C_I2CMDR_BC_BIT8FDF));
I2C_RSET(I2CMDR0,I2C_I2CMDR_RMK(I2C_I2CMDR_NACKMOD_ACK,
I2C_I2CMDR_FREE_BSTOP,
I2C_I2CMDR_STT_START,
I2C_I2CMDR_STP_STOP,
I2C_I2CMDR_MST_MASTER,
I2C_I2CMDR_TRX_XMT,
I2C_I2CMDR_XA_7BIT,
I2C_I2CMDR_RM_NONE,
I2C_I2CMDR_DLB_NONE,
I2C_I2CMDR_IRS_NRST,
I2C_I2CMDR_STB_NONE,
I2C_I2CMDR_FDF_NONE,
I2C_I2CMDR_BC_BIT8FDF));
while((I2C_RGET(I2CSTR0)&_I2C_I2CSTR_BB_MASK)==0);
// send all bytes
while (number>0) {
if ((I2C_RGET(I2CSTR0)&_I2C_I2CSTR_ICXRDY_MASK)!=0) {
2C_RSET(I2CDXR0,I2C_I2CDXR_RMK(I2C_I2CDXR_OF(*source)));
source++;
number--;
}
}/**/
// wait until all is sent
while((I2C_RGET(I2CSTR0)&_I2C_I2CSTR_BB_MASK)!=0);
while((I2C_RGET(I2CSTR0)&_I2C_I2CSTR_BB_MASK)!=0);
}

(You need to be a member of c6x -- send a blank email to c6x-subscribe@yahoogroups.com )
Re: C6713: I2C master transmitter and NACK - Raja Das - Jul 5 5:36:00 2005
HI
As far as my knowledge goes, the I2C peripheral slave dont acknowledge
for the last transmitted byte. but as your saying that the slave is
sending a NACK, that means the slave is not able to receive the last
byte properly, that might be possible due to many reasons.
Regards
Raja
On 7/5/05, Bernhard 'Gustl' Bauer <gustl@gust...> wrote:
> Hi,
>
> I have a problem with I2C again :-)
>
> I send some bytes to a slave transmitter and the last one is answered
> with a NACK. When this happens I2C stops. If I send this to a slave
> which answers the last byte with a ACK all is fine.
>
> I have no EDMA, no IRQ and no csl for this. So I must do it by polling
> the registers. Any idea how I should treat this situation?
>
> AFAIK it is possible for an I2C slave to answer the last byte (if it
> knew its the last one) with an NACK. The I2C module should be able to
> deal with this.
>
> TIA Gustl
>
> This is my code:
> ----------------
> far void pipe_data(unsigned char *typ_string)
> {
> unsigned char *hw_ptr;
> unsigned int i,help;
> unsigned char dest[10];
> unsigned char address=typ_string[1];
> unsigned char number=typ_string[2];
> unsigned char ret_number=typ_string[3];
> unsigned char *source;
>
> source=&typ_string[4];
> send_byte=(void(*)(unsigned char))(0x00000CC8);
> // I2C open/reset
> I2C_RSET(I2COAR0,I2C_I2COAR_DEFAULT);
> I2C_RSET(I2CIMR0,I2C_I2CIMR_DEFAULT);
> I2C_RSET(I2CCLKL0,I2C_I2CCLKL_DEFAULT);
> I2C_RSET(I2CCLKH0,I2C_I2CCLKH_DEFAULT);
> I2C_RSET(I2CCNT0,I2C_I2CCNT_DEFAULT);
> I2C_RSET(I2CSAR0,I2C_I2CSAR_DEFAULT);
> I2C_RSET(I2CMDR0,I2C_I2CMDR_DEFAULT);
> I2C_RSET(I2CPSC0,I2C_I2CPSC_DEFAULT);
>
> // I2c_init
> I2C_RSET(I2COAR0,I2C_I2COAR_RMK(I2C_I2COAR_A_OF(0)));
> I2C_RSET(I2CIMR0,I2C_I2CIMR_RMK(I2C_I2CIMR_ICXRDY_MSK,
> I2C_I2CIMR_ICRRDY_MSK,
> I2C_I2CIMR_ARDY_MSK,
> I2C_I2CIMR_NACK_MSK,
> I2C_I2CIMR_AL_MSK));
> I2C_RSET(I2CCLKL0,I2C_I2CCLKL_RMK(I2C_I2CCLKL_ICCL_OF(12-6)));
> I2C_RSET(I2CCLKH0,I2C_I2CCLKH_RMK(I2C_I2CCLKH_ICCH_OF(12-6)));
> I2C_RSET(I2CCNT0,I2C_I2CCNT_RMK(I2C_I2CCNT_ICDC_OF(0)));
> I2C_RSET(I2CSAR0,I2C_I2CSAR_RMK(I2C_I2CSAR_A_OF(0)));
> I2C_RSET(I2CMDR0,I2C_I2CMDR_RMK(I2C_I2CMDR_NACKMOD_ACK,
> I2C_I2CMDR_FREE_BSTOP,
> I2C_I2CMDR_STT_NONE,
> I2C_I2CMDR_STP_NONE,
> I2C_I2CMDR_MST_MASTER,
> I2C_I2CMDR_TRX_XMT,
> I2C_I2CMDR_XA_7BIT,
> I2C_I2CMDR_RM_NONE,
> I2C_I2CMDR_DLB_NONE,
> I2C_I2CMDR_IRS_RST,
> I2C_I2CMDR_STB_NONE,
> I2C_I2CMDR_FDF_NONE,
> I2C_I2CMDR_BC_BIT8FDF));
> I2C_RSET(I2CPSC0,I2C_I2CPSC_RMK(I2C_I2CPSC_IPSC_OF(10-1)));
> // I2C out of reset
> I2C_RSET(I2CMDR0,I2C_RGET(I2CMDR0)|_I2C_I2CMDR_IRS_MASK);
> // clear BB in case of malfunction slave device
> I2C_RSET(I2CSTR0,_I2C_I2CSTR_BB_MASK);
> // prepare send
> I2C_RSET(I2CSAR0,I2C_I2CSAR_RMK(I2C_I2CSAR_A_OF(address)));
> I2C_RSET(I2CCNT0,I2C_I2CCNT_RMK(I2C_I2CCNT_ICDC_OF(number)));
> I2C_RSET(I2CDXR0,I2C_I2CDXR_RMK(I2C_I2CDXR_OF(*source)));
> source++;
> number--;
> // starting I2C
> I2C_RSET(I2CMDR0,I2C_I2CMDR_RMK(I2C_I2CMDR_NACKMOD_ACK,
> I2C_I2CMDR_FREE_BSTOP,
> I2C_I2CMDR_STT_NONE,
> I2C_I2CMDR_STP_NONE,
> I2C_I2CMDR_MST_MASTER,
> I2C_I2CMDR_TRX_XMT,
> I2C_I2CMDR_XA_7BIT,
> I2C_I2CMDR_RM_NONE,
> I2C_I2CMDR_DLB_NONE,
> I2C_I2CMDR_IRS_NRST,
> I2C_I2CMDR_STB_NONE,
> I2C_I2CMDR_FDF_NONE,
> I2C_I2CMDR_BC_BIT8FDF));
> I2C_RSET(I2CMDR0,I2C_I2CMDR_RMK(I2C_I2CMDR_NACKMOD_ACK,
> I2C_I2CMDR_FREE_BSTOP,
> I2C_I2CMDR_STT_START,
> I2C_I2CMDR_STP_STOP,
> I2C_I2CMDR_MST_MASTER,
> I2C_I2CMDR_TRX_XMT,
> I2C_I2CMDR_XA_7BIT,
> I2C_I2CMDR_RM_NONE,
> I2C_I2CMDR_DLB_NONE,
> I2C_I2CMDR_IRS_NRST,
> I2C_I2CMDR_STB_NONE,
> I2C_I2CMDR_FDF_NONE,
> I2C_I2CMDR_BC_BIT8FDF));
> while((I2C_RGET(I2CSTR0)&_I2C_I2CSTR_BB_MASK)==0);
> // send all bytes
> while (number>0) {
> if ((I2C_RGET(I2CSTR0)&_I2C_I2CSTR_ICXRDY_MASK)!=0) {
> 2C_RSET(I2CDXR0,I2C_I2CDXR_RMK(I2C_I2CDXR_OF(*source)));
> source++;
> number--;
> }
> }/**/
> // wait until all is sent
> while((I2C_RGET(I2CSTR0)&_I2C_I2CSTR_BB_MASK)!=0);
> while((I2C_RGET(I2CSTR0)&_I2C_I2CSTR_BB_MASK)!=0);
> }
--
Raja Das
Flextronics Software Systems
______________________________
New Code Sharing Section now Live on DSPRelated.com.
Learn about the Reward
Program for Contributors here. 
(You need to be a member of c6x -- send a blank email to c6x-subscribe@yahoogroups.com )
Re: C6713: I2C master transmitter and NACK - Bernhard 'Gustl' Bauer - Jul 5 7:03:00 2005
Hi Raja,
thanks for your quick answer.
Raja Das wrote:
> HI
> As far as my knowledge goes, the I2C peripheral slave dont acknowledge
> for the last transmitted byte. but as your saying that the slave is
> sending a NACK, that means the slave is not able to receive the last
> byte properly, that might be possible due to many reasons.
This is a bit confusing. Isn't a NACK the same as 'don't acknowledge'?
I see there is a problem in distinguishing whether it is a last byte or
e.g. a transmission error.
I've had a look at the specification of Philips. The only situation
where a NACK is used to terminate a data stream is when a master
receiver signals to a slave transmitter 'no more data'.
I think this answers my problem, or at least shifts it to the slave
receiver.
Thanks a lot
Gustl
> Regards
> Raja
>
>
> On 7/5/05, Bernhard 'Gustl' Bauer <gustl@gust...> wrote:
>
>>Hi,
>>
>>I have a problem with I2C again :-)
>>
>>I send some bytes to a slave transmitter and the last one is answered
>>with a NACK. When this happens I2C stops. If I send this to a slave
>>which answers the last byte with a ACK all is fine.
>>
>>I have no EDMA, no IRQ and no csl for this. So I must do it by
polling
>>the registers. Any idea how I should treat this situation?
>>
>>AFAIK it is possible for an I2C slave to answer the last byte (if it
>>knew its the last one) with an NACK. The I2C module should be able to
>>deal with this.
>>
>>TIA Gustl
>>
>>This is my code:
>>----------------
>>far void pipe_data(unsigned char *typ_string)
>>{
>> unsigned char *hw_ptr;
>> unsigned int i,help;
>> unsigned char dest[10];
>> unsigned char address=typ_string[1];
>> unsigned char number=typ_string[2];
>> unsigned char ret_number=typ_string[3];
>> unsigned char *source;
>>
>> source=&typ_string[4];
>> send_byte=(void(*)(unsigned char))(0x00000CC8);
>>
>>
>> // I2C open/reset
>> I2C_RSET(I2COAR0,I2C_I2COAR_DEFAULT);
>> I2C_RSET(I2CIMR0,I2C_I2CIMR_DEFAULT);
>> I2C_RSET(I2CCLKL0,I2C_I2CCLKL_DEFAULT);
>> I2C_RSET(I2CCLKH0,I2C_I2CCLKH_DEFAULT);
>> I2C_RSET(I2CCNT0,I2C_I2CCNT_DEFAULT);
>> I2C_RSET(I2CSAR0,I2C_I2CSAR_DEFAULT);
>> I2C_RSET(I2CMDR0,I2C_I2CMDR_DEFAULT);
>> I2C_RSET(I2CPSC0,I2C_I2CPSC_DEFAULT);
>>
>> // I2c_init
>> I2C_RSET(I2COAR0,I2C_I2COAR_RMK(I2C_I2COAR_A_OF(0)));
>> I2C_RSET(I2CIMR0,I2C_I2CIMR_RMK(I2C_I2CIMR_ICXRDY_MSK,
>> I2C_I2CIMR_ICRRDY_MSK,
>> I2C_I2CIMR_ARDY_MSK,
>> I2C_I2CIMR_NACK_MSK,
>> I2C_I2CIMR_AL_MSK));
>> I2C_RSET(I2CCLKL0,I2C_I2CCLKL_RMK(I2C_I2CCLKL_ICCL_OF(12-6)));
>> I2C_RSET(I2CCLKH0,I2C_I2CCLKH_RMK(I2C_I2CCLKH_ICCH_OF(12-6)));
>> I2C_RSET(I2CCNT0,I2C_I2CCNT_RMK(I2C_I2CCNT_ICDC_OF(0)));
>> I2C_RSET(I2CSAR0,I2C_I2CSAR_RMK(I2C_I2CSAR_A_OF(0)));
>> I2C_RSET(I2CMDR0,I2C_I2CMDR_RMK(I2C_I2CMDR_NACKMOD_ACK,
>> I2C_I2CMDR_FREE_BSTOP,
>> I2C_I2CMDR_STT_NONE,
>> I2C_I2CMDR_STP_NONE,
>> I2C_I2CMDR_MST_MASTER,
>> I2C_I2CMDR_TRX_XMT,
>> I2C_I2CMDR_XA_7BIT,
>> I2C_I2CMDR_RM_NONE,
>> I2C_I2CMDR_DLB_NONE,
>> I2C_I2CMDR_IRS_RST,
>> I2C_I2CMDR_STB_NONE,
>> I2C_I2CMDR_FDF_NONE,
>> I2C_I2CMDR_BC_BIT8FDF));
>> I2C_RSET(I2CPSC0,I2C_I2CPSC_RMK(I2C_I2CPSC_IPSC_OF(10-1)));
>> // I2C out of reset
>> I2C_RSET(I2CMDR0,I2C_RGET(I2CMDR0)|_I2C_I2CMDR_IRS_MASK);
>> // clear BB in case of malfunction slave device
>> I2C_RSET(I2CSTR0,_I2C_I2CSTR_BB_MASK);
>> // prepare send
>> I2C_RSET(I2CSAR0,I2C_I2CSAR_RMK(I2C_I2CSAR_A_OF(address)));
>> I2C_RSET(I2CCNT0,I2C_I2CCNT_RMK(I2C_I2CCNT_ICDC_OF(number)));
>> I2C_RSET(I2CDXR0,I2C_I2CDXR_RMK(I2C_I2CDXR_OF(*source)));
>> source++;
>> number--;
>> // starting I2C
>> I2C_RSET(I2CMDR0,I2C_I2CMDR_RMK(I2C_I2CMDR_NACKMOD_ACK,
>> I2C_I2CMDR_FREE_BSTOP,
>> I2C_I2CMDR_STT_NONE,
>> I2C_I2CMDR_STP_NONE,
>> I2C_I2CMDR_MST_MASTER,
>> I2C_I2CMDR_TRX_XMT,
>> I2C_I2CMDR_XA_7BIT,
>> I2C_I2CMDR_RM_NONE,
>> I2C_I2CMDR_DLB_NONE,
>> I2C_I2CMDR_IRS_NRST,
>> I2C_I2CMDR_STB_NONE,
>> I2C_I2CMDR_FDF_NONE,
>> I2C_I2CMDR_BC_BIT8FDF));
>> I2C_RSET(I2CMDR0,I2C_I2CMDR_RMK(I2C_I2CMDR_NACKMOD_ACK,
>> I2C_I2CMDR_FREE_BSTOP,
>> I2C_I2CMDR_STT_START,
>> I2C_I2CMDR_STP_STOP,
>> I2C_I2CMDR_MST_MASTER,
>> I2C_I2CMDR_TRX_XMT,
>> I2C_I2CMDR_XA_7BIT,
>> I2C_I2CMDR_RM_NONE,
>> I2C_I2CMDR_DLB_NONE,
>> I2C_I2CMDR_IRS_NRST,
>> I2C_I2CMDR_STB_NONE,
>> I2C_I2CMDR_FDF_NONE,
>> I2C_I2CMDR_BC_BIT8FDF));
>> while((I2C_RGET(I2CSTR0)&_I2C_I2CSTR_BB_MASK)==0);
>> // send all bytes
>> while (number>0) {
>> if ((I2C_RGET(I2CSTR0)&_I2C_I2CSTR_ICXRDY_MASK)!=0) {
>> 2C_RSET(I2CDXR0,I2C_I2CDXR_RMK(I2C_I2CDXR_OF(*source)));
>> source++;
>> number--;
>> }
>> }/**/
>> // wait until all is sent
>> while((I2C_RGET(I2CSTR0)&_I2C_I2CSTR_BB_MASK)!=0);
>> while((I2C_RGET(I2CSTR0)&_I2C_I2CSTR_BB_MASK)!=0);
>>}
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>

(You need to be a member of c6x -- send a blank email to c6x-subscribe@yahoogroups.com )