@@ -840,97 +840,185 @@ void handleGnssDataTask(void *e)
840840 {
841841 markSemaphore (FUNCTION_WRITESD);
842842
843- // Reduce bytes to record if we have more then the end of the buffer
844- if ((sdRingBufferTail + bytesToSend) > settings.gnssHandlerBufferSize )
845- bytesToSend = settings.gnssHandlerBufferSize - sdRingBufferTail;
846-
847- if (settings.enablePrintSDBuffers && (!inMainMenu))
843+ do // Do the SD write in a do loop so we can break out if needed
848844 {
849- int bufferAvailable;
850- if (USE_I2C_GNSS)
851- bufferAvailable = serialGNSS.available ();
852- else
845+ if (settings.enablePrintSDBuffers && (!inMainMenu))
853846 {
854- theGNSS.checkUblox ();
855- bufferAvailable = theGNSS.fileBufferAvailable ();
847+ int bufferAvailable;
848+ if (USE_I2C_GNSS)
849+ bufferAvailable = serialGNSS.available ();
850+ else
851+ {
852+ theGNSS.checkUblox ();
853+ bufferAvailable = theGNSS.fileBufferAvailable ();
854+ }
855+ int availableUARTSpace;
856+ if (USE_I2C_GNSS)
857+ availableUARTSpace = settings.uartReceiveBufferSize - bufferAvailable;
858+ else
859+ // Use gnssHandlerBufferSize for now. TODO: work out if the SPI GNSS needs its own buffer
860+ // size setting
861+ availableUARTSpace = settings.gnssHandlerBufferSize - bufferAvailable;
862+ systemPrintf (" SD Incoming Serial: %04d\t ToRead: %04d\t MovedToBuffer: %04d\t availableUARTSpace: "
863+ " %04d\t availableHandlerSpace: %04d\t ToRecord: %04d\t Recorded: %04d\t BO: %d\r\n " ,
864+ bufferAvailable, 0 , 0 , availableUARTSpace, availableHandlerSpace, bytesToSend, 0 ,
865+ bufferOverruns);
856866 }
857- int availableUARTSpace;
858- if (USE_I2C_GNSS)
859- availableUARTSpace = settings.uartReceiveBufferSize - bufferAvailable;
860- else
861- // Use gnssHandlerBufferSize for now. TODO: work out if the SPI GNSS needs its own buffer
862- // size setting
863- availableUARTSpace = settings.gnssHandlerBufferSize - bufferAvailable;
864- systemPrintf (" SD Incoming Serial: %04d\t ToRead: %04d\t MovedToBuffer: %04d\t availableUARTSpace: "
865- " %04d\t availableHandlerSpace: %04d\t ToRecord: %04d\t Recorded: %04d\t BO: %d\r\n " ,
866- bufferAvailable, 0 , 0 , availableUARTSpace, availableHandlerSpace, bytesToSend, 0 ,
867- bufferOverruns);
868- }
869867
870- // Write the data to the file
871- long startTime = millis ();
872- startMillis = millis ();
868+ // For the SD card, we need to write everything we've got
869+ // to prevent the ARP Write and Events from gatecrashing...
870+
871+ int32_t sendTheseBytes = bytesToSend;
873872
874- bytesToSend = ubxFile->write (&ringBuffer[sdRingBufferTail], bytesToSend);
875- if (PERIODIC_DISPLAY (PD_SD_LOG_WRITE) && (bytesToSend > 0 ))
876- {
877- PERIODIC_CLEAR (PD_SD_LOG_WRITE);
878- systemPrintf (" SD %d bytes written to log file\r\n " , bytesToSend);
879- }
873+ // Reduce bytes to record if we have more then the end of the buffer
874+ if ((sdRingBufferTail + sendTheseBytes) > settings.gnssHandlerBufferSize )
875+ sendTheseBytes = settings.gnssHandlerBufferSize - sdRingBufferTail;
880876
881- static unsigned long lastFlush = 0 ;
882- if (USE_MMC_MICROSD)
883- {
884- if (millis () > (lastFlush + 250 )) // Flush every 250ms, not every write
877+ // Write the data to the file
878+ startMillis = millis ();
879+
880+ int32_t bytesSent = ubxFile->write (&ringBuffer[sdRingBufferTail], sendTheseBytes);
881+
882+ // Account for the sent data or dropped
883+ sdRingBufferTail += bytesSent;
884+ if (sdRingBufferTail >= settings.gnssHandlerBufferSize )
885+ sdRingBufferTail -= settings.gnssHandlerBufferSize ;
886+
887+ if (bytesSent != sendTheseBytes)
885888 {
886- ubxFile->flush ();
887- lastFlush += 250 ;
889+ systemPrintf (" SD write mismatch (1): wrote %d bytes of %d\r\n " ,
890+ bytesSent, sendTheseBytes);
891+ break ; // Exit the do loop
888892 }
889- }
890- fileSize = ubxFile->fileSize (); // Update file size
891893
892- sdFreeSpace -= bytesToSend; // Update remaining space on SD
894+ // If we have more data to write - and the first write was successful
895+ if (bytesToSend > sendTheseBytes)
896+ {
897+ sendTheseBytes = bytesToSend - sendTheseBytes;
893898
894- // Force file sync every 60s
895- if (millis () - lastUBXLogSyncTime > 60000 )
896- {
897- if (productVariant == RTK_SURVEYOR)
898- digitalWrite (pin_baseStatusLED,
899- !digitalRead (pin_baseStatusLED)); // Blink LED to indicate logging activity
899+ bytesSent = ubxFile->write (&ringBuffer[sdRingBufferTail], sendTheseBytes);
900900
901- ubxFile->sync ();
902- ubxFile->updateFileAccessTimestamp (); // Update the file access time & date
901+ // Account for the sent data or dropped
902+ sdRingBufferTail += bytesSent;
903+ if (sdRingBufferTail >= settings.gnssHandlerBufferSize ) // Should be redundant
904+ sdRingBufferTail -= settings.gnssHandlerBufferSize ;
903905
904- if (productVariant == RTK_SURVEYOR)
905- digitalWrite (pin_baseStatusLED,
906- !digitalRead (pin_baseStatusLED)); // Return LED to previous state
906+ if (bytesSent != sendTheseBytes)
907+ {
908+ systemPrintf (" SD write mismatch (2): wrote %d bytes of %d\r\n " ,
909+ bytesSent, sendTheseBytes);
910+ break ; // Exit the do loop
911+ }
912+ }
907913
908- lastUBXLogSyncTime = millis ();
909- }
914+ if (PERIODIC_DISPLAY (PD_SD_LOG_WRITE) && (bytesToSend > 0 ) && (!inMainMenu))
915+ {
916+ PERIODIC_CLEAR (PD_SD_LOG_WRITE);
917+ systemPrintf (" SD %d bytes written to log file\r\n " , bytesToSend);
918+ }
910919
911- // Remember the maximum transfer time
912- deltaMillis = millis () - startMillis;
913- if (maxMillis[RBC_SD_CARD] < deltaMillis)
914- maxMillis[RBC_SD_CARD] = deltaMillis;
915- long endTime = millis ();
920+ sdFreeSpace -= bytesToSend; // Update remaining space on SD
916921
917- if (settings.enablePrintBufferOverrun )
918- {
919- if (endTime - startTime > 150 )
920- systemPrintf (" Long Write! Time: %ld ms / Location: %ld / Recorded %d bytes / "
921- " spaceRemaining %d bytes\r\n " ,
922- endTime - startTime, fileSize, bytesToSend, combinedSpaceRemaining);
923- }
922+ // Record any pending trigger events
923+ if (newEventToRecord == true )
924+ {
925+ newEventToRecord = false ;
924926
925- xSemaphoreGive (sdCardSemaphore);
927+ if ((settings.enablePrintLogFileStatus ) && (!inMainMenu))
928+ systemPrintln (" Recording event" );
926929
927- // Account for the sent data or dropped
928- if (bytesToSend > 0 )
929- {
930- sdRingBufferTail += bytesToSend;
931- if (sdRingBufferTail >= settings.gnssHandlerBufferSize )
932- sdRingBufferTail -= settings.gnssHandlerBufferSize ;
933- }
930+ // Record trigger count with Time Of Week of rising edge (ms), Millisecond fraction of Time Of Week of
931+ // rising edge (ns), and accuracy estimate (ns)
932+ char eventData[82 ]; // Max NMEA sentence length is 82
933+ snprintf (eventData, sizeof (eventData), " %d,%d,%d,%d" , triggerCount, triggerTowMsR, triggerTowSubMsR,
934+ triggerAccEst);
935+
936+ char nmeaMessage[82 ]; // Max NMEA sentence length is 82
937+ createNMEASentence (CUSTOM_NMEA_TYPE_EVENT, nmeaMessage, sizeof (nmeaMessage),
938+ eventData); // textID, buffer, sizeOfBuffer, text
939+
940+ ubxFile->write ((const uint8_t *)nmeaMessage, strlen (nmeaMessage));
941+ const char *crlf = " \r\n " ;
942+ ubxFile->write ((const uint8_t *)crlf, 2 );
943+
944+ sdFreeSpace -= strlen (nmeaMessage) + 2 ; // Update remaining space on SD
945+ }
946+
947+ // Record the Antenna Reference Position - if available
948+ if (newARPAvailable == true && settings.enableARPLogging &&
949+ ((millis () - lastARPLog) > (settings.ARPLoggingInterval_s * 1000 )))
950+ {
951+ lastARPLog = millis ();
952+ newARPAvailable = false ;
953+
954+ double x = ARPECEFX;
955+ x /= 10000.0 ; // Convert to m
956+ double y = ARPECEFY;
957+ y /= 10000.0 ; // Convert to m
958+ double z = ARPECEFZ;
959+ z /= 10000.0 ; // Convert to m
960+ double h = ARPECEFH;
961+ h /= 10000.0 ; // Convert to m
962+ char ARPData[82 ]; // Max NMEA sentence length is 82
963+ snprintf (ARPData, sizeof (ARPData), " %.4f,%.4f,%.4f,%.4f" , x, y, z, h);
964+
965+ if ((settings.enablePrintLogFileStatus ) && (!inMainMenu))
966+ systemPrintf (" Recording Antenna Reference Position %s\r\n " , ARPData);
967+
968+ char nmeaMessage[82 ]; // Max NMEA sentence length is 82
969+ createNMEASentence (CUSTOM_NMEA_TYPE_ARP_ECEF_XYZH, nmeaMessage, sizeof (nmeaMessage),
970+ ARPData); // textID, buffer, sizeOfBuffer, text
971+
972+ ubxFile->write ((const uint8_t *)nmeaMessage, strlen (nmeaMessage));
973+ const char *crlf = " \r\n " ;
974+ ubxFile->write ((const uint8_t *)crlf, 2 );
975+
976+ sdFreeSpace -= strlen (nmeaMessage) + 2 ; // Update remaining space on SD
977+ }
978+
979+ static unsigned long lastFlush = 0 ;
980+ if (USE_MMC_MICROSD)
981+ {
982+ if (millis () > (lastFlush + 250 )) // Flush every 250ms, not every write
983+ {
984+ ubxFile->flush ();
985+ lastFlush += 250 ;
986+ }
987+ }
988+ fileSize = ubxFile->fileSize (); // Update file size
989+
990+ // Force file sync every 60s
991+ if (millis () - lastUBXLogSyncTime > 60000 )
992+ {
993+ if (productVariant == RTK_SURVEYOR)
994+ digitalWrite (pin_baseStatusLED,
995+ !digitalRead (pin_baseStatusLED)); // Blink LED to indicate logging activity
996+
997+ ubxFile->sync ();
998+ ubxFile->updateFileAccessTimestamp (); // Update the file access time & date
999+
1000+ if (productVariant == RTK_SURVEYOR)
1001+ digitalWrite (pin_baseStatusLED,
1002+ !digitalRead (pin_baseStatusLED)); // Return LED to previous state
1003+
1004+ lastUBXLogSyncTime = millis ();
1005+ }
1006+
1007+ // Remember the maximum transfer time
1008+ deltaMillis = millis () - startMillis;
1009+ if (maxMillis[RBC_SD_CARD] < deltaMillis)
1010+ maxMillis[RBC_SD_CARD] = deltaMillis;
1011+
1012+ if (settings.enablePrintBufferOverrun )
1013+ {
1014+ if (deltaMillis > 150 )
1015+ systemPrintf (" Long Write! Time: %ld ms / Location: %ld / Recorded %d bytes / "
1016+ " spaceRemaining %d bytes\r\n " ,
1017+ deltaMillis, fileSize, bytesToSend, combinedSpaceRemaining);
1018+ }
1019+ } while (0 );
1020+
1021+ xSemaphoreGive (sdCardSemaphore);
9341022 } // End sdCardSemaphore
9351023 else
9361024 {
0 commit comments