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.

CCS/MSP430F5529: Sample code for BOOSTXL-BATPAKMKII on MSP430F5529

Part Number: MSP430F5529
Other Parts Discussed in Thread: BOOSTXL-BATPAKMKII, MSP430FR6989

Tool/software: Code Composer Studio

Dear all, I recently bought the BOOSTXL-BATPAKMKII for my launchpad project (MSP430F5529). I realise that the sample code only works for MSP-EXP432P401R. I have been trying to find sample code for my specific launchpad for the past 1 week and I can't find any. I know I can try to code my own but I don't think I have the skill to code them now. Really need help with the development. If you have any sample code that works with MSP430F5529 and BATPAKMKII please share with me. I tried looking through the code for MSP432P401R but I don't understand it well enough to port the code over so that it works on MSP430F5529 as well. 

Any help is appreciated. I am really desperate as it's for my final year project. 

  • Hello,

    As you have already seen, example code for BOOSTXL-BATPAKMKII is only provided for the MSP432P401R. You can find some resources online that can assist you in porting code between MSP430 and MSP432 but it will involve a fair amount of work due to core architectural differences. By looking at Table 5 of the MSP432 Platform Porting Guide (SLAA656), you can see all of the differences that need to be addressed:

    Taking advantage of Driverlib APIs where possible will make the process a little easier.

    Best regards,

    Matt Calvo

  • Hello,

    I have reached out to the SW team for the BOOSTXL-BATPAKMKII and there is example code released for the MSP430FR6989 on the TI Resource Explorer ( dev.ti.com/.../ ).

    This example will allow you to get a much better head start on porting the code over to whatever MSP430 device you'd like to interface with the Booster-Pack. Another option would be to purchase the MSP430FR6989 Launchpad to immediately get started working with the Booster-Pack without having to port any code. Hopefully this helps you move forward on your project!

    If support for this thread is complete, please go ahead and select "Resolved" so we can close this thread out.

    Thanks and best regards,

    Matt Calvo
  • Hi thank you for the assistance I really appreciate the help. Example for MSP430FR6989 is a closer match MSP430F5529. However, I understand that in the example code of the MSP430FR6989 it uses EUSCI and in MSP430F5529 it only has USCI. I did a some research and found out that there isn't much difference between EUSCI and USCI even for the syntax it is almost the same. So to port the code over to fit the MSP430F5529 I basically change all EUSCI function to USCI change the port and pin allocation to fit the one on my target board and reprogrammed the clocksource specific to MSP430F5529. The UART works perfectly however, the I2C segment of the code did not work well. 

    The Freq that I need it to operate at is: 400khz

    I put it on an oscilloscope and found that there isn't any acknowledgement from the slave and but I could observe I2C signal coming out

    I narrowed it down to a few reasons

    1. When converting the EUSCI to USCI I2C I might have initialised the I2c wrongly.

    2. my clock initialisation might be wrong as well. 

    So sorry to trouble you on this as I am very new to microcontroller I would need your help to look through the code for me and see if you could spot any error. 

    ClocK Initialisation:

    //#include <stdbool.h>
    #include <driverlib.h>
    #include "myClocks.h"
    
    
    //***** Defines ***************************************************************
    #define LF_CRYSTAL_FREQUENCY_IN_HZ     32768                                    // 32KHz
    #define HF_CRYSTAL_FREQUENCY_IN_HZ     4000000                                  // 4MHz
    
    #define MCLK_DESIRED_FREQUENCY_IN_KHZ  8000                                     // 8MHz
    #define MCLK_FLLREF_RATIO              MCLK_DESIRED_FREQUENCY_IN_KHZ / ( UCS_REFOCLK_FREQUENCY / 1024 )    // Ratio = 250
    
    
    //***** Global Variables ******************************************************
    uint32_t myACLK  = 0;
    uint32_t mySMCLK = 0;
    uint32_t myMCLK  = 0;
    
    
    //***** initClocks ************************************************************
    void initClocks(void) {
    
        //**************************************************************************
        // Configure core voltage level
        //**************************************************************************
         // Set core voltage level to handle 8MHz clock rate
         PMM_setVCore( PMM_CORE_LEVEL_1 );
    
    
        //**************************************************************************
        // Configure Oscillators
        //**************************************************************************
        // Set the XT1/XT2 crystal frequencies used on the LaunchPad, and connected
    	// to the clock pins, so that driverlib knows how fast they are (these are 
        // needed for the DriverLib clock 'get' and crystal start functions)
        UCS_setExternalClockSource(
                LF_CRYSTAL_FREQUENCY_IN_HZ,                                         // XT1CLK input
                HF_CRYSTAL_FREQUENCY_IN_HZ                                          // XT2CLK input
        );
    
        // Verify if the default clock settings are as expected
        myACLK  = UCS_getACLK();
        mySMCLK = UCS_getSMCLK();
        myMCLK  = UCS_getMCLK();
    
    
    
        //**************************************************************************
        // Configure Clocks
        //**************************************************************************
        // Set ACLK to use REFO as its oscillator source (32KHz)
        UCS_initClockSignal(
                UCS_ACLK,                                    // Clock you're configuring
                UCS_REFOCLK_SELECT,                          // Clock source
                UCS_CLOCK_DIVIDER_1                          // Divide down clock source by this much
        );
    
        // Set REFO as the oscillator reference clock for the FLL
        UCS_initClockSignal(
                UCS_FLLREF,                                  // Clock you're configuring
                UCS_REFOCLK_SELECT,                          // Clock source
                UCS_CLOCK_DIVIDER_1                          // Divide down clock source by this much
        );
    
        // Set MCLK and SMCLK to use the DCO/FLL as their oscillator source (8MHz)
    	// The function does a number of things: Calculates required FLL settings; Configures FLL and DCO,
    	// and then sets MCLK and SMCLK to use the DCO (with FLL runtime calibration)
        UCS_initFLLSettle(
                MCLK_DESIRED_FREQUENCY_IN_KHZ,               // MCLK frequency
                MCLK_FLLREF_RATIO                            // Ratio between MCLK and FLL's reference clock source
        );
    
    //    // Optional lab step set MCLK to run from REFO
    //    // This will make the LED blink very sloooowly in our while{} loop
    //    UCS_initClockSignal( UCS_BASE,
    //            UCS_MCLK,                                    // Clock you're configuring
    //            UCS_REFOCLK_SELECT,                          // Clock source
    //            UCS_CLOCK_DIVIDER_1                          // Divide down clock source by this much
    //    );
    
        // Verify that the modified clock settings are as expected
        myACLK  = UCS_getACLK();
        mySMCLK = UCS_getSMCLK();
        myMCLK  = UCS_getMCLK();
    }



    I2C initialisation

    #include <driverlib.h>
    #include "HAL_I2C.h"

    #define I2C_BASE            USCI_B1_BASE
    
    #define I2C_SCL_PORT        GPIO_PORT_P4
    #define I2C_SCL_PIN         GPIO_PIN2
    
    #define I2C_SDA_PORT        GPIO_PORT_P4
    #define I2C_SDA_PIN         GPIO_PIN1

    #include <driverlib.h>
    #include "HAL_I2C.h"
    
    
    ///* I2C Master Configuration Parameter */
    //USCI_B_I2C_initMasterParam i2cParam =
    //{
    //        USCI_B_I2C_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
    //		8000000,                           // SMCLK = 8MHz
    //        USCI_B_I2C_SET_DATA_RATE_400KBPS,      // Desired I2C Clock of 400khz
    //        0                                      // No byte counter threshold
    //        //*USCI_B_I2C_NO_AUTO_STOP                // No Autostop
    //};
    
    
    void I2C_initGPIO()
    {
        /* Select I2C function for I2C_SCL & I2C_SDA */
        GPIO_setAsPeripheralModuleFunctionOutputPin(
        		I2C_SCL_PORT,
    			I2C_SCL_PIN);
    
        GPIO_setAsPeripheralModuleFunctionOutputPin(
        		I2C_SDA_PORT,
    			I2C_SDA_PIN);
        //P4SEL |= BIT1 + BIT2;
    }
    
    
    /***************************************************************************//**
     * @brief  Configures I2C
     * @param  none
     * @return none
     ******************************************************************************/
    
    void I2C_init(void)
    {
        USCI_B_I2C_initMasterParam param = {0};
        param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK;
        param.i2cClk = UCS_getSMCLK();
        param.dataRate = USCI_B_I2C_SET_DATA_RATE_400KBPS;
            /* Initialize USCI_B0 and I2C Master to communicate with slave devices*/
        //USCI_B_I2C_initMaster(I2C_BASE, &i2cParam);
        USCI_B_I2C_initMaster(I2C_BASE, &param);
    
        /* Disable I2C module to make changes */
        USCI_B_I2C_disable(I2C_BASE);
    
        /* Enable I2C Module to start operations */
        USCI_B_I2C_enable(I2C_BASE);
    
        return;
    }
    
    
    /***************************************************************************//**
     * @brief  Writes data to the sensor
     * @param  pointer  Address of register you want to modify
     * @param  writeByte Data to be written to the specified register
     * @return none
     ******************************************************************************/
    
    bool I2C_write8 (unsigned char pointer, unsigned char writeByte, unsigned int timeout)
    {
        /* Set master to transmit mode PL */
    	USCI_B_I2C_setMode(I2C_BASE,
            USCI_B_I2C_TRANSMIT_MODE);
    
        /* Clear any existing interrupt flag PL */
    	USCI_B_I2C_clearInterrupt(I2C_BASE,
            USCI_B_I2C_TRANSMIT_INTERRUPT);
    
        /* Initiate start and send first character */
        if (!USCI_B_I2C_masterSendMultiByteStartWithTimeout(I2C_BASE,
            pointer, timeout))
        	return 0;
    
        if (!USCI_B_I2C_masterSendMultiByteFinishWithTimeout(I2C_BASE,
            writeByte, timeout))
        	return 0;
    
        return 1;
    }
    
    
    /***************************************************************************//**
     * @brief  Writes data to the sensor
     * @param  pointer  Address of register you want to modify
     * @param  writeWord Data to be written to the specified register
     * @return none
     ******************************************************************************/
    
    bool I2C_write16 (unsigned char pointer, unsigned short writeWord, unsigned int timeout)
    {
        /* Set master to transmit mode PL */
    	USCI_B_I2C_setMode(I2C_BASE,
            USCI_B_I2C_TRANSMIT_MODE);
    
        /* Clear any existing interrupt flag PL */
    	USCI_B_I2C_clearInterrupt(I2C_BASE,
            USCI_B_I2C_TRANSMIT_INTERRUPT);
    
        /* Initiate start and send first character */
        if (!USCI_B_I2C_masterSendMultiByteStartWithTimeout(I2C_BASE,
            pointer, timeout))
        	return 0;
    
        /* Send the MSB of writeByte to SENSOR */
        if (!USCI_B_I2C_masterSendMultiByteNextWithTimeout(I2C_BASE,
            (unsigned char)(writeWord&0xFF), timeout))
        	return 0;
    
        if (!USCI_B_I2C_masterSendMultiByteFinishWithTimeout(I2C_BASE,
            (unsigned char)(writeWord>>8), timeout))
        	return 0;
    
        return 1;
    }
    
    
    /***************************************************************************//**
     * @brief  Reads data from the sensor
     * @param  pointer Address of register to read from
     * @return Register contents
     ******************************************************************************/
    
    bool I2C_read8(unsigned char pointer, char * result, unsigned int timeout)
    {
    	volatile int val = 0;
    	volatile int valScratch = 0;
    
        /* Set master to transmit mode PL */
    	USCI_B_I2C_setMode(I2C_BASE,
            USCI_B_I2C_TRANSMIT_MODE);
    
        /* Clear any existing interrupt flag PL */
    	USCI_B_I2C_clearInterrupt(I2C_BASE,
            USCI_B_I2C_TRANSMIT_INTERRUPT);
    
        /* Initiate start and send first character */
        if (!USCI_B_I2C_masterSendSingleByteWithTimeout(I2C_BASE,
            pointer, timeout))
        	return 0;
    
        /*
         * Generate Start condition and set it to receive mode.
         * This sends out the slave address and continues to read
         * until you issue a STOP
         */
    //    I2C_masterReceiveStart(I2C_BASE);
    //
    //    /* Read from I2C RX register */
    //    if(!I2C_masterReceiveMultiByteFinishWithTimeout(I2C_BASE, &val, timeout))
    //    	return 0;
    //
    //    /* Return temperature value */
    //    *result = val;
    
        *result = USCI_B_I2C_masterReceiveSingle(I2C_BASE);
    
        return 1;
    }
    
    
    /***************************************************************************//**
     * @brief  Reads data from the sensor
     * @param  pointer Address of register to read from
     * @return Register contents
     ******************************************************************************/
    
    bool I2C_read16(unsigned char pointer, short * result, unsigned int timeout)
    {
        uint8_t val = 0;
        uint8_t valScratch = 0;
        short r = 0;
    
        /* Set master to transmit mode PL */
        USCI_B_I2C_setMode(I2C_BASE,
            USCI_B_I2C_TRANSMIT_MODE);
    
        /* Clear any existing interrupt flag PL */
        USCI_B_I2C_clearInterrupt(I2C_BASE,
            USCI_B_I2C_TRANSMIT_INTERRUPT);
    
        /* Initiate start and send first character */
        if (!USCI_B_I2C_masterSendSingleByteWithTimeout(I2C_BASE, pointer, timeout))
        	return 0;
    
        /*
         * Generate Start condition and set it to receive mode.
         * This sends out the slave address and continues to read
         * until you issue a STOP
         */
        USCI_B_I2C_masterReceiveSingleStart(I2C_BASE);
    
        /* Wait for RX buffer to fill */
        while(!(USCI_B_I2C_getInterruptStatus(I2C_BASE,
            USCI_B_I2C_RECEIVE_INTERRUPT)));
    
        /* Read from I2C RX register */
        valScratch = USCI_B_I2C_masterReceiveMultiByteNext(I2C_BASE);
    
        /* Receive second byte then send STOP condition */
        if (!USCI_B_I2C_masterReceiveMultiByteFinishWithTimeout(I2C_BASE, &val, timeout))
        	return 0;
    
        /* Shift val to top MSB */
        r = (val << 8);
    
        /* Read from I2C RX Register and write to LSB of r */
        r |= valScratch;
    
        /* Return temperature value */
        *result = r;
    
        return 1;
    }
    
    
    void I2C_setslave(unsigned short slaveAdr)
    {
        /* Specify slave address for I2C */
    	USCI_B_I2C_setSlaveAddress(I2C_BASE,
            slaveAdr);
    
        /* Enable and clear the interrupt flag */
    	USCI_B_I2C_clearInterrupt(I2C_BASE,
            USCI_B_I2C_TRANSMIT_INTERRUPT + USCI_B_I2C_RECEIVE_INTERRUPT);
        return;
    }

    In the programme a typical I2C read will call for the following functions stated below

     
    bool BQ27441_read16(short stdcommand, short *result, unsigned int timeout)
    {
    	I2C_init();
    
    	/* Specify slave address for BQ27441 */
    	I2C_setslave(BQ27441_SLAVE_ADDRESS);
    
    	if (!I2C_read16(stdcommand, result, timeout))
    		return 0;
    
    	return 1;
    }

    
    

  • Hello,

    I am glad to see that you have made progress in porting the code over from the FR6989 to the F5529. It is definitely best to work in steps and ensuring that each module that is converted is working before moving on to the next one, which is what you seem to be doing successfully. It sounds like there might be some sort of communication mismatch between the I2C master and slave.

    Since you have a working example code that has been tested to operate successfully on an MSP430FR6989 Launchpad, it is in your best interest to make sure that you use it as a guideline when coding your MSP430F5529 I2C and clock initialization and implementation. One resource that may help you determine what the possible bug could be is the App Report that focuses on Solutions to Common eUSCI and USCI Serial
    Communication Issues on MSP430™ MCUs ( www.ti.com/.../slaa734.pdf ).

    -Matt
  • Hello,

    Please let us know if there are any updates to this thread. If support is completed please go ahead and select "Resolved" so we can close this thread out and log it. Thank you for your help!

    Best regards,

    Matt Calvo

**Attention** This is a public forum