Quantcast
Channel: MSP low-power microcontroller forum - Recent Threads
Viewing all articles
Browse latest Browse all 22202

MSP430F5438A: I2C USCI30 Errata workaround

$
0
0
Part Number: MSP430F5438A

Hi, I have observed that my I2C bus is hanging on the 7th bit of the second byte

I saw the USCI30 errata so I tried to implement the workaround

  case  8u:                              // Vector  8: STPIFG
      if (UCB1IFG & UCRXIFG)
      {
          if ((ucb1_i2c.rx_curr_len < ucb1_i2c.slave_rx->dat_len) &&
                  (ucb1_i2c.slave_rx != NULL))
          {
              *ucb1_i2c.slave_rx->data++ = UCB1RXBUF;             // Get RX'd byte into buffer
              ucb1_i2c.rx_curr_len++;
          }
          else
          {
              ucb1_i2c.rx_succeed = 0u;
              uint8_t dummyClear = UCB1RXBUF;
          }
      }
      if (ucb1_i2c.rx_succeed && (NULL != ucb1_i2c.stp_cb))
      {
          (*ucb1_i2c.stp_cb)();
//          vTaskNotifyGiveFromISR(decode_i2c_handler, pdFALSE);
      }
      ucb1_i2c.rx_succeed = 1u;
      ucb1_i2c.rx_curr_len = 0;
      break;
  case 10u:                                  // Vector 10: RXIFG
  {
    if ((UCB1STAT & UCSCLLOW) != 0)
    {
        __delay_cycles(200);
    }
    else
    {
        UCB1IFG |= UCRXIFG;
        break;
    }
    if (ucb1_i2c.rx_mode == SLAVE_RECEIVE)
    {
        if ((ucb1_i2c.rx_curr_len < ucb1_i2c.slave_rx->dat_len)&& (ucb1_i2c.slave_rx != NULL))
        {
            *ucb1_i2c.slave_rx->data++ = UCB1RXBUF;                 // Get RX'd byte into buffer
            ucb1_i2c.rx_curr_len++;
        }
        else
        {
            ucb1_i2c.rx_succeed = 0u;
            uint8_t dummyClear = UCB1RXBUF;
        }
    }

The above is a snippet of my I2C ISR (the STPIFG and the slave receive of the RXIFG portion)

So, from the errata, the workaround is to check that the UCSCLLOW has been set for at least 3 USCI bit clock cycle.

I am working with 12.8MHz SMCLK and 400kHz I2C clock frequency.

So, in my RX ISR handling, I am checking if UCSCLLOW is set, I will delay for 200 cycles.
I think this should be long enough since 200 cycles of 12.8MHz clock is around 15.625us and I only need 7.5us to cover 3 USCI bit clock cycle

If the UCSCLLOW is not set, I will just break and let it reenter the ISR to check again.
For the last byte received, I am expecting the UCSCLLOW to not be set. So, I will wait for the STPIFG to be triggered and read the last byte in there.

After implementing this, I get this image for my SCL line on the oscilloscope

I observed that I am still facing the same issue with I2C hanging occasionally on the 7th bit of the second byte even after implementing this.
May I ask if I am misunderstanding something regarding this errata/workaround and check if my implementation of the workaround is correct?


Viewing all articles
Browse latest Browse all 22202

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>