TWI ASF and NACKs

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm using the TWI ASF on a SAMG55 for I2C communications.  Most stuff (including a couple SMBUS devices) is working fine, but I have one somewhat non-standard chip that I'm not sure how to accommodate.

 

During a read operation (Master writes command code, then reads result), the slave chip will NACK the slave address byte until the result is ready.  The problem here is that the ASF is written to return a failure as soon as it sees the NACK.  I'm also not sure how to manually detect this and re-send just the slave address byte.  Inside twi_master_read(), the line p_twi->TWI_CR = TWI_CR_START; sets up the entire transfer, including writing the command byte.  How can I configure it to simply resend the NACKed byte until it is ACKed (or times out)?

 

Attached image is the result of the  p_twi->TWI_CR = TWI_CR_START; line using a chip address of 0x40 and a command byte of 0xF5

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hillridge wrote:
I have one somewhat non-standard chip

 

I'll begin by saying I have not worked with ASF or the SAM chips.

It would help to know what chip this is, DS link? As others may have run into it before.

 

Given what you have provided about the chip, you may need to write a wrapper function around your calls to handle this special case.

 

Jim

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sure, I'd be surprised if no one has used it, seems to be fairly popular:

https://www.silabs.com/documents...

 

It can also operate in a clock stretching mode, which I previously had working on an XMEGA.  I'm going to look into that as well since I'm close to having it work that way, but something still isn't quite right.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Re: The clock stretching mode -

I haven't figured out how to make the SAMG55 handle this.  I can artificially get it to work via the debugger by stepping through the TWI driver code and introducing delays, but it fails if run normally.  It seems like there's a variety of TWI configurations the ASF makes no provision for (an unfortunately common theme with a lot of the ASFs available), so I'm going to dig through the reading and see what I come up with.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It looks like you need to keep doing repeated starts until ACK'd (conversion completed)

If that is not supported by ASF, then a wrapper function will be needed to do that.

 

Jim

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
   
 uint8_t     temp8 = 0xF5;
    uint16_t 	temp = 0;
	packet.length = 1;
	packet.addr_length = 0;
	packet.buffer = &temp8;
	
	twi_master_write(TWI0, &packet);
	
	packet.length = 2;
	packet.addr_length = 0;
	packet.buffer = &temp;

	while(twi_master_read(TWI0, &packet) == TWI_RECEIVE_NACK)
	{
		twi_master_read(TWI0, &packet);
	}

I managed to get it working with this code.  Obviously I'll want to revise this and add a timeout so it doesn't get stuck in a forever loop if an ACK never arrives.  It would be nice to be able to use the clock stretching method as it wouldn't require me to effectively poll the slave chip for 7+ms to get readings back, but I'll tackle that later.

 

On a side note, why does my inserted code all show up as green instead of properly color formatted like in the editor?