@@ -33,15 +33,17 @@ void F9PSerialWriteTask(void *e)
3333// Task for reading data from the GNSS receiver.
3434void F9PSerialReadTask (void *e)
3535{
36- int btConnected; // Is the RTK in a state to send Bluetooth data?
37- int btData; // Amount of buffered Bluetooth data
38- int length;
3936 static uint8_t rBuffer[SERIAL_SIZE_RX]; // Buffer for reading from F9P to SPP
40- static uint16_t rBufferBtOffset; // Removal offset for Bluetooth
41- static uint16_t rBufferFillOffset; // Fill offset for serial data
42- static uint16_t rBufferSdOffset; // Removal offset for microSD card logging
43- int s;
44- int sdData; // Amount of buffered microSD card logging data
37+ static uint16_t dataHead = 0 ; // Head advances as data comes in from GNSS's UART
38+ static uint16_t btTail = 0 ; // BT Tail advances as it is sent over BT
39+ static uint16_t sdTail = 0 ; // SD Tail advances as it is recorded to SD
40+
41+ int btBytesToSend; // Amount of buffered Bluetooth data
42+ int sdBytesToRecord; // Amount of buffered microSD card logging data
43+ int availableBufferSpace; // Distance between head and furthest away tail
44+
45+ int btConnected; // Is the RTK in a state to send Bluetooth data?
46+ int newBytesToRecord; // Size of data from GNSS
4547
4648 while (true )
4749 {
@@ -55,128 +57,147 @@ void F9PSerialReadTask(void *e)
5557 // approximately 2 seconds worth of data. Bluetooth congestion or conflicts
5658 // with the SD card semaphore should clear within this time. At 57600 baud
5759 // the Bluetooth UART is able to send 7200 characters a second. With a 10
58- // mSec delay this rouitne runs approximately 100 times per second providing
60+ // mSec delay this routine runs approximately 100 times per second providing
5961 // multiple chances to empty the buffer.
6062 //
61- // Ring buffer empty when (rBufferFillOffset == rBufferBtOffset) and
62- // (rBufferFillOffset == rBufferSdOffset)
63+ // Ring buffer empty when (dataHead == btTail) and (dataHead == sdTail)
6364 //
6465 // +---------+
6566 // | |
6667 // | |
6768 // | |
6869 // | |
69- // +---------+ <-- rBufferFillOffset, rBufferBtOffset, rBufferSdOffset
70+ // +---------+ <-- dataHead, btTail, sdTail
7071 //
71- // Ring buffer contains data when (rBufferFillOffset != rBufferBtOffset) or
72- // (rBufferFillOffset != rBufferSdOffset)
72+ // Ring buffer contains data when (dataHead != btTail) or (dataHead != sdTail)
7373 //
7474 // +---------+
7575 // | |
7676 // | |
77- // | yyyyyyy | <-- rBufferFillOffset
78- // | xxxxxxx | <-- rBufferBtOffset (1 byte in buffer)
79- // +---------+ <-- rBufferSdOffset (2 bytes in buffer)
77+ // | yyyyyyy | <-- dataHead
78+ // | xxxxxxx | <-- btTail (1 byte in buffer)
79+ // +---------+ <-- sdTail (2 bytes in buffer)
8080 //
8181 // +---------+
82- // | yyyyyyy | <-- rBufferBtOffset (1 byte in buffer)
83- // | xxxxxxx | <-- rBufferSdOffset (2 bytes in buffer)
82+ // | yyyyyyy | <-- btTail (1 byte in buffer)
83+ // | xxxxxxx | <-- sdTail (2 bytes in buffer)
8484 // | |
8585 // | |
86- // +---------+ <-- rBufferFillOffset
86+ // +---------+ <-- dataHead
8787 //
8888 // Maximum ring buffer fill is sizeof(rBuffer) - 1
8989 // ----------------------------------------------------------------------
9090
91- // Determine the amount of Bluetooth data in the buffer
92- length = sizeof (rBuffer);
93- btData = 0 ;
91+ availableBufferSpace = sizeof (rBuffer);
92+
93+ // Determine BT connection state
9494 btConnected = (bluetoothGetState () == BT_CONNECTED)
95- && (systemState != STATE_BASE_TEMP_SETTLE)
96- && (systemState != STATE_BASE_TEMP_SURVEY_STARTED);
95+ && (systemState != STATE_BASE_TEMP_SETTLE)
96+ && (systemState != STATE_BASE_TEMP_SURVEY_STARTED);
97+
98+ // Determine the amount of Bluetooth data in the buffer
99+ btBytesToSend = 0 ;
97100 if (btConnected)
98101 {
99- btData = rBufferFillOffset - rBufferBtOffset;
100- if (btData < 0 )
101- btData += sizeof (rBuffer);
102- length = sizeof (rBuffer) - btData;
102+ btBytesToSend = dataHead - btTail;
103+ if (btBytesToSend < 0 )
104+ btBytesToSend += sizeof (rBuffer);
103105 }
106+ Serial.printf (" btBytesToSend: %d " , btBytesToSend);
104107
105108 // Determine the amount of microSD card logging data in the buffer
106- sdData = 0 ;
109+ sdBytesToRecord = 0 ;
107110 if (online.logging )
108111 {
109- sdData = rBufferFillOffset - rBufferSdOffset;
110- if (sdData < 0 )
111- sdData += sizeof (rBuffer);
112- if (length > (sizeof (rBuffer) - sdData))
113- length = sizeof (rBuffer) - sdData;
112+ sdBytesToRecord = dataHead - sdTail;
113+ if (sdBytesToRecord < 0 )
114+ sdBytesToRecord += sizeof (rBuffer);
114115 }
116+ Serial.printf (" sdBytesToRecord: %d " , sdBytesToRecord);
115117
116118 // Determine the free bytes in the buffer
119+ if (btBytesToSend >= sdBytesToRecord)
120+ availableBufferSpace = sizeof (rBuffer) - btBytesToSend;
121+ else
122+ availableBufferSpace = sizeof (rBuffer) - sdBytesToRecord;
123+
124+ Serial.printf (" pure: %d " , availableBufferSpace);
125+
117126 // Don't fill the last byte to prevent buffer overflow
118- if (length)
119- length -= 1 ;
127+ if (availableBufferSpace)
128+ availableBufferSpace -= 1 ;
129+
130+ Serial.printf (" protected: %d " , availableBufferSpace);
120131
121132 // Fill the buffer to the end and then start at the beginning
122- if ((rBufferFillOffset + length ) > sizeof (rBuffer))
123- length = sizeof (rBuffer) - rBufferFillOffset ;
133+ if ((dataHead + availableBufferSpace ) > sizeof (rBuffer))
134+ availableBufferSpace = sizeof (rBuffer) - dataHead ;
124135
125- // Read more data from the GNSS into the buffer
126- s = 0 ;
127- if (length)
128- s = serialGNSS.readBytes (rBuffer, length);
136+ Serial.printf (" trimmed: %d " , availableBufferSpace);
129137
130- // Account for the bytes read
131- if (s > 0 )
138+ // If we have buffer space, read data from the GNSS into the buffer
139+ newBytesToRecord = 0 ;
140+ if (availableBufferSpace)
141+ {
142+ // Add new data into circular buffer in front of the head
143+ // availableBufferSpace is already reduced to avoid buffer overflow
144+ newBytesToRecord = serialGNSS.readBytes (&rBuffer[dataHead], availableBufferSpace);
145+ }
146+
147+ // Account for the byte read
148+ if (newBytesToRecord > 0 )
132149 {
133150 // Set the next fill offset
134- rBufferFillOffset += s ;
135- if (rBufferFillOffset >= sizeof (rBuffer))
136- rBufferFillOffset -= sizeof (rBuffer);
151+ dataHead += newBytesToRecord ;
152+ if (dataHead >= sizeof (rBuffer))
153+ dataHead -= sizeof (rBuffer);
137154
138155 // Account for the new data
139156 if (btConnected)
140- btData += s ;
157+ btBytesToSend += newBytesToRecord ;
141158 if (online.logging )
142- sdData += s ;
159+ sdBytesToRecord += newBytesToRecord ;
143160 }
144161
162+ Serial.printf (" btBytesToSend: %d " , btBytesToSend);
163+ Serial.printf (" sdBytesToRecord: %d " , sdBytesToRecord);
164+
165+ Serial.println ();
166+
145167 // ----------------------------------------------------------------------
146168 // Send data over Bluetooth
147169 // ----------------------------------------------------------------------
148170
149171 // If we are actively survey-in then do not pass NMEA data from ZED to phone
150- if (!btData )
172+ if (!btConnected )
151173 // Discard the data
152- rBufferBtOffset = rBufferFillOffset ;
174+ btTail = dataHead ;
153175 else
154176 {
155- // Fill the buffer to the end and then start at the beginning
156- length = btData;
157- if ((rBufferBtOffset + length ) > sizeof (rBuffer))
158- length = sizeof (rBuffer) - rBufferBtOffset ;
177+ // Reduce bytes to send if we have more to send then the end of the buffer
178+ // We'll wrap next loop
179+ if ((btTail + btBytesToSend ) > sizeof (rBuffer))
180+ btBytesToSend = sizeof (rBuffer) - btTail ;
159181
160182 if ((bluetoothIsCongested () == false ) || (settings.throttleDuringSPPCongestion == false ))
161183 {
162184 // Push new data to BT SPP if not congested or not throttling
163- length = bluetoothWriteBytes (&rBuffer[rBufferBtOffset ], length );
185+ btBytesToSend = bluetoothWriteBytes (&rBuffer[btTail ], btBytesToSend );
164186 online.txNtripDataCasting = true ;
165187 }
166188 else
167189 {
168190 // Don't push data to BT SPP if there is congestion to prevent heap hits.
169- if (btData < (sizeof (rBuffer) - 1 ))
170- length = 0 ;
191+ if (btBytesToSend < (sizeof (rBuffer) - 1 ))
192+ btBytesToSend = 0 ;
171193 else
172- Serial.printf (" ERROR - Congestion, dropped %d bytes: GNSS --> Bluetooth\r\n " , length );
194+ Serial.printf (" ERROR - Congestion, dropped %d bytes: GNSS --> Bluetooth\r\n " , btBytesToSend );
173195 }
174196
175197 // Account for the sent data or dropped
176- // Set the next removal offset
177- rBufferBtOffset += length;
178- if (rBufferBtOffset >= sizeof (rBuffer))
179- rBufferBtOffset -= sizeof (rBuffer);
198+ btTail += btBytesToSend;
199+ if (btTail >= sizeof (rBuffer))
200+ btTail -= sizeof (rBuffer);
180201 }
181202
182203 // ----------------------------------------------------------------------
@@ -186,7 +207,7 @@ void F9PSerialReadTask(void *e)
186207 // If user wants to log, record to SD
187208 if (!online.logging )
188209 // Discard the data
189- rBufferSdOffset = rBufferFillOffset ;
210+ sdTail = dataHead ;
190211 else
191212 {
192213 // Check if we are inside the max time window for logging
@@ -196,29 +217,29 @@ void F9PSerialReadTask(void *e)
196217 // writing from other functions like recordSystemSettingsToFile()
197218 if (xSemaphoreTake (sdCardSemaphore, fatSemaphore_shortWait_ms) == pdPASS)
198219 {
199- // Fill the buffer to the end and then start at the beginning
200- length = sdData;
201- if ((rBufferSdOffset + length ) > sizeof (rBuffer))
202- length = sizeof (rBuffer) - rBufferSdOffset ;
220+ // Reduce bytes to send if we have more to send then the end of the buffer
221+ // We'll wrap next loop
222+ if ((sdTail + sdBytesToRecord ) > sizeof (rBuffer))
223+ sdBytesToRecord = sizeof (rBuffer) - sdTail ;
203224
204225 // Write the data to the file
205- length = ubxFile->write (rBuffer, length );
226+ sdBytesToRecord = ubxFile->write (rBuffer, sdBytesToRecord );
206227 xSemaphoreGive (sdCardSemaphore);
207228
208229 // Account for the sent data or dropped
209- rBufferSdOffset += length ;
210- if (rBufferSdOffset >= sizeof (rBuffer))
211- rBufferSdOffset -= sizeof (rBuffer);
230+ sdTail += sdBytesToRecord ;
231+ if (sdTail >= sizeof (rBuffer))
232+ sdTail -= sizeof (rBuffer);
212233 } // End sdCardSemaphore
213234 else
214235 {
215236 // Retry the semaphore a little later if possible
216- if (sdData == (sizeof (rBuffer) - 1 ))
237+ if (sdBytesToRecord == (sizeof (rBuffer) - 1 ))
217238 {
218239 // Error - no more room in the buffer, drop a buffer's worth of data
219- rBufferSdOffset = rBufferFillOffset ;
240+ sdTail = dataHead ;
220241 log_e (" ERROR - sdCardSemaphore failed to yield, Tasks.ino line %d\r\n " , __LINE__);
221- Serial.printf (" ERROR - Dropped %d bytes: GNSS --> log file\r\n " , sdData );
242+ Serial.printf (" ERROR - Dropped %d bytes: GNSS --> log file\r\n " , sdBytesToRecord );
222243 }
223244 else
224245 log_w (" WARNING - sdCardSemaphore failed to yield, Tasks.ino line %d\r\n " , __LINE__);
@@ -231,7 +252,7 @@ void F9PSerialReadTask(void *e)
231252 // Let other tasks run, prevent watch dog timer (WDT) resets
232253 // ----------------------------------------------------------------------
233254
234- delay (10 );
255+ delay (50 );
235256 }
236257}
237258
@@ -623,7 +644,7 @@ void idleTask(void *e)
623644
624645 // Display the high water mark if requested
625646 if ((settings.enableTaskReports == true )
626- && ((millis () - lastStackPrintTime) >= (IDLE_TIME_DISPLAY_SECONDS * 1000 )))
647+ && ((millis () - lastStackPrintTime) >= (IDLE_TIME_DISPLAY_SECONDS * 1000 )))
627648 {
628649 lastStackPrintTime = millis ();
629650 Serial.printf (" idleTask %d High watermark: %d\n\r " ,
0 commit comments