You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* The RP2040 ADC engine takes over the control of the MCU's ADC. Parallel ADC access is not permitted, as this would
16
+
* cause conflicts with the engine's DMA based access and cause crashes.
17
+
* To use the other ADC channels, use them via this engine. Use addPin() to add them to the conversion, and getLastResult()
18
+
* to retrieve their value at any time.
19
+
*
20
+
* For motor current sensing, the engine supports both inline sensing and low-side sensing.
21
+
*
22
+
* Inline sensing is supported by offering a user-selectable fixed ADC sampling rate, which can be set between 500kHz and 1Hz.
23
+
* After starting the engine it will continuously sample and provide new values at the configured rate.
24
+
*
25
+
* Low-side sensing is supported by configuring a trigger from the PWM signal. The trigger happens at the middle-point of the
26
+
* up/down counting PWM, which is the mid-point of the on-period.
27
+
* So in the case of low-side sensing, all ADC channels are converted at the rate of the PWM frequency.
28
+
*
29
+
* The SimpleFOC PWM driver for RP2040 syncs all the slices, so the PWM trigger is applied to the first used slice. For current
30
+
* sensing to work correctly, all PWM slices have to be set to the same PWM frequency.
31
+
* In theory, two motors could be sensed using 2 shunts on each motor. In practice, due to the slow conversion rate of the RP2040's
32
+
* ADC, this would mean 8us conversion time, which would have to fit in the low-side on-time even at low duty-cycles... It remains
33
+
* to be seen how well this can work, or if it works at all, but presumably the PWM frequency would have to be quite low.
34
+
*
35
+
* TODO we need the mid-point of the low-side, which is actually the beginning/end of the PWM cycle - hmmmm...
36
+
*
37
+
* Note that if using other ADC channels along with the motor current sensing, those channels will be subject to the same conversion schedule as the motor's ADC channels, i.e. convert at the same fixed rate in case
38
+
* of inline sensing, or based on the motor PWM in case of PWM-triggered low-side sensing.
39
+
*
40
+
* Solution to trigger ADC conversion from PWM via DMA:
41
+
* use the PWM wrap as a DREQ to a DMA channel, and have the DMA channel write to the ADC's CS register to trigger an ADC sample.
42
+
* Solution for ADC conversion:
43
+
* ADC converts all channels in round-robin mode, and writes to FIFO. FIFO is emptied by a DMA which triggers after N conversions,
44
+
* where N is the number of ADC channels used. So this DMA copies all the values from one round-robin conversion. This first DMA
45
+
* triggers a second DMA which does a 32bit copy of all converted values (up to 4 channels x 8bit) at once, and triggers an interrupt.
46
+
* The interrupt routine copies the values to the output buffer.
47
+
*
48
+
* TODO think about whether the second DMA is needed
49
+
*/
50
+
51
+
52
+
#defineSIMPLEFOC_RP2040_ADC_RESOLUTION256
53
+
#ifndef SIMPLEFOC_RP2040_ADC_VDDA
54
+
#defineSIMPLEFOC_RP2040_ADC_VDDA3.3f
55
+
#endif
56
+
57
+
classRP2040ADCEngine {
58
+
59
+
public:
60
+
RP2040ADCEngine();
61
+
voidaddPin(int pin);
62
+
voidsetPWMTrigger(uint slice);
63
+
64
+
boolinit();
65
+
voidstart();
66
+
voidstop();
67
+
68
+
voidgetLastResult();
69
+
70
+
voidhandleADCUpdate();
71
+
72
+
int samples_per_second = 0; // leave at 0 to convert in tight loop
73
+
float adc_conv = (SIMPLEFOC_RP2040_ADC_VDDA / SIMPLEFOC_RP2040_ADC_RESOLUTION); // conversion from raw ADC to float
0 commit comments