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.

【TI 测评】TI-MSP432P401R LanchPad评测 I2C采样加速度传感器计步功能及OLED显示

Other Parts Discussed in Thread: MSP432WARE

         很荣幸在21IC论坛活动中获得一块MSP432P401R LanchPad。拿到开发板后,先搭建开发环境,MSP432P401R可在CCS、KEIL、IAR 3个IDE平台都可开发,这里选择了比较熟悉的KEIL。并对MSP432P401R的SDK进行熟悉。

         刚好手头有一块带6轴LSM6DSO传感器的板子和一块0.96寸的OLED屏,两个都可通过I2C进行通讯。LSM6DSO传感器自带计步功能,既通过中断通知计步事件,也可以通过读取对应的寄存器获得。那就做一个计步功能,来测试MSP432P401R的I2C功能。

         下图是I2C的框架图

        MSP432P401R的I2C模块包括下列功能:

7位和10位设备寻址模式

启动、重启和停止

多主发射机/接收机模式

从接收机/发射机模式

支持高达100 Kbps的标准模式、高达400 Kbps的快速模式和高达1 Mbps的快速模式

主模式下可编程UCXCLK频率

专为低功耗设计

具有中断能力和自动停止断言的8位字节计数器

多达四个硬件从地址,每个都有自己的中断和DMA触发器

从机地址和地址接收中断的屏蔽寄存器

时钟低超时中断,以避免总线暂停

 

I2C模块的功能非常丰富。此次评测只使用I2C的基本功能。

硬件连接为SCL -- P1.7,SDA -- P1.6,gpio中断 -- P5.0。

 

 

 

/* DriverLib Includes */

#include <ti/devices/msp432p4xx/driverlib/driverlib.h>

 

/* Standard Includes */

#include <stdint.h>

#include <stdbool.h>

#include "i2c_driver.h"

#include "oled_i2c.h"

#include "Lsm6dso.h"

 

#define system_jump_time     1000    //   1/system_jump_time = 1ms

 

/* Slave Address for I2C Slave */

#define SLAVE_ADDRESS_1 0x48

#define SLAVE_ADDRESS_2 0x49

#define NUM_OF_REC_BYTES   10

 

#define I2C_DELAY           50

 

 

uint32_t i, j;

uint32_t pedometerCnt, pedometerCntOld = 0xffffffff;

static uint8_t index, indexOld = 0xff;

 

//一次滴答中断的tick数

uint32_t System_tick_num;

static uint32_t delayCnt = 0xffffffff, delayTarget = 0;

static uint8_t delayFinFlag = 0;

 

static volatile uint8_t Lsm6dsoEventDetected = 0;

uint8_t pedoFlag = 0;

 

//

void pedometerShow(void);

 

 

 

void MCU_Init()

{



// Set P1.0 to output direction

GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);

 

/* Configuring P1.1 as an input and enabling interrupts */

MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1);

MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1);

MAP_GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1);

MAP_Interrupt_enableInterrupt(INT_PORT1);

 

/* Configuring P1.1 as an input and enabling interrupts */

MAP_GPIO_setAsInputPinWithPullDownResistor(GPIO_PORT_P5, GPIO_PIN0);

MAP_GPIO_clearInterruptFlag(GPIO_PORT_P5, GPIO_PIN0);

MAP_GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN0);

MAP_Interrupt_enableInterrupt(INT_PORT5);



/* Enabling SRAM Bank Retention */

MAP_SysCtl_enableSRAMBankRetention(SYSCTL_SRAM_BANK1);



/* Enabling MASTER interrupts */

MAP_Interrupt_enableMaster();

}

 

 

void SysTick_Init(void)

{

         /* Setup SysTick Timer for 10ms interrupts */

         System_tick_num = SystemCoreClock / system_jump_time;

         if (SysTick_Config(System_tick_num))

         {

//   OLED_ShowStr(1, 3, "SysTick err", 2);

//   OLED_ON();//OLED唤醒

                   while (1);

         }

 

}

 

 

void delayMS(uint32_t num)

{

delayTarget = num;

delayCnt = 0;

delayFinFlag = 0;

while(!delayFinFlag);

}

 

 

int main(void)

{

/* Disabling the Watchdog */

MAP_WDT_A_holdTimer();



MCU_Init();

SysTick_Init();

BSP_I2C_Init();

 

for(i = 0; i < 4; i++)

{

   // Toggle P1.0 output

   GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);

 

   delayMS(250);

}



