cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H753ZI / MDMA issue with linked list (DMA ADC)

lclor
Associate III

Hi,

I would like to use MDMA to get values from ADC.

I have one adc set with 6 channels, starting conversion with timer (100µs).

So I would like to save in memory adc values like that :

val1, val2, val3, val4, val5, val6 -> val1(100µs),val1(200µs)...val1(1000µs),val2(100µs),val2(200µs)...val2(1000µs)...val6(1000µs)

the destination memory is 60 values of 16 bits. That means I would like to be interrupted every 1ms by MDMA.

So I use this configuration (at beginning I would like to test only 2 first values val1 and val2):

this is the code to initialize MDMA

MDMA_HandleTypeDef hmdma_mdma_channel0_dma1_stream2_tc_0;
MDMA_LinkNodeTypeDef node_mdma_channel0_dma1_stream2_tc_1;

/**
  * Enable MDMA controller clock
  * Configure MDMA for global transfers
  *   hmdma_mdma_channel0_dma1_stream2_tc_0
  *   node_mdma_channel0_dma1_stream2_tc_1
  */
void MX_MDMA_Init(void)
{

  /* MDMA controller clock enable */
  __HAL_RCC_MDMA_CLK_ENABLE();
  /* Local variables */
  MDMA_LinkNodeConfTypeDef nodeConfig;

  /* Configure MDMA channel MDMA_Channel0 */
  /* Configure MDMA request hmdma_mdma_channel0_dma1_stream2_tc_0 on MDMA_Channel0 */
  hmdma_mdma_channel0_dma1_stream2_tc_0.Instance = MDMA_Channel0;
  hmdma_mdma_channel0_dma1_stream2_tc_0.Init.Request = MDMA_REQUEST_DMA1_Stream2_TC;
  hmdma_mdma_channel0_dma1_stream2_tc_0.Init.TransferTriggerMode = MDMA_REPEAT_BLOCK_TRANSFER;
  hmdma_mdma_channel0_dma1_stream2_tc_0.Init.Priority = MDMA_PRIORITY_LOW;
  hmdma_mdma_channel0_dma1_stream2_tc_0.Init.Endianness = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  hmdma_mdma_channel0_dma1_stream2_tc_0.Init.SourceInc = MDMA_SRC_INC_HALFWORD;
  hmdma_mdma_channel0_dma1_stream2_tc_0.Init.DestinationInc = MDMA_DEST_INC_HALFWORD;
  hmdma_mdma_channel0_dma1_stream2_tc_0.Init.SourceDataSize = MDMA_SRC_DATASIZE_HALFWORD;
  hmdma_mdma_channel0_dma1_stream2_tc_0.Init.DestDataSize = MDMA_DEST_DATASIZE_HALFWORD;
  hmdma_mdma_channel0_dma1_stream2_tc_0.Init.DataAlignment = MDMA_DATAALIGN_PACKENABLE;
  hmdma_mdma_channel0_dma1_stream2_tc_0.Init.BufferTransferLength = 2;
  hmdma_mdma_channel0_dma1_stream2_tc_0.Init.SourceBurst = MDMA_SOURCE_BURST_SINGLE;
  hmdma_mdma_channel0_dma1_stream2_tc_0.Init.DestBurst = MDMA_DEST_BURST_SINGLE;
  hmdma_mdma_channel0_dma1_stream2_tc_0.Init.SourceBlockAddressOffset = 0;
  hmdma_mdma_channel0_dma1_stream2_tc_0.Init.DestBlockAddressOffset = 18;
  if (HAL_MDMA_Init(&hmdma_mdma_channel0_dma1_stream2_tc_0) != HAL_OK)
  {
    Error_Handler();
  }

  /* Configure post request address and data masks */
  if (HAL_MDMA_ConfigPostRequestMask(&hmdma_mdma_channel0_dma1_stream2_tc_0, (uint32_t)(&(DMA1->LIFCR)), DMA_LIFCR_CTCIF2) != HAL_OK)
  {
    Error_Handler();
  }

  /* Initialize MDMA link node according to specified parameters */
  nodeConfig.Init.Request = MDMA_REQUEST_DMA1_Stream2_TC;
  nodeConfig.Init.TransferTriggerMode = MDMA_REPEAT_BLOCK_TRANSFER;
  nodeConfig.Init.Priority = MDMA_PRIORITY_LOW;
  nodeConfig.Init.Endianness = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  nodeConfig.Init.SourceInc = MDMA_SRC_INC_HALFWORD;
  nodeConfig.Init.DestinationInc = MDMA_DEST_INC_HALFWORD;
  nodeConfig.Init.SourceDataSize = MDMA_SRC_DATASIZE_HALFWORD;
  nodeConfig.Init.DestDataSize = MDMA_DEST_DATASIZE_HALFWORD;
  nodeConfig.Init.DataAlignment = MDMA_DATAALIGN_PACKENABLE;
  nodeConfig.Init.BufferTransferLength = 2;
  nodeConfig.Init.SourceBurst = MDMA_SOURCE_BURST_SINGLE;
  nodeConfig.Init.DestBurst = MDMA_DEST_BURST_SINGLE;
  nodeConfig.Init.SourceBlockAddressOffset = 0;
  nodeConfig.Init.DestBlockAddressOffset = 18;
  nodeConfig.PostRequestMaskAddress = (uint32_t)(&(DMA1->LIFCR));
  nodeConfig.PostRequestMaskData = DMA_LIFCR_CTCIF2;
  nodeConfig.SrcAddress = 0;
  nodeConfig.DstAddress = _v_BufAdc1;
  nodeConfig.BlockDataLength = 2;
  nodeConfig.BlockCount = 6;
  if (HAL_MDMA_LinkedList_CreateNode(&node_mdma_channel0_dma1_stream2_tc_1, &nodeConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN mdma_channel0_dma1_stream2_tc_1 */

  /* USER CODE END mdma_channel0_dma1_stream2_tc_1 */

  /* Connect a node to the linked list */
  if (HAL_MDMA_LinkedList_AddNode(&hmdma_mdma_channel0_dma1_stream2_tc_0, &node_mdma_channel0_dma1_stream2_tc_1, 0) != HAL_OK)
  {
    Error_Handler();
  }

  /* MDMA interrupt initialization */
  /* MDMA_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(MDMA_IRQn, 5, 0);
  HAL_NVIC_EnableIRQ(MDMA_IRQn);

}

this is the code to start MDMA

static ALIGN_32BYTES(uint16_t __attribute__((section (".RAM_D1"))) _v_BufAdc [10 * 6]);
ALIGN_32BYTES(uint32_t __attribute__((section (".RAM_D1"))) _v_BufAdc1);
ALIGN_32BYTES(uint32_t __attribute__((section (".RAM_D1"))) _v_BufAdc2);

    _v_BufAdc1 = (uint32_t)&_v_BufAdc [1];
    _v_BufAdc2 = (uint32_t)&_v_BufAdc [2];

    MX_MDMA_Init();

    // Start ADC conversion
    HAL_ADC_Start_DMA (_k_ADC1, (DEF_t_U32 *) &_v_AdcValues1, _SPVRT_k_NUMBER_OF_ADC1);

    // Start timer for adc
    if (HAL_TIM_Base_Start_IT(&htim8) != HAL_OK)
    {
      Error_Handler();
    }

    if (HAL_MDMA_Start_IT(&hmdma_mdma_channel0_dma1_stream2_tc_0, (uint32_t)&_v_AdcValues1, (uint32_t)&_v_BufAdc, (2), 6) != HAL_OK)
    {
      /* Transfer Error */
      Error_Handler();
    }

 

When I run this code, the first time the DMA ends ADC conversion, it works, MDMA copy the 6 values to _v_BufAdc at position 0, 10, 20, 30, 40 ,50.

But the second DMA ends ADC conversion doesn't work.

So I checks MDMA registers and I saw something I don't understand :

normally (if I well understood the manual) at the end of the first repeat block transfer, the MDMA registers C0MAR and C0MDR are used to reset the TC flag of DMA (ADC).

but when the function "HAL_MDMA_Start_IT" is executed, and at this line :

    /* Enable the Peripheral */
    __HAL_MDMA_ENABLE(hmdma);

the both registers C0MAR and C0MDR are lost.

before the call of the macro __HAL_MDMA_ENABLE, C0MAR = 0x40020008 and C0MDR = 0x200000 that is correct, and after the macro is executed; registers C0MAR = 0x0 and C0MDR = 0x40020008.

Before macro :

Before macroBefore macro

After macro :

After macroAfter macro

it seems the registers are shifted ?!

Maybe an issue with the MDMA settings ?

 

0 REPLIES 0