Library to interface with 1-wire through the DS2480B

Dependents:   DS2480B_1_Wire_Master

DS2480B.cpp

Committer:
giorgos2405
Date:
2016-08-29
Revision:
0:07f0cd3758fa

File content as of revision 0:07f0cd3758fa:

#include "mbed.h"
#include "DS2480B.h" 

#define Reset           0xC1
#define Pullup          0x3B
#define DataMode        0xE1
#define CommandMode     0xE3
#define ConvertT        0x44
#define PullupArm       0xEF
#define PullupDisarm    0xED
#define PulseTerminate  0xF1
#define PullupDisarm    0xED
#define ReadScratchpad  0xBE
#define SkipROM         0xCC
#define MatchROM        0x55

Serial serial(p9, p10);

int DS1920[8] = {0x10, 0x7A, 0xA8, 0x92, 0x02, 0x08, 0x00, 0x7E};

void DS2480B::mreset(void){
    serial.send_break();
    serial.putc(0xC1);
}

int DS2480B::reset(void)
{
    serial.putc(0xC1);
    result = serial.getc();
//    printf("reset = %X \n \r", result);  DEBUGGING

    if(result == 0xCD){
        return 1;
    }
    else{
        mreset();
        return 0;
    }
}

//for commands that the ds2480b returns nothing over the UART
void DS2480B::Mode(int command)
{
    serial.putc(command);
}

//for commands that the ds2480b returns a character over the UART
int DS2480B::Command(int command)
{
    serial.putc(command);
    result = serial.getc();
//    printf("sent = %X\t received = %X \n \r", command, result);  DEBUGGING
    
    return result;
}


//Search Accelerator algorithm
void DS2480B::Search(int searchmode) //search ROM or Alarm Search command
{
    hdb = 0; //reset highest discrepancy bit found
    last_hdb = 0; //last discrepancy bit
    
    index = 0; //index of array for saving device's addresses 
     
    
    //clear array where current devices are being stored
    int b = sizeof(romstorage)/ sizeof(uint64_t);
    for(int i=0; i<b; i++){
        romstorage[i] = 0;
    }
    
   
    //Reset pulse
    if(reset()){
    

        //set data mode
        Mode(0xE1);
            
        //search rom/alert search
        Command(searchmode);
            
        //set mode command
        Mode(0xE3);
        
        //search accelerator on
        Mode(0xB1);
    
        //set data mode
        Mode(0xE1);
    
        //First search data
        for(int i=0; i<16; i++){
            serial.putc(0x00);
        }
        
        //read found ROM code 
        for(int i=0; i<16; i++){
            ROM[i] = serial.getc();
        }
        
        //command mode
        Mode(0xE3);
        
        //search accelerator off
        Mode(0xA1);
    
        reset();
        getROM();
    }
    
    while(1)
    {
        bool flag(false); //flag to break nested loops
        bool last(false); //flag signifying last device found
        
        for(int i=15; i>-1; i--) //Run through obtained ROM bytes
        {
            last_hdb = hdb; 
                        
            mask = 0x40; // mask for bits detection
            
            //run discrepancy bits ( 1st, 3rd, 5th, 7th in byte)
            for(int j=7; j>0; j=j-2) 
            {   
                if((mask & ROM[i]) != 0) //check for discrepancy
                {   
                    mask = mask << 1; // move from discrepancy to pattern bits
                    ROM[i] = (ROM[i] | mask); //set pattern
                    mask = 0xFF >> (7-j);
                    ROM[i] = ROM[i] & mask;
                    
                    hdb = (((i) * j)+j); 
                    if(hdb == last_hdb){
                        flag = true;
                        last = true;
                        break;
                    }
                    
// DEBUGGING        printf("discrepancy flag at byte %d, bit %d\n\r", i, j);
                    
                    int dbyte = i;
                    for(int k=dbyte+1; i<16; i++){
                        ROM[k] = 0;
                    }
 
                    flag = true;
                    break;
                }
                if(flag == true)
                {
                    break;
                }
                mask = mask >> 2;
            }
            
            if(flag == true)
            {
                break;
            }
        }
        
        if(flag == false)
        {
            break;
        }
        
        if (last == true)
        {   
            break;
        }
        
        //Reset pulse
        if(reset()){
            
            //set data mode
            Mode(0xE1);
                
            //search rom
            Command(0xF0);
                
            //set mode command
            Mode(0xE3);
            
            //search accelerator on
            Mode(0xB1);
        
            //set data mode
            Mode(0xE1);
          
//          insert previous rom code with search path set
            for(int i=0; i<16; i++){
                serial.putc(ROM[i]);
            }
            
            for(int i=0; i<16; i++){
                ROM[i] = serial.getc();
    //            printf("rom %X \t", ROM[i]); Debugging
            }            
            
            //command mode
            Mode(0xE3);
    
            //search accelerator off
            Mode(0xA1);
        
            //Reset
            reset();
            getROM();
        }        
    }
}

