//*****************************************************************************
// Title                : Pulse to tone (DTMF) converter
// Author                : Boris Cherkasskiy
// Created                : 2011-10-24
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
// DTMF generator logic is loosely based on the AVR314 app note from Atmel
//
//*****************************************************************************

//*****************************************************************************
//            PIC16F628A VERSION TRANSLATED BY GioRock 2018
//*****************************************************************************

//*****************************************************************************
/*'     Rotary Dial                            PIC & uP
'                      /---------------------- readyPin
'  /- ready switch (NO) -- pull-up resistor -- VCC
' /-- pulse switch (NC) -- pull-up resistor -/
' \                    \---------------------- pulsePin
'  \------------------------------------------ GND
'
'
'La corretta sequenza è:
'readyPin  pulsePin  stato
'HIGH      n/a       default (attesa)
'LOW       LOW       pronto per la chiamata / per il primo impulso
'LOW       HIGH      impulso ricevuto (numero = 1)
'LOW       LOW       pronto per il prossimo impulso
'LOW       HIGH      impulso ricevuto  (numero = 2)
'LOW       ...       (via così...)
'HIGH      n/a       rotazione completa, conteggio memorizzato*/
//*****************************************************************************

#ifndef ROTARY_PULSE_TO_TONE_H
#define ROTARY_PULSE_TO_TONE_H

#define USE_LED

// Definizioni costanti
#define  N_samples        128 // Numero dei campioni nella lookup table

#define DIGIT_BEEP        -10
#define DIGIT_BEEP_LOW    -13
#define DIGIT_TUNE_ASC    -11
#define DIGIT_TUNE_DESC   -12
#define DIGIT_OFF         -1
#define DIGIT_STAR        10
#define DIGIT_POUND       11

#define DTMF_DURATION_MS 100

// Frequenza PWM = 8Mhz / 256 * 2 = 62500 Hz
#define T1_OVERFLOW_PER_MS       2
#define T1_PRELOAD_PER_MS      252
#define SF_DELAY_MS           2000
#define SPEED_DIAL_SIZE         18 // lunghezza massima del numero

// RB3 (CCP1) come uscita PWM
#define PIN_PWM_OUT     RB3_bit

#define PIN_DIAL        RB5_bit
#define PIN_PULSE       RB4_bit

#define PIN_DIAL_TEMP   RA0_bit
#define PIN_PULSE_TEMP  RA1_bit

// RA3 come segnalazione di
// attivazione del PWM
#ifdef USE_LED
    #define PIN_LED RA3_bit
#endif

// Definisce iil tipo booleano
#ifndef bool
    #define bool unsigned char
#endif

// Definisce i valori per
// acceso e spento
#ifndef OFF
    #define OFF 0
#endif
#ifndef ON
    #define ON  1
#endif

// Definisce i valori booleani
#ifndef false
    #define false 0
#endif
#ifndef true
    #define true  1
#endif

// Modalità del TIMER1
#define SLEEP_MODE_PWR_DOWN 0
#define SLEEP_MODE_IDLE     1

// Funzioni di supporto MACRO
// Attiva il PWM
#define PWM_Start() PIE1.TMR2IE  = true;       \
                    PIR1.TMR2IF  = false;      \
                    T2CON.TMR2ON = true;       \
                    CCP1CON      = 0b00001100; \
                    CCPR1L       = 0
                    
// Disattiva il PWM                  
#define PWM_Stop()  T2CON.TMR2ON = false; \
                    PIE1.TMR2IE  = false; \
                    PIR1.TMR2IF  = false; \
                    CCP1CON      = 0;     \
                    CCPR1L       = 0
                    
// BIT VALUE
#ifndef BV
        #define BV(bit)             (1<<(bit))
#endif
// CLEAR BIT INDEX (0)
#ifndef cbi
        #define cbi(reg,bit)        reg &= ~(BV(bit))
#endif
// SET BIT INDEX (1)
#ifndef sbi
        #define sbi(reg,bit)        reg |= (BV(bit))
#endif

