cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WB10 ADC DMA needs more regular channels

Ugilten
Associate III

Hi,

I am developing a small module with the STM32WB10 and I need to do 10 ADC conversions (9 external and the internal temperature).

However, I can only get the DMA to do the 8 channels configured in the regular channel ranks (Number of conversions = 8 is max in the CubeIDE configurator).

How do I make the DMA handle the last 2 channels aswell? if it is at all possible?

I can see in the stm32wb10xx.h that there is this define

#define ADC_SUPPORT_2_5_MSPS

that prevents the stm32wbxx_hal_adc.h from providing more than 8 ranks for the ADC, but I don't need 2,5MSPS. Is it possible to slow it down somewhere? I tried just giving it a slower clock, but that didn't do the trick...

0693W00000NpmVkQAJ.png

1 ACCEPTED SOLUTION

Accepted Solutions
Simon.T
ST Employee

Hi,

You don't need to implement the scan mode by your self. There is a reference in cube Mx. As I said in my previous message. If you want to scan more than 8 channels you need to set the sequencer as "Sequencer set to not fully configurable". This option is present on the ADC parameter settings.

Nevertheless I observed a bug on cube MX. Normally to config and set the ADC as not fully configurable. The user needs to select to set the sequencer as "Sequencer set to not fully configurable" and after selects the direction of the scan in the "Scan Conversion Mode" like in STM32G071RB cube MX:

0693W00000NpqatQAB.png 

But in the STM32WB1x when the user sets the sequencer as not fully configurable, the scan conversion mode stays stuck at "Disable".

0693W00000Npqa0QAB.pngThus when you generate the code. Normally in the ADC setup function (static void MX_ADC1_Init(void)) you should have this line :

  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;

Then to activate the scan you just need to replace ADC_SCAN_DISABLE by ADC_SCAN_DIRECTION_FORWARD or ADC_SCAN_DIRECTION_BACKWARD following the desired direction.

Best regards,

Simon TALAS

View solution in original post

6 REPLIES 6
Simon.T
ST Employee

Hello @Ugilten​ ,

The STM32WB can only scan 8 channels when the sequencer is set as fully configurable. If you want to scan more than 8 channels you need to set the sequencer at "not fully configurable".

It's explained in the part 15.3.8 Channel selection (CHSEL, SCANDIR, CHSELRMOD) of the RM0478 rev4.

Best regards,

Simon TALAS

Ugilten
Associate III

Hi @Simon.T​ ,

That is a good reference, however I cannot find any reference for this in the CubeMX configuration...

If I look through the setup functions i find this comment in "stm32wbxx_hal_adc.c" (around line 690)

/* Configuration of regular group sequencer:                              */
/* - if scan mode is disabled, regular channels sequence length is set to */
/*   0x00: 1 channel converted (channel on regular rank 1)                */
/*   Parameter "NbrOfConversion" is discarded.                            */
/*   Note: Scan mode is not present by hardware on this device, but       */
/*   emulated by software for alignment over all STM32 devices.           */
/* - if scan mode is enabled, regular channels sequence length is set to  */
/*   parameter "NbrOfConversion".                                         */
/*   Channels must be configured into each rank using function            */
/*   "HAL_ADC_ConfigChannel()".                                           */

So my next question is, if I have to implement the scan mode my self or if this happens behind the scenes in the HAL? and how do I set it up to do that?

Do I expand the autogenerated MX_ADC1_Init() function with the HAL_ADC_ConfiChannel() function or do I need to get into the LowLayer regime for this?

Thanks in advance

Simon.T
ST Employee

Hi,

You don't need to implement the scan mode by your self. There is a reference in cube Mx. As I said in my previous message. If you want to scan more than 8 channels you need to set the sequencer as "Sequencer set to not fully configurable". This option is present on the ADC parameter settings.

Nevertheless I observed a bug on cube MX. Normally to config and set the ADC as not fully configurable. The user needs to select to set the sequencer as "Sequencer set to not fully configurable" and after selects the direction of the scan in the "Scan Conversion Mode" like in STM32G071RB cube MX:

0693W00000NpqatQAB.png 

But in the STM32WB1x when the user sets the sequencer as not fully configurable, the scan conversion mode stays stuck at "Disable".

0693W00000Npqa0QAB.pngThus when you generate the code. Normally in the ADC setup function (static void MX_ADC1_Init(void)) you should have this line :

  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;

Then to activate the scan you just need to replace ADC_SCAN_DISABLE by ADC_SCAN_DIRECTION_FORWARD or ADC_SCAN_DIRECTION_BACKWARD following the desired direction.

Best regards,

Simon TALAS

Ugilten
Associate III

Ok, Now I finally got it working.

So just for my own peace of mind I will post my findings here so I can do it again in 6 months :beaming_face_with_smiling_eyes:

As @Simon.T​ mentioned above, I had to set the direction of the scanmode, but also register the channels it needs to scan in the CHSELR register by using the LL function

void LL_ADC_REG_SetSequencerChannels(ADC_TypeDef *ADCx, uint32_t Channel)

after the HAL setup of the ADC.

The ADC init code looks as follows

static void MX_ADC1_Init(void)
{
  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;/* CHANGED AS [STALA.1] SUGGESTED */
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_39CYCLES_5;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 9; /* Not sure if this makes any difference, I don't think it does */
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DMAContinuousRequests = ENABLE; /* Makes sure the DMA is triggered */
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */
	LL_ADC_REG_SetSequencerChannels(ADC1, LL_ADC_CHANNEL_2 | LL_ADC_CHANNEL_3 | LL_ADC_CHANNEL_5 | LL_ADC_CHANNEL_6 | LL_ADC_CHANNEL_7 | LL_ADC_CHANNEL_8 | LL_ADC_CHANNEL_9 | LL_ADC_CHANNEL_10 | LL_ADC_CHANNEL_11);
  /* USER CODE END ADC1_Init 2 */
}

Thanks for your help @Simon.T​ :thumbs_up:

Ugilten
Associate III

I have just been digging through the code in the HAL_ADC_Init() function in stm32wbxx_hal_adc.c and it only handles cases where ScanConvMode is ADC_SCAN_DISABLE or ADC_SCAN_ENABLE.

In both of these modes it sets CHSELRMOD = 1. In any other case this bit is 0, and that is what it makes the ADC/DMA work in the Not Fully Configured Mode.

Thus, to make sure it works after modifying the .ioc file and rebuilding the code from CubeMX, make sure to add these lines in user code ADC_Init 2 section

LL_ADC_REG_SetSequencerConfigurable(ADC1, LL_ADC_REG_SEQ_FIXED);
LL_ADC_REG_SetSequencerScanDirection(ADC1, LL_ADC_REG_SEQ_SCAN_DIR_FORWARD);
LL_ADC_REG_SetSequencerChannels(ADC1, LL_ADC_CHANNEL_2 | LL_ADC_CHANNEL_3 | ...);

Again, this is just for my own recolection, and hopefully someone else might find it usefull ;)

ADhim.1
Associate

Hi @Ugilten​ , actually i am facing the same issue as you , as i have to you all the adc channels here on dma, but when I turn on the sequencer to not fully configurable mode and select all the adc , my resulted dma buffer is showing fluctuating values if I pull that particular pin to 3.3v.

I am using dma on circular mode , couldn't find any resolution on st community.