Browse Source

Merge pull request #511 from AubrCool/fix-lpc4088candriver

Fix lpc4088candriver
Bernard Xiong 10 years ago
parent
commit
eb23f0def3

+ 1 - 1
bsp/lpc408x/applications/board.c

@@ -64,5 +64,5 @@ void rt_hw_board_init()
     lpc_sdram_hw_init();
     rt_kprintf("done!\n");
 #endif
-
+    rt_components_board_init();
 }

+ 84 - 0
bsp/lpc408x/applications/canapp.c

@@ -0,0 +1,84 @@
+/*
+ * File      : canapp.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       		Notes
+ * 2015-05-14     aubrcool@qq.com 	first version
+ */
+
+#include <board.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+#ifdef RT_USING_CAN
+#include "drv_lpccan.h"
+struct can_app_struct
+{
+	const char* name;
+	struct rt_can_filter_config * filter;
+	rt_uint8_t eventopt;
+	struct rt_semaphore sem;
+};
+static struct can_app_struct can_data[1];
+struct rt_can_filter_item filter1item[4] =
+{
+	LPC_CAN_AF_STD_INIT(1),
+	LPC_CAN_AF_STD_GRP_INIT(3,5),
+	LPC_CAN_AF_EXT_INIT(2),
+	LPC_CAN_AF_EXT_GRP_INIT(4,6),
+};
+struct rt_can_filter_config filter1 =
+{
+	.count = 4,
+	.actived = 1,
+	.items = filter1item,
+};
+static struct can_app_struct can_data[1] = {
+	{
+		.name = "lpccan1",
+		.filter = &filter1,
+		.eventopt = RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
+	},
+};
+static rt_err_t lpccanind(rt_device_t dev, rt_size_t size)
+{
+	rt_sem_release(&can_data[0].sem);
+}
+void rt_can_thread_entry(void* parameter)
+{
+	struct rt_can_msg msg;
+	struct can_app_struct* canpara = (struct can_app_struct*) parameter;
+	rt_device_t candev;
+
+	candev = rt_device_find(canpara->name);
+	RT_ASSERT(candev);
+	rt_sem_init(&canpara->sem, canpara->name, 0, RT_IPC_FLAG_FIFO);
+	rt_device_open(candev, (RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX));
+	rt_device_control(candev,RT_CAN_CMD_SET_FILTER,canpara->filter);
+	rt_device_set_rx_indicate(candev, lpccanind);
+	while(1) {
+		rt_sem_take(&canpara->sem, RT_WAITING_FOREVER);
+		while (rt_device_read(candev, 0, &msg, sizeof(msg)) == sizeof(msg)) {
+			rt_device_write(candev, 0, &msg, sizeof(msg));
+		}
+	}
+}
+int rt_can_app_init(void)
+{
+	rt_thread_t tid;
+
+	tid = rt_thread_create("canapp1",
+			rt_can_thread_entry, &can_data[0],
+			512, RT_THREAD_PRIORITY_MAX /3 - 1, 20);
+	if (tid != RT_NULL) rt_thread_startup(tid);
+
+	return 0;
+}
+
+INIT_APP_EXPORT(rt_can_app_init);
+#endif /*RT_USING_CAN*/

+ 0 - 1
bsp/lpc408x/applications/startup.c

@@ -39,7 +39,6 @@ void rtthread_startup(void)
     rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
 #endif
 #endif
-
     /* initialize scheduler system */
     rt_system_scheduler_init();
     /* initialize system timer*/

+ 973 - 0
bsp/lpc408x/drivers/drv_lpccan.c

