From dde5cb11bc7a8964335a3d50bdfd0a40bae1ebbd Mon Sep 17 00:00:00 2001 From: Gabriel Zerbib Date: Thu, 25 Sep 2025 08:47:11 +0200 Subject: [PATCH] g431-esc: use internal ADC channels, also fix some typos --- src/common/base_classes/FOCMotor.h | 2 +- src/communication/Commander.h | 4 +- .../stm32/b_g431/b_g431_hal.cpp | 53 ++++++++++++++-- .../stm32/b_g431/b_g431_hal.h | 2 + .../stm32/b_g431/b_g431_mcu.cpp | 60 ++++++++++++++----- 5 files changed, 98 insertions(+), 23 deletions(-) diff --git a/src/common/base_classes/FOCMotor.h b/src/common/base_classes/FOCMotor.h index 064426e4..d21e068e 100644 --- a/src/common/base_classes/FOCMotor.h +++ b/src/common/base_classes/FOCMotor.h @@ -22,7 +22,7 @@ #define _MON_ANGLE 0b0000001 // monitor angle value /** - * Motiron control type + * Motion control type */ enum MotionControlType : uint8_t { torque = 0x00, //!< Torque control diff --git a/src/communication/Commander.h b/src/communication/Commander.h index 4ec2b281..24bd3fbe 100644 --- a/src/communication/Commander.h +++ b/src/communication/Commander.h @@ -15,7 +15,7 @@ enum VerboseMode : uint8_t { nothing = 0x00, // display nothing - good for monitoring on_request = 0x01, // display only on user request - user_friendly = 0x02, // display textual messages to the user + user_friendly = 0x02, // display textual messages to the user machine_readable = 0x03 // display machine readable commands, matching commands to set each settings }; @@ -86,7 +86,7 @@ class Commander void run(char* user_input); /** - * Function adding a callback to the coomander withe the command id + * Function adding a callback to the commander with the command id * @param id - char command letter * @param onCommand - function pointer void function(char*) * @param label - string label to be displayed when scan command sent diff --git a/src/current_sense/hardware_specific/stm32/b_g431/b_g431_hal.cpp b/src/current_sense/hardware_specific/stm32/b_g431/b_g431_hal.cpp index dc505d6f..e72c09a6 100644 --- a/src/current_sense/hardware_specific/stm32/b_g431/b_g431_hal.cpp +++ b/src/current_sense/hardware_specific/stm32/b_g431/b_g431_hal.cpp @@ -95,7 +95,11 @@ void MX_ADC1_Init(ADC_HandleTypeDef* hadc1) hadc1->Init.EOCSelection = ADC_EOC_SINGLE_CONV; hadc1->Init.LowPowerAutoWait = DISABLE; hadc1->Init.ContinuousConvMode = DISABLE; + #ifdef OPAMP_USE_INTERNAL_CHANNEL + hadc1->Init.NbrOfConversion = 4; + #else hadc1->Init.NbrOfConversion = 5; + #endif hadc1->Init.DiscontinuousConvMode = DISABLE; hadc1->Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_TRGO; hadc1->Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; @@ -114,9 +118,10 @@ void MX_ADC1_Init(ADC_HandleTypeDef* hadc1) { SIMPLEFOC_DEBUG("HAL_ADCEx_MultiModeConfigChannel failed!"); } + #ifndef OPAMP_USE_INTERNAL_CHANNEL /** Configure Regular Channel */ - sConfig.Channel = ADC_CHANNEL_12; // ADC1_IN12 = PB1 = OP3_OUT + sConfig.Channel = ADC_CHANNEL_12; // ADC1_IN12 = PB1 = OP3_OUT or ADC2_IN18 for internal channel sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5; sConfig.SingleDiff = ADC_SINGLE_ENDED; @@ -126,10 +131,16 @@ void MX_ADC1_Init(ADC_HandleTypeDef* hadc1) { SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); } + #endif /** Configure Regular Channel */ - sConfig.Channel = ADC_CHANNEL_3; // ADC1_IN3 = PA2 = OP1_OUT + #ifdef OPAMP_USE_INTERNAL_CHANNEL + sConfig.Channel = ADC_CHANNEL_13; // ADC1_IN3 = PA2 = OP1_OUT or ADC1_IN13 for internal channel + sConfig.Rank = ADC_REGULAR_RANK_1; + #else + sConfig.Channel = ADC_CHANNEL_3; // ADC1_IN3 = PA2 = OP1_OUT or ADC1_IN13 for internal channel sConfig.Rank = ADC_REGULAR_RANK_2; + #endif if (HAL_ADC_ConfigChannel(hadc1, &sConfig) != HAL_OK) { SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); @@ -140,7 +151,11 @@ void MX_ADC1_Init(ADC_HandleTypeDef* hadc1) /* Configure Regular Channel (PB12, Potentiometer) */ sConfig.Channel = ADC_CHANNEL_11; + #ifdef OPAMP_USE_INTERNAL_CHANNEL + sConfig.Rank = ADC_REGULAR_RANK_2; + #else sConfig.Rank = ADC_REGULAR_RANK_3; + #endif sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5; sConfig.SingleDiff = ADC_SINGLE_ENDED; sConfig.OffsetNumber = ADC_OFFSET_NONE; @@ -153,7 +168,11 @@ void MX_ADC1_Init(ADC_HandleTypeDef* hadc1) /** Configure Regular Channel (PB14, Temperature) */ sConfig.Channel = ADC_CHANNEL_5; + #ifdef OPAMP_USE_INTERNAL_CHANNEL + sConfig.Rank = ADC_REGULAR_RANK_3; + #else sConfig.Rank = ADC_REGULAR_RANK_4; + #endif sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5; sConfig.SingleDiff = ADC_SINGLE_ENDED; sConfig.OffsetNumber = ADC_OFFSET_NONE; @@ -163,10 +182,14 @@ void MX_ADC1_Init(ADC_HandleTypeDef* hadc1) SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); } - /** Configure Regular Channel (PB14, Temperature) + /** Configure Regular Channel (PA0, VBUS) */ sConfig.Channel = ADC_CHANNEL_1; + #ifdef OPAMP_USE_INTERNAL_CHANNEL + sConfig.Rank = ADC_REGULAR_RANK_4; + #else sConfig.Rank = ADC_REGULAR_RANK_5; + #endif sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5; sConfig.SingleDiff = ADC_SINGLE_ENDED; sConfig.OffsetNumber = ADC_OFFSET_NONE; @@ -208,7 +231,11 @@ void MX_ADC2_Init(ADC_HandleTypeDef* hadc2) hadc2->Init.EOCSelection = ADC_EOC_SINGLE_CONV; hadc2->Init.LowPowerAutoWait = DISABLE; hadc2->Init.ContinuousConvMode = DISABLE; + #ifdef OPAMP_USE_INTERNAL_CHANNEL + hadc2->Init.NbrOfConversion = 2; + #else hadc2->Init.NbrOfConversion = 1; + #endif hadc2->Init.DiscontinuousConvMode = DISABLE; hadc2->Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_TRGO; hadc2->Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; @@ -221,7 +248,11 @@ void MX_ADC2_Init(ADC_HandleTypeDef* hadc2) } /** Configure Regular Channel */ - sConfig.Channel = ADC_CHANNEL_3; // ADC2_IN3 = PA6 + #ifdef OPAMP_USE_INTERNAL_CHANNEL + sConfig.Channel = ADC_CHANNEL_16; // ADC2_IN3 = PA6 = OP2_OUT or ADC2_IN16 for internal channel + #else + sConfig.Channel = ADC_CHANNEL_3; // ADC2_IN3 = PA6 = OP2_OUT or ADC2_IN16 for internal channel + #endif sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5; sConfig.SingleDiff = ADC_SINGLE_ENDED; @@ -231,6 +262,20 @@ void MX_ADC2_Init(ADC_HandleTypeDef* hadc2) { SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); } + #ifdef OPAMP_USE_INTERNAL_CHANNEL + /** Configure Regular Channel + */ + sConfig.Channel = ADC_CHANNEL_18; // ADC1_IN12 = PB1 = OP3_OUT or ADC2_IN18 for internal channel + sConfig.Rank = ADC_REGULAR_RANK_2; + sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5; + sConfig.SingleDiff = ADC_SINGLE_ENDED; + sConfig.OffsetNumber = ADC_OFFSET_NONE; + sConfig.Offset = 0; + if (HAL_ADC_ConfigChannel(hadc2, &sConfig) != HAL_OK) + { + SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); + } + #endif /* USER CODE BEGIN ADC2_Init 2 */ /* USER CODE END ADC2_Init 2 */ diff --git a/src/current_sense/hardware_specific/stm32/b_g431/b_g431_hal.h b/src/current_sense/hardware_specific/stm32/b_g431/b_g431_hal.h index 2d6a1f0a..e10f72e9 100644 --- a/src/current_sense/hardware_specific/stm32/b_g431/b_g431_hal.h +++ b/src/current_sense/hardware_specific/stm32/b_g431/b_g431_hal.h @@ -13,6 +13,8 @@ void MX_ADC2_Init(ADC_HandleTypeDef* hadc2); void MX_OPAMP1_Init(OPAMP_HandleTypeDef* hopamp); void MX_OPAMP2_Init(OPAMP_HandleTypeDef* hopamp); void MX_OPAMP3_Init(OPAMP_HandleTypeDef* hopamp); + +#define OPAMP_USE_INTERNAL_CHANNEL #endif #endif \ No newline at end of file diff --git a/src/current_sense/hardware_specific/stm32/b_g431/b_g431_mcu.cpp b/src/current_sense/hardware_specific/stm32/b_g431/b_g431_mcu.cpp index 0f105ee3..851d8b81 100644 --- a/src/current_sense/hardware_specific/stm32/b_g431/b_g431_mcu.cpp +++ b/src/current_sense/hardware_specific/stm32/b_g431/b_g431_mcu.cpp @@ -11,8 +11,13 @@ #define _ADC_VOLTAGE 3.3f #define _ADC_RESOLUTION 4096.0f +#ifdef OPAMP_USE_INTERNAL_CHANNEL +#define ADC_BUF_LEN_1 4 +#define ADC_BUF_LEN_2 2 +#else #define ADC_BUF_LEN_1 5 #define ADC_BUF_LEN_2 1 +#endif static ADC_HandleTypeDef hadc1; static ADC_HandleTypeDef hadc2; @@ -39,23 +44,46 @@ Stm32AdcInterruptConfig adc_interrupt_config[5] = { // function reading an ADC value and returning the read voltage // As DMA is being used just return the DMA result float _readADCVoltageLowSide(const int pin, const void* cs_params){ - uint32_t raw_adc = 0; - if(pin == PA2) // = ADC1_IN3 = phase U (OP1_OUT) on B-G431B-ESC1 - raw_adc = adcBuffer1[1]; - else if(pin == PA6) // = ADC2_IN3 = phase V (OP2_OUT) on B-G431B-ESC1 + uint32_t raw_adc; + #ifdef OPAMP_USE_INTERNAL_CHANNEL + #define ADC1_OFFSET 0 + #else + #define ADC1_OFFSET 1 + #endif + + switch (pin) + { + case A_OP1_OUT: + case -1: + raw_adc = adcBuffer1[0+ADC1_OFFSET]; + break; + case A_OP2_OUT: + case -2: raw_adc = adcBuffer2[0]; -#ifdef PB1 - else if(pin == PB1) // = ADC1_IN12 = phase W (OP3_OUT) on B-G431B-ESC1 + break; + #ifdef A_OP3_OUT + case A_OP3_OUT: + #endif + case -3: + #ifdef OPAMP_USE_INTERNAL_CHANNEL + raw_adc = adcBuffer2[1]; + #else raw_adc = adcBuffer1[0]; -#endif - - else if (pin == A_POTENTIOMETER) - raw_adc = adcBuffer1[2]; - else if (pin == A_TEMPERATURE) - raw_adc = adcBuffer1[3]; - else if (pin == A_VBUS) - raw_adc = adcBuffer1[4]; - + #endif + break; + case A_POTENTIOMETER: + raw_adc = adcBuffer1[1+ADC1_OFFSET]; + break; + case A_TEMPERATURE: + raw_adc = adcBuffer1[2+ADC1_OFFSET]; + break; + case A_VBUS: + raw_adc = adcBuffer1[3+ADC1_OFFSET]; + break; + default: + raw_adc = 0; + break; + } return raw_adc * ((Stm32CurrentSenseParams*)cs_params)->adc_voltage_conv; } @@ -65,7 +93,7 @@ void _configureOPAMP(OPAMP_HandleTypeDef *hopamp, OPAMP_TypeDef *OPAMPx_Def){ hopamp->Init.PowerMode = OPAMP_POWERMODE_HIGHSPEED; hopamp->Init.Mode = OPAMP_PGA_MODE; hopamp->Init.NonInvertingInput = OPAMP_NONINVERTINGINPUT_IO0; - hopamp->Init.InternalOutput = DISABLE; + hopamp->Init.InternalOutput = ENABLE; hopamp->Init.TimerControlledMuxmode = OPAMP_TIMERCONTROLLEDMUXMODE_DISABLE; hopamp->Init.PgaConnect = OPAMP_PGA_CONNECT_INVERTINGINPUT_IO0_BIAS; hopamp->Init.PgaGain = OPAMP_PGA_GAIN_16_OR_MINUS_15;