1.底层接口新增返回值,增加超时判断。2.完善i2c机制,为软件i2c增加ack支持。

This commit is contained in:
MacRsh
2024-02-02 01:46:05 +08:00
parent fbeeac68ac
commit 7930b355aa
19 changed files with 238 additions and 198 deletions

View File

@@ -44,6 +44,15 @@ menu "Driver configure"
config MR_USING_SPI1
bool "Enable SPI1 driver"
default n
menu "SPI1 driver configure"
depends on MR_USING_SPI1
config MR_CFG_SPI1_GROUP
int "SPI1 Group"
default 1
range 1 2
endmenu
endmenu
menu "Timer"

View File

@@ -93,7 +93,11 @@ static ssize_t mr_adc_read(struct mr_dev *dev, void *buf, size_t count)
for (rd_size = 0; rd_size < MR_ALIGN_DOWN(count, sizeof(*rd_buf)); rd_size += sizeof(*rd_buf))
{
*rd_buf = ops->read(adc, dev->position);
int ret = ops->read(adc, dev->position, rd_buf);
if (ret < 0)
{
return (rd_size == 0) ? ret : rd_size;
}
rd_buf++;
}
return rd_size;

View File

@@ -93,7 +93,11 @@ static ssize_t mr_dac_write(struct mr_dev *dev, const void *buf, size_t count)
for (wr_size = 0; wr_size < MR_ALIGN_DOWN(count, sizeof(*wr_buf)); wr_size += sizeof(*wr_buf))
{
ops->write(dac, dev->position, *wr_buf);
int ret = ops->write(dac, dev->position, *wr_buf);
if (ret < 0)
{
return (wr_size == 0) ? ret : wr_size;
}
wr_buf++;
}
return wr_size;

View File

@@ -84,8 +84,10 @@ int _mr_fast_pin_mode(int number, int mode)
uint8_t _mr_fast_pin_read(int number)
{
struct mr_dev *dev = *_fast_pin_dev_get(MR_MAGIC_NUMBER);
uint8_t value = 0;
return ((struct mr_pin_ops *)dev->drv->ops)->read((struct mr_pin *)dev, number);
((struct mr_pin_ops *)dev->drv->ops)->read((struct mr_pin *)dev, number, &value);
return value;
}
/**

View File

@@ -51,9 +51,14 @@ static ssize_t mr_i2c_bus_isr(struct mr_dev *dev, int event, void *args)
case MR_ISR_I2C_RD_INT:
{
struct mr_i2c_dev *i2c_dev = (struct mr_i2c_dev *)i2c_bus->owner;
uint8_t data = ops->read(i2c_bus, MR_ENABLE);
uint8_t data;
/* Read data to FIFO */
int ret = ops->read(i2c_bus, &data, MR_ENABLE);
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);
@@ -152,7 +157,7 @@ MR_INLINE int i2c_dev_release_bus(struct mr_i2c_dev *i2c_dev)
#define MR_I2C_RD (0)
#define MR_I2C_WR (1)
MR_INLINE void i2c_dev_send_addr(struct mr_i2c_dev *i2c_dev, int rdwr)
MR_INLINE int i2c_dev_send_addr(struct mr_i2c_dev *i2c_dev, int rdwr)
{
struct mr_i2c_bus *i2c_bus = (struct mr_i2c_bus *)i2c_dev->dev.parent;
struct mr_i2c_bus_ops *ops = (struct mr_i2c_bus_ops *)i2c_bus->dev.drv->ops;
@@ -163,13 +168,19 @@ MR_INLINE void i2c_dev_send_addr(struct mr_i2c_dev *i2c_dev, int rdwr)
addr_bits = i2c_dev->addr_bits;
/* Set the read command */
addr = (0xf000 | ((addr >> 8) & 0x03) << 9) | (addr & 0xff);
if (rdwr == MR_I2C_RD)
{
addr |= 0x01;
addr |= (addr_bits == MR_I2C_ADDR_BITS_7) ? 0x01 : 0x10;
}
ops->start(i2c_bus);
ops->send_addr(i2c_bus, addr, addr_bits);
int ret = ops->send_addr(i2c_bus, addr, addr_bits);
if (ret < 0)
{
ops->stop(i2c_bus);
}
return ret;
}
MR_INLINE void i2c_dev_send_stop(struct mr_i2c_dev *i2c_dev)
@@ -189,7 +200,13 @@ MR_INLINE ssize_t i2c_dev_read(struct mr_i2c_dev *i2c_dev, uint8_t *buf, size_t
for (rd_size = 0; rd_size < count; rd_size += sizeof(*rd_buf))
{
*rd_buf = ops->read(i2c_bus, (count - rd_size) == sizeof(*rd_buf));
int ack = ((count - rd_size) == sizeof(*rd_buf));
int ret = ops->read(i2c_bus, rd_buf, ack);
if (ret < 0)
{
return (rd_size == 0) ? ret : rd_size;
}
rd_buf++;
}
return rd_size;
@@ -204,7 +221,11 @@ MR_INLINE ssize_t i2c_dev_write(struct mr_i2c_dev *i2c_dev, const uint8_t *buf,
for (wr_size = 0; wr_size < count; wr_size += sizeof(*wr_buf))
{
ops->write(i2c_bus, *wr_buf);
int ret = ops->write(i2c_bus, *wr_buf);
if (ret < 0)
{
return (wr_size == 0) ? ret : wr_size;
}
wr_buf++;
}
return wr_size;
@@ -240,24 +261,32 @@ static ssize_t mr_i2c_dev_read(struct mr_dev *dev, void *buf, size_t count)
/* Send the address of the register that needs to be read */
if (dev->position >= 0)
{
i2c_dev_send_addr(i2c_dev, MR_I2C_WR);
i2c_dev_write(i2c_dev, (uint8_t *)&dev->position, (i2c_dev->config.reg_bits >> 3));
ret = i2c_dev_send_addr(i2c_dev, MR_I2C_WR);
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)
{
goto release_bus;
}
}
i2c_dev_send_addr(i2c_dev, MR_I2C_RD);
ret = i2c_dev_send_addr(i2c_dev, MR_I2C_RD);
if (ret < 0)
{
goto release_bus;
}
ret = i2c_dev_read(i2c_dev, (uint8_t *)buf, count);
i2c_dev_send_stop(i2c_dev);
} else
{
if (mr_ringbuf_get_bufsz(&i2c_dev->rd_fifo) == 0)
{
ret = i2c_dev_read(i2c_dev, (uint8_t *)buf, count);
} else
{
ret = (ssize_t)mr_ringbuf_read(&i2c_dev->rd_fifo, buf, count);
}
ret = (ssize_t)mr_ringbuf_read(&i2c_dev->rd_fifo, buf, count);
}
release_bus:
i2c_dev_release_bus(i2c_dev);
return ret;
}
@@ -274,12 +303,20 @@ static ssize_t mr_i2c_dev_write(struct mr_dev *dev, const void *buf, size_t coun
if (i2c_dev->config.host_slave == MR_I2C_HOST)
{
i2c_dev_send_addr(i2c_dev, MR_I2C_WR);
ret = i2c_dev_send_addr(i2c_dev, MR_I2C_WR);
if (ret < 0)
{
goto release_bus;
}
/* Send the address of the register that needs to be written */
if (dev->position >= 0)
{
i2c_dev_write(i2c_dev, (uint8_t *)&dev->position, (i2c_dev->config.reg_bits >> 3));
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);
@@ -289,6 +326,7 @@ static ssize_t mr_i2c_dev_write(struct mr_dev *dev, const void *buf, size_t coun
ret = i2c_dev_write(i2c_dev, (uint8_t *)buf, count);
}
release_bus:
i2c_dev_release_bus(i2c_dev);
return ret;
}
@@ -414,6 +452,8 @@ int mr_i2c_dev_register(struct mr_i2c_dev *i2c_dev, const char *path, int addr,
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));
/* Initialize the fields */
i2c_dev->config = default_config;
@@ -422,7 +462,7 @@ int mr_i2c_dev_register(struct mr_i2c_dev *i2c_dev, const char *path, int addr,
#define MR_CFG_I2C_RD_BUFSZ (0)
#endif /* MR_CFG_I2C_RD_BUFSZ */
i2c_dev->rd_bufsz = MR_CFG_I2C_RD_BUFSZ;
i2c_dev->addr = (addr_bits == MR_I2C_ADDR_BITS_7) ? addr : ((0xf0 | ((addr >> 7) & 0x06)) << 8) | (addr & 0xff);
i2c_dev->addr = addr;
i2c_dev->addr_bits = addr_bits;
/* Register the i2c-device */

View File

@@ -41,7 +41,11 @@ static ssize_t mr_pin_read(struct mr_dev *dev, void *buf, size_t count)
for (rd_size = 0; rd_size < count; rd_size += sizeof(*rd_buf))
{
*rd_buf = (uint8_t)ops->read(pin, dev->position);
int ret = (uint8_t)ops->read(pin, dev->position, rd_buf);
if (ret < 0)
{
return (rd_size == 0) ? ret : rd_size;
}
rd_buf++;
}
return rd_size;
@@ -64,7 +68,11 @@ static ssize_t mr_pin_write(struct mr_dev *dev, const void *buf, size_t count)
for (wr_size = 0; wr_size < count; wr_size += sizeof(*wr_buf))
{
ops->write(pin, dev->position, *wr_buf);
int ret = ops->write(pin, dev->position, *wr_buf);
if (ret < 0)
{
return (wr_size == 0) ? ret : wr_size;
}
wr_buf++;
}
return wr_size;

View File

@@ -157,8 +157,14 @@ static ssize_t mr_pwm_read(struct mr_dev *dev, void *buf, size_t count)
for (rd_size = 0; rd_size < MR_ALIGN_DOWN(count, sizeof(*rd_buf)); rd_size += sizeof(*rd_buf))
{
uint32_t compare_value;
/* Calculate the duty */
uint32_t compare_value = ops->read(pwm, dev->position);
int ret = ops->read(pwm, dev->position, &compare_value);
if (ret < 0)
{
return (rd_size == 0) ? ret : rd_size;
}
*rd_buf = (uint32_t)(((float)compare_value / (float)pwm->period) * 1000000.0f);
rd_buf++;
}
@@ -186,7 +192,11 @@ static ssize_t mr_pwm_write(struct mr_dev *dev, const void *buf, size_t count)
uint32_t compare_value = MR_BOUND((uint32_t)(((float)*wr_buf / 1000000.0f) * (float)(pwm->period)),
0,
pwm->period);
ops->write(pwm, dev->position, compare_value);
int ret = ops->write(pwm, dev->position, compare_value);
if (ret < 0)
{
return (wr_size == 0) ? ret : wr_size;
}
wr_buf++;
}
return wr_size;
@@ -236,8 +246,14 @@ static int mr_pwm_ioctl(struct mr_dev *dev, int cmd, void *args)
{
if (MR_BIT_IS_SET(pwm->channel, (1 << i)) == MR_ENABLE)
{
uint32_t compare_value;
/* Get old duty */
uint32_t compare_value = ops->read(pwm, (int)i);
ret = ops->read(pwm, (int)i, &compare_value);
if (ret < 0)
{
continue;
}
/* Calculate new compare value */
compare_value = (uint32_t)(((float)compare_value / (float)old_period) * (float)(pwm->period));

View File

@@ -52,7 +52,11 @@ static ssize_t mr_serial_read(struct mr_dev *dev, void *buf, size_t count)
{
for (rd_size = 0; rd_size < count; rd_size += sizeof(*rd_buf))
{
*rd_buf = ops->read(serial);
int ret = ops->read(serial, rd_buf);
if (ret < 0)
{
return (rd_size == 0) ? ret : rd_size;
}
rd_buf++;
}
} else
@@ -73,7 +77,11 @@ static ssize_t mr_serial_write(struct mr_dev *dev, const void *buf, size_t count
{
for (wr_size = 0; wr_size < count; wr_size += sizeof(*wr_buf))
{
ops->write(serial, *wr_buf);
int ret = ops->write(serial, *wr_buf);
if (ret < 0)
{
return (wr_size == 0) ? ret : wr_size;
}
wr_buf++;
}
} else
@@ -226,16 +234,23 @@ static ssize_t mr_serial_isr(struct mr_dev *dev, int event, void *args)
{
case MR_ISR_SERIAL_RD_INT:
{
uint8_t data;
/* Read data to FIFO */
uint8_t data = ops->read(serial);
int ret = ops->read(serial, &data);
if (ret < 0)
{
return ret;
}
mr_ringbuf_push_force(&serial->rd_fifo, data);
return (ssize_t)mr_ringbuf_get_data_size(&serial->rd_fifo);
}
case MR_ISR_SERIAL_WR_INT:
{
/* Write data from FIFO, if FIFO is empty, stop transmit */
uint8_t data;
/* Write data from FIFO, if FIFO is empty, stop transmit */
if (mr_ringbuf_pop(&serial->wr_fifo, &data) == sizeof(data))
{
ops->write(serial, data);

View File

@@ -37,9 +37,10 @@ MR_INLINE uint8_t soft_i2c_sda_get(struct mr_soft_i2c_bus *soft_i2c_bus)
return (uint8_t)_mr_fast_pin_read(soft_i2c_bus->sda_pin);
}
static void soft_i2c_bus_wait_ack(struct mr_i2c_bus *i2c_bus)
static int soft_i2c_bus_wait_ack(struct mr_i2c_bus *i2c_bus)
{
struct mr_soft_i2c_bus *soft_i2c_bus = (struct mr_soft_i2c_bus *)i2c_bus;
int ret = MR_ETIMEOUT;
soft_i2c_scl_set(soft_i2c_bus, SOFT_I2C_LOW);
soft_i2c_bus_sda_set(soft_i2c_bus, SOFT_I2C_HIGH);
@@ -48,9 +49,13 @@ static void soft_i2c_bus_wait_ack(struct mr_i2c_bus *i2c_bus)
soft_i2c_scl_set(soft_i2c_bus, SOFT_I2C_HIGH);
mr_delay_us(soft_i2c_bus->delay);
soft_i2c_sda_get(soft_i2c_bus);
if (soft_i2c_sda_get(soft_i2c_bus) == SOFT_I2C_LOW)
{
ret = MR_EOK;
}
soft_i2c_scl_set(soft_i2c_bus, SOFT_I2C_LOW);
mr_delay_us(soft_i2c_bus->delay);
return ret;
}
static void soft_i2c_bus_send_ack(struct mr_i2c_bus *i2c_bus, int ack)
@@ -58,7 +63,6 @@ static void soft_i2c_bus_send_ack(struct mr_i2c_bus *i2c_bus, int ack)
struct mr_soft_i2c_bus *soft_i2c_bus = (struct mr_soft_i2c_bus *)i2c_bus;
soft_i2c_scl_set(soft_i2c_bus, SOFT_I2C_LOW);
mr_delay_us(soft_i2c_bus->delay);
if (ack == MR_ENABLE)
{
soft_i2c_bus_sda_set(soft_i2c_bus, SOFT_I2C_LOW);
@@ -67,10 +71,11 @@ static void soft_i2c_bus_send_ack(struct mr_i2c_bus *i2c_bus, int ack)
soft_i2c_bus_sda_set(soft_i2c_bus, SOFT_I2C_HIGH);
}
mr_delay_us(soft_i2c_bus->delay);
soft_i2c_scl_set(soft_i2c_bus, SOFT_I2C_HIGH);
mr_delay_us(soft_i2c_bus->delay);
soft_i2c_scl_set(soft_i2c_bus, SOFT_I2C_LOW);
mr_delay_us(soft_i2c_bus->delay);
soft_i2c_bus_sda_set(soft_i2c_bus, SOFT_I2C_HIGH);
}
static int mr_soft_i2c_bus_configure(struct mr_i2c_bus *i2c_bus, struct mr_i2c_config *config, int addr, int addr_bits)
@@ -118,15 +123,25 @@ static void mr_soft_i2c_bus_start(struct mr_i2c_bus *i2c_bus)
soft_i2c_scl_set(soft_i2c_bus, SOFT_I2C_LOW);
}
static void mr_soft_i2c_bus_write(struct mr_i2c_bus *i2c_bus, uint8_t data);
static int mr_soft_i2c_bus_write(struct mr_i2c_bus *i2c_bus, uint8_t data);
static void mr_soft_i2c_bus_send_addr(struct mr_i2c_bus *i2c_bus, int addr, int addr_bits)
static int mr_soft_i2c_bus_send_addr(struct mr_i2c_bus *i2c_bus, int addr, int addr_bits)
{
mr_soft_i2c_bus_write(i2c_bus, addr);
if (addr_bits == MR_I2C_ADDR_BITS_10)
{
mr_soft_i2c_bus_write(i2c_bus, (addr >> 8));
int ret = mr_soft_i2c_bus_write(i2c_bus, addr >> 8);
if (ret < 0)
{
return ret;
}
}
int ret = mr_soft_i2c_bus_write(i2c_bus, addr);
if (ret < 0)
{
return ret;
}
return MR_EOK;
}
static void mr_soft_i2c_bus_stop(struct mr_i2c_bus *i2c_bus)
@@ -140,50 +155,43 @@ static void mr_soft_i2c_bus_stop(struct mr_i2c_bus *i2c_bus)
soft_i2c_scl_set(soft_i2c_bus, SOFT_I2C_HIGH);
mr_delay_us(soft_i2c_bus->delay);
soft_i2c_bus_sda_set(soft_i2c_bus, SOFT_I2C_HIGH);
mr_delay_us(soft_i2c_bus->delay);
}
static uint8_t mr_soft_i2c_bus_read(struct mr_i2c_bus *i2c_bus, int ack_state)
static int mr_soft_i2c_bus_read(struct mr_i2c_bus *i2c_bus, uint8_t *data, int ack_state)
{
struct mr_soft_i2c_bus *soft_i2c_bus = (struct mr_soft_i2c_bus *)i2c_bus;
uint8_t data = 0;
soft_i2c_scl_set(soft_i2c_bus, SOFT_I2C_LOW);
mr_delay_us(soft_i2c_bus->delay);
soft_i2c_bus_sda_set(soft_i2c_bus, SOFT_I2C_HIGH);
for (size_t bits = 0; bits < 8; bits++)
for (size_t bits = 0; bits < (sizeof(*data) * 8); bits++)
{
mr_delay_us(soft_i2c_bus->delay);
soft_i2c_scl_set(soft_i2c_bus, SOFT_I2C_LOW);
mr_delay_us(soft_i2c_bus->delay);
soft_i2c_scl_set(soft_i2c_bus, SOFT_I2C_HIGH);
mr_delay_us(soft_i2c_bus->delay);
data <<= 1;
*data <<= 1;
if (soft_i2c_sda_get(soft_i2c_bus) == SOFT_I2C_HIGH)
{
data |= 0x01;
*data |= 0x01;
}
}
soft_i2c_scl_set(soft_i2c_bus, SOFT_I2C_LOW);
mr_delay_us(soft_i2c_bus->delay);
soft_i2c_bus_send_ack(i2c_bus, ack_state);
return data;
return MR_EOK;
}
static void mr_soft_i2c_bus_write(struct mr_i2c_bus *i2c_bus, uint8_t data)
static int mr_soft_i2c_bus_write(struct mr_i2c_bus *i2c_bus, uint8_t data)
{
struct mr_soft_i2c_bus *soft_i2c_bus = (struct mr_soft_i2c_bus *)i2c_bus;
for (size_t bits = 0; bits < 8; bits++)
{
if (data & 0x80)
{
soft_i2c_bus_sda_set(soft_i2c_bus, SOFT_I2C_HIGH);
} else
{
soft_i2c_bus_sda_set(soft_i2c_bus, SOFT_I2C_LOW);
}
soft_i2c_bus_sda_set(soft_i2c_bus, (data & 0x80) ? SOFT_I2C_HIGH : SOFT_I2C_LOW);
data <<= 1;
mr_delay_us(soft_i2c_bus->delay);
@@ -191,7 +199,7 @@ static void mr_soft_i2c_bus_write(struct mr_i2c_bus *i2c_bus, uint8_t data)
mr_delay_us(soft_i2c_bus->delay);
soft_i2c_scl_set(soft_i2c_bus, SOFT_I2C_LOW);
}
soft_i2c_bus_wait_ack(i2c_bus);
return soft_i2c_bus_wait_ack(i2c_bus);
}
/**

View File

@@ -65,11 +65,17 @@ static ssize_t mr_spi_bus_isr(struct mr_dev *dev, int event, void *args)
case MR_ISR_SPI_RD_INT:
{
struct mr_spi_dev *spi_dev = (struct mr_spi_dev *)spi_bus->owner;
uint32_t data = ops->read(spi_bus);
uint8_t data;
/* Read data to FIFO. if callback is set, call it */
mr_ringbuf_write_force(&spi_dev->rd_fifo, &data, (spi_bus->config.data_bits >> 3));
return MR_EOK;
/* Read data to FIFO */
int ret = ops->read(spi_bus, &data);
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);;
}
default:
{
@@ -186,7 +192,6 @@ MR_INLINE int spi_dev_take_bus(struct mr_spi_dev *spi_dev)
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.data_bits != spi_bus->config.data_bits
|| spi_dev->config.bit_order != spi_bus->config.bit_order)
{
int ret = ops->configure(spi_bus, &spi_dev->config);
@@ -229,143 +234,57 @@ MR_INLINE int spi_dev_release_bus(struct mr_spi_dev *spi_dev)
#define MR_SPI_WR (1)
#define MR_SPI_RDWR (2)
static ssize_t spi_dev_transfer(struct mr_spi_dev *spi_dev, void *rd_buf, const void *wr_buf, size_t size, int rdwr)
static ssize_t spi_dev_transfer(struct mr_spi_dev *spi_dev,
uint8_t *rd_buf,
const uint8_t *wr_buf,
size_t size,
int rdwr)
{
struct mr_spi_bus *spi_bus = (struct mr_spi_bus *)spi_dev->dev.parent;
struct mr_spi_bus_ops *ops = (struct mr_spi_bus_ops *)spi_bus->dev.drv->ops;
size_t tf_size;
ssize_t tf_size;
if (rdwr == MR_SPI_RD)
{
switch (spi_dev->config.data_bits)
for (tf_size = 0; tf_size < size; tf_size += sizeof(*rd_buf))
{
case MR_SPI_DATA_BITS_8:
ops->write(spi_bus, 0);
int ret = ops->read(spi_bus, rd_buf);
if (ret < 0)
{
uint8_t *rd_data = (uint8_t *)rd_buf;
for (tf_size = 0; tf_size < MR_ALIGN_DOWN(size, sizeof(*rd_data)); tf_size += sizeof(*rd_data))
{
ops->write(spi_bus, 0);
*rd_data = ops->read(spi_bus);
rd_data++;
}
break;
}
case MR_SPI_DATA_BITS_16:
{
uint16_t *rd_data = (uint16_t *)rd_buf;
for (tf_size = 0; tf_size < MR_ALIGN_DOWN(size, sizeof(*rd_data)); tf_size += sizeof(*rd_data))
{
ops->write(spi_bus, 0);
*rd_data = ops->read(spi_bus);
rd_data++;
}
break;
}
case MR_SPI_DATA_BITS_32:
{
uint32_t *rd_data = (uint32_t *)rd_buf;
for (tf_size = 0; tf_size < MR_ALIGN_DOWN(size, sizeof(*rd_data)); tf_size += sizeof(*rd_data))
{
ops->write(spi_bus, 0);
*rd_data = ops->read(spi_bus);
rd_data++;
}
break;
}
default:
{
return MR_EINVAL;
return (tf_size == 0) ? ret : tf_size;
}
rd_buf++;
}
} else if (rdwr == MR_SPI_WR)
{
switch (spi_dev->config.data_bits)
for (tf_size = 0; tf_size < size; tf_size += sizeof(*wr_buf))
{
case MR_SPI_DATA_BITS_8:
int ret = ops->write(spi_bus, *wr_buf);
if (ret < 0)
{
uint8_t *wr_data = (uint8_t *)wr_buf;
for (tf_size = 0; tf_size < MR_ALIGN_DOWN(size, sizeof(*wr_data)); tf_size += sizeof(*wr_data))
{
ops->write(spi_bus, *wr_data);
ops->read(spi_bus);
wr_data++;
}
break;
}
case MR_SPI_DATA_BITS_16:
{
uint16_t *wr_data = (uint16_t *)wr_buf;
for (tf_size = 0; tf_size < MR_ALIGN_DOWN(size, sizeof(*wr_data)); tf_size += sizeof(*wr_data))
{
ops->write(spi_bus, *wr_data);
ops->read(spi_bus);
wr_data++;
}
break;
}
case MR_SPI_DATA_BITS_32:
{
uint32_t *wr_data = (uint32_t *)wr_buf;
for (tf_size = 0; tf_size < MR_ALIGN_DOWN(size, sizeof(*wr_data)); tf_size += sizeof(*wr_data))
{
ops->write(spi_bus, *wr_data);
ops->read(spi_bus);
wr_data++;
}
break;
}
default:
{
return MR_EINVAL;
return (tf_size == 0) ? ret : tf_size;
}
ops->read(spi_bus, MR_MAKE_LOCAL(uint8_t, 0));
wr_buf++;
}
} else
{
switch (spi_dev->config.data_bits)
for (tf_size = 0; tf_size < MR_ALIGN_DOWN(size, sizeof(*wr_buf)); tf_size += sizeof(*wr_buf))
{
case MR_SPI_DATA_BITS_8:
int ret = ops->write(spi_bus, *wr_buf);
if (ret < 0)
{
uint8_t *rd_data = (uint8_t *)rd_buf;
uint8_t *wr_data = (uint8_t *)wr_buf;
for (tf_size = 0; tf_size < MR_ALIGN_DOWN(size, sizeof(*wr_data)); tf_size += sizeof(*wr_data))
{
ops->write(spi_bus, *wr_data);
*rd_data = ops->read(spi_bus);
rd_data++;
wr_data++;
}
break;
return (tf_size == 0) ? ret : tf_size;
}
case MR_SPI_DATA_BITS_16:
ret = ops->read(spi_bus, rd_buf);
if (ret < 0)
{
uint16_t *wr_data = (uint16_t *)wr_buf;
uint16_t *rd_data = (uint16_t *)rd_buf;
for (tf_size = 0; tf_size < MR_ALIGN_DOWN(size, sizeof(*wr_data)); tf_size += sizeof(*wr_data))
{
ops->write(spi_bus, *wr_data);
*rd_data = ops->read(spi_bus);
rd_data++;
wr_data++;
}
break;
}
case MR_SPI_DATA_BITS_32:
{
uint32_t *wr_data = (uint32_t *)wr_buf;
uint32_t *rd_data = (uint32_t *)rd_buf;
for (tf_size = 0; tf_size < MR_ALIGN_DOWN(size, sizeof(*wr_data)); tf_size += sizeof(*wr_data))
{
ops->write(spi_bus, *wr_data);
*rd_data = ops->read(spi_bus);
rd_data++;
wr_data++;
}
break;
}
default:
{
return MR_EINVAL;
return (tf_size == 0) ? ret : tf_size;
}
rd_buf++;
wr_buf++;
}
}
return (ssize_t)tf_size;
@@ -413,7 +332,17 @@ static ssize_t mr_spi_dev_read(struct mr_dev *dev, void *buf, size_t count)
/* Send the address of the register that needs to be read */
if (dev->position >= 0)
{
spi_dev_transfer(spi_dev, MR_NULL, &dev->position, (spi_dev->config.reg_bits >> 3), MR_SPI_WR);
ret = spi_dev_transfer(spi_dev,
MR_NULL,
(uint8_t *)&dev->position,
(spi_dev->config.reg_bits >> 3),
MR_SPI_WR);
if (ret < 0)
{
spi_dev_cs_set(spi_dev, MR_DISABLE);
spi_dev_release_bus(spi_dev);
return ret;
}
}
ret = spi_dev_transfer(spi_dev, buf, MR_NULL, count, MR_SPI_RD);
@@ -444,7 +373,17 @@ static ssize_t mr_spi_dev_write(struct mr_dev *dev, const void *buf, size_t coun
/* Send the address of the register that needs to be written */
if (dev->position >= 0)
{
spi_dev_transfer(spi_dev, MR_NULL, &dev->position, (spi_dev->config.reg_bits >> 3), MR_SPI_WR);
ret = spi_dev_transfer(spi_dev,
MR_NULL,
(uint8_t *)&dev->position,
(spi_dev->config.reg_bits >> 3),
MR_SPI_WR);
if (ret < 0)
{
spi_dev_cs_set(spi_dev, MR_DISABLE);
spi_dev_release_bus(spi_dev);
return ret;
}
}
ret = spi_dev_transfer(spi_dev, MR_NULL, buf, count, MR_SPI_WR);

View File

@@ -61,7 +61,7 @@ struct mr_adc_ops
{
int (*configure)(struct mr_adc *adc, int state);
int (*channel_configure)(struct mr_adc *adc, int channel, int state);
uint32_t (*read)(struct mr_adc *adc, int channel);
int (*read)(struct mr_adc *adc, int channel, uint32_t *data);
};
int mr_adc_register(struct mr_adc *adc, const char *path, struct mr_drv *drv);

View File

@@ -61,7 +61,7 @@ struct mr_dac_ops
{
int (*configure)(struct mr_dac *dac, int state);
int (*channel_configure)(struct mr_dac *dac, int channel, int state);
void (*write)(struct mr_dac *dac, int channel, uint32_t data);
int (*write)(struct mr_dac *dac, int channel, uint32_t data);
};
int mr_dac_register(struct mr_dac *dac, const char *path, struct mr_drv *drv);

View File

@@ -99,10 +99,10 @@ struct mr_i2c_bus_ops
{
int (*configure)(struct mr_i2c_bus *i2c_bus, struct mr_i2c_config *config, int addr, int addr_bits);
void (*start)(struct mr_i2c_bus *i2c_bus);
void (*send_addr)(struct mr_i2c_bus *i2c_bus, int addr, int addr_bits);
int (*send_addr)(struct mr_i2c_bus *i2c_bus, int addr, int addr_bits);
void (*stop)(struct mr_i2c_bus *i2c_bus);
uint8_t (*read)(struct mr_i2c_bus *i2c_bus, int ack_state);
void (*write)(struct mr_i2c_bus *i2c_bus, uint8_t data);
int (*read)(struct mr_i2c_bus *i2c_bus, uint8_t *data, int ack_state);
int (*write)(struct mr_i2c_bus *i2c_bus, uint8_t data);
};
/**

View File

@@ -83,8 +83,8 @@ struct mr_pin
struct mr_pin_ops
{
int (*configure)(struct mr_pin *pin, int number, int mode);
uint8_t (*read)(struct mr_pin *pin, int number);
void (*write)(struct mr_pin *pin, int number, uint8_t value);
int (*read)(struct mr_pin *pin, int number, uint8_t *value);
int (*write)(struct mr_pin *pin, int number, uint8_t value);
};
int mr_pin_register(struct mr_pin *pin, const char *path, struct mr_drv *drv);

View File

@@ -87,8 +87,8 @@ struct mr_pwm_ops
int (*configure)(struct mr_pwm *pwm, int state);
int (*channel_configure)(struct mr_pwm *pwm, int channel, int state, int polarity);
void (*start)(struct mr_pwm *pwm, uint32_t prescaler, uint32_t period);
void (*write)(struct mr_pwm *pwm, int channel, uint32_t compare_value);
uint32_t (*read)(struct mr_pwm *pwm, int channel);
int (*read)(struct mr_pwm *pwm, int channel, uint32_t *compare_value);
int (*write)(struct mr_pwm *pwm, int channel, uint32_t compare_value);
};
int mr_pwm_register(struct mr_pwm *pwm, const char *path, struct mr_drv *drv, struct mr_pwm_info *info);

View File

@@ -112,6 +112,7 @@ typedef uint8_t mr_serial_data_t; /**< Serial
*/
#define MR_ISR_SERIAL_RD_INT (MR_ISR_RD | (0x01)) /**< Read interrupt */
#define MR_ISR_SERIAL_WR_INT (MR_ISR_WR | (0x02)) /**< Write interrupt */
#define MR_ISR_SERIAL_RD_IDLE (MR_ISR_RD | (0x03)) /**< Read idle */
/**
* @brief Serial structure.
@@ -133,8 +134,8 @@ struct mr_serial
struct mr_serial_ops
{
int (*configure)(struct mr_serial *serial, struct mr_serial_config *config);
uint8_t (*read)(struct mr_serial *serial);
void (*write)(struct mr_serial *serial, uint8_t data);
int (*read)(struct mr_serial *serial, uint8_t *data);
int (*write)(struct mr_serial *serial, uint8_t data);
void (*start_tx)(struct mr_serial *serial);
void (*stop_tx)(struct mr_serial *serial);
};

View File

@@ -36,13 +36,6 @@ extern "C" {
#define MR_SPI_MODE_2 (2) /**< CPOL = 1, CPHA = 0 */
#define MR_SPI_MODE_3 (3) /**< CPOL = 1, CPHA = 1 */
/**
* @brief SPI data bits.
*/
#define MR_SPI_DATA_BITS_8 (8) /**< 8 bits data */
#define MR_SPI_DATA_BITS_16 (16) /**< 16 bits data */
#define MR_SPI_DATA_BITS_32 (32) /**< 32 bits data */
/**
* @brief SPI bit order.
*/
@@ -64,7 +57,6 @@ extern "C" {
3000000, \
MR_SPI_HOST, \
MR_SPI_MODE_0, \
MR_SPI_DATA_BITS_8, \
MR_SPI_BIT_ORDER_MSB, \
MR_SPI_REG_BITS_8, \
}
@@ -77,7 +69,6 @@ struct mr_spi_config
uint32_t baud_rate; /**< Baud rate */
int host_slave; /**< Host/slave */
int mode; /**< Mode */
int data_bits; /**< Data bits */
int bit_order; /**< Bit order */
int reg_bits; /**< Register bits */
};
@@ -137,8 +128,8 @@ struct mr_spi_bus
struct mr_spi_bus_ops
{
int (*configure)(struct mr_spi_bus *spi_bus, struct mr_spi_config *config);
uint32_t (*read)(struct mr_spi_bus *spi_bus);
void (*write)(struct mr_spi_bus *spi_bus, uint32_t data);
int (*read)(struct mr_spi_bus *spi_bus, uint8_t *data);
int (*write)(struct mr_spi_bus *spi_bus, uint8_t data);
};
/**

View File

@@ -115,6 +115,7 @@ typedef void (*mr_init_fn_t)(void); /**< Auto in
#define MR_EEXIST (-5) /**< Exists */
#define MR_ENOTSUP (-6) /**< Operation not supported */
#define MR_EINVAL (-7) /**< Invalid argument */
#define MR_ETIMEOUT (-8) /**< Timeout */
/** @} */
/**

View File

@@ -170,6 +170,8 @@ const char *mr_strerror(int err)
return "operation not supported";
case MR_EINVAL:
return "invalid argument";
case MR_ETIMEOUT:
return "timeout";
default:
return "unknown error";
}