Skip to content

Commit

Permalink
Comments
Browse files Browse the repository at this point in the history
  • Loading branch information
cybergibbons committed Feb 23, 2014
1 parent 85bc0cc commit b33db8c
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 13 deletions.
99 changes: 88 additions & 11 deletions OneWire.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
#include "OneWire.h"
#include <Wire.h>

// Constructor with no parameters for compatability with OneWire lib
OneWire::OneWire()
{
OneWire(0);
}

OneWire::OneWire(uint8_t address)
{
// Address is determined by two pins on the DS2482 AD1/AD0
// Pass 0b00, 0b01, 0b10 or 0b11
mAddress = 0x18 | address;
mError = 0;
Wire.begin();
}

Expand All @@ -22,6 +26,7 @@ uint8_t OneWire::getError()
return mError;
}

// Helper functions to make dealing with I2C side easier
void OneWire::begin()
{
Wire.beginTransmission(mAddress);
Expand All @@ -43,19 +48,23 @@ uint8_t OneWire::readByte()
return Wire.read();
}

// Simply starts and ends an Wire transmission
// If no devices are present, this returns false
uint8_t OneWire::checkPresence()
{
begin();
return end();
}

// Performs a global reset of device state machine logic. Terminates any ongoing 1-Wire communication.
void OneWire::deviceReset()
{
begin();
write(DS2482_COMMAND_RESET);
end();
}

// Sets the read pointer to the specified register. Overwrites the read pointer position of any 1-Wire communication command in progress.
void OneWire::setReadPointer(uint8_t readPointer)
{
begin();
Expand All @@ -64,24 +73,32 @@ void OneWire::setReadPointer(uint8_t readPointer)
end();
}

// Read the status register
uint8_t OneWire::readStatus()
{
setReadPointer(DS2482_POINTER_STATUS);
return readByte();
}

// Read the data register
uint8_t OneWire::readData()
{
setReadPointer(DS2482_POINTER_DATA);
return readByte();
}

// Read the config register
uint8_t OneWire::readConfig()
{
setReadPointer(DS2482_POINTER_CONFIG);
return readByte();
}

// Churn until the busy bit in the status register is clear
uint8_t OneWire::waitOnBusy()
{
uint8_t status;

int testCount = 2000;

for(int i=1000; i>0; i--)
{
status = readStatus();
Expand All @@ -90,30 +107,32 @@ uint8_t OneWire::waitOnBusy()
delayMicroseconds(20);
}

// if we have reached this point and we are still busy, there is an error
if (status & DS2482_STATUS_BUSY)
mError = 1;
mError = DS2482_ERROR_TIMEOUT;

// Return the status so we don't need to explicitly do it again
return status;
}

uint8_t OneWire::readConfig()
{
setReadPointer(DS2482_POINTER_CONFIG);
return readByte();
}

// Write to the config register
void OneWire::writeConfig(uint8_t config)
{
waitOnBusy();
begin();
writeByte(DS2482_COMMAND_WRITECONFIG);
// Write the 4 bits and the complement 4 bits
writeByte(config | (~config)<<4);
end();

// This should return the config bits without the complement
if (readByte() != config)
mError = 1;
mError = DS2482_ERROR_CONFIG;
}

// Generates a 1-Wire reset/presence-detect cycle (Figure 4) at the 1-Wire line. The state
// of the 1-Wire line is sampled at tSI and tMSP and the result is reported to the host
// processor through the Status Register, bits PPD and SD.
uint8_t OneWire::wireReset()
{
waitOnBusy();
Expand All @@ -123,9 +142,15 @@ uint8_t OneWire::wireReset()

uint8_t status = waitOnBusy();

return status & DS2482_STATUS_PPD ? true : false;
if (status & DS2482_STATUS_SD)
{
mError = DS2482_ERROR_SHORT;
}

return (status & DS2482_STATUS_PPD) ? true : false;
}

