Skip to content

Commit c3052b0

Browse files
Smaller optimizations of pga and gps software
1 parent c12d9cd commit c3052b0

File tree

6 files changed

+116
-23
lines changed

6 files changed

+116
-23
lines changed

src/OpenBikeSensorFirmware.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,12 @@ void loop() {
515515
auto* currentSet = new DataSet;
516516
uint32_t thisLoopTow;
517517

518+
if(shutdownState != 0) {
519+
obsDisplay->clear();
520+
while(1)
521+
delay(1);
522+
}
523+
518524
if (gps.hasTowTicks()) {
519525
/* only Timeinfo is reliably set until now! */
520526
GpsRecord incoming = gps.getIncomingGpsRecord();
@@ -555,7 +561,6 @@ void loop() {
555561
button.handle(currentTimeMillis);
556562
gps.handle();
557563
if (sensorManager->pollDistancesAlternating()) {
558-
log_w("poll");
559564
// if a new minimum on the selected sensor is detected, the value and the time of detection will be stored
560565
const uint16_t reading = sensorManager->sensorValues[confirmationSensorID];
561566
if (reading > 0 && reading < minDistanceToConfirm) {
@@ -707,6 +712,8 @@ bool loadConfig(ObsConfig &cfg) {
707712
}
708713
}
709714

715+
SPI.begin(18, 19, 23, 5);
716+
SPI.setDataMode(SPI_MODE0);
710717
if (SD.begin() && SD.exists("/obs.json")) {
711718
obsDisplay->showTextOnGrid(2, obsDisplay->currentLine(), "Init from SD.");
712719
log_i("Configuration init from SD.");

src/gps.cpp

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,21 @@ void Gps::begin() {
5454
setMessageInterval(UBX_MSG::NAV_TIMEGPS, 240);
5555
#endif
5656
}
57+
58+
//Serial.updateBaudRate(9600);
59+
//mSerial.begin(9600, SERIAL_8N1);
60+
// Debug - forward gps serial to normal serial
61+
/*
62+
log_e("--------_STARTING LOOP");
63+
while(1)
64+
{
65+
int val = mSerial.read();
66+
if(val >= 0)
67+
Serial.write(val);
68+
val = Serial.read();
69+
if(val >= 0)
70+
mSerial.write(val);
71+
}*/
5772
}
5873

5974
void Gps::sendUbx(UBX_MSG ubxMsgId, const uint8_t payload[], uint16_t length) {
@@ -167,6 +182,11 @@ void Gps::configureGpsModule() {
167182
#endif
168183
enableSbas();
169184

185+
#ifdef UBX_M10
186+
// Enable Glonass for M10, GPS and Galileo are enabled by default
187+
sendCfgAndWaitForAck(UBX_CFG_LAYER::RAM, UBX_CFG_KEY_ID::CFG_SIGNAL_GLO_ENA, 1);
188+
#endif
189+
170190
#ifdef UBX_M6
171191
setMessageInterval(UBX_MSG::NAV_SBAS, 59);
172192
setMessageInterval(UBX_MSG::NAV_POSLLH, 1);
@@ -198,7 +218,9 @@ void Gps::configureGpsModule() {
198218
};
199219
sendAndWaitForAck(UBX_MSG::CFG_NAV5, UBX_CFG_NAV5, sizeof(UBX_CFG_NAV5));
200220
#endif
201-
// TODO: Set dynModel for M10, static hold stuff does not seem to be available any more
221+
#ifdef UBX_M10
222+
sendCfgAndWaitForAck(UBX_CFG_LAYER::RAM, UBX_CFG_KEY_ID::CFG_NAVSPG_DYNMODEL, 4); // Set dynamic model to 4 (automotive)
223+
#endif
202224

203225
#ifdef UBX_M6
204226
// Not used for M10, as OBSPro does not have a GPS LED
@@ -383,6 +405,7 @@ bool Gps::setMessageInterval(UBX_CFG_KEY_ID msgId, uint8_t seconds, bool waitFor
383405
bool Gps::setBaud() {
384406
mSerial.end();
385407
mSerial.setRxBufferSize(512);
408+
386409
mSerial.begin(115200, SERIAL_8N1);
387410
while(mSerial.read() >= 0) ;
388411

@@ -392,6 +415,7 @@ bool Gps::setBaud() {
392415
}
393416

394417
mSerial.updateBaudRate(9600);
418+
395419
// switch to 115200 "blind", switch off NMEA
396420
#ifdef UBX_M6
397421
const uint8_t UBX_CFG_PRT[] = {
@@ -544,8 +568,19 @@ bool Gps::handle() {
544568
boolean gotGpsData = false;
545569
int bytesProcessed = 0;
546570
int data;
571+
#ifdef GPS_TRANSPARENT_UART
572+
// Redicrect data to GPS
573+
while((data = Serial.read()) >= 0)
574+
mSerial.write(data);
575+
#endif
547576
while ((data = mSerial.read()) >= 0) {
548577
bytesProcessed++;
578+
579+
#ifdef GPS_TRANSPARENT_UART
580+
// Redicrect data from GPS
581+
Serial.write(data);
582+
#endif
583+
549584
#ifdef GPS_LOW_LEVEL_DEBUGGING
550585
log_w("GPS in: 0x%02x", data);
551586
#endif
@@ -1083,9 +1118,9 @@ void Gps::parseUbxMessage() {
10831118
}
10841119
break;
10851120
case (uint16_t) UBX_MSG::NAV_PVT: {
1086-
log_v("PVT: iTOW: %u, gpsFix: %d, flags: %02x, numSV: %d, pDop: %04d.",
1087-
mGpsBuffer.navPvt.iTow, mGpsBuffer.navPvt.gpsFix, mGpsBuffer.navPvt.flags,
1088-
mGpsBuffer.navPvt.numSV, mGpsBuffer.navPvt.pDop);
1121+
log_v("PVT: iTOW: %u, fixType: %d, flags: %02x, numSV: %d, pDop: %04d.",
1122+
mGpsBuffer.navPvt.iTow, mGpsBuffer.navPvt.fixType, mGpsBuffer.navPvt.flags,
1123+
mGpsBuffer.navPvt.numSV, mGpsBuffer.navPvt.pDOP);
10891124
prepareGpsData(mGpsBuffer.navPvt.iTow, mMessageStarted);
10901125
mIncomingGpsRecord.setInfo(mGpsBuffer.navPvt.numSV, mGpsBuffer.navPvt.fixType, mGpsBuffer.navPvt.flags);
10911126
}

src/gps.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
#include "config.h" // PrivacyArea
3131
#include "displays.h"
3232
#include "gpsrecord.h"
33+
#include "variant.h"
34+
35+
// Connects both UARTs together to directly talkt to the GPS with the USB interface
36+
// If set, also disable serial logging (DCORE_DEBUG_LEVEL=0 in platformio.ini)
37+
//#define GPS_TRANSPARENT_UART
3338

3439
class DisplayDevice;
3540

@@ -185,6 +190,7 @@ class Gps {
185190

186191
// UBX, special 0xf1
187192
};
193+
#ifdef UBX_M10
188194
// Key-ID pairs are only available in M10, they are used for the configuration
189195
enum class UBX_CFG_KEY_ID {
190196
CFG_UART1_BAUDRATE = 0x40520001, // Type: U4
@@ -197,7 +203,10 @@ class Gps {
197203
CFG_MSGOUT_UBX_NAV_DOP_UART1 = 0x20910039, // Type: U1, Output rate of the UBX-NAV-DOP message on port UART1
198204
CFG_MSGOUT_UBX_NAV_VELNED_UART1 = 0x20910043, // Type: U1, Output rate of the UBX-NAV-VELNED message on port UART1
199205
CFG_MSGOUT_UBX_NAV_PVT_UART1 = 0x20910007, // Type: U1, Output rate of the UBX-NAV-PVT message on port UART1
206+
CFG_SIGNAL_GLO_ENA = 0x10310025, // Type: L, GLONASS enable
207+
CFG_NAVSPG_DYNMODEL = 0x20110021, // Type: E1, Dynamic platform model, 0=portable, 2=stationary, 3=pedestrian, 4=automotive, 5=sea, 6..8=airborne, ...
200208
};
209+
#endif
201210
// CFG Layers are only available in M10, they are used for selecting wehere to store a configuration
202211
enum UBX_CFG_LAYER : uint8_t {
203212
RAM = 1,
@@ -568,10 +577,14 @@ class Gps {
568577
void sendUbx(uint16_t ubxMsgId, const uint8_t *payload = {}, uint16_t length = 0);
569578

570579
void sendUbx(UBX_MSG ubxMsgId, const uint8_t *payload = {}, uint16_t length = 0);
580+
#ifdef UBX_M10
571581
void sendUbxCfg(enum UBX_CFG_LAYER layer, UBX_CFG_KEY_ID keyId, uint32_t value); // Only available in M10
582+
#endif
572583

573584
bool sendAndWaitForAck(UBX_MSG ubxMsgId, const uint8_t *buffer = {}, size_t size = 0, const uint16_t timeoutMs = 200);
574-
bool sendCfgAndWaitForAck(enum UBX_CFG_LAYER layer, UBX_CFG_KEY_ID keyId, uint32_t value, const uint16_t timeoutMs = 200);
585+
#ifdef UBX_M10
586+
bool sendCfgAndWaitForAck(enum UBX_CFG_LAYER layer, UBX_CFG_KEY_ID keyId, uint32_t value, const uint16_t timeoutMs = 200); // Only available in M10
587+
#endif
575588

576589
void parseUbxMessage();
577590

src/pgaSensor.cpp

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,29 @@ void PGASensorManager::registerSensor(const PGASensorInfo &sensorInfo, uint8_t s
2525
sensorValues[sensorId] = MAX_SENSOR_VALUE;
2626
m_sensors[sensorId].median = new Median<uint16_t>(5, MAX_SENSOR_VALUE);
2727
setupSensor(sensorId);
28+
29+
// DEBUG: Dump complete config register map
30+
/*Serial.printf("Register dump for sensor %d\n", sensorId);
31+
uint8_t dump_regs[] = {0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F};
32+
for(int i = 0; i < sizeof(dump_regs); i++)
33+
Serial.printf("Reg 0x%02x: 0x%02x\n", dump_regs[i], spiRegRead(sensorId, dump_regs[i]));*/
34+
35+
// DEBUG: Stress test writing/reading user register
36+
/*uint8_t test = 0;
37+
uint32_t count = 0;
38+
log_e("Starting pga stress test");
39+
while(1)
40+
{
41+
spiRegWrite(sensorId, PGA_REG_USER_DATA1, test);
42+
uint8_t readback = spiRegRead(sensorId, PGA_REG_USER_DATA1);
43+
if(test != readback)
44+
{
45+
log_e("Failed on %d after %d tests", test, count);
46+
count = 0;
47+
}
48+
count++;
49+
test++;
50+
}*/
2851
}
2952

3053
// Guess: Returns true if both sensor results are available
@@ -110,6 +133,9 @@ void PGASensorManager::setupSensor(int sensorId)
110133
pinMode(sensorInfo.mosi_pin, OUTPUT);
111134
pinMode(sensorInfo.miso_pin, INPUT);
112135

136+
// Wait at least 15 ms to sync the synchronous UART
137+
safe_usleep(20000);
138+
113139
// Check communication
114140
// Rerad the DEV_STAT0 register, where the upper nibble should be 0x4
115141
// These are the values for REV_ID (0x2) and OPT_ID (0x0)
@@ -134,20 +160,21 @@ void PGASensorManager::setupSensor(int sensorId)
134160
// th_t = np.array([2000, 5200, 2400, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000])
135161
// th_l = np.array([200, 80, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24])
136162
PGAThresholds thresholds(
137-
TH_TIME_DELTA_2000US, 200/8,
138-
TH_TIME_DELTA_5200US, 80/8,
139-
TH_TIME_DELTA_2400US, 16/8,
140-
TH_TIME_DELTA_8000US, 16/8,
141-
TH_TIME_DELTA_8000US, 16/8,
142-
TH_TIME_DELTA_8000US, 24/8,
163+
TH_TIME_DELTA_2000US, 255/8,
164+
TH_TIME_DELTA_4000US, 80/8,
165+
TH_TIME_DELTA_2400US, 24/8,
143166
TH_TIME_DELTA_8000US, 24/8,
144167
TH_TIME_DELTA_8000US, 24/8,
145-
TH_TIME_DELTA_8000US, 24,
146-
TH_TIME_DELTA_8000US, 24,
147-
TH_TIME_DELTA_8000US, 24,
148-
TH_TIME_DELTA_8000US, 24
168+
TH_TIME_DELTA_8000US, 32/8,
169+
TH_TIME_DELTA_8000US, 32/8,
170+
TH_TIME_DELTA_8000US, 32/8,
171+
TH_TIME_DELTA_8000US, 32,
172+
TH_TIME_DELTA_8000US, 32,
173+
TH_TIME_DELTA_8000US, 32,
174+
TH_TIME_DELTA_8000US, 32
149175
);
150176
spiRegWriteThesholds(sensorId, 1, thresholds);
177+
spiRegWriteThesholds(sensorId, 2, thresholds);
151178

152179
spiRegWrite(sensorId, PGA_REG_DEV_STAT1, 0x00); // Clear stat1 register
153180
safe_usleep(1000); // Wait a bit
@@ -171,14 +198,15 @@ uint8_t PGASensorManager::spiTransfer(uint8_t sensorId, uint8_t data_out)
171198
uint8_t data_in = 0;
172199
for(uint8_t i = 0; i < 8; i++)
173200
{
174-
digitalWrite(sensorInfo.sck_pin, HIGH);
201+
// It seems that the datasheet is wrong about the SPI mode...
202+
// It says: ... with data set on the rising edge of the clock and sampled on the falling edge of the clock
203+
// But we have to set the data before the rising edge.
175204
digitalWrite(sensorInfo.mosi_pin, data_out&0x01);
176205
data_out >>= 1;
177-
safe_usleep(2);
178-
digitalWrite(sensorInfo.sck_pin, LOW);
206+
digitalWrite(sensorInfo.sck_pin, HIGH);
179207
data_in >>= 1;
180208
data_in |= digitalRead(sensorInfo.miso_pin)<<7;
181-
safe_usleep(2);
209+
digitalWrite(sensorInfo.sck_pin, LOW);
182210
}
183211
return data_in;
184212
}
@@ -242,6 +270,7 @@ void PGASensorManager::spiRegWrite(uint8_t sensorId, uint8_t reg_addr, uint8_t v
242270
void PGASensorManager::spiRegWriteThesholds(uint8_t sensorId, uint8_t preset, PGAThresholds &thresholds)
243271
{
244272
assert(sensorId >= 0 && sensorId <= 1);
273+
assert(preset >= 1 && preset <= 2);
245274

246275
uint8_t regOffset = preset == 1 ? 0 : PGA_REG_P2_THR_0 - PGA_REG_P1_THR_0;
247276
spiRegWrite(sensorId, PGA_REG_P1_THR_0 + regOffset, thresholds.t1<<4 | thresholds.t2);
@@ -276,7 +305,7 @@ void PGASensorManager::spiBurstAndListen(uint8_t sensorId, uint8_t preset, uint8
276305

277306
checksum_clear();
278307
spiTransfer(sensorId, 0x55); // Sync byte
279-
uint8_t cmd = 0<<5 | preset == 1 ? PGA_CMD_BURST_AND_LISTEN_1 : PGA_CMD_BURST_AND_LISTEN_2;
308+
uint8_t cmd = 0<<5 | (preset == 1 ? PGA_CMD_BURST_AND_LISTEN_1 : PGA_CMD_BURST_AND_LISTEN_2);
280309
spiTransfer(sensorId, cmd); // Command
281310
checksum_append_byte(cmd);
282311
spiTransfer(sensorId, numberOfObjectsToDetect);

src/pgaSensor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@
139139

140140
#define PGA_DIAG_BUSY_MASK 0x01
141141
#define PGA_DUMP_ENABLE 0 // Prints raw data of the measurements, for debugging or calibration of a new transducer
142-
#define PGA_DUMP_TIME 500
142+
#define PGA_DUMP_TIME 500 // Period for dumping a complete raw data measurement (RX amplitude over time)
143143

144144

145145
struct PGASensorInfo

src/writer.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,13 @@ bool FileWriter::flush() {
107107
log_v("Writing to concrete file.");
108108
const auto start = millis();
109109
result = FileUtil::appendFile(SD, mFileName.c_str(), mBuffer.c_str() );
110+
const unsigned int fileAppendSize = mBuffer.length();
110111
mBuffer.clear();
111112
mWriteTimeMillis = millis() - start;
112113
if (!mFinalFileName) {
113114
correctFilename();
114115
}
115-
log_v("Writing to concrete file done took %lums.", mWriteTimeMillis);
116+
log_e("Writing %u bytes to concrete file done took %lums.", fileAppendSize, mWriteTimeMillis);
116117
return result;
117118
}
118119

@@ -124,6 +125,14 @@ bool CSVFileWriter::writeHeader(String trackId) {
124125
String header;
125126
header += "OBSDataFormat=2&";
126127
header += "OBSFirmwareVersion=" + String(OBSVersion) + "&";
128+
#ifdef OBSPRO
129+
header += "HardwareType=OBSPro&";
130+
header += "HardwareRev=v2.1&"; // TODO: Use hardware revision detection
131+
#endif
132+
#ifdef OBSCLASSIC
133+
header += "HardwareType=OBSClassic&";
134+
//header += "HardwareRev=?" // TODO: Auto detect hardware revision not available in OBSClassic
135+
#endif
127136
header += "DeviceId=" + String((uint16_t)(ESP.getEfuseMac() >> 32), 16) + "&";
128137
header += "DataPerMeasurement=3&";
129138
header += "MaximumMeasurementsPerLine=" + String(MAX_NUMBER_MEASUREMENTS_PER_INTERVAL) + "&";

0 commit comments

Comments
 (0)