A simple twi slave in avr_gcc

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

The code that follows for a simple twi slave is taken from a previous
post in this forum.

I have added a variable called debug to read out the result.


#include 
#include 



volatile unsigned char receiver[12];
volatile unsigned char transmitter[12];
volatile unsigned char cmd_Index;
volatile unsigned char debug;



ISR (TWI_vect)
{
  unsigned char I2C_control = 0;

  I2C_control = TWSR & 0xf8; // Mask prescaler bits.
  switch (I2C_control)
    {
    case TW_SR_SLA_ACK: // Slave address with receive.
    case TW_SR_ARB_LOST_SLA_ACK:
      debug |= 0x40;
      cmd_Index = 1;
      break;
    case TW_SR_DATA_ACK: // Data received.
      debug |= 0x20;
      receiver[cmd_Index] = TWDR;
      cmd_Index++;
      break;
    case TW_SR_DATA_NACK:
      debug |= 0x10;
      break;
    case TW_SR_STOP: // Stop or repeated start received.
    case TW_ST_SLA_ACK: // Slave address plus transmit received.
    case TW_ST_ARB_LOST_SLA_ACK:
      debug |= 0x08;
      cmd_Index = 1;
      TWDR = transmitter[cmd_Index];
      break;
    case TW_ST_DATA_ACK:
      debug |= 0x04;
      cmd_Index++;
      TWDR = transmitter[cmd_Index];
      break;
    case TW_ST_DATA_NACK:
      debug |= 0x02;
      break;
    case TW_ST_LAST_DATA:
      debug |= 0x01;
      break;
    case TW_NO_INFO:
      PORTB |= _BV(PB6);  //Set red LED.
      break;
    case TW_BUS_ERROR:
      PORTB |= _BV(PB6);  //Set red LED.
      TWCR = _BV(TWINT) | _BV(TWSTO);
      break;
    default:
      PORTB |= _BV(PB6);  //Set red LED.
      break;


    }

  TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE);


}

The result of debug is 0x6e.
Which means I do not get slave receiver SR_DATA_NACK or slave transmitter ST_LAST_DATA.
Should I have got them ?
The code does work but is not exactly robust code.
Given the slightest disturbance it fails.
How can I improve it ?
How can I tell from the slave side if there is a problem with my master code?
I used twitest.c which comes with avrlibc as a starting point for my master code.

John

If all else fails, read the instructions.

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

When your AVR is the Slave Receiver, it is up to you when you set the acknowledge bit high or low, so that the next received byte gets acked or nacked by the TWI hardware. If you never set the bit low, then you never send nack, so you never get any SR_DATA_NACK status.

When your AVR is the Slave Transmitter, and AVR is transmitting bytesm the master either sends your AVR ACK if it wants more data or NACK if does not want any more data. So again it is up to the AVR software to set the ACK bit accordingly in control register to know if you know it is the last data before it is transmitted, the TWI hardware just compares if master sends NAK and also AVR knows this byte should be the last.

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

hi,
can tell anyone how to get nack when I using TWI in slave mode.

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

Quote:

can tell anyone how to get nack when I using TWI in slave mode.

What does it say immediately above your post?
Quote:

the master either sends your AVR ACK if it wants more data or NACK if does not want any more data.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Nice to see this old one of mine pop up.
Many thanks Jepael.
What happend after this was that I went back to using hardware slaves for any production purpose.
I have still this idea of using software slaves.
Something I am still working on.
If I could get software to work as reliably as hardware I could use about four times as many AVR as I use now.
The snag with the hardware slaves is that you must find exactly what you want. I have never found anything as simple as a pulse counter for instance but this is simple to implement with an AVR and software.

John

If all else fails, read the instructions.

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

Here's the old dissapeared AVR appnotes 300/302 (courtecy JS)

Assembler but might give an idea.

But even a "tiny" has USI/TWI , so i can't see the need.

/Bingo

Attachment(s):