This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to conditionally ACK/NAK with eUSCI_B in I2C Slave Receiver mode on FRAM MSP430FR5739 ???

Other Parts Discussed in Thread: MSP430FR5739, MSP430G2231

I have an application in which I need to conditionally ACK or NAK the last received byte on the I2C bus based on the value of that byte.

However, with the eUSCI_B in I2C Slave Receiver mode on the FRAM MSP430FR5739 device, the eUSCI_B automatically ACKs the received byte before indicating it has received the byte to the firmware. I had attempted, in the UCRXIFG0 handler, to test the received value and do a NAK with the UCTXNACK bit, but that NAKed the next received byte - too late!

Is there a way to turn off the automatic ACK of received bytes in the eUSCI_B in I2C Slave Receiver mode similar to turning off the automatic ACK of received addresses with the UCSWACK bit?

I have no problems doing this with the USI in the MSP430G2231 device as the USI allows/requires more low-level control by the firmware, but the eUSCI_B seems have its own way about doing things automatically (which is generally simpler to code than with the USI).

Thanks,

Dan

 

  • The I2C support in the USI is rather a hardware shift register than a real full-featured I2C controller. This allows some things that cannot be done on devices with a higher-level I2C support.

    However, there is a small chance. If you make busy waiting for the RXIFG bit, you should be able to switch the USCI clock to something clockless (= freeze the bus) as soon as the byte arrived. Then you shoul dhave enough time to check the byte and decide whether to manually throw a NACK.

    However, I haven't tested this. I'm not sure whether you may switch the clock source during operation and whether setting UCNACK after RXIFG has been set.

    I's the only idea I have.

    Or the high-level protocol must contain the case that certain operations may result in a nack after the next byte. It's then the job of the master to support this. Since the already master needs to know how your slave works and what to send to it, this added support shouldn't be a problem - unless you want to mimick an existing device.

  • Jens-Michael Gross said:

    However, there is a small chance. If you make busy waiting for the RXIFG bit, you should be able to switch the USCI clock to something clockless (= freeze the bus) as soon as the byte arrived. Then you shoul dhave enough time to check the byte and decide whether to manually throw a NACK.

    I've already tried this - polling for UCRXIFG0 bit in the UCB0IFG register to be set still results in the ACK being sent before the UCRXIFG0 indication occurs.

    I'm attempting to replace an existing USI-based I2C device with the MSP430FR5739 eUCSI_B-based I2C device without changing the master side.

     

  • you should be able to switch the USCI clock to something clockless

    My fault, in I2C slave mode, the clock comes from the master. Forget this. You'll need to take control over the port pins.

    According to the timing diagram, you'll get the STTIFG when your slave address is received, this is the rising edge of the clock signal after the last bit was set, or the next falling edge. Now the USCI will automatically output the ACK, but this isn't valid until the next rising edge. There's still some time to check whether this is a sender or receiver request (by checking UCTR) and simply switch the port pins back to GPIO mode and set th edat aline low. If you do this before the next rising edge, the master will see the NACK.

    The eUSCI also has an option for this:by setting UCSWACK the clock is stretched if you are addressed by the master, until you set the UCTXACK bit. Unfortunately, it doesn't work for data bytes too (this would disable the double-buffering, but well, if you need it...).

    If you decide to receive, you will see RXIFG being set egain after the last bit is received but before the ACK (which is automatically issued)  is accepted by the master. Then again it is still time to get control over the port bit and either hold the clock line low for getting additional time, or the data line to emit a NACK. If you want to continue transfer, switch the clock line back to module use (which releases the clock line).

    Example (symbolic notation):

    PxDIR.CLK=1;
    PxOUT.CLK=0;
    PxDIR.DATA=0;
    ...
    while (!RXIFG);
    PxSEL.CLK=0;
    read and check RXBUF
    If(continue)
      PxSEL.CLK=1;
    else
      PxSEL.DATA=0; PxSEL.CLK=1; reset USCI; PxSEL.DATA=1;

     

     

**Attention** This is a public forum