cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7B0 starting MDMA fails to unexpected IRQ (WWDG)

OGhis
Senior

Dear,

We use the STM32H7B0 100 pins version.
The MPU, ICACHE, DCACHE are disabled

We will use a MDMA to copy some data from one to another place.

Therefore we had try an example to understand the configuration.
We had use a part of example:   https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Projects/STM32H7B3I-EVAL/Examples/MDMA/MDMA_LinkedList/Src/main.c

When we start the MDMA we becom an unexpected IRQ (WWDG) when we do the verfication with Buffercmp().
What goes wrong here?

Here is the used code:

#define BUFFER_SIZE0 32
#define BUFFER_SIZE1 16
#define BUFFER_SIZE2 8

/* 32-bytes Alignment is needed for cache maintenance purpose */
ALIGN_32BYTES(int16_t dma_secBuffer[BSPADC_DMA_BUF_SIZE]);
ALIGN_32BYTES(MDMA_LinkNodeTypeDef Xfer_Node1);
ALIGN_32BYTES(MDMA_LinkNodeTypeDef Xfer_Node2);
MDMA_HandleTypeDef MDMA_Hdlr;

static const uint32_t SRC_Const_Buffer0[BUFFER_SIZE0] =
{
  0x01020304, 0x05060708, 0x090A0B0C, 0x0D0E0F10,
  0x11121314, 0x15161718, 0x191A1B1C, 0x1D1E1F20,
  0x21222324, 0x25262728, 0x292A2B2C, 0x2D2E2F30,
  0x31323334, 0x35363738, 0x393A3B3C, 0x3D3E3F40,
  0x41424344, 0x45464748, 0x494A4B4C, 0x4D4E4F50,
  0x51525354, 0x55565758, 0x595A5B5C, 0x5D5E5F60,
  0x61626364, 0x65666768, 0x696A6B6C, 0x6D6E6F70,
  0x71727374, 0x75767778, 0x797A7B7C, 0x7D7E7F80
};

static const uint32_t SRC_Const_Buffer1[BUFFER_SIZE1] =
{
  0x0A0B0C0D, 0x1A1B1C1D, 0x2A2B2C2D, 0x2A2B2C2D,
  0x3A3B3C3D, 0x4A4B4C4D, 0x5A5B5C5D, 0x6A6B6C6D,
  0x7A7B7C7D, 0x8A8B8C8D, 0x9A9B9C9D, 0xAAABACAD,
  0xBABBBCBD, 0xCACBCCCD, 0xDADBDCDD, 0xEAEBECED
};

static const uint32_t SRC_Const_Buffer2[BUFFER_SIZE2] =
{
  0x00010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F,
  0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF
};

ALIGN_32BYTES(uint32_t __attribute__((section (".RAM_D1"))) DESTBuffer0_AXISRAM[BUFFER_SIZE0]);
ALIGN_32BYTES(uint32_t __attribute__((section (".RAM_D2"))) DESTBuffer1_SRAM1[BUFFER_SIZE0]);
ALIGN_32BYTES(uint32_t __attribute__((section (".RAM_D3"))) DESTBuffer2_AHBSRAM[BUFFER_SIZE0]);

void main(void) {
  HAL_StatusTypeDef errCode = HAL_OK;

  errCode |= MDMA_init(&MDMA_Hdlr, MDMA_Channel0);
  errCode |= MDMA_copy(&MDMA_Hdlr)

  while(1) {
    __NOP();
  }
}

