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.
Dear community
I'm currently working on a project with a MSP430 launchpad connected to a compass module (MPU-9150). With the following code, I try to read two registers of the compass module. The module thereby requires a repeated start condition, in order to initiate a read command. The full sequence to read a register is: "Start | Slave Address | Write bit | ACK | Register address | ACK | Start | Slave address | Read bit | ACK | Slave response | NACK". The attached figure shows what I get as response from the compass module. The problem is that the for the first register, the read byte is followed by two 0x00 bytes, and for the second register, the read byte is followed by one 0x00 byte. How can I terminate the communication earlier, so that the trailing zero bytes vanish? The response from the slave should only be one byte (0x68).
#define TEST_REG 0x75
#define DEV_ADDRESS 0x68
#define ADDRESSING 1 #define RESTARTING 2 #define READING 3 #define FINISHING 4 const unsigned char regAddress[] = {TEST_REG, TEST_REG}; unsigned char magData[6] = {}; unsigned char i = 0; unsigned char mode = ADDRESSING; int main(void) { //--- IO settings -------------------------------------------------------------------- WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0 P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0 //------------------------------------------------------------------------------------ //--- I2C controller settings -------------------------------------------------------- UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB0BR0 = 3; // fSCL = SMCLK/3 = ~400kHz UCB0BR1 = 0; UCB0I2CSA = DEV_ADDRESS; // Set slave address UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UCB0CTL1 |= UCTR; // Configure controller as transmitter //------------------------------------------------------------------------------------ __bis_SR_register(GIE); // Global interrupt enable while(1) { while(i < sizeof regAddress) // All registers read? { UCB0CTL1 |= UCTXSTT; // Generate start condition IE2 |= UCB0TXIE; // Enable TX interrupt while (UCB0STAT & UCBBUSY); // Wait for current transmission to finish i++; // Proceed with next register } } } #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void) { switch(mode) { case ADDRESSING: UCB0TXBUF = regAddress[i]; // Put register address on bus mode = RESTARTING; // Proceed with next mode break; case RESTARTING: IE2 &= ~UCB0TXIE; // Diable TX interrupt IE2 |= UCB0RXIE; // Enable RX interrupt UCB0CTL1 &= ~UCTR; // Reconfigure controller as receiver UCB0CTL1 |= UCTXSTT; // Generate a reapeated start condition IFG2 &= ~UCB0TXIFG; // Clear TX interrupt flag mode = READING; // Proceed with next mode break; case READING: magData[i] = UCB0RXBUF; // Save read values mode = FINISHING; // Proceed with next mode break; case FINISHING: UCB0CTL1 |= UCTXSTP; // Generate stop condition IFG2 &= ~UCB0RXIFG; // Clear RX interrupt flag IE2 &= ~UCB0RXIE; // Disable RX interrupt UCB0CTL1 |= UCTR; // Reconfigure controller as transmitter mode = ADDRESSING; // Reset mode break; default: break; } }
Note that in the figure, the ACK bits are not displayed for the write and read command-parts, because of lack of space. They are however present.
Thanks in advance.
Section 17.3.4.2.2 of the User's Guide says:
If a master wants to receive a single byte only, the UCTXSTP bit must be set while the byte is being received. For this case, the UCTXSTT may be polled to determine when it is cleared.
**Attention** This is a public forum