~ubuntu-branches/debian/jessie/digitemp/jessie

« back to all changes in this revision

Viewing changes to userial/ds9097u/owtrnu.c

  • Committer: Bazaar Package Importer
  • Author(s): Jesus Roncero
  • Date: 2004-09-01 01:34:37 UTC
  • Revision ID: james.westby@ubuntu.com-20040901013437-eicsrrd40dr371u0
Tags: upstream-3.3.2
ImportĀ upstreamĀ versionĀ 3.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
//  owTranU.C - Transport functions for 1-Wire Net
 
28
//              using the DS2480B (U) serial interface chip.
 
29
//
 
30
//  Version: 2.01
 
31
//
 
32
//  History: 1.02 -> 1.03  Removed caps in #includes for Linux capatibility
 
33
//           1.03 -> 2.00  Changed 'MLan' to 'ow'. Added support for
 
34
//                         multiple ports.
 
35
//           2.00 -> 2.01  Added support for owError library
 
36
//           2.01 -> 2.10  Added SMALLINT for small processors and error
 
37
//                         handling plus the raw memory utilities.
 
38
//           2.10 -> 3.00 Added memory bank functionality
 
39
//                        Added file I/O operations
 
40
//
 
41
 
 
42
#include "ownet.h"
 
43
#include "ds2480.h"
 
44
 
 
45
// external functions defined in owllu.c
 
46
extern SMALLINT owTouchReset(int);
 
47
extern SMALLINT owWriteByte(int,SMALLINT);
 
48
extern SMALLINT owReadByte(int);
 
49
extern SMALLINT owProgramPulse(int);
 
50
 
 
51
// external network-level functions defined in owsesu.c
 
52
extern SMALLINT owAccess(int);
 
53
 
 
54
// external COM functions required defined in system specific link file
 
55
extern SMALLINT WriteCOM(int,int,uchar *);
 
56
extern int      ReadCOM(int,int,uchar *);
 
57
extern void     FlushCOM(int);
 
58
 
 
59
// external defined in ds2480ut.c
 
60
extern SMALLINT DS2480Detect(int);
 
61
extern SMALLINT UBaud[MAX_PORTNUM];
 
62
extern SMALLINT UMode[MAX_PORTNUM];
 
63
extern SMALLINT USpeed[MAX_PORTNUM];
 
64
extern uchar SerialNum[MAX_PORTNUM][8];
 
65
 
 
66
// external functions defined in crcutil.c
 
67
extern void setcrc16(int,ushort);
 
68
extern ushort docrc16(int,ushort);
 
69
extern void setcrc8(int,uchar);
 
70
extern uchar docrc8(int,uchar);
 
71
 
 
72
// exportable functions defined in owtrnu.c
 
73
SMALLINT owBlock(int,SMALLINT,uchar *,SMALLINT);
 
74
SMALLINT owReadPacketStd(int,SMALLINT,int,uchar *);
 
75
SMALLINT owWritePacketStd(int,int,uchar *,SMALLINT,SMALLINT,SMALLINT);
 
76
SMALLINT owProgramByte(int,SMALLINT,int,SMALLINT,SMALLINT,SMALLINT);
 
77
 
 
78
// local static functions
 
79
static SMALLINT Write_Scratchpad(int,uchar *,int,SMALLINT);
 
80
static SMALLINT Copy_Scratchpad(int,int,SMALLINT);
 
81
 
 
82
//--------------------------------------------------------------------------
 
83
// The 'owBlock' transfers a block of data to and from the
 
84
// 1-Wire Net with an optional reset at the begining of communication.
 
85
// The result is returned in the same buffer.
 
86
//
 
87
// 'portnum'  - number 0 to MAX_PORTNUM-1.  This number is provided to
 
88
//              indicate the symbolic port number.
 
89
// 'do_reset' - cause a owTouchReset to occure at the begining of
 
90
//              communication TRUE(1) or not FALSE(0)
 
