//-----------------------------------------------------------------------------------------
// Portkonstanten fr DIP180

#define D0D7PORT	PORTC
#define D0D7DDR		DDRC
#define D0D7PIN		PINC

#define RSPORT		PORTB
#define RS			5
#define RWPORT		PORTB
#define RW			6

#define E1PORT		PORTD
#define E1			4		// muss im Hardwareinit auf 0 gesetzt werden
#define E2PORT		PORTD
#define E2			5		// muss im Hardwareinit auf 0 gesetzt werden
#define E3PORT		PORTB
#define E3			7		// muss im Hardwareinit auf 0 gesetzt werden

#define DRESPORT	PORTB
#define DRES		4		// muss im Hardwareinit auf 1 gesetzt werden


//*****************************************************************************************
// Konstanten fr DIP180

#define XMAX    179
#define MAXPAGE   3

#define E1MIN     0
#define E1MAX    59
#define E2MIN    60
#define E2MAX   119
#define E3MIN   120
#define E3MAX   179

//-----------------------------------------------------------------------------------------
// Konstanten fr SED1520

#define DISPOFF    0xAE  // Command fr Display OFF
#define DISPON     0xAF  // Command fr Display ON
#define DISPSTART  0xC0  // Basiswert fr Display Start Line
#define PAGEADR    0xB8  // Basiswert fr Page Address Set
#define COLADR     0x00  // Basiswert fr Column Address Set
#define DUTY16     0xA8  // Command fr 1/16 Multiplex Rate
#define DUTY32     0xA9  // Command fr 1/32 Multiplex Rate
#define STATOFF    0xA4  // Command fr Static Drive OFF
#define STATON     0xA5  // Command fr Static Drive ON
#define ADCLEFT    0xA0  // Command fr ADC-Select von Links->Rechts
#define ADCRIGHT   0xA1  // Command fr ADC-Select von Rechts->Links
#define RDMODWRON  0xE0  // Command fr Read Modify On
#define RDMODWROFF 0xEE  // Command fr Read Modify Off
#define RESET      0xE2  // Command fr Software Reset


//-----------------------------------------------------------------------------------------
// Funktions Makros

#define SetBit(adr, bnr)	(  (adr) |=  (1 << (bnr))      )
#define ClrBit(adr, bnr)	(  (adr) &= ~(1 << (bnr))      )
#define EorBit(adr, bnr)	(  (adr) ^=  (1 << (bnr))      )
#define TstBit(adr, bnr)	( ((adr) &   (1 << (bnr))) > 0 )

//-----------------------------------------------------------------------------------------
// Funktions deklarationen

void DisplayInit       (void);

void lcd3xbefout       (unsigned char byte);
void lcdbefout         (unsigned char enable, unsigned char byte);
void lcddatout         (unsigned char enable, unsigned char byte);
unsigned char lcddatin (unsigned char enable);

//-----------------------------------------------------------------------------------------

void DisplayInit(void)
{
  unsigned int i;
  
  ClrBit(DRESPORT, DRES);			// Display Reset
  for(i=0; i < 6; i++)  _NOP(); 	// ~3s warten (ein Durchlauf ca. 500ns bei 14,74 MHz)
  SetBit(DRESPORT, DRES);
  for(i=0; i < 60000; i++)  _NOP();	// ~30ms warten (ein Durchlauf ca. 500ns bei 14,74 MHz)
  
  lcd3xbefout(DUTY32);
  lcd3xbefout(ADCLEFT);
  lcd3xbefout(DISPON);
  lcd3xbefout(STATOFF);
  lcd3xbefout(DISPSTART+0);
}

unsigned char SetColumn(unsigned char Xcolumn, unsigned char Ypage)
{
  unsigned char enable, offset;
  
  enable = 0;

  if(Ypage <= MAXPAGE)
   {
     if(Xcolumn <= E1MAX)
      { enable = 1;
        offset = E1MIN;
      }
     else if(Xcolumn <= E2MAX)
      { enable = 2;
        offset = E2MIN;
      }
     else if(Xcolumn <= E3MAX)
      { enable = 3;
        offset = E3MIN;
      }
   }
     
  if(enable > 0)
   { lcdbefout(enable, PAGEADR + Ypage);
     lcdbefout(enable, COLADR + Xcolumn - offset);
   }

  return enable;
}

//-----------------------------------------------------------------------------------------

void lcd3xbefout(unsigned char bef)
{ 
  unsigned char enable;
  
  for(enable = 1; enable <= 3; enable++)
     lcdbefout(enable, bef);
}

//-----------------------------------------------------------------------------------------
// Funktionen fr Byte En-/Ausghabe vom/zum SED1520

unsigned char SED1520in(unsigned char enable)
{
  unsigned char in;

  if(enable == 1)
     SetBit(E1PORT, E1);
  else if(enable == 2)
     SetBit(E2PORT, E2);
  else if(enable == 3)
     SetBit(E3PORT, E3);
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  in = D0D7PIN;
  _NOP();
  if(enable == 1)
     ClrBit(E1PORT, E1);
  else if(enable == 2)
     ClrBit(E2PORT, E2);
  else if(enable == 3)
     ClrBit(E3PORT, E3);

  return in;
}

void SED1520out(unsigned char enable)
{
  if(enable == 1)
     SetBit(E1PORT, E1);
  else if(enable == 2)
     SetBit(E2PORT, E2);
  else if(enable == 3)
     SetBit(E3PORT, E3);
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  _NOP();
  if(enable == 1)
     ClrBit(E1PORT, E1);
  else if(enable == 2)
     ClrBit(E2PORT, E2);
  else if(enable == 3)
     ClrBit(E3PORT, E3);
}

void lcdwaitbusy(unsigned char enable)
{
  D0D7DDR  = 0x00;
  D0D7PORT = 0x00;

  ClrBit(RSPORT, RS);
  SetBit(RWPORT, RW);
     
  while(TstBit(SED1520in(enable), 7) == 1)
     ;
}

void lcdbefout(unsigned char enable, unsigned char out)
{
  if(enable == 0)
     return;
     
  lcdwaitbusy(enable);

  D0D7DDR  = 0xFF;
  D0D7PORT = out;

  ClrBit(RWPORT, RW);

  SED1520out(enable);
}

void lcddatout(unsigned char enable, unsigned char out)
{
  if(enable == 0)
     return;
     
  lcdwaitbusy(enable);

  D0D7DDR  = 0xFF;
  D0D7PORT = out;

  SetBit(RSPORT, RS);
  ClrBit(RWPORT, RW);

  SED1520out(enable);
}

unsigned char lcddatin(unsigned char enable)
{
  if(enable == 0)
     return(0);

  lcdwaitbusy(enable);
 
  SetBit(RSPORT, RS);

  return(SED1520in(enable));
}

