1- // Initial startup functions for GNSS, SD, display, radio, etc
1+ /* ------------------------------------------------------------------------------
2+ Begin.ino
23
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)
433{
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+ }
2443
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
2552 int pin_deviceID = 35 ;
2653 uint16_t idValue = analogReadMilliVolts (pin_deviceID);
2754 log_d (" Board ADC ID (mV): %d" , idValue);
2855
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 )))
3964 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 )))
4668 {
4769 productVariant = REFERENCE_STATION;
4870 // We can't auto-detect the ZED version if the firmware is in configViaEthernet mode,
4971 // so fake it here - otherwise messageSupported always returns false
5072 zedFirmwareVersionInt = 112 ;
5173 }
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
5689 else
57- {
5890 productVariant = RTK_UNKNOWN; // Need to wait until the GNSS and Accel have been initialized
59- }
6091}
6192
6293// Setup any essential power pins
@@ -172,9 +203,6 @@ void beginBoard()
172203 // Bug in ZED-F9P v1.13 firmware causes RTK LED to not light when RTK Floating with SBAS on.
173204 // The following changes the POR default but will be overwritten by settings in NVM or settings file
174205 settings.ubxConstellations [1 ].enabled = false ;
175-
176- strncpy (platformFilePrefix, " SFE_Surveyor" , sizeof (platformFilePrefix) - 1 );
177- strncpy (platformPrefix, " Surveyor" , sizeof (platformPrefix) - 1 );
178206 }
179207 else if (productVariant == RTK_EXPRESS || productVariant == RTK_EXPRESS_PLUS)
180208 {
@@ -198,17 +226,6 @@ void beginBoard()
198226 pinMode (pin_setupButton, INPUT_PULLUP);
199227
200228 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- }
212229 }
213230 else if (productVariant == RTK_FACET || productVariant == RTK_FACET_LBAND ||
214231 productVariant == RTK_FACET_LBAND_DIRECT)
@@ -247,21 +264,8 @@ void beginBoard()
247264 pinMode (pin_radio_cts, OUTPUT);
248265 digitalWrite (pin_radio_cts, LOW);
249266
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)
261268 {
262- strncpy (platformFilePrefix, " SFE_Facet_LBand_Direct" , sizeof (platformFilePrefix) - 1 );
263- strncpy (platformPrefix, " Facet L-Band Direct" , sizeof (platformPrefix) - 1 );
264-
265269 // Override the default setting if a user has not explicitly configured the setting
266270 if (settings.useI2cForLbandCorrectionsConfigured == false )
267271 settings.useI2cForLbandCorrections = false ;
@@ -272,9 +276,6 @@ void beginBoard()
272276 // No powerOnCheck
273277
274278 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 );
278279 }
279280
280281 char versionString[21 ];
@@ -1239,25 +1240,77 @@ void beginI2C()
12391240// Assign I2C interrupts to the core that started the task. See: https://github.com/espressif/arduino-esp32/issues/3386
12401241void pinI2CTask (void *pvParameters)
12411242{
1243+ bool i2cBusAvailable;
1244+ uint32_t timer;
1245+
12421246 Wire.begin (); // Start I2C on core the core that was chosen when the task was started
12431247 // Wire.setClock(400000);
12441248
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+ }
12581271
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+ }
12601296
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 ;
12611314 vTaskDelete (nullptr ); // Delete task once it has run once
12621315}
12631316
0 commit comments