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

📄 can_at91sam7.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 5 页
字号:
//==========================================================================
//
//      devs/can/arm/at91sam7x/current/src/can_at91sam7x.c
//
//      CAN driver for Atmel AT91SAM7X microcontrollers
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2003 Gary Thomas
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):    Uwe Kindler
// Contributors: Uwe Kindler
// Date:         2007-01-06
// Purpose:      Support at91sam7 on-chip CAN moduls
// Description: 
//
//####DESCRIPTIONEND####
//
//==========================================================================


//==========================================================================
//                              INCLUDES
//==========================================================================
#include <pkgconf/system.h>
#include <pkgconf/io_can.h>
#include <pkgconf/io.h>
#include <pkgconf/devs_can_at91sam7.h>

#include <cyg/infra/diag.h>

#include <cyg/io/io.h>
#include <cyg/io/devtab.h>
#include <cyg/io/can.h>

#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/hal_io.h>

#include <cyg/hal/hal_diag.h>
#include <cyg/infra/cyg_ass.h>


//===========================================================================
//                                DEFINES  
//===========================================================================

//
// Support debug output if this option is enabled in CDL file
//
#ifdef CYGDBG_DEVS_CAN_AT91SAM7_DEBUG
#define AT91SAM7_DBG_PRINT diag_printf
#else
#define AT91SAM7_DBG_PRINT( fmt, ... )
#endif


//
// we define our own set of register bits in order to be independent from
// platform specific names
//

//---------------------------------------------------------------------------
// Mailbox bits
//
#define BIT_MB0            (0x01 << 0)
#define BIT_MB1            (0x01 << 1)
#define BIT_MB2            (0x01 << 2)
#define BIT_MB3            (0x01 << 3)
#define BIT_MB4            (0x01 << 4)
#define BIT_MB5            (0x01 << 5)
#define BIT_MB6            (0x01 << 6)
#define BIT_MB7            (0x01 << 7)


//---------------------------------------------------------------------------
// CAN Mode Register bits (CAN_MR)
//
#define MR_CAN_ENABLE      (0x01 << 0)
#define MR_LOW_POWER       (0x01 << 1)
#define MR_AUTOBAUD        (0x01 << 2)
#define MR_OVERLOAD        (0x01 << 3)
#define MR_TIMESTAMP_EOF   (0x01 << 4)
#define MR_TIME_TRIG       (0x01 << 5)
#define MR_TIMER_FREEZE    (0x01 << 6)
#define MR_DISABLE_REPEAT  (0x01 << 7)


//---------------------------------------------------------------------------
// CAN Interrupt Enable/Disable, Mask and Status Register bits (CAN_IER, CAN_IDR, CAN_IMR)
//
#define INT_ERR_ACTIVE     (0x01 << 16)
#define INT_WARN           (0x01 << 17)
#define INT_ERR_PASSIVE    (0x01 << 18)
#define INT_BUS_OFF        (0x01 << 19)
#define INT_SLEEP          (0x01 << 20)
#define INT_WAKEUP         (0x01 << 21)
#define INT_TMR_OVF        (0x01 << 22)
#define INT_TIMESTAMP      (0x01 << 23)
#define INT_CRC_ERR        (0x01 << 24)
#define INT_STUFF_ERR      (0x01 << 25)
#define INT_ACKN_ERR       (0x01 << 26)
#define INT_FORM_ERR       (0x01 << 27)
#define INT_BIT_ERR        (0x01 << 28)
#define INT_MB              0xFF        // message box intterupt (mbox 1 - 8)
#define INT_MB_RX           0x7F        // rx message box interrupts
#define INT_MB_TX           0x80        // tx message box interrupts

//
// We do not enable INT_WARN by default because this flug is buggy and causes interrupts
// event if no counter reached warning level.
//
#define INT_ALL_ERR        (INT_CRC_ERR | INT_STUFF_ERR | INT_ACKN_ERR | INT_FORM_ERR | INT_BIT_ERR)
#define INT_DEFAULT        (INT_ERR_PASSIVE | INT_BUS_OFF | INT_SLEEP | INT_WAKEUP | INT_ALL_ERR)


//
// these bits are only in status register (CAN_SR)
//
#define SR_RX_BUSY         (0x01 << 29)
#define SR_TX_BUSY         (0x01 << 30)
#define SR_OVL_BUSY        (0x01 << 31)


