// delay.c
#include "delay.h"
// неоптимизируемые компилятором функции процессорных задержек
void delay8(uint8_t ticks)
{
	/*
	архитектрура AVR8 (2560, 328pb), частота = 16 MHz, период 62.5 ns
	испытано на коде c замером осциллографом
		PORTA |= (1 << 1);
		delay8(val);
		PORTA &= ~(1 << 1);
	полученная формула задержки (мкс) = 0,191 * ticks + 1,227, если ticks > 0
	0 ticks = 1,38 мкс
	*/
	__asm__ volatile (	
		"cpc  %A0,__zero_reg__ \n\t" \
		"breq L_Exit_%=       \n\t"  \
		"L_LOOP_%=:           \n\t"  \
		"subi %A0,1           \n\t"  \
		"brne L_LOOP_%=       \n\t"  \
		"L_Exit_%=:           \n\t"  \
		: "=w" (ticks)               \
		: "0"  (ticks)               \
	);                             \
	return;
}

void delay16(uint16_t ticks)
{
	/*
	архитектрура AVR8 (2560, 328pb), частота = 16 MHz, период 62.5 ns
	испытано на коде c замером осциллографом
		PORTA |= (1 << 1);
		delay16(val);
		PORTA &= ~(1 << 1);
	полученная формула задержки (мкс) = 0,250 * ticks + 1,294 , если ticks > 0
	0 ticks = 1,44 мкс
	*/
	__asm__ volatile (
		"cp  %A0,__zero_reg__ \n\t"  \
		"cpc %B0,__zero_reg__ \n\t"  \
		"breq L_Exit_%=       \n\t"  \
		"L_LOOP_%=:           \n\t"  \
		"subi %A0,1           \n\t"  \
		"sbci %B0,0           \n\t"  \
		"brne L_LOOP_%=       \n\t"  \
		"L_Exit_%=:           \n\t"  \
		: "=w" (ticks)               \
		: "0"  (ticks)               \
	);                             \
	return;
}

void init_PUTR()
{
	DDRC |= 1 << PORTC0;
	PORTC |= 1 << PORTC0;
}

void PUTR(uint8_t byte)
{
	#define BIT_TICK	35 // 115200
	uint8_t bit[8];
	for(uint8_t i = 0; i < 8; i++)
		bit[i] = (byte >> i) & 0x01;
	
	// transmittion
	PORTC &= ~(1 << PORTC0);
	delay8(BIT_TICK);
	for(uint8_t i = 0; i < 8; i++)
	{
		if(bit[i] != 0)
			PORTC |= 1 << PORTC0;
		else
			PORTC &= ~(1 << PORTC0);
		delay8(BIT_TICK);
	}
	PORTC |= 1 << PORTC0;
	delay8(BIT_TICK);
}