1
Diff: OneWire_Functions.cpp
- Revision:
- 0:3e574710804f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OneWire_Functions.cpp Mon Nov 27 06:05:15 2017 +0000 @@ -0,0 +1,724 @@ +#include "OneWire_Functions.h" + +Serial pc2(USBTX,USBRX); + +OneWire::OneWire (PinName wire): _pin(wire) +{ + + //default alram temperture + sca[2]=0x50; //+80 'C + sca[1]=0xec; //-25 'C + + + //default resolution + sca[0]=Twebitresolution; + + reso = Twebitresolution; +} + +//initialization 1-wire devices +int OneWire::init() +{ + int result; //define a value for read presence pulse + + _pin.output(); //set pin as output + _pin = 0; //pull the bus low + wait_us(480); //minimum rest pulse is 480 µs + + _pin.input();//set pin as input, bus pull up by pullup resistor + wait_us(70); //wait for slave response + result = _pin.read(); //read presence pulse + wait_us(410); + + return result; //return the presence pulse. 0->TURE. 1->FALSE +} + +//write a bite +void OneWire::write_bit(uint8_t data) +{ + data = data & 0x01; //only transmit LSB + + if (data) { + //Write '1' + wait_us(1); + _pin.output(); //set pin as output + _pin = 0; //pull the bus low + wait_us(10); //write '1' need pull up within 15µs + _pin.input();//set pin as input, bus pull up by pullup resistor + wait_us(60); //rest duration time + recovery time + + } else { + //Write '0' + wait_us(1); + _pin.output();//set pin as output + _pin = 0; //pull the bus low + wait_us(60); //rest duration time + _pin.input();//set pin as input, bus pull up by pullup resistor + wait_us(10); //recovery time + } +} + +//read a bite +int OneWire::read_bit() +{ + int result; //define a value for read result + + wait_us(1); + _pin.output(); //set pin as output + _pin = 0; //pull the bus low + wait_us(5); + + _pin.input(); + wait_us(10); + result = _pin; //sample the bus + wait_us(65); //rest duration time + recovery time + + return result; +} + +//write a byte +void OneWire::write_byte(uint8_t data) +{ + int loop; + + for(loop = 0; loop < 8; loop++) { + + write_bit(data & 0x01); + + data = (data >> 1); + + } +} + +//read a byte +int OneWire::read_byte() +{ + int result,loop; + + for(loop = 0; loop < 8; loop++) { + + result = (result >> 1); + + if (read_bit()) { + + result |= 0x80; + + } + } + + return result; +} + +//get tempreture from a device +char * OneWire::init_Match_Get_Temp(char addr[8]) +{ + int loop,i=0; + char sc[2]; + + init(); + + write_byte(0x55); + + for (loop = 0; loop < 8; loop++) { + + write_byte(addr[i]); + + i++; + + } + + write_byte(0xbe); + + i=0; + + for (loop = 0; loop < 2; loop++) { + + sc[i]=read_byte(); + + i++; + + } + + return sc; +} + +//get scratchpad from a device +//char* OneWire::init_Match_Read_Scratchpad(char addr[8]) +//{ + +//int loop, i = 0; +//char sc[9]; + +//init(); + +//write_byte(0x55); + +// for(loop = 0; loop<8; loop++) { + +//write_byte(addr[i]); +//i++; + +//} + +//i=0; + +//write_byte(0xbe); + +//for(loop = 0; loop < 9; loop++) { + +//sc[i] = read_byte(); + +//i++; + +//} + +//return sc; + +//} + +//write Th, Tl and configuration register to a device +void OneWire::init_Match_Write_Scratchpad(char addr[8],char Scratchpad[3]) +{ + int loop,i=0; + + + + init(); + + write_byte(0x55); + + for(loop = 0; loop<8; loop++) { + + write_byte(addr[i]); + i++; + + } + + write_byte(0x4e); + + write_byte(Scratchpad[2]);//write Th + write_byte(Scratchpad[1]);//write Tl + write_byte(Scratchpad[0]);//write resolution + +} + + +//all device on the bus convert t +int OneWire::Skip_Convert_T() +{ + + int relt = init(); + + if (!relt) { + write_byte(0xcc); + + write_byte(0x44); + + wait_us(1000); + + return TRUE; + } else { + return FALSE; + } + + +} + + +//search any alarm on bus, if ture, send email +int OneWire::Read_alarm_Email() +{ + + Skip_Convert_T(); //all device convert temperature + int rslt = OWSearch_alarm(); //find first device + + if (rslt) { //find one device have alarm. send email + + pc2.printf("Sending Email...\n\r"); + //get time first + ntp.setTime("pool.ntp.org"); + time_t ctTime = time(NULL); + + //send email + smtp.setFromAddress(FROM_ADDRESS); + smtp.setToAddress(TO_ADDRESS); + char msg[]= "One of 1-wire device is burning."; + smtp.setMessage(SUBJECT,msg); + smtp.sendmail(SERVER, USER, PWD, DOMAIN,PORT,SMTP_AUTH_PLAIN); + return TRUE; + } + return FALSE; +} + +//read all devices temperature on the bus +int OneWire::Read_Temp_On_bus() +{ + char temp[2]; + int i=OneWireTempReg-1; + int rslt = Skip_Convert_T(); //all device convert temperature + if (rslt) { + OWFirst();//find first device + strcpy(temp,init_Match_Get_Temp(ROM_NO)); //read temp from that sensor + alltemp[i]=temp[1]; + alltemp[i-1]=temp[0]; + rslt = OWNext(); //strat search next 1-wire device + while(rslt) { + i=i-2; + strcpy(temp, init_Match_Get_Temp( ROM_NO)); //read temp from that sensor + alltemp[i]=temp[1]; + alltemp[i-1]=temp[0]; + rslt = OWNext(); //strat search next 1-wire device + } + return TRUE; + } else { + return FALSE; + } +} + +//set resolution to all 1-wire device +void OneWire::Change_Res() +{ + int rslt = OWFirst(); //search first device on bus + + if (rslt) { //found first device + + init_Match_Write_Scratchpad(ROM_NO, sca); //change resolution or alarm temperature + + rslt = OWNext(); //find next device + + while(rslt) { //found next device + + init_Match_Write_Scratchpad(ROM_NO, sca); //change resolution or alarm temperature + + rslt = OWNext(); //find next device + + } + } +} + +//read the address when there is only one slave on the bus +//char* OneWire::init_Read_ROM() +//{ +//char addr[8]; + +//int loop,i; + +//i=0; + +//init(); + +//write_byte(0x33); + +//for ( loop = 0; loop < 8; loop++) { + +//addr[i] = read_byte(); + +//i++; + +//} + +//return addr; +//} + +//read temperature when there is only one slave on the bus +//char* OneWire::init_Skip_Get_Temp() +//{ +//int loop, i; +//char temp[2]; + +//i = 0; + +//init(); + +//write_byte(0xcc); + +//write_byte(0x44); + +//wait_us(1000); + +//init(); + +//write_byte(0xcc); + +//write_byte(0xbe); + +//for(loop = 0; loop < 2;loop++){ + +//temp[i] = read_byte(); + +//i++; + +//} + +//return temp; +//} + +//int OneWire::init_Skip_Read_Scratchpad() +//{ +//} + +//void OneWire::init_Skip_Write_Scratchpad(char Scratchpad[7]) +//{ +//} + +// Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing +// search state. +// Return TRUE : device found, ROM number in ROM_NO buffer +// FALSE : device not found, end of search +// +int OneWire::OWSearch() +{ + int id_bit_number; + int last_zero, rom_byte_number, search_result; + int id_bit, cmp_id_bit; + unsigned char rom_byte_mask, search_direction; + + // initialize for search + id_bit_number = 1; + last_zero = 0; + rom_byte_number = 0; + rom_byte_mask = 1; + search_result = 0; + crc8 = 0; + + // if the last call was not the last one + if (!LastDeviceFlag) { + // 1-Wire reset + if (init()) { + // reset the search + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + return FALSE; + } + + // issue the search command + write_byte(0xF0); + + // loop to do the search + do { + // read a bit and its complement + id_bit = read_bit(); + cmp_id_bit = read_bit(); + + // check for no devices on 1-wire + if ((id_bit == 1) && (cmp_id_bit == 1)) + break; + else { + // all devices coupled have 0 or 1 + if (id_bit != cmp_id_bit) + search_direction = id_bit; // bit write value for search + else { + // if this discrepancy if before the Last Discrepancy + // on a previous next then pick the same as last time + if (id_bit_number < LastDiscrepancy) + search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); + else + // if equal to last pick 1, if not then pick 0 + search_direction = (id_bit_number == LastDiscrepancy); + + // if 0 was picked then record its position in LastZero + if (search_direction == 0) { + last_zero = id_bit_number; + + // check for Last discrepancy in family + if (last_zero < 9) + LastFamilyDiscrepancy = last_zero; + } + } + + // set or clear the bit in the ROM byte rom_byte_number + // with mask rom_byte_mask + if (search_direction == 1) + ROM_NO[rom_byte_number] |= rom_byte_mask; + else + ROM_NO[rom_byte_number] &= ~rom_byte_mask; + + // serial number search direction write bit + write_bit(search_direction); + + // increment the byte counter id_bit_number + // and shift the mask rom_byte_mask + id_bit_number++; + rom_byte_mask <<= 1; + + // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask + if (rom_byte_mask == 0) { + docrc8(ROM_NO[rom_byte_number]); // accumulate the CRC + rom_byte_number++; + rom_byte_mask = 1; + } + } + } while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 + + // if the search was successful then + if (!((id_bit_number < 65) || (crc8 != 0))) { + // search successful so set LastDiscrepancy,LastDeviceFlag,search_result + LastDiscrepancy = last_zero; + + // check for last device + if (LastDiscrepancy == 0) + LastDeviceFlag = TRUE; + + search_result = TRUE; + } + } + + // if no device found then reset counters so next 'search' will be like a first + if (!search_result || !ROM_NO[0]) { + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + search_result = FALSE; + } + + return search_result; +} + + +// Perform the 1-Wire Search alarm Algorithm on the 1-Wire bus using the existing +// search state. +// Return TRUE : device found, ROM number in ROM_NO buffer +// FALSE : device not found, end of search +// +int OneWire::OWSearch_alarm() +{ + int id_bit_number; + int last_zero, rom_byte_number, search_result; + int id_bit, cmp_id_bit; + unsigned char rom_byte_mask, search_direction; + + // initialize for search + id_bit_number = 1; + last_zero = 0; + rom_byte_number = 0; + rom_byte_mask = 1; + search_result = 0; + crc8 = 0; + + // if the last call was not the last one + if (!LastDeviceFlag) { + // 1-Wire reset + if (init()) { + // reset the search + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + return FALSE; + } + + // issue the search alarm command + write_byte(0xEC); + + // loop to do the search + do { + // read a bit and its complement + id_bit = read_bit(); + cmp_id_bit = read_bit(); + + // check for no devices on 1-wire + if ((id_bit == 1) && (cmp_id_bit == 1)) + break; + else { + // all devices coupled have 0 or 1 + if (id_bit != cmp_id_bit) + search_direction = id_bit; // bit write value for search + else { + // if this discrepancy if before the Last Discrepancy + // on a previous next then pick the same as last time + if (id_bit_number < LastDiscrepancy) + search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); + else + // if equal to last pick 1, if not then pick 0 + search_direction = (id_bit_number == LastDiscrepancy); + + // if 0 was picked then record its position in LastZero + if (search_direction == 0) { + last_zero = id_bit_number; + + // check for Last discrepancy in family + if (last_zero < 9) + LastFamilyDiscrepancy = last_zero; + } + } + + // set or clear the bit in the ROM byte rom_byte_number + // with mask rom_byte_mask + if (search_direction == 1) + ROM_NO[rom_byte_number] |= rom_byte_mask; + else + ROM_NO[rom_byte_number] &= ~rom_byte_mask; + + // serial number search direction write bit + write_bit(search_direction); + + // increment the byte counter id_bit_number + // and shift the mask rom_byte_mask + id_bit_number++; + rom_byte_mask <<= 1; + + // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask + if (rom_byte_mask == 0) { + docrc8(ROM_NO[rom_byte_number]); // accumulate the CRC + rom_byte_number++; + rom_byte_mask = 1; + } + } + } while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 + + // if the search was successful then + if (!((id_bit_number < 65) || (crc8 != 0))) { + // search successful so set LastDiscrepancy,LastDeviceFlag,search_result + LastDiscrepancy = last_zero; + + // check for last device + if (LastDiscrepancy == 0) + LastDeviceFlag = TRUE; + + search_result = TRUE; + } + } + + // if no device found then reset counters so next 'search' will be like a first + if (!search_result || !ROM_NO[0]) { + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + search_result = FALSE; + } + + return search_result; +} + + +//-------------------------------------------------------------------------- +// Verify the device with the ROM number in ROM_NO buffer is present. +// Return TRUE : device verified present +// FALSE : device not present +// +int OneWire::OWVerify() +{ + unsigned char rom_backup[8]; + int i,rslt,ld_backup,ldf_backup,lfd_backup; + + // keep a backup copy of the current state + for (i = 0; i < 8; i++) + rom_backup[i] = ROM_NO[i]; + ld_backup = LastDiscrepancy; + ldf_backup = LastDeviceFlag; + lfd_backup = LastFamilyDiscrepancy; + + // set search to find the same device + LastDiscrepancy = 64; + LastDeviceFlag = FALSE; + + if (OWSearch()) { + // check if same device found + rslt = TRUE; + for (i = 0; i < 8; i++) { + if (rom_backup[i] != ROM_NO[i]) { + rslt = FALSE; + break; + } + } + } else + rslt = FALSE; + + // restore the search state + for (i = 0; i < 8; i++) + ROM_NO[i] = rom_backup[i]; + LastDiscrepancy = ld_backup; + LastDeviceFlag = ldf_backup; + LastFamilyDiscrepancy = lfd_backup; + + // return the result of the verify + return rslt; +} + +// Setup the search to find the device type 'family_code' on the next call +// to OWNext() if it is present. +// +void OneWire::OWTargetSetup(unsigned char family_code) +{ + int i; + + // set the search state to find SearchFamily type devices + ROM_NO[0] = family_code; + for (i = 1; i < 8; i++) + ROM_NO[i] = 0; + LastDiscrepancy = 64; + LastFamilyDiscrepancy = 0; + LastDeviceFlag = FALSE; +} + +// Setup the search to skip the current device type on the next call +// to OWNext(). +// +void OneWire::OWFamilySkipSetup() +{ + // set the Last discrepancy to last family discrepancy + LastDiscrepancy = LastFamilyDiscrepancy; + LastFamilyDiscrepancy = 0; + + // check for end of list + if (LastDiscrepancy == 0) + LastDeviceFlag = TRUE; +} + +// Find the 'first' devices on the 1-Wire bus +// Return TRUE : device found, ROM number in ROM_NO buffer +// FALSE : no device present +// +int OneWire::OWFirst() +{ + // reset the search state + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + + return OWSearch(); +} + +// Find the 'next' devices on the 1-Wire bus +// Return TRUE : device found, ROM number in ROM_NO buffer +// FALSE : device not found, end of search +// +int OneWire::OWNext() +{ + // leave the search state alone + return OWSearch(); +} + +// TEST BUILD +const unsigned char dscrc_table[256] = { + 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, + 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, + 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, + 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, + 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, + 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, + 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, + 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, + 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, + 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, + 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, + 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, + 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, + 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, + 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, + 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53 +}; + +//-------------------------------------------------------------------------- +// Calculate the CRC8 of the byte value provided with the current +// global 'crc8' value. +// Returns current global crc8 value +// +unsigned char OneWire::docrc8(unsigned char value) +{ + // See Application Note 27 + + // TEST BUILD + crc8 = dscrc_table[crc8 ^ value]; + return crc8; +}