OLED_Init();





if(0 == Lsm6dso_Init())

{

   OLED_ShowStr(0, 1, "PEDOMETER :", 1);

}

else

{

   OLED_ShowStr(1, 3, "Lsm6dso err", 2);

   OLED_ON();//OLED唤醒

   while(1);

}



pedometerCnt = 0;



while(1)

{

   if(Lsm6dsoEventDetected)

   {

     Lsm6dsoEventDetected = 0;

     if(RET_OK == Get_Lsm6dso_Event(&pedoFlag))

     {

       pedoFlag = 0;

       pedometerCnt++;

     }

   }

   pedometerShow();

}

}

 

void SysTick_Handler(void)

{

if(delayCnt < delayTarget)

{

   delayCnt++;

   if(delayCnt >= delayTarget)

   {

     delayFinFlag = 1;

   }

}

}

 

 

void pedometerShow()

{

stOledShow currRow;

uint32_t pedometerCntShow;



if(pedometerCntOld == pedometerCnt)

{

   return;

}



pedometerCntOld = pedometerCnt;

pedometerCntShow = pedometerCnt;



index = 0;

currRow.str[MAX_ROW_STR_NUM] = 0x0;

while(pedometerCntShow > 9)

{

   index++;

   currRow.str[MAX_ROW_STR_NUM - index] = (pedometerCntShow % 10) + 0x30;

   pedometerCntShow /= 10;

}

index++;

if(index > MAX_PEDOMETER_INDEX)

{

   index = 1;

   currRow.str[MAX_ROW_STR_NUM - index] = 0x21;

   index++;

   currRow.str[MAX_ROW_STR_NUM - index] = 0x4c;

   index++;

   currRow.str[MAX_ROW_STR_NUM - index] = 0x6e;

   index++;

   currRow.str[MAX_ROW_STR_NUM - index] = 0x6e;

   index++;

   currRow.str[MAX_ROW_STR_NUM - index] = 0x41;

}

else

{

   currRow.str[MAX_ROW_STR_NUM - index] = (pedometerCntShow % 10) + 0x30;

}

if(indexOld != index)

{

   indexOld = index;

   currRow.x = 0;

   currRow.y = 2;

   OLED_Fill_Line(currRow.y, 0x0);

   OLED_Fill_Line(currRow.y+1, 0x0);

   OLED_Fill_Line(currRow.y+2, 0x0);

   OLED_Fill_Line(currRow.y+3, 0x0);

}

currRow.y = 3;

currRow.TextSize = 4;

currRow.x = (ROW_PIXEL - 16 * index) / 2;

OLED_ShowStr(currRow.x, currRow.y, &currRow.str[MAX_ROW_STR_NUM - index], currRow.TextSize);

}

 

/* GPIO ISR */

void PORT1_IRQHandler(void)

{

   uint32_t status;

 

   status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);

   MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status);

 

   /* Toggling the output on the LED */

   if(status & GPIO_PIN1)

 {

//       MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);

     pedometerCnt = 0;

   }

 

}

 

/* GPIO ISR */

void PORT5_IRQHandler(void)

{

   uint32_t status;

 

   status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P5);

   MAP_GPIO_clearInterruptFlag(GPIO_PORT_P5, status);

 

   /* Toggling the output on the LED */

   if(status & GPIO_PIN0)

   {

//     if(GPIO_INPUT_PIN_HIGH == GPIO_getInputPinValue(GPIO_PORT_P5, GPIO_PIN0))

     {

         Lsm6dsoEventDetected = 1;

     }

   }

}

 

 

I2C调试期间遇到了很多问题,也参考了E2E上帖子解决了问题(具体的网页一时找不到了)。这里把驱动文件上传上来,可供大家参考。

0167.i2c_driver.c
//*****************************************************************************
//
// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  Redistributions of source code must retain the above copyright
//  notice, this list of conditions and the following disclaimer.
//
//  Redistributions in binary form must reproduce the above copyright
//  notice, this list of conditions and the following disclaimer in the
//  documentation and/or other materials provided with the
//  distribution.
//
//  Neither the name of Texas Instruments Incorporated nor the names of
//  its contributors may be used to endorse or promote products derived
//  from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//****************************************************************************

