TWI slave mode hangs in XMEGA32E5

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

Hi all,

 

I have problems using twi slave mode in atxmega32e5.

The have TWI master running in atxmega256a3bu, polling data from slave. The slave can receive data, but when I try to set data to slave.sendData buffer, the program hangs there. It doesn't matter where I try set slave.sendData in the code, it stops running there.

 

If don't touch slave.sendData, the slave responds two zero bytes 0x00 0x00.

 

Using Atmel Studio 7.0 and XMEGAE_DFP 1.0.30 and TWI drivers from AVR1308

 

 

/*! Defining an example slave address. */
#define TWI_SLAVE            TWIC
#define TWI_SLAVE_ADDRESS    0x51
#define TWI_SLAVE_NUM_BYTES  8

/* Global variables */
TWI_Slave_t slave;

ISR(TWIC_TWIS_vect) {
  TWI_SlaveInterruptHandler(&slave);
}

void slave_process()
{

  uint8_t rData = slave.receivedData[slave.bytesReceived];
  printf("slave data [%u] %x [%u]\r\n", slave.bytesReceived, rData, slave.result);
  printf("update slave data\r\n");
  slave.sendData[0] = 0x0f;
  slave.sendData[1] = 0xf0;
  uint8_t data = slave.sendData[0];
}  

void twi_init() {

  // Initialize TWI_SLAVE
  for (uint8_t i = 0; i < TWIS_SEND_BUFFER_SIZE; i++) {
    slave.receivedData[i] = 0;
  }

  sysclk_enable_peripheral_clock(&TWI_SLAVE);
  TWI_SlaveInitializeDriver(&slave, &TWI_SLAVE, *slave_process);
  TWI_SlaveInitializeModule(&slave, TWI_SLAVE_ADDRESS, TWI_SLAVE_INTLVL_HI_gc);

  ioport_set_pin_dir(READY_PIN, IOPORT_DIR_OUTPUT);
  ioport_set_pin_low(READY_PIN);
}

Does anyone have similar problems? 

 

This topic has a solution.
Last Edited: Fri. May 21, 2021 - 12:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

well, the problem is in line 25 of your senddata routine. Sorry that is all my Chrystal ball is giving as possible error code at the moment.

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

sydis wrote:
it stops running

programs don't just "stop running" - it must be doing something.

 

Have you used the debugger to find what, exactly, it is doing? And where?

 

Have you used an oscilloscope or logic analyser to see what's happening on the wires?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sydis wrote:

/* Global variables */
TWI_Slave_t slave;

For starters, that will need to be 'volatile'

 

Addendum:

 

https://www.avrfreaks.net/forum/tutcoptimization-and-importance-volatile-gcc

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Thu. May 20, 2021 - 09:00 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


I dig it a bit deeper, it seems that slave does not make STOP condition.

 

 

In made a breakpoint to TWI_SlaveInterruptHandler and observed that TWI slave status is TWI_SLAVE_COLL_bm. 

 

 

 

TWI master code

uint8_t readbuffer[2]={0};
uint8_t s = 0;
twi_package_t packet;

packet.chip = 0x51;
packet.buffer = &readbuffer;
packet.length = 2;
packet.addr_length = 0;
packet.addr[0] = 0x00;
packet.no_wait = false;

while (1 ) {
    dbg_printf("\r\nPoll for noisedata...");
    status_code_t status = twi_master_read(&TWI_MASTER, &packet);
    if ( status == TWI_SUCCESS ) {
      dbg_printf("%u %u\r\n", readbuffer[0], readbuffer[1]);
    } else {
      dbg_printf("poll failed %x\r\n", status );
    }
    os_timer_delay_ms(1000);
    hal_wdt_reset();     
  }

 

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

it looks like your pullups might be a bit weak?

 

sydis wrote:
observed that TWI slave status is TWI_SLAVE_COLL_bm. 

so did you look up what that means?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah, I am only using internal pullups in both xmegas.

TWI_SLAVE_COLL_bm = Collision. This flag is set when a slave has not been able to transfer a high data bit or a NACK bit.

 

So could it be because of weak pullups? 

 

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

 

highly unlikely that internal pullups are sufficient.

 

See https://www.avrfreaks.net/commen... and the following posts on I2C pullups.

 

Also, the datasheet tells you what value you need - depending on the bus speed:

 

 

 

sydis wrote:
could it be because of weak pullups? 

Why even think about it? Just put the proper values in!

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Thu. May 20, 2021 - 10:47 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sydis wrote:
Yeah, I am only using internal pullups in both xmegas.

 

You should ALWAYS use external pullups.

 

I am fairly gobsmacked that the Saleae decoded it at all.

I am guessing that the bus is in Fast mode (400kHz).

 

Report back when you have added the external pullups e.g. 2k7

 

I might try the Master and Slave code on a real 32E5

 

David.

 

p.s. I note that you have the newer Saleae.   I only have the original Logic-8 (8-channel 24MHz)

I seldom look at Analog signals.    Only when the hardware is unusual.    I never suspected that a grey haired member would omit pullups !!

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


Hi again,

 

 

I found that I have 4.7k pullups on board. Then I have also internal pull-ups enabled.

Previous test was with 500kHz TWI clock. Now changed clock to run 100kHz.

 

 

Everytime I put something else than 0 to slave DATA register,  I get status TWI_SLAVE_COLL_bm. 

 

 

 

 

 

 

 

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

sydis wrote:
 it seems that slave does not make STOP condition.

It's not the slave that sends stop, but the master!

 

Your LA traces seem odd to me, the clock and data lines should idle high, due to the pull ups, but your traces above show them low.

