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 // mbAppReg.c - Reads and writes to memory locations for the AppReg memory bank.
28 // version 1.00
29 //
30
31 // Include Files
32 #include "ownet.h"
33 #include "mbappreg.h"
34
35 // External functions
36 extern SMALLINT owBlock(int,int,uchar *,int);
37 extern void setcrc8(int,uchar);
38 extern uchar docrc8(int,uchar);
39 extern SMALLINT owReadByte(int);
40 extern SMALLINT owWriteByte(int,int);
41 extern void msDelay(int);
42 extern void owSerialNum(int,uchar *,int);
43 extern SMALLINT owAccess(int);
44 extern void setcrc16(int,ushort);
45 extern ushort docrc16(int,ushort);
46
47
48 // Local functions
49 SMALLINT readStatus(int portnum, uchar *extra);
50 // OTP Local functions
51 SMALLINT lockPageAppReg();
52 SMALLINT isPageLockedAppReg();
53 SMALLINT redirectPageAppReg();
54 SMALLINT isPageRedirectedAppReg();
55 SMALLINT getRedirectPageAppReg();
56 SMALLINT lockRedirectPageAppReg();
57
58 // General command defines
59 #define READ_MEMORY_COMMAND 0xC3
60 #define WRITE_MEMORY_COMMAND 0x99
61 #define COPY_LOCK_COMMAND 0x5A
62 #define READ_STATUS_COMMAND 0x66
63 #define VALIDATION_KEY 0xA5
64 #define LOCKED_FLAG 0xFC
65 // Local defines
66 #define SIZE 8
67 #define PAGE_LENGTH 8
68
69 // Global variables
70 char *bankDescriptionAR = "Application register, non-volatile when locked.";
71 SMALLINT writeVerificationAR = TRUE;
72 SMALLINT generalPurposeMemoryAR = TRUE;
73 SMALLINT readWriteAR = TRUE;
74 SMALLINT writeOnceAR = FALSE;
75 SMALLINT readOnlyAR = FALSE;
76 SMALLINT nonVolatileAR = FALSE;
77 SMALLINT needsProgramPulseAR = FALSE;
78 SMALLINT needsPowerDeliveryAR = TRUE;
79 SMALLINT hasExtraInfoAR = TRUE;
80 SMALLINT extraInfoLengthAR = 1;
81 char *extraInfoDescAR = "Page Locked Flag";
82 SMALLINT pageAutoCRCAR = FALSE;
83 SMALLINT canRedirectPageAR = FALSE;
84 SMALLINT canLockPageAR = TRUE;
85 SMALLINT canLockRedirecPageAR = FALSE;
86
87
88 /**
89 * Read memory in the current bank with no CRC checking (device or
90 * data). The resulting data from this API may or may not be what is on
91 * the 1-Wire device. It is recommends that the data contain some kind
92 * of checking (CRC) like in the readPagePackeAppRegt() method or have
93 * the 1-Wire device provide the CRC as in readPageCRCAppReg(). readPageCRCAppReg()
94 * however is not supported on all memory types, see 'hasPageAutoCRCAppReg()'.
95 * If neither is an option then this method could be called more
96 * then once to at least verify that the same thing is read consistantly.
97 *
98 * bank to tell what memory bank of the ibutton to use.
99 * portnum the port number of the port being used for the
100 * 1-Wire Network.
101 * SNum the serial number for the part that the read is
102 * to be done on.
103 * str_add starting physical address
104 * rd_cont if 'true' then device read is continued without
105 * re-selecting. This can only be used if the new
106 * read() continious where the last one led off
107 * and it is inside a 'beginExclusive/endExclusive'
108 * block.
109 * buff byte array to place read data into
110 * len length in bytes to read
111 *
112 * @return 'true' if the read was complete
113 */
readAppReg(SMALLINT bank,int portnum,uchar * SNum,int str_add,SMALLINT rd_cont,uchar * buff,int len)114 SMALLINT readAppReg(SMALLINT bank, int portnum, uchar *SNum, int str_add,
115 SMALLINT rd_cont, uchar *buff, int len)
116 {
117 uchar raw_buf[2];
118 int i;
119
120 // check if read exceeds memory
121 if((str_add + len) > PAGE_LENGTH)
122 {
123 OWERROR(OWERROR_READ_OUT_OF_RANGE);
124 return FALSE;
125 }
126
127 owSerialNum(portnum,SNum,FALSE);
128
129 // select the device
130 if (!owAccess(portnum))
131 {
132 OWERROR(OWERROR_DEVICE_SELECT_FAIL);
133 return FALSE;
134 }
135
136 // start the read
137 raw_buf[0] = READ_MEMORY_COMMAND;
138 raw_buf[1] = str_add & 0xFF;
139
140 if(!owBlock(portnum,FALSE,raw_buf,2))
141 {
142 OWERROR(OWERROR_BLOCK_FAILED);
143 return FALSE;
144 }
145
146 for(i=0;i<len;i++)
147 buff[i] = 0xFF;
148
149 if(!owBlock(portnum,FALSE,buff,len))
150 {
151 OWERROR(OWERROR_BLOCK_FAILED);
152 return FALSE;
153 }
154
155 return TRUE;
156 }
157
158 /**
159 * Write memory in the current bank. It is recommended that
160 * when writing data that some structure in the data is created
161 * to provide error free reading back with readAppReg(). Or the
162 * method 'writePagePacketAppReg()' could be used which automatically
163 * wraps the data in a length and CRC.
164 *
165 * When using on Write-Once devices care must be taken to write into
166 * into empty space. If writeAppReg() is used to write over an unlocked
167 * page on a Write-Once device it will fail.
168 *
169 * bank to tell what memory bank of the ibutton to use.
170 * portnum the port number of the port being used for the
171 * 1-Wire Network.
172 * SNum the serial number for the part that the write is
173 * to be done on.
174 * str_add starting address
175 * buff byte array containing data to write
176 * len length in bytes to write
177 *
178 * @return 'true' if the write was complete.
179 */
writeAppReg(SMALLINT bank,int portnum,uchar * SNum,int str_add,uchar * buff,int len)180 SMALLINT writeAppReg(SMALLINT bank, int portnum, uchar *SNum,
181 int str_add, uchar *buff, int len)
182 {
183 uchar raw_buf[64];
184 int i;
185
186 // return if nothing to do
187 if (len == 0)
188 return TRUE;
189
190 // check if power delivery is available
191 /* if(!owDeliverPower())
192 {
193 OWERROR(OWERROR_NO_POWER_DELIVERY);
194 return FALSE;
195 }*/
196
197 // check if write exceeds memory
198 if ((str_add + len) > PAGE_LENGTH)
199 {
200 OWERROR(OWERROR_WRITE_OUT_OF_RANGE);
201 return FALSE;
202 }
203
204 owSerialNum(portnum,SNum,FALSE);
205
206 // select the device
207 if (!owAccess(portnum))
208 {
209 OWERROR(OWERROR_DEVICE_SELECT_FAIL);
210 return FALSE;
211 }
212
213 // start the write
214 raw_buf[0] = WRITE_MEMORY_COMMAND;
215 raw_buf[1] = str_add & 0xFF;
216
217 for(i=0;i<len;i++)
218 raw_buf[i+2] = buff[i];
219
220 if(!owBlock(portnum,FALSE,raw_buf,len+2))
221 {
222 OWERROR(OWERROR_BLOCK_FAILED);
223 return FALSE;
224 }
225
226 // check for write verification
227 if(writeVerificationAR)
228 {
229 // read back
230 readAppReg(bank,portnum,SNum,str_add,TRUE,raw_buf,len);
231
232 // compare
233 for(i=0;i<len;i++)
234 {
235 if(raw_buf[i] != buff[i])
236 {
237 OWERROR(OWERROR_READ_BACK_INCORRECT);
238 return FALSE;
239 }
240 }
241 }
242
243 return TRUE;
244 }
245
246 /**
247 * Read page in the current bank with no
248 * CRC checking (device or data). The resulting data from this API
249 * may or may not be what is on the 1-Wire device. It is recommends
250 * that the data contain some kind of checking (CRC) like in the
251 * readPagePacketAppReg() method or have the 1-Wire device provide the
252 * CRC as in readPageCRCAppReg(). readPageCRCAppReg() however is not
253 * supported on all memory types, see 'hasPageAutoCRCAppReg()'.
254 * If neither is an option then this method could be called more
255 * then once to at least verify that the same thing is read consistantly.
256 *
257 * bank to tell what memory bank of the ibutton to use.
258 * portnum the port number of the port being used for the
259 * 1-Wire Network.
260 * SNum the serial number for the part.
261 * page the page to read
262 * rd_cont if 'true' then device read is continued without
263 * re-selecting. This can only be used if the new
264 * read() continious where the last one led off
265 * and it is inside a 'beginExclusive/endExclusive'
266 * block.
267 * buff byte array containing data that was read.
268 * len length in bytes to write
269 *
270 * @return - returns '0' if the read page wasn't completed.
271 * '1' if the operation is complete.
272 */
readPageAppReg(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff)273 SMALLINT readPageAppReg(SMALLINT bank, int portnum, uchar *SNum, int page,
274 SMALLINT rd_cont, uchar *buff)
275 {
276 // check if for valid page
277 if(page != 0)
278 {
279 OWERROR(OWERROR_INVALID_PAGE_NUMBER);
280 return FALSE;
281 }
282
283 // do the read
284 if(!readAppReg(bank,portnum,SNum,page*PAGE_LENGTH,
285 TRUE,buff,PAGE_LENGTH))
286 return FALSE;
287
288 return TRUE;
289 }
290
291 /**
292 * Read page with extra information in the current bank with no
293 * CRC checking (device or data). The resulting data from this API
294 * may or may not be what is on the 1-Wire device. It is recommends
295 * that the data contain some kind of checking (CRC) like in the
296 * readPagePacketAppReg() method or have the 1-Wire device provide the
297 * CRC as in readPageCRCAppReg(). readPageCRCAppReg() however is not
298 * supported on all memory types, see 'hasPageAutoCRCAppReg()'.
299 * If neither is an option then this method could be called more
300 * then once to at least verify that the same thing is read consistantly.
301 * See the method 'hasExtraInfoAppReg()' for a description of the optional
302 * extra information some devices have.
303 *
304 * bank to tell what memory bank of the ibutton to use.
305 * portnum the port number of the port being used for the
306 * 1-Wire Network.
307 * SNum the serial number for the part.
308 * page the page to read
309 * rd_cont if 'true' then device read is continued without
310 * re-selecting. This can only be used if the new
311 * read() continious where the last one led off
312 * and it is inside a 'beginExclusive/endExclusive'
313 * block.
314 * buff byte array containing data that was read
315 * len length in bytes to write
316 * extra the extra information
317 *
318 * @return - returns '0' if the read page wasn't completed with extra info.
319 * '1' if the operation is complete.
320 */
readPageExtraAppReg(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff,uchar * extra)321 SMALLINT readPageExtraAppReg(SMALLINT bank, int portnum, uchar *SNum, int page,
322 SMALLINT rd_cont, uchar *buff, uchar *extra)
323 {
324 if(page != 0)
325 {
326 OWERROR(OWERROR_INVALID_PAGE_NUMBER);
327 return FALSE;
328 }
329
330 // read the page data
331 if(!readAppReg(bank,portnum,SNum,page*PAGE_LENGTH,
332 TRUE,buff,PAGE_LENGTH))
333 return FALSE;
334
335 // read the extra information (status)
336 if(!readStatus(portnum,extra))
337 {
338 OWERROR(OWERROR_READ_STATUS_NOT_COMPLETE);
339 return FALSE;
340 }
341
342 return TRUE;
343 }
344
345 /**
346 * Read page with extra information in the current bank with no
347 * CRC checking (device or data). The resulting data from this API
348 * may or may not be what is on the 1-Wire device. It is recommends
349 * that the data contain some kind of checking (CRC) like in the
350 * readPagePacket() method or have the 1-Wire device provide the
351 * CRC as in readPageCRC(). readPageCRC() however is not
352 * supported on all memory types, see 'hasPageAutoCRC()'.
353 * If neither is an option then this method could be called more
354 * then once to at least verify that the same thing is read consistantly.
355 * See the method 'haveExtraInfo()' for a description of the optional
356 * extra information some devices have.
357 *
358 * bank to tell what memory bank of the ibutton to use.
359 * portnum the port number of the port being used for the
360 * 1-Wire Network.
361 * SNum the serial number for the part.
362 * page the page to read
363 * buff byte array containing data that was read.
364 * extra the extra information
365 *
366 * @return - returns '0' if the read page wasn't completed with extra info.
367 * '1' if the operation is complete.
368 */
readPageExtraCRCAppReg(SMALLINT bank,int portnum,uchar * SNum,int page,uchar * read_buff,uchar * extra)369 SMALLINT readPageExtraCRCAppReg(SMALLINT bank, int portnum, uchar *SNum, int page,
370 uchar *read_buff, uchar *extra)
371 {
372 // read the page data
373 if(!readAppReg(bank,portnum,SNum,page*PAGE_LENGTH,
374 TRUE,read_buff,PAGE_LENGTH))
375 return FALSE;
376
377 // read the extra information (status)
378 if(!readStatus(portnum,extra))
379 {
380 OWERROR(OWERROR_READ_STATUS_NOT_COMPLETE);
381 return FALSE;
382 }
383
384 return TRUE;
385 }
386
387 /**
388 * Read a complete memory page with CRC verification provided by the
389 * device. Not supported by all devices. See the method
390 * 'hasPageAutoCRCAppReg()'.
391 *
392 * bank to tell what memory bank of the ibutton to use.
393 * portnum the port number of the port being used for the
394 * 1-Wire Network.
395 * SNum the serial number for the part.
396 * page the page to read
397 * buff byte array containing data that was read
398 *
399 * @return - returns '0' if the read page wasn't completed.
400 * '1' if the operation is complete.
401 */
readPageCRCAppReg(SMALLINT bank,int portnum,uchar * SNum,int str_add,uchar * buff)402 SMALLINT readPageCRCAppReg(SMALLINT bank, int portnum, uchar *SNum,
403 int str_add, uchar *buff)
404 {
405 OWERROR(OWERROR_CRC_NOT_SUPPORTED);
406 return FALSE;
407 }
408
409 /**
410 * Read a Universal Data Packet.
411 *
412 * The Universal Data Packet always starts on page boundaries but
413 * can end anywhere in the page. The structure specifies the length of
414 * data bytes not including the length byte and the CRC16 bytes.
415 * There is one length byte. The CRC16 is first initialized to
416 * the page number. This provides a check to verify the page that
417 * was intended is being read. The CRC16 is then calculated over
418 * the length and data bytes. The CRC16 is then inverted and stored
419 * low byte first followed by the high byte. This is structure is
420 * used by this method to verify the data but is not returned, only
421 * the data payload is returned.
422 *
423 * bank to tell what memory bank of the ibutton to use.
424 * portnum the port number of the port being used for the
425 * 1-Wire Network.
426 * SNum the serial number for the part.
427 * page the page to read
428 * rd_cont if 'true' then device read is continued without
429 * re-selecting. This can only be used if the new
430 * read() continious where the last one led off
431 * and it is inside a 'beginExclusive/endExclusive'
432 * block.
433 * buff byte array containing data that was read.
434 * len length of the packet
435 *
436 * @return - returns '0' if the read page packet wasn't completed
437 * '1' if the operation is complete.
438 */
readPagePacketAppReg(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff,int * len)439 SMALLINT readPagePacketAppReg(SMALLINT bank, int portnum, uchar *SNum, int page,
440 SMALLINT rd_cont, uchar *buff, int *len)
441 {
442 uchar raw_buf[PAGE_LENGTH];
443 ushort lastcrc16;
444 int i;
445
446 // read the entire page data
447 readAppReg(bank,portnum,SNum,page,rd_cont,raw_buf,PAGE_LENGTH);
448
449 // check if length is realistic
450 if((raw_buf[0] > (PAGE_LENGTH - 2)) || (raw_buf[0] <= 0))
451 {
452 OWERROR(OWERROR_INVALID_PACKET_LENGTH);
453 return FALSE;
454 }
455
456 // verify the CRC is correct
457 setcrc16(portnum,(ushort)((getStartingAddressAppReg(bank,SNum)/PAGE_LENGTH) + page));
458 for(i=0;i<(raw_buf[0]+3);i++)
459 lastcrc16 = docrc16(portnum,raw_buf[i]);
460
461 if(lastcrc16 == 0xB001)
462 {
463 *len = (int) raw_buf[0];
464
465 // extract the data out of the packet
466 for(i=1;i<raw_buf[0]+1;i++)
467 buff[i-1] = raw_buf[i];
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 'readPagePacketAppReg()' for a description of the packet structure.
481 * See the method 'hasExtraInfoAppReg()' 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 */
readPagePacketExtraAppReg(SMALLINT bank,int portnum,uchar * SNum,int page,SMALLINT rd_cont,uchar * buff,int * len,uchar * extra)501 SMALLINT readPagePacketExtraAppReg(SMALLINT bank, int portnum, uchar *SNum,
502 int page, SMALLINT rd_cont, uchar *buff,
503 int *len, uchar *extra)
504 {
505 uchar raw_buf[32];
506 int i;
507 ushort lastcrc16;
508
509 // check if current bank is not scratchpad bank, or not page 0
510 if(!hasExtraInfoAppReg(bank,SNum))
511 {
512 OWERROR(OWERROR_EXTRA_INFO_NOT_SUPPORTED);
513 return FALSE;
514 }
515
516 // read the entire page data
517 readAppReg(bank,portnum,SNum,page*PAGE_LENGTH,
518 TRUE,raw_buf,PAGE_LENGTH);
519
520 // check if length is realistic
521 if((raw_buf[0] > (PAGE_LENGTH - 2)) || (raw_buf[0] <= 0))
522 {
523 OWERROR(OWERROR_INVALID_PACKET_LENGTH);
524 return FALSE;
525 }
526
527 // verify the CRC is correct
528 setcrc16(portnum,(ushort) ((getStartingAddressAppReg(bank,SNum)/PAGE_LENGTH) + page));
529 for(i=0;i<(raw_buf[0]+3);i++)
530 lastcrc16 = docrc16(portnum,raw_buf[i]);
531
532 if(lastcrc16 == 0xB001)
533 {
534 *len = (int) raw_buf[0];
535
536 if(!readStatus(portnum,extra))
537 {
538 OWERROR(OWERROR_READ_STATUS_NOT_COMPLETE);
539 return FALSE;
540 }
541
542 // extract the data out of the packet
543 for(i=1;i<raw_buf[0]+1;i++)
544 buff[i-1] = raw_buf[i];
545 }
546 else
547 {
548 OWERROR(OWERROR_CRC_FAILED);
549 return FALSE;
550 }
551
552 return TRUE;
553 }
554
555 /**
556 * Write a Universal Data Packet. See the method 'readPagePacketAppReg()'
557 * for a description of the packet structure.
558 *
559 * bank to tell what memory bank of the ibutton to use.
560 * portnum the port number of the port being used for the
561 * 1-Wire Network.
562 * SNum the serial number for the part.
563 * page the page the packet is being written to.
564 * rd_cont if 'true' then device read is continued without
565 * re-selecting. This can only be used if the new
566 * read() continious where the last one led off
567 * and it is inside a 'beginExclusive/endExclusive'
568 * block.
569 * buff byte array containing data that to write.
570 * len length of the packet
571 *
572 * @return - returns '0' if the write page packet wasn't completed
573 * '1' if the operation is complete.
574 */
writePagePacketAppReg(SMALLINT bank,int portnum,uchar * SNum,int page,uchar * buff,int len)575 SMALLINT writePagePacketAppReg(SMALLINT bank, int portnum, uchar *SNum,
576 int page, uchar *buff, int len)
577 {
578 uchar raw_buf[PAGE_LENGTH];
579 ushort crc;
580 int i;
581
582 // make sure length does not exceed max
583 if((len > (PAGE_LENGTH - 2)) || (len <= 0))
584 {
585 OWERROR(OWERROR_PACKET_LENGTH_EXCEEDS_PAGE);
586 return FALSE;
587 }
588
589 raw_buf[0] = (uchar) len + 3;
590
591 for(i=0;i<len;i++)
592 raw_buf[i+1] = buff[i];
593
594 setcrc16(portnum,(ushort) ((getStartingAddressAppReg(bank,SNum)/PAGE_LENGTH) + page));
595 for(i=0;i<len+1;i++)
596 crc = docrc16(portnum,raw_buf[i]);
597
598 raw_buf[len + 1] = ~crc & 0xFF;
599 raw_buf[len + 2] = ((~crc & 0xFFFF) >> 8) & 0xFF;
600
601 // write the packet, return result
602 if(!writeAppReg(bank,portnum,SNum,page*PAGE_LENGTH,raw_buf,len + 3))
603 return FALSE;
604
605 return TRUE;
606 }
607
608 /**
609 * Query to get the number of pages in current memory bank.
610 *
611 * bank to tell what memory bank of the ibutton to use.
612 * SNum the serial number for the part.
613 *
614 * @return number of pages in current memory bank
615 */
getNumberPagesAppReg(SMALLINT bank,uchar * SNum)616 SMALLINT getNumberPagesAppReg(SMALLINT bank, uchar *SNum)
617 {
618 return 1;
619 }
620
621 /**
622 * Query to get the memory bank size in bytes.
623 *
624 * bank to tell what memory bank of the ibutton to use.
625 * SNum the serial number for the part.
626 *
627 * @return memory bank size in bytes.
628 */
getSizeAppReg(SMALLINT bank,uchar * SNum)629 int getSizeAppReg(SMALLINT bank, uchar *SNum)
630 {
631 return SIZE;
632 }
633
634 /**
635 * Query to get the starting physical address of this bank. Physical
636 * banks are sometimes sub-divided into logical banks due to changes
637 * in attributes.
638 *
639 * bank to tell what memory bank of the ibutton to use.
640 * SNum the serial number for the part.
641 *
642 * @return physical starting address of this logical bank.
643 */
getStartingAddressAppReg(SMALLINT bank,uchar * SNum)644 int getStartingAddressAppReg(SMALLINT bank, uchar *SNum)
645 {
646 return 0;
647 }
648
649 /**
650 * Query to get page length in bytes in current memory bank.
651 *
652 * bank to tell what memory bank of the ibutton to use.
653 * SNum the serial number for the part.
654 *
655 * @return page length in bytes in current memory bank
656 */
getPageLengthAppReg(SMALLINT bank,uchar * SNum)657 SMALLINT getPageLengthAppReg(SMALLINT bank, uchar *SNum)
658 {
659 return PAGE_LENGTH;
660 }
661
662 /**
663 * Query to see get a string description of the current memory bank.
664 *
665 * bank to tell what memory bank of the ibutton to use.
666 * SNum the serial number for the part.
667 *
668 * @return String containing the memory bank description
669 */
getBankDescriptionAppReg(SMALLINT bank,uchar * SNum)670 char *getBankDescriptionAppReg(SMALLINT bank, uchar *SNum)
671 {
672 return bankDescriptionAR;
673 }
674
675 /**
676 * Query to see if the current memory bank is general purpose
677 * user memory. If it is NOT then it is Memory-Mapped and writing
678 * values to this memory will affect the behavior of the 1-Wire
679 * device.
680 *
681 * bank to tell what memory bank of the ibutton to use.
682 * SNum the serial number for the part.
683 *
684 * @return 'true' if current memory bank is general purpose
685 */
isGeneralPurposeMemoryAppReg(SMALLINT bank,uchar * SNum)686 SMALLINT isGeneralPurposeMemoryAppReg(SMALLINT bank, uchar *SNum)
687 {
688 return generalPurposeMemoryAR;
689 }
690
691 /**
692 * Query to see if current memory bank is read/write.
693 *
694 * bank to tell what memory bank of the ibutton to use.
695 * SNum the serial number for the part.
696 *
697 * @return 'true' if current memory bank is read/write
698 */
isReadWriteAppReg(SMALLINT bank,int portnum,uchar * SNum)699 SMALLINT isReadWriteAppReg(SMALLINT bank, int portnum, uchar *SNum)
700 {
701 return readWriteAR;
702 }
703
704 /**
705 * Query to see if current memory bank is read only.
706 *
707 * @return 'true' if current memory bank can only be read
708 */
isReadOnlyAppReg(SMALLINT bank,int portnum,uchar * SNum)709 SMALLINT isReadOnlyAppReg(SMALLINT bank, int portnum, uchar *SNum)
710 {
711 return readOnlyAR;
712 }
713
714 /**
715 * Query to see if current memory bank is write write once such
716 * as with EPROM technology.
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 can only be written once
722 */
isWriteOnceAppReg(SMALLINT bank,int portnum,uchar * SNum)723 SMALLINT isWriteOnceAppReg(SMALLINT bank, int portnum, uchar *SNum)
724 {
725 return writeOnceAR;
726 }
727
728 /**
729 * Query to see if current memory bank non-volatile. Memory is
730 * non-volatile if it retains its contents even when removed from
731 * the 1-Wire network.
732 *
733 * bank to tell what memory bank of the ibutton to use.
734 * SNum the serial number for the part.
735 *
736 * @return 'true' if current memory bank non volatile.
737 */
isNonVolatileAppReg(SMALLINT bank,uchar * SNum)738 SMALLINT isNonVolatileAppReg(SMALLINT bank, uchar *SNum)
739 {
740 return nonVolatileAR;
741 }
742
743 /**
744 * Query to see if current memory bank pages need the adapter to
745 * have a 'ProgramPulse' in order to write to the memory.
746 *
747 * bank to tell what memory bank of the ibutton to use.
748 * SNum the serial number for the part.
749 *
750 * @return 'true' if writing to the current memory bank pages
751 * requires a 'ProgramPulse'.
752 */
needsProgramPulseAppReg(SMALLINT bank,uchar * SNum)753 SMALLINT needsProgramPulseAppReg(SMALLINT bank, uchar *SNum)
754 {
755 return needsProgramPulseAR;
756 }
757
758 /**
759 * Query to see if current memory bank pages need the adapter to
760 * have a 'PowerDelivery' feature in order to write to the memory.
761 *
762 * bank to tell what memory bank of the ibutton to use.
763 * SNum the serial number for the part.
764 *
765 * @return 'true' if writing to the current memory bank pages
766 * requires 'PowerDelivery'.
767 */
needsPowerDeliveryAppReg(SMALLINT bank,uchar * SNum)768 SMALLINT needsPowerDeliveryAppReg(SMALLINT bank, uchar *SNum)
769 {
770 return needsPowerDeliveryAR;
771 }
772
773 /**
774 * Checks to see if this memory bank's pages deliver extra
775 * information outside of the normal data space, when read. Examples
776 * of this may be a redirection byte, counter, tamper protection
777 * bytes, or SHA-1 result. If this method returns true then the
778 * methods with an 'extraInfo' parameter can be used.
779 *
780 * bank to tell what memory bank of the ibutton to use.
781 * SNum the serial number for the part.
782 *
783 * @return true if reading the this memory bank's
784 * pages provides extra information
785 */
hasExtraInfoAppReg(SMALLINT bank,uchar * SNum)786 SMALLINT hasExtraInfoAppReg(SMALLINT bank, uchar *SNum)
787 {
788 return hasExtraInfoAR;
789 }
790
791 /**
792 * Query to get the length in bytes of extra information that
793 * is read when read a page in the current memory bank. See
794 * 'hasExtraInfoAppReg()'.
795 *
796 * bank to tell what memory bank of the ibutton to use.
797 * SNum the serial number for the part.
798 *
799 * @return number of bytes in Extra Information read when reading
800 * pages in the current memory bank.
801 */
getExtraInfoLengthAppReg(SMALLINT bank,uchar * SNum)802 SMALLINT getExtraInfoLengthAppReg(SMALLINT bank, uchar *SNum)
803 {
804 return extraInfoLengthAR;
805 }
806
807 /**
808 * Query to get a string description of what is contained in
809 * the Extra Informationed return when reading pages in the current
810 * memory bank. See 'hasExtraInfoAppReg()'.
811 *
812 * bank to tell what memory bank of the ibutton to use.
813 * SNum the serial number for the part.
814 *
815 * @return string describing extra information.
816 */
getExtraInfoDescAppReg(SMALLINT bank,uchar * SNum)817 char *getExtraInfoDescAppReg(SMALLINT bank, uchar *SNum)
818 {
819 return extraInfoDescAR;
820 }
821
822 /**
823 * Query to see if current memory bank pages can be read with
824 * the contents being verified by a device generated CRC.
825 * This is used to see if the 'ReadPageCRCAppReg()' can be used.
826 *
827 * bank to tell what memory bank of the ibutton to use.
828 * SNum the serial number for the part.
829 *
830 * @return 'true' if current memory bank can be read with self
831 * generated CRC.
832 */
hasPageAutoCRCAppReg(SMALLINT bank,uchar * SNum)833 SMALLINT hasPageAutoCRCAppReg(SMALLINT bank, uchar *SNum)
834 {
835 return pageAutoCRCAR;
836 }
837
838 /**
839 * Query to get Maximum data page length in bytes for a packet
840 * read or written in the current memory bank. See the 'ReadPagePacket()'
841 * and 'WritePagePacket()' methods. This method is only usefull
842 * if the current memory bank is general purpose memory.
843 *
844 * @return max packet page length in bytes in current memory bank
845 */
getMaxPacketDataLengthAppReg(SMALLINT bank,uchar * SNum)846 SMALLINT getMaxPacketDataLengthAppReg(SMALLINT bank, uchar *SNum)
847 {
848 return PAGE_LENGTH - 3;
849 }
850
851 //--------
852 //-------- OTPMemoryBank query methods
853 //--------
854
855 /**
856 * Query to see if current memory bank pages can be redirected
857 * to another pages. This is mostly used in Write-Once memory
858 * to provide a means to update.
859 *
860 * bank to tell what memory bank of the ibutton to use.
861 * SNum the serial number for the part.
862 *
863 * @return 'true' if current memory bank pages can be redirected
864 * to a new page.
865 */
canRedirectPageAppReg(SMALLINT bank,uchar * SNum)866 SMALLINT canRedirectPageAppReg(SMALLINT bank, uchar *SNum)
867 {
868 return FALSE;
869 }
870
871 /**
872 * Query to see if current memory bank pages can be locked. A
873 * locked page would prevent any changes to the memory.
874 *
875 * bank to tell what memory bank of the ibutton to use.
876 * SNum the serial number for the part.
877 *
878 * @return 'true' if current memory bank pages can be redirected
879 * to a new page.
880 */
canLockPageAppReg(SMALLINT bank,uchar * SNum)881 SMALLINT canLockPageAppReg(SMALLINT bank, uchar *SNum)
882 {
883 return TRUE;
884 }
885
886 /**
887 * Query to see if current memory bank pages can be locked from
888 * being redirected. This would prevent a Write-Once memory from
889 * being updated.
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 locked from
895 * being redirected to a new page.
896 */
canLockRedirectPageAppReg(SMALLINT bank,uchar * SNum)897 SMALLINT canLockRedirectPageAppReg(SMALLINT bank, uchar *SNum)
898 {
899 return FALSE;
900 }
901
902 //--------
903 //-------- OTPMemoryBank I/O methods
904 //--------
905
906 /**
907 * Lock the specifed page in the current memory bank. Not supported
908 * by all devices. See the method 'canLockPage()'.
909 *
910 * portnum the port number of the port being used for the
911 * 1-Wire Network.
912 * SNum the serial number for the part.
913 * page the page to be used.
914 *
915 * @return 'true' if page is locked.
916 */
lockPageAppReg(SMALLINT portnum,int page,uchar * SNum)917 SMALLINT lockPageAppReg(SMALLINT portnum, int page, uchar *SNum)
918 {
919
920 // select the device
921 owSerialNum(portnum,SNum,FALSE);
922 if (!owAccess(portnum))
923 {
924 OWERROR(OWERROR_DEVICE_SELECT_FAIL);
925 return FALSE;
926 }
927
928 // do the copy/lock sequence
929 owWriteByte(portnum,COPY_LOCK_COMMAND);
930 owWriteByte(portnum,VALIDATION_KEY);
931
932 // read back to verify
933 if(!isPageLockedAppReg(portnum,page,SNum))
934 {
935 OWERROR(OWERROR_READ_BACK_NOT_VALID);
936 return FALSE;
937 }
938
939 return TRUE;
940 }
941
942 /**
943 * Query to see if the specified page is locked.
944 * See the method 'canLockPage()'.
945 *
946 * portnum the port number of the port being used for the
947 * 1-Wire Network.
948 * SNum the serial number for the part.
949 * page the page to be used.
950 *
951 * @return 'true' if page is locked.
952 */
isPageLockedAppReg(int portnum,int page,uchar * SNum)953 SMALLINT isPageLockedAppReg(int portnum, int page, uchar *SNum)
954 {
955 uchar extra[2];
956
957 // check if for valid page
958 if(page != 0)
959 {
960 OWERROR(OWERROR_INVALID_PAGE_NUMBER);
961 return FALSE;
962 }
963
964 // read status and return result
965 if(!readStatus(portnum,&extra[0]))
966 {
967 OWERROR(OWERROR_READ_STATUS_NOT_COMPLETE);
968 return FALSE;
969 }
970
971 if(extra[0] == LOCKED_FLAG)
972 return TRUE;
973
974 return FALSE;
975 }
976
977 /**
978 * Redirect the specifed page in the current memory bank to a new page.
979 * Not supported by all devices. See the method 'canRedirectPage()'.
980 *
981 * portnum the port number of the port being used for the
982 * 1-Wire Network.
983 * SNum the serial number for the part.
984 * page the page to be used.
985 *
986 * @return 'true' if page is redirected.
987 */
redirectPageAppReg(int portnum,int page,int newPage,uchar * SNum)988 SMALLINT redirectPageAppReg(int portnum, int page, int newPage, uchar *SNum)
989 {
990 OWERROR(OWERROR_PAGE_REDIRECTION_NOT_SUPPORTED);
991 return FALSE;
992 }
993
994 /**
995 * Gets the page redirection of the specified page.
996 * Not supported by all devices.
997 *
998 * portnum the port number of the port being used for the
999 * 1-Wire Network.
1000 * SNum the serial number for the part.
1001 * page the page to be used.
1002 *
1003 * @return where the redirected page is.
1004 */
getRedirectedPageAppReg(int portnum,int page,uchar * SNum)1005 SMALLINT getRedirectedPageAppReg(int portnum, int page, uchar *SNum)
1006 {
1007 return 0;
1008 }
1009
1010 /**
1011 * Lock the redirection option for the specifed page in the current
1012 * memory bank. Not supported by all devices. See the method
1013 * 'canLockRedirectPage()'.
1014 *
1015 * portnum the port number of the port being used for the
1016 * 1-Wire Network.
1017 * SNum the serial number for the part.
1018 * page the page to be used.
1019 *
1020 * @return 'true' if redirected page is locked.
1021 */
lockRedirectPageAppReg(int portnum,int page,uchar * SNum)1022 SMALLINT lockRedirectPageAppReg(int portnum, int page, uchar *SNum)
1023 {
1024 // only needs to be implemented if supported by hardware
1025 OWERROR(OWERROR_LOCK_REDIRECTION_NOT_SUPPORTED);
1026 return FALSE;
1027 }
1028
1029 /**
1030 * Query to see if the specified page has redirection locked.
1031 * Not supported by all devices. See the method 'canRedirectPage()'.
1032 *
1033 * portnum the port number of the port being used for the
1034 * 1-Wire Network.
1035 * SNum the serial number for the part.
1036 * page the page to be used.
1037 *
1038 * @return return 'true' if redirection is locked for this page
1039 */
isRedirectPageLockedAppReg(int portnum,int page,uchar * SNum)1040 SMALLINT isRedirectPageLockedAppReg(int portnum, int page, uchar *SNum)
1041 {
1042 return FALSE;
1043 }
1044
1045 //--------
1046 //-------- Bank specific methods
1047 //--------
1048
1049 /**
1050 * Read the status register for this memory bank.
1051 *
1052 * portnum the port number of the port being used for the
1053 * 1-Wire Network.
1054 * extra the extra information
1055 *
1056 * @return 'true' if the status was read.
1057 *
1058 */
readStatus(int portnum,uchar * extra)1059 SMALLINT readStatus(int portnum, uchar *extra)
1060 {
1061 // select the device
1062 if(!owAccess(portnum))
1063 {
1064 OWERROR(OWERROR_DEVICE_SELECT_FAIL);
1065 return FALSE;
1066 }
1067
1068 // do the read status sequence
1069 if(!owWriteByte(portnum,READ_STATUS_COMMAND))
1070 return FALSE;
1071
1072 // validation key
1073 if(!owWriteByte(portnum,0x00))
1074 return FALSE;
1075
1076 extra[0] = owReadByte(portnum);
1077
1078 return TRUE;
1079 }