// code to compile the bytes of the rom address and determine the type of device connected
void DS2480B::getROM(void)
{
    rom = 0;
    for(int i=14; i>-1; i=i-2){
    byte = 0; //variable to store the byte value  
    mask = 2;
    
        //use the mask to get the LS nibble
        for(int j=1; j<5; j=j++){
            temp = mask & ROM[i];
            temp = temp >> j;
            byte = byte + temp;
            mask = mask << 2;
        }
        
    mask = 2;
        
        //use the mask to get the MS nibble
        for(int j=3; j>-1; j=j--){
            temp = mask & ROM[i+1];
            temp = temp << j;
            byte = byte + temp;
            mask = mask << 2;
        }
        
        rom = ((rom >> i * 4) + byte) << i * 4;    

//        printf("byte = %X \t", byte); DEBUGGING
          

    romstorage[index] = rom;

//    printf("rom address = %llX\n", romstorage[index]);  DEBUGGING
    index++;
}
}
            
//**************************************************DS1920*******************************************\\            

float DS2480B::AcquireTemp(uint64_t address){   
    if(reset()){    
        //set data mode
        Mode(DataMode);
                
        //MatchRom
        Command(MatchROM);
            
        for(int i=0; i<8; i++){
            //use mask to send rom byte-by-byte lsb first.
            Command((address >> (i*8)) & 0xFF); 
        }
        
            
        //Read scratchpad
        Command(ReadScratchpad);        
                
        for(int i=0; i<9; i++){
            serial.putc(0xFF);
            scratchpad[i] = serial.getc();
        }
            
        temperature = scratchpad[0]/2;
            
        if(scratchpad[1] == 0xFF)
        {
            temperature = temperature * -1;
        }
        
//        printf("temperature = %f \n", temperature);   DEBUGGING
                
        //set mode command
        Mode(CommandMode);
        reset();
    }
    return temperature;
}

void DS2480B::ConvertTemp(void){
    //set strong pullup duration
    Command(Pullup);
        
    //Reset pulse
    if(reset()){
                
        //set data mode
        Mode(DataMode);
            
        //skip rom
        Command(SkipROM);
            
        //set mode command
        Mode(CommandMode);
            
        //arm strong pullup
        Mode(PullupArm);
            
        //terminate pulse
        Command(PulseTerminate);
               
        //set data mode
        Mode(DataMode);
        
        //convert Temp
        Command(ConvertT);
               
        serial.getc();
                
        //set mode command
        Mode(CommandMode);
        
        //disarm strong pullup
        Mode(PullupDisarm);
            
        //terminate pulse
        Command(PulseTerminate); // to clear rx buffer of lpc1768
        reset();
    }
}

int DS2480B::Checkdevices(void){
    int devices; // determine number of devices connected to the master
    int type;
    ds1920no = 0; //number of temperature sensors
    ds1920first = 0;//position of 1st ds1920 in array
    ds1990no = 0; //number of ID tags
    ds1990first = 0; //position of 1st ds1990 in array
    for(int i=0; i<2000; i++){
        devices = devices++;
        type = romstorage[i] & 0xFF; //check family byte

        //count ds1920 devices
        if(type == 0x10){
            if(ds1920no == 0){
                ds1920first = i;
            }
            ds1920no = ds1920no + 1;
        }
        
        if(type == 0x01){
            if(ds1990no == 0){
                ds1990first = i;
            }
            ds1920no = ds1920no + 1;
        }        
    }
    return devices;
}