cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103C8 and I2C CMSIS problem to access to my MPU9250. Please help.

DAlat.1
Associate II
void initI2C()
{
      SET_BIT(GPIOB->CRL, GPIO_CRL_CNF7_1 | GPIO_CRL_CNF6_1 | GPIO_CRL_CNF7_0 | 
                                    GPIO_CRL_CNF6_0 |\
				  GPIO_CRL_MODE7_1 | GPIO_CRL_MODE6_1 | GPIO_CRL_MODE7_0 | 
                              GPIO_CRL_MODE6_0);
	SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPBEN);
	//RCC peripheral clock enabling
	SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);
	//Delay after an RCC peripheral clock enabling
	__IO uint32_t tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);
	//Disable  acknowledge on Own Address2 match address
	CLEAR_BIT(I2C1->OAR2, I2C_OAR2_ENDUAL);
	//Disable General Call
	CLEAR_BIT(I2C1->CR1, I2C_CR1_ENGC);
	//Enable Clock stretching
	CLEAR_BIT(I2C1->CR1, I2C_CR1_NOSTRETCH);
	//Disable I2C peripheral
	CLEAR_BIT(I2C1->CR1, I2C_CR1_PE);
	//ClockSpeed
	MODIFY_REG(I2C1->CR2, I2C_CR2_FREQ, 36);
	//MODIFY_REG(I2C1->TRISE, I2C_TRISE_TRISE, 36 + 1); //100
	MODIFY_REG(I2C1->TRISE, I2C_TRISE_TRISE, 11); //400
	//MODIFY_REG(I2C1->CCR, (I2C_CCR_FS | I2C_CCR_DUTY | I2C_CCR_CCR), 180); //100
	MODIFY_REG(I2C1->CCR, (I2C_CCR_FS | I2C_CCR_DUTY | I2C_CCR_CCR), 0x0000801E); //400
	//Set the Own Address1
	MODIFY_REG(I2C1->OAR1, I2C_OAR1_ADD0 | I2C_OAR1_ADD1_7 | I2C_OAR1_ADD8_9 | I2C_OAR1_ADDMODE, I2C_OWNADDRESS1_7BIT);
	//Configure I2C1 peripheral mode with parameter : I2C
	MODIFY_REG(I2C1->CR1, I2C_CR1_SMBUS | I2C_CR1_SMBTYPE | I2C_CR1_ENARP, I2C_MODE_I2C);
	//Enable I2C peripheral
	SET_BIT(I2C1->CR1, I2C_CR1_PE);
	//TypeAcknowledge
	MODIFY_REG(I2C1->CR1, I2C_CR1_ACK, I2C_CR1_ACK);
	//Set the 7bits Own Address2
	MODIFY_REG(I2C1->OAR2, I2C_OAR2_ADD2, 0);
}

and here is read/write functions

void	write(uint8_t devAddress, uint16_t regAddress, uint8_t data)
{
	__IO uint16_t temp;
 
	SET_BIT(I2C1->CR1, I2C_CR1_PE);
	I2C1->CR1 |= I2C_CR1_ACK;
	
	// send START
	I2C1->CR1 |= I2C_CR1_START;
	while(!(I2C1->SR1 & I2C_SR1_SB));
	temp = I2C1->SR1;
	
	// by writing DR clear SB flag and send address
	I2C1->DR = devAddress;
	while(!(I2C1->SR1 & I2C_SR1_ADDR));
	temp = I2C1->SR1;
	temp = I2C1->SR2;
	
	// send slave register address
	I2C1->DR = regAddress;
	while(!(I2C1->SR1 & I2C_SR1_TXE));
 
	// send data and clear TXE flag
	I2C1->DR = data;
	while(!(I2C1->SR1 & I2C_SR1_TXE));
 
	// send stop
	I2C1->CR1 |= I2C_CR1_STOP;
	//while((I2C1->SR1 & I2C_SR1_STOPF));
}
 
void 	read(uint8_t devAddress, uint16_t regAddress, uint8_t *data, const uint8_t &len)
{
	__IO uint16_t temp;
 
	SET_BIT(I2C1->CR1, I2C_CR1_PE);
	I2C1->CR1 |= I2C_CR1_ACK;
 
	// send START
	I2C1->CR1 |= I2C_CR1_START;
	while(!(I2C1->SR1 & I2C_SR1_SB));
	temp = I2C1->SR1;
	
	// send DEV ADDRESS
	I2C1->DR = devAddress;
	while(!(I2C1->SR1 & I2C_SR1_ADDR));
	temp = I2C1->SR1;
	temp = I2C1->SR2;
 
	// send register address
	I2C1->DR = regAddress;
	while(!(I2C1->SR1 & I2C_SR1_TXE)); 
	
	// send START
	I2C1->CR1 |= I2C_CR1_START;
	while(!(I2C1->SR1 & I2C_SR1_SB));  
	temp = I2C1->SR1;
	
	// send DEVADDRESS read mode
	I2C1->DR = devAddress | 1;
	while(!(I2C1->SR1 & I2C_SR1_ADDR));
	temp = I2C1->SR1;
	temp = I2C1->SR2;
	
	for(uint8_t i = 0; i<len; i++)
	{
		if(i < (len - 1))
		{
			while(!(I2C1->SR1 & I2C_SR1_RXNE));
			*(data+i) = I2C1->DR;
		}
		else
		{
			I2C1->CR1 &= ~I2C_CR1_ACK;
			I2C1->CR1 |= I2C_CR1_STOP;
 
			while(!(I2C1->SR1 & I2C_SR1_RXNE));
			*(data+i) = I2C1->DR;
		}
	}
}

After I setup my MPU9250 and sometimes it stalls in

while(!(I2C1->SR1 & I2C_SR1_ADDR));

sometimes in

while(!(I2C1->SR1 & I2C_SR1_SB));

sometimes

I2C_SR1_AF

is 1, . Please Help, if you need additional information I can send it.

0 REPLIES 0