1.为提速软件模拟效率,引入快速Pin,注意此接口仅为模拟接口使用,请不要随意使用此接口,严禁跳过设备框架在应用层使用此功能(如果不遵守,将破坏软件架构,导致解耦失效)。

This commit is contained in:
MacRsh
2024-01-31 22:49:25 +08:00
parent 9985cd07f4
commit b218bbdbd2
4 changed files with 159 additions and 94 deletions

108
device/fast_pin.c Normal file
View File

@@ -0,0 +1,108 @@
/*
* @copyright (c) 2023-2024, MR Development Team
*
* @license SPDX-License-Identifier: Apache-2.0
*
* @date 2024-11-08 MacRsh First version
*/
#include "include/device/mr_pin.h"
#ifdef MR_USING_PIN
/**
* @addtogroup PIN
* @{
*/
/**
* @brief This function get the fast pin device pointer.
*
* @param magic The magic number.
*
* @return The fast pin device pointer.
*
* @note Please do not appear the code in this file in the application layer.
*/
MR_INLINE struct mr_dev **_fast_pin_dev_get(uint32_t magic)
{
static struct mr_dev *dev = MR_NULL;
/* If that doesn't stop you, feel free to use it */
if (magic == MR_MAGIC_NUMBER)
{
return &dev;
}
return MR_NULL;
}
/**
* @brief This function initialize the fast pin device.
*
* @param dev The pin device.
*
* @note Please do not appear the code in this file in the application layer.
*/
void _mr_fast_pin_init(struct mr_dev *dev)
{
if (_fast_pin_dev_get(dev->magic) != MR_NULL)
{
*_fast_pin_dev_get(dev->magic) = dev;
}
}
/**
* @brief This function set the pin mode.
*
* @param number The pin number.
* @param mode The pin mode.
*
* @return 0 on success, otherwise an error code.
*
* @note Please do not appear the code in this file in the application layer.
*/
int _mr_fast_pin_mode(int number, int mode)
{
struct mr_dev *dev = *_fast_pin_dev_get(MR_MAGIC_NUMBER);
if (dev == MR_NULL)
{
return MR_ENOTFOUND;
}
return ((struct mr_pin_ops *)dev->drv->ops)->configure((struct mr_pin *)dev, number, mode);
}
/**
* @brief This function read the pin value.
*
* @param number The pin number.
*
* @return The pin value.
*
* @note Please do not appear the code in this file in the application layer.
*/
uint8_t _mr_fast_pin_read(int number)
{
struct mr_dev *dev = *_fast_pin_dev_get(MR_MAGIC_NUMBER);
return ((struct mr_pin_ops *)dev->drv->ops)->read((struct mr_pin *)dev, number);
}
/**
* @brief This function write the pin value.
*
* @param number The pin number.
* @param value The pin value.
*
* @note Please do not appear the code in this file in the application layer.
*/
void _mr_fast_pin_write(int number, int value)
{
struct mr_dev *dev = *_fast_pin_dev_get(MR_MAGIC_NUMBER);
((struct mr_pin_ops *)dev->drv->ops)->write((struct mr_pin *)dev, number, value);
}
/** @} */
#endif /* MR_USING_PIN */

View File