@@ -0,0 +1,973 @@
+/*
+ * File      : drv_lpccan.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2015, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       		Notes
+ * 2015-06-30     aubrcool@qq.com 	first version
+ */
+#include <rthw.h>
+#include <rtdevice.h>
+#include <board.h>
+#include <drv_lpccan.h>
+#ifdef RT_USING_COMPONENTS_INIT
+#include <components.h>
+#endif
+
+#ifdef RT_USING_CAN
+
+#include "lpc_types.h"
+#include "lpc_can.h"
+#include "lpc_pinsel.h"
+#include "lpc_exti.h"
+#include "lpc_clkpwr.h"
+
+struct lpccandata {
+	en_CAN_unitId id;		
+};
+static const rt_uint32_t LPCBAUDTAB[] = {
+	1000000,
+	800000,
+	500000,
+	250000,
+	125000,
+	100000,
+	50000,
+	20000,
+	10000,
+};
+static LPC_CAN_TypeDef*  lcpcan_get_reg_base(rt_uint32_t id)
+{
+	LPC_CAN_TypeDef* pCan;
+
+	switch (id) {
+		case CAN_ID_1:
+			pCan = LPC_CAN1;
+			break;
+
+		case CAN_ID_2:
+			pCan = LPC_CAN2;
+			break;
+		default:
+			pCan = NULL;
+	}
+	return pCan;
+}
+static void lpccan_irqstate_init(rt_uint32_t id)
+{
+	LPC_CAN_TypeDef* pCan = lcpcan_get_reg_base(id);
+
+	pCan->MOD = 1; // Enter Reset Mode
+	pCan->IER = 0; // Disable All CAN Interrupts
+	pCan->GSR = 0;
+
+	/* Request command to release Rx, Tx buffer and clear data overrun */
+	//pCan->CMR = CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO;
+	pCan->CMR = (1 << 1) | (1 << 2) | (1 << 3);
+
+	/* Read to clear interrupt pending in interrupt capture register */
+	rt_int32_t i = pCan->ICR;
+	pCan->MOD = 0;// Return Normal operating
+}
+static void lpccan_baud_set(rt_uint32_t id, rt_uint32_t baud)
+{
+	uint32_t result = 0;
+	uint8_t NT, TSEG1, TSEG2;
+	uint32_t CANPclk = 0;
+	uint32_t BRP;
+	LPC_CAN_TypeDef* pCan = lcpcan_get_reg_base(id);
+
+	CANPclk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER);
+	result = CANPclk / LPCBAUDTAB[baud];
+	/* Calculate suitable nominal time value
+	 * NT (nominal time) = (TSEG1 + TSEG2 + 3)
+	 * NT <= 24
+	 * TSEG1 >= 2*TSEG2
+	 */
+	for(NT = 24; NT > 0; NT = NT-2)
+	{
+		if ((result%NT) == 0)
+		{
+			BRP = result / NT - 1;
+			NT--;
+			TSEG2 = (NT/3) - 1;
+			TSEG1 = NT -(NT/3) - 1;
+			break;
+		}
+	}
+	/* Enter reset mode */
+	pCan->MOD = 0x01;
+	/* Set bit timing
+	 * Default: SAM = 0x00;
+	 *          SJW = 0x03;
+	 */
+	pCan->BTR = (TSEG2 << 20) | (TSEG1 << 16) | (3 << 14) | BRP;
+	/* Return to normal operating */
+	pCan->MOD = 0;
+}
+static void lpccan_init_alut_ram(void)
+{
+	//Reset CANAF value
+	LPC_CANAF->AFMR = 0x01;
+	//clear ALUT RAM
+	rt_memset((void *)LPC_CANAF_RAM->mask, 0, 2048);
+	LPC_CANAF->SFF_sa = 0;
+	LPC_CANAF->SFF_GRP_sa = 0;
+	LPC_CANAF->EFF_sa = 0;
+	LPC_CANAF->EFF_GRP_sa = 0;
+	LPC_CANAF->ENDofTable = 0;
+	LPC_CANAF->AFMR = 0x00;
+	// Set AF Mode
+	CAN_SetAFMode(CAN_NORMAL);
+}
+#ifdef RT_USING_LPCCAN1
+static void lpccan1_turnon_clk(void)
+{
+	CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN1, ENABLE);
+}
+static void lpccan1_filter_init(struct rt_can_device *can)
+{
+}
+static void lpccan1_hw_init(enum CANBAUD baud, CAN_MODE_Type mode)
+{
+	if(mode != CAN_SELFTEST_MODE) {
+#ifndef LPCCAN1_USEING_GPIO_SECOND
+		PINSEL_ConfigPin (0, 0, 1);
+		PINSEL_ConfigPin (0, 1, 1);
+#else
+		PINSEL_ConfigPin (0, 21, 4);
+		PINSEL_ConfigPin (0, 22, 4);
+#endif
+	}
+	lpccan1_turnon_clk();
+	lpccan_irqstate_init(CAN_1);
+	lpccan_init_alut_ram();
+	lpccan1_turnon_clk();
+	lpccan_baud_set(CAN_1, baud);
+	CAN_ModeConfig(CAN_1, mode, ENABLE);
+	if(mode == CAN_SELFTEST_MODE) {
+		//CAN_ModeConfig(CAN_1, CAN_TEST_MODE, ENABLE);
+		CAN_SetAFMode(CAN_ACC_BP);
+	}
+}
+#endif /*RT_USING_LPCCAN1*/
+#ifdef RT_USING_LPCCAN2
+static void lpccan2_turnon_clk(void)
+{
+	CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN2, ENABLE);
+}
+static void lpccan2_filter_init(struct rt_can_device *can)
+{
+}
+static void lpccan2_hw_init(enum CANBAUD baud,  CAN_MODE_Type mode)
+{
+	if(mode != CAN_SELFTEST_MODE) {
+#ifndef LPCCAN2_USEING_GPIO_SECOND
+		PINSEL_ConfigPin (0, 4, 2);
+		PINSEL_ConfigPin (0, 5, 2);
+#else
+		PINSEL_ConfigPin (2, 7, 1);
+		PINSEL_ConfigPin (2, 8, 1);
+#endif
+	}
+	lpccan2_turnon_clk();
+	lpccan_irqstate_init(CAN_2);
+#ifndef RT_USING_LPCCAN1
+	lpccan_init_alut_ram();
+#endif /*RT_USING_LPCCAN1*/
+	lpccan_baud_set(CAN_2, baud);
+	CAN_ModeConfig(CAN_2, mode, ENABLE);
+	if(mode == CAN_SELFTEST_MODE) {
+		CAN_SetAFMode(CAN_ACC_BP);
+	}
+}
+#endif /*RT_USING_LPCCAN2*/
+static rt_err_t configure(struct rt_can_device *can, struct can_configure *cfg)
+{
+	CAN_MODE_Type mode;
+	switch(cfg->mode) {
+		case RT_CAN_MODE_NORMAL:
+			mode = CAN_OPERATING_MODE;
+			break;
+		case RT_CAN_MODE_LISEN:
+			mode = CAN_LISTENONLY_MODE;
+			break;
+		case RT_CAN_MODE_LOOPBACKANLISEN:
+			mode = CAN_SELFTEST_MODE;
+			break;
+		default:
+			return RT_EIO;
+	}
+	rt_uint32_t canid;
+	canid = ((struct lpccandata  *) can->parent.user_data)->id;
+#ifdef RT_USING_LPCCAN1			
+	if(canid == CAN_1)
+	{
+		lpccan1_hw_init(cfg->baud_rate, mode);
+		lpccan1_filter_init(can);
+	}
+#endif /*RT_USING_LPCCAN1*/
+#ifdef RT_USING_LPCCAN2
+#ifdef RT_USING_LPCCAN1
+	else
+#endif /*RT_USING_LPCCAN1*/
+	{
+		lpccan2_hw_init(cfg->baud_rate, mode);
+		lpccan2_filter_init(can);
+	}
+#endif /*RT_USING_LPCCAN2*/
+	return RT_EOK;
+}
+static CAN_ERROR findfilter(struct lpccandata* plpccan, struct rt_can_filter_item* pitem, rt_int32_t* pos)
+{
+	extern uint16_t CANAF_FullCAN_cnt;
+	extern uint16_t CANAF_std_cnt;
+	extern uint16_t CANAF_gstd_cnt;
+	extern uint16_t CANAF_ext_cnt;
+	extern uint16_t CANAF_gext_cnt;
+
+	rt_uint32_t buf0 = 0, buf1 = 0;
+	rt_int16_t cnt1 = 0, cnt2 = 0, bound1 = 0;
+	CAN_ID_FORMAT_Type format;
+	*pos = -1;
+	if(pitem->ide) {
+		format = EXT_ID_FORMAT;
+	} else {
+		format = STD_ID_FORMAT;
+	}
+	if(pitem->mode) {
+		rt_uint32_t id = pitem->id;
+		if(format == STD_ID_FORMAT)
+		{
+			id &= 0x07FF;
+
+			id |= plpccan->id << 13;/* Add controller number */
+
+			if (CANAF_std_cnt == 0)
+			{
+				return CAN_ENTRY_NOT_EXIT_ERROR;
+			}
+			else if (CANAF_std_cnt == 1)
+			{
+				cnt2 = (CANAF_FullCAN_cnt + 1) >> 1;
+				if(id != LPC_CANAF_RAM->mask[cnt2] >> 16) {
+					return CAN_ENTRY_NOT_EXIT_ERROR; 
+				}
+			}
+			else
+			{
+				cnt1 = (CANAF_FullCAN_cnt+1)>>1;
+
+				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)
+					{
+						*pos = cnt1 * 2;
+						return CAN_OK;
+					}
+
+					if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000E7FF) == id)
+					{
+						*pos = cnt1 * 2 + 1;
+						return CAN_OK;
+					}
+					if (((LPC_CANAF_RAM->mask[cnt1] >> 16) & 0xE7FF) > id)
+					{
+						return CAN_ENTRY_NOT_EXIT_ERROR; 
+					}
+
+					if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000E7FF) > id)
+					{
+						return CAN_ENTRY_NOT_EXIT_ERROR; 
+					}
+					cnt1++;
+				}
+				return CAN_ENTRY_NOT_EXIT_ERROR; 
+			}
+		}
+		/*********** Add Explicit Extended Identifier Frame Format entry *********/
+		else
+		{
+			/* Add controller number */
+			id |= plpccan->id << 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)
+				{
+					*pos = cnt2;
+					return CAN_OK;
+				}
+				if (LPC_CANAF_RAM->mask[cnt1] > id)
+				{
+					return CAN_ENTRY_NOT_EXIT_ERROR;
+				}
+				cnt1++;
+				cnt2++;
+			}							
+		}
+	} else {
+		rt_uint32_t lowerID =  pitem->id;
+		rt_uint32_t upperID =  pitem->mask;
+		rt_uint32_t  LID,UID;
+		if(lowerID > upperID)
+			return CAN_CONFLICT_ID_ERROR;
+		if(format == STD_ID_FORMAT)
+		{
+			lowerID &=0x7FF; //mask ID
+			upperID &=0x7FF;
+			cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1);
+			if(CANAF_gstd_cnt == 0)
+			{
+				return CAN_ENTRY_NOT_EXIT_ERROR;
+			}
+			else
+			{
+				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) < (plpccan->id))//increase until meet greater or equal controller
+						cnt1++;
+					buf0 = LPC_CANAF_RAM->mask[cnt1];
+					if((LPC_CANAF_RAM->mask[cnt1] >> 29) > (plpccan->id)) //meet greater controller
+					{
+						return CAN_ENTRY_NOT_EXIT_ERROR;
+					}
+					else //meet equal controller
+					{
+						LID  = (buf0 >> 16)&0x7FF;
+						UID  = buf0 & 0x7FF;
+						if (upperID == LID && lowerID == UID)
+						{
+							*pos = cnt1;
+							return CAN_OK;
+						}
+						if (upperID < LID)
+						{
+							return CAN_ENTRY_NOT_EXIT_ERROR;
+						}
+						else if (lowerID >= UID)
+						{
+							cnt1 ++;
+						}
+						else
+							return CAN_CONFLICT_ID_ERROR;
+					}
+				}
+				if(cnt1 >= bound1)
+				{
+					return CAN_ENTRY_NOT_EXIT_ERROR;
+				}
+			}
+		}
+		/*********Add Group of Extended Identifier Frame Format************/
+		else
+		{
+			lowerID  &= 0x1FFFFFFF; //mask ID
+			upperID &= 0x1FFFFFFF;
+			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)
+			{
+				return CAN_ENTRY_NOT_EXIT_ERROR;
+			}
+			else
+			{
+				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)< plpccan->id ) //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) > plpccan->id ) //meet greater controller
+					{
+						return CAN_ENTRY_NOT_EXIT_ERROR;
+					}
+					else //meet equal controller
+					{
+						LID  = buf0 & 0x1FFFFFFF; //mask ID
+						UID  = buf1 & 0x1FFFFFFF;
+						if (upperID == LID && lowerID == UID)
+						{
+							*pos = cnt1;
+							return CAN_OK;
+						}
+						if (upperID < LID)
+						{
+							return CAN_ENTRY_NOT_EXIT_ERROR;
+						}
+						else if (lowerID >= UID)
+						{
+							//load next entry to compare
+							cnt1 +=2;
+						}
+						else
+							return CAN_CONFLICT_ID_ERROR;
+					}
+				}
+				if(cnt1 >= bound1)
+				{
+					return CAN_ENTRY_NOT_EXIT_ERROR;
+				}
+			}
+		}
+	}
+	return CAN_ENTRY_NOT_EXIT_ERROR;
+}
+static rt_err_t setfilter(struct lpccandata* plpccan,struct rt_can_filter_config *pconfig)
+{
+	struct rt_can_filter_item* pitem = pconfig->items;
+	rt_uint32_t count = pconfig->count;
+	rt_int32_t pos;
+	CAN_ID_FORMAT_Type format;
+	CAN_ERROR lpccanres;
+	while(count) {
+		if(pitem->ide) {
+			format = EXT_ID_FORMAT;
+		} else {
+			format = STD_ID_FORMAT;
+		}
+		lpccanres = findfilter(plpccan, pitem, &pos);
+		if(pconfig->actived && lpccanres != CAN_OK) {
+			if(pitem->mode) {
+				lpccanres = CAN_LoadGroupEntry(plpccan->id, pitem->id, pitem->mask, format);
+			} else {
+				lpccanres = CAN_LoadExplicitEntry(plpccan->id, pitem->id, format);
+			}
+		} else if(!pconfig->actived && lpccanres == CAN_OK) {
+			AFLUT_ENTRY_Type type;
+			if(pitem->mode) {
+				if(format == EXT_ID_FORMAT) {
+					type = GROUP_EXTEND_ENTRY;
+				} else {
+					type = GROUP_STANDARD_ENTRY;
+				}
+			} else {
+				if(format == EXT_ID_FORMAT) {
+					type = EXPLICIT_EXTEND_ENTRY;
+				} else {
+					type = EXPLICIT_STANDARD_ENTRY;
+				}
+			}
+			lpccanres = CAN_RemoveEntry(type, (rt_uint16_t)(pos));
+		} else if(!pconfig->actived && lpccanres != CAN_OK) {
+			lpccanres = CAN_OK;
+		}
+		if(lpccanres != CAN_OK) {
+			return RT_EIO;
+		}
+		pitem++;
+		count--;
+	}
+	return RT_EOK;
+}
+static rt_err_t control(struct rt_can_device *can, int cmd, void *arg)
+{
+	struct lpccandata* plpccan;
+	rt_uint32_t argval;
+	CAN_MODE_Type mode;
+	plpccan = (struct lpccandata* )  can->parent.user_data;
+	RT_ASSERT(plpccan != RT_NULL);
+	switch (cmd)
+	{
+		case RT_DEVICE_CTRL_CLR_INT:
+			argval = (rt_uint32_t) arg;
+			if(argval == RT_DEVICE_FLAG_INT_RX)
+			{
+				CAN_IRQCmd(plpccan->id, CANINT_RIE, DISABLE);
+				CAN_IRQCmd(plpccan->id, CANINT_DOIE, DISABLE);
+			} else if(argval == RT_DEVICE_FLAG_INT_TX) {
+				CAN_IRQCmd(plpccan->id, CANINT_TIE1, DISABLE);
+				CAN_IRQCmd(plpccan->id, CANINT_TIE2, DISABLE);
+				CAN_IRQCmd(plpccan->id, CANINT_TIE3, DISABLE);
+			} else if(argval == RT_DEVICE_CAN_INT_ERR) {
+				CAN_IRQCmd(plpccan->id, CANINT_EIE, DISABLE);
+			}
+			break;
+		case RT_DEVICE_CTRL_SET_INT:
+			argval = (rt_uint32_t) arg;
+			if(argval == RT_DEVICE_FLAG_INT_RX)
+			{
+				CAN_IRQCmd(plpccan->id, CANINT_RIE, ENABLE);
+				CAN_IRQCmd(plpccan->id, CANINT_DOIE, ENABLE);
+			} else if(argval == RT_DEVICE_FLAG_INT_TX) {
+				CAN_IRQCmd(plpccan->id, CANINT_TIE1, ENABLE);
+				CAN_IRQCmd(plpccan->id, CANINT_TIE2, ENABLE);
+				CAN_IRQCmd(plpccan->id, CANINT_TIE3, ENABLE);
+			} else if(argval == RT_DEVICE_CAN_INT_ERR) {
+				CAN_IRQCmd(plpccan->id, CANINT_EIE, ENABLE);
+			}
+			break;
+		case RT_CAN_CMD_SET_FILTER:
+			return setfilter(plpccan, (struct rt_can_filter_config*) arg);
+		case RT_CAN_CMD_SET_MODE:
+			argval = (rt_uint32_t) arg;
+			if(argval != RT_CAN_MODE_NORMAL ||
+					argval != RT_CAN_MODE_LISEN) {
+				return RT_ERROR; 
+			}
+			if(argval != can->config.mode)
+			{
+				can->config.mode = argval;
+				switch(argval) {
+					case RT_CAN_MODE_NORMAL:
+						mode = CAN_OPERATING_MODE;
+						break;
+					case RT_CAN_MODE_LISEN:
+						mode = CAN_LISTENONLY_MODE;
+						break;
+					case RT_CAN_MODE_LOOPBACKANLISEN:
+						mode = CAN_SELFTEST_MODE;
+						break;
+					default:
+						return RT_EIO;
+				}
+				CAN_ModeConfig(plpccan->id, mode, ENABLE);
+				if(mode == CAN_SELFTEST_MODE) {
+					//CAN_ModeConfig(CAN_1, CAN_TEST_MODE, ENABLE);
+					CAN_SetAFMode(CAN_ACC_BP);
+				}
+			}
+			break;
+		case RT_CAN_CMD_SET_BAUD:
+			argval = (rt_uint32_t) arg;
+			if(argval != CAN1MBaud &&
+					argval != CAN800kBaud &&
+					argval != CAN500kBaud &&
+					argval != CAN250kBaud &&
+					argval != CAN125kBaud &&
+					argval != CAN100kBaud &&
+					argval != CAN50kBaud  &&
+					argval != CAN20kBaud  &&
+					argval != CAN10kBaud  ) {
+				return RT_ERROR; 
+			}
+			if(argval != can->config.baud_rate)
+			{
+				can->config.baud_rate = argval;
+				lpccan_baud_set(plpccan->id, (rt_uint32_t) arg);
+			}
+			break;
+		case RT_CAN_CMD_SET_PRIV:
+			argval = (rt_uint32_t) arg;
+			if(argval != RT_CAN_MODE_PRIV ||
+					argval != RT_CAN_MODE_NOPRIV) {
+				return RT_ERROR; 
+			}
+			if(argval != can->config.privmode)
+			{
+				can->config.privmode = argval;
+				CAN_ModeConfig(plpccan->id, CAN_TXPRIORITY_MODE, ENABLE);
+			}
+			break;
+		case RT_CAN_CMD_GET_STATUS:
+			{
+				rt_uint32_t errtype;
+				can->status.rcverrcnt = 0;
+				can->status.snderrcnt = 0;
+				can->status.errcode = 0;
+				if(arg != &can->status) {
+					rt_memcpy(arg,&can->status,sizeof(can->status));
+				}
+			}
+			break;
+	}
+	return RT_EOK;
+}
+static int sendmsg(struct rt_can_device *can, const void* buf, rt_uint32_t boxno)
+{
+	struct lpccandata* plpccan;
+	plpccan = (struct lpccandata* )  can->parent.user_data;
+	RT_ASSERT(plpccan != RT_NULL);
+	LPC_CAN_TypeDef* pCan = lcpcan_get_reg_base(plpccan->id);
+	RT_ASSERT(pCan != RT_NULL);
+	struct rt_can_msg* pmsg = (struct rt_can_msg*) buf;
+	rt_uint32_t SR_Mask;
+	if(boxno > 2) {
+		return RT_ERROR;
+	}
+	rt_uint32_t CMRMsk = 0x01 | (0x01 << (boxno + 5));
+	SR_Mask = 0x01 <<(boxno * 8 + 2);
+	volatile unsigned int  *pTFI = (&pCan->TFI1 + 0 + 4 * boxno);
+	volatile unsigned int  *pTID = (&pCan->TFI1 + 1 + 4 * boxno);
+	volatile unsigned int  *pTDA = (&pCan->TFI1 + 2 + 4 * boxno);
+	volatile unsigned int  *pTDB = (&pCan->TFI1 + 3 + 4 * boxno);
+	rt_uint32_t data;
+	if(pCan->SR & SR_Mask) {
+		/* Transmit Channel 1 is available */
+		/* Write frame informations and frame data into its CANxTFI1,
+		 * CANxTID1, CANxTDA1, CANxTDB1 register */
+		*pTFI &= ~ 0x000F0000;
+		*pTFI |= (pmsg->len) << 16;
+		if(pmsg->rtr == REMOTE_FRAME)
+		{
+			*pTFI |= (1 << 30); //set bit RTR
+		}
+		else
+		{
+			*pTFI &= ~(1 << 30);
+		}
+
+		if(pmsg->ide == EXT_ID_FORMAT)
+		{
+			*pTFI |= (((uint32_t)1) << 31); //set bit FF
+		}
+		else
+		{
+			*pTFI &= ~(((uint32_t)1) << 31);
+		}
+		if(can->config.privmode) {
+			*pTFI &= ~0x000000FF;
+			*pTFI |= pmsg->priv;
+		}
+		/* Write CAN ID*/
+		*pTID = pmsg->id;
+		/*Write first 4 data bytes*/
+		data = (pmsg->data[0]) | (((pmsg->data[1]))<< 8) | ((pmsg->data[2]) << 16) | ((pmsg->data[3]) << 24);
+		*pTDA = data;
+		/*Write second 4 data bytes*/
+		data = (pmsg->data[4]) | (((pmsg->data[5])) << 8) | ((pmsg->data[6]) << 16) | ((pmsg->data[7]) << 24);
+		*pTDB = data;
+		/*Write transmission request*/
+		pCan->CMR = CMRMsk;
+		return RT_EOK;
+	} else {
+		return RT_ERROR;
+	}
+}
+static int recvmsg(struct rt_can_device *can, void* buf, rt_uint32_t boxno)
+{
+	struct lpccandata* plpccan;
+	plpccan = (struct lpccandata* )  can->parent.user_data;
+	RT_ASSERT(plpccan != RT_NULL);
+	LPC_CAN_TypeDef* pCan = lcpcan_get_reg_base(plpccan->id);
+	RT_ASSERT(pCan != RT_NULL);
+	//CAN_ReceiveMsg
+	uint32_t data;
+	struct rt_can_msg* pmsg = (struct rt_can_msg*) buf;
+	//check status of Receive Buffer
+	if((pCan->SR &0x00000001))
+	{
+		/* Receive message is available */
+		/* Read frame informations */
+		pmsg->ide = (uint8_t)(((pCan->RFS) & 0x80000000) >> 31);
+		pmsg->rtr = (uint8_t)(((pCan->RFS) & 0x40000000) >> 30);
+		pmsg->len = (uint8_t)(((pCan->RFS) & 0x000F0000) >> 16);
+		/* Read CAN message identifier */
+		pmsg->id = pCan->RID;
+		/* Read the data if received message was DATA FRAME */
+		if (!pmsg->rtr)
+		{
+			/* Read first 4 data bytes */
+			data = pCan->RDA;
+			pmsg->data[0] = data & 0x000000FF;
+			pmsg->data[1] = (data & 0x0000FF00) >> 8;
+			pmsg->data[2] = (data & 0x00FF0000) >> 16;
+			pmsg->data[3] = (data & 0xFF000000) >> 24;
+			/* Read second 4 data bytes */
+			if(pmsg->len > 4) {
+				data = pCan->RDB;
+				pmsg->data[4] = data & 0x000000FF;
+				pmsg->data[5] = (data & 0x0000FF00) >> 8;
+				pmsg->data[6] = (data & 0x00FF0000) >> 16;
+				pmsg->data[7] = (data & 0xFF000000) >> 24;
+			}
+			pmsg->hdr = 0;
+			/*release receive buffer*/
+			pCan->CMR = 0x04;
+		}
+		else
+		{
+			/* Received Frame is a Remote Frame, not have data, we just receive
+			 * message information only */
+			pCan->CMR = 0x04; /*release receive buffer*/
+			return SUCCESS;
+		}
+	}
+	else
+	{
+		// no receive message available
+		return ERROR;
+	}
+	return RT_EOK;
+}
+
+static const struct rt_can_ops canops =
+{
+	configure,
+	control,
+	sendmsg,
+	recvmsg,
+};
+#ifdef RT_USING_LPCCAN1
+#ifdef RT_CAN_USING_LED
+#endif
+static struct lpccandata lpccandata1 = {
+		CAN_1,
+};
+static struct rt_can_device lpccan1;
+#endif /*RT_USINGLPCCAN1*/
+
+#ifdef RT_USING_LPCCAN2
+#ifdef RT_CAN_USING_LED
+#endif
+static struct lpccandata lpccandata2 = {
+		CAN_2,
+};
+static struct rt_can_device lpccan2;
+#endif /*RT_USINGLPCCAN2*/
+/*----------------- INTERRUPT SERVICE ROUTINES --------------------------*/
+/*********************************************************************//**
+ * @brief        Event Router IRQ Handler
+ * @param[in]    None
+ * @return       None
+ **********************************************************************/
+void CAN_IRQHandler(void)
+{
+	rt_uint32_t IntStatus;
+#ifdef RT_USING_LPCCAN1
+	IntStatus = CAN_IntGetStatus(CAN_1);
+	//check receive interrupt
+	if((IntStatus >> 0) & 0x01)
+	{
+		rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_RX_IND | 0<<8); 
+	}
+	//check Transmit Interrupt  interrupt1
+	if((IntStatus >> 1) & 0x01)
+	{
+		rt_uint32_t state = 0;
+		state = CAN_GetCTRLStatus(CAN_1, CANCTRL_STS);
+		if(state & (0x01 << 3))
+		{
+			rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 0<<8);
+		} else {
+			rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 0<<8);
+		}
+	}
+	//check Error Warning Interrupt
+	if((IntStatus >> 2) & 0x01)
+	{
+		rt_uint32_t errtype;
+		errtype = (IntStatus >> 16);
+		if(errtype & 0x1F && lpccan1.status.lasterrtype == (errtype & 0x1F)) {
+			switch((errtype & 0x1F)) {
+				case 00011: // Start of Frame
+				case 00010: // ID28 ... ID21
+				case 00110: //ID20 ... ID18
+				case 00100: // SRTR Bit
+				case 00101: // IDE bit
+				case 00111: // ID17 ... 13
+				case 01111: // ID12 ... ID5
+				case 01110: // ID4 ... ID0
+				case 01100: // RTR Bit
+				case 01011: // Data Length Code
+				case 01010: // Data Field
+					lpccan1.status.formaterrcnt++;
+					break;
+				case 01101: // Reserved Bit 1
+				case 01001: // Reserved Bit 0
+					lpccan1.status.bitpaderrcnt++;
+					break;
+				case 01000: // CRC Sequence
+				case 11000: // CRC Delimiter
+					lpccan1.status.crcerrcnt++;
+					break;
+				case 11001: // Acknowledge Slot
+				case 11011: // Acknowledge Delimiter
+					lpccan1.status.ackerrcnt++;
+					break;
+				case 11010: // End of Frame
+				case 10010: // Intermission
+					lpccan1.status.formaterrcnt++;
+					break;
+			}
+			lpccan1.status.lasterrtype = errtype & 0x1F;
+		}
+		rt_uint32_t state = 0;
+		state = CAN_GetCTRLStatus(CAN_1, CANCTRL_GLOBAL_STS);
+		lpccan1.status.rcverrcnt = (state >> 16) & 0xFF;
+		lpccan1.status.snderrcnt = (state >> 24) & 0xFF;
+		lpccan1.status.errcode = (state >> 5) & 0x06;
+	}
+	//check Data Overrun Interrupt Interrupt
+	if((IntStatus >> 3) & 0x01)
+	{
+		rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_RXOF_IND | 0<<8);
+	}
+	//check Transmit Interrupt  interrupt2
+	if((IntStatus >> 9) & 0x01)
+	{
+		rt_uint32_t state = 0;
+		state = CAN_GetCTRLStatus(CAN_1, CANCTRL_STS);
+		if(state & (0x01 << 11))
+		{
+			rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 1<<8);
+		} else {
+			rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 1<<8);
+		}
+	}
+	//check Transmit Interrupt  interrupt3
+	if((IntStatus >> 10) & 0x01)
+	{
+		rt_uint32_t state = 0;
+		state = CAN_GetCTRLStatus(CAN_1, CANCTRL_STS);
+		if(state & (0x01 << 19))
+		{
+			rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 2<<8);
+		} else {
+			rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 2<<8);
+		}
+	}
+#endif /*RT_USING_LPCCAN1*/
+#ifdef RT_USING_LPCCAN2
+	IntStatus = CAN_IntGetStatus(CAN_2);
+	//check receive interrupt
+	if((IntStatus >> 0) & 0x01)
+	{
+		rt_hw_can_isr(&lpccan2,RT_CAN_EVENT_RX_IND | 0<<8); 
+	}
+	//check Transmit Interrupt  interrupt1
+	if((IntStatus >> 1) & 0x01)
+	{
+		rt_uint32_t state = 0;
+		state = CAN_GetCTRLStatus(CAN_2, CANCTRL_STS);
+		if(state & (0x01 << 3))
+		{
+			rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 0<<8);
+		} else {
+			rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 0<<8);
+		}
+	}
+	//check Error Warning Interrupt
+	if((IntStatus >> 2) & 0x01)
+	{
+		rt_uint32_t errtype;
+		errtype = (IntStatus >> 16);
+		if(errtype & 0x1F && lpccan2.status.lasterrtype == (errtype & 0x1F)) {
+			switch((errtype & 0x1F)) {
+				case 00011: // Start of Frame
+				case 00010: // ID28 ... ID21
+				case 00110: //ID20 ... ID18
+				case 00100: // SRTR Bit
+				case 00101: // IDE bit
+				case 00111: // ID17 ... 13
+				case 01111: // ID12 ... ID5
+				case 01110: // ID4 ... ID0
+				case 01100: // RTR Bit
+				case 01011: // Data Length Code
+				case 01010: // Data Field
+					lpccan2.status.formaterrcnt++;
+					break;
+				case 01101: // Reserved Bit 1
+				case 01001: // Reserved Bit 0
+					lpccan2.status.bitpaderrcnt++;
+					break;
+				case 01000: // CRC Sequence
+				case 11000: // CRC Delimiter
+					lpccan2.status.crcerrcnt++;
+					break;
+				case 11001: // Acknowledge Slot
+				case 11011: // Acknowledge Delimiter
+					lpccan2.status.ackerrcnt++;
+					break;
+				case 11010: // End of Frame
+				case 10010: // Intermission
+					lpccan2.status.formaterrcnt++;
+					break;
+			}
+			lpccan2.status.lasterrtype = errtype & 0x1F;
+		}
+		rt_uint32_t state = 0;
+		state = CAN_GetCTRLStatus(CAN_2, CANCTRL_GLOBAL_STS);
+		lpccan2.status.rcverrcnt = (state >> 16) & 0xFF;
+		lpccan2.status.snderrcnt = (state >> 24) & 0xFF;
+		lpccan2.status.errcode = (state >> 5) & 0x06;
+	}
+	//check Data Overrun Interrupt Interrupt
+	if((IntStatus >> 3) & 0x01)
+	{
+		rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_RXOF_IND | 0<<8);
+	}
+	//check Transmit Interrupt  interrupt2
+	if((IntStatus >> 9) & 0x01)
+	{
+		rt_uint32_t state = 0;
+		state = CAN_GetCTRLStatus(CAN_2, CANCTRL_STS);
+		if(state & (0x01 << 11))
+		{
+			rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 1<<8);
+		} else {
+			rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 1<<8);
+		}
+	}
+	//check Transmit Interrupt  interrupt3
+	if((IntStatus >> 10) & 0x01)
+	{
+		rt_uint32_t state = 0;
+		state = CAN_GetCTRLStatus(CAN_2, CANCTRL_STS);
+		if(state & (0x01 << 19))
+		{
+			rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 2<<8);
+		} else {
+			rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 2<<8);
+		}
+	}
+#endif /*RT_USING_LPCCAN2*/
+}
+int lpc_can_init(void)
+{
+#ifdef RT_USING_LPCCAN1
+	lpccan1.config.baud_rate=CAN1MBaud;
+	lpccan1.config.msgboxsz=16;
+	lpccan1.config.sndboxnumber=3;
+	lpccan1.config.mode=RT_CAN_MODE_NORMAL;
+	lpccan1.config.privmode=0;
+#ifdef RT_CAN_USING_LED
+#endif
+	lpccan1.config.ticks = 50;
+#ifdef RT_CAN_USING_HDR
+#endif
+	//Enable CAN Interrupt
+	NVIC_EnableIRQ(CAN_IRQn);
+	rt_hw_can_register(&lpccan1, "lpccan1", &canops, &lpccandata1);
+#endif
+
+#ifdef RT_USING_LPCCAN2
+	lpccan2.config.baud_rate=CAN1MBaud;
+	lpccan2.config.msgboxsz=16;
+	lpccan2.config.sndboxnumber=3;
+	lpccan2.config.mode=RT_CAN_MODE_NORMAL;
+	lpccan2.config.privmode=0;
+#ifdef RT_CAN_USING_LED
+#endif			
+	lpccan2.config.ticks = 50;
+#ifdef RT_CAN_USING_HDR
+#endif
+#ifndef RT_USING_LPCCAN1
+	//Enable CAN Interrupt
+	NVIC_EnableIRQ(CAN_IRQn);
+#endif
+#ifdef RT_CAN_USING_HDR
+#endif
+	rt_hw_can_register(&lpccan2, "lpccan2", &canops, &lpccandata2);
+#endif
+	return RT_EOK;
+}
+INIT_BOARD_EXPORT(lpc_can_init);
+
+#endif /*RT_USING_CAN*/

