[MOD] Added stream SPI transfer
This commit is contained in:
parent
455ce12eed
commit
e07d1d9dc1
2 changed files with 166 additions and 0 deletions
126
src/Module.cpp
126
src/Module.cpp
|
@ -253,6 +253,132 @@ void Module::SPItransfer(uint8_t cmd, uint8_t reg, uint8_t* dataOut, uint8_t* da
|
|||
this->SPIendTransaction();
|
||||
}
|
||||
|
||||
int16_t Module::SPItransferStream(uint8_t* cmd, uint8_t cmdLen, bool write, uint8_t* dataOut, uint8_t* dataIn, uint8_t numBytes, bool waitForGpio, uint32_t timeout) {
|
||||
#if defined(RADIOLIB_VERBOSE)
|
||||
uint8_t debugBuff[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#endif
|
||||
|
||||
// pull NSS low
|
||||
this->digitalWrite(this->getCs(), LOW);
|
||||
|
||||
// ensure GPIO is low
|
||||
uint32_t start = this->millis();
|
||||
while(this->digitalRead(this->getGpio())) {
|
||||
this->yield();
|
||||
if(this->millis() - start >= timeout) {
|
||||
this->digitalWrite(this->getCs(), HIGH);
|
||||
return(RADIOLIB_ERR_SPI_CMD_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
// start transfer
|
||||
this->SPIbeginTransaction();
|
||||
|
||||
// send command byte(s)
|
||||
for(uint8_t n = 0; n < cmdLen; n++) {
|
||||
this->SPItransfer(cmd[n]);
|
||||
}
|
||||
|
||||
// variable to save error during SPI transfer
|
||||
int16_t state = RADIOLIB_ERR_NONE;
|
||||
|
||||
// send/receive all bytes
|
||||
if(write) {
|
||||
for(uint8_t n = 0; n < numBytes; n++) {
|
||||
// send byte
|
||||
uint8_t in = this->SPItransfer(dataOut[n]);
|
||||
#if defined(RADIOLIB_VERBOSE)
|
||||
debugBuff[n] = in;
|
||||
#endif
|
||||
|
||||
// check status
|
||||
if(this->SPIparseStatusCb != nullptr) {
|
||||
state = this->SPIparseStatusCb(in);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// skip the first byte for read-type commands (status-only)
|
||||
uint8_t in = this->SPItransfer(this->SPIreadCommand);
|
||||
#if defined(RADIOLIB_VERBOSE)
|
||||
debugBuff[0] = in;
|
||||
#endif
|
||||
|
||||
// check status
|
||||
if(this->SPIparseStatusCb != nullptr) {
|
||||
state = this->SPIparseStatusCb(in);
|
||||
} else {
|
||||
state = RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
// read the data
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
for(uint8_t n = 0; n < numBytes; n++) {
|
||||
dataIn[n] = this->SPItransfer(this->SPIreadCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// stop transfer
|
||||
this->SPIendTransaction();
|
||||
this->digitalWrite(this->getCs(), HIGH);
|
||||
|
||||
// wait for GPIO to go high and then low
|
||||
if(waitForGpio) {
|
||||
this->delayMicroseconds(1);
|
||||
uint32_t start = this->millis();
|
||||
while(this->digitalRead(this->getGpio())) {
|
||||
this->yield();
|
||||
if(this->millis() - start >= timeout) {
|
||||
state = RADIOLIB_ERR_SPI_CMD_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// print debug output
|
||||
#if defined(RADIOLIB_VERBOSE)
|
||||
// print command byte(s)
|
||||
RADIOLIB_VERBOSE_PRINT("CMD\t");
|
||||
for(uint8_t n = 0; n < cmdLen; n++) {
|
||||
RADIOLIB_VERBOSE_PRINT(cmd[n], HEX);
|
||||
RADIOLIB_VERBOSE_PRINT('\t');
|
||||
}
|
||||
RADIOLIB_VERBOSE_PRINTLN();
|
||||
|
||||
// print data bytes
|
||||
RADIOLIB_VERBOSE_PRINT("DAT");
|
||||
if(write) {
|
||||
RADIOLIB_VERBOSE_PRINT("W\t");
|
||||
for(uint8_t n = 0; n < numBytes; n++) {
|
||||
RADIOLIB_VERBOSE_PRINT(dataOut[n], HEX);
|
||||
RADIOLIB_VERBOSE_PRINT('\t');
|
||||
RADIOLIB_VERBOSE_PRINT(debugBuff[n], HEX);
|
||||
RADIOLIB_VERBOSE_PRINT('\t');
|
||||
}
|
||||
RADIOLIB_VERBOSE_PRINTLN();
|
||||
} else {
|
||||
RADIOLIB_VERBOSE_PRINT("R\t");
|
||||
// skip the first byte for read-type commands (status-only)
|
||||
RADIOLIB_VERBOSE_PRINT(this->SPIreadCommand, HEX);
|
||||
RADIOLIB_VERBOSE_PRINT('\t');
|
||||
RADIOLIB_VERBOSE_PRINT(debugBuff[0], HEX);
|
||||
RADIOLIB_VERBOSE_PRINT('\t')
|
||||
|
||||
for(uint8_t n = 0; n < numBytes; n++) {
|
||||
RADIOLIB_VERBOSE_PRINT(this->SPIreadCommand, HEX);
|
||||
RADIOLIB_VERBOSE_PRINT('\t');
|
||||
RADIOLIB_VERBOSE_PRINT(dataIn[n], HEX);
|
||||
RADIOLIB_VERBOSE_PRINT('\t');
|
||||
}
|
||||
RADIOLIB_VERBOSE_PRINTLN();
|
||||
}
|
||||
RADIOLIB_VERBOSE_PRINTLN();
|
||||
#endif
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
void Module::waitForMicroseconds(uint32_t start, uint32_t len) {
|
||||
#if defined(RADIOLIB_INTERRUPT_TIMING)
|
||||
(void)start;
|
||||
|
|
40
src/Module.h
40
src/Module.h
|
@ -139,6 +139,23 @@ class Module {
|
|||
*/
|
||||
uint8_t SPIwriteCommand = 0b10000000;
|
||||
|
||||
/*!
|
||||
\brief Whether the SPI interface is stream-type (e.g. SX126x) or register-type (e.g. SX127x).
|
||||
Defaults to register-type SPI interfaces.
|
||||
*/
|
||||
bool SPIstreamType = false;
|
||||
|
||||
/*!
|
||||
\brief SPI status parsing callback typedef.
|
||||
*/
|
||||
typedef int16_t (*SPIparseStatusCb_t)(uint8_t in);
|
||||
|
||||
/*!
|
||||
\brief Callback to function that will parse the module-specific status codes to RadioLib status codes.
|
||||
Typically used for modules with SPI stream-type interface (e.g. SX126x/SX128x).
|
||||
*/
|
||||
SPIparseStatusCb_t SPIparseStatusCb = nullptr;
|
||||
|
||||
#if defined(RADIOLIB_INTERRUPT_TIMING)
|
||||
|
||||
/*!
|
||||
|
@ -259,6 +276,29 @@ class Module {
|
|||
*/
|
||||
void SPItransfer(uint8_t cmd, uint8_t reg, uint8_t* dataOut, uint8_t* dataIn, uint8_t numBytes);
|
||||
|
||||
/*!
|
||||
\brief SPI single transfer method for modules with stream-type SPI interface (SX126x, SX128x etc.).
|
||||
|
||||
\param cmd SPI operation command.
|
||||
|
||||
\param cmd SPI command length in bytes.
|
||||
|
||||
\param write Set to true for write commands, false for read commands.
|
||||
|
||||
\param dataOut Data that will be transfered from master to slave.
|
||||
|
||||
\param dataIn Data that was transfered from slave to master.
|
||||
|
||||
\param numBytes Number of bytes to transfer.
|
||||
|
||||
\param waitForGpio Whether to wait for some GPIO at the end of transfer (e.g. BUSY line on SX126x/SX128x).
|
||||
|
||||
\param timeout GPIO wait period timeout in milliseconds.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t SPItransferStream(uint8_t* cmd, uint8_t cmdLen, bool write, uint8_t* dataOut, uint8_t* dataIn, uint8_t numBytes, bool waitForGpio, uint32_t timeout);
|
||||
|
||||
// pin number access methods
|
||||
|
||||
/*!
|
||||
|
|
Loading…
Add table
Reference in a new issue