Actually center the ADC samples where we want
Change-Id: I55047f863600f0f46394fd2460a4d71b28453dba
diff --git a/motors/fet12/fet12v2.cc b/motors/fet12/fet12v2.cc
index a310170..7d18f46 100644
--- a/motors/fet12/fet12v2.cc
+++ b/motors/fet12/fet12v2.cc
@@ -511,6 +511,8 @@
motor.set_deadtime_compensation(9);
ConfigurePwmFtm(FTM0);
+ // TODO(Brian): Figure out how to avoid duplicating this code to slave one FTM
+ // to another.
FTM2->CONF = FTM_CONF_GTBEEN;
FTM2->MODE = FTM_MODE_WPDIS;
FTM2->MODE = FTM_MODE_WPDIS | FTM_MODE_FTMEN;
@@ -548,7 +550,8 @@
FTM2->EXTTRIG = FTM_EXTTRIG_CH0TRIG | FTM_EXTTRIG_CH1TRIG;
- teensy::AdcDmaSampler adc_dma;
+ // TODO(Brian): Don't duplicate the timer's MOD value.
+ teensy::AdcDmaSampler adc_dma{BUS_CLOCK_FREQUENCY / SWITCHING_FREQUENCY};
// ADC0_Dx0 is 1-0
// ADC0_Dx2 is 1-2
// ADC0_Dx3 is 2-0
diff --git a/motors/peripheral/adc_dma.cc b/motors/peripheral/adc_dma.cc
index e59a96f..bdd84d6 100644
--- a/motors/peripheral/adc_dma.cc
+++ b/motors/peripheral/adc_dma.cc
@@ -65,7 +65,7 @@
} // namespace
-AdcDmaSampler::AdcDmaSampler() {
+AdcDmaSampler::AdcDmaSampler(int counts_per_cycle) : counts_per_cycle_(counts_per_cycle) {
for (int adc = 0; adc < 2; ++adc) {
for (int i = 0; i < 2; ++i) {
adc_sc1s_[adc][kNumberAdcSamples + i] = ADC_SC1_ADCH(0x1f);
@@ -117,17 +117,24 @@
static constexpr int kHscAdder = 2 * kAdcClockDivider;
+
static constexpr int kConversionTime =
kSfcAdder + 1 /* AverageNum */ * (kBct + kLstAdder + kHscAdder);
+ // Sampling takes 8 ADCK cycles according to
+ // "33.4.4.5 Sample time and total conversion time". This means we want 0
+ // (the start of the cycle) to be 4 ADCK cycles into the second of our four
+ // samples.
+ const int delay_before_cycle =
+ (kConversionTime -
+ 4 /* Clocks before middle of sample */ * kAdcClockDivider +
+ ftm_clock_divider - 1) /
+ ftm_clock_divider;
const int ftm_delay =
(kConversionTime * 2 /* 2 ADC samples */ + ftm_clock_divider - 1) /
ftm_clock_divider;
- // TODO(Brian): Center on the start of the cycle instead. Need to think
- // through how to get it started synced correctly though. Specifically,
- // the second of the four samples should happen on the cycle boundary.
- *ftm_delays_[0] = 0;
- *ftm_delays_[1] = ftm_delay;
+ *ftm_delays_[0] = counts_per_cycle_ - delay_before_cycle;
+ *ftm_delays_[1] = ftm_delay - delay_before_cycle;
}
InitializePdbChannel(&PDB0.CH[0]);
diff --git a/motors/peripheral/adc_dma.h b/motors/peripheral/adc_dma.h
index 8d98dde..6cd0742 100644
--- a/motors/peripheral/adc_dma.h
+++ b/motors/peripheral/adc_dma.h
@@ -28,7 +28,7 @@
// Corresponding samples in adc0_samples and adc1_samples happen
// simultaneously. Second sample happens at the cycle boundary. Elements
// should include the appropriate ADCH and DIFF values.
- AdcDmaSampler();
+ AdcDmaSampler(int counts_per_cycle);
// Must be called before Initialize().
void set_adc0_samples(
@@ -97,6 +97,8 @@
return ENCODER_VALUE_DMA_CHANNEL;
}
+ const int counts_per_cycle_;
+
::std::array<::std::array<volatile uint32_t, kNumberAdcSamples + 2>, 2>
adc_sc1s_{};
::std::array<::std::array<volatile uint16_t, kNumberAdcSamples>, 2>