Merge remote-tracking branch 'origin/master' into composite

This commit is contained in:
Gregory Nutt
2017-06-01 16:35:41 -06:00
34 changed files with 1764 additions and 181 deletions

View File

@@ -280,7 +280,11 @@ tools/cnvwindeps$(HOSTEXEEXT):
# Directories links. Most of establishing the NuttX configuration involves
# setting up symbolic links with 'generic' directory names to specific,
# configured directories.
#
Make.defs:
echo "include $(TOPDIR)$(DELIM).config" > Make.defs
echo "include $(TOPDIR)$(DELIM)tools$(DELIM)Config.mk" >> Make.defs
# Link the arch/<arch-name>/include directory to include/arch
include/arch: Make.defs

View File

@@ -275,7 +275,11 @@ tools\mkdeps$(HOSTEXEEXT):
# Directories links. Most of establishing the NuttX configuration involves
# setting up symbolic links with 'generic' directory names to specific,
# configured directories.
#
Make.defs:
echo "include $(TOPDIR)$(DELIM).config" > Make.defs
echo "include $(TOPDIR)$(DELIM)tools$(DELIM)Config.mk" >> Make.defs
# Link the arch\<arch-name>\include directory to include\arch
include\arch: Make.defs

View File

@@ -186,6 +186,13 @@ Ubuntu Bash under Windows 10
With these differences (perhaps a few other Windows quirks) the Ubuntu
install works just like Ubuntu running natively on your PC.
A good tip for file sharing is to use symbolic links within your Ubuntu
home directory. For example, suppose you have your "projects" directory
at C:\Documents\projects. Then you can set up a link to the projects/
directory in your Ubuntu directory like:
$ ln -s /mnt/c/Documents/projects projects
Accessing Ubuntu Files From Windows
-----------------------------------
In Ubuntu Userspace for Windows, the Ubuntu file system root directory is
@@ -205,6 +212,8 @@ Ubuntu Bash under Windows 10
able to use Windows tools outside of the Ubuntu sandbox with versions of
NuttX built within the sandbox using that path.
Executing Windows Tools from Ubuntu
-----------------------------------
You can also execute Windows tools from within the Ubuntu sandbox:
$ /mnt/c/Program\ Files\ \(x86\)/Microchip/xc32/v1.43/bin/xc32-gcc.exe --version
@@ -217,7 +226,7 @@ Ubuntu Bash under Windows 10
POSIX paths. I think you would have to use Linux tools only from within
the Ubuntu sandbox.
Install Linux Software.
Install Ubuntu Software
-----------------------
Use "sudo apt-get install <package name>". As examples, this is how
you would get GIT:

9
TODO
View File

@@ -1,4 +1,4 @@
NuttX TODO List (Last updated May 18, 2017)
NuttX TODO List (Last updated May 31, 2017)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This file summarizes known NuttX bugs, limitations, inconsistencies with
@@ -45,6 +45,13 @@ o Task/Scheduler (sched/)
terminated?
Status: Closed. No, this behavior will not be implemented.
Priority: Medium, required for good emulation of process/pthread model.
The current behavior allows for the main thread of a task to
exit() and any child pthreads will perist. That does raise
some issues: The main thread is treated much like just-another-
pthread but must follow the semantics of a task or a process.
That results in some inconsistencies (for example, with robust
mutexes, what should happen if the main thread exits while
holding a mutex?)
Title: pause() NON-COMPLIANCE
Description: In the POSIX description of this function the pause() function

View File