HAL_StatusTypeDef MDMA_init(MDMA_HandleTypeDef *pMdmaHdlr,
                            MDMA_Channel_TypeDef *pChan) {

  HAL_StatusTypeDef errCode = HAL_OK;
  MDMA_LinkNodeConfTypeDef mdmaLinkNodeConfig;

   /*##-1- Enable the MDMA clock ###############################################*/
   __HAL_RCC_MDMA_CLK_ENABLE();

   /*##-2- Select the MDMA instance to be used for the transfer : MDMA_Channel0 #*/
   pMdmaHdlr->Instance = pChan;

   /*##-3- Initialize the MDMA channel for Node 0 ##############################*/

   /* Set the parameters to be configured for transfer Node0 */
   pMdmaHdlr->Init.Request              = MDMA_REQUEST_SW;
   pMdmaHdlr->Init.TransferTriggerMode  = MDMA_FULL_TRANSFER;
   pMdmaHdlr->Init.Priority             = MDMA_PRIORITY_HIGH;
   pMdmaHdlr->Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;
   pMdmaHdlr->Init.SourceInc            = MDMA_SRC_INC_WORD;
   pMdmaHdlr->Init.DestinationInc       = MDMA_DEST_INC_BYTE;
   pMdmaHdlr->Init.SourceDataSize       = MDMA_SRC_DATASIZE_WORD;
   pMdmaHdlr->Init.DestDataSize         = MDMA_DEST_DATASIZE_BYTE;
   pMdmaHdlr->Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;
   pMdmaHdlr->Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
   pMdmaHdlr->Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
   pMdmaHdlr->Init.BufferTransferLength = 4;
   pMdmaHdlr->Init.SourceBlockAddressOffset  = 0;
   pMdmaHdlr->Init.DestBlockAddressOffset    = 0;

   errCode |= HAL_MDMA_Init(pMdmaHdlr);

   /*##-4 Add linked-list node 1 and  2 #########################################*/
   /* Set the parameters to be configured for transfer Node1 */
   mdmaLinkNodeConfig.Init.Request              = MDMA_REQUEST_SW;
   mdmaLinkNodeConfig.Init.TransferTriggerMode  = MDMA_FULL_TRANSFER;
   mdmaLinkNodeConfig.Init.Priority             = MDMA_PRIORITY_HIGH;
   mdmaLinkNodeConfig.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;
   mdmaLinkNodeConfig.Init.SourceInc            = MDMA_SRC_INC_BYTE;
   mdmaLinkNodeConfig.Init.DestinationInc       = MDMA_DEST_INC_BYTE;
   mdmaLinkNodeConfig.Init.SourceDataSize       = MDMA_SRC_DATASIZE_BYTE;
   mdmaLinkNodeConfig.Init.DestDataSize         = MDMA_DEST_DATASIZE_BYTE;
   mdmaLinkNodeConfig.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;
   mdmaLinkNodeConfig.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
   mdmaLinkNodeConfig.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
   mdmaLinkNodeConfig.Init.BufferTransferLength = 2;
   mdmaLinkNodeConfig.Init.SourceBlockAddressOffset  = 0;
   mdmaLinkNodeConfig.Init.DestBlockAddressOffset    = 0;

   mdmaLinkNodeConfig.SrcAddress      = (uint32_t)SRC_Const_Buffer1;
   mdmaLinkNodeConfig.DstAddress      = (uint32_t)DESTBuffer1_SRAM1;
   mdmaLinkNodeConfig.BlockDataLength = (BUFFER_SIZE1*4);
   mdmaLinkNodeConfig.BlockCount      = 1;

   errCode |= HAL_MDMA_LinkedList_CreateNode(&Xfer_Node1, &mdmaLinkNodeConfig);

   /* Set the parameters to be configured for transfer Node2 */
   mdmaLinkNodeConfig.Init.Request              = MDMA_REQUEST_SW;
   mdmaLinkNodeConfig.Init.TransferTriggerMode  = MDMA_FULL_TRANSFER;
   mdmaLinkNodeConfig.Init.Priority             = MDMA_PRIORITY_HIGH;
   mdmaLinkNodeConfig.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;
   mdmaLinkNodeConfig.Init.SourceInc            = MDMA_SRC_INC_BYTE;
   mdmaLinkNodeConfig.Init.DestinationInc       = MDMA_DEST_INC_WORD;
   mdmaLinkNodeConfig.Init.SourceDataSize       = MDMA_SRC_DATASIZE_BYTE;
   mdmaLinkNodeConfig.Init.DestDataSize         = MDMA_DEST_DATASIZE_WORD;
   mdmaLinkNodeConfig.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;
   mdmaLinkNodeConfig.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
   mdmaLinkNodeConfig.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
   mdmaLinkNodeConfig.Init.BufferTransferLength = 4;
   mdmaLinkNodeConfig.Init.SourceBlockAddressOffset  = 0;
   mdmaLinkNodeConfig.Init.DestBlockAddressOffset    = 0;

   mdmaLinkNodeConfig.SrcAddress      = (uint32_t)SRC_Const_Buffer2;
   mdmaLinkNodeConfig.DstAddress      = (uint32_t)DESTBuffer2_AHBSRAM;
   mdmaLinkNodeConfig.BlockDataLength = (BUFFER_SIZE2*4);
   mdmaLinkNodeConfig.BlockCount      = 1;

   errCode |= HAL_MDMA_LinkedList_CreateNode(&Xfer_Node2, &mdmaLinkNodeConfig);

   /* Link the different nodes */
   errCode |= HAL_MDMA_LinkedList_AddNode(pMdmaHdlr, &Xfer_Node1, 0);
   errCode |= HAL_MDMA_LinkedList_AddNode(pMdmaHdlr, &Xfer_Node2, 0);

   /*##-5- Select Callbacks functions called after Transfer complete and Transfer error */
   errCode |= HAL_MDMA_RegisterCallback(pMdmaHdlr, HAL_MDMA_XFER_CPLT_CB_ID, MDMA_TransferCompleteCallback);
   errCode |= HAL_MDMA_RegisterCallback(pMdmaHdlr, HAL_MDMA_XFER_ERROR_CB_ID, MDMA_TransferErrorCallback);

   /*##-6- Configure NVIC for MDMA transfer complete/error interrupts ##########*/
   /* Set Interrupt Group Priority */
   HAL_NVIC_SetPriority(MDMA_IRQn, 0, 0);

   /* Enable the MDMA channel global Interrupt */
   HAL_NVIC_EnableIRQ(MDMA_IRQn);

  return(HAL_OK);
}


