void i2c_lpc_transfer(i2c_bus_t* const bus, const uint_fast8_t slave_address, const uint8_t* const data_tx, const size_t count_tx, uint8_t* const data_rx, const size_t count_rx ) { const uint32_t port = (uint32_t)bus->obj; size_t i; bool ack = false; if (data_tx && (count_tx > 0)) { i2c_tx_start(port); i2c_tx_byte(port, (slave_address << 1) | I2C_WRITE); for(i=0; i<count_tx; i++) { i2c_tx_byte(port, data_tx[i]); } } if (data_rx && (count_rx > 0)) { i2c_tx_start(port); i2c_tx_byte(port, (slave_address << 1) | I2C_READ); for(i=0; i<count_rx; i++) { /* ACK each byte except the last */ ack = (i!=count_rx-1); data_rx[i] = i2c_rx_byte(port, ack); } } i2c_stop(port); }
/* * Reads count bytes of data from the slave (addr) * @param addr Address of the slave to read from * @param size Number of bytes to read from the slave * @param data Array of bytes to transmit * @param delay_us Busy waits for delay_us microseconds following each transferred byte */ void i2c_rx(uint8_t addr, int size, uint8_t *data, int delay_us) { i2c_acquire_bus(); // Wait for bus to become idle i2c_tx_addr(addr, I2C_READ, delay_us); // Send start bit, slave address, and read bit MCF_I2C0_I2CR &= ~(MCF_I2C_I2CR_MTX); // Become a receiver MCF_I2C0_I2CR &= ~(MCF_I2C_I2CR_TXAK); // Configure to ACK each recv'd data byte // Read a dummy byte in order to complete the mode switch uint8_t dummy = i2c_rx_byte(delay_us); // Master-receivers must generate clock pulses on SCL to recv 8 data bytes from slave // Read and ACK up until the last byte (size-2) for(int i = 0; i <= (size-2); i++) data[i] = i2c_rx_byte(delay_us); // NACK to stop transmission and read the last byte MCF_I2C0_I2CR |= MCF_I2C_I2CR_TXAK; data[size-1] = i2c_rx_byte(delay_us); // Terminate communication i2c_rxtx_end(); }
void i2c_lpc_transfer(const uint32_t port, const uint_fast8_t slave_address, const uint8_t* const data_tx, const size_t count_tx, uint8_t* const data_rx, const size_t count_rx ) { i2c_tx_start(port); i2c_tx_byte(port, (slave_address << 1) | I2C_WRITE); for(size_t i=0; i<count_tx; i++) { i2c_tx_byte(port, data_tx[i]); } if( data_rx ) { i2c_tx_start(port); i2c_tx_byte(port, (slave_address << 1) | I2C_READ); for(size_t i=0; i<count_rx; i++) { data_rx[i] = i2c_rx_byte(port); } } i2c_stop(port); }