diff --git a/keywords.txt b/keywords.txt index b2b7cab..831b4c2 100644 --- a/keywords.txt +++ b/keywords.txt @@ -66,6 +66,7 @@ disableUBX7Fcheck KEYWORD2 checkUblox KEYWORD2 checkUbloxI2C KEYWORD2 checkUbloxSerial KEYWORD2 +checkUbloxSPI KEYWORD2 process KEYWORD2 processNMEA KEYWORD2 diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp index ae80176..c50645b 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp @@ -452,12 +452,15 @@ boolean SFE_UBLOX_GNSS::begin(Stream &serialPort) } // Initialize for SPI -boolean SFE_UBLOX_GNSS::begin(SPIClass &spiPort, uint8_t ssPin, int spiSpeed) +boolean SFE_UBLOX_GNSS::begin(SPIClass &spiPort, uint8_t csPin, uint32_t spiSpeed) { commType = COMM_TYPE_SPI; _spiPort = &spiPort; - _ssPin = ssPin; + _csPin = csPin; _spiSpeed = spiSpeed; + // Initialize the chip select pin + pinMode(_csPin, OUTPUT); + digitalWrite(_csPin, HIGH); //New in v2.0: allocate memory for the packetCfg payload here - if required. (The user may have called setPacketCfgPayloadSize already) if (packetCfgPayloadSize == 0) setPacketCfgPayloadSize(MAX_PAYLOAD_SIZE); @@ -790,32 +793,22 @@ boolean SFE_UBLOX_GNSS::checkUbloxSerial(ubxPacket *incomingUBX, uint8_t request //Checks SPI for data, passing any new bytes to process() boolean SFE_UBLOX_GNSS::checkUbloxSpi(ubxPacket *incomingUBX, uint8_t requestedClass, uint8_t requestedID) { - // process the contents of the SPI buffer if not empty! - uint8_t bufferByte = spiBuffer[0]; - uint8_t bufferIndex = 0; - - while (bufferByte != 0xFF) { - process(bufferByte, incomingUBX, requestedClass, requestedID); - bufferIndex++; - bufferByte = spiBuffer[bufferIndex]; + // Process the contents of the SPI buffer if not empty! + for (uint8_t i = 0; i < spiBufferIndex; i++) { + process(spiBuffer[i], incomingUBX, requestedClass, requestedID); } - - // reset the contents of the SPI buffer - for(uint8_t i = 0; i < bufferIndex; i++) - { - spiBuffer[i] = 0xFF; - } - + spiBufferIndex = 0; + SPISettings settingsA(_spiSpeed, MSBFIRST, SPI_MODE0); _spiPort->beginTransaction(settingsA); - digitalWrite(_ssPin, LOW); + digitalWrite(_csPin, LOW); uint8_t byteReturned = _spiPort->transfer(0x0A); while (byteReturned != 0xFF || currentSentence != NONE) { process(byteReturned, incomingUBX, requestedClass, requestedID); byteReturned = _spiPort->transfer(0x0A); } - digitalWrite(_ssPin, HIGH); + digitalWrite(_csPin, HIGH); _spiPort->endTransaction(); return (true); @@ -2858,7 +2851,7 @@ void SFE_UBLOX_GNSS::sendSerialCommand(ubxPacket *outgoingUBX) void SFE_UBLOX_GNSS::spiTransfer(uint8_t byteToTransfer) { uint8_t returnedByte = _spiPort->transfer(byteToTransfer); - if (returnedByte != 0xFF) + if (returnedByte != 0xFF || currentSentence != NONE) { spiBuffer[spiBufferIndex] = returnedByte; spiBufferIndex++; @@ -2868,9 +2861,24 @@ void SFE_UBLOX_GNSS::spiTransfer(uint8_t byteToTransfer) // Send a command via SPI void SFE_UBLOX_GNSS::sendSpiCommand(ubxPacket *outgoingUBX) { + if (spiBuffer == NULL) //Memory has not yet been allocated - so use new + { + spiBuffer = new uint8_t[SPI_BUFFER_SIZE]; + } + + if (spiBuffer == NULL) { + if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging + { + _debugSerial->print(F("process: memory allocation failed for SPI Buffer!")); + } + } + + // Start at the beginning of the SPI buffer + spiBufferIndex = 0; + SPISettings settingsA(_spiSpeed, MSBFIRST, SPI_MODE0); _spiPort->beginTransaction(settingsA); - digitalWrite(_ssPin, LOW); + digitalWrite(_csPin, LOW); //Write header bytes spiTransfer(UBX_SYNCH_1); //μ - oh ublox, you're funny. I will call you micro-blox from now on. if (_printDebug) _debugSerial->printf("%x ", UBX_SYNCH_1); @@ -2898,7 +2906,7 @@ void SFE_UBLOX_GNSS::sendSpiCommand(ubxPacket *outgoingUBX) if (_printDebug) _debugSerial->printf("%x ", outgoingUBX->checksumA); spiTransfer(outgoingUBX->checksumB); if (_printDebug) _debugSerial->printf("%x \n", outgoingUBX->checksumB); - digitalWrite(_ssPin, HIGH); + digitalWrite(_csPin, HIGH); _spiPort->endTransaction(); } diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.h b/src/SparkFun_u-blox_GNSS_Arduino_Library.h index 015ba3f..6f75034 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.h +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.h @@ -494,6 +494,9 @@ enum sfe_ublox_ls_src_e //#define MAX_PAYLOAD_SIZE 768 //Worst case: UBX_CFG_VALSET packet with 64 keyIDs each with 64 bit values #endif +// For storing SPI bytes received during sendSpiCommand +#define SPI_BUFFER_SIZE 128 + //-=-=-=-=- UBX binary specific variables struct ubxPacket { @@ -562,8 +565,8 @@ public: boolean begin(TwoWire &wirePort = Wire, uint8_t deviceAddress = 0x42); //Returns true if module is detected //serialPort needs to be perviously initialized to correct baud rate boolean begin(Stream &serialPort); //Returns true if module is detected - //SPI - supply instance of SPIClass, slave select pin and SPI speed (in Hz) - boolean begin(SPIClass &spiPort, uint8_t ssPin, int spiSpeed); + //SPI - supply instance of SPIClass, chip select pin and SPI speed (in Hz) + boolean begin(SPIClass &spiPort, uint8_t csPin, uint32_t spiSpeed); void end(void); //Stop all automatic message processing. Free all used RAM @@ -1283,7 +1286,7 @@ private: Stream *_debugSerial; //The stream to send debug messages to if enabled SPIClass *_spiPort; //The instance of SPIClass - uint8_t _ssPin; //The slave select pin + uint8_t _csPin; //The chip select pin int _spiSpeed; //The speed to use for SPI (Hz) uint8_t _gpsI2Caddress = 0x42; //Default 7-bit unshifted address of the ublox 6/7/8/M8/F9 series @@ -1305,8 +1308,8 @@ private: uint8_t *payloadCfg = NULL; uint8_t *payloadAuto = NULL; - uint8_t spiBuffer[20]; // A small buffer to store any bytes being recieved back from the device while we are sending via SPI - uint8_t spiBufferIndex = 0; // The index into the SPI buffer + uint8_t *spiBuffer = NULL; // A buffer to store any bytes being recieved back from the device while we are sending via SPI + uint8_t spiBufferIndex = 0; // Index into the SPI buffer //Init the packet structures and init them with pointers to the payloadAck, payloadCfg, payloadBuf and payloadAuto arrays ubxPacket packetAck = {0, 0, 0, 0, 0, payloadAck, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED};