Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial HyperSPI support for RPi Pico (rp2040) #610

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions sources/leddevice/dev_spi/LedDeviceAWA_spi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ int LedDeviceAWA_spi::write(const std::vector<ColorRgb>& ledValues)
return writeBytesEsp8266(bufferLength, _ledBuffer.data());
else if (_spiType == "esp32")
return writeBytesEsp32(bufferLength, _ledBuffer.data());
else if (_spiType == "rp2040")
return writeBytesRp2040(bufferLength, _ledBuffer.data());
else
return writeBytes(bufferLength, _ledBuffer.data());
}
Expand Down
65 changes: 64 additions & 1 deletion sources/leddevice/dev_spi/ProviderSpi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ bool ProviderSpi::init(const QJsonObject& deviceConfig)
_baudRate_Hz = deviceConfig["rate"].toInt(_baudRate_Hz);
_spiMode = deviceConfig["spimode"].toInt(_spiMode);
_spiDataInvert = deviceConfig["invert"].toBool(_spiDataInvert);


if (_spiType == "rp2040" && _baudRate_Hz > 20833333)
{
_baudRate_Hz = 20833333;
}

Debug(_log, "_baudRate_Hz [%d], _spiType: %s", _baudRate_Hz, QSTRING_CSTR(_spiType));
Debug(_log, "_spiDataInvert [%d], _spiMode [%d]", _spiDataInvert, _spiMode);

Expand Down Expand Up @@ -91,6 +96,17 @@ int ProviderSpi::open()
}
else
{
uint8_t rpBuffer[] = { 0x41, 0x77, 0x41, 0x2a, 0xa2, 0x15, 0x68, 0x79, 0x70, 0x65, 0x72, 0x68, 0x64, 0x72 };

if (_spiType == "rp2040")
{
writeBytesRp2040(sizeof(rpBuffer), rpBuffer);
}
else if (_spiType == "esp32")
{
writeBytesEsp32(sizeof(rpBuffer), rpBuffer);
}

// Everything OK -> enable device
_isDeviceReady = true;
retval = 0;
Expand All @@ -113,10 +129,17 @@ int ProviderSpi::open()

int ProviderSpi::close()
{
uint8_t rpBuffer[] = { 0x41, 0x77, 0x41, 0x2a, 0xa2, 0x35, 0x68, 0x79, 0x70, 0x65, 0x72, 0x68, 0x64, 0x72 };

// LedDevice specific closing activities
int retval = 0;
_isDeviceReady = false;

if (_spiType == "rp2040")
{
writeBytesRp2040(sizeof(rpBuffer), rpBuffer);
}

// Test, if device requires closing
if (_fid > -1)
{
Expand Down Expand Up @@ -193,6 +216,43 @@ int ProviderSpi::writeBytesEsp8266(unsigned size, const uint8_t* data)
return retVal;
}

int ProviderSpi::writeBytesRp2040(unsigned size, const uint8_t* data)
{
static const int REAL_BUFFER = 1536;
static const uint32_t BUFFER_SIZE = REAL_BUFFER ;

uint8_t* startData = (uint8_t*)data;
uint8_t* endData = (uint8_t*)data + size;
uint8_t buffer[BUFFER_SIZE];

if (_fid < 0)
{
return -1;
}

_spi.tx_buf = __u64(&buffer);
_spi.len = __u32(BUFFER_SIZE);
_spi.delay_usecs = 0;

int retVal = 0;

while (retVal >= 0 && startData < endData)
{
if (startData != data)
usleep(1000);

memset(buffer, 0, sizeof(buffer));
for (int i = 0; i < REAL_BUFFER && startData < endData; i++, startData++)
{
buffer[i] = *startData;
}
retVal = ioctl(_fid, SPI_IOC_MESSAGE(1), &_spi);
ErrorIf((retVal < 0), _log, "SPI failed to write. errno: %d, %s", errno, strerror(errno));
}

return retVal;
}

int ProviderSpi::writeBytesEsp32(unsigned size, const uint8_t* data)
{
static const int REAL_BUFFER = 1536;
Expand All @@ -215,6 +275,9 @@ int ProviderSpi::writeBytesEsp32(unsigned size, const uint8_t* data)

while (retVal >= 0 && startData < endData)
{
if (startData != data)
usleep(1000);

memset(buffer, 0, sizeof(buffer));
for (int i = 0; i < REAL_BUFFER && startData < endData; i++, startData++)
{
Expand Down
3 changes: 3 additions & 0 deletions sources/leddevice/dev_spi/ProviderSpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ public slots:
// esp32 spi packet protocol
int writeBytesEsp32(unsigned size, const uint8_t* data);

// rp2040 spi packet protocol
int writeBytesRp2040(unsigned size, const uint8_t* data);

/// The name of the output device
QString _deviceName;

Expand Down
4 changes: 2 additions & 2 deletions sources/leddevice/schemas/schema-awa_spi.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@
"spitype": {
"type": "string",
"title":"edt_conf_smooth_type_title",
"enum" : ["esp8266","esp32","standard"],
"enum" : ["esp8266","esp32","rp2040","standard"],
"options" : {
"enum_titles" : ["esp8266","esp32","standard"]
"enum_titles" : ["esp8266","esp32","Raspberry Pi Pico (rp2040)","standard"]
},
"default" : "esp8266",
"required" : true,
Expand Down