GCC Code Coverage Report


Directory: lib/fprime-samd/fprime-samd/
File: Drv/AdcDriver/AdcDriverHardwareStub.cpp
Date: 2026-09-26 00:05:09
Exec Total Coverage
Lines: 0 53 0.0%
Functions: 0 14 0.0%
Branches: 0 4 0.0%

Line Branch Exec Source
1 // ======================================================================
2 // \title AdcDriverHardwareStub.cpp
3 // \author crsmith
4 // \brief Stub hardware implementation for the ADC peripheral (Linux/test builds)
5 //
6 // This file is compiled for Linux/test builds to enable unit testing.
7 // For SAMD21 target builds, AdcDriverHardware.cpp would be used instead.
8 //
9 // The stub records the arguments of each hardware call and exposes injectable
10 // hardware state so unit tests can drive the component's logic without any real MCU.
11 // ======================================================================
12
13 #include "fprime-samd/Drv/AdcDriver/AdcDriverHardware.hpp"
14
15 namespace Samd21 {
16 namespace AdcHardware {
17
18 static StubState s_state = {};
19
20 ✗ StubState& getStubState() {
21 ✗ return s_state;
22 }
23
24 ✗ void resetStubState() {
25 ✗ s_state = StubState{};
26 ✗ }
27
28 ✗ void AdcHal::waitForGclkSync() {
29 ✗ s_state.waitForGclkSync_calls++;
30 // Stub never blocks - assumes hardware sync completes immediately
31 ✗ }
32
33 ✗ void AdcHal::waitForAdcSync() {
34 ✗ s_state.waitForAdcSync_calls++;
35 // Stub never blocks - assumes hardware sync completes immediately
36 ✗ }
37
38 ✗ void AdcHal::configure(AdcDriver::VoltageReference ref,
39 AdcDriver::Resolution res,
40 AdcDriver::SampleCount samples,
41 U8 samplingTime,
42 AdcDriver::Gain gain) {
43 // Call sync waits to track them (mirroring the real hardware sequence)
44 ✗ waitForGclkSync(); // Called once for GCLK setup
45 ✗ waitForAdcSync(); // Called for reset
46 ✗ waitForAdcSync(); // Called for REFCTRL
47 ✗ waitForAdcSync(); // Called for CTRLB
48 ✗ waitForAdcSync(); // Called for INPUTCTRL before dummy conversion
49 // Additional waits happen in the real implementation
50
51 ✗ s_state.configured = true;
52 ✗ s_state.configure_count++;
53 ✗ s_state.ref = ref;
54 ✗ s_state.res = res;
55 ✗ s_state.samples = samples;
56 ✗ s_state.samplingTime = samplingTime;
57 ✗ s_state.gain = gain;
58 ✗ }
59
60 ✗ void AdcHal::configureChannel(AdcDriver::AdcChannel channel) {
61 ✗ s_state.configureChannel_count++;
62 ✗ s_state.last_configured_channel = channel;
63 ✗ }
64
65 ✗ void AdcHal::selectChannel(AdcDriver::AdcChannel channel, U8 gain) {
66 ✗ s_state.selectChannel_count++;
67 ✗ s_state.selected_channel = channel;
68 ✗ s_state.selected_gain = gain;
69 ✗ }
70
71 ✗ void AdcHal::startConversion() {
72 ✗ s_state.startConversion_count++;
73 ✗ }
74
75 ✗ U32 AdcHal::readResult() {
76 // Model the auto-clear behavior: reading result clears RESRDY flag
77 // per SAMD21 datasheet ยง33.6.5
78 ✗ U32 value = s_state.result;
79 ✗ s_state.result_ready = false;
80 ✗ return value;
81 }
82
83 ✗ bool AdcHal::isResultReady() {
84 ✗ return s_state.result_ready;
85 }
86
87 ✗ bool AdcHal::isOverrun() {
88 ✗ return s_state.overrun;
89 }
90
91 ✗ void AdcHal::clearOverrun() {
92 ✗ s_state.clearOverrun_count++;
93 // Model the write-1-clear: once cleared, no longer set
94 ✗ s_state.overrun = false;
95 ✗ }
96
97 ✗ void AdcHal::enableInterrupt() {
98 // Stub no-op: interrupt enable recorded implicitly
99 ✗ }
100
101 ✗ void AdcHal::enableAdcInterrupts() {
102 // Stub no-op: peripheral interrupt enable recorded implicitly
103 ✗ }
104
105 } // namespace AdcHardware
106 } // namespace Samd21
107