Čeština / English
Login

SVN Repository / Prohlížení

Aktuální adresář: FITkit / trunk / apps / communication / 1-wire_mcu / mcu /

one_wire.c

   1  /*******************************************************************************
   2     main: rozhrani one wire
   3     Copyright (C) 2009 Brno University of Technology,
   4                        Faculty of Information Technology
   5     Author(s): Karel Slany <slany AT fit.vutbr.cz>
   6  
   7     LICENSE TERMS
   8  
   9     Redistribution and use in source and binary forms, with or without
  10     modification, are permitted provided that the following conditions
  11     are met:
  12     1. Redistributions of source code must retain the above copyright
  13        notice, this list of conditions and the following disclaimer.
  14     2. Redistributions in binary form must reproduce the above copyright
  15        notice, this list of conditions and the following disclaimer in
  16        the documentation and/or other materials provided with the
  17        distribution.
  18     3. All advertising materials mentioning features or use of this software
  19        or firmware must display the following acknowledgement:
  20  
  21          This product includes software developed by the University of
  22          Technology, Faculty of Information Technology, Brno and its
  23          contributors.
  24  
  25     4. Neither the name of the Company nor the names of its contributors
  26        may be used to endorse or promote products derived from this
  27        software without specific prior written permission.
  28  
  29     This software or firmware is provided ``as is'', and any express or implied
  30     warranties, including, but not limited to, the implied warranties of
  31     merchantability and fitness for a particular purpose are disclaimed.
  32     In no event shall the company or contributors be liable for any
  33     direct, indirect, incidental, special, exemplary, or consequential
  34     damages (including, but not limited to, procurement of substitute
  35     goods or services; loss of use, data, or profits; or business
  36     interruption) however caused and on any theory of liability, whether
  37     in contract, strict liability, or tort (including negligence or
  38     otherwise) arising in any way out of the use of this software, even
  39     if advised of the possibility of such damage.
  40  
  41     $Id$
  42  
  43  
  44  *******************************************************************************/
  45  
  46  /*
  47   * Note:
  48   *
  49   * The source code is based o the source codes released in the following
  50   * application notes related to the DS18B20 digital thermometer device.
  51   *
  52   * AN126 - 1-Wire Communication Through Software
  53   * http://www.maxim-ic.com/app-notes/index.mvp/id/126
  54   * http://pdfserv.maxim-ic.com/en/an/AN126.pdf
  55   *
  56   * AN187 - 1-Wire Search Algorithm
  57   * http://www.maxim-ic.com/app-notes/index.mvp/id/187
  58   * http://pdfserv.maxim-ic.com/en/an/AN187.pdf
  59   *
  60   */
  61  
  62  
  63  #include <fitkitlib.h>
  64  
  65  #include "one_wire.h"
  66  
  67  
  68  /*******************************************************************************
  69   * 1-wire global wariables
  70  *******************************************************************************/
  71  unsigned char ROM[ROM_BYTES];                      // ROM bits
  72  unsigned char last_discrep = 0;                    // last discrepancy
  73  unsigned char done_flag = 0;                       // done flag
  74  unsigned char found_ROMs[MAX_DEVICES][ROM_BYTES];  // table of found ROM codes
  75  unsigned char num_ROMs;
  76  unsigned char dowcrc;
  77  unsigned char dscrc_table[] = {
  78      0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
  79    157,195, 33,127,252,162, 64, 30, 95,  1,227,189, 62, 96,130,220,
  80     35,125,159,193, 66, 28,254,160,225,191, 93,  3,128,222, 60, 98,
  81    190,224,  2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
  82     70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89,  7,
  83    219,133,103, 57,186,228,  6, 88, 25, 71,165,251,120, 38,196,154,
  84    101, 59,217,135,  4, 90,184,230,167,249, 27, 69,198,152,122, 36,
  85    248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91,  5,231,185,
  86    140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
  87     17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
  88    175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
  89     50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
  90    202,148,118, 40,171,245, 23, 73,  8, 86,180,234,105, 55,213,139,
  91     87,  9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
  92    233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
  93    116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
  94  
  95  
  96  /*******************************************************************************
  97   * TimerB delay function, behaviour defined by timerb_init() - period 0.5425us
  98  *******************************************************************************/
  99  void delay_1us083(unsigned long us)
 100  {
 101  #if defined MSP_16X
 102  #elif defined MSP_261X
 103    TBCCR1 = (us << 1) + TBR;
 104    while (TBR != TBCCR1) {}
 105  #else
 106    #error "Unknown CPU type"
 107  #endif
 108  
 109  }
 110  
 111  
 112  /*******************************************************************************
 113   * 1-wire bus reset
 114  *******************************************************************************/
 115  unsigned char ow_reset(void)
 116  {
 117  	unsigned long presence;    // 0 - presence, 1 - no part
 118  
 119  	DQ_dir_out();              // set output
 120  	DQ_set_0();                // and set it to 0
 121  	delay_500us();
 122  	DQ_dir_in(); 	             // set input
 123  	delay_60us();
 124  
 125    presence = DQ_read();
 126  
 127  	delay_420us();
 128  
 129    return presence;
 130  }
 131  
 132  
 133  /*******************************************************************************
 134   * read one bit
 135  *******************************************************************************/
 136  unsigned char ow_read_bit(void)
 137  {
 138    unsigned char bit;
 139  
 140    delay_7us();
 141  
 142    DQ_dir_out();           // out
 143    DQ_set_0();             // 0
 144    delay_7us();
 145    DQ_dir_in();            // in
 146    delay_7us();
 147  
 148    bit = DQ_read();        // read bus
 149  
 150    delay_80us();
 151  
 152    return(bit);
 153  }
 154  
 155  
 156  /*******************************************************************************
 157   * write one bit
 158  *******************************************************************************/
 159  void ow_write_bit(unsigned char bit)
 160  {
 161    DQ_dir_out();     // out
 162    DQ_set_0();       // 0
 163    delay_7us();
 164  
 165    if (bit)
 166      DQ_set_1();     // 1
 167    else
 168      DQ_set_0();     // 0
 169    delay_80us();
 170  
 171    DQ_dir_in();
 172    delay_7us();
 173  }
 174  
 175  
 176  /*******************************************************************************
 177   * read one byte
 178  *******************************************************************************/
 179  unsigned char ow_read_byte(void)
 180  {
 181    unsigned char i;
 182    unsigned char byte = 0;
 183  
 184    for (i = 0; i < 8; i++)
 185    {
 186      if (ow_read_bit())
 187        byte |= 0x01 << i;
 188    }
 189  
 190    return byte;
 191  }
 192  
 193  
 194  /*******************************************************************************
 195   * write one byte
 196  *******************************************************************************/
 197  void ow_write_byte(unsigned char byte)
 198  {
 199    unsigned char i;
 200  
 201    for (i = 0; i < 8; i++)
 202    {
 203      ow_write_bit((byte >> i) & 0x01);
 204    }
 205  }
 206  
 207  
 208  /*******************************************************************************
 209   * 1-wire crc
 210  *******************************************************************************/
 211  unsigned char ow_crc(unsigned char x)
 212  {
 213    dowcrc = dscrc_table[dowcrc^x];
 214    return dowcrc;
 215  }
 216  
 217  
 218  /*******************************************************************************
 219   * next
 220   * The function searches for the next device on the 1-wire bus. If
 221   * there are no more devices on the 1-wire then false is returned.
 222  *******************************************************************************/
 223  unsigned char next(void)
 224  {
 225    unsigned char bit_i = 1;          // ROM bit index
 226    unsigned char byte_i = 0;         // ROM byte index
 227    unsigned char bit_mask = 1;       // bit mask
 228    unsigned char x = 0;
 229    unsigned char discrep_marker = 0; // discrepancy marker
 230    unsigned char out_bit;            // output bit
 231    unsigned char nxt;                // return value
 232    int flag;
 233  
 234    nxt = FALSE;                      // set the next flag to false
 235    dowcrc = 0;                       // reset the dowcrc
 236    flag = ow_reset();                // reset the 1-wire
 237  
 238    if (flag || done_flag)            // no parts -> return false
 239    {
 240      last_discrep = 0;               // reset the search
 241      return FALSE;
 242    }
 243  
 244    ow_write_byte(0xF0);                       // send search ROM command
 245    do                                         // for all eight bytes
 246    {
 247      x = 0;
 248      if (ow_read_bit())
 249        x = 0x02;
 250      if (ow_read_bit())
 251        x |= 0x01;                             // and its complement
 252      if (x == 0x03)                           // there are no devices on the 1-wire
 253        break;
 254      else
 255      {
 256        if(x > 0)                              // all devices coupled have 0 or 1
 257          out_bit = x >> 1;                    // bit write value for search
 258        else
 259        {
 260                                               // if this discrepancy is before the last
 261                                               // discrepancy on a previous next call then pick
 262                                               // the same as last time
 263          if (bit_i < last_discrep)
 264            out_bit = ((ROM[byte_i] & bit_mask) > 0);
 265          else                                 // if equal to last pick 1
 266            out_bit = (bit_i == last_discrep); // if not then pick 0
 267                                               // if 0 was picked then record
 268                                               // position with mask bit_mask
 269          if (out_bit == 0)
 270            discrep_marker = bit_i;
 271        }
 272        if (out_bit == 1)                      // isolate bit in ROM[byte_i] with mask bit_mask
 273          ROM[byte_i] |= bit_mask;
 274        else
 275          ROM[byte_i] &= ~bit_mask;
 276        ow_write_bit(out_bit);                 // ROM search write
 277        bit_i++;                               // increment bit counter bit_i
 278        bit_mask = bit_mask << 1;              // and shift the bit mask bit_mask
 279        if (bit_mask == 0)                     // if the mask is 0 then go to new ROM
 280        {                                      // byte byte_i and reset mask
 281          ow_crc(ROM[byte_i]);                 // accumulate the CRC
 282          byte_i++; bit_mask++;
 283        }
 284      }
 285    } while (byte_i < ROM_BYTES);              // loop until through all ROM bytes 0-7
 286  
 287    if (bit_i < 65 || dowcrc)                  // if search was unsuccessful then
 288      last_discrep = 0;                        // reset the last discrepancy to 0
 289    else
 290    {
 291                                               // search was successful, so set last_discrep,
 292                                               // done_flag, nxt
 293      last_discrep = discrep_marker;
 294      done_flag = (last_discrep == 0);
 295      nxt = TRUE;                              // indicates search is not complete yet, more
 296                                               // parts remain
 297    }
 298  
 299    return nxt;
 300  
 301  }
 302  
 303  
 304  /*******************************************************************************
 305   * first
 306   * The function resets the current state of a ROM search and calls
 307   * function next to find the first device on the 1-wire bus.
 308  *******************************************************************************/
 309  unsigned char first(void)
 310  {
 311    last_discrep = 0;                          // reset the ROM search last discrepancy global
 312    done_flag = FALSE;
 313    return next();                             // call next and return its return value
 314  }
 315  
 316  
 317  /*******************************************************************************
 318   * searches for devices connected to the 1-wire
 319  *******************************************************************************/
 320  void ow_find_devices(void)
 321  {
 322    unsigned char m;
 323  
 324    if (!ow_reset())                                  // begins when a presence is detected
 325    {
 326      if (first())                                    // begins when at least one part is found
 327      {
 328        num_ROMs = 0;
 329        do
 330        {
 331          //num_ROMs++;
 332          for (m = 0; m < ROM_BYTES; m++)
 333          {
 334            found_ROMs[num_ROMs][m] = ROM[m];         // identifies ROM
 335                                                      // number on found device
 336          }
 337          num_ROMs++;
 338        } while (next() && (num_ROMs < MAX_DEVICES)); // continues until no additional devices are found
 339      }
 340    }
 341  
 342  }
 343  
 344  
 345  /*******************************************************************************
 346   * perform match ROM
 347  *******************************************************************************/
 348  unsigned char ow_send_match_rom(unsigned char idx)
 349  {
 350    unsigned char i;
 351    if (ow_reset())
 352      return FALSE;
 353    ow_write_byte(0x55);                      // match ROM
 354    for (i = 0; i < ROM_BYTES; i++)
 355    {
 356      ow_write_byte(found_ROMs[idx][i]);      // send ROM code
 357    }
 358    return TRUE;
 359  
 360  }
 361  
Zobrazeno: 597159x Naposledy: 27.1.2022 15:50:23