0
\$\begingroup\$

To brush up on my skills, I am using I2C it with these devices on the same I2C bus:

  • master: ESP2866, micropython built-int libraries
  • slave: MSP430G2231 slave, C routines using USI, developed from MSP430Ware examples
  • slave: STM32F100RB, Arduino routines (platform.io toolchain)
  • slave: oled display, type SSD1306

Note: I have to rewrite most of the MSP430 code, because the examples are terrible. Example: when MSP430 receives an address other than its own... it replies with a NACK. This is incorrect, it should not respond.

Scenario:

  • When the master sends a 4 bytes command to the STM32, the STM32 replies with 4 ACKs.
  • When the ESP sends a 4 bytes command to the MSP430, the MSP430 replies with 3 ACKs.

This is clear looking at the MSP430Ware examples, here polished and commented:

case I2C_state_read_rx :
    flag = I2C_rx(USISRL);

    USICTL0 |= USIOE;   // SDA = output

    if (flag == _I2C_rx_has_space)
    {
        _send_ACK();
        I2C_State = I2C_state_start_rx;
    }
    else    // last byte
    {
        _send_NACK();
        I2C_State = I2C_state_idle;
    }
    break;

The Master communicates smoothly with the three slaves. Taking into account the two cases, this is an excerpt from my ESP code:

    // writeto retuns the number of ACKs from the slave
    i = I2C.writeto(... slave address ..., cmd)
    if i != len(cmd) - 1 and i != len(cmd) :
        raise RuntimeError("I2C: writeto error: ack = ", i)

Searching the web, I found the electrical specs of I2C, but no clarification on this issue.

I don't understand if the MSP430 behaviour is wrong or there is a bug in the arduino STM32 library. It could be, because most of the time STM32 is used as master, not slave: maybe I am hitting a corner case.

Questions:

  1. When a slave receives an N bytes command, should it reply to the master with N-1 or N ACKs ?
  2. Are there any official specs on proper slaves behaviour?

P.S.: sorry for the use of Master / Slave, I don't think it is offensive in this context.


ADDENDUM

I found this Texas Instruments application note: SLVA704 - Understanding the I2C bus

Reading paragraphs 3.3: the Master wants to read a register from the Slave:

Looking at the figure 9 I understand this:

  • The master sends the I2c address (the slave ACK it) and the register address (the slave ACK it)
  • To read the reply, the master restart the communication: it sends the I2C address (slave ACK it) and the slave send one byte without ACK/NACK

Once the master has received the number of bytes it is expecting, it will send a NACK, signaling to the slave to halt communications and release the bus.

This is the case when reading a one-byte register.

Is it possible for the slave to respond with many bytes? Should it send ACK / NACK ? after each byte?

\$\endgroup\$
4
  • 1
    \$\begingroup\$ when MSP430 receives an address other than its own... it replies with a NACK. This is incorrect, it should not respond. I haven't looked at the library code, so I might be missing the point. But on the physical layer, not responding and 'sending a NACK' is essentially the same. A NACK bit is a recessive state (HiZ) and an ACK is dominant (active LOW). \$\endgroup\$
    – Velvet
    Commented Apr 28, 2023 at 13:55
  • \$\begingroup\$ OP, @Velvel is spot on. 'Sending a NACK' is actually 'signalling a NACK': just putting the SDA bus drive to hi-Z and waiting for at least a bit period. Nothing is sent. \$\endgroup\$
    – TonyM
    Commented Apr 28, 2023 at 14:02
  • \$\begingroup\$ Please read the ADDENDUM, with the app note. \$\endgroup\$
    – Massimo
    Commented Apr 28, 2023 at 14:05
  • \$\begingroup\$ @TonyM Do you mean: for the slave sending the last NACK is useless? \$\endgroup\$
    – Massimo
    Commented Apr 28, 2023 at 14:09

2 Answers 2

2
\$\begingroup\$

I think you have some confusion on how the ACK bit is used. In I2C, the ACK bit always generated by the device that just received that byte.

The ACK bit has two functions:

  • A target device indicating recognition of an address from a master
  • A device indicating it has received a byte and what it wants to do next

When the I2C master transmits the address/RW byte, a recognising target device generates the ACK bit. This informs the master that a target is ready for communications.

When the I2C master transmits a data byte, the target device generates the ACK bit. This is an ACK if it can receive another byte, no ACK if the message will end.

When the I2C master receives a data byte, the master generates the ACK bit. This is an ACK if it will be reading another byte, no ACK if the message will end.

\$\endgroup\$
2
\$\begingroup\$

The master can try send any amount of bytes it wants.

The slave must ACK received bytes, either all or until it can't receive any more, so the master needs to stop sending if it receives a NAK.

So it seems the problem is not on STM32.

  1. Yes in general if you send N bytes to a generic slave it should be able to ACK all N bytes.

  2. The official I2C specification by NXP has the details how the devices should work.

  3. Slave can respond with any amount of bytes the master wants to read until the master does not want to read more.

Also, if the address does not match, the hardware I2C peripheral should stop listening the bus because address did not match. But some I2C peripherals are simple or of the reception is made in software, it may be required to send out a bit based on the address byte, and sending out a NAK is same as not sending anything due to the bus being driven with open-collector/open-drain IO stages.

\$\endgroup\$
4
  • \$\begingroup\$ Please read the ADDENDUM and give me a link to the NXP docs. Thanks. \$\endgroup\$
    – Massimo
    Commented Apr 28, 2023 at 14:06
  • \$\begingroup\$ You changed the question to have even more different scenarios to answer? Well, that's easy, it's not the slave that sends ACK/NAK if the slave is transmitting data. Also you can likely google for I2C specification faster yourself, than having me to google that and post the link here for you to read. \$\endgroup\$
    – Justme
    Commented Apr 28, 2023 at 14:14
  • \$\begingroup\$ I dont' change the question, they are details. BTW, are you sure that doc answers my questions? Sorry, I google and found too many docs, so without a linkk I cannot upvote your incomplete answer. \$\endgroup\$
    – Massimo
    Commented Apr 28, 2023 at 14:19
  • 1
    \$\begingroup\$ Since NXP has removed a direct download of the specification and requiring to create an account for downloading it, I am forced to provide an alternative source : pololu.com/file/0J435/UM10204.pdf \$\endgroup\$
    – Justme
    Commented Apr 28, 2023 at 14:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.