This would indicate to me the TWI lines are being driven with totem pole drivers, rather then open collector drivers, so it looks like those pins are misconfigured.

Sorry I don't have any experience with xmega to guide you on how to fix that.

 

Jim

 

 

 

Keys to wealth:

Invest for cash flow, not capital gains!

Wealth is attracted, not chased! 

Income is proportional to how many you serve!

 

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

ki0bk wrote:

Your LA traces seem odd to me, the clock and data lines should idle high, due to the pull ups, but your traces above show them low.

This would indicate to me the TWI lines are being driven with totem pole drivers, rather then open collector drivers, so it looks like those pins are misconfigured.

 

I tried to set PINCTRL register on both xmegas like this

  PORTC.PIN0CTRL = PORT_OPC_WIREDAND_gc;
  PORTC.PIN1CTRL = PORT_OPC_WIREDAND_gc;

But no luck...still same kind of LA traces

 

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


In these screenshots MASTER is reading one byte from SLAVE.

 

In the SlaveDataHandler 

void slave_process()
{
  slave.sendData[0] = 0x01;  
} 

 

 

 

 

 

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

Just out of curiosity why TWI?  SPI is much faster, or USART?  The latter two being much easier to implement.

 

jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

Your 100kHz trace looks more promising than the previous ones.   However SCL seems to be held low and never released.

 

The Shark Fin rise time seems to be about 2us.   I would be happier with a single clock cycle.   I can only guess from your image.

If you have 4k7 pullups,  RC = 2us implies C = 2us / 4k7 i.e. 425pF which is massive.

 

I2C is easy to drive,  easy to debug,  uses few wires, ...

I2C is relatively slow.

 

However you do have to use appropriate pullup resistors.  And sensible pcb layout etc.   425pF is beyond human comprehension.

 

Of course my eyes might just be crap.

 

David.

Last Edited: Thu. May 20, 2021 - 02:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

In the SlaveDataHandler 

I would forget about trying to 'process' anything until you can get the atmel code to respond correctly to a master read. Fill in the sendData array with something (like values 1-8), then get the master to read a byte. You should have nothing to do in the slave as it will just send the data in the array each time, as many bytes as requested up to the array size.

 

If you are trying to use your 'process' function as the read callback, it will not be called when there is a master read as this function will only be called when there is a data write (master write). It looks like master read = slave write (data callback not used), master write = slave read (data callback used).

 

Your logic analyzer software should be able to do better than translate a 0x51 address to a char 'O' sorry Q, and present the info a little better I would think. You should also be looking at a longer time frame to figure out when sda/scl decide to to go back to idle, if ever. If scl is stuck low, then someone is not doing their job correctly as they are waiting for something (and keeping scl pulled low while waiting).

 

The picture attached is something like you should be seeing. This was with a tiny416 talking to itself from master to slave using this example-

https://github.com/cv007/Avr01Dx...

and slightly modified to read 2 bytes from the 'slave'.

 

Attachment(s): 

Last Edited: Fri. May 21, 2021 - 12:35 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
If you have 4k7 pullups,  RC = 2us implies C = 2us / 4k7 i.e. 425pF which is massive ... beyond human comprehension.

Or maybe they aren't really 4k7 ... ?

 

Perhaps time for some photos of the setup.

 

And schematics.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Thank you all for quick replies and hints smiley and apologies for not providing you all information like schema at first.

 

The problem was that I had not flashed the two other xmega32's which I have connected in the same TWI lines. I didn't check what are default pin conf for unflashed xmega...Once I flashed those, it started working and I had following traces:

 

 

 

 

Last Edited: Fri. May 21, 2021 - 06:34 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am pleased that you have it working.

 

It is incredibly difficult to guess what the SCL rise time is from your Analog traces.   It still looks like 1us - 2us or so.   i.e. implies either that C is 210pF and R is 4k7 or that C is 21pF and R is 47k.

 

Please post a single clock cycle trace or just measure it yourself.  i.e. rise time to 63%

You can measure 50% rise time or 75% rise time if you find it easier.  Just say which measurement you use.

 

Note that any inter-connected electronics needs to be powered.   A hardware chip can only "three-state" when it is actively powered.   e.g. every Slave on an I2C bus.  every Slave on an SPI bus.

 

David.

Last Edited: Fri. May 21, 2021 - 06:58 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Voltage on marker A2 is 2.225V

 

 

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

sydis wrote:
I had not flashed the two other xmega32's which I have connected in the same TWI lines.

As always, best to start simple to get things working - just the master and one slave.

 

If you'd have mentioned that there were other slaves, I'm sure someone would have suggested that...

 

For a bus - any bus - to work properly, it does require that all participants are working correctly.

 

it started working

So time to mark the solution?

 

Or maybe address David's concerns first ...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for posting the single SCL cycle trace.   I am amazed at the accuracy of my guess in #19.   So we really do have an RC time-constant of about 1us !!

 

I suggest that you measure the 4k7 pullup.   Is it really 4k7 ?

 

I have no idea how your pcb traces implement the I2C bus.   Or the official input capacitance of your Saleae model.

It seems unlikely to add up to 200pF.

 

I am guessing that the 32E5 chips service some physical sensors.   Unlikely to be a vast amount of I2C bytes in the traffic.

So Standard 100kHz bus should be fine.   Especially if the Master is using interrupts.

If you address the RC anomaly you could use 400kHz Fast mode.

 

Oh,  if your other 32E5 chips were powered but unprogrammed there would not have been any "load" on the bus compared an operational un-addressed I2C Slave.    i.e. the unprogrammed port pins are Hi-Z with just a few pF input capacitance.

 

David.