drivers/i2c: Move wrapper that implements I2C_WRITEREAD using I2C_transfer from pc9555.c to a new, comon i2c directory

This commit is contained in:
Gregory Nutt 2016-01-26 09:58:18 -06:00
parent 7fb7bef2d2
commit 67f38169b2
10 changed files with 245 additions and 72 deletions

View File

@ -11369,3 +11369,6 @@
ioexpander and not the I2C address. From Stefan Kolb (2016-01-26). ioexpander and not the I2C address. From Stefan Kolb (2016-01-26).
* drivers/ioexpander/pca9555: Convert to use I2C_TRANSFER vs. I2C_WRITEREAD, * drivers/ioexpander/pca9555: Convert to use I2C_TRANSFER vs. I2C_WRITEREAD,
the former is thread safe while the latter is deprecated (2016-01-26). the former is thread safe while the latter is deprecated (2016-01-26).
* drivers/i2c/i2c_writeread.c: Create a wrapper that uses I2C_TRANSFER
to implement I2C_WRITEREAD functionalit (2016-01-26).

View File

@ -271,38 +271,8 @@ menuconfig I2C
See include/nuttx/i2c.h for further I2C driver information. See include/nuttx/i2c.h for further I2C driver information.
if I2C if I2C
source drivers/i2c/Kconfig
config I2C_SLAVE endif
bool "I2C Slave"
default n
config I2C_TRANSFER
bool "Support the I2C transfer() method"
default n
config I2C_WRITEREAD
bool "Support the I2C writeread() method"
default n
config I2C_POLLED
bool "Polled I2C (no interrupts)"
default n
config I2C_TRACE
bool "Enable I2C trace debug"
default n
config I2C_NTRACE
int "Number of I2C trace records"
default 32
depends on I2C_TRACE
config I2C_RESET
bool "Support up_i2creset"
default n
depends on ARCH_HAVE_I2CRESET
endif # I2C
menuconfig SPI menuconfig SPI
bool "SPI Driver Support" bool "SPI Driver Support"

View File

@ -52,6 +52,7 @@ VPATH = .
include analog$(DELIM)Make.defs include analog$(DELIM)Make.defs
include audio$(DELIM)Make.defs include audio$(DELIM)Make.defs
include bch$(DELIM)Make.defs include bch$(DELIM)Make.defs
include i2c$(DELIM)Make.defs
include input$(DELIM)Make.defs include input$(DELIM)Make.defs
include ioexpander$(DELIM)Make.defs include ioexpander$(DELIM)Make.defs
include lcd$(DELIM)Make.defs include lcd$(DELIM)Make.defs

View File

@ -68,6 +68,9 @@ eeprom/
interface but instead use the simple character interface provided by interface but instead use the simple character interface provided by
the EEPROM drivers. the EEPROM drivers.
i2c/
I2C drivers and support logic. See include/nuttx/i2c.h
input/ input/
This directory holds implementations of human input device (HID) This directory holds implementations of human input device (HID)
drivers. This includes such things as mouse, touchscreen, joystick, drivers. This includes such things as mouse, touchscreen, joystick,
@ -144,7 +147,7 @@ serial/
the NuttX system console. See also include/nuttx/serial/serial.h the NuttX system console. See also include/nuttx/serial/serial.h
spi/ spi/
SPI drivers. See include/nuttx/spi.h SPI drivers and support logic. See include/nuttx/spi/spi.h
syslog/ syslog/
System logging devices. See include/syslog.h and include/nuttx/syslog/syslog.h System logging devices. See include/syslog.h and include/nuttx/syslog/syslog.h

38
drivers/i2c/Kconfig Normal file
View File

@ -0,0 +1,38 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
if I2C
config I2C_SLAVE
bool "I2C Slave"
default n
config I2C_TRANSFER
bool "Support the I2C transfer() method"
default n
config I2C_WRITEREAD
bool "Support the I2C writeread() method"
default n
config I2C_POLLED
bool "Polled I2C (no interrupts)"
default n
config I2C_TRACE
bool "Enable I2C trace debug"
default n
config I2C_NTRACE
int "Number of I2C trace records"
default 32
depends on I2C_TRACE
config I2C_RESET
bool "Support up_i2creset"
default n
depends on ARCH_HAVE_I2CRESET
endif # I2C

50
drivers/i2c/Make.defs Normal file
View File

@ -0,0 +1,50 @@
############################################################################
# drivers/i2c/Make.defs
#
# Copyright (C) 2016 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.
#
############################################################################
# Don't build anything if there is no I2C support
ifeq ($(CONFIG_I2C),y)
ifeq ($(CONFIG_I2C_TRANSFER),y)
CSRCS += i2c_writeread.c
endif
# Include I2C device driver build support
DEPPATH += --dep-path i2c
VPATH += :i2c
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)i2c}
endif

103
drivers/i2c/i2c_writeread.c Normal file
View File

