1-Wire implementation, using DS2480B controller interfaced with serial port, working example to read DS18B20, based on work already in progress / Dallas - Public domain code

Dependencies:   mbed

Committer:
pwheels
Date:
Thu Mar 24 17:21:29 2011 +0000
Revision:
0:1193dbfe28e2

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pwheels 0:1193dbfe28e2 1 //---------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 2 // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
pwheels 0:1193dbfe28e2 3 //
pwheels 0:1193dbfe28e2 4 // Permission is hereby granted, free of charge, to any person obtaining a
pwheels 0:1193dbfe28e2 5 // copy of this software and associated documentation files (the "Software"),
pwheels 0:1193dbfe28e2 6 // to deal in the Software without restriction, including without limitation
pwheels 0:1193dbfe28e2 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
pwheels 0:1193dbfe28e2 8 // and/or sell copies of the Software, and to permit persons to whom the
pwheels 0:1193dbfe28e2 9 // Software is furnished to do so, subject to the following conditions:
pwheels 0:1193dbfe28e2 10 //
pwheels 0:1193dbfe28e2 11 // The above copyright notice and this permission notice shall be included
pwheels 0:1193dbfe28e2 12 // in all copies or substantial portions of the Software.
pwheels 0:1193dbfe28e2 13 //
pwheels 0:1193dbfe28e2 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
pwheels 0:1193dbfe28e2 15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
pwheels 0:1193dbfe28e2 16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
pwheels 0:1193dbfe28e2 17 // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
pwheels 0:1193dbfe28e2 18 // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
pwheels 0:1193dbfe28e2 19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
pwheels 0:1193dbfe28e2 20 // OTHER DEALINGS IN THE SOFTWARE.
pwheels 0:1193dbfe28e2 21 //
pwheels 0:1193dbfe28e2 22 // Except as contained in this notice, the name of Dallas Semiconductor
pwheels 0:1193dbfe28e2 23 // shall not be used except as stated in the Dallas Semiconductor
pwheels 0:1193dbfe28e2 24 // Branding Policy.
pwheels 0:1193dbfe28e2 25 //---------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 26 //
pwheels 0:1193dbfe28e2 27 // owTranU.C - Transport functions for 1-Wire Net
pwheels 0:1193dbfe28e2 28 // using the DS2480B (U) serial interface chip.
pwheels 0:1193dbfe28e2 29 //
pwheels 0:1193dbfe28e2 30 // Version: 2.01
pwheels 0:1193dbfe28e2 31 //
pwheels 0:1193dbfe28e2 32 // History: 1.02 -> 1.03 Removed caps in #includes for Linux capatibility
pwheels 0:1193dbfe28e2 33 // 1.03 -> 2.00 Changed 'MLan' to 'ow'. Added support for
pwheels 0:1193dbfe28e2 34 // multiple ports.
pwheels 0:1193dbfe28e2 35 // 2.00 -> 2.01 Added support for owError library
pwheels 0:1193dbfe28e2 36 // 2.01 -> 2.10 Added SMALLINT for small processors and error
pwheels 0:1193dbfe28e2 37 // handling plus the raw memory utilities.
pwheels 0:1193dbfe28e2 38 // 2.10 -> 3.00 Added memory bank functionality
pwheels 0:1193dbfe28e2 39 // Added file I/O operations
pwheels 0:1193dbfe28e2 40 //
pwheels 0:1193dbfe28e2 41
pwheels 0:1193dbfe28e2 42 #include "ownet.h"
pwheels 0:1193dbfe28e2 43 #include "./Headers/ds2480.h"
pwheels 0:1193dbfe28e2 44 // external defined in ds2480ut.c
pwheels 0:1193dbfe28e2 45 extern SMALLINT UBaud[MAX_PORTNUM];
pwheels 0:1193dbfe28e2 46 extern SMALLINT UMode[MAX_PORTNUM];
pwheels 0:1193dbfe28e2 47 extern SMALLINT USpeed[MAX_PORTNUM];
pwheels 0:1193dbfe28e2 48 extern uchar SerialNum[MAX_PORTNUM][8];
pwheels 0:1193dbfe28e2 49
pwheels 0:1193dbfe28e2 50 // local static functions
pwheels 0:1193dbfe28e2 51 static SMALLINT Write_Scratchpad(int,uchar *,int,SMALLINT);
pwheels 0:1193dbfe28e2 52 static SMALLINT Copy_Scratchpad(int,int,SMALLINT);
pwheels 0:1193dbfe28e2 53
pwheels 0:1193dbfe28e2 54 //--------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 55 // The 'owBlock' transfers a block of data to and from the
pwheels 0:1193dbfe28e2 56 // 1-Wire Net with an optional reset at the begining of communication.
pwheels 0:1193dbfe28e2 57 // The result is returned in the same buffer.
pwheels 0:1193dbfe28e2 58 //
pwheels 0:1193dbfe28e2 59 // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
pwheels 0:1193dbfe28e2 60 // indicate the symbolic port number.
pwheels 0:1193dbfe28e2 61 // 'do_reset' - cause a owTouchReset to occure at the begining of
pwheels 0:1193dbfe28e2 62 // communication TRUE(1) or not FALSE(0)
pwheels 0:1193dbfe28e2 63 // 'tran_buf' - pointer to a block of unsigned
pwheels 0:1193dbfe28e2 64 // chars of length 'tran_len' that will be sent
pwheels 0:1193dbfe28e2 65 // to the 1-Wire Net
pwheels 0:1193dbfe28e2 66 // 'tran_len' - length in bytes to transfer
pwheels 0:1193dbfe28e2 67
pwheels 0:1193dbfe28e2 68 // Supported devices: all
pwheels 0:1193dbfe28e2 69 //
pwheels 0:1193dbfe28e2 70 // Returns: TRUE (1) : The optional reset returned a valid
pwheels 0:1193dbfe28e2 71 // presence (do_reset == TRUE) or there
pwheels 0:1193dbfe28e2 72 // was no reset required.
pwheels 0:1193dbfe28e2 73 // FALSE (0): The reset did not return a valid prsence
pwheels 0:1193dbfe28e2 74 // (do_reset == TRUE).
pwheels 0:1193dbfe28e2 75 //
pwheels 0:1193dbfe28e2 76 // The maximum tran_length is (160)
pwheels 0:1193dbfe28e2 77 //
pwheels 0:1193dbfe28e2 78 SMALLINT owBlock(int portnum, SMALLINT do_reset, uchar *tran_buf, SMALLINT tran_len)
pwheels 0:1193dbfe28e2 79 {
pwheels 0:1193dbfe28e2 80 uchar sendpacket[320];
pwheels 0:1193dbfe28e2 81 uchar sendlen=0,i;
pwheels 0:1193dbfe28e2 82
pwheels 0:1193dbfe28e2 83 // check for a block too big
pwheels 0:1193dbfe28e2 84 if (tran_len > 160)
pwheels 0:1193dbfe28e2 85 {
pwheels 0:1193dbfe28e2 86 OWERROR(OWERROR_BLOCK_TOO_BIG);
pwheels 0:1193dbfe28e2 87 return FALSE;
pwheels 0:1193dbfe28e2 88 }
pwheels 0:1193dbfe28e2 89
pwheels 0:1193dbfe28e2 90 // check if need to do a owTouchReset first
pwheels 0:1193dbfe28e2 91 if (do_reset)
pwheels 0:1193dbfe28e2 92 {
pwheels 0:1193dbfe28e2 93 if (!owTouchReset(portnum))
pwheels 0:1193dbfe28e2 94 {
pwheels 0:1193dbfe28e2 95 OWERROR(OWERROR_NO_DEVICES_ON_NET);
pwheels 0:1193dbfe28e2 96 return FALSE;
pwheels 0:1193dbfe28e2 97 }
pwheels 0:1193dbfe28e2 98 }
pwheels 0:1193dbfe28e2 99
pwheels 0:1193dbfe28e2 100 // construct the packet to send to the DS2480
pwheels 0:1193dbfe28e2 101 // check if correct mode
pwheels 0:1193dbfe28e2 102 if (UMode[portnum] != MODSEL_DATA)
pwheels 0:1193dbfe28e2 103 {
pwheels 0:1193dbfe28e2 104 UMode[portnum] = MODSEL_DATA;
pwheels 0:1193dbfe28e2 105 sendpacket[sendlen++] = MODE_DATA;
pwheels 0:1193dbfe28e2 106 }
pwheels 0:1193dbfe28e2 107
pwheels 0:1193dbfe28e2 108 // add the bytes to send
pwheels 0:1193dbfe28e2 109 // pos = sendlen;
pwheels 0:1193dbfe28e2 110 for (i = 0; i < tran_len; i++)
pwheels 0:1193dbfe28e2 111 {
pwheels 0:1193dbfe28e2 112 sendpacket[sendlen++] = tran_buf[i];
pwheels 0:1193dbfe28e2 113
pwheels 0:1193dbfe28e2 114 // check for duplication of data that looks like COMMAND mode
pwheels 0:1193dbfe28e2 115 if (tran_buf[i] == MODE_COMMAND)
pwheels 0:1193dbfe28e2 116 sendpacket[sendlen++] = tran_buf[i];
pwheels 0:1193dbfe28e2 117 }
pwheels 0:1193dbfe28e2 118
pwheels 0:1193dbfe28e2 119 // flush the buffers
pwheels 0:1193dbfe28e2 120 FlushCOM(portnum);
pwheels 0:1193dbfe28e2 121
pwheels 0:1193dbfe28e2 122 // send the packet
pwheels 0:1193dbfe28e2 123 if (WriteCOM(portnum,sendlen,sendpacket))
pwheels 0:1193dbfe28e2 124 {
pwheels 0:1193dbfe28e2 125 // read back the response
pwheels 0:1193dbfe28e2 126 if (ReadCOM(portnum,tran_len,tran_buf) == tran_len)
pwheels 0:1193dbfe28e2 127 return TRUE;
pwheels 0:1193dbfe28e2 128 else
pwheels 0:1193dbfe28e2 129 OWERROR(OWERROR_READCOM_FAILED);
pwheels 0:1193dbfe28e2 130 }
pwheels 0:1193dbfe28e2 131 else
pwheels 0:1193dbfe28e2 132 OWERROR(OWERROR_WRITECOM_FAILED);
pwheels 0:1193dbfe28e2 133
pwheels 0:1193dbfe28e2 134 // an error occured so re-sync with DS2480
pwheels 0:1193dbfe28e2 135 DS2480Detect(portnum);
pwheels 0:1193dbfe28e2 136
pwheels 0:1193dbfe28e2 137 return FALSE;
pwheels 0:1193dbfe28e2 138 }
pwheels 0:1193dbfe28e2 139
pwheels 0:1193dbfe28e2 140 //--------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 141 // Read a Universal Data Packet from a standard NVRAM iButton
pwheels 0:1193dbfe28e2 142 // and return it in the provided buffer. The page that the
pwheels 0:1193dbfe28e2 143 // packet resides on is 'start_page'. Note that this function is limited
pwheels 0:1193dbfe28e2 144 // to single page packets. The buffer 'read_buf' must be at least
pwheels 0:1193dbfe28e2 145 // 29 bytes long.
pwheels 0:1193dbfe28e2 146 //
pwheels 0:1193dbfe28e2 147 // The Universal Data Packet always start on page boundaries but
pwheels 0:1193dbfe28e2 148 // can end anywhere. The length is the number of data bytes not
pwheels 0:1193dbfe28e2 149 // including the length byte and the CRC16 bytes. There is one
pwheels 0:1193dbfe28e2 150 // length byte. The CRC16 is first initialized to the starting
pwheels 0:1193dbfe28e2 151 // page number. This provides a check to verify the page that
pwheels 0:1193dbfe28e2 152 // was intended is being read. The CRC16 is then calculated over
pwheels 0:1193dbfe28e2 153 // the length and data bytes. The CRC16 is then inverted and stored
pwheels 0:1193dbfe28e2 154 // low byte first followed by the high byte.
pwheels 0:1193dbfe28e2 155 //
pwheels 0:1193dbfe28e2 156 // Supported devices: DS1992, DS1993, DS1994, DS1995, DS1996, DS1982,
pwheels 0:1193dbfe28e2 157 // DS1985, DS1986, DS2407, and DS1971.
pwheels 0:1193dbfe28e2 158 //
pwheels 0:1193dbfe28e2 159 // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
pwheels 0:1193dbfe28e2 160 // indicate the symbolic port number.
pwheels 0:1193dbfe28e2 161 // 'do_access' - flag to indicate if an 'owAccess' should be
pwheels 0:1193dbfe28e2 162 // peformed at the begining of the read. This may
pwheels 0:1193dbfe28e2 163 // be FALSE (0) if the previous call was to read the
pwheels 0:1193dbfe28e2 164 // previous page (start_page-1).
pwheels 0:1193dbfe28e2 165 // 'start_page' - page number to start the read from
pwheels 0:1193dbfe28e2 166 // 'read_buf' - pointer to a location to store the data read
pwheels 0:1193dbfe28e2 167 //
pwheels 0:1193dbfe28e2 168 // Returns: >=0 success, number of data bytes in the buffer
pwheels 0:1193dbfe28e2 169 // -1 failed to read a valid UDP
pwheels 0:1193dbfe28e2 170 //
pwheels 0:1193dbfe28e2 171 //
pwheels 0:1193dbfe28e2 172 SMALLINT owReadPacketStd(int portnum, SMALLINT do_access, int start_page, uchar *read_buf)
pwheels 0:1193dbfe28e2 173 {
pwheels 0:1193dbfe28e2 174 uchar i,length,sendlen=0,head_len=0;
pwheels 0:1193dbfe28e2 175 uchar sendpacket[50];
pwheels 0:1193dbfe28e2 176 unsigned short lastcrc16;
pwheels 0:1193dbfe28e2 177
pwheels 0:1193dbfe28e2 178 // check if access header is done
pwheels 0:1193dbfe28e2 179 // (only use if in sequention read with one access at begining)
pwheels 0:1193dbfe28e2 180 if (do_access)
pwheels 0:1193dbfe28e2 181 {
pwheels 0:1193dbfe28e2 182 // match command
pwheels 0:1193dbfe28e2 183 sendpacket[sendlen++] = 0x55;
pwheels 0:1193dbfe28e2 184 for (i = 0; i < 8; i++)
pwheels 0:1193dbfe28e2 185 sendpacket[sendlen++] = SerialNum[portnum][i];
pwheels 0:1193dbfe28e2 186 // read memory command
pwheels 0:1193dbfe28e2 187 sendpacket[sendlen++] = 0xF0;
pwheels 0:1193dbfe28e2 188 // write the target address
pwheels 0:1193dbfe28e2 189 sendpacket[sendlen++] = ((start_page << 5) & 0xFF);
pwheels 0:1193dbfe28e2 190 sendpacket[sendlen++] = (start_page >> 3);
pwheels 0:1193dbfe28e2 191 // check for DS1982 exception (redirection byte)
pwheels 0:1193dbfe28e2 192 if (SerialNum[portnum][0] == 0x09)
pwheels 0:1193dbfe28e2 193 sendpacket[sendlen++] = 0xFF;
pwheels 0:1193dbfe28e2 194 // record the header length
pwheels 0:1193dbfe28e2 195 head_len = sendlen;
pwheels 0:1193dbfe28e2 196 }
pwheels 0:1193dbfe28e2 197 // read the entire page length byte
pwheels 0:1193dbfe28e2 198 for (i = 0; i < 32; i++)
pwheels 0:1193dbfe28e2 199 sendpacket[sendlen++] = 0xFF;
pwheels 0:1193dbfe28e2 200
pwheels 0:1193dbfe28e2 201 // send/recieve the transfer buffer
pwheels 0:1193dbfe28e2 202 if (owBlock(portnum,do_access,sendpacket,sendlen))
pwheels 0:1193dbfe28e2 203 {
pwheels 0:1193dbfe28e2 204 // seed crc with page number
pwheels 0:1193dbfe28e2 205 setcrc16(portnum,(unsigned short)start_page);
pwheels 0:1193dbfe28e2 206
pwheels 0:1193dbfe28e2 207 // attempt to read UDP from sendpacket
pwheels 0:1193dbfe28e2 208 length = sendpacket[head_len];
pwheels 0:1193dbfe28e2 209 docrc16(portnum,(unsigned short)length);
pwheels 0:1193dbfe28e2 210
pwheels 0:1193dbfe28e2 211 // verify length is not too large
pwheels 0:1193dbfe28e2 212 if (length <= 29)
pwheels 0:1193dbfe28e2 213 {
pwheels 0:1193dbfe28e2 214 // loop to read packet including CRC
pwheels 0:1193dbfe28e2 215 for (i = 0; i < length; i++)
pwheels 0:1193dbfe28e2 216 {
pwheels 0:1193dbfe28e2 217 read_buf[i] = sendpacket[i+1+head_len];
pwheels 0:1193dbfe28e2 218 docrc16(portnum,read_buf[i]);
pwheels 0:1193dbfe28e2 219 }
pwheels 0:1193dbfe28e2 220
pwheels 0:1193dbfe28e2 221 // read and compute the CRC16
pwheels 0:1193dbfe28e2 222 docrc16(portnum,sendpacket[i+1+head_len]);
pwheels 0:1193dbfe28e2 223 lastcrc16 = docrc16(portnum,sendpacket[i+2+head_len]);
pwheels 0:1193dbfe28e2 224
pwheels 0:1193dbfe28e2 225 // verify the CRC16 is correct
pwheels 0:1193dbfe28e2 226 if (lastcrc16 == 0xB001)
pwheels 0:1193dbfe28e2 227 return length; // return number of byte in record
pwheels 0:1193dbfe28e2 228 else
pwheels 0:1193dbfe28e2 229 OWERROR(OWERROR_CRC_FAILED);
pwheels 0:1193dbfe28e2 230 }
pwheels 0:1193dbfe28e2 231 else
pwheels 0:1193dbfe28e2 232 OWERROR(OWERROR_INCORRECT_CRC_LENGTH);
pwheels 0:1193dbfe28e2 233 }
pwheels 0:1193dbfe28e2 234 else
pwheels 0:1193dbfe28e2 235 OWERROR(OWERROR_BLOCK_FAILED);
pwheels 0:1193dbfe28e2 236
pwheels 0:1193dbfe28e2 237 // failed block or incorrect CRC
pwheels 0:1193dbfe28e2 238 return -1;
pwheels 0:1193dbfe28e2 239 }
pwheels 0:1193dbfe28e2 240
pwheels 0:1193dbfe28e2 241 //--------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 242 // Write a Universal Data Packet onto a standard NVRAM 1-Wire device
pwheels 0:1193dbfe28e2 243 // on page 'start_page'. This function is limited to UDPs that
pwheels 0:1193dbfe28e2 244 // fit on one page. The data to write is provided as a buffer
pwheels 0:1193dbfe28e2 245 // 'write_buf' with a length 'write_len'.
pwheels 0:1193dbfe28e2 246 //
pwheels 0:1193dbfe28e2 247 // The Universal Data Packet always start on page boundaries but
pwheels 0:1193dbfe28e2 248 // can end anywhere. The length is the number of data bytes not
pwheels 0:1193dbfe28e2 249 // including the length byte and the CRC16 bytes. There is one
pwheels 0:1193dbfe28e2 250 // length byte. The CRC16 is first initialized to the starting
pwheels 0:1193dbfe28e2 251 // page number. This provides a check to verify the page that
pwheels 0:1193dbfe28e2 252 // was intended is being read. The CRC16 is then calculated over
pwheels 0:1193dbfe28e2 253 // the length and data bytes. The CRC16 is then inverted and stored
pwheels 0:1193dbfe28e2 254 // low byte first followed by the high byte.
pwheels 0:1193dbfe28e2 255 //
pwheels 0:1193dbfe28e2 256 // Supported devices: is_eprom=0
pwheels 0:1193dbfe28e2 257 // DS1992, DS1993, DS1994, DS1995, DS1996
pwheels 0:1193dbfe28e2 258 // is_eprom=1, crc_type=0(CRC8)
pwheels 0:1193dbfe28e2 259 // DS1982
pwheels 0:1193dbfe28e2 260 // is_eprom=1, crc_type=1(CRC16)
pwheels 0:1193dbfe28e2 261 // DS1985, DS1986, DS2407
pwheels 0:1193dbfe28e2 262 //
pwheels 0:1193dbfe28e2 263 // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
pwheels 0:1193dbfe28e2 264 // indicate the symbolic port number.
pwheels 0:1193dbfe28e2 265 // 'start_page' - page number to write packet to
pwheels 0:1193dbfe28e2 266 // 'write_buf' - pointer to buffer containing data to write
pwheels 0:1193dbfe28e2 267 // 'write_len' - number of data byte in write_buf
pwheels 0:1193dbfe28e2 268 // 'is_eprom' - flag set if device is an EPROM (1 EPROM, 0 NVRAM)
pwheels 0:1193dbfe28e2 269 // 'crc_type' - if is_eprom=1 then indicates CRC type
pwheels 0:1193dbfe28e2 270 // (0 CRC8, 1 CRC16)
pwheels 0:1193dbfe28e2 271 //
pwheels 0:1193dbfe28e2 272 // Returns: TRUE(1) success, packet written
pwheels 0:1193dbfe28e2 273 // FALSE(0) failure to write, contact lost or device locked
pwheels 0:1193dbfe28e2 274 //
pwheels 0:1193dbfe28e2 275 SMALLINT owWritePacketStd(int portnum, int start_page, uchar *write_buf,
pwheels 0:1193dbfe28e2 276 SMALLINT write_len, SMALLINT is_eprom, SMALLINT crc_type)
pwheels 0:1193dbfe28e2 277 {
pwheels 0:1193dbfe28e2 278 uchar construct_buffer[32];
pwheels 0:1193dbfe28e2 279 uchar i,buffer_cnt=0,start_address,do_access;
pwheels 0:1193dbfe28e2 280 unsigned short lastcrc16=0;
pwheels 0:1193dbfe28e2 281
pwheels 0:1193dbfe28e2 282 // check to see if data too long to fit on device
pwheels 0:1193dbfe28e2 283 if (write_len > 29)
pwheels 0:1193dbfe28e2 284 return FALSE;
pwheels 0:1193dbfe28e2 285
pwheels 0:1193dbfe28e2 286 // seed crc with page number
pwheels 0:1193dbfe28e2 287 setcrc16(portnum,(unsigned short)start_page);
pwheels 0:1193dbfe28e2 288
pwheels 0:1193dbfe28e2 289 // set length byte
pwheels 0:1193dbfe28e2 290 construct_buffer[buffer_cnt++] = (uchar)(write_len);
pwheels 0:1193dbfe28e2 291 docrc16(portnum,(unsigned short)write_len);
pwheels 0:1193dbfe28e2 292
pwheels 0:1193dbfe28e2 293 // fill in the data to write
pwheels 0:1193dbfe28e2 294 for (i = 0; i < write_len; i++)
pwheels 0:1193dbfe28e2 295 {
pwheels 0:1193dbfe28e2 296 lastcrc16 = docrc16(portnum,write_buf[i]);
pwheels 0:1193dbfe28e2 297 construct_buffer[buffer_cnt++] = write_buf[i];
pwheels 0:1193dbfe28e2 298 }
pwheels 0:1193dbfe28e2 299
pwheels 0:1193dbfe28e2 300 // add the crc
pwheels 0:1193dbfe28e2 301 construct_buffer[buffer_cnt++] = (uchar)(~(lastcrc16 & 0xFF));
pwheels 0:1193dbfe28e2 302 construct_buffer[buffer_cnt++] = (uchar)(~((lastcrc16 & 0xFF00) >> 8));
pwheels 0:1193dbfe28e2 303
pwheels 0:1193dbfe28e2 304 // check if not EPROM
pwheels 0:1193dbfe28e2 305 if (!is_eprom)
pwheels 0:1193dbfe28e2 306 {
pwheels 0:1193dbfe28e2 307 // write the page
pwheels 0:1193dbfe28e2 308 if (!Write_Scratchpad(portnum,construct_buffer,start_page,buffer_cnt))
pwheels 0:1193dbfe28e2 309 {
pwheels 0:1193dbfe28e2 310 OWERROR(OWERROR_WRITE_SCRATCHPAD_FAILED);
pwheels 0:1193dbfe28e2 311 return FALSE;
pwheels 0:1193dbfe28e2 312 }
pwheels 0:1193dbfe28e2 313
pwheels 0:1193dbfe28e2 314 // copy the scratchpad
pwheels 0:1193dbfe28e2 315 if (!Copy_Scratchpad(portnum,start_page,buffer_cnt))
pwheels 0:1193dbfe28e2 316 {
pwheels 0:1193dbfe28e2 317 OWERROR(OWERROR_COPY_SCRATCHPAD_FAILED);
pwheels 0:1193dbfe28e2 318 return FALSE;
pwheels 0:1193dbfe28e2 319 }
pwheels 0:1193dbfe28e2 320
pwheels 0:1193dbfe28e2 321 // copy scratch pad was good then success
pwheels 0:1193dbfe28e2 322 return TRUE;
pwheels 0:1193dbfe28e2 323 }
pwheels 0:1193dbfe28e2 324 // is EPROM
pwheels 0:1193dbfe28e2 325 else
pwheels 0:1193dbfe28e2 326 {
pwheels 0:1193dbfe28e2 327 // calculate the start address
pwheels 0:1193dbfe28e2 328 start_address = ((start_page >> 3) << 8) | ((start_page << 5) & 0xFF);
pwheels 0:1193dbfe28e2 329 do_access = TRUE;
pwheels 0:1193dbfe28e2 330 // loop to program each byte
pwheels 0:1193dbfe28e2 331 for (i = 0; i < buffer_cnt; i++)
pwheels 0:1193dbfe28e2 332 {
pwheels 0:1193dbfe28e2 333 if (owProgramByte(portnum,construct_buffer[i], start_address + i,
pwheels 0:1193dbfe28e2 334 0x0F, crc_type, do_access) != construct_buffer[i])
pwheels 0:1193dbfe28e2 335 {
pwheels 0:1193dbfe28e2 336 OWERROR(OWERROR_PROGRAM_BYTE_FAILED);
pwheels 0:1193dbfe28e2 337 return FALSE;
pwheels 0:1193dbfe28e2 338 }
pwheels 0:1193dbfe28e2 339 do_access = FALSE;
pwheels 0:1193dbfe28e2 340 }
pwheels 0:1193dbfe28e2 341 return TRUE;
pwheels 0:1193dbfe28e2 342 }
pwheels 0:1193dbfe28e2 343 }
pwheels 0:1193dbfe28e2 344
pwheels 0:1193dbfe28e2 345 //--------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 346 // Write a byte to an EPROM 1-Wire device.
pwheels 0:1193dbfe28e2 347 //
pwheels 0:1193dbfe28e2 348 // Supported devices: crc_type=0(CRC8)
pwheels 0:1193dbfe28e2 349 // DS1982
pwheels 0:1193dbfe28e2 350 // crc_type=1(CRC16)
pwheels 0:1193dbfe28e2 351 // DS1985, DS1986, DS2407
pwheels 0:1193dbfe28e2 352 //
pwheels 0:1193dbfe28e2 353 // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
pwheels 0:1193dbfe28e2 354 // indicate the symbolic port number.
pwheels 0:1193dbfe28e2 355 // 'write_byte' - byte to program
pwheels 0:1193dbfe28e2 356 // 'addr' - address of byte to program
pwheels 0:1193dbfe28e2 357 // 'write_cmd' - command used to write (0x0F reg mem, 0x55 status)
pwheels 0:1193dbfe28e2 358 // 'crc_type' - CRC used (0 CRC8, 1 CRC16)
pwheels 0:1193dbfe28e2 359 // 'do_access' - Flag to access device for each byte
pwheels 0:1193dbfe28e2 360 // (0 skip access, 1 do the access)
pwheels 0:1193dbfe28e2 361 // WARNING, only use do_access=0 if programing the NEXT
pwheels 0:1193dbfe28e2 362 // byte immediatly after the previous byte.
pwheels 0:1193dbfe28e2 363 //
pwheels 0:1193dbfe28e2 364 // Returns: >=0 success, this is the resulting byte from the program
pwheels 0:1193dbfe28e2 365 // effort
pwheels 0:1193dbfe28e2 366 // -1 error, device not connected or program pulse voltage
pwheels 0:1193dbfe28e2 367 // not available
pwheels 0:1193dbfe28e2 368 //
pwheels 0:1193dbfe28e2 369 SMALLINT owProgramByte(int portnum, SMALLINT write_byte, int addr, SMALLINT write_cmd,
pwheels 0:1193dbfe28e2 370 SMALLINT crc_type, SMALLINT do_access)
pwheels 0:1193dbfe28e2 371 {
pwheels 0:1193dbfe28e2 372 unsigned short lastcrc16;
pwheels 0:1193dbfe28e2 373 uchar lastcrc8;
pwheels 0:1193dbfe28e2 374
pwheels 0:1193dbfe28e2 375 // optionally access the device
pwheels 0:1193dbfe28e2 376 if (do_access)
pwheels 0:1193dbfe28e2 377 {
pwheels 0:1193dbfe28e2 378 if (!owAccess(portnum))
pwheels 0:1193dbfe28e2 379 {
pwheels 0:1193dbfe28e2 380 OWERROR(OWERROR_ACCESS_FAILED);
pwheels 0:1193dbfe28e2 381 return -1;
pwheels 0:1193dbfe28e2 382 }
pwheels 0:1193dbfe28e2 383
pwheels 0:1193dbfe28e2 384 // send the write command
pwheels 0:1193dbfe28e2 385 if (!owWriteByte(portnum,write_cmd))
pwheels 0:1193dbfe28e2 386 {
pwheels 0:1193dbfe28e2 387 OWERROR(OWERROR_WRITE_BYTE_FAILED);
pwheels 0:1193dbfe28e2 388 return -1;
pwheels 0:1193dbfe28e2 389 }
pwheels 0:1193dbfe28e2 390
pwheels 0:1193dbfe28e2 391 // send the address
pwheels 0:1193dbfe28e2 392 if (!owWriteByte(portnum,addr & 0xFF) || !owWriteByte(portnum,addr >> 8))
pwheels 0:1193dbfe28e2 393 {
pwheels 0:1193dbfe28e2 394 OWERROR(OWERROR_WRITE_BYTE_FAILED);
pwheels 0:1193dbfe28e2 395 return -1;
pwheels 0:1193dbfe28e2 396 }
pwheels 0:1193dbfe28e2 397 }
pwheels 0:1193dbfe28e2 398
pwheels 0:1193dbfe28e2 399 // send the data to write
pwheels 0:1193dbfe28e2 400 if (!owWriteByte(portnum,write_byte))
pwheels 0:1193dbfe28e2 401 {
pwheels 0:1193dbfe28e2 402 OWERROR(OWERROR_WRITE_BYTE_FAILED);
pwheels 0:1193dbfe28e2 403 return -1;
pwheels 0:1193dbfe28e2 404 }
pwheels 0:1193dbfe28e2 405
pwheels 0:1193dbfe28e2 406 // read the CRC
pwheels 0:1193dbfe28e2 407 if (crc_type == 0)
pwheels 0:1193dbfe28e2 408 {
pwheels 0:1193dbfe28e2 409 // calculate CRC8
pwheels 0:1193dbfe28e2 410 if (do_access)
pwheels 0:1193dbfe28e2 411 {
pwheels 0:1193dbfe28e2 412 setcrc8(portnum,0);
pwheels 0:1193dbfe28e2 413 docrc8(portnum,(uchar)write_cmd);
pwheels 0:1193dbfe28e2 414 docrc8(portnum,(uchar)(addr & 0xFF));
pwheels 0:1193dbfe28e2 415 docrc8(portnum,(uchar)(addr >> 8));
pwheels 0:1193dbfe28e2 416 }
pwheels 0:1193dbfe28e2 417 else
pwheels 0:1193dbfe28e2 418 setcrc8(portnum,(uchar)(addr & 0xFF));
pwheels 0:1193dbfe28e2 419
pwheels 0:1193dbfe28e2 420 docrc8(portnum,(uchar)write_byte);
pwheels 0:1193dbfe28e2 421 // read and calculate the read crc
pwheels 0:1193dbfe28e2 422 lastcrc8 = docrc8(portnum,(uchar)owReadByte(portnum));
pwheels 0:1193dbfe28e2 423 // crc should now be 0x00
pwheels 0:1193dbfe28e2 424 if (lastcrc8 != 0)
pwheels 0:1193dbfe28e2 425 {
pwheels 0:1193dbfe28e2 426 OWERROR(OWERROR_CRC_FAILED);
pwheels 0:1193dbfe28e2 427 return -1;
pwheels 0:1193dbfe28e2 428 }
pwheels 0:1193dbfe28e2 429 }
pwheels 0:1193dbfe28e2 430 else
pwheels 0:1193dbfe28e2 431 {
pwheels 0:1193dbfe28e2 432 // CRC16
pwheels 0:1193dbfe28e2 433 if (do_access)
pwheels 0:1193dbfe28e2 434 {
pwheels 0:1193dbfe28e2 435 setcrc16(portnum,0);
pwheels 0:1193dbfe28e2 436 docrc16(portnum,(unsigned short)write_cmd);
pwheels 0:1193dbfe28e2 437 docrc16(portnum,(unsigned short)(addr & 0xFF));
pwheels 0:1193dbfe28e2 438 docrc16(portnum,(unsigned short)(addr >> 8));
pwheels 0:1193dbfe28e2 439 }
pwheels 0:1193dbfe28e2 440 else
pwheels 0:1193dbfe28e2 441 setcrc16(portnum,(unsigned short)addr);
pwheels 0:1193dbfe28e2 442 docrc16(portnum,(unsigned short)write_byte);
pwheels 0:1193dbfe28e2 443 // read and calculate the read crc
pwheels 0:1193dbfe28e2 444 docrc16(portnum,( unsigned short)owReadByte(portnum));
pwheels 0:1193dbfe28e2 445 lastcrc16 = docrc16(portnum,( unsigned short)owReadByte(portnum));
pwheels 0:1193dbfe28e2 446 // crc should now be 0xB001
pwheels 0:1193dbfe28e2 447 if (lastcrc16 != 0xB001)
pwheels 0:1193dbfe28e2 448 {
pwheels 0:1193dbfe28e2 449 OWERROR(OWERROR_CRC_FAILED);
pwheels 0:1193dbfe28e2 450 return -1;
pwheels 0:1193dbfe28e2 451 }
pwheels 0:1193dbfe28e2 452 }
pwheels 0:1193dbfe28e2 453
pwheels 0:1193dbfe28e2 454 // send the program pulse
pwheels 0:1193dbfe28e2 455 if (!owProgramPulse(portnum))
pwheels 0:1193dbfe28e2 456 {
pwheels 0:1193dbfe28e2 457 OWERROR(OWERROR_PROGRAM_PULSE_FAILED);
pwheels 0:1193dbfe28e2 458 return -1;
pwheels 0:1193dbfe28e2 459 }
pwheels 0:1193dbfe28e2 460
pwheels 0:1193dbfe28e2 461 // read back and return the resulting byte
pwheels 0:1193dbfe28e2 462 return owReadByte(portnum);
pwheels 0:1193dbfe28e2 463 }
pwheels 0:1193dbfe28e2 464
pwheels 0:1193dbfe28e2 465 //--------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 466 // Write the scratchpad of a standard NVRam device such as the DS1992,3,4
pwheels 0:1193dbfe28e2 467 // and verify its contents.
pwheels 0:1193dbfe28e2 468 //
pwheels 0:1193dbfe28e2 469 // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
pwheels 0:1193dbfe28e2 470 // indicate the symbolic port number.
pwheels 0:1193dbfe28e2 471 // 'write_buf' - pointer to buffer containing data to write
pwheels 0:1193dbfe28e2 472 // 'start_page' - page number to write packet to
pwheels 0:1193dbfe28e2 473 // 'write_len' - number of data byte in write_buf
pwheels 0:1193dbfe28e2 474 //
pwheels 0:1193dbfe28e2 475 // Returns: TRUE(1) success, the data was written and verified
pwheels 0:1193dbfe28e2 476 // FALSE(0) failure, the data could not be written
pwheels 0:1193dbfe28e2 477 //
pwheels 0:1193dbfe28e2 478 //
pwheels 0:1193dbfe28e2 479 SMALLINT Write_Scratchpad(int portnum, uchar *write_buf, int start_page, SMALLINT write_len)
pwheels 0:1193dbfe28e2 480 {
pwheels 0:1193dbfe28e2 481 uchar i,sendlen=0;
pwheels 0:1193dbfe28e2 482 uchar sendpacket[50];
pwheels 0:1193dbfe28e2 483
pwheels 0:1193dbfe28e2 484 // match command
pwheels 0:1193dbfe28e2 485 sendpacket[sendlen++] = 0x55;
pwheels 0:1193dbfe28e2 486 for (i = 0; i < 8; i++)
pwheels 0:1193dbfe28e2 487 sendpacket[sendlen++] = SerialNum[portnum][i];
pwheels 0:1193dbfe28e2 488 // write scratchpad command
pwheels 0:1193dbfe28e2 489 sendpacket[sendlen++] = 0x0F;
pwheels 0:1193dbfe28e2 490 // write the target address
pwheels 0:1193dbfe28e2 491 sendpacket[sendlen++] = ((start_page << 5) & 0xFF);
pwheels 0:1193dbfe28e2 492 sendpacket[sendlen++] = (start_page >> 3);
pwheels 0:1193dbfe28e2 493
pwheels 0:1193dbfe28e2 494 // write packet bytes
pwheels 0:1193dbfe28e2 495 for (i = 0; i < write_len; i++)
pwheels 0:1193dbfe28e2 496 sendpacket[sendlen++] = write_buf[i];
pwheels 0:1193dbfe28e2 497
pwheels 0:1193dbfe28e2 498 // send/recieve the transfer buffer
pwheels 0:1193dbfe28e2 499 if (owBlock(portnum,TRUE,sendpacket,sendlen))
pwheels 0:1193dbfe28e2 500 {
pwheels 0:1193dbfe28e2 501 // now attempt to read back to check
pwheels 0:1193dbfe28e2 502 sendlen = 0;
pwheels 0:1193dbfe28e2 503 // match command
pwheels 0:1193dbfe28e2 504 sendpacket[sendlen++] = 0x55;
pwheels 0:1193dbfe28e2 505 for (i = 0; i < 8; i++)
pwheels 0:1193dbfe28e2 506 sendpacket[sendlen++] = SerialNum[portnum][i];
pwheels 0:1193dbfe28e2 507 // read scratchpad command
pwheels 0:1193dbfe28e2 508 sendpacket[sendlen++] = 0xAA;
pwheels 0:1193dbfe28e2 509 // read the target address, offset and data
pwheels 0:1193dbfe28e2 510 for (i = 0; i < (write_len + 3); i++)
pwheels 0:1193dbfe28e2 511 sendpacket[sendlen++] = 0xFF;
pwheels 0:1193dbfe28e2 512
pwheels 0:1193dbfe28e2 513 // send/recieve the transfer buffer
pwheels 0:1193dbfe28e2 514 if (owBlock(portnum,TRUE,sendpacket,sendlen))
pwheels 0:1193dbfe28e2 515 {
pwheels 0:1193dbfe28e2 516 // check address and offset of scratchpad read
pwheels 0:1193dbfe28e2 517 if ((sendpacket[10] != ((start_page << 5) & 0xFF)) ||
pwheels 0:1193dbfe28e2 518 (sendpacket[11] != (start_page >> 3)) ||
pwheels 0:1193dbfe28e2 519 (sendpacket[12] != (write_len - 1)))
pwheels 0:1193dbfe28e2 520 {
pwheels 0:1193dbfe28e2 521 OWERROR(OWERROR_READ_VERIFY_FAILED);
pwheels 0:1193dbfe28e2 522 return FALSE;
pwheels 0:1193dbfe28e2 523 }
pwheels 0:1193dbfe28e2 524
pwheels 0:1193dbfe28e2 525 // verify each data byte
pwheels 0:1193dbfe28e2 526 for (i = 0; i < write_len; i++)
pwheels 0:1193dbfe28e2 527 if (sendpacket[i+13] != write_buf[i])
pwheels 0:1193dbfe28e2 528 {
pwheels 0:1193dbfe28e2 529 OWERROR(OWERROR_WRITE_VERIFY_FAILED);
pwheels 0:1193dbfe28e2 530 return FALSE;
pwheels 0:1193dbfe28e2 531 }
pwheels 0:1193dbfe28e2 532
pwheels 0:1193dbfe28e2 533 // must have verified
pwheels 0:1193dbfe28e2 534 return TRUE;
pwheels 0:1193dbfe28e2 535 }
pwheels 0:1193dbfe28e2 536 else
pwheels 0:1193dbfe28e2 537 OWERROR(OWERROR_BLOCK_FAILED);
pwheels 0:1193dbfe28e2 538 }
pwheels 0:1193dbfe28e2 539 else
pwheels 0:1193dbfe28e2 540 OWERROR(OWERROR_BLOCK_FAILED);
pwheels 0:1193dbfe28e2 541
pwheels 0:1193dbfe28e2 542 // failed a block tranfer
pwheels 0:1193dbfe28e2 543 return FALSE;
pwheels 0:1193dbfe28e2 544 }
pwheels 0:1193dbfe28e2 545
pwheels 0:1193dbfe28e2 546 //--------------------------------------------------------------------------
pwheels 0:1193dbfe28e2 547 // Copy the contents of the scratchpad to its intended nv ram page. The
pwheels 0:1193dbfe28e2 548 // page and length of the data is needed to build the authorization bytes
pwheels 0:1193dbfe28e2 549 // to copy.
pwheels 0:1193dbfe28e2 550 //
pwheels 0:1193dbfe28e2 551 // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
pwheels 0:1193dbfe28e2 552 // indicate the symbolic port number.
pwheels 0:1193dbfe28e2 553 // 'start_page' - page number to write packet to
pwheels 0:1193dbfe28e2 554 // 'write_len' - number of data bytes that are being copied
pwheels 0:1193dbfe28e2 555 //
pwheels 0:1193dbfe28e2 556 // Returns: TRUE(1) success
pwheels 0:1193dbfe28e2 557 // FALSE(0) failure
pwheels 0:1193dbfe28e2 558 //
pwheels 0:1193dbfe28e2 559 SMALLINT Copy_Scratchpad(int portnum, int start_page, SMALLINT write_len)
pwheels 0:1193dbfe28e2 560 {
pwheels 0:1193dbfe28e2 561 uchar i,sendlen=0;
pwheels 0:1193dbfe28e2 562 uchar sendpacket[50];
pwheels 0:1193dbfe28e2 563
pwheels 0:1193dbfe28e2 564 // match command
pwheels 0:1193dbfe28e2 565 sendpacket[sendlen++] = 0x55;
pwheels 0:1193dbfe28e2 566 for (i = 0; i < 8; i++)
pwheels 0:1193dbfe28e2 567 sendpacket[sendlen++] = SerialNum[portnum][i];
pwheels 0:1193dbfe28e2 568 // copy scratchpad command
pwheels 0:1193dbfe28e2 569 sendpacket[sendlen++] = 0x55;
pwheels 0:1193dbfe28e2 570 // write the target address
pwheels 0:1193dbfe28e2 571 sendpacket[sendlen++] = ((start_page << 5) & 0xFF);
pwheels 0:1193dbfe28e2 572 sendpacket[sendlen++] = (start_page >> 3);
pwheels 0:1193dbfe28e2 573 sendpacket[sendlen++] = write_len - 1;
pwheels 0:1193dbfe28e2 574 // read copy result
pwheels 0:1193dbfe28e2 575 sendpacket[sendlen++] = 0xFF;
pwheels 0:1193dbfe28e2 576
pwheels 0:1193dbfe28e2 577 // send/recieve the transfer buffer
pwheels 0:1193dbfe28e2 578 if (owBlock(portnum,TRUE,sendpacket,sendlen))
pwheels 0:1193dbfe28e2 579 {
pwheels 0:1193dbfe28e2 580 // check address and offset of scratchpad read
pwheels 0:1193dbfe28e2 581 if ((sendpacket[10] != ((start_page << 5) & 0xFF)) ||
pwheels 0:1193dbfe28e2 582 (sendpacket[11] != (start_page >> 3)) ||
pwheels 0:1193dbfe28e2 583 (sendpacket[12] != (write_len - 1)) ||
pwheels 0:1193dbfe28e2 584 (sendpacket[13] & 0xF0))
pwheels 0:1193dbfe28e2 585 {
pwheels 0:1193dbfe28e2 586 OWERROR(OWERROR_READ_VERIFY_FAILED);
pwheels 0:1193dbfe28e2 587 return FALSE;
pwheels 0:1193dbfe28e2 588 }
pwheels 0:1193dbfe28e2 589 else
pwheels 0:1193dbfe28e2 590 return TRUE;
pwheels 0:1193dbfe28e2 591 }
pwheels 0:1193dbfe28e2 592 else
pwheels 0:1193dbfe28e2 593 OWERROR(OWERROR_BLOCK_FAILED);
pwheels 0:1193dbfe28e2 594
pwheels 0:1193dbfe28e2 595 // failed a block tranfer
pwheels 0:1193dbfe28e2 596 return FALSE;
pwheels 0:1193dbfe28e2 597 }
pwheels 0:1193dbfe28e2 598