OneWire DS18B20,DS2450,MAX31850
Dependents: MAX31850_HelloWorld
onewire.cpp
- Committer:
- fblanc
- Date:
- 2015-02-12
- Revision:
- 0:9acbbb021a43
File content as of revision 0:9acbbb021a43:
/**
* @file onewire.c
* @brief library 1-Wire(www.maxim-ic.com)
* @author Maciej Rajtar (Published 10 May 2010 www.mbed.org)
* @author Frederic BLANC (Published 01/03/2012 www.mbed.org)
*/
#include "mbed.h"
#include "onewire.h"
DigitalInOut ow_pin(p21);
DigitalInOut ow_0(p21);
DigitalInOut ow_1(p22);
DigitalInOut ow_2(p23);
DigitalInOut ow_3(p24);
DigitalInOut* t_ow[4]={&ow_0,&ow_1,&ow_2,&ow_3};
//**********************************************************************************************************
//* show_id
//**********************************************************************************************************
/**
* @brief show_id
* @param [in] id[] = rom_code
* @param [out] text id
* @date 02/12/2013
*/
char* ow_show_id( uint8_t id[],char *text) {
char hex[4];
sprintf(text,"");
sprintf(hex,"%2.2X",id[0]);
strcat(text,hex);
for (int i = OW_ROMCODE_SIZE-2; i >=1 ; --i ) {
sprintf(hex,"%2.2X",id[i]);
strcat(text,hex);
}
sprintf(hex,"%2.2X",id[OW_ROMCODE_SIZE-1]);
strcat(text,hex);
return text;
}
//**********************************************************************************************************
//* show_id
//**********************************************************************************************************
/**
* @brief uint64_id
* @param [in] id[] = rom_code
* @return [out] uint64_t id
* @date 28/03/2011
*/
uint64_t uint64_id( uint8_t id[]) {
uint64_t *ptr;
ptr=(uint64_t *) &id[0];
return *ptr;
}
//**********************************************************************************************************
//* search_sensors
//**********************************************************************************************************
/**
* @brief search_sensors
* @param [out] nSensors number of device onewire
* @param [out] gSensorIDs[][] array of id romcode
* @return OW_OK or OW_PRESENCE_ERR or OW_DATA_ERR
* @date 20/06/2011
*/
uint8_t search_sensors(uint8_t *nSensors,uint8_t gSensorIDs[][OW_ROMCODE_SIZE] ) {
uint8_t i;
uint8_t id[OW_ROMCODE_SIZE];
uint8_t diff;
//printf( "Scanning Bus\r\n" );
diff = OW_SEARCH_FIRST;
for (*nSensors = 0 ; (diff != OW_LAST_DEVICE) && (*nSensors < MAXSENSORS) ;++(*nSensors) ) {
ow_find_sensor( &diff, &id[0] );
if ( diff == OW_PRESENCE_ERR ) {
//printf( "No Sensor found\r\n" );
return diff;
}
if ( diff == OW_DATA_ERR ) {
//printf( "Bus Error\r\n" );
return diff;
}
for (i=0;i<OW_ROMCODE_SIZE;i++)
gSensorIDs[*nSensors][i]=id[i];
}
return OW_OK;
}
/**
* @brief search_sensors
* @param [in] n num bus onewire
* @param [out] nSensors number of device onewire
* @param [out] gSensorIDs[][][] array of id romcode
* @return OW_OK or OW_PRESENCE_ERR or OW_DATA_ERR
* @date 02/09/2011
*/
uint8_t search_sensors(uint8_t n,uint8_t *nSensors,uint8_t gSensorIDs[][MAXSENSORS][OW_ROMCODE_SIZE] ) {
uint8_t i;
uint8_t id[OW_ROMCODE_SIZE];
uint8_t diff;
//printf( "Scanning Bus %d\r\n",n );
diff = OW_SEARCH_FIRST;
for (*nSensors = 0 ; (diff != OW_LAST_DEVICE) && (*nSensors < MAXSENSORS) ;++(*nSensors) ) {
ow_find_sensor(n, &diff, &id[0] );
if ( diff == OW_PRESENCE_ERR ) {
//printf( "No Sensor found\r\n" );
return diff;
}
if ( diff == OW_DATA_ERR ) {
//printf( "Bus Error\r\n" );
return diff;
}
for (i=0;i<OW_ROMCODE_SIZE;i++){
gSensorIDs[n][*nSensors][i]=id[i];
//printf( "id[%d]=%d\r\n" ,i,id[i]);
}
}
return OW_OK;
}
//**********************************************************************************************************
//* find Sensors on 1-Wire-Bus
//**********************************************************************************************************
/**
* @brief find Sensors on 1-Wire-Bus
* @param [in/out] diff is the result of the last rom-search
* @param [out] is the rom-code of the sensor found
* @return OW_OK or OW_ERROR
* @date 20/06/2011
*/
uint8_t ow_find_sensor(uint8_t *diff, uint8_t id[]) {
for (;;)
{
*diff = ow_rom_search( *diff, &id[0] );
if ( *diff==OW_PRESENCE_ERR)
return OW_ERROR;
if ( *diff==OW_DATA_ERR )
return OW_ERROR;
if ( *diff == OW_LAST_DEVICE )
return OW_OK ;
if ( id[0] == DS18B20_ID || id[0] == DS18S20_ID )
return OW_OK ;
if ( id[0] == DS2450_ID )
return OW_OK ;
if ( id[0] == MAX31850_ID )
return OW_OK ;
}
}
/**
* @brief find Sensors on 1-Wire-Bus
* @param [in] num bus onewire
* @param [in/out] diff is the result of the last rom-search
* @param [out] is the rom-code of the sensor found
* @return OW_OK or OW_ERROR
* @date 30/08/2011
*/
uint8_t ow_find_sensor(uint8_t n,uint8_t *diff, uint8_t id[]) {
for (;;)
{
*diff = ow_rom_search(n, *diff, &id[0] );
if ( *diff==OW_PRESENCE_ERR)
return OW_ERROR;
if ( *diff==OW_DATA_ERR )
return OW_ERROR;
if ( *diff == OW_LAST_DEVICE )
return OW_OK ;
if ( id[0] == DS18B20_ID || id[0] == DS18S20_ID )
return OW_OK ;
if ( id[0] == DS2450_ID )
return OW_OK ;
if ( id[0] == MAX31850_ID )
return OW_OK ;
}
}
//**********************************************************************************************************
//* search romcode
//**********************************************************************************************************
/**
* @brief search romcode
* @param [in] uint8_t diff
* @param [out] id romcode
* @return next_diff or OW_LAST_DEVICE or OW_DATA_ERR or OW_PRESENCE_ERR
* @date 20/06/2011
*/
uint8_t ow_rom_search( uint8_t diff, uint8_t id[] ) {
uint8_t i, j, next_diff;
uint8_t b;
if ( ow_reset() )
return OW_PRESENCE_ERR; // error, no device found
ow_byte_wr( OW_SEARCH_ROM ); // ROM search command
next_diff = OW_LAST_DEVICE; // unchanged on last device
i = OW_ROMCODE_SIZE * 8; // 8 bytes
do {
j = 8; // 8 bits
do {
b = ow_bit_io( 1 ); // read bit
if ( ow_bit_io( 1 ) ) { // read complement bit
if ( b ) // 11
return OW_DATA_ERR; // data error
} else {
if ( !b ) { // 00 = 2 devices
if ( diff > i || ((*id & 1) && diff != i) ) {
b = 1; // now 1
next_diff = i; // next pass 0
}
}
}
ow_bit_io( b ); // write bit
*id >>= 1;
if ( b )
*id |= 0x80; // store bit
--i;
} while ( --j );
id++; // next byte
} while ( i );
return next_diff; // to continue search
}
/**
* @brief search romcode
* @param [in]n num bus onewire
* @param [in] uint8_t diff
* @param [out] id romcode
* @return next_diff or OW_LAST_DEVICE or OW_DATA_ERR or OW_PRESENCE_ERR
* @date 30/08/2011
*/
uint8_t ow_rom_search(uint8_t n, uint8_t diff, uint8_t id[] ) {
uint8_t i, j, next_diff;
uint8_t b;
if ( ow_reset(n) )
return OW_PRESENCE_ERR; // error, no device found
ow_byte_wr(n, OW_SEARCH_ROM ); // ROM search command
next_diff = OW_LAST_DEVICE; // unchanged on last device
i = OW_ROMCODE_SIZE * 8; // 8 bytes
do {
j = 8; // 8 bits
do {
b = ow_bit_io(n, 1 ); // read bit
if ( ow_bit_io(n, 1 ) ) { // read complement bit
if ( b ) // 11
{
return OW_DATA_ERR; // data error
}
} else {
if ( !b ) { // 00 = 2 devices
if ( diff > i || ((*id & 1) && diff != i) ) {
b = 1; // now 1
next_diff = i; // next pass 0
}
}
}
ow_bit_io(n, b ); // write bit
*id >>= 1;
if ( b )
*id |= 0x80; // store bit
--i;
} while ( --j );
id++; // next byte
} while ( i );
return next_diff; // to continue search
}
//**********************************************************************************************************
//* test pin onewire bus
//**********************************************************************************************************
/**
* @brief test pin onewire bus
* @return etat pin ow
* @date 20/06/2011
*/
uint8_t ow_test_pin (void){
if (ow_pin)
return 1;
return 0;
}
/**
* @brief test pin onewire bus
* @param [in] num bus one wire
* @return etat pin ow
* @date 30/08/2011
*/
uint8_t ow_test_pin (uint8_t n){
if (*t_ow[n])
return 1;
return 0;
}
//**********************************************************************************************************
//* onewire reset bus
//**********************************************************************************************************
/**
* @brief onewire reset bus
* @return pin ow or OW_SHORT_CIRCUIT
* @date 20/06/2011
*/
uint8_t ow_reset(void) { // reset. Should improve to act as a presence pulse
uint8_t err;
ow_pin.output();
ow_pin = 0; // bring low for 500 us
wait_us(500);
ow_pin.input();
wait_us(60);
err = ow_pin;
wait_us(240);
if ( ow_pin == 0 ) { // short circuit
err = OW_SHORT_CIRCUIT;
}
return err;
}
/**
* @brief onewire reset bus
* @param [in] num bus onewire
* @return pin ow or OW_SHORT_CIRCUIT
* @date 30/08/2011
*/
uint8_t ow_reset(uint8_t n) { // reset. Should improve to act as a presence pulse
uint8_t err;
t_ow[n]->output();
*t_ow[n] = 0; // bring low for 500 us
wait_us(500);
t_ow[n]->input();
wait_us(60);
err = *t_ow[n];
wait_us(240);
if ( *t_ow[n] == 0 ) { // short circuit
err = OW_SHORT_CIRCUIT;
}
return err;
}
//**********************************************************************************************************
//* read write onewire
//**********************************************************************************************************
/**
* @brief read write onewire
* @param [in/out] b data
* @return data
* @date 20/06/2011
*/
uint8_t ow_bit_io( uint8_t b ) {
ow_pin.output(); // drive bus low
ow_pin = 0;
wait_us(1); // Recovery-Time wuffwuff was 1
if ( b )
ow_pin.input(); // if bit is 1 set bus high (by ext. pull-up)
// delay was 15uS-1 see comment above
wait_us(15-1);
if ( ow_pin == 0 ) b = 0; // sample at end of read-timeslot
wait_us(60-15);
ow_pin.input();
return b;
}
/**
* @brief read write onewire
* @param [in] n num bus onewire
* @param [in/out] b data
* @return data
* @date 30/08/2011
*/
uint8_t ow_bit_io(uint8_t n, uint8_t b ) {
t_ow[n]->output(); // drive bus low
*t_ow[n] = 0;
wait_us(1); // Recovery-Time wuffwuff was 1
if ( b )
t_ow[n]->input(); // if bit is 1 set bus high (by ext. pull-up)
// delay was 15uS-1 see comment above
wait_us(15-1);
if ( *t_ow[n] == 0 ) b = 0; // sample at end of read-timeslot
wait_us(60-15);
t_ow[n]->input();
// printf("ow_bit_io n=%d b=%X\n",n,b);
return b;
}
//**********************************************************************************************************
//* byte write on onewire
//**********************************************************************************************************
/**
* @brief byte write on onewire
* @param [in] b data
* @return data
* @date 20/06/2011
*/
uint8_t ow_byte_wr( uint8_t b ) {
uint8_t i = 8, j;
do {
j = ow_bit_io( b & 1 );
b >>= 1;
if ( j )
b |= 0x80;
} while ( --i );
return b;
}
/**
* @brief byte write on onewire
* @param [in] n num bus onewire
* @param [in] b data
* @return data
* @date 30/08/2011
*/
uint8_t ow_byte_wr(uint8_t n, uint8_t b ) {
uint8_t i = 8, j;
do {
j = ow_bit_io(n, b & 1 );
b >>= 1;
if ( j )
b |= 0x80;
} while ( --i );
return b;
}
//**********************************************************************************************************
//* byte write on onewire
//**********************************************************************************************************
/**
* @brief byte read on onewire
* @return data
* @date 20/06/2011
*/
uint8_t ow_byte_rd( void ) {
// read by sending 0xff (a dontcare?)
return ow_byte_wr( 0xFF );
}
/**
* @brief byte read on onewire
* @param [in] n num onewire
* @return data
* @date 30/08/2011
*/
uint8_t ow_byte_rd( uint8_t n) {
// read by sending 0xff (a dontcare?)
return ow_byte_wr(n, 0xFF );
}
//**********************************************************************************************************
//* byte write on onewire
//**********************************************************************************************************
/**
* @brief write command
* @param [in] command
* @param [in] id romcode
* @date 20/06/2011
*/
uint8_t ow_command( uint8_t command, uint8_t id[] ) {
uint8_t i;
ow_reset();
if ( id ) {
ow_byte_wr( OW_MATCH_ROM ); // to a single device
i = OW_ROMCODE_SIZE;
do {
ow_byte_wr( *id );
++id;
} while ( --i );
} else {
ow_byte_wr( OW_SKIP_ROM ); // to all devices
}
ow_byte_wr( command );
return 0;
}
/**
* @brief write command
* @param [in] n num bus onewire
* @param [in] command
* @param [in] id romcode
* @date 30/08/2011
*/
uint8_t ow_command(uint8_t n, uint8_t command, uint8_t id[] ) {
uint8_t i;
ow_reset(n);
if ( id ) {
ow_byte_wr( n,OW_MATCH_ROM ); // to a single device
i = OW_ROMCODE_SIZE;
do {
ow_byte_wr(n, *id );
++id;
} while ( --i );
} else {
ow_byte_wr(n, OW_SKIP_ROM ); // to all devices
}
ow_byte_wr(n, command );
return 0;
}
//**********************************************************************************************************
//* ow mode
//**********************************************************************************************************
/**
* @brief parasite enable
* @date 20/06/2011
*/
uint8_t ow_parasite_enable(void) {
ow_pin.output();
ow_pin = 1;
return 0;
}
/**
* @brief parasite disable
* @date 20/06/2011
*/
uint8_t ow_parasite_disable(void) {
ow_pin.input();
return 0;
}
/**
* @brief parasite enable
* @param [in] n num bus onewire
* @date 30/08/2011
*/
uint8_t ow_parasite_enable(uint8_t n) {
t_ow[n]->output();
*t_ow[n] = 1;
return 0;
}
/**
* @brief parasite disable
* @param [in] n num bus onewire
* @date 30/08/2011
*/
uint8_t ow_parasite_disable(uint8_t n) {
t_ow[n]->input();
return 0;
}
/**
* @brief PUL-UP bus OW
* @return OW_OK
* @date 20/06/2011
*/
uint8_t ow_PullUp(void)
{
ow_pin.mode(PullUp); //PULL-UP bus OW
return OW_OK;
}
/**
* @brief PUL-UP bus OW
* @param [in] n num bus onewire
* @return OW_OK
* @date 30/08/2011
*/
uint8_t ow_PullUp(uint8_t n)
{
t_ow[n]->mode(PullUp); //PULL-UP bus OW
return OW_OK;
}
frederic blanc