cancel
Showing results for 
Search instead for 
Did you mean: 

CubeMX ADC Init bug

Posted on November 29, 2017 at 08:52

Hello there,

Here is my CubeMX version:

0690X000006091bQAA.png

The libs versions:

0690X000006090OQAQ.png

So I am using STM32L4. The bug is within ADC initialization procedure created by CubeMX. This is how to trace the bug:

Locate this function:

HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig)

In the file stm32l4xx_hal_adc.c. In line 2201 there is an assert:

assert_param(IS_ADC_REGULAR_RANK(sConfig->Rank));

The condition for it is wrong, If we go to the IS_ADC_REGULAR_RANK code we get:

/**

  * @brief Verify the ADC regular channel setting.

  * @param  __CHANNEL__ programmed ADC regular channel.

  * @retval SET (__CHANNEL__ is valid) or RESET (__CHANNEL__ is invalid)

  */

&sharpdefine IS_ADC_REGULAR_RANK(__CHANNEL__) (((__CHANNEL__) == ADC_REGULAR_RANK_1 ) || \

                                          ((__CHANNEL__) == ADC_REGULAR_RANK_2 ) || \

                                          ((__CHANNEL__) == ADC_REGULAR_RANK_3 ) || \

                                          ((__CHANNEL__) == ADC_REGULAR_RANK_4 ) || \

                                          ((__CHANNEL__) == ADC_REGULAR_RANK_5 ) || \

                                          ((__CHANNEL__) == ADC_REGULAR_RANK_6 ) || \

                                          ((__CHANNEL__) == ADC_REGULAR_RANK_7 ) || \

                                          ((__CHANNEL__) == ADC_REGULAR_RANK_8 ) || \

                                          ((__CHANNEL__) == ADC_REGULAR_RANK_9 ) || \

                                          ((__CHANNEL__) == ADC_REGULAR_RANK_10) || \

                                          ((__CHANNEL__) == ADC_REGULAR_RANK_11) || \

                                          ((__CHANNEL__) == ADC_REGULAR_RANK_12) || \

                                          ((__CHANNEL__) == ADC_REGULAR_RANK_13) || \

                                          ((__CHANNEL__) == ADC_REGULAR_RANK_14) || \

                                          ((__CHANNEL__) == ADC_REGULAR_RANK_15) || \

                                          ((__CHANNEL__) == ADC_REGULAR_RANK_16)   )

Then we check what is under the ADC_REGULAR_RANK_1:

&sharpdefine ADC_REGULAR_RANK_1                 (LL_ADC_REG_RANK_1)  /*!< ADC group regular sequencer rank 1 */

Then going further what is under LL_ADC_REG_RANK_1:

&sharpdefine LL_ADC_REG_RANK_1                  (ADC_SQR1_REGOFFSET | ADC_REG_RANK_1_SQRX_BITOFFSET_POS)  /*!< ADC group regular sequencer rank 1 */

ADC_SQR1_REGOFFSET is 0, ADC_REG_RANK_1_SQRX_BITOFFSET_POS is 6, ADC_REG_RANK_2_SQRX_BITOFFSET_POS is 12 and so on.

The parameter generated by CubeMX for Rank 1 (sConfig->Rank) is 1, thus it cannot past an assert because 1 != 6, 2 != 12 and so on.

Could someone please confirm this bug?

#cubemx #adc #bug-report
1 ACCEPTED SOLUTION

Accepted Solutions
Sirma Siang
ST Employee
Posted on January 10, 2018 at 18:07

Hello

Przenioslo.Lukasz

First I would like to thank you for your bug report.

I confirm you that this has been corrected in the 4.

Regular and injected channels use now library definitions.

It will be available by end of January.

Kind regards

Sirma

View solution in original post

5 REPLIES 5
Nils Zottmann
Associate II
Posted on November 29, 2017 at 12:08

I discovered the same bug, but there is a deeper problem when using more than 5 channels.

CubeMX (4.0, L4 1.0) generates ADC init code like this:

/**Configure Regular Channel 
 */
 sConfig.Channel = ADC_CHANNEL_8;
 sConfig.Rank = 1;
 sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
 sConfig.SingleDiff = ADC_SINGLE_ENDED;
 sConfig.OffsetNumber = ADC_OFFSET_NONE;
 sConfig.Offset = 0;
 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }�?�?�?�?�?�?�?�?�?�?�?�?

In the mentioned

stm32l4xx_hal_adc.c we find this code:

if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET)
 {
 #if !defined (USE_FULL_ASSERT)
 /* Correspondance for compatibility with legacy definition of */
 /* sequencer ranks in direct number format. This correspondance can */
 /* be done only on ranks 1 to 5 due to literal values. */
 /* Note: Sequencer ranks in direct number format are no more used */
 /* and are detected by activating USE_FULL_ASSERT feature. */
 if (sConfig->Rank <= 5U)
 {
 switch (sConfig->Rank)
 {
 case 2U: sConfig->Rank = ADC_REGULAR_RANK_2; break;
 case 3U: sConfig->Rank = ADC_REGULAR_RANK_3; break;
 case 4U: sConfig->Rank = ADC_REGULAR_RANK_4; break;
 case 5U: sConfig->Rank = ADC_REGULAR_RANK_5; break;
 /* case 1U */
 default: sConfig->Rank = ADC_REGULAR_RANK_1;
 }
 }
 #endif
 
 /* Set ADC group regular sequence: channel on the selected scan sequence rank */
 LL_ADC_REG_SetSequencerRanks(hadc->Instance, sConfig->Rank, sConfig->Channel);�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

As you can see, if the rank is >5, it is not handled by the switch. This leads to a wrong rank definition if using more than 5 channels with CubeMX!

But the main question is: The comment says

Note: Sequencer ranks in direct number format are no more usedand are detected by activating USE_FULL_ASSERT feature.

It's nice that FULL_ASSERT is detecting the no more used direct number format, but why does CubeMX use it when generating code?

CubeMX generates this:

sConfig.Rank = 1;�?

but shouln't it be this:

sConfig.Rank = ADC_REGULAR_RANK_1;�?

?

Posted on November 29, 2017 at 12:44

Hello All,

Please note that your feedback is raised internally and ADC issue is already reported to our CubeMx team for fix.

Sorry for the inconvenience it may bring.

Best Regards

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
Posted on December 05, 2017 at 09:16

Thank you this solved my issue.

Posted on December 07, 2017 at 09:35

I used the following workaround, this works without changing any ST libs and is CubeMX regeneration safe. Insert in user code 2 section after MX_***_Init() calls.

#define ADC1_CHCNT 4
/* TODO: Remove if bug is fixed
 * Correct wrong code by CubeM
X */
MODIFY_REG(hadc1.Instance->SQR1, ADC_SQR1_L, (ADC1_CHCNT - (uint8_t)1));
LL_ADC_REG_SetSequencerRanks(hadc1.Instance, ADC_REGULAR_RANK_1, ADC_CHANNEL_8);
LL_ADC_REG_SetSequencerRanks(hadc1.Instance, ADC_REGULAR_RANK_2, ADC_CHANNEL_15);
LL_ADC_REG_SetSequencerRanks(hadc1.Instance, ADC_REGULAR_RANK_3, ADC_CHANNEL_12);
LL_ADC_REG_SetSequencerRanks(hadc1.Instance, ADC_REGULAR_RANK_4, ADC_CHANNEL_13);�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Sirma Siang
ST Employee
Posted on January 10, 2018 at 18:07

Hello

Przenioslo.Lukasz

First I would like to thank you for your bug report.

I confirm you that this has been corrected in the 4.

Regular and injected channels use now library definitions.

It will be available by end of January.

Kind regards

Sirma