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 //  mbEE.c - Reads and writes to memory locations for the EE memory bank.
28 //  version 1.00
29 //
30 
31 // Include Files
32 #include "ownet.h"
33 #include "mbee.h"
34 
35 // External functions
36 extern SMALLINT owBlock(int,int,uchar *,int);
37 extern SMALLINT owReadByte(int);
38 extern SMALLINT owWriteByte(int,int);
39 extern void     output_status(int, char *);
40 extern void     msDelay(int);
41 extern void     owSerialNum(int,uchar *,int);
42 extern SMALLINT owAccess(int);
43 extern SMALLINT owWriteByte(int,int);
44 extern void     setcrc16(int,ushort);
45 extern ushort   docrc16(int,ushort);
46 extern SMALLINT owWriteBytePower(int,int);
47 extern SMALLINT owLevel(int,int);
48 extern SMALLINT owHasPowerDelivery(int);
49 
50 // Local functions
51 SMALLINT writeScratchpad (int portnum,int startAddr, uchar *writeBuf, int len);
52 SMALLINT readScratchpad (int portnum, uchar *readBuf, int startAddr, int len);
53 SMALLINT copyScratchpad (int portnum);
54 
55 // General command defines
56 #define READ_MEMORY_COMMAND      0xF0
57 #define WRITE_SCRATCHPAD_COMMAND 0x0F
58 #define READ_SCRATCHPAD_COMMAND  0xAA
59 #define COPY_SCRATCHPAD_COMMAND  0x55
60 // Local defines
61 #define SIZE        32
62 #define PAGE_LENGTH 32
63 
64 // Global variables
65 char     *bankDescription     = "Main Memory";
66 SMALLINT  writeVerification    = TRUE;
67 SMALLINT  generalPurposeMemory = TRUE;
68 SMALLINT  readWrite            = TRUE;
69 SMALLINT  writeOnce            = FALSE;
70 SMALLINT  readOnly             = FALSE;
71 SMALLINT  nonVolatile          = TRUE;
72 SMALLINT  needsProgramPulse    = FALSE;
73 SMALLINT  needsPowerDelivery   = TRUE;
74 SMALLINT  hasExtraInfo         = FALSE;
75 SMALLINT  extraInfoLength      = 0;
76 char     *extraInfoDesc       = "";
77 SMALLINT  pageAutoCRC          = FALSE;
78 
79 
80 /**
81  * Read  memory in the current bank with no CRC checking (device or
82  * data). The resulting data from this API may or may not be what is on
83  * the 1-Wire device.  It is recommends that the data contain some kind
84  * of checking (CRC) like in the readPagePacketEE() method or have
85  * the 1-Wire device provide the CRC as in readPageCRCEE().  readPageCRCEE()
86  * however is not supported on all memory types, see 'hasPageAutoCRCEE()'.
87  * If neither is an option then this method could be called more
88  * then once to at least verify that the same thing is read consistantly.
89  *
90  * bank     to tell what memory bank of the ibutton to use.
91  * portnum  the port number of the port being used for the
92  *          1-Wire Network.
93  * SNum     the serial number for the part that the read is
94  *          to be done on.
95  * str_add  starting physical address
96  * rd_cont  if 'true' then device read is continued without
97  *          re-selecting.  This can only be used if the new
98  *          read() continious where the last one led off
99  *          and it is inside a 'beginExclusive/endExclusive'
100  *          block.
101  * buff     byte array to place read data into
102  * len      length in bytes to read
103  *
104  * @return 'true' if the read was complete
105  */
readEE(SMALLINT bank,int portnum,uchar * SNum,int str_add,SMALLINT rd_cont,uchar * buff,int len)106 SMALLINT readEE(SMALLINT bank, int portnum, uchar *SNum, int str_add,
107                 SMALLINT rd_cont, uchar *buff, int len)
108 {
109    int    i;
110    uchar  raw_buf[2];
111 
112    // check if read exceeds memory
113    if((str_add + len)>SIZE)
114    {
115       OWERROR(OWERROR_READ_OUT_OF_RANGE);
116       return FALSE;
117    }
118 
119    owSerialNum(portnum,SNum,FALSE);
120 
121    // select the device
122    if (!owAccess(portnum))
123    {
124       OWERROR(OWERROR_DEVICE_SELECT_FAIL);
125       return FALSE;
126    }
127 
128    // build start reading memory block
129    raw_buf[0] = READ_MEMORY_COMMAND;
130    raw_buf[1] = (uchar)str_add & 0xFF;
131 
132    // do the first block for command, address
133    if(!owBlock(portnum,FALSE,raw_buf,2))
134    {
135       OWERROR(OWERROR_BLOCK_FAILED);
136       return FALSE;
137    }
138 
139    // pre-fill readBuf with 0xFF
140    for(i=0;i<len;i++)
141       buff[i] = 0xFF;
142 
143    // send the block
144    if(!owBlock(portnum,FALSE,buff,len))
145    {
146       OWERROR(OWERROR_BLOCK_FAILED);
147       return FALSE;
148    }
149 
150 
151    return TRUE;
152 }
153 
154 /**
155  * Write  memory in the current bank.  It is recommended that
156  * when writing  data that some structure in the data is created
157  * to provide error free reading back with readEE().  Or the
158  * method 'writePagePacketEE()' could be used which automatically
159  * wraps the data in a length and CRC.
160  *
161  * When using on Write-Once devices care must be taken to write into
162  * into empty space.  If write() is used to write over an unlocked
163  * page on a Write-Once device it will fail.
164  *
165  * bank     to tell what memory bank of the ibutton to use.
166  * portnum  the port number of the port being used for the
167  *          1-Wire Network.
168  * SNum     the serial number for the part that the write is
169  *          to be done on.
170  * str_add  starting address
171  * buff     byte array containing data to write
172  * len      length in bytes to write
173  *
174  * @return 'true' if the write was complete.
175  */
writeEE(SMALLINT bank,int portnum,uchar * SNum,int str_add,uchar * buff,int len)176 SMALLINT writeEE(SMALLINT bank, int portnum, uchar *SNum, int str_add,
177                  uchar *buff, int len)
178 {
179    int i;
180    uchar raw_buf[64];
181 
182    // return if nothing to do
183    if (len == 0)
184       return TRUE;
185 
186    // check if power delivery is available
187    if(!owHasPowerDelivery(portnum))
188    {
189       OWERROR(OWERROR_POWER_NOT_AVAILABLE);
190       return FALSE;
191    }
192 
193    // check if write exceeds memory
194    if ((str_add + len) > SIZE)
195    {
196       OWERROR(OWERROR_WRITE_OUT_OF_RANGE);
197       return FALSE;
198    }
199 
200    owSerialNum(portnum,SNum,FALSE);
201 
202    // write the page of data to scratchpad
203    writeScratchpad(portnum,str_add,buff,len);
204 
205    // read the data back for verification
206    readScratchpad(portnum,raw_buf,str_add,PAGE_LENGTH);
207 
208    // check to see if the same
209    for (i = 0; i < len; i++)
210       if (raw_buf[i] != buff[i])
211       {
212          OWERROR(OWERROR_READ_SCRATCHPAD_VERIFY);
213          return FALSE;
214       }
215 
216    // do the copy
217    copyScratchpad(portnum);
218 
219    // check on write verification
220    if (writeVerification)
221    {
222 
223       // read back to verify
224       if(!readEE(bank,portnum,SNum,str_add,FALSE,buff,len))
225          return FALSE;
226 
227       for (i=0;i<len;i++)
228          if (raw_buf[i] != buff[i])
229          {
230             OWERROR(OWERROR_READ_VERIFY_FAILED);
231             return FALSE;
232          }
233    }
234 
235    return TRUE;
236 }
237 
238 /**
239  * Read  page in the current bank with no
240  * CRC checking (device or data). The resulting data from this API
241  * may or may not be what is on the 1-Wire device.  It is recommends
242  * that the data contain some kind of checking (CRC) like in the
243  * readPagePacketEE() method or have the 1-Wire device provide the
244  * CRC as in readPageCRCEE().  readPageCRCEE() however is not
245  * supported on all memory types, see 'hasPageAutoCRCEE()'.
246  * If neither is an option then this method could be called more
247  * then once to at least verify that the same thing is read consistantly.
248  *
249  * bank     to tell what memory bank of the ibutton to use.
250  * portnum  the port number of the port being used for the
251  *          1-Wire Network.
252  * SNum     the serial number for the part.
253  * page     the page to read
254  * rd_cont  if 'true' then device read is continued without
255  *          re-selecting.  This can only be used if the new
256  *          read() continious where the last one led off
257  *          and it is inside a 'beginExclusive/endExclusive'
258  *          block.
259  * buff     byte array containing data that was read.
260  * len      length in bytes to write
261  *
262  * @return - returns '0' if the read page wasn't completed.
263  *                   '1' if the operation is complete.
264  */
readPageEE(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff)265 SMALLINT readPageEE(SMALLINT bank, int portnum, uchar *SNum, int page,
266                     SMALLINT rd_cont, uchar *buff)
267 {
268    if(page != 0)
269    {
270       OWERROR(OWERROR_INVALID_PAGE_NUMBER);
271       return FALSE;
272    }
273 
274    return readEE(bank,portnum,SNum,page,rd_cont,buff,PAGE_LENGTH);
275 }
276 
277 /**
278  * Read  page with extra information in the current bank with no
279  * CRC checking (device or data). The resulting data from this API
280  * may or may not be what is on the 1-Wire device.  It is recommends
281  * that the data contain some kind of checking (CRC) like in the
282  * readPagePacketEE() method or have the 1-Wire device provide the
283  * CRC as in readPageCRCEE().  readPageCRCEE() however is not
284  * supported on all memory types, see 'hasPageAutoCRCEE()'.
285  * If neither is an option then this method could be called more
286  * then once to at least verify that the same thing is read consistantly.
287  * See the method 'hasExtraInfoEE()' for a description of the optional
288  * extra information some devices have.
289  *
290  * bank     to tell what memory bank of the ibutton to use.
291  * portnum  the port number of the port being used for the
292  *          1-Wire Network.
293  * SNum     the serial number for the part.
294  * page     the page to read
295  * rd_cont  if 'true' then device read is continued without
296  *          re-selecting.  This can only be used if the new
297  *          read() continious where the last one led off
298  *          and it is inside a 'beginExclusive/endExclusive'
299  *          block.
300  * buff     byte array containing data that was read
301  * len      length in bytes to write
302  * extra    the extra information
303  *
304  * @return - returns '0' if the read page wasn't completed with extra info.
305  *                   '1' if the operation is complete.
306  */
readPageExtraEE(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff,uchar * extra)307 SMALLINT readPageExtraEE(SMALLINT bank, int portnum, uchar *SNum, int page,
308                          SMALLINT rd_cont, uchar *buff, uchar *extra)
309 {
310    OWERROR(OWERROR_EXTRA_INFO_NOT_SUPPORTED);
311    return FALSE;
312 }
313 
314 /**
315  * Read a complete memory page with CRC verification provided by the
316  * device with extra information.  Not supported by all devices.
317  * See the method 'hasPageAutoCRC()'.
318  * See the method 'haveExtraInfo()' for a description of the optional
319  * extra information.
320  *
321  * bank     to tell what memory bank of the ibutton to use.
322  * portnum  the port number of the port being used for the
323  *          1-Wire Network.
324  * SNum     the serial number for the part.
325  * page     the page to read
326  * buff     byte array containing data that was read.
327  * extra    the extra information
328  *
329  * @return - returns '0' if the read page wasn't completed with extra info.
330  *                   '1' if the operation is complete.
331  */
readPageExtraCRCEE(SMALLINT bank,int portnum,uchar * SNum,int page,uchar * read_buff,uchar * extra)332 SMALLINT readPageExtraCRCEE(SMALLINT bank, int portnum, uchar *SNum, int page,
333                             uchar *read_buff, uchar *extra)
334 {
335    OWERROR(OWERROR_CRC_EXTRA_INFO_NOT_SUPPORTED);
336    return FALSE;
337 }
338 /**
339  * Read a complete memory page with CRC verification provided by the
340  * device.  Not supported by all devices.  See the method
341  * 'hasPageAutoCRCEE()'.
342  *
343  * bank     to tell what memory bank of the ibutton to use.
344  * portnum  the port number of the port being used for the
345  *          1-Wire Network.
346  * SNum     the serial number for the part.
347  * page     the page to read
348  * buff     byte array containing data that was read
349  *
350  * @return - returns '0' if the read page wasn't completed.
351  *                   '1' if the operation is complete.
352  */
readPageCRCEE(SMALLINT bank,int portnum,uchar * SNum,int page,uchar * buff)353 SMALLINT readPageCRCEE(SMALLINT bank, int portnum, uchar *SNum, int page, uchar *buff)
354 {
355    OWERROR(OWERROR_CRC_NOT_SUPPORTED);
356    return FALSE;
357 }
358 
359 /**
360  * Read a Universal Data Packet.
361  *
362  * The Universal Data Packet always starts on page boundaries but
363  * can end anywhere in the page.  The structure specifies the length of
364  * data bytes not including the length byte and the CRC16 bytes.
365  * There is one length byte. The CRC16 is first initialized to
366  * the page number.  This provides a check to verify the page that
367  * was intended is being read.  The CRC16 is then calculated over
368  * the length and data bytes.  The CRC16 is then inverted and stored
369  * low byte first followed by the high byte.  This is structure is
370  * used by this method to verify the data but is not returned, only
371  * the data payload is returned.
372  *
373  * bank     to tell what memory bank of the ibutton to use.
374  * portnum  the port number of the port being used for the
375  *          1-Wire Network.
376  * SNum     the serial number for the part.
377  * page     the page to read
378  * rd_cont  if 'true' then device read is continued without
379  *          re-selecting.  This can only be used if the new
380  *          read() continious where the last one led off
381  *          and it is inside a 'beginExclusive/endExclusive'
382  *          block.
383  * buff     byte array containing data that was read.
384  * len      length of the packet
385  *
386  * @return - returns '0' if the read page packet wasn't completed
387  *                   '1' if the operation is complete.
388  */
readPagePacketEE(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff,int * len)389 SMALLINT readPagePacketEE(SMALLINT bank, int portnum, uchar *SNum, int page,
390                           SMALLINT rd_cont, uchar *buff, int *len)
391 {
392    uchar raw_buf[PAGE_LENGTH];
393    ushort lastcrc16;
394    int i;
395 
396    // read the scratchpad, discard extra information
397    if(!readEE(bank,portnum,SNum,page,rd_cont,raw_buf,PAGE_LENGTH))
398       return FALSE;
399 
400    // check if length is realistic
401    if((raw_buf[0] > (PAGE_LENGTH - 3)) || (raw_buf[0] <= 0))
402    {
403       OWERROR(OWERROR_INVALID_PACKET_LENGTH);
404       return FALSE;
405    }
406 
407    // verify the CRC is correct
408    setcrc16(portnum,(ushort) ((getStartingAddressEE(bank,SNum)/PAGE_LENGTH) + page));
409    for(i=0;i<raw_buf[0]+3;i++)
410       lastcrc16 = docrc16(portnum,raw_buf[i]);
411 
412    if(lastcrc16 == 0xB001)
413    {
414 
415       // extract the data out of the packet
416       for(i=1;i<raw_buf[0]+1;i++)
417          buff[i-1] = raw_buf[i];
418 
419       // return the length
420       *len = (int) raw_buf[0];
421    }
422    else
423    {
424       OWERROR(OWERROR_CRC_FAILED);
425       return FALSE;
426    }
427 
428    return TRUE;
429 }
430 
431 /**
432  * Read a Universal Data Packet and extra information.  See the
433  * method 'readPagePacketEE()' for a description of the packet structure.
434  * See the method 'hasExtraInfoEE()' for a description of the optional
435  * extra information some devices have.
436  *
437  * bank     to tell what memory bank of the ibutton to use.
438  * portnum  the port number of the port being used for the
439  *          1-Wire Network.
440  * SNum     the serial number for the part.
441  * page     the page to read
442  * rd_cont  if 'true' then device read is continued without
443  *          re-selecting.  This can only be used if the new
444  *          read() continious where the last one led off
445  *          and it is inside a 'beginExclusive/endExclusive'
446  *          block.
447  * buff     byte array containing data that was read.
448  * len      length of the packet
449  * extra    extra information
450  *
451  * @return - returns '0' if the read page packet wasn't completed
452  *                   '1' if the operation is complete.
453  */
readPagePacketExtraEE(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff,int * len,uchar * extra)454 SMALLINT readPagePacketExtraEE(SMALLINT bank, int portnum, uchar *SNum,
455                                int page, SMALLINT rd_cont, uchar *buff,
456                                int *len, uchar *extra)
457 {
458    OWERROR(OWERROR_PG_PACKET_WITHOUT_EXTRA);
459    return FALSE;
460 }
461 
462 /**
463  * Write a Universal Data Packet.  See the method 'readPagePacketEE()'
464  * for a description of the packet structure.
465  *
466  * bank     to tell what memory bank of the ibutton to use.
467  * portnum  the port number of the port being used for the
468  *          1-Wire Network.
469  * SNum     the serial number for the part.
470  * page     the page the packet is being written to.
471  * rd_cont  if 'true' then device read is continued without
472  *          re-selecting.  This can only be used if the new
473  *          read() continious where the last one led off
474  *          and it is inside a 'beginExclusive/endExclusive'
475  *          block.
476  * buff     byte array containing data that to write.
477  * len      length of the packet
478  *
479  * @return - returns '0' if the write page packet wasn't completed
480  *                   '1' if the operation is complete.
481  */
writePagePacketEE(SMALLINT bank,int portnum,uchar * SNum,int page,uchar * buff,int len)482 SMALLINT writePagePacketEE(SMALLINT bank, int portnum, uchar *SNum, int page,
483                            uchar *buff, int len)
484 {
485    uchar raw_buf[64];
486    int i;
487    ushort crc;
488 
489    // make sure length does not exceed max
490    if ((len > (PAGE_LENGTH - 3)) || (len <= 0))
491    {
492       OWERROR(OWERROR_PACKET_LENGTH_EXCEEDS_PAGE);
493       return FALSE;
494    }
495 
496    // construct the packet to write
497    raw_buf[0] = (uchar) len + 3;
498 
499    for(i=1;i<len+1;i++)
500       raw_buf[i] = buff[i-1];
501 
502    setcrc16(portnum,(ushort) ((getStartingAddressEE(bank,SNum)/PAGE_LENGTH) + page));
503    for(i=0;i<len+1;i++)
504       crc = docrc16(portnum,raw_buf[i]);
505 
506    raw_buf[len + 1] = ~crc & 0xFF;
507    raw_buf[len + 2] = ((~crc & 0xFFFF) >> 8) & 0xFF;
508 
509    // write the packet, return result
510    if(!writeEE(bank,portnum,SNum,page * PAGE_LENGTH,raw_buf,len + 3))
511       return FALSE;
512 
513    return TRUE;
514 }
515 
516 /**
517  * Query to get the number of pages in current memory bank.
518  *
519  * bank     to tell what memory bank of the ibutton to use.
520  * SNum     the serial number for the part.
521  *
522  * @return  number of pages in current memory bank
523  */
getNumberPagesEE(SMALLINT bank,uchar * SNum)524 SMALLINT getNumberPagesEE(SMALLINT bank, uchar *SNum)
525 {
526    return 1;
527 }
528 
529 /**
530  * Query to get the memory bank size in bytes.
531  *
532  * bank     to tell what memory bank of the ibutton to use.
533  * SNum     the serial number for the part.
534  *
535  * @return  memory bank size in bytes.
536  */
getSizeEE(SMALLINT bank,uchar * SNum)537 int getSizeEE(SMALLINT bank, uchar *SNum)
538 {
539    return SIZE;
540 }
541 
542 /**
543  * Query to get the starting physical address of this bank.  Physical
544  * banks are sometimes sub-divided into logical banks due to changes
545  * in attributes.
546  *
547  * bank     to tell what memory bank of the ibutton to use.
548  * SNum     the serial number for the part.
549  *
550  * @return  physical starting address of this logical bank.
551  */
getStartingAddressEE(SMALLINT bank,uchar * SNum)552 int getStartingAddressEE(SMALLINT bank, uchar *SNum)
553 {
554    return 0;
555 }
556 
557 /**
558  * Query to get page length in bytes in current memory bank.
559  *
560  * bank     to tell what memory bank of the ibutton to use.
561  * SNum     the serial number for the part.
562  *
563  * @return   page length in bytes in current memory bank
564  */
getPageLengthEE(SMALLINT bank,uchar * SNum)565 SMALLINT getPageLengthEE(SMALLINT bank, uchar *SNum)
566 {
567    return PAGE_LENGTH;
568 }
569 
570 /**
571  * Query to see get a string description of the current memory bank.
572  *
573  * bank     to tell what memory bank of the ibutton to use.
574  * SNum     the serial number for the part.
575  *
576  * @return  String containing the memory bank description
577  */
getBankDescriptionEE(SMALLINT bank,uchar * SNum)578 char *getBankDescriptionEE(SMALLINT bank, uchar *SNum)
579 {
580    return bankDescription;
581 }
582 
583 /**
584  * Query to see if the current memory bank is general purpose
585  * user memory.  If it is NOT then it is Memory-Mapped and writing
586  * values to this memory will affect the behavior of the 1-Wire
587  * device.
588  *
589  * bank     to tell what memory bank of the ibutton to use.
590  * SNum     the serial number for the part.
591  *
592  * @return  'true' if current memory bank is general purpose
593  */
isGeneralPurposeMemoryEE(SMALLINT bank,uchar * SNum)594 SMALLINT isGeneralPurposeMemoryEE(SMALLINT bank, uchar *SNum)
595 {
596    return generalPurposeMemory;
597 }
598 
599 /**
600  * Query to see if current memory bank is read/write.
601  *
602  * bank     to tell what memory bank of the ibutton to use.
603  * SNum     the serial number for the part.
604  *
605  * @return  'true' if current memory bank is read/write
606  */
isReadWriteEE(SMALLINT bank,int portnum,uchar * SNum)607 SMALLINT isReadWriteEE(SMALLINT bank, int portnum, uchar *SNum)
608 {
609    return readWrite;
610 }
611 
612 /**
613  * Query to see if current memory bank is write write once such
614  * as with EPROM technology.
615  *
616  * bank     to tell what memory bank of the ibutton to use.
617  * SNum     the serial number for the part.
618  *
619  * @return  'true' if current memory bank can only be written once
620  */
isWriteOnceEE(SMALLINT bank,int portnum,uchar * SNum)621 SMALLINT isWriteOnceEE(SMALLINT bank, int portnum, uchar *SNum)
622 {
623    return writeOnce;
624 }
625 
626 /**
627  * Query to see if current memory bank is read only.
628  *
629  * @return  'true' if current memory bank can only be read
630  */
isReadOnlyEE(SMALLINT bank,int portnum,uchar * SNum)631 SMALLINT isReadOnlyEE(SMALLINT bank, int portnum, uchar *SNum)
632 {
633    return readOnly;
634 }
635 
636 /**
637  * Query to see if current memory bank non-volatile.  Memory is
638  * non-volatile if it retains its contents even when removed from
639  * the 1-Wire network.
640  *
641  * bank     to tell what memory bank of the ibutton to use.
642  * SNum     the serial number for the part.
643  *
644  * @return  'true' if current memory bank non volatile.
645  */
isNonVolatileEE(SMALLINT bank,uchar * SNum)646 SMALLINT isNonVolatileEE(SMALLINT bank, uchar *SNum)
647 {
648    return nonVolatile;
649 }
650 
651 /**
652  * Query to see if current memory bank pages need the adapter to
653  * have a 'ProgramPulse' in order to write to the memory.
654  *
655  * bank     to tell what memory bank of the ibutton to use.
656  * SNum     the serial number for the part.
657  *
658  * @return  'true' if writing to the current memory bank pages
659  *                 requires a 'ProgramPulse'.
660  */
needsProgramPulseEE(SMALLINT bank,uchar * SNum)661 SMALLINT needsProgramPulseEE(SMALLINT bank, uchar *SNum)
662 {
663    return needsProgramPulse;
664 }
665 
666 /**
667  * Query to see if current memory bank pages need the adapter to
668  * have a 'PowerDelivery' feature in order to write to the memory.
669  *
670  * bank     to tell what memory bank of the ibutton to use.
671  * SNum     the serial number for the part.
672  *
673  * @return  'true' if writing to the current memory bank pages
674  *                 requires 'PowerDelivery'.
675  */
needsPowerDeliveryEE(SMALLINT bank,uchar * SNum)676 SMALLINT needsPowerDeliveryEE(SMALLINT bank, uchar *SNum)
677 {
678    return needsPowerDelivery;
679 }
680 
681 /**
682  * Checks to see if this memory bank's pages deliver extra
683  * information outside of the normal data space,  when read.  Examples
684  * of this may be a redirection byte, counter, tamper protection
685  * bytes, or SHA-1 result.  If this method returns true then the
686  * methods with an 'extraInfo' parameter can be used.
687  *
688  * bank     to tell what memory bank of the ibutton to use.
689  * SNum     the serial number for the part.
690  *
691  * @return  true if reading the this memory bank's
692  *               pages provides extra information
693  */
hasExtraInfoEE(SMALLINT bank,uchar * SNum)694 SMALLINT hasExtraInfoEE(SMALLINT bank, uchar *SNum)
695 {
696    return hasExtraInfo;
697 }
698 
699 /**
700  * Query to get the length in bytes of extra information that
701  * is read when read a page in the current memory bank.  See
702  * 'hasExtraInfoEE()'.
703  *
704  * bank     to tell what memory bank of the ibutton to use.
705  * SNum     the serial number for the part.
706  *
707  * @return  number of bytes in Extra Information read when reading
708  *          pages in the current memory bank.
709  */
getExtraInfoLengthEE(SMALLINT bank,uchar * SNum)710 SMALLINT getExtraInfoLengthEE(SMALLINT bank, uchar *SNum)
711 {
712    return extraInfoLength;
713 }
714 
715 /**
716  * Query to get a string description of what is contained in
717  * the Extra Informationed return when reading pages in the current
718  * memory bank.  See 'hasExtraInfoEE()'.
719  *
720  * bank     to tell what memory bank of the ibutton to use.
721  * SNum     the serial number for the part.
722  *
723  * @return string describing extra information.
724  */
getExtraInfoDescEE(SMALLINT bank,uchar * SNum)725 char *getExtraInfoDescEE(SMALLINT bank, uchar *SNum)
726 {
727    return extraInfoDesc;
728 }
729 
730 /**
731  * Query to see if current memory bank pages can be read with
732  * the contents being verified by a device generated CRC.
733  * This is used to see if the 'ReadPageCRCEE()' can be used.
734  *
735  * bank     to tell what memory bank of the ibutton to use.
736  * SNum     the serial number for the part.
737  *
738  * @return  'true' if current memory bank can be read with self
739  *          generated CRC.
740  */
hasPageAutoCRCEE(SMALLINT bank,uchar * SNum)741 SMALLINT hasPageAutoCRCEE(SMALLINT bank, uchar *SNum)
742 {
743    return pageAutoCRC;
744 }
745 
746 /**
747  * Query to get Maximum data page length in bytes for a packet
748  * read or written in the current memory bank.  See the 'ReadPagePacket()'
749  * and 'WritePagePacket()' methods.  This method is only usefull
750  * if the current memory bank is general purpose memory.
751  *
752  * @return  max packet page length in bytes in current memory bank
753  */
getMaxPacketDataLengthEE(SMALLINT bank,uchar * SNum)754 SMALLINT getMaxPacketDataLengthEE(SMALLINT bank, uchar *SNum)
755 {
756    return PAGE_LENGTH - 3;
757 }
758 
759 //--------
760 //-------- Bank specific methods
761 //--------
762 
763 
764 /**
765  * Read the scratchpad page of memory from the device
766  * This method reads and returns the entire scratchpad after the byte
767  * offset regardless of the actual ending offset
768  *
769  * portnum       the port number used to reference the port
770  * readBuf       byte array to place read data into
771  *                       length of array is always pageLength.
772  * startAddr     address to start to read from scratchPad
773  * len           length in bytes to read
774  *
775  * @return       'true' if read scratch pad was successful
776  */
readScratchpad(int portnum,uchar * readBuf,int startAddr,int len)777 SMALLINT readScratchpad (int portnum, uchar *readBuf, int startAddr, int len)
778 {
779    int i;
780    uchar raw_buf[2];
781 
782    // select the device
783    if (!owAccess(portnum))
784    {
785       OWERROR(OWERROR_DEVICE_SELECT_FAIL);
786       return FALSE;
787    }
788 
789    // build first block
790    raw_buf[0] = READ_SCRATCHPAD_COMMAND;
791    raw_buf[1] = startAddr;
792 
793    // do the first block for address
794    if(!owBlock(portnum,FALSE,raw_buf,2))
795    {
796       OWERROR(OWERROR_BLOCK_FAILED);
797       return FALSE;
798    }
799 
800    // build the next block
801    for(i=0;i<len;i++)
802       readBuf[i] = 0xFF;
803 
804    // send second block to read data, return result
805    if(!owBlock(portnum,FALSE,readBuf,len))
806    {
807       OWERROR(OWERROR_BLOCK_FAILED);
808       return FALSE;
809    }
810 
811    return TRUE;
812 }
813 
814 /**
815  * Write to the scratchpad page of memory device.
816  *
817  * portnum       the port number used to reference the port
818  * startAddr     starting address
819  * writeBuf      byte array containing data to write
820  * len           length in bytes to write
821  *
822  * @return       'true' if the write to scratch pad was successful
823  */
writeScratchpad(int portnum,int startAddr,uchar * writeBuf,int len)824 SMALLINT writeScratchpad (int portnum,int startAddr, uchar *writeBuf, int len)
825 {
826    int i;
827    uchar raw_buf[64];
828 
829    // select the device
830    if (!owAccess(portnum))
831    {
832       OWERROR(OWERROR_DEVICE_SELECT_FAIL);
833       return FALSE;
834    }
835 
836    // build block to send
837    raw_buf[0] = WRITE_SCRATCHPAD_COMMAND;
838    raw_buf[1] = startAddr & 0xFF;
839 
840    for(i=2;i<len+2;i++)
841       raw_buf[i] = writeBuf[i-2];
842 
843    // send second block to read data, return result
844    if(!owBlock(portnum,FALSE,raw_buf,len+2))
845    {
846       OWERROR(OWERROR_BLOCK_FAILED);
847       return FALSE;
848    }
849 
850    return TRUE;
851 }
852 
853 /**
854  * Copy the scratchpad page to memory.
855  *
856  * portnum       the port number used to reference the port
857  *
858  * @return       'true' if the copy scratchpad was successful
859  */
copyScratchpad(int portnum)860 SMALLINT copyScratchpad(int portnum)
861 {
862 
863    // select the device
864    if (!owAccess(portnum))
865    {
866       OWERROR(OWERROR_DEVICE_SELECT_FAIL);
867       return FALSE;
868    }
869 
870    // copy scratch
871    owWriteByte(portnum,COPY_SCRATCHPAD_COMMAND);
872 
873    // send command and setup strong pullup
874    owWriteBytePower(portnum,0xA5);
875 
876    // delay for 10ms
877    msDelay(10);
878 
879    // disable power
880    owLevel(portnum,MODE_NORMAL);
881 
882    return TRUE;
883 }
884 
885 
886 /**
887  * Query to see if current memory bank pages can be redirected
888  * to another pages.  This is mostly used in Write-Once memory
889  * to provide a means to update.
890  *
891  * bank     to tell what memory bank of the ibutton to use.
892  * SNum     the serial number for the part.
893  *
894  * @return  'true' if current memory bank pages can be redirected
895  *          to a new page.
896  */
canRedirectPageEE(SMALLINT bank,uchar * SNum)897 SMALLINT canRedirectPageEE(SMALLINT bank, uchar *SNum)
898 {
899    return FALSE;
900 }
901 
902 /**
903  * Query to see if current memory bank pages can be locked.  A
904  * locked page would prevent any changes to the memory.
905  *
906  * bank     to tell what memory bank of the ibutton to use.
907  * SNum     the serial number for the part.
908  *
909  * @return  'true' if current memory bank pages can be redirected
910  *          to a new page.
911  */
canLockPageEE(SMALLINT bank,uchar * SNum)912 SMALLINT canLockPageEE(SMALLINT bank, uchar *SNum)
913 {
914    return FALSE;
915 }
916 
917 /**
918  * Query to see if current memory bank pages can be locked from
919  * being redirected.  This would prevent a Write-Once memory from
920  * being updated.
921  *
922  * bank     to tell what memory bank of the ibutton to use.
923  * SNum     the serial number for the part.
924  *
925  * @return  'true' if current memory bank pages can be locked from
926  *          being redirected to a new page.
927  */
canLockRedirectPageEE(SMALLINT bank,uchar * SNum)928 SMALLINT canLockRedirectPageEE(SMALLINT bank, uchar *SNum)
929 {
930    return FALSE;
931 }
932 
933