Hello TI community,
i can so far succesfully read the WHOAMI register of the MPU9250. My next step was to write a write-able register (0x6B) and then read it again to see if the write process was successful.
This is my code:
#include "driverlib.h" #include "MPU9250_reg.h" /* Slave address */ #define SLAVE_ADDRESS 0x68 volatile uint8_t a = 0; volatile uint8_t byte_counter = 0; volatile uint8_t write_read = 0; uint8_t transmitData; uint8_t RXData; void my_EUSCI_B_I2C_masterSendSingleByte (uint16_t baseAddress, uint8_t txData ); int main(void) { WDT_A_hold(WDT_A_BASE); GPIO_setAsPeripheralModuleFunctionInputPin( GPIO_PORT_P1, GPIO_PIN6 + GPIO_PIN7, GPIO_SECONDARY_MODULE_FUNCTION ); /* * Disable the GPIO power-on default high-impedance mode to activate * previously configured port settings */ PMM_unlockLPM5(); //Enter LPM4 w/interrupt /* WICHTIG, NICHT VERGESSEN */ __bis_SR_register(GIE); //Initialize transmit data packet transmitData = 0x75; //Initialize Master EUSCI_B_I2C_initMasterParam param = {0}; param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = CS_getSMCLK(); param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_100KBPS; param.byteCounterThreshold = 1; param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP; EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, ¶m); //Specify slave address EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS ); //Set in transmit mode EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE ); //Enable I2C Module to start operations EUSCI_B_I2C_enable(EUSCI_B0_BASE); // enable txi interrupt EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0); // sending /* start condition */ // interrupt should be activated afterwards byte_counter = 1; write_read = 1; UCB0CTLW0 |= UCTXSTT; while(!(UCB0CTLW0 & UCBBUSY)){} byte_counter = 1; write_read = 0; EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0); UCB0CTLW0 |= UCTXSTT; while(1) { _nop(); } } void my_EUSCI_B_I2C_masterSendSingleByte (uint16_t baseAddress, uint8_t txData ) { //Store current TXIE status uint16_t txieStatus = HWREG16(baseAddress + OFS_UCBxIE) & UCTXIE; //Disable transmit interrupt enable HWREG16(baseAddress + OFS_UCBxIE) &= ~(UCTXIE); //Send start condition. HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTR + UCTXSTT; //Poll for transmit interrupt flag. while (!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ; //Send single byte data. HWREG16(baseAddress + OFS_UCBxTXBUF) = txData; //Poll for transmit interrupt flag. while (!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ; //Send stop condition. //HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP; //Clear transmit interrupt flag before enabling interrupt again HWREG16(baseAddress + OFS_UCBxIFG) &= ~(UCTXIFG); //Reinstate transmit interrupt enable HWREG16(baseAddress + OFS_UCBxIE) |= txieStatus; } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=USCI_B0_VECTOR __interrupt #elif defined(__GNUC__) __attribute__((interrupt(USCI_B0_VECTOR))) #endif void USCIB0_ISR(void) { switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG)) { case USCI_NONE: // No interrupts break; break; case USCI_I2C_UCALIFG: // Arbitration lost break; case USCI_I2C_UCNACKIFG: // NAK received (master only) break; case USCI_I2C_UCSTTIFG: // START condition detected with own address (slave mode only) break; case USCI_I2C_UCSTPIFG: // STOP condition detected (master & slave mode) break; case USCI_I2C_UCRXIFG3: // RXIFG3 break; case USCI_I2C_UCTXIFG3: // TXIFG3 break; case USCI_I2C_UCRXIFG2: // RXIFG2 break; case USCI_I2C_UCTXIFG2: // TXIFG2 break; case USCI_I2C_UCRXIFG1: // RXIFG1 break; case USCI_I2C_UCTXIFG1: // TXIFG1 break; case USCI_I2C_UCRXIFG0: // RXIFG0^ // read one byte RXData = UCB0RXBUF; break; case USCI_I2C_UCTXIFG0: // TXIFG0 if(byte_counter == 1) { // send the register to read //UCB0TXBUF = 0x75; EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0); UCB0TXBUF = 0x6B; byte_counter--; } else if(byte_counter == 0) { if(write_read) { // go on writing EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0); UCB0TXBUF = 0xFF; // add quickly a new counter byte_counter = 100; } else { // clear and disable interrupt EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0); EUSCI_B_I2C_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0); //Set in receive mode EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE ); // enable receive interrupt EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0); // start condition UCB0CTLW0 |= UCTXSTT; //Poll for start condition transmission while(UCB0CTLW0 & UCTXSTT); // send stop UCB0CTLW0 |= UCTXSTP; } } else if(byte_counter == 100) { // send stop UCB0CTLW0 |= UCTXSTP; // clear and disable interrupt EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0); EUSCI_B_I2C_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0); } else { // not aloud while(1){} } break; case USCI_I2C_UCBCNTIFG: // Byte count limit reached (UCBxTBCNT) break; case USCI_I2C_UCCLTOIFG: // Clock low timeout - clock held low too long break; case USCI_I2C_UCBIT9IFG: // Generated on 9th bit of a transmit (for debugging) break; default: break; } }
first i read and than i write. However i think that the writing process doesn't work. I don't read the value i wrote and after writing the data in the writing process the UCSTPIEG flag gets set. According to the Familiy users guide on pg. 829 this means data wasn't sent. (
"If UCTXSTP is
set during the transmission of the slave address or while the eUSCI_B module waits for data to be written
into UCBxTXBUF, a STOP condition is generated, even if no data was transmitted to the slave. In this
case, the UCSTPIFG is set. ")
What do i need to change to make my code work?
Thanks in advance and best regards