91
// 'tran_buf' - pointer to a block of unsigned
 
92
//              chars of length 'tran_len' that will be sent
 
93
//              to the 1-Wire Net
 
94
// 'tran_len' - length in bytes to transfer
 
95
 
 
96
// Supported devices: all
 
97
//
 
98
// Returns:   TRUE (1) : The optional reset returned a valid
 
99
//                       presence (do_reset == TRUE) or there
 
100
//                       was no reset required.
 
101
//            FALSE (0): The reset did not return a valid prsence
 
102
//                       (do_reset == TRUE).
 
103
//
 
104
//  The maximum tran_length is 64
 
105
//
 
106
SMALLINT owBlock(int portnum, SMALLINT do_reset, uchar *tran_buf, SMALLINT tran_len)
 
107
{
 
108
   uchar sendpacket[150];
 
109
   uchar sendlen=0,pos,i;
 
110
 
 
111
   // check for a block too big
 
112
   if (tran_len > 64)
 
113
   {
 
114
      OWERROR(OWERROR_BLOCK_TOO_BIG);
 
115
      return FALSE;
 
116
   }
 
117
 
 
118
   // check if need to do a owTouchReset first
 
119
   if (do_reset)
 
120
   {
 
121
      if (!owTouchReset(portnum))
 
122
      {
 
123
         OWERROR(OWERROR_NO_DEVICES_ON_NET);
 
124
         return FALSE;
 
125
      }
 
126
   }
 
127
 
 
128
   // construct the packet to send to the DS2480
 
129
   // check if correct mode
 
130
   if (UMode[portnum] != MODSEL_DATA)
 
131
   {
 
132
      UMode[portnum] = MODSEL_DATA;
 
133
      sendpacket[sendlen++] = MODE_DATA;
 
134
   }
 
135
 
 
136
   // add the bytes to send
 
137
   pos = sendlen;
 
138
   for (i = 0; i < tran_len; i++)
 
139
   {
 
140
      sendpacket[sendlen++] = tran_buf[i];
 
141
 
 
142
      // check for duplication of data that looks like COMMAND mode
 
143
      if (tran_buf[i] == MODE_COMMAND)
 
144
         sendpacket[sendlen++] = tran_buf[i];
 
145
   }
 
146
 
 
147
   // flush the buffers
 
148
   FlushCOM(portnum);
 
149
 
 
150
   // send the packet
 
151
   if (WriteCOM(portnum,sendlen,sendpacket))
 
152
   {
 
153
      // read back the response
 
154
      if (ReadCOM(portnum,tran_len,tran_buf) == tran_len)
 
155
         return TRUE;
 
156
      else
 
157
         OWERROR(OWERROR_READCOM_FAILED);
 
158
   }
 
159
   else
 
160
      OWERROR(OWERROR_WRITECOM_FAILED);
 
161
 
 
162
   // an error occured so re-sync with DS2480
 
163
   DS2480Detect(portnum);
 
164
 
 
165
   return FALSE;
 
166
}
 
167
 
 
168
//--------------------------------------------------------------------------
 
169
// Read a Universal Data Packet from a standard NVRAM iButton
 
170
// and return it in the provided buffer. The page that the
 
171
// packet resides on is 'start_page'.  Note that this function is limited
 
172
// to single page packets. The buffer 'read_buf' must be at least
 
173
// 29 bytes long.
 
174
//
 
175
// The Universal Data Packet always start on page boundaries but
 
176
// can end anywhere.  The length is the number of data bytes not
 
177
// including the length byte and the CRC16 bytes.  There is one
 
178
// length byte. The CRC16 is first initialized to the starting
 
179
// page number.  This provides a check to verify the page that
 
180
// was intended is being read.  The CRC16 is then calculated over
 
181
// the length and data bytes.  The CRC16 is then inverted and stored
 
182
// low byte first followed by the high byte.
 
183
//
 
184
// Supported devices: DS1992, DS1993, DS1994, DS1995, DS1996, DS1982,
 
