//--------------------------------------------------------------- // Description: // Attept to open a com port. // portnum - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // port_zstr - the string of the port to be used // Returns FALSE if unsuccessful and TRUE if successful. // SMALLINT OpenCOM(int portnum, char *port_zstr) { int i; for(i=0;i<4;i++) port[i] = port_zstr[i]; // Check if port has already been opened if (ComID[portnum] < 0) // Not opened { // Obtain port id ComID[portnum] = OpenComm(port_zstr,1024,1024); if (ComID[portnum] < 0) { OWERROR(OWERROR_GET_SYSTEM_RESOURCE_FAILED); return FALSE; } } else { return TRUE; // Already opened } if(!SetupCOM(portnum,CBR_9600)) // Reset unsuccessful { CloseCOM(portnum); OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED); return FALSE; } return TRUE; }
/** * 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; }
//-------------------------------------------------------------------------- // Reset all of the devices on the 1-Wire Net and return the result. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // // Returns: TRUE(1): presense pulse(s) detected, device(s) reset // FALSE(0): no presense pulses detected // SMALLINT owTouchResetUSB(int portnum) { SETUP_PACKET setup; SMALLINT present,vpp; SMALLINT ret = 0; // make sure strong pullup is not on if (USBLevel[portnum] == MODE_STRONG5) owLevelUSB(portnum, MODE_NORMAL); // construct command setup.RequestTypeReservedBits = 0x40; setup.Request = COMM_CMD; setup.Value = COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE; setup.Index = (USBSpeed[portnum] == MODE_OVERDRIVE) ? ONEWIREBUSSPEED_OVERDRIVE : ONEWIREBUSSPEED_FLEXIBLE; setup.Length = 0; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(usb_dev_handle_list[portnum], setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { // failure OWERROR(OWERROR_RESET_FAILED); AdapterRecover(portnum); return FALSE; } else { // extra delay for alarming DS1994/DS2404 complience if ((FAMILY_CODE_04_ALARM_TOUCHRESET_COMPLIANCE) && (USBSpeed[portnum] != MODE_OVERDRIVE)) msDelay(5); // success, check for shorts if (DS2490ShortCheck(usb_dev_handle_list[portnum], &present,&vpp)) { USBVpp[portnum] = vpp; return present; } else { OWERROR(OWERROR_OW_SHORTED); // short occuring msDelay(300); AdapterRecover(portnum); return FALSE; } } }
//---------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------- // Reset all of the devices on the 1-Wire Net and return the result. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // // Returns: TRUE(1): presense pulse(s) detected, device(s) reset // FALSE(0): no presense pulses detected // SMALLINT owTouchReset(int portnum) { SETUP_PACKET setup; ULONG nOutput = 0; SMALLINT present,vpp; // make sure strong pullup is not on if (USBLevel[portnum] == MODE_STRONG5) owLevel(portnum, MODE_NORMAL); // construct command setup.RequestTypeReservedBits = 0x40; setup.Request = COMM_CMD; setup.Value = COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE; setup.Index = (USBSpeed[portnum] == MODE_OVERDRIVE) ? ONEWIREBUSSPEED_OVERDRIVE : ONEWIREBUSSPEED_FLEXIBLE; setup.Length = 0; setup.DataOut = FALSE; // call the driver if (!DeviceIoControl(usbhnd[portnum], DS2490_IOCTL_VENDOR, &setup, sizeof(SETUP_PACKET), NULL, 0, &nOutput, NULL)) { // failure OWERROR(OWERROR_RESET_FAILED); AdapterRecover(portnum); return FALSE; } else { // extra delay for alarming DS1994/DS2404 complience if ((FAMILY_CODE_04_ALARM_TOUCHRESET_COMPLIANCE) && (USBSpeed[portnum] != MODE_OVERDRIVE)) Sleep(5); // success, check for shorts if (DS2490ShortCheck(usbhnd[portnum], &present,&vpp)) { USBVpp[portnum] = vpp; return present; } else { OWERROR(OWERROR_OW_SHORTED); // short occuring msDelay(300); AdapterRecover(portnum); return FALSE; } } }
//-------------------------------------------------------------------------- // This procedure creates a fixed 480 microseconds 12 volt pulse // on the 1-Wire Net for programming EPROM iButtons. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // // Returns: TRUE successful // FALSE program voltage not available // SMALLINT owProgramPulse(int portnum) { uchar sendpacket[10],readbuffer[10]; uchar sendlen=0; // check if programming voltage available if (!ProgramAvailable[portnum]) return FALSE; // make sure normal level owLevel(portnum,MODE_NORMAL); // check if correct mode if (UMode[portnum] != MODSEL_COMMAND) { UMode[portnum] = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // set the SPUD time value sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_12VPULSE | PARMSET_512us; // pulse command sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | BITPOL_12V | SPEEDSEL_PULSE; // flush the buffers FlushCOM(portnum); // send the packet if (WriteCOM(portnum,sendlen,sendpacket)) { // read back the 2 byte response if (ReadCOM(portnum,2,readbuffer) == 2) { // check response byte if (((readbuffer[0] | CMD_CONFIG) == (CMD_CONFIG | PARMSEL_12VPULSE | PARMSET_512us)) && ((readbuffer[1] & 0xFC) == (0xFC & (CMD_COMM | FUNCTSEL_CHMOD | BITPOL_12V | SPEEDSEL_PULSE)))) return TRUE; } else OWERROR(OWERROR_READCOM_FAILED); } else OWERROR(OWERROR_WRITECOM_FAILED); // an error occurred so re-sync with DS2480 DS2480Detect(portnum); return FALSE; }
//-------------------------------------------------------------------------- // Reset all of the devices on the 1-Wire Net and return the result. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // // Returns: TRUE(1): presense pulse(s) detected, device(s) reset // FALSE(0): no presense pulses detected // // WARNING: This routine will not function correctly on some // Alarm reset types of the DS1994/DS1427/DS2404 with // Rev 1,2, and 3 of the DS2480/DS2480B. // SMALLINT owTouchReset(int portnum) { uchar readbuffer[10],sendpacket[10]; uchar sendlen=0; // make sure normal level owLevel(portnum,MODE_NORMAL); // check if correct mode if (UMode[portnum] != MODSEL_COMMAND) { UMode[portnum] = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // construct the command sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_RESET | USpeed[portnum]); // flush the buffers FlushCOM(portnum); // send the packet if (WriteCOM(portnum,sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(portnum,1,readbuffer) == 1) { // make sure this byte looks like a reset byte if (((readbuffer[0] & RB_RESET_MASK) == RB_PRESENCE) || ((readbuffer[0] & RB_RESET_MASK) == RB_ALARMPRESENCE)) { // check if programming voltage available ProgramAvailable[portnum] = ((readbuffer[0] & 0x20) == 0x20); return TRUE; } else OWERROR(OWERROR_RESET_FAILED); } else OWERROR(OWERROR_READCOM_FAILED); } else OWERROR(OWERROR_WRITECOM_FAILED); // an error occurred so re-sync with DS2480 DS2480Detect(portnum); return FALSE; }
/** * 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; }
//-------------------------------------------------------------------------- // 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: // // 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 the buffer for the data that was read // pg the page that starts the read // // return TRUE if the read was successful. // SMALLINT ExtendedRead_Page(int portnum, uchar *SNum, uchar *buff, PAGE_TYPE pg) { SMALLINT bank; PAGE_TYPE page; uchar extra[20]; 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)) { if(getJobData(portnum,SNum,pg,&buff[1],&len)) { 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<owGetExtraInfoLength(bank,SNum);i++) buff[i+32] = extra[i]; extra[0] = 0xFF; } if(extra[0] != 0xFF) { OWERROR(OWERROR_REDIRECTED_PAGE); return FALSE; } return TRUE; }
//-------------------------------------------------------------------------- // Send 8 bits of communication to the 1-Wire Net and verify that the // 8 bits read from the 1-Wire Net is the same (write operation). // The parameter 'sendbyte' least significant 8 bits are used. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'sendbyte' - 8 bits to send (least significant byte) // // Returns: TRUE: bytes written and echo was the same // FALSE: echo was not the same // SMALLINT owTouchByteUSB(int portnum, SMALLINT sendbyte) { SETUP_PACKET setup; ushort nBytes; uchar buf[2]; SMALLINT ret = 0; // make sure strong pullup is not on if (USBLevel[portnum] == MODE_STRONG5) owLevelUSB(portnum, MODE_NORMAL); // set to do touchbyte setup.RequestTypeReservedBits = 0x40; setup.Request = COMM_CMD; setup.Value = COMM_BYTE_IO | COMM_IM; setup.Index = sendbyte & 0xFF; setup.Length = 0; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(usb_dev_handle_list[portnum], setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { // failure OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return 0; } else { // success, read the result nBytes = 1; if (DS2490Read(usb_dev_handle_list[portnum], buf, &nBytes)) return buf[0]; else { OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return 0; } } }
//-------------------------------------------------------------------------- // Send 8 bits of communication to the 1-Wire Net and verify that the // 8 bits read from the 1-Wire Net is the same (write operation). // The parameter 'sendbyte' least significant 8 bits are used. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'sendbyte' - 8 bits to send (least significant byte) // // Returns: TRUE: bytes written and echo was the same // FALSE: echo was not the same // SMALLINT owTouchByte(int portnum, SMALLINT sendbyte) { SETUP_PACKET setup; ULONG nOutput = 0; WORD nBytes; BYTE buf[2]; // make sure strong pullup is not on if (USBLevel[portnum] == MODE_STRONG5) owLevel(portnum, MODE_NORMAL); // set to do touchbyte setup.RequestTypeReservedBits = 0x40; setup.Request = COMM_CMD; setup.Value = COMM_BYTE_IO | COMM_IM; setup.Index = sendbyte & 0xFF; setup.Length = 0; setup.DataOut = FALSE; // call the driver if (!DeviceIoControl(usbhnd[portnum], DS2490_IOCTL_VENDOR, &setup, sizeof(SETUP_PACKET), NULL, 0, &nOutput, NULL)) { // failure OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return 0; } else { // success, read the result nBytes = 1; if (DS2490Read(usbhnd[portnum], buf, &nBytes)) return buf[0]; else { OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return 0; } } }
//--------------------------------------------------------------------------- // Description: Perfroms a hardware reset of the DS2490 equivalent to a // power-on reset // Input: hDevice - the handle to the DS2490 device // Returns: FALSE on failure, TRUE on success // Error Codes: DS2490COMM_ERR_USBDEVICE // SMALLINT DS2490Reset(usb_dev_handle *hDevice) { SETUP_PACKET setup; SMALLINT ret = 0; // setup for reset setup.RequestTypeReservedBits = 0x40; setup.Request = CONTROL_CMD; setup.Value = CTL_RESET_DEVICE; setup.Index = 0x00; setup.Length = 0x00; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(hDevice, setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { OWERROR(OWERROR_ADAPTER_ERROR); return FALSE; } return TRUE; }
//-------------------------------------------------------------------------- // Set the 1-Wire Net communucation speed. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'new_speed' - new speed defined as // MODE_NORMAL 0x00 // MODE_OVERDRIVE 0x01 // // Returns: current 1-Wire Net speed // SMALLINT owSpeed(int portnum, SMALLINT new_speed) { SETUP_PACKET setup; ULONG nOutput = 0; // set to change the speed setup.RequestTypeReservedBits = 0x40; setup.Request = MODE_CMD; setup.Value = MOD_1WIRE_SPEED; setup.Index = ((new_speed == MODE_OVERDRIVE) ? ONEWIREBUSSPEED_OVERDRIVE : ONEWIREBUSSPEED_FLEXIBLE) & 0x00FF; setup.Length = 0x00; setup.DataOut = FALSE; // call the driver if (!DeviceIoControl(usbhnd[portnum], DS2490_IOCTL_VENDOR, &setup, sizeof(SETUP_PACKET), NULL, 0, &nOutput, NULL)) { // failure OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return USBSpeed[portnum]; } else { // success, read the result USBSpeed[portnum] = new_speed; return new_speed; } }
//-------------------------------------------------------------------------- // 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 // pg 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; uchar addpg; // 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 { addpg = AddPage(portnum,SNum,pg,buff,len); } return TRUE; }
//-------------------------------------------------------------------------- // Set the 1-Wire Net communucation speed. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'new_speed' - new speed defined as // MODE_NORMAL 0x00 // MODE_OVERDRIVE 0x01 // // Returns: current 1-Wire Net speed // SMALLINT owSpeedUSB(int portnum, SMALLINT new_speed) { SETUP_PACKET setup; SMALLINT ret = 0; // set to change the speed setup.RequestTypeReservedBits = 0x40; setup.Request = MODE_CMD; setup.Value = MOD_1WIRE_SPEED; setup.Index = ((new_speed == MODE_OVERDRIVE) ? ONEWIREBUSSPEED_OVERDRIVE : ONEWIREBUSSPEED_FLEXIBLE) & 0x00FF; setup.Length = 0x00; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(usb_dev_handle_list[portnum], setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { // failure OWERROR(OWERROR_ADAPTER_ERROR); AdapterRecover(portnum); return USBSpeed[portnum]; } else { // success, read the result USBSpeed[portnum] = new_speed; return new_speed; } }
/** * 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; }
//-------------------------------------------------------------------------- // Send 1 bit of communication to the 1-Wire Net and return the // result 1 bit read from the 1-Wire Net. The parameter 'sendbit' // least significant bit is used and the least significant bit // of the result is the return bit. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // 'sendbit' - the least significant bit is the bit to send // // Returns: 0: 0 bit read from sendbit // 1: 1 bit read from sendbit // SMALLINT owTouchBit(int portnum, SMALLINT sendbit) { uchar readbuffer[10],sendpacket[10]; uchar sendlen=0; // make sure normal level owLevel(portnum,MODE_NORMAL); // check if correct mode if (UMode[portnum] != MODSEL_COMMAND) { UMode[portnum] = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // construct the command sendpacket[sendlen] = (sendbit != 0) ? BITPOL_ONE : BITPOL_ZERO; sendpacket[sendlen++] |= CMD_COMM | FUNCTSEL_BIT | USpeed[portnum]; // flush the buffers FlushCOM(portnum); // send the packet if (WriteCOM(portnum,sendlen,sendpacket)) { // read back the response if (ReadCOM(portnum,1,readbuffer) == 1) { // interpret the response if (((readbuffer[0] & 0xE0) == 0x80) && ((readbuffer[0] & RB_BIT_MASK) == RB_BIT_ONE)) return 1; else return 0; } else OWERROR(OWERROR_READCOM_FAILED); } else OWERROR(OWERROR_WRITECOM_FAILED); // an error occurred so re-sync with DS2480 DS2480Detect(portnum); return 0; }
//-------------------------------------------------------------------------- // Send 8 bits of communication to the 1-Wire Net and return the // result 8 bits read from the 1-Wire Net. The parameter 'sendbyte' // least significant 8 bits are used and the least significant 8 bits // of the result is the return byte. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // 'sendbyte' - 8 bits to send (least significant byte) // // Returns: 8 bits read from sendbyte // SMALLINT owTouchByte(int portnum, SMALLINT sendbyte) { uchar readbuffer[10],sendpacket[10]; uchar sendlen=0; // make sure normal level owLevel(portnum,MODE_NORMAL); // check if correct mode if (UMode[portnum] != MODSEL_DATA) { UMode[portnum] = MODSEL_DATA; sendpacket[sendlen++] = MODE_DATA; } // add the byte to send sendpacket[sendlen++] = (uchar)sendbyte; // check for duplication of data that looks like COMMAND mode if (sendbyte ==(SMALLINT)MODE_COMMAND) sendpacket[sendlen++] = (uchar)sendbyte; // flush the buffers FlushCOM(portnum); // send the packet if (WriteCOM(portnum,sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(portnum,1,readbuffer) == 1) { // return the response return (int)readbuffer[0]; } else OWERROR(OWERROR_READCOM_FAILED); } else OWERROR(OWERROR_WRITECOM_FAILED); // an error occurred so re-sync with DS2480 DS2480Detect(portnum); return 0; }
//---------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------- // 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; }
//------------------------------------------------------------------------- // Returns the user's current balance as an int // // 'user' - Structure for holding user token information. // // Return: Current value of the user's balance. // int GetBalance(SHAUser* user) { int balance = -1; if(user->devAN[0]==0x18) balance = BytesToInt(((DebitFile*)user->accountFile)->balanceBytes, 3); else if((user->devAN[0]&0x7F)==0x33) { DebitFile33* acctFile = (DebitFile33*)user->accountFile; if(acctFile->fileLength==RECORD_A_LENGTH) balance = BytesToInt(acctFile->balanceBytes_A, 3); else if(acctFile->fileLength==RECORD_B_LENGTH) balance = BytesToInt(acctFile->balanceBytes_B, 3); else OWERROR(OWERROR_BAD_SERVICE_DATA); } else OWERROR(OWERROR_BAD_SERVICE_DATA); return balance; }
//--------------------------------------------------------------------------- // Attempt to acquire a 1-Wire net using a com port and a DS2480 based // adapter. // // 'port_zstr' - zero terminated port name. For this platform // use format COMX where X is the port number. // // Returns: valid handle, or -1 if an error occurred // // exportable functions defined in ownetu.c // int owAcquireEx(char *port_zstr) { int portnum; // attempt to open the communications port if ((portnum = OpenCOMEx(port_zstr)) < 0) { OWERROR(OWERROR_OPENCOM_FAILED); return -1; } // detect DS2480 if (!DS2480Detect(portnum)) { CloseCOM(portnum); OWERROR(OWERROR_DS2480_NOT_DETECTED); return -1; } return portnum; }
//-------------------------------------------------------------------------- // 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; }
/* Release port 'portnum' */ void owRelease(int portnum) { /* Restore original settings */ if(tcsetattr(fd[portnum], TCSANOW, &term_orig[portnum]) < 0 ) { /* We failed doing that */ OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED); perror("owAcquire: failed to set attributes"); close(fd[portnum]); } /* Close the port */ if (close(fd[portnum]) < 0) { /* We failed closing the port */ OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED); perror("owAcquire: failed to close port"); } /* we should return an error condition here but MAXIMS API is * badly designed */ }
//--------------------------------------------------------------------------- // Description: Gets the status of the DS2490 device // Input: hDevice - the handle to the DS2490 device // pStatus - the Status Packet to be filled with data // pResultSize - the number of result register codes returned // // Returns: FALSE on failure, TRUE on success // SMALLINT DS2490GetStatus(usb_dev_handle *hDevice, STATUS_PACKET *status, uchar *pResultSize) { // buffer to retrieve status uchar buffer[32]; SMALLINT i = 0; SMALLINT bufferlength = 0; // initialize buffer memset(&buffer[0],0x00,32); // get status buffer bufferlength = usb_bulk_read(hDevice,DS2490_EP1,(char*)&buffer[0],32,TIMEOUT_LIBUSB); /* rma: fixed signedness warning */ if (bufferlength < 0) { OWERROR(OWERROR_ADAPTER_ERROR); return FALSE; } // make status packet from return buffer status->EnableFlags = buffer[0]; status->OneWireSpeed = buffer[1]; status->StrongPullUpDuration = buffer[2]; status->ProgPulseDuration = buffer[3]; status->PullDownSlewRate = buffer[4]; status->Write1LowTime = buffer[5]; status->DSOW0RecoveryTime = buffer[6]; status->Reserved1 = buffer[7]; status->StatusFlags = buffer[8]; status->CurrentCommCmd1 = buffer[9]; status->CurrentCommCmd2 = buffer[10]; status->CommBufferStatus = buffer[11]; status->WriteBufferStatus = buffer[12]; status->ReadBufferStatus = buffer[13]; status->Reserved2 = buffer[14]; status->Reserved3 = buffer[15]; // take care for CommResultCodes (if they exist) if (bufferlength > 15) { for (i=0; i<16; i++) { status->CommResultCodes[i] = buffer[16 + i]; } *pResultSize = bufferlength - 16; // This should be the size of CommResultCodes... } else { *pResultSize = 0; } 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 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; }
//-------------------------------------------------------------------------- // Attempt to recover communication with the DS2490 // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // indicate the port number. // // Returns: TRUE DS2490 recover successfull // FALSE failed to recover // SMALLINT AdapterRecover(int portnum) { // dectect DS2490 and set it up if (DS2490Detect(usbhnd[portnum])) { USBSpeed[portnum] = MODE_NORMAL; // current DS2490 1-Wire Net communication speed USBLevel[portnum] = MODE_NORMAL; // current DS2490 1-Wire Net level return TRUE; } else { OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED); return FALSE; } }
//--------------------------------------------------------------------------- // Attempt to acquire a 1-Wire net using a com port and a DS2480 based // adapter. // // 'port_zstr' - zero terminated port name. For this platform // use format COMX where X is the port number. // // Returns: The portnum or -1 if the port wasn't acquired. // int owAcquireEx(char *port_zstr) { int portnum = 0; port_zstr = 0; OW_PORT = 1; // drive bus high. usDelay(500); // give time for line to settle // checks to make sure the line is idling high. if(OW_PORT != 1) { OWERROR(OWERROR_OPENCOM_FAILED); return -1; } return portnum; }
//--------------------------------------------------------------------------- // Attempt to acquire a 1-Wire net using a com port and a DS2480 based // adapter. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // 'port_zstr' - zero terminated port name. For this platform // use format COMX where X is the port number. // // Returns: TRUE - success, COM port opened // // exportable functions defined in ownetu.c SMALLINT owAcquire(int portnum, char *port_zstr) { // attempt to open the communications port if (OpenCOM(portnum,port_zstr) < 0) { OWERROR(OWERROR_OPENCOM_FAILED); return FALSE; } // detect DS2480 if (!DS2480Detect(portnum)) { CloseCOM(portnum); //OWERROR(OWERROR_DS2480_NOT_DETECTED); return FALSE; } return TRUE; }