//	Modulární grafický LED displej
//	řídící program pro jednotku Master
#include "mega8.h"
#include "TWI_Master.h"

#define TWI_GEN_CALL         0x00  // The General Call address is 0

// Sample TWI transmission commands
#define TWI_CMD_HORNI_SEGMENT 0x01
#define TWI_CMD_DOLNI_SEGMENT 0x02
#define TWI_CMD_ZVYSIT_RYCHLOST 0x03
#define TWI_CMD_SNIZIT_RYCHLOST 0x04
#define TWI_CMD_MASTER_READ  0x05
#define TWI_CMD_CHANGE_MODE  0x06
// Sample TWI transmission states, used in the main application.
#define SEND_DATA             0x01
#define REQUEST_DATA          0x02
#define READ_DATA_FROM_BUFFER 0x03
#define SEND_COMMAND 0x03
//USART
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
// USART Receiver buffer
#define RX_BUFFER_SIZE 32
//-----------------------------------------------------------------------------------------
char rx_buffer[RX_BUFFER_SIZE],i,RESTART=0;
unsigned char rx_wr_index,rx_rd_index,rx_counter,tx_wr_index,tx_rd_index,tx_counter,pocet=0;
volatile char   pom=0;
bit rx_buffer_overflow;
//eeprom char znaky[100];
interrupt [1] void reset(void)
{


}
//--------------------------------------------------------------------------------------
//obsluha přerušení UARTu
interrupt [USART_RXC] void uart_rx_isr(void)
{
char status,ctrl,data;  
#asm
    push r26
    push r27
    push r30
    push r31
    in   r26,sreg
    push r26
#endasm   
status=UCSRA;
ctrl=UCSRB;
data=UDR; 
rx_buffer[rx_wr_index]=data;
if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if (++rx_counter == RX_BUFFER_SIZE)
      	{
      	rx_counter=RX_BUFFER_SIZE;
      	rx_buffer_overflow=1;
      	}   
#asm
    pop  r26
    out  sreg,r26
    pop  r31
    pop  r30
    pop  r27
    pop  r26
#endasm
}
//--------------------------------------------------------------------------------------
unsigned char TWI_Failure_In_Last_Transm ( unsigned char TWIerrorMsg )
{  
 if ( (TWIerrorMsg == TWI_MTX_ADR_NACK) | (TWIerrorMsg == TWI_MRX_ADR_NACK) )
    TWI_Start_Transceiver();
  
  PORTC.1=1; 
  return TWIerrorMsg; 
}
   
//--------------------------------------------------------------------------------------
//funkce pro vyslání jednoho bajtu přes UART
void putchar(char c) 
{ 
#asm("cli")
while ( ! (UCSRA & (1<< UDRE)))
	;
UDR=c;	
#asm("sei")  

}
//--------------------------------------------------------------------------------------
//funkce pro načtení jednoho bajtu z příjímacího bufferu UARTu
char getchar(void)
{
char datax;
while (rx_counter==0);
datax=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#asm("cli")
--rx_counter;
#asm("sei")
return datax;
}
//--------------------------------------------------------------------------------------
void main( void )
{
  unsigned char messageBuf[32], znak[6]={10, 11, 12, 13, 14, 15 };
  unsigned char TWI_targetSlaveAddress=0x01, temp, TWI_operation=0,stav,index=2,k;

TWI_statusReg.lastTransOK=1;
               
PORTB=0x00;
DDRB=0x00;
PORTC=0x00;
DDRC=0x03;
PORTD=0x00;
DDRD=0x00;
// nastavení čítače/časovače 0
TCCR0=0x00;
TCNT0=0x00;
// nastavení čítače/časovače 1
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// nastavení čítače/časovače 2
TCCR2=0x00;
ASSR=0x00;
TCNT2=0x00;
OCR2=0x00;
// nastavení vnějších zdrojů přerušení
GICR=0x00;
MCUCR=0x00;
// nastavení přerušení od čítačů/časovačů
TIMSK=0x00;
//nastavení A/D převodníku
ACSR=0x80;
SFIOR=0x00;
//nastavení USARTU
UCSRA=0x00;             //satus register
UCSRB=0b10011000;	//Rx_int enable | Tx_int disable | datareg_empty_int disable |
			//reciever enable| Trensmitter enable | 9 databit disable | 9th_Rx | 9th_Tx
UCSRC=0b10000110;  	// nic | mode asynchronous | parity dis. | parity dis. | 1 stop bit | 8databits | 8databits |  clock_pol.    
//UCSRC=0b10001110;  	//2stopbit
UBRRL=0x33;		//9600 baud
UBRRH=0x00;   
TWI_Master_Initialise();	//inicializace rozhraní TWI

#asm("sei")	//povolení přerušení
//--------------------------------------------------------------------------------------
 for(;;)
 {        
  if (rx_counter>0 )   
   	{ 
    	pom=getchar();
        //=========================================================================================================
   	switch (pom) 
    		{
	       	case TWI_CMD_HORNI_SEGMENT:
	           	messageBuf[0] = (TWI_targetSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); 
		       	messageBuf[1] = TWI_CMD_HORNI_SEGMENT; 
                        TWI_operation = SEND_DATA;
                        
                        //TWI_Start_Transcvr_With_Data( messageBuf, index-1 ); 
          	break;
      	       //..................................................................................................
      	       case TWI_CMD_DOLNI_SEGMENT: 
      	       	     
	       	        messageBuf[0] = (TWI_targetSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); 
	  		messageBuf[1] = TWI_CMD_DOLNI_SEGMENT;             // The first byte is used for commands.
                        TWI_operation = SEND_DATA;
                break; 
      	       //..................................................................................................
      		case TWI_CMD_CHANGE_MODE:
      		       // PORTC.0=1;
      		          //	putchar('M');
		 	//zakazat preruseni od prijmu USART
		        messageBuf[0] = (TWI_targetSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); 
			messageBuf[1] = TWI_CMD_CHANGE_MODE;             // The first byte is used for commands.
                	TWI_operation=SEND_COMMAND;
                break; 
      	       //..................................................................................................
      		case TWI_CMD_ZVYSIT_RYCHLOST:
      			messageBuf[0] = (TWI_targetSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); 
			messageBuf[1] = TWI_CMD_ZVYSIT_RYCHLOST;             // The first byte is used for commands.
                        TWI_operation=SEND_COMMAND;   
   		break;
      	       //..................................................................................................
      	 	case TWI_CMD_SNIZIT_RYCHLOST: 
      		        
      		            //	putchar('-');
		 	//zakazat preruseni od prijmu USART
		        messageBuf[0] = (TWI_targetSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); 
			messageBuf[1] = TWI_CMD_SNIZIT_RYCHLOST;             // The first byte is used for commands.
                	TWI_operation=SEND_COMMAND;    
   		break;
      	       //..................................................................................................
      		default:
      			messageBuf[index++]=pom;
      		}	//konec switch (pom)
        //=========================================================================================================
	if ( ! TWI_Transceiver_Busy() )
    		{
    		// zkontroluje jestli poslední operacewe proběhla správně
      		if ( TWI_statusReg.lastTransOK )
      			{
        		if ( TWI_operation ) // následující operace
        			{
       				// rozhodování akce podle status kódu
           			if (TWI_operation == SEND_DATA )
          				{	  
               			      /*	for(temp=0;temp<index;temp++) 
            					{
            	       	       			putchar(messageBuf[temp]);
            					}  */
                			TWI_Start_Transcvr_With_Data( messageBuf, index );  
            				index=2; 
          				TWI_operation = FALSE;
          	       			}
     				else if (TWI_operation == SEND_COMMAND)
          				{ 
               				TWI_Start_Transcvr_With_Data( messageBuf, 2 );       
            				TWI_operation = FALSE;              
          				}  
        			}
      			}
      		else // nastala chyba při poslením TWI přenosu
      			{
        		// zjistí stav TWI a provede příslušnou akci
        		TWI_Failure_In_Last_Transm( TWI_Get_State_Info( )) ;
      			}
    		}

    // možno provádět jinou činnost než bude dokončen přenos
   	}//konec if (rx_counter>0) 
 }  	//konec for(;;)
}	//konec main()
   
