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/MSP432P401R: ADXL345 I2C Communication Issues

Part Number: MSP432P401R

Tool/software: Code Composer Studio

Hi, 

I am attempting to communicate with the ADXL345 using I2C and am unable to transmit or receive data in any capacity. I have hooked up a logic analyzer and am getting the same data no matter what I am transmitting, and it is very random. I have used the example code for i2C that comes with the MSP432, and even run that on the logic analyzer where I get random unclear data. 

I've attached my code below. Let me know if you have any suggestions or help I really need it!

  1. /* 
  2.  * i2c.c 
  3.  * 
  4.  *  Created on: Nov 18, 2017 
  5.  *      Author: noamargalit 
  6.  */  
  7.   
  8. //slave (accelerometer) 
  9. //master (msp432p401r)  
  10.   
  11. #include "msp.h"  
  12. #include "i2cmaster.h"  
  13.   
  14. #define PWR_CTRL 0x2D  
  15.   
  16.   
  17. volatile uint8_t rxbuf[6];  
  18. uint8_t *rxdata;  
  19. volatile uint8_t transmit[2];  
  20.   
  21. void i2c_data_transmission(){  
  22.     uint8_t i;  
  23.     P1->SEL0 |= BIT6 | BIT7;  
  24.     __enable_irq();  
  25.     //power on:  
  26.     i2c_receive_configure();  
  27.     i2c_transmit_configure();  
  28.   
  29.     transmit_two_data(0x00,PWR_CTRL); //wake up  
  30.     while (EUSCI_B0->CTLW0 & EUSCI_B_CTLW0_TXSTP);  
  31.     transmit_two_data(0x10, PWR_CTRL); //auto sleep  
  32.     while (EUSCI_B0->CTLW0 & EUSCI_B_CTLW0_TXSTP);  
  33.     transmit_two_data(0x08, PWR_CTRL); //measure data  
  34.     while (EUSCI_B0->CTLW0 & EUSCI_B_CTLW0_TXSTP);  
  35.   
  36.     while(1){  
  37.   
  38.        uint8_t test_byte = (0x32<<1) + 1; //sends read request to register with address 0x32: X_DATA  
  39.        uint8_t datarequest = 0x32;  
  40.   
  41.         //transmit_array(&test_byte, 1); //data request  
  42.         transmit_one_data(test_byte);  
  43.         for(i=0; i < 20; i++);  
  44.         while (EUSCI_B0->CTLW0 & EUSCI_B_CTLW0_TXSTP);  
  45.         receive_data();  
  46.         while (EUSCI_B0->CTLW0 & EUSCI_B_CTLW0_TXSTP);  
  47.     //    EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTP;//stop after end  
  48.   
  49. */  
  50.   
  51.     }  
  52. }  
  53.   
  54. void i2c_transmit_configure(){  
  55.   
  56.     EUSCI_B0->CTLW0 = EUSCI_A_CTLW0_SWRST;  
  57.     EUSCI_B0->CTLW0 = EUSCI_B_CTLW0_MODE_3 | EUSCI_B_CTLW0_SYNC | EUSCI_B_CTLW0_SSEL__SMCLK;  
  58.     EUSCI_B0->CTLW0 &= ~EUSCI_B_CTLW0_SWRST;  
  59.   
  60.     EUSCI_B0->IE |= EUSCI_B_IE_TXIE0;  
  61.   
  62.   
  63. }  
  64.   
  65. void i2c_receive_configure(){  
  66.     EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_SWRST; //reset state  
  67.     EUSCI_B0->CTLW0 =  EUSCI_B_CTLW0_MST | EUSCI_B_CTLW0_SYNC | EUSCI_B_CTLW0_SSEL__SMCLK; //master,sync,SMCLK mode  
  68.     EUSCI_B0->CTLW1 |= EUSCI_B_CTLW1_ASTP_2; //automatic stop when reaching threshold  
  69.     EUSCI_B0->CTLW1 |= EUSCI_B_CTLW1_SWACK;  
  70.     EUSCI_B0->BRW = 30; //baud rate using SMCLK  
  71.     EUSCI_B0->TBCNT = 6; //6 bytes received for every direction  
  72.     EUSCI_B0->CTLW0 &= ~EUSCI_B_CTLW0_SWRST;  
  73.   
  74.     EUSCI_B0->IE |= EUSCI_B_IE_RXIE0| EUSCI_B_IE_NACKIE; // do i need other interrupts? NACK? EUSCI_B_IE_NACKIE Byte counter??  
  75.   
  76.   
  77. }  
  78.   
  79. void transmit_two_data(uint8_t purpose, uint8_t power_control){  
  80.     transmit[0] = purpose;  
  81.     transmit[1] = power_control;  
  82.     EUSCI_B0->I2CSA = (0x53 << 1 )| I2C_READ;  
  83.     while (EUSCI_B0->CTLW0 & EUSCI_B_CTLW0_TXSTP); //while stop condition sent  
  84.     EUSCI_B0->CTLW0 |= UCTR;  
  85.     EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTT; //start transmit  
  86.     NVIC_EnableIRQ(EUSCIB0_IRQn); //enter interrupt handler  
  87. }  
  88.   
  89. void transmit_one_data(uint8_t data){  
  90.     transmit[0] = data;  
  91.     while (EUSCI_B0->CTLW0 & EUSCI_B_CTLW0_TXSTP);  
  92.     EUSCI_B0->I2CSA = (0x53 << 1 )| I2C_READ;  
  93.     EUSCI_B0->CTLW0 |= UCTR;  
  94.     EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTT;  
  95.     NVIC_EnableIRQ(EUSCIB0_IRQn);  
  96. }  
  97.   
  98.   
  99. void receive_data(void){  
  100.     rxdata = (uint8_t *)rxbuf;  
  101.     while (EUSCI_B0->CTLW0 & EUSCI_B_CTLW0_TXSTP);  
  102.     EUSCI_B0->CTLW0 &= ~UCTR;  
  103.     EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTT;  
  104.     NVIC_EnableIRQ(EUSCIB0_IRQn);  
  105. }  
  106.   
  107. void EUSCIB0_IRQHandler(void){  
  108.   
  109.     if (EUSCI_B0->IFG & EUSCI_B_IFG_NACKIFG)  
  110.         {  
  111.             EUSCI_B0->IFG &= ~ EUSCI_B_IFG_NACKIFG; //checks if nack flag received from slave if this is happens txbuf is cleared  
  112.             EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTT; //does restart condition  
  113.   
  114.            if (EUSCI_B0->IFG & EUSCI_B_IFG_TXIFG0) //checks tx flag  
  115.                 {  
  116.                     EUSCI_B0->TXBUF = transmit[0];  
  117.                     EUSCI_B0->CTLW0 &= ~EUSCI_B_CTLW0_TXSTT;  
  118.   
  119.                 }  
  120.   
  121.   
  122.         }  
  123.   
  124.     else {  
  125.         EUSCI_B0->TXBUF = 0x00;  
  126.         EUSCI_B0->CTLW0 &= ~EUSCI_B_CTLW0_TXSTT;  
  127.         EUSCI_B0->IFG  |= EUSCI_B_IFG_TXIFG0;  
  128.   
  129.     }  
  130.   
  131.   
  132.     if (EUSCI_B0->IFG & EUSCI_B_IFG_RXIFG0)  
  133.     {  
  134.         EUSCI_B0->IFG &= ~EUSCI_B_IFG_RXIFG0; //clear flag  
  135.         *rxdata++ = EUSCI_B0->RXBUF;  
  136.   
  137.   
  138.     }  
  139.   
  140.     if (EUSCI_B0->IFG & EUSCI_B_IFG_TXIFG0)  
  141.     {  
  142.   
  143.         EUSCI_B0->TXBUF = transmit[0];  
  144.         UCB0IFG &= ~UCTXIFG;  
  145.   
  146.     }  
  147.   
  148.   
  149.   
  150. }  

  • Noa,
    Before digging into this code, have you successfully tried one of the master-slave examples using two Red LaunchPads?. (assuming you are not using the old Black MSP432 LaunchPads, which were pre-production and had some differences to the production silicon.) Which example did you use as a base for your code?

    Regards,
    Bob L.
  • Hi Bob,

    I used the master-slave examples as an attempt to write this new code, but did not actually test it using two launchpads. However I did try and directly modify that specific code at one time to try and see data on the logic analyzer and received the same random data. I used the msp432p401x_euscib0_i2c_10 and _11 as examples and I've heard similar issues from other students that they were running into issues getting expected data on the logic analyzer. I have tested the code both on my black msp as well as my red msp. I also am currently attempting a different example code from one of the forums to see if that will work.

    Let me know if you see anything that seems incorrect.

    Thanks,

    Noa Margalit

  • Noa,

    Are you using pull up resistors on your I2C lines? We also highly suggest that you do not use the black launchpad. Best place to start in your effort is to get the two example codes (master & slave) together one two separate red launchpads and test. Make sure you have pull up resistors for SDA and SCL.
  • Hi Evan,

    I have pull up resistors on the I2C lines. I am not using the black launchpad, I have tested with both. No one has had success in using the example codes including our faculty members who are experts in embedded systems. Is there any example code without interrupts? Just basic configuration and successful transmit and receive data?

    I am now able to transmit the slave address but it is the only thing I can send: 

  • Noa,

    Can you explain what exactly you are doing?

    What examples are you using for master and slave?

    What value on your pull up resistors?

    Are you using the latest SimpleLink MSP432 SDK?

    Are you using two red launchpads (you're answer is yes so no action there)

    What connections are you making?

    I tested these examples just this morning so they are working properly.
  • Noa,

     If you're only seeing the slave address, then that means you're not getting an acknowledge from the slave when sending.  For these examples you need the following configuration (forgive me if some of this is obvious):

    Here's what I'm using:

    1. Two Red Launchpads- 1 slave, 1 Master

    2. Pullups - 10kohm to 3.3v Vcc (Launchpad's 3.3v supply)

    3. Grounds on LaunchPads connected to one another (avoid non-common ground issue, though this is not really a problem here)

    4. Open up 2 instances of CCS 7.3 (let's call them CCS-Mstr and CCS-Slv)

       - Note- you'll need to create separate workspaces for each instance and import the respective examples into them

    5. Disconnect both LPs (USB) if you've not done so already

    6. Start with CCS-Slave-

    a. Connect the Slave LaunchPad only
    b. Import & Compile msp432p401x_euscib0_i2c_11 
    c. connect debugger (Run-> Debug)
    d. Start the slave code 

    7. Start the CCS- Master

    a. Connect the Master LaunchPad while leaving the Slave LP connected
    b. Import & Compile msp432p401x_euscib0_i2c_10
    c. connect debugger (Run-> Debug)
    d. Start Logic Analyzer w/ trigger on SCL HL edge
    e. Start the master code 

    Note that, once programmed, you of course don't need the slave to be connected to the PC, but you will still need to start it before running the master.

    If your procedure is different in any way from the above, let me know.

    Regards,

      Bob L.

  • Noa,

    Have you looked into this any more? We are interested in helping y'all get this working.
  • Hi,

    I have. I had something hooked up on my breadboard incorrectly, but I am still getting a lot of issues with the BUS being busy when it is not. I unplug the board, replug it in and the bus stays busy. I've tried reconfiguring the pins so that i have it bring the bus back to an unbusy state but it results in unexpected voltages and drops my SCL low. Here is my newer code: 

    #include "msp.h"

    /**

     * main.c

     */

    void i2c_configure();

    void i2c_multiple_write(uint8_t registers, uint16_t val);

    void i2c_read_single_byte(uint8_t registers, uint8_t direction);

    volatile uint8_t data[6];

    volatile int i=0;

    #define X 0

    #define Y 1

    #define Z 2

    void main(void)

    {

    WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // stop watchdog timer

      //  if(EUSCI_B1->STATW & EUSCI_B_STATW_BBUSY){

    //  P1->OUT &= ~BIT5;

    //   P1->OUT |= BIT5;

        P6->SEL1 &= ~BIT5;

        P6->SEL1 &= ~BIT4;

        P6->OUT |= BIT5;

        P6->OUT |= BIT4;

        P6->SEL0 |= BIT5;

        P6->SEL0 |= BIT4;

    while(1){

        i2c_configure();

           // i2c_multiple_write(0x2D,0x00);

          //  i2c_multiple_write(0x2D,0x10);

            i2c_multiple_write(0x2D,0x08);

        i2c_read_single_byte(0x32,X);

      //  for(i=0;i<20;i++);

        i2c_read_single_byte(0x34,Y);

        i2c_read_single_byte(0x36,Z);

      //  *x = (int16_t)((((int)data[1]) << 8) | data[0]);

      //  *y = (int16_t)((((int)data[3]) << 8) | data[2]);

      //  *z = (int16_t)((((int)data[5]) << 8) | data[4]);

    }

    }

    void i2c_configure(){

           // P1->SEL1 |= BIT7 | BIT6;

            /*ENABLE RESET,MASTER,I2C (Mode 3), SMCLK*/

            EUSCI_B1->CTLW0 = (EUSCI_B_CTLW0_SWRST |EUSCI_B_CTLW0_MST|EUSCI_B_CTLW0_MODE_3 | EUSCI_B_CTLW0_SSEL__SMCLK);

            /*NO AUTOSTOP*/

            EUSCI_B1->CTLW1 = EUSCI_B_CTLW1_ASTP_0;

            /*SET CLOCK FOR SMCLK, 3MHZ for 100KBPS RATE*/

            EUSCI_B1->BRW = 30;

            /*CONFIGURE PINS 1.6 (SDA) 1.7 (SCL) (these are secondary mode pins) */

            //P6->SEL0 |= BIT5 | BIT4;

           // P1->SEL1 &= ~(BIT7 | BIT6);

    /*

            P6->SEL1 &= ~BIT5;

            P6->SEL1 &= ~BIT4;

            P6->OUT |= BIT5;

            P6->OUT |= BIT4;

            P6->SEL0 |= BIT5;

            P6->SEL0 |= BIT4;

            */

            /*SOFTWARE RESET DISABELE*/

            EUSCI_B1->CTLW0 &= ~EUSCI_B_CTLW0_SWRST;

            //EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTP;

            /*SLAVE ADDRESS*/

            EUSCI_B1->I2CSA = 0x53;

        }

    void i2c_multiple_write(uint8_t registers, uint16_t val)

    {

             /* Transmit mode for slave address and register read address */

              EUSCI_B1->IE &= ~EUSCI_B_IE_TXIE0;

              EUSCI_B1->CTLW0 |= UCTR;

              EUSCI_B1->IFG &= ~EUSCI_B_IFG_TXIFG0;

              while (EUSCI_B1->STATW & EUSCI_B_STATW_BBUSY);

              /*START*/

              EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTT;

             while (!(EUSCI_B1->IFG & EUSCI_B_IFG_TXIFG0));

             /*WRITE REGISTER TO TXBUF*/

             EUSCI_B1 ->TXBUF = registers;

             while (!(EUSCI_B1->IFG & EUSCI_B_IFG_TXIFG0));

             /*WRITE VALUE TO REGISTER*/

             EUSCI_B1->TXBUF = val;

             /*EMPTY TX BUF? SEND STOP*/

             while (!(EUSCI_B1->IFG & EUSCI_B_IFG_TXIFG0));

             EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTP;

    }

    void i2c_read_single_byte(uint8_t registers, uint8_t direction)

    {

              /* Transmit mode for slave address and register read address */

              EUSCI_B1->IE &= ~EUSCI_B_IE_TXIE0;

              EUSCI_B1->CTLW0 |= UCTR;

              EUSCI_B1->IFG &= ~EUSCI_B_IFG_TXIFG0;

              while (EUSCI_B1->STATW & EUSCI_B_STATW_BBUSY);

              /*START*/

              EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTT;

             while (!(EUSCI_B1->IFG & EUSCI_B_IFG_TXIFG0));

             EUSCI_B1 ->TXBUF = registers;

             while (!(EUSCI_B1->IFG & EUSCI_B_IFG_TXIFG0));

             EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTP;

             while (!(EUSCI_B1->IFG & EUSCI_B_IFG_TXIFG0));

             /*RECEIVER MODE*/

              EUSCI_B1->CTLW0 &= ~UCTR;

              EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTT;

              while (!(EUSCI_B1->IFG & EUSCI_B_IE_RXIE0));

              if(X){

                  //for(i=0; i<1; i++)

                  //{

                      data[X] = (EUSCI_B1->RXBUF);

                  //}

              }

              if(Y){

                  data[Y] = (EUSCI_B1->RXBUF);

              }

              if(Z){

                   data[Z] = (EUSCI_B1->RXBUF);

              }

              EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTP;

              while (!(EUSCI_B1->IFG & EUSCI_B_IFG_TXIFG0));

              while (!(EUSCI_B1->IFG & EUSCI_B_IE_RXIE0));

    }

    It only works in collecting data some of the time, the rest of the time the line stays busy. Let me know if you have any suggestions on how to configure the pins. 

**Attention** This is a public forum