Post Go back to editing

Uniquely identify a PCB through an external ROM

Dear all,

     I need to uniquely identify a PCB that uses ADUCM3029 as micro-controller. For that i'm connecting a ROM using 1-wire protocol in a GPIO pin. I browsed the ADI drivers and examples however I didn't find anything related to this matter, so I started writing a 1-wire protocol driver to read this ROM. One of the configuration needed is a pull-up resistor connecting to this pin. I'm asking:

what is value of the internal GPIO pull-up resistors?

Did Analog Devices has already an example or documentation concerning the 1-wire protocol?

Regards,

Mohamed Amine MESSAOUD

Parents
  • Hello Messaoud,

    The datasheet specifies that at the maximum battery supply voltage of 3.6V and 0V input on the GPIO the pull-up will sink 100uA.

    http://www.analog.com/media/en/technical-documentation/data-sheets/ADuCM3027_3029.pdf

    Currently there is no 1-wire example from ADI that I could find.

    Regards,

    Andrei.

  • I tried to write a driver for this DS2401 could you review it with me. 

    This is the one_wire_driver.h header file

    #ifndef ONE_WIRE_DRIVER
    #define ONE_WIRE_DRIVER
    /*
       see
       https://www.maximintegrated.com/en/app-notes/index.mvp/id/126
    */
    #include <adi_processor.h>
    #include "ADuCM3029.H"
    #include <stddef.h>		/* for 'NULL' */
    #include <string.h>		/* for strlen */
    #include <stdint.h>
    #include <drivers/pwr/adi_pwr.h>
    #include <drivers/gpio/adi_gpio.h>
    #include <drivers/dma/adi_dma.h>
    #include "common.h"
    #include <drivers/general/adi_drivers_general.h>
    
    #define STANDARD_SPEED_A         6u
    #define STANDARD_SPEED_B         64u
    #define STANDARD_SPEED_C         60u
    #define STANDARD_SPEED_D         10u
    #define STANDARD_SPEED_E         9u
    #define STANDARD_SPEED_F         55u
    #define STANDARD_SPEED_G         0u
    #define STANDARD_SPEED_H         480u
    #define STANDARD_SPEED_I         70u
    #define STANDARD_SPEED_J         410u
    
    #define DS2401_READ_ROM_COMMAND	 0x33
    
    
    /* tick every 1us*/
    #define TICKS        (26000000u / 1000000u)
    
    volatile uint32_t usTicks = 0; 
    
    
    typedef struct{
        ADI_GPIO_PORT port;
        ADI_GPIO_DATA pins;
    } PinMap;
    
    
    void delay_us(uint32_t nus);
    
    /* 1-wire basic functions */
    uint16_t OWTouchReset(PinMap _1wd_pin);
    void OWWriteBit(uint8_t bit,PinMap _1wd_pin);
    uint16_t OWReadBit(PinMap _1wd_pin);
    
    /* 1-wire drived functions */
    void OWWriteByte(uint8_t data,PinMap _1wd_pin);
    uint8_t OWReadByte(PinMap _1wd_pin);
    uint8_t OWTouchByte(uint8_t data,PinMap _1wd_pin);
    void OWBlock(uint8_t *data, uint8_t data_len,PinMap _1wd_pin);
    #endif /* ONE_WIRE_DRIVER */
    

    And this is the implementation

    #include "one_wire_driver.h"
    
    /* delay in µs unit*/
    void delay_us(uint32_t nus) {
        while (nus--) {
          while (usTicks != 0) 
          {
          }
        }
    }
    
    /* Tick every 1µs*/
    void SysTick_Handler(){
        usTicks++;
        if(usTicks==26000000u)
        {
           usTicks=0;
        }
    }
    
    uint8_t ROM_VALUE[8];
    volatile uint8_t family_code;
    volatile uint64_t serial_number;
    volatile uint8_t crc_byte;
    
    int main(void)
    {
         PinMap data_DS2401 = { ADI_GPIO_PORT1, ADI_GPIO_PIN_13 };
        /* initialisations */
        uint8_t         gpioMemory[ADI_GPIO_MEMORY_SIZE] = {0};
        ADI_PWR_RESULT  ePwrResult;
        ADI_GPIO_RESULT eGpioResult;
        common_Init();
        
        ePwrResult = adi_pwr_Init();
        DEBUG_RESULT("adi_pwr_Init failed.", ePwrResult, ADI_PWR_SUCCESS);
        ePwrResult = adi_pwr_SetClockDivider(ADI_CLOCK_HCLK, 1u);
        DEBUG_RESULT("adi_pwr_SetClockDivider (HCLK) failed.", ePwrResult, ADI_PWR_SUCCESS);
        ePwrResult = adi_pwr_SetClockDivider(ADI_CLOCK_PCLK, 1u);
        DEBUG_RESULT("adi_pwr_SetClockDivider (PCLK) failed.", ePwrResult, ADI_PWR_SUCCESS);
        
        /* initialize the systick driver */
        SysTick_Config(TICKS);
        
        /* Initialize GPIO driver */
        eGpioResult= adi_gpio_Init(gpioMemory, ADI_GPIO_MEMORY_SIZE);
        DEBUG_RESULT("adi_GPIO_Init failed.", eGpioResult, ADI_GPIO_SUCCESS);
        
        /* set output enable */
        eGpioResult = adi_gpio_OutputEnable(data_DS2401.port, data_DS2401.pins, true);
        DEBUG_RESULT("adi_GPIO_SetOutputEnable failed on data_DS2401.", eGpioResult, ADI_GPIO_SUCCESS);
        /* set pull up. In this case pull-up resistor is external */
        //eGpioResult = adi_gpio_PullUpEnable(data_DS2401.port,data_DS2401.pins,true);
        //DEBUG_RESULT("adi_gpio_PullUpEnable failed on data_DS2401.", eGpioResult, ADI_GPIO_SUCCESS);
        eGpioResult = adi_gpio_SetHigh(data_DS2401.port, data_DS2401.pins);
        DEBUG_RESULT("adi_gpio_SetHigh data_DS2401.port.", eGpioResult, ADI_GPIO_SUCCESS);
        /* read DS2401 ROM */
        if(OWTouchReset(data_DS2401))
        {
            /* send read ROM Command */
            OWWriteByte(DS2401_READ_ROM_COMMAND,data_DS2401);
            /* read ROM_VALUE */
            OWBlock(ROM_VALUE,8,data_DS2401);
            /* parse family_code */
            family_code=ROM_VALUE[0];
            /* parse Serial_Number*/
            uint8_t loop;
            for(loop=1;loop<8;loop++)
                serial_number|=(64-8*loop)>>ROM_VALUE[loop];
            /* parse crc_byte */
            crc_byte=ROM_VALUE[8];
        }
        
    }
    
    uint16_t  OWTouchReset(PinMap _1wd_pin)
    {
        uint16_t  result;
        ADI_GPIO_RESULT eGpioResult;
        delay_us(STANDARD_SPEED_G);
        eGpioResult = adi_gpio_SetLow (_1wd_pin.port, _1wd_pin.pins);
        delay_us(STANDARD_SPEED_H);
        /*  release the bus */
        eGpioResult = adi_gpio_SetHigh(_1wd_pin.port, _1wd_pin.pins);
        delay_us(STANDARD_SPEED_I);
        /* Sample for presence pulse from slave */
        eGpioResult = adi_gpio_GetData(_1wd_pin.port,_1wd_pin.pins,&result);
        delay_us(STANDARD_SPEED_J);
        return result;
    }
    
    void OWWriteBit(uint8_t bit,PinMap _1wd_pin)
    {
        ADI_GPIO_RESULT eGpioResult;
        eGpioResult = adi_gpio_SetLow(_1wd_pin.port, _1wd_pin.pins);
        if(bit)
            {
                 /* write 1 bit */
                 delay_us(STANDARD_SPEED_A);
                 /*  release the bus */
                 eGpioResult = adi_gpio_SetHigh(_1wd_pin.port, _1wd_pin.pins);
                 delay_us(STANDARD_SPEED_B);             
            }
        else
            {
                 /* write 0 bit */
                 delay_us(STANDARD_SPEED_C);
                 /*  release the bus */
                 eGpioResult = adi_gpio_SetHigh(_1wd_pin.port, _1wd_pin.pins);
                 delay_us(STANDARD_SPEED_D);
            }
    }
    
    uint16_t OWReadBit(PinMap _1wd_pin)
    {
        uint16_t result;
        ADI_GPIO_RESULT eGpioResult;
        eGpioResult = adi_gpio_SetLow(_1wd_pin.port, _1wd_pin.pins);
        delay_us(STANDARD_SPEED_A);
        /*  release the bus */
        eGpioResult = adi_gpio_SetHigh(_1wd_pin.port, _1wd_pin.pins);
        delay_us(STANDARD_SPEED_E);
        /* Sample the bit value from slave */
        eGpioResult = adi_gpio_GetData(_1wd_pin.port,_1wd_pin.pins,&result);
        delay_us(STANDARD_SPEED_F);
        return result;
    }
    
    void OWWriteByte(uint8_t data,PinMap _1wd_pin)
    {
        uint8_t loop;
        // Loop to write each bit in the byte, LS-bit first
        for (loop = 0; loop < 8; loop++)
        {
            OWWriteBit(data & 0x01,_1wd_pin);
            // shift the data byte for the next bit
            data >>= 1;
        }
    }
    
    uint8_t OWReadByte(PinMap _1wd_pin)
    {
        uint8_t loop,result;
        for(loop = 0; loop < 8; loop++)
        {
            // shift the result to get it ready for the next bit
            result >>= 1;
            // if result is one, then set MS bit
            if(OWReadBit(_1wd_pin))
                result|= 0x80;
        }
        return result;
    }
    
    /*
     * Write a 1-Wire data byte and return the sampled result.
    */
    uint8_t OWTouchByte(uint8_t data,PinMap _1wd_pin)
    {
        uint8_t loop,result;
        for(loop = 0; loop < 8; loop++)
        {
            // shift the result to get it ready for the next bit
            result >>= 1;
            // If sending a '1' then read a bit else write a '0'
            if(data & 0x01)
            {
                if(OWReadBit(_1wd_pin))
                    result |= 0x80;
            }
            else
                OWWriteBit(0,_1wd_pin);
            // shift the data byte for the next bit
            data >>= 1;
        }
        return result;
    }
    
    void OWBlock(uint8_t *data, uint8_t data_len,PinMap _1wd_pin)
    {
        uint8_t loop;
        for(loop = 0; loop < data_len; loop++)
        {
            data[loop] = OWTouchByte(data[loop],_1wd_pin);
        }
    }
    
    

