⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lpc177x_8x_can.c

📁 LPC1788的USBHOST的FATFS移植
💻 C
📖 第 1 页 / 共 4 页
字号:
 * 				- 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 + -