Reflow oven controller firmware
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

95 lines
1.8 KiB

/* i2c.c */
#include <avr/io.h>
#include <util/twi.h>
#include <avr/interrupt.h>
#include "common.h"
#include "beep.h"
//#define i2c_wait() do { uint16_t count = 0; while (!(TWCR & (1<<TWINT))) if (count++ > 1000) break; } while (0)
//#define i2c_status() (TWSR & 0xF8)
#define i2c_check(status) if (i2c_status() != (status)) goto ERROR
static void i2c_wait(void)
{
uint16_t count = 0;
while (!(TWCR & (1<<TWINT)))
if (count++ > 1000)
break;
}
static __attribute__ ((noinline)) uint8_t i2c_status(void)
{
return TWSR & 0xF8;
}
uint8_t i2c_xor;
void i2c_init(void)
{
TWSR = 0; /* prescaler TWPS = 0 */
TWBR = 10; /* minimum value allowed */
/* f_SCL = clk / (16+(2*TWBR*TWPS)) */
TWCR = (1<<TWEN);
i2c_xor = 0;
}
//#define i2c_start() do { TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); } while (0)
//#define i2c_stop() do { TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); } while (0)
//#define i2c_txbyte(data) do { TWDR = data; TWCR = (1 << TWINT) | (1<<TWEN); } while (0)
static void i2c_start(void)
{
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
}
static void i2c_stop(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
}
static __attribute__((noinline)) void i2c_txbyte(uint8_t data)
{
TWDR = data;
TWCR = (1 << TWINT) | (1<<TWEN);
}
void i2c_set_xor(uint8_t xor)
{
i2c_xor = xor;
}
bool i2c_write(uint8_t address, uint8_t prefix, uint8_t bytes, uint8_t *data)
{
uint8 i;
i2c_start();
i2c_wait();
i2c_check(TW_START);
i2c_txbyte((address << 1) + 0);
i2c_wait();
i2c_check(TW_MT_SLA_ACK);
i2c_txbyte(prefix);
i2c_wait();
i2c_check(TW_MT_DATA_ACK);
for (i = 0; i < bytes; i++) {
i2c_txbyte(data[i] ^ i2c_xor);
i2c_wait();
i2c_check(TW_MT_DATA_ACK);
}
i2c_stop();
return TRUE;
ERROR:
i2c_stop();
return FALSE;
}