Exemplo n.º 1
0
bool ICACHE_FLASH_ATTR write(uint8_t addr, uint8_t *buf, uint8_t length)
{
	i2c_master_start();
	i2c_master_writeByte(PCA9685_ADDR | I2C_WRITE);
	if (i2c_master_getAck())
	{
//		os_printf("addr not ack when tx write cmd \n");
		i2c_master_stop();
		return false;
	}

	i2c_master_writeByte(addr);
	if (i2c_master_getAck())
	{
//		os_printf("data not ack when tx write byte1 \n");
		i2c_master_stop();
		return false;
	}

	uint8_t i;
	for(i=0; i<length; i++)
	{
		i2c_master_writeByte(buf[i]);
		if (i2c_master_getAck())
		{
//			os_printf("data not ack when tx write byte %d\n", i);
			i2c_master_stop();
			return false;
		}
	}
	i2c_master_stop();
	return true;
}
Exemplo n.º 2
0
bool rv3029_write(uint8_t regaddr, uint8_t bytes, uint8_t *val) {
    i2c_master_start();

	// Write I²C Address for writing register
    i2c_master_writeByte(RV3029_ADDR_W);
    if (i2c_master_getAck()) {
		os_printf("RV3029: no ACK for write addr\r\n");
		i2c_master_stop();
		return false;
	}

	// Write register address
    i2c_master_writeByte(regaddr);
    if(i2c_master_getAck()) {
		os_printf("RV3029: no ACK for register\r\n");
		i2c_master_stop();
		return false;
	}

	uint8_t i;
	for (i = 0; i < bytes; ++i) {
		i2c_master_writeByte(val[i]);
	    if(i2c_master_getAck()) {
			os_printf("RV3029: no ACK for datawrite\r\n");
			i2c_master_stop();
			return false;
		}
	}

	i2c_master_stop();

	return true;
}
static bool ICACHE_FLASH_ATTR singleByteWrite(uint8_t adr, uint8_t reg, uint8_t data){
	i2c_master_start();

	i2c_master_writeByte((uint8_t)(adr << 1));
	if (!i2c_master_checkAck()) {
		i2c_master_stop();
		return false;
	}

	i2c_master_writeByte(reg);
	if (!i2c_master_checkAck()) {
		i2c_master_stop();
		return false;
	}
	
	i2c_master_writeByte(data);
	if (!i2c_master_checkAck()) {
		i2c_master_stop();
		return false;
	}

	i2c_master_stop();

	return true;
}
Exemplo n.º 4
0
// send a number of bytes to the rtc over i2c
// returns true to indicate success
static bool ICACHE_FLASH_ATTR ds1307_send(uint8 *data, uint8 len) {

	int loop;

	// signal i2c start
	i2c_master_start();

	// write address & direction
	i2c_master_writeByte((uint8)(DS1307_ADDR << 1));
	if (!i2c_master_checkAck()) {
		//uart0_send("i2c error1\r\n");
		i2c_master_stop();
		return false;
	}

	// send the data
	for (loop = 0; loop < len; loop++) {
		i2c_master_writeByte(data[loop]);
		if (!i2c_master_checkAck()) {
			//uart0_send("i2c error2\r\n");
			i2c_master_stop();
			return false;
		}
	}

	// signal i2c stop
	i2c_master_stop();

	return true;

}
Exemplo n.º 5
0
bool i2c_master_writeBytes(uint8 address, uint8 *values, uint8 length)
{
	i2c_master_start();

	i2c_master_writeByte(address);
	if (!i2c_master_checkAck())
	{
		i2c_master_stop();
#ifdef CONFIG_I2C_MASTER_DEBUG
		console_printf( "Device not ACKed on address\n" );
#endif
		return false;
	}

	for(uint8 i = 0; i < length; i++){

		i2c_master_writeByte(values[i]);
		if (!i2c_master_checkAck())
		{
#ifdef CONFIG_I2C_MASTER_DEBUG
			console_printf( "Device not ACKed on write\n" );
#endif
			i2c_master_stop();
			return false;
		}
	}

	i2c_master_stop();
	return true;
}
Exemplo n.º 6
0
// read a number of bytes from the rtc over i2c
// returns true to indicate success
static bool ICACHE_FLASH_ATTR ds1307_recv(uint8 *data, uint8 len) {
	
	int loop;

	// signal i2c start
	i2c_master_start();

	// write address & direction
	i2c_master_writeByte((uint8)((DS1307_ADDR << 1) | 1));
	if (!i2c_master_checkAck()) {
		//uart0_send("i2c error3\r\n");
		i2c_master_stop();
		return false;
	}

	// read bytes
	for (loop = 0; loop < len; loop++) {
		data[loop] = i2c_master_readByte();
		// send ack (except after last byte, then we send nack)
		if (loop < (len - 1)) i2c_master_send_ack(); else i2c_master_send_nack();
	}

	// signal i2c stop
	i2c_master_stop();

	return true;

}
Exemplo n.º 7
0
LOCAL void ICACHE_FLASH_ATTR
read_cb(void)
{
	uint8_t ack, low, high;
	wdt_feed();
	os_printf("Time=%ld\n", system_get_time());
	i2c_master_start();
	i2c_master_writeByte(BH1750_ADDR);
	ack = i2c_master_getAck();
	if (ack)
	{
		os_printf("I2C:No ack after sending address\n");
		i2c_master_stop();
		return;
	}
	i2c_master_stop();
    i2c_master_wait(40000); // why?

    i2c_master_start();
    i2c_master_writeByte(BH1750_ADDR + 1);
    ack = i2c_master_getAck();
	if (ack)
	{
		os_printf("I2C:No ack after write command\n");
		i2c_master_stop();
		return;
	}
	low = i2c_master_readByte();
	high = i2c_master_readByte();
	i2c_master_setAck(1);
    i2c_master_stop();
	os_printf("I2C:read(L/H)=(0x%02x/0x%02x)\n", low, high);
}
Exemplo n.º 8
0
LOCAL i2c_status ICACHE_FLASH_ATTR io2_set_execute(uint8 address, uint8 command, uint8 data) {
	i2c_master_start();

	/* Send address */
	i2c_master_writeByte(address << 1 | 0);
	if (i2c_master_getAck()) {
		i2c_master_stop();
		return I2C_ADDRESS_NACK;
	}

	/* Send command */
	i2c_master_writeByte(command);
	if (i2c_master_getAck()) {
		goto error;
	}

	/* Send data */
	i2c_master_writeByte(data);
	if (i2c_master_getAck()) {
		goto error;
	}
	
	i2c_master_stop();
	return I2C_OK;
	
	error: i2c_master_stop();
	return I2C_DATA_NACK;
}
Exemplo n.º 9
0
i2c_status ICACHE_FLASH_ATTR rgb_set(i2c_config *config) {
    rgb_config_data *config_data = (rgb_config_data *)config->data;
    i2c_master_start();

    /* Send address */
    i2c_master_writeByte(config->address << 1 | 0);
    if (i2c_master_getAck()) {
        i2c_master_stop();
        return I2C_ADDRESS_NACK;
    }

    /* Send command */
    i2c_master_writeByte(0x03);
    if (i2c_master_getAck())
        goto error;

    i2c_master_writeByte(config_data->red);
    if (i2c_master_getAck())
        goto error;

    i2c_master_writeByte(config_data->green);
    if (i2c_master_getAck())
        goto error;

    i2c_master_writeByte(config_data->blue);
    if (i2c_master_getAck())
        goto error;

    i2c_master_stop();
    return I2C_OK;

error:
    i2c_master_stop();
    return I2C_DATA_NACK;
}
Exemplo n.º 10
0
static int es_read_reg(uint8_t reg_add, uint8_t *pData)
{
    uint8_t data;
    int res = 0;
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();

    res |= i2c_master_start(cmd);
    res |= i2c_master_write_byte(cmd, ES8388_ADDR, 1 /*ACK_CHECK_EN*/);
    res |= i2c_master_write_byte(cmd, reg_add, 1 /*ACK_CHECK_EN*/);
    res |= i2c_master_stop(cmd);
    res |= i2c_master_cmd_begin(0, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);

    cmd = i2c_cmd_link_create();
    res |= i2c_master_start(cmd);
    res |= i2c_master_write_byte(cmd, ES8388_ADDR | 0x01, 1 /*ACK_CHECK_EN*/);
    res |= i2c_master_read_byte(cmd, &data, 0x01/*NACK_VAL*/);
    res |= i2c_master_stop(cmd);
    res |= i2c_master_cmd_begin(0, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);

    ES_ASSERT(res, "es_read_reg error", -1);
    *pData = data;
    return res;
}
Exemplo n.º 11
0
// write within a page
// note if you try to write past a page boundary the write will
// wrap back to the start of the same page, so you need to know
// how much you're writing and where you're writing it to
// you don't need to start writing at the start of a page, but if you
// start in the middle you'll be able to write less before wrapping
// optionally wait for the eeprom to complete the write
// returns true to indicate success
bool ICACHE_FLASH_ATTR at24c_writeInPage(uint16 addr, uint8* data, uint8 len, bool wait) {

	int loop;

	// set data address (includes i2c setup,
	// so no need to call i2c_master_start here)
	if (!at24c_setAddr(addr)) return false;

	// send the data
	for (loop = 0; loop < len; loop++) {
		i2c_master_writeByte(data[loop]);
		if (!i2c_master_checkAck()) {
			//uart0_send("i2c error\r\n");
			i2c_master_stop();
			return false;
		}
	}

	// signal i2c stop
	i2c_master_stop();

	// optionally, wait until the eeprom signals the write is finished
	if (wait) at24c_writeWait();

	return true;
}
Exemplo n.º 12
0
// set the current data address, this is the start of the write command
// next either send the data to be written, or start a read instead
// returns true to indicate success
static bool ICACHE_FLASH_ATTR at24c_setAddr(uint16 addr) {

	uint8 loop;
	uint8 data[2];

	// signal i2c start
	i2c_master_start();

	// write i2c address & direction
	i2c_master_writeByte((uint8)(AT24C_ADDR << 1));
	if (!i2c_master_checkAck()) {
		//uart0_send("i2c error\r\n");
		i2c_master_stop();
		return false;
	}

	// write data address
	data[0] = (uint8)(((unsigned)addr) >> 8);
	data[1] = (uint8)(((unsigned)addr) & 0xff);
	for (loop = 0; loop < 2; loop++) {
		i2c_master_writeByte(data[loop]);
		if (!i2c_master_checkAck()) {
			//uart0_send("i2c error\r\n");
			i2c_master_stop();
			return false;
		}
	}

	return true;
}
Exemplo n.º 13
0
/************ low level data pushing commands **********/
void LCD_expanderWrite(uint8 _data){                                        
    i2c_master_start();
    i2c_master_writeByte(LCD_ADDRESS << 1);
    if (!i2c_master_checkAck()) 
    {
        i2c_master_stop();
        return;
    }
    //i2c_master_writeByte((uint8)(_data) | _backlightval);
    i2c_master_writeByte((uint8)(_data) | LCD_BACKLIGHT);
    i2c_master_checkAck();
    i2c_master_stop();
}
Exemplo n.º 14
0
void i2c_expander_init(void){
    i2c_master_start();
    i2c_master_send(0x40); //OPCODE
    i2c_master_send(0x00);  // Reg ADDRESS
    i2c_master_send(0xF0); //set GP7-GP4 as inputs, GP3-GP0 as output
    i2c_master_stop();
    //set latch
   
    i2c_master_start();
    i2c_master_send(0x40);
    i2c_master_send(0x0A);
    i2c_master_send(0x00);
    i2c_master_stop();
}
Exemplo n.º 15
0
i2c_status ICACHE_FLASH_ATTR tc_read(i2c_config *config) {
	tc_config_data *config_data = (tc_config_data *)config->data;
	i2c_master_start();

	/* Send address */
	i2c_master_writeByte(config->address << 1 | 0);
	if (i2c_master_getAck()) {
		i2c_master_stop();
		return I2C_ADDRESS_NACK;
	}

	/* Send command */
	i2c_master_writeByte(0x21);
	if (i2c_master_getAck()) {
		i2c_master_stop();
		return I2C_DATA_NACK;	
	}

	i2c_master_stop();
	i2c_master_start();
	
	i2c_master_writeByte(config->address << 1 | 1);
	if (i2c_master_getAck()) {
		i2c_master_stop();
		return I2C_ADDRESS_NACK;
	}
	
	uint8 i;
	uint8 data[4];
	for (i=0; i < 4; i++) {
		data[i] = i2c_master_readByte();
		i2c_master_setAck(i == 3);
	}
	i2c_master_stop();
	
	if ((data[2] & 0x01) != 0) {
		return I2C_COMMUNICATION_FAILED;
	}
	
	sint16 d = data[3] * 256 + (data[2] & 0xFC);
	float tf = 0.0625 * d;
	int ti = tf;
	uint16 td = (tf - ti) * 100;
	
	config_data->temperature = d / 4;
	os_sprintf(config_data->temperature_str, "%d.%02d", ti, td);
	
	return I2C_OK;
}
Exemplo n.º 16
0
void rtc_writeValue(time_t newTime) {
	ESP_LOGD(tag, ">> writeValue: %ld", newTime);
	struct tm tm;
	gmtime_r(&newTime, &tm);
	char buf[30];
	ESP_LOGD(tag, " - %s", asctime_r(&tm, buf));

	esp_err_t errRc;
	i2c_cmd_handle_t cmd = i2c_cmd_link_create();
	ESP_ERROR_CHECK(i2c_master_start(cmd));
	ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (RTC_ADDRESS << 1) | I2C_MASTER_WRITE, 1 /* expect ack */));
	ESP_ERROR_CHECK(i2c_master_write_byte(cmd, 0x03, 1));
	ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_sec), 1));      // seconds
	ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_min), 1 ));     // minutes
	ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_hour), 1 ));    // hours
	ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_mday), 1));     // date of month
	ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_wday+1), 1 ));  // week day
	ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_mon+1), 1));    // month
	ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_year-100), 1)); // year
	ESP_ERROR_CHECK(i2c_master_stop(cmd));
	errRc = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS);
	if (errRc != 0) {
		ESP_LOGE(tag, "i2c_master_cmd_begin: %d", errRc);
	}
	i2c_cmd_link_delete(cmd);
}
Exemplo n.º 17
0
/*
 * PCF8523 slightly changed its 7 bytes encoded in BCD:
 * 03h - Seconds 	- 00-59
 * 04h - Minutes 	- 00-59
 * 05h - Hours   	- 00-23
 * 06h - monthday	- 01-31
 * 07h - weekday	- 00-06
 * 08h - Month   	- 01-12
 * 09h - Year    	- 00-99
 *
 */
time_t rtc_readValue() {
	i2c_cmd_handle_t cmd = i2c_cmd_link_create();
	ESP_ERROR_CHECK(i2c_master_start(cmd));
	ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (RTC_ADDRESS << 1) | I2C_MASTER_WRITE, true /* expect ack */));
	ESP_ERROR_CHECK(i2c_master_write_byte(cmd, 0x03, 1)); // start address
	ESP_ERROR_CHECK(i2c_master_start(cmd));
	ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (RTC_ADDRESS << 1) | I2C_MASTER_READ, true /* expect ack */));
	uint8_t data[7];
	ESP_ERROR_CHECK(i2c_master_read(cmd, data, 7, false));
	ESP_ERROR_CHECK(i2c_master_stop(cmd));
	COMMANDCHECKOKERR(i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS),"RTC COMMAND");
	i2c_cmd_link_delete(cmd);

	int i;
	for (i=0; i<7; i++) {
		ESP_LOGD(tag, "%d: 0x%.2x", i, data[i]);
	}

	struct tm tm;
	tm.tm_sec  = bcdToInt(data[0]);
	tm.tm_min  = bcdToInt(data[1]);
	tm.tm_hour = bcdToInt(data[2]);
	tm.tm_mday = bcdToInt(data[3]);
	tm.tm_mon  = bcdToInt(data[5]) - 1; // 0-11 - Note: The month on the PCF8523 is 1-12.
	tm.tm_year = bcdToInt(data[6]) + 100; // Years since 1900
	time_t readTime = mktime(&tm);
	return readTime;
}
Exemplo n.º 18
0
void i2c_write_single(unsigned char address, unsigned char data) {
    i2c_master_start();                         //ST
    i2c_master_send(IMU_ADDRESS << 1);          //SAD+W - SAK
    i2c_master_send(address);                   //SUB - SAK
    i2c_master_send(data);                      //DATA - SAK
    i2c_master_stop();                          //SP
}
Exemplo n.º 19
0
void init_ctrl1(void){
  i2c_master_start();
  i2c_master_send(0x6B << 1 | 0);   // chip address & indicate write
  i2c_master_send(0x10);   // addr of ctrl_1 register
  i2c_master_send(0x80);   // send the value to the register, enable accelerometer
  i2c_master_stop();
}
Exemplo n.º 20
0
uint8_t i2c_ds13x7_get_block(uint8_t addr, char *data, uint8_t len) {
     uint8_t ret = 0;

     uint8_t sreg = SREG; cli();
     
     if (!i2c_master_select( I2C_SLA_DS13X7, TW_WRITE)) { ret=1; goto end; }
     
     TWDR = addr;
     if (i2c_master_transmit_with_ack() != TW_MT_DATA_ACK) { ret=2; goto end; }

     /* Do an repeated start condition */
     if (i2c_master_start() != TW_REP_START) {ret = 3; goto end; }

     /* Send the address again */
     TWDR = (I2C_SLA_DS13X7 << 1) | TW_READ;
     if(i2c_master_transmit() != TW_MR_SLA_ACK) {ret = 4; goto end; }

     for (uint8_t i=0;i<len;i++) {
	  if (i2c_master_transmit_with_ack() != TW_MR_DATA_ACK) { ret = 5; goto end; }
	  *(data+i) = TWDR;
     }
     
     
 end:
     i2c_master_stop();
     SREG = sreg; 
     return ret;
}
Exemplo n.º 21
0
// wait for a write operation to complete
// by 'acknowledge polling'
void ICACHE_FLASH_ATTR at24c_writeWait() {
	do {
		i2c_master_start();
		i2c_master_writeByte((uint8)((AT24C_ADDR << 1) | 1));
	} while (!i2c_master_checkAck());
	i2c_master_stop();
}
Exemplo n.º 22
0
void init_ctrl3(void){
  i2c_master_start();
  i2c_master_send(0x6B << 1 | 0);   // chip address & indicate write
  i2c_master_send(0x12);   // addr of ctrl_3 register
  i2c_master_send(0x04);   // send the value to the register, enable if_inc
  i2c_master_stop();
}
void writeByte(unsigned char address, unsigned char data) {
    i2c_master_start();
    i2c_master_send(MCP23008_ADDRESS << 1);
    i2c_master_send(address);
    i2c_master_send(data);
    i2c_master_stop();
}
Exemplo n.º 24
0
int i2c_scan(int argc, char** argv)
{
    int count = 1;
    if (argc > 1)
        count = atoi(argv[1]);

    printf("Scanning for I2C devices (%d)\n", count);
    for (int j = 0; j < count; ++j)
    {
        printf("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n");
        printf("00:         ");
        for (int i = 3; i < 0x78; ++i)
        {
            i2c_cmd_handle_t cmd = i2c_cmd_link_create();
            i2c_master_start(cmd);
            i2c_master_write_byte(cmd, (i << 1) | I2C_MASTER_WRITE, 1 /* expect ack */);
            i2c_master_stop(cmd);

            const auto espRc = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS);
            if (i%16 == 0)
                printf("\n%.2x:", i);
            if (espRc == 0)
                printf(" %.2x", i);
            else
                printf(" --");
            //ESP_LOGD(tag, "i=%d, rc=%d (0x%x)", i, espRc, espRc);
            i2c_cmd_link_delete(cmd);
        }
        printf("\n");
        vTaskDelay(100/portTICK_PERIOD_MS);
    }
    
    return 0;
}
Exemplo n.º 25
0
/******************************************************************************
 * FunctionName : i2c_master_init
 * Description  : initilize I2C bus to enable i2c operations
 * Parameters   : NONE
 * Returns      : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
i2c_master_init(void)
{
    uint8 i;

    i2c_master_setDC(1, 0);
    i2c_master_wait(5);

    // when SCL = 0, toggle SDA to clear up
    i2c_master_setDC(0, 0) ;
    i2c_master_wait(5);
    i2c_master_setDC(1, 0) ;
    i2c_master_wait(5);

    // set data_cnt to max value
    for (i = 0; i < 28; i++) {
        i2c_master_setDC(1, 0);
        i2c_master_wait(5);	// sda 1, scl 0
        i2c_master_setDC(1, 1);
        i2c_master_wait(5);	// sda 1, scl 1
    }

    // reset all
    i2c_master_stop();
    return;
}
Exemplo n.º 26
0
void init_ctrl2(void){
  i2c_master_start();
  i2c_master_send(0x6B << 1 | 0);   // chip address & indicate write
  i2c_master_send(0x11);   // addr of ctrl_2 register
  i2c_master_send(0x80);   // send the value to the register, enable agyroscope
  i2c_master_stop();
}
Exemplo n.º 27
0
uint8_t i2c_24aaXX_read_block(uint8_t addr, uint8_t *ptr, uint8_t len) {
     
     uint8_t ret = 0;
     
     if (!i2c_master_select( I2C_SLA_24AAXX, TW_WRITE)) { ret=1; goto end; }
     
     TWDR = addr;
     if (i2c_master_transmit_with_ack() != TW_MT_DATA_ACK) { ret=2; goto end; }

     /* Do an repeated start condition */
     if (i2c_master_start() != TW_REP_START) {ret = 3; goto end; }

     /* Send the address again */
     TWDR = (I2C_SLA_24AAXX << 1) | TW_READ;
     if(i2c_master_transmit() != TW_MR_SLA_ACK) {ret = 4; goto end; }

     for (uint8_t i=0;i<len;i++) {
	  if (i2c_master_transmit_with_ack() != TW_MR_DATA_ACK) { ret = 5; goto end; }
	  *(ptr+i) = TWDR;
     }
     
 end:
     i2c_master_stop();
     return ret;

}
Exemplo n.º 28
0
static void clear_display(void) {
  matrix_clear(&display);

  // Clear all of the display bits (there can be random noise
  // in the RAM on startup)
  send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1);
  send_cmd3(ColumnAddr, 0, DisplayWidth - 1);

  if (i2c_start_write(SSD1306_ADDRESS)) {
    goto done;
  }
  if (i2c_master_write(0x40)) {
    // Data mode
    goto done;
  }
  for (uint8_t row = 0; row < MatrixRows; ++row) {
    for (uint8_t col = 0; col < DisplayWidth; ++col) {
      i2c_master_write(0);
    }
  }

  display.dirty = false;

done:
  i2c_master_stop();
}
Exemplo n.º 29
0
void setlsm(char reg, char value){
    i2c_master_start();
    i2c_master_send(0b11010110);
    i2c_master_send(reg);
    i2c_master_send(value);
    i2c_master_stop();    
}
Exemplo n.º 30
0
// Get rows from other half over i2c
int i2c_transaction(void) {
    int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;

    int err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
    if (err) goto i2c_error;

    // Matrix stored at 0x00-0x03
    err = i2c_master_write(0x00);
    if (err) goto i2c_error;

    // Start read
    err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ);
    if (err) goto i2c_error;

    if (!err) {
        int i;
        for (i = 0; i < ROWS_PER_HAND-1; ++i) {
            matrix[slaveOffset+i] = i2c_master_read(I2C_ACK);
        }
        matrix[slaveOffset+i] = i2c_master_read(I2C_NACK);
        i2c_master_stop();
    } else {
i2c_error: // the cable is disconnceted, or something else went wrong
        i2c_reset_state();
        return err;
    }

    return 0;
}