what this stm32 HAL statement does? - Page 1
Forum section: electronics / general

author: jeet55
author_rank: Contributor
timestamp: April 27, 2021, 11:59:03 am
content: so I was implementing a DMA interrupt on stm32g031k8 Nucleo but whenever I enabled interrupt the debug always ended up in a hard fault.Code:HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);this statement gave me the error. So I looked into code generated using MX cube there was one difference I didn't call this statementCode:__HAL_LINKDMA(&ADC1_Handle,DMA_Handle,DMA1Channel1_Handle);so can anyone explain what this statement does and when to use it?

author: DavidAlfa
author_rank: Super Contributor
timestamp: April 28, 2021, 02:49:55 am
content: Go to the macro declaration and see yourself, it's only 1 line!

author: SiliconWizard
author_rank: Super Contributor
timestamp: April 28, 2021, 05:08:19 pm
content: As with the other thread, we can't guess what you wrote - in particular, we absolutely don't know how you set up the corresponding DMA channel. The second line suggests you want to link it to the ADC1 peripheral, but it's almost certain you are not setting things up correctly.

author: DavidAlfa
author_rank: Super Contributor
timestamp: April 28, 2021, 06:23:14 pm
content: Code:/*** @brief ADC handle Structure definition*/#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)typedef struct __ADC_HandleTypeDef#elsetypedef struct#endif{ADC_TypeDef *Instance; /*!< Register base address */ADC_InitTypeDef Init; /*!< ADC required parameters */__IO uint32_t NbrOfCurrentConversionRank; /*!< ADC number of current conversion rank */DMA_HandleTypeDef *DMA_Handle; /*!< Pointer DMA Handler */HAL_LockTypeDef Lock; /*!< ADC locking object */__IO uint32_t State; /*!< ADC communication state */__IO uint32_t ErrorCode; /*!< ADC Error code */#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)void (* ConvCpltCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC conversion complete callback */void (* ConvHalfCpltCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC conversion DMA half-transfer callback */void (* LevelOutOfWindowCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC analog watchdog 1 callback */void (* ErrorCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC error callback */void (* InjectedConvCpltCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC group injected conversion complete callback */void (* MspInitCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC Msp Init callback */void (* MspDeInitCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC Msp DeInit callback */#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */}ADC_HandleTypeDef;Code:#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \do{ \(__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \(__DMA_HANDLE__).Parent = (__HANDLE__); \} while(0U)Code:__HAL_LINKDMA(&ADC1_Handle,DMA_Handle,DMA1Channel1_Handle);It sets up everything for the HAL.So when the ADC code handles the ADC, it will use ADC1_Handle.DMA_Handle for configuring the DMA.And when the DMA interrupt happens, it will check the Parent.It does exactly this:Code:ADC1_Handle.DMA_Handle = &DMA1Channel1_Handle;DMA1Channel1_Handle.Parent = &ADC1_Handle;It doesn't touch the hardware in any way.I'm pretty sure it's only internal, for the HAL, and you're not supposed to use it.