Skip to content

Commit

Permalink
Add support for read PIO-A of DS2406 (#2174)
Browse files Browse the repository at this point in the history
* Add support for read PIO-A of DS2406

* Verify reset() reseult
  • Loading branch information
rmcbc authored Mar 12, 2020
1 parent c02a981 commit ae232c9
Showing 1 changed file with 121 additions and 28 deletions.
149 changes: 121 additions & 28 deletions code/espurna/sensors/DallasSensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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; i<DS2406_STATE_BUF_LEN; 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;
}

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() {
Expand Down Expand Up @@ -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() {
Expand All @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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");
}

Expand Down

0 comments on commit ae232c9

Please sign in to comment.