stm32f429i Disco ADC DMA

Hello, Im developing some applicatnion whitch must use FreeRTOS and sample 2 channels ADC. I decided to use DMA mechanism for easier data preparation. Code is fully generated from ST CubeMx and just without FreeRTOS works fine. Here is same topic but there is no answer: here I created few task to refresh LCD, read Touchscreen state and some more… DMA works once and then processor do not goes into DMA interrupt and do not refresh buffer. I have no more ideas. I think FreeRTOS is bad configured for DMA and thats the reason of this behaviour. Can you help? ~~~~

include “stm32f4xx_hal.h”

include “cmsis_os.h”

/* USER CODE BEGIN Includes */

include “stm32f429idiscoverylcd.h”

include “stm32f429idiscoveryts.h”

include “expander_mcp23s17.h”

/* USER CODE END Includes */ /* Private variables ———————————————————*/ ADC_HandleTypeDef hadc3; DMA_HandleTypeDef hdma_adc3; DAC_HandleTypeDef hdac; SPI_HandleTypeDef hspi4; UART_HandleTypeDef huart5; osThreadId defaultTaskHandle; /* USER CODE BEGIN PV / / Private variables ———————————————————*/ /* USER CODE END PV */ /* Private function prototypes ———————————————–*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_DMA_Init(void); static void MX_ADC3_Init(void); static void MX_DAC_Init(void); static void MX_SPI4_Init(void); static void MX_UART5_Init(void); void StartDefaultTask(void const * argument); /* USER CODE BEGIN PFP / / Private function prototypes ———————————————–*/ osThreadId ScreenTaskHandle; osThreadId TouchPanelTaskHandle; void ScreenTask(void const * argument); void TouchPanelTask (void const * argument); /* USER CODE END PFP */ /* USER CODE BEGIN 0 */ TS_StateTypeDef touch; uint32t gADCBuffer[2]; /* USER CODE END 0 */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration———————————————————-*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_ADC3_Init(); //MX_DAC_Init(); MX_SPI4_Init(); MX_UART5_Init(); /* USER CODE BEGIN 2 */
    HAL_ADC_Start_DMA(&hadc3, g_ADCBuffer, 2);
/* USER CODE END 2 */ /* USER CODE BEGIN RTOSMUTEX */ /* add mutexes, … */ /* USER CODE END RTOSMUTEX */ /* USER CODE BEGIN RTOSSEMAPHORES */ /* add semaphores, … */ /* USER CODE END RTOSSEMAPHORES */ /* USER CODE BEGIN RTOSTIMERS */ /* start timers, add new ones, … */ /* USER CODE END RTOSTIMERS */ /* Create the thread(s) / / definition and creation of defaultTask */ osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128); defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL); /* USER CODE BEGIN RTOS_THREADS */
    osThreadDef(ScreenTask, ScreenTask, osPriorityNormal, 0, 128);
ScreenTaskHandle = osThreadCreate(osThread(ScreenTask), NULL);
    osThreadDef(TouchPanelTask, TouchPanelTask, osPriorityNormal, 0, 128);
TouchPanelTaskHandle = osThreadCreate(osThread(TouchPanelTask), NULL); /* USER CODE END RTOS_THREADS */ /* USER CODE BEGIN RTOSQUEUES */ /* add queues, … */ /* USER CODE END RTOSQUEUES */ /* Start scheduler */ osKernelStart(); /* We should never get here as control is now taken by the scheduler */ /* Infinite loop / / USER CODE BEGIN WHILE / while (1) { / USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** System Clock Configuration */ void SystemClock_Config(void) { RCCOscInitTypeDef RCCOscInitStruct; RCCClkInitTypeDef RCCClkInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; __PWRCLKENABLE(); __HALPWRVOLTAGESCALINGCONFIG(PWRREGULATORVOLTAGESCALE1); RCCOscInitStruct.OscillatorType = RCCOSCILLATORTYPEHSI; RCCOscInitStruct.HSIState = RCCHSION; RCCOscInitStruct.HSICalibrationValue = 16; RCCOscInitStruct.PLL.PLLState = RCCPLLON; RCCOscInitStruct.PLL.PLLSource = RCCPLLSOURCEHSI; RCCOscInitStruct.PLL.PLLM = 10; RCCOscInitStruct.PLL.PLLN = 210; RCCOscInitStruct.PLL.PLLP = RCCPLLPDIV2; RCCOscInitStruct.PLL.PLLQ = 4; HALRCCOscConfig(&RCCOscInitStruct); RCCClkInitStruct.ClockType = RCCCLOCKTYPESYSCLK|RCCCLOCKTYPEPCLK1 |RCCCLOCKTYPEPCLK2; RCCClkInitStruct.SYSCLKSource = RCCSYSCLKSOURCEPLLCLK; RCCClkInitStruct.AHBCLKDivider = RCCSYSCLKDIV1; RCCClkInitStruct.APB1CLKDivider = RCCHCLKDIV4; RCCClkInitStruct.APB2CLKDivider = RCCHCLKDIV2; HALRCCClockConfig(&RCCClkInitStruct, FLASHLATENCY5); PeriphClkInitStruct.PeriphClockSelection = RCCPERIPHCLKLTDC; PeriphClkInitStruct.PLLSAI.PLLSAIN = 120; PeriphClkInitStruct.PLLSAI.PLLSAIR = 2; PeriphClkInitStruct.PLLSAIDivR = RCCPLLSAIDIVR2; HALRCCExPeriphCLKConfig(&PeriphClkInitStruct); HALSYSTICKConfig(HALRCCGetHCLKFreq()/1000); HALSYSTICKCLKSourceConfig(SYSTICKCLKSOURCEHCLK); } /* ADC3 init function */ void MX_ADC3_Init(void) { ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc3.Instance = ADC3; hadc3.Init.ClockPrescaler = ADCCLOCKPRESCALERPCLKDIV4; hadc3.Init.Resolution = ADCRESOLUTION12b; hadc3.Init.ScanConvMode = ENABLE; hadc3.Init.ContinuousConvMode = ENABLE; hadc3.Init.DiscontinuousConvMode = DISABLE; hadc3.Init.ExternalTrigConvEdge = ADCEXTERNALTRIGCONVEDGENONE; hadc3.Init.DataAlign = ADCDATAALIGNRIGHT; hadc3.Init.NbrOfConversion = 2; hadc3.Init.DMAContinuousRequests = ENABLE; hadc3.Init.EOCSelection = EOCSINGLECONV; HALADCInit(&hadc3);
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADCCHANNEL4; sConfig.Rank = 1; sConfig.SamplingTime = ADCSAMPLETIME144CYCLES; HALADCConfigChannel(&hadc3, &sConfig);
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADCCHANNEL13; sConfig.Rank = 2; HALADCConfigChannel(&hadc3, &sConfig);
    HAL_ADC_MspInit(&hadc3);
} /* DAC init function */ void MX_DAC_Init(void) { DAC_ChannelConfTypeDef sConfig;
/**DAC Initialization
*/
hdac.Instance = DAC; HALDACInit(&hdac);
/**DAC channel OUT2 config
*/
sConfig.DACTrigger = DACTRIGGERNONE; sConfig.DACOutputBuffer = DACOUTPUTBUFFERENABLE; HALDACConfigChannel(&hdac, &sConfig, DACCHANNEL2); } /* SPI4 init function */ void MX_SPI4_Init(void) { hspi4.Instance = SPI4; hspi4.Init.Mode = SPIMODEMASTER; hspi4.Init.Direction = SPIDIRECTION2LINES; hspi4.Init.DataSize = SPIDATASIZE8BIT; hspi4.Init.CLKPolarity = SPIPOLARITYLOW; hspi4.Init.CLKPhase = SPIPHASE1EDGE; hspi4.Init.NSS = SPINSSSOFT; hspi4.Init.BaudRatePrescaler = SPIBAUDRATEPRESCALER256; hspi4.Init.FirstBit = SPIFIRSTBITMSB; hspi4.Init.TIMode = SPITIMODEDISABLED; hspi4.Init.CRCCalculation = SPICRCCALCULATIONDISABLED; hspi4.Init.CRCPolynomial = 10; HALSPIInit(&hspi4);
    HAL_SPI_MspInit(&hspi4);
} /* UART5 init function */ void MX_UART5_Init(void) { huart5.Instance = UART5; huart5.Init.BaudRate = 115200; huart5.Init.WordLength = UARTWORDLENGTH8B; huart5.Init.StopBits = UARTSTOPBITS1; huart5.Init.Parity = UARTPARITYNONE; huart5.Init.Mode = UARTMODETXRX; huart5.Init.HwFlowCtl = UARTHWCONTROLNONE; huart5.Init.OverSampling = UARTOVERSAMPLING16; HALUART_Init(&huart5);
    HAL_UART_MspInit(&huart5);
} /** * Enable DMA controller clock / void MX_DMA_Init(void) { / DMA controller clock enable */ __DMA2_CLK_ENABLE(); /* DMA interrupt init */ HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0); HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); } /** Configure pins as * Analog * Input * Output * EVENTOUT * EXTI */ void MXGPIO_Init(void) { GPIOInitTypeDef GPIOInitStruct; /* GPIO Ports Clock Enable */ __GPIOE_CLK_ENABLE(); __GPIOF_CLK_ENABLE(); __GPIOC_CLK_ENABLE(); __GPIOA_CLK_ENABLE(); __GPIOB_CLK_ENABLE(); __GPIOD_CLK_ENABLE(); __GPIOG_CLK_ENABLE(); /*Configure GPIO pins : PE3 PE4 */ GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FAST; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); /*Configure GPIO pin : PA0 */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pins : PG13 PG14 */ GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_LOW; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); } /* USER CODE BEGIN 4 */ /* ScreenTask function */ void ScreenTask(void const * argument) { BSP_LCD_Init(); BSP_LCD_LayerDefaultInit(0, (uint32_t) LCD_FRAME_BUFFER); BSP_LCD_SetLayerVisible(0, ENABLE);
            BSP_LCD_SelectLayer(0);
            BSP_LCD_Clear(LCD_COLOR_RED);
            BSP_LCD_SetBackColor(LCD_COLOR_RED);
            BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
            BSP_LCD_DisplayOn();

            BSP_LCD_DisplayStringAtLine(1, (uint8_t *) "SAMPLE TEXT");

            while(1)
            {
                    osDelay(200);
            }
} /* TouchPanelTask function */ void TouchPanelTask (void const * argument) { BSP_TS_Init(240, 320);
            while(1)
            {
                            BSP_TS_GetState(&touch);
                            osDelay(200);
            }
} /* USER CODE END 4 */ /* StartDefaultTask function */ void StartDefaultTask(void const * argument) { /* USER CODE BEGIN 5 */ uint8_t start = 0; uint8_t fr = 1;
    Expander_MCP23s17_Set_Direction(&hspi4, GPIOE, GPIO_PIN_4, VoltageCard, 0, 0);
    Expander_MCP23s17_Set_Direction(&hspi4, GPIOE, GPIO_PIN_4, VoltageCard, 0, 1);

    Expander_MCP23s17_Set_Pin(&hspi4, GPIOE, GPIO_PIN_4, VoltageCard, 7, 0);
    Expander_MCP23s17_Set_Pin(&hspi4, GPIOE, GPIO_PIN_4, VoltageCard, 6, 1);
for(;;) {
uint8t elo[10] = “”; HALUART_Transmit(&huart5, elo, sizeof(elo), 1);
            sprintf(elo, "%i", g_ADCBuffer[0]);
            BSP_LCD_DisplayStringAtLine(11, (uint8_t*)elo);

            sprintf(elo, "%i", g_ADCBuffer[1]);
            BSP_LCD_DisplayStringAtLine(12, (uint8_t*)elo);

osDelay(200);
            HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_14 | GPIO_PIN_13);

            if(touch.TouchDetected) {

                    if((!start && touch.X >= 50 && touch.X <= 150 && touch.Y >= 200 && touch.Y <= 250) || fr) {
                            BSP_LCD_Clear(LCD_COLOR_RED);
                            BSP_LCD_DrawRect(50, 50, 100, 50);
                            BSP_LCD_DisplayStringAt(60, 75, (uint8_t*) "BTN1", LEFT_MODE);

                            if(!fr)
                                    BSP_LCD_DisplayStringAtLine(1, (uint8_t*)"BTN2 pressed");

                            start = 1;
                            fr = 0;
                    }
                    else if(start && touch.X >= 50 && touch.X <= 150 && touch.Y >= 50 && touch.Y <= 100){
                            BSP_LCD_Clear(LCD_COLOR_RED);
                            BSP_LCD_DrawRect(50, 200, 100, 50);
                            BSP_LCD_DisplayStringAt(60, 210, (uint8_t*) "BTN2", LEFT_MODE);
                            BSP_LCD_DisplayStringAtLine(1, (uint8_t*)"BTN1 pressed");

                            start = 0;
                    }
            }
} /* USER CODE END 5 */ } GeSHi ~~~~

stm32f429i Disco ADC DMA

Please note, this forum can assist in the use of FreeRTOS, using the FreeRTOS API, we are not able to support or advise on chip specific periipheral setup, or support third party code. We can try and help with your specific question – which I think is related to a DMA that fires only once. There is too much code to read through though, can you be more specific, and highlight just the code that is causing the problem. I would suggest creating an application, or commenting out all other code, so you have a FreeRTOS application that does nothing but perform the ADC conversions using the DMA so you can see how it behaves in isloation (without any other code). If that does not work there will be much less code to try and diagnose – and if it does work you can then start adding the rest of the application code until you find the point where the ADC/DMA stops working. Regards.