onewire DS18B20 DS2450

Dependencies:   mbed

Committer:
fblanc
Date:
Thu Jun 30 13:18:22 2011 +0000
Revision:
0:df0e3c8895f4
2011_06_30

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fblanc 0:df0e3c8895f4 1 /**
fblanc 0:df0e3c8895f4 2 * @file onewire.c
fblanc 0:df0e3c8895f4 3 * @brief library 1-Wire(www.maxim-ic.com)
fblanc 0:df0e3c8895f4 4 * @author Maciej Rajtar (Published 10 May 2010 www.mbed.org)
fblanc 0:df0e3c8895f4 5 * @author Frederic BLANC
fblanc 0:df0e3c8895f4 6 */
fblanc 0:df0e3c8895f4 7 #include "mbed.h"
fblanc 0:df0e3c8895f4 8 #include "onewire.h"
fblanc 0:df0e3c8895f4 9 #include "DS2450.h"
fblanc 0:df0e3c8895f4 10 #include "DS18X20.h"
fblanc 0:df0e3c8895f4 11 #include "crc8.h"
fblanc 0:df0e3c8895f4 12
fblanc 0:df0e3c8895f4 13 DigitalInOut ow_pin(ONEWIRE_PIN);
fblanc 0:df0e3c8895f4 14
fblanc 0:df0e3c8895f4 15 /**
fblanc 0:df0e3c8895f4 16 * @brief PUL-UP bus OW
fblanc 0:df0e3c8895f4 17 * @return OW_OK
fblanc 0:df0e3c8895f4 18 * @date 20/06/2011
fblanc 0:df0e3c8895f4 19 */
fblanc 0:df0e3c8895f4 20 uint8_t ow_PullUp(void)
fblanc 0:df0e3c8895f4 21 {
fblanc 0:df0e3c8895f4 22 ow_pin.mode(PullUp); //PULL-UP bus OW
fblanc 0:df0e3c8895f4 23 return OW_OK;
fblanc 0:df0e3c8895f4 24 }
fblanc 0:df0e3c8895f4 25 /**
fblanc 0:df0e3c8895f4 26 * @brief search_sensors
fblanc 0:df0e3c8895f4 27 * @param [out] nSensors number of device onewire
fblanc 0:df0e3c8895f4 28 * @param [out] gSensorIDs[][] array of id romcode
fblanc 0:df0e3c8895f4 29 * @return OW_OK or OW_PRESENCE_ERR or OW_DATA_ERR
fblanc 0:df0e3c8895f4 30 * @date 20/06/2011
fblanc 0:df0e3c8895f4 31 */
fblanc 0:df0e3c8895f4 32 uint8_t search_sensors(uint8_t *nSensors,uint8_t *gSensorIDs ) {
fblanc 0:df0e3c8895f4 33 uint8_t i;
fblanc 0:df0e3c8895f4 34 uint8_t id[OW_ROMCODE_SIZE];
fblanc 0:df0e3c8895f4 35 uint8_t diff;
fblanc 0:df0e3c8895f4 36 printf( "Scanning Bus\n" );
fblanc 0:df0e3c8895f4 37 diff = OW_SEARCH_FIRST;
fblanc 0:df0e3c8895f4 38 for (*nSensors = 0 ; (diff != OW_LAST_DEVICE) && (*nSensors < MAXSENSORS) ;++(*nSensors) ) {
fblanc 0:df0e3c8895f4 39 ow_find_sensor( &diff, &id[0] );
fblanc 0:df0e3c8895f4 40 if ( diff == OW_PRESENCE_ERR ) {
fblanc 0:df0e3c8895f4 41 printf( "No Sensor found\n" );
fblanc 0:df0e3c8895f4 42 return diff;
fblanc 0:df0e3c8895f4 43 }
fblanc 0:df0e3c8895f4 44 if ( diff == OW_DATA_ERR ) {
fblanc 0:df0e3c8895f4 45 printf( "Bus Error\n" );
fblanc 0:df0e3c8895f4 46 return diff;
fblanc 0:df0e3c8895f4 47 }
fblanc 0:df0e3c8895f4 48 for (i=0;i<OW_ROMCODE_SIZE;i++)
fblanc 0:df0e3c8895f4 49 gSensorIDs[(*nSensors)*OW_ROMCODE_SIZE+i]=id[i];
fblanc 0:df0e3c8895f4 50
fblanc 0:df0e3c8895f4 51 }
fblanc 0:df0e3c8895f4 52 return OW_OK;
fblanc 0:df0e3c8895f4 53 }
fblanc 0:df0e3c8895f4 54 /**
fblanc 0:df0e3c8895f4 55 * @brief show_id
fblanc 0:df0e3c8895f4 56 * @param [in] id[] = rom_code
fblanc 0:df0e3c8895f4 57 * @param [in] n number of id[n]
fblanc 0:df0e3c8895f4 58 * @param [out] text id
fblanc 0:df0e3c8895f4 59 * @return OW_OK or OW_ERROR_CRC
fblanc 0:df0e3c8895f4 60 * @date 20/06/2011
fblanc 0:df0e3c8895f4 61 */
fblanc 0:df0e3c8895f4 62 uint8_t ow_show_id( uint8_t id[], size_t n ,char *text) {
fblanc 0:df0e3c8895f4 63 size_t i;
fblanc 0:df0e3c8895f4 64 char hex[4];
fblanc 0:df0e3c8895f4 65 sprintf(text,"");
fblanc 0:df0e3c8895f4 66
fblanc 0:df0e3c8895f4 67 for ( i = 0; i < n; i++ ) {
fblanc 0:df0e3c8895f4 68 if ( i == 0 ) strcat(text, " FC: " );
fblanc 0:df0e3c8895f4 69 else if ( i == n-1 ) strcat(text, "CRC: " );
fblanc 0:df0e3c8895f4 70 if ( i == 1 ) strcat(text, " SN: " );
fblanc 0:df0e3c8895f4 71 sprintf(hex,"%2.2X ",id[i]);
fblanc 0:df0e3c8895f4 72 strcat(text,hex);
fblanc 0:df0e3c8895f4 73 if ( i == 0 ) {
fblanc 0:df0e3c8895f4 74 if ( id[0] == DS18S20_ID ) strcat(text,"(18S)");
fblanc 0:df0e3c8895f4 75 else if ( id[0] == DS18B20_ID ) strcat(text,"(18B)");
fblanc 0:df0e3c8895f4 76 else if ( id[0] == DS2450_ID ) strcat(text,"(ADC)");
fblanc 0:df0e3c8895f4 77 else strcat(text,"( ? )");
fblanc 0:df0e3c8895f4 78 }
fblanc 0:df0e3c8895f4 79 }
fblanc 0:df0e3c8895f4 80 if ( crc8( id, OW_ROMCODE_SIZE) )
fblanc 0:df0e3c8895f4 81 return OW_ERROR_CRC;
fblanc 0:df0e3c8895f4 82 return OW_OK;
fblanc 0:df0e3c8895f4 83 }
fblanc 0:df0e3c8895f4 84
fblanc 0:df0e3c8895f4 85 /**
fblanc 0:df0e3c8895f4 86 * @brief test pin onewire bus
fblanc 0:df0e3c8895f4 87 * @return etat pin ow
fblanc 0:df0e3c8895f4 88 * @date 20/06/2011
fblanc 0:df0e3c8895f4 89 */
fblanc 0:df0e3c8895f4 90 uint8_t ow_test_pin (void){
fblanc 0:df0e3c8895f4 91 if (ow_pin)
fblanc 0:df0e3c8895f4 92 return 1;
fblanc 0:df0e3c8895f4 93 return 0;
fblanc 0:df0e3c8895f4 94 }
fblanc 0:df0e3c8895f4 95 /**
fblanc 0:df0e3c8895f4 96 * @brief onewire reset bus
fblanc 0:df0e3c8895f4 97 * @return pin ow or OW_SHORT_CIRCUIT
fblanc 0:df0e3c8895f4 98 * @date 20/06/2011
fblanc 0:df0e3c8895f4 99 */
fblanc 0:df0e3c8895f4 100 uint8_t ow_reset(void) { // reset. Should improve to act as a presence pulse
fblanc 0:df0e3c8895f4 101 uint8_t err;
fblanc 0:df0e3c8895f4 102
fblanc 0:df0e3c8895f4 103 ow_pin.output();
fblanc 0:df0e3c8895f4 104 ow_pin = 0; // bring low for 500 us
fblanc 0:df0e3c8895f4 105 wait_us(500);
fblanc 0:df0e3c8895f4 106 ow_pin.input();
fblanc 0:df0e3c8895f4 107 wait_us(60);
fblanc 0:df0e3c8895f4 108 err = ow_pin;
fblanc 0:df0e3c8895f4 109 wait_us(240);
fblanc 0:df0e3c8895f4 110 if ( ow_pin == 0 ) { // short circuit
fblanc 0:df0e3c8895f4 111 err = OW_SHORT_CIRCUIT;
fblanc 0:df0e3c8895f4 112 }
fblanc 0:df0e3c8895f4 113 return err;
fblanc 0:df0e3c8895f4 114 }
fblanc 0:df0e3c8895f4 115
fblanc 0:df0e3c8895f4 116 /**
fblanc 0:df0e3c8895f4 117 * @brief read write onewire
fblanc 0:df0e3c8895f4 118 * @param [in/out] b data
fblanc 0:df0e3c8895f4 119 * @return data
fblanc 0:df0e3c8895f4 120 * @date 20/06/2011
fblanc 0:df0e3c8895f4 121 */
fblanc 0:df0e3c8895f4 122 uint8_t ow_bit_io( uint8_t b ) {
fblanc 0:df0e3c8895f4 123
fblanc 0:df0e3c8895f4 124 ow_pin.output(); // drive bus low
fblanc 0:df0e3c8895f4 125 ow_pin = 0;
fblanc 0:df0e3c8895f4 126 wait_us(1); // Recovery-Time wuffwuff was 1
fblanc 0:df0e3c8895f4 127
fblanc 0:df0e3c8895f4 128 if ( b )
fblanc 0:df0e3c8895f4 129 ow_pin.input(); // if bit is 1 set bus high (by ext. pull-up)
fblanc 0:df0e3c8895f4 130 // delay was 15uS-1 see comment above
fblanc 0:df0e3c8895f4 131 wait_us(15-1);
fblanc 0:df0e3c8895f4 132 if ( ow_pin == 0 ) b = 0; // sample at end of read-timeslot
fblanc 0:df0e3c8895f4 133 wait_us(60-15);
fblanc 0:df0e3c8895f4 134 ow_pin.input();
fblanc 0:df0e3c8895f4 135 return b;
fblanc 0:df0e3c8895f4 136 }
fblanc 0:df0e3c8895f4 137
fblanc 0:df0e3c8895f4 138 /**
fblanc 0:df0e3c8895f4 139 * @brief byte write on onewire
fblanc 0:df0e3c8895f4 140 * @param [in] b data
fblanc 0:df0e3c8895f4 141 * @return data
fblanc 0:df0e3c8895f4 142 * @date 20/06/2011
fblanc 0:df0e3c8895f4 143 */
fblanc 0:df0e3c8895f4 144 uint8_t ow_byte_wr( uint8_t b ) {
fblanc 0:df0e3c8895f4 145 uint8_t i = 8, j;
fblanc 0:df0e3c8895f4 146
fblanc 0:df0e3c8895f4 147 do {
fblanc 0:df0e3c8895f4 148 j = ow_bit_io( b & 1 );
fblanc 0:df0e3c8895f4 149 b >>= 1;
fblanc 0:df0e3c8895f4 150 if ( j )
fblanc 0:df0e3c8895f4 151 b |= 0x80;
fblanc 0:df0e3c8895f4 152 } while ( --i );
fblanc 0:df0e3c8895f4 153 return b;
fblanc 0:df0e3c8895f4 154 }
fblanc 0:df0e3c8895f4 155
fblanc 0:df0e3c8895f4 156 /**
fblanc 0:df0e3c8895f4 157 * @brief byte read on onewire
fblanc 0:df0e3c8895f4 158 * @param [in] uint8_t b
fblanc 0:df0e3c8895f4 159 * @return
fblanc 0:df0e3c8895f4 160 * @date 20/06/2011
fblanc 0:df0e3c8895f4 161 */
fblanc 0:df0e3c8895f4 162 uint8_t ow_byte_rd( void ) {
fblanc 0:df0e3c8895f4 163 // read by sending 0xff (a dontcare?)
fblanc 0:df0e3c8895f4 164 return ow_byte_wr( 0xFF );
fblanc 0:df0e3c8895f4 165 }
fblanc 0:df0e3c8895f4 166
fblanc 0:df0e3c8895f4 167
fblanc 0:df0e3c8895f4 168 /**
fblanc 0:df0e3c8895f4 169 * @brief search romcode
fblanc 0:df0e3c8895f4 170 * @param [in] uint8_t diff
fblanc 0:df0e3c8895f4 171 * @param [out] id romcode
fblanc 0:df0e3c8895f4 172 * @return next_diff or OW_LAST_DEVICE or OW_DATA_ERR or OW_PRESENCE_ERR
fblanc 0:df0e3c8895f4 173 * @date 20/06/2011
fblanc 0:df0e3c8895f4 174 */
fblanc 0:df0e3c8895f4 175 uint8_t ow_rom_search( uint8_t diff, uint8_t id[] ) {
fblanc 0:df0e3c8895f4 176 uint8_t i, j, next_diff;
fblanc 0:df0e3c8895f4 177 uint8_t b;
fblanc 0:df0e3c8895f4 178
fblanc 0:df0e3c8895f4 179 if ( ow_reset() )
fblanc 0:df0e3c8895f4 180 return OW_PRESENCE_ERR; // error, no device found
fblanc 0:df0e3c8895f4 181 ow_byte_wr( OW_SEARCH_ROM ); // ROM search command
fblanc 0:df0e3c8895f4 182 next_diff = OW_LAST_DEVICE; // unchanged on last device
fblanc 0:df0e3c8895f4 183 i = OW_ROMCODE_SIZE * 8; // 8 bytes
fblanc 0:df0e3c8895f4 184 do {
fblanc 0:df0e3c8895f4 185 j = 8; // 8 bits
fblanc 0:df0e3c8895f4 186 do {
fblanc 0:df0e3c8895f4 187 b = ow_bit_io( 1 ); // read bit
fblanc 0:df0e3c8895f4 188 if ( ow_bit_io( 1 ) ) { // read complement bit
fblanc 0:df0e3c8895f4 189 if ( b ) // 11
fblanc 0:df0e3c8895f4 190 return OW_DATA_ERR; // data error
fblanc 0:df0e3c8895f4 191 } else {
fblanc 0:df0e3c8895f4 192 if ( !b ) { // 00 = 2 devices
fblanc 0:df0e3c8895f4 193 if ( diff > i || ((*id & 1) && diff != i) ) {
fblanc 0:df0e3c8895f4 194 b = 1; // now 1
fblanc 0:df0e3c8895f4 195 next_diff = i; // next pass 0
fblanc 0:df0e3c8895f4 196 }
fblanc 0:df0e3c8895f4 197 }
fblanc 0:df0e3c8895f4 198 }
fblanc 0:df0e3c8895f4 199 ow_bit_io( b ); // write bit
fblanc 0:df0e3c8895f4 200 *id >>= 1;
fblanc 0:df0e3c8895f4 201 if ( b )
fblanc 0:df0e3c8895f4 202 *id |= 0x80; // store bit
fblanc 0:df0e3c8895f4 203 --i;
fblanc 0:df0e3c8895f4 204 } while ( --j );
fblanc 0:df0e3c8895f4 205 id++; // next byte
fblanc 0:df0e3c8895f4 206 } while ( i );
fblanc 0:df0e3c8895f4 207 return next_diff; // to continue search
fblanc 0:df0e3c8895f4 208 }
fblanc 0:df0e3c8895f4 209
fblanc 0:df0e3c8895f4 210 /**
fblanc 0:df0e3c8895f4 211 * @brief write command
fblanc 0:df0e3c8895f4 212 * @param [in] command
fblanc 0:df0e3c8895f4 213 * @param [in] id romcode
fblanc 0:df0e3c8895f4 214 * @date 20/06/2011
fblanc 0:df0e3c8895f4 215 */
fblanc 0:df0e3c8895f4 216 uint8_t ow_command( uint8_t command, uint8_t id[] ) {
fblanc 0:df0e3c8895f4 217 uint8_t i;
fblanc 0:df0e3c8895f4 218
fblanc 0:df0e3c8895f4 219 ow_reset();
fblanc 0:df0e3c8895f4 220 if ( id ) {
fblanc 0:df0e3c8895f4 221 ow_byte_wr( OW_MATCH_ROM ); // to a single device
fblanc 0:df0e3c8895f4 222 i = OW_ROMCODE_SIZE;
fblanc 0:df0e3c8895f4 223 do {
fblanc 0:df0e3c8895f4 224 ow_byte_wr( *id );
fblanc 0:df0e3c8895f4 225 ++id;
fblanc 0:df0e3c8895f4 226 } while ( --i );
fblanc 0:df0e3c8895f4 227 } else {
fblanc 0:df0e3c8895f4 228 ow_byte_wr( OW_SKIP_ROM ); // to all devices
fblanc 0:df0e3c8895f4 229 }
fblanc 0:df0e3c8895f4 230 ow_byte_wr( command );
fblanc 0:df0e3c8895f4 231 return 0;
fblanc 0:df0e3c8895f4 232 }
fblanc 0:df0e3c8895f4 233 /**
fblanc 0:df0e3c8895f4 234 * @brief parasite enable
fblanc 0:df0e3c8895f4 235 * @date 20/06/2011
fblanc 0:df0e3c8895f4 236 */
fblanc 0:df0e3c8895f4 237 uint8_t ow_parasite_enable(void) {
fblanc 0:df0e3c8895f4 238 ow_pin.output();
fblanc 0:df0e3c8895f4 239 ow_pin = 1;
fblanc 0:df0e3c8895f4 240 return 0;
fblanc 0:df0e3c8895f4 241 }
fblanc 0:df0e3c8895f4 242 /**
fblanc 0:df0e3c8895f4 243 * @brief parasite disable
fblanc 0:df0e3c8895f4 244 * @date 20/06/2011
fblanc 0:df0e3c8895f4 245 */
fblanc 0:df0e3c8895f4 246 uint8_t ow_parasite_disable(void) {
fblanc 0:df0e3c8895f4 247
fblanc 0:df0e3c8895f4 248 ow_pin.input();
fblanc 0:df0e3c8895f4 249 return 0;
fblanc 0:df0e3c8895f4 250 }
fblanc 0:df0e3c8895f4 251
fblanc 0:df0e3c8895f4 252
fblanc 0:df0e3c8895f4 253 /**
fblanc 0:df0e3c8895f4 254 * @brief find Sensors on 1-Wire-Bus
fblanc 0:df0e3c8895f4 255 * @param [in/out] diff is the result of the last rom-search
fblanc 0:df0e3c8895f4 256 * @param [out] is the rom-code of the sensor found
fblanc 0:df0e3c8895f4 257 * @return OW_OK or OW_ERROR
fblanc 0:df0e3c8895f4 258 */
fblanc 0:df0e3c8895f4 259 uint8_t ow_find_sensor(uint8_t *diff, uint8_t id[]) {
fblanc 0:df0e3c8895f4 260 for (;;)
fblanc 0:df0e3c8895f4 261 {
fblanc 0:df0e3c8895f4 262 *diff = ow_rom_search( *diff, &id[0] );
fblanc 0:df0e3c8895f4 263 if ( *diff==OW_PRESENCE_ERR)
fblanc 0:df0e3c8895f4 264 return OW_ERROR;
fblanc 0:df0e3c8895f4 265 if ( *diff==OW_DATA_ERR )
fblanc 0:df0e3c8895f4 266 return OW_ERROR;
fblanc 0:df0e3c8895f4 267 if ( *diff == OW_LAST_DEVICE )
fblanc 0:df0e3c8895f4 268 return OW_OK ;
fblanc 0:df0e3c8895f4 269 if ( id[0] == DS18B20_ID || id[0] == DS18S20_ID )
fblanc 0:df0e3c8895f4 270 return OW_OK ;
fblanc 0:df0e3c8895f4 271 if ( id[0] == DS2450_ID )
fblanc 0:df0e3c8895f4 272 return OW_OK ;
fblanc 0:df0e3c8895f4 273 }
fblanc 0:df0e3c8895f4 274 }
fblanc 0:df0e3c8895f4 275
fblanc 0:df0e3c8895f4 276 /**
fblanc 0:df0e3c8895f4 277 * @brief output byte d (least sig bit first)
fblanc 0:df0e3c8895f4 278 * @param [in] d output byte (least sig bit first)
fblanc 0:df0e3c8895f4 279 * @return OW_OK
fblanc 0:df0e3c8895f4 280 */
fblanc 0:df0e3c8895f4 281 uint8_t OneWireOutByte(uint8_t d) { // output byte d (least sig bit first).
fblanc 0:df0e3c8895f4 282 for (int n=8; n!=0; n--) {
fblanc 0:df0e3c8895f4 283 if ((d & 0x01) == 1) { // test least sig bit
fblanc 0:df0e3c8895f4 284 ow_pin.output();
fblanc 0:df0e3c8895f4 285 ow_pin = 0;
fblanc 0:df0e3c8895f4 286 wait_us(5);
fblanc 0:df0e3c8895f4 287 ow_pin.input();
fblanc 0:df0e3c8895f4 288 wait_us(80);
fblanc 0:df0e3c8895f4 289 } else {
fblanc 0:df0e3c8895f4 290 ow_pin.output();
fblanc 0:df0e3c8895f4 291 ow_pin = 0;
fblanc 0:df0e3c8895f4 292 wait_us(80);
fblanc 0:df0e3c8895f4 293 ow_pin.input();
fblanc 0:df0e3c8895f4 294 }
fblanc 0:df0e3c8895f4 295 d=d>>1; // now the next bit is in the least sig bit position.
fblanc 0:df0e3c8895f4 296 }
fblanc 0:df0e3c8895f4 297 return OW_OK;
fblanc 0:df0e3c8895f4 298 }
fblanc 0:df0e3c8895f4 299 /**
fblanc 0:df0e3c8895f4 300 * @brief read byte, least sig byte first
fblanc 0:df0e3c8895f4 301 * @return byte, least sig byte first
fblanc 0:df0e3c8895f4 302 */
fblanc 0:df0e3c8895f4 303 uint8_t OneWireInByte(void) { // read byte, least sig byte first
fblanc 0:df0e3c8895f4 304 uint8_t d = 0, b;
fblanc 0:df0e3c8895f4 305 for (int n=0; n<8; n++) {
fblanc 0:df0e3c8895f4 306 ow_pin.output();
fblanc 0:df0e3c8895f4 307 ow_pin = 0;
fblanc 0:df0e3c8895f4 308 wait_us(5);
fblanc 0:df0e3c8895f4 309 ow_pin.input();
fblanc 0:df0e3c8895f4 310 wait_us(5);
fblanc 0:df0e3c8895f4 311 b =ow_pin;
fblanc 0:df0e3c8895f4 312 wait_us(50);
fblanc 0:df0e3c8895f4 313 d = (d >> 1) | (b << 7); // shift d to right and insert b in most sig bit position
fblanc 0:df0e3c8895f4 314 }
fblanc 0:df0e3c8895f4 315 return d;
fblanc 0:df0e3c8895f4 316 }
fblanc 0:df0e3c8895f4 317