int i2c_write_regs(i2c_t dev, uint8_t address, uint8_t reg, const void *data, int length) { I2C_TypeDef *i2c; switch (dev) { #if I2C_0_EN case I2C_0: i2c = I2C_0_DEV; break; #endif #if I2C_1_EN case I2C_1: i2c = I2C_1_DEV; break; #endif default: return -1; } /* start transmission and send slave address */ _start(i2c, address, I2C_FLAG_WRITE); _clear_addr(i2c); /* send register address and wait for complete transfer to be finished*/ _write(i2c, ®, 1); /* write data to register */ _write(i2c, data, length); /* finish transfer */ _stop(i2c); /* return number of bytes send */ return length; }
int i2c_read_regs(i2c_t dev, uint8_t address, uint8_t reg, void *data, int length) { I2C_TypeDef *i2c; switch (dev) { #if I2C_0_EN case I2C_0: i2c = I2C_0_DEV; break; #endif #if I2C_1_EN case I2C_1: i2c = I2C_1_DEV; break; #endif default: return -1; } /* send start condition and slave address */ DEBUG("Send slave address and clear ADDR flag\n"); _start(i2c, address, I2C_FLAG_WRITE); _clear_addr(i2c); DEBUG("Write reg into DR\n"); i2c->DR = reg; _stop(i2c); DEBUG("Now start a read transaction\n"); return i2c_read_bytes(dev, address, data, length); }
int i2c_write_bytes(i2c_t dev, uint8_t address, const void *data, int length) { I2C_TypeDef *i2c; switch (dev) { #if I2C_0_EN case I2C_0: i2c = I2C_0_DEV; break; #endif #if I2C_1_EN case I2C_1: i2c = I2C_1_DEV; break; #endif default: return -1; } /* start transmission and send slave address */ DEBUG("sending start sequence\n"); _start(i2c, address, I2C_FLAG_WRITE); _clear_addr(i2c); /* send out data bytes */ _write(i2c, data, length); /* end transmission */ DEBUG("Ending transmission\n"); _stop(i2c); DEBUG("STOP condition was send out\n"); return length; }
int i2c_read_regs(i2c_t dev, uint8_t address, uint8_t reg, char *data, int length) { if ((unsigned int)dev >= I2C_NUMOF) { return -1; } I2C_TypeDef *i2c = i2c_config[dev].dev; /* send start condition and slave address */ DEBUG("Send slave address and clear ADDR flag\n"); _start(i2c, address, I2C_FLAG_WRITE); _clear_addr(i2c); DEBUG("Write reg into DR\n"); i2c->DR = reg; _stop(i2c); DEBUG("Now start a read transaction\n"); return i2c_read_bytes(dev, address, data, length); }
int i2c_write_regs(i2c_t dev, uint8_t address, uint8_t reg, char *data, int length) { if ((unsigned int)dev >= I2C_NUMOF) { return -1; } I2C_TypeDef *i2c = i2c_config[dev].dev; /* start transmission and send slave address */ _start(i2c, address, I2C_FLAG_WRITE); _clear_addr(i2c); /* send register address and wait for complete transfer to be finished*/ _write(i2c, (char *)(®), 1); /* write data to register */ _write(i2c, data, length); /* finish transfer */ _stop(i2c); /* return number of bytes send */ return length; }
int i2c_write_bytes(i2c_t dev, uint8_t address, char *data, int length) { if ((unsigned int)dev >= I2C_NUMOF) { return -1; } I2C_TypeDef *i2c = i2c_config[dev].dev; /* start transmission and send slave address */ DEBUG("sending start sequence\n"); _start(i2c, address, I2C_FLAG_WRITE); _clear_addr(i2c); /* send out data bytes */ _write(i2c, data, length); /* end transmission */ DEBUG("Ending transmission\n"); _stop(i2c); DEBUG("STOP condition was send out\n"); return length; }
int i2c_read_bytes(i2c_t dev, uint8_t address, void *data, int length) { unsigned int state; int i = 0; I2C_TypeDef *i2c; uint8_t *my_data = data; switch (dev) { #if I2C_0_EN case I2C_0: i2c = I2C_0_DEV; break; #endif #if I2C_1_EN case I2C_1: i2c = I2C_1_DEV; break; #endif default: return -1; } switch (length) { case 1: DEBUG("Send Slave address and wait for ADDR == 1\n"); _start(i2c, address, I2C_FLAG_READ); DEBUG("Set ACK = 0\n"); i2c->CR1 &= ~(I2C_CR1_ACK); DEBUG("Clear ADDR and set STOP = 1\n"); state = irq_disable(); _clear_addr(i2c); i2c->CR1 |= (I2C_CR1_STOP); irq_restore(state); DEBUG("Wait for RXNE == 1\n"); while (!(i2c->SR1 & I2C_SR1_RXNE)) {} DEBUG("Read received data\n"); *my_data = i2c->DR; /* wait until STOP is cleared by hardware */ while (i2c->CR1 & I2C_CR1_STOP) {} /* reset ACK to be able to receive new data */ i2c->CR1 |= (I2C_CR1_ACK); break; case 2: DEBUG("Send Slave address and wait for ADDR == 1\n"); _start(i2c, address, I2C_FLAG_READ); DEBUG("Set POS bit\n"); i2c->CR1 |= (I2C_CR1_POS | I2C_CR1_ACK); DEBUG("Crit block: Clear ADDR bit and clear ACK flag\n"); state = irq_disable(); _clear_addr(i2c); i2c->CR1 &= ~(I2C_CR1_ACK); irq_restore(state); DEBUG("Wait for transfer to be completed\n"); while (!(i2c->SR1 & I2C_SR1_BTF)) {} DEBUG("Crit block: set STOP and read first byte\n"); state = irq_disable(); i2c->CR1 |= (I2C_CR1_STOP); my_data[0] = i2c->DR; irq_restore(state); DEBUG("read second byte\n"); my_data[1] = i2c->DR; DEBUG("wait for STOP bit to be cleared again\n"); while (i2c->CR1 & I2C_CR1_STOP) {} DEBUG("reset POS = 0 and ACK = 1\n"); i2c->CR1 &= ~(I2C_CR1_POS); i2c->CR1 |= (I2C_CR1_ACK); break; default: DEBUG("Send Slave address and wait for ADDR == 1\n"); _start(i2c, address, I2C_FLAG_READ); _clear_addr(i2c); while (i < (length - 3)) { DEBUG("Wait until byte was received\n"); while (!(i2c->SR1 & I2C_SR1_RXNE)) {} DEBUG("Copy byte from DR\n"); my_data[i++] = i2c->DR; } DEBUG("Reading the last 3 bytes, waiting for BTF flag\n"); while (!(i2c->SR1 & I2C_SR1_BTF)) {} DEBUG("Disable ACK\n"); i2c->CR1 &= ~(I2C_CR1_ACK); DEBUG("Crit block: set STOP and read N-2 byte\n"); state = irq_disable(); my_data[i++] = i2c->DR; i2c->CR1 |= (I2C_CR1_STOP); irq_restore(state); DEBUG("Read N-1 byte\n"); my_data[i++] = i2c->DR; while (!(i2c->SR1 & I2C_SR1_RXNE)) {} DEBUG("Read last byte\n"); my_data[i++] = i2c->DR; DEBUG("wait for STOP bit to be cleared again\n"); while (i2c->CR1 & I2C_CR1_STOP) {} DEBUG("reset POS = 0 and ACK = 1\n"); i2c->CR1 &= ~(I2C_CR1_POS); i2c->CR1 |= (I2C_CR1_ACK); } return length; }
int i2c_read_bytes(i2c_t dev, uint8_t address, char *data, int length) { unsigned int state; int i = 0; if ((unsigned int)dev >= I2C_NUMOF) { return -1; } I2C_TypeDef *i2c = i2c_config[dev].dev; switch (length) { case 1: DEBUG("Send Slave address and wait for ADDR == 1\n"); _start(i2c, address, I2C_FLAG_READ); DEBUG("Set ACK = 0\n"); i2c->CR1 &= ~(I2C_CR1_ACK); DEBUG("Clear ADDR and set STOP = 1\n"); state = disableIRQ(); _clear_addr(i2c); i2c->CR1 |= (I2C_CR1_STOP); restoreIRQ(state); DEBUG("Wait for RXNE == 1\n"); while (!(i2c->SR1 & I2C_SR1_RXNE)); DEBUG("Read received data\n"); *data = (char)i2c->DR; /* wait until STOP is cleared by hardware */ while (i2c->CR1 & I2C_CR1_STOP); /* reset ACK to be able to receive new data */ i2c->CR1 |= (I2C_CR1_ACK); break; case 2: DEBUG("Send Slave address and wait for ADDR == 1\n"); _start(i2c, address, I2C_FLAG_READ); DEBUG("Set POS bit\n"); i2c->CR1 |= (I2C_CR1_POS | I2C_CR1_ACK); DEBUG("Crit block: Clear ADDR bit and clear ACK flag\n"); state = disableIRQ(); _clear_addr(i2c); i2c->CR1 &= ~(I2C_CR1_ACK); restoreIRQ(state); DEBUG("Wait for transfer to be completed\n"); while (!(i2c->SR1 & I2C_SR1_BTF)); DEBUG("Crit block: set STOP and read first byte\n"); state = disableIRQ(); i2c->CR1 |= (I2C_CR1_STOP); data[0] = (char)i2c->DR; restoreIRQ(state); DEBUG("read second byte\n"); data[1] = (char)i2c->DR; DEBUG("wait for STOP bit to be cleared again\n"); while (i2c->CR1 & I2C_CR1_STOP); DEBUG("reset POS = 0 and ACK = 1\n"); i2c->CR1 &= ~(I2C_CR1_POS); i2c->CR1 |= (I2C_CR1_ACK); break; default: DEBUG("Send Slave address and wait for ADDR == 1\n"); _start(i2c, address, I2C_FLAG_READ); _clear_addr(i2c); while (i < (length - 3)) { DEBUG("Wait until byte was received\n"); while (!(i2c->SR1 & I2C_SR1_RXNE)); DEBUG("Copy byte from DR\n"); data[i++] = (char)i2c->DR; } DEBUG("Reading the last 3 bytes, waiting for BTF flag\n"); while (!(i2c->SR1 & I2C_SR1_BTF)); DEBUG("Disable ACK\n"); i2c->CR1 &= ~(I2C_CR1_ACK); DEBUG("Crit block: set STOP and read N-2 byte\n"); state = disableIRQ(); data[i++] = (char)i2c->DR; i2c->CR1 |= (I2C_CR1_STOP); restoreIRQ(state); DEBUG("Read N-1 byte\n"); data[i++] = (char)i2c->DR; while (!(i2c->SR1 & I2C_SR1_RXNE)); DEBUG("Read last byte\n"); data[i++] = (char)i2c->DR; DEBUG("wait for STOP bit to be cleared again\n"); while (i2c->CR1 & I2C_CR1_STOP); DEBUG("reset POS = 0 and ACK = 1\n"); i2c->CR1 &= ~(I2C_CR1_POS); i2c->CR1 |= (I2C_CR1_ACK); } return length; }