2019-08-22 02:53 AM
I'm working on stm32f103 I2C peripheral. I've one stm32f103 master and another stm32f103 slave. The master should send some text to the slave, but start condition never generates. The BUSY flag is set as soon as the peripheral is enable and the program hangs on a loop that waits until start condition is generated.
( i.e
// Wait until start condition is generated
while(!(I2C1->SR1 & I2C_SR1_S){}
)
#include "stm32f10x.h" // Device header
void clockConfig(void);
void I2C1Init(void);
void I2C1Send(uint8_t* MSG);
int main(void)
{
clockConfig();
I2C1Init();
I2C1Send((uint8_t*)"Hello, I2C1!");
while(1)
{
}
}
void I2C1Send(uint8_t* MSG)
{
// Generate start bit
I2C1->CR1 |= I2C_CR1_START;
// Wait until start condition is generated
while(!(I2C1->SR1 & I2C_SR1_SB)){} /* the program stops here*/
// clear start condition flag
uint32_t dummyRead = I2C1->SR1;
// Write slave address, and master transmitter mode
I2C1->DR = 0x72;
// Wait until address phase is complete
while(!(I2C1->SR1 & I2C_SR1_ADDR)){}
// Clear ADDR
dummyRead = I2C1->SR1;
dummyRead = I2C1->SR2;
while(*MSG)
{
// Wait until TXE flag is set
while(!(I2C1->SR1 & I2C_SR1_TXE)){}
I2C1->DR = *MSG;
MSG++;
}
// Wait unitl byte trasfer finished flag
while(!(I2C1->SR1 & I2C_SR1_BTF)){}
// program stop condition
I2C1->CR1 |= I2C_CR1_STOP;
// BTF flag is cleared by hardware
}
void I2C1Init(void)
{
// Enable clock access for port B
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
// Configure Gpios as af open drain
GPIOB->CRL |= GPIO_CRL_CNF6 | GPIO_CRL_MODE6;
// Enable internal pull up
GPIOB->ODR |= GPIO_ODR_ODR6;
GPIOB->CRL |= GPIO_CRL_CNF7 | GPIO_CRL_MODE7;
// Enable internal pull up
GPIOB->ODR |= GPIO_ODR_ODR7;
// Configure I2C1
// Enable clock access for I2C1
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
// Configure APB1 frequency
I2C1->CR2 |= 36;
// configure CCR
I2C1->CCR |= 180; // 100KHz standard mode
// Configure the rise time register
I2C1->TRISE |= 37;
// Enable I2C1
I2C1->CR1 |= I2C_CR1_PE;
// Enable ACK
I2C1->CR1 |= I2C_CR1_ACK;
}
/* This sets all peripherals to their maximum speed.*/
void clockConfig(void)
{
// HSE ON
RCC->CR |= 0x1<<16;
// wait unit HSE is ready
while(!(RCC->CR & (0x1<<17))){}
// PLL OFF
RCC->CR &= ~(0x1<<24);
//HSE clock not divided
RCC->CFGR &= ~(0x1<<17);
// PLL SRC = HSE
RCC->CFGR |= 0x1<<16;
// PLL MUL, x9
RCC->CFGR &= ~(0xF<<18);
RCC->CFGR |= 0x7<<18;
// PLL ON
RCC->CR |= 0x1<<24;
// wait until PLL is ready
while(!(RCC->CR & (0x1 << 25))){}
// choose PLL as Sys clock
RCC->CFGR &= ~(0x3);
RCC->CFGR |= 0x2;
// AHB prescaler x1
RCC->CFGR &= ~(0xF<<4);
// APB1 (36MHz max ) prescaler /2
RCC->CFGR &= ~(0x7<<8);
RCC->CFGR |= (0x4<<8);
// APB2(72MHz) prescaler x1
RCC->CFGR &= ~(0x7<<11);
}
Solved! Go to Solution.
2019-08-22 07:52 AM
Hi @ASeyo ,
Please make sure that the sequence recommended in the product errata sheet (I2C analog filter may provide wrong value, locking BUSY flag and preventing master mode entry) is well applied.
Here the link to the errata sheet document.
-Amel
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2019-08-22 07:52 AM
Hi @ASeyo ,
Please make sure that the sequence recommended in the product errata sheet (I2C analog filter may provide wrong value, locking BUSY flag and preventing master mode entry) is well applied.
Here the link to the errata sheet document.
-Amel
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2024-05-07 07:40 AM
Is there a sample mxcube generated code with errata applied?