Skip to content

Commit 6019e9d

Browse files
committed
esp32 final support for multiple motors + samd refactor for new low level api
1 parent 4441d36 commit 6019e9d

File tree

3 files changed

+88
-95
lines changed

3 files changed

+88
-95
lines changed

src/current_sense/hardware_specific/esp32_mcu.cpp

Lines changed: 57 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,33 @@
1616
#define _ADC_VOLTAGE 3.3f
1717
#define _ADC_RESOLUTION 4095.0f
1818

19+
20+
typedef struct ESP32MCPWMCurrentSenseParams {
21+
int pins[3];
22+
float adc_voltage_conv;
23+
mcpwm_unit_t mcpwm_unit;
24+
int buffer_index;
25+
} ESP32MCPWMCurrentSenseParams;
26+
27+
1928
/**
2029
* Inline adc reading implementation
2130
*/
2231
// function reading an ADC value and returning the read voltage
2332
float _readADCVoltageInline(const int pinA, const void* cs_params){
2433
uint32_t raw_adc = adcRead(pinA);
25-
return raw_adc * ((GenericCurrentSenseParams*)cs_params)->adc_voltage_conv;
34+
return raw_adc * ((ESP32MCPWMCurrentSenseParams*)cs_params)->adc_voltage_conv;
2635
}
2736

2837
// function reading an ADC value and returning the read voltage
29-
void* _configureADCInline(const void* driver_params, const int pinA,const int pinB,const int pinC){
38+
void* _configureADCInline(const void* driver_params, const int pinA, const int pinB, const int pinC){
3039
_UNUSED(driver_params);
3140

3241
pinMode(pinA, INPUT);
3342
pinMode(pinB, INPUT);
3443
if( _isset(pinC) ) pinMode(pinC, INPUT);
3544

36-
GenericCurrentSenseParams* params = new GenericCurrentSenseParams {
45+
ESP32MCPWMCurrentSenseParams* params = new ESP32MCPWMCurrentSenseParams {
3746
.pins = { pinA, pinB, pinC },
3847
.adc_voltage_conv = (_ADC_VOLTAGE)/(_ADC_RESOLUTION)
3948
};
@@ -46,60 +55,68 @@ void* _configureADCInline(const void* driver_params, const int pinA,const int pi
4655
/**
4756
* Low side adc reading implementation
4857
*/
49-
static mcpwm_dev_t *MCPWM[2] = {&MCPWM0, &MCPWM1};
50-
int a1, a2, a3; // Current readings from internal current sensor amplifiers
51-
int _pinA, _pinB, _pinC;
5258

5359
static void IRAM_ATTR mcpwm0_isr_handler(void*);
5460
static void IRAM_ATTR mcpwm1_isr_handler(void*);
5561
byte currentState = 1;
56-
57-
int* adc_pins;
58-
int* adc_buffer;
59-
int adc_pin_count;
60-
int adc_pin_read_index;
61-
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};
6268

6369
// function reading an ADC value and returning the read voltage
6470
float _readADCVoltageLowSide(const int pin, const void* cs_params){
6571
uint32_t raw_adc;
6672

67-
if (pin == _pinA) raw_adc = a1;
68-
else if (pin == _pinB) raw_adc = a2;
69-
else if (pin == _pinC) raw_adc = a3;
73+
mcpwm_unit_t unit = ((ESP32MCPWMCurrentSenseParams*)cs_params)->mcpwm_unit;
74+
int buffer_index = ((ESP32MCPWMCurrentSenseParams*)cs_params)->buffer_index;
75+
float adc_voltage_conv = ((ESP32MCPWMCurrentSenseParams*)cs_params)->adc_voltage_conv;
7076

71-
return raw_adc * ((GenericCurrentSenseParams*)cs_params)->adc_voltage_conv;
77+
for(int i=0; i < adc_pin_count[unit]; i++){
78+
if( pin == ((ESP32MCPWMCurrentSenseParams*)cs_params)->pins[i]) // found in the buffer
79+
return adc_buffer[unit][buffer_index + i] * adc_voltage_conv;
80+
}
81+
// not found
82+
return 0;
7283
}
7384

74-
// function reading an ADC value and returning the read voltage
85+
// function configuring low-side current sensing
7586
void* _configureADCLowSide(const void* driver_params, const int pinA,const int pinB,const int pinC){
76-
_UNUSED(driver_params);
77-
78-
_pinA= pinA;
79-
_pinB= pinB;
80-
if( _isset(pinC) ) _pinC= pinC;
87+
88+
mcpwm_unit_t unit = ((ESP32MCPWMDriverParams*)driver_params)->mcpwm_unit;
89+
int index_start = adc_pin_count[unit];
90+
adc_pins[unit][adc_pin_count[unit]++] = pinA;
91+
adc_pins[unit][adc_pin_count[unit]++] = pinB;
92+
if( _isset(pinC) ) adc_pins[unit][adc_pin_count[unit]++] = pinC;
8193

8294
pinMode(pinA, INPUT);
8395
pinMode(pinB, INPUT);
8496
if( _isset(pinC) ) pinMode(pinC, INPUT);
8597

86-
GenericCurrentSenseParams* params = new GenericCurrentSenseParams {
98+
ESP32MCPWMCurrentSenseParams* params = new ESP32MCPWMCurrentSenseParams {
8799
.pins = { pinA, pinB, pinC },
88-
.adc_voltage_conv = (_ADC_VOLTAGE)/(_ADC_RESOLUTION)
100+
.adc_voltage_conv = (_ADC_VOLTAGE)/(_ADC_RESOLUTION),
101+
.mcpwm_unit = unit,
102+
.buffer_index = index_start
89103
};
90104

91105
return params;
92106
}
93107

94108

95109
void _driverSyncLowSide(void* driver_params, void* cs_params){
96-
// high side registers enable interrupt
97-
// MCPWM[MCPWM_UNIT_0]->int_ena.timer0_tez_int_ena = true;//A PWM timer 0 TEP event will trigger this interrupt
98110

99-
// low-side register enable interrupt
100111
mcpwm_dev_t* mcpwm_dev = ((ESP32MCPWMDriverParams*)driver_params)->mcpwm_dev;
101112
mcpwm_unit_t mcpwm_unit = ((ESP32MCPWMDriverParams*)driver_params)->mcpwm_unit;
113+
114+
// low-side register enable interrupt
102115
mcpwm_dev->int_ena.timer0_tep_int_ena = true;//A PWM timer 0 TEP event will trigger this interrupt
116+
// high side registers enable interrupt
117+
//mcpwm_dev->int_ena.timer0_tep_int_ena = true;//A PWM timer 0 TEZ event will trigger this interrupt
118+
119+
// register interrupts (mcpwm number, interrupt handler, handler argument = NULL, interrupt signal/flag, return handler = NULL)
103120
if(mcpwm_unit == MCPWM_UNIT_0)
104121
mcpwm_isr_register(mcpwm_unit, mcpwm0_isr_handler, NULL, ESP_INTR_FLAG_IRAM, NULL); //Set ISR Handler
105122
else
@@ -109,63 +126,38 @@ void _driverSyncLowSide(void* driver_params, void* cs_params){
109126
// Read currents when interrupt is triggered
110127
static void IRAM_ATTR mcpwm0_isr_handler(void*){
111128
// // high side
112-
// uint32_t mcpwm_intr_status_0 = MCPWM0.int_st.timer0_tez_int_st;
129+
// uint32_t mcpwm_intr_status = MCPWM0.int_st.timer0_tez_int_st;
113130

114131
// low side
115132
uint32_t mcpwm_intr_status = MCPWM0.int_st.timer0_tep_int_st;
116133
if(mcpwm_intr_status){
117-
switch (currentState)
118-
{
119-
case 1 :
120-
a1 = adcRead(_pinA);
121-
currentState = 2;
122-
break;
123-
case 2 :
124-
a2 = adcRead(_pinB);
125-
currentState = _isset(_pinC) ? 3 : 1;
126-
break;
127-
case 3 :
128-
a3 = adcRead(_pinC);
129-
currentState = 1;
130-
break;
131-
}
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;
132137
}
133-
// high side
134-
// MCPWM0.int_clr.timer0_tez_int_clr = mcpwm_intr_status_0;
135-
136138
// low side
137139
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;
138142
}
139143

144+
140145
// Read currents when interrupt is triggered
141146
static void IRAM_ATTR mcpwm1_isr_handler(void*){
142147
// // high side
143-
// uint32_t mcpwm_intr_status_0 = MCPWM1.int_st.timer0_tez_int_st;
148+
// uint32_t mcpwm_intr_status = MCPWM1.int_st.timer0_tez_int_st;
144149

145150
// low side
146151
uint32_t mcpwm_intr_status = MCPWM1.int_st.timer0_tep_int_st;
147152
if(mcpwm_intr_status){
148-
switch (currentState)
149-
{
150-
case 1 :
151-
a1 = adcRead(_pinA);
152-
currentState = 2;
153-
break;
154-
case 2 :
155-
a2 = adcRead(_pinB);
156-
currentState = _isset(_pinC) ? 3 : 1;
157-
break;
158-
case 3 :
159-
a3 = adcRead(_pinC);
160-
currentState = 1;
161-
break;
162-
}
153+
adc_buffer[1][adc_read_index[1]] = adcRead(adc_pins[1][adc_read_index[1]]);
154+
adc_read_index[1]++;
155+
if(adc_read_index[1] == adc_pin_count[1]) adc_read_index[1] = 0;
163156
}
164-
// high side
165-
// MCPWM1.int_clr.timer0_tez_int_clr = mcpwm_intr_status_0;
166-
167157
// low side
168158
MCPWM1.int_clr.timer0_tep_int_clr = mcpwm_intr_status;
159+
// high side
160+
// MCPWM1.int_clr.timer0_tez_int_clr = mcpwm_intr_status_0;
169161
}
170162

171163

src/current_sense/hardware_specific/samd21_mcu.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,23 @@ static bool freeRunning = false;
88
static int _pinA, _pinB, _pinC;
99
static uint16_t a = 0xFFFF, b = 0xFFFF, c = 0xFFFF; // updated by adcStopWithDMA when configured in freerunning mode
1010
static SAMDCurrentSenseADCDMA instance;
11-
/**
12-
* function reading an ADC value and returning the read voltage
13-
*
14-
* @param pinA - adc pin A
15-
* @param pinB - adc pin B
16-
* @param pinC - adc pin C
17-
*/
18-
void _configureADCLowSide(const int pinA,const int pinB,const int pinC)
11+
12+
// function configuring low-side current sensing
13+
void* _configureADCLowSide(const void* driver_params, const int pinA,const int pinB,const int pinC)
1914
{
15+
_UNUSED(driver_params);
16+
2017
_pinA = pinA;
2118
_pinB = pinB;
2219
_pinC = pinC;
2320
freeRunning = true;
2421
instance.init(pinA, pinB, pinC);
2522

23+
GenericCurrentSenseParams* params = new GenericCurrentSenseParams {
24+
.pins = { pinA, pinB, pinC }
25+
};
26+
27+
return params;
2628
}
2729
void _startADC3PinConversionLowSide()
2830
{
@@ -33,8 +35,10 @@ void _startADC3PinConversionLowSide()
3335
*
3436
* @param pinA - the arduino pin to be read (it has to be ADC pin)
3537
*/
36-
float _readADCVoltageLowSide(const int pinA)
38+
float _readADCVoltageLowSide(const int pinA, const void* cs_params)
3739
{
40+
_UNUSED(cs_params);
41+
3842
instance.readResults(a, b, c);
3943

4044
if(pinA == _pinA)
@@ -50,8 +54,11 @@ float _readADCVoltageLowSide(const int pinA)
5054
/**
5155
* function syncing the Driver with the ADC for the LowSide Sensing
5256
*/
53-
void _driverSyncLowSide()
57+
void _driverSyncLowSide(void* driver_params, void* cs_params)
5458
{
59+
_UNUSED(driver_params);
60+
_UNUSED(cs_params);
61+
5562
SIMPLEFOC_SAMD_DEBUG_SERIAL.println(F("TODO! _driverSyncLowSide() is not implemented"));
5663
instance.startADCScan();
5764
//TODO: hook with PWM interrupts
Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,31 @@
11
#include "../hardware_api.h"
22

3-
#if defined(_SAMD21_)||defined(_SAMD51_)||defined(_SAME51_)
3+
#if defined(_SAMD21_)|| defined(_SAMD51_) || defined(_SAME51_)
44

55
#define _ADC_VOLTAGE 3.3f
66
#define _ADC_RESOLUTION 1024.0f
77

8-
// adc counts to voltage conversion ratio
9-
// some optimizing for faster execution
10-
#define _ADC_CONV ( (_ADC_VOLTAGE) / (_ADC_RESOLUTION) )
11-
128
// function reading an ADC value and returning the read voltage
13-
float _readADCVoltageInline(const int pinA){
9+
float _readADCVoltageInline(const int pinA, const void* cs_params){
10+
digitalWrite(7,HIGH);
1411
uint32_t raw_adc = analogRead(pinA);
15-
return raw_adc * _ADC_CONV;
12+
digitalWrite(7,LOW);
13+
return raw_adc * ((GenericCurrentSenseParams*)cs_params)->adc_voltage_conv;
1614
}
15+
1716
// function reading an ADC value and returning the read voltage
18-
void _configureADCInline(const int pinA,const int pinB,const int pinC){
17+
void* _configureADCInline(const void* driver_params, const int pinA,const int pinB,const int pinC){
18+
_UNUSED(driver_params);
19+
pinMode(7,OUTPUT);
1920
pinMode(pinA, INPUT);
2021
pinMode(pinB, INPUT);
2122
if( _isset(pinC) ) pinMode(pinC, INPUT);
22-
}
2323

24+
GenericCurrentSenseParams* params = new GenericCurrentSenseParams {
25+
.pins = { pinA, pinB, pinC },
26+
.adc_voltage_conv = (_ADC_VOLTAGE)/(_ADC_RESOLUTION)
27+
};
2428

25-
// function reading an ADC value and returning the read voltage
26-
float _readADCVoltageLowSide(const int pinA){
27-
return _readADCVoltageInline(pinA);
29+
return params;
2830
}
29-
// Configure low side for generic mcu
30-
// cannot do much but
31-
void _configureADCLowSide(const int pinA,const int pinB,const int pinC){
32-
pinMode(pinA, INPUT);
33-
pinMode(pinB, INPUT);
34-
if( _isset(pinC) ) pinMode(pinC, INPUT);
35-
}
36-
3731
#endif

0 commit comments

Comments
 (0)