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

📄 mcohw_lpc2.c

📁 CanOpen的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
}


#ifndef USE_CANOPEN_MANAGER
/**************************************************************************
DOES:    CAN receive interrupt handler
**************************************************************************/
void MCOHW_CANISR_Rx1 
  (
  void
  )
{
UNSIGNED32 buf;
UNSIGNED32 *pDest;

  if (!(C1RFS & 0xC0000400L))
  { // 11-bit ID, no RTR, matched a filter

    {
    // initialize destination pointer
    // filter number is in lower 10 bits of C1RFS
    pDest = (UNSIGNED32 *) &(gFullCANList[C1RFS & 0x000003FFL].Dat1);
    
    // calculate contents for first entry into FullCAN list
    buf = C1RFS & 0xC00F0000L; // mask FF, RTR and DLC
    buf |= 0x01000000L; // set semaphore to 01b
    buf |= C1RID & 0x000007FFL; // get CAN message ID

    // now copy entire message to FullCAN list
    *pDest = buf; 
    pDest++; // set to gFullCANList[(C1RFS & 0x000003FFL)].DatA
    *pDest = C1RDA; 
    pDest++; // set to gFullCANList[(C1RFS & 0x000003FFL)].DatB
    *pDest = C1RDB; 

    // now set the sempahore to complete
    buf |= 0x03000000L; // set semaphore to 11b
    pDest -= 2; // set to gFullCANList[(C1RFS & 0x000003FFL)].Dat1
    *pDest = buf; 
    }
  }

  C1CMR = 0x04; // release receive buffer
  VICVectAddr = 0xFFFFFFFF; // acknowledge Interrupt
}


/**************************************************************************
DOES:    CAN transmit interrupt handler
**************************************************************************/
void MCOHW_CANISR_Tx1 
  (
  void
  )
{
UNSIGNED32 istat;

  istat = C1ICR; // Reset interrupt by reading the register
  VICSoftIntClr = 0x00100000;  

  MCOHW_CheckTxQueue(); // check if something is in the Tx queue

  VICVectAddr = 0xFFFFFFFF; // acknowledge Interrupt
}
#endif // USE_CANOPEN_MANAGER


/**************************************************************************
DOES:    This function implements the initialization of the CAN interface.
RETURNS: 1 if init is completed 
         0 if init failed, bit INIT of MCOHW_GetStatus stays 0
**************************************************************************/
UNSIGNED8 MCOHW_Init 
  (
  UNSIGNED16 BaudRate
  )
{
  if (BaudRate != 125) 
  { // This implementation only supports 125kbit
      return 0;
  }

  // Enable Pins for CAN port 1 and 2
  PINSEL1 |= (UNSIGNED32) 0x00054000; 
  
  C1MOD = 1; // Enter Reset Mode
  C1GSR = 0; // Clear status register
  C1BTR = CANBitrate125k_12MHz; // Set bit timing
  
  AFMR = 0x00000001; // Disable acceptance filter

  // Disable All Interrupts
  C1IER = 0;

  // Enter Normal Operating Mode
  C1MOD = 0; // Operating Mode 

  // Init Interrupts
  VICDefVectAddr = (unsigned long) MCOHW_DefaultISR;

  // Initialize Timer Interrupt
  T0MR0 = 59999; // 1mSec = 60.000-1 counts
  T0MCR = 3; // Interrupt and Reset on MR0
  T0TCR = 1;  // Timer0 Enable

  VICVectAddr0 = (unsigned long) MCOHW_TimerISR; // set interrupt vector
  VICVectCntl0 = 0x20 | 4;  // use it for Timer 0 Interrupt
  VICIntEnable = 0x00000010;  // Enable Timer0 Interrupt

  VICVectAddr1 = (unsigned long) MCOHW_CANISR_Rx1; // set interrupt vector
  VICVectCntl1 = 0x20 | 26;  // use it for CAN Rx1 Interrupt
  VICIntEnable = 0x04000000;  // Enable CAN Rx1 Interrupt
  
  VICVectAddr2 = (unsigned long) MCOHW_CANISR_Tx1; // set interrupt vector
  VICVectCntl2 = 0x20 | 20;  // use it for CAN Tx1 Interrupt
  VICIntEnable = 0x00100000;  // Enable CAN Tx1 Interrupt

  C1IER = 0x0003; // Enable CAN 1 RX and TX interrupt

  gCANFilter = 0; // Reset all filters

  // Init Tx queue buffer pointer
  mTxIn = 0;
  mTxOut = 0;

  mStatus |= HW_INIT;

  return 1;
}


