/*=======================================================================+
|             DEPARTAMENTO MECANICA UNIVERSIDADE AVEIRO                  |
|               Projecto Humanoide (PHUA - MODULROB)                     |
|                                                                        |
| Programadores:                                                         |
|              David Manuel Costa Gameiro          N:20281               |
|              Filipe Carvalho Mostardinha         N:22085               |
|                                                                        |
| Data: Segunda - 20/Maio/2004                                           |
|                                                                        |
| Nome Ficheiro: Master.c                                                |
|                                                                        |
|                            SOURCE FILE                                 |
+=======================================================================*/

#include <p18f258.h>
#include "include\adc.h"
#include "include\can18xx8.h"
#include "include\Usart.h"
#include "include\FuncAux.h"
#include "InitPic.h"

typedef unsigned char byte;
typedef enum _bool { false = 0, true = 1} bool;
typedef unsigned int inteiro;



#define NUM_ARTIC 5//num de mebros existentes no rob

inteiro NomeMCU = 0x01;//Nome deste MCU


/*------------------------------------------------------------------+
|       Macros com definicoes das Comunicacoes e leitura ADC's      |
+------------------------------------------------------------------*/

#define FREQ_OSC 20E6 //valor da frequencia do oscilador

////////////////////////////////////////////////
//    Mascaras relativas a config das ADC's   //
////////////////////////////////////////////////

//velocidade de conversao|justificacao a esquerda (ADRESH)
//apenas entrada AN0 analogica, com AN3 tensao V+ e massa Vss
#define ADC1_FLAGS 0b10000010
//escolhe-se o canal 0 para iniciar|desligar interrupts ADC
#define ADC2_FLAGS ADC_CH_ALL



////////////////////////////////////////////////
//  Mascaras relativas a configuracao do CAN  //
//                                            //
//  Todas as configura‡”es do CAN s„o         //
//  efectuadas na header file InitCan.h       //
////////////////////////////////////////////////

#include "InitCan.h"

//byte definido 0b1a111bcd
// a - caso seja pretendido retorno de recepØ"o de msg (1) caso contrario 0
// b - indica qual o tipo de indentificador (1)STD (0)XTD
// [c,d] - prioridade a dar a esta mensagem, ver registo TXBnCON
#define CAN_TX_FLAGS 0b10000111

////////////////////////////////////////////////
//       Mascaras da USART, TRIS e PORTOS     //
////////////////////////////////////////////////

//baudRate desejado a colocar no PIC
#define BAUD 9600 




/*------------------------------------------------------------------+
|                     Declaracao de variaveis                       |
+------------------------------------------------------------------*/

juntas Membro[NUM_ARTIC]={{2,2,2,4,6,6}, // MCU Pernas lado esquerdo
			 			  {8,8,8,8,8,8}, // MCU Braco lado esquerdo
			 			  {3,3,3,5,7,7}, // MCU Pernas lado direito
			 			  {9,9,9,9,9,9}};// MCU Braco lado esquerdo


//dados recebidos ou enviados pela Usart
byte MsgRecebUsart[2], MsgEnvUsart[9];
//byte conta;//num bytes a enviar pela Usart
bool FaltaByte = false;//falta o segundo byte			 

//dados recebidos ou enviados pelo Can
byte MsgEnvCan[2], MsgRecebCan[8];
byte CompMsgCan;//num bytes a enviar pelo Can

byte PicRemoto; //Nome do micro remoto

/*------------------------------------------------------------------+
|                       Declaracao de funcoes                       |
+------------------------------------------------------------------*/

#pragma interrupt ComIsr
void ComIsr(void)
{
#define BYTES_CAN 2

byte NumMembro, NumJunta;
byte Msg[BYTES_CAN];
byte tmp, RemoteID;

/*--------------------------------------+
|            Interrupt Usart            |
+--------------------------------------*/
if(PIR1bits.RCIF)
{
	MsgRecebUsart[FaltaByte] = RCREG;
	
	
	if (FaltaByte)
	{
		FaltaByte = false;
		
		NumMembro = (MsgRecebUsart[0] & BITS_SIDE_TOP);
		NumJunta = (MsgRecebUsart[0] & BITS_IDENT );
		//retira a numero do microcontrolador na rede do can
		PicRemoto = Membro[NumMembro].Junta[NumJunta];

		// char com o tipo d msg e o num da junta, motor
		Msg[0] = (MsgRecebUsart[0] & BITS_TIPO_MSG)+(NumJunta);

		Msg[1] = MsgRecebUsart[1];//retira a segunda parte da mensagem
		switch (Msg[0])
		{
			case LER_TDOS_SENS:
			{	
			if (MsgRecebUsart[1] == 0xFF)
				TdasJuntasMembro(&Membro[NumMembro], NUM_ARTIC, Msg, CAN_TX_FLAGS);
			else
				CANSendMessage(PicRemoto, Msg, BYTES_CAN, CAN_TX_FLAGS);	

			break;
			}
			case LER_POS_JUNTA:
			{
			CANSendMessage(PicRemoto, Msg, BYTES_CAN, CAN_TX_FLAGS);
			break;
			}
			case LER_SENS_PE:
			{
			CANSendMessage(PicRemoto, Msg, BYTES_CAN, CAN_TX_FLAGS);
			break;
			}
			case NOV_POS_MOT:
			{
			if( MsgRecebUsart[1]==0xFF )
			{
				TdasJuntasMembro(&Membro[NumMembro], NUM_ARTIC, Msg, CAN_TX_FLAGS);
			}
			CANSendMessage(PicRemoto, Msg, BYTES_CAN, CAN_TX_FLAGS);
			break;
			}
			default: EnvCh((byte *)13);
		};
	}
	else
		FaltaByte = true;//falta ainda um byte

PIR1bits.RCIF = false;//desliga-se o interrupt
}

/*-------------------------------------------------------------------------+
|                   Interrupt referente ao CAN                             |
+-------------------------------------------------------------------------*/

if (PIR3 & 0b00000011)
{
//acabou = CANReceiveMessage(&RemoteID, MsgRecebCan, &CompMsgCan, &tmp);
	
//	if (acabou)
	{
//	MsgEnvUsart[0] = ;
//	EnviaD(, CompMsgCan);
//	EnviaD(&Msg);
	}
}

}


#pragma code IsrHigh=0x08
void IsrHigh(void)
{
_asm
	goto ComIsr //salta para a rotina de interrupt
_endasm
}


#pragma code

void main(void)
{
//InitCan();

SetADC(ADC1_FLAGS, ADC2_FLAGS);//Actualiza a ADC

InitPic(FREQ_OSC, BAUD);


while(1)
{// Digitalizar os valores dos sensores

};//Normal Funcionamento do PIC
}
