cancel
Showing results for 
Search instead for 
Did you mean: 

I2C In Master Receive Mode, DMA transfer in circular mode not working

NMan.11
Associate II

Hi I'm using the STM32F446RE with the latest FW Package - SMT32Cube_FW_F4 V1.28.1, and i have a MCP3221 connected to an I2C port.
Its a strange ADC that returns a sample every 2 bytes when its setup to send data to the I2C master. There are no addresses like most I2C devices. 
Since it works in this way i can take advantage of this and I'd like to read it continuously in DMA mode, with no interruptions and so i tried DMA circular mode. The problem is that it runs 1 time trough the recv process and stops after the callback. I'm using CubeMX to setup the peripherals.

I2C init code. 

  /* USER CODE END I2C3_Init 1 */
  hi2c3.Instance = I2C3;
  hi2c3.Init.ClockSpeed = 400000;
  hi2c3.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c3.Init.OwnAddress1 = 0;
  hi2c3.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c3.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c3.Init.OwnAddress2 = 0;
  hi2c3.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c3.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c3) != HAL_OK)
  {
    Error_Handler();
  }

DMA Init code. 

    /* I2C3 DMA Init */
    /* I2C3_RX Init */
    hdma_i2c3_rx.Instance = DMA1_Stream1;
    hdma_i2c3_rx.Init.Channel = DMA_CHANNEL_1;
    hdma_i2c3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_i2c3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_i2c3_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_i2c3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_i2c3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_i2c3_rx.Init.Mode = DMA_CIRCULAR;
    hdma_i2c3_rx.Init.Priority = DMA_PRIORITY_LOW;
    hdma_i2c3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(&hdma_i2c3_rx) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(hi2c,hdmarx,hdma_i2c3_rx);

    /* I2C3 interrupt Init */
    HAL_NVIC_SetPriority(I2C3_EV_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(I2C3_EV_IRQn);
    HAL_NVIC_SetPriority(I2C3_ER_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(I2C3_ER_IRQn);
  /* USER CODE BEGIN I2C3_MspInit 1 */

 Call code.

static volatile uint8_t data_buff[200*2]; //Global variable.

HAL_I2C_Master_Receive_DMA(&hi2c3, I2C_ADDRESS_ADC, (uint8_t *)data_buff, 200/2);

 

currently my void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) is just blank. I just use it with a breakpoint to check, if it got there. it gets there once and then it stops. 

NMan11_0-1729455206683.png

Currently i have it bodged where i start a new transfer as soon as the previous one ends, but I'd prefer to have it with proper circular mode.
Any help would be highly appreciated.

 

0 REPLIES 0