cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 I2c with DMA not working

MDeva.1
Associate II

I am working on NUCLEO-h745ziq board.I am interface i2c to BMP280 sensor using DMA method.But I am unable to read chipID .Using the polling method Iable to get chipiD and also temperature but using DMA i am unable please help me.

s8 BME280_I2C_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)

{

  HAL_StatusTypeDef status = HAL_OK;

s32 iError = BME280_INIT_VALUE;

u8 array[I2C_BUFFER_LEN] = {BME280_INIT_VALUE};

u8 stringpos = BME280_INIT_VALUE;

array[BME280_INIT_VALUE] = reg_addr;

//while (HAL_I2C_IsDeviceReady(&hi2c4, (uint16_t)(dev_addr<<1), 3, 100) != HAL_OK) {}

  status = HAL_I2C_Mem_Read_DMA(&hi2c4, // i2c handle

    (uint8_t)(dev_addr<<1), // i2c address, left aligned

 (uint8_t)reg_addr, // register address

 I2C_MEMADD_SIZE_8BIT, // bme280 uses 8bit register addresses

 (uint8_t*)(&array), // write returned data to this variable

 cnt // how many bytes to expect returned

 ); // timeout

  if (status != HAL_OK)

  {

   // The BME280 API calls for 0 return value as a success, and -1 returned as failure

   iError = (-1);

  }

  while (HAL_I2C_GetState(&hi2c4) != HAL_I2C_STATE_READY)

   {

   }

for (stringpos = BME280_INIT_VALUE; stringpos < cnt; stringpos++) {

*(reg_data + stringpos) = array[stringpos];

}

void SystemClock_Config(void)

{

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 /** Supply configuration update enable

 */

 HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY);

 /** Configure the main internal regulator output voltage

 */

 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

 while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

 /** Initializes the RCC Oscillators according to the specified parameters

 * in the RCC_OscInitTypeDef structure.

 */

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

 RCC_OscInitStruct.HSEState = RCC_HSE_ON;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

 RCC_OscInitStruct.PLL.PLLM = 1;

 RCC_OscInitStruct.PLL.PLLN = 100;

 RCC_OscInitStruct.PLL.PLLP = 2;

 RCC_OscInitStruct.PLL.PLLQ = 2;

 RCC_OscInitStruct.PLL.PLLR = 2;

 RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;

 RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;

 RCC_OscInitStruct.PLL.PLLFRACN = 0;

 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

  Error_Handler();

 }

 /** Initializes the CPU, AHB and APB buses clocks

 */

 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2

               |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;

 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

 RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;

 RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;

 RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;

 RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;

 RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;

 RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)

 {

  Error_Handler();

 }

}

return (s8)iError;

}

void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)

{

 GPIO_InitTypeDef GPIO_InitStruct = {0};

 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

 if(hi2c->Instance==I2C4)

 {

 /* USER CODE BEGIN I2C4_MspInit 0 */

 /* USER CODE END I2C4_MspInit 0 */

 /** Initializes the peripherals clock

 */

  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C4;

  PeriphClkInitStruct.I2c4ClockSelection = RCC_I2C4CLKSOURCE_D3PCLK1;

  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)

  {

   Error_Handler();

  }

  __HAL_RCC_GPIOF_CLK_ENABLE();

  /**I2C4 GPIO Configuration

  PF14   ------> I2C4_SCL

  PF15   ------> I2C4_SDA

  */

  GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;

  GPIO_InitStruct.Alternate = GPIO_AF4_I2C4;

  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

  /* Peripheral clock enable */

  __HAL_RCC_I2C4_CLK_ENABLE();

  /* I2C4 DMA Init */

  /* I2C4_RX Init */

  hdma_i2c4_rx.Instance = BDMA_Channel0;

  hdma_i2c4_rx.Init.Request = BDMA_REQUEST_I2C4_RX;

  hdma_i2c4_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;

  hdma_i2c4_rx.Init.PeriphInc = DMA_PINC_DISABLE;

  hdma_i2c4_rx.Init.MemInc = DMA_MINC_ENABLE;

  hdma_i2c4_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

  hdma_i2c4_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

  hdma_i2c4_rx.Init.Mode = DMA_NORMAL;

  hdma_i2c4_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;

  if (HAL_DMA_Init(&hdma_i2c4_rx) != HAL_OK)

  {

   Error_Handler();

  }

  __HAL_LINKDMA(hi2c,hdmarx,hdma_i2c4_rx);

  /* I2C4_TX Init */

  hdma_i2c4_tx.Instance = BDMA_Channel1;

  hdma_i2c4_tx.Init.Request = BDMA_REQUEST_I2C4_TX;

  hdma_i2c4_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;

  hdma_i2c4_tx.Init.PeriphInc = DMA_PINC_DISABLE;

  hdma_i2c4_tx.Init.MemInc = DMA_MINC_ENABLE;

  hdma_i2c4_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

  hdma_i2c4_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

  hdma_i2c4_tx.Init.Mode = DMA_NORMAL;

  hdma_i2c4_tx.Init.Priority = DMA_PRIORITY_MEDIUM;

  if (HAL_DMA_Init(&hdma_i2c4_tx) != HAL_OK)

  {

   Error_Handler();

  }

  __HAL_LINKDMA(hi2c,hdmatx,hdma_i2c4_tx);

  /* I2C4 interrupt Init */

  HAL_NVIC_SetPriority(I2C4_EV_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(I2C4_EV_IRQn);

  HAL_NVIC_SetPriority(I2C4_ER_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(I2C4_ER_IRQn);

 /* USER CODE BEGIN I2C4_MspInit 1 */

 /* USER CODE END I2C4_MspInit 1 */

 }

}

2 REPLIES 2

Are you sure using local/auto variables is advisable for DMA buffers?

Do you manage cache coherency?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I am assign the variablein SRAM and updated in flash files.And aslo manage the cache but still get it read the NULL value i am unable to understand why its get