//************************ TABELLA DEL SENO ********************************
// Tabella dei campioni : un periodo campionato con 128 campioni e
// quantizzato a 7 bit
//**************************************************************************
const code unsigned char auc_SinParam [N_samples] = {
        64, 67,  70, 73,
        76, 79,  82, 85,
        88, 91,  94, 96,
        99, 102, 104,106,
        109,111, 113,115,
        117,118, 120,121,
        123,124, 125,126,
        126,127, 127,127,
        127,127, 127,127,
        126,126, 125,124,
        123,121, 120,118,
        117,115, 113,111,
        109,106, 104,102,
        99, 96,  94, 91,
        88, 85,  82, 79,
        76, 73,  70, 67,
        64, 60,  57, 54,
        51, 48,  45, 42,
        39, 36,  33, 31,
        28, 25,  23, 21,
        18, 16,  14, 12,
        10, 9,   7,  6,
        4,  3,   2,  1,
        1,  0,   0,  0,
        0,  0,   0,  0,
        1,  1,   2,  3,
        4,  6,   7,  9,
        10, 12, 14,  16,
        18, 21, 23,  25,
        28, 31, 33,  36,
        39, 42, 45,  48,
        51, 54, 57,  60
};
//************************ TABELLA DEL SENO ********************************
// Tabella dei campioni : un periodo campionato con 64 campioni e
// quantizzato a 7 bit
//**************************************************************************
/*const code unsigned char auc_SinParam[N_samples] = {  // Sine Lookup table
     50, 54, 59, 64, 68, 73, 77, 81,
     85, 88, 91, 93, 95, 97, 98, 99,
     99, 99, 98, 97, 95, 93, 91, 88,
     85, 81, 77, 73, 68, 64, 59, 54,
     50, 45, 40, 35, 31, 26, 22, 18,
     14, 11,  8,  6,  4,  2,  1,  0,
      0,  0,  1,  2,  4,  6,  8, 11,
     14, 18, 22, 26, 31, 35, 40, 45
};*/

//******************************  x_SW  ************************************
// Fck = Xtal / prescaler (for PIC = 4)
// Table of x_SW (excess 8): x_SW = ROUND(8 * N_samples * f * 255 / Fck)
//**************************************************************************

//frequenza alta
//1209hz  ---> x_SW = 158
//1336hz  ---> x_SW = 174
//1477hz  ---> x_SW = 192
//1633hz  ---> x_SW = 214
//
//frequenza bassa
//697hz  ---> x_SW = 92
//770hz  ---> x_SW = 100
//852hz  ---> x_SW = 112
//941hz  ---> x_SW = 122
//
// QUADRANTI TELEFONICI vs. FREQUENZE
//      |  1209 | 1336 | 1477 | 1633
//  697 |   1   |  2   |   3  |   A
//  770 |   4   |  5   |   6  |   B
//  852 |   7   |  8   |   9  |   C
//  941 |   *   |  0   |   #  |   D


// rapporto frequenza da AVR8 a PIC16 (1:4 = x4)
// qui si usa solo il moltiplicatore x2 (char = 255)
const code unsigned char auc_frequency [12][2] = {
        {174, 122},        // 0
        {158,  92},        // 1
        {174,  92},        // 2
        {192,  92},        // 3
        {158, 100},        // 4
        {174, 100},        // 5
        {192, 100},        // 6
        {158, 112},        // 7
        {174, 112},        // 8
        {192, 112},        // 9
        {158, 122},        // *
        {192, 122},        // #
};

// Prototipo delle funzioni
void main(void);

void ProcessDialedDigit(void);

void init(void);

void GenerateDigit(signed char scDigit, unsigned int uiDuarationMS);

void EnablePWM(void);
void SleepMS(unsigned int uiMsec);

void Dial_SpeedDialNumber(unsigned char ucSpeedDialIndex);
void WriteCurrentSpeedDial(unsigned char ucSpeedDialIndex);

void eeprom_read_byte_block(char * __dst, char __src, unsigned short __n);
void eeprom_update_byte_block(char * __src, char __dst, unsigned short __n);

void Interrupt(void);

void SetDutyCycle(unsigned int v);

void set_sleep_mode(unsigned char mode);

void ResetTMR1(void);

#endif