C:/nxpdrv/LPC1700CMSIS/Drivers/source/lpc17xx_can.c
Go to the documentation of this file.00001 00020 /* Peripheral group ----------------------------------------------------------- */ 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 ---------------------------------------------------------- */ 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 00105 /* Public Functions ----------------------------------------------------------- */ 00111 /*********************************************************************/ 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 /********************************************************************/ 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 CANx->MOD = 0;// Return Normal operating 00205 00206 //Reset CANAF value 00207 LPC_CANAF->AFMR = 0x01; 00208 00209 //clear ALUT RAM 00210 for (i = 0; i < 512; i++) { 00211 LPC_CANAF_RAM->mask[i] = 0x00; 00212 } 00213 00214 LPC_CANAF->SFF_sa = 0x00; 00215 LPC_CANAF->SFF_GRP_sa = 0x00; 00216 LPC_CANAF->EFF_sa = 0x00; 00217 LPC_CANAF->EFF_GRP_sa = 0x00; 00218 LPC_CANAF->ENDofTable = 0x00; 00219 00220 LPC_CANAF->AFMR = 0x00; 00221 /* Set baudrate */ 00222 CAN_SetBaudRate (CANx, baudrate); 00223 } 00224 /********************************************************************/ 00231 void CAN_DeInit(LPC_CAN_TypeDef *CANx) 00232 { 00233 CHECK_PARAM(PARAM_CANx(CANx)); 00234 00235 if(CANx == LPC_CAN1) 00236 { 00237 /* Turn on power and clock for CAN1 */ 00238 CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN1, DISABLE); 00239 } 00240 else 00241 { 00242 /* Turn on power and clock for CAN1 */ 00243 CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN2, DISABLE); 00244 } 00245 } 00246 /********************************************************************/ 00256 CAN_ERROR CAN_SetupAFLUT(LPC_CANAF_TypeDef* CANAFx, AF_SectionDef* AFSection) 00257 { 00258 uint8_t ctrl1,ctrl2; 00259 uint8_t dis1, dis2; 00260 uint16_t SID, SID_temp,i, count = 0; 00261 uint32_t EID, EID_temp, entry, buf; 00262 uint16_t lowerSID, upperSID; 00263 uint32_t lowerEID, upperEID; 00264 00265 CHECK_PARAM(PARAM_CANAFx(CANAFx)); 00266 CANAFx->AFMR = 0x01; 00267 00268 /***** setup FullCAN Table *****/ 00269 if(AFSection->FullCAN_Sec == NULL) 00270 { 00271 FULLCAN_ENABLE = DISABLE; 00272 } 00273 else 00274 { 00275 FULLCAN_ENABLE = ENABLE; 00276 for(i=0;i<(AFSection->FC_NumEntry);i++) 00277 { 00278 if(count + 1 > 64) 00279 { 00280 return CAN_OBJECTS_FULL_ERROR; 00281 } 00282 ctrl1 = AFSection->FullCAN_Sec->controller; 00283 SID = AFSection->FullCAN_Sec->id_11; 00284 dis1 = AFSection->FullCAN_Sec->disable; 00285 00286 CHECK_PARAM(PARAM_CTRL(ctrl1)); 00287 CHECK_PARAM(PARAM_ID_11(SID)); 00288 CHECK_PARAM(PARAM_MSG_DISABLE(dis1)); 00289 entry = 0x00; //reset entry value 00290 if((CANAF_FullCAN_cnt & 0x00000001)==0) 00291 { 00292 if(count!=0x00) 00293 { 00294 buf = LPC_CANAF_RAM->mask[count-1]; 00295 SID_temp = (buf & 0x000003FF); 00296 if(SID_temp > SID) 00297 { 00298 return CAN_AF_ENTRY_ERROR; 00299 } 00300 } 00301 entry = (ctrl1<<29)|(dis1<<28)|(SID<<16)|(1<<27); 00302 LPC_CANAF_RAM->mask[count] &= 0x0000FFFF; 00303 LPC_CANAF_RAM->mask[count] |= entry; 00304 CANAF_FullCAN_cnt++; 00305 } 00306 else 00307 { 00308 buf = LPC_CANAF_RAM->mask[count]; 00309 SID_temp = (buf & 0x03FF0000)>>16; 00310 if(SID_temp > SID) 00311 { 00312 return CAN_AF_ENTRY_ERROR; 00313 } 00314 entry = (ctrl1<<13)|(dis1<<12)|(SID<<0)|(1<<11); 00315 LPC_CANAF_RAM->mask[count] &= 0xFFFF0000; 00316 LPC_CANAF_RAM->mask[count]|= entry; 00317 count++; 00318 CANAF_FullCAN_cnt++; 00319 } 00320 AFSection->FullCAN_Sec = (FullCAN_Entry *)((uint32_t)(AFSection->FullCAN_Sec)+ sizeof(FullCAN_Entry)); 00321 } 00322 } 00323 00324 /***** Setup Explicit Standard Frame Format Section *****/ 00325 if(AFSection->SFF_Sec != NULL) 00326 { 00327 for(i=0;i<(AFSection->SFF_NumEntry);i++) 00328 { 00329 if(count + 1 > 512) 00330 { 00331 return CAN_OBJECTS_FULL_ERROR; 00332 } 00333 ctrl1 = AFSection->SFF_Sec->controller; 00334 SID = AFSection->SFF_Sec->id_11; 00335 dis1 = AFSection->SFF_Sec->disable; 00336 00337 //check parameter 00338 CHECK_PARAM(PARAM_CTRL(ctrl1)); 00339 CHECK_PARAM(PARAM_ID_11(SID)); 00340 CHECK_PARAM(PARAM_MSG_DISABLE(dis1)); 00341 00342 entry = 0x00; //reset entry value 00343 if((CANAF_std_cnt & 0x00000001)==0) 00344 { 00345 if(CANAF_std_cnt !=0 ) 00346 { 00347 buf = LPC_CANAF_RAM->mask[count-1]; 00348 SID_temp = (buf & 0x00000FFF); 00349 if(SID_temp > SID) 00350 { 00351 return CAN_AF_ENTRY_ERROR; 00352 } 00353 } 00354 entry = (ctrl1<<29)|(dis1<<28)|(SID<<16); 00355 LPC_CANAF_RAM->mask[count] &= 0x0000FFFF; 00356 LPC_CANAF_RAM->mask[count] |= entry; 00357 CANAF_std_cnt++; 00358 } 00359 else 00360 { 00361 buf = LPC_CANAF_RAM->mask[count]; 00362 SID_temp = (buf & 0x0FFF0000)>>16; 00363 if(SID_temp > SID) 00364 { 00365 return CAN_AF_ENTRY_ERROR; 00366 } 00367 entry = (ctrl1<<13)|(dis1<<12)|(SID<<0); 00368 LPC_CANAF_RAM->mask[count] &= 0xFFFF0000; 00369 LPC_CANAF_RAM->mask[count] |= entry; 00370 count++; 00371 CANAF_std_cnt++; 00372 } 00373 AFSection->SFF_Sec = (SFF_Entry *)((uint32_t)(AFSection->SFF_Sec)+ sizeof(SFF_Entry)); 00374 } 00375 } 00376 00377 /***** Setup Group of Standard Frame Format Identifier Section *****/ 00378 if(AFSection->SFF_GPR_Sec != NULL) 00379 { 00380 for(i=0;i<(AFSection->SFF_GPR_NumEntry);i++) 00381 { 00382 if(count + 1 > 512) 00383 { 00384 return CAN_OBJECTS_FULL_ERROR; 00385 } 00386 ctrl1 = AFSection->SFF_GPR_Sec->controller1; 00387 ctrl2 = AFSection->SFF_GPR_Sec->controller2; 00388 dis1 = AFSection->SFF_GPR_Sec->disable1; 00389 dis2 = AFSection->SFF_GPR_Sec->disable2; 00390 lowerSID = AFSection->SFF_GPR_Sec->lowerID; 00391 upperSID = AFSection->SFF_GPR_Sec->upperID; 00392 00393 /* check parameter */ 00394 CHECK_PARAM(PARAM_CTRL(ctrl1)); 00395 CHECK_PARAM(PARAM_CTRL(ctrl2)); 00396 CHECK_PARAM(PARAM_MSG_DISABLE(dis1)); 00397 CHECK_PARAM(PARAM_MSG_DISABLE(dis2)); 00398 CHECK_PARAM(PARAM_ID_11(lowerSID)); 00399 CHECK_PARAM(PARAM_ID_11(upperSID)); 00400 00401 entry = 0x00; 00402 if(CANAF_gstd_cnt!=0) 00403 { 00404 buf = LPC_CANAF_RAM->mask[count-1]; 00405 SID_temp = buf & 0x00000FFF; 00406 if(SID_temp > lowerSID) 00407 { 00408 return CAN_AF_ENTRY_ERROR; 00409 } 00410 } 00411 entry = (ctrl1 << 29)|(dis1 << 28)|(lowerSID << 16)| \ 00412 (ctrl2 << 13)|(dis2 << 12)|(upperSID << 0); 00413 LPC_CANAF_RAM->mask[count] = entry; 00414 CANAF_gstd_cnt++; 00415 count++; 00416 AFSection->SFF_GPR_Sec = (SFF_GPR_Entry *)((uint32_t)(AFSection->SFF_GPR_Sec)+ sizeof(SFF_GPR_Entry)); 00417 } 00418 } 00419 00420 /***** Setup Explicit Extend Frame Format Identifier Section *****/ 00421 if(AFSection->EFF_Sec != NULL) 00422 { 00423 for(i=0;i<(AFSection->EFF_NumEntry);i++) 00424 { 00425 if(count + 1 > 512) 00426 { 00427 return CAN_OBJECTS_FULL_ERROR; 00428 } 00429 EID = AFSection->EFF_Sec->ID_29; 00430 ctrl1 = AFSection->EFF_Sec->controller; 00431 00432 // check parameter 00433 CHECK_PARAM(PARAM_ID_29(EID)); 00434 CHECK_PARAM(PARAM_CTRL(ctrl1)); 00435 00436 entry = 0x00; //reset entry value 00437 if(CANAF_ext_cnt != 0) 00438 { 00439 buf = LPC_CANAF_RAM->mask[count-1]; 00440 EID_temp = buf & 0x0FFFFFFF; 00441 if(EID_temp > EID) 00442 { 00443 return CAN_AF_ENTRY_ERROR; 00444 } 00445 } 00446 entry = (ctrl1 << 29)|(EID << 0); 00447 LPC_CANAF_RAM->mask[count] = entry; 00448 CANAF_ext_cnt ++; 00449 count++; 00450 AFSection->EFF_Sec = (EFF_Entry *)((uint32_t)(AFSection->EFF_Sec)+ sizeof(EFF_Entry)); 00451 } 00452 } 00453 00454 /***** Setup Group of Extended Frame Format Identifier Section *****/ 00455 if(AFSection->EFF_GPR_Sec != NULL) 00456 { 00457 for(i=0;i<(AFSection->EFF_GPR_NumEntry);i++) 00458 { 00459 if(count + 2 > 512) 00460 { 00461 return CAN_OBJECTS_FULL_ERROR; 00462 } 00463 ctrl1 = AFSection->EFF_GPR_Sec->controller1; 00464 ctrl2 = AFSection->EFF_GPR_Sec->controller2; 00465 lowerEID = AFSection->EFF_GPR_Sec->lowerEID; 00466 upperEID = AFSection->EFF_GPR_Sec->upperEID; 00467 00468 //check parameter 00469 CHECK_PARAM(PARAM_CTRL(ctrl1)); 00470 CHECK_PARAM(PARAM_CTRL(ctrl2)); 00471 CHECK_PARAM(PARAM_ID_29(lowerEID)); 00472 CHECK_PARAM(PARAM_ID_29(upperEID)); 00473 00474 entry = 0x00; 00475 if(CANAF_gext_cnt != 0) 00476 { 00477 buf = LPC_CANAF_RAM->mask[count-1]; 00478 EID_temp = buf & 0x0FFFFFFF; 00479 if(EID_temp > lowerEID) 00480 { 00481 return CAN_AF_ENTRY_ERROR; 00482 } 00483 } 00484 entry = (ctrl1 << 29)|(lowerEID << 0); 00485 LPC_CANAF_RAM->mask[count++] = entry; 00486 entry = (ctrl2 << 29)|(upperEID << 0); 00487 LPC_CANAF_RAM->mask[count++] = entry; 00488 CANAF_gext_cnt++; 00489 AFSection->EFF_GPR_Sec = (EFF_GPR_Entry *)((uint32_t)(AFSection->EFF_GPR_Sec)+ sizeof(EFF_GPR_Entry)); 00490 } 00491 } 00492 //update address values 00493 LPC_CANAF->SFF_sa = ((CANAF_FullCAN_cnt + 1)>>1)<<2; 00494 LPC_CANAF->SFF_GRP_sa = LPC_CANAF->SFF_sa + (((CANAF_std_cnt+1)>>1)<< 2); 00495 LPC_CANAF->EFF_sa = LPC_CANAF->SFF_GRP_sa + (CANAF_gstd_cnt << 2); 00496 LPC_CANAF->EFF_GRP_sa = LPC_CANAF->EFF_sa + (CANAF_ext_cnt << 2); 00497 LPC_CANAF->ENDofTable = LPC_CANAF->EFF_GRP_sa + (CANAF_gext_cnt << 3); 00498 00499 if(FULLCAN_ENABLE == DISABLE) 00500 { 00501 LPC_CANAF->AFMR = 0x00; // Normal mode 00502 } 00503 else 00504 { 00505 LPC_CANAF->AFMR = 0x04; 00506 } 00507 return CAN_OK; 00508 } 00509 /********************************************************************/ 00523 CAN_ERROR CAN_LoadExplicitEntry(LPC_CAN_TypeDef* CANx, uint32_t id, CAN_ID_FORMAT_Type format) 00524 { 00525 uint32_t tmp0 = 0; 00526 uint32_t buf0=0, buf1=0; 00527 int16_t cnt1=0, cnt2=0, bound1=0, total=0; 00528 00529 00530 CHECK_PARAM(PARAM_CANx(CANx)); 00531 CHECK_PARAM(PARAM_ID_FORMAT(format)); 00532 00533 if (CANx == LPC_CAN1) 00534 { 00535 tmp0 = 0; 00536 } 00537 else if (CANx == LPC_CAN2) 00538 { 00539 tmp0 = 1; 00540 } 00541 00542 /* Acceptance Filter Memory full - return */ 00543 total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+ \ 00544 CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1); 00545 if (total >= 512){ //don't have enough space 00546 return CAN_OBJECTS_FULL_ERROR; 00547 } 00548 00549 /* Setup Acceptance Filter Configuration 00550 Acceptance Filter Mode Register = Off */ 00551 LPC_CANAF->AFMR = 0x00000001; 00552 00553 /*********** Add Explicit Standard Identifier Frame Format entry *********/ 00554 if(format == STD_ID_FORMAT) 00555 { 00556 id &= 0x07FF; 00557 id |= (tmp0 << 13); /* Add controller number */ 00558 /* Move all remaining sections one place up 00559 if new entry will increase FullCAN list */ 00560 if ((CANAF_std_cnt & 0x0001) == 0) 00561 { 00562 cnt1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1); 00563 bound1 = total - cnt1; 00564 buf0 = LPC_CANAF_RAM->mask[cnt1]; 00565 while(bound1--) 00566 { 00567 cnt1++; 00568 buf1 = LPC_CANAF_RAM->mask[cnt1]; 00569 LPC_CANAF_RAM->mask[cnt1] = buf0; 00570 buf0 = buf1; 00571 } 00572 } 00573 if (CANAF_std_cnt == 0) 00574 { 00575 cnt2 = (CANAF_FullCAN_cnt + 1)>>1; 00576 /* For entering first ID */ 00577 LPC_CANAF_RAM->mask[cnt2] = 0x0000FFFF | (id << 16); 00578 } 00579 else if (CANAF_std_cnt == 1) 00580 { 00581 cnt2 = (CANAF_FullCAN_cnt + 1)>>1; 00582 /* For entering second ID */ 00583 if ((LPC_CANAF_RAM->mask[cnt2] >> 16) > id) 00584 { 00585 LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] >> 16) | (id << 16); 00586 } 00587 else 00588 { 00589 LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] & 0xFFFF0000) | id; 00590 } 00591 } 00592 else 00593 { 00594 /* Find where to insert new ID */ 00595 cnt1 = (CANAF_FullCAN_cnt+1)>>1; 00596 cnt2 = CANAF_std_cnt; 00597 bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1); 00598 while (cnt1 < bound1) 00599 { 00600 /* Loop through standard existing IDs */ 00601 if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id) 00602 { 00603 cnt2 = cnt1 * 2; 00604 break; 00605 } 00606 00607 if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id) 00608 { 00609 cnt2 = cnt1 * 2 + 1; 00610 break; 00611 } 00612 00613 cnt1++; 00614 } 00615 /* cnt1 = U32 where to insert new ID */ 00616 /* cnt2 = U16 where to insert new ID */ 00617 00618 if (cnt1 == bound1) 00619 { 00620 /* Adding ID as last entry */ 00621 /* Even number of IDs exists */ 00622 if ((CANAF_std_cnt & 0x0001) == 0) 00623 { 00624 LPC_CANAF_RAM->mask[cnt1] = 0x0000FFFF | (id << 16); 00625 } 00626 /* Odd number of IDs exists */ 00627 else 00628 { 00629 LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id; 00630 } 00631 } 00632 else 00633 { 00634 buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */ 00635 if ((cnt2 & 0x0001) == 0) 00636 { 00637 /* Insert new mask to even address*/ 00638 buf1 = (id << 16) | (buf0 >> 16); 00639 } 00640 else 00641 { 00642 /* Insert new mask to odd address */ 00643 buf1 = (buf0 & 0xFFFF0000) | id; 00644 } 00645 LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */ 00646 bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1)-1; 00647 /* Move all remaining standard mask entries one place up */ 00648 while (cnt1 < bound1) 00649 { 00650 cnt1++; 00651 buf1 = LPC_CANAF_RAM->mask[cnt1]; 00652 LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16); 00653 buf0 = buf1; 00654 } 00655 00656 if ((CANAF_std_cnt & 0x0001) == 0) 00657 { 00658 /* Even number of IDs exists */ 00659 LPC_CANAF_RAM->mask[cnt1+1] = (buf0 <<16) |(0x0000FFFF); 00660 } 00661 } 00662 } 00663 CANAF_std_cnt++; 00664 //update address values 00665 LPC_CANAF->SFF_GRP_sa +=0x04 ; 00666 LPC_CANAF->EFF_sa +=0x04 ; 00667 LPC_CANAF->EFF_GRP_sa +=0x04; 00668 LPC_CANAF->ENDofTable +=0x04; 00669 } 00670 00671 /*********** Add Explicit Extended Identifier Frame Format entry *********/ 00672 else 00673 { 00674 /* Add controller number */ 00675 id |= (tmp0) << 29; 00676 00677 cnt1 = ((CANAF_FullCAN_cnt+1)>>1)+(((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt); 00678 cnt2 = 0; 00679 while (cnt2 < CANAF_ext_cnt) 00680 { 00681 /* Loop through extended existing masks*/ 00682 if (LPC_CANAF_RAM->mask[cnt1] > id) 00683 { 00684 break; 00685 } 00686 cnt1++;/* cnt1 = U32 where to insert new mask */ 00687 cnt2++; 00688 } 00689 00690 buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */ 00691 LPC_CANAF_RAM->mask[cnt1] = id; /* Insert mask */ 00692 00693 CANAF_ext_cnt++; 00694 00695 bound1 = total; 00696 /* Move all remaining extended mask entries one place up*/ 00697 while (cnt2 < bound1) 00698 { 00699 cnt1++; 00700 cnt2++; 00701 buf1 = LPC_CANAF_RAM->mask[cnt1]; 00702 LPC_CANAF_RAM->mask[cnt1] = buf0; 00703 buf0 = buf1; 00704 } 00705 /* update address values */ 00706 LPC_CANAF->EFF_GRP_sa += 4; 00707 LPC_CANAF->ENDofTable += 4; 00708 } 00709 if(CANAF_FullCAN_cnt == 0) //not use FullCAN mode 00710 { 00711 LPC_CANAF->AFMR = 0x00;//not use FullCAN mode 00712 } 00713 else 00714 { 00715 LPC_CANAF->AFMR = 0x04; 00716 } 00717 00718 return CAN_OK; 00719 } 00720 00721 /********************************************************************/ 00732 CAN_ERROR CAN_LoadFullCANEntry (LPC_CAN_TypeDef* CANx, uint16_t id) 00733 { 00734 uint32_t ctrl0 = 0; 00735 uint32_t buf0=0, buf1=0, buf2=0; 00736 uint32_t tmp0=0, tmp1=0, tmp2=0; 00737 int16_t cnt1=0, cnt2=0, bound1=0, total=0; 00738 00739 CHECK_PARAM(PARAM_CANx(CANx)); 00740 00741 if (CANx == LPC_CAN1) 00742 { 00743 ctrl0 = 0; 00744 } 00745 else if (CANx == LPC_CAN2) 00746 { 00747 ctrl0 = 1; 00748 } 00749 00750 /* Acceptance Filter Memory full - return */ 00751 total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+ \ 00752 CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1); 00753 //don't have enough space for this fullCAN Entry and its Object(3*32 bytes) 00754 if ((total >=508)||(CANAF_FullCAN_cnt>=64)){ 00755 return CAN_OBJECTS_FULL_ERROR; 00756 } 00757 /* Setup Acceptance Filter Configuration 00758 Acceptance Filter Mode Register = Off */ 00759 LPC_CANAF->AFMR = 0x00000001; 00760 00761 /* Add mask for standard identifiers */ 00762 id &= 0x07FF; 00763 id |= (ctrl0 << 13) | (1 << 11); /* Add controller number */ 00764 // total = ((CANAF_std_cnt + 1) >> 1)+ CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1); 00765 /* Move all remaining sections one place up 00766 if new entry will increase FullCAN list */ 00767 if (((CANAF_FullCAN_cnt & 0x0001) == 0)&&(total!=0)) 00768 { 00769 //then remove remaining section 00770 cnt1 = (CANAF_FullCAN_cnt >> 1); 00771 bound1 = total; 00772 buf0 = LPC_CANAF_RAM->mask[cnt1]; 00773 00774 while (bound1--) 00775 { 00776 cnt1++; 00777 buf1 = LPC_CANAF_RAM->mask[cnt1]; 00778 LPC_CANAF_RAM->mask[cnt1] = buf0; 00779 buf0 = buf1; 00780 } 00781 } 00782 if (CANAF_FullCAN_cnt == 0) 00783 { 00784 /* For entering first ID */ 00785 LPC_CANAF_RAM->mask[0] = 0x0000FFFF | (id << 16); 00786 } 00787 else if (CANAF_FullCAN_cnt == 1) 00788 { 00789 /* For entering second ID */ 00790 if ((LPC_CANAF_RAM->mask[0] >> 16) > id) 00791 { 00792 LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] >> 16) | (id << 16); 00793 } 00794 else 00795 { 00796 LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] & 0xFFFF0000) | id; 00797 } 00798 } 00799 else 00800 { 00801 /* Find where to insert new ID */ 00802 cnt1 = 0; 00803 cnt2 = CANAF_FullCAN_cnt; 00804 bound1 = (CANAF_FullCAN_cnt - 1) >> 1; 00805 while (cnt1 <= bound1) 00806 { 00807 /* Loop through standard existing IDs */ 00808 if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id) 00809 { 00810 cnt2 = cnt1 * 2; 00811 break; 00812 } 00813 00814 if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id) 00815 { 00816 cnt2 = cnt1 * 2 + 1; 00817 break; 00818 } 00819 00820 cnt1++; 00821 } 00822 /* cnt1 = U32 where to insert new ID */ 00823 /* cnt2 = U16 where to insert new ID */ 00824 00825 if (cnt1 > bound1) 00826 { 00827 /* Adding ID as last entry */ 00828 /* Even number of IDs exists */ 00829 if ((CANAF_FullCAN_cnt & 0x0001) == 0) 00830 { 00831 LPC_CANAF_RAM->mask[cnt1] = 0x0000FFFF | (id << 16); 00832 } 00833 /* Odd number of IDs exists */ 00834 else 00835 { 00836 LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id; 00837 } 00838 } 00839 else 00840 { 00841 buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */ 00842 if ((cnt2 & 0x0001) == 0) 00843 { 00844 /* Insert new mask to even address*/ 00845 buf1 = (id << 16) | (buf0 >> 16); 00846 } 00847 else 00848 { 00849 /* Insert new mask to odd address */ 00850 buf1 = (buf0 & 0xFFFF0000) | id; 00851 } 00852 LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */ 00853 bound1 = CANAF_FullCAN_cnt >> 1; 00854 /* Move all remaining standard mask entries one place up */ 00855 while (cnt1 < bound1) 00856 { 00857 cnt1++; 00858 buf1 = LPC_CANAF_RAM->mask[cnt1]; 00859 LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16); 00860 buf0 = buf1; 00861 } 00862 00863 if ((CANAF_FullCAN_cnt & 0x0001) == 0) 00864 { 00865 /* Even number of IDs exists */ 00866 LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) 00867 | (0x0000FFFF); 00868 } 00869 } 00870 } 00871 //restruct FulCAN Object Section 00872 bound1 = CANAF_FullCAN_cnt - cnt2; 00873 cnt1 = total - (CANAF_FullCAN_cnt)*3 + cnt2*3 + 1; 00874 buf0 = LPC_CANAF_RAM->mask[cnt1]; 00875 buf1 = LPC_CANAF_RAM->mask[cnt1+1]; 00876 buf2 = LPC_CANAF_RAM->mask[cnt1+2]; 00877 LPC_CANAF_RAM->mask[cnt1]=LPC_CANAF_RAM->mask[cnt1+1]= LPC_CANAF_RAM->mask[cnt1+2]=0x00; 00878 cnt1+=3; 00879 while(bound1--) 00880 { 00881 tmp0 = LPC_CANAF_RAM->mask[cnt1]; 00882 tmp1 = LPC_CANAF_RAM->mask[cnt1+1]; 00883 tmp2 = LPC_CANAF_RAM->mask[cnt1+2]; 00884 LPC_CANAF_RAM->mask[cnt1]= buf0; 00885 LPC_CANAF_RAM->mask[cnt1+1]= buf1; 00886 LPC_CANAF_RAM->mask[cnt1+2]= buf2; 00887 buf0 = tmp0; 00888 buf1 = tmp1; 00889 buf2 = tmp2; 00890 cnt1+=3; 00891 } 00892 CANAF_FullCAN_cnt++; 00893 //update address values 00894 LPC_CANAF->SFF_sa +=0x04; 00895 LPC_CANAF->SFF_GRP_sa +=0x04 ; 00896 LPC_CANAF->EFF_sa +=0x04 ; 00897 LPC_CANAF->EFF_GRP_sa +=0x04; 00898 LPC_CANAF->ENDofTable +=0x04; 00899 00900 LPC_CANAF->AFMR = 0x04; 00901 return CAN_OK; 00902 } 00903 00904 /********************************************************************/ 00918 CAN_ERROR CAN_LoadGroupEntry(LPC_CAN_TypeDef* CANx, uint32_t lowerID, \ 00919 uint32_t upperID, CAN_ID_FORMAT_Type format) 00920 { 00921 uint16_t tmp = 0; 00922 uint32_t buf0, buf1, entry1, entry2, LID,UID; 00923 int16_t cnt1, bound1, total; 00924 00925 CHECK_PARAM(PARAM_CANx(CANx)); 00926 CHECK_PARAM(PARAM_ID_FORMAT(format)); 00927 00928 if(lowerID > upperID) return CAN_CONFLICT_ID_ERROR; 00929 if(CANx == LPC_CAN1) 00930 { 00931 tmp = 0; 00932 } 00933 else 00934 { 00935 tmp = 1; 00936 } 00937 00938 total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+ \ 00939 CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1); 00940 00941 /* Setup Acceptance Filter Configuration 00942 Acceptance Filter Mode Register = Off */ 00943 LPC_CANAF->AFMR = 0x00000001; 00944 00945 /*********Add Group of Standard Identifier Frame Format************/ 00946 if(format == STD_ID_FORMAT) 00947 { 00948 if ((total >= 512)){//don't have enough space 00949 return CAN_OBJECTS_FULL_ERROR; 00950 } 00951 lowerID &=0x7FF; //mask ID 00952 upperID &=0x7FF; 00953 entry1 = (tmp << 29)|(lowerID << 16)|(tmp << 13)|(upperID << 0); 00954 cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1); 00955 00956 //if this is the first Group standard ID entry 00957 if(CANAF_gstd_cnt == 0) 00958 { 00959 LPC_CANAF_RAM->mask[cnt1] = entry1; 00960 } 00961 else 00962 { 00963 //find the position to add new Group entry 00964 bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt; 00965 while(cnt1 < bound1) 00966 { 00967 buf0 = LPC_CANAF_RAM->mask[cnt1]; 00968 LID = (buf0 >> 16)&0x7FF; 00969 UID = buf0 & 0x7FF; 00970 if (upperID <= LID) 00971 { 00972 //add new entry before this entry 00973 LPC_CANAF_RAM->mask[cnt1] = entry1; 00974 break; 00975 } 00976 else if (lowerID >= UID) 00977 { 00978 //load next entry to compare 00979 cnt1 ++; 00980 } 00981 else 00982 return CAN_CONFLICT_ID_ERROR; 00983 } 00984 if(cnt1 >= bound1) 00985 { 00986 //add new entry at the last position in this list 00987 buf0 = LPC_CANAF_RAM->mask[cnt1]; 00988 LPC_CANAF_RAM->mask[cnt1] = entry1; 00989 } 00990 00991 //remove all remaining entry of this section one place up 00992 bound1 = total - cnt1; 00993 while(bound1--) 00994 { 00995 cnt1++; 00996 buf1 = LPC_CANAF_RAM->mask[cnt1]; 00997 LPC_CANAF_RAM->mask[cnt1] = buf0; 00998 buf0 = buf1; 00999 } 01000 } 01001 CANAF_gstd_cnt++; 01002 //update address values 01003 LPC_CANAF->EFF_sa +=0x04 ; 01004 LPC_CANAF->EFF_GRP_sa +=0x04; 01005 LPC_CANAF->ENDofTable +=0x04; 01006 } 01007 01008 01009 /*********Add Group of Extended Identifier Frame Format************/ 01010 else 01011 { 01012 if ((total >= 511)){//don't have enough space 01013 return CAN_OBJECTS_FULL_ERROR; 01014 } 01015 lowerID &= 0x1FFFFFFF; //mask ID 01016 upperID &= 0x1FFFFFFF; 01017 entry1 = (tmp << 29)|(lowerID << 0); 01018 entry2 = (tmp << 29)|(upperID << 0); 01019 01020 cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt + CANAF_ext_cnt; 01021 //if this is the first Group standard ID entry 01022 if(CANAF_gext_cnt == 0) 01023 { 01024 LPC_CANAF_RAM->mask[cnt1] = entry1; 01025 LPC_CANAF_RAM->mask[cnt1+1] = entry2; 01026 } 01027 else 01028 { 01029 //find the position to add new Group entry 01030 bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt \ 01031 + CANAF_ext_cnt + (CANAF_gext_cnt<<1); 01032 while(cnt1 < bound1) 01033 { 01034 buf0 = LPC_CANAF_RAM->mask[cnt1]; 01035 buf1 = LPC_CANAF_RAM->mask[cnt1+1]; 01036 LID = buf0 & 0x1FFFFFFF; //mask ID 01037 UID = buf1 & 0x1FFFFFFF; 01038 if (upperID <= LID) 01039 { 01040 //add new entry before this entry 01041 LPC_CANAF_RAM->mask[cnt1] = entry1; 01042 LPC_CANAF_RAM->mask[++cnt1] = entry2; 01043 break; 01044 } 01045 else if (lowerID >= UID) 01046 { 01047 //load next entry to compare 01048 cnt1 +=2; 01049 } 01050 else 01051 return CAN_CONFLICT_ID_ERROR; 01052 } 01053 if(cnt1 >= bound1) 01054 { 01055 //add new entry at the last position in this list 01056 buf0 = LPC_CANAF_RAM->mask[cnt1]; 01057 buf1 = LPC_CANAF_RAM->mask[cnt1+1]; 01058 LPC_CANAF_RAM->mask[cnt1] = entry1; 01059 LPC_CANAF_RAM->mask[++cnt1] = entry2; 01060 } 01061 //remove all remaining entry of this section two place up 01062 bound1 = total - cnt1 + 1; 01063 cnt1++; 01064 while(bound1>0) 01065 { 01066 entry1 = LPC_CANAF_RAM->mask[cnt1]; 01067 entry2 = LPC_CANAF_RAM->mask[cnt1+1]; 01068 LPC_CANAF_RAM->mask[cnt1] = buf0; 01069 LPC_CANAF_RAM->mask[cnt1+1] = buf1; 01070 buf0 = entry1; 01071 buf1 = entry2; 01072 cnt1 +=2; 01073 bound1 -=2; 01074 } 01075 } 01076 CANAF_gext_cnt++; 01077 //update address values 01078 LPC_CANAF->ENDofTable +=0x08; 01079 } 01080 LPC_CANAF->AFMR = 0x04; 01081 return CAN_OK; 01082 } 01083 01084 /********************************************************************/ 01098 CAN_ERROR CAN_RemoveEntry(AFLUT_ENTRY_Type EntryType, uint16_t position) 01099 { 01100 uint16_t cnt, bound, total; 01101 uint32_t buf0, buf1; 01102 CHECK_PARAM(PARAM_AFLUT_ENTRY_TYPE(EntryType)); 01103 CHECK_PARAM(PARAM_POSITION(position)); 01104 01105 /* Setup Acceptance Filter Configuration 01106 Acceptance Filter Mode Register = Off */ 01107 LPC_CANAF->AFMR = 0x00000001; 01108 total = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt + 1) >> 1) + \ 01109 CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1); 01110 01111 01112 /************** Remove FullCAN Entry *************/ 01113 if(EntryType == FULLCAN_ENTRY) 01114 { 01115 if((CANAF_FullCAN_cnt==0)||(position >= CANAF_FullCAN_cnt)) 01116 { 01117 return CAN_ENTRY_NOT_EXIT_ERROR; 01118 } 01119 else 01120 { 01121 cnt = position >> 1; 01122 buf0 = LPC_CANAF_RAM->mask[cnt]; 01123 bound = (CANAF_FullCAN_cnt - position -1)>>1; 01124 if((position & 0x0001) == 0) //event position 01125 { 01126 while(bound--) 01127 { 01128 //remove all remaining FullCAN entry one place down 01129 buf1 = LPC_CANAF_RAM->mask[cnt+1]; 01130 LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16); 01131 buf0 = buf1; 01132 cnt++; 01133 } 01134 } 01135 else //odd position 01136 { 01137 while(bound--) 01138 { 01139 //remove all remaining FullCAN entry one place down 01140 buf1 = LPC_CANAF_RAM->mask[cnt+1]; 01141 LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000)|(buf1 >> 16); 01142 LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+1] << 16; 01143 buf0 = buf1<<16; 01144 cnt++; 01145 } 01146 } 01147 if((CANAF_FullCAN_cnt & 0x0001) == 0) 01148 { 01149 if((position & 0x0001)==0) 01150 LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF); 01151 else 01152 LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF; 01153 } 01154 else 01155 { 01156 //remove all remaining section one place down 01157 cnt = (CANAF_FullCAN_cnt + 1)>>1; 01158 bound = total + CANAF_FullCAN_cnt * 3; 01159 while(bound>cnt) 01160 { 01161 LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt]; 01162 cnt++; 01163 } 01164 LPC_CANAF_RAM->mask[cnt-1]=0x00; 01165 //update address values 01166 LPC_CANAF->SFF_sa -=0x04; 01167 LPC_CANAF->SFF_GRP_sa -=0x04 ; 01168 LPC_CANAF->EFF_sa -=0x04 ; 01169 LPC_CANAF->EFF_GRP_sa -=0x04; 01170 LPC_CANAF->ENDofTable -=0x04; 01171 } 01172 CANAF_FullCAN_cnt--; 01173 01174 //delete its FullCAN Object in the FullCAN Object section 01175 //remove all remaining FullCAN Object three place down 01176 cnt = total + position * 3; 01177 bound = (CANAF_FullCAN_cnt - position + 1) * 3; 01178 01179 while(bound) 01180 { 01181 LPC_CANAF_RAM->mask[cnt]=LPC_CANAF_RAM->mask[cnt+3];; 01182 LPC_CANAF_RAM->mask[cnt+1]=LPC_CANAF_RAM->mask[cnt+4]; 01183 LPC_CANAF_RAM->mask[cnt+2]=LPC_CANAF_RAM->mask[cnt+5]; 01184 bound -=3; 01185 cnt +=3; 01186 } 01187 } 01188 } 01189 01190 /************** Remove Explicit Standard ID Entry *************/ 01191 else if(EntryType == EXPLICIT_STANDARD_ENTRY) 01192 { 01193 if((CANAF_std_cnt==0)||(position >= CANAF_std_cnt)) 01194 { 01195 return CAN_ENTRY_NOT_EXIT_ERROR; 01196 } 01197 else 01198 { 01199 cnt = ((CANAF_FullCAN_cnt+1)>>1)+ (position >> 1); 01200 buf0 = LPC_CANAF_RAM->mask[cnt]; 01201 bound = (CANAF_std_cnt - position - 1)>>1; 01202 if((position & 0x0001) == 0) //event position 01203 { 01204 while(bound--) 01205 { 01206 //remove all remaining FullCAN entry one place down 01207 buf1 = LPC_CANAF_RAM->mask[cnt+1]; 01208 LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16); 01209 buf0 = buf1; 01210 cnt++; 01211 } 01212 } 01213 else //odd position 01214 { 01215 while(bound--) 01216 { 01217 //remove all remaining FullCAN entry one place down 01218 buf1 = LPC_CANAF_RAM->mask[cnt+1]; 01219 LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000)|(buf1 >> 16); 01220 LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+1] << 16; 01221 buf0 = buf1<<16; 01222 cnt++; 01223 } 01224 } 01225 if((CANAF_std_cnt & 0x0001) == 0) 01226 { 01227 if((position & 0x0001)==0) 01228 LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF); 01229 else 01230 LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF; 01231 } 01232 else 01233 { 01234 //remove all remaining section one place down 01235 cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1); 01236 bound = total + CANAF_FullCAN_cnt * 3; 01237 while(bound>cnt) 01238 { 01239 LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt]; 01240 cnt++; 01241 } 01242 LPC_CANAF_RAM->mask[cnt-1]=0x00; 01243 //update address value 01244 LPC_CANAF->SFF_GRP_sa -=0x04 ; 01245 LPC_CANAF->EFF_sa -=0x04 ; 01246 LPC_CANAF->EFF_GRP_sa -=0x04; 01247 LPC_CANAF->ENDofTable -=0x04; 01248 } 01249 CANAF_std_cnt--; 01250 } 01251 } 01252 01253 /************** Remove Group of Standard ID Entry *************/ 01254 else if(EntryType == GROUP_STANDARD_ENTRY) 01255 { 01256 if((CANAF_gstd_cnt==0)||(position >= CANAF_gstd_cnt)) 01257 { 01258 return CAN_ENTRY_NOT_EXIT_ERROR; 01259 } 01260 else 01261 { 01262 cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1)+ position + 1; 01263 bound = total + CANAF_FullCAN_cnt * 3; 01264 while (cnt<bound) 01265 { 01266 LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt]; 01267 cnt++; 01268 } 01269 LPC_CANAF_RAM->mask[cnt-1]=0x00; 01270 } 01271 CANAF_gstd_cnt--; 01272 //update address value 01273 LPC_CANAF->EFF_sa -=0x04; 01274 LPC_CANAF->EFF_GRP_sa -=0x04; 01275 LPC_CANAF->ENDofTable -=0x04; 01276 } 01277 01278 /************** Remove Explicit Extended ID Entry *************/ 01279 else if(EntryType == EXPLICIT_EXTEND_ENTRY) 01280 { 01281 if((CANAF_ext_cnt==0)||(position >= CANAF_ext_cnt)) 01282 { 01283 return CAN_ENTRY_NOT_EXIT_ERROR; 01284 } 01285 else 01286 { 01287 cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1)+ CANAF_gstd_cnt + position + 1; 01288 bound = total + CANAF_FullCAN_cnt * 3; 01289 while (cnt<bound) 01290 { 01291 LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt]; 01292 cnt++; 01293 } 01294 LPC_CANAF_RAM->mask[cnt-1]=0x00; 01295 } 01296 CANAF_ext_cnt--; 01297 LPC_CANAF->EFF_GRP_sa -=0x04; 01298 LPC_CANAF->ENDofTable -=0x04; 01299 } 01300 01301 /************** Remove Group of Extended ID Entry *************/ 01302 else 01303 { 01304 if((CANAF_gext_cnt==0)||(position >= CANAF_gext_cnt)) 01305 { 01306 return CAN_ENTRY_NOT_EXIT_ERROR; 01307 } 01308 else 01309 { 01310 cnt = total - (CANAF_gext_cnt<<1) + (position<<1); 01311 bound = total + CANAF_FullCAN_cnt * 3; 01312 while (cnt<bound) 01313 { 01314 //remove all remaining entry two place up 01315 LPC_CANAF_RAM->mask[cnt] = LPC_CANAF_RAM->mask[cnt+2]; 01316 LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+3]; 01317 cnt+=2; 01318 } 01319 } 01320 CANAF_gext_cnt--; 01321 LPC_CANAF->ENDofTable -=0x08; 01322 } 01323 LPC_CANAF->AFMR = 0x04; 01324 return CAN_OK; 01325 } 01326 01327 /********************************************************************/ 01338 Status CAN_SendMsg (LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg) 01339 { 01340 uint32_t data; 01341 CHECK_PARAM(PARAM_CANx(CANx)); 01342 CHECK_PARAM(PARAM_ID_FORMAT(CAN_Msg->format)); 01343 if(CAN_Msg->format==STD_ID_FORMAT) 01344 { 01345 CHECK_PARAM(PARAM_ID_11(CAN_Msg->id)); 01346 } 01347 else 01348 { 01349 CHECK_PARAM(PARAM_ID_29(CAN_Msg->id)); 01350 } 01351 CHECK_PARAM(PARAM_DLC(CAN_Msg->len)); 01352 CHECK_PARAM(PARAM_FRAME_TYPE(CAN_Msg->type)); 01353 01354 //Check status of Transmit Buffer 1 01355 if ((CANx->SR & 0x00000004)>>2) 01356 { 01357 /* Transmit Channel 1 is available */ 01358 /* Write frame informations and frame data into its CANxTFI1, 01359 * CANxTID1, CANxTDA1, CANxTDB1 register */ 01360 CANx->TFI1 &= ~0x000F000; 01361 CANx->TFI1 |= (CAN_Msg->len)<<16; 01362 if(CAN_Msg->type == REMOTE_FRAME) 01363 { 01364 CANx->TFI1 |= (1<<30); //set bit RTR 01365 } 01366 else 01367 { 01368 CANx->TFI1 &= ~(1<<30); 01369 } 01370 if(CAN_Msg->format == EXT_ID_FORMAT) 01371 { 01372 CANx->TFI1 |= (1<<31); //set bit FF 01373 } 01374 else 01375 { 01376 CANx->TFI1 &= ~(1<<31); 01377 } 01378 01379 /* Write CAN ID*/ 01380 CANx->TID1 = CAN_Msg->id; 01381 01382 /*Write first 4 data bytes*/ 01383 data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24); 01384 // CANx->TDA1 = *((uint32_t *) &(CAN_Msg->dataA)); 01385 CANx->TDA1 = data; 01386 01387 /*Write second 4 data bytes*/ 01388 data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24); 01389 // CANx->TDB1 = *((uint32_t *) &(CAN_Msg->dataB)); 01390 CANx->TDB1 = data; 01391 01392 /*Write transmission request*/ 01393 CANx->CMR = 0x21; 01394 return SUCCESS; 01395 } 01396 //check status of Transmit Buffer 2 01397 else if((CANx->SR & 0x00000004)>>10) 01398 { 01399 /* Transmit Channel 2 is available */ 01400 /* Write frame informations and frame data into its CANxTFI2, 01401 * CANxTID2, CANxTDA2, CANxTDB2 register */ 01402 CANx->TFI2 &= ~0x000F000; 01403 CANx->TFI2 |= (CAN_Msg->len)<<16; 01404 if(CAN_Msg->type == REMOTE_FRAME) 01405 { 01406 CANx->TFI2 |= (1<<30); //set bit RTR 01407 } 01408 else 01409 { 01410 CANx->TFI2 &= ~(1<<30); 01411 } 01412 if(CAN_Msg->format == EXT_ID_FORMAT) 01413 { 01414 CANx->TFI2 |= (1<<31); //set bit FF 01415 } 01416 else 01417 { 01418 CANx->TFI2 &= ~(1<<31); 01419 } 01420 01421 /* Write CAN ID*/ 01422 CANx->TID2 = CAN_Msg->id; 01423 01424 /*Write first 4 data bytes*/ 01425 data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24); 01426 // CANx->TDA2 = *((uint32_t *) &(CAN_Msg->dataA)); 01427 CANx->TDA2 = data; 01428 01429 /*Write second 4 data bytes*/ 01430 data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24); 01431 // CANx->TDB2 = *((uint32_t *) &(CAN_Msg->dataB)); 01432 CANx->TDB2 = data; 01433 01434 /*Write transmission request*/ 01435 CANx->CMR = 0x41; 01436 return SUCCESS; 01437 } 01438 //check status of Transmit Buffer 3 01439 else if ((CANx->SR & 0x00000004)>>18) 01440 { 01441 /* Transmit Channel 3 is available */ 01442 /* Write frame informations and frame data into its CANxTFI3, 01443 * CANxTID3, CANxTDA3, CANxTDB3 register */ 01444 CANx->TFI3 &= ~0x000F000; 01445 CANx->TFI3 |= (CAN_Msg->len)<<16; 01446 if(CAN_Msg->type == REMOTE_FRAME) 01447 { 01448 CANx->TFI3 |= (1<<30); //set bit RTR 01449 } 01450 else 01451 { 01452 CANx->TFI3 &= ~(1<<30); 01453 } 01454 if(CAN_Msg->format == EXT_ID_FORMAT) 01455 { 01456 CANx->TFI3 |= (1<<31); //set bit FF 01457 } 01458 else 01459 { 01460 CANx->TFI3 &= ~(1<<31); 01461 } 01462 01463 /* Write CAN ID*/ 01464 CANx->TID3 = CAN_Msg->id; 01465 01466 /*Write first 4 data bytes*/ 01467 data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24); 01468 // CANx->TDA3 = *((uint32_t *) &(CAN_Msg->dataA)); 01469 CANx->TDA3 = data; 01470 01471 /*Write second 4 data bytes*/ 01472 data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24); 01473 // CANx->TDB3 = *((uint32_t *) &(CAN_Msg->dataB)); 01474 CANx->TDB3 = data; 01475 01476 /*Write transmission request*/ 01477 CANx->CMR = 0x81; 01478 return SUCCESS; 01479 } 01480 else 01481 { 01482 return ERROR; 01483 } 01484 } 01485 01486 /********************************************************************/ 01497 Status CAN_ReceiveMsg (LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg) 01498 { 01499 uint32_t data; 01500 01501 CHECK_PARAM(PARAM_CANx(CANx)); 01502 01503 //check status of Receive Buffer 01504 if((CANx->SR &0x00000001)) 01505 { 01506 /* Receive message is available */ 01507 /* Read frame informations */ 01508 CAN_Msg->format = (uint8_t)(((CANx->RFS) & 0x80000000)>>31); 01509 CAN_Msg->type = (uint8_t)(((CANx->RFS) & 0x40000000)>>30); 01510 CAN_Msg->len = (uint8_t)(((CANx->RFS) & 0x000F0000)>>16); 01511 01512 01513 /* Read CAN message identifier */ 01514 CAN_Msg->id = CANx->RID; 01515 01516 /* Read the data if received message was DATA FRAME */ 01517 if (CAN_Msg->type == DATA_FRAME) 01518 { 01519 /* Read first 4 data bytes */ 01520 // *((uint32_t *) &CAN_Msg->dataA) = CANx->RDA; 01521 data = CANx->RDA; 01522 *((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF; 01523 *((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00)>>8;; 01524 *((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000)>>16; 01525 *((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000)>>24; 01526 01527 /* Read second 4 data bytes */ 01528 // *((uint32_t *) &CAN_Msg->dataB) = CANx->RDB; 01529 data = CANx->RDB; 01530 *((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF; 01531 *((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00)>>8; 01532 *((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000)>>16; 01533 *((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000)>>24; 01534 01535 /*release receive buffer*/ 01536 CANx->CMR = 0x04; 01537 } 01538 else 01539 { 01540 /* Received Frame is a Remote Frame, not have data, we just receive 01541 * message information only */ 01542 return SUCCESS; 01543 } 01544 } 01545 else 01546 { 01547 // no receive message available 01548 return ERROR; 01549 } 01550 return SUCCESS; 01551 } 01552 01553 /********************************************************************/ 01563 CAN_ERROR FCAN_ReadObj (LPC_CANAF_TypeDef* CANAFx, CAN_MSG_Type *CAN_Msg) 01564 { 01565 uint32_t *pSrc, data; 01566 uint32_t interrut_word, msg_idx, test_bit, head_idx, tail_idx; 01567 01568 CHECK_PARAM(PARAM_CANAFx(CANAFx)); 01569 01570 interrut_word = 0; 01571 01572 if (LPC_CANAF->FCANIC0 != 0) 01573 { 01574 interrut_word = LPC_CANAF->FCANIC0; 01575 head_idx = 0; 01576 tail_idx = 31; 01577 } 01578 else if (LPC_CANAF->FCANIC1 != 0) 01579 { 01580 interrut_word = LPC_CANAF->FCANIC1; 01581 head_idx = 32; 01582 tail_idx = 63; 01583 } 01584 01585 if (interrut_word != 0) 01586 { 01587 /* Detect for interrupt pending */ 01588 msg_idx = 0; 01589 for (msg_idx = head_idx; msg_idx <= tail_idx; msg_idx++) 01590 { 01591 test_bit = interrut_word & 0x1; 01592 interrut_word = interrut_word >> 1; 01593 01594 if (test_bit) 01595 { 01596 pSrc = (uint32_t *) (LPC_CANAF->ENDofTable + LPC_CANAF_RAM_BASE + msg_idx * 12); 01597 01598 /* Has been finished updating the content */ 01599 if ((*pSrc & 0x03000000L) == 0x03000000L) 01600 { 01601 /*clear semaphore*/ 01602 *pSrc &= 0xFCFFFFFF; 01603 01604 /*Set to DatA*/ 01605 pSrc++; 01606 /* Copy to dest buf */ 01607 // *((uint32_t *) &CAN_Msg->dataA) = *pSrc; 01608 data = *pSrc; 01609 *((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF; 01610 *((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00)>>8; 01611 *((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000)>>16; 01612 *((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000)>>24; 01613 01614 /*Set to DatB*/ 01615 pSrc++; 01616 /* Copy to dest buf */ 01617 // *((uint32_t *) &CAN_Msg->dataB) = *pSrc; 01618 data = *pSrc; 01619 *((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF; 01620 *((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00)>>8; 01621 *((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000)>>16; 01622 *((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000)>>24; 01623 /*Back to Dat1*/ 01624 pSrc -= 2; 01625 01626 CAN_Msg->id = *pSrc & 0x7FF; 01627 CAN_Msg->len = (uint8_t) (*pSrc >> 16) & 0x0F; 01628 CAN_Msg->format = 0; //FullCAN Object ID always is 11-bit value 01629 CAN_Msg->type = (uint8_t)(*pSrc >> 30) &0x01; 01630 /*Re-read semaphore*/ 01631 if ((*pSrc & 0x03000000L) == 0) 01632 { 01633 return CAN_OK; 01634 } 01635 } 01636 } 01637 } 01638 } 01639 return CAN_FULL_OBJ_NOT_RCV; 01640 } 01641 /********************************************************************/ 01654 uint32_t CAN_GetCTRLStatus (LPC_CAN_TypeDef* CANx, CAN_CTRL_STS_Type arg) 01655 { 01656 CHECK_PARAM(PARAM_CANx(CANx)); 01657 CHECK_PARAM(PARAM_CTRL_STS_TYPE(arg)); 01658 01659 switch (arg) 01660 { 01661 case CANCTRL_GLOBAL_STS: 01662 return CANx->GSR; 01663 01664 case CANCTRL_INT_CAP: 01665 return CANx->ICR; 01666 01667 case CANCTRL_ERR_WRN: 01668 return CANx->EWL; 01669 01670 default: // CANCTRL_STS 01671 return CANx->SR; 01672 } 01673 } 01674 /********************************************************************/ 01684 uint32_t CAN_GetCRStatus (LPC_CANCR_TypeDef* CANCRx, CAN_CR_STS_Type arg) 01685 { 01686 CHECK_PARAM(PARAM_CANCRx(CANCRx)); 01687 CHECK_PARAM(PARAM_CR_STS_TYPE(arg)); 01688 01689 switch (arg) 01690 { 01691 case CANCR_TX_STS: 01692 return CANCRx->CANTxSR; 01693 01694 case CANCR_RX_STS: 01695 return CANCRx->CANRxSR; 01696 01697 default: // CANCR_MS 01698 return CANCRx->CANMSR; 01699 } 01700 } 01701 /********************************************************************/ 01725 void CAN_IRQCmd (LPC_CAN_TypeDef* CANx, CAN_INT_EN_Type arg, FunctionalState NewState) 01726 { 01727 CHECK_PARAM(PARAM_CANx(CANx)); 01728 CHECK_PARAM(PARAM_INT_EN_TYPE(arg)); 01729 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 01730 01731 if(NewState == ENABLE) 01732 { 01733 if(arg==CANINT_FCE) 01734 { 01735 LPC_CANAF->AFMR = 0x01; 01736 LPC_CANAF->FCANIE = 0x01; 01737 LPC_CANAF->AFMR = 0x04; 01738 } 01739 else 01740 CANx->IER |= (1 << arg); 01741 } 01742 else 01743 { 01744 if(arg==CANINT_FCE){ 01745 LPC_CANAF->AFMR = 0x01; 01746 LPC_CANAF->FCANIE = 0x01; 01747 LPC_CANAF->AFMR = 0x00; 01748 } 01749 else 01750 CANx->IER &= ~(1 << arg); 01751 } 01752 } 01753 /*********************************************************************/ 01771 void CAN_SetupCBS(CAN_INT_EN_Type arg,fnCANCbs_Type* pnCANCbs) 01772 { 01773 CHECK_PARAM(PARAM_INT_EN_TYPE(arg)); 01774 _apfnCANCbs[arg] = pnCANCbs; 01775 } 01776 /********************************************************************/ 01786 void CAN_SetAFMode (LPC_CANAF_TypeDef* CANAFx, CAN_AFMODE_Type AFMode) 01787 { 01788 CHECK_PARAM(PARAM_CANAFx(CANAFx)); 01789 CHECK_PARAM(PARAM_AFMODE_TYPE(AFMode)); 01790 01791 switch(AFMode) 01792 { 01793 case CAN_Normal: 01794 CANAFx->AFMR = 0x00; 01795 break; 01796 case CAN_AccOff: 01797 CANAFx->AFMR = 0x01; 01798 break; 01799 case CAN_AccBP: 01800 CANAFx->AFMR = 0x02; 01801 break; 01802 case CAN_eFCAN: 01803 CANAFx->AFMR = 0x04; 01804 break; 01805 } 01806 } 01807 01808 /********************************************************************/ 01827 void CAN_ModeConfig(LPC_CAN_TypeDef* CANx, CAN_MODE_Type mode, FunctionalState NewState) 01828 { 01829 CHECK_PARAM(PARAM_CANx(CANx)); 01830 CHECK_PARAM(PARAM_MODE_TYPE(mode)); 01831 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 01832 01833 switch(mode) 01834 { 01835 case CAN_OPERATING_MODE: 01836 CANx->MOD = 0x00; 01837 break; 01838 case CAN_RESET_MODE: 01839 if(NewState == ENABLE) 01840 CANx->MOD |=CAN_MOD_RM; 01841 else 01842 CANx->MOD &= ~CAN_MOD_RM; 01843 break; 01844 case CAN_LISTENONLY_MODE: 01845 CANx->MOD |=CAN_MOD_RM; 01846 if(NewState == ENABLE) 01847 CANx->MOD |=CAN_MOD_LOM; 01848 else 01849 CANx->MOD &=~CAN_MOD_LOM; 01850 break; 01851 case CAN_SELFTEST_MODE: 01852 CANx->MOD |=CAN_MOD_RM; 01853 if(NewState == ENABLE) 01854 CANx->MOD |=CAN_MOD_STM; 01855 else 01856 CANx->MOD &=~CAN_MOD_STM; 01857 break; 01858 case CAN_TXPRIORITY_MODE: 01859 if(NewState == ENABLE) 01860 CANx->MOD |=CAN_MOD_TPM; 01861 else 01862 CANx->MOD &=~CAN_MOD_TPM; 01863 break; 01864 case CAN_SLEEP_MODE: 01865 if(NewState == ENABLE) 01866 CANx->MOD |=CAN_MOD_SM; 01867 else 01868 CANx->MOD &=~CAN_MOD_SM; 01869 break; 01870 case CAN_RXPOLARITY_MODE: 01871 if(NewState == ENABLE) 01872 CANx->MOD |=CAN_MOD_RPM; 01873 else 01874 CANx->MOD &=~CAN_MOD_RPM; 01875 break; 01876 case CAN_TEST_MODE: 01877 if(NewState == ENABLE) 01878 CANx->MOD |=CAN_MOD_TM; 01879 else 01880 CANx->MOD &=~CAN_MOD_TM; 01881 break; 01882 } 01883 } 01884 /*********************************************************************/ 01891 void CAN_IntHandler(LPC_CAN_TypeDef* CANx) 01892 { 01893 uint8_t t; 01894 //scan interrupt pending 01895 if(LPC_CANAF->FCANIE) 01896 { 01897 _apfnCANCbs[11](); 01898 } 01899 //scan interrupt channels 01900 for(t=0;t<11;t++) 01901 { 01902 if(((CANx->ICR)>>t)&0x01) 01903 { 01904 _apfnCANCbs[t](); 01905 } 01906 } 01907 } 01908 01913 #endif /* _CAN */ 01914 01919 /* --------------------------------- End Of File ------------------------------ */
Generated on Mon Feb 8 10:01:37 2010 for LPC1700CMSIS Standard Peripheral Firmware Library by
