/****************************************************************************** main : point d'entrée du programme. ******************************************************************************/ int main() { /* variables locales */ char buffer[256]; int nId, nChoice, nBytesWritten, nBytesRead; /* demande du numéro du port COM */ printf("Entrez le numero du port COM : "); scanf("%d", &nId); /* tentative d'ouverture */ printf("Ouverture et configuration du port COM%d...\r\n", nId); if(!OpenCOM(nId)) return -1; printf("...OK\r\n"); /* boucle tant que l'on ne quitte pas */ do { /* menu */ printf("\r\n"); printf("1 : Envoyer des donnees.\r\n"); printf("2 : Recevoir des donnees.\r\n"); printf("3 : Quitter.\r\n"); printf("Choix : "); scanf("%d", &nChoice); /* enoyer des données */ if(nChoice == 1) { printf("\r\n"); printf("Donnees a envoyer :\r\n"); fflush(stdin); gets(buffer); printf("\r\n"); printf("Envoi des donnees...\r\n"); if(WriteCOM(buffer, strlen(buffer), &nBytesWritten)) printf("%d octet(s) envoye(s).\r\n", nBytesWritten); else printf("Erreur lors de l'envoi.\r\n"); } /* recevoir des données */ if(nChoice == 2) { printf("\r\n"); printf("Reception de donnees...\r\n"); if(ReadCOM(buffer, sizeof(buffer)-1, &nBytesRead)) { buffer[nBytesRead] = '\0'; printf("%d octet(s) recu(s) :\r\n%s\r\n", nBytesRead, buffer); } else printf("Erreur lors de la réception.\r\n"); } }while(nChoice != 3); /* fermeture du port COM et retour */ CloseCOM(); return 0; }
//-------------------------------------------------------------------------- // Set the MicroLAN communucation speed. // // 'NewSpeed' - new speed defined as // MODE_NORMAL 0x00 // MODE_OVERDRIVE 0x01 // // Returns: current MicroLAN speed // int MLanSpeed(int NewSpeed) { uchar sendpacket[5]; short sendlen=0; int rt = FALSE; // check if change from current mode if (((NewSpeed == MODE_OVERDRIVE) && (USpeed != SPEEDSEL_OD)) || ((NewSpeed == MODE_NORMAL) && (USpeed != SPEEDSEL_FLEX))) { if (NewSpeed == MODE_OVERDRIVE) { // if overdrive then switch to 115200 baud if (DS2480ChangeBaud(PARMSET_57600) == PARMSET_57600) { USpeed = SPEEDSEL_OD; rt = TRUE; } } else if (NewSpeed == MODE_NORMAL) { // else normal so set to 9600 baud if (DS2480ChangeBaud(PARMSET_9600) == PARMSET_9600) { USpeed = SPEEDSEL_FLEX; rt = TRUE; } } // if baud rate is set correctly then change DS2480 speed if (rt) { // check if correct mode if (UMode != MODSEL_COMMAND) { UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // proceed to set the DS2480 communication speed sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed; // send the packet if (!WriteCOM(sendlen,sendpacket)) { rt = FALSE; // lost communication with DS2480 then reset DS2480Detect(); } } } // return the current speed return (USpeed == SPEEDSEL_OD) ? MODE_OVERDRIVE : MODE_NORMAL; }
//-------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------- // The 'OWBlock' transfers a block of data to and from the // 1-Wire Net. The result is returned in the same buffer. // // 'tran_buf' - pointer to a block of unsigned // chars of length 'tran_len' that will be sent // to the 1-Wire Net // 'tran_len' - length in bytes to transfer // // Returns: TRUE (1) : If the buffer transfer was succesful. // FALSE (0): If an error occured. // // The maximum tran_length is (160) // int DallasOneWire::OWBlock(unsigned char *tran_buf, int tran_len) { DATA(F("OWBlock")); unsigned char sendpacket[320]; unsigned char sendlen=0; // check for a block too big if (tran_len > 160) return FALSE; // construct the packet to send to the DS2480B // check for correct mode if (UMode != MODSEL_DATA) { UMode = MODSEL_DATA; sendpacket[sendlen++] = MODE_DATA; } // add the bytes to send for (int i = 0; i < tran_len; i++) { sendpacket[sendlen++] = tran_buf[i]; // duplicate data that looks like COMMAND mode if (tran_buf[i] == MODE_COMMAND) sendpacket[sendlen++] = tran_buf[i]; } // flush the buffers flush(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the response if (ReadCOM(tran_len,tran_buf) == tran_len) { return TRUE; } else DEBUG(F("Read error")); } WARNING(F("OWBlock: An error occured so re-sync with DS2480B")); // an error occured so re-sync with DS2480B DS2480B_Detect(); return FALSE; }
//-------------------------------------------------------------------------- // This procedure creates a fixed 480 microseconds 12 volt pulse // on the 1-Wire Net for programming EPROM iButtons. // // Returns: TRUE successful // FALSE program voltage not available // int DallasOneWire::OWProgramPulse(void) { DATA(F("OWProgramPulse")); unsigned char sendpacket[10],readbuffer[10]; unsigned char sendlen=0; // make sure normal level OWLevel(MODE_NORMAL); // check for correct mode if (UMode != MODSEL_COMMAND) { UMode = 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 flush(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 2 byte response if (ReadCOM(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 DEBUG(F("Read error")); } // an error occured so re-sync with DS2480B WARNING(F("OWProgramPulse - lost communication with DS2480B then reset")); DS2480B_Detect(); return FALSE; }
//-------------------------------------------------------------------------- // This procedure creates a fixed 480 microseconds 12 volt pulse // on the MicroLAN for programming EPROM iButtons. // // Returns: TRUE successful // FALSE program voltage not available // int MLanProgramPulse(void) { uchar sendpacket[10],readbuffer[10]; short sendlen=0; // check if programming voltage available if (!ProgramAvailable) return FALSE; // make sure normal level MLanLevel(MODE_NORMAL); // check if correct mode if (UMode != MODSEL_COMMAND) { UMode = 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(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 2 byte response if (ReadCOM(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; } } // an error occured so re-sync with DS2480 DS2480Detect(); return FALSE; }
//-------------------------------------------------------------------------- // Reset all of the devices on the 1-Wire Net and return the result. // // Returns: TRUE(1): presense pulse(s) detected, device(s) reset // FALSE(0): no presense pulses detected // // WARNING: Without setting the above global (FAMILY_CODE_04_ALARM_TOUCHRESET_COMPLIANCE) // to TRUE, 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. // // int DallasOneWire::OWReset(void) { DATA(F("OWReset")); unsigned char readbuffer[10],sendpacket[10]; unsigned char sendlen=0; // make sure normal level OWLevel(MODE_NORMAL); // check for correct mode if (UMode != MODSEL_COMMAND) { UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // construct the command sendpacket[sendlen++] = (unsigned char)(CMD_COMM | FUNCTSEL_RESET | USpeed); // flush the buffers flush(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(1,readbuffer) == 1) { //_delay_ms(5); // delay 5 ms to give DS1994 enough time flush(); //return TRUE; // make sure this byte looks like a reset byte if (((readbuffer[0] & RB_RESET_MASK) == RB_PRESENCE) || ((readbuffer[0] & RB_RESET_MASK) == RB_ALARMPRESENCE)) return TRUE; } else DEBUG(F("Read error")); } WARNING(F("An error occurred so re-sync with DS2480B")); // an error occurred so re-sync with DS2480B DS2480B_Detect(); return FALSE; }
//-------------------------------------------------------------------------- // 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 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. // // 'sendbit' - the least significant bit is the bit to send // // Returns: 0: 0 bit read from sendbit // 1: 1 bit read from sendbit // unsigned char DallasOneWire::OWTouchBit(unsigned char sendbit) { DATA("OWTouchBit"); unsigned char readbuffer[10],sendpacket[10]; unsigned char sendlen=0; // make sure normal level OWLevel(MODE_NORMAL); // check for correct mode if (UMode != MODSEL_COMMAND) { UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // construct the command sendpacket[sendlen] = (sendbit != 0) ? BITPOL_ONE : BITPOL_ZERO; sendpacket[sendlen++] |= CMD_COMM | FUNCTSEL_BIT | USpeed; // flush the buffers flush(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the response if (ReadCOM(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 DEBUG(F("Read error")); } WARNING(F("OWTouchBit: An error occured so re-sync with DS2480B")); // an error occured so re-sync with DS2480B DS2480B_Detect(); 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; }
//-------------------------------------------------------------------------- // Reset all of the devices on the MicroLAN and return the result. // // 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 and 2 of the DS2480. // int MLanTouchReset(void) { uchar readbuffer[10],sendpacket[10]; int sendlen=0; // make sure normal level MLanLevel(MODE_NORMAL); // check if correct mode if (UMode != MODSEL_COMMAND) { UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // construct the command sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_RESET | USpeed); // flush the buffers FlushCOM(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(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 = ((readbuffer[0] & 0x20) == 0x20); return TRUE; } else return FALSE; } } // an error occured so re-sync with DS2480 DS2480Detect(); return FALSE; }
//-------------------------------------------------------------------------- // 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. // // 'sendbyte' - 8 bits to send (least significant byte) // // Returns: 8 bits read from sendbyte // unsigned char DallasOneWire::OWTouchByte(unsigned char sendbyte) { DATA(F("OWTouchByte")); unsigned char readbuffer[10],sendpacket[10]; unsigned char sendlen=0; // make sure normal level OWLevel(MODE_NORMAL); // check for correct mode if (UMode != MODSEL_DATA) { UMode = MODSEL_DATA; sendpacket[sendlen++] = MODE_DATA; } // add the byte to send sendpacket[sendlen++] = (unsigned char)sendbyte; // check for duplication of data that looks like COMMAND mode if (sendbyte ==(int)MODE_COMMAND) sendpacket[sendlen++] = (unsigned char)sendbyte; // flush the buffers flush(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(1,readbuffer) == 1) { // return the response return readbuffer[0]; } else DEBUG(F("Read error")); } WARNING(F("OWTouchByte: An error occured so re-sync with DS2480B")); // an error occured so re-sync with DS2480B DS2480B_Detect(); return 0; }
//-------------------------------------------------------------------------- // Send 1 bit of communication to the MicroLAN and return the // result 1 bit read from the MicroLAN. The parameter 'sendbit' // least significant bit is used and the least significant bit // of the result is the return bit. // // 'sendbit' - the least significant bit is the bit to send // // Returns: 0: 0 bit read from sendbit // 1: 1 bit read from sendbit // int MLanTouchBit(int sendbit) { uchar readbuffer[10],sendpacket[10]; int sendlen=0; // make sure normal level MLanLevel(MODE_NORMAL); // check if correct mode if (UMode != MODSEL_COMMAND) { UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // construct the command sendpacket[sendlen] = (sendbit != 0) ? BITPOL_ONE : BITPOL_ZERO; sendpacket[sendlen++] |= CMD_COMM | FUNCTSEL_BIT | USpeed; // flush the buffers FlushCOM(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the response if (ReadCOM(1,readbuffer) == 1) { // interpret the response if (((readbuffer[0] & 0xE0) == 0x80) && ((readbuffer[0] & RB_BIT_MASK) == RB_BIT_ONE)) return 1; else return 0; } } // an error occured so re-sync with DS2480 DS2480Detect(); return 0; }
//-------------------------------------------------------------------------- // Send 8 bits of communication to the MicroLAN and return the // result 8 bits read from the MicroLAN. The parameter 'sendbyte' // least significant 8 bits are used and the least significant 8 bits // of the result is the return byte. // // 'sendbyte' - 8 bits to send (least significant byte) // // Returns: 8 bytes read from sendbyte // int MLanTouchByte(int sendbyte) { uchar readbuffer[10],sendpacket[10]; int sendlen=0; // make sure normal level MLanLevel(MODE_NORMAL); // check if correct mode if (UMode != MODSEL_DATA) { UMode = 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 == MODE_COMMAND) sendpacket[sendlen++] = (uchar)sendbyte; // flush the buffers FlushCOM(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(1,readbuffer) == 1) { // return the response return (int)readbuffer[0]; } } // an error occured so re-sync with DS2480 DS2480Detect(); return 0; }
//-------------------------------------------------------------------------- // The 'owNext' function does a general search. This function // continues from the previos search state. The search state // can be reset by using the 'owFirst' function. // This function contains one parameter 'alarm_only'. // When 'alarm_only' is TRUE (1) the find alarm command // 0xEC is sent instead of the normal search command 0xF0. // Using the find alarm command 0xEC will limit the search to only // 1-Wire devices that are in an 'alarm' state. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // 'do_reset' - TRUE (1) perform reset before search, FALSE (0) do not // perform reset before search. // 'alarm_only' - TRUE (1) the find alarm command 0xEC is // sent instead of the normal search command 0xF0 // // Returns: TRUE (1) : when a 1-Wire device was found and it's // Serial Number placed in the global SerialNum // FALSE (0): when no new device was found. Either the // last search was the last device or there // are no devices on the 1-Wire Net. // SMALLINT owNext(int portnum, SMALLINT do_reset, SMALLINT alarm_only) { uchar last_zero,pos; uchar tmp_serial_num[8]; uchar readbuffer[20],sendpacket[40]; uchar i,sendlen=0; uchar lastcrc8; // if the last call was the last one if (LastDevice[portnum]) { // reset the search LastDiscrepancy[portnum] = 0; LastDevice[portnum] = FALSE; LastFamilyDiscrepancy[portnum] = 0; return FALSE; } // check if reset first is requested if (do_reset) { // reset the 1-wire // if there are no parts on 1-wire, return FALSE if (!owTouchReset(portnum)) { // reset the search LastDiscrepancy[portnum] = 0; LastFamilyDiscrepancy[portnum] = 0; OWERROR(OWERROR_NO_DEVICES_ON_NET); return FALSE; } } // build the command stream // call a function that may add the change mode command to the buff // check if correct mode if (UMode[portnum] != MODSEL_DATA) { UMode[portnum] = MODSEL_DATA; sendpacket[sendlen++] = MODE_DATA; } // search command if (alarm_only) sendpacket[sendlen++] = 0xEC; // issue the alarming search command else sendpacket[sendlen++] = 0xF0; // issue the search command // change back to command mode UMode[portnum] = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; // search mode on sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_SEARCHON | USpeed[portnum]); // change back to data mode UMode[portnum] = MODSEL_DATA; sendpacket[sendlen++] = MODE_DATA; // set the temp Last Descrep to none last_zero = 0; // add the 16 bytes of the search pos = sendlen; for (i = 0; i < 16; i++) sendpacket[sendlen++] = 0; // only modify bits if not the first search if (LastDiscrepancy[portnum] != 0) { // set the bits in the added buffer for (i = 0; i < 64; i++) { // before last discrepancy if (i < (LastDiscrepancy[portnum] - 1)) bitacc(WRITE_FUNCTION, bitacc(READ_FUNCTION,0,i,&SerialNum[portnum][0]), (short)(i * 2 + 1), &sendpacket[pos]); // at last discrepancy else if (i == (LastDiscrepancy[portnum] - 1)) bitacc(WRITE_FUNCTION,1, (short)(i * 2 + 1), &sendpacket[pos]); // after last discrepancy so leave zeros } } // change back to command mode UMode[portnum] = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; // search OFF sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed[portnum]); // flush the buffers FlushCOM(portnum); // send the packet if (WriteCOM(portnum,sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(portnum,17,readbuffer) == 17) { // interpret the bit stream for (i = 0; i < 64; i++) { // get the SerialNum bit bitacc(WRITE_FUNCTION, bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]), i, &tmp_serial_num[0]); // check LastDiscrepancy if ((bitacc(READ_FUNCTION,0,(short)(i * 2),&readbuffer[1]) == 1) && (bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]) == 0)) { last_zero = i + 1; // check LastFamilyDiscrepancy if (i < 8) LastFamilyDiscrepancy[portnum] = i + 1; } } // do dowcrc setcrc8(portnum,0); // for (i = 0; i < 8; i++) // lastcrc8 = docrc8(portnum,tmp_serial_num[i]); // The above has been commented out for the DS28E04. The // below has been added to accomidate the valid CRC with the // possible changing serial number values of the DS28E04. for (i = 0; i < 8; i++) { if (((tmp_serial_num[0] & 0x7F) == 0x1C) && (i == 1)) lastcrc8 = docrc8(portnum,0x7F); else lastcrc8 = docrc8(portnum,tmp_serial_num[i]); } // check results if ((lastcrc8 != 0) || (LastDiscrepancy[portnum] == 63) || (tmp_serial_num[0] == 0)) { // error during search // reset the search LastDiscrepancy[portnum] = 0; LastDevice[portnum] = FALSE; LastFamilyDiscrepancy[portnum] = 0; OWERROR(OWERROR_SEARCH_ERROR); return FALSE; } // successful search else { // set the last discrepancy LastDiscrepancy[portnum] = last_zero; // check for last device if (LastDiscrepancy[portnum] == 0) LastDevice[portnum] = TRUE; // copy the SerialNum to the buffer for (i = 0; i < 8; i++) SerialNum[portnum][i] = tmp_serial_num[i]; // set the count return TRUE; } } else OWERROR(OWERROR_READCOM_FAILED); } else OWERROR(OWERROR_WRITECOM_FAILED); // an error occured so re-sync with DS2480 DS2480Detect(portnum); // reset the search LastDiscrepancy[portnum] = 0; LastDevice[portnum] = FALSE; LastFamilyDiscrepancy[portnum] = 0; return FALSE; }
//-------------------------------------------------------------------------- // Set the MicroLAN line level. The values for NewLevel are // as follows: // // 'NewLevel' - new level defined as // MODE_NORMAL 0x00 // MODE_STRONG5 0x02 // MODE_PROGRAM 0x04 // MODE_BREAK 0x08 (not supported) // // Returns: current MicroLAN level // int MLanLevel(int NewLevel) { uchar sendpacket[10],readbuffer[10]; short sendlen=0; short rt=FALSE; // check if need to change level if (NewLevel != ULevel) { // check if just putting back to normal if (NewLevel == MODE_NORMAL) { // check if correct mode if (UMode != MODSEL_COMMAND) { UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // stop pulse command sendpacket[sendlen++] = MODE_STOP_PULSE; // flush the buffers FlushCOM(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(1,readbuffer) == 1) { // check response byte if ((readbuffer[0] & 0xE0) == 0xE0) { rt = TRUE; ULevel = MODE_NORMAL; } } } } // set new level else { // check if correct mode if (UMode != MODSEL_COMMAND) { UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // strong 5 volts if (NewLevel == MODE_STRONG5) { // set the SPUD time value sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_5VPULSE | PARMSET_infinite; // add the command to begin the pulse sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V; } // 12 volts else if (NewLevel == MODE_PROGRAM) { // check if programming voltage available if (!ProgramAvailable) return MODE_NORMAL; // set the PPD time value sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_12VPULSE | PARMSET_infinite; // add the command to begin the pulse sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_12V; } // flush the buffers FlushCOM(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 1 byte response from setting time limit if (ReadCOM(1,readbuffer) == 1) { // check response byte if ((readbuffer[0] & 0x81) == 0) { ULevel = NewLevel; rt = TRUE; } } } } // if lost communication with DS2480 then reset if (rt != TRUE) DS2480Detect(); } // return the current level return ULevel; }
//-------------------------------------------------------------------------- // The 'OWSearch' function does a general search. This function // continues from the previos search state. The search state // can be reset by using the 'OWFirst' function. // This function contains one parameter 'alarm_only'. // When 'alarm_only' is TRUE (1) the find alarm command // 0xEC is sent instead of the normal search command 0xF0. // Using the find alarm command 0xEC will limit the search to only // 1-Wire devices that are in an 'alarm' state. // // Returns: TRUE (1) : when a 1-Wire device was found and it's // Serial Number placed in the global ROM // FALSE (0): when no new device was found. Either the // last search was the last device or there // are no devices on the 1-Wire Net. // int DallasOneWire::OWSearch(void) { DATA(F("OWSearch")); unsigned char last_zero,pos; unsigned char tmp_rom[8]; unsigned char readbuffer[20],sendpacket[40]; unsigned char i,sendlen=0; // if the last call was the last one if (LastDeviceFlag) { DATA(F("OWSearch: the last call was the last one")); // reset the search LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; return FALSE; } // reset the 1-wire // if there are no parts on 1-wire, return FALSE if (!OWReset()) { DEBUG(F("OWSearch: there are no parts on 1-wire, return FALSE")); // reset the search LastDiscrepancy = 0; LastFamilyDiscrepancy = 0; return FALSE; } // build the command stream // call a function that may add the change mode command to the buff // check for correct mode if (UMode != MODSEL_DATA) { DATA(F("OWSearch: UMode != MODSEL_DATA")); UMode = MODSEL_DATA; sendpacket[sendlen++] = MODE_DATA; } // search command sendpacket[sendlen++] = 0xF0; // change back to command mode UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; // search mode on sendpacket[sendlen++] = (unsigned char)(CMD_COMM | FUNCTSEL_SEARCHON | USpeed); // change back to data mode UMode = MODSEL_DATA; sendpacket[sendlen++] = MODE_DATA; // set the temp Last Discrepancy to 0 last_zero = 0; // add the 16 bytes of the search pos = sendlen; for (i = 0; i < 16; i++) sendpacket[sendlen++] = 0; // only modify bits if not the first search if (LastDiscrepancy != 0) { DATA(F("OWSearch: LastDiscrepancy != 0")); // set the bits in the added buffer for (i = 0; i < 64; i++) { // before last discrepancy if (i < (LastDiscrepancy - 1)) bitacc(WRITE_FUNCTION, bitacc(READ_FUNCTION,0,i,&ROM_NO[0]), (short)(i * 2 + 1), &sendpacket[pos]); // at last discrepancy else if (i == (LastDiscrepancy - 1)) bitacc(WRITE_FUNCTION,1,(short)(i * 2 + 1), &sendpacket[pos]); // after last discrepancy so leave zeros } } // change back to command mode UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; // search OFF command sendpacket[sendlen++] = (unsigned char)(CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed); // flush the buffers flush(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(17,readbuffer) == 17) { // interpret the bit stream for (i = 0; i < 64; i++) { // get the ROM bit bitacc(WRITE_FUNCTION, bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]),i, &tmp_rom[0]); // check LastDiscrepancy if ((bitacc(READ_FUNCTION,0,(short)(i * 2),&readbuffer[1]) == 1) && (bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]) == 0)) { last_zero = i + 1; // check LastFamilyDiscrepancy if (i < 8) LastFamilyDiscrepancy = i + 1; } } // do dowcrc crc8 = 0; for (i = 0; i < 8; i++) docrc8(tmp_rom[i]); // check results if ((crc8 != 0) || (LastDiscrepancy == 63) || (tmp_rom[0] == 0)) { // error during search // reset the search LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; return FALSE; } // successful search else { // set the last discrepancy LastDiscrepancy = last_zero; // check for last device if (LastDiscrepancy == 0) LastDeviceFlag = TRUE; // copy the ROM to the buffer for (i = 0; i < 8; i++) ROM_NO[i] = tmp_rom[i]; return TRUE; } } } WARNING(F("OWSearch: an error occured so re-sync with DS2480B")); // an error occured so re-sync with DS2480B DS2480B_Detect(); // reset the search LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; return FALSE; }
//-------------------------------------------------------------------------- // Set the 1-Wire Net communucation speed. // // 'new_speed' - new speed defined as // MODE_NORMAL 0x00 // MODE_OVERDRIVE 0x01 // // Returns: current 1-Wire Net speed // int DallasOneWire::OWSpeed(int new_speed) { DATA("OWSpeed"); unsigned char sendpacket[5]; unsigned char sendlen=0; unsigned char rt = FALSE; // check if change from current mode if (((new_speed == MODE_OVERDRIVE) && (USpeed != SPEEDSEL_OD)) || ((new_speed == MODE_NORMAL) && (USpeed != SPEEDSEL_FLEX))) { if (new_speed == MODE_OVERDRIVE) { // if overdrive then switch to 115200 baud if (DS2480B_ChangeBaud(MAX_BAUD) == MAX_BAUD) { USpeed = SPEEDSEL_OD; rt = TRUE; } } else if (new_speed == MODE_NORMAL) { // else normal so set to 9600 baud if (DS2480B_ChangeBaud(PARMSET_9600) == PARMSET_9600) { USpeed = SPEEDSEL_FLEX; rt = TRUE; } } // if baud rate is set correctly then change DS2480B speed if (rt) { // check for correct mode if (UMode != MODSEL_COMMAND) { UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // proceed to set the DS2480B communication speed sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed; // send the packet if (!WriteCOM(sendlen,sendpacket)) { rt = FALSE; WARNING(F("OWSpeed - lost communication with DS2480B then reset")); // lost communication with DS2480B then reset DS2480B_Detect(); } } } // return the current speed return (USpeed == SPEEDSEL_OD) ? MODE_OVERDRIVE : MODE_NORMAL; }
//-------------------------------------------------------------------------- // Set the 1-Wire Net line level. The values for new_level are // as follows: // // 'new_level' - new level defined as // MODE_NORMAL 0x00 // MODE_STRONG5 0x02 // // Returns: current 1-Wire Net level // int DallasOneWire::OWLevel(int new_level) { DATA("OWLevel"); DATA(new_level); unsigned char sendpacket[10],readbuffer[10]; unsigned char sendlen=0; unsigned char rt=FALSE;//,docheck=FALSE; // check if need to change level if (new_level != ULevel) { // check for correct mode if (UMode != MODSEL_COMMAND) { UMode = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // check if just putting back to normal if (new_level == MODE_NORMAL) { // // check for disable strong pullup step // if (ULevel == MODE_STRONG5) // docheck = TRUE; // stop pulse command sendpacket[sendlen++] = MODE_STOP_PULSE; // add the command to begin the pulse WITHOUT prime sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V | PRIME5V_FALSE; // stop pulse command sendpacket[sendlen++] = MODE_STOP_PULSE; // flush the buffers flush(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 1 byte response if (ReadCOM(2,readbuffer) == 2) { // check response byte if (((readbuffer[0] & 0xE0) == 0xE0) && ((readbuffer[1] & 0xE0) == 0xE0)) { rt = TRUE; ULevel = MODE_NORMAL; } else DEBUG(F("Read error")); } } } // set new level else { // set the SPUD time value sendpacket[sendlen++] = CMD_CONFIG | PARMSEL_5VPULSE | PARMSET_infinite; // add the command to begin the pulse sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_CHMOD | SPEEDSEL_PULSE | BITPOL_5V; // flush the buffers flush(); // send the packet if (WriteCOM(sendlen,sendpacket)) { // read back the 1 byte response from setting time limit if (ReadCOM(1,readbuffer) == 1) { // check response byte if ((readbuffer[0] & 0x81) == 0) { ULevel = new_level; rt = TRUE; } else DEBUG(F("Read error")); } } } // if lost communication with DS2480B then reset if (rt != TRUE) { WARNING(F("OWLevel - lost communication with DS2480B then reset")); DS2480B_Detect(); } } // return the current level return ULevel; }
//-------------------------------------------------------------------------- // Set the 1-Wire Net communucation speed. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the 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) { uchar sendpacket[5]; uchar sendlen=0; uchar rt = FALSE; // check if change from current mode if (((new_speed == MODE_OVERDRIVE) && (USpeed[portnum] != SPEEDSEL_OD)) || ((new_speed == MODE_NORMAL) && (USpeed[portnum] != SPEEDSEL_FLEX))) { if (new_speed == MODE_OVERDRIVE) { // if overdrive then switch to 115200 baud if (DS2480ChangeBaud(portnum,PARMSET_115200) == PARMSET_115200) { USpeed[portnum] = SPEEDSEL_OD; rt = TRUE; } } else if (new_speed == MODE_NORMAL) { // else normal so set to 9600 baud if (DS2480ChangeBaud(portnum,PARMSET_9600) == PARMSET_9600) { USpeed[portnum] = SPEEDSEL_FLEX; rt = TRUE; } } // if baud rate is set correctly then change DS2480 speed if (rt) { // check if correct mode if (UMode[portnum] != MODSEL_COMMAND) { UMode[portnum] = MODSEL_COMMAND; sendpacket[sendlen++] = MODE_COMMAND; } // proceed to set the DS2480 communication speed sendpacket[sendlen++] = CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed[portnum]; // send the packet if (!WriteCOM(portnum,sendlen,sendpacket)) { OWERROR(OWERROR_WRITECOM_FAILED); rt = FALSE; // lost communication with DS2480 then reset DS2480Detect(portnum); } } } // return the current speed return (USpeed[portnum] == SPEEDSEL_OD) ? MODE_OVERDRIVE : MODE_NORMAL; }