Skip to content

Use interrupt if no repetition counter #383

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,6 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
HAL_ADCEx_InjectedConfigChannel(&hadc, &sConfigInjected);
}

#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
// enable interrupt
HAL_NVIC_SetPriority(ADC1_2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
#endif

cs_params->adc_handle = &hadc;

return 0;
Expand All @@ -153,14 +147,11 @@ void _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const in

}

#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
extern "C" {
void ADC1_2_IRQHandler(void)
{
HAL_ADC_IRQHandler(&hadc);
}

}
#endif

#endif
38 changes: 27 additions & 11 deletions src/current_sense/hardware_specific/stm32/stm32f1/stm32f1_mcu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ bool needs_downsample[3] = {1};
// downsampling variable - per adc (3)
uint8_t tim_downsample[3] = {0};

#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
uint8_t use_adc_interrupt = 1;
#else
uint8_t use_adc_interrupt = 0;
#endif

int _adcToIndex(ADC_HandleTypeDef *AdcHandle){
if(AdcHandle->Instance == ADC1) return 0;
#ifdef ADC2 // if ADC2 exists
Expand Down Expand Up @@ -63,19 +69,31 @@ void _driverSyncLowSide(void* _driver_params, void* _cs_params){
cs_params->timer_handle->getHandle()->Instance->CNT = cs_params->timer_handle->getHandle()->Instance->ARR;
// remember that this timer has repetition counter - no need to downasmple
needs_downsample[_adcToIndex(cs_params->adc_handle)] = 0;
}else{
if(!use_adc_interrupt){
// If the timer has no repetition counter, it needs to use the interrupt to downsample for low side sensing
use_adc_interrupt = 1;
#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-CS: timer has no repetition counter, ADC interrupt has to be used");
#endif
}
}
// set the trigger output event
LL_TIM_SetTriggerOutput(cs_params->timer_handle->getHandle()->Instance, LL_TIM_TRGO_UPDATE);

// Start the adc calibration
HAL_ADCEx_Calibration_Start(cs_params->adc_handle);

// start the adc
#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
HAL_ADCEx_InjectedStart_IT(cs_params->adc_handle);
#else
HAL_ADCEx_InjectedStart(cs_params->adc_handle);
#endif
if(use_adc_interrupt){
HAL_NVIC_SetPriority(ADC1_2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC1_2_IRQn);

HAL_ADCEx_InjectedStart_IT(cs_params->adc_handle);
}else{
HAL_ADCEx_InjectedStart(cs_params->adc_handle);
}


// restart all the timers of the driver
_startTimers(driver_params->timers, 6);
Expand All @@ -86,19 +104,18 @@ void _driverSyncLowSide(void* _driver_params, void* _cs_params){
float _readADCVoltageLowSide(const int pin, const void* cs_params){
for(int i=0; i < 3; i++){
if( pin == ((Stm32CurrentSenseParams*)cs_params)->pins[i]){ // found in the buffer
#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
if (use_adc_interrupt){
return adc_val[_adcToIndex(((Stm32CurrentSenseParams*)cs_params)->adc_handle)][i] * ((Stm32CurrentSenseParams*)cs_params)->adc_voltage_conv;
#else
}else{
// an optimized way to go from i to the channel i=0 -> channel 1, i=1 -> channel 2, i=2 -> channel 3
uint32_t channel = (i == 0) ? ADC_INJECTED_RANK_1 : (i == 1) ? ADC_INJECTED_RANK_2 : ADC_INJECTED_RANK_3;;
return HAL_ADCEx_InjectedGetValue(((Stm32CurrentSenseParams*)cs_params)->adc_handle, channel) * ((Stm32CurrentSenseParams*)cs_params)->adc_voltage_conv;
#endif
}
}
}
return 0;
}

#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
extern "C" {
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *AdcHandle){
// calculate the instance
Expand All @@ -115,6 +132,5 @@ extern "C" {
adc_val[adc_index][2]=HAL_ADCEx_InjectedGetValue(AdcHandle, ADC_INJECTED_RANK_3);
}
}
#endif

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,6 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
}
}

#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
// enable interrupt
HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC_IRQn);
#endif

cs_params->adc_handle = &hadc;
return 0;
}
Expand All @@ -162,13 +156,11 @@ void _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const in
}
}

#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
extern "C" {
void ADC_IRQHandler(void)
{
HAL_ADC_IRQHandler(&hadc);
}
}
#endif

#endif
36 changes: 26 additions & 10 deletions src/current_sense/hardware_specific/stm32/stm32f4/stm32f4_mcu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ bool needs_downsample[3] = {1};
// downsampling variable - per adc (3)
uint8_t tim_downsample[3] = {0};

#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
uint8_t use_adc_interrupt = 1;
#else
uint8_t use_adc_interrupt = 0;
#endif

void* _configureADCLowSide(const void* driver_params, const int pinA, const int pinB, const int pinC){

Stm32CurrentSenseParams* cs_params= new Stm32CurrentSenseParams {
Expand Down Expand Up @@ -55,16 +61,28 @@ void _driverSyncLowSide(void* _driver_params, void* _cs_params){
cs_params->timer_handle->getHandle()->Instance->CNT = cs_params->timer_handle->getHandle()->Instance->ARR;
// remember that this timer has repetition counter - no need to downasmple
needs_downsample[_adcToIndex(cs_params->adc_handle)] = 0;
}else{
if(!use_adc_interrupt){
// If the timer has no repetition counter, it needs to use the interrupt to downsample for low side sensing
use_adc_interrupt = 1;
#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-CS: timer has no repetition counter, ADC interrupt has to be used");
#endif
}
}
// set the trigger output event
LL_TIM_SetTriggerOutput(cs_params->timer_handle->getHandle()->Instance, LL_TIM_TRGO_UPDATE);

// start the adc
#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
HAL_ADCEx_InjectedStart_IT(cs_params->adc_handle);
#else
HAL_ADCEx_InjectedStart(cs_params->adc_handle);
#endif
if (use_adc_interrupt){
// enable interrupt
HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC_IRQn);

HAL_ADCEx_InjectedStart_IT(cs_params->adc_handle);
}else{
HAL_ADCEx_InjectedStart(cs_params->adc_handle);
}

// restart all the timers of the driver
_startTimers(driver_params->timers, 6);
Expand All @@ -75,19 +93,18 @@ void _driverSyncLowSide(void* _driver_params, void* _cs_params){
float _readADCVoltageLowSide(const int pin, const void* cs_params){
for(int i=0; i < 3; i++){
if( pin == ((Stm32CurrentSenseParams*)cs_params)->pins[i]){ // found in the buffer
#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
if (use_adc_interrupt){
return adc_val[_adcToIndex(((Stm32CurrentSenseParams*)cs_params)->adc_handle)][i] * ((Stm32CurrentSenseParams*)cs_params)->adc_voltage_conv;
#else
}else{
// an optimized way to go from i to the channel i=0 -> channel 1, i=1 -> channel 2, i=2 -> channel 3
uint32_t channel = (i == 0) ? ADC_INJECTED_RANK_1 : (i == 1) ? ADC_INJECTED_RANK_2 : ADC_INJECTED_RANK_3;
return HAL_ADCEx_InjectedGetValue(((Stm32CurrentSenseParams*)cs_params)->adc_handle, channel) * ((Stm32CurrentSenseParams*)cs_params)->adc_voltage_conv;
#endif
}
}
}
return 0;
}

#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
extern "C" {
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *AdcHandle){
// calculate the instance
Expand All @@ -104,6 +121,5 @@ extern "C" {
adc_val[adc_index][2]=HAL_ADCEx_InjectedGetValue(AdcHandle, ADC_INJECTED_RANK_3);
}
}
#endif

#endif
39 changes: 0 additions & 39 deletions src/current_sense/hardware_specific/stm32/stm32g4/stm32g4_hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,43 +180,6 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
}
}


#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
if(hadc.Instance == ADC1) {
// enable interrupt
HAL_NVIC_SetPriority(ADC1_2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
}
#ifdef ADC2
else if (hadc.Instance == ADC2) {
// enable interrupt
HAL_NVIC_SetPriority(ADC1_2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
}
#endif
#ifdef ADC3
else if (hadc.Instance == ADC3) {
// enable interrupt
HAL_NVIC_SetPriority(ADC3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC3_IRQn);
}
#endif
#ifdef ADC4
else if (hadc.Instance == ADC4) {
// enable interrupt
HAL_NVIC_SetPriority(ADC4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC4_IRQn);
}
#endif
#ifdef ADC5
else if (hadc.Instance == ADC5) {
// enable interrupt
HAL_NVIC_SetPriority(ADC5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC5_IRQn);
}
#endif
#endif

cs_params->adc_handle = &hadc;
return 0;
}
Expand All @@ -238,7 +201,6 @@ void _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const in
}
}

#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
extern "C" {
void ADC1_2_IRQHandler(void)
{
Expand All @@ -265,6 +227,5 @@ extern "C" {
}
#endif
}
#endif

#endif
68 changes: 57 additions & 11 deletions src/current_sense/hardware_specific/stm32/stm32g4/stm32g4_mcu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ bool needs_downsample[5] = {1};
// downsampling variable - per adc (5)
uint8_t tim_downsample[5] = {0};

#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
uint8_t use_adc_interrupt = 1;
#else
uint8_t use_adc_interrupt = 0;
#endif

void* _configureADCLowSide(const void* driver_params, const int pinA, const int pinB, const int pinC){

Expand Down Expand Up @@ -58,6 +63,14 @@ void _driverSyncLowSide(void* _driver_params, void* _cs_params){
cs_params->timer_handle->getHandle()->Instance->CNT = cs_params->timer_handle->getHandle()->Instance->ARR;
// remember that this timer has repetition counter - no need to downasmple
needs_downsample[_adcToIndex(cs_params->adc_handle)] = 0;
}else{
if(!use_adc_interrupt){
// If the timer has no repetition counter, it needs to use the interrupt to downsample for low side sensing
use_adc_interrupt = 1;
#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-CS: timer has no repetition counter, ADC interrupt has to be used");
#endif
}
}

// set the trigger output event
Expand All @@ -66,12 +79,47 @@ void _driverSyncLowSide(void* _driver_params, void* _cs_params){
// Start the adc calibration
HAL_ADCEx_Calibration_Start(cs_params->adc_handle,ADC_SINGLE_ENDED);

// start the adc
#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
HAL_ADCEx_InjectedStart_IT(cs_params->adc_handle);
#else
HAL_ADCEx_InjectedStart(cs_params->adc_handle);
#endif
// start the adc
if (use_adc_interrupt){
// enable interrupt
if(cs_params->adc_handle->Instance == ADC1) {
// enable interrupt
HAL_NVIC_SetPriority(ADC1_2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
}
#ifdef ADC2
else if (cs_params->adc_handle->Instance == ADC2) {
// enable interrupt
HAL_NVIC_SetPriority(ADC1_2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
}
#endif
#ifdef ADC3
else if (cs_params->adc_handle->Instance == ADC3) {
// enable interrupt
HAL_NVIC_SetPriority(ADC3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC3_IRQn);
}
#endif
#ifdef ADC4
else if (cs_params->adc_handle->Instance == ADC4) {
// enable interrupt
HAL_NVIC_SetPriority(ADC4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC4_IRQn);
}
#endif
#ifdef ADC5
else if (cs_params->adc_handle->Instance == ADC5) {
// enable interrupt
HAL_NVIC_SetPriority(ADC5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC5_IRQn);
}
#endif

HAL_ADCEx_InjectedStart_IT(cs_params->adc_handle);
}else{
HAL_ADCEx_InjectedStart(cs_params->adc_handle);
}

// restart all the timers of the driver
_startTimers(driver_params->timers, 6);
Expand All @@ -82,19 +130,18 @@ void _driverSyncLowSide(void* _driver_params, void* _cs_params){
float _readADCVoltageLowSide(const int pin, const void* cs_params){
for(int i=0; i < 3; i++){
if( pin == ((Stm32CurrentSenseParams*)cs_params)->pins[i]){ // found in the buffer
#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
if (use_adc_interrupt){
return adc_val[_adcToIndex(((Stm32CurrentSenseParams*)cs_params)->adc_handle)][i] * ((Stm32CurrentSenseParams*)cs_params)->adc_voltage_conv;
#else
}else{
// an optimized way to go from i to the channel i=0 -> channel 1, i=1 -> channel 2, i=2 -> channel 3
uint32_t channel = (i == 0) ? ADC_INJECTED_RANK_1 : (i == 1) ? ADC_INJECTED_RANK_2 : ADC_INJECTED_RANK_3;
return HAL_ADCEx_InjectedGetValue(((Stm32CurrentSenseParams*)cs_params)->adc_handle, channel) * ((Stm32CurrentSenseParams*)cs_params)->adc_voltage_conv;
#endif
}
}
}
return 0;
}

#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
extern "C" {
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *AdcHandle){
// calculate the instance
Expand All @@ -111,6 +158,5 @@ extern "C" {
adc_val[adc_index][2]=HAL_ADCEx_InjectedGetValue(AdcHandle, ADC_INJECTED_RANK_3);
}
}
#endif

#endif
Loading