Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => ARM => Konuyu başlatan: robikod - 02 Temmuz 2021, 15:26:27

Başlık: I2C Master Mode DMA Kullanımı
Gönderen: robikod - 02 Temmuz 2021, 15:26:27
Eeproma yazmak için normal moddan DMA moduna geçtim, normal modda gayet başarılı çalışırken, DMA modunda bir yerde takılıyor. Stm32f4 kullanıyorum ve kodlarım şu şekilde:

if(hi2c->Instance==I2C1)
  {
  /* USER CODE BEGIN I2C1_MspInit 0 */

  /* USER CODE END I2C1_MspInit 0 */

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**I2C1 GPIO Configuration
    PB6     ------> I2C1_SCL
    PB7     ------> I2C1_SDA
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* Peripheral clock enable */
    __HAL_RCC_I2C1_CLK_ENABLE();
   /* I2C1 DMA Init */
    /* I2C1_RX Init */
    hdma_i2c1_rx.Instance = DMA1_Stream0;
    hdma_i2c1_rx.Init.Channel = DMA_CHANNEL_1;
    hdma_i2c1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_i2c1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_i2c1_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_i2c1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_i2c1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_i2c1_rx.Init.Mode = DMA_NORMAL;
    hdma_i2c1_rx.Init.Priority = DMA_PRIORITY_LOW;
    hdma_i2c1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(&hdma_i2c1_rx) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(hi2c,hdmarx,hdma_i2c1_rx);

    /* I2C1_TX Init */
    hdma_i2c1_tx.Instance = DMA1_Stream7;
    hdma_i2c1_tx.Init.Channel = DMA_CHANNEL_1;
    hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_i2c1_tx.Init.Mode = DMA_NORMAL;
    hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_LOW;
    hdma_i2c1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(&hdma_i2c1_tx) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(hi2c,hdmatx,hdma_i2c1_tx);

    /* I2C1 interrupt Init */
    HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
        HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(I2C1_ER_IRQn);
  /* USER CODE BEGIN I2C1_MspInit 1 */

  /* USER CODE END I2C1_MspInit 1 */
 
  }
}



Aşağıdaki kodda, HAL_I2C_Master_Transmit_DMA çağırdıktan sonra fonksiyonun içerisinden HAL_OK olarak çıkıyor ancak hemen I2C1_EV_IRQHandler içerisinde loopta kalıyor bu interruptan çıkamıyor. Bu neden olabilir ? Nasıl çözebilirim?

     while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY)
      {

      }
      errorCode = HAL_I2C_Master_Transmit_DMA(hi2c, (uint16_t)deviceAddress, (uint8_t*)dataArray, 2);
      if(errorCode != HAL_OK)
      {
      // print("%d",errorCode);
      }
Başlık: Ynt: I2C Master Mode DMA Kullanımı
Gönderen: robikod - 05 Temmuz 2021, 08:40:29
Bu konuda yardımcı olabilecek yok mu ?
Başlık: Ynt: I2C Master Mode DMA Kullanımı
Gönderen: Cemre. - 05 Temmuz 2021, 09:32:25
Merhaba,

Bu konu ST community forumunda da konuşulmuş. Hatta bug fix geçilmiş gözüküyor.

Tavsiye olarak CubeMX kütüphane paketlerini güncellemek ve proje ayarlarından en güncel kütüphaneyi kullanacak şekilde ayarlamak önerilebilir. Denemekte fayda var.

https://community.st.com/s/question/0D50X0000BTcGDf/bug-report-fix-hal-i2c-interrupt-handler-not-working
Başlık: Ynt: I2C Master Mode DMA Kullanımı
Gönderen: mr.engineer - 05 Temmuz 2021, 09:38:05
ST'lerin bazı I2C modüllerinde problem olduğu söyleniyordu. Hala devam ediyor galiba sorun