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.

MSP430FR2633: Initializing I2C

Part Number: MSP430FR2633
Other Parts Discussed in Thread: TLV320DAC3203,

Hi dear people,

I am sorry to bother you with this boring question, but I am in need of help.

I am trying to work with I2C on a MSP430FR2633, sending as master configurations data to a TLV320DAC3203.
I was looking at everything I could get as examples, but still I am in doubt.

Would you be so kind to check my code snipplet here and guide me in this matter?

Thank you very much in advance!

Gustavo

#include <msp430.h>
#include <stdio.h>
#include "driverlib.h"
#include "eusci_b_i2c.h"

#define MCLK_FREQ_MHZ 2.8224
#define SLAVE_ADDRESS 0x30


configureClocks_to2822400Hz();                                    //  MCLK adjust to 2.8224 MHz

void I2C_masterInit()
{
    __bic_SR_register(GIE);
    UCB0CTLW0 = UCSWRST;                                        // Enable SW reset
    UCB0CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC;     // I2C master mode, SMCLK
    UCB0BRW = 28;                                                  // fSCL = SMCLK/28 = 2822400/28 = 100800Hz
    UCB0I2CSA = SLAVE_ADDRESS;                                   // Slave Address
    UCB0CTL1 &= ~UCSWRST;                                       // eUSCI_B in operational state
    UCB0CTLW0 &= ~UCSWRST;                                      // Clear SW reset, resume operation
    UCB0IE |= UCTXIE;                                           // enable TX-interrupt
    UCB0IE |= UCNACKIE;
    __bis_SR_register(GIE);                                     // general interrupt enable
}

EUSCI_B_I2C_masterSendMultiByteStart(SLAVE_ADDRESS, regAddress);
EUSCI_B_I2C_masterSendMultiByteNext(SLAVE_ADDRESS, dataValues[j]);
EUSCI_B_I2C_masterSendMultiByteFinish(SLAVE_ADDRESS, dataValues[numDataValues - 1]);

int main(void) {
    WDTCTL = WDTPW | WDTHOLD; // Stop the watchdog timer

    // Configure I/O pins for I2C
    // P1.7-SMCLK

    P1SEL |= BIT6 + BIT7;
    P1SEL2 |= BIT6 + BIT7;

    I2C_masterInit();                                             // Initialize I2C

    // Send I2C start condition
    SendMyValues()
    
    // Inside the function SendMyValues() I am using the following functions from
    // eusci_b_i2c.c (driver library - Driver for the eusci_b_i2c Module.):

    // EUSCI_B_I2C_masterSendMultiByteStart(SLAVE_ADDRESS, regAddress);
    // EUSCI_B_I2C_masterSendMultiByteNext(SLAVE_ADDRESS, dataValues[j]);
    // EUSCI_B_I2C_masterSendMultiByteFinish(SLAVE_ADDRESS, dataValues[numDataValues - 1]);i2cccccc

    free(dataValues);                                            // Free dynamically allocated memory for dataValues
    
    __bis_SR_register(CPUOFF);                                     // Enter low-power mode
}

  • It seems that you put nothing in "configureClocks_to2822400Hz()".

    Can you catch the wave using a oscillascope at the same time?

  • Hi Eason,

    I didn't include the function "configureClocks_to2822400Hz()", because the clock 2.8224 MHz (MCLK and SMCLK) is already working propperly by 2.8224 MHz.

    The questions I have refers to the initializing from the I2C itself.

    For instance, I am not sure if I have to first clear the GIE and set it again at the end of the configuration. Is this well done inside the function "I2C_masterInit()", or should I set this in the "main()", like some examples I have seen do?

    Also about these two rows I am not sure:
    UCB0IE |= UCTXIE;                                           // enable TX-interrupt
    UCB0IE |= UCNACKIE;

    By now, I am not using any interrupt routine in my code. Everything is being called from "main()" and "SendMyValues()".
    Later I will be using the touch capabilities of the MSP, but by now I only need to get the TLV320DAC3203 to work.

    I am now traveling, not close to an oscilloscope and do not have the board by me. It could be good, however, to be sure that the code is correct, before I make some tests again.

    For instance, I had the problem that SDA was not changing state while I2C was suppose to send (the hardware works, when tested by pulling SDA pin HIGH by software, without activating I2C)
    SCL pin was working too.

    But the "EUSCI_B_I2C_masterSendMultiByteStart(SLAVE_ADDRESS, regAddress);" stucks in the line polling for a transmit interrupt flag.

    Thats why I decided to start from scratch and reconfigure everything under Ti's supervision, if possible.

    I hope you can understand now better the situation.

    Thanks for the help!

    Best regards,

    Gustavo

  • #define SLAVE_ADDRESS 0x30

    Per TLV320DAC3203 data sheet (SLOS756B) Sec 7.3.8.1, its I2C address is 0x18, not 0x30. (The R/W bit is not part of the address.)

    ------------------

    >    UCB0IE |= UCTXIE;                                           // enable TX-interrupt
    >    UCB0IE |= UCNACKIE;

    If you don't have an ISR (I don't see one) you shouldn't set these IE bits.

    ------------------

    > EUSCI_B_I2C_masterSendMultiByteStart(SLAVE_ADDRESS, regAddress);

    The first argument provides the EUSCI (registers) address, not the slave address, something like:

    > EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, regAddress);

    Similarly for the other calls.

    ------------------

    If you're calling that write sequence multiple times, it's probably a good idea to precede each sequence with something like 

    > while (EUSCI_B_I2C_isBusBusy(EUSCI_B0_BASE))/*EMPTY*/;

    to make sure the previous operation (notably Stop condition) has completed.

  • Hi Bruce,

    thanks for your quick reaction!

    Regarding the slave address, I made a mistake, or better I missunderstood the answer from Ivan Salazar to my question why the address in the datasheet was diferent from the one in the scripts for the GUI of the EVM.
    I understood I could continue with the address being 0x30. Sorry for this.

    However, I still don't get the thing with the slave address.
    Every example I see is different, because made for something special.
    The simplest I could find is "eusci_b_i2c_ex4_masterTxSingle".
    There is defined:

    //Set the address for slave module. This is a 7-bit address sent in the
    //following format:
    //[A6:A5:A4:A3:A2:A1:A0:RS]
    //
    //A zero in the "RS" position of the first byte means that the master
    //transmits (sends) data to the selected slave, and a one in this position
    //means that the master receives data from the slave.
    //
    //*****************************************************************************
    #define SLAVE_ADDRESS 0x48,

    which is 01001000 being the last bit '0' means 'transmit'. Correct?
    However, in the example "eusci_b_i2c_ex2_masterRxSingle" the slave address is the same. I would expect here '0x49' (01001001)
    Am I missing the point?

    If in my case the address of the TLV320DAC3203 is 0x18, where does the 'RS' bit comes to be?

    You see, I am a bit lost in this matter.

    Anyway, I don't want to disturb you with silly questions. I was trying to go beyond of my knowless in this matter. Better I start by trying out the "eusci_b_i2c_ex4_masterTxSingle" and see what appens.

    This, if you could explain me the thing about the slave address before.

    Best regards,

    Gustavo

  • The 8 bits containing the slave address and the R/W bit (I don't think I've heard the term "RS" bit) is usually called the "SLA byte". The R/W bit is inserted by the I2C unit according to the UCTR setting. I suspect that the only significance to the address 0x48 is that it matches the one chosen over in ex4_slaveRxSingle. (And it fits in 7 bits.)

    To be sure, many datasheets don't make this distinction very clear (yours does). The first clue is if they say there are different "addresses" for Read and Write, in which case (probably) the address is either of those values shifted right by 1.

  • Thanks Bruce, now I get it.
    As I said, I will come back to the roots and give the example a try (with the needed modifications for my hardware.)
    I think, we can close this for now. Anyway, I will be back, I suppose...
    As usual, Ti has the best service. It is a pleasure, thanks again!
    Best regards,
    Gustavo

**Attention** This is a public forum