Skip to content

Commit 1dad275

Browse files
committed
Move hardware interrupt core assignment to NVM.
1 parent f551d7b commit 1dad275

File tree

6 files changed

+111
-37
lines changed

6 files changed

+111
-37
lines changed

Firmware/RTK_Surveyor/Begin.ino

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -557,14 +557,15 @@ void beginUART2()
557557
2000, // Stack Size
558558
nullptr, // Task input parameter
559559
0, // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest
560-
&pinUART2TaskHandle, // Task handle
561-
0); // Core where task should run, 0=core, 1=Arduino
560+
&pinUART2TaskHandle, // Task handle
561+
settings.gnssUartInterruptsCore); // Core where task should run, 0=core, 1=Arduino
562562

563563
while (uart2pinned == false) // Wait for task to run once
564564
delay(1);
565565
}
566566

567-
// Assign UART2 interrupts to the core 0. See: https://github.com/espressif/arduino-esp32/issues/3386
567+
// Assign UART2 interrupts to the core that started the task. See:
568+
// https://github.com/espressif/arduino-esp32/issues/3386
568569
void pinUART2Task(void *pvParameters)
569570
{
570571
// Note: ESP32 2.0.6 does some strange auto-bauding thing here which takes 20s to complete if there is no data for
@@ -1150,7 +1151,24 @@ void beginIdleTasks()
11501151

11511152
void beginI2C()
11521153
{
1153-
Wire.begin(); // Start I2C on core 1
1154+
if (pinI2CTaskHandle == nullptr)
1155+
xTaskCreatePinnedToCore(
1156+
pinI2CTask,
1157+
"I2CStart", // Just for humans
1158+
2000, // Stack Size
1159+
nullptr, // Task input parameter
1160+
0, // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest
1161+
&pinI2CTaskHandle, // Task handle
1162+
settings.i2cInterruptsCore); // Core where task should run, 0=core, 1=Arduino
1163+
1164+
while (i2cPinned == false) // Wait for task to run once
1165+
delay(1);
1166+
}
1167+
1168+
// Assign I2C interrupts to the core that started the task. See: https://github.com/espressif/arduino-esp32/issues/3386
1169+
void pinI2CTask(void *pvParameters)
1170+
{
1171+
Wire.begin(); // Start I2C on core the core that was chosen when the task was started
11541172
// Wire.setClock(400000);
11551173

11561174
// begin/end wire transmission to see if bus is responding correctly
@@ -1166,6 +1184,10 @@ void beginI2C()
11661184
online.i2c = true;
11671185
else
11681186
systemPrintln("Error: I2C Bus Not Responding");
1187+
1188+
i2cPinned = true;
1189+
1190+
vTaskDelete(nullptr); // Delete task once it has run once
11691191
}
11701192

11711193
// Depending on radio selection, begin hardware

Firmware/RTK_Surveyor/Bluetooth.ino

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,14 +166,21 @@ void bluetoothStart()
166166
else if (settings.bluetoothRadioType == BLUETOOTH_RADIO_BLE)
167167
bluetoothSerial = new BTLESerial();
168168

169-
if (bluetoothSerial->begin(deviceName) == false)
170-
{
171-
systemPrintln("An error occurred initializing Bluetooth");
169+
if (pinBluetoothTaskHandle == nullptr)
170+
xTaskCreatePinnedToCore(
171+
pinBluetoothTask,
172+
"BluetoothStart", // Just for humans
173+
2000, // Stack Size
174+
nullptr, // Task input parameter
175+
0, // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest
176+
&pinBluetoothTaskHandle, // Task handle
177+
settings.bluetoothInterruptsCore); // Core where task should run, 0=core, 1=Arduino
178+
179+
while (bluetoothPinned == false) // Wait for task to run once
180+
delay(1);
181+
182+
172183

173-
if (productVariant == RTK_SURVEYOR)
174-
digitalWrite(pin_bluetoothStatusLED, LOW);
175-
return;
176-
}
177184

178185
// Set PIN to 1234 so we can connect to older BT devices, but not require a PIN for modern device pairing
179186
// See issue: https://github.com/sparkfun/SparkFun_RTK_Firmware/issues/5
@@ -216,6 +223,24 @@ void bluetoothStart()
216223
#endif // COMPILE_BT
217224
}
218225

226+
// Assign Bluetooth interrupts to the core that started the task. See:
227+
// https://github.com/espressif/arduino-esp32/issues/3386
228+
void pinBluetoothTask(void *pvParameters)
229+
{
230+
231+
if (bluetoothSerial->begin(deviceName) == false)
232+
{
233+
systemPrintln("An error occurred initializing Bluetooth");
234+
235+
if (productVariant == RTK_SURVEYOR)
236+
digitalWrite(pin_bluetoothStatusLED, LOW);
237+
}
238+
239+
bluetoothPinned = true;
240+
241+
vTaskDelete(nullptr); // Delete task once it has run once
242+
}
243+
219244
// This function stops BT so that it can be restarted later
220245
// It also releases as much system resources as possible so that WiFi/caster is more stable
221246
void bluetoothStop()

