//--------------------------------------------------------------------------- // 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. //-------------------------------------------------------------------------- // // owprgm.c - This source file contains the EPROM Program routines. // version 1.00 // // Include Files #include "ownet.h" #include "owfile.h" #include "rawmem.h" // external function prototypes extern SMALLINT ReadBitMap(int, uchar *, uchar *); extern void InitDHash(void); extern SMALLINT Read_Page(int portnum, uchar *SNum, uchar *buff, uchar flag, PAGE_TYPE *pg, int *len); extern void setcrc16(int,ushort); extern ushort docrc16(int,ushort); extern void owSerialNum(int,uchar *,SMALLINT); extern SMALLINT BitMapChange(int, uchar *, uchar, uchar, uchar *); extern SMALLINT ExtendedRead_Page(int portnum, uchar *SNum, uchar *buff, PAGE_TYPE pg); extern SMALLINT owFirst(int,SMALLINT,SMALLINT); extern SMALLINT owNext(int,SMALLINT,SMALLINT); extern void owSerialNum(int,uchar *,int); extern PAGE_TYPE getLastPage(int, uchar *); extern SMALLINT owProgramByte(int,SMALLINT,int,SMALLINT,SMALLINT,SMALLINT); extern int maxPages(int,uchar *); // exportable function prototypes SMALLINT owCreateProgramJob(int, uchar *); SMALLINT owDoProgramJob(int, uchar *); SMALLINT isJob(int,uchar *); SMALLINT isJobWritten(int,uchar *,PAGE_TYPE); SMALLINT getJobData(int,uchar *,PAGE_TYPE,uchar *,int *); SMALLINT setJobData(int,uchar *,PAGE_TYPE,uchar *,int); SMALLINT setJobWritten(int,uchar *,PAGE_TYPE,SMALLINT); SMALLINT getOrigBM(int,uchar *,uchar *); SMALLINT setProgramJob(int,uchar *,uchar,int); SMALLINT getProgramJob(int,uchar *,uchar *,int); // local function prototypes SMALLINT WriteJobByte(int, uchar *, PAGE_TYPE, short, uchar, short); SMALLINT TerminatePage(int, uchar *, short, uchar *); // global paramters SMALLINT job_started = FALSE; ProgramJob job; //-------------------------------------------------------------------------- // Start an programming job. This function assumes that the Garbage bag D // is at least 11049 bytes long. This function check to see if the // current device is of the correct type. It reads the bitmap of the // device for reference during accumulation of Program write jobs. // // portnum the port number of the port being used for the // 1-Wire Network. // SNum the serial number for the job part to be executed on. // // Returns: TRUE program job created // FALSE error // SMALLINT owCreateProgramJob(int portnum, uchar *SNum) { SMALLINT bank = 1; short i,j; // Make sure there is no current job job_started = FALSE; // check the device type if(!owIsWriteOnce(bank,portnum,SNum)) { OWERROR(OWERROR_WRONG_TYPE); return FALSE; } // flush all of the cached pages InitDHash(); // read the bitmap if(!ReadBitMap(portnum,SNum,&job.EBitmap[0])) return FALSE; // keep the original bitmap for (i = 0; i < 32; i++) job.OrgBitmap[i] = job.EBitmap[i]; // clear all the job pages for (i = 0; i < MAX_NUM_PGS; i++) { job.Page[i].wr = PJOB_NONE; // clear bits in each page for (j = 0; j < 29; j++) job.Page[i].data[j] = 0xFF; } // record the current rom for (i = 0; i < 8; i++) job.ERom[i] = SNum[i]; // Set the job to true job_started = TRUE; return TRUE; } //-------------------------------------------------------------------------- // Do an program job. This function assumes that the Garbage back D // is at least 11049 bytes long. This function check to see if the // current device is of the correct type. It reads the bitmap of the // device for reference during accumulation of Program write jobs. // // Returns: =1 program job created // <0 TMEX error // SMALLINT owDoProgramJob(int portnum, uchar *SNum) { uchar BM[32],WPBM[32],RWPBM[32],pgbuf[32],RDB[256],tpg; short i,j,l,Bcnt=0,mBcnt,xtra,pg,cnt,inflp=0,redit; uchar ROM[8]; SMALLINT bank = 1; PAGE_TYPE page = 0; int maxp = 0; int flag; // checks to see if the ROM number has changed for(i=0;i<8;i++) if(job.ERom[i] != SNum[i]) { OWERROR(OWERROR_NONMATCHING_SNUM); return FALSE; } // Make sure there is a job open if (job_started != TRUE) { OWERROR(OWERROR_NO_PROGRAM_JOB); return FALSE; } // Make sure that only eproms are on the line l = TRUE; // flag to see if operation is ok flag = owFirst(portnum,TRUE,FALSE); while(flag) { // check the family code owSerialNum(portnum,&ROM[0],TRUE); if(!owIsWriteOnce(bank,portnum,&ROM[0])) { l = FALSE; break; } // look for next device flag = owNext(portnum,FALSE,FALSE); } // restore the rom number for (i = 0; i < 8; i ++) ROM[i] = job.ERom[i]; owSerialNum(portnum,&ROM[0],FALSE); // check for fail if (l == FALSE) { OWERROR(OWERROR_NON_PROGRAM_PARTS); return FALSE; } // flush all of the cached pages InitDHash(); maxp = maxPages(portnum,SNum); // read the write protect bits and redirect write protect bits // and redirection bytes if(owIsWriteOnce(bank,portnum,&ROM[0]) && ((ROM[0] == 0x0B) || (ROM[0] == 0x0F))) { // DS1985,DS1986 for(i=0;i<32;i++) BM[i] = job.OrgBitmap[i]; // get number of status bytes needed mBcnt = ((maxp+1) / 8) + ((((maxp+1) % 8) > 0) ? 1 : 0); // get number of pages to get that many bytes l = (mBcnt / 8) + ((mBcnt % 8) > 0 ? 1 : 0); // loop through the number of write protect bitmap pages for(i=0;i> 4) & 0x0F; // extract the write protect bitmap WPBM[0] = (~pgbuf[0]) & 0x0F; // extract the redirection write protect RWPBM[0] = 0; // there are non in the DS1982 // extract the redirection bytes for (i = 0; i < 4; i++) RDB[i] = ~(pgbuf[i+1]); } else return TRUE; } else { OWERROR(OWERROR_NON_PROGRAM_PARTS); return FALSE; } // flush all of the cached pages InitDHash(); // loop through all of the pages and check too see how many pages need to // be re-directed. From that see if there is enough room on the device // to do all of the desired operations // Count the extra-pages for later xtra = maxp+1; for(i=0;i<=maxp;i++) { // if the page is aleady taken then subtract 2 pages if ((job.Page[i].wr & PJOB_MASK) == PJOB_WRITE) // (2.01) xtra -= (((BM[i / 8] >> (i % 8)) & 0x01) ? 2 : 1); else if ((BM[i / 8] >> (i % 8)) & 0x01) xtra--; } // check to see if the changes will really fit on the devices if (xtra < 0) { OWERROR(OWERROR_OUT_OF_SPACE); return FALSE; } // loop to write each page that has an eprom job for(i=0;i<=maxp;i++) { // check for an infinite loop (if redirection point to each other) if (inflp++ > 20480) { OWERROR(OWERROR_PROGRAM_WRITE_PROTECT); return FALSE; } // check the type of operation (1 = page write, 2 redirection) // page write if ((job.Page[i].wr & PJOB_MASK) == PJOB_WRITE || (job.Page[i].wr & PJOB_MASK) == PJOB_TERM) { // flag the says we are going to re-direct to this page redit = FALSE; pg = -1; // check to see if this page is already re-directed if (RDB[i] != 0x00) { // get the page and redirect pg = RDB[i]; redit = TRUE; // check to see if this could be real if ((job.Page[pg].wr & PJOB_MASK) != PJOB_NONE) { OWERROR(OWERROR_PROGRAM_WRITE_PROTECT); return FALSE; } } // not re-directed else { // if write protected set or bitmap says already used then write // redirection byte and change the Program job to an empty page // only redirect this is a JOB_WRITE job if (((WPBM[i / 8] >> (i % 8)) & 0x01) || (((BM[i / 8] >> (i % 8)) & 0x01) && ((job.Page[i].wr & PJOB_MASK) == PJOB_WRITE))) { // check if the write-protect redirection byte is set if ((RWPBM[i / 8] >> (i % 8)) & 0x01) { OWERROR(OWERROR_PROGRAM_WRITE_PROTECT); return FALSE; } // able to be re-directed so do it else redit = TRUE; } // ok so write the page else { // construct the page to write for(j=0;j<=job.Page[i].len;j++) pgbuf[j] = job.Page[i].data[j]; // set this page as having an attempt made to programming job.Page[getLastPage(portnum,SNum)].wr |= PJOB_START; bank = getBank(portnum,SNum,(PAGE_TYPE)i,REGMEM); page = getPage(portnum,SNum,(PAGE_TYPE)i,REGMEM); if(!owWritePagePacket(bank,portnum,SNum,page,&pgbuf[0],job.Page[i].len)) return FALSE; // check to see if the bitmap is not set if (!(BM[i / 8] & (0x01 << (i % 8)))) { // set the bitmap bit for this page // EPROM1/EPROM3 exception if((ROM[0] == 0x0B) || (ROM[0] == 0x0F)) { if(owProgramByte(portnum,(~(0x01 << (i%8))),(0x40+(i/8)),0x55,1,TRUE) == -1) return FALSE; } else { if(owProgramByte(portnum,(~(0x01 << (i+4))),0,0x55,0,TRUE) == -1) return FALSE; } // update the bitmap BitMapChange(portnum,SNum,(uchar)i,1,&BM[0]); // clear this Program job job.Page[i].wr = PJOB_NONE; } } } // check to see if need to re-direct the page if (redit == TRUE) { // find an empty page in the Program job and bitmap if (pg == -1) { for(j=1;j<=maxp;j++) { // loop for a spot that is free in the bitmap, has not // Program job on it, can be redirected, and is not write // protected. if (!((BM[j / 8] >> (j % 8)) & 0x01) && ((job.Page[j].wr & PJOB_MASK) == PJOB_NONE) && (RDB[j] == 0x00) && !((WPBM[j / 8] >> (j % 8)) & 0x01) && !((RWPBM[j / 8] >> (j % 8)) & 0x01)) { pg = j; break; } } // check to see if one was found, if not then we are out of space if (pg == -1) { OWERROR(OWERROR_OUT_OF_SPACE); return FALSE; } } // change the Program job to reflect the change job.Page[pg].wr = PJOB_WRITE; job.Page[pg].len = job.Page[i].len; // copy the data to the new job location for(j=0;j> (i % 8)) & 0x01) && (RDB[i] != pg)) || ((RDB[i] | pg) ^ pg)) { OWERROR(OWERROR_PROGRAM_WRITE_PROTECT); return FALSE; } // write the redirection byte and set the bitmap // EPROM1/EPROM3 exception if((ROM[0] == 0x0B) || (ROM[0] == 0x0F)) { if((owProgramByte(portnum,(~pg),(0x100+i),0x55,1,TRUE) == -1) ||(owProgramByte(portnum,(~(0x01 << (i%8))),(0x40+(i/8)),0x55,1,TRUE) == -1)) return FALSE; } else { if((owProgramByte(portnum,(~pg),(1+i),0x55,0,TRUE) == -1) ||(owProgramByte(portnum,(~(0x01 << (i+4))),0,0x55,0,TRUE) == -1)) return FALSE; } BitMapChange(portnum,SNum,(uchar)i,1,&BM[0]); // clear this Program job job.Page[i].wr = PJOB_NONE; } // overwrite add file page else if((job.Page[i].wr & PJOB_MASK) == PJOB_ADD) { for(j=1;j<=29;j++) { // check to see if this byte needs to be programmed if(job.Page[i].bm[j / 8] & (0x01 << (j % 8))) { // write the byte if((ROM[0] == 0x0B) || (ROM[0] == 0x0F)) { if(owProgramByte(portnum,job.Page[i].data[j-1],((i<<5)+j),0x0F,1,TRUE) == -1) return FALSE; } else { if(owProgramByte(portnum,job.Page[i].data[j-1],((i<<5)+j),0x0F,0,TRUE) == -1) return FALSE; } } } // check to see if the bitmap is not set if (!(BM[i / 8] & (0x01 << (i % 8)))) { // set the bitmap bit for this page // EPROM1/EPROM3 exception if ((ROM[0] == 0x0B) || (ROM[0] == 0x0F)) { if(owProgramByte(portnum,(~(0x01 << (i%8))),(0x40+(i/8)),0x55,1,TRUE) == -1) return FALSE; } else { if(owProgramByte(portnum,(~(0x01 << (i+4))),0,0x55,0,TRUE) == -1) return FALSE; } BitMapChange(portnum,SNum,(uchar)i,1,&BM[0]); } // clear this Program job job.Page[i].wr = PJOB_NONE; } } // turn off the Program job job_started = FALSE; // finished return TRUE; } //-------------------------------------------------------------------------- // Indicates if a job has already been initialized and waiting to be // written. // // 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. // // return: TRUE : job started // FALSE : no jobs // SMALLINT isJob(int portnum, uchar *SNum) { int i; for(i=0;i<8;i++) if(SNum[i] != job.ERom[i]) { return FALSE; } return job_started; } //------------------------------------------------------------------------- // Indicates weather a page needs to be written // // 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. // pg the page that is checked to see if it needs to // be written. // // return: TRUE: page needs to be written // FALSE: doesn't need to be written // SMALLINT isJobWritten(int portnum,uchar *SNum,PAGE_TYPE pg) { int i; for(i=0;i<8;i++) if(SNum[i] != job.ERom[i]) { OWERROR(OWERROR_NONMATCHING_SNUM); return FALSE; } return job.Page[pg].wr; } //------------------------------------------------------------------------- // Sets the status for the job on that 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. // pg the page that is checked to see if it needs to // be written. // status the status that the page is being set to. // // return: TRUE: page needs to be written // FALSE: doesn't need to be written // SMALLINT setJobWritten(int portnum,uchar *SNum,PAGE_TYPE pg,SMALLINT status) { int i; for(i=0;i<8;i++) if(SNum[i] != job.ERom[i]) { OWERROR(OWERROR_NONMATCHING_SNUM); return FALSE; } job.Page[pg].wr = status; return TRUE; } //------------------------------------------------------------------------- // The purpose is to get the original bitmap. // // 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. // BM the bitmap to set to the original bitmap. // // return: TRUE: page needs to be written // FALSE: doesn't need to be written // SMALLINT getOrigBM(int portnum, uchar *SNum, uchar *BM) { int i; for(i=0;i<8;i++) if(SNum[i] != job.ERom[i]) { OWERROR(OWERROR_NONMATCHING_SNUM); return FALSE; } for(i=0;i<32;i++) BM[i] = job.OrgBitmap[i]; return TRUE; } //------------------------------------------------------------------------- // Gets the page data of the job // // 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. // pg the page that the data is gotten from. // buff the buffer to store the data on that page // len the len of the data for that page // // return: TRUE: page needs to be written // FALSE: doesn't need to be written // SMALLINT getJobData(int portnum,uchar *SNum,PAGE_TYPE page,uchar *buff,int *len) { int i; for(i=0;i<8;i++) if(SNum[i] != job.ERom[i]) { OWERROR(OWERROR_NONMATCHING_SNUM); return FALSE; } if(job.Page[page].wr != PJOB_NONE) { for(i=0;i 0) job.Page[pg].wr = PJOB_WRITE; return TRUE; } //------------------------------------------------------------------------- // Sets a certain job for programming. // // 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. // value the value to set in the bitmap. // spot the spot to set the bitmap. // // return: TRUE: page needs to be written // FALSE: doesn't need to be written // SMALLINT setProgramJob(int portnum,uchar *SNum,uchar value,int spot) { int i; for(i=0;i<8;i++) if(SNum[i] != job.ERom[i]) { OWERROR(OWERROR_NONMATCHING_SNUM); return FALSE; } job.EBitmap[spot] = value; return TRUE; } //------------------------------------------------------------------------- // Gets a certain number of bitmap job programming starting from the first // value in the array. // // 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. // BM the array of values for the bitmap. // spot the number of spots copied. // // return: TRUE: page needs to be written // FALSE: doesn't need to be written // SMALLINT getProgramJob(int portnum,uchar *SNum,uchar *BM,int spots) { int i; for(i=0;i<8;i++) if(SNum[i] != job.ERom[i]) { OWERROR(OWERROR_NONMATCHING_SNUM); return FALSE; } for(i=0;i