1.为提速软件模拟效率,引入快速Pin,注意此接口仅为模拟接口使用,请不要随意使用此接口,严禁跳过设备框架在应用层使用此功能(如果不遵守,将破坏软件架构,导致解耦失效)。
This commit is contained in:
108
device/fast_pin.c
Normal file
108
device/fast_pin.c
Normal 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 */
|
||||
|
||||
@@ -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) */
|
||||
|
||||
@@ -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) */
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user