mirror of
https://github.com/apache/nuttx.git
synced 2026-09-24 00:42:03 +08:00
arch/arm/src/stm32/stm32_i2cslave_v2.c: add STM32 I2C Slave support for the v2 ip core
This commit adds the lowerhalf driver support for the I2C Slave. While not currently ideal, it is compatible with the upperhalf i2c slave driver. A workqueue can be used to delegate the isr work to the upperhalf driver. But keep in mind wq introduces a lot of delay and in certain scenarios, it is better to write your own better upperhalf driver. Signed-off-by: Stepan Pressl <pressl.stepan@gmail.com>
This commit is contained in:
committed by
Xiang Xiao
parent
3d37e85b13
commit
55bef681e1
@@ -2,7 +2,7 @@
|
||||
I2C Device Drivers
|
||||
==================
|
||||
|
||||
- ``include/nuttx/i2c/i2c_master.h`` and ``include/nuttx/i2c/i2c_slave.h``.
|
||||
- ``include/nuttx/i2c/i2c_master.h``
|
||||
All structures and APIs needed to work with I2C drivers are provided in
|
||||
this header file.
|
||||
|
||||
@@ -22,10 +22,59 @@ I2C Device Drivers
|
||||
- **Examples**: ``arch/z80/src/ez80/ez80_i2c.c``,
|
||||
``arch/z80/src/z8/z8_i2c.c``, etc.
|
||||
|
||||
- ``struct i2c_slaveops_s``. Each I2C slave device driver must implement
|
||||
|
||||
========================
|
||||
I2C Slave Device Drivers
|
||||
========================
|
||||
|
||||
- ``include/nuttx/i2c/i2c_slave.h``
|
||||
Declaration of all macros and ops and ``int i2c_slave_register``,
|
||||
used to bind the lowerhalf driver to the upper one and register an
|
||||
I2C slave device.
|
||||
|
||||
- **Binding I2C Slave Drivers**. Use ``int i2c_slave_register`` in your BSP
|
||||
to register your slave device. Before that, you need to get the instance
|
||||
of ``struct i2c_slave_s`` from the hardware-specific I2C Slave driver.
|
||||
|
||||
- **Using I2C Slave in your Application**. I2C slave drivers are normally directly
|
||||
accessed by user code, We can read and write to device nodes using posix
|
||||
interfaces. The device is registered as ``/dev/i2cslv%d``, where ``%d``
|
||||
is a number provided in the BSP initialization phase.
|
||||
|
||||
- **BSP initialization example (STM32 I2C Slave)**:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int stm32_i2cs_setup(void)
|
||||
{
|
||||
i2cs = stm32_i2cbus_slaveinitialize(1);
|
||||
if (i2cs != NULL)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
return i2c_slave_register(i2cs, 1, 0x01, 7);
|
||||
}
|
||||
|
||||
I2C Slave Driver API
|
||||
--------------------
|
||||
|
||||
.. c:function:: int i2c_slave_register(FAR struct i2c_slave_s *dev, int bus, int addr, int nbit);
|
||||
|
||||
Bind the lowerhalf ``dev`` driver to the upperhalf driver and register
|
||||
a device. The name of the device is ``/dev/i2cslv%d``, where ``%d`` is
|
||||
bus. The address the I2C slave is specified in ``addr``.
|
||||
``nbit`` is either 7 or 10 and it specifies the address format.
|
||||
|
||||
|
||||
- ``struct i2c_slaveops_s``. Each I2C slave lowerhalf driver must implement
|
||||
an instance of ``struct i2c_slaveops_s``. That structure defines a call
|
||||
table with the following methods:
|
||||
|
||||
- **Binding I2C Slave Drivers**. I2C slave drivers are normally directly
|
||||
accessed by user code, We can read and write to device nodes using posix
|
||||
interfaces.
|
||||
- ``setownaddress``: the address the slave responds to,
|
||||
- ``write``: sets the tx buffer pointer,
|
||||
- ``read``: sets the rx buffer pointer,
|
||||
- ``registercallback``: registers the callback function which should
|
||||
be called from a service routine. Signals the received or fully transferred
|
||||
I2C packet.
|
||||
- ``setup``: initializes the peripheral,
|
||||
- ``shutdown``: shutdowns the peripheral.
|
||||
|
||||
@@ -82,6 +82,9 @@ if(CONFIG_STM32_HAVE_IP_I2C_V1)
|
||||
endif()
|
||||
elseif(CONFIG_STM32_HAVE_IP_I2C_V2)
|
||||
list(APPEND SRCS stm32_i2c_v2.c)
|
||||
if(CONFIG_STM32_I2C_SLAVE)
|
||||
list(APPEND SRCS stm32_i2cslave_v2.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_USBDEV)
|
||||
|
||||
@@ -3024,6 +3024,24 @@ config STM32_I2C3
|
||||
depends on STM32_HAVE_I2C3
|
||||
select STM32_I2C
|
||||
|
||||
config STM32_I2C1_SLAVE
|
||||
bool "I2C1 Slave"
|
||||
default n
|
||||
depends on !STM32_I2C1 && I2C_SLAVE
|
||||
select STM32_I2C_SLAVE
|
||||
|
||||
config STM32_I2C2_SLAVE
|
||||
bool "I2C2 Slave"
|
||||
default n
|
||||
depends on STM32_HAVE_I2C2 && !STM32_I2C2 && I2C_SLAVE
|
||||
select STM32_I2C_SLAVE
|
||||
|
||||
config STM32_I2C3_SLAVE
|
||||
bool "I2C3 Slave"
|
||||
default n
|
||||
depends on STM32_HAVE_I2C3 && !STM32_I2C3 && I2C_SLAVE
|
||||
select STM32_I2C_SLAVE
|
||||
|
||||
config STM32_LPTIM1
|
||||
bool "LPTIM1"
|
||||
default n
|
||||
@@ -3421,6 +3439,10 @@ config STM32_I2C
|
||||
bool
|
||||
default n
|
||||
|
||||
config STM32_I2C_SLAVE
|
||||
bool
|
||||
default n
|
||||
|
||||
config STM32_CAN
|
||||
bool
|
||||
default n
|
||||
@@ -10720,6 +10742,31 @@ config STM32_I2C_DMA
|
||||
|
||||
endmenu
|
||||
|
||||
menu "I2C Slave Configuration"
|
||||
depends on STM32_I2C_SLAVE
|
||||
|
||||
config STM32_I2C_SLAVE_DEFAULT_TX
|
||||
hex "Default TX byte to be sent when the TX buffer is empty"
|
||||
default 0xFF
|
||||
|
||||
config STM32_I2C_SLAVE_USEWQ
|
||||
bool "Use work queue to delegate the isr completion status"
|
||||
default n
|
||||
---help---
|
||||
With the current upperhalf I2C slave driver implementation, the user
|
||||
should delegate the callback completion status using a work queue.
|
||||
However, work queues introduce a delay, so in certain scenarios
|
||||
it is better to use a custom driver without using a work queue.
|
||||
|
||||
config STM32_I2C_SLAVE_RETRANSFER
|
||||
bool "The frame is retransferred when stop is issued beforehand"
|
||||
default n
|
||||
---help---
|
||||
If stop is issued before the whole frame is transferred,
|
||||
the tx pointer is reset to 0.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "SDIO Configuration"
|
||||
depends on STM32_SDIO
|
||||
|
||||
|
||||
@@ -65,6 +65,9 @@ CHIP_CSRCS += stm32_i2c.c
|
||||
endif
|
||||
else ifeq ($(CONFIG_STM32_HAVE_IP_I2C_V2),y)
|
||||
CHIP_CSRCS += stm32_i2c_v2.c
|
||||
ifeq ($(CONFIG_STM32_I2C_SLAVE),y)
|
||||
CHIP_CSRCS += stm32_i2cslave_v2.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USBDEV),y)
|
||||
|
||||
@@ -88,4 +88,38 @@ struct i2c_master_s *stm32_i2cbus_initialize(int port);
|
||||
|
||||
int stm32_i2cbus_uninitialize(struct i2c_master_s *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_i2cbus_slaveinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the selected I2C port as a slave. Return an unique
|
||||
* instance of struct i2c_slave_s.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Port number (for hardware that has multiple I2C interfaces)
|
||||
*
|
||||
* Returned Value:
|
||||
* Valid I2C device structure reference on success; a NULL on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct i2c_slave_s *stm32_i2cbus_slaveinitialize(int port);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_i2cbus_uninitialize
|
||||
*
|
||||
* Description:
|
||||
* De-initialize the selected I2C port, and power down the device.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Device structure as returned by the stm32_i2cbus_initialize()
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success, ERROR when internal reference count mismatch or dev
|
||||
* points to invalid hardware device.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int stm32_i2cbus_uninitialize(struct i2c_master_s *dev);
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_STM32_STM32_I2C_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user