#define F_CPU 20000000UL  // 20 MHz

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

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

void __delay_us(int s){
	int i;
	/*if(s<10) _delay_us(s);
	else */for(i=0;i<(s/10);i++) _delay_us(10);
}

// 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) // Функция сброса
{
	DDRB |= _BV(PB1); // Порт как выход
	PORTB &= ~_BV(PB1); // Уст. 0
	__delay_us(500);
	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"
{
	DDRB |= _BV(PB1); // Порт как выход
	PORTB &= ~_BV(PB1); // Уст. 0
	__delay_us(60);
	DDRB &= ~_BV(PB1); // Порт как вход
	_delay_us(10);
}

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

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

/*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() ){
		OWI_Send_command(0x33);
		_delay_us(75); // не уверин что нужно, подглядел в чужих исходниках
		unsigned char *tmp="";
		int i;

		for(i=0;i<64;i++){ // читаем 64 бита
			if(OWI_Read_bit()){ tmp[i] = '1'; // и заносим в темп
			} else tmp[i] = '0';
		}
		tmp[64]=0x00;
		Send(tmp); // выводим адрес
	}

	return 0;
}
