day09/ex04/src/lib/i2c.c

65 lines
1.1 KiB
C
Raw Normal View History

2026-04-27 15:29:51 +02:00
#include "lib/mystd.h"
#include <avr/io.h>
#include <util/twi.h>
#include "lib/i2c.h"
static inline t_error i2c_wait(void) {
uint16_t o = 0;
// wait until done
while (!(TWCR & BV(TWINT)) && o < 32768)
o++;
if (o >= 32768)
return ERROR;
return NO_ERROR;
}
void i2c_init(void) {
// clear the status registers
TWSR = 0x00;
// set the i2c clock speed
TWBR = ((F_CPU / I2C_CLOCK) - 16) / 2;
}
t_error i2c_start(void) {
// CLR INT | SET MASTER | ENABLE ;
TWCR = BV(TWINT) | BV(TWSTA) | BV(TWEN);
ERR_RET(i2c_wait());
return NO_ERROR;
}
t_error i2c_stop(void) {
// CLR INT | ENABLE | STOP ;
TWCR = BV(TWINT) | BV(TWEN) | BV(TWSTO);
return NO_ERROR;
}
t_error i2c_write(uint8_t data) {
// set data to write
TWDR = data;
// CLR INT | ENABLE ;
TWCR = BV(TWINT) | BV(TWEN);
ERR_RET(i2c_wait());
return NO_ERROR;
}
t_error i2c_read_ack(uint8_t* out) {
TWCR = BV(TWINT) | BV(TWEN) | BV(TWEA);
ERR_RET(i2c_wait());
*out = TWDR;
return NO_ERROR;
}
t_error i2c_read_nack(uint8_t* out) {
TWCR = BV(TWINT) | BV(TWEN);
ERR_RET(i2c_wait());
*out = TWDR;
return NO_ERROR;
}