A piece of my I2C code... then you can compare with yours

/* SCL P2.1 */
#define SCL_L    P2OUT &= ~BIT1
#define SCL_H    P2OUT |= BIT1
/* SDA P1.4 */
#define SDA_L    P1DIR |= BIT4
#define SDA_HIZ  P1DIR &= ~BIT4
#define SDA_READ (P1IN & BIT4)

#define send_start(x) { SDA_L; SCL_L; }
#define send_stop(x)  { SDA_L; SCL_H; SDA_HIZ; SDA_L; SCL_H; }
#define send_ack(x)   { SDA_L; SCL_H; SCL_L; SDA_HIZ; }
#define send_noack(x) { SDA_HIZ; SCL_H; SCL_L; }

/* return 0 if fails
 * my I2C device will answer with ACK in less than 100ns
 * just a nop will be enough to wait ack from device */
int wait_ack(void) {
  int k = 1;
  SDA_HIZ;
  nop();
  SCL_H;
  nop();
  if (SDA_READ)
    k = 0;
  SCL_L;
  return k;
}

#define send_8bits(val) {   \
  for(i = 0; i < 8; i++) {  \
    if (val & 0x80) {       \
      SDA_HIZ;              \
    } else {                \
      SDA_L;                \
    }                       \
    SCL_H;                  \
    val <<= 1;              \
    SCL_L;                  \
  }                         \
  SDA_HIZ;                  \
}

uint8_t recv_8bits (void) {
  unsigned int i, val = 0;
  for (i = 0; i < 8; i++) {
    val <<= 1;
    SCL_H;
    if (SDA_READ)
      val |= 1;
    SCL_L;
  }
  return val;
}

void i2c_init(void)
{
  P1SEL &= ~BIT4; /* GPIO P1.4 */
  P1OUT &= ~BIT4; /* output always 0 */
  SDA_HIZ;

  P2SEL &= ~BIT1; /* GPIO P2.1 */
  P2DIR |= BIT1;  /*P2.1 output (SCL) */
  SCL_H;
}

/* size is 0 for 8bits or 1 for 16bits */
int i2c_write (uint8_t addr, uint16_t val, int size) {
  int i;

  send_start();
  /* BIT0 is 0 for WRITE */
  addr <<= 1;
  send_8bits(addr);
  if (! wait_ack()) {
    i2c_sync();
    return 0;
  }
  if (size) {
    uint16_t v;
    v = val >> 8;
    send_8bits(v);
    if (! wait_ack()) {
      i2c_sync();
      return 0;
    }
  }
  send_8bits(val);
  if (! wait_ack()) {
    i2c_sync();
    return 0;
  }
  send_stop();
  return 1;
}

/* size is 0 for 8bits or 1 for 16bits */
int i2c_read  (uint8_t addr, uint16_t * val, int size) {
  int i, ret;

  send_start();
  addr <<= 1;
  /* BIT0 is 1 for READ */
  addr |= 0x01;

  send_8bits(addr);
  if (wait_ack()) {
    *val = 0;
    if (size) {
      * (((uint8_t *) val) + 1) = recv_8bits();
      send_ack();
    }
    * (uint8_t *) val = recv_8bits();
    send_noack();
    send_stop();
    ret = 1;
  }
  else {
    ret = 0;
  }
  return ret;
}


 Fri, Sep 24, 2004 at 06:04:25PM -0500, karan wrote:
> hi,
> im trying to bit-bang i2c...
> here's part of my code for checking the line on the port..

Reply via email to