STM32H7B0 starting MDMA fails to unexpected IRQ (WWDG)
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;
}
