Esempio n. 1
0
static bool
i2c_isr(void)
{
  bool handled = false;

  if (read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_STOP_DET_MASK) {
    i2c_data_read();

    write(QUARKX1000_IC_INTR_MASK, 0);
    read(QUARKX1000_IC_CLR_INTR);

    if (device.direction == I2C_DIRECTION_WRITE) {
      if (device.config.cb_tx)
        device.config.cb_tx();
    } else {
      if (device.config.cb_rx)
        device.config.cb_rx();
    }

    handled = true;
  }

  if (read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK) {
    i2c_data_send();
    if (device.rx_tx_len <= 0) {
      set_value(QUARKX1000_IC_INTR_MASK,
        QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK, QUARKX1000_IC_INTR_STAT_TX_EMPTY_SHIFT, 0);
      set_value(QUARKX1000_IC_INTR_MASK,
        QUARKX1000_IC_INTR_STAT_STOP_DET_MASK, QUARKX1000_IC_INTR_STAT_STOP_DET_SHIFT, 1);
    }

    handled = true;
  }

  if(read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_RX_FULL_MASK) {
    i2c_data_read();

    handled = true;
  }

  if (read(QUARKX1000_IC_INTR_STAT) & (QUARKX1000_IC_INTR_STAT_TX_ABRT_MASK
    | QUARKX1000_IC_INTR_STAT_TX_OVER_MASK | QUARKX1000_IC_INTR_STAT_RX_OVER_MASK
    | QUARKX1000_IC_INTR_STAT_RX_UNDER_MASK)) {
    write(QUARKX1000_IC_INTR_MASK, 0);
    read(QUARKX1000_IC_CLR_INTR);

    if (device.config.cb_err)
      device.config.cb_err();

    handled = true;
  }

  return handled;
}
Esempio n. 2
0
/*  receives an acknowledge from I2C rountine.
 *
 *  @return value: 0--Ack received; 1--Nack received
 *          
 */
static int i2c_receive_ack(void)
{
    int nack;
    unsigned char regvalue;
    
    DELAY(1);
    
    regvalue = HW_REG(GPIO_0_DIR);
    regvalue &= (~SDA);
    HW_REG(GPIO_0_DIR) = regvalue;
    
    DELAY(1);
    i2c_clr(SCL);
    DELAY(1);
    i2c_set(SCL);
    DELAY(1);
    
    

    nack = i2c_data_read();

    DELAY(1);
    i2c_clr(SCL);
    DELAY(1);
  //  i2c_set(SDA);
  //  DELAY(1);

    if (nack == 0)
        return 1; 

    return 0;
}
Esempio n. 3
0
/*  receives a character from I2C rountine.
 *
 *  @return value: character received
 *
 */
