cancel
Showing results for 
Search instead for 
Did you mean: 

porting stm32f4 to stm32f1-stuck with ERROR: last event is different from I2C_EVENT

ajith sudhakaran
Associate
Posted on April 26, 2018 at 08:21

hi,

i was trying to port code from stm32f4 to stm32f1.

the code is used for obtaining gyroscope values from GY521(mPU6050) through i2c by dma.

and iam stuck with ERROR: last event is different from I2C_EVENT.

below is my 12c mpu setup function.

setup_i2c_for_mpu6050()

{

GPIO_InitTypeDef GPIO_InitStruct;

I2C_InitTypeDef I2C_InitStruct;

NVIC_InitTypeDef NVIC_InitStructure;

DMA_InitTypeDef DMA_InitStructure;

/* Use I2C1, with SCL on PB8 and SDA on PB7. */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

/* Reset the I2C unit. */

/* Enable DMA clock for I2C. */

RCC_APB1PeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

/* Configure I2C_EE pins: SCL and SDA */

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;

GPIO_Init(GPIOB, &GPIO_InitStruct);

/* Initialise DMA. */

DMA_ClearFlag(DMA1_FLAG_TC1|DMA1_FLAG_TE1|DMA1_FLAG_HT1);

DMA_DeInit(DMA1_Channel1);

//DMA_Cmd(DMA1_Channel1, DISABLE);

// DMA_DeInit(DMA1_Channel1);

/* Address of data register. */

DMA_InitStructure.DMA_PeripheralBaseAddr = I2C1_BASE + I2C_Register_DR;

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_Medium;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)mpu6050_reg_buffer;

DMA_InitStructure.DMA_BufferSize = 14;

DMA_DeInit(DMA1_Channel1);

DMA_Init(DMA1_Channel1, &DMA_InitStructure);

DMA_Cmd(DMA1_Channel1 , ENABLE ) ;

I2C_InitStruct.I2C_ClockSpeed = 100000;

I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;

I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;

I2C_InitStruct.I2C_OwnAddress1 = 0x00;

I2C_InitStruct.I2C_Ack = I2C_Ack_Disable;

I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

I2C_Init(I2C1, &I2C_InitStruct);

I2C_ITConfig(I2C1, I2C_IT_BUF|I2C_IT_EVT|I2C_IT_ERR, DISABLE);

/* Configure the I2C interrupts. */

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 10;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 10;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, DISABLE);

NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 10;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);

I2C_Cmd(I2C1, ENABLE);

}

when iam calling this below function it gets stucked

while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

I2C_CheckEvent function is given below------

ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)

{

  uint32_t lastevent = 0;

  uint32_t flag1 = 0, flag2 = 0;

  ErrorStatus status = ERROR;

  /* Check the parameters */

  assert_param(IS_I2C_ALL_PERIPH(I2Cx));

  assert_param(IS_I2C_EVENT(I2C_EVENT));

  /* Read the I2Cx status register */

  flag1 = I2Cx->SR1;

  flag2 = I2Cx->SR2;

  flag2 = flag2 << 16;

  /* Get the last event value from I2C status register */

  lastevent = (flag1 | flag2) & FLAG_Mask;

  /* Check whether the last event contains the I2C_EVENT */

  if ((lastevent & I2C_EVENT) == I2C_EVENT)

  {

    /* SUCCESS: last event is equal to I2C_EVENT */

    status = SUCCESS;

  }

  else

  {

    /* ERROR: last event is different from I2C_EVENT */

    status = ERROR;

  }

  /* Return status */

  return status;

}

anyone has same issues?

1 REPLY 1
Amel NASRI
ST Employee
Posted on April 26, 2018 at 17:40

Hi

ajithcs818

I2C peripheral available in STM32F4 family isn't the same as the one embedded in STM32F1.

With I2C in STM32F1, you have more limitations and constraints to manage than what we have in STM32F4 I2C.

What I suggest in your case is to refer to an I2C example if there is one available in STM32F1 SPL library (or CPAL library) and implement the data transfer you need.

You may also check the examples provided in

http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-library-expansion/stsw-stm32html

.

-Amel

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.