summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--c/src/ChangeLog6
-rw-r--r--c/src/lib/libbsp/powerpc/gen83xx/ChangeLog8
-rw-r--r--c/src/lib/libbsp/powerpc/gen83xx/Makefile.am13
-rw-r--r--c/src/lib/libbsp/powerpc/gen83xx/i2c/i2c_init.c7
-rw-r--r--c/src/lib/libbsp/powerpc/gen83xx/include/bsp.h7
-rw-r--r--c/src/lib/libcpu/powerpc/ChangeLog21
-rw-r--r--c/src/lib/libcpu/powerpc/Makefile.am8
-rw-r--r--c/src/lib/libcpu/powerpc/mpc83xx/i2c/mpc83xx_i2cdrv.c165
-rw-r--r--c/src/lib/libcpu/powerpc/mpc83xx/include/mpc83xx.h27
-rw-r--r--c/src/lib/libcpu/powerpc/mpc83xx/network/tsec.c118
-rw-r--r--c/src/lib/libcpu/powerpc/preinstall.am4
-rw-r--r--c/src/libchip/Makefile.am6
-rw-r--r--c/src/libchip/preinstall.am4
-rw-r--r--cpukit/ChangeLog6
-rw-r--r--cpukit/libi2c/libi2c.c98
-rw-r--r--cpukit/libi2c/libi2c.h98
16 files changed, 505 insertions, 91 deletions
diff --git a/c/src/ChangeLog b/c/src/ChangeLog
index 51a4462d81..e1c189ba8c 100644
--- a/c/src/ChangeLog
+++ b/c/src/ChangeLog
@@ -1,3 +1,9 @@
+2007-09-24 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+
+ * libchip/i2c/spi-flash-m25p40.c, libchip/i2c/spi-flash-m25p40.c,
+ * libchip/Makefile.am:
+ added SPI flash driver for a M25P40 chip (based on libi2c extensions)
+
2007-09-25 Joel Sherrill <joel.sherrill@OARcorp.com>
* libchip/shmdr/dump.c, libchip/shmdr/shm_driver.h: Fix warnings.
diff --git a/c/src/lib/libbsp/powerpc/gen83xx/ChangeLog b/c/src/lib/libbsp/powerpc/gen83xx/ChangeLog
index 8a78ce195f..8c1865e233 100644
--- a/c/src/lib/libbsp/powerpc/gen83xx/ChangeLog
+++ b/c/src/lib/libbsp/powerpc/gen83xx/ChangeLog
@@ -1,3 +1,11 @@
+2007-10-25 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+
+ * include/bsp.h: fixed some typos
+
+2007-10-25 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+
+ * Makefile.am, spi/spi_init.c, include/bsp.h: add spi support
+
2007-09-17 Joel Sherrill <joel.sherrill@OARcorp.com>
* console/console.c, irq/irq_init.c: Eliminate warnings.
diff --git a/c/src/lib/libbsp/powerpc/gen83xx/Makefile.am b/c/src/lib/libbsp/powerpc/gen83xx/Makefile.am
index efb6ce6da7..ddf23f28e3 100644
--- a/c/src/lib/libbsp/powerpc/gen83xx/Makefile.am
+++ b/c/src/lib/libbsp/powerpc/gen83xx/Makefile.am
@@ -76,7 +76,7 @@ irq_rel_CPPFLAGS = $(AM_CPPFLAGS)
irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_PROGRAMS += console.rel
-console_rel_SOURCES = console/console.c console/ns16550cfg.c
+console_rel_SOURCES = console/console.c console/ns16550cfg.c
console_rel_CPPFLAGS = $(AM_CPPFLAGS)
console_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
@@ -93,10 +93,16 @@ bsp_i2c_rel_SOURCES = i2c/i2c_init.c
bsp_i2c_rel_CPPFLAGS = $(AM_CPPFLAGS)
bsp_i2c_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+noinst_PROGRAMS += bsp_spi.rel
+bsp_spi_rel_SOURCES = spi/spi_init.c
+bsp_spi_rel_CPPFLAGS = $(AM_CPPFLAGS)
+bsp_spi_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+
noinst_LIBRARIES = libbsp.a
libbsp_a_SOURCES =
libbsp_a_LIBADD = startup.rel pclock.rel console.rel vectors.rel irq.rel \
- mpc83xx_regs.rel bsp_i2c.rel
+ mpc83xx_regs.rel bsp_i2c.rel bsp_spi.rel
libbsp_a_LIBADD += ../../../libcpu/@RTEMS_CPU@/shared/cpuIdent.rel \
../../../libcpu/@RTEMS_CPU@/shared/cache.rel \
../../../libcpu/@RTEMS_CPU@/@exceptions@/rtems-cpu.rel \
@@ -106,7 +112,8 @@ libbsp_a_LIBADD += ../../../libcpu/@RTEMS_CPU@/shared/cpuIdent.rel \
../../../libcpu/@RTEMS_CPU@/mpc6xx/clock.rel \
../../../libcpu/@RTEMS_CPU@/mpc6xx/mmu.rel \
../../../libcpu/@RTEMS_CPU@/mpc6xx/timer.rel \
- ../../../libcpu/@RTEMS_CPU@/mpc83xx/i2c.rel
+ ../../../libcpu/@RTEMS_CPU@/mpc83xx/i2c.rel \
+ ../../../libcpu/@RTEMS_CPU@/mpc83xx/spi.rel
if HAS_NETWORKING
libbsp_a_LIBADD += network.rel
diff --git a/c/src/lib/libbsp/powerpc/gen83xx/i2c/i2c_init.c b/c/src/lib/libbsp/powerpc/gen83xx/i2c/i2c_init.c
index c64d8e45f0..868cf0c8c5 100644
--- a/c/src/lib/libbsp/powerpc/gen83xx/i2c/i2c_init.c
+++ b/c/src/lib/libbsp/powerpc/gen83xx/i2c/i2c_init.c
@@ -73,9 +73,10 @@ rtems_status_code bsp_register_i2c
{
int ret_code;
+ int i2c1_busno,i2c2_busno;
/*
- * init I2C library
+ * init I2C library (if not already done)
*/
rtems_libi2c_initialize ();
@@ -87,6 +88,7 @@ rtems_status_code bsp_register_i2c
if (ret_code < 0) {
return -ret_code;
}
+ i2c1_busno = ret_code;
/*
* register second I2C bus
*/
@@ -95,12 +97,13 @@ rtems_status_code bsp_register_i2c
if (ret_code < 0) {
return -ret_code;
}
+ i2c2_busno = ret_code;
/*
* register EEPROM to bus 1, Address 0x50
*/
ret_code = rtems_libi2c_register_drv(RTEMS_BSP_I2C_EEPROM_DEVICE_NAME,
i2c_2b_eeprom_driver_descriptor,
- 0,0x50);
+ i2c1_busno,0x50);
if (ret_code < 0) {
return -ret_code;
}
diff --git a/c/src/lib/libbsp/powerpc/gen83xx/include/bsp.h b/c/src/lib/libbsp/powerpc/gen83xx/include/bsp.h
index 857edac726..7b019d7eb6 100644
--- a/c/src/lib/libbsp/powerpc/gen83xx/include/bsp.h
+++ b/c/src/lib/libbsp/powerpc/gen83xx/include/bsp.h
@@ -239,6 +239,7 @@ extern rtems_configuration_table BSP_Configuration;
void bsp_cleanup(void);
rtems_status_code bsp_register_i2c(void);
+rtems_status_code bsp_register_spi(void);
/* console modes (only termios) */
#ifdef PRINTK_MINOR
@@ -280,6 +281,12 @@ extern int BSP_tsec_attach(struct rtems_bsdnet_ifconfig *config,int attaching);
#define RTEMS_BSP_I2C_EEPROM_DEVICE_NAME "eeprom"
#define RTEMS_BSP_I2C_EEPROM_DEVICE_PATH "/dev/i2c1.eeprom"
+/*
+ * SPI Flash device name
+ */
+#define RTEMS_BSP_SPI_FLASH_DEVICE_NAME "flash"
+#define RTEMS_BSP_SPI_FLASH_DEVICE_PATH "/dev/spi.flash"
+
#ifdef __cplusplus
}
#endif
diff --git a/c/src/lib/libcpu/powerpc/ChangeLog b/c/src/lib/libcpu/powerpc/ChangeLog
index 13562c767f..8bee2193b9 100644
--- a/c/src/lib/libcpu/powerpc/ChangeLog
+++ b/c/src/lib/libcpu/powerpc/ChangeLog
@@ -1,3 +1,24 @@
+2007-10-25 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+
+ * mpc83xx/network/tsec.c:
+ fixed typo in comment of attach function
+
+2007-10-25 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+
+ * Makefile.am, mpc83xx/spi/mpc83xx_spidrv.c,
+ * mpc83xx/spi/mpc83xx_spidrv.h, mpc83xx/include/mpc83xx.h:
+ added spi driver
+
+2007-10-25 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+
+ * mpc83xx/i2c/mpc83xx_i2cdrv.c:
+ added IRQ support in I2C driver
+
+2007-10-25 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+
+ * mpc83xx/network/tsec.c:
+ added statistics counters to tsec
+
2007-09-12 Joel Sherrill <joel.sherrill@OARcorp.com>
PR 1257/bsps
diff --git a/c/src/lib/libcpu/powerpc/Makefile.am b/c/src/lib/libcpu/powerpc/Makefile.am
index cfc7e45660..c5290d5d9a 100644
--- a/c/src/lib/libcpu/powerpc/Makefile.am
+++ b/c/src/lib/libcpu/powerpc/Makefile.am
@@ -348,6 +348,14 @@ mpc83xx_i2c_rel_SOURCES = mpc83xx/i2c/mpc83xx_i2cdrv.c \
mpc83xx_i2c_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc83xx_i2c_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+## mpc83xx/spi
+include_mpc83xx_HEADERS += mpc83xx/spi/mpc83xx_spidrv.h
+noinst_PROGRAMS += mpc83xx/spi.rel
+mpc83xx_spi_rel_SOURCES = mpc83xx/spi/mpc83xx_spidrv.c \
+ mpc83xx/spi/mpc83xx_spidrv.h
+mpc83xx_spi_rel_CPPFLAGS = $(AM_CPPFLAGS)
+mpc83xx_spi_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
endif
include $(srcdir)/preinstall.am
diff --git a/c/src/lib/libcpu/powerpc/mpc83xx/i2c/mpc83xx_i2cdrv.c b/c/src/lib/libcpu/powerpc/mpc83xx/i2c/mpc83xx_i2cdrv.c
index 5b0f6cd88f..57b97a0967 100644
--- a/c/src/lib/libcpu/powerpc/mpc83xx/i2c/mpc83xx_i2cdrv.c
+++ b/c/src/lib/libcpu/powerpc/mpc83xx/i2c/mpc83xx_i2cdrv.c
@@ -26,11 +26,7 @@
#include <errno.h>
#include <rtems/libi2c.h>
-/* #define DEBUG */
-
-/*
- * XXX: for the beginning, this driver works polled
- */
+#define DEBUG
/*=========================================================================*\
| Function: |
@@ -110,9 +106,12 @@ static int mpc83xx_i2c_wait
#if defined(DEBUG)
printk("mpc83xx_i2c_wait called... ");
#endif
- softc_ptr->reg_ptr->i2ccr |= MPC83XX_I2CCR_MIEN;
if (softc_ptr->initialized) {
+ /*
+ * enable interrupt mask
+ */
+ softc_ptr->reg_ptr->i2ccr |= MPC83XX_I2CCR_MIEN;
rc = rtems_semaphore_obtain(softc_ptr->irq_sema_id,RTEMS_WAIT,100);
if (rc != RTEMS_SUCCESSFUL) {
return rc;
@@ -131,8 +130,8 @@ static int mpc83xx_i2c_wait
}
softc_ptr->reg_ptr->i2ccr &= ~MPC83XX_I2CCR_MIEN;
- act_status = softc_ptr->reg_ptr->i2csr & status_mask;
- if (act_status != desired_status) {
+ act_status = softc_ptr->reg_ptr->i2csr;
+ if ((act_status & status_mask) != desired_status) {
#if defined(DEBUG)
printk("... exit with RTEMS_IO_ERROR\r\n");
#endif
@@ -147,6 +146,145 @@ static int mpc83xx_i2c_wait
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
+static void mpc83xx_i2c_irq_handler
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| handle interrupts |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ rtems_irq_hdl_param handle /* handle, is softc_ptr structure */
+)
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| <none> |
+\*=========================================================================*/
+{
+ mpc83xx_i2c_softc_t *softc_ptr = (mpc83xx_i2c_softc_t *)handle;
+
+ /*
+ * disable interrupt mask
+ */
+ softc_ptr->reg_ptr->i2ccr &= ~MPC83XX_I2CCR_MIEN;
+ if (softc_ptr->initialized) {
+ rtems_semaphore_release(softc_ptr->irq_sema_id);
+ }
+}
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+static void mpc83xx_i2c_irq_on_off
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| enable/disable interrupts (void, handled at different position) |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ const
+ rtems_irq_connect_data *irq_conn_data /* irq connect data */
+)
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| <none> |
+\*=========================================================================*/
+{
+}
+
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+static int mpc83xx_i2c_irq_isOn
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| check state of interrupts, void, done differently |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ const
+ rtems_irq_connect_data *irq_conn_data /* irq connect data */
+)
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| TRUE, if enabled |
+\*=========================================================================*/
+{
+ return (TRUE);
+}
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+static void mpc83xx_i2c_install_irq_handler
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| (un-)install the interrupt handler |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ mpc83xx_i2c_softc_t *softc_ptr, /* ptr to control structure */
+ int install /* TRUE: install, FALSE: remove */
+)
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| <none> |
+\*=========================================================================*/
+{
+ rtems_status_code rc = RTEMS_SUCCESSFUL;
+
+ rtems_irq_connect_data irq_conn_data = {
+ softc_ptr->irq_number,
+ mpc83xx_i2c_irq_handler, /* rtems_irq_hdl */
+ (rtems_irq_hdl_param)softc_ptr, /* (rtems_irq_hdl_param) */
+ mpc83xx_i2c_irq_on_off, /* (rtems_irq_enable) */
+ mpc83xx_i2c_irq_on_off, /* (rtems_irq_disable) */
+ mpc83xx_i2c_irq_isOn /* (rtems_irq_is_enabled) */
+ };
+
+ /*
+ * (un-)install handler for I2C device
+ */
+ if (install) {
+ /*
+ * create semaphore for IRQ synchronization
+ */
+ rc = rtems_semaphore_create(rtems_build_name('i','2','c','s'),
+ 0,
+ RTEMS_FIFO
+ | RTEMS_SIMPLE_BINARY_SEMAPHORE,
+ 0,
+ &softc_ptr->irq_sema_id);
+ if (rc != RTEMS_SUCCESSFUL) {
+ rtems_panic("I2C: cannot create semaphore");
+ }
+ if (!BSP_install_rtems_irq_handler (&irq_conn_data)) {
+ rtems_panic("I2C: cannot install IRQ handler");
+ }
+ }
+ else {
+ if (!BSP_remove_rtems_irq_handler (&irq_conn_data)) {
+ rtems_panic("I2C: cannot uninstall IRQ handler");
+ }
+ /*
+ * delete sync semaphore
+ */
+ if (softc_ptr->irq_sema_id != 0) {
+ rc = rtems_semaphore_delete(softc_ptr->irq_sema_id);
+ if (rc != RTEMS_SUCCESSFUL) {
+ rtems_panic("I2C: cannot delete semaphore");
+ }
+ }
+ }
+}
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
static rtems_status_code mpc83xx_i2c_init
(
/*-------------------------------------------------------------------------*\
@@ -185,7 +323,7 @@ static rtems_status_code mpc83xx_i2c_init
*/
softc_ptr->reg_ptr->i2cdfsrr = 0x10 ; /* no special filtering needed */
/*
- * set own slave address to broadcasr (0x00)
+ * set own slave address to broadcast (0x00)
*/
softc_ptr->reg_ptr->i2cadr = 0x00 ;
@@ -195,11 +333,14 @@ static rtems_status_code mpc83xx_i2c_init
softc_ptr->reg_ptr->i2ccr = MPC83XX_I2CCR_MEN;
/*
- * FIXME: init interrupt stuff
- */
+ * init interrupt stuff
+ */
+ mpc83xx_i2c_install_irq_handler(softc_ptr,TRUE);
+
/*
- * FIXME: init other stuff
+ * mark, that we have initialized
*/
+ softc_ptr->initialized = TRUE;
#if defined(DEBUG)
printk("... exit OK\r\n");
#endif
diff --git a/c/src/lib/libcpu/powerpc/mpc83xx/include/mpc83xx.h b/c/src/lib/libcpu/powerpc/mpc83xx/include/mpc83xx.h
index 6c7288164e..ee06c2fee7 100644
--- a/c/src/lib/libcpu/powerpc/mpc83xx/include/mpc83xx.h
+++ b/c/src/lib/libcpu/powerpc/mpc83xx/include/mpc83xx.h
@@ -376,6 +376,29 @@ typedef struct m83xxSPIRegisters_ {
volatile uint32_t spird; /* 0x0_7034 SPI receive register R 0xFFFF_FFFF 19.4.1.6/19-15 */
uint8_t reserved0_7038[0x07100-0x07038];/* 0x0_7038-70FF Reserved */
} m83xxSPIRegisters_t;
+ /* SPIMODE register fields */
+#define MPC83XX_SPIMODE_LOOP (1 << (31- 1)) /* loopback */
+#define MPC83XX_SPIMODE_CI (1 << (31- 2)) /* clock invert */
+#define MPC83XX_SPIMODE_CP (1 << (31- 3)) /* clock phase */
+#define MPC83XX_SPIMODE_DIV16 (1 << (31- 4)) /* divide by 16 */
+#define MPC83XX_SPIMODE_REV (1 << (31- 5)) /* LSB first */
+#define MPC83XX_SPIMODE_M_S (1 << (31- 6)) /* master/slave */
+#define MPC83XX_SPIMODE_EN (1 << (31- 7)) /* enable */
+#define MPC83XX_SPIMODE_LEN(n) ((n) << (31-11)) /* length code */
+#define MPC83XX_SPIMODE_PM(n) ((n) << (31-15)) /* prescaler */
+#define MPC83XX_SPIMODE_OD (1 << (31-19)) /* open drain */
+
+ /* SPCOM register fields */
+#define MPC83XX_SPCOM_LST (1 << (31- 9)) /* last transfer */
+
+ /* SPIE/M register fields */
+#define MPC83XX_SPIE_LT (1 << (31-17)) /* last character transmitted */
+#define MPC83XX_SPIE_DNR (1 << (31-18)) /* data not ready */
+#define MPC83XX_SPIE_OV (1 << (31-19)) /* overrun */
+#define MPC83XX_SPIE_UN (1 << (31-20)) /* unterrun */
+#define MPC83XX_SPIE_MME (1 << (31-21)) /* multi-master error */
+#define MPC83XX_SPIE_NE (1 << (31-22)) /* not empty */
+#define MPC83XX_SPIE_NF (1 << (31-23)) /* not full */
typedef struct m83xxDMARegisters_ {
/* DMA Registers */
@@ -774,6 +797,10 @@ typedef struct m83xxTSEC_Registers_ {
*/
#define M83xx_TSEC_TSTAT_THLT (1<<(31-0))
+/*
+ * TSEC RSTAT bit definitions
+ */
+#define M83xx_TSEC_RSTAT_QHLT (1<<(31-8))
/*
* TSEC ECNTRL bit positions
*/
diff --git a/c/src/lib/libcpu/powerpc/mpc83xx/network/tsec.c b/c/src/lib/libcpu/powerpc/mpc83xx/network/tsec.c
index bccc05c651..8b3ac09e96 100644
--- a/c/src/lib/libcpu/powerpc/mpc83xx/network/tsec.c
+++ b/c/src/lib/libcpu/powerpc/mpc83xx/network/tsec.c
@@ -94,23 +94,12 @@ struct mpc83xx_tsec_struct {
* statistic counters Rx
*/
unsigned long rxInterrupts;
- unsigned long rxNotLast;
- unsigned long rxGiant;
- unsigned long rxNonOctet;
- unsigned long rxBadCRC;
- unsigned long rxOverrun;
- unsigned long rxCollision;
-
+ unsigned long rxErrors;
/*
* statistic counters Tx
*/
unsigned long txInterrupts;
- unsigned long txDeferred;
- unsigned long txLateCollision;
- unsigned long txUnderrun;
- unsigned long txMisaligned;
- unsigned long rxNotFirst;
- unsigned long txRetryLimit;
+ unsigned long txErrors;
};
static struct mpc83xx_tsec_struct tsec_driver[M83xx_TSEC_NIFACES];
@@ -238,10 +227,14 @@ static void mpc83xx_tsec_hwinit
* due to alignment */
/*
- * init EDIS register: enable all error reportings
- * FIXME: make sure we handle these errors correctly
+ * init EDIS register: disable all error reportings
*/
- reg_ptr->edis = 0;
+ reg_ptr->edis = (M83xx_TSEC_EDIS_BSYDIS |
+ M83xx_TSEC_EDIS_EBERRDIS |
+ M83xx_TSEC_EDIS_TXEDIS |
+ M83xx_TSEC_EDIS_LCDIS |
+ M83xx_TSEC_EDIS_CRLXDADIS |
+ M83xx_TSEC_EDIS_FUNDIS);
/*
* init minimum frame length register
*/
@@ -616,26 +609,6 @@ static void mpc83xx_tsec_receive_packets
* throw away mbuf
*/
MFREE(m,n);
- /*
- * update statistics
- */
- if (0 != (status & M83xx_BD_LAST))
- sc->rxNotLast++;
- if (0 != (status & M83xx_BD_FIRST_IN_FRAME))
- sc->rxNotFirst++;
-
- if (0 == (status & M83xx_BD_LONG)) {
- sc->rxGiant++;
- }
- if (0 == (status & M83xx_BD_NONALIGNED)) {
- sc->rxNonOctet++;
- }
- if (0 == (status & M83xx_BD_CRC_ERROR)) {
- sc->rxBadCRC++;
- }
- if (0 == (status & M83xx_BD_OVERRUN)) {
- sc->rxOverrun++;
- }
}
/*
* mark buffer as non-allocated (for refill)
@@ -1234,18 +1207,26 @@ static void mpc83xx_tsec_err_irq_handler
| <none> |
\*=========================================================================*/
{
+ struct mpc83xx_tsec_struct *sc =
+ (struct mpc83xx_tsec_struct *)handle;
/*
- * FIXME: check error conditions, do something useful
+ * clear error events in IEVENT
*/
-#if 0
+ sc->reg_ptr->tstat = M83xx_IEVENT_ERRALL;
/*
- * disable error interrupts
+ * has Rx been stopped? then restart it
*/
- M83xx_TSEC_IMASK_SET(sc->reg_ptr->imask,M83xx_IEVENT_ERRALL,0);
+ if (0 != (sc->reg_ptr->rstat & M83xx_TSEC_RSTAT_QHLT)) {
+ sc->rxErrors++;
+ sc->reg_ptr->rstat = M83xx_TSEC_RSTAT_QHLT;
+ }
/*
- * FIXME: do something :-)
+ * has Tx been stopped? then restart it
*/
-#endif
+ if (0 != (sc->reg_ptr->tstat & M83xx_TSEC_TSTAT_THLT)) {
+ sc->txErrors++;
+ sc->reg_ptr->tstat = M83xx_TSEC_TSTAT_THLT;
+ }
}
@@ -1529,7 +1510,7 @@ static void mpc83xx_tsec_off
\*=========================================================================*/
{
/*
- * FIXME: deinitialize driver
+ * deinitialize driver?
*/
}
@@ -1540,7 +1521,7 @@ static void mpc83xx_tsec_stats
(
/*-------------------------------------------------------------------------*\
| Purpose: |
-| perform io control functions |
+| print statistics |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
@@ -1568,21 +1549,35 @@ static void mpc83xx_tsec_stats
/*
* print some statistics
*/
- printf (" Rx Interrupts:%-8lu", sc->rxInterrupts);
- printf (" Not First:%-8lu", sc->rxNotFirst);
- printf (" Not Last:%-8lu\n", sc->rxNotLast);
- printf (" Giant:%-8lu", sc->rxGiant);
- printf (" Non-octet:%-8lu\n", sc->rxNonOctet);
- printf (" Bad CRC:%-8lu", sc->rxBadCRC);
- printf (" Overrun:%-8lu", sc->rxOverrun);
- printf (" Collision:%-8lu\n", sc->rxCollision);
+ printf (" Rx Interrupts:%-8lu", sc->rxInterrupts);
+ printf (" Rx Errors:%-8lu", sc->rxErrors);
+ printf (" Rx packets:%-8lu\n",
+ sc->reg_ptr->rmon_mib[m83xx_tsec_rmon_rpkt]);
+ printf (" Rx broadcasts:%-8lu",
+ sc->reg_ptr->rmon_mib[m83xx_tsec_rmon_rbca]);
+ printf (" Rx multicasts:%-8lu",
+ sc->reg_ptr->rmon_mib[m83xx_tsec_rmon_rmca]);
+ printf (" Giant:%-8lu\n",
+ sc->reg_ptr->rmon_mib[m83xx_tsec_rmon_rovr]);
+ printf (" Non-octet:%-8lu",
+ sc->reg_ptr->rmon_mib[m83xx_tsec_rmon_raln]);
+ printf (" Bad CRC:%-8lu",
+ sc->reg_ptr->rmon_mib[m83xx_tsec_rmon_rfcs]);
+ printf (" Overrun:%-8lu\n",
+ sc->reg_ptr->rmon_mib[m83xx_tsec_rmon_rdrp]);
- printf (" Tx Interrupts:%-8lu", sc->txInterrupts);
- printf (" Deferred:%-8lu", sc->txDeferred);
- printf (" Late Collision:%-8lu\n", sc->txLateCollision);
- printf ("Retransmit Limit:%-8lu", sc->txRetryLimit);
- printf (" Underrun:%-8lu", sc->txUnderrun);
- printf (" Misaligned:%-8lu\n", sc->txMisaligned);
+ printf (" Tx Interrupts:%-8lu", sc->txInterrupts);
+ printf (" Tx Errors:%-8lu", sc->txErrors);
+ printf (" Tx packets:%-8lu\n",
+ sc->reg_ptr->rmon_mib[m83xx_tsec_rmon_tpkt]);
+ printf (" Deferred:%-8lu",
+ sc->reg_ptr->rmon_mib[m83xx_tsec_rmon_tdfr]);
+ printf (" Late Collision:%-8lu",
+ sc->reg_ptr->rmon_mib[m83xx_tsec_rmon_tlcl]);
+ printf ("Retransmit Limit:%-8lu\n",
+ sc->reg_ptr->rmon_mib[m83xx_tsec_rmon_tedf]);
+ printf (" Underrun:%-8lu\n",
+ sc->reg_ptr->rmon_mib[m83xx_tsec_rmon_tund]);
}
/*=========================================================================*\
@@ -1632,7 +1627,7 @@ static int mpc83xx_tsec_ioctl
mpc83xx_tsec_off(sc);
}
if (ifp->if_flags & IFF_UP) {
- mpc83xx_tsec_off(sc);
+ mpc83xx_tsec_init(sc);
}
break;
@@ -1644,7 +1639,7 @@ static int mpc83xx_tsec_ioctl
break;
/*
- * FIXME: All sorts of multicast commands need to be added here!
+ * All sorts of multicast commands need to be added here!
*/
default:
error = EINVAL;
@@ -1799,7 +1794,7 @@ static int mpc83xx_tsec_driver_attach
)
/*-------------------------------------------------------------------------*\
| Return Value: |
-| zero, if success |
+| 1, if success |
\*=========================================================================*/
{
struct mpc83xx_tsec_struct *sc;
@@ -1900,7 +1895,6 @@ static int mpc83xx_tsec_driver_attach
return 1;
}
-
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
diff --git a/c/src/lib/libcpu/powerpc/preinstall.am b/c/src/lib/libcpu/powerpc/preinstall.am
index c6b99de4db..46b75369a8 100644
--- a/c/src/lib/libcpu/powerpc/preinstall.am
+++ b/c/src/lib/libcpu/powerpc/preinstall.am
@@ -211,4 +211,8 @@ PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc83xx/tsec.h
$(PROJECT_INCLUDE)/mpc83xx/mpc83xx_i2cdrv.h: mpc83xx/i2c/mpc83xx_i2cdrv.h $(PROJECT_INCLUDE)/mpc83xx/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc83xx/mpc83xx_i2cdrv.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc83xx/mpc83xx_i2cdrv.h
+
+$(PROJECT_INCLUDE)/mpc83xx/mpc83xx_spidrv.h: mpc83xx/spi/mpc83xx_spidrv.h $(PROJECT_INCLUDE)/mpc83xx/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc83xx/mpc83xx_spidrv.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc83xx/mpc83xx_spidrv.h
endif
diff --git a/c/src/libchip/Makefile.am b/c/src/libchip/Makefile.am
index 51de8821f1..fb633d2837 100644
--- a/c/src/libchip/Makefile.am
+++ b/c/src/libchip/Makefile.am
@@ -64,12 +64,14 @@ EXTRA_DIST += rtc/README.ds1643 rtc/README.icm7170 rtc/README.m48t08 \
# i2c
if LIBCHIP
-include_libchip_HEADERS += i2c/i2c-ds1621.h i2c/i2c-2b-eeprom.h
+include_libchip_HEADERS += i2c/i2c-ds1621.h i2c/i2c-2b-eeprom.h \
+ i2c/spi-flash-m25p40.h
noinst_LIBRARIES += libi2cio.a
libi2cio_a_CPPFLAGS = $(AM_CPPFLAGS)
libi2cio_a_SOURCES = i2c/i2c-ds1621.c i2c/i2c-2b-eeprom.c \
- i2c/i2c-ds1621.h i2c/i2c-2b-eeprom.h
+ i2c/i2c-ds1621.h i2c/i2c-2b-eeprom.h \
+ i2c/spi-flash-m25p40.c i2c/spi-flash-m25p40.h
endif
# serial
diff --git a/c/src/libchip/preinstall.am b/c/src/libchip/preinstall.am
index e65e3928f2..0eec432aaf 100644
--- a/c/src/libchip/preinstall.am
+++ b/c/src/libchip/preinstall.am
@@ -115,6 +115,10 @@ PREINSTALL_FILES += $(PROJECT_INCLUDE)/libchip/i2c-ds1621.h
$(PROJECT_INCLUDE)/libchip/i2c-2b-eeprom.h: i2c/i2c-2b-eeprom.h $(PROJECT_INCLUDE)/libchip/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libchip/i2c-2b-eeprom.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libchip/i2c-2b-eeprom.h
+
+$(PROJECT_INCLUDE)/libchip/spi-flash-m25p40.h: i2c/spi-flash-m25p40.h $(PROJECT_INCLUDE)/libchip/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libchip/spi-flash-m25p40.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/libchip/spi-flash-m25p40.h
endif
if LIBCHIP
$(PROJECT_INCLUDE)/libchip/mc68681.h: serial/mc68681.h $(PROJECT_INCLUDE)/libchip/$(dirstamp)
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog
index 7e1ae2fa6e..47f8d8f386 100644
--- a/cpukit/ChangeLog
+++ b/cpukit/ChangeLog
@@ -1,3 +1,9 @@
+2007-10-25 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+
+ * libi2c/libi2c.c, libi2c/libi2c.h:
+ extend API to support SPI devices
+ made libi2c.h C++-proof
+
2007-10-19 Joel Sherrill <joel.sherrill@OARcorp.com>
* libcsupport/src/assoc.c: Removed. Accidentally included routine
diff --git a/cpukit/libi2c/libi2c.c b/cpukit/libi2c/libi2c.c
index 0adf2f1ae4..7069b35527 100644
--- a/cpukit/libi2c/libi2c.c
+++ b/cpukit/libi2c/libi2c.c
@@ -46,6 +46,10 @@
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
+/*
+ * adaptations to also handle SPI devices
+ * by Thomas Doerfler, embedded brains GmbH, Puchheim, Germany
+ */
#if HAVE_CONFIG_H
#include "config.h"
#endif
@@ -55,6 +59,7 @@
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
+#include <stdarg.h>
#include <rtems.h>
#include <rtems/error.h>
@@ -318,7 +323,15 @@ int
rtems_libi2c_initialize ()
{
rtems_status_code sc;
+ static boolean is_initialized = FALSE;
+ if (is_initialized) {
+ /*
+ * already called before? then skip this step
+ */
+ return 0;
+ }
+
if (!(libmutex = mutexCreate (rtems_build_name ('l', 'I', '2', 'C'))))
return -1;
@@ -331,6 +344,7 @@ rtems_libi2c_initialize ()
libmutex = 0;
return -1;
}
+ is_initialized = TRUE;
return 0;
}
@@ -428,7 +442,7 @@ not_started (int busno)
}
rtems_status_code
-rtems_libi2c_send_start (uint32_t minor)
+rtems_libi2c_send_start (rtems_device_minor_number minor)
{
int rval;
DECL_CHECKED_BH (busno, bush, minor, +)
@@ -459,7 +473,7 @@ rtems_libi2c_send_start (uint32_t minor)
}
rtems_status_code
-rtems_libi2c_send_stop (uint32_t minor)
+rtems_libi2c_send_stop (rtems_device_minor_number minor)
{
rtems_status_code rval;
DECL_CHECKED_BH (busno, bush, minor, +)
@@ -476,7 +490,7 @@ rtems_libi2c_send_stop (uint32_t minor)
}
rtems_status_code
-rtems_libi2c_send_addr (uint32_t minor, int rw)
+rtems_libi2c_send_addr (rtems_device_minor_number minor, int rw)
{
rtems_status_code sc;
DECL_CHECKED_BH (busno, bush, minor, +)
@@ -491,7 +505,9 @@ rtems_libi2c_send_addr (uint32_t minor, int rw)
}
int
-rtems_libi2c_read_bytes (uint32_t minor, unsigned char *bytes, int nbytes)
+rtems_libi2c_read_bytes (rtems_device_minor_number minor,
+ unsigned char *bytes,
+ int nbytes)
{
int sc;
DECL_CHECKED_BH (busno, bush, minor, -)
@@ -506,7 +522,9 @@ rtems_libi2c_read_bytes (uint32_t minor, unsigned char *bytes, int nbytes)
}
int
-rtems_libi2c_write_bytes (uint32_t minor, unsigned char *bytes, int nbytes)
+rtems_libi2c_write_bytes (rtems_device_minor_number minor,
+ unsigned char *bytes,
+ int nbytes)
{
int sc;
DECL_CHECKED_BH (busno, bush, minor, -)
@@ -520,8 +538,70 @@ rtems_libi2c_write_bytes (uint32_t minor, unsigned char *bytes, int nbytes)
return sc;
}
+int
+rtems_libi2c_ioctl (rtems_device_minor_number minor,
+ int cmd,
+ ...)
+{
+ va_list ap;
+ int sc = 0;
+ void *args;
+ DECL_CHECKED_BH (busno, bush, minor, -)
+
+ if (not_started (busno))
+ return -RTEMS_NOT_OWNER_OF_RESOURCE;
+
+ va_start(ap, cmd);
+ args = va_arg(ap, void *);
+
+ switch(cmd) {
+ /*
+ * add ioctls defined for this level here:
+ */
+
+ case RTEMS_LIBI2C_IOCTL_START_TFM_READ_WRITE:
+ /*
+ * address device, then set transfer mode and perform read_write transfer
+ */
+ /*
+ * perform start/address
+ */
+ if (sc == 0) {
+ sc = rtems_libi2c_send_start (minor);
+ }
+ /*
+ * set tfr mode
+ */
+ if (sc == 0) {
+ sc = bush->ops->ioctl
+ (bush,
+ RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
+ &((rtems_libi2c_tfm_read_write_t *)args)->tfr_mode);
+ }
+ /*
+ * perform read_write
+ */
+ if (sc == 0) {
+ sc = bush->ops->ioctl
+ (bush,
+ RTEMS_LIBI2C_IOCTL_READ_WRITE,
+ &((rtems_libi2c_tfm_read_write_t *)args)->rd_wr);
+ }
+ break;
+ default:
+ sc = bush->ops->ioctl (bush, cmd, args);
+ break;
+ }
+ if (sc < 0)
+ rtems_libi2c_send_stop (minor);
+ return sc;
+}
+
static int
-do_s_rw (uint32_t minor, unsigned char *bytes, int nbytes, int rw)
+do_s_rw (rtems_device_minor_number minor,
+ unsigned char *bytes,
+ int nbytes,
+ int rw)
{
rtems_status_code sc;
rtems_libi2c_bus_t *bush;
@@ -549,14 +629,16 @@ do_s_rw (uint32_t minor, unsigned char *bytes, int nbytes, int rw)
}
int
-rtems_libi2c_start_read_bytes (uint32_t minor, unsigned char *bytes,
+rtems_libi2c_start_read_bytes (rtems_device_minor_number minor,
+ unsigned char *bytes,
int nbytes)
{
return do_s_rw (minor, bytes, nbytes, 1);
}
int
-rtems_libi2c_start_write_bytes (uint32_t minor, unsigned char *bytes,
+rtems_libi2c_start_write_bytes (rtems_device_minor_number minor,
+ unsigned char *bytes,
int nbytes)
{
return do_s_rw (minor, bytes, nbytes, 0);
diff --git a/cpukit/libi2c/libi2c.h b/cpukit/libi2c/libi2c.h
index 2dfbddd458..d243574333 100644
--- a/cpukit/libi2c/libi2c.h
+++ b/cpukit/libi2c/libi2c.h
@@ -46,6 +46,7 @@
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
+
#include <rtems.h>
#include <rtems/io.h>
@@ -101,6 +102,11 @@ typedef struct rtems_libi2c_bus_ops_
/* write a number of bytes */
int (*write_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes,
int nbytes);
+ /* ioctl misc functions */
+ int (*ioctl) (rtems_libi2c_bus_t * bushdl,
+ int cmd,
+ void *buffer;
+ );
} rtems_libi2c_bus_ops_t;
@@ -265,14 +271,102 @@ rtems_libi2c_write_bytes (rtems_device_minor_number minor,
/* Send start, send address and read bytes */
int
-rtems_libi2c_start_read_bytes (uint32_t minor, unsigned char *bytes,
+rtems_libi2c_start_read_bytes (rtems_device_minor_number minor,
+ unsigned char *bytes,
int nbytes);
/* Send start, send address and write bytes */
int
-rtems_libi2c_start_write_bytes (uint32_t minor, unsigned char *bytes,
+rtems_libi2c_start_write_bytes (rtems_device_minor_number minor,
+ unsigned char *bytes,
int nbytes);
+
+/* call misc iocontrol function */
+int
+rtems_libi2c_ioctl (rtems_device_minor_number minor,
+ int cmd,
+ ...);
+/*
+ * NOTE: any low-level driver ioctl returning a negative
+ * result for release the bus (perform a STOP condition)
+ */
+/*******************************
+ * defined IOCTLs:
+ *******************************/
+#define RTEMS_LIBI2C_IOCTL_READ_WRITE 1
+/*
+ * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
+ * RTEMS_LIBI2C_IOCTL_READ_WRITE,
+ * rtems_libi2c_read_write_t *arg);
+ *
+ * This call performs a simultanous read/write transfer,
+ * which is possible (and sometimes needed) for SPI devices
+ *
+ * arg is a pointer to a rd_wr info data structure
+ *
+ * This call is only needed for SPI devices
+ */
+#define RTEMS_LIBI2C_IOCTL_START_TFM_READ_WRITE 2
+/*
+ * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
+ * RTEMS_LIBI2C_IOCTL_START_READ_WRITE,
+ * unsigned char *rd_buffer,
+ * const unsigned char *wr_buffer,
+ * int byte_cnt,
+ * const rtems_libi2c_tfr_mode_t *tfr_mode_ptr);
+ *
+ * This call addresses a slave and then:
+ * - sets the proper transfer mode,
+ * - performs a simultanous read/write transfer,
+ * (which is possible and sometimes needed for SPI devices)
+ * NOTE: - if rd_buffer is NULL, receive data will be dropped
+ * - if wr_buffer is NULL, bytes with content 0 will transmitted
+ *
+ * rd_buffer is a pointer to a receive buffer (or NULL)
+ * wr_buffer is a pointer to the data to be sent (or NULL)
+ *
+ * This call is only needed for SPI devices
+ */
+
+#define RTEMS_LIBI2C_IOCTL_SET_TFRMODE 3
+/*
+ * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
+ * RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
+ * const rtems_libi2c_tfr_mode_t *tfr_mode_ptr);
+ *
+ * This call sets an SPI device to the transfer mode needed (baudrate etc.)
+ *
+ * tfr_mode is a pointer to a structure defining the SPI transfer mode needed
+ * (see below).
+ *
+ * This call is only needed for SPI devices
+ */
+
+/*
+ * arguemtn data structures for IOCTLs defined above
+ */
+typedef struct {
+ unsigned char *rd_buf;
+ const unsigned char *wr_buf;
+ int byte_cnt;
+} rtems_libi2c_read_write_t;
+
+typedef struct {
+ uint32_t baudrate; /* maximum bits per second */
+ /* only valid for SPI drivers: */
+ uint8_t bits_per_char; /* how many bits per byte/word/longword? */
+ boolean lsb_first; /* TRUE: send LSB first */
+ boolean clock_inv; /* TRUE: inverted clock (high active) */
+ boolean clock_phs; /* TRUE: clock starts toggling at start of data tfr */
+} rtems_libi2c_tfr_mode_t;
+
+typedef struct {
+ rtems_libi2c_tfr_mode_t tfr_mode;
+ rtems_libi2c_read_write_t rd_wr;
+} rtems_libi2c_tfm_read_write_t;
+
+
#ifdef __cplusplus
}
#endif