📄 lpc177x_8x_can.c
字号:
LPC_CANAF_RAM->mask[cnt1] = buf0;
buf0 = buf1;
}
}
CANAF_gstd_cnt++;
//update address values
LPC_CANAF->EFF_sa +=0x04 ;
LPC_CANAF->EFF_GRP_sa +=0x04;
LPC_CANAF->ENDofTable +=0x04;
}
/*********Add Group of Extended Identifier Frame Format************/
else
{
if ((total >= 511))
{
//don't have enough space
return CAN_OBJECTS_FULL_ERROR;
}
lowerID &= 0x1FFFFFFF; //mask ID
upperID &= 0x1FFFFFFF;
entry1 = (canId << 29)|(lowerID << 0);
entry2 = (canId << 29)|(upperID << 0);
cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt + CANAF_ext_cnt;
//if this is the first Group standard ID entry
if(CANAF_gext_cnt == 0)
{
LPC_CANAF_RAM->mask[cnt1] = entry1;
LPC_CANAF_RAM->mask[cnt1+1] = entry2;
}
else
{
//find the position to add new Group entry
bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt \
+ CANAF_ext_cnt + (CANAF_gext_cnt<<1);
while(cnt1 < bound1)
{
while((LPC_CANAF_RAM->mask[cnt1] >>29)< canId) //increase until meet greater or equal controller
cnt1++;
buf0 = LPC_CANAF_RAM->mask[cnt1];
buf1 = LPC_CANAF_RAM->mask[cnt1+1];
if((LPC_CANAF_RAM->mask[cnt1] >> 29)> canId) //meet greater controller
{
//add at this position
LPC_CANAF_RAM->mask[cnt1] = entry1;
LPC_CANAF_RAM->mask[++cnt1] = entry2;
break;
}
else //meet equal controller
{
LID = buf0 & 0x1FFFFFFF; //mask ID
UID = buf1 & 0x1FFFFFFF;
if (upperID <= LID)
{
//add new entry before this entry
LPC_CANAF_RAM->mask[cnt1] = entry1;
LPC_CANAF_RAM->mask[++cnt1] = entry2;
break;
}
else if (lowerID >= UID)
{
//load next entry to compare
cnt1 +=2;
}
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];
buf1 = LPC_CANAF_RAM->mask[cnt1+1];
LPC_CANAF_RAM->mask[cnt1] = entry1;
LPC_CANAF_RAM->mask[++cnt1] = entry2;
}
//remove all remaining entry of this section two place up
bound1 = total - cnt1 + 1;
cnt1++;
while(bound1>0)
{
entry1 = LPC_CANAF_RAM->mask[cnt1];
entry2 = LPC_CANAF_RAM->mask[cnt1+1];
LPC_CANAF_RAM->mask[cnt1] = buf0;
LPC_CANAF_RAM->mask[cnt1+1] = buf1;
buf0 = entry1;
buf1 = entry2;
cnt1 +=2;
bound1 -=2;
}
}
CANAF_gext_cnt++;
//update address values
LPC_CANAF->ENDofTable +=0x08;
}
LPC_CANAF->AFMR = 0x04;
return CAN_OK;
}
/********************************************************************//**
* @brief Remove AFLUT entry (FullCAN entry and Explicit Standard entry)
* @param[in] EntryType: the type of entry that want to remove, should be:
* - FULLCAN_ENTRY
* - EXPLICIT_STANDARD_ENTRY
* - GROUP_STANDARD_ENTRY
* - EXPLICIT_EXTEND_ENTRY
* - GROUP_EXTEND_ENTRY
* @param[in] position: the position of this entry in its section
* Note: the first position is 0
* @return CAN_ERROR, could be:
* - CAN_OK: removing is successful
* - CAN_ENTRY_NOT_EXIT_ERROR: entry want to remove is not exit
*********************************************************************/
CAN_ERROR CAN_RemoveEntry(AFLUT_ENTRY_Type EntryType, uint16_t position)
{
uint16_t cnt, bound, total;
uint32_t buf0, buf1;
/* Setup Acceptance Filter Configuration
Acceptance Filter Mode Register = Off */
LPC_CANAF->AFMR = 0x00000001;
total = ((CANAF_FullCAN_cnt + 1) >> 1) + ((CANAF_std_cnt + 1) >> 1) + \
+ CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt << 1);
/************** Remove FullCAN Entry *************/
if(EntryType == FULLCAN_ENTRY)
{
if((CANAF_FullCAN_cnt == 0)||(position >= CANAF_FullCAN_cnt))
{
return CAN_ENTRY_NOT_EXIT_ERROR;
}
else
{
cnt = position >> 1;
buf0 = LPC_CANAF_RAM->mask[cnt];
bound = (CANAF_FullCAN_cnt - position -1)>>1;
if((position & 0x0001) == 0) //event position
{
while(bound--)
{
//remove all remaining FullCAN entry one place down
buf1 = LPC_CANAF_RAM->mask[cnt+1];
LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16);
buf0 = buf1;
cnt++;
}
}
else //odd position
{
while(bound--)
{
//remove all remaining FullCAN entry one place down
buf1 = LPC_CANAF_RAM->mask[cnt+1];
LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000)|(buf1 >> 16);
LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+1] << 16;
buf0 = buf1<<16;
cnt++;
}
}
if((CANAF_FullCAN_cnt & 0x0001) == 0)
{
if((position & 0x0001)==0)
LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF);
else
LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF;
}
else
{
//remove all remaining section one place down
cnt = (CANAF_FullCAN_cnt + 1)>>1;
bound = total + CANAF_FullCAN_cnt * 3;
while(bound>cnt)
{
LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
cnt++;
}
LPC_CANAF_RAM->mask[cnt-1]=0x00;
//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;
}
CANAF_FullCAN_cnt--;
//delete its FullCAN Object in the FullCAN Object section
//remove all remaining FullCAN Object three place down
cnt = total + position * 3;
bound = (CANAF_FullCAN_cnt - position + 1) * 3;
while(bound)
{
LPC_CANAF_RAM->mask[cnt]= LPC_CANAF_RAM->mask[cnt+3];;
LPC_CANAF_RAM->mask[cnt+1]= LPC_CANAF_RAM->mask[cnt+4];
LPC_CANAF_RAM->mask[cnt+2]= LPC_CANAF_RAM->mask[cnt+5];
bound -= 3;
cnt += 3;
}
}
}
/************** Remove Explicit Standard ID Entry *************/
else if(EntryType == EXPLICIT_STANDARD_ENTRY)
{
if((CANAF_std_cnt == 0)||(position >= CANAF_std_cnt))
{
return CAN_ENTRY_NOT_EXIT_ERROR;
}
else
{
cnt = ((CANAF_FullCAN_cnt+1) >> 1) + (position >> 1);
buf0 = LPC_CANAF_RAM->mask[cnt];
bound = (CANAF_std_cnt - position - 1) >> 1;
if((position & 0x0001) == 0) //event position
{
while(bound--)
{
//remove all remaining FullCAN entry one place down
buf1 = LPC_CANAF_RAM->mask[cnt + 1];
LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16);
buf0 = buf1;
cnt++;
}
}
else //odd position
{
while(bound--)
{
//remove all remaining FullCAN entry one place down
buf1 = LPC_CANAF_RAM->mask[cnt + 1];
LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000) | (buf1 >> 16);
LPC_CANAF_RAM->mask[cnt + 1] = LPC_CANAF_RAM->mask[cnt + 1] << 16;
buf0 = buf1<<16;
cnt++;
}
}
if((CANAF_std_cnt & 0x0001) == 0)
{
if((position & 0x0001)==0)
LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF);
else
LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF;
}
else
{
//remove all remaining section one place down
cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1);
bound = total + CANAF_FullCAN_cnt * 3;
while(bound>cnt)
{
LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
cnt++;
}
LPC_CANAF_RAM->mask[cnt-1]=0x00;
//update address value
LPC_CANAF->SFF_GRP_sa -= 0x04 ;
LPC_CANAF->EFF_sa -= 0x04 ;
LPC_CANAF->EFF_GRP_sa -= 0x04;
LPC_CANAF->ENDofTable -= 0x04;
}
CANAF_std_cnt--;
}
}
/************** Remove Group of Standard ID Entry *************/
else if(EntryType == GROUP_STANDARD_ENTRY)
{
if((CANAF_gstd_cnt == 0)||(position >= CANAF_gstd_cnt))
{
return CAN_ENTRY_NOT_EXIT_ERROR;
}
else
{
cnt = ((CANAF_FullCAN_cnt + 1) >> 1) + ((CANAF_std_cnt + 1) >> 1)+ position + 1;
bound = total + CANAF_FullCAN_cnt * 3;
while (cnt < bound)
{
LPC_CANAF_RAM->mask[cnt - 1] = LPC_CANAF_RAM->mask[cnt];
cnt++;
}
LPC_CANAF_RAM->mask[cnt - 1]=0x00;
}
CANAF_gstd_cnt--;
//update address value
LPC_CANAF->EFF_sa -= 0x04;
LPC_CANAF->EFF_GRP_sa -= 0x04;
LPC_CANAF->ENDofTable -= 0x04;
}
/************** Remove Explicit Extended ID Entry *************/
else if(EntryType == EXPLICIT_EXTEND_ENTRY)
{
if((CANAF_ext_cnt == 0)||(position >= CANAF_ext_cnt))
{
return CAN_ENTRY_NOT_EXIT_ERROR;
}
else
{
cnt = ((CANAF_FullCAN_cnt + 1) >> 1) + ((CANAF_std_cnt + 1) >> 1)+ CANAF_gstd_cnt + position + 1;
bound = total + CANAF_FullCAN_cnt * 3;
while (cnt<bound)
{
LPC_CANAF_RAM->mask[cnt - 1] = LPC_CANAF_RAM->mask[cnt];
cnt++;
}
LPC_CANAF_RAM->mask[cnt - 1]=0x00;
}
CANAF_ext_cnt--;
LPC_CANAF->EFF_GRP_sa -= 0x04;
LPC_CANAF->ENDofTable -= 0x04;
}
/************** Remove Group of Extended ID Entry *************/
else
{
if((CANAF_gext_cnt == 0)||(position >= CANAF_gext_cnt))
{
return CAN_ENTRY_NOT_EXIT_ERROR;
}
else
{
cnt = total - (CANAF_gext_cnt << 1) + (position << 1);
bound = total + CANAF_FullCAN_cnt * 3;
while (cnt<bound)
{
//remove all remaining entry two place up
LPC_CANAF_RAM->mask[cnt] = LPC_CANAF_RAM->mask[cnt + 2];
LPC_CANAF_RAM->mask[cnt + 1] = LPC_CANAF_RAM->mask[cnt + 3];
cnt += 2;
}
}
CANAF_gext_cnt--;
LPC_CANAF->ENDofTable -= 0x08;
}
LPC_CANAF->AFMR = 0x04;
return CAN_OK;
}
/********************************************************************//**
* @brief Send message data
* @param[in] canId The Id of the expected CAN component
*
* @param[in] CAN_Msg point to the CAN_MSG_Type Structure, it contains message
* information such as: ID, DLC, RTR, ID Format
* @return Status:
* - SUCCESS: send message successfully
* - ERROR: send message unsuccessfully
*********************************************************************/
Status CAN_SendMsg (uint8_t canId, CAN_MSG_Type *CAN_Msg)
{
LPC_CAN_TypeDef* pCan = CAN_GetPointer(canId);
uint32_t data;
//Check status of Transmit Buffer 1
if (pCan->SR & (1 << 2))
{
/* Transmit Channel 1 is available */
/* Write frame informations and frame data into its CANxTFI1,
* CANxTID1, CANxTDA1, CANxTDB1 register */
pCan->TFI1 &= ~ 0x000F0000;
pCan->TFI1 |= (CAN_Msg->len) << 16;
if(CAN_Msg->type == REMOTE_FRAME)
{
pCan->TFI1 |= (1 << 30); //set bit RTR
}
else
{
pCan->TFI1 &= ~(1 << 30);
}
if(CAN_Msg->format == EXT_ID_FORMAT)
{
pCan->TFI1 |= (1 << 31); //set bit FF
}
else
{
pCan->TFI1 &= ~(1 << 31);
}
/* Write CAN ID*/
pCan->TID1 = CAN_Msg->id;
/*Write first 4 data bytes*/
data = (CAN_Msg->dataA[0]) | (((CAN_Msg->dataA[1]))<< 8) | ((CAN_Msg->dataA[2]) << 16) | ((CAN_Msg->dataA[3]) << 24);
pCan->TDA1 = data;
/*Write second 4 data bytes*/
data = (CAN_Msg->dataB[0]) | (((CAN_Msg->dataB[1])) << 8)|((CAN_Msg->dataB[2]) << 16)|((CAN_Msg->dataB[3]) << 24);
pCan->TDB1 = data;
/*Write transmission request*/
pCan->CMR = 0x21;
return SUCCESS;
}
//check status of Transmit Buffer 2
else if((pCan->SR) & (1 << 10))
{
/* Transmit Channel 2 is available */
/* Write frame informations and frame data into its CANxTFI2,
* CANxTID2, CANxTDA2, CANxTDB2 register */
pCan->TFI2 &= ~0x000F0000;
pCan->TFI2 |= (CAN_Msg->len) << 16;
if(CAN_Msg->type == REMOTE_FRAME)
{
pCan->TFI2 |= (1 << 30); //set bit RTR
}
else
{
pCan->TFI2 &= ~(1 << 30);
}
if(CAN_Msg->format == EXT_ID_FORMAT)
{
pCan->TFI2 |= (1 << 31); //set bit FF
}
else
{
pCan->TFI2 &= ~(1 << 31);
}
/* Write CAN ID*/
pCan->TID2 = CAN_Msg->id;
/*Write first 4 data bytes*/
data = (CAN_Msg->dataA[0]) | (((CAN_Msg->dataA[1])) << 8) | ((CAN_Msg->dataA[2]) << 16)|((CAN_Msg->dataA[3]) << 24);
pCan->TDA2 = data;
/*Write second 4 data bytes*/
data = (CAN_Msg->dataB[0]) | (((CAN_Msg->dataB[1])) << 8) | ((CAN_Msg->dataB[2]) << 16) | ((CAN_Msg->dataB[3]) << 24);
pCan->TDB2 = data;
/*Write transmission request*/
pCan->CMR = 0x41;
return SUCCESS;
}
//check status of Transmit Buffer 3
else if (pCan->SR & (1<<18))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -