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 //  mbSCR.c - Reads and writes to memory locations for the Scratch memory bank.
28 //  version 1.00
29 //
30 
31 // Include Files
32 #include "ownet.h"
33 #include "mbscr.h"
34 #include "mbscree.h"
35 #include "mbscrex.h"
36 #include "mbscrcrc.h"
37 #include "mbsha.h"
38 
39 // External functions
40 extern SMALLINT owBlock(int,int,uchar *,int);
41 extern SMALLINT owReadByte(int);
42 extern SMALLINT owWriteByte(int,int);
43 extern void     output_status(int, char *);
44 extern void     msDelay(int);
45 extern void     owSerialNum(int,uchar *,int);
46 extern SMALLINT owAccess(int);
47 extern SMALLINT owWriteByte(int,int);
48 extern void     setcrc16(int,ushort);
49 extern ushort   docrc16(int,ushort);
50 extern SMALLINT owWriteBytePower(int,int);
51 extern SMALLINT owLevel(int,int);
52 
53 // General command defines
54 #define READ_MEMORY_COMMAND      0xF0
55 #define WRITE_SCRATCHPAD_COMMAND 0x0F
56 #define READ_SCRATCHPAD_COMMAND  0xAA
57 #define COPY_SCRATCHPAD_COMMAND  0x55
58 
59 // Local defines
60 #define SIZE_SCR        32
61 #define PAGE_LENGTH_SCR 32
62 
63 // Global variables
64 char    *bankDescriptionSCR      = "Scratchpad";
65 SMALLINT writeVerificationSCR    = TRUE;
66 SMALLINT generalPurposeMemorySCR = FALSE;
67 SMALLINT readWriteSCR            = TRUE;
68 SMALLINT writeOnceSCR            = FALSE;
69 SMALLINT readOnlySCR             = FALSE;
70 SMALLINT nonVolatileSCR          = FALSE;
71 SMALLINT needProgramPulseSCR     = FALSE;
72 SMALLINT needPowerDeliverySCR    = FALSE;
73 SMALLINT ExtraInfoSCR            = TRUE;
74 SMALLINT extraInfoLengthSCR      = 3;
75 char    *extraInfoDescSCR        = "Target address, offset";
76 SMALLINT pageAutoCRCSCR          = FALSE;
77 
78 
79 /**
80  * Read  memory in the current bank with no CRC checking (device or
81  * data). The resulting data from this API may or may not be what is on
82  * the 1-Wire device.  It is recommends that the data contain some kind
83  * of checking (CRC) like in the readPagePacketScratch() method or have
84  * the 1-Wire device provide the CRC as in readPageCRCScratch().  readPageCRCScratch()
85  * however is not supported on all memory types, see 'hasPageAutoCRCScratch()'.
86  * If neither is an option then this method could be called more
87  * then once to at least verify that the same thing is read consistantly.
88  *
89  * bank     to tell what memory bank of the ibutton to use.
90  * portnum  the port number of the port being used for the
91  *          1-Wire Network.
92  * SNum     the serial number for the part that the read is
93  *          to be done on.
94  * str_add  starting physical address
95  * rd_cont  if 'true' then device read is continued without
96  *          re-selecting.  This can only be used if the new
97  *          read() continious where the last one led off
98  *          and it is inside a 'beginExclusive/endExclusive'
99  *          block.
100  * buff     byte array to place read data into
101  * len      length in bytes to read
102  *
103  * @return 'true' if the read was complete
104  */
readScratch(SMALLINT bank,int portnum,uchar * SNum,int str_add,SMALLINT rd_cont,uchar * buff,int len)105 SMALLINT readScratch(SMALLINT bank, int portnum, uchar *SNum, int str_add,
106                      SMALLINT rd_cont, uchar *buff, int len)
107 {
108    uchar extra[3];
109    uchar read_buf[PAGE_LENGTH_SCR];
110    int i;
111 
112    // check if read exceeds memory
113    if ((str_add + len) > getSizeScratch(bank,SNum))
114    {
115       OWERROR(OWERROR_READ_OUT_OF_RANGE);
116       return FALSE;
117    }
118 
119    owSerialNum(portnum,SNum,FALSE);
120 
121    // read the scratchpad, discard extra information
122    switch(SNum[0])
123    {
124       case 0x18: case 0x21:
125          if(!readScratchPadCRC(portnum,read_buf,len+str_add,extra))
126             return FALSE;
127          break;
128 
129       default:
130          if(!readScratchpd(portnum,read_buf,len+str_add))
131             return FALSE;
132          break;
133    }
134 
135    for(i=str_add;i<(len+str_add);i++)
136       buff[i-str_add] = read_buf[i];
137 
138    return TRUE;
139 }
140 
141 /**
142  * Write  memory in the current bank.  It is recommended that
143  * when writing  data that some structure in the data is created
144  * to provide error free reading back with readScratch().  Or the
145  * method 'writePagePacketScratch()' could be used which automatically
146  * wraps the data in a length and CRC.
147  *
148  * When using on Write-Once devices care must be taken to write into
149  * into empty space.  If write() is used to write over an unlocked
150  * page on a Write-Once device it will fail.
151  *
152  * bank     to tell what memory bank of the ibutton to use.
153  * portnum  the port number of the port being used for the
154  *          1-Wire Network.
155  * SNum     the serial number for the part that the write is
156  *          to be done on.
157  * str_add  starting address
158  * buff     byte array containing data to write
159  * len      length in bytes to write
160  *
161  * @return 'true' if the write was complete.
162  */
writeScratch(SMALLINT bank,int portnum,uchar * SNum,int str_add,uchar * buff,int len)163 SMALLINT writeScratch(SMALLINT bank, int portnum, uchar *SNum, int str_add,
164                       uchar *buff, int len)
165 {
166    int i;
167    uchar raw_buf[PAGE_LENGTH_SCR];
168    uchar extra[3];
169 
170    // return if nothing to do
171    if (len == 0)
172       return TRUE;
173 
174    // check if write exceeds memory
175    if(len > getSizeScratch(bank,SNum))
176    {
177       OWERROR(OWERROR_WRITE_OUT_OF_RANGE);
178       return FALSE;
179    }
180 
181    owSerialNum(portnum,SNum,FALSE);
182 
183    // write the page of data to scratchpad
184    switch(SNum[0])
185    {
186       case 0x18:
187          if(!writeScratchPadSHA(portnum,str_add,buff,len))
188             return FALSE;
189          break;
190 
191       case 0x21:
192          if(!writeScratchPadEx(portnum,str_add,buff,len))
193             return FALSE;
194          break;
195 
196       case 0x23:
197          if(!writeScratchPadEE(portnum,str_add,buff,len))
198             return FALSE;
199          break;
200 
201       default:
202          if(!writeScratchpd(portnum,str_add,buff,len))
203             return FALSE;
204          break;
205    }
206 
207    // read to verify ok
208    switch(SNum[0])
209    {
210       case 0x18: case 0x21:
211          if(readScratchPadCRC(portnum,raw_buf,PAGE_LENGTH_SCR,extra))
212             return FALSE;
213          break;
214 
215       default:
216          if(!readScratchpdExtra(portnum,raw_buf,PAGE_LENGTH_SCR,extra))
217             return FALSE;
218          break;
219    }
220 
221    // check to see if the same
222    for (i=0;i<len;i++)
223       if(raw_buf[i] != buff[i])
224       {
225          OWERROR(OWERROR_READ_SCRATCHPAD_VERIFY);
226          return FALSE;
227       }
228 
229    // check to make sure that the address is correct
230    if ((((extra[0] & 0x00FF) | ((extra[1] << 8) & 0x00FF00))
231            & 0x00FFFF) != str_add)
232    {
233       OWERROR(OWERROR_ADDRESS_READ_BACK_FAILED);
234       return FALSE;
235    }
236 
237    return TRUE;
238 }
239 
240 /**
241  * Read  page in the current bank with no
242  * CRC checking (device or data). The resulting data from this API
243  * may or may not be what is on the 1-Wire device.  It is recommends
244  * that the data contain some kind of checking (CRC) like in the
245  * readPagePacketScratch() method or have the 1-Wire device provide the
246  * CRC as in readPageCRCScratch().  readPageCRCScratch() however is not
247  * supported on all memory types, see 'hasPageAutoCRCScratch()'.
248  * If neither is an option then this method could be called more
249  * then once to at least verify that the same thing is read consistantly.
250  *
251  * bank     to tell what memory bank of the ibutton to use.
252  * portnum  the port number of the port being used for the
253  *          1-Wire Network.
254  * SNum     the serial number for the part.
255  * page     the page to read
256  * rd_cont  if 'true' then device read is continued without
257  *          re-selecting.  This can only be used if the new
258  *          read() continious where the last one led off
259  *          and it is inside a 'beginExclusive/endExclusive'
260  *          block.
261  * buff     byte array containing data that was read.
262  * len      length in bytes to write
263  *
264  * @return - returns '0' if the read page wasn't completed.
265  *                   '1' if the operation is complete.
266  */
readPageScratch(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff)267 SMALLINT readPageScratch(SMALLINT bank, int portnum, uchar *SNum, int page,
268                          SMALLINT rd_cont, uchar *buff)
269 {
270    if(page != 0)
271    {
272       OWERROR(OWERROR_INVALID_PAGE_NUMBER);
273       return FALSE;
274    }
275 
276    return readScratch(bank,portnum,SNum,page,rd_cont,buff,PAGE_LENGTH_SCR);
277 }
278 
279 /**
280  * Read  page with extra information in the current bank with no
281  * CRC checking (device or data). The resulting data from this API
282  * may or may not be what is on the 1-Wire device.  It is recommends
283  * that the data contain some kind of checking (CRC) like in the
284  * readPagePacketScratch() method or have the 1-Wire device provide the
285  * CRC as in readPageCRCScratch().  readPageCRCScratch() however is not
286  * supported on all memory types, see 'hasPageAutoCRCScratch()'.
287  * If neither is an option then this method could be called more
288  * then once to at least verify that the same thing is read consistantly.
289  * See the method 'hasExtraInfoScratch()' for a description of the optional
290  * extra information some devices have.
291  *
292  * bank     to tell what memory bank of the ibutton to use.
293  * portnum  the port number of the port being used for the
294  *          1-Wire Network.
295  * SNum     the serial number for the part.
296  * page     the page to read
297  * rd_cont  if 'true' then device read is continued without
298  *          re-selecting.  This can only be used if the new
299  *          read() continious where the last one led off
300  *          and it is inside a 'beginExclusive/endExclusive'
301  *          block.
302  * buff     byte array containing data that was read
303  * len      length in bytes to write
304  * extra    the extra information
305  *
306  * @return - returns '0' if the read page wasn't completed with extra info.
307  *                   '1' if the operation is complete.
308  */
readPageExtraScratch(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff,uchar * extra)309 SMALLINT readPageExtraScratch(SMALLINT bank, int portnum, uchar *SNum, int page,
310                               SMALLINT rd_cont, uchar *buff, uchar *extra)
311 {
312    // check if read exceeds memory
313    if(page != 0)
314    {
315       OWERROR(OWERROR_INVALID_PAGE_NUMBER);
316       return FALSE;
317    }
318 
319    owSerialNum(portnum,SNum,FALSE);
320 
321    // read the scratchpad, discard extra information
322    switch(SNum[0])
323    {
324       case 0x18: case 0x21:
325          if(!readPageExtraScratchCRC(bank,portnum,SNum,page,FALSE,buff,extra))
326             return FALSE;
327          break;
328 
329       default:
330          if(!readScratchpdExtra(portnum,buff,PAGE_LENGTH_SCR,extra))
331             return FALSE;
332          break;
333    }
334 
335    return TRUE;
336 }
337 
338 /**
339  * Read a complete memory page with CRC verification provided by the
340  * device with extra information.  Not supported by all devices.
341  * See the method 'hasPageAutoCRC()'.
342  * See the method 'haveExtraInfo()' for a description of the optional
343  * extra information.
344  *
345  * bank     to tell what memory bank of the ibutton to use.
346  * portnum  the port number of the port being used for the
347  *          1-Wire Network.
348  * SNum     the serial number for the part.
349  * page     the page to read
350  * buff     byte array containing data that was read.
351  * extra    the extra information
352  *
353  * @return - returns '0' if the read page wasn't completed with extra info.
354  *                   '1' if the operation is complete.
355  */
readPageExtraCRCScratch(SMALLINT bank,int portnum,uchar * SNum,int page,uchar * read_buff,uchar * extra)356 SMALLINT readPageExtraCRCScratch(SMALLINT bank, int portnum, uchar *SNum, int page,
357                                  uchar *read_buff, uchar *extra)
358 {
359    switch(SNum[0])
360    {
361       case 0x21: case 0x18:
362          if(!readPageExtraScratchCRC(bank,portnum,SNum,page,FALSE,read_buff,extra))
363             return FALSE;
364          break;
365 
366       default:
367          OWERROR(OWERROR_CRC_EXTRA_INFO_NOT_SUPPORTED);
368          return FALSE;
369          break;
370    }
371 
372    return TRUE;
373 }
374 /**
375  * Read a complete memory page with CRC verification provided by the
376  * device.  Not supported by all devices.  See the method
377  * 'hasPageAutoCRCScratch()'.
378  *
379  * bank     to tell what memory bank of the ibutton to use.
380  * portnum  the port number of the port being used for the
381  *          1-Wire Network.
382  * SNum     the serial number for the part.
383  * page     the page to read
384  * buff     byte array containing data that was read
385  *
386  * @return - returns '0' if the read page wasn't completed.
387  *                   '1' if the operation is complete.
388  */
readPageCRCScratch(SMALLINT bank,int portnum,uchar * SNum,int page,uchar * buff)389 SMALLINT readPageCRCScratch(SMALLINT bank, int portnum, uchar *SNum, int page, uchar *buff)
390 {
391    switch(SNum[0])
392    {
393       case 0x21: case 0x18:
394          if(!readPageScratchCRC(bank,portnum,SNum,page,FALSE,buff))
395             return FALSE;
396          break;
397 
398       default:
399          OWERROR(OWERROR_CRC_NOT_SUPPORTED);
400          return FALSE;
401          break;
402    }
403 
404    return TRUE;
405 }
406 
407 /**
408  * Read a Universal Data Packet.
409  *
410  * The Universal Data Packet always starts on page boundaries but
411  * can end anywhere in the page.  The structure specifies the length of
412  * data bytes not including the length byte and the CRC16 bytes.
413  * There is one length byte. The CRC16 is first initialized to
414  * the page number.  This provides a check to verify the page that
415  * was intended is being read.  The CRC16 is then calculated over
416  * the length and data bytes.  The CRC16 is then inverted and stored
417  * low byte first followed by the high byte.  This is structure is
418  * used by this method to verify the data but is not returned, only
419  * the data payload is returned.
420  *
421  * bank     to tell what memory bank of the ibutton to use.
422  * portnum  the port number of the port being used for the
423  *          1-Wire Network.
424  * SNum     the serial number for the part.
425  * page     the page to read
426  * rd_cont  if 'true' then device read is continued without
427  *          re-selecting.  This can only be used if the new
428  *          read() continious where the last one led off
429  *          and it is inside a 'beginExclusive/endExclusive'
430  *          block.
431  * buff     byte array containing data that was read.
432  * len      length of the packet
433  *
434  * @return - returns '0' if the read page packet wasn't completed
435  *                   '1' if the operation is complete.
436  */
readPagePacketScratch(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff,int * len)437 SMALLINT readPagePacketScratch(SMALLINT bank, int portnum, uchar *SNum, int page,
438                                SMALLINT rd_cont, uchar *buff, int *len)
439 {
440    uchar raw_buf[PAGE_LENGTH_SCR];
441    int i;
442    ushort lastcrc16;
443 
444    // read the scratchpad, discard extra information
445    if(!readScratch(bank,portnum,SNum,0,rd_cont,raw_buf,PAGE_LENGTH_SCR))
446       return FALSE;
447 
448    // check if length is realistic
449    if((raw_buf[0] > (PAGE_LENGTH_SCR-3)) || (raw_buf[0] <= 0))
450    {
451       OWERROR(OWERROR_INVALID_PACKET_LENGTH);
452       return FALSE;
453    }
454 
455    // verify the CRC is correct
456    setcrc16(portnum,(ushort)((getStartingAddressScratch(bank,SNum)/PAGE_LENGTH_SCR) + page));
457    for(i=0;i<raw_buf[0]+3;i++)
458       lastcrc16 = docrc16(portnum,raw_buf[i]);
459 
460    if(lastcrc16 == 0xB001)
461    {
462       // extract the data out of the packet
463       for(i=1;i<raw_buf[0]+1;i++)
464          buff[i-1] = raw_buf[i];
465 
466       // return the length
467       *len = (int) raw_buf[0];
468    }
469    else
470    {
471       OWERROR(OWERROR_CRC_FAILED);
472       return FALSE;
473    }
474 
475    return TRUE;
476 }
477 
478 /**
479  * Read a Universal Data Packet and extra information.  See the
480  * method 'readPagePacketScratch()' for a description of the packet structure.
481  * See the method 'hasExtraInfoScratch()' for a description of the optional
482  * extra information some devices have.
483  *
484  * bank     to tell what memory bank of the ibutton to use.
485  * portnum  the port number of the port being used for the
486  *          1-Wire Network.
487  * SNum     the serial number for the part.
488  * page     the page to read
489  * rd_cont  if 'true' then device read is continued without
490  *          re-selecting.  This can only be used if the new
491  *          read() continious where the last one led off
492  *          and it is inside a 'beginExclusive/endExclusive'
493  *          block.
494  * buff     byte array containing data that was read.
495  * len      length of the packet
496  * extra    extra information
497  *
498  * @return - returns '0' if the read page packet wasn't completed
499  *                   '1' if the operation is complete.
500  */
readPagePacketExtraScratch(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff,int * len,uchar * extra)501 SMALLINT readPagePacketExtraScratch(SMALLINT bank, int portnum, uchar *SNum,
502                                     int page, SMALLINT rd_cont, uchar *buff,
503                                     int *len, uchar *extra)
504 {
505    uchar raw_buf[PAGE_LENGTH_SCR];
506    int i;
507    ushort lastcrc16;
508 
509    // read the scratchpad, discard extra information
510    switch(SNum[0])
511    {
512       case 0x18: case 0x21:
513          if(readScratchPadCRC(portnum,&raw_buf[0],page,extra))
514             return FALSE;
515          break;
516 
517       default:
518          if(!readScratchpdExtra(portnum,&raw_buf[0],page,extra))
519             return FALSE;
520    }
521 
522    // check if length is realistic
523    if((raw_buf[0] > (PAGE_LENGTH_SCR-3)) || (raw_buf[0] <= 0))
524    {
525       OWERROR(OWERROR_INVALID_PACKET_LENGTH);
526       return FALSE;
527    }
528 
529    // verify the CRC is correct
530    setcrc16(portnum,(ushort)((getStartingAddressScratch(bank,SNum)/PAGE_LENGTH_SCR) + page));
531    for(i=0;i<raw_buf[0]+3;i++)
532       lastcrc16 = docrc16(portnum,raw_buf[i]);
533 
534    if(lastcrc16 == 0xB001)
535    {
536       // extract the data out of the packet
537       for(i=1;i<raw_buf[0]+1;i++)
538          buff[i-1] = raw_buf[i];
539 
540       // return the length
541       *len = (int) raw_buf[0];
542    }
543    else
544    {
545       OWERROR(OWERROR_CRC_FAILED);
546       return FALSE;
547    }
548 
549    return TRUE;
550 }
551 
552 /**
553  * Write a Universal Data Packet.  See the method 'readPagePacketScratch()'
554  * for a description of the packet structure.
555  *
556  * bank     to tell what memory bank of the ibutton to use.
557  * portnum  the port number of the port being used for the
558  *          1-Wire Network.
559  * SNum     the serial number for the part.
560  * page     the page the packet is being written to.
561  * rd_cont  if 'true' then device read is continued without
562  *          re-selecting.  This can only be used if the new
563  *          read() continious where the last one led off
564  *          and it is inside a 'beginExclusive/endExclusive'
565  *          block.
566  * buff     byte array containing data that to write.
567  * len      length of the packet
568  *
569  * @return - returns '0' if the write page packet wasn't completed
570  *                   '1' if the operation is complete.
571  */
writePagePacketScratch(SMALLINT bank,int portnum,uchar * SNum,int page,uchar * buff,int len)572 SMALLINT writePagePacketScratch(SMALLINT bank, int portnum, uchar *SNum, int page,
573                                 uchar *buff, int len)
574 {
575    uchar raw_buf[64];
576    int i;
577    ushort crc;
578 
579    // make sure length does not exceed max
580    if ((len > (PAGE_LENGTH_SCR - 3)) || (len <= 0))
581    {
582       OWERROR(OWERROR_PACKET_LENGTH_EXCEEDS_PAGE);
583       return FALSE;
584    }
585 
586    // see if this bank is general read/write
587    if (!isGeneralPurposeMemoryScratch(bank,SNum))
588    {
589       OWERROR(OWERROR_NOT_GENERAL_PURPOSE);
590       return FALSE;
591    }
592 
593    // construct the packet to write
594    raw_buf[0] = (uchar) len + 3;
595 
596    for(i=1;i<len+1;i++)
597       raw_buf[i] = buff[i-1];
598 
599    setcrc16(portnum,(ushort)((getStartingAddressScratch(bank,SNum)/PAGE_LENGTH_SCR) + page));
600    for(i=0;i<len+1;i++)
601       crc = docrc16(portnum,raw_buf[i]);
602 
603    raw_buf[len + 1] = (uchar) ~crc & 0xFF;
604    raw_buf[len + 2] = (uchar) ((~crc & 0xFFFF) >> 8) & 0xFF;
605 
606    // write the packet, return result
607    if(!writeScratch(bank,portnum,SNum,page,raw_buf,len+3))
608       return FALSE;
609 
610    return TRUE;
611 }
612 
613 /**
614  * Query to get the number of pages in current memory bank.
615  *
616  * bank     to tell what memory bank of the ibutton to use.
617  * SNum     the serial number for the part.
618  *
619  * @return  number of pages in current memory bank
620  */
getNumberPagesScratch(SMALLINT bank,uchar * SNum)621 SMALLINT getNumberPagesScratch(SMALLINT bank, uchar *SNum)
622 {
623    return 1;
624 }
625 
626 /**
627  * Query to get the memory bank size in bytes.
628  *
629  * bank     to tell what memory bank of the ibutton to use.
630  * SNum     the serial number for the part.
631  *
632  * @return  memory bank size in bytes.
633  */
getSizeScratch(SMALLINT bank,uchar * SNum)634 int getSizeScratch(SMALLINT bank, uchar *SNum)
635 {
636    return SIZE_SCR;
637 }
638 
639 /**
640  * Query to get the starting physical address of this bank.  Physical
641  * banks are sometimes sub-divided into logical banks due to changes
642  * in attributes.
643  *
644  * bank     to tell what memory bank of the ibutton to use.
645  * SNum     the serial number for the part.
646  *
647  * @return  physical starting address of this logical bank.
648  */
getStartingAddressScratch(SMALLINT bank,uchar * SNum)649 int getStartingAddressScratch(SMALLINT bank, uchar *SNum)
650 {
651    return 0;
652 }
653 
654 /**
655  * Query to get page length in bytes in current memory bank.
656  *
657  * bank     to tell what memory bank of the ibutton to use.
658  * SNum     the serial number for the part.
659  *
660  * @return   page length in bytes in current memory bank
661  */
getPageLengthScratch(SMALLINT bank,uchar * SNum)662 SMALLINT getPageLengthScratch(SMALLINT bank, uchar *SNum)
663 {
664    return PAGE_LENGTH_SCR;
665 }
666 
667 /**
668  * Query to see get a string description of the current memory bank.
669  *
670  * bank     to tell what memory bank of the ibutton to use.
671  * SNum     the serial number for the part.
672  *
673  * @return  String containing the memory bank description
674  */
getBankDescriptionScratch(SMALLINT bank,uchar * SNum)675 char *getBankDescriptionScratch(SMALLINT bank, uchar *SNum)
676 {
677    switch(SNum[0])
678    {
679       case 0x18:
680          return getBankDescriptionScratchSHA(bank,SNum);
681          break;
682 
683       case 0x1A: case 0x1D:
684          return getBankDescriptionScratchEx(bank,SNum);
685          break;
686 
687       case 0x23:
688          return getBankDescriptionScratchCRC(bank,SNum);
689          break;
690 
691       default:
692          return bankDescriptionSCR;
693          break;
694    }
695 
696    return "No description given.";
697 }
698 
699 /**
700  * Query to see if the current memory bank is general purpose
701  * user memory.  If it is NOT then it is Memory-Mapped and writing
702  * values to this memory will affect the behavior of the 1-Wire
703  * device.
704  *
705  * bank     to tell what memory bank of the ibutton to use.
706  * SNum     the serial number for the part.
707  *
708  * @return  'true' if current memory bank is general purpose
709  */
isGeneralPurposeMemoryScratch(SMALLINT bank,uchar * SNum)710 SMALLINT isGeneralPurposeMemoryScratch(SMALLINT bank, uchar *SNum)
711 {
712    return generalPurposeMemorySCR;
713 }
714 
715 /**
716  * Query to see if current memory bank is read/write.
717  *
718  * bank     to tell what memory bank of the ibutton to use.
719  * SNum     the serial number for the part.
720  *
721  * @return  'true' if current memory bank is read/write
722  */
isReadWriteScratch(SMALLINT bank,int portnum,uchar * SNum)723 SMALLINT isReadWriteScratch(SMALLINT bank, int portnum, uchar *SNum)
724 {
725    return readWriteSCR;
726 }
727 
728 /**
729  * Query to see if current memory bank is write write once such
730  * as with EPROM technology.
731  *
732  * bank     to tell what memory bank of the ibutton to use.
733  * SNum     the serial number for the part.
734  *
735  * @return  'true' if current memory bank can only be written once
736  */
isWriteOnceScratch(SMALLINT bank,int portnum,uchar * SNum)737 SMALLINT isWriteOnceScratch(SMALLINT bank, int portnum, uchar *SNum)
738 {
739    return writeOnceSCR;
740 }
741 
742 /**
743  * Query to see if current memory bank is read only.
744  *
745  * @return  'true' if current memory bank can only be read
746  */
isReadOnlyScratch(SMALLINT bank,int portnum,uchar * SNum)747 SMALLINT isReadOnlyScratch(SMALLINT bank, int portnum, uchar *SNum)
748 {
749    return readOnlySCR;
750 }
751 
752 /**
753  * Query to see if current memory bank non-volatile.  Memory is
754  * non-volatile if it retains its contents even when removed from
755  * the 1-Wire network.
756  *
757  * bank     to tell what memory bank of the ibutton to use.
758  * SNum     the serial number for the part.
759  *
760  * @return  'true' if current memory bank non volatile.
761  */
isNonVolatileScratch(SMALLINT bank,uchar * SNum)762 SMALLINT isNonVolatileScratch(SMALLINT bank, uchar *SNum)
763 {
764    return nonVolatileSCR;
765 }
766 
767 /**
768  * Query to see if current memory bank pages need the adapter to
769  * have a 'ProgramPulse' in order to write to the memory.
770  *
771  * bank     to tell what memory bank of the ibutton to use.
772  * SNum     the serial number for the part.
773  *
774  * @return  'true' if writing to the current memory bank pages
775  *                 requires a 'ProgramPulse'.
776  */
needsProgramPulseScratch(SMALLINT bank,uchar * SNum)777 SMALLINT needsProgramPulseScratch(SMALLINT bank, uchar *SNum)
778 {
779    return needProgramPulseSCR;
780 }
781 
782 /**
783  * Query to see if current memory bank pages need the adapter to
784  * have a 'PowerDelivery' feature in order to write to the memory.
785  *
786  * bank     to tell what memory bank of the ibutton to use.
787  * SNum     the serial number for the part.
788  *
789  * @return  'true' if writing to the current memory bank pages
790  *                 requires 'PowerDelivery'.
791  */
needsPowerDeliveryScratch(SMALLINT bank,uchar * SNum)792 SMALLINT needsPowerDeliveryScratch(SMALLINT bank, uchar *SNum)
793 {
794    SMALLINT ret;
795 
796    switch(SNum[0])
797    {
798       case 0x23:
799          ret = TRUE;
800          break;
801 
802       default:
803          ret = needPowerDeliverySCR;
804          break;
805    }
806 
807    return ret;
808 }
809 
810 /**
811  * Checks to see if this memory bank's pages deliver extra
812  * information outside of the normal data space,  when read.  Examples
813  * of this may be a redirection byte, counter, tamper protection
814  * bytes, or SHA-1 result.  If this method returns true then the
815  * methods with an 'extraInfo' parameter can be used.
816  *
817  * bank     to tell what memory bank of the ibutton to use.
818  * SNum     the serial number for the part.
819  *
820  * @return  true if reading the this memory bank's
821  *               pages provides extra information
822  */
hasExtraInfoScratch(SMALLINT bank,uchar * SNum)823 SMALLINT hasExtraInfoScratch(SMALLINT bank, uchar *SNum)
824 {
825    return ExtraInfoSCR;
826 }
827 
828 /**
829  * Query to get the length in bytes of extra information that
830  * is read when read a page in the current memory bank.  See
831  * 'hasExtraInfoScratch()'.
832  *
833  * bank     to tell what memory bank of the ibutton to use.
834  * SNum     the serial number for the part.
835  *
836  * @return  number of bytes in Extra Information read when reading
837  *          pages in the current memory bank.
838  */
getExtraInfoLengthScratch(SMALLINT bank,uchar * SNum)839 SMALLINT getExtraInfoLengthScratch(SMALLINT bank, uchar *SNum)
840 {
841    return extraInfoLengthSCR;
842 }
843 
844 /**
845  * Query to get a string description of what is contained in
846  * the Extra Informationed return when reading pages in the current
847  * memory bank.  See 'hasExtraInfoScratch()'.
848  *
849  * bank     to tell what memory bank of the ibutton to use.
850  * SNum     the serial number for the part.
851  *
852  * @return string describing extra information.
853  */
getExtraInfoDescScratch(SMALLINT bank,uchar * SNum)854 char *getExtraInfoDescScratch(SMALLINT bank, uchar *SNum)
855 {
856    return extraInfoDescSCR;
857 }
858 
859 /**
860  * Query to see if current memory bank pages can be read with
861  * the contents being verified by a device generated CRC.
862  * This is used to see if the 'ReadPageCRCScratch()' can be used.
863  *
864  * bank     to tell what memory bank of the ibutton to use.
865  * SNum     the serial number for the part.
866  *
867  * @return  'true' if current memory bank can be read with self
868  *          generated CRC.
869  */
hasPageAutoCRCScratch(SMALLINT bank,uchar * SNum)870 SMALLINT hasPageAutoCRCScratch(SMALLINT bank, uchar *SNum)
871 {
872    SMALLINT ret;
873 
874    switch(SNum[0])
875    {
876       case 0x21: case 0x18:
877          ret = hasPageAutoCRCScratchCRC(bank,SNum);
878          break;
879 
880       default:
881          ret = pageAutoCRCSCR;
882          break;
883    }
884 
885    return ret;
886 }
887 
888 /**
889  * Query to get Maximum data page length in bytes for a packet
890  * read or written in the current memory bank.  See the 'ReadPagePacket()'
891  * and 'WritePagePacket()' methods.  This method is only usefull
892  * if the current memory bank is general purpose memory.
893  *
894  * @return  max packet page length in bytes in current memory bank
895  */
getMaxPacketDataLengthScratch(SMALLINT bank,uchar * SNum)896 SMALLINT getMaxPacketDataLengthScratch(SMALLINT bank, uchar *SNum)
897 {
898    return PAGE_LENGTH_SCR - 3;
899 }
900 
901 //--------
902 //-------- Bank specific methods
903 //--------
904 
905 /**
906  * Query to see if current memory bank pages can be redirected
907  * to another pages.  This is mostly used in Write-Once memory
908  * to provide a means to update.
909  *
910  * bank     to tell what memory bank of the ibutton to use.
911  * SNum     the serial number for the part.
912  *
913  * @return  'true' if current memory bank pages can be redirected
914  *          to a new page.
915  */
canRedirectPageScratch(SMALLINT bank,uchar * SNum)916 SMALLINT canRedirectPageScratch(SMALLINT bank, uchar *SNum)
917 {
918    return FALSE;
919 }
920 
921 /**
922  * Query to see if current memory bank pages can be locked.  A
923  * locked page would prevent any changes to the memory.
924  *
925  * bank     to tell what memory bank of the ibutton to use.
926  * SNum     the serial number for the part.
927  *
928  * @return  'true' if current memory bank pages can be redirected
929  *          to a new page.
930  */
canLockPageScratch(SMALLINT bank,uchar * SNum)931 SMALLINT canLockPageScratch(SMALLINT bank, uchar *SNum)
932 {
933    return FALSE;
934 }
935 
936 /**
937  * Query to see if current memory bank pages can be locked from
938  * being redirected.  This would prevent a Write-Once memory from
939  * being updated.
940  *
941  * bank     to tell what memory bank of the ibutton to use.
942  * SNum     the serial number for the part.
943  *
944  * @return  'true' if current memory bank pages can be locked from
945  *          being redirected to a new page.
946  */
canLockRedirectPageScratch(SMALLINT bank,uchar * SNum)947 SMALLINT canLockRedirectPageScratch(SMALLINT bank, uchar *SNum)
948 {
949    return FALSE;
950 }
951 
952 //--------
953 //-------- ScratchPad methods
954 //--------
955 
956 /**
957  * Read the scratchpad page of memory from a NV device
958  * This method reads and returns the entire scratchpad after the byte
959  * offset regardless of the actual ending offset
960  *
961  * portnum       the port number of the port being used for the
962  *               1-Wire Network.
963  * readBuf       byte array to place read data into
964  *                       length of array is always pageLength.
965  * str_add       offset into readBuf to pug data
966  * len           length in bytes to read
967  * extraInfo     byte array to put extra info read into
968  *               (TA1, TA2, e/s byte)
969  *               length of array is always extraInfoLength.
970  *               Can be 'null' if extra info is not needed.
971  *
972  * @return  'true' if reading scratch pad was successfull.
973  */
readScratchpd(int portnum,uchar * buff,int len)974 SMALLINT readScratchpd(int portnum, uchar *buff, int len)
975 {
976    int i;
977    uchar raw_buf[4];
978 
979    // select the device
980    if(!owAccess(portnum))
981    {
982       OWERROR(OWERROR_DEVICE_SELECT_FAIL);
983       return FALSE;
984    }
985 
986    // build first block
987    raw_buf[0] = READ_SCRATCHPAD_COMMAND;
988 
989    for(i=1;i<extraInfoLengthSCR+1;i++)
990       raw_buf[i] = 0xFF;
991 
992    // do the first block for TA1, TA2, and E/S
993    if(!owBlock(portnum,FALSE,raw_buf,extraInfoLengthSCR+1))
994    {
995       OWERROR(OWERROR_BLOCK_FAILED);
996       return FALSE;
997    }
998 
999    // build the next block
1000    for(i=0;i<len;i++)
1001       buff[i] = 0xFF;
1002 
1003    // send second block to read data, return result
1004    if(!owBlock(portnum,FALSE,buff,len))
1005    {
1006       OWERROR(OWERROR_BLOCK_FAILED);
1007       return FALSE;
1008    }
1009 
1010    return TRUE;
1011 }
1012 
1013 /**
1014  * Read the scratchpad page of memory from a NV device
1015  * This method reads and returns the entire scratchpad after the byte
1016  * offset regardless of the actual ending offset
1017  *
1018  * portnum       the port number of the port being used for the
1019  *               1-Wire Network.
1020  * readBuf       byte array to place read data into
1021  *                       length of array is always pageLength.
1022  * str_add       offset into readBuf to pug data
1023  * len           length in bytes to read
1024  * extraInfo     byte array to put extra info read into
1025  *               (TA1, TA2, e/s byte)
1026  *               length of array is always extraInfoLength.
1027  *               Can be 'null' if extra info is not needed.
1028  *
1029  * @return  'true' if reading scratch pad was successfull.
1030  */
readScratchpdExtra(int portnum,uchar * buff,int len,uchar * extra)1031 SMALLINT readScratchpdExtra(int portnum, uchar *buff, int len, uchar *extra)
1032 {
1033    int i;
1034    uchar raw_buf[PAGE_LENGTH_SCR+4];
1035 
1036    // select the device
1037    if(!owAccess(portnum))
1038    {
1039       OWERROR(OWERROR_DEVICE_SELECT_FAIL);
1040       return FALSE;
1041    }
1042 
1043    // build first block
1044    raw_buf[0] = READ_SCRATCHPAD_COMMAND;
1045 
1046    for(i=1;i<extraInfoLengthSCR+1;i++)
1047       raw_buf[i] = 0xFF;
1048 
1049    // do the first block for TA1, TA2, and E/S
1050    if(!owBlock(portnum,FALSE,raw_buf,extraInfoLengthSCR+1))
1051    {
1052       OWERROR(OWERROR_BLOCK_FAILED);
1053       return FALSE;
1054    }
1055 
1056    for(i=0;i<len;i++)
1057       buff[i] = 0xFF;
1058 
1059    if(!owBlock(portnum,FALSE,buff,len))
1060    {
1061       OWERROR(OWERROR_BLOCK_FAILED);
1062       return FALSE;
1063    }
1064    for(i=1;i<extraInfoLengthSCR+1;i++)
1065       extra[i-1] = raw_buf[i];
1066 
1067    return TRUE;
1068 }
1069 
1070 /**
1071  * Write to the scratchpad page of memory a NV device.
1072  *
1073  * @param  startAddr     starting address
1074  * @param  writeBuf      byte array containing data to write
1075  * @param  offset        offset into readBuf to place data
1076  * @param  len           length in bytes to write
1077  *
1078  * @return 'true' if writing was successful
1079  */
writeScratchpd(int portnum,int str_add,uchar * writeBuf,int len)1080 SMALLINT writeScratchpd(int portnum,int str_add, uchar *writeBuf, int len)
1081 {
1082    uchar raw_buf[PAGE_LENGTH_SCR+3];
1083    int i;
1084 
1085    // select the device
1086    if (!owAccess(portnum))
1087    {
1088       OWERROR(OWERROR_DEVICE_SELECT_FAIL);
1089       return FALSE;
1090    }
1091 
1092    // build block to send
1093    raw_buf[0] = WRITE_SCRATCHPAD_COMMAND;
1094    raw_buf[1] = (uchar) str_add & 0xFF;
1095    raw_buf[2] = (uchar) ((str_add & 0xFFFF) >> 8) & 0xFF;
1096 
1097    for(i=0;i<len;i++)
1098       raw_buf[i+3] = writeBuf[i];
1099 
1100    // send block, return result
1101    if(!owBlock(portnum,FALSE,&raw_buf[0],len + 3))
1102    {
1103       OWERROR(OWERROR_BLOCK_FAILED);
1104       return FALSE;
1105    }
1106 
1107    return TRUE;
1108 }
1109 
1110 /**
1111  * Copy the scratchpad page to memory.
1112  *
1113  * portnum       the port number of the port being used for the
1114  *               1-Wire Network.
1115  * str_add       starting address
1116  * len           length in bytes that was written already
1117  *
1118  * @return       'true' if the coping was successful.
1119  */
copyScratchpd(int portnum,int str_add,int len)1120 SMALLINT copyScratchpd (int portnum, int str_add, int len)
1121 {
1122    uchar raw_buf[5];
1123 
1124    // select the device
1125    if (!owAccess(portnum))
1126    {
1127       OWERROR(OWERROR_DEVICE_SELECT_FAIL);
1128       return FALSE;
1129    }
1130 
1131    // build block to send
1132    raw_buf[0] = COPY_SCRATCHPAD_COMMAND;
1133    raw_buf[1] = str_add & 0xFF;
1134    raw_buf[2] = ((str_add & 0xFFFF) >> 8) & 0xFF;
1135    raw_buf[3] = (str_add + len - 1) & 0x1F;
1136    raw_buf[4] = 0xFF;
1137 
1138    // send block (check copy indication complete)
1139    if(!owBlock(portnum,FALSE,raw_buf,5))
1140    {
1141       OWERROR(OWERROR_BLOCK_FAILED);
1142       return FALSE;
1143    }
1144 
1145    if((raw_buf[4] & 0x0F0) != 0)
1146    {
1147       OWERROR(OWERROR_COPY_SCRATCHPAD_NOT_FOUND);
1148       return FALSE;
1149    }
1150 
1151    return TRUE;
1152 }
1153 
1154