185
//                    DS1985, DS1986, DS2407, and DS1971.
 
186
//
 
187
// 'portnum'    - number 0 to MAX_PORTNUM-1.  This number is provided to
 
188
//                indicate the symbolic port number.
 
189
// 'do_access'  - flag to indicate if an 'owAccess' should be
 
190
//                peformed at the begining of the read.  This may
 
191
//                be FALSE (0) if the previous call was to read the
 
192
//                previous page (start_page-1).
 
193
// 'start_page' - page number to start the read from
 
194
// 'read_buf'   - pointer to a location to store the data read
 
195
//
 
196
// Returns:  >=0 success, number of data bytes in the buffer
 
197
//           -1  failed to read a valid UDP
 
198
//
 
199
//
 
200
SMALLINT owReadPacketStd(int portnum, SMALLINT do_access, int start_page, uchar *read_buf)
 
201
{
 
202
   uchar i,length,sendlen=0,head_len=0;
 
203
   uchar sendpacket[50];
 
204
   ushort lastcrc16;
 
205
 
 
206
   // check if access header is done
 
207
   // (only use if in sequention read with one access at begining)
 
208
   if (do_access)
 
209
   {
 
210
      // match command
 
211
      sendpacket[sendlen++] = 0x55;
 
212
      for (i = 0; i < 8; i++)
 
213
         sendpacket[sendlen++] = SerialNum[portnum][i];
 
214
      // read memory command
 
215
      sendpacket[sendlen++] = 0xF0;
 
216
      // write the target address
 
217
      sendpacket[sendlen++] = ((start_page << 5) & 0xFF);
 
218
      sendpacket[sendlen++] = (start_page >> 3);
 
219
      // check for DS1982 exception (redirection byte)
 
220
      if (SerialNum[portnum][0] == 0x09)
 
221
         sendpacket[sendlen++] = 0xFF;
 
222
      // record the header length
 
223
      head_len = sendlen;
 
224
   }
 
225
   // read the entire page length byte
 
226
   for (i = 0; i < 32; i++)
 
227
      sendpacket[sendlen++] = 0xFF;
 
228
 
 
229
   // send/recieve the transfer buffer
 
230
   if (owBlock(portnum,do_access,sendpacket,sendlen))
 
231
   {
 
232
      // seed crc with page number
 
233
      setcrc16(portnum,(ushort)start_page);
 
234
 
 
235
      // attempt to read UDP from sendpacket
 
236
      length = sendpacket[head_len];
 
237
      docrc16(portnum,(ushort)length);
 
238
 
 
239
      // verify length is not too large
 
240
      if (length <= 29)
 
241
      {
 
242
         // loop to read packet including CRC
 
243
         for (i = 0; i < length; i++)
 
244
         {
 
245
             read_buf[i] = sendpacket[i+1+head_len];
 
246
             docrc16(portnum,read_buf[i]);
 
247
         }
 
248
 
 
249
         // read and compute the CRC16
 
250
         docrc16(portnum,sendpacket[i+1+head_len]);
 
251
         lastcrc16 = docrc16(portnum,sendpacket[i+2+head_len]);
 
252
 
 
253
         // verify the CRC16 is correct
 
254
         if (lastcrc16 == 0xB001)
 
255
           return length;        // return number of byte in record
 
256
         else
 
257
            OWERROR(OWERROR_CRC_FAILED);
 
258
      }
 
259
      else
 
260
         OWERROR(OWERROR_INCORRECT_CRC_LENGTH);
 
261
   }
 
262
   else
 
263
      OWERROR(OWERROR_BLOCK_FAILED);
 
264
 
 
265
   // failed block or incorrect CRC
 
266
   return -1;
 
267
}
 
268
 
 
269
//--------------------------------------------------------------------------
 
270
// Write a Universal Data Packet onto a standard NVRAM 1-Wire device
 
271
// on page 'start_page'.  This function is limited to UDPs that
 
