can_mcf52xx.c
来自「开放源码实时操作系统源码.」· C语言 代码 · 共 1,632 行 · 第 1/5 页
C
1,632 行
//==========================================================================
//
// devs/serial/m68k/flexcan/current/src/can_mcf_flexcan.c
//
// CAN driver for Motorola coldfire processors
//
//==========================================================================
//####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: 2005-05-12
// Purpose: support coldfire on-chip flexcan moduls
// Description:
//
//####DESCRIPTIONEND####
//
//==========================================================================
//==========================================================================
// INCLUDES
//==========================================================================
#include <pkgconf/system.h>
#include <pkgconf/io_can.h>
#include <pkgconf/devs_can_mcf52xx_flexcan.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>
//===========================================================================
// DEFINES
//===========================================================================
//
// we define our own ste of register bits in order to be independent from
// platform specific names
//
//---------------------------------------------------------------------------
// MCR regsiter bits
//
#define FLEXCAN_MCR_STOP (0x01 << 15)
#define FLEXCAN_MCR_FRZ (0x01 << 14)
#define FLEXCAN_MCR_HALT (0x01 << 12)
#define FLEXCAN_MCR_NOTRDY (0x01 << 11)
#define FLEXCAN_MCR_WAKEMSK (0x01 << 10)
#define FLEXCAN_MCR_SOFTRST (0x01 << 9)
#define FLEXCAN_MCR_FRZACK (0x01 << 8)
#define FLEXCAN_MCR_SUPV (0x01 << 7)
#define FLEXCAN_MCR_SELFWAKE (0x01 << 6)
#define FLEXCAN_MCR_APS (0x01 << 5)
#define FLEXCAN_MCR_STOPACK (0x01 << 4)
//---------------------------------------------------------------------------
// CTRL0 register bits
//
#define FLEXCAN_CTRL0_BOFFMSK (0x01 << 7)
#define FLEXCAN_CTRL0_ERRMASK (0x01 << 6)
#define FLEXCAN_CTRL0_RXMODE (0x01 << 2)
#define FLEXCAN_CTRL0_RXMODE_0_DOMINANT (0x00 << 2)
#define FLEXCAN_CTRL0_RXMODE_1_DOMINANT (0x01 << 2)
#define FLEXCAN_CTRL0_TXMODE_MASK (0x03 << 0)
#define FLEXCAN_CTRL0_TXMODE_SHIFT 0
#define FLEXCAN_CTRL0_TXMODE_FULL_0_DOMINANT (0x00 << 0)
#define FLEXCAN_CTRL0_TXMODE_FULL_1_DOMINANT (0x01 << 0)
#define FLEXCAN_CTRL0_TXMODE_OPEN_0_DOMINANT (0x02 << 0)
//---------------------------------------------------------------------------
// CTRL1 register bits
//
#define FLEXCAN_CTRL1_SAMP (0x01 << 7)
#define FLEXCAN_CTRL1_TSYNC (0x01 << 5)
#define FLEXCAN_CTRL1_LBUF (0x01 << 4)
#define FLEXCAN_CTRL1_LOM (0x01 << 3)
#define FLEXCAN_CTRL1_PROPSEG_MASK (0x07 << 0)
#define FLEXCAN_CTRL1_PROPSEG_SHIFT 0
//---------------------------------------------------------------------------
// CTRL2 register bits
//
#define FLEXCAN_CTRL2_RJW_MASK (0x03 << 6)
#define FLEXCAN_CTRL2_RJW_SHIFT 6
#define FLEXCAN_CTRL2_PSEG1_MASK (0x07 << 3)
#define FLEXCAN_CTRL2_PSEG1_SHIFT 3
#define FLEXCAN_CTRL2_PSEG2_MASK (0x07 << 0)
#define FLEXCAN_CTRL2_PSEG2_SHIFT 0
//---------------------------------------------------------------------------
// ESTAT register bits
//
#define FLEXCAN_ESTAT_BITERR_MASK (0x03 << 14)
#define FLEXCAN_ESTAT_BITERR_SHIFT 14
#define FLEXCAN_ESTAT_BITERR_NONE (0x00 << 14)
#define FLEXCAN_ESTAT_BITERR_DOMINANT_RECESSIVE (0x01 << 14)
#define FLEXCAN_ESTAT_BITERR_RECESSIVE_DOMINANT (0x02 << 14)
#define FLEXCAN_ESTAT_ACKERR (0x01 << 13)
#define FLEXCAN_ESTAT_CRCERR (0x01 << 12)
#define FLEXCAN_ESTAT_FORMERR (0x01 << 11)
#define FLEXCAN_ESTAT_STUFFERR (0x01 << 10)
#define FLEXCAN_ESTAT_TXWARN (0x01 << 9)
#define FLEXCAN_ESTAT_RXWARN (0x01 << 8)
#define FLEXCAN_ESTAT_IDLE (0x01 << 7)
#define FLEXCAN_ESTAT_TX_RX (0x01 << 6)
#define FLEXCAN_ESTAT_FCS_MASK (0x03 << 4)
#define FLEXCAN_ESTAT_FCS_SHIFT 4
#define FLEXCAN_ESTAT_FCS_ERROR_ACTIVE (0x00 << 4)
#define FLEXCAN_ESTAT_FCS_ERROR_PASSIVE (0x01 << 4)
#define FLEXCAN_ESTAT_BOFFINT (0x01 << 2)
#define FLEXCAN_ESTAT_ERRINT (0x01 << 1)
#define FLEXCAN_ESTAT_WAKEINT (0x01 << 0)
//
// For receive event calls we use these two identifiers for
// err and bus off events - message boxes use 0 - 15
//
#define FLEXCAN_ERR_EVENT 16
#define FLEXCAN_BUSOFF_EVENT 17
#define FLEXCAN_WAKE_EVENT 18
//
// Acceptance mask
//
#define FLEXCAN_ACCEPTANCE_MASK_RX_ALL 0x00 // receive all messages - mbox ID does not matter
#define FLEXCAN_ACCEPTANCE_MASK_RX_ID 0x1FFFFFFF // receive only messages where ID exactly matches mbox ID
//---------------------------------------------------------------------------
// message buffer cfg bits
//
#define MBOX_RXCODE_NOT_ACTIVE 0x00
#define MBOX_RXCODE_BUSY 0x10
#define MBOX_RXCODE_EMPTY 0x40
#define MBOX_RXCODE_FULL 0x20
#define MBOX_RXCODE_OVERRUN 0x60
#define MBOX_TXCODE_NOT_READY 0x80
#define MBOX_TXCODE_TRANSMIT 0xC0
#define MBOX_TXCODE_RESPONSE 0xA0
#define MBOX_DATA_FRAME 0x00 // data frame
#define MBOX_REMOTE_FRAME 0x01 // remote frame
#define MBOX_STD_ID 0x00 // standard identifier
#define MBOX_EXT_ID 0x01 // remote identifier
#define MBOX_TX 0x08 // tx message box
#define MBOX_RX 0x00 // rx messge box
#define MBOX_CFG_IDE 0x08
#define MBOX_CFG_RTR_EXT 0x01
#define MBOX_CFG_RTR_STD 0x10
#define MBOX_CFG_SSR 0x10
#define MBOX_CFG_DLC_MASK 0x0F
#define MBOX_CFG_STAT_MASK 0xF0
//---------------------------------------------------------------------------
// flexcan message buffer configuration
//
#define FLEXCAN_MBOX_MIN 0
#define FLEXCAN_MBOX_MAX 15
#define FLEXCAN_MBOX_CNT 16
#define FLEXCAN_MBOX_TX CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_DEFAULT_TX_MBOX
#define FLEXCAN_MBOX_RX_MIN 0
#define FLEXCAN_MBOX_RX_MAX (FLEXCAN_MBOX_MAX - 1) // one msg box is tx
#define FLEXCAN_MBOX_RX_CNT (FLEXCAN_MBOX_CNT - 1) // one msg box is tx
#define FLEXCAN_CTRLSTAT_NOT_READ 0 // indicates that control status register is not read
//===========================================================================
// DATA TYPES
//===========================================================================
//
// Type of message buffer - required for function getevent in order to
// identify the type of message box that cause event
//
typedef enum
{
MBOX_STATE_DISABLED, // message box unused (free)
MBOX_STATE_TX, // TX message box
MBOX_STATE_REMOTE_TX, // remote TX msaage box (data will be sent on reception of rtr frame)
MBOX_STATE_RX_ALL_STD, // RX message box for standard IDs
MBOX_STATE_RX_ALL_EXT, // RX message box for standard IDs
MBOX_STATE_RX_FILT // RX message box for filter mboxes
} flexcan_mbox_state;
//
// configuration info for flexcan message buffer
//
typedef struct flexcan_mbox_info_st
{
cyg_vector_t isr_vec; // isr vector
int isr_priority; // isr priority
cyg_interrupt interrupt; // stores interrupt data
cyg_handle_t interrupt_handle; // stores interrupt number
cyg_uint8 num; // number of message buffer
bool busy; // if true, then transmission or reception is in progress
flexcan_mbox_state state; // message box state
cyg_uint8 ctrlstat_shadow; // shadow register of message box ctrlstat register
} flexcan_mbox_info;
//
// Between ISR and DSR handling there is some kind of circular buffer.
// A DSR is only invoked if no other message box invoked a DSR before
// the DSR will read all available message buffers. This structure
// is for exchange of information between ISR and DSR
//
typedef struct st_rxmbox_circbuf
{
cyg_uint8 idx_rd; // the message box the DSR will read from
cyg_uint8 idx_wr; // the message box that will receive the next message
cyg_uint8 count; // the number of received message before DSR starts (number of ISR nesting)
} flexcan_rxmbox_circbuf;
//
// flexcan interrupt (busoff, err, wake) data - stores interrupt data for
// a non message box interrupt (bus off, err or wake interrupt)
//
typedef struct flexcan_int_st
{
cyg_vector_t isr_vec;
int isr_priority;
cyg_interrupt interrupt;
cyg_handle_t interrupt_handle;
} flexcan_int;
//
// flexcan message box initialisation
//
#define FLEXCAN_MBOX_INIT(_mbox0_vec, _prio, _mbox_no) { \
isr_vec : (_mbox0_vec) + (_mbox_no), \
isr_priority : (_prio), \
num : (_mbox_no), \
busy : false \
}
//
// Interrupt initialisation
//
#define FLEXCAN_INT_INIT(_vec, _prio) \
{ \
isr_vec : (_vec), \
isr_priority : (_prio) \
}
//
// flexcan configuration
//
typedef struct flexcan_info
{
cyg_uint8 *base; // base address of flexcan modul
cyg_vector_t isr_vec_mbox0; // vector number of ISR vector of first message box
flexcan_mbox_info mboxes[FLEXCAN_MBOX_CNT];// message boxes
cyg_uint32 last_tx_id; // last transmitted message identifier
flexcan_int boff_int; // bus off interrupt data
flexcan_int err_int; // error interrupt data
flexcan_int wake_int; // wake interrupt data
cyg_uint8 tx_all_mbox; // number of message box for all transmit messages
cyg_uint8 free_mboxes; // number of free message boxes for msg filters and rtr buffers
cyg_can_state state; // state of CAN controller
flexcan_rxmbox_circbuf rxmbox_std_circbuf;
flexcan_rxmbox_circbuf rxmbox_ext_circbuf;
cyg_uint8 mboxes_std_cnt; // contains number of standard message boxes available
cyg_uint8 mboxes_ext_cnt; // number of message boxes with ext id
cyg_uint8 mboxes_rx_all_cnt;// number of all available mboxes
bool rx_all; // true if reception of call can messages is active
cyg_uint16 imask_shadow; // interrupt mask shadow register
#ifdef CYGOPT_IO_CAN_TX_EVENT_SUPPORT
cyg_can_message last_tx_msg; // stores last transmitted message for TX events
#endif
#ifdef FLEXCAN_CAN_STATS
cyg_uint32 isr_count;
cyg_uint32 dsr_count;
cyg_uint32 rx_bytes;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?