GCC Code Coverage Report


Directory: ./
File: sensors/ADS7828.cpp
Date: 2026-10-29 08:11:58
Exec Total Coverage
Lines: 36 45 80.0%
Functions: 2 3 66.7%
Branches: 39 72 54.2%

Line Branch Exec Source
1 /*
2 * This file is part of the Falcon Player (FPP) and is Copyright (C)
3 * 2013-2022 by the Falcon Player Developers.
4 *
5 * The Falcon Player (FPP) is free software, and is covered under
6 * multiple Open Source licenses. Please see the included 'LICENSES'
7 * file for descriptions of what files are covered by each license.
8 *
9 * This source file is covered under the LGPL v2.1 as described in the
10 * included LICENSE.LGPL file.
11 */
12
13 #include "fpp-pch.h"
14
15 #include "fpp-json.h"
16
17 #if __has_include(<byteswap.h>)
18 #include <byteswap.h>
19 #else
20 inline uint16_t bswap_16(uint16_t num) {
21 return (num >> 8) | (num << 8);
22 }
23 #endif
24
25 #include "../common.h"
26 #include "../util/I2CUtils.h"
27
28 #include "ADS7828.h"
29
30 3 ADS7828Sensor::ADS7828Sensor(Json::Value& config) :
31 3 SensorSource(config) {
32
3/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
3 i2cBus = config["i2cBus"].asInt();
33
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if (config["i2cAddress"].isString()) {
34
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 std::string ad = config["i2cAddress"].asString();
35
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 i2cAddress = std::stoul(ad, nullptr, 16);
36 2 } else {
37 ✗ i2cAddress = config["i2cAddress"].asInt();
38 }
39
4/8
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
1 if (config["type"].asString() == "ads7830") {
40 ✗ bits = 8;
41 } else {
42 1 bits = 12;
43 }
44
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 internalRefVoltage = config["internalRefVoltage"].asBool();
45
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 for (int x = 0; x < 8; x++) {
46 8 enabled[x] = false;
47 }
48 // Last, once every field has been read: a wrong-typed one throws out of
49 // this constructor, and the destructor that frees this would not run.
50
3/8
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1 i2c = new I2CUtils(i2cBus, i2cAddress);
51 3 }
52
53 ✗ ADS7828Sensor::~ADS7828Sensor() {
54 ✗ delete i2c;
55 ✗ }
56
57 7 int32_t ADS7828Sensor::getValue(int ch) {
58
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
14 if (ch < 0 || ch >= (int)enabled.size()) {
59 ✗ return 0;
60 }
61
3/6
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
7 if (enabled[ch] && i2c->isOk()) {
62
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 std::unique_lock<std::mutex> lock(updateMutex);
63
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 uint8_t baseCmd = 0x80 | (internalRefVoltage ? 0xC : 0x4);
64 7 uint8_t cmd = baseCmd | (((ch >> 1) | (ch & 0x01) << 2) << 4);
65 7 constexpr int samples = 4;
66 7 constexpr int wanted = samples * 2;
67 7 uint16_t b2[samples] = { 0, 0, 0, 0 };
68 // readI2CBlockData() returns -1 on any failed transfer, and isOk() only
69 // says the bus was opened, not that the chip still answers. The read
70 // count must therefore never be accumulated blindly: a negative c both
71 // indexes before b2 and asks for more than sizeof(b2) bytes on the next
72 // pass, and c never reaches wanted, so the loop runs away scribbling
73 // over the caller's stack. Bail on the first failure instead.
74
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 int c = i2c->readI2CBlockData(cmd, (uint8_t*)b2, wanted - 2);
75
4/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
8 while (c > 0 && c < wanted) {
76
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 int r = i2c->readI2CBlockData(cmd, ((uint8_t*)b2) + c, wanted - c);
77
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (r <= 0) {
78 ✗ c = -1;
79 ✗ break;
80 }
81 1 c += r;
82 }
83
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 if (c != wanted) {
84 6 return lastValue[ch];
85 }
86 1 uint32_t sum = 0;
87
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 for (int x = 0; x < samples; x++) {
88 4 sum += bswap_16(b2[x]);
89 }
90 1 lastValue[ch] = sum / samples;
91 1 return lastValue[ch];
92 7 }
93 ✗ return 0;
94 };
95