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