diff options
Diffstat (limited to 'nuttx')
33 files changed, 1685 insertions, 335 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index adb52afce..a8e045616 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -3177,7 +3177,7 @@ * arch/arm/src/stm32/stm32_otgfshost.c: This driver now appears to be functional (although more testing is necesary). -6.22 2012-xx-xx Gregory Nutt <gnutt@nuttx.org> +6.22 2012-09-29 Gregory Nutt <gnutt@nuttx.org> * include/semaphore.h, sched/sem_holders.c, and lib/semaphore/sem_init.c: Fix some strange (and probably wrong) list handling when @@ -3193,7 +3193,7 @@ speed/duplex. This does not work for certain PHYs. Still some unresolved issues (also from Kate). * tools/Config.mk, Makefile, configs/*/Make.defs: Add a new Makefile - fragement to de-quoate certain strings from the Kconfig logic that + fragment to de-quote certain strings from the Kconfig logic that need to be used at path segments (Richard Cochran). * arch/arm/src/stm32/stm32_usbotghost.c: The STM32 USB host driver only works with debug turned on. The problem appears to be that with debug @@ -3201,7 +3201,7 @@ reveals a variety of errors. This check in improves NAK robustness for control transfers but does not resolve all of the issues. * configs/stm3220g-eval/*/defconfig: Calibrated delay loop. It had - never been calibrated was was way off. + never been calibrated was way off. * sched/sem_holder.c: Add logic to handler some priority inheritance cases when sem_post() is called from an interrupt handler. The logic is clearly wrong, but it is not known if this is the @@ -3212,13 +3212,13 @@ CONFIG_LIBC_STRERROR_SHORT that can be used to output shortened strings by strerror(). * arch/arm/src/stm32/stm32_usbotghost.c: Finally... the USB OTG FS - appears to handle NAKing correctly is complete. + appears to handle NAKing correctly. * configs/stm32f4discovery/*: Added and verifed support for USB OTG FS host on the STM32F4Discovery board. * configs/*/defconfig: Remove configuration documentation from config files. It is redundant, error-prone, and difficult to maintain. Configuration documentation is available in configs/README.txt for - common configurations and in configs/*/README.txt for board and MCU_ + common configurations and in configs/*/README.txt for board and MCU- specific configurations. * configs/stm3240g-eval: Add USB host support. * sched/os_bring.c, configs/*/defconfig, tools/mkconfig.c, and others: Added @@ -3226,7 +3226,7 @@ the default entry from user_start to some other symbol. Contributed by Kate. NOTE: This change does introduce a minor backward incompatibility. For example, if your application uses NSH as its start-up program, then your - code will not fail because it will be unable to find "user_start". The fix + build will now fail because it will be unable to find "user_start". The fix for this link failure is to add the following to your configuration file: CONFIG_USER_ENTRYPOINT="nsh_main". * libs/stdio/lib_libfread.c and lib_*flush*.c: Correct a couple of @@ -3269,7 +3269,7 @@ CONFIG_HEAP2_SIZE (decimal) instead of CONFIG_HEAP2_END (hex). * tools/configure.sh: Don't append the apps directory path setting if the correct setting is already in defined in the defconfig file. - * fs/fat/fs_utils.c: Improper constructed bool expression. This + * fs/fat/fs_utils.c: Improperly constructed bool expression. This would cause many unnecessary writes to FLASH (Thanks Ronen Vainish). * Kconfig: Verify configuration settings for the LPC43xx. This includes some corrections to configuration variable names and defconfig settings. @@ -3319,13 +3319,13 @@ in all places. * drivers/enc28j60.c, include/nuttx/net/enc28j60.h, and olimex-strp711/src/up_enc28j60.c: No longer passes IRQ number - as a parameters. Instead now passes a call table to manage + as a parameter. Instead now passes a call table to manage ENC28J60 GPIO interrupts. That is because GPIO interrupts are handled in different ways by different MCUs and some do not support IRQ numbers for GPIO interrupts. * mm/mm_gran* and include/nuttx/gran.h: Add a simple granule- based allocator. The intent of this allocator is to support - simple allocation of DMA I/O buffers. The initiali check-in + simple allocation of DMA I/O buffers. The initial check-in is code complete but untested (not event built into the mm/Makefile yet. * confgs/fire-stm32v2: The board port is basically functional. @@ -3352,7 +3352,7 @@ * arch/arm/include/armv7-m/irq.h: Fix a critical bug in irqsave(). It looks like sometimes the compile will re-order some instructions inapproapriately. This end result is that interrupts will get - stuff off. + stuck off. * drivers/mtd/w25.c: Beginning of a driver for the Windbond SPI FLASH family (W25x16, W25x32, and W25x64). The initial check-in is basically just the SST25 driver with some name changes. @@ -3372,7 +3372,7 @@ I2C reset logic to recover from locked devices on the bus. * configs/*/*/Make.defs, tools/Config.mk, Makefile: Refactor all common make definitions from the various Make.defs files into - the common tools/Make.mk. Add support for a verbosity options: + the common tools/Config.mk. Add support for a verbosity options: Specify V=1 on the make command line in order to see the exact commands used in the build (Contributed by Richard Cochran). * drivers/net/enc28j60.c: The ENC28J60 Ethernet driver is @@ -3400,17 +3400,17 @@ * configs/shenzhou/src/up_lcd.c: Oops. Shenzhou LCD does not have an SSD1289 controller. Its an ILI93xx. Ported the STM3240G-EVAL ILI93xx driver to work on the Shenzhou board. - * configs/shenzhou/nxwm: Added an NxWM configuratino for the + * configs/shenzhou/nxwm: Added an NxWM configuration for the Shenzhou board. This is untested on initial check-in. It will be used to verify the Shenzhou LCD driver (and eventually the touchscreen driver). * configs/shenzhou/src/up_touchscreen.c: Add ADS7843E touchscreen support for the Shenzhou board. The initial check-in is untested - and basically a clone of the the touchscreen support fro the SAM-3U. + and basically a clone of the the touchscreen support for the SAM-3U. * tools/cfgparser.c: There are some NxWidget configuration settings that must be de-quoted. * arch/arm/src/stm32/Kconfig: There is no SPI4. Some platforms - SPI3 and some do not (still not clear). + support SPI3 and some do not (still not clear). * nuttx/configs/shenzhou: Various fixes to build new NxWM configuration. * configs/shenzhou: Oops. The Shenzhou LCD is and SSD1289, @@ -3419,4 +3419,55 @@ on the Shenzhou board. * graphics/nxmu: Correct some bad parameter checking that caused failures when DEBUG was enabled. + * arch/arm/src/armv7-m/nvic.h: Add bit definitions for the AIRCR + register. + * drivers/input/ads7843.c: Need semaphore protection in logic + that samples the position. + * drivers/lcd/ssd1289.c: On some platforms we are unable to + read the device ID -- reason unknown; workaround in place. + * drivers/input/ads7843.c: Add thresholding options and an + option to swap X and Y positions. Fix some logic errors in + the SPI locking/selecting logic. + * arch/arm/src/armv7-m/up_systemreset.c: Add logic to reset + the Cortex-Mx using the AIRCR register. Contributed by Darcy + Gong. + * arch/arm/src/stm32/up_eth.c: Add logic specifically for the + DM9161 PHY. If the DM9161 failed to initialize, then use the + up_sysemreset() logic to reset the MCU. Contributed by Darcy + Gong. + * arch/arm/src/stm32/stm32_gpio.c: Add missing logic to set bit + for SPI3 remap. This fixes the XPT2046 touchscreen driver using + drivers/input/ads7843.c + * configs/shenzhou/src/up_ssd1289.c: Fix naming error in + conditional compilation. + * configs/shenzhou/nxwm/defconfig: Disable reading from the LCD. + This does not work. The hardware and the driver support the + capability, but there is some bug that causes memory corruption. + The work around for now: Just disable reading from the LCD. + * drivers/lcd/ssd1289.c: Add some logic to reduce the amount of + output when CONFIG_DEBUG_LCD is enabled. + * configs/shenzhou/nxwm/defconfig: Bug found and fixed... The + original configuration had too much stuff turned on. Reducing + stack sizes, some features, and buffer sizes made the + configuration reliable (Reading from the LCD is still disabled). + * net/uip/uip_icmpping.c: Fix problem that prevented ping from + going outside of local network. Submitted by Darcy Gong + +6.23 2012-09-29 Gregory Nutt <gnutt@nuttx.org> + + * arch/arm/src/stm32/stm32_rng.c, chip/stm32_rng.h, and other files: + Implementation of /dev/random using the STM32 Random Number + Generator (RNG). + * board.h file for shenzhou, fire-stm32v2, and olimex-stm32-p107: + Add frequencies for HSE, HSI, LSE, and LSI. These are needed + by the STM32 watchdog driver. + * CONFIG_EXAMPLES_*: To make things consistent, changed all occurrences + of CONFIG_EXAMPLE_* to CONFIG_EXAMPLES_*. + * drivers/mtd/w25.c and configs/*/src/up_w25.c: Several fixes for the + W25 SPI FLASH. + * configs/*/Make.defs: All buildroot tools now use the extension + xxx-nuttx-elf- vs. xxx-elf- + * configs/shenzhou/*/Make.defs: Now uses the new buildroot 4.6.3 + EABI toolchain. + * lib/stdio/lib_libdtoa.c: Another dtoa() fix from Mike Smith. diff --git a/nuttx/README.txt b/nuttx/README.txt index 7477e0a24..d60da2d88 100644 --- a/nuttx/README.txt +++ b/nuttx/README.txt @@ -853,9 +853,8 @@ apps |- system/ | |- i2c/README.txt | |- free/README.txt - | `- install - | `- README.txt - |- vsn/ + | |- install + | | `- README.txt | |- poweroff | | `- README.txt | |- ramtron diff --git a/nuttx/ReleaseNotes b/nuttx/ReleaseNotes index 4d7211669..b1d5f6064 100644 --- a/nuttx/ReleaseNotes +++ b/nuttx/ReleaseNotes @@ -1606,6 +1606,8 @@ The 61st release of NuttX, NuttX-5.14, was made on November 27, 2010. This release includes multiple, important bugfixes as well as a new driver for the NXP LPC1766. +This release corresponds with SVN release number: r3137 + Important bugfixes include: * Cortex-M3 Hard Fault. Fixed a hard fault problem that can occur @@ -2052,6 +2054,8 @@ interest expressed by members of the forum and because of the availability of newer, larger capacity AVR parts (that I don't have yet). +This release corresponds with SVN release number: r3730 + This release includes support for the following AVR boards. As with any initial support for new architectures, there are some incomplete areas and a few caveats that need to be stated. Here @@ -3063,3 +3067,107 @@ Bugfixes (see the change log for details) : for C++ As well as other, less critical bugs (see the ChangeLog for details) + +NuttX-6.22 +^^^^^^^^^^ + +The 89th release of NuttX, Version 6.22, was made on September 29, 2012, +and is available for download from the SourceForge website. Note +that release consists of two tarballs: nuttx-6.22.tar.gz and +apps-6.22.tar.gz. Both may be needed (see the top-level nuttx/README.txt +file for build information). + +This release corresponds with SVN release number: r5206 + +Note that all SVN information has been stripped from the tarballs. If you +need the SVN configuration, you should check out directly from SVN. Revision +r5206 should equivalent to release 6.22 of NuttX 6.22: + + svn checkout -r5206 svn://svn.code.sf.net/p/nuttx/code/trunk nuttx-code + +Or + + svn checkout -r5206 http://svn.code.sf.net/p/nuttx/code/trunk nuttx-code + +Additional new features and extended functionality: + + * RTOS: Application entry point is no longer user_start, but can be + configured using CONFIG_USER_ENTRYPOINT. NuttX now supports two work + queues: A lower priority work queue (for extended processing) and a + higher priority work queue (for quick, high priority operations). + + * Memory Management: Added a new granule-based allocated that can be + used to manage, aligned and quantized DMA memory. + + * File System: Add hooks to allocate I/O memory with and external + allocated (need if required by DMA). + + * Networking: ENC28J60 driver is (finally) verified. + + * Drivers: Add hooks USB device drivers to allocate I/O memory with and + external allocated (need if required by DMA). Driver for the Windbond + SPI FLASH family (W25x16, W25x32, W25x64, and others). ADS7843E driver + extended for TSC2046 and XPT2046 and verified. + + * ARMv7-M: Added logic to reset the MCU using the NVIC. + + * STM32: Add support for STM32F103VET6. + + * STM32 Drivers: Add logic to re-initialize UARTs a second time to + enable DMA (Mike Smith). I2C driver error recovery (Mike Smith). + + * STM32 boards: Support for USB host added add to several configurations + (or at least explained in README files). Support for the Shenzhou + STM32F107 board (see www.armjishu.com). Support for M3 Wildfire + STM32F103 board (v2 and v3). + + * Build System: Kconfig string de-quoting logic. Remove comments from + defconfig files (Kate). Add tool to create NuttX-style symbol tables. + Numerous changes to configuration logic as needed for the new mconf-based + configuration (much of this from Richard Cochran). Refactor common + Make.defs logic into tools/Config.mk (Richard Cochran). + + * Library: Configurable terse output from strerror(). Added perror() (Kate). + Add %n format to sscanf() (Kate). + + * Applications: Numerous changes and extensions to the old uIP web server + (from Kate and Max Holtzberg, see the ChangeLog for specific extensions). + UDP network discovery utility (Max Holtzberg). Embeddable Lightweight + XML-RPC Server (http://www.drdobbs.com/web-development/an-embeddable-lightweight-xml-rpc-server/184405364, Max Holtzberg). + +Bugfixes (see the change log for details). Some of these are very important +(marked *critical*): + + * RTOS: Fixes to priority inheritance logic (*critical*). waitpid() + critical section. Assertion in work_cancel() (Mike Smith). mmap() (Kate). + + * FAT File System: Improper Boolean expression caused un-necessary writes + and performance issues (*critical*, Ronen Vainish). + + * Networking: Remove an un-necessary delay from recvfrom(). This greatly + improves network performance (*critical*, Max Holtzberg). + + * Graphics: NX parameter checking errors. + + * Drivers: Fix double release of memory in SDIO-based, MMC/SD driver + (Ronen Vainish). + + * LPC17xx: Ethernet driver fixes needed for certain PHYs (Kate). + + * AVR: Fix build error (Richard Cochran). + + * STM32: USB OTG FS host driver NAKing an retries. Power management + compilation errors (Diego Sanchez). Missing SPI3 remap logic. + + * STM32 Drivers: Fix for Ethernet errata for STM32F107 (*critical*). + Ethernet buffer alignment check. Add "kludge" to Ethernet driver to + handle DM9161 PHY which (at least on the Shenzhou board), sometimes + does not come up correctly. + + * Applications: THTTPD (Kate). NSH ping when IP address is on a different + network (Darcy Gong). + + * Library: fread(), fflush(), fdopen(): Fix error handling logic (Ronen + Vainish). Fix some field-width handling issues in sscanf() + +As well as other, less critical bugs (see the ChangeLog for details) diff --git a/nuttx/TODO b/nuttx/TODO index 72a94290b..906601192 100644 --- a/nuttx/TODO +++ b/nuttx/TODO @@ -12,7 +12,7 @@ nuttx/ (2) Signals (sched/, arch/) (2) pthreads (sched/) (2) C++ Support - (5) Binary loaders (binfmt/) + (6) Binary loaders (binfmt/) (17) Network (net/, drivers/net) (3) USB (drivers/usbdev, drivers/usbhost) (11) Libraries (lib/) @@ -376,15 +376,15 @@ o Binary loaders (binfmt/) Description: Windows build issue. Some of the configurations that use NXFLAT have the linker script specified like this: - NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat.ld -no-check-sections + NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-gotoff.ld -no-check-sections That will not work for windows-based tools because they require Windows style paths. The solution is to do something like this: if ($(WINTOOL)y) - NXFLATLDSCRIPT=${cygpath -w $(TOPDIR)/binfmt/libnxflat/gnu-nxflat.ld} + NXFLATLDSCRIPT=${cygpath -w $(TOPDIR)/binfmt/libnxflat/gnu-nxflat-gotoff.ld} else - NXFLATLDSCRIPT=$(TOPDIR)/binfmt/libnxflat/gnu-nxflat.ld + NXFLATLDSCRIPT=$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-gotoff.ld endif Then use @@ -395,6 +395,48 @@ o Binary loaders (binfmt/) Priority: There are too many references like the above. They will have to get fixed as needed for Windows native tool builds. + Title: TOOLCHAIN COMPATIBILITY PROBLEM + Descripton: The older 4.3.3 compiler generates GOTOFF relocations to the constant + strings, like: + + .L3: + .word .LC0(GOTOFF) + .word .LC1(GOTOFF) + .word .LC2(GOTOFF) + .word .LC3(GOTOFF) + .word .LC4(GOTOFF) + + Where .LC0, LC1, LC2, LC3, and .LC4 are the labels correponding to strings in + the .rodata.str1.1 section. One consequence of this is that .rodata must reside + in D-Space since it will addressed relative to the GOT (see the section entitled + "Read-Only Data in RAM" at + http://nuttx.org/Documentation/NuttXNxFlat.html#limitations). + + The newer 4.6.3compiler generated PC relative relocations to the strings: + + .L2: + .word .LC0-(.LPIC0+4) + .word .LC1-(.LPIC1+4) + .word .LC2-(.LPIC2+4) + .word .LC3-(.LPIC4+4) + .word .LC4-(.LPIC5+4) + + This is good and bad. This is good because it means that .rodata.str1.1 can not + reside in FLASH with .text and can be accessed using PC-relative addressing. + That can be accomplished by simply moving the .rodata from the .data section to + the .text section in the linker script. (The NXFLAT linker script is located at + nuttx/binfmt/libnxflat/gnu-nxflat.ld). + + This is bad because a lot of stuff may get broken an a lot of test will need to + be done. One question that I have is does this apply to all kinds of .rodata? + Or just to .rodata.str1.1? + + Status: Open. Many of the required changes are in place but, unfortunately, not enough + go be fully functional. I think all of the I-Space-to-I-Space fixes are in place. + However, the generated code also includes PC-relative references to .bss which + just cannot be done. + Priority: Medium. The workaround for now is to use the older, 4.3.3 OABI compiler. + o Network (net/, drivers/net) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/nuttx/arch/arm/src/armv7-m/nvic.h b/nuttx/arch/arm/src/armv7-m/nvic.h index 1d30c5f7c..6bd842a76 100644 --- a/nuttx/arch/arm/src/armv7-m/nvic.h +++ b/nuttx/arch/arm/src/armv7-m/nvic.h @@ -175,7 +175,7 @@ #define NVIC_CPUID_BASE_OFFSET 0x0d00 /* CPUID base register */ #define NVIC_INTCTRL_OFFSET 0x0d04 /* Interrupt control state register */ #define NVIC_VECTAB_OFFSET 0x0d08 /* Vector table offset register */ -#define NVIC_AIRC_OFFSET 0x0d0c /* Application interrupt/reset contol registr */ +#define NVIC_AIRCR_OFFSET 0x0d0c /* Application interrupt/reset contol registr */ #define NVIC_SYSCON_OFFSET 0x0d10 /* System control register */ #define NVIC_CFGCON_OFFSET 0x0d14 /* Configuration control register */ #define NVIC_SYSH_PRIORITY_OFFSET(n) (0x0d14 + 4*((n) >> 2)) @@ -348,7 +348,7 @@ #define NVIC_CPUID_BASE (ARMV7M_NVIC_BASE + NVIC_CPUID_BASE_OFFSET) #define NVIC_INTCTRL (ARMV7M_NVIC_BASE + NVIC_INTCTRL_OFFSET) #define NVIC_VECTAB (ARMV7M_NVIC_BASE + NVIC_VECTAB_OFFSET) -#define NVIC_AIRC (ARMV7M_NVIC_BASE + NVIC_AIRC_OFFSET) +#define NVIC_AIRCR (ARMV7M_NVIC_BASE + NVIC_AIRCR_OFFSET) #define NVIC_SYSCON (ARMV7M_NVIC_BASE + NVIC_SYSCON_OFFSET) #define NVIC_CFGCON (ARMV7M_NVIC_BASE + NVIC_CFGCON_OFFSET) #define NVIC_SYSH_PRIORITY(n) (ARMV7M_NVIC_BASE + NVIC_SYSH_PRIORITY_OFFSET(n)) @@ -500,6 +500,20 @@ #define NVIC_SYSHCON_BUSFAULTENA (1 << 17) /* Bit 17: BusFault enabled */ #define NVIC_SYSHCON_USGFAULTENA (1 << 18) /* Bit 18: UsageFault enabled */ +/* Application Interrupt and Reset Control Register (AIRCR) */ + +#define NVIC_AIRCR_VECTRESET (1 << 0) /* Bit 0: VECTRESET */ +#define NVIC_AIRCR_VECTCLRACTIVE (1 << 1) /* Bit 1: Reserved for debug use */ +#define NVIC_AIRCR_SYSRESETREQ (1 << 2) /* Bit 2: System reset */ + /* Bits 2-7: Reserved */ +#define NVIC_AIRCR_PRIGROUP_SHIFT (8) /* Bits 8-14: PRIGROUP */ +#define NVIC_AIRCR_PRIGROUP_MASK (7 << NVIC_AIRCR_PRIGROUP_SHIFT) +#define NVIC_AIRCR_ENDIANNESS (1 << 15) /* Bit 15: 1=Big endian */ +#define NVIC_AIRCR_VECTKEY_SHIFT (16) /* Bits 16-31: VECTKEY */ +#define NVIC_AIRCR_VECTKEY_MASK (0xffff << NVIC_AIRCR_VECTKEY_SHIFT) +#define NVIC_AIRCR_VECTKEYSTAT_SHIFT (16) /* Bits 16-31: VECTKEYSTAT */ +#define NVIC_AIRCR_VECTKEYSTAT_MASK (0xffff << NVIC_AIRCR_VECTKEYSTAT_SHIFT) + /* Debug Exception and Monitor Control Register (DEMCR) */ #define NVIC_DEMCR_VCCORERESET (1 << 0) /* Bit 0: Reset Vector Catch */ diff --git a/nuttx/arch/arm/src/armv7-m/up_systemreset.c b/nuttx/arch/arm/src/armv7-m/up_systemreset.c new file mode 100644 index 000000000..0d7bd2736 --- /dev/null +++ b/nuttx/arch/arm/src/armv7-m/up_systemreset.c @@ -0,0 +1,79 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/up_systemreset.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * Darcy Gong + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> + +#include "up_arch.h" +#include "nvic.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + + /**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public functions + ****************************************************************************/ + +void up_systemreset(void) +{ + uint32_t regval; + + /* Set up for the system reset, retaining the priority group from the + * the AIRCR register. + */ + + regval = getreg32(NVIC_AIRCR) & NVIC_AIRCR_PRIGROUP_MASK; + regval |= ((0x5fa << NVIC_AIRCR_VECTKEY_SHIFT) | NVIC_AIRCR_SYSRESETREQ); + putreg32(regval, NVIC_AIRCR); + + /* Ensure completion of memory accesses */ + + __asm volatile ("dsb"); + + /* Wait for the reset */ + + for (;;); +} diff --git a/nuttx/arch/arm/src/common/up_initialize.c b/nuttx/arch/arm/src/common/up_initialize.c index 094835c29..80f9b1193 100644 --- a/nuttx/arch/arm/src/common/up_initialize.c +++ b/nuttx/arch/arm/src/common/up_initialize.c @@ -171,6 +171,12 @@ void up_initialize(void) ramlog_consoleinit(); #endif + /* Initialize the Random Number Generator (RNG) */ + +#ifdef CONFIG_DEV_RANDOM + up_rnginitialize(); +#endif + /* Initialize the system logging device */ #ifdef CONFIG_SYSLOG_CHAR diff --git a/nuttx/arch/arm/src/common/up_internal.h b/nuttx/arch/arm/src/common/up_internal.h index 9f20775c0..0d3c5b1f2 100644 --- a/nuttx/arch/arm/src/common/up_internal.h +++ b/nuttx/arch/arm/src/common/up_internal.h @@ -241,6 +241,10 @@ extern void up_pminitialize(void); # define up_pminitialize() #endif +#if defined(CONFIG_ARCH_CORTEXM3) || defined(CONFIG_ARCH_CORTEXM4) +extern void up_systemreset(void) noreturn_function; +#endif + /* Interrupt handling *******************************************************/ extern void up_irqinitialize(void); @@ -369,6 +373,12 @@ extern void up_usbuninitialize(void); # define up_usbuninitialize() #endif +/* Random Number Generator (RNG) ********************************************/ + +#ifdef CONFIG_DEV_RANDOM +extern void up_rnginitialize(void); +#endif + /**************************************************************************** * Name: up_check_stack * diff --git a/nuttx/arch/arm/src/stm32/Kconfig b/nuttx/arch/arm/src/stm32/Kconfig index 8d93fb104..2f9100236 100644 --- a/nuttx/arch/arm/src/stm32/Kconfig +++ b/nuttx/arch/arm/src/stm32/Kconfig @@ -269,6 +269,7 @@ config STM32_ETHMAC bool "Ethernet MAC" default n depends on STM32_CONNECTIVITYLINE || STM32_STM32F20XX || STM32_STM32F40XX + select ARCH_HAVE_PHY config STM32_FSMC bool "FSMC" @@ -319,6 +320,7 @@ config STM32_RNG bool "RNG" default n depends on STM32_STM32F20XX || STM32_STM32F40XX + select ARCH_HAVE_RNG config STM32_SDIO bool "SDIO" diff --git a/nuttx/arch/arm/src/stm32/Make.defs b/nuttx/arch/arm/src/stm32/Make.defs index 32e84a78a..54067a168 100644 --- a/nuttx/arch/arm/src/stm32/Make.defs +++ b/nuttx/arch/arm/src/stm32/Make.defs @@ -45,8 +45,8 @@ CMN_CSRCS = up_assert.c up_blocktask.c up_copystate.c \ up_initialize.c up_initialstate.c up_interruptcontext.c \ up_memfault.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c \ up_releasepending.c up_releasestack.c up_reprioritizertr.c \ - up_schedulesigaction.c up_sigdeliver.c up_unblocktask.c \ - up_usestack.c up_doirq.c up_hardfault.c up_svcall.c \ + up_schedulesigaction.c up_sigdeliver.c up_systemreset.c \ + up_unblocktask.c up_usestack.c up_doirq.c up_hardfault.c up_svcall.c \ up_stackcheck.c ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) @@ -83,7 +83,7 @@ endif ifeq ($(CONFIG_USBHOST),y) ifeq ($(CONFIG_STM32_OTGFS),y) -CMN_CSRCS += stm32_otgfshost.c +CMN_CSRCS += stm32_otgfshost.c endif endif @@ -124,6 +124,10 @@ ifeq ($(CONFIG_DAC),y) CHIP_CSRCS += stm32_dac.c endif +ifeq ($(CONFIG_DEV_RANDOM),y) +CHIP_CSRCS += stm32_rng.c +endif + ifeq ($(CONFIG_PWM),y) CHIP_CSRCS += stm32_pwm.c endif diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_rng.h b/nuttx/arch/arm/src/stm32/chip/stm32_rng.h new file mode 100644 index 000000000..5e31d5817 --- /dev/null +++ b/nuttx/arch/arm/src/stm32/chip/stm32_rng.h @@ -0,0 +1,77 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_rng.h + * + * Copyright (C) 2012 Max Holtzberg. All rights reserved. + * Author: Max Holtzberg <mh@uvc.de> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32_CHIP_STM32_RNG_H +#define __ARCH_ARM_STC_STM32_CHIP_STM32_RNG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include <nuttx/config.h> +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_RNG_CR_OFFSET 0x0000 /* RNG Control Register */ +#define STM32_RNG_SR_OFFSET 0x0004 /* RNG Status Register */ +#define STM32_RNG_DR_OFFSET 0x0008 /* RNG Data Register */ + +/* Register Addresses ***************************************************************/ + +#define STM32_RNG_CR (STM32_RNG_BASE+STM32_RNG_CR_OFFSET) +#define STM32_RNG_SR (STM32_RNG_BASE+STM32_RNG_SR_OFFSET) +#define STM32_RNG_DR (STM32_RNG_BASE+STM32_RNG_DR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* RNG Control Register */ + +#define RNG_CR_RNGEN (1 << 2) /* Bit 2: RNG enable */ +#define RNG_CR_IE (1 << 3) /* Bit 3: Interrupt enable */ + +/* RNG Status Register */ + +#define RNG_SR_DRDY (1 << 0) /* Bit 0: Data ready */ +#define RNG_SR_CECS (1 << 1) /* Bit 1: Clock error current status */ +#define RNG_SR_SECS (1 << 2) /* Bit 2: Seed error current status */ +#define RNG_SR_CEIS (1 << 5) /* Bit 5: Clock error interrupt status */ +#define RNG_SR_SEIS (1 << 6) /* Bit 6: Seed error interrupt status */ + +#endif /* __ARCH_ARM_STC_STM32_CHIP_STM32_RNG_H */ diff --git a/nuttx/arch/arm/src/stm32/stm32_eth.c b/nuttx/arch/arm/src/stm32/stm32_eth.c index 2e892c9e5..3054142ce 100644 --- a/nuttx/arch/arm/src/stm32/stm32_eth.c +++ b/nuttx/arch/arm/src/stm32/stm32_eth.c @@ -664,6 +664,9 @@ static void stm32_rxdescinit(FAR struct stm32_ethmac_s *priv); static int stm32_phyread(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t *value); static int stm32_phywrite(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t value); +#ifdef CONFIG_PHY_DM9161 +static inline int stm32_dm9161(FAR struct stm32_ethmac_s *priv); +#endif static int stm32_phyinit(FAR struct stm32_ethmac_s *priv); /* MAC/DMA Initialization */ @@ -1653,6 +1656,7 @@ static void stm32_receive(FAR struct stm32_ethmac_s *priv) stm32_freebuffer(priv, dev->d_buf); dev->d_buf = NULL; + dev->d_len = 0; } } } @@ -1953,7 +1957,7 @@ static void stm32_polltimer(int argc, uint32_t arg, ...) /* Check if the next TX descriptor is owned by the Ethernet DMA or CPU. We * cannot perform the timer poll if we are unable to accept another packet * for transmission. Hmmm.. might be bug here. Does this mean if there is - * a transmit in progress, we will missing TCP time state updates? + * a transmit in progress, we will miss TCP time state updates? * * In a race condition, ETH_TDES0_OWN may be cleared BUT still not available * because stm32_freeframe() has not yet run. If stm32_freeframe() has run, @@ -2480,6 +2484,72 @@ static int stm32_phywrite(uint16_t phydevaddr, uint16_t phyregaddr, uint16_t val } /**************************************************************************** + * Function: stm32_dm9161 + * + * Description: + * Special workaround for the Davicom DM9161 PHY is required. On power, + * up, the PHY is not usually configured correctly but will work after + * a powered-up reset. This is really a workaround for some more + * fundamental issue with the PHY clocking initialization, but the + * root cause has not been studied (nor will it be with this workaround). + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_PHY_DM9161 +static inline int stm32_dm9161(FAR struct stm32_ethmac_s *priv) +{ + uint16_t phyval; + int ret; + + /* Read the PHYID1 register; A failure to read the PHY ID is one + * indication that check if the DM9161 PHY CHIP is not ready. + */ + + ret = stm32_phyread(CONFIG_STM32_PHYADDR, MII_PHYID1, &phyval); + if (ret < 0) + { + ndbg("Failed to read the PHY ID1: %d\n", ret); + return ret; + } + + /* If we failed to read the PHY ID1 register, the reset the MCU to recover */ + + else if (phyval == 0xffff) + { + up_systemreset(); + } + + nvdbg("PHY ID1: 0x%04X\n", phyval); + + /* Now check the "DAVICOM Specified Configuration Register (DSCR)", Register 16 */ + + ret = stm32_phyread(CONFIG_STM32_PHYADDR, 16, &phyval); + if (ret < 0) + { + ndbg("Failed to read the PHY Register 0x10: %d\n", ret); + return ret; + } + + /* Bit 8 of the DSCR register is zero, the the DM9161 has not selected RMII. + * If RMII is not selected, then reset the MCU to recover. + */ + + else if ((phyval & (1 << 8)) == 0) + { + up_systemreset(); + } + + return OK; +} +#endif + +/**************************************************************************** * Function: stm32_phyinit * * Description: @@ -2524,6 +2594,16 @@ static int stm32_phyinit(FAR struct stm32_ethmac_s *priv) } up_mdelay(PHY_RESET_DELAY); + /* Special workaround for the Davicom DM9161 PHY is required. */ + +#ifdef CONFIG_PHY_DM9161 + ret = stm32_dm9161(priv); + if (ret < 0) + { + return ret; + } +#endif + /* Perform auto-negotion if so configured */ #ifdef CONFIG_STM32_AUTONEG diff --git a/nuttx/arch/arm/src/stm32/stm32_gpio.c b/nuttx/arch/arm/src/stm32/stm32_gpio.c index 4703e8208..1dedd7ce7 100644 --- a/nuttx/arch/arm/src/stm32/stm32_gpio.c +++ b/nuttx/arch/arm/src/stm32/stm32_gpio.c @@ -128,6 +128,7 @@ static inline void stm32_gpioremap(void) val |= AFIO_MAPR_SPI1_REMAP; #endif #ifdef CONFIG_STM32_SPI3_REMAP + val |= AFIO_MAPR_SPI3_REMAP; #endif #ifdef CONFIG_STM32_I2C1_REMAP diff --git a/nuttx/arch/arm/src/stm32/stm32_rng.c b/nuttx/arch/arm/src/stm32/stm32_rng.c new file mode 100644 index 000000000..38e8108fe --- /dev/null +++ b/nuttx/arch/arm/src/stm32/stm32_rng.c @@ -0,0 +1,264 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_rng.c + * + * Copyright (C) 2012 Max Holtzberg. All rights reserved. + * Author: Max Holtzberg <mh@uvc.de> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdint.h> +#include <stdio.h> +#include <stdbool.h> +#include <debug.h> +#include <errno.h> + +#include <nuttx/irq.h> +#include <nuttx/arch.h> + +#include "up_arch.h" +#include "chip/stm32_rng.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int stm32_rnginitialize(void); +static int stm32_interrupt(int irq, void *context); +static void stm32_enable(void); +static void stm32_disable(void); +static ssize_t stm32_read(struct file *filep, char *buffer, size_t); + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct rng_dev_s +{ + sem_t rd_devsem; /* Threads can only exclusively access the RNG */ + sem_t rd_readsem; /* To block until the buffer is filled */ + char *rd_buf; + size_t rd_buflen; + uint32_t rd_lastval; + bool rd_first; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct rng_dev_s g_rngdev; + +static const struct file_operations g_rngops = +{ + 0, /* open */ + 0, /* close */ + stm32_read, /* read */ + 0, /* write */ + 0, /* seek */ + 0 /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + ,0 /* poll */ +#endif +}; + +/**************************************************************************** + * Private functions + ****************************************************************************/ + +static int stm32_rnginitialize() +{ + uint32_t regval; + + vdbg("Initializing RNG\n"); + + memset(&g_rngdev, 0, sizeof(struct rng_dev_s)); + + sem_init(&g_rngdev.rd_devsem, 0, 1); + + if (irq_attach(STM32_IRQ_RNG, stm32_interrupt)) + { + /* We could not attach the ISR to the interrupt */ + + vdbg("Could not attach IRQ.\n"); + + return -EAGAIN; + } + + /* Enable interrupts */ + + regval = getreg32(STM32_RNG_CR); + regval |= RNG_CR_IE; + putreg32(regval, STM32_RNG_CR); + + up_enable_irq(STM32_IRQ_RNG); + + return OK; +} + +static void stm32_enable() +{ + uint32_t regval; + + g_rngdev.rd_first = true; + + regval = getreg32(STM32_RNG_CR); + regval |= RNG_CR_RNGEN; + putreg32(regval, STM32_RNG_CR); +} + +static void stm32_disable() +{ + uint32_t regval; + regval = getreg32(STM32_RNG_CR); + regval &= ~RNG_CR_RNGEN; + putreg32(regval, STM32_RNG_CR); +} + +static int stm32_interrupt(int irq, void *context) +{ + uint32_t rngsr; + uint32_t data; + + rngsr = getreg32(STM32_RNG_SR); + + if ((rngsr & (RNG_SR_SEIS | RNG_SR_CEIS)) /* Check for error bits */ + || !(rngsr & RNG_SR_DRDY)) /* Data ready must be set */ + { + /* This random value is not valid, we will try again. */ + + return OK; + } + + data = getreg32(STM32_RNG_DR); + + /* As required by the FIPS PUB (Federal Information Processing Standard + * Publication) 140-2, the first random number generated after setting the + * RNGEN bit should not be used, but saved for comparison with the next + * generated random number. Each subsequent generated random number has to be + * compared with the previously generated number. The test fails if any two + * compared numbers are equal (continuous random number generator test). + */ + + if (g_rngdev.rd_first) + { + g_rngdev.rd_first = false; + g_rngdev.rd_lastval = data; + return OK; + } + + if (g_rngdev.rd_lastval == data) + { + /* Two subsequent same numbers, we will try again. */ + + return OK; + } + + /* If we get here, the random number is valid. */ + + g_rngdev.rd_lastval = data; + + if (g_rngdev.rd_buflen >= 4) + { + g_rngdev.rd_buflen -= 4; + *(uint32_t*)&g_rngdev.rd_buf[g_rngdev.rd_buflen] = data; + } + else + { + while (g_rngdev.rd_buflen > 0) + { + g_rngdev.rd_buf[--g_rngdev.rd_buflen] = (char)data; + data >>= 8; + } + } + + if (g_rngdev.rd_buflen == 0) + { + /* Buffer filled, stop further interrupts. */ + + stm32_disable(); + sem_post(&g_rngdev.rd_readsem); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_read + ****************************************************************************/ + +static ssize_t stm32_read(struct file *filep, char *buffer, size_t buflen) +{ + if (sem_wait(&g_rngdev.rd_devsem) != OK) + { + return -errno; + } + else + { + /* We've got the semaphore. */ + + /* Initialize semaphore with 0 for blocking until the buffer is filled from + * interrupts. + */ + + sem_init(&g_rngdev.rd_readsem, 0, 1); + + g_rngdev.rd_buflen = buflen; + g_rngdev.rd_buf = buffer; + + /* Enable RNG with interrupts */ + + stm32_enable(); + + /* Wait until the buffer is filled */ + + sem_wait(&g_rngdev.rd_readsem); + + /* Free RNG for next use */ + + sem_post(&g_rngdev.rd_devsem); + + return buflen; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void up_rnginitialize() +{ + stm32_rnginitialize(); + register_driver("/dev/random", &g_rngops, 0444, NULL); +} diff --git a/nuttx/binfmt/libnxflat/gnu-nxflat.ld b/nuttx/binfmt/libnxflat/gnu-nxflat-gotoff.ld index e66b1dff5..47debd663 100644 --- a/nuttx/binfmt/libnxflat/gnu-nxflat.ld +++ b/nuttx/binfmt/libnxflat/gnu-nxflat-gotoff.ld @@ -1,7 +1,7 @@ /**************************************************************************** - * examples/nxflat/nxflat.ld + * examples/nxflat/gnu-nxflat-gotoff.ld * - * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -48,7 +48,17 @@ MEMORY * (2) DSpace (Data Space). This is the segment that contains both * read-write data (.data, .bss) as well as read-only data (.rodata). * Everything in this segment should be access-able with machine - * with machine load and store instructions. + * PIC load and store instructions. + * + * Older versions of GCC (at least up to GCC 4.3.3), use GOT-relative + * addressing to access RO data. In that case, read-only data (.rodata) must + * reside in D-Space and this linker script should be used. + * + * Newer versions of GCC (at least as of GCC 4.6.3), use PC-relative + * addressing to access RO data. In that case, read-only data (.rodata) must + * reside in I-Space and this linker script should NOT be used with those + * newer tools. + * ****************************************************************************/ SECTIONS @@ -97,11 +107,16 @@ SECTIONS .data 0x00000000 : { + /* In this model, .rodata is access using PC-relative addressing + * and, hence, must also reside in the .text section. + */ + __data_start = . ; *(.rodata) *(.rodata1) *(.rodata.*) *(.gnu.linkonce.r*) + *(.data) *(.data1) *(.data.*) diff --git a/nuttx/binfmt/libnxflat/gnu-nxflat-pcrel.ld b/nuttx/binfmt/libnxflat/gnu-nxflat-pcrel.ld new file mode 100644 index 000000000..71e4399ba --- /dev/null +++ b/nuttx/binfmt/libnxflat/gnu-nxflat-pcrel.ld @@ -0,0 +1,187 @@ +/**************************************************************************** + * examples/nxflat/gnu-nxflat-pcrel.ld + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +MEMORY +{ + ISPACE : ORIGIN = 0x0, LENGTH = 2097152 + DSPACE : ORIGIN = 0x0, LENGTH = 2097152 +} + +/**************************************************************************** + * The XFLAT program image is divided into two segments: + * + * (1) ISpace (Instruction Space). This is the segment that contains + * code (.text) as well as read-only data (.rodata). Everything in the + * segment should be fetch-able machine PC instructions (jump, branch, + * call, etc.) or PC-relative loads. + * (2) DSpace (Data Space). This is the segment that contains read-write + * data (.data, .bss). Everything in this segment should be access-able + * with machine PIC load and store instructions. + * + * Older versions of GCC (at least up to GCC 4.3.3), use GOT-relative + * addressing to access RO data. In that case, read-only data (.rodata) must + * reside in D-Space and this linker script should NOT be used with those + * older tools. + * + * Newer versions of GCC (at least as of GCC 4.6.3), use PC-relative + * addressing to access RO data. In that case, read-only data (.rodata) must + * reside in I-Space and this linker script should be used. + * + ****************************************************************************/ + +SECTIONS +{ + .text 0x00000000 : + { + /* ISpace is located at address 0. Every (unrelocated) ISpace + * address is an offset from the begining of this segment. + */ + + text_start = . ; + + *(.text) + *(.text.*) + *(.gnu.warning) + *(.stub) + *(.glue_7) + *(.glue_7t) + *(.jcr) + + /* C++ support: The .init and .fini sections contain XFLAT- + * specific logic to manage static constructors and destructors. + */ + + *(.gnu.linkonce.t.*) + *(.init) + *(.fini) + + /* This is special code area at the end of the normal + text section. It contains a small lookup table at + the start followed by the code pointed to by entries + in the lookup table. */ + + . = ALIGN (4) ; + PROVIDE(__ctbp = .); + *(.call_table_data) + *(.call_table_text) + + /* In this model, .rodata is access using PC-relative addressing + * and, hence, must also reside in the .text section. + */ + + *(.rodata) + *(.rodata1) + *(.rodata.*) + *(.gnu.linkonce.r*) + + _etext = . ; + + } > ISPACE + + /* DSpace is also located at address 0. Every (unrelocated) DSpace + * address is an offset from the begining of this segment. + */ + + .data 0x00000000 : + { + __data_start = . ; + *(.data) + *(.data1) + *(.data.*) + *(.gnu.linkonce.d*) + *(.data1) + *(.eh_frame) + *(.gcc_except_table) + + *(.gnu.linkonce.s.*) + *(__libc_atexit) + *(__libc_subinit) + *(__libc_subfreeres) + *(.note.ABI-tag) + + /* C++ support. For each global and static local C++ object, + * GCC creates a small subroutine to construct the object. Pointers + * to these routines (not the routines themselves) are stored as + * simple, linear arrays in the .ctors section of the object file. + * Similarly, pointers to global/static destructor routines are + * stored in .dtors. + */ + + *(.gnu.linkonce.d.*) + + _ctors_start = . ; + *(.ctors) + _ctors_end = . ; + _dtors_start = . ; + *(.dtors) + _dtors_end = . ; + + _edata = . ; + edata = ALIGN( 0x10 ) ; + } > DSPACE + + .bss : + { + __bss_start = _edata ; + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.scommon) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.bss*) + *(.gnu.linkonce.b*) + *(COMMON) + end = ALIGN( 0x10 ) ; + _end = ALIGN( 0x10 ) ; + } > DSPACE + + .got 0 : { *(.got.plt) *(.got) } + .junk 0 : { *(.rel*) *(.rela*) } + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/nuttx/configs/Kconfig b/nuttx/configs/Kconfig index b67c11ab3..ebe6d5480 100644 --- a/nuttx/configs/Kconfig +++ b/nuttx/configs/Kconfig @@ -23,6 +23,7 @@ config ARCH_BOARD_PX4IO depends on ARCH_CHIP_STM32F100C8 ---help--- PX4 system I/O expansion board + endchoice config ARCH_BOARD diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt index 5bbec874f..e6bde645d 100644 --- a/nuttx/configs/README.txt +++ b/nuttx/configs/README.txt @@ -1524,7 +1524,7 @@ configs/c5471evm This is a port to the Spectrum Digital C5471 evaluation board. The TMS320C5471 is a dual core processor from TI with an ARM7TDMI general purpose processor and a c54 DSP. It is also known as TMS320DA180 or just DA180. - NuttX runs on the ARM core and is built with a GNU arm-elf toolchain*. + NuttX runs on the ARM core and is built with a GNU arm-nuttx-elf toolchain*. This port is complete and verified. configs/compal_e88 and compal_e99 @@ -1540,19 +1540,19 @@ configs/demo9s12ne64 configs/ea3131 Embedded Artists EA3131 Development board. This board is based on the - an NXP LPC3131 MCU. This OS is built with the arm-elf toolchain*. + an NXP LPC3131 MCU. This OS is built with the arm-nuttx-elf toolchain*. STATUS: This port is complete and mature. configs/ea3152 Embedded Artists EA3152 Development board. This board is based on the - an NXP LPC3152 MCU. This OS is built with the arm-elf toolchain*. + an NXP LPC3152 MCU. This OS is built with the arm-nuttx-elf toolchain*. STATUS: This port is has not be exercised well, but since it is a simple derivative of the ea3131, it should be fully functional. configs/eagle100 Micromint Eagle-100 Development board. This board is based on the an ARM Cortex-M3 MCU, the Luminary LM3S6918. This OS is built with the - arm-elf toolchain*. STATUS: This port is complete and mature. + arm-nuttx-elf toolchain*. STATUS: This port is complete and mature. configs/ekk-lm3s9b96 TI/Stellaris EKK-LM3S9B96 board. This board is based on the @@ -1591,7 +1591,7 @@ configs/lm3s6432-s2e configs/lm3s6965-ek Stellaris LM3S6965 Evaluation Kit. This board is based on the an ARM Cortex-M3 MCU, the Luminary/TI LM3S6965. This OS is built with the - arm-elf toolchain*. STATUS: This port is complete and mature. + arm-nuttx-elf toolchain*. STATUS: This port is complete and mature. configs/lm3s8962-ek Stellaris LMS38962 Evaluation Kit. @@ -1607,17 +1607,17 @@ configs/lpc4330-xplorer configs/m68322evb This is a work in progress for the venerable m68322evb board from - Motorola. This OS is also built with the arm-elf toolchain*. STATUS: + Motorola. This OS is also built with the arm-nuttx-elf toolchain*. STATUS: This port was never completed. configs/mbed The configurations in this directory support the mbed board (http://mbed.org) that features the NXP LPC1768 microcontroller. This OS is also built - with the arm-elf toolchain*. STATUS: Contributed. + with the arm-nuttx-elf toolchain*. STATUS: Contributed. configs/mcu123-lpc214x This port is for the NXP LPC2148 as provided on the mcu123.com - lpc214x development board. This OS is also built with the arm-elf + lpc214x development board. This OS is also built with the arm-nuttx-elf toolchain*. The port supports serial, timer0, spi, and usb. configs/micropendous3 @@ -1642,7 +1642,7 @@ configs/ne64badge not yet been fully tested. configs/ntosd-dm320 - This port uses the Neuros OSD v1.0 Dev Board with a GNU arm-elf + This port uses the Neuros OSD v1.0 Dev Board with a GNU arm-nuttx-elf toolchain*: see http://wiki.neurostechnology.com/index.php/OSD_1.0_Developer_Home @@ -1666,18 +1666,18 @@ configs/olimex-lpc1766stk Linux or Cygwin. STATUS: Complete and mature. configs/olimex-lpc2378 - This port uses the Olimex-lpc2378 board and a GNU arm-elf toolchain* under + This port uses the Olimex-lpc2378 board and a GNU arm-nuttx-elf toolchain* under Linux or Cygwin. STATUS: ostest and NSH configurations available. This port for the NXP LPC2378 was contributed by Rommel Marcelo. configs/olimex-stm32-p107 - This port uses the Olimex STM32-P107 board (STM32F107VC) and a GNU arm-elf + This port uses the Olimex STM32-P107 board (STM32F107VC) and a GNU arm-nuttx-elf toolchain* under Linux or Cygwin. See the https://www.olimex.com/dev/stm32-p107.html for further information. Contributed by Max Holtzberg. STATUS: Configurations for the basic OS test and NSH are available and verified. configs/olimex-strp711 - This port uses the Olimex STR-P711 board and a GNU arm-elf toolchain* under + This port uses the Olimex STR-P711 board and a GNU arm-nuttx-elf toolchain* under Linux or Cygwin. See the http://www.olimex.com/dev/str-p711.html" for further information. STATUS: Configurations for the basic OS test and NSH are complete and verified. diff --git a/nuttx/configs/px4io/common/setenv.sh b/nuttx/configs/px4io/common/setenv.sh index ee33a8d21..ff9a4bf8a 100755 --- a/nuttx/configs/px4io/common/setenv.sh +++ b/nuttx/configs/px4io/common/setenv.sh @@ -41,7 +41,7 @@ if [ -z "${PATH_ORIG}" ]; then export PATH_ORIG="${PATH}"; fi WD=`pwd` export RIDE_BIN="/cygdrive/c/Program Files/Raisonance/Ride/arm-gcc/bin" -export BUILDROOT_BIN="${WD}/../buildroot/build_arm_nofpu/staging_dir/bin" +export BUILDROOT_BIN="${WD}/../misc/buildroot/build_arm_nofpu/staging_dir/bin" export PATH="${BUILDROOT_BIN}:${RIDE_BIN}:/sbin:/usr/sbin:${PATH_ORIG}" echo "PATH : ${PATH}" diff --git a/nuttx/configs/px4io/io/setenv.sh b/nuttx/configs/px4io/io/setenv.sh index ee33a8d21..ff9a4bf8a 100755 --- a/nuttx/configs/px4io/io/setenv.sh +++ b/nuttx/configs/px4io/io/setenv.sh @@ -41,7 +41,7 @@ if [ -z "${PATH_ORIG}" ]; then export PATH_ORIG="${PATH}"; fi WD=`pwd` export RIDE_BIN="/cygdrive/c/Program Files/Raisonance/Ride/arm-gcc/bin" -export BUILDROOT_BIN="${WD}/../buildroot/build_arm_nofpu/staging_dir/bin" +export BUILDROOT_BIN="${WD}/../misc/buildroot/build_arm_nofpu/staging_dir/bin" export PATH="${BUILDROOT_BIN}:${RIDE_BIN}:/sbin:/usr/sbin:${PATH_ORIG}" echo "PATH : ${PATH}" diff --git a/nuttx/drivers/Kconfig b/nuttx/drivers/Kconfig index ea218a592..1d263ec14 100644 --- a/nuttx/drivers/Kconfig +++ b/nuttx/drivers/Kconfig @@ -11,6 +11,14 @@ config DEV_ZERO bool "Enable /dev/zero" default n +config ARCH_HAVE_RNG + bool + +config DEV_RANDOM + bool "Enable /dev/random" + default n + depends on ARCH_HAVE_RNG + config LOOP bool "Enable loop device" default n diff --git a/nuttx/drivers/input/Kconfig b/nuttx/drivers/input/Kconfig index 9fde35ff6..1f345ee14 100644 --- a/nuttx/drivers/input/Kconfig +++ b/nuttx/drivers/input/Kconfig @@ -2,6 +2,7 @@ # For a description of the syntax of this configuration file, # see misc/tools/kconfig-language.txt. # + config INPUT_TSC2007 bool "TI TSC2007 touchscreen controller" default n @@ -9,7 +10,29 @@ config INPUT_TSC2007 ---help--- Enable support for the TI TSC2007 touchscreen controller - +if INPUT_TSC2007 + +config TSC2007_8BIT + bool "8-bit Conversions" + default n + ---help--- + Use faster, but less accurate, 8-bit conversions. Default: 12-bit conversions. + +config TSC2007_MULTIPLE + bool "Multiple TSC2007 Devices" + default n + ---help--- + Can be defined to support multiple TSC2007 devices on board. + +config TSC2007_NPOLLWAITERS + int "Number poll waiters" + default 4 + depends on !DISABLE_POLL + ---help--- + Maximum number of threads that can be waiting on poll() + +endif + config INPUT_ADS7843E bool "TI ADS7843/TSC2046 touchscreen controller" default n @@ -18,3 +41,169 @@ config INPUT_ADS7843E Enable support for the TI/Burr-Brown ADS7842 touchscreen controller. I believe that driver should be compatibile with the TI/Burr-Brown TSC2046 and XPT2046 touchscreen controllers as well. + +if INPUT_ADS7843E + +config ADS7843E_MULTIPLE + bool "Multiple ADS7843E Devices" + default n + ---help--- + Can be defined to support multiple ADS7843E devices on board. + +config ADS7843E_NPOLLWAITERS + int "Number poll waiters" + default 4 + depends on !DISABLE_POLL + ---help--- + Maximum number of threads that can be waiting on poll() + +config ADS7843E_SPIMODE + int "SPI mode" + default 0 + range 0,3 + ---help--- + Controls the SPI mode. The device should work in mode 0, but sometimes + you need to experiment. + +config ADS7843E_FREQUENCY + int "SPI frequency" + default 100000 + ---help--- + Define to use a different SPI bus frequency. + +config ADS7843E_SWAPXY + bool "Swap X/Y" + default n + ---help--- + Reverse the meaning of X and Y to handle different LCD orientations. + +config ADS7843E_THRESHX + int "X threshold" + default 12 + ---help--- + New touch positions will only be reported when the X or Y data changes by these + thresholds. This trades reduces data rate for some loss in dragging accuracy. For + 12-bit values so the raw ranges are 0-4095. So for example, if your display is + 320x240, then THRESHX=13 and THRESHY=17 would correspond to one pixel. Default: 12 + +config ADS7843E_THRESHY + int "Y threshold" + default 12 + ---help--- + New touch positions will only be reported when the X or Y data changes by these + thresholds. This trades reduces data rate for some loss in dragging accuracy. For + 12-bit values so the raw ranges are 0-4095. So for example, if your display is + 320x240, then THRESHX=13 and THRESHY=17 would correspond to one pixel. Default: 12 + +endif + +config INPUT_STMPE811 + bool "STMicro STMPE811 Driver" + default n + ---help--- + Enables support for the STMPE811 driver + +if INPUT_STMPE811 + +choice + prompt "STMPE Interface" + default STMPE811_I2C + +config STMPE811_SPI + bool "SPI Interface" + select SPI + ---help--- + Enables support for the SPI interface (not currently supported) + +config STMPE811_I2C + bool "STMPE811 I2C Interface" + select I2C + ---help--- + Enables support for the I2C interface + +endchoice + +config STMPE811_MULTIPLE + bool "Multiple STMPE811 Devices" + default n + ---help--- + Can be defined to support multiple STMPE811 devices on board. + +config STMPE811_NPOLLWAITERS + int "Number poll waiters" + default 4 + depends on !DISABLE_POLL + ---help--- + Maximum number of threads that can be waiting on poll() + +config STMPE811_TSC_DISABLE + bool "Disable STMPE811 Touchscreen Support" + default n + ---help--- + Disable driver touchscreen functionality. + +config STMPE811_SWAPXY + bool "Swap X/Y" + default n + depends on !STMPE811_TSC_DISABLE + ---help--- + Reverse the meaning of X and Y to handle different LCD orientations. + +config STMPE811_THRESHX + int "X threshold" + default 12 + depends on !STMPE811_TSC_DISABLE + ---help--- + STMPE811 touchscreen data comes in a a very high rate. New touch positions + will only be reported when the X or Y data changes by these thresholds. + This trades reduces data rate for some loss in dragging accuracy. The + STMPE811 is configure for 12-bit values so the raw ranges are 0-4095. So + for example, if your display is 320x240, then THRESHX=13 and THRESHY=17 + would correspond to one pixel. Default: 12 + +config STMPE811_THRESHY + int "Y threshold" + default 12 + depends on !STMPE811_TSC_DISABLE + ---help--- + STMPE811 touchscreen data comes in a a very high rate. New touch positions + will only be reported when the X or Y data changes by these thresholds. + This trades reduces data rate for some loss in dragging accuracy. The + STMPE811 is configure for 12-bit values so the raw ranges are 0-4095. So + for example, if your display is 320x240, then THRESHX=13 and THRESHY=17 + would correspond to one pixel. Default: 12 + +config STMPE811_ADC_DISABLE + bool "Disable STMPE811 ADC Support" + default y + ---help--- + Disable driver ADC functionality. + +config STMPE811_GPIO_DISABLE + bool "Disable STMPE811 GPIO Support" + default y + ---help--- + Disable driver GPIO functionality. + +config STMPE811_GPIOINT_DISABLE + bool "Disable STMPE811 GPIO Interrupt Support" + default y + depends on !STMPE811_GPIO_DISABLE + ---help--- + Disable driver GPIO interrupt functionlality (ignored if GPIO functionality is + disabled). + +config STMPE811_TEMP_DISABLE + bool "Disable STMPE811 Temperature Sensor Support" + default y + ---help--- + Disable driver temperature sensor functionality. + +config STMPE811_REGDEBUG + bool "Enable Register-Level STMPE811 Debug" + default n + depends on DEBUG + ---help--- + Enable very low register-level debug output. + +endif diff --git a/nuttx/drivers/input/ads7843e.c b/nuttx/drivers/input/ads7843e.c index 07e5e515d..06969e6d2 100644 --- a/nuttx/drivers/input/ads7843e.c +++ b/nuttx/drivers/input/ads7843e.c @@ -79,6 +79,12 @@ * Pre-processor Definitions ****************************************************************************/ +/* This is a value for the threshold that guantees a big difference on the + * first pendown (but can't overflow). + */ + +#define INVALID_THRESHOLD 0x1000 + /**************************************************************************** * Private Types ****************************************************************************/ @@ -88,13 +94,14 @@ ****************************************************************************/ /* Low-level SPI helpers */ -static inline void ads7843e_configspi(FAR struct spi_dev_s *spi); #ifdef CONFIG_SPI_OWNBUS -static inline void ads7843e_select(FAR struct spi_dev_s *spi); -static inline void ads7843e_deselect(FAR struct spi_dev_s *spi); +static inline void ads7843e_configspi(FAR struct spi_dev_s *spi); +# define ads7843e_lock(spi) +# define ads7843e_unlock(spi) #else -static void ads7843e_select(FAR struct spi_dev_s *spi); -static void ads7843e_deselect(FAR struct spi_dev_s *spi); +# define ads7843e_configspi(spi); +static void ads7843e_lock(FAR struct spi_dev_s *spi); +static void ads7843e_unlock(FAR struct spi_dev_s *spi); #endif static inline void ads7843e_waitbusy(FAR struct ads7843e_dev_s *priv); @@ -157,13 +164,12 @@ static struct ads7843e_dev_s *g_ads7843elist; ****************************************************************************/ /**************************************************************************** - * Function: ads7843e_select + * Function: ads7843e_lock * * Description: - * Select the SPI, locking and re-configuring if necessary. This function - * must be called before initiating any sequence of SPI operations. If we - * are sharing the SPI bus with other devices (CONFIG_SPI_OWNBUS undefined) - * then we need to lock and configure the SPI bus for each transfer. + * Lock the SPI bus and re-configure as necessary. This function must be + * to assure: (1) exclusive access to the SPI bus, and (2) to assure that + * the shared bus is properly configured for the touchscreen controller. * * Parameters: * spi - Reference to the SPI driver structure @@ -175,42 +181,35 @@ static struct ads7843e_dev_s *g_ads7843elist; * ****************************************************************************/ -#ifdef CONFIG_SPI_OWNBUS -static inline void ads7843e_select(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just select the chip */ - - SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, true); -} -#else -static void ads7843e_select(FAR struct spi_dev_s *spi) +#ifndef CONFIG_SPI_OWNBUS +static void ads7843e_lock(FAR struct spi_dev_s *spi) { - /* Select ADS7843 chip (locking the SPI bus in case there are multiple - * devices competing for the SPI bus + /* Lock the SPI bus because there are multiple devices competing for the + * SPI bus */ (void)SPI_LOCK(spi, true); - SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, true); - /* Now make sure that the SPI bus is configured for the ADS7843 (it - * might have gotten configured for a different device while unlocked) + /* We have the lock. Now make sure that the SPI bus is configured for the + * ADS7843 (it might have gotten configured for a different device while + * unlocked) */ + SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, true); SPI_SETMODE(spi, CONFIG_ADS7843E_SPIMODE); SPI_SETBITS(spi, 8); SPI_SETFREQUENCY(spi, CONFIG_ADS7843E_FREQUENCY); + SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, false); } #endif /**************************************************************************** - * Function: ads7843e_deselect + * Function: ads7843e_unlock * * Description: - * De-select the SPI, unlocking as necessary. This function must be - * after completing a sequence of SPI operations. If we are sharing the SPI - * bus with other devices (CONFIG_SPI_OWNBUS undefined) then we need to - * un-lock the SPI bus for each transfer, possibly losing the current - * configuration. + * If we are sharing the SPI bus with other devices (CONFIG_SPI_OWNBUS + * undefined) then we need to un-lock the SPI bus for each transfer, + * possibly losing the current configuration. * * Parameters: * spi - Reference to the SPI driver structure @@ -222,19 +221,11 @@ static void ads7843e_select(FAR struct spi_dev_s *spi) * ****************************************************************************/ -#ifdef CONFIG_SPI_OWNBUS -static inline void ads7843e_deselect(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just de-select the chip */ - - SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, false); -} -#else -static void ads7843e_deselect(FAR struct spi_dev_s *spi) +#ifndef CONFIG_SPI_OWNBUS +static void ads7843e_unlock(FAR struct spi_dev_s *spi) { - /* De-select ADS7843 chip and relinquish the SPI bus. */ + /* Relinquish the SPI bus. */ - SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, false); (void)SPI_LOCK(spi, false); } #endif @@ -258,23 +249,20 @@ static void ads7843e_deselect(FAR struct spi_dev_s *spi) * ****************************************************************************/ +#ifdef CONFIG_SPI_OWNBUS static inline void ads7843e_configspi(FAR struct spi_dev_s *spi) { - idbg("Mode: %d Bits: 8 Frequency: %d\n", - CONFIG_ADS7843E_SPIMODE, CONFIG_ADS7843E_FREQUENCY); - /* Configure SPI for the ADS7843. But only if we own the SPI bus. Otherwise, don't * bother because it might change. */ -#ifdef CONFIG_SPI_OWNBUS SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, true); SPI_SETMODE(spi, CONFIG_ADS7843E_SPIMODE); SPI_SETBITS(spi, 8); SPI_SETFREQUENCY(spi, CONFIG_ADS7843E_FREQUENCY); SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, false); -#endif } +#endif /**************************************************************************** * Name: ads7843e_waitbusy @@ -296,7 +284,7 @@ static uint16_t ads7843e_sendcmd(FAR struct ads7843e_dev_s *priv, uint8_t cmd) /* Select the ADS7843E */ - ads7843e_select(priv->spi); + SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, true); /* Send the command */ @@ -306,7 +294,7 @@ static uint16_t ads7843e_sendcmd(FAR struct ads7843e_dev_s *priv, uint8_t cmd) /* Read the data */ SPI_RECVBLOCK(priv->spi, buffer, 2); - ads7843e_deselect(priv->spi); + SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, false); result = ((uint16_t)buffer[0] << 8) | (uint16_t)buffer[1]; result = result >> 4; @@ -554,7 +542,12 @@ static void ads7843e_worker(FAR void *arg) { FAR struct ads7843e_dev_s *priv = (FAR struct ads7843e_dev_s *)arg; FAR struct ads7843e_config_s *config; + uint16_t x; + uint16_t y; + uint16_t xdiff; + uint16_t ydiff; bool pendown; + int ret; ASSERT(priv != NULL); @@ -565,10 +558,30 @@ static void ads7843e_worker(FAR void *arg) config = priv->config; DEBUGASSERT(config != NULL); - /* Disable the watchdog timer */ + /* Disable the watchdog timer. This is safe because it is started only + * by this function and this function is serialized on the worker thread. + */ wd_cancel(priv->wdog); + /* Lock the SPI bus so that we have exclusive access */ + + ads7843e_lock(priv->spi); + + /* Get exclusive access to the driver data structure */ + + do + { + ret = sem_wait(&priv->devsem); + + /* This should only fail if the wait was canceled by an signal + * (and the worker thread will receive a lot of signals). + */ + + DEBUGASSERT(ret == OK || errno == EINTR); + } + while (ret < 0); + /* Check for pen up or down by reading the PENIRQ GPIO. */ pendown = config->pendown(config); @@ -577,13 +590,20 @@ static void ads7843e_worker(FAR void *arg) if (!pendown) { - /* Ignore the interrupt if the pen was already up (CONTACT_NONE == pen up and - * already reported. CONTACT_UP == pen up, but not reported) + /* The pen is up.. reset thresholding variables. */ + + priv->threshx = INVALID_THRESHOLD; + priv->threshy = INVALID_THRESHOLD; + + /* Ignore the interrupt if the pen was already up (CONTACT_NONE == pen up + * and already reported; CONTACT_UP == pen up, but not reported) */ - if (priv->sample.contact == CONTACT_NONE) + if (priv->sample.contact == CONTACT_NONE || + priv->sample.contact == CONTACT_UP) + { - goto errout; + goto ignored; } /* The pen is up. NOTE: We know from a previous test, that this is a @@ -601,14 +621,57 @@ static void ads7843e_worker(FAR void *arg) else if (priv->sample.contact == CONTACT_UP) { - goto errout; + /* If we have not yet processed the last pen up event, then we + * cannot handle this pen down event. We will have to discard it. That + * should be okay because we will set the timer to to sample again + * later. + */ + + wd_start(priv->wdog, ADS7843E_WDOG_DELAY, ads7843e_wdog, 1, (uint32_t)priv); + goto ignored; } else { /* Handle pen down events. First, sample positional values. */ - priv->sample.x = ads7843e_sendcmd(priv, ADS7843_CMD_XPOSITION); - priv->sample.y = ads7843e_sendcmd(priv, ADS7843_CMD_YPOSITION); +#ifdef CONFIG_ADS7843E_SWAPXY + x = ads7843e_sendcmd(priv, ADS7843_CMD_YPOSITION); + y = ads7843e_sendcmd(priv, ADS7843_CMD_XPOSITION); +#else + x = ads7843e_sendcmd(priv, ADS7843_CMD_XPOSITION); + y = ads7843e_sendcmd(priv, ADS7843_CMD_YPOSITION); +#endif + + /* Perform a thresholding operation so that the results will be more stable. + * If the difference from the last sample is small, then ignore the event. + * REVISIT: Should a large change in pressure also generate a event? + */ + + xdiff = x > priv->threshx ? (x - priv->threshx) : (priv->threshx - x); + ydiff = y > priv->threshy ? (y - priv->threshy) : (priv->threshy - y); + + /* Continue to sample the position while the pen is down */ + + wd_start(priv->wdog, ADS7843E_WDOG_DELAY, ads7843e_wdog, 1, (uint32_t)priv); + + /* Check the thresholds. Bail if there is no significant difference */ + + if (xdiff < CONFIG_ADS7843E_THRESHX && ydiff < CONFIG_ADS7843E_THRESHY) + { + /* Little or no change in either direction ... don't report anything. */ + + goto ignored; + } + + /* When we see a big difference, snap to the new x/y thresholds */ + + priv->threshx = x; + priv->threshy = y; + + /* Update the x/y position in the sample data */ + + priv->sample.x = priv->threshx; + priv->sample.y = priv->threshy; /* The X/Y positional data is now valid */ @@ -625,10 +688,6 @@ static void ads7843e_worker(FAR void *arg) priv->sample.contact = CONTACT_DOWN; } - - /* Continue to sample the position while the pen is down */ - - wd_start(priv->wdog, ADS7843E_WDOG_DELAY, ads7843e_wdog, 1, (uint32_t)priv); } /* Indicate the availability of new sample data for this ID */ @@ -642,9 +701,15 @@ static void ads7843e_worker(FAR void *arg) /* Exit, re-enabling ADS7843E interrupts */ -errout: +ignored: + (void)ads7843e_sendcmd(priv, ADS7843_CMD_ENABPINIRQ); config->enable(config, true); + + /* Release our lock on the state structure and unlock the SPI bus */ + + sem_post(&priv->devsem); + ads7843e_unlock(priv->spi); } /**************************************************************************** @@ -871,7 +936,7 @@ static ssize_t ads7843e_read(FAR struct file *filep, FAR char *buffer, size_t le report = (FAR struct touch_sample_s *)buffer; memset(report, 0, SIZEOF_TOUCH_SAMPLE_S(1)); report->npoints = 1; - report->point[0].id = priv->id; + report->point[0].id = sample.id; report->point[0].x = sample.x; report->point[0].y = sample.y; @@ -886,8 +951,7 @@ static ssize_t ads7843e_read(FAR struct file *filep, FAR char *buffer, size_t le if (sample.valid) { - report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID | - TOUCH_POS_VALID | TOUCH_PRESSURE_VALID; + report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID | TOUCH_POS_VALID; } else { @@ -1098,7 +1162,7 @@ errout: * ****************************************************************************/ -int ads7843e_register(FAR struct spi_dev_s *dev, +int ads7843e_register(FAR struct spi_dev_s *spi, FAR struct ads7843e_config_s *config, int minor) { FAR struct ads7843e_dev_s *priv; @@ -1108,11 +1172,11 @@ int ads7843e_register(FAR struct spi_dev_s *dev, #endif int ret; - ivdbg("dev: %p minor: %d\n", dev, minor); + ivdbg("spi: %p minor: %d\n", spi, minor); /* Debug-only sanity checks */ - DEBUGASSERT(dev != NULL && config != NULL && minor >= 0 && minor < 100); + DEBUGASSERT(spi != NULL && config != NULL && minor >= 0 && minor < 100); /* Create and initialize a ADS7843E device driver instance */ @@ -1130,11 +1194,14 @@ int ads7843e_register(FAR struct spi_dev_s *dev, /* Initialize the ADS7843E device driver instance */ memset(priv, 0, sizeof(struct ads7843e_dev_s)); - priv->spi = dev; /* Save the SPI device handle */ - priv->config = config; /* Save the board configuration */ - priv->wdog = wd_create(); /* Create a watchdog timer */ - sem_init(&priv->devsem, 0, 1); /* Initialize device structure semaphore */ - sem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */ + priv->spi = spi; /* Save the SPI device handle */ + priv->config = config; /* Save the board configuration */ + priv->wdog = wd_create(); /* Create a watchdog timer */ + priv->threshx = INVALID_THRESHOLD; /* Initialize thresholding logic */ + priv->threshy = INVALID_THRESHOLD; /* Initialize thresholding logic */ + + sem_init(&priv->devsem, 0, 1); /* Initialize device structure semaphore */ + sem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */ /* Make sure that interrupts are disabled */ @@ -1150,14 +1217,25 @@ int ads7843e_register(FAR struct spi_dev_s *dev, goto errout_with_priv; } + idbg("Mode: %d Bits: 8 Frequency: %d\n", + CONFIG_ADS7843E_SPIMODE, CONFIG_ADS7843E_FREQUENCY); + + /* Lock the SPI bus so that we have exclusive access */ + + ads7843e_lock(spi); + /* Configure the SPI interface */ - ads7843e_configspi(dev); + ads7843e_configspi(spi); /* Enable the PEN IRQ */ ads7843e_sendcmd(priv, ADS7843_CMD_ENABPINIRQ); + /* Unlock the bus */ + + ads7843e_unlock(spi); + /* Register the device as an input device */ (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, minor); diff --git a/nuttx/drivers/input/ads7843e.h b/nuttx/drivers/input/ads7843e.h index 43b79c7b7..6fd70d98b 100644 --- a/nuttx/drivers/input/ads7843e.h +++ b/nuttx/drivers/input/ads7843e.h @@ -139,6 +139,8 @@ struct ads7843e_dev_s uint8_t nwaiters; /* Number of threads waiting for ADS7843E data */ uint8_t id; /* Current touch point ID */ volatile bool penchange; /* An unreported event is buffered */ + uint16_t threshx; /* Thresholding X value */ + uint16_t threshy; /* Thresholding Y value */ sem_t devsem; /* Manages exclusive access to this structure */ sem_t waitsem; /* Used to wait for the availability of data */ diff --git a/nuttx/drivers/lcd/ssd1289.c b/nuttx/drivers/lcd/ssd1289.c index 3d5ba96d3..e42b5bded 100644 --- a/nuttx/drivers/lcd/ssd1289.c +++ b/nuttx/drivers/lcd/ssd1289.c @@ -229,8 +229,8 @@ /* Debug ******************************************************************************/ #ifdef CONFIG_DEBUG_LCD -# define lcddbg dbg -# define lcdvdbg vdbg +# define lcddbg dbg +# define lcdvdbg vdbg #else # define lcddbg(x...) # define lcdvdbg(x...) @@ -253,6 +253,16 @@ struct ssd1289_dev_s FAR struct ssd1289_lcd_s *lcd; /* The contained platform-specific, LCD interface */ uint8_t power; /* Current power setting */ + /* These fields simplify and reduce debug output */ + +#ifdef CONFIG_DEBUG_LCD + bool put; /* Last raster operation was a putrun */ + fb_coord_t firstrow; /* First row of the run */ + fb_coord_t lastrow; /* Last row of the run */ + fb_coord_t col; /* Column of the run */ + size_t npixels; /* Length of the run */ +#endif + /* This is working memory allocated by the LCD driver for each LCD device * and for each color plane. This memory will hold one raster line of data. * The size of the allocated run buffer must therefore be at least @@ -287,6 +297,19 @@ static void ssd1289_setcursor(FAR struct ssd1289_lcd_s *lcd, uint16_t column, /* LCD Data Transfer Methods */ +#if 0 /* Sometimes useful */ +static void ssd1289_dumprun(FAR const char *msg, FAR uint16_t *run, size_t npixels); +#else +# define ssd1289_dumprun(m,r,n) +#endif + +#ifdef CONFIG_DEBUG_LCD +static void ssd1289_showrun(FAR struct ssd1289_dev_s *priv, fb_coord_t row, + fb_coord_t col, size_t npixels, bool put); +#else +# define ssd1289_showrun(p,r,c,n,b) +#endif + static int ssd1289_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, size_t npixels); static int ssd1289_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, @@ -489,6 +512,64 @@ static void ssd1289_dumprun(FAR const char *msg, FAR uint16_t *run, size_t npixe #endif /************************************************************************************** + * Name: ssd1289_showrun + * + * Description: + * When LCD debug is enabled, try to reduce then amount of ouptut data generated by + * ssd1289_putrun and ssd1289_getrun + * + **************************************************************************************/ + +#ifdef CONFIG_DEBUG_LCD +static void ssd1289_showrun(FAR struct ssd1289_dev_s *priv, fb_coord_t row, + fb_coord_t col, size_t npixels, bool put) +{ + fb_coord_t nextrow = priv->lastrow + 1; + + /* Has anything changed (other than the row is the next row in the sequence)? */ + + if (put == priv->put && row == nextrow && col == priv->col && + npixels == priv->npixels) + { + /* No, just update the last row */ + + priv->lastrow = nextrow; + } + else + { + /* Yes... then this is the end of the preceding sequence. Output the last run + * (if there were more than one run in the sequence). + */ + + if (priv->firstrow != priv->lastrow) + { + lcddbg("...\n"); + lcddbg("%s row: %d col: %d npixels: %d\n", + priv->put ? "PUT" : "GET", + priv->lastrow, priv->col, priv->npixels); + } + + /* And we are starting a new sequence. Output the first run of the + * new sequence + */ + + lcddbg("%s row: %d col: %d npixels: %d\n", + put ? "PUT" : "GET", row, col, npixels); + + /* And save information about the run so that we can detect continuations + * of the sequence. + */ + + priv->put = put; + priv->firstrow = row; + priv->lastrow = row; + priv->col = col; + priv->npixels = npixels; + } +} +#endif + +/************************************************************************************** * Name: ssd1289_putrun * * Description: @@ -512,7 +593,7 @@ static int ssd1289_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buf /* Buffer must be provided and aligned to a 16-bit address boundary */ - lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); + ssd1289_showrun(priv, row, col, npixels, true); DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0); /* Select the LCD */ @@ -536,7 +617,7 @@ static int ssd1289_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buf ssd1289_gramselect(lcd); ssd1289_gramwrite(lcd, *src); - /* Increment to next column */ + /* Increment to the next column */ src++; col++; @@ -581,7 +662,7 @@ static int ssd1289_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buf ssd1289_gramselect(lcd); ssd1289_gramwrite(lcd, *src); - /* Increment to next column */ + /* Increment to the next column */ src++; col--; @@ -604,7 +685,7 @@ static int ssd1289_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buf ssd1289_gramselect(lcd); ssd1289_gramwrite(lcd, *src); - /* Decrement to next column */ + /* Decrement to the next column */ src++; col++; @@ -632,7 +713,7 @@ static int ssd1289_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buf **************************************************************************************/ static int ssd1289_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels) + size_t npixels) { #ifndef CONFIG_LCD_NOGETRUN FAR struct ssd1289_dev_s *priv = &g_lcddev; @@ -643,7 +724,7 @@ static int ssd1289_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, /* Buffer must be provided and aligned to a 16-bit address boundary */ - lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); + ssd1289_showrun(priv, row, col, npixels, false); DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0); /* Select the LCD */ @@ -666,7 +747,7 @@ static int ssd1289_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, ssd1289_readsetup(lcd, &accum); *dest++ = ssd1289_gramread(lcd, &accum); - /* Increment to next column */ + /* Increment to the next column */ col++; } @@ -715,7 +796,7 @@ static int ssd1289_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, ssd1289_readsetup(lcd, &accum); *dest++ = ssd1289_gramread(lcd, &accum); - /* Increment to next column */ + /* Increment to the next column */ col--; } @@ -738,7 +819,7 @@ static int ssd1289_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, ssd1289_readsetup(lcd, &accum); *dest++ = ssd1289_gramread(lcd, &accum); - /* Decrement to next column */ + /* Decrement to the next column */ col++; } @@ -931,9 +1012,27 @@ static inline int ssd1289_hwinitialize(FAR struct ssd1289_dev_s *priv) lcd->select(lcd); + /* Read the device ID. Skip verification of the device ID is the LCD is + * write-only. What choice do we have? + */ + #ifndef CONFIG_LCD_NOGETRUN id = ssd1289_readreg(lcd, SSD1289_DEVCODE); - lcddbg("LCD ID: %04x\n", id); + if (id != 0) + { + lcddbg("LCD ID: %04x\n", id); + } + + /* If we could not get the ID, then let's just assume that this is an SSD1289. + * Perhaps we have some early register access issues. This seems to happen. + * But then perhaps we should not even bother to read the device ID at all? + */ + + else + { + lcddbg("No LCD ID, assuming SSD1289\n"); + id = SSD1289_DEVCODE_VALUE; + } /* Check if the ID is for the SSD1289 */ diff --git a/nuttx/drivers/mtd/ramtron.c b/nuttx/drivers/mtd/ramtron.c index 074545e2d..34273bccf 100644 --- a/nuttx/drivers/mtd/ramtron.c +++ b/nuttx/drivers/mtd/ramtron.c @@ -98,7 +98,7 @@ #define RAMTRON_WRITE 0x02 /* 1 Write A 0 1-256 */ #define RAMTRON_SLEEP 0xb9 // TODO: #define RAMTRON_RDID 0x9f /* 1 Read Identification 0 0 1-3 */ -#define RAMTRON_SN 0xc3 // TODO: +#define RAMTRON_SN 0xc3 // TODO: /* Status register bit definitions */ @@ -125,12 +125,12 @@ struct ramtron_parts_s { - const char *name; - uint8_t id1; - uint8_t id2; - uint32_t size; - uint8_t addr_len; - uint32_t speed; + const char *name; + uint8_t id1; + uint8_t id2; + uint32_t size; + uint8_t addr_len; + uint32_t speed; }; /* This type represents the state of the MTD device. The struct mtd_dev_s @@ -146,84 +146,86 @@ struct ramtron_dev_s uint8_t pageshift; uint16_t nsectors; uint32_t npages; - const struct ramtron_parts_s *part; /* part instance */ + const struct ramtron_parts_s *part; /* part instance */ }; /************************************************************************************ * Supported Part Lists ************************************************************************************/ -// Defines the initial speed compatible with all devices. In case of RAMTRON -// the defined devices within the part list have all the same speed. -#define RAMTRON_INIT_CLK_MAX 40000000UL +/* Defines the initial speed compatible with all devices. In case of RAMTRON + * the defined devices within the part list have all the same speed. + */ + +#define RAMTRON_INIT_CLK_MAX 40000000UL static struct ramtron_parts_s ramtron_parts[] = { - { - "FM25V02", /* name */ - 0x22, /* id1 */ - 0x00, /* id2 */ - 32L*1024L, /* size */ - 2, /* addr_len */ - 40000000 /* speed */ - }, - { - "FM25VN02", /* name */ - 0x22, /* id1 */ - 0x01, /* id2 */ - 32L*1024L, /* size */ - 2, /* addr_len */ - 40000000 /* speed */ - }, - { - "FM25V05", /* name */ - 0x23, /* id1 */ - 0x00, /* id2 */ - 64L*1024L, /* size */ - 2, /* addr_len */ - 40000000 /* speed */ - }, - { - "FM25VN05", /* name */ - 0x23, /* id1 */ - 0x01, /* id2 */ - 64L*1024L, /* size */ - 2, /* addr_len */ - 40000000 /* speed */ - }, - { - "FM25V10", /* name */ - 0x24, /* id1 */ - 0x00, /* id2 */ - 128L*1024L, /* size */ - 3, /* addr_len */ - 40000000 /* speed */ - }, - { - "FM25VN10", /* name */ - 0x24, /* id1 */ - 0x01, /* id2 */ - 128L*1024L, /* size */ - 3, /* addr_len */ - 40000000 /* speed */ - }, + { + "FM25V02", /* name */ + 0x22, /* id1 */ + 0x00, /* id2 */ + 32L*1024L, /* size */ + 2, /* addr_len */ + 40000000 /* speed */ + }, + { + "FM25VN02", /* name */ + 0x22, /* id1 */ + 0x01, /* id2 */ + 32L*1024L, /* size */ + 2, /* addr_len */ + 40000000 /* speed */ + }, + { + "FM25V05", /* name */ + 0x23, /* id1 */ + 0x00, /* id2 */ + 64L*1024L, /* size */ + 2, /* addr_len */ + 40000000 /* speed */ + }, + { + "FM25VN05", /* name */ + 0x23, /* id1 */ + 0x01, /* id2 */ + 64L*1024L, /* size */ + 2, /* addr_len */ + 40000000 /* speed */ + }, + { + "FM25V10", /* name */ + 0x24, /* id1 */ + 0x00, /* id2 */ + 128L*1024L, /* size */ + 3, /* addr_len */ + 40000000 /* speed */ + }, + { + "FM25VN10", /* name */ + 0x24, /* id1 */ + 0x01, /* id2 */ + 128L*1024L, /* size */ + 3, /* addr_len */ + 40000000 /* speed */ + }, #ifdef CONFIG_RAMTRON_FRAM_NON_JEDEC - { - "FM25H20", /* name */ - 0xff, /* id1 */ - 0xff, /* id2 */ - 256L*1024L, /* size */ - 3, /* addr_len */ - 40000000 /* speed */ - }, - { - NULL, /* name */ - 0, /* id1 */ - 0, /* id2 */ - 0, /* size */ - 0, /* addr_len */ - 0 /* speed */ - } + { + "FM25H20", /* name */ + 0xff, /* id1 */ + 0xff, /* id2 */ + 256L*1024L, /* size */ + 3, /* addr_len */ + 40000000 /* speed */ + }, + { + NULL, /* name */ + 0, /* id1 */ + 0, /* id2 */ + 0, /* size */ + 0, /* addr_len */ + 0 /* speed */ + } #endif }; @@ -240,17 +242,17 @@ static inline int ramtron_readid(struct ramtron_dev_s *priv); static void ramtron_waitwritecomplete(struct ramtron_dev_s *priv); static void ramtron_writeenable(struct ramtron_dev_s *priv); static inline void ramtron_pagewrite(struct ramtron_dev_s *priv, FAR const uint8_t *buffer, - off_t offset); + off_t offset); /* MTD driver methods */ static int ramtron_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks); static ssize_t ramtron_bread(FAR struct mtd_dev_s *dev, off_t startblock, - size_t nblocks, FAR uint8_t *buf); + size_t nblocks, FAR uint8_t *buf); static ssize_t ramtron_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, - size_t nblocks, FAR const uint8_t *buf); + size_t nblocks, FAR const uint8_t *buf); static ssize_t ramtron_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, - FAR uint8_t *buffer); + FAR uint8_t *buffer); static int ramtron_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); /************************************************************************************ @@ -317,31 +319,37 @@ static inline int ramtron_readid(struct ramtron_dev_s *priv) /* Send the "Read ID (RDID)" command and read the first three ID bytes */ (void)SPI_SEND(priv->dev, RAMTRON_RDID); - for (i=0; i<6; i++) manufacturer = SPI_SEND(priv->dev, RAMTRON_DUMMY); - memory = SPI_SEND(priv->dev, RAMTRON_DUMMY); - capacity = SPI_SEND(priv->dev, RAMTRON_DUMMY); // fram.id1 - part = SPI_SEND(priv->dev, RAMTRON_DUMMY); // fram.id2 + for (i = 0; i < 6; i++) + { + manufacturer = SPI_SEND(priv->dev, RAMTRON_DUMMY); + } + + memory = SPI_SEND(priv->dev, RAMTRON_DUMMY); + capacity = SPI_SEND(priv->dev, RAMTRON_DUMMY); // fram.id1 + part = SPI_SEND(priv->dev, RAMTRON_DUMMY); // fram.id2 /* Deselect the FLASH and unlock the bus */ SPI_SELECT(priv->dev, SPIDEV_FLASH, false); ramtron_unlock(priv->dev); - // Select part from the part list + /* Select part from the part list */ + for (priv->part = ramtron_parts; - priv->part->name != NULL && !(priv->part->id1 == capacity && priv->part->id2 == part); - priv->part++); - - if (priv->part->name) { - fvdbg("RAMTRON %s of size %d bytes (mf:%02x mem:%02x cap:%02x part:%02x)\n", - priv->part->name, priv->part->size, manufacturer, memory, capacity, part); - - priv->sectorshift = RAMTRON_EMULATE_SECTOR_SHIFT; - priv->nsectors = priv->part->size / (1 << RAMTRON_EMULATE_SECTOR_SHIFT); - priv->pageshift = RAMTRON_EMULATE_PAGE_SHIFT; - priv->npages = priv->part->size / (1 << RAMTRON_EMULATE_PAGE_SHIFT); - return OK; - } + priv->part->name != NULL && !(priv->part->id1 == capacity && priv->part->id2 == part); + priv->part++); + + if (priv->part->name) + { + fvdbg("RAMTRON %s of size %d bytes (mf:%02x mem:%02x cap:%02x part:%02x)\n", + priv->part->name, priv->part->size, manufacturer, memory, capacity, part); + + priv->sectorshift = RAMTRON_EMULATE_SECTOR_SHIFT; + priv->nsectors = priv->part->size / (1 << RAMTRON_EMULATE_SECTOR_SHIFT); + priv->pageshift = RAMTRON_EMULATE_PAGE_SHIFT; + priv->npages = priv->part->size / (1 << RAMTRON_EMULATE_PAGE_SHIFT); + return OK; + } fvdbg("RAMTRON device not found\n"); return -ENODEV; @@ -408,8 +416,10 @@ static inline void ramtron_sendaddr(const struct ramtron_dev_s *priv, uint32_t a DEBUGASSERT(priv->part->addr_len == 3 || priv->part->addr_len == 2); if (priv->part->addr_len == 3) - (void)SPI_SEND(priv->dev, (addr >> 16) & 0xff); - + { + (void)SPI_SEND(priv->dev, (addr >> 16) & 0xff); + } + (void)SPI_SEND(priv->dev, (addr >> 8) & 0xff); (void)SPI_SEND(priv->dev, addr & 0xff); } @@ -419,7 +429,7 @@ static inline void ramtron_sendaddr(const struct ramtron_dev_s *priv, uint32_t a ************************************************************************************/ static inline void ramtron_pagewrite(struct ramtron_dev_s *priv, FAR const uint8_t *buffer, - off_t page) + off_t page) { off_t offset = page << priv->pageshift; @@ -475,7 +485,7 @@ static int ramtron_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nbl ************************************************************************************/ static ssize_t ramtron_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, - FAR uint8_t *buffer) + FAR uint8_t *buffer) { FAR struct ramtron_dev_s *priv = (FAR struct ramtron_dev_s *)dev; ssize_t nbytes; @@ -489,6 +499,7 @@ static ssize_t ramtron_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t { return nbytes >> priv->pageshift; } + return (int)nbytes; } @@ -497,7 +508,7 @@ static ssize_t ramtron_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t ************************************************************************************/ static ssize_t ramtron_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, - FAR const uint8_t *buffer) + FAR const uint8_t *buffer) { FAR struct ramtron_dev_s *priv = (FAR struct ramtron_dev_s *)dev; size_t blocksleft = nblocks; @@ -512,8 +523,8 @@ static ssize_t ramtron_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_ ramtron_pagewrite(priv, buffer, startblock); startblock++; } - ramtron_unlock(priv->dev); + ramtron_unlock(priv->dev); return nblocks; } @@ -522,7 +533,7 @@ static ssize_t ramtron_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_ ************************************************************************************/ static ssize_t ramtron_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, - FAR uint8_t *buffer) + FAR uint8_t *buffer) { FAR struct ramtron_dev_s *priv = (FAR struct ramtron_dev_s *)dev; @@ -662,6 +673,7 @@ FAR struct mtd_dev_s *ramtron_initialize(FAR struct spi_dev_s *dev) if (ramtron_readid(priv) != OK) { /* Unrecognized! Discard all of that work we just did and return NULL */ + kfree(priv); priv = NULL; } diff --git a/nuttx/drivers/mtd/w25.c b/nuttx/drivers/mtd/w25.c index 0d7028fec..bd6680fdf 100644 --- a/nuttx/drivers/mtd/w25.c +++ b/nuttx/drivers/mtd/w25.c @@ -693,7 +693,7 @@ static void w25_pagewrite(struct w25_dev_s *priv, FAR const uint8_t *buffer, uint8_t status; fvdbg("address: %08lx nwords: %d\n", (long)address, (int)nbytes); - DEBUGASSERT(priv && buffer && ((uintptr_t)buffer & 0xff) == 0 && + DEBUGASSERT(priv && buffer && (address & 0xff) == 0 && (nbytes & 0xff) == 0); for (; nbytes > 0; nbytes -= W25_PAGE_SIZE) @@ -955,36 +955,27 @@ static int w25_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks static ssize_t w25_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, FAR uint8_t *buffer) { -#ifdef CONFIG_W25_SECTOR512 ssize_t nbytes; fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); /* On this device, we can handle the block read just like the byte-oriented read */ +#ifdef CONFIG_W25_SECTOR512 nbytes = w25_read(dev, startblock << W25_SECTOR512_SHIFT, nblocks << W25_SECTOR512_SHIFT, buffer); if (nbytes > 0) { - return nbytes >> W25_SECTOR512_SHIFT; + nbytes >>= W25_SECTOR512_SHIFT; } - - return (int)nbytes; #else - FAR struct w25_dev_s *priv = (FAR struct w25_dev_s *)dev; - ssize_t nbytes; - - fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); - - /* On this device, we can handle the block read just like the byte-oriented read */ - nbytes = w25_read(dev, startblock << W25_SECTOR_SHIFT, nblocks << W25_SECTOR_SHIFT, buffer); if (nbytes > 0) { - return nbytes >> W25_SECTOR_SHIFT; + nbytes >>= W25_SECTOR_SHIFT; } - - return (int)nbytes; #endif + + return nbytes; } /************************************************************************************ diff --git a/nuttx/fs/nxffs/Kconfig b/nuttx/fs/nxffs/Kconfig index b233e85ea..9f4ef8231 100644 --- a/nuttx/fs/nxffs/Kconfig +++ b/nuttx/fs/nxffs/Kconfig @@ -12,31 +12,31 @@ config FS_NXFFS if FS_NXFFS config NXFFS_ERASEDSTATE - bool "FLASH erased state" - default n + hex "FLASH erased state" + default 0xff ---help--- The erased state of FLASH. This must have one of the values of 0xff or 0x00. Default: 0xff. config NXFFS_PACKTHRESHOLD - bool "Re-packing threshold" - default n + int "Re-packing threshold" + default 32 ---help--- When packing flash file data, don't both with file chunks smaller than this number of data bytes. Default: 32. config NXFFS_MAXNAMLEN - bool "Maximum file name length" - default n + int "Maximum file name length" + default 255 ---help--- The maximum size of an NXFFS file name. Default: 255. config NXFFS_TAILTHRESHOLD - bool "Tail threshold" - default n + int "Tail threshold" + default 8192 ---help--- clean-up can either mean packing files together toward the end of the file or, if file are diff --git a/nuttx/include/nuttx/input/ads7843e.h b/nuttx/include/nuttx/input/ads7843e.h index 53aa2f227..fe4382f2f 100644 --- a/nuttx/include/nuttx/input/ads7843e.h +++ b/nuttx/include/nuttx/input/ads7843e.h @@ -70,6 +70,16 @@ # define CONFIG_ADS7843E_SPIMODE SPIDEV_MODE0 #endif +/* Thresholds */ + +#ifndef CONFIG_ADS7843E_THRESHX +# define CONFIG_ADS7843E_THRESHX 12 +#endif + +#ifndef CONFIG_ADS7843E_THRESHY +# define CONFIG_ADS7843E_THRESHY 12 +#endif + /* Check for some required settings. This can save the user a lot of time * in getting the right configuration. */ @@ -149,7 +159,7 @@ extern "C" { * number * * Input Parameters: - * dev - An SPI driver instance + * spi - An SPI driver instance * config - Persistent board configuration data * minor - The input device minor number * @@ -159,7 +169,7 @@ extern "C" { * ****************************************************************************/ -EXTERN int ads7843e_register(FAR struct spi_dev_s *dev, +EXTERN int ads7843e_register(FAR struct spi_dev_s *spi, FAR struct ads7843e_config_s *config, int minor); diff --git a/nuttx/include/nuttx/input/stmpe811.h b/nuttx/include/nuttx/input/stmpe811.h index cea54a34f..fc311f7c4 100644 --- a/nuttx/include/nuttx/input/stmpe811.h +++ b/nuttx/include/nuttx/input/stmpe811.h @@ -85,7 +85,7 @@ * CONFIG_STMPE811_TEMP_DISABLE * Disable driver temperature sensor functionality. * CONFIG_STMPE811_REGDEBUG - * Enabled very low register-level debug output. Requires CONFIG_DEBUG. + * Enable very low register-level debug output. Requires CONFIG_DEBUG. * CONFIG_STMPE811_THRESHX and CONFIG_STMPE811_THRESHY * STMPE811 touchscreen data comes in a a very high rate. New touch positions * will only be reported when the X or Y data changes by these thresholds. diff --git a/nuttx/lib/stdio/lib_libvsprintf.c b/nuttx/lib/stdio/lib_libvsprintf.c index 2bf095880..30c988599 100644 --- a/nuttx/lib/stdio/lib_libvsprintf.c +++ b/nuttx/lib/stdio/lib_libvsprintf.c @@ -1169,7 +1169,9 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const char *src, va_list a FAR char *ptmp; #ifndef CONFIG_NOPRINTF_FIELDWIDTH int width; +#ifdef CONFIG_LIBC_FLOATINGPOINT int trunc; +#endif uint8_t fmt; #endif uint8_t flags; @@ -1212,8 +1214,10 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const char *src, va_list a #ifndef CONFIG_NOPRINTF_FIELDWIDTH fmt = FMT_RJUST; width = 0; +#ifdef CONFIG_LIBC_FLOATINGPOINT trunc = 0; #endif +#endif /* Process each format qualifier. */ @@ -1260,8 +1264,10 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const char *src, va_list a int value = va_arg(ap, int); if (IS_HASDOT(flags)) { +#ifdef CONFIG_LIBC_FLOATINGPOINT trunc = value; SET_HASASTERISKTRUNC(flags); +#endif } else { @@ -1300,7 +1306,9 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const char *src, va_list a if (IS_HASDOT(flags)) { +#ifdef CONFIG_LIBC_FLOATINGPOINT trunc = n; +#endif } else { diff --git a/nuttx/net/Kconfig b/nuttx/net/Kconfig index 718b28b8f..d4ea8befb 100644 --- a/nuttx/net/Kconfig +++ b/nuttx/net/Kconfig @@ -18,6 +18,9 @@ choice prompt "Board PHY Selection" depends on ARCH_HAVE_PHY default PHY_KS8721 + ---help--- + Identify the PHY on your board. This setting is not used by all Ethernet + drivers no do all Ethernet drivers support all PHYs. config PHY_KS8721 bool "Micrel KS8721 PHY" @@ -28,6 +31,9 @@ config PHY_DP83848C config PHY_LAN8720 bool "SMSC LAN8720 PHY" +config PHY_DM9161 + bool "Davicom DM9161 PHY" + endchoice config NET_NOINTS diff --git a/nuttx/net/uip/uip_icmpping.c b/nuttx/net/uip/uip_icmpping.c index 356187d09..e3ebf7252 100644 --- a/nuttx/net/uip/uip_icmpping.c +++ b/nuttx/net/uip/uip_icmpping.c @@ -148,122 +148,129 @@ static inline int ping_timeout(struct icmp_ping_s *pstate) ****************************************************************************/ static uint16_t ping_interrupt(struct uip_driver_s *dev, void *conn, - void *pvpriv, uint16_t flags) + void *pvpriv, uint16_t flags) { struct icmp_ping_s *pstate = (struct icmp_ping_s *)pvpriv; uint8_t *ptr; - int failcode = -ETIMEDOUT; int i; nllvdbg("flags: %04x\n", flags); if (pstate) { - /* Check if this device is on the same network as the destination device. */ - - if (!uip_ipaddr_maskcmp(pstate->png_addr, dev->d_ipaddr, dev->d_netmask)) - { - /* Destination address was not on the local network served by this - * device. If a timeout occurs, then the most likely reason is - * that the destination address is not reachable. - */ + /* Check if this is a ICMP ECHO reply. If so, return the sequence + * number to the caller. NOTE: We may not even have sent the + * requested ECHO request; this could have been the delayed ECHO + * response from a previous ping. + */ - nllvdbg("Not reachable\n"); - failcode = -ENETUNREACH; - } - else + if ((flags & UIP_ECHOREPLY) != 0 && conn != NULL) { - /* Check if this is a ICMP ECHO reply. If so, return the sequence - * number to the caller. NOTE: We may not even have sent the - * requested ECHO request; this could have been the delayed ECHO - * response from a previous ping. - */ + struct uip_icmpip_hdr *icmp = (struct uip_icmpip_hdr *)conn; + nlldbg("ECHO reply: id=%d seqno=%d\n", + ntohs(icmp->id), ntohs(icmp->seqno)); - if ((flags & UIP_ECHOREPLY) != 0 && conn != NULL) + if (ntohs(icmp->id) == pstate->png_id) { - struct uip_icmpip_hdr *icmp = (struct uip_icmpip_hdr *)conn; - nlldbg("ECHO reply: id=%d seqno=%d\n", ntohs(icmp->id), ntohs(icmp->seqno)); + /* Consume the ECHOREPLY */ - if (ntohs(icmp->id) == pstate->png_id) - { - /* Consume the ECHOREPLY */ + flags &= ~UIP_ECHOREPLY; + dev->d_len = 0; - flags &= ~UIP_ECHOREPLY; - dev->d_len = 0; + /* Return the result to the caller */ - /* Return the result to the caller */ - - pstate->png_result = OK; - pstate->png_seqno = ntohs(icmp->seqno); - goto end_wait; - } + pstate->png_result = OK; + pstate->png_seqno = ntohs(icmp->seqno); + goto end_wait; } + } - /* Check: - * If the outgoing packet is available (it may have been claimed - * by a sendto interrupt serving a different thread - * -OR- - * If the output buffer currently contains unprocessed incoming - * data. - * -OR- - * If we have alread sent the ECHO request - * - * In the first two cases, we will just have to wait for the next - * polling cycle. - */ + /* Check: + * If the outgoing packet is available (it may have been claimed + * by a sendto interrupt serving a different thread) + * -OR- + * If the output buffer currently contains unprocessed incoming + * data. + * -OR- + * If we have alread sent the ECHO request + * + * In the first two cases, we will just have to wait for the next + * polling cycle. + */ - if (dev->d_sndlen <= 0 && /* Packet available */ - (flags & UIP_NEWDATA) == 0 && /* No incoming data */ - !pstate->png_sent) /* Request not sent */ - { - struct uip_icmpip_hdr *picmp = ICMPBUF; + if (dev->d_sndlen <= 0 && /* Packet available */ + (flags & UIP_NEWDATA) == 0 && /* No incoming data */ + !pstate->png_sent) /* Request not sent */ + { + struct uip_icmpip_hdr *picmp = ICMPBUF; - /* We can send the ECHO request now. - * - * Format the ICMP ECHO request packet - */ + /* We can send the ECHO request now. + * + * Format the ICMP ECHO request packet + */ - picmp->type = ICMP_ECHO_REQUEST; - picmp->icode = 0; + picmp->type = ICMP_ECHO_REQUEST; + picmp->icode = 0; #ifndef CONFIG_NET_IPv6 - picmp->id = htons(pstate->png_id); - picmp->seqno = htons(pstate->png_seqno); + picmp->id = htons(pstate->png_id); + picmp->seqno = htons(pstate->png_seqno); #else # error "IPv6 ECHO Request not implemented" #endif - /* Add some easily verifiable data */ + /* Add some easily verifiable data */ - for (i = 0, ptr = ICMPDAT; i < pstate->png_datlen; i++) - { - *ptr++ = i; - } + for (i = 0, ptr = ICMPDAT; i < pstate->png_datlen; i++) + { + *ptr++ = i; + } - /* Send the ICMP echo request. Note that d_sndlen is set to - * the size of the ICMP payload and does not include the size - * of the ICMP header. - */ + /* Send the ICMP echo request. Note that d_sndlen is set to + * the size of the ICMP payload and does not include the size + * of the ICMP header. + */ - nlldbg("Send ECHO request: seqno=%d\n", pstate->png_seqno); + nlldbg("Send ECHO request: seqno=%d\n", pstate->png_seqno); - dev->d_sndlen = pstate->png_datlen + 4; - uip_icmpsend(dev, &pstate->png_addr); - pstate->png_sent = true; - return flags; - } + dev->d_sndlen = pstate->png_datlen + 4; + uip_icmpsend(dev, &pstate->png_addr); + pstate->png_sent = true; + return flags; } /* Check if the selected timeout has elapsed */ if (ping_timeout(pstate)) { - /* Yes.. report the timeout */ + int failcode; + + /* Check if this device is on the same network as the destination + * device. + */ + + if (!uip_ipaddr_maskcmp(pstate->png_addr, dev->d_ipaddr, dev->d_netmask)) + { + /* Destination address was not on the local network served by this + * device. If a timeout occurs, then the most likely reason is + * that the destination address is not reachable. + */ + + nlldbg("Not reachable\n"); + failcode = -ENETUNREACH; + } + else + { + nlldbg("Ping timeout\n"); + failcode = -ETIMEDOUT; + } + + /* Report the failure */ - nlldbg("Ping timeout\n"); pstate->png_result = failcode; goto end_wait; } /* Continue waiting */ } + return flags; end_wait: |