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.)