forked from Imagelibrary/rtems
2010-06-23 Sebastian Huber <sebastian.huber@embedded-brains.de>
* make/custom/lpc32xx_mzx_boot_int.cfg, startup/linkcmds.lpc32xx_mzx_boot_int: Removed files. * include/boot.h, include/emc.h, include/i2c.h, include/nand-mlc.h, make/custom/lpc32xx_mzx.cfg, make/custom/lpc32xx_mzx_stage_1.cfg, make/custom/lpc32xx_mzx_stage_2.cfg, misc/boot.c, misc/emc.c, misc/i2c.c, misc/nand-mlc.c, misc/nand-mlc-read-blocks.c, misc/nand-mlc-write-blocks.c, misc/restart.c, startup/linkcmds.lpc32xx, startup/linkcmds.lpc32xx_mzx, startup/linkcmds.lpc32xx_mzx_stage_1, startup/linkcmds.lpc32xx_mzx_stage_2: New files. * configure.ac, Makefile.am, preinstall.am: Reflect changes above. * include/bsp.h, include/lpc32xx.h, irq/irq.c, rtc/rtc-config.c, startup/bspstart.c, startup/bspstarthooks.c, startup/linkcmds.lpc32xx_phycore: Changes throughout.
This commit is contained in:
@@ -1,3 +1,20 @@
|
||||
2010-06-23 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||
|
||||
* make/custom/lpc32xx_mzx_boot_int.cfg,
|
||||
startup/linkcmds.lpc32xx_mzx_boot_int: Removed files.
|
||||
* include/boot.h, include/emc.h, include/i2c.h, include/nand-mlc.h,
|
||||
make/custom/lpc32xx_mzx.cfg, make/custom/lpc32xx_mzx_stage_1.cfg,
|
||||
make/custom/lpc32xx_mzx_stage_2.cfg, misc/boot.c, misc/emc.c,
|
||||
misc/i2c.c, misc/nand-mlc.c, misc/nand-mlc-read-blocks.c,
|
||||
misc/nand-mlc-write-blocks.c, misc/restart.c,
|
||||
startup/linkcmds.lpc32xx, startup/linkcmds.lpc32xx_mzx,
|
||||
startup/linkcmds.lpc32xx_mzx_stage_1,
|
||||
startup/linkcmds.lpc32xx_mzx_stage_2: New files.
|
||||
* configure.ac, Makefile.am, preinstall.am: Reflect changes above.
|
||||
* include/bsp.h, include/lpc32xx.h, irq/irq.c, rtc/rtc-config.c,
|
||||
startup/bspstart.c, startup/bspstarthooks.c,
|
||||
startup/linkcmds.lpc32xx_phycore: Changes throughout.
|
||||
|
||||
2010-05-25 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||
|
||||
* configure.ac, include/bspopts.h.in: Added BSP_SMALL_MEMORY option.
|
||||
|
||||
@@ -44,6 +44,10 @@ include_bsp_HEADERS += include/mmu.h
|
||||
include_bsp_HEADERS += include/lpc32xx.h
|
||||
include_bsp_HEADERS += include/lpc-clock-config.h
|
||||
include_bsp_HEADERS += include/lpc-ethernet-config.h
|
||||
include_bsp_HEADERS += include/nand-mlc.h
|
||||
include_bsp_HEADERS += include/boot.h
|
||||
include_bsp_HEADERS += include/i2c.h
|
||||
include_bsp_HEADERS += include/emc.h
|
||||
|
||||
include_libcpu_HEADERS = ../../../libcpu/arm/shared/include/cache.h \
|
||||
../../../libcpu/arm/shared/include/arm-cp15.h
|
||||
@@ -59,10 +63,13 @@ libbspstart_a_SOURCES = ../shared/start/start.S
|
||||
project_lib_DATA = start.$(OBJEXT)
|
||||
|
||||
project_lib_DATA += startup/linkcmds
|
||||
project_lib_DATA += startup/linkcmds.lpc32xx
|
||||
project_lib_DATA += ../shared/startup/linkcmds.base
|
||||
|
||||
EXTRA_DIST = startup/linkcmds.lpc32xx_phycore \
|
||||
startup/linkcmds.lpc32xx_mzx_boot_int
|
||||
startup/linkcmds.lpc32xx_mzx_stage_1 \
|
||||
startup/linkcmds.lpc32xx_mzx_stage_2 \
|
||||
startup/linkcmds.lpc32xx_mzx
|
||||
|
||||
###############################################################################
|
||||
# LibBSP #
|
||||
@@ -113,8 +120,15 @@ libbsp_a_SOURCES += ../shared/lpc/clock/lpc-clock-config.c \
|
||||
libbsp_a_SOURCES += ../../shared/tod.c \
|
||||
rtc/rtc-config.c
|
||||
|
||||
# Timer
|
||||
libbsp_a_SOURCES += misc/timer.c
|
||||
# Misc
|
||||
libbsp_a_SOURCES += misc/timer.c \
|
||||
misc/nand-mlc.c \
|
||||
misc/nand-mlc-read-blocks.c \
|
||||
misc/nand-mlc-write-blocks.c \
|
||||
misc/restart.c \
|
||||
misc/boot.c \
|
||||
misc/emc.c \
|
||||
misc/i2c.c
|
||||
|
||||
# SSP
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ RTEMS_PROG_CCAS
|
||||
RTEMS_CHECK_NETWORKING
|
||||
AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
|
||||
|
||||
RTEMS_BSPOPTS_SET([BSP_SMALL_MEMORY],[lpc32xx_mzx_boot_int],[1])
|
||||
RTEMS_BSPOPTS_SET([BSP_SMALL_MEMORY],[lpc32xx_mzx_stage_1],[1])
|
||||
RTEMS_BSPOPTS_SET([BSP_SMALL_MEMORY],[*],[])
|
||||
RTEMS_BSPOPTS_HELP([BSP_SMALL_MEMORY],[disable testsuite samples with high memory demands])
|
||||
|
||||
@@ -40,6 +40,7 @@ RTEMS_BSPOPTS_HELP([LPC32XX_HCLK],[AHB bus clock in Hz])
|
||||
RTEMS_BSPOPTS_SET([LPC32XX_PERIPH_CLK],[*],[13000000U])
|
||||
RTEMS_BSPOPTS_HELP([LPC32XX_PERIPH_CLK],[peripheral clock in Hz])
|
||||
|
||||
RTEMS_BSPOPTS_SET([LPC32XX_ETHERNET_RMII],[lpc32xx_mzx*][])
|
||||
RTEMS_BSPOPTS_SET([LPC32XX_ETHERNET_RMII],[*],[1])
|
||||
RTEMS_BSPOPTS_HELP([LPC32XX_ETHERNET_RMII],[enable RMII for Ethernet])
|
||||
|
||||
@@ -67,13 +68,14 @@ RTEMS_BSPOPTS_HELP([LPC32XX_CONFIG_U6CLK],[clock configuration for UART 6])
|
||||
RTEMS_BSPOPTS_SET([LPC32XX_CONFIG_UART_CLKMODE],[*],[0x00000200U])
|
||||
RTEMS_BSPOPTS_HELP([LPC32XX_CONFIG_UART_CLKMODE],[clock mode configuration for UARTs])
|
||||
|
||||
RTEMS_BSPOPTS_SET([LPC32XX_DISABLE_MMU],[lpc32xx_mzx_boot_int],[1])
|
||||
RTEMS_BSPOPTS_SET([LPC32XX_DISABLE_MMU],[*],[])
|
||||
RTEMS_BSPOPTS_HELP([LPC32XX_DISABLE_MMU],[disable MMU])
|
||||
|
||||
RTEMS_BSPOPTS_SET([LPC32XX_DISABLE_READ_WRITE_DATA_CACHE],[lpc32xx_mzx*],[1])
|
||||
RTEMS_BSPOPTS_SET([LPC32XX_DISABLE_READ_WRITE_DATA_CACHE],[*],[])
|
||||
RTEMS_BSPOPTS_HELP([LPC32XX_DISABLE_READ_WRITE_DATA_CACHE],[disable cache for read-write data sections])
|
||||
|
||||
RTEMS_BSPOPTS_SET([LPC32XX_DISABLE_READ_ONLY_PROTECTION],[lpc32xx_mzx*],[1])
|
||||
RTEMS_BSPOPTS_SET([LPC32XX_DISABLE_READ_ONLY_PROTECTION],[*],[])
|
||||
RTEMS_BSPOPTS_HELP([LPC32XX_DISABLE_READ_ONLY_PROTECTION],[disable MMU protection of read-only sections])
|
||||
|
||||
|
||||
111
c/src/lib/libbsp/arm/lpc32xx/include/boot.h
Normal file
111
c/src/lib/libbsp/arm/lpc32xx/include/boot.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc32xx_boot
|
||||
*
|
||||
* @brief Boot support 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_LPC32XX_BOOT_H
|
||||
#define LIBBSP_ARM_LPC32XX_BOOT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <bsp/nand-mlc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @defgroup lpc32xx_boot Boot Support
|
||||
*
|
||||
* @ingroup lpc32xx
|
||||
*
|
||||
* @brief Boot support.
|
||||
*
|
||||
* The NXP internal boot program shall be the "stage-0 program".
|
||||
*
|
||||
* The boot program within the first page of the first or second block shall be
|
||||
* "stage-1 program". It will be invoked by the stage-0 program from NXP.
|
||||
*
|
||||
* The program loaded by the stage-1 program will be the "stage-2 program" or the
|
||||
* "boot loader".
|
||||
*
|
||||
* The program loaded by the stage-2 program will be the "stage-3 program" or the
|
||||
* "application".
|
||||
*
|
||||
* The stage-1 program image must have a format specified by NXP.
|
||||
*
|
||||
* The stage-2 and stage-3 program images may have any format.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define LPC32XX_BOOT_STAGE_1_BLOCK_0 0
|
||||
#define LPC32XX_BOOT_STAGE_1_BLOCK_1 1
|
||||
#define LPC32XX_BOOT_STAGE_2_BLOCK_0 2
|
||||
|
||||
#define LPC32XX_BOOT_ICR_SP_3AC_8IF 0xf0
|
||||
#define LPC32XX_BOOT_ICR_SP_4AC_8IF 0xd2
|
||||
#define LPC32XX_BOOT_ICR_LP_4AC_8IF 0xb4
|
||||
#define LPC32XX_BOOT_ICR_LP_5AC_8IF 0x96
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t d0;
|
||||
uint8_t reserved_0 [3];
|
||||
uint8_t d1;
|
||||
uint8_t reserved_1 [3];
|
||||
uint8_t d2;
|
||||
uint8_t reserved_2 [3];
|
||||
uint8_t d3;
|
||||
uint8_t reserved_3 [3];
|
||||
uint8_t d4;
|
||||
uint8_t reserved_4 [3];
|
||||
uint8_t d5;
|
||||
uint8_t reserved_5 [3];
|
||||
uint8_t d6;
|
||||
uint8_t reserved_6 [3];
|
||||
uint8_t d7;
|
||||
uint8_t reserved_7 [3];
|
||||
uint8_t d8;
|
||||
uint8_t reserved_8 [3];
|
||||
uint8_t d9;
|
||||
uint8_t reserved_9 [3];
|
||||
uint8_t d10;
|
||||
uint8_t reserved_10 [3];
|
||||
uint8_t d11;
|
||||
uint8_t reserved_11 [3];
|
||||
uint8_t d12;
|
||||
uint8_t reserved_12 [463];
|
||||
} field;
|
||||
uint32_t data [MLC_SMALL_DATA_WORD_COUNT];
|
||||
} lpc32xx_boot_block;
|
||||
|
||||
void lpc32xx_setup_boot_block(
|
||||
lpc32xx_boot_block *boot_block,
|
||||
uint8_t icr,
|
||||
uint8_t page_count
|
||||
);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* LIBBSP_ARM_LPC32XX_BOOT_H */
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009
|
||||
* Copyright (c) 2009, 2010
|
||||
* embedded brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <rtems/clockdrv.h>
|
||||
|
||||
#include <bsp/lpc32xx.h>
|
||||
#include <bsp/lpc-timer.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -91,7 +90,7 @@ int lpc_eth_attach_detach(
|
||||
*/
|
||||
void *lpc32xx_idle(uintptr_t ignored);
|
||||
|
||||
#define LPC32XX_STANDARD_TIMER ((volatile lpc_timer *) LPC32XX_BASE_TIMER_1)
|
||||
#define LPC32XX_STANDARD_TIMER (&lpc32xx.timer_1)
|
||||
|
||||
static inline unsigned lpc32xx_timer(void)
|
||||
{
|
||||
@@ -100,7 +99,41 @@ static inline unsigned lpc32xx_timer(void)
|
||||
return timer->tc;
|
||||
}
|
||||
|
||||
#define BSP_CONSOLE_UART_BASE 0x40090000
|
||||
static inline void lpc32xx_micro_seconds_delay(unsigned us)
|
||||
{
|
||||
unsigned start = lpc32xx_timer();
|
||||
unsigned end = start + us * (LPC32XX_PERIPH_CLK / 1000000);
|
||||
unsigned now = 0;
|
||||
|
||||
do {
|
||||
now = lpc32xx_timer();
|
||||
} while (now < end);
|
||||
}
|
||||
|
||||
void lpc32xx_restart(void *addr);
|
||||
|
||||
#define BSP_CONSOLE_UART_BASE LPC32XX_BASE_UART_5
|
||||
|
||||
/**
|
||||
* @brief Begin of magic zero area.
|
||||
*
|
||||
* A read from this area returns zero. Writes have no effect.
|
||||
*/
|
||||
extern uint32_t lpc32xx_magic_zero_begin [];
|
||||
|
||||
/**
|
||||
* @brief End of magic zero area.
|
||||
*
|
||||
* A read from this area returns zero. Writes have no effect.
|
||||
*/
|
||||
extern uint32_t lpc32xx_magic_zero_end [];
|
||||
|
||||
/**
|
||||
* @brief Size of magic zero area.
|
||||
*
|
||||
* A read from this area returns zero. Writes have no effect.
|
||||
*/
|
||||
extern uint32_t lpc32xx_magic_zero_size [];
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
231
c/src/lib/libbsp/arm/lpc32xx/include/emc.h
Normal file
231
c/src/lib/libbsp/arm/lpc32xx/include/emc.h
Normal file
@@ -0,0 +1,231 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc32xx_emc
|
||||
*
|
||||
* @brief EMC support 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_LPC32XX_EMC_H
|
||||
#define LIBBSP_ARM_LPC32XX_EMC_H
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include <bsp/lpc32xx.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @defgroup lpc32xx_emc EMC Support
|
||||
*
|
||||
* @ingroup lpc32xx
|
||||
*
|
||||
* @brief EMC Support
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @name SDRAM Clock Control Register (SDRAMCLK_CTRL)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define SDRAMCLK_CLOCKS_DIS BIT32(0)
|
||||
#define SDRAMCLK_DDR_MODE BIT32(1)
|
||||
#define SDRAMCLK_DDR_DQSIN_DELAY(val) FIELD32(val, 2, 6)
|
||||
#define SDRAMCLK_RTC_TICK_EN BIT32(7)
|
||||
#define SDRAMCLK_SW_DDR_CAL BIT32(8)
|
||||
#define SDRAMCLK_CAL_DELAY BIT32(9)
|
||||
#define SDRAMCLK_SENSITIVITY_FACTOR(val) FIELD32(val, 10, 12)
|
||||
#define SDRAMCLK_DCA_STATUS BIT32(13)
|
||||
#define SDRAMCLK_COMMAND_DELAY(val) FIELD32(val, 14, 18)
|
||||
#define SDRAMCLK_SW_DDR_RESET BIT32(19)
|
||||
#define SDRAMCLK_PIN_1_FAST BIT32(20)
|
||||
#define SDRAMCLK_PIN_2_FAST BIT32(21)
|
||||
#define SDRAMCLK_PIN_3_FAST BIT32(22)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name EMC Control Register (EMCControl)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define EMC_CTRL_EN BIT32(0)
|
||||
#define EMC_CTRL_LOW_POWER BIT32(2)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name EMC Dynamic Memory Control Register (EMCDynamicControl)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define EMC_DYN_CTRL_CE BIT32(0)
|
||||
#define EMC_DYN_CTRL_CS BIT32(1)
|
||||
#define EMC_DYN_CTRL_SR BIT32(2)
|
||||
#define EMC_DYN_CTRL_SRMCC BIT32(3)
|
||||
#define EMC_DYN_CTRL_IMCC BIT32(4)
|
||||
#define EMC_DYN_CTRL_MCC BIT32(5)
|
||||
#define EMC_DYN_CTRL_I_MASK MASK32(7, 8)
|
||||
#define EMC_DYN_CTRL_I_NORMAL FIELD32(0x0, 7, 8)
|
||||
#define EMC_DYN_CTRL_I_MODE FIELD32(0x1, 7, 8)
|
||||
#define EMC_DYN_CTRL_I_PALL FIELD32(0x2, 7, 8)
|
||||
#define EMC_DYN_CTRL_I_NOP FIELD32(0x3, 7, 8)
|
||||
#define EMC_DYN_CTRL_DP BIT32(9)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name EMC Dynamic Memory Read Configuration Register (EMCDynamicReadConfig)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define EMC_DYN_READ_CONFIG_SDR_STRAT(val) FIELD32(val, 0, 1)
|
||||
#define EMC_DYN_READ_CONFIG_SDR_POL_POS BIT32(4)
|
||||
#define EMC_DYN_READ_CONFIG_DDR_STRAT(val) FIELD32(val, 8, 9)
|
||||
#define EMC_DYN_READ_CONFIG_DDR_POL_POS BIT32(12)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name EMC Dynamic Memory Configuration N Register (EMCDynamicConfigN)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define EMC_DYN_CFG_MD(val) FIELD32(val, 0, 2)
|
||||
#define EMC_DYN_CFG_AM(val) FIELD32(val, 7, 14)
|
||||
#define EMC_DYN_CFG_P(val) BIT32(20)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name EMC Dynamic Memory RAS and CAS Delay N Register (EMCDynamicRasCasN)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define EMC_DYN_RAS(val) FIELD32(val, 0, 3)
|
||||
#define EMC_DYN_CAS(val) FIELD32(val, 7, 10)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name EMC AHB Control Register (EMCAHBControl)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define EMC_AHB_PORT_BUFF_EN BIT32(0)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name EMC AHB Timeout Register (EMCAHBTimeOut)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define EMC_AHB_TIMEOUT(val) FIELD32(val, 0, 9)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name SDRAM Mode and Extended Mode Registers
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define SDRAM_ADDR_ROW_16MB(val) ((uint32_t) (val) << 10)
|
||||
#define SDRAM_ADDR_ROW_32MB(val) ((uint32_t) (val) << 11)
|
||||
#define SDRAM_ADDR_ROW_64MB(val) ((uint32_t) (val) << 11)
|
||||
|
||||
#define SDRAM_ADDR_BANK_16MB(ba1, ba0) \
|
||||
(((uint32_t) (ba1) << 23) | ((uint32_t) (ba0) << 22))
|
||||
#define SDRAM_ADDR_BANK_32MB(ba1, ba0) \
|
||||
(((uint32_t) (ba1) << 23) | ((uint32_t) (ba0) << 24))
|
||||
#define SDRAM_ADDR_BANK_64MB(ba1, ba0) \
|
||||
(((uint32_t) (ba1) << 25) | ((uint32_t) (ba0) << 24))
|
||||
|
||||
#define SDRAM_MODE_16MB(mode) \
|
||||
(SDRAM_ADDR_BANK_16MB(0, 0) | SDRAM_ADDR_ROW_16MB(mode))
|
||||
#define SDRAM_MODE_32MB(mode) \
|
||||
(SDRAM_ADDR_BANK_32MB(0, 0) | SDRAM_ADDR_ROW_32MB(mode))
|
||||
#define SDRAM_MODE_64MB(mode) \
|
||||
(SDRAM_ADDR_BANK_64MB(0, 0) | SDRAM_ADDR_ROW_64MB(mode))
|
||||
|
||||
#define SDRAM_EXTMODE_16MB(mode) \
|
||||
(SDRAM_ADDR_BANK_16MB(1, 0) | SDRAM_ADDR_ROW_16MB(mode))
|
||||
#define SDRAM_EXTMODE_32MB(mode) \
|
||||
(SDRAM_ADDR_BANK_32MB(1, 0) | SDRAM_ADDR_ROW_32MB(mode))
|
||||
#define SDRAM_EXTMODE_64MB(mode) \
|
||||
(SDRAM_ADDR_BANK_64MB(1, 0) | SDRAM_ADDR_ROW_64MB(mode))
|
||||
|
||||
#define SDRAM_MODE_BURST_LENGTH(val) FIELD32(val, 0, 2)
|
||||
#define SDRAM_MODE_BURST_INTERLEAVE BIT32(3)
|
||||
#define SDRAM_MODE_CAS(val) FIELD32(val, 4, 6)
|
||||
#define SDRAM_MODE_TEST_MODE(val) FIELD32(val, 7, 8)
|
||||
#define SDRAM_MODE_WRITE_BURST_SINGLE_BIT BIT32(9)
|
||||
|
||||
#define SDRAM_EXTMODE_PASR(val) FIELD32(val, 0, 2)
|
||||
#define SDRAM_EXTMODE_DRIVER_STRENGTH(val) FIELD32(val, 5, 6)
|
||||
|
||||
/** @} */
|
||||
|
||||
typedef struct {
|
||||
uint32_t size;
|
||||
uint32_t config;
|
||||
uint32_t rascas;
|
||||
uint32_t mode;
|
||||
uint32_t extmode;
|
||||
} lpc32xx_emc_dynamic_chip_config;
|
||||
|
||||
typedef struct {
|
||||
uint32_t sdramclk_ctrl;
|
||||
uint32_t nop_time_in_us;
|
||||
uint32_t control;
|
||||
uint32_t refresh;
|
||||
uint32_t readconfig;
|
||||
uint32_t trp;
|
||||
uint32_t tras;
|
||||
uint32_t tsrex;
|
||||
uint32_t twr;
|
||||
uint32_t trc;
|
||||
uint32_t trfc;
|
||||
uint32_t txsr;
|
||||
uint32_t trrd;
|
||||
uint32_t tmrd;
|
||||
uint32_t tcdlr;
|
||||
lpc32xx_emc_dynamic_chip_config chip [EMC_DYN_CHIP_COUNT];
|
||||
} lpc32xx_emc_dynamic_config;
|
||||
|
||||
void lpc32xx_emc_init(const lpc32xx_emc_dynamic_config *dyn_cfg);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* LIBBSP_ARM_LPC32XX_EMC_H */
|
||||
269
c/src/lib/libbsp/arm/lpc32xx/include/i2c.h
Normal file
269
c/src/lib/libbsp/arm/lpc32xx/include/i2c.h
Normal file
@@ -0,0 +1,269 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc32xx_i2c
|
||||
*
|
||||
* @brief I2C support 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_LPC32XX_I2C_H
|
||||
#define LIBBSP_ARM_LPC32XX_I2C_H
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include <bsp/lpc32xx.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @defgroup lpc32xx_i2c I2C Support
|
||||
*
|
||||
* @ingroup lpc32xx
|
||||
*
|
||||
* @brief I2C Support
|
||||
*
|
||||
* All writes and reads will be performed in master mode. Exclusive bus access
|
||||
* will be assumed.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name I2C Clock Control Register (I2CCLK_CTRL)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define I2CCLK_1_EN BIT32(0)
|
||||
#define I2CCLK_2_EN BIT32(1)
|
||||
#define I2CCLK_1_HIGH_DRIVE BIT32(2)
|
||||
#define I2CCLK_2_HIGH_DRIVE BIT32(3)
|
||||
#define I2CCLK_USB_HIGH_DRIVE BIT32(4)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name I2C TX Data FIFO Register (I2Cn_TX)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define I2C_TX_READ BIT32(0)
|
||||
#define I2C_TX_ADDR(val) FIELD32(val, 1, 7)
|
||||
#define I2C_TX_START BIT32(8)
|
||||
#define I2C_TX_STOP BIT32(9)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name I2C Status Register (I2Cn_STAT)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define I2C_STAT_TDI BIT32(0)
|
||||
#define I2C_STAT_AFI BIT32(1)
|
||||
#define I2C_STAT_NAI BIT32(2)
|
||||
#define I2C_STAT_DRMI BIT32(3)
|
||||
#define I2C_STAT_DRSI BIT32(4)
|
||||
#define I2C_STAT_ACTIVE BIT32(5)
|
||||
#define I2C_STAT_SCL BIT32(6)
|
||||
#define I2C_STAT_SDA BIT32(7)
|
||||
#define I2C_STAT_RFF BIT32(8)
|
||||
#define I2C_STAT_RFE BIT32(9)
|
||||
#define I2C_STAT_TFF BIT32(10)
|
||||
#define I2C_STAT_TFE BIT32(11)
|
||||
#define I2C_STAT_TFFS BIT32(12)
|
||||
#define I2C_STAT_TFES BIT32(13)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name I2C Control Register (I2Cn_CTRL)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define I2C_CTRL_TDIE BIT32(0)
|
||||
#define I2C_CTRL_AFIE BIT32(1)
|
||||
#define I2C_CTRL_NAIE BIT32(2)
|
||||
#define I2C_CTRL_DRMIE BIT32(3)
|
||||
#define I2C_CTRL_DRSIE BIT32(4)
|
||||
#define I2C_CTRL_RFFIE BIT32(5)
|
||||
#define I2C_CTRL_RFDAIE BIT32(6)
|
||||
#define I2C_CTRL_TFFIO BIT32(7)
|
||||
#define I2C_CTRL_RESET BIT32(8)
|
||||
#define I2C_CTRL_SEVEN BIT32(9)
|
||||
#define I2C_CTRL_TFFSIE BIT32(10)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Initializes the I2C module @a i2c.
|
||||
*
|
||||
* Valid @a clock_in_hz values are 100000 and 400000.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_INVALID_ID Invalid @a i2c value.
|
||||
* @retval RTEMS_INVALID_CLOCK Invalid @a clock_in_hz value.
|
||||
*/
|
||||
rtems_status_code lpc32xx_i2c_init(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
unsigned clock_in_hz
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Resets the I2C module @a i2c.
|
||||
*/
|
||||
void lpc32xx_i2c_reset(volatile lpc32xx_i2c *i2c);
|
||||
|
||||
/**
|
||||
* @brief Sets the I2C module @a i2c clock.
|
||||
*
|
||||
* Valid @a clock_in_hz values are 100000 and 400000.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_INVALID_CLOCK Invalid @a clock_in_hz value.
|
||||
*/
|
||||
rtems_status_code lpc32xx_i2c_clock(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
unsigned clock_in_hz
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Starts a write transaction on the I2C module @a i2c.
|
||||
*
|
||||
* The address parameter @a addr must not contain the read/write bit.
|
||||
*
|
||||
* The error status may be delayed to the next
|
||||
* lpc32xx_i2c_write_with_optional_stop() due to controller flaws.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_IO_ERROR Received a NACK from the slave.
|
||||
*/
|
||||
rtems_status_code lpc32xx_i2c_write_start(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
unsigned addr
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Writes data via the I2C module @a i2c with optional stop.
|
||||
*
|
||||
* The error status may be delayed to the next
|
||||
* lpc32xx_i2c_write_with_optional_stop() due to controller flaws.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_IO_ERROR Received a NACK from the slave.
|
||||
*/
|
||||
rtems_status_code lpc32xx_i2c_write_with_optional_stop(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
const uint8_t *out,
|
||||
size_t n,
|
||||
bool stop
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Starts a read transaction on the I2C module @a i2c.
|
||||
*
|
||||
* The address parameter @a addr must not contain the read/write bit.
|
||||
*
|
||||
* The error status may be delayed to the next
|
||||
* lpc32xx_i2c_read_with_optional_stop() due to controller flaws.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_IO_ERROR Received a NACK from the slave.
|
||||
*/
|
||||
rtems_status_code lpc32xx_i2c_read_start(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
unsigned addr
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Reads data via the I2C module @a i2c with optional stop.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_IO_ERROR Received a NACK from the slave.
|
||||
* @retval RTEMS_NOT_IMPLEMENTED Stop is @a false.
|
||||
*/
|
||||
rtems_status_code lpc32xx_i2c_read_with_optional_stop(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
uint8_t *in,
|
||||
size_t n,
|
||||
bool stop
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Writes and reads data via the I2C module @a i2c.
|
||||
*
|
||||
* This will be one bus transaction.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_IO_ERROR Received a NACK from the slave.
|
||||
*/
|
||||
rtems_status_code lpc32xx_i2c_write_and_read(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
unsigned addr,
|
||||
const uint8_t *out,
|
||||
size_t out_size,
|
||||
uint8_t *in,
|
||||
size_t in_size
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Writes data via the I2C module @a i2c.
|
||||
*
|
||||
* This will be one bus transaction.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_IO_ERROR Received a NACK from the slave.
|
||||
*/
|
||||
static inline rtems_status_code lpc32xx_i2c_write(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
unsigned addr,
|
||||
const uint8_t *out,
|
||||
size_t out_size
|
||||
)
|
||||
{
|
||||
return lpc32xx_i2c_write_and_read(i2c, addr, out, out_size, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads data via the I2C module @a i2c.
|
||||
*
|
||||
* This will be one bus transaction.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_IO_ERROR Received a NACK from the slave.
|
||||
*/
|
||||
static inline rtems_status_code lpc32xx_i2c_read(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
unsigned addr,
|
||||
uint8_t *in,
|
||||
size_t in_size
|
||||
)
|
||||
{
|
||||
return lpc32xx_i2c_write_and_read(i2c, addr, NULL, 0, in, in_size);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* LIBBSP_ARM_LPC32XX_I2C_H */
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009
|
||||
* Copyright (c) 2009, 2010
|
||||
* embedded brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <bsp/utility.h>
|
||||
#include <bsp/lpc-timer.h>
|
||||
|
||||
/**
|
||||
* @defgroup lpc32xx_reg Register Definitions
|
||||
@@ -164,41 +165,9 @@
|
||||
#define LPC32XX_KEYCLK_CTRL (*(volatile uint32_t *) 0x400040b0)
|
||||
#define LPC32XX_PWMCLK_CTRL (*(volatile uint32_t *) 0x400040b8)
|
||||
#define LPC32XX_UARTCLK_CTRL (*(volatile uint32_t *) 0x400040e4)
|
||||
#define LPC32XX_POS0_IRAM_CTRl (*(volatile uint32_t *) 0x40004110)
|
||||
#define LPC32XX_POS1_IRAM_CTRl (*(volatile uint32_t *) 0x40004114)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name GPIO Registers
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define LPC32XX_P0_INP_STATE (*(volatile uint32_t *) 0x40028040)
|
||||
#define LPC32XX_P0_OUTP_SET (*(volatile uint32_t *) 0x40028044)
|
||||
#define LPC32XX_P0_OUTP_CLR (*(volatile uint32_t *) 0x40028048)
|
||||
#define LPC32XX_P0_DIR_SET (*(volatile uint32_t *) 0x40028050)
|
||||
#define LPC32XX_P0_DIR_CLR (*(volatile uint32_t *) 0x40028054)
|
||||
#define LPC32XX_P0_DIR_STATE (*(volatile uint32_t *) 0x40028058)
|
||||
#define LPC32XX_P0_OUTP_STATE (*(volatile uint32_t *) 0x4002804c)
|
||||
#define LPC32XX_P1_INP_STATE (*(volatile uint32_t *) 0x40028060)
|
||||
#define LPC32XX_P1_OUTP_SET (*(volatile uint32_t *) 0x40028064)
|
||||
#define LPC32XX_P1_OUTP_CLR (*(volatile uint32_t *) 0x40028068)
|
||||
#define LPC32XX_P1_DIR_SET (*(volatile uint32_t *) 0x40028070)
|
||||
#define LPC32XX_P1_DIR_CLR (*(volatile uint32_t *) 0x40028074)
|
||||
#define LPC32XX_P1_DIR_STATE (*(volatile uint32_t *) 0x40028078)
|
||||
#define LPC32XX_P1_OUTP_STATE (*(volatile uint32_t *) 0x4002806c)
|
||||
#define LPC32XX_P2_INP_STATE (*(volatile uint32_t *) 0x4002801c)
|
||||
#define LPC32XX_P2_OUTP_SET (*(volatile uint32_t *) 0x40028020)
|
||||
#define LPC32XX_P2_OUTP_CLR (*(volatile uint32_t *) 0x40028024)
|
||||
#define LPC32XX_P2_DIR_SET (*(volatile uint32_t *) 0x40028010)
|
||||
#define LPC32XX_P2_DIR_CLR (*(volatile uint32_t *) 0x40028014)
|
||||
#define LPC32XX_P2_DIR_STATE (*(volatile uint32_t *) 0x40028018)
|
||||
#define LPC32XX_P3_INP_STATE (*(volatile uint32_t *) 0x40028000)
|
||||
#define LPC32XX_P3_OUTP_SET (*(volatile uint32_t *) 0x40028004)
|
||||
#define LPC32XX_P3_OUTP_CLR (*(volatile uint32_t *) 0x40028008)
|
||||
#define LPC32XX_P3_OUTP_STATE (*(volatile uint32_t *) 0x4002800c)
|
||||
#define LPC32XX_POS0_IRAM_CTRL (*(volatile uint32_t *) 0x40004110)
|
||||
#define LPC32XX_POS1_IRAM_CTRL (*(volatile uint32_t *) 0x40004114)
|
||||
#define LPC32XX_SDRAMCLK_CTRL (*(volatile uint32_t *) 0x40004068)
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -250,6 +219,321 @@
|
||||
|
||||
/** @} */
|
||||
|
||||
#define LPC32XX_RESERVED(a, b, s) (((b) - (a) - sizeof(s)) / 4)
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_nand_slc;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_ssp;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_spi;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_i2s;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_sd_card;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_dma;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_usb;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_lcd;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_etb;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_syscon;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_uart_ctrl;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_uart;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_ms_timer;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_hs_timer;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_wdg_timer;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_debug;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_adc;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_keyscan;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_pwm;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_mcpwm;
|
||||
|
||||
typedef struct {
|
||||
} lpc32xx_eth;
|
||||
|
||||
typedef struct {
|
||||
uint32_t er;
|
||||
uint32_t rsr;
|
||||
uint32_t sr;
|
||||
uint32_t apr;
|
||||
uint32_t atr;
|
||||
uint32_t itr;
|
||||
} lpc32xx_irq;
|
||||
|
||||
typedef struct {
|
||||
uint32_t p3_inp_state;
|
||||
uint32_t p3_outp_set;
|
||||
uint32_t p3_outp_clr;
|
||||
uint32_t p3_outp_state;
|
||||
uint32_t p2_dir_set;
|
||||
uint32_t p2_dir_clr;
|
||||
uint32_t p2_dir_state;
|
||||
uint32_t p2_inp_state;
|
||||
uint32_t p2_outp_set;
|
||||
uint32_t p2_outp_clr;
|
||||
uint32_t reserved_0 [6];
|
||||
uint32_t p0_inp_state;
|
||||
uint32_t p0_outp_set;
|
||||
uint32_t p0_outp_clr;
|
||||
uint32_t p0_outp_state;
|
||||
uint32_t p0_dir_set;
|
||||
uint32_t p0_dir_clr;
|
||||
uint32_t p0_dir_state;
|
||||
uint32_t reserved_1 [1];
|
||||
uint32_t p1_inp_state;
|
||||
uint32_t p1_outp_set;
|
||||
uint32_t p1_outp_clr;
|
||||
uint32_t p1_outp_state;
|
||||
uint32_t p1_dir_set;
|
||||
uint32_t p1_dir_clr;
|
||||
uint32_t p1_dir_state;
|
||||
} lpc32xx_gpio;
|
||||
|
||||
typedef struct {
|
||||
uint32_t rx_or_tx;
|
||||
uint32_t stat;
|
||||
uint32_t ctrl;
|
||||
uint32_t clk_hi;
|
||||
uint32_t clk_lo;
|
||||
uint32_t adr;
|
||||
uint32_t rxfl;
|
||||
uint32_t txfl;
|
||||
uint32_t rxb;
|
||||
uint32_t txb;
|
||||
uint32_t s_tx;
|
||||
uint32_t s_txfl;
|
||||
} lpc32xx_i2c;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ucount;
|
||||
uint32_t dcount;
|
||||
uint32_t match0;
|
||||
uint32_t match1;
|
||||
uint32_t ctrl;
|
||||
uint32_t intstat;
|
||||
uint32_t key;
|
||||
uint32_t sram [32];
|
||||
} lpc32xx_rtc;
|
||||
|
||||
#define EMC_DYN_CHIP_COUNT 2
|
||||
|
||||
#define EMC_STATIC_CHIP_COUNT 4
|
||||
|
||||
typedef struct {
|
||||
uint32_t config;
|
||||
uint32_t rascas;
|
||||
uint32_t reserved_0 [6];
|
||||
} lpc32xx_emc_dynamic;
|
||||
|
||||
typedef struct {
|
||||
uint32_t config;
|
||||
uint32_t waitwen;
|
||||
uint32_t waitoen;
|
||||
uint32_t waitrd;
|
||||
uint32_t waitpage;
|
||||
uint32_t waitwr;
|
||||
uint32_t waitturn;
|
||||
uint32_t reserved_0 [1];
|
||||
} lpc32xx_emc_static;
|
||||
|
||||
typedef struct {
|
||||
uint32_t control;
|
||||
uint32_t status;
|
||||
uint32_t timeout;
|
||||
uint32_t reserved_0 [5];
|
||||
} lpc32xx_emc_ahb;
|
||||
|
||||
typedef struct {
|
||||
uint32_t control;
|
||||
uint32_t status;
|
||||
uint32_t config;
|
||||
uint32_t reserved_0 [5];
|
||||
uint32_t dynamiccontrol;
|
||||
uint32_t dynamicrefresh;
|
||||
uint32_t dynamicreadconfig;
|
||||
uint32_t reserved_1;
|
||||
uint32_t dynamictrp;
|
||||
uint32_t dynamictras;
|
||||
uint32_t dynamictsrex;
|
||||
uint32_t reserved_2 [2];
|
||||
uint32_t dynamictwr;
|
||||
uint32_t dynamictrc;
|
||||
uint32_t dynamictrfc;
|
||||
uint32_t dynamictxsr;
|
||||
uint32_t dynamictrrd;
|
||||
uint32_t dynamictmrd;
|
||||
uint32_t dynamictcdlr;
|
||||
uint32_t reserved_3 [8];
|
||||
uint32_t staticextendedwait;
|
||||
uint32_t reserved_4 [31];
|
||||
lpc32xx_emc_dynamic dynamic [EMC_DYN_CHIP_COUNT];
|
||||
uint32_t reserved_5 [48];
|
||||
lpc32xx_emc_static emcstatic [EMC_STATIC_CHIP_COUNT];
|
||||
uint32_t reserved_6 [96];
|
||||
lpc32xx_emc_ahb ahb [5];
|
||||
} lpc32xx_emc;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
uint32_t w32;
|
||||
uint16_t w16;
|
||||
uint8_t w8;
|
||||
} buff;
|
||||
uint32_t reserved_0 [8191];
|
||||
union {
|
||||
uint32_t w32;
|
||||
uint16_t w16;
|
||||
uint8_t w8;
|
||||
} data;
|
||||
uint32_t reserved_1 [8191];
|
||||
uint32_t cmd;
|
||||
uint32_t addr;
|
||||
uint32_t ecc_enc;
|
||||
uint32_t ecc_dec;
|
||||
uint32_t ecc_auto_enc;
|
||||
uint32_t ecc_auto_dec;
|
||||
uint32_t rpr;
|
||||
uint32_t wpr;
|
||||
uint32_t rubp;
|
||||
uint32_t robp;
|
||||
uint32_t sw_wp_add_low;
|
||||
uint32_t sw_wp_add_hig;
|
||||
uint32_t icr;
|
||||
uint32_t time;
|
||||
uint32_t irq_mr;
|
||||
uint32_t irq_sr;
|
||||
uint32_t lock_pr;
|
||||
uint32_t isr;
|
||||
uint32_t ceh;
|
||||
} lpc32xx_nand_mlc;
|
||||
|
||||
typedef struct {
|
||||
lpc32xx_nand_slc nand_slc;
|
||||
uint32_t reserved_0 [LPC32XX_RESERVED(0x20020000, 0x20084000, lpc32xx_nand_slc)];
|
||||
lpc32xx_ssp ssp_0;
|
||||
uint32_t reserved_1 [LPC32XX_RESERVED(0x20084000, 0x20088000, lpc32xx_ssp)];
|
||||
lpc32xx_spi spi_1;
|
||||
uint32_t reserved_2 [LPC32XX_RESERVED(0x20088000, 0x2008c000, lpc32xx_spi)];
|
||||
lpc32xx_ssp ssp_1;
|
||||
uint32_t reserved_3 [LPC32XX_RESERVED(0x2008c000, 0x20090000, lpc32xx_ssp)];
|
||||
lpc32xx_spi spi_2;
|
||||
uint32_t reserved_4 [LPC32XX_RESERVED(0x20090000, 0x20094000, lpc32xx_spi)];
|
||||
lpc32xx_i2s i2s_0;
|
||||
uint32_t reserved_5 [LPC32XX_RESERVED(0x20094000, 0x20098000, lpc32xx_i2s)];
|
||||
lpc32xx_sd_card sd_card;
|
||||
uint32_t reserved_6 [LPC32XX_RESERVED(0x20098000, 0x2009c000, lpc32xx_sd_card)];
|
||||
lpc32xx_i2s i2s_1;
|
||||
uint32_t reserved_7 [LPC32XX_RESERVED(0x2009c000, 0x200a8000, lpc32xx_i2s)];
|
||||
lpc32xx_nand_mlc nand_mlc;
|
||||
uint32_t reserved_8 [LPC32XX_RESERVED(0x200a8000, 0x31000000, lpc32xx_nand_mlc)];
|
||||
lpc32xx_dma dma;
|
||||
uint32_t reserved_9 [LPC32XX_RESERVED(0x31000000, 0x31020000, lpc32xx_dma)];
|
||||
lpc32xx_usb usb;
|
||||
uint32_t reserved_10 [LPC32XX_RESERVED(0x31020000, 0x31040000, lpc32xx_usb)];
|
||||
lpc32xx_lcd lcd;
|
||||
uint32_t reserved_11 [LPC32XX_RESERVED(0x31040000, 0x31060000, lpc32xx_lcd)];
|
||||
lpc32xx_eth eth;
|
||||
uint32_t reserved_12 [LPC32XX_RESERVED(0x31060000, 0x31080000, lpc32xx_eth)];
|
||||
lpc32xx_emc emc;
|
||||
uint32_t reserved_13 [LPC32XX_RESERVED(0x31080000, 0x310c0000, lpc32xx_emc)];
|
||||
lpc32xx_etb etb;
|
||||
uint32_t reserved_14 [LPC32XX_RESERVED(0x310c0000, 0x40004000, lpc32xx_etb)];
|
||||
lpc32xx_syscon syscon;
|
||||
uint32_t reserved_15 [LPC32XX_RESERVED(0x40004000, 0x40008000, lpc32xx_syscon)];
|
||||
lpc32xx_irq mic;
|
||||
uint32_t reserved_16 [LPC32XX_RESERVED(0x40008000, 0x4000c000, lpc32xx_irq)];
|
||||
lpc32xx_irq sic_1;
|
||||
uint32_t reserved_17 [LPC32XX_RESERVED(0x4000c000, 0x40010000, lpc32xx_irq)];
|
||||
lpc32xx_irq sic_2;
|
||||
uint32_t reserved_18 [LPC32XX_RESERVED(0x40010000, 0x40014000, lpc32xx_irq)];
|
||||
lpc32xx_uart uart_1;
|
||||
uint32_t reserved_19 [LPC32XX_RESERVED(0x40014000, 0x40018000, lpc32xx_uart)];
|
||||
lpc32xx_uart uart_2;
|
||||
uint32_t reserved_20 [LPC32XX_RESERVED(0x40018000, 0x4001c000, lpc32xx_uart)];
|
||||
lpc32xx_uart uart_7;
|
||||
uint32_t reserved_21 [LPC32XX_RESERVED(0x4001c000, 0x40024000, lpc32xx_uart)];
|
||||
lpc32xx_rtc rtc;
|
||||
uint32_t reserved_22 [LPC32XX_RESERVED(0x40024000, 0x40028000, lpc32xx_rtc)];
|
||||
lpc32xx_gpio gpio;
|
||||
uint32_t reserved_23 [LPC32XX_RESERVED(0x40028000, 0x4002c000, lpc32xx_gpio)];
|
||||
lpc_timer timer_4;
|
||||
uint32_t reserved_24 [LPC32XX_RESERVED(0x4002c000, 0x40030000, lpc_timer)];
|
||||
lpc_timer timer_5;
|
||||
uint32_t reserved_25 [LPC32XX_RESERVED(0x40030000, 0x40034000, lpc_timer)];
|
||||
lpc32xx_ms_timer ms_timer;
|
||||
uint32_t reserved_26 [LPC32XX_RESERVED(0x40034000, 0x40038000, lpc32xx_ms_timer)];
|
||||
lpc32xx_hs_timer hs_timer;
|
||||
uint32_t reserved_27 [LPC32XX_RESERVED(0x40038000, 0x4003c000, lpc32xx_hs_timer)];
|
||||
lpc32xx_wdg_timer wdg_timer;
|
||||
uint32_t reserved_28 [LPC32XX_RESERVED(0x4003c000, 0x40040000, lpc32xx_wdg_timer)];
|
||||
lpc32xx_debug debug;
|
||||
uint32_t reserved_29 [LPC32XX_RESERVED(0x40040000, 0x40044000, lpc32xx_debug)];
|
||||
lpc_timer timer_0;
|
||||
uint32_t reserved_30 [LPC32XX_RESERVED(0x40044000, 0x40048000, lpc_timer)];
|
||||
lpc32xx_adc adc;
|
||||
uint32_t reserved_31 [LPC32XX_RESERVED(0x40048000, 0x4004c000, lpc32xx_adc)];
|
||||
lpc_timer timer_1;
|
||||
uint32_t reserved_32 [LPC32XX_RESERVED(0x4004c000, 0x40050000, lpc_timer)];
|
||||
lpc32xx_keyscan keyscan;
|
||||
uint32_t reserved_33 [LPC32XX_RESERVED(0x40050000, 0x40054000, lpc32xx_keyscan)];
|
||||
lpc32xx_uart_ctrl uart_ctrl;
|
||||
uint32_t reserved_34 [LPC32XX_RESERVED(0x40054000, 0x40058000, lpc32xx_uart_ctrl)];
|
||||
lpc_timer timer_2;
|
||||
uint32_t reserved_35 [LPC32XX_RESERVED(0x40058000, 0x4005c000, lpc_timer)];
|
||||
lpc32xx_pwm pwm_1_and_pwm_2;
|
||||
uint32_t reserved_36 [LPC32XX_RESERVED(0x4005c000, 0x40060000, lpc32xx_pwm)];
|
||||
lpc_timer timer3;
|
||||
uint32_t reserved_37 [LPC32XX_RESERVED(0x40060000, 0x40080000, lpc_timer)];
|
||||
lpc32xx_uart uart_3;
|
||||
uint32_t reserved_38 [LPC32XX_RESERVED(0x40080000, 0x40088000, lpc32xx_uart)];
|
||||
lpc32xx_uart uart_4;
|
||||
uint32_t reserved_39 [LPC32XX_RESERVED(0x40088000, 0x40090000, lpc32xx_uart)];
|
||||
lpc32xx_uart uart_5;
|
||||
uint32_t reserved_40 [LPC32XX_RESERVED(0x40090000, 0x40098000, lpc32xx_uart)];
|
||||
lpc32xx_uart uart_6;
|
||||
uint32_t reserved_41 [LPC32XX_RESERVED(0x40098000, 0x400a0000, lpc32xx_uart)];
|
||||
lpc32xx_i2c i2c_1;
|
||||
uint32_t reserved_42 [LPC32XX_RESERVED(0x400a0000, 0x400a8000, lpc32xx_i2c)];
|
||||
lpc32xx_i2c i2c_2;
|
||||
uint32_t reserved_43 [LPC32XX_RESERVED(0x400a8000, 0x400e8000, lpc32xx_i2c)];
|
||||
lpc32xx_mcpwm mcpwm;
|
||||
} lpc32xx_registers;
|
||||
|
||||
extern volatile lpc32xx_registers lpc32xx;
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* LIBBSP_ARM_LPC32XX_LPC32XX_H */
|
||||
|
||||
335
c/src/lib/libbsp/arm/lpc32xx/include/nand-mlc.h
Normal file
335
c/src/lib/libbsp/arm/lpc32xx/include/nand-mlc.h
Normal file
@@ -0,0 +1,335 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc32xx_nand_mlc
|
||||
*
|
||||
* @brief NAND MLC controller 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_LPC32XX_NAND_MLC_H
|
||||
#define LIBBSP_ARM_LPC32XX_NAND_MLC_H
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include <bsp/utility.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @defgroup lpc32xx_nand_mlc NAND MLC Controller
|
||||
*
|
||||
* @ingroup lpc32xx
|
||||
*
|
||||
* @brief NAND MLC Controller.
|
||||
*
|
||||
* Timing constraints:
|
||||
*
|
||||
* -# (WR_LOW + 1) / HCLK >= tWP
|
||||
* -# (WR_HIGH - WR_LOW) / HCLK >= tWH
|
||||
* -# (WR_LOW + 1) / HCLK + (WR_HIGH - WR_LOW) / HCLK >= tWC
|
||||
* -# (RD_LOW + 1) / HCLK >= tRP
|
||||
* -# (RD_LOW + 1) / HCLK >= tREA + tSU
|
||||
* -# (RD_HIGH - RD_LOW) / HCLK >= tREH
|
||||
* -# (RD_LOW + 1) / HCLK + (RD_HIGH - RD_LOW) / HCLK >= tRC
|
||||
* -# (RD_HIGH - RD_LOW) / HCLK + NAND_TA / HCLK >= tRHZ
|
||||
* -# BUSY_DELAY / HCLK >= max(tWB, tRB)
|
||||
* -# TCEA_DELAY / HCLK >= tCEA - tREA
|
||||
*
|
||||
* Known flash layouts (Format: SP = small pages, LP = large pages / address
|
||||
* cycles / pages per block):
|
||||
*
|
||||
* -# SP/3/32
|
||||
* -# SP/4/32
|
||||
* -# LP/4/64
|
||||
* -# LP/5/64
|
||||
* -# LP/5/128
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name MLC NAND Flash Dimensions
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define MLC_SMALL_PAGE_SIZE 528
|
||||
#define MLC_SMALL_DATA_SIZE 512
|
||||
#define MLC_SMALL_SPARE_SIZE 16
|
||||
#define MLC_SMALL_DATA_WORD_COUNT (MLC_SMALL_DATA_SIZE / 4)
|
||||
#define MLC_SMALL_SPARE_WORD_COUNT (MLC_SMALL_SPARE_SIZE / 4)
|
||||
#define MLC_SMALL_PAGES_PER_LARGE_PAGE 4
|
||||
#define MLC_LARGE_PAGE_SIZE \
|
||||
(MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_PAGE_SIZE)
|
||||
#define MLC_LARGE_DATA_SIZE \
|
||||
(MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_DATA_SIZE)
|
||||
#define MLC_LARGE_SPARE_SIZE \
|
||||
(MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_SPARE_SIZE)
|
||||
#define MLC_LARGE_DATA_WORD_COUNT (MLC_LARGE_DATA_SIZE / 4)
|
||||
#define MLC_LARGE_SPARE_WORD_COUNT (MLC_LARGE_SPARE_SIZE / 4)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name NAND Flash Clock Control Register (FLASHCLK_CTRL)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define FLASHCLK_IRQ_MLC BIT32(5)
|
||||
#define FLASHCLK_MLC_DMA_RNB BIT32(4)
|
||||
#define FLASHCLK_MLC_DMA_INT BIT32(3)
|
||||
#define FLASHCLK_SELECT_SLC BIT32(2)
|
||||
#define FLASHCLK_MLC_CLK_ENABLE BIT32(1)
|
||||
#define FLASHCLK_SLC_CLK_ENABLE BIT32(0)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name MLC NAND Timing Register (MLC_TIME_REG)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define MLC_TIME_WR_LOW(val) FIELD32(val, 0, 3)
|
||||
#define MLC_TIME_WR_HIGH(val) FIELD32(val, 4, 7)
|
||||
#define MLC_TIME_RD_LOW(val) FIELD32(val, 8, 11)
|
||||
#define MLC_TIME_RD_HIGH(val) FIELD32(val, 12, 15)
|
||||
#define MLC_TIME_NAND_TA(val) FIELD32(val, 16, 18)
|
||||
#define MLC_TIME_BUSY_DELAY(val) FIELD32(val, 19, 23)
|
||||
#define MLC_TIME_TCEA_DELAY(val) FIELD32(val, 24, 25)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name MLC NAND Lock Protection Register (MLC_LOCK_PR)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define MLC_UNLOCK_PROT 0xa25e
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name MLC NAND Status Register (MLC_ISR)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define MLC_ISR_DECODER_FAILURE BIT32(6)
|
||||
#define MLC_ISR_ERRORS_DETECTED BIT32(3)
|
||||
#define MLC_ISR_ECC_READY BIT32(2)
|
||||
#define MLC_ISR_CONTROLLER_READY BIT32(1)
|
||||
#define MLC_ISR_NAND_READY BIT32(0)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name MLC NAND Controller Configuration Register (MLC_ICR)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define MLC_ICR_SOFT_WRITE_PROT BIT32(3)
|
||||
#define MLC_ICR_LARGE_PAGES BIT32(2)
|
||||
#define MLC_ICR_ADDR_WORD_COUNT_4_5 BIT32(1)
|
||||
#define MLC_ICR_IO_BUS_16 BIT32(0)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name MLC NAND Auto Encode Register (MLC_ECC_AUTO_ENC)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define MLC_ECC_AUTO_ENC_PROGRAM BIT32(8)
|
||||
|
||||
/** @} */
|
||||
|
||||
#define MLC_BAD_BLOCK_MASK ((uint32_t) 0xff00)
|
||||
|
||||
/**
|
||||
* @name NAND Status Register
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define NAND_STATUS_ERROR (1U << 0)
|
||||
#define NAND_STATUS_READY (1U << 6)
|
||||
#define NAND_STATUS_NOT_PROTECTED (1U << 7)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief MLC NAND controller configuration.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Selects small pages (512 Bytes user data and 16 Bytes spare data)
|
||||
* or large pages (2048 Bytes user data and 64 Bytes spare data).
|
||||
*/
|
||||
bool small_pages;
|
||||
|
||||
/**
|
||||
* @brief Selects 3/4 address cycles for small pages/large pages or 4/5
|
||||
* address cycles.
|
||||
*/
|
||||
bool many_address_cycles;
|
||||
|
||||
/**
|
||||
* @brief Selects 64 or 128 pages per block in case of large pages.
|
||||
*/
|
||||
bool normal_blocks;
|
||||
|
||||
uint32_t block_count;
|
||||
|
||||
/**
|
||||
* @brief Value for the MLC NAND Timing Register (MLC_TIME_REG).
|
||||
*/
|
||||
uint32_t time;
|
||||
} lpc32xx_mlc_config;
|
||||
|
||||
/**
|
||||
* @brief Initializes the MLC NAND controller according to @a cfg.
|
||||
*/
|
||||
void lpc32xx_mlc_init(const lpc32xx_mlc_config *cfg);
|
||||
|
||||
uint32_t lpc32xx_mlc_page_size(void);
|
||||
|
||||
uint32_t lpc32xx_mlc_pages_per_block(void);
|
||||
|
||||
uint32_t lpc32xx_mlc_block_count(void);
|
||||
|
||||
void lpc32xx_mlc_write_protection(
|
||||
uint32_t page_index_low,
|
||||
uint32_t page_index_high
|
||||
);
|
||||
|
||||
void lpc32xx_mlc_read_id(uint8_t *id, size_t n);
|
||||
|
||||
/**
|
||||
* @brief Reads the page with index @a page_index.
|
||||
*
|
||||
* 32-bit reads will be performed.
|
||||
*
|
||||
* Bytes 7 to 15 of the spare area will contain the ECC.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_INVALID_ID Invalid @a page_index value.
|
||||
* @retval RTEMS_IO_ERROR Uncorrectable bit error.
|
||||
*/
|
||||
rtems_status_code lpc32xx_mlc_read_page(
|
||||
uint32_t page_index,
|
||||
uint32_t *data,
|
||||
uint32_t *spare
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Erases the block with index @a block_index.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_INVALID_ID Invalid @a block_index value.
|
||||
* @retval RTEMS_IO_ERROR Erase error.
|
||||
*/
|
||||
rtems_status_code lpc32xx_mlc_erase_block(uint32_t block_index);
|
||||
|
||||
/**
|
||||
* @brief Writes the page with index @a page_index.
|
||||
*
|
||||
* 32-bit writes will be performed.
|
||||
*
|
||||
* Bytes 7 to 15 of the spare area will be used for the automatically generated
|
||||
* ECC.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_INVALID_ID Invalid @a page_index value.
|
||||
* @retval RTEMS_IO_ERROR Write error.
|
||||
*/
|
||||
rtems_status_code lpc32xx_mlc_write_page_with_ecc(
|
||||
uint32_t page_index,
|
||||
const uint32_t *data,
|
||||
const uint32_t *spare
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Writes @a src_size Bytes from @a src to the flash area specified by
|
||||
* @a block_begin and @a block_end.
|
||||
*
|
||||
* The @a page_buffer will be used as an intermediate buffer.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_INVALID_ID Invalid @a block_begin or @a block_end value.
|
||||
* @retval RTEMS_IO_ERROR To many bad blocks or source area to big.
|
||||
*/
|
||||
rtems_status_code lpc32xx_mlc_write_blocks(
|
||||
uint32_t block_begin,
|
||||
uint32_t block_end,
|
||||
const void *src,
|
||||
size_t src_size,
|
||||
uint32_t page_buffer [MLC_LARGE_DATA_WORD_COUNT]
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Read blocks process function type.
|
||||
*
|
||||
* @see lpc32xx_mlc_read_blocks().
|
||||
*
|
||||
* @retval false Continue processing.
|
||||
* @retval true Stop processing.
|
||||
*/
|
||||
typedef bool (*lpc32xx_mlc_read_process)(
|
||||
void *process_arg,
|
||||
uint32_t page_index,
|
||||
uint32_t page_size,
|
||||
uint32_t page_data [MLC_LARGE_DATA_WORD_COUNT],
|
||||
uint32_t page_spare [MLC_LARGE_SPARE_WORD_COUNT]
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Reads the pages of block @a block_begin up to and excluding
|
||||
* @a block_end.
|
||||
*
|
||||
* For each page @a process will be called with the @a process_arg parameter,
|
||||
* the page_index, the page data and the page spare.
|
||||
*
|
||||
* The @a page_buffer_0 and @a page_buffer_1 will be used as
|
||||
* intermediate buffers.
|
||||
*/
|
||||
rtems_status_code lpc32xx_mlc_read_blocks(
|
||||
uint32_t block_begin,
|
||||
uint32_t block_end,
|
||||
lpc32xx_mlc_read_process process,
|
||||
void *process_arg,
|
||||
uint32_t page_buffer_0 [MLC_LARGE_DATA_WORD_COUNT],
|
||||
uint32_t page_buffer_1 [MLC_LARGE_DATA_WORD_COUNT]
|
||||
);
|
||||
|
||||
static inline bool lpc32xx_mlc_is_bad_page(const uint32_t *spare)
|
||||
{
|
||||
return (spare [1] & MLC_BAD_BLOCK_MASK) != MLC_BAD_BLOCK_MASK;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* LIBBSP_ARM_LPC32XX_NAND_MLC_H */
|
||||
@@ -42,21 +42,6 @@ typedef union {
|
||||
uint32_t fields_table [LPC32XX_IRQ_MODULE_COUNT];
|
||||
} lpc32xx_irq_fields;
|
||||
|
||||
typedef struct {
|
||||
uint32_t er;
|
||||
uint32_t rsr;
|
||||
uint32_t sr;
|
||||
uint32_t apr;
|
||||
uint32_t atr;
|
||||
uint32_t itr;
|
||||
} lpc32xx_irq_controller;
|
||||
|
||||
static volatile lpc32xx_irq_controller *const lpc32xx_mic = (volatile lpc32xx_irq_controller *) LPC32XX_BASE_MIC;
|
||||
|
||||
static volatile lpc32xx_irq_controller *const lpc32xx_sic_1 = (volatile lpc32xx_irq_controller *) LPC32XX_BASE_SIC_1;
|
||||
|
||||
static volatile lpc32xx_irq_controller *const lpc32xx_sic_2 = (volatile lpc32xx_irq_controller *) LPC32XX_BASE_SIC_2;
|
||||
|
||||
static uint8_t lpc32xx_irq_priority_table [LPC32XX_IRQ_COUNT];
|
||||
|
||||
static lpc32xx_irq_fields lpc32xx_irq_priority_masks [LPC32XX_IRQ_PRIORITY_COUNT];
|
||||
@@ -80,8 +65,8 @@ static inline bool lpc32xx_irq_priority_is_valid(unsigned priority)
|
||||
#define LPC32XX_IRQ_BIT_OPS_FOR_REG_DEFINE \
|
||||
LPC32XX_IRQ_BIT_OPS_DEFINE; \
|
||||
unsigned module_offset = module << 14; \
|
||||
volatile uint32_t *reg = \
|
||||
(volatile uint32_t *) (LPC32XX_BASE_MIC + module_offset + register_offset)
|
||||
volatile uint32_t *reg = (volatile uint32_t *) \
|
||||
((volatile char *) &lpc32xx.mic + module_offset + register_offset)
|
||||
|
||||
#define LPC32XX_IRQ_OFFSET_ER 0U
|
||||
#define LPC32XX_IRQ_OFFSET_RSR 4U
|
||||
@@ -234,10 +219,10 @@ lpc32xx_irq_activation_type lpc32xx_irq_get_activation_type(rtems_vector_number
|
||||
|
||||
void bsp_interrupt_dispatch(void)
|
||||
{
|
||||
uint32_t status = lpc32xx_mic->sr & LPC32XX_MIC_STATUS_MASK;
|
||||
uint32_t er_mic = lpc32xx_mic->er;
|
||||
uint32_t er_sic_1 = lpc32xx_sic_1->er;
|
||||
uint32_t er_sic_2 = lpc32xx_sic_2->er;
|
||||
uint32_t status = lpc32xx.mic.sr & LPC32XX_MIC_STATUS_MASK;
|
||||
uint32_t er_mic = lpc32xx.mic.er;
|
||||
uint32_t er_sic_1 = lpc32xx.sic_1.er;
|
||||
uint32_t er_sic_2 = lpc32xx.sic_2.er;
|
||||
uint32_t psr = 0;
|
||||
lpc32xx_irq_fields *masks = NULL;
|
||||
rtems_vector_number vector = 0;
|
||||
@@ -246,11 +231,11 @@ void bsp_interrupt_dispatch(void)
|
||||
if (status != 0) {
|
||||
vector = lpc32xx_irq_get_index(status);
|
||||
} else {
|
||||
status = lpc32xx_sic_1->sr;
|
||||
status = lpc32xx.sic_1.sr;
|
||||
if (status != 0) {
|
||||
vector = lpc32xx_irq_get_index(status) + LPC32XX_IRQ_MODULE_SIC_1;
|
||||
} else {
|
||||
status = lpc32xx_sic_2->sr;
|
||||
status = lpc32xx.sic_2.sr;
|
||||
if (status != 0) {
|
||||
vector = lpc32xx_irq_get_index(status) + LPC32XX_IRQ_MODULE_SIC_2;
|
||||
} else {
|
||||
@@ -263,9 +248,9 @@ void bsp_interrupt_dispatch(void)
|
||||
|
||||
masks = &lpc32xx_irq_priority_masks [priority];
|
||||
|
||||
lpc32xx_mic->er = er_mic & masks->field.mic;
|
||||
lpc32xx_sic_1->er = er_sic_1 & masks->field.sic_1;
|
||||
lpc32xx_sic_2->er = er_sic_2 & masks->field.sic_2;
|
||||
lpc32xx.mic.er = er_mic & masks->field.mic;
|
||||
lpc32xx.sic_1.er = er_sic_1 & masks->field.sic_1;
|
||||
lpc32xx.sic_2.er = er_sic_2 & masks->field.sic_2;
|
||||
|
||||
psr = arm_status_irq_enable();
|
||||
|
||||
@@ -273,9 +258,9 @@ void bsp_interrupt_dispatch(void)
|
||||
|
||||
arm_status_restore(psr);
|
||||
|
||||
lpc32xx_mic->er = er_mic & lpc32xx_irq_enable.field.mic;
|
||||
lpc32xx_sic_1->er = er_sic_1 & lpc32xx_irq_enable.field.sic_1;
|
||||
lpc32xx_sic_2->er = er_sic_2 & lpc32xx_irq_enable.field.sic_2;
|
||||
lpc32xx.mic.er = er_mic & lpc32xx_irq_enable.field.mic;
|
||||
lpc32xx.sic_1.er = er_sic_1 & lpc32xx_irq_enable.field.sic_1;
|
||||
lpc32xx.sic_2.er = er_sic_2 & lpc32xx_irq_enable.field.sic_2;
|
||||
}
|
||||
|
||||
rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
|
||||
@@ -308,11 +293,7 @@ void lpc32xx_set_exception_handler(
|
||||
)
|
||||
{
|
||||
if ((unsigned) exception < MAX_EXCEPTIONS) {
|
||||
#ifndef LPC32XX_DISABLE_MMU
|
||||
uint32_t *table = (uint32_t *) bsp_section_vector_begin + MAX_EXCEPTIONS;
|
||||
#else
|
||||
uint32_t *table = (uint32_t *) bsp_section_start_begin + MAX_EXCEPTIONS;
|
||||
#endif
|
||||
uint32_t *table = (uint32_t *) bsp_vector_table_begin + MAX_EXCEPTIONS;
|
||||
|
||||
table [exception] = (uint32_t) handler;
|
||||
|
||||
@@ -341,24 +322,24 @@ rtems_status_code bsp_interrupt_facility_initialize(void)
|
||||
lpc32xx_irq_enable.field.sic_2 = 0x0;
|
||||
lpc32xx_irq_enable.field.sic_1 = 0x0;
|
||||
lpc32xx_irq_enable.field.mic = 0xc0000003;
|
||||
lpc32xx_sic_1->er = 0x0;
|
||||
lpc32xx_sic_2->er = 0x0;
|
||||
lpc32xx_mic->er = 0xc0000003;
|
||||
lpc32xx.sic_1.er = 0x0;
|
||||
lpc32xx.sic_2.er = 0x0;
|
||||
lpc32xx.mic.er = 0xc0000003;
|
||||
|
||||
/* Set interrupt types to IRQ */
|
||||
lpc32xx_mic->itr = 0x0;
|
||||
lpc32xx_sic_1->itr = 0x0;
|
||||
lpc32xx_sic_2->itr = 0x0;
|
||||
lpc32xx.mic.itr = 0x0;
|
||||
lpc32xx.sic_1.itr = 0x0;
|
||||
lpc32xx.sic_2.itr = 0x0;
|
||||
|
||||
/* Set interrupt activation polarities */
|
||||
lpc32xx_mic->apr = 0x3ff0efe0;
|
||||
lpc32xx_sic_1->apr = 0xfbd27184;
|
||||
lpc32xx_sic_2->apr = 0x801810c0;
|
||||
lpc32xx.mic.apr = 0x3ff0efe0;
|
||||
lpc32xx.sic_1.apr = 0xfbd27184;
|
||||
lpc32xx.sic_2.apr = 0x801810c0;
|
||||
|
||||
/* Set interrupt activation types */
|
||||
lpc32xx_mic->atr = 0x0;
|
||||
lpc32xx_sic_1->atr = 0x26000;
|
||||
lpc32xx_sic_2->atr = 0x0;
|
||||
lpc32xx.mic.atr = 0x0;
|
||||
lpc32xx.sic_1.atr = 0x26000;
|
||||
lpc32xx.sic_2.atr = 0x0;
|
||||
|
||||
lpc32xx_set_exception_handler(ARM_EXCEPTION_IRQ, arm_exc_interrupt);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Config file for boot loader.
|
||||
# Config file for MZX application.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# Config file for MZX stage-1 program.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/lpc32xx.inc
|
||||
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# Config file for MZX stage-2 program.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/lpc32xx.inc
|
||||
54
c/src/lib/libbsp/arm/lpc32xx/misc/boot.c
Normal file
54
c/src/lib/libbsp/arm/lpc32xx/misc/boot.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc32xx_boot
|
||||
*
|
||||
* @brief Boot support implementation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <bsp/boot.h>
|
||||
|
||||
void lpc32xx_setup_boot_block(
|
||||
lpc32xx_boot_block *boot_block,
|
||||
uint8_t icr,
|
||||
uint8_t page_count
|
||||
)
|
||||
{
|
||||
memset(boot_block, 0, sizeof(*boot_block));
|
||||
|
||||
++page_count;
|
||||
|
||||
boot_block->field.d0 = icr;
|
||||
boot_block->field.d2 = icr;
|
||||
boot_block->field.d4 = page_count;
|
||||
boot_block->field.d6 = page_count;
|
||||
boot_block->field.d8 = page_count;
|
||||
boot_block->field.d10 = page_count;
|
||||
|
||||
icr = (uint8_t) ~((unsigned) icr);
|
||||
page_count = (uint8_t) ~((unsigned) page_count);
|
||||
|
||||
boot_block->field.d1 = icr;
|
||||
boot_block->field.d3 = icr;
|
||||
boot_block->field.d5 = page_count;
|
||||
boot_block->field.d7 = page_count;
|
||||
boot_block->field.d9 = page_count;
|
||||
boot_block->field.d11 = page_count;
|
||||
|
||||
boot_block->field.d12 = 0xaa;
|
||||
}
|
||||
124
c/src/lib/libbsp/arm/lpc32xx/misc/emc.c
Normal file
124
c/src/lib/libbsp/arm/lpc32xx/misc/emc.c
Normal file
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc32xx_emc
|
||||
*
|
||||
* @brief EMC support implementation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <bsp/emc.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/mmu.h>
|
||||
|
||||
static volatile lpc32xx_emc *const emc = &lpc32xx.emc;
|
||||
|
||||
static void set_translation_table_entries(
|
||||
uint32_t begin,
|
||||
uint32_t size
|
||||
)
|
||||
{
|
||||
uint32_t end = begin + size;
|
||||
uint32_t *ttb = arm_cp15_get_translation_table_base();
|
||||
uint32_t i = ARM_MMU_SECT_GET_INDEX(begin);
|
||||
uint32_t iend = ARM_MMU_SECT_GET_INDEX(ARM_MMU_SECT_MVA_ALIGN_UP(end));
|
||||
|
||||
while (i < iend) {
|
||||
ttb [i] = (i << ARM_MMU_SECT_BASE_SHIFT) | LPC32XX_MMU_READ_WRITE;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
static void dynamic_init(const lpc32xx_emc_dynamic_config *cfg)
|
||||
{
|
||||
uint32_t chip_begin = LPC32XX_BASE_EMC_DYCS_0;
|
||||
uint32_t dynamiccontrol = (cfg->control | EMC_DYN_CTRL_CE | EMC_DYN_CTRL_CS)
|
||||
& ~EMC_DYN_CTRL_I_MASK;
|
||||
size_t i = 0;
|
||||
|
||||
LPC32XX_SDRAMCLK_CTRL = cfg->sdramclk_ctrl;
|
||||
|
||||
emc->dynamicreadconfig = cfg->readconfig;
|
||||
|
||||
/* Timings */
|
||||
emc->dynamictrp = cfg->trp;
|
||||
emc->dynamictras = cfg->tras;
|
||||
emc->dynamictsrex = cfg->tsrex;
|
||||
emc->dynamictwr = cfg->twr;
|
||||
emc->dynamictrc = cfg->trc;
|
||||
emc->dynamictrfc = cfg->trfc;
|
||||
emc->dynamictxsr = cfg->txsr;
|
||||
emc->dynamictrrd = cfg->trrd;
|
||||
emc->dynamictmrd = cfg->tmrd;
|
||||
emc->dynamictcdlr = cfg->tcdlr;
|
||||
for (i = 0; i < EMC_DYN_CHIP_COUNT; ++i) {
|
||||
if (cfg->chip [i].size != 0) {
|
||||
emc->dynamic [i].config = cfg->chip [i].config;
|
||||
emc->dynamic [i].rascas = cfg->chip [i].rascas;
|
||||
}
|
||||
}
|
||||
|
||||
/* NOP period */
|
||||
emc->dynamiccontrol = dynamiccontrol | EMC_DYN_CTRL_I_NOP;
|
||||
lpc32xx_micro_seconds_delay(cfg->nop_time_in_us);
|
||||
|
||||
/* Precharge */
|
||||
emc->dynamiccontrol = dynamiccontrol | EMC_DYN_CTRL_I_PALL;
|
||||
emc->dynamicrefresh = 1;
|
||||
/* FIXME: Why a delay, why this value? */
|
||||
lpc32xx_micro_seconds_delay(10);
|
||||
|
||||
/* Refresh timing */
|
||||
emc->dynamicrefresh = cfg->refresh;
|
||||
/* FIXME: Why a delay, why this value? */
|
||||
lpc32xx_micro_seconds_delay(16);
|
||||
|
||||
/* Set modes */
|
||||
for (i = 0; i < EMC_DYN_CHIP_COUNT; ++i) {
|
||||
if (cfg->chip [i].size != 0) {
|
||||
set_translation_table_entries(chip_begin, cfg->chip [i].size);
|
||||
emc->dynamiccontrol = dynamiccontrol | EMC_DYN_CTRL_I_MODE;
|
||||
*(volatile uint32_t *)(LPC32XX_BASE_EMC_DYCS_0 + cfg->chip [i].mode);
|
||||
emc->dynamiccontrol = dynamiccontrol | EMC_DYN_CTRL_I_MODE;
|
||||
*(volatile uint32_t *)(LPC32XX_BASE_EMC_DYCS_0 + cfg->chip [i].extmode);
|
||||
}
|
||||
chip_begin += 0x20000000;
|
||||
}
|
||||
|
||||
emc->dynamiccontrol = cfg->control;
|
||||
}
|
||||
|
||||
void lpc32xx_emc_init(const lpc32xx_emc_dynamic_config *dyn_cfg)
|
||||
{
|
||||
/* Enable clock */
|
||||
LPC32XX_HCLKDIV_CTRL |= HCLK_DIV_DDRAM_CLK(1);
|
||||
|
||||
/* Enable buffers in AHB ports */
|
||||
emc->ahb [0].control = EMC_AHB_PORT_BUFF_EN;
|
||||
emc->ahb [3].control = EMC_AHB_PORT_BUFF_EN;
|
||||
emc->ahb [4].control = EMC_AHB_PORT_BUFF_EN;
|
||||
|
||||
/* Set AHB port timeouts */
|
||||
emc->ahb [0].timeout = EMC_AHB_TIMEOUT(32);
|
||||
emc->ahb [3].timeout = EMC_AHB_TIMEOUT(32);
|
||||
emc->ahb [4].timeout = EMC_AHB_TIMEOUT(32);
|
||||
|
||||
/* Enable EMC */
|
||||
emc->control = EMC_CTRL_EN,
|
||||
emc->config = 0;
|
||||
|
||||
dynamic_init(dyn_cfg);
|
||||
}
|
||||
259
c/src/lib/libbsp/arm/lpc32xx/misc/i2c.c
Normal file
259
c/src/lib/libbsp/arm/lpc32xx/misc/i2c.c
Normal file
@@ -0,0 +1,259 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc32xx_i2c
|
||||
*
|
||||
* @brief I2C support implementation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/i2c.h>
|
||||
|
||||
void lpc32xx_i2c_reset(volatile lpc32xx_i2c *i2c)
|
||||
{
|
||||
i2c->ctrl = I2C_CTRL_RESET;
|
||||
}
|
||||
|
||||
rtems_status_code lpc32xx_i2c_init(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
unsigned clock_in_hz
|
||||
)
|
||||
{
|
||||
uint32_t i2cclk = 0;
|
||||
|
||||
if (i2c == &lpc32xx.i2c_1) {
|
||||
i2cclk |= I2CCLK_1_EN | I2CCLK_1_HIGH_DRIVE;
|
||||
} else if (i2c == &lpc32xx.i2c_2) {
|
||||
i2cclk |= I2CCLK_2_EN | I2CCLK_2_HIGH_DRIVE;
|
||||
} else {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
LPC32XX_I2CCLK_CTRL |= i2cclk;
|
||||
|
||||
lpc32xx_i2c_reset(i2c);
|
||||
|
||||
return lpc32xx_i2c_clock(i2c, clock_in_hz);
|
||||
}
|
||||
|
||||
#if LPC32XX_HCLK != 104000000U
|
||||
#error "unexpected HCLK"
|
||||
#endif
|
||||
|
||||
rtems_status_code lpc32xx_i2c_clock(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
unsigned clock_in_hz
|
||||
)
|
||||
{
|
||||
uint32_t clk_lo = 0;
|
||||
uint32_t clk_hi = 0;
|
||||
|
||||
switch (clock_in_hz) {
|
||||
case 100000:
|
||||
clk_lo = 520;
|
||||
clk_hi = 520;
|
||||
break;
|
||||
case 400000:
|
||||
clk_lo = 166;
|
||||
clk_hi = 94;
|
||||
break;
|
||||
default:
|
||||
return RTEMS_INVALID_CLOCK;
|
||||
}
|
||||
|
||||
i2c->clk_lo = clk_lo;
|
||||
i2c->clk_hi = clk_hi;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static rtems_status_code wait_for_transaction_done(volatile lpc32xx_i2c *i2c)
|
||||
{
|
||||
uint32_t stat = 0;
|
||||
|
||||
do {
|
||||
stat = i2c->stat;
|
||||
} while ((stat & I2C_STAT_TDI) == 0);
|
||||
|
||||
if ((stat & I2C_STAT_TFE) != 0) {
|
||||
i2c->stat = I2C_STAT_TDI;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
} else {
|
||||
lpc32xx_i2c_reset(i2c);
|
||||
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static rtems_status_code tx(volatile lpc32xx_i2c *i2c, uint32_t data)
|
||||
{
|
||||
uint32_t stat = 0;
|
||||
|
||||
do {
|
||||
stat = i2c->stat;
|
||||
} while ((stat & (I2C_STAT_TFE | I2C_STAT_TDI)) == 0);
|
||||
|
||||
if ((stat & I2C_STAT_TDI) == 0) {
|
||||
i2c->rx_or_tx = data;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
} else {
|
||||
lpc32xx_i2c_reset(i2c);
|
||||
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
rtems_status_code lpc32xx_i2c_write_start(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
unsigned addr
|
||||
)
|
||||
{
|
||||
return tx(i2c, I2C_TX_ADDR(addr) | I2C_TX_START);
|
||||
}
|
||||
|
||||
rtems_status_code lpc32xx_i2c_read_start(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
unsigned addr
|
||||
)
|
||||
{
|
||||
return tx(i2c, I2C_TX_ADDR(addr) | I2C_TX_START | I2C_TX_READ);
|
||||
}
|
||||
|
||||
rtems_status_code lpc32xx_i2c_write_with_optional_stop(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
const uint8_t *out,
|
||||
size_t n,
|
||||
bool stop
|
||||
)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
size_t i = 0;
|
||||
|
||||
for (i = 0; i < n - 1 && sc == RTEMS_SUCCESSFUL; ++i) {
|
||||
sc = tx(i2c, out [i]);
|
||||
}
|
||||
|
||||
if (sc == RTEMS_SUCCESSFUL) {
|
||||
uint32_t stop_flag = stop ? I2C_TX_STOP : 0;
|
||||
|
||||
sc = tx(i2c, out [n - 1] | stop_flag);
|
||||
}
|
||||
|
||||
if (stop && sc == RTEMS_SUCCESSFUL) {
|
||||
sc = wait_for_transaction_done(i2c);
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
static bool can_tx_for_rx(volatile lpc32xx_i2c *i2c)
|
||||
{
|
||||
return (i2c->stat & (I2C_STAT_TFF | I2C_STAT_RFF)) == 0;
|
||||
}
|
||||
|
||||
static bool can_rx(volatile lpc32xx_i2c *i2c)
|
||||
{
|
||||
return (i2c->stat & I2C_STAT_RFE) == 0;
|
||||
}
|
||||
|
||||
rtems_status_code lpc32xx_i2c_read_with_optional_stop(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
uint8_t *in,
|
||||
size_t n,
|
||||
bool stop
|
||||
)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
size_t last = n - 1;
|
||||
size_t rx = 0;
|
||||
size_t tx = 0;
|
||||
|
||||
if (!stop) {
|
||||
return RTEMS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
while (rx <= last) {
|
||||
if ((i2c->stat & I2C_STAT_TDI) != 0) {
|
||||
stop = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
while (tx < last && can_tx_for_rx(i2c)) {
|
||||
i2c->rx_or_tx = 0;
|
||||
++tx;
|
||||
}
|
||||
|
||||
if (tx == last && can_tx_for_rx(i2c)) {
|
||||
uint32_t stop_flag = stop ? I2C_TX_STOP : 0;
|
||||
|
||||
i2c->rx_or_tx = stop_flag;
|
||||
++tx;
|
||||
}
|
||||
|
||||
while (rx <= last && can_rx(i2c)) {
|
||||
in [rx] = (uint8_t) i2c->rx_or_tx;
|
||||
++rx;
|
||||
}
|
||||
}
|
||||
|
||||
if (stop) {
|
||||
sc = wait_for_transaction_done(i2c);
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
rtems_status_code lpc32xx_i2c_write_and_read(
|
||||
volatile lpc32xx_i2c *i2c,
|
||||
unsigned addr,
|
||||
const uint8_t *out,
|
||||
size_t out_size,
|
||||
uint8_t *in,
|
||||
size_t in_size
|
||||
)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
|
||||
if (out_size > 0) {
|
||||
bool stop = in_size == 0;
|
||||
|
||||
sc = lpc32xx_i2c_write_start(i2c, addr);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
return sc;
|
||||
}
|
||||
|
||||
sc = lpc32xx_i2c_write_with_optional_stop(i2c, out, out_size, stop);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
return sc;
|
||||
}
|
||||
}
|
||||
|
||||
if (in_size > 0) {
|
||||
sc = lpc32xx_i2c_read_start(i2c, addr);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
return sc;
|
||||
}
|
||||
|
||||
lpc32xx_i2c_read_with_optional_stop(i2c, in, in_size, true);
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
132
c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc-read-blocks.c
Normal file
132
c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc-read-blocks.c
Normal file
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc32xx_nand_mlc
|
||||
*
|
||||
* @brief lpc32xx_mlc_read_blocks() implementation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <bsp/nand-mlc.h>
|
||||
|
||||
static rtems_status_code read_page(
|
||||
uint32_t first_page_of_block,
|
||||
uint32_t page,
|
||||
uint32_t page_data [MLC_LARGE_DATA_WORD_COUNT],
|
||||
uint32_t page_spare [MLC_LARGE_SPARE_WORD_COUNT]
|
||||
)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
uint32_t page_index = first_page_of_block + page;
|
||||
bool possible_bad_page = page == 0 || page == 1;
|
||||
|
||||
if (possible_bad_page) {
|
||||
memset(page_spare, 0, MLC_LARGE_SPARE_SIZE);
|
||||
}
|
||||
|
||||
sc = lpc32xx_mlc_read_page(page_index, page_data, page_spare);
|
||||
if (possible_bad_page && lpc32xx_mlc_is_bad_page(page_spare)) {
|
||||
return RTEMS_UNSATISFIED;
|
||||
} else if (sc == RTEMS_SUCCESSFUL) {
|
||||
return RTEMS_SUCCESSFUL;
|
||||
} else {
|
||||
return sc;
|
||||
}
|
||||
}
|
||||
|
||||
rtems_status_code lpc32xx_mlc_read_blocks(
|
||||
uint32_t block_begin,
|
||||
uint32_t block_end,
|
||||
lpc32xx_mlc_read_process process,
|
||||
void *process_arg,
|
||||
uint32_t page_buffer_0 [MLC_LARGE_DATA_WORD_COUNT],
|
||||
uint32_t page_buffer_1 [MLC_LARGE_DATA_WORD_COUNT]
|
||||
)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
uint32_t page_spare_0 [MLC_LARGE_SPARE_WORD_COUNT];
|
||||
uint32_t page_spare_1 [MLC_LARGE_SPARE_WORD_COUNT];
|
||||
uint32_t pages_per_block = lpc32xx_mlc_pages_per_block();
|
||||
uint32_t page_size = lpc32xx_mlc_page_size();
|
||||
uint32_t block = 0;
|
||||
uint32_t first_page_of_block = block_begin * pages_per_block;
|
||||
|
||||
for (
|
||||
block = block_begin;
|
||||
block != block_end;
|
||||
++block, first_page_of_block += pages_per_block
|
||||
) {
|
||||
uint32_t page = 0;
|
||||
bool done = false;
|
||||
|
||||
sc = read_page(first_page_of_block, 0, page_buffer_0, page_spare_0);
|
||||
if (sc == RTEMS_UNSATISFIED) {
|
||||
continue;
|
||||
} else if (sc != RTEMS_SUCCESSFUL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
sc = read_page(first_page_of_block, 1, page_buffer_1, page_spare_1);
|
||||
if (sc == RTEMS_UNSATISFIED) {
|
||||
continue;
|
||||
} else if (sc != RTEMS_SUCCESSFUL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
done = (*process)(
|
||||
process_arg,
|
||||
first_page_of_block + 0,
|
||||
page_size,
|
||||
page_buffer_0,
|
||||
page_spare_0
|
||||
);
|
||||
if (done) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
done = (*process)(
|
||||
process_arg,
|
||||
first_page_of_block + 1,
|
||||
page_size,
|
||||
page_buffer_1,
|
||||
page_spare_1
|
||||
);
|
||||
if (done) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (page = 2; page < pages_per_block; ++page) {
|
||||
sc = read_page(first_page_of_block, page, page_buffer_1, page_spare_1);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
done = (*process)(
|
||||
process_arg,
|
||||
first_page_of_block + page,
|
||||
page_size,
|
||||
page_buffer_1,
|
||||
page_spare_1
|
||||
);
|
||||
if (done) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
return sc;
|
||||
}
|
||||
166
c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc-write-blocks.c
Normal file
166
c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc-write-blocks.c
Normal file
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc32xx_nand_mlc
|
||||
*
|
||||
* @brief lpc32xx_mlc_write_blocks() implementation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <bsp/nand-mlc.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <bsp.h>
|
||||
|
||||
static const uint32_t ones_spare [MLC_LARGE_SPARE_WORD_COUNT] = {
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff,
|
||||
0xffffffff
|
||||
};
|
||||
|
||||
static void zero_block(uint32_t first_page_of_block, uint32_t pages_per_block)
|
||||
{
|
||||
uint32_t page = 0;
|
||||
|
||||
for (page = 0; page < pages_per_block; ++page) {
|
||||
lpc32xx_mlc_write_page_with_ecc(
|
||||
first_page_of_block + page,
|
||||
lpc32xx_magic_zero_begin,
|
||||
lpc32xx_magic_zero_begin
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_bad_page(
|
||||
uint32_t first_page_of_block,
|
||||
uint32_t page
|
||||
)
|
||||
{
|
||||
uint32_t spare [MLC_LARGE_SPARE_WORD_COUNT];
|
||||
|
||||
memset(spare, 0, MLC_LARGE_SPARE_SIZE);
|
||||
lpc32xx_mlc_read_page(
|
||||
first_page_of_block + page,
|
||||
lpc32xx_magic_zero_begin,
|
||||
spare
|
||||
);
|
||||
return lpc32xx_mlc_is_bad_page(spare);
|
||||
}
|
||||
|
||||
static rtems_status_code erase_block(
|
||||
uint32_t block,
|
||||
uint32_t first_page_of_block,
|
||||
uint32_t pages_per_block
|
||||
)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
|
||||
if (is_bad_page(first_page_of_block, 0)) {
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
|
||||
if (is_bad_page(first_page_of_block, 1)) {
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
|
||||
sc = lpc32xx_mlc_erase_block(block);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
zero_block(first_page_of_block, pages_per_block);
|
||||
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code lpc32xx_mlc_write_blocks(
|
||||
uint32_t block_begin,
|
||||
uint32_t block_end,
|
||||
const void *src,
|
||||
size_t src_size,
|
||||
uint32_t *page_data_buffer
|
||||
)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
uint32_t pages_per_block = lpc32xx_mlc_pages_per_block();
|
||||
uint32_t block_count = lpc32xx_mlc_block_count();
|
||||
uint32_t page_size = lpc32xx_mlc_page_size();
|
||||
uint32_t block = 0;
|
||||
const uint8_t *current = src;
|
||||
const uint8_t *last = current;
|
||||
const uint8_t *end = current + src_size;
|
||||
|
||||
if (block_begin > block_end || block_end > block_count) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
for (block = block_begin; block != block_end; ++block) {
|
||||
uint32_t first_page_of_block = block * pages_per_block;
|
||||
uint32_t page = 0;
|
||||
|
||||
sc = erase_block(block, first_page_of_block, pages_per_block);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (page = 0; page < pages_per_block; ++page) {
|
||||
uintptr_t remainder = (uintptr_t) end - (uintptr_t) current;
|
||||
size_t delta = remainder < page_size ? remainder : page_size;
|
||||
|
||||
if (remainder > 0) {
|
||||
memcpy(page_data_buffer, current, delta);
|
||||
sc = lpc32xx_mlc_write_page_with_ecc(
|
||||
first_page_of_block + page,
|
||||
page_data_buffer,
|
||||
ones_spare
|
||||
);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
erase_block(block, first_page_of_block, pages_per_block);
|
||||
zero_block(first_page_of_block, pages_per_block);
|
||||
current = last;
|
||||
continue;
|
||||
}
|
||||
|
||||
current += delta;
|
||||
} else {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
last = current;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
if (current != end) {
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
322
c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc.c
Normal file
322
c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc.c
Normal file
@@ -0,0 +1,322 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc32xx_nand_mlc
|
||||
*
|
||||
* @brief NAND MLC controller implementation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <bsp/lpc32xx.h>
|
||||
#include <bsp/nand-mlc.h>
|
||||
|
||||
static volatile lpc32xx_nand_mlc *const mlc = &lpc32xx.nand_mlc;
|
||||
|
||||
static bool mlc_small_pages;
|
||||
|
||||
static bool mlc_many_address_cycles;
|
||||
|
||||
static bool mlc_normal_blocks;
|
||||
|
||||
static uint32_t mlc_block_count;
|
||||
|
||||
static uint32_t mlc_page_count;
|
||||
|
||||
uint32_t lpc32xx_mlc_page_size(void)
|
||||
{
|
||||
if (mlc_small_pages) {
|
||||
return 512;
|
||||
} else {
|
||||
return 2048;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t lpc32xx_mlc_pages_per_block(void)
|
||||
{
|
||||
if (mlc_small_pages) {
|
||||
return 32;
|
||||
} else {
|
||||
if (mlc_normal_blocks) {
|
||||
return 64;
|
||||
} else {
|
||||
return 128;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t lpc32xx_mlc_block_count(void)
|
||||
{
|
||||
return mlc_block_count;
|
||||
}
|
||||
|
||||
static void mlc_unlock(void)
|
||||
{
|
||||
mlc->lock_pr = MLC_UNLOCK_PROT;
|
||||
}
|
||||
|
||||
static void mlc_wait(uint32_t flags)
|
||||
{
|
||||
while ((mlc->isr & flags) != flags) {
|
||||
/* Wait */
|
||||
}
|
||||
}
|
||||
|
||||
static void mlc_wait_until_ready(void)
|
||||
{
|
||||
mlc_wait(MLC_ISR_CONTROLLER_READY | MLC_ISR_NAND_READY);
|
||||
}
|
||||
|
||||
static void mlc_reset(void)
|
||||
{
|
||||
mlc->cmd = 0xff;
|
||||
}
|
||||
|
||||
static uint32_t mlc_status(void)
|
||||
{
|
||||
mlc_wait_until_ready();
|
||||
mlc->cmd = 0x70;
|
||||
|
||||
return mlc->data.w8;
|
||||
}
|
||||
|
||||
static bool mlc_was_operation_successful(void)
|
||||
{
|
||||
return (mlc_status() & (NAND_STATUS_READY | NAND_STATUS_ERROR))
|
||||
== NAND_STATUS_READY;
|
||||
}
|
||||
|
||||
static void mlc_set_block_address(uint32_t block_index)
|
||||
{
|
||||
if (mlc_small_pages) {
|
||||
mlc->addr = (uint8_t) (block_index << 5);
|
||||
mlc->addr = (uint8_t) (block_index >> 3);
|
||||
if (mlc_many_address_cycles) {
|
||||
mlc->addr = (uint8_t) (block_index >> 11);
|
||||
}
|
||||
} else {
|
||||
if (mlc_normal_blocks) {
|
||||
mlc->addr = (uint8_t) (block_index << 6);
|
||||
mlc->addr = (uint8_t) (block_index >> 2);
|
||||
if (mlc_many_address_cycles) {
|
||||
mlc->addr = (uint8_t) (block_index >> 10);
|
||||
}
|
||||
} else {
|
||||
mlc->addr = (uint8_t) (block_index << 7);
|
||||
mlc->addr = (uint8_t) (block_index >> 1);
|
||||
if (mlc_many_address_cycles) {
|
||||
mlc->addr = (uint8_t) (block_index >> 9);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mlc_set_page_address(uint32_t page_index)
|
||||
{
|
||||
mlc->addr = 0;
|
||||
if (mlc_small_pages) {
|
||||
mlc->addr = (uint8_t) page_index;
|
||||
mlc->addr = (uint8_t) (page_index >> 8);
|
||||
if (mlc_many_address_cycles) {
|
||||
mlc->addr = (uint8_t) (page_index >> 16);
|
||||
}
|
||||
} else {
|
||||
mlc->addr = 0;
|
||||
mlc->addr = (uint8_t) page_index;
|
||||
mlc->addr = (uint8_t) (page_index >> 8);
|
||||
if (mlc_many_address_cycles) {
|
||||
mlc->addr = (uint8_t) (page_index >> 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lpc32xx_mlc_init(const lpc32xx_mlc_config *cfg)
|
||||
{
|
||||
uint32_t icr = 0;
|
||||
|
||||
mlc_small_pages = cfg->small_pages;
|
||||
mlc_many_address_cycles = cfg->many_address_cycles;
|
||||
mlc_normal_blocks = cfg->normal_blocks;
|
||||
mlc_block_count = cfg->block_count;
|
||||
mlc_page_count = cfg->block_count * lpc32xx_mlc_pages_per_block();
|
||||
|
||||
/* Clock */
|
||||
LPC32XX_FLASHCLK_CTRL = FLASHCLK_IRQ_MLC | FLASHCLK_MLC_CLK_ENABLE;
|
||||
|
||||
/* Timing settings */
|
||||
mlc_unlock();
|
||||
mlc->time = cfg->time;
|
||||
|
||||
/* Configuration */
|
||||
if (!mlc_small_pages) {
|
||||
icr |= MLC_ICR_LARGE_PAGES;
|
||||
}
|
||||
if (mlc_many_address_cycles) {
|
||||
icr |= MLC_ICR_ADDR_WORD_COUNT_4_5;
|
||||
}
|
||||
mlc_unlock();
|
||||
mlc->icr = icr;
|
||||
|
||||
mlc_reset();
|
||||
}
|
||||
|
||||
void lpc32xx_mlc_write_protection(
|
||||
uint32_t page_index_low,
|
||||
uint32_t page_index_high
|
||||
)
|
||||
{
|
||||
mlc_unlock();
|
||||
mlc->sw_wp_add_low = page_index_low;
|
||||
mlc_unlock();
|
||||
mlc->sw_wp_add_hig = page_index_high;
|
||||
mlc_unlock();
|
||||
mlc->icr |= MLC_ICR_SOFT_WRITE_PROT;
|
||||
}
|
||||
|
||||
rtems_status_code lpc32xx_mlc_read_page(
|
||||
uint32_t page_index,
|
||||
uint32_t *data,
|
||||
uint32_t *spare
|
||||
)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
size_t small_pages_count = mlc_small_pages ? 1 : MLC_SMALL_PAGES_PER_LARGE_PAGE;
|
||||
size_t sp = 0;
|
||||
size_t i = 0;
|
||||
uint32_t isr = 0;
|
||||
|
||||
if (page_index >= mlc_page_count) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
mlc_wait_until_ready();
|
||||
mlc->cmd = 0x00;
|
||||
if (!mlc_small_pages) {
|
||||
mlc->cmd = 0x30;
|
||||
}
|
||||
mlc_set_page_address(page_index);
|
||||
mlc_wait(MLC_ISR_NAND_READY);
|
||||
|
||||
for (sp = 0; sc == RTEMS_SUCCESSFUL && sp < small_pages_count; ++sp) {
|
||||
mlc->ecc_dec = 0;
|
||||
|
||||
for (i = 0; i < MLC_SMALL_DATA_WORD_COUNT; ++i) {
|
||||
data [i] = mlc->data.w32;
|
||||
}
|
||||
for (i = 0; i < MLC_SMALL_SPARE_WORD_COUNT; ++i) {
|
||||
spare [i] = mlc->data.w32;
|
||||
}
|
||||
|
||||
mlc_wait(MLC_ISR_ECC_READY);
|
||||
|
||||
isr = mlc->isr;
|
||||
if ((isr & MLC_ISR_ERRORS_DETECTED) != 0) {
|
||||
if ((isr & MLC_ISR_DECODER_FAILURE) == 0) {
|
||||
mlc->rubp = 0;
|
||||
for (i = 0; i < MLC_SMALL_DATA_WORD_COUNT; ++i) {
|
||||
data [i] = mlc->buff.w32;
|
||||
}
|
||||
mlc->robp = 0;
|
||||
for (i = 0; i < MLC_SMALL_SPARE_WORD_COUNT; ++i) {
|
||||
spare [i] = mlc->buff.w32;
|
||||
}
|
||||
} else {
|
||||
sc = RTEMS_IO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
data += MLC_SMALL_DATA_WORD_COUNT;
|
||||
spare += MLC_SMALL_SPARE_WORD_COUNT;
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
void lpc32xx_mlc_read_id(uint8_t *id, size_t n)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
mlc_wait_until_ready();
|
||||
mlc->cmd = 0x90;
|
||||
mlc->addr = 0;
|
||||
mlc_wait(MLC_ISR_NAND_READY);
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
id [i] = mlc->data.w8;
|
||||
}
|
||||
}
|
||||
|
||||
rtems_status_code lpc32xx_mlc_erase_block(uint32_t block_index)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_IO_ERROR;
|
||||
|
||||
if (block_index >= mlc_block_count) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
mlc_wait_until_ready();
|
||||
mlc->cmd = 0x60;
|
||||
mlc_set_block_address(block_index);
|
||||
mlc->cmd = 0xd0;
|
||||
|
||||
if (mlc_was_operation_successful()) {
|
||||
sc = RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
rtems_status_code lpc32xx_mlc_write_page_with_ecc(
|
||||
uint32_t page_index,
|
||||
const uint32_t *data,
|
||||
const uint32_t *spare
|
||||
)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_IO_ERROR;
|
||||
size_t small_pages_count = mlc_small_pages ? 1 : MLC_SMALL_PAGES_PER_LARGE_PAGE;
|
||||
size_t sp = 0;
|
||||
size_t i = 0;
|
||||
|
||||
if (page_index >= mlc_page_count) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
mlc_wait_until_ready();
|
||||
mlc->cmd = 0x80;
|
||||
mlc_set_page_address(page_index);
|
||||
|
||||
for (sp = 0; sp < small_pages_count; ++sp) {
|
||||
mlc->ecc_enc = 0;
|
||||
|
||||
for (i = 0; i < MLC_SMALL_DATA_WORD_COUNT; ++i) {
|
||||
mlc->data.w32 = data [i];
|
||||
}
|
||||
mlc->data.w32 = spare [0];
|
||||
mlc->data.w16 = (uint16_t) spare [1];
|
||||
mlc->wpr = 0;
|
||||
|
||||
mlc_wait(MLC_ISR_CONTROLLER_READY);
|
||||
|
||||
data += MLC_SMALL_DATA_WORD_COUNT;
|
||||
spare += MLC_SMALL_SPARE_WORD_COUNT;
|
||||
}
|
||||
|
||||
mlc->cmd = 0x10;
|
||||
|
||||
if (mlc_was_operation_successful()) {
|
||||
sc = RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
56
c/src/lib/libbsp/arm/lpc32xx/misc/restart.c
Normal file
56
c/src/lib/libbsp/arm/lpc32xx/misc/restart.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc32xx
|
||||
*
|
||||
* @brief Restart implementation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include <libcpu/arm-cp15.h>
|
||||
|
||||
#include <bsp.h>
|
||||
|
||||
void lpc32xx_restart(void *addr)
|
||||
{
|
||||
ARM_SWITCH_REGISTERS;
|
||||
rtems_interrupt_level level;
|
||||
uint32_t ctrl = 0;
|
||||
|
||||
/* FIXME: DMA shutdown */
|
||||
|
||||
/* FIXME: USB shutdown */
|
||||
|
||||
/* FIXME: Ethernet interface reset */
|
||||
|
||||
rtems_interrupt_disable(level);
|
||||
|
||||
arm_cp15_data_cache_test_and_clean();
|
||||
arm_cp15_instruction_cache_invalidate();
|
||||
|
||||
ctrl = arm_cp15_get_control();
|
||||
ctrl &= ~(ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M);
|
||||
arm_cp15_set_control(ctrl);
|
||||
|
||||
asm volatile (
|
||||
ARM_SWITCH_TO_ARM
|
||||
"mov pc, %[addr]\n"
|
||||
ARM_SWITCH_BACK
|
||||
: ARM_SWITCH_OUTPUT
|
||||
: [addr] "r" (addr)
|
||||
);
|
||||
}
|
||||
@@ -122,6 +122,22 @@ $(PROJECT_INCLUDE)/bsp/lpc-ethernet-config.h: include/lpc-ethernet-config.h $(PR
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/lpc-ethernet-config.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/lpc-ethernet-config.h
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/nand-mlc.h: include/nand-mlc.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/nand-mlc.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/nand-mlc.h
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/boot.h: include/boot.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/boot.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/boot.h
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/i2c.h: include/i2c.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/i2c.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/i2c.h
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/emc.h: include/emc.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/emc.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/emc.h
|
||||
|
||||
$(PROJECT_INCLUDE)/libcpu/cache.h: ../../../libcpu/arm/shared/include/cache.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/cache.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/cache.h
|
||||
@@ -138,6 +154,10 @@ $(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds
|
||||
TMPINSTALL_FILES += $(PROJECT_LIB)/linkcmds
|
||||
|
||||
$(PROJECT_LIB)/linkcmds.lpc32xx: startup/linkcmds.lpc32xx $(PROJECT_LIB)/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.lpc32xx
|
||||
TMPINSTALL_FILES += $(PROJECT_LIB)/linkcmds.lpc32xx
|
||||
|
||||
$(PROJECT_LIB)/linkcmds.base: ../shared/startup/linkcmds.base $(PROJECT_LIB)/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.base
|
||||
TMPINSTALL_FILES += $(PROJECT_LIB)/linkcmds.base
|
||||
|
||||
@@ -38,28 +38,14 @@
|
||||
#define LPC32XX_RTC_CTRL_MATCH_1_INTR (1U << 1)
|
||||
#define LPC32XX_RTC_CTRL_MATCH_0_INTR (1U << 0)
|
||||
|
||||
typedef struct {
|
||||
uint32_t ucount;
|
||||
uint32_t dcount;
|
||||
uint32_t match0;
|
||||
uint32_t match1;
|
||||
uint32_t ctrl;
|
||||
uint32_t intstat;
|
||||
uint32_t key;
|
||||
uint32_t sram [32];
|
||||
} lpc32xx_rtc_registers;
|
||||
|
||||
static volatile lpc32xx_rtc_registers *const lpc32xx_rtc =
|
||||
(volatile lpc32xx_rtc_registers *) LPC32XX_BASE_RTC;
|
||||
|
||||
static void lpc32xx_rtc_set(uint32_t val)
|
||||
{
|
||||
unsigned i = LPC32XX_ARM_CLK / LPC32XX_OSCILLATOR_RTC;
|
||||
|
||||
lpc32xx_rtc->ctrl |= LPC32XX_RTC_CTRL_STOP;
|
||||
lpc32xx_rtc->ucount = val;
|
||||
lpc32xx_rtc->dcount = LPC32XX_RTC_COUNTER_DELTA - val;
|
||||
lpc32xx_rtc->ctrl &= ~LPC32XX_RTC_CTRL_STOP;
|
||||
lpc32xx.rtc.ctrl |= LPC32XX_RTC_CTRL_STOP;
|
||||
lpc32xx.rtc.ucount = val;
|
||||
lpc32xx.rtc.dcount = LPC32XX_RTC_COUNTER_DELTA - val;
|
||||
lpc32xx.rtc.ctrl &= ~LPC32XX_RTC_CTRL_STOP;
|
||||
|
||||
/* It needs some time before we can read the values back */
|
||||
while (i != 0) {
|
||||
@@ -70,9 +56,9 @@ static void lpc32xx_rtc_set(uint32_t val)
|
||||
|
||||
static void lpc32xx_rtc_reset(void)
|
||||
{
|
||||
lpc32xx_rtc->ctrl = LPC32XX_RTC_CTRL_RESET;
|
||||
lpc32xx_rtc->ctrl = 0;
|
||||
lpc32xx_rtc->key = LPC32XX_RTC_KEY;
|
||||
lpc32xx.rtc.ctrl = LPC32XX_RTC_CTRL_RESET;
|
||||
lpc32xx.rtc.ctrl = 0;
|
||||
lpc32xx.rtc.key = LPC32XX_RTC_KEY;
|
||||
lpc32xx_rtc_set(0);
|
||||
}
|
||||
|
||||
@@ -83,15 +69,15 @@ static void lpc32xx_rtc_initialize(int minor)
|
||||
uint32_t down_first = 0;
|
||||
uint32_t down_second = 0;
|
||||
|
||||
if (lpc32xx_rtc->key != LPC32XX_RTC_KEY) {
|
||||
if (lpc32xx.rtc.key != LPC32XX_RTC_KEY) {
|
||||
lpc32xx_rtc_reset();
|
||||
}
|
||||
|
||||
do {
|
||||
up_first = lpc32xx_rtc->ucount;
|
||||
down_first = lpc32xx_rtc->dcount;
|
||||
up_second = lpc32xx_rtc->ucount;
|
||||
down_second = lpc32xx_rtc->dcount;
|
||||
up_first = lpc32xx.rtc.ucount;
|
||||
down_first = lpc32xx.rtc.dcount;
|
||||
up_second = lpc32xx.rtc.ucount;
|
||||
down_second = lpc32xx.rtc.dcount;
|
||||
} while (up_first != up_second || down_first != down_second);
|
||||
|
||||
if (up_first + down_first != LPC32XX_RTC_COUNTER_DELTA) {
|
||||
@@ -102,7 +88,7 @@ static void lpc32xx_rtc_initialize(int minor)
|
||||
static int lpc32xx_rtc_get_time(int minor, rtems_time_of_day *tod)
|
||||
{
|
||||
struct timeval now = {
|
||||
.tv_sec = lpc32xx_rtc->ucount,
|
||||
.tv_sec = lpc32xx.rtc.ucount,
|
||||
.tv_usec = 0
|
||||
};
|
||||
struct tm time;
|
||||
|
||||
@@ -27,21 +27,6 @@
|
||||
#include <bsp/stackalloc.h>
|
||||
#include <bsp/lpc32xx.h>
|
||||
|
||||
static void lpc32xx_timer_initialize(void)
|
||||
{
|
||||
volatile lpc_timer *timer = LPC32XX_STANDARD_TIMER;
|
||||
|
||||
LPC32XX_TIMCLK_CTRL1 = (1U << 2) | (1U << 3);
|
||||
|
||||
timer->tcr = LPC_TIMER_TCR_RST;
|
||||
timer->ctcr = 0x0;
|
||||
timer->pr = 0x0;
|
||||
timer->ir = 0xff;
|
||||
timer->mcr = 0x0;
|
||||
timer->ccr = 0x0;
|
||||
timer->tcr = LPC_TIMER_TCR_EN;
|
||||
}
|
||||
|
||||
void bsp_start(void)
|
||||
{
|
||||
if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) {
|
||||
@@ -52,6 +37,4 @@ void bsp_start(void)
|
||||
bsp_section_stack_begin,
|
||||
(uintptr_t) bsp_section_stack_size
|
||||
);
|
||||
|
||||
lpc32xx_timer_initialize();
|
||||
}
|
||||
|
||||
@@ -42,7 +42,9 @@
|
||||
#define LPC32XX_MMU_CODE LPC32XX_MMU_READ_ONLY_CACHED
|
||||
#endif
|
||||
|
||||
static void BSP_START_SECTION lpc32xx_clear_bss(void)
|
||||
LINKER_SYMBOL(lpc32xx_translation_table_base);
|
||||
|
||||
static void BSP_START_SECTION clear_bss(void)
|
||||
{
|
||||
const int *end = (const int *) bsp_section_bss_end;
|
||||
int *out = (int *) bsp_section_bss_begin;
|
||||
@@ -115,10 +117,14 @@ static void BSP_START_SECTION lpc32xx_clear_bss(void)
|
||||
.begin = 0x40000000U,
|
||||
.end = 0x40100000U,
|
||||
.flags = LPC32XX_MMU_READ_WRITE
|
||||
}, {
|
||||
.begin = (uint32_t) lpc32xx_magic_zero_begin,
|
||||
.end = (uint32_t) lpc32xx_magic_zero_end,
|
||||
.flags = LPC32XX_MMU_READ_WRITE_DATA
|
||||
}
|
||||
};
|
||||
|
||||
static void BSP_START_SECTION lpc32xx_mmu_set_entries(
|
||||
static void BSP_START_SECTION set_translation_table_entries(
|
||||
uint32_t *ttb,
|
||||
const lpc32xx_mmu_config *config
|
||||
)
|
||||
@@ -136,11 +142,11 @@ static void BSP_START_SECTION lpc32xx_clear_bss(void)
|
||||
}
|
||||
|
||||
static void BSP_START_SECTION
|
||||
lpc32xx_setup_translation_table_and_enable_mmu(uint32_t ctrl)
|
||||
setup_translation_table_and_enable_mmu(uint32_t ctrl)
|
||||
{
|
||||
uint32_t const dac =
|
||||
ARM_CP15_DAC_DOMAIN(LPC32XX_MMU_CLIENT_DOMAIN, ARM_CP15_DAC_CLIENT);
|
||||
uint32_t *const ttb = (uint32_t *) bsp_section_work_end;
|
||||
uint32_t *const ttb = (uint32_t *) lpc32xx_translation_table_base;
|
||||
size_t const config_entry_count =
|
||||
sizeof(lpc32xx_mmu_config_table) / sizeof(lpc32xx_mmu_config_table [0]);
|
||||
size_t i = 0;
|
||||
@@ -154,7 +160,7 @@ static void BSP_START_SECTION lpc32xx_clear_bss(void)
|
||||
}
|
||||
|
||||
for (i = 0; i < config_entry_count; ++i) {
|
||||
lpc32xx_mmu_set_entries(ttb, &lpc32xx_mmu_config_table [i]);
|
||||
set_translation_table_entries(ttb, &lpc32xx_mmu_config_table [i]);
|
||||
}
|
||||
|
||||
/* Enable MMU and cache */
|
||||
@@ -163,7 +169,7 @@ static void BSP_START_SECTION lpc32xx_clear_bss(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void BSP_START_SECTION lpc32xx_mmu_and_cache_setup(void)
|
||||
static void BSP_START_SECTION setup_mmu_and_cache(void)
|
||||
{
|
||||
uint32_t ctrl = 0;
|
||||
|
||||
@@ -178,7 +184,7 @@ static void BSP_START_SECTION lpc32xx_mmu_and_cache_setup(void)
|
||||
arm_cp15_tlb_invalidate();
|
||||
|
||||
#ifndef LPC32XX_DISABLE_MMU
|
||||
lpc32xx_setup_translation_table_and_enable_mmu(ctrl);
|
||||
setup_translation_table_and_enable_mmu(ctrl);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -186,7 +192,7 @@ static void BSP_START_SECTION lpc32xx_mmu_and_cache_setup(void)
|
||||
#error "unexpected main oscillator frequency"
|
||||
#endif
|
||||
|
||||
static void BSP_START_SECTION lpc32xx_pll_setup(void)
|
||||
static void BSP_START_SECTION setup_pll(void)
|
||||
{
|
||||
uint32_t pwr_ctrl = LPC32XX_PWR_CTRL;
|
||||
|
||||
@@ -207,11 +213,11 @@ static void BSP_START_SECTION lpc32xx_pll_setup(void)
|
||||
|
||||
void BSP_START_SECTION bsp_start_hook_0(void)
|
||||
{
|
||||
lpc32xx_pll_setup();
|
||||
lpc32xx_mmu_and_cache_setup();
|
||||
setup_pll();
|
||||
setup_mmu_and_cache();
|
||||
}
|
||||
|
||||
static void BSP_START_SECTION bsp_start_config_uarts(void)
|
||||
static void BSP_START_SECTION setup_uarts(void)
|
||||
{
|
||||
uint32_t uartclk_ctrl = 0;
|
||||
|
||||
@@ -246,9 +252,25 @@ static void BSP_START_SECTION bsp_start_config_uarts(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void BSP_START_SECTION setup_timer(void)
|
||||
{
|
||||
volatile lpc_timer *timer = LPC32XX_STANDARD_TIMER;
|
||||
|
||||
LPC32XX_TIMCLK_CTRL1 = (1U << 2) | (1U << 3);
|
||||
|
||||
timer->tcr = LPC_TIMER_TCR_RST;
|
||||
timer->ctcr = 0x0;
|
||||
timer->pr = 0x0;
|
||||
timer->ir = 0xff;
|
||||
timer->mcr = 0x0;
|
||||
timer->ccr = 0x0;
|
||||
timer->tcr = LPC_TIMER_TCR_EN;
|
||||
}
|
||||
|
||||
void BSP_START_SECTION bsp_start_hook_1(void)
|
||||
{
|
||||
bsp_start_config_uarts();
|
||||
setup_uarts();
|
||||
setup_timer();
|
||||
|
||||
/* Copy .text section */
|
||||
arm_cp15_instruction_cache_invalidate();
|
||||
@@ -283,7 +305,7 @@ void BSP_START_SECTION bsp_start_hook_1(void)
|
||||
);
|
||||
|
||||
/* Clear .bss section */
|
||||
lpc32xx_clear_bss();
|
||||
clear_bss();
|
||||
|
||||
/* At this point we can use objects outside the .start section */
|
||||
}
|
||||
|
||||
17
c/src/lib/libbsp/arm/lpc32xx/startup/linkcmds.lpc32xx
Normal file
17
c/src/lib/libbsp/arm/lpc32xx/startup/linkcmds.lpc32xx
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc32xx_linker
|
||||
*
|
||||
* @brief Linker support.
|
||||
*/
|
||||
|
||||
lpc32xx_translation_table_base = ORIGIN (RAM_MMU);
|
||||
|
||||
lpc32xx = 0x20020000;
|
||||
|
||||
lpc32xx_magic_zero_begin = 0x05000000;
|
||||
lpc32xx_magic_zero_end = 0x07000000;
|
||||
lpc32xx_magic_zero_size = lpc32xx_magic_zero_end - lpc32xx_magic_zero_end;
|
||||
|
||||
INCLUDE linkcmds.base
|
||||
63
c/src/lib/libbsp/arm/lpc32xx/startup/linkcmds.lpc32xx_mzx
Normal file
63
c/src/lib/libbsp/arm/lpc32xx/startup/linkcmds.lpc32xx_mzx
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc32xx_linker_mzx
|
||||
*
|
||||
* @brief Memory map.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup lpc32xx_linker_mzx MZX Application Memory Map
|
||||
*
|
||||
* @ingroup bsp_linker
|
||||
*
|
||||
* @brief MZX application memory map.
|
||||
*
|
||||
* <table>
|
||||
* <tr><th>Region Name</th><th>Region Begin</th><th>Region Size</th></tr>
|
||||
* <tr><td>RAM_INT</td><td>0x08000000</td><td>256k</td></tr>
|
||||
* <tr><td>RAM_MMU</td><td>0x80000000</td><td>16k</td></tr>
|
||||
* <tr><td>RAM_EXT</td><td>0x80004000</td><td>32M - 16k</td></tr>
|
||||
* </table>
|
||||
*
|
||||
* <table>
|
||||
* <tr><th>Section Name</th><th>Section Runtime Region</th><th>Section Load Region</th></tr>
|
||||
* <tr><td>.start</td><td>RAM_EXT</td><td></td></tr>
|
||||
* <tr><td>.vector</td><td>RAM_INT</td><td></td></tr>
|
||||
* <tr><td>.text</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
|
||||
* <tr><td>.rodata</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
|
||||
* <tr><td>.data</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
|
||||
* <tr><td>.fast</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
|
||||
* <tr><td>.bss</td><td>RAM_EXT</td><td></td></tr>
|
||||
* <tr><td>.work</td><td>RAM_EXT</td><td></td></tr>
|
||||
* <tr><td>.stack</td><td>RAM_INT</td><td></td></tr>
|
||||
* </table>
|
||||
*/
|
||||
|
||||
MEMORY {
|
||||
RAM_INT (AIW) : ORIGIN = 0x08000000, LENGTH = 256k
|
||||
RAM_MMU (AIW) : ORIGIN = 0x80000000, LENGTH = 16k /* SDRAM on DYCS0 */
|
||||
RAM_EXT (AIW) : ORIGIN = 0x80004000, LENGTH = 32M - 16k /* SDRAM on DYCS0 */
|
||||
NIRVANA : ORIGIN = 0, LENGTH = 0
|
||||
}
|
||||
|
||||
REGION_ALIAS ("REGION_START", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_VECTOR", RAM_INT);
|
||||
REGION_ALIAS ("REGION_TEXT", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_TEXT_LOAD", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_RODATA", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_RODATA_LOAD", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_DATA", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_DATA_LOAD", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_FAST", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_FAST_LOAD", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_BSS", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_WORK", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_STACK", RAM_INT);
|
||||
|
||||
bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 4096;
|
||||
bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024;
|
||||
|
||||
bsp_section_robarrier_align = DEFINED (bsp_section_robarrier_align) ? bsp_section_robarrier_align : 1M;
|
||||
|
||||
INCLUDE linkcmds.lpc32xx
|
||||
@@ -1,21 +1,23 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc32xx_linker_boot
|
||||
* @ingroup lpc32xx_linker_mzx_stage_1
|
||||
*
|
||||
* @brief Memory map.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup lpc32xx_linker_boot Boot Memory Map
|
||||
* @defgroup lpc32xx_linker_mzx_stage_1 MZX Stage-1 Program Memory Map
|
||||
*
|
||||
* @ingroup bsp_linker
|
||||
*
|
||||
* @brief Boot memory map.
|
||||
* @brief MZX stage-1 program memory map.
|
||||
*
|
||||
* <table>
|
||||
* <tr><th>Region Name</th><th>Region Begin</th><th>Region Size</th></tr>
|
||||
* <tr><td>RAM_INT</td><td>0x08000000</td><td>256k</td></tr>
|
||||
* <tr><td>RAM_INT</td><td>0x08000000</td><td>232k</td></tr>
|
||||
* <tr><td>RAM_MMU</td><td>0x0803a000</td><td>16k</td></tr>
|
||||
* <tr><td>RAM_VEC</td><td>0x0803d000</td><td>8k</td></tr>
|
||||
* </table>
|
||||
*
|
||||
* <table>
|
||||
@@ -33,12 +35,14 @@
|
||||
*/
|
||||
|
||||
MEMORY {
|
||||
RAM_INT (AIW) : ORIGIN = 0x08000000, LENGTH = 256k
|
||||
RAM_INT (AIW) : ORIGIN = 0x08000000, LENGTH = 232k
|
||||
RAM_VEC (AIW) : ORIGIN = 0x0803a000, LENGTH = 8k
|
||||
RAM_MMU (AIW) : ORIGIN = 0x0803c000, LENGTH = 16k
|
||||
NIRVANA : ORIGIN = 0, LENGTH = 0
|
||||
}
|
||||
|
||||
REGION_ALIAS ("REGION_START", RAM_INT);
|
||||
REGION_ALIAS ("REGION_VECTOR", RAM_INT);
|
||||
REGION_ALIAS ("REGION_VECTOR", RAM_VEC);
|
||||
REGION_ALIAS ("REGION_TEXT", RAM_INT);
|
||||
REGION_ALIAS ("REGION_TEXT_LOAD", RAM_INT);
|
||||
REGION_ALIAS ("REGION_RODATA", RAM_INT);
|
||||
@@ -51,7 +55,8 @@ REGION_ALIAS ("REGION_BSS", RAM_INT);
|
||||
REGION_ALIAS ("REGION_WORK", RAM_INT);
|
||||
REGION_ALIAS ("REGION_STACK", RAM_INT);
|
||||
|
||||
bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 4096;
|
||||
bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024;
|
||||
bsp_stack_svc_size = DEFINED (bsp_stack_svc_size) ? bsp_stack_svc_size : 7296;
|
||||
|
||||
INCLUDE linkcmds.base
|
||||
bsp_vector_table_in_start_section = 1;
|
||||
|
||||
INCLUDE linkcmds.lpc32xx
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc32xx_linker_mzx_stage_2
|
||||
*
|
||||
* @brief Memory map.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup lpc32xx_linker_mzx_stage_2 MZX Stage-2 Program Memory Map
|
||||
*
|
||||
* @ingroup bsp_linker
|
||||
*
|
||||
* @brief MZX stage-2 program memory map.
|
||||
*
|
||||
* <table>
|
||||
* <tr><th>Region Name</th><th>Region Begin</th><th>Region Size</th></tr>
|
||||
* <tr><td>RAM_INT</td><td>0x08000000</td><td>256k</td></tr>
|
||||
* <tr><td>RAM_MMU</td><td>0x81c00000</td><td>16k</td></tr>
|
||||
* <tr><td>RAM_EXT</td><td>0x81c04000</td><td>4M - 16k</td></tr>
|
||||
* </table>
|
||||
*
|
||||
* <table>
|
||||
* <tr><th>Section Name</th><th>Section Runtime Region</th><th>Section Load Region</th></tr>
|
||||
* <tr><td>.start</td><td>RAM_EXT</td><td></td></tr>
|
||||
* <tr><td>.vector</td><td>RAM_INT</td><td></td></tr>
|
||||
* <tr><td>.text</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
|
||||
* <tr><td>.rodata</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
|
||||
* <tr><td>.data</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
|
||||
* <tr><td>.fast</td><td>RAM_EXT</td><td>RAM_EXT</td></tr>
|
||||
* <tr><td>.bss</td><td>RAM_EXT</td><td></td></tr>
|
||||
* <tr><td>.work</td><td>RAM_EXT</td><td></td></tr>
|
||||
* <tr><td>.stack</td><td>RAM_INT</td><td></td></tr>
|
||||
* </table>
|
||||
*/
|
||||
|
||||
MEMORY {
|
||||
RAM_INT (AIW) : ORIGIN = 0x08000000, LENGTH = 256k
|
||||
RAM_MMU (AIW) : ORIGIN = 0x81c00000, LENGTH = 16k /* SDRAM on DYCS0 */
|
||||
RAM_EXT (AIW) : ORIGIN = 0x81c04000, LENGTH = 4M - 16k /* SDRAM on DYCS0 */
|
||||
NIRVANA : ORIGIN = 0, LENGTH = 0
|
||||
}
|
||||
|
||||
REGION_ALIAS ("REGION_START", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_VECTOR", RAM_INT);
|
||||
REGION_ALIAS ("REGION_TEXT", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_TEXT_LOAD", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_RODATA", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_RODATA_LOAD", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_DATA", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_DATA_LOAD", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_FAST", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_FAST_LOAD", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_BSS", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_WORK", RAM_EXT);
|
||||
REGION_ALIAS ("REGION_STACK", RAM_INT);
|
||||
|
||||
bsp_stack_svc_size = DEFINED (bsp_stack_svc_size) ? bsp_stack_svc_size : 8192;
|
||||
|
||||
INCLUDE linkcmds.lpc32xx
|
||||
@@ -16,7 +16,8 @@
|
||||
* <table>
|
||||
* <tr><th>Region Name</th><th>Region Begin</th><th>Region Size</th></tr>
|
||||
* <tr><td>RAM_INT</td><td>0x08000000</td><td>256k</td></tr>
|
||||
* <tr><td>RAM_EXT</td><td>0x80000000</td><td>64M</td></tr>
|
||||
* <tr><td>RAM_MMU</td><td>0x80000000</td><td>16k</td></tr>
|
||||
* <tr><td>RAM_EXT</td><td>0x80004000</td><td>64M - 16k</td></tr>
|
||||
* <tr><td>ROM_EXT</td><td>0xe0000000</td><td>2M</td></tr>
|
||||
* </table>
|
||||
*
|
||||
@@ -36,7 +37,8 @@
|
||||
|
||||
MEMORY {
|
||||
RAM_INT (AIW) : ORIGIN = 0x08000000, LENGTH = 256k
|
||||
RAM_EXT (AIW) : ORIGIN = 0x80000000, LENGTH = 64M - 16k /* SDRAM on DYCS0 */
|
||||
RAM_MMU (AIW) : ORIGIN = 0x80000000, LENGTH = 16k /* SDRAM on DYCS0 */
|
||||
RAM_EXT (AIW) : ORIGIN = 0x80004000, LENGTH = 64M - 16k /* SDRAM on DYCS0 */
|
||||
ROM_EXT (RX) : ORIGIN = 0xe0000000, LENGTH = 2M /* NOR flash on CS0 */
|
||||
NIRVANA : ORIGIN = 0, LENGTH = 0
|
||||
}
|
||||
@@ -60,4 +62,4 @@ bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024;
|
||||
|
||||
bsp_section_robarrier_align = DEFINED (bsp_section_robarrier_align) ? bsp_section_robarrier_align : 1M;
|
||||
|
||||
INCLUDE linkcmds.base
|
||||
INCLUDE linkcmds.lpc32xx
|
||||
|
||||
Reference in New Issue
Block a user