2024-08-26 12:02 PM
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;
}
2024-08-26 01:35 PM
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.
2024-08-26 01:39 PM
... 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
...
2024-08-27 12:05 PM - edited 2024-08-27 12:19 PM
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?
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();
}