one wire driver
Dependents: 09_PT1000 10_PT1000 11_PT1000
DS2482.cpp
- Committer:
- rs27
- Date:
- 2014-07-26
- Revision:
- 5:d94037eb31ed
- Parent:
- 4:c29e67d55f86
File content as of revision 5:d94037eb31ed:
#include "mbed.h"
#include "DS2482.h"
#include "monitor.h"
extern Serial pc;
//-----------------------------------------------------------------------------
// CRC = X^8 + X^5 + X^4 + 1
#define CRC_TABLE_ITEMS 256
const uint8_t crc_table[CRC_TABLE_ITEMS] =
{
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
};
//==========================================================================
// destructor
DS2482::DS2482(PinName sda, PinName scl, int address) : i2c(sda, scl)
{
addr = address;
i2c.frequency(100000);
}
//-----------------------------------------------------------------------------
// Calculate the CRC8 of the byte value provided with the current
// global 'crc8' value.
// Returns current global crc8 value
//
uint8_t DS2482::crc_calc(uint8_t x)
{
crc_value = crc_table[crc_value ^ x];
return crc_value;
}
uint8_t DS2482::crc_calc_buffer(uint8_t *pbuffer, uint8_t count)
{
uint8_t n;
crc_value = 0;
for (n = 0; n < count; n++)
{
crc_value = crc_table[crc_value ^ *pbuffer++];
}
return crc_value;
}
//==========================================================================
// I2C DS2482
//
//--------------------------------------------------------------------------
// DS2482 Detect routine that sets the I2C address and then performs a
// device reset followed by writing the configuration byte to default values:
// 1-Wire speed (c1WS) = standard (0)
// Strong pullup (cSPU) = off (0)
// Presence pulse masking (cPPM) = off (0)
// Active pullup (cAPU) = on (CONFIG_APU = 0x01)
//
// Returns: TRUE if device was detected and written
// FALSE device not detected or failure to write configuration byte
//uint8_t DS2482_detect(unsigned char addr)
//
uint8_t DS2482::detect(void)
{
if (!reset()) // reset the DS2482 ON selected address
{
#if OW_MASTER_START
pc.printf("\r\n--- DS2482 bus0 reset not executed \n");
wait(0.1);
#endif
return false;
}
// default configuration
c1WS = 0;
cSPU = 0;
cPPM = 0;
cAPU = DS2482_CFG_APU;
// write the default configuration setup
if (!write_config(c1WS | cSPU | cPPM | cAPU))
{
#if OW_MASTER_START
pc.printf("\r\n--- DS2482 configuration failure \n");
wait(0.1);
#endif
return false;
}
#if OW_MASTER_START
pc.printf("\r\n*** DS2482 detect OK \n");
wait(0.1);
#endif
return true;
}
//--------------------------------------------------------------------------
// Perform a device reset on the DS2482
//
// Returns: TRUE if device was reset
// FALSE device not detected or failure to perform reset
//
int DS2482::reset(void)
{
char cmd[2];
cmd[0] = DS2482_CMD_DRST;
// pc.printf("\nreset write");
i2c.write(addr, cmd, 1);
// pc.printf("\nreset read");
i2c.read(addr, cmd, 1);
// pc.printf(" cmd = %02x \n",cmd[0]);
wait(0.1);
return ((cmd[0] & 0xF7) == 0x10);
}
//--------------------------------------------------------------------------
// Write the configuration register in the DS2482. The configuration
// options are provided in the lower nibble of the provided config byte.
// The uppper nibble in bitwise inverted when written to the DS2482.
//
// Returns: TRUE: config written and response correct
// FALSE: response incorrect
//
uint8_t DS2482::write_config(uint8_t config)
{
char cmd[2];
char read_config;
cmd[0] = DS2482_CMD_WCFG;
cmd[1] = config | (~config << 4);
i2c.write(addr, cmd, 2);
i2c.read(addr, cmd, 1);
read_config = cmd[0];
if (config != read_config) // check for failure due to incorrect read back
{
// handle error
// ...
#if OW_MASTER_START
pc.printf("\r\n---check for failure due to incorrect config read back");
#endif
reset();
return false;
}
return true;
}
//--------------------------------------------------------------------------
// DS2482 1-Wire Operations
//--------------------------------------------------------------------------
//
//OWReset
//--------------------------------------------------------------------------
// Reset all of the devices on the 1-Wire Net and return the result.
//
// Returns: TRUE(1): presence pulse(s) detected, device(s) reset
// FALSE(0): no presence pulses detected
//
uint8_t DS2482::OWReset(void)
{
uint8_t poll_count = 0;
char cmd[2];
cmd[0] = DS2482_CMD_1WRS;
i2c.write(addr,cmd,1);
#if OW_MASTER_DEBUG
pc.printf("\r\n*** Reset all devices on the 1-Wire Net\r\n");
#endif
do
{
i2c.read(addr,cmd,1);
// pc.printf("\n read %04x",cmd[0]);
}
while ((cmd[0] & DS2482_STATUS_1WB) && (poll_count++ < POLL_LIMIT));
// check for failure due to poll limit reached
if (poll_count >= POLL_LIMIT)
{
// handle error
// ...
#if OW_MASTER_DEBUG
pc.printf("\r\n---poll limit reached");
#endif
reset();
return false;
}
// check for short condition
if (cmd[0] & DS2482_STATUS_SD)
{
#if OW_MASTER_DEBUG
pc.printf("\r\n---1-Wire Net short detected %04x",cmd[0]);
#endif
short_detected = true;
}
else
{
#if OW_MASTER_DEBUG
pc.printf("\r\n*** 1-Wire electrical net is OK");
#endif
short_detected = false;
}
// check for presence detect
if (cmd[0] & DS2482_STATUS_PPD)
{
#if OW_MASTER_DEBUG
pc.printf("\r\n*** 1-Wire Device detected");
#endif
return true;
}
else
{
#if OW_MASTER_DEBUG
pc.printf("\r\n---No Device detected");
#endif
return false;
}
}
//--------------------------------------------------------------------------
// Send 1 bit of communication to the 1-Wire Net.
// The parameter 'sendbit' least significant bit is used.
//
// 'sendbit' - 1 bit to send (least significant byte)
//
void DS2482::OWWriteBit(uint8_t sendbit)
{
OWTouchBit(sendbit);
}
//--------------------------------------------------------------------------
// Reads 1 bit of communication from the 1-Wire Net and returns the
// result
//
// Returns: 1 bit read from 1-Wire Net
//
uint8_t DS2482::OWReadBit(void)
{
return OWTouchBit(0x01);
}
//--------------------------------------------------------------------------
// Send 1 bit of communication to the 1-Wire Net and return the
// result 1 bit read from the 1-Wire Net. The parameter 'sendbit'
// least significant bit is used and the least significant bit
// of the result is the return bit.
//
// 'sendbit' - the least significant bit is the bit to send
//
// Returns: 0: 0 bit read from sendbit
// 1: 1 bit read from sendbit
//
uint8_t DS2482::OWTouchBit(uint8_t sendbit)
{
char cmd[2];
uint8_t poll_count = 0;
cmd[0] = DS2482_CMD_1WSB;
cmd[1] = sendbit ? 0x80 : 0x00;
i2c.write(addr, cmd, 2);
// loop checking 1WB bit for completion of 1-Wire operation
// abort if poll limit reached
do
{
i2c.read(addr, cmd, 1);
}
while ((cmd[0] & DS2482_STATUS_1WB) && (poll_count++ < POLL_LIMIT));
#if OW_MASTER_DEBUG
pc.printf("\r\n*** Send 1 bit to the 1-Wire Net");
#endif
// check for failure due to poll limit reached
if (poll_count >= POLL_LIMIT)
{
// handle error
// ...
#if OW_MASTER_DEBUG
pc.printf("\r\n---handle error OW Write Bit");
#endif
reset();
return 0;
}
// return bit state
if (cmd[0] & DS2482_STATUS_SBR)
{
return 1;
}
else
{
return 0;
}
}
//--------------------------------------------------------------------------
// Send 8 bits of communication to the 1-Wire Net and verify that the
// 8 bits read from the 1-Wire Net are the same (write operation).
// The parameter 'sendbyte' least significant 8 bits are used.
//
// 'sendbyte' - 8 bits to send (least significant byte)
//
// Returns: TRUE: bytes written and echo was the same
// FALSE: echo was not the same
//
void DS2482::OWWriteByte(uint8_t sendbyte)
{
char cmd[2];
uint8_t poll_count = 0;
#if OW_MASTER_DEBUG
pc.printf("\r\n*** Send 8 bits of WRITE to the 1-Wire Net");
#endif
cmd[0] = DS2482_CMD_1WWB;
cmd[1] = sendbyte;
i2c.write(addr, cmd, 2);
// loop checking 1WB bit for completion of 1-Wire operation
// abort if poll limit reached
do
{
i2c.read(addr, cmd, 1);
}
while ((cmd[0] & DS2482_STATUS_1WB) && (poll_count++ < POLL_LIMIT));
// check for failure due to poll limit reached
if (poll_count >= POLL_LIMIT)
{
// handle error
// ...
#if OW_MASTER_DEBUG
pc.printf("\r\n---handle error OW Write Byte");
#endif
reset();
}
#if OW_MASTER_DEBUG
pc.printf(" done");
#endif
}
//--------------------------------------------------------------------------
// Send 8 bits of read communication to the 1-Wire Net and return the
// result 8 bits read from the 1-Wire Net.
//
// Returns: 8 bits read from 1-Wire Net
//
uint8_t DS2482::OWReadByte(void)
{
uint8_t poll_count = 0;
char cmd[2];
#if OW_MASTER_DEBUG
pc.printf("\r\n*** Read 8 bits from the 1-Wire Net");
#endif
cmd[0] = DS2482_CMD_1WRB; // DS2482 1-Wire Read Byte
i2c.write(addr, cmd, 1);
// loop checking 1WB bit for completion of 1-Wire operation
// abort if poll limit reached
do
{
i2c.read(addr, cmd, 1);
}
while ((cmd[0] & DS2482_STATUS_1WB) && (poll_count++ < POLL_LIMIT));
// check for failure due to poll limit reached
if (poll_count >= POLL_LIMIT)
{
// handle error
// ...
#if OW_MASTER_DEBUG
pc.printf("\r\n---handle error OW Read Byte");
#endif
reset();
return 0;
}
cmd[0] = DS2482_CMD_SRP; // DS2482 Set Read Pointer
cmd[1] = DS2482_READPTR_RDR; // DS2482 Read Data Register
i2c.write(addr, cmd, 2);
i2c.read(addr, cmd, 1);
return cmd[0];
}
//--------------------------------------------------------------------------
// The 'OWBlock' transfers a block of data to and from the
// 1-Wire Net. The result is returned in the same buffer.
//
// 'tran_buf' - pointer to a block of unsigned
// chars of length 'tran_len' that will be sent
// to the 1-Wire Net
// 'tran_len' - length in bytes to transfer
//
void DS2482::OWBlock(uint8_t *tran_buf, uint8_t tran_len)
{
uint8_t i;
for (i = 0; i < tran_len; i++)
{
tran_buf[i] = OWTouchByte(tran_buf[i]);
}
}
//--------------------------------------------------------------------------
// Send 8 bits of communication to the 1-Wire Net and return the
// result 8 bits read from the 1-Wire Net. The parameter 'sendbyte'
// least significant 8 bits are used and the least significant 8 bits
// of the result are the return byte.
//
// 'sendbyte' - 8 bits to send (least significant byte)
//
// Returns: 8 bits read from sendbyte
//
uint8_t DS2482::OWTouchByte(uint8_t sendbyte)
{
if (sendbyte == 0xFF)
{
return OWReadByte();
}
else
{
OWWriteByte(sendbyte);
return sendbyte;
}
}
//--------------------------------------------------------------------------
// Search state
//--------------------------------------------------------------------------
// Find the 'first' devices on the 1-Wire network
// Return TRUE : device found, ROM number in ROM_NO buffer
// FALSE : no device present
//
uint8_t DS2482::OWFirst(void)
{
// reset the search state
LastDiscrepancy = 0;
LastDeviceFlag = FALSE;
LastFamilyDiscrepancy = 0;
#if OW_MASTER_DEBUG
pc.printf("\r\n*** Find the 'first' device on the 1-Wire network");
#endif
return OWSearch();
}
//--------------------------------------------------------------------------
// Find the 'next' devices on the 1-Wire network
// Return TRUE : device found, ROM number in ROM_NO buffer
// FALSE : device not found, end of search
//
uint8_t DS2482::OWNext(void)
{
#if OW_MASTER_DEBUG
pc.printf("\r\n*** Find the 'next' device on the 1-Wire network");
#endif
// leave the search state alone
return OWSearch();
}
//--------------------------------------------------------------------------
// Verify the device with the ROM number in ROM_NO buffer is present.
// Return TRUE : device present
// FALSE : device not present
//
int DS2482::OWVerify(void)
{
uint8_t rom_backup[8], status;
int i,ld_backup,ldf_backup,lfd_backup;
// keep a backup copy of the current state
for (i = 0; i < 8; i++)
{
rom_backup[i] = ROM_NO[i];
}
ld_backup = LastDiscrepancy;
ldf_backup = LastDeviceFlag;
lfd_backup = LastFamilyDiscrepancy;
// set search to find the same device
LastDiscrepancy = 64;
LastDeviceFlag = FALSE;
if (OWSearch())
{
// check if same device found
status = TRUE;
for (i = 0; i < 8; i++)
{
if (rom_backup[i] != ROM_NO[i])
{
status = FALSE;
break;
}
}
}
else
{
status = FALSE;
}
// restore the search state
for (i = 0; i < 8; i++)
{
ROM_NO[i] = rom_backup[i];
}
LastDiscrepancy = ld_backup;
LastDeviceFlag = ldf_backup;
LastFamilyDiscrepancy = lfd_backup;
// return the result of the verify
#if OW_MASTER_DEBUG
pc.printf("\r\n*** 1-Wire Verify device with the ROM number in ROM_NO");
#endif
return status;
}
//--------------------------------------------------------------------------
// Setup the search to find the device type 'family_code' on the next call
// to OWNext() if it is present.
//
void DS2482::OWTargetSetup(uint8_t family_code)
{
uint8_t i;
// set the search state to find SearchFamily type devices
ROM_NO[0] = family_code;
for (i = 1; i < 8; i++)
{
ROM_NO[i] = 0;
}
LastDiscrepancy = 64;
LastFamilyDiscrepancy = 0;
LastDeviceFlag = FALSE;
}
//--------------------------------------------------------------------------
// Setup the search to skip the current device type on the next call
// to OWNext().
//
void DS2482::OWFamilySkipSetup(void)
{
// set the Last discrepancy to last family discrepancy
LastDiscrepancy = LastFamilyDiscrepancy;
// clear the last family discrpepancy
LastFamilyDiscrepancy = 0;
// check for end of list
if (LastDiscrepancy == 0)
{
LastDeviceFlag = TRUE;
}
}
//--------------------------------------------------------------------------
// The 'OWSearch' function does a general search. This function
// continues from the previous search state. The search state
// can be reset by using the 'OWFirst' function.
// This function contains one parameter 'alarm_only'.
// When 'alarm_only' is TRUE (1) the find alarm command
// 0xEC is sent instead of the normal search command 0xF0.
// Using the find alarm command 0xEC will limit the search to only
// 1-Wire devices that are in an 'alarm' state.
//
// Returns: TRUE (1) : when a 1-Wire device was found and its
// Serial Number placed in the global ROM
// FALSE (0): when no new device was found. Either the
// last search was the last device or there
// are no devices on the 1-Wire Net.
//
uint8_t DS2482::OWSearch()
{
int id_bit_number;
int last_zero, rom_byte_number, search_result;
int id_bit, cmp_id_bit;
uint8_t rom_byte_mask, search_direction, status;
// initialize for search
id_bit_number = 1;
last_zero = 0;
rom_byte_number = 0;
rom_byte_mask = 1;
search_result = FALSE;
crc_value = 0;
#if OW_MASTER_DEBUG
pc.printf("\r\n*** one wire search");
#endif
if (!LastDeviceFlag) // if the last call was not the last one
{
// 1-Wire reset
if (!OWReset())
{
// reset the search
LastDiscrepancy = 0;
LastDeviceFlag = FALSE;
LastFamilyDiscrepancy = 0;
return FALSE;
}
// issue the search command
OWWriteByte(OW_SEARCH_ROM);
// loop to do the search
do
{
// if this discrepancy if before the Last Discrepancy
// on a previous next then pick the same as last time
if (id_bit_number < LastDiscrepancy)
{
if ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0)
search_direction = 1;
else
search_direction = 0;
}
else
{
// if equal to last pick 1, if not then pick 0
if (id_bit_number == LastDiscrepancy)
search_direction = 1;
else
search_direction = 0;
}
// Perform a triple operation on the DS2482 which will perform 2 read bits and 1 write bit
//pc.printf("\n *** preform triplet operation ");
status = search_triplet(search_direction);
//pc.printf("%04x",status);
// check bit results in status byte
id_bit = ((status & DS2482_STATUS_SBR) == DS2482_STATUS_SBR);
cmp_id_bit = ((status & DS2482_STATUS_TSB) == DS2482_STATUS_TSB);
search_direction = ((status & DS2482_STATUS_DIR) == DS2482_STATUS_DIR) ? 1 : 0;
// check for no devices on 1-Wire
if ((id_bit) && (cmp_id_bit))
{
break;
}
else
{
if ((!id_bit) && (!cmp_id_bit) && (search_direction == 0))
{
last_zero = id_bit_number;
// check for Last discrepancy in family
if (last_zero < 9)
{
LastFamilyDiscrepancy = last_zero;
}
}
// set or clear the bit in the ROM byte rom_byte_number
// with mask rom_byte_mask
if (search_direction == 1)
{
ROM_NO[rom_byte_number] |= rom_byte_mask;
}
else
{
ROM_NO[rom_byte_number] &= ~rom_byte_mask;
}
// increment the byte counter id_bit_number
// and shift the mask rom_byte_mask
id_bit_number++;
rom_byte_mask <<= 1;
// if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
if (rom_byte_mask == 0)
{
crc_calc(ROM_NO[rom_byte_number]); // accumulate the CRC
rom_byte_number++;
rom_byte_mask = 1;
}
}
}
while(rom_byte_number < 8); // loop until through all ROM bytes 0-7
// if the search was successful then
if (!((id_bit_number < 65) || (crc_value != 0)))
{
// search successful so set LastDiscrepancy,LastDeviceFlag,search_result
LastDiscrepancy = last_zero;
// check for last device
if (LastDiscrepancy == 0)
{
LastDeviceFlag = TRUE;
}
search_result = TRUE;
}
}
// if no device found then reset counters so next 'search' will be like a first
if (!search_result || (ROM_NO[0] == 0))
{
LastDiscrepancy = 0;
LastDeviceFlag = FALSE;
LastFamilyDiscrepancy = 0;
search_result = FALSE;
}
#if OW_MASTER_DEBUG
pc.printf(" pass ");
#endif
return search_result;
}
//--------------------------------------------------------------------------
// Use the DS2482 help command '1-Wire triplet' to perform one bit of a
// 1-Wire search.
// This command does two read bits and one write bit. The write bit
// is either the default direction (all device have same bit) or in case of
// a discrepancy, the 'search_direction' parameter is used.
//
// Returns – The DS2482 status byte result from the triplet command
//
uint8_t DS2482::search_triplet(uint8_t search_direction)
{
char cmd[2];
uint8_t status, poll_count = 0;
cmd[0] = DS2482_CMD_1WT;
cmd[1] = (search_direction ? 0x80 : 0x00);
i2c.write(addr,cmd,2);
do
{
i2c.read(addr,cmd,1);
status = cmd[0];
}
while ((status & DS2482_STATUS_1WB) && (poll_count++ < POLL_LIMIT));
// check for failure due to poll limit reached
if (poll_count >= POLL_LIMIT)
{
// handle error
// ...
reset();
return 0;
}
// return status byte
return status;
}
//--------------------------------------------------------------------------
// Set the 1-Wire Net communication speed.
//
// 'new_speed' - new speed defined as
// MODE_STANDARD 0x00
// MODE_OVERDRIVE 0x01
//
// Returns: current 1-Wire Net speed
//
uint8_t DS2482::OWSpeed(uint8_t new_speed)
{
// set the speed
if (new_speed == MODE_OVERDRIVE)
{
c1WS = DS2482_CFG_1WS;
}
else
{
c1WS = FALSE;
}
// write the new config
write_config(c1WS | cSPU | cPPM | cAPU);
return new_speed;
}
//--------------------------------------------------------------------------
// Set the 1-Wire Net line level pullup to normal. The DS2482 only
// allows enabling strong pullup on a bit or byte event.
// Consequently this function only allows the MODE_STANDARD argument.
// To enable strong pullup
// use OWWriteBytePower or OWReadBitPower.
//
// 'new_level' - new level defined as
// MODE_STANDARD 0x00
//
// Returns: current 1-Wire Net level
//
uint8_t DS2482::OWLevel(uint8_t new_level)
{
// function only will turn back to non-strong pullup
if (new_level != MODE_STANDARD)
{
return MODE_STRONG;
}
// clear the strong pullup bit in the global config state
cSPU = FALSE;
// write the new config
write_config(c1WS | cSPU | cPPM | cAPU);
return MODE_STANDARD;
}
//--------------------------------------------------------------------------
// Send 1 bit of communication to the 1-Wire Net and verify that the
// response matches the 'applyPowerResponse' bit and apply power delivery
// to the 1-Wire net. Note that some implementations may apply the power
// first and then turn it off if the response is incorrect.
//
// 'applyPowerResponse' - 1 bit response to check, if correct then start
// power delivery
//
// Returns: TRUE: bit written and response correct, strong pullup now on
// FALSE: response incorrect
//
uint8_t DS2482::OWReadBitPower(uint8_t applyPowerResponse)
{
uint8_t rdbit;
// set strong pullup enable
cSPU = DS2482_CFG_SPU;
// write the new config
if (!write_config(c1WS | cSPU | cPPM | cAPU))
{
return FALSE;
}
// perform read bit
rdbit = OWReadBit();
// check if response was correct, if not then turn off strong pullup
if (rdbit != applyPowerResponse)
{
OWLevel(MODE_STANDARD);
return FALSE;
}
return TRUE;
}
//--------------------------------------------------------------------------
// Send 8 bits of communication to the 1-Wire Net and verify that the
// 8 bits read from the 1-Wire Net are the same (write operation).
// The parameter 'sendbyte' least significant 8 bits are used. After the
// 8 bits are sent change the level of the 1-Wire net.
//
// 'sendbyte' - 8 bits to send (least significant bit)
//
// Returns: TRUE: bytes written and echo was the same, strong pullup now on
// FALSE: echo was not the same
//
uint8_t DS2482::OWWriteBytePower(uint8_t sendbyte)
{
// set strong pullup enable
cSPU = DS2482_CFG_SPU;
// write the new config
if (!write_config(c1WS | cSPU | cPPM | cAPU))
{
#if OW_MASTER_DEBUG
pc.printf("\r\nSPU off");
#endif
return FALSE;
}
// perform write byte
OWWriteByte(sendbyte);
return TRUE;
}
// end I2C DS2482
//======================================================================
//---------------------------------------------------------------------------
//-------------------------DS18XX OPERATIONS---------------------------------
//---------------------------------------------------------------------------
// find ALL devices on bus 1
//
void DS2482::DS18XX_Read_Address(void)
{
uint8_t status, i, j;
//--------------------------------------------------------------
// Device Tabele für bus 1 und bus 2 löschen
for (i = 0; i < OW_MAX_DEVICES; i++)
{
for (j = 0; j < 8; j++)
{
ow.device_table[i].rom[j] = 0;
}
}
// pc.printf("\n --- DS18xx_Read_Address --- ");
// wait(0.1);
ow.devices = 0;
//--------------------------------------------------------------
// die Bausteine am Bus suchen
//pc.printf("\n -- detect -- \n");
//wait(0.5);
detect(); // reset and init the 1-wire master
//pc.printf("\n -- OWFirst --\n");
//wait(0.1);
status = OWFirst();
if(status == 0)
{
#if OW_MASTER_START
pc.printf("\r\nno 1-Wire slaves found");
#endif
}
while(status)
{
// TODO hier ins eeprom schreiben
#if OW_MASTER_START
pc.printf("\n*** #%02d ROM_NO= ",ow.devices);
wait(0.1);
#endif
for (uint8_t i = 0; i < 8; i++)
{
ow.device_table[ow.devices].rom[i] = ROM_NO[i];
#if OW_MASTER_START
pc.printf(" 0x%02x",ROM_NO[i]);
wait (0.1);
#endif
}
ow.device_table[ow.devices].status = 0x01; // Wandler gefunden
status = OWNext();
ow.devices++; // Zeiger auf den nächsten freien Baustein
// maximal 16 Bausteine
if (ow.devices >= OW_MAX_DEVICES)
{
ow.devices--; // zeiget auf den letzten gültigen Baustein
return;
}
}
#if OW_MASTER_START
pc.printf("\r\n");
#endif
return;
}
//---------------------------------------------------------------------------
//
void DS2482::start_conversion(void)
{
//--------------------------------------------------------------
// alle Bausteine an bus 0 starten
// find a DS18S20
OWFirst();
OWReset();
// address all devices
OWWriteByte(OW_SKIP_ROM);
// Start Conversion and Config Strong Pull-Up
if (!OWWriteBytePower(OW_CONVERT_TEMP))
{
#if OW_MASTER_DEBUG
pc.printf("Fail convert command\r\n");
#endif
}
//--------------------------------------------------------------
// alle Bausteine an bus 1 starten
// find a DS18S20
OWFirst();
OWReset();
// address all devices
OWWriteByte(OW_SKIP_ROM);
// Start Conversion and Config Strong Pull-Up
if (!OWWriteBytePower(OW_CONVERT_TEMP))
{
#if OW_MASTER_DEBUG
pc.printf("Fail convert command\r\n");
#endif
}
}
//-----------------------------------------------------------------------------
bool DS2482::ow_read_rom(void)
{
uint8_t n;
// Write Read ROM Code command
OWWriteByte(OW_CMD_READ_ROM);
// Read 8 bytes of ROM code
for (n = 0; n < 8; n++)
{
ow_rom_code[n] = OWReadByte();
}
// Do Cyclic Redundancy Check
if (crc_calc_buffer(&ow_rom_code[0],7) != ow_rom_code[7])
{
ow_flags |= OW_CRC_ERROR;
return false;
}
return true;
}
//-----------------------------------------------------------------------------
bool DS2482::ow_read_scratchpad(void)
{
uint8_t i, crc;
ow_flags = 0;
if (!OWReset()) return false;
// select the device
// den Baustein wird über den ROM Code adressiert
OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command
for (i = 0; i < 8; i++)
{
OWWriteByte(ow.device_table[ow.device_table_index].rom[i]);
}
OWWriteByte(OW_CMD_READ_SCRATCHPAD); // Read Scratch pad 0xBE
// Read 9 bytes of scratchpad memory
for (i = 0; i < OW_SCRATCHPAD_BYTES; i++)
{
crc = OWReadByte();
ow_scratchpad[i] = crc;
}
#if OW_MASTER_DEBUG
pc.printf("\n*** Scratch_Val ");
for (i = 1; i < OW_SCRATCHPAD_BYTES; i++)
{
pc.printf(":0x%02x",ow_scratchpad[i]);
}
pc.printf("\r\n");
#endif
return true;
}
//-----------------------------------------------------------------------------
bool DS2482::ow_read_scratchpad_ds2438(uint8_t page)
{
uint8_t n, crc;
ow_flags = 0;
if (!OWReset()) return false;
// select the device
// den Baustein wird über den ROM Code adressiert
OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command
for (n = 0; n < 8; n++)
{
OWWriteByte(ow.device_table[ow.device_table_index].rom[n]);
}
// Write command to read scratchpad memory
OWWriteByte(0xbe); // 0xBE
OWWriteByte(page); // 0x03
// Read 9 bytes of scratchpad memory
for (n = 0; n < OW_SCRATCHPAD_BYTES; n++)
{
crc = OWReadByte();
ow_scratchpad[n] = crc;
// printf_P(PSTR("%02x "),crc);
}
crc = crc_calc_buffer(ow_scratchpad,8);
// Calculate CRC
if (crc != ow_scratchpad[8])
{
ow_flags |= OW_CRC_ERROR;
// Read 9 bytes of scratchpad memory
pc.printf("\now_read_scratchpad: ");
for (n = 0; n < OW_SCRATCHPAD_BYTES; n++)
{
pc.printf("%02x ",ow_scratchpad[n]);
}
pc.printf(": CRC error %02x",crc);
return false;
}
return true;
}
//----------------------------------------------------------------------------
bool DS2482::ow_write_scratchpad_ds18x20 (uint8_t th, uint8_t tl)
{
uint8_t i;
// Do bus reset
if (!OWReset()) return false;
// select the device
// den Baustein wird über den ROM Code adressiert
OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command
for (i = 0; i < 8; i++)
{
OWWriteByte(ow.device_table[ow.device_table_index].rom[i]);
}
// Write command to read scratchpad memory
OWWriteByte(OW_CMD_WRITE_SCRATCHPAD);
// Write 1 byte at scratchpad memory
OWWriteByte(th); // Th
wait_us(8); // ist für das Timing der 8 MHZ CPU notwendig
// Write 1 byte at scratchpad memory
OWWriteByte(tl); // Th
wait_us(8); // ist für das Timing der 8 MHZ CPU notwendig
// Write 1 byte at scratchpad memory
OWWriteByte(0x7F); // 12 Bit Auflösung
wait_us(8); // ist für das Timing der 8 MHZ CPU notwendig
return true;
}
//----------------------------------------------------------------------------
bool DS2482::ow_write_scratchpad_ds2438 (uint8_t th, uint8_t tl)
{
uint8_t i;
// Do bus reset
if (!OWReset()) return false;
// select the device
// den Baustein wird über den ROM Code adressiert
OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command
for (i = 0; i < 8; i++)
{
OWWriteByte(ow.device_table[ow.device_table_index].rom[i]);
}
// Write command to read scratchpad memory
OWWriteByte(0x4E);
OWWriteByte(0x03);
// Write 3 bytes to scratchpad memory
OWWriteByte(th); // Th
wait_us(8);
OWWriteByte(tl); // Tl
wait_us(8);
return true;
}
//----------------------------------------------------------------------------
bool DS2482::ow_write_eeprom_ds18x20 (void)
{
uint8_t i;
// Do bus reset
if (!OWReset()) return false;
// select the device
// den Baustein wird über den ROM Code adressiert
OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command
for (i = 0; i < 8; i++)
{
OWWriteByte(ow.device_table[ow.device_table_index].rom[i]);
}
// Write command to write eeprom
OWWriteByte(0x48);
return true;
}
//----------------------------------------------------------------------------
bool DS2482::ow_write_eeprom_ds2438 (void)
{
uint8_t i;
// Do bus reset
if (!OWReset()) return false;
// select the device
// den Baustein wird über den ROM Code adressiert
OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command
for (i = 0; i < 8; i++)
{
OWWriteByte(ow.device_table[ow.device_table_index].rom[i]);
}
// Write command to read scratchpad memory
OWWriteByte(0x48);
OWWriteByte(0x03);
return true;
}
//----------------------------------------------------------------------------
void DS2482::ow_read_address (void)
{
uint8_t n;
// ow Adressen aus den Bausteinen lesen
for (n = 0; n < OW_MAX_DEVICES; n++)
{
if ((ow.device_table[n].status & 0x0f) == 1)
{
// printf_P(PSTR("\n device table %d"),n);
ow.device_table_index = n;
if ((ow.device_table[n].rom[0] == 0x10) || (ow.device_table[n].rom[0] == 0x28))
{
if (ow_read_scratchpad())
{
if(ow_scratchpad[2] == ow_scratchpad[3]) ow.device_table[n].adr = ow_scratchpad[3];
}
}
if ((ow.device_table[n].rom[0] == 0xa6) || (ow.device_table[n].rom[0] == 0x26))
{
if (ow_read_scratchpad_ds2438(0x03))
{
if(ow_scratchpad[0] == ow_scratchpad[1]) ow.device_table[n].adr = ow_scratchpad[0];
}
}
}
} // end for(...
}
//-----------------------------------------------------------------------------
bool DS2482::ds1820_start_conversion(uint8_t command)
{
uint8_t i;
// Do bus reset
if (!OWReset()) return false;
// Check if a match ROM code must be done or just skip ROM code (0xFF)
if (command > 0xFE)
{
OWWriteByte(OW_CMD_SKIP_ROM); // Send Skip ROM Code command
}
else
{
// select the device
// den Baustein wird über den ROM Code adressiert
OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command
for (i = 0; i < 8; i++)
{
OWWriteByte(ow.device_table[ow.device_table_index].rom[i]);
}
}
// Send the "Convert T" command to start conversion
OWWriteByte(OW_CMD_CONVERT_T);
// Set flag to mark a measurement in progress
ds1820_request_pending = true;
return TRUE;
}
//-----------------------------------------------------------------------------
bool DS2482::ds18B20_read_hrtemp(void)
{
union ds18B20_temp_union
{
int16_t word;
uint8_t byte[2];
} ds18B20_temp;
// uint8_t temp_lo;
// uint8_t temp_hi;
// int8_t digit;
float ds1820_float_result;
// Preset float result to zero in case of function termination (return false)
//ds1820_float_result = 0.0;
ow.device_table[ow.device_table_index].result = 0;
// Return false if reading scratchpad memory fails
if (!ow_read_scratchpad())
{
ow.device_table[ow.device_table_index].status &= 0xf0;
ow.device_table[ow.device_table_index].status |= 4;
return FALSE;
}
ds18B20_temp.byte[0] = ow_scratchpad[DS1820_LSB];
ds18B20_temp.byte[1] = ow_scratchpad[DS1820_MSB];
//ds18B20_temp.word <<= 4; // Vorzeichenbit auf MSB Bit schieben
//ds18B20_temp.word /= 16; // die letzten 4 Stellen wieder löschen
ds1820_float_result = ds18B20_temp.word * 0.0625;
//pc.printf("\nDS18B20 T-Kanal: %d = %2.2f ",ow.device_table_index,ds1820_float_result);
ow.device_table[ow.device_table_index].result = (int16_t)(ds1820_float_result * 100);
// Clear flag to mark that no measurement is in progress
ds1820_request_pending = false;
// Flag für erfolgreiches Lesen setzen
ow.device_table[ow.device_table_index].status &= 0xf0;
ow.device_table[ow.device_table_index].status |= 3;
return true;
}
//-----------------------------------------------------------------------------