Firmware/RTK_Surveyor/NVM.ino

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,9 @@ void recordSystemSettingsToFile(File *settingsFile)
420420
settingsFile->printf("%s=%d\r\n", "btReadTaskCore", settings.btReadTaskCore);
421421
settingsFile->printf("%s=%d\r\n", "gnssReadTaskCore", settings.gnssReadTaskCore);
422422
settingsFile->printf("%s=%d\r\n", "handleGnssDataTaskCore", settings.handleGnssDataTaskCore);
423+
settingsFile->printf("%s=%d\r\n", "gnssUartInterruptsCore", settings.gnssUartInterruptsCore);
424+
settingsFile->printf("%s=%d\r\n", "bluetoothInterruptsCore", settings.bluetoothInterruptsCore);
425+
settingsFile->printf("%s=%d\r\n", "i2cInterruptsCore", settings.i2cInterruptsCore);
423426
}
424427

425428
// Given a fileName, parse the file and load the given settings struct
@@ -1296,6 +1299,12 @@ bool parseLine(char *str, Settings *settings)
12961299
settings->gnssReadTaskCore = d;
12971300
else if (strcmp(settingName, "handleGnssDataTaskCore") == 0)
12981301
settings->handleGnssDataTaskCore = d;
1302+
else if (strcmp(settingName, "gnssUartInterruptsCore") == 0)
1303+
settings->gnssUartInterruptsCore = d;
1304+
else if (strcmp(settingName, "bluetoothInterruptsCore") == 0)
1305+
settings->bluetoothInterruptsCore = d;
1306+
else if (strcmp(settingName, "i2cInterruptsCore") == 0)
1307+
settings->i2cInterruptsCore = d;
12991308

13001309
// Check for bulk settings (WiFi credentials, constellations, message rates, ESPNOW Peers)
13011310
// Must be last on else list

Firmware/RTK_Surveyor/RTK_Surveyor.ino

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,6 @@ HardwareSerial serialGNSS(2); // TX on 17, RX on 16
394394
uint8_t wBuffer[SERIAL_SIZE_TX]; // Buffer for writing from incoming SPP to F9P
395395
TaskHandle_t btReadTaskHandle =
396396
nullptr; // Store handles so that we can kill them if user goes into WiFi NTRIP Server mode
397-
const uint8_t btReadTaskPriority = 1; // 3 being the highest, and 0 being the lowest
398397
const int btReadTaskStackSize = 2000;
399398

400399
uint8_t *ringBuffer; // Buffer for reading from F9P. At 230400bps, 23040 bytes/s. If SD blocks for 250ms, we need 23040
@@ -406,9 +405,15 @@ const int gnssReadTaskStackSize = 2000;
406405
TaskHandle_t handleGnssDataTaskHandle = nullptr;
407406
const int handleGnssDataTaskStackSize = 3000;
408407

409-
TaskHandle_t pinUART2TaskHandle = nullptr; // Dummy task to start UART2 on core 0.
408+
TaskHandle_t pinUART2TaskHandle = nullptr; // Dummy task to start hardware on an assigned core
410409
volatile bool uart2pinned = false; // This variable is touched by core 0 but checked by core 1. Must be volatile.
411410

411+
TaskHandle_t pinI2CTaskHandle = nullptr; // Dummy task to start hardware on an assigned core
412+
volatile bool i2cPinned = false; // This variable is touched by core 0 but checked by core 1. Must be volatile.
413+
414+
TaskHandle_t pinBluetoothTaskHandle = nullptr; // Dummy task to start hardware on an assigned core
415+
volatile bool bluetoothPinned = false; // This variable is touched by core 0 but checked by core 1. Must be volatile.
416+
412417
volatile static int combinedSpaceRemaining = 0; // Overrun indicator
413418
volatile static long fileSize = 0; // Updated with each write
414419
int bufferOverruns = 0; // Running count of possible data losses since power-on

Firmware/RTK_Surveyor/menuSystem.ino

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,15 @@ void menuDebug()
685685
systemPrint("47) Set Serial GNSS RX Full Threshold: ");
686686
systemPrintln(settings.serialGNSSRxFullThreshold);
687687

688+
systemPrint("48) Set Core used for GNSS UART Interrupts: ");
689+
systemPrintln(settings.gnssUartInterruptsCore);
690+
691+
systemPrint("49) Set Core used for Bluetooth Interrupts: ");
692+
systemPrintln(settings.bluetoothInterruptsCore);
693+
694+
systemPrint("50) Set Core used for I2C Interrupts: ");
695+
systemPrintln(settings.i2cInterruptsCore);
696+
688697
systemPrintln("t) Enter Test Screen");
689698

