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
lpc17xx_can.c
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 ------------------------------ */
Generated on Tue Jul 12 2022 17:06:02 by 1.7.2