/*=======================================================================+
|             DEPARTAMENTO MECANICA UNIVERSIDADE AVEIRO                  |
|               Projecto Humanoide (PHUA - MODULROB)                     |
|                                                                        |
| Programadores:                                                         |
|              David Manuel Costa Gameiro          N:20281               |
|              Filipe Carvalho Mostardinha         N:22085               |
|                                                                        |
| Nome Ficheiro: InitPic.c                                               |
|                                                                        |
|                            SOURCE FILE                                 |
+=======================================================================*/


#include <p18f258.h>
#include "InitPic.h"

/*------------------------------------------------------------------+
|    int InitPic(long FreqOsc, int baud,byte FreqAct)               |
|                                                                   |
| Entradas: FreqOsc - frequencia do oscilador em MHz                |
|           baud - baudrate para a Usart                            |
|           FreqAct - frequencia d actualizacao Juntas em (KHz)     |
|                                                                   |
| Saidas: numero de contagen a serem efectuadas para aquela FreqAct |
|                                                                   |
| Objectivos: Inicializar os registos do Pic                        | 
+------------------------------------------------------------------*/


int InitPic(byte FreqOsc, int baud,byte FreqAct)
{
//Prescaler para gerar a onda a que serao enviadas as mensagens
#define PresScalerTimer2 4
int Duty50;//DutyCycle da Onda a 50%
byte ValPR2;

/*------------------------------------------------------------------+
|                    Definicoes dos TRIS do PIC                     |
+------------------------------------------------------------------*/
//PortoA <1:7> saˇdas exepto RA0
TRISA = 0x01;
//PortoB <2> entradas CanRx, <0:1><3:7> saidas
TRISB = 0b00001010;
//PortoC <0:6> saidas, RC7 entrada(RX USART)
TRISC = 0b10000000;

/*------------------------------------------------------------------+
|          			    Defini‡”es da USART             		    |
+------------------------------------------------------------------*/

 //verificar datasheet pag 185
SPBRG = (byte)(((FreqOsc*1E6)/baud)/16)-1;

//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 do TIMER2 e Gerador PWM            		|
+------------------------------------------------------------------*/

//Calculo de PR2, para gerar o pwm, pag 130 datasheet

ValPR2 = (byte)(FreqOsc*1E3/(4.0*FreqAct*PresScalerTimer2))-1;
//valor a contar para 50% de duty cycle
Duty50 = (byte)(FreqOsc*1E3/(2.0*FreqAct*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 dos Interrupts             		    |
+------------------------------------------------------------------*/

// Global interrupt enable bit (enables all unmasked interrupts)


INTCON2bits.INTEDG1 = true; //interrupt na ascens"o da onda

//Prioridades do Interrupts
IPR1bits.RCIP = true;

INTCON3bits.INT1IP = false; //alta prioridade no interrupt
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;

INTCON3bits.INT1IE = true;//oscilador da onda de Actualizacao ligada
}
