From ae232c938101f2becb2c4b2d65de04e84282b4bd Mon Sep 17 00:00:00 2001 From: Rui Caridade Date: Thu, 12 Mar 2020 03:03:46 +0000 Subject: [PATCH] Add support for read PIO-A of DS2406 (#2174) * Add support for read PIO-A of DS2406 * Verify reset() reseult --- code/espurna/sensors/DallasSensor.h | 149 ++++++++++++++++++++++------ 1 file changed, 121 insertions(+), 28 deletions(-) diff --git a/code/espurna/sensors/DallasSensor.h b/code/espurna/sensors/DallasSensor.h index ca5218aa..9c7c791d 100644 --- a/code/espurna/sensors/DallasSensor.h +++ b/code/espurna/sensors/DallasSensor.h @@ -16,6 +16,7 @@ #include "BaseSensor.h" #define DS_CHIP_DS18S20 0x10 +#define DS_CHIP_DS2406 0x12 #define DS_CHIP_DS1822 0x22 #define DS_CHIP_DS18B20 0x28 #define DS_CHIP_DS1825 0x3B @@ -27,6 +28,40 @@ #define DS_CMD_START_CONVERSION 0x44 #define DS_CMD_READ_SCRATCHPAD 0xBE +// ====== DS2406 specific constants ======= + +#define DS2406_CHANNEL_ACCESS 0xF5; + +// CHANNEL CONTROL BYTE +// 7 6 5 4 3 2 1 0 +// ALR IM TOG IC CHS1 CHS0 CRC1 CRC0 +// 0 1 0 0 0 1 0 1 0x45 + +// CHS1 CHS0 Description +// 0 0 (not allowed) +// 0 1 channel A only +// 1 0 channel B only +// 1 1 both channels interleaved + +// TOG IM CHANNELS EFFECT +// 0 0 one channel Write all bits to the selected channel +// 0 1 one channel Read all bits from the selected channel +// 1 0 one channel Write 8 bits, read 8 bits, write, read, etc. to/from the selected channel +// 1 1 one channel Read 8 bits, write 8 bits, read, write, etc. from/to the selected channel +// 0 0 two channels Repeat: four times (write A, write B) +// 0 1 two channels Repeat: four times (read A, read B) +// 1 0 two channels Four times: (write A, write B), four times: (readA, read B), write, read, etc. +// 1 1 two channels Four times: (read A, read B), four times: (write A, write B), read, write, etc. + +// CRC1 CRC0 Description +// 0 0 CRC disabled (no CRC at all) +// 0 1 CRC after every byte +// 1 0 CRC after 8 bytes +// 1 1 CRC after 32 bytes +#define DS2406_CHANNEL_CONTROL_BYTE 0x45; + +#define DS2406_STATE_BUF_LEN 7 + class DallasSensor : public BaseSensor { public: @@ -120,37 +155,68 @@ class DallasSensor : public BaseSensor { // Read scratchpads for (unsigned char index=0; index<_devices.size(); index++) { - // Read scratchpad - if (_wire->reset() == 0) { - // Force a CRC check error - _devices[index].data[0] = _devices[index].data[0] + 1; - return; - } + if (_devices[index].address[0] == DS_CHIP_DS2406) { - _wire->select(_devices[index].address); - _wire->write(DS_CMD_READ_SCRATCHPAD); + uint8_t data[DS2406_STATE_BUF_LEN]; - uint8_t data[DS_DATA_SIZE]; - for (unsigned char i = 0; i < DS_DATA_SIZE; i++) { - data[i] = _wire->read(); - } + // Read scratchpad + if (_wire->reset() == 0) { + // Force a CRC check error + _devices[index].data[0] = _devices[index].data[0] + 1; + return; + } + + _wire->select(_devices[index].address); - if (_wire->reset() != 1) { - // Force a CRC check error - _devices[index].data[0] = _devices[index].data[0] + 1; - return; - } + data[0] = DS2406_CHANNEL_ACCESS; + data[1] = DS2406_CHANNEL_CONTROL_BYTE; + data[2] = 0xFF; - memcpy(_devices[index].data, data, DS_DATA_SIZE); + _wire->write_bytes(data,3); - } + // 3 cmd bytes, 1 channel info byte, 1 0x00, 2 CRC16 + for(int i = 3; iread(); + } - } + // Read scratchpad + if (_wire->reset() == 0) { + // Force a CRC check error + _devices[index].data[0] = _devices[index].data[0] + 1; + return; + } - conversion = !conversion; + memcpy(_devices[index].data, data, DS2406_STATE_BUF_LEN); - } + } else { + + // Read scratchpad + if (_wire->reset() == 0) { + // Force a CRC check error + _devices[index].data[0] = _devices[index].data[0] + 1; + return; + } + _wire->select(_devices[index].address); + _wire->write(DS_CMD_READ_SCRATCHPAD); + + uint8_t data[DS_DATA_SIZE]; + for (unsigned char i = 0; i < DS_DATA_SIZE; i++) { + data[i] = _wire->read(); + } + + if (_wire->reset() != 1) { + // Force a CRC check error + _devices[index].data[0] = _devices[index].data[0] + 1; + return; + } + + memcpy(_devices[index].data, data, DS_DATA_SIZE); + } + } + } + conversion = !conversion; + } // Descriptive name of the sensor String description() { @@ -190,14 +256,20 @@ class DallasSensor : public BaseSensor { // Type for slot # index unsigned char type(unsigned char index) { - if (index < _count) return MAGNITUDE_TEMPERATURE; + if (index < _count) { + if (chip(index) == DS_CHIP_DS2406) { + return MAGNITUDE_DIGITAL; + } else { + return MAGNITUDE_TEMPERATURE; + } + } return MAGNITUDE_NONE; } - // Number of decimals for a magnitude (or -1 for default) - signed char decimals(unsigned char type) { - return 2; // smallest increment is 0.0625 C, so 2 decimals - } + // Number of decimals for a magnitude (or -1 for default) + signed char decimals(unsigned char type) { + return 2; // smallest increment is 0.0625 C, so 2 decimals + } // Pre-read hook (usually to populate registers with up-to-date data) void pre() { @@ -211,6 +283,26 @@ class DallasSensor : public BaseSensor { uint8_t * data = _devices[index].data; + if (chip(index) == DS_CHIP_DS2406) { + + if (!OneWire::check_crc16(data, 5, &data[5])) { + _error = SENSOR_ERROR_CRC; + return 0; + } + + // 3 cmd bytes, 1 channel info byte, 1 0x00, 2 CRC16 + // CHANNEL INFO BYTE + // Bit 7 : Supply Indication 0 = no supply + // Bit 6 : Number of Channels 0 = channel A only + // Bit 5 : PIO-B Activity Latch + // Bit 4 : PIO-A Activity Latch + // Bit 3 : PIO B Sensed Level + // Bit 2 : PIO A Sensed Level + // Bit 1 : PIO-B Channel Flip-Flop Q + // Bit 0 : PIO-A Channel Flip-Flop Q + return (data[3] & 0x04) != 0; + } + if (OneWire::crc8(data, DS_DATA_SIZE-1) != data[DS_DATA_SIZE-1]) { _error = SENSOR_ERROR_CRC; return 0; @@ -261,7 +353,7 @@ class DallasSensor : public BaseSensor { // --------------------------------------------------------------------- bool validateID(unsigned char id) { - return (id == DS_CHIP_DS18S20) || (id == DS_CHIP_DS18B20) || (id == DS_CHIP_DS1822) || (id == DS_CHIP_DS1825); + return (id == DS_CHIP_DS18S20) || (id == DS_CHIP_DS18B20) || (id == DS_CHIP_DS1822) || (id == DS_CHIP_DS1825) || (id == DS_CHIP_DS2406) ; } unsigned char chip(unsigned char index) { @@ -275,6 +367,7 @@ class DallasSensor : public BaseSensor { if (chip_id == DS_CHIP_DS18B20) return String("DS18B20"); if (chip_id == DS_CHIP_DS1822) return String("DS1822"); if (chip_id == DS_CHIP_DS1825) return String("DS1825"); + if (chip_id == DS_CHIP_DS2406) return String("DS2406"); return String("Unknown"); }