B@tto

FR5969 and i2c issue

15 posts in this topic

Hello everyone,

 

I have trouble with i2c on FR5969 launchpad.

 

I wanted to interface a BMP180. As it didn't work, I tested my module on my TivaC launchpad and Arduino and it was OK. So I connected my oscilloscope and my logic analyzer on pin P1.6 and P1.7 and there was strictly no activity ...

 

Searching on the internet I couldn't find any person using i2c on this launchpad, so has anyone tried to play with i2c on it ?

 

Problem detected on Energia v15, v14 doesn't work too. I looked at pins_energia.h, it seems ok ...

Share this post


Link to post
Share on other sites

First I tried BMP085 lib in library section. After I tried adafruit bmp085, and the example sketch wored well on all platform except FR5969. So after UART debuging, I found that the problem comes from simple call to Wire functions. So I tried something like this (hex values are random, I have not my original code in front of me):

Wire.begin();
Wire.beginTransmission(0x77);
Wire.write(0x45);
Wire.endTransmission();

And I discovered the

Share this post


Link to post
Share on other sites

I have an Adafruit I2C RTC that I will try with the FR5969.  I thought I had used it successfully in the past but when I pulled it up again this evening I didn't get it going right off the bat.  Will try again and let you know if I am successful.

 

UPDATE

=======

I couldn't get the RTC to work when I tried again today - I do a Wire.begin() and then it calls a library where it freezes.

 

I then tried with a LCD that has an I2C backpack.  I got it running on the F5529 and moved it to the FR5969.  It doesn't freeze completely but gives garbage on the LCD that changes from time to time.  I checked the wiring and it seems correct. 

 

So I am unsuccessful getting I2C to work on the FR5969 as well.  I am using Energia E0015.

B@tto likes this

Share this post


Link to post
Share on other sites

I investigated a little bit more, playing with Energia in CCS, so with debug. The micro stay exactly stuck here :

 

line 446 of twi.c , twi_writeTo() function:

/* Wait for the transaction to complete */
while(twi_state != TWI_IDLE) {
__bis_SR_register(LPM0_bits);
}

I placed breakpoints in interrupt routines : simply nothing happens. As it's the part in twi.c where i2c start condition is called, I had interrupt enabled on start (UCSSTTIE) ==> still no interrupt.

 

To resume : twi_state value is managed by ISR, but no ISR seem to happen, so twi_state is never set to TWI_IDLE, so the while() condition is never good and we stay here.

 

Note : during this part, twi_state value is 0x02

Fmilburn likes this

Share this post


Link to post
Share on other sites

Probably, but could also be a race condition. What if the interrupt happens between the test and going into sleep mode?

That would be quite problematic since that logic is depended upon for all the other MSP430 I2C implementations as well in Energia.  I'm still doubtful but it's always worth a check...

Share this post


Link to post
Share on other sites

Hmm, looking at twi.c for Energia 15...

    case USCI_I2C_UCTXIFG0:    // USCI I2C Mode: UCTXIFG0
                UCB0IFG &= ~UCTXIFG;                  // Clear USCI_B0 TX int flag
                if (twi_state == TWI_MTX) {      // Master receive mode
                        // if there is data to send, send it, otherwise stop 
                        if(twi_masterBufferIndex < twi_masterBufferLength){
                                // copy data to output register and ack
                                UCB0TXBUF = twi_masterBuffer[twi_masterBufferIndex++];                 // Transmit data at address PTxData
                        }else{
                           if (twi_sendStop)
                                UCB0CTLW0 |= UCTXSTP;                // Generate I2C stop condition
                           else {
                                 twi_inRepStart = true;   // we're gonna send the START
                                 // don't enable the interrupt. We'll generate the start, but we 
                                 // avoid handling the interrupt until we're in the next transaction,
                                 // at the point where we would normally issue the start.
                                 UCB0CTLW0 |= UCTXSTT;        
                                 twi_state = TWI_IDLE;
                           }
                        }
                } else {
                        // copy data to output register
                        UCB0TXBUF = twi_txBuffer[twi_txBufferIndex++];
                        // if there is more to send, ack, otherwise nack
                        if(twi_txBufferIndex < twi_txBufferLength){
                        }else{
                                UCB0CTLW0 |= UCTXNACK;                // Generate NACK condition
                        }
                }
      break;

