diff --git a/device/can.c b/device/can.c index 3264aa4..15f04b6 100644 --- a/device/can.c +++ b/device/can.c @@ -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 */ diff --git a/device/i2c.c b/device/i2c.c index c87f70a..4fe6c9c 100644 --- a/device/i2c.c +++ b/device/i2c.c @@ -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; diff --git a/device/pin.c b/device/pin.c index 621ddde..b3a6fcd 100644 --- a/device/pin.c +++ b/device/pin.c @@ -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); } diff --git a/device/serial.c b/device/serial.c index be91725..a846e2d 100644 --- a/device/serial.c +++ b/device/serial.c @@ -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 */ diff --git a/device/spi.c b/device/spi.c index b6c332d..ce0f684 100644 --- a/device/spi.c +++ b/device/spi.c @@ -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); diff --git a/document/device/i2c/i2c.md b/document/device/i2c/i2c.md index 77df8ae..49c2c60 100644 --- a/document/device/i2c/i2c.md +++ b/document/device/i2c/i2c.md @@ -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); diff --git a/document/device/i2c/i2c_EN.md b/document/device/i2c/i2c_EN.md index a24681f..21fa646 100644 --- a/document/device/i2c/i2c_EN.md +++ b/document/device/i2c/i2c_EN.md @@ -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. diff --git a/document/device/pin/pin.md b/document/device/pin/pin.md index ca94c2f..924a4bb 100644 --- a/document/device/pin/pin.md +++ b/document/device/pin/pin.md @@ -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) { diff --git a/document/device/pin/pin_EN.md b/document/device/pin/pin_EN.md index b68602a..82928cd 100644 --- a/document/device/pin/pin_EN.md +++ b/document/device/pin/pin_EN.md @@ -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) { diff --git a/include/device/mr_can.h b/include/device/mr_can.h index b7b5a45..bfa9021 100644 --- a/include/device/mr_can.h +++ b/include/device/mr_can.h @@ -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 diff --git a/include/device/mr_pin.h b/include/device/mr_pin.h index 7dbe62e..20de88a 100644 --- a/include/device/mr_pin.h +++ b/include/device/mr_pin.h @@ -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 diff --git a/source/device.c b/source/device.c index 63808be..335d2a3 100644 --- a/source/device.c +++ b/source/device.c @@ -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); }