Steven Vlach / 1-WireLib
Committer:
svlach
Date:
Tue Nov 30 22:11:18 2010 +0000
Revision:
0:70c3bea805ee
Child:
1:dcf2f8359398

        

Who changed what in which revision?

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