//************************MODIFICATON INFORMATION*****************************
//Modified from original source located at:
// https://e2e.ti.com/support/microcontrollers/msp430/f/166/p/472504/1701554#1701554
//
//Modifed by Reid Kersey, CEO, Sniffer GPS - 7/19/2017
//  sniffergps.com
//  reid@sniffergps.com
//  678-209-2215
//
//Updates:
//6/7/2017
//Changed EUSCI_Bx_MODULE to EUSCI_Bx_BASE
//Changed from using B1 to allowing use of any Bx Module
//Added funciton description comments

//7/19/2017
//removed slow speed bug on B2 and B3

//Feel free to contact me about modifications to this code or questions about usage,
//however I am not the original author. Credit goes to DavidL https://e2e.ti.com/members/2005340

#include "msp432.h"
#include "i2c_driver.h"
//#include "driverlib.h"
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>

//*****************************************************************************
//
// Definitions
//
//*****************************************************************************

//*****************************************************************************
//
// Global Data
//
//*****************************************************************************
volatile eUSCI_status ui8Status;

uint8_t  *pData;
uint8_t  ui8DummyRead;
uint32_t g_ui32ByteCount;
bool     burstMode = false;


//B0-3 configurations
/* I2C Master Configuration Parameter */
//volatile eUSCI_I2C_MasterConfig i2cConfig_B0 =
eUSCI_I2C_MasterConfig i2cConfig_B0 =
{
        EUSCI_B_I2C_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
        0,
        EUSCI_B_I2C_SET_DATA_RATE_100KBPS,      // Desired I2C Clock of 400khz
        0,                                      // No byte counter threshold
        EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD                // Autostop
};

//volatile eUSCI_I2C_MasterConfig i2cConfig_B1 =
eUSCI_I2C_MasterConfig i2cConfig_B1 =
{
        EUSCI_B_I2C_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
        0,
        EUSCI_B_I2C_SET_DATA_RATE_100KBPS,      // Desired I2C Clock of 400khz
        0,                                      // No byte counter threshold
        EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD                // Autostop
};

//volatile eUSCI_I2C_MasterConfig i2cConfig_B2 =
eUSCI_I2C_MasterConfig i2cConfig_B2 =
{
        EUSCI_B_I2C_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
        0,
        EUSCI_B_I2C_SET_DATA_RATE_100KBPS,      // Desired I2C Clock of 400khz
        0,                                      // No byte counter threshold
        EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD                // Autostop
};

//volatile eUSCI_I2C_MasterConfig i2cConfig_B3 =
eUSCI_I2C_MasterConfig i2cConfig_B3 =
{
        EUSCI_B_I2C_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
        0,
        EUSCI_B_I2C_SET_DATA_RATE_100KBPS,      // Desired I2C Clock of 400khz
        0,                                      // No byte counter threshold
        EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD                // Autostop
};

//*****************************************************************************
//
// Imported Data
//
//*****************************************************************************

//*****************************************************************************
//
// Constants
//
//*****************************************************************************

//*****************************************************************************
//
// Function Prototypes
//
//*****************************************************************************

/***********************************************************
  Function:

  You MUST call this before doing any read or writes
    @param module the EUSCI module to use ex: EUSCI_B0_BASE
*/
void initI2C(int module)
{
    /* I2C Clock Soruce Speed */
    if(module == EUSCI_B0_BASE){
        i2cConfig_B0.i2cClk = MAP_CS_getSMCLK();
        GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1, GPIO_PIN6 | GPIO_PIN7,
                GPIO_PRIMARY_MODULE_FUNCTION);

        /* Initializing I2C Master to SMCLK at 100kbs with autostop */
        MAP_I2C_initMaster(EUSCI_B0_BASE, &i2cConfig_B0);
    }else if(module == EUSCI_B1_BASE){
        i2cConfig_B1.i2cClk = MAP_CS_getSMCLK();
        GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P6, GPIO_PIN5 | GPIO_PIN4,
                GPIO_PRIMARY_MODULE_FUNCTION);

        /* Initializing I2C Master to SMCLK at 100kbs with autostop */
        MAP_I2C_initMaster(EUSCI_B1_BASE, &i2cConfig_B1);
    }else if(module == EUSCI_B2_BASE){
        i2cConfig_B2.i2cClk = MAP_CS_getSMCLK();

        GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3, GPIO_PIN6 | GPIO_PIN7,
                GPIO_PRIMARY_MODULE_FUNCTION);

        /* Initializing I2C Master to SMCLK at 100kbs with autostop */
        MAP_I2C_initMaster(EUSCI_B2_BASE, &i2cConfig_B2);
    }else if(module == EUSCI_B3_BASE){
        i2cConfig_B3.i2cClk = MAP_CS_getSMCLK();
        GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P6, GPIO_PIN6 | GPIO_PIN7,
                GPIO_SECONDARY_MODULE_FUNCTION);

        /* Initializing I2C Master to SMCLK at 100kbs with autostop */
        MAP_I2C_initMaster(EUSCI_B3_BASE, &i2cConfig_B3);
    }
}

/***********************************************************
  Function:

  @param module the EUSCI module to use ex: EUSCI_B0_BASE
  @param ui8Addr the 7 bit address of the module
  @param ui8Reg the register to write to
  @param Data a pointer to where the data to be written is stored
  @param ui32ByteCount the number of bytes to write
  @returns true if successful, false otherwise
*/
bool writeI2C(int module, uint8_t ui8Addr, uint8_t ui8Reg, uint8_t *Data, uint8_t ui8ByteCount)
{
    /* Wait until ready to write */
    while (MAP_I2C_isBusBusy(module));

    /* Assign Data to local Pointer */
    pData = Data;

    /* Disable I2C module to make changes */
    MAP_I2C_disableModule(module);

    /* Setup the number of bytes to transmit + 1 to account for the register byte */
    if(module == EUSCI_B0_BASE){
        i2cConfig_B0.byteCounterThreshold = ui8ByteCount + 1;
        MAP_I2C_initMaster(module, (const eUSCI_I2C_MasterConfig *)&i2cConfig_B0);
    }else if(module == EUSCI_B1_BASE){
        i2cConfig_B1.byteCounterThreshold = ui8ByteCount + 1;
        MAP_I2C_initMaster(module, (const eUSCI_I2C_MasterConfig *)&i2cConfig_B1);
    }else if(module == EUSCI_B2_BASE){
        i2cConfig_B2.byteCounterThreshold = ui8ByteCount + 1;
        MAP_I2C_initMaster(module, (const eUSCI_I2C_MasterConfig *)&i2cConfig_B2);
    }else if(module == EUSCI_B3_BASE){
        i2cConfig_B3.byteCounterThreshold = ui8ByteCount + 1;
        MAP_I2C_initMaster(module, (const eUSCI_I2C_MasterConfig *)&i2cConfig_B3);
    }else{
        return false;
    }


    /* Load device slave address */
    MAP_I2C_setSlaveAddress(module, ui8Addr);

    /* Enable I2C Module to start operations */
    MAP_I2C_enableModule(module);

    /* Enable master STOP, TX and NACK interrupts */
    MAP_I2C_enableInterrupt(module, EUSCI_B_I2C_STOP_INTERRUPT +
            EUSCI_B_I2C_NAK_INTERRUPT + EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

    /* Set our local state to Busy */
    ui8Status = eUSCI_BUSY;

    /* Send start bit and register */
    MAP_I2C_masterSendMultiByteStart(module,ui8Reg);

    /* Enable master interrupt for the remaining data */
    if(module == EUSCI_B0_BASE){
        MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
    }else if(module == EUSCI_B1_BASE){
        MAP_Interrupt_enableInterrupt(INT_EUSCIB1);
    }else if(module == EUSCI_B2_BASE){
        MAP_Interrupt_enableInterrupt(INT_EUSCIB2);
    }else if(module == EUSCI_B3_BASE){
        MAP_Interrupt_enableInterrupt(INT_EUSCIB3);
    }else{
        return false;
    }

    // NOW WAIT FOR DATA BYTES TO BE SENT
    while(ui8Status == eUSCI_BUSY)
    {
#ifdef USE_LPM
        MAP_PCM_gotoLPM0();
#else
        __no_operation();
#endif
    }

    /* Disable interrupts */
    MAP_I2C_disableInterrupt(module, EUSCI_B_I2C_STOP_INTERRUPT +
            EUSCI_B_I2C_NAK_INTERRUPT + EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
    if(module == EUSCI_B0_BASE){
        MAP_Interrupt_disableInterrupt(INT_EUSCIB0);
    }else if(module == EUSCI_B1_BASE){
        MAP_Interrupt_disableInterrupt(INT_EUSCIB1);
    }else if(module == EUSCI_B2_BASE){
        MAP_Interrupt_disableInterrupt(INT_EUSCIB2);
    }else if(module == EUSCI_B3_BASE){
        MAP_Interrupt_disableInterrupt(INT_EUSCIB3);
    }else{
        return false;
    }

    if(ui8Status == eUSCI_NACK)
    {
        return(false);
    }
    else
    {
        return(true);
    }
}

/***********************************************************
  Function:

  @param module the EUSCI module to use ex: EUSCI_B0_BASE
  @param ui8Addr the 7 bit address of the module
  @param ui8Reg the register to read from
  @param Data a pointer to where to put the data
  @param ui32ByteCount the number of bytes to read
  @returns true if successful, false otherwise
*/
bool readI2C(int module, uint8_t ui8Addr, uint8_t ui8Reg, uint8_t *Data, uint8_t ui8ByteCount)
{
    /* Todo: Put a delay */
    //todo reset if busy for long enough time
    /* Wait until ready */
    while (MAP_I2C_isBusBusy(module));

    /* Assign Data to local Pointer */
    pData = Data;

    /* Disable I2C module to make changes */
    MAP_I2C_disableModule(module);

    /* Setup the number of bytes to receive */
    if(module == EUSCI_B0_BASE){
        i2cConfig_B0.byteCounterThreshold = ui8ByteCount;
        i2cConfig_B0.autoSTOPGeneration = EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD;
        MAP_I2C_initMaster(module, (const eUSCI_I2C_MasterConfig *)&i2cConfig_B0);
//        i2cConfig_B0.byteCounterThreshold = ui8ByteCount;
//        i2cConfig_B0.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;//EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD;//
//        g_ui32ByteCount = ui8ByteCount;
//        burstMode = true;
    }else if(module == EUSCI_B1_BASE){
        i2cConfig_B1.byteCounterThreshold = ui8ByteCount;
        i2cConfig_B1.autoSTOPGeneration = EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD;
        MAP_I2C_initMaster(module, (const eUSCI_I2C_MasterConfig *)&i2cConfig_B1);
    }else if(module == EUSCI_B2_BASE){
        i2cConfig_B2.byteCounterThreshold = ui8ByteCount;
        i2cConfig_B2.autoSTOPGeneration = EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD;
        MAP_I2C_initMaster(module, (const eUSCI_I2C_MasterConfig *)&i2cConfig_B2);
    }else if(module == EUSCI_B3_BASE){
        i2cConfig_B3.byteCounterThreshold = ui8ByteCount;
        i2cConfig_B3.autoSTOPGeneration = EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD;
        MAP_I2C_initMaster(module, (const eUSCI_I2C_MasterConfig *)&i2cConfig_B3);
    }else{
        return false;
    }

    /* Load device slave address */
    MAP_I2C_setSlaveAddress(module, ui8Addr);

    /* Enable I2C Module to start operations */
    MAP_I2C_enableModule(module);

    /* Enable master STOP and NACK interrupts */
    MAP_I2C_enableInterrupt(module, EUSCI_B_I2C_STOP_INTERRUPT +
            EUSCI_B_I2C_NAK_INTERRUPT);

    /* Set our local state to Busy */
    ui8Status = eUSCI_BUSY;

    /* Send start bit and register */
    MAP_I2C_masterSendMultiByteStart(module,ui8Reg);

    /* Enable master interrupt for the remaining data */
    if(module == EUSCI_B0_BASE){
        MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
    }else if(module == EUSCI_B1_BASE){
        MAP_Interrupt_enableInterrupt(INT_EUSCIB1);
    }else if(module == EUSCI_B2_BASE){
        MAP_Interrupt_enableInterrupt(INT_EUSCIB2);
    }else if(module == EUSCI_B3_BASE){
        MAP_Interrupt_enableInterrupt(INT_EUSCIB3);
    }else{
        return false;
    }

    /* NOTE: If the number of bytes to receive = 1, then as target register is being shifted
     * out during the write phase, UCBxTBCNT will be counted and will trigger STOP bit prematurely
     * If count is > 1, wait for the next TXBUF empty interrupt (just after reg value has been
     * shifted out
     *
     * If your code is getting stuck here, you probably called this function from an interrupt
     * DON'T DO THAT!
     */
    while(ui8Status == eUSCI_BUSY)
    {
        if(MAP_I2C_getInterruptStatus(module, EUSCI_B_I2C_TRANSMIT_INTERRUPT0))
        {
            ui8Status = eUSCI_IDLE;
        }
    }

    ui8Status = eUSCI_BUSY;

    /* Turn off TX and generate RE-Start */
    MAP_I2C_masterReceiveStart(module);

    /* Enable RX interrupt */
    MAP_I2C_enableInterrupt(module, EUSCI_B_I2C_RECEIVE_INTERRUPT0);

    /* Wait for all data be received */
    while(ui8Status == eUSCI_BUSY)
    {

#ifdef USE_LPM
        MAP_PCM_gotoLPM0();
#else
        __no_operation();
#endif
    }

    /* Disable interrupts */
    MAP_I2C_disableInterrupt(module, EUSCI_B_I2C_STOP_INTERRUPT +
            EUSCI_B_I2C_NAK_INTERRUPT + EUSCI_B_I2C_RECEIVE_INTERRUPT0);
    if(module == EUSCI_B0_BASE){
        MAP_Interrupt_disableInterrupt(INT_EUSCIB0);
    }else if(module == EUSCI_B1_BASE){
        MAP_Interrupt_disableInterrupt(INT_EUSCIB1);
    }else if(module == EUSCI_B2_BASE){
        MAP_Interrupt_disableInterrupt(INT_EUSCIB2);
    }else if(module == EUSCI_B3_BASE){
        MAP_Interrupt_disableInterrupt(INT_EUSCIB3);
    }else{
        return false;
    }

    if(ui8Status == eUSCI_NACK)
    {
        return(false);
    }
    else
    {
        return(true);
    }
}

/***********************************************************
  Function:
  @param module the EUSCI module to use ex: EUSCI_B0_BASE
  @param ui8Addr the 7 bit address of the module
  @param ui8Reg the register to read from
  @param Data a pointer to where to put the data
  @param ui32ByteCount the number of bytes to read
  @returns true if successful, false otherwise
*/
bool readBurstI2C(int module, uint8_t ui8Addr, uint8_t ui8Reg, uint8_t *Data, uint32_t ui32ByteCount)
{
    /* Todo: Put a delay */
    /* Wait until ready */
    while (MAP_I2C_isBusBusy(module));

    /* Assign Data to local Pointer */
    pData = Data;

    /* Disable I2C module to make changes */
    MAP_I2C_disableModule(module);

    /* Setup the number of bytes to receive */
    if(module == EUSCI_B0_BASE){
        i2cConfig_B0.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
        g_ui32ByteCount = ui32ByteCount;
        burstMode = true;
        MAP_I2C_initMaster(module, (const eUSCI_I2C_MasterConfig *)&i2cConfig_B0);
    }else if(module == EUSCI_B1_BASE){
        i2cConfig_B0.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
        g_ui32ByteCount = ui32ByteCount;
        burstMode = true;
        MAP_I2C_initMaster(module, (const eUSCI_I2C_MasterConfig *)&i2cConfig_B1);
    }else if(module == EUSCI_B2_BASE){
        i2cConfig_B0.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
        g_ui32ByteCount = ui32ByteCount;
        burstMode = true;
        MAP_I2C_initMaster(module, (const eUSCI_I2C_MasterConfig *)&i2cConfig_B2);
    }else if(module == EUSCI_B3_BASE){
        i2cConfig_B0.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
        g_ui32ByteCount = ui32ByteCount;
        burstMode = true;
        MAP_I2C_initMaster(module, (const eUSCI_I2C_MasterConfig *)&i2cConfig_B3);
    }else{
        return false;
    }


    /* Load device slave address */
    MAP_I2C_setSlaveAddress(module, ui8Addr);

    /* Enable I2C Module to start operations */
    MAP_I2C_enableModule(module);

    /* Enable master STOP and NACK interrupts */
    MAP_I2C_enableInterrupt(module, EUSCI_B_I2C_STOP_INTERRUPT +
            EUSCI_B_I2C_NAK_INTERRUPT);

    /* Set our local state to Busy */
    ui8Status = eUSCI_BUSY;

    /* Send start bit and register */
    MAP_I2C_masterSendMultiByteStart(module,ui8Reg);

    /* Enable master interrupt for the remaining data */
    if(module == EUSCI_B0_BASE){
        MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
    }else if(module == EUSCI_B1_BASE){
        MAP_Interrupt_enableInterrupt(INT_EUSCIB1);
    }else if(module == EUSCI_B2_BASE){
        MAP_Interrupt_enableInterrupt(INT_EUSCIB2);
    }else if(module == EUSCI_B3_BASE){
        MAP_Interrupt_enableInterrupt(INT_EUSCIB3);
    }else{
        return false;
    }

    /* NOTE: If the number of bytes to receive = 1, then as target register is being shifted
     * out during the write phase, UCBxTBCNT will be counted and will trigger STOP bit prematurely
     * If count is > 1, wait for the next TXBUF empty interrupt (just after reg value has been
     * shifted out
     *
     * If your code is getting stuck here, you probably called this function from an interrupt
     * DON'T DO THAT!
     */
    while(ui8Status == eUSCI_BUSY)
    {
        if(MAP_I2C_getInterruptStatus(module, EUSCI_B_I2C_TRANSMIT_INTERRUPT0))
        {
            ui8Status = eUSCI_IDLE;
        }
    }

    ui8Status = eUSCI_BUSY;

    /* Turn off TX and generate RE-Start */
    MAP_I2C_masterReceiveStart(module);

    /* Enable RX interrupt */
    MAP_I2C_enableInterrupt(module, EUSCI_B_I2C_RECEIVE_INTERRUPT0);

    /* Wait for all data be received */
    while(ui8Status == eUSCI_BUSY)
    {

#ifdef USE_LPM
        MAP_PCM_gotoLPM0();
#else
        __no_operation();
#endif
    }

    /* Disable interrupts */
    MAP_I2C_disableInterrupt(module, EUSCI_B_I2C_STOP_INTERRUPT +
            EUSCI_B_I2C_NAK_INTERRUPT + EUSCI_B_I2C_RECEIVE_INTERRUPT0);

    if(module == EUSCI_B0_BASE){
        MAP_Interrupt_disableInterrupt(INT_EUSCIB0);
    }else if(module == EUSCI_B1_BASE){
        MAP_Interrupt_disableInterrupt(INT_EUSCIB1);
    }else if(module == EUSCI_B2_BASE){
        MAP_Interrupt_disableInterrupt(INT_EUSCIB2);
    }else if(module == EUSCI_B3_BASE){
        MAP_Interrupt_disableInterrupt(INT_EUSCIB3);
    }else{
        return false;
    }


    if(ui8Status == eUSCI_NACK)
    {
        return(false);
    }
    else
    {
        return(true);
    }
}

/***********************************************************
  Function: euscib0IntHandler
 */
void EUSCIB0_IRQHandler(void)
{
    uint_fast16_t status;

    status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B0_BASE);
    MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, status);

    if (status & EUSCI_B_I2C_NAK_INTERRUPT)
    {
        /* Generate STOP when slave NACKS */
        MAP_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);

        /* Clear any pending TX interrupts */
        MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

        /* Set our local state to NACK received */
        ui8Status = eUSCI_NACK;
    }

    if (status & EUSCI_B_I2C_START_INTERRUPT)
    {
        /* Change our local state */
        ui8Status = eUSCI_START;
    }

    if (status & EUSCI_B_I2C_STOP_INTERRUPT)
    {
        /* Change our local state */
        ui8Status = eUSCI_STOP;
    }

    if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
    {
        /* RX data */
        *pData++ = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
        ui8DummyRead= MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);

        if (burstMode)
        {
            g_ui32ByteCount--;
            if (g_ui32ByteCount == 1)
            {
                burstMode = false;

                /* Generate STOP */
                MAP_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
            }
        }
    }

    if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0)
    {
        /* Send the next data */
        MAP_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, *pData++);
    }

#ifdef USE_LPM
    MAP_Interrupt_disableSleepOnIsrExit();
#endif
}

void EUSCIB1_IRQHandler(void)
{
    uint_fast16_t status;

    status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B1_BASE);
    MAP_I2C_clearInterruptFlag(EUSCI_B1_BASE, status);

    if (status & EUSCI_B_I2C_NAK_INTERRUPT)
    {
        /* Generate STOP when slave NACKS */
        MAP_I2C_masterSendMultiByteStop(EUSCI_B1_BASE);

        /* Clear any pending TX interrupts */
        MAP_I2C_clearInterruptFlag(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

        /* Set our local state to NACK received */
        ui8Status = eUSCI_NACK;
    }

    if (status & EUSCI_B_I2C_START_INTERRUPT)
    {
        /* Change our local state */
        ui8Status = eUSCI_START;
    }

    if (status & EUSCI_B_I2C_STOP_INTERRUPT)
    {
        /* Change our local state */
        ui8Status = eUSCI_STOP;
    }

    if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
    {
        /* RX data */
        *pData++ = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B1_BASE);
        ui8DummyRead= MAP_I2C_masterReceiveMultiByteNext(EUSCI_B1_BASE);

        if (burstMode)
        {
            g_ui32ByteCount--;
            if (g_ui32ByteCount == 1)
            {
                burstMode = false;

                /* Generate STOP */
                MAP_I2C_masterSendMultiByteStop(EUSCI_B1_BASE);
            }
        }
    }

    if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0)
    {
        /* Send the next data */
        MAP_I2C_masterSendMultiByteNext(EUSCI_B1_BASE, *pData++);
    }

