This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTOS/LAUNCHXL-CC1350: What is the best way to implement a microsecond delay (1-wire app).

Part Number: LAUNCHXL-CC1350
Other Parts Discussed in Thread: CC1350

Tool/software: TI-RTOS

I am trying to add and use a ds18b20 sensor whose communication protocol is 1-wire. I could not find the protocol library for cc1350 inside the SDK, so I will try to write it.

1) Do you have any idea where I can find this library? or

2) What is the best way (simple and efficient) to implement a microsecond delay to make one 1-wire library?

3) Can a timer put the CPU in sleep mode and run mode after a count (like a timer_Sleep), how to do it?

I am working with CC1350 / launchpad, sensortag and ti-15.4-Stack.

thanks in advance.

  • Hi,

    1. I have not seen library for CC1350 supporting 1-wire interface.

    2 & 3. You can use uSleep to sleep in units of microseconds.
    #include <unistd.h>
    You can evaluate this in pinStandby example.

    Regards,
    Toby
  • Hi,

    I've integrated DS18B20 in the "SENSOR" example (sensor to cloud).

    And I solved the problem with microseconds delay in that way:

    ############################################################

    void DELAY_Init(void) {

    /* Enable Debug Exception and Monitor Control Register */

    HWREG(CPU_SCS_BASE + CPU_SCS_O_DEMCR) &= ~0x01000000;
    HWREG(CPU_SCS_BASE + CPU_SCS_O_DEMCR) |= 0x01000000;

    /* Enable Control Register */

    HWREG(CPU_DWT_BASE + CPU_DWT_O_CTRL) &= ~0x00000001;
    HWREG(CPU_DWT_BASE + CPU_DWT_O_CTRL) |= 0x00000001;

    }

    #############################################################

    void delay_us(volatile uint32_t micros) {

    uint32_t start = HWREG(CPU_DWT_BASE + CPU_DWT_O_CYCCNT) - 48;

    /* Go to number of cycles for system */
    micros *= 48;

    /* Delay till end */
    while (((HWREG(CPU_DWT_BASE + CPU_DWT_O_CYCCNT)) - start) < micros);

    }

    ##############################################################

    The delay_us() function is pretty precise and can be used in onewire library.
    My problem is the MCU consumes around 1100 µA in idle mode. I don't understand why the power consumption is not going down between reportings.
    I've activated the power_meas mode but without impact on current consumption. Something is still working in background.
  • Thanks Lukas Lukas51, i already have one solution but, i haven't tried in the sensor aplication. for now only test in one example of pinshutdown. this is the code.

    Ds18b20 library
    
    #include <stdint.h>
    #include <stdbool.h>
    #include <stddef.h>
    
    #include <unistd.h>
    
    /* Driver Header files */
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/pin/PINCC26XX.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    #include "OneWire.h"
    #include "delay.h"
    
    /****************************************************************************/
    /***        Local Function Prototypes                                     ***/
    /****************************************************************************/
    
    /* Reading bus 1-wire*/
    uint8_t Read_Byte(void);
    uint8_t Read_bit(void);
    
    /* Writing 1-wire*/
    void vWrite_Byte(int val);
    void vWrite_Bit(int bit_val);
    
    static void vInputMode(void);
    static void vOutputMode(void);
    
    uint8_t byte;
    
    /****************************************************************************/
    /***        Local Variables                                               ***/
    /****************************************************************************/
    PIN_Config GPIO_OutLine[] =
    {
        Board_DIO23_ANALOG  | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_OPENDRAIN, /* DQ line initially off */
        PIN_TERMINATE                                                                      /* Terminate list */
    };
    
    PIN_Config GPIO_InLine[] =
    {
        Board_DIO23_ANALOG  | PIN_INPUT_EN | PIN_NOPULL | PIN_HYSTERESIS,
        PIN_TERMINATE                                                                      /* Terminate list */
    };
    
    static PIN_State   pinState;
    static PIN_Handle  hDqPin;
    
    /****************************************************************************
    Name: vInit_OneWire
    Function: Init 1-Wire bus.
    Return:
    ****************************************************************************/
    void vInit_OneWire(void){
        hDqPin = PIN_open(&pinState, GPIO_OutLine);
        PIN_setPortOutputValue(hDqPin, GPIO23_HIGH);
    }
    
    /****************************************************************************
    Name: vSetDs18b20
    Function: Setting DS18B20 writting the scratchpad
    Return:
    ****************************************************************************/
    void vSetDs18b20(uint8_t u8SetResolution){
    
        if(Reset_Pulse())
        {
            byte = 0xCC;                                  // Ejecutar el comando SKIP_ROM
            vWrite_Byte(byte);
    
            byte = 0x4E;                                  //Ejecutar el comando WRITE_SCRATCHPAD
            vWrite_Byte(byte);
    
            byte = 0xAA;                                  //Envía TH
            vWrite_Byte(byte);
    
            byte = 0xAA;                                  //Envía TL
            vWrite_Byte(byte);
    
            byte = u8SetResolution;                                  //Envía Configuration bit
            vWrite_Byte(byte);
        }
    }
    
    /****************************************************************************
    Name: vConvertTemp
    Function: Starting the convertion into DS18B20.
    Return:
    ****************************************************************************/
    void vConvertTemp(void){
    
        if(Reset_Pulse())
        {
            byte=0xCC;                                  // Issue SKIP_ROM 0xcc
            vWrite_Byte(byte);
    
            byte=0x44;                                  //Issue CONVERT_T
            vWrite_Byte(byte);
    
            //Comment if the delay is in the application.
    //        sleep(1);
    
            vOutputMode();
        }
    
        PIN_setPortOutputValue(hDqPin, GPIO23_HIGH);
    }
    
    /****************************************************************************
    Name: vReadTemp
    Function: Read temperature from scratchpad in DS18B20.
    Return: Temperature in raw data of 16bit.
    
        LS BYTE 2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4
        MS BYTE S   S   S   S   S    2^6  2^5  2^4
        S = SIGN
    ****************************************************************************/
    uint16_t vReadTemp(const uint8_t u64Rom_Address[8]){
    
        uint16_t u16TempRaw = 0xFFFF;
        int8_t u8slide;
    
        if(Reset_Pulse())
        {
            if(/*u64Rom_Address == BROADCAST*/ 0) // If there are two or more sensor the data will be corrupted.
            {
                byte = 0xCC;                                  // Issue SKIP_ROM
                vWrite_Byte(byte);
            }
            else
            {
                byte = 0x55;                            // Match ROM
                vWrite_Byte(byte);
    
                for(u8slide = 0; u8slide < 8; u8slide++)
                {
                    vWrite_Byte(u64Rom_Address[u8slide]);
    //                delay_us(2);
                }
            }
    
            byte = 0xBE;                                  //Issue READ_SCRATCHPAD
            vWrite_Byte(byte);
    
            u16TempRaw = Read_Byte() & 0xFF;     //  Temperature LSB
            u16TempRaw |= (Read_Byte() & 0xFF) << 8 ;     //  Temperature MSB
    
        }
    
        return (u16TempRaw);
    }
    /****************************************************************************
    Name: Read_Rom
    Function: Read 64-bit rom address.
    Return: 8Bytes
    ***************************************************************************/
    void vReadRom(uint8_t * u8Address)
    {
        if(Reset_Pulse())
        {
            uint8_t i;
    
            byte = 0x33;
            vWrite_Byte(byte);
    
            for(i = 0; i < 8; i++){
                u8Address[i] = Read_Byte() & 0xFF;
            }
        }
    }
    /****************************************************************************
    Name: Read_byte(bits)
    Function: Read byte from 1-wire bus.
    Return: byte
    ***************************************************************************/
    uint8_t Read_Byte(void)
    {
        uint8_t loop, result=0;
    
    
        for (loop = 0; loop < 8; loop++)
        {
            result >>= 1;               // shift the result to get it ready for the next bit to receive
            if (Read_bit())
            result |= 0x80;             // if result is one, then set MS-bit
        }
    
        return result;
    }
    /****************************************************************************
    
    Name: Read_bit(bits)
    
    Function: Read bit from 1-wire bus.
    
    Return: byte
    
    ****************************************************************************/
    uint8_t Read_bit(void)
    {
        uint8_t read_data=0;
    
        PIN_setPortOutputValue(hDqPin, GPIO23_LOW);
    
        delay_us(2);
    
        vInputMode();
    
        delay_us(10);
    
        read_data = PIN_getInputValue(Board_DIO23_ANALOG);
    
        delay_us(20);
    
        vOutputMode();
    
        PIN_setPortOutputValue(hDqPin, GPIO23_HIGH);
    
        return(read_data);
    }
    /****************************************************************************
    Name: vWrite_Byte
    Function: Escribe el Byte "byte" en el bus 1-wire
    Return: Nada
    ****************************************************************************/
    void vWrite_Byte(int byte)
    {
        int j,temp;
    
        for(j=0;j<8;j++)
        {
            temp  = byte>>j;        //shifting "i" bits to the left
            temp &= 0x01;           //writting only the LSB bit
            vWrite_Bit(temp);
        }
    }
    
    /****************************************************************************
    Name: vWrite_Bit
    Function: Escribe 1 bit en el bus 1-wire
    Return:
    ****************************************************************************/
    void vWrite_Bit(int bit_val)
    {
        PIN_setPortOutputValue(hDqPin, GPIO23_LOW);
    
        delay_us(2);
    
        if (bit_val==1)
        {
            PIN_setPortOutputValue(hDqPin, GPIO23_HIGH);
            delay_us(58);
        }else
        {
            delay_us(60);
        }
    
        PIN_setPortOutputValue(hDqPin, GPIO23_HIGH);
    
        delay_us(2);
    }
    
    /****************************************************************************
    Name:     Reset Pulse
    Function:    reset and presence detector.
    Return:   TRUE: if there are sensor
    
                FALSE: if there aren't sensor.
    ****************************************************************************/
    bool Reset_Pulse(void)
    {
        bool estado = FALSE;
    
        PIN_setPortOutputValue(hDqPin, GPIO23_HIGH);        //DIO_23 High
    
        PIN_setPortOutputValue(hDqPin, GPIO23_LOW);
    
        usleep(500);
    
        vInputMode();
    
        delay_us(45);
    
        if(PIN_getInputValue(Board_DIO23_ANALOG))
            estado=FALSE;
    
        else
            estado=TRUE;
    
        usleep(420);                        // wait to end
    
        vOutputMode();
    
        PIN_setPortOutputValue(hDqPin, GPIO23_HIGH);
    
        return(estado);
    }
    
    /****************************************************************************
    Name:     vInputMode
    Function:    Change to input the direction of object.
    Return:
    ****************************************************************************/
    void vInputMode(void){
    
        PIN_close(hDqPin);
        hDqPin = PIN_open(&pinState, GPIO_InLine);
    }
    
    /****************************************************************************
    Name:     vOutputMode
    Function:    Change to output the direction of object.
    return:
    ****************************************************************************/
    void vOutputMode(void){
    
        PIN_close(hDqPin);
        hDqPin = PIN_open(&pinState, GPIO_OutLine);
    }
    

    And the delay functions:

    #include "delay.h"
    #include <stdint.h>
    
    /****************************************************************************/
    /***        Local Function Prototypes                                     ***/
    /****************************************************************************/
    /****************************************************************************
    Nombre:     delay_us
    Función:    delay of microseconds.
    Devuelve:
    ****************************************************************************/
    void delay_us(uint16_t u16timedelay){
    
        uint16_t i;
    
        if(u16timedelay > 1){
           for(i=0; i<u16timedelay; ++i){
               Delay1us();
           }
        }
    }
    
    /****************************************************************************
    Nombre:     Delay1us
    Función:    delay of one microsecond 
    Devuelve:
    ****************************************************************************/
    void Delay1us(void){
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
        __asm (" nop");
    }
    

    it doesn't elegant way, but works in POSIX example. 

  • Hello Anibal,

    thanks a lot for your code!

    I'll try to use it in my example, because I have also problems with pin configuration for the one wire as input/output.

    I do not use Pin_Config table. It is working on the launchpad, but with some problems on my custom board (RSM package 4x4)

    I do something like this:

    #include "gpio.h"
    #include "Board.h"
    
    /* Pin settings */
    #define     PIN_DS18B20                        IOID_3 //Pin für den DS18B20
    
    #define     ONEWIRE_OUTPUT()           IOCPinTypeGpioOutput(PIN_DS18B20)
    #define     ONEWIRE_LOW()	                GPIO_writeDio(PIN_DS18B20, 0)
    #define     ONEWIRE_HIGH()	                GPIO_writeDio(PIN_DS18B20, 1)
    
    #define     ONEWIRE_INPUT()                IOCPinTypeGpioInput(PIN_DS18B20)
    
    BR
    Lukas