272
// fit on one page.  The data to write is provided as a buffer
 
273
// 'write_buf' with a length 'write_len'.
 
274
//
 
275
// The Universal Data Packet always start on page boundaries but
 
276
// can end anywhere.  The length is the number of data bytes not
 
277
// including the length byte and the CRC16 bytes.  There is one
 
278
// length byte. The CRC16 is first initialized to the starting
 
279
// page number.  This provides a check to verify the page that
 
280
// was intended is being read.  The CRC16 is then calculated over
 
281
// the length and data bytes.  The CRC16 is then inverted and stored
 
282
// low byte first followed by the high byte.
 
283
//
 
284
// Supported devices: is_eprom=0
 
285
//                        DS1992, DS1993, DS1994, DS1995, DS1996
 
286
//                    is_eprom=1, crc_type=0(CRC8)
 
287
//                        DS1982
 
288
//                    is_eprom=1, crc_type=1(CRC16)
 
289
//                        DS1985, DS1986, DS2407
 
290
//
 
291
// 'portnum'    - number 0 to MAX_PORTNUM-1.  This number is provided to
 
292
//                indicate the symbolic port number.
 
293
// 'start_page' - page number to write packet to
 
294
// 'write_buf'  - pointer to buffer containing data to write
 
295
// 'write_len'  - number of data byte in write_buf
 
296
// 'is_eprom'   - flag set if device is an EPROM (1 EPROM, 0 NVRAM)
 
297
// 'crc_type'   - if is_eprom=1 then indicates CRC type
 
298
//                (0 CRC8, 1 CRC16)
 
299
//
 
300
// Returns: TRUE(1)  success, packet written
 
301
//          FALSE(0) failure to write, contact lost or device locked
 
302
//
 
303
SMALLINT owWritePacketStd(int portnum, int start_page, uchar *write_buf,
 
304
                        SMALLINT write_len, SMALLINT is_eprom, SMALLINT crc_type)
 
305
{
 
306
   uchar construct_buffer[32];
 
307
   uchar i,buffer_cnt=0,start_address,do_access;
 
308
   ushort lastcrc16=0;
 
309
 
 
310
   // check to see if data too long to fit on device
 
311
   if (write_len > 29)
 
312
     return FALSE;
 
313
 
 
314
   // seed crc with page number
 
315
   setcrc16(portnum,(ushort)start_page);
 
316
 
 
317
   // set length byte
 
318
   construct_buffer[buffer_cnt++] = (uchar)(write_len);
 
319
   docrc16(portnum,(ushort)write_len);
 
320
 
 
321
   // fill in the data to write
 
322
   for (i = 0; i < write_len; i++)
 
323
   {
 
324
     lastcrc16 = docrc16(portnum,write_buf[i]);
 
325
     construct_buffer[buffer_cnt++] = write_buf[i];
 
326
   }
 
327
 
 
328
   // add the crc
 
329
   construct_buffer[buffer_cnt++] = (uchar)(~(lastcrc16 & 0xFF));
 
330
   construct_buffer[buffer_cnt++] = (uchar)(~((lastcrc16 & 0xFF00) >> 8));
 
331
 
 
332
   // check if not EPROM
 
333
   if (!is_eprom)
 
334
   {
 
335
      // write the page
 
336
      if (!Write_Scratchpad(portnum,construct_buffer,start_page,buffer_cnt))
 
337
      {
 
338
         OWERROR(OWERROR_WRITE_SCRATCHPAD_FAILED);
 
339
         return FALSE;
 
340
      }
 
341
 
 
342
      // copy the scratchpad
 
343
      if (!Copy_Scratchpad(portnum,start_page,buffer_cnt))
 
344
      {
 
345
         OWERROR(OWERROR_COPY_SCRATCHPAD_FAILED);
 
346
         return FALSE;
 
347
      }
 
348
 
 
349
      // copy scratch pad was good then success
 
350
      return TRUE;
 
351
   }
 
352
   // is EPROM
 
353
   else
 
354
   {
 
355
      // calculate the start address
 
356
      start_address = ((start_page >> 3) << 8) | ((start_page << 5) & 0xFF);
 
357
      do_access = TRUE;
 
358
      // loop to program each byte
 
359
      for (i = 0; i < buffer_cnt; i++)
 
360
      {
 
361
         if (owProgramByte(portnum,construct_buffer[i], start_address + i,
 
362
             0x0F, crc_type, do_access) != construct_buffer[i])
 
363
         {
 
364
            OWERROR(OWERROR_PROGRAM_BYTE_FAILED);
 
365
            return FALSE;
 
366
         }
 
367
         do_access = FALSE;
 
368
      }
 
369
      return TRUE;
 
370
   }
 
371
}
 
