/* FILE / DATE:     dcf_sim_.c / 2010-05-03
   DESCRIPTION:     DCF Simulator

   MICRO-PROCESSOR: PIC16F886
   COMPILER:        B Knudsen Cc5x C-compiler - not ANSI-C

   EXTERNAL HW:     LCD Display 
                    4 pushbuttons with LED
                    Rotating encoder
                    2 LEDs

   DESIGNER:        Hans Sundgren
   CREDIT:          William Sandqvist for rotary encoder reading

   RAM usage:       172 bytes (12 local), 196 bytes free
   CODE WORDS:      4450 code words (54 %)
   

CHIP CONNECTIONS ********************************************
                      _________  ________           
                     |         \/        |         
                     |       16F886      |   
                    -|RE3   1     28  RB7|-   
     Output.PULSE--<-|RA0   2     27  RB6|-  
     LCD.backlight-<-|RA1   3     26  RB5|-<-Btn.START      
      LED.SET------<-|RA2   4     25  RB4|-<-Btn.TRANSMIT
      LED.VIEW-----<-|RA3   5     24  RB3|-<-Btn.VIEW
      LED.TRANSMIT-<-|RA4   6     23  RB2|-<-Btn.SET 
      LED.START----<-|RA5   7     22  RB1|-<-Encoder.A
               GND---|Vss   8     21  RB0|-<-Encoder.B
           LED.one-<-|RA7   9     20  Vdd|---+5V    
          LED.null-<-|RA6  10     19  Vss|---GND
   XTAL 32,768 kHz---|OSO  11     18  RC7|->-LCD.D7
   XTAL 32,768 kHz---|OSI  12     17  RC6|->-LCD.D6
            LCD.RS-<-|RC2  13     16  RC5|->-LCD.D5
            LCD.EN-<-|RC3  14     15  RC4|->-LCD.D4
                     |___________________|         


DISPLAY VIEWS, 1 -> 2 -> 3 -> 4 -> 1 -> ...
 _____________________________________________
| View | Shows                | LCD backlight |
|------|----------------------|---------------|
| 1    | Time and bit display | No            |
| 2    | Time and bit display | Yes           |
| 3    | Bit overview         | Yes           |
| 4    | Bit description      | Yes           |
|______|______________________|_______________|


PUSH-BUTTONS
 ____________________________________________________________
| Button     | Color  | Pin | Lamp, pin: lit                 |
|------------|--------|-----|--------------------------------|
| Start/Stop | Green  | RB5 | RA5 | On during clock running  |
| Transmit   | Red    | RB4 | RA4 | Blink on output signal   |
| View       | Blue   | RB3 | RA3 | Blink when pressed       |
| Set        | Yellow | RB2 | RA2 | On during set clock      |
|____________|________|_____|________________________________|


LED INDICATORS
 ____________________________________________________________
| LED        | Color  | Pin | Lit during...                  |
|------------|--------|-----|--------------------------------|
| 0          | Yellow | RA7 | Output = 0                     |
|            |        |     | Decrement during clock setting |
|            |        |     |                                |
| 1          | Green  | RA6 | Output = 1                     |
|            |        |     | Increment during clock setting |
|____________|________|_____|________________________________|


ROTATING DIALS
 ____________________________________________________________
| Type           |  Function                       | Pin     |
|----------------|-------------------------------------------|
| Rotary encoder | Increase/decrease clock setting | RB0/RB1 |              
|________________|_________________________________|_________|


                                     
PROGRAM OVERVIEW  *******************************************

    Interrupt: 1 Hz ----------------------------------------
   |  If start_mode = 1                                     |
   |     Update clock (step up one second)                  |
   |     Output pulse-value                                 |
   |  Update display                                        |
   |  Check buttons                                         |
   |     If VIEW-button                                     |
   |        Step up display mode 0->1->2->3->0              |
   |     If SET-button                                      |
   |        Setting > 0                                     |
   |         Stop interrupt, jump out to setting sequence   |
    --------------------------------------------------------

    Interrupt: Rotary encoder, during "set clock" ----------
   |  Read encoder                                          |
   |     If increase                                        |
   |        up = 1 and blink LED0                           |
   |     If decrease                                        |
   |        down = 1 and blink LED1                         |
    --------------------------------------------------------

    Main ---------------------------------------------------
   |  Initialization                                        |
   |  Read stored time from EEPROM                          |
   |  Interrupt is active 1 Hz, but the clock is stopped    |
   |  Loop                                                  |
   |     Check START-button                                 |
   |        If START-button                                 |
   |           Toggle start_mode                            |
    --------------------------------------------------------

    Set clock sequence  ------------------------------------
   |  Disable 1 Hz interrupt                                |
   |  Enable rotary encoder interrupt                       |
   |  Step through set sequence, read rotary encoder        |
   |     Update and display time values                     |
   |  Store set time in EEPROM                              |
   |  Enable 1 Hz interrupt                                 |
    --------------------------------------------------------
   */


/* _______________________________ INCLUDE __________________________ */
#include "16F886.h"
#include "int16CXX.H"

/* _______________________________ CONFIGURATION ____________________ */

#pragma config WDTE=0, FOSC=4, PWRTE=1

/* _______________________________ GLOBAL VARIABLES _________________ */


bit start_mode;     // Clock running or not
char display_mode;  // Display alternatives: 1=clock, 2=overview, 3=details
char set_mode;      // Setting mode; 0=no set, 1=min, 2=hour, 3=day, etc.

char tick_pos;      // Current position in the bit stream
char tick_pos_1;
char tick_pos_10;
char bit_val;
char transit;       // Store rotary encoder transitions 
bit up;
bit down;
bit tranmit_on;


char stored_time[14]; // Time data stored in EEPROM
char START_pressed;
char SET_pressed;
char no_of_ones;      // Counter of total no. of ones for parity bit setting
char first;
bit trans_mode;       //Transmitting on/off

//#pragma rambank 1


#pragma rambank 1

char bit_value[60]; // The one-minute bit stream to output

int sec1;           // DCF77 clock, second units
int sec10;          // DCF77 clock, second tens
int min1;           // DCF77 clock, minute units
int min10;          // DCF77 clock, minute tens
int hour1;          // DCF77 clock, hour units
int hour10;         // DCF77 clock, hour tens
int day1;           // DCF77 clock, day units
int day10;          // DCF77 clock, day tens 
int month1;         // DCF77 clock, month units
int month10;        // DCF77 clock, month tens 
int year1;          // DCF77 clock, year units (200X)
int year10;         // DCF77 clock, year tens  (20x0)
char weekday;       // DCF77 clock, day of week, starting Monday
char dst;           // DCF77 clock, Daylights saving time on/off 


#pragma rambank 2

char c_pos[60];


/* _______________________________ FUNCTIONS _____________ */

void delay(char millisec);
void delay10(char n);
void delay250us(char millisec);

void get_bitvalue();            // Get the value of the current bit
void output_bitvalue();         // Send the bitvalue to LED and output

void set_bitvalue (void);       // Set bit stream once per minute based on clock

void pixel_def( void );
void lcd_init( void );          // Initalize the LCD display
void lcd_putchar( char data );  // Display one character on LCD
void lcd_putint( char value );
void lcd_strobe( void );
void lcd_startmsg(void);

void lcd_string ( char * s );

void lcd_command ( char cmd );

void put_eedata( void );
void get_eedata( void );

void update_display_mode_3 (void);
void update_display_mode_4 (void);

char text1( char );
char text2( char );
char text3( char );
char text4( char );
char text5( char );
char text6( char );
char text11( char );
char text12( char );
char text13( char );
char text14( char );
char text15( char );
char text16( char );
char text17( char );


void blink_led (char id);

void blink_null (void);
void blink_one (void);

void update_clock (void);
void update_minutes (void);

void set_clock (void);

void blink_empty (char digits);
void blink_digits (char dig1, char dig2);

void check_btn (void);

void display_time(void);

void display_weekday (void);
void display_dst (void);

void display_3_pos (void);
void display_4_pos (void);

//void display_bit_range (char s1, char s2, char t1, char t2);

interrupt int_server(void);

#define CLEAR     0b0.0000001

#define POS_1_0   0b1.0000000    // LCD display line 1
#define POS_1_1   0b1.0000001
#define POS_1_4   0b1.0000100
#define POS_1_5   0b1.0000101
#define POS_1_6   0b1.0000110
#define POS_1_7   0b1.0000111
#define POS_1_8   0b1.0001000
#define POS_1_9   0b1.0001001
#define POS_1_10  0b1.0001010
#define POS_1_11  0b1.0001011
#define POS_1_12  0b1.0001100
#define POS_1_13  0b1.0001101
#define POS_1_14  0b1.0001110
#define POS_1_15  0b1.0001111
#define POS_1_16  0b1.0010000
#define POS_1_17  0b1.0010001
#define POS_1_18  0b1.0010010
#define POS_1_19  0b1.0010011

#define POS_2_0   0b1.1000000    // LCD display line 2
#define POS_2_1   0b1.1000001
#define POS_2_2   0b1.1000010
#define POS_2_3   0b1.1000011
#define POS_2_4   0b1.1000100
#define POS_2_5   0b1.1000101
#define POS_2_6   0b1.1000110
#define POS_2_7   0b1.1000111
#define POS_2_8   0b1.1001000
#define POS_2_9   0b1.1001001
#define POS_2_10  0b1.1001010
#define POS_2_11  0b1.1001011
#define POS_2_12  0b1.1001100
#define POS_2_13  0b1.1001101
#define POS_2_14  0b1.1001110
#define POS_2_15  0b1.1001111
#define POS_2_16  0b1.1010000
#define POS_2_17  0b1.1010001
#define POS_2_18  0b1.1010010
#define POS_2_19  0b1.1010011

#define POS_3_0   0b1.0010100     // LCD display line 3
#define POS_3_1   0b1.0010101
#define POS_3_2   0b1.0010110
#define POS_3_3   0b1.0010111
#define POS_3_4   0b1.0011000
#define POS_3_5   0b1.0011001
#define POS_3_6   0b1.0011010
#define POS_3_7   0b1.0011011
#define POS_3_8   0b1.0011100
#define POS_3_9   0b1.0011101
#define POS_3_10  0b1.0011110
#define POS_3_11  0b1.0011111
#define POS_3_12  0b1.0100000
#define POS_3_13  0b1.0100001
#define POS_3_14  0b1.0100010
#define POS_3_15  0b1.0100011
#define POS_3_16  0b1.0100100
#define POS_3_17  0b1.0100101
#define POS_3_18  0b1.0100110
#define POS_3_19  0b1.0100111

#define POS_4_0   0b1.1010100      // LCD display line 4
#define POS_4_1   0b1.1010101
#define POS_4_2   0b1.1010110
#define POS_4_3   0b1.1010111
#define POS_4_4   0b1.1011000
#define POS_4_5   0b1.1011001
#define POS_4_6   0b1.1011010
#define POS_4_7   0b1.1011011
#define POS_4_8   0b1.1011100
#define POS_4_9   0b1.1011101
#define POS_4_10  0b1.1011110
#define POS_4_11  0b1.1011111
#define POS_4_12  0b1.1100000
#define POS_4_13  0b1.1100001
#define POS_4_14  0b1.1100010
#define POS_4_15  0b1.1100011
#define POS_4_16  0b1.1100100
#define POS_4_17  0b1.1100101
#define POS_4_18  0b1.1100110
#define POS_4_19  0b1.1100111


/* _______________________________ I/O PIN DEFINITIONS ____ */

#pragma bit PULSE @ PORTA.0     // Output signal to transmitter
#pragma bit T_ON  @ PORTB.7     // Transmitter on/off

#pragma bit LED0  @ PORTA.6     // LED indication "zero"
#pragma bit LED1  @ PORTA.7     // LED indication "one"

#pragma bit START @ PORTB.5     // Button START
#pragma bit TRANS @ PORTB.4     // Button TRANMIT
#pragma bit VIEW  @ PORTB.3     // Button VIEW
#pragma bit SET   @ PORTB.2     // Button SET
#pragma bit ROTA  @ PORTB.0     // Rotating encoder A
#pragma bit ROTB  @ PORTB.1     // Rotating encoder B

#pragma bit I_START @ PORTA.5   // Indicator START button
#pragma bit I_TRANS @ PORTA.4   // Indicator TRANMIT button
#pragma bit I_VIEW  @ PORTA.3   // Indicator VIEW button
#pragma bit I_SET   @ PORTA.2   // Indicator SET button

#pragma bit D4    @ PORTC.4     // LCD control
#pragma bit D5    @ PORTC.5     // LCD control
#pragma bit D6    @ PORTC.6     // LCD control
#pragma bit D7    @ PORTC.7     // LCD control
#pragma bit RS    @ PORTC.2     // LCD control
#pragma bit EN    @ PORTC.3     // LCD control
#pragma bit LCDLI @ PORTA.1     // LCD backlight

//#pragma bit start_VIEW @ 0x20.7


#pragma origin 4                // Special interrupt instruction CC5x
#pragma sharedAllocation        // Special interrupt instruction CC5x


/* _______________________________ INTERRUPT FUNCTION _______________________ */

interrupt int_server(void)
{
   int_save_registers                 // W, STATUS (and PCLATH)
   char sv_FSR = FSR;

   if(RBIF==1)                        // Rotary encoder interrupt
   {
      char m;
      char k;
      for (m=0; m<2; m++)             // debounce
      {
         for (k=0; k<250; k++)
         {
         nop();
         nop();
         }
      }
      transit.0=ROTB;                 // Read rotary encoder value
      transit.1=ROTA;
      if( transit==0b00.01 )          // Compare value
      {
         down=1;
      }
      if( transit==0b01.00 )
      {
         up=1;
      }
      transit.2=transit.0;            // Replace old with new
      transit.3=transit.1;
      RBIF = 0;                       // Reset interrupt flag
   }
   if (TMR1IF)                        // Timer 1 overflow interrupt
   {
      TMR1IF = 0;                     // Reset overflow flag
      TMR1H  = 0x80;                  // Reset counter
      TMR1L  = 0x00;

      if (start_mode == 0)
      {
         trans_mode=0;                // Switch off transmitter
         I_TRANS=0;
         T_ON = 0;

         I_START=1; delay250us(10);  I_START=0; delay250us(30); // Blink Start button (x3)
         I_START=1; delay250us(10);  I_START=0; delay250us(30);
         I_START=1; delay250us(10);  I_START=0; delay250us(30);
      }
      if (start_mode ==1)
      {
         I_START=1;
         tick_pos++;                 // Step up tick_pos one second (not needed )
         sec1++;                     // Step up one second
         update_clock ();            // Main clock updated every second   

         if (tick_pos == 60)
         {
            tick_pos = 0;
         }

         if (tick_pos == 0)
         {
            set_bitvalue();          // Set all 60 bits with initial valu
            first=0;
            if (display_mode == 3)
            {
                update_display_mode_3 ();  //Update bits
            }
         }
         output_bitvalue();          // Binary pulse on output
         }
      if (display_mode == 1 || display_mode == 2)
      {
         display_time ();
      }
      check_btn ();
   }
   FSR = sv_FSR;
   int_restore_registers          // W, STATUS (and PCLATH)
}


/* _______________________________ MAIN FUNCTION start ________________________ */

void main(void)
{
   ANSEL=0;                // Initialisation to enable PORTC as digital I/O
   ANSELH=0;

   CM1CON0 = 0 ;           // Behvös den??
   CM2CON0 = 0 ;           // Behvös den??

   TRISA = 0b0000.0000;    //  Port A are all outputs
   TRISC=  0b0000.0000;    //  Port C are all outputs
   TRISB = 0b0011.1111;    //  Port B are mainly inputs

   OPTION.7 = 0;
   WPUB.0 = 1;             //  Weak pullup Encoder.B input
   WPUB.1 = 1;             //  Weak pullup Encoder.A input
   WPUB.2 = 1;             //  Weak pullup SET input
   WPUB.3 = 1;             //  Weak pullup VIEW input
   WPUB.4 = 1;             //  Weak pullup TRANSMIT input
   WPUB.5 = 1;             //  Weak pullup START input

   IOCB.0  = 1;            //  Enable interrupt on Encoder.B
   IOCB.1  = 1;            //  Enable interrupt on Encoder.A
   IOCB.4  = 1;            //  Enable interrupt on TRANSMIT input

   I_START = 0;
   I_TRANS = 0;
   I_VIEW = 0;
   I_SET = 0;
   LED0 = 0;
   LED1 = 0;

   RBIE   = 1;             /* local enable  */

   get_eedata ();                 // Get the string of time data from EEPROM ...
   hour10  =stored_time[0];       // ... and store in variables
   hour1   =stored_time[1];
   min10   =stored_time[2];
   min1    =stored_time[3];
   dst     =stored_time[6];
   year10  =stored_time[7];
   year1   =stored_time[8];
   month10 =stored_time[9];
   month1  =stored_time[10];
   day10   =stored_time[11];
   day1    =stored_time[12];
   weekday =stored_time[13];

   sec1 = 9;                      // Sec = 59
   sec10 = 5;                     // Sec = 59

   tick_pos = 59;
   display_mode = 1;              // Show clock at start + bitvalue

   trans_mode = 0;                // Transmitter off
   set_mode = 0;
   first=0;

   lcd_init();                     // Initiate the LCD
   LCDLI=0;                        // No backlight to start with

   char i;

   lcd_command (POS_1_0);
   for(i=0; i<16; i++) lcd_putchar(text1(i));  // display start text 1
   delay10(100);

   lcd_command (POS_2_0);
   for(i=0; i<16; i++) lcd_putchar(text2(i));  // display start text 2
   delay10(100);
   lcd_command (CLEAR);          // Clear display  

   /* Definition of interrupt 1 Hz
   00.xx.x.x.x.x --
   xx.00.x.x.x.x Prescale 1/1
   xx.xx.1.x.x.x TMR1-oscillator is on
   xx.xx.x.0.x.x - (clock input synchronization)
   xx.xx.x.x.1.x Use external clock 32.768
   xx.xx.x.x.x.1 TIMER1 is ON
   */

   T1CON = 0b00.00.1.1.1.1 ;
   /* CCPR = CLOSC * Timer1Period = 32768*1 = 32768 */
   /* CCPR = 32768 = 0x8000 CCPR1H = 0x80, CCPR1L = 0x00 */

   //TMR1IE = 0;

   //TMR1H = 0x00;      //Short time to initial interrupt after Start
   //TMR1L = 0x11;
   /* Timer1Period is now 1 s */

//*********************************************************

   //lcd_command (0b0000.0000);                   // Clear display
                          //next interrupt should start at 00 
   start_mode = 0;

   PULSE = 1;
   LED0 = 0;
   LED1 = 0;

   TMR1H = 0xEE;  //Short time to initial interrupt after Start
   TMR1L = 0x00;
   TMR1IE = 1;                // Enable TMR1 interrupt
   GIE = 1;                   // Interrupts allowed
   PEIE = 1;
   //display_time ();


/*
   while (1)                             // Infinite loop, wait for button press 
   {
      while( START == 0) ;                // Button pressed
      {
         start_mode = ! start_VIEW;         // Start/stop signal
         delay10 (1);   

         if (display_mode == 1 || display_mode == 2)
         {
            //lcd_command (CLEAR);          // Clear display
         }
      }
      while( START == 1 ) ;               // Button up
      {
         delay10 (1);
         //lcd_command (CLEAR);          // Clear display   
      
      }    
      

                
   }

*/
   while (1)
   {



   if (START==0)
      {
         if (START_pressed==0)
         {
            start_mode = ! start_mode;         // Start/stop signal
            delay10 (1);
            if (display_mode == 1 || display_mode == 2)
            {
               lcd_command (POS_1_0);
               for(i=0; i<20; i++) lcd_putchar(text5(i));  // display start text 1

               lcd_command (POS_2_18);          // move cursor to "line 2, position 18
               lcd_putchar('=');
            }
            START_pressed=1;
            //if (start_mode == 1)
            //{
            //   TMR1IE = 1;                // Enable TMR1 interrupt
            //}
            //else
            //{
            //   TMR1IE = 0;                // Enable TMR1 interrupt
            //}
         }
         if (START==1)
         {
            delay10 (1);
            START_pressed=0;
         }

      }

/*
    if (SET == 0)               // Button pressed
      {
         if (SET_pressed==0)
         {
            set_mode =  1;         // Step up display VIEW
            delay10 (1);   
            lcd_command(0b0000.1100);  /* display on, cursor off, blink off */
            lcd_command (CLEAR);          // Clear display'
            SET_pressed=1;
            if (set_VIEW==1)
            {
               set_clock ();
            }
         }

      //set_clock ();                   // Funkar inte

         if (SET==1)
         {
            delay10 (1);
            SET_pressed=0;
         }

      }

*/
   }


   //}
      //if (VIEW==down)
      //{

}


/* ________________________ TRANSMITTER OUTPUT FUNCTION start ________________________ */

void output_bitvalue(void)
{
   char i;
   bit_val = bit_value[tick_pos];

   if (display_mode == 1 || display_mode == 2)
   {
      tick_pos_1 = tick_pos%10;         // Get the single digit for display
      tick_pos_10 = tick_pos/10;        // Get the single digit for display
      lcd_command (0b1001.0010);                     // reposition to "line 2, position 18
      lcd_putchar(48+tick_pos_10);
      lcd_putchar(48+tick_pos_1);
   }

   if (display_mode == 3)
   {
      update_display_mode_3 ();
   }

   if (display_mode == 4)                 // Endast markering tillsivdare
   {
      update_display_mode_4 ();
   }

   if (bit_val == 0)
      {
      if (display_mode == 1 || display_mode == 2)
         {
         lcd_command (0b1101.0011);                     // reposition to "line 1, position 19
         lcd_putchar('0');
         }

      LED0 = 1;
      if (trans_mode==1)
      {
         I_TRANS = 0;
      }
      PULSE = 0;
      delay10(10);

      LED0 = 0;
      if (trans_mode==1)
      {
         I_TRANS = 1;
      }
      PULSE = 1;
      }


   if (bit_val == 1)
   {
      if (display_mode == 1 || display_mode == 2)
      {

         lcd_command (0b1101.0011);                     // reposition to "line 1, position 19
      //lcd_command (0b1000.0000);                     // reposition to "line 1, position 0

         //RS = 1;  // LCD in character-VIEW
         lcd_putchar('1');
         }

      LED1 = 1;
       if (trans_mode==1)
      {
         I_TRANS = 0;
      }
      PULSE = 0;
      delay10(20);

      LED1 = 0;
      if (trans_mode==1)
      {
         I_TRANS = 1;
      }
      PULSE = 1;
      }



   if (bit_val == 9)    //last second before new minute, no pulse
      {

      if (display_mode == 1 || display_mode == 2)
         {
         //RS = 0;  // LCD in command-VIEW
         //lcd_putchar( 0b00000010 ); //Cursor hoME
         //RS = 1;  // LCD in character-VIEW
         lcd_command (0b1101.0011);                     // reposition to "line 1, position 19
         lcd_putchar('-');
         }
      //PULSE2 = 0;
      }



}