+ 29 - 0
bsp/lpc408x/drivers/drv_lpccan.h

@@ -0,0 +1,29 @@
+/*
+ * File      : drv_lpccan.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2015, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2015-06-30     aubrcool@qq.com first version
+ */
+
+#ifndef DRV_LPCCAN_H_
+#define DRV_LPCCAN_H_
+#include <rthw.h>
+#include <rtdevice.h>
+
+#define LPC_CAN_AF_STD_INIT(id) \
+     RT_CAN_FILTER_ITEM_INIT(id,0,0,0,0xFFFFFFFF)
+#define LPC_CAN_AF_EXT_INIT(id) \
+     RT_CAN_FILTER_ITEM_INIT(id,1,0,0,0xFFFFFFFF)
+#define LPC_CAN_AF_STD_GRP_INIT(id1,id2) \
+     RT_CAN_FILTER_ITEM_INIT(id1,0,0,1,id2)
+#define LPC_CAN_AF_EXT_GRP_INIT(id1,id2) \
+     RT_CAN_FILTER_ITEM_INIT(id1,1,0,1,id2)
+
+#endif /*DRV_LPCCAN_H_*/

+ 129 - 218
bsp/lpc408x/project.uvproj → bsp/lpc408x/project.uvprojx

@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
-<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_proj.xsd">
-  <SchemaVersion>1.1</SchemaVersion>
+<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
+
+  <SchemaVersion>2.1</SchemaVersion>
+
   <Header>### uVision Project, (C) Keil Software</Header>
