#define F_CPU 20000000UL  // 20 MHz

#define BAUD 9600
#include <util/setbaud.h>

#include <avr/io.h> // ввод-вывод
#include <util/delay.h>

// USART
void UART_Init(void)
{
    UBRRH = UBRRH_VALUE;
    UBRRL = UBRRL_VALUE;
    UCSRB = (1 << TXEN) | (1 << RXEN); // на будущее, прием пока не нужен
    UCSRC = (1 << USBS) | (3 << UCSZ0);
}

void Send(unsigned char *data) // задел под будущие устройства отображения
{
	USART_Send(data);
}

void USART_Send(unsigned char *data) // Отправка в USART
{
	int i;
	while(data[i]){
		if (data == '\n')
		        USART_Send('\r');
		while ( !( UCSRA & (1<<UDRE)) ){};
		UDR = data[i];
		i++;
	}
}
// END USART

// 1-Wire
int OWI_Init(void) // Функция инициализации
{
	if(OWI_Reset()) { // Даем сброс
		DDRB |= _BV(PB0); // Порт как выход
		PORTB &= ~_BV(PB0); // Уст. 0 (Зажечь светодиод)
		return 1;
	} else return 0;
}

int OWI_Reset(void) // Функция сброса
{
	PORTB &= ~_BV(PB1); // Уст. 0
	DDRB |= _BV(PB1); // Порт как выход
	_delay_us(480);
	DDRB &= ~_BV(PB1); // Порт как вход
	_delay_us(70);
	if ( PINB & _BV(PB1) ){ // если на линии 0, значит SLAVE на линии, дадим ему 410мкс форы
		return 0;
	} else {
		_delay_us(410);
		return 1;
	}
}

void OWI_Send_0(void) // Отправить бит "0"
{
	PORTB &= ~_BV(PB1); // Уст. 0
	DDRB |= _BV(PB1); // Порт как выход
	_delay_us(60);
	DDRB &= ~_BV(PB1); // Порт как вход
	_delay_us(5);
}

void OWI_Send_1(void) // Отправить бит "1"
{
	PORTB &= ~_BV(PB1); // Уст. 0
	DDRB |= _BV(PB1); // Порт как выход
	_delay_us(10);
	DDRB &= ~_BV(PB1); // Порт как вход
	_delay_us(50);
	_delay_us(5);
}

int OWI_Read_bit(void) // Читаем бит
{
	int ret;
	PORTB &= ~_BV(PB1); // Уст. 0
	DDRB |= _BV(PB1); // Порт как выход
	_delay_us(1);
	DDRB &= ~_BV(PB1); // Порт как вход
	_delay_us(14);
	if ( PINB & _BV(PB1) ) {
		ret=1;
	} else {
		ret=0;
	}
	_delay_us(50);
	return ret;
}

/*char OWI_Read_byte(void) // Функция сброса
{
	unsigned char data;
	int i;
	for(i=0;i<8;i++)
	{
		if(OWI_Read_bit()) data |= 1<<(7-i); // Уст. 0
		else data &= ~(1<<(7-i)); // Уст. 0
	}
	return data;
}*/

void OWI_Send_command(unsigned char command)
{
	unsigned char data=command;
	int i;
	for(i=0;i<8;i++)
	{
		data=data<<7;        //Сдвиг на i разрядов влево
		command=command>>1;  //Сдвиг передаваемого байта
		if(data==0x80) OWI_Send_1();       //Передача лог.1
		else  OWI_Send_0();                //Передача лог.0
		data=command;        //Новое значение для сдвига
	};
}
// END 1-Wire

int main(void)
{
	DDRA = 0x00; // Весь порт как вход
	DDRB = 0x00; // Весь порт как вход

	UART_Init();
	if( OWI_Init() ){

		unsigned char *tmp="00000000";
		int i;

		OWI_Send_command(0xEE); // Старт темп. преобразования
		_delay_us(5); // не уверин что нужно, подглядел в чужих исходниках

		//if( ( PINB & _BV(PB1)) ) {} else { Send("Line down\r"); } // Проверяем линию на занятость
		//while( !( PINB & _BV(PB1)) ) {} // Ждем когда освободится
		for(i=0;i<8;i++) _delay_ms(100);

		OWI_Reset();
		OWI_Send_command(0xAA); // Чтение температуры
		_delay_us(5); // не уверин что нужно, подглядел в чужих исходниках
		for(i=0;i<8;i++){ // читаем 8 бит
			if(OWI_Read_bit()){ tmp[7-i] = '1'; // и заносим в темп
			} else tmp[7-i] = '0';
		}
		Send("Temp: ");
		Send(tmp);
		Send("\r");
	}
	return 0;
}
