f192db572eb9a0188bfdea20e79f07d0dffde337
[fw/sdcc] / device / examples / ds390 / ow390 / owfile.c
1 #define DEBUG_OW_FILE 0
2 #if DEBUG_OW_FILE
3 #include <stdio.h>
4 #endif
5 //---------------------------------------------------------------------------
6 // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
7 // 
8 // Permission is hereby granted, free of charge, to any person obtaining a 
9 // copy of this software and associated documentation files (the "Software"), 
10 // to deal in the Software without restriction, including without limitation 
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 
12 // and/or sell copies of the Software, and to permit persons to whom the 
13 // Software is furnished to do so, subject to the following conditions:
14 // 
15 // The above copyright notice and this permission notice shall be included 
16 // in all copies or substantial portions of the Software.
17 // 
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
19 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
20 // MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
21 // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES 
22 // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
23 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
24 // OTHER DEALINGS IN THE SOFTWARE.
25 // 
26 // Except as contained in this notice, the name of Dallas Semiconductor 
27 // shall not be used except as stated in the Dallas Semiconductor 
28 // Branding Policy. 
29 //---------------------------------------------------------------------------
30 //
31 // owFile.C: Rudimentary level functions for reading and writing TMEX
32 //             files on NVRAM iButton using the packet level functions.
33 //
34 // Version:  2.00
35 //
36 // History:
37 //           1.02 -> 1.03  Removed caps in #includes for Linux capatibility
38 //           1.03 -> 2.00  Changed 'MLan' to 'ow'. Added support for 
39 //                         multiple ports.  
40 //
41
42 #include "ownet.h"
43
44 //--------------------------------------------------------------------------
45 // Read a TMEX file return it in the provided buffer. 
46 //
47 // 'portnum'  - number 0 to MAX_PORTNUM-1.  This number was provided to
48 //              OpenCOM to indicate the port number.
49 // 'filename' - pointer to five byte filename to read where the
50 //              the first four bytes are the name and the fifth is
51 //              the extension (0 to 101 decimal).             
52 // 'buf'      - pointer to a buffer to place the file information into.
53 //              This may need to be as large as 7084 bytes.
54 // 
55 // Supported devices: All devices supported by owReadPacketStd
56 //
57 // Returns:  >=0  success, number of bytes in the buffer
58 //           <0   failed to read the file (error code) 
59 //
60 int owReadFile(int portnum, uchar *filename, uchar *buf)
61 {  
62   uchar dirpg=0,pgbuf[32],filepg=0;
63   char pglen;
64   ushort bufcnt=0,i;
65                
66 #if DEBUG_OW_FILE
67    printf ("owReadFile: %s\n", filename);
68 #endif
69    // loop read directory pages until the file entry is found
70    do
71    {
72       // read a directory page
73       pglen = owReadPacketStd(portnum,TRUE,dirpg,pgbuf);  
74        
75       // check for reading error
76       if (pglen <= 0)
77          return READ_ERROR;
78          
79       // if this is the first page make sure this is a directory
80       // structure
81       if (  ((dirpg == 0) && 
82             ((pgbuf[0] != 0xAA) || (pgbuf[1] != 0) || (pglen < 7)))
83             ||
84             ((pglen-1) % 7) ) 
85          return INVALID_DIR;
86       
87       // loop through each file entry in directory page (page 0 exception)
88       for (i = (dirpg == 0) ? 7 : 0; i < 28; i += 7)
89       {     
90          // file entry found?
91          if ((filename[0] == pgbuf[i]) &&
92              (filename[1] == pgbuf[i+1]) &&
93              (filename[2] == pgbuf[i+2]) &&
94              (filename[3] == pgbuf[i+3]) &&
95              (filename[4] == (pgbuf[i+4] & 0x7F)) )
96          {
97             // get the file starting page number
98             filepg = pgbuf[i+5];
99 #if DEBUG_OW_FILE
100             printf ("owReadFile: file %s starts at %d\n", filename, filepg);
101 #endif
102             break;
103          }
104       }
105       
106       // get the next directory page (from page pointer) 
107       dirpg = pgbuf[pglen-1];
108    }
109    while (dirpg && (filepg == 0));  
110    
111    // check if file found
112    if (!filepg)
113       return NO_FILE;
114    
115    // loop to read the file pages
116    do
117    {
118       // read a file page
119       pglen = owReadPacketStd(portnum,TRUE,filepg,pgbuf);  
120       
121       // check result of read
122       if (pglen <= 0) {
123         return READ_ERROR;
124       }
125    
126       // append the page data to the buffer
127       for (i = 0; i < (pglen - 1); i++)
128          buf[bufcnt++] = pgbuf[i];
129
130       // get the next file page (from page pointer) 
131       _asm ;johan _endasm;
132       filepg = pgbuf[pglen-1];
133    }
134    while (filepg);
135
136    // return the number of data bytes read
137    return bufcnt;
138 }
139
140
141 //--------------------------------------------------------------------------
142 // Format and Write a TMEX file. 
143 // Any previous files will be removed in the Format operation.
144 // The file length 'fllen' can be up to:
145 //     420  bytes for a DS1993   
146 //     1736 bytes for a DS1995
147 //     7084 bytes for a DS1996.
148 //
149 // 'portnum'  - number 0 to MAX_PORTNUM-1.  This number was provided to
150 //              OpenCOM to indicate the port number.
151 // 'filename' - pointer to five byte filename to write where the
152 //              the first four bytes are the name and the fifth is
153 //              the extension (0 to 101 decimal).             
154 // 'buf'      - pointer to a buffer containing the file information to write.
155 //
156 // Supported devices: DS1993, DS1994, DS1995, DS1996
157 //
158 // Returns:  TRUE(1) success, device formated and file written
159 //           <0      failed to read the file (error code) 
160 //     
161 //
162 int owFormatWriteFile(int portnum, uchar *filename, int fllen, uchar *buf)
163 {
164    uchar dummydir[] = { 0xAA, 0, 0x80, 0x01, 0, 0, 0, 0 },
165       newdir[] = { 0xAA, 0, 0x80, 0x01, 0, 0, 0, ' ', ' ', ' ', ' ', 0, 1, 1, 0 },
166       bmpg1[] = { 0x03,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x02 },
167       bmpg2[] = { 0,0,0,0,0 }, pgbuf[32];   
168    int i,numdirpgs,flpg,bmpg1len,bmpg2len,cntleft,pos,numpgs;
169
170 #if DEBUG_OW_FILE
171    printf ("owFormatWriteFile: %s %d\n", filename, fllen);
172 #endif
173    // calculate the number of pages needed to write the file
174    numpgs = (fllen / 28) + ((fllen % 28) ? 1 : 0);
175    
176    // put the file in the newdirectory
177    for(i = 0; i < 5; i++)
178       newdir[i+7] = filename[i];
179    newdir[13] = (uchar)numpgs;
180    
181    // set the directory pages for formatting device depending on the device type
182    switch (SerialNum[portnum][0])  //jpe
183    {
184       case 0x06:  // DS1993
185          // check for file too big
186          if (numpgs > 15)
187             return FILE_TOO_BIG;
188          // set the bitmap in the directory page
189          for (i = 0; i < numpgs; i++)
190             bitacc(WRITE_FUNCTION,1,i+1,&newdir[3]);
191          numdirpgs = 1;
192          flpg = 1;   
193          newdir[12] = (uchar)flpg;
194          break;                               
195       case 0x0A:  // DS1995
196          // check for file too big
197          if (numpgs > 62)
198             return FILE_TOO_BIG;       
199          // set to external bitmap file
200          newdir[2] = 0; 
201          // set the bitmap in the first (and only) bitmap page
202          for (i = 0; i < numpgs; i++)
203             bitacc(WRITE_FUNCTION,1,i+2,&bmpg1[0]);
204          numdirpgs = 2;
205          flpg = 2; 
206          newdir[12] = (uchar)flpg; // startpage
207          bmpg1len = 9;                          
208          newdir[3] = 0; // remove local bitmap
209          newdir[5] = 1; // bitmap start page
210          newdir[6] = 1; // bitmap number of pages
211          break;                               
212       case 0x0C:  // DS1996 
213          // check for file too big
214          if (numpgs > 253)
215             return FILE_TOO_BIG;
216          // set to external bitmap file
217          newdir[2] = 0; 
218          // set the 3rd bitmap page in the bitmap
219          bitacc(WRITE_FUNCTION,1,2,&bmpg1[0]);
220          
221          // set the bitmap in the first and second bitmap page
222          for (i = 0; i < numpgs; i++)
223          {
224             if (i <= 221)
225                bitacc(WRITE_FUNCTION,1,i+3,&bmpg1[0]);  
226             else
227                bitacc(WRITE_FUNCTION,1,i-221,&bmpg2[0]);  
228          }   
229          numdirpgs = 3;
230          flpg = 3;   
231          newdir[12] = (uchar)flpg; // startpage
232          bmpg1len = 29;  
233          bmpg2len = 5;  
234          newdir[3] = 0; // remove local bitmap
235          newdir[5] = 1; // bitmap start page
236          newdir[6] = 2; // bitmap number of pages
237          break;                               
238       default:
239          return WRONG_TYPE;
240    }
241    
242    // write a dummy directory in page 0 in case we get interrupted
243    if (!owWritePacketStd(portnum,0,dummydir,8,FALSE,FALSE))
244       return WRITE_ERROR;
245    
246    // loop to write the file in contiguous pages start with flpg
247    cntleft = fllen;  // count of bytes left to write  
248    pos = 0; // current position in the buffer to write
249    while (cntleft > 0)
250    {
251       // get a page of data to write
252       for (i = 0; i < ((cntleft > 28) ? 28 : cntleft); i++)
253          pgbuf[i] = buf[pos++];
254                                     
255       // adjust the bytes left
256       cntleft -= i;
257                                     
258       // set the next page pointer   
259       pgbuf[i] = (cntleft == 0) ? 0 : flpg+1;
260       
261       // write the page and check to result
262       if (!owWritePacketStd(portnum,flpg,pgbuf,i+1,FALSE,FALSE))
263          return WRITE_ERROR;
264       
265       // set the next page
266       flpg++;      
267    } 
268
269    // now write the second bitmap page if needed
270    if (numdirpgs == 3)
271       if (!owWritePacketStd(portnum,2,bmpg2,bmpg2len,FALSE,FALSE))
272          return WRITE_ERROR;
273
274    // now write the first bitmap page if needed
275    if (numdirpgs >= 2)
276       if (!owWritePacketStd(portnum,1,bmpg1,bmpg1len,FALSE,FALSE))
277          return WRITE_ERROR;
278    
279    // now write the directory page
280    if (!owWritePacketStd(portnum,0,newdir,15,FALSE,FALSE))
281       return WRITE_ERROR;
282    
283    // success file written
284    return TRUE;
285
286