AnsweredAssumed Answered

USART2 - I2C1 problem in STM32F1

Question asked by martin.sergio on Mar 14, 2014
Latest reply on Mar 14, 2014 by martin.sergio
When I send data to the USART2 it's well received BUT after that the last data character  keeps being received until filling up my reception buffer. Note that in the same application I'm also using I2C1 to transmit other data.

After some debugging, I went through the STM32F103RG product manual , page 272, figure 50 - DMA1 Request Mapping picture states that the USART2 and I2C1 share the DMA1 channels.

I kept doing some testing, concluding that this happens when using:
- USART2 with DMA RX enabled, and
- I2C1 in master mode using the IRQ Handlers as in "OptimizedI2Cexamples", EVEN with DMA disabled.

I can avoid this problem making 2 tricks:
1) Or disabling the USART2 DMA.
2) Or writing into the I2C1 using the "I2C_CheckEvent function" way, instead of using the I2C1 IRQ Handlers way as in "OptimizedI2Cexamples".

Well, I don't know exactly why this problem occurs. Is there any kind of incompatibility between the USART2 with DMA mode  and the I2C1 with IRQ Handlers?

This is my USART2 configuration:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
 
USART_DeInit(USART2);
 
USART_StructInit(&USART_InitStruct);
USART_InitStruct.USART_BaudRate = 57600;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_Mode = (USART_Mode_Rx | USART_Mode_Tx);
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART2, &USART_InitStruct);
 
USART_ClearFlag(USART2, USART_FLAG_RXNE | USART_FLAG_TC);
 
USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);

This is the DMA configuration:
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
 
DMA_DeInit(DMA1_Channel6);
 
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_PeripheralBaseAddr = USART2->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = rx_buf;
DMA_InitStructure.DMA_BufferSize = rx_buf_sz;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
 
DMA_Init(DMA1_Channel6, &DMA_InitStructure);

And the I2C configuration:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
I2C_DeInit(I2C1 );
  
I2C_ClearFlag(I2C1, I2C_FLAG_SMBALERT | I2C_FLAG_TIMEOUT | I2C_FLAG_PECERR | I2C_FLAG_OVR | I2C_FLAG_AF | I2C_FLAG_ARLO | I2C_FLAG_BERR);
  
I2C_ClearITPendingBit(I2C1, I2C_IT_SMBALERT | I2C_FLAG_TIMEOUT | I2C_IT_PECERR | I2C_IT_OVR | I2C_IT_AF | I2C_IT_ARLO | I2C_IT_BERR);
              
I2C_ITConfig(I2C1,I2C_IT_EVT,ENABLE);
I2C_ITConfig(I2C1,I2C_IT_ERR,ENABLE);
I2C_ITConfig(I2C1,I2C_IT_BUF,ENABLE);

I really hope to hear from you :-p

Outcomes