+
   <Targets>
     <Target>
       <TargetName>RT-Thread LPC408x</TargetName>
@@ -9,30 +12,33 @@
       <ToolsetName>ARM-ADS</ToolsetName>
       <TargetOption>
         <TargetCommonOption>
-          <Device>LPC4088</Device>
-          <Vendor>NXP (founded by Philips)</Vendor>
-          <Cpu>IRAM(0x10000000-0x1000FFFF) IRAM2(0x20000000-0x20007FFF) IROM(0-0x7FFFF) CLOCK(12000000) CPUTYPE("Cortex-M4") FPU2</Cpu>
-          <FlashUtilSpec />
-          <StartupFile>"STARTUP\NXP\LPC407x_8x_177x_8x\startup_LPC407x_8x_177x_8x.s" ("NXP LPC407x_8x_177x_8x Startup Code")</StartupFile>
-          <FlashDriverDll>UL2CM3(-O4303 -S0 -C0 -FO7 -FD10000000 -FC800 -FN1 -FF0LPC_IAP_512 -FS00 -FL080000)</FlashDriverDll>
-          <DeviceId>6493</DeviceId>
-          <RegisterFile>LPC407x_8x_177x_8x.h</RegisterFile>
-          <MemoryEnv />
-          <Cmp />
-          <Asm />
-          <Linker />
-          <OHString />
-          <InfinionOptionDll />
-          <SLE66CMisc />
-          <SLE66AMisc />
-          <SLE66LinkerMisc />
-          <SFDFile>SFD\NXP\LPC407x_8x_177x_8x\LPC408x_7x.SFR</SFDFile>
+          <Device>LPC4088FBD208</Device>
+          <Vendor>NXP</Vendor>
+          <PackID>Keil.LPC4000_DFP.1.1.0</PackID>
+          <PackURL>http://www.keil.com/pack/</PackURL>
+          <Cpu>IROM(0x00000000,0x80000) IRAM(0x10000000,0x10000) IRAM2(0x20000000,0x8000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
+          <FlashUtilSpec></FlashUtilSpec>
+          <StartupFile></StartupFile>
+          <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD10000000 -FCFE0 -FN1 -FF0LPC_IAP_512 -FS00 -FL080000 -FP0($$Device:LPC4088FBD208$Flash\LPC_IAP_512.FLM))</FlashDriverDll>
+          <DeviceId>0</DeviceId>
+          <RegisterFile>$$Device:LPC4088FBD208$Device\Include\LPC407x_8x_177x_8x.h</RegisterFile>
+          <MemoryEnv></MemoryEnv>
+          <Cmp></Cmp>
+          <Asm></Asm>
+          <Linker></Linker>
+          <OHString></OHString>
+          <InfinionOptionDll></InfinionOptionDll>
+          <SLE66CMisc></SLE66CMisc>
+          <SLE66AMisc></SLE66AMisc>
+          <SLE66LinkerMisc></SLE66LinkerMisc>
+          <SFDFile>$$Device:LPC4088FBD208$SVD\LPC408x_7x.svd</SFDFile>
+          <bCustSvd>0</bCustSvd>
           <UseEnv>0</UseEnv>
-          <BinPath />
-          <IncludePath />
-          <LibPath />
-          <RegisterFilePath>NXP\LPC407x_8x_177x_8x\</RegisterFilePath>
-          <DBRegisterFilePath>NXP\LPC407x_8x_177x_8x\</DBRegisterFilePath>
+          <BinPath></BinPath>
+          <IncludePath></IncludePath>
+          <LibPath></LibPath>
+          <RegisterFilePath></RegisterFilePath>
+          <DBRegisterFilePath></DBRegisterFilePath>
           <TargetStatus>
             <Error>0</Error>
             <ExitCodeStop>0</ExitCodeStop>
@@ -54,8 +60,8 @@
           <BeforeCompile>
             <RunUserProg1>0</RunUserProg1>
             <RunUserProg2>0</RunUserProg2>
-            <UserProg1Name />
-            <UserProg2Name />
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
             <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
             <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
             <nStopU1X>0</nStopU1X>
@@ -64,21 +70,25 @@
           <BeforeMake>
             <RunUserProg1>0</RunUserProg1>
             <RunUserProg2>0</RunUserProg2>
-            <UserProg1Name />
-            <UserProg2Name />
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
             <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
             <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopB1X>0</nStopB1X>
+            <nStopB2X>0</nStopB2X>
           </BeforeMake>
           <AfterMake>
             <RunUserProg1>0</RunUserProg1>
             <RunUserProg2>0</RunUserProg2>