@@ -80,6 +80,7 @@
#include "up_internal.h"
#include "up_arch.h"
#include "cache.h"
#include "chip.h"
#include "stm32_gpio.h"
#include "stm32_dma.h"
@@ -110,12 +111,10 @@
#ifdef CONFIG_STM32F7_SPI_DMA
# error "SPI DMA not yet supported"
# if defined(CONFIG_SPI_DMAPRIO)
# define SPI_DMA_PRIO CONFIG_SPI_DMAPRIO
# elif defined(DMA_SCR_PRIMED)
# define SPI_DMA_PRIO DMA_SCR_PRIMED
# define SPI_DMA_PRIO DMA_SCR_PRILO
# else
# error "Unknown STM32 DMA"
# endif
@@ -264,8 +263,8 @@ static struct stm32_spidev_s g_spi1dev =
.spiirq = STM32_IRQ_SPI1,
#endif
#ifdef CONFIG_STM32F7_SPI_DMA
.rxch = DMACHAN_SPI1_RX,
.txch = DMACHAN_SPI1_TX,
.rxch = DMAMAP_SPI1_RX,
.txch = DMAMAP_SPI1_TX,
#endif
};
#endif
@@ -308,8 +307,8 @@ static struct stm32_spidev_s g_spi2dev =
.spiirq = STM32_IRQ_SPI2,
#endif
#ifdef CONFIG_STM32F7_SPI_DMA
.rxch = DMACHAN_SPI2_RX,
.txch = DMACHAN_SPI2_TX,
.rxch = DMAMAP_SPI2_RX,
.txch = DMAMAP_SPI2_TX,
#endif
};
#endif
@@ -352,8 +351,8 @@ static struct stm32_spidev_s g_spi3dev =
.spiirq = STM32_IRQ_SPI3,
#endif
#ifdef CONFIG_STM32F7_SPI_DMA
.rxch = DMACHAN_SPI3_RX,
.txch = DMACHAN_SPI3_TX,
.rxch = DMAMAP_SPI3_RX,
.txch = DMAMAP_SPI3_TX,
#endif
};
#endif
@@ -396,8 +395,8 @@ static struct stm32_spidev_s g_spi4dev =
.spiirq = STM32_IRQ_SPI4,
#endif
#ifdef CONFIG_STM32F7_SPI_DMA
.rxch = DMACHAN_SPI4_RX,
.txch = DMACHAN_SPI4_TX,
.rxch = DMAMAP_SPI4_RX,
.txch = DMAMAP_SPI4_TX,
#endif
};
#endif
@@ -440,8 +439,8 @@ static struct stm32_spidev_s g_spi5dev =
.spiirq = STM32_IRQ_SPI5,
#endif
#ifdef CONFIG_STM32F7_SPI_DMA
.rxch = DMACHAN_SPI5_RX,
.txch = DMACHAN_SPI5_TX,
.rxch = DMAMAP_SPI5_RX,
.txch = DMAMAP_SPI5_TX,
#endif
};
#endif
@@ -484,8 +483,8 @@ static struct stm32_spidev_s g_spi6dev =
.spiirq = STM32_IRQ_SPI6,
#endif
#ifdef CONFIG_STM32F7_SPI_DMA
.rxch = DMACHAN_SPI6_RX,
.txch = DMACHAN_SPI6_TX,
.rxch = DMAMAP_SPI6_RX,
.txch = DMAMAP_SPI6_TX,
#endif
};
#endif
@@ -927,7 +926,7 @@ static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv, FAR const void *txbu
************************************************************************************/
#ifdef CONFIG_STM32F7_SPI_DMA
static inline void spi_dmarxstart(FAR struct stm32_spidev_s *priv)
static void spi_dmarxstart(FAR struct stm32_spidev_s *priv)
{
priv->rxresult = 0;
stm32_dmastart(priv->rxdma, spi_dmarxcallback, priv, false);
@@ -943,7 +942,7 @@ static inline void spi_dmarxstart(FAR struct stm32_spidev_s *priv)
************************************************************************************/
#ifdef CONFIG_STM32F7_SPI_DMA
static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv)
static void spi_dmatxstart(FAR struct stm32_spidev_s *priv)
{
priv->txresult = 0;
stm32_dmastart(priv->txdma, spi_dmatxcallback, priv, false);
@@ -1528,6 +1527,8 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
{
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
DEBUGASSERT(priv != NULL);
#ifdef CONFIG_STM32F7_DMACAPABLE
if ((txbuffer && !stm32_dmacapable((uint32_t)txbuffer, nwords, priv->txccr)) ||
(rxbuffer && !stm32_dmacapable((uint32_t)rxbuffer, nwords, priv->rxccr)))
@@ -1539,17 +1540,31 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
else
#endif
{
static uint16_t rxdummy = 0xffff;
static uint8_t rxdummy[ARMV7M_DCACHE_LINESIZE]
__attribute__((aligned(ARMV7M_DCACHE_LINESIZE)));
static const uint16_t txdummy = 0xffff;
size_t buflen = nwords;
if (spi_9to16bitmode(priv))
{
buflen = nwords * sizeof(uint16_t);
}
spiinfo("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords);
DEBUGASSERT(priv && priv->spibase);
DEBUGASSERT(priv->spibase != 0);
/* Setup DMAs */
spi_dmarxsetup(priv, rxbuffer, &rxdummy, nwords);
spi_dmarxsetup(priv, rxbuffer, (uint16_t *)rxdummy, nwords);
spi_dmatxsetup(priv, txbuffer, &txdummy, nwords);
/* Flush cache to physical memory */
if (txbuffer)
{
arch_flush_dcache((uintptr_t)txbuffer, (uintptr_t)txbuffer + buflen);
}
/* Start the DMAs */
spi_dmarxstart(priv);
@@ -1559,6 +1574,19 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
spi_dmarxwait(priv);
spi_dmatxwait(priv);
/* Force RAM re-read */
if (rxbuffer)
{
arch_invalidate_dcache((uintptr_t)rxbuffer,
(uintptr_t)rxbuffer + buflen);
}
else
{
arch_invalidate_dcache((uintptr_t)rxdummy,
(uintptr_t)rxdummy + sizeof(rxdummy));
}
}
}
#endif /* CONFIG_STM32F7_SPI_DMA */
@@ -1694,7 +1722,7 @@ static void spi_bus_initialize(FAR struct stm32_spidev_s *priv)
priv->txdma = stm32_dmachannel(priv->txch);
DEBUGASSERT(priv->rxdma && priv->txdma);
spi_putreg(priv, STM32_SPI_CR2_OFFSET, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN);
spi_modifycr2(priv, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN, 0);
#endif
/* Enable spi */

View File

@@ -309,17 +309,15 @@ int stm32l4_configgpio(uint32_t cfgset)
/* Otherwise, it is an input pin. Should it configured as an EXTI interrupt? */
if ((cfgset & GPIO_EXTI) != 0)
if (pinmode != GPIO_MODER_OUTPUT && (cfgset & GPIO_EXTI) != 0)
{
#if 0
/* "In STM32 F1 the selection of the EXTI line source is performed through
* the EXTIx bits in the AFIO_EXTICRx registers, while in F2 series this
* selection is done through the EXTIx bits in the SYSCFG_EXTICRx registers.
/* The selection of the EXTI line source is performed through the EXTIx
* bits in the SYSCFG_EXTICRx registers.
*
* "Only the mapping of the EXTICRx registers has been changed, without any
* changes to the meaning of the EXTIx bits. However, the range of EXTI
* bits values has been extended to 0b1000 to support the two ports added
* in F2, port H and I (in F1 series the maximum value is 0b0110)."
* The range of EXTI bit values in STM32L4x6 goes to 0b1000 to support the
* ports up to PI in STM32L496xx devices. For STM32L4x3 the EXTI bit values
* end at 0b111 (for PH0, PH1 and PH3 only) and values for non-existent
* ports F and G are reserved.
*/
uint32_t regaddr;
@@ -334,7 +332,6 @@ int stm32l4_configgpio(uint32_t cfgset)
regval |= (((uint32_t)port) << shift);
putreg32(regval, regaddr);
#endif
}
leave_critical_section(flags);

View File

@@ -114,7 +114,7 @@ static inline void rcc_resetbkp(void)
/* Check if the RTC is already configured */
init_stat = rtc_is_inits();
init_stat = stm32l4_rtc_is_initialized();
if(!init_stat)
{
/* Enable write access to the backup domain (RTC registers, RTC

View File

@@ -76,7 +76,7 @@ enum alm_id_e
RTC_ALARM_LAST
};
/* Structure used to pass parmaters to set an alarm */
/* Structure used to pass parameters to set an alarm */
struct alm_setalarm_s
{
@@ -106,7 +106,7 @@ extern "C"
****************************************************************************/
/************************************************************************************
* Name: rtc_is_inits
* Name: stm32l4_rtc_is_initialized
*
* Description:
* Returns 'true' if the RTC has been initialized (according to the RTC itself).
@@ -120,10 +120,10 @@ extern "C"
* bool -- true if the INITS flag is set in the ISR.
*
************************************************************************************/
#ifdef CONFIG_RTC_DRIVER
bool rtc_is_inits(void);
#endif
#ifdef CONFIG_RTC_DRIVER
bool stm32l4_rtc_is_initialized(void);
#endif
/****************************************************************************
* Name: stm32l4_rtc_getdatetime_with_subseconds

View File

@@ -176,7 +176,7 @@ static void stm32l4_alarm_callback(FAR void *arg, unsigned int alarmid)
rtc_alarm_callback_t cb;
FAR void *priv;
DEBUGASSERT(priv != NULL);
DEBUGASSERT(arg != NULL);
DEBUGASSERT(alarmid == RTC_ALARMA || alarmid == RTC_ALARMB);
lower = (struct stm32l4_lowerhalf_s *)arg;

View File

@@ -95,6 +95,10 @@
# define CONFIG_RTC_MAGIC_REG (0)
#endif
#define RTC_MAGIC CONFIG_RTC_MAGIC
#define RTC_MAGIC_TIME_SET CONFIG_RTC_MAGIC_TIME_SET
#define RTC_MAGIC_REG STM32L4_RTC_BKR(CONFIG_RTC_MAGIC_REG)
/* Constants ************************************************************************/
#define SYNCHRO_TIMEOUT (0x00020000)
@@ -816,7 +820,7 @@ static inline void rtc_enable_alarm(void)
************************************************************************************/
/************************************************************************************
* Name: rtc_is_inits
* Name: stm32l4_rtc_is_initialized
*
* Description:
* Returns 'true' if the RTC has been initialized (according to the RTC itself).
@@ -831,7 +835,7 @@ static inline void rtc_enable_alarm(void)
*
************************************************************************************/
bool rtc_is_inits(void)
bool stm32l4_rtc_is_initialized(void)
{
uint32_t regval;
@@ -867,8 +871,7 @@ int up_rtc_initialize(void)
* backed, we don't need or want to re-initialize on each reset.
*/
init_stat = rtc_is_inits();
init_stat = stm32l4_rtc_is_initialized();
if (!init_stat)
{
/* Enable write access to the backup domain (RTC registers, RTC
@@ -1164,7 +1167,7 @@ int stm32l4_rtc_setdatetime(FAR const struct tm *tp)
/* Then write the broken out values to the RTC */
/* Convert the struct tm format to RTC time register fields. All of the STM32
/* Convert the struct tm format to RTC time register fields.
* All of the ranges of values correspond between struct tm and the time
* register.
*/
@@ -1216,10 +1219,10 @@ int stm32l4_rtc_setdatetime(FAR const struct tm *tp)
/* Remember that the RTC is initialized and had its time set. */
if (getreg32(CONFIG_RTC_MAGIC_REG) != CONFIG_RTC_MAGIC_TIME_SET)
if (getreg32(RTC_MAGIC_REG) != RTC_MAGIC_TIME_SET)
{
stm32l4_pwr_enablebkp(true);
putreg32(CONFIG_RTC_MAGIC_TIME_SET, CONFIG_RTC_MAGIC_REG);
putreg32(RTC_MAGIC_TIME_SET, RTC_MAGIC_REG);
stm32l4_pwr_enablebkp(false);
}
@@ -1243,7 +1246,7 @@ int stm32l4_rtc_setdatetime(FAR const struct tm *tp)
bool stm32l4_rtc_havesettime(void)
{
return getreg32(CONFIG_RTC_MAGIC_REG) == CONFIG_RTC_MAGIC_TIME_SET;
return getreg32(RTC_MAGIC_REG) == RTC_MAGIC_TIME_SET;
}
/************************************************************************************

View File

@@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/tiva/tiva_ssi.c
*
* Copyright (C) 2009-2010, 2014, 2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2009-2010, 2014, 2016-2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -1616,8 +1616,8 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
* to the SSI3 peripheral, bringing it a fully functional state.
*/
tiva_ssi1_enablepwr();
tiva_ssi1_enableclk();
tiva_ssi3_enablepwr();
tiva_ssi3_enableclk();
/* Configure SSI3 GPIOs */
@@ -1626,7 +1626,7 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
tiva_configgpio(GPIO_SSI3_RX); /* PE2: SSI3 receive (SSI3Rx) */
tiva_configgpio(GPIO_SSI3_TX); /* PE3: SSI3 transmit (SSI3Tx) */
break;
#endif /* CONFIG_TIVA_SSI1 */
#endif /* CONFIG_TIVA_SSI3 */
default:
leave_critical_section(flags);

View File

@@ -183,7 +183,7 @@ void board_userled(int led, bool ledon)
{
if (led == 1)
{
stm32_gpiowrite(GPIO_LD2, ldeon);
stm32_gpiowrite(GPIO_LD2, ledon);
}
}
@@ -193,10 +193,7 @@ void board_userled(int led, bool ledon)
void board_userled_all(uint8_t ledset)
{
if (led == 1)
{
stm32_gpiowrite(GPIO_LD2, (ledset & BOARD_LD2_BIT) != 0);
}
stm32_gpiowrite(GPIO_LD2, (ledset & BOARD_LD2_BIT) != 0);
}
/****************************************************************************

View File

@@ -28,6 +28,7 @@ CONFIG_BUILD_FLAT=y
# CONFIG_MOTOROLA_SREC is not set
# CONFIG_RAW_BINARY is not set
# CONFIG_UBOOT_UIMAGE is not set
# CONFIG_DFU_BINARY is not set
#
# Customize Header Files
@@ -77,11 +78,11 @@ CONFIG_HOST_X86_64=y
CONFIG_SIM_X8664_SYSTEMV=y
# CONFIG_SIM_X8664_MICROSOFT is not set
# CONFIG_SIM_WALLTIME is not set
CONFIG_SIM_NET_HOST_ROUTE=y
# CONFIG_SIM_NET_BRIDGE is not set
# CONFIG_SIM_FRAMEBUFFER is not set
# CONFIG_SIM_SPIFLASH is not set
# CONFIG_SIM_QSPIFLASH is not set
# CONFIG_ARCH_TOOLCHAIN_IAR is not set
# CONFIG_ARCH_TOOLCHAIN_GNU is not set
#
# Architecture Options
@@ -102,6 +103,7 @@ CONFIG_ARCH_HAVE_MULTICPU=y
# CONFIG_ARCH_HAVE_EXTCLK is not set
CONFIG_ARCH_HAVE_POWEROFF=y
# CONFIG_ARCH_HAVE_RESET is not set
# CONFIG_ARCH_HAVE_RTC_SUBSECONDS is not set
# CONFIG_ARCH_STACKDUMP is not set
# CONFIG_ENDIAN_BIG is not set
# CONFIG_ARCH_IDLE_CUSTOM is not set
@@ -204,6 +206,8 @@ CONFIG_SCHED_WAITPID=y
#
CONFIG_PTHREAD_MUTEX_TYPES=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
# CONFIG_PTHREAD_MUTEX_UNSAFE is not set
# CONFIG_PTHREAD_MUTEX_BOTH is not set
CONFIG_NPTHREAD_KEYS=4
# CONFIG_PTHREAD_CLEANUP is not set
# CONFIG_CANCELLATION_POINTS is not set
@@ -368,6 +372,7 @@ CONFIG_SERIAL_CONSOLE=y
# CONFIG_PSEUDOTERM is not set
# CONFIG_USBDEV is not set
# CONFIG_USBHOST is not set
# CONFIG_USBMISC is not set
# CONFIG_HAVE_USBTRACE is not set
# CONFIG_DRIVERS_WIRELESS is not set
# CONFIG_DRIVERS_CONTACTLESS is not set
@@ -376,7 +381,9 @@ CONFIG_SERIAL_CONSOLE=y
# System Logging
#
# CONFIG_ARCH_SYSLOG is not set
CONFIG_SYSLOG_WRITE=y
# CONFIG_RAMLOG is not set
# CONFIG_SYSLOG_BUFFER is not set
# CONFIG_SYSLOG_INTBUFFER is not set
# CONFIG_SYSLOG_TIMESTAMP is not set
CONFIG_SYSLOG_SERIAL_CONSOLE=y
@@ -437,6 +444,11 @@ CONFIG_MM_REGIONS=1
# CONFIG_ARCH_HAVE_HEAP2 is not set
# CONFIG_GRAN is not set
#
# Common I/O Buffer Support
#
# CONFIG_MM_IOB is not set
#
# Audio Support
#
@@ -445,6 +457,7 @@ CONFIG_MM_REGIONS=1
#
# Wireless Support
#
# CONFIG_WIRELESS is not set
#
# Binary Loader
@@ -594,7 +607,6 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512
# CONFIG_EXAMPLES_MM is not set
# CONFIG_EXAMPLES_MODBUS is not set
# CONFIG_EXAMPLES_MOUNT is not set
# CONFIG_EXAMPLES_NRF24L01TERM is not set
# CONFIG_EXAMPLES_NSH is not set
# CONFIG_EXAMPLES_NULL is not set
# CONFIG_EXAMPLES_NX is not set
@@ -630,6 +642,7 @@ CONFIG_EXAMPLES_OSTEST_WAITRESULT=y
# CONFIG_EXAMPLES_TOUCHSCREEN is not set
# CONFIG_EXAMPLES_WATCHDOG is not set
# CONFIG_EXAMPLES_WEBSERVER is not set
# CONFIG_EXAMPLES_XBC_TEST is not set
#
# File System Utilities
@@ -700,3 +713,14 @@ CONFIG_EXAMPLES_OSTEST_WAITRESULT=y
# CONFIG_SYSTEM_UBLOXMODEM is not set
# CONFIG_SYSTEM_VI is not set
# CONFIG_SYSTEM_ZMODEM is not set
#
# Wireless Libraries and NSH Add-Ons
#
#
# IEEE 802.15.4 applications
#
# CONFIG_IEEE802154_LIBMAC is not set
# CONFIG_IEEE802154_LIBUTILS is not set
# CONFIG_IEEE802154_I8SAK is not set

View File

@@ -322,6 +322,30 @@ config STMPE811_REGDEBUG
endif # INPUT_STMPE811
config INPUT_CYPRESS_MBR3108
bool "Enable Cypress MBR3108 CapSense driver"
default n
---help---
Enable support for Cypress MBR3108 CapSense touch button & proximity
input sensor.
if INPUT_CYPRESS_MBR3108
config INPUT_CYPRESS_MBR3108_DEBUG
bool "Enable debug support for Cypress sensor"
default n
depends on DEBUG_FEATURES
---help---
Enable debugging traces for MBR3108 driver
config INPUT_CYPRESS_MBR3108_NPOLLWAITERS
int "Number of waiters to poll"
default 1
---help---
Maximum number of threads that can be waiting on poll()
endif # INPUT_CYPRESS_MBR3108
config BUTTONS
bool "Button Inputs"
default n

View File

@@ -71,6 +71,10 @@ ifneq ($(CONFIG_INPUT_STMPE811_TEMP_DISABLE),y)
endif
endif
ifeq ($(CONFIG_INPUT_CYPRESS_MBR3108),y)
CSRCS += cypress_mbr3108.c
endif
ifeq ($(CONFIG_BUTTONS),y)
CSRCS += button_upper.c
ifeq ($(CONFIG_BUTTONS_LOWER),y)

File diff suppressed because it is too large Load Diff

View File

@@ -352,7 +352,14 @@ static int mtdconfig_findfirstentry(FAR struct mtdconfig_struct_s *dev,
off_t bytes_left_in_block;
uint16_t endblock;
mtdconfig_readbytes(dev, 0, sig, sizeof(sig)); /* Read the signature bytes */
/* Read the signature bytes */
ret = mtdconfig_readbytes(dev, 0, sig, sizeof(sig));
if (ret != OK)
{
return 0;
}
if (sig[0] != 'C' || sig[1] != 'D' || sig[2] != CONFIGDATA_FORMAT_VERSION)
{
/* Config Data partition not formatted. */
@@ -788,7 +795,14 @@ static off_t mtdconfig_consolidate(FAR struct mtdconfig_struct_s *dev)
/* Scan all headers and move them to the src_offset */
retry_relocate:
MTD_READ(dev->mtd, src_offset, sizeof(hdr), (uint8_t *) &hdr);
bytes = MTD_READ(dev->mtd, src_offset, sizeof(hdr), (uint8_t *) &hdr);
if (bytes != sizeof(hdr))
{
/* I/O Error! */
goto errout;
}
if (hdr.flags == MTD_ERASED_FLAGS)
{
/* Test if the source entry is active or if we are at the end
@@ -967,6 +981,11 @@ static ssize_t mtdconfig_read(FAR struct file *filep, FAR char *buffer,
/* Read data from the file */
bytes = MTD_READ(dev->mtd, dev->readoff, len, (uint8_t *) buffer);
if (bytes != len)
{
return -EIO;
}
dev->readoff += bytes;
return bytes;
}
@@ -981,6 +1000,7 @@ static int mtdconfig_findentry(FAR struct mtdconfig_struct_s *dev,
FAR struct mtdconfig_header_s *phdr)
{
uint16_t endblock;
int ret;
#ifdef CONFIG_MTD_CONFIG_RAM_CONSOLIDATE
endblock = dev->neraseblocks;
@@ -1013,7 +1033,15 @@ static int mtdconfig_findentry(FAR struct mtdconfig_struct_s *dev,
/* Read the 1st header from the next block */
mtdconfig_readbytes(dev, offset, (uint8_t *) phdr, sizeof(*phdr));
ret = mtdconfig_readbytes(dev, offset, (uint8_t *) phdr, sizeof(*phdr));
if (ret != OK)
{
/* Error reading the data */
offset = 0;
break;
}
if (phdr->flags == MTD_ERASED_FLAGS)
{
continue;

View File

@@ -157,7 +157,7 @@ static int part_procfs_stat(FAR const char *relpath,
****************************************************************************/
#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_PROCFS_EXCLUDE_PARTITIONS)
struct mtd_partition_s *g_pfirstpartition = NULL;
static struct mtd_partition_s *g_pfirstpartition = NULL;
const struct procfs_operations part_procfsoperations =
{

View File

@@ -1368,7 +1368,8 @@ static int smart_add_sector_to_cache(FAR struct smart_struct_s *dev,
index = 1;
if (dev->cache_entries < CONFIG_MTD_SMART_SECTOR_CACHE_SIZE)
{
index = dev->cache_entries++;
oldest = 0;
index = dev->cache_entries++;
}
else
{
@@ -1387,7 +1388,7 @@ static int smart_add_sector_to_cache(FAR struct smart_struct_s *dev,
if (dev->sCache[x].birth < oldest)
{
oldest = dev->sCache[x].birth;
index = x;
index = x;
}
}
}

View File

@@ -224,6 +224,7 @@ struct w25_dev_s
struct mtd_dev_s mtd; /* MTD interface */
FAR struct spi_dev_s *spi; /* Saved SPI interface instance */
uint16_t nsectors; /* Number of erase sectors */
uint8_t prev_instr; /* Previous instruction given to W25 device */
#if defined(CONFIG_W25_SECTOR512) && !defined(CONFIG_W25_READONLY)
uint8_t flags; /* Buffered sector flags */
@@ -247,6 +248,7 @@ static void w25_unprotect(FAR struct w25_dev_s *priv);
static uint8_t w25_waitwritecomplete(FAR struct w25_dev_s *priv);
static inline void w25_wren(FAR struct w25_dev_s *priv);
static inline void w25_wrdi(FAR struct w25_dev_s *priv);
static bool w25_is_erased(struct w25_dev_s *priv, off_t address, off_t size);
static void w25_sectorerase(FAR struct w25_dev_s *priv, off_t offset);
static inline int w25_chiperase(FAR struct w25_dev_s *priv);
static void w25_byteread(FAR struct w25_dev_s *priv, FAR uint8_t *buffer,
@@ -494,17 +496,17 @@ static uint8_t w25_waitwritecomplete(struct w25_dev_s *priv)
/* Given that writing could take up to few tens of milliseconds, and erasing
* could take more. The following short delay in the "busy" case will allow
* other peripherals to access the SPI bus.
* other peripherals to access the SPI bus. Delay would slow down writing
* too much, so go to sleep only if previous operation was not a page program
* operation.
*/
#if 0 /* Makes writes too slow */
if ((status & W25_SR_BUSY) != 0)
if (priv->prev_instr != W25_PP && (status & W25_SR_BUSY) != 0)
{
w25_unlock(priv->spi);
usleep(1000);
w25_lock(priv->spi);
}
#endif
}
while ((status & W25_SR_BUSY) != 0);
@@ -549,6 +551,55 @@ static inline void w25_wrdi(struct w25_dev_s *priv)
SPI_SELECT(priv->spi, SPIDEV_FLASH(0), false);
}
/************************************************************************************
* Name: w25_is_erased
************************************************************************************/
static bool w25_is_erased(struct w25_dev_s *priv, off_t address, off_t size)
{
size_t npages = size >> W25_PAGE_SHIFT;
uint32_t erased_32;
unsigned int i;
uint32_t *buf;
DEBUGASSERT((address % W25_PAGE_SIZE) == 0);
DEBUGASSERT((size % W25_PAGE_SIZE) == 0);
buf = kmm_malloc(W25_PAGE_SIZE);
if (!buf)
{
return false;
}
memset(&erased_32, W25_ERASED_STATE, sizeof(erased_32));
/* Walk all pages in given area. */
while (npages)
{
/* Check if all bytes of page is in erased state. */
w25_byteread(priv, (unsigned char *)buf, address, W25_PAGE_SIZE);
for (i = 0; i < W25_PAGE_SIZE / sizeof(uint32_t); i++)
{
if (buf[i] != erased_32)
{
/* Page not in erased state! */
kmm_free(buf);
return false;
}
}
address += W25_PAGE_SIZE;
npages--;
}
kmm_free(buf);
return true;
}
/************************************************************************************
* Name: w25_sectorerase
************************************************************************************/
@@ -559,6 +610,15 @@ static void w25_sectorerase(struct w25_dev_s *priv, off_t sector)
finfo("sector: %08lx\n", (long)sector);
/* Check if sector is already erased. */
if (w25_is_erased(priv, address, W25_SECTOR_SIZE))
{
/* Sector already in erased state, so skip erase. */
return;
}
/* Wait for any preceding write or erase operation to complete. */
(void)w25_waitwritecomplete(priv);
@@ -574,6 +634,7 @@ static void w25_sectorerase(struct w25_dev_s *priv, off_t sector)
/* Send the "Sector Erase (SE)" instruction */
(void)SPI_SEND(priv->spi, W25_SE);
priv->prev_instr = W25_SE;
/* Send the sector address high byte first. Only the most significant bits (those
* corresponding to the sector) have any meaning.
@@ -611,6 +672,7 @@ static inline int w25_chiperase(struct w25_dev_s *priv)
/* Send the "Chip Erase (CE)" instruction */
(void)SPI_SEND(priv->spi, W25_CE);
priv->prev_instr = W25_CE;
/* Deselect the FLASH */
@@ -647,8 +709,10 @@ static void w25_byteread(FAR struct w25_dev_s *priv, FAR uint8_t *buffer,
#ifdef CONFIG_W25_SLOWREAD
(void)SPI_SEND(priv->spi, W25_RDDATA);
priv->prev_instr = W25_RDDATA;
#else
(void)SPI_SEND(priv->spi, W25_FRD);
priv->prev_instr = W25_FRD;
#endif
/* Send the address high byte first. */
@@ -704,6 +768,7 @@ static void w25_pagewrite(struct w25_dev_s *priv, FAR const uint8_t *buffer,
/* Send the "Page Program (W25_PP)" Command */
SPI_SEND(priv->spi, W25_PP);
priv->prev_instr = W25_PP;
/* Send the address high byte first. */
@@ -760,6 +825,7 @@ static inline void w25_bytewrite(struct w25_dev_s *priv, FAR const uint8_t *buff
/* Send "Page Program (PP)" command */
(void)SPI_SEND(priv->spi, W25_PP);
priv->prev_instr = W25_PP;
/* Send the page offset high byte first. */

View File

@@ -406,7 +406,9 @@ static int rwb_rhreload(struct rwbuffer_s *rwb, off_t startblock)
int rwb_invalidate_writebuffer(FAR struct rwbuffer_s *rwb,
off_t startblock, size_t blockcount)
{
int ret;
int ret = OK;
/* Is there a write buffer? Is data saved in the write buffer? */
if (rwb->wrmaxblocks > 0 && rwb->wrnblocks > 0)
{
@@ -909,7 +911,7 @@ ssize_t rwb_write(FAR struct rwbuffer_s *rwb, off_t startblock,
*/
}
else
#else
#endif /* CONFIG_DRVR_WRITEBUFFER */
{
/* No write buffer.. just pass the write operation through via the
* flush callback.
@@ -917,7 +919,6 @@ ssize_t rwb_write(FAR struct rwbuffer_s *rwb, off_t startblock,
ret = rwb->wrflush(rwb->dev, wrbuffer, startblock, nblocks);
}
#endif
return (ssize_t)ret;
}

View File

@@ -41,6 +41,11 @@ config HTS221
if HTS221
config HTS221_I2C_FREQUENCY
int "HTS221 I2C frequency"
default 400000
range 1 400000
config DEBUG_HTS221
bool "Debug support for the HTS221"
default n
@@ -84,6 +89,11 @@ config LIS2DH
if LIS2DH
config LIS2DH_I2C_FREQUENCY
int "LIS2DH I2C frequency"
default 400000
range 1 400000
config DEBUG_LIS2DH
bool "Debug support for the LIS2DH"
default n
@@ -144,6 +154,11 @@ config LPS25H
if LPS25H
config LPS25H_I2C_FREQUENCY
int "LPS25H I2C frequency"
default 400000
range 1 400000
config DEBUG_LPS25H
bool "Debug support for the LPS25H"
default n

View File

@@ -61,6 +61,10 @@
# define hts221_dbg(x, ...) sninfo(x, ##__VA_ARGS__)
#endif
#ifndef CONFIG_HTS221_I2C_FREQUENCY
# define CONFIG_HTS221_I2C_FREQUENCY 400000
#endif
#define HTS221_WHO_AM_I 0x0f
#define HTS221_AV_CONF 0x10
#define HTS221_CTRL_REG1 0x20
@@ -221,16 +225,18 @@ static int32_t hts221_write_reg8(FAR struct hts221_dev_s *priv,
struct i2c_msg_s msgv[2] =
{
{
.addr = priv->addr,
.flags = 0,
.buffer = (FAR void *)&command[0],
.length = 1
.frequency = CONFIG_HTS221_I2C_FREQUENCY,
.addr = priv->addr,
.flags = 0,
.buffer = (FAR void *)&command[0],
.length = 1
},
{
.addr = priv->addr,
.flags = I2C_M_NORESTART,
.buffer = (FAR void *)&command[1],
.length = 1
.frequency = CONFIG_HTS221_I2C_FREQUENCY,
.addr = priv->addr,
.flags = I2C_M_NORESTART,
.buffer = (FAR void *)&command[1],
.length = 1
}
};
@@ -243,16 +249,18 @@ static int hts221_read_reg(FAR struct hts221_dev_s *priv,
struct i2c_msg_s msgv[2] =
{
{
.addr = priv->addr,
.flags = 0,
.buffer = (FAR void *)command,
.length = 1
.frequency = CONFIG_HTS221_I2C_FREQUENCY,
.addr = priv->addr,
.flags = 0,
.buffer = (FAR void *)command,
.length = 1
},
{
.addr = priv->addr,
.flags = I2C_M_READ,
.buffer = value,
.length = 1
.frequency = CONFIG_HTS221_I2C_FREQUENCY,
.addr = priv->addr,
.flags = I2C_M_READ,
.buffer = value,
.length = 1
}
};

View File

@@ -65,6 +65,10 @@
# define lis2dh_dbg(x, ...) sninfo(x, ##__VA_ARGS__)
#endif
#ifndef CONFIG_LIS2DH_I2C_FREQUENCY
# define CONFIG_LIS2DH_I2C_FREQUENCY 400000
#endif
#ifdef CONFIG_LIS2DH_DRIVER_SELFTEST
# define LSB_AT_10BIT_RESOLUTION 4
# define LSB_AT_12BIT_RESOLUTION 1
@@ -1594,16 +1598,18 @@ static int lis2dh_access(FAR struct lis2dh_dev_s *dev, uint8_t subaddr,
struct i2c_msg_s msgv[2] =
{
{
.addr = dev->addr,
.flags = 0,
.buffer = &subaddr,
.length = 1
.frequency = CONFIG_LIS2DH_I2C_FREQUENCY,
.addr = dev->addr,
.flags = 0,
.buffer = &subaddr,
.length = 1
},
{
.addr = dev->addr,
.flags = flags,
.buffer = buf,
.length = length
.frequency = CONFIG_LIS2DH_I2C_FREQUENCY,
.addr = dev->addr,
.flags = flags,
.buffer = buf,
.length = length
}
};

View File

@@ -58,6 +58,10 @@
# define lps25h_dbg(x, ...) sninfo(x, ##__VA_ARGS__)
#endif
#ifndef CONFIG_LPS25H_I2C_FREQUENCY
# define CONFIG_LPS25H_I2C_FREQUENCY 400000
#endif
#define LPS25H_PRESSURE_INTERNAL_DIVIDER 4096
/* 'AN4450 - Hardware and software guidelines for use of LPS25H pressure
@@ -277,16 +281,18 @@ static int lps25h_write_reg8(struct lps25h_dev_s *dev, uint8_t reg_addr,
struct i2c_msg_s msgv[2] =
{
{
.addr = dev->addr,
.flags = 0,
.buffer = &reg_addr,
.length = 1
.frequency = CONFIG_LPS25H_I2C_FREQUENCY,
.addr = dev->addr,
.flags = 0,
.buffer = &reg_addr,
.length = 1
},
{
.addr = dev->addr,
.flags = I2C_M_NORESTART,
.buffer = (void *)&value,
.length = 1
.frequency = CONFIG_LPS25H_I2C_FREQUENCY,
.addr = dev->addr,
.flags = I2C_M_NORESTART,
.buffer = (void *)&value,
.length = 1
}
};
@@ -300,16 +306,18 @@ static int lps25h_read_reg8(FAR struct lps25h_dev_s *dev,
struct i2c_msg_s msgv[2] =
{
{
.addr = dev->addr,
.flags = 0,
.buffer = reg_addr,
.length = 1
.frequency = CONFIG_LPS25H_I2C_FREQUENCY,
.addr = dev->addr,
.flags = 0,
.buffer = reg_addr,
.length = 1
},
{
.addr = dev->addr,
.flags = I2C_M_READ,
.buffer = value,
.length = 1
.frequency = CONFIG_LPS25H_I2C_FREQUENCY,
.addr = dev->addr,
.flags = I2C_M_READ,
.buffer = value,
.length = 1
}
};

View File

@@ -551,7 +551,7 @@ struct usb_strdesc_s;
int usbmsc_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc);
/************************************************************************************
* Name: usbmsc_getepdesc
* Name: usbmsc_getdevdesc
*
* Description:
* Return a pointer to the raw device descriptor

View File

@@ -14,6 +14,11 @@ config FUSB301
if FUSB301
config FUSB301_I2C_FREQUENCY
int "FUSB301 I2C frequency"
default 400000
range 1 400000
config DEBUG_FUSB301
bool "Enable debug support for the FUSB301"
default n

View File

@@ -63,6 +63,10 @@
# define fusb301_info(x, ...) uinfo(x, ##__VA_ARGS__)
#endif
#ifndef CONFIG_FUSB301_I2C_FREQUENCY
# define CONFIG_FUSB301_I2C_FREQUENCY 400000
#endif
/* Other macros */
#define FUSB301_I2C_RETRIES 10
@@ -146,15 +150,17 @@ static int fusb301_getreg(FAR struct fusb301_dev_s *priv, uint8_t reg)
DEBUGASSERT(priv);
msg[0].addr = priv->addr;
msg[0].flags = 0;
msg[0].buffer = &reg;
msg[0].length = 1;
msg[0].frequency = CONFIG_FUSB301_I2C_FREQUENCY;
msg[0].addr = priv->addr;
msg[0].flags = 0;
msg[0].buffer = &reg;
msg[0].length = 1;
msg[1].addr = priv->addr;
msg[1].flags = I2C_M_READ;
msg[1].buffer = &regval;
msg[1].length = 1;
msg[1].frequency = CONFIG_FUSB301_I2C_FREQUENCY;
msg[1].addr = priv->addr;
msg[1].flags = I2C_M_READ;
msg[1].buffer = &regval;
msg[1].length = 1;
/* Perform the transfer */
@@ -220,10 +226,11 @@ static int fusb301_putreg(FAR struct fusb301_dev_s *priv, uint8_t regaddr,
/* Setup 8-bit FUSB301 address write message */
msg.addr = priv->addr;
msg.flags = 0;
msg.buffer = txbuffer;
msg.length = 2;
msg.frequency = CONFIG_FUSB301_I2C_FREQUENCY;
msg.addr = priv->addr;
msg.flags = 0;
msg.buffer = txbuffer;
msg.length = 2;
/* Perform the transfer */

View File

@@ -221,11 +221,7 @@ FAR struct file_struct *fs_fdopen(int fd, int oflags, FAR struct tcb_s *tcb)
{
/* Zero the structure */
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
memset(stream, 0, sizeof(FILE));
#elif CONFIG_NUNGET_CHARS > 0
stream->fs_nungotten = 0;
#endif
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
/* Initialize the semaphore the manages access to the buffer */

View File

@@ -0,0 +1,139 @@
/****************************************************************************
* include/nuttx/input/cypress_mbr3108.c
*
* Copyright (C) 2014 Haltian Ltd. All rights reserved.
* Author: Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 __INCLUDE_NUTTX_INPUT_CYPRESS_MBR3108_H_
#define __INCLUDE_NUTTX_INPUT_CYPRESS_MBR3108_H_
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/compiler.h>
#include <stdbool.h>
#include <stdint.h>
/****************************************************************************
* Public Types
****************************************************************************/
/* Sensor configuration for Cypress MBR3108 device */
begin_packed_struct struct mbr3108_sensor_conf_s
{
uint8_t conf_data[128]; /* Sensor configuration, generated with EZ-Click. */
} end_packed_struct;
/* Debug configuration */
begin_packed_struct struct mbr3108_debug_conf_s
{
bool debug_mode; /* Configure to debug mode if 'true'. */
uint8_t debug_sensor_id; /* Sensor to read in debug mode. */
} end_packed_struct;
/* Write commands to MBR3108 driver. */
begin_packed_struct enum mbr3108_cmd_e
{
CYPRESS_MBR3108_CMD_SENSOR_CONF = -3,
CYPRESS_MBR3108_CMD_DEBUG_CONF,
CYPRESS_MBR3108_CMD_CLEAR_LATCHED,
} end_packed_struct;
/* CYPRESS_MBR3108_CMD_SENSOR_CONF command structure. Used to reconfigure
* chip with new configuration generated using EZ-Click tool. */
begin_packed_struct struct mbr3108_cmd_sensor_conf_s
{
enum mbr3108_cmd_e id;
struct mbr3108_sensor_conf_s conf;
} end_packed_struct;
/* CYPRESS_MBR3108_CMD_DEBUG_CONF command structure. Use to enable debug
* output from chip/sensor, see 'struct mbr3108_sensor_data_s'. */
begin_packed_struct struct mbr3108_cmd_debug_conf_s
{
enum mbr3108_cmd_e id;
struct mbr3108_debug_conf_s conf;
} end_packed_struct;
/* Sensor status output */
begin_packed_struct struct mbr3108_sensor_status_s
{
unsigned int button:8; /* MBR3108 has maximum of 8 button sensors
* configurable.
* Each bit in this field indicate if
* corresponding button is pressed. */
unsigned int latched_button:8;
unsigned int proximity:2; /* MBR3108 has maximum of 2 proximity
* sensors configurable. */
unsigned int latched_proximity:2;
} end_packed_struct;
/* Sensor debug data output */
begin_packed_struct struct mbr3108_sensor_debug_s
{
uint8_t sensor_total_capacitance;
uint16_t sensor_diff_counts;
uint16_t sensor_baseline;
uint16_t sensor_raw_counts;
uint16_t sensor_average_counts;
} end_packed_struct;
/* Board configuration */
struct mbr3108_board_s
{
int (*irq_attach) (FAR struct mbr3108_board_s *state, xcpt_t isr, FAR void *arg);
void (*irq_enable) (FAR struct mbr3108_board_s *state, bool enable);
int (*set_power) (FAR struct mbr3108_board_s *state, bool on);
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/* Device registration */
int cypress_mbr3108_register(FAR const char *devpath,
FAR struct i2c_master_s *dev,
uint8_t i2c_devaddr,
struct mbr3108_board_s *board_config,
const struct mbr3108_sensor_conf_s *sensor_conf);
#endif /* __INCLUDE_NUTTX_INPUT_CYPRESS_MBR3108_H_ */

View File

@@ -320,7 +320,7 @@
*
****************************************************************************/
#define SPI_SEND(d,wd) ((d)->ops->send(d,(uint16_t)wd))
#define SPI_SEND(d,wd) ((d)->ops->send(d,(uint16_t)(wd)))
/****************************************************************************
* Name: SPI_SNDBLOCK

View File

@@ -71,7 +71,7 @@
* Public Types
************************************************************************************/
/************************************************************************************
/************************************************************************************
* Public Data
************************************************************************************/

View File

@@ -240,9 +240,9 @@
#define COPY_SHIFT(shift) \
{ \
UIntN* dstN = (UIntN*)((((UIntN)dst8) PRE_LOOP_ADJUST) & \
UIntN* dstN = (UIntN*)((((uintptr_t)dst8) PRE_LOOP_ADJUST) & \
~(TYPE_WIDTH - 1)); \
UIntN* srcN = (UIntN*)((((UIntN)src8) PRE_LOOP_ADJUST) & \
UIntN* srcN = (UIntN*)((((uintptr_t)src8) PRE_LOOP_ADJUST) & \
~(TYPE_WIDTH - 1)); \
size_t length = count / TYPE_WIDTH; \
UIntN srcWord = INC_VAL(srcN); \
@@ -324,13 +324,13 @@ FAR void *memcpy(FAR void *dest, FAR const void *src, size_t count)
START_VAL(dst8);
START_VAL(src8);
while (((UIntN)dst8 & (TYPE_WIDTH - 1)) != WHILE_DEST_BREAK)
while (((uintptr_t)dst8 & (TYPE_WIDTH - 1)) != WHILE_DEST_BREAK)
{
INC_VAL(dst8) = INC_VAL(src8);
count--;
}
switch ((((UIntN)src8) PRE_SWITCH_ADJUST) & (TYPE_WIDTH - 1))
switch ((((uintptr_t)src8) PRE_SWITCH_ADJUST) & (TYPE_WIDTH - 1))
{
case 0: COPY_NO_SHIFT(); break;
case 1: COPY_SHIFT(1); break;

View File

@@ -58,7 +58,7 @@
* Name: pthread_mutex_add
*
* Description:
* Add the mutex to the list of mutexes held by this thread.
* Add the mutex to the list of mutexes held by this pthread.
*
* Parameters:
* mutex - The mux to be locked
@@ -70,17 +70,89 @@
static void pthread_mutex_add(FAR struct pthread_mutex_s *mutex)
{
FAR struct pthread_tcb_s *rtcb = (FAR struct pthread_tcb_s *)this_task();
irqstate_t flags;
FAR struct tcb_s *rtcb = this_task();
DEBUGASSERT(mutex->flink == NULL);
/* Add the mutex to the list of mutexes held by this task */
/* Check if this is a pthread. The main thread may also lock and unlock
* mutexes. The main thread, however, does not participate in the mutex
* consistency logic. Presumably, when the main thread exits, all of the
* child pthreads will also terminate.
*
* REVISIT: NuttX does not support that behavior at present; child pthreads
* will persist after the main thread exits.
*/
flags = enter_critical_section();
mutex->flink = rtcb->mhead;
rtcb->mhead = mutex;
leave_critical_section(flags);
if ((rtcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD)
{
FAR struct pthread_tcb_s *ptcb = (FAR struct pthread_tcb_s *)rtcb;
irqstate_t flags;
/* Add the mutex to the list of mutexes held by this pthread */
flags = enter_critical_section();
mutex->flink = ptcb->mhead;
ptcb->mhead = mutex;
leave_critical_section(flags);
}
}
/****************************************************************************
* Name: pthread_mutex_remove
*
* Description:
* Remove the mutex to the list of mutexes held by this pthread.
*
* Parameters:
* mutex - The mux to be locked
*
* Return Value:
* None
*
****************************************************************************/
static void pthread_mutex_remove(FAR struct pthread_mutex_s *mutex)
{
FAR struct tcb_s *rtcb = this_task();
/* Check if this is a pthread. The main thread may also lock and unlock
* mutexes. The main thread, however, does not participate in the mutex
* consistency logic.
*/
if ((rtcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD)
{
FAR struct pthread_tcb_s *ptcb = (FAR struct pthread_tcb_s *)rtcb;
FAR struct pthread_mutex_s *curr;
FAR struct pthread_mutex_s *prev;
irqstate_t flags;
flags = enter_critical_section();
/* Remove the mutex from the list of mutexes held by this task */
for (prev = NULL, curr = ptcb->mhead;
curr != NULL && curr != mutex;
prev = curr, curr = curr->flink);
DEBUGASSERT(curr == mutex);
/* Remove the mutex from the list. prev == NULL means that the mutex
* to be removed is at the head of the list.
*/
if (prev == NULL)
{
ptcb->mhead = mutex->flink;
}
else
{
prev->flink = mutex->flink;
}
mutex->flink = NULL;
leave_critical_section(flags);
}
}
/****************************************************************************
@@ -233,8 +305,6 @@ int pthread_mutex_trytake(FAR struct pthread_mutex_s *mutex)
int pthread_mutex_give(FAR struct pthread_mutex_s *mutex)
{
FAR struct pthread_mutex_s *curr;
FAR struct pthread_mutex_s *prev;
int ret = EINVAL;
/* Verify input parameters */
@@ -242,34 +312,9 @@ int pthread_mutex_give(FAR struct pthread_mutex_s *mutex)
DEBUGASSERT(mutex != NULL);
if (mutex != NULL)
{
FAR struct pthread_tcb_s *rtcb = (FAR struct pthread_tcb_s *)this_task();
irqstate_t flags;
flags = enter_critical_section();
/* Remove the mutex from the list of mutexes held by this task */
for (prev = NULL, curr = rtcb->mhead;
curr != NULL && curr != mutex;
prev = curr, curr = curr->flink);
DEBUGASSERT(curr == mutex);
/* Remove the mutex from the list. prev == NULL means that the mutex
* to be removed is at the head of the list.
*/
if (prev == NULL)
{
rtcb->mhead = mutex->flink;
}
else
{
prev->flink = mutex->flink;
}
mutex->flink = NULL;
leave_critical_section(flags);
pthread_mutex_remove(mutex);
/* Now release the underlying semaphore */
@@ -300,7 +345,7 @@ int pthread_mutex_give(FAR struct pthread_mutex_s *mutex)
#ifdef CONFIG_CANCELLATION_POINTS
uint16_t pthread_disable_cancel(void)
{
FAR struct pthread_tcb_s *tcb = (FAR struct pthread_tcb_s *)this_task();
FAR struct tcb_s *tcb = this_task();
irqstate_t flags;
uint16_t old;
@@ -309,15 +354,15 @@ uint16_t pthread_disable_cancel(void)
*/
flags = enter_critical_section();
old = tcb->cmn.flags & (TCB_FLAG_CANCEL_PENDING | TCB_FLAG_NONCANCELABLE);
tcb->cmn.flags &= ~(TCB_FLAG_CANCEL_PENDING | TCB_FLAG_NONCANCELABLE);
old = tcb->flags & (TCB_FLAG_CANCEL_PENDING | TCB_FLAG_NONCANCELABLE);
tcb->flags &= ~(TCB_FLAG_CANCEL_PENDING | TCB_FLAG_NONCANCELABLE);
leave_critical_section(flags);
return old;
}
void pthread_enable_cancel(uint16_t cancelflags)
{
FAR struct pthread_tcb_s *tcb = (FAR struct pthread_tcb_s *)this_task();
FAR struct tcb_s *tcb = this_task();
irqstate_t flags;
/* We need perform the following operations from within a critical section
@@ -325,7 +370,7 @@ void pthread_enable_cancel(uint16_t cancelflags)
*/
flags = enter_critical_section();
tcb->cmn.flags |= cancelflags;
tcb->flags |= cancelflags;
/* What should we do if there is a pending cancellation?
*
@@ -337,8 +382,8 @@ void pthread_enable_cancel(uint16_t cancelflags)
* then we need to terminate now by simply calling pthread_exit().
*/
if ((tcb->cmn.flags & TCB_FLAG_CANCEL_DEFERRED) == 0 &&
(tcb->cmn.flags & TCB_FLAG_CANCEL_PENDING) != 0)
if ((tcb->flags & TCB_FLAG_CANCEL_DEFERRED) == 0 &&
(tcb->flags & TCB_FLAG_CANCEL_PENDING) != 0)
{
pthread_exit(NULL);
}