summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernard Xiong <[email protected]>2018-12-10 09:29:42 +0800
committerGitHub <[email protected]>2018-12-10 09:29:42 +0800
commit9677fe6f2ce77bc3ddc4e5b05099b8bac63d85ae (patch)
tree411d58049709a4bf07e8880800fcdd36a334c76b
parentd43fcbcd80f8199c87ee9239f1d6b8a4f5a07186 (diff)
parent5098c934d31a3fcff23648a78ec31f036108ef9e (diff)
Merge pull request #2045 from ErnestChen1/master
[add] DMA choice of serial
-rwxr-xr-xcomponents/drivers/Kconfig6
-rw-r--r--components/drivers/serial/serial.c110
2 files changed, 73 insertions, 43 deletions
diff --git a/components/drivers/Kconfig b/components/drivers/Kconfig
index 9e97aac3c3..d8dc5e7458 100755
--- a/components/drivers/Kconfig
+++ b/components/drivers/Kconfig
@@ -16,6 +16,12 @@ config RT_USING_SERIAL
select RT_USING_DEVICE
default y
+if RT_USING_SERIAL
+ config RT_SERIAL_USING_DMA
+ bool "Enable serial DMA mode"
+ default y
+endif
+
config RT_USING_CAN
bool "Using CAN device drivers"
default n
diff --git a/components/drivers/serial/serial.c b/components/drivers/serial/serial.c
index 959d8444c1..c5932df7d9 100644
--- a/components/drivers/serial/serial.c
+++ b/components/drivers/serial/serial.c
@@ -21,6 +21,7 @@
* 2017-11-07 JasonJia fix data bits error issue when using tcsetattr.
* 2017-11-15 JasonJia fix poll rx issue when data is full.
* add TCFLSH and FIONREAD support.
+ * 2018-12-08 Ernest Chen add DMA choice
*/
#include <rthw.h>
@@ -328,6 +329,7 @@ rt_inline int _serial_int_tx(struct rt_serial_device *serial, const rt_uint8_t *
return size - length;
}
+#if defined(RT_USING_POSIX) || defined(RT_SERIAL_USING_DMA)
static rt_size_t _serial_fifo_calc_recved_len(struct rt_serial_device *serial)
{
struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
@@ -350,7 +352,9 @@ static rt_size_t _serial_fifo_calc_recved_len(struct rt_serial_device *serial)
}
}
}
+#endif /* RT_USING_POSIX || RT_SERIAL_USING_DMA */
+#ifdef RT_SERIAL_USING_DMA
/**
* Calculate DMA received data length.
*
@@ -527,6 +531,7 @@ rt_inline int _serial_dma_tx(struct rt_serial_device *serial, const rt_uint8_t *
return 0;
}
}
+#endif /* RT_SERIAL_USING_DMA */
/* RT-Thread Device Interface */
/*
@@ -561,11 +566,13 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
LOG_D("open serial device: 0x%08x with open flag: 0x%04x",
dev, oflag);
+#ifdef RT_SERIAL_USING_DMA
/* check device flag with the open flag */
if ((oflag & RT_DEVICE_FLAG_DMA_RX) && !(dev->flag & RT_DEVICE_FLAG_DMA_RX))
return -RT_EIO;
if ((oflag & RT_DEVICE_FLAG_DMA_TX) && !(dev->flag & RT_DEVICE_FLAG_DMA_TX))
return -RT_EIO;
+#endif /* RT_SERIAL_USING_DMA */
if ((oflag & RT_DEVICE_FLAG_INT_RX) && !(dev->flag & RT_DEVICE_FLAG_INT_RX))
return -RT_EIO;
if ((oflag & RT_DEVICE_FLAG_INT_TX) && !(dev->flag & RT_DEVICE_FLAG_INT_TX))
@@ -580,8 +587,27 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
/* initialize the Rx/Tx structure according to open flag */
if (serial->serial_rx == RT_NULL)
- {
- if (oflag & RT_DEVICE_FLAG_DMA_RX)
+ {
+ if (oflag & RT_DEVICE_FLAG_INT_RX)
+ {
+ struct rt_serial_rx_fifo* rx_fifo;
+
+ rx_fifo = (struct rt_serial_rx_fifo*) rt_malloc (sizeof(struct rt_serial_rx_fifo) +
+ serial->config.bufsz);
+ RT_ASSERT(rx_fifo != RT_NULL);
+ rx_fifo->buffer = (rt_uint8_t*) (rx_fifo + 1);
+ rt_memset(rx_fifo->buffer, 0, serial->config.bufsz);
+ rx_fifo->put_index = 0;
+ rx_fifo->get_index = 0;
+ rx_fifo->is_full = RT_FALSE;
+
+ serial->serial_rx = rx_fifo;
+ dev->open_flag |= RT_DEVICE_FLAG_INT_RX;
+ /* configure low level device */
+ serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX);
+ }
+#ifdef RT_SERIAL_USING_DMA
+ else if (oflag & RT_DEVICE_FLAG_DMA_RX)
{
if (serial->config.bufsz == 0) {
struct rt_serial_rx_dma* rx_dma;
@@ -608,24 +634,7 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
}
dev->open_flag |= RT_DEVICE_FLAG_DMA_RX;
}
- else if (oflag & RT_DEVICE_FLAG_INT_RX)
- {
- struct rt_serial_rx_fifo* rx_fifo;
-
- rx_fifo = (struct rt_serial_rx_fifo*) rt_malloc (sizeof(struct rt_serial_rx_fifo) +
- serial->config.bufsz);
- RT_ASSERT(rx_fifo != RT_NULL);
- rx_fifo->buffer = (rt_uint8_t*) (rx_fifo + 1);
- rt_memset(rx_fifo->buffer, 0, serial->config.bufsz);
- rx_fifo->put_index = 0;
- rx_fifo->get_index = 0;
- rx_fifo->is_full = RT_FALSE;
-
- serial->serial_rx = rx_fifo;
- dev->open_flag |= RT_DEVICE_FLAG_INT_RX;
- /* configure low level device */
- serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX);
- }
+#endif /* RT_SERIAL_USING_DMA */
else
{
serial->serial_rx = RT_NULL;
@@ -633,28 +642,17 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
}
else
{
- if (oflag & RT_DEVICE_FLAG_DMA_RX)
- dev->open_flag |= RT_DEVICE_FLAG_DMA_RX;
- else if (oflag & RT_DEVICE_FLAG_INT_RX)
+ if (oflag & RT_DEVICE_FLAG_INT_RX)
dev->open_flag |= RT_DEVICE_FLAG_INT_RX;
+#ifdef RT_SERIAL_USING_DMA
+ else if (oflag & RT_DEVICE_FLAG_DMA_RX)
+ dev->open_flag |= RT_DEVICE_FLAG_DMA_RX;
+#endif /* RT_SERIAL_USING_DMA */
}
if (serial->serial_tx == RT_NULL)
{
- if (oflag & RT_DEVICE_FLAG_DMA_TX)
- {
- struct rt_serial_tx_dma* tx_dma;
-
- tx_dma = (struct rt_serial_tx_dma*) rt_malloc (sizeof(struct rt_serial_tx_dma));
- RT_ASSERT(tx_dma != RT_NULL);
- tx_dma->activated = RT_FALSE;
-
- rt_data_queue_init(&(tx_dma->data_queue), 8, 4, RT_NULL);
- serial->serial_tx = tx_dma;
-
- dev->open_flag |= RT_DEVICE_FLAG_DMA_TX;
- }
- else if (oflag & RT_DEVICE_FLAG_INT_TX)
+ if (oflag & RT_DEVICE_FLAG_INT_TX)
{
struct rt_serial_tx_fifo *tx_fifo;
@@ -668,6 +666,21 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
/* configure low level device */
serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_TX);
}
+#ifdef RT_SERIAL_USING_DMA
+ else if (oflag & RT_DEVICE_FLAG_DMA_TX)
+ {
+ struct rt_serial_tx_dma* tx_dma;
+
+ tx_dma = (struct rt_serial_tx_dma*) rt_malloc (sizeof(struct rt_serial_tx_dma));
+ RT_ASSERT(tx_dma != RT_NULL);
+ tx_dma->activated = RT_FALSE;
+
+ rt_data_queue_init(&(tx_dma->data_queue), 8, 4, RT_NULL);
+ serial->serial_tx = tx_dma;
+
+ dev->open_flag |= RT_DEVICE_FLAG_DMA_TX;
+ }
+#endif /* RT_SERIAL_USING_DMA */
else
{
serial->serial_tx = RT_NULL;
@@ -675,10 +688,12 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
}
else
{
- if (oflag & RT_DEVICE_FLAG_DMA_TX)
- dev->open_flag |= RT_DEVICE_FLAG_DMA_TX;
- else if (oflag & RT_DEVICE_FLAG_INT_TX)
+ if (oflag & RT_DEVICE_FLAG_INT_TX)
dev->open_flag |= RT_DEVICE_FLAG_INT_TX;
+#ifdef RT_SERIAL_USING_DMA
+ else if (oflag & RT_DEVICE_FLAG_DMA_TX)
+ dev->open_flag |= RT_DEVICE_FLAG_DMA_TX;
+#endif /* RT_SERIAL_USING_DMA */
}
/* set stream flag */
@@ -710,6 +725,7 @@ static rt_err_t rt_serial_close(struct rt_device *dev)
/* configure low level device */
serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_RX);
}
+#ifdef RT_SERIAL_USING_DMA
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX)
{
if (serial->config.bufsz == 0) {
@@ -732,7 +748,8 @@ static rt_err_t rt_serial_close(struct rt_device *dev)
serial->serial_rx = RT_NULL;
dev->open_flag &= ~RT_DEVICE_FLAG_DMA_RX;
}
-
+#endif /* RT_SERIAL_USING_DMA */
+
if (dev->open_flag & RT_DEVICE_FLAG_INT_TX)
{
struct rt_serial_tx_fifo* tx_fifo;
@@ -746,6 +763,7 @@ static rt_err_t rt_serial_close(struct rt_device *dev)
/* configure low level device */
serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_TX);
}
+#ifdef RT_SERIAL_USING_DMA
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX)
{
struct rt_serial_tx_dma* tx_dma;
@@ -757,7 +775,7 @@ static rt_err_t rt_serial_close(struct rt_device *dev)
serial->serial_tx = RT_NULL;
dev->open_flag &= ~RT_DEVICE_FLAG_DMA_TX;
}
-
+#endif /* RT_SERIAL_USING_DMA */
return RT_EOK;
}
@@ -777,10 +795,12 @@ static rt_size_t rt_serial_read(struct rt_device *dev,
{
return _serial_int_rx(serial, buffer, size);
}
+#ifdef RT_SERIAL_USING_DMA
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX)
{
return _serial_dma_rx(serial, buffer, size);
}
+#endif /* RT_SERIAL_USING_DMA */
return _serial_poll_rx(serial, buffer, size);
}
@@ -801,10 +821,12 @@ static rt_size_t rt_serial_write(struct rt_device *dev,
{
return _serial_int_tx(serial, buffer, size);
}
+#ifdef RT_SERIAL_USING_DMA
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX)
{
return _serial_dma_tx(serial, buffer, size);
}
+#endif /* RT_SERIAL_USING_DMA */
else
{
return _serial_poll_tx(serial, buffer, size);
@@ -1181,12 +1203,13 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
rt_completion_done(&(tx_fifo->completion));
break;
}
+#ifdef RT_SERIAL_USING_DMA
case RT_SERIAL_EVENT_TX_DMADONE:
{
const void *data_ptr;
rt_size_t data_size;
const void *last_data_ptr;
- struct rt_serial_tx_dma* tx_dma;
+ struct rt_serial_tx_dma *tx_dma;
tx_dma = (struct rt_serial_tx_dma*) serial->serial_tx;
@@ -1246,6 +1269,7 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
}
break;
}
+#endif /* RT_SERIAL_USING_DMA */
}
}