@@ -12,8 +12,11 @@
#ifdef MR_USING_PIN
#include "include/device/mr_pin.h"
int _mr_fast_pin_mode(int number, int mode);
uint8_t _mr_fast_pin_read(int number);
void _mr_fast_pin_write(int number, int value);
#else
#warning "Please define MR_USING_PIN. Otherwise Soft-I2C will not work."
#error "Please define MR_USING_PIN. Otherwise Soft-I2C will not work."
#endif /* MR_USING_PIN */
#define SOFT_I2C_LOW 0
@@ -21,23 +24,17 @@
MR_INLINE void soft_i2c_scl_set(struct mr_soft_i2c_bus *soft_i2c_bus, uint8_t value)
{
mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_NUMBER, &soft_i2c_bus->scl_pin);
mr_dev_write(soft_i2c_bus->desc, &value, sizeof(value));
_mr_fast_pin_write(soft_i2c_bus->scl_pin, value);
}
MR_INLINE void soft_i2c_bus_sda_set(struct mr_soft_i2c_bus *soft_i2c_bus, uint8_t value)
{
mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_NUMBER, &soft_i2c_bus->sda_pin);
mr_dev_write(soft_i2c_bus->desc, &value, sizeof(value));
_mr_fast_pin_write(soft_i2c_bus->sda_pin, value);
}
MR_INLINE uint8_t soft_i2c_sda_get(struct mr_soft_i2c_bus *soft_i2c_bus)
{
uint8_t value;
mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_NUMBER, &soft_i2c_bus->sda_pin);
mr_dev_read(soft_i2c_bus->desc, &value, sizeof(value));
return value;
return (uint8_t)_mr_fast_pin_read(soft_i2c_bus->sda_pin);
}
static void soft_i2c_bus_wait_ack(struct mr_i2c_bus *i2c_bus)
@@ -80,6 +77,7 @@ static int mr_soft_i2c_bus_configure(struct mr_i2c_bus *i2c_bus, struct mr_i2c_c
{
struct mr_soft_i2c_bus *soft_i2c_bus = (struct mr_soft_i2c_bus *)i2c_bus;
int state = (config->baud_rate != 0) ? MR_ENABLE : MR_DISABLE;
int mode = (state == MR_ENABLE) ? MR_PIN_MODE_OUTPUT_OD : MR_PIN_MODE_NONE;
if (state == MR_ENABLE)
{
@@ -91,58 +89,18 @@ static int mr_soft_i2c_bus_configure(struct mr_i2c_bus *i2c_bus, struct mr_i2c_c
/* Calculate the delay time */
soft_i2c_bus->delay = (1000000 / config->baud_rate) / 2;
}
/* Configure SCL and SDA */
if (soft_i2c_bus->desc < 0)
{
soft_i2c_bus->desc = mr_dev_open("pin", MR_OFLAG_RDWR);
if (soft_i2c_bus->desc < 0)
{
return soft_i2c_bus->desc;
}
/* Configure SCL pin */
mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_NUMBER, &soft_i2c_bus->scl_pin);
int ret = (int)mr_dev_ioctl(soft_i2c_bus->desc,
MR_CTL_PIN_SET_MODE,
MR_MAKE_LOCAL(int, MR_PIN_MODE_OUTPUT_OD));
if (ret < 0)
{
return ret;
}
/* Configure SDA pin */
mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_NUMBER, &soft_i2c_bus->sda_pin);
ret = (int)mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_MODE, MR_MAKE_LOCAL(int, MR_PIN_MODE_OUTPUT_OD));
if (ret < 0)
{
return ret;
}
}
} else
/* Configure SCL and SDA */
int ret = _mr_fast_pin_mode(soft_i2c_bus->scl_pin, mode);
if (ret < 0)
{
/* Reconfigure SCL and SDA */
if (soft_i2c_bus->desc >= 0)
{
/* Reconfigure SCL pin */
mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_NUMBER, &soft_i2c_bus->scl_pin);
int ret = (int)mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_MODE, MR_MAKE_LOCAL(int, MR_PIN_MODE_NONE));
if (ret < 0)
{
return ret;
}
/* Reconfigure SDA pin */
mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_NUMBER, &soft_i2c_bus->sda_pin);
ret = (int)mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_MODE, MR_MAKE_LOCAL(int, MR_PIN_MODE_NONE));
if (ret < 0)
{
return ret;
}
mr_dev_close(soft_i2c_bus->desc);
soft_i2c_bus->desc = -1;
}
return ret;
}
ret = _mr_fast_pin_mode(soft_i2c_bus->sda_pin, mode);
if (ret < 0)
{
return ret;
}
return MR_EOK;
}
@@ -240,13 +198,13 @@ static void mr_soft_i2c_bus_write(struct mr_i2c_bus *i2c_bus, uint8_t data)
* @brief This function registers a soft-i2c-bus.
*
* @param soft_i2c_bus The soft-i2c-bus.
* @param name The name of the soft-i2c-bus.
* @param path The path of the soft-i2c-bus.
* @param scl_pin The scl pin of the soft-i2c-bus.
* @param sda_pin The sda pin of the soft-i2c-bus.
*
* @return MR_EOK on success, otherwise an error code.
* @return 0 on success, otherwise an error code.
*/
int mr_soft_i2c_bus_register(struct mr_soft_i2c_bus *soft_i2c_bus, const char *name, int scl_pin, int sda_pin)
int mr_soft_i2c_bus_register(struct mr_soft_i2c_bus *soft_i2c_bus, const char *path, int scl_pin, int sda_pin)
{
static struct mr_i2c_bus_ops ops =
{
@@ -259,22 +217,20 @@ int mr_soft_i2c_bus_register(struct mr_soft_i2c_bus *soft_i2c_bus, const char *n
};
static struct mr_drv drv =
{
Mr_Drv_Type_I2C,
&ops,
MR_NULL
};
MR_ASSERT(soft_i2c_bus != MR_NULL);
MR_ASSERT(name != MR_NULL);
MR_ASSERT(path != MR_NULL);
/* Initialize the fields */
soft_i2c_bus->delay = 0;
soft_i2c_bus->scl_pin = scl_pin;
soft_i2c_bus->sda_pin = sda_pin;
soft_i2c_bus->desc = -1;
/* Register the soft-i2c-bus */
return mr_i2c_bus_register(&soft_i2c_bus->i2c_bus, name, &drv);
return mr_i2c_bus_register(&soft_i2c_bus->i2c_bus, path, &drv);
}
#endif /* defined(MR_USING_I2C) && defined(MR_USING_SOFT_I2C) */

View File

@@ -19,6 +19,11 @@ extern "C" {
#include "include/device/mr_i2c.h"
/**
* @addtogroup I2C
* @{
*/
/**
* @brief Soft-I2C bus structure.
*/
@@ -29,14 +34,9 @@ struct mr_soft_i2c_bus
uint32_t delay; /**< Speed delay */
int scl_pin; /**< SCL pin */
int sda_pin; /**< SDA pin */
int desc; /**< SCL-SDA descriptor */
};
/**
* @addtogroup Soft-I2C.
* @{
*/
int mr_soft_i2c_bus_register(struct mr_soft_i2c_bus *soft_i2c_bus, const char *name, int scl_pin, int sda_pin);
int mr_soft_i2c_bus_register(struct mr_soft_i2c_bus *soft_i2c_bus, const char *path, int scl_pin, int sda_pin);
/** @} */
#endif /* defined(MR_USING_I2C) && defined(MR_USING_SOFT_I2C) */

View File

@@ -17,6 +17,11 @@ extern "C" {
#ifdef MR_USING_SPI
/**
* @addtogroup SPI
* @{
*/
/**
* @brief SPI host/slave.
*/
@@ -90,18 +95,18 @@ struct mr_spi_transfer
/**
* @brief SPI control command.
*/
#define MR_CTL_SPI_SET_CONFIG MR_CTL_SET_CONFIG /**< Set configuration */
#define MR_CTL_SPI_SET_REG MR_CTL_SET_OFFSET /**< Set register */
#define MR_CTL_SPI_SET_RD_BUFSZ MR_CTL_SET_RD_BUFSZ /**< Set read buffer size */
#define MR_CTL_SPI_CLR_RD_BUF MR_CTL_CLR_RD_BUF /**< Clear read buffer */
#define MR_CTL_SPI_SET_RD_CALL MR_CTL_SET_RD_CALL /**< Set read callback */
#define MR_CTL_SPI_TRANSFER (0x01) /**< Transfer */
#define MR_IOC_SPI_SET_CONFIG MR_IOC_SCFG /**< Set configuration */
#define MR_IOC_SPI_SET_REG MR_IOC_SPOS /**< Set register */
#define MR_IOC_SPI_SET_RD_BUFSZ MR_IOC_SRBSZ /**< Set read buffer size */
#define MR_IOC_SPI_CLR_RD_BUF MR_IOC_CRBD /**< Clear read buffer */
#define MR_IOC_SPI_SET_RD_CALL MR_IOC_SRCB /**< Set read callback */
#define MR_IOC_SPI_TRANSFER (0x01) /**< Transfer */
#define MR_CTL_SPI_GET_CONFIG MR_CTL_GET_CONFIG /**< Get configuration */
#define MR_CTL_SPI_GET_REG MR_CTL_GET_OFFSET /**< Get register */
#define MR_CTL_SPI_GET_RD_BUFSZ MR_CTL_GET_RD_BUFSZ /**< Get read buffer size */
#define MR_CTL_SPI_GET_RD_DATASZ MR_CTL_GET_RD_DATASZ /**< Get read data size */
#define MR_CTL_SPI_GET_RD_CALL MR_CTL_GET_RD_CALL /**< Get read callback */
#define MR_IOC_SPI_GET_CONFIG MR_IOC_GCFG /**< Get configuration */
#define MR_IOC_SPI_GET_REG MR_IOC_GPOS /**< Get register */
#define MR_IOC_SPI_GET_RD_BUFSZ MR_IOC_GRBSZ /**< Get read buffer size */
#define MR_IOC_SPI_GET_RD_DATASZ MR_IOC_GRBDSZ /**< Get read data size */
#define MR_IOC_SPI_GET_RD_CALL MR_IOC_GRCB /**< Get read callback */
/**
* @brief SPI data type.
@@ -111,7 +116,7 @@ typedef uint8_t mr_spi_data_t; /**< SPI rea
/**
* @brief SPI ISR events.
*/
#define MR_ISR_SPI_RD_INT (MR_ISR_RD | (0x01 << 8)) /**< Read interrupt */
#define MR_ISR_SPI_RD_INT (MR_ISR_RD | (0x01)) /**< Read interrupt */
/**
* @brief SPI bus structure.
@@ -141,7 +146,7 @@ struct mr_spi_bus_ops
*/
#define MR_SPI_CS_ACTIVE_LOW (0) /**< Active low */
#define MR_SPI_CS_ACTIVE_HIGH (1) /**< Active high */
#define MR_SPI_CS_ACTIVE_NONE (2) /**< No active */
#define MR_SPI_CS_ACTIVE_HARDWARE (2) /**< Hardware */
/**
* @brief SPI device structure.
@@ -153,16 +158,12 @@ struct mr_spi_dev
struct mr_spi_config config; /**< Config */
struct mr_ringbuf rd_fifo; /**< Read FIFO */
size_t rd_bufsz; /**< Read buffer size */
uint32_t cs_pin: 30; /**< CS pin */
uint32_t cs_active: 2; /**< CS active level */
int cs_pin; /**< CS pin */
int cs_active; /**< CS active level */
};
/**
* @addtogroup SPI.
* @{
*/
int mr_spi_bus_register(struct mr_spi_bus *spi_bus, const char *name, struct mr_drv *drv);
int mr_spi_dev_register(struct mr_spi_dev *spi_dev, const char *name, int cs_pin, int cs_active);
int mr_spi_bus_register(struct mr_spi_bus *spi_bus, const char *path, struct mr_drv *drv);
int mr_spi_dev_register(struct mr_spi_dev *spi_dev, const char *path, int cs_pin, int cs_active);
/** @} */
#endif /* MR_USING_SPI */