void check_btn (void)
{
char i;
   if (VIEW == 0)               // Button pressed
   {
      I_VIEW=1; delay250us(30);  I_VIEW=0;  // Blink Start button

      display_mode =  display_mode+1;         // Step up display VIEW

      //lcd_command (CLEAR);          // Clear display
      first=0;

      if (display_mode==5)
      {
         display_mode = 1;
      }
      if (display_mode == 1 || display_mode == 2)
      {
         lcd_command (POS_1_0);
         for(i=0; i<20; i++) lcd_putchar(text5(i));  // display start text 1

         lcd_command (POS_2_0);
         for(i=0; i<20; i++) lcd_putchar(text6(i));  // display start text 1

         lcd_command (POS_2_18);          // move cursor to "line 2, position 18
         lcd_putchar('=');

         lcd_command(0b0000.1100);  /* display on, cursor off, blink off */
         //lcd_command (CLEAR);          // Clear display'  
         LCDLI=0;

      }
      if (display_mode == 2 || display_mode == 3 || display_mode == 4)
      {
         LCDLI=1;

      }
      if (display_mode==4)
      {
         //LCDLI=1;
         lcd_command(0b0000.1100);  /* display on, cursor off, blink off */
         lcd_command (CLEAR);          // Clear display'

      }
   }
   if (SET == 0)               // Button pressed
   {
      if (start_mode == 0)
       {
         set_mode =  1;         // Step up display VIEW
         lcd_command(0b0000.1100);  /* display on, cursor off, blink off */
         lcd_command (CLEAR);          // Clear display'
         //set_clock ();                   // Funkar inte

         if (set_mode==1)
         {
            set_clock ();
         }
      }
   }



   if (TRANS == 0)               // Button pressed
   {
      if (start_mode == 1)         // Transmit button active only during run
      {
         I_TRANS=1; delay250us(30);  I_TRANS=0;  // Blink Start button
         trans_mode = ! trans_mode;         // Start/stop signal
         delay10 (1);
         if (trans_mode == 1)
         {
            I_TRANS=1;
            T_ON = 1;
         }
         if (trans_mode == 0)
         {
            I_TRANS=0;
           T_ON = 0;
         }

}
    }


/*
    if (SET == 0)               // Button pressed
    {
         if (SET_pressed==0)
         {
            set_mode =  1;         // Step up display VIEW
            delay10 (1);   
            lcd_command(0b0000.1100);  /* display on, cursor off, blink off */
            lcd_command (CLEAR);          // Clear display'
            SET_pressed=1;
            if (set_VIEW==1)
            {
               set_clock ();
            }
         }

      //set_clock ();                   // Funkar inte

       if (SET==1)
       {
          delay10 (1);
          SET_pressed=0;
       }

    }
*/



}




void blink_empty (char digits)     // Erases a number of LCD characters
{
   char i;
   for (i=0; i<digits; i++)
   {
      lcd_putchar(' ');
   }
   delay10 (30);                    // Wait 500 ms
}


void blink_digits (char dig1, char dig2)    // Erases a number of LCD characters
{
   lcd_putchar(48+dig1);            // 48 = 0011.0000
   lcd_putchar(48+dig2);
   delay10(20);
}



/* ________________________ DCF77 CLOCK start ________________________ */

void update_clock (void)       // Updates the clock data with one second
{
   if (sec1>9)
   {
      sec1 = 0;
      sec10++;
   }
      if (sec10 > 5)
   {
      sec10 = 0;
      min1++;
   }
   update_minutes ();
}


void update_minutes (void)      // Clock over minute > hour > day > month > year
{
   if(min1>9)
   {
      min1 = 0;
      min10++;
   }
   if(min10>5)
   {
      min10 = 0;
      hour1++;
   }
   if(hour1>9)
   {
      hour1 = 0;
      hour10++;
   }
   if(hour10 >2){
      hour10 = 0;
   }
   if(hour10 >=2 && hour1>3)
   {
      hour1 = 0;
      hour10 = 0;
      day1++;
   }
   if(day1>9){
      day1 = 0;
      day10++;
   }
   if(day10 >=2 && day1>1)
   {
      day1 = 1;
      day10 = 0;
      month1++;
   }
   if(month1>9)
   {
      month1 = 0;
      month10++;
   }
   if(month10 >=1 && month1>2)
   {
      month1 = 1;
      month10 = 0;
      year1++;
   }
   if(year1>9)
   {
      year1 = 0;
      year10++;
   }
}


void display_time ( void )
{

   lcd_command (POS_3_0);                  // reposition to line 1

   lcd_putint(hour10);
   lcd_putint(hour1);
   lcd_putchar(':');
   lcd_putint(min10);
   lcd_putint(min1);
   lcd_putchar(':');
   lcd_putint(sec10);
   lcd_putint(sec1);
   lcd_putchar(' ');
   lcd_putchar(' ');
   lcd_putchar(' ');
   lcd_putchar('D');
   lcd_putchar('S');
   lcd_putchar('T');
   lcd_putchar('=');
   lcd_putint(dst);


   lcd_command (POS_4_0);                  // reposition to line 1
   lcd_putchar('2');
   lcd_putchar('0');
   lcd_putint(year10);            // 48 = 0011.0000
   lcd_putint(year1);
   lcd_putchar('-');
   lcd_putint(month10);
   lcd_putint(month1);
   lcd_putchar('-');
   lcd_putint(day10);
   lcd_putint(day1);
   lcd_putchar(' ');

   if (weekday == 1)
   {
      lcd_putchar('M');
      lcd_putchar('o');
      lcd_putchar('n');
      lcd_putchar('d');
      lcd_putchar('a');
      lcd_putchar('y');
      lcd_putchar(' ');
   }

   if (weekday == 2)
   {
      lcd_putchar('T');
      lcd_putchar('u');
      lcd_putchar('e');
      lcd_putchar('s');
      lcd_putchar('d');
      lcd_putchar('a');
      lcd_putchar('y');
      lcd_putchar(' ');
      lcd_putchar(' ');
   }
   if (weekday == 3)
   {
      lcd_putchar('W');
      lcd_putchar('e');
      lcd_putchar('d');
      lcd_putchar('n');
      lcd_putchar('e');
      lcd_putchar('s');
      lcd_putchar('d');
      lcd_putchar('a');
      lcd_putchar('y');
   }
   if (weekday == 4)
   {
      lcd_putchar('T');
      lcd_putchar('h');
      lcd_putchar('u');
      lcd_putchar('r');
      lcd_putchar('s');
      lcd_putchar('d');
      lcd_putchar('a');
      lcd_putchar('y');
      lcd_putchar(' ');


   }
   if (weekday == 5)
   {
      lcd_putchar('F');
      lcd_putchar('r');
      lcd_putchar('i');
      lcd_putchar('d');
      lcd_putchar('a');
      lcd_putchar('y');
      lcd_putchar(' ');
      lcd_putchar(' ');
   }
   if (weekday == 6)
   {
      lcd_putchar('S');
      lcd_putchar('a');
      lcd_putchar('t');
      lcd_putchar('u');
      lcd_putchar('r');
      lcd_putchar('d');
      lcd_putchar('a');
      lcd_putchar('y');
   }

   if (weekday == 7)
   {
      lcd_putchar('S');
      lcd_putchar('u');
      lcd_putchar('n');
      lcd_putchar('d');
      lcd_putchar('a');
      lcd_putchar('y');
      lcd_putchar(' ');
      lcd_putchar(' ');
   }
}




/* ________________________ SET TRANSMIT BIT VALUES________________________ */

