forked from Imagelibrary/rtems
Changes throughout.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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 #
|
||||
###############################################################################
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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';
|
||||
|
||||
Reference in New Issue
Block a user