1#include "../../../hardware_api.h"
3#if defined(ARDUINO_B_G431B_ESC1)
7#include "../stm32_mcu.h"
8#include "../../../../drivers/hardware_specific/stm32/stm32_mcu.h"
10#include "../stm32_adc_utils.h"
12#define _ADC_VOLTAGE 3.3f
13#define _ADC_RESOLUTION 4096.0f
14#ifdef OPAMP_USE_INTERNAL_CHANNEL
15#define ADC_BUF_LEN_1 4
16#define ADC_BUF_LEN_2 2
18#define ADC_BUF_LEN_1 5
19#define ADC_BUF_LEN_2 1
22static ADC_HandleTypeDef hadc1;
23static ADC_HandleTypeDef hadc2;
24static OPAMP_HandleTypeDef hopamp1;
25static OPAMP_HandleTypeDef hopamp2;
26static OPAMP_HandleTypeDef hopamp3;
28static DMA_HandleTypeDef hdma_adc1;
29static DMA_HandleTypeDef hdma_adc2;
31volatile uint16_t adcBuffer1[ADC_BUF_LEN_1] = {0};
32volatile uint16_t adcBuffer2[ADC_BUF_LEN_2] = {0};
36Stm32AdcInterruptConfig adc_interrupt_config[5] = {
48 #ifdef OPAMP_USE_INTERNAL_CHANNEL
58 raw_adc = adcBuffer1[0+ADC1_OFFSET];
62 raw_adc = adcBuffer2[0];
68 #ifdef OPAMP_USE_INTERNAL_CHANNEL
69 raw_adc = adcBuffer2[1];
71 raw_adc = adcBuffer1[0];
75 raw_adc = adcBuffer1[1+ADC1_OFFSET];
78 raw_adc = adcBuffer1[2+ADC1_OFFSET];
81 raw_adc = adcBuffer1[3+ADC1_OFFSET];
87 return raw_adc * ((Stm32CurrentSenseParams*)
cs_params)->adc_voltage_conv;
90void _configureOPAMP(OPAMP_HandleTypeDef *hopamp, OPAMP_TypeDef *OPAMPx_Def){
92 hopamp->Instance = OPAMPx_Def;
93 hopamp->Init.PowerMode = OPAMP_POWERMODE_HIGHSPEED;
94 hopamp->Init.Mode = OPAMP_PGA_MODE;
95 hopamp->Init.NonInvertingInput = OPAMP_NONINVERTINGINPUT_IO0;
96 hopamp->Init.InternalOutput = OPAMP_USE_INTERNAL_CHANNEL ? ENABLE : DISABLE;
97 hopamp->Init.TimerControlledMuxmode = OPAMP_TIMERCONTROLLEDMUXMODE_DISABLE;
98 hopamp->Init.PgaConnect = OPAMP_PGA_CONNECT_INVERTINGINPUT_IO0_BIAS;
99 hopamp->Init.PgaGain = OPAMP_PGA_GAIN_16_OR_MINUS_15;
100 hopamp->Init.UserTrimming = OPAMP_TRIMMING_FACTORY;
101 if (HAL_OPAMP_Init(hopamp) != HAL_OK)
106void _configureOPAMPs(OPAMP_HandleTypeDef *OPAMPA, OPAMP_HandleTypeDef *OPAMPB, OPAMP_HandleTypeDef *OPAMPC){
108 _configureOPAMP(OPAMPA, OPAMP1);
109 _configureOPAMP(OPAMPB, OPAMP2);
110 _configureOPAMP(OPAMPC, OPAMP3);
113void MX_DMA1_Init(ADC_HandleTypeDef *hadc, DMA_HandleTypeDef *hdma_adc, DMA_Channel_TypeDef* channel, uint32_t request) {
114 hdma_adc->Instance = channel;
115 hdma_adc->Init.Request = request;
116 hdma_adc->Init.Direction = DMA_PERIPH_TO_MEMORY;
117 hdma_adc->Init.PeriphInc = DMA_PINC_DISABLE;
118 hdma_adc->Init.MemInc = DMA_MINC_ENABLE;
119 hdma_adc->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
120 hdma_adc->Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
121 hdma_adc->Init.Mode = DMA_CIRCULAR;
122 hdma_adc->Init.Priority = DMA_PRIORITY_LOW;
123 HAL_DMA_DeInit(hdma_adc);
124 if (HAL_DMA_Init(hdma_adc) != HAL_OK)
128 __HAL_LINKDMA(hadc, DMA_Handle, *hdma_adc);
137 SIMPLEFOC_DEBUG(
"B-G431B does not implement inline current sense. Use low-side current sense instead.");
148 _configureOPAMPs(&hopamp1, &hopamp3, &hopamp2);
149 MX_ADC1_Init(&hadc1);
150 MX_ADC2_Init(&hadc2);
152 HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED);
153 HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);
155 MX_DMA1_Init(&hadc1, &hdma_adc1, DMA1_Channel1, DMA_REQUEST_ADC1);
156 MX_DMA1_Init(&hadc2, &hdma_adc2, DMA1_Channel2, DMA_REQUEST_ADC2);
158 if (HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adcBuffer1, ADC_BUF_LEN_1) != HAL_OK)
162 if (HAL_ADC_Start_DMA(&hadc2, (uint32_t*)adcBuffer2, ADC_BUF_LEN_2) != HAL_OK)
167 HAL_OPAMP_Start(&hopamp1);
168 HAL_OPAMP_Start(&hopamp2);
169 HAL_OPAMP_Start(&hopamp3);
171 Stm32CurrentSenseParams*
params =
new Stm32CurrentSenseParams {
173 .adc_voltage_conv = (_ADC_VOLTAGE) / (_ADC_RESOLUTION),
174 .timer_handle = ((STM32DriverParams*)driver_params)->timers_handle[0],
181void DMA1_Channel1_IRQHandler(
void) {
182 HAL_DMA_IRQHandler(&hdma_adc1);
185void DMA1_Channel2_IRQHandler(
void) {
186 HAL_DMA_IRQHandler(&hdma_adc2);
191 STM32DriverParams* driver_params = (STM32DriverParams*)_driver_params;
192 Stm32CurrentSenseParams*
cs_params = (Stm32CurrentSenseParams*)_cs_params;
195 stm32_pause(driver_params);
198 int adc_index = _adcToIndex(
cs_params->adc_handle);
200 bool tim_interrupt = _initTimerInterruptDownsampling(
cs_params, driver_params, adc_interrupt_config[adc_index]);
203 SIMPLEFOC_DEBUG(
"STM32-CS: timer has no repetition counter, ADC interrupt not supported for B-G431");
208 LL_TIM_SetTriggerOutput(
cs_params->timer_handle->Instance, LL_TIM_TRGO_UPDATE);
211 stm32_resume(driver_params);
#define SIMPLEFOC_DEBUG(msg,...)
void * _configureADCInline(const void *driver_params, const int pinA, const int pinB, const int pinC=NOT_SET)
void * _driverSyncLowSide(void *driver_params, void *cs_params)
#define SIMPLEFOC_CURRENT_SENSE_INIT_FAILED
void * _configureADCLowSide(const void *driver_params, const int pinA, const int pinB, const int pinC=NOT_SET)
float _readADCVoltageLowSide(const int pinA, const void *cs_params)
const int const int const int pinC
GenericCurrentSenseParams * params