lpc-field

Template project for programming NXP's LPC1768 MCUs
git clone git://git.mdnr.space/lpc-field
Log | Files | Refs | README | LICENSE

lpc17xx_can.c (55791B)


      1 /**********************************************************************
      2 * $Id$		lpc17xx_can.c				2011-03-09
      3 *//**
      4 * @file		lpc17xx_can.c
      5 * @brief	Contains all functions support for CAN firmware library on LPC17xx
      6 * @version	3.3
      7 * @date		09. March. 2011
      8 * @author	NXP MCU SW Application Team
      9 *
     10 * Copyright(C) 2011, NXP Semiconductor
     11 * All rights reserved.
     12 *
     13 ***********************************************************************
     14 * Software that is described herein is for illustrative purposes only
     15 * which provides customers with programming information regarding the
     16 * products. This software is supplied "AS IS" without any warranties.
     17 * NXP Semiconductors assumes no responsibility or liability for the
     18 * use of the software, conveys no license or title under any patent,
     19 * copyright, or mask work right to the product. NXP Semiconductors
     20 * reserves the right to make changes in the software without
     21 * notification. NXP Semiconductors also make no representation or
     22 * warranty that such application will be suitable for the specified
     23 * use without further testing or modification.
     24 * Permission to use, copy, modify, and distribute this software and its
     25 * documentation is hereby granted, under NXP Semiconductors'
     26 * relevant copyright in the software, without fee, provided that it
     27 * is used in conjunction with NXP Semiconductors microcontrollers.  This
     28 * copyright, permission, and disclaimer notice must appear in all copies of
     29 * this code.
     30 **********************************************************************/
     31 
     32 /* Peripheral group ----------------------------------------------------------- */
     33 /** @addtogroup CAN
     34  * @{
     35  */
     36 
     37 /* Includes ------------------------------------------------------------------- */
     38 #include "lpc17xx_can.h"
     39 #include "lpc17xx_clkpwr.h"
     40 
     41 /* If this source file built with example, the LPC17xx FW library configuration
     42  * file in each example directory ("lpc17xx_libcfg.h") must be included,
     43  * otherwise the default FW library configuration file must be included instead
     44  */
     45 #ifdef __BUILD_WITH_EXAMPLE__
     46 #include "lpc17xx_libcfg.h"
     47 #else
     48 #include "lpc17xx_libcfg_default.h"
     49 #endif /* __BUILD_WITH_EXAMPLE__ */
     50 
     51 
     52 #ifdef _CAN
     53 
     54 /* Private Variables ---------------------------------------------------------- */
     55 /** @defgroup CAN_Private_Variables CAN Private Variables
     56  * @{
     57  */
     58 
     59 FunctionalState FULLCAN_ENABLE;
     60 
     61 
     62 /* Counts number of filters (CAN message objects) used */
     63 uint16_t CANAF_FullCAN_cnt = 0;
     64 uint16_t CANAF_std_cnt = 0;
     65 uint16_t CANAF_gstd_cnt = 0;
     66 uint16_t CANAF_ext_cnt = 0;
     67 uint16_t CANAF_gext_cnt = 0;
     68 
     69 /* End of Private Variables ----------------------------------------------------*/
     70 /**
     71  * @}
     72  */
     73 
     74 /* Private Variables ---------------------------------------------------------- */
     75 static void can_SetBaudrate (LPC_CAN_TypeDef *CANx, uint32_t baudrate);
     76 
     77 /*********************************************************************//**
     78  * @brief 		Setting CAN baud rate (bps)
     79  * @param[in] 	CANx point to LPC_CAN_TypeDef object, should be:
     80  * 				- LPC_CAN1: CAN1 peripheral
     81  * 				- LPC_CAN2: CAN2 peripheral
     82  * @param[in]	baudrate: is the baud rate value will be set
     83  * @return 		None
     84  ***********************************************************************/
     85 static void can_SetBaudrate (LPC_CAN_TypeDef *CANx, uint32_t baudrate)
     86 {
     87 	uint32_t result = 0;
     88 	uint8_t NT, TSEG1, TSEG2, BRFail;
     89 	uint32_t CANPclk = 0;
     90 	uint32_t BRP;
     91 	CHECK_PARAM(PARAM_CANx(CANx));
     92 
     93 	if (CANx == LPC_CAN1)
     94 	{
     95 		CANPclk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_CAN1);
     96 	}
     97 	else
     98 	{
     99 		CANPclk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_CAN2);
    100 	}
    101 	result = CANPclk / baudrate;
    102 	/* Calculate suitable nominal time value
    103 	 * NT (nominal time) = (TSEG1 + TSEG2 + 3)
    104 	 * NT <= 24
    105 	 * TSEG1 >= 2*TSEG2
    106 	 */
    107 	BRFail = 1;
    108 	for(NT=24;NT>0;NT=NT-2)
    109 	{
    110 		if ((result%NT)==0)
    111 		{
    112 			BRP = result / NT - 1;
    113 			NT--;
    114 			TSEG2 = (NT/3) - 1;
    115 			TSEG1 = NT -(NT/3) - 1;
    116 			BRFail = 0;
    117 			break;
    118 		}
    119 	}
    120 	if(BRFail)
    121 		while(1); // Failed to calculate exact CAN baud rate
    122 	/* Enter reset mode */
    123 	CANx->MOD = 0x01;
    124 	/* Set bit timing
    125 	 * Default: SAM = 0x00;
    126 	 *          SJW = 0x03;
    127 	 */
    128 	CANx->BTR  = (TSEG2<<20)|(TSEG1<<16)|(3<<14)|BRP;
    129 	/* Return to normal operating */
    130 	CANx->MOD = 0;
    131 }
    132 /* End of Private Functions ----------------------------------------------------*/
    133 
    134 
    135 /* Public Functions ----------------------------------------------------------- */
    136 /** @addtogroup CAN_Public_Functions
    137  * @{
    138  */
    139 
    140 /********************************************************************//**
    141  * @brief		Initialize CAN peripheral with given baudrate
    142  * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
    143  * 				- LPC_CAN1: CAN1 peripheral
    144  * 				- LPC_CAN2: CAN2 peripheral
    145  * @param[in]	baudrate: the value of CAN baudrate will be set (bps)
    146  * @return 		None
    147  *********************************************************************/
    148 void CAN_Init(LPC_CAN_TypeDef *CANx, uint32_t baudrate)
    149 {
    150 	uint16_t i;
    151 	CHECK_PARAM(PARAM_CANx(CANx));
    152 
    153 	if(CANx == LPC_CAN1)
    154 	{
    155 		/* Turn on power and clock for CAN1 */
    156 		CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN1, ENABLE);
    157 		/* Set clock divide for CAN1 */
    158 	}
    159 	else
    160 	{
    161 		/* Turn on power and clock for CAN1 */
    162 		CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN2, ENABLE);
    163 		/* Set clock divide for CAN2 */
    164 	}
    165 	CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_CAN1, CLKPWR_PCLKSEL_CCLK_DIV_2);
    166 	CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_CAN2, CLKPWR_PCLKSEL_CCLK_DIV_2);
    167 	CLKPWR_SetPCLKDiv (CLKPWR_PCLKSEL_ACF, CLKPWR_PCLKSEL_CCLK_DIV_2);
    168 
    169 	CANx->MOD = 1; // Enter Reset Mode
    170 	CANx->IER = 0; // Disable All CAN Interrupts
    171 	CANx->GSR = 0;
    172 	/* Request command to release Rx, Tx buffer and clear data overrun */
    173 	//CANx->CMR = CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO;
    174 	CANx->CMR = (1<<1)|(1<<2)|(1<<3);
    175 	/* Read to clear interrupt pending in interrupt capture register */
    176 	i = CANx->ICR;
    177 	CANx->MOD = 0;// Return Normal operating
    178 
    179 	//Reset CANAF value
    180 	LPC_CANAF->AFMR = 0x01;
    181 
    182 	//clear ALUT RAM
    183 	for (i = 0; i < 512; i++) {
    184 		LPC_CANAF_RAM->mask[i] = 0x00;
    185 	}
    186 
    187 	LPC_CANAF->SFF_sa = 0x00;
    188 	LPC_CANAF->SFF_GRP_sa = 0x00;
    189 	LPC_CANAF->EFF_sa = 0x00;
    190 	LPC_CANAF->EFF_GRP_sa = 0x00;
    191 	LPC_CANAF->ENDofTable = 0x00;
    192 
    193 	LPC_CANAF->AFMR = 0x00;
    194 	/* Set baudrate */
    195 	can_SetBaudrate (CANx, baudrate);
    196 }
    197 
    198 /********************************************************************//**
    199  * @brief		CAN deInit
    200  * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
    201  * 				- LPC_CAN1: CAN1 peripheral
    202  * 				- LPC_CAN2: CAN2 peripheral
    203  * @return 		None
    204  *********************************************************************/
    205 void CAN_DeInit(LPC_CAN_TypeDef *CANx)
    206 {
    207 	CHECK_PARAM(PARAM_CANx(CANx));
    208 
    209 	if(CANx == LPC_CAN1)
    210 	{
    211 		/* Turn on power and clock for CAN1 */
    212 		CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN1, DISABLE);
    213 	}
    214 	else
    215 	{
    216 		/* Turn on power and clock for CAN1 */
    217 		CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN2, DISABLE);
    218 	}
    219 }
    220 
    221 /********************************************************************//**
    222  * @brief		Setup Acceptance Filter Look-Up Table
    223  * @param[in]	CANAFx	pointer to LPC_CANAF_TypeDef
    224  * 				Should be: LPC_CANAF
    225  * @param[in]	AFSection	the pointer to AF_SectionDef structure
    226  * 				It contain information about 5 sections will be install in AFLUT
    227  * @return 		CAN Error	could be:
    228  * 				- CAN_OBJECTS_FULL_ERROR: No more rx or tx objects available
    229  * 				- CAN_AF_ENTRY_ERROR: table error-violation of ascending numerical order
    230  * 				- CAN_OK: ID is added into table successfully
    231  *********************************************************************/
    232 CAN_ERROR CAN_SetupAFLUT(LPC_CANAF_TypeDef* CANAFx, AF_SectionDef* AFSection)
    233 {
    234 	uint8_t ctrl1,ctrl2;
    235 	uint8_t dis1, dis2;
    236 	uint16_t SID, ID_temp,i, count = 0;
    237 	uint32_t EID, entry, buf;
    238 	uint16_t lowerSID, upperSID;
    239 	uint32_t lowerEID, upperEID;
    240 
    241 	CHECK_PARAM(PARAM_CANAFx(CANAFx));
    242 	CANAFx->AFMR = 0x01;
    243 
    244 /***** setup FullCAN Table *****/
    245 	if(AFSection->FullCAN_Sec == NULL)
    246 	{
    247 		FULLCAN_ENABLE = DISABLE;
    248 	}
    249 	else
    250 	{
    251 		FULLCAN_ENABLE = ENABLE;
    252 		for(i=0;i<(AFSection->FC_NumEntry);i++)
    253 		{
    254 			if(count + 1 > 64)
    255 			{
    256 				return CAN_OBJECTS_FULL_ERROR;
    257 			}
    258 			ctrl1 = AFSection->FullCAN_Sec->controller;
    259 			SID = AFSection->FullCAN_Sec->id_11;
    260 			dis1 = AFSection->FullCAN_Sec->disable;
    261 
    262 			CHECK_PARAM(PARAM_CTRL(ctrl1));
    263 			CHECK_PARAM(PARAM_ID_11(SID));
    264 			CHECK_PARAM(PARAM_MSG_DISABLE(dis1));
    265 			entry = 0x00; //reset entry value
    266 			if((CANAF_FullCAN_cnt & 0x00000001)==0)
    267 			{
    268 				if(count!=0x00)
    269 				{
    270 					buf = LPC_CANAF_RAM->mask[count-1];
    271 					ID_temp = (buf & 0xE7FF); //mask controller & identifier bits
    272 					if(ID_temp > ((ctrl1<<13)|SID))
    273 					{
    274 						return CAN_AF_ENTRY_ERROR;
    275 					}
    276 				}
    277 				entry = (ctrl1<<29)|(dis1<<28)|(SID<<16)|(1<<27);
    278 				LPC_CANAF_RAM->mask[count] &= 0x0000FFFF;
    279 				LPC_CANAF_RAM->mask[count] |= entry;
    280 				CANAF_FullCAN_cnt++;
    281 				if(CANAF_FullCAN_cnt == AFSection->FC_NumEntry) //this is the lastest FullCAN entry
    282 					count++;
    283 			}
    284 			else
    285 			{
    286 				buf = LPC_CANAF_RAM->mask[count];
    287 				ID_temp = (buf >>16) & 0xE7FF;
    288 				if(ID_temp > ((ctrl1<<13)|SID))
    289 				{
    290 					return CAN_AF_ENTRY_ERROR;
    291 				}
    292 				entry = (ctrl1<<13)|(dis1<<12)|(SID<<0)|(1<<11);
    293 				LPC_CANAF_RAM->mask[count] &= 0xFFFF0000;
    294 				LPC_CANAF_RAM->mask[count]|= entry;
    295 				count++;
    296 				CANAF_FullCAN_cnt++;
    297 			}
    298 			AFSection->FullCAN_Sec = (FullCAN_Entry *)((uint32_t)(AFSection->FullCAN_Sec)+ sizeof(FullCAN_Entry));
    299 		}
    300 	}
    301 
    302 /***** Setup Explicit Standard Frame Format Section *****/
    303 	if(AFSection->SFF_Sec != NULL)
    304 	{
    305 		for(i=0;i<(AFSection->SFF_NumEntry);i++)
    306 		{
    307 			if(count + 1 > 512)
    308 			{
    309 				return CAN_OBJECTS_FULL_ERROR;
    310 			}
    311 			ctrl1 = AFSection->SFF_Sec->controller;
    312 			SID = AFSection->SFF_Sec->id_11;
    313 			dis1 = AFSection->SFF_Sec->disable;
    314 
    315 			//check parameter
    316 			CHECK_PARAM(PARAM_CTRL(ctrl1));
    317 			CHECK_PARAM(PARAM_ID_11(SID));
    318 			CHECK_PARAM(PARAM_MSG_DISABLE(dis1));
    319 
    320 			entry = 0x00; //reset entry value
    321 			if((CANAF_std_cnt & 0x00000001)==0)
    322 			{
    323 				if(CANAF_std_cnt !=0 )
    324 				{
    325 					buf = LPC_CANAF_RAM->mask[count-1];
    326 					ID_temp = (buf & 0xE7FF); //mask controller & identifier bits
    327 					if(ID_temp > ((ctrl1<<13)|SID))
    328 					{
    329 						return CAN_AF_ENTRY_ERROR;
    330 					}
    331 				}
    332 				entry = (ctrl1<<29)|(dis1<<28)|(SID<<16);
    333 				LPC_CANAF_RAM->mask[count] &= 0x0000FFFF;
    334 				LPC_CANAF_RAM->mask[count] |= entry;
    335 				CANAF_std_cnt++;
    336 				if(CANAF_std_cnt == AFSection->SFF_NumEntry)//if this is the last SFF entry
    337 					count++;
    338 			}
    339 			else
    340 			{
    341 				buf = LPC_CANAF_RAM->mask[count];
    342 				ID_temp = (buf >>16) & 0xE7FF;
    343 				if(ID_temp > ((ctrl1<<13)|SID))
    344 				{
    345 					return CAN_AF_ENTRY_ERROR;
    346 				}
    347 				entry = (ctrl1<<13)|(dis1<<12)|(SID<<0);
    348 				LPC_CANAF_RAM->mask[count] &= 0xFFFF0000;
    349 				LPC_CANAF_RAM->mask[count] |= entry;
    350 				count++;
    351 				CANAF_std_cnt++;
    352 			}
    353 			AFSection->SFF_Sec = (SFF_Entry *)((uint32_t)(AFSection->SFF_Sec)+ sizeof(SFF_Entry));
    354 		}
    355 	}
    356 
    357 /***** Setup Group of Standard Frame Format Identifier Section *****/
    358 	if(AFSection->SFF_GPR_Sec != NULL)
    359 	{
    360 		for(i=0;i<(AFSection->SFF_GPR_NumEntry);i++)
    361 		{
    362 			if(count + 1 > 512)
    363 			{
    364 				return CAN_OBJECTS_FULL_ERROR;
    365 			}
    366 			ctrl1 = AFSection->SFF_GPR_Sec->controller1;
    367 			ctrl2 = AFSection->SFF_GPR_Sec->controller2;
    368 			dis1 = AFSection->SFF_GPR_Sec->disable1;
    369 			dis2 = AFSection->SFF_GPR_Sec->disable2;
    370 			lowerSID = AFSection->SFF_GPR_Sec->lowerID;
    371 			upperSID = AFSection->SFF_GPR_Sec->upperID;
    372 
    373 			/* check parameter */
    374 			CHECK_PARAM(PARAM_CTRL(ctrl1));
    375 			CHECK_PARAM(PARAM_CTRL(ctrl2));
    376 			CHECK_PARAM(PARAM_MSG_DISABLE(dis1));
    377 			CHECK_PARAM(PARAM_MSG_DISABLE(dis2));
    378 			CHECK_PARAM(PARAM_ID_11(lowerSID));
    379 			CHECK_PARAM(PARAM_ID_11(upperSID));
    380 
    381 			entry = 0x00;
    382 			if(CANAF_gstd_cnt!=0)
    383 			{
    384 				buf = LPC_CANAF_RAM->mask[count-1];
    385 				ID_temp = buf & 0xE7FF;
    386 				if((ctrl1 != ctrl2)||(lowerSID > upperSID)||(ID_temp > ((ctrl1<<13)|lowerSID)))
    387 				{
    388 					return CAN_AF_ENTRY_ERROR;
    389 				}
    390 			}
    391 			entry = (ctrl1 << 29)|(dis1 << 28)|(lowerSID << 16)|  \
    392 					(ctrl2 << 13)|(dis2 << 12)|(upperSID << 0);
    393 			LPC_CANAF_RAM->mask[count] = entry;
    394 			CANAF_gstd_cnt++;
    395 			count++;
    396 			AFSection->SFF_GPR_Sec = (SFF_GPR_Entry *)((uint32_t)(AFSection->SFF_GPR_Sec)+ sizeof(SFF_GPR_Entry));
    397 		}
    398 	}
    399 
    400 /***** Setup Explicit Extend Frame Format Identifier Section *****/
    401 	if(AFSection->EFF_Sec != NULL)
    402 	{
    403 		for(i=0;i<(AFSection->EFF_NumEntry);i++)
    404 		{
    405 			if(count + 1 > 512)
    406 			{
    407 				return CAN_OBJECTS_FULL_ERROR;
    408 			}
    409 			EID = AFSection->EFF_Sec->ID_29;
    410 			ctrl1 = AFSection->EFF_Sec->controller;
    411 
    412 			// check parameter
    413 			CHECK_PARAM(PARAM_ID_29(EID));
    414 			CHECK_PARAM(PARAM_CTRL(ctrl1));
    415 
    416 			entry = (ctrl1 << 29)|(EID << 0);
    417 			if(CANAF_ext_cnt != 0)
    418 			{
    419 				buf = LPC_CANAF_RAM->mask[count-1];
    420 //				EID_temp = buf & 0x0FFFFFFF;
    421 				if(buf > entry)
    422 				{
    423 					return CAN_AF_ENTRY_ERROR;
    424 				}
    425 			}
    426 			LPC_CANAF_RAM->mask[count] = entry;
    427 			CANAF_ext_cnt ++;
    428 			count++;
    429 			AFSection->EFF_Sec = (EFF_Entry *)((uint32_t)(AFSection->EFF_Sec)+ sizeof(EFF_Entry));
    430 		}
    431 	}
    432 
    433 /***** Setup Group of Extended Frame Format Identifier Section *****/
    434 	if(AFSection->EFF_GPR_Sec != NULL)
    435 	{
    436 		for(i=0;i<(AFSection->EFF_GPR_NumEntry);i++)
    437 		{
    438 			if(count + 2 > 512)
    439 			{
    440 				return CAN_OBJECTS_FULL_ERROR;
    441 			}
    442 			ctrl1 = AFSection->EFF_GPR_Sec->controller1;
    443 			ctrl2 = AFSection->EFF_GPR_Sec->controller2;
    444 			lowerEID = AFSection->EFF_GPR_Sec->lowerEID;
    445 			upperEID = AFSection->EFF_GPR_Sec->upperEID;
    446 
    447 			//check parameter
    448 			CHECK_PARAM(PARAM_CTRL(ctrl1));
    449 			CHECK_PARAM(PARAM_CTRL(ctrl2));
    450 			CHECK_PARAM(PARAM_ID_29(lowerEID));
    451 			CHECK_PARAM(PARAM_ID_29(upperEID));
    452 
    453 			entry = 0x00;
    454 			if(CANAF_gext_cnt != 0)
    455 			{
    456 				buf = LPC_CANAF_RAM->mask[count-1];
    457 //				EID_temp = buf & 0x0FFFFFFF;
    458 				if((ctrl1 != ctrl2) || (lowerEID > upperEID) || (buf > ((ctrl1 << 29)|(lowerEID << 0))))
    459 				{
    460 					return CAN_AF_ENTRY_ERROR;
    461 				}
    462 			}
    463 			entry = (ctrl1 << 29)|(lowerEID << 0);
    464 			LPC_CANAF_RAM->mask[count++] = entry;
    465 			entry = (ctrl2 << 29)|(upperEID << 0);
    466 			LPC_CANAF_RAM->mask[count++] = entry;
    467 			CANAF_gext_cnt++;
    468 			AFSection->EFF_GPR_Sec = (EFF_GPR_Entry *)((uint32_t)(AFSection->EFF_GPR_Sec)+ sizeof(EFF_GPR_Entry));
    469 		}
    470 	}
    471 	//update address values
    472 	LPC_CANAF->SFF_sa = ((CANAF_FullCAN_cnt + 1)>>1)<<2;
    473 	LPC_CANAF->SFF_GRP_sa = LPC_CANAF->SFF_sa + (((CANAF_std_cnt+1)>>1)<< 2);
    474 	LPC_CANAF->EFF_sa = LPC_CANAF->SFF_GRP_sa + (CANAF_gstd_cnt << 2);
    475 	LPC_CANAF->EFF_GRP_sa = LPC_CANAF->EFF_sa + (CANAF_ext_cnt << 2);
    476 	LPC_CANAF->ENDofTable = LPC_CANAF->EFF_GRP_sa + (CANAF_gext_cnt << 3);
    477 
    478 	if(FULLCAN_ENABLE == DISABLE)
    479 	{
    480 		LPC_CANAF->AFMR = 0x00; // Normal mode
    481 	}
    482 	else
    483 	{
    484 		LPC_CANAF->AFMR = 0x04;
    485 	}
    486 	return CAN_OK;
    487 }
    488 /********************************************************************//**
    489  * @brief		Add Explicit ID into AF Look-Up Table dynamically.
    490  * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
    491  * 				- LPC_CAN1: CAN1 peripheral
    492  * 				- LPC_CAN2: CAN2 peripheral
    493  * @param[in]	id: The ID of entry will be added
    494  * @param[in]	format: is the type of ID Frame Format, should be:
    495  * 				- STD_ID_FORMAT: 11-bit ID value
    496  * 				- EXT_ID_FORMAT: 29-bit ID value
    497  * @return 		CAN Error, could be:
    498  * 				- CAN_OBJECTS_FULL_ERROR: No more rx or tx objects available
    499  * 				- CAN_ID_EXIT_ERROR: ID exited in table
    500  * 				- CAN_OK: ID is added into table successfully
    501  *********************************************************************/
    502 CAN_ERROR CAN_LoadExplicitEntry(LPC_CAN_TypeDef* CANx, uint32_t id, CAN_ID_FORMAT_Type format)
    503 {
    504 	uint32_t tmp0 = 0;
    505 	uint32_t buf0=0, buf1=0;
    506 	int16_t cnt1=0, cnt2=0, bound1=0, total=0;
    507 
    508 
    509 	CHECK_PARAM(PARAM_CANx(CANx));
    510 	CHECK_PARAM(PARAM_ID_FORMAT(format));
    511 
    512 	if (CANx == LPC_CAN1)
    513 	{
    514 		tmp0 = 0;
    515 	}
    516 	else if (CANx == LPC_CAN2)
    517 	{
    518 		tmp0 = 1;
    519 	}
    520 
    521 	/* Acceptance Filter Memory full - return */
    522 	total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+  \
    523 			CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
    524 	if (total >= 512){ //don't have enough space
    525 		return CAN_OBJECTS_FULL_ERROR;
    526 	}
    527 
    528 	/* Setup Acceptance Filter Configuration
    529     Acceptance Filter Mode Register = Off */
    530 	LPC_CANAF->AFMR = 0x00000001;
    531 
    532 /*********** Add Explicit Standard Identifier Frame Format entry *********/
    533  	if(format == STD_ID_FORMAT)
    534  	{
    535  		id &= 0x07FF;
    536  		id |= (tmp0 << 13); /* Add controller number */
    537 		/* Move all remaining sections one place up
    538 		if new entry will increase FullCAN list */
    539 		if ((CANAF_std_cnt & 0x0001) == 0)
    540 		{
    541 			cnt1   = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1);
    542 			bound1 = total - cnt1;
    543 			buf0   = LPC_CANAF_RAM->mask[cnt1];
    544 			while(bound1--)
    545 			{
    546 				cnt1++;
    547 				buf1 = LPC_CANAF_RAM->mask[cnt1];
    548 				LPC_CANAF_RAM->mask[cnt1] = buf0;
    549 				buf0 = buf1;
    550 			}
    551 		}
    552 		if (CANAF_std_cnt == 0)
    553 		{
    554 			cnt2 = (CANAF_FullCAN_cnt + 1)>>1;
    555 			/* For entering first ID */
    556 			LPC_CANAF_RAM->mask[cnt2] = 0x0000FFFF | (id << 16);
    557 		}
    558 		else if (CANAF_std_cnt == 1)
    559 		{
    560 			cnt2 = (CANAF_FullCAN_cnt + 1)>>1;
    561 			/* For entering second ID */
    562 			if (((LPC_CANAF_RAM->mask[cnt2] >> 16)& 0xE7FF) > id)
    563 			{
    564 				LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] >> 16) | (id << 16);
    565 			}
    566 			else
    567 			{
    568 				LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] & 0xFFFF0000) | id;
    569 			}
    570 		}
    571 		else
    572 		{
    573 			/* Find where to insert new ID */
    574 			cnt1 = (CANAF_FullCAN_cnt+1)>>1;
    575 			cnt2 = CANAF_std_cnt;
    576 			bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1);
    577 			while (cnt1 < bound1)
    578 			{
    579 				/* Loop through standard existing IDs */
    580 				if (((LPC_CANAF_RAM->mask[cnt1] >> 16) & 0xE7FF) > id)
    581 				{
    582 					cnt2 = cnt1 * 2;
    583 					break;
    584 				}
    585 
    586 				if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000E7FF) > id)
    587 				{
    588 					cnt2 = cnt1 * 2 + 1;
    589 					break;
    590 				}
    591 
    592 				cnt1++;
    593 			}
    594 			/* cnt1 = U32 where to insert new ID */
    595 			/* cnt2 = U16 where to insert new ID */
    596 
    597 			if (cnt1 == bound1)
    598 			{
    599 				/* Adding ID as last entry */
    600 				/* Even number of IDs exists */
    601 				if ((CANAF_std_cnt & 0x0001) == 0)
    602 				{
    603 					LPC_CANAF_RAM->mask[cnt1]  = 0x0000FFFF | (id << 16);
    604 				}
    605 				/* Odd  number of IDs exists */
    606 				else
    607 				{
    608 					LPC_CANAF_RAM->mask[cnt1]  = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
    609 				}
    610 			}
    611 			else
    612 			{
    613 				buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */
    614 				if ((cnt2 & 0x0001) == 0)
    615 				{
    616 					/* Insert new mask to even address*/
    617 					buf1 = (id << 16) | (buf0 >> 16);
    618 				}
    619 				else
    620 				{
    621 					/* Insert new mask to odd  address */
    622 					buf1 = (buf0 & 0xFFFF0000) | id;
    623 				}
    624 				LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */
    625 				bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1)-1;
    626 				/* Move all remaining standard mask entries one place up */
    627 				while (cnt1 < bound1)
    628 				{
    629 					cnt1++;
    630 					buf1  = LPC_CANAF_RAM->mask[cnt1];
    631 					LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
    632 					buf0  = buf1;
    633 				}
    634 
    635 				if ((CANAF_std_cnt & 0x0001) == 0)
    636 				{
    637 					/* Even number of IDs exists */
    638 					LPC_CANAF_RAM->mask[cnt1+1] = (buf0 <<16) |(0x0000FFFF);
    639 				}
    640 			}
    641 		}
    642 		CANAF_std_cnt++;
    643 		//update address values
    644 		LPC_CANAF->SFF_GRP_sa +=0x04 ;
    645 		LPC_CANAF->EFF_sa     +=0x04 ;
    646 		LPC_CANAF->EFF_GRP_sa +=0x04;
    647 		LPC_CANAF->ENDofTable +=0x04;
    648  	}
    649 
    650 /*********** Add Explicit Extended Identifier Frame Format entry *********/
    651  	else
    652  	{
    653  		/* Add controller number */
    654  		id |= (tmp0) << 29;
    655 
    656  		cnt1 = ((CANAF_FullCAN_cnt+1)>>1)+(((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt);
    657  		cnt2 = 0;
    658  		while (cnt2 < CANAF_ext_cnt)
    659  		{
    660  			/* Loop through extended existing masks*/
    661  			if (LPC_CANAF_RAM->mask[cnt1] > id)
    662  			{
    663  				break;
    664  			}
    665  			cnt1++;/* cnt1 = U32 where to insert new mask */
    666 			cnt2++;
    667  		}
    668 
    669  		buf0 = LPC_CANAF_RAM->mask[cnt1];  /* Remember current entry */
    670  		LPC_CANAF_RAM->mask[cnt1] = id;    /* Insert mask */
    671 
    672  		CANAF_ext_cnt++;
    673 
    674  		bound1 = total;
    675  		/* Move all remaining extended mask entries one place up*/
    676  		while (cnt2 < bound1)
    677  		{
    678  			cnt1++;
    679  			cnt2++;
    680  			buf1 = LPC_CANAF_RAM->mask[cnt1];
    681  			LPC_CANAF_RAM->mask[cnt1] = buf0;
    682  			buf0 = buf1;
    683  		}
    684  		/* update address values */
    685  		LPC_CANAF->EFF_GRP_sa += 4;
    686  		LPC_CANAF->ENDofTable += 4;
    687  	}
    688  	if(CANAF_FullCAN_cnt == 0) //not use FullCAN mode
    689  	{
    690  		LPC_CANAF->AFMR = 0x00;//not use FullCAN mode
    691  	}
    692  	else
    693  	{
    694  		LPC_CANAF->AFMR = 0x04;
    695  	}
    696 
    697  	return CAN_OK;
    698 }
    699 
    700 /********************************************************************//**
    701  * @brief		Load FullCAN entry into AFLUT
    702  * @param[in]	CANx: CAN peripheral selected, should be:
    703  * 				- LPC_CAN1: CAN1 peripheral
    704  * 				- LPC_CAN2: CAN2 peripheral
    705  * @param[in]	id: identifier of entry that will be added
    706  * @return 		CAN_ERROR, could be:
    707  * 				- CAN_OK: loading is successful
    708  * 				- CAN_ID_EXIT_ERROR: ID exited in FullCAN Section
    709  * 				- CAN_OBJECTS_FULL_ERROR: no more space available
    710  *********************************************************************/
    711 CAN_ERROR CAN_LoadFullCANEntry (LPC_CAN_TypeDef* CANx, uint16_t id)
    712 {
    713 	uint32_t ctrl0 = 0;
    714 	uint32_t buf0=0, buf1=0, buf2=0;
    715 	uint32_t tmp0=0, tmp1=0, tmp2=0;
    716 	int16_t cnt1=0, cnt2=0, bound1=0, total=0;
    717 
    718 	CHECK_PARAM(PARAM_CANx(CANx));
    719 
    720 	if (CANx == LPC_CAN1)
    721 	{
    722 		ctrl0 = 0;
    723 	}
    724 	else if (CANx == LPC_CAN2)
    725 	{
    726 		ctrl0 = 1;
    727 	}
    728 
    729 	/* Acceptance Filter Memory full - return */
    730 	total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+  \
    731 			CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
    732 	//don't have enough space for this fullCAN Entry and its Object(3*32 bytes)
    733 	if ((total >=508)||(CANAF_FullCAN_cnt>=64)){
    734 		return CAN_OBJECTS_FULL_ERROR;
    735 	}
    736 	/* Setup Acceptance Filter Configuration
    737     Acceptance Filter Mode Register = Off */
    738 	LPC_CANAF->AFMR = 0x00000001;
    739 
    740 	/* Add mask for standard identifiers   */
    741 	id &= 0x07FF;
    742 	id |= (ctrl0 << 13) | (1 << 11); /* Add controller number */
    743 //	total = ((CANAF_std_cnt + 1) >> 1)+ CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
    744 	/* Move all remaining sections one place up
    745 	if new entry will increase FullCAN list */
    746 	if (((CANAF_FullCAN_cnt & 0x0001) == 0)&&(total!=0))
    747 	{
    748 		//then remove remaining section
    749 		cnt1   = (CANAF_FullCAN_cnt >> 1);
    750 		bound1 = total;
    751 		buf0   = LPC_CANAF_RAM->mask[cnt1];
    752 
    753 		while (bound1--)
    754 		{
    755 			cnt1++;
    756 			buf1 = LPC_CANAF_RAM->mask[cnt1];
    757 			LPC_CANAF_RAM->mask[cnt1] = buf0;
    758 			buf0 = buf1;
    759 		}
    760 	}
    761 	if (CANAF_FullCAN_cnt == 0)
    762 	{
    763 		/* For entering first ID */
    764 		LPC_CANAF_RAM->mask[0] = 0x0000FFFF | (id << 16);
    765 	}
    766 	else if (CANAF_FullCAN_cnt == 1)
    767 	{
    768 		/* For entering second ID */
    769 		if (((LPC_CANAF_RAM->mask[0] >> 16)& 0xE7FF) > id)
    770 		{
    771 			LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] >> 16) | (id << 16);
    772 		}
    773 		else
    774 		{
    775 			LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] & 0xFFFF0000) | id;
    776 		}
    777 	}
    778 	else
    779 	{
    780 		/* Find where to insert new ID */
    781 		cnt1 = 0;
    782 		cnt2 = CANAF_FullCAN_cnt;
    783 		bound1 = (CANAF_FullCAN_cnt - 1) >> 1;
    784 		while (cnt1 <= bound1)
    785 		{
    786 			/* Loop through standard existing IDs */
    787 			if (((LPC_CANAF_RAM->mask[cnt1] >> 16) & 0xE7FF) > (id & 0xE7FF))
    788 			{
    789 				cnt2 = cnt1 * 2;
    790 				break;
    791 			}
    792 
    793 			if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000E7FF) > (id & 0xE7FF))
    794 			{
    795 				cnt2 = cnt1 * 2 + 1;
    796 				break;
    797 			}
    798 
    799 			cnt1++;
    800 		}
    801 		/* cnt1 = U32 where to insert new ID */
    802 		/* cnt2 = U16 where to insert new ID */
    803 
    804 		if (cnt1 > bound1)
    805 		{
    806 			/* Adding ID as last entry */
    807 			/* Even number of IDs exists */
    808 			if ((CANAF_FullCAN_cnt & 0x0001) == 0)
    809 			{
    810 				LPC_CANAF_RAM->mask[cnt1]  = 0x0000FFFF | (id << 16);
    811 			}
    812 			/* Odd  number of IDs exists */
    813 			else
    814 			{
    815 				LPC_CANAF_RAM->mask[cnt1]  = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
    816 			}
    817 		}
    818 		else
    819 		{
    820 			buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */
    821 			if ((cnt2 & 0x0001) == 0)
    822 			{
    823 				/* Insert new mask to even address*/
    824 				buf1 = (id << 16) | (buf0 >> 16);
    825 			}
    826 			else
    827 			{
    828 				/* Insert new mask to odd  address */
    829 				buf1 = (buf0 & 0xFFFF0000) | id;
    830 			}
    831 			LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */
    832 			bound1 = CANAF_FullCAN_cnt >> 1;
    833 			/* Move all remaining standard mask entries one place up */
    834 			while (cnt1 < bound1)
    835 			{
    836 				cnt1++;
    837 				buf1  = LPC_CANAF_RAM->mask[cnt1];
    838 				LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
    839 				buf0  = buf1;
    840 			}
    841 
    842 			if ((CANAF_FullCAN_cnt & 0x0001) == 0)
    843 			{
    844 				/* Even number of IDs exists */
    845 				LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000)
    846 											| (0x0000FFFF);
    847 			}
    848 		}
    849 	}
    850 	//restruct FulCAN Object Section
    851 	bound1 = CANAF_FullCAN_cnt - cnt2;
    852 	cnt1 = total - (CANAF_FullCAN_cnt)*3 + cnt2*3 + 1;
    853 	buf0 = LPC_CANAF_RAM->mask[cnt1];
    854 	buf1 = LPC_CANAF_RAM->mask[cnt1+1];
    855 	buf2 = LPC_CANAF_RAM->mask[cnt1+2];
    856 	LPC_CANAF_RAM->mask[cnt1]=LPC_CANAF_RAM->mask[cnt1+1]= LPC_CANAF_RAM->mask[cnt1+2]=0x00;
    857 	cnt1+=3;
    858 	while(bound1--)
    859 	{
    860 		tmp0 = LPC_CANAF_RAM->mask[cnt1];
    861 		tmp1 = LPC_CANAF_RAM->mask[cnt1+1];
    862 		tmp2 = LPC_CANAF_RAM->mask[cnt1+2];
    863 		LPC_CANAF_RAM->mask[cnt1]= buf0;
    864 		LPC_CANAF_RAM->mask[cnt1+1]= buf1;
    865 		LPC_CANAF_RAM->mask[cnt1+2]= buf2;
    866 		buf0 = tmp0;
    867 		buf1 = tmp1;
    868 		buf2 = tmp2;
    869 		cnt1+=3;
    870 	}
    871 	CANAF_FullCAN_cnt++;
    872 	//update address values
    873 	LPC_CANAF->SFF_sa 	  +=0x04;
    874 	LPC_CANAF->SFF_GRP_sa +=0x04 ;
    875 	LPC_CANAF->EFF_sa     +=0x04 ;
    876 	LPC_CANAF->EFF_GRP_sa +=0x04;
    877 	LPC_CANAF->ENDofTable +=0x04;
    878 
    879 	LPC_CANAF->AFMR = 0x04;
    880  	return CAN_OK;
    881 }
    882 
    883 /********************************************************************//**
    884  * @brief		Load Group entry into AFLUT
    885  * @param[in]	CANx: CAN peripheral selected, should be:
    886  * 				- LPC_CAN1: CAN1 peripheral
    887  * 				- LPC_CAN2: CAN2 peripheral
    888  * @param[in]	lowerID, upperID: lower and upper identifier of entry
    889  * @param[in]	format: type of ID format, should be:
    890  * 				- STD_ID_FORMAT: Standard ID format (11-bit value)
    891  * 				- EXT_ID_FORMAT: Extended ID format (29-bit value)
    892  * @return 		CAN_ERROR, could be:
    893  * 				- CAN_OK: loading is successful
    894  * 				- CAN_CONFLICT_ID_ERROR: Conflict ID occurs
    895  * 				- CAN_OBJECTS_FULL_ERROR: no more space available
    896  *********************************************************************/
    897 CAN_ERROR CAN_LoadGroupEntry(LPC_CAN_TypeDef* CANx, uint32_t lowerID, \
    898 		uint32_t upperID, CAN_ID_FORMAT_Type format)
    899 {
    900 	uint16_t tmp = 0;
    901 	uint32_t buf0, buf1, entry1, entry2, LID,UID;
    902 	int16_t cnt1, bound1, total;
    903 	//LPC_CANAF_RAM_TypeDef *AFLUTTest = LPC_CANAF_RAM;
    904 
    905 	CHECK_PARAM(PARAM_CANx(CANx));
    906 	CHECK_PARAM(PARAM_ID_FORMAT(format));
    907 
    908 	if(lowerID > upperID) return CAN_CONFLICT_ID_ERROR;
    909 	if(CANx == LPC_CAN1)
    910 	{
    911 		tmp = 0;
    912 	}
    913 	else
    914 	{
    915 		tmp = 1;
    916 	}
    917 
    918 	total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+  \
    919 			CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
    920 
    921 	/* Setup Acceptance Filter Configuration
    922 	Acceptance Filter Mode Register = Off */
    923 	LPC_CANAF->AFMR = 0x00000001;
    924 
    925 /*********Add Group of Standard Identifier Frame Format************/
    926 	if(format == STD_ID_FORMAT)
    927 	{
    928 		if ((total >= 512)){//don't have enough space
    929 			return CAN_OBJECTS_FULL_ERROR;
    930 		}
    931 		lowerID &=0x7FF; //mask ID
    932 		upperID &=0x7FF;
    933 		entry1  = (tmp << 29)|(lowerID << 16)|(tmp << 13)|(upperID << 0);
    934 		cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1);
    935 
    936 		//if this is the first Group standard ID entry
    937 		if(CANAF_gstd_cnt == 0)
    938 		{
    939 			LPC_CANAF_RAM->mask[cnt1] = entry1;
    940 		}
    941 		else
    942 		{
    943 			//find the position to add new Group entry
    944 			bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt;
    945 			while(cnt1 < bound1)
    946 			{
    947 				//compare controller first
    948 				while((LPC_CANAF_RAM->mask[cnt1] >> 29)< (entry1 >> 29))//increase until meet greater or equal controller
    949 					cnt1++;
    950 				buf0 = LPC_CANAF_RAM->mask[cnt1];
    951 				if((LPC_CANAF_RAM->mask[cnt1] >> 29)> (entry1 >> 29)) //meet greater controller
    952 				{
    953 					//add at this position
    954 					LPC_CANAF_RAM->mask[cnt1] = entry1;
    955 					break;
    956 				}
    957 				else //meet equal controller
    958 				{
    959 					LID  = (buf0 >> 16)&0x7FF;
    960 					UID  = buf0 & 0x7FF;
    961 					if (upperID <= LID)
    962 					{
    963 						//add new entry before this entry
    964 						LPC_CANAF_RAM->mask[cnt1] = entry1;
    965 						break;
    966 					}
    967 					else if (lowerID >= UID)
    968 					{
    969 						//load next entry to compare
    970 						cnt1 ++;
    971 					}
    972 					else
    973 						return CAN_CONFLICT_ID_ERROR;
    974 				}
    975 			}
    976 			if(cnt1 >= bound1)
    977 			{
    978 				//add new entry at the last position in this list
    979 				buf0 = LPC_CANAF_RAM->mask[cnt1];
    980 				LPC_CANAF_RAM->mask[cnt1] = entry1;
    981 			}
    982 
    983 			//remove all remaining entry of this section one place up
    984 			bound1 = total - cnt1;
    985 			while(bound1--)
    986 			{
    987 				cnt1++;
    988 				buf1 = LPC_CANAF_RAM->mask[cnt1];
    989 				LPC_CANAF_RAM->mask[cnt1] = buf0;
    990 				buf0 = buf1;
    991 			}
    992 		}
    993 		CANAF_gstd_cnt++;
    994 		//update address values
    995 		LPC_CANAF->EFF_sa     +=0x04 ;
    996 		LPC_CANAF->EFF_GRP_sa +=0x04;
    997 		LPC_CANAF->ENDofTable +=0x04;
    998 	}
    999 
   1000 
   1001 /*********Add Group of Extended Identifier Frame Format************/
   1002 	else
   1003 	{
   1004 		if ((total >= 511)){//don't have enough space
   1005 			return CAN_OBJECTS_FULL_ERROR;
   1006 		}
   1007 		lowerID  &= 0x1FFFFFFF; //mask ID
   1008 		upperID &= 0x1FFFFFFF;
   1009 		entry1   = (tmp << 29)|(lowerID << 0);
   1010 		entry2   = (tmp << 29)|(upperID << 0);
   1011 
   1012 		cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt + CANAF_ext_cnt;
   1013 		//if this is the first Group standard ID entry
   1014 		if(CANAF_gext_cnt == 0)
   1015 		{
   1016 			LPC_CANAF_RAM->mask[cnt1] = entry1;
   1017 			LPC_CANAF_RAM->mask[cnt1+1] = entry2;
   1018 		}
   1019 		else
   1020 		{
   1021 			//find the position to add new Group entry
   1022 			bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt \
   1023 						+ CANAF_ext_cnt + (CANAF_gext_cnt<<1);
   1024 			while(cnt1 < bound1)
   1025 			{
   1026 				while((LPC_CANAF_RAM->mask[cnt1] >>29)< tmp) //increase until meet greater or equal controller
   1027 					cnt1++;
   1028 				buf0 = LPC_CANAF_RAM->mask[cnt1];
   1029 				buf1 = LPC_CANAF_RAM->mask[cnt1+1];
   1030 				if((LPC_CANAF_RAM->mask[cnt1] >> 29)> (entry1 >> 29)) //meet greater controller
   1031 				{
   1032 					//add at this position
   1033 					LPC_CANAF_RAM->mask[cnt1] = entry1;
   1034 					LPC_CANAF_RAM->mask[++cnt1] = entry2;
   1035 					break;
   1036 				}
   1037 				else //meet equal controller
   1038 				{
   1039 					LID  = buf0 & 0x1FFFFFFF; //mask ID
   1040 					UID  = buf1 & 0x1FFFFFFF;
   1041 					if (upperID <= LID)
   1042 					{
   1043 						//add new entry before this entry
   1044 						LPC_CANAF_RAM->mask[cnt1] = entry1;
   1045 						LPC_CANAF_RAM->mask[++cnt1] = entry2;
   1046 						break;
   1047 					}
   1048 					else if (lowerID >= UID)
   1049 					{
   1050 						//load next entry to compare
   1051 						cnt1 +=2;
   1052 					}
   1053 					else
   1054 						return CAN_CONFLICT_ID_ERROR;
   1055 				}
   1056 			}
   1057 			if(cnt1 >= bound1)
   1058 			{
   1059 				//add new entry at the last position in this list
   1060 				buf0 = LPC_CANAF_RAM->mask[cnt1];
   1061 				buf1 = LPC_CANAF_RAM->mask[cnt1+1];
   1062 				LPC_CANAF_RAM->mask[cnt1]   = entry1;
   1063 				LPC_CANAF_RAM->mask[++cnt1] = entry2;
   1064 			}
   1065 			//remove all remaining entry of this section two place up
   1066 			bound1 = total - cnt1 + 1;
   1067 			cnt1++;
   1068 			while(bound1>0)
   1069 			{
   1070 				entry1 = LPC_CANAF_RAM->mask[cnt1];
   1071 				entry2 = LPC_CANAF_RAM->mask[cnt1+1];
   1072 				LPC_CANAF_RAM->mask[cnt1]   = buf0;
   1073 				LPC_CANAF_RAM->mask[cnt1+1] = buf1;
   1074 				buf0 = entry1;
   1075 				buf1 = entry2;
   1076 				cnt1   +=2;
   1077 				bound1 -=2;
   1078 			}
   1079 		}
   1080 		CANAF_gext_cnt++;
   1081 		//update address values
   1082 		LPC_CANAF->ENDofTable +=0x08;
   1083 	}
   1084 	LPC_CANAF->AFMR = 0x04;
   1085  	return CAN_OK;
   1086 }
   1087 
   1088 /********************************************************************//**
   1089  * @brief		Remove AFLUT entry (FullCAN entry and Explicit Standard entry)
   1090  * @param[in]	EntryType: the type of entry that want to remove, should be:
   1091  * 				- FULLCAN_ENTRY
   1092  * 				- EXPLICIT_STANDARD_ENTRY
   1093  * 				- GROUP_STANDARD_ENTRY
   1094  * 				- EXPLICIT_EXTEND_ENTRY
   1095  * 				- GROUP_EXTEND_ENTRY
   1096  * @param[in]	position: the position of this entry in its section
   1097  * Note: the first position is 0
   1098  * @return 		CAN_ERROR, could be:
   1099  * 				- CAN_OK: removing is successful
   1100  * 				- CAN_ENTRY_NOT_EXIT_ERROR: entry want to remove is not exit
   1101  *********************************************************************/
   1102 CAN_ERROR CAN_RemoveEntry(AFLUT_ENTRY_Type EntryType, uint16_t position)
   1103 {
   1104 	uint16_t cnt, bound, total;
   1105 	uint32_t buf0, buf1;
   1106 	CHECK_PARAM(PARAM_AFLUT_ENTRY_TYPE(EntryType));
   1107 	CHECK_PARAM(PARAM_POSITION(position));
   1108 
   1109 	/* Setup Acceptance Filter Configuration
   1110 	Acceptance Filter Mode Register = Off */
   1111 	LPC_CANAF->AFMR = 0x00000001;
   1112 	total = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt + 1) >> 1) + \
   1113 			CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
   1114 
   1115 
   1116 /************** Remove FullCAN Entry *************/
   1117 	if(EntryType == FULLCAN_ENTRY)
   1118 	{
   1119 		if((CANAF_FullCAN_cnt==0)||(position >= CANAF_FullCAN_cnt))
   1120 		{
   1121 			return CAN_ENTRY_NOT_EXIT_ERROR;
   1122 		}
   1123 		else
   1124 		{
   1125 			cnt = position >> 1;
   1126 			buf0 = LPC_CANAF_RAM->mask[cnt];
   1127 			bound = (CANAF_FullCAN_cnt - position -1)>>1;
   1128 			if((position & 0x0001) == 0) //event position
   1129 			{
   1130 				while(bound--)
   1131 				{
   1132 					//remove all remaining FullCAN entry one place down
   1133 					buf1  = LPC_CANAF_RAM->mask[cnt+1];
   1134 					LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16);
   1135 					buf0  = buf1;
   1136 					cnt++;
   1137 				}
   1138 			}
   1139 			else //odd position
   1140 			{
   1141 				while(bound--)
   1142 				{
   1143 					//remove all remaining FullCAN entry one place down
   1144 					buf1  = LPC_CANAF_RAM->mask[cnt+1];
   1145 					LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000)|(buf1 >> 16);
   1146 					LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+1] << 16;
   1147 					buf0  = buf1<<16;
   1148 					cnt++;
   1149 				}
   1150 			}
   1151 			if((CANAF_FullCAN_cnt & 0x0001) == 0)
   1152 			{
   1153 				if((position & 0x0001)==0)
   1154 					LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF);
   1155 				else
   1156 					LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF;
   1157 			}
   1158 			else
   1159 			{
   1160 				//remove all remaining section one place down
   1161 				cnt = (CANAF_FullCAN_cnt + 1)>>1;
   1162 				bound = total + CANAF_FullCAN_cnt * 3;
   1163 				while(bound>cnt)
   1164 				{
   1165 					LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
   1166 					cnt++;
   1167 				}
   1168 				LPC_CANAF_RAM->mask[cnt-1]=0x00;
   1169 				//update address values
   1170 				LPC_CANAF->SFF_sa 	  -=0x04;
   1171 				LPC_CANAF->SFF_GRP_sa -=0x04 ;
   1172 				LPC_CANAF->EFF_sa     -=0x04 ;
   1173 				LPC_CANAF->EFF_GRP_sa -=0x04;
   1174 				LPC_CANAF->ENDofTable -=0x04;
   1175 			}
   1176 			CANAF_FullCAN_cnt--;
   1177 
   1178 			//delete its FullCAN Object in the FullCAN Object section
   1179 			//remove all remaining FullCAN Object three place down
   1180 			cnt = total + position * 3;
   1181 			bound = (CANAF_FullCAN_cnt - position + 1) * 3;
   1182 
   1183 			while(bound)
   1184 			{
   1185 				LPC_CANAF_RAM->mask[cnt]=LPC_CANAF_RAM->mask[cnt+3];;
   1186 				LPC_CANAF_RAM->mask[cnt+1]=LPC_CANAF_RAM->mask[cnt+4];
   1187 				LPC_CANAF_RAM->mask[cnt+2]=LPC_CANAF_RAM->mask[cnt+5];
   1188 				bound -=3;
   1189 				cnt   +=3;
   1190 			}
   1191 		}
   1192 	}
   1193 
   1194 /************** Remove Explicit Standard ID Entry *************/
   1195 	else if(EntryType == EXPLICIT_STANDARD_ENTRY)
   1196 	{
   1197 		if((CANAF_std_cnt==0)||(position >= CANAF_std_cnt))
   1198 		{
   1199 			return CAN_ENTRY_NOT_EXIT_ERROR;
   1200 		}
   1201 		else
   1202 		{
   1203 			cnt = ((CANAF_FullCAN_cnt+1)>>1)+ (position >> 1);
   1204 			buf0 = LPC_CANAF_RAM->mask[cnt];
   1205 			bound = (CANAF_std_cnt - position - 1)>>1;
   1206 			if((position & 0x0001) == 0) //event position
   1207 			{
   1208 				while(bound--)
   1209 				{
   1210 					//remove all remaining FullCAN entry one place down
   1211 					buf1  = LPC_CANAF_RAM->mask[cnt+1];
   1212 					LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16);
   1213 					buf0  = buf1;
   1214 					cnt++;
   1215 				}
   1216 			}
   1217 			else //odd position
   1218 			{
   1219 				while(bound--)
   1220 				{
   1221 					//remove all remaining FullCAN entry one place down
   1222 					buf1  = LPC_CANAF_RAM->mask[cnt+1];
   1223 					LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000)|(buf1 >> 16);
   1224 					LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+1] << 16;
   1225 					buf0  = buf1<<16;
   1226 					cnt++;
   1227 				}
   1228 			}
   1229 			if((CANAF_std_cnt & 0x0001) == 0)
   1230 			{
   1231 				if((position & 0x0001)==0)
   1232 					LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF);
   1233 				else
   1234 					LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF;
   1235 			}
   1236 			else
   1237 			{
   1238 				//remove all remaining section one place down
   1239 				cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1);
   1240 				bound = total + CANAF_FullCAN_cnt * 3;
   1241 				while(bound>cnt)
   1242 				{
   1243 					LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
   1244 					cnt++;
   1245 				}
   1246 				LPC_CANAF_RAM->mask[cnt-1]=0x00;
   1247 				//update address value
   1248 				LPC_CANAF->SFF_GRP_sa -=0x04 ;
   1249 				LPC_CANAF->EFF_sa     -=0x04 ;
   1250 				LPC_CANAF->EFF_GRP_sa -=0x04;
   1251 				LPC_CANAF->ENDofTable -=0x04;
   1252 			}
   1253 			CANAF_std_cnt--;
   1254 		}
   1255 	}
   1256 
   1257 /************** Remove Group of Standard ID Entry *************/
   1258 	else if(EntryType == GROUP_STANDARD_ENTRY)
   1259 	{
   1260 		if((CANAF_gstd_cnt==0)||(position >= CANAF_gstd_cnt))
   1261 		{
   1262 			return CAN_ENTRY_NOT_EXIT_ERROR;
   1263 		}
   1264 		else
   1265 		{
   1266 			cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1)+ position + 1;
   1267 			bound = total + CANAF_FullCAN_cnt * 3;
   1268 			while (cnt<bound)
   1269 			{
   1270 				LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
   1271 				cnt++;
   1272 			}
   1273 			LPC_CANAF_RAM->mask[cnt-1]=0x00;
   1274 		}
   1275 		CANAF_gstd_cnt--;
   1276 		//update address value
   1277 		LPC_CANAF->EFF_sa     -=0x04;
   1278 		LPC_CANAF->EFF_GRP_sa -=0x04;
   1279 		LPC_CANAF->ENDofTable -=0x04;
   1280 	}
   1281 
   1282 /************** Remove Explicit Extended ID Entry *************/
   1283 	else if(EntryType == EXPLICIT_EXTEND_ENTRY)
   1284 	{
   1285 		if((CANAF_ext_cnt==0)||(position >= CANAF_ext_cnt))
   1286 		{
   1287 			return CAN_ENTRY_NOT_EXIT_ERROR;
   1288 		}
   1289 		else
   1290 		{
   1291 			cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1)+ CANAF_gstd_cnt + position + 1;
   1292 			bound = total + CANAF_FullCAN_cnt * 3;
   1293 			while (cnt<bound)
   1294 			{
   1295 				LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
   1296 				cnt++;
   1297 			}
   1298 			LPC_CANAF_RAM->mask[cnt-1]=0x00;
   1299 		}
   1300 		CANAF_ext_cnt--;
   1301 		LPC_CANAF->EFF_GRP_sa -=0x04;
   1302 		LPC_CANAF->ENDofTable -=0x04;
   1303 	}
   1304 
   1305 /************** Remove Group of Extended ID Entry *************/
   1306 	else
   1307 	{
   1308 		if((CANAF_gext_cnt==0)||(position >= CANAF_gext_cnt))
   1309 		{
   1310 			return CAN_ENTRY_NOT_EXIT_ERROR;
   1311 		}
   1312 		else
   1313 		{
   1314 			cnt = total - (CANAF_gext_cnt<<1) + (position<<1);
   1315 			bound = total + CANAF_FullCAN_cnt * 3;
   1316 			while (cnt<bound)
   1317 			{
   1318 				//remove all remaining entry two place up
   1319 				LPC_CANAF_RAM->mask[cnt] = LPC_CANAF_RAM->mask[cnt+2];
   1320 				LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+3];
   1321 				cnt+=2;
   1322 			}
   1323 		}
   1324 		CANAF_gext_cnt--;
   1325 		LPC_CANAF->ENDofTable -=0x08;
   1326 	}
   1327 	LPC_CANAF->AFMR = 0x04;
   1328 	return CAN_OK;
   1329 }
   1330 
   1331 /********************************************************************//**
   1332  * @brief		Send message data
   1333  * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
   1334  * 				- LPC_CAN1: CAN1 peripheral
   1335  * 				- LPC_CAN2: CAN2 peripheral
   1336  * @param[in]	CAN_Msg point to the CAN_MSG_Type Structure, it contains message
   1337  * 				information such as: ID, DLC, RTR, ID Format
   1338  * @return 		Status:
   1339  * 				- SUCCESS: send message successfully
   1340  * 				- ERROR: send message unsuccessfully
   1341  *********************************************************************/
   1342 Status CAN_SendMsg (LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg)
   1343 {
   1344 	uint32_t data;
   1345 	CHECK_PARAM(PARAM_CANx(CANx));
   1346 	CHECK_PARAM(PARAM_ID_FORMAT(CAN_Msg->format));
   1347 	if(CAN_Msg->format==STD_ID_FORMAT)
   1348 	{
   1349 		CHECK_PARAM(PARAM_ID_11(CAN_Msg->id));
   1350 	}
   1351 	else
   1352 	{
   1353 		CHECK_PARAM(PARAM_ID_29(CAN_Msg->id));
   1354 	}
   1355 	CHECK_PARAM(PARAM_DLC(CAN_Msg->len));
   1356 	CHECK_PARAM(PARAM_FRAME_TYPE(CAN_Msg->type));
   1357 
   1358 	//Check status of Transmit Buffer 1
   1359 	if (CANx->SR & (1<<2))
   1360 	{
   1361 		/* Transmit Channel 1 is available */
   1362 		/* Write frame informations and frame data into its CANxTFI1,
   1363 		 * CANxTID1, CANxTDA1, CANxTDB1 register */
   1364 		CANx->TFI1 &= ~0x000F0000;
   1365 		CANx->TFI1 |= (CAN_Msg->len)<<16;
   1366 		if(CAN_Msg->type == REMOTE_FRAME)
   1367 		{
   1368 			CANx->TFI1 |= (1<<30); //set bit RTR
   1369 		}
   1370 		else
   1371 		{
   1372 			CANx->TFI1 &= ~(1<<30);
   1373 		}
   1374 		if(CAN_Msg->format == EXT_ID_FORMAT)
   1375 		{
   1376 			CANx->TFI1 |= (0x80000000); //set bit FF
   1377 		}
   1378 		else
   1379 		{
   1380 			CANx->TFI1 &= ~(0x80000000);
   1381 		}
   1382 
   1383 		/* Write CAN ID*/
   1384 		CANx->TID1 = CAN_Msg->id;
   1385 
   1386 		/*Write first 4 data bytes*/
   1387 		data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);
   1388 		CANx->TDA1 = data;
   1389 
   1390 		/*Write second 4 data bytes*/
   1391 		data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);
   1392 		CANx->TDB1 = data;
   1393 
   1394 		 /*Write transmission request*/
   1395 		 CANx->CMR = 0x21;
   1396 		 return SUCCESS;
   1397 	}
   1398 	//check status of Transmit Buffer 2
   1399 	else if(CANx->SR & (1<<10))
   1400 	{
   1401 		/* Transmit Channel 2 is available */
   1402 		/* Write frame informations and frame data into its CANxTFI2,
   1403 		 * CANxTID2, CANxTDA2, CANxTDB2 register */
   1404 		CANx->TFI2 &= ~0x000F0000;
   1405 		CANx->TFI2 |= (CAN_Msg->len)<<16;
   1406 		if(CAN_Msg->type == REMOTE_FRAME)
   1407 		{
   1408 			CANx->TFI2 |= (1<<30); //set bit RTR
   1409 		}
   1410 		else
   1411 		{
   1412 			CANx->TFI2 &= ~(1<<30);
   1413 		}
   1414 		if(CAN_Msg->format == EXT_ID_FORMAT)
   1415 		{
   1416 			CANx->TFI2 |= (0x80000000); //set bit FF
   1417 		}
   1418 		else
   1419 		{
   1420 			CANx->TFI2 &= ~(0x80000000);
   1421 		}
   1422 
   1423 		/* Write CAN ID*/
   1424 		CANx->TID2 = CAN_Msg->id;
   1425 
   1426 		/*Write first 4 data bytes*/
   1427 		data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);
   1428 		CANx->TDA2 = data;
   1429 
   1430 		/*Write second 4 data bytes*/
   1431 		data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);
   1432 		CANx->TDB2 = data;
   1433 
   1434 		/*Write transmission request*/
   1435 		CANx->CMR = 0x41;
   1436 		return SUCCESS;
   1437 	}
   1438 	//check status of Transmit Buffer 3
   1439 	else if (CANx->SR & (1<<18))
   1440 	{
   1441 		/* Transmit Channel 3 is available */
   1442 		/* Write frame informations and frame data into its CANxTFI3,
   1443 		 * CANxTID3, CANxTDA3, CANxTDB3 register */
   1444 		CANx->TFI3 &= ~0x000F0000;
   1445 		CANx->TFI3 |= (CAN_Msg->len)<<16;
   1446 		if(CAN_Msg->type == REMOTE_FRAME)
   1447 		{
   1448 			CANx->TFI3 |= (1<<30); //set bit RTR
   1449 		}
   1450 		else
   1451 		{
   1452 			CANx->TFI3 &= ~(1<<30);
   1453 		}
   1454 		if(CAN_Msg->format == EXT_ID_FORMAT)
   1455 		{
   1456 			CANx->TFI3 |= (0x80000000); //set bit FF
   1457 		}
   1458 		else
   1459 		{
   1460 			CANx->TFI3 &= ~(0x80000000);
   1461 		}
   1462 
   1463 		/* Write CAN ID*/
   1464 		CANx->TID3 = CAN_Msg->id;
   1465 
   1466 		/*Write first 4 data bytes*/
   1467 		data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);
   1468 		CANx->TDA3 = data;
   1469 
   1470 		/*Write second 4 data bytes*/
   1471 		data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);
   1472 		CANx->TDB3 = data;
   1473 
   1474 		/*Write transmission request*/
   1475 		CANx->CMR = 0x81;
   1476 		return SUCCESS;
   1477 	}
   1478 	else
   1479 	{
   1480 		return ERROR;
   1481 	}
   1482 }
   1483 
   1484 /********************************************************************//**
   1485  * @brief		Receive message data
   1486  * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
   1487  * 				- LPC_CAN1: CAN1 peripheral
   1488  * 				- LPC_CAN2: CAN2 peripheral
   1489  * @param[in]	CAN_Msg point to the CAN_MSG_Type Struct, it will contain received
   1490  *  			message information such as: ID, DLC, RTR, ID Format
   1491  * @return 		Status:
   1492  * 				- SUCCESS: receive message successfully
   1493  * 				- ERROR: receive message unsuccessfully
   1494  *********************************************************************/
   1495 Status CAN_ReceiveMsg (LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg)
   1496 {
   1497 	uint32_t data;
   1498 
   1499 	CHECK_PARAM(PARAM_CANx(CANx));
   1500 
   1501 	//check status of Receive Buffer
   1502 	if((CANx->SR &0x00000001))
   1503 	{
   1504 		/* Receive message is available */
   1505 		/* Read frame informations */
   1506 		CAN_Msg->format   = (uint8_t)(((CANx->RFS) & 0x80000000)>>31);
   1507 		CAN_Msg->type     = (uint8_t)(((CANx->RFS) & 0x40000000)>>30);
   1508 		CAN_Msg->len      = (uint8_t)(((CANx->RFS) & 0x000F0000)>>16);
   1509 
   1510 
   1511 		/* Read CAN message identifier */
   1512 		CAN_Msg->id = CANx->RID;
   1513 
   1514 		/* Read the data if received message was DATA FRAME */
   1515 		if (CAN_Msg->type == DATA_FRAME)
   1516 		{
   1517 			/* Read first 4 data bytes */
   1518 			data = CANx->RDA;
   1519 			*((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF;
   1520 			*((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00)>>8;;
   1521 			*((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000)>>16;
   1522 			*((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000)>>24;
   1523 
   1524 			/* Read second 4 data bytes */
   1525 			data = CANx->RDB;
   1526 			*((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF;
   1527 			*((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00)>>8;
   1528 			*((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000)>>16;
   1529 			*((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000)>>24;
   1530 
   1531 		/*release receive buffer*/
   1532 		CANx->CMR = 0x04;
   1533 		}
   1534 		else
   1535 		{
   1536 			/* Received Frame is a Remote Frame, not have data, we just receive
   1537 			 * message information only */
   1538 			CANx->CMR = 0x04; /*release receive buffer*/
   1539 			return SUCCESS;
   1540 		}
   1541 	}
   1542 	else
   1543 	{
   1544 		// no receive message available
   1545 		return ERROR;
   1546 	}
   1547 	return SUCCESS;
   1548 }
   1549 
   1550 /********************************************************************//**
   1551  * @brief		Receive FullCAN Object
   1552  * @param[in]	CANAFx: CAN Acceptance Filter register, should be: LPC_CANAF
   1553  * @param[in]	CAN_Msg point to the CAN_MSG_Type Struct, it will contain received
   1554  *  			message information such as: ID, DLC, RTR, ID Format
   1555  * @return 		CAN_ERROR, could be:
   1556  * 				- CAN_FULL_OBJ_NOT_RCV: FullCAN Object is not be received
   1557  * 				- CAN_OK: Received FullCAN Object successful
   1558  *
   1559  *********************************************************************/
   1560 CAN_ERROR FCAN_ReadObj (LPC_CANAF_TypeDef* CANAFx, CAN_MSG_Type *CAN_Msg)
   1561 {
   1562 	uint32_t *pSrc, data;
   1563 	uint32_t interrut_word, msg_idx, test_bit, head_idx, tail_idx;
   1564 
   1565 	CHECK_PARAM(PARAM_CANAFx(CANAFx));
   1566 
   1567 	interrut_word = 0;
   1568 
   1569 	if (LPC_CANAF->FCANIC0 != 0)
   1570 	{
   1571 		interrut_word = LPC_CANAF->FCANIC0;
   1572 		head_idx = 0;
   1573 		tail_idx = 31;
   1574 	}
   1575 	else if (LPC_CANAF->FCANIC1 != 0)
   1576 	{
   1577 		interrut_word = LPC_CANAF->FCANIC1;
   1578 		head_idx = 32;
   1579 		tail_idx = 63;
   1580 	}
   1581 
   1582 	if (interrut_word != 0)
   1583 	{
   1584 		/* Detect for interrupt pending */
   1585 		msg_idx = 0;
   1586 		for (msg_idx = head_idx; msg_idx <= tail_idx; msg_idx++)
   1587 		{
   1588 			test_bit = interrut_word & 0x1;
   1589 			interrut_word = interrut_word >> 1;
   1590 
   1591 			if (test_bit)
   1592 			{
   1593 				pSrc = (uint32_t *) (LPC_CANAF->ENDofTable + LPC_CANAF_RAM_BASE + msg_idx * 12);
   1594 
   1595 	    	 	/* Has been finished updating the content */
   1596 	    	 	if ((*pSrc & 0x03000000L) == 0x03000000L)
   1597 	    	 	{
   1598 	    	 		/*clear semaphore*/
   1599 	    	 		*pSrc &= 0xFCFFFFFF;
   1600 
   1601 	    	 		/*Set to DatA*/
   1602 	    	 		pSrc++;
   1603 	    	 		/* Copy to dest buf */
   1604 	    	 		data = *pSrc;
   1605 	    			*((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF;
   1606 	    			*((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00)>>8;
   1607 	    			*((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000)>>16;
   1608 	    			*((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000)>>24;
   1609 
   1610 	    	 		/*Set to DatB*/
   1611 	    	 		pSrc++;
   1612 	    	 		/* Copy to dest buf */
   1613 	    	 		data = *pSrc;
   1614 	    			*((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF;
   1615 	    			*((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00)>>8;
   1616 	    			*((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000)>>16;
   1617 	    			*((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000)>>24;
   1618 	    	 		/*Back to Dat1*/
   1619 	    	 		pSrc -= 2;
   1620 
   1621 	    	 		CAN_Msg->id = *pSrc & 0x7FF;
   1622 	    	 		CAN_Msg->len = (uint8_t) (*pSrc >> 16) & 0x0F;
   1623 					CAN_Msg->format = 0; //FullCAN Object ID always is 11-bit value
   1624 					CAN_Msg->type = (uint8_t)(*pSrc >> 30) &0x01;
   1625 	    	 		/*Re-read semaphore*/
   1626 	    	 		if ((*pSrc & 0x03000000L) == 0)
   1627 	    	 		{
   1628 	    	 			return CAN_OK;
   1629 	    	 		}
   1630 	    	 	}
   1631 			}
   1632 		}
   1633 	}
   1634 	return CAN_FULL_OBJ_NOT_RCV;
   1635 }
   1636 /********************************************************************//**
   1637  * @brief		Get CAN Control Status
   1638  * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
   1639  * 				- LPC_CAN1: CAN1 peripheral
   1640  * 				- LPC_CAN2: CAN2 peripheral
   1641  * @param[in]	arg: type of CAN status to get from CAN status register
   1642  * 				Should be:
   1643  * 				- CANCTRL_GLOBAL_STS: CAN Global Status
   1644  * 				- CANCTRL_INT_CAP: CAN Interrupt and Capture
   1645  * 				- CANCTRL_ERR_WRN: CAN Error Warning Limit
   1646  * 				- CANCTRL_STS: CAN Control Status
   1647  * @return 		Current Control Status that you want to get value
   1648  *********************************************************************/
   1649 uint32_t CAN_GetCTRLStatus (LPC_CAN_TypeDef* CANx, CAN_CTRL_STS_Type arg)
   1650 {
   1651 	CHECK_PARAM(PARAM_CANx(CANx));
   1652 	CHECK_PARAM(PARAM_CTRL_STS_TYPE(arg));
   1653 
   1654 	switch (arg)
   1655 	{
   1656 	case CANCTRL_GLOBAL_STS:
   1657 		return CANx->GSR;
   1658 
   1659 	case CANCTRL_INT_CAP:
   1660 		return CANx->ICR;
   1661 
   1662 	case CANCTRL_ERR_WRN:
   1663 		return CANx->EWL;
   1664 
   1665 	default: // CANCTRL_STS
   1666 		return CANx->SR;
   1667 	}
   1668 }
   1669 /********************************************************************//**
   1670  * @brief		Get CAN Central Status
   1671  * @param[in]	CANCRx point to LPC_CANCR_TypeDef, should be: LPC_CANCR
   1672  * @param[in]	arg: type of CAN status to get from CAN Central status register
   1673  * 				Should be:
   1674  * 				- CANCR_TX_STS: Central CAN Tx Status
   1675  * 				- CANCR_RX_STS: Central CAN Rx Status
   1676  * 				- CANCR_MS: Central CAN Miscellaneous Status
   1677  * @return 		Current Central Status that you want to get value
   1678  *********************************************************************/
   1679 uint32_t CAN_GetCRStatus (LPC_CANCR_TypeDef* CANCRx, CAN_CR_STS_Type arg)
   1680 {
   1681 	CHECK_PARAM(PARAM_CANCRx(CANCRx));
   1682 	CHECK_PARAM(PARAM_CR_STS_TYPE(arg));
   1683 
   1684 	switch (arg)
   1685 	{
   1686 	case CANCR_TX_STS:
   1687 		return CANCRx->CANTxSR;
   1688 
   1689 	case CANCR_RX_STS:
   1690 		return CANCRx->CANRxSR;
   1691 
   1692 	default:	// CANCR_MS
   1693 		return CANCRx->CANMSR;
   1694 	}
   1695 }
   1696 /********************************************************************//**
   1697  * @brief		Enable/Disable CAN Interrupt
   1698  * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
   1699  * 				- LPC_CAN1: CAN1 peripheral
   1700  * 				- LPC_CAN2: CAN2 peripheral
   1701  * @param[in]	arg: type of CAN interrupt that you want to enable/disable
   1702  * 				Should be:
   1703  * 				- CANINT_RIE: CAN Receiver Interrupt Enable
   1704  * 				- CANINT_TIE1: CAN Transmit Interrupt Enable
   1705  * 				- CANINT_EIE: CAN Error Warning Interrupt Enable
   1706  * 				- CANINT_DOIE: CAN Data Overrun Interrupt Enable
   1707  * 				- CANINT_WUIE: CAN Wake-Up Interrupt Enable
   1708  * 				- CANINT_EPIE: CAN Error Passive Interrupt Enable
   1709  * 				- CANINT_ALIE: CAN Arbitration Lost Interrupt Enable
   1710  * 				- CANINT_BEIE: CAN Bus Error Interrupt Enable
   1711  * 				- CANINT_IDIE: CAN ID Ready Interrupt Enable
   1712  * 				- CANINT_TIE2: CAN Transmit Interrupt Enable for Buffer2
   1713  * 				- CANINT_TIE3: CAN Transmit Interrupt Enable for Buffer3
   1714  * 				- CANINT_FCE: FullCAN Interrupt Enable
   1715  * @param[in]	NewState: New state of this function, should be:
   1716  * 				- ENABLE
   1717  * 				- DISABLE
   1718  * @return 		none
   1719  *********************************************************************/
   1720 void CAN_IRQCmd (LPC_CAN_TypeDef* CANx, CAN_INT_EN_Type arg, FunctionalState NewState)
   1721 {
   1722 	CHECK_PARAM(PARAM_CANx(CANx));
   1723 	CHECK_PARAM(PARAM_INT_EN_TYPE(arg));
   1724 	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
   1725 
   1726 	if(NewState == ENABLE)
   1727 	{
   1728 		if(arg==CANINT_FCE)
   1729 		{
   1730 			LPC_CANAF->AFMR = 0x01;
   1731 			LPC_CANAF->FCANIE = 0x01;
   1732 			LPC_CANAF->AFMR = 0x04;
   1733 		}
   1734 		else
   1735 			CANx->IER |= (1 << arg);
   1736 	}
   1737 	else
   1738 	{
   1739 		if(arg==CANINT_FCE){
   1740 			LPC_CANAF->AFMR = 0x01;
   1741 			LPC_CANAF->FCANIE = 0x01;
   1742 			LPC_CANAF->AFMR = 0x00;
   1743 		}
   1744 		else
   1745 			CANx->IER &= ~(1 << arg);
   1746 	}
   1747 }
   1748 
   1749 /********************************************************************//**
   1750  * @brief		Setting Acceptance Filter mode
   1751  * @param[in]	CANAFx point to LPC_CANAF_TypeDef object, should be: LPC_CANAF
   1752  * @param[in]	AFMode: type of AF mode that you want to set, should be:
   1753  * 				- CAN_Normal: Normal mode
   1754  * 				- CAN_AccOff: Acceptance Filter Off Mode
   1755  * 				- CAN_AccBP: Acceptance Fileter Bypass Mode
   1756  * 				- CAN_eFCAN: FullCAN Mode Enhancement
   1757  * @return 		none
   1758  *********************************************************************/
   1759 void CAN_SetAFMode (LPC_CANAF_TypeDef* CANAFx, CAN_AFMODE_Type AFMode)
   1760 {
   1761 	CHECK_PARAM(PARAM_CANAFx(CANAFx));
   1762 	CHECK_PARAM(PARAM_AFMODE_TYPE(AFMode));
   1763 
   1764 	switch(AFMode)
   1765 	{
   1766 	case CAN_Normal:
   1767 		CANAFx->AFMR = 0x00;
   1768 		break;
   1769 	case CAN_AccOff:
   1770 		CANAFx->AFMR = 0x01;
   1771 		break;
   1772 	case CAN_AccBP:
   1773 		CANAFx->AFMR = 0x02;
   1774 		break;
   1775 	case CAN_eFCAN:
   1776 		CANAFx->AFMR = 0x04;
   1777 		break;
   1778 	}
   1779 }
   1780 
   1781 /********************************************************************//**
   1782  * @brief		Enable/Disable CAN Mode
   1783  * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
   1784  * 				- LPC_CAN1: CAN1 peripheral
   1785  * 				- LPC_CAN2: CAN2 peripheral
   1786  * @param[in]	mode: type of CAN mode that you want to enable/disable, should be:
   1787  * 				- CAN_OPERATING_MODE: Normal Operating Mode
   1788  * 				- CAN_RESET_MODE: Reset Mode
   1789  * 				- CAN_LISTENONLY_MODE: Listen Only Mode
   1790  * 				- CAN_SELFTEST_MODE: Self Test Mode
   1791  * 				- CAN_TXPRIORITY_MODE: Transmit Priority Mode
   1792  * 				- CAN_SLEEP_MODE: Sleep Mode
   1793  * 				- CAN_RXPOLARITY_MODE: Receive Polarity Mode
   1794  * 				- CAN_TEST_MODE: Test Mode
   1795  * @param[in]	NewState: New State of this function, should be:
   1796  * 				- ENABLE
   1797  * 				- DISABLE
   1798  * @return 		none
   1799  *********************************************************************/
   1800 void CAN_ModeConfig(LPC_CAN_TypeDef* CANx, CAN_MODE_Type mode, FunctionalState NewState)
   1801 {
   1802 	CHECK_PARAM(PARAM_CANx(CANx));
   1803 	CHECK_PARAM(PARAM_MODE_TYPE(mode));
   1804 	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
   1805 
   1806 	switch(mode)
   1807 	{
   1808 	case CAN_OPERATING_MODE:
   1809 		CANx->MOD = 0x00;
   1810 		break;
   1811 	case CAN_RESET_MODE:
   1812 		if(NewState == ENABLE)
   1813 			CANx->MOD |=CAN_MOD_RM;
   1814 		else
   1815 			CANx->MOD &= ~CAN_MOD_RM;
   1816 		break;
   1817 	case CAN_LISTENONLY_MODE:
   1818 		CANx->MOD |=CAN_MOD_RM;//Enter Reset mode
   1819 		if(NewState == ENABLE)
   1820 			CANx->MOD |=CAN_MOD_LOM;
   1821 		else
   1822 			CANx->MOD &=~CAN_MOD_LOM;
   1823 		CANx->MOD &=~CAN_MOD_RM;//Release Reset mode
   1824 		break;
   1825 	case CAN_SELFTEST_MODE:
   1826 		CANx->MOD |=CAN_MOD_RM;//Enter Reset mode
   1827 		if(NewState == ENABLE)
   1828 			CANx->MOD |=CAN_MOD_STM;
   1829 		else
   1830 			CANx->MOD &=~CAN_MOD_STM;
   1831 		CANx->MOD &=~CAN_MOD_RM;//Release Reset mode
   1832 		break;
   1833 	case CAN_TXPRIORITY_MODE:
   1834 		if(NewState == ENABLE)
   1835 			CANx->MOD |=CAN_MOD_TPM;
   1836 		else
   1837 			CANx->MOD &=~CAN_MOD_TPM;
   1838 		break;
   1839 	case CAN_SLEEP_MODE:
   1840 		if(NewState == ENABLE)
   1841 			CANx->MOD |=CAN_MOD_SM;
   1842 		else
   1843 			CANx->MOD &=~CAN_MOD_SM;
   1844 		break;
   1845 	case CAN_RXPOLARITY_MODE:
   1846 		if(NewState == ENABLE)
   1847 			CANx->MOD |=CAN_MOD_RPM;
   1848 		else
   1849 			CANx->MOD &=~CAN_MOD_RPM;
   1850 		break;
   1851 	case CAN_TEST_MODE:
   1852 		if(NewState == ENABLE)
   1853 			CANx->MOD |=CAN_MOD_TM;
   1854 		else
   1855 			CANx->MOD &=~CAN_MOD_TM;
   1856 		break;
   1857 	}
   1858 }
   1859 /*********************************************************************//**
   1860  * @brief		Set CAN command request
   1861  * @param[in]	CANx point to CAN peripheral selected, should be:
   1862  * 				- LPC_CAN1: CAN1 peripheral
   1863  * 				- LPC_CAN2: CAN2 peripheral
   1864  * @param[in]	CMRType	command request type, should be:
   1865  * 				- CAN_CMR_TR: Transmission request
   1866  * 				- CAN_CMR_AT: Abort Transmission request
   1867  * 				- CAN_CMR_RRB: Release Receive Buffer request
   1868  * 				- CAN_CMR_CDO: Clear Data Overrun request
   1869  * 				- CAN_CMR_SRR: Self Reception request
   1870  * 				- CAN_CMR_STB1: Select Tx Buffer 1 request
   1871  * 				- CAN_CMR_STB2: Select Tx Buffer 2 request
   1872  * 				- CAN_CMR_STB3: Select Tx Buffer 3 request
   1873  * @return		CANICR (CAN interrupt and Capture register) value
   1874  **********************************************************************/
   1875 void CAN_SetCommand(LPC_CAN_TypeDef* CANx, uint32_t CMRType)
   1876 {
   1877 	CHECK_PARAM(PARAM_CANx(CANx));
   1878 	CANx->CMR |= CMRType;
   1879 }
   1880 
   1881 /*********************************************************************//**
   1882  * @brief		Get CAN interrupt status
   1883  * @param[in]	CANx point to CAN peripheral selected, should be:
   1884  * 				- LPC_CAN1: CAN1 peripheral
   1885  * 				- LPC_CAN2: CAN2 peripheral
   1886  * @return		CANICR (CAN interrupt and Capture register) value
   1887  **********************************************************************/
   1888 uint32_t CAN_IntGetStatus(LPC_CAN_TypeDef* CANx)
   1889 {
   1890 	CHECK_PARAM(PARAM_CANx(CANx));
   1891 	return CANx->ICR;
   1892 }
   1893 
   1894 /*********************************************************************//**
   1895  * @brief		Check if FullCAN interrupt enable or not
   1896  * @param[in]	CANAFx point to LPC_CANAF_TypeDef object, should be: LPC_CANAF
   1897  * @return		IntStatus, could be:
   1898  * 				- SET: if FullCAN interrupt is enable
   1899  * 				- RESET: if FullCAN interrupt is disable
   1900  **********************************************************************/
   1901 IntStatus CAN_FullCANIntGetStatus (LPC_CANAF_TypeDef* CANAFx)
   1902 {
   1903 	CHECK_PARAM( PARAM_CANAFx(CANAFx));
   1904 	if (CANAFx->FCANIE)
   1905 		return SET;
   1906 	return RESET;
   1907 }
   1908 
   1909 /*********************************************************************//**
   1910  * @brief		Get value of FullCAN interrupt and capture register
   1911  * @param[in]	CANAFx point to LPC_CANAF_TypeDef object, should be: LPC_CANAF
   1912  * @param[in]	type: FullCAN IC type, should be:
   1913  * 				- FULLCAN_IC0: FullCAN Interrupt Capture 0
   1914  * 				- FULLCAN_IC1: FullCAN Interrupt Capture 1
   1915  * @return		FCANIC0 or FCANIC1 (FullCAN interrupt and Capture register) value
   1916  **********************************************************************/
   1917 uint32_t CAN_FullCANPendGetStatus(LPC_CANAF_TypeDef* CANAFx, FullCAN_IC_Type type)
   1918 {
   1919 	CHECK_PARAM(PARAM_CANAFx(CANAFx));
   1920 	CHECK_PARAM( PARAM_FULLCAN_IC(type));
   1921 	if (type == FULLCAN_IC0)
   1922 		return CANAFx->FCANIC0;
   1923 	return CANAFx->FCANIC1;
   1924 }
   1925 /* End of Public Variables ---------------------------------------------------------- */
   1926 /**
   1927  * @}
   1928  */
   1929 
   1930 #endif /* _CAN */
   1931 
   1932 /**
   1933  * @}
   1934  */
   1935 
   1936 /* --------------------------------- End Of File ------------------------------ */