void set_bitvalue (void)            // Set new bitvalues before a new minute
   {
   char i;
   min1 = min1 + 1;                 // Time to transmit = next minute                                   
   update_clock ();

   bit_value[0] = 0;
   bit_value[1] = 0;
   bit_value[2] = 1;
   bit_value[3] = 0;
   bit_value[4] = 0;
   bit_value[5] = 0;
   bit_value[6] = 0;
   bit_value[7] = 0;
   bit_value[8] = 0;
   bit_value[9] = 0;
   bit_value[10] = 0;
   bit_value[11] = 0;
   bit_value[12] = 0;
   bit_value[13] = 0;
   bit_value[14] = 0;
   bit_value[15] = 0;               // 0 = primary antenna in use
   bit_value[16] = 0;               // 0 = No DST change in the next hour
   bit_value[17] = dst;             //  DST on/off
   bit_value[18] = !dst;            // Timezone, usually opposite of bit 17
   bit_value[19] = 0;               // 0 = No leap second insertion
   bit_value[20] = 1;               // Always 1
   bit_value[21] = min1.0;          // Minutes, BCD least significant first
   bit_value[22] = min1.1;
   bit_value[23] = min1.2;
   bit_value[24] = min1.3;
   bit_value[25] = min10.0;
   bit_value[26] = min10.1;
   bit_value[27] = min10.2;

   no_of_ones = 0;
   for (i=21; i<28; i++)
      {
      no_of_ones = no_of_ones+bit_value[i];
      }
   bit_value[28] = no_of_ones%2;    // Even parity bit, minute bits
   bit_value[29] = hour1.0;         // Hours, BCD least significant first
   bit_value[30] = hour1.1;
   bit_value[31] = hour1.2;
   bit_value[32] = hour1.3;
   bit_value[33] = hour10.0;
   bit_value[34] = hour10.1;

   no_of_ones = 0;
   for (i=29; i<35; i++)            // Calculate number of "ones"
      {
      no_of_ones = no_of_ones + bit_value[i];
      }
   bit_value[35] = no_of_ones%2;    // Even parity bit, hour bits
   bit_value[36] = day1.0;          // Day of month, BCD least significant first
   bit_value[37] = day1.1;
   bit_value[38] = day1.2;
   bit_value[39] = day1.3;
   bit_value[40] = day10.0;
   bit_value[41] = day10.1;
   bit_value[42] = weekday.0;       // Day of week, BCD least significant first, Mon=1
   bit_value[43] = weekday.1;
   bit_value[44] = weekday.2;
   bit_value[45] = month1.0;        // Month, BCD least significant first
   bit_value[46] = month1.1;
   bit_value[47] = month1.2;
   bit_value[48] = month1.3;
   bit_value[49] = month10.0;
   bit_value[50] = year1.0;         // Year, BCD least significant first
   bit_value[51] = year1.1;
   bit_value[52] = year1.2;
   bit_value[53] = year1.3;
   bit_value[54] = year10.0;
   bit_value[55] = year10.1;
   bit_value[56] = year10.2;
   bit_value[57] = year10.3;

   no_of_ones = 0;
   for (i=36; i<58; i++)            // Calculate number of "ones"
      {
      no_of_ones = no_of_ones + bit_value[i];
      }
   bit_value[58] = no_of_ones%2;    // Even parity bit, all transmitted bits
   bit_value[59] = 9;               // No transmission

   min1 = min1-1;                   // Reset to real time                           
   if(min1<0)                       // For case "00.00"
   {
      min1 = 9;
      min10--;
   }
   if(min10 < 0)
   {
      min10 = 5;
      hour1--;
   }
   if(hour1 < 0)
   {
      hour1 = 3;
      hour10--;
   }
   if(hour10<0){
      hour10 = 2;
   }
   // MORE FUNCTIONS required to correct day, month, year
   if (display_mode ==3)            // Update bit overview display
   {
      update_display_mode_3 ();
   }

}


void put_eedata( void )
{
/* Put global s[] -string in EEPROM-data */
char i, c;
for(i = 0;  i <14; i++)
    {
      c = stored_time[i];
      /* Write EEPROM-data sequence                          */
      EEADR = i;          /* EEPROM-data adress 0x00 => 0x7F */
      EEDATA = c;         /* data to be written              */
      WREN = 1;           /* write enable                    */
      EECON2 = 0x55;      /* first Byte in comandsequence    */
      EECON2 = 0xAA;      /* second Byte in comandsequence   */
      WR = 1;             /* write                           */
      while( EEIF == 0) ; /* wait for done (EEIF=1)          */
      WREN = 0;           /* write disable - safety first    */
      EEIF = 0;           /* Reset EEIF bit in software      */
      /* End of write EEPROM-data sequence                   */
      //if(stored_time == '\0') break;  
    }
}



void get_eedata( void )
{
/* Get EEPROM-data and put it in global s[] */
char i;
for(i = 0;  i <14; i++)
    {
      /* Start of read EEPROM-data sequence                */
      EEADR = i;       /* EEPROM-data adress 0x00 => 0x7F  */
      RD = 1;          /* Read                             */
      stored_time[i] = EEDATA;   /* data to be read                  */
      /* End of read EEPROM-data sequence                  */
      //if( s[i] == '\0') break;
    }
}





/* ________________________ LCD TEXT STORAGE________________________ */

char text1( char x)                         // this is the way to store a sentence
{
   skip(x);                                 /* internal function CC5x.  */
   #pragma return[] = "DCF77 Simulator "    // 16-teckens rad
}

char text2( char x)                          // this is the way to store a sentence
{
   skip(x);                                 /* internal function CC5x.  */
   #pragma return[] = "Set clock, start"    // 8 chars max!
}

char text3( char x)                          // this is the way to store a sentence
{
   skip(x);                                 /* internal function CC5x.  */
   #pragma return[] = "Set a fake time "    // 8 chars max!
}

char text4( char x)                          // this is the way to store a sentence
{
   skip(x);                                 /* internal function CC5x.  */
   #pragma return[] = "Time is set. START  "    // 8 chars max!
}
char text5( char x)                          // this is the way to store a sentence
{
   skip(x);                                 /* internal function CC5x.  */
   #pragma return[] = "Transmitting bit:   "    // 8 chars max!
}

char text6( char x)                          // this is the way to store a sentence
{
   skip(x);                                 /* internal function CC5x.  */
   #pragma return[] = "                    "    // 20 empty characters (erase)
}
char text7( char x)                          // this is the way to store a sentence
{
   skip(x);                                 /* internal function CC5x.  */
   #pragma return[] = "bit"    // 20 empty characters (erase)
}




/* ________________________ LCD INITIALIZE________________________ */

void lcd_init( void ) // must be run once before using the display
{
   delay(40);                 // give LCD time to settle
   RS = 0;                    // LCD in command-VIEW
   lcd_putchar(0b0011.0011);  /* LCD starts in 8 bit VIEW          */
   lcd_putchar(0b0011.0010);  /* change to 4 bit VIEW              */
   lcd_putchar(0b0010.1000);  /* two line (8+8 chars in the row)   */
   lcd_putchar(0b0000.1100);  /* display on, cursor off, blink off */
   lcd_putchar(0b0000.0001);  /* display clear                     */
   lcd_putchar(0b0000.0110);  /* ROTArement VIEW, shift off         */
   RS = 1;                     // LCD in character-VIEW
}


/* ________________________ LCD PUT CHARACTER________________________ */


void lcd_putchar( char data )
{
   // Must set LCD-VIEW before calling this function
   // RS = 1 LCD in character-VIEW
   // RS = 0 LCD in command-VIEW

   D7 = data.7;         // upper Nibble
   D6 = data.6;
   D5 = data.5;
   D4 = data.4;
   EN = 0; nop(); nop(); EN = 1; delay(1);

   D7 = data.3;         // lower Nibble
   D6 = data.2;
   D5 = data.1;
   D4 = data.0;
   EN = 0; nop(); nop(); EN = 1; delay(2);
}



void lcd_command ( char cmd )       // Write command to LCD
{
   RS = 0;
   lcd_putchar( cmd );
   RS = 1;                          // Back to character VIEW
   delay(2);
}

void lcd_string ( char * s )       // Write command to LCD
{
   RS = 1;
   while (*s) lcd_putchar(*s++);
   delay(2);
}

void lcd_putint( char value )
{
  lcd_putchar(value+48);
}





/* ____ DELAY CAUSING PROBLEMS SOMETIMES ____ */


void delay ( char millisec)
/*
  Delays a multiple of 1 milliseconds at 4 MHz
  using the TMR0 timer 
*/


{
   OPTION = 2;  /* prescaler divide by 8        */
   do  {
       TMR0 = 0;
       while ( TMR0 < 125)   /* 125 * 8 = 1000  */
            ;
   } while ( -- millisec > 0);
}




void delay250us ( char millisec)
{
   char m;
   char k;
   for (m=0; m<millisec; m++)
   {
         for (k=0; k<250; k++)
         {
         nop();
         nop();
         }
   }
}



void delay10 ( char n)
/*
  Delays a multiple of 10 milliseconds using the TMR0 timer
  Clock : 4 MHz   => period T = 0.25 microseconds
  1 IS = 1 Instruction Cycle = 1 microsecond
  error: 0.16 percent
*/
{
    char i;

    OPTION = 7;
    do  {
        i = TMR0 + 39; /* 256 microsec * 39 = 10 ms */
        while ( i != TMR0)
            ;
    } while ( --n > 0);
}


#pragma codepage 1

