2
2
#include " ../../../drivers/hardware_api.h"
3
3
#include " ../../../drivers/hardware_specific/esp32/esp32_driver_mcpwm.h"
4
4
5
- #if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && !defined(SIMPLEFOC_ESP32_USELEDC) && 0
5
+ #if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && !defined(SIMPLEFOC_ESP32_USELEDC)
6
6
7
- #include " esp32_adc_driver.h"
8
-
9
- #include " driver/mcpwm.h"
7
+ #include " driver/mcpwm_prelude.h"
10
8
#include " soc/mcpwm_reg.h"
11
9
#include " soc/mcpwm_struct.h"
12
-
13
10
#include < soc/sens_reg.h>
14
11
#include < soc/sens_struct.h>
15
12
16
13
#define _ADC_VOLTAGE 3 .3f
17
14
#define _ADC_RESOLUTION 4095 .0f
18
15
16
+ // set the pin 19 in high during the adc interrupt
17
+ // #define SIMPLEFOC_ESP32_INTERRUPT_DEBUG
19
18
20
19
typedef struct ESP32MCPWMCurrentSenseParams {
21
20
int pins[3 ];
22
21
float adc_voltage_conv;
23
- mcpwm_unit_t mcpwm_unit;
24
- int buffer_index;
22
+ int adc_buffer[3 ] = {};
23
+ int buffer_index = 0 ;
24
+ int no_adc_channels = 0 ;
25
25
} ESP32MCPWMCurrentSenseParams;
26
26
27
27
@@ -36,8 +36,8 @@ float _readADCVoltageInline(const int pinA, const void* cs_params){
36
36
37
37
// function reading an ADC value and returning the read voltage
38
38
void * _configureADCInline (const void * driver_params, const int pinA, const int pinB, const int pinC){
39
- _UNUSED (driver_params);
40
39
40
+ SIMPLEFOC_DEBUG (" ESP32-CS: Configuring ADC inline" );
41
41
if ( _isset (pinA) ) pinMode (pinA, INPUT);
42
42
if ( _isset (pinB) ) pinMode (pinB, INPUT);
43
43
if ( _isset (pinC) ) pinMode (pinC, INPUT);
@@ -51,30 +51,15 @@ void* _configureADCInline(const void* driver_params, const int pinA, const int p
51
51
}
52
52
53
53
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
-
69
54
// function reading an ADC value and returning the read voltage
70
55
float _readADCVoltageLowSide (const int pin, const void * cs_params){
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 ;
56
+ ESP32MCPWMCurrentSenseParams* p = (ESP32MCPWMCurrentSenseParams*)cs_params;
57
+ int no_channel = 0 ;
58
+ for ( int i= 0 ; i < 3 ; i++){
59
+ if (! _isset (p-> pins [i])) continue ;
60
+ if (pin == p-> pins [i]) // found in the buffer
61
+ return p-> adc_buffer [no_channel] * p-> adc_voltage_conv ;
62
+ else no_channel++ ;
78
63
}
79
64
// not found
80
65
return 0 ;
@@ -83,83 +68,68 @@ float _readADCVoltageLowSide(const int pin, const void* cs_params){
83
68
// function configuring low-side current sensing
84
69
void * _configureADCLowSide (const void * driver_params, const int pinA,const int pinB,const int pinC){
85
70
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;
71
+ SIMPLEFOC_DEBUG (" ESP32-CS: Configuring ADC low-side" );
72
+ // check if driver timer is already running
73
+ // fail if it is
74
+ // the easiest way that I've found to check if timer is running
75
+ // is to start it and stop it
76
+ ESP32MCPWMDriverParams *p = (ESP32MCPWMDriverParams*)driver_params;
77
+ if (mcpwm_timer_start_stop (p->timers [0 ], MCPWM_TIMER_START_NO_STOP) != ESP_ERR_INVALID_STATE){
78
+ // if we get the invalid state error it means that the timer is not enabled
79
+ // that means that we can configure it for low-side current sensing
80
+ SIMPLEFOC_DEBUG (" ESP32-CS: ERR - The timer is already enabled. Cannot be configured for low-side current sensing." );
81
+ return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;
82
+ }
91
83
92
- if ( _isset (pinA) ) pinMode (pinA, INPUT);
93
- if ( _isset (pinB) ) pinMode (pinB, INPUT);
94
- if ( _isset (pinC) ) pinMode (pinC, INPUT);
95
84
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
- };
85
+ ESP32MCPWMCurrentSenseParams* params = new ESP32MCPWMCurrentSenseParams{};
86
+ int no_adc_channels = 0 ;
87
+ if ( _isset (pinA) ){
88
+ pinMode (pinA, INPUT);
89
+ params->pins [no_adc_channels++] = pinA;
90
+ }
91
+ if ( _isset (pinB) ){
92
+ pinMode (pinB, INPUT);
93
+ params->pins [no_adc_channels++] = pinB;
94
+ }
95
+ if ( _isset (pinC) ){
96
+ pinMode (pinC, INPUT);
97
+ params->pins [no_adc_channels++] = pinC;
98
+ }
102
99
100
+ params->adc_voltage_conv = (_ADC_VOLTAGE)/(_ADC_RESOLUTION);
101
+ params->no_adc_channels = no_adc_channels;
103
102
return params;
104
103
}
105
104
106
105
107
106
void _driverSyncLowSide (void * driver_params, void * cs_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;
107
+ #ifdef SIMPLEFOC_ESP32_INTERRUPT_DEBUG
108
+ pinMode (19 , OUTPUT);
109
+ #endif
110
+ ESP32MCPWMDriverParams *p = (ESP32MCPWMDriverParams*)driver_params;
130
111
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;
112
+ mcpwm_timer_event_callbacks_t cbs_timer = {
113
+ .on_full = [](mcpwm_timer_handle_t tim, const mcpwm_timer_event_data_t * edata, void * user_data){
114
+ ESP32MCPWMCurrentSenseParams *p = (ESP32MCPWMCurrentSenseParams*)user_data;
115
+ #ifdef SIMPLEFOC_ESP32_INTERRUPT_DEBUG
116
+ digitalWrite (19 , HIGH);
117
+ #endif
118
+ // increment buffer index
119
+ p->buffer_index = (p->buffer_index + 1 ) % p->no_adc_channels ;
120
+ // sample the phase currents one at a time
121
+ p->adc_buffer [p->buffer_index ] = adcRead (p->pins [p->buffer_index ]);
122
+ #ifdef SIMPLEFOC_ESP32_INTERRUPT_DEBUG
123
+ digitalWrite (19 , LOW);
124
+ #endif
125
+ return true ;
126
+ }
127
+ };
128
+ if (mcpwm_timer_register_event_callbacks (p->timers [0 ], &cbs_timer, cs_params) != ESP_OK){
129
+ SIMPLEFOC_DEBUG (" ESP32-CS: ERR - Failed to sync ADC and driver" );
130
+ }
142
131
}
143
132
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
- }
163
133
164
134
165
135
#endif
0 commit comments