diff --git a/MotorControl/low_level.c b/MotorControl/low_level.c index 0002a6c6..2d2cbbcc 100644 --- a/MotorControl/low_level.c +++ b/MotorControl/low_level.c @@ -15,6 +15,8 @@ #include // Global variables +float vbus_voltage = 0; + Motor_t motors[] = { { //M0 /* .motor_thread to be set by thread at thread start */ @@ -178,10 +180,12 @@ static void init_encoders() { static void start_adc_pwm(){ //Enable ADC and interrupts + __HAL_ADC_ENABLE(&hadc1); __HAL_ADC_ENABLE(&hadc2); __HAL_ADC_ENABLE(&hadc3); //Warp field stabilize. osDelay(2); + __HAL_ADC_ENABLE_IT(&hadc1, ADC_IT_JEOC); __HAL_ADC_ENABLE_IT(&hadc2, ADC_IT_JEOC); __HAL_ADC_ENABLE_IT(&hadc3, ADC_IT_JEOC); @@ -221,6 +225,13 @@ static float phase_current_from_adcval(uint32_t ADCValue, int motornum) { return current; } +void vbus_sense_adc_cb(ADC_HandleTypeDef* hadc) { + const float voltage_scale = 3.3 * 11 / (float)(1<<12); + //Only one conversion in sequence, so only rank1 + uint32_t ADCValue = HAL_ADCEx_InjectedGetValue(hadc, ADC_INJECTED_RANK_1); + vbus_voltage = ADCValue * voltage_scale; +} + // This is the callback from the ADC that we expect after the PWM has triggered an ADC conversion. //@TODO: Document how the phasing is done void pwm_trig_adc_cb(ADC_HandleTypeDef* hadc) { diff --git a/MotorControl/low_level.h b/MotorControl/low_level.h index d9a7d8d8..669813c2 100644 --- a/MotorControl/low_level.h +++ b/MotorControl/low_level.h @@ -23,11 +23,13 @@ enum Motor_thread_signals { M_SIGNAL_PH_CURRENT_MEAS = 1u << 0 }; +extern float vbus_voltage; extern Motor_t motors[]; extern const int num_motors; void init_motor_control(); void pwm_trig_adc_cb(ADC_HandleTypeDef* hadc); +void vbus_sense_adc_cb(ADC_HandleTypeDef* hadc); //@TODO move motor thread to high level file void motor_thread(void const * argument); diff --git a/Src/stm32f4xx_it.c b/Src/stm32f4xx_it.c index b51c5389..00e77c76 100644 --- a/Src/stm32f4xx_it.c +++ b/Src/stm32f4xx_it.c @@ -175,6 +175,7 @@ void ADC_IRQHandler(void) // The HAL's ADC handling mechanism adds many clock cycles of overhead // So we bypass it and handle the logic ourselves. //@TODO add vbus meaasurement on adc1 here + ADC_IRQ_Dispatch(&hadc1, &vbus_sense_adc_cb); ADC_IRQ_Dispatch(&hadc2, &pwm_trig_adc_cb); ADC_IRQ_Dispatch(&hadc3, &pwm_trig_adc_cb);