void display_3_pos (void)
{

   c_pos[0]  = POS_1_5;
   c_pos[1]  = POS_1_6;
   c_pos[2]  = POS_1_7;
   c_pos[3]  = POS_1_8;
   c_pos[4]  = POS_1_9;
   c_pos[5]  = POS_1_10;
   c_pos[6]  = POS_1_11;
   c_pos[7]  = POS_1_12;
   c_pos[8]  = POS_1_13;
   c_pos[9]  = POS_1_14;
   c_pos[10] = POS_1_15;
   c_pos[11] = POS_1_16;
   c_pos[12] = POS_1_17;
   c_pos[13] = POS_1_18;
   c_pos[14] = POS_1_19;

   c_pos[15] = POS_2_5;
   c_pos[16] = POS_2_6;
   c_pos[17] = POS_2_7;
   c_pos[18] = POS_2_8;
   c_pos[19] = POS_2_9;
   c_pos[20] = POS_2_10;
   c_pos[21] = POS_2_11;
   c_pos[22] = POS_2_12;
   c_pos[23] = POS_2_13;
   c_pos[24] = POS_2_14;
   c_pos[25] = POS_2_15;
   c_pos[26] = POS_2_16;
   c_pos[27] = POS_2_17;
   c_pos[28] = POS_2_18;
   c_pos[29] = POS_2_19;

   c_pos[30] = POS_3_5;
   c_pos[31] = POS_3_6;
   c_pos[32] = POS_3_7;
   c_pos[33] = POS_3_8;
   c_pos[34] = POS_3_9;
   c_pos[35] = POS_3_10;
   c_pos[36] = POS_3_11;
   c_pos[37] = POS_3_12;
   c_pos[38] = POS_3_13;
   c_pos[39] = POS_3_14;
   c_pos[40] = POS_3_15;
   c_pos[41] = POS_3_16;
   c_pos[42] = POS_3_17;
   c_pos[43] = POS_3_18;
   c_pos[44] = POS_3_19;

   c_pos[45] = POS_4_5;
   c_pos[46] = POS_4_6;
   c_pos[47] = POS_4_7;
   c_pos[48] = POS_4_8;
   c_pos[49] = POS_4_9;
   c_pos[50] = POS_4_10;
   c_pos[51] = POS_4_11;
   c_pos[52] = POS_4_12;
   c_pos[53] = POS_4_13;
   c_pos[54] = POS_4_14;
   c_pos[55] = POS_4_15;
   c_pos[56] = POS_4_16;
   c_pos[57] = POS_4_17;
   c_pos[58] = POS_4_18;
   c_pos[59] = POS_4_19;

}


void display_4_pos (void)
{
   c_pos[0]  = POS_2_0;
   c_pos[1]  = POS_2_1;
   c_pos[2]  = POS_2_2;
   c_pos[3]  = POS_2_3;
   c_pos[4]  = POS_2_4;
   c_pos[5]  = POS_2_5;
   c_pos[6]  = POS_2_6;
   c_pos[7]  = POS_2_7;
   c_pos[8]  = POS_2_8;
   c_pos[9]  = POS_2_9;
   c_pos[10] = POS_2_10;
   c_pos[11] = POS_2_11;
   c_pos[12] = POS_2_12;
   c_pos[13] = POS_2_13;
   c_pos[14] = POS_2_14;

   c_pos[15] = POS_1_1;
   c_pos[16] = POS_2_0;
   c_pos[17] = POS_2_1;
   c_pos[18] = POS_2_2;
   c_pos[19] = POS_2_3;
   c_pos[20] = POS_1_1;
   c_pos[21] = POS_2_0;
   c_pos[22] = POS_2_1;
   c_pos[23] = POS_2_2;
   c_pos[24] = POS_2_3;
   c_pos[25] = POS_2_4;
   c_pos[26] = POS_2_5;
   c_pos[27] = POS_2_6;
   c_pos[28] = POS_3_1;
   c_pos[29] = POS_2_0;

   c_pos[30] = POS_2_1;
   c_pos[31] = POS_2_2;
   c_pos[32] = POS_2_3;
   c_pos[33] = POS_2_4;
   c_pos[34] = POS_2_5;
   c_pos[35] = POS_3_1;
   c_pos[36] = POS_2_0;
   c_pos[37] = POS_2_1;
   c_pos[38] = POS_2_2;
   c_pos[39] = POS_2_3;
   c_pos[40] = POS_2_4;
   c_pos[41] = POS_2_5;
   c_pos[42] = POS_2_0;
   c_pos[43] = POS_2_1;
   c_pos[44] = POS_2_2;

   c_pos[45] = POS_2_0;
   c_pos[46] = POS_2_1;
   c_pos[47] = POS_2_2;
   c_pos[48] = POS_2_3;
   c_pos[49] = POS_2_4;
   c_pos[50] = POS_2_0;
   c_pos[51] = POS_2_1;
   c_pos[52] = POS_2_2;
   c_pos[53] = POS_2_3;
   c_pos[54] = POS_2_4;
   c_pos[55] = POS_2_5;
   c_pos[56] = POS_2_6;
   c_pos[57] = POS_2_7;
   c_pos[58] = POS_2_0;
   c_pos[59] = POS_2_0;

}


void update_display_mode_3 (void)
{
   display_3_pos ();                      // load the cursor position for display 2
   lcd_command (c_pos[tick_pos]);        // move cursor to current bit position  
   if(first==0)
   {
      lcd_command (0b0000.1110);             // Cursor on, blink off
      lcd_command (0b0000.0110);             // ROTArement, not shifted

      lcd_command (POS_1_0);                  // reposition to line 1
      lcd_putchar('0');
      lcd_putchar('0');
      lcd_putchar('-');
      lcd_putchar(':');
      lcd_putchar(' ');
      char i;
      for(i=0; i<15; i++)                   // display binary values 1-14
      {
         lcd_putint(bit_value[i]);
      }
      lcd_command (POS_2_0);
      lcd_putchar('1');
      lcd_putchar('5');
      lcd_putchar('-');
      lcd_putchar(':');
      lcd_putchar(' ');
      for(i=15; i<30; i++)                   // display binary values 15-29
      {
         lcd_putint(bit_value[i]);
      }
      lcd_command (POS_3_0);
      lcd_putchar('3');
      lcd_putchar('0');
      lcd_putchar('-');
      lcd_putchar(':');
      lcd_putchar(' ');
      for(i=30; i<45; i++)                   // display binary values 30-44
      {
         lcd_putint(bit_value[i]);
      }
      lcd_command (POS_4_0);
      lcd_putchar('4');
      lcd_putchar('5');
      lcd_putchar('-');
      lcd_putchar(':');
      lcd_putchar(' ');
      for(i=45; i<59; i++)                   // display binary values 45-58
      {
         lcd_putint(bit_value[i]);
      }
      lcd_putchar('-');                      // bit 59 always no signal         
      first=1;
   }
}




