This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

I need help to port some libraries for nrf5340

Hi

 I am using NRF5340dk with NCS version 1.5.0, I need to port  the below library which was written for nrf51.

github.com/.../ADS1231

KIndly, Help me to resolve this

Thanks & Regards

Navin

Parents
  • Hello, 

    Given that the nRF5340 is based on the Arm Cortex M33 I suggest making the driver from scratch following the Zephyr Device Driver Model. Also, you could try to find similar drivers in Zephyr and look at how they are designed. 

    Kind regards,
    Øyvind

  • Hi Oyvind

      I have written some code like the same for nrf5340. I can't able to read any data 

    I will attach that code for your reference. Kindly guide me to get the output

    /**
     * @brief       ADS1231.c
     * @details     24-Bit Analog-to-Digital Converter for Bridge Sensors.
     *              Functions file.
     *
     *
     * @return      NA
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017    The ORIGIN
     * @pre         NaN.
     * @warning     NaN
     * @pre         This code belongs to AqueronteBlog ( http://unbarquero.blogspot.com ).
     */
    
    #include <drivers/gpio.h>
    #include <hal/nrf_gpio.h>
    #include "ADS1231.h"
    
    /**
     * @brief       ADS1231_Init ( uint32_t , uint32_t )
     *
     * @details     It performs an internal reset.
     *
     * @param[in]    myDOUT:        Pin to be #DRDY/DOUT.
     * @param[in]    mySCLK:        Pin to be SCLK.
     *
     * @param[out]   NaN.
     *
     *
     * @return       The configured pins.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     NaN.
     */
    ADS1231_pins_t ADS1231_Init ( uint32_t myDOUT, uint32_t mySCLK )
    {
        ADS1231_pins_t myPins;
    
    
        // INPUT. #DRDY/DOUT PIN
         nrf_gpio_cfg_input(myDOUT,NRF_GPIO_PIN_NOPULL);
    
        // OUTPUT. SCLK PIN
        nrf_gpio_cfg_output(mySCLK);
    
    
        // Associate the pins
        myPins.DOUT     =   myDOUT;
        myPins.SCLK     =   mySCLK;
    
    
        return   myPins;
    }
    
    
    
    /**
     * @brief       ADS1231_Reset   ( void )
     *
     * @details     It performs an internal reset.
     *
     * @param[in]    NaN.
     *
     * @param[out]   NaN.
     *
     *
     * @return       Status of ADS1231_Reset.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         When SCLK pin changes from low to high and stays at high for
     *              longer than 26μs, ADS1231 enters power down mode.
     *
     *              When SCLK returns to low, chip will reset and enter normal
     *              operation mode.
     * @warning     NaN.
     */
    ADS1231_status_t  ADS1231_Reset   ( ADS1231_pins_t myPins )
    {
        nrf_gpio_pin_set(  myPins.SCLK );                                // SCLK HIGH
        k_usleep ( 52 );                                                          // Datasheet p15. At least 26us ( Security Factor: 2*26us = 52us )
        nrf_gpio_pin_clear(  myPins.SCLK );                                // SCLK LOW
    
    
    
        if ( ( ( nrf_gpio_pin_read( myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH )
            return   ADS1231_SUCCESS;
        else
            return   ADS1231_FAILURE;
    }
    
    
    
    /**
     * @brief       ADS1231_PowerDown   ( void )
     *
     * @details     It puts the device in power-down mode.
     *
     * @param[in]    NaN.
     *
     * @param[out]   NaN.
     *
     *
     * @return       Status of ADS1231_PowerDown.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         When SCLK pin changes from low to high and stays at high for
     *              longer than 26μs, ADS1231 enters power down mode.
     * @warning     NaN.
     */
    ADS1231_status_t  ADS1231_PowerDown   ( ADS1231_pins_t myPins )
    {
        // _SCLK  =  ADS1231_PIN_HIGH;
        nrf_gpio_pin_set(  myPins.SCLK );
        k_usleep( 52 );                                                           // Datasheet p15. At least 26us ( Security Factor: 2*26us = 52us )
    
    
    
        if ( ( ( nrf_gpio_pin_read (myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH )
            return   ADS1231_SUCCESS;
        else
            return   ADS1231_FAILURE;
    }
    
    
    
    /**
     * @brief       ADS1231_ReadRawData   ( ADS1231_pins_t, Vector_count_t*, uint32_t )
     *
     * @details     It reads the raw data from the device.
     *
     * @param[in]    myPins:            The pins to communicate with the device.
     * @param[in]    myAverage:         How many measurement we have to get and deliver the average.
     *
     * @param[out]   myNewRawData:      The new value from the device.
     *
     *
     * @return       Status of ADS1231_ReadRawData.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     nrf_delay_us ( 1 ) does not seem to work well, the delay is about
     *              5us instead of 1us.
     */
    ADS1231_status_t  ADS1231_ReadRawData    ( ADS1231_pins_t myPins, Vector_count_t* myNewRawData, uint32_t myAverage )
    {
        uint32_t i           =   0;                                                 // Counter and timeout variable
        uint32_t ii          =   0;                                                 // Counter for average
        uint32_t myAuxData   =   0;
    
    
    
        myNewRawData->myRawValue    =   0;                                          // Reset variable at the beginning
    
        // Start collecting the new measurement as many as myAverage
        for ( ii = 0; ii < myAverage; ii++ )
        {
            // Reset the value
            myAuxData    =   0;
    
            // Wait until the device is ready or timeout
            i        =   23232323;
            //_SCLK  =  ADS1231_PIN_LOW;
            nrf_gpio_pin_clear( myPins.SCLK );
            while ( ( ( ( nrf_gpio_pin_read( myPins.DOUT)  ) & 1UL ) == ADS1231_PIN_HIGH ) && ( --i ) );
    
            // Check if something is wrong with the device because of the timeout
            if ( i < 1 )
                return   ADS1231_FAILURE;
    
    
            // Read the data
            for ( i = 0; i < 24; i++ )
            {
                // nrf_delay_us ( 1 );                                                  // Datasheet p13.  t_SCLK ( Min. 100ns )
                nrf_gpio_pin_set (myPins.SCLK );
                // nrf_delay_us ( 1 );                                                  // Datasheet p13.  t_SCLK ( Min. 100ns )
                myAuxData    <<=     1;
                nrf_gpio_pin_clear(myPins.SCLK );
    
                // High or Low bit
                if ( ( ( nrf_gpio_pin_read( myPins.DOUT)  ) & 1UL ) == ADS1231_PIN_HIGH )
                    myAuxData++;
            }
    
            // Last bit to release the bus
            // nrf_delay_us ( 1 );                                                      // Datasheet p13.  t_SCLK ( Min. 100ns )
            nrf_gpio_pin_set ( myPins.SCLK );
            // nrf_delay_us ( 1 );                                                      // Datasheet p13.  t_SCLK ( Min. 100ns )
            nrf_gpio_pin_clear( myPins.SCLK );
    
    
    
            // Update data to get the average
            myAuxData                  ^=    0x800000;
            myNewRawData->myRawValue   +=    myAuxData;
        }
    
        myNewRawData->myRawValue    /=    ( float )myAverage;
    
    
    
        if ( ( ( nrf_gpio_pin_read( myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH )
            return   ADS1231_SUCCESS;
        else
            return   ADS1231_FAILURE;
    }
    
    
    
    /**
     * @brief       ADS1231_ReadData_WithCalibratedMass ( ADS1231_pins_t , Vector_count_t* , uint32_t )
     *
     * @details     It reads data with a calibrated mass on the load cell.
     *
     * @param[in]    myPins:                The pins to communicate with the device.
     * @param[in]    myAverage:             How many data to read.
     *
     * @param[out]   myNewRawData:          myRawValue_WithCalibratedMass ( ADC code taken with calibrated mass ).
     *
     *
     * @return       Status of ADS1231_ReadData_WithCalibratedMass.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     NaN.
     */
    ADS1231_status_t  ADS1231_ReadData_WithCalibratedMass   ( ADS1231_pins_t myPins, Vector_count_t* myNewRawData, uint32_t myAverage )
    {
        ADS1231_status_t        aux;
    
        // Perform a new bunch of readings
        aux  =   ADS1231_ReadRawData ( myPins, myNewRawData, myAverage );
    
    
        // Update the value with a calibrated mass
        myNewRawData->myRawValue_WithCalibratedMass  =   myNewRawData->myRawValue;
    
    
    
        if ( aux == ADS1231_SUCCESS )
            return   ADS1231_SUCCESS;
        else
            return   ADS1231_FAILURE;
    }
    
    
    
    /**
     * @brief       ADS1231_ReadData_WithoutMass ( ADS1231_pins_t , Vector_count_t* , uint32_t )
     *
     * @details     It reads data without any mass on the load cell.
     *
     * @param[in]    myPins:                The pins to communicate with the device.
     * @param[in]    myAverage:             How many data to read.
     *
     * @param[out]   myNewRawData:          myRawValue_WithoutCalibratedMass ( ADC code taken without any mass ).
     *
     *
     * @return       Status of ADS1231_ReadData_WithoutMass.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     NaN.
     */
    ADS1231_status_t  ADS1231_ReadData_WithoutMass   ( ADS1231_pins_t myPins, Vector_count_t* myNewRawData, uint32_t myAverage )
    {
        ADS1231_status_t        aux;
    
        // Perform a new bunch of readings
        aux  =   ADS1231_ReadRawData ( myPins, myNewRawData, myAverage );
    
    
        // Update the value without any mass
        myNewRawData->myRawValue_WithoutCalibratedMass  =   myNewRawData->myRawValue;
    
    
    
        if ( aux == ADS1231_SUCCESS )
            return   ADS1231_SUCCESS;
        else
            return   ADS1231_FAILURE;
    }
    
    
    
    /**
     * @brief       ADS1231_CalculateMass ( Vector_count_t* , uint32_t , ADS1231_scale_t )
     *
     * @details     It calculates the mass.
     *
     * @param[in]    myNewRawData:              It has myRawValue_WithCalibratedMass ( ADC code taken with calibrated mass ),
     *                                          myRawValue_WithoutCalibratedMass ( ADC code taken without any mass ) and
     *                                          myRawValue ( the current data taken by the system ).
     * @param[in]    myCalibratedMass:          A known value for the calibrated mass when myRawValue_WithCalibratedMass was
     *                                          calculated.
     * @param[in]    myScaleCalibratedMass:     The range of the calibrated mass ( kg, g, mg or ug ).
     *
     * @param[out]   NaN.
     *
     *
     * @return       The calculated mass.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     NaN.
     */
    Vector_mass_t  ADS1231_CalculateMass ( Vector_count_t* myNewRawData, float myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass )
    {
        // Terminology by Texas Instruments: sbau175a.pdf, p8 2.1.1 Calculation of Mass
        float m, w_zs;
        float c_zs, w_fs, c_fs, w_t;
        float c = 0;
        float myFactor   =   1.0;
    
        Vector_mass_t w;
    
    
        // Adapt the scale ( kg as reference )
        switch ( myScaleCalibratedMass )
        {
        default:
        case ADS1231_SCALE_kg:
            // myFactor     =   1.0;
            break;
    
        case ADS1231_SCALE_g:
            myFactor     /=   1000.0;
            break;
    
        case ADS1231_SCALE_mg:
            myFactor     /=   1000000.0;
            break;
    
        case ADS1231_SCALE_ug:
            myFactor     /=   1000000000.0;
            break;
    
        }
    
    
        // Calculate the Calibration Constant ( m )
        w_fs    =    ( myCalibratedMass / myFactor );                               // User-specified calibration mass
        c_zs    =    myNewRawData->myRawValue_WithoutCalibratedMass;                // ADC measurement taken with no load
        c_fs    =    myNewRawData->myRawValue_WithCalibratedMass;                   // ADC code taken with the calibration mass applied
    
        m       =    ( float )( w_fs / ( ( c_fs ) - c_zs  ) );                      // The Calibration Constant
    
    
        // Calculate the zero-scale mass ( w_zs )
        w_zs    =    - ( m * c_zs );
    
    
        // Calculate the mass ( w )
        w_t     =    myNewRawData->myRawValue_TareWeight;                           // ADC code taken without any mass after the system is calibrated;
        c       =    myNewRawData->myRawValue;                                      // The ADC code
    
        w.myMass   =    ( m * c ) + w_zs - w_t;                                     // The mass according to myScaleCalibratedMass
    
    
        // Update Internal Parameters
        //_ADS1231_USER_CALIBATED_MASS   =   myCalibratedMass;
        //_ADS1231_SCALE                 =   w;
    
    
    
        return   w;
    }
    
    
    
    /**
     * @brief       ADS1231_SetAutoTare ( ADS1231_pins_t, float , ADS1231_scale_t , Vector_count_t* , float )
     *
     * @details     It reads data without any mass on the load cell after the system is calibrated to calculate the tare weight.
     *
     * @param[in]    myPins:                    The pins to communicate with the device.
     * @param[in]    myCalibratedMass:          A known value for the calibrated mass when myRawValue_WithCalibratedMass was
     *                                          calculated.
     * @param[in]    myScaleCalibratedMass:     The range of the calibrated mass ( kg, g, mg or ug ).
     * @param[in]    myTime:                    How long the auto-set lasts.
     *
     * @param[out]   myNewRawData:              myRawValue_TareWeight ( ADC code taken without any mass ).
     *
     *
     * @return       Status of ADS1231_SetAutoTare.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     NaN.
     */
    ADS1231_status_t  ADS1231_SetAutoTare   ( ADS1231_pins_t myPins, float myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass, Vector_count_t* myNewRawData, float myTime )
    {
        
       ADS1231_status_t        aux;
        Vector_mass_t         myCalculatedMass;
        float                 myAuxData = 0;
        uint32_t              i = 0;
    
    
        // Perform a new bunch of readings every 1 second
        for ( i = 0; i < myTime; i++ )
        {
            aux         =   ADS1231_ReadRawData ( myPins, myNewRawData, 10 );
            myAuxData   +=   myNewRawData->myRawValue;
            k_msleep ( 1000 );
        }
    
        myNewRawData->myRawValue    =    ( float )( myAuxData / myTime );
    
        // Turn it into mass
        myCalculatedMass     =   ADS1231_CalculateMass ( myNewRawData, myCalibratedMass, myScaleCalibratedMass );
    
        // Update the value without any mass
        myNewRawData->myRawValue_TareWeight  =   myCalculatedMass.myMass;
    
    
        // Update Internal Parameters
        //_ADS1231_USER_CALIBATED_MASS   =   myCalibratedMass;
        //_ADS1231_SCALE                 =   myScaleCalibratedMass;
    
    
    
        if (aux == ADS1231_SUCCESS )
        {
            return   ADS1231_SUCCESS;
        }
        else
        {
            return   ADS1231_FAILURE;
         }
    }
    
    
    
    /**
     * @brief       ADS1231_SetManualTare ( float myTareWeight )
     *
     * @details     It sets a tare weight manually.
     *
     * @param[in]    myTareWeight:          Tare weight.
     *
     * @param[out]   NaN.
     *
     *
     * @return       myRawValue_TareWeight.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     NaN.
     */
    Vector_count_t  ADS1231_SetManualTare   ( float myTareWeight )
    {
        Vector_count_t myNewTareWeight;
    
        // Update the value defined by the user
        myNewTareWeight.myRawValue_TareWeight  =   myTareWeight;
    
    
    
        return   myNewTareWeight;
    }
    
    
    
    /**
     * @brief       ADS1231_CalculateVoltage ( Vector_count_t* ,float )
     *
     * @details     It calculates the mass.
     *
     * @param[in]    myNewRawData:              myRawValue ( the current data taken by the system ).
     * @param[in]    myVoltageReference:        The voltage at the converter reference input.
     *
     * @param[out]   NaN.
     *
     *
     * @return       The calculated voltage.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     NaN.
     */
    Vector_voltage_t  ADS1231_CalculateVoltage ( Vector_count_t* myNewRawData, float myVoltageReference )
    {
        // Terminology by Texas Instruments: sbau175a.pdf, p12 3.2 Measurement Modes Raw
        float x, B, A;
    
        Vector_voltage_t v;
    
    
        x   =    myNewRawData->myRawValue;
        B   =    ( 16777216.0 - 1.0 );              // 2^24 - 1
        A   =    128.0;                             // Gain
    
    
    
        // Calculate the voltage ( v )
        v.myVoltage = ( float )( ( x / B ) * ( myVoltageReference / A ) );          // The voltage
    
    
    
    
        return   v;
    }

    5277.ADS1231.h

    #include <zephyr.h>
    #include <device.h>
    #include <devicetree.h>
    #include <drivers/gpio.h>
    #include <stdio.h>
    #include <hal/nrf_gpio.h>
    #include "ADS1231.h"
    
    #define PWDN 21
    #define LED1 28
    #define LED2 29
    #define LED3 30
     
    #define YES  1
    #define NO  0
    int main( void )
    {
        ADS1231_status_t        aux;
        ADS1231_pins_t          myADS1231pins;
        Vector_count_t          myData;
        Vector_mass_t           myCalculatedMass;
        Vector_voltage_t        myCalculatedVoltage;
        bool myNewMeasurement;
        
       // conf_GPIO   ();
        //conf_TIMER0 ();
        nrf_gpio_cfg_output(LED1);
        nrf_gpio_cfg_output(LED2);
        nrf_gpio_cfg_output(LED3);
    
        // Configure the pins to handle the ADS1231 device ( P0.12: #DRDY/DOUT, P0.13: SCLK )
        myADS1231pins = ADS1231_Init ( 19, 20 );
    
        aux = ADS1231_PowerDown   ( myADS1231pins );
        aux = ADS1231_Reset       ( myADS1231pins );
        k_msleep( 1000 );
    
    
        // CALIBRATION time start!
        // 1. REMOVE THE MASS ON THE LOAD CELL ( ALL LEDs OFF ). Read data without any mass on the load cell
        aux = ADS1231_ReadData_WithoutMass ( myADS1231pins, &myData, 4 );
    
        nrf_gpio_pin_clear(LED1 );
        k_msleep ( 3000 );
    
        // 2. PUT A KNOWN MASS ON THE LOAD CELL ( JUST LED1 ON ). Read data with an user-specified calibration mass
        aux = ADS1231_ReadData_WithCalibratedMass ( myADS1231pins, &myData, 4 );
        // CALIBRATION time end!
    
    
        // [ OPTIONAL ] REMOVE THE MASS ON THE LOAD CELL ( JUST LED2 ON ). Read the device without any mass to calculate the tare weight for 5 seconds
       // NRF_GPIO->OUTSET    =   ( 1UL << LED1 );
        //NRF_GPIO->OUTCLR    =   ( 1UL << LED2 );
        //nrf_delay_ms ( 3000 );
       // NRF_GPIO->OUTSET    =   ( 1UL << LED2 );
    
        // Calculating the tare weight ( JUST LED3 ON )
       nrf_gpio_pin_clear(LED3 );
        aux = ADS1231_SetAutoTare ( myADS1231pins, 1.0, ADS1231_SCALE_kg, &myData, 5 );
      nrf_gpio_pin_set(LED3 );
        nrf_gpio_cfg_output(PWDN);
        nrf_gpio_pin_clear(PWDN);
        k_msleep ( 3000 );
        nrf_gpio_pin_set(PWDN);
       myNewMeasurement = YES ;
        //NRF_TIMER0->TASKS_START  =   1;                 // Start Timer0
    
        while( 1 )
        {
            //NRF_POWER->SYSTEMOFF = 1;
           /* NRF_POWER->TASKS_LOWPWR = 1;                // Sub power mode: Low power.
    
            // Enter System ON sleep mode
    		__WFE();
    		// Make sure any pending events are cleared
    		__SEV();
    		__WFE();*/
    
    
    		if ( myNewMeasurement == YES ){
                
    
                aux                 =    ADS1231_ReadRawData       ( myADS1231pins, &myData, 4 );
                myCalculatedMass    =    ADS1231_CalculateMass     ( &myData, 1.0, ADS1231_SCALE_kg );
                myCalculatedVoltage =    ADS1231_CalculateVoltage  ( &myData, 5.0 );
               printf("Load in Kg: %f",myCalculatedMass);
                myNewMeasurement    =   NO;
    
               
    		}
    
            
    
        }
    }

    Thanks & regards 

    Navin

Reply
  • Hi Oyvind

      I have written some code like the same for nrf5340. I can't able to read any data 

    I will attach that code for your reference. Kindly guide me to get the output

    /**
     * @brief       ADS1231.c
     * @details     24-Bit Analog-to-Digital Converter for Bridge Sensors.
     *              Functions file.
     *
     *
     * @return      NA
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017    The ORIGIN
     * @pre         NaN.
     * @warning     NaN
     * @pre         This code belongs to AqueronteBlog ( http://unbarquero.blogspot.com ).
     */
    
    #include <drivers/gpio.h>
    #include <hal/nrf_gpio.h>
    #include "ADS1231.h"
    
    /**
     * @brief       ADS1231_Init ( uint32_t , uint32_t )
     *
     * @details     It performs an internal reset.
     *
     * @param[in]    myDOUT:        Pin to be #DRDY/DOUT.
     * @param[in]    mySCLK:        Pin to be SCLK.
     *
     * @param[out]   NaN.
     *
     *
     * @return       The configured pins.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     NaN.
     */
    ADS1231_pins_t ADS1231_Init ( uint32_t myDOUT, uint32_t mySCLK )
    {
        ADS1231_pins_t myPins;
    
    
        // INPUT. #DRDY/DOUT PIN
         nrf_gpio_cfg_input(myDOUT,NRF_GPIO_PIN_NOPULL);
    
        // OUTPUT. SCLK PIN
        nrf_gpio_cfg_output(mySCLK);
    
    
        // Associate the pins
        myPins.DOUT     =   myDOUT;
        myPins.SCLK     =   mySCLK;
    
    
        return   myPins;
    }
    
    
    
    /**
     * @brief       ADS1231_Reset   ( void )
     *
     * @details     It performs an internal reset.
     *
     * @param[in]    NaN.
     *
     * @param[out]   NaN.
     *
     *
     * @return       Status of ADS1231_Reset.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         When SCLK pin changes from low to high and stays at high for
     *              longer than 26μs, ADS1231 enters power down mode.
     *
     *              When SCLK returns to low, chip will reset and enter normal
     *              operation mode.
     * @warning     NaN.
     */
    ADS1231_status_t  ADS1231_Reset   ( ADS1231_pins_t myPins )
    {
        nrf_gpio_pin_set(  myPins.SCLK );                                // SCLK HIGH
        k_usleep ( 52 );                                                          // Datasheet p15. At least 26us ( Security Factor: 2*26us = 52us )
        nrf_gpio_pin_clear(  myPins.SCLK );                                // SCLK LOW
    
    
    
        if ( ( ( nrf_gpio_pin_read( myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH )
            return   ADS1231_SUCCESS;
        else
            return   ADS1231_FAILURE;
    }
    
    
    
    /**
     * @brief       ADS1231_PowerDown   ( void )
     *
     * @details     It puts the device in power-down mode.
     *
     * @param[in]    NaN.
     *
     * @param[out]   NaN.
     *
     *
     * @return       Status of ADS1231_PowerDown.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         When SCLK pin changes from low to high and stays at high for
     *              longer than 26μs, ADS1231 enters power down mode.
     * @warning     NaN.
     */
    ADS1231_status_t  ADS1231_PowerDown   ( ADS1231_pins_t myPins )
    {
        // _SCLK  =  ADS1231_PIN_HIGH;
        nrf_gpio_pin_set(  myPins.SCLK );
        k_usleep( 52 );                                                           // Datasheet p15. At least 26us ( Security Factor: 2*26us = 52us )
    
    
    
        if ( ( ( nrf_gpio_pin_read (myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH )
            return   ADS1231_SUCCESS;
        else
            return   ADS1231_FAILURE;
    }
    
    
    
    /**
     * @brief       ADS1231_ReadRawData   ( ADS1231_pins_t, Vector_count_t*, uint32_t )
     *
     * @details     It reads the raw data from the device.
     *
     * @param[in]    myPins:            The pins to communicate with the device.
     * @param[in]    myAverage:         How many measurement we have to get and deliver the average.
     *
     * @param[out]   myNewRawData:      The new value from the device.
     *
     *
     * @return       Status of ADS1231_ReadRawData.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     nrf_delay_us ( 1 ) does not seem to work well, the delay is about
     *              5us instead of 1us.
     */
    ADS1231_status_t  ADS1231_ReadRawData    ( ADS1231_pins_t myPins, Vector_count_t* myNewRawData, uint32_t myAverage )
    {
        uint32_t i           =   0;                                                 // Counter and timeout variable
        uint32_t ii          =   0;                                                 // Counter for average
        uint32_t myAuxData   =   0;
    
    
    
        myNewRawData->myRawValue    =   0;                                          // Reset variable at the beginning
    
        // Start collecting the new measurement as many as myAverage
        for ( ii = 0; ii < myAverage; ii++ )
        {
            // Reset the value
            myAuxData    =   0;
    
            // Wait until the device is ready or timeout
            i        =   23232323;
            //_SCLK  =  ADS1231_PIN_LOW;
            nrf_gpio_pin_clear( myPins.SCLK );
            while ( ( ( ( nrf_gpio_pin_read( myPins.DOUT)  ) & 1UL ) == ADS1231_PIN_HIGH ) && ( --i ) );
    
            // Check if something is wrong with the device because of the timeout
            if ( i < 1 )
                return   ADS1231_FAILURE;
    
    
            // Read the data
            for ( i = 0; i < 24; i++ )
            {
                // nrf_delay_us ( 1 );                                                  // Datasheet p13.  t_SCLK ( Min. 100ns )
                nrf_gpio_pin_set (myPins.SCLK );
                // nrf_delay_us ( 1 );                                                  // Datasheet p13.  t_SCLK ( Min. 100ns )
                myAuxData    <<=     1;
                nrf_gpio_pin_clear(myPins.SCLK );
    
                // High or Low bit
                if ( ( ( nrf_gpio_pin_read( myPins.DOUT)  ) & 1UL ) == ADS1231_PIN_HIGH )
                    myAuxData++;
            }
    
            // Last bit to release the bus
            // nrf_delay_us ( 1 );                                                      // Datasheet p13.  t_SCLK ( Min. 100ns )
            nrf_gpio_pin_set ( myPins.SCLK );
            // nrf_delay_us ( 1 );                                                      // Datasheet p13.  t_SCLK ( Min. 100ns )
            nrf_gpio_pin_clear( myPins.SCLK );
    
    
    
            // Update data to get the average
            myAuxData                  ^=    0x800000;
            myNewRawData->myRawValue   +=    myAuxData;
        }
    
        myNewRawData->myRawValue    /=    ( float )myAverage;
    
    
    
        if ( ( ( nrf_gpio_pin_read( myPins.DOUT) ) & 1UL ) == ADS1231_PIN_HIGH )
            return   ADS1231_SUCCESS;
        else
            return   ADS1231_FAILURE;
    }
    
    
    
    /**
     * @brief       ADS1231_ReadData_WithCalibratedMass ( ADS1231_pins_t , Vector_count_t* , uint32_t )
     *
     * @details     It reads data with a calibrated mass on the load cell.
     *
     * @param[in]    myPins:                The pins to communicate with the device.
     * @param[in]    myAverage:             How many data to read.
     *
     * @param[out]   myNewRawData:          myRawValue_WithCalibratedMass ( ADC code taken with calibrated mass ).
     *
     *
     * @return       Status of ADS1231_ReadData_WithCalibratedMass.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     NaN.
     */
    ADS1231_status_t  ADS1231_ReadData_WithCalibratedMass   ( ADS1231_pins_t myPins, Vector_count_t* myNewRawData, uint32_t myAverage )
    {
        ADS1231_status_t        aux;
    
        // Perform a new bunch of readings
        aux  =   ADS1231_ReadRawData ( myPins, myNewRawData, myAverage );
    
    
        // Update the value with a calibrated mass
        myNewRawData->myRawValue_WithCalibratedMass  =   myNewRawData->myRawValue;
    
    
    
        if ( aux == ADS1231_SUCCESS )
            return   ADS1231_SUCCESS;
        else
            return   ADS1231_FAILURE;
    }
    
    
    
    /**
     * @brief       ADS1231_ReadData_WithoutMass ( ADS1231_pins_t , Vector_count_t* , uint32_t )
     *
     * @details     It reads data without any mass on the load cell.
     *
     * @param[in]    myPins:                The pins to communicate with the device.
     * @param[in]    myAverage:             How many data to read.
     *
     * @param[out]   myNewRawData:          myRawValue_WithoutCalibratedMass ( ADC code taken without any mass ).
     *
     *
     * @return       Status of ADS1231_ReadData_WithoutMass.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     NaN.
     */
    ADS1231_status_t  ADS1231_ReadData_WithoutMass   ( ADS1231_pins_t myPins, Vector_count_t* myNewRawData, uint32_t myAverage )
    {
        ADS1231_status_t        aux;
    
        // Perform a new bunch of readings
        aux  =   ADS1231_ReadRawData ( myPins, myNewRawData, myAverage );
    
    
        // Update the value without any mass
        myNewRawData->myRawValue_WithoutCalibratedMass  =   myNewRawData->myRawValue;
    
    
    
        if ( aux == ADS1231_SUCCESS )
            return   ADS1231_SUCCESS;
        else
            return   ADS1231_FAILURE;
    }
    
    
    
    /**
     * @brief       ADS1231_CalculateMass ( Vector_count_t* , uint32_t , ADS1231_scale_t )
     *
     * @details     It calculates the mass.
     *
     * @param[in]    myNewRawData:              It has myRawValue_WithCalibratedMass ( ADC code taken with calibrated mass ),
     *                                          myRawValue_WithoutCalibratedMass ( ADC code taken without any mass ) and
     *                                          myRawValue ( the current data taken by the system ).
     * @param[in]    myCalibratedMass:          A known value for the calibrated mass when myRawValue_WithCalibratedMass was
     *                                          calculated.
     * @param[in]    myScaleCalibratedMass:     The range of the calibrated mass ( kg, g, mg or ug ).
     *
     * @param[out]   NaN.
     *
     *
     * @return       The calculated mass.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     NaN.
     */
    Vector_mass_t  ADS1231_CalculateMass ( Vector_count_t* myNewRawData, float myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass )
    {
        // Terminology by Texas Instruments: sbau175a.pdf, p8 2.1.1 Calculation of Mass
        float m, w_zs;
        float c_zs, w_fs, c_fs, w_t;
        float c = 0;
        float myFactor   =   1.0;
    
        Vector_mass_t w;
    
    
        // Adapt the scale ( kg as reference )
        switch ( myScaleCalibratedMass )
        {
        default:
        case ADS1231_SCALE_kg:
            // myFactor     =   1.0;
            break;
    
        case ADS1231_SCALE_g:
            myFactor     /=   1000.0;
            break;
    
        case ADS1231_SCALE_mg:
            myFactor     /=   1000000.0;
            break;
    
        case ADS1231_SCALE_ug:
            myFactor     /=   1000000000.0;
            break;
    
        }
    
    
        // Calculate the Calibration Constant ( m )
        w_fs    =    ( myCalibratedMass / myFactor );                               // User-specified calibration mass
        c_zs    =    myNewRawData->myRawValue_WithoutCalibratedMass;                // ADC measurement taken with no load
        c_fs    =    myNewRawData->myRawValue_WithCalibratedMass;                   // ADC code taken with the calibration mass applied
    
        m       =    ( float )( w_fs / ( ( c_fs ) - c_zs  ) );                      // The Calibration Constant
    
    
        // Calculate the zero-scale mass ( w_zs )
        w_zs    =    - ( m * c_zs );
    
    
        // Calculate the mass ( w )
        w_t     =    myNewRawData->myRawValue_TareWeight;                           // ADC code taken without any mass after the system is calibrated;
        c       =    myNewRawData->myRawValue;                                      // The ADC code
    
        w.myMass   =    ( m * c ) + w_zs - w_t;                                     // The mass according to myScaleCalibratedMass
    
    
        // Update Internal Parameters
        //_ADS1231_USER_CALIBATED_MASS   =   myCalibratedMass;
        //_ADS1231_SCALE                 =   w;
    
    
    
        return   w;
    }
    
    
    
    /**
     * @brief       ADS1231_SetAutoTare ( ADS1231_pins_t, float , ADS1231_scale_t , Vector_count_t* , float )
     *
     * @details     It reads data without any mass on the load cell after the system is calibrated to calculate the tare weight.
     *
     * @param[in]    myPins:                    The pins to communicate with the device.
     * @param[in]    myCalibratedMass:          A known value for the calibrated mass when myRawValue_WithCalibratedMass was
     *                                          calculated.
     * @param[in]    myScaleCalibratedMass:     The range of the calibrated mass ( kg, g, mg or ug ).
     * @param[in]    myTime:                    How long the auto-set lasts.
     *
     * @param[out]   myNewRawData:              myRawValue_TareWeight ( ADC code taken without any mass ).
     *
     *
     * @return       Status of ADS1231_SetAutoTare.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     NaN.
     */
    ADS1231_status_t  ADS1231_SetAutoTare   ( ADS1231_pins_t myPins, float myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass, Vector_count_t* myNewRawData, float myTime )
    {
        
       ADS1231_status_t        aux;
        Vector_mass_t         myCalculatedMass;
        float                 myAuxData = 0;
        uint32_t              i = 0;
    
    
        // Perform a new bunch of readings every 1 second
        for ( i = 0; i < myTime; i++ )
        {
            aux         =   ADS1231_ReadRawData ( myPins, myNewRawData, 10 );
            myAuxData   +=   myNewRawData->myRawValue;
            k_msleep ( 1000 );
        }
    
        myNewRawData->myRawValue    =    ( float )( myAuxData / myTime );
    
        // Turn it into mass
        myCalculatedMass     =   ADS1231_CalculateMass ( myNewRawData, myCalibratedMass, myScaleCalibratedMass );
    
        // Update the value without any mass
        myNewRawData->myRawValue_TareWeight  =   myCalculatedMass.myMass;
    
    
        // Update Internal Parameters
        //_ADS1231_USER_CALIBATED_MASS   =   myCalibratedMass;
        //_ADS1231_SCALE                 =   myScaleCalibratedMass;
    
    
    
        if (aux == ADS1231_SUCCESS )
        {
            return   ADS1231_SUCCESS;
        }
        else
        {
            return   ADS1231_FAILURE;
         }
    }
    
    
    
    /**
     * @brief       ADS1231_SetManualTare ( float myTareWeight )
     *
     * @details     It sets a tare weight manually.
     *
     * @param[in]    myTareWeight:          Tare weight.
     *
     * @param[out]   NaN.
     *
     *
     * @return       myRawValue_TareWeight.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     NaN.
     */
    Vector_count_t  ADS1231_SetManualTare   ( float myTareWeight )
    {
        Vector_count_t myNewTareWeight;
    
        // Update the value defined by the user
        myNewTareWeight.myRawValue_TareWeight  =   myTareWeight;
    
    
    
        return   myNewTareWeight;
    }
    
    
    
    /**
     * @brief       ADS1231_CalculateVoltage ( Vector_count_t* ,float )
     *
     * @details     It calculates the mass.
     *
     * @param[in]    myNewRawData:              myRawValue ( the current data taken by the system ).
     * @param[in]    myVoltageReference:        The voltage at the converter reference input.
     *
     * @param[out]   NaN.
     *
     *
     * @return       The calculated voltage.
     *
     *
     * @author      Manuel Caballero
     * @date        18/September/2017
     * @version     18/September/2017   The ORIGIN
     * @pre         NaN.
     * @warning     NaN.
     */
    Vector_voltage_t  ADS1231_CalculateVoltage ( Vector_count_t* myNewRawData, float myVoltageReference )
    {
        // Terminology by Texas Instruments: sbau175a.pdf, p12 3.2 Measurement Modes Raw
        float x, B, A;
    
        Vector_voltage_t v;
    
    
        x   =    myNewRawData->myRawValue;
        B   =    ( 16777216.0 - 1.0 );              // 2^24 - 1
        A   =    128.0;                             // Gain
    
    
    
        // Calculate the voltage ( v )
        v.myVoltage = ( float )( ( x / B ) * ( myVoltageReference / A ) );          // The voltage
    
    
    
    
        return   v;
    }

    5277.ADS1231.h

    #include <zephyr.h>
    #include <device.h>
    #include <devicetree.h>
    #include <drivers/gpio.h>
    #include <stdio.h>
    #include <hal/nrf_gpio.h>
    #include "ADS1231.h"
    
    #define PWDN 21
    #define LED1 28
    #define LED2 29
    #define LED3 30
     
    #define YES  1
    #define NO  0
    int main( void )
    {
        ADS1231_status_t        aux;
        ADS1231_pins_t          myADS1231pins;
        Vector_count_t          myData;
        Vector_mass_t           myCalculatedMass;
        Vector_voltage_t        myCalculatedVoltage;
        bool myNewMeasurement;
        
       // conf_GPIO   ();
        //conf_TIMER0 ();
        nrf_gpio_cfg_output(LED1);
        nrf_gpio_cfg_output(LED2);
        nrf_gpio_cfg_output(LED3);
    
        // Configure the pins to handle the ADS1231 device ( P0.12: #DRDY/DOUT, P0.13: SCLK )
        myADS1231pins = ADS1231_Init ( 19, 20 );
    
        aux = ADS1231_PowerDown   ( myADS1231pins );
        aux = ADS1231_Reset       ( myADS1231pins );
        k_msleep( 1000 );
    
    
        // CALIBRATION time start!
        // 1. REMOVE THE MASS ON THE LOAD CELL ( ALL LEDs OFF ). Read data without any mass on the load cell
        aux = ADS1231_ReadData_WithoutMass ( myADS1231pins, &myData, 4 );
    
        nrf_gpio_pin_clear(LED1 );
        k_msleep ( 3000 );
    
        // 2. PUT A KNOWN MASS ON THE LOAD CELL ( JUST LED1 ON ). Read data with an user-specified calibration mass
        aux = ADS1231_ReadData_WithCalibratedMass ( myADS1231pins, &myData, 4 );
        // CALIBRATION time end!
    
    
        // [ OPTIONAL ] REMOVE THE MASS ON THE LOAD CELL ( JUST LED2 ON ). Read the device without any mass to calculate the tare weight for 5 seconds
       // NRF_GPIO->OUTSET    =   ( 1UL << LED1 );
        //NRF_GPIO->OUTCLR    =   ( 1UL << LED2 );
        //nrf_delay_ms ( 3000 );
       // NRF_GPIO->OUTSET    =   ( 1UL << LED2 );
    
        // Calculating the tare weight ( JUST LED3 ON )
       nrf_gpio_pin_clear(LED3 );
        aux = ADS1231_SetAutoTare ( myADS1231pins, 1.0, ADS1231_SCALE_kg, &myData, 5 );
      nrf_gpio_pin_set(LED3 );
        nrf_gpio_cfg_output(PWDN);
        nrf_gpio_pin_clear(PWDN);
        k_msleep ( 3000 );
        nrf_gpio_pin_set(PWDN);
       myNewMeasurement = YES ;
        //NRF_TIMER0->TASKS_START  =   1;                 // Start Timer0
    
        while( 1 )
        {
            //NRF_POWER->SYSTEMOFF = 1;
           /* NRF_POWER->TASKS_LOWPWR = 1;                // Sub power mode: Low power.
    
            // Enter System ON sleep mode
    		__WFE();
    		// Make sure any pending events are cleared
    		__SEV();
    		__WFE();*/
    
    
    		if ( myNewMeasurement == YES ){
                
    
                aux                 =    ADS1231_ReadRawData       ( myADS1231pins, &myData, 4 );
                myCalculatedMass    =    ADS1231_CalculateMass     ( &myData, 1.0, ADS1231_SCALE_kg );
                myCalculatedVoltage =    ADS1231_CalculateVoltage  ( &myData, 5.0 );
               printf("Load in Kg: %f",myCalculatedMass);
                myNewMeasurement    =   NO;
    
               
    		}
    
            
    
        }
    }

    Thanks & regards 

    Navin

Children
Related