📄 can_lpc2xxx.c
字号:
//==========================================================================
//
// devs/can/arm/lpc2xxx/current/src/can_lpc2xxx.c
//
// CAN driver for LPC2xxx 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-04-09
// Purpose: Support LPC2xxx on-chip CAN moduls
// Description:
//
//####DESCRIPTIONEND####
//
//==========================================================================
//==========================================================================
// INCLUDES
//==========================================================================
#include <pkgconf/system.h>
#include <pkgconf/io_can.h>
#include <pkgconf/io.h>
#include <pkgconf/devs_can_lpc2xxx.h>
#include <cyg/infra/diag.h>
#include <cyg/io/io.h>
#include <cyg/io/devtab.h>
#include <cyg/io/can.h>
#include <cyg/io/can_lpc2xxx.h>
#include <cyg/io/can_lpc2xxx_baudrates.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
//===========================================================================
//
// Check if the macro HAL_LPC2XXX_GET_CAN_BR is provided
//
#ifndef HAL_LPC2XXX_GET_CAN_BR
#error "Macro HAL_LPC2XXX_GET_CAN_BR() missing"
#endif
//
// Support debug output if this option is enabled in CDL file
//
#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
#define LPC2XXX_DBG_PRINT diag_printf
#else
#define LPC2XXX_DBG_PRINT( fmt, ... )
#endif
//---------------------------------------------------------------------------
// we define our own set of register bits in order to be independent from
// platform specific names
//
//---------------------------------------------------------------------------
// Memory map of CAN block
//
#define CAN_ACCFILT_RAM_BASE 0xE0038000
#define CAN_ACCFILT_REG_BASE 0xE003C000
#define CAN_CENTRAL_REG_BASE 0xE0040000
#define CAN_CTRL_1_REG_BASE 0xE0044000
#define CAN_CTRL_2_REG_BASE 0xE0048000
#define CAN_CTRL_3_REG_BASE 0xE004C000
#define CAN_CTRL_4_REG_BASE 0xE0050000
//---------------------------------------------------------------------------
// CAN Acceptance Filter register layout
//
#define CAN_ACCFILT_AFMR (CAN_ACCFILT_REG_BASE + 0x0000)
#define CAN_ACCFILT_SFF_SA (CAN_ACCFILT_REG_BASE + 0x0004)
#define CAN_ACCFILT_SFF_GRP_SA (CAN_ACCFILT_REG_BASE + 0x0008)
#define CAN_ACCFILT_EFF_SA (CAN_ACCFILT_REG_BASE + 0x000C)
#define CAN_ACCFILT_EFF_GRP_SA (CAN_ACCFILT_REG_BASE + 0x0010)
#define CAN_ACCFILT_ENDOFTABLE (CAN_ACCFILT_REG_BASE + 0x0014)
#define CAN_ACCFILT_LUT_ERR_ADDR (CAN_ACCFILT_REG_BASE + 0x0018)
#define CAN_ACCFILT_LUT_ERR (CAN_ACCFILT_REG_BASE + 0x001C)
//---------------------------------------------------------------------------
// CAN_ACCFILT_AFMR Bits
//
#define AFMR_OFF 0x00000001 // 1 = Acceptance filter is not operational
#define AFMR_BYPASS 0x00000002 // 1 = all Rx messages are accepted on enabled CAN controllers.
#define AFMR_FULLCAN 0x00000004 // 1 = FullCAN mode
#define AFMR_ON 0x00000000 // Acceptance filter on
#define ACCFILT_RAM_SIZE 2048 // size of acceptance filter ram
//---------------------------------------------------------------------------
// Acceptance filter tool macros
//
#define ACCFILT_STD_ID_MASK 0x7FF
#define ACCFILT_EXT_ID_MASK 0x1FFFFFFF
#define ACCFILT_STD_DIS 0x1000
#define ACCFILT_STD_CTRL_MASK 0xE000
#define ACCFILT_EXT_CTRL_MASK 0xE0000000
#define ACCFILT_STD_GET_CTRL(_entry_) (((_entry_) >> 13) & 0x7)
#define ACCFILT_STD_GET_CTRL_LOWER(_entry_) (((_entry_) >> 29) & 0x7)
#define ACCFILT_STD_GET_CTRL_UPPER(_entry_) (((_entry_) >> 13) & 0x7)
#define ACCFILT_STD_GET_ID(_entry_) ((_entry_) & ACCFILT_STD_ID_MASK)
#define ACCFILT_EXT_GET_ID(_entry_) ((_entry_) & ACCFILT_EXT_ID_MASK)
#define ACCFILT_EXT_GET_CTRL(_entry_) (((_entry_) >> 29) & 0x7)
#define ACCFILT_EXT_SET_CTRL(_entry_, _ctrl_) ((_entry_ & 0xE0000000) | ((_ctrl_) << 29))
//---------------------------------------------------------------------------
// CAN Central CAN Registers register layout
//
#define CAN_CENTRAL_TXSR (CAN_CENTRAL_REG_BASE + 0x0000)
#define CAN_CENTRAL_RXSR (CAN_CENTRAL_REG_BASE + 0x0004)
#define CAN_CENTRAL_MSR (CAN_CENTRAL_REG_BASE + 0x0008)
//---------------------------------------------------------------------------
// CAN Controller register offsets
// Registers are offsets from base CAN module control register
//
#define CANREG_MOD 0x0000
#define CANREG_CMR 0x0004
#define CANREG_GSR 0x0008
#define CANREG_ICR 0x000C
#define CANREG_IER 0x0010
#define CANREG_BTR 0x0014
#define CANREG_EWL 0x0018
#define CANREG_SR 0x001C
#define CANREG_RFS 0x0020
#define CANREG_RID 0x0024
#define CANREG_RDA 0x0028
#define CANREG_RDB 0x002C
#define CANREG_TFI1 0x0030
#define CANREG_TID1 0x0034
#define CANREG_TDA1 0x0038
#define CANREG_TDB1 0x003C
#define CANREG_TFI2 0x0040
#define CANREG_TID2 0x0044
#define CANREG_TDA2 0x0048
#define CANREG_TDB2 0x004C
#define CANREG_TFI3 0x0050
#define CANREG_TID3 0x0054
#define CANREG_TDA3 0x0058
#define CANREG_TDB3 0x005C
//---------------------------------------------------------------------------
// CAN Controller register layout
//
#define CAN_CTRL_MOD(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_MOD)
#define CAN_CTRL_CMR(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_CMR)
#define CAN_CTRL_GSR(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_GSR)
#define CAN_CTRL_ICR(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_ICR)
#define CAN_CTRL_IER(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_IER)
#define CAN_CTRL_BTR(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_BTR)
#define CAN_CTRL_EWL(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_EWL)
#define CAN_CTRL_SR(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_SR)
#define CAN_CTRL_RFS(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_RFS)
#define CAN_CTRL_RID(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_RID)
#define CAN_CTRL_RDA(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_RDA)
#define CAN_CTRL_RDB(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_RDB)
#define CAN_CTRL_TFI1(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TFI1)
#define CAN_CTRL_TID1(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TID1)
#define CAN_CTRL_TDA1(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDA1)
#define CAN_CTRL_TDB1(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDB1)
#define CAN_CTRL_TFI2(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TFI2)
#define CAN_CTRL_TID2(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TID2)
#define CAN_CTRL_TDA2(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDA2)
#define CAN_CTRL_TDB2(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDB2)
#define CAN_CTRL_TFI3(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TFI3)
#define CAN_CTRL_TID3(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TID3)
#define CAN_CTRL_TDA3(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDA3)
#define CAN_CTRL_TDB3(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDB3)
//---------------------------------------------------------------------------
// CAN_CTRL_ICR register bits
//
#define ICR_RX 0x00000001
#define ICR_TX1 0x00000002
#define ICR_ERR_WARN 0x00000004
#define ICR_DATA_OVR 0x00000008
#define ICR_WAKE_UP 0x00000010
#define ICR_ERR_PASSIVE 0x00000020
#define ICR_ARBITR_LOST 0x00000040
#define ICR_BUS_ERR 0x00000080
#define ICR_ID_READY 0x00000100
#define ICR_TX2 0x00000200
#define ICR_TX3 0x00000400
#define ICR_LUT_ERR 0x00000800
#define ICR_GET_ERRBIT(_icr_) (((_icr_) >> 16) & 0x1F)
#define ICR_ERR_DIRECTION 0x00200000
#define ICR_GET_ERRCODE(_icr_) (((_icr_) >> 22) & 0x03)
#define ICR_GET_ALCBIT(_icr_) (((_icr_) >> 24) & 0x1F)
#define CAN_ALL_ERR_INT (ICR_ERR_PASSIVE | ICR_ARBITR_LOST | ICR_BUS_ERR | ICR_ERR_WARN)
#define CAN_MISC_INT (CAN_ALL_ERR_INT | ICR_WAKE_UP)
//---------------------------------------------------------------------------
// CAN_CTRL_ICR register bits
//
#define ICR_ERRCODE_BIT_ERR 0x00
#define ICR_ERRCODE_FORM_ERR 0x01
#define ICR_ERRCODE_STUFF_ERR 0x02
#define ICR_ERRCODE_OTHER_ERR 0x03
//---------------------------------------------------------------------------
// CAN_CTRL_RFS register bits
//
#define RFS_ACCFILT_INDEX_MASK 0x000003FF
#define RFS_RECEIVED_IN_BYPASS_MODE 0x00000400
#define RFS_DLC_MASK 0x000F0000
#define RFS_RTR 0x40000000
#define RFS_EXT 0x80000000
#define RFS_GET_DLC(_regval_) (((_regval_) >> 16) & 0xF)
//---------------------------------------------------------------------------
// CAN_CTRL_CMR register bits
//
#define CMR_TX_REQ 0x00000001
#define CMR_TX_ABORT 0x00000002
#define CMR_RX_RELEASE_BUF 0x00000004
#define CMR_CLEAR_DATA_OVR 0x00000008
#define CMR_SELF_RX_REQ 0x00000010
#define CMR_SEND_TX_BUF1 0x00000020
#define CMR_SEND_TX_BUF2 0x00000040
#define CMR_SEND_TX_BUF3 0x00000080
//---------------------------------------------------------------------------
// CAN_CTRL_TFI register bits
//
#define TFI_PRIO_MASK 0x000000FF
#define TFI_DLC_MASK 0x000F0000
#define TFI_DLC_RTR 0x40000000
#define TFI_DLC_EXT 0x80000000
//---------------------------------------------------------------------------
// CAN_CTRL_MOD register bits
//
#define CANMOD_OPERATIONAL 0x00000000
#define CANMOD_RESET 0x00000001
#define CANMOD_LISTEN_ONLY 0x00000002
#define CANMOD_SELF_TEST 0x00000004
#define CANMOD_TX_BUF_CFG 0x00000008
#define CANMOD_SLEEP 0x00000010
#define CANMOD_REV_POLARITY 0x00000020
#define CANMOD_TEST 0x00000040
//---------------------------------------------------------------------------
// CAN_CTRL_IER register bits
//
#define IER_RX 0x00000001
#define IER_TX1 0x00000002
#define IER_ERR_WARN 0x00000004
#define IER_DATA_OVR 0x00000008
#define IER_WAKE_UP 0x00000010
#define IER_ERR_PASSIVE 0x00000020
#define IER_ARBITR_LOST 0x00000040
#define IER_BUS_ERR 0x00000080
#define IER_ID_READY 0x00000100
#define IER_TX2 0x00000200
#define IER_TX3 0x00000400
//---------------------------------------------------------------------------
// CAN_CTRL_GSR register bits
//
#define GSR_RX_MSG_AVAILABLE 0x00000001
#define GSR_DATA_OVR 0x00000002
#define GSR_TX_NOT_PENDING 0x00000004
#define GSR_ALL_TX_COMPLETE 0x00000008
#define GSR_RECEIVING_ACTIVE 0x00000010
#define GSR_SENDING_ACTIVE 0x00000020
#define GSR_ERR 0x00000040
#define GSR_BUS_OFF 0x00000080
#define GSR_RXERR_CNT(_reg_) (((_reg_) >> 16) & 0xFF)
#define GSR_TXERR_CNT(_reg_) (((_reg_) >> 24) & 0xFF)
//---------------------------------------------------------------------------
// CAN_CTRL_SR register bits
//
#define SR_RX_MSG_AVAILABLE 0x01
#define SR_DATA_OVR 0x02
#define SR_TX_BUF_WRITE_OK 0x04 // TBS1, TBS2, TBS3 (Bit 2, 10, 18)
#define SR_TX_COMPLETE 0x08 // TCS1, TCS2, TCS3 (Bit 3, 11, 19)
#define SR_RECEIVING_ACTIVE 0x10
#define SR_SENDING_ACTIVE 0x20 // TS1, TS2, TS3 (5, 13, 21)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -