cancel
Showing results for 
Search instead for 
Did you mean: 

Question about I2C TXIS bit in stm32g071rb

dmrsim
Associate III

Hello, 

I'm studing I2C on stm32g071rb and I have a question about it.

In the datasheet there is this line: "In the case of a write transfer, the TXIS flag is set after each byte transmission, after the 9th SCL pulse when an ACK is received", but for the last byte TXIS remain LOW and TC become HIGH.

It's correct that for the last byte that I have to send via I2C, the TXIS bit remain LOW?

For example if I have to send(master to slave): 0x00, 0x01, 0x02

I set the CR2_NBYTES bit (3 << I2C_CR2_NBYTES_Pos)...etc

But after send the 0x02 byte, only TC is HIGH...so also the TXIS bit should be HIGH in this case?

Thanks

 

Simeon

6 REPLIES 6

> I set the CR2_NBYTES bit (3 << I2C_CR2_NBYTES_Pos)...etc

What is "etc"? Details do matter, so post code and observed waveforms.

JW

 

PS. For your reference, an example, manually walked through in debugger, here - the first example is the correct/expected behaviour of the I2C registers/flags for given peripheral (SHT31).

dmrsim
Associate III

Hello, at the moment I have a problem with my oscilloscope and I have to fix it...
My code(sorry for code quality but  at the moment is only a test), I followed the datasheet flowchart(image in attach).
Do you think that I make some mistakes?
The slave seems to send an ACK at the moment.
I have 2 questions:

1) Sometimes at the end of the transmission, the TC bit remain low but I notices that if I put some delay before the TC check it work(as if I had to wait a certain time first, but in the flowchat I don't see this)

2) It's correct that for the last byte TXIS remain low?


Thanks a lot!

Simeon

 

 

void i2c_enable()
{
	RCC->IOPENR |= RCC_IOPENR_GPIOBEN_Msk;
	RCC->APBENR1 |= RCC_APBSMENR1_I2C1SMEN_Msk;

	GPIOB->MODER &= ~(GPIO_MODER_MODE8_Msk | GPIO_MODER_MODE9_Msk);
	GPIOB->MODER |= (GPIO_MODER_MODE8_1 | GPIO_MODER_MODE9_1);

	GPIOB->OSPEEDR |= (GPIO_OSPEEDR_OSPEED8_1 | GPIO_OSPEEDR_OSPEED9_1);

	GPIOB->AFR[1] |= GPIO_AFRH_AFSEL8_1
			| GPIO_AFRH_AFSEL8_2
			| GPIO_AFRH_AFSEL9_1
			| GPIO_AFRH_AFSEL9_2;

	GPIOB->OTYPER |= (GPIO_OTYPER_OT8 | GPIO_OTYPER_OT9);

	I2C1->CR1 &= ~(I2C_CR1_PE_Msk); //clean PE bit

	//clock configuration
	I2C1->TIMINGR |= 1 << I2C_TIMINGR_PRESC_Pos
			| 2 << I2C_TIMINGR_SDADEL_Pos
			| 3 << I2C_TIMINGR_SCLDEL_Pos
			| 3 << I2C_TIMINGR_SCLH_Pos
			| 9 << I2C_TIMINGR_SCLL_Pos;

	I2C1->CR1 |= I2C_CR1_PE_Msk;
}

void i2cSendStartCondition()
{
	while((I2C1->ISR & I2C_ISR_BUSY_Msk)) {
		printf("BUS not free!!!\r\n"); // wait for free bus
	}

	I2C1->CR2 |= I2C_CR2_START_Msk; // SEND START CONDITION

	while ((I2C1->CR2 & I2C_CR2_START_Msk)) {
		//start = 0, wait for start sended on BUS
		printf("Waiting\r\n");
		if (I2C1->ISR & I2C_ISR_NACKF_Msk) {
				printf("ERROR: NACK received\r\n");
				return;
		}
	}

	while (!(I2C1->ISR & I2C_ISR_TXIS_Msk)) {
		printf("Wait for ack\r\n");
		if (I2C1->ISR & I2C_ISR_NACKF_Msk) {
			printf("ERROR: NACK received\r\n");
			return;
		}

	}

}


void i2cMasterSendData2(uint8_t slaveAddr, uint8_t addr, uint8_t *data, uint8_t len)
{
	i2cMasterInit(slaveAddr, false);
	I2C1->TXDR = addr;

	for (int i = 0; i < len; i++) {
		while (!(I2C1->ISR & I2C_ISR_TXIS_Msk)) {
			printf("Wait for TXIS\r\n");
			if (I2C1->ISR & I2C_ISR_NACKF_Msk) {
				printf("ERROR: NACK received\r\n");
				return;
			}
		}
		printf("send data");

		I2C1->TXDR = data[i];
	}

	if ((I2C1->ISR & I2C_ISR_TC_Msk)) {
		printf("TC setted: %u\r\n", I2C1->ISR);
		//send stop condition
		I2C1->CR2 |= I2C_CR2_STOP_Msk;
	} else {
		printf("ISR: %u,  \r\n", I2C1->ISR);

		printf("TC not setted\r\n");
	}

}

 

 

 

> set the CR2_NBYTES bit (3 << I2C_CR2_NBYTES_Pos)...etc

I don't see that in the above code.

Try to step through it, reading out and printing/displaying I2C_ISR and I2C_CR2 after each relevant step; post resulting sequence.

JW

OK I think I understand what is the source of your confusion. I believe the flowchart is not quite correct. We might've discussed this here before, I can't find that thread at the moment.

> 1) Sometimes at the end of the transmission, the TC bit remain low but I notices that if I put some delay before the TC check it work(as if I had to wait a certain time first, but in the flowchat I don't see this)

After storing the last byte to TXDR, it takes time until it gets transmitted. Only after the last byte gets transmitted is TC set.

> 2) It's correct that for the last byte TXIS remain low?

Yes. Again, the narrative and the flowchart is not quite correct. The intention is, that TXIS is not indicator of "transmit register got empty" but "transmit register needs data"; the distinction is exactly that after the NBYTE bytes have been transmitted, there is no more "transmit register needs data" request.

waclawekjan_0-1709721332467.png

 

JW

Hello @waclawek.jan , thanks as always!

Yes you guessed the cause of my confusion.

For the answer to the first question, I have a doubt: How do I understand how many time I have to check the TC bit before report a I2C timeout?

However yesterday night I have checked the i2c write using an oscilloscope, I sended:

start + 0x40 + 0x05 + 0x02 + 0x01 + stop

As you can see in attacched image it seems to work correctly(could you check please?)

 

Simeon

 

 

dmrsim
Associate III