?? bsp_can.c
字號:
/****************************************************************************
FILE BSP_CAN.C - (hardware dependent)
VERSION 1.00
AUTHORS Patrice Vilchez (Europe Technologies)
Frederic SAMSON (Europe Technologies)
COPYRIGHT (c) Europe Technologies
COMMERCIAL IN CONFIDENCE
CONTAINS Structure and Enum Definitions and Standard Typedef
for CAN Package
MODIFICATION HISTORY
* 1 29/06/2000 Patrice Vilchez
- Initial File
* 1 16/07/2001 Frederic SAMSON
- Clean Up : Add BSP_CANConfigMailbox,
BIOS_Can_Status_a_s modified to BSP_Can_Status_a_s
Add initialisations in BSP_CANInit
Remove configuration of STANBY mode.
Update BSP_CANConfigActiveMode
* 002 MOD 31/01/02 Mahmoud Mesgarzadeh Clean Up
****************************************************************************/
#include <string.h>
#include "csp.h"
#include "bsp.h"
/****************************************************************************
* BSP CAN Object Declatation
****************************************************************************/
BSP_CAN_STATUS_T BSP_CanStatus_a_s[(U8_T) BSP_NB_CAN_IO];
/****************************************************************************
Function : BSP_CANInit
Description :
Inputs :
Returns : None
****************************************************************************/
void BSP_CANInit(void)
{
/* Local Variable */
U8_T i_u8;
U8_T j_u8;
/* CAN Configuration Data Initialisation */
for(i_u8=0; i_u8<BSP_NB_CAN_IO; i_u8++)
{
BSP_CanStatus_a_s[i_u8].can_mode_u32 = BSP_CANMode_a_u32[i_u8];
BSP_CanStatus_a_s[i_u8].can_controller_u32 = BSP_CANController_a_u32[i_u8];
BSP_CanStatus_a_s[i_u8].ack_limit_u8 = BSP_CANAckLimit_a_u8[i_u8];
BSP_CanStatus_a_s[i_u8].number_of_mailbox_u8 = BSP_CANNumberOfMailbox[i_u8];
BSP_CanStatus_a_s[i_u8].ack_counter_u8 = 0;
BSP_CanStatus_a_s[i_u8].transmit_u8 = 0;
BSP_CanStatus_a_s[i_u8].queue.tx_tailptr = 0;
BSP_CanStatus_a_s[i_u8].queue.tx_headptr = 0;
BSP_CanStatus_a_s[i_u8].queue.rx_tailptr = 0;
BSP_CanStatus_a_s[i_u8].queue.rx_headptr = 0;
/* Init CAN Controller */
CSP_CANInit((CSP_CAN_PTR)BSP_CanStatus_a_s[i_u8].can_controller_u32, BSP_CanStatus_a_s[i_u8].can_mode_u32);
/* Configure General Transmit Mailbox */
CSP_CANChannelConfigInterrupt((CSP_CAN_PTR)BSP_CanStatus_a_s[i_u8].can_controller_u32, 0, (TXOK|ACK));
/* Configure General Receive Mailbox */
CSP_CANReceive((CSP_CAN_PTR)BSP_CanStatus_a_s[i_u8].can_controller_u32, (BSP_CanStatus_a_s[i_u8].number_of_mailbox_u8 - 1), 0, 0x1FFFFFFF, (8|OVERWRITE));
CSP_CANChannelConfigInterrupt((CSP_CAN_PTR)BSP_CanStatus_a_s[i_u8].can_controller_u32, (BSP_CanStatus_a_s[i_u8].number_of_mailbox_u8 - 1), RXOK);
BSP_CanStatus_a_s[i_u8].mailbox_status[BSP_CanStatus_a_s[i_u8].number_of_mailbox_u8 - 1].identifier_mask = 0x1FFFFFFF ;
/* General Receive & General Transmit Used */
BSP_CanStatus_a_s[i_u8].mailboxes_available = ( (1 << BSP_CanStatus_a_s[i_u8].number_of_mailbox_u8) - 1);
BSP_CanStatus_a_s[i_u8].mailboxes_used = (1 | (1 << (BSP_CanStatus_a_s[i_u8].number_of_mailbox_u8 - 1)));
BSP_CanStatus_a_s[i_u8].mailboxes_available &= ~(1 | (1 << (BSP_CanStatus_a_s[i_u8].number_of_mailbox_u8 - 1)));
/* Initialize Mailbox Status */
for(j_u8=1; j_u8<(BSP_CanStatus_a_s[i_u8].number_of_mailbox_u8 - 1); j_u8++)
{
BSP_CanStatus_a_s[i_u8].mailbox_status[j_u8].mailbox_valid = 1;
}
}
}
/****************************************************************************
Function : BSP_CANConfigActiveMode
Description :
Inputs :
Returns : None
****************************************************************************/
void BSP_CANConfigActiveMode(BSP_CAN_IO_E can_io)
{
/* Local Variable */
CSP_CAN_PTR can_controller_ptr;
U32_T can_general_callback;
/* Get Current CAN Controller */
can_controller_ptr = (CSP_CAN_PTR) BSP_CanStatus_a_s[can_io].can_controller_u32;
/* Get Appropriate Callback Function */
switch( can_io )
{
case CAN0_IO:
can_general_callback = (U32_T) BSP_CAN0AsmInterruptHandler;
break;
case CAN1_IO:
can_general_callback = (U32_T) BSP_CAN1AsmInterruptHandler;
break;
case CAN2_IO:
can_general_callback = (U32_T) BSP_CAN2AsmInterruptHandler;
break;
default:
break;
}
/* Configure CAN Controller General Interrupt */
CSP_CANConfigInterrupt(can_controller_ptr, (HIGH_LEVEL_SENSITIVE | PRIOR_2), 0, can_general_callback);
/* Start CAN */
CSP_CANEnable(can_controller_ptr);
}
/****************************************************************************
Function : BSP_CANSendPacket
Description : CAN Send Packet
:
Inputs : None
Returns : None
****************************************************************************/
void BSP_CANSendPacket(BSP_CAN_IO_E can_io)
{
/* Local Variables */
BSP_CAN_PKT_T *can_pkt;
U8_T *tx_tailptr;
U8_T *tx_headptr;
/* Get Current head & tail pointers in Tx Queue */
tx_tailptr = &(BSP_CanStatus_a_s[can_io].queue.tx_tailptr);
tx_headptr = &(BSP_CanStatus_a_s[can_io].queue.tx_headptr);
/* Get Current Tx Packet in Tx Queue */
can_pkt = &(BSP_CanStatus_a_s[can_io].queue.tx_queue[*tx_tailptr]);
/* Check if the Trasmit Queue is Empty (no more frame to send) */
if( *tx_headptr != *tx_tailptr )
{
/* Copy Data to Send In CAN Mailbox*/
CSP_CAN_CHANNEL_SET_DRA((CSP_CAN_PTR)(BSP_CanStatus_a_s[can_io].can_controller_u32), GENERAL_TRANSMIT, *(U32_T *)(&(can_pkt->data[0])));
CSP_CAN_CHANNEL_SET_DRB((CSP_CAN_PTR)(BSP_CanStatus_a_s[can_io].can_controller_u32), GENERAL_TRANSMIT, *(U32_T *)(&(can_pkt->data[4])));
/* Set Idetifier Field */
CSP_CAN_CHANNEL_SET_IR(((CSP_CAN_PTR)(BSP_CanStatus_a_s[can_io].can_controller_u32)), GENERAL_TRANSMIT, ((can_pkt->identifier & 0x1FFC0000 ) >> 18) | ((can_pkt->identifier & 0x3FFFF) << 11));
/* Send Data (Extended Format) */
CSP_CAN_CHANNEL_SET_CR(((CSP_CAN_PTR)(BSP_CanStatus_a_s[can_io].can_controller_u32)), GENERAL_TRANSMIT, ( CHANEN | IDE | PCB | ( can_pkt->length & DLC_MASK)));
/* Increment Tail Pointer to the next packet to send*/
(*tx_tailptr)++;
(*tx_tailptr) %= BSP_CAN_TX_QUEUE_SIZE;
}
}
/****************************************************************************
Function : BSP_CAN0InterruptHandler
Description :
Inputs :
Returns : None
****************************************************************************/
void BSP_CAN0InterruptHandler(void)
{
/* Local Variables */
BSP_CAN_PKT_T can_pkt;
U8_T i;
/* Check Bus Off Interrupt */
if( (CSP_CAN_GET_SR(CAN0) & BUSOFF & CSP_CAN_GET_IMR(CAN0)) != 0 )
{
CSP_CAN_SET_CSR(CAN0, BUSOFF);
//BSP_CanStatus_a_s[0].bus_off = 1;
}
else
{
/* Check General Receive Interrupt */
if( (CSP_CAN_GET_ISSR(CAN0) & (1 << 15) & CSP_CAN_GET_SIMR(CAN0)) != 0 )
{
CSP_CAN_SET_CISR(CAN0, (1 << 15));
BSP_CAN0MBX15InterruptHandler();
}
/* Check General Transmit Interrupt */
if( (CSP_CAN_GET_ISSR(CAN0) & (1 << 0) & CSP_CAN_GET_SIMR(CAN0)) != 0 )
{
CSP_CAN_SET_CISR(CAN0,(1 << 0));
BSP_CAN0MBX0InterruptHandler();
}
/* Check Which Channel Produce an Interrupt */
for(i=1; i<15; i++)
{
if( (CSP_CAN_GET_ISSR(CAN0) & (1 << i) & CSP_CAN_GET_SIMR(CAN0)) != 0 )
{
/* Clear Interrupt Flag */
CSP_CAN_SET_CISR(CAN0,(1 << i));
/* Get packet length */
can_pkt.length = CSP_CAN_CHANNEL_GET_CR(CAN0, i) & 0x0F ;
/* Copy Data */
memcpy((U8_T*)(&(can_pkt.data[0])), (U8_T *)(&(CSP_CAN_CHANNEL_GET_DRA(CAN0, i))), (8 * sizeof(U8_T)) );
/* Get Idetifier Field */
can_pkt.identifier = (( CSP_CAN_CHANNEL_GET_IR(CAN0, i) & 0x7FF ) << 18) | ((CSP_CAN_CHANNEL_GET_IR(CAN0, i) & 0x1FFFF800) >> 11);
/* Set Message Waiting Flag */
BSP_CanStatus_a_s[CAN0_IO].mailbox_status[i].message_waiting = 1;
memcpy((U8_T*)(&(BSP_CanStatus_a_s[CAN0_IO].mailbox_status[i].data[0])), (U8_T *)(&(CSP_CAN_CHANNEL_GET_DRA(CAN0, i))), (8 * sizeof(U8_T)));
/* Call BIOS CAN Mailbox Callback */
(BSP_CanStatus_a_s[CAN0_IO].mailbox_status[i].mailbox_function)(&can_pkt);
/* Restart Reception */
CSP_CAN_CHANNEL_SET_CR(CAN0, i, 0x98);
}
}
}
}
/****************************************************************************
Function : BSP_CAN1InterruptHandler
Description :
Inputs :
Returns : None
****************************************************************************/
void BSP_CAN1InterruptHandler(void)
{
/* Local Variables */
BSP_CAN_PKT_T can_pkt;
U8_T i;
/* Check Bus Off Interrupt */
if( (CSP_CAN_GET_SR(CAN1) & BUSOFF & CSP_CAN_GET_IMR(CAN1)) != 0 )
{
CSP_CAN_SET_CSR(CAN1, BUSOFF);
// BIOS_CanStatus_a_s[J1939].bus_off = 1;
}
else
{
/* Check General Receive Interrupt */
if( (CSP_CAN_GET_ISSR(CAN1) & (1 << 15) & CSP_CAN_GET_SIMR(CAN1)) != 0 )
{
CSP_CAN_SET_CISR(CAN1, (1 << 15));
BSP_CAN1MBX15InterruptHandler();
}
/* Check General Transmit Interrupt */
if( (CSP_CAN_GET_ISSR(CAN1) & (1 << 0) & CSP_CAN_GET_SIMR(CAN1)) != 0 )
{
CSP_CAN_SET_CISR(CAN1,(1 << 0));
BSP_CAN1MBX0InterruptHandler();
}
/* Check Which Channel Produce an Interrupt */
for(i=1; i<15; i++)
{
if( (CSP_CAN_GET_ISSR(CAN1) & (1 << i) & CSP_CAN_GET_SIMR(CAN1)) != 0 )
{
/* Clear Interrupt Flag */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -