onewire 1-wire ds18x20 ds2450 multi-channel

Dependents:   ibutton

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers onewire.cpp Source File

onewire.cpp

00001 /**
00002 * @file onewire.c
00003 * @brief library 1-Wire(www.maxim-ic.com)
00004 * @author Maciej Rajtar (Published 10 May 2010 www.mbed.org)
00005 * @author Frederic BLANC (Published 01/03/2012 www.mbed.org)
00006 */
00007 
00008 #include "mbed.h"
00009 #include "onewire.h"
00010 
00011 DigitalInOut ow_pin(p21);
00012 DigitalInOut ow_0(p21);
00013 DigitalInOut ow_1(p22);
00014 DigitalInOut ow_2(p23);
00015 DigitalInOut ow_3(p24);
00016 DigitalInOut* t_ow[4]={&ow_0,&ow_1,&ow_2,&ow_3}; 
00017 //**********************************************************************************************************
00018 //*                                  show_id
00019 //**********************************************************************************************************
00020   
00021 
00022 /**
00023 *     @brief show_id
00024 *    @param  [in] id[] = rom_code
00025 *    @return  [out] text id
00026 *     @date 20/06/2011
00027 */
00028 string ow_show_id( uint8_t id[]) {
00029 
00030     char hex[4];
00031     string  text ("");
00032     sprintf(hex,"%2.2X",id[0]);
00033         text+=hex;    
00034     for (int i = OW_ROMCODE_SIZE-2; i >=1 ; --i ) {
00035         sprintf(hex,"%2.2X",id[i]);
00036         text+=hex;       
00037     }
00038     sprintf(hex,"%2.2X",id[OW_ROMCODE_SIZE-1]);
00039         text+=hex;  
00040     return text;
00041 }
00042 
00043 //**********************************************************************************************************
00044 //*                                  search_sensors
00045 //**********************************************************************************************************
00046 
00047 /**
00048 *     @brief search_sensors
00049 *    @param  [out] nSensors number of device onewire
00050 *    @param  [out] gSensorIDs[][] array of id romcode
00051 *    @return OW_OK or OW_PRESENCE_ERR or OW_DATA_ERR
00052 *     @date 20/06/2011
00053 */
00054 uint8_t search_sensors(uint8_t *nSensors,uint8_t gSensorIDs[][OW_ROMCODE_SIZE] ) {
00055     
00056 
00057     uint8_t i;
00058     uint8_t id[OW_ROMCODE_SIZE];
00059     uint8_t diff;
00060     printf( "Scanning Bus\n" );
00061     diff = OW_SEARCH_FIRST;
00062     for (*nSensors = 0 ; (diff != OW_LAST_DEVICE) && (*nSensors < MAXSENSORS) ;++(*nSensors) ) {
00063         ow_find_sensor( &diff, &id[0] );
00064         if ( diff == OW_PRESENCE_ERR ) {
00065             printf( "No Sensor found\r\n" );
00066             return diff;
00067         }
00068         if ( diff == OW_DATA_ERR ) {
00069             printf( "Bus Error\r\n" );
00070             return diff;
00071         }
00072         for (i=0;i<OW_ROMCODE_SIZE;i++)
00073             gSensorIDs[*nSensors][i]=id[i];
00074 
00075     }
00076     return OW_OK;
00077 }
00078 /**
00079 *     @brief search_sensors
00080 *   @param [in] n num bus onewire
00081 *    @param  [out] nSensors number of device onewire
00082 *    @param  [out] gSensorIDs[][][] array of id romcode
00083 *    @return OW_OK or OW_PRESENCE_ERR or OW_DATA_ERR
00084 *     @date 02/09/2011
00085 */
00086 uint8_t search_sensors(uint8_t n,uint8_t *nSensors,uint8_t gSensorIDs[][MAXSENSORS][OW_ROMCODE_SIZE] ) {
00087     
00088 
00089     uint8_t i;
00090     uint8_t id[OW_ROMCODE_SIZE];
00091     uint8_t diff;
00092     printf( "Scanning Bus %d\r\n",n );
00093     diff = OW_SEARCH_FIRST;
00094     for (*nSensors = 0 ; (diff != OW_LAST_DEVICE) && (*nSensors < MAXSENSORS) ;++(*nSensors) ) {
00095         ow_find_sensor(n, &diff, &id[0] );
00096         if ( diff == OW_PRESENCE_ERR ) {
00097             printf( "No Sensor found\r\n" );
00098             return diff;
00099         }
00100         if ( diff == OW_DATA_ERR ) {
00101             printf( "Bus Error\r\n" );
00102             return diff;
00103         }
00104         for (i=0;i<OW_ROMCODE_SIZE;i++)
00105             gSensorIDs[n][*nSensors][i]=id[i];
00106 
00107     }
00108     return OW_OK;
00109 }
00110 //**********************************************************************************************************
00111 //*                                  find Sensors on 1-Wire-Bus
00112 //**********************************************************************************************************
00113 
00114 /**
00115 *     @brief find Sensors on 1-Wire-Bus
00116 *    @param  [in/out] diff is the result of the last rom-search
00117 *    @param  [out] is the rom-code of the sensor found
00118 *    @return  OW_OK or OW_ERROR 
00119 *     @date 20/06/2011
00120 */
00121 uint8_t ow_find_sensor(uint8_t *diff, uint8_t id[]) {
00122     for (;;) 
00123     {
00124         *diff = ow_rom_search( *diff, &id[0] );
00125         if ( *diff==OW_PRESENCE_ERR)
00126             return OW_ERROR;
00127         if ( *diff==OW_DATA_ERR )
00128             return OW_ERROR;
00129         if ( *diff == OW_LAST_DEVICE )
00130             return OW_OK ;
00131         if ( id[0] == DS18B20_ID || id[0] == DS18S20_ID ) 
00132             return OW_OK ;
00133         if ( id[0] == DS2450_ID ) 
00134             return OW_OK ;
00135     }
00136 }
00137 
00138 /**
00139 *     @brief find Sensors on 1-Wire-Bus
00140 *    @param  [in] num bus onewire
00141 *    @param  [in/out] diff is the result of the last rom-search
00142 *    @param  [out] is the rom-code of the sensor found
00143 *    @return  OW_OK or OW_ERROR
00144 *     @date 30/08/2011 
00145 */
00146 uint8_t ow_find_sensor(uint8_t n,uint8_t *diff, uint8_t id[]) {
00147     for (;;) 
00148     {
00149         *diff = ow_rom_search(n, *diff, &id[0] );
00150         if ( *diff==OW_PRESENCE_ERR)
00151             return OW_ERROR;
00152         if ( *diff==OW_DATA_ERR )
00153             return OW_ERROR;
00154         if ( *diff == OW_LAST_DEVICE )
00155             return OW_OK ;
00156         if ( id[0] == DS18B20_ID || id[0] == DS18S20_ID ) 
00157             return OW_OK ;
00158         if ( id[0] == DS2450_ID ) 
00159             return OW_OK ;
00160     }
00161 }
00162 //**********************************************************************************************************
00163 //*                                  search romcode
00164 //**********************************************************************************************************
00165 
00166 /**
00167 *     @brief search romcode
00168 *    @param  [in] uint8_t diff
00169 *    @param  [out] id romcode
00170 *    @return next_diff or OW_LAST_DEVICE or OW_DATA_ERR or OW_PRESENCE_ERR
00171 *     @date 20/06/2011
00172 */
00173 uint8_t ow_rom_search( uint8_t diff, uint8_t id[] ) {
00174     uint8_t i, j, next_diff;
00175     uint8_t b;
00176 
00177     if ( ow_reset() )
00178         return OW_PRESENCE_ERR;    // error, no device found
00179     ow_byte_wr( OW_SEARCH_ROM );            // ROM search command
00180     next_diff = OW_LAST_DEVICE;            // unchanged on last device
00181     i = OW_ROMCODE_SIZE * 8;                    // 8 bytes
00182     do {
00183         j = 8;                                // 8 bits
00184         do {
00185             b = ow_bit_io( 1 );                // read bit
00186             if ( ow_bit_io( 1 ) ) {            // read complement bit
00187                 if ( b )                    // 11
00188                     return OW_DATA_ERR;        // data error
00189             } else {
00190                 if ( !b ) {                    // 00 = 2 devices
00191                     if ( diff > i || ((*id & 1) && diff != i) ) {
00192                         b = 1;                // now 1
00193                         next_diff = i;        // next pass 0
00194                     }
00195                 }
00196             }
00197             ow_bit_io( b );                 // write bit
00198             *id >>= 1;
00199             if ( b ) 
00200                 *id |= 0x80;            // store bit
00201             --i;
00202         } while ( --j );
00203         id++;                                // next byte
00204     } while ( i );
00205     return next_diff;                // to continue search
00206 }
00207 /**
00208 *     @brief search romcode
00209 *    @param  [in]n num bus onewire
00210 *    @param  [in] uint8_t diff
00211 *    @param  [out] id romcode
00212 *    @return next_diff or OW_LAST_DEVICE or OW_DATA_ERR or OW_PRESENCE_ERR
00213 *     @date 30/08/2011
00214 */
00215 uint8_t ow_rom_search(uint8_t n, uint8_t diff, uint8_t id[] ) {
00216     uint8_t i, j, next_diff;
00217     uint8_t b;
00218     if ( ow_reset(n) )
00219         return OW_PRESENCE_ERR;    // error, no device found
00220     ow_byte_wr(n, OW_SEARCH_ROM );            // ROM search command 
00221     next_diff = OW_LAST_DEVICE;            // unchanged on last device
00222     i = OW_ROMCODE_SIZE * 8;                    // 8 bytes
00223     do {
00224         j = 8;                                // 8 bits
00225         do {
00226             b = ow_bit_io(n, 1 );                // read bit
00227             if ( ow_bit_io(n, 1 ) ) {            // read complement bit
00228                 if ( b )                    // 11
00229                 {
00230                    
00231                     return OW_DATA_ERR;        // data error
00232                 }
00233             } else {
00234                 if ( !b ) {                    // 00 = 2 devices
00235                     if ( diff > i || ((*id & 1) && diff != i) ) {
00236                         b = 1;                // now 1
00237                         next_diff = i;        // next pass 0
00238                     }
00239                 }
00240             }
00241             ow_bit_io(n, b );                 // write bit
00242             
00243             *id >>= 1;
00244             if ( b ) 
00245                 *id |= 0x80;            // store bit
00246             --i;
00247         } while ( --j );
00248         id++;                                // next byte
00249         
00250     } while ( i );
00251 
00252 
00253     return next_diff;                // to continue search
00254 }
00255 
00256 
00257 //**********************************************************************************************************
00258 //*                                  test pin onewire bus
00259 //**********************************************************************************************************
00260 /**
00261 *     @brief test pin onewire bus
00262 *    @return etat pin ow
00263 *     @date 20/06/2011
00264 */
00265 uint8_t ow_test_pin (void){
00266     if (ow_pin)
00267         return 1;
00268 return 0;   
00269 }
00270 
00271 /**
00272 *     @brief test pin onewire bus
00273 *       @param [in] num bus one wire
00274 *    @return etat pin ow
00275 *     @date 30/08/2011
00276 */
00277 uint8_t ow_test_pin (uint8_t n){
00278 
00279        if (*t_ow[n])
00280             return 1;
00281 return 0; 
00282 }
00283 
00284 //**********************************************************************************************************
00285 //*                                  onewire reset bus
00286 //**********************************************************************************************************
00287 /**
00288 *     @brief onewire reset bus
00289 *    @return pin ow or OW_SHORT_CIRCUIT
00290 *     @date 20/06/2011
00291 */
00292 uint8_t ow_reset(void) { // reset.  Should improve to act as a presence pulse
00293     uint8_t err;
00294 
00295     ow_pin.output();
00296     ow_pin = 0;     // bring low for 500 us
00297     wait_us(500);
00298     ow_pin.input();
00299     wait_us(60);
00300     err = ow_pin;
00301     wait_us(240);
00302     if ( ow_pin == 0 )    {    // short circuit
00303         err = OW_SHORT_CIRCUIT;
00304     }
00305     return err;
00306 }
00307 
00308 /**
00309 *     @brief onewire reset bus
00310 *       @param [in] num bus onewire
00311 *    @return pin ow or OW_SHORT_CIRCUIT
00312 *     @date 30/08/2011
00313 */
00314 uint8_t ow_reset(uint8_t n) { // reset.  Should improve to act as a presence pulse
00315     uint8_t err;
00316     
00317     t_ow[n]->output();
00318     *t_ow[n] = 0;     // bring low for 500 us
00319     wait_us(500);
00320     t_ow[n]->input();
00321     wait_us(60);
00322     err = *t_ow[n];
00323     wait_us(240);
00324     if ( *t_ow[n] == 0 )    {    // short circuit
00325         err = OW_SHORT_CIRCUIT;
00326         
00327     }
00328     return err;
00329 }
00330 //**********************************************************************************************************
00331 //*                                  read write onewire
00332 //**********************************************************************************************************
00333 /**
00334 *     @brief read write onewire
00335 *    @param  [in/out] b data
00336 *    @return data
00337 *     @date 20/06/2011
00338 */
00339 uint8_t ow_bit_io( uint8_t b ) {
00340 
00341     ow_pin.output(); // drive bus low
00342     ow_pin = 0;
00343     wait_us(1); // Recovery-Time wuffwuff was 1
00344     
00345     if ( b ) 
00346         ow_pin.input(); // if bit is 1 set bus high (by ext. pull-up)
00347     //  delay was 15uS-1 see comment above
00348     wait_us(15-1);
00349     if ( ow_pin == 0 ) b = 0; // sample at end of read-timeslot
00350     wait_us(60-15);
00351     ow_pin.input();
00352     return b;
00353 }
00354 /**
00355 *     @brief read write onewire
00356 *    @param  [in] n num bus onewire
00357 *    @param  [in/out] b data
00358 *    @return data
00359 *     @date 30/08/2011
00360 */
00361 uint8_t ow_bit_io(uint8_t n, uint8_t b ) {
00362 
00363     t_ow[n]->output(); // drive bus low
00364     *t_ow[n] = 0;
00365     wait_us(1); // Recovery-Time wuffwuff was 1
00366     
00367     if ( b ) 
00368         t_ow[n]->input(); // if bit is 1 set bus high (by ext. pull-up)
00369     //  delay was 15uS-1 see comment above
00370     wait_us(15-1);
00371     if ( *t_ow[n] == 0 ) b = 0; // sample at end of read-timeslot
00372     wait_us(60-15);
00373     t_ow[n]->input();
00374    // printf("ow_bit_io n=%d b=%X\n",n,b);
00375     return b;
00376 }
00377 //**********************************************************************************************************
00378 //*                                  byte write on onewire
00379 //**********************************************************************************************************
00380 /**
00381 *     @brief byte write on onewire
00382 *    @param  [in] b data
00383 *    @return data
00384 *     @date 20/06/2011
00385 */
00386 uint8_t ow_byte_wr( uint8_t b ) {
00387     uint8_t i = 8, j;
00388 
00389     do {
00390         j = ow_bit_io( b & 1 );
00391         b >>= 1;
00392         if ( j )
00393             b |= 0x80;
00394     } while ( --i );
00395     return b;
00396 }
00397 /**
00398 *     @brief byte write on onewire
00399 *    @param  [in] n num bus onewire
00400 *    @param  [in] b data
00401 *    @return data
00402 *     @date 30/08/2011
00403 */
00404 uint8_t ow_byte_wr(uint8_t n, uint8_t b ) {
00405     uint8_t i = 8, j;
00406 
00407     do {
00408         j = ow_bit_io(n, b & 1 );
00409         b >>= 1;
00410         if ( j )
00411             b |= 0x80;
00412     } while ( --i );
00413     return b;
00414 }
00415 //**********************************************************************************************************
00416 //*                                  byte write on onewire
00417 //**********************************************************************************************************
00418 /**
00419 *     @brief byte read on onewire
00420 *       @return data
00421 *     @date 20/06/2011
00422 */
00423 uint8_t ow_byte_rd( void ) {
00424     // read by sending 0xff (a dontcare?)
00425     return ow_byte_wr( 0xFF );
00426 }
00427 
00428 /**
00429 *     @brief byte read on onewire
00430 *    @param  [in] n num onewire
00431 *    @return data
00432 *     @date 30/08/2011
00433 */
00434 uint8_t ow_byte_rd( uint8_t n) {
00435     // read by sending 0xff (a dontcare?)
00436     return ow_byte_wr(n, 0xFF );
00437 }
00438 //**********************************************************************************************************
00439 //*                                  byte write on onewire
00440 //**********************************************************************************************************
00441 /**
00442 *     @brief write command
00443 *    @param  [in] command
00444 *    @param  [in] id romcode
00445 *     @date 20/06/2011
00446 */
00447 uint8_t ow_command( uint8_t command, uint8_t id[] ) {
00448     uint8_t i;
00449 
00450     ow_reset();
00451     if ( id ) {
00452         ow_byte_wr( OW_MATCH_ROM );            // to a single device
00453         i = OW_ROMCODE_SIZE;
00454         do {
00455             ow_byte_wr( *id );
00456             ++id;
00457         } while ( --i );
00458     } else {
00459         ow_byte_wr( OW_SKIP_ROM );            // to all devices
00460     }
00461     ow_byte_wr( command );
00462     return 0;
00463 }
00464 /**
00465 *     @brief write command
00466 *    @param  [in] n num bus onewire
00467 *    @param  [in] command
00468 *    @param  [in] id romcode
00469 *     @date 30/08/2011
00470 */
00471 uint8_t ow_command(uint8_t n, uint8_t command, uint8_t id[] ) {
00472     uint8_t i;
00473 
00474     ow_reset(n);
00475     if ( id ) {
00476         ow_byte_wr( n,OW_MATCH_ROM );            // to a single device
00477         i = OW_ROMCODE_SIZE;
00478         do {
00479             ow_byte_wr(n, *id );
00480             ++id;
00481         } while ( --i );
00482     } else {
00483         ow_byte_wr(n, OW_SKIP_ROM );            // to all devices
00484     }
00485     ow_byte_wr(n, command );
00486     return 0;
00487 }
00488 //**********************************************************************************************************
00489 //*                                  ow mode
00490 //**********************************************************************************************************
00491 /**
00492 *     @brief parasite enable
00493 *     @date 20/06/2011
00494 */
00495 uint8_t ow_parasite_enable(void) {
00496     ow_pin.output();
00497     ow_pin = 1;
00498     return 0;
00499 }
00500 /**
00501 *     @brief parasite disable
00502 *     @date 20/06/2011
00503 */
00504 uint8_t ow_parasite_disable(void) {
00505 
00506     ow_pin.input();
00507     return 0;
00508 }
00509 
00510 /**
00511 *     @brief parasite enable
00512 *    @param  [in] n num bus onewire
00513 *     @date 30/08/2011
00514 */
00515 uint8_t ow_parasite_enable(uint8_t n) {
00516     t_ow[n]->output();
00517     *t_ow[n] = 1;
00518     return 0;
00519 }
00520 /**
00521 *     @brief parasite disable
00522 *    @param  [in] n num bus onewire
00523 *     @date 30/08/2011
00524 */
00525 uint8_t ow_parasite_disable(uint8_t n) {
00526     t_ow[n]->input();
00527     return 0;
00528 }
00529 /**
00530 *     @brief PUL-UP bus OW
00531 *    @return OW_OK
00532 *     @date 20/06/2011
00533 */
00534 uint8_t ow_PullUp(void)
00535 {
00536     ow_pin.mode(PullUp); //PULL-UP bus OW
00537 return OW_OK;
00538 }
00539 /**
00540 *     @brief PUL-UP bus OW
00541 *    @param  [in] n num bus onewire
00542 *    @return OW_OK
00543 *     @date 30/08/2011
00544 */
00545 uint8_t ow_PullUp(uint8_t n)
00546 {
00547     t_ow[n]->mode(PullUp); //PULL-UP bus OW
00548 return OW_OK;
00549 }