cancel
Showing results for 
Search instead for 
Did you mean: 

NUCLEO-F767ZI how to proper configure ADC Triple Interleaved Mode?

Helder Sales
Associate II
Posted on July 15, 2018 at 03:45

Hi folks,

I'm stuck trying to run ADC Triple interleaved mode. When I try to run at 7.2MSPS, it never executes the while(1) loop in main function. When I use the Clock Prescaler as PCLK2 divided by 6 (resulting 12MHz ADC Clock), the results are printed on UART but it shows wrong values (like 268374015 in 3.3V). I've tried to get my inspiration at the STM32F7 examples that have Triple Interleaved Mode. What am I doing wrong?

My main code is:

/* USER CODE BEGIN PV */

/* Private variables ---------------------------------------------------------*/

__IO uint32_t g_val[3];

char g_adcResult[16];

/* 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_USART3_UART_Init(void);

static void MX_ADC1_Init(void);

static void MX_ADC2_Init(void);

static void MX_ADC3_Init(void);

/* USER CODE BEGIN PFP */

/* Private function prototypes -----------------------------------------------*/

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**

* @brief The application entry point.

*

* @retval None

*/

int main(void)

{

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/* Enable I-Cache-------------------------------------------------------------*/

SCB_EnableICache();

/* Enable D-Cache-------------------------------------------------------------*/

SCB_EnableDCache();

/* MCU Configuration----------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */

SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_DMA_Init();

MX_USART3_UART_Init();

MX_ADC1_Init();

MX_ADC2_Init();

MX_ADC3_Init();

/* USER CODE BEGIN 2 */

uint8_t clear[] = ''\033[2J\033[H'';

HAL_UART_Transmit(&huart3, clear, sizeof clear, 100);

uint8_t init[] = ''Initializing ADC Test'';

HAL_UART_Transmit(&huart3, init, sizeof init, 100);

HAL_ADC_Start(&hadc3);

HAL_ADC_Start(&hadc2);

HAL_ADCEx_MultiModeStart_DMA(&hadc1, (uint32_t *)g_val, 3);

/* USER CODE END 2 */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

snprintf(g_adcResult, sizeof g_adcResult, ''%04lu\n\r'', g_val[0]);

HAL_UART_Transmit(&huart3, (uint8_t *)g_adcResult, sizeof g_adcResult, 100);

snprintf(g_adcResult, sizeof g_adcResult, ''%04lu\n\r'', g_val[1]);

HAL_UART_Transmit(&huart3, (uint8_t *)g_adcResult, sizeof g_adcResult, 100);

snprintf(g_adcResult, sizeof g_adcResult, ''%04lu\n\r'', g_val[2]);

HAL_UART_Transmit(&huart3, (uint8_t *)g_adcResult, sizeof g_adcResult, 100);

HAL_Delay(100);

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

}

/* USER CODE END 3 */

}

And these are the screenshots of the CubeMX (latest version) configs:

0690X0000060MCaQAM.png0690X0000060MCfQAM.png0690X0000060MCkQAM.png0690X0000060MCpQAM.png

#stm32f7-nucleo #hal-adc-dma-triplemode #hal-adc #adc-configuration
2 REPLIES 2
Posted on July 15, 2018 at 04:45

I'd expect the samples to be packed as 16-bit values, not 32-bit ones, you'll want to read as 16-bit words or take the 32-bit word and split into two samples.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 15, 2018 at 06:57

That's it! I thought the three ADCs were triggering with some phase delay, but it seems that according to some text file I've found (thanks to your reply), 

1st request: ADC_CDR[31:0] = (ADC2_DR[15:0] << 16) | ADC1_DR[15:0] (step1)

2nd request: ADC_CDR[31:0] = (ADC1_DR[15:0] << 16) | ADC3_DR[15:0] (step2)

3rd request: ADC_CDR[31:0] = (ADC3_DR[15:0] << 16) | ADC2_DR[15:0] (step3)

Now things are more clear! Thank you! (got the values by splitting into g_val[0] >> 16 and g_val[0] & 0xFFFF)

Now I've only one problem left, setting ADC sample rate higher than 2.4MSPS makes the code 'hang' after HAL_ADCEx_MultiModeStart_DMA call. I've examined with the debugger and the ADC variables are updating, but the program never reaches while(1) loop, it just stucks right after the ADC start call. I don't believe 2.4MSPS is extremely high to cause that...

EDIT: Actually, it does look like the CPU is trying to reach while loop but never reaches because of interrupts, and when I disabled the I/D Caches (or triggered the ADC by timer) the situation worsened.