Reply
  • I tried to write a driver for this DS2401 could you review it with me. 

    This is the one_wire_driver.h header file

    #ifndef ONE_WIRE_DRIVER
    #define ONE_WIRE_DRIVER
    /*
       see
       https://www.maximintegrated.com/en/app-notes/index.mvp/id/126
    */
    #include <adi_processor.h>
    #include "ADuCM3029.H"
    #include <stddef.h>		/* for 'NULL' */
    #include <string.h>		/* for strlen */
    #include <stdint.h>
    #include <drivers/pwr/adi_pwr.h>
    #include <drivers/gpio/adi_gpio.h>
    #include <drivers/dma/adi_dma.h>
    #include "common.h"
    #include <drivers/general/adi_drivers_general.h>
    
    #define STANDARD_SPEED_A         6u
    #define STANDARD_SPEED_B         64u
    #define STANDARD_SPEED_C         60u
    #define STANDARD_SPEED_D         10u
    #define STANDARD_SPEED_E         9u
    #define STANDARD_SPEED_F         55u
    #define STANDARD_SPEED_G         0u
    #define STANDARD_SPEED_H         480u
    #define STANDARD_SPEED_I         70u
    #define STANDARD_SPEED_J         410u
    
    #define DS2401_READ_ROM_COMMAND	 0x33
    
    
    /* tick every 1us*/
    #define TICKS        (26000000u / 1000000u)
    
    volatile uint32_t usTicks = 0; 
    
    
    typedef struct{
        ADI_GPIO_PORT port;
        ADI_GPIO_DATA pins;
    } PinMap;
    
    
    void delay_us(uint32_t nus);
    
    /* 1-wire basic functions */
    uint16_t OWTouchReset(PinMap _1wd_pin);
    void OWWriteBit(uint8_t bit,PinMap _1wd_pin);
    uint16_t OWReadBit(PinMap _1wd_pin);
    
    /* 1-wire drived functions */
    void OWWriteByte(uint8_t data,PinMap _1wd_pin);
    uint8_t OWReadByte(PinMap _1wd_pin);
    uint8_t OWTouchByte(uint8_t data,PinMap _1wd_pin);
    void OWBlock(uint8_t *data, uint8_t data_len,PinMap _1wd_pin);
    #endif /* ONE_WIRE_DRIVER */
    

    And this is the implementation

    #include "one_wire_driver.h"
    
    /* delay in µs unit*/
    void delay_us(uint32_t nus) {
        while (nus--) {
          while (usTicks != 0) 
          {
          }
        }
    }
    
    /* Tick every 1µs*/
    void SysTick_Handler(){
        usTicks++;
        if(usTicks==26000000u)
        {
           usTicks=0;
        }
    }
    
    uint8_t ROM_VALUE[8];
    volatile uint8_t family_code;
    volatile uint64_t serial_number;
    volatile uint8_t crc_byte;
    
    int main(void)
    {
         PinMap data_DS2401 = { ADI_GPIO_PORT1, ADI_GPIO_PIN_13 };
        /* initialisations */
        uint8_t         gpioMemory[ADI_GPIO_MEMORY_SIZE] = {0};
        ADI_PWR_RESULT  ePwrResult;
        ADI_GPIO_RESULT eGpioResult;
        common_Init();
        
        ePwrResult = adi_pwr_Init();
        DEBUG_RESULT("adi_pwr_Init failed.", ePwrResult, ADI_PWR_SUCCESS);
        ePwrResult = adi_pwr_SetClockDivider(ADI_CLOCK_HCLK, 1u);
        DEBUG_RESULT("adi_pwr_SetClockDivider (HCLK) failed.", ePwrResult, ADI_PWR_SUCCESS);
        ePwrResult = adi_pwr_SetClockDivider(ADI_CLOCK_PCLK, 1u);
        DEBUG_RESULT("adi_pwr_SetClockDivider (PCLK) failed.", ePwrResult, ADI_PWR_SUCCESS);
        
        /* initialize the systick driver */
        SysTick_Config(TICKS);
        
        /* Initialize GPIO driver */
        eGpioResult= adi_gpio_Init(gpioMemory, ADI_GPIO_MEMORY_SIZE);
        DEBUG_RESULT("adi_GPIO_Init failed.", eGpioResult, ADI_GPIO_SUCCESS);
        
        /* set output enable */
        eGpioResult = adi_gpio_OutputEnable(data_DS2401.port, data_DS2401.pins, true);
        DEBUG_RESULT("adi_GPIO_SetOutputEnable failed on data_DS2401.", eGpioResult, ADI_GPIO_SUCCESS);
        /* set pull up. In this case pull-up resistor is external */
        //eGpioResult = adi_gpio_PullUpEnable(data_DS2401.port,data_DS2401.pins,true);
        //DEBUG_RESULT("adi_gpio_PullUpEnable failed on data_DS2401.", eGpioResult, ADI_GPIO_SUCCESS);
        eGpioResult = adi_gpio_SetHigh(data_DS2401.port, data_DS2401.pins);
        DEBUG_RESULT("adi_gpio_SetHigh data_DS2401.port.", eGpioResult, ADI_GPIO_SUCCESS);
        /* read DS2401 ROM */
        if(OWTouchReset(data_DS2401))
        {
            /* send read ROM Command */
            OWWriteByte(DS2401_READ_ROM_COMMAND,data_DS2401);
            /* read ROM_VALUE */
            OWBlock(ROM_VALUE,8,data_DS2401);
            /* parse family_code */
            family_code=ROM_VALUE[0];
            /* parse Serial_Number*/
            uint8_t loop;
            for(loop=1;loop<8;loop++)
                serial_number|=(64-8*loop)>>ROM_VALUE[loop];
            /* parse crc_byte */
            crc_byte=ROM_VALUE[8];
        }
        
    }
    
    uint16_t  OWTouchReset(PinMap _1wd_pin)
    {
        uint16_t  result;
        ADI_GPIO_RESULT eGpioResult;
        delay_us(STANDARD_SPEED_G);
        eGpioResult = adi_gpio_SetLow (_1wd_pin.port, _1wd_pin.pins);
        delay_us(STANDARD_SPEED_H);
        /*  release the bus */
        eGpioResult = adi_gpio_SetHigh(_1wd_pin.port, _1wd_pin.pins);
        delay_us(STANDARD_SPEED_I);
        /* Sample for presence pulse from slave */
        eGpioResult = adi_gpio_GetData(_1wd_pin.port,_1wd_pin.pins,&result);
        delay_us(STANDARD_SPEED_J);
        return result;
    }
    
    void OWWriteBit(uint8_t bit,PinMap _1wd_pin)
    {
        ADI_GPIO_RESULT eGpioResult;
        eGpioResult = adi_gpio_SetLow(_1wd_pin.port, _1wd_pin.pins);
        if(bit)
            {
                 /* write 1 bit */
                 delay_us(STANDARD_SPEED_A);
                 /*  release the bus */
                 eGpioResult = adi_gpio_SetHigh(_1wd_pin.port, _1wd_pin.pins);
                 delay_us(STANDARD_SPEED_B);             
            }
        else
            {
                 /* write 0 bit */
                 delay_us(STANDARD_SPEED_C);
                 /*  release the bus */
                 eGpioResult = adi_gpio_SetHigh(_1wd_pin.port, _1wd_pin.pins);
                 delay_us(STANDARD_SPEED_D);
            }
    }
    
    uint16_t OWReadBit(PinMap _1wd_pin)
    {
        uint16_t result;
        ADI_GPIO_RESULT eGpioResult;
        eGpioResult = adi_gpio_SetLow(_1wd_pin.port, _1wd_pin.pins);
        delay_us(STANDARD_SPEED_A);
        /*  release the bus */
        eGpioResult = adi_gpio_SetHigh(_1wd_pin.port, _1wd_pin.pins);
        delay_us(STANDARD_SPEED_E);
        /* Sample the bit value from slave */
        eGpioResult = adi_gpio_GetData(_1wd_pin.port,_1wd_pin.pins,&result);
        delay_us(STANDARD_SPEED_F);
        return result;
    }
    
    void OWWriteByte(uint8_t data,PinMap _1wd_pin)
    {
        uint8_t loop;
        // Loop to write each bit in the byte, LS-bit first
        for (loop = 0; loop < 8; loop++)
        {
            OWWriteBit(data & 0x01,_1wd_pin);
            // shift the data byte for the next bit
            data >>= 1;
        }
    }
    
    uint8_t OWReadByte(PinMap _1wd_pin)
    {
        uint8_t loop,result;
        for(loop = 0; loop < 8; loop++)
        {
            // shift the result to get it ready for the next bit
            result >>= 1;
            // if result is one, then set MS bit
            if(OWReadBit(_1wd_pin))
                result|= 0x80;
        }
        return result;
    }
    
    /*
     * Write a 1-Wire data byte and return the sampled result.
    */
    uint8_t OWTouchByte(uint8_t data,PinMap _1wd_pin)
    {
        uint8_t loop,result;
        for(loop = 0; loop < 8; loop++)
        {
            // shift the result to get it ready for the next bit
            result >>= 1;
            // If sending a '1' then read a bit else write a '0'
            if(data & 0x01)
            {
                if(OWReadBit(_1wd_pin))
                    result |= 0x80;
            }
            else
                OWWriteBit(0,_1wd_pin);
            // shift the data byte for the next bit
            data >>= 1;
        }
        return result;
    }
    
    void OWBlock(uint8_t *data, uint8_t data_len,PinMap _1wd_pin)
    {
        uint8_t loop;
        for(loop = 0; loop < data_len; loop++)
        {
            data[loop] = OWTouchByte(data[loop],_1wd_pin);
        }
    }
    
    

Children