I think there's supposed to be a "twi_state = TWI_IDLE" after that "UCB0CTLW0 |= UCTXSTP;     // Generate I2C stop condition" line just like there is in the section below it.  That does happen for the USCI implementation (F5529/G2553 et al).  Also those perform a __bic_SR_register_on_exit(LPM0_bits) after setting twi_state too.

Share this post


Link to post
Share on other sites

I think the problem is not here, as absolutely no interrupt are triggered. Using debugger, I placed a breakpoint at the beginning of the interrupt routine, and it never triggered ! So the question is not what does not work in isr, but why it's never triggered ? It could empty that for now it wont change anaything ...

 

 

I saw another potential errors : 

- interrupt flag register does not have to be clear before setting up interrupts ? => twi_init()

 

From family guide :

 

All interrupt flags are not cleared automatically, but they need to be cleared together by user interactions
(for example, reading the UCRXBUF clears UCRXIFGx). If the user wants to use an interrupt flag he
needs to ensure that the flag has the correct state before the corresponding interrupt is enabled.
 

 

UCSWRST is set two times in twi_init :


//Disable the USCI module and clears the other bits of control register
UCB0CTLW0 = UCSWRST;


//Configure Automatic STOP condition generation
UCB0CTLW1 &= ~UCASTP_3;
//UCB0CTLW1 |= autoSTOPGeneration;


//Byte Count Threshold
//UCB0TBCNT = byteCounterThreshold;
/*
* Configure as I2C master mode.
* UCMST = Master mode
* UCMODE_3 = I2C mode
* UCSYNC = Synchronous mode
* UCCLK = SMCLK
*/
UCB0CTLW0 = UCMODE_3 | UCSSEL__SMCLK | UCSYNC | UCSWRST;

But I don't think it has any effect ...

 

 

- this is a routine proposed in msp430fr family user guide :

 

UCBxCTL1 |= UCSWRST; // put eUSCI_B in reset state
UCBxCTLW0 |= UCMODE_3 + UCMST; // I2C master mode
UCBxBRW = 0x0008; // baudrate = SMCLK / 8
UCBxCTLW1 = UCASTP_2; // autom. STOP assertion
UCBxTBCNT = 0x07; // TX 7 bytes of data
UCBxI2CSA = 0x0012; // address slave is 12hex
P2SEL |= 0x03; // configure I2C pins (device specific)
UCBxCTL1 &= ^UCSWRST; // eUSCI_B in operational state
UCBxIE |= UCTXIE; // enable TX-interrupt
GIE; // general interrupt enable
...
// inside the eUSCI_B TX interrupt service routine
UCBxTXBUF = 0x77; // fill TX buffer

Share this post


Link to post
Share on other sites

Oh..... that might do it. I'll remember to bring my wolverine LP and an I2C dev today to verify.

 

Sent from my Galaxy Note II using Tapatalk

Share this post


Link to post
Share on other sites

Have someone investigate more about this issue ? 

 

I continued with Energia in CCS, and I tested a lot of things, without any success. I also found, I think, errors but correcting them did not do any change for i2c.

 

With debugger I checked registers : everything seems ok, the status eUSCI register shows a busy status and it never changes. 

 

I tried native code supplied by TI in my previous post => no reaction. 

 

All this problem is very strange, it's like no clock is supplied to eUSCI => maybe a problem about clocks ?

 

EDIT : I got it !!! I have no explanation for now, but the problem is initiating START manipulating UCB0CTLW0 register. If you do :

 

UCB0CTLW0 |= UCTXSTT; 

 

It will not work, with :

 

UCB0CTL1 |= UCTXSTT; 

 

I got interruption. 

 

Normally it would be the same, but I don't know why, it's not. To discover that, I simply used an example code provide by TI in Ressource Explorer :

 


//******************************************************************************
//  MSP430FR59xx Demo - eUSCI_B0 I2C Master RX multiple bytes from MSP430 Slave
//
//  Description: This demo connects two MSP430's via the I2C bus. The master
//  reads 5 bytes from the slave. This is the MASTER CODE. The data from the slave
//  transmitter begins at 0 and increments with each transfer.
//  The USCI_B0 RX interrupt is used to know when new data has been received.
//  ACLK = n/a, MCLK = SMCLK = BRCLK =  DCO = 1MHz
//
//    *****used with "MSP430FR59xx_euscib0_i2c_11.c"****
//
//                                /|\  /|\
//               MSP430FR5969      10k  10k     MSP430F5969
//                   slave         |    |        master
//             -----------------   |    |   -----------------
//           -|XIN  P1.6/UCB0SDA|<-|----+->|P1.6/UCB0SDA  XIN|-
//            |                 |  |       |                 | 32kHz
//           -|XOUT             |  |       |             XOUT|-
//            |     P1.7/UCB0SCL|<-+------>|P1.7/UCB0SCL     |
//            |                 |          |             P1.0|--> LED
//
//   P. Thanigai
//   Texas Instruments Inc.
//   Feb 2012
//   Built with CCS V5.5
//******************************************************************************
#include <msp430.h>


volatile unsigned char RXData;


int main(void)
{
  WDTCTL = WDTPW | WDTHOLD;


  // Configure GPIO
  P1OUT &= ~BIT0;                           // Clear P1.0 output latch
  P1DIR |= BIT0;                            // For LED
  P1SEL1 |= BIT6 | BIT7;                    // I2C pins


  // Disable the GPIO power-on default high-impedance mode to activate
  // previously configured port settings
  PM5CTL0 &= ~LOCKLPM5;


  // Configure USCI_B0 for I2C mode
  UCB0CTLW0 |= UCSWRST;                     // Software reset enabled
  UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC;   // I2C mode, Master mode, sync
  UCB0CTLW1 |= UCASTP_2;                    // Automatic stop generated
                                            // after UCB0TBCNT is reached
  UCB0BRW = 0x0008;                         // baudrate = SMCLK / 8
  UCB0TBCNT = 0x0005;                       // number of bytes to be received
  UCB0I2CSA = 0x0077;                       // Slave address
  UCB0CTL1 &= ~UCSWRST;
  UCB0IE |= UCRXIE | UCNACKIE | UCBCNTIE;


  while (1)
  {
    __delay_cycles(2000);
    while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent
    UCB0CTL1 |= UCTXSTT;                    // I2C start condition


    __bis_SR_register(LPM0_bits | GIE);     // Enter LPM0 w/ interrupt
  }
}


#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  switch(UCB0IV)
  {
    case USCI_NONE:          break;         // Vector 0: No interrupts
    case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
    case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
      UCB0CTL1 |= UCTXSTT;                  // I2C start condition
      break;
    case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
    case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
    case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
    case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
    case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
    case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
    case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
    case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
    case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
      RXData = UCB0RXBUF;                   // Get RX data
      __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
      break;
    case USCI_I2C_UCTXIFG0:  break;         // Vector 24: TXIFG0
    case USCI_I2C_UCBCNTIFG:                // Vector 26: BCNTIFG
      P1OUT ^= BIT0;                        // Toggle LED on P1.0
      break;
    case USCI_I2C_UCCLTOIFG: break;         // Vector 28: clock low timeout
    case USCI_I2C_UCBIT9IFG: break;         // Vector 30: 9th bit
    default: break;
  }
}
 
Fmilburn likes this

Share this post


Link to post
Share on other sites

Working on this problem + Energia in CCS full of bugs is a pain in the ass ... And I had another problem : inspired by the previous example code, I was trying to adapt it to twi.c. In the end, it was just like a cut/paste in it and it was still not working. So I tried to re-up example code, and ... it did not work :o I deconnected my launchpad, reconnected it and ... It worked :o :o I just wanted to play frisbee with it ...

 

I also found another errors in twi.c, like this line (301) : 

 

UCB0IE |= (UCRXIE0|UCALIE|UCNACKIFG|UCSTTIFG|UCSTPIFG);

 

Interrupt Enable with Interrupt FlaGs ?? I didn't check but I hope it's the same bits as UCSSTTIE and UCSTPIE ... But intellectually it's not good at all. And it's not the only eror I found.

 

To continu ...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now