TWI and *slave* TX arbitration (not master TX)

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

So I'm curious how to handle the "SMBus Alert" protocol using the TWI controller ... has anyone here managed to do that? Thing is, the TWI controller doesn't document any states that involves arbitration during slave transmit. Only during master transmit. Which seems to mean that devices using the TWI controller (unlike ones using USI) can't participate in the SMBus alert protocol...

Summary of the alert protocol: N slaves share an SMBALERT# signal line, open drain. One or more of them raise the alert by pulling that line low. Host/master receives that IRQ and then reads a byte from address 0x0c. There is only one SMBus master, so the master TX doesn't trigger arbitration... However, each slave that's holding SMBALERT# low will respond to address 0x0c. Which in itself can be awkward with a TWI controller, since it assumes slaves will respond to only one address ... some TWI controllers, like the Mega32, don't have a TWAMR (TWI Address Mask) register (unlike the Mega168p), so they physically can't do that! OK, let's assume an optimally friendly case: this device has TWAMR, and its address is 0x0c plus one more bit set. So the IRQ handler can tell if it's responding to 0x0c or to its other address, and there's no "message not for me, discard the data" path to care about.

Then the slave responds to a message at the 0x0c address. If no other slave responds, there's no problem ... the response is its own address (in the seven MSBs) plus one data bit (LSB). Easy. When it's done sending its address, it releases SMBALERT# and the host can tell nobody else is alerting. Host could tell which slave raised the alert, and presumably started some other work to address whatever caused the alert.

But the interesting part is when some other slave is concurrently raising SMBALERT#, the requirement is for those slaves to arbitrate when they send that byte. Only one may succeed, of course; that's the one with the lowest address. It releases SMBALERT#, then the host sees that signal is still held high ... so it talks to address 0x0c again to find what other slave was alerting. (Repeat until done.)

Yet as I noted, the TWI controller doesn't document states for slave arbitration. This "interesting" part looks to be treated as an error. Is this a flaw in the documentation, or design goof for TWI controllers?

(The XMega TWI docs are inconsistent. They say there's support for slave arbitration, but there are no details in the text to support such a claim. And there's no address mask register, so it seems like they can't support the alert protocol at all. With luck, this works properly and the docs are just a bit goofy there.)

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

No, I have not read any documentation.

I understand from you that there are three lines: SCL, SDA and SMBALERT. all open drain.

The slaves will have to arbitrate themselves as to who pulls the SMBALERT line low. The other slaves will know that it was not me guv. And the Master will know that a slave is demanding attention. He asks slave #0x0c, who will identify herself, get serviced and release the ALERT line.

It is of course possible that two slaves, despite polling, pull the line down at the same time. If you have two identical slaves responding to identical hardware conditions each would have to double check the low line. They would choose to do this at the same time.

Edit. If the Master asks for #0x0c and both #0x34 and #0x56 respond, the Master will have to ask a subsequent question. A possible answer would be that each slave responds to the 0x0c+READ address with a unique active low bit mask to identify herself. Each low bit will notify the Master which slaves are addressed.

Surely there must be some official documentation of this protocol, and you just follow this.

David.

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

The XMEGA should support it since it has a slave collision flag in the 'Slave Status Register' which is set if the slave lost arbitration.

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

I bypassed the entire problem (with TWI) when I required the master to poll each device that could generate an interrupt request and read the status. That status would tell me if a service request was needed. Only works with devices where I can control both ends, though.

Harvey

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

david.prentice wrote:
The slaves will have to arbitrate themselves as to who pulls the SMBALERT line low.
But that's equivalent to saying the slaves are not using the SMBALERT protocol!! The arbitration is not supposed to be done at that point ... it's supposed to be done when the slaves respond to the 0x0c request. Which is why $SUBJECT highlights slave TX arbitration.

david.prentice wrote:
If the Master asks for #0x0c and both #0x34 and #0x56 respond, the Master will have to ask a subsequent question. A possible answer would be that each slave responds to the 0x0c+READ address with a unique active low bit mask to identify herself. Each low bit will notify the Master which slaves are addressed.
That's essentially what the slave TX arbitration does. Both slaves transmit their (seven bit) addresses, then a data bit, and arbitration happens while they transmit. The first bit of 0x34 (011.0100) is 0, while the first bit of 0x56 (101.0110) is 1 ... so 0x34 wins that arbitration, completes its transmit, and stops asserting SMBALERT#. The next time the master asks to receive a byte from 0x0c, only the 0x56 slave is still asserting SMBALERT#; so no arbitration needs to be done

david.prentice wrote:
Surely there must be some official documentation of this protocol, and you just follow this.
I had summarized the relevant parts of the SMBus spec; yes, that's official. My question was whether the TWI controller was as crippled as it seems to be ... it doesn't support following that spec. USI can do this. Docs say TWI can't. If that's not a doc bug, that's a compelling reason to avoid AVRs without USI whenever I need to talk SMBus.

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

atomicdog wrote:
The XMEGA should support it since it has a slave collision flag in the 'Slave Status Register' which is set if the slave lost arbitration.
OK, good ... I see that STATUS.COLL flag, so it looks like the issue is mostly just weakness in other parts of that initial doc revision. (A quick scan didn't seem to suggest there's a way to get an IRQ on arbitration loss ...) Or so I'll assume, until I play with an XMEGA! For reference, the relevant description follows.
Quote:
Bit 3 - COLL: Collision
The slave Collision (COLL) flag is set when slave is not been able to transfer a high data bit or a
NACK bit. If a collision is detected, the slave will commence its normal operation, disable data
and acknowledge output, and no low values will be shifted out onto the SDA line. Writing a one
to this bit location will clear the COLL flag.
The flag is also automatically cleared when a START or Repeated START condition is detected.

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

Hi,
Anyone knows if attiny44 only sets the USIDC or it also "disable data and acknowledge output, and no low values will be shifted out onto the SDA line."?
Thanks

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

Pity but it sends anything on SDA causing a wire-AND...