📄 lpc177x_8x_can.c
字号:
* - CAN_ID_EXIT_ERROR: ID exited in table
* - CAN_OK: ID is added into table successfully
*********************************************************************/
CAN_ERROR CAN_LoadExplicitEntry(uint8_t canId, uint32_t id, CAN_ID_FORMAT_Type format)
{
uint32_t buf0 = 0, buf1 = 0;
int16_t cnt1 = 0, cnt2 = 0, bound1 = 0, total = 0;
/* Acceptance Filter Memory full - return */
total =((CANAF_FullCAN_cnt + 1) >> 1) + CANAF_FullCAN_cnt * 3 + ((CANAF_std_cnt + 1) >> 1) \
+ CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt << 1);
if (total >= 512)
{
//don't have enough space
return CAN_OBJECTS_FULL_ERROR;
}
/* Setup Acceptance Filter Configuration
Acceptance Filter Mode Register = Off */
LPC_CANAF->AFMR = 0x00000001;
/*********** Add Explicit Standard Identifier Frame Format entry *********/
if(format == STD_ID_FORMAT)
{
id &= 0x07FF;
id |= canId << 13;/* Add controller number */
/* Move all remaining sections one place up
if new entry will increase FullCAN list */
if ((CANAF_std_cnt & 0x0001) == 0)
{
cnt1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1);
bound1 = total - cnt1;
buf0 = LPC_CANAF_RAM->mask[cnt1];
while(bound1--)
{
cnt1++;
buf1 = LPC_CANAF_RAM->mask[cnt1];
LPC_CANAF_RAM->mask[cnt1] = buf0;
buf0 = buf1;
}
}
if (CANAF_std_cnt == 0)
{
cnt2 = (CANAF_FullCAN_cnt + 1)>>1;
/* For entering first ID */
LPC_CANAF_RAM->mask[cnt2] = 0x0000FFFF | (id << 16);
}
else if (CANAF_std_cnt == 1)
{
cnt2 = (CANAF_FullCAN_cnt + 1) >> 1;
/* For entering second ID */
if (((LPC_CANAF_RAM->mask[cnt2] >> 16)& 0xE7FF) > id)
{
LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] >> 16) | (id << 16);
}
else
{
LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] & 0xFFFF0000) | id;
}
}
else
{
/* Find where to insert new ID */
cnt1 = (CANAF_FullCAN_cnt+1)>>1;
cnt2 = CANAF_std_cnt;
bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1);
while (cnt1 < bound1)
{
/* Loop through standard existing IDs */
if (((LPC_CANAF_RAM->mask[cnt1] >> 16) & 0xE7FF) > id)
{
cnt2 = cnt1 * 2;
break;
}
if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000E7FF) > id)
{
cnt2 = cnt1 * 2 + 1;
break;
}
cnt1++;
}
/* cnt1 = U32 where to insert new ID */
/* cnt2 = U16 where to insert new ID */
if (cnt1 == bound1)
{
/* Adding ID as last entry */
/* Even number of IDs exists */
if ((CANAF_std_cnt & 0x0001) == 0)
{
LPC_CANAF_RAM->mask[cnt1] = 0x0000FFFF | (id << 16);
}
/* Odd number of IDs exists */
else
{
LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
}
}
else
{
buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */
if ((cnt2 & 0x0001) == 0)
{
/* Insert new mask to even address*/
buf1 = (id << 16) | (buf0 >> 16);
}
else
{
/* Insert new mask to odd address */
buf1 = (buf0 & 0xFFFF0000) | id;
}
LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */
bound1 = ((CANAF_FullCAN_cnt + 1) >> 1) + ((CANAF_std_cnt+1) >> 1) - 1;
/* Move all remaining standard mask entries one place up */
while (cnt1 < bound1)
{
cnt1++;
buf1 = LPC_CANAF_RAM->mask[cnt1];
LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
buf0 = buf1;
}
if ((CANAF_std_cnt & 0x0001) == 0)
{
/* Even number of IDs exists */
LPC_CANAF_RAM->mask[cnt1+1] = (buf0 <<16) |(0x0000FFFF);
}
}
}
CANAF_std_cnt++;
//update address values
LPC_CANAF->SFF_GRP_sa += 0x04 ;
LPC_CANAF->EFF_sa += 0x04 ;
LPC_CANAF->EFF_GRP_sa += 0x04;
LPC_CANAF->ENDofTable += 0x04;
}
/*********** Add Explicit Extended Identifier Frame Format entry *********/
else
{
/* Add controller number */
id |= canId << 29;
cnt1 = ((CANAF_FullCAN_cnt+1) >> 1) + (((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt);
cnt2 = 0;
while (cnt2 < CANAF_ext_cnt)
{
/* Loop through extended existing masks*/
if (LPC_CANAF_RAM->mask[cnt1] > id)
{
break;
}
cnt1++;/* cnt1 = U32 where to insert new mask */
cnt2++;
}
buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */
LPC_CANAF_RAM->mask[cnt1] = id; /* Insert mask */
CANAF_ext_cnt++;
bound1 = total;
/* Move all remaining extended mask entries one place up*/
while (cnt2 < bound1)
{
cnt1++;
cnt2++;
buf1 = LPC_CANAF_RAM->mask[cnt1];
LPC_CANAF_RAM->mask[cnt1] = buf0;
buf0 = buf1;
}
/* update address values */
LPC_CANAF->EFF_GRP_sa += 4;
LPC_CANAF->ENDofTable += 4;
}
if(CANAF_FullCAN_cnt == 0) //not use FullCAN mode
{
LPC_CANAF->AFMR = 0x00;//not use FullCAN mode
}
else
{
LPC_CANAF->AFMR = 0x04;
}
return CAN_OK;
}
/********************************************************************//**
* @brief Load FullCAN entry into AFLUT
* @param[in] canId The Id of the expected CAN component
*
* @param[in] id: identifier of entry that will be added
* @return CAN_ERROR, could be:
* - CAN_OK: loading is successful
* - CAN_ID_EXIT_ERROR: ID exited in FullCAN Section
* - CAN_OBJECTS_FULL_ERROR: no more space available
*********************************************************************/
CAN_ERROR CAN_LoadFullCANEntry (uint8_t canId, uint16_t id)
{
uint32_t buf0 = 0, buf1 = 0, buf2 = 0;
uint32_t tmp0 = 0, tmp1 = 0, tmp2 = 0;
int16_t cnt1 = 0, cnt2 = 0, bound1 = 0, total = 0;
/* Acceptance Filter Memory full - return */
total =((CANAF_FullCAN_cnt + 1) >> 1) + CANAF_FullCAN_cnt*3 + ((CANAF_std_cnt + 1) >> 1) \
+ CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt << 1);
//don't have enough space for this fullCAN Entry and its Object(3*32 bytes)
if ((total >= 508) || (CANAF_FullCAN_cnt >= 64))
{
return CAN_OBJECTS_FULL_ERROR;
}
/* Setup Acceptance Filter Configuration
Acceptance Filter Mode Register = Off */
LPC_CANAF->AFMR = 0x00000001;
/* Add mask for standard identifiers */
id &= 0x07FF;
id |= (canId << 13) | (1 << 11);
/* Move all remaining sections one place up
if new entry will increase FullCAN list */
if (((CANAF_FullCAN_cnt & 0x0001) == 0)&&(total!=0))
{
//then remove remaining section
cnt1 = (CANAF_FullCAN_cnt >> 1);
bound1 = total;
buf0 = LPC_CANAF_RAM->mask[cnt1];
while (bound1--)
{
cnt1++;
buf1 = LPC_CANAF_RAM->mask[cnt1];
LPC_CANAF_RAM->mask[cnt1] = buf0;
buf0 = buf1;
}
}
if (CANAF_FullCAN_cnt == 0)
{
/* For entering first ID */
LPC_CANAF_RAM->mask[0] = 0x0000FFFF | (id << 16);
}
else if (CANAF_FullCAN_cnt == 1)
{
/* For entering second ID */
if (((LPC_CANAF_RAM->mask[0] >> 16)& 0xE7FF) > id)
{
LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] >> 16) | (id << 16);
}
else
{
LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] & 0xFFFF0000) | id;
}
}
else
{
/* Find where to insert new ID */
cnt1 = 0;
cnt2 = CANAF_FullCAN_cnt;
bound1 = (CANAF_FullCAN_cnt - 1) >> 1;
while (cnt1 <= bound1)
{
/* Loop through standard existing IDs */
if (((LPC_CANAF_RAM->mask[cnt1] >> 16) & 0xE7FF) > (id & 0xE7FF))
{
cnt2 = cnt1 * 2;
break;
}
if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000E7FF) > (id & 0xE7FF))
{
cnt2 = cnt1 * 2 + 1;
break;
}
cnt1++;
}
/* cnt1 = U32 where to insert new ID */
/* cnt2 = U16 where to insert new ID */
if (cnt1 > bound1)
{
/* Adding ID as last entry */
/* Even number of IDs exists */
if ((CANAF_FullCAN_cnt & 0x0001) == 0)
{
LPC_CANAF_RAM->mask[cnt1] = 0x0000FFFF | (id << 16);
}
/* Odd number of IDs exists */
else
{
LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
}
}
else
{
buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */
if ((cnt2 & 0x0001) == 0)
{
/* Insert new mask to even address*/
buf1 = (id << 16) | (buf0 >> 16);
}
else
{
/* Insert new mask to odd address */
buf1 = (buf0 & 0xFFFF0000) | id;
}
LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */
bound1 = CANAF_FullCAN_cnt >> 1;
/* Move all remaining standard mask entries one place up */
while (cnt1 < bound1)
{
cnt1++;
buf1 = LPC_CANAF_RAM->mask[cnt1];
LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
buf0 = buf1;
}
if ((CANAF_FullCAN_cnt & 0x0001) == 0)
{
/* Even number of IDs exists */
LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000)
| (0x0000FFFF);
}
}
}
//restruct FulCAN Object Section
bound1 = CANAF_FullCAN_cnt - cnt2;
cnt1 = total - (CANAF_FullCAN_cnt)*3 + cnt2*3 + 1;
buf0 = LPC_CANAF_RAM->mask[cnt1];
buf1 = LPC_CANAF_RAM->mask[cnt1+1];
buf2 = LPC_CANAF_RAM->mask[cnt1+2];
LPC_CANAF_RAM->mask[cnt1]=LPC_CANAF_RAM->mask[cnt1+1]= LPC_CANAF_RAM->mask[cnt1+2]=0x00;
cnt1+=3;
while(bound1--)
{
tmp0 = LPC_CANAF_RAM->mask[cnt1];
tmp1 = LPC_CANAF_RAM->mask[cnt1+1];
tmp2 = LPC_CANAF_RAM->mask[cnt1+2];
LPC_CANAF_RAM->mask[cnt1]= buf0;
LPC_CANAF_RAM->mask[cnt1+1]= buf1;
LPC_CANAF_RAM->mask[cnt1+2]= buf2;
buf0 = tmp0;
buf1 = tmp1;
buf2 = tmp2;
cnt1+=3;
}
CANAF_FullCAN_cnt++;
//update address values
LPC_CANAF->SFF_sa += 0x04;
LPC_CANAF->SFF_GRP_sa += 0x04 ;
LPC_CANAF->EFF_sa += 0x04 ;
LPC_CANAF->EFF_GRP_sa += 0x04;
LPC_CANAF->ENDofTable += 0x04;
LPC_CANAF->AFMR = 0x04;
return CAN_OK;
}
/********************************************************************//**
* @brief Load Group entry into AFLUT
* @param[in] canId The Id of the expected CAN component
*
* @param[in] lowerID, upperID: lower and upper identifier of entry
* @param[in] format: type of ID format, should be:
* - STD_ID_FORMAT: Standard ID format (11-bit value)
* - EXT_ID_FORMAT: Extended ID format (29-bit value)
* @return CAN_ERROR, could be:
* - CAN_OK: loading is successful
* - CAN_CONFLICT_ID_ERROR: Conflict ID occurs
* - CAN_OBJECTS_FULL_ERROR: no more space available
*********************************************************************/
CAN_ERROR CAN_LoadGroupEntry(uint8_t canId, uint32_t lowerID,
uint32_t upperID, CAN_ID_FORMAT_Type format)
{
uint32_t buf0, buf1, entry1, entry2, LID,UID;
int16_t cnt1, bound1, total;
if(lowerID > upperID)
return CAN_CONFLICT_ID_ERROR;
total =((CANAF_FullCAN_cnt+1) >> 1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1) \
+ CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
/* Setup Acceptance Filter Configuration
Acceptance Filter Mode Register = Off */
LPC_CANAF->AFMR = 0x00000001;
/*********Add Group of Standard Identifier Frame Format************/
if(format == STD_ID_FORMAT)
{
if ((total >= 512))
{
//don't have enough space
return CAN_OBJECTS_FULL_ERROR;
}
lowerID &=0x7FF; //mask ID
upperID &=0x7FF;
entry1 = (canId << 29) | (lowerID << 16) | (canId << 13)|(upperID << 0);
cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1);
//if this is the first Group standard ID entry
if(CANAF_gstd_cnt == 0)
{
LPC_CANAF_RAM->mask[cnt1] = entry1;
}
else
{
//find the position to add new Group entry
bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt;
while(cnt1 < bound1)
{
//compare controller first
while((LPC_CANAF_RAM->mask[cnt1] >> 29)< (entry1 >> 29))//increase until meet greater or equal controller
cnt1++;
buf0 = LPC_CANAF_RAM->mask[cnt1];
if((LPC_CANAF_RAM->mask[cnt1] >> 29)> (entry1 >> 29)) //meet greater controller
{
//add at this position
LPC_CANAF_RAM->mask[cnt1] = entry1;
break;
}
else //meet equal controller
{
LID = (buf0 >> 16)&0x7FF;
UID = buf0 & 0x7FF;
if (upperID <= LID)
{
//add new entry before this entry
LPC_CANAF_RAM->mask[cnt1] = entry1;
break;
}
else if (lowerID >= UID)
{
//load next entry to compare
cnt1 ++;
}
else
return CAN_CONFLICT_ID_ERROR;
}
}
if(cnt1 >= bound1)
{
//add new entry at the last position in this list
buf0 = LPC_CANAF_RAM->mask[cnt1];
LPC_CANAF_RAM->mask[cnt1] = entry1;
}
//remove all remaining entry of this section one place up
bound1 = total - cnt1;
while(bound1--)
{
cnt1++;
buf1 = LPC_CANAF_RAM->mask[cnt1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -