//individual Serial #s and readings
#define DEVICES 4
int ROMS[DEVICES][8];
int TEMPS[DEVICES];
int GetTemperatures(int BASE)
{
// init. the 1-Wire Master
Initialize(BASE);
// exit if no devices can be found
if(Reset(BASE)) return(1);
// find all individual Serial#s
FindROMs(BASE);
// Convert temp. and read devices
ConvertT(BASE);
ReadTemps(BASE);
return(0);
}
int Reset(int BASE)
{
outp(BASE,0x02); // send reset
WaitforInterrupt();
if(inp(BASE+2) & 0x02)
return(1); //no presence found
else
return(0); //presence found
}
ホストは、1-Wireバス上の各デバイスの個別のROMコードを知る必要があります。これは、Search ROMアルゴリズムを実行することで行います。ホストはSearch ROMコマンドをスレーブに送信し、1-WireマスタをSearch ROM Acceleratorモードに置きます。ホストは検出した最後のROM値に基づいた16バイトの検索値を送信します。この16バイトの値は、最初に実行するときは0x00です。返される16バイトには新しいROMコードが含まれ、また、これを使用して次に送信する16バイトも生成します。
このプロセスは、シリアル番号が複写されてすべてのデバイスが検出されるまで繰り返されます。例のケースでは、デバイスは4つだけであり、4つのROMコードに必要十分なメモリしか割り当てられていないため、ループは4回だけ実行されます。RecoverROM関数は新しいデータを生成して送信し、受信したばかりのデータから新しいROMコードを抽出します。この関数は、受信したデータを初期化するため、一度だけNULLポインタを用いて呼び出す必要があります。RecoverROM関数についての詳細は、このアプリケーションノートの最後に記載しています。Search ROM Acceleratorのプロセスについては、DS1WMのデータシートに詳細に説明しています。
int FindROMs(int BASE)
{
int loop;
int dev;
int TData[16];
int RData[16];
// reset RecoverROM and generate the
// starting TData
RecoverROM(NULL,TData,NULL);
//run once for each device
for(dev=0;dev<4;dev++)
{
outp(BASE,0x01); // send reset
WaitforInterrupt();
outp(BASE+1,0xF0); // send SeachROM
WaitforInterrupt();
// enter Accelerator mode
outp(BASE,0x02);
// transmit the TDATA and receive
// the RDATA.
for(loop=0;loop<16;loop++)
{
outp(BASE+1,TData[loop]);
WaitforInterrupt();
inp(BASE+1,RData[loop]);
}
//decode recovered ROM and generate
//next Search value
RecoverROM(RDATA,TData,ROMS[dev]);
}
}
/////////////////////////////////////////////////////////////////////////////////
// RecoverROM performs two functions. Given 16 bytes of receive data taken from
// the 1-Wire Master during a Search ROM function, it will extract the ROM code
// found into an 8 byte array and it will generate the next 16 bytes to be trans-
// mitted during the next Search ROM.
// RecoverROM must be initialized by sending a NULL pointer in ReceivedData. It
// will write 16 bytes of zeros into TransmitData and clear the discrepancy tree.
// The discrepancy tree keeps track of which ROM discrepancies have already been
// explored.
// RecoverROM also returns a value telling whether there are any more ROM codes to
// be found. If a zero is returned, there are still discrepancies. If a one is
// returned all ROMs on the bus have been found. Running RecoverROM again in this
// case will result in repeating ROM codes already found
////////////////////////////////////////////////////////////////////////////////
int RecoverROM(int* ReceiveData, int* TransmitData, int* ROMCode)
{
int loop;
int result;
int TROM[64]; // the transmit value being generated
int RROM[64]; // the ROM recovered from the received data
int RDIS[64]; // the discrepancy bits in the received data
static int TREE[64]; // used to keep track of which discrepancy bits have
// already been flipped.
// If receivedata is NULL, this is the first run. Transmit data should be all
// zeros, and the discrepancy tree must also be reset.
if(ReceiveData == NULL)
{
for(loop = 0; loop < 64; loop++) TREE[loop] = 0;
for(loop = 0; loop < 16; loop++) TransmitData[loop] = 0;
return 1;
}
// de-interleave the received data into the new ROM code and the discrepancy bits
for(loop = 0; loop < 16; loop++)
{
if((ReceiveData[loop] & 0x02) == 0x00) RROM[loop*4] = 0; else RROM[loop*4 ] = 1;
if((ReceiveData[loop] & 0x08) == 0x00) RROM[loop*4+1] = 0; else RROM[loop*4+1] = 1;
if((ReceiveData[loop] & 0x20) == 0x00) RROM[loop*4+2] = 0; else RROM[loop*4+2] = 1;
if((ReceiveData[loop] & 0x80) == 0x00) RROM[loop*4+3] = 0; else RROM[loop*4+3] = 1;
if((ReceiveData[loop] & 0x01) == 0x00) RDIS[loop*4] = 0; else RDIS[loop*4 ] = 1;
if((ReceiveData[loop] & 0x04) == 0x00) RDIS[loop*4+1] = 0; else RDIS[loop*4+1] = 1;
if((ReceiveData[loop] & 0x10) == 0x00) RDIS[loop*4+2] = 0; else RDIS[loop*4+2] = 1;
if((ReceiveData[loop] & 0x40) == 0x00) RDIS[loop*4+3] = 0; else RDIS[loop*4+3] = 1;
}
// initialize the transmit ROM to the recovered ROM
for(loop = 0; loop < 64; loop++) TROM[loop] = RROM[loop];
// work through the new transmit ROM backwards setting every bit to 0 until the
// most significant discrepancy bit which has not yet been flipped is found.
// The transmit ROM bit at that location must be flipped.
for(loop = 63; loop >= 0; loop--)
{
// This is a new discrepancy bit. Set the indicator in the tree, flip the
// transmit bit, and then break from the loop.
if((TREE[loop] == 0) && (RDIS[loop] == 1) && (TROM[loop] == 0))
{
TREE[loop] = 1;
TROM[loop] = 1;
break;
}
if((TREE[loop] == 0) && (RDIS[loop] == 1) && (TROM[loop] == 1))
{
TREE[loop] = 1;
TROM[loop] = 0;
break;
}
// This bit has already been flipped, remove it from the tree and continue
// setting the transmit bits to zero.
if((TREE[loop] == 1) && (RDIS[loop] == 1)) TREE[loop] = 0;
TROM[loop] = 0;
}
result = loop; // if loop made it to -1, there are no more discrepancy bits
// and the search can end.
// Convert the individual transmit ROM bit into a 16 byte format
// every other bit is don't care.
for(loop = 0; loop < 16; loop++)
{
TransmitData[loop] = (TROM[loop*4]<<1) +
(TROM[loop*4+1]<<3) +
(TROM[loop*4+2]<<5) +
(TROM[loop*4+3]<<7);
}
// Convert the individual recovered ROM bits into an 8 byte format
for(loop = 0; loop < 8; loop++)
{
ROMCode[loop] = (RROM[loop*8]) +
(RROM[loop*8+1]<<1) +
(RROM[loop*8+2]<<2) +
(RROM[loop*8+3]<<3) +
(RROM[loop*8+4]<<4) +
(RROM[loop*8+5]<<5) +
(RROM[loop*8+6]<<6) +
(RROM[loop*8+7]<<7);
}
if(result == -1) return 1; // There are no DIS bits that haven't been flipped
// Tell the main loop the search is over
return 0; // else continue
}