32U4 TWI and UART ISRs

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

Hello Everyone,

 

I am setting an 32U4 as a UART bridge communicating with a XMEGA128A1U and a TWI slave communicating with another Renesas microprocessor

The issue I am having is when the 32U4 received a byte on UART in the middle of an I2C transmission.

Basically, on the TWI, the ISR ticks 5 times as I am receiving the slaveAddr+W followed by three Bytes of data and stop condition.

to illustrate that, here is a screenshot from the logic analyzer. Channel 0 and 1 are for the I2C lines. Channel 2 is watching the I2C ISR, everytime time I enter the ISR I toggle a PIN for debugging.

The transmission below is successful and the slave us ACKing all bytes.

I2C

 

Sometimes, a UART transmission will happen between two I2C ISRs like in the example below:

I2C

In the second case, the Channel 3 shows some bytes on the UART bus. I also made a pin toggle everytime the UART  ISR executes.

Everytime this happens, the 32U4 puts the I2C data line to ground and never releases it.

What do you think I should do ?

I though about disabling the UART interrupt when an I2C communication starts ( when I receive SlaveAddr +W ) and enables it after the stop condition ?

if I do that is there a risque of dropping UART bytes ? or is there a hardware UART buffer that would keep the data for me.

My UART ISR is really tightm I can't seem to think of a tighter one :

ISR(USART1_RX_vect)
{
	LEDG_S;
	if(Bridge_Mode)
	{
		if(USB_connected)
			dataToStream[data_index++]=UDR1;
	}

	else
	{
		fputc(UDR1,&USBSerialStream);
	}
	LEDG_C;
}

 

 

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

 

Note how in the first trace, the scl shows an up arrow except for the ACK.  In the second

trace, for the last byte, the logic analyzer doesn't show the scl up arrow.  What is the logic

analyzer trying to indicate - that the signals don't conform to I2C? 

 

Also note how in the top trace, the TWI ISR fires at the end of the third byte and then for the

STOP.  For the bottom trace, the TWI ISR does not fire at the end of the third byte, nor the STOP.

 

What prevents the TWI ISR from running?

 

BTW, What is the TWI clock rate and the UART baud rate?

 

 

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

The Saleae analysis shows bus speed is ~140 kHz and 7-bit Slave address is 1.
Both of these are unusual but should not be a problem for TWI hardware.
.
As Chuck99 has shown, there is no IRQ on the 3rd byte. I suggest that you ZIP up your AS7 project.
Preferably the minimal code that displays this behaviour.

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

No range check on datatostream
Fputc might block

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

Hello Chuck,

1. Yes I noticed the fourth and fifth ISRs are missing. the Logic is reporting what is happening on the I2C bus, which is in this case the master generatign both clock and data. the slave is only generating the ACKs or NACK.

I believe that because of the UART ISR ticking in the middle of an I2C incoming byte, the 32U4, slave, did not get all 8 clocks and therefore waiting for the ninth clock cycle to generate the ACK or NACK. The master on the other side, did actually send all 8 clocks and did release the clock for the ninth ( waiting for the slave to ACK or NACK )

 

What is preventing the TWI ISR from running is that it will run when the slaves sees 8 clocks + 1transision up to provide ACK / NACK. The master on the other hand provided all clocks and waits for the slave to Acknowledge.

 

The UART baud is 460800.  The I2C freq is much lower( 140Khz ) I am limited by the bus capacitance due to the physical distance between the master and slave.

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

Hello David,

 

We can set the slave address to anything between 1 and 128, we have one slave on the bus at this time. the choice of 1 was just arbitrary.

The TWI clock is limited by the bus capacitance and by the Renesas.

In the absence of the UART ISR, I can run the I2C transmission thousands of times without a single NACK.

 

I2C

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

Hello Kartman,

 

Thanks for the comments but I do have a range check outside the UART ISR. and have a buffer max size of 128 bytes. I try to limit the number of If statements inside my ISRs.

Fputc is not the problem as I am operating in BridgeMode. fputc will only run when I use the 32U4 as ISP to program the 128A1U through a bootloader. The I2C is not running in ISP mode.

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

Hello Everyone,

 

The I2C and UART will run together most of the time. as long as the UART ISR does not tick in the middle of an I2C transmission

here is a screenshot where up[ the last I2C transmission, everything works fine.

I2C

 

Strange enough, I found cases where both ISRs run simultaneously without issues:

 

Normal transmission:

I2C

Failed Transmission

I2C

 

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

There is something seriously wrong with a 140kHz bus being limited by bus capacitance. The I2C bus can have up to 400pF. Obviously you have to use sensible pullups e.g. 820R to 4k7 for a 3.3V chip. For 4k7 and 400pF RC = 1.9us.
Typical device capacitances are 20pF e.g. 20 devices on the same bus.
Many devices are considerably less than 20pF.
.
You could specify input and output. Post your bridge project. There is no need to publish any top secret Renesas code.
You can and should write a suitable test suite.
.
David.

Last Edited: Wed. Nov 15, 2017 - 01:26 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

maminej wrote:
I am limited by the bus capacitance due to the physical distance between the master and slave.

So what distance is that, then?

 

Note that I2C is not designed for long distances!

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

That's a very good point. The I2C link is between two boards, the length is around 30 cm including PCB traces and the wires.

We tried 250Khz with 4.7K pullups and the transmission started to fail. you can see the clock raising edge getting slower.

I have a TXS0104 buffer on the I2C line and the 4.7K on the 5V side. should I pull up both sides with a lower resistance , 2.2K?

 

buffer

Last Edited: Wed. Nov 15, 2017 - 03:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would just run the 32U4 at 3.3V.   No need for any level shifting.

 

How good are the TXS0104 chips in practice?

I have some somewhere.   I will try them on an SPI bus.

 

I2C bus should work with the pullups to 3.3V.   Even if you have 5V GPIO on one side.   After all, the I2C bus is open-drain not push-pull.

 

It is a complete mystery why any manufacturer would market MCUs with a "faster speed at 5V".

Nothing wrong with rating ALL chips at 3.3V and making the inputs 5V tolerant.

 

300mm lines on an I2C bus are not unreasonable.   You are still looking at 10s of pF and not 100s.

 

David.

Last Edited: Wed. Nov 15, 2017 - 04:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I made a change to my board and added a wire connecting the 32U4 to the 128A1U that are communicating with USART.

I pull this wire low to indicate an I2C SADR+W and therefore request the 128A1U to wait until the I2C stop condition is achieved, then I pull this flag back up again. I basically interrupt the UART sender when an I2C is happening.

below is the trace with the new wire :

UART

 

The problem is that the issue of dropping bits on the I2C is still happenening with this new flag

Below is a case where the I2C fails in the absence of UART :

 

UART

 

The I2C transmission fails even in the absence of the UART. Also, the first byte of data is wrong .. The master is supposed to send a 0x01 as first byte, instead I am reading 0x03 on the saleae...

 

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

What does it look like on an oscilloscope; ie, in the analogue domain ?

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

maminej wrote:
The I2C link is between two boards

again, not what it's designed for.

 

Are you sure you have a good, solid ground between the two ... ?

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

Here is a scope trace of the lines when I2C transmission is working fine. I changed the master freq to 97.7Khz .

I can't trigger on a case where the I2C fail as it happens kind of randomly.

 

scope

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

maminej wrote:
I am setting an 32U4 as a UART bridge communicating with a XMEGA128A1U and a TWI slave communicating with another Renesas microprocessor

I'm still unclear after reading the above description what is talking what protocol to who(m)? 

 

Is it:  USB ->M32U4 (UART) -> (UART) Xmega (TWI master) -> Renesas (I2C slave)   or

 

Xmega (UART) -> (UART) M32U4 (TWI master) -> (I2C slave) Renesas  or

 

Xmega (UART) -> (UART) M32U4 (TWI slave) <- (I2C master) Renesas .....   or ????

 

Draw me a picture please

Jim

 

 

 

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

ki0bk wrote:
Draw me a picture please

+1000