diff options
-rw-r--r-- | c/src/ChangeLog | 6 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/gen83xx/ChangeLog | 8 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/gen83xx/Makefile.am | 13 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/gen83xx/i2c/i2c_init.c | 7 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/gen83xx/include/bsp.h | 7 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ChangeLog | 21 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/Makefile.am | 8 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/mpc83xx/i2c/mpc83xx_i2cdrv.c | 165 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/mpc83xx/include/mpc83xx.h | 27 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/mpc83xx/network/tsec.c | 118 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/preinstall.am | 4 | ||||
-rw-r--r-- | c/src/libchip/Makefile.am | 6 | ||||
-rw-r--r-- | c/src/libchip/preinstall.am | 4 | ||||
-rw-r--r-- | cpukit/ChangeLog | 6 | ||||
-rw-r--r-- | cpukit/libi2c/libi2c.c | 98 | ||||
-rw-r--r-- | cpukit/libi2c/libi2c.h | 98 |
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 |