//--------------------------------------------------------------------------- // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // // Except as contained in this notice, the name of Dallas Semiconductor // shall not be used except as stated in the Dallas Semiconductor // Branding Policy. //-------------------------------------------------------------------------- // // owPgRW.c - Reads and writes pages for the File I/O operations. // version 1.00 // // Include Files #include "owfile.h" #include "rawmem.h" // External Functions extern SMALLINT FindPage(int portnum, uchar *SNum, PAGE_TYPE *pg, uchar mflag, uchar time, uchar *buf, int *len, uchar *space); extern uchar AddPage(int portnum, uchar *SNum, PAGE_TYPE pg, uchar *buf, int len); extern void FindEmpties(int portnum, uchar *SNum, uchar *BM, PAGE_TYPE *avail, PAGE_TYPE *next); extern SMALLINT BitMapChange(int portnum, uchar *SNum, uchar, uchar, uchar *); extern void setcrc16(int,ushort); extern ushort docrc16(int,ushort); extern SMALLINT isJob(int,uchar *); extern SMALLINT getJobData(int,uchar *,PAGE_TYPE,uchar *,int *); extern SMALLINT setJobData(int,uchar *,PAGE_TYPE,uchar *,int); extern SMALLINT isJobWritten(int,uchar *,PAGE_TYPE); // Functions defined in this file SMALLINT Read_Page(int portnum, uchar *SNum, uchar *buff, uchar flag, PAGE_TYPE *pg, int *len); SMALLINT Write_Page(int portnum, uchar *SNum, uchar *buff, PAGE_TYPE page, int len); SMALLINT ExtWrite(int portnum, uchar *SNum, uchar strt_page, uchar *file, int fllen, uchar *BM); SMALLINT ExtRead(int portnum, uchar *SNum, uchar *file, int start_page, int maxlen, uchar del, uchar *BM, int *fl_len); SMALLINT ExtendedRead_Page(int portnum, uchar *SNum, uchar *buff, PAGE_TYPE pg); //-------------------------------------------------------------------------- // Read_Page: // // Read a default data structure page from the current Touch Memory. // The record will be placed shorto a (uchar) memory location // starting at the location poshorted to by (buf). This function will // read a page out of normal memory (flag = REGMEM) or a status memory // page out of an eprom (flag = STATUSMEM). If the page being read is // redirected as in an eprom device then the page value passes by referece // is changed to match the new page. // // portnum the port number of the port being used for the // 1-Wire Network. // SNum the serial number for the part that the read is // to be done on. // flag tells weather to read regular memory or status memory // buff location for data read // page page number to read packet from // SMALLINT Read_Page(int portnum, uchar *SNum, uchar *buff, uchar flag, PAGE_TYPE *pg, int *len) { SMALLINT bank; int page; int jobopen = FALSE; int cnt = 0; uchar extra[3],space; uchar temp_buff[32]; uchar rd_buf[2]; int i; // Are program jobs possible // is there a job that has been opened and is this a regular memory read if(isJob(portnum,SNum)) jobopen = TRUE; // loop while redirected for (cnt = 0; cnt <= 256; cnt++) { // if an program job is open then check there for page if(jobopen && (flag != STATUSMEM)) { if(getJobData(portnum,SNum,*pg,buff,len)) return TRUE; } // nope so look for page in cache if(FindPage(portnum,SNum,pg,flag,TRUE,buff,len,&space)) { if(*len == 0x41) { *pg = buff[0]; } else if(flag != STATUSMEM) return TRUE; } else { bank = getBank(portnum,SNum,*pg,flag); page = getPage(portnum,SNum,*pg,flag); // nope so get it from the part // if the page is in the status memory then call read status if (flag == STATUSMEM) { if(owIsWriteOnce(bank,portnum,SNum) && owHasExtraInfo(bank,SNum)) { if(!owReadPageExtraCRC(bank,portnum,SNum,page,&temp_buff[0],&extra[0])) { if(extra[0] == 0xFF) return FALSE; } } else { if(owHasPageAutoCRC(bank,SNum)) { if(!owReadPageCRC(bank,portnum,SNum,page,&temp_buff[0])) return FALSE; } else { if(!owReadPage(bank,portnum,SNum,page,FALSE,&temp_buff[0])) return FALSE; } extra[0] = 0xFF; } if(extra[0] != 0xFF) { rd_buf[0] = ~extra[0]; AddPage(portnum,SNum,*pg,&rd_buf[0],0x41); *pg = (PAGE_TYPE) rd_buf[0]; continue; } else { *len = 8; for(i=0;i<*len;i++) buff[i] = temp_buff[i]; AddPage(portnum,SNum,*pg,&buff[0],*len); return TRUE; } } // else call on the regular readpack function else { *len = 0; if(owIsWriteOnce(bank,portnum,SNum) && owHasExtraInfo(bank,SNum)) { if(!owReadPagePacketExtra(bank,portnum,SNum,page,FALSE, &temp_buff[0],len,&extra[0])) { if(extra[0] == 0xFF) return FALSE; } } else { if(owHasPageAutoCRC(bank,SNum)) { if(!owReadPageCRC(bank,portnum,SNum,page,&temp_buff[0])) return FALSE; } else { if(!owReadPage(bank,portnum,SNum,page,FALSE,&temp_buff[0])) return FALSE; } extra[0] = 0xFF; } if(extra[0] != 0xFF) { rd_buf[0] = ~extra[0]; AddPage(portnum,SNum,*pg,&rd_buf[0],0x41); *pg = (PAGE_TYPE) rd_buf[0]; continue; } else { if(*len > 0) { if(*len > 32) { OWERROR(OWERROR_INVALID_PACKET_LENGTH); return FALSE; } for(i=0;i<(*len);i++) buff[i] = temp_buff[i]; } else { if(temp_buff[0] > 32) { OWERROR(OWERROR_INVALID_PACKET_LENGTH); return FALSE; } for(i=1;i<(temp_buff[0]+1);i++) buff[i-1] = temp_buff[i]; *len = temp_buff[0]; } AddPage(portnum,SNum,*pg,&buff[0],*len); return TRUE; } } } } // could not find the page return FALSE; } //-------------------------------------------------------------------------- // Write_Page: // // Write a page to a Touch Memory at a provided location (pg). // // portnum the port number of the port being used for the // 1-Wire Network. // SNum the serial number for the part that the read is // to be done on. // buff location of the write data // page page number to write the packet // len the length of the packet // SMALLINT Write_Page(int portnum, uchar *SNum, uchar *buff, PAGE_TYPE pg, int len) { SMALLINT bank; PAGE_TYPE page; // check for length too long for a page if (len > 29) { OWERROR(OWERROR_INVALID_PACKET_LENGTH); return FALSE; } // Are program jobs possible // is there a job that has been opened if(isJob(portnum,SNum)) { if(setJobData(portnum,SNum,pg,buff,len)) return TRUE; } bank = getBank(portnum,SNum,pg,REGMEM); page = getPage(portnum,SNum,pg,REGMEM); if(!owWritePagePacket(bank,portnum,SNum,page,buff,len)) return FALSE; else AddPage(portnum,SNum,pg,buff,len); return TRUE; } //-------------------------------------------------------------------------- // ExtWrite writes an extended file at a location. The bitmap bits are // set each time a pages is written and verified. // // portnum the port number of the port being used for the // 1-Wire Network. // SNum the serial number for the part that the read is // to be done on. // file location of the file to write // fllen the length of the file // SMALLINT ExtWrite(int portnum, uchar *SNum, uchar strt_page, uchar *file, int fllen, uchar *BM) { int pgs = 0; int len = 0; PAGE_TYPE avail,next; uchar WrStr[32]; int i,j; if(fllen == 0) { BitMapChange(portnum,SNum,strt_page,1,BM); return TRUE; } // calculate number of universal pages in file pgs = fllen / 28; if (fllen % 28 || !fllen) pgs++; // find available page and next available page FindEmpties(portnum,SNum,BM,&avail,&next); next = avail; avail = strt_page; // loop to write each page of the file for(i=0;i 28) len = 28; // copy next chuck to write buffer for (j=0; j maxlen) { OWERROR(OWERROR_BUFFER_TOO_SMALL); return FALSE; } for(i=0;i<(len-1);i++) file[buff_len++] = pgbuf[i]; } bank = getBank(portnum,SNum,pg,REGMEM); page = getPage(portnum,SNum,pg,REGMEM); // flag to indicate that the page should be cleared in the BM flag = FALSE; // do if have a NVRAM device if(owIsReadWrite(bank,portnum,SNum) && owIsGeneralPurposeMemory(bank,SNum)) flag = TRUE; // or non written buffered eprom page if(isJob(portnum,SNum)) { // see if page set to write but has not started yet if(isJobWritten(portnum,SNum,pg) && del) { flag = TRUE; } } // clear bit in bitmap if(flag) BitMapChange(portnum,SNum,pg,0,BM); // check on continuation pointer if (pgbuf[len-1] == 0) { *fl_len = buff_len; done = TRUE; // all done } else pg = pgbuf[len-1]; } while(!done); return TRUE; } //-------------------------------------------------------------------------- // ExtendedRead_Page: // // Read a extended page from the current Eprom Touch Memory. // The record will be placed into a (uchar) memory location // starting at the location pointed to by (buf). This function will // read a page out of normal memory. If the page being read is // redirected then an error is returned // The following return codes will be provided to the caller: // // >=0 : Operation successful, the string is placed at // (buf). Length is the return value // XNO_DEVICE : No Touch Memory detected on 1-Wire. // XFILE_READ_ERR : Touch Memory detected but contact was lost or // record invalid. // XONE_WIRE_PORT_ERROR : error on 1-wire (setup may not have been called // yet) // XINVALID_SESSION : session not valid // SMALLINT ExtendedRead_Page(int portnum, uchar *SNum, uchar *buff, PAGE_TYPE pg) { SMALLINT bank; PAGE_TYPE page; uchar extra[20],buf[32]; int len,i; bank = getBank(portnum,SNum,pg,REGMEM); page = getPage(portnum,SNum,pg,REGMEM); if(!owIsWriteOnce(bank,portnum,SNum) && ((SNum[0] != 0x18) && (SNum[0] != 0x33) && (SNum[0] != 0xB3)) ) { OWERROR(OWERROR_NOT_WRITE_ONCE); return FALSE; } // check on the program job to see if this page is in it if(isJob(portnum,SNum)) { buf[0] = 0xFF; buf[30] = 0xFF; buf[31] = 0xFF; if(getJobData(portnum,SNum,pg,&buff[1],&len)) { for(i=len;i<29;i++) buf[i] = 0xFF; return TRUE; } } if(owIsWriteOnce(bank,portnum,SNum)) { if(!owReadPageExtraCRC(bank,portnum,SNum,page,&buff[0],&extra[0])) return FALSE; } else { if(!owReadPageExtra(bank,portnum,SNum,page,FALSE,&buff[0],&extra[0])) return FALSE; for(i=0;i