-            <UserProg1Name />
-            <UserProg2Name />
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
             <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
             <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+            <nStopA1X>0</nStopA1X>
+            <nStopA2X>0</nStopA2X>
           </AfterMake>
           <SelectedForBatchBuild>0</SelectedForBatchBuild>
-          <SVCSIdString />
+          <SVCSIdString></SVCSIdString>
         </TargetCommonOption>
         <CommonProperty>
           <UseCPPCompiler>0</UseCPPCompiler>
@@ -92,16 +102,17 @@
           <AssembleAssemblyFile>0</AssembleAssemblyFile>
           <PublicsOnly>0</PublicsOnly>
           <StopOnExitCode>3</StopOnExitCode>
-          <CustomArgument />
-          <IncludeLibraryModules />
+          <CustomArgument></CustomArgument>
+          <IncludeLibraryModules></IncludeLibraryModules>
+          <ComprImg>1</ComprImg>
         </CommonProperty>
         <DllOption>
           <SimDllName>SARMCM3.DLL</SimDllName>
-          <SimDllArguments>-MPU</SimDllArguments>
+          <SimDllArguments>  -MPU</SimDllArguments>
           <SimDlgDll>DCM.DLL</SimDlgDll>
           <SimDlgDllArguments>-pCM4</SimDlgDllArguments>
           <TargetDllName>SARMCM3.DLL</TargetDllName>
-          <TargetDllArguments>-MPU</TargetDllArguments>
+          <TargetDllArguments> -MPU</TargetDllArguments>
           <TargetDlgDll>TCM.DLL</TargetDlgDll>
           <TargetDlgDllArguments>-pCM4</TargetDlgDllArguments>
         </DllOption>
@@ -123,33 +134,35 @@
             <RestoreFunctions>1</RestoreFunctions>
             <RestoreToolbox>1</RestoreToolbox>
             <LimitSpeedToRealTime>0</LimitSpeedToRealTime>
+            <RestoreSysVw>1</RestoreSysVw>
           </Simulator>
           <Target>
             <UseTarget>1</UseTarget>
             <LoadApplicationAtStartup>1</LoadApplicationAtStartup>
-            <RunToMain>0</RunToMain>
+            <RunToMain>1</RunToMain>
             <RestoreBreakpoints>1</RestoreBreakpoints>
             <RestoreWatchpoints>1</RestoreWatchpoints>
             <RestoreMemoryDisplay>1</RestoreMemoryDisplay>
             <RestoreFunctions>0</RestoreFunctions>
             <RestoreToolbox>1</RestoreToolbox>
             <RestoreTracepoints>0</RestoreTracepoints>
+            <RestoreSysVw>1</RestoreSysVw>
           </Target>
           <RunDebugAfterBuild>0</RunDebugAfterBuild>
-          <TargetSelection>7</TargetSelection>
+          <TargetSelection>6</TargetSelection>
           <SimDlls>
-            <CpuDll />
-            <CpuDllArguments />
-            <PeripheralDll />
-            <PeripheralDllArguments />
-            <InitializationFile />
+            <CpuDll></CpuDll>
+            <CpuDllArguments></CpuDllArguments>
+            <PeripheralDll></PeripheralDll>
+            <PeripheralDllArguments></PeripheralDllArguments>
+            <InitializationFile></InitializationFile>
           </SimDlls>
           <TargetDlls>
-            <CpuDll />
-            <CpuDllArguments />
-            <PeripheralDll />
-            <PeripheralDllArguments />
-            <InitializationFile />
+            <CpuDll></CpuDll>
+            <CpuDllArguments></CpuDllArguments>
+            <PeripheralDll></PeripheralDll>
+            <PeripheralDllArguments></PeripheralDllArguments>
+            <InitializationFile></InitializationFile>
             <Driver>Segger\JL2CM3.dll</Driver>
           </TargetDlls>
         </DebugOption>
@@ -158,14 +171,18 @@
             <UseTargetDll>1</UseTargetDll>
             <UseExternalTool>0</UseExternalTool>
             <RunIndependent>0</RunIndependent>
-            <UpdateFlashBeforeDebugging>0</UpdateFlashBeforeDebugging>
+            <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
             <Capability>1</Capability>
             <DriverSelection>4099</DriverSelection>
           </Flash1>
-          <bUseTDR>0</bUseTDR>
+          <bUseTDR>1</bUseTDR>
           <Flash2>Segger\JL2CM3.dll</Flash2>
           <Flash3>"" ()</Flash3>
