📄 ownetu.c
字号:
#define DEBUG_OW_NETU 0
#if DEBUG_OW_NETU
#include <stdio.h>
#endif
//---------------------------------------------------------------------------
// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// Except as contained in this notice, the name of Dallas Semiconductor
// shall not be used except as stated in the Dallas Semiconductor
// Branding Policy.
//---------------------------------------------------------------------------
//
// owNetU.C - Network functions for 1-Wire Net devices
// using the DS2480/DS2480B (U) serial interface chip.
//
// Version: 2.00
//
// 1.02 -> 1.03 Removed caps in #includes for Linux capatibility
// 1.03 -> 2.00 Changed 'MLan' to 'ow'. Added support for
// multiple ports.
//
#include "ownet.h"
#include "ds2480.h"
// globally used
uchar SerialNum[MAX_PORTNUM][8];
// local variables for this module to hold search state information
static int LastDiscrepancy[MAX_PORTNUM];
static int LastFamilyDiscrepancy[MAX_PORTNUM];
static int LastDevice[MAX_PORTNUM];
//--------------------------------------------------------------------------
// The 'owFirst' finds the first device on the 1-Wire Net 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.
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
// indicate the symbolic port number.
// 'do_reset' - TRUE (1) perform reset before search, FALSE (0) do not
// perform reset before search.
// 'alarm_only' - TRUE (1) the find alarm command 0xEC is
// sent instead of the normal search command 0xF0
//
// Returns: TRUE (1) : when a 1-Wire device was found and it's
// Serial Number placed in the global SerialNum
// FALSE (0): There are no devices on the 1-Wire Net.
//
int owFirst(int portnum, int do_reset, int alarm_only)
{
// reset the search state
LastDiscrepancy[portnum] = 0;
LastDevice[portnum] = FALSE;
LastFamilyDiscrepancy[portnum] = 0;
return owNext(portnum, do_reset, alarm_only);
}
//--------------------------------------------------------------------------
// The 'owNext' function does a general search. This function
// continues from the previos 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.
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
// OpenCOM to indicate the port number.
// 'do_reset' - TRUE (1) perform reset before search, FALSE (0) do not
// perform reset before search.
// 'alarm_only' - TRUE (1) the find alarm command 0xEC is
// sent instead of the normal search command 0xF0
//
// Returns: TRUE (1) : when a 1-Wire device was found and it's
// Serial Number placed in the global SerialNum
// 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 owNext(int portnum, int do_reset, int alarm_only)
{
int i,tmp_last_desc,pos;
uchar tmp_serial_num[8];
uchar readbuffer[20],sendpacket[40];
int sendlen=0;
uchar lastcrc8;
// if the last call was the last one
if (LastDevice[portnum])
{
// reset the search
LastDiscrepancy[portnum] = 0;
LastDevice[portnum] = FALSE;
LastFamilyDiscrepancy[portnum] = 0;
#if DEBUG_OW_NETU
printf ("owNext: no (more) devices\n");
#endif
return FALSE;
}
// check if reset first is requested
if (do_reset)
{
// reset the 1-wire
// if there are no parts on 1-wire, return FALSE
if (!owTouchReset(portnum))
{
// reset the search
LastDiscrepancy[portnum] = 0;
LastFamilyDiscrepancy[portnum] = 0;
return FALSE;
}
}
// build the command stream
// call a function that may add the change mode command to the buff
// check if correct mode
if (UMode[portnum] != MODSEL_DATA)
{
UMode[portnum] = MODSEL_DATA;
sendpacket[sendlen++] = MODE_DATA;
}
// search command
if (alarm_only)
sendpacket[sendlen++] = 0xEC; // issue the alarming search command
else
sendpacket[sendlen++] = 0xF0; // issue the search command
// change back to command mode
UMode[portnum] = MODSEL_COMMAND;
sendpacket[sendlen++] = MODE_COMMAND;
// search mode on
sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_SEARCHON | USpeed[portnum]);
// change back to data mode
UMode[portnum] = MODSEL_DATA;
sendpacket[sendlen++] = MODE_DATA;
// set the temp Last Descrep to none
tmp_last_desc = 0xFF;
// add the 16 bytes of the search
pos = sendlen;
for (i = 0; i < 16; i++)
sendpacket[sendlen++] = 0;
// only modify bits if not the first search
if (LastDiscrepancy[portnum] != 0xFF)
{
// set the bits in the added buffer
for (i = 0; i < 64; i++)
{
// before last discrepancy
if (i < (LastDiscrepancy[portnum] - 1))
bitacc(WRITE_FUNCTION,
bitacc(READ_FUNCTION,0,i,&SerialNum[portnum][0]),
(short)(i * 2 + 1),
&sendpacket[pos]);
// at last discrepancy
else if (i == (LastDiscrepancy[portnum] - 1))
bitacc(WRITE_FUNCTION,1,
(short)(i * 2 + 1),
&sendpacket[pos]);
// after last discrepancy so leave zeros
}
}
// change back to command mode
UMode[portnum] = MODSEL_COMMAND;
sendpacket[sendlen++] = MODE_COMMAND;
// search OFF
sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed[portnum]);
// flush the buffers
FlushCOM(portnum);
// send the packet
if (WriteCOM(portnum,sendlen,sendpacket))
{
// read back the 1 byte response
if (ReadCOM(portnum,17,readbuffer) == 17)
{
// interpret the bit stream
for (i = 0; i < 64; i++)
{
// get the SerialNum bit
bitacc(WRITE_FUNCTION,
bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]),
i,
&tmp_serial_num[0]);
// check LastDiscrepancy
if ((bitacc(READ_FUNCTION,0,(short)(i * 2),&readbuffer[1]) == 1) &&
(bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]) == 0))
{
tmp_last_desc = i + 1;
// check LastFamilyDiscrepancy
if (i < 8)
LastFamilyDiscrepancy[portnum] = i + 1;
}
}
// do dowcrc
setcrc8(portnum,0);
for (i = 0; i < 8; i++)
lastcrc8 = docrc8(portnum,tmp_serial_num[i]);
// check results
if ((lastcrc8 != 0) || (LastDiscrepancy[portnum] == 63) || (tmp_serial_num[0] == 0))
{
// error during search
// reset the search
LastDiscrepancy[portnum] = 0;
LastDevice[portnum] = FALSE;
LastFamilyDiscrepancy[portnum] = 0;
#if DEBUG_OW_NETU
printf ("owNext: check results failed\n");
#endif
return FALSE;
}
// successful search
else
{
// check for lastone
if ((tmp_last_desc == LastDiscrepancy[portnum]) || (tmp_last_desc == 0xFF))
LastDevice[portnum] = TRUE;
// copy the SerialNum to the buffer
for (i = 0; i < 8; i++)
SerialNum[portnum][i] = tmp_serial_num[i];
// set the count
LastDiscrepancy[portnum] = tmp_last_desc;
return TRUE;
}
} else {
#if DEBUG_OW_NETU
printf ("owNext: ReadCOM failed\n");
#endif
}
} else {
#if DEBUG_OW_NETU
printf ("owNext: WriteCOM failed\n");
#endif
}
// an error occured so re-sync with DS2480
DS2480Detect(portnum);
// reset the search
LastDiscrepancy[portnum] = 0;
LastDevice[portnum] = FALSE;
LastFamilyDiscrepancy[portnum] = 0;
return FALSE;
}
//--------------------------------------------------------------------------
// The 'owSerialNum' function either reads or sets the SerialNum buffer
// that is used in the search functions 'owFirst' and 'owNext'.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -