1
- // Initial startup functions for GNSS, SD, display, radio, etc
1
+ /* ------------------------------------------------------------------------------
2
+ Begin.ino
2
3
3
- void identifyBoard ()
4
+ This module implements the initial startup functions for GNSS, SD, display,
5
+ radio, etc.
6
+ ------------------------------------------------------------------------------*/
7
+
8
+ // ----------------------------------------
9
+ // Constants
10
+ // ----------------------------------------
11
+
12
+ #define MAX_ADC_VOLTAGE 3300 // Millivolts
13
+
14
+ // Testing shows the combined ADC+resistors is under a 1% window
15
+ #define TOLERANCE 4.75 // Percent: 95.25% - 104.75%
16
+
17
+ // ----------------------------------------
18
+ // Macros
19
+ // ----------------------------------------
20
+
21
+ // ADC input
22
+ // Ra KOhms | Rb KOhms
23
+ // MAX_ADC_VOLTAGE -----/\/\/\/\-----+-----/\/\/\/\----- Ground
24
+ //
25
+ #define ADC_ID_mV (RaK, RbK ) ((uint16_t )(MAX_ADC_VOLTAGE * RbK / (RaK + RbK)))
26
+
27
+ // ----------------------------------------
28
+ // Hardware initialization functions
29
+ // ----------------------------------------
30
+
31
+ // Determine if the measured value matches the product ID value
32
+ bool idWithAdc (uint16_t mvMeasured, uint16_t mvProduct)
4
33
{
5
- // Use ADC to check resistor divider
6
- // Express: 10/3.3
7
- // Express+: 3.3/10
8
- // Facet: 10/10
9
- // Facet L-Band: 10/20
10
- // Reference Station: 20/10
11
- // Facet L-Band Direct: 10/100
12
- // Surveyor: ID resistors do not exist
13
-
14
- const float rtkExpressID = 3.3 / (10 + 3.3 ) * 3300 ; // 819mV
15
- const float rtkExressPlusID = 10.0 / (10 + 3.3 ) * 3300 ; // 2481mV
16
- const float rtkFacetID = 10.0 / (10 + 10 ) * 3300 ; // 1650mV
17
- const float rtkFacetLbandID = 20.0 / (20 + 10 ) * 3300 ; // 2200mV
18
- const float rtkReferenceStationID = 10.0 / (10 + 20 ) * 3300 ; // 1100mV
19
- const float rtkFacetLbandDirectID = 1.0 / (4.7 + 1 ) * 3300 ; // 579mV
20
-
21
- const float tolerance = 0.0475 ; // 4.75% Testing shows the combined ADC+resistors is under a 1% window
22
- const float upperThreshold = 1 + tolerance; // 104.75%
23
- const float lowerThreshold = 1 - tolerance; // 95.25%
34
+ uint16_t lowerThreshold;
35
+ uint16_t upperThreshold;
36
+
37
+ // Return true if the mvMeasured value is within the tolerance range
38
+ // of the mvProduct value
39
+ upperThreshold = (1.0 + (TOLERANCE / 100 .)) * mvProduct;
40
+ lowerThreshold = (1.0 - (TOLERANCE / 100 .)) * mvProduct;
41
+ return (upperThreshold > mvMeasured) && (mvMeasured > lowerThreshold);
42
+ }
24
43
44
+ // Use a pair of resistors on pin 35 to ID the board type
45
+ // If the ID resistors are not available then use a variety of other methods
46
+ // (I2C, GPIO test, etc) to ID the board.
47
+ // Assume no hardware interfaces have been started so we need to start/stop any hardware
48
+ // used in tests accordingly.
49
+ void identifyBoard ()
50
+ {
51
+ // Use ADC to check the resistor divider
25
52
int pin_deviceID = 35 ;
26
53
uint16_t idValue = analogReadMilliVolts (pin_deviceID);
27
54
log_d (" Board ADC ID (mV): %d" , idValue);
28
55
29
- if (idValue > (rtkFacetID * lowerThreshold) && idValue < (rtkFacetID * upperThreshold))
30
- {
31
- productVariant = RTK_FACET;
32
- }
33
- else if (idValue > (rtkFacetLbandID * lowerThreshold) && idValue < (rtkFacetLbandID * upperThreshold))
34
- {
35
- productVariant = RTK_FACET_LBAND;
36
- }
37
- else if (idValue > (rtkExpressID * lowerThreshold) && idValue < (rtkExpressID * upperThreshold))
38
- {
56
+ // Order checks by millivolt values high to low
57
+
58
+ // Facet L-Band Direct: 4.7/1 --> 551mV < 579mV < 607mV
59
+ if (idWithAdc (idValue, ADC_ID_mV (4.7 , 1 )))
60
+ productVariant = RTK_FACET_LBAND_DIRECT;
61
+
62
+ // Express: 10/3.3 --> 779mV < 819mV < 858mV
63
+ else if (idWithAdc (idValue, ADC_ID_mV (10 , 3.3 )))
39
64
productVariant = RTK_EXPRESS;
40
- }
41
- else if (idValue > (rtkExressPlusID * lowerThreshold) && idValue < (rtkExressPlusID * upperThreshold))
42
- {
43
- productVariant = RTK_EXPRESS_PLUS;
44
- }
45
- else if (idValue > (rtkReferenceStationID * lowerThreshold) && idValue < (rtkReferenceStationID * upperThreshold))
65
+
66
+ // Reference Station: 20/10 --> 1047mV < 1100mV < 1153mV
67
+ else if (idWithAdc (idValue, ADC_ID_mV (20 , 10 )))
46
68
{
47
69
productVariant = REFERENCE_STATION;
48
70
// We can't auto-detect the ZED version if the firmware is in configViaEthernet mode,
49
71
// so fake it here - otherwise messageSupported always returns false
50
72
zedFirmwareVersionInt = 112 ;
51
73
}
52
- else if (idValue > (rtkFacetLbandDirectID * lowerThreshold) && idValue < (rtkFacetLbandDirectID * upperThreshold))
53
- {
54
- productVariant = RTK_FACET_LBAND_DIRECT;
55
- }
74
+ // Facet: 10/10 --> 1571mV < 1650mV < 1729mV
75
+ else if (idWithAdc (idValue, ADC_ID_mV (10 , 10 )))
76
+ productVariant = RTK_FACET;
77
+
78
+ // Facet L-Band: 10/20 --> 2095mV < 2200mV < 2305mV
79
+ else if (idWithAdc (idValue, ADC_ID_mV (10 , 20 )))
80
+ productVariant = RTK_FACET_LBAND;
81
+
82
+ // Express+: 3.3/10 --> 2363mV < 2481mV < 2600mV
83
+ else if (idWithAdc (idValue, ADC_ID_mV (3.3 , 10 )))
84
+ productVariant = RTK_EXPRESS_PLUS;
85
+
86
+ // ID resistors do not exist for the following:
87
+ // Surveyor
88
+ // Unknown
56
89
else
57
- {
58
90
productVariant = RTK_UNKNOWN; // Need to wait until the GNSS and Accel have been initialized
59
- }
60
91
}
61
92
62
93
// Setup any essential power pins
@@ -172,9 +203,6 @@ void beginBoard()
172
203
// Bug in ZED-F9P v1.13 firmware causes RTK LED to not light when RTK Floating with SBAS on.
173
204
// The following changes the POR default but will be overwritten by settings in NVM or settings file
174
205
settings.ubxConstellations [1 ].enabled = false ;
175
-
176
- strncpy (platformFilePrefix, " SFE_Surveyor" , sizeof (platformFilePrefix) - 1 );
177
- strncpy (platformPrefix, " Surveyor" , sizeof (platformPrefix) - 1 );
178
206
}
179
207
else if (productVariant == RTK_EXPRESS || productVariant == RTK_EXPRESS_PLUS)
180
208
{
@@ -198,17 +226,6 @@ void beginBoard()
198
226
pinMode (pin_setupButton, INPUT_PULLUP);
199
227
200
228
setMuxport (settings.dataPortChannel ); // Set mux to user's choice: NMEA, I2C, PPS, or DAC
201
-
202
- if (productVariant == RTK_EXPRESS)
203
- {
204
- strncpy (platformFilePrefix, " SFE_Express" , sizeof (platformFilePrefix) - 1 );
205
- strncpy (platformPrefix, " Express" , sizeof (platformPrefix) - 1 );
206
- }
207
- else if (productVariant == RTK_EXPRESS_PLUS)
208
- {
209
- strncpy (platformFilePrefix, " SFE_Express_Plus" , sizeof (platformFilePrefix) - 1 );
210
- strncpy (platformPrefix, " Express Plus" , sizeof (platformPrefix) - 1 );
211
- }
212
229
}
213
230
else if (productVariant == RTK_FACET || productVariant == RTK_FACET_LBAND ||
214
231
productVariant == RTK_FACET_LBAND_DIRECT)
@@ -247,21 +264,8 @@ void beginBoard()
247
264
pinMode (pin_radio_cts, OUTPUT);
248
265
digitalWrite (pin_radio_cts, LOW);
249
266
250
- if (productVariant == RTK_FACET)
251
- {
252
- strncpy (platformFilePrefix, " SFE_Facet" , sizeof (platformFilePrefix) - 1 );
253
- strncpy (platformPrefix, " Facet" , sizeof (platformPrefix) - 1 );
254
- }
255
- else if (productVariant == RTK_FACET_LBAND)
256
- {
257
- strncpy (platformFilePrefix, " SFE_Facet_LBand" , sizeof (platformFilePrefix) - 1 );
258
- strncpy (platformPrefix, " Facet L-Band" , sizeof (platformPrefix) - 1 );
259
- }
260
- else if (productVariant == RTK_FACET_LBAND_DIRECT)
267
+ if (productVariant == RTK_FACET_LBAND_DIRECT)
261
268
{
262
- strncpy (platformFilePrefix, " SFE_Facet_LBand_Direct" , sizeof (platformFilePrefix) - 1 );
263
- strncpy (platformPrefix, " Facet L-Band Direct" , sizeof (platformPrefix) - 1 );
264
-
265
269
// Override the default setting if a user has not explicitly configured the setting
266
270
if (settings.useI2cForLbandCorrectionsConfigured == false )
267
271
settings.useI2cForLbandCorrections = false ;
@@ -272,9 +276,6 @@ void beginBoard()
272
276
// No powerOnCheck
273
277
274
278
settings.enablePrintBatteryMessages = false ; // No pesky battery messages
275
-
276
- strncpy (platformFilePrefix, " SFE_Reference_Station" , sizeof (platformFilePrefix) - 1 );
277
- strncpy (platformPrefix, " Reference Station" , sizeof (platformPrefix) - 1 );
278
279
}
279
280
280
281
char versionString[21 ];
@@ -1239,25 +1240,77 @@ void beginI2C()
1239
1240
// Assign I2C interrupts to the core that started the task. See: https://github.com/espressif/arduino-esp32/issues/3386
1240
1241
void pinI2CTask (void *pvParameters)
1241
1242
{
1243
+ bool i2cBusAvailable;
1244
+ uint32_t timer;
1245
+
1242
1246
Wire.begin (); // Start I2C on core the core that was chosen when the task was started
1243
1247
// Wire.setClock(400000);
1244
1248
1245
- // begin/end wire transmission to see if bus is responding correctly
1246
- // All good: 0ms, response 2
1247
- // SDA/SCL shorted: 1000ms timeout, response 5
1248
- // SCL/VCC shorted: 14ms, response 5
1249
- // SCL/GND shorted: 1000ms, response 5
1250
- // SDA/VCC shorted: 1000ms, reponse 5
1251
- // SDA/GND shorted: 14ms, response 5
1252
- Wire.beginTransmission (0x15 ); // Dummy address
1253
- int endValue = Wire.endTransmission ();
1254
- if (endValue == 2 )
1255
- online.i2c = true ;
1256
- else
1257
- systemPrintln (" Error: I2C Bus Not Responding" );
1249
+ // Display the device addresses
1250
+ i2cBusAvailable = false ;
1251
+ for (uint8_t addr = 0 ; addr < 127 ; addr++)
1252
+ {
1253
+ // begin/end wire transmission to see if the bus is responding correctly
1254
+ // All good: 0ms, response 2
1255
+ // SDA/SCL shorted: 1000ms timeout, response 5
1256
+ // SCL/VCC shorted: 14ms, response 5
1257
+ // SCL/GND shorted: 1000ms, response 5
1258
+ // SDA/VCC shorted: 1000ms, response 5
1259
+ // SDA/GND shorted: 14ms, response 5
1260
+ timer = millis ();
1261
+ Wire.beginTransmission (addr);
1262
+ if (Wire.endTransmission () == 0 )
1263
+ {
1264
+ i2cBusAvailable = true ;
1265
+ switch (addr)
1266
+ {
1267
+ default : {
1268
+ systemPrintf (" 0x%02x\r\n " , addr);
1269
+ break ;
1270
+ }
1258
1271
1259
- i2cPinned = true ;
1272
+ case 0x19 : {
1273
+ systemPrintf (" 0x%02x - LIS2DH12 Accelerometer\r\n " , addr);
1274
+ break ;
1275
+ }
1276
+
1277
+ case 0x36 : {
1278
+ systemPrintf (" 0x%02x - MAX17048 Fuel Guage\r\n " , addr);
1279
+ break ;
1280
+ }
1281
+
1282
+ case 0x3d : {
1283
+ systemPrintf (" 0x%02x - SSD1306 (64x48) OLED Driver\r\n " , addr);
1284
+ break ;
1285
+ }
1286
+
1287
+ case 0x42 : {
1288
+ systemPrintf (" 0x%02x - u-blox ZED-F9P GNSS Receiver\r\n " , addr);
1289
+ break ;
1290
+ }
1291
+
1292
+ case 0x43 : {
1293
+ systemPrintf (" 0x%02x - u-blox NEO-D9S-00B Correction Data Receiver\r\n " , addr);
1294
+ break ;
1295
+ }
1260
1296
1297
+ case 0x60 : {
1298
+ systemPrintf (" 0x%02x - Crypto Coprocessor\r\n " , addr);
1299
+ break ;
1300
+ }
1301
+ }
1302
+ }
1303
+ else if ((millis () - timer) > 3 )
1304
+ {
1305
+ systemPrintln (" Error: I2C Bus Not Responding" );
1306
+ i2cBusAvailable = false ;
1307
+ break ;
1308
+ }
1309
+ }
1310
+
1311
+ // Update the I2C status
1312
+ online.i2c = i2cBusAvailable;
1313
+ i2cPinned = true ;
1261
1314
vTaskDelete (nullptr ); // Delete task once it has run once
1262
1315
}
1263
1316
0 commit comments