/* FILE / DATE:     tone_generator_0502.c / 2010-05-02     
   DESCRIPTION:     Tone generator for DCF simulator

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

   EXTERNAL HW:     Output amplifier
                    3 pins on PIC16F690 (Sound selection)
                    2 pins on PIC16F886 (Sound trigger)

   DESIGNER:        Hans Sundgren

   RAM usage:       4 bytes (3 local), 220 bytes free
   CODE WORDS:      181 code words (8 %)


CHIP CONNECTIONS ********************************************
                      ________  _______           
                     |        \/       |         
                     |    PIC16F628    |         
                  ---|RA2  1    18  RA1|->- Sound output
                  ---|RA3  2    17  RA0|---
                  ---|RA4  3    16  RA7|---       
                  ---|RA5  4    15  RA6|---
              GND ---|Vss  5    14  Vdd|--- +5V
     Sound mode.1 ->-|RB0  6    13  RB7|---
     Sound mode.2 ->-|RB1  7    12  RB6|---
     Sound mode.3 ->-|RB2  8    11  RB5|-<- Trigger.0       
                  ---|RB3  9    10  RB4|-<- Trigger.1    
                     |_________________|         


INPUT: SOUND TRIGGER (fron PIC16F886)
 __________________________________________________________
| Type                | Function                 | Pin     |
|---------------------|------------------------------------|
| "Null" sound        | Trigger 0 sound (RA6)    | RB5     |              
| "One" sound         | Trigger 1 sound (RA7)    | RB4     |              
|_____________________|__________________________|_________|


INPUT: SOUND SELECTION (fron PIC16F690)
 __________________________________________________________
| Type                | Function                 | Pin     |
|---------------------|------------------------------------|
| Sound mode 1 bit    | Interface (RB4)          | RB0     |              
| Sound mode 2 bit    | Interface (RB5)          | RB1     |              
| Sound mode 3 bit    | Interface (RB6)          | RB2     |              
|_____________________|__________________________|_________|

         
OUTPUT: SOUND to amplifier
 __________________________________________________________
| Type                | Function                 | Pin     |
|---------------------|------------------------------------|
| Digital output      | Sound                    | RA1     |                         
|_____________________|__________________________|_________|



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

    Main ---------------------------------------------------
   |  Initialization                                        |
   |  Loop                                                  |
   |     Read mode bits and convert to decimal mode         |
   |     If mode = 1                                        |
   |        Play click sound                                |
   |     If mode = 2                                        |
   |        Play other sound                                |
   |     If mode = 3                                        |
   |        Play other sound                                |
   |     If mode = 4                                        |
   |        Play other sound                                |
   |     <can be expanded up to mode = 7>                   |
    --------------------------------------------------------

   */


/* _______________________________ INCLUDE __________________________ */

#include "16f628.h"
#include "int16CXX.h"


/* _______________________________ CONFIGURATION ____________________ */

#pragma config |= 0x3f10         // use internal 4MHz oscillator


/* _______________________________ GLOBAL VARIABLES _________________ */

char mode;                       // Ordered sound mode from PIC "Sound selection"


/* _______________________________ FUNCTIONS ________________________ */

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

void tone_a (void);
void tone_b (void);


/* _______________________________ I/O PIN DEFINITIONS ____ */

#pragma bit TONE   @ PORTA.1     // Main output to transmitter

#pragma bit MODE_1  @ PORTB.0    // Sound selection bit 1
#pragma bit MODE_2  @ PORTB.1    // Sound selection bit 2
#pragma bit MODE_3  @ PORTB.2    // Sound selection bit 3
#pragma bit TRIG_0  @ PORTB.4    // "Null" signal from DCF simulator
#pragma bit TRIG_1  @ PORTB.5    // "One" signal from DCF simulator


/* _______________________________ MAIN FUNCTION start ________________________ */


void main(void)
{

   TRISA = 0b0000.0000;          // A1 = output
   TRISB = 0b0011.0111;          // B0, B1, B4, B5 = inputs 
   OPTION.7 = 0;                 // Activate internal pullup resistors
   CM0=1; CM1=1;  CM2=1;         // No comparators on PORTA

   while(1)
   {
      mode.0 = MODE_1;           // Read mode from Sound Selection PIC
      mode.1 = MODE_2;
      mode.2 = MODE_3;

      if (mode == 1)
      {
         char s;
         if (TRIG_0 == 1)
         {
            for (s=0; s<6; s++)
            {
               tone_a ();
            }
            delay10(20);          // Wait for TRIG_0 to reset to 0
         }
         if (TRIG_1 == 1)
         {
            for (s=0; s<6; s++)
            {
               tone_b ();
            }
            delay10(25);          // Wait for TRIG_1 to reset to 0
            }
         }
      if (mode == 2)
      {
         while (TRIG_0 == 1)
         {
               tone_a ();
         }
         while (TRIG_1 == 1)
         {
               tone_b ();
         }
      }
      if (mode == 3)
      {
         if (TRIG_0 == 0  && TRIG_1 == 0)
         {
               tone_b ();
         }
      }
      if (mode == 4)
      {
         if (TRIG_0 == 0  && TRIG_1 == 0)
         {
               tone_a ();
         }
      }
   }
}


/* _______________________________ FUNCTIONS ________________________ */


void tone_a (void)
   {
      nop();
      delay(2);
      TONE = 1;
      delay(2);
      TONE = 0;
   }

void tone_b (void)
   {
      nop();
      delay(1);
      TONE = 1;
      delay(1);
      TONE = 0;
   }

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

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();
         }
   }
}