void update_display_mode_4 (void)
{
   display_4_pos ();                      // Update cursor positions for this display
   char i;
   lcd_command (0b0000.1110);             // Cursor on, blink off
   lcd_command (0b0000.0110);             // ROTArement, not shifted
   lcd_command (POS_1_11);
   lcd_putchar('b');
   lcd_putchar('i');
   lcd_putchar('t');

   if(tick_pos > 0 && tick_pos < 15)
   {

      lcd_command (POS_3_0);
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');

      lcd_command (POS_1_0);
      lcd_putchar('W');
      lcd_putchar('e');
      lcd_putchar('a');
      lcd_putchar('t');
      lcd_putchar('h');
      lcd_putchar('e');
      lcd_putchar('r');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');

      lcd_command (POS_1_14);
      lcd_putchar(' ');
      lcd_putchar('0');
      lcd_putchar('1');
      lcd_putchar('-');
      lcd_putchar('1');
      lcd_putchar('4');

      lcd_command (POS_2_0);

      for(i=0; i<15; i++)
      {
         lcd_putint(bit_value[i]);
      }
   }

   if (tick_pos > 15 && tick_pos < 20)
   {
      lcd_command (POS_1_0);
      lcd_putchar('D');
      lcd_putchar('S');
      lcd_putchar('T');
      lcd_putchar('+');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');

      lcd_command (POS_1_15);
      lcd_putchar('1');
      lcd_putchar('6');
      lcd_putchar('-');
      lcd_putchar('1');
      lcd_putchar('9');

      lcd_command (POS_2_0);
      for(i=16; i<20; i++)
      {
         lcd_putint(bit_value[i]);
      }

      for(i=0; i<11; i++)
      {
         lcd_putchar(' ');
      }
   }


   if (tick_pos == 21)
   {
      lcd_command (POS_1_0);
      lcd_putchar('M');
      lcd_putchar('i');
      lcd_putchar('n');
      lcd_putchar('u');
      lcd_putchar('t');
      lcd_putchar('e');

      lcd_command (POS_1_15);
      lcd_putchar('2');
      lcd_putchar('1');
      lcd_putchar('-');
      lcd_putchar('2');
      lcd_putchar('7');

      lcd_command (POS_2_0);
      for(i=21; i<28; i++)
      {
         lcd_putint(bit_value[i]);
      }
      lcd_command (POS_2_8);
      lcd_putchar('=');
      lcd_putchar(' ');
      lcd_putint(min10);
      lcd_putint(min1);
      lcd_putchar(' ');

   }

   if(tick_pos == 29)
   {
      lcd_command (POS_1_0);
      lcd_putchar('H');
      lcd_putchar('o');
      lcd_putchar('u');
      lcd_putchar('r');
      lcd_putchar(' ');
      lcd_putchar(' ');

      lcd_command (POS_1_15);
      lcd_putchar('2');
      lcd_putchar('9');
      lcd_putchar('-');
      lcd_putchar('3');
      lcd_putchar('4');

      lcd_command (POS_2_0);
      for(i=29; i<35; i++)
      {
         lcd_putint(bit_value[i]);
      }
      lcd_putchar(' ');

      lcd_command (POS_2_7);
      lcd_putchar('=');
      lcd_putchar(' ');
      lcd_putint(hour10);
      lcd_putint(hour1);
      lcd_putchar(' ');
   }

   if(tick_pos == 36)
   {

      lcd_command (POS_1_0);
      lcd_putchar('D');
      lcd_putchar('a');
      lcd_putchar('y');
      lcd_putchar(' ');


      lcd_command (POS_1_15);
      lcd_putchar('3');
      lcd_putchar('6');
      lcd_putchar('-');
      lcd_putchar('4');
      lcd_putchar('1');

      lcd_command (POS_2_0);

      for(i=36; i<42; i++)
      {
         lcd_putint(bit_value[i]);
      }
      lcd_putchar(' ');
      lcd_command (POS_2_7);
      lcd_putchar('=');
      lcd_putchar(' ');
      lcd_putint(day10);
      lcd_putint(day1);
   }
   if(tick_pos == 42)
   {
      lcd_command (POS_1_0);
      lcd_putchar('W');
      lcd_putchar('e');
      lcd_putchar('e');
      lcd_putchar('k');
      lcd_putchar('d');
      lcd_putchar('a');
      lcd_putchar('y');


      lcd_command (POS_1_15);
      lcd_putchar('4');
      lcd_putchar('2');
      lcd_putchar('-');
      lcd_putchar('4');
      lcd_putchar('4');

      lcd_command (POS_2_0);
      lcd_putint(bit_value[42]);
      lcd_putint(bit_value[43]);
      lcd_putint(bit_value[44]);
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');


      lcd_command (POS_2_4);
      lcd_putchar('=');
      lcd_putchar(' ');
      lcd_putchar('D');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');
   }

   if(tick_pos ==45)
   {

      lcd_command (POS_1_0);
      lcd_putchar('M');
      lcd_putchar('o');
      lcd_putchar('n');
      lcd_putchar('t');
      lcd_putchar('h');
      lcd_putchar(' ');
      lcd_putchar(' ');


      lcd_command (POS_1_15);
      lcd_putchar('4');
      lcd_putchar('5');
      lcd_putchar('-');
      lcd_putchar('4');
      lcd_putchar('9');

      lcd_command (POS_2_0);
      for(i=45; i<50; i++)
      {
         lcd_putint(bit_value[i]);
      }

      lcd_command (POS_2_6);
      lcd_putchar('=');
      lcd_putchar(' ');
      lcd_putint(month10);
      lcd_putint(month1);

   }
   if(tick_pos == 50)
   {
      lcd_command (POS_1_0);
      lcd_putchar('Y');
      lcd_putchar('e');
      lcd_putchar('a');
      lcd_putchar('r');
      lcd_putchar(' ');

      lcd_command (POS_1_15);
      lcd_putchar('5');
      lcd_putchar('0');
      lcd_putchar('-');
      lcd_putchar('5');
      lcd_putchar('7');

      lcd_command (POS_2_0);
      for(i=50; i<58; i++)
      {
         lcd_putint(bit_value[i]);
      }

      lcd_command (POS_2_9);
      lcd_putchar('=');
      lcd_putchar(' ');
      lcd_putchar('(');
      lcd_putchar('2');
      lcd_putchar('0');
      lcd_putchar(')');
      lcd_putint(year10);
      lcd_putint(year1);
   }

   if(tick_pos > 58 || tick_pos < 01)
   {

      lcd_command (POS_1_0);
      lcd_putchar('M');
      lcd_putchar('i');
      lcd_putchar('n');
      lcd_putchar('u');
      lcd_putchar('t');
      lcd_putchar('e');
      lcd_putchar('M');
      lcd_putchar('a');
      lcd_putchar('r');
      lcd_putchar('k');

      lcd_command (POS_1_15);
      lcd_putchar(' ');
      lcd_putchar('5');
      lcd_putchar('9');

      lcd_command (POS_2_0);
      lcd_putchar('[');
      lcd_putchar('N');
      lcd_putchar('o');
      lcd_putchar(' ');
      lcd_putchar('p');
      lcd_putchar('u');
      lcd_putchar('l');
      lcd_putchar('s');
      lcd_putchar('e');
      lcd_putchar(']');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');
      lcd_putchar(' ');
   }
   lcd_command (c_pos[tick_pos]);        // move cursor to current bit position
}

#pragma codepage 2

/* ________________________ SET CLOCK start ________________________ */


