1.软件i2c功能优化。

This commit is contained in:
MacRsh
2023-12-19 19:22:48 +08:00
parent 8e6ce1b215
commit 0786360508
2 changed files with 50 additions and 17 deletions

View File

@@ -82,6 +82,16 @@ static int mr_soft_i2c_bus_configure(struct mr_i2c_bus *i2c_bus, struct mr_i2c_c
if (state == MR_ENABLE) if (state == MR_ENABLE)
{ {
/* Soft I2C only support host mode */
if (config->host_slave != MR_I2C_HOST)
{
return MR_ENOTSUP;
}
/* Calculate the delay time */
soft_i2c_bus->delay = 1000000 / config->baud_rate;
/* Configure SCL and SDA */
if (soft_i2c_bus->desc < 0) if (soft_i2c_bus->desc < 0)
{ {
soft_i2c_bus->desc = mr_dev_open("pin", MR_OFLAG_RDWR); soft_i2c_bus->desc = mr_dev_open("pin", MR_OFLAG_RDWR);
@@ -89,25 +99,26 @@ static int mr_soft_i2c_bus_configure(struct mr_i2c_bus *i2c_bus, struct mr_i2c_c
{ {
return soft_i2c_bus->desc; return soft_i2c_bus->desc;
} }
}
/* Configure SCL pin */ /* Configure SCL pin */
mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_NUMBER, &soft_i2c_bus->scl_pin); mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_NUMBER, &soft_i2c_bus->scl_pin);
int ret = mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_MODE, mr_make_local(int, MR_PIN_MODE_OUTPUT_OD)); int ret = mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_MODE, mr_make_local(int, MR_PIN_MODE_OUTPUT_OD));
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
} }
/* Configure SDA pin */ /* Configure SDA pin */
mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_NUMBER, &soft_i2c_bus->sda_pin); mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_NUMBER, &soft_i2c_bus->sda_pin);
ret = mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_MODE, mr_make_local(int, MR_PIN_MODE_OUTPUT_OD)); ret = mr_dev_ioctl(soft_i2c_bus->desc, MR_CTL_PIN_SET_MODE, mr_make_local(int, MR_PIN_MODE_OUTPUT_OD));
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
}
} }
} else } else
{ {
/* Reconfigure SCL and SDA */
if (soft_i2c_bus->desc >= 0) if (soft_i2c_bus->desc >= 0)
{ {
/* Reconfigure SCL pin */ /* Reconfigure SCL pin */

View File

@@ -9,6 +9,7 @@
#include "include/mr_api.h" #include "include/mr_api.h"
#define MR_ROOT_DEV_NAME "dev" #define MR_ROOT_DEV_NAME "dev"
static struct mr_dev root_dev = {MR_MAGIC_NUMBER, static struct mr_dev root_dev = {MR_MAGIC_NUMBER,
MR_ROOT_DEV_NAME, MR_ROOT_DEV_NAME,
Mr_Dev_Type_Root, Mr_Dev_Type_Root,
@@ -188,11 +189,13 @@ static void dev_lock_release(struct mr_dev *dev, int release)
static int dev_register(struct mr_dev *dev, const char *path) static int dev_register(struct mr_dev *dev, const char *path)
{ {
/* Register the device to the root device */
return dev_register_by_path(&root_dev, dev, path); return dev_register_by_path(&root_dev, dev, path);
} }
static struct mr_dev *dev_find(const char *path) static struct mr_dev *dev_find(const char *path)
{ {
/* Find the device from the root device */
return dev_find_by_path(&root_dev, path); return dev_find_by_path(&root_dev, path);
} }
@@ -205,8 +208,10 @@ static int dev_open(struct mr_dev *dev, int oflags)
} }
#endif /* MR_USING_RDWR_CTL */ #endif /* MR_USING_RDWR_CTL */
/* Check whether the device is opened */
if (dev->ref_count == 0) if (dev->ref_count == 0)
{ {
/* Continue iterating */
if (dev->parent != NULL) if (dev->parent != NULL)
{ {
int ret = dev_open(dev->parent, oflags); int ret = dev_open(dev->parent, oflags);
@@ -216,6 +221,7 @@ static int dev_open(struct mr_dev *dev, int oflags)
} }
} }
/* Open the device */
if (dev->ops->open != MR_NULL) if (dev->ops->open != MR_NULL)
{ {
int ret = dev->ops->open(dev); int ret = dev->ops->open(dev);
@@ -232,16 +238,20 @@ static int dev_open(struct mr_dev *dev, int oflags)
} }
#endif /* MR_USING_RDWR_CTL */ #endif /* MR_USING_RDWR_CTL */
/* Increase the reference count */
dev->ref_count++; dev->ref_count++;
return MR_EOK; return MR_EOK;
} }
static int dev_close(struct mr_dev *dev) static int dev_close(struct mr_dev *dev)
{ {
/* Decrease the reference count */
dev->ref_count--; dev->ref_count--;
/* Check whether the device needs to be closed */
if (dev->ref_count == 0) if (dev->ref_count == 0)
{ {
/* Continue iterating */
if (dev->parent != NULL) if (dev->parent != NULL)
{ {
int ret = dev_close(dev->parent); int ret = dev_close(dev->parent);
@@ -251,6 +261,7 @@ static int dev_close(struct mr_dev *dev)
} }
} }
/* Close the device */
if (dev->ops->close != MR_NULL) if (dev->ops->close != MR_NULL)
{ {
return dev->ops->close(dev); return dev->ops->close(dev);
@@ -327,6 +338,7 @@ static ssize_t dev_write(struct mr_dev *dev, int offset, const void *buf, size_t
static int dev_ioctl(struct mr_dev *dev, int desc, int off, int cmd, void *args) static int dev_ioctl(struct mr_dev *dev, int desc, int off, int cmd, void *args)
{ {
/* Check whether the device has an ioctl function */
if (dev->ops->ioctl == MR_NULL) if (dev->ops->ioctl == MR_NULL)
{ {
return MR_ENOTSUP; return MR_ENOTSUP;
@@ -461,6 +473,7 @@ int mr_dev_isr(struct mr_dev *dev, int event, void *args)
{ {
mr_assert(dev != MR_NULL); mr_assert(dev != MR_NULL);
/* Check whether the device is opened */
if (dev->ref_count == 0) if (dev->ref_count == 0)
{ {
return MR_EINVAL; return MR_EINVAL;
@@ -468,12 +481,14 @@ int mr_dev_isr(struct mr_dev *dev, int event, void *args)
if (dev->ops->isr != MR_NULL) if (dev->ops->isr != MR_NULL)
{ {
/* Call the device ISR */
ssize_t ret = dev->ops->isr(dev, event, args); ssize_t ret = dev->ops->isr(dev, event, args);
if (ret < 0) if (ret < 0)
{ {
return (int)ret; return (int)ret;
} }
/* Handle the event */
switch (event & MR_ISR_MASK) switch (event & MR_ISR_MASK)
{ {
case MR_ISR_RD: case MR_ISR_RD:
@@ -536,13 +551,13 @@ int mr_dev_get_path(struct mr_dev *dev, char *buf, size_t bufsz)
} }
/* Check memory */ /* Check memory */
if(ret < 0) if (ret < 0)
{ {
return MR_ENOMEM; return MR_ENOMEM;
} }
/* If the space is sufficient, continue to obtain the path */ /* If the space is sufficient, continue to obtain the path */
if((bufsz-ret) > strlen(dev->name)) if ((bufsz - ret) > strlen(dev->name))
{ {
ret += snprintf(buf + ret, bufsz - ret, "/%s", dev->name); ret += snprintf(buf + ret, bufsz - ret, "/%s", dev->name);
} }
@@ -568,9 +583,10 @@ static struct mr_desc
static int desc_allocate(const char *path) static int desc_allocate(const char *path)
{ {
int desc = -1; int desc = -1;
int i = 0;
/* Find a free descriptor */ /* Find a free descriptor */
for (int i = 0; i < MR_CFG_DESC_MAX; i++) for (i = 0; i < MR_CFG_DESC_MAX; i++)
{ {
if (desc_of(i).dev == MR_NULL) if (desc_of(i).dev == MR_NULL)
{ {
@@ -620,12 +636,14 @@ int mr_dev_open(const char *path, int oflags)
mr_assert(path != MR_NULL); mr_assert(path != MR_NULL);
mr_assert(oflags != MR_OFLAG_CLOSED); mr_assert(oflags != MR_OFLAG_CLOSED);
/* Allocate a descriptor */
int desc = desc_allocate(path); int desc = desc_allocate(path);
if (desc < 0) if (desc < 0)
{ {
return desc; return desc;
} }
/* Open the device */
int ret = dev_open(desc_of(desc).dev, oflags); int ret = dev_open(desc_of(desc).dev, oflags);
if (ret != MR_EOK) if (ret != MR_EOK)
{ {
@@ -633,6 +651,7 @@ int mr_dev_open(const char *path, int oflags)
return ret; return ret;
} }
/* Initialize the open flags */
desc_of(desc).oflags = oflags; desc_of(desc).oflags = oflags;
return desc; return desc;
} }
@@ -648,11 +667,14 @@ int mr_dev_close(int desc)
{ {
mr_assert(desc_is_valid(desc)); mr_assert(desc_is_valid(desc));
/* Close the device */
int ret = dev_close(desc_of(desc).dev); int ret = dev_close(desc_of(desc).dev);
if (ret != MR_EOK) if (ret != MR_EOK)
{ {
return ret; return ret;
} }
/* Free the descriptor */
desc_free(desc); desc_free(desc);
return MR_EOK; return MR_EOK;
} }