cube-kl/firmware/twi.c

67 lines
1.6 KiB
C

#include "twi.h"
void twi_init() {
// bitrate = 1600000MHz / (16 + 2 * TWBR * 4^TWPS)
// Overall prescaler 40 = 16 + 2 * 3 * 4^1
TWBR = 3; // 2 * 3 = 6
TWSR |= (1 << TWPS0); // 4
}
uint8_t twi_start(void) {
// Enable internal pull-ups
PORTC |= (1 << PC5) | (1 << PC4);
// Setup for sending start condition, trigger sending, keep TWI enabled
TWCR |= (1 << TWSTA) | (1 << TWINT) | (1 << TWEN);
// Poll for TWI unit to finish
while(!(TWCR & (1 << TWINT)));
// Check if start was succesfull
return (TW_STATUS != TW_START);
}
void twi_stop(void) {
// Setup for sending stop condition, trigger sending, keep TWI enabled
TWCR = (1 << TWSTO) | (1 << TWINT) | (1 << TWEN);
}
uint8_t twi_write(uint8_t address, uint8_t data[], uint8_t len) {
// Send start condition
if(twi_start()) {
return 1;
}
TWDR = (address << 1) | TW_WRITE; // We want to write to the slave
TWCR = (1 << TWINT) | (1 << TWEN); // Trigger transmission, keep TWI enabled
// Wait for TWI unit to finish
while(!(TWCR & (1 << TWINT)));
// Make sure the slave has acked
if(TW_STATUS != TW_MT_SLA_ACK) {
return 1;
}
for(uint8_t i = 0; i < len; i++) {
TWDR = data[i]; // Send actual data
TWCR = (1 << TWINT ) | (1 << TWEN); // Trigger transmission, keep TWI enabled
// Wait for TWI unit to finish
while(!(TWCR & (1 << TWINT)));
// Make sure the data has been acked
if(TW_STATUS != TW_MT_DATA_ACK) {
return 1;
}
}
// Send stop condition
twi_stop();
return 0;
}