1-
2- // STL includes
1+ /* ProviderSpiGeneric.cpp
2+ *
3+ * MIT License
4+ *
5+ * Copyright (c) 2020-2025 awawa-dev
6+ *
7+ * Project homesite: https://github.com/awawa-dev/HyperHDR
8+ *
9+ * Permission is hereby granted, free of charge, to any person obtaining a copy
10+ * of this software and associated documentation files (the "Software"), to deal
11+ * in the Software without restriction, including without limitation the rights
12+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+ * copies of the Software, and to permit persons to whom the Software is
14+ * furnished to do so, subject to the following conditions:
15+ *
16+ * The above copyright notice and this permission notice shall be included in all
17+ * copies or substantial portions of the Software.
18+
19+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25+ * SOFTWARE.
26+ */
27+
28+ // STL includes
329#include < cstring>
430#include < cstdio>
531#include < iostream>
1137#include < sys/ioctl.h>
1238
1339// Local HyperHDR includes
14- #include < led-drivers/spi/ProviderSpi .h>
40+ #include < led-drivers/spi/ProviderSpiGeneric .h>
1541#include < utils/Logger.h>
1642
1743#include < QDirIterator>
1844
19- ProviderSpi::ProviderSpi (const QJsonObject& deviceConfig)
20- : LedDevice(deviceConfig)
21- , _deviceName(" /dev/spidev0.0" )
22- , _baudRate_Hz(1000000 )
23- , _fid(-1 )
24- , _spiMode(SPI_MODE_0)
25- , _spiDataInvert(false )
26- , _spiType(" " )
45+ ProviderSpiGeneric::ProviderSpiGeneric (Logger* logger)
46+ : QObject(), ProviderSpiInterface(logger)
2747{
2848}
2949
30- ProviderSpi::~ProviderSpi ()
50+
51+ ProviderSpiGeneric::~ProviderSpiGeneric ()
3152{
53+ close ();
3254}
3355
34- bool ProviderSpi ::init (const QJsonObject& deviceConfig)
56+ bool ProviderSpiGeneric ::init (const QJsonObject& deviceConfig)
3557{
3658 bool isInitOK = false ;
3759
38- // Initialise sub-class
39- if (LedDevice::init (deviceConfig))
40- {
41- _deviceName = deviceConfig[" output" ].toString (_deviceName);
42- _spiType = deviceConfig[" spitype" ].toString (" " );
43- _baudRate_Hz = deviceConfig[" rate" ].toInt (_baudRate_Hz);
44- _spiMode = deviceConfig[" spimode" ].toInt (_spiMode);
45- _spiDataInvert = deviceConfig[" invert" ].toBool (_spiDataInvert);
46-
47- if (_spiType == " rp2040" && _baudRate_Hz > 20833333 )
48- {
49- _baudRate_Hz = 20833333 ;
50- }
60+ _deviceName = deviceConfig[" output" ].toString (_deviceName);
61+ _spiType = deviceConfig[" spitype" ].toString (" " );
62+ _baudRate_Hz = deviceConfig[" rate" ].toInt (_baudRate_Hz);
63+ _spiMode = deviceConfig[" spimode" ].toInt (_spiMode);
64+ _spiDataInvert = deviceConfig[" invert" ].toBool (_spiDataInvert);
5165
52- Debug (_log, " Speed: %d, Type: %s" , _baudRate_Hz, QSTRING_CSTR (_spiType));
53- Debug (_log, " Inverted: %s, Mode: %d" , (_spiDataInvert) ? " yes" : " no" , _spiMode);
66+ if (_spiType == " rp2040" && _baudRate_Hz > 20833333 )
67+ {
68+ _baudRate_Hz = 20833333 ;
69+ }
5470
55- if (_defaultInterval > 0 )
56- Warning (_log, " The refresh timer is enabled ('Refresh time' > 0) and may limit the performance of the LED driver. Ignore this error if you set it on purpose for some reason (but you almost never need it)." );
71+ Debug (_log, " Speed: %d, Type: %s" , _baudRate_Hz, QSTRING_CSTR (_spiType));
72+ Debug (_log, " Real speed: %d" , getRate ());
73+ Debug (_log, " Inverted: %s, Mode: %d" , (_spiDataInvert) ? " yes" : " no" , _spiMode);
5774
58- isInitOK = true ;
59- }
6075 return isInitOK;
6176}
6277
63- int ProviderSpi ::open ()
78+ QString ProviderSpiGeneric ::open ()
6479{
65- int retval = -1 ;
66- QString errortext;
67- _isDeviceReady = false ;
80+ QString error;
6881
6982 const int bitsPerWord = 8 ;
7083
7184 _fid = ::open (QSTRING_CSTR (_deviceName), O_RDWR);
7285
7386 if (_fid < 0 )
7487 {
75- errortext = QString (" Failed to open device (%1). Error message: %2" ).arg (_deviceName, strerror (errno));
76- retval = -1 ;
88+ error = QString (" Failed to open device (%1). Error message: %2" ).arg (_deviceName, strerror (errno));
7789 }
7890 else
7991 {
8092 if (ioctl (_fid, SPI_IOC_WR_MODE, &_spiMode) == -1 || ioctl (_fid, SPI_IOC_RD_MODE, &_spiMode) == -1 )
8193 {
82- retval = - 2 ;
94+ error = " Cannot set SPI mode " ;
8395 }
8496 else
8597 {
8698 if (ioctl (_fid, SPI_IOC_WR_BITS_PER_WORD, &bitsPerWord) == -1 || ioctl (_fid, SPI_IOC_RD_BITS_PER_WORD, &bitsPerWord) == -1 )
8799 {
88- retval = - 4 ;
100+ error = " Cannot set SPI bits per word " ;
89101 }
90102 else
91103 {
92104 if (ioctl (_fid, SPI_IOC_WR_MAX_SPEED_HZ, &_baudRate_Hz) == -1 || ioctl (_fid, SPI_IOC_RD_MAX_SPEED_HZ, &_baudRate_Hz) == -1 )
93105 {
94- retval = - 6 ;
106+ error = " Cannot set SPI baudrate " ;
95107 }
96108 else
97109 {
@@ -105,32 +117,17 @@ int ProviderSpi::open()
105117 {
106118 writeBytesEsp32 (sizeof (rpBuffer), rpBuffer);
107119 }
108-
109- _isDeviceReady = true ;
110- retval = 0 ;
111120 }
112121 }
113122 }
114- if (retval < 0 )
115- {
116- errortext = QString (" Failed to open device (%1). Error Code: %2" ).arg (_deviceName).arg (retval);
117- }
118- }
119-
120- if (retval < 0 )
121- {
122- this ->setInError (errortext);
123123 }
124124
125- return retval ;
125+ return error ;
126126}
127127
128- int ProviderSpi ::close ()
128+ int ProviderSpiGeneric ::close ()
129129{
130130 uint8_t rpBuffer[] = { 0x41 , 0x77 , 0x41 , 0x2a , 0xa2 , 0x35 , 0x68 , 0x79 , 0x70 , 0x65 , 0x72 , 0x68 , 0x64 , 0x72 };
131- int retval = 0 ;
132-
133- _isDeviceReady = false ;
134131
135132 Debug (_log, " Closing SPI interface" );
136133
@@ -139,20 +136,16 @@ int ProviderSpi::close()
139136 writeBytesRp2040 (sizeof (rpBuffer), rpBuffer);
140137 }
141138
142- // Test, if device requires closing
143- if (_fid > -1 )
139+ if (_fid > -1 && ::close (_fid) != 0 )
144140 {
145- // Close device
146- if (::close (_fid) != 0 )
147- {
148- Error (_log, " Failed to close device (%s). Error message: %s" , QSTRING_CSTR (_deviceName), strerror (errno));
149- retval = -1 ;
150- }
141+ Error (_log, " Failed to close device (%s). Error message: %s" , QSTRING_CSTR (_deviceName), strerror (errno));
142+ return -1 ;
151143 }
152- return retval;
144+
145+ return 0 ;
153146}
154147
155- int ProviderSpi ::writeBytes (unsigned size, const uint8_t * data)
148+ int ProviderSpiGeneric ::writeBytes (unsigned size, const uint8_t * data)
156149{
157150 MemoryBuffer<uint8_t > buffer;
158151 spi_ioc_transfer _spi;
@@ -182,7 +175,22 @@ int ProviderSpi::writeBytes(unsigned size, const uint8_t* data)
182175 return retVal;
183176}
184177
185- QJsonObject ProviderSpi::discover (const QJsonObject& /* params*/ )
178+ int ProviderSpiGeneric::getRate ()
179+ {
180+ return _baudRate_Hz;
181+ }
182+
183+ QString ProviderSpiGeneric::getSpiType ()
184+ {
185+ return _spiType;
186+ }
187+
188+ ProviderSpiInterface::SpiProvider ProviderSpiGeneric::getProviderType ()
189+ {
190+ return ProviderSpiInterface::SpiProvider::GENERIC;
191+ }
192+
193+ QJsonObject ProviderSpiGeneric::discover (const QJsonObject& /* params*/ )
186194{
187195 QJsonObject devicesDiscovered;
188196 QJsonArray deviceList;
@@ -198,10 +206,9 @@ QJsonObject ProviderSpi::discover(const QJsonObject& /*params*/)
198206 {" value" , path},
199207 { " name" , path } });
200208
201- devicesDiscovered.insert (" ledDeviceType" , _activeDeviceType);
202209 devicesDiscovered.insert (" devices" , deviceList);
203210
204- Debug (_log, " SPI devices discovered: [%s]" , QString (QJsonDocument (devicesDiscovered).toJson (QJsonDocument::Compact)).toUtf8 ().constData ());
211+ Debug (_log, " Generic SPI devices discovered: [%s]" , QString (QJsonDocument (devicesDiscovered).toJson (QJsonDocument::Compact)).toUtf8 ().constData ());
205212
206213 return devicesDiscovered;
207214}
0 commit comments