Esempio n. 1
0
int main(void)
{
	qm_i2c_config_t cfg;

	QM_PUTS("Starting: I2C");

	QM_IR_UNMASK_INT(QM_IRQ_I2C_0_INT);
	QM_IRQ_REQUEST(QM_IRQ_I2C_0_INT, qm_i2c_0_irq_isr);

	/* Enable I2C 0. */
	clk_periph_enable(CLK_PERIPH_CLK | CLK_PERIPH_I2C_M0_REGISTER);

	pin_mux_setup();

	/* Configure I2C. */
	cfg.address_mode = QM_I2C_7_BIT;
	cfg.mode = QM_I2C_MASTER;
	cfg.speed = QM_I2C_SPEED_STD;

	if (qm_i2c_set_config(QM_I2C_0, &cfg)) {
		QM_PUTS("Error: I2C_0 config failed");
	}

	/* Add eeprom data address to the beginning of each message. */
	eeprom_pio_write_data[0] = EEPROM_ADDR_FIRST_PAGE_LO;
	eeprom_pio_write_data[1] = EEPROM_ADDR_FIRST_PAGE_HI;
	eeprom_irq_write_data[0] = EEPROM_ADDR_FIRST_PAGE_LO;
	eeprom_irq_write_data[1] = EEPROM_ADDR_FIRST_PAGE_HI;

	/* PIO example. */
	i2c_pio_write_example();
	i2c_pio_combined_transaction_example();
	eeprom_compare_page(eeprom_pio_write_data, eeprom_read_buf);

	/* IRQ example. */
	i2c_irq_write_example();
	i2c_irq_combined_transaction_example();
	eeprom_compare_page(eeprom_irq_write_data, eeprom_read_buf);

	/* DMA example. */

	/* Verify irq callback was fired before initiating a new request */
	while (!i2c_0_irq_complete)
		;

	QM_IRQ_REQUEST(QM_IRQ_I2C_0_INT, qm_i2c_0_dma_isr);
	i2c_dma_setup();
	i2c_dma_write_example();
	i2c_dma_combined_transaction_example();
	eeprom_compare_page(eeprom_pio_write_data, eeprom_read_buf);

	QM_PUTS("Finished: I2C");

	return 0;
}
Esempio n. 2
0
static int i2c_qmsi_configure(struct device *dev, u32_t config)
{
	qm_i2c_t instance = GET_CONTROLLER_INSTANCE(dev);
	struct i2c_qmsi_driver_data *driver_data = GET_DRIVER_DATA(dev);
	qm_i2c_reg_t *const controller = QM_I2C[instance];
	int rc;
	qm_i2c_config_t qm_cfg;

	/* This driver only supports master mode. */
	if (!(I2C_MODE_MASTER & config))
		return -EINVAL;

	qm_cfg.mode = QM_I2C_MASTER;
	if (I2C_ADDR_10_BITS & config) {
		qm_cfg.address_mode = QM_I2C_10_BIT;
	} else {
		qm_cfg.address_mode = QM_I2C_7_BIT;
	}

	switch (I2C_SPEED_GET(config)) {
	case I2C_SPEED_STANDARD:
		qm_cfg.speed = QM_I2C_SPEED_STD;
		break;
	case I2C_SPEED_FAST:
		qm_cfg.speed = QM_I2C_SPEED_FAST;
		break;
	case I2C_SPEED_FAST_PLUS:
		qm_cfg.speed = QM_I2C_SPEED_FAST_PLUS;
		break;
	default:
		return -EINVAL;
	}

	k_sem_take(&driver_data->sem, K_FOREVER);
	rc = qm_i2c_set_config(instance, &qm_cfg);
	k_sem_give(&driver_data->sem);

	controller->ic_sda_hold = (CONFIG_I2C_SDA_RX_HOLD << 16) +
				   CONFIG_I2C_SDA_TX_HOLD;

	controller->ic_sda_setup = CONFIG_I2C_SDA_SETUP;

	return rc;
}
SOL_API struct sol_i2c *
sol_i2c_open_raw(uint8_t bus, enum sol_i2c_speed speed)
{
    struct sol_i2c *i2c;
    qm_i2c_config_t cfg;
    qm_i2c_speed_t bus_speed;
    qm_rc_t ret;

    if (bus >= QM_I2C_NUM) {
        SOL_WRN("I2C bus #%" PRIu8 " doesn't exist.", bus);
        return NULL;
    }

    if ((i2c = buses[bus]) != NULL)
        return i2c;

    switch (speed) {
    case SOL_I2C_SPEED_10KBIT:
    case SOL_I2C_SPEED_100KBIT:
        bus_speed = QM_I2C_SPEED_STD;
        break;
    case SOL_I2C_SPEED_400KBIT:
        bus_speed = QM_I2C_SPEED_FAST;
        break;
    case SOL_I2C_SPEED_1MBIT:
    case SOL_I2C_SPEED_3MBIT_400KBIT:
        bus_speed = QM_I2C_SPEED_FAST_PLUS;
        break;
    default:
        SOL_WRN("Unsupported speed value: %d", speed);
        return NULL;
    };

    switch (bus) {
    case QM_I2C_0:
        qm_irq_request(QM_IRQ_I2C_0, qm_i2c_0_isr);
        clk_periph_enable(CLK_PERIPH_CLK | CLK_PERIPH_I2C_M0_REGISTER);
        break;
#if QUARK_SE
    case QM_I2C_1:
        qm_irq_request(QM_IRQ_I2C_1, qm_i2c_1_isr);
        clk_periph_enable(CLK_PERIPH_CLK | CLK_PERIPH_I2C_M1_REGISTER);
        break;
#endif
    case QM_I2C_NUM:
        /* We checked if we were passed the limit before, so we should never
         * hit this point. Using all the enum values and no default, however,
         * allows us to rely on the compiler to know if there are values
         * we are not considering (depending on warning levels) */
        break;
    }

    i2c = calloc(1, sizeof(*i2c));
    SOL_NULL_CHECK(i2c, NULL);

    i2c->bus = bus;

    ret = qm_i2c_get_config(i2c->bus, &cfg);
    SOL_EXP_CHECK_GOTO(ret != QM_RC_OK, error);

    cfg.speed = bus_speed;
    cfg.address_mode = QM_I2C_7_BIT;
    cfg.mode = QM_I2C_MASTER;
    cfg.slave_addr = 0;

    ret = qm_i2c_set_config(i2c->bus, &cfg);
    SOL_EXP_CHECK_GOTO(ret != QM_RC_OK, error);

    if (!i2c_irq_event) {
        bool r;

        i2c_irq_event = process_alloc_event();
        r = sol_mainloop_contiki_event_handler_add(&i2c_irq_event, NULL,
            i2c_cb_dispatch, NULL);
        SOL_EXP_CHECK_GOTO(!r, error);
    }

    buses[i2c->bus] = i2c;

    return i2c;

error:
    free(i2c);
    return NULL;
}