Skip to content

Commit

Permalink
use current sensing only if mpcpwm used and force LEDC for now
Browse files Browse the repository at this point in the history
  • Loading branch information
askuric committed Jun 7, 2024
1 parent 83b606b commit 93bcfe0
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 57 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "esp32_adc_driver.h"

#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32S3)
#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32S3) && !defined(SIMPLEFOC_ESP32_USELEDC)

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#include "Arduino.h"

#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED)
#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && !defined(SIMPLEFOC_ESP32_USELEDC)
/*
* Get ADC value for pin
* */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "../../hardware_api.h"
#include "../../../drivers/hardware_api.h"

#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && !defined(SOC_MCPWM_SUPPORTED)
#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && (!defined(SOC_MCPWM_SUPPORTED) || defined(SIMPLEFOC_ESP32_USELEDC))

#include "esp32_adc_driver.h"

Expand Down
2 changes: 1 addition & 1 deletion src/current_sense/hardware_specific/esp32/esp32_mcu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "../../../drivers/hardware_api.h"
#include "../../../drivers/hardware_specific/esp32/esp32_driver_mcpwm.h"

#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && !defined(SIMPLEFOC_ESP32_USELEDC)
#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && !defined(SIMPLEFOC_ESP32_USELEDC)

#include "esp32_adc_driver.h"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "esp32_adc_driver.h"

#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && (defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3))
#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && (defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)) && !defined(SIMPLEFOC_ESP32_USELEDC)

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
Expand Down
1 change: 1 addition & 0 deletions src/drivers/hardware_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@



#define SIMPLEFOC_ESP32_USELEDC

// flag returned if driver init fails
#define SIMPLEFOC_DRIVER_INIT_FAILED ((void*)-1)
Expand Down
109 changes: 57 additions & 52 deletions src/drivers/hardware_specific/esp32/esp32_ledc_mcu.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
#include "../../hardware_api.h"

/*
For the moment the LEDC driver implements the simplest possible way to set the PWM on esp32 while enabling to set the frequency and resolution.
The pwm is not center aligned and moreover there are no guarantees on the proper alignement between the PWM signals.
Therefore this driver is not recommended for boards that have MCPWM.
There are however ways to improve the LEDC driver, by not using directly espressif sdk:
https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/ledc.html#ledc-api-change-pwm-signal
- We could potentially use the ledc_set_duty_with_hpoint function to set the duty cycle and the high time point to make the signals center-aligned
- We could force the use of the same ledc timer within one driver to ensure the alignement between the signals
*/

#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && ( !defined(SOC_MCPWM_SUPPORTED) || defined(SIMPLEFOC_ESP32_USELEDC) )

#pragma message("")
Expand All @@ -11,14 +24,10 @@
#define _PWM_FREQUENCY 25000 // 25khz
#define _PWM_FREQUENCY_MAX 38000 // 38khz max to be able to have 10 bit pwm resolution
#define _PWM_RES_BIT 10 // 10 bir resolution
#define _PWM_RES 1023 // 2^10-1 = 1023-1
#define _PWM_RES 1023 // 2^10-1 = 1024-1


// empty motor slot
#define _EMPTY_SLOT -20
#define _TAKEN_SLOT -21

// figure out how many ledc channels are avaible
// figure out how many ledc channels are available
// esp32 - 2x8=16
// esp32s2 - 8
// esp32c3 - 6
Expand All @@ -30,18 +39,16 @@
#endif


// current channel stack index
// currently used ledc channels
// support for multiple motors
// esp32 has 16 channels
// esp32s2 has 8 channels
// esp32c3 has 6 channels
int channel_index = 0;


int channels_used = 0;


typedef struct ESP32LEDCDriverParams {
int channels[6];
int pins[6];
long pwm_frequency;
} ESP32LEDCDriverParams;

Expand All @@ -50,9 +57,11 @@ typedef struct ESP32LEDCDriverParams {


// configure High PWM frequency
void _setHighFrequency(const long freq, const int pin, const int channel){
ledcSetup(channel, freq, _PWM_RES_BIT );
ledcAttachPin(pin, channel);
bool _setHighFrequency(const long freq, const int pin){
// sets up the pwm resolution and frequency on this pin
// https://docs.espressif.com/projects/arduino-esp32/en/latest/api/ledc.html
// from v5.x no more need to deal with channels
return ledcAttach(pin, freq, _PWM_RES_BIT);
}


Expand All @@ -65,13 +74,14 @@ void* _configure1PWM(long pwm_frequency, const int pinA) {
else pwm_frequency = _constrain(pwm_frequency, 0, _PWM_FREQUENCY_MAX); // constrain to 50kHz max

// check if enough channels available
if ( channel_index + 1 >= LEDC_CHANNELS ) return SIMPLEFOC_DRIVER_INIT_FAILED;
if ( channels_used + 1 >= LEDC_CHANNELS ) return SIMPLEFOC_DRIVER_INIT_FAILED;
channels_used++;

int ch1 = channel_index++;
_setHighFrequency(pwm_frequency, pinA, ch1);
// setup the channel
if (!_setHighFrequency(pwm_frequency, pinA)) return SIMPLEFOC_DRIVER_INIT_FAILED;

ESP32LEDCDriverParams* params = new ESP32LEDCDriverParams {
.channels = { ch1 },
.pins = { pinA },
.pwm_frequency = pwm_frequency
};
return params;
Expand All @@ -89,15 +99,15 @@ void* _configure2PWM(long pwm_frequency, const int pinA, const int pinB) {
else pwm_frequency = _constrain(pwm_frequency, 0, _PWM_FREQUENCY_MAX); // constrain to 50kHz max

// check if enough channels available
if ( channel_index + 2 >= LEDC_CHANNELS ) return SIMPLEFOC_DRIVER_INIT_FAILED;
if ( channels_used + 2 >= LEDC_CHANNELS ) return SIMPLEFOC_DRIVER_INIT_FAILED;
channels_used += 2;

int ch1 = channel_index++;
int ch2 = channel_index++;
_setHighFrequency(pwm_frequency, pinA, ch1);
_setHighFrequency(pwm_frequency, pinB, ch2);
// setup the channels
if(!_setHighFrequency(pwm_frequency, pinA) || !_setHighFrequency(pwm_frequency, pinB))
return SIMPLEFOC_DRIVER_INIT_FAILED;

ESP32LEDCDriverParams* params = new ESP32LEDCDriverParams {
.channels = { ch1, ch2 },
.pins = { pinA, pinB },
.pwm_frequency = pwm_frequency
};
return params;
Expand All @@ -110,17 +120,15 @@ void* _configure3PWM(long pwm_frequency,const int pinA, const int pinB, const in
else pwm_frequency = _constrain(pwm_frequency, 0, _PWM_FREQUENCY_MAX); // constrain to 50kHz max

// check if enough channels available
if ( channel_index + 3 >= LEDC_CHANNELS ) return SIMPLEFOC_DRIVER_INIT_FAILED;
if ( channels_used + 3 >= LEDC_CHANNELS ) return SIMPLEFOC_DRIVER_INIT_FAILED;
channels_used += 3;

int ch1 = channel_index++;
int ch2 = channel_index++;
int ch3 = channel_index++;
_setHighFrequency(pwm_frequency, pinA, ch1);
_setHighFrequency(pwm_frequency, pinB, ch2);
_setHighFrequency(pwm_frequency, pinC, ch3);
// setup the channels
if(!_setHighFrequency(pwm_frequency, pinA) || !_setHighFrequency(pwm_frequency, pinB) || !_setHighFrequency(pwm_frequency, pinC))
return SIMPLEFOC_DRIVER_INIT_FAILED;

ESP32LEDCDriverParams* params = new ESP32LEDCDriverParams {
.channels = { ch1, ch2, ch3 },
.pins = { pinA, pinB, pinC },
.pwm_frequency = pwm_frequency
};
return params;
Expand All @@ -133,19 +141,16 @@ void* _configure4PWM(long pwm_frequency,const int pinA, const int pinB, const in
else pwm_frequency = _constrain(pwm_frequency, 0, _PWM_FREQUENCY_MAX); // constrain to 50kHz max

// check if enough channels available
if ( channel_index + 4 >= LEDC_CHANNELS ) return SIMPLEFOC_DRIVER_INIT_FAILED;
if ( channels_used + 4 >= LEDC_CHANNELS ) return SIMPLEFOC_DRIVER_INIT_FAILED;
channels_used += 4;

int ch1 = channel_index++;
int ch2 = channel_index++;
int ch3 = channel_index++;
int ch4 = channel_index++;
_setHighFrequency(pwm_frequency, pinA, ch1);
_setHighFrequency(pwm_frequency, pinB, ch2);
_setHighFrequency(pwm_frequency, pinC, ch3);
_setHighFrequency(pwm_frequency, pinD, ch4);
// setup the channels
if(!_setHighFrequency(pwm_frequency, pinA) || !_setHighFrequency(pwm_frequency, pinB) ||
!_setHighFrequency(pwm_frequency, pinC)|| !_setHighFrequency(pwm_frequency, pinD))
return SIMPLEFOC_DRIVER_INIT_FAILED;

ESP32LEDCDriverParams* params = new ESP32LEDCDriverParams {
.channels = { ch1, ch2, ch3, ch4 },
.pins = { pinA, pinB, pinC, pinD },
.pwm_frequency = pwm_frequency
};
return params;
Expand All @@ -155,31 +160,31 @@ void* _configure4PWM(long pwm_frequency,const int pinA, const int pinB, const in


void _writeDutyCycle1PWM(float dc_a, void* params){
ledcWrite(((ESP32LEDCDriverParams*)params)->channels[0], _constrain(_PWM_RES*dc_a, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->pins[0], _constrain(_PWM_RES*dc_a, 0, _PWM_RES));
}



void _writeDutyCycle2PWM(float dc_a, float dc_b, void* params){
ledcWrite(((ESP32LEDCDriverParams*)params)->channels[0], _constrain(_PWM_RES*dc_a, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->channels[1], _constrain(_PWM_RES*dc_b, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->pins[0], _constrain(_PWM_RES*dc_a, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->pins[1], _constrain(_PWM_RES*dc_b, 0, _PWM_RES));
}



void _writeDutyCycle3PWM(float dc_a, float dc_b, float dc_c, void* params){
ledcWrite(((ESP32LEDCDriverParams*)params)->channels[0], _constrain(_PWM_RES*dc_a, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->channels[1], _constrain(_PWM_RES*dc_b, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->channels[2], _constrain(_PWM_RES*dc_c, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->pins[0], _constrain(_PWM_RES*dc_a, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->pins[1], _constrain(_PWM_RES*dc_b, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->pins[2], _constrain(_PWM_RES*dc_c, 0, _PWM_RES));
}



void _writeDutyCycle4PWM(float dc_1a, float dc_1b, float dc_2a, float dc_2b, void* params){
ledcWrite(((ESP32LEDCDriverParams*)params)->channels[0], _constrain(_PWM_RES*dc_1a, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->channels[1], _constrain(_PWM_RES*dc_1b, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->channels[2], _constrain(_PWM_RES*dc_2a, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->channels[3], _constrain(_PWM_RES*dc_2b, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->pins[0], _constrain(_PWM_RES*dc_1a, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->pins[1], _constrain(_PWM_RES*dc_1b, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->pins[2], _constrain(_PWM_RES*dc_2a, 0, _PWM_RES));
ledcWrite(((ESP32LEDCDriverParams*)params)->pins[3], _constrain(_PWM_RES*dc_2b, 0, _PWM_RES));
}

#endif

0 comments on commit 93bcfe0

Please sign in to comment.