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

help :one wire master bridge ds2482 interface with lpc2148

hi aim implementing i-button interface to lpc2148 using ds2482 1-wire to i2c bridge. my problem is i am using hardware i2c controller in lpc2148.i am writing 3 routine
1 detect the i button
2 read i-button
3 write i-button each routine using i2c interrupt.i seen some example in that all i2c code are written in side the interrupt routine only.
im confused about how can i uses the interrupt routine for 3 main routine. and can i enable the i2c and initiate start and send slave addresses and receive the acknowledgment and come back from interrupt routine and do some work in main routine and again enter to i2c interrupt routine and continue the next i2c operation

  • aka "Finite State Machine" or "FSM" for short.

    This sounds like a job for a State Machine:

    Your interrupt routine besically just detects "Events", and it is up to the State Machine (in your "main" code) to handle these events.

    Google for "State Machine", "Finite State Machine", and "FSM"...

    Have you looked at the sample code available from Maxim?

  • That is generally a bad idea.

    In general, interrupt handlers should be kept as short and quick as possible - just gathering data and/or setting flags to be used by the "main" code to do the "main" processing work...

  • hi .. can i configure I2CON to certain value and I2DAT with certain value after this enable I2C interrupt . in isr of I2C im not doing anything and checking status using containt of I2CSTAT resister to do the next part of i2c once again put the value in I2DAT and I2CON and once again enabling I2C interrupt.

  • It sounds like your first step needs to be to learn how to use the I2C controller in the LPC2148?

    You need to do that before you start worrying about the DS2482.

    I suggest that you start by reading the LPC2148 datasheet, and working through all the NXP examples and application notes that you can find.

    See also: http://www.keil.com/download/list/arm.htm

    The Maxim APPLICATION NOTE 3684, "How to Use the DS2482 I2C 1-Wire Master" requires only five I2C routines:

    I2C_start: I2C start command.
    I2C_rep_start: I2C repeated start command.
    I2C_stop: I2C stop command.
    I2C_write: Writes a byte to the I2C bus.
    I2C_read: Reads a byte from the I2C bus.

    So you need to get yourself to the stage of being able to write those 5 routines...

  • Is there any particular reason you are using a DS2482 as opposed to implementing a 1-Wire master on your LPC2148? For instance are you out of GPIO lines (you only need one)?

    The reason I ask is because I think writing your own 1-Wire master is a lot simpler than using the I2C to 1-Wire bridge. Removing I2C from the equation is one less thing that can go wrong, if you know what I mean.

    Either way, the app note Andy mentioned before (www.maxim-ic.com/.../3684) has a lot of code in it that you could use. I also have some 1-wire code for a lpc2148 that I wrote that I could post if you want.

  • It is trivial to bit-bang the one-wire protocol. The only real problem is if the processor is constantly busy, not having any time slots available where it may busy-wait for the bit delays and with multiple (or slow) high-priority interrupt routines that makes it hard to figure out a worst-case scenario.

    Since everything in the one-wire interface is handled with varying pulse lengths, delays may only deviate with a few us.

  • "Since everything in the one-wire interface is handled with varying pulse lengths, delays may only deviate with a few us."

    Note that timing only needs to be controlled within a timeslot - the timing between timeslots is completely uncritical.

  • Yes, infinite pauses are allowed, as long as they are not put within a bit read, bit write or presence detect. And a reset may be infinitely long.

    If the target has other very high-priority tasks, the one-wire communication can be an interesting exercise in time multiplexing.

  • please send 1-wire code on lpc2148

  • I have pasted what I have. My code is set up to use Timer0 irq to clear the busy wait flag. 1-Wire line is on P0.4.

    Please note that I haven't finished the Overdrive implementation. I was planning to switch on ODFlag to vary the low pulse times.

    /*
    OneWire.c
    Source file for one wire ARM LPC2148 code
    One Wire line is on P0.4
    */
    
    #include <LPC21xx.H>
    #include <stdio.h>
    #include <stdlib.h>
    #include "OneWire.h"
    
    /********golbals***********/
    char ODflag = 0;
    volatile char waiting = 1;
    /********end globals******/
    
    /********Macros************/
    #define OWline  0x00000010      //OWline to p0.4
    #define ReadOne   IO0PIN&OWline
    /*******end Macros*********/
    
    /*************************/
    //wait clears the waiting flag
    //and dissables timer irq
    /*************************/
    __irq void wait()
    {
            T0IR = 1;              // Clear interrupt flag
            T0TCR = 0;
            waiting = 0;               // clear flag when irq fires
            VICVectAddr = 0;       // Acknowledge Interrupt
    }
    /*************************/
    //initializes 1-Wire pin and
    //timer irq
    /*************************/
    void OW_init()
    {
            PINSEL0 &= 0xFFFFFFCF;                                               // set pinsel to gpio p0.4
            IO0DIR &=  ~OWline;                                                  // set to input
            T0MCR = 3;                                   // Interrupt and Reset on MR0
            T0TCR = 0;                                   // Timer0 dont enable until readyEnable
            VICVectAddr1 = (unsigned long)wait;          // set interrupt vector in 0
            VICVectCntl1 = 0x20 | 4;                     // use it for Timer 0 Interrupt
            VICIntEnable = 0x00000010;                   // Enable Timer0 Interrupt
    
    }
    
    /*************************/
    //Pulls 1-Wire line low for
    //specified number of cycles
    /*************************/
    __inline void PullLineLow(unsigned int cycles)
    {
        /* 60Mhz/4 = 15Mhz per instruction */
            T0MR0 = cycles;         //set # of cycles for irq
            waiting=1;                              //reset global
            //pull line low here
            IO0DIR |= OWline;           //set p0.0 to ouput
            IO0CLR |= OWline;               //set p0.0 to low
            T0TCR = 1;              // Timer0 enable
            while(waiting){}                //wait here until irq fires
            //let go of line here
            IO0DIR &= ~OWline;          //set to input (hi-z)
            waiting=1;                              //reset global
    }
    
    /*************************/
    //same as PullLineLow, without pulling line low
    /*************************/
    __inline void delay(unsigned int cycles)
    {
        /* 60Mhz/4 = 15Mhz per instruction */
            T0MR0 = cycles;
            waiting=1;                              //reset global
            T0TCR = 1;              // Timer0 enable
            while(waiting){}
            waiting=1;
    }
    
    /****OW_ResetAndPD********/
    //Sends a standard speed One Wire
    //Reset. Returns if a PD pulse
    //is read.
    /*************************/
    int OW_ResetAndPD()
    {
            //Pull line low for reset pulse
            PullLineLow(7200);          // pull low ~480us
            delay(900);                     // wait ~60us for tpdh
            //read Presence detect
            if( ReadOne )                   // line high, no presence detect low
                    return 0;                       // means no part or error
    
            delay(2700);            // finish tpdl ~180us
    
            ODflag = 0;
            return 1;
    }
    
    
    /****OW_ReadByte***********/
    //Reads a 1-Wire byte and returns it.
    /****************************/
    char OW_ReadByte()
    {
            char Byte;
            short i;
    
            Byte=0;
            for(i=0;i<8;i++)
            {
                    PullLineLow(70);  //low for ~5us
                    delay(140);       //wait about 10us
                    if( ReadOne )
                            Byte |= (1<<i);
                    delay(675);       //wait45; //complete tslot
            }
            return Byte;
    }
    
    /****OW_ReadByte***********/
    //Reads multiple 1-Wire bytes
    //and returns a pointer to them.
    /****************************/
    void OW_ReadBytes(int howMany, char* Byte)
    {
            int byteCount;
    
            for(byteCount=0;byteCount<howMany;byteCount++)
                    Byte[byteCount] = OW_ReadByte();
    }
    
    /****OW_WriteByte***********/
    //Writes a 1-wire byte.
    /****************************/
    void OW_WriteByte(char Byte)
    {
            int i;
    
            for(i=0;i<8;i++)
            {
                    if(Byte & (1<<i))     {
                            PullLineLow(70); //line low for ~5us
                            delay(900);              //line high for rest of tslot 60us
                    }else {
                       PullLineLow(970); //lin low for ~65us
                    }
                    delay(70);            //trec about 5us
            }
            return;
    }
    
    /****OW_WriteByte***********/
    //Writes Multiple 1-wire bytes.
    /****************************/
    void OW_WriteBytes(char* Bytes, int howMany)
    {
            int i;
            for(i=0;i<howMany;i++)
                    OW_WriteByte(Bytes[i]);
    
            return;
    }
    
    /****OW_ResetAndSkipRom***/
    //Sends a standard speed One Wire
    //Reset and a skip rom command. Returns a
    //1 on successful PD pulse.
    /**************************/
    int OW_ResetAndSkipRom()
    {
            PullLineLow(7200);       //pull low ~480us
            delay(900);              // wait ~60us for tpdh
            //read Presence detect
            if( ReadOne )        //line high, no presence detect low
                    return 0;                //means no part or error
    
            delay(2700);         //finish tpdl ~180us
            ODflag = 0;
    
            OW_WriteByte(0xCC);
    
            return 1;
    }
    
    /****OW_ResetAndMatchRom***/
    //Sends a standard speed One Wire
    //Reset and a match rom command with
    //Rom Code. Fails if no PD is read.
    /****************************/
    int OW_ResetAndMatchRom(char* Rom)
    {
            PullLineLow(7200);       //pull low ~480us
            delay(900);              // wait ~60us for tpdh
            //read Presence detect
            if( ReadOne )        //line high, no presence detect low
                    return 0;                //means no part or error
    
            delay(2700);         //finish tpdl ~180us
    
            ODflag = 0;
            OW_WriteByte(0x55);  //Match Rom
            OW_WriteBytes(Rom,8); //Write RomCode
            return 1;
    }
    
    void OW_WriteScratch(char* scratchpadData,char TA1,char TA2)
    {
    
            OW_WriteByte(0x0F); //write scratch
            OW_WriteByte(TA1); //write TA1
            OW_WriteByte(TA2); //write TA2
            OW_WriteBytes(scratchpadData,32); //write scratch
    
            return;
    }
    
    
    
    
    

  • int OW_ReadScratch(char* scratchpadData,char TA1,char TA2,char ES)
    {
            char readTA1,readTA2,readES;
            char* readScratchPad;
            short i;
    
            readScratchPad = 0;
            OW_ResetAndSkipRom();
            OW_WriteByte(0xAA); //read scratch
            readTA1 = OW_ReadByte(); //read TA1
            if(readTA1 != TA1)
                    return 0;
            readTA2 = OW_ReadByte(); //read TA2
            if(readTA2 != TA2)
                    return 0;
            readES = OW_ReadByte(); //read ES byte
            if(readES != ES)
                    return 0;
            OW_ReadBytes(32, readScratchPad ); //read entire scratchpad
            for(i=0;i<32;i++)
            {// make sure it is what we think it is
                    if(readScratchPad[i] != scratchpadData[i])
                            return 0;
            }
    
            return 1;
    }
    
    void OW_CopyScratch(char TA1,char TA2,char ES)
    {
            OW_ResetAndSkipRom();
            OW_WriteByte(0x55);
            OW_WriteByte(TA1);
            OW_WriteByte(TA2);
            OW_WriteByte(ES);
    //      waitSec;
    }
    
    char* OW_ReadRom(char TA1,char TA2,int howmany)
    {
            char* readbytes;
    
            readbytes=0;
            OW_ResetAndSkipRom();
            OW_WriteByte(0xF0);
            OW_WriteByte(TA1);
            OW_WriteByte(TA2);
            OW_ReadBytes(howmany, readbytes); //read 'howmany' bytes of mem
    
            return readbytes;
    }
    
    //////******////////////
    //      Overdrive functions
    ///////////////////////
    
    /****OW_ResetAndSkipRom***/
    //Sends a standard speed One Wire
    //Reset and a OD skip rom command. Returns a
    //1 on successful PD pulse. Done at regular
    //speed, puts part in OD mode.
    /**************************/
    int OW_ResetAndODSkipRom()
    {
            PullLineLow(7200);       //pull low ~480us
            delay(900);              // wait ~60us for tpdh
            //read Presence detect
            if( ReadOne )   //line high, no presence detect low
                    return 0;                //means no part or error
    
            delay(2700);         //finish tpdl ~180us
            OW_WriteByte(0x3C);
    
            ODflag=1;
    
            return 1;
    }
    
    /****OW_ResetAndMatchRom***/
    //Sends a standard speed One Wire
    //Reset and a match rom command with
    //Rom Code. Fails if no PD is read.
    //Reset and PD done at reg speed,
    //puts part in OD mode, sends rom
    //code at OD speeds.
    /****************************/
    int OW_ResetAndODMatchRom(char* Rom)
    {
    
            return 0;
    }
    

  • I forgot to mention that this code uses a MCB2140 running at 60Mhz.

    Drew

  • //one wire interface using ds2482 using LPC2148 hardware I2C
    
    //************** crystal=12Mhz  Pclk=12Mhz**************//
    #include<lpc214x.h>
    void i2c_INIT(void);
    void i2c_STOP(void);
    unsigned int i2c_data_read(void);
    void i2c_data_write(unsigned int);
    void SendI2CAddress_R(unsigned char);
    void SendI2CAddress_W(unsigned char);
    #define ds2482_address_write 0x30
    #define ds2482_address_read 0x31
    #define STA 0x20
    #define SIC 0x08
    #define SI 0x08
    #define STO 0x10
    #define STAC 0x20
    #define AA 0x04
    #define AAC 0x04
    #define I2CBLOCK_ENABLE 0x40 //enable the hardware I2C block
    unsigned int   state;
    //*****************MAIN_START************************//
    main()
    {
    
    unsigned  int value;
    i2c_INIT();
    while(1)
    {
    unsigned int temp=0x00;SendI2CAddress_W(ds2482_address_write);
    
    i2c_data_write(command);
    
    SendI2CAddress_R(ds2482_address_read);
    
    temp=i2c_data_read();
    
    
    
    
      while(1);
    
       }
     }
    //*****************I2C_INITIALIZATION***************************//
    void i2c_INIT(void)
    {
    I2C0CONCLR = 0xFF;
    PINSEL0 |= 0x50; // Set pinouts as scl and sda
    I2C0SCLL=0x64; //Set bit rate 12 Mhz/VPBDIV+SCLH+SCLL
    I2C0SCLH=0x64; //
    
    }
    
    //****************i2c_write*******************//
    void i2c_data_write(unsigned int data)
    I2C0DAT=data;
    while( ! (I2C0CONSET & SI));        //wait untill status available...
    
    state=I2C0STAT;
    
    if(state ==0x28 )
    {
    I2C0CONCLR |= SIC;
    }
    else
    if(state==0x30)// i2c stop condition.
     {
     I2C0CONCLR = SIC;
     I2C0CONSET = STO;
      }
    
    }
    //****************i2c_address_write*****************//
    void SendI2CAddress_W(unsigned char Addr_S)
    {
      I2C0CONCLR = 0xFF; // function would hang.
     I2C0CONSET = I2CBLOCK_ENABLE; // Hardware I2C bus //block enabled
    
     I2C0CONSET = STA ; // set STA - allow master to //acknowlege slave;
     while(I2C0STAT!=0x08); // Wait for start to be completed
    I2C0CONCLR =             STAC    ;//stop repeatrd //start condition
     I2C0DAT = Addr_S; // Charge slave Address
     I2C0CONCLR = SIC;
     while( ! ( I2C0CONSET & SI)) ; // wait till status //available
    state=I2C0STAT; // read Status.See standard error codes
    if(state ==  0x18)
    {
    state=I2C0STAT; // read Status.See standard error codes
    }
    else
    if(state !=0x18)
    {
    
    i2c_STOP();
    }
    }
    //****************i2c_address_read*****************//
    void SendI2CAddress_R(unsigned char Addr_S)
    {
      I2C0CONCLR = 0xFF; // function would hang.
     I2C0CONSET = I2CBLOCK_ENABLE; // Hardware I2C bus block enabled
    
     I2C0CONSET = STA | AA; // set STA - allow master to //acknowlege slave;
     while(I2C0STAT!=0x08); // Wait for start to be //completed
     I2C0CONCLR = STAC;//clear repeated start condition
     I2C0DAT = Addr_S; // Charge slave Address
     I2C0CONCLR = SIC;
    while( !(I2C0CONSET & SI)) ;// wait till  status //available
    state=I2C0STAT;// read Status. See standard error code
      if(state !=0x40)
    {
    
    i2c_STOP();
    }
    else
    if(state ==  0x40)
    {
    
    
      state=I2C0STAT; // read Status. See standard error codes
    
    }
    
    }
    
    //*******************I2C_READ_DATA*****************//
    unsigned int i2c_data_read(void)
    {
             unsigned int temp;
               I2C0CONCLR = SIC;
    while( ! ( I2C0CONSET & SI)) ; // wait till status available
    
    state=I2C0STAT;
    
    if(state == 0x50)
    {
    return  I2C0DAT;
    }
    else
    if(state== 0x58)
    {
    
    i2c_STOP();
    }
    
    }
    // ********************I2C_STOP**************************//
    void i2c_STOP(void)
    {
     while( ! ( I2C0CONSET & SI)) ; // wait till status available
     I2C0CONSET = STO;
    I2C0CONCLR = SIC;
    
    
    }
    
    }
    
    ******************************************
    


    1.my problem is that when i send the address to i2c slave im getting status code as 0x18 ie address+w is sented to save and ack is received by master.
    2. when i try to write data im getting status code as 0x30 insted of 0x28 i.e. data on I2C0DAT is transmitted and ack not recived.

  • What is the value of command in i2c_data_write(command)
    ? I think if you send an invalid command the ds2482 will nack.

    0xF0 is a device reset and clears the state machine of the DS2482, have you tried writing that as your first command?