#include <p32xxxx.h>
#include <stdio.h>
#include <stdlib.h>
#include <plib.h>
//#include <peripheral\system.h>
#include <peripheral\CAN.h>
#include "GenericTypeDefs.h"
#define SYSTEM_FREQ 80000000
#define CAN_BUS_SPEED 125000
/*Fsys = 80MHz */
/*Fpb = 80MHz */
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1
BYTE CAN1MessageFifoArea[2 * 8 * 16];
BOOL isCAN1MsgReceived = FALSE;
CANRxMessageBuffer * messageRx;
CANTxMessageBuffer * messageTx;
int prueba=0;
void CAN1Init(void);
void CAN1TxSendRTRMsg(void);
/************************************/
/************************************/
/* Función Principal */
/************************************/
/************************************/
void main (void){
/*Ponemos los puertos Analógicos-Digitales*/
AD1PCFG = 0xFFFF;
/*Pin del Led como salida*/
_TRISF3=0;
_LATF3 = 0;
/*Pines del CAN como entrada y Salida Respectivamente.*/
_TRISF0=1;
_TRISF1=0;
INTEnableSystemMultiVectoredInt();
/*Configuramos CAN1*/
CAN1Init();
prueba=0;
while(1){
if(prueba==0){
CAN1TxSendRTRMsg();
}
//CAN1TxSendRTRMsg();
//CAN1RxMsgProcess();
/*Verificamos si Tx = Rx*/
if ((messageRx->messageWord[2]==0)){
_LATF3 = 1;
}
else
_LATF3 = 0;
}
}
/***************************/
/***************************/
/*Configuración del Bus CAN*/
/***************************/
/***************************/
void CAN1Init(void)
{
CAN_BIT_CONFIG canBitConfig;
UINT baudPrescalar;
/*Ponemos el módulo CAN en modo configuración*/
CANEnableModule(CAN1,TRUE);
CANSetOperatingMode(CAN1, CAN_CONFIGURATION);
/*Esperamos hasta que entre en modo configuración*/
while(CANGetOperatingMode(CAN1) != CAN_CONFIGURATION);
/*Configuramos el reloj del módulo CAN*/
canBitConfig.phaseSeg2Tq = CAN_BIT_3TQ;
canBitConfig.phaseSeg1Tq = CAN_BIT_3TQ;
canBitConfig.propagationSegTq = CAN_BIT_1TQ;
canBitConfig.phaseSeg2TimeSelect = TRUE;
canBitConfig.sample3Time = FALSE;
canBitConfig.syncJumpWidth = CAN_BIT_1TQ;
CANSetSpeed(CAN1,&canBitConfig,SYSTEM_FREQ,CAN_BUS_SPEED);
/*Asignamos el tamaño del Búfer*/
CANAssignMemoryBuffer(CAN1,CAN1MessageFifoArea,(2 * 8 * 16));
/*Seleccionamos las FIFOS */
/*FIFO0 para Tx */
/*FIFO1 para Rx */
/*FIFO0 con RTR deshabilitado y prioridad baja*/
/*FIFO1 recepción del mensaje completo*/
CANConfigureChannelForTx(CAN1, CAN_CHANNEL0, 8, CAN_TX_RTR_DISABLED, CAN_LOW_MEDIUM_PRIORITY);
CANConfigureChannelForRx(CAN1, CAN_CHANNEL1, 8, CAN_RX_FULL_RECEIVE);
/*Configuramos Filtros y máscaras */
/*Filtro0 para aceptar SID 0x201 */
/*Máscara0 para comparar todos los ID */
/*El mensaje debe ser almacenado en FIFO1 */
//CANConfigureFilter (CAN1, CAN_FILTER0, 0x001, CAN_SID);
//CANConfigureFilterMask (CAN1, CAN_FILTER_MASK0, 0x7FC, CAN_SID, CAN_FILTER_MASK_IDE_TYPE);
//CANLinkFilterToChannel (CAN1, CAN_FILTER0, CAN_FILTER_MASK0, CAN_CHANNEL1);
//CANEnableFilter (CAN1, CAN_FILTER0, TRUE);
/*Habilitamos interrupciones y eventos */
/*Habilitamos la recepción si hay un evento */
/*Habilitamos la interrupción */
CANEnableChannelEvent(CAN1, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, TRUE);
CANEnableModuleEvent (CAN1, CAN_RX_EVENT, TRUE);
INTSetVectorPriority(INT_CAN_1_VECTOR, INT_PRIORITY_LEVEL_4);
INTSetVectorSubPriority(INT_CAN_1_VECTOR, INT_SUB_PRIORITY_LEVEL_0);
INTEnable(INT_CAN1, INT_ENABLED);
//IEC1SET = 0x04000000;
/*Ponemos el módulo CAN en modo normal */
CANSetOperatingMode(CAN1, CAN_LOOPBACK);
while(CANGetOperatingMode(CAN1) != CAN_LOOPBACK);
CANClearModuleEvent(CAN1, CAN_OPERATION_MODE_CHANGE_EVENT);
}
/***************************************************/
/***************************************************/
/*Función para enviar un mensaje al bus CAN */
/***************************************************/
/***************************************************/
void CAN1TxSendRTRMsg(void)
{
//CANTxMessageBuffer * messageTx;//Lo saco a variable global
/*Actualizamos el índice en la FIFO0 */
messageTx = CANGetTxMessageBuffer(CAN1,CAN_CHANNEL0);
/*Mensaje a enviar */
messageTx->messageWord[0] = 0;
messageTx->messageWord[1] = 0;
messageTx->messageWord[2] = 0;
messageTx->messageWord[3] = 0;
messageTx->msgSID.SID = 0x001;
messageTx->msgEID.IDE = 0;
messageTx->msgEID.RTR = 0;
messageTx->msgEID.DLC = 4;
/*Actualizamos el índice a la nueva posición de la FIFO0*/
CANUpdateChannel(CAN1,CAN_CHANNEL0);
/*Limpiamos la FIFO0 permitiendo enviar cualquier mensaje de Tx*/
CANFlushTxChannel(CAN1,CAN_CHANNEL0);
}
/***************************************************/
/***************************************************/
/*Manejador de la interrupción del CAN1 */
/*Todos los eventos se habilitan en CanEnableEvent */
/*En este caso un evento en la recepción */
/***************************************************/
/***************************************************/
void __ISR (_CAN_1_VECTOR, ipl4) CAN1Interrupt(void)
{
/*Verifica si hay un evento en la recepción*/
if((CANGetModuleEvent(CAN1) & CAN_RX_EVENT) != 0)
{
/*Se podría verificar que causó el evento mediante*/
/*CANGetModuleEvent(), que devuelve el código */
/*que representa la prioridad más alta del evento */
/*pendiente */
if(CANGetPendingEventCode(CAN1) == CAN_CHANNEL1_EVENT)
{
/*Verificamos si se ha producido un evento en la FIFO1 */
/*El evento CAN_RX_CHANNEL_NOT_EMPTY es persistente */
/*Se puede leer la FIFO por la interrupción para borrar */
/*la condición de evento o deshabilitar el origen de */
/*de los eventos y hacerlo mediante una función como aquí */
CANEnableChannelEvent(CAN1, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, FALSE);
messageRx = (CANRxMessageBuffer *)CANGetRxMessage(CAN1,CAN_CHANNEL1);
CANUpdateChannel(CAN1, CAN_CHANNEL1);
CANClearModuleEvent (CAN1, CAN_RX_EVENT);
prueba=1;
}
}
/*Se borra la bandera de la interrupción */
/*Siempre al final para que si se produce */
/*otra interrupción no tenga efecto */
INTClearFlag(INT_CAN1);
}