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.

MSP430F5529: msp430

Part Number: MSP430F5529

Hello , i want to know one thing that is actually  in CCS SDK they have given a code for UART UCA0 Port so i want change to another pin so which and all i need to change , what i have changed is register names as from Ao to A1 and pins by using P1SEL thats all i have changed is that enough or do i need to change anything......

thanks ,regards  

Veerendra B

  • Hi Veerendra,

    if I understood you correctly, you have code for UART UCA0 and want to use UCA1 instead.
    You will need to adapt all configuration to Port and Pin you'll use and also use the registers for UCA1 instead of UCA0. Apart from the hardware connection that will need to be changed to UCA1 as well.
    Best is to follow the User's Guide to understand the steps you'd need to take.

    Best regards,
    Britta
  • thank you for responds and actually i have changed form UCA0 to UCA1 and hardware also connected properly as will as pins also from P3.0,P3.1 to P4.1,P4,2

    actual code :

    P3SEL |= BIT0 + BIT1; // P3.0,1 option select
    UCB0CTL1 |= UCSWRST; // Enable SW reset
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
    UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
    UCB0BR0 = 160; // fSCL = SMCLK/160 = ~100kHz
    UCB0BR1 = 0;
    UCB0I2CSA = SLAVE_ADDR; // Slave Address is 048h
    UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
    UCB0IE |= UCNACKIE;

    Modified code :

    P4SEL |= BIT1 + BIT2; // P4.1,2 option select
    UCB1CTL1 |= UCSWRST; // Enable SW reset
    UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
    UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
    UCB1BR0 = 160; // fSCL = SMCLK/160 = ~100kHz
    UCB1BR1 = 0;
    UCB1I2CSA = SLAVE_ADDR; // Slave Address is 048h
    UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
    UCB1IE |= UCNACKIE;

  • Thanks for sharing.
    Did you test that yet? If so, is there anything that indicates it's not working?
    My assumption at first glance (I didn't test the code) is that it should behave like the actual code, simply using a different module for I2C communication. You should be good to go.

    Best regards,
    Britta
  • yeah i have checked by Debugging the code its not coming out of the Interrupt ISR , below code only i have used earlier  now i want to change from UCB0 to UCB1 so please help where and all i need to change in code... 
    
    
    
    //******************************************************************************
    // MSP430F552x Demo - USCI_B0, I2C Master multiple byte TX/RX
    //
    // Description: I2C master communicates to I2C slave sending and receiving
    // 3 different messages of different length. I2C master will enter LPM0 mode
    // while waiting for the messages to be sent/receiving using I2C interrupt.
    // ACLK = NA, MCLK = SMCLK = DCO 16MHz.
    //
    // /|\ /|\
    // MSP430F5529 4.7k |
    // ----------------- | 4.7k
    // /|\ | P3.1|---+---|-- I2C Clock (UCB0SCL)
    // | | | |
    // ---|RST P3.0|-------+-- I2C Data (UCB0SDA)
    // | |
    // | |
    // | |
    // | |
    // | |
    // | |
    //
    // Nima Eskandari
    // Texas Instruments Inc.
    // April 2017
    // Built with CCS V7.0
    //******************************************************************************
    
    #include <msp430.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    
    //******************************************************************************
    // Example Commands ************************************************************
    //******************************************************************************
    
    #define SLAVE_ADDR 0x10
    
    /* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
    * The slave will send example SlaveTypeX buffers in response.
    *
    * CMD_TYPE_X_MASTER are example commands the master sends to the slave.
    * The slave will initialize itself to receive MasterTypeX example buffers.
    * */
    
    #define CMD_TYPE_0_SLAVE 0
    #define CMD_TYPE_1_SLAVE 1
    #define CMD_TYPE_2_SLAVE 2
    
    #define CMD_TYPE_0_MASTER 3
    #define CMD_TYPE_1_MASTER 4
    #define CMD_TYPE_2_MASTER 5
    
    #define TYPE_0_LENGTH 1
    #define TYPE_1_LENGTH 2
    #define TYPE_2_LENGTH 6
    
    #define MAX_BUFFER_SIZE 10
    
    /* MasterTypeX are example buffers initialized in the master, they will be
    * sent by the master to the slave.
    * SlaveTypeX are example buffers initialized in the slave, they will be
    * sent by the slave to the master.
    * */
    
    uint8_t MasterType2 [TYPE_2_LENGTH] = {'F', '4', '1', '9', '2', 'B'};
    uint8_t MasterType1 [TYPE_1_LENGTH] = { 8, 9};
    uint8_t MasterType0 [TYPE_0_LENGTH] = { 11};
    
    
    uint8_t SlaveType2 [TYPE_2_LENGTH] = {0};
    uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
    
    int i = 0;
    //******************************************************************************
    // General I2C State Machine ***************************************************
    //******************************************************************************
    
    typedef enum I2C_ModeEnum{
    IDLE_MODE,
    NACK_MODE,
    TX_REG_ADDRESS_MODE,
    RX_REG_ADDRESS_MODE,
    TX_DATA_MODE,
    RX_DATA_MODE,
    SWITCH_TO_RX_MODE,
    SWITHC_TO_TX_MODE,
    TIMEOUT_MODE
    } I2C_Mode;
    
    /* Used to track the state of the software state machine*/
    I2C_Mode MasterMode = IDLE_MODE;
    
    /* The Register Address/Command to use*/
    uint8_t TransmitRegAddr = 0;
    
    /* ReceiveBuffer: Buffer used to receive data in the ISR
    * RXByteCtr: Number of bytes left to receive
    * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
    * TransmitBuffer: Buffer used to transmit data in the ISR
    * TXByteCtr: Number of bytes left to transfer
    * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
    * */
    uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 0;
    
    /* I2C Write and Read Functions */
    
    /* For slave device with dev_addr, writes the data specified in *reg_data
    *
    * dev_addr: The slave device address.
    * Example: SLAVE_ADDR
    * reg_addr: The register or command to send to the slave.
    * Example: CMD_TYPE_0_MASTER
    * *reg_data: The buffer to write
    * Example: MasterType0
    * count: The length of *reg_data
    * Example: TYPE_0_LENGTH
    * */
    //I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);
    
    /* For slave device with dev_addr, read the data specified in slaves reg_addr.
    * The received data is available in ReceiveBuffer
    *
    * dev_addr: The slave device address.
    * Example: SLAVE_ADDR
    * reg_addr: The register or command to send to the slave.
    * Example: CMD_TYPE_0_SLAVE
    * count: The length of data to read
    * Example: TYPE_0_LENGTH
    * */
    I2C_Mode I2C_Master_ReadReg(uint8_t *buffer,uint8_t dev_addr, uint8_t reg_addr, uint8_t count);
    //void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    uint8_t *strcpy(uint8_t *destination, const uint8_t *source);
    I2C_Mode I2C_Master_ReadReg(uint8_t *buffer,uint8_t dev_addr, uint8_t reg_addr, uint8_t count)
    {
    /* Initialize state machine */
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;
    RXByteCtr = count;
    TXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;
    
    /* Initialize slave address and interrupts */
    UCB0I2CSA = dev_addr;
    UCB0IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts
    UCB0IE &= ~UCRXIE; // Disable RX interrupt
    UCB0IE |= UCTXIE; // Enable TX interrupt
    
    UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
    __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
    
    strcpy(buffer,ReceiveBuffer);
    
    return MasterMode;
    
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
    /* Initialize state machine */
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;
    
    //Copy register data to TransmitBuffer
    CopyArray(reg_data, TransmitBuffer, count);
    
    TXByteCtr = count;
    RXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;
    
    /* Initialize slave address and interrupts */
    UCB0I2CSA = dev_addr;
    UCB0IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts
    UCB0IE &= ~UCRXIE; // Disable RX interrupt
    UCB0IE |= UCTXIE; // Enable TX interrupt
    
    UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
    __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
    
    return MasterMode;
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
    {
    uint8_t copyIndex = 0;
    for (copyIndex = 0; copyIndex < count; copyIndex++)
    {
    dest[copyIndex] = source[copyIndex];
    }
    }
    
    
    //******************************************************************************
    // Device Initialization *******************************************************
    //******************************************************************************
    
    void initClockTo16MHz()
    {
    UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO
    UCSCTL4 |= SELA_2; // Set ACLK = REFO
    __bis_SR_register(SCG0); // Disable the FLL control loop
    UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
    UCSCTL1 = DCORSEL_5; // Select DCO range 16MHz operation
    UCSCTL2 = FLLD_0 + 487; // Set DCO Multiplier for 16MHz
    // (N + 1) * FLLRef = Fdco
    // (487 + 1) * 32768 = 16MHz
    // Set FLL Div = fDCOCLK
    __bic_SR_register(SCG0); // Enable the FLL control loop
    
    // Worst-case settling time for the DCO when the DCO range bits have been
    // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
    // UG for optimization.
    // 32 x 32 x 16 MHz / 32,768 Hz = 500000 = MCLK cycles for DCO to settle
    __delay_cycles(500000);//
    // Loop until XT1,XT2 & DCO fault flag is cleared
    do
    {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG; // Clear fault flags
    }while (SFRIFG1&OFIFG); // Test oscillator fault flag
    }
    
    uint16_t setVCoreUp(uint8_t level){
    uint32_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
    
    //The code flow for increasing the Vcore has been altered to work around
    //the erratum FLASH37.
    //Please refer to the Errata sheet to know if a specific device is affected
    //DO NOT ALTER THIS FUNCTION
    
    //Open PMM registers for write access
    PMMCTL0_H = 0xA5;
    
    //Disable dedicated Interrupts
    //Backup all registers
    PMMRIE_backup = PMMRIE;
    PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE |
    SVSLPE | SVMHVLRIE | SVMHIE |
    SVSMHDLYIE | SVMLVLRIE | SVMLIE |
    SVSMLDLYIE
    );
    SVSMHCTL_backup = SVSMHCTL;
    SVSMLCTL_backup = SVSMLCTL;
    
    //Clear flags
    PMMIFG = 0;
    
    //Set SVM highside to new level and check if a VCore increase is possible
    SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level);
    
    //Wait until SVM highside is settled
    while((PMMIFG & SVSMHDLYIFG) == 0)
    {
    ;
    }
    
    //Clear flag
    PMMIFG &= ~SVSMHDLYIFG;
    
    //Check if a VCore increase is possible
    if((PMMIFG & SVMHIFG) == SVMHIFG)
    {
    //-> Vcc is too low for a Vcore increase
    //recover the previous settings
    PMMIFG &= ~SVSMHDLYIFG;
    SVSMHCTL = SVSMHCTL_backup;
    
    //Wait until SVM highside is settled
    while((PMMIFG & SVSMHDLYIFG) == 0)
    {
    ;
    }
    
    //Clear all Flags
    PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
    SVMLVLRIFG | SVMLIFG |
    SVSMLDLYIFG
    );
    
    //Restore PMM interrupt enable register
    PMMRIE = PMMRIE_backup;
    //Lock PMM registers for write access
    PMMCTL0_H = 0x00;
    //return: voltage not set
    return false;
    }
    
    //Set also SVS highside to new level
    //Vcc is high enough for a Vcore increase
    SVSMHCTL |= (SVSHRVL0 * level);
    
    //Wait until SVM highside is settled
    while((PMMIFG & SVSMHDLYIFG) == 0)
    {
    ;
    }
    
    //Clear flag
    PMMIFG &= ~SVSMHDLYIFG;
    
    //Set VCore to new level
    PMMCTL0_L = PMMCOREV0 * level;
    
    //Set SVM, SVS low side to new level
    SVSMLCTL = SVMLE | (SVSMLRRL0 * level) |
    SVSLE | (SVSLRVL0 * level);
    
    //Wait until SVM, SVS low side is settled
    while((PMMIFG & SVSMLDLYIFG) == 0)
    {
    ;
    }
    
    //Clear flag
    PMMIFG &= ~SVSMLDLYIFG;
    //SVS, SVM core and high side are now set to protect for the new core level
    
    //Restore Low side settings
    //Clear all other bits _except_ level settings
    SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 +
    SVSMLRRL1 + SVSMLRRL2
    );
    
    //Clear level settings in the backup register,keep all other bits
    SVSMLCTL_backup &=
    ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
    
    //Restore low-side SVS monitor settings
    SVSMLCTL |= SVSMLCTL_backup;
    
    //Restore High side settings
    //Clear all other bits except level settings
    SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 +
    SVSMHRRL0 + SVSMHRRL1 +
    SVSMHRRL2
    );
    
    //Clear level settings in the backup register,keep all other bits
    SVSMHCTL_backup &=
    ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
    
    //Restore backup
    SVSMHCTL |= SVSMHCTL_backup;
    
    //Wait until high side, low side settled
    while(((PMMIFG & SVSMLDLYIFG) == 0) &&
    ((PMMIFG & SVSMHDLYIFG) == 0))
    {
    ;
    }
    
    //Clear all Flags
    PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
    SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG
    );
    
    //Restore PMM interrupt enable register
    PMMRIE = PMMRIE_backup;
    
    //Lock PMM registers for write access
    PMMCTL0_H = 0x00;
    
    return true;
    }
    
    bool increaseVCoreToLevel2()
    {
    uint8_t level = 2;
    uint8_t actlevel;
    bool status = true;
    
    //Set Mask for Max. level
    level &= PMMCOREV_3;
    
    //Get actual VCore
    actlevel = PMMCTL0 & PMMCOREV_3;
    
    //step by step increase or decrease
    while((level != actlevel) && (status == true))
    {
    if(level > actlevel)
    {
    status = setVCoreUp(++actlevel);
    }
    }
    
    return (status);
    }
    
    
    void initI2C()
    {
    increaseVCoreToLevel2();
    P3SEL |= BIT0 + BIT1; // P3.0,1 option select
    UCB0CTL1 |= UCSWRST; // Enable SW reset
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
    UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
    UCB0BR0 = 160; // fSCL = SMCLK/160 = ~100kHz
    UCB0BR1 = 0;
    UCB0I2CSA = SLAVE_ADDR; // Slave Address is 048h
    UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
    UCB0IE |= UCNACKIE;
    }
    
    
    //******************************************************************************
    // I2C 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
    {
    //Must read from UCB0RXBUF
    uint8_t rx_val = 0;
    
    switch(__even_in_range(UCB0IV,0xC))
    {
    
    case USCI_NONE:break; // Vector 0 - no interrupt
    case USCI_I2C_UCALIFG:break; // Interrupt Vector: I2C Mode: UCALIFG
    case USCI_I2C_UCNACKIFG:break; // Interrupt Vector: I2C Mode: UCNACKIFG
    case USCI_I2C_UCSTTIFG:break; // Interrupt Vector: I2C Mode: UCSTTIFG
    case USCI_I2C_UCSTPIFG:break; // Interrupt Vector: I2C Mode: UCSTPIFG
    case USCI_I2C_UCRXIFG:
    rx_val = UCB0RXBUF;
    if (RXByteCtr)
    {
    for(i = 0; i < 600; i++);
    ReceiveBuffer[ReceiveIndex++] = rx_val;
    RXByteCtr--;
    }
    
    if (RXByteCtr == 1)
    {
    UCB0CTL1 |= UCTXSTP;
    }
    else if (RXByteCtr == 0)
    {
    UCB0IE &= ~UCRXIE;
    MasterMode = IDLE_MODE;
    __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
    }
    break; // Interrupt Vector: I2C Mode: UCRXIFG
    case USCI_I2C_UCTXIFG:
    switch (MasterMode)
    {
    case TX_REG_ADDRESS_MODE:
    UCB0TXBUF = TransmitRegAddr;
    if (RXByteCtr)
    MasterMode = SWITCH_TO_RX_MODE; // Need to start receiving now
    else
    MasterMode = TX_DATA_MODE; // Continue to transmission with the data in Transmit Buffer
    break;
    
    case SWITCH_TO_RX_MODE:
    UCB0IE |= UCRXIE; // Enable RX interrupt
    UCB0IE &= ~UCTXIE; // Disable TX interrupt
    UCB0CTL1 &= ~UCTR; // Switch to receiver
    MasterMode = RX_DATA_MODE; // State state is to receive data
    UCB0CTL1 |= UCTXSTT; // Send repeated start
    if (RXByteCtr == 1)
    {
    //Must send stop since this is the N-1 byte
    while((UCB0CTL1 & UCTXSTT));
    UCB0CTL1 |= UCTXSTP; // Send stop condition
    }
    break;
    
    case TX_DATA_MODE:
    if (TXByteCtr)
    {
    for(i = 0; i < 1000; i++);
    UCB0TXBUF = TransmitBuffer[TransmitIndex++];
    TXByteCtr--;
    }
    else
    {
    //Done with transmission
    UCB0CTL1 |= UCTXSTP; // Send stop condition
    MasterMode = IDLE_MODE;
    UCB0IE &= ~UCTXIE; // disable TX interrupt
    __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
    }
    break;
    
    default:
    __no_operation();
    break;
    }
    break; // Interrupt Vector: I2C Mode: UCTXIFG
    default: break;
    }
    }

    0842.i2c.c
    //******************************************************************************
    //   MSP430F552x Demo - USCI_B0, I2C Master multiple byte TX/RX
    //
    //   Description: I2C master communicates to I2C slave sending and receiving
    //   3 different messages of different length. I2C master will enter LPM0 mode
    //   while waiting for the messages to be sent/receiving using I2C interrupt.
    //   ACLK = NA, MCLK = SMCLK = DCO 16MHz.
    //
    //                                     /|\ /|\
    //                   MSP430F5529       4.7k |
    //                 -----------------    |  4.7k
    //            /|\ |             P3.1|---+---|-- I2C Clock (UCB0SCL)
    //             |  |                 |       |
    //             ---|RST          P3.0|-------+-- I2C Data (UCB0SDA)
    //                |                 |
    //                |                 |
    //                |                 |
    //                |                 |
    //                |                 |
    //                |                 |
    //
    //   Nima Eskandari
    //   Texas Instruments Inc.
    //   April 2017
    //   Built with CCS V7.0
    //******************************************************************************
    
    #include <msp430.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    
    //******************************************************************************
    // Example Commands ************************************************************
    //******************************************************************************
    
    #define SLAVE_ADDR  0x10
    
    /* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
     * The slave will send example SlaveTypeX buffers in response.
     *
     * CMD_TYPE_X_MASTER are example commands the master sends to the slave.
     * The slave will initialize itself to receive MasterTypeX example buffers.
     * */
    
    #define CMD_TYPE_0_SLAVE      0
    #define CMD_TYPE_1_SLAVE      1
    #define CMD_TYPE_2_SLAVE      2
    
    #define CMD_TYPE_0_MASTER      3
    #define CMD_TYPE_1_MASTER      4
    #define CMD_TYPE_2_MASTER      5
    
    #define TYPE_0_LENGTH   1
    #define TYPE_1_LENGTH   2
    #define TYPE_2_LENGTH   6
    
    #define MAX_BUFFER_SIZE     10
    
    /* MasterTypeX are example buffers initialized in the master, they will be
     * sent by the master to the slave.
     * SlaveTypeX are example buffers initialized in the slave, they will be
     * sent by the slave to the master.
     * */
    
    uint8_t MasterType2 [TYPE_2_LENGTH] = {'F', '4', '1', '9', '2', 'B'};
    uint8_t MasterType1 [TYPE_1_LENGTH] = { 8, 9};
    uint8_t MasterType0 [TYPE_0_LENGTH] = { 11};
    
    
    uint8_t SlaveType2 [TYPE_2_LENGTH] = {0};
    uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
    
    int i = 0;
    //******************************************************************************
    // General I2C State Machine ***************************************************
    //******************************************************************************
    
    typedef enum I2C_ModeEnum{
        IDLE_MODE,
        NACK_MODE,
        TX_REG_ADDRESS_MODE,
        RX_REG_ADDRESS_MODE,
        TX_DATA_MODE,
        RX_DATA_MODE,
        SWITCH_TO_RX_MODE,
        SWITHC_TO_TX_MODE,
        TIMEOUT_MODE
    } I2C_Mode;
    
    /* Used to track the state of the software state machine*/
    I2C_Mode MasterMode = IDLE_MODE;
    
    /* The Register Address/Command to use*/
    uint8_t TransmitRegAddr = 0;
    
    /* ReceiveBuffer: Buffer used to receive data in the ISR
     * RXByteCtr: Number of bytes left to receive
     * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
     * TransmitBuffer: Buffer used to transmit data in the ISR
     * TXByteCtr: Number of bytes left to transfer
     * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
     * */
    uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 0;
    
    /* I2C Write and Read Functions */
    
    /* For slave device with dev_addr, writes the data specified in *reg_data
     *
     * dev_addr: The slave device address.
     *           Example: SLAVE_ADDR
     * reg_addr: The register or command to send to the slave.
     *           Example: CMD_TYPE_0_MASTER
     * *reg_data: The buffer to write
     *           Example: MasterType0
     * count: The length of *reg_data
     *           Example: TYPE_0_LENGTH
     *  */
    //I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);
    
    /* For slave device with dev_addr, read the data specified in slaves reg_addr.
     * The received data is available in ReceiveBuffer
     *
     * dev_addr: The slave device address.
     *           Example: SLAVE_ADDR
     * reg_addr: The register or command to send to the slave.
     *           Example: CMD_TYPE_0_SLAVE
     * count: The length of data to read
     *           Example: TYPE_0_LENGTH
     *  */
    I2C_Mode I2C_Master_ReadReg(uint8_t *buffer,uint8_t dev_addr, uint8_t reg_addr, uint8_t count);
    //void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    uint8_t *strcpy(uint8_t *destination, const uint8_t *source);
    I2C_Mode I2C_Master_ReadReg(uint8_t *buffer,uint8_t dev_addr, uint8_t reg_addr, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = reg_addr;
        RXByteCtr = count;
        TXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB0I2CSA = dev_addr;
        UCB0IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
        UCB0IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB0IE |= UCTXIE;                        // Enable TX interrupt
    
        UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __bis_SR_register(LPM0_bits + GIE);              // Enter LPM0 w/ interrupts
    
        strcpy(buffer,ReceiveBuffer);
    
        return MasterMode;
    
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = reg_addr;
    
        //Copy register data to TransmitBuffer
        CopyArray(reg_data, TransmitBuffer, count);
    
        TXByteCtr = count;
        RXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB0I2CSA = dev_addr;
        UCB0IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
        UCB0IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB0IE |= UCTXIE;                        // Enable TX interrupt
    
        UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __bis_SR_register(LPM0_bits + GIE);              // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
    {
        uint8_t copyIndex = 0;
        for (copyIndex = 0; copyIndex < count; copyIndex++)
        {
            dest[copyIndex] = source[copyIndex];
        }
    }
    
    
    //******************************************************************************
    // Device Initialization *******************************************************
    //******************************************************************************
    
    void initClockTo16MHz()
    {
        UCSCTL3 |= SELREF_2;                      // Set DCO FLL reference = REFO
        UCSCTL4 |= SELA_2;                        // Set ACLK = REFO
        __bis_SR_register(SCG0);                  // Disable the FLL control loop
        UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
        UCSCTL1 = DCORSEL_5;                      // Select DCO range 16MHz operation
        UCSCTL2 = FLLD_0 + 487;                   // Set DCO Multiplier for 16MHz
                                                  // (N + 1) * FLLRef = Fdco
                                                  // (487 + 1) * 32768 = 16MHz
                                                  // Set FLL Div = fDCOCLK
        __bic_SR_register(SCG0);                  // Enable the FLL control loop
    
        // Worst-case settling time for the DCO when the DCO range bits have been
        // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
        // UG for optimization.
        // 32 x 32 x 16 MHz / 32,768 Hz = 500000 = MCLK cycles for DCO to settle
        __delay_cycles(500000);//
        // Loop until XT1,XT2 & DCO fault flag is cleared
        do
        {
            UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
            SFRIFG1 &= ~OFIFG;                          // Clear fault flags
        }while (SFRIFG1&OFIFG);                         // Test oscillator fault flag
    }
    
    uint16_t setVCoreUp(uint8_t level){
        uint32_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
    
        //The code flow for increasing the Vcore has been altered to work around
        //the erratum FLASH37.
        //Please refer to the Errata sheet to know if a specific device is affected
        //DO NOT ALTER THIS FUNCTION
    
        //Open PMM registers for write access
        PMMCTL0_H = 0xA5;
    
        //Disable dedicated Interrupts
        //Backup all registers
        PMMRIE_backup = PMMRIE;
        PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE |
                    SVSLPE | SVMHVLRIE | SVMHIE |
                    SVSMHDLYIE | SVMLVLRIE | SVMLIE |
                    SVSMLDLYIE
                    );
        SVSMHCTL_backup = SVSMHCTL;
        SVSMLCTL_backup = SVSMLCTL;
    
        //Clear flags
        PMMIFG = 0;
    
        //Set SVM highside to new level and check if a VCore increase is possible
        SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level);
    
        //Wait until SVM highside is settled
        while((PMMIFG & SVSMHDLYIFG) == 0)
        {
            ;
        }
    
        //Clear flag
        PMMIFG &= ~SVSMHDLYIFG;
    
        //Check if a VCore increase is possible
        if((PMMIFG & SVMHIFG) == SVMHIFG)
        {
            //-> Vcc is too low for a Vcore increase
            //recover the previous settings
            PMMIFG &= ~SVSMHDLYIFG;
            SVSMHCTL = SVSMHCTL_backup;
    
            //Wait until SVM highside is settled
            while((PMMIFG & SVSMHDLYIFG) == 0)
            {
                ;
            }
    
            //Clear all Flags
            PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
                         SVMLVLRIFG | SVMLIFG |
                         SVSMLDLYIFG
                         );
    
            //Restore PMM interrupt enable register
            PMMRIE = PMMRIE_backup;
            //Lock PMM registers for write access
            PMMCTL0_H = 0x00;
            //return: voltage not set
            return false;
        }
    
        //Set also SVS highside to new level
        //Vcc is high enough for a Vcore increase
        SVSMHCTL |= (SVSHRVL0 * level);
    
        //Wait until SVM highside is settled
        while((PMMIFG & SVSMHDLYIFG) == 0)
        {
            ;
        }
    
        //Clear flag
        PMMIFG &= ~SVSMHDLYIFG;
    
        //Set VCore to new level
        PMMCTL0_L = PMMCOREV0 * level;
    
        //Set SVM, SVS low side to new level
        SVSMLCTL = SVMLE | (SVSMLRRL0 * level) |
                   SVSLE | (SVSLRVL0 * level);
    
        //Wait until SVM, SVS low side is settled
        while((PMMIFG & SVSMLDLYIFG) == 0)
        {
            ;
        }
    
        //Clear flag
        PMMIFG &= ~SVSMLDLYIFG;
        //SVS, SVM core and high side are now set to protect for the new core level
    
        //Restore Low side settings
        //Clear all other bits _except_ level settings
        SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 +
                     SVSMLRRL1 + SVSMLRRL2
                     );
    
        //Clear level settings in the backup register,keep all other bits
        SVSMLCTL_backup &=
            ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
    
        //Restore low-side SVS monitor settings
        SVSMLCTL |= SVSMLCTL_backup;
    
        //Restore High side settings
        //Clear all other bits except level settings
        SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 +
                     SVSMHRRL0 + SVSMHRRL1 +
                     SVSMHRRL2
                     );
    
        //Clear level settings in the backup register,keep all other bits
        SVSMHCTL_backup &=
            ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
    
        //Restore backup
        SVSMHCTL |= SVSMHCTL_backup;
    
        //Wait until high side, low side settled
        while(((PMMIFG & SVSMLDLYIFG) == 0) &&
              ((PMMIFG & SVSMHDLYIFG) == 0))
        {
            ;
        }
    
        //Clear all Flags
        PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
                    SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG
                    );
    
        //Restore PMM interrupt enable register
        PMMRIE = PMMRIE_backup;
    
        //Lock PMM registers for write access
        PMMCTL0_H = 0x00;
    
        return true;
    }
    
    bool increaseVCoreToLevel2()
    {
        uint8_t level = 2;
        uint8_t actlevel;
        bool status = true;
    
        //Set Mask for Max. level
        level &= PMMCOREV_3;
    
        //Get actual VCore
        actlevel = PMMCTL0 & PMMCOREV_3;
    
        //step by step increase or decrease
        while((level != actlevel) && (status == true))
        {
            if(level > actlevel)
            {
                status = setVCoreUp(++actlevel);
            }
        }
    
        return (status);
    }
    
    
    void initI2C()
    {
        increaseVCoreToLevel2();
        P3SEL |= BIT0 + BIT1;                     // P3.0,1 option select
        UCB0CTL1 |= UCSWRST;                      // Enable SW reset
        UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
        UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
        UCB0BR0 = 160;                            // fSCL = SMCLK/160 = ~100kHz
        UCB0BR1 = 0;
        UCB0I2CSA = SLAVE_ADDR;                   // Slave Address is 048h
        UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
        UCB0IE |= UCNACKIE;
    }
    
    
    //******************************************************************************
    // I2C 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
    {
      //Must read from UCB0RXBUF
      uint8_t rx_val = 0;
    
      switch(__even_in_range(UCB0IV,0xC))
      {
    
        case USCI_NONE:break;                             // Vector 0 - no interrupt
        case USCI_I2C_UCALIFG:break;                      // Interrupt Vector: I2C Mode: UCALIFG
        case USCI_I2C_UCNACKIFG:break;                    // Interrupt Vector: I2C Mode: UCNACKIFG
        case USCI_I2C_UCSTTIFG:break;                     // Interrupt Vector: I2C Mode: UCSTTIFG
        case USCI_I2C_UCSTPIFG:break;                     // Interrupt Vector: I2C Mode: UCSTPIFG
        case USCI_I2C_UCRXIFG:
            rx_val = UCB0RXBUF;
            if (RXByteCtr)
            {
              for(i = 0; i < 1000; i++);
              ReceiveBuffer[ReceiveIndex++] = rx_val;
              RXByteCtr--;
            }
    
            if (RXByteCtr == 1)
            {
              UCB0CTL1 |= UCTXSTP;
            }
            else if (RXByteCtr == 0)
            {
              UCB0IE &= ~UCRXIE;
              MasterMode = IDLE_MODE;
              __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
            }
            break;                      // Interrupt Vector: I2C Mode: UCRXIFG
        case USCI_I2C_UCTXIFG:
            switch (MasterMode)
            {
              case TX_REG_ADDRESS_MODE:
                  UCB0TXBUF = TransmitRegAddr;
                  if (RXByteCtr)
                      MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
                  else
                      MasterMode = TX_DATA_MODE;        // Continue to transmission with the data in Transmit Buffer
                  break;
    
              case SWITCH_TO_RX_MODE:
                  UCB0IE |= UCRXIE;              // Enable RX interrupt
                  UCB0IE &= ~UCTXIE;             // Disable TX interrupt
                  UCB0CTL1 &= ~UCTR;            // Switch to receiver
                  MasterMode = RX_DATA_MODE;    // State state is to receive data
                  UCB0CTL1 |= UCTXSTT;          // Send repeated start
                  if (RXByteCtr == 1)
                  {
                      //Must send stop since this is the N-1 byte
                      while((UCB0CTL1 & UCTXSTT));
                      UCB0CTL1 |= UCTXSTP;      // Send stop condition
                  }
                  break;
    
              case TX_DATA_MODE:
                  if (TXByteCtr)
                  {
                      for(i = 0; i < 1000; i++);
                      UCB0TXBUF = TransmitBuffer[TransmitIndex++];
                      TXByteCtr--;
                  }
                  else
                  {
                      //Done with transmission
                      UCB0CTL1 |= UCTXSTP;     // Send stop condition
                      MasterMode = IDLE_MODE;
                      UCB0IE &= ~UCTXIE;                       // disable TX interrupt
                      __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
                  }
                  break;
    
              default:
                  __no_operation();
                  break;
            }
            break;                      // Interrupt Vector: I2C Mode: UCTXIFG
        default: break;
      }
    }
    
    
    yeah i have checked by Debugging the code its not coming out of the Interrupt ISR , below code only i have used earlier  now i want to change from UCB0 to UCB1 so please help where and all i need to change in code... 

  • Hi,

    did you also enable the interrupt for the module you're using USCI_B1 and adapt the interrupt service routine to handle the USCI_B1 module instead of USCI_B0? Maybe your interrupt service routine is still unchanged. As you've enabled an interrupt you also need to take care that it is handled properly.
    The code you've posted above is the example code for USCI_B0, right? I actually don't see where you've made the changes. Could you please check that and come back to me afterwards? Instead of posting your code let's start with the general understanding of the firmware flow.

    Best regards,
    Britta
  • /* Modified Code  form B0 to B1 */
    
    
    
    //******************************************************************************
    // MSP430F552x Demo - USCI_B1, I2C Master multiple byte TX/RX
    
    //
    // Description: I2C master communicates to I2C slave sending and receiving
    // 3 different messages of different length. I2C master will enter LPM0 mode
    // while waiting for the messages to be sent/receiving using I2C interrupt.
    // ACLK = NA, MCLK = SMCLK = DCO 16MHz.
    //
    // /|\ /|\
    // MSP430F5529 4.7k |
    // ----------------- | 4.7k
    // /|\ | P3.1|---+---|-- I2C Clock (UCB1SCL)
    // | | | |
    // ---|RST P3.0|-------+-- I2C Data (UCB1SDA)
    // | |
    // | |
    // | |
    // | |
    // | |
    // | |
    //
    // Nima Eskandari
    // Texas Instruments Inc.
    // April 2017
    // Built with CCS V7.0
    //******************************************************************************
    
    #include <msp430.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    
    
    //******************************************************************************
    // Example Commands ************************************************************
    //******************************************************************************
    
    #define SLAVE_ADDR 0x10
    
    /* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
    * The slave will send example SlaveTypeX buffers in response.
    *
    * CMD_TYPE_X_MASTER are example commands the master sends to the slave.
    * The slave will initialize itself to receive MasterTypeX example buffers.
    * */
    
    #define CMD_TYPE_0_SLAVE 0
    #define CMD_TYPE_1_SLAVE 1
    #define CMD_TYPE_2_SLAVE 2
    
    #define CMD_TYPE_0_MASTER 3
    #define CMD_TYPE_1_MASTER 4
    #define CMD_TYPE_2_MASTER 5
    
    #define TYPE_0_LENGTH 1
    #define TYPE_1_LENGTH 2
    #define TYPE_2_LENGTH 6
    
    #define MAX_BUFFER_SIZE 10
    
    /* MasterTypeX are example buffers initialized in the master, they will be
    * sent by the master to the slave.
    * SlaveTypeX are example buffers initialized in the slave, they will be
    * sent by the slave to the master.
    * */
    
    uint8_t MasterType2 [TYPE_2_LENGTH] = {'F', '4', '1', '9', '2', 'B'};
    uint8_t MasterType1 [TYPE_1_LENGTH] = { 8, 9};
    uint8_t MasterType0 [TYPE_0_LENGTH] = { 11};
    
    
    uint8_t SlaveType2 [TYPE_2_LENGTH] = {0};
    uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
    
    int i = 0;
    //******************************************************************************
    // General I2C State Machine ***************************************************
    //******************************************************************************
    
    typedef enum I2C_ModeEnum{
    IDLE_MODE,
    NACK_MODE,
    TX_REG_ADDRESS_MODE,
    RX_REG_ADDRESS_MODE,
    TX_DATA_MODE,
    RX_DATA_MODE,
    SWITCH_TO_RX_MODE,
    SWITHC_TO_TX_MODE,
    TIMEOUT_MODE
    } I2C_Mode;
    
    /* Used to track the state of the software state machine*/
    I2C_Mode MasterMode = IDLE_MODE;
    
    /* The Register Address/Command to use*/
    uint8_t TransmitRegAddr = 0;
    
    /* ReceiveBuffer: Buffer used to receive data in the ISR
    * RXByteCtr: Number of bytes left to receive
    * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
    * TransmitBuffer: Buffer used to transmit data in the ISR
    * TXByteCtr: Number of bytes left to transfer
    * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
    * */
    uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 0;
    
    /* I2C Write and Read Functions */
    
    /* For slave device with dev_addr, writes the data specified in *reg_data
    *
    * dev_addr: The slave device address.
    * Example: SLAVE_ADDR
    * reg_addr: The register or command to send to the slave.
    * Example: CMD_TYPE_0_MASTER
    * *reg_data: The buffer to write
    * Example: MasterType0
    * count: The length of *reg_data
    * Example: TYPE_0_LENGTH
    * */
    //I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);
    
    /* For slave device with dev_addr, read the data specified in slaves reg_addr.
    * The received data is available in ReceiveBuffer
    *
    * dev_addr: The slave device address.
    * Example: SLAVE_ADDR
    * reg_addr: The register or command to send to the slave.
    * Example: CMD_TYPE_0_SLAVE
    * count: The length of data to read
    * Example: TYPE_0_LENGTH
    * */
    I2C_Mode I2C_Master_ReadReg(uint8_t *buffer,uint8_t dev_addr, uint8_t reg_addr, uint8_t count);
    //void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    uint8_t *strcpy(uint8_t *destination, const uint8_t *source);
    I2C_Mode I2C_Master_ReadReg(uint8_t *buffer,uint8_t dev_addr, uint8_t reg_addr, uint8_t count)
    {
    /* Initialize state machine */
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;
    RXByteCtr = count;
    TXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;
    
    /* Initialize slave address and interrupts */
    UCB1I2CSA = dev_addr;
    UCB1IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts
    UCB1IE &= ~UCRXIE; // Disable RX interrupt
    UCB1IE |= UCTXIE; // Enable TX interrupt
    
    UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition 0001 0000 + 0000 0010
    __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
    
    strcpy(buffer,ReceiveBuffer);
    
    return MasterMode;
    
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
    /* Initialize state machine */
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;
    
    //Copy register data to TransmitBuffer
    CopyArray(reg_data, TransmitBuffer, count);
    
    TXByteCtr = count;
    RXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;
    
    /* Initialize slave address and interrupts */
    UCB1I2CSA = dev_addr;
    UCB1IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts
    UCB1IE &= ~UCRXIE; // Disable RX interrupt
    UCB1IE |= UCTXIE; // Enable TX interrupt
    
    UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
    __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
    
    return MasterMode;
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
    {
    uint8_t copyIndex = 0;
    for (copyIndex = 0; copyIndex < count; copyIndex++)
    {
    dest[copyIndex] = source[copyIndex];
    }
    }
    
    
    //******************************************************************************
    // Device Initialization *******************************************************
    //******************************************************************************
    
    void initClockTo16MHz()
    {
    UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO
    UCSCTL4 |= SELA_2; // Set ACLK = REFO
    __bis_SR_register(SCG0); // Disable the FLL control loop
    UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
    UCSCTL1 = DCORSEL_5; // Select DCO range 16MHz operation
    UCSCTL2 = FLLD_0 + 487; // Set DCO Multiplier for 16MHz
    // (N + 1) * FLLRef = Fdco
    // (487 + 1) * 32768 = 16MHz
    // Set FLL Div = fDCOCLK
    __bic_SR_register(SCG0); // Enable the FLL control loop
    
    // Worst-case settling time for the DCO when the DCO range bits have been
    // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
    // UG for optimization.
    // 32 x 32 x 16 MHz / 32,768 Hz = 500000 = MCLK cycles for DCO to settle
    __delay_cycles(500000);//
    // Loop until XT1,XT2 & DCO fault flag is cleared
    do
    {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG; // Clear fault flags
    }while (SFRIFG1&OFIFG); // Test oscillator fault flag
    }
    
    uint16_t setVCoreUp(uint8_t level){
    uint32_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
    
    //The code flow for increasing the Vcore has been altered to work around
    //the erratum FLASH37.
    //Please refer to the Errata sheet to know if a specific device is affected
    //DO NOT ALTER THIS FUNCTION
    
    //Open PMM registers for write access
    PMMCTL0_H = 0xA5;
    
    //Disable dedicated Interrupts
    //Backup all registers
    PMMRIE_backup = PMMRIE;
    PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE |
    SVSLPE | SVMHVLRIE | SVMHIE |
    SVSMHDLYIE | SVMLVLRIE | SVMLIE |
    SVSMLDLYIE
    );
    SVSMHCTL_backup = SVSMHCTL;
    SVSMLCTL_backup = SVSMLCTL;
    
    //Clear flags
    PMMIFG = 0;
    
    //Set SVM highside to new level and check if a VCore increase is possible
    SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level);
    
    //Wait until SVM highside is settled
    while((PMMIFG & SVSMHDLYIFG) == 0)
    {
    ;
    }
    
    //Clear flag
    PMMIFG &= ~SVSMHDLYIFG;
    
    //Check if a VCore increase is possible
    if((PMMIFG & SVMHIFG) == SVMHIFG)
    {
    //-> Vcc is too low for a Vcore increase
    //recover the previous settings
    PMMIFG &= ~SVSMHDLYIFG;
    SVSMHCTL = SVSMHCTL_backup;
    
    //Wait until SVM highside is settled
    while((PMMIFG & SVSMHDLYIFG) == 0)
    {
    ;
    }
    
    //Clear all Flags
    PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
    SVMLVLRIFG | SVMLIFG |
    SVSMLDLYIFG
    );
    
    //Restore PMM interrupt enable register
    PMMRIE = PMMRIE_backup;
    //Lock PMM registers for write access
    PMMCTL0_H = 0x00;
    //return: voltage not set
    return false;
    }
    
    //Set also SVS highside to new level
    //Vcc is high enough for a Vcore increase
    SVSMHCTL |= (SVSHRVL0 * level);
    
    //Wait until SVM highside is settled
    while((PMMIFG & SVSMHDLYIFG) == 0)
    {
    ;
    }
    
    //Clear flag
    PMMIFG &= ~SVSMHDLYIFG;
    
    //Set VCore to new level
    PMMCTL0_L = PMMCOREV0 * level;
    
    //Set SVM, SVS low side to new level
    SVSMLCTL = SVMLE | (SVSMLRRL0 * level) |
    SVSLE | (SVSLRVL0 * level);
    
    //Wait until SVM, SVS low side is settled
    while((PMMIFG & SVSMLDLYIFG) == 0)
    {
    ;
    }
    
    //Clear flag
    PMMIFG &= ~SVSMLDLYIFG;
    //SVS, SVM core and high side are now set to protect for the new core level
    
    //Restore Low side settings
    //Clear all other bits _except_ level settings
    SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 +
    SVSMLRRL1 + SVSMLRRL2
    );
    
    //Clear level settings in the backup register,keep all other bits
    SVSMLCTL_backup &=
    ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
    
    //Restore low-side SVS monitor settings
    SVSMLCTL |= SVSMLCTL_backup;
    
    //Restore High side settings
    //Clear all other bits except level settings
    SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 +
    SVSMHRRL0 + SVSMHRRL1 +
    SVSMHRRL2
    );
    
    //Clear level settings in the backup register,keep all other bits
    SVSMHCTL_backup &=
    ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
    
    //Restore backup
    SVSMHCTL |= SVSMHCTL_backup;
    
    //Wait until high side, low side settled
    while(((PMMIFG & SVSMLDLYIFG) == 0) &&
    ((PMMIFG & SVSMHDLYIFG) == 0))
    {
    ;
    }
    
    //Clear all Flags
    PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
    SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG
    );
    
    //Restore PMM interrupt enable register
    PMMRIE = PMMRIE_backup;
    
    //Lock PMM registers for write access
    PMMCTL0_H = 0x00;
    
    return true;
    }
    
    bool increaseVCoreToLevel2()
    {
    uint8_t level = 2;
    uint8_t actlevel;
    bool status = true;
    
    //Set Mask for Max. level
    level &= PMMCOREV_3;
    
    //Get actual VCore
    actlevel = PMMCTL0 & PMMCOREV_3;
    
    //step by step increase or decrease
    while((level != actlevel) && (status == true))
    {
    if(level > actlevel)
    {
    status = setVCoreUp(++actlevel);
    }
    }
    
    return (status);
    }
    
    
    void initI2C()
    {
    increaseVCoreToLevel2();
    P4SEL |= BIT1 + BIT2 ; // P4.1,2 option select
    UCB1CTL1 |= UCSWRST; // Enable SW reset
    UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
    UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
    UCB1BR0 = 80; // fSCL = SMCLK/160 = ~100kHz
    UCB1BR1 = 0;
    UCB1I2CSA = SLAVE_ADDR; // Slave Address is 048h
    UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
    UCB1IE |= UCNACKIE;
    }
    
    
    //******************************************************************************
    // I2C Interrupt ***************************************************************
    //******************************************************************************
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCI_B1_VECTOR
    __interrupt void USCI_B1_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    //Must read from UCB1RXBUF
    uint8_t rx_val = 0;
    
    switch(__even_in_range(UCB1IV,12))//12 or 0XC
    {
    
    case USCI_NONE:break; // Vector 0 - no interrupt
    case USCI_I2C_UCALIFG:break; // Interrupt Vector: I2C Mode: UCALIFG
    case USCI_I2C_UCNACKIFG:break; // Interrupt Vector: I2C Mode: UCNACKIFG
    case USCI_I2C_UCSTTIFG:break; // Interrupt Vector: I2C Mode: UCSTTIFG
    case USCI_I2C_UCSTPIFG:break; // Interrupt Vector: I2C Mode: UCSTPIFG
    case USCI_I2C_UCRXIFG:
    rx_val = UCB1RXBUF;
    if (RXByteCtr)
    {
    for(i = 0; i < 600; i++);
    ReceiveBuffer[ReceiveIndex++] = rx_val;
    RXByteCtr--;
    }
    
    if (RXByteCtr == 1)
    {
    UCB1CTL1 |= UCTXSTP;
    }
    else if (RXByteCtr == 0)
    {
    UCB1IE &= ~UCRXIE;
    MasterMode = IDLE_MODE;
    __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
    }
    break; // Interrupt Vector: I2C Mode: UCRXIFG
    case USCI_I2C_UCTXIFG:
    switch (MasterMode)
    {
    case TX_REG_ADDRESS_MODE:
    UCB1TXBUF = TransmitRegAddr;
    RXByteCtr = 0;
    if ( RXByteCtr)
    {
    MasterMode = SWITCH_TO_RX_MODE; // Need to start receiving now
    }
    else
    {
    MasterMode = TX_DATA_MODE; // Continue to transmission with the data in Transmit Buffer
    }
    break;
    
    case SWITCH_TO_RX_MODE:
    UCB1IE |= UCRXIE; // Enable RX interrupt
    UCB1IE &= ~UCTXIE; // Disable TX interrupt
    UCB1CTL1 &= ~UCTR; // Switch to receiver
    MasterMode = RX_DATA_MODE; // State state is to receive data
    UCB1CTL1 |= UCTXSTT; // Send repeated start
    if (RXByteCtr == 1)
    {
    //Must send stop since this is the N-1 byte
    while((UCB1CTL1 & UCTXSTT));
    UCB1CTL1 |= UCTXSTP; // Send stop condition
    }
    break;
    
    case TX_DATA_MODE:
    if (TXByteCtr)
    {
    for(i = 0; i < 1000; i++);
    UCB1TXBUF = TransmitBuffer[TransmitIndex++];
    TXByteCtr--;
    }
    else
    {
    //Done with transmission
    UCB1CTL1 |= UCTXSTP; // Send stop condition
    MasterMode = IDLE_MODE;
    UCB1IE &= ~UCTXIE; // disable TX interrupt
    __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
    }
    break;
    
    default:
    __no_operation();
    break;
    }
    break; // Interrupt Vector: I2C Mode: UCTXIFG
    default: break;
    }
    }
    
    

  • /* Modified Code  form B0 to B1 */

    //******************************************************************************
    // MSP430F552x Demo - USCI_B1, I2C Master multiple byte TX/RX
    
    //
    // Description: I2C master communicates to I2C slave sending and receiving
    // 3 different messages of different length. I2C master will enter LPM0 mode
    // while waiting for the messages to be sent/receiving using I2C interrupt.
    // ACLK = NA, MCLK = SMCLK = DCO 16MHz.
    //
    // /|\ /|\
    // MSP430F5529 4.7k |
    // ----------------- | 4.7k
    // /|\ | P3.1|---+---|-- I2C Clock (UCB1SCL)
    // | | | |
    // ---|RST P3.0|-------+-- I2C Data (UCB1SDA)
    // | |
    // | |
    // | |
    // | |
    // | |
    // | |
    //
    // Nima Eskandari
    // Texas Instruments Inc.
    // April 2017
    // Built with CCS V7.0
    //******************************************************************************
    
    #include <msp430.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    
    
    //******************************************************************************
    // Example Commands ************************************************************
    //******************************************************************************
    
    #define SLAVE_ADDR 0x10
    
    /* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
    * The slave will send example SlaveTypeX buffers in response.
    *
    * CMD_TYPE_X_MASTER are example commands the master sends to the slave.
    * The slave will initialize itself to receive MasterTypeX example buffers.
    * */
    
    #define CMD_TYPE_0_SLAVE 0
    #define CMD_TYPE_1_SLAVE 1
    #define CMD_TYPE_2_SLAVE 2
    
    #define CMD_TYPE_0_MASTER 3
    #define CMD_TYPE_1_MASTER 4
    #define CMD_TYPE_2_MASTER 5
    
    #define TYPE_0_LENGTH 1
    #define TYPE_1_LENGTH 2
    #define TYPE_2_LENGTH 6
    
    #define MAX_BUFFER_SIZE 10
    
    /* MasterTypeX are example buffers initialized in the master, they will be
    * sent by the master to the slave.
    * SlaveTypeX are example buffers initialized in the slave, they will be
    * sent by the slave to the master.
    * */
    
    uint8_t MasterType2 [TYPE_2_LENGTH] = {'F', '4', '1', '9', '2', 'B'};
    uint8_t MasterType1 [TYPE_1_LENGTH] = { 8, 9};
    uint8_t MasterType0 [TYPE_0_LENGTH] = { 11};
    
    
    uint8_t SlaveType2 [TYPE_2_LENGTH] = {0};
    uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
    
    int i = 0;
    //******************************************************************************
    // General I2C State Machine ***************************************************
    //******************************************************************************
    
    typedef enum I2C_ModeEnum{
    IDLE_MODE,
    NACK_MODE,
    TX_REG_ADDRESS_MODE,
    RX_REG_ADDRESS_MODE,
    TX_DATA_MODE,
    RX_DATA_MODE,
    SWITCH_TO_RX_MODE,
    SWITHC_TO_TX_MODE,
    TIMEOUT_MODE
    } I2C_Mode;
    
    /* Used to track the state of the software state machine*/
    I2C_Mode MasterMode = IDLE_MODE;
    
    /* The Register Address/Command to use*/
    uint8_t TransmitRegAddr = 0;
    
    /* ReceiveBuffer: Buffer used to receive data in the ISR
    * RXByteCtr: Number of bytes left to receive
    * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
    * TransmitBuffer: Buffer used to transmit data in the ISR
    * TXByteCtr: Number of bytes left to transfer
    * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
    * */
    uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 0;
    
    /* I2C Write and Read Functions */
    
    /* For slave device with dev_addr, writes the data specified in *reg_data
    *
    * dev_addr: The slave device address.
    * Example: SLAVE_ADDR
    * reg_addr: The register or command to send to the slave.
    * Example: CMD_TYPE_0_MASTER
    * *reg_data: The buffer to write
    * Example: MasterType0
    * count: The length of *reg_data
    * Example: TYPE_0_LENGTH
    * */
    //I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);
    
    /* For slave device with dev_addr, read the data specified in slaves reg_addr.
    * The received data is available in ReceiveBuffer
    *
    * dev_addr: The slave device address.
    * Example: SLAVE_ADDR
    * reg_addr: The register or command to send to the slave.
    * Example: CMD_TYPE_0_SLAVE
    * count: The length of data to read
    * Example: TYPE_0_LENGTH
    * */
    I2C_Mode I2C_Master_ReadReg(uint8_t *buffer,uint8_t dev_addr, uint8_t reg_addr, uint8_t count);
    //void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    uint8_t *strcpy(uint8_t *destination, const uint8_t *source);
    I2C_Mode I2C_Master_ReadReg(uint8_t *buffer,uint8_t dev_addr, uint8_t reg_addr, uint8_t count)
    {
    /* Initialize state machine */
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;
    RXByteCtr = count;
    TXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;
    
    /* Initialize slave address and interrupts */
    UCB1I2CSA = dev_addr;
    UCB1IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts
    UCB1IE &= ~UCRXIE; // Disable RX interrupt
    UCB1IE |= UCTXIE; // Enable TX interrupt
    
    UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition 0001 0000 + 0000 0010
    __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
    
    strcpy(buffer,ReceiveBuffer);
    
    return MasterMode;
    
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
    /* Initialize state machine */
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;
    
    //Copy register data to TransmitBuffer
    CopyArray(reg_data, TransmitBuffer, count);
    
    TXByteCtr = count;
    RXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;
    
    /* Initialize slave address and interrupts */
    UCB1I2CSA = dev_addr;
    UCB1IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts
    UCB1IE &= ~UCRXIE; // Disable RX interrupt
    UCB1IE |= UCTXIE; // Enable TX interrupt
    
    UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
    __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
    
    return MasterMode;
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
    {
    uint8_t copyIndex = 0;
    for (copyIndex = 0; copyIndex < count; copyIndex++)
    {
    dest[copyIndex] = source[copyIndex];
    }
    }
    
    
    //******************************************************************************
    // Device Initialization *******************************************************
    //******************************************************************************
    
    void initClockTo16MHz()
    {
    UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO
    UCSCTL4 |= SELA_2; // Set ACLK = REFO
    __bis_SR_register(SCG0); // Disable the FLL control loop
    UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
    UCSCTL1 = DCORSEL_5; // Select DCO range 16MHz operation
    UCSCTL2 = FLLD_0 + 487; // Set DCO Multiplier for 16MHz
    // (N + 1) * FLLRef = Fdco
    // (487 + 1) * 32768 = 16MHz
    // Set FLL Div = fDCOCLK
    __bic_SR_register(SCG0); // Enable the FLL control loop
    
    // Worst-case settling time for the DCO when the DCO range bits have been
    // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
    // UG for optimization.
    // 32 x 32 x 16 MHz / 32,768 Hz = 500000 = MCLK cycles for DCO to settle
    __delay_cycles(500000);//
    // Loop until XT1,XT2 & DCO fault flag is cleared
    do
    {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG; // Clear fault flags
    }while (SFRIFG1&OFIFG); // Test oscillator fault flag
    }
    
    uint16_t setVCoreUp(uint8_t level){
    uint32_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
    
    //The code flow for increasing the Vcore has been altered to work around
    //the erratum FLASH37.
    //Please refer to the Errata sheet to know if a specific device is affected
    //DO NOT ALTER THIS FUNCTION
    
    //Open PMM registers for write access
    PMMCTL0_H = 0xA5;
    
    //Disable dedicated Interrupts
    //Backup all registers
    PMMRIE_backup = PMMRIE;
    PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE |
    SVSLPE | SVMHVLRIE | SVMHIE |
    SVSMHDLYIE | SVMLVLRIE | SVMLIE |
    SVSMLDLYIE
    );
    SVSMHCTL_backup = SVSMHCTL;
    SVSMLCTL_backup = SVSMLCTL;
    
    //Clear flags
    PMMIFG = 0;
    
    //Set SVM highside to new level and check if a VCore increase is possible
    SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level);
    
    //Wait until SVM highside is settled
    while((PMMIFG & SVSMHDLYIFG) == 0)
    {
    ;
    }
    
    //Clear flag
    PMMIFG &= ~SVSMHDLYIFG;
    
    //Check if a VCore increase is possible
    if((PMMIFG & SVMHIFG) == SVMHIFG)
    {
    //-> Vcc is too low for a Vcore increase
    //recover the previous settings
    PMMIFG &= ~SVSMHDLYIFG;
    SVSMHCTL = SVSMHCTL_backup;
    
    //Wait until SVM highside is settled
    while((PMMIFG & SVSMHDLYIFG) == 0)
    {
    ;
    }
    
    //Clear all Flags
    PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
    SVMLVLRIFG | SVMLIFG |
    SVSMLDLYIFG
    );
    
    //Restore PMM interrupt enable register
    PMMRIE = PMMRIE_backup;
    //Lock PMM registers for write access
    PMMCTL0_H = 0x00;
    //return: voltage not set
    return false;
    }
    
    //Set also SVS highside to new level
    //Vcc is high enough for a Vcore increase
    SVSMHCTL |= (SVSHRVL0 * level);
    
    //Wait until SVM highside is settled
    while((PMMIFG & SVSMHDLYIFG) == 0)
    {
    ;
    }
    
    //Clear flag
    PMMIFG &= ~SVSMHDLYIFG;
    
    //Set VCore to new level
    PMMCTL0_L = PMMCOREV0 * level;
    
    //Set SVM, SVS low side to new level
    SVSMLCTL = SVMLE | (SVSMLRRL0 * level) |
    SVSLE | (SVSLRVL0 * level);
    
    //Wait until SVM, SVS low side is settled
    while((PMMIFG & SVSMLDLYIFG) == 0)
    {
    ;
    }
    
    //Clear flag
    PMMIFG &= ~SVSMLDLYIFG;
    //SVS, SVM core and high side are now set to protect for the new core level
    
    //Restore Low side settings
    //Clear all other bits _except_ level settings
    SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 +
    SVSMLRRL1 + SVSMLRRL2
    );
    
    //Clear level settings in the backup register,keep all other bits
    SVSMLCTL_backup &=
    ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
    
    //Restore low-side SVS monitor settings
    SVSMLCTL |= SVSMLCTL_backup;
    
    //Restore High side settings
    //Clear all other bits except level settings
    SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 +
    SVSMHRRL0 + SVSMHRRL1 +
    SVSMHRRL2
    );
    
    //Clear level settings in the backup register,keep all other bits
    SVSMHCTL_backup &=
    ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
    
    //Restore backup
    SVSMHCTL |= SVSMHCTL_backup;
    
    //Wait until high side, low side settled
    while(((PMMIFG & SVSMLDLYIFG) == 0) &&
    ((PMMIFG & SVSMHDLYIFG) == 0))
    {
    ;
    }
    
    //Clear all Flags
    PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
    SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG
    );
    
    //Restore PMM interrupt enable register
    PMMRIE = PMMRIE_backup;
    
    //Lock PMM registers for write access
    PMMCTL0_H = 0x00;
    
    return true;
    }
    
    bool increaseVCoreToLevel2()
    {
    uint8_t level = 2;
    uint8_t actlevel;
    bool status = true;
    
    //Set Mask for Max. level
    level &= PMMCOREV_3;
    
    //Get actual VCore
    actlevel = PMMCTL0 & PMMCOREV_3;
    
    //step by step increase or decrease
    while((level != actlevel) && (status == true))
    {
    if(level > actlevel)
    {
    status = setVCoreUp(++actlevel);
    }
    }
    
    return (status);
    }
    
    
    void initI2C()
    {
    increaseVCoreToLevel2();
    P4SEL |= BIT1 + BIT2 ; // P4.1,2 option select
    UCB1CTL1 |= UCSWRST; // Enable SW reset
    UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
    UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
    UCB1BR0 = 80; // fSCL = SMCLK/160 = ~100kHz
    UCB1BR1 = 0;
    UCB1I2CSA = SLAVE_ADDR; // Slave Address is 048h
    UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
    UCB1IE |= UCNACKIE;
    }
    
    
    //******************************************************************************
    // I2C Interrupt ***************************************************************
    //******************************************************************************
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCI_B1_VECTOR
    __interrupt void USCI_B1_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    //Must read from UCB1RXBUF
    uint8_t rx_val = 0;
    
    switch(__even_in_range(UCB1IV,12))//12 or 0XC
    {
    
    case USCI_NONE:break; // Vector 0 - no interrupt
    case USCI_I2C_UCALIFG:break; // Interrupt Vector: I2C Mode: UCALIFG
    case USCI_I2C_UCNACKIFG:break; // Interrupt Vector: I2C Mode: UCNACKIFG
    case USCI_I2C_UCSTTIFG:break; // Interrupt Vector: I2C Mode: UCSTTIFG
    case USCI_I2C_UCSTPIFG:break; // Interrupt Vector: I2C Mode: UCSTPIFG
    case USCI_I2C_UCRXIFG:
    rx_val = UCB1RXBUF;
    if (RXByteCtr)
    {
    for(i = 0; i < 600; i++);
    ReceiveBuffer[ReceiveIndex++] = rx_val;
    RXByteCtr--;
    }
    
    if (RXByteCtr == 1)
    {
    UCB1CTL1 |= UCTXSTP;
    }
    else if (RXByteCtr == 0)
    {
    UCB1IE &= ~UCRXIE;
    MasterMode = IDLE_MODE;
    __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
    }
    break; // Interrupt Vector: I2C Mode: UCRXIFG
    case USCI_I2C_UCTXIFG:
    switch (MasterMode)
    {
    case TX_REG_ADDRESS_MODE:
    UCB1TXBUF = TransmitRegAddr;
    RXByteCtr = 0;
    if ( RXByteCtr)
    {
    MasterMode = SWITCH_TO_RX_MODE; // Need to start receiving now
    }
    else
    {
    MasterMode = TX_DATA_MODE; // Continue to transmission with the data in Transmit Buffer
    }
    break;
    
    case SWITCH_TO_RX_MODE:
    UCB1IE |= UCRXIE; // Enable RX interrupt
    UCB1IE &= ~UCTXIE; // Disable TX interrupt
    UCB1CTL1 &= ~UCTR; // Switch to receiver
    MasterMode = RX_DATA_MODE; // State state is to receive data
    UCB1CTL1 |= UCTXSTT; // Send repeated start
    if (RXByteCtr == 1)
    {
    //Must send stop since this is the N-1 byte
    while((UCB1CTL1 & UCTXSTT));
    UCB1CTL1 |= UCTXSTP; // Send stop condition
    }
    break;
    
    case TX_DATA_MODE:
    if (TXByteCtr)
    {
    for(i = 0; i < 1000; i++);
    UCB1TXBUF = TransmitBuffer[TransmitIndex++];
    TXByteCtr--;
    }
    else
    {
    //Done with transmission
    UCB1CTL1 |= UCTXSTP; // Send stop condition
    MasterMode = IDLE_MODE;
    UCB1IE &= ~UCTXIE; // disable TX interrupt
    __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
    }
    break;
    
    default:
    __no_operation();
    break;
    }
    break; // Interrupt Vector: I2C Mode: UCTXIFG
    default: break;
    }
    }
    
    

  • Hi Veerenda,

    as mentioned before, I think it actually makes sense to discuss the general firmware flow understanding before having a look at the code.
    There are several ways to make sure to set up the USCI module correctly, such as reviewing the important settings in the device family User's Guide or, as you've done, look at the example code.
    It might help you to debug the example code using module B0, to understand which settings are specific to the module you want to use, and than adapt it to the module of choice B1.
    I think you've gone a long way already. Could you please let me know where exactly you're having issues. Best way would be to debug the code and let me know where exactly you observe unintended behavior. Please don't just post extensive code without any comment or explanation as I won't know what you'll need from me.

    Best regards,
    Britta
  • Hi Veerenda,

    as I didn't hear back from you I assume that the issue has been solved on your end.
    Please note that I'm closing this thread but that replying back to it will re-open it if needed.

    Best regards,
    Britta
  • Hello , actually my requirement is to change I2C pin from 3.0 and 3.1 to 4.1 and 4.2 (means UCB0_I2C to UCB1_I2C )that all i want, for that i have already shared you B0 code as well as B1 Code also...
  • Hi Veerenda,

    yes, I know that you want to switch from UCB0 to UCB1 and I saw in the code you've shared that you've adapted the example code.
    Still, could you share where you're seeing issues? Did you debug your code and see unintended behavior? If so, what happens? As I've mentioned before please let me know where you're currently stuck so that I can dig deeper into it.

    Best regards,
    Britta
  • Hello TI team  Very good morning,... here i'm facing problem  in ISR  Function actually it should check the cases until last byte of data (switch case means Mode of operation like tx/rx mode or TX_DATA_MODE /SWITCH_TO_RX_MODE)but only one time its checking and it coming out of the switch.... i have mentioned ----- *1* like this in code you can check below...  




    __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 { //Must read from UCB0RXBUF uint8_t rx_val = 0; switch(__even_in_range(UCB0IV,12))//12 or 0XC { case USCI_NONE:break; // Vector 0 - no interrupt case USCI_I2C_UCALIFG:break; // Interrupt Vector: I2C Mode: UCALIFG case USCI_I2C_UCNACKIFG:break; // Interrupt Vector: I2C Mode: UCNACKIFG case USCI_I2C_UCSTTIFG:break; // Interrupt Vector: I2C Mode: UCSTTIFG case USCI_I2C_UCSTPIFG:break; // Interrupt Vector: I2C Mode: UCSTPIFG case USCI_I2C_UCRXIFG: rx_val = UCB0RXBUF; if (RXByteCtr) { for(i = 0; i < 600; i++); ReceiveBuffer[ReceiveIndex++] = rx_val; RXByteCtr--; } if (RXByteCtr == 1) { UCB0CTL1 |= UCTXSTP; } else if (RXByteCtr == 0) { UCB0IE &= ~UCRXIE; MasterMode = IDLE_MODE; __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } break; // Interrupt Vector: I2C Mode: UCRXIFG case USCI_I2C_UCTXIFG: switch (MasterMode) { case TX_REG_ADDRESS_MODE: UCB0TXBUF = TransmitRegAddr; RXByteCtr = 0; if ( RXByteCtr) { MasterMode = SWITCH_TO_RX_MODE; // Need to start receiving now } else { MasterMode = TX_DATA_MODE; // Continue to transmission with the data in Transmit Buffer } break; case SWITCH_TO_RX_MODE: UCB0IE |= UCRXIE; // Enable RX interrupt UCB0IE &= ~UCTXIE; // Disable TX interrupt UCB0CTL1 &= ~UCTR; // Switch to receiver MasterMode = RX_DATA_MODE; // State state is to receive data UCB0CTL1 |= UCTXSTT; // Send repeated start if (RXByteCtr == 1) { //Must send stop since this is the N-1 byte while((UCB0CTL1 & UCTXSTT)); UCB0CTL1 |= UCTXSTP; // Send stop condition } break; case TX_DATA_MODE: if (TXByteCtr) { for(i = 0; i < 1000; i++); UCB0TXBUF = TransmitBuffer[TransmitIndex++]; TXByteCtr--; } else { //Done with transmission UCB0CTL1 |= UCTXSTP; // Send stop condition MasterMode = IDLE_MODE; UCB0IE &= ~UCTXIE; // disable TX interrupt __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } break; default: __no_operation(); break; } break; // Interrupt Vector: I2C Mode: UCTXIFG default: break; }//---------------------------------------------------------------------------------------------------------------------------------------------------- * 1 * //here its directly coming down in first execution only }

  • Hi Veerenda,

    your isr is still configured for UCB0. Do you also see the issue after adapting the interrupt service routine to UCB1?
    Let me know in case you see the same behavior after replacing every UCB0xxx with UCB1xxx.
    If I misunderstood your question I apologize and might need further explanation. Thanks.

    Best regards,
    Britta
  • Everything  i have changed in place of  B0 , i have replaced B1 even though its not working please try to understand once again im telling you in place of B0 i have replaced  with B1 and i have changed Pins also like P3.0,P3.1 changed to P4.1 and P4.2  also...

  • Ok, assuming that in the code shown above everything related to B0 is replaced with B1 your issues are as follows:

    1) The cases are only checked for one byte (not for all bytes until the last bytes) and

    2) the switch jumps to the default case.

    Did you single step your application and have you verified that the flag you're expecting is actually set?

    Could it be that the flags you'd expect are reset? Please check section 38.3.7 of the User's Guide if this could be happening.

    With regards to 1): Could you explain what you'd like the firmware to do? The switch cases will be checked depending on the interrupt flag. You might want to have a look at the following code snippet from your code above:

    rx_val = UCB0RXBUF;
            if (RXByteCtr)
            {
              for(i = 0; i < 600; i++);
              ReceiveBuffer[ReceiveIndex++] = rx_val;
              RXByteCtr--;
            }

    Please check if you really want the delay loop or if you want to fill the ReceiveBuffer? You might need to remove the semicolon in the ladder case,

    Could you please confirm that your application never jumps into any case except the default? Is this true. I understand this is tiring for you but I'd really ask to give a detailed description of the issue you're seeing, best would be to describe the behavior you seeing when stepping through the application.

    Thanks a lot,

    Britta

  • Hi Veerenda,

    I assume that your issue has been solved as I didn't hear back from you anymore.
    Please ask a related question in a new post in case another question comes up.
    Let me know if you need anything else.

    Thanks and best regards,
    Britta

**Attention** This is a public forum