summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Anton Lundin <glance@acc.umu.se>2014-10-27 21:55:04 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2014-10-27 14:41:49 -0700
commitb5dedcfba41cf5f3d4d62de37aa83470ce8ccba3 (patch)
tree52a42e9c95580da8e81d64129891bf1d6fb3ad76
parent0afc52579b6827497b6a808556ac0c9e1f7c982d (diff)
downloadsubsurface-b5dedcfba41cf5f3d4d62de37aa83470ce8ccba3.tar.gz
Write config data to the OSTC
This adds code that writes configuration data to the OSTC. As we don't look at all the values in the OSTC config blocks, we read the current blocks and only change the values we can change. Signed-off-by: Anton Lundin <glance@acc.umu.se> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--configuredivecomputerthreads.cpp321
1 files changed, 312 insertions, 9 deletions
diff --git a/configuredivecomputerthreads.cpp b/configuredivecomputerthreads.cpp
index 7c7c912d4..f89aa8d79 100644
--- a/configuredivecomputerthreads.cpp
+++ b/configuredivecomputerthreads.cpp
@@ -493,6 +493,7 @@ void ReadSettingsThread::run()
supported = true;
unsigned char data[256] = {};
#ifdef DEBUG_OSTC_CF
+ // FIXME: how should we report settings not supported back?
unsigned char max_CF = 0;
#endif
rc = hw_ostc_device_eeprom_read(m_data->device, 0, data, sizeof(data));
@@ -534,6 +535,7 @@ void ReadSettingsThread::run()
gas4.type = (data[27] & 0x08) >> 3;
gas5.type = (data[27] & 0x10) >> 4;
+ // Gas switch depths
gas1.depth = data[28];
gas2.depth = data[29];
gas3.depth = data[30];
@@ -735,9 +737,6 @@ void ReadSettingsThread::run()
for(int cf = 0; cf <= 31 && cf <= max_CF; cf++)
printf("CF %d: %d\n", cf, read_ostc_cf(data, cf));
#endif
-#ifdef DEBUG_OSTC
- local_hw_ostc_device_eeprom_write(m_data->device, 0, data, sizeof(data));
-#endif
}
rc = hw_ostc_device_eeprom_read(m_data->device, 1, data, sizeof(data));
if (rc == DC_STATUS_SUCCESS) {
@@ -766,9 +765,6 @@ void ReadSettingsThread::run()
for(int cf = 32; cf <= 63 && cf <= max_CF; cf++)
printf("CF %d: %d\n", cf, read_ostc_cf(data, cf));
#endif
-#ifdef DEBUG_OSTC
- local_hw_ostc_device_eeprom_write(m_data->device, 1, data, sizeof(data));
-#endif
}
rc = hw_ostc_device_eeprom_read(m_data->device, 2, data, sizeof(data));
if (rc == DC_STATUS_SUCCESS) {
@@ -792,9 +788,6 @@ void ReadSettingsThread::run()
for(int cf = 64; cf <= 95 && cf <= max_CF; cf++)
printf("CF %d: %d\n", cf, read_ostc_cf(data, cf));
#endif
-#ifdef DEBUG_OSTC
- local_hw_ostc_device_eeprom_write(m_data->device, 2, data, sizeof(data));
-#endif
}
emit devicedetails(m_deviceDetails);
break;
@@ -831,7 +824,11 @@ void WriteSettingsThread::run()
{
bool supported = false;
dc_status_t rc;
+#ifdef DEBUG_OSTC
+ rc = DC_STATUS_SUCCESS;
+#else
rc = dc_device_open(&m_data->device, m_data->context, m_data->descriptor, m_data->devname);
+#endif
if (rc == DC_STATUS_SUCCESS) {
switch (dc_device_get_type(m_data->device)) {
case DC_FAMILY_SUUNTO_VYPER:
@@ -1029,6 +1026,312 @@ void WriteSettingsThread::run()
break;
}
#endif // divecomputer 0.5.0
+#ifdef DEBUG_OSTC
+ case DC_FAMILY_NULL:
+#endif
+ case DC_FAMILY_HW_OSTC: {
+ supported = true;
+ unsigned char data[256] = {};
+ unsigned char max_CF = 0;
+
+ // Because we write whole memory blocks, we read all the current
+ // values out and then change then ones we should change.
+ rc = hw_ostc_device_eeprom_read(m_data->device, 0, data, sizeof(data));
+ if (rc == DC_STATUS_SUCCESS) {
+ //Byte5-6:
+ //Gas 1 default (%O2=21, %He=0)
+ gas gas1 = m_deviceDetails->gas1();
+ data[6] = gas1.oxygen;
+ data[7] = gas1.helium;
+ //Byte9-10:
+ //Gas 2 default (%O2=21, %He=0)
+ gas gas2 = m_deviceDetails->gas2();
+ data[10] = gas2.oxygen;
+ data[11] = gas2.helium;
+ //Byte13-14:
+ //Gas 3 default (%O2=21, %He=0)
+ gas gas3 = m_deviceDetails->gas3();
+ data[14] = gas3.oxygen;
+ data[15] = gas3.helium;
+ //Byte17-18:
+ //Gas 4 default (%O2=21, %He=0)
+ gas gas4 = m_deviceDetails->gas4();
+ data[18] = gas4.oxygen;
+ data[19] = gas4.helium;
+ //Byte21-22:
+ //Gas 5 default (%O2=21, %He=0)
+ gas gas5 = m_deviceDetails->gas5();
+ data[22] = gas5.oxygen;
+ data[23] = gas5.helium;
+ //Byte25-26:
+ //Gas 6 current (%O2, %He)
+ data[26] = m_deviceDetails->salinity();
+ // Gas types, 0=Disabled, 1=Active, 2=Fist
+ // Active Gas Flag Register
+ data[27] = 0;
+ if (gas1.type)
+ data[27] ^= 0x01;
+ if (gas2.type)
+ data[27] ^= 0x02;
+ if (gas3.type)
+ data[27] ^= 0x04;
+ if (gas4.type)
+ data[27] ^= 0x08;
+ if (gas5.type)
+ data[27] ^= 0x10;
+
+ // Gas switch depths
+ data[28] = gas1.depth;
+ data[29] = gas2.depth;
+ data[30] = gas3.depth;
+ data[31] = gas4.depth;
+ data[32] = gas5.depth;
+ // 33 which gas is Fist gas
+ if (gas1.type == 2)
+ data[33] = 1;
+ else if (gas2.type == 2)
+ data[33] = 2;
+ else if (gas3.type == 2)
+ data[33] = 3;
+ else if (gas4.type == 2)
+ data[33] = 4;
+ else if (gas5.type == 2)
+ data[33] = 5;
+ else {
+ // FIXME: No gas was First?
+ // Set gas 1 to first
+ data[33] = 1;
+ }
+ data[34] = m_deviceDetails->decoType();
+ //Byte36:
+ //Use O2 Sensor Module in CC Modes (0= OFF, 1= ON) (Only available in old OSTC1 - unused for OSTC Mk.2/2N)
+ //m_deviceDetails->setCcrMode(data[35]);
+ data[36] = m_deviceDetails->sp1().sp;
+ data[37] = m_deviceDetails->sp2().sp;
+ data[38] = m_deviceDetails->sp3().sp;
+ // Byte41-42:
+ // Lowest Battery voltage seen (in mV)
+ // Byte43:
+ // Lowest Battery voltage seen at (Month)
+ // Byte44:
+ // Lowest Battery voltage seen at (Day)
+ // Byte45:
+ // Lowest Battery voltage seen at (Year)
+ // Byte46-47:
+ // Lowest Battery voltage seen at (Temperature in 0.1 °C)
+ // Byte48:
+ // Last complete charge at (Month)
+ // Byte49:
+ // Last complete charge at (Day)
+ // Byte50:
+ // Last complete charge at (Year)
+ // Byte51-52:
+ // Total charge cycles
+ // Byte53-54:
+ // Total complete charge cycles
+ // Byte55-56:
+ // Temperature Extrema minimum (Temperature in 0.1 °C)
+ // Byte57:
+ // Temperature Extrema minimum at (Month)
+ // Byte58:
+ // Temperature Extrema minimum at (Day)
+ // Byte59:
+ // Temperature Extrema minimum at (Year)
+ // Byte60-61:
+ // Temperature Extrema maximum (Temperature in 0.1 °C)
+ // Byte62:
+ // Temperature Extrema maximum at (Month)
+ // Byte63:
+ // Temperature Extrema maximum at (Day)
+ // Byte64:
+ // Temperature Extrema maximum at (Year)
+ // Byte65:
+ // Custom Text active (=1), Custom Text Disabled (<>1)
+ // Byte66-90:
+ // (25Bytes): Custom Text for Surfacemode (Real text must end with "}")
+ // Example: OSTC Dive Computer} (19 Characters incl. "}") Bytes 85-90 will be ignored.
+ if (m_deviceDetails->customText() == "")
+ data[64] = 0;
+ else {
+ data[64] = 1;
+ // Copy the string to the right place in the memory, padded with 0x20 (" ")
+ strncpy((char *) data + 65, QString("%1").arg(m_deviceDetails->customText(), -23, QChar(' ')).toUtf8().data(), 23);
+ // And terminate the string.
+ if (m_deviceDetails->customText().length() <= 23)
+ data[65 + m_deviceDetails->customText().length()] = '}';
+ else
+ data[90] = '}';
+ }
+ // Byte91:
+ // Dim OLED in Divemode (>0), Normal mode (=0)
+ // Byte92:
+ // Date format for all outputs:
+ // =0: MM/DD/YY
+ // =1: DD/MM/YY
+ // =2: YY/MM/DD
+ data[91] = m_deviceDetails->dateFormat();
+ // Byte93:
+ // Total number of CF used in installed firmware
+ max_CF = data[92];
+ // Byte94:
+ // Last selected view for customview area in surface mode
+ // Byte95:
+ // Last selected view for customview area in dive mode
+ // Byte96-97:
+ // Diluent 1 Default (%O2,%He)
+ // Byte98-99:
+ // Diluent 1 Current (%O2,%He)
+ gas dil1 = m_deviceDetails->dil1();
+ data[97] = dil1.oxygen;
+ data[98] = dil1.helium;
+ // Byte100-101:
+ // Gasuent 2 Default (%O2,%He)
+ // Byte102-103:
+ // Gasuent 2 Current (%O2,%He)
+ gas dil2 = m_deviceDetails->dil2();
+ data[101] = dil2.oxygen;
+ data[102] = dil2.helium;
+ // Byte104-105:
+ // Gasuent 3 Default (%O2,%He)
+ // Byte106-107:
+ // Gasuent 3 Current (%O2,%He)
+ gas dil3 = m_deviceDetails->dil3();
+ data[105] = dil3.oxygen;
+ data[106] = dil3.helium;
+ // Byte108-109:
+ // Gasuent 4 Default (%O2,%He)
+ // Byte110-111:
+ // Gasuent 4 Current (%O2,%He)
+ gas dil4 = m_deviceDetails->dil4();
+ data[109] = dil4.oxygen;
+ data[110] = dil4.helium;
+ // Byte112-113:
+ // Gasuent 5 Default (%O2,%He)
+ // Byte114-115:
+ // Gasuent 5 Current (%O2,%He)
+ gas dil5 = m_deviceDetails->dil5();
+ data[113] = dil5.oxygen;
+ data[114] = dil5.helium;
+ // Byte116:
+ // First Diluent (1-5)
+ if (dil1.type == 2)
+ data[115] = 1;
+ else if (dil2.type == 2)
+ data[115] = 2;
+ else if (dil3.type == 2)
+ data[115] = 3;
+ else if (dil4.type == 2)
+ data[115] = 4;
+ else if (dil5.type == 2)
+ data[115] = 5;
+ else {
+ // FIXME: No first diluent?
+ // Set gas 1 to fist
+ data[115] = 1;
+ }
+ // Byte117-128:
+ // not used/reserved
+ // Byte129-256:
+ // 32 custom Functions (CF0-CF31)
+
+ // Write the relevant ones
+ // CF11: Factor for saturation processes
+ write_ostc_cf(data, 11, max_CF, m_deviceDetails->saturation());
+ // CF12: Factor for desaturation processes
+ write_ostc_cf(data, 12, max_CF, m_deviceDetails->desaturation());
+ // CF17: Lower threshold for ppO2 warning
+ write_ostc_cf(data, 17, max_CF, m_deviceDetails->ppO2Min());
+ // CF18: Upper threshold for ppO2 warning
+ write_ostc_cf(data, 18, max_CF, m_deviceDetails->ppO2Max());
+ // CF20: Depth sampling rate for Profile storage
+ write_ostc_cf(data, 20, max_CF, m_deviceDetails->samplingRate());
+ // CF29: Depth of last decompression stop
+ write_ostc_cf(data, 29, max_CF, m_deviceDetails->lastDeco());
+
+#ifdef DEBUG_OSTC_CF
+ for(int cf = 0; cf <= 31 && cf <= max_CF; cf++)
+ printf("CF %d: %d\n", cf, read_ostc_cf(data, cf));
+#endif
+ rc = hw_ostc_device_eeprom_write(m_data->device, 0, data, sizeof(data));
+ if (rc != DC_STATUS_SUCCESS) {
+ //FIXME: ERROR!
+ }
+ }
+ rc = hw_ostc_device_eeprom_read(m_data->device, 1, data, sizeof(data));
+ if (rc == DC_STATUS_SUCCESS) {
+ // Byte1:
+ // Logbook version indicator (Not writable!)
+ // Byte2-3:
+ // Last Firmware installed, 1st Byte.2nd Byte (e.g. „1.90“) (Not writable!)
+ // Byte4:
+ // OLED brightness (=0: Eco, =1 High) (Not writable!)
+ // Byte5-11:
+ // Time/Date vault during firmware updates
+ // Byte12-128
+ // not used/reserved
+ // Byte129-256:
+ // 32 custom Functions (CF 32-63)
+
+ // Decode the relevant ones
+ // CF32: Gradient Factor low
+ write_ostc_cf(data, 32, max_CF, m_deviceDetails->gfLow());
+ // CF33: Gradient Factor high
+ write_ostc_cf(data, 33, max_CF, m_deviceDetails->gfHigh());
+ // CF58: Future time to surface setFutureTTS
+ write_ostc_cf(data, 58, max_CF, m_deviceDetails->futureTTS());
+#ifdef DEBUG_OSTC_CF
+ for(int cf = 32; cf <= 63 && cf <= max_CF; cf++)
+ printf("CF %d: %d\n", cf, read_ostc_cf(data, cf));
+#endif
+ rc = hw_ostc_device_eeprom_write(m_data->device, 1, data, sizeof(data));
+ if (rc != DC_STATUS_SUCCESS) {
+ //FIXME: ERROR!
+ }
+ }
+ rc = hw_ostc_device_eeprom_read(m_data->device, 2, data, sizeof(data));
+ if (rc == DC_STATUS_SUCCESS) {
+ // Byte1-4:
+ // not used/reserved (Not writable!)
+ // Byte5-128:
+ // not used/reserved
+ // Byte129-256:
+ // 32 custom Functions (CF 64-95)
+
+ // Decode the relevant ones
+ // CF65: Show safety stop
+ write_ostc_cf(data, 65, max_CF, m_deviceDetails->safetyStop());
+ // CF67: Alternaitve Gradient Factor low
+ write_ostc_cf(data, 67, max_CF, m_deviceDetails->aGFLow());
+ // CF68: Alternative Gradient Factor high
+ write_ostc_cf(data, 68, max_CF, m_deviceDetails->aGFHigh());
+ // CF69: Allow Gradient Factor change
+ write_ostc_cf(data, 69, max_CF, m_deviceDetails->aGFSelectable());
+#ifdef DEBUG_OSTC_CF
+ for(int cf = 64; cf <= 95 && cf <= max_CF; cf++)
+ printf("CF %d: %d\n", cf, read_ostc_cf(data, cf));
+#endif
+ rc = hw_ostc_device_eeprom_write(m_data->device, 2, data, sizeof(data));
+ if (rc != DC_STATUS_SUCCESS) {
+ //FIXME: ERROR!
+ }
+ }
+ //sync date and time
+ if (m_deviceDetails->syncTime()) {
+ QDateTime timeToSet = QDateTime::currentDateTime();
+ dc_datetime_t time;
+ time.year = timeToSet.date().year();
+ time.month = timeToSet.date().month();
+ time.day = timeToSet.date().day();
+ time.hour = timeToSet.time().hour();
+ time.minute = timeToSet.time().minute();
+ time.second = timeToSet.time().second();
+ rc = hw_ostc_device_clock(m_data->device, &time);
+ if (rc != DC_STATUS_SUCCESS) {
+ //FIXME: ERROR!
+ }
+ }
+ break;
+ }
default:
supported = false;
break;