diff --git a/MotorControl/low_level.c b/MotorControl/low_level.c index 2a38c756..1d888c7e 100644 --- a/MotorControl/low_level.c +++ b/MotorControl/low_level.c @@ -152,11 +152,17 @@ static void start_adc_pwm(){ __HAL_ADC_ENABLE_IT(&hadc1, ADC_IT_JEOC); __HAL_ADC_ENABLE_IT(&hadc2, ADC_IT_JEOC); __HAL_ADC_ENABLE_IT(&hadc3, ADC_IT_JEOC); + __HAL_ADC_ENABLE_IT(&hadc2, ADC_IT_EOC); + __HAL_ADC_ENABLE_IT(&hadc3, ADC_IT_EOC); //Ensure that debug halting of the core doesn't leave the motor PWM running __HAL_DBGMCU_FREEZE_TIM1(); __HAL_DBGMCU_FREEZE_TIM8(); + //Turn off the regular conversion trigger for the inital phase + hadc2.Instance->CR2 &= ~ADC_CR2_EXTEN; + hadc3.Instance->CR2 &= ~ADC_CR2_EXTEN; + start_pwm(&htim1); start_pwm(&htim8); sync_timers(&htim1, &htim8, TIM_CLOCKSOURCE_ITR0, TIM_PERIOD_CLOCKS/2); @@ -229,7 +235,7 @@ static void sync_timers(TIM_HandleTypeDef* htim_a, TIM_HandleTypeDef* htim_b, htim_a->Instance->CNT = count_offset; htim_b->Instance->CNT = 0; - // Start Timer 1 + // Start Timer a htim_a->Instance->CR1 |= (TIM_CR1_CEN); // Restore timer configs @@ -293,16 +299,27 @@ void pwm_trig_adc_cb(ADC_HandleTypeDef* hadc) { // Check if this trigger was the CC4 channel, used for actual current measurement at SVM vector 0 // or the update trigger, which is used for DC_CAL measurement at SVM vector 7 - uint32_t trig_src = hadc->Instance->CR2 & ADC_CR2_JEXTSEL; - if (trig_src == ADC_EXTERNALTRIGINJECCONV_T1_CC4) { + uint32_t inj_src = hadc->Instance->CR2 & ADC_CR2_JEXTSEL; + uint32_t reg_edge = hadc->Instance->CR2 & ADC_CR2_EXTEN; + if (reg_edge != ADC_EXTERNALTRIGCONVEDGE_NONE) { + //We are measuring M1 DC_CAL here + Motor_t* motor = &motors[0]; //TODO WRONG + check_timing(motor->timer_handle, timing_logs[1], &timing_log_index[1]); + //Next measurement on this motor will be M1 current measurement + HAL_GPIO_WritePin(M1_DC_CAL_GPIO_Port, M1_DC_CAL_Pin, GPIO_PIN_RESET); + //Next measurement on this ADC will be M0 current + hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN | ADC_CR2_EXTEN | ADC_CR2_JEXTSEL); + hadc->Instance->CR2 |= (ADC_EXTERNALTRIGINJECCONVEDGE_RISING | ADC_EXTERNALTRIGINJECCONV_T1_CC4); + + } else if (inj_src == ADC_EXTERNALTRIGINJECCONV_T1_CC4) { //We are measuring M0 current here Motor_t* motor = &motors[0]; check_timing(motor->timer_handle, timing_logs[0], &timing_log_index[0]); //Next measurement on this motor will be M0 DC_CAL measurement HAL_GPIO_WritePin(M0_DC_CAL_GPIO_Port, M0_DC_CAL_Pin, GPIO_PIN_SET); //Next measurement on this ADC will be M1 current - hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL); - hadc->Instance->CR2 |= ADC_EXTERNALTRIGINJECCONV_T8_CC4; + hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN | ADC_CR2_EXTEN | ADC_CR2_JEXTSEL); + hadc->Instance->CR2 |= (ADC_EXTERNALTRIGINJECCONVEDGE_RISING | ADC_EXTERNALTRIGINJECCONV_T8_CC4); // ADC2 and ADC3 record the phB and phC currents concurrently, // and their interrupts should arrive on the same clock cycle. @@ -326,15 +343,25 @@ void pwm_trig_adc_cb(ADC_HandleTypeDef* hadc) { osSignalSet(motor->motor_thread, M_SIGNAL_PH_CURRENT_MEAS); } - } else if (trig_src == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) { + } else if (inj_src == ADC_EXTERNALTRIGINJECCONV_T8_CC4) { + //We are measuring M1 current here + Motor_t* motor = &motors[0]; //TODO WRONG + check_timing(motor->timer_handle, timing_logs[1], &timing_log_index[1]); + //Next measurement on this motor will be M1 DC_CAL measurement + HAL_GPIO_WritePin(M1_DC_CAL_GPIO_Port, M1_DC_CAL_Pin, GPIO_PIN_SET); + //Next measurement on this ADC will be M0 DC_CAL + hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN | ADC_CR2_EXTEN | ADC_CR2_JEXTSEL); + hadc->Instance->CR2 |= (ADC_EXTERNALTRIGINJECCONVEDGE_RISING | ADC_EXTERNALTRIGINJECCONV_T1_TRGO); + + } else if (inj_src == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) { //We are measuring M0 DC_CAL here Motor_t* motor = &motors[0]; check_timing(motor->timer_handle, timing_logs[0], &timing_log_index[0]); - //Set up next measurement to be M0 current measurement - // @TODO Add M1 to sequence - hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL); - hadc->Instance->CR2 |= ADC_EXTERNALTRIGINJECCONV_T1_CC4; + //Next measurement on this motor will be M0 current measurement HAL_GPIO_WritePin(M0_DC_CAL_GPIO_Port, M0_DC_CAL_Pin, GPIO_PIN_RESET); + //Next measurement on this ADC will be M1 DC_CAL + hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN | ADC_CR2_EXTEN | ADC_CR2_JEXTSEL); + hadc->Instance->CR2 |= ADC_EXTERNALTRIGCONVEDGE_RISING; if (hadc == &hadc2) { motor->DC_calib.phB += (current - motor->DC_calib.phB) * calib_filter_k; @@ -345,15 +372,6 @@ void pwm_trig_adc_cb(ADC_HandleTypeDef* hadc) { safe_assert(0); } - } else if (trig_src == ADC_EXTERNALTRIGINJECCONV_T8_CC4) { - //We are measuring M1 current here - Motor_t* motor = &motors[0]; //TODO WRONG - check_timing(motor->timer_handle, timing_logs[1], &timing_log_index[1]); - //Next measurement on this motor will be M1 DC_CAL measurement - HAL_GPIO_WritePin(M1_DC_CAL_GPIO_Port, M1_DC_CAL_Pin, GPIO_PIN_SET); - //Next measurement on this ADC will be M0 DC_CAL - hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL); - hadc->Instance->CR2 |= ADC_EXTERNALTRIGINJECCONV_T1_TRGO; } else { safe_assert(0); } diff --git a/Odrive.ioc b/Odrive.ioc index 32bc879c..47605767 100755 --- a/Odrive.ioc +++ b/Odrive.ioc @@ -33,10 +33,11 @@ ADC2.DataAlign=ADC_DATAALIGN_RIGHT ADC2.DiscontinuousConvMode=DISABLE ADC2.EOCSelection=ADC_EOC_SINGLE_CONV ADC2.EnableAnalogWatchDog=false -ADC2.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE +ADC2.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T8_TRGO +ADC2.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_RISING ADC2.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_T1_CC4 ADC2.ExternalTrigInjecConvEdge=ADC_EXTERNALTRIGINJECCONVEDGE_RISING -ADC2.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,ClockPrescaler,Resolution,DataAlign,ScanConvMode,ContinuousConvMode,DiscontinuousConvMode,DMAContinuousRequests,EOCSelection,NbrOfConversion,InjNumberOfConversion,EnableAnalogWatchDog,Rank-1\#ChannelInjectedConversion,Channel-1\#ChannelInjectedConversion,SamplingTime-1\#ChannelInjectedConversion,InjectedOffset-1\#ChannelInjectedConversion,ExternalTrigInjecConvEdge,ExternalTrigConvEdge,InjectedConvMode,ExternalTrigInjecConv +ADC2.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,ClockPrescaler,Resolution,DataAlign,ScanConvMode,ContinuousConvMode,DiscontinuousConvMode,DMAContinuousRequests,EOCSelection,NbrOfConversion,InjNumberOfConversion,EnableAnalogWatchDog,Rank-1\#ChannelInjectedConversion,Channel-1\#ChannelInjectedConversion,SamplingTime-1\#ChannelInjectedConversion,InjectedOffset-1\#ChannelInjectedConversion,ExternalTrigInjecConvEdge,ExternalTrigConvEdge,InjectedConvMode,ExternalTrigInjecConv,ExternalTrigConv ADC2.InjNumberOfConversion=1 ADC2.InjectedConvMode=None ADC2.InjectedOffset-1\#ChannelInjectedConversion=0 @@ -57,10 +58,11 @@ ADC3.DataAlign=ADC_DATAALIGN_RIGHT ADC3.DiscontinuousConvMode=DISABLE ADC3.EOCSelection=ADC_EOC_SINGLE_CONV ADC3.EnableAnalogWatchDog=false -ADC3.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE +ADC3.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T8_TRGO +ADC3.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_RISING ADC3.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_T1_CC4 ADC3.ExternalTrigInjecConvEdge=ADC_EXTERNALTRIGINJECCONVEDGE_RISING -ADC3.IPParameters=Rank-7\#ChannelRegularConversion,Channel-7\#ChannelRegularConversion,SamplingTime-7\#ChannelRegularConversion,NbrOfConversionFlag,ClockPrescaler,Resolution,DataAlign,ScanConvMode,ContinuousConvMode,DiscontinuousConvMode,DMAContinuousRequests,EOCSelection,NbrOfConversion,ExternalTrigConvEdge,InjNumberOfConversion,EnableAnalogWatchDog,Rank-8\#ChannelInjectedConversion,Channel-8\#ChannelInjectedConversion,SamplingTime-8\#ChannelInjectedConversion,InjectedOffset-8\#ChannelInjectedConversion,ExternalTrigInjecConvEdge,InjectedConvMode,ExternalTrigInjecConv +ADC3.IPParameters=Rank-7\#ChannelRegularConversion,Channel-7\#ChannelRegularConversion,SamplingTime-7\#ChannelRegularConversion,NbrOfConversionFlag,ClockPrescaler,Resolution,DataAlign,ScanConvMode,ContinuousConvMode,DiscontinuousConvMode,DMAContinuousRequests,EOCSelection,NbrOfConversion,ExternalTrigConvEdge,InjNumberOfConversion,EnableAnalogWatchDog,Rank-8\#ChannelInjectedConversion,Channel-8\#ChannelInjectedConversion,SamplingTime-8\#ChannelInjectedConversion,InjectedOffset-8\#ChannelInjectedConversion,ExternalTrigInjecConvEdge,InjectedConvMode,ExternalTrigInjecConv,ExternalTrigConv ADC3.InjNumberOfConversion=1 ADC3.InjectedConvMode=None ADC3.InjectedOffset-8\#ChannelInjectedConversion=0 diff --git a/Src/adc.c b/Src/adc.c index 717e3c37..0821a2d7 100644 --- a/Src/adc.c +++ b/Src/adc.c @@ -120,7 +120,8 @@ void MX_ADC2_Init(void) hadc2.Init.ScanConvMode = DISABLE; hadc2.Init.ContinuousConvMode = DISABLE; hadc2.Init.DiscontinuousConvMode = DISABLE; - hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; + hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; + hadc2.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T8_TRGO; hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc2.Init.NbrOfConversion = 1; hadc2.Init.DMAContinuousRequests = DISABLE; @@ -171,7 +172,8 @@ void MX_ADC3_Init(void) hadc3.Init.ScanConvMode = DISABLE; hadc3.Init.ContinuousConvMode = DISABLE; hadc3.Init.DiscontinuousConvMode = DISABLE; - hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; + hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; + hadc3.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T8_TRGO; hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc3.Init.NbrOfConversion = 1; hadc3.Init.DMAContinuousRequests = DISABLE; diff --git a/Src/stm32f4xx_it.c b/Src/stm32f4xx_it.c index 00e77c76..b4cc0af9 100644 --- a/Src/stm32f4xx_it.c +++ b/Src/stm32f4xx_it.c @@ -194,14 +194,21 @@ void ADC_IRQHandler(void) /* USER CODE BEGIN 1 */ void ADC_IRQ_Dispatch(ADC_HandleTypeDef* hadc, ADC_handler_t callback) { - //Only handles injected measurements - //@TODO Add regular measurements too (requried for M1 update trigger) + + // Injected measurements uint32_t JEOC = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC); uint32_t JEOC_IT_EN = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_JEOC); if (JEOC && JEOC_IT_EN) { callback(hadc); __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JSTRT | ADC_FLAG_JEOC)); } + // Regular measurements + uint32_t EOC = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC); + uint32_t EOC_IT_EN = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_EOC); + if (EOC && EOC_IT_EN) { + callback(hadc); + __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_STRT | ADC_FLAG_EOC)); + } } /* USER CODE END 1 */