-          <Flash4 />
+          <Flash4></Flash4>
+          <pFcarmOut></pFcarmOut>
+          <pFcarmGrp></pFcarmGrp>
+          <pFcArmRoot></pFcArmRoot>
+          <FcArmLst>0</FcArmLst>
         </Utilities>
         <TargetArmAds>
           <ArmAdsMisc>
@@ -197,7 +214,7 @@
             <RvctClst>0</RvctClst>
             <GenPPlst>0</GenPPlst>
             <AdsCpuType>"Cortex-M4"</AdsCpuType>
-            <RvctDeviceName />
+            <RvctDeviceName></RvctDeviceName>
             <mOS>0</mOS>
             <uocRom>0</uocRom>
             <uocRam>0</uocRam>
@@ -328,7 +345,7 @@
                 <Size>0x8000</Size>
               </OCR_RVCT10>
             </OnChipMemories>
-            <RvctStartVector />
+            <RvctStartVector></RvctStartVector>
           </ArmAdsMisc>
           <Cads>
             <interw>1</interw>
@@ -344,10 +361,14 @@
             <wLevel>0</wLevel>
             <uThumb>0</uThumb>
             <uSurpInc>0</uSurpInc>
+            <uC99>1</uC99>
+            <useXO>0</useXO>
+            <v6Lang>0</v6Lang>
+            <v6LangP>0</v6LangP>
             <VariousControls>
-              <MiscControls />
+              <MiscControls></MiscControls>
               <Define>CORE_M4, RT_USING_ARM_LIBC</Define>
-              <Undefine />
+              <Undefine></Undefine>
               <IncludePath>Libraries/Device/NXP/LPC407x_8x_177x_8x/Include;Libraries/CMSIS/Include;Libraries/Drivers/include;applications;.;drivers;../../include;../../libcpu/arm/cortex-m4;../../libcpu/arm/common;../../components/pthreads;../../components/libc/armlibc;../../components/drivers/include;../../components/drivers/include;../../components/finsh</IncludePath>
             </VariousControls>
           </Cads>
@@ -360,11 +381,12 @@
             <SwStkChk>0</SwStkChk>
             <NoWarn>0</NoWarn>
             <uSurpInc>0</uSurpInc>
+            <useXO>0</useXO>
             <VariousControls>
-              <MiscControls />
-              <Define />
-              <Undefine />
-              <IncludePath />
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
             </VariousControls>
           </Aads>
           <LDads>
@@ -376,12 +398,13 @@
             <useFile>0</useFile>
             <TextAddressRange>0x00000000</TextAddressRange>
             <DataAddressRange>0x10000000</DataAddressRange>
-            <ScatterFile />
-            <IncludeLibs />
-            <IncludeLibsPath />
+            <pXoBase></pXoBase>
+            <ScatterFile></ScatterFile>
+            <IncludeLibs></IncludeLibs>
+            <IncludeLibsPath></IncludeLibsPath>
             <Misc> --keep *.o(.rti_fn.*)   --keep *.o(FSymTab) --keep *.o(VSymTab) </Misc>
-            <LinkerInputFile />
-            <DisabledWarnings />
+            <LinkerInputFile></LinkerInputFile>
+            <DisabledWarnings></DisabledWarnings>
           </LDads>
         </TargetArmAds>
       </TargetOption>
@@ -394,8 +417,6 @@
               <FileType>1</FileType>
               <FilePath>Libraries/Device/NXP/LPC407x_8x_177x_8x/Source/Templates/system_LPC407x_8x_177x_8x.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>startup_LPC407x_8x_177x_8x.s</FileName>
               <FileType>2</FileType>
@@ -411,176 +432,126 @@
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_adc.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_bod.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_bod.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_can.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_can.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_clkpwr.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_clkpwr.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_crc.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_crc.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_dac.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_dac.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_eeprom.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_eeprom.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_emc.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_emc.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_exti.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_exti.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_gpdma.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_gpdma.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_gpio.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_gpio.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_i2c.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_i2c.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_i2s.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_i2s.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_iap.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_iap.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_lcd.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_lcd.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_mcpwm.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_mcpwm.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_nvic.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_nvic.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_pinsel.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_pinsel.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_pwm.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_pwm.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_qei.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_qei.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_rtc.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_rtc.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_ssp.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_ssp.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_systick.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_systick.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_timer.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_timer.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_uart.c</FileName>
               <FileType>1</FileType>
               <FilePath>Libraries/Drivers/source/lpc_uart.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>lpc_wwdt.c</FileName>
               <FileType>1</FileType>
@@ -596,27 +567,26 @@
               <FileType>1</FileType>
               <FilePath>applications/application.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>board.c</FileName>
               <FileType>1</FileType>
               <FilePath>applications/board.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>sram.c</FileName>
               <FileType>1</FileType>
               <FilePath>applications/sram.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>startup.c</FileName>
               <FileType>1</FileType>
               <FilePath>applications/startup.c</FilePath>
             </File>
+            <File>
+              <FileName>canapp.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\applications\canapp.c</FilePath>
+            </File>
           </Files>
         </Group>
         <Group>
@@ -627,13 +597,16 @@
               <FileType>1</FileType>
               <FilePath>drivers/drv_led.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>drv_uart.c</FileName>
               <FileType>1</FileType>
               <FilePath>drivers/drv_uart.c</FilePath>
             </File>
+            <File>
+              <FileName>drv_lpccan.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>.\drivers\drv_lpccan.c</FilePath>
+            </File>
           </Files>
         </Group>
         <Group>
@@ -644,92 +617,66 @@
               <FileType>1</FileType>
               <FilePath>../../src/clock.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>components.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../src/components.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>device.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../src/device.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>idle.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../src/idle.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>ipc.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../src/ipc.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>irq.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../src/irq.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>kservice.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../src/kservice.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>mem.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../src/mem.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>memheap.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../src/memheap.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>mempool.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../src/mempool.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>object.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../src/object.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>scheduler.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../src/scheduler.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>thread.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../src/thread.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>timer.c</FileName>
               <FileType>1</FileType>
@@ -745,29 +692,21 @@
               <FileType>1</FileType>
               <FilePath>../../libcpu/arm/cortex-m4/cpuport.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>context_rvds.S</FileName>
               <FileType>2</FileType>
               <FilePath>../../libcpu/arm/cortex-m4/context_rvds.S</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>backtrace.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../libcpu/arm/common/backtrace.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>div0.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../libcpu/arm/common/div0.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>showmem.c</FileName>
               <FileType>1</FileType>
@@ -783,78 +722,56 @@
               <FileType>1</FileType>
               <FilePath>../../components/pthreads/clock_time.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>mqueue.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/pthreads/mqueue.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>pthread.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/pthreads/pthread.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>pthread_attr.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/pthreads/pthread_attr.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>pthread_barrier.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/pthreads/pthread_barrier.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>pthread_cond.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/pthreads/pthread_cond.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>pthread_mutex.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/pthreads/pthread_mutex.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>pthread_rwlock.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/pthreads/pthread_rwlock.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>pthread_spin.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/pthreads/pthread_spin.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>pthread_tls.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/pthreads/pthread_tls.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>sched.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/pthreads/sched.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>semaphore.c</FileName>
               <FileType>1</FileType>
@@ -870,8 +787,6 @@
               <FileType>1</FileType>
               <FilePath>../../components/libc/armlibc/mem_std.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>stubs.c</FileName>
               <FileType>1</FileType>
@@ -887,48 +802,41 @@
               <FileType>1</FileType>
               <FilePath>../../components/drivers/serial/serial.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>completion.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/drivers/src/completion.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>dataqueue.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/drivers/src/dataqueue.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>pipe.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/drivers/src/pipe.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>portal.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/drivers/src/portal.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>ringbuffer.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/drivers/src/ringbuffer.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>workqueue.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/drivers/src/workqueue.c</FilePath>
             </File>
+            <File>
+              <FileName>can.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\drivers\can\can.c</FilePath>
+            </File>
           </Files>
         </Group>
         <Group>
@@ -939,93 +847,96 @@
               <FileType>1</FileType>
               <FilePath>../../components/finsh/shell.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>symbol.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/finsh/symbol.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>cmd.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/finsh/cmd.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>finsh_compiler.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/finsh/finsh_compiler.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>finsh_error.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/finsh/finsh_error.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>finsh_heap.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/finsh/finsh_heap.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>finsh_init.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/finsh/finsh_init.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>finsh_node.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/finsh/finsh_node.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>finsh_ops.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/finsh/finsh_ops.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>finsh_parser.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/finsh/finsh_parser.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>finsh_var.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/finsh/finsh_var.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>finsh_vm.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/finsh/finsh_vm.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>finsh_token.c</FileName>
               <FileType>1</FileType>
               <FilePath>../../components/finsh/finsh_token.c</FilePath>
             </File>
+            <File>
+              <FileName>msh.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\msh.c</FilePath>
+            </File>
+            <File>
+              <FileName>msh_cmd.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\components\finsh\msh_cmd.c</FilePath>
+            </File>
           </Files>
         </Group>
+        <Group>
+          <GroupName>::CMSIS</GroupName>
+        </Group>
       </Groups>
     </Target>
   </Targets>
+
+  <RTE>
+    <apis/>
+    <components>
+      <component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="4.1.0" condition="CMSIS Core">
+        <package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="4.3.0"/>
+        <targetInfos>
+          <targetInfo name="RT-Thread LPC408x"/>
+        </targetInfos>
+      </component>
+    </components>
+    <files/>
+  </RTE>
+
 </Project>

+ 4 - 1
bsp/lpc408x/rtconfig.h

@@ -72,6 +72,7 @@
 #define RT_USING_DEVICE_IPC
 // <bool name="RT_USING_SERIAL" description="Using Serial Device Driver Framework" default="true" />
 #define RT_USING_SERIAL
+#define RT_USING_CAN
 // <integer name="RT_UART_RX_BUFFER_SIZE" description="The buffer size for UART reception" default="64" />
 #define RT_UART_RX_BUFFER_SIZE    64
 // </section>
@@ -95,6 +96,7 @@
 #define RT_USING_COMPONENTS_INIT
 // <section name="RT_USING_FINSH" description="Using finsh as shell, which is a C-Express shell" default="true" >
 #define RT_USING_FINSH
+#define FINSH_USING_MSH
 // <bool name="FINSH_USING_SYMTAB" description="Using symbol table in finsh shell" default="true" />
 #define FINSH_USING_SYMTAB
 // <bool name="FINSH_USING_DESCRIPTION" description="Keeping description in symbol table" default="true" />
@@ -236,5 +238,6 @@
 // </section>
 
 // </RDTConfigurator>
-
+#define  RT_USING_LPCCAN1
+#define RT_USING_CPU_FFS
 #endif

+ 1 - 1
bsp/stm32f10x/drivers/bxcan.c

@@ -16,7 +16,7 @@
 #include <board.h>
 #include <bxcan.h>
 #ifdef RT_USING_COMPONENTS_INIT
-#include <init/components.h>
+#include <components.h>
 #endif
 #ifdef RT_USING_CAN
 

+ 11 - 12
components/drivers/can/can.c

@@ -607,11 +607,15 @@ static rt_err_t rt_can_control(struct rt_device *dev,
  */
 static void cantimeout(void* arg)
 {
+		 #ifdef RT_CAN_USING_LED
      rt_uint32_t ledonflag = 0;
+		 #endif /*RT_CAN_USING_LED*/
      rt_can_t can = (rt_can_t)arg;
      rt_device_control((rt_device_t)can,RT_CAN_CMD_GET_STATUS,(void* )&can->status);
      if(can->timerinitflag == 1) {
-         ledonflag = 1;
+			 	 #ifdef RT_CAN_USING_LED
+				 ledonflag = 1;
+				 #endif /*RT_CAN_USING_LED*/
          can->timerinitflag = 0xFF;
      }
      #ifdef RT_CAN_USING_LED
@@ -713,17 +717,12 @@ rt_err_t rt_hw_can_register(struct rt_can_device *can,
 
     device->user_data   = data;
     can->timerinitflag = 0;
-    if(can->config.rcvled != RT_NULL ||
-       can->config.sndled != RT_NULL ||
-       can->config.errled != RT_NULL)
-    {
-        rt_timer_init(&can->timer,
-                  name,
-                  cantimeout,
-                  (void*)can,
-                  can->config.ticks,
-                  RT_TIMER_FLAG_PERIODIC);
-    }
+		rt_timer_init(&can->timer,
+							name,
+							cantimeout,
+							(void*)can,
+							can->config.ticks,
+							RT_TIMER_FLAG_PERIODIC);
     /* register a character device */
     return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
 }

+ 18 - 15
components/drivers/include/drivers/can.h

@@ -14,6 +14,8 @@
 #ifndef CAN_H_
 #define CAN_H_
 
+#include <rtthread.h>
+
 #ifndef RT_CANMSG_BOX_SZ
 #define RT_CANMSG_BOX_SZ 16
 #endif
@@ -58,8 +60,10 @@ struct rt_can_filter_item
         rt_uint32_t mode :1;
         rt_uint32_t mask;
         rt_int32_t hdr;
+#ifdef RT_CAN_USING_HDR
         rt_err_t  (*ind)(rt_device_t dev, void* args ,rt_int32_t hdr, rt_size_t size);
-        void* args;
+	      void* args;
+#endif /*RT_CAN_USING_HDR*/
 };
 #ifdef RT_CAN_USING_HDR
 #define RT_CAN_FILTER_ITEM_INIT(id,ide,rtr,mode,mask,ind,args) \
@@ -86,7 +90,7 @@ struct rt_can_filter_item
 #define RT_CAN_EXT_RMT_DATA_FILTER_INIT(id,ind,args) \
      RT_CAN_FILTER_ITEM_INIT(id,1,0,1,0xFFFFFFFF,ind,args)
 #else
-#define RT_CAN_FILTER_ITEM_INIT(id,ide,rtr,mode,mask,args) \
+#define RT_CAN_FILTER_ITEM_INIT(id,ide,rtr,mode,mask) \
      {\
          id,\
          ide,\
@@ -94,20 +98,19 @@ struct rt_can_filter_item
          mode,\
          mask,\
          -1,\
-         args,\
      }
-#define RT_CAN_FILTER_STD_INIT(id,args) \
-     RT_CAN_FILTER_ITEM_INIT(id,0,0,0,0xFFFFFFFF,args)
-#define RT_CAN_FILTER_EXT_INIT(id,args) \
-     RT_CAN_FILTER_ITEM_INIT(id,1,0,0,0xFFFFFFFF,args)
-#define RT_CAN_STD_RMT_FILTER_INIT(id,args) \
-     RT_CAN_FILTER_ITEM_INIT(id,0,1,0,0xFFFFFFFF,args)
-#define RT_CAN_EXT_RMT_FILTER_INIT(id,args) \
-     RT_CAN_FILTER_ITEM_INIT(id,1,1,0,0xFFFFFFFF,args)
-#define RT_CAN_STD_RMT_DATA_FILTER_INIT(id,args) \
-     RT_CAN_FILTER_ITEM_INIT(id,0,0,1,0xFFFFFFFF,args)
-#define RT_CAN_EXT_RMT_DATA_FILTER_INIT(id,args) \
-     RT_CAN_FILTER_ITEM_INIT(id,1,0,1,0xFFFFFFFF,args)
+#define RT_CAN_FILTER_STD_INIT(id) \
+     RT_CAN_FILTER_ITEM_INIT(id,0,0,0,0xFFFFFFFF)
+#define RT_CAN_FILTER_EXT_INIT(id) \
+     RT_CAN_FILTER_ITEM_INIT(id,1,0,0,0xFFFFFFFF)
+#define RT_CAN_STD_RMT_FILTER_INIT(id) \
+     RT_CAN_FILTER_ITEM_INIT(id,0,1,0,0xFFFFFFFF)
+#define RT_CAN_EXT_RMT_FILTER_INIT(id) \
+     RT_CAN_FILTER_ITEM_INIT(id,1,1,0,0xFFFFFFFF)
+#define RT_CAN_STD_RMT_DATA_FILTER_INIT(id) \
+     RT_CAN_FILTER_ITEM_INIT(id,0,0,1,0xFFFFFFFF)
+#define RT_CAN_EXT_RMT_DATA_FILTER_INIT(id) \
+     RT_CAN_FILTER_ITEM_INIT(id,1,0,1,0xFFFFFFFF)
 #endif
 
 struct rt_can_filter_config