Esempio n. 1
0
File: i2c_hw.c Progetto: sch17/wasp
void i2c_transmit(uint8_t slave_addr, uint8_t len, volatile bool_t* finished) {
    i2c_len = len;
    i2c_slave_addr = slave_addr & ~I2C_RECEIVE;
    i2c_finished = finished;
    i2c_status = I2C_BUSY;
    I2cSendStart();
}
Esempio n. 2
0
bool_t i2c_submit(struct i2c_periph* p, struct i2c_transaction* t) {

  uint8_t idx;
  idx = p->trans_insert_idx + 1;
  if (idx >= I2C_TRANSACTION_QUEUE_LEN) idx = 0;
  if (idx == p->trans_extract_idx) {
    /* queue full */
    p->errors->queue_full_cnt++;
    t->status = I2CTransFailed;
    return FALSE;
  }
  t->status = I2CTransPending;

  /* disable I2C interrupt */
  //uint8_t* vic = (uint8_t*)(p->init_struct);
  //VICIntEnClear = VIC_BIT(*vic);
  disableIRQ();

  p->trans[p->trans_insert_idx] = t;
  p->trans_insert_idx = idx;
  /* if peripheral is idle, start the transaction */
  if (p->status == I2CIdle)
    I2cSendStart(p);
  /* else it will be started by the interrupt handler */
  /* when the previous transactions completes         */

  /* enable I2C interrupt again */
  //VICIntEnable = VIC_BIT(*vic);
  enableIRQ();

  return TRUE;
}
Esempio n. 3
0
bool_t i2c_submit(struct i2c_periph* p, struct i2c_transaction* t) {
  unsigned cpsr;

  uint8_t idx;
  idx = p->trans_insert_idx + 1;
  if (idx >= I2C_TRANSACTION_QUEUE_LEN) idx = 0;
  if (idx == p->trans_extract_idx) {
    t->status = I2CTransFailed;
    return FALSE;  /* queue full */
  }
  t->status = I2CTransPending;

  uint8_t* vic = (uint8_t*)(p->init_struct);
  cpsr = disableIRQ();                                // disable global interrupts
  VICIntEnClear = VIC_BIT(*vic);
  restoreIRQ(cpsr);                                   // restore global interrupts

  p->trans[p->trans_insert_idx] = t;
  p->trans_insert_idx = idx;
  /* if peripheral is idle, start the transaction */
  if (p->status == I2CIdle)
    I2cSendStart(p);
  /* else it will be started by the interrupt handler */
  /* when the previous transactions completes         */

  //int_enable();
  cpsr = disableIRQ();                                // disable global interrupts
  VICIntEnable = VIC_BIT(*vic);
  restoreIRQ(cpsr);                                   // restore global interrupts

  return TRUE;
}
Esempio n. 4
0
__attribute__ ((always_inline)) static inline void I2cEndOfTransaction(struct i2c_periph* p) {
  // handle fifo here
  p->trans_extract_idx++;
  if (p->trans_extract_idx >= I2C_TRANSACTION_QUEUE_LEN)
    p->trans_extract_idx = 0;
  // if no more transaction to process, stop here, else start next transaction
  if (p->trans_extract_idx == p->trans_insert_idx) {
    p->status = I2CIdle;
  }
  else {
    I2cSendStart(p);
  }
}
Esempio n. 5
0
File: i2c_hw.c Progetto: sch17/wasp
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 */
    }
}
Esempio n. 6
0
static SiiResultCodes_t CraWriteBlockI2c ( int_t busIndex, uint8_t deviceId, uint8_t regAddr, const uint8_t *pBuffer, uint16_t count )
{
    SiiResultCodes_t status = SII_ERR_FAIL;

    do {
        // Send the register address but don't send stop
        if ( I2cSendStart( busIndex, deviceId, &regAddr, 1, FALSE ) != PLATFORM_SUCCESS )
        {
            break;
        }
        // Send the remainder of the data, if necessary
        if ( I2cSendContinue( busIndex, pBuffer, count, TRUE ) != PLATFORM_SUCCESS )
        {
            break;
        }
        status = SII_SUCCESS;
    } while (0);

    return( status );
}
Esempio n. 7
0
static SiiResultCodes_t CraReadBlockI2c (int_t busIndex, uint8_t deviceId, uint8_t regAddr, uint8_t *pBuffer, uint16_t count )
{
    SiiResultCodes_t status = SII_ERR_FAIL;

    do {
        // Send the register address and stop bit
        if ( I2cSendStart( busIndex, deviceId, &regAddr, 1, FALSE ) != PLATFORM_SUCCESS )
        {
            break;
        }
        // Receive the requested number of data bytes
        if ( I2cReceiveStart( busIndex, deviceId, pBuffer, count, TRUE ) != PLATFORM_SUCCESS )
        {
            break;
        }

        status = SII_SUCCESS;
    } while (0);

    return( status );
}
Esempio n. 8
0
bool_t i2c_submit(struct i2c_periph* p, struct i2c_transaction* t) {

  uint8_t idx;
  idx = p->trans_insert_idx + 1;
  if (idx >= I2C_TRANSACTION_QUEUE_LEN) idx = 0;
  if (idx == p->trans_extract_idx) {
    t->status = I2CTransFailed;
    return FALSE;  /* queue full */
  }
  t->status = I2CTransPending;
  int_disable();
  p->trans[p->trans_insert_idx] = t;
  p->trans_insert_idx = idx;
  /* if peripheral is idle, start the transaction */
  if (p->status == I2CIdle)
    I2cSendStart(p);
  /* else it will be started by the interrupt handler */
  /* when the previous transactions completes         */
  int_enable();

  return TRUE;
}
Esempio n. 9
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;
  }
}