onewire 1-wire ds18x20 ds2450 multi-channel

Dependents:   ibutton

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DS2450.c Source File

DS2450.c

Go to the documentation of this file.
00001 /**
00002 * @file DS2450.c
00003 * @brief library of DS2450 1-Wire Quad A/D Converter  (http://www.maxim-ic.com/datasheet/index.mvp/id/2921)
00004 * @author Frederic BLANC (Published 01/03/2012 www.mbed.org)
00005 */
00006 #include "mbed.h"
00007 #include "onewire.h"
00008 #include "DS2450.h"
00009 #include "crc8.h"
00010 #include "crc16.h"
00011 #include "utils.h"
00012 //**********************************************************************************************************
00013 //*                                  DS2450_read_ADC
00014 //**********************************************************************************************************
00015 
00016 /**
00017  *     @brief lancement lecture DS2450 ADC
00018  *    @param  [in] id[] tableau d'identifiant OW
00019  *    @param  [out] adc[] tableau des valeurs des adc
00020  *    @return OW_OK si erreur retourne OW_ERROR_CRC
00021  *     @date 20/06/2011
00022  *
00023  */
00024 uint8_t DS2450_read_ADC(uint8_t id[], uint16_t adc[]) {
00025     uint8_t i,j;
00026     uint8_t error;
00027     uint8_t sp[DS2450_SP_SIZE];
00028     //waiting for convertion time ( nbchannel x resolution x 80�s +160�s)
00029 
00030     error=DS2450_read_page(&id[0],DS2450_PAGE0,&sp[0]); //read data
00031     if (error)
00032         return error;
00033     j=0;
00034     for (i=0;i<8;i+=2)
00035         adc[j++]=uint8_to_uint16(sp[i+3],sp[i+4]); //sp[i+3] LSB ,sp[i+4] MSB
00036     return OW_OK;
00037 }
00038 
00039 
00040 /**
00041  *     @brief lancement lecture DS2450 ADC
00042  *    @param  [in] n num bus onewire
00043  *    @param  [in] id[] tableau d'identifiant OW
00044  *    @param  [out] adc[] tableau des valeurs des adc
00045  *    @return OW_OK si erreur retourne OW_ERROR_CRC
00046  *     @date 07/09/2011
00047  *
00048  */
00049 uint8_t DS2450_read_ADC(uint8_t n,uint8_t id[], uint16_t adc[]) {
00050     uint8_t i,j;
00051     uint8_t error;
00052     uint8_t sp[DS2450_SP_SIZE];
00053     //waiting for convertion time ( nbchannel x resolution x 80&#65533;s +160&#65533;s)
00054 
00055     error=DS2450_read_page(n,&id[0],DS2450_PAGE0,&sp[0]); //read data
00056     if (error)
00057         return error;
00058     j=0;
00059     for (i=0;i<8;i+=2)
00060         adc[j++]=uint8_to_uint16(sp[i+3],sp[i+4]); //sp[i+3] LSB ,sp[i+4] MSB
00061     return OW_OK;
00062 }
00063 //**********************************************************************************************************
00064 //*                                  DS2450_start_and_read_ADC
00065 //**********************************************************************************************************
00066 
00067 /**
00068  *     @brief lancement & lecture DS2450 ADC
00069  *    @param  [in] id[] tableau d'identifiant OW
00070  *    @param  [out] adc[] tableau des valeurs des adc
00071  *    @return OW_OK si erreur retourne OW_ERROR_CRC
00072  *     @date 20/06/2011
00073  *
00074  */
00075 uint8_t DS2450_start_and_read_ADC(uint8_t id[], uint16_t adc[]) {
00076     uint8_t i,j;
00077     uint8_t error;
00078     uint8_t sp[DS2450_SP_SIZE];
00079 
00080     error=DS2450_convert(&id[0],0x0F,0x00); //start convert
00081     if (error)
00082         return error;
00083 
00084     wait_ms(15);                           //waiting for convertion time ( nbchannel x resolution x 80&#65533;s +160&#65533;s)
00085 
00086     error=DS2450_read_page(&id[0],DS2450_PAGE0,&sp[0]); //read data
00087     if (error)
00088         return error;
00089 
00090     j=0;
00091     for (i=0;i<8;i+=2)
00092         adc[j++]=uint8_to_uint16(sp[i+3],sp[i+4]); //sp[i+3] LSB ,sp[i+4] MSB
00093     return OW_OK;
00094 }
00095 
00096 /**
00097  *     @brief lancement & lecture DS2450 ADC
00098  *    @param  [in] n num bus onewire
00099  *    @param  [in] id[] tableau d'identifiant OW
00100  *    @param  [out] adc[] tableau des valeurs des adc
00101  *    @return OW_OK si erreur retourne OW_ERROR_CRC
00102  *     @date 07/09/2011
00103  *
00104  */
00105 uint8_t DS2450_start_and_read_ADC(uint8_t n,uint8_t id[], uint16_t adc[]) {
00106     uint8_t i,j;
00107     uint8_t error;
00108     uint8_t sp[DS2450_SP_SIZE];
00109 
00110     error=DS2450_convert(n,&id[0],0x0F,0x00); //start convert
00111     if (error)
00112         return error;
00113 
00114     wait_ms(15);                           //waiting for convertion time ( nbchannel x resolution x 80&#65533;s +160&#65533;s)
00115 
00116     error=DS2450_read_page(n,&id[0],DS2450_PAGE0,&sp[0]); //read data
00117     if (error)
00118         return error;
00119 
00120     j=0;
00121     for (i=0;i<8;i+=2)
00122         adc[j++]=uint8_to_uint16(sp[i+3],sp[i+4]); //sp[i+3] LSB ,sp[i+4] MSB
00123     return OW_OK;
00124 }
00125 
00126 //**********************************************************************************************************
00127 //*                                  DS2450_read_page
00128 //**********************************************************************************************************
00129 
00130 /**
00131  *     @brief lancement lecture page DS2450 ADC
00132  *    @param  [in]  id[] tableau d'identifiant OW
00133  *    @param  [in]  adresse de la page a lire
00134  *    @param  [out]  uint16_t sp tableau des valeurs de la page
00135  *    @return OW_OK si erreur retourne OW_ERROR_CRC
00136  *     @date 20/06/2011
00137  *
00138  */
00139 uint8_t DS2450_read_page(uint8_t id[], uint8_t adresse,
00140                          uint8_t *sp) {
00141     uint8_t i;
00142     if (id[0] == DS2450_ID) {
00143         if (ow_reset())                 //reset OW
00144             return OW_SHORT_CIRCUIT;
00145         sp[0]=DS2450_READ_MEMORY;   // command
00146         sp[1]=adresse;              //adress page LSB
00147         sp[2]=0;                    //adress page MSB
00148         ow_command(sp[0], &id[0]);
00149         ow_byte_wr(sp[1]);
00150         ow_byte_wr(sp[2]);
00151 
00152         for ( i=3 ; i< DS2450_SP_SIZE; i++ ) { //read 8xdata + CRC16
00153             sp[i]=ow_byte_rd();
00154         }
00155 
00156         if (ctrl_crc16( &sp[0], DS2450_SP_SIZE ) ) { //CRC16 (command+adress page LSB+adress page MSB+8xdata)
00157             wait_ms(100);                   //wait 100ms if error
00158             if ((sp[DS2450_SP_SIZE-1]==0xFF) && (sp[DS2450_SP_SIZE-2]==0xFF))
00159                 return OW_ERROR;    // bus error
00160             if ((sp[DS2450_SP_SIZE-1]==0x00) && (sp[DS2450_SP_SIZE-2]==0x00))
00161                 return OW_BUSY;
00162     
00163             return OW_ERROR_CRC;    // data error
00164         }
00165         return OW_OK;
00166     }
00167     return OW_ERROR_BAD_ID;
00168 }
00169 /**
00170  *     @brief lancement lecture page DS2450 ADC
00171   *    @param  [in] n num bus onewire
00172  *    @param  [in]  id[] tableau d'identifiant OW
00173  *    @param  [in]  adresse de la page a lire
00174  *    @param  [out]   sp tableau des valeurs de la page
00175  *    @return OW_OK si erreur retourne OW_ERROR_CRC
00176  *     @date 07/09/2011
00177  *
00178  */
00179 uint8_t DS2450_read_page(uint8_t n,uint8_t id[], uint8_t adresse,
00180                          uint8_t *sp) {
00181     uint8_t i;
00182     if (id[0] == DS2450_ID) {
00183         if (ow_reset(n))                 //reset OW
00184             return OW_SHORT_CIRCUIT;
00185         sp[0]=DS2450_READ_MEMORY;   // command
00186         sp[1]=adresse;              //adress page LSB
00187         sp[2]=0;                    //adress page MSB
00188         ow_command(n,sp[0], &id[0]);
00189         ow_byte_wr(n,sp[1]);
00190         ow_byte_wr(n,sp[2]);
00191 
00192         for ( i=3 ; i< DS2450_SP_SIZE; i++ ) { //read 8xdata + CRC16
00193             sp[i]=ow_byte_rd(n);
00194         }
00195 
00196         if (ctrl_crc16( &sp[0], DS2450_SP_SIZE ) ) { //CRC16 (command+adress page LSB+adress page MSB+8xdata)
00197             wait_ms(100);                   //wait 100ms if error
00198             if ((sp[DS2450_SP_SIZE-1]==0xFF) && (sp[DS2450_SP_SIZE-2]==0xFF))
00199                 return OW_ERROR;    // bus error
00200             if ((sp[DS2450_SP_SIZE-1]==0x00) && (sp[DS2450_SP_SIZE-2]==0x00))
00201                 return OW_BUSY;
00202     
00203             return OW_ERROR_CRC;    // data error
00204         }
00205         return OW_OK;
00206     }
00207     return OW_ERROR_BAD_ID;
00208 }
00209 //**********************************************************************************************************
00210 //*                                  DS2450_convert
00211 //**********************************************************************************************************
00212 
00213 /**
00214  *     @brief lancement convertion DS2450 ADC
00215  *    @param  [in] uint8_t id[] tableau d'identifiant OW
00216  *    @param  [in] uint8_t input_select_mask
00217  *    @param  [in] uint8_t read_out_control
00218  *    @return OW_OK si erreur retourne OW_ERROR_CRC
00219  *     @date 20/06/2011
00220  *
00221  */
00222 uint8_t DS2450_convert(uint8_t id[], uint8_t input_select_mask,uint8_t read_out_control) {
00223     uint8_t i;
00224     uint8_t sp[5];
00225     if (id[0] == DS2450_ID) {
00226         if (ow_reset())                 //reset OW
00227             return OW_SHORT_CIRCUIT;
00228         sp[0]=DS2450_CONVERT;       // command
00229         sp[1]=input_select_mask;    //mask
00230         sp[2]=read_out_control;     //control
00231         ow_command(sp[0], &id[0]);
00232         ow_byte_wr(sp[1]);
00233         ow_byte_wr(sp[2]);
00234         for ( i=3 ; i< 5; i++ ) {   // read CRC16
00235             sp[i]=ow_byte_rd();
00236         }
00237 
00238         if (ctrl_crc16( &sp[0], 5 ) ) { //CRC16 (command+mask LSB+control)
00239             if ((sp[3]==0xFF) && (sp[3]==0xFF))
00240                 return OW_ERROR;
00241             return OW_ERROR_CRC;
00242         }
00243         return OW_OK;
00244     }
00245     return OW_ERROR_BAD_ID;
00246 }
00247 /**
00248  *     @brief lancement convertion DS2450 ADC
00249  *    @param  [in] n num bus onewire
00250  *    @param  [in] uint8_t id[] tableau d'identifiant OW
00251  *    @param  [in] uint8_t input_select_mask
00252  *    @param  [in] uint8_t read_out_control
00253  *    @return OW_OK si erreur retourne OW_ERROR_CRC
00254  *     @date 07/09/2011
00255  *
00256  */
00257 uint8_t DS2450_convert(uint8_t n,uint8_t id[], uint8_t input_select_mask,uint8_t read_out_control) {
00258     uint8_t i;
00259     uint8_t sp[5];
00260     if (id[0] == DS2450_ID) {
00261         if (ow_reset(n))                 //reset OW
00262             return OW_SHORT_CIRCUIT;
00263         sp[0]=DS2450_CONVERT;       // command
00264         sp[1]=input_select_mask;    //mask
00265         sp[2]=read_out_control;     //control
00266         ow_command(n,sp[0], &id[0]);
00267         ow_byte_wr(n,sp[1]);
00268         ow_byte_wr(n,sp[2]);
00269         for ( i=3 ; i< 5; i++ ) {   // read CRC16
00270             sp[i]=ow_byte_rd(n);
00271         }
00272 
00273         if (ctrl_crc16( &sp[0], 5 ) ) { //CRC16 (command+mask LSB+control)
00274             if ((sp[3]==0xFF) && (sp[3]==0xFF))
00275                 return OW_ERROR;
00276             return OW_ERROR_CRC;
00277         }
00278         return OW_OK;
00279     }
00280     return OW_ERROR_BAD_ID;
00281 }
00282 
00283 //**********************************************************************************************************
00284 //*                                  DS2450_configure_channel_ADC
00285 //**********************************************************************************************************
00286 
00287 /**
00288  *     @brief configure canal ADC  DS2450
00289  *    @param  [in] id[] tableau d'identifiant OW
00290  *    @param  [in] channel
00291  *  @param  [in] conflsb configuration OE-A OC-A 0 0 RC3-A RC2-A RC1-A RC0-A
00292  *  @param  [in] confmsb configuration POR 0 AFH-A AFL-A AEH-A AEL-A 0 IR-A
00293  *    @return OW_OK si erreur retourne OW_ERROR_CRC
00294  *     @date 20/06/2011
00295  *
00296  */
00297 uint8_t DS2450_configure_channel_ADC(uint8_t id[],uint8_t channel,uint8_t conflsb,uint8_t confmsb) {
00298     uint8_t i;
00299     uint8_t sp[7];
00300     if (id[0] == DS2450_ID) {
00301         if (ow_reset())                 //reset OW
00302             return OW_SHORT_CIRCUIT;
00303         sp[0]=DS2450_WRITE_MEMORY;  // command
00304         sp[1]=DS2450_PAGE1+channel; //adress page LSB
00305         sp[2]=0x00;                 //adress page MSB
00306         sp[3]=conflsb;              //databyte
00307         ow_command(sp[0], &id[0]);
00308         ow_byte_wr(sp[1]);
00309         ow_byte_wr(sp[2]);
00310         ow_byte_wr(sp[3]);
00311         for ( i=4 ; i< 7; i++ ) {   //read CRC16+databyte
00312             sp[i]=ow_byte_rd();
00313         }
00314 
00315         if (ctrl_crc16( &sp[0], 6 ) ) //CRC16 (command+adress page LSB+adress page MSB+databyte)
00316             return OW_ERROR_CRC;
00317         sp[3]=confmsb;                //databyte
00318         ow_byte_wr(sp[3]);
00319         for ( i=4 ; i< 7; i++ ) {   //read CRC16+databyte
00320             sp[i]=ow_byte_rd();
00321         }
00322 
00323         if (sp[3]!=sp[6] ) //control data
00324             return OW_ERROR_CRC;
00325         return OW_OK;
00326     }
00327     return OW_ERROR_BAD_ID;
00328 }
00329 /**
00330  *     @brief configure canal ADC  DS2450
00331  *    @param  [in] n num bus onewire
00332  *    @param  [in] id[] tableau d'identifiant OW
00333  *    @param  [in] channel
00334  *  @param  [in] conflsb configuration OE-A OC-A 0 0 RC3-A RC2-A RC1-A RC0-A
00335  *  @param  [in] confmsb configuration POR 0 AFH-A AFL-A AEH-A AEL-A 0 IR-A
00336  *    @return OW_OK si erreur retourne OW_ERROR_CRC
00337  *     @date 20/06/2011
00338  *
00339  */
00340 uint8_t DS2450_configure_channel_ADC(uint8_t n,uint8_t id[],uint8_t channel,uint8_t conflsb,uint8_t confmsb) {
00341     uint8_t i;
00342     uint8_t sp[7];
00343     if (id[0] == DS2450_ID) {
00344         if (ow_reset(n))                 //reset OW
00345             return OW_SHORT_CIRCUIT;
00346         sp[0]=DS2450_WRITE_MEMORY;  // command
00347         sp[1]=DS2450_PAGE1+channel; //adress page LSB
00348         sp[2]=0x00;                 //adress page MSB
00349         sp[3]=conflsb;              //databyte
00350         ow_command(n,sp[0], &id[0]);
00351         ow_byte_wr(n,sp[1]);
00352         ow_byte_wr(n,sp[2]);
00353         ow_byte_wr(n,sp[3]);
00354         for ( i=4 ; i< 7; i++ ) {   //read CRC16+databyte
00355             sp[i]=ow_byte_rd(n);
00356         }
00357 
00358         if (ctrl_crc16( &sp[0], 6 ) ) //CRC16 (command+adress page LSB+adress page MSB+databyte)
00359             return OW_ERROR_CRC;
00360         sp[3]=confmsb;                //databyte
00361         ow_byte_wr(n,sp[3]);
00362         for ( i=4 ; i< 7; i++ ) {   //read CRC16+databyte
00363             sp[i]=ow_byte_rd(n);
00364         }
00365 
00366         if (sp[3]!=sp[6] ) //control data
00367             return OW_ERROR_CRC;
00368         return OW_OK;
00369     }
00370     return OW_ERROR_BAD_ID;
00371 }
00372 //**********************************************************************************************************
00373 //*                                  DS2450_configure_channel_ADC
00374 //**********************************************************************************************************
00375 
00376 /**
00377  *     @brief configure PAGE
00378  *    @param  [in] id[] tableau d'identifiant OW
00379   *    @param  [in] uint8_t adresse de la page a ecrire
00380  *  @param  [in] config_page tableau de 8 byte
00381  *    @return OW_OK si erreur retourne OW_ERROR_CRC
00382  *     @date 20/06/2011
00383  *
00384  */
00385 uint8_t DS2450_configure_page(uint8_t id[], uint8_t adresse,uint8_t configpage[]) {
00386     uint8_t i,j;
00387     uint8_t sp[7];
00388     if (id[0] == DS2450_ID) {
00389         if (ow_reset())                 //reset OW
00390             return OW_SHORT_CIRCUIT;
00391         sp[0]=DS2450_WRITE_MEMORY;      // command
00392         sp[1]=adresse;                  //adress page LSB
00393         sp[2]=0x00;                     //adress page MSB
00394         sp[3]=configpage[0];            //databyte
00395         ow_command(sp[0], &id[0]);
00396         ow_byte_wr(sp[1]);
00397         ow_byte_wr(sp[2]);
00398         ow_byte_wr(sp[3]);
00399         for ( i=4 ; i< 7; i++ ) {       //read CRC16+databyte
00400             sp[i]=ow_byte_rd();
00401         }
00402 
00403         if (sp[3]!=sp[6] ) //control data
00404             return OW_ERROR_CRC;
00405 
00406         for ( j=1 ; j< 7; j++ ) {
00407             sp[3]=configpage[j];        //databyte
00408             ow_byte_wr(sp[3]);
00409             for ( i=4 ; i< 7; i++ ) {   //read CRC16+databyte
00410                 sp[i]=ow_byte_rd();
00411             }
00412             if (sp[3]!=sp[6] ) //control data
00413                 return OW_ERROR_CRC;
00414 
00415         }
00416         return OW_OK;
00417     }
00418     return OW_ERROR_BAD_ID;
00419 }
00420 /**
00421  *     @brief configure PAGE
00422   *    @param  [in] n num bus onewire
00423  *    @param  [in] id[] tableau d'identifiant OW
00424   *    @param  [in] uint8_t adresse de la page a ecrire
00425  *  @param  [in] config_page tableau de 8 byte
00426  *    @return OW_OK si erreur retourne OW_ERROR_CRC
00427  *     @date 07/09/2011
00428  *
00429  */
00430 uint8_t DS2450_configure_page(uint8_t n,uint8_t id[], uint8_t adresse,uint8_t configpage[]) {
00431     uint8_t i,j;
00432     uint8_t sp[7];
00433     if (id[0] == DS2450_ID) {
00434         if (ow_reset(n))                 //reset OW
00435             return OW_SHORT_CIRCUIT;
00436         sp[0]=DS2450_WRITE_MEMORY;      // command
00437         sp[1]=adresse;                  //adress page LSB
00438         sp[2]=0x00;                     //adress page MSB
00439         sp[3]=configpage[0];            //databyte
00440         ow_command(n,sp[0], &id[0]);
00441         ow_byte_wr(n,sp[1]);
00442         ow_byte_wr(n,sp[2]);
00443         ow_byte_wr(n,sp[3]);
00444         for ( i=4 ; i< 7; i++ ) {       //read CRC16+databyte
00445             sp[i]=ow_byte_rd(n);
00446         }
00447 
00448         if (sp[3]!=sp[6] ) //control data
00449             return OW_ERROR_CRC;
00450 
00451         for ( j=1 ; j< 7; j++ ) {
00452             sp[3]=configpage[j];        //databyte
00453             ow_byte_wr(n,sp[3]);
00454             for ( i=4 ; i< 7; i++ ) {   //read CRC16+databyte
00455                 sp[i]=ow_byte_rd(n);
00456             }
00457             if (sp[3]!=sp[6] ) //control data
00458                 return OW_ERROR_CRC;
00459 
00460         }
00461         return OW_OK;
00462     }
00463     return OW_ERROR_BAD_ID;
00464 }