#ifdef USE_LPM
    MAP_Interrupt_disableSleepOnIsrExit();
#endif
}

void EUSCIB2_IRQHandler(void)
{
    uint_fast16_t status;

    status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B2_BASE);
    MAP_I2C_clearInterruptFlag(EUSCI_B2_BASE, status);

    if (status & EUSCI_B_I2C_NAK_INTERRUPT)
    {
        /* Generate STOP when slave NACKS */
        MAP_I2C_masterSendMultiByteStop(EUSCI_B2_BASE);

        /* Clear any pending TX interrupts */
        MAP_I2C_clearInterruptFlag(EUSCI_B2_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

        /* Set our local state to NACK received */
        ui8Status = eUSCI_NACK;
    }

    if (status & EUSCI_B_I2C_START_INTERRUPT)
    {
        /* Change our local state */
        ui8Status = eUSCI_START;
    }

    if (status & EUSCI_B_I2C_STOP_INTERRUPT)
    {
        /* Change our local state */
        ui8Status = eUSCI_STOP;
    }

    if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
    {
        /* RX data */
        *pData++ = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B2_BASE);
        ui8DummyRead= MAP_I2C_masterReceiveMultiByteNext(EUSCI_B2_BASE);

        if (burstMode)
        {
            g_ui32ByteCount--;
            if (g_ui32ByteCount == 1)
            {
                burstMode = false;

                /* Generate STOP */
                MAP_I2C_masterSendMultiByteStop(EUSCI_B2_BASE);
            }
        }
    }

    if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0)
    {
        /* Send the next data */
        MAP_I2C_masterSendMultiByteNext(EUSCI_B2_BASE, *pData++);
    }

