📄 lpc2000_can_driver.c
字号:
// Transmit_TxBuf_Start = 0x32; // Single Self-Testing mode
break;
case 2: Transmit_TxBuf_Start = 0x41; // Transmit by Tx2
// Transmit_TxBuf_Start = 0x43; // Single transmit in spite of successful
// Transmit_TxBuf_Start = 0x50; // Self-Testing mode, CAN1MOD:STM should be "1"
// Transmit_TxBuf_Start = 0x52; // Single Self-Testing mode
break;
case 3: Transmit_TxBuf_Start = 0x81; // Transmit by Tx3
// Transmit_TxBuf_Start = 0x83; // Single transmit in spite of successful
// Transmit_TxBuf_Start = 0x90; // Self-Testing mode, CAN1MOD:STM should be "1"
// Transmit_TxBuf_Start = 0x92; // Single Self-Testing mode
break;
default:return (LPC2000_CANDRIVER_ERR_WRONG_CAN_TxBUFFER_NUMBER);
// break;
}
// Read Global Status Register
switch (canChannel)
{
case 1: TransmitBufferStatus = CAN1SR;
break;
case 2: TransmitBufferStatus = CAN2SR;
break;
// case 3: TransmitBufferStatus = CAN3SR;
// break;
// case 4: TransmitBufferStatus = CAN4SR;
// break;
default:return (LPC2000_CANDRIVER_ERR_WRONG_CAN_CHANNEL_NUMBER);
}
switch (txbuffer)
{
case 1: TransmitBufferFree = TransmitBufferStatus & 0x0000000C; //c 发送完了
if (TransmitBufferFree == 0) // one of Two(TBS,TCS) fits will pass
{
return (LPC2000_CANDRIVER_ERR_TRANSMIT_BUFFER1_NOT_FREE);
}
break;
case 2: TransmitBufferFree = TransmitBufferStatus & 0x00000C00;
if (TransmitBufferFree == 0)
{
return (LPC2000_CANDRIVER_ERR_TRANSMIT_BUFFER2_NOT_FREE);
}
break;
case 3: TransmitBufferFree = TransmitBufferStatus & 0x000C0000;
if (TransmitBufferFree == 0)
{
return (LPC2000_CANDRIVER_ERR_TRANSMIT_BUFFER3_NOT_FREE);
}
break;
default:// wrong txbuffer number
return (LPC2000_CANDRIVER_ERR);
}
switch (canChannel) // CAN Channel
{
// CAN Channel 1
case 1: Address_TFI_ID_DATA = (UInt32)&CAN1TFI1 + TXB_Offset; //TF1/2/3 30/40/50
Address_CMR = (UInt32)&CAN1CMR;
Address_GSR = (UInt32)&CAN1GSR;
break;
// CAN Channel 2
case 2: Address_TFI_ID_DATA = (UInt32)&CAN1TFI1 + 0x00004000 + TXB_Offset;
Address_CMR = (UInt32)&CAN1CMR + 0x00004000;
Address_GSR = (UInt32)&CAN1GSR + 0x00004000;
break;
// CAN Channel 3
// case 3: Address_TFI_ID_DATA = (UInt32)&CAN1TFI1 + 0x00008000 + TXB_Offset;
// Address_CMR = (UInt32)&CAN1CMR + 0x00008000;
// Address_GSR = (UInt32)&CAN1GSR + 0x00008000;
// break;
// CAN Channel 4
// case 4: Address_TFI_ID_DATA = (UInt32)&CAN1TFI1 + 0x0000C000 + TXB_Offset;
// Address_CMR = (UInt32)&CAN1CMR + 0x0000C000;
// Address_GSR = (UInt32)&CAN1GSR + 0x0000C000;
// break;
default: // wrong channel number
return (LPC2000_CANDRIVER_ERR_WRONG_CAN_CHANNEL_NUMBER);
}
// Copy message contents into local variable(s)
OUTW( Address_TFI_ID_DATA + 0, pTransmitBuf -> TFI);
OUTW( Address_TFI_ID_DATA + 4, pTransmitBuf -> ID); //CANxTID
OUTW( Address_TFI_ID_DATA + 8, pTransmitBuf -> DataField[0]); //CANxTDA
OUTW( Address_TFI_ID_DATA +12, pTransmitBuf -> DataField[1]); //CANxTDB
OUTB( Address_CMR, Transmit_TxBuf_Start ); //Requst transmit
while ( (INW(Address_GSR) & 0x0048) == 0x0000 ); // Wait Trans successed or error counter reach limit
if( (INW(Address_GSR) & 0x0040) == 0x0040 ) // if error, stop transmit
{ // for demo used, stop screen roll
OUTB( Address_CMR, 0x02 );
}
Print_Chars_to_Screen(LiuJiaju_Send) ;
return (LPC2000_CANDRIVER_OK);
} // lpc2000CANdriver_PrepareTransmitMessage;
// **************************************************************************
// FUNCTION: lpc2000CANdriver_ReceiveMessageCh2
//
// DESCRIPTION: This function reads the received CAN message and stores
// the data in the CPU User RAM
//
// GLOBAL VARIABLES USED:
//
// PARAMETERS:
//
// RETURN: CanStatusCode: Status of operation
//
// LPC2000_CANDRIVER_OK - successful
//
// **************************************************************************
CanStatusCode
lpc2000CANdriver_ReceiveMessageCh2 (plpc2000CANdriver_RXObj_t pReceiveBuf)
{
// CAN Channe1 1 2吧
pReceiveBuf -> FULLCALmsg = 0;
pReceiveBuf -> RFS = CAN2RFS;
pReceiveBuf -> ID = CAN2RID;
pReceiveBuf -> DataField[0] = CAN2RDA;
pReceiveBuf -> DataField[1] = CAN2RDB;
// Release Receive Buffer
CAN2CMR = 0x04; // Release Rx Buffer
return (1);
} // lpc2000CANdriver_ReceiveMessageCh0;
// **************************************************************************
// FUNCTION: lpc2000CANdriver_LoadAcceptanceFilter
//
// DESCRIPTION: The function lpc2000hwCANdriver_LoadAcceptanceFilter configures
// the Acceptance Filter Memory.
// In addition to the filter memory configuration, this
// function also configures the acceptance filter start address
// registers according to the number of CAN identifiers.
//
// GLOBAL VARIABLES USED:
//
// PARAMETERS:
//
// RETURN: CanStatusCode: Status of operation
//
// LPC2000_CANDRIVER_OK - successful
//
// LPC2000_CANDRIVER_ERR - not successful -> table error
// **************************************************************************
CanStatusCode
lpc2000CANdriver_LoadAcceptanceFilter(void)
{
UInt32 address;
UInt32 memory_address;
UInt32 IDcount;
UInt32 i;
UInt32 acfword_pre;
UInt32 acfword_upper;
UInt32 acfword_lower;
address =0;
// ----------------------------------------------------------
// ---------- Fill Standard FULLCAN Section ------------
// ----------------------------------------------------------
#ifdef LPC2000_CANDRIVER_STD_FULLCAN //entry FullCAN identify
//填表
IDcount = LPC2000_CANDRIVER_NUMBER_OF_STD_FULLCAN_IDS;
acfword_pre = 0;
i = 0;
while (IDcount != 0) //an10674 p9根据表的结构填
{
acfword_lower = (gklpc2000CANdriver_StdFULLCAN_Section[i].ID << 16)
+ (gklpc2000CANdriver_StdFULLCAN_Section[i].Channel << 29)
+ (1 << 27 ); //Enable the interrupt
IDcount--;
if (IDcount == 0)
{
// odd number of identifiers -> disable ID !
acfword_upper = 0x00001FFF
+ (gklpc2000CANdriver_StdFULLCAN_Section[i].Channel << 13);
}
else
{
acfword_upper = (gklpc2000CANdriver_StdFULLCAN_Section[i+1].ID)
+ (gklpc2000CANdriver_StdFULLCAN_Section[i+1].Channel << 13)
+ (1 << 11 ); //Enable the interrupt
IDcount--;
}
// Check ascending numerical order
if ((acfword_lower >> 16) >= acfword_upper)
{
// table error - violation of ascending numerical order
return(LPC2000_CANDRIVER_ERR_TABLE_ERROR_IN_STD_FULLCAN_SECTION);
}
else
{
if (acfword_pre >= (acfword_lower >> 16))
{
// table error - violation of ascending numerical order
return(LPC2000_CANDRIVER_ERR_TABLE_ERROR_IN_STD_FULLCAN_SECTION);
}
else
{
// write configuration into Acceptance Filter Memeory
OUTW( CAFMEM + address, acfword_lower + acfword_upper);
acfword_pre = acfword_upper;
}
}
// increment configuration table index
i = i + 2;
// next Acceptance Filter Memory address
address = address + 4;//32bit 4bytes
};
#endif
// ----------------------------------------------------------
// ---------- Fill Standard Individual Section ------------
// ----------------------------------------------------------
// Set Standard Frame Individual Startaddress
CAN_SFF_SA = address; //写完FULLCAN message ID,接着写
#ifdef LPC2000_CANDRIVER_STD_INDIVIDUAL //entry in individual standard identifier table
IDcount = LPC2000_CANDRIVER_NUMBER_OF_STD_INDIVIDUAL_IDS;
acfword_pre = 0;
i = 0;
while (IDcount != 0)
{
acfword_lower = (gklpc2000CANdriver_StdIndividualSection[i].ID << 16)
+ (gklpc2000CANdriver_StdIndividualSection[i].Channel << 29);
IDcount--;
if (IDcount == 0)
{
// odd number of identifiers -> disable ID !
acfword_upper = 0x00001FFF
+ (gklpc2000CANdriver_StdIndividualSection[i].Channel << 13);
}
else
{
acfword_upper = (gklpc2000CANdriver_StdIndividualSection[i+1].ID)
+ (gklpc2000CANdriver_StdIndividualSection[i+1].Channel << 13);
IDcount--;
}
// Check ascending numerical order
if ((acfword_lower >> 16) >= acfword_upper)
{
// table error - violation of ascending numerical order
return(LPC2000_CANDRIVER_ERR_TABLE_ERROR_IN_STD_INDIVIDUAL_SECTION);
}
else
{
if (acfword_pre >= (acfword_lower >> 16))
{
// table error - violation of ascending numerical order
return(LPC2000_CANDRIVER_ERR_TABLE_ERROR_IN_STD_INDIVIDUAL_SECTION);
}
else
{
// write configuration into Acceptance Filter Memeory
OUTW( CAFMEM + address, acfword_lower + acfword_upper);
acfword_pre = acfword_upper;
}
}
// increment configuration table index
i = i + 2;
// next Acceptance Filter Memory address
address = address + 4;
};
#endif
// Set Standard Frame Group Startaddress
CAN_SFF_GRP_SA = address;
// ----------------------------------------------------------
// ---------- Fill Standard Group Section -----------------
// ----------------------------------------------------------
#ifdef LPC2000_CANDRIVER_STD_GROUP
IDcount = LPC2000_CANDRIVER_NUMBER_OF_STD_GROUP_IDS;
acfword_pre = 0;
i = 0;
while (IDcount != 0)
{
acfword_lower = (gklpc2000CANdriver_StdGroupSection[i].ID << 16)
+ (gklpc2000CANdriver_StdGroupSection[i].Channel << 29);
IDcount--;
if (IDcount == 0)
{
// table error - odd number of identifiers
// not allowed for group definitions
return (LPC2000_CANDRIVER_ERR_TABLE_ERROR_IN_STD_GROUP_SECTION);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -