22#include " ../../../drivers/hardware_api.h"
33#include " ../../../drivers/hardware_specific/esp32/esp32_driver_mcpwm.h"
44
5- #if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && !defined(SIMPLEFOC_ESP32_USELEDC)
5+ #if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && !defined(SIMPLEFOC_ESP32_USELEDC) && 0
66
77#include " esp32_adc_driver.h"
88
9- #include " driver/mcpwm_prelude .h"
9+ #include " driver/mcpwm .h"
1010#include " soc/mcpwm_reg.h"
1111#include " soc/mcpwm_struct.h"
12+
1213#include < soc/sens_reg.h>
1314#include < soc/sens_struct.h>
14- #include " esp_idf_version.h"
15-
16- // version check - this mcpwm driver is specific for ESP-IDF 5.x and arduino-esp32 3.x
17- #if ESP_IDF_VERSION_MAJOR < 5
18- #error SimpleFOC: ESP-IDF version 4 or lower detected. Please update to ESP-IDF 5.x and Arduino-esp32 3.0 (or higher)
19- #endif
2015
2116#define _ADC_VOLTAGE 3 .3f
2217#define _ADC_RESOLUTION 4095 .0f
2318
24- // set the pin 19 in high during the adc interrupt
25- // #define SIMPLEFOC_ESP32_INTERRUPT_DEBUG
2619
2720typedef struct ESP32MCPWMCurrentSenseParams {
2821 int pins[3 ];
2922 float adc_voltage_conv;
30- int adc_buffer[3 ] = {};
31- int buffer_index = 0 ;
32- int no_adc_channels = 0 ;
23+ mcpwm_unit_t mcpwm_unit;
24+ int buffer_index;
3325} ESP32MCPWMCurrentSenseParams;
3426
3527
@@ -44,8 +36,8 @@ float _readADCVoltageInline(const int pinA, const void* cs_params){
4436
4537// function reading an ADC value and returning the read voltage
4638void * _configureADCInline (const void * driver_params, const int pinA, const int pinB, const int pinC){
39+ _UNUSED (driver_params);
4740
48- SIMPLEFOC_DEBUG (" ESP32-CS: Configuring ADC inline" );
4941 if ( _isset (pinA) ) pinMode (pinA, INPUT);
5042 if ( _isset (pinB) ) pinMode (pinB, INPUT);
5143 if ( _isset (pinC) ) pinMode (pinC, INPUT);
@@ -59,15 +51,30 @@ void* _configureADCInline(const void* driver_params, const int pinA, const int p
5951}
6052
6153
54+
55+ /* *
56+ * Low side adc reading implementation
57+ */
58+
59+ static void IRAM_ATTR mcpwm0_isr_handler (void *);
60+ static void IRAM_ATTR mcpwm1_isr_handler (void *);
61+ byte currentState = 1 ;
62+ // two mcpwm units
63+ // - max 2 motors per mcpwm unit (6 adc channels)
64+ int adc_pins[2 ][6 ]={0 };
65+ int adc_pin_count[2 ]={0 };
66+ uint32_t adc_buffer[2 ][6 ]={0 };
67+ int adc_read_index[2 ]={0 };
68+
6269// function reading an ADC value and returning the read voltage
6370float _readADCVoltageLowSide (const int pin, const void * cs_params){
64- ESP32MCPWMCurrentSenseParams* p = (ESP32MCPWMCurrentSenseParams*)cs_params;
65- int no_channel = 0 ;
66- for ( int i= 0 ; i < 3 ; i++){
67- if (! _isset (p-> pins [i])) continue ;
68- if (pin == p-> pins [i]) // found in the buffer
69- return p-> adc_buffer [no_channel] * p-> adc_voltage_conv ;
70- else no_channel++ ;
71+ mcpwm_unit_t unit = (( ESP32MCPWMCurrentSenseParams*)cs_params)-> mcpwm_unit ;
72+ int buffer_index = ((ESP32MCPWMCurrentSenseParams*)cs_params)-> buffer_index ;
73+ float adc_voltage_conv = ((ESP32MCPWMCurrentSenseParams*)cs_params)-> adc_voltage_conv ;
74+
75+ for ( int i= 0 ; i < adc_pin_count[unit]; i++){
76+ if ( pin == ((ESP32MCPWMCurrentSenseParams*)cs_params)-> pins [i]) // found in the buffer
77+ return adc_buffer[unit][buffer_index + i] * adc_voltage_conv ;
7178 }
7279 // not found
7380 return 0 ;
@@ -76,68 +83,83 @@ float _readADCVoltageLowSide(const int pin, const void* cs_params){
7683// function configuring low-side current sensing
7784void * _configureADCLowSide (const void * driver_params, const int pinA,const int pinB,const int pinC){
7885
79- SIMPLEFOC_DEBUG (" ESP32-CS: Configuring ADC low-side" );
80- // check if driver timer is already running
81- // fail if it is
82- // the easiest way that I've found to check if timer is running
83- // is to start it and stop it
84- ESP32MCPWMDriverParams *p = (ESP32MCPWMDriverParams*)driver_params;
85- if (mcpwm_timer_start_stop (p->timers [0 ], MCPWM_TIMER_START_NO_STOP) != ESP_ERR_INVALID_STATE){
86- // if we get the invalid state error it means that the timer is not enabled
87- // that means that we can configure it for low-side current sensing
88- SIMPLEFOC_DEBUG (" ESP32-CS: ERR - The timer is already enabled. Cannot be configured for low-side current sensing." );
89- return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;
90- }
86+ mcpwm_unit_t unit = ((ESP32MCPWMDriverParams*)driver_params)->mcpwm_unit ;
87+ int index_start = adc_pin_count[unit];
88+ if ( _isset (pinA) ) adc_pins[unit][adc_pin_count[unit]++] = pinA;
89+ if ( _isset (pinB) ) adc_pins[unit][adc_pin_count[unit]++] = pinB;
90+ if ( _isset (pinC) ) adc_pins[unit][adc_pin_count[unit]++] = pinC;
9191
92+ if ( _isset (pinA) ) pinMode (pinA, INPUT);
93+ if ( _isset (pinB) ) pinMode (pinB, INPUT);
94+ if ( _isset (pinC) ) pinMode (pinC, INPUT);
9295
93- ESP32MCPWMCurrentSenseParams* params = new ESP32MCPWMCurrentSenseParams{};
94- int no_adc_channels = 0 ;
95- if ( _isset (pinA) ){
96- pinMode (pinA, INPUT);
97- params->pins [no_adc_channels++] = pinA;
98- }
99- if ( _isset (pinB) ){
100- pinMode (pinB, INPUT);
101- params->pins [no_adc_channels++] = pinB;
102- }
103- if ( _isset (pinC) ){
104- pinMode (pinC, INPUT);
105- params->pins [no_adc_channels++] = pinC;
106- }
96+ ESP32MCPWMCurrentSenseParams* params = new ESP32MCPWMCurrentSenseParams {
97+ .pins = { pinA, pinB, pinC },
98+ .adc_voltage_conv = (_ADC_VOLTAGE)/(_ADC_RESOLUTION),
99+ .mcpwm_unit = unit,
100+ .buffer_index = index_start
101+ };
107102
108- params->adc_voltage_conv = (_ADC_VOLTAGE)/(_ADC_RESOLUTION);
109- params->no_adc_channels = no_adc_channels;
110103 return params;
111104}
112105
113106
114107void _driverSyncLowSide (void * driver_params, void * cs_params){
115- #ifdef SIMPLEFOC_ESP32_INTERRUPT_DEBUG
116- pinMode (19 , OUTPUT);
117- #endif
118- ESP32MCPWMDriverParams *p = (ESP32MCPWMDriverParams*)driver_params;
108+
109+ mcpwm_dev_t * mcpwm_dev = ((ESP32MCPWMDriverParams*)driver_params)->mcpwm_dev ;
110+ mcpwm_unit_t mcpwm_unit = ((ESP32MCPWMDriverParams*)driver_params)->mcpwm_unit ;
111+
112+ // low-side register enable interrupt
113+ mcpwm_dev->int_ena .timer0_tep_int_ena = true ;// A PWM timer 0 TEP event will trigger this interrupt
114+ // high side registers enable interrupt
115+ // mcpwm_dev->int_ena.timer0_tep_int_ena = true;//A PWM timer 0 TEZ event will trigger this interrupt
116+
117+ // register interrupts (mcpwm number, interrupt handler, handler argument = NULL, interrupt signal/flag, return handler = NULL)
118+ if (mcpwm_unit == MCPWM_UNIT_0)
119+ mcpwm_isr_register (mcpwm_unit, mcpwm0_isr_handler, NULL , ESP_INTR_FLAG_IRAM, NULL ); // Set ISR Handler
120+ else
121+ mcpwm_isr_register (mcpwm_unit, mcpwm1_isr_handler, NULL , ESP_INTR_FLAG_IRAM, NULL ); // Set ISR Handler
122+ }
123+
124+ static void IRAM_ATTR mcpwm0_isr_handler (void *) __attribute__ ((unused));
125+
126+ // Read currents when interrupt is triggered
127+ static void IRAM_ATTR mcpwm0_isr_handler (void *){
128+ // // high side
129+ // uint32_t mcpwm_intr_status = MCPWM0.int_st.timer0_tez_int_st;
119130
120- mcpwm_timer_event_callbacks_t cbs_timer = {
121- .on_full = [](mcpwm_timer_handle_t tim, const mcpwm_timer_event_data_t * edata, void * user_data){
122- ESP32MCPWMCurrentSenseParams *p = (ESP32MCPWMCurrentSenseParams*)user_data;
123- #ifdef SIMPLEFOC_ESP32_INTERRUPT_DEBUG
124- digitalWrite (19 , HIGH);
125- #endif
126- // increment buffer index
127- p->buffer_index = (p->buffer_index + 1 ) % p->no_adc_channels ;
128- // sample the phase currents one at a time
129- p->adc_buffer [p->buffer_index ] = adcRead (p->pins [p->buffer_index ]);
130- #ifdef SIMPLEFOC_ESP32_INTERRUPT_DEBUG
131- digitalWrite (19 , LOW);
132- #endif
133- return true ;
134- }
135- };
136- if (mcpwm_timer_register_event_callbacks (p->timers [0 ], &cbs_timer, cs_params) != ESP_OK){
137- SIMPLEFOC_DEBUG (" ESP32-CS: ERR - Failed to sync ADC and driver" );
138- }
131+ // low side
132+ uint32_t mcpwm_intr_status = MCPWM0.int_st .timer0_tep_int_st ;
133+ if (mcpwm_intr_status){
134+ adc_buffer[0 ][adc_read_index[0 ]] = adcRead (adc_pins[0 ][adc_read_index[0 ]]);
135+ adc_read_index[0 ]++;
136+ if (adc_read_index[0 ] == adc_pin_count[0 ]) adc_read_index[0 ] = 0 ;
137+ }
138+ // low side
139+ MCPWM0.int_clr .timer0_tep_int_clr = mcpwm_intr_status;
140+ // high side
141+ // MCPWM0.int_clr.timer0_tez_int_clr = mcpwm_intr_status_0;
139142}
140143
144+ static void IRAM_ATTR mcpwm1_isr_handler (void *) __attribute__ ((unused));
145+
146+ // Read currents when interrupt is triggered
147+ static void IRAM_ATTR mcpwm1_isr_handler (void *){
148+ // // high side
149+ // uint32_t mcpwm_intr_status = MCPWM1.int_st.timer0_tez_int_st;
150+
151+ // low side
152+ uint32_t mcpwm_intr_status = MCPWM1.int_st .timer0_tep_int_st ;
153+ if (mcpwm_intr_status){
154+ adc_buffer[1 ][adc_read_index[1 ]] = adcRead (adc_pins[1 ][adc_read_index[1 ]]);
155+ adc_read_index[1 ]++;
156+ if (adc_read_index[1 ] == adc_pin_count[1 ]) adc_read_index[1 ] = 0 ;
157+ }
158+ // low side
159+ MCPWM1.int_clr .timer0_tep_int_clr = mcpwm_intr_status;
160+ // high side
161+ // MCPWM1.int_clr.timer0_tez_int_clr = mcpwm_intr_status_0;
162+ }
141163
142164
143165#endif
0 commit comments