// Writes a single data byte to the 1-Wire line.
void OneWire::wireWriteByte(uint8_t data)
{
waitOnBusy();
Expand All @@ -135,6 +160,7 @@ void OneWire::wireWriteByte(uint8_t data)
end();
}

// Generates eight read-data time slots on the 1-Wire line and stores result in the Read Data Register.
uint8_t OneWire::wireReadByte()
{
waitOnBusy();
Expand All @@ -145,6 +171,10 @@ uint8_t OneWire::wireReadByte()
return readData();
}

// Generates a single 1-Wire time slot with a bit value “V” as specified by the bit byte at the 1-Wire line
// (see Table 2). A V value of 0b generates a write-zero time slot (Figure 5); a V value of 1b generates a
// write-one time slot, which also functions as a read-data time slot (Figure 6). In either case, the logic
// level at the 1-Wire line is tested at tMSR and SBR is updated.
void OneWire::wireWriteBit(uint8_t data)
{
waitOnBusy();
Expand All @@ -154,13 +184,15 @@ void OneWire::wireWriteBit(uint8_t data)
end();
}

// As wireWriteBit
uint8_t OneWire::wireReadBit()
{
wireWriteBit(1);
uint8_t status = waitOnBusy();
return status & DS2482_STATUS_SBR ? 1 : 0;
}

// 1-Wire skip
void OneWire::wireSkip()
{
wireWriteByte(WIRE_COMMAND_SKIP);
Expand All @@ -173,6 +205,7 @@ void OneWire::wireSelect(const uint8_t rom[8])
wireWriteByte(rom[i]);
}

// 1-Wire reset seatch algorithm
void OneWire::wireResetSearch()
{
searchLastDiscrepancy = 0;
Expand All @@ -185,6 +218,7 @@ void OneWire::wireResetSearch()

}

// Perform a search of the 1-Wire bus
uint8_t OneWire::wireSearch(uint8_t *address)
{
uint8_t direction;
Expand Down Expand Up @@ -252,6 +286,48 @@ uint8_t OneWire::wireSearch(uint8_t *address)
return 1;
}

#if ONEWIRE_CRC8_TABLE
// This table comes from Dallas sample code where it is freely reusable,
// though Copyright (C) 2000 Dallas Semiconductor Corporation
static const uint8_t PROGMEM dscrc_table[] = {
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};

//
// Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM
// and the registers. (note: this might better be done without to
// table, it would probably be smaller and certainly fast enough
// compared to all those delayMicrosecond() calls. But I got
// confused, so I use this table from the examples.)
//
uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len)
{
uint8_t crc = 0;

while (len--) {
crc = pgm_read_byte(dscrc_table + (crc ^ *addr++));
}
return crc;
}
#else
//
// Compute a Dallas Semiconductor 8 bit CRC directly.
// this is much slower, but much smaller, than the lookup table.
//
uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len)
{
uint8_t crc = 0;
Expand All @@ -267,6 +343,7 @@ uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len)
}
return crc;
}
#endif

void OneWire::reset_search()
{
Expand Down
10 changes: 8 additions & 2 deletions OneWire.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

#include <inttypes.h>

// Chose between a table based CRC (flash expensive, fast)
// or a computed CRC (smaller, slow)
#define ONEWIRE_CRC8_TABLE 1

#define DS2482_COMMAND_RESET 0xF0 // Device reset

#define DS2482_COMMAND_SRP 0xE1 // Set read pointer
Expand All @@ -29,6 +33,10 @@
#define WIRE_COMMAND_SELECT 0x55
#define WIRE_COMMAND_SEARCH 0xF0

#define DS2482_ERROR_TIMEOUT (1<<0)
#define DS2482_ERROR_SHORT (1<<1)
#define DS2482_ERROR_CONFIG (1<<2)

class OneWire
{
public:
Expand Down Expand Up @@ -67,8 +75,6 @@ class OneWire
uint8_t read_bit(void);
void write_bit(uint8_t v);



private:
void begin();
uint8_t end();
Expand Down

0 comments on commit b33db8c

Please sign in to comment.