372
 
 
373
//--------------------------------------------------------------------------
 
374
// Write a byte to an EPROM 1-Wire device.
 
375
//
 
376
// Supported devices: crc_type=0(CRC8)
 
377
//                        DS1982
 
378
//                    crc_type=1(CRC16)
 
379
//                        DS1985, DS1986, DS2407
 
380
//
 
381
// 'portnum'    - number 0 to MAX_PORTNUM-1.  This number is provided to
 
382
//                indicate the symbolic port number.
 
383
// 'write_byte' - byte to program
 
384
// 'addr'       - address of byte to program
 
385
// 'write_cmd'  - command used to write (0x0F reg mem, 0x55 status)
 
386
// 'crc_type'   - CRC used (0 CRC8, 1 CRC16)
 
387
// 'do_access'  - Flag to access device for each byte
 
388
//                (0 skip access, 1 do the access)
 
389
//                WARNING, only use do_access=0 if programing the NEXT
 
390
//                byte immediatly after the previous byte.
 
391
//
 
392
// Returns: >=0   success, this is the resulting byte from the program
 
393
//                effort
 
394
//          -1    error, device not connected or program pulse voltage
 
395
//                not available
 
396
//
 
397
SMALLINT owProgramByte(int portnum, SMALLINT write_byte, int addr, SMALLINT write_cmd,
 
398
                    SMALLINT crc_type, SMALLINT do_access)
 
