added dma header

added thumb support to start.S
updated documentation
This commit is contained in:
Thomas Doerfler
2010-04-09 12:22:57 +00:00
parent 6d614c4729
commit 7a6f8d09fe
6 changed files with 308 additions and 9 deletions

View File

@@ -1,3 +1,21 @@
2010-04-09 Sebastian Huber <sebastian.huber@embedded-brains.de>
* shared/lpc/include/lpc-dma.h: New file.
* shared/lpc/clock/lpc-clock-config.c, shared/lpc/include/lpc-timer.h,
shared/lpc/network/lpc-ethernet.c: Documentation.
* shared/start/start.S: Do not require ARM mode for start hooks.
2010-01-12 Sebastian Huber <sebastian.huber@embedded-brains.de>
* shared/lpc/network/lpc-ethernet.c: New file.
* shared/abort/abort.c, shared/abort/simple_abort.c: Use new mode
switch macros.
* shared/start/start.S: Fixed mode switching function calls. Use
standard PSR defines.
* shared/startup/linkcmds.base, shared/include/linker-symbols.h: Added
.vbarrier and .robarrier output sections. Added defines for output
section end alignment. Renamed undefined mode stack defines.
2009-12-15 Sebastian Huber <sebastian.huber@embedded-brains.de> 2009-12-15 Sebastian Huber <sebastian.huber@embedded-brains.de>
* shared/include/linker-symbols.h: C++ compatibility. * shared/include/linker-symbols.h: C++ compatibility.

View File

@@ -1,7 +1,7 @@
/** /**
* @file * @file
* *
* @ingroup lpc * @ingroup lpc_clock
* *
* @brief Clock driver configuration. * @brief Clock driver configuration.
*/ */

View File