void set_clock (void)
{
   I_SET=1;          // SET button indicator on
   I_START=0;        // START button off
   I_TRANS=0;        // TRANS button indicator on
   LED0 = 0;
   LED1 = 0;

   T_ON = 0;         // Switch off transmitter
   trans_mode=0;

   transit = 0;
   up = 0;
   down = 0;
   start_mode = 0;

   TMR1IE = 0;                // Disable TMR1 interrupt
   T1CON.0 = 0 ;    // Stop the oscillator
   TMR1IF = 0;

   RBIE   = 1;   /* local enable  */
   GIE     = 1;   /* global enable */

   char i;
   lcd_command (0b00000010);              // Cursor home
   lcd_command (0b0000.1110);             // Cursor on, blink off

   for(i=0; i<16; i++) lcd_putchar(text3(i));  // display start text 1

   display_time();
   delay10(9);

   lcd_command (POS_3_0);           // Reposition to hours position
   blink_empty (2) ;                // Blink hours

   while (set_mode ==1)
   {
      if (up ==1)
      {
         up = 0;
         blink_one ();
         hour1++;
         if(hour1>9)
         {
            hour1 = 0;
            hour10++;
         }
         if(hour10 >= 2 && hour1 > 3)
         {
           hour1=0;
           hour10=0;
         }

      }
      if (down ==1)
      {
         down = 0;
         blink_null ();
         hour1--;

         if(hour1<0)
         {
            hour1 = 9;
            hour10--;
         }

         if(hour10<0)
         {
            hour10 = 2;
            hour1 = 3;
         }

      }
      lcd_command (POS_3_0);                  // reposition to hour position ...   
      lcd_putint(hour10);                     // ... and display hours
      lcd_putint(hour1);

      if (SET == 0)                           // If SET-button is pressed
      {
         set_mode = 2;                        // Move to minutes VIEW
         lcd_command (POS_3_3);               // Reposition to minutes position
         blink_empty (2);                     // Blink minutes
      }
   }
   while (set_mode ==2)
   {
      if (up ==1)
      {
         up = 0;
         blink_one ();
         min1++;

         if(min1>9)  {
            min1=0;
            min10++; }

         if(min10>5) {
            min10=0; }
      }

      if (down ==1)
      {
         down = 0;
         blink_null ();
         min1--;

         if(min1<0)  {
            min1=9;
            min10--; }

         if(min10<0) {
            min10=5; }
      }

      lcd_command (POS_3_3);                  // reposition to line 1    
      lcd_putint(min10);
      lcd_putint(min1);


      if (SET == 0)
      {
         set_mode = 3;                        // Move to seconds VIEW
         lcd_command (POS_3_6);           // Goto seconds position
         blink_empty (2) ;                    // Blink seconds
      }
   }

   while (set_mode ==3)
   {
      if (up ==1)
      {
         up = 0;
         blink_one ();
         sec1++;
         if(sec1>9)
         {
            sec1 = 0;
            sec10++;
         }
         if(sec10>5)
         {
            sec10=0;
         }
      tick_pos = sec10*10 + sec1;
      }

      if (down ==1)
      {
         down = 0;
         blink_null ();
         sec1--;

         if(sec1<0)  {
            sec1=9;
            sec10--; }

         if(sec10<0) {
            sec10=5; }
      }
      tick_pos = sec10*10 + sec1;
      lcd_command (POS_3_6);                  // reposition to line 1    
      lcd_putint(sec10);
      lcd_putint(sec1);

      if (SET == 0)
      {
         set_mode = 4;                        // Move to seconds VIEW
         lcd_command (POS_3_15);           // Goto seconds position
         blink_empty (1) ;                    // Blink seconds
      }
   }
   while (set_mode ==4)
   {
      if ((up ==1) || (down == 1))
      {
         up = 0;
         blink_one ();
         blink_null ();
         down = 0;

         //dst = ! dst;
         dst++;
         if(dst>1)
         {
            dst = 0;
         }
      }
      lcd_command (POS_3_15);                  // reposition to line 1    
      lcd_putint(dst);


      if (SET == 0)
      {
         set_mode = 5;                        // Move to minutes VIEW
         lcd_command (POS_4_0);           // Reposition to minutes position
         blink_empty (4) ;
      }
   }


   while (set_mode ==5)
   {

      if (up ==1)
      {
         up = 0;
         blink_one ();
         year1++;
         if(year1>9)
         {
            year1 = 0;
            year10++;
         }
         if(year10>9)
         {
            year10=0;
         }
      }


      if (down ==1)
      {
         down = 0;
         blink_null ();
         year1--;
         if(year1<0)
         {
            year1 = 9;
            year10--;
         }
         if(year10<0)
         {
            year10=9;
         }
      }

      lcd_command (POS_4_0);                  // reposition to line 1    
      lcd_putchar('2');
      lcd_putchar('0');
      lcd_putint(year10);
      lcd_putint(year1);

      if (SET == 0)
      {
         set_mode = 6;                        // Move to minutes VIEW
         lcd_command (POS_4_5);           // Reposition to minutes position
         blink_empty (2) ;
      }
   }


   while (set_mode ==6)
    {
      if (up ==1)
      {
         up = 0;
         blink_one ();
         month1++;
         if(month1>9)
         {
            month1 = 0;
            month10++;
         }
         if(month10==1 && month1>2)
         {
            month10 = 0;
            month1 = 1;
         }
      }

      if (down ==1)
      {
         down = 0;
         blink_null ();
         month1--;
         if(month1<0)
         {
            month1 = 9;
            month10--;
         }
         if(month10<1 && month1<1)
         {
            month10 = 1;
            month1 = 2;
         }
      }

      lcd_command (POS_4_5);                  // reposition to line 1    
      lcd_putint(month10);
      lcd_putint(month1);


      if (SET == 0)
      {
         set_mode = 7;                        // Move to minutes VIEW
         lcd_command (POS_4_8);           // Reposition to minutes position
         blink_empty (2) ;
      }
   }


   while (set_mode ==7)
    {

      if (up ==1)
      {
         up = 0;
         blink_one ();
         day1++;
         if(day1>9)
         {
            day1 = 0;
            day10++;
         }
         if(day10 >2 && day1>1)
         {
            day1 = 1;
            day10 = 0;
         }
      }


      if (down ==1)
      {
         down = 0;
         blink_null ();
         day1--;
         if(day1<0)
         {
            day1 = 9;
            day10--;
         }
         if(day10<1 && day1<1)
         {
            day1 = 1;
            day10 = 3;              // Måste justeras
         }
      }

      lcd_command (POS_4_8);                  // reposition to line 1    
      lcd_putint(day10);
      lcd_putint(day1);


      if (SET == 0)
      {
         set_mode = 8;                        // Move to minutes VIEW
         lcd_command (POS_4_11);           // Reposition to weekday position
         blink_empty (9) ;
      }
   }


   while (set_mode ==8)
   {

      if (up ==1)
      {
         up = 0;
         blink_one ();
         weekday++;
         if (weekday > 7)
         {
            weekday = 1;
         }
      }


      if (down ==1)
      {
         down = 0;
         blink_null ();
         weekday--;
         if (weekday <1)
         {
            weekday = 7;
         }
      }
   lcd_command (POS_4_11);
   if (weekday == 1)
   {
      lcd_putchar('M');
      lcd_putchar('o');
      lcd_putchar('n');
      lcd_putchar('d');
      lcd_putchar('a');
      lcd_putchar('y');
      lcd_putchar(' ');
   }

   if (weekday == 2)
   {
      lcd_putchar('T');
      lcd_putchar('u');
      lcd_putchar('e');
      lcd_putchar('s');
      lcd_putchar('d');
      lcd_putchar('a');
      lcd_putchar('y');
      lcd_putchar(' ');
      lcd_putchar(' ');
   }
   if (weekday == 3)
   {
      lcd_putchar('W');
      lcd_putchar('e');
      lcd_putchar('d');
      lcd_putchar('n');
      lcd_putchar('e');
      lcd_putchar('s');
      lcd_putchar('d');
      lcd_putchar('a');
      lcd_putchar('y');
   }
   if (weekday == 4)
   {
      lcd_putchar('T');
      lcd_putchar('h');
      lcd_putchar('u');
      lcd_putchar('r');
      lcd_putchar('s');
      lcd_putchar('d');
      lcd_putchar('a');
      lcd_putchar('y');
      lcd_putchar(' ');


   }
   if (weekday == 5)
   {
      lcd_putchar('F');
      lcd_putchar('r');
      lcd_putchar('i');
      lcd_putchar('d');
      lcd_putchar('a');
      lcd_putchar('y');
      lcd_putchar(' ');
      lcd_putchar(' ');
   }
   if (weekday == 6)
   {
      lcd_putchar('S');
      lcd_putchar('a');
      lcd_putchar('t');
      lcd_putchar('u');
      lcd_putchar('r');
      lcd_putchar('d');
      lcd_putchar('a');
      lcd_putchar('y');
   }

   if (weekday == 7)
   {
      lcd_putchar('S');
      lcd_putchar('u');
      lcd_putchar('n');
      lcd_putchar('d');
      lcd_putchar('a');
      lcd_putchar('y');
      lcd_putchar(' ');
      lcd_putchar(' ');
   }


      if (SET == 0)
      {
         delay10 (10);                         // Debounce 
         set_mode=0;
      }
   }

   stored_time[0]=hour10;     // Update string with set time
   stored_time[1]=hour1;
   stored_time[2]=min10;
   stored_time[3]=min1;
   stored_time[4]=sec10;
   stored_time[5]=sec1;
   stored_time[6]=dst;
   stored_time[7]=year10;
   stored_time[8]=year1;
   stored_time[9]=month10;
   stored_time[10]=month1;
   stored_time[11]=day10;
   stored_time[12]=day1;
   stored_time[13]=weekday;

   put_eedata ();              // Store set time in EEPROM

   lcd_command (0b0000.0001);                  // Cursor hoME
   for(i=0; i<20; i++) lcd_putchar(text4(i));  // display text 4
   display_mode = 1;                           // display VIEW should be 1 again
   lcd_command(0b0000.1100);                   // display on, cursor off, blink off */ 


   //Lägg in senast använd display mode här

   GIE = 0;                         // Interrupts llowed

   RBIE   = 0;                     /* local enable  */
   TMR1H = 0x80;                    // Reset counter
   TMR1L = 0x00;
   TMR1IF = 0;                      // Enable interrupt
   T1CON.0 = 1 ;                    // Start the oscillator

   TMR1IE = 1;                      // Enable interrupt
   PEIE = 1;                     // Interrupts llowed
   GIE = 1;                     // Interrupts llowed

   I_SET=0;
}

void blink_one (void)
{
   LED1=1;
   delay250us(1);
   LED1=0;
}
void blink_null (void)
{
   LED0=1;
   delay250us(1);
   LED0=0;
}