feat(serial,device): 新增串口异步写功能

body
1.串口异步写入功能适配,串口设备全部功能已完成。
2.设备异步操作函数名与宏命名修改。
3.Python脚本优化'mr_lib.h'中include路径。
This commit is contained in:
MacRsh
2024-05-12 02:34:44 +08:00
parent a2284e4278
commit c50aa742a1
17 changed files with 453 additions and 218 deletions

View File

@@ -15,8 +15,9 @@ menu "Uart driver configure"
range 1 4
config MR_USE_UART1_DMA
depends on MR_USE_SERIAL_DMA
bool "Use uart1 dma"
default n
default y
endmenu
# UART2
@@ -33,8 +34,9 @@ menu "Uart driver configure"
range 1 2
config MR_USE_UART2_DMA
depends on MR_USE_SERIAL_DMA
bool "Use uart2 dma"
default n
default y
endmenu
# UART3
@@ -51,8 +53,9 @@ menu "Uart driver configure"
range 1 4
config MR_USE_UART3_DMA
depends on MR_USE_SERIAL_DMA
bool "Use uart3 dma"
default n
default y
endmenu
# UART4
@@ -69,8 +72,9 @@ menu "Uart driver configure"
range 1 3
config MR_USE_UART4_DMA
depends on MR_USE_SERIAL_DMA
bool "Use uart4 dma"
default n
default y
endmenu
# UART5
@@ -87,8 +91,9 @@ menu "Uart driver configure"
range 1 3
config MR_USE_UART5_DMA
depends on MR_USE_SERIAL_DMA
bool "Use uart5 dma"
default n
default y
endmenu
# UART6
@@ -105,8 +110,9 @@ menu "Uart driver configure"
range 1 3
config MR_USE_UART6_DMA
depends on MR_USE_SERIAL_DMA
bool "Use uart6 dma"
default n
default y
endmenu
# UART7
@@ -123,8 +129,9 @@ menu "Uart driver configure"
range 1 3
config MR_USE_UART7_DMA
depends on MR_USE_SERIAL_DMA
bool "Use uart7 dma"
default n
default y
endmenu
# UART8
@@ -141,8 +148,9 @@ menu "Uart driver configure"
range 1 3
config MR_USE_UART8_DMA
depends on MR_USE_SERIAL_DMA
bool "Use uart8 dma"
default n
default y
endmenu
endif

View File

@@ -136,6 +136,9 @@ static int serial_driver_configure(struct mr_driver *driver, bool enable,
if (enable == true)
{
/* Configure baud rate */
USART_InitStructure.USART_BaudRate = config->baud_rate;
/* Configure data bits */
switch (config->data_bits)
{
case MR_SERIAL_DATA_BITS_8:
@@ -238,7 +241,6 @@ static int serial_driver_configure(struct mr_driver *driver, bool enable,
}
/* Configure UART */
USART_InitStructure.USART_BaudRate = config->baud_rate;
USART_InitStructure.USART_HardwareFlowControl = 0;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(serial->instance, &USART_InitStructure);

View File

@@ -1,21 +1,22 @@
menu "Device configure"
# Name
config MR_CFG_DEVICE_NAME_MAX
int "Device name max length"
range 4 1024
default 12
help
"This option sets the max length of the device name."
This option sets the max length of the device name.
# Descriptors
config MR_CFG_DESCRIPTOR_MAX
int "Descriptors max number"
range 8 4096
default 128
help
"This option sets the max number of descriptors."
int "Descriptors max number"
range 8 4096
default 128
help
This option sets the max number of descriptors.
comment " Device "
comment "--- Device ---"
# ADC
source "device/adc/Kconfig"
@@ -25,4 +26,5 @@ menu "Device configure"
# Serial
source "device/serial/Kconfig"
endmenu
endmenu

View File

@@ -1,15 +1,17 @@
menu "Adc configure"
config MR_USE_ADC
bool "Use adc"
default y
help
"Use this option allows for the use of adc."
menu "ADC configure"
# ADC
config MR_USE_ADC
bool "Use ADC"
default n
help
Use this option allows for the use of ADC.
# Check
config MR_USE_ADC_CHECK
depends on MR_USE_ADC
bool "Use adc check"
bool "Use ADC check"
default y
help
"This option allows for the use of adc check."
endmenu
This option allows for the use of ADC check.
endmenu

View File

@@ -18,7 +18,7 @@
(MR_BIT_IS_SET((_adc)->channels, (1 << (_channel))))
MR_INLINE int _adc_channel_configure_set(struct mr_adc *adc, int channel,
struct mr_adc_config *config)
const struct mr_adc_config *config)
{
struct mr_driver *driver = _MR_DEVICE_DRIVER_GET((struct mr_device *)adc);
struct mr_adc_driver_ops *ops = _MR_DRIVER_OPS_GET(driver);
@@ -60,7 +60,7 @@ MR_INLINE int _adc_channel_configure_set(struct mr_adc *adc, int channel,
return MR_EOK;
}
MR_INLINE int _adc_channel_configure_get(struct mr_adc *adc, int channel,
MR_INLINE int _adc_channel_configure_get(const struct mr_adc *adc, int channel,
struct mr_adc_config *config)
{
/* Check if the channel is valid */
@@ -228,7 +228,7 @@ static int adc_ioctl(struct mr_device *device, int pos, int cmd, void *args)
* @return The error code.
*/
int mr_adc_register(struct mr_adc *adc, const char *path,
struct mr_driver *driver)
const struct mr_driver *driver)
{
MR_ASSERT(adc != NULL);
MR_ASSERT(path != NULL);

View File

@@ -1,15 +1,17 @@
menu "Pin configure"
# Pin
config MR_USE_PIN
bool "Use pin"
default y
default n
help
"Use this option allows for the use of pin."
Use this option allows for the use of pin.
# Check
config MR_USE_PIN_CHECK
depends on MR_USE_PIN
bool "Use pin check"
default y
help
"This option allows for the use of pin check."
endmenu
This option allows for the use of pin check.
endmenu

View File

@@ -32,7 +32,7 @@
(_PIN_MODE_GET(_pin, _number) != MR_PIN_MODE_NONE)
MR_INLINE int _pin_configure_set(struct mr_pin *pin, int number,
struct mr_pin_config *config)
const struct mr_pin_config *config)
{
struct mr_driver *driver = _MR_DEVICE_DRIVER_GET((struct mr_device *)pin);
struct mr_pin_driver_ops *ops = _MR_DRIVER_OPS_GET(driver);
@@ -68,7 +68,7 @@ MR_INLINE int _pin_configure_set(struct mr_pin *pin, int number,
return MR_EOK;
}
MR_INLINE int _pin_configure_get(struct mr_pin *pin, int number,
MR_INLINE int _pin_configure_get(const struct mr_pin *pin, int number,
struct mr_pin_config *config)
{
/* Check if the pin is valid */
@@ -257,12 +257,14 @@ static int pin_isr(struct mr_device *device, uint32_t event, void *args)
/* Check if the pin is enabled */
if ((_PIN_IS_VALID(pin, *number) == false) ||
_PIN_IS_ENABLED(pin, *number) == false)
(_PIN_IS_ENABLED(pin, *number) == false))
{
/* This EXTI will be ignored */
return MR_EINVAL;
}
return MR_EOK;
/* Return the interrupt source pin number */
return *number;
}
default:
{
@@ -281,7 +283,7 @@ static int pin_isr(struct mr_device *device, uint32_t event, void *args)
* @return The error code.
*/
int mr_pin_register(struct mr_pin *pin, const char *path,
struct mr_driver *driver)
const struct mr_driver *driver)
{
static struct mr_device_ops ops = {.open = pin_open,
.close = pin_close,
@@ -296,8 +298,8 @@ int mr_pin_register(struct mr_pin *pin, const char *path,
/* Register the pin */
return mr_device_register((struct mr_device *)pin, path,
MR_DEVICE_TYPE_PIN | MR_DEVICE_TYPE_FULL_DUPLEX,
&ops, driver);
MR_DEVICE_TYPE_PIN | MR_DEVICE_TYPE_FDX, &ops,
driver);
}
#endif /* MR_USE_PIN */

View File

@@ -1,51 +1,58 @@
menu "Serial configure"
# Serial
config MR_USE_SERIAL
bool "Use serial"
default y
default n
help
"Use this option allows for the use of serial."
Use this option allows for the use of serial.
# RD-FIFO
config MR_CFG_SERIAL_RD_FIFO_SIZE
depends on MR_USE_SERIAL
int "Serial read fifo size"
int "Serial read FIFO size"
range 0 2147483647
default 128
help
"This option sets the size of the read fifo."
This option sets the size of the read FIFO.
# WR-FIFO
config MR_CFG_SERIAL_WR_FIFO_SIZE
depends on MR_USE_SERIAL
int "Serial write fifo size"
int "Serial write FIFO size"
range 0 2147483647
default 0
help
"This option sets the size of the write fifo."
This option sets the size of the write FIFO.
# DMA
config MR_USE_SERIAL_DMA
depends on MR_USE_SERIAL
bool "Use serial dma"
bool "Use serial DMA"
default n
help
"Use this option allows for the use of serial dma."
Use this option allows for the use of serial DMA.
# DMA RD-FIFO
config MR_CFG_SERIAL_RD_DMA_FIFO_SIZE
depends on MR_USE_SERIAL_DMA
int "Serial read dma fifo size"
int "Serial read DMA FIFO size"
range 0 2147483647
default 128
help
"This option sets the size of the read dma fifo."
This option sets the size of the read DMA FIFO.
# DMA WR-FIFO
config MR_CFG_SERIAL_WR_DMA_FIFO_SIZE
depends on MR_USE_SERIAL_DMA
int "Serial write dma fifo size"
int "Serial write DMA FIFO size"
range 0 2147483647
default 128
help
"This option sets the size of the write dma fifo."
endmenu
This option sets the size of the write DMA FIFO.
# Async
config MR_USE_SERIAL_ASYNC
depends on MR_USE_SERIAL
bool "Use serial async"
default n
help
Use this option allows for the use of serial async.
endmenu

View File

@@ -11,13 +11,15 @@
#ifdef MR_USE_SERIAL
#define _SERIAL_STATE_RECEIVE_INT_ASYNC (0x01 << 0) /**< Receive interrupt async */
#define _SERIAL_STATE_SEND_INT (0x01 << 8) /**< Send interrupt */
#define _SERIAL_STATE_SEND_INT_ASYNC (0x02 << 8) /**< Send interrupt async */
#define _SERIAL_STATE_RECEIVE_DMA (0x01 << 16) /**< Receive DMA */
#define _SERIAL_STATE_RECEIVE_DMA_TOP (0x02 << 16) /**< Receive DMA top */
#define _SERIAL_STATE_RECEIVE_DMA_BOT (0x04 << 16) /**< Receive DMA bot */
#define _SERIAL_STATE_RECEIVE_DMA_ASYNC (0x08 << 16) /**< Receive DMA async */
#define _STATE_RECEIVE_INT_ASYNC (0x01 << 0) /**< Receive interrupt async */
#define _STATE_SEND_INT (0x01 << 8) /**< Send interrupt */
#define _STATE_SEND_INT_ASYNC (0x02 << 8) /**< Send interrupt async */
#define _STATE_RECEIVE_DMA (0x01 << 16) /**< Receive DMA */
#define _STATE_RECEIVE_DMA_TOP (0x02 << 16) /**< Receive DMA top */
#define _STATE_RECEIVE_DMA_BOT (0x04 << 16) /**< Receive DMA bot */
#define _STATE_RECEIVE_DMA_ASYNC (0x08 << 16) /**< Receive DMA async */
#define _STATE_SEND_DMA (0x01 << 24) /**< Send DMA */
#define _STATE_SEND_DMA_ASYNC (0x08 << 24) /**< Send DMA async */
MR_INLINE ssize_t _serial_read_poll(struct mr_serial *serial, uint8_t *buf,
size_t count)
@@ -51,8 +53,8 @@ MR_INLINE ssize_t _serial_read_fifo(struct mr_serial *serial, uint8_t *buf,
}
#ifdef MR_USE_SERIAL_ASYNC
MR_INLINE ssize_t _serial_async_read_int(struct mr_serial *serial, uint8_t *buf,
size_t count)
MR_INLINE ssize_t _serial_aread_int(struct mr_serial *serial, uint8_t *buf,
size_t count)
{
/* Receive data from FIFO */
size_t rcount = mr_fifo_read(&serial->rfifo, buf, count);
@@ -67,13 +69,13 @@ MR_INLINE ssize_t _serial_async_read_int(struct mr_serial *serial, uint8_t *buf,
/* Set the async receive buffer and count */
serial->rabuf = buf + rcount;
serial->racount = count - rcount;
MR_BIT_SET(serial->state, _SERIAL_STATE_RECEIVE_INT_ASYNC);
MR_BIT_SET(serial->state, _STATE_RECEIVE_INT_ASYNC);
return MR_EOK;
}
#ifdef MR_USE_SERIAL_DMA
MR_INLINE ssize_t _serial_async_read_dma(struct mr_serial *serial, uint8_t *buf,
size_t count)
MR_INLINE ssize_t _serial_aread_dma(struct mr_serial *serial, uint8_t *buf,
size_t count)
{
struct mr_driver *driver =
_MR_DEVICE_DRIVER_GET((struct mr_device *)serial);
@@ -90,12 +92,15 @@ MR_INLINE ssize_t _serial_async_read_dma(struct mr_serial *serial, uint8_t *buf,
}
/* Stop the current transmission */
if (MR_BIT_IS_SET(serial->state, _SERIAL_STATE_RECEIVE_DMA) == true)
if (MR_BIT_IS_SET(serial->state, _STATE_RECEIVE_DMA) == true)
{
ops->receive_dma(driver, false, NULL, 0);
MR_BIT_CLR(serial->state, _SERIAL_STATE_RECEIVE_DMA |
_SERIAL_STATE_RECEIVE_DMA_TOP |
_SERIAL_STATE_RECEIVE_DMA_BOT);
int ret = ops->receive_dma(driver, false, NULL, 0);
if (ret < 0)
{
return ret;
}
MR_BIT_CLR(serial->state, _STATE_RECEIVE_DMA | _STATE_RECEIVE_DMA_TOP |
_STATE_RECEIVE_DMA_BOT);
}
/* Set the async receive buffer and count */
@@ -103,13 +108,12 @@ MR_INLINE ssize_t _serial_async_read_dma(struct mr_serial *serial, uint8_t *buf,
serial->racount = count - rcount;
/* Start the receive DMA */
MR_BIT_SET(serial->state,
_SERIAL_STATE_RECEIVE_DMA | _SERIAL_STATE_RECEIVE_DMA_ASYNC);
MR_BIT_SET(serial->state, _STATE_RECEIVE_DMA | _STATE_RECEIVE_DMA_ASYNC);
int ret = ops->receive_dma(driver, true, serial->rabuf, serial->racount);
if (ret < 0)
{
MR_BIT_CLR(serial->state,
_SERIAL_STATE_RECEIVE_DMA | _SERIAL_STATE_RECEIVE_DMA_ASYNC);
_STATE_RECEIVE_DMA | _STATE_RECEIVE_DMA_ASYNC);
return ret;
}
return MR_EOK;
@@ -148,39 +152,113 @@ MR_INLINE ssize_t _serial_write_fifo(struct mr_serial *serial,
_MR_DEVICE_DRIVER_GET((struct mr_device *)serial);
struct mr_serial_driver_ops *ops = _MR_DRIVER_OPS_GET(driver);
/* Send data to FIFO */
ssize_t wcount = (ssize_t)mr_fifo_write(&serial->wfifo, buf, count);
if (wcount == 0)
{
return wcount;
}
#ifdef MR_USE_SERIAL_DMA
if (ops->send_dma != NULL)
{
if (MR_BIT_IS_SET(serial->state, _STATE_SEND_DMA) == false)
{
/* Write data to DMA buffer */
size_t wdma_count = mr_fifo_peek(&serial->wfifo, &serial->wdma,
sizeof(serial->wdma));
/* Start the DMA transmission */
MR_BIT_SET(serial->state, _STATE_SEND_DMA);
int ret = ops->send_dma(driver, true, serial->wdma, wdma_count);
if (ret < 0)
{
/* Data has been written to the FIFO, if the boot sent
* fails, wait for the next retry startup */
MR_BIT_CLR(serial->state, _STATE_SEND_DMA);
return wcount;
}
mr_fifo_discard(&serial->wfifo, wdma_count);
return wcount;
}
/* Return the number of bytes sent */
return wcount;
}
#endif /* MR_USE_SERIAL_DMA */
/* Driver does not support this function */
if (ops->send_int_configure == NULL)
{
return MR_EIO;
}
/* Send data to FIFO */
ssize_t wcount = (ssize_t)mr_fifo_write(&serial->wfifo, buf, count);
if (wcount <= 0)
{
return wcount;
}
/* If the serial port is not sending, enable it */
if (MR_BIT_IS_SET(serial->state, _SERIAL_STATE_SEND_INT) == false)
if (MR_BIT_IS_SET(serial->state, _STATE_SEND_INT) == false)
{
/* Enable serial TX interrupt */
MR_BIT_SET(serial->state, _STATE_SEND_INT);
int ret = ops->send_int_configure(driver, true);
if (ret >= 0)
if (ret < 0)
{
/* Data has been written to the FIFO, if the boot sent fails, wait
* for the next retry startup */
MR_BIT_CLR(serial->state, _STATE_SEND_INT);
return wcount;
}
/* Set the sending state */
MR_BIT_SET(serial->state, _SERIAL_STATE_SEND_INT);
}
/* Return the number of bytes sent */
return wcount;
}
#ifdef MR_USE_SERIAL_ASYNC
MR_INLINE ssize_t _serial_awrite_int(struct mr_serial *serial,
const uint8_t *buf, size_t count)
{
struct mr_driver *driver =
_MR_DEVICE_DRIVER_GET((struct mr_device *)serial);
struct mr_serial_driver_ops *ops = _MR_DRIVER_OPS_GET(driver);
/* Set the async send buffer and count */
serial->wabuf = buf;
serial->wacount = count;
MR_BIT_SET(serial->state, _STATE_SEND_INT | _STATE_SEND_INT_ASYNC);
/* Start the send interrupt */
int ret = ops->send_int_configure(driver, true);
if (ret < 0)
{
MR_BIT_CLR(serial->state, _STATE_SEND_INT | _STATE_SEND_INT_ASYNC);
return ret;
}
return MR_EOK;
}
#ifdef MR_USE_SERIAL_DMA
MR_INLINE ssize_t _serial_awrite_dma(struct mr_serial *serial,
const uint8_t *buf, size_t count)
{
struct mr_driver *driver =
_MR_DEVICE_DRIVER_GET((struct mr_device *)serial);
struct mr_serial_driver_ops *ops = _MR_DRIVER_OPS_GET(driver);
/* Set the async send buffer and count */
serial->wabuf = buf;
serial->wacount = count;
MR_BIT_SET(serial->state, _STATE_SEND_DMA | _STATE_SEND_DMA_ASYNC);
/* Start the send DMA */
int ret = ops->send_dma(driver, true, serial->wabuf, serial->wacount);
if (ret < 0)
{
MR_BIT_CLR(serial->state, _STATE_SEND_DMA | _STATE_SEND_DMA_ASYNC);
return ret;
}
return MR_EOK;
}
#endif /* MR_USE_SERIAL_DMA */
#endif /* MR_USE_SERIAL_ASYNC */
MR_INLINE int _serial_fifo_allocate(struct mr_fifo *fifo, size_t *size)
{
/* Allocate new buffer for FIFO */
@@ -215,8 +293,7 @@ static int serial_open(struct mr_device *device)
/* If the driver supports DMA, start DMA to receive data */
if (ops->receive_dma != NULL)
{
MR_BIT_SET(serial->state,
_SERIAL_STATE_RECEIVE_DMA | _SERIAL_STATE_RECEIVE_DMA_TOP);
MR_BIT_SET(serial->state, _STATE_RECEIVE_DMA | _STATE_RECEIVE_DMA_TOP);
ops->receive_dma(driver, true, serial->rdma, sizeof(serial->rdma) / 2);
}
#endif /* MR_USE_SERIAL_DMA */
@@ -229,21 +306,20 @@ static int serial_close(struct mr_device *device)
struct mr_driver *driver = _MR_DEVICE_DRIVER_GET(device);
struct mr_serial_driver_ops *ops = _MR_DRIVER_OPS_GET(driver);
/* Disable serial TX interrupt */
if (MR_BIT_IS_SET(serial->state, _SERIAL_STATE_SEND_INT) == true)
/* If the serial port is sending, disable it */
if (MR_BIT_IS_SET(serial->state, _STATE_SEND_INT) == true)
{
ops->send_int_configure(driver, false);
MR_BIT_CLR(serial->state, _SERIAL_STATE_SEND_INT);
MR_BIT_CLR(serial->state, _STATE_SEND_INT);
}
#ifdef MR_USE_SERIAL_DMA
/* Stop DMA */
if (MR_BIT_IS_SET(serial->state, _SERIAL_STATE_RECEIVE_DMA) == true)
/* If the serial port is receiving, disable it */
if (MR_BIT_IS_SET(serial->state, _STATE_RECEIVE_DMA) == true)
{
ops->receive_dma(driver, false, NULL, 0);
MR_BIT_CLR(serial->state, _SERIAL_STATE_RECEIVE_DMA |
_SERIAL_STATE_RECEIVE_DMA_TOP |
_SERIAL_STATE_RECEIVE_DMA_BOT);
MR_BIT_CLR(serial->state, _STATE_RECEIVE_DMA | _STATE_RECEIVE_DMA_TOP |
_STATE_RECEIVE_DMA_BOT);
}
#endif /* MR_USE_SERIAL_DMA */
@@ -276,14 +352,13 @@ static ssize_t serial_read(struct mr_device *device, int pos, void *buf,
}
#ifdef MR_USE_SERIAL_ASYNC
static ssize_t serial_read_async(struct mr_device *device, int pos, void *buf,
size_t count)
static ssize_t serial_aread(struct mr_device *device, int pos, void *buf,
size_t count)
{
struct mr_serial *serial = (struct mr_serial *)device;
/* Check if the serial port is busy */
if (serial->state &
(_SERIAL_STATE_RECEIVE_INT_ASYNC | _SERIAL_STATE_RECEIVE_DMA_ASYNC))
if (serial->state & (_STATE_RECEIVE_INT_ASYNC | _STATE_RECEIVE_DMA_ASYNC))
{
return MR_EBUSY;
}
@@ -295,12 +370,12 @@ static ssize_t serial_read_async(struct mr_device *device, int pos, void *buf,
/* If the driver supports DMA, start DMA to async read data */
if (ops->receive_dma != NULL)
{
return _serial_async_read_dma(serial, buf, count);
return _serial_aread_dma(serial, buf, count);
}
#endif /* MR_USE_SERIAL_DMA */
/* Interrupt async read data */
return _serial_async_read_int(serial, buf, count);
return _serial_aread_int(serial, buf, count);
}
#endif /* MR_USE_SERIAL_ASYNC */
@@ -308,9 +383,16 @@ static ssize_t serial_write(struct mr_device *device, int pos, const void *buf,
size_t count)
{
struct mr_serial *serial = (struct mr_serial *)device;
struct mr_driver *driver = _MR_DEVICE_DRIVER_GET(device);
struct mr_serial_driver_ops *ops = _MR_DRIVER_OPS_GET(driver);
/* If FIFO is set, write from FIFO */
if (mr_fifo_size_get(&serial->wfifo) != 0)
/* If FIFO is set and the driver supports it, write to FIFO */
if ((mr_fifo_size_get(&serial->wfifo) != 0) &&
((ops->send_int_configure != NULL)
#ifdef MR_USE_SERIAL_DMA
|| (ops->send_dma != NULL)
#endif /* MR_USE_SERIAL_DMA */
))
{
return _serial_write_fifo(serial, buf, count);
}
@@ -319,6 +401,34 @@ static ssize_t serial_write(struct mr_device *device, int pos, const void *buf,
return _serial_write_poll(serial, buf, count);
}
#ifdef MR_USE_SERIAL_ASYNC
static ssize_t serial_awrite(struct mr_device *device, int pos, const void *buf,
size_t count)
{
struct mr_serial *serial = (struct mr_serial *)device;
/* Check if the serial port is busy */
if (serial->state & (_STATE_SEND_INT | _STATE_SEND_DMA))
{
return MR_EBUSY;
}
#ifdef MR_USE_SERIAL_DMA
struct mr_driver *driver = _MR_DEVICE_DRIVER_GET(device);
struct mr_serial_driver_ops *ops = _MR_DRIVER_OPS_GET(driver);
/* If the driver supports DMA, start DMA to async write data */
if (ops->send_dma != NULL)
{
return _serial_awrite_dma(serial, buf, count);
}
#endif /* MR_USE_SERIAL_DMA */
/* Interrupt async write data */
return _serial_awrite_int(serial, buf, count);
}
#endif /* MR_USE_SERIAL_ASYNC */
static int serial_ioctl(struct mr_device *device, int pos, int cmd, void *args)
{
struct mr_serial *serial = (struct mr_serial *)device;
@@ -482,30 +592,26 @@ static int serial_isr(struct mr_device *device, uint32_t event, void *args)
{
size_t count = 1;
/* Hardware FIFO is considered to be used */
if (args != NULL)
{
/* Hardware FIFO is considered to be used */
count = *((size_t *)args);
}
#ifdef MR_USE_SERIAL_ASYNC
if (MR_BIT_IS_SET(serial->state, _SERIAL_STATE_RECEIVE_INT_ASYNC) ==
true)
if (MR_BIT_IS_SET(serial->state, _STATE_RECEIVE_INT_ASYNC) == true)
{
size_t rcount;
/* Read all data from hardware FIFO */
for (rcount = 0; rcount < count; rcount++)
{
uint8_t data;
/* Read data from serial */
int ret = ops->receive(driver, &data);
int ret = ops->receive(driver, serial->rabuf);
if (ret < 0)
{
return ret;
}
*serial->rabuf = data;
serial->rabuf++;
serial->racount--;
@@ -513,8 +619,7 @@ static int serial_isr(struct mr_device *device, uint32_t event, void *args)
if (serial->racount == 0)
{
/* Stop async read operation */
MR_BIT_CLR(serial->state,
_SERIAL_STATE_RECEIVE_INT_ASYNC);
MR_BIT_CLR(serial->state, _STATE_RECEIVE_INT_ASYNC);
break;
}
}
@@ -529,7 +634,8 @@ static int serial_isr(struct mr_device *device, uint32_t event, void *args)
count -= rcount;
if (count == 0)
{
return MR_EOK;
/* Returns the number of data in the read FIFO */
return mr_fifo_used_get(&serial->rfifo);
}
}
#endif /* MR_USE_SERIAL_ASYNC */
@@ -537,7 +643,7 @@ static int serial_isr(struct mr_device *device, uint32_t event, void *args)
/* If FIFO is empty, the read operation is abandoned */
if (mr_fifo_size_get(&serial->rfifo) == 0)
{
return MR_EOK;
return 0;
}
/* Read all data from hardware FIFO */
@@ -555,11 +661,13 @@ static int serial_isr(struct mr_device *device, uint32_t event, void *args)
/* Force write data to FIFO */
mr_fifo_write_force(&serial->rfifo, &data, sizeof(data));
}
return MR_EOK;
/* Returns the number of data in the read FIFO */
return mr_fifo_used_get(&serial->rfifo);
}
case MR_EVENT_SERIAL_WR_COMPLETE_INT:
{
uint8_t data;
size_t count = 1;
/* Driver does not support this function */
if (ops->send_int_configure == NULL)
@@ -567,39 +675,90 @@ static int serial_isr(struct mr_device *device, uint32_t event, void *args)
return MR_EIO;
}
/* If FIFO is empty, the write operation is abandoned */
if (mr_fifo_size_get(&serial->wfifo) == 0)
/* Hardware FIFO is considered to be used */
if (args != NULL)
{
return MR_EOK;
count = *((size_t *)args);
}
/* If FIFO is empty, stop sending */
if (mr_fifo_peek(&serial->wfifo, &data, sizeof(data)) !=
sizeof(data))
#ifdef MR_USE_SERIAL_ASYNC
if (MR_BIT_IS_SET(serial->state, _STATE_SEND_INT_ASYNC) == true)
{
/* Stop sending */
int ret = ops->send_int_configure(driver, false);
size_t wcount;
/* Write all data to hardware FIFO */
for (wcount = 0; wcount < count; wcount++)
{
/* If there is no more data to write, exit the loop */
if (serial->wacount == 0)
{
/* Stop async write operation */
MR_BIT_CLR(serial->state, _STATE_SEND_INT_ASYNC);
break;
}
/* Write data to serial */
int ret = ops->send(driver, *serial->wabuf);
if (ret < 0)
{
return ret;
}
serial->wabuf++;
serial->wacount--;
}
/* Async write operation is incomplete */
if (serial->wacount != 0)
{
return MR_EBUSY;
}
/* If there is any data left, it is stored in the buffer */
count -= wcount;
if (count == 0)
{
/* Returns the number of data in the write FIFO */
return mr_fifo_used_get(&serial->wfifo);
}
}
#endif /* MR_USE_SERIAL_ASYNC */
/* Write all data to hardware FIFO */
for (size_t wcount = 0; wcount < count; wcount++)
{
uint8_t data;
/* If FIFO is empty, stop sending */
if (mr_fifo_peek(&serial->wfifo, &data, sizeof(data)) == 0)
{
/* Stop sending */
int ret = ops->send_int_configure(driver, false);
if (ret < 0)
{
/* If the stop is failed, nothing can do */
return ret;
}
/* Clear the sending state */
MR_BIT_CLR(serial->state, _STATE_SEND_INT);
/* Returns the number of data in the write FIFO */
return mr_fifo_used_get(&serial->wfifo);
}
/* Write data to serial */
int ret = ops->send(driver, data);
if (ret < 0)
{
/* If the stop is failed, nothing can do */
return ret;
}
/* Clear the sending state */
MR_BIT_CLR(serial->state, _SERIAL_STATE_SEND_INT);
return MR_EOK;
/* Discard sent data */
mr_fifo_discard(&serial->wfifo, sizeof(data));
}
/* Write data to serial */
int ret = ops->send(driver, data);
if (ret < 0)
{
return ret;
}
/* Discard data from FIFO */
mr_fifo_discard(&serial->wfifo, sizeof(data));
return MR_EBUSY;
/* Returns the number of data in the write FIFO */
return mr_fifo_used_get(&serial->wfifo);
}
#ifdef MR_USE_SERIAL_DMA
case MR_EVENT_SERIAL_RD_COMPLETE_DMA:
@@ -626,32 +785,31 @@ static int serial_isr(struct mr_device *device, uint32_t event, void *args)
}
/* Ping-pong operation */
if (MR_BIT_IS_SET(serial->state, _SERIAL_STATE_RECEIVE_DMA_TOP) ==
true)
if (MR_BIT_IS_SET(serial->state, _STATE_RECEIVE_DMA_TOP) == true)
{
/* Top half of DMA buffer is used */
rdma = serial->rdma;
ndma = &serial->rdma[sizeof(serial->rdma) / 2];
MR_BIT_CLR(serial->state, _SERIAL_STATE_RECEIVE_DMA_TOP);
MR_BIT_SET(serial->state, _SERIAL_STATE_RECEIVE_DMA_BOT);
} else if (MR_BIT_IS_SET(serial->state,
_SERIAL_STATE_RECEIVE_DMA_BOT) == true)
MR_BIT_CLR(serial->state, _STATE_RECEIVE_DMA_TOP);
MR_BIT_SET(serial->state, _STATE_RECEIVE_DMA_BOT);
} else if (MR_BIT_IS_SET(serial->state, _STATE_RECEIVE_DMA_BOT) ==
true)
{
/* Bottom half of DMA buffer is used */
rdma = &serial->rdma[sizeof(serial->rdma) / 2];
ndma = serial->rdma;
MR_BIT_CLR(serial->state, _SERIAL_STATE_RECEIVE_DMA_BOT);
MR_BIT_SET(serial->state, _SERIAL_STATE_RECEIVE_DMA_TOP);
MR_BIT_CLR(serial->state, _STATE_RECEIVE_DMA_BOT);
MR_BIT_SET(serial->state, _STATE_RECEIVE_DMA_TOP);
}
#ifdef MR_USE_SERIAL_ASYNC
else if (MR_BIT_IS_SET(serial->state,
_SERIAL_STATE_RECEIVE_DMA_ASYNC) == true)
else if (MR_BIT_IS_SET(serial->state, _STATE_RECEIVE_DMA_ASYNC) ==
true)
{
count = serial->racount;
/* Only partially done */
if (args != NULL)
{
/* Only partially done */
count = *((size_t *)args);
/* Not more than async read count */
@@ -668,11 +826,18 @@ static int serial_isr(struct mr_device *device, uint32_t event, void *args)
if (serial->racount == 0)
{
/* Stop async read operation */
MR_BIT_CLR(serial->state, _SERIAL_STATE_RECEIVE_DMA_ASYNC);
MR_BIT_SET(serial->state, _SERIAL_STATE_RECEIVE_DMA_TOP);
ops->receive_dma(driver, true, serial->rdma,
sizeof(serial->rdma) / 2);
return MR_EOK;
MR_BIT_CLR(serial->state, _STATE_RECEIVE_DMA_ASYNC);
MR_BIT_SET(serial->state, _STATE_RECEIVE_DMA_TOP);
int ret = ops->receive_dma(driver, true, serial->rdma,
sizeof(serial->rdma) / 2);
if (ret < 0)
{
return ret;
}
/* Returns the number of data in the read FIFO */
return mr_fifo_used_get(&serial->rfifo);
}
/* Continue reading */
@@ -697,6 +862,45 @@ static int serial_isr(struct mr_device *device, uint32_t event, void *args)
return ops->receive_dma(driver, true, ndma,
sizeof(serial->rdma) / 2);
}
case MR_EVENT_SERIAL_WR_COMPLETE_DMA:
{
/* Driver does not support this function */
if (ops->send_dma == NULL)
{
return MR_EIO;
}
#ifdef MR_USE_SERIAL_ASYNC
if (MR_BIT_IS_SET(serial->state, _STATE_SEND_DMA_ASYNC) == true)
{
/* Async write operation is complete */
MR_BIT_CLR(serial->state, _STATE_SEND_DMA_ASYNC);
int ret = ops->send_dma(driver, false, NULL, 0);
if (ret < 0)
{
return ret;
}
MR_BIT_CLR(serial->state, _STATE_SEND_DMA);
return 0;
}
#endif /* MR_USE_SERIAL_ASYNC */
size_t count = mr_fifo_peek(&serial->wfifo, serial->wdma,
sizeof(serial->wdma));
if (count == 0)
{
/* No data in the write FIFO */
MR_BIT_CLR(serial->state, _STATE_SEND_DMA);
return 0;
}
int ret = ops->send_dma(driver, true, serial->wdma, count);
if (ret < 0)
{
return ret;
}
return MR_EBUSY;
}
#endif /* MR_USE_SERIAL_DMA */
default:
{
@@ -725,7 +929,8 @@ int mr_serial_register(struct mr_serial *serial, const char *path,
.close = serial_close,
.read = serial_read,
#ifdef MR_USE_SERIAL_ASYNC
.read_async = serial_read_async,
.aread = serial_aread,
.awrite = serial_awrite,
#endif /* MR_USE_SERIAL_ASYNC */
.write = serial_write,
.ioctl = serial_ioctl,
@@ -747,9 +952,9 @@ int mr_serial_register(struct mr_serial *serial, const char *path,
serial->state = 0;
/* Register the serial */
return mr_device_register(
(struct mr_device *)serial, path,
MR_DEVICE_TYPE_SERIAL | MR_DEVICE_TYPE_FULL_DUPLEX, &ops, driver);
return mr_device_register((struct mr_device *)serial, path,
MR_DEVICE_TYPE_SERIAL | MR_DEVICE_TYPE_FDX, &ops,
driver);
}
#endif /* MR_USE_SERIAL */

View File

@@ -1,3 +1,5 @@
menu "Driver configure"
# No driver
endmenu

View File

@@ -69,8 +69,8 @@ struct mr_adc_driver_data
uint32_t resolution; /**< Resolution */
};
int mr_adc_register(struct mr_adc *adc, const char *path,
struct mr_driver *driver);
int mr_adc_register(struct mr_adc *adc, const char *path,
const struct mr_driver *driver);
/** @} */

View File

@@ -78,8 +78,8 @@ struct mr_pin_driver_data
uint32_t pins[16]; /**< Pins exists mask */
};
int mr_pin_register(struct mr_pin *pin, const char *path,
struct mr_driver *driver);
int mr_pin_register(struct mr_pin *pin, const char *path,
const struct mr_driver *driver);
/** @} */

View File

@@ -68,6 +68,8 @@ extern "C" {
MR_EVENT_WR_COMPLETE /**< Interrupt on write completion event */
#define MR_EVENT_SERIAL_RD_COMPLETE_DMA \
(MR_EVENT_RD_COMPLETE | 0x01) /**< Interrupt on read DMA completion event */
#define MR_EVENT_SERIAL_WR_COMPLETE_DMA \
(MR_EVENT_WR_COMPLETE | 0x01) /**< Interrupt on write DMA completion event */
typedef uint8_t mr_serial_data_t; /**< Serial read/write data type */
@@ -110,7 +112,7 @@ struct mr_serial
#ifdef MR_USE_SERIAL_ASYNC
uint8_t *rabuf; /**< Read async buffer */
size_t racount; /**< Read async count */
uint8_t *wabuf; /**< Write async buffer */
const uint8_t *wabuf; /**< Write async buffer */
size_t wacount; /**< Write async count */
#endif /* MR_USE_SERIAL_ASYNC */
};

View File

@@ -155,9 +155,9 @@ struct mr_fifo
#define MR_FLAG_RDONLY (0x01 << 24) /**< Read only flag */
#define MR_FLAG_WRONLY (0x02 << 24) /**< Write only flag */
#define MR_FLAG_RDWR (0x03 << 24) /**< Read/write flag */
#define MR_FLAG_RDONLY_ASYNC (0x04 << 24) /**< Async read only flag */
#define MR_FLAG_WRONLY_ASYNC (0x08 << 24) /**< Async write only flag */
#define MR_FLAG_RDWR_ASYNC (0x0c << 24) /**< Async read/write flag */
#define MR_FLAG_ARDONLY (0x04 << 24) /**< Async read only flag */
#define MR_FLAG_AWRONLY (0x08 << 24) /**< Async write only flag */
#define MR_FLAG_ARDWR (0x0c << 24) /**< Async read/write flag */
#define MR_CTRL_SET(_cmd) (_cmd) /**< Set operation */
#define MR_CTRL_GET(_cmd) (-(_cmd)) /**< Get operation */
@@ -191,7 +191,7 @@ enum mr_device_type
MR_DEVICE_TYPE_SPI, /**< SPI device */
MR_DEVICE_TYPE_TIMER, /**< Timer device */
MR_DEVICE_TYPE_PWM, /**< PWM device */
MR_DEVICE_TYPE_FULL_DUPLEX = 0x80000000, /**< Full duplex device */
MR_DEVICE_TYPE_FDX = 0x80000000, /**< Full duplex device */
};
struct mr_device;
@@ -206,10 +206,10 @@ struct mr_device_ops
ssize_t (*read)(struct mr_device *device, int pos, void *buf, size_t count);
ssize_t (*write)(struct mr_device *device, int pos, const void *buf,
size_t count);
ssize_t (*read_async)(struct mr_device *device, int pos, void *buf,
size_t count);
ssize_t (*write_async)(struct mr_device *device, int pos, const void *buf,
size_t count);
ssize_t (*aread)(struct mr_device *device, int pos, void *buf,
size_t count);
ssize_t (*awrite)(struct mr_device *device, int pos, const void *buf,
size_t count);
int (*ioctl)(struct mr_device *device, int pos, int cmd, void *args);
int (*isr)(struct mr_device *device, uint32_t event, void *args);
@@ -232,13 +232,13 @@ struct mr_device
void *parent; /**< Parent device */
uint32_t type: 31; /**< Type */
uint32_t full_duplex: 1; /**< Full duplex */
uint32_t fdx: 1; /**< Full duplex */
uint32_t flags; /**< Flags */
size_t ref_count; /**< Reference count */
volatile uint32_t lock; /**< Operation lock */
const struct mr_device_ops *ops; /**< Operations */
const void *driver; /**< Driver */
struct mr_list event_list; /**< Event list */
struct mr_list elist; /**< Event list */
};
/**

View File

@@ -1,4 +1,5 @@
menu "Framework configure"
# Printf
menu "Printf configure"
config MR_CFG_PRINTF_BUF_SIZE
@@ -6,13 +7,13 @@ menu "Framework configure"
default 256
range 32 2147483647
help
"This option sets the buffer size used by the printf function."
This option sets the buffer size used by the printf function.
config MR_CFG_PRINTF_NAME
string "Printf port device name"
default "serial1"
help
"This option sets the name of the device used by the printf function."
This option sets the name of the device used by the printf function.
endmenu
# Log
@@ -21,32 +22,32 @@ menu "Framework configure"
bool "Use error log"
default y
help
"Use this option allows for the use of error log."
Use this option allows for the use of error log.
config MR_USE_LOG_WARN
bool "Use warning log"
default y
help
"Use this option allows for the use of warning log."
Use this option allows for the use of warning log.
config MR_USE_LOG_INFO
bool "Use info log"
default y
help
"Use this option allows for the use of info log."
Use this option allows for the use of info log.
config MR_USE_LOG_DEBUG
bool "Use debug log"
default y
help
"Use this option allows for the use of debug log."
Use this option allows for the use of debug log.
config MR_CFG_LOG_PRINTF_BUF_SIZE
int "Log printf buffer size"
default 256
range 32 2147483647
help
"This option sets the buffer size used by the log printf function."
This option sets the buffer size used by the log printf function.
endmenu
# Assert
@@ -54,14 +55,14 @@ menu "Framework configure"
bool "Use assert"
default y
help
"Use this option allows the use of assert statements in the code."
Use this option allows the use of assert statements in the code.
# Heap
config MR_CFG_HEAP_SIZE
int "Heap size (Bytes)"
default 4096
int "Heap size (bytes)"
default 8192
range 32 2147483647
help
"This option sets the size of the heap used by the library."
endmenu
This option sets the size of the heap used by the library.
endmenu

View File

@@ -157,8 +157,8 @@ MR_INLINE int _device_event_create(struct mr_device *device, int descriptor,
mr_critical_enter();
/* Check if the event exists */
for (struct mr_list *list = device->event_list.next;
list != &device->event_list; list = list->next)
for (struct mr_list *list = device->elist.next; list != &device->elist;
list = list->next)
{
struct _device_event *_event =
MR_CONTAINER_OF(list, struct _device_event, list);
@@ -186,7 +186,7 @@ MR_INLINE int _device_event_create(struct mr_device *device, int descriptor,
_event->event = event->event;
_event->private = event->private;
_event->callback = event->callback;
mr_list_insert_before(&device->event_list, &_event->list);
mr_list_insert_before(&device->elist, &_event->list);
ret = MR_EOK;
_exit:
@@ -205,8 +205,8 @@ MR_INLINE int _device_event_destroy(const struct mr_device *device,
mr_critical_enter();
/* Find the event */
for (struct mr_list *list = device->event_list.next;
list != &device->event_list; list = list->next)
for (struct mr_list *list = device->elist.next; list != &device->elist;
list = list->next)
{
struct _device_event *_event =
MR_CONTAINER_OF(list, struct _device_event, list);
@@ -246,8 +246,8 @@ MR_INLINE void _device_event_destroy_all(const struct mr_device *device,
mr_critical_enter();
/* Destroy all events for the specified descriptor */
for (struct mr_list *list = device->event_list.next;
list != &device->event_list; list = list->next)
for (struct mr_list *list = device->elist.next; list != &device->elist;
list = list->next)
{
struct _device_event *_event =
MR_CONTAINER_OF(list, struct _device_event, list);
@@ -277,8 +277,8 @@ MR_INLINE void _device_event_handler(const struct mr_device *device,
uint32_t event, void *args)
{
/* Trigger events */
for (struct mr_list *list = device->event_list.next;
list != &device->event_list; list = list->next)
for (struct mr_list *list = device->elist.next; list != &device->elist;
list = list->next)
{
struct _device_event *_event =
MR_CONTAINER_OF(list, struct _device_event, list);
@@ -310,8 +310,8 @@ MR_INLINE void _device_event_handler(const struct mr_device *device,
}
/* Destroy free events */
for (struct mr_list *list = device->event_list.next;
list != &device->event_list; list = list->next)
for (struct mr_list *list = device->elist.next; list != &device->elist;
list = list->next)
{
struct _device_event *_event =
MR_CONTAINER_OF(list, struct _device_event, list);
@@ -363,7 +363,7 @@ MR_INLINE int _device_take(struct mr_device *device, int descriptor,
int ret;
/* If the device is not FDX, the read/writing must be locked */
mask = (device->full_duplex == true) ? mask : _MR_OPERATE_MASK_ALL;
mask = (device->fdx == true) ? mask : _MR_OPERATE_MASK_ALL;
/* Calculate the lock mask, since the descriptor can be 0, need to add 1 */
uint32_t lock = (((descriptor + 1) << 16) | (descriptor + 1)) & mask;
@@ -392,7 +392,7 @@ MR_INLINE int _device_take(struct mr_device *device, int descriptor,
MR_INLINE void _device_release(struct mr_device *device, uint32_t mask)
{
/* If the device is not FDX, the read/writing must be locked */
mask = (device->full_duplex == true) ? mask : _MR_OPERATE_MASK_ALL;
mask = (device->fdx == true) ? mask : _MR_OPERATE_MASK_ALL;
/* Release the device lock */
MR_BIT_CLR(device->lock, mask);
@@ -468,17 +468,17 @@ static int _device_register(struct mr_device *device, const char *path,
mr_list_init(&device->list);
mr_list_init(&device->clist);
device->parent = NULL;
device->type = type & (~MR_DEVICE_TYPE_FULL_DUPLEX);
device->full_duplex = MR_BIT_IS_SET(type, MR_DEVICE_TYPE_FULL_DUPLEX);
device->type = type & (~MR_DEVICE_TYPE_FDX);
device->fdx = MR_BIT_IS_SET(type, MR_DEVICE_TYPE_FDX);
device->flags = (ops->read != NULL ? MR_FLAG_RDONLY : 0) |
(ops->write != NULL ? MR_FLAG_WRONLY : 0) |
(ops->read_async != NULL ? MR_FLAG_RDONLY_ASYNC : 0) |
(ops->write_async != NULL ? MR_FLAG_WRONLY_ASYNC : 0);
(ops->aread != NULL ? MR_FLAG_ARDONLY : 0) |
(ops->awrite != NULL ? MR_FLAG_AWRONLY : 0);
device->ref_count = 0;
device->lock = 0;
device->ops = ops;
device->driver = driver;
mr_list_init(&device->event_list);
mr_list_init(&device->elist);
/* Critical section enter */
mr_critical_enter();
@@ -566,7 +566,7 @@ static int _device_isr(struct mr_device *device, uint32_t event, void *args)
_device_release(device, mask);
/* Call the event handler */
_device_event_handler(device, event, args);
_device_event_handler(device, event, &ret);
ret = MR_EOK;
_exit:
@@ -686,10 +686,10 @@ static ssize_t _device_read(int descriptor, void *buf, size_t count)
int pos = _descriptor_map[descriptor].pos;
/* Async or sync read */
if (_descriptor_flags_is_valid(descriptor, MR_FLAG_RDONLY_ASYNC) == true)
if (_descriptor_flags_is_valid(descriptor, MR_FLAG_ARDONLY) == true)
{
/* Async read */
ret = device->ops->read_async(device, pos, buf, count);
ret = device->ops->aread(device, pos, buf, count);
if ((ret == 0) && (count > 0))
{
/* If the operation is successful, the device will not be released
@@ -730,10 +730,10 @@ static ssize_t _device_write(int descriptor, const void *buf, size_t count)
int pos = _descriptor_map[descriptor].pos;
/* Async or sync writes */
if (_descriptor_flags_is_valid(descriptor, MR_FLAG_WRONLY_ASYNC) == true)
if (_descriptor_flags_is_valid(descriptor, MR_FLAG_AWRONLY) == true)
{
/* Async write */
ret = device->ops->write_async(device, pos, buf, count);
ret = device->ops->awrite(device, pos, buf, count);
if ((ret == 0) && (count > 0))
{
/* If the operation is successful, the device will not be released

View File

@@ -310,7 +310,7 @@ class MrLib:
# Link include
for hf in header_files:
if hf != os.path.basename(header_out):
header_file.write('#include "' + hf + '"\n')
header_file.write('#include "../mr-library/include/' + hf + '"\n')
# Add the micro
header_file.write("\n#ifdef __cplusplus\n")