Changes throughout.

This commit is contained in:
Thomas Doerfler
2009-09-18 08:05:40 +00:00
parent f90c5fb37c
commit ba938b8d7d
19 changed files with 773 additions and 957 deletions

View File

@@ -1,3 +1,12 @@
2009-09-17 Sebastian Huber <sebastian.huber@embedded-brains.de>
* startup/bspstarthooks.c, misc/dma-copy.c, misc/timer.c: New files.
* Makefile.am, configure.ac, i2c/i2c.c, include/bsp.h, include/dma.h,
include/i2c.h, include/io.h, include/irq.h, include/lpc24xx.h,
include/ssp.h, include/system-clocks.h, irq/irq.c, misc/bspidle.c,
misc/dma.c, misc/io.c, misc/system-clocks.c, network/network.c,
ssp/ssp.c, startup/bspstart.c: Changes throughout.
2009-09-15 Ralf Corsépius <ralf.corsepius@rtems.org>
* configure.ac: Remove RTEMS_BSP_BOOTCARD_OPTIONS.

View File

@@ -90,6 +90,7 @@ libbsp_a_SOURCES += ../../shared/src/irq-generic.c \
../../shared/src/irq-legacy.c \
../../shared/src/irq-info.c \
../../shared/src/irq-shell.c \
../../shared/src/irq-server.c \
irq/irq.c
# Console
@@ -103,14 +104,14 @@ libbsp_a_SOURCES += clock/clock-config.c \
# RTC
libbsp_a_SOURCES += ../../shared/tod.c \
rtc/rtc-config.c
# Timer
libbsp_a_SOURCES += ../../shared/timerstub.c
# Misc
libbsp_a_SOURCES += misc/system-clocks.c \
misc/dma.c \
misc/dma-copy.c \
misc/bspidle.c \
misc/io.c
misc/io.c \
misc/timer.c
# SSP
libbsp_a_SOURCES += ssp/ssp.c
@@ -118,6 +119,13 @@ libbsp_a_SOURCES += ssp/ssp.c
# I2C
libbsp_a_SOURCES += i2c/i2c.c
# Start hooks (FIXME: This is brittle.)
libbsp_a_SOURCES += startup/bspstarthooks.c
bspstarthooks.o: startup/bspstarthooks.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS:-mthumb=) \
-MT bspstarthooks.o -MD -MP -MF $(DEPDIR)/bspstarthooks.Tpo -c -o bspstarthooks.o \
`test -f 'startup/bspstarthooks.c' || echo '$(srcdir)/'`startup/bspstarthooks.c
###############################################################################
# Network #
###############################################################################

View File

@@ -1,9 +1,9 @@
/**
* @file
*
* @ingroup lpc24xx
* @ingroup lpc24xx_libi2c
*
* LibI2C bus driver for the I2C modules.
* @brief LibI2C bus driver for the I2C modules.
*/
/*

View File

@@ -3,7 +3,7 @@
*
* @ingroup lpc24xx
*
* @brief Global BSP variables and functions.
* @brief Global BSP definitions.
*/
/*
@@ -35,25 +35,59 @@ extern "C" {
#ifndef ASM
/* Network driver configuration */
struct rtems_bsdnet_ifconfig;
/**
* @defgroup lpc24xx LPC24XX Support
*
* @ingroup bsp_kit
*
* @brief LPC24XX support package.
*
* @{
*/
/**
* @brief Network driver attach and detach function.
*/
int lpc24xx_eth_attach_detach(
struct rtems_bsdnet_ifconfig *config,
int attaching
);
/**
* @brief Standard network driver attach and detach function.
*/
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH lpc24xx_eth_attach_detach
/**
* @brief Standard network driver name.
*/
#define RTEMS_BSP_NETWORK_DRIVER_NAME "eth0"
/*
* BSP specific idle thread
/**
* @brief Optimized idle task.
*
* This idle task sets the power mode to idle. This causes the processor clock
* to be stopped, while on-chip peripherals remain active. Any enabled
* interrupt from a peripheral or an external interrupt source will cause the
* processor to resume execution.
*
* To enable the idle task use the following in the system configuration:
*
* @code
* #include <bsp.h>
*
* #define CONFIGURE_INIT
*
* #define CONFIGURE_IDLE_TASK_BODY lpc24xx_idle
*
* #include <confdefs.h>
* @endcode
*/
void *bsp_idle_thread( uint32_t ignored);
void *lpc24xx_idle(uintptr_t ignored);
#define BSP_IDLE_TASK_BODY bsp_idle_thread
/** @} */
#endif /* ASM */

View File

