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; }
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; }