NXP's driver library for LPC17xx, ported to mbed's online compiler. Not tested! I had to fix a lot of warings and found a couple of pretty obvious bugs, so the chances are there are more. Original: http://ics.nxp.com/support/documents/microcontrollers/zip/lpc17xx.cmsis.driver.library.zip

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lpc17xx_can.c Source File

lpc17xx_can.c

Go to the documentation of this file.
00001 /**
00002  * @file    : lpc17xx_can.c
00003  * @brief    : Contains all functions support for CAN firmware library on LPC17xx
00004  * @version    : 1.0
00005  * @date    : 1.June.2009
00006  * @author    : NguyenCao
00007  **************************************************************************
00008  * Software that is described herein is for illustrative purposes only
00009  * which provides customers with programming information regarding the
00010  * products. This software is supplied "AS IS" without any warranties.
00011  * NXP Semiconductors assumes no responsibility or liability for the
00012  * use of the software, conveys no license or title under any patent,
00013  * copyright, or mask work right to the product. NXP Semiconductors
00014  * reserves the right to make changes in the software without
00015  * notification. NXP Semiconductors also make no representation or
00016  * warranty that such application will be suitable for the specified
00017  * use without further testing or modification.
00018  **********************************************************************/
00019 
00020 /* Peripheral group ----------------------------------------------------------- */
00021 /** @addtogroup CAN
00022  * @{
00023  */
00024 
00025 /* Includes ------------------------------------------------------------------- */
00026 #include "lpc17xx_can.h"
00027 #include "lpc17xx_clkpwr.h"
00028 
00029 /* If this source file built with example, the LPC17xx FW library configuration
00030  * file in each example directory ("lpc17xx_libcfg.h") must be included,
00031  * otherwise the default FW library configuration file must be included instead
00032  */
00033 #ifdef __BUILD_WITH_EXAMPLE__
00034 #include "lpc17xx_libcfg.h"
00035 #else
00036 #include "lpc17xx_libcfg_default.h"
00037 #endif /* __BUILD_WITH_EXAMPLE__ */
00038 
00039 
00040 #ifdef _CAN
00041 
00042 /* Private Variables ---------------------------------------------------------- */
00043 /** @defgroup CAN_Private_Variables
00044  * @{
00045  */
00046 
00047 FunctionalState FULLCAN_ENABLE;
00048 
00049 //use for debugging
00050 LPC_CAN_TypeDef *CAN1x = LPC_CAN1;
00051 LPC_CAN_TypeDef *CAN2x = LPC_CAN2;
00052 LPC_CANAF_RAM_TypeDef *CANAFRAMx = LPC_CANAF_RAM;
00053 LPC_CANAF_TypeDef *CANAFx = LPC_CANAF;
00054 
00055 /* Values of bit time register for different baudrates
00056    NT = Nominal bit time = TSEG1 + TSEG2 + 3
00057    SP = Sample point     = ((TSEG2 +1) / (TSEG1 + TSEG2 + 3)) * 100%
00058                                             SAM,  SJW, TSEG1, TSEG2, NT,  SP */
00059 const uint32_t CAN_BIT_TIME[] ={0, /*             not used             */
00060 0, /*             not used             */
00061 0, /*             not used             */
00062 0, /*             not used             */
00063 0x0001C000, /* 0+1,  3+1,   1+1,   0+1,  4, 75% */
00064 0, /*             not used             */
00065 0x0012C000, /* 0+1,  3+1,   2+1,   1+1,  6, 67% */
00066 0, /*             not used             */
00067 0x0023C000, /* 0+1,  3+1,   3+1,   2+1,  8, 63% */
00068 0, /*             not used             */
00069 0x0025C000, /* 0+1,  3+1,   5+1,   2+1, 10, 70% */
00070 0, /*             not used             */
00071 0x0036C000, /* 0+1,  3+1,   6+1,   3+1, 12, 67% */
00072 0, /*             not used             */
00073 0, /*             not used             */
00074 0x0048C000, /* 0+1,  3+1,   8+1,   4+1, 15, 67% */
00075 0x0049C000, /* 0+1,  3+1,   9+1,   4+1, 16, 69% */
00076 };
00077 
00078 /* Counts number of filters (CAN message objects) used */
00079 uint16_t CANAF_FullCAN_cnt = 0;
00080 uint16_t CANAF_std_cnt = 0;
00081 uint16_t CANAF_gstd_cnt = 0;
00082 uint16_t CANAF_ext_cnt = 0;
00083 uint16_t CANAF_gext_cnt = 0;
00084 
00085 static fnCANCbs_Type* _apfnCANCbs[12]={
00086         NULL,     //CAN Recieve  Call-back funtion pointer
00087         NULL,    //CAN Transmit1 Call-back funtion pointer
00088         NULL,    //CAN Error Warning Call-back function pointer
00089         NULL,    //CAN Data Overrun Call-back function pointer
00090         NULL,    //CAN Wake-up Call-back funtion pointer
00091         NULL,    //CAN Error Passive Call-back function pointer
00092         NULL,    //CAN Arbitration Lost Call-back function pointer
00093         NULL,    //CAN Bus Error Call-back function pointer
00094         NULL,    //CAN ID Ready Call-back function pointer
00095         NULL,    //CAN Transmit2 Call-back function pointer
00096         NULL,    //CAN Transmit3 Call-back function pointer
00097         NULL    //FullCAN Receive Call-back function pointer
00098 };
00099 
00100 /**
00101  * @}
00102  */
00103 
00104 
00105 /* Public Functions ----------------------------------------------------------- */
00106 /** @addtogroup CAN_Public_Functions
00107  * @{
00108  */
00109 
00110 
00111 /*********************************************************************//**
00112  * @brief         Setting CAN baud rate (bps)
00113  * @param[in]     CANx point to LPC_CAN_TypeDef object, should be:
00114  *                 - CAN1
00115  *                 - CAN2
00116  * @param[in]    baudrate is the baud rate value will be set
00117  * @return         None
00118  ***********************************************************************/
00119 void CAN_SetBaudRate (LPC_CAN_TypeDef *CANx, uint32_t baudrate)
00120 {
00121     uint32_t nominal_time;
00122     uint32_t result = 0;
00123     uint32_t CANPclk = 0;
00124 
00125     CHECK_PARAM(PARAM_CANx(CANx));
00126 
00127     if (CANx == LPC_CAN1)
00128     {
00129         CANPclk = CLKPWR_GetPCLK (CLKPWR_PCONP_PCAN1);
00130     }
00131     else
00132     {
00133         CANPclk = CLKPWR_GetPCLK (CLKPWR_PCONP_PCAN2);
00134     }
00135     /* Determine which nominal time to use for PCLK and baudrate */
00136     if (baudrate <= 500000)
00137     {
00138         nominal_time = 12;
00139     }
00140     else if (((CANPclk / 1000000) % 15) == 0)
00141     {
00142         nominal_time = 15;
00143     }
00144     else if (((CANPclk / 1000000) % 16) == 0)
00145     {
00146         nominal_time = 16;
00147     }
00148     else
00149     {
00150         nominal_time = 10;
00151     }
00152 
00153     /* Prepare value appropriate for bit time register                         */
00154     result  = (CANPclk / nominal_time) / baudrate - 1;
00155     result &= 0x000003FF;
00156     result |= CAN_BIT_TIME[nominal_time];
00157 
00158     /* Enter reset mode */
00159     CANx->MOD = 0x01;
00160     /* Set bit timing */
00161     CANx->BTR  = result;
00162 
00163     /* Return to normal operating */
00164     CANx->MOD = 0;
00165 }
00166 
00167 /********************************************************************//**
00168  * @brief        Initialize CAN peripheral with given baudrate
00169  * @param[in]    CANx pointer to LPC_CAN_TypeDef, should be:
00170  *                 - CAN1: CAN 1
00171  *                 - CAN2: CAN 2
00172  * @param[in]    baudrate: the value of CAN baudrate will be set (bps)
00173  * @return         void
00174  *********************************************************************/
00175 void CAN_Init(LPC_CAN_TypeDef *CANx, uint32_t baudrate)
00176 {
00177     uint32_t temp;
00178     uint16_t i;
00179     CHECK_PARAM(PARAM_CANx(CANx));
00180 
00181     if(CANx == LPC_CAN1)
00182     {
00183         /* Turn on power and clock for CAN1 */
00184         CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN1, ENABLE);
00185         /* Set clock divide for CAN1 */
00186         CLKPWR_SetPCLKDiv (CLKPWR_PCONP_PCAN1, CLKPWR_PCLKSEL_CCLK_DIV_4);
00187     }
00188     else
00189     {
00190         /* Turn on power and clock for CAN1 */
00191         CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN2, ENABLE);
00192         /* Set clock divide for CAN2 */
00193         CLKPWR_SetPCLKDiv (CLKPWR_PCONP_PCAN2, CLKPWR_PCLKSEL_CCLK_DIV_4);
00194     }
00195 
00196     CANx->MOD = 1; // Enter Reset Mode
00197     CANx->IER = 0; // Disable All CAN Interrupts
00198     CANx->GSR = 0;
00199     /* Request command to release Rx, Tx buffer and clear data overrun */
00200     //CANx->CMR = CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO;
00201     CANx->CMR = (1<<1)|(1<<2)|(1<<3);
00202     /* Read to clear interrupt pending in interrupt capture register */
00203     temp = CANx->ICR;
00204     // shut up the compiler
00205     (void)temp;
00206     CANx->MOD = 0;// Return Normal operating
00207 
00208     //Reset CANAF value
00209     LPC_CANAF->AFMR = 0x01;
00210 
00211     //clear ALUT RAM
00212     for (i = 0; i < 512; i++) {
00213         LPC_CANAF_RAM->mask[i] = 0x00;
00214     }
00215 
00216     LPC_CANAF->SFF_sa = 0x00;
00217     LPC_CANAF->SFF_GRP_sa = 0x00;
00218     LPC_CANAF->EFF_sa = 0x00;
00219     LPC_CANAF->EFF_GRP_sa = 0x00;
00220     LPC_CANAF->ENDofTable = 0x00;
00221 
00222     LPC_CANAF->AFMR = 0x00;
00223     /* Set baudrate */
00224     CAN_SetBaudRate (CANx, baudrate);
00225 }
00226 /********************************************************************//**
00227  * @brief        CAN deInit
00228  * @param[in]    CANx pointer to LPC_CAN_TypeDef, should be:
00229  *                 - CAN1: CAN 1
00230  *                 - CAN2: CAN 2
00231  * @return         void
00232  *********************************************************************/
00233 void CAN_DeInit(LPC_CAN_TypeDef *CANx)
00234 {
00235     CHECK_PARAM(PARAM_CANx(CANx));
00236 
00237     if(CANx == LPC_CAN1)
00238     {
00239         /* Turn on power and clock for CAN1 */
00240         CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN1, DISABLE);
00241     }
00242     else
00243     {
00244         /* Turn on power and clock for CAN1 */
00245         CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN2, DISABLE);
00246     }
00247 }
00248 /********************************************************************//**
00249  * @brief        Setup Acceptance Filter Look-Up Table
00250  * @param[in]    CANAFx    pointer to LPC_CANAF_TypeDef, should be: CANAF
00251  * @param[in]    AFSection    the pointer to AF_SectionDef struct
00252  *                 It contain information about 5 sections will be install in AFLUT
00253  * @return         CAN Error    could be:
00254  *                 - CAN_OBJECTS_FULL_ERROR: No more rx or tx objects available
00255  *                 - CAN_AF_ENTRY_ERROR: table error-violation of ascending numerical order
00256  *                 - CAN_OK: ID is added into table successfully
00257  *********************************************************************/
00258 CAN_ERROR CAN_SetupAFLUT(LPC_CANAF_TypeDef* CANAFx, AF_SectionDef* AFSection)
00259 {
00260     uint8_t ctrl1,ctrl2;
00261     uint8_t dis1, dis2;
00262     uint16_t SID, SID_temp,i, count = 0;
00263     uint32_t EID, EID_temp, entry, buf;
00264     uint16_t lowerSID, upperSID;
00265     uint32_t lowerEID, upperEID;
00266 
00267     CHECK_PARAM(PARAM_CANAFx(CANAFx));
00268     CANAFx->AFMR = 0x01;
00269 
00270 /***** setup FullCAN Table *****/
00271     if(AFSection->FullCAN_Sec == NULL)
00272     {
00273         FULLCAN_ENABLE = DISABLE;
00274     }
00275     else
00276     {
00277         FULLCAN_ENABLE = ENABLE;
00278         for(i=0;i<(AFSection->FC_NumEntry);i++)
00279         {
00280             if(count + 1 > 64)
00281             {
00282                 return CAN_OBJECTS_FULL_ERROR;
00283             }
00284             ctrl1 = AFSection->FullCAN_Sec->controller;
00285             SID = AFSection->FullCAN_Sec->id_11;
00286             dis1 = AFSection->FullCAN_Sec->disable;
00287 
00288             CHECK_PARAM(PARAM_CTRL(ctrl1));
00289             CHECK_PARAM(PARAM_ID_11(SID));
00290             CHECK_PARAM(PARAM_MSG_DISABLE(dis1));
00291             entry = 0x00; //reset entry value
00292             if((CANAF_FullCAN_cnt & 0x00000001)==0)
00293             {
00294                 if(count!=0x00)
00295                 {
00296                     buf = LPC_CANAF_RAM->mask[count-1];
00297                     SID_temp = (buf & 0x000003FF);
00298                     if(SID_temp > SID)
00299                     {
00300                         return CAN_AF_ENTRY_ERROR;
00301                     }
00302                 }
00303                 entry = (ctrl1<<29)|(dis1<<28)|(SID<<16)|(1<<27);
00304                 LPC_CANAF_RAM->mask[count] &= 0x0000FFFF;
00305                 LPC_CANAF_RAM->mask[count] |= entry;
00306                 CANAF_FullCAN_cnt++;
00307             }
00308             else
00309             {
00310                 buf = LPC_CANAF_RAM->mask[count];
00311                 SID_temp = (buf & 0x03FF0000)>>16;
00312                 if(SID_temp > SID)
00313                 {
00314                     return CAN_AF_ENTRY_ERROR;
00315                 }
00316                 entry = (ctrl1<<13)|(dis1<<12)|(SID<<0)|(1<<11);
00317                 LPC_CANAF_RAM->mask[count] &= 0xFFFF0000;
00318                 LPC_CANAF_RAM->mask[count]|= entry;
00319                 count++;
00320                 CANAF_FullCAN_cnt++;
00321             }
00322             AFSection->FullCAN_Sec = (FullCAN_Entry *)((uint32_t)(AFSection->FullCAN_Sec)+ sizeof(FullCAN_Entry));
00323         }
00324     }
00325 
00326 /***** Setup Explicit Standard Frame Format Section *****/
00327     if(AFSection->SFF_Sec != NULL)
00328     {
00329         for(i=0;i<(AFSection->SFF_NumEntry);i++)
00330         {
00331             if(count + 1 > 512)
00332             {
00333                 return CAN_OBJECTS_FULL_ERROR;
00334             }
00335             ctrl1 = AFSection->SFF_Sec->controller;
00336             SID = AFSection->SFF_Sec->id_11;
00337             dis1 = AFSection->SFF_Sec->disable;
00338 
00339             //check parameter
00340             CHECK_PARAM(PARAM_CTRL(ctrl1));
00341             CHECK_PARAM(PARAM_ID_11(SID));
00342             CHECK_PARAM(PARAM_MSG_DISABLE(dis1));
00343 
00344             entry = 0x00; //reset entry value
00345             if((CANAF_std_cnt & 0x00000001)==0)
00346             {
00347                 if(CANAF_std_cnt !=0 )
00348                 {
00349                     buf = LPC_CANAF_RAM->mask[count-1];
00350                     SID_temp = (buf & 0x00000FFF);
00351                     if(SID_temp > SID)
00352                     {
00353                         return CAN_AF_ENTRY_ERROR;
00354                     }
00355                 }
00356                 entry = (ctrl1<<29)|(dis1<<28)|(SID<<16);
00357                 LPC_CANAF_RAM->mask[count] &= 0x0000FFFF;
00358                 LPC_CANAF_RAM->mask[count] |= entry;
00359                 CANAF_std_cnt++;
00360             }
00361             else
00362             {
00363                 buf = LPC_CANAF_RAM->mask[count];
00364                 SID_temp = (buf & 0x0FFF0000)>>16;
00365                 if(SID_temp > SID)
00366                 {
00367                     return CAN_AF_ENTRY_ERROR;
00368                 }
00369                 entry = (ctrl1<<13)|(dis1<<12)|(SID<<0);
00370                 LPC_CANAF_RAM->mask[count] &= 0xFFFF0000;
00371                 LPC_CANAF_RAM->mask[count] |= entry;
00372                 count++;
00373                 CANAF_std_cnt++;
00374             }
00375             AFSection->SFF_Sec = (SFF_Entry *)((uint32_t)(AFSection->SFF_Sec)+ sizeof(SFF_Entry));
00376         }
00377     }
00378 
00379 /***** Setup Group of Standard Frame Format Identifier Section *****/
00380     if(AFSection->SFF_GPR_Sec != NULL)
00381     {
00382         for(i=0;i<(AFSection->SFF_GPR_NumEntry);i++)
00383         {
00384             if(count + 1 > 512)
00385             {
00386                 return CAN_OBJECTS_FULL_ERROR;
00387             }
00388             ctrl1 = AFSection->SFF_GPR_Sec->controller1;
00389             ctrl2 = AFSection->SFF_GPR_Sec->controller2;
00390             dis1 = AFSection->SFF_GPR_Sec->disable1;
00391             dis2 = AFSection->SFF_GPR_Sec->disable2;
00392             lowerSID = AFSection->SFF_GPR_Sec->lowerID;
00393             upperSID = AFSection->SFF_GPR_Sec->upperID;
00394 
00395             /* check parameter */
00396             CHECK_PARAM(PARAM_CTRL(ctrl1));
00397             CHECK_PARAM(PARAM_CTRL(ctrl2));
00398             CHECK_PARAM(PARAM_MSG_DISABLE(dis1));
00399             CHECK_PARAM(PARAM_MSG_DISABLE(dis2));
00400             CHECK_PARAM(PARAM_ID_11(lowerSID));
00401             CHECK_PARAM(PARAM_ID_11(upperSID));
00402 
00403             entry = 0x00;
00404             if(CANAF_gstd_cnt!=0)
00405             {
00406                 buf = LPC_CANAF_RAM->mask[count-1];
00407                 SID_temp = buf & 0x00000FFF;
00408                 if(SID_temp > lowerSID)
00409                 {
00410                     return CAN_AF_ENTRY_ERROR;
00411                 }
00412             }
00413             entry = (ctrl1 << 29)|(dis1 << 28)|(lowerSID << 16)|  \
00414                     (ctrl2 << 13)|(dis2 << 12)|(upperSID << 0);
00415             LPC_CANAF_RAM->mask[count] = entry;
00416             CANAF_gstd_cnt++;
00417             count++;
00418             AFSection->SFF_GPR_Sec = (SFF_GPR_Entry *)((uint32_t)(AFSection->SFF_GPR_Sec)+ sizeof(SFF_GPR_Entry));
00419         }
00420     }
00421 
00422 /***** Setup Explicit Extend Frame Format Identifier Section *****/
00423     if(AFSection->EFF_Sec != NULL)
00424     {
00425         for(i=0;i<(AFSection->EFF_NumEntry);i++)
00426         {
00427             if(count + 1 > 512)
00428             {
00429                 return CAN_OBJECTS_FULL_ERROR;
00430             }
00431             EID = AFSection->EFF_Sec->ID_29;
00432             ctrl1 = AFSection->EFF_Sec->controller;
00433 
00434             // check parameter
00435             CHECK_PARAM(PARAM_ID_29(EID));
00436             CHECK_PARAM(PARAM_CTRL(ctrl1));
00437 
00438             entry = 0x00; //reset entry value
00439             if(CANAF_ext_cnt != 0)
00440             {
00441                 buf = LPC_CANAF_RAM->mask[count-1];
00442                 EID_temp = buf & 0x0FFFFFFF;
00443                 if(EID_temp > EID)
00444                 {
00445                     return CAN_AF_ENTRY_ERROR;
00446                 }
00447             }
00448             entry = (ctrl1 << 29)|(EID << 0);
00449             LPC_CANAF_RAM->mask[count] = entry;
00450             CANAF_ext_cnt ++;
00451             count++;
00452             AFSection->EFF_Sec = (EFF_Entry *)((uint32_t)(AFSection->EFF_Sec)+ sizeof(EFF_Entry));
00453         }
00454     }
00455 
00456 /***** Setup Group of Extended Frame Format Identifier Section *****/
00457     if(AFSection->EFF_GPR_Sec != NULL)
00458     {
00459         for(i=0;i<(AFSection->EFF_GPR_NumEntry);i++)
00460         {
00461             if(count + 2 > 512)
00462             {
00463                 return CAN_OBJECTS_FULL_ERROR;
00464             }
00465             ctrl1 = AFSection->EFF_GPR_Sec->controller1;
00466             ctrl2 = AFSection->EFF_GPR_Sec->controller2;
00467             lowerEID = AFSection->EFF_GPR_Sec->lowerEID;
00468             upperEID = AFSection->EFF_GPR_Sec->upperEID;
00469 
00470             //check parameter
00471             CHECK_PARAM(PARAM_CTRL(ctrl1));
00472             CHECK_PARAM(PARAM_CTRL(ctrl2));
00473             CHECK_PARAM(PARAM_ID_29(lowerEID));
00474             CHECK_PARAM(PARAM_ID_29(upperEID));
00475 
00476             entry = 0x00;
00477             if(CANAF_gext_cnt != 0)
00478             {
00479                 buf = LPC_CANAF_RAM->mask[count-1];
00480                 EID_temp = buf & 0x0FFFFFFF;
00481                 if(EID_temp > lowerEID)
00482                 {
00483                     return CAN_AF_ENTRY_ERROR;
00484                 }
00485             }
00486             entry = (ctrl1 << 29)|(lowerEID << 0);
00487             LPC_CANAF_RAM->mask[count++] = entry;
00488             entry = (ctrl2 << 29)|(upperEID << 0);
00489             LPC_CANAF_RAM->mask[count++] = entry;
00490             CANAF_gext_cnt++;
00491             AFSection->EFF_GPR_Sec = (EFF_GPR_Entry *)((uint32_t)(AFSection->EFF_GPR_Sec)+ sizeof(EFF_GPR_Entry));
00492         }
00493     }
00494     //update address values
00495     LPC_CANAF->SFF_sa = ((CANAF_FullCAN_cnt + 1)>>1)<<2;
00496     LPC_CANAF->SFF_GRP_sa = LPC_CANAF->SFF_sa + (((CANAF_std_cnt+1)>>1)<< 2);
00497     LPC_CANAF->EFF_sa = LPC_CANAF->SFF_GRP_sa + (CANAF_gstd_cnt << 2);
00498     LPC_CANAF->EFF_GRP_sa = LPC_CANAF->EFF_sa + (CANAF_ext_cnt << 2);
00499     LPC_CANAF->ENDofTable = LPC_CANAF->EFF_GRP_sa + (CANAF_gext_cnt << 3);
00500 
00501     if(FULLCAN_ENABLE == DISABLE)
00502     {
00503         LPC_CANAF->AFMR = 0x00; // Normal mode
00504     }
00505     else
00506     {
00507         LPC_CANAF->AFMR = 0x04;
00508     }
00509     return CAN_OK;
00510 }
00511 /********************************************************************//**
00512  * @brief        Add Explicit ID into AF Look-Up Table dynamically.
00513  * @param[in]    CANx pointer to LPC_CAN_TypeDef, should be:
00514  *                 - CAN1: CAN 1
00515  *                 - CAN2: CAN 2
00516  * @param[in]    id: The ID of entry will be added
00517  * @param[in]    format: is the type of ID Frame Format, should be:
00518  *                 - STD_ID_FORMAT: 11-bit ID value
00519  *                 - EXT_ID_FORMAT: 29-bit ID value
00520  * @return         CAN Error, could be:
00521  *                 - CAN_OBJECTS_FULL_ERROR: No more rx or tx objects available
00522  *                 - CAN_ID_EXIT_ERROR: ID exited in table
00523  *                 - CAN_OK: ID is added into table successfully
00524  *********************************************************************/
00525 CAN_ERROR CAN_LoadExplicitEntry(LPC_CAN_TypeDef* CANx, uint32_t id, CAN_ID_FORMAT_Type format)
00526 {
00527     uint32_t tmp0 = 0;
00528     uint32_t buf0=0, buf1=0;
00529     int16_t cnt1=0, cnt2=0, bound1=0, total=0;
00530 
00531 
00532     CHECK_PARAM(PARAM_CANx(CANx));
00533     CHECK_PARAM(PARAM_ID_FORMAT(format));
00534 
00535     if (CANx == LPC_CAN1)
00536     {
00537         tmp0 = 0;
00538     }
00539     else if (CANx == LPC_CAN2)
00540     {
00541         tmp0 = 1;
00542     }
00543 
00544     /* Acceptance Filter Memory full - return */
00545     total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+  \
00546             CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
00547     if (total >= 512){ //don't have enough space
00548         return CAN_OBJECTS_FULL_ERROR;
00549     }
00550 
00551     /* Setup Acceptance Filter Configuration
00552     Acceptance Filter Mode Register = Off */
00553     LPC_CANAF->AFMR = 0x00000001;
00554 
00555 /*********** Add Explicit Standard Identifier Frame Format entry *********/
00556      if(format == STD_ID_FORMAT)
00557      {
00558          id &= 0x07FF;
00559          id |= (tmp0 << 13); /* Add controller number */
00560         /* Move all remaining sections one place up
00561         if new entry will increase FullCAN list */
00562         if ((CANAF_std_cnt & 0x0001) == 0)
00563         {
00564             cnt1   = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1);
00565             bound1 = total - cnt1;
00566             buf0   = LPC_CANAF_RAM->mask[cnt1];
00567             while(bound1--)
00568             {
00569                 cnt1++;
00570                 buf1 = LPC_CANAF_RAM->mask[cnt1];
00571                 LPC_CANAF_RAM->mask[cnt1] = buf0;
00572                 buf0 = buf1;
00573             }
00574         }
00575         if (CANAF_std_cnt == 0)
00576         {
00577             cnt2 = (CANAF_FullCAN_cnt + 1)>>1;
00578             /* For entering first ID */
00579             LPC_CANAF_RAM->mask[cnt2] = 0x0000FFFF | (id << 16);
00580         }
00581         else if (CANAF_std_cnt == 1)
00582         {
00583             cnt2 = (CANAF_FullCAN_cnt + 1)>>1;
00584             /* For entering second ID */
00585             if ((LPC_CANAF_RAM->mask[cnt2] >> 16) > id)
00586             {
00587                 LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] >> 16) | (id << 16);
00588             }
00589             else
00590             {
00591                 LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] & 0xFFFF0000) | id;
00592             }
00593         }
00594         else
00595         {
00596             /* Find where to insert new ID */
00597             cnt1 = (CANAF_FullCAN_cnt+1)>>1;
00598             cnt2 = CANAF_std_cnt;
00599             bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1);
00600             while (cnt1 < bound1)
00601             {
00602                 /* Loop through standard existing IDs */
00603                 if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id)
00604                 {
00605                     cnt2 = cnt1 * 2;
00606                     break;
00607                 }
00608 
00609                 if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id)
00610                 {
00611                     cnt2 = cnt1 * 2 + 1;
00612                     break;
00613                 }
00614 
00615                 cnt1++;
00616             }
00617             /* cnt1 = U32 where to insert new ID */
00618             /* cnt2 = U16 where to insert new ID */
00619 
00620             if (cnt1 == bound1)
00621             {
00622                 /* Adding ID as last entry */
00623                 /* Even number of IDs exists */
00624                 if ((CANAF_std_cnt & 0x0001) == 0)
00625                 {
00626                     LPC_CANAF_RAM->mask[cnt1]  = 0x0000FFFF | (id << 16);
00627                 }
00628                 /* Odd  number of IDs exists */
00629                 else
00630                 {
00631                     LPC_CANAF_RAM->mask[cnt1]  = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
00632                 }
00633             }
00634             else
00635             {
00636                 buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */
00637                 if ((cnt2 & 0x0001) == 0)
00638                 {
00639                     /* Insert new mask to even address*/
00640                     buf1 = (id << 16) | (buf0 >> 16);
00641                 }
00642                 else
00643                 {
00644                     /* Insert new mask to odd  address */
00645                     buf1 = (buf0 & 0xFFFF0000) | id;
00646                 }
00647                 LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */
00648                 bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1)-1;
00649                 /* Move all remaining standard mask entries one place up */
00650                 while (cnt1 < bound1)
00651                 {
00652                     cnt1++;
00653                     buf1  = LPC_CANAF_RAM->mask[cnt1];
00654                     LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
00655                     buf0  = buf1;
00656                 }
00657 
00658                 if ((CANAF_std_cnt & 0x0001) == 0)
00659                 {
00660                     /* Even number of IDs exists */
00661                     LPC_CANAF_RAM->mask[cnt1+1] = (buf0 <<16) |(0x0000FFFF);
00662                 }
00663             }
00664         }
00665         CANAF_std_cnt++;
00666         //update address values
00667         LPC_CANAF->SFF_GRP_sa +=0x04 ;
00668         LPC_CANAF->EFF_sa     +=0x04 ;
00669         LPC_CANAF->EFF_GRP_sa +=0x04;
00670         LPC_CANAF->ENDofTable +=0x04;
00671      }
00672 
00673 /*********** Add Explicit Extended Identifier Frame Format entry *********/
00674      else
00675      {
00676          /* Add controller number */
00677          id |= (tmp0) << 29;
00678 
00679          cnt1 = ((CANAF_FullCAN_cnt+1)>>1)+(((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt);
00680          cnt2 = 0;
00681          while (cnt2 < CANAF_ext_cnt)
00682          {
00683              /* Loop through extended existing masks*/
00684              if (LPC_CANAF_RAM->mask[cnt1] > id)
00685              {
00686                  break;
00687              }
00688              cnt1++;/* cnt1 = U32 where to insert new mask */
00689             cnt2++;
00690          }
00691 
00692          buf0 = LPC_CANAF_RAM->mask[cnt1];  /* Remember current entry */
00693          LPC_CANAF_RAM->mask[cnt1] = id;    /* Insert mask */
00694 
00695          CANAF_ext_cnt++;
00696 
00697          bound1 = total;
00698          /* Move all remaining extended mask entries one place up*/
00699          while (cnt2 < bound1)
00700          {
00701              cnt1++;
00702              cnt2++;
00703              buf1 = LPC_CANAF_RAM->mask[cnt1];
00704              LPC_CANAF_RAM->mask[cnt1] = buf0;
00705              buf0 = buf1;
00706          }
00707          /* update address values */
00708          LPC_CANAF->EFF_GRP_sa += 4;
00709          LPC_CANAF->ENDofTable += 4;
00710      }
00711      if(CANAF_FullCAN_cnt == 0) //not use FullCAN mode
00712      {
00713          LPC_CANAF->AFMR = 0x00;//not use FullCAN mode
00714      }
00715      else
00716      {
00717          LPC_CANAF->AFMR = 0x04;
00718      }
00719 
00720      return CAN_OK;
00721 }
00722 
00723 /********************************************************************//**
00724  * @brief        Load FullCAN entry into AFLUT
00725  * @param[in]    CANx: CAN peripheral selected, should be:
00726  *                 - CAN1: CAN 1
00727  *                 - CAN2: CAN 2
00728  * @param[in]    id: identifier of entry that will be added
00729  * @return         CAN_ERROR, could be:
00730  *                 - CAN_OK: loading is successful
00731  *                 - CAN_ID_EXIT_ERROR: ID exited in FullCAN Section
00732  *                 - CAN_OBJECTS_FULL_ERROR: no more space available
00733  *********************************************************************/
00734 CAN_ERROR CAN_LoadFullCANEntry (LPC_CAN_TypeDef* CANx, uint16_t id)
00735 {
00736     uint32_t ctrl0 = 0;
00737     uint32_t buf0=0, buf1=0, buf2=0;
00738     uint32_t tmp0=0, tmp1=0, tmp2=0;
00739     int16_t cnt1=0, cnt2=0, bound1=0, total=0;
00740 
00741     CHECK_PARAM(PARAM_CANx(CANx));
00742 
00743     if (CANx == LPC_CAN1)
00744     {
00745         ctrl0 = 0;
00746     }
00747     else if (CANx == LPC_CAN2)
00748     {
00749         ctrl0 = 1;
00750     }
00751 
00752     /* Acceptance Filter Memory full - return */
00753     total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+  \
00754             CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
00755     //don't have enough space for this fullCAN Entry and its Object(3*32 bytes)
00756     if ((total >=508)||(CANAF_FullCAN_cnt>=64)){
00757         return CAN_OBJECTS_FULL_ERROR;
00758     }
00759     /* Setup Acceptance Filter Configuration
00760     Acceptance Filter Mode Register = Off */
00761     LPC_CANAF->AFMR = 0x00000001;
00762 
00763     /* Add mask for standard identifiers   */
00764     id &= 0x07FF;
00765     id |= (ctrl0 << 13) | (1 << 11); /* Add controller number */
00766 //    total = ((CANAF_std_cnt + 1) >> 1)+ CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
00767     /* Move all remaining sections one place up
00768     if new entry will increase FullCAN list */
00769     if (((CANAF_FullCAN_cnt & 0x0001) == 0)&&(total!=0))
00770     {
00771         //then remove remaining section
00772         cnt1   = (CANAF_FullCAN_cnt >> 1);
00773         bound1 = total;
00774         buf0   = LPC_CANAF_RAM->mask[cnt1];
00775 
00776         while (bound1--)
00777         {
00778             cnt1++;
00779             buf1 = LPC_CANAF_RAM->mask[cnt1];
00780             LPC_CANAF_RAM->mask[cnt1] = buf0;
00781             buf0 = buf1;
00782         }
00783     }
00784     if (CANAF_FullCAN_cnt == 0)
00785     {
00786         /* For entering first ID */
00787         LPC_CANAF_RAM->mask[0] = 0x0000FFFF | (id << 16);
00788     }
00789     else if (CANAF_FullCAN_cnt == 1)
00790     {
00791         /* For entering second ID */
00792         if ((LPC_CANAF_RAM->mask[0] >> 16) > id)
00793         {
00794             LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] >> 16) | (id << 16);
00795         }
00796         else
00797         {
00798             LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] & 0xFFFF0000) | id;
00799         }
00800     }
00801     else
00802     {
00803         /* Find where to insert new ID */
00804         cnt1 = 0;
00805         cnt2 = CANAF_FullCAN_cnt;
00806         bound1 = (CANAF_FullCAN_cnt - 1) >> 1;
00807         while (cnt1 <= bound1)
00808         {
00809             /* Loop through standard existing IDs */
00810             if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id)
00811             {
00812                 cnt2 = cnt1 * 2;
00813                 break;
00814             }
00815 
00816             if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id)
00817             {
00818                 cnt2 = cnt1 * 2 + 1;
00819                 break;
00820             }
00821 
00822             cnt1++;
00823         }
00824         /* cnt1 = U32 where to insert new ID */
00825         /* cnt2 = U16 where to insert new ID */
00826 
00827         if (cnt1 > bound1)
00828         {
00829             /* Adding ID as last entry */
00830             /* Even number of IDs exists */
00831             if ((CANAF_FullCAN_cnt & 0x0001) == 0)
00832             {
00833                 LPC_CANAF_RAM->mask[cnt1]  = 0x0000FFFF | (id << 16);
00834             }
00835             /* Odd  number of IDs exists */
00836             else
00837             {
00838                 LPC_CANAF_RAM->mask[cnt1]  = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
00839             }
00840         }
00841         else
00842         {
00843             buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */
00844             if ((cnt2 & 0x0001) == 0)
00845             {
00846                 /* Insert new mask to even address*/
00847                 buf1 = (id << 16) | (buf0 >> 16);
00848             }
00849             else
00850             {
00851                 /* Insert new mask to odd  address */
00852                 buf1 = (buf0 & 0xFFFF0000) | id;
00853             }
00854             LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */
00855             bound1 = CANAF_FullCAN_cnt >> 1;
00856             /* Move all remaining standard mask entries one place up */
00857             while (cnt1 < bound1)
00858             {
00859                 cnt1++;
00860                 buf1  = LPC_CANAF_RAM->mask[cnt1];
00861                 LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
00862                 buf0  = buf1;
00863             }
00864 
00865             if ((CANAF_FullCAN_cnt & 0x0001) == 0)
00866             {
00867                 /* Even number of IDs exists */
00868                 LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000)
00869                                             | (0x0000FFFF);
00870             }
00871         }
00872     }
00873     //restruct FulCAN Object Section
00874     bound1 = CANAF_FullCAN_cnt - cnt2;
00875     cnt1 = total - (CANAF_FullCAN_cnt)*3 + cnt2*3 + 1;
00876     buf0 = LPC_CANAF_RAM->mask[cnt1];
00877     buf1 = LPC_CANAF_RAM->mask[cnt1+1];
00878     buf2 = LPC_CANAF_RAM->mask[cnt1+2];
00879     LPC_CANAF_RAM->mask[cnt1]=LPC_CANAF_RAM->mask[cnt1+1]= LPC_CANAF_RAM->mask[cnt1+2]=0x00;
00880     cnt1+=3;
00881     while(bound1--)
00882     {
00883         tmp0 = LPC_CANAF_RAM->mask[cnt1];
00884         tmp1 = LPC_CANAF_RAM->mask[cnt1+1];
00885         tmp2 = LPC_CANAF_RAM->mask[cnt1+2];
00886         LPC_CANAF_RAM->mask[cnt1]= buf0;
00887         LPC_CANAF_RAM->mask[cnt1+1]= buf1;
00888         LPC_CANAF_RAM->mask[cnt1+2]= buf2;
00889         buf0 = tmp0;
00890         buf1 = tmp1;
00891         buf2 = tmp2;
00892         cnt1+=3;
00893     }
00894     CANAF_FullCAN_cnt++;
00895     //update address values
00896     LPC_CANAF->SFF_sa       +=0x04;
00897     LPC_CANAF->SFF_GRP_sa +=0x04 ;
00898     LPC_CANAF->EFF_sa     +=0x04 ;
00899     LPC_CANAF->EFF_GRP_sa +=0x04;
00900     LPC_CANAF->ENDofTable +=0x04;
00901 
00902     LPC_CANAF->AFMR = 0x04;
00903      return CAN_OK;
00904 }
00905 
00906 /********************************************************************//**
00907  * @brief        Load Group entry into AFLUT
00908  * @param[in]    CANx: CAN peripheral selected, should be:
00909  *                 - CAN1: CAN 1
00910  *                 - CAN2: CAN 2
00911  * @param[in]    lowerID, upperID: lower and upper identifier of entry
00912  * @param[in]    format: type of ID format, should be:
00913  *                 - STD_ID_FORMAT: Standard ID format (11-bit value)
00914  *                 - EXT_ID_FORMAT: Extended ID format (29-bit value)
00915  * @return         CAN_ERROR, could be:
00916  *                 - CAN_OK: loading is successful
00917  *                 - CAN_CONFLICT_ID_ERROR: Conflict ID occurs
00918  *                 - CAN_OBJECTS_FULL_ERROR: no more space available
00919  *********************************************************************/
00920 CAN_ERROR CAN_LoadGroupEntry(LPC_CAN_TypeDef* CANx, uint32_t lowerID, \
00921         uint32_t upperID, CAN_ID_FORMAT_Type format)
00922 {
00923     uint16_t tmp = 0;
00924     uint32_t buf0=0, buf1=0, entry1, entry2, LID,UID;
00925     int16_t cnt1, bound1, total;
00926 
00927     CHECK_PARAM(PARAM_CANx(CANx));
00928     CHECK_PARAM(PARAM_ID_FORMAT(format));
00929 
00930     if(lowerID > upperID) return CAN_CONFLICT_ID_ERROR;
00931     if(CANx == LPC_CAN1)
00932     {
00933         tmp = 0;
00934     }
00935     else
00936     {
00937         tmp = 1;
00938     }
00939 
00940     total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+  \
00941             CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
00942 
00943     /* Setup Acceptance Filter Configuration
00944     Acceptance Filter Mode Register = Off */
00945     LPC_CANAF->AFMR = 0x00000001;
00946 
00947 /*********Add Group of Standard Identifier Frame Format************/
00948     if(format == STD_ID_FORMAT)
00949     {
00950         if ((total >= 512)){//don't have enough space
00951             return CAN_OBJECTS_FULL_ERROR;
00952         }
00953         lowerID &=0x7FF; //mask ID
00954         upperID &=0x7FF;
00955         entry1  = (tmp << 29)|(lowerID << 16)|(tmp << 13)|(upperID << 0);
00956         cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1);
00957 
00958         //if this is the first Group standard ID entry
00959         if(CANAF_gstd_cnt == 0)
00960         {
00961             LPC_CANAF_RAM->mask[cnt1] = entry1;
00962         }
00963         else
00964         {
00965             //find the position to add new Group entry
00966             bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt;
00967             while(cnt1 < bound1)
00968             {
00969                 buf0 = LPC_CANAF_RAM->mask[cnt1];
00970                 LID  = (buf0 >> 16)&0x7FF;
00971                 UID  = buf0 & 0x7FF;
00972                 if (upperID <= LID)
00973                 {
00974                     //add new entry before this entry
00975                     LPC_CANAF_RAM->mask[cnt1] = entry1;
00976                     break;
00977                 }
00978                 else if (lowerID >= UID)
00979                 {
00980                     //load next entry to compare
00981                     cnt1 ++;
00982                 }
00983                 else
00984                     return CAN_CONFLICT_ID_ERROR;
00985             }
00986             if(cnt1 >= bound1)
00987             {
00988                 //add new entry at the last position in this list
00989                 buf0 = LPC_CANAF_RAM->mask[cnt1];
00990                 LPC_CANAF_RAM->mask[cnt1] = entry1;
00991             }
00992 
00993             //remove all remaining entry of this section one place up
00994             bound1 = total - cnt1;
00995             while(bound1--)
00996             {
00997                 cnt1++;
00998                 buf1 = LPC_CANAF_RAM->mask[cnt1];
00999                 LPC_CANAF_RAM->mask[cnt1] = buf0;
01000                 buf0 = buf1;
01001             }
01002         }
01003         CANAF_gstd_cnt++;
01004         //update address values
01005         LPC_CANAF->EFF_sa     +=0x04 ;
01006         LPC_CANAF->EFF_GRP_sa +=0x04;
01007         LPC_CANAF->ENDofTable +=0x04;
01008     }
01009 
01010 
01011 /*********Add Group of Extended Identifier Frame Format************/
01012     else
01013     {
01014         if ((total >= 511)){//don't have enough space
01015             return CAN_OBJECTS_FULL_ERROR;
01016         }
01017         lowerID  &= 0x1FFFFFFF; //mask ID
01018         upperID &= 0x1FFFFFFF;
01019         entry1   = (tmp << 29)|(lowerID << 0);
01020         entry2   = (tmp << 29)|(upperID << 0);
01021 
01022         cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt + CANAF_ext_cnt;
01023         //if this is the first Group standard ID entry
01024         if(CANAF_gext_cnt == 0)
01025         {
01026             LPC_CANAF_RAM->mask[cnt1] = entry1;
01027             LPC_CANAF_RAM->mask[cnt1+1] = entry2;
01028         }
01029         else
01030         {
01031             //find the position to add new Group entry
01032             bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt \
01033                         + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
01034             while(cnt1 < bound1)
01035             {
01036                 buf0 = LPC_CANAF_RAM->mask[cnt1];
01037                 buf1 = LPC_CANAF_RAM->mask[cnt1+1];
01038                 LID  = buf0 & 0x1FFFFFFF; //mask ID
01039                 UID  = buf1 & 0x1FFFFFFF;
01040                 if (upperID <= LID)
01041                 {
01042                     //add new entry before this entry
01043                     LPC_CANAF_RAM->mask[cnt1] = entry1;
01044                     LPC_CANAF_RAM->mask[++cnt1] = entry2;
01045                     break;
01046                 }
01047                 else if (lowerID >= UID)
01048                 {
01049                     //load next entry to compare
01050                     cnt1 +=2;
01051                 }
01052                 else
01053                     return CAN_CONFLICT_ID_ERROR;
01054             }
01055             if(cnt1 >= bound1)
01056             {
01057                 //add new entry at the last position in this list
01058                 buf0 = LPC_CANAF_RAM->mask[cnt1];
01059                 buf1 = LPC_CANAF_RAM->mask[cnt1+1];
01060                 LPC_CANAF_RAM->mask[cnt1]   = entry1;
01061                 LPC_CANAF_RAM->mask[++cnt1] = entry2;
01062             }
01063             //remove all remaining entry of this section two place up
01064             bound1 = total - cnt1 + 1;
01065             cnt1++;
01066             while(bound1>0)
01067             {
01068                 entry1 = LPC_CANAF_RAM->mask[cnt1];
01069                 entry2 = LPC_CANAF_RAM->mask[cnt1+1];
01070                 LPC_CANAF_RAM->mask[cnt1]   = buf0;
01071                 LPC_CANAF_RAM->mask[cnt1+1] = buf1;
01072                 buf0 = entry1;
01073                 buf1 = entry2;
01074                 cnt1   +=2;
01075                 bound1 -=2;
01076             }
01077         }
01078         CANAF_gext_cnt++;
01079         //update address values
01080         LPC_CANAF->ENDofTable +=0x08;
01081     }
01082     LPC_CANAF->AFMR = 0x04;
01083      return CAN_OK;
01084 }
01085 
01086 /********************************************************************//**
01087  * @brief        Remove AFLUT entry (FullCAN entry and Explicit Standard entry)
01088  * @param[in]    EntryType: the type of entry that want to remove, should be:
01089  *                 - FULLCAN_ENTRY
01090  *                 - EXPLICIT_STANDARD_ENTRY
01091  *                 - GROUP_STANDARD_ENTRY
01092  *                 - EXPLICIT_EXTEND_ENTRY
01093  *                 - GROUP_EXTEND_ENTRY
01094  * @param[in]    position: the position of this entry in its section
01095  * Note: the first position is 0
01096  * @return         CAN_ERROR, could be:
01097  *                 - CAN_OK: removing is successful
01098  *                 - CAN_ENTRY_NOT_EXIT_ERROR: entry want to remove is not exit
01099  *********************************************************************/
01100 CAN_ERROR CAN_RemoveEntry(AFLUT_ENTRY_Type EntryType, uint16_t position)
01101 {
01102     uint16_t cnt, bound, total;
01103     uint32_t buf0, buf1;
01104     CHECK_PARAM(PARAM_AFLUT_ENTRY_TYPE(EntryType));
01105     CHECK_PARAM(PARAM_POSITION(position));
01106 
01107     /* Setup Acceptance Filter Configuration
01108     Acceptance Filter Mode Register = Off */
01109     LPC_CANAF->AFMR = 0x00000001;
01110     total = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt + 1) >> 1) + \
01111             CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
01112 
01113 
01114 /************** Remove FullCAN Entry *************/
01115     if(EntryType == FULLCAN_ENTRY)
01116     {
01117         if((CANAF_FullCAN_cnt==0)||(position >= CANAF_FullCAN_cnt))
01118         {
01119             return CAN_ENTRY_NOT_EXIT_ERROR;
01120         }
01121         else
01122         {
01123             cnt = position >> 1;
01124             buf0 = LPC_CANAF_RAM->mask[cnt];
01125             bound = (CANAF_FullCAN_cnt - position -1)>>1;
01126             if((position & 0x0001) == 0) //event position
01127             {
01128                 while(bound--)
01129                 {
01130                     //remove all remaining FullCAN entry one place down
01131                     buf1  = LPC_CANAF_RAM->mask[cnt+1];
01132                     LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16);
01133                     buf0  = buf1;
01134                     cnt++;
01135                 }
01136             }
01137             else //odd position
01138             {
01139                 while(bound--)
01140                 {
01141                     //remove all remaining FullCAN entry one place down
01142                     buf1  = LPC_CANAF_RAM->mask[cnt+1];
01143                     LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000)|(buf1 >> 16);
01144                     LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+1] << 16;
01145                     buf0  = buf1<<16;
01146                     cnt++;
01147                 }
01148             }
01149             if((CANAF_FullCAN_cnt & 0x0001) == 0)
01150             {
01151                 if((position & 0x0001)==0)
01152                     LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF);
01153                 else
01154                     LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF;
01155             }
01156             else
01157             {
01158                 //remove all remaining section one place down
01159                 cnt = (CANAF_FullCAN_cnt + 1)>>1;
01160                 bound = total + CANAF_FullCAN_cnt * 3;
01161                 while(bound>cnt)
01162                 {
01163                     LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
01164                     cnt++;
01165                 }
01166                 LPC_CANAF_RAM->mask[cnt-1]=0x00;
01167                 //update address values
01168                 LPC_CANAF->SFF_sa       -=0x04;
01169                 LPC_CANAF->SFF_GRP_sa -=0x04 ;
01170                 LPC_CANAF->EFF_sa     -=0x04 ;
01171                 LPC_CANAF->EFF_GRP_sa -=0x04;
01172                 LPC_CANAF->ENDofTable -=0x04;
01173             }
01174             CANAF_FullCAN_cnt--;
01175 
01176             //delete its FullCAN Object in the FullCAN Object section
01177             //remove all remaining FullCAN Object three place down
01178             cnt = total + position * 3;
01179             bound = (CANAF_FullCAN_cnt - position + 1) * 3;
01180 
01181             while(bound)
01182             {
01183                 LPC_CANAF_RAM->mask[cnt]=LPC_CANAF_RAM->mask[cnt+3];;
01184                 LPC_CANAF_RAM->mask[cnt+1]=LPC_CANAF_RAM->mask[cnt+4];
01185                 LPC_CANAF_RAM->mask[cnt+2]=LPC_CANAF_RAM->mask[cnt+5];
01186                 bound -=3;
01187                 cnt   +=3;
01188             }
01189         }
01190     }
01191 
01192 /************** Remove Explicit Standard ID Entry *************/
01193     else if(EntryType == EXPLICIT_STANDARD_ENTRY)
01194     {
01195         if((CANAF_std_cnt==0)||(position >= CANAF_std_cnt))
01196         {
01197             return CAN_ENTRY_NOT_EXIT_ERROR;
01198         }
01199         else
01200         {
01201             cnt = ((CANAF_FullCAN_cnt+1)>>1)+ (position >> 1);
01202             buf0 = LPC_CANAF_RAM->mask[cnt];
01203             bound = (CANAF_std_cnt - position - 1)>>1;
01204             if((position & 0x0001) == 0) //event position
01205             {
01206                 while(bound--)
01207                 {
01208                     //remove all remaining FullCAN entry one place down
01209                     buf1  = LPC_CANAF_RAM->mask[cnt+1];
01210                     LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16);
01211                     buf0  = buf1;
01212                     cnt++;
01213                 }
01214             }
01215             else //odd position
01216             {
01217                 while(bound--)
01218                 {
01219                     //remove all remaining FullCAN entry one place down
01220                     buf1  = LPC_CANAF_RAM->mask[cnt+1];
01221                     LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000)|(buf1 >> 16);
01222                     LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+1] << 16;
01223                     buf0  = buf1<<16;
01224                     cnt++;
01225                 }
01226             }
01227             if((CANAF_std_cnt & 0x0001) == 0)
01228             {
01229                 if((position & 0x0001)==0)
01230                     LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF);
01231                 else
01232                     LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF;
01233             }
01234             else
01235             {
01236                 //remove all remaining section one place down
01237                 cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1);
01238                 bound = total + CANAF_FullCAN_cnt * 3;
01239                 while(bound>cnt)
01240                 {
01241                     LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
01242                     cnt++;
01243                 }
01244                 LPC_CANAF_RAM->mask[cnt-1]=0x00;
01245                 //update address value
01246                 LPC_CANAF->SFF_GRP_sa -=0x04 ;
01247                 LPC_CANAF->EFF_sa     -=0x04 ;
01248                 LPC_CANAF->EFF_GRP_sa -=0x04;
01249                 LPC_CANAF->ENDofTable -=0x04;
01250             }
01251             CANAF_std_cnt--;
01252         }
01253     }
01254 
01255 /************** Remove Group of Standard ID Entry *************/
01256     else if(EntryType == GROUP_STANDARD_ENTRY)
01257     {
01258         if((CANAF_gstd_cnt==0)||(position >= CANAF_gstd_cnt))
01259         {
01260             return CAN_ENTRY_NOT_EXIT_ERROR;
01261         }
01262         else
01263         {
01264             cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1)+ position + 1;
01265             bound = total + CANAF_FullCAN_cnt * 3;
01266             while (cnt<bound)
01267             {
01268                 LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
01269                 cnt++;
01270             }
01271             LPC_CANAF_RAM->mask[cnt-1]=0x00;
01272         }
01273         CANAF_gstd_cnt--;
01274         //update address value
01275         LPC_CANAF->EFF_sa     -=0x04;
01276         LPC_CANAF->EFF_GRP_sa -=0x04;
01277         LPC_CANAF->ENDofTable -=0x04;
01278     }
01279 
01280 /************** Remove Explicit Extended ID Entry *************/
01281     else if(EntryType == EXPLICIT_EXTEND_ENTRY)
01282     {
01283         if((CANAF_ext_cnt==0)||(position >= CANAF_ext_cnt))
01284         {
01285             return CAN_ENTRY_NOT_EXIT_ERROR;
01286         }
01287         else
01288         {
01289             cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1)+ CANAF_gstd_cnt + position + 1;
01290             bound = total + CANAF_FullCAN_cnt * 3;
01291             while (cnt<bound)
01292             {
01293                 LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
01294                 cnt++;
01295             }
01296             LPC_CANAF_RAM->mask[cnt-1]=0x00;
01297         }
01298         CANAF_ext_cnt--;
01299         LPC_CANAF->EFF_GRP_sa -=0x04;
01300         LPC_CANAF->ENDofTable -=0x04;
01301     }
01302 
01303 /************** Remove Group of Extended ID Entry *************/
01304     else
01305     {
01306         if((CANAF_gext_cnt==0)||(position >= CANAF_gext_cnt))
01307         {
01308             return CAN_ENTRY_NOT_EXIT_ERROR;
01309         }
01310         else
01311         {
01312             cnt = total - (CANAF_gext_cnt<<1) + (position<<1);
01313             bound = total + CANAF_FullCAN_cnt * 3;
01314             while (cnt<bound)
01315             {
01316                 //remove all remaining entry two place up
01317                 LPC_CANAF_RAM->mask[cnt] = LPC_CANAF_RAM->mask[cnt+2];
01318                 LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+3];
01319                 cnt+=2;
01320             }
01321         }
01322         CANAF_gext_cnt--;
01323         LPC_CANAF->ENDofTable -=0x08;
01324     }
01325     LPC_CANAF->AFMR = 0x04;
01326     return CAN_OK;
01327 }
01328 
01329 /********************************************************************//**
01330  * @brief        Send message data
01331  * @param[in]    CANx pointer to LPC_CAN_TypeDef, should be:
01332  *                 - CAN1: CAN 1
01333  *                 - CAN2: CAN 2
01334  * @param[in]    CAN_Msg point to the CAN_MSG_Type Structure, it contains message
01335  *                 information such as: ID, DLC, RTR, ID Format
01336  * @return         Status:
01337  *                 - SUCCESS: send message successfully
01338  *                 - ERROR: send message unsuccessfully
01339  *********************************************************************/
01340 Status CAN_SendMsg (LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg)
01341 {
01342     uint32_t data;
01343     CHECK_PARAM(PARAM_CANx(CANx));
01344     CHECK_PARAM(PARAM_ID_FORMAT(CAN_Msg->format));
01345     if(CAN_Msg->format==STD_ID_FORMAT)
01346     {
01347         CHECK_PARAM(PARAM_ID_11(CAN_Msg->id));
01348     }
01349     else
01350     {
01351         CHECK_PARAM(PARAM_ID_29(CAN_Msg->id));
01352     }
01353     CHECK_PARAM(PARAM_DLC(CAN_Msg->len));
01354     CHECK_PARAM(PARAM_FRAME_TYPE(CAN_Msg->type));
01355 
01356     //Check status of Transmit Buffer 1
01357     if ((CANx->SR & 0x00000004)>>2)
01358     {
01359         /* Transmit Channel 1 is available */
01360         /* Write frame informations and frame data into its CANxTFI1,
01361          * CANxTID1, CANxTDA1, CANxTDB1 register */
01362         CANx->TFI1 &= ~0x000F000;
01363         CANx->TFI1 |= (CAN_Msg->len)<<16;
01364         if(CAN_Msg->type == REMOTE_FRAME)
01365         {
01366             CANx->TFI1 |= (1<<30); //set bit RTR
01367         }
01368         else
01369         {
01370             CANx->TFI1 &= ~(1<<30);
01371         }
01372         if(CAN_Msg->format == EXT_ID_FORMAT)
01373         {
01374             CANx->TFI1 |= (1UL<<31); //set bit FF
01375         }
01376         else
01377         {
01378             CANx->TFI1 &= ~(1UL<<31);
01379         }
01380 
01381         /* Write CAN ID*/
01382         CANx->TID1 = CAN_Msg->id;
01383 
01384         /*Write first 4 data bytes*/
01385         data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);
01386 //        CANx->TDA1 = *((uint32_t *) &(CAN_Msg->dataA));
01387         CANx->TDA1 = data;
01388 
01389         /*Write second 4 data bytes*/
01390         data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);
01391 //        CANx->TDB1 = *((uint32_t *) &(CAN_Msg->dataB));
01392         CANx->TDB1 = data;
01393 
01394          /*Write transmission request*/
01395          CANx->CMR = 0x21;
01396          return SUCCESS;
01397     }
01398     //check status of Transmit Buffer 2
01399     else if((CANx->SR & 0x00000004)>>10)
01400     {
01401         /* Transmit Channel 2 is available */
01402         /* Write frame informations and frame data into its CANxTFI2,
01403          * CANxTID2, CANxTDA2, CANxTDB2 register */
01404         CANx->TFI2 &= ~0x000F000;
01405         CANx->TFI2 |= (CAN_Msg->len)<<16;
01406         if(CAN_Msg->type == REMOTE_FRAME)
01407         {
01408             CANx->TFI2 |= (1<<30); //set bit RTR
01409         }
01410         else
01411         {
01412             CANx->TFI2 &= ~(1<<30);
01413         }
01414         if(CAN_Msg->format == EXT_ID_FORMAT)
01415         {
01416             CANx->TFI2 |= (1UL<<31); //set bit FF
01417         }
01418         else
01419         {
01420             CANx->TFI2 &= ~(1UL<<31);
01421         }
01422 
01423         /* Write CAN ID*/
01424         CANx->TID2 = CAN_Msg->id;
01425 
01426         /*Write first 4 data bytes*/
01427         data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);
01428 //        CANx->TDA2 = *((uint32_t *) &(CAN_Msg->dataA));
01429         CANx->TDA2 = data;
01430 
01431         /*Write second 4 data bytes*/
01432         data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);
01433 //        CANx->TDB2 = *((uint32_t *) &(CAN_Msg->dataB));
01434         CANx->TDB2 = data;
01435 
01436         /*Write transmission request*/
01437         CANx->CMR = 0x41;
01438         return SUCCESS;
01439     }
01440     //check status of Transmit Buffer 3
01441     else if ((CANx->SR & 0x00000004)>>18)
01442     {
01443         /* Transmit Channel 3 is available */
01444         /* Write frame informations and frame data into its CANxTFI3,
01445          * CANxTID3, CANxTDA3, CANxTDB3 register */
01446         CANx->TFI3 &= ~0x000F000;
01447         CANx->TFI3 |= (CAN_Msg->len)<<16;
01448         if(CAN_Msg->type == REMOTE_FRAME)
01449         {
01450             CANx->TFI3 |= (1<<30); //set bit RTR
01451         }
01452         else
01453         {
01454             CANx->TFI3 &= ~(1<<30);
01455         }
01456         if(CAN_Msg->format == EXT_ID_FORMAT)
01457         {
01458             CANx->TFI3 |= (1UL<<31); //set bit FF
01459         }
01460         else
01461         {
01462             CANx->TFI3 &= ~(1UL<<31);
01463         }
01464 
01465         /* Write CAN ID*/
01466         CANx->TID3 = CAN_Msg->id;
01467 
01468         /*Write first 4 data bytes*/
01469         data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);
01470 //        CANx->TDA3 = *((uint32_t *) &(CAN_Msg->dataA));
01471         CANx->TDA3 = data;
01472 
01473         /*Write second 4 data bytes*/
01474         data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);
01475 //        CANx->TDB3 = *((uint32_t *) &(CAN_Msg->dataB));
01476         CANx->TDB3 = data;
01477 
01478         /*Write transmission request*/
01479         CANx->CMR = 0x81;
01480         return SUCCESS;
01481     }
01482     else
01483     {
01484         return ERROR;
01485     }
01486 }
01487 
01488 /********************************************************************//**
01489  * @brief        Receive message data
01490  * @param[in]    CANx pointer to LPC_CAN_TypeDef, should be:
01491  *                 - CAN1: CAN 1
01492  *                 - CAN2: CAN 2
01493  * @param[in]    CAN_Msg point to the CAN_MSG_Type Struct, it will contain received
01494  *              message information such as: ID, DLC, RTR, ID Format
01495  * @return         Status:
01496  *                 - SUCCESS: receive message successfully
01497  *                 - ERROR: receive message unsuccessfully
01498  *********************************************************************/
01499 Status CAN_ReceiveMsg (LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg)
01500 {
01501     uint32_t data;
01502 
01503     CHECK_PARAM(PARAM_CANx(CANx));
01504 
01505     //check status of Receive Buffer
01506     if((CANx->SR &0x00000001))
01507     {
01508         /* Receive message is available */
01509         /* Read frame informations */
01510         CAN_Msg->format   = (uint8_t)(((CANx->RFS) & 0x80000000)>>31);
01511         CAN_Msg->type     = (uint8_t)(((CANx->RFS) & 0x40000000)>>30);
01512         CAN_Msg->len      = (uint8_t)(((CANx->RFS) & 0x000F0000)>>16);
01513 
01514 
01515         /* Read CAN message identifier */
01516         CAN_Msg->id = CANx->RID;
01517 
01518         /* Read the data if received message was DATA FRAME */
01519         if (CAN_Msg->type == DATA_FRAME)
01520         {
01521             /* Read first 4 data bytes */
01522 //            *((uint32_t *) &CAN_Msg->dataA) = CANx->RDA;
01523             data = CANx->RDA;
01524             *((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF;
01525             *((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00)>>8;;
01526             *((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000)>>16;
01527             *((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000)>>24;
01528 
01529             /* Read second 4 data bytes */
01530 //            *((uint32_t *) &CAN_Msg->dataB) = CANx->RDB;
01531             data = CANx->RDB;
01532             *((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF;
01533             *((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00)>>8;
01534             *((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000)>>16;
01535             *((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000)>>24;
01536 
01537         /*release receive buffer*/
01538         CANx->CMR = 0x04;
01539         }
01540         else
01541         {
01542             /* Received Frame is a Remote Frame, not have data, we just receive
01543              * message information only */
01544             return SUCCESS;
01545         }
01546     }
01547     else
01548     {
01549         // no receive message available
01550         return ERROR;
01551     }
01552     return SUCCESS;
01553 }
01554 
01555 /********************************************************************//**
01556  * @brief        Receive FullCAN Object
01557  * @param[in]    CANAFx: CAN Acceptance Filter register, should be LPC_CANAF
01558  * @param[in]    CAN_Msg point to the CAN_MSG_Type Struct, it will contain received
01559  *              message information such as: ID, DLC, RTR, ID Format
01560  * @return         CAN_ERROR, could be:
01561  *                 - CAN_FULL_OBJ_NOT_RCV: FullCAN Object is not be received
01562  *                 - CAN_OK: Received FullCAN Object successful
01563  *
01564  *********************************************************************/
01565 CAN_ERROR FCAN_ReadObj (LPC_CANAF_TypeDef* CANAFx, CAN_MSG_Type *CAN_Msg)
01566 {
01567     uint32_t *pSrc, data;
01568     uint32_t interrut_word, msg_idx, test_bit, head_idx, tail_idx;
01569 
01570     CHECK_PARAM(PARAM_CANAFx(CANAFx));
01571 
01572     interrut_word = 0;
01573 
01574     if (LPC_CANAF->FCANIC0 != 0)
01575     {
01576         interrut_word = LPC_CANAF->FCANIC0;
01577         head_idx = 0;
01578         tail_idx = 31;
01579     }
01580     else if (LPC_CANAF->FCANIC1 != 0)
01581     {
01582         interrut_word = LPC_CANAF->FCANIC1;
01583         head_idx = 32;
01584         tail_idx = 63;
01585     }
01586 
01587     if (interrut_word != 0)
01588     {
01589         /* Detect for interrupt pending */
01590         msg_idx = 0;
01591         for (msg_idx = head_idx; msg_idx <= tail_idx; msg_idx++)
01592         {
01593             test_bit = interrut_word & 0x1;
01594             interrut_word = interrut_word >> 1;
01595 
01596             if (test_bit)
01597             {
01598                 pSrc = (uint32_t *) (LPC_CANAF->ENDofTable + LPC_CANAF_RAM_BASE + msg_idx * 12);
01599 
01600                  /* Has been finished updating the content */
01601                  if ((*pSrc & 0x03000000L) == 0x03000000L)
01602                  {
01603                      /*clear semaphore*/
01604                      *pSrc &= 0xFCFFFFFF;
01605 
01606                      /*Set to DatA*/
01607                      pSrc++;
01608                      /* Copy to dest buf */
01609 //                     *((uint32_t *) &CAN_Msg->dataA) = *pSrc;
01610                      data = *pSrc;
01611                     *((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF;
01612                     *((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00)>>8;
01613                     *((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000)>>16;
01614                     *((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000)>>24;
01615 
01616                      /*Set to DatB*/
01617                      pSrc++;
01618                      /* Copy to dest buf */
01619 //                     *((uint32_t *) &CAN_Msg->dataB) = *pSrc;
01620                      data = *pSrc;
01621                     *((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF;
01622                     *((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00)>>8;
01623                     *((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000)>>16;
01624                     *((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000)>>24;
01625                      /*Back to Dat1*/
01626                      pSrc -= 2;
01627 
01628                      CAN_Msg->id = *pSrc & 0x7FF;
01629                      CAN_Msg->len = (uint8_t) (*pSrc >> 16) & 0x0F;
01630                     CAN_Msg->format = 0; //FullCAN Object ID always is 11-bit value
01631                     CAN_Msg->type = (uint8_t)(*pSrc >> 30) &0x01;
01632                      /*Re-read semaphore*/
01633                      if ((*pSrc & 0x03000000L) == 0)
01634                      {
01635                          return CAN_OK;
01636                      }
01637                  }
01638             }
01639         }
01640     }
01641     return CAN_FULL_OBJ_NOT_RCV;
01642 }
01643 /********************************************************************//**
01644  * @brief        Get CAN Control Status
01645  * @param[in]    CANx pointer to LPC_CAN_TypeDef, should be:
01646  *                 - CAN1: CAN 1
01647  *                 - CAN2: CAN 2
01648  * @param[in]    arg: type of CAN status to get from CAN status register
01649  *                 Should be:
01650  *                 - CANCTRL_GLOBAL_STS: CAN Global Status
01651  *                 - CANCTRL_INT_CAP: CAN Interrupt and Capture
01652  *                 - CANCTRL_ERR_WRN: CAN Error Warning Limit
01653  *                 - CANCTRL_STS: CAN Control Status
01654  * @return         Current Control Status that you want to get value
01655  *********************************************************************/
01656 uint32_t CAN_GetCTRLStatus (LPC_CAN_TypeDef* CANx, CAN_CTRL_STS_Type arg)
01657 {
01658     CHECK_PARAM(PARAM_CANx(CANx));
01659     CHECK_PARAM(PARAM_CTRL_STS_TYPE(arg));
01660 
01661     switch (arg)
01662     {
01663     case CANCTRL_GLOBAL_STS:
01664         return CANx->GSR;
01665 
01666     case CANCTRL_INT_CAP:
01667         return CANx->ICR;
01668 
01669     case CANCTRL_ERR_WRN:
01670         return CANx->EWL;
01671 
01672     default: // CANCTRL_STS
01673         return CANx->SR;
01674     }
01675 }
01676 /********************************************************************//**
01677  * @brief        Get CAN Central Status
01678  * @param[in]    CANCRx point to LPC_CANCR_TypeDef
01679  * @param[in]    arg: type of CAN status to get from CAN Central status register
01680  *                 Should be:
01681  *                 - CANCR_TX_STS: Central CAN Tx Status
01682  *                 - CANCR_RX_STS: Central CAN Rx Status
01683  *                 - CANCR_MS: Central CAN Miscellaneous Status
01684  * @return         Current Central Status that you want to get value
01685  *********************************************************************/
01686 uint32_t CAN_GetCRStatus (LPC_CANCR_TypeDef* CANCRx, CAN_CR_STS_Type arg)
01687 {
01688     CHECK_PARAM(PARAM_CANCRx(CANCRx));
01689     CHECK_PARAM(PARAM_CR_STS_TYPE(arg));
01690 
01691     switch (arg)
01692     {
01693     case CANCR_TX_STS:
01694         return CANCRx->CANTxSR;
01695 
01696     case CANCR_RX_STS:
01697         return CANCRx->CANRxSR;
01698 
01699     default:    // CANCR_MS
01700         return CANCRx->CANMSR;
01701     }
01702 }
01703 /********************************************************************//**
01704  * @brief        Enable/Disable CAN Interrupt
01705  * @param[in]    CANx pointer to LPC_CAN_TypeDef, should be:
01706  *                 - CAN1: CAN 1
01707  *                 - CAN2: CAN 2
01708  * @param[in]    arg: type of CAN interrupt that you want to enable/disable
01709  *                 Should be:
01710  *                 - CANINT_RIE: CAN Receiver Interrupt Enable
01711  *                 - CANINT_TIE1: CAN Transmit Interrupt Enable
01712  *                 - CANINT_EIE: CAN Error Warning Interrupt Enable
01713  *                 - CANINT_DOIE: CAN Data Overrun Interrupt Enable
01714  *                 - CANINT_WUIE: CAN Wake-Up Interrupt Enable
01715  *                 - CANINT_EPIE: CAN Error Passive Interrupt Enable
01716  *                 - CANINT_ALIE: CAN Arbitration Lost Interrupt Enable
01717  *                 - CANINT_BEIE: CAN Bus Error Interrupt Enable
01718  *                 - CANINT_IDIE: CAN ID Ready Interrupt Enable
01719  *                 - CANINT_TIE2: CAN Transmit Interrupt Enable for Buffer2
01720  *                 - CANINT_TIE3: CAN Transmit Interrupt Enable for Buffer3
01721  *                 - CANINT_FCE: FullCAN Interrupt Enable
01722  * @param[in]    NewState: New state of this function, should be:
01723  *                 - ENABLE
01724  *                 - DISABLE
01725  * @return         none
01726  *********************************************************************/
01727 void CAN_IRQCmd (LPC_CAN_TypeDef* CANx, CAN_INT_EN_Type arg, FunctionalState NewState)
01728 {
01729     CHECK_PARAM(PARAM_CANx(CANx));
01730     CHECK_PARAM(PARAM_INT_EN_TYPE(arg));
01731     CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
01732 
01733     if(NewState == ENABLE)
01734     {
01735         if(arg==CANINT_FCE)
01736         {
01737             LPC_CANAF->AFMR = 0x01;
01738             LPC_CANAF->FCANIE = 0x01;
01739             LPC_CANAF->AFMR = 0x04;
01740         }
01741         else
01742             CANx->IER |= (1 << arg);
01743     }
01744     else
01745     {
01746         if(arg==CANINT_FCE){
01747             LPC_CANAF->AFMR = 0x01;
01748             LPC_CANAF->FCANIE = 0x01;
01749             LPC_CANAF->AFMR = 0x00;
01750         }
01751         else
01752             CANx->IER &= ~(1 << arg);
01753     }
01754 }
01755 /*********************************************************************//**
01756  * @brief        Install interrupt call-back function
01757  * @param[in]    arg: CAN interrupt type, should be:
01758  *                   - CANINT_RIE: CAN Receiver Interrupt Enable
01759  *                 - CANINT_TIE1: CAN Transmit Interrupt Enable
01760  *                 - CANINT_EIE: CAN Error Warning Interrupt Enable
01761  *                 - CANINT_DOIE: CAN Data Overrun Interrupt Enable
01762  *                 - CANINT_WUIE: CAN Wake-Up Interrupt Enable
01763  *                 - CANINT_EPIE: CAN Error Passive Interrupt Enable
01764  *                 - CANINT_ALIE: CAN Arbitration Lost Interrupt Enable
01765  *                 - CANINT_BEIE: CAN Bus Error Interrupt Enable
01766  *                 - CANINT_IDIE: CAN ID Ready Interrupt Enable
01767  *                 - CANINT_TIE2: CAN Transmit Interrupt Enable for Buffer2
01768  *                 - CANINT_TIE3: CAN Transmit Interrupt Enable for Buffer3
01769  *                 - CANINT_FCE: FullCAN Interrupt Enable
01770  * @param[in]    pnCANCbs: pointer point to call-back function
01771  * @return        None
01772  **********************************************************************/
01773 void CAN_SetupCBS(CAN_INT_EN_Type arg,fnCANCbs_Type* pnCANCbs)
01774 {
01775     CHECK_PARAM(PARAM_INT_EN_TYPE(arg));
01776     _apfnCANCbs[arg] = pnCANCbs;
01777 }
01778 /********************************************************************//**
01779  * @brief        Setting Acceptance Filter mode
01780  * @param[in]    CANAFx point to LPC_CANAF_TypeDef object, should be: CANAF
01781  * @param[in]    AFMode: type of AF mode that you want to set, should be:
01782  *                 - CAN_Normal: Normal mode
01783  *                 - CAN_AccOff: Acceptance Filter Off Mode
01784  *                 - CAN_AccBP: Acceptance Fileter Bypass Mode
01785  *                 - CAN_eFCAN: FullCAN Mode Enhancement
01786  * @return         none
01787  *********************************************************************/
01788 void CAN_SetAFMode (LPC_CANAF_TypeDef* CANAFx, CAN_AFMODE_Type AFMode)
01789 {
01790     CHECK_PARAM(PARAM_CANAFx(CANAFx));
01791     CHECK_PARAM(PARAM_AFMODE_TYPE(AFMode));
01792 
01793     switch(AFMode)
01794     {
01795     case CAN_Normal:
01796         CANAFx->AFMR = 0x00;
01797         break;
01798     case CAN_AccOff:
01799         CANAFx->AFMR = 0x01;
01800         break;
01801     case CAN_AccBP:
01802         CANAFx->AFMR = 0x02;
01803         break;
01804     case CAN_eFCAN:
01805         CANAFx->AFMR = 0x04;
01806         break;
01807     }
01808 }
01809 
01810 /********************************************************************//**
01811  * @brief        Enable/Disable CAN Mode
01812  * @param[in]    CANx pointer to LPC_CAN_TypeDef, should be:
01813  *                 - CAN1: CAN 1
01814  *                 - CAN2: CAN 2
01815  * @param[in]    mode: type of CAN mode that you want to enable/disable, should be:
01816  *                 - CAN_OPERATING_MODE: Normal Operating Mode
01817  *                 - CAN_RESET_MODE: Reset Mode
01818  *                 - CAN_LISTENONLY_MODE: Listen Only Mode
01819  *                 - CAN_SELFTEST_MODE: Self Test Mode
01820  *                 - CAN_TXPRIORITY_MODE: Transmit Priority Mode
01821  *                 - CAN_SLEEP_MODE: Sleep Mode
01822  *                 - CAN_RXPOLARITY_MODE: Receive Polarity Mode
01823  *                 - CAN_TEST_MODE: Test Mode
01824  * @param[in]    NewState: New State of this function, should be:
01825  *                 - ENABLE
01826  *                 - DISABLE
01827  * @return         none
01828  *********************************************************************/
01829 void CAN_ModeConfig(LPC_CAN_TypeDef* CANx, CAN_MODE_Type mode, FunctionalState NewState)
01830 {
01831     CHECK_PARAM(PARAM_CANx(CANx));
01832     CHECK_PARAM(PARAM_MODE_TYPE(mode));
01833     CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
01834 
01835     switch(mode)
01836     {
01837     case CAN_OPERATING_MODE:
01838         CANx->MOD = 0x00;
01839         break;
01840     case CAN_RESET_MODE:
01841         if(NewState == ENABLE)
01842             CANx->MOD |=CAN_MOD_RM;
01843         else
01844             CANx->MOD &= ~CAN_MOD_RM;
01845         break;
01846     case CAN_LISTENONLY_MODE:
01847         CANx->MOD |=CAN_MOD_RM;
01848         if(NewState == ENABLE)
01849             CANx->MOD |=CAN_MOD_LOM;
01850         else
01851             CANx->MOD &=~CAN_MOD_LOM;
01852         break;
01853     case CAN_SELFTEST_MODE:
01854         CANx->MOD |=CAN_MOD_RM;
01855         if(NewState == ENABLE)
01856             CANx->MOD |=CAN_MOD_STM;
01857         else
01858             CANx->MOD &=~CAN_MOD_STM;
01859         break;
01860     case CAN_TXPRIORITY_MODE:
01861         if(NewState == ENABLE)
01862             CANx->MOD |=CAN_MOD_TPM;
01863         else
01864             CANx->MOD &=~CAN_MOD_TPM;
01865         break;
01866     case CAN_SLEEP_MODE:
01867         if(NewState == ENABLE)
01868             CANx->MOD |=CAN_MOD_SM;
01869         else
01870             CANx->MOD &=~CAN_MOD_SM;
01871         break;
01872     case CAN_RXPOLARITY_MODE:
01873         if(NewState == ENABLE)
01874             CANx->MOD |=CAN_MOD_RPM;
01875         else
01876             CANx->MOD &=~CAN_MOD_RPM;
01877         break;
01878     case CAN_TEST_MODE:
01879         if(NewState == ENABLE)
01880             CANx->MOD |=CAN_MOD_TM;
01881         else
01882             CANx->MOD &=~CAN_MOD_TM;
01883         break;
01884     }
01885 }
01886 /*********************************************************************//**
01887  * @brief        Standard CAN interrupt handler, this function will check
01888  *                 all interrupt status of CAN channels, then execute the call
01889  *                 back function if they're already installed
01890  * @param[in]    CANx point to CAN peripheral selected, should be: CAN1 or CAN2
01891  * @return        None
01892  **********************************************************************/
01893 void CAN_IntHandler(LPC_CAN_TypeDef* CANx)
01894 {
01895     uint8_t t;
01896     //scan interrupt pending
01897     if(LPC_CANAF->FCANIE)
01898     {
01899         _apfnCANCbs[11]();
01900     }
01901     //scan interrupt channels
01902     for(t=0;t<11;t++)
01903     {
01904         if(((CANx->ICR)>>t)&0x01)
01905         {
01906             _apfnCANCbs[t]();
01907         }
01908     }
01909 }
01910 
01911 /**
01912  * @}
01913  */
01914 
01915 #endif /* _CAN */
01916 
01917 /**
01918  * @}
01919  */
01920 
01921 /* --------------------------------- End Of File ------------------------------ */