@@ -1,9 +1,9 @@
/**
* @file
*
* @ingroup lpc24xx
* @ingroup lpc24xx_dma
*
* @brief DMA support.
* @brief Direct memory access (DMA) support.
*/
/*
@@ -12,10 +12,11 @@
* Obere Lagerstr. 30
* D-82178 Puchheim
* Germany
* rtems@embedded-brains.de
* <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.
* 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_LPC24XX_DMA_H
@@ -27,14 +28,66 @@
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup lpc24xx_dma DMA Support
*
* @ingroup lpc24xx
*
* @brief Direct memory access (DMA) support.
*
* @{
*/
/**
* @brief Initializes the general purpose DMA.
*/
void lpc24xx_dma_initialize(void);
/**
* @brief Tries to obtain the DMA channel @a channel.
*
* @retval RTEMS_SUCCESSFUL Successful operation.
* @retval RTEMS_INVALID_ID Invalid channel number.
* @retval RTEMS_RESOURCE_IN_USE Channel already occupied.
*/
rtems_status_code lpc24xx_dma_channel_obtain(unsigned channel);
/**
* @brief Releases the DMA channel @a channel.
*
* You must have obtained this channel with lpc24xx_dma_channel_obtain()
* previously.
*
* If the channel number @a channel is out of range nothing will happen.
*/
void lpc24xx_dma_channel_release(unsigned channel);
/**
* @brief Disables the DMA channel @a channel.
*
* If @a force is @c false the channel will be halted and disabled when the
* channel is inactive otherwise it will be disabled immediately.
*
* If the channel number @a channel is out of range nothing will happen.
*/
void lpc24xx_dma_channel_disable(unsigned channel, bool force);
rtems_status_code lpc24xx_dma_copy_initialize(void);
rtems_status_code lpc24xx_dma_copy_release(void);
rtems_status_code lpc24xx_dma_copy(
unsigned channel,
void *dest,
const void *src,
size_t n,
size_t width
);
rtems_status_code lpc24xx_dma_copy_wait(unsigned channel);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -1,9 +1,9 @@
/**
* @file
*
* @ingroup lpc24xx
* @ingroup lpc24xx_libi2c
*
* LibI2C bus driver for the I2C modules.
* @brief LibI2C bus driver for the I2C modules.
*/
/*
@@ -28,12 +28,24 @@
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup lpc24xx_libi2c LPC24XX Bus Drivers
*
* @ingroup libi2c
*
* @brief LibI2C bus drivers for LPC24XX.
*
* @{
*/
extern rtems_libi2c_bus_t * const lpc24xx_i2c_0;
extern rtems_libi2c_bus_t * const lpc24xx_i2c_1;
extern rtems_libi2c_bus_t * const lpc24xx_i2c_2;
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -1,9 +1,9 @@
/**
* @file
*
* @ingroup lpc24xx
* @ingroup lpc24xx_io
*
* Input and output module.
* @brief Input and output module.
*/
/*
@@ -30,6 +30,16 @@
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup lpc24xx_io IO Support and Configuration
*
* @ingroup lpc24xx
*
* @brief Input and output module.
*
* @{
*/
#define LPC24XX_IO_PORT_COUNT 5U
#define LPC24XX_IO_INDEX_MAX (LPC24XX_IO_PORT_COUNT * 32U)
@@ -64,7 +74,7 @@ typedef enum {
LPC24XX_MODULE_UART,
LPC24XX_MODULE_USB,
LPC24XX_MODULE_WDT,
LPC24XX_MODULE_NUMBER
LPC24XX_MODULE_COUNT
} lpc24xx_module;
typedef enum {
@@ -159,6 +169,8 @@ static inline bool lpc24xx_gpio_get( unsigned index)
}
}
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -66,8 +66,8 @@
#define LPC24XX_IRQ_I2C_2 30
#define LPC24XX_IRQ_I2S 31
#define LPC24XX_IRQ_PRIORITY_VALUE_MIN 0
#define LPC24XX_IRQ_PRIORITY_VALUE_MAX 15
#define LPC24XX_IRQ_PRIORITY_VALUE_MIN 0U
#define LPC24XX_IRQ_PRIORITY_VALUE_MAX 15U
/**
* @brief Minimum vector number.

View File

@@ -1,7 +1,7 @@
/**
* @file
*
* @ingroup lpc24xx
* @ingroup lpc24xx_regs
*
* @brief Register definitions.
*/
@@ -25,6 +25,16 @@
#include <bsp/utility.h>
/**
* @defgroup lpc24xx_regs Register Definitions
*
* @ingroup lpc24xx
*
* @brief Register definitions.
*
* @{
*/
/* Vectored Interrupt Controller (VIC) */
#define VIC_BASE_ADDR 0xFFFFF000
#define VICIRQStatus (*(volatile uint32_t *) (VIC_BASE_ADDR + 0x000))
@@ -458,6 +468,7 @@ Reset, and Code Security/Debugging */
#define EMC_DYN_RASCAS3 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x184))
/* static RAM access registers */
#define EMC_STA_BASE_0 ((uint32_t *) (EMC_BASE_ADDR + 0x200))
#define EMC_STA_CFG0 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x200))
#define EMC_STA_WAITWEN0 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x204))
#define EMC_STA_WAITOEN0 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x208))
@@ -466,6 +477,7 @@ Reset, and Code Security/Debugging */
#define EMC_STA_WAITWR0 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x214))
#define EMC_STA_WAITTURN0 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x218))
#define EMC_STA_BASE_1 ((uint32_t *) (EMC_BASE_ADDR + 0x220))
#define EMC_STA_CFG1 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x220))
#define EMC_STA_WAITWEN1 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x224))
#define EMC_STA_WAITOEN1 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x228))
@@ -474,6 +486,7 @@ Reset, and Code Security/Debugging */
#define EMC_STA_WAITWR1 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x234))
#define EMC_STA_WAITTURN1 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x238))
#define EMC_STA_BASE_2 ((uint32_t *) (EMC_BASE_ADDR + 0x240))
#define EMC_STA_CFG2 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x240))
#define EMC_STA_WAITWEN2 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x244))
#define EMC_STA_WAITOEN2 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x248))
@@ -482,6 +495,7 @@ Reset, and Code Security/Debugging */
#define EMC_STA_WAITWR2 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x254))
#define EMC_STA_WAITTURN2 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x258))
#define EMC_STA_BASE_3 ((uint32_t *) (EMC_BASE_ADDR + 0x260))
#define EMC_STA_CFG3 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x260))
#define EMC_STA_WAITWEN3 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x264))
#define EMC_STA_WAITOEN3 (*(volatile uint32_t *) (EMC_BASE_ADDR + 0x268))
@@ -1646,6 +1660,10 @@ typedef struct {
uint32_t dest;
uint32_t lli;
uint32_t ctrl;
} lpc24xx_dma_descriptor;
typedef struct {
lpc24xx_dma_descriptor desc;
uint32_t cfg;
} lpc24xx_dma_channel;
@@ -2087,6 +2105,16 @@ typedef struct {
#define EMC_DYN_CTRL_CMD_NOP 0x00000180U
typedef struct {
uint32_t cfg;
uint32_t waitwen;
uint32_t waitoen;
uint32_t waitrd;
uint32_t waitpage;
uint32_t waitwr;
uint32_t waitrun;
} lpc24xx_emc_static;
/* I2C */
typedef struct {
@@ -2120,10 +2148,12 @@ typedef struct {
uint32_t clr;
} lpc24xx_fio;
static volatile uint32_t * const LPC24XX_PINSEL = &PINSEL0;
#define LPC24XX_PINSEL ((volatile uint32_t *) &PINSEL0)
static volatile uint32_t * const LPC24XX_PINMODE = &PINMODE0;
#define LPC24XX_PINMODE ((volatile uint32_t *) &PINMODE0)
static volatile lpc24xx_fio * const LPC24XX_FIO = (volatile lpc24xx_fio *) FIO_BASE_ADDR;
#define LPC24XX_FIO ((volatile lpc24xx_fio *) FIO_BASE_ADDR)
/** @} */
#endif /* LIBBSP_ARM_LPC24XX_LPC24XX_H */

View File

@@ -1,7 +1,7 @@
/**
* @file
*
* @ingroup lpc24xx
* @ingroup lpc24xx_libi2c
*
* @brief LibI2C bus driver for the Synchronous Serial Port (SSP).
*/
@@ -27,10 +27,18 @@
extern "C" {
#endif /* __cplusplus */
/**
* @ingroup lpc24xx_libi2c
*
* @{
*/
extern rtems_libi2c_bus_t * const lpc24xx_ssp_0;
extern rtems_libi2c_bus_t * const lpc24xx_ssp_1;
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -1,37 +1,86 @@
/**
* @file
*
* @ingroup lpc24xx
* @ingroup lpc24xx_clocks
*
* @brief System clocks.
*/
/*
* Copyright (c) 2008
* Embedded Brains GmbH
* Copyright (c) 2008, 2009
* embedded brains GmbH
* Obere Lagerstr. 30
* D-82178 Puchheim
* Germany
* rtems@embedded-brains.de
* <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.
* 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_LPC24XX_SYSTEM_CLOCKS_H
#define LIBBSP_ARM_LPC24XX_SYSTEM_CLOCKS_H
#include <bsp/lpc24xx.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void lpc24xx_micro_seconds_delay( unsigned us);
/**
* @defgroup lpc24xx_clock System Clocks
*
* @ingroup lpc24xx
*
* @brief System clocks.
*
* @{
*/
unsigned lpc24xx_pllclk( void);
/**
* @brief Initializes the standard timer.
*
* This function uses Timer 1.
*/
void lpc24xx_timer_initialize(void);
unsigned lpc24xx_cclk( void);
/**
* @brief Returns current standard timer value in CPU clocks.
*
* This function uses Timer 1.
*/
static inline unsigned lpc24xx_timer(void)
{
return T1TC;
}
void lpc24xx_set_pll( unsigned clksrc, unsigned nsel, unsigned msel, unsigned cclksel);
/**
* @brief Delay for @a us micro seconds.
*
* This function uses the standard timer and assumes that the CPU frequency is
* in whole MHz numbers. The delay value @a us will be converted to CPU ticks
* and there is no protection against integer overflows.
*
* This function uses Timer 1.
*/
void lpc24xx_micro_seconds_delay(unsigned us);
/**
* @brief Returns the PLL output clock frequency in [Hz].
*
* Returns zero in case of an unexpected PLL input frequency.
*/
unsigned lpc24xx_pllclk(void);
/**
* @brief Returns the CPU clock frequency in [Hz].
*
* Returns zero in case of an unexpected PLL input frequency.
*/
unsigned lpc24xx_cclk(void);
/** @} */
#ifdef __cplusplus
}

View File

@@ -44,7 +44,7 @@ unsigned lpc24xx_irq_priority( rtems_vector_number vector)
if (lpc24xx_irq_is_valid( vector)) {
return VICVectPriorityBase [vector];
} else {
return LPC24XX_IRQ_PRIORITY_VALUE_MIN - 1;
return LPC24XX_IRQ_PRIORITY_VALUE_MIN - 1U;
}
}

View File

@@ -24,7 +24,7 @@
#include <bsp.h>
#include <bsp/lpc24xx.h>
void *bsp_idle_thread(uint32_t ignored)
void *bsp_idle_thread(uintptr_t ignored)
{
while (true) {
/*

View File

@@ -1,9 +1,9 @@
/**
* @file
*
* @ingroup lpc24xx
* @ingroup lpc24xx_dma
*
* @brief DMA support.
* @brief Direct memory access (DMA) support.
*/
/*
@@ -12,10 +12,11 @@
* Obere Lagerstr. 30
* D-82178 Puchheim
* Germany
* rtems@embedded-brains.de
* <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.
* 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/endian.h>
@@ -29,9 +30,6 @@
*/
static bool lpc24xx_dma_channel_occupation [GPDMA_CH_NUMBER];
/**
* @brief Initializes the general purpose DMA.
*/
void lpc24xx_dma_initialize(void)
{
rtems_interrupt_level level;
@@ -57,13 +55,6 @@ void lpc24xx_dma_initialize(void)
GPDMA_SYNC = 0;
}
/**
* @brief Tries to obtain the channel @a channel.
*
* @retval RTEMS_SUCCESSFUL Successful operation.
* @retval RTEMS_INVALID_ID Invalid channel number.
* @retval RTEMS_RESOURCE_IN_USE Channel already occupied.
*/
rtems_status_code lpc24xx_dma_channel_obtain(unsigned channel)
{
if (channel < GPDMA_CH_NUMBER) {
@@ -81,14 +72,6 @@ rtems_status_code lpc24xx_dma_channel_obtain(unsigned channel)
}
}
/**
* @brief Releases the channel @a channel.
*
* You must have obtained this channel with lpc24xx_dma_channel_obtain()
* previously.
*
* If the channel number @a channel is out of range nothing will happen.
*/
void lpc24xx_dma_channel_release(unsigned channel)
{
if (channel < GPDMA_CH_NUMBER) {
@@ -96,29 +79,23 @@ void lpc24xx_dma_channel_release(unsigned channel)
}
}
/**
* @brief Disables the channel @a channel.
*
* If @a force is false the channel will be halted and disabled when the
* channel is inactive.
*
* If the channel number @a channel is out of range the behaviour is undefined.
*/
void lpc24xx_dma_channel_disable(unsigned channel, bool force)
{
volatile lpc24xx_dma_channel *ch = GPDMA_CH_BASE_ADDR(channel);
uint32_t cfg = ch->cfg;
if (!force) {
/* Halt */
ch->cfg = SET_FLAG(cfg, GPDMA_CH_CFG_HALT);
/* Wait for inactive */
do {
cfg = ch->cfg;
} while (IS_FLAG_SET(cfg, GPDMA_CH_CFG_ACTIVE));
if (channel < GPDMA_CH_NUMBER) {
volatile lpc24xx_dma_channel *ch = GPDMA_CH_BASE_ADDR(channel);
uint32_t cfg = ch->cfg;
if (!force) {
/* Halt */
ch->cfg = SET_FLAG(cfg, GPDMA_CH_CFG_HALT);
/* Wait for inactive */
do {
cfg = ch->cfg;
} while (IS_FLAG_SET(cfg, GPDMA_CH_CFG_ACTIVE));
}
/* Disable */
ch->cfg = CLEAR_FLAG(cfg, GPDMA_CH_CFG_EN);
}
/* Disable */
ch->cfg = CLEAR_FLAG(cfg, GPDMA_CH_CFG_EN);
}

View File

@@ -1,9 +1,9 @@
/**
* @file
*
* @ingroup lpc24xx
* @ingroup lpc24xx_io
*
* Input and output module.
* @brief Input and output module.
*/
/*
@@ -20,10 +20,11 @@
*/
#include <bsp/io.h>
#include <bsp/system-clocks.h>
#define LPC24XX_IO_SELECT( index) (index >> 4U)
#define LPC24XX_IO_SELECT(pin) (pin >> 4U)
#define LPC24XX_IO_SELECT_SHIFT( index) ((index & 0xfU) << 1U)
#define LPC24XX_IO_SELECT_SHIFT(pin) ((pin & 0xfU) << 1U)
#define LPC24XX_IO_SELECT_MASK 0x3U
@@ -35,136 +36,78 @@
#define LPC24XX_IO_ALTERNATE_2 0x3U
#define LPC24XX_IO_HEADER_FLAG 0x80U
#define LPC24XX_IO_ENTRY( b, e, f) \
{ .function = f, .begin = b, .end = e }
#define LPC24XX_IO_HEADER( module, index, config) \
{ .function = config | LPC24XX_IO_HEADER_FLAG, .begin = module, .end = index }
typedef struct __attribute__ ((__packed__)) {
unsigned char function;
unsigned char begin;
unsigned char end;
} lpc24xx_io_entry;
typedef void (*lpc24xx_io_iterate_routine)( unsigned /* index */, unsigned /* function */);
static const lpc24xx_io_entry lpc24xx_io_config_table [] = {
/* EMC */
LPC24XX_IO_HEADER( LPC24XX_MODULE_EMC, 0, 0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 2, 16), LPC24XX_IO_INDEX_BY_PORT( 2, 22), LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 2, 24), LPC24XX_IO_INDEX_BY_PORT( 2, 26), LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 2, 26), LPC24XX_IO_INDEX_BY_PORT( 2, 30), LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 3, 0), LPC24XX_IO_INDEX_BY_PORT( 3, 16), LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 4, 0), LPC24XX_IO_INDEX_BY_PORT( 4, 28), LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 4, 30), LPC24XX_IO_INDEX_BY_PORT( 5, 0), LPC24XX_IO_ALTERNATE_0),
/* UART */
LPC24XX_IO_HEADER( LPC24XX_MODULE_UART, 0, 0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 0, 2), LPC24XX_IO_INDEX_BY_PORT( 0, 4), LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_HEADER( LPC24XX_MODULE_UART, 1, 0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 0, 15), LPC24XX_IO_INDEX_BY_PORT( 0, 17), LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_HEADER( LPC24XX_MODULE_UART, 1, 1),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 2, 0), LPC24XX_IO_INDEX_BY_PORT( 2, 2), LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_HEADER( LPC24XX_MODULE_UART, 1, 2),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 3, 16), LPC24XX_IO_INDEX_BY_PORT( 3, 18), LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_HEADER( LPC24XX_MODULE_UART, 2, 0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 0, 10), LPC24XX_IO_INDEX_BY_PORT( 0, 12), LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_HEADER( LPC24XX_MODULE_UART, 2, 1),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 2, 8), LPC24XX_IO_INDEX_BY_PORT( 2, 10), LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_HEADER( LPC24XX_MODULE_UART, 2, 2),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 4, 22), LPC24XX_IO_INDEX_BY_PORT( 4, 24), LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_HEADER( LPC24XX_MODULE_UART, 3, 0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 0, 0), LPC24XX_IO_INDEX_BY_PORT( 0, 2), LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_HEADER( LPC24XX_MODULE_UART, 3, 1),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 0, 25), LPC24XX_IO_INDEX_BY_PORT( 0, 27), LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_HEADER( LPC24XX_MODULE_UART, 3, 2),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 4, 28), LPC24XX_IO_INDEX_BY_PORT( 4, 30), LPC24XX_IO_ALTERNATE_2),
/* Ethernet */
LPC24XX_IO_HEADER( LPC24XX_MODULE_ETHERNET, 0, 0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 1, 0), LPC24XX_IO_INDEX_BY_PORT( 1, 18), LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_HEADER( LPC24XX_MODULE_ETHERNET, 0, 1),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 1, 0), LPC24XX_IO_INDEX_BY_PORT( 1, 2), LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 1, 4), LPC24XX_IO_INDEX_BY_PORT( 1, 5), LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 1, 8), LPC24XX_IO_INDEX_BY_PORT( 1, 11), LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 1, 14), LPC24XX_IO_INDEX_BY_PORT( 1, 18), LPC24XX_IO_ALTERNATE_0),
/* ADC */
LPC24XX_IO_HEADER( LPC24XX_MODULE_ADC, 0, 0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 0, 12), LPC24XX_IO_INDEX_BY_PORT( 0, 14), LPC24XX_IO_ALTERNATE_2),
/* I2C */
LPC24XX_IO_HEADER( LPC24XX_MODULE_I2C, 0, 0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 0, 27), LPC24XX_IO_INDEX_BY_PORT( 0, 29), LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_HEADER( LPC24XX_MODULE_I2C, 1, 0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 0, 0), LPC24XX_IO_INDEX_BY_PORT( 0, 2), LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_HEADER( LPC24XX_MODULE_I2C, 1, 1),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 0, 19), LPC24XX_IO_INDEX_BY_PORT( 0, 21), LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_HEADER( LPC24XX_MODULE_I2C, 1, 2),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 2, 14), LPC24XX_IO_INDEX_BY_PORT( 2, 16), LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_HEADER( LPC24XX_MODULE_I2C, 2, 0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 0, 10), LPC24XX_IO_INDEX_BY_PORT( 0, 12), LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_HEADER( LPC24XX_MODULE_I2C, 2, 1),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 2, 30), LPC24XX_IO_INDEX_BY_PORT( 3, 0), LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_HEADER( LPC24XX_MODULE_I2C, 2, 2),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 4, 20), LPC24XX_IO_INDEX_BY_PORT( 4, 22), LPC24XX_IO_ALTERNATE_1),
/* USB */
LPC24XX_IO_HEADER( LPC24XX_MODULE_USB, 0, 0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 0, 29), LPC24XX_IO_INDEX_BY_PORT( 0, 31), LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY( LPC24XX_IO_INDEX_BY_PORT( 1, 19), LPC24XX_IO_INDEX_BY_PORT( 1, 20), LPC24XX_IO_ALTERNATE_1),
};
static size_t lpc24xx_io_get_entry_index( lpc24xx_module module, unsigned index, unsigned config)
{
size_t i = 0;
config |= LPC24XX_IO_HEADER_FLAG;
for (i = 0; i < sizeof( lpc24xx_io_config_table); ++i) {
const lpc24xx_io_entry *e = lpc24xx_io_config_table + i;
if (e->function == config && e->begin == module && e->end == index) {
return i + 1;
}
#define LPC24XX_IO_ENTRY(mod, idx, cfg, begin_port, begin_index, last_port, last_index, function) \
{ \
.module = mod, \
.index = idx, \
.config = cfg, \
.pin_begin = LPC24XX_IO_INDEX_BY_PORT(begin_port, begin_index), \
.pin_last = LPC24XX_IO_INDEX_BY_PORT(last_port, last_index), \
.pin_function = function \
}
return (size_t) -1;
}
typedef struct {
unsigned module : 5;
unsigned index : 4;
unsigned config : 4;
unsigned pin_begin : 8;
unsigned pin_last : 8;
unsigned pin_function : 3;
} lpc24xx_io_entry;
static void lpc24xx_io_do_config( unsigned index, unsigned function)
{
rtems_interrupt_level level;
unsigned select = LPC24XX_IO_SELECT( index);
unsigned shift = LPC24XX_IO_SELECT_SHIFT( index);
typedef void (*lpc24xx_io_iterate_routine)(unsigned /* pin */, unsigned /* function */);
rtems_interrupt_disable( level);
static const lpc24xx_io_entry lpc24xx_io_config_table [] = {
/* UART */
LPC24XX_IO_ENTRY(LPC24XX_MODULE_UART, 0, 0, 0, 2, 0, 3, LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_UART, 1, 0, 0, 15, 0, 16, LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_UART, 1, 1, 2, 0, 2, 1, LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_UART, 1, 2, 3, 16, 3, 17, LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_UART, 2, 0, 0, 10, 0, 11, LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_UART, 2, 1, 2, 8, 2, 9, LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_UART, 2, 2, 4, 22, 4, 23, LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_UART, 3, 0, 0, 0, 0, 1, LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_UART, 3, 1, 0, 25, 0, 26, LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_UART, 3, 2, 4, 28, 4, 29, LPC24XX_IO_ALTERNATE_2),
LPC24XX_PINSEL [select] =
(LPC24XX_PINSEL [select] & ~(LPC24XX_IO_SELECT_MASK << shift))
| ((function & LPC24XX_IO_SELECT_MASK) << shift);
/* Ethernet */
LPC24XX_IO_ENTRY(LPC24XX_MODULE_ETHERNET, 0, 0, 1, 0, 1, 17, LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_ETHERNET, 0, 1, 1, 0, 1, 1, LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_ETHERNET, 0, 1, 1, 4, 1, 4, LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_ETHERNET, 0, 1, 1, 8, 1, 10, LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_ETHERNET, 0, 1, 1, 14, 1, 17, LPC24XX_IO_ALTERNATE_0),
rtems_interrupt_flash( level);
/* ADC */
LPC24XX_IO_ENTRY(LPC24XX_MODULE_ADC, 0, 0, 0, 12, 0, 13, LPC24XX_IO_ALTERNATE_2),
LPC24XX_PINMODE [select] &= ~(LPC24XX_IO_SELECT_MASK << shift);
/* I2C */
LPC24XX_IO_ENTRY(LPC24XX_MODULE_I2C, 0, 0, 0, 27, 0, 28, LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_I2C, 1, 0, 0, 0, 0, 1, LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_I2C, 1, 1, 0, 19, 0, 20, LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_I2C, 1, 2, 2, 14, 2, 15, LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_I2C, 2, 0, 0, 10, 0, 11, LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_I2C, 2, 1, 2, 30, 2, 31, LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_I2C, 2, 2, 4, 20, 4, 21, LPC24XX_IO_ALTERNATE_1),
rtems_interrupt_enable( level);
}
/* SSP */
LPC24XX_IO_ENTRY(LPC24XX_MODULE_SSP, 0, 0, 0, 15, 0, 18, LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_SSP, 0, 1, 1, 20, 0, 21, LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_SSP, 0, 1, 1, 23, 0, 24, LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_SSP, 0, 2, 2, 22, 2, 23, LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_SSP, 0, 2, 2, 26, 2, 27, LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_SSP, 1, 0, 0, 6, 0, 9, LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_SSP, 1, 1, 0, 12, 0, 13, LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_SSP, 1, 1, 0, 14, 0, 14, LPC24XX_IO_ALTERNATE_2),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_SSP, 1, 1, 1, 31, 1, 31, LPC24XX_IO_ALTERNATE_1),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_SSP, 1, 2, 4, 20, 4, 23, LPC24XX_IO_ALTERNATE_2),
static void lpc24xx_io_do_release( unsigned index, unsigned function)
{
rtems_interrupt_level level;
unsigned select = LPC24XX_IO_SELECT( index);
unsigned shift = LPC24XX_IO_SELECT_SHIFT( index);
/* USB */
LPC24XX_IO_ENTRY(LPC24XX_MODULE_USB, 0, 0, 0, 29, 0, 30, LPC24XX_IO_ALTERNATE_0),
LPC24XX_IO_ENTRY(LPC24XX_MODULE_USB, 0, 0, 1, 19, 1, 19, LPC24XX_IO_ALTERNATE_1),
rtems_interrupt_disable( level);
LPC24XX_PINSEL [select] =
(LPC24XX_PINSEL [select] & ~(LPC24XX_IO_SELECT_MASK << shift));
rtems_interrupt_enable( level);
}
/* Terminate */
LPC24XX_IO_ENTRY(LPC24XX_MODULE_COUNT, 0, 0, 0, 0, 0, 0, 0),
};
static rtems_status_code lpc24xx_io_iterate(
lpc24xx_module module,
@@ -173,31 +116,58 @@ static rtems_status_code lpc24xx_io_iterate(
lpc24xx_io_iterate_routine routine
)
{
size_t i = lpc24xx_io_get_entry_index( module, index, config);
rtems_status_code sc = RTEMS_INVALID_ID;
const lpc24xx_io_entry *e = &lpc24xx_io_config_table [0];
if (i != (size_t) -1) {
const lpc24xx_io_entry * const table_end = lpc24xx_io_config_table
+ sizeof( lpc24xx_io_config_table) / sizeof( lpc24xx_io_config_table [0]);
const lpc24xx_io_entry *e = lpc24xx_io_config_table + i;
while (e->module != LPC24XX_MODULE_COUNT) {
if (e->module == module && e->index == index && e->config == config) {
unsigned pin = e->pin_begin;
unsigned last = e->pin_last;
unsigned function = e->pin_function;
while (e != table_end && (e->function & LPC24XX_IO_HEADER_FLAG) == 0) {
unsigned j = e->begin;
unsigned end = e->end;
unsigned function = e->function;
while (pin <= last) {
(*routine)(pin, function);
while (j < end) {
routine( j, function);
++j;
++pin;
}
++e;
sc = RTEMS_SUCCESSFUL;
}
} else {
return RTEMS_INVALID_ID;
++e;
}
return RTEMS_SUCCESSFUL;
return sc;
}
static void lpc24xx_io_do_config(unsigned pin, unsigned function)
{
rtems_interrupt_level level;
unsigned select = LPC24XX_IO_SELECT(pin);
unsigned shift = LPC24XX_IO_SELECT_SHIFT(pin);
rtems_interrupt_disable(level);
LPC24XX_PINSEL [select] =
(LPC24XX_PINSEL [select] & ~(LPC24XX_IO_SELECT_MASK << shift))
| ((function & LPC24XX_IO_SELECT_MASK) << shift);
rtems_interrupt_flash(level);
LPC24XX_PINMODE [select] &= ~(LPC24XX_IO_SELECT_MASK << shift);
rtems_interrupt_enable(level);
}
static void lpc24xx_io_do_release(unsigned pin, unsigned function)
{
rtems_interrupt_level level;
unsigned select = LPC24XX_IO_SELECT(pin);
unsigned shift = LPC24XX_IO_SELECT_SHIFT(pin);
rtems_interrupt_disable(level);
LPC24XX_PINSEL [select] =
(LPC24XX_PINSEL [select] & ~(LPC24XX_IO_SELECT_MASK << shift));
rtems_interrupt_enable(level);
}
rtems_status_code lpc24xx_io_config(
@@ -206,7 +176,7 @@ rtems_status_code lpc24xx_io_config(
unsigned config
)
{
return lpc24xx_io_iterate( module, index, config, lpc24xx_io_do_config);
return lpc24xx_io_iterate(module, index, config, lpc24xx_io_do_config);
}
rtems_status_code lpc24xx_io_release(
@@ -215,20 +185,20 @@ rtems_status_code lpc24xx_io_release(
unsigned config
)
{
return lpc24xx_io_iterate( module, index, config, lpc24xx_io_do_release);
return lpc24xx_io_iterate(module, index, config, lpc24xx_io_do_release);
}
rtems_status_code lpc24xx_gpio_config(
unsigned index,
unsigned pin,
lpc24xx_gpio_settings settings
)
{
if (index <= LPC24XX_IO_INDEX_MAX) {
if (pin <= LPC24XX_IO_INDEX_MAX) {
rtems_interrupt_level level;
unsigned port = LPC24XX_IO_PORT( index);
unsigned bit = LPC24XX_IO_PORT_BIT( index);
unsigned select = LPC24XX_IO_SELECT( index);
unsigned shift = LPC24XX_IO_SELECT_SHIFT( index);
unsigned port = LPC24XX_IO_PORT(pin);
unsigned bit = LPC24XX_IO_PORT_BIT(pin);
unsigned select = LPC24XX_IO_SELECT(pin);
unsigned shift = LPC24XX_IO_SELECT_SHIFT(pin);
unsigned resistor = settings & LPC24XX_GPIO_RESISTOR_MASK;
unsigned output = (settings & LPC24XX_GPIO_OUTPUT) != 0 ? 1U : 0U;
@@ -248,20 +218,20 @@ rtems_status_code lpc24xx_gpio_config(
return RTEMS_INVALID_NUMBER;
}
rtems_interrupt_disable( level);
rtems_interrupt_disable(level);
/* Resistor */
LPC24XX_PINMODE [select] =
(LPC24XX_PINMODE [select] & ~(LPC24XX_IO_SELECT_MASK << shift))
| ((resistor & LPC24XX_IO_SELECT_MASK) << shift);
rtems_interrupt_flash( level);
rtems_interrupt_flash(level);
/* Input or output */
LPC24XX_FIO [port].dir =
(LPC24XX_FIO [port].dir & ~(1U << bit)) | (output << bit);
rtems_interrupt_enable( level);
rtems_interrupt_enable(level);
} else {
return RTEMS_INVALID_ID;
}
@@ -445,12 +415,12 @@ static rtems_status_code lpc24xx_module_do_enable(
if (enable) {
rtems_interrupt_level level;
rtems_interrupt_disable( level);
rtems_interrupt_disable(level);
PCONP |= 1U << power_bit;
rtems_interrupt_enable( level);
rtems_interrupt_enable(level);
if (module != LPC24XX_MODULE_USB) {
rtems_interrupt_disable( level);
rtems_interrupt_disable(level);
if (clock_shift < 32U) {
PCLKSEL0 = (PCLKSEL0 & ~(LPC24XX_MODULE_CLOCK_MASK << clock_shift))
| (clock << clock_shift);
@@ -459,7 +429,7 @@ static rtems_status_code lpc24xx_module_do_enable(
PCLKSEL1 = (PCLKSEL1 & ~(LPC24XX_MODULE_CLOCK_MASK << clock_shift))
| (clock << clock_shift);
}
rtems_interrupt_enable( level);
rtems_interrupt_enable(level);
} else {
unsigned pllclk = lpc24xx_pllclk();
unsigned usbsel = pllclk / 48000000U - 1U;
@@ -473,9 +443,9 @@ static rtems_status_code lpc24xx_module_do_enable(
} else {
rtems_interrupt_level level;
rtems_interrupt_disable( level);
rtems_interrupt_disable(level);
PCONP &= ~(1U << power_bit);
rtems_interrupt_enable( level);
rtems_interrupt_enable(level);
}
return RTEMS_SUCCESSFUL;
@@ -487,7 +457,7 @@ rtems_status_code lpc24xx_module_enable(
lpc24xx_module_clock clock
)
{
return lpc24xx_module_do_enable( module, index, clock, true);
return lpc24xx_module_do_enable(module, index, clock, true);
}
rtems_status_code lpc24xx_module_disable(
@@ -495,5 +465,5 @@ rtems_status_code lpc24xx_module_disable(
unsigned index
)
{
return lpc24xx_module_do_enable( module, index, 0U, false);
return lpc24xx_module_do_enable(module, index, 0U, false);
}

View File

@@ -1,7 +1,7 @@
/**
* @file
*
* @ingroup lpc24xx
* @ingroup lpc24xx_clocks
*
* @brief System clocks.
*/
@@ -36,45 +36,44 @@
#error "unknown RTC oscillator frequency"
#endif
/**
* @brief Delay for @a us micro seconds.
*
* @note Uses Timer 1.
*/
void lpc24xx_micro_seconds_delay( unsigned us)
void lpc24xx_timer_initialize(void)
{
/* Stop and reset timer */
T1TCR = 0x02;
/* Reset timer */
T1TCR = TCR_RST;
/* Set timer mode */
T1CTCR = 0;
/* Set prescaler to zero */
T1PR = 0x00;
/* Set match value */
T1MR0 = (uint32_t) ((uint64_t) 4000000 * (uint64_t) us / (uint64_t) lpc24xx_cclk()) + 1;
T1PR = 0;
/* Reset all interrupt flags */
T1IR = 0xff;
/* Stop timer on match */
T1MCR = 0x04;
/* Do not stop on a match */
T1MCR = 0;
/* No captures */
T1CCR = 0;
/* Start timer */
T1TCR = 0x01;
/* Wait until delay time has elapsed */
while ((T1TCR & 0x01) != 0) {
/* Wait */
}
T1TCR = TCR_EN;
}
/**
* @brief Returns the PLL output clock frequency in [Hz].
*
* Returns zero in case of an unexpected PLL input frequency.
*/
unsigned lpc24xx_pllclk( void)
void lpc24xx_micro_seconds_delay(unsigned us)
{
unsigned clksrc = GET_CLKSRCSEL_CLKSRC( CLKSRCSEL);
unsigned start = lpc24xx_timer();
unsigned end = start + us * (lpc24xx_cclk() / 1000000);
unsigned now = 0;
do {
now = lpc24xx_timer();
} while (now < end);
}
unsigned lpc24xx_pllclk(void)
{
unsigned clksrc = GET_CLKSRCSEL_CLKSRC(CLKSRCSEL);
unsigned pllinclk = 0;
unsigned pllclk = 0;
@@ -94,10 +93,10 @@ unsigned lpc24xx_pllclk( void)
}
/* Get PLL output frequency */
if (IS_FLAG_SET( PLLSTAT, PLLSTAT_PLLC)) {
if (IS_FLAG_SET(PLLSTAT, PLLSTAT_PLLC)) {
uint32_t pllcfg = PLLCFG;
unsigned n = GET_PLLCFG_NSEL( pllcfg) + 1;
unsigned m = GET_PLLCFG_MSEL( pllcfg) + 1;
unsigned n = GET_PLLCFG_NSEL(pllcfg) + 1;
unsigned m = GET_PLLCFG_MSEL(pllcfg) + 1;
pllclk = (pllinclk / n) * 2 * m;
} else {
@@ -107,81 +106,13 @@ unsigned lpc24xx_pllclk( void)
return pllclk;
}
/**
* @brief Returns the CPU clock frequency in [Hz].
*
* Returns zero in case of an unexpected PLL input frequency.
*/
unsigned lpc24xx_cclk( void)
unsigned lpc24xx_cclk(void)
{
/* Get PLL output frequency */
unsigned pllclk = lpc24xx_pllclk();
/* Get CPU frequency */
unsigned cclk = pllclk / (GET_CCLKCFG_CCLKSEL( CCLKCFG) + 1);
unsigned cclk = pllclk / (GET_CCLKCFG_CCLKSEL(CCLKCFG) + 1);
return cclk;
}
static void lpc24xx_pll_config( uint32_t val)
{
PLLCON = val;
PLLFEED = 0xaa;
PLLFEED = 0x55;
}
/**
* @brief Sets the Phase Locked Loop (PLL).
*
* @param clksrc Selects the clock source for the PLL.
*
* @param nsel Selects PLL pre-divider value (sometimes named psel).
*
* @param msel Selects PLL multiplier value.
*
* @param cclksel Selects the divide value for creating the CPU clock (CCLK)
* from the PLL output.
*
* @note All parameter values are the actual register field values.
*/
void lpc24xx_set_pll( unsigned clksrc, unsigned nsel, unsigned msel, unsigned cclksel)
{
bool pll_enabled = IS_FLAG_SET( PLLSTAT, PLLSTAT_PLLE);
/* Disconnect PLL if necessary */
if (IS_FLAG_SET( PLLSTAT, PLLSTAT_PLLC)) {
if (pll_enabled) {
lpc24xx_pll_config( PLLCON_PLLE);
} else {
lpc24xx_pll_config( 0);
}
}
/* Set CPU clock divider to a reasonable save value */
CCLKCFG = 0;
/* Disable PLL if necessary */
if (pll_enabled) {
lpc24xx_pll_config( 0);
}
/* Select clock source */
CLKSRCSEL = SET_CLKSRCSEL_CLKSRC( 0, clksrc);
/* Set PLL Configuration Register */
PLLCFG = SET_PLLCFG_NSEL( 0, nsel) | SET_PLLCFG_MSEL( 0, msel);
/* Enable PLL */
lpc24xx_pll_config( PLLCON_PLLE);
/* Wait for lock */
while (IS_FLAG_CLEARED( PLLSTAT, PLLSTAT_PLOCK)) {
/* Wait */
}
/* Set CPU clock divider and ensure that we have an odd value */
CCLKCFG = SET_CCLKCFG_CCLKSEL( 0, cclksel | 1);
/* Connect PLL */
lpc24xx_pll_config( PLLCON_PLLE | PLLCON_PLLC);
}

View File

@@ -170,11 +170,11 @@ static char lpc24xx_eth_transmit_buffer [LPC24XX_ETH_TRANSMIT_DATA_SIZE];
| ETH_TX_CTRL_LAST)
#ifdef DEBUG
#define LPC24XX_ETH_PRINTF( ...) printf( __VA_ARGS__)
#define LPC24XX_ETH_PRINTK( ...) printk( __VA_ARGS__)
#define LPC24XX_ETH_PRINTF(...) printf(__VA_ARGS__)
#define LPC24XX_ETH_PRINTK(...) printk(__VA_ARGS__)
#else
#define LPC24XX_ETH_PRINTF( ...)
#define LPC24XX_ETH_PRINTK( ...)
#define LPC24XX_ETH_PRINTF(...)
#define LPC24XX_ETH_PRINTK(...)
#endif
typedef enum {
@@ -231,7 +231,7 @@ static inline uint32_t lpc24xx_eth_increment(
}
}
static void lpc24xx_eth_reset_filter( void)
static void lpc24xx_eth_reset_filter(void)
{
MAC_RXFILTERCTRL = 0;
MAC_RXFILTERWOLCLR = 0xcf;
@@ -239,7 +239,7 @@ static void lpc24xx_eth_reset_filter( void)
MAC_HASHFILTERH = 0;
}
static void lpc24xx_eth_enable_promiscous_mode( bool enable)
static void lpc24xx_eth_enable_promiscous_mode(bool enable)
{
if (enable) {
MAC_RXFILTERCTRL = ETH_RX_FIL_CTRL_ACCEPT_PERFECT
@@ -267,98 +267,98 @@ static void lpc24xx_eth_interrupt_handler(
uint32_t is = MAC_INTSTATUS & im;
/* Check receive interrupts */
if (IS_FLAG_SET( is, ETH_INT_RX_OVERRUN)) {
if (IS_FLAG_SET(is, ETH_INT_RX_OVERRUN)) {
re = LPC24XX_ETH_EVENT_INITIALIZE;
++e->receive_fatal_errors;
} else if (IS_ANY_FLAG_SET( is, LPC24XX_ETH_INTERRUPT_RECEIVE)) {
} else if (IS_ANY_FLAG_SET(is, LPC24XX_ETH_INTERRUPT_RECEIVE)) {
re = LPC24XX_ETH_EVENT_INTERRUPT;
ie = SET_FLAGS( ie, LPC24XX_ETH_INTERRUPT_RECEIVE);
ie = SET_FLAGS(ie, LPC24XX_ETH_INTERRUPT_RECEIVE);
}
/* Send events to receive task */
if (re != 0) {
++e->receive_interrupts;
(void) rtems_event_send( e->receive_task, re);
(void) rtems_event_send(e->receive_task, re);
}
/* Check transmit interrupts */
if (IS_FLAG_SET( is, ETH_INT_TX_UNDERRUN)) {
if (IS_FLAG_SET(is, ETH_INT_TX_UNDERRUN)) {
te = LPC24XX_ETH_EVENT_INITIALIZE;
++e->transmit_fatal_errors;
} else if (IS_ANY_FLAG_SET( is, LPC24XX_ETH_INTERRUPT_TRANSMIT)) {
} else if (IS_ANY_FLAG_SET(is, LPC24XX_ETH_INTERRUPT_TRANSMIT)) {
te = LPC24XX_ETH_EVENT_INTERRUPT;
ie = SET_FLAGS( ie, LPC24XX_ETH_INTERRUPT_TRANSMIT);
ie = SET_FLAGS(ie, LPC24XX_ETH_INTERRUPT_TRANSMIT);
}
/* Send events to transmit task */
if (te != 0) {
++e->transmit_interrupts;
(void) rtems_event_send( e->transmit_task, te);
(void) rtems_event_send(e->transmit_task, te);
}
LPC24XX_ETH_PRINTK( "interrupt: rx = 0x%08x, tx = 0x%08x\n", re, te);
LPC24XX_ETH_PRINTK("interrupt: rx = 0x%08x, tx = 0x%08x\n", re, te);
/* Update interrupt mask */
MAC_INTENABLE = CLEAR_FLAGS( im, ie);
MAC_INTENABLE = CLEAR_FLAGS(im, ie);
/* Clear interrupts */
MAC_INTCLEAR = is;
}
static void lpc24xx_eth_enable_receive_interrupts( void)
static void lpc24xx_eth_enable_receive_interrupts(void)
{
rtems_interrupt_level level;
rtems_interrupt_disable( level);
MAC_INTENABLE = SET_FLAGS( MAC_INTENABLE, LPC24XX_ETH_INTERRUPT_RECEIVE);
rtems_interrupt_enable( level);
rtems_interrupt_disable(level);
MAC_INTENABLE = SET_FLAGS(MAC_INTENABLE, LPC24XX_ETH_INTERRUPT_RECEIVE);
rtems_interrupt_enable(level);
}
static void lpc24xx_eth_disable_receive_interrupts( void)
static void lpc24xx_eth_disable_receive_interrupts(void)
{
rtems_interrupt_level level;
rtems_interrupt_disable( level);
MAC_INTENABLE = CLEAR_FLAGS( MAC_INTENABLE, LPC24XX_ETH_INTERRUPT_RECEIVE);
rtems_interrupt_enable( level);
rtems_interrupt_disable(level);
MAC_INTENABLE = CLEAR_FLAGS(MAC_INTENABLE, LPC24XX_ETH_INTERRUPT_RECEIVE);
rtems_interrupt_enable(level);
}
static void lpc24xx_eth_enable_transmit_interrupts( void)
static void lpc24xx_eth_enable_transmit_interrupts(void)
{
rtems_interrupt_level level;
rtems_interrupt_disable( level);
MAC_INTENABLE = SET_FLAGS( MAC_INTENABLE, LPC24XX_ETH_INTERRUPT_TRANSMIT);
rtems_interrupt_enable( level);
rtems_interrupt_disable(level);
MAC_INTENABLE = SET_FLAGS(MAC_INTENABLE, LPC24XX_ETH_INTERRUPT_TRANSMIT);
rtems_interrupt_enable(level);
}
static void lpc24xx_eth_disable_transmit_interrupts( void)
static void lpc24xx_eth_disable_transmit_interrupts(void)
{
rtems_interrupt_level level;
rtems_interrupt_disable( level);
MAC_INTENABLE = CLEAR_FLAGS( MAC_INTENABLE, LPC24XX_ETH_INTERRUPT_TRANSMIT);
rtems_interrupt_enable( level);
rtems_interrupt_disable(level);
MAC_INTENABLE = CLEAR_FLAGS(MAC_INTENABLE, LPC24XX_ETH_INTERRUPT_TRANSMIT);
rtems_interrupt_enable(level);
}
static struct mbuf *lpc24xx_eth_new_mbuf( struct ifnet *ifp, bool wait)
static struct mbuf *lpc24xx_eth_new_mbuf(struct ifnet *ifp, bool wait)
{
struct mbuf *m = NULL;
int mw = wait ? M_WAIT : M_DONTWAIT;
MGETHDR( m, mw, MT_DATA);
MGETHDR(m, mw, MT_DATA);
if (m != NULL) {
MCLGET( m, mw);
if (IS_FLAG_SET( m->m_flags, M_EXT)) {
MCLGET(m, mw);
if (IS_FLAG_SET(m->m_flags, M_EXT)) {
/* Set receive interface */
m->m_pkthdr.rcvif = ifp;
/* Adjust by two bytes for proper IP header alignment */
m->m_data = mtod( m, char *) + 2;
m->m_data = mtod(m, char *) + 2;
return m;
} else {
m_free( m);
m_free(m);
}
}
@@ -374,13 +374,13 @@ static bool lpc24xx_eth_add_new_mbuf(
)
{
/* New mbuf */
struct mbuf *m = lpc24xx_eth_new_mbuf( ifp, wait);
struct mbuf *m = lpc24xx_eth_new_mbuf(ifp, wait);
/* Check mbuf */
if (m != NULL) {
/* Add mbuf to queue */
desc [i].start = mtod( m, uint32_t);
desc [i].control = SET_ETH_RX_CTRL_SIZE( 0, MCLBYTES - 1)
desc [i].start = mtod(m, uint32_t);
desc [i].control = SET_ETH_RX_CTRL_SIZE(0, MCLBYTES - 1)
| ETH_RX_CTRL_INTERRUPT;
/* Add mbuf to table */
@@ -392,7 +392,7 @@ static bool lpc24xx_eth_add_new_mbuf(
}
}
static void lpc24xx_eth_receive_task( void *arg)
static void lpc24xx_eth_receive_task(void *arg)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
rtems_event_set events = 0;
@@ -411,7 +411,7 @@ static void lpc24xx_eth_receive_task( void *arg)
uint32_t consume_index = 0;
uint32_t receive_index = 0;
LPC24XX_ETH_PRINTF( "%s\n", __func__);
LPC24XX_ETH_PRINTF("%s\n", __func__);
/* Main event loop */
while (true) {
@@ -424,25 +424,25 @@ static void lpc24xx_eth_receive_task( void *arg)
RTEMS_NO_TIMEOUT,
&events
);
RTEMS_CLEANUP_SC( sc, cleanup, "wait for events");
RTEMS_CLEANUP_SC(sc, cleanup, "wait for events");
LPC24XX_ETH_PRINTF( "rx: wake up: 0x%08" PRIx32 "\n", events);
LPC24XX_ETH_PRINTF("rx: wake up: 0x%08" PRIx32 "\n", events);
/* Initialize receiver? */
if (IS_FLAG_SET( events, LPC24XX_ETH_EVENT_INITIALIZE)) {
if (IS_FLAG_SET(events, LPC24XX_ETH_EVENT_INITIALIZE)) {
/* Disable receive interrupts */
lpc24xx_eth_disable_receive_interrupts();
/* Disable receiver */
MAC_COMMAND = CLEAR_FLAG( MAC_COMMAND, ETH_CMD_RX_ENABLE);
MAC_COMMAND = CLEAR_FLAG(MAC_COMMAND, ETH_CMD_RX_ENABLE);
/* Wait for inactive status */
while (IS_FLAG_SET( MAC_STATUS, ETH_STAT_RX_ACTIVE)) {
while (IS_FLAG_SET(MAC_STATUS, ETH_STAT_RX_ACTIVE)) {
/* Wait */
}
/* Reset */
MAC_COMMAND = SET_FLAG( MAC_COMMAND, ETH_CMD_RX_RESET);
MAC_COMMAND = SET_FLAG(MAC_COMMAND, ETH_CMD_RX_RESET);
/* Clear receive interrupts */
MAC_INTCLEAR = LPC24XX_ETH_INTERRUPT_RECEIVE;
@@ -462,7 +462,7 @@ static void lpc24xx_eth_receive_task( void *arg)
/* Fill receive queue */
for (produce_index = consume_index; produce_index <= index_max; ++produce_index) {
if (
!lpc24xx_eth_add_new_mbuf( ifp, desc, mbuf_table, produce_index, false)
!lpc24xx_eth_add_new_mbuf(ifp, desc, mbuf_table, produce_index, false)
) {
break;
}
@@ -478,7 +478,7 @@ static void lpc24xx_eth_receive_task( void *arg)
/* Reduce the queue size */
index_max = produce_index - 1;
RTEMS_SYSLOG_ERROR( "not enough mbufs to fill receive queue");
RTEMS_SYSLOG_ERROR("not enough mbufs to fill receive queue");
}
/* Receive descriptor table */
@@ -492,7 +492,7 @@ static void lpc24xx_eth_receive_task( void *arg)
receive_index = consume_index;
/* Enable receiver */
MAC_COMMAND = SET_FLAG( MAC_COMMAND, ETH_CMD_RX_ENABLE);
MAC_COMMAND = SET_FLAG(MAC_COMMAND, ETH_CMD_RX_ENABLE);
/* Enable receive interrupts */
lpc24xx_eth_enable_receive_interrupts();
@@ -517,58 +517,58 @@ static void lpc24xx_eth_receive_task( void *arg)
mbuf_table [receive_index] = NULL;
if (
IS_FLAG_SET( stat, ETH_RX_STAT_LAST_FLAG)
&& ARE_FLAGS_CLEARED( stat, LPC24XX_ETH_RX_STAT_ERRORS)
IS_FLAG_SET(stat, ETH_RX_STAT_LAST_FLAG)
&& ARE_FLAGS_CLEARED(stat, LPC24XX_ETH_RX_STAT_ERRORS)
) {
/* Ethernet header */
struct ether_header *eh = mtod( m, struct ether_header *);
struct ether_header *eh = mtod(m, struct ether_header *);
/* Discard Ethernet header and CRC */
int sz = (int) GET_ETH_RX_STAT_RXSIZE( stat) + 1
int sz = (int) GET_ETH_RX_STAT_RXSIZE(stat) + 1
- ETHER_HDR_LEN - ETHER_CRC_LEN;
/* Update mbuf */
m->m_len = sz;
m->m_pkthdr.len = sz;
m->m_data = mtod( m, char *) + ETHER_HDR_LEN;
m->m_data = mtod(m, char *) + ETHER_HDR_LEN;
LPC24XX_ETH_PRINTF( "rx: %02" PRIu32 ": %u\n", receive_index, sz);
LPC24XX_ETH_PRINTF("rx: %02" PRIu32 ": %u\n", receive_index, sz);
/* Hand over */
ether_input( ifp, eh, m);
ether_input(ifp, eh, m);
/* Increment received frames counter */
++e->received_frames;
} else {
/* Release mbuf */
m_free( m);
m_free(m);
/* Update error counters */
if (IS_FLAG_SET( stat, ETH_RX_STAT_OVERRUN)) {
if (IS_FLAG_SET(stat, ETH_RX_STAT_OVERRUN)) {
++e->receive_overrun_errors;
}
if (IS_FLAG_CLEARED( stat, ETH_RX_STAT_LAST_FLAG)) {
if (IS_FLAG_CLEARED(stat, ETH_RX_STAT_LAST_FLAG)) {
++e->receive_fragment_errors;
}
if (IS_FLAG_SET( stat, ETH_RX_STAT_CRC_ERROR)) {
if (IS_FLAG_SET(stat, ETH_RX_STAT_CRC_ERROR)) {
++e->receive_crc_errors;
}
if (IS_FLAG_SET( stat, ETH_RX_STAT_SYMBOL_ERROR)) {
if (IS_FLAG_SET(stat, ETH_RX_STAT_SYMBOL_ERROR)) {
++e->receive_symbol_errors;
}
if (IS_FLAG_SET( stat, ETH_RX_STAT_LENGTH_ERROR)) {
if (IS_FLAG_SET(stat, ETH_RX_STAT_LENGTH_ERROR)) {
++e->receive_length_errors;
}
if (IS_FLAG_SET( stat, ETH_RX_STAT_ALIGNMENT_ERROR)) {
if (IS_FLAG_SET(stat, ETH_RX_STAT_ALIGNMENT_ERROR)) {
++e->receive_alignment_errors;
}
if (IS_FLAG_SET( stat, ETH_RX_STAT_NO_DESCRIPTOR)) {
if (IS_FLAG_SET(stat, ETH_RX_STAT_NO_DESCRIPTOR)) {
++e->receive_no_descriptor_errors;
}
}
/* Increment receive index */
receive_index = lpc24xx_eth_increment( receive_index, index_max);
receive_index = lpc24xx_eth_increment(receive_index, index_max);
} else {
/* Nothing to do, enable receive interrupts */
lpc24xx_eth_enable_receive_interrupts();
@@ -578,7 +578,7 @@ static void lpc24xx_eth_receive_task( void *arg)
/* Wait for mbuf? */
wait_for_mbuf =
lpc24xx_eth_increment( produce_index, index_max) == consume_index;
lpc24xx_eth_increment(produce_index, index_max) == consume_index;
/* Fill queue with new mbufs */
while (consume_index != produce_index) {
@@ -595,7 +595,7 @@ static void lpc24xx_eth_receive_task( void *arg)
wait_for_mbuf = false;
/* Increment consume index */
consume_index = lpc24xx_eth_increment( consume_index, index_max);
consume_index = lpc24xx_eth_increment(consume_index, index_max);
/* Update consume indices */
MAC_RXCONSUMEINDEX = consume_index;
@@ -611,7 +611,7 @@ cleanup:
rtems_bsdnet_semaphore_release();
/* Terminate self */
(void) rtems_task_delete( RTEMS_SELF);
(void) rtems_task_delete(RTEMS_SELF);
}
static struct mbuf *lpc24xx_eth_next_fragment(
@@ -626,7 +626,7 @@ static struct mbuf *lpc24xx_eth_next_fragment(
while (true) {
if (m == NULL) {
/* Dequeue first fragment of the next frame */
IF_DEQUEUE( &ifp->if_snd, m);
IF_DEQUEUE(&ifp->if_snd, m);
/* Empty queue? */
if (m == NULL) {
@@ -642,29 +642,29 @@ static struct mbuf *lpc24xx_eth_next_fragment(
break;
} else {
/* Discard empty fragments */
m = m_free( m);
m = m_free(m);
}
}
/* Set fragment size */
*ctrl = SET_ETH_TX_CTRL_SIZE( 0, size - 1);
*ctrl = SET_ETH_TX_CTRL_SIZE(0, size - 1);
/* Discard empty successive fragments */
n = m->m_next;
while (n != NULL && n->m_len <= 0) {
n = m_free( n);
n = m_free(n);
}
m->m_next = n;
/* Is our fragment the last in the frame? */
if (n == NULL) {
*ctrl = SET_FLAGS( *ctrl, LPC24XX_ETH_LAST_FRAGMENT_FLAGS);
*ctrl = SET_FLAGS(*ctrl, LPC24XX_ETH_LAST_FRAGMENT_FLAGS);
}
return m;
}
static void lpc24xx_eth_transmit_task( void *arg)
static void lpc24xx_eth_transmit_task(void *arg)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
rtems_event_set events = 0;
@@ -685,7 +685,7 @@ static void lpc24xx_eth_transmit_task( void *arg)
uint32_t frame_length = 0;
char *frame_buffer = NULL;
LPC24XX_ETH_PRINTF( "%s\n", __func__);
LPC24XX_ETH_PRINTF("%s\n", __func__);
/* Initialize descriptor table */
for (produce_index = 0; produce_index <= index_max; ++produce_index) {
@@ -704,25 +704,25 @@ static void lpc24xx_eth_transmit_task( void *arg)
RTEMS_NO_TIMEOUT,
&events
);
RTEMS_CLEANUP_SC( sc, cleanup, "wait for events");
RTEMS_CLEANUP_SC(sc, cleanup, "wait for events");
LPC24XX_ETH_PRINTF( "tx: wake up: 0x%08" PRIx32 "\n", events);
LPC24XX_ETH_PRINTF("tx: wake up: 0x%08" PRIx32 "\n", events);
/* Initialize transmitter? */
if (IS_FLAG_SET( events, LPC24XX_ETH_EVENT_INITIALIZE)) {
if (IS_FLAG_SET(events, LPC24XX_ETH_EVENT_INITIALIZE)) {
/* Disable transmit interrupts */
lpc24xx_eth_disable_transmit_interrupts();
/* Disable transmitter */
MAC_COMMAND = CLEAR_FLAG( MAC_COMMAND, ETH_CMD_TX_ENABLE);
MAC_COMMAND = CLEAR_FLAG(MAC_COMMAND, ETH_CMD_TX_ENABLE);
/* Wait for inactive status */
while (IS_FLAG_SET( MAC_STATUS, ETH_STAT_TX_ACTIVE)) {
while (IS_FLAG_SET(MAC_STATUS, ETH_STAT_TX_ACTIVE)) {
/* Wait */
}
/* Reset */
MAC_COMMAND = SET_FLAG( MAC_COMMAND, ETH_CMD_TX_RESET);
MAC_COMMAND = SET_FLAG(MAC_COMMAND, ETH_CMD_TX_RESET);
/* Clear transmit interrupts */
MAC_INTCLEAR = LPC24XX_ETH_INTERRUPT_TRANSMIT;
@@ -740,7 +740,7 @@ static void lpc24xx_eth_transmit_task( void *arg)
frame_buffer = (char *) desc [produce_index].start;
/* Enable transmitter */
MAC_COMMAND = SET_FLAG( MAC_COMMAND, ETH_CMD_TX_ENABLE);
MAC_COMMAND = SET_FLAG(MAC_COMMAND, ETH_CMD_TX_ENABLE);
}
/* Free consumed fragments */
@@ -764,34 +764,34 @@ static void lpc24xx_eth_transmit_task( void *arg)
/* Update error counters */
if (
IS_ANY_FLAG_SET( s, ETH_TX_STAT_ERROR | ETH_TX_STAT_NO_DESCRIPTOR)
IS_ANY_FLAG_SET(s, ETH_TX_STAT_ERROR | ETH_TX_STAT_NO_DESCRIPTOR)
) {
if (IS_FLAG_SET( s, ETH_TX_STAT_UNDERRUN)) {
if (IS_FLAG_SET(s, ETH_TX_STAT_UNDERRUN)) {
++e->transmit_underrun_errors;
}
if (IS_FLAG_SET( s, ETH_TX_STAT_LATE_COLLISION)) {
if (IS_FLAG_SET(s, ETH_TX_STAT_LATE_COLLISION)) {
++e->transmit_late_collision_errors;
}
if (IS_FLAG_SET( s, ETH_TX_STAT_EXCESSIVE_COLLISION)) {
if (IS_FLAG_SET(s, ETH_TX_STAT_EXCESSIVE_COLLISION)) {
++e->transmit_excessive_collision_errors;
}
if (IS_FLAG_SET( s, ETH_TX_STAT_EXCESSIVE_DEFER)) {
if (IS_FLAG_SET(s, ETH_TX_STAT_EXCESSIVE_DEFER)) {
++e->transmit_excessive_defer_errors;
}
if (IS_FLAG_SET( s, ETH_TX_STAT_NO_DESCRIPTOR)) {
if (IS_FLAG_SET(s, ETH_TX_STAT_NO_DESCRIPTOR)) {
++e->transmit_no_descriptor_errors;
}
}
/* Next consume index */
c = lpc24xx_eth_increment( c, index_max);
c = lpc24xx_eth_increment(c, index_max);
}
}
/* Transmit new fragments */
while (true) {
/* Compute next produce index */
uint32_t p = lpc24xx_eth_increment( produce_index, index_max);
uint32_t p = lpc24xx_eth_increment(produce_index, index_max);
/* Queue full? */
if (p == consume_index) {
@@ -800,24 +800,24 @@ static void lpc24xx_eth_transmit_task( void *arg)
}
/* Get next fragment and control value */
m = lpc24xx_eth_next_fragment( ifp, m, &ctrl);
m = lpc24xx_eth_next_fragment(ifp, m, &ctrl);
/* New fragment? */
if (m != NULL) {
size_t fragment_length = (size_t) m->m_len;
void *fragment_start = mtod( m, void *);
void *fragment_start = mtod(m, void *);
uint32_t new_frame_length = frame_length + fragment_length;
/* Check buffer size */
if (new_frame_length > LPC24XX_ETH_TRANSMIT_BUFFER_SIZE) {
LPC24XX_ETH_PRINTF( "tx: overflow\n");
LPC24XX_ETH_PRINTF("tx: overflow\n");
/* Discard overflow data */
new_frame_length = LPC24XX_ETH_TRANSMIT_BUFFER_SIZE;
fragment_length = new_frame_length - frame_length;
/* Finalize frame */
ctrl = SET_FLAGS( ctrl, LPC24XX_ETH_LAST_FRAGMENT_FLAGS);
ctrl = SET_FLAGS(ctrl, LPC24XX_ETH_LAST_FRAGMENT_FLAGS);
/* Update error counter */
++e->transmit_overflow_errors;
@@ -826,19 +826,19 @@ static void lpc24xx_eth_transmit_task( void *arg)
LPC24XX_ETH_PRINTF(
"tx: copy: %" PRIu32 "%s%s\n",
fragment_length,
IS_FLAG_SET( m->m_flags, M_EXT) ? ", E" : "",
IS_FLAG_SET( m->m_flags, M_PKTHDR) ? ", H" : ""
IS_FLAG_SET(m->m_flags, M_EXT) ? ", E" : "",
IS_FLAG_SET(m->m_flags, M_PKTHDR) ? ", H" : ""
);
/* Copy fragment to buffer in Ethernet RAM */
memcpy( frame_buffer, fragment_start, fragment_length);
memcpy(frame_buffer, fragment_start, fragment_length);
if (IS_FLAG_SET( ctrl, ETH_TX_CTRL_LAST)) {
if (IS_FLAG_SET(ctrl, ETH_TX_CTRL_LAST)) {
/* Finalize descriptor */
desc [produce_index].control =
SET_ETH_TX_CTRL_SIZE( ctrl, new_frame_length - 1);
SET_ETH_TX_CTRL_SIZE(ctrl, new_frame_length - 1);
LPC24XX_ETH_PRINTF( "tx: %02" PRIu32 ": %" PRIu32 "\n", produce_index, new_frame_length);
LPC24XX_ETH_PRINTF("tx: %02" PRIu32 ": %" PRIu32 "\n", produce_index, new_frame_length);
/* Next produce index */
produce_index = p;
@@ -861,7 +861,7 @@ static void lpc24xx_eth_transmit_task( void *arg)
}
/* Free mbuf and get next */
m = m_free( m);
m = m_free(m);
} else {
/* Nothing to transmit */
break;
@@ -871,7 +871,7 @@ static void lpc24xx_eth_transmit_task( void *arg)
/* No more fragments? */
if (m == NULL) {
/* Interface is now inactive */
ifp->if_flags = CLEAR_FLAG( ifp->if_flags, IFF_OACTIVE);
ifp->if_flags = CLEAR_FLAG(ifp->if_flags, IFF_OACTIVE);
} else {
/* Enable transmit interrupts */
lpc24xx_eth_enable_transmit_interrupts();
@@ -887,79 +887,68 @@ cleanup:
rtems_bsdnet_semaphore_release();
/* Terminate self */
(void) rtems_task_delete( RTEMS_SELF);
(void) rtems_task_delete(RTEMS_SELF);
}
static void lpc24xx_eth_interface_init( void *arg)
static void lpc24xx_eth_interface_init(void *arg)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
lpc24xx_eth_driver_entry *e = (lpc24xx_eth_driver_entry *) arg;
struct ifnet *ifp = &e->arpcom.ac_if;
LPC24XX_ETH_PRINTF( "%s\n", __func__);
LPC24XX_ETH_PRINTF("%s\n", __func__);
if (e->state == LPC24XX_ETH_INITIALIZED) {
#ifndef LPC24XX_HAS_UBOOT
/* Enable module power */
lpc24xx_module_enable(
LPC24XX_MODULE_ETHERNET,
0,
LPC24XX_MODULE_PCLK_DEFAULT
);
/* Enable module power */
lpc24xx_module_enable(
LPC24XX_MODULE_ETHERNET,
0,
LPC24XX_MODULE_PCLK_DEFAULT
);
/* Module IO configuration */
#ifdef LPC24XX_ETHERNET_RMII
lpc24xx_io_config( LPC24XX_MODULE_ETHERNET, 0, 0);
#else
lpc24xx_io_config( LPC24XX_MODULE_ETHERNET, 0, 1);
#endif
/* Module IO configuration */
#ifdef LPC24XX_ETHERNET_RMII
lpc24xx_io_config(LPC24XX_MODULE_ETHERNET, 0, 0);
#else
lpc24xx_io_config(LPC24XX_MODULE_ETHERNET, 0, 1);
#endif
/* Soft reset */
/* Soft reset */
/* Do soft reset */
MAC_COMMAND = 0x38;
MAC_MAC1 = 0xcf00;
/* Do soft reset */
MAC_COMMAND = 0x38;
MAC_MAC1 = 0xcf00;
/* Initialize PHY */
/* TODO */
/* Initialize PHY */
/* TODO */
/* Reinitialize registers */
MAC_MAC2 = 0x31;
MAC_IPGT = 0x15;
MAC_IPGR = 0x12;
MAC_CLRT = 0x370f;
MAC_MAXF = 0x0600;
MAC_SUPP = 0x0100;
MAC_TEST = 0;
#ifdef LPC24XX_ETHERNET_RMII
MAC_COMMAND = 0x0400;
#else
MAC_COMMAND = 0x0600;
#endif
MAC_INTENABLE = 0;
MAC_INTCLEAR = 0x30ff;
MAC_POWERDOWN = 0;
/* Reinitialize registers */
MAC_MAC2 = 0x31;
MAC_IPGT = 0x15;
MAC_IPGR = 0x12;
MAC_CLRT = 0x370f;
MAC_MAXF = 0x0600;
MAC_SUPP = 0x0100;
MAC_TEST = 0;
#ifdef LPC24XX_ETHERNET_RMII
MAC_COMMAND = 0x0400;
#else
MAC_COMMAND = 0x0600;
#endif
MAC_INTENABLE = 0;
MAC_INTCLEAR = 0x30ff;
MAC_POWERDOWN = 0;
/* MAC address */
MAC_SA0 = ((uint32_t) e->arpcom.ac_enaddr [5] << 8)
| (uint32_t) e->arpcom.ac_enaddr [4];
MAC_SA1 = ((uint32_t) e->arpcom.ac_enaddr [3] << 8)
| (uint32_t) e->arpcom.ac_enaddr [2];
MAC_SA2 = ((uint32_t) e->arpcom.ac_enaddr [1] << 8)
| (uint32_t) e->arpcom.ac_enaddr [0];
/* MAC address */
MAC_SA0 = ((uint32_t) e->arpcom.ac_enaddr [5] << 8)
| (uint32_t) e->arpcom.ac_enaddr [4];
MAC_SA1 = ((uint32_t) e->arpcom.ac_enaddr [3] << 8)
| (uint32_t) e->arpcom.ac_enaddr [2];
MAC_SA2 = ((uint32_t) e->arpcom.ac_enaddr [1] << 8)
| (uint32_t) e->arpcom.ac_enaddr [0];
/* Enable receiver */
MAC_MAC1 = 0x03;
#else /* LPC24XX_HAS_UBOOT */
/* Reset receiver and transmitter */
MAC_COMMAND = SET_FLAGS(
MAC_COMMAND,
ETH_CMD_RX_RESET | ETH_CMD_TX_RESET | ETH_CMD_REG_RESET
);
/* MAC configuration */
MAC_MAC1 = 0x3;
#endif /* LPC24XX_HAS_UBOOT */
/* Enable receiver */
MAC_MAC1 = 0x03;
/* Start receive task */
if (e->receive_task == RTEMS_ID_NONE) {
@@ -969,8 +958,8 @@ static void lpc24xx_eth_interface_init( void *arg)
lpc24xx_eth_receive_task,
e
);
sc = rtems_event_send( e->receive_task, LPC24XX_ETH_EVENT_INITIALIZE);
RTEMS_SYSLOG_ERROR_SC( sc, "send receive initialize event");
sc = rtems_event_send(e->receive_task, LPC24XX_ETH_EVENT_INITIALIZE);
RTEMS_SYSLOG_ERROR_SC(sc, "send receive initialize event");
}
/* Start transmit task */
@@ -981,8 +970,8 @@ static void lpc24xx_eth_interface_init( void *arg)
lpc24xx_eth_transmit_task,
e
);
sc = rtems_event_send( e->transmit_task, LPC24XX_ETH_EVENT_INITIALIZE);
RTEMS_SYSLOG_ERROR_SC( sc, "send transmit initialize event");
sc = rtems_event_send(e->transmit_task, LPC24XX_ETH_EVENT_INITIALIZE);
RTEMS_SYSLOG_ERROR_SC(sc, "send transmit initialize event");
}
/* Change state */
@@ -999,43 +988,43 @@ static void lpc24xx_eth_interface_init( void *arg)
/* Enable promiscous mode */
lpc24xx_eth_enable_promiscous_mode(
IS_FLAG_SET( ifp->if_flags, IFF_PROMISC)
IS_FLAG_SET(ifp->if_flags, IFF_PROMISC)
);
/* Start watchdog timer */
ifp->if_timer = 1;
/* Set interface to running state */
ifp->if_flags = SET_FLAG( ifp->if_flags, IFF_RUNNING);
ifp->if_flags = SET_FLAG(ifp->if_flags, IFF_RUNNING);
/* Change state */
e->state = LPC24XX_ETH_RUNNING;
}
}
static void lpc24xx_eth_interface_stats( const lpc24xx_eth_driver_entry *e)
static void lpc24xx_eth_interface_stats(const lpc24xx_eth_driver_entry *e)
{
rtems_bsdnet_semaphore_release();
printf( "received frames: %u\n", e->received_frames);
printf( "receive interrupts: %u\n", e->receive_interrupts);
printf( "transmitted frames: %u\n", e->transmitted_frames);
printf( "transmit interrupts: %u\n", e->transmit_interrupts);
printf( "receive overrun errors: %u\n", e->receive_overrun_errors);
printf( "receive fragment errors: %u\n", e->receive_fragment_errors);
printf( "receive CRC errors: %u\n", e->receive_crc_errors);
printf( "receive symbol errors: %u\n", e->receive_symbol_errors);
printf( "receive length errors: %u\n", e->receive_length_errors);
printf( "receive alignment errors: %u\n", e->receive_alignment_errors);
printf( "receive no descriptor errors: %u\n", e->receive_no_descriptor_errors);
printf( "receive fatal errors: %u\n", e->receive_fatal_errors);
printf( "transmit underrun errors: %u\n", e->transmit_underrun_errors);
printf( "transmit late collision errors: %u\n", e->transmit_late_collision_errors);
printf( "transmit excessive collision errors: %u\n", e->transmit_excessive_collision_errors);
printf( "transmit excessive defer errors: %u\n", e->transmit_excessive_defer_errors);
printf( "transmit no descriptor errors: %u\n", e->transmit_no_descriptor_errors);
printf( "transmit overflow errors: %u\n", e->transmit_overflow_errors);
printf( "transmit fatal errors: %u\n", e->transmit_fatal_errors);
printf("received frames: %u\n", e->received_frames);
printf("receive interrupts: %u\n", e->receive_interrupts);
printf("transmitted frames: %u\n", e->transmitted_frames);
printf("transmit interrupts: %u\n", e->transmit_interrupts);
printf("receive overrun errors: %u\n", e->receive_overrun_errors);
printf("receive fragment errors: %u\n", e->receive_fragment_errors);
printf("receive CRC errors: %u\n", e->receive_crc_errors);
printf("receive symbol errors: %u\n", e->receive_symbol_errors);
printf("receive length errors: %u\n", e->receive_length_errors);
printf("receive alignment errors: %u\n", e->receive_alignment_errors);
printf("receive no descriptor errors: %u\n", e->receive_no_descriptor_errors);
printf("receive fatal errors: %u\n", e->receive_fatal_errors);
printf("transmit underrun errors: %u\n", e->transmit_underrun_errors);
printf("transmit late collision errors: %u\n", e->transmit_late_collision_errors);
printf("transmit excessive collision errors: %u\n", e->transmit_excessive_collision_errors);
printf("transmit excessive defer errors: %u\n", e->transmit_excessive_defer_errors);
printf("transmit no descriptor errors: %u\n", e->transmit_no_descriptor_errors);
printf("transmit overflow errors: %u\n", e->transmit_overflow_errors);
printf("transmit fatal errors: %u\n", e->transmit_fatal_errors);
rtems_bsdnet_semaphore_obtain();
}
@@ -1049,28 +1038,28 @@ static int lpc24xx_eth_interface_ioctl(
lpc24xx_eth_driver_entry *e = (lpc24xx_eth_driver_entry *) ifp->if_softc;
int rv = 0;
LPC24XX_ETH_PRINTF( "%s\n", __func__);
LPC24XX_ETH_PRINTF("%s\n", __func__);
switch (command) {
case SIOCGIFMEDIA:
case SIOCSIFMEDIA:
rtems_mii_ioctl( &e->mdio_info, e, (int) command, (int *) data);
rtems_mii_ioctl(&e->mdio_info, e, (int) command, (int *) data);
break;
case SIOCGIFADDR:
case SIOCSIFADDR:
ether_ioctl( ifp, command, data);
ether_ioctl(ifp, command, data);
break;
case SIOCSIFFLAGS:
if (ifp->if_flags & IFF_RUNNING) {
/* TODO: off */
}
if (ifp->if_flags & IFF_UP) {
ifp->if_flags = SET_FLAG( ifp->if_flags, IFF_RUNNING);
ifp->if_flags = SET_FLAG(ifp->if_flags, IFF_RUNNING);
/* TODO: init */
}
break;
case SIO_RTEMS_SHOW_STATS:
lpc24xx_eth_interface_stats( e);
lpc24xx_eth_interface_stats(e);
break;
default:
rv = EINVAL;
@@ -1080,46 +1069,46 @@ static int lpc24xx_eth_interface_ioctl(
return rv;
}
static void lpc24xx_eth_interface_start( struct ifnet *ifp)
static void lpc24xx_eth_interface_start(struct ifnet *ifp)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
lpc24xx_eth_driver_entry *e = (lpc24xx_eth_driver_entry *) ifp->if_softc;
ifp->if_flags = SET_FLAG( ifp->if_flags, IFF_OACTIVE);
ifp->if_flags = SET_FLAG(ifp->if_flags, IFF_OACTIVE);
sc = rtems_event_send( e->transmit_task, LPC24XX_ETH_EVENT_START);
RTEMS_SYSLOG_ERROR_SC( sc, "send transmit start event");
sc = rtems_event_send(e->transmit_task, LPC24XX_ETH_EVENT_START);
RTEMS_SYSLOG_ERROR_SC(sc, "send transmit start event");
}
static void lpc24xx_eth_interface_watchdog( struct ifnet *ifp)
static void lpc24xx_eth_interface_watchdog(struct ifnet *ifp)
{
lpc24xx_eth_driver_entry *e = (lpc24xx_eth_driver_entry *) ifp->if_softc;
LPC24XX_ETH_PRINTF( "%s\n", __func__);
LPC24XX_ETH_PRINTF("%s\n", __func__);
}
static int lpc24xx_eth_attach( struct rtems_bsdnet_ifconfig *config)
static int lpc24xx_eth_attach(struct rtems_bsdnet_ifconfig *config)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
lpc24xx_eth_driver_entry *e = &lpc24xx_eth_driver_data;
struct ifnet *ifp = &e->arpcom.ac_if;
char *unit_name = NULL;
int unit_number = rtems_bsdnet_parse_driver_name( config, &unit_name);
int unit_number = rtems_bsdnet_parse_driver_name(config, &unit_name);
uint32_t reg = 0;
/* Check parameter */
if (unit_number < 0) {
RTEMS_SYSLOG_ERROR( "parse error for interface name\n");
RTEMS_SYSLOG_ERROR("parse error for interface name\n");
return 0;
}
if (unit_number != 0) {
RTEMS_DO_CLEANUP( cleanup, "unexpected unit number");
RTEMS_DO_CLEANUP(cleanup, "unexpected unit number");
}
if (config->hardware_address == NULL) {
RTEMS_DO_CLEANUP( cleanup, "MAC address missing");
RTEMS_DO_CLEANUP(cleanup, "MAC address missing");
}
if (e->state != LPC24XX_ETH_NOT_INITIALIZED) {
RTEMS_DO_CLEANUP( cleanup, "already attached");
RTEMS_DO_CLEANUP(cleanup, "already attached");
}
/* Interrupt number */
@@ -1157,13 +1146,13 @@ static int lpc24xx_eth_attach( struct rtems_bsdnet_ifconfig *config)
lpc24xx_eth_interrupt_handler,
e
);
RTEMS_CLEANUP_SC( sc, cleanup, "install interrupt handler");
RTEMS_CLEANUP_SC(sc, cleanup, "install interrupt handler");
/* Copy MAC address */
memcpy( e->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
memcpy(e->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
/* Clear Ethernet RAM */
memset( (void *) LPC24XX_ETH_RAM_START, 0, (size_t) LPC24XX_ETH_RAM_SIZE);
memset((void *) LPC24XX_ETH_RAM_START, 0, (size_t) LPC24XX_ETH_RAM_SIZE);
/* Set interface data */
ifp->if_softc = e;
@@ -1183,15 +1172,28 @@ static int lpc24xx_eth_attach( struct rtems_bsdnet_ifconfig *config)
e->state = LPC24XX_ETH_INITIALIZED;
/* Attach the interface */
if_attach( ifp);
ether_ifattach( ifp);
if_attach(ifp);
ether_ifattach(ifp);
return 1;
cleanup:
/* FIXME: Type */
free( unit_name, (int) 0xdeadbeef);
free(unit_name, (int) 0xdeadbeef);
return 0;
}
static int lpc24xx_eth_detach(struct rtems_bsdnet_ifconfig *config)
{
/* FIXME: Detach the interface from the upper layers? */
/* Module soft reset */
MAC_COMMAND = 0x38;
MAC_MAC1 = 0xcf00;
/* FIXME: More cleanup */
return 0;
}
@@ -1204,9 +1206,8 @@ int lpc24xx_eth_attach_detach(
/* FIXME: Return value */
if (attaching) {
return lpc24xx_eth_attach( config);
return lpc24xx_eth_attach(config);
} else {
/* TODO */
return 0;
return lpc24xx_eth_detach(config);
}
}

View File

@@ -1,7 +1,7 @@
/**
* @file
*
* @ingroup lpc24xx
* @ingroup lpc24xx_libi2c
*
* @brief LibI2C bus driver for the Synchronous Serial Port (SSP).
*/
@@ -74,29 +74,29 @@ static lpc24xx_ssp_dma_entry lpc24xx_ssp_dma_data = {
static uint32_t lpc24xx_ssp_trash = 0;
static inline bool lpc24xx_ssp_is_busy( const lpc24xx_ssp_bus_entry *bus)
static inline bool lpc24xx_ssp_is_busy(const lpc24xx_ssp_bus_entry *bus)
{
return lpc24xx_ssp_dma_data.bus == bus
&& lpc24xx_ssp_dma_data.status != LPC24XX_SSP_DMA_AVAILABLE;
}
static void lpc24xx_ssp_handler( rtems_vector_number vector, void *arg)
static void lpc24xx_ssp_handler(rtems_vector_number vector, void *arg)
{
lpc24xx_ssp_bus_entry *e = (lpc24xx_ssp_bus_entry *) arg;
volatile lpc24xx_ssp *regs = e->regs;
uint32_t mis = regs->mis;
uint32_t icr = 0;
if (IS_FLAG_SET( mis, SSP_MIS_RORRIS)) {
if (IS_FLAG_SET(mis, SSP_MIS_RORRIS)) {
/* TODO */
printk( "%s: Receiver overrun!\n", __func__);
printk("%s: Receiver overrun!\n", __func__);
icr |= SSP_ICR_RORRIS;
}
regs->icr = icr;
}
static void lpc24xx_ssp_dma_handler( rtems_vector_number vector, void *arg)
static void lpc24xx_ssp_dma_handler(rtems_vector_number vector, void *arg)
{
lpc24xx_ssp_dma_entry *e = (lpc24xx_ssp_dma_entry *) arg;
lpc24xx_ssp_dma_status status = e->status;
@@ -105,7 +105,7 @@ static void lpc24xx_ssp_dma_handler( rtems_vector_number vector, void *arg)
int rv = 0;
/* Return if we are not in a transfer status */
if (IS_FLAG_CLEARED( status, LPC24XX_SSP_DMA_TRANSFER_FLAG)) {
if (IS_FLAG_CLEARED(status, LPC24XX_SSP_DMA_TRANSFER_FLAG)) {
return;
}
@@ -121,25 +121,25 @@ static void lpc24xx_ssp_dma_handler( rtems_vector_number vector, void *arg)
if (err == 0) {
switch (status) {
case LPC24XX_SSP_DMA_WAIT:
if (ARE_FLAGS_SET( tc, GPDMA_STATUS_CH_0 | GPDMA_STATUS_CH_1)) {
if (ARE_FLAGS_SET(tc, GPDMA_STATUS_CH_0 | GPDMA_STATUS_CH_1)) {
status = LPC24XX_SSP_DMA_DONE;
} else if (IS_FLAG_SET( tc, GPDMA_STATUS_CH_0)) {
} else if (IS_FLAG_SET(tc, GPDMA_STATUS_CH_0)) {
status = LPC24XX_SSP_DMA_WAIT_FOR_CHANNEL_1;
} else if (IS_FLAG_SET( tc, GPDMA_STATUS_CH_1)) {
} else if (IS_FLAG_SET(tc, GPDMA_STATUS_CH_1)) {
status = LPC24XX_SSP_DMA_WAIT_FOR_CHANNEL_0;
}
break;
case LPC24XX_SSP_DMA_WAIT_FOR_CHANNEL_0:
if (IS_FLAG_SET( tc, GPDMA_STATUS_CH_1)) {
if (IS_FLAG_SET(tc, GPDMA_STATUS_CH_1)) {
status = LPC24XX_SSP_DMA_ERROR;
} else if (IS_FLAG_SET( tc, GPDMA_STATUS_CH_0)) {
} else if (IS_FLAG_SET(tc, GPDMA_STATUS_CH_0)) {
status = LPC24XX_SSP_DMA_DONE;
}
break;
case LPC24XX_SSP_DMA_WAIT_FOR_CHANNEL_1:
if (IS_FLAG_SET( tc, GPDMA_STATUS_CH_0)) {
if (IS_FLAG_SET(tc, GPDMA_STATUS_CH_0)) {
status = LPC24XX_SSP_DMA_ERROR;
} else if (IS_FLAG_SET( tc, GPDMA_STATUS_CH_1)) {
} else if (IS_FLAG_SET(tc, GPDMA_STATUS_CH_1)) {
status = LPC24XX_SSP_DMA_DONE;
}
break;
@@ -153,8 +153,8 @@ static void lpc24xx_ssp_dma_handler( rtems_vector_number vector, void *arg)
/* Error cleanup */
if (status == LPC24XX_SSP_DMA_ERROR) {
lpc24xx_dma_channel_disable( 0, true);
lpc24xx_dma_channel_disable( 1, true);
lpc24xx_dma_channel_disable(0, true);
lpc24xx_dma_channel_disable(1, true);
status = LPC24XX_SSP_DMA_DONE;
rv = -RTEMS_IO_ERROR;
}
@@ -163,7 +163,7 @@ static void lpc24xx_ssp_dma_handler( rtems_vector_number vector, void *arg)
if (status == LPC24XX_SSP_DMA_DONE) {
status = LPC24XX_SSP_DMA_AVAILABLE;
if (e->done != NULL) {
e->done( rv, e->n, e->arg);
e->done(rv, e->n, e->arg);
e->done = NULL;
}
}
@@ -172,7 +172,7 @@ static void lpc24xx_ssp_dma_handler( rtems_vector_number vector, void *arg)
e->status = status;
}
static rtems_status_code lpc24xx_ssp_init( rtems_libi2c_bus_t *bus)
static rtems_status_code lpc24xx_ssp_init(rtems_libi2c_bus_t *bus)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
rtems_interrupt_level level;
@@ -187,12 +187,12 @@ static rtems_status_code lpc24xx_ssp_init( rtems_libi2c_bus_t *bus)
lpc24xx_ssp_dma_status status = LPC24XX_SSP_DMA_INVALID;
/* Test and set DMA support status */
rtems_interrupt_disable( level);
rtems_interrupt_disable(level);
status = lpc24xx_ssp_dma_data.status;
if (status == LPC24XX_SSP_DMA_NOT_INITIALIZED) {
lpc24xx_ssp_dma_data.status = LPC24XX_SSP_DMA_INITIALIZATION;
}
rtems_interrupt_enable( level);
rtems_interrupt_enable(level);
if (status == LPC24XX_SSP_DMA_NOT_INITIALIZED) {
/* Install DMA interrupt handler */
@@ -203,7 +203,7 @@ static rtems_status_code lpc24xx_ssp_init( rtems_libi2c_bus_t *bus)
lpc24xx_ssp_dma_handler,
&lpc24xx_ssp_dma_data
);
RTEMS_CHECK_SC( sc, "Install DMA interrupt handler");
RTEMS_CHECK_SC(sc, "install DMA interrupt handler");
/* Set DMA support status */
lpc24xx_ssp_dma_data.status = LPC24XX_SSP_DMA_AVAILABLE;
@@ -216,16 +216,16 @@ static rtems_status_code lpc24xx_ssp_init( rtems_libi2c_bus_t *bus)
/* Set clock select and get vector number */
switch ((uintptr_t) regs) {
case SSP0_BASE_ADDR:
rtems_interrupt_disable( level);
PCLKSEL1 = SET_PCLKSEL1_PCLK_SSP0( PCLKSEL1, 1);
rtems_interrupt_enable( level);
rtems_interrupt_disable(level);
PCLKSEL1 = SET_PCLKSEL1_PCLK_SSP0(PCLKSEL1, 1);
rtems_interrupt_enable(level);
vector = LPC24XX_IRQ_SPI_SSP_0;
break;
case SSP1_BASE_ADDR:
rtems_interrupt_disable( level);
PCLKSEL0 = SET_PCLKSEL0_PCLK_SSP1( PCLKSEL0, 1);
rtems_interrupt_enable( level);
rtems_interrupt_disable(level);
PCLKSEL0 = SET_PCLKSEL0_PCLK_SSP1(PCLKSEL0, 1);
rtems_interrupt_enable(level);
vector = LPC24XX_IRQ_SSP_1;
break;
@@ -234,7 +234,7 @@ static rtems_status_code lpc24xx_ssp_init( rtems_libi2c_bus_t *bus)
}
/* Set serial clock rate to save value */
regs->cr0 = SET_SSP_CR0_SCR( 0, 255);
regs->cr0 = SET_SSP_CR0_SCR(0, 255);
/* Set clock prescaler */
if (pre > 254) {
@@ -258,7 +258,7 @@ static rtems_status_code lpc24xx_ssp_init( rtems_libi2c_bus_t *bus)
lpc24xx_ssp_handler,
e
);
RTEMS_CHECK_SC( sc, "Install interrupt handler");
RTEMS_CHECK_SC(sc, "install interrupt handler");
/* Enable receiver overrun interrupts */
e->regs->imsc = SSP_IMSC_RORIM;
@@ -266,20 +266,20 @@ static rtems_status_code lpc24xx_ssp_init( rtems_libi2c_bus_t *bus)
return RTEMS_SUCCESSFUL;
}
static rtems_status_code lpc24xx_ssp_send_start( rtems_libi2c_bus_t *bus)
static rtems_status_code lpc24xx_ssp_send_start(rtems_libi2c_bus_t *bus)
{
return RTEMS_SUCCESSFUL;
}
static rtems_status_code lpc24xx_ssp_send_stop( rtems_libi2c_bus_t *bus)
static rtems_status_code lpc24xx_ssp_send_stop(rtems_libi2c_bus_t *bus)
{
lpc24xx_ssp_bus_entry *e = (lpc24xx_ssp_bus_entry *) bus;
/* Release DMA support */
if (lpc24xx_ssp_dma_data.bus == e) {
if (lpc24xx_ssp_dma_data.status == LPC24XX_SSP_DMA_AVAILABLE) {
lpc24xx_dma_channel_release( 0);
lpc24xx_dma_channel_release( 1);
lpc24xx_dma_channel_release(0);
lpc24xx_dma_channel_release(1);
lpc24xx_ssp_dma_data.bus = NULL;
} else {
return RTEMS_RESOURCE_IN_USE;
@@ -297,7 +297,7 @@ static rtems_status_code lpc24xx_ssp_send_addr(
{
lpc24xx_ssp_bus_entry *e = (lpc24xx_ssp_bus_entry *) bus;
if (lpc24xx_ssp_is_busy( e)) {
if (lpc24xx_ssp_is_busy(e)) {
return RTEMS_RESOURCE_IN_USE;
}
@@ -315,7 +315,7 @@ static int lpc24xx_ssp_set_transfer_mode(
unsigned br = mode->baudrate;
unsigned scr = (clk + br - 1) / br;
if (lpc24xx_ssp_is_busy( e)) {
if (lpc24xx_ssp_is_busy(e)) {
return -RTEMS_RESOURCE_IN_USE;
}
@@ -363,12 +363,12 @@ static int lpc24xx_ssp_set_transfer_mode(
e->idle_char = mode->idle_char;
while (IS_FLAG_CLEARED( regs->sr, SSP_SR_TFE)) {
while (IS_FLAG_CLEARED(regs->sr, SSP_SR_TFE)) {
/* Wait */
}
regs->cr0 = SET_SSP_CR0_DSS( 0, 0x7)
| SET_SSP_CR0_SCR( 0, scr)
regs->cr0 = SET_SSP_CR0_DSS(0, 0x7)
| SET_SSP_CR0_SCR(0, scr)
| (mode->clock_inv ? SSP_CR0_CPOL : 0)
| (mode->clock_phs ? SSP_CR0_CPHA : 0);
@@ -393,7 +393,7 @@ static int lpc24xx_ssp_read_write(
unsigned char trash = 0;
unsigned char idle_char = (unsigned char) e->idle_char;
if (lpc24xx_ssp_is_busy( e)) {
if (lpc24xx_ssp_is_busy(e)) {
return -RTEMS_RESOURCE_IN_USE;
}
@@ -426,14 +426,14 @@ static int lpc24xx_ssp_read_write(
m = w - r;
/* Write */
if (IS_FLAG_SET( sr, SSP_SR_TNF) && m < LPC24XX_SSP_FIFO_SIZE) {
if (IS_FLAG_SET(sr, SSP_SR_TNF) && m < LPC24XX_SSP_FIFO_SIZE) {
regs->dr = *out;
++w;
out += dw;
}
/* Read */
if (IS_FLAG_SET( sr, SSP_SR_RNE)) {
if (IS_FLAG_SET(sr, SSP_SR_RNE)) {
*in = (unsigned char) regs->dr;
++r;
in += dr;
@@ -448,7 +448,7 @@ static int lpc24xx_ssp_read_write(
/* Wait */
do {
sr = regs->sr;
} while (IS_FLAG_CLEARED( sr, SSP_SR_RNE));
} while (IS_FLAG_CLEARED(sr, SSP_SR_RNE));
/* Read */
*in = (unsigned char) regs->dr;
@@ -472,8 +472,8 @@ static int lpc24xx_ssp_read_write_async(
rtems_interrupt_level level;
lpc24xx_ssp_bus_entry *e = (lpc24xx_ssp_bus_entry *) bus;
volatile lpc24xx_ssp *ssp = e->regs;
volatile lpc24xx_dma_channel *receive_channel = GPDMA_CH_BASE_ADDR( 0);
volatile lpc24xx_dma_channel *transmit_channel = GPDMA_CH_BASE_ADDR( 1);
volatile lpc24xx_dma_channel *receive_channel = GPDMA_CH_BASE_ADDR(0);
volatile lpc24xx_dma_channel *transmit_channel = GPDMA_CH_BASE_ADDR(1);
uint32_t di = GPDMA_CH_CTRL_DI;
uint32_t si = GPDMA_CH_CTRL_SI;
@@ -483,24 +483,24 @@ static int lpc24xx_ssp_read_write_async(
/* Try to reserve DMA support for this bus */
if (lpc24xx_ssp_dma_data.bus == NULL) {
rtems_interrupt_disable( level);
rtems_interrupt_disable(level);
if (lpc24xx_ssp_dma_data.bus == NULL) {
lpc24xx_ssp_dma_data.bus = e;
}
rtems_interrupt_enable( level);
rtems_interrupt_enable(level);
/* Try to obtain DMA channels */
if (lpc24xx_ssp_dma_data.bus == e) {
bool channel_0 = lpc24xx_dma_channel_obtain( 0);
bool channel_1 = lpc24xx_dma_channel_obtain( 1);
rtems_status_code cs0 = lpc24xx_dma_channel_obtain(0);
rtems_status_code cs1 = lpc24xx_dma_channel_obtain(1);
if (!channel_0 && channel_1) {
lpc24xx_dma_channel_release( 1);
lpc24xx_ssp_dma_data.bus = NULL;
} else if (channel_0 && !channel_1) {
lpc24xx_dma_channel_release( 0);
lpc24xx_ssp_dma_data.bus = NULL;
} else if (!channel_0 || !channel_1) {
if (cs0 != RTEMS_SUCCESSFUL || cs1 != RTEMS_SUCCESSFUL) {
if (cs0 == RTEMS_SUCCESSFUL) {
lpc24xx_dma_channel_release(0);
}
if (cs1 == RTEMS_SUCCESSFUL) {
lpc24xx_dma_channel_release(1);
}
lpc24xx_ssp_dma_data.bus = NULL;
}
}
@@ -523,44 +523,44 @@ static int lpc24xx_ssp_read_write_async(
/* Receive */
if (in != NULL) {
receive_channel->dest = (uint32_t) in;
receive_channel->desc.dest = (uint32_t) in;
} else {
receive_channel->dest = (uint32_t) &lpc24xx_ssp_trash;
receive_channel->desc.dest = (uint32_t) &lpc24xx_ssp_trash;
di = 0;
}
receive_channel->src = (uint32_t) &ssp->dr;
receive_channel->lli = 0;
receive_channel->ctrl = SET_GPDMA_CH_CTRL_TSZ( 0, n)
| SET_GPDMA_CH_CTRL_SBSZ( 0, GPDMA_CH_CTRL_BSZ_4)
| SET_GPDMA_CH_CTRL_DBSZ( 0, GPDMA_CH_CTRL_BSZ_4)
| SET_GPDMA_CH_CTRL_SW( 0, GPDMA_CH_CTRL_W_8)
| SET_GPDMA_CH_CTRL_DW( 0, GPDMA_CH_CTRL_W_8)
receive_channel->desc.src = (uint32_t) &ssp->dr;
receive_channel->desc.lli = 0;
receive_channel->desc.ctrl = SET_GPDMA_CH_CTRL_TSZ(0, n)
| SET_GPDMA_CH_CTRL_SBSZ(0, GPDMA_CH_CTRL_BSZ_4)
| SET_GPDMA_CH_CTRL_DBSZ(0, GPDMA_CH_CTRL_BSZ_4)
| SET_GPDMA_CH_CTRL_SW(0, GPDMA_CH_CTRL_W_8)
| SET_GPDMA_CH_CTRL_DW(0, GPDMA_CH_CTRL_W_8)
| GPDMA_CH_CTRL_ITC
| di;
receive_channel->cfg = SET_GPDMA_CH_CFG_SRCPER( 0, GPDMA_CH_CFG_PER_SSP1_RX)
| SET_GPDMA_CH_CFG_FLOW( 0, GPDMA_CH_CFG_FLOW_PER_TO_MEM_DMA)
receive_channel->cfg = SET_GPDMA_CH_CFG_SRCPER(0, GPDMA_CH_CFG_PER_SSP1_RX)
| SET_GPDMA_CH_CFG_FLOW(0, GPDMA_CH_CFG_FLOW_PER_TO_MEM_DMA)
| GPDMA_CH_CFG_IE
| GPDMA_CH_CFG_ITC
| GPDMA_CH_CFG_EN;
/* Transmit */
if (out != NULL) {
transmit_channel->src = (uint32_t) out;
transmit_channel->desc.src = (uint32_t) out;
} else {
transmit_channel->src = (uint32_t) &e->idle_char;
transmit_channel->desc.src = (uint32_t) &e->idle_char;
si = 0;
}
transmit_channel->dest = (uint32_t) &ssp->dr;
transmit_channel->lli = 0;
transmit_channel->ctrl = SET_GPDMA_CH_CTRL_TSZ( 0, n)
| SET_GPDMA_CH_CTRL_SBSZ( 0, GPDMA_CH_CTRL_BSZ_4)
| SET_GPDMA_CH_CTRL_DBSZ( 0, GPDMA_CH_CTRL_BSZ_4)
| SET_GPDMA_CH_CTRL_SW( 0, GPDMA_CH_CTRL_W_8)
| SET_GPDMA_CH_CTRL_DW( 0, GPDMA_CH_CTRL_W_8)
transmit_channel->desc.dest = (uint32_t) &ssp->dr;
transmit_channel->desc.lli = 0;
transmit_channel->desc.ctrl = SET_GPDMA_CH_CTRL_TSZ(0, n)
| SET_GPDMA_CH_CTRL_SBSZ(0, GPDMA_CH_CTRL_BSZ_4)
| SET_GPDMA_CH_CTRL_DBSZ(0, GPDMA_CH_CTRL_BSZ_4)
| SET_GPDMA_CH_CTRL_SW(0, GPDMA_CH_CTRL_W_8)
| SET_GPDMA_CH_CTRL_DW(0, GPDMA_CH_CTRL_W_8)
| GPDMA_CH_CTRL_ITC
| si;
transmit_channel->cfg = SET_GPDMA_CH_CFG_DESTPER( 0, GPDMA_CH_CFG_PER_SSP1_TX)
| SET_GPDMA_CH_CFG_FLOW( 0, GPDMA_CH_CFG_FLOW_MEM_TO_PER_DMA)
transmit_channel->cfg = SET_GPDMA_CH_CFG_DESTPER(0, GPDMA_CH_CFG_PER_SSP1_TX)
| SET_GPDMA_CH_CFG_FLOW(0, GPDMA_CH_CFG_FLOW_MEM_TO_PER_DMA)
| GPDMA_CH_CFG_IE
| GPDMA_CH_CFG_ITC
| GPDMA_CH_CFG_EN;
@@ -568,9 +568,9 @@ static int lpc24xx_ssp_read_write_async(
return 0;
}
static int lpc24xx_ssp_read( rtems_libi2c_bus_t *bus, unsigned char *in, int n)
static int lpc24xx_ssp_read(rtems_libi2c_bus_t *bus, unsigned char *in, int n)
{
return lpc24xx_ssp_read_write( bus, in, NULL, n);
return lpc24xx_ssp_read_write(bus, in, NULL, n);
}
static int lpc24xx_ssp_write(
@@ -579,10 +579,10 @@ static int lpc24xx_ssp_write(
int n
)
{
return lpc24xx_ssp_read_write( bus, NULL, out, n);
return lpc24xx_ssp_read_write(bus, NULL, out, n);
}
static int lpc24xx_ssp_ioctl( rtems_libi2c_bus_t *bus, int cmd, void *arg)
static int lpc24xx_ssp_ioctl(rtems_libi2c_bus_t *bus, int cmd, void *arg)
{
int rv = -1;
const rtems_libi2c_tfr_mode_t *tm = (const rtems_libi2c_tfr_mode_t *) arg;
@@ -592,7 +592,7 @@ static int lpc24xx_ssp_ioctl( rtems_libi2c_bus_t *bus, int cmd, void *arg)
switch (cmd) {
case RTEMS_LIBI2C_IOCTL_READ_WRITE:
rv = lpc24xx_ssp_read_write( bus, rw->rd_buf, rw->wr_buf, rw->byte_cnt);
rv = lpc24xx_ssp_read_write(bus, rw->rd_buf, rw->wr_buf, rw->byte_cnt);
break;
case RTEMS_LIBI2C_IOCTL_READ_WRITE_ASYNC:
rv = lpc24xx_ssp_read_write_async(
@@ -605,7 +605,7 @@ static int lpc24xx_ssp_ioctl( rtems_libi2c_bus_t *bus, int cmd, void *arg)
);
break;
case RTEMS_LIBI2C_IOCTL_SET_TFRMODE:
rv = lpc24xx_ssp_set_transfer_mode( bus, tm);
rv = lpc24xx_ssp_set_transfer_mode(bus, tm);
break;
default:
rv = -RTEMS_NOT_DEFINED;
@@ -630,7 +630,7 @@ static lpc24xx_ssp_bus_entry lpc24xx_ssp_bus_table [LPC24XX_SSP_NUMBER] = {
/* SSP 0 */
.bus = {
.ops = &lpc24xx_ssp_ops,
.size = sizeof( lpc24xx_ssp_bus_entry)
.size = sizeof(lpc24xx_ssp_bus_entry)
},
.regs = (volatile lpc24xx_ssp *) SSP0_BASE_ADDR,
.clock = 0,
@@ -639,7 +639,7 @@ static lpc24xx_ssp_bus_entry lpc24xx_ssp_bus_table [LPC24XX_SSP_NUMBER] = {
/* SSP 1 */
.bus = {
.ops = &lpc24xx_ssp_ops,
.size = sizeof( lpc24xx_ssp_bus_entry)
.size = sizeof(lpc24xx_ssp_bus_entry)
},
.regs = (volatile lpc24xx_ssp *) SSP1_BASE_ADDR,
.clock = 0,

View File

@@ -7,19 +7,18 @@
*/
/*
* Copyright (c) 2008
* Embedded Brains GmbH
* Copyright (c) 2008, 2009
* embedded brains GmbH
* Obere Lagerstr. 30
* D-82178 Puchheim
* Germany
* rtems@embedded-brains.de
* <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.
* 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.h>
#include <bsp/bootcard.h>
#include <bsp/dma.h>
@@ -29,309 +28,32 @@
#include <bsp/linker-symbols.h>
#include <bsp/lpc24xx.h>
#include <bsp/stackalloc.h>
#include <bsp/start.h>
#include <bsp/system-clocks.h>
static void lpc24xx_fatal_error( void)
void bsp_start(void)
{
while (true) {
/* Spin forever */
}
}
/* Initialize Timer 1 */
lpc24xx_module_enable(LPC24XX_MODULE_TIMER, 1, LPC24XX_MODULE_CCLK);
static void lpc24xx_ram_test_32( void)
{
const unsigned *end = (const unsigned *) bsp_region_data_end;
unsigned *begin = (unsigned *) bsp_region_data_begin;
unsigned *out = begin;
/* Initialize standard timer */
lpc24xx_timer_initialize();
while (out != end) {
*out = (unsigned) out;
++out;
}
out = begin;
while (out != end) {
if (*out != (unsigned) out) {
lpc24xx_fatal_error();
}
++out;
}
}
/**
* @brief EMC initialization.
*
* Dynamic Memory 0: Micron M T48LC 4M16 A2 P 75 IT
*/
static void lpc24xx_init_emc( void)
{
#ifdef LPC24XX_EMC_MICRON
int i = 0;
uint32_t mode = 0;
/* Enable module power */
lpc24xx_module_enable( LPC24XX_MODULE_EMC, 0, LPC24XX_MODULE_PCLK_DEFAULT);
/* IO configuration */
lpc24xx_io_config( LPC24XX_MODULE_EMC, 0, 0);
/* Enable module, normal memory map and normal power mode */
EMC_CTRL = 1;
/* Use little-endian mode and 1:1 clock ratio */
EMC_CONFIG = 0;
/* Global dynamic settings */
/* FIXME */
EMC_DYN_APR = 2;
/* Data-in to active command period tWR + tRP */
EMC_DYN_DAL = 4;
/* Load mode register to active or refresh command period 2 tCK */
EMC_DYN_MRD = 1;
/* Active to precharge command period 44 ns */
EMC_DYN_RAS = 3;
/* Active to active command period 66 ns */
EMC_DYN_RC = 4;
/* Use command delayed strategy */
EMC_DYN_RD_CFG = 1;
/* Auto refresh period 66 ns */
EMC_DYN_RFC = 4;
/* Precharge command period 20 ns */
EMC_DYN_RP = 1;
/* Active bank a to active bank b command period 15 ns */
EMC_DYN_RRD = 1;
/* FIXME */
EMC_DYN_SREX = 5;
/* Write recovery time 15 ns */
EMC_DYN_WR = 1;
/* Exit self refresh to active command period 75 ns */
EMC_DYN_XSR = 5;
/* Dynamic Memory 0 settings */
/*
* Use SDRAM, 0 0 001 01 address mapping, disabled buffer, unprotected writes
*/
EMC_DYN_CFG0 = 0x0280;
/* CAS and RAS latency */
EMC_DYN_RASCAS0 = 0x0202;
/* Wait 50 micro seconds */
lpc24xx_micro_seconds_delay( 50);
/* Send command: NOP */
EMC_DYN_CTRL = EMC_DYN_CTRL_CE | EMC_DYN_CTRL_CS | EMC_DYN_CTRL_CMD_NOP;
/* Wait 50 micro seconds */
lpc24xx_micro_seconds_delay( 50);
/* Send command: PRECHARGE ALL */
EMC_DYN_CTRL = EMC_DYN_CTRL_CE | EMC_DYN_CTRL_CS | EMC_DYN_CTRL_CMD_PALL;
/* Shortest possible refresh period */
EMC_DYN_RFSH = 0x01;
/* Wait at least 128 ABH clock cycles */
for (i = 0; i < 128; ++i) {
asm volatile (" nop");
}
/* Wait 1 micro second */
lpc24xx_micro_seconds_delay( 1);
/* Set refresh period */
EMC_DYN_RFSH = 0x46;
/* Send command: MODE */
EMC_DYN_CTRL = EMC_DYN_CTRL_CE | EMC_DYN_CTRL_CS | EMC_DYN_CTRL_CMD_MODE;
/* Set mode registerin SDRAM */
mode = *((volatile uint32_t *) (0xa0000000 | (0x23 << (1 + 2 + 8))));
/* Send command: NORMAL */
EMC_DYN_CTRL = 0;
/* Enable buffer */
EMC_DYN_CFG0 |= 0x00080000;
/* Extended wait register */
EMC_STA_EXT_WAIT = 0;
/* Static Memory 1 settings */
EMC_STA_WAITWEN1 = 0x02;
EMC_STA_WAITOEN1 = 0x02;
EMC_STA_WAITRD1 = 0x08;
EMC_STA_WAITPAGE1 = 0x1f;
EMC_STA_WAITWR1 = 0x08;
EMC_STA_WAITTURN1 = 0x0f;
EMC_STA_CFG1 = 0x81;
/* RAM test */
lpc24xx_ram_test_32();
/* Initialize console */
#ifdef LPC24XX_CONFIG_CONSOLE
lpc24xx_module_enable(LPC24XX_MODULE_UART, 0, LPC24XX_MODULE_CCLK);
lpc24xx_io_config(LPC24XX_MODULE_UART, 0, LPC24XX_CONFIG_CONSOLE);
U0LCR = 0;
U0IER = 0;
U0LCR = 0x80;
U0DLL = lpc24xx_cclk() / 16 / LPC24XX_UART_BAUD;
U0DLM = 0;
U0LCR = 0x03;
U0FCR = 0x07;
#endif
}
static void lpc24xx_init_pll( void)
{
#ifndef LPC24XX_HAS_UBOOT
/* Enable main oscillator */
SCS = SET_FLAG( SCS, 0x20);
while (IS_FLAG_CLEARED( SCS, 0x40)) {
/* Wait */
}
/* Set PLL */
lpc24xx_set_pll( 1, 0, 11, 3);
#endif
}
void /* __attribute__ ((section (".entry"))) */ bsp_start_hook_0( void)
{
/* Initialize PLL */
lpc24xx_init_pll();
#ifndef LPC24XX_HAS_UBOOT
/* Set pin functions */
PINSEL0 = 0;
PINSEL1 = 0;
PINSEL2 = 0;
PINSEL3 = 0;
PINSEL4 = 0;
PINSEL5 = 0;
PINSEL6 = 0;
PINSEL7 = 0;
PINSEL8 = 0;
PINSEL9 = 0;
PINSEL10 = 0;
PINSEL11 = 0;
/* Set pin modes */
PINMODE0 = 0;
PINMODE1 = 0;
PINMODE2 = 0;
PINMODE3 = 0;
PINMODE4 = 0;
PINMODE5 = 0;
PINMODE6 = 0;
PINMODE7 = 0;
PINMODE8 = 0;
PINMODE9 = 0;
/* Set periperal clocks */
PCLKSEL0 = 0;
PCLKSEL1 = 0;
/* Disable power for all modules */
PCONP = 0;
/* Set memory accelerator module (MAM) */
MAMCR = 0;
MAMTIM = 4;
/* Enable fast IO for ports 0 and 1 */
SCS = SET_FLAG( SCS, 0x1);
/* Set fast IO */
FIO0DIR = 0;
FIO1DIR = 0;
FIO2DIR = 0;
FIO3DIR = 0;
FIO4DIR = 0;
FIO0CLR = 0xffffffff;
FIO1CLR = 0xffffffff;
FIO2CLR = 0xffffffff;
FIO3CLR = 0xffffffff;
FIO4CLR = 0xffffffff;
/* Initialize console */
#ifdef LPC24XX_CONFIG_CONSOLE
lpc24xx_module_enable( LPC24XX_MODULE_UART, 0, LPC24XX_MODULE_CCLK);
lpc24xx_io_config( LPC24XX_MODULE_UART, 0, LPC24XX_CONFIG_CONSOLE);
U0LCR = 0;
U0IER = 0;
U0LCR = 0x80;
U0DLL = lpc24xx_cclk() / 16 / LPC24XX_UART_BAUD;
U0DLM = 0;
U0LCR = 0x03;
U0FCR = 0x07;
#endif
/* Initialize Timer 1 */
lpc24xx_module_enable( LPC24XX_MODULE_TIMER, 1, LPC24XX_MODULE_CCLK);
#endif
}
static void lpc24xx_copy_data( void)
{
#ifndef LPC24XX_HAS_UBOOT
const unsigned *end = (const unsigned *) bsp_section_data_end;
unsigned *in = (unsigned *) bsp_section_data_load_begin;
unsigned *out = (unsigned *) bsp_section_data_begin;
/* Copy data */
while (out != end) {
*out = *in;
++out;
++in;
}
#endif
}
static void lpc24xx_clear_bss( void)
{
const unsigned *end = (const unsigned *) bsp_section_bss_end;
unsigned *out = (unsigned *) bsp_section_bss_begin;
/* Clear BSS */
while (out != end) {
*out = 0;
++out;
}
}
void /* __attribute__ ((section (".entry"))) */ bsp_start_hook_1( void)
{
/* Re-map interrupt vectors to internal RAM */
MEMMAP = SET_MEMMAP_MAP( MEMMAP, 2);
/* Initialize External Memory Controller (EMC) */
lpc24xx_init_emc();
/* Copy data */
lpc24xx_copy_data();
/* Clear BSS */
lpc24xx_clear_bss();
}
void bsp_start( void)
{
printk( "CPU clock (CCLK): %u\n", lpc24xx_cclk());
/* Exceptions */
/* FIXME
rtems_exception_init_mngt();
*/
/* Interrupts */
if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) {
/* FIXME */
printk( "cannot intitialize interrupt support\n");
lpc24xx_fatal_error();
_CPU_Fatal_halt(0xe);
}
/* DMA */
@@ -340,35 +62,35 @@ void bsp_start( void)
/* Task stacks */
bsp_stack_initialize(
bsp_section_stack_begin,
(intptr_t) bsp_section_stack_size
(uintptr_t) bsp_section_stack_size
);
/* UART configurations */
#ifdef LPC24XX_CONFIG_UART_1
lpc24xx_module_enable( LPC24XX_MODULE_UART, 1, LPC24XX_MODULE_CCLK);
lpc24xx_io_config( LPC24XX_MODULE_UART, 1, LPC24XX_CONFIG_UART_1);
lpc24xx_module_enable(LPC24XX_MODULE_UART, 1, LPC24XX_MODULE_CCLK);
lpc24xx_io_config(LPC24XX_MODULE_UART, 1, LPC24XX_CONFIG_UART_1);
#endif
#ifdef LPC24XX_CONFIG_UART_2
lpc24xx_module_enable( LPC24XX_MODULE_UART, 2, LPC24XX_MODULE_CCLK);
lpc24xx_io_config( LPC24XX_MODULE_UART, 2, LPC24XX_CONFIG_UART_2);
lpc24xx_module_enable(LPC24XX_MODULE_UART, 2, LPC24XX_MODULE_CCLK);
lpc24xx_io_config(LPC24XX_MODULE_UART, 2, LPC24XX_CONFIG_UART_2);
#endif
#ifdef LPC24XX_CONFIG_UART_3
lpc24xx_module_enable( LPC24XX_MODULE_UART, 3, LPC24XX_MODULE_CCLK);
lpc24xx_io_config( LPC24XX_MODULE_UART, 3, LPC24XX_CONFIG_UART_3);
lpc24xx_module_enable(LPC24XX_MODULE_UART, 3, LPC24XX_MODULE_CCLK);
lpc24xx_io_config(LPC24XX_MODULE_UART, 3, LPC24XX_CONFIG_UART_3);
#endif
}
#define ULSR_THRE 0x00000020U
static void lpc24xx_BSP_output_char( char c)
static void lpc24xx_BSP_output_char(char c)
{
while (IS_FLAG_CLEARED( U0LSR, ULSR_THRE)) {
while (IS_FLAG_CLEARED(U0LSR, ULSR_THRE)) {
/* Wait */
}
U0THR = c;
if (c == '\n') {
while (IS_FLAG_CLEARED( U0LSR, ULSR_THRE)) {
while (IS_FLAG_CLEARED(U0LSR, ULSR_THRE)) {
/* Wait */
}
U0THR = '\r';