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.

I2C library

Other Parts Discussed in Thread: MSP430F5529, MSP430WARE, MSP430F6779

Hallo TI Community,

I am trying to write a I2C Master Code for MSP430F5529 LaunchPad and I think, I will need the USI_I2CMaster.h...
Where can I find the USI_I2CMaster.h ?

Thanks a lot

Tiemo

  • Hi,

    first of all, the MSP430F5529 has USCI module instead of USI module.

    second, you don't need to re-invent the wheel. We have already a fully supported USCI I2C module for the MSP430F5529. Please refer to the MSP430ware driverlib for this.

  • oh, you are right! Thank you very much.

    So I tried the example codes for transmitting and receiving and its working very well, but how can I combine these codes? First I want to write data and after that receive data from the slave.

    best regards
    Tiemo

  • To handle the I2C protocol there are 4 pieces of software applicable:

    • Master

    - Generate Clock (CLK)

    - Generate START/STOP (S/P)

    - Writes Slave Address

    - Controls Read/Write bit

    • Slave

    - Detecting Own Address

    • Transmitter

    - Writes Data to the Bus

    - Waits for ACK/NACK

    • Receiver

    - Reads Data from the Bus

    - Acknowledge Data reception (ACK)

     

    The Master only is generating the clock. The Slave reads and writes data synchronous to the Master clock, therefore the clock doesn’t need to be precisely calibrated. Most I2C devices have filtered inputs for 100 and 400KHz baud rate, but in most cases any speed between 1 and 400KHz will properly work.

    The Transmitter and Receiver are fully in depended pieces of software with each their own ISR and are equal for both Master and Slave.

    The Transmitter writes data to a Master or a Slave and waits for an acknowledge (ACK).

    The Receiver reads data from a Master or a Slave and acknowledge the reception (ACK). The Receiver can end the transmission by not-acknowledging (NACK) for example if the Receiver can’t read more data bytes.

    If the Master needs only to read data from the Slave, the Master may have only Receiver and the Slave only Transmitter.

    If the Master needs only to write data to the Slave, the Master may have only Transmitter and the Slave only Receiver.

    Normally the hardware will be initialized as Slave (either Master or Slave) and his Own address will be loaded, in this case there is no specific Slave software needed other then the Receiver and/or Transmitter part.

  • Hi Leo,

    I am using msp430f6779 mcu and I am trying to read/write eeprom from i2c  module. But I could not read/write to eeprom. I dont know what is the problem but my transmit interrupt function doesnt work. My code stay "EUSCI_B_I2C_isBusBusy(EUSCI_B1_BASE)"  function.

    Here is my code:

    #include "driverlib.h"

    #define SLAVE_ADDRESS 0xA0

    #define TXLENGTH 0x04

    uint8_t transmitData[40] = { 0x61,
    0x62,
    0x63,
    0x64,
    0x65,
    0x66,
    0x67,
    0x68 };

    uint8_t transmitCounter = 0;

    void main()
    {
    //Stop WDT
    WDT_A_hold(WDT_A_BASE);

    //Assign I2C pins to USCI_B0
    GPIO_setAsPeripheralModuleFunctionInputPin(
    GPIO_PORT_P4,
    GPIO_PIN4 + GPIO_PIN5
    );

    //Initialize Master
    EUSCI_B_I2C_masterInit(EUSCI_B1_BASE,
    EUSCI_B_I2C_CLOCKSOURCE_SMCLK,
    UCS_getSMCLK(),
    EUSCI_B_I2C_SET_DATA_RATE_400KBPS,
    EUSCI_B_I2C_SET_BYTECOUNT_THRESHOLD_FLAG,
    EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD
    );




    //Specify slave address
    EUSCI_B_I2C_setSlaveAddress(EUSCI_B1_BASE,
    SLAVE_ADDRESS
    );

    //Set Transmit mode
    EUSCI_B_I2C_setMode(EUSCI_B1_BASE,
    EUSCI_B_I2C_TRANSMIT_MODE
    );

    //Enable I2C Module to start operations
    EUSCI_B_I2C_enable(EUSCI_B1_BASE);


    while (1) {
    //Enable transmit Interrupt
    EUSCI_B_I2C_clearInterruptFlag(EUSCI_B1_BASE,
    EUSCI_B_I2C_TRANSMIT_INTERRUPT0
    );
    EUSCI_B_I2C_enableInterrupt(EUSCI_B1_BASE,
    EUSCI_B_I2C_TRANSMIT_INTERRUPT0
    );

    //Delay between each transaction
    __delay_cycles(50);

    //Load TX byte counter
    transmitCounter = 1;

    //Initiate start and send first character
    EUSCI_B_I2C_masterMultiByteSendStart(EUSCI_B1_BASE,
    transmitData[0]
    );

    //Enter LPM0 with interrupts enabled
    // __bis_SR_register(LPM0_bits + GIE);
    // __no_operation();

    //Delay until transmission completes
    while (EUSCI_B_I2C_isBusBusy(EUSCI_B1_BASE)) ;
    }
    }

    //******************************************************************************
    //
    //This is the USCI_B0 interrupt vector service routine.
    //
    //******************************************************************************
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_B1_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(USCI_B0_VECTOR)))
    #endif
    void USCI_B1_ISR(void)
    {
    switch (__even_in_range(UCB1IV, 12)) {
    case USCI_I2C_UCTXIFG0:
    {
    //Check TX byte counter
    if (transmitCounter < TXLENGTH) {
    //Initiate send of character from Master to Slave
    EUSCI_B_I2C_masterMultiByteSendNext(EUSCI_B1_BASE,
    transmitData[transmitCounter]
    );

    //Increment TX byte counter
    transmitCounter++;
    } else {
    //Initiate stop only
    EUSCI_B_I2C_masterMultiByteSendStop(EUSCI_B1_BASE);

    //Clear master interrupt status
    EUSCI_B_I2C_clearInterruptFlag(EUSCI_B1_BASE,
    EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

    //Exit LPM0 on interrupt return
    __bic_SR_register_on_exit(LPM0_bits);
    }
    break;
    }
    }
    }

     

  • You don’t use the library to set the system clock speeds. So are you sure that setting the I2C clock to 400kHz is working correctly? How will the library know what you actual SMCLK speed is?

    Also, why not trying with less than 400kHz first, to get the software working, and then raise speed (if necessary at all) and see whether the hardware can cope with this?
    In many cases of failed I2C communication, the hardware (pull-ups, lien capacitance, crosstalk) was prohibiting or at least slowing down a high-speed communication, while the code itself was okay.

     However, the slave address is obviously wrong. The slave address is a 7 bit value. And 0xA0 if definitely 8 bit. So likely, the slave address is 0x50, and 0xA0 is the start byte for a write transfer (assembled from slave address and direction bit, but the USCI assembles this on its own, depending on the selected transfer direction). With a wrong slave address, the communication cannot work.

**Attention** This is a public forum