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 ------------------------------ */