static unsigned char i2c_receive_byte(void)
{
    int j=0;
    int i;
    unsigned char regvalue;

    local_irq_disable();
    for (i=0; i<8; i++)
    {
        DELAY(1);
        i2c_clr(SCL);
        DELAY(1);
        i2c_set(SCL);
        
        regvalue = HW_REG(GPIO_0_DIR);
        regvalue &= (~SDA);
        HW_REG(GPIO_0_DIR) = regvalue;
        DELAY(1);
        
        if (i2c_data_read())
            j+=(1<<(7-i));

        DELAY(1);
        i2c_clr(SCL);
    }
    local_irq_enable();
    DELAY(1);
   // i2c_clr(SDA);
   // DELAY(1);

    return j;
}
Esempio n. 4
0
static int i2c_receive_ack(int Grp)
{
    int nack;
    unsigned char regvalue;

    DELAY(1);
    
    regvalue  = HW_REG(GPIO_I2C_DIR[Grp]);
    regvalue &= (~GPIO_I2C_BIT[Grp][PINI2C_SDA]);
    HW_REG(GPIO_I2C_DIR[Grp]) = regvalue;

    DELAY(1);
    i2c_clr(Grp, PINI2C_SCL);

    DELAY(1);
    i2c_set(Grp, PINI2C_SCL);

    DELAY(1);
    nack = i2c_data_read(Grp);
    
    DELAY(1);       
    i2c_clr(Grp, PINI2C_SCL);

    DELAY(1);

    return !nack;
}
Esempio n. 5
0
static unsigned char i2c_receive_byte(int Grp)
{
    int j = 0;
    int i;
    unsigned char regvalue;

    local_irq_disable();

    for (i = 0; i < 8; i ++) {
        DELAY(1);
        i2c_clr(Grp, PINI2C_SCL);

        DELAY(2);
        i2c_set(Grp, PINI2C_SCL);

        regvalue  = HW_REG(GPIO_I2C_DIR[Grp]);
        regvalue &= (~GPIO_I2C_BIT[Grp][PINI2C_SDA]);
        HW_REG(GPIO_I2C_DIR[Grp]) = regvalue;

        DELAY(1);
        if (i2c_data_read(Grp)) {
            j+=(1<<(7-i));
        }

        DELAY(1);
        i2c_clr(Grp, PINI2C_SCL);
    }

    local_irq_enable();

    DELAY(1);

    return j;
}
Esempio n. 6
0
static int
i2c_polling_operation(uint8_t *write_buf, uint8_t write_len,
  uint8_t *read_buf,  uint8_t read_len, uint16_t addr)
{
  uint32_t start_time, intr_mask_stat;

  if (!(read(QUARKX1000_IC_CON) & QUARKX1000_IC_CON_MASTER_MODE_MASK))
    return -1;

  /* Wait i2c idle */
  start_time = clock_seconds();
  while (read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_ACTIVITY_MASK) {
    if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
      return -1;
    }
  }

  /* Get interrupt mask to restore in the end of polling operation */
  intr_mask_stat = read(QUARKX1000_IC_INTR_MASK);

  i2c_operation_setup(write_buf, write_len, read_buf, read_len, addr);

  /* Enable controller */
  set_value(QUARKX1000_IC_ENABLE,
    QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 1);

  /* Transmit */
  if (device.tx_len != 0) {
    while (device.tx_len > 0) {
      start_time = clock_seconds();
      while (!(read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_TFNF_MASK)) {
        if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
          set_value(QUARKX1000_IC_ENABLE,
            QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
          return -1;
        }
      }
      i2c_data_send();
    }

    start_time = clock_seconds();
    while (!(read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_TFE_MASK)) {
      if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
        set_value(QUARKX1000_IC_ENABLE,
          QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
        return -1;
      }
    }
  }

  i2c_data_send();

  /* Receive */
  if (device.rx_len != 0) {
    while (device.rx_len > 0) {
      start_time = clock_seconds();
      while (!(read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_RFNE_MASK)) {
        if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
          set_value(QUARKX1000_IC_ENABLE,
            QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
          return -1;
        }
      }
      i2c_data_read();
    }
  }

  /* Stop Det */
  start_time = clock_seconds();
  while (!(read(QUARKX1000_IC_RAW_INTR_STAT) & QUARKX1000_IC_INTR_STAT_STOP_DET_MASK)) {
    if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
      set_value(QUARKX1000_IC_ENABLE,
        QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
      return -1;
    }
  }
  read(QUARKX1000_IC_CLR_STOP_DET);

  /* Wait i2c idle */
  start_time = clock_seconds();
  while (read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_ACTIVITY_MASK) {
    if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
      set_value(QUARKX1000_IC_ENABLE,
        QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
      return -1;
    }
  }

  /* Disable controller */
  set_value(QUARKX1000_IC_ENABLE,
    QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);

  /* Restore interrupt mask */
  write(QUARKX1000_IC_INTR_MASK, intr_mask_stat);

  return 0;
}
static void decode_i2cstat(lpc17xx_i2c_config_t *config, int status) {
	error_code_t error = NO_ERROR;
	i2c_command_t *cmd = config->buffer;
	if (cmd->expected_status != status || status == ERROR) {
		cmd->expected_status = ERROR;
		//TODO: Should I issue a STOP command?
	} else {
		switch (status) {
			case START:
				//Send Address byte.
				//After Sending the address, next status should be SLA+W ACK.
				error = i2c_clear_start(config);
				cmd->expected_status = MASTER_SLAVEWr_ACK ;
				error |= i2c_address(config, WRITE);
				break;
			case MASTER_SLAVEWr_ACK:
				//Send Register to Write.
				error = i2c_reg(config);
				cmd->expected_status = MASTER_DATAWr_ACK;
				break;
			case MASTER_DATAWr_ACK:
				//If operation is read, RESTART.
				if (cmd->operation == READ) {
					cmd->expected_status = RESTART;
					error = i2c_set_start(config);
				//Else,just send the data.
				} else if (cmd->data_written < cmd->size ) {
					error = i2c_data_write(config, cmd->data[cmd->data_written]);
					cmd->data_written++;
				//If previous send was the last byte, then next should be STOP.
				} else {
					cmd->expected_status = IDLE;
					error = i2c_stop(config);
				}
				break;
			case RESTART:
				//Send address byte, with direction bit set to READ. I2C will ACK the address.
				error = i2c_clear_start(config);
				cmd->expected_status = MASTER_SLARd_ACK ;
				error |= i2c_address(config, READ);
				break;
			case MASTER_SLARd_ACK:
				//I2C will receive the first byte, set the ACK bit.
				if (cmd->data_written == ( cmd->size - 1) ) {
					error  |= i2c_clear_ack(config);
					cmd->expected_status = MASTER_DATARd_NAK;
				} else {
					error = i2c_set_ack(config);
					cmd->expected_status = MASTER_DATARd_ACK;
				}
				break;
			case MASTER_DATARd_ACK:
				error = i2c_data_read(config);
				//A byte of data was received.
				cmd->data_written++;
				if (cmd->data_written == ( cmd->size - 1) ) {
					//The next byte will be the last byte, send a NAK.
					error  |= i2c_clear_ack(config);
					cmd->expected_status = MASTER_DATARd_NAK;
				} else {
					error |= i2c_set_ack(config);
					cmd->expected_status = MASTER_DATARd_ACK;
				}
				break;
			case MASTER_DATARd_NAK:
				error = i2c_data_read(config);
				cmd->expected_status = IDLE;
				i2c_stop(config);
				break;
			default:
				break;
		}

	}
	if (error != NO_ERROR) {
		cmd->expected_status = ERROR;
	}
	i2c_clear_interrupt(config);
}