/*-----------------------------------------------------------------------+
|             DEPARTAMENTO MECANICA UNIVERSIDADE AVEIRO                  |
|                                                                        |
| Nome:                                                                  |
|       David Manuel Costa Gameiro          N:20281                      |
|       Filipe Carvalho Mostardinha         N:22085                      |
|                                                                        |
| Data:   10/Maio/2004       Nome Fihceiro: InitPIC.c                    |
+-----------------------------------------------------------------------*/

#include <p18f258.h>
#include "InitPIC.h"
#include "Can18xx8.h"

void InitPic(unsigned long FreqRes, unsigned long FreqOsc, int Baud)
{
//Prescaler para gerar onda quadrada de 100KHz
#define PresScalerTimer2 4


int Duty50; //dutycycle de 50%
byte ValPR2;

/*------------------------------------------------------------------+
|                    Definicoes dos TRIS do PIC                     |
+------------------------------------------------------------------*/
//PortoA <1:7> saˇdas exepto RA0
TRISA = 0x01;
//PortoB <0:2> entradas(INT0, INT1, CANRX), <3:7> saidas
TRISB = 0b00001011;
//PortoC <0:6> saidas, RC7 entrada(RX USART)
TRISC = 0b10000000;

/*------------------------------------------------------------------+
|          Definicoes do Timer2 e Gerador PWM1(CCP1CON)             |
+------------------------------------------------------------------*/
//Calculo de PR2, para gerar o pwm, pag 130 datasheet

ValPR2 = (byte)(FreqOsc*1E6/(4.0*FreqRes*1E3*PresScalerTimer2))-1;
//valor a contar para 50% de duty cycle
Duty50 = (byte)(FreqOsc*1E6/(2.0*FreqRes*1E3*PresScalerTimer2));
//Parar a compila‡„o devido ao valor obtido para o PR2
#if ((ValPR2<0) || (ValPR2>256) || (Duty50<0 || Duty50>256))
	#error "valor de PR2 nao e aceitavel."
#endif

PR2 = ValPR2;


switch (PresScalerTimer2)
{
	case 1:{ T2CON = 0b00000100; break;}
	case 4:{ T2CON = 0b00000101;break;}
	case 16:{ T2CON = 0b00000110;break;}
}

//ocupar apenas a posicao dos bits menos significativos do pwm
CCP1CON = (Duty50 & 0x03) << 4;
//bits + significativos do dutycycle
CCPR1L = Duty50 >> 2;

/*------------------------------------------------------------------+
|          			    Defini‡”es da USART             		    |
+------------------------------------------------------------------*/

SPBRG = (byte)((FreqOsc*1E6/Baud)/16.0)-1; //verificar datasheet pag 185

//Usar a USART em High Speed,(BRG=0 Low Speed)
TXSTAbits.BRGH = true;   
//Activa os pinos da porta serie
RCSTAbits.SPEN = true;   

TXSTAbits.TXEN = true;
//Modo continuo na recepcao fica activo
RCSTAbits.CREN = true;

/*------------------------------------------------------------------+
|          			 Defini‡”es dos Interrupts             		    |
+------------------------------------------------------------------*/

// Global interrupt enable bit (enables all unmasked interrupts)

//ligar o interrupt dos rising edges dos osciladores externos

INTCON2bits.INTEDG0 = true; //interrupt na ascens„o da onda 50Hz

INTCON2bits.INTEDG1 = true; //interrupt na ascens„o da onda


//Prioridades do Interrupts
INTCON3bits.INT1IP = true; //alta prioridade no interrupt
IPR1bits.RCIP = false;
IPR3bits.RXB0IP = false;
IPR3bits.RXB1IP = false;

RCONbits.IPEN = true;//Activa interrupts priorit rios

INTCONbits.GIEH = true;	//Interrupts prioritarios activos
INTCONbits.GIEL = true;	//Interrupts menos prioritarios activos

//Activa o interrupt, para o caso que chegue algo pela porta serie
PIE1bits.RCIE = true;

INTCONbits.INT0IE = true;//oscilador de 50Hz ligado a RB0

INTCON3bits.INT1IE = true;//oscilador da onda de resolucao ligada
}