HAL_StatusTypeDef MDMA_copy(MDMA_HandleTypeDef *pHdlr) {

  HAL_StatusTypeDef errCode = HAL_OK;

  /*
    As the MDMA Nodes descriptors are located in the SRAM which
    is cacheable, it is necessary to clean the data cache after creating the nodes
    in order to make sure that the MDMA will load up-to-date data from the linked-list nodes
  */
  // SCB_CleanDCache_by_Addr( (uint32_t*)&Xfer_Node1, sizeof(MDMA_LinkNodeTypeDef));
  // SCB_CleanDCache_by_Addr( (uint32_t*)&Xfer_Node2, sizeof(MDMA_LinkNodeTypeDef));

  /*##-7- Start the MDMA transfer using the interrupt mode ####################*/
  /* Configure the source, destination and buffer size MDMA fields and Start MDMA channel transfer of Node 0 */
  errCode = HAL_MDMA_Start_IT(&MDMA_Hdlr,
                              (uint32_t)&SRC_Const_Buffer0,
                              (uint32_t)&DESTBuffer0_AXISRAM,
                              (BUFFER_SIZE0 * 4),
                              1);

  if(Buffercmp((uint8_t *)SRC_Const_Buffer0, (uint8_t *)DESTBuffer0_AXISRAM, (BUFFER_SIZE0 * 4)) != 0)
  {
   __NOP();
  }

  if(Buffercmp((uint8_t *)SRC_Const_Buffer1, (uint8_t *)DESTBuffer1_SRAM1, (BUFFER_SIZE1 * 4)) != 0)
  {
    __NOP();
  }

  if(Buffercmp((uint8_t *)SRC_Const_Buffer2, (uint8_t *)DESTBuffer2_AHBSRAM, (BUFFER_SIZE2 * 4)) != 0)
  {
    __NOP();
  }



  if (errCode != HAL_OK) {
    return (errCode);
  }

  return(HAL_OK);
}

