void i2c_slave_end_listening(void) { _i2c_state.listening = false; if(!i2c_is_busy()){ i2c_do_listen(); } }
void i2c_slave_listen(void) { _i2c_state.listening = true; if(!i2c_is_busy()){ i2c_do_listen(); } }
static int i2c_is_busy_wait(struct saa7134_dev *dev) { enum i2c_status status; int count; for (count = 0; count < I2C_WAIT_RETRY; count++) { status = i2c_get_status(dev); if (!i2c_is_busy(status)) break; saa_wait(I2C_WAIT_DELAY); } if (I2C_WAIT_RETRY == count) return FALSE; return TRUE; }
static int i2c_wait_done(struct i2c_adapter *i2c_adap) { int count; for (count = 0; count < I2C_WAIT_RETRY; count++) { if (!i2c_is_busy(i2c_adap)) break; udelay(I2C_WAIT_DELAY); } if (I2C_WAIT_RETRY == count) return 0; return 1; }
/** * Настраивает шину i2c в режим мастер. * @param device адрес устройства. * @param page_address адрес в устройстве. * @param data данные. * @param data_size размер данных. * @return Код ошибки. */ err_t i2c_master_setup_rw(i2c_address_t device, void* page_address, size_t page_address_size, void* data, i2c_size_t data_size) { if(i2c_is_busy()) return E_BUSY; if(data == NULL) return E_NULL_POINTER; if(data_size == 0) return E_INVALID_VALUE; if(page_address == NULL){ page_address_size = 0; }else{ if(page_address_size == 0) return E_INVALID_VALUE; } i2c_data_init(&_i2c_state.master.data, page_address, page_address_size, data, data_size); _i2c_state.master.device = device; _i2c_state.has_transfer = true; return E_NO_ERROR; }
int chip_i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size, uint8_t *in, int in_size, int flags) { struct i2c_port_data *pd = pdata + port; uint32_t events = 0; if (out_size == 0 && in_size == 0) return EC_SUCCESS; if (pd->i2ccs) { if ((flags & I2C_XFER_SINGLE) == I2C_XFER_SINGLE) flags &= ~I2C_XFER_START; } /* Copy data to port struct */ pd->out = out; pd->out_size = out_size; pd->in = in; pd->in_size = in_size; pd->flags = flags; pd->widx = 0; pd->ridx = 0; pd->err = 0; pd->addr = slave_addr; if (port < I2C_STANDARD_PORT_COUNT) { /* Make sure we're in a good state to start */ if ((flags & I2C_XFER_START) && (i2c_is_busy(port) || (IT83XX_SMB_HOSTA(port) & HOSTA_ALL_WC_BIT) || (i2c_get_line_levels(port) != I2C_LINE_IDLE))) { /* Attempt to unwedge the port. */ i2c_unwedge(port); /* reset i2c port */ i2c_reset(port, I2C_RC_NO_IDLE_FOR_START); } } else { /* Make sure we're in a good state to start */ if ((flags & I2C_XFER_START) && (i2c_is_busy(port) || (i2c_get_line_levels(port) != I2C_LINE_IDLE))) { /* Attempt to unwedge the port. */ i2c_unwedge(port); /* reset i2c port */ i2c_reset(port, I2C_RC_NO_IDLE_FOR_START); } } pd->task_waiting = task_get_current(); if (pd->flags & I2C_XFER_START) { pd->i2ccs = I2C_CH_NORMAL; /* enable i2c interrupt */ task_clear_pending_irq(i2c_ctrl_regs[port].irq); task_enable_irq(i2c_ctrl_regs[port].irq); } /* Start transaction */ i2c_transaction(port); /* Wait for transfer complete or timeout */ events = task_wait_event_mask(TASK_EVENT_I2C_IDLE, pd->timeout_us); /* disable i2c interrupt */ task_disable_irq(i2c_ctrl_regs[port].irq); pd->task_waiting = TASK_ID_INVALID; /* Handle timeout */ if (!(events & TASK_EVENT_I2C_IDLE)) { pd->err = EC_ERROR_TIMEOUT; /* reset i2c port */ i2c_reset(port, I2C_RC_TIMEOUT); } /* reset i2c channel status */ if (pd->err) pd->i2ccs = I2C_CH_NORMAL; return pd->err; }