drivers: uart_xmc4xxx: Forward DMA overrun errors to user
Currently DMA overrun errors are ignored. Forward the error to the user using the UART_RX_STOPPED with UART_ERROR_OVERRUN reason. Signed-off-by: Andriy Gelman <andriy.gelman@gmail.com>
This commit is contained in:
parent
e9fd49f180
commit
3a4f868084
1 changed files with 34 additions and 6 deletions
|
@ -428,6 +428,28 @@ static inline void async_evt_rx_release_buffer(struct uart_xmc4xxx_data *data, i
|
|||
}
|
||||
}
|
||||
|
||||
static inline void async_evt_rx_stopped(struct uart_xmc4xxx_data *data,
|
||||
enum uart_rx_stop_reason reason)
|
||||
{
|
||||
struct uart_event event = {.type = UART_RX_STOPPED, .data.rx_stop.reason = reason};
|
||||
struct uart_event_rx *rx = &event.data.rx_stop.data;
|
||||
struct dma_status stat;
|
||||
|
||||
if (data->dma_rx.buffer_len == 0 || data->async_cb == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
rx->buf = data->dma_rx.buffer;
|
||||
if (dma_get_status(data->dma_rx.dma_dev, data->dma_rx.dma_channel, &stat) == 0) {
|
||||
data->dma_rx.counter = data->dma_rx.buffer_len - stat.pending_length;
|
||||
}
|
||||
|
||||
rx->len = data->dma_rx.counter - data->dma_rx.offset;
|
||||
rx->offset = data->dma_rx.counter;
|
||||
|
||||
data->async_cb(data->dev, &event, data->async_user_data);
|
||||
}
|
||||
|
||||
static inline void async_evt_rx_disabled(struct uart_xmc4xxx_data *data)
|
||||
{
|
||||
struct uart_event event = {.type = UART_RX_DISABLED};
|
||||
|
@ -707,14 +729,20 @@ static void uart_xmc4xxx_dma_rx_cb(const struct device *dma_dev, void *user_data
|
|||
unsigned int key;
|
||||
int ret;
|
||||
|
||||
if (status != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
__ASSERT_NO_MSG(channel == data->dma_rx.dma_channel);
|
||||
key = irq_lock();
|
||||
k_work_cancel_delayable(&data->dma_rx.timeout_work);
|
||||
|
||||
if (status < 0) {
|
||||
async_evt_rx_stopped(data, UART_ERROR_OVERRUN);
|
||||
uart_xmc4xxx_irq_rx_disable(dev_uart);
|
||||
dma_stop(data->dma_rx.dma_dev, data->dma_rx.dma_channel);
|
||||
async_evt_rx_release_buffer(data, CURRENT_BUFFER);
|
||||
async_evt_rx_release_buffer(data, NEXT_BUFFER);
|
||||
async_evt_rx_disabled(data);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (data->dma_rx.buffer_len == 0) {
|
||||
goto done;
|
||||
}
|
||||
|
@ -725,8 +753,8 @@ static void uart_xmc4xxx_dma_rx_cb(const struct device *dma_dev, void *user_data
|
|||
async_evt_rx_release_buffer(data, CURRENT_BUFFER);
|
||||
|
||||
if (!data->rx_next_buffer) {
|
||||
dma_stop(data->dma_rx.dma_dev, data->dma_rx.dma_channel);
|
||||
uart_xmc4xxx_irq_rx_disable(dev_uart);
|
||||
dma_stop(data->dma_rx.dma_dev, data->dma_rx.dma_channel);
|
||||
async_evt_rx_disabled(data);
|
||||
goto done;
|
||||
}
|
||||
|
@ -743,8 +771,8 @@ static void uart_xmc4xxx_dma_rx_cb(const struct device *dma_dev, void *user_data
|
|||
data->dma_rx.buffer_len);
|
||||
|
||||
if (ret < 0) {
|
||||
dma_stop(data->dma_rx.dma_dev, data->dma_rx.dma_channel);
|
||||
uart_xmc4xxx_irq_rx_disable(dev_uart);
|
||||
dma_stop(data->dma_rx.dma_dev, data->dma_rx.dma_channel);
|
||||
async_evt_rx_release_buffer(data, CURRENT_BUFFER);
|
||||
async_evt_rx_disabled(data);
|
||||
goto done;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue