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

📄 mscandrvlite.c

📁 freescale最新的16位单片机
💻 C
📖 第 1 页 / 共 4 页
字号:
                              identifier reference 

Return            :     ERR_OK if no error, otherwise error code
******************************************************************************/
UINT8
CAN_L_ConfigMB(UINT8 buffer, UINT8 cmode, UINT8 identifierRef)
{
      UINT8 currentCANRIER, 
            currentCANTIER;

      if (identifierRef >= NoOfID)
      {
            return (ERR_ID);
      }

      if (cmode >= INVALID)
      {
            return (ERR_MODE);
      }

      if (buffer >= NoOfMB)
      {
            return (ERR_MB);
      }

      SEI;
      currentCANRIER = CANRIER;                                                /* save interrupt enables */
      currentCANTIER = CANTIER;                            

      CANRIER = 0;                                           /* disable all interrupts */
      CANTIER = 0;

      if (!(CCRcopy & IMASK))
      {
            CLI;                                             /* restore interrupt mask */
      }

      if(BufferStatus_CAN0[buffer] == QUEUED2)               /* MB in msCAN buffer */            
      {
            if (MB_MSCAN[0] == buffer)                       /* MB in this MSCAN buffer */ 
            {
                  CANTARQ |= 0x01;                    /* set ABTRQi for msCAN buffer */
            }
            else
            {
                  if (MB_MSCAN[1] == buffer)                 /* MB in this MSCAN buffer */
                  {
                        CANTARQ |= 0x02;              /* set ABTRQi for msCAN buffer */
                  }
                  else                                       /* must be MB_MSCAN[2] */
                  {
                        CANTARQ |= 0x04;              /* set ABTRQi for msCAN buffer */
                  }
            }
#if (NO_OF_MSCAN_TXBUFFER != 3)
#error msCAN buffer not aborted
#endif
      }

      BufferMode_CAN0[buffer] = cmode;
      BufferStatus_CAN0[buffer] = NODATA;
      BufferID_Ref_CAN0[buffer] = identifierRef;

      CANRIER = currentCANRIER;                              /* restore interrupts */
      CANTIER  = currentCANTIER;

      return (ERR_OK);
}

/******************************************************************************
Function Name     :     CAN_L_CheckStatusMB
Engineer          :     Stuart Robb
Date              :     10/8/98

Arguments         :     buffer number
                        address for status 

Return            :     ERR_OK if no error, otherwise error code
******************************************************************************/
UINT8
CAN_L_CheckStatusMB (UINT8 buffer, UINT8 *statusPtr)
{
      if (buffer >= NoOfMB)
      {
            return (ERR_MB);
      }

      SEI;                                                   /* disable interrupts */
      *(statusPtr) = BufferStatus_CAN0[buffer];
      *(statusPtr + 1) = BufferMode_CAN0[buffer];
      if (!(CCRcopy & IMASK))
      {
            CLI;                                             /* restore interrupt mask */
      }

      return (ERR_OK);
}

/******************************************************************************
Function Name     :     CAN_L_LoadMB
Engineer          :     Stuart Robb
Date              :     10/8/98

Arguments         :     buffer number
                        address of data 

Return            :     ERR_OK if no error, otherwise error code
******************************************************************************/
UINT8
CAN_L_LoadMB (UINT8 buffer, UINT8 *dataPtr)
{
      UINT8 *bufferPtr;             
      UINT8 dataLength, 
              i;

      if (buffer >= NoOfMB)
      {
            return (ERR_MB);
      }

      if (*dataPtr > 8)
      {
            return (ERR_DLC);
      }

      if ((BufferMode_CAN0[buffer] != TXDF)
            && (BufferMode_CAN0[buffer] != AUTOTXDF))
      {
            return (ERR_CONFIG);
      }

      if ((BufferStatus_CAN0[buffer] == QUEUED)              /* Message Buffer already queued */
            || (BufferStatus_CAN0[buffer] == QUEUED2) 
            || (BufferStatus_CAN0[buffer] == ABORTREQ))
      {
            return (ERR_QED);
      }

      SEI;                                                   /* disable ALL interrupts */
      dataLength = *dataPtr;
      BufferDLC_CAN0[buffer] = dataLength;                   /* copy DLC */

      bufferPtr = BufferData_CAN0[buffer];            
      dataPtr++;                                             /* increment to start of data */

      for (i = 0; i < dataLength; i++)
      {
            bufferPtr[i] = dataPtr[i];                       /* copy data */
      }

      if (!(CCRcopy & IMASK))
      {
            CLI;                                             /* restore interrupt mask */
      }

      BufferStatus_CAN0[buffer] = VALIDDATA;

      return (ERR_OK);
}

/******************************************************************************
Function Name     :     CAN_L_TransmitMB
Engineer          :     Stuart Robb
Date              :     10/8/98

Arguments         :     buffer number 

Return            :     ERR_OK if no error, otherwise error code
******************************************************************************/
UINT8
CAN_L_TransmitMB (UINT8 buffer)
{
      UINT8 bufferStatus, 
              bufferMode;

      if (CANCTL1 & INITAK)
      {
            return (ERR_INIT);
      }

      if ((CANRFLG & BUSOFF) == BUSOFF)
      {
            return (ERR_BOFF);
      }

      if (buffer >= NoOfMB)
      {
            return (ERR_MB);
      }

      SEI;                                                   /* mask ALL interrupts */
      bufferMode = BufferMode_CAN0[buffer];

      if (!((bufferMode == TXDF) || (bufferMode == TXRF)))
      {
            if (!(CCRcopy & IMASK))
            {
                  CLI;                                       /* restore interrupt mask */
            }
            return (ERR_CONFIG);
      }

      bufferStatus = BufferStatus_CAN0[buffer];

      if ((bufferMode == TXDF)
            && (bufferStatus == NODATA))
      {
            if (!(CCRcopy & IMASK))
            {
                  CLI;                                       /* restore interrupt mask */
            }
            return (ERR_NODATA);
      }

      if ((bufferStatus == QUEUED)                           /* MB already queued */
            || (bufferStatus == QUEUED2)  
            || (bufferStatus == ABORTREQ))
      {
            if (!(CCRcopy & IMASK))
            {
                  CLI;                                       /* restore interrupt mask */
            }
            return (ERR_QED);
      }

      CAN_L_QueueMB (buffer);                                /* queue buffer, copy to msCAN if buffer available,   */
                                                             /* abort msCAN buffer if all full and this buffer higher priority */

      if (!(CCRcopy & IMASK))
      {
            CLI;                                             /* restore interrupt mask */
      }

      if (CANCTL1 & SLPAK)                                     /* msCAN in SLEEP mode */
      {                                                           
            CANCTL0 &= ~SLPRQ;                                 /* wake-up msCAN */
      }

      DriverFlags &= ~SLEEP;                                 /* clear sleep request flag */


      if (CANCTL0 & SYNCH)
      {
            return (ERR_OK);
      }

      else
      {
            return (ERR_SYNCH);
      }

}

/******************************************************************************
Function Name     :     CAN_L_QueueMB
Engineer          :     Stuart Robb
Date              :     10/8/98

Arguments         :     buffer number

Return            :     none
Notes             :     All interrupts must be disabled when this function is called
******************************************************************************/
void
CAN_L_QueueMB (UINT8 buffer)
{
      UINT8 MB_ID_Ref = BufferID_Ref_CAN0[buffer];           /* ID_Ref of this MB = priority of MO */

      /* Variables req. only if msCAN transmit buffer is not available */
      UINT8 lowestPriority, 
            lowestPriorityTXBuffer;

      /* If: All msCAN transmit buffers are already scheduled:
       * and if priority of Message Object in buffer is greater (ID_Ref is less) than any
       * Message Object already in msCAN transmit buffer, request abort transmission of the
       * msCAN tx buffer with the   lowest priority Message Object.
       */

      if (CANTIER == 0x07)                             /* msCAN transmit buffers all scheduled */
                                                             /* do not use CANTFLG: TXEn could be set but interrupt not serviced yet */
      {
            if (buffer < LowestQueuedBuffer)
            {
                  LowestQueuedBuffer = buffer;               /* lowest buffer # with QUEUED status, used in TxISR */
            }

            BufferStatus_CAN0[buffer] = QUEUED; 

            if (  (MB_ID_Ref < MBP_MSCAN[0])                  /* queued MO higher priority than MO in msCAN ? */   
                ||(MB_ID_Ref <MBP_MSCAN[1])
                ||(MB_ID_Ref < MBP_MSCAN[2]))                  
            {
                  lowestPriority = MBP_MSCAN[0];              /* find msCAN buffer with lowest priority MO */
                  lowestPriorityTXBuffer = 0x01;
                  
                  if (MBP_MSCAN[1] > lowestPriority)
                  {
                        lowestPriority = MBP_MSCAN[1];
                        lowestPriorityTXBuffer = 0x02;
                  }
                  
                  if (MBP_MSCAN[2] > lowestPriority)
                  {
               //       lowestPriority = TBP_MSCAN[2];
                        lowestPriorityTXBuffer = 0x04;
                  }
                        
                  CANTARQ |= lowestPriorityTXBuffer;  /* set ABTRQ for msCAN buffer */

                  if((AbortMessage == 0xff) || (MB_ID_Ref < BufferID_Ref_CAN0[AbortMessage]))         
                  {
                        AbortMessage = buffer;               /* highest priority queued MB, causing abort */ 
                  }
            }
      }

      /* Else: msCAN transmit buffer is available:
       * Find free tx buffer: copy identifier into buffer.
       * If data frame is to be transmitted, copy data and DLC into buffer, otherwise set RTR bit.
       * Write priority reg, schedule buffer and enable interrupt.
       */

      else
      {
            if (MB_MSCAN[0] == 0xff)                              /* TX_BUFF0 is empty */
            {
                  MBP_MSCAN[0] = BufferID_Ref_CAN0[buffer];
                  MB_MSCAN[0] = buffer;                           /* write buffer # */
                  MSCAN_L_Load_Buff(TX_BUFF0, buffer, MB_ID_Ref);
                  CANTFLG = 0x01;                                 /* write 1 to TXE to schedule buffer */
                  CANTIER |= 0x01;                                /* enable interrupt for this buffer */
            }
            else
            {
                  if (MB_MSCAN[1] == 0xff)                        /* TX_BUFF1 is empty */
                  {
                        MBP_MSCAN[1] = BufferID_Ref_CAN0[buffer];              
                        MB_MSCAN[1] = buffer;                           /* write buffer # */
                        MSCAN_L_Load_Buff(TX_BUFF1, buffer, MB_ID_Ref);
                        CANTFLG = 0x02;                                 /* write 1 to TXE to schedule buffer */
                        CANTIER |= 0x02;                                /* enable interrupt for this buffer */
                  }
                  else                                            /* TX_BUFF2 is empty */
                  {
                        MBP_MSCAN[2] = BufferID_Ref_CAN0[buffer];

⌨️ 快捷键说明

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