onewire 1-wire ds18x20 ds2450 multi-channel

Dependents:   ibutton

Revision:
0:8c4e1841eb30
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DS2450.c	Fri Mar 02 08:29:49 2012 +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&#65533;s +160&#65533;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&#65533;s +160&#65533;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&#65533;s +160&#65533;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