@@ -0,0 +1,215 @@
/**
* @file
*
* @ingroup lpc_dma
*
* @brief DMA API.
*/
/*
* Copyright (c) 2010
* embedded brains GmbH
* Obere Lagerstr. 30
* D-82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#ifndef LIBBSP_ARM_SHARED_LPC_DMA_H
#define LIBBSP_ARM_SHARED_LPC_DMA_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup lpc_dma DMA Support
*
* @ingroup lpc
*
* @brief DMA support.
*
* @{
*/
/**
* @brief DMA descriptor item.
*/
typedef struct {
uint32_t src;
uint32_t dest;
uint32_t lli;
uint32_t ctrl;
} lpc_dma_descriptor;
/**
* @brief DMA channel block.
*/
typedef struct {
lpc_dma_descriptor desc;
uint32_t cfg;
uint32_t reserved [3];
} lpc_dma_channel;
/**
* @brief DMA control block.
*/
typedef struct {
uint32_t int_stat;
uint32_t int_tc_stat;
uint32_t int_tc_clear;
uint32_t int_err_stat;
uint32_t int_err_clear;
uint32_t raw_tc_stat;
uint32_t raw_err_stat;
uint32_t enabled_channels;
uint32_t soft_burst_req;
uint32_t soft_single_req;
uint32_t soft_last_burst_req;
uint32_t soft_last_single_req;
uint32_t cfg;
uint32_t sync;
uint32_t reserved [50];
lpc_dma_channel channels [];
} lpc_dma;
/**
* @name DMA Configuration Register Defines
*
* @{
*/
#define LPC_DMA_CFG_EN (1U << 0)
#define LPC_DMA_CFG_M_0 (1U << 1)
#define LPC_DMA_CFG_M_1 (1U << 2)
/** @} */
/**
* @name DMA Channel Control Register Defines
*
* @{
*/
#define LPC_DMA_CH_CTRL_TSZ_MASK 0xfffU
#define LPC_DMA_CH_CTRL_TSZ_MAX 0xfffU
#define LPC_DMA_CH_CTRL_SB_MASK (0x7U << 12)
#define LPC_DMA_CH_CTRL_SB_1 (0x0U << 12)
#define LPC_DMA_CH_CTRL_SB_4 (0x1U << 12)
#define LPC_DMA_CH_CTRL_SB_8 (0x2U << 12)
#define LPC_DMA_CH_CTRL_SB_16 (0x3U << 12)
#define LPC_DMA_CH_CTRL_SB_32 (0x4U << 12)
#define LPC_DMA_CH_CTRL_SB_64 (0x5U << 12)
#define LPC_DMA_CH_CTRL_SB_128 (0x6U << 12)
#define LPC_DMA_CH_CTRL_SB_256 (0x7U << 12)
#define LPC_DMA_CH_CTRL_DB_MASK (0x7U << 15)
#define LPC_DMA_CH_CTRL_DB_1 (0x0U << 15)
#define LPC_DMA_CH_CTRL_DB_4 (0x1U << 15)
#define LPC_DMA_CH_CTRL_DB_8 (0x2U << 15)
#define LPC_DMA_CH_CTRL_DB_16 (0x3U << 15)
#define LPC_DMA_CH_CTRL_DB_32 (0x4U << 15)
#define LPC_DMA_CH_CTRL_DB_64 (0x5U << 15)
#define LPC_DMA_CH_CTRL_DB_128 (0x6U << 15)
#define LPC_DMA_CH_CTRL_DB_256 (0x7U << 15)
#define LPC_DMA_CH_CTRL_SW_MASK (0x7U << 18)
#define LPC_DMA_CH_CTRL_SW_8 (0x0U << 18)
#define LPC_DMA_CH_CTRL_SW_16 (0x1U << 18)
#define LPC_DMA_CH_CTRL_SW_32 (0x2U << 18)
#define LPC_DMA_CH_CTRL_DW_MASK (0x7U << 21)
#define LPC_DMA_CH_CTRL_DW_8 (0x0U << 21)
#define LPC_DMA_CH_CTRL_DW_16 (0x1U << 21)
#define LPC_DMA_CH_CTRL_DW_32 (0x2U << 21)
#define LPC_DMA_CH_CTRL_SM_0 (0U << 24)
#define LPC_DMA_CH_CTRL_SM_1 (1U << 24)
#define LPC_DMA_CH_CTRL_DM_0 (0U << 25)
#define LPC_DMA_CH_CTRL_DM_1 (1U << 25)
#define LPC_DMA_CH_CTRL_SI (1U << 26)
#define LPC_DMA_CH_CTRL_DI (1U << 27)
#define LPC_DMA_CH_CTRL_ITC (1U << 31)
/** @} */
/**
* @name DMA Channel Configuration Register Defines
*
* @{
*/
#define LPC_DMA_CH_CFG_EN (1U << 0)
#define LPC_DMA_CH_CFG_SPER_MASK (0xfU << 1)
#define LPC_DMA_CH_CFG_SPER_SHIFT 1
#define LPC_DMA_CH_CFG_SPER_0 (0x0U << 1)
#define LPC_DMA_CH_CFG_SPER_1 (0x1U << 1)
#define LPC_DMA_CH_CFG_SPER_2 (0x2U << 1)
#define LPC_DMA_CH_CFG_SPER_3 (0x3U << 1)
#define LPC_DMA_CH_CFG_SPER_4 (0x4U << 1)
#define LPC_DMA_CH_CFG_SPER_5 (0x5U << 1)
#define LPC_DMA_CH_CFG_SPER_6 (0x6U << 1)
#define LPC_DMA_CH_CFG_SPER_7 (0x7U << 1)
#define LPC_DMA_CH_CFG_SPER_8 (0x8U << 1)
#define LPC_DMA_CH_CFG_SPER_9 (0x9U << 1)
#define LPC_DMA_CH_CFG_SPER_10 (0xaU << 1)
#define LPC_DMA_CH_CFG_SPER_11 (0xbU << 1)
#define LPC_DMA_CH_CFG_SPER_12 (0xcU << 1)
#define LPC_DMA_CH_CFG_SPER_13 (0xdU << 1)
#define LPC_DMA_CH_CFG_SPER_14 (0xeU << 1)
#define LPC_DMA_CH_CFG_SPER_15 (0xfU << 1)
#define LPC_DMA_CH_CFG_DPER_MASK (0xfU << 6)
#define LPC_DMA_CH_CFG_DPER_SHIFT 6
#define LPC_DMA_CH_CFG_DPER_0 (0x0U << 6)
#define LPC_DMA_CH_CFG_DPER_1 (0x1U << 6)
#define LPC_DMA_CH_CFG_DPER_2 (0x2U << 6)
#define LPC_DMA_CH_CFG_DPER_3 (0x3U << 6)
#define LPC_DMA_CH_CFG_DPER_4 (0x4U << 6)
#define LPC_DMA_CH_CFG_DPER_5 (0x5U << 6)
#define LPC_DMA_CH_CFG_DPER_6 (0x6U << 6)
#define LPC_DMA_CH_CFG_DPER_7 (0x7U << 6)
#define LPC_DMA_CH_CFG_DPER_8 (0x8U << 6)
#define LPC_DMA_CH_CFG_DPER_9 (0x9U << 6)
#define LPC_DMA_CH_CFG_DPER_10 (0xaU << 6)
#define LPC_DMA_CH_CFG_DPER_11 (0xbU << 6)
#define LPC_DMA_CH_CFG_DPER_12 (0xcU << 6)
#define LPC_DMA_CH_CFG_DPER_13 (0xdU << 6)
#define LPC_DMA_CH_CFG_DPER_14 (0xeU << 6)
#define LPC_DMA_CH_CFG_DPER_15 (0xfU << 6)
#define LPC_DMA_CH_CFG_FLOW_MASK (0x7U << 11)
#define LPC_DMA_CH_CFG_FLOW_MEM_TO_MEM_DMA (0x0U << 11)
#define LPC_DMA_CH_CFG_FLOW_MEM_TO_PER_DMA (0x1U << 11)
#define LPC_DMA_CH_CFG_FLOW_PER_TO_MEM_DMA (0x2U << 11)
#define LPC_DMA_CH_CFG_FLOW_PER_TO_PER_DMA (0x3U << 11)
#define LPC_DMA_CH_CFG_FLOW_PER_TO_PER_DEST (0x4U << 11)
#define LPC_DMA_CH_CFG_FLOW_MEM_TO_PER_PER (0x5U << 11)
#define LPC_DMA_CH_CFG_FLOW_PER_TO_MEM_PER (0x6U << 11)
#define LPC_DMA_CH_CFG_FLOW_PER_TO_PER_SRC (0x7U << 11)
#define LPC_DMA_CH_CFG_IE (1U << 14)
#define LPC_DMA_CH_CFG_ITC (1U << 15)
#define LPC_DMA_CH_CFG_LOCK (1U << 16)
#define LPC_DMA_CH_CFG_ACTIVE (1U << 17)
#define LPC_DMA_CH_CFG_HALT (1U << 18)
/** @} */
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LIBBSP_ARM_SHARED_LPC_DMA_H */

View File

@@ -1,7 +1,7 @@
/** /**
* @file * @file
* *
* @ingroup lpc * @ingroup lpc_timer
* *
* @brief Timer API. * @brief Timer API.
*/ */
@@ -28,6 +28,22 @@
extern "C" { extern "C" {
#endif #endif
/**
* @defgroup lpc_timer Timer Support
*
* @ingroup lpc
*
* @brief Timer support.
*
* @{
*/
/**
* @name Interrupt Register Defines
*
* @{
*/
#define LPC_TIMER_IR_MR0 0x1U #define LPC_TIMER_IR_MR0 0x1U
#define LPC_TIMER_IR_MR1 0x2U #define LPC_TIMER_IR_MR1 0x2U
#define LPC_TIMER_IR_MR2 0x4U #define LPC_TIMER_IR_MR2 0x4U
@@ -38,9 +54,25 @@ extern "C" {
#define LPC_TIMER_IR_CR3 0x80U #define LPC_TIMER_IR_CR3 0x80U
#define LPC_TIMER_IR_ALL 0xffU #define LPC_TIMER_IR_ALL 0xffU
/** @} */
/**
* @name Timer Control Register Defines
*
* @{
*/
#define LPC_TIMER_TCR_EN 0x1U #define LPC_TIMER_TCR_EN 0x1U
#define LPC_TIMER_TCR_RST 0x2U #define LPC_TIMER_TCR_RST 0x2U
/** @} */
/**
* @name Match Control Register Defines
*
* @{
*/
#define LPC_TIMER_MCR_MR0_INTR 0x1U #define LPC_TIMER_MCR_MR0_INTR 0x1U
#define LPC_TIMER_MCR_MR0_RST 0x2U #define LPC_TIMER_MCR_MR0_RST 0x2U
#define LPC_TIMER_MCR_MR0_STOP 0x4U #define LPC_TIMER_MCR_MR0_STOP 0x4U
@@ -54,6 +86,14 @@ extern "C" {
#define LPC_TIMER_MCR_MR3_RST 0x400U #define LPC_TIMER_MCR_MR3_RST 0x400U
#define LPC_TIMER_MCR_MR3_STOP 0x800U #define LPC_TIMER_MCR_MR3_STOP 0x800U
/** @} */
/**
* @name Capture Control Register Defines
*
* @{
*/
#define LPC_TIMER_CCR_CAP0_RE 0x1U #define LPC_TIMER_CCR_CAP0_RE 0x1U
#define LPC_TIMER_CCR_CAP0_FE 0x2U #define LPC_TIMER_CCR_CAP0_FE 0x2U
#define LPC_TIMER_CCR_CAP0_INTR 0x4U #define LPC_TIMER_CCR_CAP0_INTR 0x4U
@@ -67,6 +107,14 @@ extern "C" {
#define LPC_TIMER_CCR_CAP3_FE 0x400U #define LPC_TIMER_CCR_CAP3_FE 0x400U
#define LPC_TIMER_CCR_CAP3_INTR 0x800U #define LPC_TIMER_CCR_CAP3_INTR 0x800U
/** @} */
/**
* @name External Match Register Defines
*
* @{
*/
#define LPC_TIMER_EMR_EM0_RE 0x1U #define LPC_TIMER_EMR_EM0_RE 0x1U
#define LPC_TIMER_EMR_EM1_FE 0x2U #define LPC_TIMER_EMR_EM1_FE 0x2U
#define LPC_TIMER_EMR_EM2_INTR 0x4U #define LPC_TIMER_EMR_EM2_INTR 0x4U
@@ -76,6 +124,11 @@ extern "C" {
#define LPC_TIMER_EMR_EMC2_RE 0x40U #define LPC_TIMER_EMR_EMC2_RE 0x40U
#define LPC_TIMER_EMR_EMC3_FE 0x80U #define LPC_TIMER_EMR_EMC3_FE 0x80U
/** @} */
/**
* @brief Timer control block.
*/
typedef struct { typedef struct {
uint32_t ir; uint32_t ir;
uint32_t tcr; uint32_t tcr;
@@ -96,6 +149,8 @@ typedef struct {
uint32_t ctcr; uint32_t ctcr;
} lpc_timer; } lpc_timer;
/** @} */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@@ -1,7 +1,7 @@
/** /**
* @file * @file
* *
* @ingroup lpc * @ingroup lpc_eth
* *
* @brief Ethernet driver. * @brief Ethernet driver.
*/ */

View File

@@ -140,17 +140,28 @@ start:
/* /*
* Branch to start hook 0. * Branch to start hook 0.
* *
* This code up to the start hook 0 may run with an address offset so * The previous code and parts of the start hook 0 may run with an
* it must be position independent. After the start hook 0 it is * address offset. This implies that only branches relative to the
* assumed that the code can run at its intended position. The link * program counter are allowed. After the start hook 0 it is assumed
* register will be loaded with the absolute address. * that the code can run at its intended position. Thus the link
* register will be loaded with the absolute address. In THUMB mode
* the start hook 0 must be within a 2kByte range due to the branch
* instruction limitation.
*/ */
ldr lr, =bsp_start_hook_0_done ldr lr, =bsp_start_hook_0_done
#ifdef __thumb__
orr lr, #1
#endif
SWITCH_FROM_ARM_TO_THUMB r0
b bsp_start_hook_0 b bsp_start_hook_0
bsp_start_hook_0_done: bsp_start_hook_0_done:
SWITCH_FROM_THUMB_TO_ARM
/* /*
* Initialize the exception vectors. This includes the exceptions * Initialize the exception vectors. This includes the exceptions
* vectors and the pointers to the default exception handlers. * vectors and the pointers to the default exception handlers.
@@ -163,11 +174,11 @@ bsp_start_hook_0_done:
ldmia r1!, {r2-r9} ldmia r1!, {r2-r9}
stmia r0!, {r2-r9} stmia r0!, {r2-r9}
SWITCH_FROM_ARM_TO_THUMB r0
/* Branch to start hook 1 */ /* Branch to start hook 1 */
bl bsp_start_hook_1 bl bsp_start_hook_1
SWITCH_FROM_ARM_TO_THUMB r0
/* Branch to boot card */ /* Branch to boot card */
mov r0, #0 mov r0, #0
bl boot_card bl boot_card