Added I2C Slave to RP2040

Added length to I2C slave callback.
This commit is contained in:
curuvar
2022-07-15 11:28:11 -04:00
committed by Xiang Xiao
parent 2428438037
commit d69d9eb0c9
6 changed files with 847 additions and 20 deletions
+114
View File
@@ -0,0 +1,114 @@
/****************************************************************************
* arch/arm/include/rp2040/i2c_slave.h
*
* 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 __ARCH_ARM_INCLUDE_RP2040_I2C_SLAVE_H
#define __ARCH_ARM_INCLUDE_RP2040_I2C_SLAVE_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/i2c/i2c_slave.h>
#ifndef __ASSEMBLY__
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/* There is no driver for I2C slave operations. To create an I2C slave,
* include this file (as: <arch/chip/i2c_slave.h>) and use either
* rp2040_i2c0_slave_initialize or rp2040_i2c1_slave_initialize to
* initialize the I2C for slave operations.
*/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: rp2040_i2c0_slave_initialize
*
* Description:
* Initialize I2C controller zero for slave operation, and return a pointer
* to the instance of struct i2c_slave_s. This function should only be
* called once of a give controller.
*
* Note: the same port cannot be initalized as both master and slave.
*
* Input Parameters:
* rx_buffer - Buffer for data transmitted to us by an I2C master.
* rx_buffer_len - Length of rx_buffer.
* callback - Callback function called when messages are received.
*
* Returned Value:
* Valid I2C device structure reference on success; a NULL on failure
*
****************************************************************************/
#ifdef CONFIG_RP2040_I2C0_SLAVE
struct i2c_slave_s *rp2040_i2c0_slave_initialize
(uint8_t *rx_buffer,
size_t rx_buffer_len,
i2c_slave_callback_t *callback);
#endif
/****************************************************************************
* Name: rp2040_i2c1_slave_initialize
*
* Description:
* Initialize I2C controller zero for slave operation, and return a pointer
* to the instance of struct i2c_slave_s. This function should only be
* called once of a give controller.
*
* Note: the same port cannot be initalized as both master and slave.
*
* Input Parameters:
* rx_buffer - Buffer for data transmitted to us by an I2C master.
* rx_buffer_len - Length of rx_buffer.
* callback - Callback function called when messages are received.
*
* Returned Value:
* Valid I2C device structure reference on success; a NULL on failure
*
****************************************************************************/
#ifdef CONFIG_RP2040_I2C1_SLAVE
struct i2c_slave_s *rp2040_i2c1_slave_initialize
(uint8_t *rx_buffer,
size_t rx_buffer_len,
i2c_slave_callback_t *callback);
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_INCLUDE_RP2040_I2C_SLAVE_H */
+85 -1
View File
@@ -118,8 +118,12 @@ config RP2040_SPI_DRIVER
endif
config RP2040_I2C
bool "I2C"
bool "I2C Master"
select I2C
---help---
Build in support for I2C master mode.
Note: Do not configure the same port as both master and slave.
if RP2040_I2C
@@ -141,6 +145,86 @@ config RP2040_I2C_DRIVER
endif
config RP2040_I2C_SLAVE
bool "I2C Slave"
select I2C_SLAVE
---help---
Build in support for I2C slave mode.
Note: Do not configure the same port as both master and slave.
if RP2040_I2C_SLAVE
config RP2040_I2C0_SLAVE
bool "I2C0"
if RP2040_I2C0_SLAVE
config RP2040_I2C0_SLAVE_SDA
int "GPIO pin number for SDA (data) line"
default 4
---help---
This pin must be one of: 0, 4, 8, 12, 16, 20, 24, or 28
config RP2040_I2C0_SLAVE_SCL
int "GPIO pin number for SCL (clock) line"
default 5
---help---
This pin must be one of: 1, 5, 9, 13, 17, 21, 25, or 29
config RP2040_I2C0_SLAVE_ADDRESS
int "Slave Address (in decimal)"
default 42
---help---
This is the default address of this device on the I2C bus.
It should be the canonical address (not the shifted address)
in the range 8-119 for 7-bit mode and in the range 0-1023
for 10-bit mode.
config RP2040_I2C0_SLAVE_10BIT
bool "Enable 10-bit slave address"
default n
---help---
Set to enable 10-bit mode addressing.
endif
config RP2040_I2C1_SLAVE
bool "I2C1"
if RP2040_I2C1_SLAVE
config RP2040_I2C1_SLAVE_SDA
int "GPIO pin number for SDA (data) line"
default 6
---help---
This pin must be one of: 2, 6, 10, 14, 18, 22, or 26
config RP2040_I2C1_SLAVE_SCL
int "GPIO pin number for SCL (clock) line"
default 7
---help---
This pin must be one of: 3, 7, 11, 15, 19, 23, or 27
config RP2040_I2C1_SLAVE_ADDRESS
int "Slave Address (in decimal)"
default 42
---help---
This is the default address of this device on the I2C bus.
It should be the canonical address (not the shifted address)
in the range 8-119 for 7-bit mode and in the range 0-1023
for 10-bit mode.
config RP2040_I2C1_SLAVE_10BIT
bool "Enable 10-bit slave address"
default n
---help---
Set to enable 10-bit mode addressing.
endif
endif
menuconfig RP2040_PWM
bool "PWM"
select PWM
+4
View File
@@ -57,6 +57,10 @@ ifeq ($(CONFIG_RP2040_I2C),y)
CHIP_CSRCS += rp2040_i2c.c
endif
ifeq ($(CONFIG_RP2040_I2C_SLAVE),y)
CHIP_CSRCS += rp2040_i2c_slave.c
endif
ifeq ($(CONFIG_RP2040_I2S),y)
CHIP_CSRCS += rp2040_i2s.c
CHIP_CSRCS += rp2040_i2s_pio.c
File diff suppressed because it is too large Load Diff
+7 -5
View File
@@ -102,8 +102,8 @@ struct s32k1xx_lpi2c_slave_priv_s
int write_buflen; /* Write buffer size */
int write_bufindex; /* Write buffer index */
int (*callback)(void *arg); /* Callback function when data has been received */
void *callback_arg; /* Argument of callback function */
i2c_slave_callback_t *callback; /* Callback function when data has been received */
void *callback_arg; /* Argument of callback function */
int refs; /* Reference count */
};
@@ -137,7 +137,7 @@ static int s32k1xx_lpi2c_write(struct i2c_slave_s *dev,
static int s32k1xx_lpi2c_read(struct i2c_slave_s *dev,
uint8_t *buffer, int buflen);
static int s32k1xx_lpi2c_registercallback(struct i2c_slave_s *dev,
int (*callback)(void *arg),
i2c_slave_callback_t *callback,
void *arg);
/****************************************************************************
@@ -427,7 +427,8 @@ static int s32k1xx_lpi2c_slave_isr_process(
if ((priv->read_bufindex > 0) && (priv->callback != NULL))
{
priv->callback(priv->callback_arg);
priv->callback(priv->callback_arg, priv->read_bufindex);
priv->read_bufindex = 0;
}
}
@@ -793,7 +794,8 @@ static int s32k1xx_lpi2c_read(struct i2c_slave_s *dev,
****************************************************************************/
static int s32k1xx_lpi2c_registercallback(struct i2c_slave_s *dev,
int (*callback)(void *arg), void *arg)
i2c_slave_callback_t *callback,
void *arg)
{
struct s32k1xx_lpi2c_slave_priv_s *priv;
irqstate_t flags;
+48 -14
View File
@@ -21,6 +21,30 @@
#ifndef __INCLUDE_NUTTX_I2C_I2C_SLAVE_H
#define __INCLUDE_NUTTX_I2C_I2C_SLAVE_H
/****************************************************************************
* Using I2C slave mode:
*
* After I2C slave mode is initialized by calling an architecture defined
* initialization function, the hardware will monitor the I2C bus waiting
* for messages with this device's address.
*
* Before I2C data can be received, the I2CS_READ macro should be called
* to register a buffer where the received data will be stored, and a
* callback function should be registered with either (not both) the
* I2CS_REGISTERCALLBACK macro. When the data is received (via an I2C
* write message) it will be written to the supplied buffer and the callback
* function will be called.
*
* The I2C_WRITE macro is used to register a buffer with data to be
* sent when the master next issues an I2C read message. There is no
* specific notification that the data has been read, but since usual
* I2C operation is for the master to transmit a message indicating
* the desired data before reading, the slave should register the
* return data in the callback function and preserve it until the next
* callback it received.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
@@ -90,10 +114,8 @@
* Name: I2CS_WRITE
*
* Description:
* Send a block of data on I2C using the previously selected I2C
* frequency and slave address. Each write operational will be an 'atomic'
* operation in the sense that any other I2C actions will be serialized
* and pend until this write completes. Required.
* Send a block of data on I2C to the next master to issue an I2C read
* transaction to this slave. Required.
*
* Input Parameters:
* dev - Device-specific state data
@@ -112,10 +134,10 @@
* Name: I2CS_READ
*
* Description:
* Receive a block of data from I2C using the previously selected I2C
* frequency and slave address. Each read operational will be an 'atomic'
* operation in the sense that any other I2C actions will be serialized
* and pend until this read completes. Required.
* Register a buffer to receive the data from the next I2C write
* transaction addressed to this slave. The callback function supplied
* by the I2CS_REGISTERCALLBACK macro will be called once the buffer
* has been filled. Required.
*
* Input Parameters:
* dev - Device-specific state data
@@ -152,18 +174,30 @@
* Public Types
****************************************************************************/
/* The callback function */
typedef int (i2c_slave_callback_t)(void *arg, size_t rx_len);
/* The I2C vtable */
struct i2c_slave_s;
struct i2c_slaveops_s
{
int (*setownaddress)(FAR struct i2c_slave_s *dev, int addr, int nbits);
int (*write)(FAR struct i2c_slave_s *dev, FAR const uint8_t *buffer,
int buflen);
int (*read)(FAR struct i2c_slave_s *dev, FAR uint8_t *buffer,
int buflen);
int (*setownaddress)(FAR struct i2c_slave_s *dev,
int addr,
int nbits);
int (*write)(FAR struct i2c_slave_s *dev,
FAR const uint8_t *buffer,
int buflen);
int (*read)(FAR struct i2c_slave_s *dev,
FAR uint8_t *buffer,
int buflen);
int (*registercallback)(FAR struct i2c_slave_s *dev,
int (*callback)(FAR void *arg), FAR void *arg);
i2c_slave_callback_t *callback,
FAR void *arg);
};
/* I2C private data. This structure only defines the initial fields of the