cancel
Showing results for 
Search instead for 
Did you mean: 

Problem using ADC on Cortex M4

mali
Associate

I am currently using a STM32MP157a on an SOC module from aries-embedded and try use the internal ADC in M4 context. However, I always get 32678 for 16bit settings regardless of the other ADC settings or channel selected. For 12 bit the value is then 2048.

I figured out that on that SOC module VDDA input of the STM32MP157 is connected to LDO2 of the STPMIC1A and there is no voltage present. I guess the LDO is not activated during boot of the Linux. I used the following settings in my dts file, for the PMIC:

&i2c4 {
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&i2c4_pins_z_mx>;
	pinctrl-1 = <&i2c4_sleep_pins_z_mx>;
	status = "okay";

	/* USER CODE BEGIN i2c4 */
	/delete-property/dmas;
		/delete-property/dma-names;

		pmic: stpmic@33 {
			compatible = "st,stpmic1";
			reg = <0x33>;
			interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>;
			interrupt-controller;
			#interrupt-cells = <2>;
			status = "okay";

			regulators {
				compatible = "st,stpmic1-regulators";
				buck1-supply = <&vin>;
				buck2-supply = <&vin>;
				buck3-supply = <&vin>;
				buck4-supply = <&vin>;
				ldo1-supply = <&v3v3>;
				ldo2-supply = <&v3v3>;
				ldo3-supply = <&v3v3>;
				ldo5-supply = <&vin>;
				ldo6-supply = <&vin>;
				vref_ddr-supply = <&vin>;
				boost-supply = <&vin>;
				pwr_sw1-supply = <&bst_out>;
				pwr_sw2-supply = <&bst_out>;

				vddcore: buck1 {
					regulator-name = "vddcore";
					regulator-min-microvolt = <1200000>;
					regulator-max-microvolt = <1250000>;
					regulator-always-on;
					regulator-initial-mode = <0>;
					regulator-over-current-protection;
				};

				vdd_ddr: buck2 {
					regulator-name = "vdd_ddr";
					regulator-min-microvolt = <1250000>;
					regulator-max-microvolt = <1250000>;
					regulator-always-on;
					regulator-initial-mode = <0>;
					regulator-over-current-protection;
				};

				vdd: buck3 {
					regulator-name = "vdd";
					regulator-min-microvolt = <3300000>;
					regulator-max-microvolt = <3300000>;
					regulator-always-on;
					st,mask-reset;
					regulator-initial-mode = <0>;
					regulator-over-current-protection;
				};

				v3v3: buck4 {
					regulator-name = "v3v3";
					regulator-min-microvolt = <3300000>;
					regulator-max-microvolt = <3300000>;
					regulator-always-on;
					regulator-over-current-protection;
					regulator-initial-mode = <0>;
				};

				vflash: ldo1 {
					regulator-name = "vflash";
					regulator-min-microvolt = <3300000>;
					regulator-max-microvolt = <3300000>;
					//interrupts = <IT_CURLIM_LDO1 0>;
				};

				vdda: ldo2 {
					regulator-name = "vdda";
					regulator-min-microvolt = <2900000>;
					regulator-max-microvolt = <2900000>;
					//interrupts = <IT_CURLIM_LDO2 0>;
					regulator-always-on;
				};

				vdd1_lpddr: ldo3 {
					regulator-name = "vdd1_lpddr";
					regulator-min-microvolt = <1800000>;
					regulator-max-microvolt = <1800000>;
					regulator-always-on;
					regulator-over-current-protection;
				};

				vdd_usb: ldo4 {
					regulator-name = "vdd_usb";
					//interrupts = <IT_CURLIM_LDO4 0>;
					regulator-always-on;
				};

				vdd_sd: ldo5 {
					regulator-name = "vdd_sd";
					regulator-min-microvolt = <2900000>;
					regulator-max-microvolt = <2900000>;
					//interrupts = <IT_CURLIM_LDO5 0>;
					regulator-boot-on;
				};

				v1v8: ldo6 {
					regulator-name = "v1v8";
					regulator-min-microvolt = <1800000>;
					regulator-max-microvolt = <1800000>;
					//interrupts = <IT_CURLIM_LDO6 0>;
				};

				vref_ddr: vref_ddr {
					regulator-name = "vref_ddr";
					regulator-always-on;
				};

				bst_out: boost {
					regulator-name = "bst_out";
					//interrupts = <IT_OCP_BOOST 0>;
				};

				vbus_otg: pwr_sw1 {
					regulator-name = "vbus_otg";
					//interrupts = <IT_OCP_OTG 0>;
				};

				vbus_sw: pwr_sw2 {
					regulator-name = "vbus_sw";
					//interrupts = <IT_OCP_SWOUT 0>;
					regulator-active-discharge = <1>;
				};
			};

			onkey {
				compatible = "st,stpmic1-onkey";
				//interrupts = <IT_PONKEY_F 0>, <IT_PONKEY_R 0>;
				//interrupt-names = "onkey-falling", "onkey-rising";
				power-off-time-sec = <10>;
				status = "okay";
			};

			watchdog {
				compatible = "st,stpmic1-wdt";
				status = "disabled";
			};
		};
	/* USER CODE END i2c4 */
};

 

for the ADC:

&m4_adc {
	pinctrl-names = "default";
	pinctrl-0 = <&m4_adc_pins_mx>;
	status = "okay";

	/* USER CODE BEGIN m4_adc */
	vref-supply = <&vrefbuf>;
	/* USER CODE END m4_adc */
};

 

for vrefbuf:

&vrefbuf {
	status = "okay";

	/* USER CODE BEGIN vrefbuf */
	regulator-min-microvolt = <2500000>;
	regulator-max-microvolt = <2500000>;
	vdda-supply = <&vdda>;
	/* USER CODE END vrefbuf */
};

 

On the m4 currently I use the the following code snippets:

main(){
...
  MX_ADC2_Init();
...  

  if(HAL_ADCEx_Calibration_Start(&hadc2, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED) != HAL_OK)
  {
	  /* Calibration Error */
	  Error_Handler();
  }

  HAL_ADC_Start(&hadc2);

  while (1)
  {
	  if(HAL_ADC_PollForConversion(&hadc2, 100)==HAL_OK){
		  value = HAL_ADC_GetValue(&hadc2);
		  HAL_ADC_Start(&hadc2);
	  }else{
		  value = 0;
	  }
   }
}

void MX_ADC2_Init(void)
{

  /* USER CODE BEGIN ADC2_Init 0 */

  /* USER CODE END ADC2_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC2_Init 1 */

  /* USER CODE END ADC2_Init 1 */

  /** Common config
  */
  hadc2.Instance = ADC2;
  hadc2.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;
  hadc2.Init.Resolution = ADC_RESOLUTION_16B;
  hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc2.Init.LowPowerAutoWait = DISABLE;
  hadc2.Init.ContinuousConvMode = DISABLE;
  hadc2.Init.NbrOfConversion = 1;
  hadc2.Init.DiscontinuousConvMode = DISABLE;
  hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc2.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
  hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc2.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc2.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc2) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_3;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC2_Init 2 */

  /* USER CODE END ADC2_Init 2 */

}

 

Any suggestions or help why I cannot use the internal ADC and why LDO2 is not powered on, which might be the root cause?

 

0 REPLIES 0