690699
systemPrintln("e) Erase LittleFS");

Firmware/RTK_Surveyor/settings.h

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ const ubxCmd ubxCommands[] = {
713713
{UBLOX_CFG_USBINPROT_SPARTN, "CFG_USBINPROT_SPARTN", 120, 9999}, //
714714

715715
{UBLOX_CFG_NAV2_OUT_ENABLED, "CFG_NAV2_OUT_ENABLED", 130,
716-
130}, // Supported on F9P 130 and up. Supported on F9R 130 and up.
716+
130}, // Supported on F9P 130 and up. Supported on F9R 130 and up.
717717
{UBLOX_CFG_NAVSPG_INFIL_MINCNO, "CFG_NAVSPG_INFIL_MINCNO", 0, 0}, //
718718
};
719719

@@ -739,26 +739,26 @@ typedef struct
739739
double fixedLong = -105.18505761;
740740
double fixedAltitude = 1560.089;
741741
uint32_t dataPortBaud =
742-
(115200 * 2); // Default to 230400bps. This limits GNSS fixes at 4Hz but allows SD buffer to be reduced to 6k.
742+
(115200 * 2); // Default to 230400bps. This limits GNSS fixes at 4Hz but allows SD buffer to be reduced to 6k.
743743
uint32_t radioPortBaud = 57600; // Default to 57600bps to support connection to SiK1000 type telemetry radios
744744
float surveyInStartingAccuracy = 1.0; // Wait for 1m horizontal positional accuracy before starting survey in
745745
uint16_t measurementRate = 250; // Elapsed ms between GNSS measurements. 25ms to 65535ms. Default 4Hz.
746746
uint16_t navigationRate =
747-
1; // Ratio between number of measurements and navigation solutions. Default 1 for 4Hz (with measurementRate).
747+
1; // Ratio between number of measurements and navigation solutions. Default 1 for 4Hz (with measurementRate).
748748
bool enableI2Cdebug = false; // Turn on to display GNSS library debug messages
749749
bool enableHeapReport = false; // Turn on to display free heap
750750
bool enableTaskReports = false; // Turn on to display task high water marks
751751
muxConnectionType_e dataPortChannel = MUX_UBLOX_NMEA; // Mux default to ublox UART1
752752
uint16_t spiFrequency = 16; // By default, use 16MHz SPI
753753
bool enableLogging = true; // If an SD card is present, log default sentences
754-
bool enableARPLogging = false; // Log the Antenna Reference Position from RTCM 1005/1006 - if available
755-
uint16_t ARPLoggingInterval_s = 10; // Log the ARP every 10 seconds - if available
754+
bool enableARPLogging = false; // Log the Antenna Reference Position from RTCM 1005/1006 - if available
755+
uint16_t ARPLoggingInterval_s = 10; // Log the ARP every 10 seconds - if available
756756
uint16_t sppRxQueueSize = 2048;
757757
uint16_t sppTxQueueSize = 512;
758758
uint8_t dynamicModel = DYN_MODEL_PORTABLE;
759759
SystemState lastState = STATE_NOT_SET; // Start unit in last known state
760-
bool enableSensorFusion = false; // If IMU is available, avoid using it unless user specifically selects automotive
761-
bool autoIMUmountAlignment = true; // Allows unit to automatically establish device orientation in vehicle
760+
bool enableSensorFusion = false; // If IMU is available, avoid using it unless user specifically selects automotive
761+
bool autoIMUmountAlignment = true; // Allows unit to automatically establish device orientation in vehicle
762762
bool enableResetDisplay = false;
763763
uint8_t resetCount = 0;
764764
bool enableExternalPulse = true; // Send pulse once lock is achieved
@@ -892,14 +892,14 @@ typedef struct
892892

