#include <stdio.h>
#include <Philips\LPC2378.h>
#include "Type.h"
#include "SystemInit.h"
#include "UART0.h"
#include "VIC.h"
#include "CAN.h"
CAN_TX_CONF CAN_CanTxConf[CAN_MAX_TX_MSG]=
{
CAN_TX_400, 8, CAN_CHANNEL1, 00, (CAN_29BIT | CAN_NO_RTR), 0x400,
CAN_TX_420, 8, CAN_CHANNEL1, 00, (CAN_29BIT | CAN_NO_RTR), 0x420,
CAN_TX_DEAD, 8, CAN_CHANNEL2, 00, (CAN_29BIT | CAN_NO_RTR), 0xDEAD,
CAN_TX_ADDED, 8, CAN_CHANNEL2, 00, (CAN_29BIT | CAN_NO_RTR), 0xADDED
};
CAN_CHANNEL_CONF CAN_CanChannelConf[MAX_CANPORTS]=
{
CAN_CHANNEL1, 0, 0, CAN_BAUD_125K,
CAN_CHANNEL2, 1, 0, CAN_BAUD_125K
};
CAN_RX_CONF CAN_CanRxConf[CAN_MAX_RX_MSG]=
{
CAN_RX_400, 0x400,
CAN_RX_420, 0x420,
CAN_RX_DEAD, 0xDEAD,
CAN_RX_ADDED, 0xADDED
};
CAN_RX_FRAME CAN_CanRxBuffer[CAN_MAX_RX_MSG];
uint32 CAN_u32CANStatus;
uint32 CAN_u32CAN1RxCount = 0, CAN_u32CAN2RxCount = 0;
uint32 CAN_u32CAN1ErrCount = 0, CAN_ulCAN2ErrCount = 0;
void CAN_SetACCFLookup( void )
{
uint32 u32address = 0;
uint32 u32i;
uint32 u32ID_high, u32ID_low;
CAN_SFF_SA = u32address;
for ( u32i = 0; u32i < ACCF_IDEN_NUM; u32i += 2 )
{
u32ID_low = (u32i << 29) | (EXP_STD_ID << 16);
u32ID_high = ((u32i+1) << 13) | (EXP_STD_ID << 0);
*((uint32 *)(CAN_MEM_BASE + u32address)) = u32ID_low | u32ID_high;
u32address += 4;
}
CAN_SFF_GRP_SA = u32address;
for ( u32i = 0; u32i < ACCF_IDEN_NUM; u32i += 2 )
{
u32ID_low = (u32i << 29) | (GRP_STD_ID << 16);
u32ID_high = ((u32i+1) << 13) | (GRP_STD_ID << 0);
*((uint32 *)(CAN_MEM_BASE + u32address)) = u32ID_low | u32ID_high;
u32address += 4;
}
CAN_EFF_SA = u32address;
for ( u32i = 0; u32i < ACCF_IDEN_NUM; u32i++ )
{
u32ID_low = (u32i << 29) | (EXP_EXT_ID << 0);
*((uint32 *)(CAN_MEM_BASE + u32address)) = u32ID_low;
u32address += 4;
}
CAN_EFF_GRP_SA = u32address;
for ( u32i = 0; u32i < ACCF_IDEN_NUM; u32i++ )
{
u32ID_low = (u32i << 29) | (GRP_EXT_ID << 0);
*((uint32 *)(CAN_MEM_BASE + u32address)) = u32ID_low;
u32address += 4;
}
CAN_EOT = u32address;
return;
}
void CAN_SetACCF( uint32 u32ACCFMode )
{
switch ( u32ACCFMode )
{
case ACCF_OFF:
CAN_AFMR = u32ACCFMode;
CAN1MOD = CAN2MOD = 1; // Reset CAN
CAN1IER = CAN2IER = 0; // Disable Receive Interrupt
CAN1GSR = CAN2GSR = 0; // Reset error counter when CANxMOD is in reset
break;
case ACCF_BYPASS:
CAN_AFMR = u32ACCFMode;
break;
case ACCF_ON:
case ACCF_FULLCAN:
CAN_AFMR = ACCF_OFF;
CAN_SetACCFLookup();
CAN_AFMR = u32ACCFMode;
break;
default:
break;
}
return;
}
void CAN_InitModule(void)
{
uint8 u8Count;
PCONP |= 0x00006000; /* Turn On CAN1 CAN2 PCLK */
PINSEL0 &= ~0x00000F0F;
PINSEL0 |= 0x0000A05; // P0.0,P0.1, function 0x01, P0.4,P0.5, function 0x10
CAN_SetACCF(ACCF_BYPASS);
for(u8Count=0; u8Count < CAN_MAX_RX_MSG ; u8Count++)
{
CAN_CanRxBuffer[u8Count].u8RxFlag =0;
}
}
uint16 CAN_InitChannel (uint8 u8ChaNo)
{
switch (u8ChaNo)
{
case CAN_CHANNEL1:
CAN1MOD = 1; // Reset CAN
CAN1IER = 0;
CAN1GSR = 0; // Reset error counter when CANxMOD is in reset
CAN1BTR = CAN_CanChannelConf[u8ChaNo].u32BaudRate;
CAN1IER = 0x01;
CAN1MOD = 0x0; // CAN in normal operation mode
break;
case CAN_CHANNEL2:
CAN2MOD = 1; // Reset CAN
CAN2IER = 0;
CAN2GSR = 0; // Reset error counter when CANxMOD is in reset
CAN2BTR = CAN_CanChannelConf[u8ChaNo].u32BaudRate;
CAN2IER = 0x01;
CAN2MOD = 0x0; // CAN in normal operation mode
break;
default:
return 0; // illegal value used
}
return 1;
}
uint32 CAN_Init(void)
{
/* Initialisation of CAN module */
CAN_InitModule();
/* init channel 0 */
CAN_InitChannel(CAN_CHANNEL1);
/* init channel 1 */
CAN_InitChannel(CAN_CHANNEL2);
#ifdef DEBUG
printf("CAN1BTR= %x,CAN1IER = %x,CAN1GSR = %x CAN1MOD = %u \n",CAN1BTR,CAN1IER,CAN1GSR,CAN1MOD);
printf("CAN2BTR= %x,CAN2IER = %x,CAN2GSR = %x CAN2MOD = %x CAN_AFMR =%x\n",CAN2BTR,CAN2IER,CAN2GSR,CAN2MOD,CAN_AFMR);
#endif
return( TRUE );
}
uint16 CAN_TxMessage(uint8 u8Handle,uint8* pu8Buff)
{
if(CAN_CanTxConf[u8Handle].u8Channel == CAN_CHANNEL1)
{
if (!(CAN1SR & 0x00000004L))
{ return 0; // No channel available
}
CAN1TFI1 = ((((uint32)CAN_CanTxConf[u8Handle].u8DLC)<<16) | CAN_CanTxConf[u8Handle].u32IsRtrExtd) & 0xC00F0000L;
CAN1TID1 = CAN_CanTxConf[u8Handle].u32CanId;
CAN1TDA1 = *(uint32*)pu8Buff;
CAN1TDB1 = *((uint32*)(pu8Buff+4));
CAN1CMR = 0x21;
return 1;
}
else if(CAN_CanTxConf[u8Handle].u8Channel == CAN_CHANNEL2)
{
if (!(CAN2SR & 0x00000004L))
{ return 0; // No channel available
}
CAN2TFI1 = ((((uint32)CAN_CanTxConf[u8Handle].u8DLC)<<16) | CAN_CanTxConf[u8Handle].u32IsRtrExtd) & 0xC00F0000L;
CAN2TID1 = CAN_CanTxConf[u8Handle].u32CanId;
CAN2TDA1 = *(uint32*)pu8Buff;
CAN2TDB1 = *((uint32*)(pu8Buff+4));
CAN2CMR = 0x21;
return 1;
}
else
{
return (0);
}
}
void CAN_IsrRx1(void)
{
uint8 u8Count;
#ifdef DEBUG
printf("CAN_IsrRx1\n");
#endif
FIO2PIN = 0x00000001;
for(u8Count=0; u8Count < CAN_MAX_RX_MSG ; u8Count++)
{
if(CAN_CanRxConf[u8Count].u32Id == CAN1RID)
{
CAN_CanRxBuffer[u8Count].u8Channel = CAN_CHANNEL1;
CAN_CanRxBuffer[u8Count].u8DLC = (CAN1RFS & 0x000F0000)>>16;
*((uint32*)&CAN_CanRxBuffer[u8Count].u8Data[0]) = CAN1RDA;
*((uint32*)&CAN_CanRxBuffer[u8Count].u8Data[4]) = CAN1RDB;
CAN_CanRxBuffer[u8Count].u8RxFlag = 1;
break;
}
}
CAN_CanRxBuffer[u8Count].u8RxFlag = 1;
CAN1CMR = 0x04; // release receive buffer
}
void CAN_IsrRx2(void)
{
uint8 u8Count;
#ifdef DEBUG
printf("CAN_IsrRx2\n");
#endif
FIO2PIN = 0x00000002; /* turn off all the LEDs */
for(u8Count=0; u8Count < CAN_MAX_RX_MSG ; u8Count++)
{
if(CAN_CanRxConf[u8Count].u32Id == CAN2RID)
{
CAN_CanRxBuffer[u8Count].u8Channel = CAN_CHANNEL1;
CAN_CanRxBuffer[u8Count].u8DLC = (CAN2RFS & 0x000F0000)>>16;
*((uint32*)&CAN_CanRxBuffer[u8Count].u8Data[0]) = CAN2RDA;
*((uint32*)&CAN_CanRxBuffer[u8Count].u8Data[4]) = CAN2RDB;
CAN_CanRxBuffer[u8Count].u8RxFlag = 1;
break;
}
}
CAN_CanRxBuffer[u8Count].u8RxFlag = 1;
CAN2CMR = 0x04; // release receive buffer
}
void CAN_ISR(void) __attribute__ ((interrupt ("IRQ")))
{
#ifdef DEBUG
printf("CAN1BTR= %x,CAN1IER = %x,CAN1GSR = %x CAN1SR = %x\n",CAN1BTR,CAN1IER,CAN1GSR,CAN1SR);
printf("CAN2BTR= %x,CAN2IER = %x,CAN2GSR = %x CAN2SR = %x\n",CAN2BTR,CAN2IER,CAN2GSR,CAN2SR);
#endif
if ( CAN_RX_SR & (1 << 8) )
{
CAN_u32CAN1RxCount++;
CAN_IsrRx1();
}
if ( CAN_RX_SR & (1 << 9) )
{
CAN_u32CAN2RxCount++;
CAN_IsrRx2();
}
if ( CAN1GSR & (1 << 6 ) )
{
CAN_u32CAN1ErrCount = (CAN1GSR >> 16 );
}
if ( CAN2GSR & (1 << 6 ) )
{
CAN_ulCAN2ErrCount = (CAN2GSR >> 16 );
}
ISR_DONE(); /* Acknowledge Interrupt */
}