//---------------------------------------------------------------------------
// CAN Baudrate Register (CAN_BR)
//
#define BR_PHASE2_BITMASK  0x00000007
#define BR_PHASE1_BITMASK  0x00000070
#define BR_PROPAG_BITMASK  0x00000700
#define BR_SJW_BITMASK     0x00003000
#define BR_BRP_BITMASK     0x007F0000
#define BR_SMP_BITMASK     0x01000000


//---------------------------------------------------------------------------
// CAN Error Counter Register (CAN_ECR)
//
#define ECR_GET_TEC(_ecr_) (((_ecr_) >> 16) & 0xFF)
#define ECR_GET_REC(_ecr_) ((_ecr_) & 0xFF)


//---------------------------------------------------------------------------
// CAN Transfer Command Resgister (CAN_TCR)
//
#define TCR_TMR_RESET      0x80000000


//---------------------------------------------------------------------------
// CAN Message Mode Register (CAN_MMRx)
//
#define MMR_TIMEMARK_BITMASK 0x0000FFFF
#define MMR_PRIOR_BITMASK    0x000F0000

#define MMR_MB_SHIFTER       24
#define MMR_MB_TYPE_BITMASK  (0x07 << MMR_MB_SHIFTER) // mask the mot bits
#define MMR_MB_TYPE_DISABLED (0x00 << MMR_MB_SHIFTER) // message box disabled
#define MMR_MB_TYPE_RX       (0x01 << MMR_MB_SHIFTER) // rx message box
#define MMR_MB_TYPE_RX_OVW   (0x02 << MMR_MB_SHIFTER) // rx message box with overwrite
#define MMR_MB_TYPE_TX       (0x03 << MMR_MB_SHIFTER) // tx message box
#define MMR_MB_TYPE_CONSUME  (0x04 << MMR_MB_SHIFTER) // consumer - receives RTR and sends its content
#define MMR_MB_TYPE_PRODUCE  (0x05 << MMR_MB_SHIFTER) // producer - sends a RTR and waits for answer
#define MMR_MB_GET_TYPE(_mb_) ((_mb_) &  MMR_MB_TYPE_BITMASK)

//---------------------------------------------------------------------------
// CAN Message Acceptance Mask/ID Register (CAN_MAMx, CAN_MIDx)
//
#define MID_MIDvB_BITMASK    0x0003FFFF
#define MID_MIDvA_BITMASK    0x1FFC0000
#define MID_MIDE             0x20000000
#define MID_MIDvA_SHIFTER    18
#define MID_SET_STD(_id_)    (((_id_) << MID_MIDvA_SHIFTER) & MID_MIDvA_BITMASK)
#define MID_SET_EXT(_id_)    ((_id_) | MID_MIDE)
#define MAM_SET_STD          ((((0x7FF << MID_MIDvA_SHIFTER) & MID_MIDvA_BITMASK) | MID_MIDE))
#define MAM_SET_EXT          0xFFFFFFFF
#define MID_GET_STD(_mid_)   (((_mid_) >> MID_MIDvA_SHIFTER) &  CYG_CAN_STD_ID_MASK)
#define MID_GET_EXT(_mid_)   ((_mid_) & CYG_CAN_EXT_ID_MASK)


//---------------------------------------------------------------------------
// CAN Message Status Register (CAN_MSRx)
//
#define MSR_TIMESTAMP      0x0000FFFF
#define MSR_DLC            0x000F0000
#define MSR_RTR            0x00100000
#define MSR_MSG_ABORT      0x00400000
#define MSR_RDY            0x00800000
#define MSR_MSG_IGNORED    0x01000000
#define MSR_DLC_SHIFTER    16
#define MSR_DLC_GET(_msr_) (((_msr_) >> 16) & 0x0F)

//---------------------------------------------------------------------------
// CAN Message Control Register (CAN_MCRx)
//
#define MCR_DLC          0x000F0000 // MDLC
#define MCR_RTR          0x00100000 // MRTR
#define MCR_MSG_ABORT    0x00400000 // MACR
#define MCR_TRANSFER_CMD 0x00800000 // MTCR
#define MCR_DLC_SHIFTER 16
#define MCR_DLC_CREATE(_len_) ((_len_) << MCR_DLC_SHIFTER)

//---------------------------------------------------------------------------
// CAN Module Register Layout
//
#define CANREG_MR         0x0000
#define CANREG_IER        0x0004
#define CANREG_IDR        0x0008
#define CANREG_IMR        0x000C
#define CANREG_SR         0x0010
#define CANREG_BR         0x0014
#define CANREG_TIM        0x0018
#define CANREG_TIMESTAMP  0x001C
#define CANREG_ECR        0x0020
#define CANREG_TCR        0x0024
#define CANREG_ACR        0x0028

