104 lines
4.3 KiB
C
104 lines
4.3 KiB
C
#include "rush_header.h"
|
|
|
|
volatile uint8_t received_data = 0;
|
|
|
|
void twi_init_slave(void) {
|
|
TWAR = (SLAVE_ADDRESS << 1);
|
|
TWCR = (1 << TWEN) | (1 << TWEA) | (1 << TWIE); // Enable TWI, enable ACK, and enable TWI interrupt
|
|
}
|
|
void twi_stop_slave(void) {
|
|
// TWCR = 0x00; // Disable TWI interrupts and TWI module
|
|
// TWAR = 0x00; // Optionally, clear the TWI address register
|
|
}
|
|
|
|
void twi_init_master() {
|
|
TWSR = TWI_PRESCALE_SET(TWI_PRESCALE_VALUE); // 22.9.3 : (Status Register) set prescaler
|
|
TWBR = ((F_CPU / TWI_FREQ) - 16) / (2 * TWI_PRESCALE_VALUE); // 22.9.1 : (Bit Rate Register) set SCL frequency (formula from datasheet, 22.5.2)
|
|
}
|
|
|
|
void twi_start() {
|
|
TWCR = SEND_START_CONDITION; // 22.9.2 : (Control Register) send Start condition (22.7.1) ! writting 1 to TWINT clears it (set it to 0)
|
|
while (!(TEST(TWCR, TWINT))); // p225 example code : Wait for TWINT Flag set. This indicates that the START condition has been transmitted
|
|
|
|
uint8_t status = TWSR & MASK_WITHOUT_LAST_3; // p225 example code : Check value of TWI Status Register. Mask prescaler bits. If status different from START go to ERROR
|
|
if (status != TW_START && status != TW_REP_START) {
|
|
TWCR = SEND_STOP_CONDITION;
|
|
return;
|
|
}
|
|
}
|
|
|
|
void twi_send_addr(uint8_t addr_r_w) {
|
|
TWDR = addr_r_w; // 22.9.4 : (Data Register) load data into TWDR register
|
|
TWCR = SEND_CONTINUE_TRANSMISSION; // p225 example code : Load SLA_W into TWDR Register. Clear TWINT bit in TWCR to start transmission of address
|
|
while (!(TEST(TWCR, TWINT))); // p225 example code : Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received
|
|
|
|
uint8_t status = TWSR & MASK_WITHOUT_LAST_3; // Check value of TWI Status Register. Mask prescaler bits. If status different from MT_SLA_ACK go to ERROR
|
|
if (status != TW_MT_SLA_ACK) {
|
|
TWCR = SEND_STOP_CONDITION;
|
|
return;
|
|
}
|
|
}
|
|
|
|
void twi_write(uint8_t data) {
|
|
TWDR = data; // 22.9.4 : (Data Register) load data into TWDR register
|
|
TWCR = SEND_CONTINUE_TRANSMISSION; // p225 example code : Load DATA into TWDR Register. Clear TWINT bit in TWCR to start transmission of data
|
|
while (!(TEST(TWCR, TWINT))); // p225 example code : Wait for TWINT Flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received
|
|
|
|
uint8_t status = TWSR & MASK_WITHOUT_LAST_3; // p225 example code : Check value of TWI Status Register. Mask prescaler bits. If status different from MT_DATA_ACK go to ERROR
|
|
if (status != TW_MT_DATA_ACK) {
|
|
TWCR = SEND_STOP_CONDITION;
|
|
return;
|
|
}
|
|
}
|
|
|
|
uint8_t twi_read(uint8_t ack) {
|
|
flash_led(D1); // Before setting TWCR
|
|
if (ack) {
|
|
TWCR = SEND_ACKNOWLEDGE; // Send ACK to request more data
|
|
} else {
|
|
TWCR = SEND_NACKNOWLEDGE; // Send NACK to indicate last byte read
|
|
}
|
|
|
|
// while (!(TEST(TWCR, TWINT))); // Wait for data reception
|
|
// Add a timeout to prevent infinite waiting
|
|
uint16_t timeout = 1000;
|
|
while (!(TEST(TWCR, TWINT)) && timeout > 0) {
|
|
timeout--;
|
|
_delay_us(10);
|
|
}
|
|
|
|
flash_led(D2); // After TWINT set or timeout
|
|
|
|
if (timeout == 0) {
|
|
// Timeout occurred, slave didn't respond
|
|
flash_led(D3); // Indicate timeout
|
|
TWCR = SEND_STOP_CONDITION;
|
|
return 0xFF; // Error code for timeout
|
|
}
|
|
|
|
uint8_t status = TWSR & MASK_WITHOUT_LAST_3;
|
|
if (status != TW_MR_DATA_ACK && status != TW_MR_DATA_NACK) {
|
|
TWCR = SEND_STOP_CONDITION;
|
|
return 0;
|
|
}
|
|
flash_led(D4); // Indicate status error
|
|
return TWDR;
|
|
}
|
|
|
|
void twi_stop() {
|
|
TWCR = SEND_STOP_CONDITION;
|
|
}
|
|
|
|
void write_one_byte_data(uint8_t data) {
|
|
twi_start();
|
|
twi_send_addr((SLAVE_ADDRESS << 1) | TW_WRITE); // Send Slave address with Write bit
|
|
twi_write(data); // write data byte
|
|
twi_stop();
|
|
}
|
|
uint8_t read_one_byte_data() {
|
|
twi_start();
|
|
twi_send_addr((SLAVE_ADDRESS << 1) | TW_READ); // Send Slave address with Write bit
|
|
uint8_t data = twi_read(FALSE); // Read data with NACK (only one byte expected)
|
|
twi_stop();
|
|
return data;
|
|
} |