cancel
Showing results for 
Search instead for 
Did you mean: 

Issue to implement I2C using STM32F0

SKUMA.19
Associate

Hi everyone I am trying to implement I2C Write and Read with DS3231. I am using stm32f051r8t6. I do not want to implement this using CUBE. Kindly help me in identifying the mistakes I have done. I am able to write and read but what I write does not affect the rtc registers to which I write a data. The data resets to its default value in the next read cycle. It wil be very helpful if anyone can point where I am making the mistake.

1 REPLY 1
SKUMA.19
Associate
void I2C_config()
{
 
	//Enabling the clock for PortB
	RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
 
	//Clock enable for I2C1 peripheral
	RCC->APB1ENR |= (RCC_APB1ENR_I2C1EN); //Clock enable for the I2C peripheral
	//PF0 and PF1 to be configured as SCL and SDA respectively [I2C1 peripheral chosen]
 
	//Configuring the GPIO pins to alternate function
	GPIOB->MODER |= ((GPIO_MODER_MODER6_1) | (GPIO_MODER_MODER7_1));
	GPIOB->MODER  &= ~(GPIO_MODER_MODER7_0 | GPIO_MODER_MODER7_0);
 
	//Configuring the GPIO pins assigned for I2C in open-drain
	GPIOB->OTYPER |= (GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7);
 
	//Configuring the speed of GPIO pins
	GPIOB->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEEDR6 | GPIO_OSPEEDR_OSPEEDR7);
 
	//Configuring the alternate functions for the mapped GPIO pins [PB6 and PB7]  ---> Alternate function 1 is Set for the pins --> AF1 is I2C for
	GPIOB->AFR[0] |= (1<<24) | (1<<28);
 
 
	I2C1->TIMINGR = (uint32_t)0x1042F013;//(uint32_t)0x00503D5A;//(uint32_t)0x0010020A; //I2C Timing register helps the controller set the fall and rise time from its peripheral to the slave device
	I2C1->CR1 |= (I2C_CR1_PE)  | (I2C_CR1_RXIE) | (I2C_CR1_TXIE); //I2C peripheral being enabled and Receive interrupt enabled
 
	I2C1->ISR = 0b00000001;
 
	NVIC_SetPriority(I2C1_IRQn,1);
	NVIC_EnableIRQ(I2C1_IRQn);
 
 
	trace_printf("\n I2C__Config done");
 
	 ISR_reg_val = I2C1->ISR;
	    		trace_printf("\n %u", ISR_reg_val);
}
 
void I2C1_IRQHandler()
{
	if((I2C1->ISR & I2C_ISR_RXNE) == I2C_ISR_RXNE)
	{
		recvd_byte = I2C1->RXDR;
 
		I2C1->ICR |= I2C_ICR_NACKCF;
	}
}
 
void I2C_Write_Reg()//uint32_t Device,uint32_t Register, uint32_t Data){
{
 
	trace_printf("\n I am in Write");
 
	//Reset CR2 Register
		I2C1->CR2 = 0x00000000;
 
		//Check to see if the bus is busy
		while((I2C1->ISR & I2C_ISR_BUSY) == I2C_ISR_BUSY);
 
 
		//Mentioning the rtc_slave addr in Write mode
		I2C1->CR2 |= (I2C_CR2_SADD & EEPROM_W);
 
		//Set CR2 for 2-Byte Transfer, for Device
	    I2C1->CR2 |= (1UL<<16); //| (EEPROM_W<<1);
 
		//Start communication
		I2C1->CR2 |= I2C_CR2_START;
 
		//Check Tx empty before writing to it
		if((I2C1->ISR & I2C_ISR_TXE) == (I2C_ISR_TXE)){
			I2C1->TXDR = reg_addr;
		}
 
		//Wait for TX Register to clear
		while((I2C1->ISR & I2C_ISR_TXE) == 0);
 
		//Check Tx empty before writing to it
		if((I2C1->ISR & I2C_ISR_TXE) == I2C_ISR_TXE){
			I2C1->TXDR = i2c_val;
		}
 
		//Wait for transfer to complete
		while((I2C1->ISR & I2C_ISR_TC) == 0);
 
		//Send Stop Condition
		I2C1->CR2 |= I2C_CR2_STOP;
 
		//Check to see if the bus is busy
		while((I2C1->ISR & I2C_ISR_BUSY) == I2C_ISR_BUSY);
 
		//Clear Stop bit flag
	I2C1->ICR |= I2C_ICR_STOPCF;
 
 
	trace_printf("\n Write done");
 
 
 
 
 
	/*
	//I2C1->CR1 |= (I2C_CR1_PE);
	trace_printf("\n I am in Write");
	//Reset CR2 Register
	I2C1->CR2 = 0x00000000;
	I2C1->ISR = 0x00000001;
 
	//Check to see if the bus is busy
	while((I2C1->ISR & I2C_ISR_BUSY) == I2C_ISR_BUSY);
 
	//Mentioning the rtc_slave addr in Write mode
		I2C1->CR2 |= (I2C_CR2_SADD & EEPROM_W);
		//I2C1->CR2 |= (1<<4 | 1<<6 | 1<<7);
 
 
		//Set CR2 for 1-Byte Transfer, for Device
		I2C1->CR2 |= (1UL<<16);
 
		//Start communication
	    I2C1->CR2 |= I2C_CR2_START;
 
	    trace_printf("\n I2C started");
	//I2C1->CR2 &= ~(1<<0);// Clearing the 0th bit for a Write operation
 
 
	//Wait for TXDR Register to become empty
	while((I2C1->ISR & I2C_ISR_TXE) == 0);
 
	trace_printf("\n TXDR empty");
 
	//Check Tx empty before writing to it
	if((I2C1->ISR & I2C_ISR_TXE) == (I2C_ISR_TXE)){
		I2C1->TXDR = reg_addr;
	}
 
	trace_printf("\n reg addr given");
 
	I2C1->ISR |= I2C_ISR_TXE;
	trace_printf("\n Set TXE bit high to flush TXDR reg");
 
	 ISR_reg_val = I2C1->ISR;
	    trace_printf("\n %u",ISR_reg_val);
 
 
 
	//Wait for transfer to complete
    while((I2C1->ISR & I2C_ISR_TC) == 0);
    trace_printf("\n Transfer complete");
 
 
	//Set CR2 for 1-Byte Transfer, for Device
	I2C1->CR2 |= (1UL<<16);
 
	//Wait for TXDR Register to become empty
    while((I2C1->ISR & I2C_ISR_TXE) == 0);
 
 
	//Check Tx empty before writing to it
	if((I2C1->ISR & I2C_ISR_TXE) == I2C_ISR_TXE){
		I2C1->TXDR = i2c_val;
	}
 
	//while(!((I2C1->CR2 & I2C_CR2_NACK) == 0));
	//trace_printf("\n ACK received : data");
 
	//Wait for transfer to complete
	while((I2C1->ISR & I2C_ISR_TC) == 0);
 
	//Send Stop Condition
	I2C1->CR2 |= I2C_CR2_STOP;
 
	//Check to see if the bus is busy
	while((I2C1->ISR & I2C_ISR_BUSY) == I2C_ISR_BUSY);
 
	//Clear Stop bit flag
	I2C1->ICR |= I2C_ICR_STOPCF;
 
	trace_printf("\n Write done");
 
	//I2C1->CR1 &= ~(I2C_CR1_PE);
 
	 */
}
 
 
 
void I2C_data_Read()
{
 
 
 
	trace_printf("\n\n Inside Read");
 
	//Reset CR2 Register
    I2C1->CR2 = 0x00000000;
 
    //Reset CR2 Register
    I2C1->ISR = 0x00000001;
    ISR_reg_val = I2C1->ISR;
    trace_printf("\n %u", ISR_reg_val);
 
 
	//Check to see if the bus is busy
    while((I2C1->ISR & I2C_ISR_BUSY) == I2C_ISR_BUSY);
 
    //Mentioning the rtc_slave addr in Read mode
	I2C1->CR2 |= (I2C_CR2_SADD & EEPROM_W);
 
	//Set CR2 for 1-byte transfer for Device
	I2C1->CR2 |=(1UL<<16);
 
	//Start communication
	I2C1->CR2 |= I2C_CR2_START;
 
	//Checking TXDR Register to become empty
	while((I2C1->ISR & I2C_ISR_TXE) == 0);
 
	//Check Tx empty before writing to it
	if((I2C1->ISR & I2C_ISR_TXE) == (I2C_ISR_TXE))
	{
		I2C1->TXDR = reg_addr;
	}
	trace_printf("\n reg specified to slave");
 
	I2C1->ISR |=  I2C_ISR_TXE;
	trace_printf("\n TXDR reg is flushed");
 
	//Wait for transfer to complete
	while((I2C1->ISR & I2C_ISR_TC) == 0);
 
	trace_printf("\n Transfer complete");
 
	//Specifying the Slave address from which data is to be read
	I2C1->CR2 |= (I2C_CR2_SADD & EEPROM_R);
 
	//Set CR2 for 1-byte transfer, in read mode for Device
	I2C1->CR2 |= (1UL<<16) | I2C_CR2_RD_WRN;
 
	//Start communication
	I2C1->CR2 |= I2C_CR2_START;
 
	//Wait for transfer to complete
	while((I2C1->ISR & I2C_ISR_TC) == 0);
 
 
	
 
		//ISR_reg_val = I2C1->ISR;
		//trace_printf("\n %u", ISR_reg_val);
 
		
		//Send Stop Condition
		I2C1->CR2 |= I2C_CR2_STOP;
 
		//Check to see if the bus is busy
		while((I2C1->ISR & I2C_ISR_BUSY) == I2C_ISR_BUSY);
 
		//Clear Stop bit flag
		I2C1->ICR |= I2C_ICR_STOPCF;
 
		//return(I2C1_RX_Data);
 
		  I2C1->ICR |= I2C_ICR_NACKCF;
	  trace_printf("\n Receive wait over");
	  //return(recvd_byte);
}