OneWire DS18B20,DS2450,MAX31850
Dependents: MAX31850_HelloWorld
Revision 0:9acbbb021a43, committed 2015-02-12
- Comitter:
- fblanc
- Date:
- Thu Feb 12 14:03:55 2015 +0000
- Commit message:
- MAX31850 ok
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DS18X20.cpp Thu Feb 12 14:03:55 2015 +0000 @@ -0,0 +1,350 @@ +/** +* @file DS18x20.c +* @brief library of DS18X20 1-Wire digital thermometer (http://www.maxim-ic.com/datasheet/index.mvp/id/2812) +* @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" +#include "DS18X20.h" +#include "crc8.h" +#include "utils.h" +//********************************************************************************************************** +//* DS18X20_show_temp +//********************************************************************************************************** + +/** +* @brief DS18X20_show_temp +* @param [in] id[] = rom_code +* @param [in] n number of id[n] +* @param [out] text temp in degre celsius + +* @date 20/06/2011 +*/ +void DS18X20_show_temp(uint8_t subzero, uint8_t cel, uint8_t cel_frac_bits,char *text) { + uint16_t decicelsius; + char s[10]; + float temperature; + sprintf(text,""); + sprintf(s,"%s", (subzero)?"-":""); + strcat(text,s); + decicelsius = DS18X20_temp_to_decicel(subzero, cel, cel_frac_bits); + temperature = decicelsius; + temperature = temperature/10; + sprintf(s,"%4.1f", temperature); + strcat(text,s); + +} +/** +* @brief DS18X20_show_temp +* @param [in] id[] = rom_code +* @param [in] n number of id[n] +* @return temp in degre celsius + +* @date 21/10/2011 +*/ +float DS18X20_temp(uint8_t subzero, uint8_t cel, uint8_t cel_frac_bits) { + return ((subzero)?-1:1)*DS18X20_temp_to_decicel(subzero, cel, cel_frac_bits)/10; +} +//********************************************************************************************************** +//* DS18X20_get_power_status +//********************************************************************************************************** + +/** +* @brief get power status of DS18x20 +* @param [in] id[] = rom_code +* @return DS18X20_POWER_EXTERN or DS18X20_POWER_PARASITE +* @date 20/06/2011 +*/ +uint8_t DS18X20_get_power_status(uint8_t id[]) { + uint8_t pstat; + ow_reset(); + ow_command(DS18X20_READ_POWER_SUPPLY, id); + pstat=ow_bit_io(1); // pstat 0=is parasite/ !=0 ext. powered + ow_reset(); + return (pstat) ? DS18X20_POWER_EXTERN:DS18X20_POWER_PARASITE; +} + +/** +* @brief get power status of DS18x20 +* @param [in] n num bus onewire +* @param [in] id[] = rom_code +* @return DS18X20_POWER_EXTERN or DS18X20_POWER_PARASITE +* @date 6/09/2011 +*/ +uint8_t DS18X20_get_power_status(uint8_t n,uint8_t id[]) { + uint8_t pstat; + ow_reset(n); + ow_command(n,DS18X20_READ_POWER_SUPPLY, id); + pstat=ow_bit_io(n,1); // pstat 0=is parasite/ !=0 ext. powered + ow_reset(n); + return (pstat) ? DS18X20_POWER_EXTERN:DS18X20_POWER_PARASITE; +} +//********************************************************************************************************** +//* DS18X20_start_meas +//********************************************************************************************************** +/** +* @brief reads temperature (scratchpad) of sensor with rom-code id + output: subzero==1 if temp.<0, cel: full celsius, mcel: frac + in millicelsius*0.1 + i.e.: subzero=1, cel=18, millicel=5000 = -18,5000�C +* @param [in] n num bus onewire +* @param [in] id[] = rom_code +* @param [out] temperature +* @return DS18X20_OK or DS18X20_ERROR_CRC +* @date 07/12/2012 +*/ +uint8_t DS18X20_read_meas(uint8_t n,uint8_t id[], float* temperature) { + uint8_t i; + uint8_t sp[DS18X20_SP_SIZE]; + uint8_t subzero; + uint8_t cel; + uint8_t cel_frac_bits; + + ow_reset(n); + ow_command(n,DS18X20_READ, id); + for ( i=0 ; i< DS18X20_SP_SIZE; i++ ) + sp[i]=ow_byte_rd(n); + if ( crc8( &sp[0], DS18X20_SP_SIZE ) ){ + if ((sp[DS18X20_SP_SIZE-1]==0xFF) && (sp[DS18X20_SP_SIZE-2]==0xFF)) + return OW_ERROR; // bus error + return DS18X20_ERROR_CRC; // data error + } + + DS18X20_meas_to_cel(id[0], sp, &subzero, &cel, &cel_frac_bits); + *temperature = cel_frac_bits*.0625; + *temperature += cel; + if (subzero) + *temperature *= -1; + return DS18X20_OK; +} +/** +* @brief start measurement (CONVERT_T) for all sensors if input id==NULL + or for single sensor. then id is the rom-code +* @param [in] with_power_extern +* @param [in] rom_code +* @return DS18X20_OK or DS18X20_START_FAIL +* @date 20/06/2011 +*/ +uint8_t DS18X20_start_meas( uint8_t with_power_extern, uint8_t id[]) { + ow_reset(); //** + if ( ow_test_pin() ) { // only send if bus is "idle" = high + ow_command( DS18X20_CONVERT_T, id ); + if (with_power_extern != DS18X20_POWER_EXTERN) + ow_parasite_enable(); + return DS18X20_OK; + } + return DS18X20_START_FAIL; + +} +/** +* @brief start measurement (CONVERT_T) for all sensors if input id==NULL + or for single sensor. then id is the rom-code +* @param [in] n num bus onewire +* @param [in] with_power_extern +* @param [in] rom_code +* @return DS18X20_OK or DS18X20_START_FAIL +* @date 06/09/2011 +*/ +uint8_t DS18X20_start_meas(uint8_t n, uint8_t with_power_extern, uint8_t id[]) { + ow_reset(n); //** + if ( ow_test_pin(n) ) { // only send if bus is "idle" = high + ow_command(n, DS18X20_CONVERT_T, id ); + if (with_power_extern != DS18X20_POWER_EXTERN) + ow_parasite_enable(n); + return DS18X20_OK; + } + return DS18X20_START_FAIL; + +} +//********************************************************************************************************** +//* DS18X20_read_meas +//********************************************************************************************************** + +/** +* @brief reads temperature (scratchpad) of sensor with rom-code id + output: subzero==1 if temp.<0, cel: full celsius, mcel: frac + in millicelsius*0.1 + i.e.: subzero=1, cel=18, millicel=5000 = -18,5000�C +* @param [in] id[] = rom_code +* @param [out] subzero +* @param [out] cel +* @param [out] cel_frac_bits +* @return DS18X20_OK or DS18X20_ERROR_CRC +* @date 20/06/2011 +*/ +uint8_t DS18X20_read_meas(uint8_t id[], uint8_t *subzero, + uint8_t *cel, uint8_t *cel_frac_bits) { + uint8_t i; + uint8_t sp[DS18X20_SP_SIZE]; + + ow_reset(); + ow_command(DS18X20_READ, id); + for ( i=0 ; i< DS18X20_SP_SIZE; i++ ) + sp[i]=ow_byte_rd(); + if ( crc8( &sp[0], DS18X20_SP_SIZE ) ){ + if ((sp[DS18X20_SP_SIZE-1]==0xFF) && (sp[DS18X20_SP_SIZE-2]==0xFF)) + return OW_ERROR; // bus error + return DS18X20_ERROR_CRC; // data error + } + + DS18X20_meas_to_cel(id[0], sp, subzero, cel, cel_frac_bits); + return DS18X20_OK; +} +/** +* @brief reads temperature (scratchpad) of sensor with rom-code id + output: subzero==1 if temp.<0, cel: full celsius, mcel: frac + in millicelsius*0.1 + i.e.: subzero=1, cel=18, millicel=5000 = -18,5000�C +* @param [in] n num bus onewire +* @param [in] id[] = rom_code +* @param [out] subzero +* @param [out] cel +* @param [out] cel_frac_bits +* @return DS18X20_OK or DS18X20_ERROR_CRC +* @date 06/09/2011 +*/ +uint8_t DS18X20_read_meas(uint8_t n,uint8_t id[], uint8_t *subzero, + uint8_t *cel, uint8_t *cel_frac_bits) { + uint8_t i; + uint8_t sp[DS18X20_SP_SIZE]; + + ow_reset(n); + ow_command(n,DS18X20_READ, id); + for ( i=0 ; i< DS18X20_SP_SIZE; i++ ) + sp[i]=ow_byte_rd(n); + if ( crc8( &sp[0], DS18X20_SP_SIZE ) ){ + if ((sp[DS18X20_SP_SIZE-1]==0xFF) && (sp[DS18X20_SP_SIZE-2]==0xFF)) + return OW_ERROR; // bus error + return DS18X20_ERROR_CRC; // data error + } + + DS18X20_meas_to_cel(id[0], sp, subzero, cel, cel_frac_bits); + return DS18X20_OK; +} +/** +* @brief convert raw value from DS18x20 to Celsius + input is: + - familycode fc (0x10/0x28 see header) + - scratchpad-buffer + output is: + - cel full celsius + - fractions of celsius in millicelsius*(10^-1)/625 (the 4 LS-Bits) + - subzero =0 positiv / 1 negativ + always returns DS18X20_OK + TODO invalid-values detection (but should be covered by CRC) +* @param [in] fc +* @param [in] sp +* @param [out] subzero +* @param [out] cel +* @param [out] cel_frac_bits +* @return DS18X20_OK +* @date 20/06/2011 +*/ +uint8_t DS18X20_meas_to_cel( uint8_t fc, uint8_t *sp, + uint8_t* subzero, uint8_t* cel, uint8_t* cel_frac_bits) { + uint16_t meas; + uint8_t i; + + meas = sp[0]; // LSB + meas |= ((uint16_t)sp[1])<<8; // MSB + //meas = 0xff5e; meas = 0xfe6f; + + // only work on 12bit-base + if ( fc == DS18S20_ID ) { // 9 -> 12 bit if 18S20 + /* Extended measurements for DS18S20 contributed by Carsten Foss */ + meas &= (uint16_t) 0xfffe; // Discard LSB , needed for later extended precicion calc + meas <<= 3; // Convert to 12-bit , now degrees are in 1/16 degrees units + meas += (16 - sp[6]) - 4; // Add the compensation , and remember to subtract 0.25 degree (4/16) + } + + // check for negative + if ( meas & 0x8000 ) { + *subzero=1; // mark negative + meas ^= 0xffff; // convert to positive => (twos complement)++ + meas++; + } else *subzero=0; + + // clear undefined bits for B != 12bit + if ( fc == DS18B20_ID ) { // check resolution 18B20 + i = sp[DS18B20_CONF_REG]; + if ( (i & DS18B20_12_BIT) == DS18B20_12_BIT ) ; + else if ( (i & DS18B20_11_BIT) == DS18B20_11_BIT ) + meas &= ~(DS18B20_11_BIT_UNDF); + else if ( (i & DS18B20_10_BIT) == DS18B20_10_BIT ) + meas &= ~(DS18B20_10_BIT_UNDF); + else { // if ( (i & DS18B20_9_BIT) == DS18B20_9_BIT ) { + meas &= ~(DS18B20_9_BIT_UNDF); + } + } + + *cel = (uint8_t)(meas >> 4); + *cel_frac_bits = (uint8_t)(meas & 0x000F); + + return DS18X20_OK; +} + +/** +* @brief converts to decicelsius + input is ouput from meas_to_cel + i.e.: sz=0, c=28, frac=15 returns 289 (=28.9�C) +0 0 0 +1 625 625 1 +2 1250 250 +3 1875 875 3 +4 2500 500 4 +5 3125 125 +6 3750 750 6 +7 4375 375 +8 5000 0 +9 5625 625 9 +10 6250 250 +11 6875 875 11 +12 7500 500 12 +13 8125 125 +14 8750 750 14 +15 9375 375 +* @param [in] subzero +* @param [in] cel +* @param [in] cel_frac_bits +* @return absolute value of temperatur in decicelsius +* @date 20/06/2011 +*/ +uint16_t DS18X20_temp_to_decicel(uint8_t subzero, uint8_t cel, + uint8_t cel_frac_bits) { + uint16_t h; + uint8_t i; + uint8_t need_rounding[] = { 1, 3, 4, 6, 9, 11, 12, 14 }; + + h = cel_frac_bits*DS18X20_FRACCONV/1000; + h += cel*10; + if (!subzero) { + for (i=0; i<sizeof(need_rounding); i++) { + if ( cel_frac_bits == need_rounding[i] ) { + h++; + break; + } + } + } + return h; +} +/** +* @brief compare temperature values (full celsius only) +* @param [in] subzero1 +* @param [in] cel1 +* @param [in] subzero2 +* @param [in] cel2 +* @return -1 if param-pair1 < param-pair2 + 0 if == + 1 if > +* @date 20/06/2011 +*/ +int8_t DS18X20_temp_cmp(uint8_t subzero1, uint16_t cel1, + uint8_t subzero2, uint16_t cel2) { + int16_t t1 = (subzero1) ? (cel1*(-1)) : (cel1); + int16_t t2 = (subzero2) ? (cel2*(-1)) : (cel2); + + if (t1<t2) return -1; + if (t1>t2) return 1; + return 0; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DS18X20.h Thu Feb 12 14:03:55 2015 +0000 @@ -0,0 +1,66 @@ +/* DS18X20 specific values (see datasheet www.maxim-ic.com/datasheet/index.mvp/id/2812) */ +#ifndef _DS18X20_ +#define _DS18X20_ +#define DS18S20_ID 0x10 +#define DS18B20_ID 0x28 + +#define DS18X20_POWER_PARASITE 0x00 +#define DS18X20_POWER_EXTERN 0x01 +#define DS18X20_CONVERT_T 0x44 +#define DS18X20_READ 0xBE +#define DS18X20_WRITE 0x4E +#define DS18X20_EE_WRITE 0x48 +#define DS18X20_EE_RECALL 0xB8 +#define DS18X20_READ_POWER_SUPPLY 0xB4 + +#define DS18X20_OK 0x00 +#define DS18X20_ERROR 0x01 +#define DS18X20_START_FAIL 0x02 +#define DS18X20_ERROR_CRC 0x03 + +#define DS18B20_CONF_REG 4 +#define DS18B20_9_BIT 0 +#define DS18B20_10_BIT (1<<5) +#define DS18B20_11_BIT (1<<6) +#define DS18B20_12_BIT ((1<<6)|(1<<5)) + +// indefined bits in LSB if 18B20 != 12bit +#define DS18B20_9_BIT_UNDF ((1<<0)|(1<<1)|(1<<2)) +#define DS18B20_10_BIT_UNDF ((1<<0)|(1<<1)) +#define DS18B20_11_BIT_UNDF ((1<<0)) +#define DS18B20_12_BIT_UNDF 0 + +// conversion times in ms +#define DS18B20_TCONV_12BIT 750 +#define DS18B20_TCONV_11BIT DS18B20_TCONV_12_BIT/2 +#define DS18B20_TCONV_10BIT DS18B20_TCONV_12_BIT/4 +#define DS18B20_TCONV_9BIT DS18B20_TCONV_12_BIT/8 +#define DS18S20_TCONV DS18B20_TCONV_12_BIT + +// constant to convert the fraction bits to cel*(10^-4) +#define DS18X20_FRACCONV 625 + +#define DS18X20_SP_SIZE 9 + +// DS18X20 EEPROM-Support +#define DS18X20_WRITE_SCRATCHPAD 0x4E +#define DS18X20_COPY_SCRATCHPAD 0x48 +#define DS18X20_RECALL_E2 0xB8 +#define DS18X20_COPYSP_DELAY 10 /* ms */ +#define DS18X20_TH_REG 2 +#define DS18X20_TL_REG 3 + +void DS18X20_show_temp(uint8_t subzero, uint8_t cel, uint8_t cel_frac_bits,char *text); +float DS18X20_temp(uint8_t subzero, uint8_t cel, uint8_t cel_frac_bits); +uint8_t DS18X20_get_power_status(uint8_t id[]); +uint8_t DS18X20_get_power_status(uint8_t n,uint8_t id[]); +uint8_t DS18X20_start_meas( uint8_t with_external, uint8_t id[]); +uint8_t DS18X20_start_meas(uint8_t n, uint8_t with_external, uint8_t id[]); +uint8_t DS18X20_read_meas(uint8_t id[], uint8_t *subzero, uint8_t *cel, uint8_t *cel_frac_bits); +uint8_t DS18X20_read_meas(uint8_t n, uint8_t id[], uint8_t *subzero, uint8_t *cel, uint8_t *cel_frac_bits); +uint8_t DS18X20_read_meas_single(uint8_t familycode, uint8_t *subzero, uint8_t *cel, uint8_t *cel_frac_bits); +uint8_t DS18X20_meas_to_cel( uint8_t fc, uint8_t *sp, uint8_t* subzero, uint8_t* cel, uint8_t* cel_frac_bits); +uint8_t DS18X20_read_meas(uint8_t n,uint8_t id[], float* temperature); +uint16_t DS18X20_temp_to_decicel(uint8_t subzero, uint8_t cel, uint8_t cel_frac_bits); +int8_t DS18X20_temp_cmp(uint8_t subzero1, uint16_t cel1, uint8_t subzero2, uint16_t cel2); +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DS2450.cpp Thu Feb 12 14:03:55 2015 +0000 @@ -0,0 +1,464 @@ +/** +* @file DS2450.c +* @brief library of DS2450 1-Wire Quad A/D Converter (http://www.maxim-ic.com/datasheet/index.mvp/id/2921) +* @author Frederic BLANC (Published 01/03/2012 www.mbed.org) +*/ +#include "mbed.h" +#include "onewire.h" +#include "DS2450.h" +#include "crc8.h" +#include "crc16.h" +#include "utils.h" +//********************************************************************************************************** +//* DS2450_read_ADC +//********************************************************************************************************** + +/** + * @brief lancement lecture DS2450 ADC + * @param [in] id[] tableau d'identifiant OW + * @param [out] adc[] tableau des valeurs des adc + * @return OW_OK si erreur retourne OW_ERROR_CRC + * @date 20/06/2011 + * + */ +uint8_t DS2450_read_ADC(uint8_t id[], uint16_t adc[]) { + uint8_t i,j; + uint8_t error; + uint8_t sp[DS2450_SP_SIZE]; + //waiting for convertion time ( nbchannel x resolution x 80�s +160�s) + + error=DS2450_read_page(&id[0],DS2450_PAGE0,&sp[0]); //read data + if (error) + return error; + j=0; + for (i=0;i<8;i+=2) + adc[j++]=uint8_to_uint16(sp[i+3],sp[i+4]); //sp[i+3] LSB ,sp[i+4] MSB + return OW_OK; +} + + +/** + * @brief lancement lecture DS2450 ADC + * @param [in] n num bus onewire + * @param [in] id[] tableau d'identifiant OW + * @param [out] adc[] tableau des valeurs des adc + * @return OW_OK si erreur retourne OW_ERROR_CRC + * @date 07/09/2011 + * + */ +uint8_t DS2450_read_ADC(uint8_t n,uint8_t id[], uint16_t adc[]) { + uint8_t i,j; + uint8_t error; + uint8_t sp[DS2450_SP_SIZE]; + //waiting for convertion time ( nbchannel x resolution x 80�s +160�s) + + error=DS2450_read_page(n,&id[0],DS2450_PAGE0,&sp[0]); //read data + if (error) + return error; + j=0; + for (i=0;i<8;i+=2) + adc[j++]=uint8_to_uint16(sp[i+3],sp[i+4]); //sp[i+3] LSB ,sp[i+4] MSB + return OW_OK; +} +//********************************************************************************************************** +//* DS2450_start_and_read_ADC +//********************************************************************************************************** + +/** + * @brief lancement & lecture DS2450 ADC + * @param [in] id[] tableau d'identifiant OW + * @param [out] adc[] tableau des valeurs des adc + * @return OW_OK si erreur retourne OW_ERROR_CRC + * @date 20/06/2011 + * + */ +uint8_t DS2450_start_and_read_ADC(uint8_t id[], uint16_t adc[]) { + uint8_t i,j; + uint8_t error; + uint8_t sp[DS2450_SP_SIZE]; + + error=DS2450_convert(&id[0],0x0F,0x00); //start convert + if (error) + return error; + + wait_ms(15); //waiting for convertion time ( nbchannel x resolution x 80�s +160�s) + + error=DS2450_read_page(&id[0],DS2450_PAGE0,&sp[0]); //read data + if (error) + return error; + + j=0; + for (i=0;i<8;i+=2) + adc[j++]=uint8_to_uint16(sp[i+3],sp[i+4]); //sp[i+3] LSB ,sp[i+4] MSB + return OW_OK; +} + +/** + * @brief lancement & lecture DS2450 ADC + * @param [in] n num bus onewire + * @param [in] id[] tableau d'identifiant OW + * @param [out] adc[] tableau des valeurs des adc + * @return OW_OK si erreur retourne OW_ERROR_CRC + * @date 07/09/2011 + * + */ +uint8_t DS2450_start_and_read_ADC(uint8_t n,uint8_t id[], uint16_t adc[]) { + uint8_t i,j; + uint8_t error; + uint8_t sp[DS2450_SP_SIZE]; + + error=DS2450_convert(n,&id[0],0x0F,0x00); //start convert + if (error) + return error; + + wait_ms(15); //waiting for convertion time ( nbchannel x resolution x 80�s +160�s) + + error=DS2450_read_page(n,&id[0],DS2450_PAGE0,&sp[0]); //read data + if (error) + return error; + + j=0; + for (i=0;i<8;i+=2) + adc[j++]=uint8_to_uint16(sp[i+3],sp[i+4]); //sp[i+3] LSB ,sp[i+4] MSB + return OW_OK; +} + +//********************************************************************************************************** +//* DS2450_read_page +//********************************************************************************************************** + +/** + * @brief lancement lecture page DS2450 ADC + * @param [in] id[] tableau d'identifiant OW + * @param [in] adresse de la page a lire + * @param [out] uint16_t sp tableau des valeurs de la page + * @return OW_OK si erreur retourne OW_ERROR_CRC + * @date 20/06/2011 + * + */ +uint8_t DS2450_read_page(uint8_t id[], uint8_t adresse, + uint8_t *sp) { + uint8_t i; + if (id[0] == DS2450_ID) { + if (ow_reset()) //reset OW + return OW_SHORT_CIRCUIT; + sp[0]=DS2450_READ_MEMORY; // command + sp[1]=adresse; //adress page LSB + sp[2]=0; //adress page MSB + ow_command(sp[0], &id[0]); + ow_byte_wr(sp[1]); + ow_byte_wr(sp[2]); + + for ( i=3 ; i< DS2450_SP_SIZE; i++ ) { //read 8xdata + CRC16 + sp[i]=ow_byte_rd(); + } + + if (ctrl_crc16( &sp[0], DS2450_SP_SIZE ) ) { //CRC16 (command+adress page LSB+adress page MSB+8xdata) + wait_ms(100); //wait 100ms if error + if ((sp[DS2450_SP_SIZE-1]==0xFF) && (sp[DS2450_SP_SIZE-2]==0xFF)) + return OW_ERROR; // bus error + if ((sp[DS2450_SP_SIZE-1]==0x00) && (sp[DS2450_SP_SIZE-2]==0x00)) + return OW_BUSY; + + return OW_ERROR_CRC; // data error + } + return OW_OK; + } + return OW_ERROR_BAD_ID; +} +/** + * @brief lancement lecture page DS2450 ADC + * @param [in] n num bus onewire + * @param [in] id[] tableau d'identifiant OW + * @param [in] adresse de la page a lire + * @param [out] sp tableau des valeurs de la page + * @return OW_OK si erreur retourne OW_ERROR_CRC + * @date 07/09/2011 + * + */ +uint8_t DS2450_read_page(uint8_t n,uint8_t id[], uint8_t adresse, + uint8_t *sp) { + uint8_t i; + if (id[0] == DS2450_ID) { + if (ow_reset(n)) //reset OW + return OW_SHORT_CIRCUIT; + sp[0]=DS2450_READ_MEMORY; // command + sp[1]=adresse; //adress page LSB + sp[2]=0; //adress page MSB + ow_command(n,sp[0], &id[0]); + ow_byte_wr(n,sp[1]); + ow_byte_wr(n,sp[2]); + + for ( i=3 ; i< DS2450_SP_SIZE; i++ ) { //read 8xdata + CRC16 + sp[i]=ow_byte_rd(n); + } + + if (ctrl_crc16( &sp[0], DS2450_SP_SIZE ) ) { //CRC16 (command+adress page LSB+adress page MSB+8xdata) + wait_ms(100); //wait 100ms if error + if ((sp[DS2450_SP_SIZE-1]==0xFF) && (sp[DS2450_SP_SIZE-2]==0xFF)) + return OW_ERROR; // bus error + if ((sp[DS2450_SP_SIZE-1]==0x00) && (sp[DS2450_SP_SIZE-2]==0x00)) + return OW_BUSY; + + return OW_ERROR_CRC; // data error + } + return OW_OK; + } + return OW_ERROR_BAD_ID; +} +//********************************************************************************************************** +//* DS2450_convert +//********************************************************************************************************** + +/** + * @brief lancement convertion DS2450 ADC + * @param [in] uint8_t id[] tableau d'identifiant OW + * @param [in] uint8_t input_select_mask + * @param [in] uint8_t read_out_control + * @return OW_OK si erreur retourne OW_ERROR_CRC + * @date 20/06/2011 + * + */ +uint8_t DS2450_convert(uint8_t id[], uint8_t input_select_mask,uint8_t read_out_control) { + uint8_t i; + uint8_t sp[5]; + if (id[0] == DS2450_ID) { + if (ow_reset()) //reset OW + return OW_SHORT_CIRCUIT; + sp[0]=DS2450_CONVERT; // command + sp[1]=input_select_mask; //mask + sp[2]=read_out_control; //control + ow_command(sp[0], &id[0]); + ow_byte_wr(sp[1]); + ow_byte_wr(sp[2]); + for ( i=3 ; i< 5; i++ ) { // read CRC16 + sp[i]=ow_byte_rd(); + } + + if (ctrl_crc16( &sp[0], 5 ) ) { //CRC16 (command+mask LSB+control) + if ((sp[3]==0xFF) && (sp[3]==0xFF)) + return OW_ERROR; + return OW_ERROR_CRC; + } + return OW_OK; + } + return OW_ERROR_BAD_ID; +} +/** + * @brief lancement convertion DS2450 ADC + * @param [in] n num bus onewire + * @param [in] uint8_t id[] tableau d'identifiant OW + * @param [in] uint8_t input_select_mask + * @param [in] uint8_t read_out_control + * @return OW_OK si erreur retourne OW_ERROR_CRC + * @date 07/09/2011 + * + */ +uint8_t DS2450_convert(uint8_t n,uint8_t id[], uint8_t input_select_mask,uint8_t read_out_control) { + uint8_t i; + uint8_t sp[5]; + if (id[0] == DS2450_ID) { + if (ow_reset(n)) //reset OW + return OW_SHORT_CIRCUIT; + sp[0]=DS2450_CONVERT; // command + sp[1]=input_select_mask; //mask + sp[2]=read_out_control; //control + ow_command(n,sp[0], &id[0]); + ow_byte_wr(n,sp[1]); + ow_byte_wr(n,sp[2]); + for ( i=3 ; i< 5; i++ ) { // read CRC16 + sp[i]=ow_byte_rd(n); + } + + if (ctrl_crc16( &sp[0], 5 ) ) { //CRC16 (command+mask LSB+control) + if ((sp[3]==0xFF) && (sp[3]==0xFF)) + return OW_ERROR; + return OW_ERROR_CRC; + } + return OW_OK; + } + return OW_ERROR_BAD_ID; +} + +//********************************************************************************************************** +//* DS2450_configure_channel_ADC +//********************************************************************************************************** + +/** + * @brief configure canal ADC DS2450 + * @param [in] id[] tableau d'identifiant OW + * @param [in] channel + * @param [in] conflsb configuration OE-A OC-A 0 0 RC3-A RC2-A RC1-A RC0-A + * @param [in] confmsb configuration POR 0 AFH-A AFL-A AEH-A AEL-A 0 IR-A + * @return OW_OK si erreur retourne OW_ERROR_CRC + * @date 20/06/2011 + * + */ +uint8_t DS2450_configure_channel_ADC(uint8_t id[],uint8_t channel,uint8_t conflsb,uint8_t confmsb) { + uint8_t i; + uint8_t sp[7]; + if (id[0] == DS2450_ID) { + if (ow_reset()) //reset OW + return OW_SHORT_CIRCUIT; + sp[0]=DS2450_WRITE_MEMORY; // command + sp[1]=DS2450_PAGE1+channel; //adress page LSB + sp[2]=0x00; //adress page MSB + sp[3]=conflsb; //databyte + ow_command(sp[0], &id[0]); + ow_byte_wr(sp[1]); + ow_byte_wr(sp[2]); + ow_byte_wr(sp[3]); + for ( i=4 ; i< 7; i++ ) { //read CRC16+databyte + sp[i]=ow_byte_rd(); + } + + if (ctrl_crc16( &sp[0], 6 ) ) //CRC16 (command+adress page LSB+adress page MSB+databyte) + return OW_ERROR_CRC; + sp[3]=confmsb; //databyte + ow_byte_wr(sp[3]); + for ( i=4 ; i< 7; i++ ) { //read CRC16+databyte + sp[i]=ow_byte_rd(); + } + + if (sp[3]!=sp[6] ) //control data + return OW_ERROR_CRC; + return OW_OK; + } + return OW_ERROR_BAD_ID; +} +/** + * @brief configure canal ADC DS2450 + * @param [in] n num bus onewire + * @param [in] id[] tableau d'identifiant OW + * @param [in] channel + * @param [in] conflsb configuration OE-A OC-A 0 0 RC3-A RC2-A RC1-A RC0-A + * @param [in] confmsb configuration POR 0 AFH-A AFL-A AEH-A AEL-A 0 IR-A + * @return OW_OK si erreur retourne OW_ERROR_CRC + * @date 20/06/2011 + * + */ +uint8_t DS2450_configure_channel_ADC(uint8_t n,uint8_t id[],uint8_t channel,uint8_t conflsb,uint8_t confmsb) { + uint8_t i; + uint8_t sp[7]; + if (id[0] == DS2450_ID) { + if (ow_reset(n)) //reset OW + return OW_SHORT_CIRCUIT; + sp[0]=DS2450_WRITE_MEMORY; // command + sp[1]=DS2450_PAGE1+channel; //adress page LSB + sp[2]=0x00; //adress page MSB + sp[3]=conflsb; //databyte + ow_command(n,sp[0], &id[0]); + ow_byte_wr(n,sp[1]); + ow_byte_wr(n,sp[2]); + ow_byte_wr(n,sp[3]); + for ( i=4 ; i< 7; i++ ) { //read CRC16+databyte + sp[i]=ow_byte_rd(n); + } + + if (ctrl_crc16( &sp[0], 6 ) ) //CRC16 (command+adress page LSB+adress page MSB+databyte) + return OW_ERROR_CRC; + sp[3]=confmsb; //databyte + ow_byte_wr(n,sp[3]); + for ( i=4 ; i< 7; i++ ) { //read CRC16+databyte + sp[i]=ow_byte_rd(n); + } + + if (sp[3]!=sp[6] ) //control data + return OW_ERROR_CRC; + return OW_OK; + } + return OW_ERROR_BAD_ID; +} +//********************************************************************************************************** +//* DS2450_configure_channel_ADC +//********************************************************************************************************** + +/** + * @brief configure PAGE + * @param [in] id[] tableau d'identifiant OW + * @param [in] uint8_t adresse de la page a ecrire + * @param [in] config_page tableau de 8 byte + * @return OW_OK si erreur retourne OW_ERROR_CRC + * @date 20/06/2011 + * + */ +uint8_t DS2450_configure_page(uint8_t id[], uint8_t adresse,uint8_t configpage[]) { + uint8_t i,j; + uint8_t sp[7]; + if (id[0] == DS2450_ID) { + if (ow_reset()) //reset OW + return OW_SHORT_CIRCUIT; + sp[0]=DS2450_WRITE_MEMORY; // command + sp[1]=adresse; //adress page LSB + sp[2]=0x00; //adress page MSB + sp[3]=configpage[0]; //databyte + ow_command(sp[0], &id[0]); + ow_byte_wr(sp[1]); + ow_byte_wr(sp[2]); + ow_byte_wr(sp[3]); + for ( i=4 ; i< 7; i++ ) { //read CRC16+databyte + sp[i]=ow_byte_rd(); + } + + if (sp[3]!=sp[6] ) //control data + return OW_ERROR_CRC; + + for ( j=1 ; j< 7; j++ ) { + sp[3]=configpage[j]; //databyte + ow_byte_wr(sp[3]); + for ( i=4 ; i< 7; i++ ) { //read CRC16+databyte + sp[i]=ow_byte_rd(); + } + if (sp[3]!=sp[6] ) //control data + return OW_ERROR_CRC; + + } + return OW_OK; + } + return OW_ERROR_BAD_ID; +} +/** + * @brief configure PAGE + * @param [in] n num bus onewire + * @param [in] id[] tableau d'identifiant OW + * @param [in] uint8_t adresse de la page a ecrire + * @param [in] config_page tableau de 8 byte + * @return OW_OK si erreur retourne OW_ERROR_CRC + * @date 07/09/2011 + * + */ +uint8_t DS2450_configure_page(uint8_t n,uint8_t id[], uint8_t adresse,uint8_t configpage[]) { + uint8_t i,j; + uint8_t sp[7]; + if (id[0] == DS2450_ID) { + if (ow_reset(n)) //reset OW + return OW_SHORT_CIRCUIT; + sp[0]=DS2450_WRITE_MEMORY; // command + sp[1]=adresse; //adress page LSB + sp[2]=0x00; //adress page MSB + sp[3]=configpage[0]; //databyte + ow_command(n,sp[0], &id[0]); + ow_byte_wr(n,sp[1]); + ow_byte_wr(n,sp[2]); + ow_byte_wr(n,sp[3]); + for ( i=4 ; i< 7; i++ ) { //read CRC16+databyte + sp[i]=ow_byte_rd(n); + } + + if (sp[3]!=sp[6] ) //control data + return OW_ERROR_CRC; + + for ( j=1 ; j< 7; j++ ) { + sp[3]=configpage[j]; //databyte + ow_byte_wr(n,sp[3]); + for ( i=4 ; i< 7; i++ ) { //read CRC16+databyte + sp[i]=ow_byte_rd(n); + } + if (sp[3]!=sp[6] ) //control data + return OW_ERROR_CRC; + + } + return OW_OK; + } + return OW_ERROR_BAD_ID; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DS2450.h Thu Feb 12 14:03:55 2015 +0000 @@ -0,0 +1,47 @@ +/* DS2450 specific values (see datasheet www.maxim-ic.com/datasheet/index.mvp/id/2921) */ +#ifndef _DS2450_ +#define _DS2450_ +#define DS2450_ID 0x20 +#define DS2450_READ_MEMORY 0xAA +#define DS2450_WRITE_MEMORY 0x55 +#define DS2450_CONVERT 0x3C + +#define DS2450_SP_SIZE 13 +#define DS2450_PAGE0 0x00 +#define DS2450_PAGE1 0x08 +#define DS2450_PAGE2 0x10 +#define DS2450_PAGE3 0x18 + +#define DS2450_ADCA 0x00 //channel A +#define DS2450_ADCB 0x02 //channel B +#define DS2450_ADCC 0x04 //channel C +#define DS2450_ADCD 0x06 //channel D + +#define DS2450_IR_2V5 0x00 //input voltage range 2.55V +#define DS2450_IR_5V1 0x01 //input voltage range 5.1V +#define DS2450_AFH 0x20 //flag alarm value higher +#define DS2450_AFL 0x10 //flag alarm value lower +#define DS2450_AEH_ENABLE 0x08 //alarm value higher enable +#define DS2450_AEL_ENABLE 0x04 //alarm value lower enable + +#define DS2450_DISABLE_OUT 0x00 //disable ouput +#define DS2450_ENABLE_OUT 0x80//enable ouput + +#define DS2450_16_BIT 0x00 //ADC 16bits enable ouput +#define DS2450_15_BIT 0x0F //ADC 15bits enable ouput +#define DS2450_12_BIT 0x0C //ADC 12bits enable ouput +#define DS2450_8_BIT 0x08 //ADC 8bits enable ouput +#define DS2450_1_BIT 0x01 //ADC 1bits enable ouput +uint8_t DS2450_read_page(uint8_t id[], uint8_t adresse, uint8_t *val); +uint8_t DS2450_read_page(uint8_t n,uint8_t id[], uint8_t adresse, uint8_t *val); +uint8_t DS2450_convert(uint8_t id[], uint8_t input_select_mask,uint8_t read_out_control); +uint8_t DS2450_convert(uint8_t n,uint8_t id[], uint8_t input_select_mask,uint8_t read_out_control); +uint8_t DS2450_read_ADC(uint8_t id[], uint16_t adc[]); +uint8_t DS2450_read_ADC(uint8_t n,uint8_t id[], uint16_t adc[]); +uint8_t DS2450_start_and_read_ADC(uint8_t id[], uint16_t adc[]); +uint8_t DS2450_start_and_read_ADC(uint8_t n,uint8_t id[], uint16_t adc[]); +uint8_t DS2450_configure_channel_ADC(uint8_t id[],uint8_t channel,uint8_t conflsb,uint8_t confmsb); +uint8_t DS2450_configure_channel_ADC(uint8_t n,uint8_t id[],uint8_t channel,uint8_t conflsb,uint8_t confmsb); +uint8_t DS2450_configure_page(uint8_t id[], uint8_t adresse,uint8_t configpage[]); +uint8_t DS2450_configure_page(uint8_t n,uint8_t id[], uint8_t adresse,uint8_t configpage[]); +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Horner_ITS90.h Thu Feb 12 14:03:55 2015 +0000 @@ -0,0 +1,49 @@ +#ifndef __Horner_ITS90_H__ +#define __Horner_ITS90_H__ + +const double ITS90_TCK_subzero[] = +{ + + +0.0, +2.5173462E-2, +-1.1662878E-6, +-1.0833638E-9, +-8.9773540E-13, +-3.7342377E-16, +-8.6632643E-20, +-1.0450598E-23, +-5.1920577E-28, +0.0 + +}; +const double ITS90_TCK_sub500[] = +{ +0.0, +2.508355E-02, +7.860106E-08, +-2.503131E-10, +8.315270E-14, +-1.228034E-17, +9.804036E-22, +-4.413030E-26, +1.057734E-30, +-1.052755E-35 +}; + +const double ITS90_TCK_sub1372[] = +{ +-1.318058E+02, +4.830222E-02, +-1.646031E-06, +5.464731E-11, +-9.650715E-16, +8.802193E-21, +-3.110810E-26, +0.0, +0.0, +0.0 + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MAX31850.cpp Thu Feb 12 14:03:55 2015 +0000 @@ -0,0 +1,125 @@ +/** +* @file MAX31850.cpp +* @brief library of MAX31850 1-Wire Thermocouple-to-Digital Converters,Cold-Junction Compensated (http://www.maximintegrated.com/datasheet/index.mvp/id/7953) +* @author Frederic BLANC +* @date 2014_01_15 +*/ +#include "mbed.h" +#include "onewire.h" +#include "MAX31850.h" +#include "crc8.h" +#include "Horner_ITS90.h" +int MAX31850_Read_Scratch(uint8_t id[],uint8_t sp[],uint8_t n) +{ + if (id[0] == MAX31850_ID) { + if (ow_reset(n)) //reset OW + return OW_SHORT_CIRCUIT; + sp[0]=MAX31850_READ; // command + ow_command(n,sp[0], &id[0]); + for ( int i=0 ; i< MAX31850_SP_SIZE; i++ ) { //read 8xdata + CRC16 + sp[i]=ow_byte_rd(n); + } + if(sp[8]!=crc8(sp,8)) + return OW_ERROR_CRC; + return OW_OK; + } + return OW_ERROR_BAD_ID; +} + +int MAX31850_Temp_TRUE(uint8_t *sp,double *temp) +{ + + + float temp_cj,temp_tc; + double vtc; + int err; + + err = MAX31850_Temp_TC(sp,&temp_tc); + if(err) { + return err; + } + MAX31850_Temp_CJ(sp,&temp_cj); + + vtc = MAX31850_K * temp_tc ; + *temp=0; + if(temp_tc < 0.0) { + for(int i=0;i<10;++i) + { + + *temp+=ITS90_TCK_subzero[i]*pow(vtc,i); + } + } else if(temp_tc < 500.0) { + for(int i=0;i<10;++i) + { + + *temp+=ITS90_TCK_sub500[i]*pow(vtc,i); + } + } else { + for(int i=0;i<10;++i) + { + + *temp+=ITS90_TCK_sub1372[i]*pow(vtc,i); + } + } + return OW_OK; +} + + +int MAX31850_Temp_TC(uint8_t *sp,float *temp) +{ + + uint8_t *ptr_meas; + uint16_t meas; + + if(sp[0]& 1) + return MAX31850_ERR_FAULT; + if(sp[2]& (1<<1)) + return MAX31850_ERR_OPEN_CIRCUIT; + if(sp[2]& (1<<2)) + return MAX31850_ERR_SHORT2GND; + if(sp[2]& (1<<3)) + return MAX31850_ERR_SHORT2VDD; + ptr_meas=(uint8_t*) &meas; + *ptr_meas = sp[0] ; // LSB + *++ptr_meas = sp[1]; // MSB + if ( meas & 0x8000 ) { + + meas ^= 0xffff; // convert to positive => (twos complement)++ + meas++; + *temp= -1.0 * MAX31850_ADC_TEMP_TC_UNIT * (float)(meas>>2); + } else { + *temp= MAX31850_ADC_TEMP_TC_UNIT * (float)(meas>>2); + } + + return OW_OK; +} + +int MAX31850_Temp_CJ(uint8_t *sp,float *temp) +{ + uint8_t *ptr_meas; + uint16_t meas; + + ptr_meas=(uint8_t*) &meas; + *ptr_meas = sp[2] ; // LSB + *++ptr_meas = sp[3]; // MSB + if ( meas & 0x8000 ) { + + meas ^= 0xffff; // convert to positive => (twos complement)++ + meas++; + *temp= -1.0 * MAX31850_ADC_TEMP_CJ_UNIT * (float)(meas>>4); + } else { + *temp= MAX31850_ADC_TEMP_CJ_UNIT * (float)(meas>>4); + } + return OW_OK; +} + +int MAX31850_Start_meas(uint8_t id[],uint8_t n=0) +{ + if (id[0] == MAX31850_ID) { + if (ow_reset(n)) //reset OW + return OW_SHORT_CIRCUIT; + ow_command(n,MAX31850_CONVERT_T, &id[0]); + return OW_OK; + } + return OW_ERROR_BAD_ID; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MAX31850.h Thu Feb 12 14:03:55 2015 +0000 @@ -0,0 +1,69 @@ +/* DS2450 specific values (see datasheet http://www.maximintegrated.com/datasheet/index.mvp/id/7953) */ +#ifndef __MAX31850_H__ +#define __MAX31850_H__ +#define MAX31850_ID 0x3B +#define MAX31850_SP_SIZE 9 + +#define MAX31850_CONVERT_T 0x44 // 0x44 +#define MAX31850_READ_POWER_SUPPLY 0xB4 +#define MAX31850_READ 0xBE + +#define MAX31850_ADC_TEMP_TC_UNIT 0.25 +#define MAX31850_ADC_TEMP_CJ_UNIT 0.0625 +#define MAX31850_K 41.276//41.276µV/C + +#define MAX31850_ERR_FAULT -10; +#define MAX31850_ERR_SHORT2VDD -12; +#define MAX31850_ERR_SHORT2GND -13; +#define MAX31850_ERR_OPEN_CIRCUIT -14; +/** + * @brief lecture registre MAX31850 + * @param [in] uint8_t id[] tableau d'identifiant OW + * @param [out] uint8_t sp[] tableau de registre + * @param [in] uint8_t n bus ow + * @return OW_OK si erreur retourne OW_ERROR_CRC + * @date 02/12/2013 + * + */ +int MAX31850_Read_Scratch(uint8_t id[],uint8_t sp[],uint8_t n) ; + +/** + * @brief lecture temperature thermocouple Linearized MAX31850 + * @param [in] uint8_t sp[] tableau registre MAX31850 + * @param [out] float temperature thermocouple Linearized degre Celsuis + * @return OW_OK si erreur retourne ERROR + * @date 04/12/2013 + * + */ + int MAX31850_Temp_TRUE(uint8_t *sp,double *temp); + +/** + * @brief lecture temperature thermocouple MAX31850 + * @param [in] uint8_t sp[] tableau registre MAX31850 + * @param [out] float temperature thermocouple degre Celsuis + * @return OW_OK si erreur retourne ERROR + * @date 04/12/2013 + * + */ + int MAX31850_Temp_TC(uint8_t *sp,float *temp) ; + +/** + * @brief lecture temperature cold junction MAX31850 + * @param [in] uint8_t sp[] tableau registre MAX31850 + * @param [out] float temperature cold junction degre Celsuis + * @return OW_OK si erreur retourne ERROR + * @date 04/12/2013 + * + */ +int MAX31850_Temp_CJ(uint8_t *sp,float *temp) ; + +/** + * @brief start convertion MAX31850 + * @param [in] uint8_t id[] tableau d'identifiant OW + * @param [in] uint8_t n bus ow + * @return OW_OK + * @date 02/12/2013 + * + */ +int MAX31850_Start_meas(uint8_t id[],uint8_t n); +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crc16.cpp Thu Feb 12 14:03:55 2015 +0000 @@ -0,0 +1,56 @@ +#include <inttypes.h> +#include "mbed.h" +#include "onewire.h" + +#define CRC16INIT 0x0000 +//#define CRC16POLY 0x8005; // Polynome =x^16 + x^15 + x^2 + x^0 = 0x18005 +#define CRC16POLY 0xA001; + +uint16_t crc16(uint8_t* octets, uint16_t nboctets) +{ +uint16_t crc = CRC16INIT; +int i, done = 0; +uint8_t todo; + if (nboctets != 0) { + do { + todo = octets[done]; + crc ^= todo; + for (i = 0; i < 8; i++) { + if (crc % 2 != 0) { + crc = (crc >> 1) ^ CRC16POLY; + } else { + crc = crc >> 1; + } + } + done++; + } while (done < nboctets); + + + } + +return crc; +} +//CRC16 byte, always two bytes, bit inverted, LSByte first +uint8_t ctrl_crc16(uint8_t* octets, uint16_t nboctets) +{ + uint16_t crc; + uint8_t *ptr; +#ifdef DEBUG + printf( "\nCRC16 : " ); + for ( uint8_t i=0 ; i< nboctets; i++ ) + printf(":%2.2X",octets[i]); + printf( "\n" ); +#endif + crc =~crc16(octets, nboctets-2); + ptr=(uint8_t*)&crc; +#ifdef DEBUG + printf( "\n" ); + printf("CRC16:%X",crc); + printf( "\n" ); +#endif + if(*ptr==octets[nboctets-2]) + if(*++ptr==octets[nboctets-1]) + return 0; + + return 1; + } \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crc16.h Thu Feb 12 14:03:55 2015 +0000 @@ -0,0 +1,5 @@ +#ifndef _CRC16_ +#define _CRC16_ +uint16_t crc16(uint8_t* octets, uint16_t nboctets); +uint8_t ctrl_crc16(uint8_t* octets, uint16_t nboctets); +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crc8.cpp Thu Feb 12 14:03:55 2015 +0000 @@ -0,0 +1,39 @@ +#include <inttypes.h> + +#define CRC8INIT 0x00 +#define CRC8POLY 0x18 //0X18 = X^8+X^5+X^4+X^0 + +uint8_t crc8 ( uint8_t *data_in, uint16_t number_of_bytes_to_read ) +{ + uint8_t crc; + uint16_t loop_count; + uint8_t bit_counter; + uint8_t data; + uint8_t feedback_bit; + + crc = CRC8INIT; + + for (loop_count = 0; loop_count != number_of_bytes_to_read; loop_count++) + { + data = data_in[loop_count]; + + bit_counter = 8; + do { + feedback_bit = (crc ^ data) & 0x01; + + if ( feedback_bit == 0x01 ) { + crc = crc ^ CRC8POLY; + } + crc = (crc >> 1) & 0x7F; + if ( feedback_bit == 0x01 ) { + crc = crc | 0x80; + } + + data = data >> 1; + bit_counter--; + + } while (bit_counter > 0); + } + + return crc; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crc8.h Thu Feb 12 14:03:55 2015 +0000 @@ -0,0 +1,4 @@ +#ifndef _CRC8_ +#define _CRC8_ +uint8_t crc8 (uint8_t* data_in, uint16_t number_of_bytes_to_read); +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/onewire.cpp Thu Feb 12 14:03:55 2015 +0000 @@ -0,0 +1,575 @@ +/** +* @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; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/onewire.h Thu Feb 12 14:03:55 2015 +0000 @@ -0,0 +1,79 @@ +/** +* @file onewire.h +* @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) +*/ + +#ifndef _onewire_ +#define _onewire_ +#include "DS2450.h" +#include "DS18X20.h" +#include "MAX31850.h" +#include "crc8.h" +#include "crc16.h" +//#define DEBUG 1 +//#define DEBUG_L1 1 +#define ONEWIRE_PIN p21 + +#define MAXSENSORS 8 +#define MAXBUS 4 +// rom-code size including CRC +#define OW_ROMCODE_SIZE 8 + +#define OW_OK 0x00 +#define OW_ERROR 0x01 +#define OW_START_FAIL 0x02 +#define OW_ERROR_CRC 0x03 +#define OW_ERROR_BAD_ID 0x04 +#define OW_BUSY 0x05 + +#define OW_MATCH_ROM 0x55 +#define OW_SKIP_ROM 0xCC +#define OW_SEARCH_ROM 0xF0 +#define OW_READ_ROM 0x33 +#define OW_CONDITIONAL_SEARCH 0xEC +#define OW_OVERDRIVE_SKIP_ROM 0x3C +#define OW_OVERDRIVE_MATCH_ROM 0x69 + +#define OW_SHORT_CIRCUIT 0xFF +#define OW_SEARCH_FIRST 0xFF // start new search +#define OW_PRESENCE_ERR 0x01 +#define OW_DATA_ERR 0xFE +#define OW_LAST_DEVICE 0x00 // last device found +// 0x01 ... 0x40: continue searching + + + +char* ow_show_id( uint8_t id[],char *text); +uint64_t uint64_id( uint8_t id[]); + +uint8_t search_sensors(uint8_t *nSensors,uint8_t id[][OW_ROMCODE_SIZE] ); +uint8_t search_sensors(uint8_t n,uint8_t *nSensors,uint8_t gSensorIDs[][MAXSENSORS][OW_ROMCODE_SIZE] ); +uint8_t ow_PullUp(void); +uint8_t ow_PullUp(uint8_t n); + + +uint8_t ow_test_pin (void); +uint8_t ow_test_pin (uint8_t n); +uint8_t ow_reset(void); +uint8_t ow_reset(uint8_t n); +uint8_t ow_rom_search( uint8_t diff, uint8_t id[] ); +uint8_t ow_rom_search(uint8_t n, uint8_t diff, uint8_t id[] ); +uint8_t ow_command( uint8_t command, uint8_t id[] ); +uint8_t ow_command(uint8_t n, uint8_t command, uint8_t id[] ); +uint8_t ow_find_sensor(uint8_t *diff, uint8_t id[]); +uint8_t ow_find_sensor(uint8_t n,uint8_t *diff, uint8_t id[]); +uint8_t ow_parasite_enable(void); +uint8_t ow_parasite_enable(uint8_t n); +uint8_t ow_parasite_disable(void); +uint8_t ow_parasite_disable(uint8_t n); +uint8_t ow_bit_io( uint8_t b ); +uint8_t ow_bit_io(uint8_t n, uint8_t b); +uint8_t ow_byte_wr( uint8_t b ); +uint8_t ow_byte_wr(uint8_t n, uint8_t b ); +uint8_t ow_byte_rd( void ); +uint8_t ow_byte_rd( uint8_t n); + + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utils.cpp Thu Feb 12 14:03:55 2015 +0000 @@ -0,0 +1,12 @@ +#include <stdint.h> + +uint16_t uint8_to_uint16(uint8_t lsb, uint8_t msb) +{ + uint16_t data; + uint8_t *ptr; + + ptr=(uint8_t*)&data; + *ptr=lsb; + *++ptr=msb; + return data; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utils.h Thu Feb 12 14:03:55 2015 +0000 @@ -0,0 +1,4 @@ +#ifndef _utils_ +#define _utils_ +uint16_t uint8_to_uint16(uint8_t lsb, uint8_t msb); +#endif \ No newline at end of file