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>
This commit is contained in:
Anton Lundin 2014-10-27 21:55:04 +01:00 committed by Dirk Hohndel
parent 0afc52579b
commit b5dedcfba4

View file

@ -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];
@ -734,9 +736,6 @@ void ReadSettingsThread::run()
#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
#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));
@ -765,9 +764,6 @@ void ReadSettingsThread::run()
#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
#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));
@ -791,9 +787,6 @@ void ReadSettingsThread::run()
#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
#ifdef DEBUG_OSTC
local_hw_ostc_device_eeprom_write(m_data->device, 2, data, sizeof(data));
#endif
}
emit devicedetails(m_deviceDetails);
@ -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;