1 //---------------------------------------------------------------------------
2 // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
18 // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 // OTHER DEALINGS IN THE SOFTWARE.
21 //
22 // Except as contained in this notice, the name of Dallas Semiconductor
23 // shall not be used except as stated in the Dallas Semiconductor
24 // Branding Policy.
25 //--------------------------------------------------------------------------
26 //
27 //  read_write.c - Reads and writes to memory locations of different buttons.
28 //  version 1.00
29 //
30 
31 // Include Files
32 #include <stdio.h>
33 #include "owfile.h"
34 #include "mbee.h"
35 #include "mbnv.h"
36 #include "mbappreg.h"
37 #include "mbeprom.h"
38 #include "mbnvcrc.h"
39 #include "mbshaee.h"
40 #include "mbscrcrc.h"
41 #include "mbscrex.h"
42 #include "mbsha.h"
43 #include "mbscree.h"
44 #include "mbscr.h"
45 
46 // External Functions
47 extern int   owBlock(int,int,uchar *,int);
48 extern void  setcrc8(int,uchar);
49 extern uchar docrc8(int,uchar);
50 extern int   owReadByte(int);
51 extern int   owWriteByte(int,int);
52 extern void  output_status(int, char *);
53 extern void  msDelay(int);
54 extern void  owSerialNum(int,uchar *,int);
55 extern int   owAccess(int);
56 
57 
58 /**
59  * Reads memory in this bank with no CRC checking (device or
60  * data). The resulting data from this API may or may not be what is on
61  * the 1-Wire device.  It is recommended that the data contain some kind
62  * of checking (CRC) like in the owReadPagePacket method.
63  * Some 1-Wire devices provide thier own CRC as in owReadPageCRC
64  * The owReadPageCRC method is not supported on all memory types, see hasPageAutoCRC
65  * in the same interface.  If neither is an option then this method could be called more
66  * then once to at least verify that the same data is read consistently.  The
67  * readContinue parameter is used to eliminate the overhead in re-accessing
68  * a part already being read from. For example, if pages 0 - 4 are to
69  * be read, readContinue would be set to false for page 0 and would be set
70  * to true for the next four calls.
71  *
72  * Note: Using readContinue = true  can only be used if the new
73  *       read continuous where the last one led off
74  *       and it is inside a 'beginExclusive/endExclusive'
75  *       block.
76  *
77  * bank          to tell what memory bank of the ibutton to use.
78  * portnum       the port number of the port being used for the
79  *               1-Wire Network.
80  * SNum          the serial number for the part that the read is
81  *               to be done on.
82  * str_add       starting address
83  * rd_cont       true then device read is
84  *               continued without re-selecting
85  * buff          location for data read
86  * len           length in bytes to read
87  */
owRead(SMALLINT bank,int portnum,uchar * SNum,int str_add,SMALLINT rd_cont,uchar * buff,int len)88 SMALLINT owRead(SMALLINT bank, int portnum, uchar *SNum, int str_add,
89                 SMALLINT rd_cont, uchar *buff, int len)
90 {
91    SMALLINT ret = 0;
92 
93    switch(SNum[0])
94    {
95       case 0x14:  //EE Memory Bank and AppReg Memory Bank
96          if(bank > 0)
97             ret = readEE(bank,portnum,SNum,str_add,rd_cont,buff,len);
98          else if(bank == 0)
99             ret = readAppReg(bank,portnum,SNum,str_add,rd_cont,buff,len);
100          break;
101 
102       case 0x04: case 0x06: case 0x08: case 0x0A:
103       case 0x0C: case 0x23: //NV Memory Bank and Scratch Memory Bank
104          if(bank > 0)
105             ret = readNV(bank,portnum,SNum,str_add,rd_cont,buff,len);
106          else if(bank == 0)
107             ret = readScratch(bank,portnum,SNum,str_add,rd_cont,buff,len);
108          break;
109 
110       case (0x18):  //NV Memory Bank and Scratch SHA Memory Bank
111          if(bank > 0)
112             ret = readNV(bank,portnum,SNum,str_add,rd_cont,buff,len);
113          else if(bank == 0)
114             ret = readScratch(bank,portnum,SNum,str_add,rd_cont,buff,len);
115          break;
116 
117       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
118          if(bank > 0)
119             ret = readNV(bank,portnum,SNum,str_add,rd_cont,buff,len);
120          else if(bank == 0)
121             ret = readScratch(bank,portnum,SNum,str_add,rd_cont,buff,len);
122          break;
123 
124       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
125          if(bank > 0)
126             ret = readNV(bank,portnum,SNum,str_add,rd_cont,buff,len);
127          else if(bank == 0)
128             ret = readScratch(bank,portnum,SNum,str_add,rd_cont,buff,len);
129          break;
130 
131       case 0x33: case 0xB3:  //SHAEE Memory Bank
132          ret = readSHAEE(bank,portnum,SNum,str_add,rd_cont,buff,len);
133          break;
134 
135       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
136          ret = readEPROM(bank,portnum,SNum,str_add,rd_cont,buff,len);
137          break;
138 
139       default:
140          break;
141    }
142 
143    return ret;
144 }
145 
146 /**
147  * Writes memory in this bank. It is recommended that a structure with some
148  * built in error checking is used to provide data integrity on read.
149  * The method owWritePagePacket, which automatically wraps the data in a length
150  * and CRC, could be used for this purpose.
151  *
152  * When using on Write-Once devices care must be taken to write into
153  * into empty space.  If owWrite is used to write over an unlocked
154  * page on a Write-Once device it will fail.
155  *
156  * bank        to tell what memory bank of the ibutton to use.
157  * portnum     the port number of the port being used for the
158  *             1-Wire Network.
159  * SNum        the serial number for the part that the read is
160  *             to be done on.
161  * str_add     starting address
162  * buff        data to write
163  * len         length in bytes to write
164  */
owWrite(SMALLINT bank,int portnum,uchar * SNum,int str_add,uchar * buff,int len)165 SMALLINT owWrite(SMALLINT bank, int portnum, uchar *SNum, int str_add,
166                  uchar *buff, int len)
167 {
168    SMALLINT ret;
169 
170    switch(SNum[0])
171    {
172       case 0x14:  //EE Memory Bank and AppReg Memory Bank
173          if(bank > 0)
174             ret = writeEE(bank,portnum,SNum,str_add,buff,len);
175          else if(bank == 0)
176             ret = writeAppReg(bank,portnum,SNum,str_add,buff,len);
177          break;
178 
179       case 0x04: case 0x06: case 0x08: case 0x0A:
180       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
181          if(bank > 0)
182             ret = writeNV(bank,portnum,SNum,str_add,buff,len);
183          else if(bank == 0)
184             ret = writeScratch(bank,portnum,SNum,str_add,buff,len);
185          break;
186 
187       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
188          if(bank > 0)
189             ret = writeNV(bank,portnum,SNum,str_add,buff,len);
190          else if(bank == 0)
191             ret = writeScratch(bank,portnum,SNum,str_add,buff,len);
192          break;
193 
194       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
195          if(bank > 0)
196             ret = writeNV(bank,portnum,SNum,str_add,buff,len);
197          else if(bank == 0)
198             ret = writeScratch(bank,portnum,SNum,str_add,buff,len);
199          break;
200 
201       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
202          if(bank > 0)
203             ret = writeNV(bank,portnum,SNum,str_add,buff,len);
204          else if(bank == 0)
205             ret = writeScratch(bank,portnum,SNum,str_add,buff,len);
206          break;
207 
208       case 0x33: case 0xB3:  //SHAEE Memory Bank
209          ret = writeSHAEE(bank,portnum,SNum,str_add,buff,len);
210          break;
211 
212       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
213          ret = writeEPROM(bank,portnum,SNum,str_add,buff,len);
214          break;
215 
216       default:
217          break;
218    }
219 
220    return ret;
221 }
222 
223 /**
224  * Reads a page in this memory bank with no
225  * CRC checking (device or data). The resulting data from this API
226  * may or may not be what is on the 1-Wire device.  It is recommends
227  * that the data contain some kind of checking (CRC) like in the
228  * owReadPagePacket function or have the 1-Wire device provide the
229  * CRC as in owReadPageCRC.
230  * However device CRC generation is not
231  * supported on all memory types, see owHasPageAutoCRC}.
232  * If neither is an option then this method could be called more
233  * then once to at least verify that the same data is read consistently.
234  *
235  * The readContinue parameter is used to eliminate the overhead in re-accessing
236  * a part already being read from. For example, if pages 0 - 4 are to
237  * be read, readContinue would be set to false for page 0 and would be set
238  * to true for the next four calls.
239  * Note: Using readContinue = true  can only be used if the new
240  *       read continues where the last one left off
241  *       and it is inside a 'beginExclusive/endExclusive'
242  *       block.
243  *
244  * bank       to tell what memory bank of the ibutton to use.
245  * portnum    the port number of the port being used for the
246  *            1-Wire Network.
247  * SNum       the serial number for the part that the read is
248  *            to be done on.
249  * page       page number to read packet from
250  * rd_cont    true, then device read
251  *            is continued without re-selecting
252  * buff       location for data read
253  */
owReadPage(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff)254 SMALLINT owReadPage(SMALLINT bank, int portnum, uchar *SNum, int page,
255                     SMALLINT rd_cont, uchar *buff)
256 {
257    SMALLINT ret = 0;
258 
259    switch(SNum[0])
260    {
261       case 0x14:  //EE Memory Bank and AppReg Memory Bank
262          if(bank > 0)
263             ret = readPageEE(bank,portnum,SNum,page,rd_cont,buff);
264          else if(bank == 0)
265             ret = readPageAppReg(bank,portnum,SNum,page,rd_cont,buff);
266          break;
267 
268       case 0x04: case 0x06: case 0x08: case 0x0A:
269       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
270          if(bank > 0)
271             ret = readPageNV(bank,portnum,SNum,page,rd_cont,buff);
272          else if(bank == 0)
273             ret = readPageScratch(bank,portnum,SNum,page,rd_cont,buff);
274          break;
275 
276       case (0x18):  //NV Memory Bank and Scratch SHA Memory Bank
277          if(bank == 3)
278             ret = readPageNV(bank,portnum,SNum,page,rd_cont,buff);
279          else if(bank > 0)
280             ret = readPageNVCRC(bank,portnum,SNum,page,rd_cont,buff);
281          else if(bank == 0)
282             ret = readPageScratch(bank,portnum,SNum,page,rd_cont,buff);
283          break;
284 
285       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
286          if(bank > 0)
287             ret = readPageNVCRC(bank,portnum,SNum,page,rd_cont,buff);
288          else if(bank == 0)
289             ret = readPageScratch(bank,portnum,SNum,page,rd_cont,buff);
290          break;
291 
292       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
293          if(bank > 0)
294             ret = readPageNVCRC(bank,portnum,SNum,page,rd_cont,buff);
295          else if(bank == 0)
296             ret = readPageScratch(bank,portnum,SNum,page,rd_cont,buff);
297          break;
298 
299       case 0x33: case 0xB3:  //SHAEE Memory Bank
300          ret = readPageSHAEE(bank,portnum,SNum,page,rd_cont,buff);
301          break;
302 
303       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
304          ret = readPageEPROM(bank,portnum,SNum,page,rd_cont,buff);
305          break;
306 
307       default:
308          break;
309    }
310 
311    return ret;
312 }
313 
314 /**
315  * Reads a page in this memory bank with extra information with no
316  * CRC checking (device or data). The resulting data from this API
317  * may or may not be what is on the 1-Wire device.  It is recommends
318  * that the data contain some kind of checking (CRC) like in the
319  * owReadPagePacket function or have the 1-Wire device provide the
320  * CRC as in owReadPageCRC}.
321  * However device CRC generation is not
322  * supported on all memory types, see owHasPageAutoCRC}.
323  * If neither is an option then this method could be called more
324  * then once to at least verify that the same data is read consistently.The
325  * readContinue parameter is used to eliminate the overhead in re-accessing
326  * a part already being read from. For example, if pages 0 - 4 are to
327  * be read, readContinue would be set to false for page 0 and would be set
328  * to true for the next four calls.
329  *
330  * Note: Using readContinue = true  can only be used if the new
331  *       read continues where the last one left off
332  *       and it is inside a 'beginExclusive/endExclusive'
333  *       block.
334  *
335  * bank       to tell what memory bank of the ibutton to use.
336  * portnum    the port number of the port being used for the
337  *            1-Wire Network.
338  * SNum       the serial number for the part that the read is
339  *            to be done on.
340  * page       page number to read packet from
341  * rd_cont    true  then device read
342  *            is continued without re-selecting
343  * buff       location for data read
344  * extra      location for extra info read
345  */
owReadPageExtra(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff,uchar * extra)346 SMALLINT owReadPageExtra(SMALLINT bank, int portnum, uchar *SNum, int page,
347                          SMALLINT rd_cont, uchar *buff, uchar *extra)
348 {
349    SMALLINT ret = 0;
350 
351    switch(SNum[0])
352    {
353       case 0x14:  //EE Memory Bank and AppReg Memory Bank
354          if(bank > 0)
355             ret = readPageExtraEE(bank,portnum,SNum,page,rd_cont,buff,extra);
356          else if(bank == 0)
357             ret = readPageExtraAppReg(bank,portnum,SNum,page,rd_cont,buff,extra);
358          break;
359 
360       case 0x04: case 0x06: case 0x08: case 0x0A:
361       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
362          if(bank > 0)
363             ret = readPageExtraNV(bank,portnum,SNum,page,rd_cont,buff,extra);
364          else if(bank == 0)
365             ret = readPageExtraScratch(bank,portnum,SNum,page,rd_cont,buff,extra);
366          break;
367 
368       case (0x18):  //NV Memory Bank and Scratch SHA Memory Bank
369          if(bank == 3)
370             ret = readPageExtraNV(bank,portnum,SNum,page,rd_cont,buff,extra);
371          else if(bank > 0)
372             ret = readPageExtraNVCRC(bank,portnum,SNum,page,rd_cont,buff,extra);
373          else if(bank == 0)
374             ret = readPageExtraScratch(bank,portnum,SNum,page,rd_cont,buff,extra);
375          break;
376 
377       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
378          if(bank > 0)
379             ret = readPageExtraNVCRC(bank,portnum,SNum,page,rd_cont,buff,extra);
380          else if(bank == 0)
381             ret = readPageExtraScratch(bank,portnum,SNum,page,rd_cont,buff,extra);
382          break;
383 
384       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
385          if(bank > 0)
386             ret = readPageExtraNVCRC(bank,portnum,SNum,page,rd_cont,buff,extra);
387          else if(bank == 0)
388             ret = readPageExtraScratch(bank,portnum,SNum,page,rd_cont,buff,extra);
389          break;
390 
391       case 0x33: case 0xB3:  //SHAEE Memory Bank
392          ret = readPageExtraSHAEE(bank,portnum,SNum,page,rd_cont,buff,extra);
393          break;
394 
395       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
396          ret = readPageExtraEPROM(bank,portnum,SNum,page,rd_cont,buff,extra);
397          break;
398 
399       default:
400          break;
401    }
402 
403    return ret;
404 }
405 
406 /**
407  * Reads a complete memory page with CRC verification provided by the
408  * device with extra information.  Not supported by all devices. The
409  * rd_Continue parameter is used to eliminate the overhead in re-accessing
410  * a part already being read from. For example, if pages 0 - 4 are to
411  * be read, readContinue would be set to false for page 0 and would be set
412  * to true for the next four calls.
413  *
414  * bank       to tell what memory bank of the ibutton to use.
415  * portnum    the port number of the port being used for the
416  *            1-Wire Network.
417  * SNum       the serial number for the part that the read is
418  *            to be done on.
419  * page       page number to read
420  * read_buff  location for data read
421  * extra      location for extra info read
422  */
owReadPageExtraCRC(SMALLINT bank,int portnum,uchar * SNum,int page,uchar * read_buff,uchar * extra)423 SMALLINT owReadPageExtraCRC(SMALLINT bank, int portnum, uchar *SNum, int page,
424                             uchar *read_buff, uchar *extra)
425 {
426    SMALLINT ret = 0;
427 
428    switch(SNum[0])
429    {
430       case 0x14:  //EE Memory Bank and AppReg Memory Bank
431          if(bank > 0)
432             ret = readPageExtraCRCEE(bank,portnum,SNum,page,read_buff,extra);
433          else if(bank == 0)
434             ret = readPageExtraCRCAppReg(bank,portnum,SNum,page,read_buff,extra);
435          break;
436 
437       case 0x04: case 0x06: case 0x08: case 0x0A:
438       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
439          if(bank > 0)
440             ret = readPageExtraCRCNV(bank,portnum,SNum,page,read_buff,extra);
441          else if(bank == 0)
442             ret = readPageExtraCRCScratch(bank,portnum,SNum,page,read_buff,extra);
443          break;
444 
445       case (0x18):  //NV Memory Bank and Scratch SHA Memory Bank
446          if(bank == 3)
447             ret = readPageExtraCRCNV(bank,portnum,SNum,page,read_buff,extra);
448          else if(bank > 0)
449             ret = readPageExtraCRCNVCRC(bank,portnum,SNum,page,read_buff,extra);
450          else if(bank == 0)
451             ret = readPageExtraCRCScratch(bank,portnum,SNum,page,read_buff,extra);
452          break;
453 
454       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
455          if(bank > 0)
456             ret = readPageExtraCRCNVCRC(bank,portnum,SNum,page,read_buff,extra);
457          else if(bank == 0)
458             ret = readPageExtraCRCScratch(bank,portnum,SNum,page,read_buff,extra);
459          break;
460 
461       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
462          if(bank > 0)
463             ret = readPageExtraCRCNVCRC(bank,portnum,SNum,page,read_buff,extra);
464          else if(bank == 0)
465             ret = readPageExtraCRCScratch(bank,portnum,SNum,page,read_buff,extra);
466          break;
467 
468       case 0x33: case 0xB3:  //SHAEE Memory Bank
469          ret = readPageExtraCRCSHAEE(bank,portnum,SNum,page,read_buff,extra);
470          break;
471 
472       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
473          ret = readPageExtraCRCEPROM(bank,portnum,SNum,page,read_buff,extra);
474          break;
475 
476       default:
477          break;
478    }
479 
480    return ret;
481 }
482 
483 
484 /**
485  * Reads a complete memory page with CRC verification provided by the
486  * device.  Not supported by all devices.  The
487  * readContinue parameter is used to eliminate the overhead in re-accessing
488  * a part already being read from. For example, if pages 0 - 4 are to
489  * be read, readContinue would be set to false for page 0 and would be set
490  * to true for the next four calls.
491  *
492  * bank       to tell what memory bank of the ibutton to use.
493  * portnum    the port number of the port being used for the
494  *            1-Wire Network.
495  * SNum       the serial number for the part that the read is
496  *            to be done on.
497  * page       page number to read
498  * buff       location for data read
499  */
owReadPageCRC(SMALLINT bank,int portnum,uchar * SNum,int page,uchar * buff)500 SMALLINT owReadPageCRC(SMALLINT bank, int portnum, uchar *SNum, int page, uchar *buff)
501 {
502    SMALLINT ret = 0;
503 
504    switch(SNum[0])
505    {
506       case 0x14:  //EE Memory Bank and AppReg Memory Bank
507          if(bank > 0)
508             ret = readPageCRCEE(bank,portnum,SNum,page,buff);
509          else if(bank == 0)
510             ret = readPageCRCAppReg(bank,portnum,SNum,page,buff);
511          break;
512 
513       case 0x04: case 0x06: case 0x08: case 0x0A:
514       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
515          if(bank > 0)
516             ret = readPageCRCNV(bank,portnum,SNum,page,buff);
517          else if(bank == 0)
518             ret = readPageCRCScratch(bank,portnum,SNum,page,buff);
519          break;
520 
521       case (0x18):  //NV Memory Bank and Scratch SHA Memory Bank
522          if(bank == 3)
523             ret = readPageCRCNV(bank,portnum,SNum,page,buff);
524          else if(bank > 0)
525             ret = readPageCRCNVCRC(bank,portnum,SNum,page,buff);
526          else if(bank == 0)
527             ret = readPageCRCScratch(bank,portnum,SNum,page,buff);
528          break;
529 
530       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
531          if(bank > 0)
532             ret = readPageCRCNVCRC(bank,portnum,SNum,page,buff);
533          else if(bank == 0)
534             ret = readPageCRCScratch(bank,portnum,SNum,page,buff);
535          break;
536 
537       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
538          if(bank > 0)
539             ret = readPageCRCNVCRC(bank,portnum,SNum,page,buff);
540          else if(bank == 0)
541             ret = readPageCRCScratch(bank,portnum,SNum,page,buff);
542          break;
543 
544       case 0x33: case 0xB3:  //SHAEE Memory Bank
545          ret = readPageCRCSHAEE(bank,portnum,SNum,page,buff);
546          break;
547 
548       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
549          ret = readPageCRCEPROM(bank,portnum,SNum,page,buff);
550          break;
551 
552       default:
553          break;
554    }
555 
556    return ret;
557 }
558 
559 /**
560  * Reads a Universal Data Packet.
561  *
562  * The Universal Data Packet always starts on page boundaries but
563  * can end anywhere in the page.  The structure specifies the length of
564  * data bytes not including the length byte and the CRC16 bytes.
565  * There is one length byte. The CRC16 is first initialized to
566  * the page number.  This provides a check to verify the page that
567  * was intended is being read.  The CRC16 is then calculated over
568  * the length and data bytes.  The CRC16 is then inverted and stored
569  * low byte first followed by the high byte.  The structure is
570  * used by this method to verify the data but only
571  * the data payload is returned. The
572  * readContinue parameter is used to eliminate the overhead in re-accessing
573  * a part already being read from. For example, if pages 0 - 4 are to
574  * be read, readContinue would be set to false for page 0 and would be set
575  * to true for the next four calls.
576  *
577  * See Dallas Semiconductor Application Note 114
578  * for details: http://www.dalsemi.com/datasheets/pdfs/app114.pdf
579  * http://www.dalsemi.com/datasheets/pdfs/app114.pdf
580  *
581  * <P> Note: Using rd_cont = true  can only be used if the new
582  *           read continues where the last one left off
583  *           and it is inside a 'beginExclusive/endExclusive'
584  *           block.
585  *
586  * bank       to tell what memory bank of the ibutton to use.
587  * portnum    the port number of the port being used for the
588  *            1-Wire Network.
589  * SNum       the serial number for the part that the read is
590  *            to be done on.
591  * page       page number to read packet from
592  * rd_cont    true then device read
593  *            is continued without re-selecting
594  * buff       location for data read
595  * len        the length of the data
596  */
owReadPagePacket(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff,int * len)597 SMALLINT owReadPagePacket(SMALLINT bank, int portnum, uchar *SNum, int page,
598                           SMALLINT rd_cont, uchar *buff, int *len)
599 {
600    SMALLINT ret = 0;
601 
602    switch(SNum[0])
603    {
604       case 0x14:  //EE Memory Bank and AppReg Memory Bank
605          if(bank > 0)
606             ret = readPagePacketEE(bank,portnum,SNum,page,rd_cont,buff,len);
607          else if(bank == 0)
608             ret = readPagePacketAppReg(bank,portnum,SNum,page,rd_cont,buff,len);
609          break;
610 
611       case 0x04: case 0x06: case 0x08: case 0x0A:
612       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
613          if(bank > 0)
614             ret = readPagePacketNV(bank,portnum,SNum,page,rd_cont,buff,len);
615          else if(bank == 0)
616             ret = readPagePacketScratch(bank,portnum,SNum,page,rd_cont,buff,len);
617          break;
618 
619       case (0x18):  //NV Memory Bank and Scratch SHA Memory Bank
620          if(bank > 0)
621             ret = readPagePacketNV(bank,portnum,SNum,page,rd_cont,buff,len);
622          else if(bank == 0)
623             ret = readPagePacketScratch(bank,portnum,SNum,page,rd_cont,buff,len);
624          break;
625 
626       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
627          if(bank > 0)
628             ret = readPagePacketNV(bank,portnum,SNum,page,rd_cont,buff,len);
629          else if(bank == 0)
630             ret = readPagePacketScratch(bank,portnum,SNum,page,rd_cont,buff,len);
631          break;
632 
633       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
634          if(bank > 0)
635             ret = readPagePacketNV(bank,portnum,SNum,page,rd_cont,buff,len);
636          else if(bank == 0)
637             ret = readPagePacketScratch(bank,portnum,SNum,page,rd_cont,buff,len);
638          break;
639 
640       case 0x33: case 0xB3:  //SHAEE Memory Bank
641          ret = readPagePacketSHAEE(bank,portnum,SNum,page,rd_cont,buff,len);
642          break;
643 
644       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
645          ret = readPagePacketEPROM(bank,portnum,SNum,page,rd_cont,buff,len);
646          break;
647 
648       default:
649          break;
650    }
651 
652    return ret;
653 }
654 
655 /**
656  * Reads a Universal Data Packet and extra information.  See the
657  * function owReadPagePacket}
658  * for a description of the packet structure.  The
659  * rd_cont parameter is used to eliminate the overhead in re-accessing
660  * a part already being read from. For example, if pages 0 - 4 are to
661  * be read, readContinue would be set to false for page 0 and would be set
662  * to true for the next four calls.
663  *
664  * Note: Using readContinue = true  can only be used if the new
665  *       read continues where the last one left off
666  *       and it is inside a 'beginExclusive/endExclusive'
667  *       block.
668  *
669  * bank       to tell what memory bank of the ibutton to use.
670  * portnum    the port number of the port being used for the
671  *            1-Wire Network.
672  * SNum       the serial number for the part that the read is
673  *            to be done on.
674  * page       page number to read packet from
675  * rd_cont    true then device read
676  *            is continued without re-selecting
677  * buff       location for data read
678  * len        the length of the data
679  * extra      location for extra info read
680  *
681  */
owReadPagePacketExtra(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff,int * len,uchar * extra)682 SMALLINT owReadPagePacketExtra(SMALLINT bank, int portnum, uchar *SNum, int page,
683                                SMALLINT rd_cont, uchar *buff, int *len, uchar *extra)
684 {
685    SMALLINT ret = 0;
686 
687    switch(SNum[0])
688    {
689       case 0x14:  //EE Memory Bank and AppReg Memory Bank
690          if(bank > 0)
691             ret = readPagePacketExtraEE(bank,portnum,SNum,page,rd_cont,buff,len,extra);
692          else if(bank == 0)
693             ret = readPagePacketExtraAppReg(bank,portnum,SNum,page,rd_cont,buff,len,extra);
694          break;
695 
696       case 0x04: case 0x06: case 0x08: case 0x0A:
697       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
698          if(bank > 0)
699             ret = readPagePacketExtraNV(bank,portnum,SNum,page,rd_cont,buff,len,extra);
700          else if(bank == 0)
701             ret = readPagePacketExtraScratch(bank,portnum,SNum,page,rd_cont,buff,len,extra);
702          break;
703 
704       case (0x18):  //NV Memory Bank and Scratch SHA Memory Bank
705          if(bank == 3)
706             ret = readPagePacketExtraNV(bank,portnum,SNum,page,rd_cont,buff,len,extra);
707          else if(bank > 0)
708             ret = readPagePacketExtraNVCRC(bank,portnum,SNum,page,rd_cont,buff,len,extra);
709          else if(bank == 0)
710             ret = readPagePacketExtraScratch(bank,portnum,SNum,page,rd_cont,buff,len,extra);
711          break;
712 
713       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
714          if(bank > 0)
715             ret = readPagePacketExtraNVCRC(bank,portnum,SNum,page,rd_cont,buff,len,extra);
716          else if(bank == 0)
717             ret = readPagePacketExtraScratch(bank,portnum,SNum,page,rd_cont,buff,len,extra);
718          break;
719 
720       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
721          if(bank > 0)
722             ret = readPagePacketExtraNVCRC(bank,portnum,SNum,page,rd_cont,buff,len,extra);
723          else if(bank == 0)
724             ret = readPagePacketExtraScratch(bank,portnum,SNum,page,rd_cont,buff,len,extra);
725          break;
726 
727       case 0x33: case 0xB3:  //SHAEE Memory Bank
728          ret = readPagePacketExtraSHAEE(bank,portnum,SNum,page,rd_cont,buff,len,extra);
729          break;
730 
731       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
732          ret = readPagePacketExtraEPROM(bank,portnum,SNum,page,rd_cont,buff,len,extra);
733          break;
734 
735       default:
736          break;
737    }
738 
739    return ret;
740 }
741 
742 /**
743  * Writes a Universal Data Packet.  See the funtion owReadPagePacket
744  * for a description of the packet structure.
745  *
746  * bank       to tell what memory bank of the ibutton to use.
747  * portnum    the port number of the port being used for the
748  *            1-Wire Network.
749  * SNum       the serial number for the part that the read is
750  *            to be done on.
751  * page       page number to write packet to
752  * buff       data to write
753  * len        number of bytes to write with a max of owGetMaxPacketDataLength
754  *            elements
755  */
owWritePagePacket(SMALLINT bank,int portnum,uchar * SNum,int page,uchar * buff,int len)756 SMALLINT owWritePagePacket(SMALLINT bank, int portnum, uchar *SNum, int page,
757                            uchar *buff, int len)
758 {
759    SMALLINT ret = 0;
760 
761    switch(SNum[0])
762    {
763       case 0x14:  //EE Memory Bank and AppReg Memory Bank
764          if(bank > 0)
765             ret = writePagePacketEE(bank,portnum,SNum,page,buff,len);
766          else if(bank == 0)
767             ret = writePagePacketAppReg(bank,portnum,SNum,page,buff,len);
768          break;
769 
770       case 0x04: case 0x06: case 0x08: case 0x0A:
771       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
772          if(bank > 0)
773             ret = writePagePacketNV(bank,portnum,SNum,page,buff,len);
774          else if(bank == 0)
775             ret = writePagePacketScratch(bank,portnum,SNum,page,buff,len);
776          break;
777 
778       case (0x18):  //NV Memory Bank and Scratch SHA Memory Bank
779          if(bank > 0)
780             ret = writePagePacketNV(bank,portnum,SNum,page,buff,len);
781          else if(bank == 0)
782             ret = writePagePacketScratch(bank,portnum,SNum,page,buff,len);
783          break;
784 
785       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
786          if(bank > 0)
787             ret = writePagePacketNV(bank,portnum,SNum,page,buff,len);
788          else if(bank == 0)
789             ret = writePagePacketScratch(bank,portnum,SNum,page,buff,len);
790          break;
791 
792       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
793          if(bank > 0)
794             ret = writePagePacketNV(bank,portnum,SNum,page,buff,len);
795          else if(bank == 0)
796             ret = writePagePacketScratch(bank,portnum,SNum,page,buff,len);
797          break;
798 
799       case 0x33: case 0xB3:  //SHAEE Memory Bank
800          ret = writePagePacketSHAEE(bank,portnum,SNum,page,buff,len);
801          break;
802 
803       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
804          ret = writePagePacketEPROM(bank,portnum,SNum,page,buff,len);
805          break;
806 
807       default:
808          break;
809    }
810 
811    return ret;
812 }
813 
814 /**
815  * Gets the number of banks for a certain button given it's family code.
816  *
817  * family     the family code
818  */
owGetNumberBanks(uchar family)819 SMALLINT owGetNumberBanks(uchar family)
820 {
821    SMALLINT ret = 0;
822 
823    switch(family)
824    {
825       case 0x14: case 0x04: case 0x06: case 0x08: case 0x0A:
826       case 0x0C: case 0x09: case 0x12: case 0x23:
827          ret = 2;
828          break;
829 
830       case 0x1A:
831          ret = 3;
832          break;
833 
834       case 0x33: case 0xB3: case 0x18: case 0x1D:
835          ret = 4;
836          break;
837 
838       case 0x0B: case 0x0F: case 0x13:
839          ret = 5;
840          break;
841 
842       case 0x21:
843          ret = 6;
844          break;
845 
846       default:
847          break;
848    }
849 
850    return ret;
851 }
852 
853 /**
854  * Gets the number of pages in this memory bank.
855  * The page numbers are then always 0 to (owGetNumberPages() - 1).
856  *
857  * bank       to tell what memory bank of the ibutton to use.
858  * SNum       the serial number for the part that the read is
859  *            to be done on.
860  *
861  * @return  number of pages in this memory bank
862  */
owGetNumberPages(SMALLINT bank,uchar * SNum)863 SMALLINT owGetNumberPages(SMALLINT bank, uchar *SNum)
864 {
865    SMALLINT ret = 0;
866 
867    switch(SNum[0])
868    {
869       case 0x14:  //EE Memory Bank and AppReg Memory Bank
870          if(bank > 0)
871             ret = getNumberPagesEE(bank,SNum);
872          else if(bank == 0)
873             ret = getNumberPagesAppReg(bank,SNum);
874          break;
875 
876       case 0x04: case 0x06: case 0x08: case 0x0A:
877       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
878          if(bank > 0)
879             ret = getNumberPagesNV(bank,SNum);
880          else if(bank == 0)
881             ret = getNumberPagesScratch(bank,SNum);
882          break;
883 
884       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
885          if(bank > 0)
886             ret = getNumberPagesNV(bank,SNum);
887          else if(bank == 0)
888             ret = getNumberPagesScratch(bank,SNum);
889          break;
890 
891       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
892          if(bank > 0)
893             ret = getNumberPagesNV(bank,SNum);
894          else if(bank == 0)
895             ret = getNumberPagesScratch(bank,SNum);
896          break;
897 
898       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
899          if(bank > 0)
900             ret = getNumberPagesNV(bank,SNum);
901          else if(bank == 0)
902             ret = getNumberPagesScratch(bank,SNum);
903          break;
904 
905       case 0x33: case 0xB3:  //SHAEE Memory Bank
906          ret = getNumberPagesSHAEE(bank,SNum);
907          break;
908 
909       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
910          ret = getNumberPagesEPROM(bank,SNum);
911          break;
912 
913       default:
914          break;
915    }
916 
917    return ret;
918 }
919 
920 /**
921  * Gets the size of this memory bank in bytes.
922  *
923  * bank       to tell what memory bank of the ibutton to use.
924  * SNum       the serial number for the part that the read is
925  *            to be done on.
926  *
927  * @return  number of bytes in current memory bank
928  */
owGetSize(SMALLINT bank,uchar * SNum)929 int owGetSize(SMALLINT bank, uchar *SNum)
930 {
931    int ret = 0;
932 
933    switch(SNum[0])
934    {
935       case 0x14:  //EE Memory Bank and AppReg Memory Bank
936          if(bank > 0)
937             ret = getSizeEE(bank,SNum);
938          else if(bank == 0)
939             ret = getSizeAppReg(bank,SNum);
940          break;
941 
942       case 0x04: case 0x06: case 0x08: case 0x0A:
943       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
944          if(bank > 0)
945             ret = getSizeNV(bank,SNum);
946          else if(bank == 0)
947             ret = getSizeScratch(bank,SNum);
948          break;
949 
950       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
951          if(bank > 0)
952             ret = getSizeNV(bank,SNum);
953          else if(bank == 0)
954             ret = getSizeScratch(bank,SNum);
955          break;
956 
957       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
958          if(bank > 0)
959             ret = getSizeNV(bank,SNum);
960          else if(bank == 0)
961             ret = getSizeScratch(bank,SNum);
962          break;
963 
964       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
965          if(bank > 0)
966             ret = getSizeNV(bank,SNum);
967          else if(bank == 0)
968             ret = getSizeScratch(bank,SNum);
969          break;
970 
971       case 0x33: case 0xB3:  //SHAEE Memory Bank
972          ret = getSizeSHAEE(bank,SNum);
973          break;
974 
975       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
976          ret = getSizeEPROM(bank,SNum);
977          break;
978 
979       default:
980          break;
981    }
982 
983    return ret;
984 }
985 
986 /**
987  * Gets raw page length in bytes in this memory bank.
988  *
989  * bank       to tell what memory bank of the ibutton to use.
990  * SNum       the serial number for the part that the read is
991  *            to be done on.
992  *
993  * @return   page length in bytes in this memory bank
994  */
owGetPageLength(SMALLINT bank,uchar * SNum)995 SMALLINT owGetPageLength(SMALLINT bank, uchar *SNum)
996 {
997    SMALLINT ret = 0;
998 
999    switch(SNum[0])
1000    {
1001       case 0x14:  // EE Memory Bank and AppReg Memory Bank
1002          if(bank > 0)
1003             ret = getPageLengthEE(bank,SNum);
1004          else if(bank == 0)
1005             ret = getPageLengthAppReg(bank,SNum);
1006          break;
1007 
1008       case 0x04: case 0x06: case 0x08: case 0x0A:
1009       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
1010          if(bank > 0)
1011             ret = getPageLengthNV(bank,SNum);
1012          else if(bank == 0)
1013             ret = getPageLengthScratch(bank,SNum);
1014          break;
1015 
1016       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
1017          if(bank > 0)
1018             ret = getPageLengthNV(bank,SNum);
1019          else if(bank == 0)
1020             ret = getPageLengthScratch(bank,SNum);
1021          break;
1022 
1023       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
1024          if(bank > 0)
1025             ret = getPageLengthNV(bank,SNum);
1026          else if(bank == 0)
1027             ret = getPageLengthScratch(bank,SNum);
1028          break;
1029 
1030       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
1031          if(bank > 0)
1032             ret = getPageLengthNV(bank,SNum);
1033          else if(bank == 0)
1034             ret = getPageLengthScratch(bank,SNum);
1035          break;
1036 
1037       case 0x33: case 0xB3:  //SHAEE Memory Bank
1038          ret = getPageLengthSHAEE(bank,SNum);
1039          break;
1040 
1041       case 0x09: case 0x0B: case 0x0F:
1042       case 0x12: case 0x13:
1043          ret = getPageLengthEPROM(bank,SNum);
1044          break;
1045 
1046       default:
1047          break;
1048    }
1049 
1050    return ret;
1051 }
1052 
1053 /**
1054  * Gets the starting physical address of this bank.  Physical
1055  * banks are sometimes sub-divided into logical banks due to changes
1056  * in attributes.  Note that this method is for information only.  The read
1057  * and write methods will automatically calculate the physical address
1058  * when writing to a logical memory bank.
1059  *
1060  * bank       to tell what memory bank of the ibutton to use.
1061  * SNum       the serial number for the part that the read is
1062  *            to be done on.
1063  *
1064  * @return  physical starting address of this logical bank
1065  */
owGetStartingAddress(SMALLINT bank,uchar * SNum)1066 int owGetStartingAddress(SMALLINT bank, uchar *SNum)
1067 {
1068    int ret = 0;
1069 
1070    switch(SNum[0])
1071    {
1072       case 0x14:  //EE Memory Bank and AppReg Memory Bank
1073          if(bank > 0)
1074             ret = getStartingAddressEE(bank,SNum);
1075          else if(bank == 0)
1076             ret = getStartingAddressAppReg(bank,SNum);
1077          break;
1078 
1079       case 0x04: case 0x06: case 0x08: case 0x0A:
1080       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
1081          if(bank > 0)
1082             ret = getStartingAddressNV(bank,SNum);
1083          else if(bank == 0)
1084             ret = getStartingAddressScratch(bank,SNum);
1085          break;
1086 
1087       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
1088          if(bank > 0)
1089             ret = getStartingAddressNV(bank,SNum);
1090          else if(bank == 0)
1091             ret = getStartingAddressScratch(bank,SNum);
1092          break;
1093 
1094       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
1095          if(bank > 0)
1096             ret = getStartingAddressNV(bank,SNum);
1097          else if(bank == 0)
1098             ret = getStartingAddressScratch(bank,SNum);
1099          break;
1100 
1101       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
1102          if(bank > 0)
1103             ret = getStartingAddressNV(bank,SNum);
1104          else if(bank == 0)
1105             ret = getStartingAddressScratch(bank,SNum);
1106          break;
1107 
1108       case 0x33: case 0xB3:  //SHAEE Memory Bank
1109          ret = getStartingAddressSHAEE(bank,SNum);
1110          break;
1111 
1112       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
1113          ret = getStartingAddressEPROM(bank,SNum);
1114          break;
1115 
1116       default:
1117          break;
1118    }
1119 
1120    return ret;
1121 }
1122 
1123 /**
1124  * Gets a string description of this memory bank.
1125  *
1126  * bank       to tell what memory bank of the ibutton to use.
1127  * SNum       the serial number for the part that the read is
1128  *            to be done on.
1129  *
1130  * @return  the memory bank description
1131  */
owGetBankDescription(SMALLINT bank,uchar * SNum)1132 char *owGetBankDescription(SMALLINT bank, uchar *SNum)
1133 {
1134    switch(SNum[0])
1135    {
1136       case 0x14:  //EE Memory Bank and AppReg Memory Bank
1137          if(bank > 0)
1138             return getBankDescriptionEE(bank,SNum);
1139          else if(bank == 0)
1140             return getBankDescriptionAppReg(bank,SNum);
1141          break;
1142 
1143       case 0x04: case 0x06: case 0x08: case 0x0A:
1144       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
1145          if(bank > 0)
1146             return getBankDescriptionNV(bank,SNum);
1147          else if(bank == 0)
1148             return getBankDescriptionScratch(bank,SNum);
1149          break;
1150 
1151       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
1152          if(bank > 0)
1153             return getBankDescriptionNV(bank,SNum);
1154          else if(bank == 0)
1155             return getBankDescriptionScratch(bank,SNum);
1156          break;
1157 
1158       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
1159          if(bank > 0)
1160             return getBankDescriptionNV(bank,SNum);
1161          else if(bank == 0)
1162             return getBankDescriptionScratch(bank,SNum);
1163          break;
1164 
1165       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
1166          if(bank > 0)
1167             return getBankDescriptionNV(bank,SNum);
1168          else if(bank == 0)
1169             return getBankDescriptionScratch(bank,SNum);
1170          break;
1171 
1172       case 0x33: case 0xB3:  //SHAEE Memory Bank
1173          return getBankDescriptionSHAEE(bank,SNum);
1174          break;
1175 
1176       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
1177          return getBankDescriptionEPROM(bank,SNum);
1178          break;
1179 
1180       default:
1181          break;
1182    }
1183 
1184    return "";
1185 }
1186 
1187 /**
1188  * Retrieves the Dallas Semiconductor part number of the 1-Wire device
1189  * as a String.  For example 'Crypto iButton' or 'DS1992'.
1190  *
1191  * SNum       the serial number for the part that the read is
1192  *            to be done on.
1193  *
1194  * @return 1-Wire device name
1195  */
owGetName(uchar * SNum)1196 char *owGetName(uchar *SNum)
1197 {
1198    switch(SNum[0])
1199    {
1200       case 0x14:
1201          return "DS1971";
1202          break;
1203 
1204       case 0x04:
1205          return "DS1994";
1206          break;
1207 
1208       case 0x06:
1209          return "DS1993";
1210          break;
1211 
1212       case 0x08:
1213          return "DS1992";
1214          break;
1215 
1216       case 0x09:
1217          return "DS1982";
1218          break;
1219 
1220       case 0x0A:
1221          return "DS1995";
1222          break;
1223 
1224       case 0x0B:
1225          return "DS1985";
1226          break;
1227 
1228       case 0x0C:
1229          return "DS1996";
1230          break;
1231 
1232       case 0x18:
1233          return "DS1963S";
1234          break;
1235 
1236       case 0x1A:
1237          return "DS1963L";
1238          break;
1239 
1240       case 0x1D:
1241          return "DS2423";
1242          break;
1243 
1244       case 0x23:
1245          return "DS1973";
1246          break;
1247 
1248       case 0x33: case 0xB3:
1249          return "DS1961S";
1250          break;
1251 
1252       default:
1253          return "No Name";
1254    }
1255 
1256    return " ";
1257 }
1258 
1259 /**
1260  * Retrieves the alternate Dallas Semiconductor part numbers or names.
1261  * A 'family' of 1-Wire Network devices may have more than one part number
1262  * depending on packaging.  There can also be nicknames such as
1263  * 'Crypto iButton'.
1264  *
1265  * SNum       the serial number for the part that the read is
1266  *            to be done on.
1267  *
1268  * @return 1-Wire device alternate names
1269  */
owGetAlternateName(uchar * SNum)1270 char *owGetAlternateName(uchar *SNum)
1271 {
1272    switch(SNum[0])
1273    {
1274       case 0x14:
1275          return "DS2430A";
1276          break;
1277 
1278       case 0x04:
1279          return "DS2404, Time-in-a-can, DS1427";
1280          break;
1281 
1282       case 0x09:
1283          return "DS2502";
1284          break;
1285 
1286       case 0x0B:
1287          return "DS2505";
1288          break;
1289 
1290       case 0x18:
1291          return "SHA-1 iButton";
1292          break;
1293 
1294       case 0x1A:
1295          return "Monetary iButton";
1296          break;
1297 
1298       case 0x23:
1299          return "DS2433";
1300          break;
1301 
1302       case 0x33: case 0xB3:
1303          return "DS2432";
1304          break;
1305 
1306       default:
1307          return "No Alternate Name";
1308    }
1309 
1310    return " ";
1311 }
1312 
1313 /**
1314  * Retrieves a short description of the function of the 1-Wire device type.
1315  *
1316  * SNum       the serial number for the part that the read is
1317  *            to be done on.
1318  *
1319  * @return device functional description
1320  */
owGetDescription(uchar * SNum)1321 char *owGetDescription(uchar *SNum)
1322 {
1323    switch(SNum[0])
1324    {
1325       case 0x14:
1326          return "Electrically Erasable Programmable Read Only Memory\n"
1327                 "*\t(EEPROM) organized as one page of 256 bits and 64 bit\n"
1328                 "*\tone-time programmable application register.";
1329          break;
1330 
1331       case 0x04:
1332          return "4096 bit read/write nonvolatile memory partitioned\n"
1333                 "*\tinto sixteen pages of 256 bits each and a real\n"
1334                 "*\ttime clock/calendar in binary format.";
1335          break;
1336 
1337       case 0x06:
1338          return "4096 bit read/write nonvolatile memory partitioned\n"
1339                 "*\tinto sixteen pages of 256 bits each.";
1340          break;
1341 
1342       case 0x08:
1343          return "1024 bit read/write nonvolatile memory partitioned\n"
1344                 "*\tinto four pages of 256 bits each.";
1345          break;
1346 
1347       case 0x09:
1348          return "1024 bit Electrically Programmable Read Only Memory\n"
1349                 "*\t(EPROM) partitioned into four 256 bit pages.\n"
1350                 "*\tEach memory page can be permanently write-protected\n"
1351                 "*\tto prevent tampering.  Architecture allows software\n"
1352                 "*\tto patch data by supersending a used page in favor of\n"
1353                 "*\ta newly programmed page.";
1354          break;
1355 
1356       case 0x0A:
1357          return "16384 bit read/write nonvolatile memory partitioned\n"
1358                 "*\tinto sixty-four pages of 256 bits each.";
1359          break;
1360 
1361       case 0x0B:
1362          return "16384 bit Electrically Programmable Read Only Memory\n"
1363                 "*\t(EPROM) partitioned into sixty-four 256 bit pages.\n"
1364                 "*\tEach memory page can be permanently write-protected\n"
1365                 "*\tto prevent tampering.  Architecture allows software\n"
1366                 "*\tto patch data by supersending a used page in favor of\n"
1367                 "*\ta newly programmed page.\n";
1368          break;
1369 
1370       case 0x0C:
1371          return "65536 bit read/write nonvolatile memory partitioned\n"
1372                 "*\tinto two-hundred fifty-six pages of 256 bits each.";
1373          break;
1374 
1375       case 0x18:
1376          return "4096 bits of read/write nonvolatile memory. Memory\n"
1377                 "*\tis partitioned into sixteen pages of 256 bits each.\n"
1378                 "*\tHas overdrive mode.  One-chip 512-bit SHA-1 engine\n"
1379                 "*\tand secret storage.\n";
1380          break;
1381 
1382       case 0x1A:
1383          return "4096 bit read/write nonvolatile memory with\n"
1384                 "*\tfour 32-bit read-only non rolling-over page write\n"
1385                 "*\tcycle counters and tamper-detect bits for small\n"
1386                 "*\tmoney storage.\n";
1387          break;
1388 
1389       case 0x1D:
1390          return "1-Wire counter with 4096 bits of read/write, nonvolatile\n"
1391                 "*\tmemory.  Memory is partitioned into sixteen pages of 256\n"
1392                 "*\tbits each.  256 bit scratchpad ensures data transfer\n"
1393                 "*\tintegrity.  Has overdrive mode.  Last four pages each have\n"
1394                 "*\t32 bit read-only non rolling-over counter.  The first two\n"
1395                 "*\tcounters increment on a page write cycle and the second two\n"
1396                 "*\thave active-low external triggers.\n";
1397          break;
1398 
1399       case 0x23:
1400          return "4096 bit Electrically Erasable Programmable Read\n"
1401                 "*\tOnly Memory (EEPROM) organized as sixteen pages of 256 bits.";
1402          break;
1403 
1404       case 0x33: case 0xB3:
1405          return "1K-Bit protected 1-Wire EEPROM with SHA-1 Engine.";
1406          break;
1407 
1408       default:
1409          return "No given description";
1410    }
1411 
1412    return " ";
1413 }
1414 
1415 /**
1416  * Checks to see if this memory bank is general purpose
1417  * user memory.  If it is NOT then it may be Memory-Mapped and writing
1418  * values to this memory may affect the behavior of the 1-Wire
1419  * device.
1420  *
1421  * bank       to tell what memory bank of the ibutton to use.
1422  * SNum       the serial number for the part that the read is
1423  *            to be done on.
1424  *
1425  * @return  true if this memory bank is general purpose
1426  */
owIsGeneralPurposeMemory(SMALLINT bank,uchar * SNum)1427 SMALLINT owIsGeneralPurposeMemory(SMALLINT bank, uchar *SNum)
1428 {
1429    SMALLINT ret = 0;
1430 
1431    switch(SNum[0])
1432    {
1433       case 0x14:  //EE Memory Bank and AppReg Memory Bank
1434          if(bank > 0)
1435             ret = isGeneralPurposeMemoryEE(bank,SNum);
1436          else if(bank == 0)
1437             ret = isGeneralPurposeMemoryAppReg(bank,SNum);
1438          break;
1439 
1440       case 0x04: case 0x06: case 0x08: case 0x0A:
1441       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
1442          if(bank > 0)
1443             ret = isGeneralPurposeMemoryNV(bank,SNum);
1444          else if(bank == 0)
1445             ret = isGeneralPurposeMemoryScratch(bank,SNum);
1446          break;
1447 
1448       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
1449          if(bank > 0)
1450             ret = isGeneralPurposeMemoryNV(bank,SNum);
1451          else if(bank == 0)
1452             ret = isGeneralPurposeMemoryScratch(bank,SNum);
1453          break;
1454 
1455       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
1456          if(bank > 0)
1457             ret = isGeneralPurposeMemoryNV(bank,SNum);
1458          else if(bank == 0)
1459             ret = isGeneralPurposeMemoryScratch(bank,SNum);
1460          break;
1461 
1462       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
1463          if(bank > 0)
1464             ret = isGeneralPurposeMemoryNV(bank,SNum);
1465          else if(bank == 0)
1466             ret = isGeneralPurposeMemoryScratch(bank,SNum);
1467          break;
1468 
1469       case 0x33: case 0xB3:  //SHAEE Memory Bank
1470          ret = isGeneralPurposeMemorySHAEE(bank,SNum);
1471          break;
1472 
1473       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
1474          ret = isGeneralPurposeMemoryEPROM(bank,SNum);
1475          break;
1476 
1477       default:
1478          break;
1479    }
1480 
1481    return ret;
1482 }
1483 
1484 /**
1485  * Checks to see if this memory bank is read/write.
1486  *
1487  * bank       to tell what memory bank of the ibutton to use.
1488  * SNum       the serial number for the part that the read is
1489  *            to be done on.
1490  *
1491  * @return    true if this memory bank is read/write
1492  */
owIsReadWrite(SMALLINT bank,int portnum,uchar * SNum)1493 SMALLINT owIsReadWrite(SMALLINT bank, int portnum, uchar *SNum)
1494 {
1495    SMALLINT ret = 0;
1496 
1497    switch(SNum[0])
1498    {
1499       case 0x14:  //EE Memory Bank and AppReg Memory Bank
1500          if(bank > 0)
1501             ret = isReadWriteEE(bank,portnum,SNum);
1502          else if(bank == 0)
1503             ret = isReadWriteAppReg(bank,portnum,SNum);
1504          break;
1505 
1506       case 0x04: case 0x06: case 0x08: case 0x0A:
1507       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
1508          if(bank > 0)
1509             ret = isReadWriteNV(bank,portnum,SNum);
1510          else if(bank == 0)
1511             ret = isReadWriteScratch(bank,portnum,SNum);
1512          break;
1513 
1514       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
1515          if(bank > 0)
1516             ret = isReadWriteNV(bank,portnum,SNum);
1517          else if(bank == 0)
1518             ret = isReadWriteScratch(bank,portnum,SNum);
1519          break;
1520 
1521       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
1522          if(bank > 0)
1523             ret = isReadWriteNV(bank,portnum,SNum);
1524          else if(bank == 0)
1525             ret = isReadWriteScratch(bank,portnum,SNum);
1526          break;
1527 
1528       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
1529          if(bank > 0)
1530             ret = isReadWriteNV(bank,portnum,SNum);
1531          else if(bank == 0)
1532             ret = isReadWriteScratch(bank,portnum,SNum);
1533          break;
1534 
1535       case 0x33: case 0xB3:  //SHAEE Memory Bank
1536          ret = isReadWriteSHAEE(bank,portnum,SNum);
1537          break;
1538 
1539       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
1540          ret = isReadWriteEPROM(bank,portnum,SNum);
1541          break;
1542 
1543       default:
1544          break;
1545    }
1546 
1547    return ret;
1548 }
1549 
1550 /**
1551  * Checks to see if this memory bank is write once such
1552  * as with EPROM technology.
1553  *
1554  * bank       to tell what memory bank of the ibutton to use.
1555  * SNum       the serial number for the part that the read is
1556  *            to be done on.
1557  *
1558  * @return    true if this memory bank can only be written once
1559  */
owIsWriteOnce(SMALLINT bank,int portnum,uchar * SNum)1560 SMALLINT owIsWriteOnce(SMALLINT bank, int portnum, uchar *SNum)
1561 {
1562    SMALLINT ret = 0;
1563 
1564    switch(SNum[0])
1565    {
1566       case 0x14:  //EE Memory Bank and AppReg Memory Bank
1567          if(bank > 0)
1568             ret = isWriteOnceEE(bank,portnum,SNum);
1569          else if(bank == 0)
1570             ret = isWriteOnceAppReg(bank,portnum,SNum);
1571          break;
1572 
1573       case 0x04: case 0x06: case 0x08: case 0x0A:
1574       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
1575          if(bank > 0)
1576             ret = isWriteOnceNV(bank,portnum,SNum);
1577          else if(bank == 0)
1578             ret = isWriteOnceScratch(bank,portnum,SNum);
1579          break;
1580 
1581       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
1582          if(bank > 0)
1583             ret = isWriteOnceNV(bank,portnum,SNum);
1584          else if(bank == 0)
1585             ret = isWriteOnceScratch(bank,portnum,SNum);
1586          break;
1587 
1588       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
1589          if(bank > 0)
1590             ret = isWriteOnceNV(bank,portnum,SNum);
1591          else if(bank == 0)
1592             ret = isWriteOnceScratch(bank,portnum,SNum);
1593          break;
1594 
1595       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
1596          if(bank > 0)
1597             ret = isWriteOnceNV(bank,portnum,SNum);
1598          else if(bank == 0)
1599             ret = isWriteOnceScratch(bank,portnum,SNum);
1600          break;
1601 
1602       case 0x33: case 0xB3:  //SHAEE Memory Bank
1603          ret = isWriteOnceSHAEE(bank,portnum,SNum);
1604          break;
1605 
1606       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
1607          ret = isWriteOnceEPROM(bank,portnum,SNum);
1608          break;
1609 
1610       default:
1611          break;
1612    }
1613 
1614    return ret;
1615 }
1616 
1617 /**
1618  * Query to see if current memory bank is read only.
1619  *
1620  * bank       to tell what memory bank of the ibutton to use.
1621  * SNum       the serial number for the part that the read is
1622  *            to be done on.
1623  *
1624  * @return    true if current memory bank can only be read
1625  */
owIsReadOnly(SMALLINT bank,int portnum,uchar * SNum)1626 SMALLINT owIsReadOnly(SMALLINT bank, int portnum, uchar *SNum)
1627 {
1628    SMALLINT ret = 0;
1629 
1630    switch(SNum[0])
1631    {
1632       case 0x14:  //EE Memory Bank and AppReg Memory Bank
1633          if(bank > 0)
1634             ret = isReadOnlyEE(bank,portnum,SNum);
1635          else if(bank == 0)
1636             ret = isReadOnlyAppReg(bank,portnum,SNum);
1637          break;
1638 
1639       case 0x04: case 0x06: case 0x08: case 0x0A:
1640       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
1641          if(bank > 0)
1642             ret = isReadOnlyNV(bank,portnum,SNum);
1643          else if(bank == 0)
1644             ret = isReadOnlyScratch(bank,portnum,SNum);
1645          break;
1646 
1647       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
1648          if(bank > 0)
1649             ret = isReadOnlyNV(bank,portnum,SNum);
1650          else if(bank == 0)
1651             ret = isReadOnlyScratch(bank,portnum,SNum);
1652          break;
1653 
1654       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
1655          if(bank > 0)
1656             ret = isReadOnlyNV(bank,portnum,SNum);
1657          else if(bank == 0)
1658             ret = isReadOnlyScratch(bank,portnum,SNum);
1659          break;
1660 
1661       case 0x33: case 0xB3:  //SHAEE Memory Bank
1662          ret = isReadOnlySHAEE(bank,portnum,SNum);
1663          break;
1664 
1665       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
1666          ret = isReadOnlyEPROM(bank,portnum,SNum);
1667          break;
1668 
1669       default:
1670          break;
1671    }
1672 
1673    return ret;
1674 }
1675 
1676 /**
1677  * Query to see if current memory bank non-volatile.  Memory is
1678  * non-volatile if it retains its contents even when removed from
1679  * the 1-Wire network.
1680  *
1681  * bank       to tell what memory bank of the ibutton to use.
1682  * SNum       the serial number for the part that the read is
1683  *            to be done on.
1684  *
1685  * @return    true if current memory bank non volatile.
1686  */
owIsNonVolatile(SMALLINT bank,uchar * SNum)1687 SMALLINT owIsNonVolatile(SMALLINT bank, uchar *SNum)
1688 {
1689    SMALLINT ret = 0;
1690 
1691    switch(SNum[0])
1692    {
1693       case 0x14:  //EE Memory Bank and AppReg Memory Bank
1694          if(bank > 0)
1695             ret = isNonVolatileEE(bank,SNum);
1696          else if(bank == 0)
1697             ret = isNonVolatileAppReg(bank,SNum);
1698          break;
1699 
1700       case 0x04: case 0x06: case 0x08: case 0x0A:
1701       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
1702          if(bank > 0)
1703             ret = isNonVolatileNV(bank,SNum);
1704          else if(bank == 0)
1705             ret = isNonVolatileScratch(bank,SNum);
1706          break;
1707 
1708       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
1709          if(bank > 0)
1710             ret = isNonVolatileNV(bank,SNum);
1711          else if(bank == 0)
1712             ret = isNonVolatileScratch(bank,SNum);
1713          break;
1714 
1715       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
1716          if(bank > 0)
1717             ret = isNonVolatileNV(bank,SNum);
1718          else if(bank == 0)
1719             ret = isNonVolatileScratch(bank,SNum);
1720          break;
1721 
1722       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
1723          if(bank > 0)
1724             ret = isNonVolatileNV(bank,SNum);
1725          else if(bank == 0)
1726             ret = isNonVolatileScratch(bank,SNum);
1727          break;
1728 
1729       case 0x33: //SHAEE Memory Bank  //SHAEE Memory Bank
1730          ret = isNonVolatileSHAEE(bank,SNum);
1731          break;
1732 
1733       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
1734          ret = isNonVolatileEPROM(bank,SNum);
1735          break;
1736 
1737       default:
1738          break;
1739    }
1740 
1741    return ret;
1742 }
1743 
1744 /**
1745  * Checks to see if this  memory bank requires a
1746  * 'ProgramPulse' in order to write.
1747  *
1748  * bank       to tell what memory bank of the ibutton to use.
1749  * SNum       the serial number for the part that the read is
1750  *            to be done on.
1751  *
1752  * @return    true if writing to this memory bank
1753  *            requires a 'ProgramPulse' from the 1-Wire Adapter.
1754  */
owNeedsProgramPulse(SMALLINT bank,uchar * SNum)1755 SMALLINT owNeedsProgramPulse(SMALLINT bank, uchar *SNum)
1756 {
1757    SMALLINT ret = 0;
1758 
1759    switch(SNum[0])
1760    {
1761       case 0x14:  //EE Memory Bank and AppReg Memory Bank
1762          if(bank > 0)
1763             ret = needsProgramPulseEE(bank,SNum);
1764          else if(bank == 0)
1765             ret = needsProgramPulseAppReg(bank,SNum);
1766          break;
1767 
1768       case 0x04: case 0x06: case 0x08: case 0x0A:
1769       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
1770          if(bank > 0)
1771             ret = needsProgramPulseNV(bank,SNum);
1772          else if(bank == 0)
1773             ret = needsProgramPulseScratch(bank,SNum);
1774          break;
1775 
1776       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
1777          if(bank > 0)
1778             ret = needsProgramPulseNV(bank,SNum);
1779          else if(bank == 0)
1780             ret = needsProgramPulseScratch(bank,SNum);
1781          break;
1782 
1783       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
1784          if(bank > 0)
1785             ret = needsProgramPulseNV(bank,SNum);
1786          else if(bank == 0)
1787             ret = needsProgramPulseScratch(bank,SNum);
1788          break;
1789 
1790       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
1791          if(bank > 0)
1792             ret = needsProgramPulseNV(bank,SNum);
1793          else if(bank == 0)
1794             ret = needsProgramPulseScratch(bank,SNum);
1795          break;
1796 
1797       case 0x33: case 0xB3:  //SHAEE Memory Bank
1798          ret = needsProgramPulseSHAEE(bank,SNum);
1799          break;
1800 
1801       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
1802          ret = needsProgramPulseEPROM(bank,SNum);
1803          break;
1804 
1805       default:
1806          break;
1807    }
1808 
1809    return ret;
1810 }
1811 
1812 /**
1813  * Checks to see if this memory bank requires 'PowerDelivery'
1814  * in order to write.
1815  *
1816  * bank       to tell what memory bank of the ibutton to use.
1817  * SNum       the serial number for the part that the read is
1818  *            to be done on.
1819  *
1820  * @return    true if writing to this memory bank
1821  *            requires 'PowerDelivery' from the 1-Wire Adapter
1822  */
owNeedsPowerDelivery(SMALLINT bank,uchar * SNum)1823 SMALLINT owNeedsPowerDelivery(SMALLINT bank, uchar *SNum)
1824 {
1825    SMALLINT ret = 0;
1826 
1827    switch(SNum[0])
1828    {
1829       case 0x14:  //EE Memory Bank and AppReg Memory Bank
1830          if(bank > 0)
1831             ret = needsPowerDeliveryEE(bank,SNum);
1832          else if(bank == 0)
1833             ret = needsPowerDeliveryAppReg(bank,SNum);
1834          break;
1835 
1836       case 0x04: case 0x06: case 0x08: case 0x0A:
1837       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
1838          if(bank > 0)
1839             ret = needsPowerDeliveryNV(bank,SNum);
1840          else if(bank == 0)
1841             ret = needsPowerDeliveryScratch(bank,SNum);
1842          break;
1843 
1844       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
1845          if(bank > 0)
1846             ret = needsPowerDeliveryNV(bank,SNum);
1847          else if(bank == 0)
1848             ret = needsPowerDeliveryScratch(bank,SNum);
1849          break;
1850 
1851       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
1852          if(bank > 0)
1853             ret = needsPowerDeliveryNV(bank,SNum);
1854          else if(bank == 0)
1855             ret = needsPowerDeliveryScratch(bank,SNum);
1856          break;
1857 
1858       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
1859          if(bank > 0)
1860             ret = needsPowerDeliveryNV(bank,SNum);
1861          else if(bank == 0)
1862             ret = needsPowerDeliveryScratch(bank,SNum);
1863          break;
1864 
1865       case 0x33: case 0xB3:  //SHAEE Memory Bank
1866          ret = needsPowerDeliverySHAEE(bank,SNum);
1867          break;
1868 
1869       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
1870          ret = needsPowerDeliveryEPROM(bank,SNum);
1871          break;
1872 
1873       default:
1874          break;
1875    }
1876 
1877    return ret;
1878 }
1879 
1880 /**
1881  * Checks to see if this memory bank's pages deliver extra
1882  * information outside of the normal data space,  when read.  Examples
1883  * of this may be a redirection byte, counter, tamper protection
1884  * bytes, or SHA-1 result.  If this method returns true then the
1885  * methods with an 'extraInfo' parameter can be used:
1886  * owReadPageExtra,
1887  * owReadPageExtraCRC, and
1888  * owReadPagePacketExtra.
1889  *
1890  * bank       to tell what memory bank of the ibutton to use.
1891  * SNum       the serial number for the part that the read is
1892  *            to be done on.
1893  *
1894  * @return  <CODE> true </CODE> if reading the this memory bank's
1895  *                 pages provides extra information
1896  */
owHasExtraInfo(SMALLINT bank,uchar * SNum)1897 SMALLINT owHasExtraInfo(SMALLINT bank, uchar *SNum)
1898 {
1899    SMALLINT ret = 0;
1900 
1901    switch(SNum[0])
1902    {
1903       case 0x14:  //EE Memory Bank and AppReg Memory Bank
1904          if(bank > 0)
1905             ret = hasExtraInfoEE(bank,SNum);
1906          else if(bank == 0)
1907             ret = hasExtraInfoAppReg(bank,SNum);
1908          break;
1909 
1910       case 0x04: case 0x06: case 0x08: case 0x0A:
1911       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
1912          if(bank > 0)
1913             ret = hasExtraInfoNV(bank,SNum);
1914          else if(bank == 0)
1915             ret = hasExtraInfoScratch(bank,SNum);
1916          break;
1917 
1918       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
1919          if(bank > 0)
1920             ret = hasExtraInfoNV(bank,SNum);
1921          else if(bank == 0)
1922             ret = hasExtraInfoScratch(bank,SNum);
1923          break;
1924 
1925       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
1926          if(bank > 0)
1927             ret = hasExtraInfoNV(bank,SNum);
1928          else if(bank == 0)
1929             ret = hasExtraInfoScratch(bank,SNum);
1930          break;
1931 
1932       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
1933          if(bank > 0)
1934             ret = hasExtraInfoNV(bank,SNum);
1935          else if(bank == 0)
1936             ret = hasExtraInfoScratch(bank,SNum);
1937          break;
1938 
1939       case 0x33: case 0xB3:  //SHAEE Memory Bank
1940          ret = hasExtraInfoSHAEE(bank,SNum);
1941          break;
1942 
1943       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
1944          ret = hasExtraInfoEPROM(bank,SNum);
1945          break;
1946 
1947       default:
1948          break;
1949    }
1950 
1951    return ret;
1952 }
1953 
1954 /**
1955  * Gets the length in bytes of extra information that
1956  * is read when reading a page in this memory bank.
1957  *
1958  * bank       to tell what memory bank of the ibutton to use.
1959  * SNum       the serial number for the part that the read is
1960  *            to be done on.
1961  *
1962  * @return  number of bytes in Extra Information read when reading
1963  *          pages from this memory bank
1964  */
owGetExtraInfoLength(SMALLINT bank,uchar * SNum)1965 SMALLINT owGetExtraInfoLength(SMALLINT bank, uchar *SNum)
1966 {
1967    SMALLINT ret = 0;
1968 
1969    switch(SNum[0])
1970    {
1971       case 0x14:  //EE Memory Bank and AppReg Memory Bank
1972          if(bank > 0)
1973             ret = getExtraInfoLengthEE(bank,SNum);
1974          else if(bank == 0)
1975             ret = getExtraInfoLengthAppReg(bank,SNum);
1976          break;
1977 
1978       case 0x04: case 0x06: case 0x08: case 0x0A:
1979       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
1980          if(bank > 0)
1981             ret = getExtraInfoLengthNV(bank,SNum);
1982          else if(bank == 0)
1983             ret = getExtraInfoLengthScratch(bank,SNum);
1984          break;
1985 
1986       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
1987          if(bank > 0)
1988             ret = getExtraInfoLengthNV(bank,SNum);
1989          else if(bank == 0)
1990             ret = getExtraInfoLengthScratch(bank,SNum);
1991          break;
1992 
1993       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
1994          if(bank > 0)
1995             ret = getExtraInfoLengthNV(bank,SNum);
1996          else if(bank == 0)
1997             ret = getExtraInfoLengthScratch(bank,SNum);
1998          break;
1999 
2000       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
2001          if(bank > 0)
2002             ret = getExtraInfoLengthNV(bank,SNum);
2003          else if(bank == 0)
2004             ret = getExtraInfoLengthScratch(bank,SNum);
2005          break;
2006 
2007       case 0x33: case 0xB3:  //SHAEE Memory Bank
2008          ret = getExtraInfoLengthSHAEE(bank,SNum);
2009          break;
2010 
2011       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
2012          ret = getExtraInfoLengthEPROM(bank,SNum);
2013          break;
2014 
2015       default:
2016          break;
2017    }
2018 
2019    return ret;
2020 }
2021 
2022 /**
2023  * Gets a string description of what is contained in
2024  * the Extra Information returned when reading pages in this
2025  * memory bank.
2026  *
2027  * bank       to tell what memory bank of the ibutton to use.
2028  * SNum       the serial number for the part that the read is
2029  *            to be done on.
2030  *
2031  * @return extra information description.
2032  */
owGetExtraInfoDesc(SMALLINT bank,uchar * SNum)2033 char *owGetExtraInfoDesc(SMALLINT bank, uchar *SNum)
2034 {
2035    switch(SNum[0])
2036    {
2037       case 0x14:  //EE Memory Bank and AppReg Memory Bank
2038          if(bank > 0)
2039             return getExtraInfoDescEE(bank,SNum);
2040          else if(bank == 0)
2041             return getExtraInfoDescAppReg(bank,SNum);
2042          break;
2043 
2044       case 0x04: case 0x06: case 0x08: case 0x0A:
2045       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
2046          if(bank > 0)
2047             return getExtraInfoDescNV(bank,SNum);
2048          else if(bank == 0)
2049             return getExtraInfoDescScratch(bank,SNum);
2050          break;
2051 
2052       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
2053          if(bank > 0)
2054             return getExtraInfoDescNV(bank,SNum);
2055          else if(bank == 0)
2056             return getExtraInfoDescScratch(bank,SNum);
2057          break;
2058 
2059       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
2060          if(bank > 0)
2061             return getExtraInfoDescNV(bank,SNum);
2062          else if(bank == 0)
2063             return getExtraInfoDescScratch(bank,SNum);
2064          break;
2065 
2066       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
2067          if(bank > 0)
2068             return getExtraInfoDescNV(bank,SNum);
2069          else if(bank == 0)
2070             return getExtraInfoDescScratch(bank,SNum);
2071          break;
2072 
2073       case 0x33: case 0xB3:  //SHAEE Memory Bank
2074          return getExtraInfoDescSHAEE(bank,SNum);
2075          break;
2076 
2077       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
2078          return getExtraInfoDescEPROM(bank,SNum);
2079          break;
2080 
2081       default:
2082          break;
2083    }
2084 
2085    return "";
2086 }
2087 
2088 /**
2089  * Gets Maximum data page length in bytes for a packet
2090  * read or written in this memory bank.  See the
2091  * owReadPagePacket and owWritePagePacket
2092  * function.  This function is only usefull
2093  * if this memory bank is general purpose memory.
2094  *
2095  * bank       to tell what memory bank of the ibutton to use.
2096  * SNum       the serial number for the part that the read is
2097  *            to be done on.
2098  *
2099  * @return  max packet page length in bytes in this memory bank
2100  */
owGetMaxPacketDataLength(SMALLINT bank,uchar * SNum)2101 SMALLINT owGetMaxPacketDataLength(SMALLINT bank, uchar *SNum)
2102 {
2103    SMALLINT ret = 0;
2104 
2105    switch(SNum[0])
2106    {
2107       case 0x14:  //EE Memory Bank and AppReg Memory Bank
2108          if(bank > 0)
2109             ret = getMaxPacketDataLengthEE(bank,SNum);
2110          else if(bank == 0)
2111             ret = getMaxPacketDataLengthAppReg(bank,SNum);
2112          break;
2113 
2114       case 0x04: case 0x06: case 0x08: case 0x0A:
2115       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
2116          if(bank > 0)
2117             ret = getMaxPacketDataLengthNV(bank,SNum);
2118          else if(bank == 0)
2119             ret = getMaxPacketDataLengthScratch(bank,SNum);
2120          break;
2121 
2122       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
2123          if(bank > 0)
2124             ret = getMaxPacketDataLengthNV(bank,SNum);
2125          else if(bank == 0)
2126             ret = getMaxPacketDataLengthScratch(bank,SNum);
2127          break;
2128 
2129       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
2130          if(bank > 0)
2131             ret = getMaxPacketDataLengthNV(bank,SNum);
2132          else if(bank == 0)
2133             ret = getMaxPacketDataLengthScratch(bank,SNum);
2134          break;
2135 
2136       case 0x33: case 0xB3:  //SHAEE Memory Bank
2137          ret = getMaxPacketDataLengthSHAEE(bank,SNum);
2138          break;
2139 
2140       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
2141          ret = getMaxPacketDataLengthEPROM(bank,SNum);
2142          break;
2143 
2144       default:
2145          break;
2146    }
2147 
2148    return ret;
2149 }
2150 
2151 /**
2152  * Checks to see if this memory bank's pages can be read with
2153  * the contents being verified by a device generated CRC.
2154  * This is used to see if the owReadPageCRC function can be used.
2155  *
2156  * bank       to tell what memory bank of the ibutton to use.
2157  * SNum       the serial number for the part that the read is
2158  *            to be done on.
2159  *
2160  * @return  true if this memory bank can be
2161  *          read with self generated CRC
2162  */
owHasPageAutoCRC(SMALLINT bank,uchar * SNum)2163 SMALLINT owHasPageAutoCRC(SMALLINT bank, uchar *SNum)
2164 {
2165    SMALLINT ret = 0;
2166 
2167    switch(SNum[0])
2168    {
2169       case 0x14:  //EE Memory Bank and AppReg Memory Bank
2170          if(bank > 0)
2171             ret = hasPageAutoCRCEE(bank,SNum);
2172          else if(bank == 0)
2173             ret = hasPageAutoCRCAppReg(bank,SNum);
2174          break;
2175 
2176       case 0x04: case 0x06: case 0x08: case 0x0A:
2177       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
2178          if(bank > 0)
2179             ret = hasPageAutoCRCNV(bank,SNum);
2180          else if(bank == 0)
2181             ret = hasPageAutoCRCScratch(bank,SNum);
2182          break;
2183 
2184       case 0x18:  //NV Memory Bank and Scratch SHA Memory Bank
2185          if(bank > 0)
2186             ret = hasPageAutoCRCNV(bank,SNum);
2187          else if(bank == 0)
2188             ret = hasPageAutoCRCScratch(bank,SNum);
2189          break;
2190 
2191       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
2192          if(bank > 0)
2193             ret = hasPageAutoCRCNV(bank,SNum);
2194          else if(bank == 0)
2195             ret = hasPageAutoCRCScratch(bank,SNum);
2196          break;
2197 
2198       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
2199          if(bank > 0)
2200             ret = hasPageAutoCRCNV(bank,SNum);
2201          else if(bank == 0)
2202             ret = hasPageAutoCRCScratch(bank,SNum);
2203          break;
2204 
2205       case 0x33: case 0xB3:  //SHAEE Memory Bank
2206          ret = hasPageAutoCRCSHAEE(bank,SNum);
2207          break;
2208 
2209       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:  //EPROM Memory Bank
2210          ret = hasPageAutoCRCEPROM(bank,SNum);
2211          break;
2212 
2213       default:
2214          break;
2215    }
2216 
2217    return ret;
2218 }
2219 
2220 /**
2221  * Checks to see if this memory bank has pages that can be redirected
2222  * to a new page.  This is used in Write-Once memory
2223  * to provide a means to update.
2224  *
2225  * bank       to tell what memory bank of the ibutton to use.
2226  * SNum       the serial number for the part that the read is
2227  *            to be done on.
2228  *
2229  * @return  true if this memory bank pages can be redirected
2230  *          to a new page
2231  */
owCanRedirectPage(SMALLINT bank,uchar * SNum)2232 SMALLINT owCanRedirectPage(SMALLINT bank, uchar *SNum)
2233 {
2234    SMALLINT ret = 0;
2235 
2236    switch(SNum[0])
2237    {
2238       case 0x14:  //EE Memory Bank and AppReg Memory Bank
2239          if(bank > 0)
2240             ret = canRedirectPageEE(bank,SNum);
2241          else if(bank == 0)
2242             ret = canRedirectPageAppReg(bank,SNum);
2243          break;
2244 
2245       case 0x04: case 0x06: case 0x08: case 0x0A:
2246       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
2247          if(bank > 0)
2248             ret = canRedirectPageNV(bank,SNum);
2249          else if(bank == 0)
2250             ret = canRedirectPageScratch(bank,SNum);
2251          break;
2252 
2253       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
2254          if(bank > 0)
2255             ret = canRedirectPageNV(bank,SNum);
2256          else if(bank == 0)
2257             ret = canRedirectPageScratch(bank,SNum);
2258          break;
2259 
2260       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
2261          if(bank > 0)
2262             ret = canRedirectPageNV(bank,SNum);
2263          else if(bank == 0)
2264             ret = canRedirectPageScratch(bank,SNum);
2265          break;
2266 
2267       case 0x33: case 0xB3:  //SHAEE Memory Bank
2268          ret = canRedirectPageSHAEE(bank,SNum);
2269          break;
2270 
2271       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:
2272          ret = canRedirectPageEPROM(bank,SNum);
2273          break;
2274 
2275       default:
2276          break;
2277    }
2278 
2279    return ret;
2280 }
2281 
2282 /**
2283  * Checks to see if this memory bank has pages that can be locked.  A
2284  * locked page would prevent any changes to it's contents.
2285  *
2286  * bank       to tell what memory bank of the ibutton to use.
2287  * SNum       the serial number for the part that the read is
2288  *            to be done on.
2289  *
2290  * @return  true if this memory bank has pages that can be
2291  *          locked
2292  */
owCanLockPage(SMALLINT bank,uchar * SNum)2293 SMALLINT owCanLockPage(SMALLINT bank, uchar *SNum)
2294 {
2295    SMALLINT ret = 0;
2296 
2297    switch(SNum[0])
2298    {
2299       case 0x14:  //EE Memory Bank and AppReg Memory Bank
2300          if(bank > 0)
2301             ret = canLockPageEE(bank,SNum);
2302          else if(bank == 0)
2303             ret = canLockPageAppReg(bank,SNum);
2304          break;
2305 
2306       case 0x04: case 0x06: case 0x08: case 0x0A:
2307       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
2308          if(bank > 0)
2309             ret = canLockPageNV(bank,SNum);
2310          else if(bank == 0)
2311             ret = canLockPageScratch(bank,SNum);
2312          break;
2313 
2314       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
2315          if(bank > 0)
2316             ret = canLockPageNV(bank,SNum);
2317          else if(bank == 0)
2318             ret = canLockPageScratch(bank,SNum);
2319          break;
2320 
2321       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
2322          if(bank > 0)
2323             ret = canLockPageNV(bank,SNum);
2324          else if(bank == 0)
2325             ret = canLockPageScratch(bank,SNum);
2326          break;
2327 
2328       case 0x33: case 0xB3:  //SHAEE Memory Bank
2329          ret = canLockPageSHAEE(bank,SNum);
2330          break;
2331 
2332       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:
2333          ret = canLockPageEPROM(bank,SNum);
2334          break;
2335 
2336       default:
2337          break;
2338    }
2339 
2340    return ret;
2341 }
2342 
2343 /**
2344  * Checks to see if this memory bank has pages that can be locked from
2345  * being redirected.  This would prevent a Write-Once memory from
2346  * being updated.
2347  *
2348  * bank       to tell what memory bank of the ibutton to use.
2349  * SNum       the serial number for the part that the read is
2350  *            to be done on.
2351  *
2352  * @return  true if this memory bank has pages that can
2353  *          be locked from being redirected to a new page
2354  */
owCanLockRedirectPage(SMALLINT bank,uchar * SNum)2355 SMALLINT owCanLockRedirectPage(SMALLINT bank, uchar *SNum)
2356 {
2357    SMALLINT ret = 0;
2358 
2359    switch(SNum[0])
2360    {
2361       case 0x14:  //EE Memory Bank and AppReg Memory Bank
2362          if(bank > 0)
2363             ret = canLockRedirectPageEE(bank,SNum);
2364          else if(bank == 0)
2365             ret = canLockRedirectPageAppReg(bank,SNum);
2366          break;
2367 
2368       case 0x04: case 0x06: case 0x08: case 0x0A:
2369       case 0x0C: case 0x23:  //NV Memory Bank and Scratch Memory Bank
2370          if(bank > 0)
2371             ret = canLockRedirectPageNV(bank,SNum);
2372          else if(bank == 0)
2373             ret = canLockRedirectPageScratch(bank,SNum);
2374          break;
2375 
2376       case 0x1A: case 0x1D:  //NVCRC Memory Bank and Scratch Ex Memory Bank
2377          if(bank > 0)
2378             ret = canLockRedirectPageNV(bank,SNum);
2379          else if(bank == 0)
2380             ret = canLockRedirectPageScratch(bank,SNum);
2381          break;
2382 
2383       case 0x21:  //NVCRC Memory Bank and Scratch CRC Memory Bank
2384          if(bank > 0)
2385             ret = canLockRedirectPageNV(bank,SNum);
2386          else if(bank == 0)
2387             ret = canLockRedirectPageScratch(bank,SNum);
2388          break;
2389 
2390       case 0x33: case 0xB3:  //SHAEE Memory Bank
2391          ret = canLockRedirectPageSHAEE(bank,SNum);
2392          break;
2393 
2394       case 0x09: case 0x0B: case 0x0F: case 0x12: case 0x13:
2395          ret = canLockRedirectPageEPROM(bank,SNum);
2396          break;
2397 
2398       default:
2399          break;
2400    }
2401 
2402    return ret;
2403 }
2404 
2405 /**
2406  * Gets the memory bank given the page for the part.
2407  *
2408  * portnum    the port number of the port being used for the
2409  *            1-Wire Network.
2410  * SNum       the serial number for the part that the read is
2411  *            to be done on.
2412  * page       the page number for the part not memory bank
2413  *
2414  * @return    the bank number that the page is in.
2415  */
getBank(int portnum,uchar * SNum,PAGE_TYPE page,uchar flag)2416 SMALLINT getBank(int portnum, uchar *SNum, PAGE_TYPE page, uchar flag)
2417 {
2418    SMALLINT bank = 1;
2419    SMALLINT i,starting_bank=1;
2420    int      tmp_pg;
2421    int      num_pg;
2422 
2423    if(flag == STATUSMEM)
2424    {
2425       tmp_pg = page;
2426 
2427       for(i=starting_bank;i<owGetNumberBanks(SNum[0]);i++)
2428       {
2429          if((i+1) == owGetNumberBanks(SNum[0]))
2430             return i;
2431          else
2432             num_pg = owGetStartingAddress(i+1,SNum)/owGetPageLength(bank,SNum);
2433 
2434          if(num_pg >= tmp_pg)
2435          {
2436             if(num_pg == tmp_pg)
2437                return i+1;
2438             else
2439                return i;
2440          }
2441 
2442       }
2443    }
2444    else
2445    {
2446       if(owIsWriteOnce(bank,portnum,SNum))
2447       {
2448          tmp_pg = page;
2449 
2450          for(i=0;i<owGetNumberBanks(SNum[0]);i++)
2451          {
2452             if(owIsNonVolatile(i,SNum) && owIsGeneralPurposeMemory(i,SNum))
2453             {
2454                num_pg = owGetNumberPages(i,SNum);
2455 
2456                if(num_pg >= tmp_pg)
2457                   return i;
2458                else
2459                   tmp_pg = tmp_pg - num_pg;
2460             }
2461          }
2462       }
2463       else
2464       {
2465          tmp_pg = page;
2466 
2467          for(i=0;i<owGetNumberBanks(SNum[0]);i++)
2468          {
2469             if(owIsNonVolatile(i,SNum) && owIsGeneralPurposeMemory(i,SNum) &&
2470                owIsReadWrite(i,portnum,SNum))
2471             {
2472                num_pg = owGetNumberPages(i,SNum);
2473 
2474                if(num_pg > tmp_pg)
2475                   return i;
2476                else
2477                tmp_pg = tmp_pg - num_pg;
2478             }
2479          }
2480       }
2481    }
2482 
2483    return FALSE;
2484 }
2485 
2486 /**
2487  * Gets the memory bank given the page for the part.
2488  *
2489  * portnum    the port number of the port being used for the
2490  *            1-Wire Network.
2491  * SNum       the serial number for the part that the read is
2492  *            to be done on.
2493  * page       the page number for the part not memory bank
2494  *
2495  * @return    the bank number that the page is in.
2496  */
getPage(int portnum,uchar * SNum,PAGE_TYPE page,uchar flag)2497 SMALLINT getPage(int portnum, uchar *SNum, PAGE_TYPE page, uchar flag)
2498 {
2499    SMALLINT bank = 1;
2500    SMALLINT i,starting_bank=1;
2501    int      tmp_pg;
2502    int      num_pg;
2503 
2504    if(flag == STATUSMEM)
2505    {
2506       tmp_pg = page;
2507 
2508       for(i=starting_bank;i<owGetNumberBanks(SNum[0]);i++)
2509       {
2510          if((i+1) == owGetNumberBanks(SNum[0]))
2511             return (tmp_pg - (owGetStartingAddress(i,SNum)/owGetPageLength(bank,SNum)));
2512          else
2513             num_pg = owGetStartingAddress(i+1,SNum)/owGetPageLength(bank,SNum);
2514 
2515          if(num_pg >= tmp_pg)
2516          {
2517             if(num_pg == tmp_pg)
2518                return 0;
2519             else if(owGetStartingAddress(i,SNum) == 0x00)
2520                return tmp_pg;
2521             else
2522                return (tmp_pg - (owGetStartingAddress(i,SNum)/owGetPageLength(bank,SNum)));
2523          }
2524       }
2525    }
2526    else
2527    {
2528       if(owIsWriteOnce(bank,portnum,SNum))
2529       {
2530          tmp_pg = page;
2531 
2532          for(i=0;i<owGetNumberBanks(SNum[0]);i++)
2533          {
2534             if(owIsNonVolatile(i,SNum) && owIsGeneralPurposeMemory(i,SNum))
2535             {
2536                num_pg = owGetNumberPages(i,SNum);
2537 
2538                if(num_pg >= tmp_pg)
2539                   return tmp_pg;
2540                else
2541                   tmp_pg = tmp_pg - num_pg;
2542             }
2543          }
2544       }
2545       else
2546       {
2547          tmp_pg = page;
2548 
2549          for(i=0;i<owGetNumberBanks(SNum[0]);i++)
2550          {
2551             if(owIsNonVolatile(i,SNum) && owIsGeneralPurposeMemory(i,SNum) &&
2552                owIsReadWrite(i,portnum,SNum))
2553             {
2554                num_pg = owGetNumberPages(i,SNum);
2555 
2556                if(num_pg > tmp_pg)
2557                   return tmp_pg;
2558                else
2559                   tmp_pg = tmp_pg - num_pg;
2560             }
2561          }
2562       }
2563    }
2564 
2565    return FALSE;
2566 }