uint16_t Buffercmp(uint8_t *pBuffer1,
                   uint8_t *pBuffer2,
                   uint16_t BufferLength) {
  /* Invalidate Data cache to get the updated SRAM content */
  //SCB_InvalidateDCache_by_Addr((uint32_t *)pBuffer2,BufferLength);

  while (BufferLength > 0) {
    if ((*pBuffer1) != *pBuffer2)
    {
      return BufferLength;
    }
    pBuffer1++;
    pBuffer2++;
    BufferLength--;
  }

  return 0;
}

 

3 REPLIES 3

Are you sure that's not just the address of the Default_Handler, or a dozen other interrupt handlers with a weak fixup?

Look at startup.s file, make sure you've named the IRQ Handler exactly right, same case, etc.

Check the .MAP file and the linkage into the Vector Table.

Watch if using C++ or .cpp file for Name Mangling issues.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
... Where every unloved one goes to die in peace..

/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
   .weak      NMI_Handler
   .thumb_set NMI_Handler,Default_Handler

   .weak      HardFault_Handler
   .thumb_set HardFault_Handler,Default_Handler

   .weak      MemManage_Handler
   .thumb_set MemManage_Handler,Default_Handler

   .weak      BusFault_Handler
   .thumb_set BusFault_Handler,Default_Handler

   .weak      UsageFault_Handler
   .thumb_set UsageFault_Handler,Default_Handler

   .weak      SVC_Handler
   .thumb_set SVC_Handler,Default_Handler

   .weak      DebugMon_Handler
   .thumb_set DebugMon_Handler,Default_Handler

   .weak      PendSV_Handler
   .thumb_set PendSV_Handler,Default_Handler

   .weak      SysTick_Handler
   .thumb_set SysTick_Handler,Default_Handler

   .weak      WWDG_IRQHandler
   .thumb_set WWDG_IRQHandler,Default_Handler

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

Hi,

We didn't really find the error, but we are now using MXcube for configuration.

There are some parameters we don't understand:

In mxCube, we can enter the source and destination address along with “block Count” and “Block data Length” but nothing is done with these values during code generation.
Is this normal or a bug in mxCube?

The “buffer transfer length” what does this value mean?


OGhis_0-1724785300850.png

  hmdma_mdma_channel0_sw_0.Instance = MDMA_Channel0;
  hmdma_mdma_channel0_sw_0.Init.Request = MDMA_REQUEST_SW;
  hmdma_mdma_channel0_sw_0.Init.TransferTriggerMode = MDMA_FULL_TRANSFER;
  hmdma_mdma_channel0_sw_0.Init.Priority = MDMA_PRIORITY_MEDIUM;
  hmdma_mdma_channel0_sw_0.Init.Endianness = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  hmdma_mdma_channel0_sw_0.Init.SourceInc = MDMA_SRC_INC_DOUBLEWORD;
  hmdma_mdma_channel0_sw_0.Init.DestinationInc = MDMA_DEST_INC_DOUBLEWORD;
  hmdma_mdma_channel0_sw_0.Init.SourceDataSize = MDMA_SRC_DATASIZE_DOUBLEWORD;
  hmdma_mdma_channel0_sw_0.Init.DestDataSize = MDMA_DEST_DATASIZE_DOUBLEWORD;
  hmdma_mdma_channel0_sw_0.Init.DataAlignment = MDMA_DATAALIGN_PACKENABLE;
  hmdma_mdma_channel0_sw_0.Init.BufferTransferLength = 16;
  hmdma_mdma_channel0_sw_0.Init.SourceBurst = MDMA_SOURCE_BURST_SINGLE;
  hmdma_mdma_channel0_sw_0.Init.DestBurst = MDMA_DEST_BURST_SINGLE;
  hmdma_mdma_channel0_sw_0.Init.SourceBlockAddressOffset = 0;
  hmdma_mdma_channel0_sw_0.Init.DestBlockAddressOffset = 0;
  if (HAL_MDMA_Init(&hmdma_mdma_channel0_sw_0) != HAL_OK)
  {
    Error_Handler();
  }