Skip to main content
ajith sudhakaran
Visitor II
April 26, 2018
Question

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

  • April 26, 2018
  • 1 reply
  • 561 views
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?

    This topic has been closed for replies.

    1 reply

    Amel NASRI
    Technical Moderator
    April 26, 2018
    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 "Best Answer" on the reply which solved your issue or answered your question.