just an example of what SDCC can do for YOU
[fw/sdcc] / device / examples / ds390 / ow390 / owfile.c
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 // owFile.C: Rudimentary level functions for reading and writing TMEX
28 //             files on NVRAM iButton using the packet level functions.
29 //
30 // Version:  2.00
31 //
32 // History:
33 //           1.02 -> 1.03  Removed caps in #includes for Linux capatibility
34 //           1.03 -> 2.00  Changed 'MLan' to 'ow'. Added support for 
35 //                         multiple ports.  
36 //
37
38 #include "ownet.h"
39
40 //--------------------------------------------------------------------------
41 // Read a TMEX file return it in the provided buffer. 
42 //
43 // 'portnum'  - number 0 to MAX_PORTNUM-1.  This number was provided to
44 //              OpenCOM to indicate the port number.
45 // 'filename' - pointer to five byte filename to read where the
46 //              the first four bytes are the name and the fifth is
47 //              the extension (0 to 101 decimal).             
48 // 'buf'      - pointer to a buffer to place the file information into.
49 //              This may need to be as large as 7084 bytes.
50 // 
51 // Supported devices: All devices supported by owReadPacketStd
52 //
53 // Returns:  >=0  success, number of bytes in the buffer
54 //           <0   failed to read the file (error code) 
55 //
56 int owReadFile(int portnum, uchar *filename, uchar *buf)
57 {  
58    uchar dirpg=0,pgbuf[32],filepg=0,pglen;
59    short bufcnt=0,i;
60                
61    // loop read directory pages until the file entry is found
62    do
63    {
64       // read a directory page
65       pglen = owReadPacketStd(portnum,TRUE,dirpg,pgbuf);  
66        
67       // check for reading error
68       if (pglen <= 0)
69          return READ_ERROR;
70          
71       // if this is the first page make sure this is a directory
72       // structure
73       if (  ((dirpg == 0) && 
74             ((pgbuf[0] != 0xAA) || (pgbuf[1] != 0) || (pglen < 7)))
75             ||
76             ((pglen-1) % 7) ) 
77          return INVALID_DIR;
78       
79       // loop through each file entry in directory page (page 0 exception)
80       for (i = (dirpg == 0) ? 7 : 0; i < 28; i += 7)
81       {     
82          // file entry found?
83          if ((filename[0] == pgbuf[i]) &&
84              (filename[1] == pgbuf[i+1]) &&
85              (filename[2] == pgbuf[i+2]) &&
86              (filename[3] == pgbuf[i+3]) &&
87              (filename[4] == (pgbuf[i+4] & 0x7F)) )
88          {
89             // get the file starting page number
90             filepg = pgbuf[i+5];
91             break;
92          }
93       }
94       
95       // get the next directory page (from page pointer) 
96       dirpg = pgbuf[pglen-1];
97    }
98    while (dirpg && (filepg == 0));  
99    
100    // check if file found
101    if (!filepg)
102       return NO_FILE;
103    
104    // loop to read the file pages
105    do
106    {
107       // read a file page
108       pglen = owReadPacketStd(portnum,TRUE,filepg,pgbuf);  
109       
110       // check result of read
111       if (pglen <= 0)
112          return READ_ERROR;
113    
114       // append the page data to the buffer
115       for (i = 0; i < (pglen - 1); i++)
116          buf[bufcnt++] = pgbuf[i];
117
118       // get the next file page (from page pointer) 
119       filepg = pgbuf[pglen-1];
120    }
121    while (filepg);
122
123    // return the number of data bytes read
124    return bufcnt;
125 }
126
127
128 //--------------------------------------------------------------------------
129 // Format and Write a TMEX file. 
130 // Any previous files will be removed in the Format operation.
131 // The file length 'fllen' can be up to:
132 //     420  bytes for a DS1993   
133 //     1736 bytes for a DS1995
134 //     7084 bytes for a DS1996.
135 //
136 // 'portnum'  - number 0 to MAX_PORTNUM-1.  This number was provided to
137 //              OpenCOM to indicate the port number.
138 // 'filename' - pointer to five byte filename to write where the
139 //              the first four bytes are the name and the fifth is
140 //              the extension (0 to 101 decimal).             
141 // 'buf'      - pointer to a buffer containing the file information to write.
142 //
143 // Supported devices: DS1993, DS1994, DS1995, DS1996
144 //
145 // Returns:  TRUE(1) success, device formated and file written
146 //           <0      failed to read the file (error code) 
147 //     
148 //
149 int owFormatWriteFile(int portnum, uchar *filename, int fllen, uchar *buf)
150 {
151    uchar dummydir[] = { 0xAA, 0, 0x80, 0x01, 0, 0, 0, 0 },
152       newdir[] = { 0xAA, 0, 0x80, 0x01, 0, 0, 0, ' ', ' ', ' ', ' ', 0, 1, 1, 0 },
153       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 },
154       bmpg2[] = { 0,0,0,0,0 }, pgbuf[32];   
155    int i,numdirpgs,flpg,bmpg1len,bmpg2len,cntleft,pos,numpgs;
156
157    // calculate the number of pages needed to write the file
158    numpgs = (fllen / 28) + ((fllen % 28) ? 1 : 0);
159    
160    // put the file in the newdirectory
161    for(i = 0; i < 5; i++)
162       newdir[i+7] = filename[i];
163    newdir[13] = (uchar)numpgs;
164    
165    // set the directory pages for formatting device depending on the device type
166    switch (SerialNum[portnum][0])  //jpe
167    {
168       case 0x06:  // DS1993
169          // check for file too big
170          if (numpgs > 15)
171             return FILE_TOO_BIG;
172          // set the bitmap in the directory page
173          for (i = 0; i < numpgs; i++)
174             bitacc(WRITE_FUNCTION,1,i+1,&newdir[3]);
175          numdirpgs = 1;
176          flpg = 1;   
177          newdir[12] = (uchar)flpg;
178          break;                               
179       case 0x0A:  // DS1995
180          // check for file too big
181          if (numpgs > 62)
182             return FILE_TOO_BIG;       
183          // set to external bitmap file
184          newdir[2] = 0; 
185          // set the bitmap in the first (and only) bitmap page
186          for (i = 0; i < numpgs; i++)
187             bitacc(WRITE_FUNCTION,1,i+2,&bmpg1[0]);
188          numdirpgs = 2;
189          flpg = 2; 
190          newdir[12] = (uchar)flpg; // startpage
191          bmpg1len = 9;                          
192          newdir[3] = 0; // remove local bitmap
193          newdir[5] = 1; // bitmap start page
194          newdir[6] = 1; // bitmap number of pages
195          break;                               
196       case 0x0C:  // DS1996 
197          // check for file too big
198          if (numpgs > 253)
199             return FILE_TOO_BIG;
200          // set to external bitmap file
201          newdir[2] = 0; 
202          // set the 3rd bitmap page in the bitmap
203          bitacc(WRITE_FUNCTION,1,2,&bmpg1[0]);
204          
205          // set the bitmap in the first and second bitmap page
206          for (i = 0; i < numpgs; i++)
207          {
208             if (i <= 221)
209                bitacc(WRITE_FUNCTION,1,i+3,&bmpg1[0]);  
210             else
211                bitacc(WRITE_FUNCTION,1,i-221,&bmpg2[0]);  
212          }   
213          numdirpgs = 3;
214          flpg = 3;   
215          newdir[12] = (uchar)flpg; // startpage
216          bmpg1len = 29;  
217          bmpg2len = 5;  
218          newdir[3] = 0; // remove local bitmap
219          newdir[5] = 1; // bitmap start page
220          newdir[6] = 2; // bitmap number of pages
221          break;                               
222       default:
223          return WRONG_TYPE;
224    }
225    
226    // write a dummy directory in page 0 in case we get interrupted
227    if (!owWritePacketStd(portnum,0,dummydir,8,FALSE,FALSE))
228       return WRITE_ERROR;
229    
230    // loop to write the file in contiguous pages start with flpg
231    cntleft = fllen;  // count of bytes left to write  
232    pos = 0; // current position in the buffer to write
233    while (cntleft > 0)
234    {
235       // get a page of data to write
236       for (i = 0; i < ((cntleft > 28) ? 28 : cntleft); i++)
237          pgbuf[i] = buf[pos++];
238                                     
239       // adjust the bytes left
240       cntleft -= i;
241                                     
242       // set the next page pointer   
243       pgbuf[i] = (cntleft == 0) ? 0 : flpg+1;
244       
245       // write the page and check to result
246       if (!owWritePacketStd(portnum,flpg,pgbuf,i+1,FALSE,FALSE))
247          return WRITE_ERROR;
248       
249       // set the next page
250       flpg++;      
251    } 
252
253    // now write the second bitmap page if needed
254    if (numdirpgs == 3)
255       if (!owWritePacketStd(portnum,2,bmpg2,bmpg2len,FALSE,FALSE))
256          return WRITE_ERROR;
257
258    // now write the first bitmap page if needed
259    if (numdirpgs >= 2)
260       if (!owWritePacketStd(portnum,1,bmpg1,bmpg1len,FALSE,FALSE))
261          return WRITE_ERROR;
262    
263    // now write the directory page
264    if (!owWritePacketStd(portnum,0,newdir,15,FALSE,FALSE))
265       return WRITE_ERROR;
266    
267    // success file written
268    return TRUE;
269
270