#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; }