⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bsp_can.c

📁 IAR 平台ATMEL 的例程, 和说明
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
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 + -