#ifndef USE_CANOPEN_MANAGER
/**************************************************************************
DOES:    This function implements the initialization of a CAN ID hardware
         filter as supported by many CAN controllers.
RETURNS: 1 if filter was set 
         2 if this HW does not support filters 
           (in this case HW will receive EVERY CAN message)
         0 if no more filter is available
**************************************************************************/
UNSIGNED8 MCOHW_SetCANFilter 
  (
  UNSIGNED16 CANID
  )
{
int p, n;
int buf0, buf1;
int ID_lower, ID_upper;
UNSIGNED32 candata;
UNSIGNED32 *pAddr;

  if (gCANFilter == 0)
  { // First call, init entry zero
    gFilterList[0] = 0x37FF; // Disabled and unused
  }
  if (gCANFilter >= MAX_FILTERS)
  {
    return 0;
  }

  // Filters must be sorted by priority

  // new filter is sorted into array
  p = 0;
  while (p < gCANFilter) // loop through all existing filters 
  {
    if (gFilterList[p] > CANID)
    {
      break;
    }
    p++;
  }
  // insert new filter here
  buf0 = gFilterList[p]; // save current entry
  gFilterList[p] = CANID; // insert the new entry
  // move all remaining entries one row up
  gCANFilter++;
  while (p < gCANFilter)
  {
    p++;
    buf1 = gFilterList[p];
    gFilterList[p] = buf0;
    buf0 = buf1;
  }

  // Now work on Acceptance Filter Configuration     
  // Acceptance Filter Mode Register = off !
  AFMR = 0x00000001;
  
  // Set CAN filter for 11-bit standard identifiers
  p = 0;

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

  pAddr = (UNSIGNED32 *) ACCEPTANCE_FILTER_RAM_BASE;
  for (n = 0; n < (MAX_FILTERS/2); n++)
  {
    if (n < ((gCANFilter+1)/2))
    {
      ID_lower = gFilterList[n * 2];
      ID_upper = gFilterList[n * 2 + 1];
      // 0x20002000 indicates CAN interface 1
      candata = 0x20002000 + (ID_lower << 16) + ID_upper;
    }
    else
    {
      candata = 0x37FF37FF; // Disabled and unused
    }
    *pAddr = candata;
    p += 4;
    pAddr++;
  }
  // p is still ENDofTable;
  
  // 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 = 0x00000000;
  
  return 1;
}
#endif // USE_CANOPEN_MANAGER


/**************************************************************************
DOES:    Timer interrupt handler (1ms)
**************************************************************************/
void MCOHW_TimerISR 
  (
  void
  ) 
{
  T0IR = 1; // Clear interrupt flag
  gTimCnt++; // increment global timer counter
  VICVectAddr = 0xFFFFFFFF; // Acknowledge Interrupt
}

#endif // (NROF_CANPORTS == 1)

/**************************************************************************
DOES:    This function reads a 1 millisecond timer tick. The timer tick
         must be a UNSIGNED16 and must be incremented once per millisecond.
RETURNS: 1 millisecond timer tick
**************************************************************************/
UNSIGNED16 MCOHW_GetTime (void)
{
  return gTimCnt;
}


/**************************************************************************
DOES:    This function compares a UNSIGNED16 timestamp to the internal 
         timer tick and returns 1 if the timestamp expired/passed.
RETURNS: 1 if timestamp expired/passed
         0 if timestamp is not yet reached
NOTES:   The maximum timer runtime measurable is 0x8000 (about 32 seconds).
         For the usage in MicroCANopen that is sufficient. 
**************************************************************************/
UNSIGNED8 MCOHW_IsTimeExpired (
  UNSIGNED16 timestamp
  )
{
UNSIGNED16 time_now;

  time_now = gTimCnt;
  if (time_now > timestamp)
  {
    if ((time_now - timestamp) < 0x8000)
      return 1;
    else
      return 0;
  }
  else
  {
    if ((timestamp - time_now) > 0x8000)
      return 1;
    else
      return 0;
  }
}

/*----------------------- END OF FILE ----------------------------------*/

⌨️ 快捷键说明

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