Loading...
 

SW4STM32 and SW4Linux fully supports the STM32MP1 asymmetric multicore Cortex/A7+M4 MPUs

   With System Workbench for Linux, Embedded Linux on the STM32MP1 family of MPUs from ST was never as simple to build and maintain, even for newcomers in the Linux world. And, if you install System Workbench for Linux in System Workbench for STM32 you can seamlessly develop and debug asymmetric applications running partly on Linux, partly on the Cortex-M4.
You can get more information from the ac6-tools website and download (registration required) various documents highlighting:

System Workbench for STM32


ADC with DMA on the STM32F769I Discovery

Hello,

problem was not solved as I thought previously.
I’ve added only pin PA6 (as analog) configuration (GPIOA init) to the “main” or to the ADC_Config (doesn’t matter where) and the HardFault error occured again at the same place - possible step debugging into HAL_DMA_Start_IT(), not out of this. I was not able to get rid of it. To change MPU_InitStruct.BaseAddress is not solution or I don’t know what parametres. Different sizes of MPU_InitStruct.Size also do not change the behaviour of the program. HardFault_Handler is called again and again. It was a try and an error.
A few days later I found that before the Hard Fault parameters of the functions were OK, but after the Hard Fault came I was able to find that parametres (arguments) of the functions

HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)

usage: HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length)
DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength)
where pData is destination buffer address or DstAddress is &ConvertedValue,
DataLength or Length is 1UL (1 word)

were changed or mixed (if the debugger was not lying).
So when the Hard Fault occured the debugger showed SrcAddress was &ConvertedValue, DataLength was DMA2 peripheral address (0x40026400) and DstAddress was 1. It was strange to me. But was not able to find the cause.

In the main.c I have ADC configuration (I don’t use _msp config file), now.

/*Global variables in the main.c file*/
ADC_HandleTypeDef AdcHandle;
volatile uint32_t ConvertedValue = 0UL;
/*func. prototype*/
static void ADC_Config(void);
...
... int main(void) {...}
...
static void ADC_Config(void)
{
static ADC_ChannelConfTypeDef sConfig;
static DMA_HandleTypeDef hdma_adc;
GPIO_InitTypeDef gpio_adc_struct;

gpio_adc_struct.Pin = GPIO_PIN_6;
gpio_adc_struct.Mode = GPIO_MODE_ANALOG;

HAL_GPIO_Init(GPIOA, &gpio_adc_struct);

/* Configure the ADC peripheral */
AdcHandle.Instance = ADC1;

AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV8;
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
AdcHandle.Init.ScanConvMode = DISABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
AdcHandle.Init.ContinuousConvMode = ENABLE; /* Continuous mode enabled to have continuous conversion */
AdcHandle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */
AdcHandle.Init.NbrOfDiscConversion = 0;
AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Conversion start NOT trigged by an external event */
AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
AdcHandle.Init.NbrOfConversion = 1;
AdcHandle.Init.DMAContinuousRequests = ENABLE;
AdcHandle.Init.EOCSelection = DISABLE;

/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* ADC1 Periph clock enable */
__HAL_RCC_ADC1_CLK_ENABLE();

/* Enable DMA2 clock */
__HAL_RCC_DMA2_CLK_ENABLE();

/*##-2- Configure the DMA streams ##########################################*/
/* Set the parameters to be configured */
hdma_adc.Instance = DMA2_Stream0; // DMA2_Stream4

hdma_adc.Init.Channel = DMA_CHANNEL_0;
hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc.Init.MemInc = DMA_MINC_DISABLE;
hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_adc.Init.Mode = DMA_CIRCULAR;
hdma_adc.Init.Priority = DMA_PRIORITY_HIGH;
hdma_adc.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_adc.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
hdma_adc.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_adc.Init.PeriphBurst = DMA_PBURST_SINGLE;

HAL_DMA_Init(&hdma_adc);

/* Associate the initialized DMA handle to the ADC handle */
__HAL_LINKDMA(&AdcHandle, DMA_Handle, hdma_adc); //(&AdcHandle)->DMA_Handle = &(hdma_adc)

/*##-3- Configure the NVIC for DMA #########################################*/
/* NVIC configuration for DMA transfer complete interrupt */
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);

// HAL_NVIC_SetPriority(DMA2_Stream4_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn);

if (HAL_ADC_Init(&AdcHandle) != HAL_OK)
{
/* ADC initialization Error */
Error_Handler();
}

/* Configure ADC Temperature Sensor Channel */
sConfig.Channel = ADC_CHANNEL_6; //CN14_A0=ADC1_IN6=PA6 //ADC_CHANNEL_TEMPSENSOR = ADC_CHANNEL_18;
//CN14_A1=ADC_IN4=PA4
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_112CYCLES; //ADC_SAMPLETIME_56CYCLES;
sConfig.Offset = 0;

if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
/* Channel Configuration Error */
Error_Handler();
}
}

Result:
If ADC_ChannelConfTypeDef sConfig declaration is used, Hard Fault occurs.
If DMA_HandleTypeDef hdma_adc decalration is used, ConvertedValue is still 0 (and program runs without any other faults.)

If I use these declarations with the static keyword, the program runs and ADC converts without faults.
Then I found that DMA_Handle was placed in the DTCM RAM region (0x2000XXXX) in the working code. In the defective code the DMA_Handle was placed at the end of the SRAM1 (0x2007fef8). However I don’t know why this should be the problem to have the variable at the end of the SRAM.

I will be happy if somebody has similar experience or can give me a comment why I should use static keyword in the config function (generally) or if it is needed to define static functions in the main.c. (However void SystemClock_Config(void) is defined in the main.c without static keyword. In all examples.)

vt23