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

View File

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

View File

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

View File

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

View File

@@ -18,7 +18,7 @@
(MR_BIT_IS_SET((_adc)->channels, (1 << (_channel)))) (MR_BIT_IS_SET((_adc)->channels, (1 << (_channel))))
MR_INLINE int _adc_channel_configure_set(struct mr_adc *adc, int 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_driver *driver = _MR_DEVICE_DRIVER_GET((struct mr_device *)adc);
struct mr_adc_driver_ops *ops = _MR_DRIVER_OPS_GET(driver); 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; 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) struct mr_adc_config *config)
{ {
/* Check if the channel is valid */ /* 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. * @return The error code.
*/ */
int mr_adc_register(struct mr_adc *adc, const char *path, 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(adc != NULL);
MR_ASSERT(path != NULL); MR_ASSERT(path != NULL);

View File

@@ -1,15 +1,17 @@
menu "Pin configure" menu "Pin configure"
# Pin
config MR_USE_PIN config MR_USE_PIN
bool "Use pin" bool "Use pin"
default y default n
help 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 config MR_USE_PIN_CHECK
depends on MR_USE_PIN depends on MR_USE_PIN
bool "Use pin check" bool "Use pin check"
default y default y
help help
"This option allows for the use of pin check." This option allows for the use of pin check.
endmenu
endmenu

View File

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

View File

@@ -1,51 +1,58 @@
menu "Serial configure" menu "Serial configure"
# Serial
config MR_USE_SERIAL config MR_USE_SERIAL
bool "Use serial" bool "Use serial"
default y default n
help 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 config MR_CFG_SERIAL_RD_FIFO_SIZE
depends on MR_USE_SERIAL depends on MR_USE_SERIAL
int "Serial read fifo size" int "Serial read FIFO size"
range 0 2147483647 range 0 2147483647
default 128 default 128
help 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 config MR_CFG_SERIAL_WR_FIFO_SIZE
depends on MR_USE_SERIAL depends on MR_USE_SERIAL
int "Serial write fifo size" int "Serial write FIFO size"
range 0 2147483647 range 0 2147483647
default 0 default 0
help help
"This option sets the size of the write fifo." This option sets the size of the write FIFO.
# DMA # DMA
config MR_USE_SERIAL_DMA config MR_USE_SERIAL_DMA
depends on MR_USE_SERIAL depends on MR_USE_SERIAL
bool "Use serial dma" bool "Use serial DMA"
default n default n
help 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 config MR_CFG_SERIAL_RD_DMA_FIFO_SIZE
depends on MR_USE_SERIAL_DMA depends on MR_USE_SERIAL_DMA
int "Serial read dma fifo size" int "Serial read DMA FIFO size"
range 0 2147483647 range 0 2147483647
default 128 default 128
help 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 config MR_CFG_SERIAL_WR_DMA_FIFO_SIZE
depends on MR_USE_SERIAL_DMA depends on MR_USE_SERIAL_DMA
int "Serial write dma fifo size" int "Serial write DMA FIFO size"
range 0 2147483647 range 0 2147483647
default 128 default 128
help help
"This option sets the size of the write dma fifo." This option sets the size of the write DMA FIFO.
endmenu
# 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 #ifdef MR_USE_SERIAL
#define _SERIAL_STATE_RECEIVE_INT_ASYNC (0x01 << 0) /**< Receive interrupt async */ #define _STATE_RECEIVE_INT_ASYNC (0x01 << 0) /**< Receive interrupt async */
#define _SERIAL_STATE_SEND_INT (0x01 << 8) /**< Send interrupt */ #define _STATE_SEND_INT (0x01 << 8) /**< Send interrupt */
#define _SERIAL_STATE_SEND_INT_ASYNC (0x02 << 8) /**< Send interrupt async */ #define _STATE_SEND_INT_ASYNC (0x02 << 8) /**< Send interrupt async */
#define _SERIAL_STATE_RECEIVE_DMA (0x01 << 16) /**< Receive DMA */ #define _STATE_RECEIVE_DMA (0x01 << 16) /**< Receive DMA */
#define _SERIAL_STATE_RECEIVE_DMA_TOP (0x02 << 16) /**< Receive DMA top */ #define _STATE_RECEIVE_DMA_TOP (0x02 << 16) /**< Receive DMA top */
#define _SERIAL_STATE_RECEIVE_DMA_BOT (0x04 << 16) /**< Receive DMA bot */ #define _STATE_RECEIVE_DMA_BOT (0x04 << 16) /**< Receive DMA bot */
#define _SERIAL_STATE_RECEIVE_DMA_ASYNC (0x08 << 16) /**< Receive DMA async */ #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, MR_INLINE ssize_t _serial_read_poll(struct mr_serial *serial, uint8_t *buf,
size_t count) 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 #ifdef MR_USE_SERIAL_ASYNC
MR_INLINE ssize_t _serial_async_read_int(struct mr_serial *serial, uint8_t *buf, MR_INLINE ssize_t _serial_aread_int(struct mr_serial *serial, uint8_t *buf,
size_t count) size_t count)
{ {
/* Receive data from FIFO */ /* Receive data from FIFO */
size_t rcount = mr_fifo_read(&serial->rfifo, buf, count); 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 */ /* Set the async receive buffer and count */
serial->rabuf = buf + rcount; serial->rabuf = buf + rcount;
serial->racount = count - 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; return MR_EOK;
} }
#ifdef MR_USE_SERIAL_DMA #ifdef MR_USE_SERIAL_DMA
MR_INLINE ssize_t _serial_async_read_dma(struct mr_serial *serial, uint8_t *buf, MR_INLINE ssize_t _serial_aread_dma(struct mr_serial *serial, uint8_t *buf,
size_t count) size_t count)
{ {
struct mr_driver *driver = struct mr_driver *driver =
_MR_DEVICE_DRIVER_GET((struct mr_device *)serial); _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 */ /* 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); int ret = ops->receive_dma(driver, false, NULL, 0);
MR_BIT_CLR(serial->state, _SERIAL_STATE_RECEIVE_DMA | if (ret < 0)
_SERIAL_STATE_RECEIVE_DMA_TOP | {
_SERIAL_STATE_RECEIVE_DMA_BOT); 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 */ /* 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; serial->racount = count - rcount;
/* Start the receive DMA */ /* Start the receive DMA */
MR_BIT_SET(serial->state, MR_BIT_SET(serial->state, _STATE_RECEIVE_DMA | _STATE_RECEIVE_DMA_ASYNC);
_SERIAL_STATE_RECEIVE_DMA | _SERIAL_STATE_RECEIVE_DMA_ASYNC);
int ret = ops->receive_dma(driver, true, serial->rabuf, serial->racount); int ret = ops->receive_dma(driver, true, serial->rabuf, serial->racount);
if (ret < 0) if (ret < 0)
{ {
MR_BIT_CLR(serial->state, MR_BIT_CLR(serial->state,
_SERIAL_STATE_RECEIVE_DMA | _SERIAL_STATE_RECEIVE_DMA_ASYNC); _STATE_RECEIVE_DMA | _STATE_RECEIVE_DMA_ASYNC);
return ret; return ret;
} }
return MR_EOK; 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); _MR_DEVICE_DRIVER_GET((struct mr_device *)serial);
struct mr_serial_driver_ops *ops = _MR_DRIVER_OPS_GET(driver); 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 */ /* Driver does not support this function */
if (ops->send_int_configure == NULL) if (ops->send_int_configure == NULL)
{ {
return MR_EIO; 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 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); 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 /* Data has been written to the FIFO, if the boot sent fails, wait
* for the next retry startup */ * for the next retry startup */
MR_BIT_CLR(serial->state, _STATE_SEND_INT);
return wcount; return wcount;
} }
/* Set the sending state */
MR_BIT_SET(serial->state, _SERIAL_STATE_SEND_INT);
} }
/* Return the number of bytes sent */ /* Return the number of bytes sent */
return wcount; 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) MR_INLINE int _serial_fifo_allocate(struct mr_fifo *fifo, size_t *size)
{ {
/* Allocate new buffer for FIFO */ /* 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 the driver supports DMA, start DMA to receive data */
if (ops->receive_dma != NULL) if (ops->receive_dma != NULL)
{ {
MR_BIT_SET(serial->state, MR_BIT_SET(serial->state, _STATE_RECEIVE_DMA | _STATE_RECEIVE_DMA_TOP);
_SERIAL_STATE_RECEIVE_DMA | _SERIAL_STATE_RECEIVE_DMA_TOP);
ops->receive_dma(driver, true, serial->rdma, sizeof(serial->rdma) / 2); ops->receive_dma(driver, true, serial->rdma, sizeof(serial->rdma) / 2);
} }
#endif /* MR_USE_SERIAL_DMA */ #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_driver *driver = _MR_DEVICE_DRIVER_GET(device);
struct mr_serial_driver_ops *ops = _MR_DRIVER_OPS_GET(driver); struct mr_serial_driver_ops *ops = _MR_DRIVER_OPS_GET(driver);
/* Disable serial TX interrupt */ /* If the serial port is sending, disable it */
if (MR_BIT_IS_SET(serial->state, _SERIAL_STATE_SEND_INT) == true) if (MR_BIT_IS_SET(serial->state, _STATE_SEND_INT) == true)
{ {
ops->send_int_configure(driver, false); 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 #ifdef MR_USE_SERIAL_DMA
/* Stop DMA */ /* If the serial port is receiving, disable it */
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); ops->receive_dma(driver, false, NULL, 0);
MR_BIT_CLR(serial->state, _SERIAL_STATE_RECEIVE_DMA | MR_BIT_CLR(serial->state, _STATE_RECEIVE_DMA | _STATE_RECEIVE_DMA_TOP |
_SERIAL_STATE_RECEIVE_DMA_TOP | _STATE_RECEIVE_DMA_BOT);
_SERIAL_STATE_RECEIVE_DMA_BOT);
} }
#endif /* MR_USE_SERIAL_DMA */ #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 #ifdef MR_USE_SERIAL_ASYNC
static ssize_t serial_read_async(struct mr_device *device, int pos, void *buf, static ssize_t serial_aread(struct mr_device *device, int pos, void *buf,
size_t count) size_t count)
{ {
struct mr_serial *serial = (struct mr_serial *)device; struct mr_serial *serial = (struct mr_serial *)device;
/* Check if the serial port is busy */ /* Check if the serial port is busy */
if (serial->state & if (serial->state & (_STATE_RECEIVE_INT_ASYNC | _STATE_RECEIVE_DMA_ASYNC))
(_SERIAL_STATE_RECEIVE_INT_ASYNC | _SERIAL_STATE_RECEIVE_DMA_ASYNC))
{ {
return MR_EBUSY; 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 the driver supports DMA, start DMA to async read data */
if (ops->receive_dma != NULL) 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 */ #endif /* MR_USE_SERIAL_DMA */
/* Interrupt async read data */ /* Interrupt async read data */
return _serial_async_read_int(serial, buf, count); return _serial_aread_int(serial, buf, count);
} }
#endif /* MR_USE_SERIAL_ASYNC */ #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) size_t count)
{ {
struct mr_serial *serial = (struct mr_serial *)device; 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 FIFO is set and the driver supports it, write to FIFO */
if (mr_fifo_size_get(&serial->wfifo) != 0) 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); 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); 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) static int serial_ioctl(struct mr_device *device, int pos, int cmd, void *args)
{ {
struct mr_serial *serial = (struct mr_serial *)device; 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; size_t count = 1;
/* Hardware FIFO is considered to be used */
if (args != NULL) if (args != NULL)
{ {
/* Hardware FIFO is considered to be used */
count = *((size_t *)args); count = *((size_t *)args);
} }
#ifdef MR_USE_SERIAL_ASYNC #ifdef MR_USE_SERIAL_ASYNC
if (MR_BIT_IS_SET(serial->state, _SERIAL_STATE_RECEIVE_INT_ASYNC) == if (MR_BIT_IS_SET(serial->state, _STATE_RECEIVE_INT_ASYNC) == true)
true)
{ {
size_t rcount; size_t rcount;
/* Read all data from hardware FIFO */ /* Read all data from hardware FIFO */
for (rcount = 0; rcount < count; rcount++) for (rcount = 0; rcount < count; rcount++)
{ {
uint8_t data;
/* Read data from serial */ /* Read data from serial */
int ret = ops->receive(driver, &data); int ret = ops->receive(driver, serial->rabuf);
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
} }
*serial->rabuf = data;
serial->rabuf++; serial->rabuf++;
serial->racount--; serial->racount--;
@@ -513,8 +619,7 @@ static int serial_isr(struct mr_device *device, uint32_t event, void *args)
if (serial->racount == 0) if (serial->racount == 0)
{ {
/* Stop async read operation */ /* Stop async read operation */
MR_BIT_CLR(serial->state, MR_BIT_CLR(serial->state, _STATE_RECEIVE_INT_ASYNC);
_SERIAL_STATE_RECEIVE_INT_ASYNC);
break; break;
} }
} }
@@ -529,7 +634,8 @@ static int serial_isr(struct mr_device *device, uint32_t event, void *args)
count -= rcount; count -= rcount;
if (count == 0) 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 */ #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 FIFO is empty, the read operation is abandoned */
if (mr_fifo_size_get(&serial->rfifo) == 0) if (mr_fifo_size_get(&serial->rfifo) == 0)
{ {
return MR_EOK; return 0;
} }
/* Read all data from hardware FIFO */ /* 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 */ /* Force write data to FIFO */
mr_fifo_write_force(&serial->rfifo, &data, sizeof(data)); 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: case MR_EVENT_SERIAL_WR_COMPLETE_INT:
{ {
uint8_t data; size_t count = 1;
/* Driver does not support this function */ /* Driver does not support this function */
if (ops->send_int_configure == NULL) 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; return MR_EIO;
} }
/* If FIFO is empty, the write operation is abandoned */ /* Hardware FIFO is considered to be used */
if (mr_fifo_size_get(&serial->wfifo) == 0) if (args != NULL)
{ {
return MR_EOK; count = *((size_t *)args);
} }
/* If FIFO is empty, stop sending */ #ifdef MR_USE_SERIAL_ASYNC
if (mr_fifo_peek(&serial->wfifo, &data, sizeof(data)) != if (MR_BIT_IS_SET(serial->state, _STATE_SEND_INT_ASYNC) == true)
sizeof(data))
{ {
/* Stop sending */ size_t wcount;
int ret = ops->send_int_configure(driver, false);
/* 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 (ret < 0)
{ {
/* If the stop is failed, nothing can do */
return ret; return ret;
} }
/* Clear the sending state */ /* Discard sent data */
MR_BIT_CLR(serial->state, _SERIAL_STATE_SEND_INT); mr_fifo_discard(&serial->wfifo, sizeof(data));
return MR_EOK;
} }
/* Write data to serial */ /* Returns the number of data in the write FIFO */
int ret = ops->send(driver, data); return mr_fifo_used_get(&serial->wfifo);
if (ret < 0)
{
return ret;
}
/* Discard data from FIFO */
mr_fifo_discard(&serial->wfifo, sizeof(data));
return MR_EBUSY;
} }
#ifdef MR_USE_SERIAL_DMA #ifdef MR_USE_SERIAL_DMA
case MR_EVENT_SERIAL_RD_COMPLETE_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 */ /* Ping-pong operation */
if (MR_BIT_IS_SET(serial->state, _SERIAL_STATE_RECEIVE_DMA_TOP) == if (MR_BIT_IS_SET(serial->state, _STATE_RECEIVE_DMA_TOP) == true)
true)
{ {
/* Top half of DMA buffer is used */ /* Top half of DMA buffer is used */
rdma = serial->rdma; rdma = serial->rdma;
ndma = &serial->rdma[sizeof(serial->rdma) / 2]; ndma = &serial->rdma[sizeof(serial->rdma) / 2];
MR_BIT_CLR(serial->state, _SERIAL_STATE_RECEIVE_DMA_TOP); MR_BIT_CLR(serial->state, _STATE_RECEIVE_DMA_TOP);
MR_BIT_SET(serial->state, _SERIAL_STATE_RECEIVE_DMA_BOT); MR_BIT_SET(serial->state, _STATE_RECEIVE_DMA_BOT);
} else if (MR_BIT_IS_SET(serial->state, } else if (MR_BIT_IS_SET(serial->state, _STATE_RECEIVE_DMA_BOT) ==
_SERIAL_STATE_RECEIVE_DMA_BOT) == true) true)
{ {
/* Bottom half of DMA buffer is used */ /* Bottom half of DMA buffer is used */
rdma = &serial->rdma[sizeof(serial->rdma) / 2]; rdma = &serial->rdma[sizeof(serial->rdma) / 2];
ndma = serial->rdma; ndma = serial->rdma;
MR_BIT_CLR(serial->state, _SERIAL_STATE_RECEIVE_DMA_BOT); MR_BIT_CLR(serial->state, _STATE_RECEIVE_DMA_BOT);
MR_BIT_SET(serial->state, _SERIAL_STATE_RECEIVE_DMA_TOP); MR_BIT_SET(serial->state, _STATE_RECEIVE_DMA_TOP);
} }
#ifdef MR_USE_SERIAL_ASYNC #ifdef MR_USE_SERIAL_ASYNC
else if (MR_BIT_IS_SET(serial->state, else if (MR_BIT_IS_SET(serial->state, _STATE_RECEIVE_DMA_ASYNC) ==
_SERIAL_STATE_RECEIVE_DMA_ASYNC) == true) true)
{ {
count = serial->racount; count = serial->racount;
/* Only partially done */
if (args != NULL) if (args != NULL)
{ {
/* Only partially done */
count = *((size_t *)args); count = *((size_t *)args);
/* Not more than async read count */ /* 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) if (serial->racount == 0)
{ {
/* Stop async read operation */ /* Stop async read operation */
MR_BIT_CLR(serial->state, _SERIAL_STATE_RECEIVE_DMA_ASYNC); MR_BIT_CLR(serial->state, _STATE_RECEIVE_DMA_ASYNC);
MR_BIT_SET(serial->state, _SERIAL_STATE_RECEIVE_DMA_TOP); MR_BIT_SET(serial->state, _STATE_RECEIVE_DMA_TOP);
ops->receive_dma(driver, true, serial->rdma, int ret = ops->receive_dma(driver, true, serial->rdma,
sizeof(serial->rdma) / 2); sizeof(serial->rdma) / 2);
return MR_EOK; if (ret < 0)
{
return ret;
}
/* Returns the number of data in the read FIFO */
return mr_fifo_used_get(&serial->rfifo);
} }
/* Continue reading */ /* 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, return ops->receive_dma(driver, true, ndma,
sizeof(serial->rdma) / 2); 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 */ #endif /* MR_USE_SERIAL_DMA */
default: default:
{ {
@@ -725,7 +929,8 @@ int mr_serial_register(struct mr_serial *serial, const char *path,
.close = serial_close, .close = serial_close,
.read = serial_read, .read = serial_read,
#ifdef MR_USE_SERIAL_ASYNC #ifdef MR_USE_SERIAL_ASYNC
.read_async = serial_read_async, .aread = serial_aread,
.awrite = serial_awrite,
#endif /* MR_USE_SERIAL_ASYNC */ #endif /* MR_USE_SERIAL_ASYNC */
.write = serial_write, .write = serial_write,
.ioctl = serial_ioctl, .ioctl = serial_ioctl,
@@ -747,9 +952,9 @@ int mr_serial_register(struct mr_serial *serial, const char *path,
serial->state = 0; serial->state = 0;
/* Register the serial */ /* Register the serial */
return mr_device_register( return mr_device_register((struct mr_device *)serial, path,
(struct mr_device *)serial, path, MR_DEVICE_TYPE_SERIAL | MR_DEVICE_TYPE_FDX, &ops,
MR_DEVICE_TYPE_SERIAL | MR_DEVICE_TYPE_FULL_DUPLEX, &ops, driver); driver);
} }
#endif /* MR_USE_SERIAL */ #endif /* MR_USE_SERIAL */

View File

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

View File

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

View File

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

View File

@@ -68,6 +68,8 @@ extern "C" {
MR_EVENT_WR_COMPLETE /**< Interrupt on write completion event */ MR_EVENT_WR_COMPLETE /**< Interrupt on write completion event */
#define MR_EVENT_SERIAL_RD_COMPLETE_DMA \ #define MR_EVENT_SERIAL_RD_COMPLETE_DMA \
(MR_EVENT_RD_COMPLETE | 0x01) /**< Interrupt on read DMA completion event */ (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 */ typedef uint8_t mr_serial_data_t; /**< Serial read/write data type */
@@ -110,7 +112,7 @@ struct mr_serial
#ifdef MR_USE_SERIAL_ASYNC #ifdef MR_USE_SERIAL_ASYNC
uint8_t *rabuf; /**< Read async buffer */ uint8_t *rabuf; /**< Read async buffer */
size_t racount; /**< Read async count */ 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 */ size_t wacount; /**< Write async count */
#endif /* MR_USE_SERIAL_ASYNC */ #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_RDONLY (0x01 << 24) /**< Read only flag */
#define MR_FLAG_WRONLY (0x02 << 24) /**< Write only flag */ #define MR_FLAG_WRONLY (0x02 << 24) /**< Write only flag */
#define MR_FLAG_RDWR (0x03 << 24) /**< Read/write flag */ #define MR_FLAG_RDWR (0x03 << 24) /**< Read/write flag */
#define MR_FLAG_RDONLY_ASYNC (0x04 << 24) /**< Async read only flag */ #define MR_FLAG_ARDONLY (0x04 << 24) /**< Async read only flag */
#define MR_FLAG_WRONLY_ASYNC (0x08 << 24) /**< Async write only flag */ #define MR_FLAG_AWRONLY (0x08 << 24) /**< Async write only flag */
#define MR_FLAG_RDWR_ASYNC (0x0c << 24) /**< Async read/write flag */ #define MR_FLAG_ARDWR (0x0c << 24) /**< Async read/write flag */
#define MR_CTRL_SET(_cmd) (_cmd) /**< Set operation */ #define MR_CTRL_SET(_cmd) (_cmd) /**< Set operation */
#define MR_CTRL_GET(_cmd) (-(_cmd)) /**< Get 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_SPI, /**< SPI device */
MR_DEVICE_TYPE_TIMER, /**< Timer device */ MR_DEVICE_TYPE_TIMER, /**< Timer device */
MR_DEVICE_TYPE_PWM, /**< PWM 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; 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 (*read)(struct mr_device *device, int pos, void *buf, size_t count);
ssize_t (*write)(struct mr_device *device, int pos, const void *buf, ssize_t (*write)(struct mr_device *device, int pos, const void *buf,
size_t count); size_t count);
ssize_t (*read_async)(struct mr_device *device, int pos, void *buf, ssize_t (*aread)(struct mr_device *device, int pos, void *buf,
size_t count); size_t count);
ssize_t (*write_async)(struct mr_device *device, int pos, const void *buf, ssize_t (*awrite)(struct mr_device *device, int pos, const void *buf,
size_t count); size_t count);
int (*ioctl)(struct mr_device *device, int pos, int cmd, void *args); int (*ioctl)(struct mr_device *device, int pos, int cmd, void *args);
int (*isr)(struct mr_device *device, uint32_t event, void *args); int (*isr)(struct mr_device *device, uint32_t event, void *args);
@@ -232,13 +232,13 @@ struct mr_device
void *parent; /**< Parent device */ void *parent; /**< Parent device */
uint32_t type: 31; /**< Type */ uint32_t type: 31; /**< Type */
uint32_t full_duplex: 1; /**< Full duplex */ uint32_t fdx: 1; /**< Full duplex */
uint32_t flags; /**< Flags */ uint32_t flags; /**< Flags */
size_t ref_count; /**< Reference count */ size_t ref_count; /**< Reference count */
volatile uint32_t lock; /**< Operation lock */ volatile uint32_t lock; /**< Operation lock */
const struct mr_device_ops *ops; /**< Operations */ const struct mr_device_ops *ops; /**< Operations */
const void *driver; /**< Driver */ 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" menu "Framework configure"
# Printf # Printf
menu "Printf configure" menu "Printf configure"
config MR_CFG_PRINTF_BUF_SIZE config MR_CFG_PRINTF_BUF_SIZE
@@ -6,13 +7,13 @@ menu "Framework configure"
default 256 default 256
range 32 2147483647 range 32 2147483647
help 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 config MR_CFG_PRINTF_NAME
string "Printf port device name" string "Printf port device name"
default "serial1" default "serial1"
help 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 endmenu
# Log # Log
@@ -21,32 +22,32 @@ menu "Framework configure"
bool "Use error log" bool "Use error log"
default y default y
help 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 config MR_USE_LOG_WARN
bool "Use warning log" bool "Use warning log"
default y default y
help 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 config MR_USE_LOG_INFO
bool "Use info log" bool "Use info log"
default y default y
help 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 config MR_USE_LOG_DEBUG
bool "Use debug log" bool "Use debug log"
default y default y
help 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 config MR_CFG_LOG_PRINTF_BUF_SIZE
int "Log printf buffer size" int "Log printf buffer size"
default 256 default 256
range 32 2147483647 range 32 2147483647
help 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 endmenu
# Assert # Assert
@@ -54,14 +55,14 @@ menu "Framework configure"
bool "Use assert" bool "Use assert"
default y default y
help 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 # Heap
config MR_CFG_HEAP_SIZE config MR_CFG_HEAP_SIZE
int "Heap size (Bytes)" int "Heap size (bytes)"
default 4096 default 8192
range 32 2147483647 range 32 2147483647
help help
"This option sets the size of the heap used by the library." This option sets the size of the heap used by the library.
endmenu
endmenu

View File

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

View File

@@ -310,7 +310,7 @@ class MrLib:
# Link include # Link include
for hf in header_files: for hf in header_files:
if hf != os.path.basename(header_out): 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 # Add the micro
header_file.write("\n#ifdef __cplusplus\n") header_file.write("\n#ifdef __cplusplus\n")