📄 owtrnu.c
字号:
#define DEBUG_OW_TRNU 0#if DEBUG_OW_TRNU#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. //---------------------------------------------------------------------------//// owTranU.C - Transport functions for 1-Wire Net// using the DS2480 (U) serial interface chip.//// Version: 2.00//// History: 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"// local functions static int Write_Scratchpad(int,uchar *,int,int);static int Copy_Scratchpad(int,int,int);//--------------------------------------------------------------------------// The 'owBlock' transfers a block of data to and from the // 1-Wire Net with an optional reset at the begining of communication.// The result is returned in the same buffer.//// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to// indicate the symbolic port number.// 'do_reset' - cause a owTouchReset to occure at the begining of // communication TRUE(1) or not FALSE(0)// '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// Supported devices: all //// Returns: TRUE (1) : The optional reset returned a valid // presence (do_reset == TRUE) or there// was no reset required.// FALSE (0): The reset did not return a valid prsence// (do_reset == TRUE).//// The maximum tran_length is 64//int owBlock(int portnum, int do_reset, uchar *tran_buf, int tran_len){ uchar sendpacket[150]; int sendlen=0,pos,i; // check for a block too big if (tran_len > 64) return FALSE; // check if need to do a owTouchReset first if (do_reset) { if (!owTouchReset(portnum)) return FALSE; } // construct the packet to send to the DS2480 // check if correct mode if (UMode[portnum] != MODSEL_DATA) { UMode[portnum] = MODSEL_DATA; sendpacket[sendlen++] = MODE_DATA; } // add the bytes to send pos = sendlen; for (i = 0; i < tran_len; i++) { sendpacket[sendlen++] = tran_buf[i]; // check for duplication of data that looks like COMMAND mode if (tran_buf[i] == MODE_COMMAND) sendpacket[sendlen++] = tran_buf[i]; } // flush the buffers FlushCOM(portnum); // send the packet if (WriteCOM(portnum,sendlen,sendpacket)) { // read back the response if (ReadCOM(portnum,tran_len,tran_buf) == tran_len) { return TRUE; } } // an error occured so re-sync with DS2480 DS2480Detect(portnum); return FALSE;} //--------------------------------------------------------------------------// Read a Universal Data Packet from a standard NVRAM iButton // and return it in the provided buffer. The page that the // packet resides on is 'start_page'. Note that this function is limited // to single page packets. The buffer 'read_buf' must be at least // 29 bytes long. //// The Universal Data Packet always start on page boundaries but // can end anywhere. The length is the number of data bytes not // including the length byte and the CRC16 bytes. There is one // length byte. The CRC16 is first initialized to the starting // page number. This provides a check to verify the page that // was intended is being read. The CRC16 is then calculated over // the length and data bytes. The CRC16 is then inverted and stored // low byte first followed by the high byte. //// Supported devices: DS1992, DS1993, DS1994, DS1995, DS1996, DS1982, // DS1985, DS1986, DS2407, and DS1971. //// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to// indicate the symbolic port number.// 'do_access' - flag to indicate if an 'owAccess' should be// peformed at the begining of the read. This may// be FALSE (0) if the previous call was to read the// previous page (start_page-1).// 'start_page' - page number to start the read from // 'read_buf' - pointer to a location to store the data read//// Returns: >=0 success, number of data bytes in the buffer// -1 failed to read a valid UDP // //int owReadPacketStd(int portnum, int do_access, int start_page, uchar *read_buf){ int i,length,sendlen=0,head_len=0; uchar sendpacket[50]; ushort lastcrc16;#if DEBUG_OW_TRNU printf ("owReadPacketStd: %d %d\n", do_access, start_page);#endif // check if access header is done // (only use if in sequention read with one access at begining) if (do_access) { // match command sendpacket[sendlen++] = 0x55; for (i = 0; i < 8; i++) sendpacket[sendlen++] = SerialNum[portnum][i]; // read memory command sendpacket[sendlen++] = 0xF0; // write the target address sendpacket[sendlen++] = ((start_page << 5) & 0xFF); sendpacket[sendlen++] = (start_page >> 3); // check for DS1982 exception (redirection byte) if (SerialNum[portnum][0] == 0x09) sendpacket[sendlen++] = 0xFF; // record the header length head_len = sendlen; } // read the entire page length byte for (i = 0; i < 32; i++) sendpacket[sendlen++] = 0xFF; // send/recieve the transfer buffer if (owBlock(portnum,do_access,sendpacket,sendlen)) { // seed crc with page number setcrc16(portnum,(ushort)start_page); // attempt to read UDP from sendpacket length = sendpacket[head_len]; docrc16(portnum,(ushort)length); // verify length is not too large if (length <= 29) { // loop to read packet including CRC for (i = 0; i < length; i++) { read_buf[i] = sendpacket[i+1+head_len]; docrc16(portnum,read_buf[i]); } // read and compute the CRC16 docrc16(portnum,sendpacket[i+1+head_len]); lastcrc16 = docrc16(portnum,sendpacket[i+2+head_len]); // verify the CRC16 is correct if (lastcrc16 == 0xB001) return length; // return number of byte in record#if DEBUG_OW_TRNU printf ("owReadPacketStd: crc error in page %d\n", start_page);#endif } }#if DEBUG_OW_TRNU printf ("owReadPacketStd: block>29 : %d\n", length);#endif // failed block or incorrect CRC return -1;}//--------------------------------------------------------------------------// Write a Universal Data Packet onto a standard NVRAM 1-Wire device// on page 'start_page'. This function is limited to UDPs that// fit on one page. The data to write is provided as a buffer// 'write_buf' with a length 'write_len'.//// The Universal Data Packet always start on page boundaries but // can end anywhere. The length is the number of data bytes not // including the length byte and the CRC16 bytes. There is one // length byte. The CRC16 is first initialized to the starting // page number. This provides a check to verify the page that // was intended is being read. The CRC16 is then calculated over // the length and data bytes. The CRC16 is then inverted and stored // low byte first followed by the high byte. //// Supported devices: is_eprom=0 // DS1992, DS1993, DS1994, DS1995, DS1996// is_eprom=1, crc_type=0(CRC8)// DS1982// is_eprom=1, crc_type=1(CRC16) // DS1985, DS1986, DS2407 //// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to// indicate the symbolic port number.// 'start_page' - page number to write packet to// 'write_buf' - pointer to buffer containing data to write// 'write_len' - number of data byte in write_buf// 'is_eprom' - flag set if device is an EPROM (1 EPROM, 0 NVRAM)// 'crc_type' - if is_eprom=1 then indicates CRC type // (0 CRC8, 1 CRC16)//// Returns: TRUE(1) success, packet written// FALSE(0) failure to write, contact lost or device locked////int owWritePacketStd(int portnum, int start_page, uchar *write_buf, int write_len, int is_eprom, int crc_type){ uchar construct_buffer[32]; int i,buffer_cnt=0,start_address,do_access; ushort lastcrc16;#if DEBUG_OW_TRNU printf ("owWritePacketStd: %d %d\n", start_page, write_len);#endif // check to see if data too long to fit on device if (write_len > 29) {#if DEBUG_OW_TRNU printf ("owWritePacketStd: too long\n");#endif return FALSE; } // seed crc with page number setcrc16(portnum,(ushort)start_page); // set length byte construct_buffer[buffer_cnt++] = (uchar)(write_len); docrc16(portnum,(ushort)write_len); // fill in the data to write for (i = 0; i < write_len; i++) { lastcrc16 = docrc16(portnum,write_buf[i]); construct_buffer[buffer_cnt++] = write_buf[i]; } // add the crc construct_buffer[buffer_cnt++] = (uchar)(~(lastcrc16 & 0xFF)); construct_buffer[buffer_cnt++] = (uchar)(~((lastcrc16 & 0xFF00) >> 8));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -