Update for MPC55XX changes

This commit is contained in:
Thomas Doerfler
2009-07-21 08:38:04 +00:00
parent 115971c321
commit d374492cc6
25 changed files with 3818 additions and 704 deletions

View File

@@ -1,3 +1,12 @@
2009-07-20 Sebastian Huber <sebastian.huber@embedded-brains.de>
* clock/clock-config.c, include/smsc9218i.h, network/smsc9218i.c: New
files.
* network/network.c: Removed file.
* Makefile.am, README, bsp_specs, preinstall.am, include/bsp.h,
startup/bspstart.c, startup/sd-card-init.c, tests/tests.c: Changes
throughout.
2009-07-16 Joel Sherrill <joel.sherrill@oarcorp.com>
* configure.ac: Rename BSP_BOOTCARD_OPTIONS to

View File

@@ -36,7 +36,10 @@ nodist_include_HEADERS = include/bspopts.h ../../shared/tod.h \
../../shared/include/coverhd.h
include_bsp_HEADERS = include/mpc55xxevb.h \
include/irq-config.h \
include/smsc9218i.h \
../../shared/include/irq-generic.h \
../../shared/include/irq-info.h \
../../shared/include/utility.h \
../shared/include/tictac.h
# startup
@@ -45,11 +48,13 @@ libbsp_a_SOURCES += ../../shared/bsplibc.c ../../shared/bsppost.c \
startup/bspstart.c startup/bspgetworkarea.c ../../shared/bsppretaskinghook.c
# clock
libbsp_a_SOURCES += ../shared/clock/clock.c
libbsp_a_SOURCES += clock/clock-config.c
# irq_generic
libbsp_a_SOURCES += ../../shared/src/irq-generic.c \
../../shared/src/irq-legacy.c
../../shared/src/irq-legacy.c \
../../shared/src/irq-info.c \
../../shared/src/irq-shell.c
# tests
libbsp_a_SOURCES += ../../shared/timerstub.c
@@ -60,7 +65,7 @@ libbsp_a_SOURCES += tests/tests.c startup/sd-card-init.c
# Network
if HAS_NETWORKING
noinst_PROGRAMS += network.rel
network_rel_SOURCES = network/network.c
network_rel_SOURCES = network/smsc9218i.c
network_rel_CPPFLAGS = $(AM_CPPFLAGS) -D__INSIDE_RTEMS_BSD_TCPIP_STACK__ -D__BSD_VISIBLE
network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
@@ -73,6 +78,7 @@ libbsp_a_LIBADD = ../../../libcpu/@RTEMS_CPU@/shared/cpuIdent.rel \
../../../libcpu/@RTEMS_CPU@/@RTEMS_CPU_MODEL@/misc.rel \
../../../libcpu/@RTEMS_CPU@/@RTEMS_CPU_MODEL@/irq.rel \
../../../libcpu/@RTEMS_CPU@/@RTEMS_CPU_MODEL@/edma.rel \
../../../libcpu/@RTEMS_CPU@/@RTEMS_CPU_MODEL@/emios.rel \
../../../libcpu/@RTEMS_CPU@/@RTEMS_CPU_MODEL@/dspi.rel \
../../../libcpu/@RTEMS_CPU@/@RTEMS_CPU_MODEL@/esci.rel \
../../../libcpu/@RTEMS_CPU@/@exceptions@/rtems-cpu.rel \

View File

@@ -8,7 +8,6 @@ CPU FAMILY: ppc
CPU: PowerPC e200z6
COPROCESSORS: N/A
MODE: 32 bit mode
DEBUG MONITOR: BAM
PERIPHERALS
===========
@@ -21,12 +20,13 @@ DMA: eDMA
VIDEO: N/A
SCSI: N/A
NETWORKING: FEC (not yet supported)
SMSC9218I (external)
SPI: DSPI
DRIVER INFORMATION
==================
CLOCK DRIVER: Book E decrementer
CLOCK DRIVER: EMIOS channel 23
IOSUPP DRIVER: N/A
SHMSUPP: N/A
TIMER DRIVER: not yet supported
@@ -47,7 +47,7 @@ NOTES
BUS WIDTH: 32 bit Flash, 32 bit SDRAM
FLASH: 3 MByte
RAM: 128 kByte SDRAM
INTERNAL RAM: 128 kByte SDRAM
EXTERNAL RAM: 512 kByte SDRAM

View File

@@ -4,10 +4,10 @@
*startfile:
%{!qrtems: %(old_startfile)} \
%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s start.o%s}}
%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s start.o%s}}
*endfile:
%{!qrtems: %(old_endfile)} %{qrtems: ecrtn.o%s}
%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
*link:
%{!qrtems: %(old_link)} %{qrtems: -dc -dp -N}

View File

@@ -0,0 +1,150 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief Clock driver configuration.
*/
/*
* Copyright (c) 2009
* 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/emios.h>
#include <rtems.h>
#include <bsp.h>
#include <bsp/irq.h>
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <rtems/status-checks.h>
#define MPC55XX_CLOCK_EMIOS_CHANNEL (MPC55XX_EMIOS_CHANNEL_NUMBER - 1)
/* This is defined in clockdrv_shell.h */
rtems_isr Clock_isr( rtems_vector_number vector);
#define Clock_driver_support_at_tick() \
do { \
union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS; \
csr.B.FLAG = 1; \
EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CSR.R = csr.R; \
} while (0)
static void mpc55xx_clock_handler_install( void)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
sc = mpc55xx_interrupt_handler_install(
MPC55XX_IRQ_EMIOS_GET_REQUEST( MPC55XX_CLOCK_EMIOS_CHANNEL),
"clock",
RTEMS_INTERRUPT_UNIQUE,
MPC55XX_INTC_MIN_PRIORITY,
(rtems_interrupt_handler) Clock_isr,
NULL
);
RTEMS_CHECK_SC_VOID( sc, "install clock interrupt handler");
}
static void mpc55xx_clock_initialize( void)
{
volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
union EMIOS_CCR_tag ccr = MPC55XX_ZERO_FLAGS;
union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS;
unsigned prescaler = mpc55xx_emios_global_prescaler();
uint64_t interval = ((uint64_t) bsp_clock_speed
* (uint64_t) rtems_configuration_get_microseconds_per_tick()) / 1000000;
/* Apply prescaler */
if (prescaler > 0) {
interval /= (uint64_t) prescaler;
} else {
RTEMS_SYSLOG_ERROR( "unexpected global eMIOS prescaler\n");
}
/* Check interval */
if (interval == 0 || interval > MPC55XX_EMIOS_VALUE_MAX) {
interval = MPC55XX_EMIOS_VALUE_MAX;
RTEMS_SYSLOG_ERROR( "clock timer interval out of range\n");
}
/* Configure eMIOS channel */
/* Set channel in GPIO mode */
ccr.B.MODE = MPC55XX_EMIOS_MODE_GPIO_INPUT;
regs->CCR.R = ccr.R;
/* Clear status flags */
csr.B.OVR = 1;
csr.B.OVFL = 1;
csr.B.FLAG = 1;
regs->CSR.R = csr.R;
/* Set timer period */
regs->CADR.R = (uint32_t) interval - 1;
/* Set unused registers */
regs->CBDR.R = 0;
regs->CCNTR.R = 0;
regs->ALTCADR.R = 0;
/* Set control register */
ccr.B.MODE = MPC55XX_EMIOS_MODE_MC_UP_INT_CLK;
ccr.B.UCPREN = 1;
ccr.B.FEN = 1;
ccr.B.FREN = 1;
regs->CCR.R = ccr.R;
}
static void mpc55xx_clock_cleanup( void)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
union EMIOS_CCR_tag ccr = MPC55XX_ZERO_FLAGS;
/* Set channel in GPIO mode */
ccr.B.MODE = MPC55XX_EMIOS_MODE_GPIO_INPUT;
regs->CCR.R = ccr.R;
/* Remove interrupt handler */
sc = rtems_interrupt_handler_remove(
MPC55XX_IRQ_EMIOS_GET_REQUEST( MPC55XX_CLOCK_EMIOS_CHANNEL),
(rtems_interrupt_handler) Clock_isr,
NULL
);
RTEMS_CHECK_SC_VOID( sc, "remove clock interrupt handler");
}
static uint32_t mpc55xx_clock_nanoseconds_since_last_tick( void)
{
uint64_t clicks = EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CCNTR.R;
uint64_t clock = bsp_clock_speed;
uint64_t ns = (clicks * 1000000000) / clock;
return (uint32_t) ns;
}
#define Clock_driver_support_initialize_hardware() mpc55xx_clock_initialize()
#define Clock_driver_support_install_isr( isr, old_isr) \
mpc55xx_clock_handler_install()
#define Clock_driver_support_shutdown_hardware() mpc55xx_clock_cleanup()
#define Clock_driver_nanoseconds_since_last_tick \
mpc55xx_clock_nanoseconds_since_last_tick
/* Include shared source clock driver code */
#include "../../../../libbsp/shared/clockdrv_shell.h"

View File

@@ -43,7 +43,20 @@ extern unsigned int bsp_clock_speed;
/** @brief Time base clicks per micro second */
extern uint32_t bsp_clicks_per_usec;
rtems_status_code mpc55xx_sd_card_init( void);
rtems_status_code mpc55xx_sd_card_init( bool mount);
/* Network driver configuration */
struct rtems_bsdnet_ifconfig;
int smsc9218i_attach_detach(
struct rtems_bsdnet_ifconfig *config,
int attaching
);
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH smsc9218i_attach_detach
#define RTEMS_BSP_NETWORK_DRIVER_NAME "eth0"
#endif /* ASM */

View File

@@ -0,0 +1,795 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief SMSC - LAN9218i
*/
/*
* Copyright (c) 2009
* 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.
*/
/**
* @name Memory Map
* @{
*/
typedef struct {
uint32_t rx_fifo_data;
uint32_t rx_fifo_data_aliases [7];
uint32_t tx_fifo_data;
uint32_t tx_fifo_data_aliases [7];
uint32_t rx_fifo_status;
uint32_t rx_fifo_status_peek;
uint32_t tx_fifo_status;
uint32_t tx_fifo_status_peek;
uint32_t id_rev;
uint32_t irq_cfg;
uint32_t int_sts;
uint32_t int_en;
uint32_t reserved_0;
uint32_t byte_test;
uint32_t fifo_int;
uint32_t rx_cfg;
uint32_t tx_cfg;
uint32_t hw_cfg;
uint32_t rx_dp_ctl;
uint32_t rx_fifo_inf;
uint32_t tx_fifo_inf;
uint32_t pmt_ctrl;
uint32_t gpio_cfg;
uint32_t gpt_cfg;
uint32_t gpt_cnt;
uint32_t reserved_1;
uint32_t word_swap;
uint32_t free_run;
uint32_t rx_drop;
uint32_t mac_csr_cmd;
uint32_t mac_csr_data;
uint32_t afc_cfg;
uint32_t e2p_cmd;
uint32_t e2p_data;
} smsc9218i_registers;
volatile smsc9218i_registers *const smsc9218i = (volatile smsc9218i_registers *) 0x3fff8000;
/** @} */
#define SMSC9218I_BIT_POS(pos) \
((pos) > 15 ? \
((pos) > 23 ? (pos) - 24 : (pos) - 8) \
: ((pos) > 7 ? (pos) + 8 : (pos) + 24))
#define SMSC9218I_FLAG(pos) \
(1U << SMSC9218I_BIT_POS(pos))
#define SMSC9218I_FIELD_8(val, pos) \
(((val) & 0xff) << SMSC9218I_BIT_POS(pos))
#define SMSC9218I_GET_FIELD_8(reg, pos) \
(((reg) >> SMSC9218I_BIT_POS(pos)) & 0xff)
#define SMSC9218I_FIELD_16(val, pos) \
(SMSC9218I_FIELD_8((val) >> 8, (pos) + 8) \
| SMSC9218I_FIELD_8((val), pos))
#define SMSC9218I_GET_FIELD_16(reg, pos) \
((SMSC9218I_GET_FIELD_8(reg, (pos) + 8) << 8) \
| SMSC9218I_GET_FIELD_8(reg, pos))
#define SMSC9218I_SWAP(val) \
((((val) >> 24) & 0xff) \
| ((((val) >> 16) & 0xff) << 8) \
| ((((val) >> 8) & 0xff) << 16) \
| (((val) & 0xff) << 24))
/**
* @name Receive Status
* @{
*/
#define SMSC9218I_RX_STS_FILTER_FAIL SMSC9218I_FLAG(30)
#define SMSC9218I_RX_STS_GET_LENGTH(reg) (SMSC9218I_GET_FIELD_16(reg, 16) & 0x3fff)
#define SMSC9218I_RX_STS_ERROR SMSC9218I_FLAG(15)
#define SMSC9218I_RX_STS_BROADCAST SMSC9218I_FLAG(13)
#define SMSC9218I_RX_STS_ERROR_LENGTH SMSC9218I_FLAG(12)
#define SMSC9218I_RX_STS_ERROR_RUNT_FRAME SMSC9218I_FLAG(11)
#define SMSC9218I_RX_STS_MULTICAST SMSC9218I_FLAG(10)
#define SMSC9218I_RX_STS_ERROR_TOO_LONG SMSC9218I_FLAG(7)
#define SMSC9218I_RX_STS_ERROR_COLLISION SMSC9218I_FLAG(6)
#define SMSC9218I_RX_STS_TYPE SMSC9218I_FLAG(5)
#define SMSC9218I_RX_STS_WATCHDOG SMSC9218I_FLAG(4)
#define SMSC9218I_RX_STS_ERROR_MII SMSC9218I_FLAG(3)
#define SMSC9218I_RX_STS_DRIBBLING_BIT SMSC9218I_FLAG(2)
#define SMSC9218I_RX_STS_ERROR_CRC SMSC9218I_FLAG(1)
/** @} */
/**
* @name Transmit Status
* @{
*/
#define SMSC9218I_TX_STS_GET_TAG(reg) SMSC9218I_GET_FIELD_16(reg, 16)
#define SMSC9218I_TX_STS_ERROR SMSC9218I_FLAG(15)
#define SMSC9218I_TX_STS_ERROR_LOSS_OF_CARRIER SMSC9218I_FLAG(11)
#define SMSC9218I_TX_STS_ERROR_NO_CARRIER SMSC9218I_FLAG(10)
#define SMSC9218I_TX_STS_ERROR_LATE_COLLISION SMSC9218I_FLAG(9)
#define SMSC9218I_TX_STS_ERROR_EXCESSIVE_COLLISIONS SMSC9218I_FLAG(8)
#define SMSC9218I_TX_STS_ERROR_EXCESSIVE_DEFERRAL SMSC9218I_FLAG(2)
#define SMSC9218I_TX_STS_ERROR_DEFERRED SMSC9218I_FLAG(0)
/** @} */
/**
* @name Transmit Command A
* @{
*/
#define SMSC9218I_TX_A_IOC SMSC9218I_FLAG(31)
#define SMSC9218I_TX_A_END_ALIGN_4 0
#define SMSC9218I_TX_A_END_ALIGN_16 SMSC9218I_FLAG(24)
#define SMSC9218I_TX_A_END_ALIGN_32 SMSC9218I_FLAG(25)
#define SMSC9218I_TX_A_DOFF(val) SMSC9218I_FIELD_8(val, 16)
#define SMSC9218I_TX_A_FIRST SMSC9218I_FLAG(13)
#define SMSC9218I_TX_A_LAST SMSC9218I_FLAG(12)
#define SMSC9218I_TX_A_FRAGMENT_LENGTH(val) SMSC9218I_FIELD_16(val, 0)
/** @} */
/**
* @name Transmit Command B
* @{
*/
#define SMSC9218I_TX_B_TAG(val) SMSC9218I_FIELD_16(val, 16)
#define SMSC9218I_TX_B_GET_TAG(reg) SMSC9218I_GET_FIELD_16(reg, 16)
#define SMSC9218I_TX_B_DISABLE_CRC SMSC9218I_FLAG(13)
#define SMSC9218I_TX_B_DISABLE_PAD SMSC9218I_FLAG(12)
#define SMSC9218I_TX_B_FRAME_LENGTH(val) SMSC9218I_FIELD_16(val, 0)
/** @} */
/**
* @name Chip ID and Revision
* @{
*/
#define SMSC9218I_ID_REV_GET_ID(reg) SMSC9218I_GET_FIELD_16(reg, 16)
#define SMSC9218I_ID_REV_GET_REV(reg) SMSC9218I_GET_FIELD_16(reg, 0)
#define SMSC9218I_ID_REV_ID_CHIP_118 0x0118U
#define SMSC9218I_ID_REV_ID_CHIP_218 0x118aU
/** @} */
/**
* @name Interrupt Configuration
* @{
*/
#define SMSC9218I_IRQ_CFG_INT_DEAS(val) SMSC9218I_FIELD_8(val, 24)
#define SMSC9218I_IRQ_CFG_GET_INT_DEAS(reg) SMSC9218I_GET_FIELD_8(reg, 24)
#define SMSC9218I_IRQ_CFG_INT_DEAS_CLR SMSC9218I_FLAG(14)
#define SMSC9218I_IRQ_CFG_INT_DEAS_STS SMSC9218I_FLAG(13)
#define SMSC9218I_IRQ_CFG_IRQ_INT SMSC9218I_FLAG(12)
#define SMSC9218I_IRQ_CFG_IRQ_EN SMSC9218I_FLAG(8)
#define SMSC9218I_IRQ_CFG_IRQ_POL SMSC9218I_FLAG(4)
#define SMSC9218I_IRQ_CFG_IRQ_TYPE SMSC9218I_FLAG(0)
/** @} */
/**
* @name Interrupt Status
* @{
*/
#define SMSC9218I_INT_STS_SW SMSC9218I_FLAG(31)
#define SMSC9218I_INT_STS_TXSTOP SMSC9218I_FLAG(25)
#define SMSC9218I_INT_STS_RXSTOP SMSC9218I_FLAG(24)
#define SMSC9218I_INT_STS_RXDFH SMSC9218I_FLAG(23)
#define SMSC9218I_INT_STS_TIOC SMSC9218I_FLAG(21)
#define SMSC9218I_INT_STS_RXD SMSC9218I_FLAG(20)
#define SMSC9218I_INT_STS_GPT SMSC9218I_FLAG(19)
#define SMSC9218I_INT_STS_PHY SMSC9218I_FLAG(18)
#define SMSC9218I_INT_STS_PME SMSC9218I_FLAG(17)
#define SMSC9218I_INT_STS_TXSO SMSC9218I_FLAG(16)
#define SMSC9218I_INT_STS_RWT SMSC9218I_FLAG(15)
#define SMSC9218I_INT_STS_RXE SMSC9218I_FLAG(14)
#define SMSC9218I_INT_STS_TXE SMSC9218I_FLAG(13)
#define SMSC9218I_INT_STS_TDFO SMSC9218I_FLAG(10)
#define SMSC9218I_INT_STS_TDFA SMSC9218I_FLAG(9)
#define SMSC9218I_INT_STS_TSFF SMSC9218I_FLAG(8)
#define SMSC9218I_INT_STS_TSFL SMSC9218I_FLAG(7)
#define SMSC9218I_INT_STS_RSFF SMSC9218I_FLAG(4)
#define SMSC9218I_INT_STS_RSFL SMSC9218I_FLAG(3)
#define SMSC9218I_INT_STS_GPIO2 SMSC9218I_FLAG(2)
#define SMSC9218I_INT_STS_GPIO1 SMSC9218I_FLAG(1)
#define SMSC9218I_INT_STS_GPIO0 SMSC9218I_FLAG(0)
/** @} */
/**
* @name Interrupt Enable
* @{
*/
#define SMSC9218I_INT_EN_SW SMSC9218I_FLAG(31)
#define SMSC9218I_INT_EN_TXSTOP SMSC9218I_FLAG(25)
#define SMSC9218I_INT_EN_RXSTOP SMSC9218I_FLAG(24)
#define SMSC9218I_INT_EN_RXDFH SMSC9218I_FLAG(23)
#define SMSC9218I_INT_EN_TIOC SMSC9218I_FLAG(21)
#define SMSC9218I_INT_EN_RXD SMSC9218I_FLAG(20)
#define SMSC9218I_INT_EN_GPT SMSC9218I_FLAG(19)
#define SMSC9218I_INT_EN_PHY SMSC9218I_FLAG(18)
#define SMSC9218I_INT_EN_PME SMSC9218I_FLAG(17)
#define SMSC9218I_INT_EN_TXSO SMSC9218I_FLAG(16)
#define SMSC9218I_INT_EN_RWT SMSC9218I_FLAG(15)
#define SMSC9218I_INT_EN_RXE SMSC9218I_FLAG(14)
#define SMSC9218I_INT_EN_TXE SMSC9218I_FLAG(13)
#define SMSC9218I_INT_EN_TDFO SMSC9218I_FLAG(10)
#define SMSC9218I_INT_EN_TDFA SMSC9218I_FLAG(9)
#define SMSC9218I_INT_EN_TSFF SMSC9218I_FLAG(8)
#define SMSC9218I_INT_EN_TSFL SMSC9218I_FLAG(7)
#define SMSC9218I_INT_EN_RSFF SMSC9218I_FLAG(4)
#define SMSC9218I_INT_EN_RSFL SMSC9218I_FLAG(3)
#define SMSC9218I_INT_EN_GPIO2 SMSC9218I_FLAG(2)
#define SMSC9218I_INT_EN_GPIO1 SMSC9218I_FLAG(1)
#define SMSC9218I_INT_EN_GPIO0 SMSC9218I_FLAG(0)
/** @} */
/**
* @name Byte Order Testing
* @{
*/
#define SMSC9218I_BYTE_TEST SMSC9218I_SWAP(0x87654321U)
/** @} */
/**
* @name FIFO Level Interrupts
* @{
*/
#define SMSC9218I_FIFO_INT_TDAL(val) SMSC9218I_FIELD_8(val, 24)
#define SMSC9218I_FIFO_INT_GET_TDAL(reg) SMSC9218I_GET_FIELD_8(reg, 24)
#define SMSC9218I_FIFO_INT_TSL(val) SMSC9218I_FIELD_8(val, 16)
#define SMSC9218I_FIFO_INT_GET_TSL(reg) SMSC9218I_GET_FIELD_8(reg, 16)
#define SMSC9218I_FIFO_INT_RSL(val) SMSC9218I_FIELD_8(val, 0)
#define SMSC9218I_FIFO_INT_GET_RSL(reg) SMSC9218I_GET_FIELD_8(reg, 0)
/** @} */
/**
* @name Receive Configuration
* @{
*/
#define SMSC9218I_RX_CFG_END_ALIGN_4 0
#define SMSC9218I_RX_CFG_END_ALIGN_16 SMSC9218I_FLAG(30)
#define SMSC9218I_RX_CFG_END_ALIGN_32 SMSC9218I_FLAG(31)
#define SMSC9218I_RX_CFG_DMA_CNT(val) SMSC9218I_FIELD_8(val, 24)
#define SMSC9218I_RX_CFG_GET_DMA_CNT(reg) SMSC9218I_GET_FIELD_8(reg, 24)
#define SMSC9218I_RX_CFG_DUMP SMSC9218I_FLAG(15)
#define SMSC9218I_RX_CFG_DOFF(val) SMSC9218I_FIELD_8(val, 8)
#define SMSC9218I_RX_CFG_GET_DOFF(reg) SMSC9218I_GET_FIELD_8(reg, 8)
/** @} */
/**
* @name Transmit Configuration
* @{
*/
#define SMSC9218I_TX_CFG_SDUMP SMSC9218I_FLAG(15)
#define SMSC9218I_TX_CFG_DDUMP SMSC9218I_FLAG(14)
#define SMSC9218I_TX_CFG_SAO SMSC9218I_FLAG(2)
#define SMSC9218I_TX_CFG_ON SMSC9218I_FLAG(1)
#define SMSC9218I_TX_CFG_STOP SMSC9218I_FLAG(0)
/** @} */
/**
* @name Hardware Configuration
* @{
*/
#define SMSC9218I_HW_CFG_AMDIX SMSC9218I_FLAG(24)
#define SMSC9218I_HW_CFG_MBO SMSC9218I_FLAG(20)
#define SMSC9218I_HW_CFG_TX_FIF_SZ(val) SMSC9218I_FIELD_8(val, 16)
#define SMSC9218I_HW_CFG_GET_TX_FIF_SZ(reg) SMSC9218I_GET_FIELD_8(reg, 16)
#define SMSC9218I_HW_CFG_BITMD_32 SMSC9218I_FLAG(2)
#define SMSC9218I_HW_CFG_SRST_TO SMSC9218I_FLAG(1)
#define SMSC9218I_HW_CFG_SRST SMSC9218I_FLAG(0)
/** @} */
/**
* @name Receive Datapath Control
* @{
*/
#define SMSC9218I_RX_DP_CTRL_FFWD SMSC9218I_FLAG(31)
/** @} */
/**
* @name Receive FIFO Information
* @{
*/
#define SMSC9218I_RX_FIFO_INF_GET_SUSED(reg) SMSC9218I_GET_FIELD_8(reg, 16)
#define SMSC9218I_RX_FIFO_INF_GET_DUSED(reg) SMSC9218I_GET_FIELD_16(reg, 0)
/** @} */
/**
* @name Transmit FIFO Information
* @{
*/
#define SMSC9218I_TX_FIFO_INF_GET_SUSED(reg) SMSC9218I_GET_FIELD_8(reg, 16)
#define SMSC9218I_TX_FIFO_INF_GET_FREE(reg) SMSC9218I_GET_FIELD_16(reg, 0)
/** @} */
/**
* @name Power Management Control
* @{
*/
#define SMSC9218I_PMT_CTRL_PM_MODE_D0 0
#define SMSC9218I_PMT_CTRL_PM_MODE_D1 SMSC9218I_FLAG(12)
#define SMSC9218I_PMT_CTRL_PM_MODE_D2 SMSC9218I_FLAG(13)
#define SMSC9218I_PMT_CTRL_PHY_RST SMSC9218I_FLAG(10)
#define SMSC9218I_PMT_CTRL_WOL_EN SMSC9218I_FLAG(9)
#define SMSC9218I_PMT_CTRL_ED_EN SMSC9218I_FLAG(8)
#define SMSC9218I_PMT_CTRL_PME_TYPE_PUPU SMSC9218I_FLAG(6)
#define SMSC9218I_PMT_CTRL_WUPS_NO 0
#define SMSC9218I_PMT_CTRL_WUPS_ENERGY SMSC9218I_FLAG(4)
#define SMSC9218I_PMT_CTRL_WUPS_MAGIC SMSC9218I_FLAG(5)
#define SMSC9218I_PMT_CTRL_PME_IND SMSC9218I_FLAG(3)
#define SMSC9218I_PMT_CTRL_PME_POL SMSC9218I_FLAG(2)
#define SMSC9218I_PMT_CTRL_PME_EN SMSC9218I_FLAG(1)
#define SMSC9218I_PMT_CTRL_READY SMSC9218I_FLAG(0)
/** @} */
/**
* @name General Purpose IO Configuration
* @{
*/
#define SMSC9218I_GPIO_CFG_LED3 SMSC9218I_FLAG(30)
#define SMSC9218I_GPIO_CFG_LED2 SMSC9218I_FLAG(29)
#define SMSC9218I_GPIO_CFG_LED1 SMSC9218I_FLAG(28)
#define SMSC9218I_GPIO_CFG_GPIO2_INT_POL SMSC9218I_FLAG(26)
#define SMSC9218I_GPIO_CFG_GPIO1_INT_POL SMSC9218I_FLAG(25)
#define SMSC9218I_GPIO_CFG_GPIO0_INT_POL SMSC9218I_FLAG(24)
#define SMSC9218I_GPIO_CFG_GPIOBUF2 SMSC9218I_FLAG(18)
#define SMSC9218I_GPIO_CFG_GPIOBUF1 SMSC9218I_FLAG(17)
#define SMSC9218I_GPIO_CFG_GPIOBUF0 SMSC9218I_FLAG(16)
#define SMSC9218I_GPIO_CFG_GPIODIR2 SMSC9218I_FLAG(10)
#define SMSC9218I_GPIO_CFG_GPIODIR1 SMSC9218I_FLAG(9)
#define SMSC9218I_GPIO_CFG_GPIODIR0 SMSC9218I_FLAG(8)
#define SMSC9218I_GPIO_CFG_GPO4 SMSC9218I_FLAG(4)
#define SMSC9218I_GPIO_CFG_GPO3 SMSC9218I_FLAG(3)
#define SMSC9218I_GPIO_CFG_GPIO0 SMSC9218I_FLAG(0)
#define SMSC9218I_GPIO_CFG_GPIO2 SMSC9218I_FLAG(2)
#define SMSC9218I_GPIO_CFG_GPIO1 SMSC9218I_FLAG(1)
/** @} */
/**
* @name General Purpose Timer Configuration
* @{
*/
#define SMSC9218I_GPT_CFG_TIMER_EN SMSC9218I_FLAG(29)
#define SMSC9218I_GPT_CFG_LOAD(val) SMSC9218I_FIELD_16(val, 0)
#define SMSC9218I_GPT_CFG_GET_LOAD(reg) SMSC9218I_GET_FIELD_16(reg, 0)
/** @} */
/**
* @name General Purpose Timer Count
* @{
*/
#define SMSC9218I_GPT_CNT_GET_CNT SMSC9218I_GET_FIELD_16(reg, 0)
/** @} */
/**
* @name Word Swap
* @{
*/
#define SMSC9218I_ENDIAN_BIG 0xffffffffU
/** @} */
/**
* @name Free Run Counter
* @{
*/
#define SMSC9218I_FREE_RUN_GET(reg) SMSC9218I_SWAP(reg)
/** @} */
/**
* @name Receiver Dropped Frames Counter
* @{
*/
#define SMSC9218I_RX_DROP_GET(reg) SMSC9218I_SWAP(reg)
/** @} */
/**
* @name MAC Control and Status Synchronizer Command
* @{
*/
#define SMSC9218I_MAC_CSR_CMD_BUSY SMSC9218I_FLAG(31)
#define SMSC9218I_MAC_CSR_CMD_READ SMSC9218I_FLAG(30)
#define SMSC9218I_MAC_CSR_CMD_ADDR(val) SMSC9218I_FIELD_8(val, 0)
#define SMSC9218I_MAC_CSR_CMD_GET_ADDR(reg) SMSC9218I_GET_FIELD_8(reg, 0)
/** @} */
/**
* @name MAC Control Register
* @{
*/
#define SMSC9218I_MAC_CR 0x00000001U
#define SMSC9218I_MAC_CR_RXALL 0x80000000U
#define SMSC9218I_MAC_CR_HBDIS 0x10000000U
#define SMSC9218I_MAC_CR_RCVOWN 0x00800000U
#define SMSC9218I_MAC_CR_LOOPBK 0x00200000U
#define SMSC9218I_MAC_CR_FDPX 0x00100000U
#define SMSC9218I_MAC_CR_MCPAS 0x00080000U
#define SMSC9218I_MAC_CR_PRMS 0x00040000U
#define SMSC9218I_MAC_CR_INVFILT 0x00020000U
#define SMSC9218I_MAC_CR_PASSBAD 0x00010000U
#define SMSC9218I_MAC_CR_HFILT 0x00008000U
#define SMSC9218I_MAC_CR_HPFILT 0x00002000U
#define SMSC9218I_MAC_CR_LCOLL 0x00001000U
#define SMSC9218I_MAC_CR_BCAST 0x00000800U
#define SMSC9218I_MAC_CR_DISRTY 0x00000400U
#define SMSC9218I_MAC_CR_PADSTR 0x00000100U
#define SMSC9218I_MAC_CR_BOLMT_MASK 0x000000c0U
#define SMSC9218I_MAC_CR_BOLMT_10 0x00000000U
#define SMSC9218I_MAC_CR_BOLMT_8 0x00000040U
#define SMSC9218I_MAC_CR_BOLMT_4 0x00000080U
#define SMSC9218I_MAC_CR_BOLMT_1 0x000000c0U
#define SMSC9218I_MAC_CR_DFCHK 0x00000020U
#define SMSC9218I_MAC_CR_TXEN 0x00000008U
#define SMSC9218I_MAC_CR_RXEN 0x00000004U
/** @} */
/**
* @name MAC Address High
* @{
*/
#define SMSC9218I_MAC_ADDRH 0x00000002U
#define SMSC9218I_MAC_ADDRH_MASK 0x0000ffffU
/** @} */
/**
* @name MAC Address Low
* @{
*/
#define SMSC9218I_MAC_ADDRL 0x00000003U
#define SMSC9218I_MAC_ADDRL_MASK 0xffffffffU
/** @} */
/**
* @name Multicast Hash Table High
* @{
*/
#define SMSC9218I_MAC_HASHH 0x00000004U
#define SMSC9218I_MAC_HASHH_MASK 0xffffffffU
/** @} */
/**
* @name Multicast Hash Table Low
* @{
*/
#define SMSC9218I_MAC_HASHL 0x00000005U
#define SMSC9218I_MAC_HASHL_MASK 0xffffffffU
/** @} */
/**
* @name MII Access
* @{
*/
#define SMSC9218I_MAC_MII_ACC 0x00000006U
#define SMSC9218I_MAC_MII_ACC_PHY_DEFAULT (1U << 11)
#define SMSC9218I_MAC_MII_ACC_WRITE (1U << 1)
#define SMSC9218I_MAC_MII_ACC_BUSY (1U << 0)
#define SMSC9218I_MAC_MII_ACC_ADDR(addr) ((addr) << 6)
/** @} */
/**
* @name MII Data
* @{
*/
#define SMSC9218I_MAC_MII_DATA 0x00000007U
/** @} */
/**
* @name Flow Control
* @{
*/
#define SMSC9218I_MAC_FLOW 0x00000008U
#define SMSC9218I_MAC_FLOW_FCPT_MASK 0xffff0000U
#define SMSC9218I_MAC_FLOW_FCPASS 0x00000004U
#define SMSC9218I_MAC_FLOW_FCEN 0x00000002U
#define SMSC9218I_MAC_FLOW_FCBSY 0x00000001U
/** @} */
/**
* @name VLAN1 Tag
* @{
*/
#define SMSC9218I_MAC_VLAN1 0x00000009U
/** @} */
/**
* @name VLAN2 Tag
* @{
*/
#define SMSC9218I_MAC_VLAN2 0x0000000aU
/** @} */
/**
* @name Wake-up Frame Filter
* @{
*/
#define SMSC9218I_MAC_WUFF 0x0000000bU
/** @} */
/**
* @name Wake-up Control and Status
* @{
*/
#define SMSC9218I_MAC_WUCSR 0x0000000cU
#define SMSC9218I_MAC_WUCSR_GUE 0x00000200U
#define SMSC9218I_MAC_WUCSR_WUFR 0x00000040U
#define SMSC9218I_MAC_WUCSR_MPR 0x00000020U
#define SMSC9218I_MAC_WUCSR_WUEN 0x00000004U
#define SMSC9218I_MAC_WUCSR_MPEN 0x00000002U
/** @} */
/**
* @name Basic Control
* @{
*/
#define SMSC9218I_PHY_BCR 0x00000000U
#define SMSC9218I_PHY_BCR_RST 0x00008000U
#define SMSC9218I_PHY_BCR_LOOPBK 0x00004000U
#define SMSC9218I_PHY_BCR_SS 0x00002000U
#define SMSC9218I_PHY_BCR_ANE 0x00001000U
#define SMSC9218I_PHY_BCR_PWRDN 0x00000800U
#define SMSC9218I_PHY_BCR_RSTAN 0x00000200U
#define SMSC9218I_PHY_BCR_FDPLX 0x00000100U
#define SMSC9218I_PHY_BCR_COLLTST 0x00000080U
/** @} */
/**
* @name Basic Status
* @{
*/
#define SMSC9218I_PHY_BSR 0x00000001U
#define SMSC9218I_PHY_BSR_100_T4_ABLE 0x00008000U
#define SMSC9218I_PHY_BSR_100_TX_FDPLX 0x00004000U
#define SMSC9218I_PHY_BSR_100_TX_HDPLX 0x00002000U
#define SMSC9218I_PHY_BSR_10_FDPLX 0x00001000U
#define SMSC9218I_PHY_BSR_10_HDPLX 0x00000800U
#define SMSC9218I_PHY_BSR_ANC 0x00000020U
#define SMSC9218I_PHY_BSR_REM_FAULT 0x00000010U
#define SMSC9218I_PHY_BSR_AN_ABLE 0x00000008U
#define SMSC9218I_PHY_BSR_LINK_STATUS 0x00000004U
#define SMSC9218I_PHY_BSR_JAB_DET 0x00000002U
#define SMSC9218I_PHY_BSR_EXT_CAP 0x00000001U
/** @} */
/**
* @name PHY Identifier 1
* @{
*/
#define SMSC9218I_PHY_ID1 0x00000002U
#define SMSC9218I_PHY_ID1_MASK 0x0000ffffU
#define SMSC9218I_PHY_ID1_LAN9118 0x00000007U
#define SMSC9218I_PHY_ID1_LAN9218 (PHY_ID1_LAN9118)
/** @} */
/**
* @name PHY Identifier 2
* @{
*/
#define SMSC9218I_PHY_ID2 0x00000003U
#define SMSC9218I_PHY_ID2_MASK 0x0000ffffU
#define SMSC9218I_PHY_ID2_MODEL_MASK 0x000003f0U
#define SMSC9218I_PHY_ID2_REV_MASK 0x0000000fU
#define SMSC9218I_PHY_ID2_LAN9118 0x0000c0d1U
#define SMSC9218I_PHY_ID2_LAN9218 0x0000c0c3U
/** @} */
/**
* @name Auto-negotiation Advertisment
* @{
*/
#define SMSC9218I_PHY_ANAR 0x00000004U
#define SMSC9218I_PHY_ANAR_NXTPG_CAP 0x00008000U
#define SMSC9218I_PHY_ANAR_REM_FAULT 0x00002000U
#define SMSC9218I_PHY_ANAR_PAUSE_OP_MASK 0x00000c00U
#define SMSC9218I_PHY_ANAR_PAUSE_OP_NONE 0x00000000U
#define SMSC9218I_PHY_ANAR_PAUSE_OP_ASLP 0x00000400U
#define SMSC9218I_PHY_ANAR_PAUSE_OP_SLP 0x00000800U
#define SMSC9218I_PHY_ANAR_PAUSE_OP_BOTH 0x00000c00U
#define SMSC9218I_PHY_ANAR_100_T4_ABLE 0x00000200U
#define SMSC9218I_PHY_ANAR_100_TX_FDPLX 0x00000100U
#define SMSC9218I_PHY_ANAR_100_TX_ABLE 0x00000080U
#define SMSC9218I_PHY_ANAR_10_FDPLX 0x00000040U
#define SMSC9218I_PHY_ANAR_10_ABLE 0x00000020U
/** @} */
/**
* @name Auto-negotiation Link Partner Ability
* @{
*/
#define SMSC9218I_PHY_ANLPAR 0x00000005U
#define SMSC9218I_PHY_ANLPAR_NXTPG_CAP 0x00008000U
#define SMSC9218I_PHY_ANLPAR_ACK 0x00004000U
#define SMSC9218I_PHY_ANLPAR_REM_FAULT 0x00002000U
#define SMSC9218I_PHY_ANLPAR_PAUSE_CAP 0x00000400U
#define SMSC9218I_PHY_ANLPAR_100_T4_ABLE 0x00000200U
#define SMSC9218I_PHY_ANLPAR_100_TX_FDPLX 0x00000100U
#define SMSC9218I_PHY_ANLPAR_100_TX_ABLE 0x00000080U
#define SMSC9218I_PHY_ANLPAR_10_FDPLX 0x00000040U
#define SMSC9218I_PHY_ANLPAR_10_ABLE 0x00000020U
/** @} */
/**
* @name Auto-negotiation Expansion
* @{
*/
#define SMSC9218I_PHY_ANEXPR 0x00000006U
#define SMSC9218I_PHY_ANEXPR_PARDET_FAULT 0x00000010U
#define SMSC9218I_PHY_ANEXPR_LP_NXTPG_CAP 0x00000008U
#define SMSC9218I_PHY_ANEXPR_NXTPG_CAP 0x00000004U
#define SMSC9218I_PHY_ANEXPR_NEWPG_REC 0x00000002U
#define SMSC9218I_PHY_ANEXPR_LP_AN_ABLE 0x00000001U
/** @} */
/**
* @name Mode Control and Status
* @{
*/
#define SMSC9218I_PHY_MCSR 0x00000011U
#define SMSC9218I_PHY_MCSR_EDPWRDOWN 0x00002000U
#define SMSC9218I_PHY_MCSR_ENERGYON 0x00000002U
/** @} */
/**
* @name Special Modes
* @{
*/
#define SMSC9218I_PHY_SPMODES 0x00000012U
/** @} */
/**
* @name Special Control and Status Indications
* @{
*/
#define SMSC9218I_PHY_CSIR 0x0000001bU
#define SMSC9218I_PHY_CSIR_SQEOFF 0x00000800U
#define SMSC9218I_PHY_CSIR_FEFIEN 0x00000020U
#define SMSC9218I_PHY_CSIR_XPOL 0x00000010U
/** @} */
/**
* @name Interrupt Source Flag
* @{
*/
#define SMSC9218I_PHY_ISR 0x0000001dU
#define SMSC9218I_PHY_ISR_INT7 0x00000080U
#define SMSC9218I_PHY_ISR_INT6 0x00000040U
#define SMSC9218I_PHY_ISR_INT5 0x00000020U
#define SMSC9218I_PHY_ISR_INT4 0x00000010U
#define SMSC9218I_PHY_ISR_INT3 0x00000008U
#define SMSC9218I_PHY_ISR_INT2 0x00000004U
#define SMSC9218I_PHY_ISR_INT1 0x00000002U
/** @} */
/**
* @name Interrupt Mask
* @{
*/
#define SMSC9218I_PHY_IMR 0x0000001eU
#define SMSC9218I_PHY_IMR_INT7 0x00000080U
#define SMSC9218I_PHY_IMR_INT6 0x00000040U
#define SMSC9218I_PHY_IMR_INT5 0x00000020U
#define SMSC9218I_PHY_IMR_INT4 0x00000010U
#define SMSC9218I_PHY_IMR_INT3 0x00000008U
#define SMSC9218I_PHY_IMR_INT2 0x00000004U
#define SMSC9218I_PHY_IMR_INT1 0x00000002U
/** @} */
/**
* @name PHY Special Control and Status
* @{
*/
#define SMSC9218I_PHY_PHYSCSR 0x0000001fU
#define SMSC9218I_PHY_PHYSCSR_ANDONE 0x00001000U
#define SMSC9218I_PHY_PHYSCSR_4B5B_EN 0x00000040U
#define SMSC9218I_PHY_PHYSCSR_SPEED_MASK 0x0000001cU
#define SMSC9218I_PHY_PHYSCSR_SPEED_10HD 0x00000004U
#define SMSC9218I_PHY_PHYSCSR_SPEED_10FD 0x00000014U
#define SMSC9218I_PHY_PHYSCSR_SPEED_100HD 0x00000008U
#define SMSC9218I_PHY_PHYSCSR_SPEED_100FD 0x00000018U
/** @} */

File diff suppressed because it is too large Load Diff

View File

@@ -85,10 +85,22 @@ $(PROJECT_INCLUDE)/bsp/irq-config.h: include/irq-config.h $(PROJECT_INCLUDE)/bsp
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-config.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-config.h
$(PROJECT_INCLUDE)/bsp/smsc9218i.h: include/smsc9218i.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/smsc9218i.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/smsc9218i.h
$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-generic.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
$(PROJECT_INCLUDE)/bsp/irq-info.h: ../../shared/include/irq-info.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-info.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-info.h
$(PROJECT_INCLUDE)/bsp/utility.h: ../../shared/include/utility.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/utility.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/utility.h
$(PROJECT_INCLUDE)/bsp/tictac.h: ../shared/include/tictac.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/tictac.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/tictac.h

View File

@@ -92,28 +92,11 @@ void bsp_predriver_hook()
static void mpc55xx_ebi_init()
{
struct EBI_CS_tag cs = { BR : MPC55XX_ZERO_FLAGS, OR : MPC55XX_ZERO_FLAGS };
struct EBI_CS_tag cs = { .BR = MPC55XX_ZERO_FLAGS, .OR = MPC55XX_ZERO_FLAGS };
union SIU_PCR_tag pcr = MPC55XX_ZERO_FLAGS;
struct MMU_tag mmu = MMU_DEFAULT;
int i = 0;
/* External SRAM (0 wait states, 512kB, 4 word burst) */
cs.BR.B.BA = 0;
cs.BR.B.PS = 1;
cs.BR.B.BL = 1;
cs.BR.B.WEBS = 0;
cs.BR.B.TBDIP = 0;
cs.BR.B.BI = 1; /* TODO: Enable burst */
cs.BR.B.V = 1;
cs.OR.B.AM = 0x1fff0;
cs.OR.B.SCY = 0;
cs.OR.B.BSCY = 0;
EBI.CS [0] = cs;
/* !CS [0] */
SIU.PCR [0].R = 0x443;
/* ADDR [8 : 31] */
for (i = 4; i < 4 + 24; ++i) {
SIU.PCR [i].R = 0x440;
@@ -140,6 +123,64 @@ static void mpc55xx_ebi_init()
/* !TS */
SIU.PCR [69].R = 0x443;
/* External SRAM (2 wait states, 512kB, 4 word burst) */
cs.BR.B.BA = 0;
cs.BR.B.PS = 1;
cs.BR.B.BL = 1;
cs.BR.B.WEBS = 0;
cs.BR.B.TBDIP = 0;
cs.BR.B.BI = 1; /* TODO: Enable burst */
cs.BR.B.V = 1;
cs.OR.B.AM = 0x1fff0;
cs.OR.B.SCY = 0;
cs.OR.B.BSCY = 0;
EBI.CS [0] = cs;
/* !CS [0] */
SIU.PCR [0].R = 0x443;
/* External Ethernet Controller (3 wait states, 64kB) */
mmu.MAS0.B.ESEL = 5;
mmu.MAS1.B.VALID = 1;
mmu.MAS1.B.IPROT = 1;
mmu.MAS1.B.TSIZ = 1;
mmu.MAS2.B.EPN = 0x3fff8;
mmu.MAS2.B.I = 1;
mmu.MAS2.B.G = 1;
mmu.MAS3.B.RPN = 0x3fff8;
mmu.MAS3.B.UW = 1;
mmu.MAS3.B.SW = 1;
mmu.MAS3.B.UR = 1;
mmu.MAS3.B.SR = 1;
PPC_SET_SPECIAL_PURPOSE_REGISTER( FREESCALE_EIS_MAS0, mmu.MAS0.R);
PPC_SET_SPECIAL_PURPOSE_REGISTER( FREESCALE_EIS_MAS1, mmu.MAS1.R);
PPC_SET_SPECIAL_PURPOSE_REGISTER( FREESCALE_EIS_MAS2, mmu.MAS2.R);
PPC_SET_SPECIAL_PURPOSE_REGISTER( FREESCALE_EIS_MAS3, mmu.MAS3.R);
asm volatile ("tlbwe");
cs.BR.B.BA = 0x7fff;
cs.BR.B.PS = 1;
cs.BR.B.BL = 0;
cs.BR.B.WEBS = 0;
cs.BR.B.TBDIP = 0;
cs.BR.B.BI = 1;
cs.BR.B.V = 1;
cs.OR.B.AM = 0x1ffff;
cs.OR.B.SCY = 1;
cs.OR.B.BSCY = 0;
EBI.CS [3] = cs;
/* !CS [3] */
SIU.PCR [3].R = 0x443;
}
/**
@@ -198,7 +239,8 @@ void bsp_start(void)
DEBUG_DONE();
}
RTEMS_DEBUG_PRINT( "BSP start done\n");
/* Initialize eMIOS */
mpc55xx_emios_initialize( 1);
return;

View File

@@ -18,20 +18,16 @@
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
*/
#include <stdio.h>
#include <stdio.h>
#include <mpc55xx/mpc55xx.h>
#include <mpc55xx/regs.h>
#include <mpc55xx/dspi.h>
#include <libchip/spi-sd-card.h>
#define DEBUG
#include <bsp.h>
#include <rtems/status-checks.h>
#include <bsp.h>
static rtems_status_code mpc55xx_dspi_init(void)
{
int rv = 0;
@@ -88,17 +84,14 @@ static rtems_status_code mpc55xx_dspi_init(void)
return RTEMS_SUCCESSFUL;
}
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdio.h>
#include <rtems/fsmount.h>
#include <rtems/dosfs.h>
#include <rtems/ide_part_table.h>
#include <rtems/bdpart.h>
#include <rtems/console.h>
#include <libchip/spi-sd-card.h>
#define MPC55XX_DEVICE "sd-card-a"
#define MPC55XX_DEVICE_FILE "/dev/" MPC55XX_DEVICE
#define MPC55XX_PARTITION "/dev/sd-card-a1"
@@ -117,21 +110,10 @@ static fstab_t mpc55xx_fs_table [] = { {
}
};
#define SD_CARD_NUMBER 1
sd_card_driver_entry sd_card_driver_table [SD_CARD_NUMBER] = { {
#if 0
.driver = {
.ops = &sd_card_driver_ops,
.size = sizeof( sd_card_driver_entry)
},
.table_index = 0,
.minor = 0,
#endif
.device_name = "sd-card-a",
#if 0
.disk_device_name = "/dev/sd-card-a",
#endif
sd_card_driver_entry sd_card_driver_table [] = {
{
.device_name = "/dev/sd-card-a",
.bus = 0,
.transfer_mode = SD_CARD_TRANSFER_MODE_DEFAULT,
.command = SD_CARD_COMMAND_DEFAULT,
/* response : whatever, */
@@ -140,13 +122,15 @@ sd_card_driver_entry sd_card_driver_table [SD_CARD_NUMBER] = { {
.block_number = 0,
.block_size = 0,
.block_size_shift = 0,
.busy = 1,
.verbose = 1,
.schedule_if_busy = 0,
.busy = true,
.verbose = true,
.schedule_if_busy = false
}
};
rtems_status_code mpc55xx_sd_card_init(void)
size_t sd_card_driver_table_size = sizeof( sd_card_driver_table) / sizeof( sd_card_driver_table [0]);
rtems_status_code mpc55xx_sd_card_init( bool mount)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
int rv = 0;
@@ -157,17 +141,18 @@ rtems_status_code mpc55xx_sd_card_init(void)
sc = mpc55xx_dspi_init();
RTEMS_CHECK_SC( rv, "Intitalize DSPI bus");
rv = rtems_libi2c_register_drv( e->device_name, (rtems_libi2c_drv_t *) e, mpc55xx_dspi_bus_table [0].bus_number, 0);
RTEMS_CHECK_RV_SC( rv, "Register SD Card driver");
e->bus = mpc55xx_dspi_bus_table [0].bus_number;
sc = rtems_ide_part_table_initialize( MPC55XX_DEVICE_FILE);
RTEMS_CHECK_SC( sc, "Initialize IDE partition table");
sc = sd_card_register();
RTEMS_CHECK_SC( sc, "Register SD Card");
rv = mkdir( MPC55XX_MOUNT_POINT, S_IRWXU);
RTEMS_CHECK_RV_SC( rv, "Create mount point");
if (mount) {
sc = rtems_bdpart_register_from_disk( MPC55XX_DEVICE_FILE);
RTEMS_CHECK_SC( sc, "Initialize IDE partition table");
rv = rtems_fsmount( mpc55xx_fs_table, sizeof( mpc55xx_fs_table) / sizeof( mpc55xx_fs_table [0]), NULL);
RTEMS_CHECK_RV_SC( rv, "Mount file systems");
rv = rtems_fsmount( mpc55xx_fs_table, sizeof( mpc55xx_fs_table) / sizeof( mpc55xx_fs_table [0]), NULL);
RTEMS_CHECK_RV_SC( rv, "Mount file systems");
}
return RTEMS_SUCCESSFUL;
}

View File

@@ -36,8 +36,6 @@
#include <libcpu/powerpc-utility.h>
/* #define DEBUG */
#include <rtems/status-checks.h>
static rtems_driver_address_table test_mpc55xx_drv_ops = {
@@ -216,7 +214,10 @@ rtems_status_code mpc55xx_dspi_register(void)
union SIU_PCR_tag pcr = MPC55XX_ZERO_FLAGS;
printk( "Boot time: %u\n", ppc_time_base());
/*
test_mpc55xx_intc( 0);
*/
rv = rtems_libi2c_initialize();
RTEMS_CHECK_RV_SC( rv, "rtems_libi2c_initialize");
@@ -268,7 +269,7 @@ rtems_status_code mpc55xx_dspi_register(void)
sc = rtems_semaphore_create (
rtems_build_name ( 'P', 'I', 'N', 'G'),
1,
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_PRIORITY,
RTEMS_NO_PRIORITY,
&test_mpc55xx_dspi_ping
);
@@ -277,7 +278,7 @@ rtems_status_code mpc55xx_dspi_register(void)
sc = rtems_semaphore_create (
rtems_build_name ( 'P', 'O', 'N', 'G'),
0,
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_PRIORITY,
RTEMS_NO_PRIORITY,
&test_mpc55xx_dspi_pong
);
@@ -325,6 +326,8 @@ rtems_status_code mpc55xx_dspi_register(void)
sc = rtems_task_start( sd_card_task_id, test_sd_card, 0);
RTEMS_CHECK_SC( sc, "rtems_task_start");
return RTEMS_SUCCESSFUL;
rtems_id intc_id;
sc = rtems_task_create(
rtems_build_name( 'I', 'N', 'T', 'C'),
@@ -338,12 +341,11 @@ rtems_status_code mpc55xx_dspi_register(void)
sc = rtems_task_start( intc_id, test_mpc55xx_intc, 0);
RTEMS_CHECK_SC( sc, "rtems_task_start");
sc = rtems_task_delete( RTEMS_SELF);
RTEMS_CHECK_SC( sc, "rtems_task_delete");
return RTEMS_SUCCESSFUL;
}
#if 0
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -421,35 +423,6 @@ static int test_sd_card_print_dir( const char* dirname, unsigned level)
return 0;
}
#define SD_CARD_NUMBER 1
static sd_card_driver_entry sd_card_driver_table_XXX [SD_CARD_NUMBER] = { {
#if 0
driver : {
ops : &sd_card_driver_ops,
size : sizeof( sd_card_driver_entry)
},
table_index : 0,
minor : 0,
#endif
device_name : "sd-card-a",
#if 0
disk_device_name : "/dev/sd-card-a",
#endif
transfer_mode : SD_CARD_TRANSFER_MODE_DEFAULT,
command : SD_CARD_COMMAND_DEFAULT,
/* response : whatever, */
response_index : SD_CARD_COMMAND_SIZE,
n_ac_max : SD_CARD_N_AC_MAX_DEFAULT,
block_number : 0,
block_size : 0,
block_size_shift : 0,
busy : 1,
verbose : 1,
schedule_if_busy : 0,
}
};
rtems_task test_sd_card( rtems_task_argument arg)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
@@ -484,17 +457,19 @@ rtems_task test_sd_card( rtems_task_argument arg)
sc = rtems_ide_part_table_initialize( TEST_SD_CARD_DEVICE_FILE);
RTEMS_CHECK_SC_TASK( sc, "Initialize IDE partition table");
rv = test_sd_card_print_dir( "/dev", 0);
RTEMS_CHECK_RV_TASK( rv, "Print directory");
rv = mkdir( TEST_SD_CARD_MOUNT_POINT, S_IRWXU);
RTEMS_CHECK_RV_TASK( rv, "Create mount point");
rv = rtems_fsmount( test_sd_card_fs_table, sizeof( test_sd_card_fs_table) / sizeof( test_sd_card_fs_table [0]), NULL);
RTEMS_CHECK_RV_TASK( rv, "Mount file systems");
/*rv = test_sd_card_print_dir( TEST_SD_CARD_MOUNT_POINT, 0); */
/*RTEMS_CHECK_RV_TASK( rv, "Print directory"); */
rv = test_sd_card_print_dir( "/dev", 0);
RTEMS_CHECK_RV_TASK( rv, "Print directory");
rv = test_sd_card_print_dir( TEST_SD_CARD_MOUNT_POINT, 0);
RTEMS_CHECK_RV_TASK( rv, "Print directory");
(void) rtems_task_delete( RTEMS_SELF);
rv = mkdir( TEST_SD_CARD_DIRECTORY, S_IRWXU);
@@ -523,6 +498,8 @@ rtems_task test_sd_card( rtems_task_argument arg)
rv = test_sd_card_print_dir( TEST_SD_CARD_DIRECTORY, 0);
RTEMS_CHECK_RV_TASK( rv, "Print directory");
(void) rtems_task_delete( RTEMS_SELF);
#if 0
/* Write */
@@ -561,35 +538,46 @@ rtems_task test_sd_card( rtems_task_argument arg)
RTEMS_CHECK_RV_TASK( rv, "close");
#endif
sc = rtems_task_delete( RTEMS_SELF);
RTEMS_CHECK_SC_TASK( sc, "rtems_task_delete");
(void) rtems_task_delete( RTEMS_SELF);
}
#endif
#define ITER 4
#define BUFSIZE (128 * ITER)
static char inbuf [BUFSIZE];
static char outbuf [BUFSIZE];
static void test_mpc55xx_edma_done( mpc55xx_edma_channel_entry *e, uint32_t error_status)
{
rtems_semaphore_release( e->id);
if (error_status != 0) {
printk( "%s: Error status: 0x%08x\n", __func__, error_status);
}
}
static rtems_status_code test_mpc55xx_edma(void)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
int rv = 0;
int channel = 0;
uint32_t error_status = 0;
rtems_id transfer_update;
mpc55xx_edma_channel_entry e = {
.channel = 0,
.done = test_mpc55xx_edma_done,
.id = RTEMS_ID_NONE
};
sc = rtems_semaphore_create (
rtems_build_name ( 'T', 'S', 'T', 'C'),
0,
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_PRIORITY,
RTEMS_NO_PRIORITY,
&transfer_update
&e.id
);
RTEMS_CHECK_SC( sc, "rtems_semaphore_create");
rv = mpc55xx_edma_obtain_channel( channel, &error_status, transfer_update);
RTEMS_CHECK_RV( rv, "mpc55xx_edma_obtain_channel");
sc = mpc55xx_edma_obtain_channel( &e);
RTEMS_CHECK_RV( sc, "mpc55xx_edma_obtain_channel");
int i = 0;
for (i = 0; i < BUFSIZE; ++i) {
@@ -599,39 +587,40 @@ static rtems_status_code test_mpc55xx_edma(void)
rtems_cache_flush_multiple_data_lines( inbuf, BUFSIZE);
rtems_cache_flush_multiple_data_lines( outbuf, BUFSIZE);
struct tcd_t tcd = MPC55XX_EDMA_TCD_DEFAULT;
struct tcd_t tcd = EDMA_TCD_DEFAULT;
tcd.SADDR = (uint32_t) &inbuf;
tcd.DADDR = (uint32_t) &outbuf;
tcd.NBYTES = BUFSIZE / ITER;
tcd.SLAST = -BUFSIZE;
tcd.CITER = ITER;
tcd.BITER = ITER;
tcd.INT_HALF = 1;
tcd.CDF.B.CITER = ITER;
tcd.BMF.B.BITER = ITER;
tcd.BMF.B.INT_HALF = 1;
EDMA.TCD [channel] = tcd;
EDMA.TCD [e.channel] = tcd;
while (1) {
while (1) {
if (EDMA.TCD [channel].DONE == 1) {
EDMA.TCD [channel].DONE = 0;
if (EDMA.TCD [e.channel].BMF.B.DONE == 1) {
EDMA.TCD [e.channel].BMF.B.DONE = 0;
printk( "%s: Done\n", __func__);
break;
} else if (EDMA.TCD [channel].ACTIVE == 0) {
EDMA.SSBR.R = channel;
printk( "%s: Start: %i (%i)\n", __func__, EDMA.TCD [channel].CITER, EDMA.TCD [channel].BITER);
} else if (EDMA.TCD [e.channel].BMF.B.ACTIVE == 0) {
EDMA.SSBR.R = e.channel;
printk( "%s: Start: %i (%i)\n", __func__, EDMA.TCD [e.channel].CDF.B.CITER, EDMA.TCD [e.channel].BMF.B.BITER);
}
sc = rtems_semaphore_obtain( transfer_update, RTEMS_WAIT, 10);
sc = rtems_semaphore_obtain( e.id, RTEMS_WAIT, 10);
if (sc == RTEMS_TIMEOUT) {
continue;
}
RTEMS_CHECK_SC( sc, "rtems_semaphore_obtain");
}
printk( "%s: Error status: 0x%08x\n", __func__, error_status);
}
return sc;
return RTEMS_SUCCESSFUL;
}
#include <stdlib.h>
static unsigned test_mpc55xx_intc_counter = 0;
static inline void test_mpc55xx_intc_worker( void *data)
@@ -667,11 +656,15 @@ static int test_mpc55xx_intc_handler_data [MPC55XX_IRQ_SOFTWARE_NUMBER];
static rtems_task test_mpc55xx_intc( rtems_task_argument arg)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
rtems_irq_connect_data e = {
.on = NULL,
.off = NULL,
.isOn = NULL
};
volatile int i = 0;
int p = 0;
unsigned s = 0;
rtems_irq_connect_data e;
rtems_status_code sc = RTEMS_SUCCESSFUL;
for (i = MPC55XX_IRQ_SOFTWARE_MIN, p = MPC55XX_INTC_MIN_PRIORITY; i <= MPC55XX_IRQ_SOFTWARE_MAX; ++i, ++p) {
test_mpc55xx_intc_handler_data [i] = i;
@@ -684,12 +677,12 @@ static rtems_task test_mpc55xx_intc( rtems_task_argument arg)
}
e.hdl = test_mpc55xx_intc_handler_2;
if (BSP_install_rtems_shared_irq_handler( &e) != RTEMS_SUCCESSFUL) {
if (BSP_install_rtems_shared_irq_handler( &e) != 1) {
BSP_panic( "Handler install 2 failed");
}
e.hdl = test_mpc55xx_intc_handler_3;
if (BSP_install_rtems_shared_irq_handler( &e) != RTEMS_SUCCESSFUL) {
if (BSP_install_rtems_shared_irq_handler( &e) != 1) {
BSP_panic( "Handler install 3 failed");
}
}

View File

@@ -1,3 +1,11 @@
2009-07-20 Sebastian Huber <sebastian.huber@embedded-brains.de>
* Makefile.am, preinstall.am: Update for MPC55XX changes.
* mpc55xx/emios/emios.c, mpc55xx/include/emios.h: New files.
* mpc55xx/dspi/dspi.c, mpc55xx/edma/edma.c, mpc55xx/esci/esci.c,
mpc55xx/include/dspi.h, mpc55xx/include/edma.h, mpc55xx/include/irq.h,
mpc55xx/include/regs.h, mpc55xx/irq/irq.c: Changes throughout.
2009-05-05 Jennifer Averett <jennifer.averett@OARcorp.com>
* mpc6xx/mmu/bat.c, new-exceptions/e500_raw_exc_init.c,

View File

@@ -419,6 +419,7 @@ include_mpc55xx_HEADERS = mpc55xx/include/regs.h \
mpc55xx/include/reg-defs.h \
mpc55xx/include/dspi.h \
mpc55xx/include/edma.h \
mpc55xx/include/emios.h \
mpc55xx/include/mpc55xx.h \
mpc55xx/include/esci.h \
mpc55xx/include/watchdog.h
@@ -433,12 +434,17 @@ noinst_PROGRAMS += mpc55xx/fec.rel
mpc55xx_fec_rel_SOURCES = mpc55xx/fec/fec.c
mpc55xx_fec_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
# EMDA
# eDMA
noinst_PROGRAMS += mpc55xx/edma.rel
mpc55xx_edma_rel_SOURCES = mpc55xx/edma/edma.c
mpc55xx_edma_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
# ESCI
# eMIOS
noinst_PROGRAMS += mpc55xx/emios.rel
mpc55xx_emios_rel_SOURCES = mpc55xx/emios/emios.c
mpc55xx_emios_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
# eSCI
noinst_PROGRAMS += mpc55xx/esci.rel
mpc55xx_esci_rel_SOURCES = mpc55xx/esci/esci.c
mpc55xx_esci_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)

View File

@@ -20,7 +20,6 @@
#include <mpc55xx/regs.h>
#include <mpc55xx/dspi.h>
#include <mpc55xx/edma.h>
#include <mpc55xx/mpc55xx.h>
#include <libcpu/powerpc-utility.h>
@@ -111,6 +110,15 @@ static const mpc55xx_dspi_baudrate_scaler_entry mpc55xx_dspi_baudrate_scaler_tab
{ 229376, 3, 15 },
};
static void mpc55xx_dspi_edma_done( mpc55xx_edma_channel_entry *e, uint32_t error_status)
{
rtems_semaphore_release( e->id);
if (error_status != 0) {
RTEMS_SYSLOG_ERROR( "eDMA error: 0x%08x\n", error_status);
}
}
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) {
@@ -151,49 +159,49 @@ static rtems_status_code mpc55xx_dspi_init( rtems_libi2c_bus_t *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;
struct tcd_t tcd_push = 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
RTEMS_SIMPLE_BINARY_SEMAPHORE,
0,
&e->edma_receive.id
);
RTEMS_CHECK_SC( sc, "Create receive update semaphore");
RTEMS_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);
RTEMS_CHECK_SC( sc, "Obtain receive eDMA channel");
sc = mpc55xx_edma_obtain_channel( &e->edma_receive);
RTEMS_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
RTEMS_SIMPLE_BINARY_SEMAPHORE,
0,
&e->edma_transmit.id
);
RTEMS_CHECK_SC( sc, "Create transmit update semaphore");
RTEMS_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);
RTEMS_CHECK_SC( sc, "Obtain transmit eDMA channel");
sc = mpc55xx_edma_obtain_channel( &e->edma_transmit);
RTEMS_CHECK_SC( sc, "obtain transmit eDMA channel");
sc = mpc55xx_edma_obtain_channel( e->edma_channel_push, NULL, RTEMS_ID_NONE);
RTEMS_CHECK_SC( sc, "Obtain push eDMA channel");
sc = mpc55xx_edma_obtain_channel( &e->edma_push);
RTEMS_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.SDF.B.SSIZE = 2;
tcd_push.SDF.B.SOFF = 0;
tcd_push.DADDR = (uint32_t) &e->regs->PUSHR.R;
tcd_push.DSIZE = 2;
tcd_push.DOFF = 0;
tcd_push.SDF.B.DSIZE = 2;
tcd_push.CDF.B.DOFF = 0;
tcd_push.NBYTES = 4;
tcd_push.CITER = 1;
tcd_push.BITER = 1;
tcd_push.CDF.B.CITER = 1;
tcd_push.BMF.B.BITER = 1;
EDMA.TCD [e->edma_channel_push] = tcd_push;
EDMA.TCD [e->edma_push.channel] = tcd_push;
/* Module Control Register */
mcr.B.MSTR = e->master ? 1 : 0;
@@ -324,8 +332,6 @@ static int mpc55xx_dspi_set_transfer_mode( rtems_libi2c_bus_t *bus, const rtems_
{
mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
union DSPI_CTAR_tag ctar = MPC55XX_ZERO_FLAGS;
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;
@@ -335,9 +341,6 @@ static int mpc55xx_dspi_set_transfer_mode( rtems_libi2c_bus_t *bus, const rtems_
ctar.R = e->regs->CTAR [MPC55XX_DSPI_CTAR_DEFAULT].R;
ctar.B.PBR = bse.pbr;
ctar.B.BR = bse.br;
ctar.B.PCSSCK = 0;
ctar.B.CSSCK = 0;
ctar.B.PASC = 0;
@@ -347,6 +350,16 @@ static int mpc55xx_dspi_set_transfer_mode( rtems_libi2c_bus_t *bus, const rtems_
ctar.B.CPOL = mode->clock_inv ? 1 : 0;
ctar.B.CPHA = mode->clock_phs ? 1 : 0;
if (mode->baudrate != e->baud) {
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);
ctar.B.PBR = bse.pbr;
ctar.B.BR = bse.br;
e->baud = mode->baudrate;
}
e->regs->CTAR [MPC55XX_DSPI_CTAR_DEFAULT].R = ctar.R;
return 0;
@@ -363,9 +376,9 @@ static int mpc55xx_dspi_set_transfer_mode( rtems_libi2c_bus_t *bus, const rtems_
* 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"];
* push -> idle_push_data [label="Transmit Request",URL="\ref mpc55xx_dspi_bus_entry::edma_transmit"];
* push -> out [label="Transmit Request",URL="\ref mpc55xx_dspi_bus_entry::edma_transmit"];
* out -> push_data [label="Channel Link",URL="\ref mpc55xx_dspi_bus_entry::edma_push"];
* edge [color=blue,fontcolor=blue];
* out -> push_data [label="Data"];
* push_data -> push [label="Data"];
@@ -380,8 +393,8 @@ static int mpc55xx_dspi_set_transfer_mode( rtems_libi2c_bus_t *bus, const rtems_
* 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"];
* pop -> nirvana [label="Receive Request",URL="\ref mpc55xx_dspi_bus_entry::edma_receive"];
* pop -> in [label="Receive Request",URL="\ref mpc55xx_dspi_bus_entry::edma_receive"];
* edge [color=blue,fontcolor=blue];
* pop -> nirvana [label="Data"];
* pop -> in [label="Data"];
@@ -424,11 +437,11 @@ static int mpc55xx_dspi_read_write( rtems_libi2c_bus_t *bus, unsigned char *in,
n_nc = (int) mpc55xx_non_cache_aligned_size( in);
n_c = (int) mpc55xx_cache_aligned_size( in, (size_t) n);
if (n_c > EDMA_TCD_BITER_LINKED_SIZE) {
RTEMS_SYSLOG_WARNING( "Buffer size out of range, cannot use eDMA\n");
RTEMS_SYSLOG_WARNING( "buffer size out of range, cannot use eDMA\n");
n_nc = n;
n_c = 0;
} else if (n_nc + n_c != n) {
RTEMS_SYSLOG_WARNING( "Input buffer not proper cache aligned, cannot use eDMA\n");
RTEMS_SYSLOG_WARNING( "input buffer not proper cache aligned, cannot use eDMA\n");
n_nc = n;
n_c = 0;
}
@@ -510,8 +523,8 @@ static int mpc55xx_dspi_read_write( rtems_libi2c_bus_t *bus, unsigned char *in,
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;
struct tcd_t tcd_transmit = EDMA_TCD_DEFAULT;
struct tcd_t tcd_receive = EDMA_TCD_DEFAULT;
/* Cache operations */
rtems_cache_flush_multiple_data_lines( out_c, (size_t) n_c);
@@ -522,52 +535,52 @@ static int mpc55xx_dspi_read_write( rtems_libi2c_bus_t *bus, unsigned char *in,
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.SDF.B.SSIZE = 2;
tcd_transmit.SDF.B.SOFF = 0;
tcd_transmit.DADDR = (uint32_t) push;
tcd_transmit.DSIZE = 2;
tcd_transmit.DOFF = 0;
tcd_transmit.SDF.B.DSIZE = 2;
tcd_transmit.CDF.B.DOFF = 0;
tcd_transmit.NBYTES = 4;
tcd_transmit.CITER = n_c;
tcd_transmit.BITER = n_c;
tcd_transmit.CDF.B.CITER = n_c;
tcd_transmit.BMF.B.BITER = n_c;
} else {
EDMA.CDSBR.R = e->edma_channel_transmit;
EDMA.CDSBR.R = e->edma_transmit.channel;
tcd_transmit.SADDR = (uint32_t) out_c;
tcd_transmit.SSIZE = 0;
tcd_transmit.SOFF = 1;
tcd_transmit.SDF.B.SSIZE = 0;
tcd_transmit.SDF.B.SOFF = 1;
tcd_transmit.DADDR = mpc55xx_dspi_push_data_address( e) + 3;
tcd_transmit.DSIZE = 0;
tcd_transmit.DOFF = 0;
tcd_transmit.SDF.B.DSIZE = 0;
tcd_transmit.CDF.B.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.CDF.B.CITERE_LINK = 1;
tcd_transmit.BMF.B.BITERE_LINK = 1;
tcd_transmit.BMF.B.MAJORLINKCH = e->edma_push.channel;
tcd_transmit.CDF.B.CITER = EDMA_TCD_LINK_AND_BITER( e->edma_push.channel, n_c);
tcd_transmit.BMF.B.BITER = EDMA_TCD_LINK_AND_BITER( e->edma_push.channel, n_c);
tcd_transmit.BMF.B.MAJORE_LINK = 1;
}
tcd_transmit.D_REQ = 1;
tcd_transmit.INT_MAJ = 1;
EDMA.TCD [e->edma_channel_transmit] = tcd_transmit;
tcd_transmit.BMF.B.D_REQ = 1;
tcd_transmit.BMF.B.INT_MAJ = 1;
EDMA.TCD [e->edma_transmit.channel] = tcd_transmit;
/* Set receive TCD */
if (in == NULL) {
tcd_receive.DOFF = 0;
tcd_receive.CDF.B.DOFF = 0;
tcd_receive.DADDR = mpc55xx_dspi_nirvana_address( e);
} else {
tcd_receive.DOFF = 1;
tcd_receive.CDF.B.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.SDF.B.SSIZE = 0;
tcd_receive.SDF.B.SOFF = 0;
tcd_receive.SDF.B.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;
tcd_receive.BMF.B.D_REQ = 1;
tcd_receive.BMF.B.INT_MAJ = 1;
tcd_receive.CDF.B.CITER = n_c;
tcd_receive.BMF.B.BITER = n_c;
EDMA.TCD [e->edma_receive.channel] = tcd_receive;
/* Clear request flags */
sr.R = 0;
@@ -576,28 +589,16 @@ static int mpc55xx_dspi_read_write( rtems_libi2c_bus_t *bus, unsigned char *in,
status->R = sr.R;
/* Enable hardware requests */
sc = mpc55xx_edma_enable_hardware_requests( e->edma_channel_receive, true);
RTEMS_CHECK_SC_RV( sc, "Enable receive hardware requests");
sc = mpc55xx_edma_enable_hardware_requests( e->edma_channel_transmit, true);
RTEMS_CHECK_SC_RV( sc, "Enable transmit hardware requests");
mpc55xx_edma_enable_hardware_requests( e->edma_receive.channel, true);
mpc55xx_edma_enable_hardware_requests( e->edma_transmit.channel, true);
/* Wait for transmit update */
sc = rtems_semaphore_obtain( e->edma_channel_transmit_update, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
RTEMS_CHECK_SC_RV( sc, "Transmit update");
if (e->edma_channel_transmit_error != 0) {
RTEMS_SYSLOG_ERROR( "Transmit error status: 0x%08x\n", e->edma_channel_transmit_error);
e->edma_channel_transmit_error = 0;
return -RTEMS_IO_ERROR;
}
sc = rtems_semaphore_obtain( e->edma_transmit.id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
RTEMS_CHECK_SC_RV( sc, "transmit update");
/* Wait for receive update */
sc = rtems_semaphore_obtain( e->edma_channel_receive_update, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
RTEMS_CHECK_SC_RV( sc, "Receive update");
if (e->edma_channel_receive_error != 0) {
RTEMS_SYSLOG_ERROR( "Receive error status: 0x%08x\n", e->edma_channel_receive_error);
e->edma_channel_receive_error = 0;
return -RTEMS_IO_ERROR;
}
sc = rtems_semaphore_obtain( e->edma_receive.id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
RTEMS_CHECK_SC_RV( sc, "receive update");
}
return n;
@@ -659,7 +660,8 @@ static const rtems_libi2c_bus_ops_t mpc55xx_dspi_ops = {
.ioctl = mpc55xx_dspi_ioctl
};
mpc55xx_dspi_bus_entry mpc55xx_dspi_bus_table [MPC55XX_DSPI_NUMBER] = { {
mpc55xx_dspi_bus_entry mpc55xx_dspi_bus_table [MPC55XX_DSPI_NUMBER] = {
{
/* DSPI A */
.bus = {
.ops = &mpc55xx_dspi_ops,
@@ -668,16 +670,25 @@ mpc55xx_dspi_bus_entry mpc55xx_dspi_bus_table [MPC55XX_DSPI_NUMBER] = { {
.table_index = 0,
.bus_number = 0,
.regs = &DSPI_A,
.master = 1,
.master = true,
.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,
.edma_transmit = {
.channel = 32,
.done = mpc55xx_dspi_edma_done,
.id = RTEMS_ID_NONE
},
.edma_push = {
.channel = 43,
.done = mpc55xx_dspi_edma_done,
.id = RTEMS_ID_NONE
},
.edma_receive = {
.channel = 33,
.done = mpc55xx_dspi_edma_done,
.id = RTEMS_ID_NONE
},
.idle_char = 0xffffffff,
.baud = 0
}, {
/* DSPI B */
.bus = {
@@ -687,16 +698,25 @@ mpc55xx_dspi_bus_entry mpc55xx_dspi_bus_table [MPC55XX_DSPI_NUMBER] = { {
.table_index = 1,
.bus_number = 0,
.regs = &DSPI_B,
.master = 1,
.master = true,
.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,
.edma_transmit = {
.channel = 12,
.done = mpc55xx_dspi_edma_done,
.id = RTEMS_ID_NONE
},
.edma_push = {
.channel = 10,
.done = mpc55xx_dspi_edma_done,
.id = RTEMS_ID_NONE
},
.edma_receive = {
.channel = 13,
.done = mpc55xx_dspi_edma_done,
.id = RTEMS_ID_NONE
},
.idle_char = 0xffffffff,
.baud = 0
}, {
/* DSPI C */
.bus = {
@@ -706,16 +726,25 @@ mpc55xx_dspi_bus_entry mpc55xx_dspi_bus_table [MPC55XX_DSPI_NUMBER] = { {
.table_index = 2,
.bus_number = 0,
.regs = &DSPI_C,
.master = 1,
.master = true,
.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,
.edma_transmit = {
.channel = 14,
.done = mpc55xx_dspi_edma_done,
.id = RTEMS_ID_NONE
},
.edma_push = {
.channel = 11,
.done = mpc55xx_dspi_edma_done,
.id = RTEMS_ID_NONE
},
.edma_receive = {
.channel = 15,
.done = mpc55xx_dspi_edma_done,
.id = RTEMS_ID_NONE
},
.idle_char = 0xffffffff,
.baud = 0
}, {
/* DSPI D */
.bus = {
@@ -725,15 +754,24 @@ mpc55xx_dspi_bus_entry mpc55xx_dspi_bus_table [MPC55XX_DSPI_NUMBER] = { {
.table_index = 3,
.bus_number = 0,
.regs = &DSPI_D,
.master = 1,
.master = true,
.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,
.edma_transmit = {
.channel = 16,
.done = mpc55xx_dspi_edma_done,
.id = RTEMS_ID_NONE
},
.edma_push = {
.channel = 18,
.done = mpc55xx_dspi_edma_done,
.id = RTEMS_ID_NONE
},
.edma_receive = {
.channel = 17,
.done = mpc55xx_dspi_edma_done,
.id = RTEMS_ID_NONE
},
.idle_char = 0xffffffff,
},
.baud = 0
}
};

View File

@@ -22,164 +22,148 @@
#include <mpc55xx/edma.h>
#include <mpc55xx/mpc55xx.h>
#include <bsp/irq.h>
#include <string.h>
#include <bsp/irq.h>
#include <bsp/utility.h>
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <rtems/status-checks.h>
#define MPC55XX_EDMA_CHANNEL_NUMBER 64
#define MPC55XX_EDMA_INVALID_CHANNEL UINT8_MAX
#define MPC55XX_EDMA_IS_CHANNEL_INVALID( i) ((i) < 0 || (i) >= MPC55XX_EDMA_CHANNEL_NUMBER)
#define MPC55XX_EDMA_CHANNEL_NUMBER 64U
#define MPC55XX_EDMA_IRQ_PRIORITY MPC55XX_INTC_MIN_PRIORITY
#define MPC55XX_EDMA_INVALID_CHANNEL MPC55XX_EDMA_CHANNEL_NUMBER
typedef struct {
uint8_t channel;
rtems_id transfer_update;
uint32_t *error_status;
} mpc55xx_edma_channel_entry;
#define MPC55XX_EDMA_IS_CHANNEL_INVALID( i) ((unsigned) (i) >= MPC55XX_EDMA_CHANNEL_NUMBER)
static mpc55xx_edma_channel_entry mpc55xx_edma_channel_table [MPC55XX_EDMA_CHANNEL_NUMBER];
#define MPC55XX_EDMA_IS_CHANNEL_VALID( i) ((unsigned) (i) < MPC55XX_EDMA_CHANNEL_NUMBER)
static uint32_t mpc55xx_edma_channel_occupation_low = 0;
#define MPC55XX_EDMA_IRQ_PRIORITY MPC55XX_INTC_DEFAULT_PRIORITY
static uint32_t mpc55xx_edma_channel_occupation_high = 0;
#define MPC55XX_EDMA_CHANNEL_FLAG( channel) ((uint64_t) 1 << (channel))
static rtems_id mpc55xx_edma_channel_occupation_mutex = RTEMS_ID_NONE;
static uint64_t mpc55xx_edma_channel_occupation = 0;
static uint8_t mpc55xx_edma_irq_error_low_channel = 0;
static rtems_chain_control mpc55xx_edma_channel_chain;
static uint8_t mpc55xx_edma_irq_error_high_channel = 32;
static void mpc55xx_edma_irq_handler( rtems_vector_number vector, void *data)
static void mpc55xx_edma_interrupt_handler( rtems_vector_number vector, void *arg)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
mpc55xx_edma_channel_entry *e = (mpc55xx_edma_channel_entry *) data;
mpc55xx_edma_channel_entry *e = (mpc55xx_edma_channel_entry *) arg;
#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;
RTEMS_DEBUG_PRINT( "Channel %i (CITER = %i)\n", e->channel, citer);
RTEMS_DEBUG_PRINT( "channel %i (CITER = %i)\n", e->channel, citer);
#endif /* DEBUG */
EDMA.CIRQR.R = e->channel;
sc = rtems_semaphore_release( e->transfer_update);
RTEMS_SYSLOG_WARNING_SC( sc, "Transfer update semaphore release");
/* Clear interrupt */
EDMA.CIRQR.R = (uint8_t) e->channel;
/* Notify user */
e->done( e, 0);
}
static void mpc55xx_edma_irq_update_error_table( uint8_t *link_table, uint8_t *error_table, int channel)
static void mpc55xx_edma_interrupt_error_handler( rtems_vector_number vector, void *arg)
{
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);
rtems_chain_control *chain = &mpc55xx_edma_channel_chain;
rtems_chain_node *node = chain->first;
unsigned i = 0;
uint64_t error_status = EDMA.ESR.R;
uint64_t error_channels = ((uint64_t) EDMA.ERH.R << 32) | EDMA.ERL.R;
uint64_t error_channels_update = 0;
RTEMS_DEBUG_PRINT( "error channels: %08x %08x\n", (unsigned) (error_channels >> 32), (unsigned) error_channels);
/* Mark all channels that are linked to a channel with errors */
do {
error_channels_update = 0;
for (i = 0; i < MPC55XX_EDMA_CHANNEL_NUMBER; ++i) {
uint64_t channel_flags = 0;
unsigned minor_link = i;
unsigned major_link = i;
/* Check if we have linked channels */
if (EDMA.TCD [i].BMF.B.BITERE_LINK) {
minor_link = EDMA_TCD_BITER_LINK( i);
}
if (EDMA.TCD [i].BMF.B.MAJORE_LINK) {
major_link = EDMA.TCD [i].BMF.B.MAJORLINKCH;
}
/* Set flags related to this channel */
channel_flags = MPC55XX_EDMA_CHANNEL_FLAG( i) | MPC55XX_EDMA_CHANNEL_FLAG( minor_link) | MPC55XX_EDMA_CHANNEL_FLAG( major_link);
/* Any errors in these channels? */
if (IS_ANY_FLAG_SET( error_channels, channel_flags)) {
/* Get new error channels */
uint64_t update = (error_channels & channel_flags) ^ channel_flags;
/* Update error channels */
error_channels = SET_FLAGS( error_channels, channel_flags);
/* Contribute to the update of this round */
error_channels_update = SET_FLAGS( error_channels_update, update);
}
}
}
}
} while (error_channels_update != 0);
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 = (uint8_t) (channel_start + 32);
int 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;
}
RTEMS_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] = (uint8_t) 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;
}
RTEMS_DEBUG_PRINT( "error channels (all): %08x %08x\n", (unsigned) (error_channels >> 32), (unsigned) error_channels);
/* 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);
RTEMS_SYSLOG_ERROR_SC( sc, "Disable hardware requests");
sc = rtems_semaphore_release( e->transfer_update);
RTEMS_SYSLOG_WARNING_SC( sc, "Transfer update semaphore release");
while (!rtems_chain_is_tail( chain, node)) {
mpc55xx_edma_channel_entry *e = (mpc55xx_edma_channel_entry *) node;
if (IS_FLAG_SET( error_channels, MPC55XX_EDMA_CHANNEL_FLAG( e->channel))) {
mpc55xx_edma_enable_hardware_requests( e->channel, false);
/* Notify user */
e->done( e, error_status);
}
node = node->next;
}
/* Clear the error interrupt requests */
for (i = 0; i < MPC55XX_EDMA_CHANNEL_NUMBER; ++i) {
if (channel_error_table [i]) {
if (IS_FLAG_SET( error_channels, MPC55XX_EDMA_CHANNEL_FLAG( i))) {
EDMA.CER.R = (uint8_t) i;
}
}
}
rtems_status_code mpc55xx_edma_enable_hardware_requests( int channel, bool enable)
void mpc55xx_edma_enable_hardware_requests( unsigned channel, bool enable)
{
if (MPC55XX_EDMA_IS_CHANNEL_INVALID( channel)) {
return RTEMS_INVALID_NUMBER;
}
if (enable) {
EDMA.SERQR.R = (uint8_t) channel;
if (MPC55XX_EDMA_IS_CHANNEL_VALID( channel)) {
if (enable) {
EDMA.SERQR.R = (uint8_t) channel;
} else {
EDMA.CERQR.R = (uint8_t) channel;
}
} else {
EDMA.CERQR.R = (uint8_t) channel;
RTEMS_SYSLOG_ERROR( "invalid channel number\n");
}
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc55xx_edma_enable_error_interrupts( int channel, bool enable)
void mpc55xx_edma_enable_error_interrupts( unsigned channel, bool enable)
{
if (MPC55XX_EDMA_IS_CHANNEL_INVALID( channel)) {
return RTEMS_INVALID_NUMBER;
}
if (enable) {
EDMA.SEEIR.R = channel;
if (MPC55XX_EDMA_IS_CHANNEL_VALID( channel)) {
if (enable) {
EDMA.SEEIR.R = (uint8_t) channel;
} else {
EDMA.CEEIR.R = (uint8_t) channel;
}
} else {
EDMA.CEEIR.R = channel;
RTEMS_SYSLOG_ERROR( "invalid channel number\n");
}
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
);
RTEMS_CHECK_SC( sc, "Create channel occupation mutex");
/* Initialize channel chain */
rtems_chain_initialize_empty( &mpc55xx_edma_channel_chain);
/* Arbitration mode: round robin */
EDMA.CR.B.ERCA = 1;
@@ -188,92 +172,101 @@ rtems_status_code mpc55xx_edma_init()
/* 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 */
/* Error interrupt handlers */
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
MPC55XX_EDMA_IRQ_PRIORITY,
mpc55xx_edma_interrupt_error_handler,
NULL
);
RTEMS_CHECK_SC( sc, "Install low error interrupt handler");
RTEMS_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
MPC55XX_EDMA_IRQ_PRIORITY,
mpc55xx_edma_interrupt_error_handler,
NULL
);
RTEMS_CHECK_SC( sc, "Install high error interrupt handler");
RTEMS_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 mpc55xx_edma_obtain_channel( mpc55xx_edma_channel_entry *e)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
int channel_occupied = 1;
rtems_interrupt_level level;
uint64_t channel_occupation = 0;
if (MPC55XX_EDMA_IS_CHANNEL_INVALID( channel)) {
if (MPC55XX_EDMA_IS_CHANNEL_INVALID( e->channel)) {
return RTEMS_INVALID_NUMBER;
}
/* Check occupation */
sc = rtems_semaphore_obtain( mpc55xx_edma_channel_occupation_mutex, RTEMS_WAIT, 0);
RTEMS_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);
RTEMS_SYSLOG_WARNING_SC( sc, "Release occupation mutex");
return RTEMS_RESOURCE_IN_USE;
} else {
sc = rtems_semaphore_release( mpc55xx_edma_channel_occupation_mutex);
RTEMS_CHECK_SC( sc, "Release channel occupation mutex");
/* Test and set channel occupation flag */
rtems_interrupt_disable( level);
channel_occupation = mpc55xx_edma_channel_occupation;
if (IS_FLAG_CLEARED( channel_occupation, MPC55XX_EDMA_CHANNEL_FLAG( e->channel))) {
mpc55xx_edma_channel_occupation = SET_FLAG( channel_occupation, MPC55XX_EDMA_CHANNEL_FLAG( e->channel));
}
rtems_interrupt_enable( level);
/* Channel data */
mpc55xx_edma_channel_table [channel].transfer_update = transfer_update;
mpc55xx_edma_channel_table [channel].error_status = error_status;
/* Check channel occupation flag */
if (IS_FLAG_SET( channel_occupation, MPC55XX_EDMA_CHANNEL_FLAG( e->channel))) {
return RTEMS_RESOURCE_IN_USE;
}
/* Interrupt handler */
sc = mpc55xx_interrupt_handler_install(
MPC55XX_IRQ_EDMA_GET_REQUEST( channel),
MPC55XX_EDMA_IRQ_PRIORITY,
MPC55XX_IRQ_EDMA_GET_REQUEST( e->channel),
"eDMA Channel",
RTEMS_INTERRUPT_SHARED,
mpc55xx_edma_irq_handler,
&mpc55xx_edma_channel_table [channel]
MPC55XX_EDMA_IRQ_PRIORITY,
mpc55xx_edma_interrupt_handler,
e
);
RTEMS_CHECK_SC( sc, "Install channel interrupt handler");
RTEMS_CHECK_SC( sc, "install channel interrupt handler");
/* Enable error interrupts */
sc = mpc55xx_edma_enable_error_interrupts( channel, true);
RTEMS_CHECK_SC( sc, "Enable error interrupts");
mpc55xx_edma_enable_error_interrupts( e->channel, true);
/* Prepend channel entry to channel list */
rtems_chain_prepend( &mpc55xx_edma_channel_chain, &e->node);
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc55xx_edma_release_channel( int channel)
rtems_status_code mpc55xx_edma_release_channel( mpc55xx_edma_channel_entry *e)
{
// TODO
return RTEMS_NOT_IMPLEMENTED;
rtems_status_code sc = RTEMS_SUCCESSFUL;
rtems_interrupt_level level;
/* Clear channel occupation flag */
rtems_interrupt_disable( level);
mpc55xx_edma_channel_occupation = CLEAR_FLAG( mpc55xx_edma_channel_occupation, MPC55XX_EDMA_CHANNEL_FLAG( e->channel));
rtems_interrupt_enable( level);
/* Disable hardware requests */
mpc55xx_edma_enable_hardware_requests( e->channel, false);
/* Disable error interrupts */
mpc55xx_edma_enable_error_interrupts( e->channel, false);
/* Extract channel entry from channel chain */
rtems_chain_extract( &e->node);
/* Remove interrupt handler */
sc = rtems_interrupt_handler_remove(
MPC55XX_IRQ_EDMA_GET_REQUEST( e->channel),
mpc55xx_edma_interrupt_handler,
e
);
RTEMS_CHECK_SC( sc, "remove channel interrupt handler");
/* Notify user */
e->done( e, 0);
return RTEMS_SUCCESSFUL;
}

View File

@@ -0,0 +1,109 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief Enhanced Modular Input Output Subsystem (eMIOS).
*/
/*
* Copyright (c) 2009
* 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/emios.h>
#include <mpc55xx/mpc55xx.h>
#include <bsp/irq.h>
#include <bsp/utility.h>
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <rtems/status-checks.h>
/**
* @brief Initialize the eMIOS module.
*
* The module is enabled. It is configured to use the internal clock. The
* global prescaler value is set to @a prescaler. If the value is greater than
* the maximum the maxium value will be used instead. A prescaler value of
* zero disables the clock.
*
* @note No protection against concurrent execution.
*/
void mpc55xx_emios_initialize( unsigned prescaler)
{
union EMIOS_MCR_tag mcr = MPC55XX_ZERO_FLAGS;
/* Enable module */
mcr.B.MDIS = 0;
/* Disable debug mode */
mcr.B.FRZ = 1;
/* Enable global time base */
mcr.B.GTBE = 1;
/* Disable global prescaler (= disable clock) */
mcr.B.GPREN = 0;
/* Set MCR */
EMIOS.MCR.R = mcr.R;
/* Set OUDR */
EMIOS.OUDR.R = 0;
/* Set global prescaler value */
mpc55xx_emios_set_global_prescaler( prescaler);
}
/**
* @brief Returns the global prescaler value of the eMIOS module.
*/
unsigned mpc55xx_emios_global_prescaler( void)
{
union EMIOS_MCR_tag mcr = EMIOS.MCR;
if (mcr.B.GPREN != 0) {
return mcr.B.GPRE + 1;
} else {
return 0;
}
}
/**
* @brief Sets the global prescaler value of the eMIOS module.
*
* The global prescaler value is set to @a prescaler. If the value is greater
* than the maximum the maxium value will be used instead. A prescaler value
* of zero disables the clock.
*
* @note No protection against concurrent execution.
*/
void mpc55xx_emios_set_global_prescaler( unsigned prescaler)
{
union EMIOS_MCR_tag mcr = EMIOS.MCR;
/* Enable or disable the global prescaler */
mcr.B.GPREN = prescaler > 0 ? 1 : 0;
/* Set global prescaler value */
if (prescaler > 256) {
prescaler = 256;
} else if (prescaler < 1) {
prescaler = 1;
}
mcr.B.GPRE = prescaler - 1;
/* Set MCR */
EMIOS.MCR.R = mcr.R;
}

View File

@@ -41,7 +41,7 @@
#define TERMIOS_CR2 CR2
#undef CR2
#define MPC55XX_ESCI_IRQ_PRIORITY MPC55XX_INTC_MIN_PRIORITY
#define MPC55XX_ESCI_IRQ_PRIORITY MPC55XX_INTC_DEFAULT_PRIORITY
#define MPC55XX_ESCI_IS_MINOR_INVALD(minor) ((minor) < 0 || (minor) >= MPC55XX_ESCI_NUMBER)
@@ -73,12 +73,7 @@ mpc55xx_esci_driver_entry mpc55xx_esci_driver_table [MPC55XX_ESCI_NUMBER] = { {
* @brief Default termios configuration.
*/
static const struct termios mpc55xx_esci_termios_default = {
0,
0,
CS8 | CREAD | CLOCAL | B115200,
0,
0,
{ 0 }
.c_cflag = CS8 | CREAD | CLOCAL | B115200
};
/**
@@ -119,17 +114,56 @@ static inline void mpc55xx_esci_write_char( mpc55xx_esci_driver_entry *e, uint8_
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;
rtems_interrupt_level level;
while (status->B.TDRE == 0) {
/* Wait */
}
/* Clear flag */
/* Set clear flag */
sr.B.TDRE = 1;
status->R = sr.R;
/* Write */
data->B.D = c;
while (true) {
rtems_interrupt_disable( level);
if (status->B.TDRE != 0) {
/* Clear flag */
status->R = sr.R;
/* Write */
data->B.D = c;
/* Done */
rtems_interrupt_enable( level);
break;
}
rtems_interrupt_enable( level);
while (status->B.TDRE == 0) {
/* Wait */
}
}
}
static inline void mpc55xx_esci_interrupts_enable( mpc55xx_esci_driver_entry *e)
{
union ESCI_CR1_tag cr1 = MPC55XX_ZERO_FLAGS;
rtems_interrupt_level level;
rtems_interrupt_disable( level);
cr1.R = e->regs->CR1.R;
cr1.B.RIE = 1;
cr1.B.TIE = 1;
e->regs->CR1.R = cr1.R;
rtems_interrupt_enable( level);
}
static inline void mpc55xx_esci_interrupts_disable( mpc55xx_esci_driver_entry *e)
{
union ESCI_CR1_tag cr1 = MPC55XX_ZERO_FLAGS;
rtems_interrupt_level level;
rtems_interrupt_disable( level);
cr1.R = e->regs->CR1.R;
cr1.B.RIE = 0;
cr1.B.TIE = 0;
e->regs->CR1.R = cr1.R;
rtems_interrupt_enable( level);
}
/** @} */
@@ -146,8 +180,8 @@ static inline void mpc55xx_esci_write_char( mpc55xx_esci_driver_entry *e, uint8_
*/
static int mpc55xx_esci_termios_first_open( int major, int minor, void *arg)
{
int rv = 0;
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 */
@@ -160,12 +194,12 @@ static int mpc55xx_esci_termios_first_open( int major, int minor, void *arg)
/* 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;
mpc55xx_esci_interrupts_enable( e);
}
rv = rtems_termios_set_initial_baud( e->tty, 115200);
RTEMS_CHECK_RV_SC( rv, "Set initial baud");
return RTEMS_SUCCESSFUL;
}
@@ -177,7 +211,6 @@ static int mpc55xx_esci_termios_first_open( int major, int minor, void *arg)
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)) {
@@ -185,10 +218,7 @@ static int mpc55xx_esci_termios_last_close( int major, int minor, void* arg)
}
/* Disable interrupts */
cr1.R = e->regs->CR1.R;
cr1.B.RIE = 0;
cr1.B.TIE = 0;
e->regs->CR1.R = cr1.R;
mpc55xx_esci_interrupts_disable( e);
/* Disconnect TTY */
e->tty = NULL;
@@ -204,13 +234,20 @@ static int mpc55xx_esci_termios_last_close( int major, int minor, void* arg)
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)) {
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;
if (status->B.RDRF == 0) {
return -1;
}
return (int) mpc55xx_esci_read_char( e);
/* Clear flag */
sr.B.RDRF = 1;
status->R = sr.R;
/* Read */
return data->B.D;
}
/**
@@ -231,9 +268,6 @@ static int mpc55xx_esci_termios_poll_write( int minor, const char *out, int n)
/* 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;
@@ -479,9 +513,9 @@ rtems_device_driver console_initialize( rtems_device_major_number major, rtems_d
if (MPC55XX_ESCI_USE_INTERRUPTS( e)) {
sc = mpc55xx_interrupt_handler_install(
e->irq_number,
MPC55XX_ESCI_IRQ_PRIORITY,
"eSCI",
RTEMS_INTERRUPT_UNIQUE,
MPC55XX_ESCI_IRQ_PRIORITY,
mpc55xx_esci_termios_interrupt_handler,
e
);
@@ -511,13 +545,7 @@ rtems_device_driver console_open( rtems_device_major_number major, rtems_device_
} 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;
}
RTEMS_CHECK_SC( sc, "Open");
}
return RTEMS_SUCCESSFUL;
@@ -623,10 +651,13 @@ static int mpc55xx_esci_output_char_minor = 0;
static void mpc55xx_esci_output_char( char c)
{
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [mpc55xx_esci_output_char_minor];
mpc55xx_esci_interrupts_disable( e);
mpc55xx_esci_write_char( e, c);
if (c == '\n') {
mpc55xx_esci_write_char( e, '\r');
}
mpc55xx_esci_interrupts_enable( e);
}
static void mpc55xx_esci_output_char_nop( char c)
@@ -636,15 +667,17 @@ static void mpc55xx_esci_output_char_nop( char c)
static void mpc55xx_esci_output_char_init( char c)
{
int console_found = 0;
bool console_found = false;
int i = 0;
for (i = 0; i < MPC55XX_ESCI_NUMBER; ++i) {
if (mpc55xx_esci_driver_table [i].console) {
console_found = 1;
console_found = true;
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);

View File

@@ -29,6 +29,8 @@
#include <rtems/libi2c.h>
#include <mpc55xx/edma.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
@@ -64,7 +66,7 @@ typedef struct {
/**
* @brief Selects SPI master or slave mode.
*/
int master;
bool master;
/**
* @brief Data for the Push Register.
@@ -72,50 +74,35 @@ typedef struct {
union DSPI_PUSHR_tag push_data;
/**
* @brief eDMA channel for transmission.
* @brief eDMA entry for transmission.
*
* The channel is fixed to particular DSPI.
* The channel is fixed to a particular DSPI.
*/
int edma_channel_transmit;
mpc55xx_edma_channel_entry edma_transmit;
/**
* @brief eDMA channel to generate the push data.
* @brief eDMA entry for push data generation.
*
* You can choose any available channel.
* You can choose every available channel.
*/
int edma_channel_push;
mpc55xx_edma_channel_entry edma_push;
/**
* @brief eDMA channel for receiving.
* @brief eDMA entry for receiving.
*
* The channel is fixed to particular DSPI.
* The channel is fixed to a 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;
mpc55xx_edma_channel_entry edma_receive;
/**
* @brief Idle character transmitted in read only mode.
*/
uint32_t idle_char;
/**
* @brief Current baud.
*/
uint32_t baud;
} mpc55xx_dspi_bus_entry;
/**

View File

@@ -22,78 +22,31 @@
#define LIBCPU_POWERPC_MPC55XX_EDMA_H
#include <stdbool.h>
#include <stdint.h>
#include <rtems.h>
#include <rtems/chain.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, \
}
typedef struct mpc55xx_edma_channel_entry {
rtems_chain_node node;
unsigned channel;
void (*done)( struct mpc55xx_edma_channel_entry *, uint32_t);
rtems_id id;
} mpc55xx_edma_channel_entry;
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_obtain_channel( mpc55xx_edma_channel_entry *e);
rtems_status_code mpc55xx_edma_enable_hardware_requests( int channel, bool enable);
rtems_status_code mpc55xx_edma_release_channel( mpc55xx_edma_channel_entry *e);
rtems_status_code mpc55xx_edma_enable_error_interrupts( int channel, bool enable);
void mpc55xx_edma_enable_hardware_requests( unsigned channel, bool enable);
void mpc55xx_edma_enable_error_interrupts( unsigned channel, bool enable);
#ifdef __cplusplus
}

View File

@@ -0,0 +1,192 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief Enhanced Modular Input Output Subsystem (eMIOS).
*/
/*
* Copyright (c) 2009
* 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_EMIOS_H
#define LIBCPU_POWERPC_MPC55XX_EMIOS_H
#include <stdbool.h>
#include <stdint.h>
#include <rtems.h>
#include <rtems/chain.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @name eMIOS - Modes
*
* @{
*/
#define MPC55XX_EMIOS_MODE_GPIO_INPUT 0U
#define MPC55XX_EMIOS_MODE_GPIO_OUTPUT 1U
#define MPC55XX_EMIOS_MODE_SAIC 2U
#define MPC55XX_EMIOS_MODE_SAOC 3U
#define MPC55XX_EMIOS_MODE_IPWM 4U
#define MPC55XX_EMIOS_MODE_IPM 5U
#define MPC55XX_EMIOS_MODE_DAOC_SECOND 6U
#define MPC55XX_EMIOS_MODE_DAOC_BOTH 7U
#define MPC55XX_EMIOS_MODE_PEA_ACCU_CONT 8U
#define MPC55XX_EMIOS_MODE_PEA_ACCU_SINGLE 9U
#define MPC55XX_EMIOS_MODE_PEA_COUNT_CONT 10U
#define MPC55XX_EMIOS_MODE_PEA_COUNT_SINGLE 11U
#define MPC55XX_EMIOS_MODE_QDEC_COUNT_DIR 12U
#define MPC55XX_EMIOS_MODE_QDEC_PHASE 13U
#define MPC55XX_EMIOS_MODE_WPTA 14U
#define MPC55XX_EMIOS_MODE_RESERVED_15 15U
#define MPC55XX_EMIOS_MODE_MC_UP_INT_CLK 16U
#define MPC55XX_EMIOS_MODE_MC_UP_EXT_CLK 17U
#define MPC55XX_EMIOS_MODE_RESERVED_18 18U
#define MPC55XX_EMIOS_MODE_RESERVED_19 19U
#define MPC55XX_EMIOS_MODE_MC_UP_DOWN_INT_CLK 20U
#define MPC55XX_EMIOS_MODE_MC_UP_DOWN_EXT_CLK 21U
#define MPC55XX_EMIOS_MODE_MC_UP_DOWN_CHANGE_INT_CLK 22U
#define MPC55XX_EMIOS_MODE_MC_UP_DOWN_CHANGE_EXT_CLK 23U
#define MPC55XX_EMIOS_MODE_OPWFM_B_IMMEDIATE 24U
#define MPC55XX_EMIOS_MODE_OPWFM_B_NEXT_PERIOD 25U
#define MPC55XX_EMIOS_MODE_OPWFM_AB_IMMEDIATE 26U
#define MPC55XX_EMIOS_MODE_OPWFM_AB_NEXT_PERIOD 27U
#define MPC55XX_EMIOS_MODE_OPWMC_TRAIL_TRAIL 28U
#define MPC55XX_EMIOS_MODE_OPWMC_TRAIL_LEAD 29U
#define MPC55XX_EMIOS_MODE_OPWMC_BOTH_TRAIL 30U
#define MPC55XX_EMIOS_MODE_OPWMC_BOTH_LEAD 31U
#define MPC55XX_EMIOS_MODE_OPWM_B_IMMEDIATE 32U
#define MPC55XX_EMIOS_MODE_OPWM_B_NEXT_PERIOD 33U
#define MPC55XX_EMIOS_MODE_OPWM_AB_IMMEDIATE 34U
#define MPC55XX_EMIOS_MODE_OPWM_AB_NEXT_PERIOD 35U
#define MPC55XX_EMIOS_MODE_RESERVED_36 36U
#define MPC55XX_EMIOS_MODE_RESERVED_37 37U
#define MPC55XX_EMIOS_MODE_RESERVED_38 38U
#define MPC55XX_EMIOS_MODE_RESERVED_39 39U
#define MPC55XX_EMIOS_MODE_RESERVED_40 40U
#define MPC55XX_EMIOS_MODE_RESERVED_41 41U
#define MPC55XX_EMIOS_MODE_RESERVED_42 42U
#define MPC55XX_EMIOS_MODE_RESERVED_43 43U
#define MPC55XX_EMIOS_MODE_RESERVED_44 44U
#define MPC55XX_EMIOS_MODE_RESERVED_45 45U
#define MPC55XX_EMIOS_MODE_RESERVED_46 46U
#define MPC55XX_EMIOS_MODE_RESERVED_47 47U
#define MPC55XX_EMIOS_MODE_RESERVED_48 48U
#define MPC55XX_EMIOS_MODE_RESERVED_49 49U
#define MPC55XX_EMIOS_MODE_RESERVED_50 50U
#define MPC55XX_EMIOS_MODE_RESERVED_51 51U
#define MPC55XX_EMIOS_MODE_RESERVED_52 52U
#define MPC55XX_EMIOS_MODE_RESERVED_53 53U
#define MPC55XX_EMIOS_MODE_RESERVED_54 54U
#define MPC55XX_EMIOS_MODE_RESERVED_55 55U
#define MPC55XX_EMIOS_MODE_RESERVED_56 56U
#define MPC55XX_EMIOS_MODE_RESERVED_57 57U
#define MPC55XX_EMIOS_MODE_RESERVED_58 58U
#define MPC55XX_EMIOS_MODE_RESERVED_59 59U
#define MPC55XX_EMIOS_MODE_RESERVED_60 60U
#define MPC55XX_EMIOS_MODE_RESERVED_61 61U
#define MPC55XX_EMIOS_MODE_RESERVED_62 62U
#define MPC55XX_EMIOS_MODE_RESERVED_63 63U
#define MPC55XX_EMIOS_MODE_RESERVED_64 64U
#define MPC55XX_EMIOS_MODE_RESERVED_65 65U
#define MPC55XX_EMIOS_MODE_RESERVED_66 66U
#define MPC55XX_EMIOS_MODE_RESERVED_67 67U
#define MPC55XX_EMIOS_MODE_RESERVED_68 68U
#define MPC55XX_EMIOS_MODE_RESERVED_69 69U
#define MPC55XX_EMIOS_MODE_RESERVED_70 70U
#define MPC55XX_EMIOS_MODE_RESERVED_71 71U
#define MPC55XX_EMIOS_MODE_RESERVED_72 72U
#define MPC55XX_EMIOS_MODE_RESERVED_73 73U
#define MPC55XX_EMIOS_MODE_RESERVED_74 74U
#define MPC55XX_EMIOS_MODE_RESERVED_75 75U
#define MPC55XX_EMIOS_MODE_RESERVED_76 76U
#define MPC55XX_EMIOS_MODE_RESERVED_77 77U
#define MPC55XX_EMIOS_MODE_RESERVED_78 78U
#define MPC55XX_EMIOS_MODE_RESERVED_79 79U
#define MPC55XX_EMIOS_MODE_MCB_UP_INT_CLK 80U
#define MPC55XX_EMIOS_MODE_MCB_UP_EXT_CLK 81U
#define MPC55XX_EMIOS_MODE_RESERVED_82 82U
#define MPC55XX_EMIOS_MODE_RESERVED_83 83U
#define MPC55XX_EMIOS_MODE_MCB_UP_DOWN_ONE_INT_CLK 84U
#define MPC55XX_EMIOS_MODE_MCB_UP_DOWN_ONE_EXT_CLK 85U
#define MPC55XX_EMIOS_MODE_MCB_UP_DOWN_BOTH_INT_CLK 86U
#define MPC55XX_EMIOS_MODE_MCB_UP_DOWN_BOTH_EXT_CLK 87U
#define MPC55XX_EMIOS_MODE_OPWFMB_B 88U
#define MPC55XX_EMIOS_MODE_RESERVED_89 89U
#define MPC55XX_EMIOS_MODE_OPWFMB_AB 90U
#define MPC55XX_EMIOS_MODE_RESERVED_91 91U
#define MPC55XX_EMIOS_MODE_OPWMCB_TRAIL_TRAIL 92U
#define MPC55XX_EMIOS_MODE_OPWMCB_TRAIL_LEAD 93U
#define MPC55XX_EMIOS_MODE_OPWMCB_BOTH_TRAIL 94U
#define MPC55XX_EMIOS_MODE_OPWMCB_BOTH_LEAD 95U
#define MPC55XX_EMIOS_MODE_OPWMB_SECOND 96U
#define MPC55XX_EMIOS_MODE_RESERVED_97 97U
#define MPC55XX_EMIOS_MODE_OPWMB_BOTH 98U
#define MPC55XX_EMIOS_MODE_RESERVED_99 99U
#define MPC55XX_EMIOS_MODE_RESERVED_100 100U
#define MPC55XX_EMIOS_MODE_RESERVED_101 101U
#define MPC55XX_EMIOS_MODE_RESERVED_102 102U
#define MPC55XX_EMIOS_MODE_RESERVED_103 103U
#define MPC55XX_EMIOS_MODE_RESERVED_104 104U
#define MPC55XX_EMIOS_MODE_RESERVED_105 105U
#define MPC55XX_EMIOS_MODE_RESERVED_106 106U
#define MPC55XX_EMIOS_MODE_RESERVED_107 107U
#define MPC55XX_EMIOS_MODE_RESERVED_108 108U
#define MPC55XX_EMIOS_MODE_RESERVED_109 109U
#define MPC55XX_EMIOS_MODE_RESERVED_110 110U
#define MPC55XX_EMIOS_MODE_RESERVED_111 111U
#define MPC55XX_EMIOS_MODE_RESERVED_112 112U
#define MPC55XX_EMIOS_MODE_RESERVED_113 113U
#define MPC55XX_EMIOS_MODE_RESERVED_114 114U
#define MPC55XX_EMIOS_MODE_RESERVED_115 115U
#define MPC55XX_EMIOS_MODE_RESERVED_116 116U
#define MPC55XX_EMIOS_MODE_RESERVED_117 117U
#define MPC55XX_EMIOS_MODE_RESERVED_118 118U
#define MPC55XX_EMIOS_MODE_RESERVED_119 119U
#define MPC55XX_EMIOS_MODE_RESERVED_120 120U
#define MPC55XX_EMIOS_MODE_RESERVED_121 121U
#define MPC55XX_EMIOS_MODE_RESERVED_122 122U
#define MPC55XX_EMIOS_MODE_RESERVED_123 123U
#define MPC55XX_EMIOS_MODE_RESERVED_124 124U
#define MPC55XX_EMIOS_MODE_RESERVED_125 125U
#define MPC55XX_EMIOS_MODE_RESERVED_126 126U
#define MPC55XX_EMIOS_MODE_RESERVED_127 127U
/** @} */
#define MPC55XX_EMIOS_CHANNEL_NUMBER 24U
#define MPC55XX_EMIOS_VALUE_MAX 0x00ffffffU
#define MPC55XX_EMIOS_IS_CHANNEL_VALID( c) \
((unsigned) (c) < MPC55XX_EMIOS_CHANNEL_NUMBER)
#define MPC55XX_EMIOS_IS_CHANNEL_INVALID( c) \
(!MPC55XX_EMIOS_IS_CHANNEL_VALID( c))
void mpc55xx_emios_initialize( unsigned prescaler);
unsigned mpc55xx_emios_global_prescaler( void);
void mpc55xx_emios_set_global_prescaler( unsigned prescaler);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LIBCPU_POWERPC_MPC55XX_EMIOS_H */

View File

@@ -33,57 +33,74 @@ extern "C" {
*/
/* Basics */
#define MPC55XX_IRQ_MIN 0
#define MPC55XX_IRQ_MAX 328
#define MPC55XX_IRQ_MIN 0U
#define MPC55XX_IRQ_MAX 328U
#define MPC55XX_IRQ_BASE MPC55XX_IRQ_MIN
#define MPC55XX_IRQ_NUMBER (MPC55XX_IRQ_MAX + 1)
#define MPC55XX_IRQ_NUMBER (MPC55XX_IRQ_MAX + 1U)
/* Software interrupts */
#define MPC55XX_IRQ_SOFTWARE_MIN 0
#define MPC55XX_IRQ_SOFTWARE_MAX 7
#define MPC55XX_IRQ_SOFTWARE_NUMBER (MPC55XX_IRQ_SOFTWARE_MAX + 1)
#define MPC55XX_IRQ_SOFTWARE_MIN 0U
#define MPC55XX_IRQ_SOFTWARE_MAX 7U
#define MPC55XX_IRQ_SOFTWARE_GET_INDEX( v) (v)
#define MPC55XX_IRQ_SOFTWARE_GET_REQUEST( i) (i)
#define MPC55XX_IRQ_SOFTWARE_NUMBER (MPC55XX_IRQ_SOFTWARE_MAX + 1U)
/* 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))
#define MPC55XX_IRQ_EDMA_ERROR_LOW 10U
#define MPC55XX_IRQ_EDMA_ERROR_HIGH 210U
#define MPC55XX_IRQ_EDMA_REQUEST_LOW_MIN 11U
#define MPC55XX_IRQ_EDMA_REQUEST_LOW_MAX 42U
#define MPC55XX_IRQ_EDMA_REQUEST_HIGH_MIN 211U
#define MPC55XX_IRQ_EDMA_REQUEST_HIGH_MAX 242U
#define MPC55XX_IRQ_EDMA_GET_CHANNEL( v) (((v) > MPC55XX_IRQ_EDMA_REQUEST_LOW_MAX) ? ((v) + 32U - MPC55XX_IRQ_EDMA_REQUEST_HIGH_MIN) : ((v) - MPC55XX_IRQ_EDMA_REQUEST_LOW_MIN))
#define MPC55XX_IRQ_EDMA_GET_REQUEST( c) (((c) >= 32U) ? ((c) - 32U + MPC55XX_IRQ_EDMA_REQUEST_HIGH_MIN) : ((c) + MPC55XX_IRQ_EDMA_REQUEST_LOW_MIN))
/* SIU external interrupts */
#define MPC55XX_IRQ_SIU_EXTERNAL_0 46U
#define MPC55XX_IRQ_SIU_EXTERNAL_1 47U
#define MPC55XX_IRQ_SIU_EXTERNAL_2 48U
#define MPC55XX_IRQ_SIU_EXTERNAL_3 49U
#define MPC55XX_IRQ_SIU_EXTERNAL_4_15 50U
/* eMIOS interrupts */
#define MPC55XX_IRQ_EMIOS_REQUEST_LOW_MIN 51U
#define MPC55XX_IRQ_EMIOS_REQUEST_LOW_MAX 66U
#define MPC55XX_IRQ_EMIOS_REQUEST_HIGH_MIN 202U
#define MPC55XX_IRQ_EMIOS_REQUEST_HIGH_MAX 209U
#define MPC55XX_IRQ_EMIOS_GET_CHANNEL( v) (((v) > MPC55XX_IRQ_EMIOS_REQUEST_LOW_MAX) ? ((v) + 16U - MPC55XX_IRQ_EMIOS_REQUEST_HIGH_MIN) : ((v) - MPC55XX_IRQ_EMIOS_REQUEST_LOW_MIN))
#define MPC55XX_IRQ_EMIOS_GET_REQUEST( c) (((c) >= 16U) ? ((c) - 16U + MPC55XX_IRQ_EMIOS_REQUEST_HIGH_MIN) : ((c) + MPC55XX_IRQ_EMIOS_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)
#define MPC55XX_IRQ_IS_VALID(v) ((v) >= MPC55XX_IRQ_MIN && (v) <= MPC55XX_IRQ_MAX)
#define MPC55XX_IRQ_IS_SOFTWARE(v) ((v) >= MPC55XX_IRQ_SOFTWARE_MIN && (v) <= 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_MIN_PRIORITY 1U
#define MPC55XX_INTC_MAX_PRIORITY 15U
#define MPC55XX_INTC_DISABLED_PRIORITY 0U
#define MPC55XX_INTC_INVALID_PRIORITY (MPC55XX_INTC_MAX_PRIORITY + 1)
#define MPC55XX_INTC_DEFAULT_PRIORITY (MPC55XX_INTC_MIN_PRIORITY + 1)
#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,
unsigned priority,
rtems_interrupt_handler handler,
void *arg
);
rtems_status_code mpc55xx_intc_get_priority( int i, int *p);
rtems_status_code mpc55xx_intc_get_priority( rtems_vector_number vector, unsigned *priority);
rtems_status_code mpc55xx_intc_set_priority( int i, int p);
rtems_status_code mpc55xx_intc_set_priority( rtems_vector_number vector, unsigned priority);
rtems_status_code mpc55xx_intc_raise_software_irq( int i);
rtems_status_code mpc55xx_intc_raise_software_irq( rtems_vector_number vector);
rtems_status_code mpc55xx_intc_clear_software_irq( int i);
rtems_status_code mpc55xx_intc_clear_software_irq( rtems_vector_number vector);
#ifdef __cplusplus
};

View File

@@ -666,7 +666,7 @@ extern "C" {
} B;
} SRCR;
union { /* External Interrupt Status Register */
union SIU_EISR_tag { /* External Interrupt Status Register */
uint32_t R;
struct {
uint32_t:16;
@@ -689,7 +689,7 @@ extern "C" {
} B;
} EISR;
union { /* DMA/Interrupt Request Enable Register */
union SIU_DIRER_tag { /* DMA/Interrupt Request Enable Register */
uint32_t R;
struct {
uint32_t:16;
@@ -712,7 +712,7 @@ extern "C" {
} B;
} DIRER;
union { /* DMA/Interrupt Select Register */
union SIU_DIRSR_tag { /* DMA/Interrupt Select Register */
uint32_t R;
struct {
uint32_t:28;
@@ -723,7 +723,7 @@ extern "C" {
} B;
} DIRSR;
union { /* Overrun Status Register */
union SIU_OSR_tag { /* Overrun Status Register */
uint32_t R;
struct {
uint32_t:16;
@@ -746,7 +746,7 @@ extern "C" {
} B;
} OSR;
union { /* Overrun Request Enable Register */
union SIU_ORER_tag { /* Overrun Request Enable Register */
uint32_t R;
struct {
uint32_t:16;
@@ -769,7 +769,7 @@ extern "C" {
} B;
} ORER;
union { /* External IRQ Rising-Edge Event Enable Register */
union SIU_IREER_tag { /* External IRQ Rising-Edge Event Enable Register */
uint32_t R;
struct {
uint32_t:16;
@@ -792,7 +792,7 @@ extern "C" {
} B;
} IREER;
union { /* External IRQ Falling-Edge Event Enable Register */
union SIU_IFEER_tag { /* External IRQ Falling-Edge Event Enable Register */
uint32_t R;
struct {
uint32_t:16;
@@ -815,7 +815,7 @@ extern "C" {
} B;
} IFEER;
union { /* External IRQ Digital Filter Register */
union SIU_IDFR_tag { /* External IRQ Digital Filter Register */
uint32_t R;
struct {
uint32_t:28;
@@ -963,7 +963,7 @@ extern "C" {
/* MODULE : EMIOS */
/****************************************************************************/
struct EMIOS_tag {
union {
union EMIOS_MCR_tag {
uint32_t R;
struct {
uint32_t:1;
@@ -979,7 +979,7 @@ extern "C" {
} B;
} MCR; /* Module Configuration Register */
union {
union EMIOS_GFR_tag {
uint32_t R;
struct {
uint32_t:8;
@@ -1010,7 +1010,7 @@ extern "C" {
} B;
} GFR; /* Global FLAG Register */
union {
union EMIOS_OUDR_tag {
uint32_t R;
struct {
uint32_t:8;
@@ -1043,7 +1043,7 @@ extern "C" {
uint32_t emios_reserved[5];
struct {
struct EMIOS_CH_tag {
union {
uint32_t R; /* Channel A Data Register */
} CADR;
@@ -1056,7 +1056,7 @@ extern "C" {
uint32_t R; /* Channel Counter Register */
} CCNTR;
union {
union EMIOS_CCR_tag {
uint32_t R;
struct {
uint32_t FREN:1;
@@ -1080,7 +1080,7 @@ extern "C" {
} B;
} CCR; /* Channel Control Register */
union {
union EMIOS_CSR_tag {
uint32_t R;
struct {
uint32_t OVR:1;
@@ -2165,19 +2165,19 @@ extern "C" {
union {
uint16_t R;
} SWTCR; //Software Watchdog Timer Control
} SWTCR; /* Software Watchdog Timer Control */
uint8_t ecsm_reserved3[3];
union {
uint8_t R;
} SWTSR; //SWT Service Register
} SWTSR; /* SWT Service Register */
uint8_t ecsm_reserved4[3];
union {
uint8_t R;
} SWTIR; //SWT Interrupt Register
} SWTIR; /* SWT Interrupt Register */
uint32_t ecsm_reserved5a[1];
@@ -2210,7 +2210,7 @@ extern "C" {
uint8_t ERNCR:1;
uint8_t EFNCR:1;
} B;
} ECR; //ECC Configuration Register
} ECR; /* ECC Configuration Register */
uint8_t mcm_reserved8[3];
@@ -2221,7 +2221,7 @@ extern "C" {
uint8_t RNCE:1;
uint8_t FNCE:1;
} B;
} ESR; //ECC Status Register
} ESR; /* ECC Status Register */
uint16_t ecsm_reserved9;
@@ -2234,7 +2234,7 @@ extern "C" {
uint16_t:1;
uint16_t ERRBIT:7;
} B;
} EEGR; //ECC Error Generation Register
} EEGR; /* ECC Error Generation Register */
uint32_t ecsm_reserved10;
@@ -2243,7 +2243,7 @@ extern "C" {
struct {
uint32_t FEAR:32;
} B;
} FEAR; //Flash ECC Address Register
} FEAR; /* Flash ECC Address Register */
uint16_t ecsm_reserved11;
@@ -2253,7 +2253,7 @@ extern "C" {
uint8_t:4;
uint8_t FEMR:4;
} B;
} FEMR; //Flash ECC Master Register
} FEMR; /* Flash ECC Master Register */
union {
uint8_t R;
@@ -2265,28 +2265,28 @@ extern "C" {
uint8_t PROT2:1;
uint8_t PROT3:1;
} B;
} FEAT; //Flash ECC Attributes Register
} FEAT; /* Flash ECC Attributes Register */
union {
uint32_t R;
struct {
uint32_t FEDH:32;
} B;
} FEDRH; //Flash ECC Data High Register
} FEDRH; /* Flash ECC Data High Register */
union {
uint32_t R;
struct {
uint32_t FEDL:32;
} B;
} FEDRL; //Flash ECC Data Low Register
} FEDRL; /* Flash ECC Data Low Register */
union {
uint32_t R;
struct {
uint32_t REAR:32;
} B;
} REAR; //RAM ECC Address
} REAR; /* RAM ECC Address */
uint8_t ecsm_reserved12[2];
@@ -2296,7 +2296,7 @@ extern "C" {
uint8_t:4;
uint8_t REMR:4;
} B;
} REMR; //RAM ECC Master
} REMR; /* RAM ECC Master */
union {
uint8_t R;
@@ -2308,21 +2308,21 @@ extern "C" {
uint8_t PROT2:1;
uint8_t PROT3:1;
} B;
} REAT; // RAM ECC Attributes Register
} REAT; /* RAM ECC Attributes Register */
union {
uint32_t R;
struct {
uint32_t REDH:32;
} B;
} REDRH; //RAM ECC Data High Register
} REDRH; /* RAM ECC Data High Register */
union {
uint32_t R;
struct {
uint32_t REDL:32;
} B;
} REDRL; //RAMECC Data Low Register
} REDRL; /* RAMECC Data Low Register */
};
/****************************************************************************/
@@ -2728,41 +2728,88 @@ extern "C" {
struct tcd_t {
uint32_t SADDR; /* source address */
uint16_t SMOD:5; /* source address modulo */
uint16_t SSIZE:3; /* source transfer size */
uint16_t DMOD:5; /* destination address modulo */
uint16_t DSIZE:3; /* destination transfer size */
int16_t SOFF; /* signed source address offset */
/* Source and destination fields */
union tcd_SDF_tag {
uint32_t R;
struct {
uint16_t SMOD:5; /* source address modulo */
uint16_t SSIZE:3; /* source transfer size */
uint16_t DMOD:5; /* destination address modulo */
uint16_t DSIZE:3; /* destination transfer size */
int16_t SOFF; /* signed source address offset */
} B;
} SDF;
uint32_t NBYTES; /* inner (“minor”) byte count */
int32_t SLAST; /* last destination address adjustment, or
scatter/gather address (if e_sg = 1) */
uint32_t DADDR; /* destination address */
uint16_t CITERE_LINK:1;
uint16_t CITER:15;
int16_t DOFF; /* signed destination address offset */
/* CITER and destination fields */
union tcd_CDF_tag {
uint32_t R;
struct {
uint16_t CITERE_LINK:1;
uint16_t CITER:15;
int16_t DOFF; /* signed destination address offset */
} B;
struct {
uint16_t CITERE_LINK:1;
uint16_t CITERLINKCH:6;
uint16_t CITER:9;
int16_t DOFF;
} B_ALT;
} CDF;
int32_t DLAST_SGA;
uint16_t BITERE_LINK:1; /* beginning ("major") iteration count */
uint16_t BITER:15;
uint16_t BWC:2; /* bandwidth control */
uint16_t MAJORLINKCH:6; /* enable channel-to-channel link */
uint16_t DONE:1; /* channel done */
uint16_t ACTIVE:1; /* channel active */
uint16_t MAJORE_LINK:1; /* enable channel-to-channel link */
uint16_t E_SG:1; /* enable scatter/gather descriptor */
uint16_t D_REQ:1; /* disable ipd_req when done */
uint16_t INT_HALF:1; /* interrupt on citer = (biter >> 1) */
uint16_t INT_MAJ:1; /* interrupt on major loop completion */
uint16_t START:1; /* explicit channel start */
/* BITER and misc fields */
union tcd_BMF_tag {
uint32_t R;
struct {
uint32_t BITERE_LINK:1; /* beginning ("major") iteration count */
uint32_t BITER:15;
uint32_t BWC:2; /* bandwidth control */
uint32_t MAJORLINKCH:6; /* enable channel-to-channel link */
uint32_t DONE:1; /* channel done */
uint32_t ACTIVE:1; /* channel active */
uint32_t MAJORE_LINK:1; /* enable channel-to-channel link */
uint32_t E_SG:1; /* enable scatter/gather descriptor */
uint32_t D_REQ:1; /* disable ipd_req when done */
uint32_t INT_HALF:1; /* interrupt on citer = (biter >> 1) */
uint32_t INT_MAJ:1; /* interrupt on major loop completion */
uint32_t START:1; /* explicit channel start */
} B;
struct {
uint32_t BITERE_LINK:1;
uint32_t BITERLINKCH:6;
uint32_t BITER:9;
uint32_t BWC:2;
uint32_t MAJORLINKCH:6;
uint32_t DONE:1;
uint32_t ACTIVE:1;
uint32_t MAJORE_LINK:1;
uint32_t E_SG:1;
uint32_t D_REQ:1;
uint32_t INT_HALF:1;
uint32_t INT_MAJ:1;
uint32_t START:1;
} B_ALT;
} BMF;
} TCD[64]; /* transfer_control_descriptor */
};
static const struct tcd_t EDMA_TCD_DEFAULT = {
.SADDR = 0,
.SDF = { .R = 0 },
.NBYTES = 0,
.SLAST = 0,
.DADDR = 0,
.CDF = { .R = 0 },
.DLAST_SGA = 0,
.BMF = { .R = 0 }
};
#define EDMA_TCD_BITER_MASK 0x7fff
@@ -2775,50 +2822,8 @@ extern "C" {
#define EDMA_TCD_LINK_AND_BITER( link, biter) (((link) << 9) + ((biter) & EDMA_TCD_BITER_LINKED_MASK))
#define EDMA_TCD_BITER_LINK( channel) (EDMA.TCD [(channel)].BITER >> 9)
#define EDMA_TCD_BITER_LINK( channel) (EDMA.TCD [(channel)].BMF.B.BITER >> 9)
/* This is outside of the eDMA structure */
/* There are 2 possible ways to use the citer bit field, this structure */
/* uses the different format from the main structure. */
struct tcd_alt_t {
uint32_t SADDR; /* source address */
uint16_t SMOD:5; /* source address modulo */
uint16_t SSIZE:3; /* source transfer size */
uint16_t DMOD:5; /* destination address modulo */
uint16_t DSIZE:3; /* destination transfer size */
int16_t SOFF; /* signed source address offset */
uint32_t NBYTES; /* inner (“minor”) byte count */
int32_t SLAST; /* last destination address adjustment, or
scatter/gather address (if e_sg = 1) */
uint32_t DADDR; /* destination address */
uint16_t CITERE_LINK:1;
uint16_t CITERLINKCH:6;
uint16_t CITER:9;
int16_t DOFF; /* signed destination address offset */
int32_t DLAST_SGA;
uint16_t BITERE_LINK:1; /* beginning (“major”) iteration count */
uint16_t BITERLINKCH:6;
uint16_t BITER:9;
uint16_t BWC:2; /* bandwidth control */
uint16_t MAJORLINKCH:6; /* enable channel-to-channel link */
uint16_t DONE:1; /* channel done */
uint16_t ACTIVE:1; /* channel active */
uint16_t MAJORE_LINK:1; /* enable channel-to-channel link */
uint16_t E_SG:1; /* enable scatter/gather descriptor */
uint16_t D_REQ:1; /* disable ipd_req when done */
uint16_t INT_HALF:1; /* interrupt on citer = (biter >> 1) */
uint16_t INT_MAJ:1; /* interrupt on major loop completion */
uint16_t START:1; /* explicit channel start */
}; /* transfer_control_descriptor */
/****************************************************************************/
/* MODULE : INTC */
/****************************************************************************/
@@ -4249,6 +4254,105 @@ extern "C" {
};
/****************************************************************************/
/* MMU */
/****************************************************************************/
struct MMU_tag {
union {
uint32_t R;
struct {
uint32_t : 2;
uint32_t TLBSEL : 2;
uint32_t : 7;
uint32_t ESEL : 5;
uint32_t : 11;
uint32_t NV : 5;
} B;
} MAS0;
union {
uint32_t R;
struct {
uint32_t VALID : 1;
uint32_t IPROT : 1;
uint32_t : 6;
uint32_t TID : 8;
uint32_t : 3;
uint32_t TS : 1;
uint32_t TSIZ : 4;
uint32_t : 8;
} B;
} MAS1;
union {
uint32_t R;
struct {
uint32_t EPN : 20;
uint32_t : 7;
uint32_t W : 1;
uint32_t I : 1;
uint32_t M : 1;
uint32_t G : 1;
uint32_t E : 1;
} B;
} MAS2;
union {
uint32_t R;
struct {
uint32_t RPN : 20;
uint32_t : 2;
uint32_t U0 : 1;
uint32_t U1 : 1;
uint32_t U2 : 1;
uint32_t U3 : 1;
uint32_t UX : 1;
uint32_t SX : 1;
uint32_t UW : 1;
uint32_t SW : 1;
uint32_t UR : 1;
uint32_t SR : 1;
} B;
} MAS3;
union {
uint32_t R;
struct {
uint32_t : 2;
uint32_t TLBSELD : 2;
uint32_t : 10;
uint32_t TIDSELD : 2;
uint32_t : 4;
uint32_t TSIZED : 4;
uint32_t : 3;
uint32_t WD : 1;
uint32_t ID : 1;
uint32_t MD : 1;
uint32_t GD : 1;
uint32_t ED : 1;
} B;
} MAS4;
union {
uint32_t R;
struct {
uint32_t : 8;
uint32_t SPID : 8;
uint32_t : 15;
uint32_t SAS : 1;
} B;
} MAS6;
};
static const struct MMU_tag MMU_DEFAULT = {
.MAS0 = { .R = 0x10000000 },
.MAS1 = { .R = 0 },
.MAS2 = { .R = 0 },
.MAS3 = { .R = 0 },
.MAS4 = { .R = 0 },
.MAS6 = { .R = 0 }
};
/* Define memories */
#define SRAM_START 0x40000000
@@ -4308,7 +4412,7 @@ extern "C" {
/*********************************************************************
*
* Copyright:
* Freescale Semiconductor, INC. All Rights Reserved.
* Freescale Semiconductor, INC. All Rights Reserved.
* You are hereby granted a copyright license to use, modify, and
* distribute the SOFTWARE so long as this entire notice is
* retained without alteration in any modified and/or redistributed

View File

@@ -21,6 +21,7 @@
#include <mpc55xx/regs.h>
#include <libcpu/raw_exception.h>
#include <libcpu/powerpc-utility.h>
#include <bsp/irq.h>
#include <bsp/irq-generic.h>
@@ -31,27 +32,27 @@
#include <rtems/status-checks.h>
/**
* @brief Returns the priority @a p of IRQ @a i from the INTC.
* @brief Returns the priority @a priority of IRQ @a vector from the INTC.
*/
rtems_status_code mpc55xx_intc_get_priority( int i, int *p)
rtems_status_code mpc55xx_intc_get_priority( rtems_vector_number vector, unsigned *priority)
{
if (MPC55XX_IRQ_IS_VALID( i)) {
*p = INTC.PSR [i].B.PRI;
if (MPC55XX_IRQ_IS_VALID( vector)) {
*priority = INTC.PSR [vector].B.PRI;
return RTEMS_SUCCESSFUL;
} else {
*p = MPC55XX_INTC_INVALID_PRIORITY;
*priority = MPC55XX_INTC_INVALID_PRIORITY;
return RTEMS_INVALID_NUMBER;
}
}
/**
* @brief Sets the priority of IRQ @a i to @a p at the INTC.
* @brief Sets the priority of IRQ @a vector to @a priority at the INTC.
*/
rtems_status_code mpc55xx_intc_set_priority( int i, int p)
rtems_status_code mpc55xx_intc_set_priority( rtems_vector_number vector, unsigned priority)
{
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) {
if (MPC55XX_IRQ_IS_VALID( vector) && MPC55XX_INTC_IS_VALID_PRIORITY( priority)) {
INTC.PSR [vector].B.PRI = priority;
if (INTC.PSR [vector].B.PRI == priority) {
return RTEMS_SUCCESSFUL;
} else {
return RTEMS_IO_ERROR;
@@ -62,12 +63,12 @@ rtems_status_code mpc55xx_intc_set_priority( int i, int p)
}
/**
* @brief Raises the software IRQ with number @a i.
* @brief Raises the software IRQ with number @a vector.
*/
rtems_status_code mpc55xx_intc_raise_software_irq( int i)
rtems_status_code mpc55xx_intc_raise_software_irq( rtems_vector_number vector)
{
if (MPC55XX_IRQ_IS_SOFTWARE( i)) {
INTC.SSCIR [i].B.SET = 1;
if (MPC55XX_IRQ_IS_SOFTWARE( vector)) {
INTC.SSCIR [vector].B.SET = 1;
return RTEMS_SUCCESSFUL;
} else {
return RTEMS_INVALID_NUMBER;
@@ -75,12 +76,12 @@ rtems_status_code mpc55xx_intc_raise_software_irq( int i)
}
/**
* @brief Clears the software IRQ with number @a i.
* @brief Clears the software IRQ with number @a vector.
*/
rtems_status_code mpc55xx_intc_clear_software_irq( int i)
rtems_status_code mpc55xx_intc_clear_software_irq( rtems_vector_number vector)
{
if (MPC55XX_IRQ_IS_SOFTWARE( i)) {
INTC.SSCIR [i].B.CLR = 1;
if (MPC55XX_IRQ_IS_SOFTWARE( vector)) {
INTC.SSCIR [vector].B.CLR = 1;
return RTEMS_SUCCESSFUL;
} else {
return RTEMS_INVALID_NUMBER;
@@ -92,18 +93,19 @@ rtems_status_code mpc55xx_intc_clear_software_irq( int i)
*/
rtems_status_code mpc55xx_interrupt_handler_install(
rtems_vector_number vector,
int priority,
const char *info,
rtems_option options,
unsigned priority,
rtems_interrupt_handler handler,
void *arg
)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
if (MPC55XX_IRQ_IS_VALID( vector) && MPC55XX_INTC_IS_VALID_PRIORITY( priority)) {
rtems_status_code sc = RTEMS_SUCCESSFUL;
sc = rtems_interrupt_handler_install( vector, info, options, handler, arg);
RTEMS_CHECK_SC( sc, "Install interrupt handler");
return mpc55xx_intc_set_priority( vector, priority);
} else {
return RTEMS_INVALID_NUMBER;
@@ -116,19 +118,16 @@ rtems_status_code mpc55xx_interrupt_handler_install(
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;
rtems_vector_number vector = INTC.IACKR.B.INTVEC;
/* Save current interrupt level */
uint32_t level = _ISR_Get_level();
/* Enable all interrupts */
_ISR_Set_level( 0);
/* Save machine state and enable external exceptions */
uint32_t msr = ppc_external_exceptions_enable();
/* Dispatch interrupt handlers */
bsp_interrupt_handler_dispatch( vector_number);
bsp_interrupt_handler_dispatch( vector);
/* Restore interrupt level */
_ISR_Set_level( level);
/* Restore machine state */
ppc_external_exceptions_disable( msr);
/* End of interrupt */
INTC.EOIR.R = 1;

View File

@@ -287,6 +287,10 @@ $(PROJECT_INCLUDE)/mpc55xx/edma.h: mpc55xx/include/edma.h $(PROJECT_INCLUDE)/mpc
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/edma.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/edma.h
$(PROJECT_INCLUDE)/mpc55xx/emios.h: mpc55xx/include/emios.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/emios.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/emios.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