Skip to content

Commit 59468f4

Browse files
committed
Move the mcpwm on_full callback entry point to the IRAM.
It will ensure that all the ADC processing triggered by the MCPWM ISR can run if the ESP32 cache is disabled, preventing the application to crash. Signed-off-by: Felipe Neves <[email protected]>
1 parent 1520b63 commit 59468f4

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed

src/current_sense/hardware_specific/esp32/esp32_mcpwm_mcu.cpp

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939

4040
/**
41-
* Low side adc reading implementation
41+
* Low side adc reading implementation
4242
*/
4343

4444

@@ -58,12 +58,12 @@ float _readADCVoltageLowSide(const int pin, const void* cs_params){
5858
}
5959

6060

61-
// function configuring low-side current sensing
61+
// function configuring low-side current sensing
6262
void* _configureADCLowSide(const void* driver_params, const int pinA,const int pinB,const int pinC){
63-
// check if driver timer is already running
63+
// check if driver timer is already running
6464
// fail if it is
6565
// the easiest way that I've found to check if timer is running
66-
// is to start it and stop it
66+
// is to start it and stop it
6767
ESP32MCPWMDriverParams *p = (ESP32MCPWMDriverParams*)driver_params;
6868
mcpwm_timer_t* t = (mcpwm_timer_t*) p->timers[0];
6969

@@ -74,7 +74,7 @@ void* _configureADCLowSide(const void* driver_params, const int pinA,const int p
7474
return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;
7575
}
7676

77-
77+
7878
ESP32CurrentSenseParams* params = new ESP32CurrentSenseParams{};
7979
int no_adc_channels = 0;
8080

@@ -90,14 +90,31 @@ void* _configureADCLowSide(const void* driver_params, const int pinA,const int p
9090
params->pins[no_adc_channels++] = adc_pins[i];
9191
}
9292
}
93-
93+
9494
t->user_data = params;
9595
params->adc_voltage_conv = (_ADC_VOLTAGE)/(_ADC_RESOLUTION);
9696
params->no_adc_channels = no_adc_channels;
9797
return params;
9898
}
9999

100+
static IRAM_ATTR _mcpwmTriggerADCCallback(mcpwm_timer_handle_t tim, const mcpwm_timer_event_data_t* edata, void* user_data){
101+
ESP32CurrentSenseParams *p = (ESP32CurrentSenseParams*)user_data;
102+
#ifdef SIMPLEFOC_ESP32_INTERRUPT_DEBUG // debugging toggle pin to measure the time of the interrupt with oscilloscope
103+
gpio_set_level(GPIO_NUM,1); //cca 250ns for on+off
104+
#endif
100105

106+
// sample the phase currents one at a time
107+
// ESP's adc read takes around 10us which is very long
108+
// increment buffer index
109+
p->buffer_index = (p->buffer_index + 1) % p->no_adc_channels;
110+
// so we are sampling one phase per call
111+
p->adc_buffer[p->buffer_index] = adcRead(p->pins[p->buffer_index]);
112+
113+
#ifdef SIMPLEFOC_ESP32_INTERRUPT_DEBUG // debugging toggle pin to measure the time of the interrupt with oscilloscope
114+
gpio_set_level(GPIO_NUM,0); //cca 250ns for on+off
115+
#endif
116+
return true;
117+
}
101118

102119
void* _driverSyncLowSide(void* driver_params, void* cs_params){
103120
#ifdef SIMPLEFOC_ESP32_INTERRUPT_DEBUG
@@ -115,29 +132,12 @@ void* _driverSyncLowSide(void* driver_params, void* cs_params){
115132

116133
// set the callback for the low side current sensing
117134
// mcpwm_timer_event_callbacks_t can be used to set the callback
118-
// for three timer events
135+
// for three timer events
119136
// - on_full - low-side
120-
// - on_empty - high-side
137+
// - on_empty - high-side
121138
// - on_sync - sync event (not used with simplefoc)
122139
auto cbs = mcpwm_timer_event_callbacks_t{
123-
.on_full = [](mcpwm_timer_handle_t tim, const mcpwm_timer_event_data_t* edata, void* user_data){
124-
ESP32CurrentSenseParams *p = (ESP32CurrentSenseParams*)user_data;
125-
#ifdef SIMPLEFOC_ESP32_INTERRUPT_DEBUG // debugging toggle pin to measure the time of the interrupt with oscilloscope
126-
gpio_set_level(GPIO_NUM,1); //cca 250ns for on+off
127-
#endif
128-
129-
// sample the phase currents one at a time
130-
// ESP's adc read takes around 10us which is very long
131-
// increment buffer index
132-
p->buffer_index = (p->buffer_index + 1) % p->no_adc_channels;
133-
// so we are sampling one phase per call
134-
p->adc_buffer[p->buffer_index] = adcRead(p->pins[p->buffer_index]);
135-
136-
#ifdef SIMPLEFOC_ESP32_INTERRUPT_DEBUG // debugging toggle pin to measure the time of the interrupt with oscilloscope
137-
gpio_set_level(GPIO_NUM,0); //cca 250ns for on+off
138-
#endif
139-
return true;
140-
},
140+
.on_full = _mcpwmTriggerADCCallback,
141141
};
142142
SIMPLEFOC_ESP32_CS_DEBUG("Timer "+String(t->timer_id)+" enable interrupt callback.");
143143
// set the timer state to init (so that we can call the `mcpwm_timer_register_event_callbacks` )

0 commit comments

Comments
 (0)