Searching \ for 'I2C read' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/i2cs.htm?key=i2c
Search entire site for: 'I2C read'.

Truncated match.
PICList Thread
'I2C read'
1999\09\25@211521 by Simon Redwood

flavicon
picon face
Reply To: "Simon Redwood" <spam_OUTspredwoodTakeThisOuTspamsri-net.demon.co.uk>
X-Mailer: ELM [version 2.4ME+ PL37 (25)]
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Content-Length: 4784

I am stuck tryubg to perform an I2C current address read on a 24C02 eeprom,
the interface is bui;lt up of pin 1 and pin 2 of the parallel port using pin
13 to read.  There is I believe a small bug in the code, but I cannot find
it.  the read produces an FF each time.  If I try the same program on a
24C08 it starts a sequential read about 1/3 of the way through the eeprom.

Any ideas, help gratefully received.

/*
* 24Cxx_1.C
*
* Illustrates how to write to and from a 24xx EEPROM.
*
* Parallel Port                         24Cxx
*
* Data0         (term 2) ------------------ SDA (term 6) ----- To Other
* /STROBE       (term 1) ------------------ SCL (term 5) ----- 24C02 Devices
*
* pin 13 (select) and pin 2 (data 0) are tied, as DataPort is write only, and
* status port is read only.
*
* 12 uclocks = approx 10us
*
*/

#include <stdio.h>
#include <time.h>
#include <pc.h>
#include <string.h>
#include <math.h>

#define DATA 0x0378
#define STATUS  DATA+1
#define CONTROL DATA+2

#define FOO0    0x00 /* 0 */
#define FOO1    0x02 /* 1 */
#define FOO2    0x04 /* 2 */
#define FOO3    0x06 /* 3 */
#define FOO4    0x08 /* 4 */
#define FOO5    0x10 /* 5 */
#define FOO6    0x12 /* 6 */
#define FOO7    0x14 /* 7 */

#define DEVSEL_R (0xA0|FOO2|0x01)
#define DEVSEL_W (0xA0|FOO2|0x00)

#define DELAY_10_MICROSECS 12

typedef unsigned char byte;

int IsBitSet(byte val, int bit)
{
       if((val & (int)pow2(bit)) != 0)
               return 1;
       return 0;
}

int SetBit(byte *val, int bit)
{
       int i;

       if((*val & (int)pow2(bit)) == 0) {
               i = (int)pow2(bit);
               *val = *val | i;
       }

       return 0;
}

int ResetBit(byte *val, int bit)
{
       int i;

       if((*val & (int)pow2(bit)) != 0) {
               i = (int)pow2(bit);
               *val = *val ^ i;
       }

       return 0;
}

volatile void nothing(void)
{
       long j;

       j = (long)uclock()+DELAY_10_MICROSECS;
       while ((long)uclock()<j);
}

void low_SDA(void)
{
       byte val;

       val = inportb(DATA);
       val = val ^ 0x01;
       outportb(DATA, val);
       nothing();
}

void high_SDA(void)
{
       byte val;

       val = inportb(DATA);
       val = val | 0x01;
       outportb(DATA, val);
       nothing();
}

void low_SCL(void)
{
       outportb(CONTROL, 0x00^0x01);
          /* inversion required on 1st bit of CONTROL port */
       nothing();
}

void high_SCL(void)
{

       outportb(CONTROL, 0x01^0x01);
          /* inversion required on ls bit of DATA port */
       nothing();
}

void start(void)
/* bring SDA high to low while SCL is high */
{
  high_SDA();
  high_SCL();
  low_SDA();  /* bring SDA low while clock is high */
  low_SCL();
  nothing();
}

void stop(void)
/* bring SDA low to high while SCL is high */
{
  low_SDA();
  high_SCL();
  high_SDA();  /* bring SDA high while clock is high */
  low_SCL();
  nothing();
}

void out_byte(byte o_byte)
/* shift out byte, beginning with most significant bit */
{
       long j;
       int n;

       j = (long)uclock();
#if 1
       for(n=7; n>=0; n--) { /* note SCL is low during transitions on SDA */
#else
       for(n=0; n<8; n++) { /* note SCL is low during transitions on SDA */
#endif

               if (((o_byte >> n) & 0x01) == 0) {
                       low_SDA();
               } else {
                       high_SDA();
               }

               /* timing */
               j+=(DELAY_10_MICROSECS/2);
               while ((long)uclock()<j);

               high_SCL();

               /* timing */
               j+=(DELAY_10_MICROSECS/2);
               while ((long)uclock()<j);

               low_SCL();
       }
}

byte in_byte(void)
/* fetch byte, most significant byte first */
{
       byte i_byte=0x00;
       long j;
       int n;

       j = (long)uclock();
       for (n=0; n<8; n++) {

               low_SCL();

               /* timing */
               j+=(DELAY_10_MICROSECS/2);
               while ((long)uclock()<j);

               high_SCL();
               j+=(DELAY_10_MICROSECS/2);
               while ((long)uclock()<j);

               i_byte=(i_byte << 1) | ( (inportb(STATUS)&0x10)>>4);

       }

       return(i_byte);
}

byte nack(void)
{
       byte ack_bit;

       high_SDA();

       high_SCL();

       if (((inportb(STATUS)&0x10)>>4)==0) {
               ack_bit=0;
       } else {
               ack_bit=1;
       }

       low_SCL();

       return(ack_bit);
}


byte ack(byte device)
{
  byte ack_bit;
  out_byte(DEVSEL_W);          /* send preface */
  ack_bit=nack();              /* look for acknowledgement */
  return(ack_bit);
}


byte read_current_data(void)
/* read from specified address.  return fetched data  */
{
       byte i_byte = 0x00;

       nack();

       high_SDA();

       i_byte = in_byte();

       return(i_byte);
}

void main(int argc, char *argv[])
{
  byte i_byte[80];
  int i;

       {
               byte val;

               val = inportb(STATUS);
               SetBit(&val, 4);
               outportb(STATUS, val);
       }

       memset(i_byte, '\000', sizeof(i_byte));

       if(argc > 0) {
               if(strcmp(argv[1], "D")==0) {
                       byte address = 0x00;

                       fprintf(stderr, "Setting address: %02x\n", address);
                       start();
                       out_byte(DEVSEL_W);
                       nack();
                       out_byte(address);
                       nack();
               }
       }

       start();
       /* Device Selection */

       out_byte(DEVSEL_R);
                               /* preface is now read.  1010 a2 a1 a0 1 */

       i=0;
       i_byte[i]=read_current_data();
       stop();

       i=0;
       fprintf(stderr, "0x%02X ", i_byte[i]);
}

--
Regards,
Simon

{ ICQ#:         12229096                        }
{ Email:        .....spredwoodKILLspamspam@spam@sri-net.demon.co.uk   }
{ Internet:     http://www.sri-net.demon.co.uk         }

More... (looser matching)
- Last day of these posts
- In 1999 , 2000 only
- Today
- New search...