399
{
 
400
   ushort lastcrc16;
 
401
   uchar lastcrc8;
 
402
 
 
403
   // optionally access the device
 
404
   if (do_access)
 
405
   {
 
406
      if (!owAccess(portnum))
 
407
      {
 
408
         OWERROR(OWERROR_ACCESS_FAILED);
 
409
         return -1;
 
410
      }
 
411
 
 
412
      // send the write command
 
413
      if (!owWriteByte(portnum,write_cmd))
 
414
      {
 
415
         OWERROR(OWERROR_WRITE_BYTE_FAILED);
 
416
         return -1;
 
417
      }
 
418
 
 
419
      // send the address
 
420
      if (!owWriteByte(portnum,addr & 0xFF) || !owWriteByte(portnum,addr >> 8))
 
421
      {
 
422
         OWERROR(OWERROR_WRITE_BYTE_FAILED);
 
423
         return -1;
 
424
      }
 
425
   }
 
426
 
 
427
   // send the data to write
 
428
   if (!owWriteByte(portnum,write_byte))
 
429
   {
 
430
      OWERROR(OWERROR_WRITE_BYTE_FAILED);
 
431
      return -1;
 
432
   }
 
433
 
 
434
   // read the CRC
 
435
   if (crc_type == 0)
 
436
   {
 
437
      // calculate CRC8
 
438
      if (do_access)
 
439
      {
 
440
         setcrc8(portnum,0);
 
441
         docrc8(portnum,(uchar)write_cmd);
 
442
         docrc8(portnum,(uchar)(addr & 0xFF));
 
443
         docrc8(portnum,(uchar)(addr >> 8));
 
444
      }
 
445
      else
 
446
         setcrc8(portnum,(uchar)(addr & 0xFF));
 
447
 
 
448
      docrc8(portnum,(uchar)write_byte);
 
449
      // read and calculate the read crc
 
450
      lastcrc8 = docrc8(portnum,(uchar)owReadByte(portnum));
 
451
      // crc should now be 0x00
 
452
      if (lastcrc8 != 0)
 
453
      {
 
454
         OWERROR(OWERROR_CRC_FAILED);
 
455
         return -1;
 
456
      }
 
457
   }
 
458
   else
 
459
   {
 
460
      // CRC16
 
461
      if (do_access)
 
462
      {
 
463
         setcrc16(portnum,0);
 
464
         docrc16(portnum,(ushort)write_cmd);
 
465
         docrc16(portnum,(ushort)(addr & 0xFF));
 
466
         docrc16(portnum,(ushort)(addr >> 8));
 
467
      }
 
468
      else
 
469
         setcrc16(portnum,(ushort)addr);
 
470
      docrc16(portnum,(ushort)write_byte);
 
471
      // read and calculate the read crc
 
472
      docrc16(portnum,(ushort)owReadByte(portnum));
 
473
      lastcrc16 = docrc16(portnum,(ushort)owReadByte(portnum));
 
474
      // crc should now be 0xB001
 
475
      if (lastcrc16 != 0xB001)
 
476
      {
 
477
         OWERROR(OWERROR_CRC_FAILED);
 
478
         return -1;
 
479
      }
 
480
   }
 
481
 
 
482
   // send the program pulse
 
483
   if (!owProgramPulse(portnum))
 
484
   {
 
485
      OWERROR(OWERROR_PROGRAM_PULSE_FAILED);
 
486
      return -1;
 
487
   }
 
488
 
 
489
   // read back and return the resulting byte
 
490
   return owReadByte(portnum);
 
491
}
 
492
 
 
493
//--------------------------------------------------------------------------
 
494
// Write the scratchpad of a standard NVRam device such as the DS1992,3,4
 
495
// and verify its contents.
 
496
//
 
497
// 'portnum'    - number 0 to MAX_PORTNUM-1.  This number is provided to
 
498
//                indicate the symbolic port number.
 
499
// 'write_buf'  - pointer to buffer containing data to write
 
500
// 'start_page'    - page number to write packet to
 
501
// 'write_len'  - number of data byte in write_buf
 
502
//
 
503
// Returns: TRUE(1)  success, the data was written and verified
 
504
//          FALSE(0) failure, the data could not be written
 
505
//
 
506
//
 
507
SMALLINT Write_Scratchpad(int portnum, uchar *write_buf, int start_page, SMALLINT write_len)
 
