1

Dependents:   final

OneWire_Functions.cpp

Committer:
ChesterLin
Date:
2017-11-27
Revision:
0:3e574710804f

File content as of revision 0:3e574710804f:

#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;
}