TWI STOP not being issued (SOLVED)

1 post / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

NOTE: About 3/4 of the way writing up this post, I had my "Eureka!" moment and realized what was wrong with the driver.  Given the amount of time I have spent debugging this, it irritates me that I don't figure it out until I am trying to clearly explain it to the forum while asking for help!  Again, I decided to go ahead an post it in case other folks are having similar problems.  The VERY short answer is line 33 below SHOULD be line 37.5...

 

Gents,

 

I'm working on getting a atxmega32E5 talking to a TLC59116 16 channel LED driver.  And for the life of me, I can't get it to send a STOP condition!

 

The driver I am using is based on this driver: https://embededtutorials.wordpre... I wanted base it on a known working driver as I haven't worked with a interrupt driven driver before.

 

The TWI write code is:

 

As you can see, it is sitting on a break point immediately after "TWIC.MASTER.CTRLC = TWI_MASTER_CMD1_bm | TWI_MASTER_CMD0_bm" which SHOULD have written bits 1:0 to 1, which per the datasheet should have had it issue a stop command.  But looking at the TWIC register at this break point:

 

It LOOKS like the status register was set to bit0 = 1, which would be a start condition instead of a stop condition.  And the driver just keeps going.  I can see it send the next two elements of the struct (using a logic analyzer and then keeps on going:

 

The address is correct, the next byte sent is the control register (also correct) and then it sends the 16 individual channel current levels.  But it just won't stop.  It should have stopped after sending the 16 current levels and it DOES drop into the "TWIC.MASTER.CTRLC = TWI_MASTER_CMD1_bm | TWI_MASTER_CMD0_bm" section when number of bytes hits zero.

 

But the STOP condition is never sent and it keeps on sending data forever (I just checked and it is STILL sending data...)

 

At this point, I am assuming I must be doing something fundamentally stupid (not the first time...).  Or my xmega has a hardware issue preventing it from issuing a STOP condition. (I assume not, but...)

 

...

 

...

 

...

 

I LOVE this forum!  I've been looking at and playing with this for several hours over the last few days (this is a hobby for me) and couldn't figure it out.  While typing this up (AGAIN!) I had one of those "Hummm...  I wonder..." moments.  The original write interrupt handler code looked like this:

	// If TWI write interrupt flag is set
	if (TWIC.MASTER.STATUS & TWI_MASTER_WIF_bm)
	{
		if (!(TWIC.MASTER.STATUS & TWI_MASTER_RXACK_bm))	// Check if acknowledgment has been received
		{
			TWIC.MASTER.DATA = TWI_transaction.data_buffer[TWI_transaction.data_index++];
			
			if (TWI_transaction.no_of_bytes)
			{
				TWI_transaction.no_of_bytes--;
			}
			else
			{
				TWIC.MASTER.CTRLC = TWI_MASTER_CMD1_bm|TWI_MASTER_CMD0_bm;
				TWI_transaction.transfer_complete = true;
			}
		}
	}

The problem is I am loading the next byte

TWIC.MASTER.DATA = TWI_transaction.data_buffer[TWI_transaction.data_index++];

THEN I am checking to see if I am at the end and trying to set the STOP condition if I am.  But it can't set STOP while it is sending data, so it never realizes it should stop and it keeps going and going and going...

 

I moved the send next byte inside the test to see if we send everything and it is working perfectly now.

	// If TWI write interrupt flag is set
	if (TWIC.MASTER.STATUS & TWI_MASTER_WIF_bm)
	{
		if (!(TWIC.MASTER.STATUS & TWI_MASTER_RXACK_bm))	// Check if acknowledgment has been received
		{
			if (TWI_transaction.no_of_bytes)
			{
				TWI_transaction.no_of_bytes--;
				TWIC.MASTER.DATA = TWI_transaction.data_buffer[TWI_transaction.data_index++];
			}
			else
			{
				TWIC.MASTER.CTRLC = TWI_MASTER_CMD1_bm|TWI_MASTER_CMD0_bm;
				TWI_transaction.transfer_complete = true;
			}
		}
	}

 

I can't believe it took me this long to figure out.  And FYI, I went back to the site with the code I was using and their WIF handler is sending the next byte BEFORE it checks for end of data, just like I was.  I have no idea how theirs is working.

 

 

Clint