#define CANREG_MB_BASE    0x0200

//
// Register layout of message box relativ to base register of a certain
// message box
//
#define CANREG_MMR     0x0000
#define CANREG_MAM     0x0004
#define CANREG_MID     0x0008
#define CANREG_MFID    0x000C
#define CANREG_MSR     0x0010
#define CANREG_MDL     0x0014
#define CANREG_MDH     0x0018
#define CANREG_MCR     0x001C


#define AT91SAM7_CAN_PERIPHERAL_ID 15
#define CAN_MBOX_MIN                0
#define CAN_MBOX_MAX                7
#define CAN_MBOX_CNT                8
#define CAN_MBOX_RX_MIN             0
#define CAN_MBOX_RX_MAX             (CAN_MBOX_MAX - 1) // one message box is tx
#define CAN_MBOX_RX_CNT             (CAN_MBOX_CNT - 1) // one message box is tx 

#define CAN_MR(_extra_)         (CAN_BASE(_extra_) + CANREG_MR)
#define CAN_IER(_extra_)        (CAN_BASE(_extra_) + CANREG_IER)
#define CAN_IDR(_extra_)        (CAN_BASE(_extra_) + CANREG_IDR)
#define CAN_IMR(_etxra_)        (CAN_BASE(_extra_) + CANREG_IMR)
#define CAN_SR(_etxra_)         (CAN_BASE(_extra_) + CANREG_SR)
#define CAN_BR(_etxra_)         (CAN_BASE(_extra_) + CANREG_BR)
#define CAN_TIM(_etxra_)        (CAN_BASE(_extra_) + CANREG_TIM)
#define CAN_TIMESTAMP(_etxra_)  (CAN_BASE(_extra_) + CANREG_TIMESTAMP)
#define CAN_ECR(_etxra_)        (CAN_BASE(_extra_) + CANREG_ECR)
#define CAN_TCR(_etxra_)        (CAN_BASE(_extra_) + CANREG_TCR)
#define CAN_ACR(_etxra_)        (CAN_BASE(_extra_) + CANREG_ACR) 

//
// Message box registers
//
#define CAN_MB_BASE(_extra_)       (CAN_BASE(_extra_) + CANREG_MB_BASE)
#define CAN_MB_MMR(_extra_, _mb_)  (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MMR)
#define CAN_MB_MAM(_extra_, _mb_)  (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MAM)
#define CAN_MB_MID(_extra_, _mb_)  (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MID)
#define CAN_MB_MFID(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MFID)
#define CAN_MB_MSR(_extra_, _mb_)  (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MSR)
#define CAN_MB_MDL(_extra_, _mb_)  (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MDL)
#define CAN_MB_MDH(_extra_, _mb_)  (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MDH)
#define CAN_MB_MCR(_extra_, _mb_)  (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MCR)


//---------------------------------------------------------------------------
// Optimize for the case of a single CAN channel, while still allowing
// multiple channels. At the moment only AT91SAM7 controllers with one
// CAN channel are known.
//
#if CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS == 1

#define CAN_PID(_extra_)            AT91SAM7_CAN_PERIPHERAL_ID
#define CAN_ISRVEC(_extra_)         CAN_PID(_extra_)
#define CAN_ISRPRIO(_extra_)        CYGNUM_DEVS_CAN_AT91SAM7_CAN0_ISR_PRIORITY
#define CAN_BASE(_extra_)           AT91_CAN
#define CAN_DECLARE_INFO(_chan_)
#define CAN_MBOX_TX(_extra_)        CYGNUM_DEVS_CAN_AT91SAM7_CAN0_DEFAULT_TX_MBOX
#define CAN_MBOX_STD_CNT(_extra_)   CYGNUM_DEVS_CAN_AT91SAM7_CAN0_STD_MBOXES
#define CAN_MBOX_EXT_CNT(_extra_)   CYGNUM_DEVS_CAN_AT91SAM7_CAN0_EXT_MBOXES
#define CAN_MBOX_RX_ALL_CNT(_extra) (CAN_MBOX_STD_CNT(_extra_) + CAN_MBOX_EXT_CNT(_extra_))

#ifndef CYGNUM_DEVS_CAN_AT91SAM7_CAN0_STD_MBOXES
#define CYGNUM_DEVS_CAN_AT91SAM7_CAN0_STD_MBOXES 0
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -