cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F051 as i2c slave - not 100% successful

kumen
Associate
Posted on July 04, 2017 at 01:17

Hi,

in my implementation, i2c slave address recognition on STM32F051 is not 100%. Followingcommunication works well. I'm using DMA.When I set HCLK frequency

to 8MHz (from HSI source), probability of address ACK and establishing i2c communication is about 10-20%. When I set

HCLK frequency

to1 or 2 MHz,

probability is nearly 100%.I have no explanation of this behaviour. This isn't dependent on i2c bus speed. Same on 20kHz and 400kHz. When address is missed on bus, no interrupt is generated.

I've read errata, but withoutluck. Increasing SYSCLK to 16MHz by PLL and selecting it as i2c clock source, didn't helped too. Shape of i2c signal is good. i2c timing configuration is from STM32CubeMX but project use StdPeriph drivers.

Tested on two discovery boards and on custom PCBs. Same behaviour.

Initialization of i2c

void init_I2C_DMA(I2C_TypeDef* I2Cx, uint8_t i2c_address)
{
 I2C_InitTypeDef I2C_InitStructure;
 NVIC_InitTypeDef NVIC_InitStructure;
 DMA_InitTypeDef DMA_InitStructure;
/*========================== Init I2C RCC =================================*/
 /* I2C Periph clock enable */
 if(I2Cx == I2C1)
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
 else
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
/* DeInit I2C */
 I2C_DeInit(I2Cx);
I2C_SlaveByteControlCmd(I2Cx, ENABLE);
 I2C_ReloadCmd(I2Cx,ENABLE);
 I2C_NumberOfBytesConfig(I2Cx, 0xFF);
 I2C_StopModeCmd(I2Cx, ENABLE);
 /* I2C configuration -------------------------------------------------------*/
 I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
 I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
 I2C_InitStructure.I2C_DigitalFilter = 0x00;
 I2C_InitStructure.I2C_OwnAddress1 = i2c_address << 1;
 I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
 I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
 //I2C_InitStructure.I2C_Timing = 0x00108EFB; //standart mode 20kHz
 //I2C_InitStructure.I2C_Timing = 0x00101D7C; //standart mode 50kHz
 //I2C_InitStructure.I2C_Timing = 0x2000090E; //standart mode 100kHz
 I2C_InitStructure.I2C_Timing = 0x0000020B; //fast mode 400kHz
 //I2C_InitStructure.I2C_Timing = 0x00000001; //fast mode plus 1MHz
 I2C_Init(I2Cx, &I2C_InitStructure);
 I2C_ITConfig(I2Cx, I2C_IT_TCI, ENABLE);
 I2C_ITConfig(I2Cx, I2C_IT_ERRI, ENABLE);
 I2C_ITConfig(I2Cx, I2C_IT_STOPI, ENABLE);
 I2C_ITConfig(I2Cx, I2C_IT_NACKI, ENABLE);
 I2C_ITConfig(I2Cx, I2C_IT_ADDRI, ENABLE);
/* DMA TRANSMITTER Configuration */
 /* DMA1 Channel2 Config */
 DMA_DeInit(DMA1_Channel2);
 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)I2C_TXDR_ADDRESS;
 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)i2c_transfering_data;
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
 DMA_InitStructure.DMA_BufferSize = 0xFF;
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
 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_VeryHigh;
 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
 DMA_Init(DMA1_Channel2, &DMA_InitStructure);
/* DMA RECEIVER Configuration */
 /* DMA1 Channel3 Config */
 DMA_DeInit(DMA1_Channel3);
 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)I2C_RXDR_ADDRESS;
 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)i2c_transfering_data;
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
 DMA_InitStructure.DMA_BufferSize = 0xFF;
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
 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_VeryHigh;
 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
 DMA_Init(DMA1_Channel3, &DMA_InitStructure);
 /* DMA1 Channel2 enable */
 DMA_Cmd(DMA1_Channel2, ENABLE);
 /* DMA1 Channel3 enable */
 DMA_Cmd(DMA1_Channel3, ENABLE);
I2C_DMACmd(I2Cx,I2C_DMAReq_Tx,ENABLE);
 I2C_DMACmd(I2Cx,I2C_DMAReq_Rx,ENABLE);
/* Configure the I2C interrupt priority */
 #ifdef I2C2_IRQn
 if(I2Cx == I2C1)
 NVIC_InitStructure.NVIC_IRQChannel = I2C1_IRQn;
 else
 NVIC_InitStructure.NVIC_IRQChannel = I2C2_IRQn
 #else
 NVIC_InitStructure.NVIC_IRQChannel = I2C1_IRQn;
 #endif
 NVIC_InitStructure.NVIC_IRQChannelPriority = 0x02;
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 NVIC_Init(&NVIC_InitStructure);
/* Enable I2C1 */
 I2C_Cmd(I2Cx, ENABLE);
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Thanks for any advice. What should i try??

#i2c #slave #stm32f0 #address #stm32f051 #clock
1 REPLY 1
Posted on July 06, 2017 at 00:32

I don't have experience with DMA on I2C, but doesn't the ISR interfere with the DMA?

JW