bloguetronica / cp2130-qt

A C++ class that uses libusb to interface with CP2130 devices. It can be used to configure the OTP ROM of such devices, as well as to control them. The class was made for Qt. If you wish to use a derived non-Qt version, please refer to https://github.com/bloguetronica/cp2130.
0 stars 0 forks source link

Implement spiWriteRead() #19

Closed samuelfmlourenco closed 2 years ago

samuelfmlourenco commented 2 years ago

This function is to be implemented in the upcoming version 2.2.0. Its purpose is to write to the SPI bus while reading back.

samuelfmlourenco commented 2 years ago

Implemented in version 2.2.0. Code as follows:

// Writes to the SPI bus while reading back, returning a vector of the same size as the one given
// This is the prefered method of writing and reading, if both endpoint addresses are known
QVector<quint8> CP2130::spiWriteRead(const QVector<quint8> &data, quint8 endpointInAddr, quint8 endpointOutAddr, int &errcnt, QString &errstr)
{
    size_t bytesToWriteRead = static_cast<size_t>(data.size());
    size_t bytesLeft = bytesToWriteRead;
    QVector<quint8> retdata;
    while (bytesLeft > 0) {
        int payload = bytesLeft > 56 ? 56 : bytesLeft;
        int bufsize = payload + 8;
        unsigned char *writeReadCommandBuffer = new unsigned char[bufsize] {
            0x00, 0x00,         // Reserved
            CP2130::WRITEREAD,  // WriteRead command
            0x00,               // Reserved
            static_cast<quint8>(payload),
            static_cast<quint8>(payload >> 8),
            static_cast<quint8>(payload >> 16),
            static_cast<quint8>(payload >> 24)
        };
        for (int i = 0; i < payload; ++i) {
            writeReadCommandBuffer[i + 8] = data[bytesToWriteRead - bytesLeft + i];
        }
#if LIBUSB_API_VERSION >= 0x01000105
        bulkTransfer(endpointOutAddr, writeReadCommandBuffer, bufsize, nullptr, errcnt, errstr);
#else
        int bytesWritten;
        bulkTransfer(endpointOutAddr, writeReadCommandBuffer, bufsize, &bytesWritten, errcnt, errstr);
#endif
        delete[] writeReadCommandBuffer;
        unsigned char *writeReadInputBuffer = new unsigned char[payload];
        int bytesRead = 0;  // Important!
        bulkTransfer(endpointInAddr, writeReadInputBuffer, payload, &bytesRead, errcnt, errstr);
        for (int i = 0; i < bytesRead; ++i) {
            retdata += writeReadInputBuffer[i];
        }
        delete[] writeReadInputBuffer;
        bytesLeft -= payload;
    }
    return retdata;
}

// This function is a shorthand version of the previous one (both endpoint addresses are automatically deduced, at the cost of decreased speed)
QVector<quint8> CP2130::spiWriteRead(const QVector<quint8> &data, int &errcnt, QString &errstr)
{
    return spiWriteRead(data, getEndpointInAddr(errcnt, errstr), getEndpointOutAddr(errcnt, errstr), errcnt, errstr);
}