GCC Code Coverage Report


Directory: ./
File: channeloutput/GPIO595.cpp
Date: 2026-10-29 08:11:58
Exec Total Coverage
Lines: 0 72 0.0%
Functions: 0 9 0.0%
Branches: 0 98 0.0%

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 GPL v2 as described in the
10 * included LICENSE.GPL file.
11 */
12
13 #include "fpp-pch.h"
14
15 #include "fpp-json.h"
16
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <thread>
20
21 #include "../log.h"
22
23 #include "GPIO595.h"
24
25 #define GPIO595_MAX_CHANNELS 128
26
27 /////////////////////////////////////////////////////////////////////////////
28
29 #include "Plugin.h"
30 class GPIO595Plugin : public FPPPlugins::Plugin, public FPPPlugins::ChannelOutputPlugin {
31 public:
32 ✗ GPIO595Plugin() :
33 ✗ FPPPlugins::Plugin("GPIO595") {
34 ✗ }
35 ✗ virtual ChannelOutput* createChannelOutput(unsigned int startChannel, unsigned int channelCount) override {
36 ✗ return new GPIO595Output(startChannel, channelCount);
37 }
38 };
39
40 extern "C" {
41 ✗ FPPPlugins::Plugin* createPlugin() {
42 ✗ return new GPIO595Plugin();
43 }
44 }
45
46 /*
47 *
48 */
49 ✗ GPIO595Output::GPIO595Output(unsigned int startChannel, unsigned int channelCount) :
50 ThreadedChannelOutput(startChannel, channelCount),
51 ✗ m_clockPin(nullptr),
52 ✗ m_dataPin(nullptr),
53 ✗ m_latchPin(nullptr) {
54 ✗ LogDebug(VB_CHANNELOUT, "GPIO595Output::GPIO595Output(%u, %u)\n",
55 startChannel, channelCount);
56 ✗ }
57
58 /*
59 *
60 */
61 ✗ GPIO595Output::~GPIO595Output() {
62 ✗ LogDebug(VB_CHANNELOUT, "GPIO595Output::~GPIO595Output()\n");
63 ✗ }
64 ✗ int GPIO595Output::Init(Json::Value config) {
65 ✗ LogDebug(VB_CHANNELOUT, "GPIO595Output::Init()\n");
66
67 ✗ if (config.isMember("clockPin")) {
68 ✗ if (config["clockPin"].isString()) {
69 ✗ m_clockPin = PinCapabilities::getPinByName(config["clockPin"].asString()).ptr();
70 } else {
71 ✗ int p = config["clockPin"].asInt();
72 ✗ m_clockPin = PinCapabilities::getPinByGPIO(0, p).ptr();
73 }
74 }
75 ✗ if (config.isMember("dataPin")) {
76 ✗ if (config["dataPin"].isString()) {
77 ✗ m_dataPin = PinCapabilities::getPinByName(config["dataPin"].asString()).ptr();
78 } else {
79 ✗ int p = config["dataPin"].asInt();
80 ✗ m_dataPin = PinCapabilities::getPinByGPIO(0, p).ptr();
81 }
82 }
83 ✗ if (config.isMember("latchPin")) {
84 ✗ if (config["latchPin"].isString()) {
85 ✗ m_latchPin = PinCapabilities::getPinByName(config["latchPin"].asString()).ptr();
86 } else {
87 ✗ int p = config["latchPin"].asInt();
88 ✗ m_latchPin = PinCapabilities::getPinByGPIO(0, p).ptr();
89 }
90 }
91
92 ✗ if ((m_clockPin == nullptr) ||
93 ✗ (m_dataPin == nullptr) ||
94 ✗ (m_latchPin == nullptr)) {
95 ✗ LogErr(VB_CHANNELOUT, "GPIO595 Invalid Config\n");
96 ✗ return 0;
97 }
98
99 ✗ m_clockPin->configPin("gpio", true);
100 ✗ m_dataPin->configPin("gpio", true);
101 ✗ m_latchPin->configPin("gpio", true);
102
103 ✗ m_clockPin->setValue(0);
104 ✗ m_dataPin->setValue(0);
105 ✗ m_latchPin->setValue(1);
106
107 ✗ m_usedGPIOS.push_back(m_clockPin->name);
108 ✗ m_usedGPIOS.push_back(m_dataPin->name);
109 ✗ m_usedGPIOS.push_back(m_latchPin->name);
110
111 ✗ return ThreadedChannelOutput::Init(config);
112 }
113
114 /*
115 *
116 */
117 ✗ int GPIO595Output::Close(void) {
118 ✗ LogDebug(VB_CHANNELOUT, "GPIO595Output::Close()\n");
119
120 ✗ return ThreadedChannelOutput::Close();
121 }
122
123 /*
124 *
125 */
126 ✗ int GPIO595Output::RawSendData(unsigned char* channelData) {
127 ✗ LogDebug(VB_CHANNELOUT, "GPIO595Output::RawSendData(%p)\n", channelData);
128
129 // Drop the latch low
130 ✗ m_latchPin->setValue(0);
131 ✗ std::this_thread::sleep_for(std::chrono::microseconds(1));
132
133 // Output one bit per channel along with a clock tick
134 ✗ int i = 0;
135 ✗ for (i = m_channelCount - 1; i >= 0; i--) {
136 // We only support basic On/Off. non-zero channel value == On
137 ✗ m_dataPin->setValue(channelData[i]);
138
139 // Send a clock tick
140 ✗ m_clockPin->setValue(1);
141 ✗ std::this_thread::sleep_for(std::chrono::microseconds(1));
142 ✗ m_clockPin->setValue(0);
143 ✗ std::this_thread::sleep_for(std::chrono::microseconds(1));
144 }
145
146 // Bring the latch high to push the bits out of the chip
147 ✗ m_latchPin->setValue(1);
148 ✗ std::this_thread::sleep_for(std::chrono::microseconds(1));
149
150 ✗ return m_channelCount;
151 }
152
153 /*
154 *
155 */
156 ✗ void GPIO595Output::DumpConfig(void) {
157 ✗ LogDebug(VB_CHANNELOUT, "GPIO595Output::DumpConfig()\n");
158
159 ✗ LogDebug(VB_CHANNELOUT, " Clock Pin: %s\n", m_clockPin ? m_clockPin->name.c_str() : "-none-");
160 ✗ LogDebug(VB_CHANNELOUT, " Data Pin : %s\n", m_dataPin ? m_dataPin->name.c_str() : "-none-");
161 ✗ LogDebug(VB_CHANNELOUT, " Latch Pin: %s\n", m_latchPin ? m_latchPin->name.c_str() : "-none-");
162
163 ✗ ThreadedChannelOutput::DumpConfig();
164 ✗ }
165