bool i2c_write(uint8_t i2c_interface, uint8_t slave_addr, uint8_t reg_addr, uint8_t *tx_buff, uint8_t tx_buff_length) { //puts("[i2c.c/i2cWrite]: entered\n"); i2c_clear_buffer((uint8_t *) i2c_master_buffer, I2C_BUFSIZE * sizeof(uint8_t)); i2c_write_length = tx_buff_length + 1; i2c_master_buffer[0] = (slave_addr << 1) & WRITE_ENABLE_BIT_MASK; i2c_master_buffer[1] = reg_addr; if ((tx_buff != NULL) && tx_buff_length < (I2C_BUFSIZE - 2)) { int32_t j = 0; for (int32_t i = 2; i < tx_buff_length + 2; i++) { i2c_master_buffer[i] = tx_buff[j]; j++; //printf("I2CMasterBuffer[%d] = %d\n", i, I2CMasterBuffer[i]); } return i2c_transaction(i2c_interface); } else { puts("[i2c.c/i2cWrite]: Invalid buffer or invalid write buffer size\n"); return false; } }
bool i2c_read(uint8_t i2c_interface, uint8_t slave_addr, uint8_t reg_addr, uint8_t *rx_buff, uint8_t rx_buff_length) { i2c_clear_buffer((uint8_t *) i2c_master_buffer, I2C_BUFSIZE * sizeof(uint8_t)); i2c_write_length = 1; i2c_read_length = rx_buff_length; bool successful; uint8_t readIndex = 3; i2c_master_buffer[0] = (slave_addr << 1) & WRITE_ENABLE_BIT_MASK; i2c_master_buffer[1] = reg_addr; i2c_master_buffer[2] = ((slave_addr << 1) & WRITE_ENABLE_BIT_MASK) | READ_ENABLE_BIT_MASK; successful = i2c_transaction(i2c_interface); if (successful && (rx_buff != NULL) && (rx_buff_length < (I2C_BUFSIZE - readIndex))) { memcpy(rx_buff, (const uint8_t *)(i2c_master_buffer + readIndex), sizeof(uint8_t) * rx_buff_length); return true; } else { return false; } }
void i2c_interrupt(int port) { int id = pdata[port].task_waiting; /* Clear the interrupt status */ task_clear_pending_irq(i2c_ctrl_regs[port].irq); /* If no task is waiting, just return */ if (id == TASK_ID_INVALID) return; /* If done doing work, wake up the task waiting for the transfer */ if (!i2c_transaction(port)) { task_disable_irq(i2c_ctrl_regs[port].irq); task_set_event(id, TASK_EVENT_I2C_IDLE, 0); } }
//burst mode, the first element in the array bool i2c_trans_receive(uint8_t i2c_interface, uint8_t slave_addr, uint8_t *tx_buff, uint8_t tx_buff_length, uint8_t *rx_buff, uint8_t rx_buff_length) { puts("[i2c.c/i2cTransReceive]: entered\n"); i2c_clear_buffer((uint8_t *) i2c_master_buffer, I2C_BUFSIZE * sizeof(uint8_t)); i2c_write_length = tx_buff_length; i2c_read_length = rx_buff_length; if (tx_buff != NULL && (tx_buff_length > 0)) { int32_t read_index = 0; i2c_master_buffer[0] = (slave_addr << 1) & WRITE_ENABLE_BIT_MASK; for (int32_t i = 1; i < tx_buff_length + 1; i++) { if (i < I2C_BUFSIZE) { i2c_master_buffer[i] = tx_buff[i - 1]; } } //enable I2C to read if ((rx_buff_length > 0) && (i < I2C_BUFSIZE)) { i2c_master_buffer[i] = ((slave_addr << 1) & WRITE_ENABLE_BIT_MASK) | READ_ENABLE_BIT_MASK; read_index = i + 1; } bool successful = i2c_transaction(i2c_interface); if (successful && (rx_buff != NULL) && (rx_buff_length > 0)) { memcpy(rx_buff, (const uint8_t *)(i2c_master_buffer + read_index), sizeof(uint8_t) * rx_buff_length); return true; } else { return false; } } else { puts( "[i2c.c/i2cRead]: the txBuff is not valid or has not a valid \ length value !\n"); return false; } }
uint8_t matrix_scan(void) { int ret = _matrix_scan(); #ifdef USE_I2C if( i2c_transaction() ) { #else if( serial_transaction() ) { #endif // turn on the indicator led when halves are disconnected TXLED1; error_count++; if (error_count > ERROR_DISCONNECT_COUNT) { // reset other half if disconnected int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; for (int i = 0; i < ROWS_PER_HAND; ++i) { matrix[slaveOffset+i] = 0; } } } else { // turn off the indicator led on no error TXLED0; error_count = 0; } return ret; } void matrix_slave_scan(void) { _matrix_scan(); int offset = (isLeftHand) ? 0 : (MATRIX_ROWS / 2); for (int i = 0; i < ROWS_PER_HAND; ++i) { serial_slave_buffer[i] = matrix[offset+i]; } }
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; }