This commit is contained in:
Олег Бородин
2025-02-02 20:13:15 +02:00
parent 9ae1e7bc07
commit 693b6b33b8
8 changed files with 253 additions and 26 deletions

38
i2c.c
View File

@@ -1,21 +1,25 @@
#include <i2c.h>
#include <util/delay.h>
uint8_t i2c_error;
uint8_t i2c_status;
#define PSC_I2C 1 // I2C prescaler
#define F_I2C 400000UL // I2C Clock
#define SET_TWBR (F_CPU/F_I2C-16UL)/(PSC_I2C*2UL)
void i2c_init(void) {
i2c_error = 0;
switch (PSC_I2C) {
case 4:
TWSR = 0x1;
TWSR = 0x01;
break;
case 16:
TWSR = 0x2;
TWSR = 0x02;
break;
case 64:
TWSR = 0x3;
TWSR = 0x03;
break;
default:
TWSR = 0x00;
@@ -28,7 +32,7 @@ void i2c_init(void) {
void i2c_start(void) {
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
uint16_t timeout = F_CPU / F_I2C * 2.0;
while ((TWCR & (1 << TWINT)) == 0) {
while (!(TWCR & (1 << TWINT))) {
if (--timeout == 0) {
i2c_error |= (1 << I2C_ERR_START);
return;
@@ -36,11 +40,22 @@ void i2c_start(void) {
};
}
void i2c_restart(void) {
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
uint16_t timeout = F_CPU / F_I2C * 2.0;
while (!(TWCR & (1 << TWINT))) {
if (--timeout == 0) {
i2c_error |= (1 << I2C_ERR_RESTART);
return;
}
};
}
void i2c_write(uint8_t byte) {
TWDR = byte;
TWCR = (1 << TWINT) | (1 << TWEN);
uint16_t timeout = F_CPU / F_I2C * 2.0;
while ((TWCR & (1 << TWINT)) == 0) {
while (!(TWCR & (1 << TWINT))) {
if (--timeout == 0) {
i2c_error |= (1 << I2C_ERR_WRITE);
return;
@@ -48,12 +63,6 @@ void i2c_write(uint8_t byte) {
};
}
void i2c_stop(void) {
TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);
while (TWCR & (1 << TWSTO));
}
uint8_t i2c_read_ack(void) {
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA);
uint16_t timeout = F_CPU / F_I2C * 2.0;
@@ -68,7 +77,7 @@ uint8_t i2c_read_ack(void) {
uint8_t i2c_read_nack(void) {
TWCR = (1 << TWINT) | (1 << TWEN);
uint16_t timeout = F_CPU / F_I2C * 4.0;
uint16_t timeout = F_CPU / F_I2C * 2.0;
while ((TWCR & (1 << TWINT)) == 0) {
if (--timeout == 0) {
i2c_error |= (1 << I2C_ERR_READNACK);
@@ -77,3 +86,8 @@ uint8_t i2c_read_nack(void) {
};
return TWDR;
}
void i2c_stop(void) {
TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);
//while (TWCR & (1 << TWSTO));
}