📄 lpc17xx_can.c.svn-base
字号:
}
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];
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 = (tmp << 29)|(lowerID << 0);
entry2 = (tmp << 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)< tmp) //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)> (entry1 >> 29)) //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;
CHECK_PARAM(PARAM_AFLUT_ENTRY_TYPE(EntryType));
CHECK_PARAM(PARAM_POSITION(position));
/* 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] CANx pointer to LPC_CAN_TypeDef, should be:
* - LPC_CAN1: CAN1 peripheral
* - LPC_CAN2: CAN2 peripheral
* @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 (LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg)
{
uint32_t data;
CHECK_PARAM(PARAM_CANx(CANx));
CHECK_PARAM(PARAM_ID_FORMAT(CAN_Msg->format));
if(CAN_Msg->format==STD_ID_FORMAT)
{
CHECK_PARAM(PARAM_ID_11(CAN_Msg->id));
}
else
{
CHECK_PARAM(PARAM_ID_29(CAN_Msg->id));
}
CHECK_PARAM(PARAM_DLC(CAN_Msg->len));
CHECK_PARAM(PARAM_FRAME_TYPE(CAN_Msg->type));
//Check status of Transmit Buffer 1
if (CANx->SR & (1<<2))
{
/* Transmit Channel 1 is available */
/* Write frame informations and frame data into its CANxTFI1,
* CANxTID1, CANxTDA1, CANxTDB1 register */
CANx->TFI1 &= ~0x000F0000;
CANx->TFI1 |= (CAN_Msg->len)<<16;
if(CAN_Msg->type == REMOTE_FRAME)
{
CANx->TFI1 |= (1<<30); //set bit RTR
}
else
{
CANx->TFI1 &= ~(1<<30);
}
if(CAN_Msg->format == EXT_ID_FORMAT)
{
CANx->TFI1 |= (1<<31); //set bit FF
}
else
{
CANx->TFI1 &= ~(1<<31);
}
/* Write CAN ID*/
CANx->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);
CANx->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);
CANx->TDB1 = data;
/*Write transmission request*/
CANx->CMR = 0x21;
return SUCCESS;
}
//check status of Transmit Buffer 2
else if(CANx->SR & (1<<10))
{
/* Transmit Channel 2 is available */
/* Write frame informations and frame data into its CANxTFI2,
* CANxTID2, CANxTDA2, CANxTDB2 register */
CANx->TFI2 &= ~0x000F0000;
CANx->TFI2 |= (CAN_Msg->len)<<16;
if(CAN_Msg->type == REMOTE_FRAME)
{
CANx->TFI2 |= (1<<30); //set bit RTR
}
else
{
CANx->TFI2 &= ~(1<<30);
}
if(CAN_Msg->format == EXT_ID_FORMAT)
{
CANx->TFI2 |= (1<<31); //set bit FF
}
else
{
CANx->TFI2 &= ~(1<<31);
}
/* Write CAN ID*/
CANx->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);
CANx->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);
CANx->TDB2 = data;
/*Write transmission request*/
CANx->CMR = 0x41;
return SUCCESS;
}
//check status of Transmit Buffer 3
else if (CANx->SR & (1<<18))
{
/* Transmit Channel 3 is available */
/* Write frame informations and frame data into its CANxTFI3,
* CANxTID3, CANxTDA3, CANxTDB3 register */
CANx->TFI3 &= ~0x000F0000;
CANx->TFI3 |= (CAN_Msg->len)<<16;
if(CAN_Msg->type == REMOTE_FRAME)
{
CANx->TFI3 |= (1<<30); //set bit RTR
}
else
{
CANx->TFI3 &= ~(1<<30);
}
if(CAN_Msg->format == EXT_ID_FORMAT)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -