@@ -302,6 +302,17 @@ modm::platform::Adc{{ id }}::isConversionSequenceFinished()
302
302
return static_cast<bool>(getInterruptFlags() & InterruptFlag::EndOfRegularSequenceOfConversions);
303
303
}
304
304
305
+ void
306
+ modm::platform::Adc{{ id }}::enableRegularConversionExternalTrigger(
307
+ ExternalTriggerPolarity externalTriggerPolarity,
308
+ RegularConversionExternalTrigger regularConversionExternalTrigger)
309
+ {
310
+ const auto polarity = (static_cast<uint32_t>(externalTriggerPolarity) << ADC_CFGR_EXTEN_Pos);
311
+ const auto externalTrigger = (static_cast<uint32_t>(regularConversionExternalTrigger) << ADC_CFGR_EXTSEL_Pos);
312
+ const auto mask = ADC_CFGR_EXTEN_Msk | ADC_CFGR_EXTSEL_Msk;
313
+ ADC{{ id }}->CFGR = (ADC{{ id }}->CFGR & ~mask) | polarity | externalTrigger;
314
+ }
315
+
305
316
void
306
317
modm::platform::Adc{{ id }}::startInjectedConversionSequence()
307
318
{
@@ -351,6 +362,19 @@ modm::platform::Adc{{ id }}::setInjectedConversionSequenceLength(uint8_t length)
351
362
return true;
352
363
}
353
364
365
+ void
366
+ modm::platform::Adc{{ id }}::enableInjectedConversionExternalTrigger(
367
+ ExternalTriggerPolarity externalTriggerPolarity,
368
+ RegularConversionExternalTrigger regularConversionExternalTrigger)
369
+ {
370
+ const auto polarity = (static_cast<uint32_t>(externalTriggerPolarity) << ADC_JSQR_JEXTEN_Pos);
371
+ const auto externalTrigger =
372
+ (static_cast<uint32_t>(regularConversionExternalTrigger) << ADC_JSQR_JEXTSEL_Pos);
373
+ const auto mask = ADC_JSQR_JEXTEN_Msk | ADC_JSQR_JEXTSEL_Msk;
374
+ ADC{{ id }}->JSQR = (ADC{{ id }}->JSQR & ~mask) | polarity | externalTrigger;
375
+ }
376
+
377
+
354
378
bool
355
379
modm::platform::Adc{{ id }}::isInjectedConversionFinished()
356
380
{
@@ -410,3 +434,70 @@ modm::platform::Adc{{ id }}::acknowledgeInterruptFlags(const InterruptFlag_t fla
410
434
// Writing a zero is ignored.
411
435
ADC{{ id }}->ISR = flags.value;
412
436
}
437
+
438
+ /**
439
+ * @arg slot for the offset register (0..3)
440
+ * @arg channel channel to which the offset is applied
441
+ * @arg offset offset value to be applied to the channel
442
+ * @return true if configuration is successful, false if the ADC is currently converting
443
+ */
444
+ bool
445
+ modm::platform::Adc{{ id }}::setChannelOffset(const OffsetSlot slot, const Channel channel, const int16_t offset,
446
+ const bool saturate = false, const bool enable = true)
447
+ {
448
+ if ( (ADC{{ id }}->CR & ADC_CR_JADSTART) || (ADC{{ id }}->CR & ADC_CR_ADSTART) ) {
449
+ // ADC is currently converting, cannot set offset
450
+ return false;
451
+ }
452
+
453
+ %% if target["family"] in["f3", "l4", "l5"] or (target["family"] in["h7"] and target["name"][0] in["4", "5", "a", "b"]):
454
+ // F3 or H74x/H75x does not support signed offsets, so signMask is always 0
455
+ if (offset < 0) {
456
+ return false; // F3 ADC offsets must be positive
457
+ }
458
+ const uint32_t signMask = 0u;
459
+
460
+ // F3 or H74x/H75x does not support saturation, so saturateMask is always 0
461
+ if (saturate) {
462
+ return false; // F3 ADC does not support saturation
463
+ }
464
+ const uint32_t saturateMask = 0u;
465
+
466
+ %% elif target["family"] in["h7"]
467
+ // H7 names the bits differently, but the logic is the same
468
+ const uint32_t signMask = (offset > 0) ? ADC3_OFR1_OFFSETPOS : 0u;
469
+ const uint32_t saturateMask = saturate ? ADC3_OFR1_SATEN : 0u;
470
+ %% else
471
+ const uint32_t signMask = (offset > 0) ? ADC_OFR1_OFFSETPOS : 0u;
472
+ const uint32_t saturateMask = saturate ? ADC_OFR1_SATEN : 0u;
473
+ %% endif
474
+
475
+ %% if target["family"] in ["h7"]
476
+ %% if target["name"][0] in ["4" , "5", "a", "b"]
477
+ (void)enable; // H74x does not have an enable bit for the offset register
478
+ const uint32_t enableMask = 0u;
479
+ %% else
480
+ // H7 uses a different register bit names
481
+ const uint32_t enableMask = enable ? ADC3_OFR1_OFFSET1_EN : 0u;
482
+ %% endif
483
+ %% else
484
+ const uint32_t enableMask = enable ? ADC_OFR1_OFFSET1_EN : 0u;
485
+ %% endif
486
+
487
+ const uint32_t channelMask = (static_cast<uint32_t>(channel) << ADC_OFR1_OFFSET1_CH_Pos) & ADC_OFR1_OFFSET1_CH_Msk;
488
+ const uint32_t offsetMask = (std::abs(offset) << ADC_OFR1_OFFSET1_Pos) & ADC_OFR1_OFFSET1_Msk;
489
+
490
+ const uint32_t offsetValue = channelMask | offsetMask | saturateMask | enableMask | signMask;
491
+
492
+ switch (slot)
493
+ {
494
+ case OffsetSlot::Slot0: ADC{{id}}->OFR1 = offsetValue; break;
495
+ case OffsetSlot::Slot1: ADC{{id}}->OFR2 = offsetValue; break;
496
+ case OffsetSlot::Slot2: ADC{{id}}->OFR3 = offsetValue; break;
497
+ case OffsetSlot::Slot3: ADC{{id}}->OFR4 = offsetValue; break;
498
+ default:
499
+ return false; // invalid slot
500
+ }
501
+
502
+ return true;
503
+ }
0 commit comments