893893
bool wifiConfigOverAP = true; // Configure device over Access Point or have it connect to WiFi
894894
uint16_t wifiTcpPort =
895-
2947; // TCP port to use in Client/Server mode. 2947 is GPS Daemon: http://tcp-udp-ports.com/port-2947.htm
895+
2947; // TCP port to use in Client/Server mode. 2947 is GPS Daemon: http://tcp-udp-ports.com/port-2947.htm
896896
uint8_t minElev = 10; // Minimum elevation (in deg) for a GNSS satellite to be used in NAV
897897
uint8_t ubxMessageRatesBase[MAX_UBX_MSG_RTCM] = {
898-
254}; // Mark first record with key so defaults will be applied. Int value for each supported message - Report
899-
// rates for RTCM Base. Default to u-blox recommended rates.
900-
uint32_t imuYaw = 0; // User defined IMU mount yaw angle (0 to 36,000) CFG-SFIMU-IMU_MNTALG_YAW
901-
int16_t imuPitch = 0; // User defined IMU mount pitch angle (-9000 to 9000) CFG-SFIMU-IMU_MNTALG_PITCH
902-
int16_t imuRoll = 0; // User defined IMU mount roll angle (-18000 to 18000) CFG-SFIMU-IMU_MNTALG_ROLL
898+
254}; // Mark first record with key so defaults will be applied. Int value for each supported message - Report
899+
// rates for RTCM Base. Default to u-blox recommended rates.
900+
uint32_t imuYaw = 0; // User defined IMU mount yaw angle (0 to 36,000) CFG-SFIMU-IMU_MNTALG_YAW
901+
int16_t imuPitch = 0; // User defined IMU mount pitch angle (-9000 to 9000) CFG-SFIMU-IMU_MNTALG_PITCH
902+
int16_t imuRoll = 0; // User defined IMU mount roll angle (-18000 to 18000) CFG-SFIMU-IMU_MNTALG_ROLL
903903
bool sfDisableWheelDirection = false; // CFG-SFODO-DIS_AUTODIRPINPOL
904904
bool sfCombineWheelTicks = false; // CFG-SFODO-COMBINE_TICKS
905905
uint8_t rateNavPrio = 0; // Output rate of priority nav mode message - CFG-RATE-NAV_PRIO
@@ -932,18 +932,22 @@ typedef struct
932932
0}; // NTPpacket::defaultReferenceId. Ref ID is 4 chars. Add one extra for a NULL.
933933

934934
CoordinateInputType coordinateInputType = COORDINATE_INPUT_TYPE_DD; // Default DD.ddddddddd
935-
uint16_t lbandFixTimeout_seconds = 180; // Number of seconds of no L-Band fix before resetting ZED
936-
int16_t minCNO_F9P = 6; // Minimum satellite signal level for navigation. ZED-F9P default is 6 dBHz
937-
int16_t minCNO_F9R = 20; // Minimum satellite signal level for navigation. ZED-F9R default is 20 dBHz
938-
bool mdnsEnable = false; // Allows locating of device from browser address 'rtk.local'
939-
uint16_t serialGNSSRxFullThreshold = 50; // RX FIFO full interrupt. Max of ~128. See pinUART2Task().
940-
941-
uint8_t btReadTaskPriority = 1; // Read from BT SPP and Write to GNSS. 3 being the highest, and 0 being the lowest
942-
uint8_t gnssReadTaskPriority = 1; // Read from ZED-F9x and Write to circular buffer (SD, TCP, BT). 3 being the highest, and 0 being the lowest
935+
uint16_t lbandFixTimeout_seconds = 180; // Number of seconds of no L-Band fix before resetting ZED
936+
int16_t minCNO_F9P = 6; // Minimum satellite signal level for navigation. ZED-F9P default is 6 dBHz
937+
int16_t minCNO_F9R = 20; // Minimum satellite signal level for navigation. ZED-F9R default is 20 dBHz
938+
bool mdnsEnable = false; // Allows locating of device from browser address 'rtk.local'
939+
uint16_t serialGNSSRxFullThreshold = 50; // RX FIFO full interrupt. Max of ~128. See pinUART2Task().
940+
uint8_t btReadTaskPriority = 1; // Read from BT SPP and Write to GNSS. 3 being the highest, and 0 being the lowest
941+
uint8_t gnssReadTaskPriority =
942+
1; // Read from ZED-F9x and Write to circular buffer (SD, TCP, BT). 3 being the highest, and 0 being the lowest
943943
uint8_t handleGnssDataTaskPriority = 1; // Read from the cicular buffer and dole out to end points (SD, TCP, BT).
944-
uint8_t btReadTaskCore = 1; // Core where task should run, 0=core, 1=Arduino
945-
uint8_t gnssReadTaskCore = 1; // Core where task should run, 0=core, 1=Arduino
946-
uint8_t handleGnssDataTaskCore = 1; // Core where task should run, 0=core, 1=Arduino
944+
uint8_t btReadTaskCore = 1; // Core where task should run, 0=core, 1=Arduino
945+
uint8_t gnssReadTaskCore = 1; // Core where task should run, 0=core, 1=Arduino
946+
uint8_t handleGnssDataTaskCore = 1; // Core where task should run, 0=core, 1=Arduino
947+
uint8_t gnssUartInterruptsCore =
948+
1; // Core where hardware is started and interrupts are assigned to, 0=core, 1=Arduino
949+
uint8_t bluetoothInterruptsCore = 1; // Core where hardware is started and interrupts are assigned to, 0=core, 1=Arduino
950+
uint8_t i2cInterruptsCore = 1; // Core where hardware is started and interrupts are assigned to, 0=core, 1=Arduino
947951

948952
} Settings;
949953
Settings settings;

0 commit comments

Comments
 (0)