cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H743ZI Bizzare behavior from I2C with Reload = 1

CLeo.1
Senior II

Hi everyone, 
Trying to create an eeprom API based on the AT24CM01 ASIC chip. I got the Byte write working no problem, however the IC is capable of doing sequential writes up to 256 bytes. The way I am doing this is setting the 'RELOAD' value within the I2C to '1'. While debugging I notice that the TCR flag sets itself even though I havent read the number of bytes transferred yet.

Here is the code in question:
All this is doing is checks if I am going to be writing more than 256 bytes and if so when I reach the max number of bytes (0xFF/255) I just reload the NBYTES with another 0xFF to send another "unlimited" amount of data. The problem is the TCR flag somehow sets itself before getting to the while loop waiting for the TXE, and wont ready the TXE flag anymore due to TCR flag being set, thus having me be stuck in it. 

for (DATA_FRAME_CNT; DATA_FRAME_CNT < DATA_FRAME_LEN; DATA_FRAME_CNT++) {

		if (DATA_FRAME_CNT == 0xFFU) {
			LL_I2C_SetTransferSize(I2C_BUS, 0xFFU);
		}

		*(uint8_t*)(&I2C_BUS->TXDR) = DATA_FRAME[DATA_FRAME_CNT];
		while (LL_I2C_IsActiveFlag_TXE(I2C_BUS) == 0); -> getting stuck here
	}

I found out if I halt the CPU, and manually write the NBYTES myself, I can see the TCR flag clear and no longer sets itself and exits out of the for loop. 

The state of the I2C registers when the CPU is halted and stuck at the while loop, after NBYTES has been set again to 0xFF.

CLeo1_0-1695410297338.png

My intention of this code is to write more than 256 Bytes by once reaching the 255 byte mark just simply reload the NBYTES register with another 0xFF and have the for loop exit itself and then initiate a stop condition at the end. 

The reason I am sending more than 256 bytes here because of the eeprom word address bytes is included in the transcation so a total of 258 Bytes needs to be sent (256 worth of data and 2 Address Bytes). 

Any advice? I am stumped. 


 

 

3 REPLIES 3
TDJ
Lead

@CLeo.1 Is clock stretching enabled?

You have to fragment the write(s). The page buffer is 256-bytes, and deals with addresses on 256-byte boundaries, so your code will need to decompose so it doesn't span pages.

Perhaps look at the HAL command form typically used for this type of EEPROM transfer

HAL_StatusTypeDef status = HAL_I2C_Mem_Write(&I2CHandle, ((0x50 | ((address >> 16) & 1) << 1), address & 0xFFFF, 2, buffer, size, 100); // 17-bit address

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Foued_KH
ST Employee

Hello @CLeo.1 , 

You can take a look at the available examples in the STM32H7CubeFW: 
stm32cube_fw_h7_v1_4_0/Projects/STM32H743I-EVAL/Examples/I2C/I2C_EEPROM_fast_mode_plus at master · suburbanembedded/stm32cube_fw_h7_v1_4_0 · GitHub

Foued

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.