cancel
Showing results for 
Search instead for 
Did you mean: 

ADDR bit is not set in I2C

ASeyo
Associate II

Hi I'm trying to configure stm32f103 as a master to write data to slave EEPROM chip. The master generates a start condition but slave doesn't acknowledge the address ( the address is mentioned in the datasheet though )

#include "stm32f10x.h"                  // Device header
#define SLAVEADDR 0b10100000
void clockConfig(void);
void I2CInit(void);
void sendByte(uint8_t mem_addr, uint8_t data);
void delayMs(uint32_t delay);
int main(void)
{
	clockConfig();
	I2CInit();
	sendByte(0x00, 'H');
	delayMs(10);
	while(1)
	{
	}
}
 
void sendByte(uint8_t mem_addr, uint8_t data)
{
	I2C2->CR1 |= I2C_CR1_START;        // Generate start condition
	while(!(I2C2->SR1 & I2C_SR1_SB)){} // Wait until start condition is sent
  I2C2->DR = SLAVEADDR; 
	while(!(I2C2->SR1 & I2C_SR1_ADDR)){} // Wait until address phase completes
	uint32_t temp;
	temp = I2C2->SR2;       // Clear ADDR
	I2C2->DR = mem_addr;    // EEPROM internal memory address
	while(!(I2C2->SR1 & I2C_SR1_TXE)){}
	I2C2->DR = data; // write value to the specified EEPROM address
	while(!(I2C2->SR1 & I2C_SR1_BTF)){}
	I2C2->CR1 |= I2C_CR1_STOP;
}
 
void I2CInit(void)
{
	/* 
	  Pinout
		I2C2_SCL: PB10
		I2C2_SDA: PB11
	*/
	
	// Enable clock access for port B
	RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
	
	// configure I2C2
	// Enable clock access for I2C2
	RCC->APB1ENR |= RCC_APB1ENR_I2C2EN;
	I2C2->CR1 |= 36; // APB1 clock frquency
	I2C2->CCR |= 180; // 100KHz standard mode
	I2C2->TRISE |= 37;
	I2C2->CR1 |= I2C_CR1_ACK; // Enable ACKing
	
	/* Unlock analog filters for a possible HIGH state */
  GPIOB->CRH |= GPIO_CRH_CNF10_0 | GPIO_CRH_MODE10 |
	              GPIO_CRH_CNF11_0 | GPIO_CRH_MODE11;  // general purpose output open drains
	GPIOB->ODR |= GPIO_ODR_ODR10 | GPIO_ODR_ODR11;
	GPIOB->ODR &= ~(GPIO_ODR_ODR10 | GPIO_ODR_ODR11);
	GPIOB->ODR |= GPIO_ODR_ODR10 | GPIO_ODR_ODR11;
	
	/* Software reset */
	I2C2->CR1 |= I2C_CR1_SWRST;
	I2C2->CR1 &= ~I2C_CR1_SWRST;
	
	/* Configure SDA and SCL as AF open drains */
  GPIOB->CRH |= GPIO_CRH_CNF10 | GPIO_CRH_MODE10 |
	              GPIO_CRH_CNF11 | GPIO_CRH_MODE11;
								
								
	I2C2->CR1 |= I2C_CR1_PE;
}
 
 
void delayMs(uint32_t delay)
{
	SysTick->LOAD = 72000-1;
	SysTick->VAL = 0;
	SysTick->CTRL |= SysTick_CTRL_CLKSOURCE | SysTick_CTRL_ENABLE;
	for ( int i = 0; i < delay; i++)
	  while(!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG)){}
}
 
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);
}	
 

ddress.

1 REPLY 1
SShin.18
Associate II

I used stm32L4xx controller for I2C interfacing, as I know I2C peripheral register should be accessed using 32bit access. you should try using 32 bit access.