incubator-nuttx/include/nuttx/i2c/i2c_master.h

391 lines
13 KiB
C

/****************************************************************************
* include/nuttx/i2c/i2c_master.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_I2C_I2C_MASTER_H
#define __INCLUDE_NUTTX_I2C_I2C_MASTER_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <nuttx/fs/ioctl.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* I2C address calculation. Convert 7- and 10-bit address to 8-bit and
* 16-bit read/write address
*/
#define I2C_READBIT 0x01
/* Convert 7- to 8-bit address */
#define I2C_ADDR8(a) ((a) << 1)
#define I2C_WRITEADDR8(a) I2C_ADDR8(a)
#define I2C_READADDR8(a) (I2C_ADDR8(a) | I2C_READBIT)
/* Convert 10- to 16-bit address */
#define I2C_ADDR10H(a) (0xf0 | (((a) >> 7) & 0x06))
#define I2C_ADDR10L(a) ((a) & 0xff)
#define I2C_WRITEADDR10H(a) I2C_ADDR10H(a)
#define I2C_WRITEADDR10L(a) I2C_ADDR10L(a)
#define I2C_READADDR10H(a) (I2C_ADDR10H(a) | I2C_READBIT)
#define I2C_READADDR10L(a) I2C_ADDR10L(a)
/* Bit definitions for the flags field in struct i2c_msg_s
*
* START/STOP Rules:
*
* 1. The lower half I2C driver will always issue the START condition at the
* beginning of a message unless I2C_M_NOSTART flag is set in the
* message.
*
* 2. The lower half I2C driver will always issue the STOP condition at the
* end of the messages unless:
*
* a. The I2C_M_NOSTOP flag is set in the message, OR
* b. The following message has the I2C_M_NOSTART flag set (meaning
* that following message is simply a continuation of the transfer).
*
* A proper I2C repeated start would then have I2C_M_NOSTOP set on msg[n]
* and I2C_M_NOSTART *not* set on msg[n+1]. See the following table:
*
* msg[n].flags msg[n+1].flags Behavior
* ------------ --------------- -----------------------------------------
* 0 0 Two normal, separate messages with STOP
* on msg[n] then START on msg[n+1]
* 0* I2C_M_NOSTART Continuation of the same transfer (must
* be the same direction). See NOTE below.
* NO_STOP 0 No STOP on msg[n]; repeated START on
* msg[n+1].
*
* * NOTE: NO_STOP is implied in this case and may or not be explicitly
* included in the msg[n] flags
*/
#define I2C_M_READ 0x0001 /* Read data, from slave to master */
#define I2C_M_TEN 0x0002 /* Ten bit address */
#define I2C_M_NOSTOP 0x0040 /* Message should not end with a STOP */
#define I2C_M_NOSTART 0x0080 /* Message should not begin with a START */
/* I2c bus speed */
#define I2C_SPEED_STANDARD 100000 /* Standard speed (100Khz) */
#define I2C_SPEED_FAST 400000 /* Fast speed (400Khz) */
#define I2C_SPEED_FAST_PLUS 1000000 /* Fast+ speed ( 1Mhz) */
#define I2C_SPEED_HIGH 3400000 /* High speed (3.4Mhz) */
/* I2C Character Driver IOCTL Commands **************************************/
/* The I2C driver is intended to support application testing of the I2C bus.
* The I2C driver simply wraps an instance of struct i2c_dev_s and then
* provides the following IOCTL commands to access each method of the I2c
* interface.
*/
/* Command: I2CIOC_TRANSFER
* Description: Perform an I2C transfer
* Argument: A reference to an instance of struct i2c_transfer_s.
* Dependencies: CONFIG_I2C_DRIVER
*/
#define I2CIOC_TRANSFER _I2CIOC(0x0001)
/* Command: I2CIOC_RESET
* Description: Perform an I2C bus reset in an attempt to break loose stuck
* I2C devices.
* Argument: None
* Dependencies: CONFIG_I2C_DRIVER && CONFIG_I2C_RESET
*/
#define I2CIOC_RESET _I2CIOC(0x0002)
/* Access macros ************************************************************/
/****************************************************************************
* Name: I2C_TRANSFER
*
* Description:
* Perform a sequence of I2C transfers, each transfer is started with a
* START and the final transfer is completed with a STOP. Each sequence
* will be an 'atomic' operation in the sense that any other I2C actions
* will be serialized and pend until this sequence of transfers completes.
*
* Input Parameters:
* dev - Device-specific state data
* msgs - A pointer to a set of message descriptors
* count - The number of transfers to perform
*
* Returned Value:
* Zero (OK) or positive on success; a negated errno value on failure.
*
* Note : some implementations of this interface return the number of
* transfers completed, but others return OK on success.
*
****************************************************************************/
#define I2C_TRANSFER(d,m,c) ((d)->ops->transfer(d,m,c))
/****************************************************************************
* Name: I2C_RESET
*
* Description:
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
* Input Parameters:
* dev - Device-specific state data
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
#ifdef CONFIG_I2C_RESET
# define I2C_RESET(d) ((d)->ops->reset(d))
#endif
/****************************************************************************
* Name: I2C_SETUP
*
* Description:
* I2c master initialize.
*
* Input Parameters:
* dev - Device-specific state data
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
#define I2C_SETUP(d) ((d)->ops->setup(d))
/****************************************************************************
* Name: I2C_SHUTDOWN
*
* Description:
* I2c master uninitialize.
*
* Input Parameters:
* dev - Device-specific state data
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
#define I2C_SHUTDOWN(d) ((d)->ops->shutdown(d))
/****************************************************************************
* Public Types
****************************************************************************/
/* The I2C lower half driver interface */
struct i2c_master_s;
struct i2c_msg_s;
struct i2c_ops_s
{
CODE int (*transfer)(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count);
#ifdef CONFIG_I2C_RESET
CODE int (*reset)(FAR struct i2c_master_s *dev);
#endif
CODE int (*setup)(FAR struct i2c_master_s *dev);
CODE int (*shutdown)(FAR struct i2c_master_s *dev);
};
/* 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
* be transferred together to form an arbitrary sequence of write/read
* transfer to an I2C slave device.
*/
struct i2c_msg_s
{
uint32_t frequency; /* I2C frequency */
uint16_t addr; /* Slave address (7- or 10-bit) */
uint16_t flags; /* See I2C_M_* definitions */
FAR uint8_t *buffer; /* Buffer to be transferred */
ssize_t length; /* Length of the buffer in bytes */
};
/* I2C private data. This structure only defines the initial fields of the
* structure visible to the I2C client. The specific implementation may
* add additional, device specific fields after the vtable.
*/
struct i2c_master_s
{
FAR const struct i2c_ops_s *ops; /* I2C vtable */
};
/* This structure is used to communicate with the I2C character driver in
* order to perform IOCTL transfers.
*/
struct i2c_transfer_s
{
FAR struct i2c_msg_s *msgv; /* Array of I2C messages for the transfer */
size_t msgc; /* Number of messages in the array. */
};
/****************************************************************************
* Public Functions Definitions
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Name: i2c_register
*
* Description:
* Create and register the I2C character driver.
*
* The I2C character driver is a simple character driver that supports I2C
* transfers. The intent of this driver is to support I2C testing. It is
* not suitable for use in any real driver application.
*
* Input Parameters:
* i2c - An instance of the lower half I2C driver
* bus - The I2C bus number. This will be used as the I2C device minor
* number. The I2C character device will be registered as /dev/i2cN
* where N is the minor number
*
* Returned Value:
* OK if the driver was successfully register; A negated errno value is
* returned on any failure.
*
****************************************************************************/
#ifdef CONFIG_I2C_DRIVER
int i2c_register(FAR struct i2c_master_s *i2c, int bus);
#endif
/****************************************************************************
* Name: i2c_writeread
*
* Description:
* Send a block of data on I2C followed by restarted read access. This
* provides a convenient wrapper to the transfer function.
*
* Input Parameters:
* dev - Device-specific state data
* config - Described the I2C configuration
* wbuffer - A pointer to the read-only buffer of data to be written to
* device
* wbuflen - The number of bytes to send from the buffer
* rbuffer - A pointer to a buffer of data to receive the data from the
* device
* rbuflen - The requested number of bytes to be read
*
* Returned Value:
* 0: success, <0: A negated errno
*
****************************************************************************/
int i2c_writeread(FAR struct i2c_master_s *dev,
FAR const struct i2c_config_s *config,
FAR const uint8_t *wbuffer, int wbuflen,
FAR uint8_t *rbuffer, int rbuflen);
/****************************************************************************
* Name: i2c_write
*
* Description:
* Send a block of data on I2C. Each write operation will be an 'atomic'
* operation in the sense that any other I2C actions will be serialized
* and pend until this write completes.
*
* Input Parameters:
* dev - Device-specific state data
* config - Described the I2C configuration
* buffer - A pointer to the read-only buffer of data to be written to
* device
* buflen - The number of bytes to send from the buffer
*
* Returned Value:
* 0: success, <0: A negated errno
*
****************************************************************************/
int i2c_write(FAR struct i2c_master_s *dev,
FAR const struct i2c_config_s *config,
FAR const uint8_t *buffer, int buflen);
/****************************************************************************
* Name: i2c_read
*
* Description:
* Receive a block of data from I2C. Each read operation will be an
* 'atomic' operation in the sense that any other I2C actions will be
* serialized and pend until this read completes.
*
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to a buffer of data to receive the data from the
* device
* buflen - The requested number of bytes to be read
*
* Returned Value:
* 0: success, <0: A negated errno
*
****************************************************************************/
int i2c_read(FAR struct i2c_master_s *dev,
FAR const struct i2c_config_s *config,
FAR uint8_t *buffer, int buflen);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __INCLUDE_NUTTX_I2C_I2C_MASTER_H */