Sets the 1-Wire communication speed, either standard or overdrive. Note that this only changes the communication speed of the 1-Wire master; the 1-Wire slave device must be instructed to make the switch when going from normal to overdrive. The 1-Wire slave will always revert to standard speed when it encounters a standard-speed 1-Wire reset.
OWLevel
Sets the 1-Wire power level (normal or power delivery).
OWReadBitPower
Reads a single bit of data from the 1-Wire network and optionally applies power delivery immediately after the bit is complete.
OWWriteBytePower
Sends a single byte of data to the 1-Wire network and applies power delivery immediately after the byte is complete.
// DS2482 state
unsigned char I2C_address;
int c1WS, cSPU, cPPM, cAPU;
int short_detected;
//--------------------------------------------------------------------------
// DS2428 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
//
int DS2482_detect(unsigned char addr)
{
// set global address
I2C_address = addr;
// reset the DS2482 ON selected address
if (!DS2482_reset())
return FALSE;
// default configuration
c1WS = FALSE;
cSPU = FALSE;
cPPM = FALSE;
cAPU = CONFIG_APU;
// write the default configuration setup
if (!DS2482_write_config(c1WS | cSPU | cPPM | cAPU))
return FALSE;
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()
{
unsigned char status;
// Device Reset
// S AD,0 [A] DRST [A] Sr AD,1 [A] [SS] A\ P
// [] indicates from slave
// SS status byte to read to verify state
I2C_start();
I2C_write(I2C_address | I2C_WRITE, EXPECT_ACK);
I2C_write(CMD_DRST, EXPECT_ACK);
I2C_rep_start();
I2C_write(I2C_address | I2C_READ, EXPECT_ACK);
status = I2C_read(NACK);
I2C_stop();
// check for failure due to incorrect read back of status
return ((status & 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
//
int DS2482_write_config(unsigned char config)
{
unsigned char read_config;
// Write configuration (Case A)
// S AD,0 [A] WCFG [A] CF [A] Sr AD,1 [A] [CF] A\ P
// [] indicates from slave
// CF configuration byte to write
I2C_start();
I2C_write(I2C_address | I2C_WRITE, EXPECT_ACK);
I2C_write(CMD_WCFG, EXPECT_ACK);
I2C_write(config | (~config << 4), EXPECT_ACK);
I2C_rep_start();
I2C_write(I2C_address | I2C_READ, EXPECT_ACK);
read_config = I2C_read(NACK);
I2C_stop();
// check for failure due to incorrect read back
if (config != read_config)
{
// handle error
// ...
DS2482_reset();
return FALSE;
}
return TRUE;
}
//--------------------------------------------------------------------------
// 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
//
int OWReset(void)
{
unsigned char status;
int poll_count = 0;
// 1-Wire reset (Case B)
// S AD,0 [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P
// \--------/
// Repeat until 1WB bit has changed to 0
// [] indicates from slave
I2C_start();
I2C_write(I2C_address | I2C_WRITE, EXPECT_ACK);
I2C_write(CMD_1WRS, EXPECT_ACK);
I2C_rep_start();
I2C_write(I2C_address | I2C_READ, EXPECT_ACK);
// loop checking 1WB bit for completion of 1-Wire operation
// abort if poll limit reached
status = I2C_read(ACK);
do
{
status = I2C_read(status & STATUS_1WB);
}
while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT));
I2C_stop();
// check for failure due to poll limit reached
if (poll_count >= POLL_LIMIT)
{
// handle error
// ...
DS2482_reset();
return FALSE;
}
// check for short condition
if (status & STATUS_SD)
short_detected = TRUE;
else
short_detected = FALSE;
// check for presence detect
if (status & STATUS_PPD)
return TRUE;
else
return FALSE;
}
図7. 1-Wire Single Bit。1-Wireライン上でシングルタイムスロットを生成します。1WBが1から0に変わると、Statusレジスタは1-Wireシングルビットコマンドの有効結果を保持します。
図8. 1-Wireシングルデータバイト
//--------------------------------------------------------------------------
// 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 OWWriteBit(unsigned char 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
//
unsigned char 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
//
unsigned char OWTouchBit(unsigned char sendbit)
{
unsigned char status;
int poll_count = 0;
// 1-Wire bit (Case B)
// S AD,0 [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] A\ P
// \--------/
// Repeat until 1WB bit has changed to 0
// [] indicates from slave
// BB indicates byte containing bit value in msbit
I2C_start();
I2C_write(I2C_address | I2C_WRITE, EXPECT_ACK);
I2C_write(CMD_1WSB, EXPECT_ACK);
I2C_write(sendbit ? 0x80 : 0x00, EXPECT_ACK);
I2C_rep_start();
I2C_write(I2C_address | I2C_READ, EXPECT_ACK);
// loop checking 1WB bit for completion of 1-Wire operation
// abort if poll limit reached
status = I2C_read(ACK);
do
{
status = I2C_read(status & STATUS_1WB);
}
while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT));
I2C_stop();
// check for failure due to poll limit reached
if (poll_count >= POLL_LIMIT)
{
// handle error
// ...
DS2482_reset();
return 0;
}
// return bit state
if (status & 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 OWWriteByte(unsigned char sendbyte)
{
unsigned char status;
int poll_count = 0;
// 1-Wire Write Byte (Case B)
// S AD,0 [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] A\ P
// \--------/
// Repeat until 1WB bit has changed to 0
// [] indicates from slave
// DD data to write
I2C_start();
I2C_write(I2C_address | I2C_WRITE, EXPECT_ACK);
I2C_write(CMD_1WWB, EXPECT_ACK);
I2C_write(sendbyte, EXPECT_ACK);
I2C_rep_start();
I2C_write(I2C_address | I2C_READ, EXPECT_ACK);
// loop checking 1WB bit for completion of 1-Wire operation
// abort if poll limit reached
status = I2C_read(ACK);
do
{
status = I2C_read(status & STATUS_1WB);
}
while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT));
I2C_stop();
// check for failure due to poll limit reached
if (poll_count >= POLL_LIMIT)
{
// handle error
// ...
DS2482_reset();
}
}
//--------------------------------------------------------------------------
// 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
//
unsigned char OWReadByte(void)
{
unsigned char data, status;
int poll_count = 0;
// 1-Wire Read Bytes (Case C)
// S AD,0 [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A\
// \--------/
// Repeat until 1WB bit has changed to 0
// Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P
//
// [] indicates from slave
// DD data read
I2C_start();
I2C_write(I2C_address | I2C_WRITE, EXPECT_ACK);
I2C_write(CMD_1WRB, EXPECT_ACK);
I2C_rep_start();
I2C_write(I2C_address | I2C_READ, EXPECT_ACK);
// loop checking 1WB bit for completion of 1-Wire operation
// abort if poll limit reached
status = I2C_read(ACK);
do
{
status = I2C_read(status & STATUS_1WB);
}
while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT));
// check for failure due to poll limit reached
if (poll_count >= POLL_LIMIT)
{
// handle error
// ...
DS2482_reset();
return 0;
}
I2C_rep_start();
I2C_write(I2C_address | I2C_WRITE, EXPECT_ACK);
I2C_write(CMD_SRP, EXPECT_ACK);
I2C_write(0xE1, EXPECT_ACK);
I2C_rep_start();
I2C_write(I2C_address | I2C_READ, EXPECT_ACK);
data = I2C_read(NACK);
I2C_stop();
return data;
}
//--------------------------------------------------------------------------
// 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 OWBlock(unsigned char *tran_buf, int tran_len)
{
int 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
//
unsigned char OWTouchByte(unsigned char sendbyte)
{
if (sendbyte == 0xFF)
return OWReadByte();
else
{
OWWriteByte(sendbyte);
return sendbyte;
}
}
// Search state
unsigned char ROM_NO[8];
int LastDiscrepancy;
int LastFamilyDiscrepancy;
int LastDeviceFlag;
unsigned char crc8;
//--------------------------------------------------------------------------
// Find the 'first' devices on the 1-Wire network
// Return TRUE : device found, ROM number in ROM_NO buffer
// FALSE : no device present
//
int OWFirst()
{
// reset the search state
LastDiscrepancy = 0;
LastDeviceFlag = FALSE;
LastFamilyDiscrepancy = 0;
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
//
int OWNext()
{
// leave the search state alone
return OWSearch();
}
//--------------------------------------------------------------------------
// 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.
//
int OWSearch()
{
int id_bit_number;
int last_zero, rom_byte_number, search_result;
int id_bit, cmp_id_bit;
unsigned char 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;
crc8 = 0;
// if the last call was not the last one
if (!LastDeviceFlag)
{
// 1-Wire reset
if (!OWReset())
{
// reset the search
LastDiscrepancy = 0;
LastDeviceFlag = FALSE;
LastFamilyDiscrepancy = 0;
return FALSE;
}
// issue the search command
OWWriteByte(0xF0);
// 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
status = DS2482_search_triplet(search_direction);
// check bit results in status byte
id_bit = ((status & STATUS_SBR) == STATUS_SBR);
cmp_id_bit = ((status & STATUS_TSB) == STATUS_TSB);
search_direction =
((status & STATUS_DIR) == STATUS_DIR) ? (byte)1 : (byte)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] &= (byte)~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)
{
calc_crc8(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) || (crc8 != 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;
}
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
//
unsigned char DS2482_search_triplet(int search_direction)
{
unsigned char status;
int poll_count = 0;
// 1-Wire Triplet (Case B)
// S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P
// \--------/
// Repeat until 1WB bit has changed to 0
// [] indicates from slave
// SS indicates byte containing search direction bit value in msbit
I2C_start();
I2C_write(I2C_address | I2C_WRITE, EXPECT_ACK);
I2C_write(CMD_1WT, EXPECT_ACK);
I2C_write(search_direction ? 0x80 : 0x00, EXPECT_ACK);
I2C_rep_start();
I2C_write(I2C_address | I2C_READ, EXPECT_ACK);
// loop checking 1WB bit for completion of 1-Wire operation
// abort if poll limit reached
status = I2C_read(ACK);
do
{
status = I2C_read(status & STATUS_1WB);
}
while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT));
I2C_stop();
// check for failure due to poll limit reached
if (poll_count >= POLL_LIMIT)
{
// handle error
// ...
DS2482_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
//
int OWSpeed(int new_speed)
{
// set the speed
if (new_speed == MODE_OVERDRIVE)
c1WS = CONFIG_1WS;
else
c1WS = FALSE;
// write the new config
DS2482_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
//
int OWLevel(int 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
DS2482_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
//
int OWReadBitPower(int applyPowerResponse)
{
unsigned char rdbit;
// set strong pullup enable
cSPU = CONFIG_SPU;
// write the new config
if (!DS2482_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
//
int OWWriteBytePower(int sendbyte)
{
// set strong pullup enable
cSPU = CONFIG_SPU;
// write the new config
if (!DS2482_write_config(c1WS | cSPU | cPPM | cAPU))
return FALSE;
// perform write byte
OWWriteByte(sendbyte);
return TRUE;
}