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.

MSP430G2553: I2C read on ADXL345

Part Number: MSP430G2553

I try to read Data from an ADXL345. Unfortunatelly my read function gets stuck at forst usage. Does anyone have an idea why and how to solve the problem?

void print(const unsigned char Data){
	UCB0TXBUF = Data;
	__bis_SR_register(LPM3_bits + GIE);
}

void printS(char data){
	UCB0CTL1 = UCSWRST;
	UCB0CTL0 = UCMODE_3 + UCMST + UCSYNC;			// I2C master mode
	UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
	//UCB0BR0 = 0xA0;                          // 100 kHz at 16 MHz
	UCB0BR0 = 0x28;                          // 400 kHz at 16 MHz
	//UCB0BR0 = 0x1B;                          // 400 kHz + 50 % at 16 MHz
	//UCB0BR0 = 0x14;                          // 400 kHz + 100 % at 16 MHz
	//UCB0BR0 = 0x08;                          // 2 MHz (400 kHz + 400 %) at 16 MHz
	//UCB0BR0 = 0x08;                          // 4 MHz at 16 MHz
	//UCB0BR0 = 0x02;                          // 8 MHz at 16 MHz
	UCB0I2CSA = data;                       // address
	UCB0CTL1 &= ~UCSWRST;
	IE2 |= UCB0TXIE;				// Enable TX ready interrupt
	__disable_interrupt();
	UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition

	__bis_SR_register(LPM3_bits + GIE);;
}

void printE(void){
	UCB0CTL1 |= UCTR + UCTXSTP;
	IE2 &= ~UCB0TXIE;
}

void readS(char address, char reg){
	UCB0CTL1 = UCSWRST;
	UCB0CTL0 = UCMODE_3 + UCMST + UCSYNC;			// I2C master mode
	UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
	UCB0BR0 = 0x28;                          // < 400 kHz
	UCB0I2CSA = address;                       // address
	UCB0CTL1 &= ~UCSWRST;

	IE2 |= UCB0TXIE;				// Enable TX ready interrupt
	__disable_interrupt();

	//go to register
	UCB0CTL1 = UCSSEL_2 + UCTR + UCTXSTT; // I2C RX, start condition
	__bis_SR_register(LPM3_bits + GIE);
	UCB0TXBUF = reg;
	__bis_SR_register(LPM3_bits + GIE);
	UCB0CTL1 = UCSSEL_2 + UCTXSTT; // I2C RX, start condition
}

char read(void){
	char output;
	__bis_SR_register(LPM3_bits + GIE);
	output = UCB0RXBUF;

	return output;
}


void adxl(void){
	unsigned int hold;

	printS(0x53);
	print(0x32);
	UCB0CTL1 = UCSSEL_2 + UCTXSTT; // I2C RX, start condition

	hold = read();
	Grav[0] = (read()<<3) + (hold>>5);
	hold = read();
	Grav[1] = (read()<<3) + (hold>>5);
	hold = read();
	Grav[2] = (read()<<3) + (hold>>5);

	UCB0CTL1 = UCSSEL_2 + UCTXSTP;
	while (UCB0CTL1 & UCTXSTP);

}

void initadxl(void){
	printS(0x53);
	print(0x2C);
	print(0x07);
	print(0x08);
	printE();
	printS(0x53);
	print(0x31);
	print(0x0D);
	printE();
	printS(0x53);
	print(0x1E);
	print(0xFE);
	print(0xFD);
	print(0x0C);
	printE();
}


void main(void){
    WDTCTL = WDTPW + WDTHOLD;

    DCOCTL = CALDCO_16MHZ;				//DCO setting = 8MHz
    BCSCTL1 = CALBC1_16MHZ;				//DCO setting = 8MHz



    // Configure Pins for I2C
    P1SEL |= BIT6 + BIT7;                  // Pin init
    P1SEL2 |= BIT6 + BIT7;                  // Pin init

    __delay_cycles(8000000);


    initadxl();

    adxl();
}


// USCI_B0 Data ISR
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void){
	IFG2 &= ~UCB0TXIFG;
	__bic_SR_register_on_exit(LPM3_bits);               // Wakeup main code
}

  • I more or less got it running. Would be nice to have repeated start implemented, unfortunatelly it does not work.

    Here the important stuff. printS - print (n times) - printSr (repeated start) - print (n times) - printE is my test case.

    void printS(char data){
    	IE2 &= ~UCA0RXIE;
    	UCB0CTL1 = UCSWRST;
    	UCB0CTL0 = UCMODE_3 + UCMST + UCSYNC;			// I2C master mode
    	UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
    	UCB0BR0 = 0xA0;                          // 100 kHz at 16 MHz
    	//UCB0BR0 = 0x28;                          // 400 kHz at 16 MHz
    	//UCB0BR0 = 0x1B;                          // 400 kHz + 50 % at 16 MHz
    	//UCB0BR0 = 0x14;                          // 400 kHz + 100 % at 16 MHz
    	//UCB0BR0 = 0x08;                          // 2 MHz (400 kHz + 400 %) at 16 MHz
    	//UCB0BR0 = 0x08;                          // 4 MHz at 16 MHz
    	//UCB0BR0 = 0x02;                          // 8 MHz at 16 MHz
    	UCB0I2CSA = data;                       // address
    	UCB0CTL1 &= ~UCSWRST;
    	IE2 |= UCB0TXIE;				// Enable TX ready interrupt
    	__disable_interrupt();
    	UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
    
    	__bis_SR_register(LPM3_bits + GIE);
    }
    
    void printSr(){
    	IE2 &= ~UCA0RXIE;
    	//UCB0CTL1 = UCSWRST;
    	//UCB0CTL0 = UCMODE_3 + UCMST + UCSYNC;			// I2C master mode
    	//UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
    	//UCB0BR0 = 0xA0;                          // 100 kHz at 16 MHz
    	//UCB0I2CSA = 0x3C;                       // address
    	//UCB0CTL1 &= ~UCSWRST;
    	IE2 |= UCB0TXIE;				// Enable TX ready interrupt
    	__disable_interrupt();
    	UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
    
    	__bis_SR_register(LPM3_bits + GIE);
    }
    
    void print(const unsigned char Data){
    	UCB0TXBUF = Data;
    	__bis_SR_register(LPM3_bits + GIE);
    }
    
    void printE(void){
    	UCB0CTL1 |= UCTR + UCTXSTP;
    	IE2 &= ~UCB0TXIE;
    while (UCB0CTL1 & UCTXSTP); } #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void){ IFG2 &= ~ (UCB0TXIFG + UCB0RXIFG); __bic_SR_register_on_exit(LPM3_bits); // Wakeup main code }

  • I could solve the problem by removing "__bis_SR_register(LPM3_bits + GIE);" from printSr()

**Attention** This is a public forum