Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Extend Dallas 1-Wire] Add support for read PIO-A of DS2406 #2174

Merged
merged 2 commits into from
Mar 12, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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