@ -0,0 +1,103 @@
/****************************************************************************
* drivers/i2c/i2c_writeread.c
*
* Copyright (C) 2016 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <nuttx/i2c.h>
#if defined(CONFIG_I2C_TRANSFER)
/****************************************************************************
* Name: pca9555_writeread
*
* Description:
* Write to then read from the I2C device.
*
****************************************************************************/
int i2c_writeread(FAR struct i2c_dev_s *dev, FAR const struct i2c_config_s *config,
FAR const uint8_t *wbuffer, int wbuflen,
FAR uint8_t *rbuffer, int rbuflen)
{
struct i2c_msg_s msg[2];
unsigned int flags;
/* 7- or 10-bit address? */
DEBUGASSERT(config->addrlen == 10 || config->addrlen == 7);
flags = (config->addrlen == 10) ? I2C_M_TEN : 0;
/* Format two messages: The first is a write */
msg[0].addr = config->address;
msg[0].flags = flags;
msg[0].buffer = (FAR uint8_t *)wbuffer; /* Override const */
msg[0].length = wbuflen;
/* The second is either a read (rbuflen > 0) or a write (rbuflen < 0) with
* no restart.
*/
if (rbuflen > 0)
{
msg[1].flags = (flags | I2C_M_READ);
}
else
{
msg[1].flags = (flags | I2C_M_NORESTART);
rbuflen = -rbuflen;
}
msg[1].addr = config->address;
msg[1].buffer = rbuffer;
msg[1].length = rbuflen;
/* Then perform the transfer
*
* REVISIT: The following two operations must become atomic in order to
* assure thread safety.
*/
I2C_SETFREQUENCY(dev, config->frequency);
return I2C_TRANSFER(dev, msg, 2);
}
#endif /* CONFIG_I2C_TRANSFER */

View File

@ -137,41 +137,19 @@ static const struct ioexpander_ops_s g_pca9555_ops =
* *
****************************************************************************/ ****************************************************************************/
static int pca9555_writeread(FAR struct pca9555_dev_s *pca, static inline int pca9555_writeread(FAR struct pca9555_dev_s *pca,
FAR const uint8_t *wbuffer, int wbuflen, FAR const uint8_t *wbuffer, int wbuflen,
FAR uint8_t *rbuffer, int rbuflen) FAR uint8_t *rbuffer, int rbuflen)
{ {
struct i2c_msg_s msg[2]; struct i2c_config_s config;
/* Format two messages: The first is a write */ /* Set up the configuration and perform the write-read operation */
msg[0].addr = pca->config->address; config.frequency = pca->config->frequency;
msg[0].flags = 0; config.address = pca->config->address;
msg[0].buffer = (uint8_t *)wbuffer; /* Override const */ config.addrlen = 7;
msg[0].length = wbuflen;
/* The second is either a read (rbuflen > 0) or a write (rbuflen < 0) with return i2c_writeread(pca->i2c, &config, wbuffer, wbuflen, rbuffer, rbuflen);
* no restart.
*/
if (rbuflen > 0)
{
msg[1].flags = I2C_M_READ;
}
else
{
msg[1].flags = I2C_M_NORESTART;
rbuflen = -rbuflen;
}
msg[1].addr = pca->config->address;
msg[1].buffer = rbuffer;
msg[1].length = rbuflen;
/* Then perform the transfer */
I2C_SETFREQUENCY(pca->i2c, pca->config->frequency);
return I2C_TRANSFER(pca->i2c, msg, 2);
} }
/**************************************************************************** /****************************************************************************

View File

@ -80,5 +80,5 @@ config SPI_BITBANG_VARWIDTH
Enable support for a variable data width transfers. Default: 8-bit Enable support for a variable data width transfers. Default: 8-bit
only. only.
endif endif # SPI_BITBANG
endif endif # SPI

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* include/nuttx/i2c.h * include/nuttx/i2c.h
* *
* Copyright(C) 2009-2012 Gregory Nutt. All rights reserved. * Copyright(C) 2009-2012, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -254,8 +254,9 @@ struct i2c_ops_s
int buflen); int buflen);
int (*read)(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen); int (*read)(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen);
#ifdef CONFIG_I2C_WRITEREAD #ifdef CONFIG_I2C_WRITEREAD
int (*writeread)(FAR struct i2c_dev_s *inst, const uint8_t *wbuffer, int (*writeread)(FAR struct i2c_dev_s *dev,
int wbuflen, uint8_t *rbuffer, int rbuflen); FAR const uint8_t *wbuffer, int wbuflen,
FAR uint8_t *rbuffer, int rbuflen);
#endif #endif
#ifdef CONFIG_I2C_TRANSFER #ifdef CONFIG_I2C_TRANSFER
int (*transfer)(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs, int (*transfer)(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs,
@ -268,6 +269,18 @@ struct i2c_ops_s
#endif #endif
}; };
/* This structure contains the full state of I2C as needed for a specific
* transfer. It is passed to I2C methods so that I2C transfer may be
* performed in a thread safe manner.
*/
struct i2c_config_s
{
uint32_t frequency; /* I2C frequency */
uint16_t address; /* I2C address (7 or 10 bit) */
uint8_t addrlen; /* I2C address length (7 or 10 bits) */
};
/* I2C transaction segment beginning with a START. A number of these can /* I2C transaction segment beginning with a START. A number of these can
* be transferred together to form an arbitrary sequence of write/read transfer * be transferred together to form an arbitrary sequence of write/read transfer
* to an I2C slave device. * to an I2C slave device.
@ -352,6 +365,20 @@ int up_i2cuninitialize(FAR struct i2c_dev_s *dev);
int up_i2creset(FAR struct i2c_dev_s *dev); int up_i2creset(FAR struct i2c_dev_s *dev);
#endif #endif
/************************************************************************************
* Name: i2c_writeread
*
* Description:
* Write to then read from the I2C device.
*
************************************************************************************/
#ifdef CONFIG_I2C_TRANSFER
int i2c_writeread(FAR struct i2c_dev_s *dev, FAR const struct i2c_config_s *config,
FAR const uint8_t *wbuffer, int wbuflen,
FAR uint8_t *rbuffer, int rbuflen);
#endif
#undef EXTERN #undef EXTERN
#if defined(__cplusplus) #if defined(__cplusplus)
} }