forked from Imagelibrary/rtems
updated gen83xx BSP
updated haleakala BSP added MPC55xx BSP
This commit is contained in:
@@ -1,3 +1,29 @@
|
||||
2008-07-14 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||
|
||||
* configure.ac: Support for MPC55XX. Changed comment format to
|
||||
Doxygen.
|
||||
|
||||
* mpc55xx/dspi/dspi.c, mpc55xx/edma/edma.c, mpc55xx/esci/esci.c,
|
||||
mpc55xx/fec/fec.c, mpc55xx/include/dspi.h, mpc55xx/include/edma.h,
|
||||
mpc55xx/include/esci.h, mpc55xx/include/irq.h,
|
||||
mpc55xx/include/mpc55xx.h, mpc55xx/include/reg-defs.h,
|
||||
mpc55xx/include/regs.h, mpc55xx/irq/irq.c, mpc55xx/misc/copy.S,
|
||||
mpc55xx/misc/flash.S, mpc55xx/misc/fmpll.S: New BSP.
|
||||
|
||||
* mpc83xx/i2c/mpc83xx_i2cdrv.c,
|
||||
mpc83xx/network/tsec.c, mpc83xx/spi/mpc83xx_spidrv.c,
|
||||
mpc83xx/spi/mpc83xx_spidrv.h: Support for MPC8313ERDB.
|
||||
|
||||
* shared/include/powerpc-utility.h: Exchanged ASM and non ASM code
|
||||
sections.
|
||||
|
||||
* rtems/powerpc/powerpc.h, shared/src/cache.c, shared/src/cache_.h:
|
||||
New defines PPC_NO_CACHE_ALIGNMENT and PPC_NO_CACHE_ALIGNMENT_POWER for
|
||||
CPUs with no cache. Provide default implementations for all cache
|
||||
functions.
|
||||
|
||||
* mpc83xx/include/gtm.h, mpc83xx/gtm/gtm.c: New files.
|
||||
|
||||
2008-07-14 Thomas Doerfler <thomas.doerfler@embedded-brains.de>
|
||||
|
||||
* Makefile.am, new-exceptions/raw_exception.c,
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
##
|
||||
## $Id$
|
||||
##
|
||||
#
|
||||
# @file
|
||||
#
|
||||
# @ingroup mpc55xx_config
|
||||
#
|
||||
# @brief Makefile of LibCPU for PowerPC.
|
||||
#
|
||||
|
||||
ACLOCAL_AMFLAGS = -I ../../../aclocal
|
||||
|
||||
@@ -19,7 +28,7 @@ EXTRA_DIST =
|
||||
|
||||
noinst_PROGRAMS = new-exceptions/rtems-cpu.rel
|
||||
new_exceptions_rtems_cpu_rel_SOURCES = new-exceptions/cpu.c \
|
||||
new-exceptions/cpu_asm.S
|
||||
new-exceptions/cpu_asm.S
|
||||
new_exceptions_rtems_cpu_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
new_exceptions_rtems_cpu_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
@@ -37,7 +46,7 @@ noinst_PROGRAMS += new-exceptions/exc_bspsupport.rel
|
||||
new_exceptions_exc_bspsupport_rel_SOURCES = \
|
||||
new-exceptions/bspsupport/ppc_exc.S \
|
||||
new-exceptions/bspsupport/ppc_exc_hdl.c \
|
||||
new-exceptions/bspsupport/vectors_init.c
|
||||
new-exceptions/bspsupport/vectors_init.c
|
||||
new_exceptions_exc_bspsupport_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
new_exceptions_exc_bspsupport_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
@@ -55,7 +64,7 @@ EXTRA_DIST += new-exceptions/bspsupport/README
|
||||
EXTRA_DIST += new-exceptions/bspsupport/nest_irq_test.c
|
||||
EXTRA_DIST += new-exceptions/bspsupport/ppc_exc_test.c
|
||||
|
||||
## shared/include
|
||||
# shared/include
|
||||
if shared
|
||||
include_libcpu_HEADERS += shared/include/io.h shared/include/mmu.h shared/include/page.h \
|
||||
shared/include/byteorder.h shared/include/pgtable.h
|
||||
@@ -67,7 +76,7 @@ shared_cpuIdent_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
include_libcpu_HEADERS += shared/include/cpuIdent.h
|
||||
|
||||
## shared/cache
|
||||
# shared/cache
|
||||
noinst_PROGRAMS += shared/cache.rel
|
||||
shared_cache_rel_SOURCES = shared/src/cache.c shared/src/cache_.h \
|
||||
../shared/src/cache_aligned_malloc.c ../shared/src/cache_manager.c \
|
||||
@@ -77,7 +86,7 @@ shared_cache_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
include_libcpu_HEADERS += ../shared/include/cache.h
|
||||
|
||||
## shared/stack
|
||||
# shared/stack
|
||||
noinst_PROGRAMS += shared/stack.rel
|
||||
shared_stack_rel_SOURCES = shared/src/stack.c shared/include/spr.h shared/src/stackTrace.h
|
||||
shared_stack_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
@@ -89,13 +98,13 @@ endif
|
||||
|
||||
EXTRA_DIST += ppc403/README ppc403/vectors/README
|
||||
if ppc403
|
||||
## ppc403/clock
|
||||
# ppc403/clock
|
||||
noinst_PROGRAMS += ppc403/clock.rel
|
||||
ppc403_clock_rel_SOURCES = ppc403/clock/clock.c
|
||||
ppc403_clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
ppc403_clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## ppc403/console
|
||||
# ppc403/console
|
||||
noinst_PROGRAMS += ppc403/console.rel
|
||||
if ppc405
|
||||
ppc403_console_rel_SOURCES = ppc403/console/console405.c
|
||||
@@ -110,13 +119,13 @@ shared_cpuIdent_rel_SOURCES = shared/include/cpuIdent.c
|
||||
shared_cpuIdent_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
shared_cpuIdent_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## ppc403/timer
|
||||
# ppc403/timer
|
||||
noinst_PROGRAMS += ppc403/timer.rel
|
||||
ppc403_timer_rel_SOURCES = ppc403/timer/timer.c
|
||||
ppc403_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
ppc403_timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## ppc403/tty_drv
|
||||
# ppc403/tty_drv
|
||||
if ppc405
|
||||
include_HEADERS += ppc403/tty_drv/tty_drv.h
|
||||
|
||||
@@ -145,13 +154,13 @@ include_mpc5xxdir = $(includedir)/mpc5xx
|
||||
|
||||
include_HEADERS = mpc5xx/include/mpc5xx.h
|
||||
|
||||
## mpc5xx/clock
|
||||
# mpc5xx/clock
|
||||
noinst_PROGRAMS += mpc5xx/clock.rel
|
||||
mpc5xx_clock_rel_SOURCES = mpc5xx/clock/clock.c
|
||||
mpc5xx_clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc5xx_clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc5xx/console-generic
|
||||
# mpc5xx/console-generic
|
||||
include_mpc5xx_HEADERS = mpc5xx/include/console.h
|
||||
|
||||
noinst_PROGRAMS += mpc5xx/console-generic.rel
|
||||
@@ -159,7 +168,7 @@ mpc5xx_console_generic_rel_SOURCES = mpc5xx/console-generic/console-generic.c
|
||||
mpc5xx_console_generic_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc5xx_console_generic_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc5xx/exceptions
|
||||
# mpc5xx/exceptions
|
||||
include_libcpu_HEADERS += mpc5xx/exceptions/raw_exception.h
|
||||
|
||||
noinst_PROGRAMS += mpc5xx/exceptions.rel
|
||||
@@ -167,7 +176,7 @@ mpc5xx_exceptions_rel_SOURCES = mpc5xx/exceptions/raw_exception.c
|
||||
mpc5xx_exceptions_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc5xx_exceptions_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc5xx/irq
|
||||
# mpc5xx/irq
|
||||
include_libcpu_HEADERS += mpc5xx/irq/irq.h
|
||||
|
||||
noinst_PROGRAMS += mpc5xx/irq.rel
|
||||
@@ -175,13 +184,13 @@ mpc5xx_irq_rel_SOURCES = mpc5xx/irq/irq.c mpc5xx/irq/irq_init.c mpc5xx/irq/irq_a
|
||||
mpc5xx_irq_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc5xx_irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc5xx/timer
|
||||
# mpc5xx/timer
|
||||
noinst_PROGRAMS += mpc5xx/timer.rel
|
||||
mpc5xx_timer_rel_SOURCES = mpc5xx/timer/timer.c
|
||||
mpc5xx_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc5xx_timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc5xx/vectors
|
||||
# mpc5xx/vectors
|
||||
include_libcpu_HEADERS += mpc5xx/vectors/vectors.h
|
||||
|
||||
noinst_PROGRAMS += mpc5xx/vectors.rel
|
||||
@@ -191,7 +200,7 @@ mpc5xx_vectors_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
endif
|
||||
|
||||
if mpc505
|
||||
## mpc505/ictrl
|
||||
# mpc505/ictrl
|
||||
include_HEADERS = mpc505/ictrl/ictrl.h
|
||||
|
||||
noinst_PROGRAMS += mpc505/ictrl.rel
|
||||
@@ -199,13 +208,13 @@ mpc505_ictrl_rel_SOURCES = mpc505/ictrl/ictrl.c
|
||||
mpc505_ictrl_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc505_ictrl_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc505/timer
|
||||
# mpc505/timer
|
||||
noinst_PROGRAMS += mpc505/timer.rel
|
||||
mpc505_timer_rel_SOURCES = mpc505/timer/timer.c
|
||||
mpc505_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc505_timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc505/vector
|
||||
# mpc505/vector
|
||||
noinst_PROGRAMS += mpc505/vectors.rel
|
||||
mpc505_vectors_rel_SOURCES = mpc505/vectors/vectors.S
|
||||
mpc505_vectors_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
@@ -214,7 +223,7 @@ endif
|
||||
|
||||
if mpc6xx
|
||||
|
||||
## mpc6xx/mmu
|
||||
# mpc6xx/mmu
|
||||
include_libcpu_HEADERS += mpc6xx/mmu/bat.h mpc6xx/mmu/pte121.h
|
||||
|
||||
noinst_PROGRAMS += mpc6xx/mmu.rel
|
||||
@@ -224,7 +233,7 @@ mpc6xx_mmu_rel_SOURCES = mpc6xx/mmu/bat.c mpc6xx/mmu/bat.h \
|
||||
mpc6xx_mmu_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc6xx_mmu_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc6xx/clock
|
||||
# mpc6xx/clock
|
||||
include_libcpu_HEADERS += mpc6xx/clock/c_clock.h
|
||||
|
||||
noinst_PROGRAMS += mpc6xx/clock.rel
|
||||
@@ -232,7 +241,7 @@ mpc6xx_clock_rel_SOURCES = mpc6xx/clock/c_clock.c mpc6xx/clock/c_clock.h
|
||||
mpc6xx_clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc6xx_clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc6xx/timer
|
||||
# mpc6xx/timer
|
||||
noinst_PROGRAMS += mpc6xx/timer.rel
|
||||
mpc6xx_timer_rel_SOURCES = mpc6xx/timer/timer.c
|
||||
mpc6xx_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
@@ -240,7 +249,7 @@ mpc6xx_timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
endif
|
||||
|
||||
if e500
|
||||
## mpc6xx/clock
|
||||
# mpc6xx/clock
|
||||
include_libcpu_HEADERS += mpc6xx/clock/c_clock.h
|
||||
|
||||
noinst_PROGRAMS += e500/clock.rel
|
||||
@@ -248,13 +257,13 @@ e500_clock_rel_SOURCES = mpc6xx/clock/c_clock.c mpc6xx/clock/c_clock.h
|
||||
e500_clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
e500_clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc6xx/timer
|
||||
# mpc6xx/timer
|
||||
noinst_PROGRAMS += e500/timer.rel
|
||||
e500_timer_rel_SOURCES = mpc6xx/timer/timer.c
|
||||
e500_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
e500_timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## e500/mmu
|
||||
# e500/mmu
|
||||
include_libcpu_HEADERS += e500/mmu/e500_mmu.h
|
||||
noinst_PROGRAMS += e500/mmu.rel
|
||||
e500_mmu_rel_SOURCES = e500/mmu/mmu.c e500/mmu/e500_mmu.h
|
||||
@@ -268,13 +277,13 @@ include_mpc8xxdir = $(includedir)/mpc8xx
|
||||
|
||||
include_HEADERS = mpc8xx/include/mpc8xx.h
|
||||
|
||||
## mpc8xx/clock
|
||||
# mpc8xx/clock
|
||||
noinst_PROGRAMS += mpc8xx/clock.rel
|
||||
mpc8xx_clock_rel_SOURCES = mpc8xx/clock/clock.c
|
||||
mpc8xx_clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc8xx_clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc8xx/console-generic
|
||||
# mpc8xx/console-generic
|
||||
include_mpc8xx_HEADERS = mpc8xx/include/console.h
|
||||
|
||||
noinst_PROGRAMS += mpc8xx/console-generic.rel
|
||||
@@ -282,7 +291,7 @@ mpc8xx_console_generic_rel_SOURCES = mpc8xx/console-generic/console-generic.c
|
||||
mpc8xx_console_generic_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc8xx_console_generic_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc8xx/cpm
|
||||
# mpc8xx/cpm
|
||||
include_mpc8xx_HEADERS += mpc8xx/include/cpm.h
|
||||
|
||||
noinst_PROGRAMS += mpc8xx/cpm.rel
|
||||
@@ -290,7 +299,7 @@ mpc8xx_cpm_rel_SOURCES = mpc8xx/cpm/cp.c mpc8xx/cpm/dpram.c
|
||||
mpc8xx_cpm_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc8xx_cpm_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc8xx/mmu
|
||||
# mpc8xx/mmu
|
||||
include_mpc8xx_HEADERS += mpc8xx/include/mmu.h
|
||||
|
||||
noinst_PROGRAMS += mpc8xx/mmu.rel
|
||||
@@ -298,7 +307,7 @@ mpc8xx_mmu_rel_SOURCES = mpc8xx/mmu/mmu.c
|
||||
mpc8xx_mmu_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc8xx_mmu_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc8xx/timer
|
||||
# mpc8xx/timer
|
||||
noinst_PROGRAMS += mpc8xx/timer.rel
|
||||
mpc8xx_timer_rel_SOURCES = mpc8xx/timer/timer.c
|
||||
mpc8xx_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
@@ -311,7 +320,7 @@ include_mpc8260dir = $(includedir)/mpc8260
|
||||
|
||||
include_HEADERS = mpc8260/include/mpc8260.h
|
||||
|
||||
## mpc8260/console-generic
|
||||
# mpc8260/console-generic
|
||||
include_mpc8260_HEADERS = mpc8260/include/console.h
|
||||
|
||||
noinst_PROGRAMS += mpc8260/console-generic.rel
|
||||
@@ -320,13 +329,13 @@ mpc8260_console_generic_rel_SOURCES = mpc8260/console-generic/console-generic.c
|
||||
mpc8260_console_generic_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc8260_console_generic_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc8260/clock
|
||||
# mpc8260/clock
|
||||
noinst_PROGRAMS += mpc8260/clock.rel
|
||||
mpc8260_clock_rel_SOURCES = mpc8260/clock/clock.c
|
||||
mpc8260_clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc8260_clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc8260/cpm
|
||||
# mpc8260/cpm
|
||||
include_mpc8260_HEADERS += mpc8260/include/cpm.h
|
||||
|
||||
noinst_PROGRAMS += mpc8260/cpm.rel
|
||||
@@ -335,7 +344,7 @@ mpc8260_cpm_rel_SOURCES = mpc8260/cpm/cp.c mpc8260/cpm/dpram.c mpc8260/cpm/brg.c
|
||||
mpc8260_cpm_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc8260_cpm_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc8260/mmu
|
||||
# mpc8260/mmu
|
||||
include_mpc8260_HEADERS += mpc8260/include/mmu.h
|
||||
|
||||
noinst_PROGRAMS += mpc8260/mmu.rel
|
||||
@@ -344,44 +353,121 @@ mpc8260_mmu_rel_SOURCES = mpc8260/mmu/mmu.c \
|
||||
mpc8260_mmu_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc8260_mmu_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc8260/timer
|
||||
# mpc8260/timer
|
||||
noinst_PROGRAMS += mpc8260/timer.rel
|
||||
mpc8260_timer_rel_SOURCES = mpc8260/timer/timer.c
|
||||
mpc8260_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc8260_timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
endif
|
||||
|
||||
##############################################################################
|
||||
# START: MPC83XX #
|
||||
##############################################################################
|
||||
if mpc83xx
|
||||
|
||||
include_mpc83xxdir = $(includedir)/mpc83xx
|
||||
include_mpc83xx_HEADERS = mpc83xx/include/mpc83xx.h
|
||||
include_mpc83xx_HEADERS += mpc83xx/network/tsec.h
|
||||
# Includes
|
||||
include_bspdir = $(includedir)/bsp
|
||||
|
||||
## mpc83xx/network
|
||||
include_bsp_HEADERS = new-exceptions/bspsupport/vectors.h \
|
||||
new-exceptions/bspsupport/ppc_exc_bspsupp.h
|
||||
|
||||
include_mpc83xxdir = $(includedir)/mpc83xx
|
||||
|
||||
include_mpc83xx_HEADERS = mpc83xx/include/mpc83xx.h
|
||||
|
||||
# Network
|
||||
include_mpc83xx_HEADERS += mpc83xx/network/tsec.h
|
||||
if HAS_NETWORKING
|
||||
noinst_PROGRAMS += mpc83xx/tsec.rel
|
||||
mpc83xx_tsec_rel_SOURCES = mpc83xx/network/tsec.c
|
||||
mpc83xx_tsec_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc83xx_tsec_rel_CPPFLAGS += -D__INSIDE_RTEMS_BSD_TCPIP_STACK__ -D__BSD_VISIBLE
|
||||
mpc83xx_tsec_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
mpc83xx_tsec_rel_SOURCES = mpc83xx/network/tsec.c
|
||||
mpc83xx_tsec_rel_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__ -D__BSD_VISIBLE
|
||||
mpc83xx_tsec_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
endif
|
||||
## mpc83xx/i2c
|
||||
|
||||
# i2c
|
||||
include_mpc83xx_HEADERS += mpc83xx/i2c/mpc83xx_i2cdrv.h
|
||||
noinst_PROGRAMS += mpc83xx/i2c.rel
|
||||
mpc83xx_i2c_rel_SOURCES = mpc83xx/i2c/mpc83xx_i2cdrv.c \
|
||||
mpc83xx/i2c/mpc83xx_i2cdrv.h
|
||||
mpc83xx_i2c_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc83xx_i2c_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
mpc83xx_i2c_rel_SOURCES = mpc83xx/i2c/mpc83xx_i2cdrv.c \
|
||||
mpc83xx/i2c/mpc83xx_i2cdrv.h
|
||||
mpc83xx_i2c_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
## mpc83xx/spi
|
||||
# SPI
|
||||
include_mpc83xx_HEADERS += mpc83xx/spi/mpc83xx_spidrv.h
|
||||
noinst_PROGRAMS += mpc83xx/spi.rel
|
||||
mpc83xx_spi_rel_SOURCES = mpc83xx/spi/mpc83xx_spidrv.c \
|
||||
mpc83xx/spi/mpc83xx_spidrv.h
|
||||
mpc83xx_spi_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
mpc83xx_spi_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
mpc83xx_spi_rel_SOURCES = mpc83xx/spi/mpc83xx_spidrv.c \
|
||||
mpc83xx/spi/mpc83xx_spidrv.h
|
||||
mpc83xx_spi_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
# GTM
|
||||
include_mpc83xx_HEADERS += mpc83xx/include/gtm.h
|
||||
noinst_PROGRAMS += mpc83xx/gtm.rel
|
||||
mpc83xx_gtm_rel_SOURCES = mpc83xx/gtm/gtm.c \
|
||||
mpc83xx/include/gtm.h
|
||||
mpc83xx_gtm_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
endif
|
||||
##############################################################################
|
||||
# END: MPC83XX #
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# START: MPC55XX #
|
||||
##############################################################################
|
||||
if mpc55xx
|
||||
|
||||
# Includes
|
||||
include_bspdir = $(includedir)/bsp
|
||||
|
||||
include_bsp_HEADERS = new-exceptions/bspsupport/vectors.h \
|
||||
new-exceptions/bspsupport/ppc_exc_bspsupp.h \
|
||||
mpc55xx/include/irq.h
|
||||
|
||||
include_mpc55xxdir = $(includedir)/mpc55xx
|
||||
|
||||
include_mpc55xx_HEADERS = mpc55xx/include/regs.h \
|
||||
mpc55xx/include/reg-defs.h \
|
||||
mpc55xx/include/dspi.h \
|
||||
mpc55xx/include/edma.h \
|
||||
mpc55xx/include/mpc55xx.h \
|
||||
mpc55xx/include/esci.h
|
||||
|
||||
|
||||
# IRQ
|
||||
noinst_PROGRAMS += mpc55xx/irq.rel
|
||||
mpc55xx_irq_rel_SOURCES = mpc55xx/irq/irq.c
|
||||
mpc55xx_irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
# FEC
|
||||
noinst_PROGRAMS += mpc55xx/fec.rel
|
||||
mpc55xx_fec_rel_SOURCES = mpc55xx/fec/fec.c
|
||||
mpc55xx_fec_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
# EMDA
|
||||
noinst_PROGRAMS += mpc55xx/edma.rel
|
||||
mpc55xx_edma_rel_SOURCES = mpc55xx/edma/edma.c
|
||||
mpc55xx_edma_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
# ESCI
|
||||
noinst_PROGRAMS += mpc55xx/esci.rel
|
||||
mpc55xx_esci_rel_SOURCES = mpc55xx/esci/esci.c
|
||||
mpc55xx_esci_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
# DSPI
|
||||
noinst_PROGRAMS += mpc55xx/dspi.rel
|
||||
mpc55xx_dspi_rel_SOURCES = mpc55xx/dspi/dspi.c
|
||||
mpc55xx_dspi_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
# Misc
|
||||
noinst_PROGRAMS += mpc55xx/misc.rel
|
||||
mpc55xx_misc_rel_SOURCES = mpc55xx/misc/copy.S \
|
||||
mpc55xx/misc/fmpll.S \
|
||||
mpc55xx/misc/flash.S
|
||||
mpc55xx_misc_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||
|
||||
endif
|
||||
##############################################################################
|
||||
# END: MPC55XX #
|
||||
##############################################################################
|
||||
|
||||
include $(srcdir)/preinstall.am
|
||||
include $(top_srcdir)/../../../automake/local.am
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
## Process this file with autoconf to produce a configure script.
|
||||
##
|
||||
## $Id$
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
#
|
||||
# $Id$
|
||||
|
||||
##
|
||||
#
|
||||
# @file
|
||||
#
|
||||
# @ingroup mpc55xx_config
|
||||
#
|
||||
# @brief Configure script of LibCPU for PowerPC.
|
||||
#
|
||||
|
||||
AC_PREREQ(2.60)
|
||||
AC_INIT([rtems-c-src-lib-libcpu-powerpc],[_RTEMS_VERSION],[http://www.rtems.org/bugzilla])
|
||||
@@ -27,6 +36,7 @@ AM_CONDITIONAL(shared, \
|
||||
|| test "$RTEMS_CPU_MODEL" = "mpc7455" \
|
||||
|| test "$RTEMS_CPU_MODEL" = "mpc7457" \
|
||||
|| test "$RTEMS_CPU_MODEL" = "mpc555" \
|
||||
|| test "$RTEMS_CPU_MODEL" = "mpc55xx" \
|
||||
|| test "$RTEMS_CPU_MODEL" = "mpc5xx" \
|
||||
|| test "$RTEMS_CPU_MODEL" = "ppc603e" \
|
||||
|| test "$RTEMS_CPU_MODEL" = "ppc403" \
|
||||
@@ -42,8 +52,9 @@ AM_CONDITIONAL(shared, \
|
||||
|| test "$RTEMS_CPU_MODEL" = "mpc83xx" \
|
||||
|| test "$RTEMS_CPU_MODEL" = "e500")
|
||||
|
||||
## test on CPU type
|
||||
# test on CPU type
|
||||
AM_CONDITIONAL(mpc505, test "$RTEMS_CPU_MODEL" = "mpc505")
|
||||
AM_CONDITIONAL(mpc55xx, test "$RTEMS_CPU_MODEL" = "mpc55xx")
|
||||
AM_CONDITIONAL(mpc5xx, test "$RTEMS_CPU_MODEL" = "mpc5xx" \
|
||||
|| test "$RTEMS_CPU_MODEL" = "mpc555" )
|
||||
AM_CONDITIONAL(mpc6xx, test "$RTEMS_CPU_MODEL" = "mpc6xx" \
|
||||
|
||||
746
c/src/lib/libcpu/powerpc/mpc55xx/dspi/dspi.c
Normal file
746
c/src/lib/libcpu/powerpc/mpc55xx/dspi/dspi.c
Normal file
@@ -0,0 +1,746 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup mpc55xx_dspi
|
||||
*
|
||||
* @brief Source file for the LibI2C bus driver for the Deserial Serial Peripheral Interface (DSPI).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be found in the file
|
||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <mpc55xx/regs.h>
|
||||
#include <mpc55xx/dspi.h>
|
||||
#include <mpc55xx/edma.h>
|
||||
#include <mpc55xx/mpc55xx.h>
|
||||
|
||||
#include <libcpu/powerpc-utility.h>
|
||||
|
||||
#define RTEMS_STATUS_CHECKS_USE_PRINTK
|
||||
|
||||
#include <rtems/status-checks.h>
|
||||
|
||||
#define MPC55XX_DSPI_FIFO_SIZE 4
|
||||
|
||||
#define MPC55XX_DSPI_CTAR_NUMBER 8
|
||||
|
||||
#define MPC55XX_DSPI_CTAR_DEFAULT 0
|
||||
|
||||
#define MPC55XX_DSPI_EDMA_MAGIC_SIZE 128
|
||||
|
||||
#define MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE 63
|
||||
|
||||
typedef struct {
|
||||
uint32_t scaler : 26;
|
||||
uint32_t pbr : 2;
|
||||
uint32_t br : 4;
|
||||
} mpc55xx_dspi_baudrate_scaler_entry;
|
||||
|
||||
static const mpc55xx_dspi_baudrate_scaler_entry mpc55xx_dspi_baudrate_scaler_table [MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE] = {
|
||||
{ 4, 0, 0 },
|
||||
{ 6, 1, 0 },
|
||||
{ 8, 0, 1 },
|
||||
{ 10, 2, 0 },
|
||||
{ 12, 1, 1 },
|
||||
{ 14, 3, 0 },
|
||||
{ 16, 0, 3 },
|
||||
{ 18, 1, 2 },
|
||||
{ 20, 2, 1 },
|
||||
{ 24, 1, 3 },
|
||||
{ 28, 3, 1 },
|
||||
{ 30, 2, 2 },
|
||||
{ 32, 0, 4 },
|
||||
{ 40, 2, 3 },
|
||||
{ 42, 3, 2 },
|
||||
{ 48, 1, 4 },
|
||||
{ 56, 3, 3 },
|
||||
{ 64, 0, 5 },
|
||||
{ 80, 2, 4 },
|
||||
{ 96, 1, 5 },
|
||||
{ 112, 3, 4 },
|
||||
{ 128, 0, 6 },
|
||||
{ 160, 2, 5 },
|
||||
{ 192, 1, 6 },
|
||||
{ 224, 3, 5 },
|
||||
{ 256, 0, 7 },
|
||||
{ 320, 2, 6 },
|
||||
{ 384, 1, 7 },
|
||||
{ 448, 3, 6 },
|
||||
{ 512, 0, 8 },
|
||||
{ 640, 2, 7 },
|
||||
{ 768, 1, 8 },
|
||||
{ 896, 3, 7 },
|
||||
{ 1024, 0, 9 },
|
||||
{ 1280, 2, 8 },
|
||||
{ 1536, 1, 9 },
|
||||
{ 1792, 3, 8 },
|
||||
{ 2048, 0, 10 },
|
||||
{ 2560, 2, 9 },
|
||||
{ 3072, 1, 10 },
|
||||
{ 3584, 3, 9 },
|
||||
{ 4096, 0, 11 },
|
||||
{ 5120, 2, 10 },
|
||||
{ 6144, 1, 11 },
|
||||
{ 7168, 3, 10 },
|
||||
{ 8192, 0, 12 },
|
||||
{ 10240, 2, 11 },
|
||||
{ 12288, 1, 12 },
|
||||
{ 14336, 3, 11 },
|
||||
{ 16384, 0, 13 },
|
||||
{ 20480, 2, 12 },
|
||||
{ 24576, 1, 13 },
|
||||
{ 28672, 3, 12 },
|
||||
{ 32768, 0, 14 },
|
||||
{ 40960, 2, 13 },
|
||||
{ 49152, 1, 14 },
|
||||
{ 57344, 3, 13 },
|
||||
{ 65536, 0, 15 },
|
||||
{ 81920, 2, 14 },
|
||||
{ 98304, 1, 15 },
|
||||
{ 114688, 3, 14 },
|
||||
{ 163840, 2, 15 },
|
||||
{ 229376, 3, 15 },
|
||||
};
|
||||
|
||||
static mpc55xx_dspi_baudrate_scaler_entry mpc55xx_dspi_search_baudrate_scaler( uint32_t scaler, int min, int mid, int max)
|
||||
{
|
||||
if (scaler <= mpc55xx_dspi_baudrate_scaler_table [mid].scaler) {
|
||||
max = mid;
|
||||
} else {
|
||||
min = mid;
|
||||
}
|
||||
mid = (min + max) / 2;
|
||||
if (mid == min) {
|
||||
return mpc55xx_dspi_baudrate_scaler_table [max];
|
||||
} else {
|
||||
return mpc55xx_dspi_search_baudrate_scaler( scaler, min, mid, max);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t mpc55xx_dspi_push_data [8 * MPC55XX_DSPI_NUMBER] __attribute__ ((aligned (32)));
|
||||
|
||||
static inline void mpc55xx_dspi_store_push_data( mpc55xx_dspi_bus_entry *e)
|
||||
{
|
||||
mpc55xx_dspi_push_data [e->table_index * 8] = e->push_data.R;
|
||||
rtems_cache_flush_multiple_data_lines( &mpc55xx_dspi_push_data [e->table_index * 8], 4);
|
||||
}
|
||||
|
||||
static inline uint32_t mpc55xx_dspi_push_data_address( mpc55xx_dspi_bus_entry *e)
|
||||
{
|
||||
return (uint32_t) &mpc55xx_dspi_push_data [e->table_index * 8];
|
||||
}
|
||||
|
||||
static inline uint32_t mpc55xx_dspi_nirvana_address( mpc55xx_dspi_bus_entry *e)
|
||||
{
|
||||
return (uint32_t) &mpc55xx_dspi_push_data [e->table_index * 8 + 1];
|
||||
}
|
||||
|
||||
static rtems_status_code mpc55xx_dspi_init( rtems_libi2c_bus_t *bus)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
|
||||
union DSPI_MCR_tag mcr = MPC55XX_ZERO_FLAGS;
|
||||
union DSPI_CTAR_tag ctar = MPC55XX_ZERO_FLAGS;
|
||||
union DSPI_RSER_tag rser = MPC55XX_ZERO_FLAGS;
|
||||
struct tcd_t tcd_push = MPC55XX_EDMA_TCD_DEFAULT;
|
||||
int i = 0;
|
||||
|
||||
/* eDMA receive */
|
||||
sc = rtems_semaphore_create (
|
||||
rtems_build_name ( 'S', 'P', 'I', 'R'),
|
||||
0,
|
||||
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
|
||||
RTEMS_NO_PRIORITY,
|
||||
&e->edma_channel_receive_update
|
||||
);
|
||||
CHECK_SC( sc, "Create receive update semaphore");
|
||||
|
||||
sc = mpc55xx_edma_obtain_channel( e->edma_channel_receive, &e->edma_channel_receive_error, e->edma_channel_receive_update);
|
||||
CHECK_SC( sc, "Obtain receive eDMA channel");
|
||||
|
||||
/* eDMA transmit */
|
||||
sc = rtems_semaphore_create (
|
||||
rtems_build_name ( 'S', 'P', 'I', 'T'),
|
||||
0,
|
||||
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
|
||||
RTEMS_NO_PRIORITY,
|
||||
&e->edma_channel_transmit_update
|
||||
);
|
||||
CHECK_SC( sc, "Create transmit update semaphore");
|
||||
|
||||
sc = mpc55xx_edma_obtain_channel( e->edma_channel_transmit, &e->edma_channel_transmit_error, e->edma_channel_transmit_update);
|
||||
CHECK_SC( sc, "Obtain transmit eDMA channel");
|
||||
|
||||
sc = mpc55xx_edma_obtain_channel( e->edma_channel_push, NULL, RTEMS_ID_NONE);
|
||||
CHECK_SC( sc, "Obtain push eDMA channel");
|
||||
|
||||
tcd_push.SADDR = mpc55xx_dspi_push_data_address( e);
|
||||
tcd_push.SSIZE = 2;
|
||||
tcd_push.SOFF = 0;
|
||||
tcd_push.DADDR = (uint32_t) &e->regs->PUSHR.R;
|
||||
tcd_push.DSIZE = 2;
|
||||
tcd_push.DOFF = 0;
|
||||
tcd_push.NBYTES = 4;
|
||||
tcd_push.CITER = 1;
|
||||
tcd_push.BITER = 1;
|
||||
|
||||
EDMA.TCD [e->edma_channel_push] = tcd_push;
|
||||
|
||||
/* Module Control Register */
|
||||
mcr.B.MSTR = e->master ? 1 : 0;
|
||||
mcr.B.CONT_SCKE = 0;
|
||||
mcr.B.DCONF = 0;
|
||||
mcr.B.FRZ = 0;
|
||||
mcr.B.MTFE = 0;
|
||||
mcr.B.PCSSE = 0;
|
||||
mcr.B.ROOE = 0;
|
||||
mcr.B.PCSIS0 = 1;
|
||||
mcr.B.PCSIS1 = 1;
|
||||
mcr.B.PCSIS2 = 1;
|
||||
mcr.B.PCSIS3 = 1;
|
||||
mcr.B.PCSIS5 = 1;
|
||||
mcr.B.MDIS = 0;
|
||||
mcr.B.DIS_TXF = 0;
|
||||
mcr.B.DIS_RXF = 0;
|
||||
mcr.B.CLR_TXF = 0;
|
||||
mcr.B.CLR_RXF = 0;
|
||||
mcr.B.SMPL_PT = 0;
|
||||
mcr.B.HALT = 0;
|
||||
|
||||
e->regs->MCR.R = mcr.R;
|
||||
|
||||
/* Clock and Transfer Attributes Register */
|
||||
ctar.B.DBR = 0;
|
||||
ctar.B.FMSZ = 0x7;
|
||||
ctar.B.CPOL = 0;
|
||||
ctar.B.CPHA = 0;
|
||||
ctar.B.LSBFE = 0;
|
||||
ctar.B.PCSSCK = 0;
|
||||
ctar.B.PASC = 0;
|
||||
ctar.B.PDT = 0;
|
||||
ctar.B.PBR = 0;
|
||||
ctar.B.CSSCK = 0;
|
||||
ctar.B.ASC = 0;
|
||||
ctar.B.DT = 0;
|
||||
ctar.B.BR = 0;
|
||||
|
||||
for (i = 0; i < MPC55XX_DSPI_CTAR_NUMBER; ++i) {
|
||||
e->regs->CTAR [i].R = ctar.R;
|
||||
}
|
||||
|
||||
/* DMA/Interrupt Request Select and Enable Register */
|
||||
rser.B.TFFFRE = 1;
|
||||
rser.B.TFFFDIRS = 1;
|
||||
rser.B.RFDFRE = 1;
|
||||
rser.B.RFDFDIRS = 1;
|
||||
|
||||
e->regs->RSER.R = rser.R;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static rtems_status_code mpc55xx_dspi_send_start( rtems_libi2c_bus_t *bus)
|
||||
{
|
||||
mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
|
||||
|
||||
/* Reset chip selects */
|
||||
e->push_data.B.PCS0 = 0;
|
||||
e->push_data.B.PCS1 = 0;
|
||||
e->push_data.B.PCS2 = 0;
|
||||
e->push_data.B.PCS3 = 0;
|
||||
e->push_data.B.PCS4 = 0;
|
||||
e->push_data.B.PCS5 = 0;
|
||||
mpc55xx_dspi_store_push_data( e);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static rtems_status_code mpc55xx_dspi_send_stop( rtems_libi2c_bus_t *bus)
|
||||
{
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static rtems_status_code mpc55xx_dspi_send_addr( rtems_libi2c_bus_t *bus, uint32_t addr, int rw)
|
||||
{
|
||||
mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
|
||||
union DSPI_SR_tag sr = MPC55XX_ZERO_FLAGS;
|
||||
|
||||
/* Flush transmit and receive FIFO */
|
||||
e->regs->MCR.B.CLR_TXF = 1;
|
||||
e->regs->MCR.B.CLR_RXF = 1;
|
||||
|
||||
/* Clear status flags */
|
||||
sr.B.EOQF = 1;
|
||||
sr.B.TFFF = 1;
|
||||
sr.B.RFDF = 1;
|
||||
e->regs->SR.R = sr.R;
|
||||
|
||||
/* Frame command */
|
||||
e->push_data.R = 0;
|
||||
e->push_data.B.CONT = 0;
|
||||
e->push_data.B.CTAS = MPC55XX_DSPI_CTAR_DEFAULT;
|
||||
e->push_data.B.EOQ = 0;
|
||||
e->push_data.B.CTCNT = 0;
|
||||
switch (addr) {
|
||||
case 0:
|
||||
e->push_data.B.PCS0 = 1;
|
||||
break;
|
||||
case 1:
|
||||
e->push_data.B.PCS1 = 1;
|
||||
break;
|
||||
case 2:
|
||||
e->push_data.B.PCS2 = 1;
|
||||
break;
|
||||
case 3:
|
||||
e->push_data.B.PCS3 = 1;
|
||||
break;
|
||||
case 4:
|
||||
e->push_data.B.PCS4 = 1;
|
||||
break;
|
||||
case 5:
|
||||
e->push_data.B.PCS5 = 1;
|
||||
break;
|
||||
default:
|
||||
return -RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
mpc55xx_dspi_store_push_data( e);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int mpc55xx_dspi_set_transfer_mode( rtems_libi2c_bus_t *bus, const rtems_libi2c_tfr_mode_t *mode)
|
||||
{
|
||||
mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
|
||||
union DSPI_CTAR_tag ctar = MPC55XX_ZERO_FLAGS;
|
||||
// FIXME, TODO
|
||||
extern uint32_t bsp_clock_speed;
|
||||
uint32_t scaler = bsp_clock_speed / mode->baudrate;
|
||||
mpc55xx_dspi_baudrate_scaler_entry bse = mpc55xx_dspi_search_baudrate_scaler( scaler, 0, MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE / 2, MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE);
|
||||
|
||||
if (mode->bits_per_char != 8) {
|
||||
return -RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
|
||||
e->idle_char = mode->idle_char;
|
||||
|
||||
ctar.R = e->regs->CTAR [MPC55XX_DSPI_CTAR_DEFAULT].R;
|
||||
|
||||
ctar.B.PBR = bse.pbr;
|
||||
ctar.B.BR = bse.br;
|
||||
|
||||
// ctar.B.PCSSCK = bse.pbr;
|
||||
// ctar.B.CSSCK = bse.br;
|
||||
// ctar.B.PASC = bse.pbr;
|
||||
// ctar.B.ASC = bse.br;
|
||||
|
||||
ctar.B.PCSSCK = 0;
|
||||
ctar.B.CSSCK = 0;
|
||||
ctar.B.PASC = 0;
|
||||
ctar.B.ASC = 0;
|
||||
|
||||
ctar.B.LSBFE = mode->lsb_first ? 1 : 0;
|
||||
ctar.B.CPOL = mode->clock_inv ? 1 : 0;
|
||||
ctar.B.CPHA = mode->clock_phs ? 1 : 0;
|
||||
|
||||
e->regs->CTAR [MPC55XX_DSPI_CTAR_DEFAULT].R = ctar.R;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes @a n characters from @a out to bus @a bus and synchronously stores the received data in @a in.
|
||||
*
|
||||
* eDMA channel usage for transmission:
|
||||
* @dot
|
||||
* digraph push {
|
||||
* push [label="Push Register"];
|
||||
* push_data [label="Push Data"];
|
||||
* idle_push_data [label="Idle Push Data"];
|
||||
* out [shape=box,label="Output Buffer"];
|
||||
* edge [color=red,fontcolor=red];
|
||||
* push -> idle_push_data [label="Transmit Request",URL="\ref mpc55xx_dspi_bus_entry::edma_channel_transmit"];
|
||||
* push -> out [label="Transmit Request",URL="\ref mpc55xx_dspi_bus_entry::edma_channel_transmit"];
|
||||
* out -> push_data [label="Channel Link",URL="\ref mpc55xx_dspi_bus_entry::edma_channel_push"];
|
||||
* edge [color=blue,fontcolor=blue];
|
||||
* out -> push_data [label="Data"];
|
||||
* push_data -> push [label="Data"];
|
||||
* idle_push_data -> push [label="Data"];
|
||||
* }
|
||||
* @enddot
|
||||
*
|
||||
* eDMA channel usage for receiving:
|
||||
* @dot
|
||||
* digraph pop {
|
||||
* pop [label="Pop Register"];
|
||||
* nirvana [label="Nirvana"];
|
||||
* in [shape=box,label="Input Buffer"];
|
||||
* edge [color=red,fontcolor=red];
|
||||
* pop -> nirvana [label="Receive Request",URL="\ref mpc55xx_dspi_bus_entry::edma_channel_receive"];
|
||||
* pop -> in [label="Receive Request",URL="\ref mpc55xx_dspi_bus_entry::edma_channel_receive"];
|
||||
* edge [color=blue,fontcolor=blue];
|
||||
* pop -> nirvana [label="Data"];
|
||||
* pop -> in [label="Data"];
|
||||
* }
|
||||
* @enddot
|
||||
*/
|
||||
static int mpc55xx_dspi_read_write( rtems_libi2c_bus_t *bus, unsigned char *in, const unsigned char *out, int n)
|
||||
{
|
||||
mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
|
||||
|
||||
/* Non cache aligned characters */
|
||||
int n_nc = n;
|
||||
|
||||
/* Cache aligned characters */
|
||||
int n_c = 0;
|
||||
|
||||
/* Register addresses */
|
||||
volatile void *push = &e->regs->PUSHR.R;
|
||||
volatile void *pop = &e->regs->POPR.R;
|
||||
volatile union DSPI_SR_tag *status = &e->regs->SR;
|
||||
|
||||
/* Push and pop data */
|
||||
union DSPI_PUSHR_tag push_data = e->push_data;
|
||||
union DSPI_POPR_tag pop_data;
|
||||
|
||||
/* Status register */
|
||||
union DSPI_SR_tag sr;
|
||||
|
||||
/* Read and write indices */
|
||||
int r = 0;
|
||||
int w = 0;
|
||||
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
} else if (in == NULL && out == NULL) {
|
||||
return -RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
if (n > MPC55XX_DSPI_EDMA_MAGIC_SIZE) {
|
||||
n_nc = mpc55xx_non_cache_aligned_size( in);
|
||||
n_c = mpc55xx_cache_aligned_size( in, n);
|
||||
if (n_c > EDMA_TCD_BITER_LINKED_SIZE) {
|
||||
SYSLOG_WARNING( "Buffer size out of range, cannot use eDMA\n");
|
||||
n_nc = n;
|
||||
n_c = 0;
|
||||
} else if (n_nc + n_c != n) {
|
||||
SYSLOG_WARNING( "Input buffer not proper cache aligned, cannot use eDMA\n");
|
||||
n_nc = n;
|
||||
n_c = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (e->regs->SR.B.TXCTR != e->regs->SR.B.RXCTR) {
|
||||
SYSLOG_WARNING( "FIFO counter not equal\n");
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* Direct IO */
|
||||
if (out == NULL) {
|
||||
push_data.B.TXDATA = e->idle_char;
|
||||
while (r < n_nc || w < n_nc) {
|
||||
/* Wait for available FIFO */
|
||||
do {
|
||||
sr.R = status->R;
|
||||
} while (sr.B.TXCTR == MPC55XX_DSPI_FIFO_SIZE && sr.B.RXCTR == 0);
|
||||
|
||||
/* Write */
|
||||
if (w < n_nc && (w - r) < MPC55XX_DSPI_FIFO_SIZE && sr.B.TXCTR != MPC55XX_DSPI_FIFO_SIZE) {
|
||||
++w;
|
||||
ppc_write_word( push_data.R, push);
|
||||
}
|
||||
|
||||
/* Read */
|
||||
if (r < n_nc && sr.B.RXCTR != 0) {
|
||||
pop_data.R = ppc_read_word( pop);
|
||||
in [r] = pop_data.B.RXDATA;
|
||||
// printk( "[%03u]: 0x%02x -> 0x%02x\n", r, out [r], in [r]);
|
||||
++r;
|
||||
}
|
||||
}
|
||||
} else if (in == NULL) {
|
||||
while (r < n_nc || w < n_nc) {
|
||||
/* Wait for available FIFO */
|
||||
do {
|
||||
sr.R = status->R;
|
||||
} while (sr.B.TXCTR == MPC55XX_DSPI_FIFO_SIZE && sr.B.RXCTR == 0);
|
||||
|
||||
/* Write */
|
||||
if (w < n_nc && (w - r) < MPC55XX_DSPI_FIFO_SIZE && sr.B.TXCTR != MPC55XX_DSPI_FIFO_SIZE) {
|
||||
push_data.B.TXDATA = out [w];
|
||||
++w;
|
||||
ppc_write_word( push_data.R, push);
|
||||
}
|
||||
|
||||
/* Read */
|
||||
if (r < n_nc && sr.B.RXCTR != 0) {
|
||||
pop_data.R = ppc_read_word( pop);
|
||||
// printk( "[%03u]: 0x%02x -> 0x%02x\n", r, out [r], in [r]);
|
||||
++r;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (r < n_nc || w < n_nc) {
|
||||
/* Wait for available FIFO */
|
||||
do {
|
||||
sr.R = status->R;
|
||||
} while (sr.B.TXCTR == MPC55XX_DSPI_FIFO_SIZE && sr.B.RXCTR == 0);
|
||||
|
||||
/* Write */
|
||||
if (w < n_nc && (w - r) < MPC55XX_DSPI_FIFO_SIZE && sr.B.TXCTR != MPC55XX_DSPI_FIFO_SIZE) {
|
||||
push_data.B.TXDATA = out [w];
|
||||
++w;
|
||||
ppc_write_word( push_data.R, push);
|
||||
}
|
||||
|
||||
/* Read */
|
||||
if (r < n_nc && sr.B.RXCTR != 0) {
|
||||
pop_data.R = ppc_read_word( pop);
|
||||
in [r] = pop_data.B.RXDATA;
|
||||
// printk( "[%03u]: 0x%02x -> 0x%02x\n", r, out [r], in [r]);
|
||||
++r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* eDMA transfers */
|
||||
if (n_c > 0) {
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
unsigned char *in_c = in + n_nc;
|
||||
const unsigned char *out_c = out + n_nc;
|
||||
struct tcd_t tcd_transmit = MPC55XX_EDMA_TCD_DEFAULT;
|
||||
struct tcd_t tcd_receive = MPC55XX_EDMA_TCD_DEFAULT;
|
||||
|
||||
/* Cache operations */
|
||||
rtems_cache_flush_multiple_data_lines( out_c, n_c);
|
||||
rtems_cache_invalidate_multiple_data_lines( in_c, n_c);
|
||||
|
||||
/* Set transmit TCD */
|
||||
if (out == NULL) {
|
||||
e->push_data.B.TXDATA = e->idle_char;
|
||||
mpc55xx_dspi_store_push_data( e);
|
||||
tcd_transmit.SADDR = mpc55xx_dspi_push_data_address( e);
|
||||
tcd_transmit.SSIZE = 2;
|
||||
tcd_transmit.SOFF = 0;
|
||||
tcd_transmit.DADDR = (uint32_t) push;
|
||||
tcd_transmit.DSIZE = 2;
|
||||
tcd_transmit.DOFF = 0;
|
||||
tcd_transmit.NBYTES = 4;
|
||||
tcd_transmit.CITER = n_c;
|
||||
tcd_transmit.BITER = n_c;
|
||||
} else {
|
||||
EDMA.CDSBR.R = e->edma_channel_transmit;
|
||||
tcd_transmit.SADDR = (uint32_t) out_c;
|
||||
tcd_transmit.SSIZE = 0;
|
||||
tcd_transmit.SOFF = 1;
|
||||
tcd_transmit.DADDR = mpc55xx_dspi_push_data_address( e) + 3;
|
||||
tcd_transmit.DSIZE = 0;
|
||||
tcd_transmit.DOFF = 0;
|
||||
tcd_transmit.NBYTES = 1;
|
||||
tcd_transmit.CITERE_LINK = 1;
|
||||
tcd_transmit.BITERE_LINK = 1;
|
||||
tcd_transmit.MAJORLINKCH = e->edma_channel_push;
|
||||
tcd_transmit.CITER = EDMA_TCD_LINK_AND_BITER( e->edma_channel_push, n_c);
|
||||
tcd_transmit.BITER = EDMA_TCD_LINK_AND_BITER( e->edma_channel_push, n_c);
|
||||
tcd_transmit.MAJORE_LINK = 1;
|
||||
}
|
||||
tcd_transmit.D_REQ = 1;
|
||||
tcd_transmit.INT_MAJ = 1;
|
||||
EDMA.TCD [e->edma_channel_transmit] = tcd_transmit;
|
||||
|
||||
/* Set receive TCD */
|
||||
if (in == NULL) {
|
||||
tcd_receive.DOFF = 0;
|
||||
tcd_receive.DADDR = mpc55xx_dspi_nirvana_address( e);
|
||||
} else {
|
||||
tcd_receive.DOFF = 1;
|
||||
tcd_receive.DADDR = (uint32_t) in_c;
|
||||
}
|
||||
tcd_receive.SADDR = (uint32_t) pop + 3;
|
||||
tcd_receive.SSIZE = 0;
|
||||
tcd_receive.SOFF = 0;
|
||||
tcd_receive.DSIZE = 0;
|
||||
tcd_receive.NBYTES = 1;
|
||||
tcd_receive.D_REQ = 1;
|
||||
tcd_receive.INT_MAJ = 1;
|
||||
tcd_receive.CITER = n_c;
|
||||
tcd_receive.BITER = n_c;
|
||||
EDMA.TCD [e->edma_channel_receive] = tcd_receive;
|
||||
|
||||
/* Clear request flags */
|
||||
sr.R = 0;
|
||||
sr.B.TFFF = 1;
|
||||
sr.B.RFDF = 1;
|
||||
status->R = sr.R;
|
||||
|
||||
/* Enable hardware requests */
|
||||
sc = mpc55xx_edma_enable_hardware_requests( e->edma_channel_receive, true);
|
||||
CHECK_SCRV( sc, "Enable receive hardware requests");
|
||||
sc = mpc55xx_edma_enable_hardware_requests( e->edma_channel_transmit, true);
|
||||
CHECK_SCRV( sc, "Enable transmit hardware requests");
|
||||
|
||||
/* Wait for transmit update */
|
||||
sc = rtems_semaphore_obtain( e->edma_channel_transmit_update, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
CHECK_SCRV( sc, "Transmit update");
|
||||
if (e->edma_channel_transmit_error != 0) {
|
||||
SYSLOG_ERROR( "Transmit error status: 0x%08x\n", e->edma_channel_transmit_error);
|
||||
e->edma_channel_transmit_error = 0;
|
||||
return -RTEMS_IO_ERROR;
|
||||
}
|
||||
|
||||
/* Wait for receive update */
|
||||
sc = rtems_semaphore_obtain( e->edma_channel_receive_update, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
CHECK_SCRV( sc, "Receive update");
|
||||
if (e->edma_channel_receive_error != 0) {
|
||||
SYSLOG_ERROR( "Receive error status: 0x%08x\n", e->edma_channel_receive_error);
|
||||
e->edma_channel_receive_error = 0;
|
||||
return -RTEMS_IO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads @a n characters from bus @a bus and stores it in @a in.
|
||||
*
|
||||
* Writes idle characters to receive data.
|
||||
*
|
||||
* @see mpc55xx_dspi_read_write().
|
||||
*/
|
||||
static int mpc55xx_dspi_read( rtems_libi2c_bus_t *bus, unsigned char *in, int n)
|
||||
{
|
||||
return mpc55xx_dspi_read_write( bus, in, NULL, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes @a n characters from @a out to bus @a bus.
|
||||
*
|
||||
* Discards the synchronously received data.
|
||||
*
|
||||
* @see mpc55xx_dspi_read_write().
|
||||
*/
|
||||
static int mpc55xx_dspi_write( rtems_libi2c_bus_t *bus, unsigned char *out, int n)
|
||||
{
|
||||
return mpc55xx_dspi_read_write( bus, NULL, out, n);
|
||||
}
|
||||
|
||||
static int mpc55xx_dspi_ioctl( rtems_libi2c_bus_t *bus, int cmd, void *arg)
|
||||
{
|
||||
int rv = -1;
|
||||
switch (cmd) {
|
||||
case RTEMS_LIBI2C_IOCTL_SET_TFRMODE:
|
||||
rv = mpc55xx_dspi_set_transfer_mode( bus, (const rtems_libi2c_tfr_mode_t *) arg);
|
||||
break;
|
||||
case RTEMS_LIBI2C_IOCTL_READ_WRITE:
|
||||
rv = mpc55xx_dspi_read_write(
|
||||
bus,
|
||||
((rtems_libi2c_read_write_t *) arg)->rd_buf,
|
||||
((rtems_libi2c_read_write_t *) arg)->wr_buf,
|
||||
((rtems_libi2c_read_write_t *) arg)->byte_cnt
|
||||
);
|
||||
break;
|
||||
default:
|
||||
rv = -RTEMS_NOT_DEFINED;
|
||||
break;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static const rtems_libi2c_bus_ops_t mpc55xx_dspi_ops = {
|
||||
.init = mpc55xx_dspi_init,
|
||||
.send_start = mpc55xx_dspi_send_start,
|
||||
.send_stop = mpc55xx_dspi_send_stop,
|
||||
.send_addr = mpc55xx_dspi_send_addr,
|
||||
.read_bytes = mpc55xx_dspi_read,
|
||||
.write_bytes = mpc55xx_dspi_write,
|
||||
.ioctl = mpc55xx_dspi_ioctl
|
||||
};
|
||||
|
||||
mpc55xx_dspi_bus_entry mpc55xx_dspi_bus_table [MPC55XX_DSPI_NUMBER] = { {
|
||||
/* DSPI A */
|
||||
.bus = {
|
||||
.ops = &mpc55xx_dspi_ops,
|
||||
.size = sizeof( mpc55xx_dspi_bus_entry)
|
||||
},
|
||||
.table_index = 0,
|
||||
.bus_number = 0,
|
||||
.regs = &DSPI_A,
|
||||
.master = 1,
|
||||
.push_data = MPC55XX_ZERO_FLAGS,
|
||||
.edma_channel_transmit = 32,
|
||||
.edma_channel_push = 43,
|
||||
.edma_channel_receive = 33,
|
||||
.edma_channel_transmit_update = 0,
|
||||
.edma_channel_receive_update = 0,
|
||||
.edma_channel_transmit_error = 0,
|
||||
.edma_channel_receive_error = 0,
|
||||
.idle_char = 0xffffffff,
|
||||
}, {
|
||||
/* DSPI B */
|
||||
.bus = {
|
||||
.ops = &mpc55xx_dspi_ops,
|
||||
.size = sizeof( mpc55xx_dspi_bus_entry)
|
||||
},
|
||||
.table_index = 1,
|
||||
.bus_number = 0,
|
||||
.regs = &DSPI_B,
|
||||
.master = 1,
|
||||
.push_data = MPC55XX_ZERO_FLAGS,
|
||||
.edma_channel_transmit = 12,
|
||||
.edma_channel_push = 10,
|
||||
.edma_channel_receive = 13,
|
||||
.edma_channel_transmit_update = 0,
|
||||
.edma_channel_receive_update = 0,
|
||||
.edma_channel_transmit_error = 0,
|
||||
.edma_channel_receive_error = 0,
|
||||
.idle_char = 0xffffffff,
|
||||
}, {
|
||||
/* DSPI C */
|
||||
.bus = {
|
||||
.ops = &mpc55xx_dspi_ops,
|
||||
.size = sizeof( mpc55xx_dspi_bus_entry)
|
||||
},
|
||||
.table_index = 2,
|
||||
.bus_number = 0,
|
||||
.regs = &DSPI_C,
|
||||
.master = 1,
|
||||
.push_data = MPC55XX_ZERO_FLAGS,
|
||||
.edma_channel_transmit = 14,
|
||||
.edma_channel_push = 11,
|
||||
.edma_channel_receive = 15,
|
||||
.edma_channel_transmit_update = 0,
|
||||
.edma_channel_receive_update = 0,
|
||||
.edma_channel_transmit_error = 0,
|
||||
.edma_channel_receive_error = 0,
|
||||
.idle_char = 0xffffffff,
|
||||
}, {
|
||||
/* DSPI D */
|
||||
.bus = {
|
||||
.ops = &mpc55xx_dspi_ops,
|
||||
.size = sizeof( mpc55xx_dspi_bus_entry)
|
||||
},
|
||||
.table_index = 3,
|
||||
.bus_number = 0,
|
||||
.regs = &DSPI_D,
|
||||
.master = 1,
|
||||
.push_data = MPC55XX_ZERO_FLAGS,
|
||||
.edma_channel_transmit = 16,
|
||||
.edma_channel_push = 18,
|
||||
.edma_channel_receive = 17,
|
||||
.edma_channel_transmit_update = 0,
|
||||
.edma_channel_receive_update = 0,
|
||||
.edma_channel_transmit_error = 0,
|
||||
.edma_channel_receive_error = 0,
|
||||
.idle_char = 0xffffffff,
|
||||
},
|
||||
};
|
||||
279
c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c
Normal file
279
c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c
Normal file
@@ -0,0 +1,279 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup mpc55xx
|
||||
*
|
||||
* @brief Enhanced Direct Memory Access (eDMA).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be found in the file
|
||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <mpc55xx/regs.h>
|
||||
#include <mpc55xx/edma.h>
|
||||
#include <mpc55xx/mpc55xx.h>
|
||||
|
||||
#include <bsp/irq.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define RTEMS_STATUS_CHECKS_USE_PRINTK
|
||||
|
||||
#include <rtems/status-checks.h>
|
||||
|
||||
#define MPC55XX_EDMA_CHANNEL_NUMBER 64
|
||||
#define MPC55XX_EDMA_INVALID_CHANNEL -1
|
||||
#define MPC55XX_EDMA_IS_CHANNEL_INVALID( i) ((i) < 0 || (i) >= MPC55XX_EDMA_CHANNEL_NUMBER)
|
||||
|
||||
#define MPC55XX_EDMA_IRQ_PRIORITY MPC55XX_INTC_MIN_PRIORITY
|
||||
|
||||
typedef struct {
|
||||
uint8_t channel;
|
||||
rtems_id transfer_update;
|
||||
uint32_t *error_status;
|
||||
} mpc55xx_edma_channel_entry;
|
||||
|
||||
static mpc55xx_edma_channel_entry mpc55xx_edma_channel_table [MPC55XX_EDMA_CHANNEL_NUMBER];
|
||||
|
||||
static uint32_t mpc55xx_edma_channel_occupation_low = 0;
|
||||
|
||||
static uint32_t mpc55xx_edma_channel_occupation_high = 0;
|
||||
|
||||
static rtems_id mpc55xx_edma_channel_occupation_mutex = RTEMS_ID_NONE;
|
||||
|
||||
static uint8_t mpc55xx_edma_irq_error_low_channel = 0;
|
||||
|
||||
static uint8_t mpc55xx_edma_irq_error_high_channel = 32;
|
||||
|
||||
static void mpc55xx_edma_irq_handler( rtems_vector_number vector, void *data)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
mpc55xx_edma_channel_entry *e = (mpc55xx_edma_channel_entry *) data;
|
||||
#ifdef DEBUG
|
||||
uint32_t citer = EDMA.TCD [e->channel].CITERE_LINK ? EDMA.TCD [e->channel].CITER & EDMA_TCD_BITER_LINKED_MASK : EDMA.TCD [e->channel].CITER;
|
||||
DEBUG_PRINT( "Channel %i (CITER = %i)\n", e->channel, citer);
|
||||
#endif /* DEBUG */
|
||||
EDMA.CIRQR.R = e->channel;
|
||||
sc = rtems_semaphore_release( e->transfer_update);
|
||||
SYSLOG_WARNING_SC( sc, "Transfer update semaphore release");
|
||||
}
|
||||
|
||||
static void mpc55xx_edma_irq_update_error_table( uint8_t *link_table, uint8_t *error_table, uint8_t channel)
|
||||
{
|
||||
int i = 0;
|
||||
error_table [channel] = 1;
|
||||
for (i = 0; i < MPC55XX_EDMA_CHANNEL_NUMBER; ++i) {
|
||||
if (channel == link_table [i] && error_table [i] == 0) {
|
||||
mpc55xx_edma_irq_update_error_table( link_table, error_table, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mpc55xx_edma_irq_error_handler( rtems_vector_number vector, void *data)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
uint8_t channel_start = *((uint8_t *) data);
|
||||
uint8_t channel_end = channel_start + 32;
|
||||
uint8_t i = 0;
|
||||
uint32_t mask = 0x1;
|
||||
uint32_t error_register = 0;
|
||||
uint8_t channel_link_table [MPC55XX_EDMA_CHANNEL_NUMBER];
|
||||
uint8_t channel_error_table [MPC55XX_EDMA_CHANNEL_NUMBER];
|
||||
|
||||
/* Error register */
|
||||
if (channel_start < 32) {
|
||||
error_register = EDMA.ERL.R;
|
||||
} else if (channel_start < 64) {
|
||||
error_register = EDMA.ERH.R;
|
||||
}
|
||||
DEBUG_PRINT( "Error register %s: 0x%08x\n", channel_start < 32 ? "low" : "high", error_register);
|
||||
|
||||
/* Fill channel link table */
|
||||
for (i = 0; i < MPC55XX_EDMA_CHANNEL_NUMBER; ++i) {
|
||||
if (EDMA.TCD [i].BITERE_LINK && EDMA.TCD [i].CITER != EDMA.TCD [i].BITER) {
|
||||
channel_link_table [i] = EDMA_TCD_BITER_LINK( i);
|
||||
} else if (EDMA.TCD [i].MAJORE_LINK && EDMA.TCD [i].CITER == EDMA.TCD [i].BITER) {
|
||||
channel_link_table [i] = EDMA.TCD [i].MAJORLINKCH;
|
||||
} else {
|
||||
channel_link_table [i] = MPC55XX_EDMA_INVALID_CHANNEL;
|
||||
}
|
||||
channel_error_table [i] = 0;
|
||||
}
|
||||
|
||||
/* Search for channels with errors */
|
||||
for (i = channel_start; i < channel_end; ++i) {
|
||||
if ((error_register & mask) != 0) {
|
||||
mpc55xx_edma_irq_update_error_table( channel_link_table, channel_error_table, i);
|
||||
}
|
||||
mask <<= 1;
|
||||
}
|
||||
|
||||
/* Process the channels related to errors */
|
||||
error_register = EDMA.ESR.R;
|
||||
for (i = 0; i < MPC55XX_EDMA_CHANNEL_NUMBER; ++i) {
|
||||
if (channel_error_table [i]) {
|
||||
mpc55xx_edma_channel_entry *e = &mpc55xx_edma_channel_table [i];
|
||||
if (e->error_status != NULL) {
|
||||
*e->error_status = error_register;
|
||||
}
|
||||
sc = mpc55xx_edma_enable_hardware_requests( i, false);
|
||||
SYSLOG_ERROR_SC( sc, "Disable hardware requests, channel = %i", i);
|
||||
sc = rtems_semaphore_release( e->transfer_update);
|
||||
SYSLOG_WARNING_SC( sc, "Transfer update semaphore release, channel = %i", i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the error interrupt requests */
|
||||
for (i = 0; i < MPC55XX_EDMA_CHANNEL_NUMBER; ++i) {
|
||||
if (channel_error_table [i]) {
|
||||
EDMA.CER.R = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rtems_status_code mpc55xx_edma_enable_hardware_requests( int channel, bool enable)
|
||||
{
|
||||
if (MPC55XX_EDMA_IS_CHANNEL_INVALID( channel)) {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
if (enable) {
|
||||
EDMA.SERQR.R = channel;
|
||||
} else {
|
||||
EDMA.CERQR.R = channel;
|
||||
}
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc55xx_edma_enable_error_interrupts( int channel, bool enable)
|
||||
{
|
||||
if (MPC55XX_EDMA_IS_CHANNEL_INVALID( channel)) {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
if (enable) {
|
||||
EDMA.SEEIR.R = channel;
|
||||
} else {
|
||||
EDMA.CEEIR.R = channel;
|
||||
}
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc55xx_edma_init()
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
int i = 0;
|
||||
|
||||
/* Channel occupation mutex */
|
||||
sc = rtems_semaphore_create (
|
||||
rtems_build_name ( 'D', 'M', 'A', 'O'),
|
||||
1,
|
||||
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
|
||||
RTEMS_NO_PRIORITY,
|
||||
&mpc55xx_edma_channel_occupation_mutex
|
||||
);
|
||||
CHECK_SC( sc, "Create channel occupation mutex");
|
||||
|
||||
/* Arbitration mode: round robin */
|
||||
EDMA.CR.B.ERCA = 1;
|
||||
EDMA.CR.B.ERGA = 1;
|
||||
|
||||
/* Clear TCDs */
|
||||
memset( &EDMA.TCD [0], 0, sizeof( EDMA.TCD));
|
||||
|
||||
/* Channel table */
|
||||
for (i = 0; i < MPC55XX_EDMA_CHANNEL_NUMBER; ++i) {
|
||||
mpc55xx_edma_channel_table [i].channel = i;
|
||||
mpc55xx_edma_channel_table [i].transfer_update = RTEMS_ID_NONE;
|
||||
mpc55xx_edma_channel_table [i].error_status = NULL;
|
||||
}
|
||||
|
||||
/* Error interrupt handler */
|
||||
sc = mpc55xx_interrupt_handler_install(
|
||||
MPC55XX_IRQ_EDMA_ERROR_LOW,
|
||||
MPC55XX_EDMA_IRQ_PRIORITY,
|
||||
"eDMA Error (Low)",
|
||||
RTEMS_INTERRUPT_UNIQUE,
|
||||
mpc55xx_edma_irq_error_handler,
|
||||
&mpc55xx_edma_irq_error_low_channel
|
||||
);
|
||||
CHECK_SC( sc, "Install low error interrupt handler");
|
||||
sc = mpc55xx_interrupt_handler_install(
|
||||
MPC55XX_IRQ_EDMA_ERROR_HIGH,
|
||||
MPC55XX_EDMA_IRQ_PRIORITY,
|
||||
"eDMA Error (High)",
|
||||
RTEMS_INTERRUPT_UNIQUE,
|
||||
mpc55xx_edma_irq_error_handler,
|
||||
&mpc55xx_edma_irq_error_high_channel
|
||||
);
|
||||
CHECK_SC( sc, "Install high error interrupt handler");
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc55xx_edma_obtain_channel( int channel, uint32_t *error_status, rtems_id transfer_update)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
int channel_occupied = 1;
|
||||
|
||||
if (MPC55XX_EDMA_IS_CHANNEL_INVALID( channel)) {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
|
||||
/* Check occupation */
|
||||
sc = rtems_semaphore_obtain( mpc55xx_edma_channel_occupation_mutex, RTEMS_WAIT, 0);
|
||||
CHECK_SC( sc, "Obtain channel occupation mutex");
|
||||
if (channel < 32) {
|
||||
channel_occupied = mpc55xx_edma_channel_occupation_low & (0x1 << channel);
|
||||
if (!channel_occupied) {
|
||||
mpc55xx_edma_channel_occupation_low |= 0x1 << channel;
|
||||
}
|
||||
} else if (channel < 64) {
|
||||
channel_occupied = mpc55xx_edma_channel_occupation_high & (0x1 << (channel - 32));
|
||||
if (!channel_occupied) {
|
||||
mpc55xx_edma_channel_occupation_high |= 0x1 << (channel - 32);
|
||||
}
|
||||
}
|
||||
if (channel_occupied) {
|
||||
sc = rtems_semaphore_release( mpc55xx_edma_channel_occupation_mutex);
|
||||
SYSLOG_WARNING_SC( sc, "Release occupation mutex");
|
||||
return RTEMS_RESOURCE_IN_USE;
|
||||
} else {
|
||||
sc = rtems_semaphore_release( mpc55xx_edma_channel_occupation_mutex);
|
||||
CHECK_SC( sc, "Release channel occupation mutex");
|
||||
}
|
||||
|
||||
/* Channel data */
|
||||
mpc55xx_edma_channel_table [channel].transfer_update = transfer_update;
|
||||
mpc55xx_edma_channel_table [channel].error_status = error_status;
|
||||
|
||||
/* Interrupt handler */
|
||||
sc = mpc55xx_interrupt_handler_install(
|
||||
MPC55XX_IRQ_EDMA_GET_REQUEST( channel),
|
||||
MPC55XX_EDMA_IRQ_PRIORITY,
|
||||
"eDMA Channel",
|
||||
RTEMS_INTERRUPT_SHARED,
|
||||
mpc55xx_edma_irq_handler,
|
||||
&mpc55xx_edma_channel_table [channel]
|
||||
);
|
||||
CHECK_SC( sc, "Install channel interrupt handler");
|
||||
|
||||
/* Enable error interrupts */
|
||||
sc = mpc55xx_edma_enable_error_interrupts( channel, true);
|
||||
CHECK_SC( sc, "Enable error interrupts");
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc55xx_edma_release_channel( int channel)
|
||||
{
|
||||
// TODO
|
||||
return RTEMS_NOT_IMPLEMENTED;
|
||||
}
|
||||
659
c/src/lib/libcpu/powerpc/mpc55xx/esci/esci.c
Normal file
659
c/src/lib/libcpu/powerpc/mpc55xx/esci/esci.c
Normal file
@@ -0,0 +1,659 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup mpc55xx_esci
|
||||
*
|
||||
* @brief Source file for the Enhanced Serial Communication Interface (eSCI).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be found in the file
|
||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
/* Include order is important */
|
||||
#include <mpc55xx/regs.h>
|
||||
#include <mpc55xx/esci.h>
|
||||
#include <bsp/irq.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <rtems/console.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#define RTEMS_STATUS_CHECKS_USE_PRINTK
|
||||
|
||||
#include <rtems/status-checks.h>
|
||||
|
||||
/* Evil define conflicts */
|
||||
#define TERMIOS_CR1 CR1
|
||||
#undef CR1
|
||||
#define TERMIOS_CR2 CR2
|
||||
#undef CR2
|
||||
|
||||
#define MPC55XX_ESCI_IRQ_PRIORITY MPC55XX_INTC_MIN_PRIORITY
|
||||
|
||||
#define MPC55XX_ESCI_IS_MINOR_INVALD(minor) ((minor) < 0 || (minor) >= MPC55XX_ESCI_NUMBER)
|
||||
|
||||
#define MPC55XX_ESCI_USE_INTERRUPTS(e) (!(e)->console && (e)->use_interrupts)
|
||||
|
||||
/**
|
||||
* @brief eSCI driver table.
|
||||
*/
|
||||
mpc55xx_esci_driver_entry mpc55xx_esci_driver_table [MPC55XX_ESCI_NUMBER] = { {
|
||||
.regs = &ESCI_A,
|
||||
.device_name = "/dev/tty1",
|
||||
.use_termios = 1,
|
||||
.use_interrupts = 0,
|
||||
.console = 1,
|
||||
.tty = NULL,
|
||||
.irq_number = 146
|
||||
}, {
|
||||
.regs = &ESCI_B,
|
||||
.device_name = "/dev/tty2",
|
||||
.use_termios = 1,
|
||||
.use_interrupts = 0,
|
||||
.console = 0,
|
||||
.tty = NULL,
|
||||
.irq_number = 149
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Default termios configuration.
|
||||
*/
|
||||
static const struct termios mpc55xx_esci_termios_default = {
|
||||
0,
|
||||
0,
|
||||
CS8 | CREAD | CLOCAL | B115200,
|
||||
0,
|
||||
0,
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/**
|
||||
* @name Low-Level
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Reads one character from the receive register.
|
||||
*
|
||||
* @note Waits for the receive data register full flag.
|
||||
*/
|
||||
static inline uint8_t mpc55xx_esci_read_char( mpc55xx_esci_driver_entry *e)
|
||||
{
|
||||
volatile union ESCI_SR_tag *status = &e->regs->SR;
|
||||
volatile union ESCI_DR_tag *data = &e->regs->DR;
|
||||
union ESCI_SR_tag sr = MPC55XX_ZERO_FLAGS;
|
||||
|
||||
while (status->B.RDRF == 0) {
|
||||
/* Wait */
|
||||
}
|
||||
|
||||
/* Clear flag */
|
||||
sr.B.RDRF = 1;
|
||||
status->R = sr.R;
|
||||
|
||||
/* Read */
|
||||
return data->B.D;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes the character @a c to the transmit register.
|
||||
*
|
||||
* @note Waits for the transmit data register empty flag.
|
||||
*/
|
||||
static inline void mpc55xx_esci_write_char( mpc55xx_esci_driver_entry *e, uint8_t c)
|
||||
{
|
||||
volatile union ESCI_SR_tag *status = &e->regs->SR;
|
||||
volatile union ESCI_DR_tag *data = &e->regs->DR;
|
||||
union ESCI_SR_tag sr = MPC55XX_ZERO_FLAGS;
|
||||
|
||||
while (status->B.TDRE == 0) {
|
||||
/* Wait */
|
||||
}
|
||||
|
||||
/* Clear flag */
|
||||
sr.B.TDRE = 1;
|
||||
status->R = sr.R;
|
||||
|
||||
/* Write */
|
||||
data->B.D = c;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Termios Support
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Opens port @a minor.
|
||||
*
|
||||
* @return Status code.
|
||||
*/
|
||||
static int mpc55xx_esci_termios_first_open( int major, int minor, void *arg)
|
||||
{
|
||||
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
|
||||
union ESCI_CR1_tag cr1 = MPC55XX_ZERO_FLAGS;
|
||||
struct rtems_termios_tty *tty = ((rtems_libio_open_close_args_t *) arg)->iop->data1;
|
||||
|
||||
/* Check minor number */
|
||||
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
|
||||
/* Connect TTY */
|
||||
e->tty = tty;
|
||||
|
||||
/* Enable interrupts */
|
||||
if (MPC55XX_ESCI_USE_INTERRUPTS( e)) {
|
||||
cr1.R = e->regs->CR1.R;
|
||||
cr1.B.RIE = 1;
|
||||
cr1.B.TIE = 1;
|
||||
e->regs->CR1.R = cr1.R;
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Closes port @a minor.
|
||||
*
|
||||
* @return Status code.
|
||||
*/
|
||||
static int mpc55xx_esci_termios_last_close( int major, int minor, void* arg)
|
||||
{
|
||||
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
|
||||
union ESCI_CR1_tag cr1 = MPC55XX_ZERO_FLAGS;
|
||||
|
||||
/* Check minor number */
|
||||
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
|
||||
/* Disable interrupts */
|
||||
cr1.R = e->regs->CR1.R;
|
||||
cr1.B.RIE = 0;
|
||||
cr1.B.TIE = 0;
|
||||
e->regs->CR1.R = cr1.R;
|
||||
|
||||
/* Disconnect TTY */
|
||||
e->tty = NULL;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads one character from port @a minor.
|
||||
*
|
||||
* @return Returns the character or -1 on error.
|
||||
*/
|
||||
static int mpc55xx_esci_termios_poll_read( int minor)
|
||||
{
|
||||
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
|
||||
|
||||
/* Check minor number */
|
||||
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int) mpc55xx_esci_read_char( e);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes @a n characters from @a out to port @a minor.
|
||||
*
|
||||
* @return Returns 0 on success or -1 otherwise.
|
||||
*/
|
||||
static int mpc55xx_esci_termios_poll_write( int minor, const char *out, int n)
|
||||
{
|
||||
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
|
||||
int i = 0;
|
||||
|
||||
/* Check minor number */
|
||||
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Write */
|
||||
for (i = 0; i < n; ++i) {
|
||||
mpc55xx_esci_write_char( e, out [i]);
|
||||
if (out [i] == '\n') {
|
||||
mpc55xx_esci_write_char( e, '\r');
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes one character from @a out to port @a minor.
|
||||
*
|
||||
* @return Returns always 0.
|
||||
*
|
||||
* @note The buffer @a out has to provide at least one character.
|
||||
* This function assumes that the transmit data register is empty.
|
||||
*/
|
||||
static int mpc55xx_esci_termios_write( int minor, const char *out, int n)
|
||||
{
|
||||
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
|
||||
|
||||
/* Write */
|
||||
e->regs->DR.B.D = out [0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets attributes of port @a minor according to termios attributes @a t.
|
||||
*
|
||||
* @return Status code.
|
||||
*/
|
||||
static int mpc55xx_esci_termios_set_attributes( int minor, const struct termios *t)
|
||||
{
|
||||
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
|
||||
volatile struct ESCI_tag *regs = e->regs;
|
||||
union ESCI_CR1_tag cr1 = MPC55XX_ZERO_FLAGS;
|
||||
union ESCI_CR2_tag cr2 = MPC55XX_ZERO_FLAGS;
|
||||
unsigned br = 0;
|
||||
|
||||
/* Check minor number */
|
||||
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
|
||||
/* Enable module */
|
||||
cr2.B.MDIS = 0;
|
||||
|
||||
/* Interrupts */
|
||||
if (MPC55XX_ESCI_USE_INTERRUPTS( e) && e->tty != NULL) {
|
||||
cr1.B.RIE = 1;
|
||||
cr1.B.TIE = 1;
|
||||
} else {
|
||||
cr1.B.RIE = 0;
|
||||
cr1.B.TIE = 0;
|
||||
}
|
||||
cr1.B.TCIE = 0;
|
||||
cr1.B.ILIE = 0;
|
||||
cr2.B.IEBERR = 0;
|
||||
cr2.B.ORIE = 0;
|
||||
cr2.B.NFIE = 0;
|
||||
cr2.B.FEIE = 0;
|
||||
cr2.B.PFIE = 0;
|
||||
|
||||
/* Disable receiver wake-up standby */
|
||||
cr1.B.RWU = 0;
|
||||
|
||||
/* Disable DMA channels */
|
||||
cr2.B.RXDMA = 0;
|
||||
cr2.B.TXDMA = 0;
|
||||
|
||||
/* Idle line type */
|
||||
cr1.B.ILT = 0;
|
||||
|
||||
/* Disable loops */
|
||||
cr1.B.LOOPS = 0;
|
||||
|
||||
/* Enable or disable receiver */
|
||||
cr1.B.RE = (t->c_cflag & CREAD) ? 1 : 0;
|
||||
|
||||
/* Enable transmitter */
|
||||
cr1.B.TE = 1;
|
||||
|
||||
/* Baud rate */
|
||||
switch (t->c_cflag & CBAUD) {
|
||||
case B50: br = 50; break;
|
||||
case B75: br = 75; break;
|
||||
case B110: br = 110; break;
|
||||
case B134: br = 134; break;
|
||||
case B150: br = 150; break;
|
||||
case B200: br = 200; break;
|
||||
case B300: br = 300; break;
|
||||
case B600: br = 600; break;
|
||||
case B1200: br = 1200; break;
|
||||
case B1800: br = 1800; break;
|
||||
case B2400: br = 2400; break;
|
||||
case B4800: br = 4800; break;
|
||||
case B9600: br = 9600; break;
|
||||
case B19200: br = 19200; break;
|
||||
case B38400: br = 38400; break;
|
||||
case B57600: br = 57600; break;
|
||||
case B115200: br = 115200; break;
|
||||
case B230400: br = 230400; break;
|
||||
case B460800: br = 460800; break;
|
||||
default: br = 0; break;
|
||||
}
|
||||
if (br > 0) {
|
||||
// FIXME, TODO
|
||||
extern uint32_t bsp_clock_speed;
|
||||
|
||||
br = bsp_clock_speed / (16 * br);
|
||||
br = (br > 8191) ? 8191 : br;
|
||||
} else {
|
||||
br = 0;
|
||||
}
|
||||
cr1.B.SBR = br;
|
||||
|
||||
/* Number of data bits */
|
||||
if ((t->c_cflag & CSIZE) != CS8) {
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
cr1.B.M = 0;
|
||||
|
||||
/* Parity */
|
||||
cr1.B.PE = (t->c_cflag & PARENB) ? 1 : 0;
|
||||
cr1.B.PT = (t->c_cflag & PARODD) ? 1 : 0;
|
||||
|
||||
/* Stop bits */
|
||||
if ( t->c_cflag & CSTOPB ) {
|
||||
/* Two stop bits */
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
|
||||
/* Set control registers */
|
||||
regs->CR1.R = cr1.R;
|
||||
regs->CR2.R = cr2.R;
|
||||
|
||||
/* Disable LIN */
|
||||
regs->LCR.R = 0;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Interrupt handler.
|
||||
*/
|
||||
static void mpc55xx_esci_termios_interrupt_handler( rtems_vector_number vector, void *arg)
|
||||
{
|
||||
mpc55xx_esci_driver_entry *e = (mpc55xx_esci_driver_entry *) arg;
|
||||
volatile union ESCI_SR_tag *status = &e->regs->SR;
|
||||
volatile union ESCI_DR_tag *data = &e->regs->DR;
|
||||
union ESCI_SR_tag sr = MPC55XX_ZERO_FLAGS;
|
||||
union ESCI_SR_tag active = MPC55XX_ZERO_FLAGS;
|
||||
|
||||
/* Status */
|
||||
sr.R = status->R;
|
||||
|
||||
/* Receive data register full? */
|
||||
if (sr.B.RDRF != 0) {
|
||||
active.B.RDRF = 1;
|
||||
}
|
||||
|
||||
/* Transmit data register empty? */
|
||||
if (sr.B.TDRE != 0) {
|
||||
active.B.TDRE = 1;
|
||||
}
|
||||
|
||||
/* Clear flags */
|
||||
status->R = active.R;
|
||||
|
||||
/* Enqueue */
|
||||
if (active.B.RDRF != 0) {
|
||||
char c = data->B.D;
|
||||
rtems_termios_enqueue_raw_characters( e->tty, &c, 1);
|
||||
}
|
||||
|
||||
/* Dequeue */
|
||||
if (active.B.TDRE != 0) {
|
||||
rtems_termios_dequeue_characters( e->tty, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Termios callbacks with interrupt support.
|
||||
*/
|
||||
static const rtems_termios_callbacks mpc55xx_esci_termios_callbacks = {
|
||||
.firstOpen = mpc55xx_esci_termios_first_open,
|
||||
.lastClose = mpc55xx_esci_termios_last_close,
|
||||
.pollRead = NULL,
|
||||
.write = mpc55xx_esci_termios_write,
|
||||
.setAttributes = mpc55xx_esci_termios_set_attributes,
|
||||
.stopRemoteTx = NULL,
|
||||
.startRemoteTx = NULL,
|
||||
.outputUsesInterrupts = TERMIOS_IRQ_DRIVEN
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Termios callbacks with polling functions (no interrupts).
|
||||
*/
|
||||
static const rtems_termios_callbacks mpc55xx_esci_termios_callbacks_polled = {
|
||||
.firstOpen = mpc55xx_esci_termios_first_open,
|
||||
.lastClose = mpc55xx_esci_termios_last_close,
|
||||
.pollRead = mpc55xx_esci_termios_poll_read,
|
||||
.write = mpc55xx_esci_termios_poll_write,
|
||||
.setAttributes = mpc55xx_esci_termios_set_attributes,
|
||||
.stopRemoteTx = NULL,
|
||||
.startRemoteTx = NULL,
|
||||
.outputUsesInterrupts = TERMIOS_POLLED
|
||||
};
|
||||
|
||||
/**
|
||||
* @name Console Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
rtems_device_driver console_initialize( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
int console_done = 0;
|
||||
int termios_do_init = 1;
|
||||
int i = 0;
|
||||
mpc55xx_esci_driver_entry *e = NULL;
|
||||
|
||||
for (i = 0; i < MPC55XX_ESCI_NUMBER; ++i) {
|
||||
e = &mpc55xx_esci_driver_table [i];
|
||||
sc = rtems_io_register_name ( e->device_name, major, i);
|
||||
CHECK_SC( sc, "Register IO device");
|
||||
if (e->console) {
|
||||
if (console_done) {
|
||||
SYSLOG_WARNING( "Multiple console ports defined\n");
|
||||
} else {
|
||||
console_done = 1;
|
||||
if (e->use_interrupts) {
|
||||
SYSLOG_WARNING( "Cannot use interrupts for console port\n");
|
||||
}
|
||||
sc = rtems_io_register_name( CONSOLE_DEVICE_NAME, major, i);
|
||||
CHECK_SC( sc, "Register IO device");
|
||||
}
|
||||
}
|
||||
if (e->use_termios && termios_do_init) {
|
||||
if (termios_do_init) {
|
||||
termios_do_init = 0;
|
||||
rtems_termios_initialize();
|
||||
}
|
||||
if (MPC55XX_ESCI_USE_INTERRUPTS( e)) {
|
||||
sc = mpc55xx_interrupt_handler_install(
|
||||
e->irq_number,
|
||||
MPC55XX_ESCI_IRQ_PRIORITY,
|
||||
"eSCI",
|
||||
RTEMS_INTERRUPT_UNIQUE,
|
||||
mpc55xx_esci_termios_interrupt_handler,
|
||||
e
|
||||
);
|
||||
CHECK_SC( sc, "Install IRQ handler");
|
||||
}
|
||||
}
|
||||
mpc55xx_esci_termios_set_attributes( minor, &mpc55xx_esci_termios_default);
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_device_driver console_open( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
int rv = 0;
|
||||
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
|
||||
|
||||
/* Check minor number */
|
||||
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
|
||||
if (e->use_termios) {
|
||||
if (MPC55XX_ESCI_USE_INTERRUPTS( e)) {
|
||||
sc = rtems_termios_open( major, minor, arg, &mpc55xx_esci_termios_callbacks);
|
||||
} else {
|
||||
sc = rtems_termios_open( major, minor, arg, &mpc55xx_esci_termios_callbacks_polled);
|
||||
}
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
return sc;
|
||||
}
|
||||
rv = rtems_termios_set_initial_baud( e->tty, 115200);
|
||||
if (rv < 0) {
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_device_driver console_close( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
|
||||
{
|
||||
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
|
||||
|
||||
/* Check minor number */
|
||||
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
|
||||
if (e->use_termios) {
|
||||
return rtems_termios_close( arg);
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_device_driver console_read( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
|
||||
{
|
||||
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
|
||||
|
||||
/* Check minor number */
|
||||
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
|
||||
if (e->use_termios) {
|
||||
return rtems_termios_read( arg);
|
||||
} else {
|
||||
rtems_libio_rw_args_t *rw = (rtems_libio_rw_args_t *) arg;
|
||||
uint32_t i = 0;
|
||||
while (i < rw->count) {
|
||||
rw->buffer [i] = mpc55xx_esci_read_char( e);
|
||||
++i;
|
||||
}
|
||||
rw->bytes_moved = i;
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_device_driver console_write( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
|
||||
{
|
||||
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
|
||||
|
||||
/* Check minor number */
|
||||
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
|
||||
if (e->use_termios) {
|
||||
return rtems_termios_write( arg);
|
||||
} else {
|
||||
rtems_libio_rw_args_t *rw = (rtems_libio_rw_args_t *) arg;
|
||||
uint32_t i = 0;
|
||||
while (i < rw->count) {
|
||||
mpc55xx_esci_write_char( e, rw->buffer [i]);
|
||||
if (rw->buffer [i] == '\n') {
|
||||
mpc55xx_esci_write_char( e, '\r');
|
||||
}
|
||||
++i;
|
||||
}
|
||||
rw->bytes_moved = i;
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_device_driver console_control( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
|
||||
{
|
||||
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
|
||||
|
||||
/* Check minor number */
|
||||
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
|
||||
if (e->use_termios) {
|
||||
return rtems_termios_ioctl( arg);
|
||||
}
|
||||
|
||||
return RTEMS_NOT_DEFINED;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Port number for the BSP character output function.
|
||||
*
|
||||
* The correct value will be set by mpc55xx_esci_output_char_init().
|
||||
*/
|
||||
static unsigned mpc55xx_esci_output_char_minor = 0;
|
||||
|
||||
/**
|
||||
* @name BSP Character Output
|
||||
* @{
|
||||
*/
|
||||
|
||||
static void mpc55xx_esci_output_char( char c)
|
||||
{
|
||||
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [mpc55xx_esci_output_char_minor];
|
||||
mpc55xx_esci_write_char( e, c);
|
||||
if (c == '\n') {
|
||||
mpc55xx_esci_write_char( e, '\r');
|
||||
}
|
||||
}
|
||||
|
||||
static void mpc55xx_esci_output_char_nop( char c)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
static void mpc55xx_esci_output_char_init( char c)
|
||||
{
|
||||
int console_found = 0;
|
||||
unsigned i = 0;
|
||||
for (i = 0; i < MPC55XX_ESCI_NUMBER; ++i) {
|
||||
if (mpc55xx_esci_driver_table [i].console) {
|
||||
console_found = 1;
|
||||
mpc55xx_esci_output_char_minor = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (console_found) {
|
||||
BSP_output_char = mpc55xx_esci_output_char;
|
||||
mpc55xx_esci_termios_set_attributes( mpc55xx_esci_output_char_minor, &mpc55xx_esci_termios_default);
|
||||
mpc55xx_esci_output_char( c);
|
||||
} else {
|
||||
BSP_output_char = mpc55xx_esci_output_char_nop;
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = mpc55xx_esci_output_char_init;
|
||||
19
c/src/lib/libcpu/powerpc/mpc55xx/fec/fec.c
Normal file
19
c/src/lib/libcpu/powerpc/mpc55xx/fec/fec.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup mpc55xx
|
||||
*
|
||||
* @brief Device driver for the Fast Ethernet Controller
|
||||
*
|
||||
* @par Copyright
|
||||
* Copyright (c) 2008<br>
|
||||
* Embedded Brains GmbH<br>
|
||||
* Obere Lagerstr. 30<br>
|
||||
* D-82178 Puchheim<br>
|
||||
* Germany<br>
|
||||
* rtems@embedded-brains.de<br>
|
||||
*
|
||||
* @par 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.
|
||||
*/
|
||||
135
c/src/lib/libcpu/powerpc/mpc55xx/include/dspi.h
Normal file
135
c/src/lib/libcpu/powerpc/mpc55xx/include/dspi.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup mpc55xx_dspi
|
||||
*
|
||||
* @brief Header file for the LibI2C bus driver for the Deserial Serial Peripheral Interface (DSPI).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be found in the file
|
||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup mpc55xx_dspi Deserial Serial Peripheral Interface (DSPI)
|
||||
*
|
||||
* @ingroup mpc55xx
|
||||
*/
|
||||
|
||||
#ifndef LIBCPU_POWERPC_MPC55XX_DSPI_H
|
||||
#define LIBCPU_POWERPC_MPC55XX_DSPI_H
|
||||
|
||||
#include <rtems/libi2c.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
struct DSPI_tag;
|
||||
|
||||
/**
|
||||
* @brief LibI2C bus driver entry.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Standard bus driver fields.
|
||||
*/
|
||||
rtems_libi2c_bus_t bus;
|
||||
|
||||
/**
|
||||
* @brief Index in the bus table: @ref mpc55xx_dspi_bus_table.
|
||||
*/
|
||||
unsigned table_index;
|
||||
|
||||
/**
|
||||
* @brief Bus number (available after rtems_libi2c_register_bus()).
|
||||
*
|
||||
* @note You must set it in the initialization code after the bus registration.
|
||||
*/
|
||||
unsigned bus_number;
|
||||
|
||||
/**
|
||||
* @brief Hardware registers.
|
||||
*/
|
||||
volatile struct DSPI_tag *regs;
|
||||
|
||||
/**
|
||||
* @brief Selects SPI master or slave mode.
|
||||
*/
|
||||
int master;
|
||||
|
||||
/**
|
||||
* @brief Data for the Push Register.
|
||||
*/
|
||||
union DSPI_PUSHR_tag push_data;
|
||||
|
||||
/**
|
||||
* @brief eDMA channel for transmission.
|
||||
*
|
||||
* The channel is fixed to particular DSPI.
|
||||
*/
|
||||
int edma_channel_transmit;
|
||||
|
||||
/**
|
||||
* @brief eDMA channel to generate the push data.
|
||||
*
|
||||
* You can choose any available channel.
|
||||
*/
|
||||
int edma_channel_push;
|
||||
|
||||
/**
|
||||
* @brief eDMA channel for receiving.
|
||||
*
|
||||
* The channel is fixed to particular DSPI.
|
||||
*/
|
||||
int edma_channel_receive;
|
||||
|
||||
/**
|
||||
* @brief Semaphore ID for a transmit update.
|
||||
*/
|
||||
rtems_id edma_channel_transmit_update;
|
||||
|
||||
/**
|
||||
* @brief Semaphore ID for a receive update.
|
||||
*/
|
||||
rtems_id edma_channel_receive_update;
|
||||
|
||||
/**
|
||||
* @brief Transmit error status.
|
||||
*/
|
||||
uint32_t edma_channel_transmit_error;
|
||||
|
||||
/**
|
||||
* @brief Receive error status.
|
||||
*/
|
||||
uint32_t edma_channel_receive_error;
|
||||
|
||||
/**
|
||||
* @brief Idle character transmitted in read only mode.
|
||||
*/
|
||||
uint32_t idle_char;
|
||||
} mpc55xx_dspi_bus_entry;
|
||||
|
||||
/**
|
||||
* @brief Number of DSPIs.
|
||||
*/
|
||||
#define MPC55XX_DSPI_NUMBER 4
|
||||
|
||||
/**
|
||||
* @brief Table with bus driver entries.
|
||||
*/
|
||||
extern mpc55xx_dspi_bus_entry mpc55xx_dspi_bus_table [ /* MPC55XX_DSPI_NUMBER */ ];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* LIBCPU_POWERPC_MPC55XX_DSPI_H */
|
||||
102
c/src/lib/libcpu/powerpc/mpc55xx/include/edma.h
Normal file
102
c/src/lib/libcpu/powerpc/mpc55xx/include/edma.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup mpc55xx
|
||||
*
|
||||
* @brief Enhanced Direct Memory Access (eDMA).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be found in the file
|
||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifndef LIBCPU_POWERPC_MPC55XX_EDMA_H
|
||||
#define LIBCPU_POWERPC_MPC55XX_EDMA_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define MPC55XX_EDMA_TCD_DEFAULT { \
|
||||
.SADDR = 0, \
|
||||
.SMOD = 0, \
|
||||
.SSIZE = 0x2, \
|
||||
.SOFF = 4, \
|
||||
.DADDR = 0, \
|
||||
.DMOD = 0, \
|
||||
.DSIZE = 0x2, \
|
||||
.DOFF = 4, \
|
||||
.NBYTES = 0, \
|
||||
.SLAST = 0, \
|
||||
.CITER = 1, \
|
||||
.BITER = 1, \
|
||||
.MAJORLINKCH = 0, \
|
||||
.CITERE_LINK = 0, \
|
||||
.BITERE_LINK = 0, \
|
||||
.MAJORE_LINK = 0, \
|
||||
.E_SG = 0, \
|
||||
.DLAST_SGA = 0, \
|
||||
.D_REQ = 0, \
|
||||
.BWC = 0, \
|
||||
.INT_HALF = 0, \
|
||||
.INT_MAJ = 0, \
|
||||
.DONE = 0, \
|
||||
.ACTIVE = 0, \
|
||||
.START = 0, \
|
||||
}
|
||||
|
||||
#define MPC55XX_EDMA_TCD_ALT_DEFAULT { \
|
||||
.SADDR = 0, \
|
||||
.SMOD = 0, \
|
||||
.SSIZE = 2, \
|
||||
.DMOD = 0, \
|
||||
.DSIZE = 2, \
|
||||
.SOFF = 4, \
|
||||
.NBYTES = 0, \
|
||||
.SLAST = 0, \
|
||||
.DADDR = 0, \
|
||||
.CITERE_LINK = 0, \
|
||||
.CITERLINKCH = 0, \
|
||||
.CITER = 0, \
|
||||
.DOFF = 4, \
|
||||
.DLAST_SGA = 0, \
|
||||
.BITERE_LINK = 0, \
|
||||
.BITERLINKCH = 0, \
|
||||
.BITER = 0, \
|
||||
.BWC = 0, \
|
||||
.MAJORLINKCH = 0, \
|
||||
.DONE = 0, \
|
||||
.ACTIVE = 0, \
|
||||
.MAJORE_LINK = 0, \
|
||||
.E_SG = 0, \
|
||||
.D_REQ = 0, \
|
||||
.INT_HALF = 0, \
|
||||
.INT_MAJ = 0, \
|
||||
.START = 0, \
|
||||
}
|
||||
|
||||
rtems_status_code mpc55xx_edma_init();
|
||||
|
||||
rtems_status_code mpc55xx_edma_obtain_channel( int channel, uint32_t *error_status, rtems_id transfer_update);
|
||||
|
||||
rtems_status_code mpc55xx_edma_enable_hardware_requests( int channel, bool enable);
|
||||
|
||||
rtems_status_code mpc55xx_edma_enable_error_interrupts( int channel, bool enable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* LIBCPU_POWERPC_MPC55XX_EDMA_H */
|
||||
48
c/src/lib/libcpu/powerpc/mpc55xx/include/esci.h
Normal file
48
c/src/lib/libcpu/powerpc/mpc55xx/include/esci.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup mpc55xx_esci
|
||||
*
|
||||
* @brief Header file for the Enhanced Serial Communication Interface (eSCI).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be found in the file
|
||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup mpc55xx_esci Enhanced Serial Communication Interface (eSCI).
|
||||
*
|
||||
* @ingroup mpc55xx
|
||||
*/
|
||||
|
||||
#ifndef LIBCPU_POWERPC_MPC55XX_ESCI_H
|
||||
#define LIBCPU_POWERPC_MPC55XX_ESCI_H
|
||||
|
||||
#include <rtems/termiostypes.h>
|
||||
|
||||
#define MPC55XX_ESCI_NUMBER 2
|
||||
|
||||
struct ESCI_tag;
|
||||
|
||||
typedef struct {
|
||||
volatile struct ESCI_tag *regs;
|
||||
const char *device_name;
|
||||
int use_termios;
|
||||
int use_interrupts;
|
||||
int console;
|
||||
struct rtems_termios_tty *tty;
|
||||
unsigned irq_number;
|
||||
} mpc55xx_esci_driver_entry;
|
||||
|
||||
extern mpc55xx_esci_driver_entry mpc55xx_esci_driver_table [ /* MPC55XX_ESCI_NUMBER */ ];
|
||||
|
||||
#endif /* LIBCPU_POWERPC_MPC55XX_ESCI_H */
|
||||
92
c/src/lib/libcpu/powerpc/mpc55xx/include/irq.h
Normal file
92
c/src/lib/libcpu/powerpc/mpc55xx/include/irq.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup mpc55xx
|
||||
*
|
||||
* @brief IRQ
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be found in the file
|
||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifndef LIBBSP_POWERPC_IRQ_H
|
||||
#define LIBBSP_POWERPC_IRQ_H
|
||||
|
||||
#include <rtems/irq-extension.h>
|
||||
#include <rtems/irq.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Interrupt numbers
|
||||
*/
|
||||
|
||||
/* Basics */
|
||||
#define MPC55XX_IRQ_MIN 0
|
||||
#define MPC55XX_IRQ_MAX 328
|
||||
#define MPC55XX_IRQ_BASE MPC55XX_IRQ_MIN
|
||||
#define MPC55XX_IRQ_NUMBER (MPC55XX_IRQ_MAX + 1)
|
||||
|
||||
/* Software interrupts */
|
||||
#define MPC55XX_IRQ_SOFTWARE_MIN 0
|
||||
#define MPC55XX_IRQ_SOFTWARE_MAX 7
|
||||
#define MPC55XX_IRQ_SOFTWARE_NUMBER (MPC55XX_IRQ_SOFTWARE_MAX + 1)
|
||||
|
||||
/* eDMA interrupts */
|
||||
#define MPC55XX_IRQ_EDMA_ERROR_LOW 10
|
||||
#define MPC55XX_IRQ_EDMA_ERROR_HIGH 210
|
||||
#define MPC55XX_IRQ_EDMA_REQUEST_LOW_MIN 11
|
||||
#define MPC55XX_IRQ_EDMA_REQUEST_LOW_MAX 42
|
||||
#define MPC55XX_IRQ_EDMA_REQUEST_HIGH_MIN 211
|
||||
#define MPC55XX_IRQ_EDMA_REQUEST_HIGH_MAX 242
|
||||
#define MPC55XX_IRQ_EDMA_GET_CHANNEL( i) (((i) > MPC55XX_IRQ_EDMA_REQUEST_LOW_MAX) ? ((i) - MPC55XX_IRQ_EDMA_REQUEST_HIGH_MIN + 32) : ((i) - MPC55XX_IRQ_EDMA_REQUEST_LOW_MIN))
|
||||
#define MPC55XX_IRQ_EDMA_GET_REQUEST( c) (((c) > 31) ? ((c) + MPC55XX_IRQ_EDMA_REQUEST_HIGH_MIN - 32) : ((c) + MPC55XX_IRQ_EDMA_REQUEST_LOW_MIN))
|
||||
|
||||
/* Checks */
|
||||
#define MPC55XX_IRQ_IS_VALID(i) ((i) >= MPC55XX_IRQ_MIN && (i) <= MPC55XX_IRQ_MAX)
|
||||
#define MPC55XX_IRQ_IS_SOFTWARE(i) ((i) >= MPC55XX_IRQ_SOFTWARE_MIN && (i) <= MPC55XX_IRQ_SOFTWARE_MAX)
|
||||
|
||||
/*
|
||||
* Interrupt controller
|
||||
*/
|
||||
|
||||
#define MPC55XX_INTC_INVALID_PRIORITY -1
|
||||
#define MPC55XX_INTC_DISABLED_PRIORITY 0
|
||||
#define MPC55XX_INTC_MIN_PRIORITY 1
|
||||
#define MPC55XX_INTC_MAX_PRIORITY 15
|
||||
#define MPC55XX_INTC_DEFAULT_PRIORITY MPC55XX_INTC_MIN_PRIORITY
|
||||
#define MPC55XX_INTC_IS_VALID_PRIORITY(p) ((p) >= MPC55XX_INTC_DISABLED_PRIORITY && (p) <= MPC55XX_INTC_MAX_PRIORITY)
|
||||
|
||||
rtems_status_code mpc55xx_interrupt_handler_install(
|
||||
rtems_vector_number vector,
|
||||
int priority,
|
||||
const char *info,
|
||||
rtems_option options,
|
||||
rtems_interrupt_handler handler,
|
||||
void *arg
|
||||
);
|
||||
|
||||
rtems_status_code mpc55xx_intc_get_priority( int i, int *p);
|
||||
|
||||
rtems_status_code mpc55xx_intc_set_priority( int i, int p);
|
||||
|
||||
rtems_status_code mpc55xx_intc_raise_software_irq( int i);
|
||||
|
||||
rtems_status_code mpc55xx_intc_clear_software_irq( int i);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* LIBBSP_POWERPC_IRQ_H */
|
||||
111
c/src/lib/libcpu/powerpc/mpc55xx/include/mpc55xx.h
Normal file
111
c/src/lib/libcpu/powerpc/mpc55xx/include/mpc55xx.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup mpc55xx
|
||||
*
|
||||
* @brief Documentation for this file
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be found in the file
|
||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup mpc55xx BSP for MPC55xx boards
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup mpc55xx_config Configuration files
|
||||
*
|
||||
* @ingroup mpc55xx
|
||||
*
|
||||
* Makefiles, configure scripts etc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page mpc55xx_ext_doc External Documentation
|
||||
*
|
||||
* @section mpc55xx_ext_doc_mpc5567rm_1 MPC5567 Microcontroller Reference Manual (Rev. 1, January 2007, Volume 1 of 2)
|
||||
* @section mpc55xx_ext_doc_mpc5567rm_2 MPC5567 Microcontroller Reference Manual (Rev. 1, January 2007, Volume 2 of 2)
|
||||
*/
|
||||
|
||||
#ifndef LIBCPU_POWERPC_MPC55XX_H
|
||||
#define LIBCPU_POWERPC_MPC55XX_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Defined in copy.S */
|
||||
int mpc55xx_copy_8( const void *src, void *dest, size_t n);
|
||||
|
||||
/* Defined in copy.S */
|
||||
int mpc55xx_zero_8( void *dest, size_t n);
|
||||
|
||||
/* Defined in copy.S */
|
||||
int mpc55xx_zero_32( void *dest, size_t n);
|
||||
|
||||
/* Defined in fmpll.S */
|
||||
void mpc55xx_fmpll_reset_config();
|
||||
|
||||
/* Defined in fmpll.S */
|
||||
void mpc55xx_fmpll_wait_for_lock();
|
||||
|
||||
/* Defined in fmpll.S */
|
||||
int mpc55xx_get_system_clock();
|
||||
|
||||
/* Defined in fmpll.S */
|
||||
void mpc55xx_system_reset();
|
||||
|
||||
/* Defined in flash.S */
|
||||
void mpc55xx_flash_config();
|
||||
|
||||
#define MPC55XX_CACHE_ALIGNED_MASK ((uintptr_t) 0x1f)
|
||||
|
||||
#define MPC55XX_CACHE_LINE_SIZE 32
|
||||
|
||||
/**
|
||||
* @brief Returns true if the buffer starting at @a s of size @a n is cache aligned.
|
||||
*/
|
||||
static inline int mpc55xx_is_cache_aligned( const void *s, size_t n)
|
||||
{
|
||||
return !(((uintptr_t) s & MPC55XX_CACHE_ALIGNED_MASK) || (n & MPC55XX_CACHE_ALIGNED_MASK));
|
||||
}
|
||||
|
||||
static inline void* mpc55xx_cache_aligned_start( const void *s)
|
||||
{
|
||||
return ((uintptr_t) s & MPC55XX_CACHE_ALIGNED_MASK) ? (((uintptr_t) s & ~MPC55XX_CACHE_ALIGNED_MASK) + MPC55XX_CACHE_LINE_SIZE) : s;
|
||||
}
|
||||
|
||||
static inline size_t mpc55xx_non_cache_aligned_size( const void *s)
|
||||
{
|
||||
return (uintptr_t) mpc55xx_cache_aligned_start( s) - (uintptr_t) s;
|
||||
}
|
||||
|
||||
static inline size_t mpc55xx_cache_aligned_size( const void *s, size_t n)
|
||||
{
|
||||
return (n - mpc55xx_non_cache_aligned_size( s)) & ~MPC55XX_CACHE_ALIGNED_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of leading zeros.
|
||||
*/
|
||||
static inline uint32_t mpc55xx_count_leading_zeros( uint32_t value)
|
||||
{
|
||||
uint32_t count;
|
||||
asm (
|
||||
"cntlzw %0, %1;"
|
||||
: "=r" (count)
|
||||
: "r" (value)
|
||||
);
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif /* LIBCPU_POWERPC_MPC55XX_H */
|
||||
193
c/src/lib/libcpu/powerpc/mpc55xx/include/reg-defs.h
Normal file
193
c/src/lib/libcpu/powerpc/mpc55xx/include/reg-defs.h
Normal file
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup mpc55xx
|
||||
*
|
||||
* @brief Register definitions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be found in the file
|
||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifndef LIBCPU_POWERPC_MPC55XX_REG_DEFS_H
|
||||
#define LIBCPU_POWERPC_MPC55XX_REG_DEFS_H
|
||||
|
||||
/*
|
||||
* Register addresses
|
||||
*/
|
||||
|
||||
#define FMPLL_SYNCR 0xC3F80000
|
||||
#define FMPLL_SYNSR 0xC3F80004
|
||||
#define FLASH_BIUCR 0xC3F8801C
|
||||
#define SIU_ECCR 0xC3F90984
|
||||
#define SIU_SRCR 0xC3F90010
|
||||
|
||||
/*
|
||||
* Special purpose registers
|
||||
*/
|
||||
|
||||
#define BUCSR 1013
|
||||
|
||||
/*
|
||||
* Branch Unit Control and Status Register (BUCSR)
|
||||
*/
|
||||
|
||||
#define BUCSR_BBFI 0x00000200
|
||||
#define BUCSR_BPEN 0x00000001
|
||||
|
||||
/*
|
||||
* Definitions for FMPLL_SYNCR (FMPLL Synthesizer Control Register)
|
||||
*/
|
||||
|
||||
/* Fields used for PREDIV (Pre-Divider bits [1:3]) */
|
||||
#define FMPLL_SYNCR_PREDIV_0 0x00000000
|
||||
|
||||
/* Fields used for MFD (Muliplication Factor Divider bits [4:8]) */
|
||||
#define FMPLL_SYNCR_MFD_0 0x00000000
|
||||
#define FMPLL_SYNCR_MFD_2 0x01000000
|
||||
#define FMPLL_SYNCR_MFD_4 0x02000000
|
||||
#define FMPLL_SYNCR_MFD_6 0x03000000
|
||||
#define FMPLL_SYNCR_MFD_8 0x04000000
|
||||
#define FMPLL_SYNCR_MFD_10 0x05000000
|
||||
#define FMPLL_SYNCR_MFD_12 0x06000000
|
||||
|
||||
/* Fields used for RFD (Reduced Frequency Divider bits [10:12]) */
|
||||
#define FMPLL_SYNCR_RFD_0 0x00000000
|
||||
#define FMPLL_SYNCR_RFD_1 0x00080000
|
||||
#define FMPLL_SYNCR_RFD_2 0x00100000
|
||||
#define FMPLL_SYNCR_RFD_3 0x00180000
|
||||
#define FMPLL_SYNCR_RFD_4 0x00200000
|
||||
#define FMPLL_SYNCR_RFD_5 0x00280000
|
||||
#define FMPLL_SYNCR_RFD_6 0x00300000
|
||||
#define FMPLL_SYNCR_RFD_7 0x00380000
|
||||
|
||||
/* Fields for LOCEN (Loss-of-clock enable bit [13]) */
|
||||
#define FMPLL_SYNCR_LOCEN 0x00040000
|
||||
|
||||
/* Fields for LOLRE (Loss-of-lock reset enable bit [14]) */
|
||||
#define FMPLL_SYNCR_LOLRE 0x00020000
|
||||
|
||||
/* Fields for LOCRE (Loss-of-clock reset enable bit [15]) */
|
||||
#define FMPLL_SYNCR_LOCRE 0x00010000
|
||||
|
||||
/* Fields for DISCLK (Disable CLKOUT bit [16]) */
|
||||
#define FMPLL_SYNCR_DISCLK 0x00008000
|
||||
|
||||
/* Fields for LOLIRQ (Loss-of-lock interrupt request bit [17]) */
|
||||
#define FMPLL_SYNCR_LOLIRQ 0x00004000
|
||||
|
||||
/* Fields for LOCIRQ (Loss-of-clock interrupt request bit [18]) */
|
||||
#define FMPLL_SYNCR_LOCIRQ 0x00002000
|
||||
|
||||
/* Fields for RATE (Modulation rate bit [19]) */
|
||||
#define FMPLL_SYNCR_RATE_FREF 0x00001000
|
||||
|
||||
/* Fields for DEPTH (Modulation depth percentage bits [20:21]) */
|
||||
#define FMPLL_SYNCR_DEPTH_0 0x00000000
|
||||
#define FMPLL_SYNCR_DEPTH_1 0x00000400
|
||||
#define FMPLL_SYNCR_DEPTH_2 0x00000800
|
||||
|
||||
/* Fields for EXP (Expected difference bits [22:31]) */
|
||||
#define FMPLL_SYNCR_EXP_0 0x00000000
|
||||
|
||||
/*
|
||||
* Definitions for the FMPLL_SYNSR (Synthesizer Status Register)
|
||||
*/
|
||||
|
||||
/* Fields for LOLF (Loss-of-lock flag bit [22]) */
|
||||
#define FMPLL_SYNSR_LOLF 0x00000200
|
||||
|
||||
/* Fields for LOCK (Lock status bit [28]) */
|
||||
#define FMPLL_SYNSR_LOCK 0x00000008
|
||||
|
||||
/* Fields for LOCF (Loss-of-clock flag bit [29]) */
|
||||
#define FMPLL_SYNSR_LOCF 0x00000004
|
||||
|
||||
/*
|
||||
* Definitions for the SIU_SRCR (System Reset Control Register)
|
||||
*/
|
||||
|
||||
/* Fields for SSR (software system reset bit [0]) */
|
||||
#define SIU_SRCR_SSR 0x80000000
|
||||
|
||||
/* Fields for SER (external system reset bit [1]) */
|
||||
#define SIU_SRCR_SER 0x40000000
|
||||
|
||||
/* Fields for CRE (checkstop reset enable bit [16]) */
|
||||
#define SIU_SRCR_CRE 0x00008000
|
||||
|
||||
/*
|
||||
* Definitions for FLASH_BIUCR (Flash BIU Control Register)
|
||||
*/
|
||||
|
||||
/* Fields for Flash Bus Interface Control */
|
||||
/* Fields for Prefetch Control (MnPFE Master n Prefetch Enable) */
|
||||
|
||||
/* Fields for M3PFE (Master 3 (EBI) prefetch enable bit [12]) */
|
||||
#define FLASH_BUICR_EBI_PREFTCH 0x00080000
|
||||
|
||||
/* Fields for M2PFE (Master 2 (eDMA) prefetch enable bit [13]) */
|
||||
#define FLASH_BUICR_EDMA_PREFTCH 0x00040000
|
||||
|
||||
/* Fields for M1PFE (Master 1 (Nexus) prefetch enable bit [14]) */
|
||||
#define FLASH_BUICR_NEX_PREFTCH 0x00020000
|
||||
|
||||
/* Fields for M0PFE (Master 0 (e200z core) prefetch enable bit [15]) */
|
||||
#define FLASH_BUICR_CPU_PREFTCH 0x00010000
|
||||
|
||||
/* Fields for APC (access pipelining control bits [16:18]) */
|
||||
#define FLASH_BUICR_APC_1 0x00002000
|
||||
#define FLASH_BUICR_APC_2 0x00004000
|
||||
#define FLASH_BUICR_APC_3 0x00006000
|
||||
#define FLASH_BUICR_APC_4 0x00008000
|
||||
#define FLASH_BUICR_APC_5 0x0000A000
|
||||
#define FLASH_BUICR_APC_6 0x0000C000
|
||||
#define FLASH_BUICR_APC_NO 0x0000E000
|
||||
|
||||
/* Fields for WWSC (write wait state control bits [19:20]) */
|
||||
#define FLASH_BUICR_WWSC_1 0x00000800
|
||||
#define FLASH_BUICR_WWSC_2 0x00001000
|
||||
#define FLASH_BUICR_WWSC_3 0x00001800
|
||||
|
||||
/* Fields for RWSC (read wait state control bits [21:23]) */
|
||||
#define FLASH_BUICR_RWSC_0 0x00000000
|
||||
#define FLASH_BUICR_RWSC_1 0x00000100
|
||||
#define FLASH_BUICR_RWSC_2 0x00000200
|
||||
#define FLASH_BUICR_RWSC_3 0x00000300
|
||||
#define FLASH_BUICR_RWSC_4 0x00000400
|
||||
#define FLASH_BUICR_RWSC_5 0x00000500
|
||||
#define FLASH_BUICR_RWSC_6 0x00000600
|
||||
#define FLASH_BUICR_RWSC_7 0x00000700
|
||||
|
||||
/* Fields for DPFEN (data prefetch enable bits [24:25]) */
|
||||
#define FLASH_BUICR_DPFEN_0 0x00000000
|
||||
#define FLASH_BUICR_DPFEN_1 0x00000040
|
||||
#define FLASH_BUICR_DPFEN_3 0x000000C0
|
||||
|
||||
/* Fields for IPFEN (instruction prefetch enable bits [26:27]) */
|
||||
#define FLASH_BUICR_IPFEN_0 0x00000000
|
||||
#define FLASH_BUICR_IPFEN_1 0x00000010
|
||||
#define FLASH_BUICR_IPFEN_3 0x00000030
|
||||
|
||||
/* Fields for PFLIM (additional line prefetch (limit) bits [28:30]) */
|
||||
#define FLASH_BUICR_PFLIM_0 0x00000000
|
||||
#define FLASH_BUICR_PFLIM_1 0x00000002
|
||||
#define FLASH_BUICR_PFLIM_2 0x00000004
|
||||
#define FLASH_BUICR_PFLIM_3 0x00000006
|
||||
#define FLASH_BUICR_PFLIM_4 0x00000008
|
||||
#define FLASH_BUICR_PFLIM_5 0x0000000A
|
||||
#define FLASH_BUICR_PFLIM_6 0x0000000C
|
||||
|
||||
/* Fields for BFEN (enable line read buffer hits bit [31]) */
|
||||
#define FLASH_BUICR_BFEN 0x00000001
|
||||
|
||||
#endif /* LIBCPU_POWERPC_MPC55XX_REG_DEFS_H */
|
||||
4337
c/src/lib/libcpu/powerpc/mpc55xx/include/regs.h
Normal file
4337
c/src/lib/libcpu/powerpc/mpc55xx/include/regs.h
Normal file
File diff suppressed because it is too large
Load Diff
179
c/src/lib/libcpu/powerpc/mpc55xx/irq/irq.c
Normal file
179
c/src/lib/libcpu/powerpc/mpc55xx/irq/irq.c
Normal file
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup mpc55xx
|
||||
*
|
||||
* @brief Source file for MPC55XX interrupt support.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be found in the file
|
||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <mpc55xx/regs.h>
|
||||
|
||||
#include <libcpu/raw_exception.h>
|
||||
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/irq-generic.h>
|
||||
#include <bsp/ppc_exc_bspsupp.h>
|
||||
|
||||
#define RTEMS_STATUS_CHECKS_USE_PRINTK
|
||||
|
||||
#include <rtems/status-checks.h>
|
||||
|
||||
/**
|
||||
* @brief Returns the priority @a p of IRQ @a i from the INTC.
|
||||
*/
|
||||
rtems_status_code mpc55xx_intc_get_priority( int i, int *p)
|
||||
{
|
||||
if (MPC55XX_IRQ_IS_VALID( i)) {
|
||||
*p = INTC.PSR [i].B.PRI;
|
||||
return RTEMS_SUCCESSFUL;
|
||||
} else {
|
||||
*p = MPC55XX_INTC_INVALID_PRIORITY;
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the priority of IRQ @a i to @a p at the INTC.
|
||||
*/
|
||||
rtems_status_code mpc55xx_intc_set_priority( int i, int p)
|
||||
{
|
||||
if (MPC55XX_IRQ_IS_VALID( i) && MPC55XX_INTC_IS_VALID_PRIORITY( p)) {
|
||||
INTC.PSR [i].B.PRI = p;
|
||||
if (INTC.PSR [i].B.PRI == p) {
|
||||
return RTEMS_SUCCESSFUL;
|
||||
} else {
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
} else {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Raises the software IRQ with number @a i.
|
||||
*/
|
||||
rtems_status_code mpc55xx_intc_raise_software_irq( int i)
|
||||
{
|
||||
if (MPC55XX_IRQ_IS_SOFTWARE( i)) {
|
||||
INTC.SSCIR [i].B.SET = 1;
|
||||
return RTEMS_SUCCESSFUL;
|
||||
} else {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears the software IRQ with number @a i.
|
||||
*/
|
||||
rtems_status_code mpc55xx_intc_clear_software_irq( int i)
|
||||
{
|
||||
if (MPC55XX_IRQ_IS_SOFTWARE( i)) {
|
||||
INTC.SSCIR [i].B.CLR = 1;
|
||||
return RTEMS_SUCCESSFUL;
|
||||
} else {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Installs interrupt handler and sets priority.
|
||||
*/
|
||||
rtems_status_code mpc55xx_interrupt_handler_install(
|
||||
rtems_vector_number vector,
|
||||
int priority,
|
||||
const char *info,
|
||||
rtems_option options,
|
||||
rtems_interrupt_handler handler,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
|
||||
if (MPC55XX_IRQ_IS_VALID( vector) && MPC55XX_INTC_IS_VALID_PRIORITY( priority)) {
|
||||
sc = rtems_interrupt_handler_install( vector, info, options, handler, arg);
|
||||
CHECK_SC( sc, "Install interrupt handler");
|
||||
return mpc55xx_intc_set_priority( vector, priority);
|
||||
} else {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief External exception handler.
|
||||
*/
|
||||
static int mpc55xx_external_exception_handler( BSP_Exception_frame *frame, unsigned exception_number)
|
||||
{
|
||||
/* Acknowlege interrupt request */
|
||||
rtems_vector_number vector_number = INTC.IACKR.B.INTVEC;
|
||||
|
||||
/* Save current interrupt level */
|
||||
uint32_t level = _ISR_Get_level();
|
||||
|
||||
/* Enable all interrupts */
|
||||
_ISR_Set_level( 0);
|
||||
|
||||
/* Dispatch interrupt handlers */
|
||||
bsp_interrupt_handler_dispatch( vector_number);
|
||||
|
||||
/* Restore interrupt level */
|
||||
_ISR_Set_level( level);
|
||||
|
||||
/* End of interrupt */
|
||||
INTC.EOIR.R = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
rtems_status_code bsp_interrupt_facility_initialize()
|
||||
{
|
||||
/* Install exception handler */
|
||||
if (ppc_exc_set_handler( ASM_EXT_VECTOR, mpc55xx_external_exception_handler)) {
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
|
||||
/* Initialize interrupt controller */
|
||||
|
||||
/* Software vector mode */
|
||||
INTC.MCR.B.VTES = 0;
|
||||
INTC.MCR.B.HVEN = 0;
|
||||
|
||||
/* Set current priority to 0 */
|
||||
INTC.CPR.B.PRI = 0;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number vector)
|
||||
{
|
||||
if (MPC55XX_IRQ_IS_VALID( vector)) {
|
||||
return mpc55xx_intc_set_priority( vector, MPC55XX_INTC_DEFAULT_PRIORITY);
|
||||
} else {
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number vector)
|
||||
{
|
||||
if (MPC55XX_IRQ_IS_VALID( vector)) {
|
||||
return mpc55xx_intc_set_priority( vector, MPC55XX_INTC_DISABLED_PRIORITY);
|
||||
} else {
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
void bsp_interrupt_handler_default( rtems_vector_number vector)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
150
c/src/lib/libcpu/powerpc/mpc55xx/misc/copy.S
Normal file
150
c/src/lib/libcpu/powerpc/mpc55xx/misc/copy.S
Normal file
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup mpc55xx_asm
|
||||
*
|
||||
* @brief Memory copy and zero functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be found in the file
|
||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <libcpu/powerpc-utility.h>
|
||||
|
||||
.section ".text"
|
||||
|
||||
/**
|
||||
* @fn int mpc55xx_copy_8( const void *src, void *dest, size_t n)
|
||||
*
|
||||
* @brief Copy @a n bytes from @a src to @a dest with 8 byte reads and writes.
|
||||
*
|
||||
* The memory areas should not overlap. The addresses @a src and @a dest have
|
||||
* to be aligned on 8 byte boundaries. The size @a n must be evenly divisible by 8.
|
||||
* The SPE operations @b evxor, @b evlddx and @b evstddx will be used.
|
||||
*/
|
||||
GLOBAL_FUNCTION mpc55xx_copy_8
|
||||
/* Loop counter = data size / 8 */
|
||||
srwi. r5, r5, 3
|
||||
beqlr
|
||||
mtctr r5
|
||||
|
||||
/* Set offset */
|
||||
evxor r5, r5, r5
|
||||
|
||||
copy_data:
|
||||
evlddx r6, r3, r5
|
||||
evstddx r6, r4, r5
|
||||
addi r5, r5, 8
|
||||
bdnz copy_data
|
||||
|
||||
/* Return */
|
||||
blr
|
||||
|
||||
/**
|
||||
* @fn int mpc55xx_zero_8( void *dest, size_t n)
|
||||
*
|
||||
* @brief Zero all @a n bytes starting at @a dest with 8 byte writes.
|
||||
*
|
||||
* The address @a dest has to be aligned on 8 byte boundaries. The size @a n
|
||||
* must be evenly divisible by 8. The SPE operations @b evxor and @b evstddx will be used.
|
||||
*/
|
||||
GLOBAL_FUNCTION mpc55xx_zero_8
|
||||
/* Create zero */
|
||||
evxor r0, r0, r0
|
||||
|
||||
/* Set offset */
|
||||
evxor r5, r5, r5
|
||||
|
||||
/* Loop counter for the first bytes up to 32 bytes */
|
||||
rlwinm. r9, r4, 29, 30, 31
|
||||
beq zero_more
|
||||
mtctr r9
|
||||
|
||||
zero_data:
|
||||
evstddx r0, r3, r5
|
||||
addi r5, r5, 8
|
||||
bdnz zero_data
|
||||
|
||||
zero_more:
|
||||
/* More than 32 bytes? */
|
||||
srwi. r9, r4, 5
|
||||
beqlr
|
||||
mtctr r9
|
||||
|
||||
/* Set offsets */
|
||||
addi r6, r5, 8
|
||||
addi r7, r5, 16
|
||||
addi r8, r5, 24
|
||||
|
||||
zero_big_data:
|
||||
evstddx r0, r3, r5
|
||||
addi r5, r5, 32
|
||||
evstddx r0, r3, r6
|
||||
addi r6, r6, 32
|
||||
evstddx r0, r3, r7
|
||||
addi r7, r7, 32
|
||||
evstddx r0, r3, r8
|
||||
addi r8, r8, 32
|
||||
bdnz zero_big_data
|
||||
|
||||
/* Return */
|
||||
blr
|
||||
|
||||
/**
|
||||
* @fn int mpc55xx_zero_32( void *dest, size_t n)
|
||||
*
|
||||
* @brief Zero all @a n bytes starting at @a dest with 32 byte writes.
|
||||
*
|
||||
* The address @a dest has to be aligned on 32 byte boundaries. The size @a n
|
||||
* must be evenly divisible by 32. The function operates with the cache block zero
|
||||
* operation @b dcbz.
|
||||
*
|
||||
* @note The cache has to be enabled for the desired memory area.
|
||||
*/
|
||||
GLOBAL_FUNCTION mpc55xx_zero_32
|
||||
/* Set offset */
|
||||
xor r5, r5, r5
|
||||
|
||||
/* Loop counter for the first bytes up to 128 bytes */
|
||||
rlwinm. r9, r4, 27, 28, 31
|
||||
beq zero_more_lines
|
||||
mtctr r9
|
||||
|
||||
zero_line:
|
||||
dcbz r3, r5
|
||||
addi r5, r5, 32
|
||||
bdnz zero_line
|
||||
|
||||
zero_more_lines:
|
||||
/* More than 128 bytes? */
|
||||
srwi. r9, r4, 7
|
||||
beqlr
|
||||
mtctr r9
|
||||
|
||||
/* Set offsets */
|
||||
addi r6, r5, 32
|
||||
addi r7, r5, 64
|
||||
addi r8, r5, 96
|
||||
|
||||
zero_big_line:
|
||||
dcbz r3, r5
|
||||
addi r5, r5, 128
|
||||
dcbz r3, r6
|
||||
addi r6, r6, 128
|
||||
dcbz r3, r7
|
||||
addi r7, r7, 128
|
||||
dcbz r3, r8
|
||||
addi r8, r8, 128
|
||||
bdnz zero_big_line
|
||||
|
||||
/* Return */
|
||||
blr
|
||||
101
c/src/lib/libcpu/powerpc/mpc55xx/misc/flash.S
Normal file
101
c/src/lib/libcpu/powerpc/mpc55xx/misc/flash.S
Normal file
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup mpc55xx_asm
|
||||
*
|
||||
* @brief Flash configuration.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be found in the file
|
||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <libcpu/powerpc-utility.h>
|
||||
#include <mpc55xx/reg-defs.h>
|
||||
|
||||
.section ".text"
|
||||
|
||||
/* Optimized flash configurations (Table 13-15 [MPC5567 Microcontroller Reference Manual]) */
|
||||
.equ FLASH_SETTINGS_RESET, 0xff00
|
||||
.equ FLASH_SETTINGS_82, FLASH_BUICR_CPU_PREFTCH | FLASH_BUICR_APC_1 | FLASH_BUICR_RWSC_1 | FLASH_BUICR_WWSC_1 | FLASH_BUICR_DPFEN_3 | FLASH_BUICR_IPFEN_3 | FLASH_BUICR_PFLIM_6 | FLASH_BUICR_BFEN
|
||||
.equ FLASH_SETTINGS_102, FLASH_BUICR_CPU_PREFTCH | FLASH_BUICR_APC_1 | FLASH_BUICR_RWSC_2 | FLASH_BUICR_WWSC_1 | FLASH_BUICR_DPFEN_3 | FLASH_BUICR_IPFEN_3 | FLASH_BUICR_PFLIM_6 | FLASH_BUICR_BFEN
|
||||
.equ FLASH_SETTINGS_132, FLASH_BUICR_CPU_PREFTCH | FLASH_BUICR_APC_2 | FLASH_BUICR_RWSC_3 | FLASH_BUICR_WWSC_1 | FLASH_BUICR_DPFEN_3 | FLASH_BUICR_IPFEN_3 | FLASH_BUICR_PFLIM_6 | FLASH_BUICR_BFEN
|
||||
|
||||
/**
|
||||
* @fn void mpc55xx_flash_config()
|
||||
* @brief Optimized flash configuration.
|
||||
* @warning Code will be copied and executed on the stack. The stack pointer
|
||||
* will not be updated, since this function has to work before memory
|
||||
* initialization.
|
||||
*/
|
||||
GLOBAL_FUNCTION mpc55xx_flash_config
|
||||
mflr r31
|
||||
|
||||
/* Flash settings dependent on system clock */
|
||||
bl mpc55xx_get_system_clock
|
||||
LWI r4, 82000000
|
||||
cmpw r3, r4
|
||||
ble clock_82
|
||||
LWI r4, 102000000
|
||||
cmpw r3, r4
|
||||
ble clock_102
|
||||
LWI r4, 132000000
|
||||
cmpw r3, r4
|
||||
ble clock_132
|
||||
LWI r30, FLASH_SETTINGS_RESET
|
||||
b settings_done
|
||||
clock_82:
|
||||
LWI r30, FLASH_SETTINGS_82
|
||||
b settings_done
|
||||
clock_102:
|
||||
LWI r30, FLASH_SETTINGS_102
|
||||
b settings_done
|
||||
clock_132:
|
||||
LWI r30, FLASH_SETTINGS_132
|
||||
b settings_done
|
||||
settings_done:
|
||||
|
||||
/* Copy store code on the stack */
|
||||
LA r3, store_start
|
||||
LA r5, store_end
|
||||
subf r5, r3, r5
|
||||
subf r4, r5, r1
|
||||
|
||||
/* Assert: Proper alignment of destination start */
|
||||
andi. r6, r4, 0x7
|
||||
bne twiddle
|
||||
|
||||
/* Copy */
|
||||
bl mpc55xx_copy_8
|
||||
|
||||
LA r6, FLASH_BIUCR
|
||||
|
||||
/* Execute store code */
|
||||
mtctr r4
|
||||
bctrl
|
||||
|
||||
mtlr r31
|
||||
blr
|
||||
|
||||
/*
|
||||
* Store flash settings
|
||||
*/
|
||||
|
||||
.align 3
|
||||
.set store_start, .
|
||||
stw r30, 0(r6)
|
||||
isync
|
||||
blr
|
||||
.align 3
|
||||
.set store_end, .
|
||||
|
||||
twiddle:
|
||||
b twiddle
|
||||
133
c/src/lib/libcpu/powerpc/mpc55xx/misc/fmpll.S
Normal file
133
c/src/lib/libcpu/powerpc/mpc55xx/misc/fmpll.S
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup mpc55xx_asm
|
||||
*
|
||||
* @brief FMPLL setup.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be found in the file
|
||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <libcpu/powerpc-utility.h>
|
||||
#include <mpc55xx/reg-defs.h>
|
||||
|
||||
.section ".text"
|
||||
|
||||
/* Timeout for delay in clocks */
|
||||
.equ FMPLL_TIMEOUT, 6000
|
||||
|
||||
/* Reference clock */
|
||||
.equ FMPLL_REF_CLOCK, 8000000
|
||||
|
||||
/* Settings for FMPLL from 12 MHz up to 128 MHz with 8 MHz reference frequency */
|
||||
.equ FMPLL_128_8_SYNCR_SETTING_0, (FMPLL_SYNCR_PREDIV_0 | FMPLL_SYNCR_MFD_12 | FMPLL_SYNCR_RFD_2 | FMPLL_SYNCR_LOCEN)
|
||||
.equ FMPLL_128_8_SYNCR_SETTING_1, (FMPLL_SYNCR_PREDIV_0 | FMPLL_SYNCR_MFD_12 | FMPLL_SYNCR_RFD_0 | FMPLL_SYNCR_LOCEN)
|
||||
|
||||
.macro DO_SETTING setting
|
||||
LWI r5, FMPLL_128_8_SYNCR_SETTING_\setting
|
||||
stw r5, 0(r4)
|
||||
msync
|
||||
bl mpc55xx_fmpll_wait_for_lock
|
||||
.endm
|
||||
|
||||
/**
|
||||
* @fn void mpc55xx_fmpll_reset_config()
|
||||
* @brief Configure FMPLL after reset.
|
||||
*
|
||||
* Sets the system clock from 12 MHz in two steps up to 128 MHz.
|
||||
*/
|
||||
GLOBAL_FUNCTION mpc55xx_fmpll_reset_config
|
||||
/* Save link register */
|
||||
mflr r3
|
||||
|
||||
LA r4, FMPLL_SYNCR
|
||||
|
||||
DO_SETTING 0
|
||||
DO_SETTING 1
|
||||
|
||||
/* Enable loss-of-clock and loss-of-lock IRQs */
|
||||
lwz r5, 0(r4)
|
||||
LWI r6, FMPLL_SYNCR_LOCIRQ | FMPLL_SYNCR_LOLIRQ
|
||||
or r5, r5, r6
|
||||
|
||||
/* Disable loss-of-clock and loss-of-lock resets */
|
||||
LWI r6, ~FMPLL_SYNCR_LOCRE & ~FMPLL_SYNCR_LOLRE
|
||||
and r5, r5, r6
|
||||
stw r5, 0(r4)
|
||||
|
||||
/* Restore link register and return */
|
||||
mtlr r3
|
||||
blr
|
||||
|
||||
/**
|
||||
* @fn void mpc55xx_fmpll_wait_for_lock()
|
||||
* @brief Wait for FMPLL lock.
|
||||
* @warning If the lock cannot be obtained within some clock cycles a software
|
||||
* system reset will be initiated.
|
||||
*/
|
||||
GLOBAL_FUNCTION mpc55xx_fmpll_wait_for_lock
|
||||
LWI r6, FMPLL_TIMEOUT
|
||||
mtctr r6
|
||||
|
||||
LWI r7, FMPLL_SYNSR_LOCK
|
||||
|
||||
LA r6, FMPLL_SYNSR
|
||||
|
||||
fmpll_not_locked:
|
||||
bdnz fmpll_continue
|
||||
|
||||
b mpc55xx_system_reset
|
||||
fmpll_continue:
|
||||
lwz r8, 0(r6)
|
||||
and. r8, r8, r7
|
||||
beq fmpll_not_locked
|
||||
|
||||
blr
|
||||
|
||||
/**
|
||||
* @fn int mpc55xx_get_system_clock()
|
||||
* @brief Returns the system clock.
|
||||
*/
|
||||
GLOBAL_FUNCTION mpc55xx_get_system_clock
|
||||
LA r4, FMPLL_SYNCR
|
||||
lwz r3, 0(r4)
|
||||
|
||||
/* PREDIV */
|
||||
rlwinm r5, r3, 4, 29, 31
|
||||
|
||||
/* MFD */
|
||||
rlwinm r6, r3, 9, 27, 31
|
||||
|
||||
/* RFD */
|
||||
rlwinm r7, r3, 13, 29, 31
|
||||
|
||||
/* Calculate system clock (Table 11-10 [MPC5567 Microcontroller Reference Manual]) */
|
||||
LWI r8, FMPLL_REF_CLOCK
|
||||
addi r5, r5, 1
|
||||
addi r6, r6, 4
|
||||
mullw r6, r6, r8
|
||||
sraw r6, r6, r7
|
||||
divw r3, r6, r5
|
||||
|
||||
blr
|
||||
|
||||
/**
|
||||
* @fn void mpc55xx_system_reset()
|
||||
* @brief Software system reset.
|
||||
*/
|
||||
GLOBAL_FUNCTION mpc55xx_system_reset
|
||||
LA r8, SIU_SRCR
|
||||
LWI r9, SIU_SRCR_SSR
|
||||
stw r9, 0(r8)
|
||||
twiddle:
|
||||
b twiddle
|
||||
274
c/src/lib/libcpu/powerpc/mpc83xx/gtm/gtm.c
Normal file
274
c/src/lib/libcpu/powerpc/mpc83xx/gtm/gtm.c
Normal file
@@ -0,0 +1,274 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief Source file for timer functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be found in the file
|
||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#include <mpc83xx/mpc83xx.h>
|
||||
#include <mpc83xx/gtm.h>
|
||||
|
||||
#define RTEMS_STATUS_CHECKS_USE_PRINTK
|
||||
|
||||
#include <rtems/status-checks.h>
|
||||
|
||||
#define MPC83XX_GTM_CHECK_INDEX( timer) \
|
||||
if (( timer) < 0 || ( timer) >= MPC83XX_GTM_NUMBER) { \
|
||||
return RTEMS_INVALID_NUMBER; \
|
||||
}
|
||||
|
||||
#define MPC83XX_GTM_VARIABLES( timer) \
|
||||
int module = (timer) / 4; \
|
||||
int module_timer = (timer) % 4; \
|
||||
int high = module_timer / 2; \
|
||||
int low = module_timer % 2; \
|
||||
rtems_interrupt_level level;
|
||||
|
||||
#define MPC83XX_GTM_CLOCK_MASK MPC83XX_GTM_CLOCK_EXTERN
|
||||
|
||||
static const uint8_t mpc83xx_gmt_interrupt_vector_table [MPC83XX_GTM_NUMBER] = { 90, 78, 84, 72, 91, 79, 85, 73 };
|
||||
|
||||
static const uint8_t mpc83xx_gmt_interrupt_priority_table [MPC83XX_GTM_NUMBER] = { 113, 77, 95, 59, 116, 80, 98, 62 };
|
||||
|
||||
rtems_status_code mpc83xx_gtm_initialize( int timer, int clock)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
|
||||
MPC83XX_GTM_VARIABLES( timer);
|
||||
|
||||
uint8_t mask = 0xf << (low * 4);
|
||||
uint8_t flags = 0x3 << (low * 4);
|
||||
uint16_t reg = 0;
|
||||
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
rtems_interrupt_disable( level);
|
||||
|
||||
reg = mpc83xx.gtm [module].gtcfr [high].reg;
|
||||
mpc83xx.gtm [module].gtcfr [high].reg = (reg & ~mask) | flags;
|
||||
|
||||
mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low] = 0;
|
||||
|
||||
rtems_interrupt_enable( level);
|
||||
|
||||
sc = mpc83xx_gtm_set_clock( timer, clock);
|
||||
CHECK_SC( sc, "Set clock");
|
||||
|
||||
sc = mpc83xx_gtm_set_value( timer, 0);
|
||||
CHECK_SC( sc, "Set value");
|
||||
|
||||
sc = mpc83xx_gtm_set_reference( timer, 0);
|
||||
CHECK_SC( sc, "Set reference");
|
||||
|
||||
sc = mpc83xx_gtm_set_prescale( timer, 0);
|
||||
CHECK_SC( sc, "Set prescale");
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc83xx_gtm_enable_restart( int timer, bool enable)
|
||||
{
|
||||
MPC83XX_GTM_VARIABLES( timer);
|
||||
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
rtems_interrupt_disable( level);
|
||||
|
||||
if (enable) {
|
||||
mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low] |= 0x0008;
|
||||
} else {
|
||||
mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low] &= ~0x0008;
|
||||
}
|
||||
|
||||
rtems_interrupt_enable( level);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc83xx_gtm_set_clock( int timer, int clock)
|
||||
{
|
||||
MPC83XX_GTM_VARIABLES( timer);
|
||||
|
||||
uint16_t reg = 0;
|
||||
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
if (clock & ~MPC83XX_GTM_CLOCK_MASK) {
|
||||
return RTEMS_INVALID_CLOCK;
|
||||
}
|
||||
|
||||
rtems_interrupt_disable( level);
|
||||
|
||||
reg = mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low];
|
||||
mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low] = (reg & ~MPC83XX_GTM_CLOCK_MASK) | clock;
|
||||
|
||||
rtems_interrupt_enable( level);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc83xx_gtm_get_clock( int timer, int *clock)
|
||||
{
|
||||
MPC83XX_GTM_VARIABLES( timer);
|
||||
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
*clock = mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low] & MPC83XX_GTM_CLOCK_MASK;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc83xx_gtm_start( int timer)
|
||||
{
|
||||
MPC83XX_GTM_VARIABLES( timer);
|
||||
|
||||
uint8_t flags = 0x2 << (low * 4);
|
||||
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
rtems_interrupt_disable( level);
|
||||
mpc83xx.gtm [module].gtcfr [high].reg &= ~flags;
|
||||
rtems_interrupt_enable( level);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc83xx_gtm_stop( int timer)
|
||||
{
|
||||
MPC83XX_GTM_VARIABLES( timer);
|
||||
|
||||
uint8_t flags = 0x2 << (low * 4);
|
||||
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
rtems_interrupt_disable( level);
|
||||
mpc83xx.gtm [module].gtcfr [high].reg |= flags;
|
||||
rtems_interrupt_enable( level);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc83xx_gtm_set_value( int timer, uint16_t value)
|
||||
{
|
||||
MPC83XX_GTM_VARIABLES( timer);
|
||||
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
mpc83xx.gtm [module].gt_tim_regs [high].gtcnr [low] = value;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc83xx_gtm_get_value( int timer, uint16_t *value)
|
||||
{
|
||||
MPC83XX_GTM_VARIABLES( timer);
|
||||
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
*value = mpc83xx.gtm [module].gt_tim_regs [high].gtcnr [low];
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc83xx_gtm_set_reference( int timer, uint16_t reference)
|
||||
{
|
||||
MPC83XX_GTM_VARIABLES( timer);
|
||||
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
mpc83xx.gtm [module].gt_tim_regs [high].gtrfr [low] = reference;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc83xx_gtm_get_reference( int timer, uint16_t *reference)
|
||||
{
|
||||
MPC83XX_GTM_VARIABLES( timer);
|
||||
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
reference = mpc83xx.gtm [module].gt_tim_regs [high].gtrfr [low];
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc83xx_gtm_set_prescale( int timer, uint8_t prescale)
|
||||
{
|
||||
MPC83XX_GTM_VARIABLES( timer);
|
||||
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
mpc83xx.gtm [module].gtpsr [module_timer] = prescale;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc83xx_gtm_get_prescale( int timer, uint8_t *prescale)
|
||||
{
|
||||
MPC83XX_GTM_VARIABLES( timer);
|
||||
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
prescale = mpc83xx.gtm [module].gtpsr [module_timer];
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc83xx_gtm_interrupt_get_vector( int timer, rtems_vector_number *vector)
|
||||
{
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
*vector = mpc83xx_gmt_interrupt_vector_table [timer];
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc83xx_gtm_interrupt_enable( int timer)
|
||||
{
|
||||
MPC83XX_GTM_VARIABLES( timer);
|
||||
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
rtems_interrupt_disable( level);
|
||||
mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low] |= 0x0010;
|
||||
rtems_interrupt_enable( level);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc83xx_gtm_interrupt_disable( int timer)
|
||||
{
|
||||
MPC83XX_GTM_VARIABLES( timer);
|
||||
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
rtems_interrupt_disable( level);
|
||||
mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low] &= ~0x0010;
|
||||
rtems_interrupt_enable( level);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_status_code mpc83xx_gtm_interrupt_clear( int timer)
|
||||
{
|
||||
MPC83XX_GTM_VARIABLES( timer);
|
||||
|
||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||
|
||||
mpc83xx.gtm [module].gtevr [module_timer] = 0x0002;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
@@ -619,11 +619,11 @@ static int mpc83xx_i2c_write_bytes
|
||||
}
|
||||
|
||||
rtems_libi2c_bus_ops_t mpc83xx_i2c_ops = {
|
||||
init: mpc83xx_i2c_init,
|
||||
send_start: mpc83xx_i2c_send_start,
|
||||
send_stop: mpc83xx_i2c_send_stop,
|
||||
send_addr: mpc83xx_i2c_send_addr,
|
||||
read_bytes: mpc83xx_i2c_read_bytes,
|
||||
write_bytes: mpc83xx_i2c_write_bytes,
|
||||
.init = mpc83xx_i2c_init,
|
||||
.send_start = mpc83xx_i2c_send_start,
|
||||
.send_stop = mpc83xx_i2c_send_stop,
|
||||
.send_addr = mpc83xx_i2c_send_addr,
|
||||
.read_bytes = mpc83xx_i2c_read_bytes,
|
||||
.write_bytes = mpc83xx_i2c_write_bytes,
|
||||
};
|
||||
|
||||
|
||||
66
c/src/lib/libcpu/powerpc/mpc83xx/include/gtm.h
Normal file
66
c/src/lib/libcpu/powerpc/mpc83xx/include/gtm.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief Header file for timer functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008
|
||||
* Embedded Brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* D-82178 Puchheim
|
||||
* Germany
|
||||
* rtems@embedded-brains.de
|
||||
*
|
||||
* The license and distribution terms for this file may be found in the file
|
||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifndef LIBBSP_POWERPC_MPC83XX_TIMER_H
|
||||
#define LIBBSP_POWERPC_MPC83XX_TIMER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#define MPC83XX_GTM_NUMBER 8
|
||||
|
||||
#define MPC83XX_GTM_CLOCK_CASCADED 0x0000
|
||||
#define MPC83XX_GTM_CLOCK_SYSTEM 0x0002
|
||||
#define MPC83XX_GTM_CLOCK_SYSTEM_SLOW 0x0004
|
||||
#define MPC83XX_GTM_CLOCK_EXTERN 0x0006
|
||||
|
||||
rtems_status_code mpc83xx_gtm_initialize( int timer, int clock);
|
||||
|
||||
rtems_status_code mpc83xx_gtm_enable_restart( int timer, bool enable);
|
||||
|
||||
rtems_status_code mpc83xx_gtm_set_clock( int timer, int clock);
|
||||
|
||||
rtems_status_code mpc83xx_gtm_get_clock( int timer, int *clock);
|
||||
|
||||
rtems_status_code mpc83xx_gtm_start( int timer);
|
||||
|
||||
rtems_status_code mpc83xx_gtm_stop( int timer);
|
||||
|
||||
rtems_status_code mpc83xx_gtm_set_value( int timer, uint16_t value);
|
||||
|
||||
rtems_status_code mpc83xx_gtm_get_value( int timer, uint16_t *value);
|
||||
|
||||
rtems_status_code mpc83xx_gtm_set_reference( int timer, uint16_t reference);
|
||||
|
||||
rtems_status_code mpc83xx_gtm_get_reference( int timer, uint16_t *reference);
|
||||
|
||||
rtems_status_code mpc83xx_gtm_set_prescale( int timer, uint8_t prescale);
|
||||
|
||||
rtems_status_code mpc83xx_gtm_get_prescale( int timer, uint8_t *prescale);
|
||||
|
||||
rtems_status_code mpc83xx_gtm_interrupt_get_vector( int timer, rtems_vector_number *vector);
|
||||
|
||||
rtems_status_code mpc83xx_gtm_interrupt_enable( int timer);
|
||||
|
||||
rtems_status_code mpc83xx_gtm_interrupt_disable( int timer);
|
||||
|
||||
rtems_status_code mpc83xx_gtm_interrupt_clear( int timer);
|
||||
|
||||
#endif /* LIBBSP_POWERPC_MPC83XX_TIMER_H */
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <bsp/irq.h>
|
||||
#include <mpc83xx/mpc83xx.h>
|
||||
#include <mpc83xx/tsec.h>
|
||||
#include <libcpu/spr.h>
|
||||
#include <rtems/error.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <rtems/rtems_bsdnet.h>
|
||||
@@ -43,6 +44,13 @@
|
||||
#include <netinet/if_ether.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* System Version Register */
|
||||
#define SVR 286
|
||||
SPR_RO( SVR)
|
||||
|
||||
/* Processor Version Register */
|
||||
SPR_RO( PVR)
|
||||
|
||||
#define CLREVENT_IN_IRQ
|
||||
|
||||
#define TSEC_WATCHDOG_TIMEOUT 5 /* check media every 5 seconds */
|
||||
@@ -57,7 +65,8 @@ struct mpc83xx_tsec_struct {
|
||||
/*
|
||||
* HW links: (filled from rtems_bsdnet_ifconfig
|
||||
*/
|
||||
m83xxTSEC_Registers_t *reg_ptr; /* pointer to TSEC register block */
|
||||
m83xxTSEC_Registers_t *reg_ptr; /* pointer to TSEC register block */
|
||||
m83xxTSEC_Registers_t *mdio_ptr; /* pointer to TSEC register block which is responsible for MDIO communication */
|
||||
int irq_num_tx; /* tx irq number */
|
||||
int irq_num_rx; /* rx irq number */
|
||||
int irq_num_err; /* error irq number */
|
||||
@@ -192,7 +201,7 @@ static void mpc83xx_tsec_hwinit
|
||||
{
|
||||
m83xxTSEC_Registers_t *reg_ptr = sc->reg_ptr; /* pointer to TSEC registers*/
|
||||
uint8_t *mac_addr;
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
/*
|
||||
* init ECNTL register
|
||||
@@ -272,9 +281,9 @@ static void mpc83xx_tsec_hwinit
|
||||
/*
|
||||
* init MACCFG2 register
|
||||
*/
|
||||
reg_ptr->maccfg2 = ((reg_ptr->maccfg2 & M83xx_TSEC_MACCFG2_IFMODE_MSK)
|
||||
| M83xx_TSEC_MACCFG2_PRELEN(7)
|
||||
| M83xx_TSEC_MACCFG2_FULLDUPLEX);
|
||||
reg_ptr->maccfg2 = (reg_ptr->maccfg2 & M83xx_TSEC_MACCFG2_IFMODE_MSK)
|
||||
| M83xx_TSEC_MACCFG2_PRELEN( 7)
|
||||
| M83xx_TSEC_MACCFG2_FULLDUPLEX;
|
||||
|
||||
/*
|
||||
* init station address register
|
||||
@@ -324,10 +333,19 @@ static void mpc83xx_tsec_mdio_init
|
||||
| <none> |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
|
||||
/* Set TSEC registers for MDIO communication */
|
||||
|
||||
/*
|
||||
* FIXME: Not clear if this works for all boards.
|
||||
* Tested only on MPC8313ERDB.
|
||||
*/
|
||||
sc->mdio_ptr = &mpc83xx.tsec [0];
|
||||
|
||||
/*
|
||||
* set clock divider
|
||||
*/
|
||||
sc->reg_ptr->miimcfg = 3;
|
||||
sc->mdio_ptr->miimcfg = 3;
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
@@ -351,10 +369,10 @@ int mpc83xx_tsec_mdio_read
|
||||
| 0, if ok, else error |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
struct mpc83xx_tsec_struct *sc = uarg;/* control structure */
|
||||
m83xxTSEC_Registers_t *reg_ptr; /* pointer to TSEC registers */
|
||||
struct mpc83xx_tsec_struct *sc = uarg;/* control structure */
|
||||
|
||||
reg_ptr = sc->reg_ptr;
|
||||
/* pointer to TSEC registers */
|
||||
m83xxTSEC_Registers_t *reg_ptr = sc->mdio_ptr;
|
||||
|
||||
/*
|
||||
* make sure we work with a valid phy
|
||||
@@ -419,10 +437,10 @@ int mpc83xx_tsec_mdio_write
|
||||
| 0, if ok, else error |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
struct mpc83xx_tsec_struct *sc = uarg;/* control structure */
|
||||
m83xxTSEC_Registers_t *reg_ptr; /* pointer to TSEC registers */
|
||||
struct mpc83xx_tsec_struct *sc = uarg;/* control structure */
|
||||
|
||||
reg_ptr = sc->reg_ptr;
|
||||
/* pointer to TSEC registers */
|
||||
m83xxTSEC_Registers_t *reg_ptr = sc->mdio_ptr;
|
||||
|
||||
/*
|
||||
* make sure we work with a valid phy
|
||||
@@ -1685,9 +1703,9 @@ int rtems_mpc83xx_tsec_mode_adapt
|
||||
| 0, if success |
|
||||
\*=========================================================================*/
|
||||
{
|
||||
int result;
|
||||
int media;
|
||||
int result = 0;
|
||||
struct mpc83xx_tsec_struct *sc = ifp->if_softc;
|
||||
int media = IFM_MAKEWORD( 0, 0, 0, sc->phy_default);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("c");
|
||||
@@ -1819,6 +1837,8 @@ static int mpc83xx_tsec_driver_attach
|
||||
struct ifnet *ifp;
|
||||
int unitNumber;
|
||||
char *unitName;
|
||||
uint32_t svr = _read_SVR();
|
||||
uint32_t pvr = _read_PVR();
|
||||
|
||||
/*
|
||||
* Parse driver name
|
||||
@@ -1865,10 +1885,30 @@ static int mpc83xx_tsec_driver_attach
|
||||
|
||||
/* get pointer to TSEC register block */
|
||||
sc->reg_ptr = &mpc83xx.tsec[unitNumber-1];
|
||||
/* get base interrupt number (for Tx irq, Rx=base+1,Err=base+2) */
|
||||
sc->irq_num_tx = config->irno + 0; /* tx irq number from BSP */
|
||||
sc->irq_num_rx = config->irno + 1; /* rx irq number from BSP */
|
||||
sc->irq_num_err = config->irno + 2; /* err irq number from BSP */
|
||||
|
||||
if (svr == 0x80b00010 && pvr == 0x80850010) {
|
||||
/*
|
||||
* This is a special case for MPC8313ERDB with silicon revision 1. Look in
|
||||
* "MPC8313ECE Rev. 3, 3/2008" errata for "IPIC 1".
|
||||
*/
|
||||
if (unitNumber == 1) {
|
||||
sc->irq_num_tx = 37;
|
||||
sc->irq_num_rx = 36;
|
||||
sc->irq_num_err = 35;
|
||||
} else if (unitNumber == 2) {
|
||||
sc->irq_num_tx = 34;
|
||||
sc->irq_num_rx = 33;
|
||||
sc->irq_num_err = 32;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* get base interrupt number (for Tx irq, Rx=base+1,Err=base+2) */
|
||||
sc->irq_num_tx = config->irno + 0; /* tx irq number from BSP */
|
||||
sc->irq_num_rx = config->irno + 1; /* rx irq number from BSP */
|
||||
sc->irq_num_err = config->irno + 2; /* err irq number from BSP */
|
||||
}
|
||||
|
||||
if (config->irno == 0) {
|
||||
rtems_panic("TSEC: interupt base number irno not defined");
|
||||
}
|
||||
@@ -1878,11 +1918,22 @@ static int mpc83xx_tsec_driver_attach
|
||||
sc->mdio_info.mdio_r = mpc83xx_tsec_mdio_read;
|
||||
sc->mdio_info.mdio_w = mpc83xx_tsec_mdio_write;
|
||||
sc->mdio_info.has_gmii = 1; /* we support gigabit IF */
|
||||
|
||||
/*
|
||||
* XXX: Although most hardware builders will assign the PHY addresses
|
||||
* like this, this should be more configurable
|
||||
*/
|
||||
#ifdef MPC8313ERDB
|
||||
if (unitNumber == 2) {
|
||||
sc->phy_default = 4;
|
||||
} else {
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
#else /* MPC8313ERDB */
|
||||
sc->phy_default = unitNumber-1;
|
||||
#endif /* MPC8313ERDB */
|
||||
|
||||
/*
|
||||
* Set up network interface values
|
||||
*/
|
||||
|
||||
@@ -434,9 +434,9 @@ int mpc83xx_spi_read_write_bytes
|
||||
#endif
|
||||
if (tbuf == NULL) {
|
||||
/*
|
||||
* perform dummy write to read byte
|
||||
* perform idle char write to read byte
|
||||
*/
|
||||
softc_ptr->reg_ptr->spitd = 0;
|
||||
softc_ptr->reg_ptr->spitd = softc_ptr->idle_char << bit_shift;
|
||||
}
|
||||
else {
|
||||
switch(bytes_per_char) {
|
||||
@@ -583,6 +583,10 @@ rtems_status_code mpc83xx_spi_set_tfr_mode
|
||||
mpc83xx_spi_softc_t *softc_ptr = &(((mpc83xx_spi_desc_t *)(bh))->softc);
|
||||
uint32_t spimode_baud,spimode;
|
||||
rtems_status_code rc = RTEMS_SUCCESSFUL;
|
||||
|
||||
/* Set idle character */
|
||||
softc_ptr->idle_char = tfr_mode->idle_char;
|
||||
|
||||
/*
|
||||
* FIXME: set proper mode
|
||||
*/
|
||||
|
||||
@@ -35,6 +35,7 @@ typedef struct mpc83xx_spi_softc {
|
||||
uint32_t base_frq; /* input frq for baud rate divider */
|
||||
rtems_id irq_sema_id;
|
||||
uint32_t curr_addr; /* current spi address */
|
||||
uint32_t idle_char;
|
||||
uint8_t bytes_per_char;
|
||||
uint8_t bit_shift;
|
||||
} mpc83xx_spi_softc_t ;
|
||||
|
||||
@@ -210,6 +210,19 @@ $(PROJECT_INCLUDE)/mpc8260/mmu.h: mpc8260/include/mmu.h $(PROJECT_INCLUDE)/mpc82
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc8260/mmu.h
|
||||
endif
|
||||
if mpc83xx
|
||||
$(PROJECT_INCLUDE)/bsp/$(dirstamp):
|
||||
@$(MKDIR_P) $(PROJECT_INCLUDE)/bsp
|
||||
@: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/vectors.h: new-exceptions/bspsupport/vectors.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vectors.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vectors.h
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h: new-exceptions/bspsupport/ppc_exc_bspsupp.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h
|
||||
|
||||
$(PROJECT_INCLUDE)/mpc83xx/$(dirstamp):
|
||||
@$(MKDIR_P) $(PROJECT_INCLUDE)/mpc83xx
|
||||
@: > $(PROJECT_INCLUDE)/mpc83xx/$(dirstamp)
|
||||
@@ -230,4 +243,55 @@ PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc83xx/mpc83xx_i2cdrv.h
|
||||
$(PROJECT_INCLUDE)/mpc83xx/mpc83xx_spidrv.h: mpc83xx/spi/mpc83xx_spidrv.h $(PROJECT_INCLUDE)/mpc83xx/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc83xx/mpc83xx_spidrv.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc83xx/mpc83xx_spidrv.h
|
||||
|
||||
$(PROJECT_INCLUDE)/mpc83xx/gtm.h: mpc83xx/include/gtm.h $(PROJECT_INCLUDE)/mpc83xx/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc83xx/gtm.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc83xx/gtm.h
|
||||
endif
|
||||
if mpc55xx
|
||||
$(PROJECT_INCLUDE)/bsp/$(dirstamp):
|
||||
@$(MKDIR_P) $(PROJECT_INCLUDE)/bsp
|
||||
@: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/vectors.h: new-exceptions/bspsupport/vectors.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vectors.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vectors.h
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h: new-exceptions/bspsupport/ppc_exc_bspsupp.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/irq.h: mpc55xx/include/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
|
||||
|
||||
$(PROJECT_INCLUDE)/mpc55xx/$(dirstamp):
|
||||
@$(MKDIR_P) $(PROJECT_INCLUDE)/mpc55xx
|
||||
@: > $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
|
||||
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
|
||||
|
||||
$(PROJECT_INCLUDE)/mpc55xx/regs.h: mpc55xx/include/regs.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/regs.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/regs.h
|
||||
|
||||
$(PROJECT_INCLUDE)/mpc55xx/reg-defs.h: mpc55xx/include/reg-defs.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/reg-defs.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/reg-defs.h
|
||||
|
||||
$(PROJECT_INCLUDE)/mpc55xx/dspi.h: mpc55xx/include/dspi.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/dspi.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/dspi.h
|
||||
|
||||
$(PROJECT_INCLUDE)/mpc55xx/edma.h: mpc55xx/include/edma.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/edma.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/edma.h
|
||||
|
||||
$(PROJECT_INCLUDE)/mpc55xx/mpc55xx.h: mpc55xx/include/mpc55xx.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/mpc55xx.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/mpc55xx.h
|
||||
|
||||
$(PROJECT_INCLUDE)/mpc55xx/esci.h: mpc55xx/include/esci.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/esci.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/esci.h
|
||||
endif
|
||||
|
||||
@@ -91,6 +91,17 @@ extern "C" {
|
||||
#define PPC_LOW_POWER_MODE_NONE 0
|
||||
#define PPC_LOW_POWER_MODE_STANDARD 1
|
||||
|
||||
/**
|
||||
* @brief For boards with no cache set PPC_CACHE_ALIGNMENT to this value.
|
||||
*/
|
||||
#define PPC_NO_CACHE_ALIGNMENT 4
|
||||
|
||||
/**
|
||||
* @brief Used to define PPC_CACHE_ALIGN_POWER for boards with no cache (and
|
||||
* PPC_NO_CACHE_ALIGNMENT defined).
|
||||
*/
|
||||
#define PPC_NO_CACHE_ALIGNMENT_POWER 2
|
||||
|
||||
/*
|
||||
* Figure out all CPU Model Feature Flags based upon compiler
|
||||
* predefines.
|
||||
@@ -129,7 +140,7 @@ extern "C" {
|
||||
#elif defined(mpc555)
|
||||
|
||||
/* Copied from mpc505 */
|
||||
#define PPC_CACHE_ALIGNMENT 16
|
||||
#define PPC_CACHE_ALIGNMENT PPC_NO_CACHE_ALIGNMENT
|
||||
|
||||
/* Added by querbach@realtime.bc.ca */
|
||||
#define PPC_LOW_POWER_MODE PPC_LOW_POWER_MODE_STANDARD
|
||||
@@ -145,7 +156,9 @@ extern "C" {
|
||||
* to get the setting correct.
|
||||
*/
|
||||
|
||||
#define PPC_CACHE_ALIGNMENT 16
|
||||
#define CPU_MODEL_NAME "PowerPC 505/509"
|
||||
|
||||
#define PPC_CACHE_ALIGNMENT PPC_NO_CACHE_ALIGNMENT
|
||||
#define PPC_I_CACHE 4096
|
||||
#define PPC_D_CACHE 0
|
||||
|
||||
@@ -280,6 +293,8 @@ extern "C" {
|
||||
#define PPC_CACHE_ALIGN_POWER 4
|
||||
#elif (PPC_CACHE_ALIGNMENT == 32)
|
||||
#define PPC_CACHE_ALIGN_POWER 5
|
||||
#elif (PPC_CACHE_ALIGNMENT == PPC_NO_CACHE_ALIGNMENT)
|
||||
#define PPC_CACHE_ALIGN_POWER PPC_NO_CACHE_ALIGNMENT_POWER
|
||||
#else
|
||||
#error "Undefined power of 2 for PPC_CACHE_ALIGNMENT"
|
||||
#endif
|
||||
|
||||
@@ -31,73 +31,7 @@
|
||||
|
||||
#include <rtems/powerpc/registers.h>
|
||||
|
||||
#ifdef ASM
|
||||
|
||||
#include <rtems/asm.h>
|
||||
|
||||
.macro LA reg, addr
|
||||
lis \reg, (\addr)@h
|
||||
ori \reg, \reg, (\addr)@l
|
||||
.endm
|
||||
|
||||
.macro LWI reg, value
|
||||
lis \reg, (\value)@h
|
||||
ori \reg, \reg, (\value)@l
|
||||
.endm
|
||||
|
||||
.macro LW reg, addr
|
||||
lis \reg, \addr@ha
|
||||
lwz \reg, \addr@l(\reg)
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Tests the bits in reg1 against the bits set in mask. A match is indicated
|
||||
* by EQ = 0 in CR0. A mismatch is indicated by EQ = 1 in CR0. The register
|
||||
* reg2 is used to load the mask.
|
||||
*/
|
||||
.macro TSTBITS reg1, reg2, mask
|
||||
LWI \reg2, \mask
|
||||
and \reg1, \reg1, \reg2
|
||||
cmplw \reg1, \reg2
|
||||
.endm
|
||||
|
||||
.macro SETBITS reg1, reg2, mask
|
||||
LWI \reg2, \mask
|
||||
or \reg1, \reg1, \reg2
|
||||
.endm
|
||||
|
||||
.macro CLRBITS reg1, reg2, mask
|
||||
LWI \reg2, \mask
|
||||
andc \reg1, \reg1, \reg2
|
||||
.endm
|
||||
|
||||
.macro GLOBAL_FUNCTION name
|
||||
.global \name
|
||||
.type \name, @function
|
||||
\name:
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Disables all asynchronous exeptions (interrupts) which may cause a context
|
||||
* switch.
|
||||
*/
|
||||
.macro INTERRUPT_DISABLE level, mask
|
||||
mfmsr \level
|
||||
mfspr \mask, sprg0
|
||||
andc \mask, \level, \mask
|
||||
mtmsr \mask
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Restore previous machine state.
|
||||
*/
|
||||
.macro INTERRUPT_ENABLE level
|
||||
mtmsr \level
|
||||
.endm
|
||||
|
||||
#define LINKER_SYMBOL( sym) .extern sym
|
||||
|
||||
#else /* ASM */
|
||||
#ifndef ASM
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -518,6 +452,72 @@ static inline void ppc_set_time_base_64( uint64_t val)
|
||||
PPC_Set_timebase_register( val);
|
||||
}
|
||||
|
||||
#else /* ASM */
|
||||
|
||||
#include <rtems/asm.h>
|
||||
|
||||
.macro LA reg, addr
|
||||
lis \reg, (\addr)@h
|
||||
ori \reg, \reg, (\addr)@l
|
||||
.endm
|
||||
|
||||
.macro LWI reg, value
|
||||
lis \reg, (\value)@h
|
||||
ori \reg, \reg, (\value)@l
|
||||
.endm
|
||||
|
||||
.macro LW reg, addr
|
||||
lis \reg, \addr@ha
|
||||
lwz \reg, \addr@l(\reg)
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Tests the bits in reg1 against the bits set in mask. A match is indicated
|
||||
* by EQ = 0 in CR0. A mismatch is indicated by EQ = 1 in CR0. The register
|
||||
* reg2 is used to load the mask.
|
||||
*/
|
||||
.macro TSTBITS reg1, reg2, mask
|
||||
LWI \reg2, \mask
|
||||
and \reg1, \reg1, \reg2
|
||||
cmplw \reg1, \reg2
|
||||
.endm
|
||||
|
||||
.macro SETBITS reg1, reg2, mask
|
||||
LWI \reg2, \mask
|
||||
or \reg1, \reg1, \reg2
|
||||
.endm
|
||||
|
||||
.macro CLRBITS reg1, reg2, mask
|
||||
LWI \reg2, \mask
|
||||
andc \reg1, \reg1, \reg2
|
||||
.endm
|
||||
|
||||
.macro GLOBAL_FUNCTION name
|
||||
.global \name
|
||||
.type \name, @function
|
||||
\name:
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Disables all asynchronous exeptions (interrupts) which may cause a context
|
||||
* switch.
|
||||
*/
|
||||
.macro INTERRUPT_DISABLE level, mask
|
||||
mfmsr \level
|
||||
mfspr \mask, sprg0
|
||||
andc \mask, \level, \mask
|
||||
mtmsr \mask
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Restore previous machine state.
|
||||
*/
|
||||
.macro INTERRUPT_ENABLE level
|
||||
mtmsr \level
|
||||
.endm
|
||||
|
||||
#define LINKER_SYMBOL( sym) .extern sym
|
||||
|
||||
#endif /* ASM */
|
||||
|
||||
#endif /* LIBCPU_POWERPC_UTILITY_H */
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* #ingroup powerpc_shared
|
||||
*
|
||||
* @brief Source file for the Cache Manager PowerPC support.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Cache Management Support Routines for the MC68040
|
||||
* Modified for MPC8260 Andy Dachs <a.dachs@sstl.co.uk>
|
||||
@@ -194,6 +202,67 @@ void _CPU_cache_disable_instruction ( void )
|
||||
mtspr( 560, r1 );
|
||||
isync;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#warning Most cache functions are not implemented
|
||||
|
||||
void _CPU_cache_flush_entire_data()
|
||||
{
|
||||
/* Void */
|
||||
}
|
||||
|
||||
void _CPU_cache_invalidate_entire_data()
|
||||
{
|
||||
/* Void */
|
||||
}
|
||||
|
||||
void _CPU_cache_freeze_data()
|
||||
{
|
||||
/* Void */
|
||||
}
|
||||
|
||||
void _CPU_cache_unfreeze_data()
|
||||
{
|
||||
/* Void */
|
||||
}
|
||||
|
||||
void _CPU_cache_enable_data()
|
||||
{
|
||||
/* Void */
|
||||
}
|
||||
|
||||
void _CPU_cache_disable_data()
|
||||
{
|
||||
/* Void */
|
||||
}
|
||||
|
||||
void _CPU_cache_invalidate_entire_instruction()
|
||||
{
|
||||
/* Void */
|
||||
}
|
||||
|
||||
void _CPU_cache_freeze_instruction()
|
||||
{
|
||||
/* Void */
|
||||
}
|
||||
|
||||
void _CPU_cache_unfreeze_instruction()
|
||||
{
|
||||
/* Void */
|
||||
}
|
||||
|
||||
|
||||
void _CPU_cache_enable_instruction()
|
||||
{
|
||||
/* Void */
|
||||
}
|
||||
|
||||
void _CPU_cache_disable_instruction()
|
||||
{
|
||||
/* Void */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void _CPU_cache_invalidate_1_data_line(
|
||||
|
||||
@@ -1,38 +1,25 @@
|
||||
/*
|
||||
* PowerPC Cache Manager Support
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* #ingroup powerpc_shared
|
||||
*
|
||||
* @brief Header file for the Cache Manager PowerPC support.
|
||||
*/
|
||||
|
||||
#ifndef __POWERPC_CACHE_h
|
||||
#define __POWERPC_CACHE_h
|
||||
/*
|
||||
* get definitions from the score/powerpc header
|
||||
* about individual cache alignments
|
||||
*/
|
||||
#ifndef LIBCPU_POWERPC_CACHE_H
|
||||
#define LIBCPU_POWERPC_CACHE_H
|
||||
|
||||
#include <rtems/score/powerpc.h>
|
||||
|
||||
/*
|
||||
* CACHE MANAGER: The following functions are CPU-specific.
|
||||
* They provide the basic implementation for the rtems_* cache
|
||||
* management routines. If a given function has no meaning for the CPU,
|
||||
* it does nothing by default.
|
||||
*
|
||||
* FIXME: Some functions simply have not been implemented.
|
||||
*/
|
||||
|
||||
#if defined(ppc603) || defined(ppc603e) || defined(mpc8260)
|
||||
/* And possibly others */
|
||||
|
||||
#if defined(PPC_CACHE_ALIGNMENT)
|
||||
|
||||
#define CPU_DATA_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
|
||||
#define CPU_INSTRUCTION_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
|
||||
|
||||
#endif
|
||||
/* Provide the CPU defines only if we have a cache */
|
||||
#if PPC_CACHE_ALIGNMENT != PPC_NO_CACHE_ALIGNMENT
|
||||
#define CPU_DATA_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
|
||||
#define CPU_INSTRUCTION_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
|
||||
#endif
|
||||
|
||||
#ifdef _OLD_EXCEPTIONS
|
||||
#include <libcpu/cache.h>
|
||||
# warning OLD EXCEPTIONS
|
||||
# include <libcpu/cache.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
||||
#endif /* LIBCPU_POWERPC_CACHE_H */
|
||||
|
||||
Reference in New Issue
Block a user