1.CAN模板更新。2.设备框架更新,中断机制重构,设备中断仅唤醒自身回调列表,需要递归调用可手动调用mr_dev_isr。3.由于使用回调列表,数据量可能发生变化,设备中断回调不再传入缓冲区数据数量,需用户手动获取。4.PIN设备支持模式保存。5.serial新增DMA支持。

This commit is contained in:
MacRsh
2024-02-19 13:23:42 +08:00
parent 85360e3470
commit b3722e4e23
12 changed files with 844 additions and 855 deletions

View File

@@ -30,12 +30,12 @@ static int mr_can_bus_close(struct mr_dev *dev)
return ops->configure(can_bus, &close_config);
}
static ssize_t mr_can_bus_read(struct mr_dev *dev, int off, void *buf, size_t size, int async)
static ssize_t mr_can_bus_read(struct mr_dev *dev, void *buf, size_t count)
{
return MR_EIO;
}
static ssize_t mr_can_bus_write(struct mr_dev *dev, int off, const void *buf, size_t size, int async)
static ssize_t mr_can_bus_write(struct mr_dev *dev, const void *buf, size_t count)
{
return MR_EIO;
}
@@ -45,37 +45,34 @@ static ssize_t mr_can_bus_isr(struct mr_dev *dev, int event, void *args)
struct mr_can_bus *can_bus = (struct mr_can_bus *)dev;
struct mr_can_bus_ops *ops = (struct mr_can_bus_ops *)dev->drv->ops;
switch (event)
{
case MR_ISR_CAN_RD_INT:
{
struct mr_list *list = MR_NULL;
switch (event) {
case MR_ISR_CAN_RD_INT: {
uint8_t data[8] = {0};
int id = ops->get_id(can_bus);
ssize_t ret = ops->read(can_bus, data, sizeof(data));
int id, ide, rtr;
/* Read id and data to FIFO */
ssize_t ret = ops->read(can_bus, &id, &ide, &rtr, data, sizeof(data));
if (ret < 0) {
return ret;
}
id = (ide == MR_CAN_IDE_STD) ? (id & 0x7ff) : (id & 0x1fffffff);
/* Search the matching device */
for (list = dev->clist.next; list != &dev->clist; list = list->next)
{
struct mr_can_dev *can_dev = (struct mr_can_dev *)MR_CONTAINER_OF(list, struct mr_dev, list);
for (struct mr_list *list = dev->clist.next; list != &dev->clist; list = list->next) {
struct mr_can_dev *can_dev = (struct mr_can_dev *)MR_CONTAINER_OF(list,
struct mr_dev,
list);
/* Check id is valid */
if (can_dev->id == (id & ((1 << 29) - 1)))
{
/* Read data to FIFO. if callback is set, call it */
if (can_dev->id == id) {
mr_ringbuf_write_force(&can_dev->rd_fifo, data, ret);
if (can_dev->dev.rd_call.call != MR_NULL)
{
ssize_t size = (ssize_t)mr_ringbuf_get_data_size(&can_dev->rd_fifo);
can_dev->dev.rd_call.call(can_dev->dev.rd_call.desc, &size);
}
break;
return mr_dev_isr(&can_dev->dev, event, &rtr);
}
}
return MR_EOK;
return MR_ENOTFOUND;
}
default:
{
default: {
return MR_ENOTSUP;
}
}
@@ -85,26 +82,23 @@ static ssize_t mr_can_bus_isr(struct mr_dev *dev, int event, void *args)
* @brief This function registers a can-bus.
*
* @param can_dev The can-device.
* @param name The name of the can-bus.
* @param path The path of the can-bus.
* @param drv The driver of the can-bus.
*
* @return MR_EOK on success, otherwise an error code.
* @return 0 on success, otherwise an error code.
*/
int mr_can_bus_register(struct mr_can_bus *can_bus, const char *name, struct mr_drv *drv)
int mr_can_bus_register(struct mr_can_bus *can_bus, const char *path, struct mr_drv *drv)
{
static struct mr_dev_ops ops =
{
mr_can_bus_open,
mr_can_bus_close,
mr_can_bus_read,
mr_can_bus_write,
MR_NULL,
mr_can_bus_isr
};
static struct mr_dev_ops ops = {mr_can_bus_open,
mr_can_bus_close,
mr_can_bus_read,
mr_can_bus_write,
MR_NULL,
mr_can_bus_isr};
struct mr_can_config default_config = MR_CAN_CONFIG_DEFAULT;
MR_ASSERT(can_bus != MR_NULL);
MR_ASSERT(name != MR_NULL);
MR_ASSERT(path != MR_NULL);
MR_ASSERT(drv != MR_NULL);
MR_ASSERT(drv->ops != MR_NULL);
@@ -113,10 +107,10 @@ int mr_can_bus_register(struct mr_can_bus *can_bus, const char *name, struct mr_
can_bus->owner = MR_NULL;
/* Register the can-bus */
return mr_dev_register(&can_bus->dev, name, Mr_Dev_Type_CAN, MR_SFLAG_RDWR, &ops, drv);
return mr_dev_register(&can_bus->dev, path, MR_DEV_TYPE_CAN, MR_O_RDWR, &ops, drv);
}
static int can_dev_filter_configure(struct mr_can_dev *can_dev, int id, int ide, int state)
MR_INLINE int can_dev_filter_configure(struct mr_can_dev *can_dev, int id, int ide, int state)
{
struct mr_can_bus *can_bus = (struct mr_can_bus *)can_dev->dev.parent;
struct mr_can_bus_ops *ops = (struct mr_can_bus_ops *)can_bus->dev.drv->ops;
@@ -129,24 +123,22 @@ MR_INLINE int can_dev_take_bus(struct mr_can_dev *can_dev)
struct mr_can_bus *can_bus = (struct mr_can_bus *)can_dev->dev.parent;
struct mr_can_bus_ops *ops = (struct mr_can_bus_ops *)can_bus->dev.drv->ops;
if ((can_dev != can_bus->owner) && (can_bus->owner != MR_NULL))
{
if ((can_bus->hold == MR_TRUE) && (can_dev != can_bus->owner)) {
return MR_EBUSY;
}
if (can_dev != can_bus->owner)
{
if (can_dev->config.baud_rate != can_bus->config.baud_rate)
{
/* If the owner changes, recheck the configuration */
if (can_dev != can_bus->owner) {
if (can_dev->config.baud_rate != can_bus->config.baud_rate) {
int ret = ops->configure(can_bus, &can_dev->config);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
}
can_bus->config = can_dev->config;
can_bus->owner = can_dev;
}
can_bus->hold = MR_TRUE;
return MR_EOK;
}
@@ -154,137 +146,97 @@ MR_INLINE int can_dev_release_bus(struct mr_can_dev *can_dev)
{
struct mr_can_bus *can_bus = (struct mr_can_bus *)can_dev->dev.parent;
if (can_dev != can_bus->owner)
{
if (can_dev != can_bus->owner) {
return MR_EINVAL;
}
can_bus->owner = MR_NULL;
can_bus->hold = MR_FALSE;
return MR_EOK;
}
MR_INLINE ssize_t can_dev_read(struct mr_can_dev *can_dev, uint8_t *buf, size_t size)
MR_INLINE ssize_t can_dev_write(struct mr_can_dev *can_dev,
int id,
int ide,
const uint8_t *buf,
size_t count)
{
struct mr_can_bus *can_bus = (struct mr_can_bus *)can_dev->dev.parent;
struct mr_can_bus_ops *ops = (struct mr_can_bus_ops *)can_bus->dev.drv->ops;
ssize_t rd_size = 0;
for (rd_size = 0; rd_size < size;)
{
/* Check id is valid */
int id = ops->get_id(can_bus);
if (can_dev->id != (id & ((1 << 29) - 1)))
{
break;
}
ssize_t ret = ops->read(can_bus, (buf + rd_size), (size - rd_size));
if (ret <= 0)
{
break;
}
rd_size += ret;
}
return rd_size;
return ops->write(can_bus, id, ide, buf, count);
}
MR_INLINE ssize_t can_dev_write(struct mr_can_dev *can_dev, int id, int ide, int rtr, const uint8_t *buf, size_t size)
MR_INLINE int can_dev_request(struct mr_can_dev *can_dev, int id, int ide)
{
struct mr_can_bus *can_bus = (struct mr_can_bus *)can_dev->dev.parent;
struct mr_can_bus_ops *ops = (struct mr_can_bus_ops *)can_bus->dev.drv->ops;
return ops->write(can_bus, id, ide, rtr, buf, size);
return ops->remote_request(can_bus, id, ide);
}
static int mr_can_dev_open(struct mr_dev *dev)
{
struct mr_can_dev *can_dev = (struct mr_can_dev *)dev;
/* Allocate FIFO buffers */
int ret = mr_ringbuf_allocate(&can_dev->rd_fifo, can_dev->rd_bufsz);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
return can_dev_filter_configure(can_dev->dev.parent, can_dev->id, can_dev->ide, MR_ENABLE);
return can_dev_filter_configure(can_dev, can_dev->id, can_dev->ide, MR_ENABLE);
}
static int mr_can_dev_close(struct mr_dev *dev)
{
struct mr_can_dev *can_dev = (struct mr_can_dev *)dev;
/* Free FIFO buffers */
mr_ringbuf_free(&can_dev->rd_fifo);
return can_dev_filter_configure(can_dev->dev.parent, can_dev->id, can_dev->ide, MR_DISABLE);
return can_dev_filter_configure(can_dev, can_dev->id, can_dev->ide, MR_DISABLE);
}
static ssize_t mr_can_dev_read(struct mr_dev *dev, int off, void *buf, size_t size, int async)
static ssize_t mr_can_dev_read(struct mr_dev *dev, void *buf, size_t count)
{
struct mr_can_dev *can_dev = (struct mr_can_dev *)dev;
ssize_t ret = can_dev_take_bus(can_dev);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
if (mr_ringbuf_get_bufsz(&can_dev->rd_fifo) == 0)
{
ret = can_dev_read(can_dev, (uint8_t *)buf, size);
} else
{
ret = (ssize_t)mr_ringbuf_read(&can_dev->rd_fifo, buf, size);
}
ret = (ssize_t)mr_ringbuf_read(&can_dev->rd_fifo, buf, count);
can_dev_release_bus(can_dev);
return ret;
}
static ssize_t mr_can_dev_write(struct mr_dev *dev, int off, const void *buf, size_t size, int async)
static ssize_t mr_can_dev_write(struct mr_dev *dev, const void *buf, size_t count)
{
struct mr_can_dev *can_dev = (struct mr_can_dev *)dev;
/* Check offset is valid */
if (off < 0)
{
return MR_EINVAL;
}
ssize_t ret = can_dev_take_bus(can_dev);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
ret = can_dev_write(can_dev,
(off & ((1 << 29) - 1)),
MR_BIT_IS_SET(off, MR_CAN_IDE_EXT),
MR_BIT_IS_SET(off, MR_CAN_RTR_REMOTE),
(uint8_t *)buf,
size);
ret = can_dev_write(can_dev, can_dev->id, can_dev->ide, (uint8_t *)buf, count);
can_dev_release_bus(can_dev);
return ret;
}
static int mr_can_dev_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
static int mr_can_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
{
struct mr_can_dev *can_dev = (struct mr_can_dev *)dev;
switch (cmd)
{
case MR_CTL_SET_CONFIG:
{
if (args != MR_NULL)
{
switch (cmd) {
case MR_IOC_CAN_SET_CONFIG: {
if (args != MR_NULL) {
struct mr_can_bus *can_bus = (struct mr_can_bus *)dev->parent;
struct mr_can_config config = *(struct mr_can_config *)args;
/* If holding the bus, release it */
if (can_dev == can_bus->owner)
{
if (can_dev == can_bus->owner) {
can_bus->hold = MR_FALSE;
can_bus->owner = MR_NULL;
}
@@ -293,16 +245,13 @@ static int mr_can_dev_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_CTL_SET_RD_BUFSZ:
{
if (args != MR_NULL)
{
case MR_IOC_CAN_SET_RD_BUFSZ: {
if (args != MR_NULL) {
size_t bufsz = *(size_t *)args;
int ret = mr_ringbuf_allocate(&can_dev->rd_fifo, bufsz);
can_dev->rd_bufsz = 0;
if (ret < 0)
{
if (ret < 0) {
return ret;
}
can_dev->rd_bufsz = bufsz;
@@ -310,10 +259,15 @@ static int mr_can_dev_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_CTL_GET_CONFIG:
{
if (args != MR_NULL)
{
case MR_IOC_CAN_CLR_RD_BUF: {
mr_ringbuf_reset(&can_dev->rd_fifo);
return MR_EOK;
}
case MR_IOC_CAN_REMOTE_REQUEST: {
return can_dev_request(can_dev, can_dev->id, can_dev->ide);
}
case MR_IOC_CAN_GET_CONFIG: {
if (args != MR_NULL) {
struct mr_can_config *config = (struct mr_can_config *)args;
*config = can_dev->config;
@@ -321,10 +275,8 @@ static int mr_can_dev_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_CTL_GET_RD_BUFSZ:
{
if (args != MR_NULL)
{
case MR_IOC_CAN_GET_RD_BUFSZ: {
if (args != MR_NULL) {
size_t *bufsz = (size_t *)args;
*bufsz = can_dev->rd_bufsz;
@@ -332,8 +284,16 @@ static int mr_can_dev_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
}
return MR_EINVAL;
}
default:
{
case MR_IOC_CAN_GET_RD_DATASZ: {
if (args != MR_NULL) {
size_t *datasz = (size_t *)args;
*datasz = mr_ringbuf_get_data_size(&can_dev->rd_fifo);
return sizeof(*datasz);
}
return MR_EINVAL;
}
default: {
return MR_ENOTSUP;
}
}
@@ -343,27 +303,27 @@ static int mr_can_dev_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
* @brief This function registers a can-device.
*
* @param can_dev The can-device.
* @param name The name of the can-device.
* @param path The path of the can-device.
* @param id The id of the can-device.
* @param ide The id identifier of the can-device.
*
* @return MR_EOK on success, otherwise an error code.
* @return 0 on success, otherwise an error code.
*/
int mr_can_dev_register(struct mr_can_dev *can_dev, const char *name, int id, int ide)
int mr_can_dev_register(struct mr_can_dev *can_dev, const char *path, int id, int ide)
{
static struct mr_dev_ops ops =
{
mr_can_dev_open,
mr_can_dev_close,
mr_can_dev_read,
mr_can_dev_write,
mr_can_dev_ioctl,
MR_NULL
};
static struct mr_dev_ops ops = {mr_can_dev_open,
mr_can_dev_close,
mr_can_dev_read,
mr_can_dev_write,
mr_can_dev_ioctl,
MR_NULL};
struct mr_can_config default_config = MR_CAN_CONFIG_DEFAULT;
MR_ASSERT(can_dev != MR_NULL);
MR_ASSERT(name != MR_NULL);
MR_ASSERT(path != MR_NULL);
MR_ASSERT((ide == MR_CAN_IDE_STD) || (ide == MR_CAN_IDE_EXT));
MR_ASSERT((ide != MR_CAN_IDE_STD) || ((id >= 0) && (id <= 0x7ff)));
MR_ASSERT((ide != MR_CAN_IDE_EXT) || ((id >= 0) && (id <= 0x1fffffff)));
/* Initialize the fields */
can_dev->config = default_config;
@@ -376,7 +336,7 @@ int mr_can_dev_register(struct mr_can_dev *can_dev, const char *name, int id, in
can_dev->ide = ide;
/* Register the can-device */
return mr_dev_register(&can_dev->dev, name, Mr_Dev_Type_CAN, MR_SFLAG_RDWR | MR_SFLAG_NONDRV, &ops, MR_NULL);
return mr_dev_register(&can_dev->dev, path, MR_DEV_TYPE_CAN, MR_O_RDWR, &ops, MR_NULL);
}
#endif /* MR_USING_CAN */

View File

@@ -46,25 +46,22 @@ static ssize_t mr_i2c_bus_isr(struct mr_dev *dev, int event, void *args)
struct mr_i2c_bus *i2c_bus = (struct mr_i2c_bus *)dev;
struct mr_i2c_bus_ops *ops = (struct mr_i2c_bus_ops *)dev->drv->ops;
switch (event)
{
case MR_ISR_I2C_RD_INT:
{
switch (event) {
case MR_ISR_I2C_RD_INT: {
struct mr_i2c_dev *i2c_dev = (struct mr_i2c_dev *)i2c_bus->owner;
uint8_t data;
/* Read data to FIFO */
int ret = ops->read(i2c_bus, &data, MR_ENABLE);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
mr_ringbuf_push_force(&i2c_dev->rd_fifo, data);
return (ssize_t)mr_ringbuf_get_data_size(&i2c_dev->rd_fifo);
/* Call the i2c-dev ISR */
return mr_dev_isr(&i2c_dev->dev, event, MR_NULL);
}
default:
{
default: {
return MR_ENOTSUP;
}
}
@@ -81,15 +78,12 @@ static ssize_t mr_i2c_bus_isr(struct mr_dev *dev, int event, void *args)
*/
int mr_i2c_bus_register(struct mr_i2c_bus *i2c_bus, const char *path, struct mr_drv *drv)
{
static struct mr_dev_ops ops =
{
mr_i2c_bus_open,
mr_i2c_bus_close,
mr_i2c_bus_read,
mr_i2c_bus_write,
MR_NULL,
mr_i2c_bus_isr
};
static struct mr_dev_ops ops = {mr_i2c_bus_open,
mr_i2c_bus_close,
mr_i2c_bus_read,
mr_i2c_bus_write,
MR_NULL,
mr_i2c_bus_isr};
struct mr_i2c_config default_config = MR_I2C_CONFIG_DEFAULT;
MR_ASSERT(i2c_bus != MR_NULL);
@@ -112,22 +106,18 @@ MR_INLINE int i2c_dev_take_bus(struct mr_i2c_dev *i2c_dev)
struct mr_i2c_bus_ops *ops = (struct mr_i2c_bus_ops *)i2c_bus->dev.drv->ops;
/* Check if the bus is busy */
if ((i2c_bus->hold == MR_TRUE) && (i2c_dev != i2c_bus->owner))
{
if ((i2c_bus->hold == MR_TRUE) && (i2c_dev != i2c_bus->owner)) {
return MR_EBUSY;
}
/* If the owner changes, recheck the configuration */
if (i2c_dev != i2c_bus->owner)
{
if (i2c_dev->config.baud_rate != i2c_bus->config.baud_rate
|| i2c_dev->config.host_slave != i2c_bus->config.host_slave)
{
if (i2c_dev != i2c_bus->owner) {
if (i2c_dev->config.baud_rate != i2c_bus->config.baud_rate ||
i2c_dev->config.host_slave != i2c_bus->config.host_slave) {
int addr = (i2c_dev->config.host_slave == MR_I2C_HOST) ? 0x00 : i2c_dev->addr;
int ret = ops->configure(i2c_bus, &i2c_dev->config, addr, i2c_dev->addr_bits);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
}
@@ -142,14 +132,12 @@ MR_INLINE int i2c_dev_release_bus(struct mr_i2c_dev *i2c_dev)
{
struct mr_i2c_bus *i2c_bus = (struct mr_i2c_bus *)i2c_dev->dev.parent;
if (i2c_dev != i2c_bus->owner)
{
if (i2c_dev != i2c_bus->owner) {
return MR_EINVAL;
}
/* If it is a host, release the bus. The slave needs to hold the bus at all times */
if (i2c_dev->config.host_slave == MR_I2C_HOST)
{
if (i2c_dev->config.host_slave == MR_I2C_HOST) {
i2c_bus->hold = MR_FALSE;
}
return MR_EOK;
@@ -170,15 +158,13 @@ MR_INLINE int i2c_dev_send_addr(struct mr_i2c_dev *i2c_dev, int rdwr)
/* Set the read command */
addr = (0xf000 | ((addr >> 8) & 0x03) << 9) | (addr & 0xff);
if (rdwr == MR_I2C_RD)
{
if (rdwr == MR_I2C_RD) {
addr |= (addr_bits == MR_I2C_ADDR_BITS_7) ? 0x01 : 0x10;
}
ops->start(i2c_bus);
int ret = ops->send_addr(i2c_bus, addr, addr_bits);
if (ret < 0)
{
if (ret < 0) {
ops->stop(i2c_bus);
}
return ret;
@@ -198,13 +184,11 @@ MR_INLINE ssize_t i2c_dev_read(struct mr_i2c_dev *i2c_dev, uint8_t *buf, size_t
struct mr_i2c_bus_ops *ops = (struct mr_i2c_bus_ops *)i2c_bus->dev.drv->ops;
ssize_t rd_size;
for (rd_size = 0; rd_size < count; rd_size += sizeof(*buf))
{
for (rd_size = 0; rd_size < count; rd_size += sizeof(*buf)) {
int ack = ((count - rd_size) != sizeof(*buf));
int ret = ops->read(i2c_bus, buf, ack);
if (ret < 0)
{
if (ret < 0) {
return (rd_size == 0) ? ret : rd_size;
}
buf++;
@@ -218,11 +202,9 @@ MR_INLINE ssize_t i2c_dev_write(struct mr_i2c_dev *i2c_dev, const uint8_t *buf,
struct mr_i2c_bus_ops *ops = (struct mr_i2c_bus_ops *)i2c_bus->dev.drv->ops;
ssize_t wr_size;
for (wr_size = 0; wr_size < count; wr_size += sizeof(*buf))
{
for (wr_size = 0; wr_size < count; wr_size += sizeof(*buf)) {
int ret = ops->write(i2c_bus, *buf);
if (ret < 0)
{
if (ret < 0) {
return (wr_size == 0) ? ret : wr_size;
}
buf++;
@@ -250,38 +232,33 @@ static ssize_t mr_i2c_dev_read(struct mr_dev *dev, void *buf, size_t count)
struct mr_i2c_dev *i2c_dev = (struct mr_i2c_dev *)dev;
ssize_t ret = i2c_dev_take_bus(i2c_dev);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
if (i2c_dev->config.host_slave == MR_I2C_HOST)
{
if (i2c_dev->config.host_slave == MR_I2C_HOST) {
/* Send the address of the register that needs to be read */
if (dev->position >= 0)
{
if (dev->position >= 0) {
ret = i2c_dev_send_addr(i2c_dev, MR_I2C_WR);
if (ret < 0)
{
if (ret < 0) {
goto release_bus;
}
ret = i2c_dev_write(i2c_dev, (uint8_t *)&dev->position, (i2c_dev->config.reg_bits >> 3));
if (ret < 0)
{
ret = i2c_dev_write(i2c_dev,
(uint8_t *)&dev->position,
(i2c_dev->config.reg_bits >> 3));
if (ret < 0) {
goto release_bus;
}
}
ret = i2c_dev_send_addr(i2c_dev, MR_I2C_RD);
if (ret < 0)
{
if (ret < 0) {
goto release_bus;
}
ret = i2c_dev_read(i2c_dev, (uint8_t *)buf, count);
i2c_dev_send_stop(i2c_dev);
} else
{
} else {
ret = (ssize_t)mr_ringbuf_read(&i2c_dev->rd_fifo, buf, count);
}
@@ -295,33 +272,29 @@ static ssize_t mr_i2c_dev_write(struct mr_dev *dev, const void *buf, size_t coun
struct mr_i2c_dev *i2c_dev = (struct mr_i2c_dev *)dev;
ssize_t ret = i2c_dev_take_bus(i2c_dev);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
if (i2c_dev->config.host_slave == MR_I2C_HOST)
{
if (i2c_dev->config.host_slave == MR_I2C_HOST) {
ret = i2c_dev_send_addr(i2c_dev, MR_I2C_WR);
if (ret < 0)
{
if (ret < 0) {
goto release_bus;
}
/* Send the address of the register that needs to be written */
if (dev->position >= 0)
{
ret = i2c_dev_write(i2c_dev, (uint8_t *)&dev->position, (i2c_dev->config.reg_bits >> 3));
if (ret < 0)
{
if (dev->position >= 0) {
ret = i2c_dev_write(i2c_dev,
(uint8_t *)&dev->position,
(i2c_dev->config.reg_bits >> 3));
if (ret < 0) {
goto release_bus;
}
}
ret = i2c_dev_write(i2c_dev, (uint8_t *)buf, count);
i2c_dev_send_stop(i2c_dev);
} else
{
} else {
ret = i2c_dev_write(i2c_dev, (uint8_t *)buf, count);
}
@@ -334,29 +307,23 @@ static int mr_i2c_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
{
struct mr_i2c_dev *i2c_dev = (struct mr_i2c_dev *)dev;
switch (cmd)
{
case MR_IOC_I2C_SET_CONFIG:
{
if (args != MR_NULL)
{
switch (cmd) {
case MR_IOC_I2C_SET_CONFIG: {
if (args != MR_NULL) {
struct mr_i2c_bus *i2c_bus = (struct mr_i2c_bus *)dev->parent;
struct mr_i2c_config config = *(struct mr_i2c_config *)args;
/* If holding the bus, release it */
if (i2c_dev == i2c_bus->owner)
{
if (i2c_dev == i2c_bus->owner) {
i2c_bus->hold = MR_FALSE;
i2c_bus->owner = MR_NULL;
}
/* Update the configuration and try again to get the bus */
i2c_dev->config = config;
if (config.host_slave == MR_I2C_SLAVE)
{
if (config.host_slave == MR_I2C_SLAVE) {
int ret = i2c_dev_take_bus(i2c_dev);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
}
@@ -364,16 +331,13 @@ static int mr_i2c_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_I2C_SET_RD_BUFSZ:
{
if (args != MR_NULL)
{
case MR_IOC_I2C_SET_RD_BUFSZ: {
if (args != MR_NULL) {
size_t bufsz = *(size_t *)args;
int ret = mr_ringbuf_allocate(&i2c_dev->rd_fifo, bufsz);
i2c_dev->rd_bufsz = 0;
if (ret < 0)
{
if (ret < 0) {
return ret;
}
i2c_dev->rd_bufsz = bufsz;
@@ -381,15 +345,12 @@ static int mr_i2c_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_I2C_CLR_RD_BUF:
{
case MR_IOC_I2C_CLR_RD_BUF: {
mr_ringbuf_reset(&i2c_dev->rd_fifo);
return MR_EOK;
}
case MR_IOC_I2C_GET_CONFIG:
{
if (args != MR_NULL)
{
case MR_IOC_I2C_GET_CONFIG: {
if (args != MR_NULL) {
struct mr_i2c_config *config = (struct mr_i2c_config *)args;
*config = i2c_dev->config;
@@ -397,10 +358,8 @@ static int mr_i2c_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_I2C_GET_RD_BUFSZ:
{
if (args != MR_NULL)
{
case MR_IOC_I2C_GET_RD_BUFSZ: {
if (args != MR_NULL) {
size_t *bufsz = (size_t *)args;
*bufsz = i2c_dev->rd_bufsz;
@@ -408,18 +367,16 @@ static int mr_i2c_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_I2C_GET_RD_DATASZ:
{
if (args != MR_NULL)
{
case MR_IOC_I2C_GET_RD_DATASZ: {
if (args != MR_NULL) {
size_t *datasz = (size_t *)args;
*datasz = mr_ringbuf_get_bufsz(&i2c_dev->rd_fifo);
return sizeof(*datasz);
}
return MR_EINVAL;
}
default:
{
default: {
return MR_ENOTSUP;
}
}
@@ -437,22 +394,19 @@ static int mr_i2c_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
*/
int mr_i2c_dev_register(struct mr_i2c_dev *i2c_dev, const char *path, int addr, int addr_bits)
{
static struct mr_dev_ops ops =
{
mr_i2c_dev_open,
mr_i2c_dev_close,
mr_i2c_dev_read,
mr_i2c_dev_write,
mr_i2c_dev_ioctl,
MR_NULL
};
static struct mr_dev_ops ops = {mr_i2c_dev_open,
mr_i2c_dev_close,
mr_i2c_dev_read,
mr_i2c_dev_write,
mr_i2c_dev_ioctl,
MR_NULL};
struct mr_i2c_config default_config = MR_I2C_CONFIG_DEFAULT;
MR_ASSERT(i2c_dev != MR_NULL);
MR_ASSERT(path != MR_NULL);
MR_ASSERT((addr_bits == MR_I2C_ADDR_BITS_7) || (addr_bits == MR_I2C_ADDR_BITS_10));
MR_ASSERT((addr_bits != MR_I2C_ADDR_BITS_7) || (addr >= 0x00 && addr <= 0x7f));
MR_ASSERT((addr_bits != MR_I2C_ADDR_BITS_10) || (addr >= 0x00 && addr <= 0x3ff));
MR_ASSERT((addr_bits != MR_I2C_ADDR_BITS_7) || (addr >= 0 && addr <= 0x7f));
MR_ASSERT((addr_bits != MR_I2C_ADDR_BITS_10) || (addr >= 0 && addr <= 0x3ff));
/* Initialize the fields */
i2c_dev->config = default_config;

View File

@@ -12,16 +12,59 @@
void _mr_fast_pin_init(struct mr_dev *dev);
MR_INLINE int pin_set_mode(struct mr_pin *pin, int number, int mode)
#define PIN_MODE_SET(_pin, _number, _mode) \
do \
{ \
MR_BIT_CLR((_pin)->pins[(_number) / 8], (0xf << (((_number) % 8) * 4))); \
MR_BIT_SET((_pin)->pins[(_number) / 8], ((_mode) << (((_number) % 8) * 4))); \
} while (0)
#define PIN_MODE_GET(_pin, _number) \
((int)(((_pin)->pins[(_number) / 8] >> (((_number) % 8) * 4)) & 0xf)) \
MR_INLINE int pin_set_mode(struct mr_pin *pin, int number, struct mr_pin_config config)
{
struct mr_pin_ops *ops = (struct mr_pin_ops *)pin->dev.drv->ops;
if (number < 0)
{
if ((number < 0) || (number >= (sizeof(pin->pins) * 2))) {
return MR_EINVAL;
}
return ops->configure(pin, number, mode);
int ret = ops->configure(pin, number, config.mode);
if (ret < 0) {
return ret;
}
PIN_MODE_SET(pin, number, config.mode);
return MR_EOK;
}
MR_INLINE int pin_get_mode(struct mr_pin *pin, int number, struct mr_pin_config *config)
{
if ((number < 0) || (number >= (sizeof(pin->pins) * 2))) {
return MR_EINVAL;
}
config->mode = PIN_MODE_GET(pin, number);
return MR_EOK;
}
static int mr_pin_close(struct mr_dev *dev)
{
struct mr_pin *pin = (struct mr_pin *)dev;
struct mr_pin_ops *ops = (struct mr_pin_ops *)dev->drv->ops;
#ifdef MR_USING_PIN_AUTO_DISABLE
/* Disable all pins */
for (size_t i = 0; i < (sizeof(pin->pins) * 2); i++)
{
if (PIN_MODE_GET(pin, i) != MR_PIN_MODE_NONE)
{
ops->configure(pin, (int)i, MR_PIN_MODE_NONE);
PIN_MODE_SET(pin, i, MR_PIN_MODE_NONE);
}
}
#endif /* MR_USING_PIN_AUTO_DISABLE */
return MR_EOK;
}
static ssize_t mr_pin_read(struct mr_dev *dev, void *buf, size_t count)
@@ -33,17 +76,16 @@ static ssize_t mr_pin_read(struct mr_dev *dev, void *buf, size_t count)
#ifdef MR_USING_PIN_CHECK
/* Check number is valid */
if (dev->position < 0)
{
if ((dev->position < 0) ||
(dev->position >= (sizeof(pin->pins) * 2)) ||
(PIN_MODE_GET(pin, dev->position) == MR_PIN_MODE_NONE)) {
return MR_EINVAL;
}
#endif /* MR_USING_PIN_CHECK */
for (rd_size = 0; rd_size < count; rd_size += sizeof(*rd_buf))
{
for (rd_size = 0; rd_size < count; rd_size += sizeof(*rd_buf)) {
int ret = (uint8_t)ops->read(pin, dev->position, rd_buf);
if (ret < 0)
{
if (ret < 0) {
return (rd_size == 0) ? ret : rd_size;
}
rd_buf++;
@@ -60,17 +102,16 @@ static ssize_t mr_pin_write(struct mr_dev *dev, const void *buf, size_t count)
#ifdef MR_USING_PIN_CHECK
/* Check number is valid */
if (dev->position < 0)
{
if ((dev->position < 0) ||
(dev->position >= (sizeof(pin->pins) * 2)) ||
(PIN_MODE_GET(pin, dev->position) == MR_PIN_MODE_NONE)) {
return MR_EINVAL;
}
#endif /* MR_USING_PIN_CHECK */
for (wr_size = 0; wr_size < count; wr_size += sizeof(*wr_buf))
{
for (wr_size = 0; wr_size < count; wr_size += sizeof(*wr_buf)) {
int ret = ops->write(pin, dev->position, *wr_buf);
if (ret < 0)
{
if (ret < 0) {
return (wr_size == 0) ? ret : wr_size;
}
wr_buf++;
@@ -82,25 +123,31 @@ static int mr_pin_ioctl(struct mr_dev *dev, int cmd, void *args)
{
struct mr_pin *pin = (struct mr_pin *)dev;
switch (cmd)
{
case MR_IOC_PIN_SET_MODE:
{
if (args != MR_NULL)
{
switch (cmd) {
case MR_IOC_PIN_SET_MODE: {
if (args != MR_NULL) {
struct mr_pin_config config = *((struct mr_pin_config *)args);
int ret = pin_set_mode(pin, dev->position, config.mode);
if (ret < 0)
{
int ret = pin_set_mode(pin, dev->position, config);
if (ret < 0) {
return ret;
}
return sizeof(config);
}
return MR_EINVAL;
}
default:
{
case MR_IOC_PIN_GET_MODE: {
if (args != MR_NULL) {
struct mr_pin_config *config = (struct mr_pin_config *)args;
int ret = pin_get_mode(pin, dev->position, config);
if (ret < 0) {
return ret;
}
return sizeof(*config);
}
}
default: {
return MR_ENOTSUP;
}
}
@@ -108,16 +155,12 @@ static int mr_pin_ioctl(struct mr_dev *dev, int cmd, void *args)
static ssize_t mr_pin_isr(struct mr_dev *dev, int event, void *args)
{
switch (event)
{
case MR_ISR_PIN_EXTI_INT:
{
switch (event) {
case MR_ISR_PIN_EXTI_INT: {
ssize_t number = *(int *)args;
return number;
}
default:
{
default: {
return MR_ENOTSUP;
}
}
@@ -134,15 +177,12 @@ static ssize_t mr_pin_isr(struct mr_dev *dev, int event, void *args)
*/
int mr_pin_register(struct mr_pin *pin, const char *path, struct mr_drv *drv)
{
static struct mr_dev_ops ops =
{
MR_NULL,
MR_NULL,
mr_pin_read,
mr_pin_write,
mr_pin_ioctl,
mr_pin_isr
};
static struct mr_dev_ops ops = {MR_NULL,
mr_pin_close,
mr_pin_read,
mr_pin_write,
mr_pin_ioctl,
mr_pin_isr};
MR_ASSERT(pin != MR_NULL);
MR_ASSERT(path != MR_NULL);
@@ -151,8 +191,7 @@ int mr_pin_register(struct mr_pin *pin, const char *path, struct mr_drv *drv)
/* Register the pin */
int ret = mr_dev_register(&pin->dev, path, MR_DEV_TYPE_PIN, MR_O_RDWR, &ops, drv);
if (ret == MR_EOK)
{
if (ret == MR_EOK) {
/* Initialize the fast pin */
_mr_fast_pin_init(&pin->dev);
}

View File

@@ -10,22 +10,119 @@
#ifdef MR_USING_SERIAL
MR_INLINE ssize_t serial_poll_read(struct mr_serial *serial, uint8_t *buf, size_t count)
{
struct mr_serial_ops *ops = (struct mr_serial_ops *)serial->dev.drv->ops;
ssize_t size;
for (size = 0; size < count; size += sizeof(*buf)) {
int ret = ops->read(serial, buf);
if (ret < 0) {
return (size == 0) ? ret : size;
}
buf++;
}
return size;
}
MR_INLINE ssize_t serial_poll_write(struct mr_serial *serial, uint8_t *buf, size_t count)
{
struct mr_serial_ops *ops = (struct mr_serial_ops *)serial->dev.drv->ops;
ssize_t size;
for (size = 0; size < count; size += sizeof(*buf)) {
int ret = ops->write(serial, *buf);
if (ret < 0) {
return (size == 0) ? ret : size;
}
buf++;
}
return size;
}
#ifdef MR_USING_SERIAL_DMA
MR_INLINE ssize_t serial_dma_write(struct mr_serial *serial, uint8_t *buf, size_t count)
{
struct mr_serial_ops *ops = (struct mr_serial_ops *)serial->dev.drv->ops;
if (serial->dma_wr_bufsz == 0) {
if (serial->nonblock_state == MR_DISABLE) {
ops->start_dma_tx(serial, buf, count);
return (ssize_t)count;
} else {
return MR_EBUSY;
}
} else {
if (serial->nonblock_state == MR_DISABLE) {
if (count > serial->dma_wr_bufsz) {
memcpy(serial->dma_wr_buf, buf, serial->dma_wr_bufsz);
ops->start_dma_tx(serial, serial->dma_wr_buf, serial->dma_wr_bufsz);
return (ssize_t)(serial->dma_wr_bufsz +
mr_ringbuf_write(&serial->wr_fifo,
buf + serial->dma_wr_bufsz,
count - serial->dma_wr_bufsz));
} else {
memcpy(serial->dma_wr_buf, buf, count);
ops->start_dma_tx(serial, serial->dma_wr_buf, count);
return (ssize_t)count;
}
} else {
return (ssize_t)mr_ringbuf_write(&serial->wr_fifo, buf, count);
}
}
}
#endif /* MR_USING_SERIAL_DMA */
MR_INLINE ssize_t serial_nonblocking_write(struct mr_serial *serial, uint8_t *buf, size_t count)
{
struct mr_serial_ops *ops = (struct mr_serial_ops *)serial->dev.drv->ops;
ssize_t size;
#ifdef MR_USING_SERIAL_DMA
/* DMA sending */
if ((ops->start_dma_tx != MR_NULL) && (ops->stop_dma_tx != MR_NULL)) {
return serial_dma_write(serial, buf, count);
}
#endif /* MR_USING_SERIAL_DMA */
/* Interrupt sending */
size = (ssize_t)mr_ringbuf_write(&serial->wr_fifo, buf, count);
if ((size > 0) && (serial->nonblock_state == MR_DISABLE)) {
ops->start_tx(serial);
}
return size;
}
static int mr_serial_open(struct mr_dev *dev)
{
struct mr_serial *serial = (struct mr_serial *)dev;
struct mr_serial_ops *ops = (struct mr_serial_ops *)dev->drv->ops;
int ret = mr_ringbuf_allocate(&serial->rd_fifo, serial->rd_bufsz);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
ret = mr_ringbuf_allocate(&serial->wr_fifo, serial->wr_bufsz);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
#ifdef MR_USING_SERIAL_DMA
serial->dma_rd_buf = (uint8_t *)mr_malloc(serial->dma_rd_bufsz);
if ((serial->dma_rd_buf == MR_NULL) && (serial->dma_rd_bufsz != 0)) {
return MR_ENOMEM;
}
serial->dma_wr_buf = (uint8_t *)mr_malloc(serial->dma_wr_bufsz);
if ((serial->dma_wr_buf == MR_NULL) && (serial->dma_wr_bufsz != 0)) {
return MR_ENOMEM;
}
/* Configure DMA */
if ((ops->start_dma_rx != MR_NULL) && (serial->dma_rd_bufsz != 0)) {
ops->start_dma_rx(serial, serial->dma_rd_buf, serial->dma_rd_bufsz);
}
#endif /* MR_USING_SERIAL_DMA */
return ops->configure(serial, &serial->config);
}
@@ -38,29 +135,23 @@ static int mr_serial_close(struct mr_dev *dev)
mr_ringbuf_free(&serial->rd_fifo);
mr_ringbuf_free(&serial->wr_fifo);
#ifdef MR_USING_SERIAL_DMA
mr_free(serial->dma_rd_buf);
mr_free(serial->dma_wr_buf);
#endif /* MR_USING_SERIAL_DMA */
return ops->configure(serial, &close_config);
}
static ssize_t mr_serial_read(struct mr_dev *dev, void *buf, size_t count)
{
struct mr_serial *serial = (struct mr_serial *)dev;
struct mr_serial_ops *ops = (struct mr_serial_ops *)dev->drv->ops;
uint8_t *rd_buf = (uint8_t *)buf;
ssize_t rd_size;
if (mr_ringbuf_get_bufsz(&serial->rd_fifo) == 0)
{
for (rd_size = 0; rd_size < count; rd_size += sizeof(*rd_buf))
{
int ret = ops->read(serial, rd_buf);
if (ret < 0)
{
return (rd_size == 0) ? ret : rd_size;
}
rd_buf++;
}
} else
{
if (mr_ringbuf_get_bufsz(&serial->rd_fifo) == 0) {
rd_size = serial_poll_read(serial, rd_buf, count);
} else {
rd_size = (ssize_t)mr_ringbuf_read(&serial->rd_fifo, buf, count);
}
return rd_size;
@@ -69,29 +160,13 @@ static ssize_t mr_serial_read(struct mr_dev *dev, void *buf, size_t count)
static ssize_t mr_serial_write(struct mr_dev *dev, const void *buf, size_t count)
{
struct mr_serial *serial = (struct mr_serial *)dev;
struct mr_serial_ops *ops = (struct mr_serial_ops *)dev->drv->ops;
uint8_t *wr_buf = (uint8_t *)buf;
ssize_t wr_size;
if (dev->sync == MR_SYNC)
{
for (wr_size = 0; wr_size < count; wr_size += sizeof(*wr_buf))
{
int ret = ops->write(serial, *wr_buf);
if (ret < 0)
{
return (wr_size == 0) ? ret : wr_size;
}
wr_buf++;
}
} else
{
wr_size = (ssize_t)mr_ringbuf_write(&serial->wr_fifo, buf, count);
if (wr_size > 0)
{
/* Start interrupt sending */
ops->start_tx(serial);
}
if (dev->sync == MR_SYNC) {
wr_size = serial_poll_write(serial, wr_buf, count);
} else {
wr_size = serial_nonblocking_write(serial, wr_buf, count);
}
return wr_size;
}
@@ -101,17 +176,13 @@ static int mr_serial_ioctl(struct mr_dev *dev, int cmd, void *args)
struct mr_serial *serial = (struct mr_serial *)dev;
struct mr_serial_ops *ops = (struct mr_serial_ops *)dev->drv->ops;
switch (cmd)
{
case MR_IOC_SERIAL_SET_CONFIG:
{
if (args != MR_NULL)
{
switch (cmd) {
case MR_IOC_SERIAL_SET_CONFIG: {
if (args != MR_NULL) {
struct mr_serial_config config = *(struct mr_serial_config *)args;
int ret = ops->configure(serial, &config);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
serial->config = config;
@@ -119,16 +190,13 @@ static int mr_serial_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_SERIAL_SET_RD_BUFSZ:
{
if (args != MR_NULL)
{
case MR_IOC_SERIAL_SET_RD_BUFSZ: {
if (args != MR_NULL) {
size_t bufsz = *(size_t *)args;
int ret = mr_ringbuf_allocate(&serial->rd_fifo, bufsz);
serial->rd_bufsz = 0;
if (ret < 0)
{
if (ret < 0) {
return ret;
}
serial->rd_bufsz = bufsz;
@@ -136,16 +204,13 @@ static int mr_serial_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_SERIAL_SET_WR_BUFSZ:
{
if (args != MR_NULL)
{
case MR_IOC_SERIAL_SET_WR_BUFSZ: {
if (args != MR_NULL) {
size_t bufsz = *(size_t *)args;
int ret = mr_ringbuf_allocate(&serial->wr_fifo, bufsz);
serial->wr_bufsz = 0;
if (ret < 0)
{
if (ret < 0) {
return ret;
}
serial->wr_bufsz = bufsz;
@@ -153,20 +218,16 @@ static int mr_serial_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_SERIAL_CLR_RD_BUF:
{
case MR_IOC_SERIAL_CLR_RD_BUF: {
mr_ringbuf_reset(&serial->rd_fifo);
return MR_EOK;
}
case MR_IOC_SERIAL_CLR_WR_BUF:
{
case MR_IOC_SERIAL_CLR_WR_BUF: {
mr_ringbuf_reset(&serial->wr_fifo);
return MR_EOK;
}
case MR_IOC_SERIAL_GET_CONFIG:
{
if (args != MR_NULL)
{
case MR_IOC_SERIAL_GET_CONFIG: {
if (args != MR_NULL) {
struct mr_serial_config *config = (struct mr_serial_config *)args;
*config = serial->config;
@@ -174,10 +235,8 @@ static int mr_serial_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_SERIAL_GET_RD_BUFSZ:
{
if (args != MR_NULL)
{
case MR_IOC_SERIAL_GET_RD_BUFSZ: {
if (args != MR_NULL) {
size_t *bufsz = (size_t *)args;
*bufsz = serial->rd_bufsz;
@@ -185,10 +244,8 @@ static int mr_serial_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_SERIAL_GET_WR_BUFSZ:
{
if (args != MR_NULL)
{
case MR_IOC_SERIAL_GET_WR_BUFSZ: {
if (args != MR_NULL) {
size_t *bufsz = (size_t *)args;
*bufsz = serial->wr_bufsz;
@@ -196,10 +253,8 @@ static int mr_serial_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_SERIAL_GET_RD_DATASZ:
{
if (args != MR_NULL)
{
case MR_IOC_SERIAL_GET_RD_DATASZ: {
if (args != MR_NULL) {
size_t *datasz = (size_t *)args;
*datasz = mr_ringbuf_get_data_size(&serial->rd_fifo);
@@ -207,10 +262,8 @@ static int mr_serial_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_SERIAL_GET_WR_DATASZ:
{
if (args != MR_NULL)
{
case MR_IOC_SERIAL_GET_WR_DATASZ: {
if (args != MR_NULL) {
size_t *datasz = (size_t *)args;
*datasz = mr_ringbuf_get_data_size(&serial->wr_fifo);
@@ -218,8 +271,64 @@ static int mr_serial_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
default:
{
#ifdef MR_USING_SERIAL_DMA
case MR_IOC_SERIAL_SET_RD_DMA_BUFSZ: {
if (args != MR_NULL) {
size_t bufsz = *(size_t *)args;
if (ops->stop_dma_rx) {
return MR_EIO;
}
ops->stop_dma_rx(serial);
uint8_t *pool = mr_realloc(serial->dma_rd_buf, bufsz);
if ((pool == MR_NULL) && (bufsz != 0)) {
return MR_ENOMEM;
}
serial->dma_rd_buf = pool;
serial->dma_rd_bufsz = bufsz;
if ((ops->start_dma_rx != MR_NULL) && (serial->dma_rd_bufsz != 0)) {
ops->start_dma_rx(serial, serial->dma_rd_buf, serial->dma_rd_bufsz);
}
return sizeof(bufsz);
}
return MR_EINVAL;
}
case MR_IOC_SERIAL_SET_WR_DMA_BUFSZ: {
if (args != MR_NULL) {
size_t bufsz = *(size_t *)args;
uint8_t *pool = mr_realloc(serial->dma_wr_buf, bufsz);
if ((pool == MR_NULL) && (bufsz != 0)) {
return MR_ENOMEM;
}
serial->dma_wr_buf = pool;
serial->dma_wr_bufsz = bufsz;
return sizeof(bufsz);
}
return MR_EINVAL;
}
case MR_IOC_SERIAL_GET_RD_DMA_BUFSZ: {
if (args != MR_NULL) {
size_t *bufsz = (size_t *)args;
*bufsz = serial->dma_rd_bufsz;
return sizeof(*bufsz);
}
return MR_EINVAL;
}
case MR_IOC_SERIAL_GET_WR_DMA_BUFSZ: {
if (args != MR_NULL) {
size_t *bufsz = (size_t *)args;
*bufsz = serial->dma_wr_bufsz;
return sizeof(*bufsz);
}
return MR_EINVAL;
}
#endif /* MR_USING_SERIAL_DMA */
default: {
return MR_ENOTSUP;
}
}
@@ -230,39 +339,67 @@ static ssize_t mr_serial_isr(struct mr_dev *dev, int event, void *args)
struct mr_serial *serial = (struct mr_serial *)dev;
struct mr_serial_ops *ops = (struct mr_serial_ops *)dev->drv->ops;
switch (event)
{
case MR_ISR_SERIAL_RD_INT:
{
switch (event) {
case MR_ISR_SERIAL_RD_INT: {
uint8_t data;
/* Read data to FIFO */
int ret = ops->read(serial, &data);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
mr_ringbuf_push_force(&serial->rd_fifo, data);
return (ssize_t)mr_ringbuf_get_data_size(&serial->rd_fifo);
return MR_EOK;
}
case MR_ISR_SERIAL_WR_INT:
{
case MR_ISR_SERIAL_WR_INT: {
uint8_t data;
/* Write data from FIFO, if FIFO is empty, stop transmit */
if (mr_ringbuf_pop(&serial->wr_fifo, &data) == sizeof(data))
{
if (mr_ringbuf_pop(&serial->wr_fifo, &data) == sizeof(data)) {
ops->write(serial, data);
return MR_EBUSY;
} else
{
} else {
serial->nonblock_state = MR_DISABLE;
ops->stop_tx(serial);
return MR_EOK;
}
}
default:
{
#ifdef MR_USING_SERIAL_DMA
case MR_ISR_SERIAL_RD_DMA: {
if (args != MR_NULL) {
size_t dma_rx_datasz = *(size_t *)args;
mr_ringbuf_write_force(&serial->rd_fifo,
serial->dma_rd_buf,
MR_BOUND(dma_rx_datasz, 0, serial->dma_rd_bufsz));
if (ops->start_dma_rx != MR_NULL) {
ops->start_dma_rx(serial, serial->dma_rd_buf, serial->dma_rd_bufsz);
}
return MR_EOK;
}
return MR_EINVAL;
}
case MR_ISR_SERIAL_WR_DMA: {
if (serial->dma_wr_bufsz == 0) {
serial->nonblock_state = MR_DISABLE;
ops->stop_dma_tx(serial);
return MR_EOK;
} else {
size_t size = mr_ringbuf_read(&serial->wr_fifo,
serial->dma_wr_buf,
serial->dma_wr_bufsz);
if (size != 0) {
ops->start_dma_tx(serial, serial->dma_wr_buf, size);
return MR_EBUSY;
} else {
serial->nonblock_state = MR_DISABLE;
ops->stop_dma_tx(serial);
return MR_EOK;
}
}
}
#endif /* MR_USING_SERIAL_DMA */
default: {
return MR_ENOTSUP;
}
}
@@ -279,15 +416,12 @@ static ssize_t mr_serial_isr(struct mr_dev *dev, int event, void *args)
*/
int mr_serial_register(struct mr_serial *serial, const char *path, struct mr_drv *drv)
{
static struct mr_dev_ops ops =
{
mr_serial_open,
mr_serial_close,
mr_serial_read,
mr_serial_write,
mr_serial_ioctl,
mr_serial_isr
};
static struct mr_dev_ops ops = {mr_serial_open,
mr_serial_close,
mr_serial_read,
mr_serial_write,
mr_serial_ioctl,
mr_serial_isr};
struct mr_serial_config default_config = MR_SERIAL_CONFIG_DEFAULT;
MR_ASSERT(serial != MR_NULL);
@@ -307,9 +441,27 @@ int mr_serial_register(struct mr_serial *serial, const char *path, struct mr_drv
#endif /* MR_CFG_SERIAL_WR_BUFSZ */
serial->rd_bufsz = MR_CFG_SERIAL_RD_BUFSZ;
serial->wr_bufsz = MR_CFG_SERIAL_WR_BUFSZ;
#ifdef MR_USING_SERIAL_DMA
serial->dma_rd_buf = MR_NULL;
serial->dma_wr_buf = MR_NULL;
#ifndef MR_CFG_SERIAL_RD_DMA_BUFSZ
#define MR_CFG_SERIAL_RD_DMA_BUFSZ (0)
#endif /* MR_CFG_SERIAL_RD_DMA_BUFSZ */
#ifndef MR_CFG_SERIAL_WR_DMA_BUFSZ
#define MR_CFG_SERIAL_WR_DMA_BUFSZ (0)
#endif /* MR_CFG_SERIAL_WR_DMA_BUFSZ */
serial->dma_rd_bufsz = MR_CFG_SERIAL_RD_DMA_BUFSZ;
serial->dma_wr_bufsz = MR_CFG_SERIAL_WR_DMA_BUFSZ;
#endif /* MR_USING_SERIAL_DMA */
serial->nonblock_state = MR_DISABLE;
/* Register the serial */
return mr_dev_register(&serial->dev, path, MR_DEV_TYPE_SERIAL, MR_O_RDWR | MR_O_NONBLOCK, &ops, drv);
return mr_dev_register(&serial->dev,
path,
MR_DEV_TYPE_SERIAL,
MR_O_RDWR | MR_O_NONBLOCK,
&ops,
drv);
}
#endif /* MR_USING_SERIAL */

View File

@@ -36,8 +36,7 @@ static int mr_spi_bus_close(struct mr_dev *dev)
struct mr_spi_config close_config = {0};
#ifdef MR_USING_PIN
if (spi_bus->cs_desc >= 0)
{
if (spi_bus->cs_desc >= 0) {
mr_dev_close(spi_bus->cs_desc);
spi_bus->cs_desc = -1;
}
@@ -60,25 +59,22 @@ static ssize_t mr_spi_bus_isr(struct mr_dev *dev, int event, void *args)
struct mr_spi_bus *spi_bus = (struct mr_spi_bus *)dev;
struct mr_spi_bus_ops *ops = (struct mr_spi_bus_ops *)dev->drv->ops;
switch (event)
{
case MR_ISR_SPI_RD_INT:
{
switch (event) {
case MR_ISR_SPI_RD_INT: {
struct mr_spi_dev *spi_dev = (struct mr_spi_dev *)spi_bus->owner;
uint8_t data;
/* Read data to FIFO */
int ret = ops->read(spi_bus, &data);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
mr_ringbuf_write_force(&spi_dev->rd_fifo, &data, sizeof(data));
return (ssize_t)mr_ringbuf_get_data_size(&spi_dev->rd_fifo);;
/* Call the spi-dev ISR */
return mr_dev_isr(&spi_dev->dev, event, MR_NULL);
}
default:
{
default: {
return MR_ENOTSUP;
}
}
@@ -95,15 +91,12 @@ static ssize_t mr_spi_bus_isr(struct mr_dev *dev, int event, void *args)
*/
int mr_spi_bus_register(struct mr_spi_bus *spi_bus, const char *path, struct mr_drv *drv)
{
static struct mr_dev_ops ops =
{
mr_spi_bus_open,
mr_spi_bus_close,
mr_spi_bus_read,
mr_spi_bus_write,
MR_NULL,
mr_spi_bus_isr
};
static struct mr_dev_ops ops = {mr_spi_bus_open,
mr_spi_bus_close,
mr_spi_bus_read,
mr_spi_bus_write,
MR_NULL,
mr_spi_bus_isr};
struct mr_spi_config default_config = MR_SPI_CONFIG_DEFAULT;
MR_ASSERT(spi_bus != MR_NULL);
@@ -127,30 +120,24 @@ static void spi_dev_cs_configure(struct mr_spi_dev *spi_dev, int state)
struct mr_spi_bus *spi_bus = (struct mr_spi_bus *)spi_dev->dev.parent;
int desc = spi_bus->cs_desc, old_number = -1;
if (desc < 0)
{
if (desc < 0) {
return;
}
if (spi_dev->cs_pin != -1)
{
if (spi_dev->cs_pin != -1) {
/* Temporarily store the old number */
mr_dev_ioctl(desc, MR_IOC_GPOS, &old_number);
/* Set the new number */
mr_dev_ioctl(desc, MR_IOC_SPOS, MR_MAKE_LOCAL(int, spi_dev->cs_pin));
if (state == MR_ENABLE)
{
if (spi_dev->config.host_slave == MR_SPI_HOST)
{
if (state == MR_ENABLE) {
if (spi_dev->config.host_slave == MR_SPI_HOST) {
mr_dev_ioctl(desc, MR_IOC_SCFG, MR_MAKE_LOCAL(int, MR_PIN_MODE_OUTPUT));
mr_dev_write(desc, MR_MAKE_LOCAL(uint8_t, !spi_dev->cs_active), sizeof(uint8_t));
} else
{
} else {
mr_dev_ioctl(desc, MR_IOC_SCFG, MR_MAKE_LOCAL(int, MR_PIN_MODE_NONE));
}
} else
{
} else {
mr_dev_ioctl(desc, MR_IOC_SCFG, MR_MAKE_LOCAL(int, MR_PIN_MODE_NONE));
}
@@ -165,13 +152,14 @@ MR_INLINE void spi_dev_cs_set(struct mr_spi_dev *spi_dev, int state)
#ifdef MR_USING_PIN
struct mr_spi_bus *spi_bus = (struct mr_spi_bus *)spi_dev->dev.parent;
if (spi_bus->cs_desc < 0)
{
if (spi_bus->cs_desc < 0) {
return;
}
/* Set the new state */
mr_dev_write(spi_bus->cs_desc, MR_MAKE_LOCAL(uint8_t, !(state ^ spi_dev->cs_active)), sizeof(uint8_t));
mr_dev_write(spi_bus->cs_desc,
MR_MAKE_LOCAL(uint8_t, !(state ^ spi_dev->cs_active)),
sizeof(uint8_t));
#endif /* MR_USING_PIN */
}
@@ -181,30 +169,25 @@ MR_INLINE int spi_dev_take_bus(struct mr_spi_dev *spi_dev)
struct mr_spi_bus_ops *ops = (struct mr_spi_bus_ops *)spi_bus->dev.drv->ops;
/* Check if the bus is busy */
if ((spi_bus->hold == MR_TRUE) && (spi_dev != spi_bus->owner))
{
if ((spi_bus->hold == MR_TRUE) && (spi_dev != spi_bus->owner)) {
return MR_EBUSY;
}
if (spi_dev != spi_bus->owner)
{
if (spi_dev != spi_bus->owner) {
/* Reconfigure the bus */
if (spi_dev->config.baud_rate != spi_bus->config.baud_rate
|| spi_dev->config.host_slave != spi_bus->config.host_slave
|| spi_dev->config.mode != spi_bus->config.mode
|| spi_dev->config.bit_order != spi_bus->config.bit_order)
{
if (spi_dev->config.baud_rate != spi_bus->config.baud_rate ||
spi_dev->config.host_slave != spi_bus->config.host_slave ||
spi_dev->config.mode != spi_bus->config.mode ||
spi_dev->config.bit_order != spi_bus->config.bit_order) {
int ret = ops->configure(spi_bus, &spi_dev->config);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
}
spi_bus->config = spi_dev->config;
spi_bus->owner = spi_dev;
#ifdef MR_USING_PIN
if ((spi_bus->cs_desc >= 0) && (spi_bus->config.host_slave == MR_SPI_HOST))
{
if ((spi_bus->cs_desc >= 0) && (spi_bus->config.host_slave == MR_SPI_HOST)) {
mr_dev_ioctl(spi_bus->cs_desc, MR_IOC_SPOS, MR_MAKE_LOCAL(int, spi_dev->cs_pin));
}
#endif /* MR_USING_PIN */
@@ -217,14 +200,12 @@ MR_INLINE int spi_dev_release_bus(struct mr_spi_dev *spi_dev)
{
struct mr_spi_bus *spi_bus = (struct mr_spi_bus *)spi_dev->dev.parent;
if (spi_dev != spi_bus->owner)
{
if (spi_dev != spi_bus->owner) {
return MR_EINVAL;
}
/* If it is a host, release the bus. The slave needs to hold the bus at all times */
if (spi_dev->config.host_slave == MR_SPI_HOST)
{
if (spi_dev->config.host_slave == MR_SPI_HOST) {
spi_bus->hold = MR_FALSE;
}
return MR_EOK;
@@ -244,43 +225,35 @@ static ssize_t spi_dev_transfer(struct mr_spi_dev *spi_dev,
struct mr_spi_bus_ops *ops = (struct mr_spi_bus_ops *)spi_bus->dev.drv->ops;
ssize_t tf_size;
if (rdwr == MR_SPI_RD)
{
for (tf_size = 0; tf_size < size; tf_size += sizeof(*rd_buf))
{
if (rdwr == MR_SPI_RD) {
for (tf_size = 0; tf_size < size; tf_size += sizeof(*rd_buf)) {
ops->write(spi_bus, 0);
int ret = ops->read(spi_bus, rd_buf);
if (ret < 0)
{
if (ret < 0) {
return (tf_size == 0) ? ret : tf_size;
}
rd_buf++;
}
} else if (rdwr == MR_SPI_WR)
{
for (tf_size = 0; tf_size < size; tf_size += sizeof(*wr_buf))
{
} else if (rdwr == MR_SPI_WR) {
for (tf_size = 0; tf_size < size; tf_size += sizeof(*wr_buf)) {
int ret = ops->write(spi_bus, *wr_buf);
if (ret < 0)
{
if (ret < 0) {
return (tf_size == 0) ? ret : tf_size;
}
ops->read(spi_bus, MR_MAKE_LOCAL(uint8_t, 0));
wr_buf++;
}
} else
{
for (tf_size = 0; tf_size < MR_ALIGN_DOWN(size, sizeof(*wr_buf)); tf_size += sizeof(*wr_buf))
{
} else {
for (tf_size = 0;
tf_size < MR_ALIGN_DOWN(size, sizeof(*wr_buf));
tf_size += sizeof(*wr_buf)) {
int ret = ops->write(spi_bus, *wr_buf);
if (ret < 0)
{
if (ret < 0) {
return (tf_size == 0) ? ret : tf_size;
}
ret = ops->read(spi_bus, rd_buf);
if (ret < 0)
{
if (ret < 0) {
return (tf_size == 0) ? ret : tf_size;
}
rd_buf++;
@@ -320,25 +293,21 @@ static ssize_t mr_spi_dev_read(struct mr_dev *dev, void *buf, size_t count)
struct mr_spi_dev *spi_dev = (struct mr_spi_dev *)dev;
ssize_t ret = spi_dev_take_bus(spi_dev);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
if (spi_dev->config.host_slave == MR_SPI_HOST)
{
if (spi_dev->config.host_slave == MR_SPI_HOST) {
spi_dev_cs_set(spi_dev, MR_ENABLE);
/* Send the address of the register that needs to be read */
if (dev->position >= 0)
{
if (dev->position >= 0) {
ret = spi_dev_transfer(spi_dev,
MR_NULL,
(uint8_t *)&dev->position,
(spi_dev->config.reg_bits >> 3),
MR_SPI_WR);
if (ret < 0)
{
if (ret < 0) {
spi_dev_cs_set(spi_dev, MR_DISABLE);
spi_dev_release_bus(spi_dev);
return ret;
@@ -347,8 +316,7 @@ static ssize_t mr_spi_dev_read(struct mr_dev *dev, void *buf, size_t count)
ret = spi_dev_transfer(spi_dev, buf, MR_NULL, count, MR_SPI_RD);
spi_dev_cs_set(spi_dev, MR_DISABLE);
} else
{
} else {
ret = (ssize_t)mr_ringbuf_read(&spi_dev->rd_fifo, buf, count);
}
@@ -361,25 +329,21 @@ static ssize_t mr_spi_dev_write(struct mr_dev *dev, const void *buf, size_t coun
struct mr_spi_dev *spi_dev = (struct mr_spi_dev *)dev;
ssize_t ret = spi_dev_take_bus(spi_dev);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
if (spi_dev->config.host_slave == MR_SPI_HOST)
{
if (spi_dev->config.host_slave == MR_SPI_HOST) {
spi_dev_cs_set(spi_dev, MR_ENABLE);
/* Send the address of the register that needs to be written */
if (dev->position >= 0)
{
if (dev->position >= 0) {
ret = spi_dev_transfer(spi_dev,
MR_NULL,
(uint8_t *)&dev->position,
(spi_dev->config.reg_bits >> 3),
MR_SPI_WR);
if (ret < 0)
{
if (ret < 0) {
spi_dev_cs_set(spi_dev, MR_DISABLE);
spi_dev_release_bus(spi_dev);
return ret;
@@ -388,8 +352,7 @@ static ssize_t mr_spi_dev_write(struct mr_dev *dev, const void *buf, size_t coun
ret = spi_dev_transfer(spi_dev, MR_NULL, buf, count, MR_SPI_WR);
spi_dev_cs_set(spi_dev, MR_DISABLE);
} else
{
} else {
ret = spi_dev_transfer(spi_dev, MR_NULL, buf, count, MR_SPI_WR);
}
@@ -401,38 +364,31 @@ static int mr_spi_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
{
struct mr_spi_dev *spi_dev = (struct mr_spi_dev *)dev;
switch (cmd)
{
case MR_IOC_SPI_SET_CONFIG:
{
if (args != MR_NULL)
{
switch (cmd) {
case MR_IOC_SPI_SET_CONFIG: {
if (args != MR_NULL) {
struct mr_spi_bus *spi_bus = (struct mr_spi_bus *)dev->parent;
struct mr_spi_config config = *(struct mr_spi_config *)args;
#ifdef MR_USING_PIN
/* Reconfigure CS */
if (config.host_slave != spi_dev->config.host_slave)
{
if (config.host_slave != spi_dev->config.host_slave) {
spi_dev->config = config;
spi_dev_cs_configure(spi_dev, MR_ENABLE);
}
#endif /* MR_USING_PIN */
/* If holding the bus, release it */
if (spi_dev == spi_bus->owner)
{
if (spi_dev == spi_bus->owner) {
spi_bus->hold = MR_FALSE;
spi_bus->owner = MR_NULL;
}
/* Update the configuration and try again to get the bus */
spi_dev->config = config;
if (config.host_slave == MR_SPI_SLAVE)
{
if (config.host_slave == MR_SPI_SLAVE) {
int ret = spi_dev_take_bus(spi_dev);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
}
@@ -440,16 +396,13 @@ static int mr_spi_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_SPI_SET_RD_BUFSZ:
{
if (args != MR_NULL)
{
case MR_IOC_SPI_SET_RD_BUFSZ: {
if (args != MR_NULL) {
size_t bufsz = *(size_t *)args;
int ret = mr_ringbuf_allocate(&spi_dev->rd_fifo, bufsz);
spi_dev->rd_bufsz = 0;
if (ret < 0)
{
if (ret < 0) {
return ret;
}
spi_dev->rd_bufsz = bufsz;
@@ -457,25 +410,20 @@ static int mr_spi_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_SPI_CLR_RD_BUF:
{
case MR_IOC_SPI_CLR_RD_BUF: {
mr_ringbuf_reset(&spi_dev->rd_fifo);
return MR_EOK;
}
case MR_IOC_SPI_TRANSFER:
{
if (args != MR_NULL)
{
case MR_IOC_SPI_TRANSFER: {
if (args != MR_NULL) {
struct mr_spi_transfer transfer = *(struct mr_spi_transfer *)args;
int ret = spi_dev_take_bus(spi_dev);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
if (spi_dev->config.host_slave == MR_SPI_HOST)
{
if (spi_dev->config.host_slave == MR_SPI_HOST) {
spi_dev_cs_set(spi_dev, MR_ENABLE);
ret = (int)spi_dev_transfer(dev->parent,
transfer.rd_buf,
@@ -483,8 +431,7 @@ static int mr_spi_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
transfer.size,
MR_SPI_RDWR);
spi_dev_cs_set(spi_dev, MR_DISABLE);
} else
{
} else {
ret = (int)spi_dev_transfer(dev->parent,
transfer.rd_buf,
transfer.wr_buf,
@@ -497,10 +444,8 @@ static int mr_spi_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_SPI_GET_CONFIG:
{
if (args != MR_NULL)
{
case MR_IOC_SPI_GET_CONFIG: {
if (args != MR_NULL) {
struct mr_spi_config *config = (struct mr_spi_config *)args;
*config = spi_dev->config;
@@ -508,10 +453,8 @@ static int mr_spi_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_SPI_GET_RD_BUFSZ:
{
if (args != MR_NULL)
{
case MR_IOC_SPI_GET_RD_BUFSZ: {
if (args != MR_NULL) {
size_t *bufsz = (size_t *)args;
*bufsz = spi_dev->rd_bufsz;
@@ -519,10 +462,8 @@ static int mr_spi_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_SPI_GET_RD_DATASZ:
{
if (args != MR_NULL)
{
case MR_IOC_SPI_GET_RD_DATASZ: {
if (args != MR_NULL) {
size_t *datasz = (size_t *)args;
*datasz = mr_ringbuf_get_data_size(&spi_dev->rd_fifo);
@@ -530,8 +471,7 @@ static int mr_spi_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
}
return MR_EINVAL;
}
default:
{
default: {
return MR_ENOTSUP;
}
}
@@ -549,15 +489,12 @@ static int mr_spi_dev_ioctl(struct mr_dev *dev, int cmd, void *args)
*/
int mr_spi_dev_register(struct mr_spi_dev *spi_dev, const char *path, int cs_pin, int cs_active)
{
static struct mr_dev_ops ops =
{
mr_spi_dev_open,
mr_spi_dev_close,
mr_spi_dev_read,
mr_spi_dev_write,
mr_spi_dev_ioctl,
MR_NULL
};
static struct mr_dev_ops ops = {mr_spi_dev_open,
mr_spi_dev_close,
mr_spi_dev_read,
mr_spi_dev_write,
mr_spi_dev_ioctl,
MR_NULL};
struct mr_spi_config default_config = MR_SPI_CONFIG_DEFAULT;
MR_ASSERT(spi_dev != MR_NULL);

View File

@@ -230,9 +230,6 @@ mr_dev_ioctl(ds, MR_IOC_GRBDSZ, &size);
/* 定义回调函数 */
void fn(int desc, void *args)
{
/* 获取缓冲区数据大小 */
ssize_t data_size = *(ssize_t *)args;
/* 处理中断 */
}
void (*callback)(int desc, void *args);
@@ -249,9 +246,6 @@ mr_dev_ioctl(ds, MR_IOC_I2C_GET_RD_CALL, &callback);
/* 定义回调函数 */
void fn(int desc, void *args)
{
/* 获取缓冲区数据大小 */
ssize_t data_size = *(ssize_t *)args;
/* 处理中断 */
}
void (*callback)(int desc, void *args);

View File

@@ -37,7 +37,7 @@ int mr_i2c_dev_register(struct mr_i2c_dev *i2c_dev, const char *path, int addr,
| `=0` | Registration succeeds |
| `<0` | Error code |
- `name`: The I2C device needs to bind to the specified I2C bus, and the name needs to add the bus name, such
- `name`: The I2C device needs to bind to the specified I2C spi_bus, and the name needs to add the spi_bus name, such
as: `i2cx/dev-name`, `i2c1/i2c10`.
- `addr`: Device address (the lowest bit is read/write bit, please pass the address shifted to the left).
When serving as a host, the address is the peer's address. When serving as a slave, the address is its own address.
@@ -142,7 +142,7 @@ Note:
- Baud rate: `100000`
- Master/slave mode: `MR_I2C_HOST`
- Register bits: `MR_I2C_REG_BITS_8`
- When an I2C device on the I2C bus is configured to slave mode, it will continuously occupy the I2C bus. At this point,
- When an I2C device on the I2C spi_bus is configured to slave mode, it will continuously occupy the I2C spi_bus. At this point,
other I2C devices cannot perform read/write operations until the I2C device in slave mode is reconfigured to master
mode.
@@ -237,9 +237,6 @@ mr_dev_ioctl(ds, MR_IOC_GRBDSZ, &size);
/* Define callback function */
void fn(int desc, void *args)
{
/* Get buffer data size */
ssize_t data_size = *(ssize_t *)args;
/* Handle interrupt */
}
void (*callback)(int desc, void *args);
@@ -256,9 +253,6 @@ Independent of I2C interface:
/* Define callback function */
void fn(int desc, void *args)
{
/* Get buffer data size */
ssize_t data_size = *(ssize_t *)args;
/* Handle interrupt */
}
void (*callback)(int desc, void *args);
@@ -441,7 +435,7 @@ int mr_soft_i2c_bus_register(struct mr_soft_i2c_bus *soft_i2c_bus, const char *p
| Parameter | Description |
|------------------|------------------------------------|
| soft_i2c_bus | Software I2C bus structure pointer |
| soft_i2c_bus | Software I2C spi_bus structure pointer |
| path | Bus path |
| scl_pin | SCL pin number |
| sda_pin | SDA pin number |
@@ -450,17 +444,17 @@ int mr_soft_i2c_bus_register(struct mr_soft_i2c_bus *soft_i2c_bus, const char *p
| `<0` | Error code |
```c
/* Define SCL, SDA pin numbers for software I2C bus */
/* Define SCL, SDA pin numbers for software I2C spi_bus */
#define SCL_PIN_NUMBER 0
#define SDA_PIN_NUMBER 1
/* Define software I2C bus */
/* Define software I2C spi_bus */
struct mr_soft_i2c_bus soft_i2c_bus;
/* Register software I2C bus */
/* Register software I2C spi_bus */
mr_soft_i2c_bus_register(&soft_i2c_bus, "i2c1", SCL_PIN_NUMBER, SDA_PIN_NUMBER);
```
After registration, the software I2C bus will simulate a hardware I2C.
After registration, the software I2C spi_bus will simulate a hardware I2C.
Note: The software I2C bus only supports master mode.
Note: The software I2C spi_bus only supports master mode.

View File

@@ -71,6 +71,7 @@ int mr_dev_ioctl(int desc, int cmd, void *args);
- `MR_IOC_PIN_SET_MODE`:设置引脚模式。
- `MR_IOC_PIN_SET_EXTI_CALL`:设置外部中断回调函数。
- `MR_IOC_PIN_GET_NUMBER`:获取引脚编号。
- `MR_IOC_PIN_GET_MODE`:获取引脚模式。
- `MR_IOC_PIN_GET_EXTI_CALL`:获取外部中断回调函数。
### 设置/获取引脚编号
@@ -110,7 +111,7 @@ int number;
mr_dev_ioctl(ds, MR_IOC_GPOS, &number);
```
### 设置引脚模式
### 设置/获取引脚模式
#### 引脚模式
@@ -137,6 +138,10 @@ mr_dev_ioctl(ds, MR_IOC_GPOS, &number);
/* 设置引脚模式 */
mr_dev_ioctl(ds, MR_IOC_PIN_SET_MODE, MR_MAKE_LOCAL(int, PIN_MODE));
/* 获取引脚模式 */
int mode;
mr_dev_ioctl(ds, MR_IOC_PIN_GET_MODE, &mode);
```
不依赖PIN接口
@@ -147,6 +152,10 @@ mr_dev_ioctl(ds, MR_IOC_PIN_SET_MODE, MR_MAKE_LOCAL(int, PIN_MODE));
/* 设置引脚模式 */
mr_dev_ioctl(ds, MR_IOC_SCFG, MR_MAKE_LOCAL(int, PIN_MODE));
/* 获取引脚模式 */
int mode;
mr_dev_ioctl(ds, MR_IOC_GCFG, &mode);
```
### 设置/获取外部中断回调函数
@@ -157,7 +166,7 @@ mr_dev_ioctl(ds, MR_IOC_SCFG, MR_MAKE_LOCAL(int, PIN_MODE));
void fn(int desc, void *args)
{
/* 获取引脚编号 */
ssize_t number = *(ssize_t *)args;
int number = *(int *)args;
if (number == PIN_NUMBER)
{
/* 处理外部中断事件 */
@@ -180,7 +189,7 @@ mr_dev_ioctl(ds, MR_IOC_PIN_GET_EXTI_CALL, &callback);
void fn(int desc, void *args)
{
/* 获取引脚编号 */
ssize_t number = *(ssize_t *)args;
int number = *(int *)args;
if (number == PIN_NUMBER)
{
/* 处理外部中断事件 */
@@ -268,7 +277,7 @@ int key_ds = -1;
void key_call(int desc, void *args)
{
ssize_t number = *((ssize_t *)args);
int number = *((int *)args);
if (number == KEY_PIN_NUMBER)
{

View File

@@ -73,6 +73,7 @@ int mr_dev_ioctl(int desc, int cmd, void *args);
- `MR_IOC_PIN_SET_MODE`: Set pin mode
- `MR_IOC_PIN_SET_EXTI_CALL`: Set external interrupt callback function
- `MR_IOC_PIN_GET_NUMBER`: Get pin number
- `MR_IOC_PIN_GET_MODE`: Get pin mode
- `MR_IOC_PIN_GET_EXTI_CALL`: Get external interrupt callback function
### Set/Get Pin Number
@@ -141,6 +142,10 @@ And 5 external interrupt modes:
/* Set pin mode */
mr_dev_ioctl(ds, MR_IOC_PIN_SET_MODE, MR_MAKE_LOCAL(int, PIN_MODE));
/* Get pin mode */
int mode;
mr_dev_ioctl(ds, MR_IOC_PIN_GET_MODE, &mode);
```
Independent of PIN interface:
@@ -151,6 +156,10 @@ Independent of PIN interface:
/* Set pin mode */
mr_dev_ioctl(ds, MR_IOC_SCFG, MR_MAKE_LOCAL(int, PIN_MODE));
/* Get pin mode */
int mode;
mr_dev_ioctl(ds, MR_IOC_GCFG, &mode);
```
### Set/Get External Interrupt Callback Function
@@ -161,7 +170,7 @@ mr_dev_ioctl(ds, MR_IOC_SCFG, MR_MAKE_LOCAL(int, PIN_MODE));
void fn(int desc, void *args)
{
/* Get pin number */
ssize_t number = *(ssize_t *)args;
int number = *(int *)args;
if (number == PIN_NUMBER)
{
/* Handle external interrupt event */
@@ -184,7 +193,7 @@ Independent of PIN interface:
void fn(int desc, void *args)
{
/* Get pin number */
ssize_t number = *(ssize_t *)args;
int number = *(int *)args;
if (number == PIN_NUMBER)
{
/* Handle external interrupt event */
@@ -272,7 +281,7 @@ int key_ds = -1;
void key_call(int desc, void *args)
{
ssize_t number = *((ssize_t *)args);
int number = *((int *)args);
if (number == KEY_PIN_NUMBER)
{

View File

@@ -17,12 +17,26 @@ extern "C" {
#ifdef MR_USING_CAN
/**
* @addtogroup CAN
* @{
*/
/**
* @brief CAN mode.
*/
#define MR_CAN_MODE_NORMAL (0) /**< Normal mode */
#define MR_CAN_MODE_LOOPBACK (1) /**< Loopback mode */
#define MR_CAN_MODE_SILENT (2) /**< Silent mode */
#define MR_CAN_MODE_SILENT_LOOPBACK (3) /**< Silent loopback mode */
/**
* @brief CAN default configuration.
*/
#define MR_CAN_CONFIG_DEFAULT \
{ \
500000, \
MR_CAN_MODE_NORMAL, \
}
/**
@@ -31,32 +45,22 @@ extern "C" {
struct mr_can_config
{
uint32_t baud_rate; /**< Baud rate */
int mode; /**< Mode */
};
/**
* @brief CAN identifier.
*/
#define MR_CAN_IDE_STD (0 << 29)
#define MR_CAN_IDE_EXT (1 << 29)
/**
* @brief CAN remote transmission request.
*/
#define MR_CAN_RTR_DATA (0 << 30)
#define MR_CAN_RTR_REMOTE (1 << 30)
/**
* @brief Help to set id.
*/
#define MR_CAN_ID(id, ide, rtr) ((id) | (ide) | (rtr)) /**< Set id-ide-rtr */
/**
* @brief CAN control command.
*/
#define MR_CTL_CAN_SET_ID MR_CTL_SET_OFFSET /**< Set id */
#define MR_CTL_CAN_GET_ID MR_CTL_GET_OFFSET /**< Get id */
#define MR_CTL_CAN_SET_RD_CALL MR_CTL_SET_RD_CALL /**< Set read call */
#define MR_CTL_CAN_GET_RD_CALL MR_CTL_GET_RD_CALL /**< Get read call */
#define MR_IOC_CAN_SET_CONFIG MR_IOC_SCFG /**< Set configuration command */
#define MR_IOC_CAN_SET_RD_BUFSZ MR_IOC_SRBSZ /**< Set read buffer size command */
#define MR_IOC_CAN_CLR_RD_BUF MR_IOC_CRBD /**< Clear read buffer command */
#define MR_IOC_CAN_SET_RD_CALL MR_IOC_SRCB /**< Set read callback command */
#define MR_IOC_CAN_REMOTE_REQUEST (0x01) /**< Remote request command */
#define MR_IOC_CAN_GET_CONFIG MR_IOC_GCFG /**< Get configuration command */
#define MR_IOC_CAN_GET_RD_BUFSZ MR_IOC_GRBSZ /**< Get read buffer size command */
#define MR_IOC_CAN_GET_RD_DATASZ MR_IOC_GRBDSZ /**< Get read data size command */
#define MR_IOC_CAN_GET_RD_CALL MR_IOC_GRCB /**< Get read callback command */
/**
* @brief CAN data type.
@@ -66,7 +70,7 @@ typedef uint8_t mr_can_data_t; /**< CAN rea
/**
* @brief CAN ISR events.
*/
#define MR_ISR_CAN_RD_INT (MR_ISR_RD | (0x01 << 8)) /**< Read interrupt */
#define MR_ISR_CAN_RD_INT (MR_ISR_RD | (0x01 << 8)) /**< Read interrupt event */
/**
* @brief CAN bus structure.
@@ -87,39 +91,35 @@ struct mr_can_bus_ops
{
int (*configure)(struct mr_can_bus *can_bus, struct mr_can_config *config);
int (*filter_configure)(struct mr_can_bus *can_bus, int id, int ide, int state);
int (*get_id)(struct mr_can_bus *can_bus);
ssize_t (*read)(struct mr_can_bus *can_bus, uint8_t *buf, size_t size);
ssize_t (*write)(struct mr_can_bus *can_bus, int id, int ide, int rtr, const uint8_t *buf, size_t size);
int (*read)(struct mr_can_bus *can_bus, int *id, int *ide, int *rtr, uint8_t *buf, size_t size);
ssize_t (*write)(struct mr_can_bus *can_bus, int id, int ide, const uint8_t *buf, size_t size);
int (*remote_request)(struct mr_can_bus *can_bus, int id, int ide);
};
/**
* @brief CAN id identifier.
* @brief CAN ID type.
*/
#define MR_CAN_ID_STD (0) /**< Standard identifier */
#define MR_CAN_ID_EXT (1) /**< Extended identifier */
#define MR_CAN_IDE_STD (0) /**< Standard ID */
#define MR_CAN_IDE_EXT (1) /**< Extended ID */
/**
* @brief CAN device structure.
*/
struct mr_can_dev
{
struct mr_dev dev;
struct mr_dev dev; /**< Device structure */
struct mr_can_config config;
struct mr_ringbuf rd_fifo;
size_t rd_bufsz;
uint32_t id: 29;
uint32_t ide: 1;
uint32_t reserved: 2;
struct mr_can_config config; /**< Configuration */
struct mr_ringbuf rd_fifo; /**< Read FIFO */
size_t rd_bufsz; /**< Read buffer size */
int id; /**< ID */
int ide; /**< ID type */
};
/**
* @addtogroup CAN.
* @{
*/
int mr_can_bus_register(struct mr_can_bus *can_bus, const char *name, struct mr_drv *drv);
int mr_can_dev_register(struct mr_can_dev *can_dev, const char *name, int id, int ide);
int mr_can_bus_register(struct mr_can_bus *can_bus, const char *path, struct mr_drv *drv);
int mr_can_dev_register(struct mr_can_dev *can_dev, const char *path, int id, int ide);
/** @} */
#endif /* MR_USING_CAN */
#ifdef __cplusplus

View File

@@ -35,11 +35,11 @@ extern "C" {
/**
* @brief PIN mode-interrupt.
*/
#define MR_PIN_MODE_IRQ_RISING (6) /**< Interrupt rising edge */
#define MR_PIN_MODE_IRQ_FALLING (7) /**< Interrupt falling edge */
#define MR_PIN_MODE_IRQ_EDGE (8) /**< Interrupt edge */
#define MR_PIN_MODE_IRQ_LOW (9) /**< Interrupt low level */
#define MR_PIN_MODE_IRQ_HIGH (10) /**< Interrupt high level */
#define MR_PIN_MODE_IRQ_RISING (6) /**< Interrupt rising edge mode */
#define MR_PIN_MODE_IRQ_FALLING (7) /**< Interrupt falling edge mode */
#define MR_PIN_MODE_IRQ_EDGE (8) /**< Interrupt edge mode */
#define MR_PIN_MODE_IRQ_LOW (9) /**< Interrupt low level mode */
#define MR_PIN_MODE_IRQ_HIGH (10) /**< Interrupt high level mode */
/**
* @brief PIN configuration structure.
@@ -57,6 +57,7 @@ struct mr_pin_config
#define MR_IOC_PIN_SET_EXTI_CALL MR_IOC_SRCB /**< Set pin exti callback command */
#define MR_IOC_PIN_GET_NUMBER MR_IOC_GPOS /**< Get pin number command */
#define MR_IOC_PIN_GET_MODE MR_IOC_GCFG /**< Get pin mode command */
#define MR_IOC_PIN_GET_EXTI_CALL MR_IOC_GRCB /**< Get pin exti callback command */
/**
@@ -67,7 +68,7 @@ typedef uint8_t mr_pin_data_t; /**< PIN rea
/**
* @brief PIN ISR events.
*/
#define MR_ISR_PIN_EXTI_INT (MR_ISR_RD | (0x01)) /**< Exti interrupt */
#define MR_ISR_PIN_EXTI_INT (MR_ISR_RD | (0x01)) /**< Exti interrupt event */
/**
* @brief PIN structure.
@@ -75,6 +76,8 @@ typedef uint8_t mr_pin_data_t; /**< PIN rea
struct mr_pin
{
struct mr_dev dev; /**< Device */
uint32_t pins[32]; /**< Pins */
};
/**
@@ -89,6 +92,7 @@ struct mr_pin_ops
int mr_pin_register(struct mr_pin *pin, const char *path, struct mr_drv *drv);
/** @} */
#endif /* MR_USING_PIN */
#ifdef __cplusplus

View File

@@ -8,14 +8,8 @@
#include "include/mr_api.h"
static struct mr_dev root_dev = /**< Root device */
{
.name = "dev",
.type = MR_DEV_TYPE_ROOT,
.parent = MR_NULL,
.list = MR_LIST_INIT(root_dev.list),
.clist = MR_LIST_INIT(root_dev.clist)
};
static struct mr_dev root_dev = {.name = "dev", .type = MR_DEV_TYPE_ROOT, .parent = MR_NULL, .list = MR_LIST_INIT(
root_dev.list), .clist = MR_LIST_INIT(root_dev.clist)}; /**< Root device */
#ifndef MR_CFG_DESC_NUM
#define MR_CFG_DESC_NUM (32)
@@ -38,11 +32,9 @@ MR_INLINE int dev_is_root(struct mr_dev *dev)
MR_INLINE struct mr_dev *dev_find_child(struct mr_dev *parent, const char *name)
{
for (struct mr_list *list = parent->clist.next; list != &parent->clist; list = list->next)
{
for (struct mr_list *list = parent->clist.next; list != &parent->clist; list = list->next) {
struct mr_dev *dev = (struct mr_dev *)MR_CONTAINER_OF(list, struct mr_dev, list);
if (strncmp(name, dev->name, MR_CFG_DEV_NAME_LEN) == 0)
{
if (strncmp(name, dev->name, MR_CFG_DEV_NAME_LEN) == 0) {
return dev;
}
}
@@ -51,8 +43,7 @@ MR_INLINE struct mr_dev *dev_find_child(struct mr_dev *parent, const char *name)
MR_INLINE int dev_register_child(struct mr_dev *parent, struct mr_dev *child, const char *name)
{
if (dev_find_child(parent, name) != MR_NULL)
{
if (dev_find_child(parent, name) != MR_NULL) {
return MR_EEXIST;
}
@@ -65,15 +56,13 @@ MR_INLINE int dev_register_child(struct mr_dev *parent, struct mr_dev *child, co
static int dev_register_by_path(struct mr_dev *parent, struct mr_dev *dev, const char *path)
{
if (path[0] == '/')
{
if (path[0] == '/') {
path++;
}
/* Check for child path separator */
const char *child_path = strchr(path, '/');
if (child_path != MR_NULL)
{
if (child_path != MR_NULL) {
char child_name[MR_CFG_DEV_NAME_LEN + 1] = {0};
size_t len = MR_BOUND(child_path - path, 0, MR_CFG_DEV_NAME_LEN);
@@ -81,15 +70,13 @@ static int dev_register_by_path(struct mr_dev *parent, struct mr_dev *dev, const
strncpy(child_name, path, len);
child_name[len] = '\0';
struct mr_dev *child = dev_find_child(parent, child_name);
if (child == MR_NULL)
{
if (child == MR_NULL) {
return MR_ENOTFOUND;
}
/* Register recursively */
return dev_register_by_path(child, dev, child_path);
} else
{
} else {
/* Register with parent */
return dev_register_child(parent, dev, path);
}
@@ -97,15 +84,13 @@ static int dev_register_by_path(struct mr_dev *parent, struct mr_dev *dev, const
static struct mr_dev *dev_find_by_path(struct mr_dev *parent, const char *path)
{
if (path[0] == '/')
{
if (path[0] == '/') {
path++;
}
/* Check for child path separator */
const char *child_path = strchr(path, '/');
if (child_path != MR_NULL)
{
if (child_path != MR_NULL) {
char child_name[MR_CFG_DEV_NAME_LEN + 1] = {0};
size_t len = MR_BOUND(child_path - path, 0, MR_CFG_DEV_NAME_LEN);
@@ -113,15 +98,13 @@ static struct mr_dev *dev_find_by_path(struct mr_dev *parent, const char *path)
strncpy(child_name, path, len);
child_name[len] = '\0';
struct mr_dev *child = dev_find_child(parent, child_name);
if (child == MR_NULL)
{
if (child == MR_NULL) {
return MR_NULL;
}
/* Find recursively */
return dev_find_by_path(child, child_path);
} else
{
} else {
/* Find with parent */
return dev_find_child(parent, path);
}
@@ -131,17 +114,14 @@ static struct mr_dev *dev_find_by_path(struct mr_dev *parent, const char *path)
static int dev_lock_take(struct mr_dev *dev, uint32_t take, uint32_t set)
{
/* Continue iterating until reach the root device */
if (dev_is_root(dev->parent) != MR_TRUE)
{
if (dev_is_root(dev->parent) != MR_TRUE) {
int ret = dev_lock_take(dev->parent, take, set);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
}
if (dev->lock & take)
{
if (dev->lock & take) {
return MR_EBUSY;
}
MR_BIT_SET(dev->lock, set);
@@ -151,8 +131,7 @@ static int dev_lock_take(struct mr_dev *dev, uint32_t take, uint32_t set)
static void dev_lock_release(struct mr_dev *dev, uint32_t release)
{
/* Continue iterating until reach the root device */
if (dev_is_root(dev->parent) != MR_TRUE)
{
if (dev_is_root(dev->parent) != MR_TRUE) {
dev_lock_release(dev->parent, release);
}
@@ -163,13 +142,12 @@ static void dev_lock_release(struct mr_dev *dev, uint32_t release)
MR_INLINE struct mr_dev *dev_find(const char *path)
{
/* Check whether the path is absolute */
if (*path == '/')
{
if (*path == '/') {
path++;
const char *next_slash = strchr(path, '/');
if ((next_slash == MR_NULL) ||
(strncmp(path, root_dev.name, MR_BOUND(next_slash - path, 0, MR_CFG_DEV_NAME_LEN)) != 0))
{
(strncmp(path, root_dev.name, MR_BOUND(next_slash - path, 0, MR_CFG_DEV_NAME_LEN)) !=
0)) {
return MR_NULL;
}
path += MR_BOUND(next_slash - path, 0, MR_CFG_DEV_NAME_LEN);
@@ -182,13 +160,12 @@ MR_INLINE struct mr_dev *dev_find(const char *path)
MR_INLINE int dev_register(struct mr_dev *dev, const char *path)
{
/* Check whether the path is absolute */
if (*path == '/')
{
if (*path == '/') {
path++;
const char *next_slash = strchr(path, '/');
if ((next_slash == MR_NULL) ||
(strncmp(path, root_dev.name, MR_BOUND(next_slash - path, 0, MR_CFG_DEV_NAME_LEN)) != 0))
{
(strncmp(path, root_dev.name, MR_BOUND(next_slash - path, 0, MR_CFG_DEV_NAME_LEN)) !=
0)) {
return MR_EINVAL;
}
path += MR_BOUND(next_slash - path, 0, MR_CFG_DEV_NAME_LEN);
@@ -201,87 +178,28 @@ MR_INLINE int dev_register(struct mr_dev *dev, const char *path)
return ret;
}
static int dev_isr(struct mr_dev *dev, int event, void *args)
{
/* Call the all registered callbacks */
switch (event)
{
case MR_ISR_RD:
{
for (struct mr_list *list = dev->rd_call_list.next; list != &dev->rd_call_list; list = list->next)
{
struct mr_dev_desc *desc = (struct mr_dev_desc *)MR_CONTAINER_OF(list,
struct mr_dev_desc,
rd_call.list);
if (desc->rd_call.fn != MR_NULL)
{
desc->rd_call.fn((int)(desc - &desc_map[0]), args);
}
}
break;
}
case MR_ISR_WR:
{
#ifdef MR_USING_RDWR_CTL
dev_lock_release(dev, MR_LOCK_NONBLOCK);
#endif /* MR_USING_RDWR_CTL */
for (struct mr_list *list = dev->wr_call_list.next; list != &dev->wr_call_list; list = list->next)
{
struct mr_dev_desc *desc = (struct mr_dev_desc *)MR_CONTAINER_OF(list,
struct mr_dev_desc,
wr_call.list);
if (desc->wr_call.fn != MR_NULL)
{
desc->wr_call.fn((int)(desc - &desc_map[0]), args);
}
}
break;
}
default:
{
return MR_ENOTSUP;
}
}
/* Wake up all child devices */
for (struct mr_list *list = dev->clist.next; list != &dev->clist; list = list->next)
{
struct mr_dev *cdev = (struct mr_dev *)MR_CONTAINER_OF(list, struct mr_dev, list);
/* Handle recursively */
dev_isr(cdev, event, args);
}
return MR_EOK;
}
static int dev_open(struct mr_dev *dev, int flags)
{
#ifdef MR_USING_RDWR_CTL
if (MR_BIT_IS_SET(dev->flags, flags) != MR_ENABLE)
{
if (MR_BIT_IS_SET(dev->flags, flags) != MR_ENABLE) {
return MR_ENOTSUP;
}
#endif /* MR_USING_RDWR_CTL */
/* Check whether the device is opened */
if (dev->ref_count == 0)
{
if (dev->ref_count == 0) {
/* Continue iterating until reach the root device */
if (dev_is_root(dev->parent) != MR_TRUE)
{
if (dev_is_root(dev->parent) != MR_TRUE) {
int ret = dev_open(dev->parent, flags);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
}
/* Open the device */
if (dev->ops->open != MR_NULL)
{
if (dev->ops->open != MR_NULL) {
int ret = dev->ops->open(dev);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
}
@@ -298,21 +216,17 @@ static int dev_close(struct mr_dev *dev)
dev->ref_count--;
/* Check whether the device needs to be closed */
if (dev->ref_count == 0)
{
if (dev->ref_count == 0) {
/* Continue iterating until reach the root device */
if (dev_is_root(dev->parent) != MR_TRUE)
{
if (dev_is_root(dev->parent) != MR_TRUE) {
int ret = dev_close(dev->parent);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
}
/* Close the device */
if (dev->ops->close != MR_NULL)
{
if (dev->ops->close != MR_NULL) {
return dev->ops->close(dev);
}
}
@@ -322,12 +236,10 @@ static int dev_close(struct mr_dev *dev)
MR_INLINE ssize_t dev_read(struct mr_dev *dev, int position, int sync, void *buf, size_t count)
{
#ifdef MR_USING_RDWR_CTL
do
{
do {
mr_interrupt_disable();
int ret = dev_lock_take(dev, (MR_LOCK_RD | MR_LOCK_SLEEP), MR_LOCK_RD);
if (ret < 0)
{
if (ret < 0) {
mr_interrupt_enable();
return ret;
}
@@ -348,17 +260,21 @@ MR_INLINE ssize_t dev_read(struct mr_dev *dev, int position, int sync, void *buf
return ret;
}
MR_INLINE ssize_t dev_write(struct mr_dev *dev, int position, int sync, const void *buf, size_t count)
MR_INLINE ssize_t dev_write(struct mr_dev *dev,
int position,
int sync,
const void *buf,
size_t count)
{
#ifdef MR_USING_RDWR_CTL
do
{
do {
mr_interrupt_disable();
int ret = dev_lock_take(dev,
(MR_LOCK_WR | MR_LOCK_SLEEP | (sync == MR_SYNC ? MR_LOCK_NONBLOCK : 0)),
(MR_LOCK_WR |
MR_LOCK_SLEEP |
(sync == MR_SYNC ? MR_LOCK_NONBLOCK : 0)),
MR_LOCK_WR);
if (ret < 0)
{
if (ret < 0) {
mr_interrupt_enable();
return ret;
}
@@ -375,8 +291,7 @@ MR_INLINE ssize_t dev_write(struct mr_dev *dev, int position, int sync, const vo
#ifdef MR_USING_RDWR_CTL
dev_lock_release(dev, MR_LOCK_WR);
if ((sync == MR_ASYNC) && (ret > 0))
{
if ((sync == MR_ASYNC) && (ret > 0)) {
mr_interrupt_disable();
dev_lock_take(dev, 0, MR_LOCK_NONBLOCK);
mr_interrupt_enable();
@@ -387,21 +302,19 @@ MR_INLINE ssize_t dev_write(struct mr_dev *dev, int position, int sync, const vo
MR_INLINE int dev_ioctl(struct mr_dev *dev, int position, int sync, int cmd, void *args)
{
if (dev->ops->ioctl == MR_NULL)
{
if (dev->ops->ioctl == MR_NULL) {
return MR_ENOTSUP;
}
#ifdef MR_USING_RDWR_CTL
do
{
do {
/* Lock only when user -> device command */
if (cmd)
{
if (cmd) {
mr_interrupt_disable();
int ret = dev_lock_take(dev, (MR_LOCK_RDWR | MR_LOCK_SLEEP | MR_LOCK_NONBLOCK), MR_LOCK_RDWR);
if (ret < 0)
{
int ret = dev_lock_take(dev,
(MR_LOCK_RDWR | MR_LOCK_SLEEP | MR_LOCK_NONBLOCK),
MR_LOCK_RDWR);
if (ret < 0) {
mr_interrupt_enable();
return ret;
}
@@ -428,22 +341,18 @@ MR_INLINE int desc_allocate(const char *path)
int desc = -1;
struct mr_dev *dev = dev_find(path);
if (dev == MR_NULL)
{
if (dev == MR_NULL) {
return MR_ENOTFOUND;
}
/* Find a free descriptor */
for (size_t i = 0; i < MR_CFG_DESC_NUM; i++)
{
if (DESC_OF(i).dev == MR_NULL)
{
for (size_t i = 0; i < MR_CFG_DESC_NUM; i++) {
if (DESC_OF(i).dev == MR_NULL) {
desc = (int)i;
break;
}
}
if (desc < 0)
{
if (desc < 0) {
return MR_ENOMEM;
}
@@ -459,8 +368,7 @@ MR_INLINE int desc_allocate(const char *path)
MR_INLINE void desc_free(int desc)
{
if (DESC_IS_VALID(desc) == MR_TRUE)
{
if (DESC_IS_VALID(desc) == MR_TRUE) {
DESC_OF(desc).dev = MR_NULL;
DESC_OF(desc).flags = MR_O_CLOSED;
DESC_OF(desc).position = -1;
@@ -543,20 +451,52 @@ int mr_dev_isr(struct mr_dev *dev, int event, void *args)
MR_ASSERT(dev != MR_NULL);
MR_ASSERT(event >= 0);
if ((dev->ref_count == 0) || (dev->ops->isr == MR_NULL))
{
if (dev->ref_count == 0) {
return MR_ENOTSUP;
}
/* Call the device ISR */
ssize_t ret = dev->ops->isr(dev, event, args);
if (ret < 0)
{
return (int)ret;
if (dev->ops->isr != MR_NULL) {
ssize_t ret = dev->ops->isr(dev, event, args);
if (ret < 0) {
return (int)ret;
}
}
/* Handle the ISR event */
return dev_isr(dev, (event & MR_ISR_MASK), &ret);
/* Call the all set callbacks */
switch (event & MR_ISR_MASK) {
case MR_ISR_RD: {
for (struct mr_list *list = dev->rd_call_list.next;
list != &dev->rd_call_list;
list = list->next) {
struct mr_dev_desc *desc = (struct mr_dev_desc *)MR_CONTAINER_OF(list,
struct mr_dev_desc,
rd_call.list);
if (desc->rd_call.fn != MR_NULL) {
desc->rd_call.fn((int)(desc - &desc_map[0]), args);
}
}
return MR_EOK;
}
case MR_ISR_WR: {
#ifdef MR_USING_RDWR_CTL
dev_lock_release(dev, MR_LOCK_NONBLOCK);
#endif /* MR_USING_RDWR_CTL */
for (struct mr_list *list = dev->wr_call_list.next;
list != &dev->wr_call_list;
list = list->next) {
struct mr_dev_desc *desc = (struct mr_dev_desc *)MR_CONTAINER_OF(list,
struct mr_dev_desc,
wr_call.list);
if (desc->wr_call.fn != MR_NULL) {
desc->wr_call.fn((int)(desc - &desc_map[0]), args);
}
}
return MR_EOK;
}
default: {
return MR_ENOTSUP;
}
}
}
/**
@@ -579,11 +519,9 @@ int mr_dev_open(const char *path, int flags)
MR_ASSERT(flags >= MR_O_CLOSED);
/* Query device flags */
if (flags == MR_O_QUERY)
{
if (flags == MR_O_QUERY) {
struct mr_dev *dev = dev_find(path);
if (dev == MR_NULL)
{
if (dev == MR_NULL) {
return MR_ENOTFOUND;
}
return dev->flags;
@@ -591,13 +529,11 @@ int mr_dev_open(const char *path, int flags)
/* Allocate descriptor and open device */
int desc = desc_allocate(path);
if (desc < 0)
{
if (desc < 0) {
return desc;
}
int ret = dev_open(DESC_OF(desc).dev, flags);
if (ret < 0)
{
if (ret < 0) {
desc_free(desc);
return ret;
}
@@ -623,8 +559,7 @@ int mr_dev_close(int desc)
/* Close the device and free the descriptor */
int ret = dev_close(DESC_OF(desc).dev);
if (ret < 0)
{
if (ret < 0) {
return ret;
}
desc_free(desc);
@@ -651,8 +586,7 @@ ssize_t mr_dev_read(int desc, void *buf, size_t count)
MR_DESC_CHECK(desc);
#ifdef MR_USING_RDWR_CTL
if (MR_BIT_IS_SET(DESC_OF(desc).flags, MR_O_RDONLY) == MR_DISABLE)
{
if (MR_BIT_IS_SET(DESC_OF(desc).flags, MR_O_RDONLY) == MR_DISABLE) {
return MR_ENOTSUP;
}
#endif /* MR_USING_RDWR_CTL */
@@ -685,8 +619,7 @@ ssize_t mr_dev_write(int desc, const void *buf, size_t count)
MR_DESC_CHECK(desc);
#ifdef MR_USING_RDWR_CTL
if (MR_BIT_IS_SET(DESC_OF(desc).flags, MR_O_WRONLY) == MR_DISABLE)
{
if (MR_BIT_IS_SET(DESC_OF(desc).flags, MR_O_WRONLY) == MR_DISABLE) {
return MR_ENOTSUP;
}
#endif /* MR_USING_RDWR_CTL */
@@ -717,12 +650,9 @@ int mr_dev_ioctl(int desc, int cmd, void *args)
{
MR_DESC_CHECK(desc);
switch (cmd)
{
case MR_IOC_SPOS:
{
if (args != MR_NULL)
{
switch (cmd) {
case MR_IOC_SPOS: {
if (args != MR_NULL) {
int position = *(int *)args;
DESC_OF(desc).position = position;
@@ -730,44 +660,48 @@ int mr_dev_ioctl(int desc, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_SRCB:
{
case MR_IOC_SRCB: {
#ifdef MR_USING_RDWR_CTL
if (MR_BIT_IS_SET(DESC_OF(desc).flags, MR_O_RDONLY) == MR_DISABLE) {
return MR_ENOTSUP;
}
#endif /* MR_USING_RDWR_CTL */
void (*fn)(int desc, void *args) = (void (*)(int desc, void *args))args;
/* Link or unlink the callback function */
DESC_OF(desc).rd_call.fn = fn;
mr_interrupt_disable();
if (fn != MR_NULL)
{
mr_list_insert_before(&DESC_OF(desc).dev->rd_call_list, &DESC_OF(desc).rd_call.list);
} else
{
if (fn != MR_NULL) {
mr_list_insert_before(&DESC_OF(desc).dev->rd_call_list,
&DESC_OF(desc).rd_call.list);
} else {
mr_list_remove(&DESC_OF(desc).rd_call.list);
}
mr_interrupt_enable();
return sizeof(fn);
}
case MR_IOC_SWCB:
{
case MR_IOC_SWCB: {
#ifdef MR_USING_RDWR_CTL
if (MR_BIT_IS_SET(DESC_OF(desc).flags, MR_O_WRONLY) == MR_DISABLE) {
return MR_ENOTSUP;
}
#endif /* MR_USING_RDWR_CTL */
void (*fn)(int desc, void *args) = (void (*)(int desc, void *args))args;
/* Link or unlink the callback function */
DESC_OF(desc).wr_call.fn = fn;
mr_interrupt_disable();
if (fn != MR_NULL)
{
mr_list_insert_before(&DESC_OF(desc).dev->wr_call_list, &DESC_OF(desc).wr_call.list);
} else
{
if (fn != MR_NULL) {
mr_list_insert_before(&DESC_OF(desc).dev->wr_call_list,
&DESC_OF(desc).wr_call.list);
} else {
mr_list_remove(&DESC_OF(desc).wr_call.list);
}
mr_interrupt_enable();
return sizeof(fn);
}
case MR_IOC_GPOS:
{
if (args != MR_NULL)
{
case MR_IOC_GPOS: {
if (args != MR_NULL) {
int *position = (int *)args;
*position = DESC_OF(desc).position;
@@ -775,26 +709,31 @@ int mr_dev_ioctl(int desc, int cmd, void *args)
}
return MR_EINVAL;
}
case MR_IOC_GRCB:
{
if (args != MR_NULL)
{
case MR_IOC_GRCB: {
#ifdef MR_USING_RDWR_CTL
if (MR_BIT_IS_SET(DESC_OF(desc).flags, MR_O_RDONLY) == MR_DISABLE) {
return MR_ENOTSUP;
}
#endif /* MR_USING_RDWR_CTL */
if (args != MR_NULL) {
*(void (**)(int desc, void *args))args = DESC_OF(desc).rd_call.fn;
return sizeof(DESC_OF(desc).rd_call.fn);
}
return MR_EINVAL;
}
case MR_IOC_GWCB:
{
if (args != MR_NULL)
{
case MR_IOC_GWCB: {
#ifdef MR_USING_RDWR_CTL
if (MR_BIT_IS_SET(DESC_OF(desc).flags, MR_O_WRONLY) == MR_DISABLE) {
return MR_ENOTSUP;
}
#endif /* MR_USING_RDWR_CTL */
if (args != MR_NULL) {
*(void (**)(int desc, void *args))args = DESC_OF(desc).wr_call.fn;
return sizeof(DESC_OF(desc).wr_call.fn);
}
return MR_EINVAL;
}
default:
{
default: {
/* I/O control to the device */
return dev_ioctl(DESC_OF(desc).dev,
DESC_OF(desc).position,
@@ -813,14 +752,12 @@ static int dev_get_path(struct mr_dev *dev, char *buf, size_t bufsz)
int ret = 0;
/* Continue iterating until reach the null parent */
if (dev->parent != MR_NULL)
{
if (dev->parent != MR_NULL) {
ret = dev_get_path(dev->parent, buf, bufsz);
}
/* Check whether the buffer is enough */
if ((bufsz - ret) <= (strlen(dev->name) + 1))
{
if ((bufsz - ret) <= (strlen(dev->name) + 1)) {
return ret;
}
ret += snprintf(buf + ret, bufsz - ret, "/%s", dev->name);
@@ -836,23 +773,23 @@ int msh_dev_get_path(int desc, char *buf, size_t size)
void msh_dlist_tree(struct mr_dev *parent, int level)
{
if (level == 0)
{
if (level == 0) {
mr_msh_printf("|%s %-*s", mr_strflags(parent->flags), MR_CFG_DEV_NAME_LEN, parent->name);
} else
{
mr_msh_printf("%*s|%s %-*s", level, " ", mr_strflags(parent->flags), MR_CFG_DEV_NAME_LEN, parent->name);
} else {
mr_msh_printf("%*s|%s %-*s",
level,
" ",
mr_strflags(parent->flags),
MR_CFG_DEV_NAME_LEN,
parent->name);
}
for (size_t i = 0; i < MR_CFG_DESC_NUM; i++)
{
if (desc_map[i].dev == parent)
{
for (size_t i = 0; i < MR_CFG_DESC_NUM; i++) {
if (desc_map[i].dev == parent) {
mr_msh_printf(" [%d]", i);
}
}
mr_msh_printf("\r\n");
for (struct mr_list *child = parent->clist.next; child != &parent->clist; child = child->next)
{
for (struct mr_list *child = parent->clist.next; child != &parent->clist; child = child->next) {
struct mr_dev *dev = MR_CONTAINER_OF(child, struct mr_dev, list);
msh_dlist_tree(dev, level + 7);
}