#ifdef USE_LPM
    MAP_Interrupt_disableSleepOnIsrExit();
#endif
}

void EUSCIB3_IRQHandler(void)
{
    uint_fast16_t status;

    status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B3_BASE);
    MAP_I2C_clearInterruptFlag(EUSCI_B3_BASE, status);

    if (status & EUSCI_B_I2C_NAK_INTERRUPT)
    {
        /* Generate STOP when slave NACKS */
        MAP_I2C_masterSendMultiByteStop(EUSCI_B3_BASE);

        /* Clear any pending TX interrupts */
        MAP_I2C_clearInterruptFlag(EUSCI_B3_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

        /* Set our local state to NACK received */
        ui8Status = eUSCI_NACK;
    }

    if (status & EUSCI_B_I2C_START_INTERRUPT)
    {
        /* Change our local state */
        ui8Status = eUSCI_START;
    }

    if (status & EUSCI_B_I2C_STOP_INTERRUPT)
    {
        /* Change our local state */
        ui8Status = eUSCI_STOP;
    }

    if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
    {
        /* RX data */
        *pData++ = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B3_BASE);
        ui8DummyRead= MAP_I2C_masterReceiveMultiByteNext(EUSCI_B3_BASE);

        if (burstMode)
        {
            g_ui32ByteCount--;
            if (g_ui32ByteCount == 1)
            {
                burstMode = false;

                /* Generate STOP */
                MAP_I2C_masterSendMultiByteStop(EUSCI_B3_BASE);
            }
        }
    }

    if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0)
    {
        /* Send the next data */
        MAP_I2C_masterSendMultiByteNext(EUSCI_B3_BASE, *pData++);
    }

#ifdef USE_LPM
    MAP_Interrupt_disableSleepOnIsrExit();
#endif
}

void BSP_I2C_Init()
{
  initI2C(EUSCI_B0_BASE);
}

bool BSP_I2C1_WriteReg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length)
{
  if(writeI2C(EUSCI_B0_BASE, (DevAddr & 0xff), (Reg & 0xff), pData, (Length & 0xff)))
  {
    return 0;
  }
  
  return 1;
}

bool BSP_I2C1_ReadReg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length)
{
  if(readI2C(EUSCI_B0_BASE, (DevAddr & 0xff), (Reg & 0xff), pData, (Length & 0xff)))
  {
    return 0;
  }
  
  return 1;
}

7875.i2c_driver.h