508
{
 
509
   uchar i,sendlen=0;
 
510
   uchar sendpacket[50];
 
511
 
 
512
   // match command
 
513
   sendpacket[sendlen++] = 0x55;
 
514
   for (i = 0; i < 8; i++)
 
515
      sendpacket[sendlen++] = SerialNum[portnum][i];
 
516
   // write scratchpad command
 
517
   sendpacket[sendlen++] = 0x0F;
 
518
   // write the target address
 
519
   sendpacket[sendlen++] = ((start_page << 5) & 0xFF);
 
520
   sendpacket[sendlen++] = (start_page >> 3);
 
521
 
 
522
   // write packet bytes
 
523
   for (i = 0; i < write_len; i++)
 
524
      sendpacket[sendlen++] = write_buf[i];
 
525
 
 
526
   // send/recieve the transfer buffer
 
527
   if (owBlock(portnum,TRUE,sendpacket,sendlen))
 
528
   {
 
529
      // now attempt to read back to check
 
530
      sendlen = 0;
 
531
      // match command
 
532
      sendpacket[sendlen++] = 0x55;
 
533
      for (i = 0; i < 8; i++)
 
534
         sendpacket[sendlen++] = SerialNum[portnum][i];
 
535
      // read scratchpad command
 
536
      sendpacket[sendlen++] = 0xAA;
 
537
      // read the target address, offset and data
 
538
      for (i = 0; i < (write_len + 3); i++)
 
539
         sendpacket[sendlen++] = 0xFF;
 
540
 
 
541
      // send/recieve the transfer buffer
 
542
      if (owBlock(portnum,TRUE,sendpacket,sendlen))
 
543
      {
 
544
         // check address and offset of scratchpad read
 
545
         if ((sendpacket[10] != ((start_page << 5) & 0xFF)) ||
 
546
             (sendpacket[11] != (start_page >> 3)) ||
 
547
             (sendpacket[12] != (write_len - 1)))
 
548
         {
 
549
            OWERROR(OWERROR_READ_VERIFY_FAILED);
 
550
            return FALSE;
 
551
         }
 
552
 
 
553
         // verify each data byte
 
554
         for (i = 0; i < write_len; i++)
 
555
            if (sendpacket[i+13] != write_buf[i])
 
556
            {
 
557
               OWERROR(OWERROR_WRITE_VERIFY_FAILED);
 
558
               return FALSE;
 
559
            }
 
560
 
 
561
         // must have verified
 
562
         return TRUE;
 
563
      }
 
564
      else
 
565
         OWERROR(OWERROR_BLOCK_FAILED);
 
566
   }
 
567
   else
 
568
      OWERROR(OWERROR_BLOCK_FAILED);
 
569
 
 
570
   // failed a block tranfer
 
571
   return FALSE;
 
572
}
 
573
 
 
574
//--------------------------------------------------------------------------
 
575
// Copy the contents of the scratchpad to its intended nv ram page.  The
 
576
// page and length of the data is needed to build the authorization bytes
 
577
// to copy.
 
578
//
 
579
// 'portnum'    - number 0 to MAX_PORTNUM-1.  This number is provided to
 
580
//                indicate the symbolic port number.
 
581
// 'start_page' - page number to write packet to
 
582
// 'write_len'  - number of data bytes that are being copied
 
583
//
 
584
// Returns: TRUE(1)  success
 
585
//          FALSE(0) failure
 
586
//
 
587
SMALLINT Copy_Scratchpad(int portnum, int start_page, SMALLINT write_len)
 
588
{
 
589
   uchar i,sendlen=0;
 
590
   uchar sendpacket[50];
 
591
 
 
592
   // match command
 
593
   sendpacket[sendlen++] = 0x55;
 
594
   for (i = 0; i < 8; i++)
 
595
      sendpacket[sendlen++] = SerialNum[portnum][i];
 
596
   // copy scratchpad command
 
597
   sendpacket[sendlen++] = 0x55;
 
598
   // write the target address
 
599
   sendpacket[sendlen++] = ((start_page << 5) & 0xFF);
 
600
   sendpacket[sendlen++] = (start_page >> 3);
 
601
   sendpacket[sendlen++] = write_len - 1;
 
602
   // read copy result
 
603
   sendpacket[sendlen++] = 0xFF;
 
604
 
 
605
   // send/recieve the transfer buffer
 
606
   if (owBlock(portnum,TRUE,sendpacket,sendlen))
 
607
   {
 
608
      // check address and offset of scratchpad read
 
609
      if ((sendpacket[10] != ((start_page << 5) & 0xFF)) ||
 
610
          (sendpacket[11] != (start_page >> 3)) ||
 
611
          (sendpacket[12] != (write_len - 1)) ||
 
612
          (sendpacket[13] & 0xF0))
 
613
      {
 
614
         OWERROR(OWERROR_READ_VERIFY_FAILED);
 
615
         return FALSE;
 
616
      }
 
617
      else
 
618
         return TRUE;
 
619
   }
 
620
   else
 
621
      OWERROR(OWERROR_BLOCK_FAILED);
 
622
 
 
623
   // failed a block tranfer
 
624
   return FALSE;
 
625
}
 
626