/*
 * RS485_lib.h
 *
 * kniznica pre riadenie zbernice RS485
 *
 * Created: 1.3.2012 17:18:24
 *  Author: JIRKO
 */ 


#ifndef RS485_LIB_H_
#define RS485_LIB_H_


	#define		cbi(sfr, bit)				(_SFR_BYTE(sfr) &= ~(1 << (bit)))					//Makro na vynulovanie jedneho bitu z registra
	#define    	sbi(sfr, bit)				(_SFR_BYTE(sfr) |= (1 << (bit)))					//Makro na nastavenie jedneho bitu z registra
	#define		UARTTXC						while (bit_is_clear(UCSRA,UDRE)) {}					// caka, pokial odosielanie na UART nie je kompletne
	#define		UARTSEND(znak)				UARTTXC UDR= znak;									// odosle a pocka aj na odoslanie znaku

// nastavenie preruseni USARTU
	#define		DIS_TX_INT					UCSRB= (1<<RXCIE)|(1<<RXEN)|(1<<TXEN)				// POVOLI PRERUSENIE RXCIE TX su zakazane
	#define		EN_TX_UDRIE_INT				UCSRB= (1<<RXCIE)|(1<<UDRIE)|(1<<RXEN)|(1<<TXEN)	// POVOLI PRERUSENIE UDRIE
	#define		EN_TX_TXCIE_INT				UCSRB= (1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN)	// vypne UDRIE zapne TXCIE


//****************   Definicia casov protokolu rs485   **********************************************
		
	// RX
	#define	TIMEOUT_END_OF_PACKET			2			// 400us doba od priatia posledneho byte po ktorej sa prehlasi ze prisiel cely paket 40us
	#define TIMEOUT_RS485_FREE				2			// 400us doba za ktoru sa moze zacat vsielat je nasobena ID casom T0  40us
	#define SET_TCNT0						TCNT0= 0x48	// nastavy casovac na 200us
		
	// TX
	#define	SIZE_TX_BUFF					4			// pocet buniek TX buferru nemoze bit viac ako 8 inak treba uprevit niektore funkcie

	typedef struct{										// definicia bunky tx bufferu
		uint8_t			cell_send_reddy;				// 0 je ze je prazdna 1 ze je obsadena
		uint8_t			data[MAX_PACKET_LENGHT];
	}t_TX_buff;	
	
//****************   Definicia flags_1  RS485  ****************************************************************
	
	#define	RS485_ACCEPTING_DATA			sbi(flags_1,0)					// primaju sa data podla tohto sa riadi casovac aby zistil ktory timeout vyprsal
	#define RS485_LISTEN					cbi(flags_1,0)	
	#define IS_RS485_MODE_ACCEPTING_DATA	bit_is_set(flags_1,0)
		
	#define RS485_IN						cbi(flags_1,1);	cbi(PORTD,2)	// mod RS485 primanie/visielanie
	#define RS485_OUT						sbi(flags_1,1);	sbi(PORTD,2)
	#define IS_RS485_IN						bit_is_clear(flags_1,1)
		
	#define RS485_FREE						sbi(flags_1,3)					// nastavuje sa po timeoute ak je to nastavene tak sa moze vysielat
	#define RS485_BUSSY						cbi(flags_1,3)
	#define IS_RS485_BUSSY					bit_is_clear(flags_1,3)			// ak je free tak sa moze vysielat
		
	#define PACKET_ACCEPTED					sbi(flags_1,4)
	#define REDY_TO_ACCEPT_PACKET			cbi(flags_1,4)
	#define IS_PACKET_ACCEPTED				bit_is_set(flags_1,4)
	#define IS_REDY_TO_ACCEPT_PACKET		bit_is_clear(flags_1,4)
		
	#define TX_1							sbi(PORTD,1)	
	#define TX_0							cbi(PORTD,1)

// ****************   Definicie funkcii   ***********************************************

	// inicializacia tejto knixnice
	void	RS485_init(void);							// inicializacia
	
	// kontroluje ci neprisiel niaky packet
	uint8_t isPacketAccepted(uint8_t *packet);			// kontroluje ci prisiel niaky packet a kopiruje ho do pola na ktore dostava smernik
	
	// casovanie k kniznici RS485_lib 200us
	void	I_TIMER0_RS485(void);				// funkcia sa vola pri viprsani casovaca TIMER 0 zabespeceuje detkciu konca packetu a prori kolizni cas 

	// prida packet do fronty na odoslanie
	uint8_t send_packet(const t_packet *packet);		// funkcia pre odoslatie packetu (ulozenie do odoslielacej fronty) request je ked je viac ako 0
	
	// zabespecuje odosielanie
	uint8_t I_check_TX_RS485(void);					// toto je v maine zabespecuje to kontrou requestov a odosielanie packetov
	
	// prerusenie pri vyprazneni registru UDR
	void	I_USART_UDRE_vect(void);			// funkcia sa vola pri vyprazdneni UDR a zabespecuje odosielanie dat

	// prerusenie ked USART prime byte
	void	I_USART_RXC_vect(void);				// funkcia sa vola pri priati byte a zabespecuje priem dat
	
	// prerusenie ked USART odosle posedny znak
	void	I_USART_TXC_vect(void);

#endif /* RS485_LIB_H_ */