[add] DMA choice of serial
This commit is contained in:
parent
538923d34e
commit
5098c934d3
|
@ -16,6 +16,12 @@ config RT_USING_SERIAL
|
||||||
select RT_USING_DEVICE
|
select RT_USING_DEVICE
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
if RT_USING_SERIAL
|
||||||
|
config RT_SERIAL_USING_DMA
|
||||||
|
bool "Enable serial DMA mode"
|
||||||
|
default y
|
||||||
|
endif
|
||||||
|
|
||||||
config RT_USING_CAN
|
config RT_USING_CAN
|
||||||
bool "Using CAN device drivers"
|
bool "Using CAN device drivers"
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
* 2017-11-07 JasonJia fix data bits error issue when using tcsetattr.
|
* 2017-11-07 JasonJia fix data bits error issue when using tcsetattr.
|
||||||
* 2017-11-15 JasonJia fix poll rx issue when data is full.
|
* 2017-11-15 JasonJia fix poll rx issue when data is full.
|
||||||
* add TCFLSH and FIONREAD support.
|
* add TCFLSH and FIONREAD support.
|
||||||
|
* 2018-12-08 Ernest Chen add DMA choice
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rthw.h>
|
#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;
|
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)
|
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;
|
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.
|
* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* RT_SERIAL_USING_DMA */
|
||||||
|
|
||||||
/* RT-Thread Device Interface */
|
/* 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",
|
LOG_D("open serial device: 0x%08x with open flag: 0x%04x",
|
||||||
dev, oflag);
|
dev, oflag);
|
||||||
|
#ifdef RT_SERIAL_USING_DMA
|
||||||
/* check device flag with the open flag */
|
/* check device flag with the open flag */
|
||||||
if ((oflag & RT_DEVICE_FLAG_DMA_RX) && !(dev->flag & RT_DEVICE_FLAG_DMA_RX))
|
if ((oflag & RT_DEVICE_FLAG_DMA_RX) && !(dev->flag & RT_DEVICE_FLAG_DMA_RX))
|
||||||
return -RT_EIO;
|
return -RT_EIO;
|
||||||
if ((oflag & RT_DEVICE_FLAG_DMA_TX) && !(dev->flag & RT_DEVICE_FLAG_DMA_TX))
|
if ((oflag & RT_DEVICE_FLAG_DMA_TX) && !(dev->flag & RT_DEVICE_FLAG_DMA_TX))
|
||||||
return -RT_EIO;
|
return -RT_EIO;
|
||||||
|
#endif /* RT_SERIAL_USING_DMA */
|
||||||
if ((oflag & RT_DEVICE_FLAG_INT_RX) && !(dev->flag & RT_DEVICE_FLAG_INT_RX))
|
if ((oflag & RT_DEVICE_FLAG_INT_RX) && !(dev->flag & RT_DEVICE_FLAG_INT_RX))
|
||||||
return -RT_EIO;
|
return -RT_EIO;
|
||||||
if ((oflag & RT_DEVICE_FLAG_INT_TX) && !(dev->flag & RT_DEVICE_FLAG_INT_TX))
|
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 */
|
/* initialize the Rx/Tx structure according to open flag */
|
||||||
if (serial->serial_rx == RT_NULL)
|
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) {
|
if (serial->config.bufsz == 0) {
|
||||||
struct rt_serial_rx_dma* rx_dma;
|
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;
|
dev->open_flag |= RT_DEVICE_FLAG_DMA_RX;
|
||||||
}
|
}
|
||||||
else if (oflag & RT_DEVICE_FLAG_INT_RX)
|
#endif /* RT_SERIAL_USING_DMA */
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
serial->serial_rx = RT_NULL;
|
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
|
else
|
||||||
{
|
{
|
||||||
if (oflag & RT_DEVICE_FLAG_DMA_RX)
|
if (oflag & RT_DEVICE_FLAG_INT_RX)
|
||||||
dev->open_flag |= RT_DEVICE_FLAG_DMA_RX;
|
|
||||||
else if (oflag & RT_DEVICE_FLAG_INT_RX)
|
|
||||||
dev->open_flag |= 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 (serial->serial_tx == RT_NULL)
|
||||||
{
|
{
|
||||||
if (oflag & RT_DEVICE_FLAG_DMA_TX)
|
if (oflag & RT_DEVICE_FLAG_INT_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)
|
|
||||||
{
|
{
|
||||||
struct rt_serial_tx_fifo *tx_fifo;
|
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 */
|
/* configure low level device */
|
||||||
serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_TX);
|
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
|
else
|
||||||
{
|
{
|
||||||
serial->serial_tx = RT_NULL;
|
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
|
else
|
||||||
{
|
{
|
||||||
if (oflag & RT_DEVICE_FLAG_DMA_TX)
|
if (oflag & RT_DEVICE_FLAG_INT_TX)
|
||||||
dev->open_flag |= RT_DEVICE_FLAG_DMA_TX;
|
|
||||||
else if (oflag & RT_DEVICE_FLAG_INT_TX)
|
|
||||||
dev->open_flag |= 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 */
|
/* set stream flag */
|
||||||
|
@ -710,6 +725,7 @@ static rt_err_t rt_serial_close(struct rt_device *dev)
|
||||||
/* configure low level device */
|
/* configure low level device */
|
||||||
serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_RX);
|
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)
|
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX)
|
||||||
{
|
{
|
||||||
if (serial->config.bufsz == 0) {
|
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;
|
serial->serial_rx = RT_NULL;
|
||||||
dev->open_flag &= ~RT_DEVICE_FLAG_DMA_RX;
|
dev->open_flag &= ~RT_DEVICE_FLAG_DMA_RX;
|
||||||
}
|
}
|
||||||
|
#endif /* RT_SERIAL_USING_DMA */
|
||||||
|
|
||||||
if (dev->open_flag & RT_DEVICE_FLAG_INT_TX)
|
if (dev->open_flag & RT_DEVICE_FLAG_INT_TX)
|
||||||
{
|
{
|
||||||
struct rt_serial_tx_fifo* tx_fifo;
|
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 */
|
/* configure low level device */
|
||||||
serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_TX);
|
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)
|
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX)
|
||||||
{
|
{
|
||||||
struct rt_serial_tx_dma* tx_dma;
|
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;
|
serial->serial_tx = RT_NULL;
|
||||||
dev->open_flag &= ~RT_DEVICE_FLAG_DMA_TX;
|
dev->open_flag &= ~RT_DEVICE_FLAG_DMA_TX;
|
||||||
}
|
}
|
||||||
|
#endif /* RT_SERIAL_USING_DMA */
|
||||||
return RT_EOK;
|
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);
|
return _serial_int_rx(serial, buffer, size);
|
||||||
}
|
}
|
||||||
|
#ifdef RT_SERIAL_USING_DMA
|
||||||
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX)
|
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX)
|
||||||
{
|
{
|
||||||
return _serial_dma_rx(serial, buffer, size);
|
return _serial_dma_rx(serial, buffer, size);
|
||||||
}
|
}
|
||||||
|
#endif /* RT_SERIAL_USING_DMA */
|
||||||
|
|
||||||
return _serial_poll_rx(serial, buffer, size);
|
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);
|
return _serial_int_tx(serial, buffer, size);
|
||||||
}
|
}
|
||||||
|
#ifdef RT_SERIAL_USING_DMA
|
||||||
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX)
|
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX)
|
||||||
{
|
{
|
||||||
return _serial_dma_tx(serial, buffer, size);
|
return _serial_dma_tx(serial, buffer, size);
|
||||||
}
|
}
|
||||||
|
#endif /* RT_SERIAL_USING_DMA */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return _serial_poll_tx(serial, buffer, size);
|
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));
|
rt_completion_done(&(tx_fifo->completion));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifdef RT_SERIAL_USING_DMA
|
||||||
case RT_SERIAL_EVENT_TX_DMADONE:
|
case RT_SERIAL_EVENT_TX_DMADONE:
|
||||||
{
|
{
|
||||||
const void *data_ptr;
|
const void *data_ptr;
|
||||||
rt_size_t data_size;
|
rt_size_t data_size;
|
||||||
const void *last_data_ptr;
|
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;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif /* RT_SERIAL_USING_DMA */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue