cancel
Showing results for 
Search instead for 
Did you mean: 

I2C DMA Does Not Transmit

t w
Associate
Posted on November 06, 2017 at 22:01

Hello, I'm working to add DMA capabilities to an I2C library I've been working on, and I've been having a couple issues getting DMA integrated. I am using a ST32F4 Discovery board (F407VGT6), and I've configured the I2C/DMA using the CubeMX tool. The MspInit function that was generated is below:

void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
 GPIO_InitTypeDef GPIO_InitStruct;
 if(hi2c->Instance==I2C1)
 {
 /* USER CODE BEGIN I2C1_MspInit 0 */
 /* USER CODE END I2C1_MspInit 0 */
 
 /**I2C1 GPIO Configuration 
 PB7 ------> I2C1_SDA
 PB8 ------> I2C1_SCL 
 */
 GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8;
 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_TX Init */
 hdma_i2c1_tx.Instance = DMA1_Stream6;
 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(__FILE__, __LINE__);
 }
 __HAL_LINKDMA(hi2c,hdmatx,hdma_i2c1_tx);
 /* I2C1_RX Init */
 hdma_i2c1_rx.Instance = DMA1_Stream5;
 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_ENABLE;
 hdma_i2c1_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
 hdma_i2c1_rx.Init.MemBurst = DMA_MBURST_SINGLE;
 hdma_i2c1_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
 if (HAL_DMA_Init(&hdma_i2c1_rx) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
 __HAL_LINKDMA(hi2c,hdmarx,hdma_i2c1_rx);
 /* USER CODE BEGIN I2C1_MspInit 1 */
 /* USER CODE END I2C1_MspInit 1 */
 }
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

The MX_GPIO_Init, MX_I2C_Init, and MX_DMA_Init functions all appear in main.c:

/** System Clock Configuration
*/
void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct;
 RCC_ClkInitTypeDef RCC_ClkInitStruct;
 /**Configure the main internal regulator output voltage 
 */
 __HAL_RCC_PWR_CLK_ENABLE();
 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 /**Initializes the CPU, AHB and APB busses clocks 
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
 RCC_OscInitStruct.HSICalibrationValue = 16;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
 /**Initializes the CPU, AHB and APB busses clocks 
 */
 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
 /**Configure the Systick interrupt time 
 */
 HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
 /**Configure the Systick 
 */
 HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
 /* SysTick_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* I2C1 init function */
static void MX_I2C1_Init(void)
{
 hi2c1.Instance = I2C1;
 hi2c1.Init.ClockSpeed = 100000;
 hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
 hi2c1.Init.OwnAddress1 = 0;
 hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
 hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
 hi2c1.Init.OwnAddress2 = 0;
 hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
 hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
 if (HAL_I2C_Init(&hi2c1) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
}
/** 
 * Enable DMA controller clock
 */
static void MX_DMA_Init(void) 
{
 /* DMA controller clock enable */
 __HAL_RCC_DMA1_CLK_ENABLE();
 /* DMA interrupt init */
 /* DMA1_Stream5_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
 /* DMA1_Stream6_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);
}
/** Pinout Configuration
*/
static void MX_GPIO_Init(void)
{
 /* GPIO Ports Clock Enable */
 __HAL_RCC_GPIOB_CLK_ENABLE();
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

And I am invoking the HAL_I2C_Master_Transmit_DMA() function as follows:

while((i2cError = HAL_I2C_Master_Transmit_DMA(&hi2c1, DEV_ADDRESS, &sendData, 1)) != HAL_OK){
 i2cError = HAL_I2C_GetError(&hi2c1);
 if (i2cError != HAL_I2C_ERROR_AF){
 return i2cError;
 }
}�?�?�?�?�?�?�?�?�?�?�?�?

However, nothing appears on my scope when the Start bit is set in CR1 for I2C1. Why could this be?I have had success in communicating with this sensor using standard blocking I2C.

##stm32f4 #dma #i2c
0 REPLIES 0