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

📄 lpc_fullcan_sw.c

📁 The following Philips LPC2k CAN examples in this directory were provided by ESAcademy. LPC2_CANA
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************
MODULE:    LPC_FullCAN_SW
CONTAINS:  Philips LPC2000 CAN interface driver.
           The first revisions of the Philips LPC2000 with CAN interface
           do NOT support the FullCAN mode in hardware. This driver 
           implements the FullCAN mode in software.
		       Compiled and Tested with Keil Tools www.keil.com
COPYRIGHT: Embedded Systems Academy, Inc. 2004.
LICENSE:   THIS VERSION CREATED FOR FREE DISTRIBUTION
		       FOR PHILIPS SEMICONDUCTORS www.philipsmcu.com
           FOR KEIL SOFTWARE www.keil.com
VERSION:   1.10, Pf 05-JAN-05, Latest errata sheet suggestions implemented
---------------------------------------------------------------------------
HISTORY:   1.01, Pf 18-APR-04, Added Timer and LED output
HISTORY:   1.00, Pf 16-APR-04, First published release
***************************************************************************/ 

#include <LPC21XX.H> // LPC21XX Peripheral Registers
#include "LPC_FullCAN_SW.h"


/**************************************************************************
GLOBAL VARIABLES
***************************************************************************/ 

// Counts number of filters (CAN message objects) used so far
short volatile gCANFilter = 0;

// FullCAN Message List
FULLCAN_MSG volatile gFullCANList[MAX_FILTERS];


/**************************************************************************
PUBLIC FUNCTIONS
***************************************************************************/ 

/**************************************************************************
Initialization of a CAN interface
as described in LPC_FullCAN_SW.h
***************************************************************************/ 
short FullCAN_Init (
  unsigned short can_port,    // CAN interface to use
  unsigned short can_isrvect, // interrupt vector number to use for Rx ISR (0-15)
  unsigned int can_btr        // CAN BTR value used to set CAN baud rate
  )
{
unsigned int *pSFR; // pointer into SFR space
unsigned int *pSFR2; // pointer into SFR space
unsigned int offset; // offset added to pSFR

  // Double check can_isrvect value
  if (can_isrvect > 15)
  { // Illegal value for can_isrvect
    return 0;
  }
                                                      
  // Enable pins for selected CAN interface
  switch (can_port)
  {
  case 1:
    PINSEL1 |= 0x00040000L; // Set bit 18
    offset = 0x00000000L; // Use 1st set of CAN registers
    break;
#if (MAX_CANPORTS > 1)
  case 2:
    PINSEL1 |= 0x00014000L; // Set bits 14 and 16
    offset = 0x00001000L; // Use 2nd set of CAN registers
    break;
#endif
#if (MAX_CANPORTS > 2)
  case 3:
    PINSEL1 |= 0x00001800L; // Set bits 11 and 12
    offset = 0x00002000L; // Use 3rd set of CAN registers
    break;
#endif
#if (MAX_CANPORTS > 3)
  case 4:
    PINSEL0 |= 0x0F000000L; // Set bits 24 to 27
    offset = 0x00003000L; // Use 4th set of CAN registers
    break;
#endif
  default:
    return 0; // illegal value used
  }

  // Reset and disable all message filters
  gCANFilter = 0;
  // Acceptance Filter Mode Register = off !
  AFMR = 0x00000001L;

  pSFR = (unsigned int *) &C1MOD + offset; // Select Mode register
  *pSFR = 1; // Go into Reset mode

  pSFR = (unsigned int *) &C1IER + offset; // Select Interrupt Enable Register
  *pSFR = 0;// Disable All Interrupts

  pSFR = (unsigned int *) &C1GSR + offset; // Select Status Register
  *pSFR = 0; // Clear Status register

  pSFR = (unsigned int *) &C1BTR + offset; // Select BTR Register
  *pSFR = can_btr; // Set bit timing

  // Set and enable receive interrupt
  pSFR = (unsigned int *) &VICVectAddr0;
  pSFR += can_isrvect; // Set to desired interrupt vector
  
  pSFR2 = (unsigned int *) &VICVectCntl0;
  pSFR2 += can_isrvect; // Set to desired interrupt control

  switch (can_port)
  {
  case 1:
    // Set interrupt vector
    *pSFR = (unsigned long) FullCAN_CANISR_Rx1; 
    // Use this Interrupt for CAN Rx1 Interrupt
    *pSFR2 = 0x20 | 26;
    // Enable CAN Rx1 Interrupt
    VICIntEnable = 0x04000000L;  
    break;
#if (MAX_CANPORTS > 1)
  case 2:
    // Set interrupt vector
    *pSFR = (unsigned long) FullCAN_CANISR_Rx2; 
    // Use this Interrupt for CAN Rx2 Interrupt
    *pSFR2 = 0x20 | 27;
    // Enable CAN Rx2 Interrupt
    VICIntEnable = 0x08000000L;  
    break;
#endif
#if (MAX_CANPORTS > 2)
  case 3:
    // Set interrupt vector
    *pSFR = (unsigned long) FullCAN_CANISR_Rx3; 
    // Use this Interrupt for CAN Rx3 Interrupt
    *pSFR2 = 0x20 | 28;
    // Enable CAN Rx3 Interrupt
    VICIntEnable = 0x10000000L;  
    break;
#endif
#if (MAX_CANPORTS > 3)
  case 4:
    // Set interrupt vector
    *pSFR = (unsigned long) FullCAN_CANISR_Rx4; 
    // Use this Interrupt for CAN Rx4 Interrupt
    *pSFR2 = 0x20 | 29;
    // Enable CAN Rx4 Interrupt
    VICIntEnable = 0x20000000L;  
    break;
#endif
  default:
    return 0; // illegal value used
  }

  pSFR = (unsigned int *) &C1IER + offset; // Select Interrupt register
  *pSFR = 1; // Enable Receive Interrupt

  // Enter Normal Operating Mode
  pSFR = (unsigned int *) &C1MOD + offset; // Select Mode register
  *pSFR = 0; // Operating Mode 

  return 1;
}
  

/**************************************************************************
Setting a CAN receive filter
as described in LPC_FullCAN_SW.h
***************************************************************************/ 
short FullCAN_SetFilter (
  unsigned short can_port, // CAN interface number
  unsigned int CANID // 11-bit CAN ID
  )
{
unsigned int p, n;
unsigned int buf0, buf1;
unsigned int ID_lower, ID_upper;
unsigned int candata;
unsigned int *pAddr;

  // Double check can_port value
  if ((can_port < 1) || (can_port > MAX_CANPORTS))
  { // Illegal value for can_port
    return 0;
  }

  // Acceptance Filter Mode Register = off !
  AFMR = 0x00000001L;

  if (gCANFilter == 0)
  { // First call, init entry zero
    gFullCANList[0].Dat1 = 0x000037FFL; // CAN 1, disabled and unused
  }
  if (gCANFilter >= MAX_FILTERS)
  {
    return 0;
  }

  CANID &= 0x000007FFL; // Mask out 11-bit ID
  CANID |= (can_port << 13); // Put can_port info in bits 13-15

  // Filters must be sorted by interface, then by priority
  // new filter is sorted into array
  p = 0;
  while (p < gCANFilter) // loop through all existing filters 
  {
    if ((gFullCANList[p].Dat1 & 0x0000FFFFL) > CANID)
    {
      break;
    }
    p++;
  }

  // insert new filter here
  buf0 = gFullCANList[p].Dat1; // save current entry
  gFullCANList[p].Dat1 = CANID; // insert the new entry

  // move all remaining entries one row up
  gCANFilter++;
  while (p < gCANFilter)
  {
    p++;
    buf1 = gFullCANList[p].Dat1;
    gFullCANList[p].Dat1 = buf0;
    buf0 = buf1;
  }

  // Now work on Acceptance Filter Configuration     
  // Set CAN filter for 11-bit standard identifiers
  p = 0;

  // Set pointer for Standard Frame Individual
  // Standard Frame Explicit
  SFF_sa = p;

  pAddr = (unsigned int *) ACCEPTANCE_FILTER_RAM_BASE;
  for (n = 0; n < ((gCANFilter+1)/2); n++)
  {
    ID_lower = gFullCANList[n * 2].Dat1 & 0x0000FFFFL;
    ID_upper = gFullCANList[n * 2 + 1].Dat1 & 0x0000FFFFL;
    candata = (ID_lower << 16) + ID_upper;
    *pAddr = candata;
    p += 4;
    pAddr++;
  }

  // p is still pointing to ENDofTable;
  // last entry must contain unused filters
  *pAddr = 0xF7FFF7FF;
  p += 4;
  
  // Set pointer for Standard Frame Groups
  // Standard Frame Group Start Address Register
  SFF_GRP_sa = p;

  // Set pointer for Extended Frame Individual
  // Extended Frame Start Address Register
  EFF_sa = p;

  // Set pointer for Extended Frame Groups
  // Extended Frame Group Start Address Register
  EFF_GRP_sa = p;

  // Set ENDofTable 
  // End of AF Tables Register
  ENDofTable = p;

  // Acceptance Filter Mode Register, start using filter
  AFMR = 0;
  
  return 1;
}


/**************************************************************************
Installing the CAN Err ISR
as described in LPC_FullCAN_SW.h
***************************************************************************/ 
short FullCAN_SetErrIRQ (
  unsigned short can_isrvect // interrupt vector number to use for Err ISR (0-15)
  )
{
unsigned int *pSFR; // pointer into SFR space

  // Double check can_isrvect value
  if (can_isrvect > 15)
  { // Illegal value for can_isrvect
    return 0;
  }

  // Set and enable err interrupt
  pSFR = (unsigned int *) &VICVectAddr0;
  pSFR += can_isrvect; // Set to desired interrupt vector
  // Set interrupt vector
  *pSFR = (unsigned long) FullCAN_CANISR_Err; 
  
  pSFR = (unsigned int *) &VICVectCntl0;
  pSFR += can_isrvect; // Set to desired interrupt control
  *pSFR = 0x20 | 19;

  // Enable Interrupt source
  VICIntEnable = 0x00080000L;  

  return 1;
}


/**************************************************************************
Transmitting a CAN message on a selected CAN interface
as described in LPC_FullCAN_SW.h
***************************************************************************/ 
short FullCAN_PushMessage (
  unsigned short can_port,
  FULLCAN_MSG *pTransmitBuf
  )
{
unsigned int *pAddr;  
unsigned int *pCandata;
unsigned int offset;

  switch (can_port)

⌨️ 快捷键说明

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