summaryrefslogtreecommitdiff
path: root/bsp/lpc408x/drivers
diff options
context:
space:
mode:
authormisonyo <[email protected]>2019-03-08 15:02:46 +0800
committermisonyo <[email protected]>2019-03-08 15:02:46 +0800
commit01671090a79b598ee2b185ff8661f32edac8bc77 (patch)
tree2544573a9a36832ea1c460d3b3d4d0baaa16690a /bsp/lpc408x/drivers
parent60b15494ac246ac277853a42128e0941ebfc43ac (diff)
[bsp/lpc408x]更新旧启动机制
Diffstat (limited to 'bsp/lpc408x/drivers')
-rw-r--r--bsp/lpc408x/drivers/Kconfig58
-rw-r--r--bsp/lpc408x/drivers/SConscript24
-rw-r--r--bsp/lpc408x/drivers/board.c68
-rw-r--r--bsp/lpc408x/drivers/board.h50
-rw-r--r--bsp/lpc408x/drivers/drv_emac.c4
-rw-r--r--bsp/lpc408x/drivers/drv_emac.h9
-rw-r--r--bsp/lpc408x/drivers/drv_hwtimer.c11
-rw-r--r--bsp/lpc408x/drivers/drv_hwtimer.h18
-rw-r--r--bsp/lpc408x/drivers/drv_led.c5
-rw-r--r--bsp/lpc408x/drivers/drv_led.h16
-rw-r--r--bsp/lpc408x/drivers/drv_lpccan.c1086
-rw-r--r--bsp/lpc408x/drivers/drv_lpccan.h25
-rw-r--r--bsp/lpc408x/drivers/drv_sdram.c68
-rw-r--r--bsp/lpc408x/drivers/drv_sdram.h23
-rw-r--r--bsp/lpc408x/drivers/drv_uart.c136
-rw-r--r--bsp/lpc408x/drivers/drv_uart.h4
-rw-r--r--bsp/lpc408x/drivers/linker_scripts/link.lds161
-rw-r--r--bsp/lpc408x/drivers/linker_scripts/link.sct15
18 files changed, 464 insertions, 1317 deletions
diff --git a/bsp/lpc408x/drivers/Kconfig b/bsp/lpc408x/drivers/Kconfig
index 248cbb088f..bf14b67519 100644
--- a/bsp/lpc408x/drivers/Kconfig
+++ b/bsp/lpc408x/drivers/Kconfig
@@ -1,21 +1,45 @@
-config RT_USING_UART0
- bool "Enable UART0"
- default y
+menu "Hardware Drivers Config"
-config RT_USING_UART2
- bool "Enable UART2"
- default n
+ menu "On-chip Peripheral Drivers"
-config RT_USING_UART4
- bool "Enable UART4"
- default n
+ config BSP_USING_EMAC
+ bool "EMAC driver"
+ select RT_USING_LWIP
+ default n
-config BSP_DRV_CLCD
- bool "CLCD driver"
- depends on PKG_USING_GUIENGINE
- default y
+ config BSP_USING_HWTIMER0
+ bool "Using timer0"
+ select RT_USING_HWTIMER
+ default n
-config BSP_DRV_EMAC
- bool "EMAC driver"
- depends on RT_USING_LWIP
- default y
+ menu "UART Drivers"
+ config BSP_USING_UART0
+ bool "Enable UART0 P0.2/P0.3(T/R)"
+ select RT_USING_SERIAL
+ default y
+
+ config BSP_USING_UART2
+ bool "Enable UART2 P2.8/P0.11(T/R)"
+ select RT_USING_SERIAL
+ default n
+
+ endmenu
+
+ endmenu
+
+ menu "Onboard Peripheral Drivers"
+
+ config BSP_USING_SDRAM
+ bool "Enable sdram"
+ default n
+
+ config BSP_USING_LED
+ bool "Enable LED"
+ default n
+ endmenu
+
+ menu "Offboard Peripheral Drivers"
+
+ endmenu
+
+endmenu
diff --git a/bsp/lpc408x/drivers/SConscript b/bsp/lpc408x/drivers/SConscript
index e5f4cd4945..8c7c4435b2 100644
--- a/bsp/lpc408x/drivers/SConscript
+++ b/bsp/lpc408x/drivers/SConscript
@@ -1,13 +1,27 @@
from building import *
cwd = GetCurrentDir()
-src = Glob('*.c')
+CPPPATH = [cwd]
-# remove no need file.
-if GetDepend('RT_USING_LWIP') == False:
- SrcRemove(src, 'drv_emac.c')
+# add the general drivers.
+src = Split("""
+board.c
+""")
-CPPPATH = [cwd]
+if GetDepend(['BSP_USING_EMAC']):
+ src += ['drv_emac.c']
+
+if GetDepend(['BSP_USING_HWTIMER0']):
+ src += ['drv_hwtimer.c']
+
+if GetDepend(['BSP_USING_LED']):
+ src += ['drv_led.c']
+
+if GetDepend(['BSP_USING_SDRAM']):
+ src += ['drv_sdram.c']
+
+if GetDepend('BSP_USING_UART0') or GetDepend('BSP_USING_UART2'):
+ src += ['drv_uart.c']
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
diff --git a/bsp/lpc408x/drivers/board.c b/bsp/lpc408x/drivers/board.c
new file mode 100644
index 0000000000..8db9473876
--- /dev/null
+++ b/bsp/lpc408x/drivers/board.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2009-01-05 Bernard first implementation
+ */
+
+#include <board.h>
+
+#if defined(BSP_USING_SDRAM) && defined(RT_USING_MEMHEAP_AS_HEAP)
+ #include "drv_sdram.h"
+ extern void rt_hw_sdram_init(void);
+ static struct rt_memheap system_heap;
+#endif
+
+void SysTick_Handler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ rt_tick_increase();
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+/**
+ * This function will initial LPC40xx board.
+ */
+void rt_hw_board_init()
+{
+ /* NVIC Configuration */
+#define NVIC_VTOR_MASK 0x3FFFFF80
+#ifdef VECT_TAB_RAM
+ /* Set the Vector Table base location at 0x10000000 */
+ SCB->VTOR = (0x10000000 & NVIC_VTOR_MASK);
+#else /* VECT_TAB_FLASH */
+ /* Set the Vector Table base location at 0x00000000 */
+ SCB->VTOR = (0x00000000 & NVIC_VTOR_MASK);
+#endif
+
+ /* init systick */
+ SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND - 1);
+ /* set pend exception priority */
+ NVIC_SetPriority(PendSV_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
+
+#ifdef RT_USING_HEAP
+
+#if defined(BSP_USING_SDRAM) && defined(RT_USING_MEMHEAP_AS_HEAP)
+ rt_hw_sdram_init();
+ rt_system_heap_init((void *)EXT_SDRAM_BEGIN, (void *)EXT_SDRAM_END);
+ rt_memheap_init(&system_heap, "sdram", (void *)HEAP_BEGIN, ((rt_uint32_t)HEAP_END - (rt_uint32_t)HEAP_BEGIN));
+#else
+ rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
+#endif
+
+#endif /* RT_USING_HEAP */
+
+#ifdef RT_USING_COMPONENTS_INIT
+ rt_components_board_init();
+#endif
+#ifdef RT_USING_CONSOLE
+ rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
+#endif
+}
diff --git a/bsp/lpc408x/drivers/board.h b/bsp/lpc408x/drivers/board.h
new file mode 100644
index 0000000000..1cc74d0fd6
--- /dev/null
+++ b/bsp/lpc408x/drivers/board.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2009-09-22 Bernard add board.h to this bsp
+ * 2010-02-04 Magicoe add board.h to LPC176x bsp
+ * 2013-12-18 Bernard porting to LPC4088 bsp
+ */
+
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+#include "LPC407x_8x_177x_8x.h"
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* SRAM allocation for Peripherals */
+#define USB_RAM_BASE 0x20000000
+#define MCI_RAM_BASE 0x20002000
+#define ETH_RAM_BASE 0x20004000
+
+/* Internal SRAM memory size[Kbytes] <16-256>, Default: 64*/
+#define SRAM_SIZE 64 * 1024
+#define SRAM_END (0x10000000 + SRAM_SIZE)
+
+#ifdef __CC_ARM
+ extern int Image$$RW_IRAM1$$ZI$$Limit;
+ #define HEAP_BEGIN ((void *)&Image$$RW_IRAM1$$ZI$$Limit)
+#elif __ICCARM__
+ #pragma section="HEAP"
+ #define HEAP_BEGIN (__segment_end("HEAP"))
+#else
+ extern int __bss_end;
+ #define HEAP_BEGIN ((void *)&__bss_end)
+#endif
+#define HEAP_END SRAM_END
+
+void rt_hw_board_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BOARD_H__ */
diff --git a/bsp/lpc408x/drivers/drv_emac.c b/bsp/lpc408x/drivers/drv_emac.c
index 7e38830f2c..7ea47d52ed 100644
--- a/bsp/lpc408x/drivers/drv_emac.c
+++ b/bsp/lpc408x/drivers/drv_emac.c
@@ -459,7 +459,7 @@ struct pbuf *lpc_emac_rx(rt_device_t dev)
return p;
}
-int lpc_emac_hw_init(void)
+int rt_hw_emac_init(void)
{
rt_event_init(&tx_event, "tx_event", RT_IPC_FLAG_FIFO);
rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO);
@@ -490,7 +490,7 @@ int lpc_emac_hw_init(void)
eth_device_init(&(lpc_emac_device.parent), "e0");
return 0;
}
-INIT_DEVICE_EXPORT(lpc_emac_hw_init);
+INIT_DEVICE_EXPORT(rt_hw_emac_init);
#ifdef RT_USING_FINSH
#include <finsh.h>
diff --git a/bsp/lpc408x/drivers/drv_emac.h b/bsp/lpc408x/drivers/drv_emac.h
index efaa0ac8e3..7d67eae178 100644
--- a/bsp/lpc408x/drivers/drv_emac.h
+++ b/bsp/lpc408x/drivers/drv_emac.h
@@ -8,8 +8,8 @@
* 2013-05-19 Bernard porting from LPC17xx drivers.
*/
-#ifndef __DRV_EMAC_H__
-#define __DRV_EMAC_H__
+#ifndef DRV_EMAC_H__
+#define DRV_EMAC_H__
#include "board.h"
@@ -20,7 +20,6 @@
#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */
-
/* MAC Configuration Register 1 */
#define MAC1_REC_EN 0x00000001 /* Receive Enable */
#define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */
@@ -282,6 +281,6 @@
#define DP83848C_DEF_ADR 0x0F00 /* Default PHY device address */
#define DP83848C_ID 0x20005C90 /* PHY Identifier */
-int lpc_emac_hw_init(void);
+int rt_hw_emac_init(void);
-#endif
+#endif /* DRV_EMAC_H__ */
diff --git a/bsp/lpc408x/drivers/drv_hwtimer.c b/bsp/lpc408x/drivers/drv_hwtimer.c
index 7946a7058a..fa09f87d76 100644
--- a/bsp/lpc408x/drivers/drv_hwtimer.c
+++ b/bsp/lpc408x/drivers/drv_hwtimer.c
@@ -50,7 +50,7 @@ static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_
match.MatchChannel = 0;
match.IntOnMatch = ENABLE;
match.ResetOnMatch = ENABLE;
- match.StopOnMatch = (opmode == HWTIMER_MODE_ONESHOT)? ENABLE : DISABLE;
+ match.StopOnMatch = (opmode == HWTIMER_MODE_ONESHOT) ? ENABLE : DISABLE;
match.ExtMatchOutputType = 0;
match.MatchValue = t;
@@ -84,7 +84,7 @@ static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
uint32_t pre;
clk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER);
- pre = clk / *((uint32_t*)arg) - 1;
+ pre = clk / *((uint32_t *)arg) - 1;
tim->PR = pre;
}
break;
@@ -126,7 +126,7 @@ static const struct rt_hwtimer_ops _ops =
static rt_hwtimer_t _timer0;
-int lpc_hwtimer_init(void)
+int rt_hw_hwtimer_init(void)
{
_timer0.info = &_info;
_timer0.ops = &_ops;
@@ -145,5 +145,6 @@ void TIMER0_IRQHandler(void)
}
}
-INIT_BOARD_EXPORT(lpc_hwtimer_init);
-#endif
+INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
+
+#endif /* RT_USING_HWTIMER */
diff --git a/bsp/lpc408x/drivers/drv_hwtimer.h b/bsp/lpc408x/drivers/drv_hwtimer.h
index b45b27dc06..21c5a25eeb 100644
--- a/bsp/lpc408x/drivers/drv_hwtimer.h
+++ b/bsp/lpc408x/drivers/drv_hwtimer.h
@@ -1,8 +1,16 @@
-#ifndef __DRV_HWTIMER_H__
-#define __DRV_HWTIMER_H__
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2015-09-02 heyuanjie87 the first version
+ */
+#ifndef DRV_HWTIMER_H__
+#define DRV_HWTIMER_H__
-int stm32_hwtimer_init(void);
+int rt_hw_hwtimer_init(void);
-
-#endif
+#endif /* DRV_HWTIMER_H__ */
diff --git a/bsp/lpc408x/drivers/drv_led.c b/bsp/lpc408x/drivers/drv_led.c
index dcbe76a7b8..d7df12ba82 100644
--- a/bsp/lpc408x/drivers/drv_led.c
+++ b/bsp/lpc408x/drivers/drv_led.c
@@ -122,7 +122,7 @@ static rt_err_t rt_led_control(rt_device_t dev, int cmd, void *args)
return RT_EOK;
}
-int rt_led_hw_init(void)
+int rt_hw_led_init(void)
{
led.parent.type = RT_Device_Class_Char;
led.parent.rx_indicate = RT_NULL;
@@ -141,7 +141,8 @@ int rt_led_hw_init(void)
rt_led_init(&led.parent);
return 0;
}
-INIT_DEVICE_EXPORT(rt_led_hw_init);
+INIT_DEVICE_EXPORT(rt_hw_led_init);
+
#ifdef RT_USING_FINSH
#include <finsh.h>
void led_test(rt_uint32_t led_num, rt_uint32_t value)
diff --git a/bsp/lpc408x/drivers/drv_led.h b/bsp/lpc408x/drivers/drv_led.h
index e69de29bb2..f3a958c9b5 100644
--- a/bsp/lpc408x/drivers/drv_led.h
+++ b/bsp/lpc408x/drivers/drv_led.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2015-09-02 heyuanjie87 the first version
+ */
+
+#ifndef DRV_LED_H__
+#define DRV_LED_H__
+
+int rt_hw_led_init(void);
+
+#endif
diff --git a/bsp/lpc408x/drivers/drv_lpccan.c b/bsp/lpc408x/drivers/drv_lpccan.c
deleted file mode 100644
index 85d6511284..0000000000
--- a/bsp/lpc408x/drivers/drv_lpccan.c
+++ /dev/null
@@ -1,1086 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2015-06-30 [email protected] first version
- */
-#include <rthw.h>
-#include <rtdevice.h>
-#include <board.h>
-#include <drv_lpccan.h>
-
-#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 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);
- volatile rt_int32_t i;
-
- 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 */
- i = pCan->ICR;
- i = i;
-
- pCan->MOD = 0;// Return Normal operating
-}
-
-static rt_err_t 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 / 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;
-
- return RT_EOK;
-}
-
-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(uint32_t 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(uint32_t 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;
- rt_uint32_t canid;
-
- 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;
- }
-
- 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 != can->config.baud_rate)
- {
- can->config.baud_rate = argval;
- return 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:
- {
- 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;
- LPC_CAN_TypeDef* pCan;
- struct rt_can_msg* pmsg;
- rt_uint32_t SR_Mask;
- rt_uint32_t CMRMsk;
-
- plpccan = (struct lpccandata* ) can->parent.user_data;
- RT_ASSERT(plpccan != RT_NULL);
-
- pCan = lcpcan_get_reg_base(plpccan->id);
- RT_ASSERT(pCan != RT_NULL);
-
- pmsg = (struct rt_can_msg*) buf;
-
- if(boxno > 2)
- {
- return RT_ERROR;
- }
-
- CMRMsk = 0x01 | (0x01 << (boxno + 5));
- SR_Mask = 0x01 <<(boxno * 8 + 2);
-
- if(pCan->SR & SR_Mask)
- {
- 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;
-
- /* 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;
- LPC_CAN_TypeDef* pCan;
-
- plpccan = (struct lpccandata* ) can->parent.user_data;
- RT_ASSERT(plpccan != RT_NULL);
- pCan = lcpcan_get_reg_base(plpccan->id);
- RT_ASSERT(pCan != RT_NULL);
-
- //CAN_ReceiveMsg
- //check status of Receive Buffer
- if((pCan->SR &0x00000001))
- {
- uint32_t data;
- struct rt_can_msg* pmsg = (struct rt_can_msg*) buf;
-
- /* 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_ID_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_ID_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;
- rt_interrupt_enter();
-#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;
- rt_uint32_t state;
-
- 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;
- }
-
- 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*/
- rt_interrupt_leave();
-}
-
-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 /*RT_USING_LPCCAN1*/
-
-#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
-
- //Enable CAN Interrupt
- NVIC_EnableIRQ(CAN_IRQn);
-
-#ifdef RT_CAN_USING_HDR
-#endif
-
- rt_hw_can_register(&lpccan2, "lpccan2", &canops, &lpccandata2);
-#endif /*RT_USING_LPCCAN2*/
-
- return RT_EOK;
-}
-INIT_BOARD_EXPORT(lpc_can_init);
-
-#endif /*RT_USING_CAN*/
diff --git a/bsp/lpc408x/drivers/drv_lpccan.h b/bsp/lpc408x/drivers/drv_lpccan.h
deleted file mode 100644
index 9dda61a1f6..0000000000
--- a/bsp/lpc408x/drivers/drv_lpccan.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2015-06-30 [email protected] 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_*/
diff --git a/bsp/lpc408x/drivers/drv_sdram.c b/bsp/lpc408x/drivers/drv_sdram.c
index 515659f244..0bb9ec6eb3 100644
--- a/bsp/lpc408x/drivers/drv_sdram.c
+++ b/bsp/lpc408x/drivers/drv_sdram.c
@@ -8,20 +8,14 @@
* 2013-05-19 Bernard The first version for LPC40xx
*/
+#include <rtthread.h>
+
+#ifdef BSP_USING_SDRAM
#include "drv_sdram.h"
#include <lpc_emc.h>
#include <lpc_timer.h>
-#define SDRAM_BASE_ADDR 0xA0000000
-#define SDRAM_SIZE 0x2000000
-
-/*******************************************************************************************
-* @��������sdram_gpio_config()
-* @���� ��void
-* @����ֵ��void
-* @���� ��SDRAM�ܽ����ú������ڲ�����
-*********************************************************************************************/
static void sdram_gpio_config(void)
{
LPC_IOCON->P3_0 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D0 @ P3.0 */
@@ -78,7 +72,7 @@ static void sdram_gpio_config(void)
LPC_IOCON->P2_29 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* DQM[1] @ P2.29 */
}
-void lpc_sdram_hw_init(void)
+void rt_hw_sdram_init(void)
{
volatile uint32_t i;
volatile uint32_t dwtemp;
@@ -88,7 +82,7 @@ void lpc_sdram_hw_init(void)
TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;
TIM_ConfigStruct.PrescaleValue = 1;
- // Set configuration for Tim_config and Tim_MatchConfig
+ /* Set configuration for Tim_config and Tim_MatchConfig */
TIM_Init(LPC_TIM0, TIM_TIMER_MODE, &TIM_ConfigStruct);
LPC_SC->PCONP |= 0x00000800;
@@ -97,53 +91,55 @@ void lpc_sdram_hw_init(void)
LPC_EMC->Config = 0x00000000;
sdram_gpio_config();
- //LPC_SC->EMCCLKSEL = 1; //����Ƶ��һ��Ƶ�ʣ�60Mhz
- LPC_EMC->DynamicRP = EMC_NS2CLK(20); /* 20ns, */
- LPC_EMC->DynamicRAS = /*EMC_NS2CLK(42, nsPerClk);*/ 15; /* 42ns to 100K ns, */
- LPC_EMC->DynamicSREX = 1 - 1; /* tSRE, 1clk, */
- LPC_EMC->DynamicAPR = 2 - 1; /* Not found!!! Estimated as 2clk, */
- LPC_EMC->DynamicDAL = EMC_NS2CLK(20) + 2; /* tDAL = tRP + tDPL = 20ns + 2clk */
- LPC_EMC->DynamicWR = 2 - 1; /* 2CLK, */
- LPC_EMC->DynamicRC = EMC_NS2CLK(63); /* H57V2562GTR-75C tRC=63ns(min)*/
- LPC_EMC->DynamicRFC = EMC_NS2CLK(63); /* H57V2562GTR-75C tRFC=tRC */
- LPC_EMC->DynamicXSR = 0x0000000F; /* exit self-refresh to active, ��֪������Ϊ��� */
- LPC_EMC->DynamicRRD = EMC_NS2CLK(63); /* 3clk, tRRD=15ns(min) */
- LPC_EMC->DynamicMRD = 2 - 1; /* 2clk, tMRD=2clk(min) */
- LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */
+ LPC_EMC->DynamicRP = EMC_NS2CLK(20); /* 20ns */
+ LPC_EMC->DynamicRAS = 15; /* EMC_NS2CLK(42, nsPerClk),42ns to 100K ns */
+ LPC_EMC->DynamicSREX = 1 - 1; /* tSRE, 1clk */
+ LPC_EMC->DynamicAPR = 2 - 1; /* Not found!!! Estimated as 2clk */
+ LPC_EMC->DynamicDAL = EMC_NS2CLK(20) + 2; /* tDAL = tRP + tDPL = 20ns + 2clk */
+ LPC_EMC->DynamicWR = 2 - 1; /* 2CLK */
+ LPC_EMC->DynamicRC = EMC_NS2CLK(63); /* H57V2562GTR-75C tRC=63ns(min)*/
+ LPC_EMC->DynamicRFC = EMC_NS2CLK(63); /* H57V2562GTR-75C tRFC=tRC */
+ LPC_EMC->DynamicXSR = 0x0000000F; /* exit self-refresh to active */
+ LPC_EMC->DynamicRRD = EMC_NS2CLK(63); /* 3clk, tRRD=15ns(min) */
+ LPC_EMC->DynamicMRD = 2 - 1; /* 2clk, tMRD=2clk(min) */
+
+ LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */
/* H57V2562GTR-75C: tCL=3CLK, tRCD=20ns(min), 3 CLK=24ns */
LPC_EMC->DynamicRasCas0 = 0x303;
/* For Manley lpc1778 SDRAM: H57V2562GTR-75C, 256Mb, 16Mx16, 4 banks, row=13, column=9 */
#ifdef SDRAM_CONFIG_16BIT
- LPC_EMC->DynamicConfig0 = 0x680; /* 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC */
+ LPC_EMC->DynamicConfig0 = 0x680; /* 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC */
#elif defined SDRAM_CONFIG_32BIT
- LPC_EMC->DynamicConfig0 = 0x4680; /* 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC */
+ LPC_EMC->DynamicConfig0 = 0x4680; /* 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC */
#endif
TIM_Waitms(100);
- LPC_EMC->DynamicControl = 0x00000183; /* Issue NOP command */
- TIM_Waitms(200); /* wait 200ms */
+ LPC_EMC->DynamicControl = 0x00000183; /* Issue NOP command */
+ TIM_Waitms(200); /* wait 200ms */
- LPC_EMC->DynamicControl = 0x00000103; /* Issue PALL command */
+ LPC_EMC->DynamicControl = 0x00000103; /* Issue PALL command */
- LPC_EMC->DynamicRefresh = 0x00000002; /* ( n * 16 ) -> 32 clock cycles */
- for (i = 0; i < 0x80; i++); /* wait 128 AHB clock cycles */
+ LPC_EMC->DynamicRefresh = 0x00000002; /* ( n * 16 ) -> 32 clock cycles */
+ for (i = 0; i < 0x80; i++); /* wait 128 AHB clock cycles */
LPC_EMC->DynamicRefresh = EMC_SDRAM_REFRESH(64);
- LPC_EMC->DynamicControl = 0x00000083; /* Issue MODE command */
+ LPC_EMC->DynamicControl = 0x00000083; /* Issue MODE command */
#ifdef SDRAM_CONFIG_16BIT
- wtemp = *((volatile uint16_t *)(SDRAM_BASE | (0x33 << 12))); /* 8 burst, 3 CAS latency */
+ wtemp = *((volatile uint16_t *)(EXT_SDRAM_BEGIN | (0x33 << 12))); /* 8 burst, 3 CAS latency */
#elif defined SDRAM_CONFIG_32BIT
- dwtemp = *((volatile uint32_t *)(SDRAM_BASE | (0x32 << 13))); /* 4 burst, 3 CAS latency */
+ dwtemp = *((volatile uint32_t *)(SDRAM_BASE | (0x32 << 13))); /* 4 burst, 3 CAS latency */
#endif
- LPC_EMC->DynamicControl = 0x00000000; /* Issue NORMAL command */
+ LPC_EMC->DynamicControl = 0x00000000; /* Issue NORMAL command */
- LPC_EMC->DynamicConfig0 |= 0x80000; /* enable buffer */
+ LPC_EMC->DynamicConfig0 |= 0x80000; /* enable buffer */
TIM_Waitms(1);
TIM_DeInit(LPC_TIM0);
}
+
+#endif /* BSP_USING_SDRAM */
diff --git a/bsp/lpc408x/drivers/drv_sdram.h b/bsp/lpc408x/drivers/drv_sdram.h
index 21c0791f32..74ceab2d18 100644
--- a/bsp/lpc408x/drivers/drv_sdram.h
+++ b/bsp/lpc408x/drivers/drv_sdram.h
@@ -8,24 +8,25 @@
* 2013-05-19 Bernard The first version for LPC40xx
*/
-#ifndef __DRV_SDRAM_H__
-#define __DRV_SDRAM_H__
+#ifndef DRV_SDRAM_H__
+#define DRV_SDRAM_H__
#include <board.h>
-#define SDRAM_CONFIG_16BIT //use the 16 bitSDRAM
-//#define SDRAM_CONFIG_32BIT //use the 32 bitSDRAM
+#define SDRAM_CONFIG_16BIT /* use the 16 bitSDRAM */
+//#define SDRAM_CONFIG_32BIT /* use the 32 bitSDRAM */
#ifdef SDRAM_CONFIG_16BIT
-#define SDRAM_SIZE 0x2000000 // 256Mbit
-#elif defined SDRAM_CONFIG_32BIT //
-#define SDRAM_SIZE 0x4000000 // 512Mbit
+ #define EXT_SDRAM_SIZE 0x2000000 /* 256Mbit */
+#elif defined SDRAM_CONFIG_32BIT
+ #define EXT_SDRAM_SIZE 0x4000000 /* 512Mbit */
#else
-error Wrong SDRAM config, check ex_sdram.h
+ error Wrong SDRAM config, check ex_sdram.h
#endif
-#define SDRAM_BASE 0xA0000000 /* CS0 */
+#define EXT_SDRAM_BEGIN 0xA0000000 /* CS0 */
+#define EXT_SDRAM_END (EXT_SDRAM_BEGIN + EXT_SDRAM_SIZE)
-void lpc_sdram_hw_init(void);
+void rt_hw_sdram_init(void);
-#endif
+#endif /* DRV_SDRAM_H__ */
diff --git a/bsp/lpc408x/drivers/drv_uart.c b/bsp/lpc408x/drivers/drv_uart.c
index 8360ca17c6..09a518f4ab 100644
--- a/bsp/lpc408x/drivers/drv_uart.c
+++ b/bsp/lpc408x/drivers/drv_uart.c
@@ -8,12 +8,12 @@
* 2013-05-18 Bernard The first version for LPC40xx
*/
-#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
-
#include "board.h"
+#ifdef RT_USING_SERIAL
+
struct lpc_uart
{
LPC_UART_TypeDef *UART;
@@ -48,7 +48,6 @@ static rt_err_t lpc_configure(struct rt_serial_device *serial, struct serial_con
/*enable and reset FIFO*/
uart->UART->FCR = 0x07;
-
return RT_EOK;
}
@@ -104,11 +103,7 @@ static const struct rt_uart_ops lpc_uart_ops =
lpc_getc,
};
-#ifdef RT_USING_UART0
-/* UART0 device driver structure */
-#if RTTHREAD_VERSION < 20000 /* RT-Thread 1.x */
-struct serial_ringbuffer uart0_int_rx;
-#endif
+#ifdef BSP_USING_UART0
struct lpc_uart uart0 =
{
@@ -128,14 +123,9 @@ void UART0_IRQHandler(void)
IIR &= 0x0e;
switch (IIR)
{
-
case 0x04:
case 0x0C:
- #if RTTHREAD_VERSION < 20000
- rt_hw_serial_isr(&serial0);
- #else
rt_hw_serial_isr(&serial0, RT_SERIAL_EVENT_RX_IND);
- #endif
break;
case 0x06:
tmp = LPC_UART0->LSR;
@@ -148,11 +138,8 @@ void UART0_IRQHandler(void)
rt_interrupt_leave();
}
#endif
-#ifdef RT_USING_UART2
-/* UART2 device driver structure */
-#if RTTHREAD_VERSION < 20000 /* RT-Thread 1.x */
-struct serial_ringbuffer uart2_int_rx;
-#endif
+
+#ifdef BSP_USING_UART2
struct lpc_uart uart2 =
{
@@ -174,11 +161,7 @@ void UART2_IRQHandler(void)
{
case 0x04:
case 0x0C:
- #if RTTHREAD_VERSION < 20000
- rt_hw_serial_isr(&serial2);
- #else
rt_hw_serial_isr(&serial2, RT_SERIAL_EVENT_RX_IND);
- #endif
break;
case 0x06:
tmp = LPC_UART2->LSR;
@@ -193,66 +176,19 @@ void UART2_IRQHandler(void)
}
#endif
-#ifdef RT_USING_UART4
-/* UART4 device driver structure */
-#if RTTHREAD_VERSION < 20000 /* RT-Thread 1.x */
-struct serial_ringbuffer uart4_int_rx;
-#endif
-
-struct lpc_uart uart4 =
-{
- LPC_UART4,
- UART4_IRQn,
-};
-struct rt_serial_device serial4;
-
-void UART4_IRQHandler(void)
-{
- volatile uint32_t IIR, tmp;
-
- /* enter interrupt */
- rt_interrupt_enter();
-
- IIR = LPC_UART4->IIR;
- IIR &= 0x0e;
- switch (IIR)
- {
- case 0x04:
- case 0x0C:
- #if RTTHREAD_VERSION < 20000
- rt_hw_serial_isr(&serial4);
- #else
- rt_hw_serial_isr(&serial4, RT_SERIAL_EVENT_RX_IND);
- #endif
- break;
- case 0x06:
- tmp = LPC_UART4->LSR;
- break;
- default :
- tmp = LPC_UART4->LSR;
- break;
- }
-
- /* leave interrupt */
- rt_interrupt_leave();
-}
-#endif
-
-void rt_hw_uart_init(void)
+int rt_hw_uart_init(void)
{
+ rt_err_t ret = RT_EOK;
struct lpc_uart *uart;
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
-#ifdef RT_USING_UART0
+#ifdef BSP_USING_UART0
uart = &uart0;
serial0.ops = &lpc_uart_ops;
serial0.config = config;
- #if RTTHREAD_VERSION < 20000
- serial0.int_rx = &uart0_int_rx;
- #endif
serial0.parent.user_data = uart;
-
+
/*
* Initialize UART0 pin connect
* P0.2: U0_TXD
@@ -273,19 +209,16 @@ void rt_hw_uart_init(void)
NVIC_EnableIRQ(uart->UART_IRQn);
/* register UART0 device */
- rt_hw_serial_register(&serial0, "uart0",
- RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
- uart);
+ ret = rt_hw_serial_register(&serial0, "uart0",
+ RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
+ uart);
#endif
-#ifdef RT_USING_UART2
+#ifdef BSP_USING_UART2
uart = &uart2;
serial2.ops = &lpc_uart_ops;
serial2.config = config;
- #if RTTHREAD_VERSION < 20000
- serial2.int_rx = &uart2_int_rx;
- #endif
serial2.parent.user_data = uart;
/*
@@ -307,42 +240,13 @@ void rt_hw_uart_init(void)
NVIC_EnableIRQ(uart->UART_IRQn);
/* register UART2 device */
- rt_hw_serial_register(&serial2, "uart2",
- RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
- uart);
+ ret = rt_hw_serial_register(&serial2, "uart2",
+ RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
+ uart);
#endif
-#ifdef RT_USING_UART4
- uart = &uart4;
-
- serial4.ops = &lpc_uart_ops;
- serial4.config = config;
- #if RTTHREAD_VERSION < 20000
- serial4.int_rx = &uart4_int_rx;
- #endif
- serial4.parent.user_data = uart;
-
- /*
- * Initialize UART2 pin connect
- * P5.4: U2_TXD
- * P5.3: U2_RXD
- */
- LPC_IOCON->P5_4 &= ~0x07;
- LPC_IOCON->P5_3 &= ~0x07;
- LPC_IOCON->P5_4 |= 0x04;
- LPC_IOCON->P5_3 |= 0x04;
-
- /* enable the uart4 power and clock */
- LPC_SC->PCONP |= 0x01 << 8;
- /* preemption = 1, sub-priority = 1 */
- NVIC_SetPriority(uart->UART_IRQn, ((0x01 << 3) | 0x01));
-
- /* Enable Interrupt for UART channel */
- NVIC_EnableIRQ(uart->UART_IRQn);
-
- /* register UART2 device */
- rt_hw_serial_register(&serial4, "uart4",
- RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
- uart);
-#endif
+ return ret;
}
+INIT_BOARD_EXPORT(rt_hw_uart_init);
+
+#endif /* RT_USING_SERIAL */
diff --git a/bsp/lpc408x/drivers/drv_uart.h b/bsp/lpc408x/drivers/drv_uart.h
index aee8a379ed..6fbe0535a5 100644
--- a/bsp/lpc408x/drivers/drv_uart.h
+++ b/bsp/lpc408x/drivers/drv_uart.h
@@ -8,8 +8,8 @@
* 2014-01-05 NongXiaoming The first version for LPC40xx
*/
-#ifndef __UART_H__
-#define __UART_H__
+#ifndef DRV_UART_H__
+#define DRV_UART_H__
void rt_hw_uart_init(void);
diff --git a/bsp/lpc408x/drivers/linker_scripts/link.lds b/bsp/lpc408x/drivers/linker_scripts/link.lds
new file mode 100644
index 0000000000..ddf10a2c20
--- /dev/null
+++ b/bsp/lpc408x/drivers/linker_scripts/link.lds
@@ -0,0 +1,161 @@
+/*
+ * linker script for LPC1788 (512kB Flash, 48kB + 48kB SRAM ) with GNU ld
+ * yiyue.fang 2012-04-14
+ */
+
+/* Program Entry, set to mark it as "used" and avoid gc */
+MEMORY
+{
+ CODE (rx) : ORIGIN = 0x00000000, LENGTH = 512k /* 512k flash */
+ DATA (rw) : ORIGIN = 0x10000000, LENGTH = 64k /* 64k sram */
+}
+ENTRY(Reset_Handler)
+_system_stack_size = 0x200;
+
+SECTIONS
+{
+ .text :
+ {
+ . = ALIGN(4);
+ KEEP(*(.interrupt_vector)) /* Startup code */
+ . = ALIGN(4);
+ *(.text) /* remaining code */
+ *(.text.*) /* remaining code */
+ *(.rodata) /* read-only data (constants) */
+ *(.rodata*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.gnu.linkonce.t*)
+
+ /* section information for finsh shell */
+ . = ALIGN(4);
+ __fsymtab_start = .;
+ KEEP(*(FSymTab))
+ __fsymtab_end = .;
+ . = ALIGN(4);
+ __vsymtab_start = .;
+ KEEP(*(VSymTab))
+ __vsymtab_end = .;
+ . = ALIGN(4);
+
+ /* section information for initial. */
+ . = ALIGN(4);
+ __rt_init_start = .;
+ KEEP(*(SORT(.rti_fn*)))
+ __rt_init_end = .;
+ . = ALIGN(4);
+
+ PROVIDE(__ctors_start__ = .);
+ /* old GCC version uses .ctors */
+ KEEP(*(SORT(.ctors.*)))
+ KEEP(*(.ctors))
+ /* new GCC version uses .init_array */
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE(__ctors_end__ = .);
+
+ . = ALIGN(4);
+ _etext = .;
+ } > CODE = 0
+
+ .ARM.extab :
+ {
+ *(.ARM.extab*)
+ } > CODE
+
+ /* The .ARM.exidx section is used for C++ exception handling. */
+ /* .ARM.exidx is sorted, so has to go in its own output section. */
+ __exidx_start = .;
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+
+ /* This is used by the startup in order to initialize the .data secion */
+ _sidata = .;
+ } > CODE
+ __exidx_end = .;
+
+ /* .data section which is used for initialized data */
+
+ .data : AT (_sidata)
+ {
+ . = ALIGN(4);
+ PROVIDE(__dtors_start__ = .);
+ KEEP(*(SORT(.dtors.*)))
+ KEEP(*(.dtors))
+ PROVIDE(__dtors_end__ = .);
+
+ . = ALIGN(4);
+ /* This is used by the startup in order to initialize the .data secion */
+ _sdata = . ;
+
+ *(.data)
+ *(.data.*)
+ *(.gnu.linkonce.d*)
+
+ . = ALIGN(4);
+ /* This is used by the startup in order to initialize the .data secion */
+ _edata = . ;
+ } > DATA
+
+ .stack :
+ {
+ . = . + _system_stack_size;
+ . = ALIGN(4);
+ _estack = .;
+ } >DATA
+
+ __bss_start = .;
+ .bss :
+ {
+ . = ALIGN(4);
+ /* This is used by the startup in order to initialize the .bss secion */
+ _sbss = .;
+
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ /* This is used by the startup in order to initialize the .bss secion */
+ _ebss = . ;
+ *(.bss.init)
+ } > DATA
+ __bss_end = .;
+
+ _end = .;
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ * Symbols in the DWARF debugging sections are relative to the beginning
+ * of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+}
diff --git a/bsp/lpc408x/drivers/linker_scripts/link.sct b/bsp/lpc408x/drivers/linker_scripts/link.sct
new file mode 100644
index 0000000000..893f49ce4a
--- /dev/null
+++ b/bsp/lpc408x/drivers/linker_scripts/link.sct
@@ -0,0 +1,15 @@
+; *************************************************************
+; *** Scatter-Loading Description File generated by uVision ***
+; *************************************************************
+
+LR_IROM1 0x00000000 0x00080000 { ; load region size_region
+ ER_IROM1 0x00000000 0x00080000 { ; load address = execution address
+ *.o (RESET, +First)
+ *(InRoot$$Sections)
+ .ANY (+RO)
+ }
+ RW_IRAM1 0x10000000 0x00010000 { ; RW data
+ .ANY (+RW +ZI)
+ }
+}
+