From 1c711e71dc9e45987f460c3633c076aa709e563a Mon Sep 17 00:00:00 2001 From: matei jordache Date: Sun, 12 Nov 2023 15:38:01 -0500 Subject: [PATCH] get ADC trigger working --- .../src/common/base_classes/FOCDriver.h | 2 +- firmware/lib/currentsense/adc.cpp | 44 +++++++------------ firmware/lib/currentsense/utils.cpp | 13 +++++- 3 files changed, 29 insertions(+), 30 deletions(-) diff --git a/firmware/lib/Arduino-FOC/src/common/base_classes/FOCDriver.h b/firmware/lib/Arduino-FOC/src/common/base_classes/FOCDriver.h index 7994134..7a60c4b 100644 --- a/firmware/lib/Arduino-FOC/src/common/base_classes/FOCDriver.h +++ b/firmware/lib/Arduino-FOC/src/common/base_classes/FOCDriver.h @@ -12,7 +12,7 @@ class FOCDriver{ virtual void disable() = 0; - virtual void setPwm(float a, float b, float c); + virtual void setPwm(float a, float b, float c) = 0; // virtual void setPwm(uint8_t a, uint8_t b); long pwm_frequency; diff --git a/firmware/lib/currentsense/adc.cpp b/firmware/lib/currentsense/adc.cpp index cf9aea3..6195155 100644 --- a/firmware/lib/currentsense/adc.cpp +++ b/firmware/lib/currentsense/adc.cpp @@ -23,7 +23,7 @@ void MX_ADC1_Init(void) hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.NbrOfConversion = 1; hadc1.Init.DiscontinuousConvMode = DISABLE; - hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T3_TRGO; + hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T2_TRGO; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; hadc1.Init.DMAContinuousRequests = ENABLE; hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED; @@ -65,7 +65,7 @@ void MX_ADC2_Init(void) hadc2.Init.ContinuousConvMode = DISABLE; hadc2.Init.NbrOfConversion = 2; hadc2.Init.DiscontinuousConvMode = DISABLE; - hadc2.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T3_TRGO; + hadc2.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T2_TRGO; hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; hadc2.Init.DMAContinuousRequests = ENABLE; hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED; @@ -92,20 +92,21 @@ void ADC_DMA_Init(ADC_HandleTypeDef* adcHandle) { RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC12; + PeriphClkInit.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } + + HAL_RCC_ADC12_CLK_ENABLED++; + if(HAL_RCC_ADC12_CLK_ENABLED==1){ + __HAL_RCC_ADC12_CLK_ENABLE(); + } + if(adcHandle->Instance==ADC1) { - PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC12; - PeriphClkInit.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) - { - Error_Handler(); - } - - HAL_RCC_ADC12_CLK_ENABLED++; - if(HAL_RCC_ADC12_CLK_ENABLED==1){ - __HAL_RCC_ADC12_CLK_ENABLE(); - } - /* ADC1 DMA Init */ /* ADC1 Init */ hdma_adc1.Instance = DMA1_Channel1; @@ -115,8 +116,9 @@ void ADC_DMA_Init(ADC_HandleTypeDef* adcHandle) hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; - hdma_adc1.Init.Mode = DMA_NORMAL; + hdma_adc1.Init.Mode = DMA_CIRCULAR; hdma_adc1.Init.Priority = DMA_PRIORITY_LOW; + HAL_DMA_DeInit(&hdma_adc1); if (HAL_DMA_Init(&hdma_adc1) != HAL_OK) { Error_Handler(); @@ -126,18 +128,6 @@ void ADC_DMA_Init(ADC_HandleTypeDef* adcHandle) } else if(adcHandle->Instance==ADC2) { - PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC12; - PeriphClkInit.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) - { - Error_Handler(); - } - - HAL_RCC_ADC12_CLK_ENABLED++; - if(HAL_RCC_ADC12_CLK_ENABLED==1){ - __HAL_RCC_ADC12_CLK_ENABLE(); - } - /* ADC2 DMA Init */ /* ADC2 Init */ hdma_adc2.Instance = DMA1_Channel2; diff --git a/firmware/lib/currentsense/utils.cpp b/firmware/lib/currentsense/utils.cpp index 0142b5f..ef71e24 100644 --- a/firmware/lib/currentsense/utils.cpp +++ b/firmware/lib/currentsense/utils.cpp @@ -115,12 +115,21 @@ void _driverSyncLowSide(void *_driver_params, void *_cs_params) _stopTimers(driver_params->timers, 6); // See RM0440 pg. 1169 - // This grabs the timer handle used for ADC and sets the direction bit as upcounting (?) + // Grab the timer handle used for ADC and sets the direction bit as upcounting cs_params->timer_handle->getHandle()->Instance->CR1 |= TIM_CR1_DIR; - // This sets the value of the timer to the reload value. I think this is so that an event is immediately fired + /** Set the value of the timer to the reload value, so that overflow event is generated immediately. + * This is because we are using repetition counter to count every other event, skipping the underflow at + * valleys of PWM. We can downsample every other peak if repetition counter is increased to 3 + */ cs_params->timer_handle->getHandle()->Instance->CNT = cs_params->timer_handle->getHandle()->Instance->ARR; + // Set TIM_CR1_URS to 0b1 -> only update events are overflows/underflow + cs_params->timer_handle->getHandle()->Instance->CR1 |= 0x0004; + + // Set TIM_CR2_MMS to 0b010 -> update event (overflow and underflow) mapped to tim2_trgo + cs_params->timer_handle->getHandle()->Instance->CR2 |= 0x0020; + _startTimers(driver_params->timers, 6); }