Beispiel #1
0
static inline void i2c_automaton(uint32_t state)
{
    switch (state) {
    case I2C_START:
    case I2C_RESTART:
        I2cSendByte(i2c_slave_addr);
        I2cClearStart();
        i2c_index = 0;
        break;
    case I2C_MR_DATA_ACK:
        if (i2c_index < i2c_len) {
            i2c_buf[i2c_index] = I2C_DATA_REG;
            i2c_index++;
            I2cReceive(i2c_index < i2c_len - 1);
        }
        else {
            /* error , we should have got NACK */
            I2cSendStop();
        }
        break;
    case I2C_MR_SLA_ACK: /* At least one char */
        /* Wait and reply with ACK or NACK */
        I2cReceive(i2c_index < i2c_len - 1);
        break;
    case I2C_MR_SLA_NACK:
    case I2C_MT_SLA_NACK:
        I2cSendStart();
        break;
    case I2C_MT_SLA_ACK:
    case I2C_MT_DATA_ACK:
        if (i2c_index < i2c_len) {
            I2cSendByte(i2c_buf[i2c_index]);
            i2c_index++;
        }
        else {
            I2cSendStop();
        }
        break;
    case I2C_MR_DATA_NACK:
        if (i2c_index < i2c_len) {
            i2c_buf[i2c_index] = I2C_DATA_REG;
        }
        I2cSendStop();
        break;
    default:
        I2cSendStop();
        /* LED_ON(2); FIXME log error */
    }
}
Beispiel #2
0
__attribute__ ((always_inline)) static inline void I2cAutomaton(int32_t state, struct i2c_periph* p) {
  struct i2c_transaction* trans = p->trans[p->trans_extract_idx];
  switch (state) {
    case I2C_START:
    case I2C_RESTART:
      // Set R/W flag
      switch (trans->type) {
        case I2CTransRx :
          SetBit(trans->slave_addr,0);
          break;
        case I2CTransTx:
        case I2CTransTxRx:
          ClearBit(trans->slave_addr,0);
          break;
        default:
          break;
      }
      I2cSendByte(p->reg_addr,trans->slave_addr);
      I2cClearStart(p->reg_addr);
      p->idx_buf = 0;
      break;
    case I2C_MR_DATA_ACK:
      if (p->idx_buf < trans->len_r) {
        trans->buf[p->idx_buf] = ((i2cRegs_t *)(p->reg_addr))->dat;
        p->idx_buf++;
        I2cReceive(p->reg_addr,p->idx_buf < trans->len_r - 1);
      }
      else {
        /* error , we should have got NACK */
        I2cFail(p,trans);
      }
      break;
    case I2C_MR_DATA_NACK:
      if (p->idx_buf < trans->len_r) {
        trans->buf[p->idx_buf] = ((i2cRegs_t *)(p->reg_addr))->dat;
      }
      I2cSendStop(p,trans);
      break;
    case I2C_MR_SLA_ACK: /* At least one char */
      /* Wait and reply with ACK or NACK */
      I2cReceive(p->reg_addr,p->idx_buf < trans->len_r - 1);
      break;
    case I2C_MR_SLA_NACK:
    case I2C_MT_SLA_NACK:
      /* Slave is not responding, transaction is failed */
      I2cFail(p,trans);
      break;
    case I2C_MT_SLA_ACK:
    case I2C_MT_DATA_ACK:
      if (p->idx_buf < trans->len_w) {
        I2cSendByte(p->reg_addr,trans->buf[p->idx_buf]);
        p->idx_buf++;
      } else {
        if (trans->type == I2CTransTxRx) {
          trans->type = I2CTransRx;	/* FIXME should not change type */
          p->idx_buf = 0;
          trans->slave_addr |= 1;
          I2cSendStart(p);
        } else {
          I2cSendStop(p,trans);
        }
      }
      break;
    default:
      I2cFail(p,trans);
      /* FIXME log error */
      break;
  }
}