/** * Writes a new identifier and password to the secure subkey iButton * * portnum the port number of the port being used for the * 1-Wire Network. * key number indicating the key to be read: 0, 1, or 2 * oldName identifier of the key used to confirm the correct * key's password to be changed. Must be exactly length 8. * newName identifier to be used for the key with the new * password. Must be exactly length 8. * newPasswd new password for destination subkey. Must be * exactly length 8. * * return TRUE if the write was successful */ SMALLINT writePassword(int portnum, int key, uchar *oldName, uchar *newName, uchar *newPasswd) { uchar buffer[96]; int i; if(owAccess(portnum)) { //confirm key names and passwd within legal parameters if (key > 0x03) { OWERROR(OWERROR_KEY_OUT_OF_RANGE); return FALSE; } buffer[0] = WRITE_PASSWORD_COMMAND; buffer[1] = (uchar) (key << 6); buffer[2] = (uchar) (~buffer[1]); //prepare buffer to receive 8 bytes of the identifier for(i = 3; i < 11; i++) buffer [i] = 0xFF; if(!owBlock(portnum,FALSE,buffer,11)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } //prepare same subkey identifier for confirmation for(i=0;i<8;i++) buffer[i] = buffer[i+3]; //prepare new subkey identifier for(i=0;i<8;i++) buffer[i+8] = newName[i]; //prepare new password for writing for(i=0;i<8;i++) buffer[i+16] = newPasswd[i]; //send command block if(!owBlock(portnum,FALSE,buffer,24)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } } else { OWERROR(OWERROR_DEVICE_SELECT_FAIL); return FALSE; } return TRUE; }
/** * Writes the data to the scratchpad from the given address. * * portnum the port number of the port being used for the * 1-Wire network. * addr address to begin writing. Must be between * 0x00 and 0x3F. * data data to write. * len the length of the data to write * * return: TRUE if the write worked * FALSE if there was an error in writing */ SMALLINT writeScratchpad (int portnum, int addr, uchar *data, int len) { int dataRoom,i; uchar buffer[96]; if(owAccess(portnum)) { //confirm that data will fit if (addr > 0x3F) { OWERROR(OWERROR_WRITE_OUT_OF_RANGE); return FALSE; } dataRoom = 0x3F - addr + 1; if (dataRoom < len) { OWERROR(OWERROR_DATA_TOO_LONG); return FALSE; } buffer[0] = ( uchar ) WRITE_SCRATCHPAD_COMMAND; buffer[1] = ( uchar ) (addr | 0xC0); buffer[2] = ( uchar ) (~buffer [1]); for(i=0;i<len;i++) buffer[i+3] = data[i]; //send command block if((len+3) > 64) { if(!owBlock(portnum,FALSE,buffer,64)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } else if(!owBlock(portnum,FALSE,&buffer[64],3)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } } else if(!owBlock(portnum,FALSE,buffer,len+3)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } } else { OWERROR(OWERROR_DEVICE_SELECT_FAIL); return FALSE; } return TRUE; }
/* ----------------------------------------------------------------------- ----------------------------------------------------------------------- */ int get_ibl_type(int portnum, uchar page, int offset) { uchar send_block[50]; int send_cnt=0; int i; ushort lastcrc8=255; /* 01/08/2004 [bcl] DigiTemp does this before calling the function * owSerialNum(portnum,SNum,FALSE); */ // Recall the Status/Configuration page // Recall command send_block[send_cnt++] = 0xB8; // Page to Recall send_block[send_cnt++] = page; if(!owBlock(portnum,FALSE,send_block,send_cnt)) return FALSE; send_cnt = 0; if(owAccess(portnum)) { // Read the Status/Configuration byte // Read scratchpad command send_block[send_cnt++] = 0xBE; // Page for the Status/Configuration byte send_block[send_cnt++] = page; for(i=0;i<9;i++) send_block[send_cnt++] = 0xFF; if(owBlock(portnum,FALSE,send_block,send_cnt)) { setcrc8(portnum,0); for(i=2;i<send_cnt;i++) lastcrc8 = docrc8(portnum,send_block[i]); if(lastcrc8 != 0x00) return FALSE; } else { return FALSE; } // Return the requested byte return send_block[2+offset]; }//Access return -1; }
/** * Reads the subkey requested with the given key name and password. * Note that this method allows for reading from the subkey data * only which starts at address 0x10 within a key. It does not allow * reading from any earlier address within a key because the device * cannot be force to allow reading the password. This is why the * subkey number is or-ed with 0x10 in creating the address in bytes * 1 and 2 of the sendBlock. * * portnum the port number of the port being used for the * 1-Wire Network. * data buffer of length 64 into which to write the data * key number indicating the key to be read: 0, 1, or 2 * passwd password of destination subkey * * return: TRUE if reading the subkey was successful. */ SMALLINT readSubkey(int portnum, uchar *data, int key, uchar *passwd) { uchar buffer[96]; int i; if(owAccess(portnum)) { //confirm key within legal parameters if (key > 0x03) { OWERROR(OWERROR_KEY_OUT_OF_RANGE); return FALSE; } buffer[0] = READ_SUBKEY_COMMAND; buffer[1] = (uchar) ((key << 6) | 0x10); buffer[2] = (uchar) (~buffer [1]); //prepare buffer to receive for (i = 3; i < 67; i++) buffer[i] = 0xFF; //insert password data for(i=0;i<8;i++) buffer[i+11] = passwd[i]; //send command block if(!owBlock(portnum,FALSE,buffer,64)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } else if(!owBlock(portnum,FALSE,&buffer[64],3)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } //create block to send back for(i=0;i<64;i++) data[i] = buffer[i+3]; } else { OWERROR(OWERROR_DEVICE_SELECT_FAIL); return FALSE; } return TRUE; }
//---------------------------------------------------------------------- // Read the scratchpad with CRC16 verification for DS1963S. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'address' - pointer to address that is read from scratchpad // 'es' - pointer to offset byte read from scratchpad // 'data' - pointer data buffer read from scratchpad // 'resume' - if true, device access is resumed using the RESUME // ROM command (0xA5). Otherwise, a a MATCH ROM is // used along with the device's entire address number. // // Return: TRUE - scratch read, address, es, and data returned // FALSE - error reading scratch, device not present // // SMALLINT ReadScratchpadSHA18(int portnum, int* address, uchar* es, uchar* data, SMALLINT resume) { short send_cnt=0; uchar send_block[40]; SMALLINT i; ushort lastcrc16; if(!resume) { // access the device OWASSERT( SelectSHA(portnum), OWERROR_ACCESS_FAILED, FALSE ); } else { // transmit RESUME command send_block[send_cnt++] = ROM_CMD_RESUME; resume = 1; // for addition later } // read scratchpad command send_block[send_cnt++] = CMD_READ_SCRATCHPAD; // now add the read bytes for data bytes and crc16 //for (i = 0; i < 37; i++) // send_block[send_cnt++] = 0xFF; memset(&send_block[send_cnt], 0x0FF, 37); send_cnt += 37; // now send the block OWASSERT( owBlock(portnum,resume,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // calculate CRC16 of result setcrc16(portnum,0); for (i = resume; i < send_cnt ; i++) lastcrc16 = docrc16(portnum,send_block[i]); // verify CRC16 is correct OWASSERT( lastcrc16==0xB001, OWERROR_CRC_FAILED, FALSE ); // copy data to return buffers if(address) *address = (send_block[2+resume] << 8) | send_block[1+resume]; if(es) *es = send_block[3+resume]; memcpy(data, &send_block[4+resume], 32); // success return TRUE; }
//---------------------------------------------------------------------- // Perform a scratchpad match using provided data. Fixed data length // of 20 bytes. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'data' - data to use in match scratch operation // 'resume' - if true, device access is resumed using the RESUME // ROM command (0xA5). Otherwise, a a MATCH ROM is // used along with the device's entire address number. // // Return: TRUE - valid match // FALSE - no match or device not present // SMALLINT MatchScratchpadSHA18(int portnum, uchar* data, SMALLINT resume) { short send_cnt=0; uchar send_block[50]; int i; ushort lastcrc16; if(!resume) { // access the device OWASSERT( SelectSHA(portnum), OWERROR_ACCESS_FAILED, FALSE ); } else { // transmit RESUME command send_block[send_cnt++] = ROM_CMD_RESUME; } setcrc16(portnum,0); // match scratchpad command send_block[send_cnt] = CMD_MATCH_SCRATCHPAD; lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // send 20 data bytes for (i = 0; i < 20; i++) { send_block[send_cnt] = data[i]; lastcrc16 = docrc16(portnum,send_block[send_cnt++]); } // send two crc bytes and verification byte //for (i = 0; i < 3; i++) // send_block[send_cnt++] = 0xFF; memset(&send_block[send_cnt], 0x0FF, 3); send_cnt += 3; // now send the block OWASSERT( owBlock(portnum,resume,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // check the CRC for (i = (send_cnt - 3); i < (send_cnt - 1); i++) lastcrc16 = docrc16(portnum,send_block[i]); // verify CRC16 is correct OWASSERT( lastcrc16==0xB001, OWERROR_CRC_FAILED, FALSE ); // check verification if(send_block[send_cnt - 1] != (uchar)0xFF) return TRUE; else return FALSE; }
//---------------------------------------------------------------------- // Read the counter on a specified page of a DS2423. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'SerialNum' - Serial Number of DS2423 that contains the counter // to be read // 'CounterPage' - page number that the counter is associated with // 'Count' - pointer to variable where that count will be returned // // Returns: TRUE(1) counter has been read and verified // FALSE(0) could not read the counter, perhaps device is not // in contact // SMALLINT ReadCounter(int portnum, int CounterPage, unsigned long *Count) { uchar rt=FALSE; uchar send_block[30]; uchar send_cnt=0, i; int address; ushort lastcrc16; setcrc16(portnum,0); // set the device serial number to the counter device /* 2/12/2003 [bcl] DigiTemp does this before calling the routine */ /* owSerialNum(portnum,SerialNum,FALSE); */ // access the device if (owAccess(portnum)) { // create a block to send that reads the counter // read memory and counter command send_block[send_cnt++] = 0xA5; docrc16(portnum,0xA5); // address of last data byte before counter address = (CounterPage << 5) + 31; // (1.02) send_block[send_cnt++] = (uchar)(address & 0xFF); docrc16(portnum,(ushort)(address & 0xFF)); send_block[send_cnt++] = (uchar)(address >> 8); docrc16(portnum,(ushort)(address >> 8)); // now add the read bytes for data byte,counter,zero bits, crc16 for (i = 0; i < 11; i++) send_block[send_cnt++] = 0xFF; // now send the block if (owBlock(portnum,FALSE,send_block,send_cnt)) { // perform the CRC16 on the last 11 bytes of packet for (i = send_cnt - 11; i < send_cnt; i++) lastcrc16 = docrc16(portnum,send_block[i]); // verify CRC16 is correct if (lastcrc16 == 0xB001) { // success rt = TRUE; // extract the counter value *Count = 0; for (i = send_cnt - 7; i >= send_cnt - 10; i--) { *Count <<= 8; *Count |= send_block[i]; } } } } // return the result flag rt return rt; }
/* ds2338mem_rd Reading DS2438 memory returns one page of memory input parameters 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. pageno the page number of memory to be read */ int ds2438mem_rd(int portnum, uchar *SNum, uchar *pagemem, uchar pageno, char *device) { int block_cnt; int i; ushort lastcrc8; owSerialNum(portnum,SNum,FALSE); block_cnt = 0; // Recall the Status/Configuration page // Recall command pagemem[block_cnt++] = 0xB8; // Page to Recall pagemem[block_cnt++] = pageno; owAccess(portnum); owBlock(portnum,FALSE,pagemem,block_cnt); syslog(LOG_DEBUG, "ds2438mem_rd: recall memory (B8h %xh): %s\n", pageno, ppagemem(pagemem)); block_cnt = 0; // Read the Status/Configuration byte // Read scratchpad command pagemem[block_cnt++] = 0xBE; // Page for the Status/Configuration byte pagemem[block_cnt++] = pageno; for(i=0;i<9;i++) pagemem[block_cnt++] = 0xFF; owAccess(portnum); owBlock(portnum,FALSE,pagemem,block_cnt); syslog(LOG_DEBUG,"ds2438mem_rd: read scratchpad (BEh %xh): %s \n", pageno, ppagemem( pagemem)); setcrc8(portnum,0); for(i=2;i<block_cnt;i++) { lastcrc8 = docrc8(portnum,pagemem[i]); } if(lastcrc8 != 0x00) { syslog(LOG_ALERT, "ds2438mem_rd: CRC error "); bitprint( lastcrc8, "lastcrc8"); return 1; } return 0; }
int Temp_DoRead(int iSensor) { uchar send_block[30], lastcrc8; int send_cnt, tsht = 0, i, loop = 0; // LED_Set(6); if(iSensor >= NumDevices) return 0; // LED_Set(7); owSerialNum(PORTNUM, TempSensorSN[iSensor], FALSE); for (loop = 0; loop < 2; loop++) { // access the device if (owAccess(PORTNUM)) { // send the convert command and if nesessary start power delivery if (!owWriteByte(PORTNUM, 0x44)) return 0; // access the device if (owAccess(PORTNUM)) { // create a block to send that reads the temperature // read scratchpad command send_cnt = 0; send_block[send_cnt++] = 0xBE; // now add the read bytes for data bytes and crc8 for (i = 0; i < 9; i++) send_block[send_cnt++] = 0xFF; // now send the block if (owBlock(PORTNUM, FALSE, send_block, send_cnt)) { // initialize the CRC8 setcrc8(PORTNUM, 0); // perform the CRC8 on the last 8 bytes of packet for (i = send_cnt - 9; i < send_cnt; i++) lastcrc8 = docrc8(PORTNUM, send_block[i]); // verify CRC8 is correct if (lastcrc8 == 0x00) { // calculate the high-res temperature tsht = send_block[2] << 8; tsht = tsht | send_block[1]; if (tsht & 0x00001000) tsht = tsht | 0xffff0000; if(!(tsht == 1360 && LastTemperature[iSensor] == 0)){ LastTemperature[iSensor] = tsht; }else{ tsht = 0; } // success break; } } } } } return tsht; }
//---------------------------------------------------------------------- // Perform a overdrive MATCH command to select the 1-Wire device with // the address in the ID data register. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // // Returns: TRUE: If the device is present on the 1-Wire Net and // can do overdrive then the device is selected. // FALSE: Device is not present or not capable of overdrive. // // *Note: This function could be converted to send DS2480 // commands in one packet. // BYTE owOverdriveAccess(BYTE portnum) { BYTE sendpacket[8]; BYTE i, bad_echo = FALSE; owSetCurrentPort(portnum); // make sure normal level owLevel(owCurrentPortnum, MODE_NORMAL); // force to normal communication speed owSpeed(owCurrentPortnum, MODE_NORMAL); // call the 1-Wire Net reset function if(owTouchReset(owCurrentPortnum)) { // send the match command 0x69 if(owWriteByte(owCurrentPortnum, 0x69)) { // switch to overdrive communication speed owSpeed(owCurrentPortnum, MODE_OVERDRIVE); // create a buffer to use with block function // Serial Number for(i = 0; i < 8; i++) { sendpacket[i] = owNetCurrent.SerialNum[i]; } // send/recieve the transfer buffer if(owBlock(owCurrentPortnum, FALSE, sendpacket,8)) { // verify that the echo of the writes was correct for(i = 0; i < 8; i++) { if(sendpacket[i] != owNetCurrent.SerialNum[i]) { bad_echo = TRUE; } } // if echo ok then success if(!bad_echo) { return TRUE; } else { OWERROR(OWERROR_WRITE_VERIFY_FAILED); } } else { OWERROR(OWERROR_BLOCK_FAILED); } } else { OWERROR(OWERROR_WRITE_BYTE_FAILED); } } else { OWERROR(OWERROR_NO_DEVICES_ON_NET); } // failure, force back to normal communication speed owSpeed(owCurrentPortnum, MODE_NORMAL); return FALSE; }
//---------------------------------------------------------------------- // The function 'owVerify' verifies that the current device // is in contact with the 1-Wire Net. // Using the find alarm command 0xEC will verify that the device // is in contact with the 1-Wire Net and is in an 'alarm' state. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'alarm_only' - TRUE (1) the find alarm command 0xEC // is sent instead of the normal search // command 0xF0. // // Returns: TRUE (1) : when the 1-Wire device was verified // to be on the 1-Wire Net // with alarm_only == FALSE // or verified to be on the 1-Wire Net // AND in an alarm state when // alarm_only == TRUE. // FALSE (0): the 1-Wire device was not on the // 1-Wire Net or if alarm_only // == TRUE, the device may be on the // 1-Wire Net but in a non-alarm state. // BYTE owVerify(BYTE portnum, BYTE alarm_only) { BYTE i, sendlen = 0, goodbits = 0, cnt = 0, s, tst; BYTE sendpacket[50]; owSetCurrentPort(portnum); // construct the search if(alarm_only) { sendpacket[sendlen++] = 0xEC; // issue the alarming search command } else { sendpacket[sendlen++] = 0xF0; // issue the search command } // set all bits at first for(i = 1; i <= 24; i++) { sendpacket[sendlen++] = 0xFF; } // now set or clear apropriate bits for search for(i = 0; i < 64; i++) { bitacc(WRITE_FUNCTION, bitacc(READ_FUNCTION, 0, i, &owNetCurrent.SerialNum[0]),(int)((i+1)*3-1),&sendpacket[1]); } // send/recieve the transfer buffer if(owBlock(owCurrentPortnum, TRUE, sendpacket, sendlen)) { // check results to see if it was a success for(i = 0; i < 192; i += 3) { tst = (bitacc(READ_FUNCTION, 0, i, &sendpacket[1]) << 1) | bitacc(READ_FUNCTION, 0, (int)(i+1), &sendpacket[1]); s = bitacc(READ_FUNCTION, 0, cnt++, &owNetCurrent.SerialNum[0]); if(tst == 0x03) { // no device on line goodbits = 0; // number of good bits set to zero break; // quit } if(((s == 0x01) && (tst == 0x02)) || ((s == 0x00) && (tst == 0x01))) { // correct bit goodbits++; // count as a good bit } } // check too see if there were enough good bits to be successful if(goodbits >= 8) { return TRUE; } } else { OWERROR(OWERROR_BLOCK_FAILED); } // block fail or device not present return FALSE; }
//---------------------------------------------------------------------- // Copy the scratchpad with verification for DS1963S. Assume that the // data was padded to get the CRC16 verification on write scratchpad. // This will result in the 'es' byte to be 0x1F. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'address' - address of destination // 'len' - length of data // 'resume' - if true, device access is resumed using the RESUME // ROM command (0xA5). Otherwise, a a MATCH ROM is // used along with the device's entire address number. // // Return: TRUE - copy scratch verified // FALSE - error during copy scratch, device not present, or HIDE // flag is in incorrect state for address being written. // SMALLINT CopyScratchpadSHA18(int portnum, int address, SMALLINT len, SMALLINT resume) { short send_cnt=0; uchar send_block[10]; int num_verf; uchar es = (address + len - 1) & 0x1F; if(!resume) { // access the device OWASSERT( SelectSHA(portnum), OWERROR_ACCESS_FAILED, FALSE ); } else { // transmit RESUME command send_block[send_cnt++] = ROM_CMD_RESUME; } // change number of verification bytes if in overdrive num_verf = (in_overdrive[portnum&0x0FF]) ? 4 : 2; // copy scratchpad command send_block[send_cnt++] = CMD_COPY_SCRATCHPAD; // address 1 send_block[send_cnt++] = (uchar)(address & 0xFF); // address 2 send_block[send_cnt++] = (uchar)((address >> 8) & 0xFF); // es send_block[send_cnt++] = es; // verification bytes //for (i = 0; i < num_verf; i++) // send_block[send_cnt++] = 0xFF; memset(&send_block[send_cnt], 0x0FF, num_verf); send_cnt += (short)num_verf; // now send the block OWASSERT( owBlock(portnum,resume,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // check verification OWASSERT( ((send_block[send_cnt-1] & 0xF0) == 0x50) || ((send_block[send_cnt-1] & 0xF0) == 0xA0), OWERROR_NO_COMPLETION_BYTE, FALSE ); return TRUE; }
/** * Reads the entire scratchpad. * * portnum the port number of the port being used for the * 1-Wire Network * data the data that was read from the scratchpad. * * return TRUE if the data was read without an error * */ SMALLINT readScratchpad(int portnum, uchar *data) { uchar buffer[96]; int i; if(owAccess(portnum)) { buffer[0] = READ_SCRATCHPAD_COMMAND; buffer[1] = 0xC0; //Starting address of scratchpad buffer[2] = 0x3F; for(i = 3; i < 67; i++) buffer[i] = 0xFF; //send command block if(!owBlock(portnum,FALSE,buffer,64)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } else if(!owBlock(portnum,FALSE,&buffer[64],3)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } for(i=0;i<64;i++) data[i] = buffer[i+3]; } else { OWERROR(OWERROR_DEVICE_SELECT_FAIL); return FALSE; } return TRUE; }
/** * Writes the data from the scratchpad to the specified block or * blocks. Note that the write will erase the data from the * scratchpad. * * portnum the port number of the port being used for the * 1-Wire Network. * key subkey being written * passwd password for the subkey being written * blockNum number of the block to be copied (see page 7 of the * DS1991 data sheet) block 0-7, or 8 to copy all 64 bytes. * * return TRUE if the copy scratchpad was successful. */ SMALLINT copyScratchpad(int portnum, int key, uchar *passwd, int blockNum) { uchar buffer[96]; int i; if(owAccess(portnum)) { //confirm that input is OK if ((key < 0) || (key > 2)) { OWERROR(OWERROR_KEY_OUT_OF_RANGE); return FALSE; } if ((blockNum < 0) || (blockNum > 8)) { OWERROR(OWERROR_BLOCK_ID_OUT_OF_RANGE); return FALSE; } buffer[0] = COPY_SCRATCHPAD_COMMAND; buffer[1] = (uchar) (key << 6); buffer[2] = (uchar) (~buffer [1]); //set up block selector code for(i=0;i<8;i++) buffer[i+3] = pscodes[blockNum][i]; //set up password for(i=0;i<8;i++) buffer[i+11] = passwd[i]; //send command block if(!owBlock(portnum,FALSE,buffer,19)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } } else { OWERROR(OWERROR_DEVICE_SELECT_FAIL); return FALSE; } return TRUE; }
//-------------------------------------------------------------------------- // The 'owAccess' function resets the 1-Wire and sends a MATCH Serial // Number command followed by the current SerialNum code. After this // function is complete the 1-Wire device is ready to accept device-specific // commands. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // // Returns: TRUE (1) : reset indicates present and device is ready // for commands. // FALSE (0): reset does not indicate presence or echos 'writes' // are not correct. // BYTE owAccess(BYTE portnum) { BYTE sendpacket[9]; BYTE i; owSetCurrentPort(portnum); // reset the 1-wire if(owTouchReset(owCurrentPortnum)) { // create a buffer to use with block function // match Serial Number command 0x55 sendpacket[0] = 0x55; // Serial Number for(i = 1; i < 9; i++) { sendpacket[i] = owNetCurrent.SerialNum[i-1]; } // send/recieve the transfer buffer if(owBlock(owCurrentPortnum, FALSE, sendpacket, 9)) { // verify that the echo of the writes was correct for(i = 1; i < 9; i++) { if(sendpacket[i] != owNetCurrent.SerialNum[i-1]) { return FALSE; } if(sendpacket[0] != 0x55) { OWERROR(OWERROR_WRITE_VERIFY_FAILED); return FALSE; } else { return TRUE; } } } else { OWERROR(OWERROR_BLOCK_FAILED); } } else { OWERROR(OWERROR_NO_DEVICES_ON_NET); } // reset or match echo failed return FALSE; }
//-------------------------------------------------------------------------- // The 'owAccess' function resets the 1-Wire and sends a MATCH Serial // Number command followed by the current SerialNum code. After this // function is complete the 1-Wire device is ready to accept device-specific // commands. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // // Returns: TRUE (1) : reset indicates present and device is ready // for commands. // FALSE (0): reset does not indicate presence or echos 'writes' // are not correct. // SMALLINT owAccess(int portnum) { uchar sendpacket[9]; uchar i; // reset the 1-wire if (owTouchReset(portnum)) { // create a buffer to use with block function // match Serial Number command 0x55 sendpacket[0] = 0x55; // Serial Number for (i = 1; i < 9; i++) sendpacket[i] = SerialNum[portnum][i-1]; // send/recieve the transfer buffer if (owBlock(portnum,FALSE,sendpacket,9)) { // verify that the echo of the writes was correct for (i = 1; i < 9; i++) if (sendpacket[i] != SerialNum[portnum][i-1]) return FALSE; if (sendpacket[0] != 0x55) { OWERROR(OWERROR_WRITE_VERIFY_FAILED); return FALSE; } else return TRUE; } else OWERROR(OWERROR_BLOCK_FAILED); } else OWERROR(OWERROR_NO_DEVICES_ON_NET); // reset or match echo failed return FALSE; }
//---------------------------------------------------------------------- // Read Memory Page for DS1963S. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'pagenum' - page number to do a read authenticate // 'data' - buffer to read into from page // 'resume' - if true, device access is resumed using the RESUME // ROM command (0xA5). Otherwise, a a MATCH ROM is // used along with the device's entire address number. // // Return: TRUE - Read successfull // FALSE - error occurred during read. // SMALLINT ReadMemoryPageSHA18(int portnum, SMALLINT pagenum, uchar* data, SMALLINT resume) { short send_cnt=0; uchar send_block[36]; int address = pagenum << 5; if(!resume) { // access the device OWASSERT( SelectSHA(portnum), OWERROR_ACCESS_FAILED, -1 ); } else { // transmit RESUME command send_block[send_cnt++] = ROM_CMD_RESUME; } // create the send block // Read Memory command send_block[send_cnt++] = CMD_READ_MEMORY; // TA1 send_block[send_cnt++] = (uchar)(address & 0xFF); // TA2 send_block[send_cnt++] = (uchar)((address >> 8) & 0xFF); // now add the read bytes for data bytes memset(&send_block[send_cnt], 0x0FF, 32); send_cnt += 32; // now send the block OWASSERT( owBlock(portnum,TRUE,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); // transfer the results memcpy(data, &send_block[send_cnt-32], 32); return TRUE; }
//---------------------------------------------------------------------- // Write the scratchpad with CRC16 verification for DS1963S. The data // is padded until the offset is 0x1F so that the CRC16 is retrieved. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'address' - address to write data to // 'data' - data to write // 'data_len' - number of bytes of data to write // 'resume' - if true, device access is resumed using the RESUME // ROM command (0xA5). Otherwise, a a MATCH ROM is // used along with the device's entire address number. // // Return: TRUE - write to scratch verified // FALSE - error writing scratch, device not present, or HIDE // flag is in incorrect state for address being written. // SMALLINT WriteScratchpadSHA18(int portnum, int address, uchar *data, SMALLINT data_len, SMALLINT resume) { uchar send_block[50]; short send_cnt=0,i; ushort lastcrc16; if(!resume) { // access the device OWASSERT( SelectSHA(portnum), OWERROR_ACCESS_FAILED, FALSE ); } else { // transmit RESUME command send_block[send_cnt++] = ROM_CMD_RESUME; } setcrc16(portnum,0); // write scratchpad command send_block[send_cnt] = CMD_WRITE_SCRATCHPAD; lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // address 1 send_block[send_cnt] = (uchar)(address & 0xFF); lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // address 2 send_block[send_cnt] = (uchar)((address >> 8) & 0xFF); lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // data for (i = 0; i < data_len; i++) { send_block[send_cnt] = data[i]; lastcrc16 = docrc16(portnum,send_block[send_cnt++]); } // pad if needed for (i = 0; i < (0x1F - ((address + data_len - 1) & 0x1F)); i++) { send_block[send_cnt] = 0xFF; lastcrc16 = docrc16(portnum,send_block[send_cnt++]); } // CRC16 send_block[send_cnt++] = 0xFF; send_block[send_cnt++] = 0xFF; // now send the block OWASSERT( owBlock(portnum,resume,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // perform CRC16 of last 2 byte in packet for (i = send_cnt - 2; i < send_cnt; i++) lastcrc16 = docrc16(portnum,send_block[i]); // verify CRC16 is correct OWASSERT( lastcrc16==0xB001, OWERROR_CRC_FAILED, FALSE ); // success return TRUE; }
//---------------------------------------------------------------------- // Read the temperature of a DS18B20 (family code 0x28) // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // 'SerialNum' - Serial Number of DS18B20 to read temperature from // 'Temp ' - pointer to variable where that temperature will be // returned // // Returns: TRUE(1) temperature has been read and verified // FALSE(0) could not read the temperature, perhaps device is not // in contact // int ReadTemperature28(int portnum, uchar *SerialNum, float *Temp) { uchar rt=FALSE; uchar send_block[30],lastcrc8; int send_cnt, tsht, i, loop=0; int power; // set the device serial number to the counter device owSerialNum(portnum,SerialNum,FALSE); for (loop = 0; loop < 2; loop ++) { // check if the chip is connected to VDD if (owAccess(portnum)) { owWriteByte(portnum,0xB4); power = owReadByte(portnum); } // access the device if (owAccess(portnum)) { // send the convert command and if nesessary start power delivery if (power) { if (!owWriteBytePower(portnum,0x44)) return FALSE; } else { if (!owWriteByte(portnum,0x44)) return FALSE; } // sleep for 1 second msDelay(1000); // turn off the 1-Wire Net strong pull-up if (power) { if (owLevel(portnum,MODE_NORMAL) != MODE_NORMAL) return FALSE; } // access the device if (owAccess(portnum)) { // create a block to send that reads the temperature // read scratchpad command send_cnt = 0; send_block[send_cnt++] = 0xBE; // now add the read bytes for data bytes and crc8 for (i = 0; i < 9; i++) send_block[send_cnt++] = 0xFF; // now send the block if (owBlock(portnum,FALSE,send_block,send_cnt)) { // initialize the CRC8 setcrc8(portnum,0); // perform the CRC8 on the last 8 bytes of packet for (i = send_cnt - 9; i < send_cnt; i++) lastcrc8 = docrc8(portnum,send_block[i]); // verify CRC8 is correct if (lastcrc8 == 0x00) { // calculate the high-res temperature tsht = send_block[2] << 8; tsht = tsht | send_block[1]; if (tsht & 0x00001000) tsht = tsht | 0xffff0000; *Temp = ((float) tsht)/16; // success rt = TRUE; break; } } } } } // return the result flag rt return rt; }
//---------------------------------------------------------------------- // Main Test // int main() //short argc, char **argv) { int PortNum=1,rslt,i,j,testcnt=0,length; uchar TempSerialNum[8]; uchar tran_buffer[2000], filename[10]; char return_msg[128]; int portnum=0; // check for required port name if (argc != 2) { printf("1-Wire Net name required on command line!\n" " (example: \"COM1\" (Win32 DS2480),\"/dev/cua0\" " "(Linux DS2480),\"1\" (Win32 TMEX)\n"); exit(1); } // attempt to acquire the 1-Wire Net if (!owAcquire(portnum, argv[1], return_msg)) { printf("%s",return_msg); exit(1); } // success printf("%s",return_msg); //---------------------------------------- // Introduction printf("\n/---------------------------------------------\n"); printf(" The following is a test excersize of the\n" " 1-Wire Net public domain library Version 2.00.\n\n" " This test was run using with 2 DS1920's (DS1820),\n" " 1 DS1971 (DS2430), and 1 DS1996.\n\n"); //---------------------------------------- // First the devices on the 1-Wire Net printf("\n/---------------------------------------------\n"); printf("TEST%d: Searching for devices on 1-Wire Net\n",testcnt++); // find the first device (all devices not just alarming) rslt = owFirst(portnum,TRUE, FALSE); while (rslt) { // print the Serial Number of the device just found PrintSerialNum(portnum); // find the next device rslt = owNext(portnum,TRUE, FALSE); } //---------------------------------------- // now search for the part with a 0x0C family code (DS1996) printf("\n/---------------------------------------------\n"); printf("TEST%d: Set to find first device with 0x0C family code\n",testcnt++); owFamilySearchSetup(portnum,0x0C); // find the first 0x0c device TempSerialNum[0]=0; while (TempSerialNum[0]!=0x0c && owNext(portnum,TRUE,FALSE)) { owSerialNum(portnum,TempSerialNum,TRUE); } printf("search result %d\n",TempSerialNum[0]==0x0c); // print the Serial Number of the device just found PrintSerialNum(portnum); //---------------------------------------- // Access a device and read ram printf("\n/---------------------------------------------\n"); printf("TEST%d: Access the current device and read ram\n",testcnt++); printf("owAccess %d\n",owAccess(portnum)); printf("Read Ram 0xF0: %02X\n",owTouchByte(portnum,0xF0)); printf("Address0 0x00: %02X\n",owTouchByte(portnum,0x00)); printf("Address1 0x00: %02X\n",owTouchByte(portnum,0x00)); printf("Page 0: "); for (i = 0; i < 32; i++) printf("%02X ",owTouchByte(portnum,0xFF)); printf("\n"); //---------------------------------------- // Read ram with owBlock printf("\n/---------------------------------------------\n"); printf("TEST%d: Read ram with owBlock\n",testcnt++); for (i = 0; i < 32; i++) tran_buffer[i] = 0xFF; printf("owBlock %d\n",owBlock(portnum,FALSE,tran_buffer,32)); printf("Page 1: "); for (i = 0; i < 32; i++) printf("%02X ",tran_buffer[i]); printf("\n"); //---------------------------------------- // Write a packet in each page of DS1996 printf("\n/---------------------------------------------\n"); printf("TEST%d: Place the DS1996 into overdrive\n",testcnt++); printf("owOverdriveAccess %d\n",owOverdriveAccess(portnum)); //---------------------------------------- // Write 4 packets with owWritePacketStd printf("\n/---------------------------------------------\n"); printf("TEST%d: Write 4 packets with owWritePacketStd\n",testcnt++); for (j = 0; j < 4; j++) { for (i = 0; i < 29; i++) tran_buffer[i] = (uchar)i + j; printf("Write page %d: %d\n",j,owWritePacketStd(portnum,j,tran_buffer,29,FALSE,FALSE)); for (i = 0; i < 29; i++) tran_buffer[i] = 0; length = owReadPacketStd(portnum,TRUE,j,tran_buffer); printf("Read page %d: %d\n",j,length); for (i = 0; i < length; i++) printf("%02X",tran_buffer[i]); printf("\n"); } //---------------------------------------- // Write a file to DS1996 printf("\n/---------------------------------------------\n"); printf("TEST%d: Format and write a file (in overdrive)\n",testcnt++); sprintf(filename,"DEMO"); // set the data to write for (i = 0; i < 2000; i++) tran_buffer[i] = i % 255; printf("Format and write file DEMO.000 %d\n", owFormatWriteFile(portnum,filename,2000,tran_buffer)); // clear the buffer for (i = 0; i < 2000; i++) tran_buffer[i] = 0x55; printf("Read file DEMO.000 %d\n",owReadFile(portnum,filename,tran_buffer)); // print the data result for (i = 0; i < 2000; i++) { if ((i % 0x20) == 0) printf("\n%03X ",i); printf("%02X",tran_buffer[i]); } printf("\n"); //---------------------------------------- // Turn off overdrive printf("\n/---------------------------------------------\n"); printf("TEST%d: Turn off overdrive\n",testcnt++); printf("Set 1-Wire Net speed to normal %d\n",owSpeed(portnum,MODE_NORMAL)); //---------------------------------------- // Verify a device printf("\n/---------------------------------------------\n"); printf("TEST%d: Verify the current device\n",testcnt++); printf("owVerify (normal) %d\n",owVerify(portnum,FALSE)); printf("owVerify (alarm) %d\n",owVerify(portnum,TRUE)); //---------------------------------------- // Skip the first family code found printf("\n/---------------------------------------------\n"); printf("TEST%d: Skip the first family code found\n",testcnt++); // find the next device printf("search result of owFirst %d\n",owFirst(portnum,TRUE, FALSE)); // print the Serial Number of the device just found PrintSerialNum(portnum); // skip the first family type found owSkipFamily(portnum); printf("owSkipFamily called\n"); // find the next device printf("search result of owNext %d\n",owNext(portnum,TRUE, FALSE)); // print the Serial Number of the device just found PrintSerialNum(portnum); //---------------------------------------- // Find first family code (DS1920) and read temperature printf("\n/---------------------------------------------\n"); printf("TEST%d: Find first family code (DS1920) and read temperature\n",testcnt++); // find the next device printf("search result of owFirst %d\n",owFirst(portnum,TRUE, FALSE)); // print the Serial Number of the device just found PrintSerialNum(portnum); // send the convert temperature command printf("Convert temperature command %02X\n",owTouchByte(portnum,0x44)); // set the 1-Wire Net to strong pull-up printf("Set power delivery %d\n",owLevel(portnum,MODE_STRONG5)); // sleep for 1 second msDelay(1000); // turn off the 1-Wire Net strong pull-up printf("Disable power delivery %d\n",owLevel(portnum,MODE_NORMAL)); // read the DS1920 temperature value printf("Access the DS1920 %d\n",owAccess(portnum)); tran_buffer[0] = 0xBE; tran_buffer[1] = 0xFF; tran_buffer[2] = 0xFF; printf("Block to read temperature %d\n",owBlock(portnum,FALSE,tran_buffer,3)); // interpret the result printf("result: DS1920 temperature read: %d C\n", (tran_buffer[1] | ((int)tran_buffer[2] << 8)) / 2); //---------------------------------------- // Verify the current device, could also be alarming printf("\n/---------------------------------------------\n"); printf("TEST%d: Verify the current device, could also be alarming\n",testcnt++); printf("owVerify (normal) %d\n",owVerify(portnum,FALSE)); printf("owVerify (alarm) %d\n",owVerify(portnum,TRUE)); //---------------------------------------- // Test setting the Serial Number with owSerialNum printf("\n/---------------------------------------------\n"); printf("TEST%d: Test setting the Serial Number with owSerialNum\n",testcnt++); // set the Serial Num to 0 to 7 for (i = 0; i < 8; i++) TempSerialNum[i] = (uchar)i; owSerialNum(portnum,TempSerialNum,FALSE); // read back the Serial Number PrintSerialNum(portnum); //---------------------------------------- // Verify the current device (should fail, no such device) printf("\n/---------------------------------------------\n"); printf("TEST%d: Verify the current device (should fail, no such device)\n",testcnt++); printf("owVerify (normal) %d\n",owVerify(portnum,FALSE)); printf("owVerify (alarm) %d\n",owVerify(portnum,TRUE)); // release the 1-Wire Net owRelease(portnum,return_msg); printf("%s",return_msg); exit(0); return 0; }
/* SetupVsens setup DS2438 to read Vsens voltage difference enable IAD, CA and EE of status configuration register ( page <0h> byte <0h>) Vsens A/D conversion occurs with a frequency of 36.41 measurements/sec once IAD is enabled ( set to '1'). No special command necessary. input parameters portnum port number SNum serial number of DS2438 device device (USB DS2490 or serial DS9097U) */ int SetupVsens(int portnum, uchar *SNum, char *device) { uchar datablock[50]; uchar conf_reg = 0x00; int send_cnt = 0; int i; ushort lastcrc8; int busybyte; double ti, tf; struct timezone tz; struct timeval tv; gettimeofday( &tv, &tz); ti = tv.tv_sec+1.0e-6*tv.tv_usec; /* enable IAD, CA and EE of configuration byte */ conf_reg |= IAD | CA | EE; owSerialNum(portnum,SNum,FALSE); // Recall the Status/Configuration page // Recall command datablock[send_cnt++] = 0xB8; // Page to Recall datablock[send_cnt++] = 0x00; if(!owBlock(portnum,FALSE,datablock,send_cnt)) return FALSE; send_cnt = 0; if(owAccess(portnum)) { // Read the Status/Configuration byte // Read scratchpad command datablock[send_cnt++] = 0xBE; // Page for the Status/Configuration byte datablock[send_cnt++] = 0x00; for(i=0;i<9;i++) datablock[send_cnt++] = 0xFF; if(owBlock(portnum,FALSE,datablock,send_cnt)) { setcrc8(portnum,0); for(i=2;i<send_cnt;i++) lastcrc8 = docrc8(portnum,datablock[i]); if(lastcrc8 != 0x00) return FALSE; }//Block else return FALSE; if ( datablock[2] & conf_reg ) { syslog(LOG_DEBUG, "SetupVsens: IAD, CA and EE are set: return!\n"); gettimeofday( &tv, &tz); tf = tv.tv_sec+1.0e-6*tv.tv_usec; syslog(LOG_DEBUG, "SetupVsens: elapsed time: %f\n", tf -ti); return TRUE; } else { syslog(LOG_DEBUG, "SetupVsens: IAD, CA and EE are not set. Continue to setup\n"); } }//Access if(owAccess(portnum)) { send_cnt = 0; // Write the Status/Configuration byte // Write scratchpad command datablock[send_cnt++] = 0x4E; // Write page datablock[send_cnt++] = 0x00; // IAD, CA and EE set to "1" datablock[send_cnt++] |= conf_reg; // do not change the rest for(i=0;i<7;i++) datablock[send_cnt++] = datablock[i+3]; if(owBlock(portnum,FALSE,datablock,send_cnt)) { send_cnt = 0; if(owAccess(portnum)) { // Copy the Status/Configuration byte // Copy scratchpad command datablock[send_cnt++] = 0x48; // Copy page datablock[send_cnt++] = 0x00; if(owBlock(portnum,FALSE,datablock,send_cnt)) { busybyte = owReadByte(portnum); while(busybyte == 0) busybyte = owReadByte(portnum); gettimeofday( &tv, &tz); tf = tv.tv_sec+1.0e-6*tv.tv_usec; syslog(LOG_DEBUG, "SetupVsens: elapsed time: %f\n", tf -ti); return TRUE; }//Block }//Access }//Block }//Access return FALSE; }
//---------------------------------------------------------------------- // Read the temperature of a DS1920/DS1820 // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // 'SerialNum' - Serial Number of DS1920/DS1820 to read temperature from // 'Temp ' - pointer to variable where that temperature will be // returned // // Returns: TRUE(1) temperature has been read and verified // FALSE(0) could not read the temperature, perhaps device is not // in contact // int ReadTemperature(int portnum, uchar *SerialNum, float *Temp) { int rt=FALSE; uchar send_block[30],lastcrc8; int send_cnt=0, tsht, i, loop=0; float tmp,cr,cpc; setcrc8(portnum,0); // set the device serial number to the counter device owSerialNum(portnum,SerialNum,FALSE); for (loop = 0; rt==FALSE && loop < 2; loop ++) { // access the device if (owAccess(portnum)) { // send the convert temperature command owTouchByte(portnum,0x44); // set the 1-Wire Net to strong pull-up if (owLevel(portnum,MODE_STRONG5) != MODE_STRONG5) return FALSE; // sleep for 1 second msDelay(1000); // turn off the 1-Wire Net strong pull-up if (owLevel(portnum,MODE_NORMAL) != MODE_NORMAL) return FALSE; // access the device if (owAccess(portnum)) { // create a block to send that reads the temperature // read scratchpad command send_block[send_cnt++] = 0xBE; // now add the read bytes for data bytes and crc8 for (i = 0; i < 9; i++) send_block[send_cnt++] = 0xFF; // now send the block if (owBlock(portnum,FALSE,send_block,send_cnt)) { // perform the CRC8 on the last 8 bytes of packet for (i = send_cnt - 9; i < send_cnt; i++) lastcrc8 = docrc8(portnum,send_block[i]); // verify CRC8 is correct if (lastcrc8 == 0x00) { // calculate the high-res temperature tsht = send_block[1]/2; if (send_block[2] & 0x01) tsht |= -128; tmp = (float)(tsht); cr = send_block[7]; cpc = send_block[8]; if (((cpc - cr) == 1) && (loop == 0)) continue; if (cpc == 0) return FALSE; else tmp = tmp - (float)0.25 + (cpc - cr)/cpc; *Temp = tmp; // success rt = TRUE; } } } } } // return the result flag rt return rt; }
//---------------------------------------------------------------------- // This is the Main routine for swtmain1c // int main(short argc, char **argv) { char msg[200]; uchar data[256]; int portnum = 0; int n=0; int addr = 0; int len; uchar es = 0x00; uchar address[2]; ushort i; uchar sn[8],state[3], reg[3], send_block[37]; uchar family[2][8]; int done=FALSE; int channel=0,send_cnt=0; SMALLINT alternate=TRUE, alt=FALSE; ushort lastcrc16; uchar latch, set; uchar check; // check for required port name if (argc != 2) { sprintf(msg,"1-Wire Net name required on command line!\n" " (example: \"COM1\" (Win32 DS2480),\"/dev/cua0\" " "(Linux DS2480),\"1\" (Win32 TMEX)\n"); printf("%s",msg); return 0; } if((portnum = owAcquireEx(argv[1])) < 0) { printf("Did not Acquire port.\n",1); exit(1); } else { if(FindDevices(portnum,&family[0],0x1C,1)) { for(i=0;i<8;i++) sn[i] = family[0][i]; printf("device found: "); for(i=0;i<8;i++) printf("%02X ",sn[i]); printf("\n"); do { printf("PICK AN OPERATION:\n\n"); printf("(1) Read Channel state\n"); // Gives channel information printf("(2) Set Channel On/Off\n"); // Sets channel printf("(3) Read Channel Mask\n"); // Read Selection Mask printf("(4) Set Channel mask\n"); // Sets channel mask printf("(5) Read Channel Polarity\n"); // Read Polarity Selection printf("(6) Set Channel polarity\n"); // sets channel polarity printf("(7) Read Control/Status Register\n"); // Read Control/Status Reg printf("(8) Set Reset Mode On/Off\n"); // Set Reset Mode printf("(9) Clear Power on Reset\n"); // Clear Power on reset printf("(10) Get VCC state\n"); // Get VCC state printf("(11) Set OR conditional search\n"); // or condition search printf("(12) Set AND conditional search\n"); // and condition search printf("(13) Write Scratchpad\n"); // write scratchpad command printf("(14) Read Scratchpad\n"); // read scratchpad command printf("(15) Copy Scratchpad\n"); // copy scratchpad command printf("(16) Read Memory\n"); // read memory printf("(17) PIO access read with CRC confirmation\n"); // access read printf("(18) LED test\n"); // LED test printf("(19) QUIT\n"); scanf("%d",&n); if(n == 19) { n = 0; //used to finish off the loop done = TRUE; break; } switch(n) { case 1: // Channel Info printf("\nEnter the channel\n"); scanf("%d",&channel); if(readSwitch1C(portnum,&sn[0],&state[0])) { printf("The channel is "); if(getLatchState1C(channel,&state[0])) printf("on.\n"); else printf("off\n"); printf("The Level is "); if(getLevel1C(channel,&state[0])) printf("high.\n"); else printf("low.\n"); if(getSensedActivity1C(channel,&state[0])) printf("Activity was detected on the channel.\n\n"); else printf("No activity was detected on the channel.\n\n"); } else OWERROR_DUMP(stdout); break; case 2: // Sets channel printf("\nEnter the channel\n"); scanf("%d",&channel); printf("Turn channel off enter 0, on 1.\n"); scanf("%d",&set); if(setLatchState1C(portnum,&sn[0],channel,set)) { printf("Latch was set "); if(set) printf("on.\n"); else printf("off.\n"); } else OWERROR_DUMP(stdout); break; case 3: // Read Selection Mask printf("\nEnter the channel\n"); scanf("%d",&channel); if(readRegister1C(portnum,&sn[0],®[0])) { printf("register is %02X %02X %02X\n",reg[0],reg[1],reg[2]); printf("The Selection Mask for channel %d is ",channel); latch = (uchar) (0x01 << channel); if((reg[0] & latch) == latch) printf("set.\n\n"); else printf("not set.\n\n"); } else OWERROR_DUMP(stdout); break; case 4: // Sets channel mask printf("\nEnter the channel\n"); scanf("%d",&channel); printf("Turn channel mask off enter 0, on 1.\n"); scanf("%d",&set); if(setChannelMask1C(portnum,&sn[0],channel,set)) { printf("The mask for channel %d was set ",channel); if(set) printf("on.\n\n"); else printf("off.\n\n"); } else OWERROR_DUMP(stdout); break; case 5: // Read Polarity Selection printf("\nEnter the channel\n"); scanf("%d",&channel); printf("The Polarity for channel %d is ",channel); if(getChannelPolarity1C(portnum,&sn[0],channel)) printf("set.\n\n"); else printf("not set.\n\n"); break; case 6: // sets channel polarity printf("\nEnter the channel\n"); scanf("%d",&channel); printf("Turn channel polarity off enter 0, on 1.\n"); scanf("%d",&set); if(setChannelPolarity1C(portnum,&sn[0],channel,set)) { printf("The polarity for channel %d was set ",channel); if(set) printf("on.\n\n"); else printf("off.\n\n"); } else OWERROR_DUMP(stdout); break; case 7: // Read Control/Status Reg if(readRegister1C(portnum,&sn[0],®[0])) printf("The Constrol/Status register is as following in hex %02X\n\n", reg[2]); else OWERROR_DUMP(stdout); break; case 8: // Set Reset Mode printf("Turn reset mode off enter 0, on 1.\n"); scanf("%d",&set); if(setResetMode1C(portnum,&sn[0],set)) { printf("Reset Mode was turned "); if(set) printf("on.\n\n"); else printf("off.\n\n"); } else OWERROR_DUMP(stdout); break; case 9: // Clear Power on reset if(clearPowerOnReset1C(portnum,&sn[0])) printf("Power on reset was cleared.\n\n"); else OWERROR_DUMP(stdout); break; case 10: // Get VCC state if(readRegister1C(portnum,&sn[0],®[0])) { printf("VCC state register is %02X\n",reg[2]); if(getVCC1C(®[0])) printf("VCC is powered.\n\n"); else printf("VCC is grounded.\n\n"); } else OWERROR_DUMP(stdout); break; case 11: // or condition search if(orConditionalSearch1C(portnum,&sn[0])) printf("OR condition search was set.\n\n"); else OWERROR_DUMP(stdout); break; case 12: // and condition search if(andConditionalSearch1C(portnum,&sn[0])) printf("AND condition search was set.\n\n"); else OWERROR_DUMP(stdout); break; case 13: // write scratchpad printf("Enter the address to start writing: "); addr = getNumber(0, 550); if(menuSelect(&sn[0]) == MODE_TEXT) len = getData(data,MAX_LEN,MODE_TEXT); else len = getData(data,MAX_LEN,MODE_HEX); if(!writeScratch1C(portnum,&sn[0],addr,len,&data[0])) OWERROR_DUMP(stdout); break; case 14: // read scratchpad if(!readScratch1C(portnum,&sn[0],&len,&es,&address[0],&data[0])) { printf("error\n"); OWERROR_DUMP(stdout); } else { printf("Address bytes: %02X %02X\n",address[0],address[1]); printf("ES byte: %02X\n",es); printf("Length: %d\n",len); printf("Scratchpad data: "); for(i=0;i<len;i++) printf("%02X ",data[i]); printf("\n"); } break; case 15: // copy scratchpad if(!copyScratch1C(portnum,&sn[0])) { OWERROR_DUMP(stdout); } else { printf("Copy Scratchpad Complete.\n"); } break; case 16: // read memory printf("Enter the address to start reading: "); addr = getNumber(0, 550); printf("Enter the length you want to read: "); len = getNumber(0,256); if(!read1C(portnum,&sn[0],addr,len,&data[0])) { OWERROR_DUMP(stdout); } else { for(i=0;i<len;i++) printf("%02X ",data[i]); printf("\n"); } break; case 17: // and condition search if (!owTouchReset(portnum)) OWERROR_DUMP(stdout); if(!owWriteByte(portnum,0xCC)) printf("skip rom error.\n"); owWriteByte(portnum,0xF5); for(i=0;i<34;i++) send_block[send_cnt++] = 0xFF; if(!owBlock(portnum,FALSE,&send_block[0],send_cnt)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } setcrc16(portnum,0); lastcrc16 = docrc16(portnum,0xF5); for(i=0;i<34;i++) lastcrc16 = docrc16(portnum,send_block[i]); if(lastcrc16 != 0xB001) printf("CRC didn't match.\n"); printf("read data: "); for(i=0;i<34;i++) printf("%02X ",send_block[i]); printf("\n"); send_cnt = 0; for(i=0;i<34;i++) send_block[send_cnt++] = 0xFF; if(!owBlock(portnum,FALSE,&send_block[0],send_cnt)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } setcrc16(portnum,0); for(i=0;i<34;i++) lastcrc16 = docrc16(portnum,send_block[i]); if(lastcrc16 != 0xB001) printf("CRC2 didn't match.\n"); printf("read data2: "); for(i=0;i<34;i++) printf("%02X ",send_block[i]); printf("\n"); send_cnt = 0; for(i=0;i<34;i++) send_block[send_cnt++] = 0xFF; if(!owBlock(portnum,FALSE,&send_block[0],send_cnt)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } setcrc16(portnum,0); for(i=0;i<34;i++) lastcrc16 = docrc16(portnum,send_block[i]); if(lastcrc16 != 0xB001) printf("CRC3 didn't match.\n"); printf("read data3: "); for(i=0;i<34;i++) printf("%02X ",send_block[i]); printf("\n"); break; case 18: // LED test printf("\nEnter the channel to turn the LED on.\n"); scanf("%d",&channel); printf("Turn reset mode off enter 1, on 0.\n"); scanf("%d",&set); printf("Alternate on and off 0=No, 1=Yes.\n"); scanf("%d",&alternate); if (!owTouchReset(portnum)) OWERROR_DUMP(stdout); if(!owWriteByte(portnum,0xCC)) printf("skip rom error.\n"); owWriteByte(portnum,0x5A); for(i=0;i<256;i++) { if(channel == 0) { if(set == 0) { if(!alternate) { if(!owWriteByte(portnum,0xFE)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x01)) printf("write byte error.\n"); check = 0xFE; } else { if(alt) { if(!owWriteByte(portnum,0xFE)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x01)) printf("write byte error.\n"); check = 0xFE; alt = FALSE; } else { if(!owWriteByte(portnum,0xFF)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x00)) printf("write byte error.\n"); check = 0xFF; alt = TRUE; } } } else { if(!alternate) { if(!owWriteByte(portnum,0xFF)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x00)) printf("write byte error.\n"); check = 0xFF; } else { if(alt) { if(!owWriteByte(portnum,0xFE)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x01)) printf("write byte error.\n"); check = 0xFE; alt = FALSE; } else { if(!owWriteByte(portnum,0xFF)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x00)) printf("write byte error.\n"); check = 0xFF; alt = TRUE; } } } } else { if(set == 0) { if(!alternate) { if(!owWriteByte(portnum,0xFD)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x02)) printf("write byte error.\n"); check = 0xFD; } else { if(alt) { if(!owWriteByte(portnum,0xFD)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x02)) printf("write byte error.\n"); check = 0xFD; alt = FALSE; } else { if(!owWriteByte(portnum,0xFF)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x00)) printf("write byte error.\n"); check = 0xFF; alt = TRUE; } } } else { if(!alternate) { if(!owWriteByte(portnum,0xFF)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x00)) printf("write byte error.\n"); check = 0xFF; } else { if(alt) { if(!owWriteByte(portnum,0xFD)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x02)) printf("write byte error.\n"); check = 0xFD; alt = FALSE; } else { if(!owWriteByte(portnum,0xFF)) printf("write byte error.\n"); if(!owWriteByte(portnum,0x00)) printf("write byte error.\n"); check = 0xFF; alt = TRUE; } } } } send_block[0] = (uchar)owReadByte(portnum); send_block[1] = (uchar)owReadByte(portnum); if((send_block[0] != 0xAA) && (send_block[1] != check)) printf("confirmation byte was %02X and read back was %02X\n", send_block[0],send_block[1]); } default: break; } }while(!done); } else printf("DS28E04 not found on One Wire Network\n"); owRelease(portnum); } return 1; }
//---------------------------------------------------------------------- // Copies hidden scratchpad data into specified secret. Resume command // is used by default. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'secretnum' - secret number to replace with scratchpad data. // // Return: TRUE - copy secret succeeded // FALSE - error or device not present // SMALLINT CopySecretSHA18(int portnum, SMALLINT secretnum) { // change number of verification bytes if in overdrive SMALLINT num_verf = (in_overdrive[portnum&0x0FF]) ? 10 : 2; // each page has 4 secrets, so look at 2 LS bits to // determine offset in the page. SMALLINT secret_offset = (secretnum&3) << 3; // secrets 0-3 are stored starting at address 0200h // and 4-7 are stored starting at address 0220h. int address = (secretnum<4 ? 0x0200 : 0x0220) + secret_offset; SMALLINT length = 32 - secret_offset; SMALLINT send_cnt = 0, i; uchar send_block[38]; ushort lastcrc16; //Since other functions must be called before this one //that are communicating with the button, resume is assumed. send_block[send_cnt++] = ROM_CMD_RESUME; send_block[send_cnt++] = CMD_WRITE_SCRATCHPAD; send_block[send_cnt++] = (uchar)address; send_block[send_cnt++] = (uchar)(address>>8); //for(i=0; i<length+2; i++) // send_block[send_cnt++] = (uchar)0x0FF; memset(&send_block[send_cnt], 0x0FF, 2+length); send_cnt += 2+length; // now send the block OWASSERT( owBlock(portnum,TRUE,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // calculate CRC16 of result setcrc16(portnum,0); for (i = 1; i < send_cnt ; i++) lastcrc16 = docrc16(portnum,send_block[i]); // verify CRC16 is correct OWASSERT( lastcrc16==0xB001, OWERROR_CRC_FAILED, FALSE ); // Now read TA1/TA2 and ES, but not rest of data; send_cnt = 1; send_block[send_cnt++] = CMD_READ_SCRATCHPAD; //for(i=0; i<3; i++) // send_block[send_cnt++] = (uchar)0x0FF; memset(&send_block[send_cnt], 0x0FF, 3); send_cnt += 3; // now send the block to get TA1/TA2 and ES OWASSERT( owBlock(portnum,TRUE,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // Use the same buffer to call copyScratchpad with proper // authorization bytes. send_block[1] = CMD_COPY_SCRATCHPAD; //for(i=0; i<num_verf; i++) // send_block[send_cnt++] = (uchar)0x0FF; memset(&send_block[send_cnt], 0x0FF, num_verf); send_cnt += num_verf; // now send the block OWASSERT( owBlock(portnum,TRUE,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // check verification OWASSERT( ((send_block[send_cnt-1] & 0xF0) == 0x50) || ((send_block[send_cnt-1] & 0xF0) == 0xA0), OWERROR_NO_COMPLETION_BYTE, FALSE ); return TRUE; }
//---------------------------------------------------------------------- // Compute sha command based on control_byte and page address. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'control_byte' - control byte used in sha operation // 'address' - address used in compute sha operation // 'resume' - if true, device access is resumed using the RESUME // ROM command (0xA5). Otherwise, a a MATCH ROM is // used along with the device's entire address number. // // Return: TRUE - compute sha finished // FALSE - CRC error, device not present // SMALLINT SHAFunction18(int portnum, uchar control_byte, int address, SMALLINT resume) { short send_cnt=0; uchar send_block[18]; int i,num_verf; ushort lastcrc16; if(!resume) { // access the device OWASSERT( SelectSHA(portnum), OWERROR_ACCESS_FAILED, FALSE ); } else { // transmit RESUME command send_block[send_cnt++] = ROM_CMD_RESUME; } setcrc16(portnum,0); // change number of verification bytes if in overdrive num_verf = (in_overdrive[portnum&0x0FF]) ? 10 : 2; // Compute SHA Command send_block[send_cnt] = CMD_COMPUTE_SHA; lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // address 1 send_block[send_cnt] = (uchar)(address & 0xFF); lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // address 2 send_block[send_cnt] = (uchar)((address >> 8) & 0xFF); lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // control byte send_block[send_cnt] = control_byte; lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // now read bytes crc16, and verification //for (i = 0; i < 2 + num_verf; i++) // send_block[send_cnt++] = 0xFF; memset(&send_block[send_cnt], 0x0FF, 2+num_verf); send_cnt += 2+num_verf; // now send the block OWASSERT( owBlock(portnum,resume,send_block,send_cnt), OWERROR_BLOCK_FAILED, FALSE ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // check the CRC for (i = resume?5:4; i < (send_cnt - num_verf); i++) lastcrc16 = docrc16(portnum,send_block[i]); // verify CRC16 is correct OWASSERT( lastcrc16==0xB001, OWERROR_CRC_FAILED, FALSE ); // check verification OWASSERT( ((send_block[send_cnt-1] & 0xF0) == 0x50) || ((send_block[send_cnt-1] & 0xF0) == 0xA0), OWERROR_NO_COMPLETION_BYTE, FALSE ); return TRUE; }
//---------------------------------------------------------------------- // Read Authenticated Page for DS1963S. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'pagenum' - page number to do a read authenticate // 'data' - buffer to read into from page // 'sign' - buffer for storing sha computation // 'resume' - if true, device access is resumed using the RESUME // ROM command (0xA5). Otherwise, a a MATCH ROM is // used along with the device's entire address number. // // Return: Value of write cycle counter for the page // -1 for error // int ReadAuthPageSHA18(int portnum, SMALLINT pagenum, uchar* data, uchar* sign, SMALLINT resume) { short send_cnt=0; uchar send_block[56]; short num_verf; SMALLINT i; ushort lastcrc16; int address = pagenum*32, wcc = -1; if(!resume) { // access the device OWASSERT( SelectSHA(portnum), OWERROR_ACCESS_FAILED, -1 ); } else { // transmit RESUME command send_block[send_cnt++] = ROM_CMD_RESUME; } //seed the crc setcrc16(portnum,0); // change number of verification bytes if in overdrive num_verf = (in_overdrive[portnum&0x0FF]) ? 10 : 2; // create the send block // Read Authenticated Page command send_block[send_cnt] = CMD_READ_AUTH_PAGE; lastcrc16 = docrc16(portnum, send_block[send_cnt++]); // TA1 send_block[send_cnt] = (uchar)(address & 0xFF); lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // TA2 send_block[send_cnt] = (uchar)((address >> 8) & 0xFF); lastcrc16 = docrc16(portnum,send_block[send_cnt++]); // now add the read bytes for data bytes, counter, and crc16, verification //for (i = 0; i < (42 + num_verf); i++) // send_block[send_cnt++] = 0xFF; memset(&send_block[send_cnt], 0x0FF, 42+num_verf); send_cnt += 42+num_verf; // now send the block OWASSERT( owBlock(portnum,resume,send_block,send_cnt), OWERROR_BLOCK_FAILED, -1 ); //\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DEBUG_DUMP debugout(send_block,send_cnt); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\// // check the CRC for (i = resume?4:3; i < (send_cnt - num_verf); i++) lastcrc16 = docrc16(portnum,send_block[i]); // verify CRC16 is correct OWASSERT( lastcrc16==0xB001, OWERROR_CRC_FAILED, -1); // check verification OWASSERT( ((send_block[send_cnt-1] & 0xF0) == 0x50) || ((send_block[send_cnt-1] & 0xF0) == 0xA0), OWERROR_NO_COMPLETION_BYTE, -1); // transfer results //cnt = 0; //for (i = send_cnt - 42 - num_verf; i < (send_cnt - 10 - num_verf); i++) // data[cnt++] = send_block[i]; memcpy(data, &send_block[send_cnt-42-num_verf], 32); wcc = BytesToInt(&send_block[send_cnt-10-num_verf], 4); if(sign!=NULL) { OWASSERT( ReadScratchpadSHA18(portnum, 0, 0, send_block, TRUE), OWERROR_READ_SCRATCHPAD_FAILED, FALSE ); //for(i=0; i<20; i++) // sign[i] = send_block[i+8]; memcpy(sign, &send_block[8], 20); } return wcc; }
//---------------------------------------------------------------------- // SUBROUTINE - SetSwitch1F // // This routine sets the main and auxilary on and off for DS2409. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'SerialNum' - Serial Number of DS2409 to set the switch state // 'Swtch' - '0' Sets Main and Auxilary off // '1' Sets Main on // '2' Sets Auxilary on // '3' Read Status Info Byte // '4' Smart On Main // 'NumExtra' - The number of extra bytes for a command. // 'InfoByte' - Returns the info byte and other information depending // on the command. The InfoByte size changes depending on // the NumExtra which is buffer length * (NumExtra + 1) // 'rst' - True then reset the search for devices // False don't reset search // // Returns: TRUE(1) State of DS2409 set and verified // FALSE(0) could not set the DS2409, perhaps device is not // in contact // int SetSwitch1F(int portnum, uchar *SerialNum, int Swtch, int NumExtra, uchar *InfoByte, int rst) { int send_cnt,i,cmd; uchar send_block[50]; if(owAccess(portnum)) { send_cnt = 0; // add the match command send_block[send_cnt++] = 0x55; for (i = 0; i < 8; i++) send_block[send_cnt++] = SerialNum[i]; // the command switch(Swtch) { case 0: // All lines off send_block[send_cnt++] = 0x66; cmd = 0x66; break; case 1: // Direct on Main send_block[send_cnt++] = 0xA5; cmd = 0xA5; break; case 2: // Smart on Auxilary send_block[send_cnt++] = 0x33; cmd = 0x33; break; case 3: // Status Read/Write send_block[send_cnt++] = 0x5A; cmd = 0x5A; // bytes 0-2: don't care // bytes 3-4: write control 0 to change status // byte 5: 0 = auto-control, 1 = manual mode // byte 6: 0 = main, 1 = auxiliary // byte 7: value to be written to control output, manual mode only // 0x00 default value *InfoByte = 0x00; send_block[send_cnt++] = *InfoByte; break; case 4: // Smart on Main send_block[send_cnt++] = 0xCC; cmd = 0xCC; break; default: return FALSE; } // extra bytes and confirmation for(i=0; i<=NumExtra; i++) send_block[send_cnt++] = 0xFF; // send the command string if(owBlock(portnum,rst,send_block,send_cnt)) { // returned information for the info byte and command for(i=0; i<=NumExtra; i++) *(InfoByte+(NumExtra-i)) = send_block[send_cnt - (i+2)]; // Set because for the read/write command the confirmation // byte is the same as the status byte if (Swtch == 3) cmd = send_block[send_cnt - 2]; if (send_block[send_cnt - 1] == cmd) return TRUE; } } return FALSE; }
/** * Writes new data to the secure subkey * * portnum the port number of the port being used for the * 1-Wire Network. * key number indicating the key to be written: 0, 1, or 2 * addr address to start writing at ( 0x00 to 0x3F ) * passwd passwird for the subkey * data data to be written * len the length of the data to be written * * return TRUE if the write was successful */ SMALLINT writeSubkey (int portnum, int key, int addr, uchar *passwd, uchar *data, int len) { uchar buffer[96]; int i; if(owAccess(portnum)) { //confirm key names and passwd within legal parameters if (key > 0x03) { OWERROR(OWERROR_KEY_OUT_OF_RANGE); return FALSE; } if ((addr < 0x00) || (addr > 0x3F)) { OWERROR(OWERROR_WRITE_OUT_OF_RANGE); return FALSE; } buffer[0] = WRITE_SUBKEY_COMMAND; buffer[1] = (uchar) ((key << 6) | addr); buffer[2] = (uchar) (~buffer [1]); //prepare buffer to receive 8 bytes of the identifier for(i = 3; i < 11; i++) buffer[i] = 0xFF; //prepare same subkey identifier for confirmation for(i=0;i<8;i++) buffer[i+11] = passwd[i]; //prepare data to write for(i=0;i<len;i++) buffer[i+19] = data[i]; //send command block if(len+19 > 64) { if(!owBlock(portnum,FALSE,&buffer[0],64)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } else if(!owBlock(portnum,FALSE,&buffer[64],(len+19)-64)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } } else { if(!owBlock(portnum,FALSE,buffer,len+19)) { OWERROR(OWERROR_BLOCK_FAILED); return FALSE; } } } else { OWERROR(OWERROR_DEVICE_SELECT_FAIL); return FALSE; } return TRUE; }
//---------------------------------------------------------------------- // Read a specified number of pages in overdrive // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // int ReadPages(int portnum, int start_pg, int num_pgs, int *last_pg, uchar *finalbuf) { int skip_overaccess = 0, skip_access = 0; uchar pkt[60]; int len,i; uchar SerialNumber[8]; ushort lastcrc16; // read the rom number owSerialNum(portnum,SerialNumber,TRUE); // verify device is in overdrive if (current_speed[portnum] == MODE_OVERDRIVE) { if (owVerify(portnum,FALSE)) skip_overaccess = 1; } if (!skip_overaccess) { if (owOverdriveAccess(portnum)) current_speed[portnum] = MODE_OVERDRIVE; else current_speed[portnum] = MODE_NORMAL; } // loop while there is pages to read do { // create a packet to read a page len = 0; setcrc16(portnum,0); // optional skip access on subsequent pages if (!skip_access) { // match pkt[len++] = 0x55; // rom number for (i = 0; i < 8; i++) pkt[len++] = SerialNumber[i]; // read memory with crc command pkt[len] = 0xA5; docrc16(portnum,pkt[len++]); // address pkt[len] = (uchar)((*last_pg << 5) & 0xFF); docrc16(portnum,pkt[len++]); pkt[len] = (uchar)(*last_pg >> 3); docrc16(portnum,pkt[len++]); } // set 32 reads for data and 2 for crc for (i = 0; i < 34; i++) pkt[len++] = 0xFF; // send the bytes if (owBlock(portnum,!skip_access,pkt,len)) { // calucate the CRC over the last 34 bytes for (i = 0; i < 34; i++) lastcrc16 = docrc16(portnum,pkt[len - 34 + i]); // check crc if (lastcrc16 == 0xB001) { // copy the data into the buffer #ifdef LetsCrashTheCompiler for (i = 0; i < 32; i++) finalbuf[i + (*last_pg - start_pg) * 32] = pkt[len - 34 + i]; #endif { ushort k; for (i = 0; i < 32; i++) { k=i + (*last_pg - start_pg) * 32; finalbuf[k] = pkt[len - 34 + i]; } } // change number of pages *last_pg = *last_pg + 1; // now skip access skip_access = TRUE; } else return FALSE; } else return FALSE; }