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