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.

MSP430 I2C to Wii Nunchuck address issue.

Other Parts Discussed in Thread: MSP430G2553, CC430F5137, MSP430F5510

Hey Guys,

Just getting into the MSP430 Launchpad, using the g2553. I learned some initial I2C stuff and successfully interfaced two launchpads in a simple Master/Slave configuration using I2C, flicked some LED's on and off...yay!

Now I'm trying to communicate with a Wii Nunchuck via it's little breakout board from SparkFun. My problem is this...my code seems to work fine and send start conditions, however when I attempt to send a start condition with the Nunchuck's slave address loaded (0x52 from internet research), the start condition will just hang and not send. I'm using basically the same code, just switching the address, but I can't even seem to send a start condition. Any idea what the problem could be? I have the launchpad and the wii nunchuck running off the same power supply, all connections are fine, etc etc.

Thoughts?

Nick 

  • Nicholas Kennedy said:
    Now I'm trying to communicate with a Wii Nunchuck via it's little breakout board from SparkFun. My problem is this...my code seems to work fine and send start conditions, however when I attempt to send a start condition with the Nunchuck's slave address loaded (0x52 from internet research), the start condition will just hang and not send.

    The Nunchuck's slave address of 0x52 looks correct.

     Are there pull-up resistors on the SCL and SDA lines?

    If there are no pull-ups, the MSP430G2553 could think the bus is busy and therefore no send a start condition.

  • Hey Chester,

    Thanks for the response. I read that the NunChuck has built in pullups inside the controller, so originally I wasn't using any. For the Master/Slave configuration I tried, I was using 10k pullups...I've tried both using them and not using them with the nunchuck to no avail. Seems as though now I'm getting a bus busy as soon as I config the UCB0 and clear the software reset, which is similar to another problem described on this forum...but none of the stuff in that thread has helped yet either :P.

    Nick

  • I have had problems with I2C slaves being busy from a previous transaction following a MSP430 reset.

    The following code was used to perform GPIO to "unhang" the I2C bus prior to the MSP430 SPI module being configured, where in this example P3.6 was SCL and P3.7 was SDA:

        // If SDA is being pulled low by the slave, attempt to generate SCL clocks
        // to release the slave from the previous incomplete transaction
        while ((P3IN & BIT7) == 0)
        {
          P3OUT &= ~BIT6;
          P3DIR |= BIT6;
          __delay_cycles (45);
          P3DIR &= ~BIT6;
          __delay_cycles (45);
       }

  • Hey Chester,

    Thanks for the code. This seems to fix the bus busy problem, but now I am back to square one...the master code simply hangs and will not transmit the start condition when it has a slave attached ( Nunchuck or another MSP). Could this be a hardware issue, or would it be worthwhile posting my code? Also, you use port 3 in your code...which I'm not familiar with. I thought using P1SEL and P1SEL2 would allow for I2C simply using P1 bits 6 and 7...is this incorrect?

    Nick

  • Nicholas Kennedy said:
    Could this be a hardware issue, or would it be worthwhile posting my code?

    Not sure if a software or hardware problem. If you post the code I will have a look.

    Nicholas Kennedy said:
    Also, you use port 3 in your code...which I'm not familiar with. I thought using P1SEL and P1SEL2 would allow for I2C simply using P1 bits 6 and 7...is this incorrect?

    Sorry for not being clear, but the code example was from a CC430F5137 which can use the Port Mapper to map the I2C module to pins of your choice.

    For the MSP430G2553 when using the USCI_B0 you are restricted to using P1.6 for SCL and P1.7 as SDA.

  • Hey, sorry for the delay, had a few busy days of school..

    Anyway, just to resolve it maybe being my code, I even used Grace to configure the I2C interface in master mode, and am just trying to transmit a start condition with the wiichuck connected. Using a common ground, tried it with/without additional pullup resistors, and with/without the P1BIT6 jumper for the LED...still just will not send a start condition to the Wiichuck. Here is the sum of the code :

     

    void main(void)
    {
    CSL_init(); // Activate Grace-generated configuration
    UCB0CTL1 = UCTR + UCTXSTT;
    while (UCB0CTL1 & UCTXSTT);

    while (1) {
    P1OUT ^= BIT0; // Toggle LED on P1.0
    __delay_cycles(100000); // Wait ~100ms at default DCO of ~1MHz
    }
    }

    and this is the content of the CSL_init();

    /* Port 1 Output Register */
    P1OUT = 0;

    /* Port 1 Port Select Register */
    P1SEL = BIT6 + BIT7;

    /* Port 1 Port Select 2 Register */
    P1SEL2 = BIT6 + BIT7;

    /* Port 1 Direction Register */
    P1DIR = BIT0;

    /* Port 1 Interrupt Edge Select Register */
    P1IES = 0;

    /* Port 1 Interrupt Flag Register */
    P1IFG = 0;

    /* Port 2 Interrupt Edge Select Register */
    P2IES = 0;

    /* Port 2 Interrupt Flag Register */
    P2IFG = 0;

    void BCSplus_init(void)
    {
    /*
    * Basic Clock System Control 2
    *
    * SELM_0 -- DCOCLK
    * DIVM_0 -- Divide by 1
    * ~SELS -- DCOCLK
    * DIVS_0 -- Divide by 1
    * ~DCOR -- DCO uses internal resistor
    *
    * Note: ~<BIT> indicates that <BIT> has value zero
    */
    BCSCTL2 = SELM_0 + DIVM_0 + DIVS_0;

    if (CALBC1_1MHZ != 0xFF) {
    /* Follow recommended flow. First, clear all DCOx and MODx bits. Then
    * apply new RSELx values. Finally, apply new DCOx and MODx bit values.
    */
    DCOCTL = 0x00;
    BCSCTL1 = CALBC1_1MHZ; /* Set DCO to 1MHz */
    DCOCTL = CALDCO_1MHZ;
    }

    /*
    * Basic Clock System Control 1
    *
    * XT2OFF -- Disable XT2CLK
    * ~XTS -- Low Frequency
    * DIVA_0 -- Divide by 1
    *
    * Note: ~XTS indicates that XTS has value zero
    */
    BCSCTL1 |= XT2OFF + DIVA_0;

    /*
    * Basic Clock System Control 3
    *
    * XT2S_0 -- 0.4 - 1 MHz
    * LFXT1S_2 -- If XTS = 0, XT1 = VLOCLK ; If XTS = 1, XT1 = 3 - 16-MHz crystal or resonator
    * XCAP_1 -- ~6 pF
    */
    BCSCTL3 = XT2S_0 + LFXT1S_2 + XCAP_1;
    }

    void USCI_B0_init(void)
    {
    /* Disable USCI */
    UCB0CTL1 |= UCSWRST;

    /*
    * Control Register 0
    *
    * ~UCA10 -- Own address is a 7-bit address
    * ~UCSLA10 -- Address slave with 7-bit address
    * ~UCMM -- Single master environment. There is no other master in the system. The address compare unit is disabled
    * UCMST -- Master mode
    * UCMODE_3 -- I2C Mode
    * UCSYNC -- Synchronous Mode
    *
    * Note: ~<BIT> indicates that <BIT> has value zero
    */
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;

    /*
    * Control Register 1
    *
    * UCSSEL_2 -- SMCLK
    * ~UCTR -- Receiver
    * ~UCTXNACK -- Acknowledge normally
    * ~UCTXSTP -- No STOP generated
    * ~UCTXSTT -- Do not generate START condition
    * UCSWRST -- Enabled. USCI logic held in reset state
    *
    * Note: ~<BIT> indicates that <BIT> has value zero
    */
    UCB0CTL1 = UCSSEL_2 + UCSWRST;

    /* I2C Slave Address Register */
    UCB0I2CSA = 82;

    /* Bit Rate Control Register 0 */
    UCB0BR0 = 3;

    /* Enable USCI */
    UCB0CTL1 &= ~UCSWRST;
    }

     Starting to think it's a hardware problem, but I tried the same code with two different launchpads to no avail...any chance it's my power supply? Putting out a nice 3.4V and should be able to deliver up to 750mA.

     


     

  • Nicholas Kennedy said:
    Anyway, just to resolve it maybe being my code, I even used Grace to configure the I2C interface in master mode, and am just trying to transmit a start condition with the wiichuck connected.

    I have created a CCS 5.2 Grace project which matches your code, and connected a wiichuck to a launchpad fitted with a MSP430G2553. Running the program I have repeated the failure, in that the loop in main to send a START condition doesn't complete.

    The debugger shows that when the code gets to the following line, UCB0CTL1 contains the value 0x80.

    UCB0CTL1 = UCTR + UCTXSTT;

    The UCSSEL bits are 10 = USCI clock source select of SMCLK which has been selected by the Grace configuration code.

    The code main sets UCB0CTL1 to UCTR + UCTXSTT (0x12). This has the side effect of changing the UCSSEL bits to 00 which changes the USCI clock source select to UCLKI - which is an external clock input sourced from P1.5. This means UCB0 has no clock, and so nothing happens on the I2C bus.

    To preserve the USCI clock source bits, the code can be changed to bitwise-OR in the UCTR and UCTXSTT:

    UCB0CTL1 |= UCTR + UCTXSTT;

    With this change the MSP430G2553 then attempts to send the start condition.

  • Hey Chester,

    Ah, thanks, just noticed the typo. Unfortunately, I usually did use the |= in other code and it seems my problem still is not solved. Did you use external pullups or just the ones in the wiichuck?

    As of now I have toggled the clock as you suggested to make sure UCBBUSY is not set...but the start condition still won't send. I have listed my register values at the time where it hangs:

     P1IN = BIT2;

    P1SEL, P1SEL2 = BIT6 + BIT7;

    UCB0CTL0 = 0x0F;

    UCBOCTL1 = 0x92;

    UCB0STAT = 0x50 (USCLLOW is set...should it be?)

    Thanks again for all the help,

    Nick

  • Nicholas Kennedy said:
    Did you use external pullups or just the ones in the wiichuck?

    I am using just the pull-ups in the wiichuck. I used a DVM to check that the wiichuck was pulling-up SDA and SCL to VCC but didn't check the value of the pull-up resistors.

    Nicholas Kennedy said:
    As of now I have toggled the clock as you suggested to make sure UCBBUSY is not set...but the start condition still won't send. I have listed my register values at the time where it hangs:

    The value of 0x92 in UCBOCTL1 shows the UCTXSTT bit remains set, which means the UCB0 hasn't attempted to send a START. What is the contents of UCB0STAT prior to executing the 'UCB0CTL1 |= UCTR + UCTXSTT;' line?

    Can you post a .zip file of your entire CCS project, just so that I can see all of the code?

  • SDA and SCL appear to be pulled up to VCC, but as soon as UCTXSTT gets set they are both pulled low. The UCB0STAT register reads empty just before the UCTR + UCTXSTT line...

    Here is the code in a zip fiel! 3554.NickI2CCode_gray.zip

    Thanks again, I really appreciate all the help to get my I2C going! So strange because I had it working before...I'm hoping it doesn't wind up being some silly hardware error, but then at least I'll have learned a lesson!

    Nick 

  • Nicholas Kennedy said:
    Here is the code in a zip fiel!

    For my setup of a nunchuck connected to a launchpad that code behaves the same as the code I had written, in that the MSP430G2553 does transmit a I2C start followed by 0xA4 which should be a write to the nunchunk. However, the nunchuck doesn't ACK the write request so can't actually communicate with the nunchuck.

    Not sure what the problem is, will try and access the nunchuck from a different device to see if that works.

  • Very interesting problem this has become! I'll try swapping out some hardware here and there to see if I can at least get the start condition transferring, now that I know my code should be working as intended. Thanks again for the extra effort!

    Nick

  • Chester Gillon said:
    Not sure what the problem is, will try and access the nunchuck from a different device to see if that works.

    Got the same problem of the nunchuck not ACKing the write requuest when interfaced to a MSP430F5510 using UCB0. With this board also have 4K7 pull-ups on SCL and SDA as well as the pull-ups in the nunchuck.

    Looking with an LSA shows:

    a) I2C start condition.

    b) 0xA4 being clocked out by the MSP430 I2C master, which is the expected write request for the nunchuck.

    c) SCL is held low for ~18 milliseconds. Presumably the nunchuck is stretching the clock.

    d) The SCL pulse for the ACK is generated, but SDA is high resulting in a NACK.

     Will try a bit-banged I2C with GPIO to see if that makes a difference.

  • Nicholas Kennedy said:
    I attempt to send a start condition with the Nunchuck's slave address loaded (0x52 from internet research)

    Sure? Or is it 0x52 for write and 0x53 for read? in this case, use 0x29 instead, as the address is 7 bit and the LSB is added based on UCTR bit.

    However, a wrong slave address won't cause the start condition to hang. It shoudl complete and return an UCNACKIFG if the slave doesn't answer.

    If the start condition hangs, there are two possible reasons: First, the SCL line is pulled low externally or by internal pulldown. Then no clock is generated and the start condition cannot complete. The other is that there is no clock signal for the USCI.
    If you really use the exact same code as in your master/slave experiment, then I'd suspect a hardware problem, pulling the SCL line low. Or the SDA line, as a start condition requires SDA be high first.

  • Hello All,

    Thanks for all the help on this. Over the past few weeks I have been experimenting using all the Serial protocols with the launchpad to a great degree of success...SPI and UART worked excellently, and I even got a basic MIDI controller working using a MIDI breakout board and UART...great fun! Decided tonight to come back to the I2C with the WiiChuck, and still not luck.

    However, I now am more experienced and think I have things setup correctly..here is what is happening. Once I send the start condition (which is now sending), the SCL line is held low and I'm faced with a UCSCLLOW, UCBBUSY, and a UCNACKIFG in that status register. Any idea what could be causing this combination of flags? I read that if the master is communicating too quickly the slave can do clock stretching to hold the line low, but I have fiddled with the clock rate from 50kHz all the way to 400kHz to no avail.

    Also, the slave is ready on startup as I have incorporated the toggling function to make sure the line is released, and as mentioned the UCTXSTT clears as expected before returning clock low, bus busy, and UNACK.

    Thanks!

    Nick 

  • Nicholas Kennedy said:
    I'm faced with a UCSCLLOW, UCBBUSY, and a UCNACKIFG in that status register.

    That's strange. UCNACKIFG means that teh USCI has finished teh cycle and the slave has nor ACKed.

    SO eithe rhte slave didn't respond. Since the ACK cycle is finished (or else UCNACKIFG wouldn't be set), SCL must have gone high (to end the ACk cycle). But when SCL has gone high and UCNACKIFG was received, then there is no reason for anyone to pull (and hold) SCL low again.
    The master may hold SCL low on the 7th bit of a byte when you didn't read the previous byte. However, then the master is actually sending an ACK after each byte, not receiving it, so NACKIFG cannot be set. Any attempt of a start condition (to explain the next clock cycle) would (IIRC) clear NACKIFG.

    So I really don't know how this combination of flags can happen. YOu should check your hardware, pullups, possible shortcuts etc. Does it still happen if you disconnect the slave?

**Attention** This is a public forum